summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2018-10-24 11:30:15 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2018-10-30 12:56:19 +0000
commit6036726eb981b6c4b42047513b9d3f4ac865daac (patch)
tree673593e70678e7789766d1f732eb51f613a2703b /chromium/third_party/blink
parent466052c4e7c052268fd931888cd58961da94c586 (diff)
downloadqtwebengine-chromium-6036726eb981b6c4b42047513b9d3f4ac865daac.tar.gz
BASELINE: Update Chromium to 70.0.3538.78
Change-Id: Ie634710bf039e26c1957f4ae45e101bd4c434ae7 Reviewed-by: Michael Brüning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/third_party/blink')
-rw-r--r--chromium/third_party/blink/common/BUILD.gn48
-rw-r--r--chromium/third_party/blink/common/DEPS1
-rw-r--r--chromium/third_party/blink/common/associated_interfaces/associated_interface_provider.cc83
-rw-r--r--chromium/third_party/blink/common/associated_interfaces/associated_interface_registry.cc38
-rw-r--r--chromium/third_party/blink/common/cache_storage/OWNERS4
-rw-r--r--chromium/third_party/blink/common/cache_storage/cache_storage_utils.cc16
-rw-r--r--chromium/third_party/blink/common/features.cc46
-rw-r--r--chromium/third_party/blink/common/font_unique_name_lookup/font_table_matcher.cc70
-rw-r--r--chromium/third_party/blink/common/font_unique_name_lookup/font_table_matcher_unittest.cc72
-rw-r--r--chromium/third_party/blink/common/font_unique_name_lookup/icu_fold_case_util.cc19
-rw-r--r--chromium/third_party/blink/common/font_unique_name_lookup/icu_fold_case_util_unittest.cc21
-rw-r--r--chromium/third_party/blink/common/frame/user_activation_state.cc9
-rw-r--r--chromium/third_party/blink/common/frame/user_activation_state_unittest.cc4
-rw-r--r--chromium/third_party/blink/common/indexeddb/OWNERS9
-rw-r--r--chromium/third_party/blink/common/indexeddb/indexeddb_key.cc143
-rw-r--r--chromium/third_party/blink/common/indexeddb/indexeddb_key_path.cc57
-rw-r--r--chromium/third_party/blink/common/indexeddb/indexeddb_key_range.cc44
-rw-r--r--chromium/third_party/blink/common/indexeddb/indexeddb_key_unittest.cc59
-rw-r--r--chromium/third_party/blink/common/indexeddb/indexeddb_metadata.cc106
-rw-r--r--chromium/third_party/blink/common/indexeddb/indexeddb_struct_traits.cc456
-rw-r--r--chromium/third_party/blink/common/manifest/manifest.cc4
-rw-r--r--chromium/third_party/blink/common/manifest/manifest_mojom_traits.cc24
-rw-r--r--chromium/third_party/blink/common/manifest/manifest_share_target_util.cc128
-rw-r--r--chromium/third_party/blink/common/manifest/manifest_share_target_util_unittest.cc266
-rw-r--r--chromium/third_party/blink/common/message_port/cloneable_message_struct_traits.cc5
-rw-r--r--chromium/third_party/blink/common/message_port/cloneable_message_struct_traits.h13
-rw-r--r--chromium/third_party/blink/common/message_port/string_message_codec_unittest.cc3
-rw-r--r--chromium/third_party/blink/common/message_port/transferable_message_struct_traits.cc3
-rw-r--r--chromium/third_party/blink/common/message_port/transferable_message_struct_traits.h5
-rw-r--r--chromium/third_party/blink/common/oom_intervention/oom_intervention_types.h25
-rw-r--r--chromium/third_party/blink/common/service_worker/service_worker_status_code.cc2
-rw-r--r--chromium/third_party/blink/common/service_worker/service_worker_utils.cc5
-rw-r--r--chromium/third_party/blink/public/BUILD.gn45
-rw-r--r--chromium/third_party/blink/public/OWNERS1
-rw-r--r--chromium/third_party/blink/public/blink_typemaps.gni1
-rw-r--r--chromium/third_party/blink/public/common/BUILD.gn30
-rw-r--r--chromium/third_party/blink/public/common/associated_interfaces/associated_interface_provider.h55
-rw-r--r--chromium/third_party/blink/public/common/associated_interfaces/associated_interface_registry.h27
-rw-r--r--chromium/third_party/blink/public/common/cache_storage/OWNERS7
-rw-r--r--chromium/third_party/blink/public/common/cache_storage/cache_storage_utils.h24
-rw-r--r--chromium/third_party/blink/public/common/features.h14
-rw-r--r--chromium/third_party/blink/public/common/font_unique_name_lookup/font_table_matcher.h63
-rw-r--r--chromium/third_party/blink/public/common/font_unique_name_lookup/font_unique_name_table.proto23
-rw-r--r--chromium/third_party/blink/public/common/font_unique_name_lookup/icu_fold_case_util.h21
-rw-r--r--chromium/third_party/blink/public/common/indexeddb/OWNERS9
-rw-r--r--chromium/third_party/blink/public/common/indexeddb/indexeddb.typemap29
-rw-r--r--chromium/third_party/blink/public/common/indexeddb/indexeddb_key.h81
-rw-r--r--chromium/third_party/blink/public/common/indexeddb/indexeddb_key_path.h44
-rw-r--r--chromium/third_party/blink/public/common/indexeddb/indexeddb_key_range.h42
-rw-r--r--chromium/third_party/blink/public/common/indexeddb/indexeddb_metadata.h95
-rw-r--r--chromium/third_party/blink/public/common/indexeddb/indexeddb_struct_traits.h197
-rw-r--r--chromium/third_party/blink/public/common/indexeddb/web_idb_types.h (renamed from chromium/third_party/blink/public/platform/modules/indexeddb/web_idb_types.h)8
-rw-r--r--chromium/third_party/blink/public/common/manifest/manifest.h17
-rw-r--r--chromium/third_party/blink/public/common/manifest/manifest_mojom_traits.h28
-rw-r--r--chromium/third_party/blink/public/common/manifest/manifest_share_target_util.h38
-rw-r--r--chromium/third_party/blink/public/common/message_port/cloneable_message.h7
-rw-r--r--chromium/third_party/blink/public/common/message_port/transferable_message.h4
-rw-r--r--chromium/third_party/blink/public/common/oom_intervention/oom_intervention_types.h34
-rw-r--r--chromium/third_party/blink/public/common/picture_in_picture/picture_in_picture_control_info.h38
-rw-r--r--chromium/third_party/blink/public/common/service_worker/service_worker_status_code.h7
-rw-r--r--chromium/third_party/blink/public/common/service_worker/service_worker_utils.h2
-rw-r--r--chromium/third_party/blink/public/mojom/BUILD.gn36
-rw-r--r--chromium/third_party/blink/public/mojom/associated_interfaces/OWNERS2
-rw-r--r--chromium/third_party/blink/public/mojom/associated_interfaces/associated_interfaces.mojom15
-rw-r--r--chromium/third_party/blink/public/mojom/crash/OWNERS5
-rw-r--r--chromium/third_party/blink/public/mojom/crash/crash_memory_metrics_reporter.mojom16
-rw-r--r--chromium/third_party/blink/public/mojom/dom_storage/OWNERS3
-rw-r--r--chromium/third_party/blink/public/mojom/dom_storage/storage_area.mojom10
-rw-r--r--chromium/third_party/blink/public/mojom/fetch/OWNERS7
-rw-r--r--chromium/third_party/blink/public/mojom/fetch/README.md2
-rw-r--r--chromium/third_party/blink/public/mojom/fetch/fetch_api_response.mojom (renamed from chromium/third_party/blink/public/platform/modules/fetch/fetch_api_response.mojom)22
-rw-r--r--chromium/third_party/blink/public/mojom/filesystem/OWNERS7
-rw-r--r--chromium/third_party/blink/public/mojom/filesystem/file_system.mojom227
-rw-r--r--chromium/third_party/blink/public/mojom/filesystem/file_writer.mojom24
-rw-r--r--chromium/third_party/blink/public/mojom/frame/find_in_page.mojom78
-rw-r--r--chromium/third_party/blink/public/mojom/indexeddb/OWNERS7
-rw-r--r--chromium/third_party/blink/public/mojom/indexeddb/indexeddb.mojom360
-rw-r--r--chromium/third_party/blink/public/mojom/loader/navigation_predictor.mojom49
-rw-r--r--chromium/third_party/blink/public/mojom/manifest/manifest.mojom16
-rw-r--r--chromium/third_party/blink/public/mojom/message_port/message_port.mojom7
-rw-r--r--chromium/third_party/blink/public/mojom/message_port/user_activation_snapshot.mojom12
-rw-r--r--chromium/third_party/blink/public/mojom/payments/OWNERS10
-rw-r--r--chromium/third_party/blink/public/mojom/payments/payment_app.mojom (renamed from chromium/third_party/blink/public/platform/modules/payments/payment_app.mojom)2
-rw-r--r--chromium/third_party/blink/public/mojom/payments/payment_request.mojom (renamed from chromium/third_party/blink/public/platform/modules/payments/payment_request.mojom)9
-rw-r--r--chromium/third_party/blink/public/mojom/portal/OWNERS2
-rw-r--r--chromium/third_party/blink/public/mojom/portal/portal.mojom19
-rw-r--r--chromium/third_party/blink/public/mojom/presentation/OWNERS5
-rw-r--r--chromium/third_party/blink/public/mojom/presentation/presentation.mojom (renamed from chromium/third_party/blink/public/platform/modules/presentation/presentation.mojom)65
-rw-r--r--chromium/third_party/blink/public/mojom/service_worker/service_worker_fetch_response_callback.mojom28
-rw-r--r--chromium/third_party/blink/public/mojom/usb/BUILD.gn36
-rw-r--r--chromium/third_party/blink/public/mojom/usb/OWNERS2
-rw-r--r--chromium/third_party/blink/public/mojom/usb/web_usb_service.mojom32
-rw-r--r--chromium/third_party/blink/public/mojom/webaudio/OWNERS6
-rw-r--r--chromium/third_party/blink/public/mojom/webaudio/audio_context_manager.mojom19
-rw-r--r--chromium/third_party/blink/public/platform/DEPS2
-rw-r--r--chromium/third_party/blink/public/platform/OWNERS2
-rw-r--r--chromium/third_party/blink/public/platform/autoplay.mojom4
-rw-r--r--chromium/third_party/blink/public/platform/code_cache_loader.h33
-rw-r--r--chromium/third_party/blink/public/platform/mac/web_scrollbar_theme.h21
-rw-r--r--chromium/third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom59
-rw-r--r--chromium/third_party/blink/public/platform/modules/background_fetch/web_background_fetch_registration.h50
-rw-r--r--chromium/third_party/blink/public/platform/modules/background_fetch/web_background_fetch_settled_fetch.h27
-rw-r--r--chromium/third_party/blink/public/platform/modules/budget_service/OWNERS7
-rw-r--r--chromium/third_party/blink/public/platform/modules/budget_service/budget_service.mojom39
-rw-r--r--chromium/third_party/blink/public/platform/modules/cache_storage/cache_storage.mojom16
-rw-r--r--chromium/third_party/blink/public/platform/modules/device_orientation/OWNERS4
-rw-r--r--chromium/third_party/blink/public/platform/modules/device_orientation/web_device_motion_listener.h50
-rw-r--r--chromium/third_party/blink/public/platform/modules/device_orientation/web_device_orientation_listener.h52
-rw-r--r--chromium/third_party/blink/public/platform/modules/font_unique_name_lookup/OWNERS4
-rw-r--r--chromium/third_party/blink/public/platform/modules/font_unique_name_lookup/font_unique_name_lookup.mojom17
-rw-r--r--chromium/third_party/blink/public/platform/modules/indexeddb/web_idb_cursor.h8
-rw-r--r--chromium/third_party/blink/public/platform/modules/indexeddb/web_idb_database.h2
-rw-r--r--chromium/third_party/blink/public/platform/modules/indexeddb/web_idb_factory.h1
-rw-r--r--chromium/third_party/blink/public/platform/modules/indexeddb/web_idb_key.h2
-rw-r--r--chromium/third_party/blink/public/platform/modules/indexeddb/web_idb_key_path.h2
-rw-r--r--chromium/third_party/blink/public/platform/modules/indexeddb/web_idb_observation.h2
-rw-r--r--chromium/third_party/blink/public/platform/modules/locks/lock_manager.mojom2
-rw-r--r--chromium/third_party/blink/public/platform/modules/notifications/notification.mojom12
-rw-r--r--chromium/third_party/blink/public/platform/modules/notifications/notification_types.typemap16
-rw-r--r--chromium/third_party/blink/public/platform/modules/notifications/web_notification_data.h7
-rw-r--r--chromium/third_party/blink/public/platform/modules/notifications/web_notification_resources.h34
-rw-r--r--chromium/third_party/blink/public/platform/modules/presentation/OWNERS3
-rw-r--r--chromium/third_party/blink/public/platform/modules/service_worker/web_service_worker_request.h3
-rw-r--r--chromium/third_party/blink/public/platform/modules/webauthn/OWNERS (renamed from chromium/third_party/blink/public/platform/modules/webauth/OWNERS)0
-rw-r--r--chromium/third_party/blink/public/platform/modules/webauthn/authenticator.mojom (renamed from chromium/third_party/blink/public/platform/modules/webauth/authenticator.mojom)9
-rw-r--r--chromium/third_party/blink/public/platform/modules/webauthn/virtual_authenticator.mojom (renamed from chromium/third_party/blink/public/platform/modules/webauth/virtual_authenticator.mojom)2
-rw-r--r--chromium/third_party/blink/public/platform/oom_intervention.mojom18
-rw-r--r--chromium/third_party/blink/public/platform/platform.h131
-rw-r--r--chromium/third_party/blink/public/platform/reporting.mojom11
-rw-r--r--chromium/third_party/blink/public/platform/scheduler/child/webthread_base.h2
-rw-r--r--chromium/third_party/blink/public/platform/scheduler/web_rail_mode_observer.h23
-rw-r--r--chromium/third_party/blink/public/platform/scheduler/web_thread_scheduler.h12
-rw-r--r--chromium/third_party/blink/public/platform/task_type.h3
-rw-r--r--chromium/third_party/blink/public/platform/web_content_security_policy.h4
-rw-r--r--chromium/third_party/blink/public/platform/web_cors.h14
-rw-r--r--chromium/third_party/blink/public/platform/web_feature.mojom26
-rw-r--r--chromium/third_party/blink/public/platform/web_file_system.h30
-rw-r--r--chromium/third_party/blink/public/platform/web_gamepad_listener.h18
-rw-r--r--chromium/third_party/blink/public/platform/web_graphics_context_3d_provider.h6
-rw-r--r--chromium/third_party/blink/public/platform/web_input_event.h7
-rw-r--r--chromium/third_party/blink/public/platform/web_layer_tree_view.h5
-rw-r--r--chromium/third_party/blink/public/platform/web_localized_string.h2
-rw-r--r--chromium/third_party/blink/public/platform/web_media_constraints.h28
-rw-r--r--chromium/third_party/blink/public/platform/web_media_player.h64
-rw-r--r--chromium/third_party/blink/public/platform/web_media_stream_source.h7
-rw-r--r--chromium/third_party/blink/public/platform/web_media_stream_track.h10
-rw-r--r--chromium/third_party/blink/public/platform/web_platform_event_type.h19
-rw-r--r--chromium/third_party/blink/public/platform/web_rtc_api_name.h1
-rw-r--r--chromium/third_party/blink/public/platform/web_rtc_certificate.h79
-rw-r--r--chromium/third_party/blink/public/platform/web_rtc_certificate_generator.h8
-rw-r--r--chromium/third_party/blink/public/platform/web_rtc_configuration.h72
-rw-r--r--chromium/third_party/blink/public/platform/web_rtc_peer_connection_handler.h18
-rw-r--r--chromium/third_party/blink/public/platform/web_rtc_peer_connection_handler_client.h1
-rw-r--r--chromium/third_party/blink/public/platform/web_runtime_features.h13
-rw-r--r--chromium/third_party/blink/public/platform/web_scoped_virtual_time_pauser.h14
-rw-r--r--chromium/third_party/blink/public/platform/web_scroll_into_view_params.h12
-rw-r--r--chromium/third_party/blink/public/platform/web_url_request.h11
-rw-r--r--chromium/third_party/blink/public/platform/web_url_response.h9
-rw-r--r--chromium/third_party/blink/public/platform/web_vector.h9
-rw-r--r--chromium/third_party/blink/public/platform/web_video_frame_submitter.h18
-rw-r--r--chromium/third_party/blink/public/platform/web_worker_fetch_context.h8
-rw-r--r--chromium/third_party/blink/public/public_typemaps.gni1
-rw-r--r--chromium/third_party/blink/public/web/DEPS6
-rw-r--r--chromium/third_party/blink/public/web/blink.h16
-rw-r--r--chromium/third_party/blink/public/web/devtools_agent.mojom25
-rw-r--r--chromium/third_party/blink/public/web/modules/service_worker/web_service_worker_context_client.h11
-rw-r--r--chromium/third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h22
-rw-r--r--chromium/third_party/blink/public/web/web_associated_url_loader_options.h16
-rw-r--r--chromium/third_party/blink/public/web/web_ax_context.h31
-rw-r--r--chromium/third_party/blink/public/web/web_ax_object.h16
-rw-r--r--chromium/third_party/blink/public/web/web_document_loader.h7
-rw-r--r--chromium/third_party/blink/public/web/web_file_chooser_params.h17
-rw-r--r--chromium/third_party/blink/public/web/web_find_options.h17
-rw-r--r--chromium/third_party/blink/public/web/web_frame_widget.h9
-rw-r--r--chromium/third_party/blink/public/web/web_hit_test_result.h4
-rw-r--r--chromium/third_party/blink/public/web/web_ime_text_span.h8
-rw-r--r--chromium/third_party/blink/public/web/web_local_frame.h62
-rw-r--r--chromium/third_party/blink/public/web/web_local_frame_client.h34
-rw-r--r--chromium/third_party/blink/public/web/web_navigation_params.h30
-rw-r--r--chromium/third_party/blink/public/web/web_navigation_timings.h1
-rw-r--r--chromium/third_party/blink/public/web/web_performance.h1
-rw-r--r--chromium/third_party/blink/public/web/web_plugin_container.h5
-rw-r--r--chromium/third_party/blink/public/web/web_print_params.h38
-rw-r--r--chromium/third_party/blink/public/web/web_remote_frame_client.h6
-rw-r--r--chromium/third_party/blink/public/web/web_security_policy.h27
-rw-r--r--chromium/third_party/blink/public/web/web_settings.h11
-rw-r--r--chromium/third_party/blink/public/web/web_user_media_request.h6
-rw-r--r--chromium/third_party/blink/public/web/web_view.h22
-rw-r--r--chromium/third_party/blink/public/web/web_view_client.h8
-rw-r--r--chromium/third_party/blink/public/web/web_widget.h8
-rw-r--r--chromium/third_party/blink/public/web/web_widget_client.h3
-rw-r--r--chromium/third_party/blink/renderer/DEPS5
-rw-r--r--chromium/third_party/blink/renderer/README.md6
-rw-r--r--chromium/third_party/blink/renderer/bindings/IDLExtendedAttributes.md10
-rw-r--r--chromium/third_party/blink/renderer/bindings/IDLExtendedAttributes.txt1
-rw-r--r--chromium/third_party/blink/renderer/bindings/bindings.gni11
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/BUILD.gn18
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/activity_logger_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/array_value.cc4
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/array_value.h4
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_message_event_custom.cc4
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_window_custom.cc2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/custom_wrappable_adapter.cc79
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/custom_wrappable_adapter.h63
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/generated_code_helper.cc6
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc12
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/referrer_script_info.cc25
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/rejected_promises.cc4
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_event_listener.cc7
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_event_listener.h9
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_function.cc15
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_function.h24
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_promise.cc28
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_promise.h3
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.cc38
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h14
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_source_code.cc17
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_source_code.h16
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_streamer.cc270
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_streamer.h53
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_streamer_test.cc141
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_streamer_thread.cc19
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_wrappable_marking_visitor_test.cc344
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_wrappable_v8_gc_integration_test.cc133
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_wrappable_visitor_test.cc5
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.cc103
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.h50
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialization_tag.h2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.cc13
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h15
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_threaded_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/serialization/transferables.h3
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc10
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.cc39
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.h3
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc46
-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_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/use_counter_callback.cc6
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_abstract_event_listener.cc44
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_abstract_event_listener.h21
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_code_cache.cc17
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_code_cache.h4
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_context_snapshot.cc11
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_dom_configuration.cc170
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_dom_configuration.h26
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_embedder_graph_builder.cc7
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_error_handler.cc24
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_error_handler.h11
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener_helper.cc52
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener_helper.h20
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener_or_event_handler.cc (renamed from chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener.cc)20
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener_or_event_handler.h (renamed from chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener.h)30
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_gc_controller.cc32
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_gc_for_context_dispose.cc11
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_gc_for_context_dispose.h9
-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_lazy_event_listener.cc7
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc10
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_script_runner_test.cc9
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_wasm_response_extensions.cc204
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_worker_or_worklet_event_listener.cc113
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_worker_or_worklet_event_listener.h67
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc34
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h7
-rw-r--r--chromium/third_party/blink/renderer/bindings/modules/BUILD.gn10
-rw-r--r--chromium/third_party/blink/renderer/bindings/modules/v8/BUILD.gn16
-rw-r--r--chromium/third_party/blink/renderer/bindings/modules/v8/generated.gni2
-rw-r--r--chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.cc14
-rw-r--r--chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules.cc7
-rw-r--r--chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules_test.cc32
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/idl_types.py15
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/v8_attributes.py27
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/v8_callback_function.py20
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/v8_callback_interface.py15
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/v8_interface.py4
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/v8_methods.py7
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/v8_types.py33
-rw-r--r--chromium/third_party/blink/renderer/bindings/templates/attributes.cpp.tmpl3
-rw-r--r--chromium/third_party/blink/renderer/bindings/templates/callback_function.cpp.tmpl129
-rw-r--r--chromium/third_party/blink/renderer/bindings/templates/callback_function.h.tmpl15
-rw-r--r--chromium/third_party/blink/renderer/bindings/templates/callback_interface.cpp.tmpl144
-rw-r--r--chromium/third_party/blink/renderer/bindings/templates/callback_invoke.cc.tmpl229
-rw-r--r--chromium/third_party/blink/renderer/bindings/templates/interface.cpp.tmpl9
-rw-r--r--chromium/third_party/blink/renderer/bindings/templates/interface_base.cpp.tmpl34
-rw-r--r--chromium/third_party/blink/renderer/bindings/templates/methods.cpp.tmpl76
-rw-r--r--chromium/third_party/blink/renderer/bindings/templates/templates.gni3
-rw-r--r--chromium/third_party/blink/renderer/bindings/templates/union_container.cpp.tmpl2
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/core/css/templates/cssom_types.cc.tmpl40
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/core/css/templates/style_property_shorthand.cc.tmpl3
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/templates/InstrumentingProbesInl.h.tmpl1
-rw-r--r--chromium/third_party/blink/renderer/controller/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/controller/blink_initializer.cc34
-rw-r--r--chromium/third_party/blink/renderer/controller/crash_memory_metrics_reporter_impl.cc161
-rw-r--r--chromium/third_party/blink/renderer/controller/crash_memory_metrics_reporter_impl.h55
-rw-r--r--chromium/third_party/blink/renderer/controller/oom_intervention_impl.cc152
-rw-r--r--chromium/third_party/blink/renderer/controller/oom_intervention_impl.h26
-rw-r--r--chromium/third_party/blink/renderer/controller/oom_intervention_impl_test.cc118
-rw-r--r--chromium/third_party/blink/renderer/core/BUILD.gn91
-rw-r--r--chromium/third_party/blink/renderer/core/DEPS13
-rw-r--r--chromium/third_party/blink/renderer/core/OWNERS1
-rw-r--r--chromium/third_party/blink/renderer/core/accessibility/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/core/accessibility/ax_context.cc28
-rw-r--r--chromium/third_party/blink/renderer/core/accessibility/ax_context.h38
-rw-r--r--chromium/third_party/blink/renderer/core/accessibility/ax_object_cache.cc24
-rw-r--r--chromium/third_party/blink/renderer/core/accessibility/ax_object_cache.h18
-rw-r--r--chromium/third_party/blink/renderer/core/animation/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animatable/animatable_double.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animatable/animatable_double.h8
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animatable/animatable_filter_operations.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animatable/animatable_filter_operations.h12
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animatable/animatable_transform.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animatable/animatable_transform.h11
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animatable/animatable_value.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animatable/animatable_value.h30
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animation.cc43
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animation.h6
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animation_effect.cc45
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animation_effect.h4
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animation_effect_test.cc61
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animation_sim_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animation_test.cc61
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animation_time_delta.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animation_time_delta.h127
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animation_time_delta_test.cc91
-rw-r--r--chromium/third_party/blink/renderer/core/animation/base_keyframe.idl4
-rw-r--r--chromium/third_party/blink/renderer/core/animation/base_property_indexed_keyframe.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/compositor_animations.cc47
-rw-r--r--chromium/third_party/blink/renderer/core/animation/compositor_animations.h3
-rw-r--r--chromium/third_party/blink/renderer/core/animation/compositor_animations_test.cc755
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css/css_animatable_value_factory.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css/css_animatable_value_factory.h4
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css/css_animation_update.h4
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css/css_animations.cc60
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css/css_animations.h5
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css/css_animations_test.cc33
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_image_list_interpolation_type.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_interpolation_types_map.cc3
-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_shadow_list_interpolation_type.cc7
-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/document_animations.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/document_animations.h2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/document_timeline.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/animation/document_timeline_test.cc21
-rw-r--r--chromium/third_party/blink/renderer/core/animation/effect_input.cc50
-rw-r--r--chromium/third_party/blink/renderer/core/animation/effect_model.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/animation/effect_model.h7
-rw-r--r--chromium/third_party/blink/renderer/core/animation/effect_stack.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/animation/effect_stack_test.cc52
-rw-r--r--chromium/third_party/blink/renderer/core/animation/element_animation.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/animation/inert_effect.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/inert_effect.h3
-rw-r--r--chromium/third_party/blink/renderer/core/animation/interpolable_value_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/animation/interpolation.h14
-rw-r--r--chromium/third_party/blink/renderer/core/animation/interpolation_effect.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/animation/interpolation_effect.h31
-rw-r--r--chromium/third_party/blink/renderer/core/animation/interpolation_effect_test.cc73
-rw-r--r--chromium/third_party/blink/renderer/core/animation/invalidatable_interpolation.h31
-rw-r--r--chromium/third_party/blink/renderer/core/animation/keyframe.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/animation/keyframe.h40
-rw-r--r--chromium/third_party/blink/renderer/core/animation/keyframe_effect.cc72
-rw-r--r--chromium/third_party/blink/renderer/core/animation/keyframe_effect.h4
-rw-r--r--chromium/third_party/blink/renderer/core/animation/keyframe_effect.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/keyframe_effect_model.cc44
-rw-r--r--chromium/third_party/blink/renderer/core/animation/keyframe_effect_model.h35
-rw-r--r--chromium/third_party/blink/renderer/core/animation/keyframe_effect_model_test.cc63
-rw-r--r--chromium/third_party/blink/renderer/core/animation/keyframe_effect_test.cc69
-rw-r--r--chromium/third_party/blink/renderer/core/animation/list_interpolation_functions.cc25
-rw-r--r--chromium/third_party/blink/renderer/core/animation/list_interpolation_functions.h19
-rw-r--r--chromium/third_party/blink/renderer/core/animation/sampled_effect.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/animation/sampled_effect.h6
-rw-r--r--chromium/third_party/blink/renderer/core/animation/string_keyframe.cc28
-rw-r--r--chromium/third_party/blink/renderer/core/animation/string_keyframe.h47
-rw-r--r--chromium/third_party/blink/renderer/core/animation/timing.h5
-rw-r--r--chromium/third_party/blink/renderer/core/animation/timing_calculations.h42
-rw-r--r--chromium/third_party/blink/renderer/core/animation/timing_calculations_test.cc37
-rw-r--r--chromium/third_party/blink/renderer/core/animation/timing_input_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/transition_interpolation.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/animation/transition_interpolation.h50
-rw-r--r--chromium/third_party/blink/renderer/core/animation/transition_keyframe.cc21
-rw-r--r--chromium/third_party/blink/renderer/core/animation/transition_keyframe.h43
-rw-r--r--chromium/third_party/blink/renderer/core/aom/computed_accessible_node.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/aom/computed_accessible_node.h3
-rw-r--r--chromium/third_party/blink/renderer/core/clipboard/BUILD.gn1
-rw-r--r--chromium/third_party/blink/renderer/core/clipboard/data_object.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/clipboard/data_object.h6
-rw-r--r--chromium/third_party/blink/renderer/core/clipboard/data_object_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/clipboard/data_transfer.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/clipboard/data_transfer_item_list.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/clipboard/data_transfer_item_list.h6
-rw-r--r--chromium/third_party/blink/renderer/core/clipboard/paste_mode.h (renamed from chromium/third_party/blink/renderer/platform/paste_mode.h)6
-rw-r--r--chromium/third_party/blink/renderer/core/core.gni6
-rw-r--r--chromium/third_party/blink/renderer/core/core_idl_files.gni10
-rw-r--r--chromium/third_party/blink/renderer/core/core_initializer.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/css/CSSProperties.json570
-rw-r--r--chromium/third_party/blink/renderer/core/css/CSSValueKeywords.json518
-rw-r--r--chromium/third_party/blink/renderer/core/css/ComputedStyleDiffFunctions.json55
-rw-r--r--chromium/third_party/blink/renderer/core/css/SVGCSSValueKeywords.json514
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_computed_style_declaration_test.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_gradient_value.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_image_set_value.cc8
-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.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_image_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_primitive_value_mappings.h36
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_style_sheet.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_style_sheet.h15
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_style_sheet.idl3
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_style_sheet_test.cc44
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_syntax_descriptor.cc61
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_syntax_descriptor.h4
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_value.h6
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_style_value.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/cssom_types.h18
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/inline_style_property_map.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/style_property_map.cc57
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/style_value_factory.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/style_value_factory.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/element_rule_collector.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/css/element_rule_collector.h30
-rw-r--r--chromium/third_party/blink/renderer/core/css/font_face_cache_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/css/font_face_set.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/css/html.css8
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_lazy_parsing_state.cc62
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_lazy_parsing_state.h35
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_lazy_parsing_test.cc68
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_lazy_property_parser_impl.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_parser_fast_paths.cc29
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_parser_impl.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_parser_token_range.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/longhands/clear_custom.cc22
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/longhands/float_custom.cc22
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/longhands/resize_custom.cc29
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_block_end_custom.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_block_start_custom.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_bottom_custom.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_inline_end_custom.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_inline_start_custom.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_left_custom.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_right_custom.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_top_custom.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_block_end_custom.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_block_start_custom.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_bottom_custom.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_inline_end_custom.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_inline_start_custom.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_left_custom.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_right_custom.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_top_custom.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/shorthands/border_block_color_custom.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/shorthands/border_block_custom.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/shorthands/border_block_style_custom.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/shorthands/border_block_width_custom.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/shorthands/border_inline_color_custom.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/shorthands/border_inline_custom.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/shorthands/border_inline_style_custom.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/shorthands/border_inline_width_custom.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/shorthands/inset_block_custom.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/shorthands/inset_custom.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/shorthands/inset_inline_custom.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/shorthands/margin_block_custom.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/shorthands/margin_inline_custom.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/shorthands/padding_block_custom.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/shorthands/padding_inline_custom.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/css/property_registration.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/css/property_registration.h7
-rw-r--r--chromium/third_party/blink/renderer/core/css/property_registry.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/css/property_registry.h11
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/css_variable_resolver.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/css_variable_resolver.h4
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/css_variable_resolver_test.cc161
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/element_style_resources.cc65
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/element_style_resources.h8
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/font_builder.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/scoped_style_resolver.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/scoped_style_resolver.h20
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/scoped_style_resolver_test.cc89
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/style_adjuster.cc127
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/style_resolver.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/style_resolver.h4
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/selector_checker.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/css/selector_checker.h2
-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_engine.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_engine_test.cc103
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_property_serializer.cc45
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_property_serializer.h4
-rw-r--r--chromium/third_party/blink/renderer/core/css/themeWin.css54
-rw-r--r--chromium/third_party/blink/renderer/core/dom/BUILD.gn3
-rw-r--r--chromium/third_party/blink/renderer/core/dom/README.md341
-rw-r--r--chromium/third_party/blink/renderer/core/dom/abort_signal.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/dom/character_data.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/dom/character_data.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/comment.h3
-rw-r--r--chromium/third_party/blink/renderer/core/dom/common_definitions.idl6
-rw-r--r--chromium/third_party/blink/renderer/core/dom/container_node.cc78
-rw-r--r--chromium/third_party/blink/renderer/core/dom/container_node.h4
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document.cc387
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document.h59
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document.idl4
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document_init.cc89
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document_init.h20
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document_type.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document_type.h5
-rw-r--r--chromium/third_party/blink/renderer/core/dom/dom_implementation.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/dom/dom_string_list.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/dom_string_list.h4
-rw-r--r--chromium/third_party/blink/renderer/core/dom/element.cc514
-rw-r--r--chromium/third_party/blink/renderer/core/dom/element.h33
-rw-r--r--chromium/third_party/blink/renderer/core/dom/element.idl4
-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/event.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event.h26
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event_dispatcher.cc44
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event_dispatcher.h6
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event_listener.h19
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event_listener_map.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event_path.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event_path.h4
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event_queue.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event_queue.h4
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event_target.cc172
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event_target.h18
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/scoped_event_queue.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/scoped_event_queue.h4
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/tree_scope_event_context.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/window_event_context.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/window_event_context.h3
-rw-r--r--chromium/third_party/blink/renderer/core/dom/first_letter_pseudo_element.cc102
-rw-r--r--chromium/third_party/blink/renderer/core/dom/first_letter_pseudo_element.h8
-rw-r--r--chromium/third_party/blink/renderer/core/dom/flat_tree_traversal.cc120
-rw-r--r--chromium/third_party/blink/renderer/core/dom/flat_tree_traversal.h30
-rw-r--r--chromium/third_party/blink/renderer/core/dom/flat_tree_traversal_ng.cc368
-rw-r--r--chromium/third_party/blink/renderer/core/dom/flat_tree_traversal_ng.h331
-rw-r--r--chromium/third_party/blink/renderer/core/dom/flat_tree_traversal_ng_test.cc772
-rw-r--r--chromium/third_party/blink/renderer/core/dom/flat_tree_traversal_test.cc139
-rw-r--r--chromium/third_party/blink/renderer/core/dom/global_event_handlers.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/global_event_handlers.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/idle_deadline_test.cc33
-rw-r--r--chromium/third_party/blink/renderer/core/dom/ignore_opens_during_unload_count_incrementer.h39
-rw-r--r--chromium/third_party/blink/renderer/core/dom/layout_tree_builder.cc28
-rw-r--r--chromium/third_party/blink/renderer/core/dom/layout_tree_builder.h5
-rw-r--r--chromium/third_party/blink/renderer/core/dom/layout_tree_builder_traversal.cc99
-rw-r--r--chromium/third_party/blink/renderer/core/dom/layout_tree_builder_traversal.h1
-rw-r--r--chromium/third_party/blink/renderer/core/dom/layout_tree_builder_traversal_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/dom/named_node_map.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/dom/named_node_map.h4
-rw-r--r--chromium/third_party/blink/renderer/core/dom/node.cc91
-rw-r--r--chromium/third_party/blink/renderer/core/dom/node.h18
-rw-r--r--chromium/third_party/blink/renderer/core/dom/node_test.cc19
-rw-r--r--chromium/third_party/blink/renderer/core/dom/node_traversal.h10
-rw-r--r--chromium/third_party/blink/renderer/core/dom/processing_instruction.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/dom/processing_instruction.h9
-rw-r--r--chromium/third_party/blink/renderer/core/dom/pseudo_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/pseudo_element_data.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/range.cc29
-rw-r--r--chromium/third_party/blink/renderer/core/dom/range.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/scripted_animation_controller.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/dom/scripted_idle_task_controller_test.cc68
-rw-r--r--chromium/third_party/blink/renderer/core/dom/shadow_root.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/dom/shadow_root.h15
-rw-r--r--chromium/third_party/blink/renderer/core/dom/shadow_root_init.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/slot_assignment.cc84
-rw-r--r--chromium/third_party/blink/renderer/core/dom/slot_assignment.h10
-rw-r--r--chromium/third_party/blink/renderer/core/dom/synchronous_mutation_notifier.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/dom/tree_ordered_map.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/dom/tree_ordered_map.h6
-rw-r--r--chromium/third_party/blink/renderer/core/dom/tree_scope.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/dom/tree_scope.h8
-rw-r--r--chromium/third_party/blink/renderer/core/dom/v0_insertion_point.cc35
-rw-r--r--chromium/third_party/blink/renderer/core/dom/v0_insertion_point.h6
-rw-r--r--chromium/third_party/blink/renderer/core/dom/visited_link_state.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/editing/BUILD.gn14
-rw-r--r--chromium/third_party/blink/renderer/core/editing/caret_display_item_client.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/editing/caret_display_item_client_test.cc57
-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.cc61
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/apply_style_command_test.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/clipboard_commands.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/composite_edit_command.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/delete_selection_command_test.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/document_exec_command.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/editing_commands_utilities.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/editor_command.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/insert_incremental_text_command_test.cc30
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/insert_list_command_test.cc23
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/insert_paragraph_separator_command_test.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/insert_text_command_test.cc107
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/move_commands.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/replace_selection_command.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/replace_selection_command_test.cc47
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/split_text_node_command.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/split_text_node_command_test.cc26
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/style_commands.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/typing_command.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/typing_command_test.cc30
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/undo_step.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/editing/compute_layer_selection.cc (renamed from chromium/third_party/blink/renderer/core/editing/rendered_position.cc)114
-rw-r--r--chromium/third_party/blink/renderer/core/editing/compute_layer_selection.h (renamed from chromium/third_party/blink/renderer/core/editing/rendered_position.h)16
-rw-r--r--chromium/third_party/blink/renderer/core/editing/compute_layer_selection_test.cc (renamed from chromium/third_party/blink/renderer/core/editing/rendered_position_test.cc)135
-rw-r--r--chromium/third_party/blink/renderer/core/editing/editing_utilities.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/editing/editing_utilities_test.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/editing/editor.cc33
-rw-r--r--chromium/third_party/blink/renderer/core/editing/editor.h9
-rw-r--r--chromium/third_party/blink/renderer/core/editing/editor_key_bindings.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/editing/editor_test.cc40
-rw-r--r--chromium/third_party/blink/renderer/core/editing/element_inner_text.cc691
-rw-r--r--chromium/third_party/blink/renderer/core/editing/element_inner_text_test.cc40
-rw-r--r--chromium/third_party/blink/renderer/core/editing/finder/find_options.h15
-rw-r--r--chromium/third_party/blink/renderer/core/editing/finder/text_finder.cc161
-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.cc59
-rw-r--r--chromium/third_party/blink/renderer/core/editing/frame_selection.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/editing/frame_selection.h30
-rw-r--r--chromium/third_party/blink/renderer/core/editing/frame_selection_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/editing/granularity_strategy.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/editing/granularity_strategy_test.cc64
-rw-r--r--chromium/third_party/blink/renderer/core/editing/ime/ime_text_span.cc2
-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.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/ime/input_method_controller.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/editing/ime/input_method_controller_test.cc76
-rw-r--r--chromium/third_party/blink/renderer/core/editing/inline_box_position.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/editing/inline_box_position.h5
-rw-r--r--chromium/third_party/blink/renderer/core/editing/iterators/search_buffer.cc47
-rw-r--r--chromium/third_party/blink/renderer/core/editing/iterators/search_buffer.h4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/iterators/text_iterator_behavior.h1
-rw-r--r--chromium/third_party/blink/renderer/core/editing/layout_selection.cc660
-rw-r--r--chromium/third_party/blink/renderer/core/editing/layout_selection.h75
-rw-r--r--chromium/third_party/blink/renderer/core/editing/layout_selection_test.cc1165
-rw-r--r--chromium/third_party/blink/renderer/core/editing/local_caret_rect.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/editing/local_caret_rect.h1
-rw-r--r--chromium/third_party/blink/renderer/core/editing/local_caret_rect_test.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/active_suggestion_marker.cc2
-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.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/active_suggestion_marker_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/composition_marker.cc2
-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.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/composition_marker_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/document_marker.h39
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/document_marker_controller.cc125
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/document_marker_controller.h25
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/document_marker_controller_test.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/styleable_marker.cc2
-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_properties.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker_properties.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/selection_controller.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/editing/selection_editor.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/editing/selection_modifier.cc51
-rw-r--r--chromium/third_party/blink/renderer/core/editing/selection_modifier_character.cc340
-rw-r--r--chromium/third_party/blink/renderer/core/editing/spellcheck/cold_mode_spell_check_requester.h8
-rw-r--r--chromium/third_party/blink/renderer/core/editing/spellcheck/hot_mode_spell_check_requester.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/editing/spellcheck/hot_mode_spell_check_requester.h4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller.cc (renamed from chromium/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_callback.cc)93
-rw-r--r--chromium/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller.h (renamed from chromium/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_callback.h)46
-rw-r--r--chromium/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller_test.cc (renamed from chromium/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_callback_test.cc)44
-rw-r--r--chromium/third_party/blink/renderer/core/editing/spellcheck/spell_checker.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/editing/spellcheck/spell_checker.h8
-rw-r--r--chromium/third_party/blink/renderer/core/editing/spellcheck/spell_checker_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller.cc24
-rw-r--r--chromium/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller_test.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/editing/web_substring_util.mm2
-rw-r--r--chromium/third_party/blink/renderer/core/events/BUILD.gn1
-rw-r--r--chromium/third_party/blink/renderer/core/events/animation_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/animation_playback_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/application_cache_error_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/application_cache_error_event.h1
-rw-r--r--chromium/third_party/blink/renderer/core/events/before_text_inserted_event.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/events/before_unload_event.h1
-rw-r--r--chromium/third_party/blink/renderer/core/events/drag_event.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/events/error_event.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/events/error_event.h1
-rw-r--r--chromium/third_party/blink/renderer/core/events/event_type_names.json56
-rw-r--r--chromium/third_party/blink/renderer/core/events/focus_event.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/events/keyboard_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/message_event.cc29
-rw-r--r--chromium/third_party/blink/renderer/core/events/message_event.h34
-rw-r--r--chromium/third_party/blink/renderer/core/events/message_event.idl1
-rw-r--r--chromium/third_party/blink/renderer/core/events/message_event_init.idl1
-rw-r--r--chromium/third_party/blink/renderer/core/events/mouse_event.cc30
-rw-r--r--chromium/third_party/blink/renderer/core/events/mouse_event.h19
-rw-r--r--chromium/third_party/blink/renderer/core/events/page_transition_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/pointer_event.cc23
-rw-r--r--chromium/third_party/blink/renderer/core/events/pointer_event.h3
-rw-r--r--chromium/third_party/blink/renderer/core/events/pointer_event_factory.cc23
-rw-r--r--chromium/third_party/blink/renderer/core/events/pointer_event_factory.h7
-rw-r--r--chromium/third_party/blink/renderer/core/events/pop_state_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/progress_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/promise_rejection_event.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/events/registered_event_listener.cc91
-rw-r--r--chromium/third_party/blink/renderer/core/events/registered_event_listener.h62
-rw-r--r--chromium/third_party/blink/renderer/core/events/resource_progress_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/security_policy_violation_event.h1
-rw-r--r--chromium/third_party/blink/renderer/core/events/touch_event.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/events/touch_event_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/events/transition_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/ui_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/events/visual_viewport_resize_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/visual_viewport_scroll_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/wheel_event.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/events/wheel_event.h2
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/execution_context.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/execution_context.h9
-rw-r--r--chromium/third_party/blink/renderer/core/exported/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/core/exported/local_frame_client_impl.cc52
-rw-r--r--chromium/third_party/blink/renderer/core/exported/local_frame_client_impl.h13
-rw-r--r--chromium/third_party/blink/renderer/core/exported/shared_worker_repository_client_impl.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_associated_url_loader_impl.cc29
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_associated_url_loader_impl.h6
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_associated_url_loader_impl_test.cc60
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.cc77
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.h5
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_document.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_document_loader_impl.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_document_loader_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_dom_message_event.cc29
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_drag_data_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_file_chooser_completion_impl.cc76
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_file_chooser_completion_impl.h57
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_form_control_element.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_frame_serializer.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_frame_test.cc813
-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_page_popup_impl.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_performance.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc124
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_plugin_container_impl.h20
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_plugin_container_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_security_policy.cc40
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_settings_impl.cc58
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_settings_impl.h15
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_shared_worker_impl.cc37
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_shared_worker_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_view_impl.cc266
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_view_impl.h23
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_view_test.cc73
-rw-r--r--chromium/third_party/blink/renderer/core/exported/worker_shadow_page.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/exported/worker_shadow_page.h11
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/body_stream_buffer.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/data_consumer_handle_test_util.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/fetch_data_loader.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/fetch_manager.cc107
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/fetch_request_data.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/fetch_request_data.h26
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/fetch_response_data.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/fetch_response_data.h2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/form_data_bytes_consumer.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/global_fetch.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/multipart_parser.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/request.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/request.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/response.h2
-rw-r--r--chromium/third_party/blink/renderer/core/fileapi/file_error.cc88
-rw-r--r--chromium/third_party/blink/renderer/core/fileapi/file_error.h2
-rw-r--r--chromium/third_party/blink/renderer/core/fileapi/file_list_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/fileapi/file_reader.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/fileapi/file_reader_loader.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/frame/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/ad_tracker.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/ad_tracker_test.cc74
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/content_security_policy.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/content_security_policy.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/content_security_policy_fuzzer.cc21
-rw-r--r--chromium/third_party/blink/renderer/core/frame/deprecation.cc82
-rw-r--r--chromium/third_party/blink/renderer/core/frame/device_single_window_event_controller.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/dom_window.cc42
-rw-r--r--chromium/third_party/blink/renderer/core/frame/dom_window.h3
-rw-r--r--chromium/third_party/blink/renderer/core/frame/event_handler_registry.cc19
-rw-r--r--chromium/third_party/blink/renderer/core/frame/event_handler_registry.h3
-rw-r--r--chromium/third_party/blink/renderer/core/frame/feature_policy_violation_report_body.h32
-rw-r--r--chromium/third_party/blink/renderer/core/frame/feature_policy_violation_report_body.idl16
-rw-r--r--chromium/third_party/blink/renderer/core/frame/find_in_page.cc134
-rw-r--r--chromium/third_party/blink/renderer/core/frame/find_in_page.h38
-rw-r--r--chromium/third_party/blink/renderer/core/frame/find_in_page_test.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame.h18
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame_test_helpers.cc46
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame_test_helpers.h4
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame_view_auto_size_info.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/frame/fullscreen_controller.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/frame/fullscreen_controller.h9
-rw-r--r--chromium/third_party/blink/renderer/core/frame/link_highlights.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/frame/link_highlights.h16
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_dom_window.cc86
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_dom_window.h13
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_frame.cc261
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_frame.h63
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_frame_client.h22
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_frame_test.cc58
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_frame_view.cc593
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_frame_view.h96
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_frame_view_test.cc62
-rw-r--r--chromium/third_party/blink/renderer/core/frame/location.cc65
-rw-r--r--chromium/third_party/blink/renderer/core/frame/location.idl32
-rw-r--r--chromium/third_party/blink/renderer/core/frame/mhtml_loading_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/frame/navigator_user_activation.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/page_scale_constraints_set.cc30
-rw-r--r--chromium/third_party/blink/renderer/core/frame/page_scale_constraints_set.h30
-rw-r--r--chromium/third_party/blink/renderer/core/frame/performance_monitor.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/frame/picture_in_picture_controller.h7
-rw-r--r--chromium/third_party/blink/renderer/core/frame/remote_frame.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/frame/remote_frame.h1
-rw-r--r--chromium/third_party/blink/renderer/core/frame/remote_frame_client.h4
-rw-r--r--chromium/third_party/blink/renderer/core/frame/remote_frame_client_impl.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/frame/remote_frame_client_impl.h3
-rw-r--r--chromium/third_party/blink/renderer/core/frame/remote_frame_view.cc87
-rw-r--r--chromium/third_party/blink/renderer/core/frame/remote_frame_view.h1
-rw-r--r--chromium/third_party/blink/renderer/core/frame/reporting_context.cc23
-rw-r--r--chromium/third_party/blink/renderer/core/frame/reporting_context.h3
-rw-r--r--chromium/third_party/blink/renderer/core/frame/root_frame_viewport.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/frame/root_frame_viewport.h4
-rw-r--r--chromium/third_party/blink/renderer/core/frame/root_frame_viewport_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/frame/rotation_viewport_anchor.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/frame/rotation_viewport_anchor.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/settings.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/frame/settings.json570
-rw-r--r--chromium/third_party/blink/renderer/core/frame/smart_clip.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/frame/test_report_body.h28
-rw-r--r--chromium/third_party/blink/renderer/core/frame/test_report_body.idl12
-rw-r--r--chromium/third_party/blink/renderer/core/frame/user_activation.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/frame/user_activation.h12
-rw-r--r--chromium/third_party/blink/renderer/core/frame/viewport_data.h3
-rw-r--r--chromium/third_party/blink/renderer/core/frame/visual_viewport.cc219
-rw-r--r--chromium/third_party/blink/renderer/core/frame/visual_viewport.h29
-rw-r--r--chromium/third_party/blink/renderer/core/frame/visual_viewport.idl1
-rw-r--r--chromium/third_party/blink/renderer/core/frame/visual_viewport_test.cc118
-rw-r--r--chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.cc97
-rw-r--r--chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.h39
-rw-r--r--chromium/third_party/blink/renderer/core/frame/window.idl8
-rw-r--r--chromium/third_party/blink/renderer/core/frame/window_post_message_options.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/window_timers.idl13
-rw-r--r--chromium/third_party/blink/renderer/core/fullscreen/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/core/fullscreen/fullscreen.cc65
-rw-r--r--chromium/third_party/blink/renderer/core/fullscreen/fullscreen_options.idl8
-rw-r--r--chromium/third_party/blink/renderer/core/fullscreen/scoped_allow_fullscreen.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/fullscreen/scoped_allow_fullscreen.h34
-rw-r--r--chromium/third_party/blink/renderer/core/fullscreen/scoped_allow_fullscreen_test.cc48
-rw-r--r--chromium/third_party/blink/renderer/core/html/BUILD.gn4
-rw-r--r--chromium/third_party/blink/renderer/core/html/anchor_element_metrics.cc111
-rw-r--r--chromium/third_party/blink/renderer/core/html/anchor_element_metrics.h34
-rw-r--r--chromium/third_party/blink/renderer/core/html/anchor_element_metrics_sender.cc63
-rw-r--r--chromium/third_party/blink/renderer/core/html/anchor_element_metrics_sender.h31
-rw-r--r--chromium/third_party/blink/renderer/core/html/anchor_element_metrics_test.cc75
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/baselines.idl9
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.cc109
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.h8
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator_test.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h6
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc40
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.h12
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc257
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.h22
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/text_metrics.cc24
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/text_metrics.h10
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/text_metrics.idl4
-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.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/focus_options.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/base_checkable_input_type.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/base_checkable_input_type.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/checkbox_input_type.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/checkbox_input_type.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/chooser_only_temporal_input_type_view.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/chooser_only_temporal_input_type_view.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/clear_button_element.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/clear_button_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/color_chooser_ui_controller.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/color_input_type.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/color_input_type.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/date_time_edit_element.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/date_time_edit_element.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/date_time_field_element.cc28
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/date_time_field_element.h6
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/date_time_field_elements.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/date_time_numeric_field_element.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/date_time_numeric_field_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/date_time_symbolic_field_element.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/date_time_symbolic_field_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/file_chooser.cc62
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/file_chooser.h41
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/file_input_type.cc29
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/file_input_type.h10
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/file_input_type_test.cc42
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_button_element.cc35
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_button_element.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_form_control_element.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_form_control_element.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_form_control_element_test.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_form_control_element_with_state.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_form_control_element_with_state.h8
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_form_element.cc27
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_form_element.h8
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_input_element.cc64
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_input_element.h10
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_input_element_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_label_element.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_label_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_legend_element.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_opt_group_element.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_opt_group_element.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_option_element.cc21
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_option_element.h5
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_select_element.cc155
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_select_element.h16
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_text_area_element.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_text_area_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/image_input_type.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/image_input_type.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/input_type_view.cc31
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/input_type_view.h22
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/keyboard_clickable_input_type_view.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/keyboard_clickable_input_type_view.h6
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/listed_element.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/listed_element.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.h6
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/number_input_type.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/number_input_type.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/picker_indicator_element.cc21
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/picker_indicator_element.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/radio_input_type.cc27
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/radio_input_type.h8
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/range_input_type.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/range_input_type.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/reset_input_type.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/reset_input_type.h2
-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/slider_thumb_element.cc22
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/slider_thumb_element.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/spin_button_element.cc38
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/spin_button_element.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/submit_input_type.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/submit_input_type.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/text_control_element.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/text_control_element.h9
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/text_control_element_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/text_control_inner_elements.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/text_control_inner_elements.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/text_field_input_type.cc56
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/text_field_input_type.h10
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/type_ahead.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/type_ahead.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/type_ahead_test.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_anchor_element.cc68
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_anchor_element.h14
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_anchor_element.idl1
-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_base_element.cc24
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_base_element.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_body_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_body_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_details_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_dialog_element.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_dialog_element.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_element.cc21
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_element.h6
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_element_test.cc21
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_frame_element_base.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_frame_element_base.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_frame_owner_element.cc62
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_frame_owner_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_frame_set_element.cc30
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_frame_set_element.h6
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_frame_set_element.idl1
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_hr_element.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_hr_element.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_hyperlink_element_utils.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_iframe_element.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_iframe_element.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_iframe_element.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_image_element.cc83
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_image_element.h34
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_image_element.idl6
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_image_loader.cc2
-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.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_map_element.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_map_element.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_marquee_element.cc22
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_marquee_element.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_meta_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_meta_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_object_element.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_object_element.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_picture_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_picture_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_plugin_element.cc54
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_plugin_element.h6
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_script_element.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_script_element.h3
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_script_element.idl1
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_slot_element.cc83
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_slot_element.h14
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_slot_element.idl1
-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_source_element.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_style_element.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_style_element.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_summary_element.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_summary_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_tag_names.json55
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_title_element.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_title_element.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/image_document.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/image_document_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/imports/html_import_child.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/html/imports/html_imports_controller.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/html/imports/link_import.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/html/lazy_load_frame_observer.cc65
-rw-r--r--chromium/third_party/blink/renderer/core/html/lazy_load_frame_observer.h16
-rw-r--r--chromium/third_party/blink/renderer/core/html/lazy_load_frame_observer_test.cc359
-rw-r--r--chromium/third_party/blink/renderer/core/html/lazy_load_image_observer.cc258
-rw-r--r--chromium/third_party/blink/renderer/core/html/lazy_load_image_observer.h65
-rw-r--r--chromium/third_party/blink/renderer/core/html/list_item_ordinal.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/autoplay_policy.cc31
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/autoplay_policy.h6
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/autoplay_uma_helper.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/html_media_element.cc67
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/html_media_element.h10
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/html_video_element.cc159
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/html_video_element.h58
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/html_video_element.idl3
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/html_video_element_test.cc67
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector.cc35
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/media_document.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/media_document.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/picture_in_picture_interstitial.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/picture_in_picture_interstitial.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/css_preload_scanner.cc112
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/css_preload_scanner.h40
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/css_preload_scanner_test.cc231
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_parser_idioms.cc26
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_parser_idioms.h6
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_parser_scheduler.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_parser_scheduler.h1
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_resource_preloader.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_resource_preloader.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/preload_request.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/preload_request.h3
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/xss_auditor.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/xss_auditor.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/plugin_document.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/html/portal/html_portal_element.cc80
-rw-r--r--chromium/third_party/blink/renderer/core/html/portal/html_portal_element.h61
-rw-r--r--chromium/third_party/blink/renderer/core/html/portal/html_portal_element.idl10
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/html_track_element.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/html_track_element.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/text_track_container.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/text_track_cue.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/text_track_cue.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/text_track_list.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/vtt/vtt_cue.h2
-rw-r--r--chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc21
-rw-r--r--chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap_options.idl8
-rw-r--r--chromium/third_party/blink/renderer/core/input/event_handler.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/input/event_handler_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/input/event_handling_util.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/input/gesture_manager.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/input/keyboard_event_manager.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/input/mouse_event_manager.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/input/mouse_wheel_event_manager.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/input/pointer_event_manager.cc83
-rw-r--r--chromium/third_party/blink/renderer/core/input/pointer_event_manager.h7
-rw-r--r--chromium/third_party/blink/renderer/core/input/scroll_manager.cc44
-rw-r--r--chromium/third_party/blink/renderer/core/input/scroll_manager.h2
-rw-r--r--chromium/third_party/blink/renderer/core/input/scroll_snap_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/input/touch_event_manager.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/BUILD.gn10
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/DEPS2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/browser_protocol.pdl81
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/dev_tools_host.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_animation_agent.cc44
-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.cc30
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_application_cache_agent.h4
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_audits_agent.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_base_agent.h18
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_css_agent.cc44
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_css_agent.h6
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc57
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_dom_agent.h5
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_dom_debugger_agent.cc181
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_dom_debugger_agent.h10
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.cc103
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.h16
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_emulation_agent.cc280
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_emulation_agent.h17
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_highlight.cc21
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_log_agent.cc68
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_log_agent.h4
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_memory_agent.cc69
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_memory_agent.h1
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_network_agent.cc136
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_network_agent.h13
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc136
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h19
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_page_agent.cc248
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_page_agent.h20
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_performance_agent.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_performance_agent.h4
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_protocol_config.json8
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_session.cc92
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_session.h45
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_session_state.cc114
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_session_state.h277
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_session_state_test.cc259
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_task_runner.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_testing_agent.cc27
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_testing_agent.h34
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_trace_events.cc44
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_trace_events.h4
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_tracing_agent.cc98
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_tracing_agent.h55
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_worker_agent.cc68
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_worker_agent.h8
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/main_thread_debugger.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/thread_debugger.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/worker_inspector_controller.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/worker_inspector_controller.h16
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/worker_thread_debugger.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/worker_thread_debugger.h4
-rw-r--r--chromium/third_party/blink/renderer/core/intersection_observer/intersection_observation.cc27
-rw-r--r--chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer.cc22
-rw-r--r--chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer.h9
-rw-r--r--chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_test.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/invisible_dom/BUILD.gn13
-rw-r--r--chromium/third_party/blink/renderer/core/invisible_dom/OWNERS4
-rw-r--r--chromium/third_party/blink/renderer/core/invisible_dom/activate_invisible_event.cc33
-rw-r--r--chromium/third_party/blink/renderer/core/invisible_dom/activate_invisible_event.h43
-rw-r--r--chromium/third_party/blink/renderer/core/invisible_dom/activate_invisible_event.idl11
-rw-r--r--chromium/third_party/blink/renderer/core/layout/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/api/line_layout_inline.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/api/line_layout_item.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/api/line_layout_text.h7
-rw-r--r--chromium/third_party/blink/renderer/core/layout/api/selection_state.h27
-rw-r--r--chromium/third_party/blink/renderer/core/layout/bidi_run_for_line.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope.idl4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope_proxy.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/flexible_box_algorithm.cc50
-rw-r--r--chromium/third_party/blink/renderer/core/layout/flexible_box_algorithm.h5
-rw-r--r--chromium/third_party/blink/renderer/core/layout/floating_objects.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/fragmentainer_iterator.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/layout/fragmentainer_iterator.h4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/grid.cc444
-rw-r--r--chromium/third_party/blink/renderer/core/layout/grid.h175
-rw-r--r--chromium/third_party/blink/renderer/core/layout/grid_test.cc335
-rw-r--r--chromium/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.cc38
-rw-r--r--chromium/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.h8
-rw-r--r--chromium/third_party/blink/renderer/core/layout/hit_test_request.h1
-rw-r--r--chromium/third_party/blink/renderer/core/layout/hit_test_result.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/intersection_geometry.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/layout/jank_tracker.cc120
-rw-r--r--chromium/third_party/blink/renderer/core/layout/jank_tracker.h11
-rw-r--r--chromium/third_party/blink/renderer/core/layout/jank_tracker_test.cc49
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_analyzer.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_block.cc113
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_block.h26
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_block_flow.cc132
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_block_flow.h19
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_block_flow_line.cc125
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_box.cc476
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_box.h231
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_box_model_object.cc193
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_box_model_object.h49
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_box_model_object_test.cc104
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_box_test.cc41
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_button.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_counter.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_deprecated_flexible_box.cc199
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_deprecated_flexible_box.h4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_details_marker.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_embedded_content.cc48
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_embedded_content.h6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_embedded_object.cc27
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_embedded_object.h5
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_fieldset.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_file_upload_control.cc25
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_file_upload_control.h5
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_flexible_box.cc173
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_flexible_box.h5
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_flow_thread.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_frame.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_frame_set.cc22
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_frame_set.h4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_geometry_map.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_geometry_map_step.h5
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_geometry_map_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_grid.cc92
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_grid.h11
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_html_canvas.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_html_canvas.h3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_iframe.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_image.cc151
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_image.h8
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_inline.cc155
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_inline.h45
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_list_box.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_list_item.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_list_marker.cc48
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_media.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_menu_list.cc27
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_multi_column_flow_thread.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_multi_column_set.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_multi_column_spanner_placeholder.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_object.cc299
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_object.h201
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_object_child_list.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_object_test.cc92
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_paged_flow_thread.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_progress.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_quote.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_replaced.cc95
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_replaced.h8
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_ruby_run.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_ruby_text.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_scrollbar.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_scrollbar_part.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_scrollbar_theme.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_scrollbar_theme.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_slider.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_slider_container.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_state.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_table.cc75
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_table.h5
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_table_box_component.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_table_cell.cc100
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_table_cell.h11
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_table_col.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_table_col.h4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_table_row.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_table_row.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_table_section.cc28
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_table_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_text.cc237
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_text.h61
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_text_combine.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_text_combine.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_text_control.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_text_control_single_line.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_text_fragment.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_text_fragment.h4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_text_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_theme.cc47
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_theme.h4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_theme_default.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_theme_default.h4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_theme_mac.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_theme_mac.mm2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_tree_as_text.cc54
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_video.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_video.h3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_view.cc58
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_view.h11
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_vtt_cue.cc10
-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/breaking_context_inline_headers.h29
-rw-r--r--chromium/third_party/blink/renderer/core/layout/line/ellipsis_box.h6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/line/inline_box.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/layout/line/inline_box.h3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/line/inline_flow_box.cc44
-rw-r--r--chromium/third_party/blink/renderer/core/layout/line/inline_flow_box.h5
-rw-r--r--chromium/third_party/blink/renderer/core/layout/line/inline_iterator.h6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/line/inline_text_box.cc165
-rw-r--r--chromium/third_party/blink/renderer/core/layout/line/inline_text_box.h7
-rw-r--r--chromium/third_party/blink/renderer/core/layout/line/layout_text_info.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/line/line_box_list.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/layout/line/line_box_list.h13
-rw-r--r--chromium/third_party/blink/renderer/core/layout/line/line_breaker.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/line/line_width.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/layout/line/root_inline_box.cc55
-rw-r--r--chromium/third_party/blink/renderer/core/layout/line/root_inline_box.h3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/multi_column_fragmentainer_group.cc39
-rw-r--r--chromium/third_party/blink/renderer/core/layout/multi_column_fragmentainer_group.h17
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.h27
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/exclusions/ng_line_layout_opportunity.h1
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/geometry/ng_box_strut.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/geometry/ng_box_strut.h9
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/geometry/ng_physical_offset_rect.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/geometry/ng_physical_offset_rect.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/geometry/ng_physical_size.h3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/layout_ng_text.h1
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc83
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h18
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_fragment_traversal.cc47
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_fragment_traversal.h8
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.h25
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.h31
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc196
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.h12
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder_test.cc185
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc162
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.h13
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc55
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc170
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h7
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_test.cc34
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.h6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc135
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h7
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.cc26
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.h1
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.cc25
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h18
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_builder.cc364
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_builder.h94
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_test.cc281
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h9
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.cc98
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.h36
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment_test.cc44
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_text_fragment_builder.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_text_fragment_builder.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow.cc46
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/layout_ng_flexible_box.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/layout_ng_flexible_box.h1
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc94
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.h18
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/layout_ng_table_cell.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.h1
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_marker.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_marker_image.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/list/ng_unpositioned_list_marker.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_base_layout_algorithm_test.cc12
-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_child_iterator.h1
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc812
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.h108
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm_test.cc463
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_block_node.cc263
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_block_node.h15
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_box_fragment.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_box_fragment.h10
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc35
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm_test.cc28
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_constraint_space.cc43
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_constraint_space.h84
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.cc108
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h76
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.cc22
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h43
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.cc44
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_floats_utils.cc277
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_floats_utils.h36
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_fragment_builder.cc46
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_fragment_builder.h6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_layout_algorithm.h5
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h13
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_layout_result.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_layout_result.h36
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_layout_utils.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc209
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_length_utils.h91
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_length_utils_test.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_link.h53
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h10
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_positioned_descendant.h4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_page_layout_algorithm.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc35
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h23
-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.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.h28
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc98
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h61
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_space_utils.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_space_utils.h21
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_unpositioned_float.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_unpositioned_float.h58
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_unpositioned_float_vector.h17
-rw-r--r--chromium/third_party/blink/renderer/core/layout/order_iterator.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/scroll_anchor.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/scrollbars_test.cc101
-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.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_block.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_container.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_ellipse.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_inline.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_inline_text.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_model_object.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_rect.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_container.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_marker.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_masker.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_paint_server.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_root.cc24
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_shape.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_shape.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_text.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_transformable_container.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_viewport_container.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/svg_layout_support.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/svg_layout_tree_as_text.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/svg_marker_data.h140
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/svg_text_layout_engine_baseline.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/svg_text_query.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/table_layout_algorithm_auto.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/layout/table_layout_algorithm_fixed.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/text_autosizer.cc49
-rw-r--r--chromium/third_party/blink/renderer/core/layout/text_autosizer.h8
-rw-r--r--chromium/third_party/blink/renderer/core/layout/text_autosizer_test.cc203
-rw-r--r--chromium/third_party/blink/renderer/core/loader/BUILD.gn11
-rw-r--r--chromium/third_party/blink/renderer/core/loader/allowed_by_nosniff.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/loader/appcache/OWNERS4
-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/base_fetch_context.cc100
-rw-r--r--chromium/third_party/blink/renderer/core/loader/base_fetch_context.h6
-rw-r--r--chromium/third_party/blink/renderer/core/loader/base_fetch_context_test.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/loader/document_load_timing.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/loader/document_load_timing.h5
-rw-r--r--chromium/third_party/blink/renderer/core/loader/document_loader.cc60
-rw-r--r--chromium/third_party/blink/renderer/core/loader/document_loader.h23
-rw-r--r--chromium/third_party/blink/renderer/core/loader/document_threadable_loader.cc1259
-rw-r--r--chromium/third_party/blink/renderer/core/loader/document_threadable_loader.h244
-rw-r--r--chromium/third_party/blink/renderer/core/loader/document_threadable_loader_client.h61
-rw-r--r--chromium/third_party/blink/renderer/core/loader/document_threadable_loader_test.cc92
-rw-r--r--chromium/third_party/blink/renderer/core/loader/empty_clients.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/loader/empty_clients.h33
-rw-r--r--chromium/third_party/blink/renderer/core/loader/form_submission.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/loader/frame_fetch_context.cc34
-rw-r--r--chromium/third_party/blink/renderer/core/loader/frame_fetch_context.h3
-rw-r--r--chromium/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/loader/frame_load_request.h13
-rw-r--r--chromium/third_party/blink/renderer/core/loader/frame_loader.cc472
-rw-r--r--chromium/third_party/blink/renderer/core/loader/frame_loader.h39
-rw-r--r--chromium/third_party/blink/renderer/core/loader/history_item.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/http_equiv.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/loader/idleness_detector.cc19
-rw-r--r--chromium/third_party/blink/renderer/core/loader/idleness_detector.h1
-rw-r--r--chromium/third_party/blink/renderer/core/loader/image_loader.cc65
-rw-r--r--chromium/third_party/blink/renderer/core/loader/image_loader.h19
-rw-r--r--chromium/third_party/blink/renderer/core/loader/interactive_detector.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/link_loader.cc33
-rw-r--r--chromium/third_party/blink/renderer/core/loader/link_loader_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/loader/long_task_detector.cc (renamed from chromium/third_party/blink/renderer/platform/long_task_detector.cc)2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/long_task_detector.h (renamed from chromium/third_party/blink/renderer/platform/long_task_detector.h)18
-rw-r--r--chromium/third_party/blink/renderer/core/loader/long_task_detector_test.cc (renamed from chromium/third_party/blink/renderer/platform/long_task_detector_test.cc)2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/mixed_content_checker.cc39
-rw-r--r--chromium/third_party/blink/renderer/core/loader/mixed_content_checker.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/document_module_script_fetcher.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/module_script_creation_params.h12
-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_loader.cc25
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/module_script_loader_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.cc26
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/worker_module_script_fetcher.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/worklet_module_script_fetcher.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/loader/navigation_scheduler.cc62
-rw-r--r--chromium/third_party/blink/renderer/core/loader/ping_loader.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/loader/previews_resource_loading_hints.cc73
-rw-r--r--chromium/third_party/blink/renderer/core/loader/previews_resource_loading_hints.h56
-rw-r--r--chromium/third_party/blink/renderer/core/loader/previews_resource_loading_hints_receiver_impl.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/loader/previews_resource_loading_hints_receiver_impl.h9
-rw-r--r--chromium/third_party/blink/renderer/core/loader/previews_resource_loading_hints_test.cc183
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/document_resource.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/image_resource.cc42
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/image_resource.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/image_resource_content.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/image_resource_content.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/image_resource_info.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/image_resource_test.cc97
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/multipart_image_resource_parser.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/script_resource.cc132
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/script_resource.h15
-rw-r--r--chromium/third_party/blink/renderer/core/loader/subresource_filter.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/loader/text_track_loader.cc54
-rw-r--r--chromium/third_party/blink/renderer/core/loader/text_track_loader.h6
-rw-r--r--chromium/third_party/blink/renderer/core/loader/threadable_loader.cc1092
-rw-r--r--chromium/third_party/blink/renderer/core/loader/threadable_loader.h281
-rw-r--r--chromium/third_party/blink/renderer/core/loader/threadable_loader_client.h9
-rw-r--r--chromium/third_party/blink/renderer/core/loader/threadable_loader_test.cc433
-rw-r--r--chromium/third_party/blink/renderer/core/loader/threadable_loading_context.cc88
-rw-r--r--chromium/third_party/blink/renderer/core/loader/threadable_loading_context.h41
-rw-r--r--chromium/third_party/blink/renderer/core/loader/worker_fetch_context.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/loader/worker_fetch_context.h5
-rw-r--r--chromium/third_party/blink/renderer/core/loader/worker_threadable_loader.cc680
-rw-r--r--chromium/third_party/blink/renderer/core/loader/worker_threadable_loader.h215
-rw-r--r--chromium/third_party/blink/renderer/core/messaging/blink_cloneable_message.h2
-rw-r--r--chromium/third_party/blink/renderer/core/messaging/blink_cloneable_message_struct_traits.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/messaging/blink_cloneable_message_struct_traits.h12
-rw-r--r--chromium/third_party/blink/renderer/core/messaging/blink_transferable_message.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/messaging/blink_transferable_message.h13
-rw-r--r--chromium/third_party/blink/renderer/core/messaging/blink_transferable_message_struct_traits.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/messaging/blink_transferable_message_struct_traits.h5
-rw-r--r--chromium/third_party/blink/renderer/core/messaging/message_port.cc90
-rw-r--r--chromium/third_party/blink/renderer/core/messaging/message_port.h16
-rw-r--r--chromium/third_party/blink/renderer/core/messaging/message_port.idl3
-rw-r--r--chromium/third_party/blink/renderer/core/messaging/post_message_options.idl10
-rw-r--r--chromium/third_party/blink/renderer/core/mojo/mojo_handle.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/mojo/mojo_handle.h4
-rw-r--r--chromium/third_party/blink/renderer/core/mojo/test/mojo_interface_interceptor.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/mojo/test/mojo_interface_request_event.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/mojo/test/mojo_interface_request_event.h1
-rw-r--r--chromium/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h4
-rw-r--r--chromium/third_party/blink/renderer/core/page/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/core/page/chrome_client.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/page/chrome_client.h36
-rw-r--r--chromium/third_party/blink/renderer/core/page/chrome_client_impl.cc109
-rw-r--r--chromium/third_party/blink/renderer/core/page/chrome_client_impl.h14
-rw-r--r--chromium/third_party/blink/renderer/core/page/chrome_client_impl_test.cc151
-rw-r--r--chromium/third_party/blink/renderer/core/page/chrome_client_test.cc30
-rw-r--r--chromium/third_party/blink/renderer/core/page/create_window.cc23
-rw-r--r--chromium/third_party/blink/renderer/core/page/drag_controller.cc59
-rw-r--r--chromium/third_party/blink/renderer/core/page/focus_controller.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/page/page.cc103
-rw-r--r--chromium/third_party/blink/renderer/core/page/page.h23
-rw-r--r--chromium/third_party/blink/renderer/core/page/page_animator.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/page/page_animator.h1
-rw-r--r--chromium/third_party/blink/renderer/core/page/page_overlay.cc25
-rw-r--r--chromium/third_party/blink/renderer/core/page/page_overlay.h8
-rw-r--r--chromium/third_party/blink/renderer/core/page/page_overlay_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/page/page_widget_delegate.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/page/pointer_lock_controller.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/page/print_context.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/page/print_context.h2
-rw-r--r--chromium/third_party/blink/renderer/core/page/print_context_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/overscroll_controller.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/root_scroller_controller.cc49
-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.cc129
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/root_scroller_util.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/root_scroller_util.h6
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/scroll_into_view_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/scroll_state.h2
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc21
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h4
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/snap_coordinator.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/sticky_position_scrolling_constraints.cc66
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/sticky_position_scrolling_constraints.h134
-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/viewport_scroll_callback.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/page/touch_adjustment.cc28
-rw-r--r--chromium/third_party/blink/renderer/core/page/touch_disambiguation.cc162
-rw-r--r--chromium/third_party/blink/renderer/core/page/touch_disambiguation.h52
-rw-r--r--chromium/third_party/blink/renderer/core/page/validation_message_client_impl.cc31
-rw-r--r--chromium/third_party/blink/renderer/core/page/validation_message_client_impl.h11
-rw-r--r--chromium/third_party/blink/renderer/core/page/validation_message_overlay_delegate.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/page/viewport_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/BUILD.gn24
-rw-r--r--chromium/third_party/blink/renderer/core/paint/DEPS2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/OWNERS1
-rw-r--r--chromium/third_party/blink/renderer/core/paint/background_image_geometry.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/paint/block_flow_painter.cc63
-rw-r--r--chromium/third_party/blink/renderer/core/paint/block_flow_painter.h31
-rw-r--r--chromium/third_party/blink/renderer/core/paint/block_paint_invalidator.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/paint/block_paint_invalidator.h2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/block_painter.cc185
-rw-r--r--chromium/third_party/blink/renderer/core/paint/block_painter.h7
-rw-r--r--chromium/third_party/blink/renderer/core/paint/block_painter_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/paint/box_clipper.cc31
-rw-r--r--chromium/third_party/blink/renderer/core/paint/box_clipper.h29
-rw-r--r--chromium/third_party/blink/renderer/core/paint/box_clipper_base.cc38
-rw-r--r--chromium/third_party/blink/renderer/core/paint/box_clipper_base.h31
-rw-r--r--chromium/third_party/blink/renderer/core/paint/box_model_object_painter.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/paint/box_model_object_painter.h2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/box_paint_invalidator.cc40
-rw-r--r--chromium/third_party/blink/renderer/core/paint/box_paint_invalidator.h4
-rw-r--r--chromium/third_party/blink/renderer/core/paint/box_paint_invalidator_test.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/paint/box_painter.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/paint/box_painter.h1
-rw-r--r--chromium/third_party/blink/renderer/core/paint/box_painter_base.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/paint/box_painter_base.h17
-rw-r--r--chromium/third_party/blink/renderer/core/paint/collapsed_border_painter.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc183
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h4
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/composited_selection.h56
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/composited_selection_bound.h61
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.cc26
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.h4
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.cc23
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.cc22
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_as_text.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_as_text.h3
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.cc60
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/css_mask_painter.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/decoration_info.h1
-rw-r--r--chromium/third_party/blink/renderer/core/paint/details_marker_painter.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/paint/document_marker_painter.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/paint/embedded_content_painter.cc101
-rw-r--r--chromium/third_party/blink/renderer/core/paint/embedded_content_painter.h5
-rw-r--r--chromium/third_party/blink/renderer/core/paint/embedded_object_paint_invalidator.cc24
-rw-r--r--chromium/third_party/blink/renderer/core/paint/embedded_object_paint_invalidator.h33
-rw-r--r--chromium/third_party/blink/renderer/core/paint/embedded_object_painter.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/paint/fieldset_painter.cc22
-rw-r--r--chromium/third_party/blink/renderer/core/paint/file_upload_control_painter.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/paint/find_properties_needing_update.h83
-rw-r--r--chromium/third_party/blink/renderer/core/paint/first_meaningful_paint_detector.cc64
-rw-r--r--chromium/third_party/blink/renderer/core/paint/first_meaningful_paint_detector.h11
-rw-r--r--chromium/third_party/blink/renderer/core/paint/first_meaningful_paint_detector_test.cc77
-rw-r--r--chromium/third_party/blink/renderer/core/paint/fragment_data.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/paint/fragment_data.h10
-rw-r--r--chromium/third_party/blink/renderer/core/paint/frame_set_painter.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/paint/grid_painter.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/paint/html_canvas_paint_invalidator.cc22
-rw-r--r--chromium/third_party/blink/renderer/core/paint/html_canvas_paint_invalidator.h33
-rw-r--r--chromium/third_party/blink/renderer/core/paint/html_canvas_painter.cc23
-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_painter.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/paint/inline_box_painter_base.cc112
-rw-r--r--chromium/third_party/blink/renderer/core/paint/inline_box_painter_base.h100
-rw-r--r--chromium/third_party/blink/renderer/core/paint/inline_flow_box_painter.cc236
-rw-r--r--chromium/third_party/blink/renderer/core/paint/inline_flow_box_painter.h57
-rw-r--r--chromium/third_party/blink/renderer/core/paint/inline_painter.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/paint/inline_text_box_painter.cc55
-rw-r--r--chromium/third_party/blink/renderer/core/paint/link_highlight_impl.cc30
-rw-r--r--chromium/third_party/blink/renderer/core/paint/link_highlight_impl.h11
-rw-r--r--chromium/third_party/blink/renderer/core/paint/link_highlight_impl_test.cc207
-rw-r--r--chromium/third_party/blink/renderer/core/paint/list_marker_painter.cc39
-rw-r--r--chromium/third_party/blink/renderer/core/paint/multi_column_set_painter.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_box_clipper.cc27
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_box_clipper.h23
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc266
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h38
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_inline_box_fragment_painter.cc227
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_inline_box_fragment_painter.h59
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc232
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h70
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_traversal.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_traversal.h1
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_traversal_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/paint/nine_piece_image_grid.h2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/nine_piece_image_grid_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/paint/object_paint_invalidator.cc76
-rw-r--r--chromium/third_party/blink/renderer/core/paint/object_paint_invalidator.h11
-rw-r--r--chromium/third_party/blink/renderer/core/paint/object_paint_invalidator_test.cc126
-rw-r--r--chromium/third_party/blink/renderer/core/paint/object_paint_properties.h363
-rw-r--r--chromium/third_party/blink/renderer/core/paint/object_painter.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/object_painter.h5
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.cc89
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_controller_paint_test.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_info_with_offset.cc (renamed from chromium/third_party/blink/renderer/core/paint/adjust_paint_offset_scope.cc)6
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_info_with_offset.h (renamed from chromium/third_party/blink/renderer/core/paint/adjust_paint_offset_scope.h)28
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_invalidator.cc44
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_invalidator.h7
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer.cc254
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer.h22
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer_clipper.cc39
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer_clipper.h3
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer_clipper_test.cc93
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer_fragment.h8
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer_painter.cc327
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer_painter.h27
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer_painting_info.h63
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc238
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h20
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc31
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_phase.h10
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc424
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc692
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_property_tree_printer.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc146
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_timing.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/paint/pre_paint_tree_walk_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/paint/replaced_painter.cc125
-rw-r--r--chromium/third_party/blink/renderer/core/paint/replaced_painter.h4
-rw-r--r--chromium/third_party/blink/renderer/core/paint/root_inline_box_painter.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/scoped_box_clipper.cc45
-rw-r--r--chromium/third_party/blink/renderer/core/paint/scoped_box_clipper.h48
-rw-r--r--chromium/third_party/blink/renderer/core/paint/scrollable_area_painter.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/paint/scrollbar_painter.h2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/svg_image_painter.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/paint/svg_inline_text_box_painter.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/paint/svg_model_object_painter.cc25
-rw-r--r--chromium/third_party/blink/renderer/core/paint/svg_model_object_painter.h7
-rw-r--r--chromium/third_party/blink/renderer/core/paint/svg_paint_context.h16
-rw-r--r--chromium/third_party/blink/renderer/core/paint/svg_root_inline_box_painter.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/paint/svg_root_painter.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/paint/svg_shape_painter.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/paint/svg_text_painter.cc20
-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_cell_paint_invalidator.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/paint/table_cell_paint_invalidator.h2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/table_cell_painter.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/paint/table_paint_invalidator.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/paint/table_paint_invalidator.h2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/table_painter.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/paint/table_row_painter.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/paint/table_section_painter.cc26
-rw-r--r--chromium/third_party/blink/renderer/core/paint/text_control_single_line_painter.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/paint/text_paint_style.h2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/theme_painter_default.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/paint/video_painter.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/view_painter.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/resize_observer/resize_observer.idl3
-rw-r--r--chromium/third_party/blink/renderer/core/resize_observer/resize_observer_entry.idl4
-rw-r--r--chromium/third_party/blink/renderer/core/scheduler/frame_throttling_test.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/scheduler/throttling_test.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/script/classic_pending_script.cc145
-rw-r--r--chromium/third_party/blink/renderer/core/script/classic_pending_script.h20
-rw-r--r--chromium/third_party/blink/renderer/core/script/dynamic_module_resolver_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/script/fetch_client_settings_object_impl.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/script/fetch_client_settings_object_impl.h3
-rw-r--r--chromium/third_party/blink/renderer/core/script/html_parser_script_runner.cc107
-rw-r--r--chromium/third_party/blink/renderer/core/script/html_parser_script_runner.h5
-rw-r--r--chromium/third_party/blink/renderer/core/script/layered_api.cc29
-rw-r--r--chromium/third_party/blink/renderer/core/script/layered_api.h10
-rw-r--r--chromium/third_party/blink/renderer/core/script/layered_api_test.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/script/mock_script_element_base.h1
-rw-r--r--chromium/third_party/blink/renderer/core/script/modulator_impl_base.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/script/module_map_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/script/module_pending_script.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/script/module_pending_script.h9
-rw-r--r--chromium/third_party/blink/renderer/core/script/module_script.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/script/module_script.h12
-rw-r--r--chromium/third_party/blink/renderer/core/script/pending_script.cc33
-rw-r--r--chromium/third_party/blink/renderer/core/script/pending_script.h10
-rw-r--r--chromium/third_party/blink/renderer/core/script/resources/layered_api/async-local-storage/index.js110
-rw-r--r--chromium/third_party/blink/renderer/core/script/script_element_base.h1
-rw-r--r--chromium/third_party/blink/renderer/core/script/script_loader.cc35
-rw-r--r--chromium/third_party/blink/renderer/core/script/script_runner.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/script/script_runner_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/BUILD.gn61
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/ns_scroller_imp_details.h (renamed from chromium/third_party/blink/renderer/platform/mac/ns_scroller_imp_details.h)6
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.cc (renamed from chromium/third_party/blink/renderer/platform/scroll/programmatic_scroll_animator.cc)6
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.h (renamed from chromium/third_party/blink/renderer/platform/scroll/programmatic_scroll_animator.h)11
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scroll_animator.cc (renamed from chromium/third_party/blink/renderer/platform/scroll/scroll_animator.cc)8
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scroll_animator.h (renamed from chromium/third_party/blink/renderer/platform/scroll/scroll_animator.h)10
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scroll_animator_base.cc (renamed from chromium/third_party/blink/renderer/platform/scroll/scroll_animator_base.cc)4
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scroll_animator_base.h (renamed from chromium/third_party/blink/renderer/platform/scroll/scroll_animator_base.h)12
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scroll_animator_compositor_coordinator.cc (renamed from chromium/third_party/blink/renderer/platform/scroll/scroll_animator_compositor_coordinator.cc)4
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scroll_animator_compositor_coordinator.h (renamed from chromium/third_party/blink/renderer/platform/scroll/scroll_animator_compositor_coordinator.h)13
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scroll_animator_mac.h (renamed from chromium/third_party/blink/renderer/platform/mac/scroll_animator_mac.h)10
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scroll_animator_mac.mm (renamed from chromium/third_party/blink/renderer/platform/mac/scroll_animator_mac.mm)10
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scroll_animator_test.cc (renamed from chromium/third_party/blink/renderer/platform/scroll/scroll_animator_test.cc)8
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scroll_customization.cc (renamed from chromium/third_party/blink/renderer/platform/scroll/scroll_customization.cc)2
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scroll_customization.h (renamed from chromium/third_party/blink/renderer/platform/scroll/scroll_customization.h)12
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scroll_state_data.h (renamed from chromium/third_party/blink/renderer/platform/scroll/scroll_state_data.h)4
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollable_area.cc (renamed from chromium/third_party/blink/renderer/platform/scroll/scrollable_area.cc)14
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollable_area.h (renamed from chromium/third_party/blink/renderer/platform/scroll/scrollable_area.h)21
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollable_area_test.cc (renamed from chromium/third_party/blink/renderer/platform/scroll/scrollable_area_test.cc)18
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar.cc (renamed from chromium/third_party/blink/renderer/platform/scroll/scrollbar.cc)12
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar.h (renamed from chromium/third_party/blink/renderer/platform/scroll/scrollbar.h)19
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar_layer_delegate.cc (renamed from chromium/third_party/blink/renderer/platform/scroll/scrollbar_layer_delegate.cc)8
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar_layer_delegate.h (renamed from chromium/third_party/blink/renderer/platform/scroll/scrollbar_layer_delegate.h)10
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar_test_suite.h (renamed from chromium/third_party/blink/renderer/platform/scroll/scrollbar_test_suite.h)16
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar_theme.cc (renamed from chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme.cc)8
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar_theme.h (renamed from chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme.h)12
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_android.cc (renamed from chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_android.cc)4
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_aura.cc (renamed from chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_aura.cc)8
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_aura.h (renamed from chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_aura.h)8
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_aura_test.cc (renamed from chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_aura_test.cc)10
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.h (renamed from chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_mac.h)25
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.mm (renamed from chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_mac.mm)58
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_mock.cc (renamed from chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_mock.cc)4
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_mock.h (renamed from chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_mock.h)10
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_overlay.cc (renamed from chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay.cc)4
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_overlay.h (renamed from chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay.h)8
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_overlay_mock.h (renamed from chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay_mock.h)10
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_overlay_test.cc (renamed from chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay_test.cc)10
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.cc (renamed from chromium/third_party/blink/renderer/platform/scroll/smooth_scroll_sequencer.cc)6
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.h (renamed from chromium/third_party/blink/renderer/platform/scroll/smooth_scroll_sequencer.h)10
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/web_scroll_into_view_params.cc (renamed from chromium/third_party/blink/renderer/platform/scroll/web_scroll_into_view_params.cc)0
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/web_scrollbar_theme.mm (renamed from chromium/third_party/blink/renderer/platform/scroll/web_scrollbar_theme.mm)59
-rw-r--r--chromium/third_party/blink/renderer/core/streams/BUILD.gn5
-rw-r--r--chromium/third_party/blink/renderer/core/streams/ReadableStream.js181
-rw-r--r--chromium/third_party/blink/renderer/core/streams/TransformStream.js91
-rw-r--r--chromium/third_party/blink/renderer/core/streams/WritableStream.js72
-rw-r--r--chromium/third_party/blink/renderer/core/streams/readable_stream_operations_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/streams/transform_stream.cc176
-rw-r--r--chromium/third_party/blink/renderer/core/streams/transform_stream.h66
-rw-r--r--chromium/third_party/blink/renderer/core/streams/transform_stream_default_controller.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/streams/transform_stream_default_controller.h39
-rw-r--r--chromium/third_party/blink/renderer/core/streams/transform_stream_test.cc502
-rw-r--r--chromium/third_party/blink/renderer/core/streams/transform_stream_transformer.h48
-rw-r--r--chromium/third_party/blink/renderer/core/style/computed_style.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/style/computed_style.h23
-rw-r--r--chromium/third_party/blink/renderer/core/style/computed_style_test.cc65
-rw-r--r--chromium/third_party/blink/renderer/core/style/style_difference.h8
-rw-r--r--chromium/third_party/blink/renderer/core/style/style_fetched_image.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/style/style_fetched_image.h11
-rw-r--r--chromium/third_party/blink/renderer/core/style/style_image.h11
-rw-r--r--chromium/third_party/blink/renderer/core/style/style_inherited_variables.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/style/style_inherited_variables.h11
-rw-r--r--chromium/third_party/blink/renderer/core/style/style_non_inherited_variables.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/style/style_non_inherited_variables.h10
-rw-r--r--chromium/third_party/blink/renderer/core/svg/animation/smil_time_container.cc134
-rw-r--r--chromium/third_party/blink/renderer/core/svg/animation/smil_time_container.h5
-rw-r--r--chromium/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/svg/animation/svg_smil_element.h4
-rw-r--r--chromium/third_party/blink/renderer/core/svg/graphics/svg_image.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/properties/svg_animated_property.cc29
-rw-r--r--chromium/third_party/blink/renderer/core/svg/properties/svg_animated_property.h70
-rw-r--r--chromium/third_party/blink/renderer/core/svg/properties/svg_list_property_helper.h35
-rw-r--r--chromium/third_party/blink/renderer/core/svg/properties/svg_list_property_tear_off_helper.h43
-rw-r--r--chromium/third_party/blink/renderer/core/svg/properties/svg_property_tear_off.cc42
-rw-r--r--chromium/third_party/blink/renderer/core/svg/properties/svg_property_tear_off.h57
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_a_element.cc16
-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_tear_off.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_angle_tear_off.h13
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animate_element.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animate_element.h4
-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_enumeration_base.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animated_href.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animated_integer.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animated_integer_optional_integer.cc4
-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.cc5
-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_number.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animated_number_optional_number.cc4
-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_document_extensions.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_document_extensions.h1
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_element.cc71
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_element.h4
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_convolve_matrix_element.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_diffuse_lighting_element.cc4
-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_flood_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_image_element.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_image_element.h4
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_specular_lighting_element.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fit_to_view_box.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_geometry_element.cc11
-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.h4
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_image_element.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_image_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_image_element.idl4
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_image_loader.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_length_list.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_length_list_tear_off.h21
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_length_tear_off.cc25
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_length_tear_off.h13
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_matrix_tear_off.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_mpath_element.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_mpath_element.h4
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_number_list.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_number_list_tear_off.h18
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_number_tear_off.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_number_tear_off.h13
-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.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_path_element.h4
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_pattern_element.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_pattern_element.h4
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_point_list.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_point_list_tear_off.h21
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_point_tear_off.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_point_tear_off.h18
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_preserve_aspect_ratio_tear_off.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_preserve_aspect_ratio_tear_off.h14
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_rect_tear_off.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_rect_tear_off.h13
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_resource.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_script_element.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_script_element.h3
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_static_string_list.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_static_string_list.h3
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_string_list.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_string_list_tear_off.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_string_list_tear_off.h13
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_style_element.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_style_element.h4
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_svg_element.cc23
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_svg_element.h4
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_tests.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_text_content_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_text_path_element.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_text_path_element.h4
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_title_element.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_title_element.h4
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_transform_list.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_transform_list_tear_off.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_transform_list_tear_off.h13
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_transform_tear_off.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_transform_tear_off.h16
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_uri_reference.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_uri_reference.h3
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_use_element.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_use_element.h4
-rw-r--r--chromium/third_party/blink/renderer/core/testing/core_unit_test_helper.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/testing/data/content_editable_multiline.html1
-rw-r--r--chromium/third_party/blink/renderer/core/testing/data/disambiguation_popup.html30
-rw-r--r--chromium/third_party/blink/renderer/core/testing/data/disambiguation_popup_200_by_800.html37
-rw-r--r--chromium/third_party/blink/renderer/core/testing/data/disambiguation_popup_blacklist.html36
-rw-r--r--chromium/third_party/blink/renderer/core/testing/data/disambiguation_popup_mobile_site.html31
-rw-r--r--chromium/third_party/blink/renderer/core/testing/data/disambiguation_popup_no_container.html25
-rw-r--r--chromium/third_party/blink/renderer/core/testing/data/disambiguation_popup_page_scale.html20
-rw-r--r--chromium/third_party/blink/renderer/core/testing/data/disambiguation_popup_viewport_site.html38
-rw-r--r--chromium/third_party/blink/renderer/core/testing/data/input_placeholder.html1
-rw-r--r--chromium/third_party/blink/renderer/core/testing/dictionary_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/testing/dictionary_test.h2
-rw-r--r--chromium/third_party/blink/renderer/core/testing/dummy_page_holder.h2
-rw-r--r--chromium/third_party/blink/renderer/core/testing/gc_object_liveness_observer.h45
-rw-r--r--chromium/third_party/blink/renderer/core/testing/internal_dictionary.idl1
-rw-r--r--chromium/third_party/blink/renderer/core/testing/internals.cc59
-rw-r--r--chromium/third_party/blink/renderer/core/testing/internals.h9
-rw-r--r--chromium/third_party/blink/renderer/core/testing/internals.idl8
-rw-r--r--chromium/third_party/blink/renderer/core/testing/null_execution_context.h7
-rw-r--r--chromium/third_party/blink/renderer/core/testing/page_test_base.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/testing/page_test_base.h12
-rw-r--r--chromium/third_party/blink/renderer/core/testing/sim/sim_canvas.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/testing/sim/sim_canvas.h5
-rw-r--r--chromium/third_party/blink/renderer/core/testing/sim/sim_test.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/testing/type_conversions.h28
-rw-r--r--chromium/third_party/blink/renderer/core/testing/use_mock_scrollbar_settings.h2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/event_timing.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/timing/memory_info.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/timing/memory_info_test.cc47
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance.cc71
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance.h27
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_entry.cc107
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_entry.h37
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_entry_names.json518
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_event_timing.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_event_timing.h4
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_long_task_timing.cc19
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_long_task_timing.h16
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_mark.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_mark.h4
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_measure.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_measure.h4
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_navigation_timing.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_paint_timing.cc34
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_paint_timing.h3
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_paint_timing.idl4
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_resource_timing.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_resource_timing.h2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_resource_timing.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_server_timing.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_server_timing.idl1
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_timing.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_timing.h1
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_user_timing.cc83
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_user_timing.h17
-rw-r--r--chromium/third_party/blink/renderer/core/timing/sub_task_attribution.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/timing/sub_task_attribution.h17
-rw-r--r--chromium/third_party/blink/renderer/core/timing/task_attribution_timing.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/timing/task_attribution_timing.h34
-rw-r--r--chromium/third_party/blink/renderer/core/timing/time_clamper.cc (renamed from chromium/third_party/blink/renderer/platform/time_clamper.cc)12
-rw-r--r--chromium/third_party/blink/renderer/core/timing/time_clamper.h (renamed from chromium/third_party/blink/renderer/platform/time_clamper.h)10
-rw-r--r--chromium/third_party/blink/renderer/core/timing/time_clamper_test.cc (renamed from chromium/third_party/blink/renderer/platform/time_clamper_test.cc)12
-rw-r--r--chromium/third_party/blink/renderer/core/timing/window_performance.cc74
-rw-r--r--chromium/third_party/blink/renderer/core/timing/window_performance.h4
-rw-r--r--chromium/third_party/blink/renderer/core/timing/window_performance_test.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/trustedtypes/BUILD.gn6
-rw-r--r--chromium/third_party/blink/renderer/core/trustedtypes/trusted_html.cc22
-rw-r--r--chromium/third_party/blink/renderer/core/trustedtypes/trusted_html.h4
-rw-r--r--chromium/third_party/blink/renderer/core/trustedtypes/trusted_script.cc40
-rw-r--r--chromium/third_party/blink/renderer/core/trustedtypes/trusted_script.h42
-rw-r--r--chromium/third_party/blink/renderer/core/trustedtypes/trusted_script.idl14
-rw-r--r--chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.cc124
-rw-r--r--chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.h54
-rw-r--r--chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.idl15
-rw-r--r--chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.cc56
-rw-r--r--chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.h50
-rw-r--r--chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.idl15
-rw-r--r--chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_options.idl17
-rw-r--r--chromium/third_party/blink/renderer/core/trustedtypes/trusted_url.cc22
-rw-r--r--chromium/third_party/blink/renderer/core/trustedtypes/trusted_url.h6
-rw-r--r--chromium/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/url/dom_url.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/url/dom_url.h2
-rw-r--r--chromium/third_party/blink/renderer/core/url/dom_url_utils.cc23
-rw-r--r--chromium/third_party/blink/renderer/core/url/dom_url_utils.h5
-rw-r--r--chromium/third_party/blink/renderer/core/url/dom_url_utils_read_only.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/url/dom_url_utils_read_only.h5
-rw-r--r--chromium/third_party/blink/renderer/core/workers/BUILD.gn4
-rw-r--r--chromium/third_party/blink/renderer/core/workers/dedicated_worker.cc95
-rw-r--r--chromium/third_party/blink/renderer/core/workers/dedicated_worker.h20
-rw-r--r--chromium/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc50
-rw-r--r--chromium/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h19
-rw-r--r--chromium/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.idl5
-rw-r--r--chromium/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.cc48
-rw-r--r--chromium/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.h17
-rw-r--r--chromium/third_party/blink/renderer/core/workers/dedicated_worker_object_proxy.cc40
-rw-r--r--chromium/third_party/blink/renderer/core/workers/dedicated_worker_object_proxy.h19
-rw-r--r--chromium/third_party/blink/renderer/core/workers/dedicated_worker_test.cc33
-rw-r--r--chromium/third_party/blink/renderer/core/workers/dedicated_worker_thread.cc40
-rw-r--r--chromium/third_party/blink/renderer/core/workers/dedicated_worker_thread.h8
-rw-r--r--chromium/third_party/blink/renderer/core/workers/global_scope_creation_params.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/workers/global_scope_creation_params.h25
-rw-r--r--chromium/third_party/blink/renderer/core/workers/main_thread_worklet_test.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/workers/shared_worker_thread.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/workers/shared_worker_thread.h1
-rw-r--r--chromium/third_party/blink/renderer/core/workers/threaded_messaging_proxy_base.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/workers/threaded_messaging_proxy_base.h3
-rw-r--r--chromium/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/workers/threaded_worklet_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker.idl3
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_animation_frame_provider.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_animation_frame_provider.h2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_backing_thread.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_classic_script_loader.cc51
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_classic_script_loader.h31
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_global_scope.cc27
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_global_scope.h10
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_global_scope.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_options.idl3
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc29
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h6
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_reporting_proxy.h12
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_thread.cc68
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_thread.h36
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_thread_lifecycle_context.cc26
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_thread_lifecycle_context.h43
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_thread_lifecycle_observer.cc23
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_thread_lifecycle_observer.h49
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_thread_test.cc21
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_thread_test_helper.h26
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worklet.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worklet.h2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worklet_global_scope.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worklet_global_scope.h17
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worklet_thread_holder.h4
-rw-r--r--chromium/third_party/blink/renderer/core/xml/dom_parser.cc19
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xpath_parser.h2
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xsl_style_sheet_libxslt.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xslt_processor.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xslt_processor_libxslt.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc68
-rw-r--r--chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h4
-rw-r--r--chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_progress_event_throttle.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_upload.cc16
-rw-r--r--chromium/third_party/blink/renderer/devtools/BUILD.gn15
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/Images/whatsnew.pngbin12279 -> 12171 bytes
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/OWNERS2
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/Runtime.js5
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/audits2/Audits2ProtocolService.js2
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/audits2/Audits2StatusView.js2
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/bindings/BlackboxManager.js249
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/bindings/BreakpointManager.js355
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/bindings/CompilerScriptMapping.js31
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/bindings/DebuggerWorkspaceBinding.js74
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/bindings/DefaultScriptMapping.js33
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/bindings/PresentationConsoleMessageHelper.js3
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/bindings/ResourceMapping.js13
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/bindings/ResourceScriptMapping.js17
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/browser_components/module.json12
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/browser_console/BrowserConsole.js4
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/browser_sdk/LogManager.js2
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/browser_sdk/module.json4
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/changes/ChangesSidebar.js2
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/changes/module.json1
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/cm/activeline.js2
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/cm/closebrackets.js15
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/cm/codemirror.css2
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/cm/codemirror.js137
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/cm/comment.js2
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/cm/markselection.js2
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/cm/matchbrackets.js15
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/cm/multiplex.js12
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/cm/overlay.js2
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/cm_headless/headlesscodemirror.js2
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/cm_modes/clike.js64
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/cm_modes/clojure.js2
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/cm_modes/coffeescript.js2
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/cm_modes/jsx.js4
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/cm_modes/livescript.js2
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/cm_modes/markdown.js22
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/cm_modes/php.js2
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/cm_modes/python.js115
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/cm_modes/shell.js27
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/cm_modes/stylus.js4
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/css.js20
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/htmlembedded.js11
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/htmlmixed.js2
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/javascript.js235
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/xml.js14
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/common/ResourceType.js11
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/components/ImagePreview.js (renamed from chromium/third_party/blink/renderer/devtools/front_end/browser_components/ImagePreview.js)4
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/components/JSPresentationUtils.js13
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/components/imagePreview.css (renamed from chromium/third_party/blink/renderer/devtools/front_end/browser_components/imagePreview.css)0
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/components/module.json2
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/console/ConsolePinPane.js119
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/console/ConsolePrompt.js100
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleView.js29
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleViewMessage.js22
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleViewport.js23
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/console/consolePinPane.css38
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/console/consolePrompt.css78
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/console/consoleView.css126
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/console/module.json9
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/console_test_runner/ConsoleTestRunner.js5
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/coverage/CoverageDecorationManager.js5
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/devtools_app.json1
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/devtools_compatibility.js60
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/elements/ElementsPanel.js2
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/elements/ElementsTreeOutline.js2
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/elements/StylesSidebarPane.js25
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/elements/module.json2
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/event_listeners/EventListenersView.js9
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/extensions/ExtensionAPI.js24
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/extensions/ExtensionServer.js11
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/formatter_worker/FormatterWorker.js17
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/har_importer/HARImporter.js8
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/heap_profiler_test_runner/HeapProfilerTestRunner.js12
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/heap_snapshot_model/HeapSnapshotModel.js16
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/heap_snapshot_worker/HeapSnapshot.js36
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/heap_snapshot_worker/HeapSnapshotLoader.js37
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/help/ReleaseNoteText.js38
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/host/InspectorFrontendHost.js32
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/host/InspectorFrontendHostAPI.js17
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/inline_editor/CSSShadowEditor.js4
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/inspector_main/module.json4
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/main/Main.js12
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/main/module.json32
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/network/HARWriter.js2
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/network/NetworkDataGridNode.js6
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/network/NetworkLogView.js41
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/network/NetworkPanel.js12
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/network/NetworkSearchScope.js3
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/network/networkConfigView.css1
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/network_test_runner/NetworkTestRunner.js4
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/object_ui/JavaScriptAutocomplete.js19
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/object_ui/JavaScriptREPL.js105
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/object_ui/ObjectPopoverHelper.js3
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/object_ui/ObjectPropertiesSection.js18
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/object_ui/RemoteObjectPreviewFormatter.js2
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/object_ui/module.json1
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/object_ui/objectPropertiesSection.css15
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/perf_ui/FlameChart.js363
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/persistence/Automapping.js7
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/persistence/FileSystemWorkspaceBinding.js85
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/persistence/IsolatedFileSystem.js117
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/persistence/IsolatedFileSystemManager.js17
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/persistence/Persistence.js3
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/persistence/PersistenceUtils.js12
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/persistence/PlatformFileSystem.js194
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/persistence/WorkspaceSettingsTab.js20
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/persistence/module.json1
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapProfileView.js52
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotGridNodes.js4
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotProxy.js8
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotView.js26
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfileDataGrid.js16
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfileType.js4
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfilesPanel.js4
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/protocol/InspectorBackend.js30
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/resources/ServiceWorkerCacheViews.js2
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/sdk/CSSMetadata.js378
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/sdk/CSSModel.js125
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/sdk/Connections.js27
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/sdk/DebuggerModel.js22
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/sdk/HARLog.js (renamed from chromium/third_party/blink/renderer/devtools/front_end/browser_sdk/HAREntry.js)181
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/sdk/HeapProfilerModel.js27
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/sdk/NetworkLog.js (renamed from chromium/third_party/blink/renderer/devtools/front_end/browser_sdk/NetworkLog.js)100
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/sdk/RuntimeModel.js34
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/sdk/Script.js14
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/sdk/SourceMap.js44
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/sdk/SourceMapManager.js35
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/sdk/module.json2
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/sdk_test_runner/PageMockTestRunner.js7
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/snippets/ScriptSnippetFileSystem.js220
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/snippets/ScriptSnippetModel.js608
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/snippets/SnippetStorage.js200
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/snippets/SnippetsQuickOpen.js8
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/snippets/module.json5
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/source_frame/JSONView.js3
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/sources/CallStackSidebarPane.js294
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/sources/DebuggerPausedMessage.js4
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/sources/DebuggerPlugin.js105
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/sources/JavaScriptBreakpointsSidebarPane.js72
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/sources/JavaScriptCompilerPlugin.js2
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/sources/NavigatorView.js18
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/sources/ScriptOriginPlugin.js53
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/sources/SnippetsPlugin.js2
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/sources/SourceFormatter.js16
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/sources/SourceMapNamesResolver.js16
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/sources/SourcesNavigator.js55
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/sources/SourcesPanel.js34
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/sources/TabbedEditorContainer.js9
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/sources/UISourceCodeFrame.js2
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/sources/module.json3
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/sources/sourcesView.css1
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/sources_test_runner/DebuggerTestRunner.js25
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/test_runner/TestRunner.js1
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/text_editor/CodeMirrorTextEditor.js19
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/text_editor/cmdevtools.css8
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineController.js31
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineLoader.js3
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineUIUtils.js205
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/timeline/module.json2
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/timeline_model/TimelineJSProfile.js34
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/timeline_model/TimelineModel.js11
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/ui/ARIAUtils.js14
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/ui/InspectorView.js32
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/ui/ListControl.js8
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/ui/ShortcutRegistry.js14
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/ui/SoftContextMenu.js39
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/ui/TabbedPane.js2
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/ui/inspectorCommon.css3
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/ui/softContextMenu.css45
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/ui/treeoutline.css30
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/ui/treeoutline.js19
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/worker_app.json1
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/workspace/FileManager.js5
-rw-r--r--chromium/third_party/blink/renderer/devtools/front_end/workspace/Workspace.js1
-rw-r--r--chromium/third_party/blink/renderer/modules/BUILD.gn6
-rw-r--r--chromium/third_party/blink/renderer/modules/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/modules/OWNERS1
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/accessibility_object_model_test.cc14
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_inline_text_box.cc3
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc88
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_media_controls.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_node_object.cc38
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_object.cc61
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_object.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc19
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_position.cc401
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_position.h58
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_position_test.cc446
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_selection.cc52
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_selection.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_selection_test.cc51
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.cc14
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.cc52
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_test.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_test.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/BUILD.gn1
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.idl6
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_messaging_proxy.cc3
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_thread.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_thread.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_thread_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/animator.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/css_animation_worklet.cc1
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/effect_proxy.cc37
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/effect_proxy.h23
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/effect_proxy.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc3
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation_test.cc7
-rw-r--r--chromium/third_party/blink/renderer/modules/app_banner/app_banner_controller.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/app_banner/before_install_prompt_event.cc3
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/BUILD.gn16
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.cc23
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.h19
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_click_event.cc29
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_click_event.h55
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_click_event.idl15
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_click_event_init.idl9
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_event.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_event.h14
-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_event_init.idl6
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_fail_event.cc55
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_fail_event.h67
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_fail_event.idl13
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.cc222
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.h47
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader_test.cc114
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc153
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager_test.cc45
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_options.idl7
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_record.cc46
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_record.h45
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_record.idl13
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc167
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h48
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.idl24
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_event.cc35
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_event.h67
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_event.idl13
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_event_init.idl9
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_fetch.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_fetches.cc53
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_fetches.h50
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_fetches.idl13
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_fetches_test.cc157
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_type_converters.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_ui_options.idl10
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_event.cc85
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_event.h64
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_event.idl14
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.cc124
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.h77
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.idl13
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetched_event.cc107
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetched_event.h87
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetched_event.idl15
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetched_event_init.idl9
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/service_worker_global_scope_background_fetch.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/service_worker_global_scope_background_fetch.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/battery/battery_manager.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_device.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.cc1
-rw-r--r--chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.cc16
-rw-r--r--chromium/third_party/blink/renderer/modules/budget/BUILD.gn18
-rw-r--r--chromium/third_party/blink/renderer/modules/budget/DEPS3
-rw-r--r--chromium/third_party/blink/renderer/modules/budget/OWNERS4
-rw-r--r--chromium/third_party/blink/renderer/modules/budget/budget_service.cc149
-rw-r--r--chromium/third_party/blink/renderer/modules/budget/budget_service.h66
-rw-r--r--chromium/third_party/blink/renderer/modules/budget/budget_service.idl19
-rw-r--r--chromium/third_party/blink/renderer/modules/budget/budget_state.cc17
-rw-r--r--chromium/third_party/blink/renderer/modules/budget/budget_state.h39
-rw-r--r--chromium/third_party/blink/renderer/modules/budget/budget_state.idl13
-rw-r--r--chromium/third_party/blink/renderer/modules/budget/navigator_budget.cc53
-rw-r--r--chromium/third_party/blink/renderer/modules/budget/navigator_budget.h40
-rw-r--r--chromium/third_party/blink/renderer/modules/budget/navigator_budget.idl12
-rw-r--r--chromium/third_party/blink/renderer/modules/budget/worker_navigator_budget.cc54
-rw-r--r--chromium/third_party/blink/renderer/modules/budget/worker_navigator_budget.h45
-rw-r--r--chromium/third_party/blink/renderer/modules/budget/worker_navigator_budget.idl12
-rw-r--r--chromium/third_party/blink/renderer/modules/cache_storage/OWNERS1
-rw-r--r--chromium/third_party/blink/renderer/modules/cache_storage/cache.cc174
-rw-r--r--chromium/third_party/blink/renderer/modules/cache_storage/cache.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/cache_storage/cache_storage.cc19
-rw-r--r--chromium/third_party/blink/renderer/modules/cache_storage/cache_storage_error.cc70
-rw-r--r--chromium/third_party/blink/renderer/modules/cache_storage/cache_storage_error.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/cache_storage/cache_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.cc11
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc15
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_api_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc65
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/path_2d.h14
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/path_2d.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/OffscreenCanvas-commit.md11
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/cookie_store.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_delete_options.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_set_options.idl1
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_proxy.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc16
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container_test.cc7
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/public_key_credential_descriptor.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/crypto/normalize_algorithm.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/csspaint/OWNERS1
-rw-r--r--chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/BUILD.gn8
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/DEPS5
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_motion_controller.cc23
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_motion_controller.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_motion_dispatcher.cc80
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_motion_dispatcher.h77
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.cc35
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.h20
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump_unittest.cc189
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_absolute_controller.cc11
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_absolute_controller.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_controller.cc31
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_controller.h7
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_data.cc15
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_data.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_dispatcher.cc97
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_dispatcher.h86
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump.cc153
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump.h26
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump_unittest.cc625
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_inspector_agent.cc50
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_inspector_agent.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_event_pump.h11
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/encrypted_media_utils.cc16
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_session.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.cc16
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.idl1
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/navigator_request_media_key_system_access.cc31
-rw-r--r--chromium/third_party/blink/renderer/modules/event_target_modules_names.json53
-rw-r--r--chromium/third_party/blink/renderer/modules/eventsource/event_source.cc16
-rw-r--r--chromium/third_party/blink/renderer/modules/exported/BUILD.gn1
-rw-r--r--chromium/third_party/blink/renderer/modules/exported/web_ax_context.cc25
-rw-r--r--chromium/third_party/blink/renderer/modules/exported/web_ax_object.cc25
-rw-r--r--chromium/third_party/blink/renderer/modules/exported/web_dom_file_system.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc43
-rw-r--r--chromium/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/exported/web_user_media_request.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/BUILD.gn8
-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_reader_sync.cc5
-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.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base.cc73
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base.h20
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base_test.cc24
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.h4
-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/dom_window_file_system.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/entry.cc14
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/entry.idl7
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/entry_base.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/entry_base.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_base_handle.cc26
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_base_handle.h25
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_base_handle.idl20
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_callbacks.cc36
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_callbacks.h31
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_client.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_handle.cc39
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_handle.h25
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_handle.idl12
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_file_handle.cc93
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_file_handle.h25
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_file_handle.idl11
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_writer.cc86
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_writer.h41
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_writer.idl15
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_writer.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/local_file_system.cc80
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/local_file_system.h9
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/window_file_system.idl7
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/worker_global_scope_file_system.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/gamepad/gamepad.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.cc18
-rw-r--r--chromium/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.h11
-rw-r--r--chromium/third_party/blink/renderer/modules/gamepad/gamepad_pose.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/gamepad/gamepad_shared_memory_reader.cc13
-rw-r--r--chromium/third_party/blink/renderer/modules/gamepad/gamepad_shared_memory_reader.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/gamepad/navigator_gamepad.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/geolocation/geolocation.cc33
-rw-r--r--chromium/third_party/blink/renderer/modules/geolocation/geoposition.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/imagecapture/image_capture.cc1
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/BUILD.gn1
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/OWNERS2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_cursor.cc5
-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_with_value.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_database.cc22
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_database.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_event_dispatcher.cc26
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_event_dispatcher.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_factory.cc14
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_factory.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_factory.idl9
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_histograms.h45
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_index.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_key.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_key_path.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_object_store.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_observation.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_observer.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_open_db_request.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_open_db_request.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_request.cc43
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_request.h11
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction.cc11
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_value.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_version_change_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.cc19
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/window_indexed_database.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/installation/installation_service_impl.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout.cc1
-rw-r--r--chromium/third_party/blink/renderer/modules/locks/lock.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/locks/lock_info.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/locks/lock_manager.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/locks/lock_manager.idl5
-rw-r--r--chromium/third_party/blink/renderer/modules/locks/lock_manager_snapshot.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/locks/lock_options.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/locks/navigator_locks.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/locks/worker_navigator_locks.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/manifest/image_resource_type_converters.cc29
-rw-r--r--chromium/third_party/blink/renderer/modules/manifest/image_resource_type_converters.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/manifest/image_resource_type_converters_test.cc17
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_button_panel_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_button_panel_element.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_cast_button_element.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_cast_button_element.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_display_cutout_fullscreen_button_element.cc50
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_display_cutout_fullscreen_button_element.h33
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_display_cutout_fullscreen_button_element_test.cc120
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_download_button_element.cc4
-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_type.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_elements_helper.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_elements_helper.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_fullscreen_button_element.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_fullscreen_button_element.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_loading_panel_element.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_loading_panel_element.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_loading_panel_element_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_mute_button_element.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_mute_button_element.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overflow_menu_button_element.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overflow_menu_button_element.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overflow_menu_list_element.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overflow_menu_list_element.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_enclosure_element.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_enclosure_element.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element.cc46
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element_test.cc50
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.cc11
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_picture_in_picture_button_element.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_picture_in_picture_button_element.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_play_button_element.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_play_button_element.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.cc16
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.h4
-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_text_track_list_element.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_text_track_list_element.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_element.cc36
-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.cc84
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_toggle_closed_captions_button_element.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_toggle_closed_captions_button_element.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_volume_slider_element.cc15
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_volume_slider_element.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc60
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl.h12
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc55
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/resources/ic_display_cutout_fullscreen.svg11
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls.css36
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls_loading.css16
-rw-r--r--chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_media_element_capture.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasource/media_source.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasource/source_buffer.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasource/source_buffer.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasource/source_buffer_list.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_constraints_impl.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_devices.cc15
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_devices.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_track.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_track_content_hint.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/navigator_display_media.cc33
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/navigator_display_media.h31
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/navigator_display_media.idl12
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/user_media_client.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/user_media_request.cc72
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/user_media_request.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/modules_idl_files.gni37
-rw-r--r--chromium/third_party/blink/renderer/modules/modules_initializer.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/navigatorcontentutils/OWNERS3
-rw-r--r--chromium/third_party/blink/renderer/modules/netinfo/network_information.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/netinfo/network_information.idl10
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/OWNERS1
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification.cc118
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification.h9
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification_data.cc91
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification_data.h19
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification_data_test.cc117
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification_image_loader.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification_image_loader_test.cc15
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification_manager.cc31
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification_manager.h15
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader.cc15
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader.h13
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader_test.cc148
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.cc19
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/basic_card_helper.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_address.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_details_modifier.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_instruments.cc66
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_instruments.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_manager.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_request.cc255
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_request.h13
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_response.cc13
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_response.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_test_helper.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payments_validators.cc63
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payments_validators.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payments_validators_test.cc158
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/BUILD.gn12
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/OWNERS1
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/README.md13
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_host.cc129
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_host.h82
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.cc112
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.h102
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h55
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_certificate.cc34
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_certificate.h12
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate_pair.idl9
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_gather_options.idl9
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_parameters.idl9
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc409
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h125
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.idl60
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc325
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h12
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.idl16
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.cc1
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_parameters.idl16
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.cc54
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.h44
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.idl25
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.cc128
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.h69
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.idl30
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/testing/internals_rtc_certificate.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/permissions/permission_status.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.cc43
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.h41
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.idl14
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event_init.idl8
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.cc64
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.h12
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.idl1
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture_test.cc113
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_control.idl9
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.cc29
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.h17
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_window.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/mock_presentation_service.h13
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_availability.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_availability_observer.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_availability_state.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_connection.cc26
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_connection.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_connection_callbacks.cc20
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_connection_callbacks.h9
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_connection_list.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_controller.cc15
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_controller.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_error.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_receiver.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_receiver_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/modules/quota/OWNERS5
-rw-r--r--chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc31
-rw-r--r--chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller_impl.cc7
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/sensor.cc7
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/client.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker.cc33
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_client.cc37
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_client.h12
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.cc18
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc15
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.cc250
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h24
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_thread.cc3
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_thread.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/detected_barcode.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/detected_face.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/detected_text.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/face_detector.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/text_detector.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_recognition.cc22
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_recognition_error.cc2
-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_synthesis.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/BUILD.gn6
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/cached_storage_area.cc630
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/cached_storage_area.h170
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/cached_storage_area_test.cc574
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/inspector_dom_storage_agent.cc32
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/inspector_dom_storage_agent.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/storage_area.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/testing/fake_area_source.h47
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/testing/mock_storage_area.cc81
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/testing/mock_storage_area.h120
-rw-r--r--chromium/third_party/blink/renderer/modules/vr/navigator_vr.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/vr/navigator_vr.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/vr/navigator_vr.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/vr/vr_controller.cc134
-rw-r--r--chromium/third_party/blink/renderer/modules/vr/vr_controller.h17
-rw-r--r--chromium/third_party/blink/renderer/modules/vr/vr_display.cc241
-rw-r--r--chromium/third_party/blink/renderer/modules/vr/vr_display.h76
-rw-r--r--chromium/third_party/blink/renderer/modules/vr/vr_display.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/vr/vr_display_capabilities.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/vr/vr_display_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/vr/vr_eye_parameters.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/vr/vr_eye_parameters.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/vr/vr_frame_data.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/vr/vr_frame_data.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/vr/vr_pose.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/vr/vr_stage_parameters.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/BUILD.gn11
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/DEPS3
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.cc57
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.h40
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.idl13
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/screen_wake_lock_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.cc133
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.h92
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.idl22
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_request.cc27
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_request.h31
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_request.idl12
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/analyser_node.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_basic_inspector_node.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_basic_processor_handler.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_context.cc35
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_context.h9
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_node.cc23
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_node.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_node_input.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_node_output.cc34
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_param.cc16
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_param.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_param_timeline.cc104
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_param_timeline.h16
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_processing_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_node.cc37
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_node.h15
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_summing_junction.cc5
-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.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope_test.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_messaging_proxy.cc3
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_thread.cc28
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_thread.h17
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_thread_test.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.cc71
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.h20
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/constant_source_node.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/convolver_node.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/default_audio_destination_node.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc53
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/deferred_task_handler.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/gain_node.cc2
-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_context.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/script_processor_node.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/database.cc19
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_agent.cc37
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_agent.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system.cc1
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system_posix.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system_win.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_statement.cc1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.cc11
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc213
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.h18
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_extension_name.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_framebuffer.cc15
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_framebuffer.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_multiview.cc106
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_multiview.h37
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_multiview.idl21
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_program.cc17
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_program.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc428
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h135
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.idl8
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/DEPS3
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/webgpu_adapter.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/webgpu_adapter.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/webgpu_adapter.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/webgpu_device.cc42
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/webgpu_device.h11
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/webgpu_device.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/midi_access.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/midi_input.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/midi_message_event.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/midi_port.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/navigator_web_midi.cc23
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/BUILD.gn3
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/OWNERS2
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/dom_websocket.cc90
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/dom_websocket.h28
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/dom_websocket_test.cc83
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/web_pepper_socket_impl.cc3
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/websocket_channel.cc66
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/websocket_channel.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc119
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h28
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/worker_websocket_channel.cc524
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/worker_websocket_channel.h217
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/BUILD.gn4
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb.cc122
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb.h18
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_alternate_interface.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_configuration.idl2
-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.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_endpoint.idl2
-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.idl2
-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.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.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.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/BUILD.gn1
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr.cc143
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr.h17
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_canvas_input_provider.cc1
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_coordinate_system.idl1
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_device.cc115
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_device.h63
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_device.idl5
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_device_pose.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_device_pose.idl1
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_frame.idl1
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_frame_of_reference.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_frame_of_reference.idl1
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_frame_of_reference_options.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_frame_provider.cc56
-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.cc29
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_frame_request_callback_collection.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_hit_result.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_input_pose.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_input_pose.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_input_source.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_input_source_event.idl1
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_input_source_event_init.idl6
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_layer.idl1
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_presentation_context.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_ray.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_ray.idl8
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_session.cc102
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_session.h35
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_session.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_session_creation_options.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_session_event.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_session_event_init.idl6
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_stage_bounds.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_stage_bounds.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_stage_bounds_point.h30
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_stage_bounds_point.idl12
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_utils.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_utils.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_view.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_view.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_view.idl8
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_viewport.idl1
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer.idl1
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer_init.idl4
-rw-r--r--chromium/third_party/blink/renderer/platform/BUILD.gn162
-rw-r--r--chromium/third_party/blink/renderer/platform/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/platform/OWNERS1
-rw-r--r--chromium/third_party/blink/renderer/platform/animation/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/platform/animation/animated_layers_test.cc122
-rw-r--r--chromium/third_party/blink/renderer/platform/animation/animation_utilities.h47
-rw-r--r--chromium/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/async_file_system_callbacks.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/audio/audio_destination.cc33
-rw-r--r--chromium/third_party/blink/renderer/platform/audio/audio_destination.h9
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/active_script_wrappable_base.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/active_script_wrappable_base.h5
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/callback_function_base.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/custom_wrappable.h31
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/parkable_string.cc (renamed from chromium/third_party/blink/renderer/platform/wtf/text/movable_string.cc)79
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/parkable_string.h (renamed from chromium/third_party/blink/renderer/platform/wtf/text/movable_string.h)74
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/parkable_string_test.cc (renamed from chromium/third_party/blink/renderer/platform/wtf/text/movable_string_test.cc)128
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/script_promise_properties.h15
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/script_wrappable_marking_visitor.cc64
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/script_wrappable_marking_visitor.h16
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/script_wrappable_visitor.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/script_wrappable_visitor_verifier.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/string_resource.cc36
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/string_resource.h46
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/to_v8.h19
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/trace_wrapper_v8_string.cc7
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/v8_binding.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/v8_dom_wrapper.cc5
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/v8_dom_wrapper.h65
-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.h40
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/v8_private_property.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/v8_value_cache.cc42
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/v8_value_cache.h30
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/wrapper_type_info.cc30
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/wrapper_type_info.h25
-rw-r--r--chromium/third_party/blink/renderer/platform/blob/BUILD.gn8
-rw-r--r--chromium/third_party/blink/renderer/platform/blob/DEPS2
-rw-r--r--chromium/third_party/blink/renderer/platform/blob/OWNERS3
-rw-r--r--chromium/third_party/blink/renderer/platform/blob/blob_bytes_provider.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/blob/blob_data.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/blob/blob_data.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/cross_thread_copier.cc18
-rw-r--r--chromium/third_party/blink/renderer/platform/cross_thread_copier.h35
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/DEPS2
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/platform.cc56
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_cors.cc47
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_file_system_callbacks.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_media_constraints.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_media_stream_source.cc5
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_runtime_features.cc44
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_service_worker_request.cc9
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_url_request.cc10
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_url_response.cc10
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_video_frame_submitter.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/feature_policy/feature_policy.cc15
-rw-r--r--chromium/third_party/blink/renderer/platform/feature_policy/feature_policy.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/file_system_type.h56
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/DEPS2
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/android/font_unique_name_lookup_android.cc49
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/android/font_unique_name_lookup_android.h29
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font.h5
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_custom_platform_data.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_description.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_fallback_iterator.cc27
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_fallback_iterator.h7
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_global_context.cc11
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_global_context.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_unique_name_lookup.cc28
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_unique_name_lookup.h36
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/mac/font_family_matcher_mac.mm1
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.cc30
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.cc17
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.cc40
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper_test.cc349
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc418
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result.h51
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_buffer.cc143
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_buffer.h11
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_inline_headers.h28
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker.cc10
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/simple_font_data.cc14
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/simple_font_data.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/skia/font_cache_skia.cc40
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/skia/skia_text_metrics.cc59
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/skia/skia_text_metrics.h7
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/blend.h59
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/double_point.h36
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/double_rect.h36
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/double_size.cc5
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/double_size.h34
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/float_box.h38
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/float_point.h38
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/float_point_3d.h27
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/float_quad.h27
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/float_rect.h38
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/float_rect_outsets.h12
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/float_rounded_rect.h54
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/float_size.h43
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/int_point.h24
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/int_rect.h46
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/int_rect_outsets.h16
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/int_size.h12
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/layout_point.h25
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/layout_rect.h34
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/layout_rect_outsets.h24
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/layout_size.h20
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/layout_size_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/DEPS22
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/begin_frame_provider.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/begin_frame_provider.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/bitmap_image.cc42
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/bitmap_image.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/bitmap_image_metrics.cc7
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/bitmap_image_metrics.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/bitmap_image_test.cc125
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc23
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.cc218
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.h24
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_resource_host.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc55
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_resource_provider.h25
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/color_blend.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc15
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositor_element_id.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositor_element_id.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/decoding_image_generator.cc10
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/decoding_image_generator.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/deferred_image_decoder_test.cc43
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/deferred_image_decoder_test_wo_platform.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc30
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h9
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test_helpers.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.cc23
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.h16
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gradient.cc23
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/graphics_layer.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/graphics_layer.h8
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/graphics_layer_test.cc197
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/graphics_types.cc21
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/graphics_types.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/image.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/image.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/image_data_buffer.cc17
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/image_data_buffer.h8
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/image_decoder_wrapper.cc302
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/image_decoder_wrapper.h70
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/image_decoding_store.cc41
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/image_decoding_store.h69
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/image_decoding_store_test.cc100
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/image_frame_generator.cc341
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/image_frame_generator.h66
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/image_frame_generator_test.cc65
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/image_layer_chromium_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/intercepting_canvas.h14
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/link_highlight.h14
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/logging_canvas.cc17
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/logging_canvas.h5
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_frame_dispatcher_test.cc37
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_placeholder.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_resource_provider.cc175
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_resource_provider.h96
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/display_item.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/display_item.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunk.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/paint_property_node.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/paint_property_node_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/scroll_paint_property_node.cc42
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/scroll_paint_property_node.h26
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h12
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint_invalidation_reason.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint_invalidation_reason.h16
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint_invalidation_reason_test.cc27
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/static_bitmap_image.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/surface_layer_bridge.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/video_frame_resource_provider.cc21
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/video_frame_resource_provider.h9
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc56
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/video_frame_submitter.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/video_frame_submitter_test.cc9
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_wrapper.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/BUILD.gn1
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/BlinkGCDesign.md194
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/DEPS3
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/address_cache.cc10
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/address_cache.h19
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/address_cache_test.cc6
-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.cc7
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/gc_info.h34
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/gc_info_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap.cc50
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap.h47
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_allocator.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_allocator.h49
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_compact.cc170
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_compact.h18
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_compact_test.cc32
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_page.cc18
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_page.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_stats_collector.h19
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_test.cc67
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/incremental_marking_test.cc144
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/marking_verifier.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/marking_visitor.cc9
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/marking_visitor.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/persistent.h27
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/persistent_node.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/process_heap.cc12
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/safe_point.h39
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/thread_state.cc276
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/thread_state.h105
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/threading_traits.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/trace_traits.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/visitor.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/histogram.h25
-rw-r--r--chromium/third_party/blink/renderer/platform/histogram_test.cc15
-rw-r--r--chromium/third_party/blink/renderer/platform/image-decoders/DEPS2
-rw-r--r--chromium/third_party/blink/renderer/platform/image-decoders/ico/ico_image_decoder.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/image-decoders/image_decoder.cc39
-rw-r--r--chromium/third_party/blink/renderer/platform/image-decoders/image_decoder.h22
-rw-r--r--chromium/third_party/blink/renderer/platform/image-decoders/image_decoder_test.cc55
-rw-r--r--chromium/third_party/blink/renderer/platform/image-decoders/image_frame.cc20
-rw-r--r--chromium/third_party/blink/renderer/platform/image-decoders/image_frame.h13
-rw-r--r--chromium/third_party/blink/renderer/platform/image-decoders/image_frame_test.cc74
-rw-r--r--chromium/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.cc25
-rw-r--r--chromium/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.cc243
-rw-r--r--chromium/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder_test.cc267
-rw-r--r--chromium/third_party/blink/renderer/platform/image-decoders/png/png_image_reader.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder.cc47
-rw-r--r--chromium/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/image-encoders/DEPS6
-rw-r--r--chromium/third_party/blink/renderer/platform/image-encoders/image_encoder.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/image-encoders/image_encoder.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/image-encoders/image_encoder_utils.cc54
-rw-r--r--chromium/third_party/blink/renderer/platform/image-encoders/image_encoder_utils.h8
-rw-r--r--chromium/third_party/blink/renderer/platform/instrumentation/DEPS2
-rw-r--r--chromium/third_party/blink/renderer/platform/layout_unit.h78
-rw-r--r--chromium/third_party/blink/renderer/platform/lifecycle_notifier.h14
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/BUILD.gn5
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/OWNERS1
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/cors/cors.cc68
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/cors/cors.h18
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/cors/cors_error_string.cc432
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/cors/cors_error_string.h92
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/client_hints_preferences.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/fetch_context.cc2
-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_initiator_info.h31
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.cc43
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h77
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/https_state.cc22
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/https_state.h35
-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/raw_resource.cc69
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource.h12
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource.cc63
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource.h54
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_error.cc5
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_error.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc130
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.cc46
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc79
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h91
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader_options_test.cc108
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_request.cc104
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_request.h98
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_request_test.cc120
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_response.cc126
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_response.h80
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_timing_info.cc36
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_timing_info.h37
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/script_cached_metadata_handler.cc75
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/script_cached_metadata_handler.h65
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/script_fetch_options.cc5
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/subresource_integrity_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/testing/fetch_testing_platform_support.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/testing/mock_fetch_context.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/mac/theme_mac.mm1
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/media_stream_source.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/blink_typemaps.gni2
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/geometry_struct_traits_test.cc12
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/interface_invalidator.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/interface_invalidator_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/notification_struct_traits.cc287
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/notification_struct_traits.h140
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/notification_struct_traits_test.cc176
-rw-r--r--chromium/third_party/blink/renderer/platform/network/DEPS2
-rw-r--r--chromium/third_party/blink/renderer/platform/network/content_security_policy_parsers.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/network/content_security_policy_parsers.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/network/header_field_tokenizer.cc15
-rw-r--r--chromium/third_party/blink/renderer/platform/network/header_field_tokenizer.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/network/http_names.json51
-rw-r--r--chromium/third_party/blink/renderer/platform/network/parsed_content_header_field_parameters_test.cc11
-rw-r--r--chromium/third_party/blink/renderer/platform/platform_chrome_client.h54
-rw-r--r--chromium/third_party/blink/renderer/platform/runtime_enabled_features.json5266
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/BUILD.gn48
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/DEPS4
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/README.md41
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/base/DEPS7
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/base/proto/sequence_manager_test_description.proto67
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/base/sequence_manager_fuzzer.cc24
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/base/sequence_manager_fuzzer_processor.cc170
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/base/sequence_manager_fuzzer_processor.h102
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/base/sequence_manager_fuzzer_processor_unittest.cc347
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/child/features.cc19
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/child/features.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/child/process_state.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.cc54
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.h60
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/child/webthread_base.cc5
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler.cc5
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/background_scheduler.cc14
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/idle_helper.cc5
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/metrics_helper.cc53
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/metrics_helper.h26
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/metrics_helper_unittest.cc29
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/scheduler_helper.cc11
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/simple_thread_scheduler.cc83
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/simple_thread_scheduler.h75
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.cc51
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.h25
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/total_duration_metric_reporter.cc47
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/total_duration_metric_reporter.h43
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/total_duration_metric_reporter_unittest.cc45
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/web_thread_scheduler.cc10
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc532
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h116
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc287
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.cc79
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.h42
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller_unittest.cc70
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.cc7
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.h30
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc247
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h60
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc31
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.cc13
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h22
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc26
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h12
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc113
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/resource_loading_task_runner_handle_impl.cc5
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.cc125
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.h27
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/public/background_scheduler.h14
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h16
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/public/page_scheduler.h7
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/public/worker_scheduler.h11
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler_unittest.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/util/task_duration_metric_reporter.h61
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/utility/webthread_impl_for_utility_thread.cc35
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/utility/webthread_impl_for_utility_thread.h41
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.cc10
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_helper.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_impl.cc30
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_impl.h11
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_task_queue.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/worker/worker_metrics_helper.h8
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler.cc17
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy.h33
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy_unittest.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.cc61
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h23
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler_unittest.cc128
-rw-r--r--chromium/third_party/blink/renderer/platform/scoped_orientation_change_indicator.cc34
-rw-r--r--chromium/third_party/blink/renderer/platform/scoped_orientation_change_indicator.h37
-rw-r--r--chromium/third_party/blink/renderer/platform/scoped_orientation_change_indicator_test.cc44
-rw-r--r--chromium/third_party/blink/renderer/platform/scroll/DEPS12
-rw-r--r--chromium/third_party/blink/renderer/platform/scroll/overscroll_behavior.h24
-rw-r--r--chromium/third_party/blink/renderer/platform/scroll/scroll_alignment.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/scroll/scroll_types.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/scroll/web_scrollbar_theme_client.h20
-rw-r--r--chromium/third_party/blink/renderer/platform/shared_buffer.h14
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/code_cache_loader_mock.cc23
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/code_cache_loader_mock.h38
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/empty_web_media_player.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/fake_graphics_layer.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/fake_graphics_layer_client.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/image_decode_bench.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/paint_test_configurations.h5
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/testing_platform_support.cc12
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/testing_platform_support.h11
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/testing_platform_support_with_custom_scheduler.cc44
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/testing_platform_support_with_custom_scheduler.h39
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/testing_platform_support_with_web_rtc.cc34
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/testing_platform_support_with_web_rtc.h15
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/viewport_layers_setup.cc58
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/viewport_layers_setup.h44
-rw-r--r--chromium/third_party/blink/renderer/platform/text/character.cc9
-rw-r--r--chromium/third_party/blink/renderer/platform/text/character.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/text/text_break_iterator.cc44
-rw-r--r--chromium/third_party/blink/renderer/platform/text/text_break_iterator.h119
-rw-r--r--chromium/third_party/blink/renderer/platform/text/text_break_iterator_icu.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/text/text_break_iterator_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/text/text_run.cc5
-rw-r--r--chromium/third_party/blink/renderer/platform/text/text_run.h5
-rw-r--r--chromium/third_party/blink/renderer/platform/timer_test.cc293
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/matrix_transform_operation.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/perspective_transform_operation.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/rotate_transform_operation.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/rotation.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/scale_transform_operation.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/skew_transform_operation.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/transform_operations.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/translate_transform_operation.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/ukm_time_aggregator.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/ukm_time_aggregator_test.cc18
-rw-r--r--chromium/third_party/blink/renderer/platform/waitable_event.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/waitable_event.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/web_icon_sizes_parser.cc12
-rw-r--r--chromium/third_party/blink/renderer/platform/web_task_runner.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/web_thread_supporting_gc.cc13
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/DEPS3
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/kurl_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/origin_access_entry.cc141
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/origin_access_entry.h59
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/origin_access_entry_test.cc330
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/referrer.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/scheme_registry.cc5
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/scheme_registry.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/security_origin.cc24
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/security_origin.h15
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/security_origin_test.cc35
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/security_policy.cc183
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/security_policy.h30
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/security_policy_test.cc148
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/BUILD.gn7
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/DEPS9
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/allocator.cc20
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/allocator.h19
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/allocator/partition_allocator.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/allocator/partition_allocator.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/allocator/partitions.h5
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/compiler.h8
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/deque.h130
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/deque_test.cc16
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/doubly_linked_list.h89
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/doubly_linked_list_test.cc222
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/forward.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/functional.h17
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/hash_counted_set.h5
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/hash_map.h13
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/hash_set.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/hash_set_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/hash_table.h14
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/linked_hash_set.h15
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/list_hash_set.h7
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/math_extras.h74
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/not_found.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/ref_vector.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/stack_util.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/stack_util.h7
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/atomic_string.h35
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/cstring.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/cstring.h7
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/string_builder.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/string_concatenate.cc10
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/string_impl.cc329
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/string_impl.h257
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/wtf_string.cc17
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/wtf_string.h44
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/threading.cc122
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/threading_primitives.h16
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/threading_primitives_test.cc81
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/threading_pthreads.cc96
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/threading_win.cc102
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/type_traits.h9
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.cc19
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.h23
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/vector.h349
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/vector_test.cc14
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/wtf.cc13
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/wtf_size_t.h36
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/wtf_thread_data.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/wtf_thread_data.h4
-rw-r--r--chromium/third_party/blink/tools/apache_config/mime.types2
-rwxr-xr-xchromium/third_party/blink/tools/audit_non_blink_usage.py69
-rw-r--r--chromium/third_party/blink/tools/blinkpy/common/checkout/baseline_optimizer.py86
-rw-r--r--chromium/third_party/blink/tools/blinkpy/common/checkout/baseline_optimizer_unittest.py59
-rw-r--r--chromium/third_party/blink/tools/blinkpy/common/host_mock.py2
-rw-r--r--chromium/third_party/blink/tools/blinkpy/common/net/git_cl.py10
-rw-r--r--chromium/third_party/blink/tools/blinkpy/common/net/git_cl_unittest.py8
-rw-r--r--chromium/third_party/blink/tools/blinkpy/common/net/layout_test_results.py8
-rw-r--r--chromium/third_party/blink/tools/blinkpy/tool/blink_tool.py2
-rw-r--r--chromium/third_party/blink/tools/blinkpy/tool/commands/rebaseline.py47
-rw-r--r--chromium/third_party/blink/tools/blinkpy/tool/commands/rebaseline_unittest.py288
-rw-r--r--chromium/third_party/blink/tools/blinkpy/w3c/chromium_exportable_commits.py2
-rw-r--r--chromium/third_party/blink/tools/blinkpy/w3c/chromium_exportable_commits_unittest.py7
-rw-r--r--chromium/third_party/blink/tools/blinkpy/w3c/gerrit.py6
-rw-r--r--chromium/third_party/blink/tools/blinkpy/w3c/gerrit_unittest.py85
-rw-r--r--chromium/third_party/blink/tools/blinkpy/w3c/import_notifier.py2
-rw-r--r--chromium/third_party/blink/tools/blinkpy/w3c/monorail.py13
-rw-r--r--chromium/third_party/blink/tools/blinkpy/w3c/monorail_unittest.py27
-rw-r--r--chromium/third_party/blink/tools/blinkpy/w3c/test_importer.py3
-rw-r--r--chromium/third_party/blink/tools/blinkpy/w3c/test_importer_unittest.py1
-rw-r--r--chromium/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater.py29
-rw-r--r--chromium/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater_unittest.py32
-rw-r--r--chromium/third_party/blink/tools/blinkpy/w3c/wpt_manifest.py30
-rw-r--r--chromium/third_party/blink/tools/blinkpy/w3c/wpt_manifest_unittest.py46
-rw-r--r--chromium/third_party/blink/tools/blinkpy/web_tests/breakpad/dump_reader_multipart.py2
-rw-r--r--chromium/third_party/blink/tools/blinkpy/web_tests/controllers/layout_test_finder.py24
-rw-r--r--chromium/third_party/blink/tools/blinkpy/web_tests/controllers/layout_test_finder_unittest.py52
-rw-r--r--chromium/third_party/blink/tools/blinkpy/web_tests/controllers/layout_test_runner.py16
-rw-r--r--chromium/third_party/blink/tools/blinkpy/web_tests/controllers/manager.py12
-rw-r--r--chromium/third_party/blink/tools/blinkpy/web_tests/controllers/single_test_runner.py41
-rw-r--r--chromium/third_party/blink/tools/blinkpy/web_tests/layout_package/bot_test_expectations.py4
-rw-r--r--chromium/third_party/blink/tools/blinkpy/web_tests/models/test_expectations.py49
-rw-r--r--chromium/third_party/blink/tools/blinkpy/web_tests/models/test_expectations_unittest.py47
-rw-r--r--chromium/third_party/blink/tools/blinkpy/web_tests/models/test_run_results.py45
-rw-r--r--chromium/third_party/blink/tools/blinkpy/web_tests/models/test_run_results_unittest.py13
-rw-r--r--chromium/third_party/blink/tools/blinkpy/web_tests/port/android.py2
-rw-r--r--chromium/third_party/blink/tools/blinkpy/web_tests/port/base.py14
-rw-r--r--chromium/third_party/blink/tools/blinkpy/web_tests/run_webkit_tests_unittest.py205
-rw-r--r--chromium/third_party/blink/tools/blinkpy/web_tests/servers/apache_http.py9
-rw-r--r--chromium/third_party/blink/tools/blinkpy/web_tests/update_expectations.py2
-rw-r--r--chromium/third_party/blink/tools/blinkpy/web_tests/update_expectations_unittest.py36
3447 files changed, 69015 insertions, 51573 deletions
diff --git a/chromium/third_party/blink/common/BUILD.gn b/chromium/third_party/blink/common/BUILD.gn
index acb6d172b48..3da79548c5e 100644
--- a/chromium/third_party/blink/common/BUILD.gn
+++ b/chromium/third_party/blink/common/BUILD.gn
@@ -6,9 +6,12 @@ import("//build/config/jumbo.gni")
import("//testing/test.gni")
jumbo_source_set("common") {
+ # No target should directly depend on this target since this is just the
+ # source set rather than the actual component that can be linked to.
+ # Dependencies instead should be to //third_party/blink/public/common:common.
visibility = [
- "//third_party/blink/*",
- ":*",
+ "//third_party/blink/public/common",
+ "//third_party/blink/public:all_blink",
]
defines = [ "BLINK_COMMON_IMPLEMENTATION=1" ]
@@ -16,7 +19,10 @@ jumbo_source_set("common") {
sources = [
# NOTE: Please do not add public headers that need to be referenced from
# outside WebKit, add them in public/common instead.
+ "associated_interfaces/associated_interface_provider.cc",
+ "associated_interfaces/associated_interface_registry.cc",
"blob/blob_utils.cc",
+ "cache_storage/cache_storage_utils.cc",
"client_hints/client_hints.cc",
"common_export.h",
"device_memory/approximated_device_memory.cc",
@@ -25,9 +31,13 @@ jumbo_source_set("common") {
"features.cc",
"frame/frame_policy.cc",
"frame/user_activation_state.cc",
+ "indexeddb/indexeddb_key.cc",
+ "indexeddb/indexeddb_key_path.cc",
+ "indexeddb/indexeddb_key_range.cc",
+ "indexeddb/indexeddb_metadata.cc",
+ "indexeddb/indexeddb_struct_traits.cc",
"manifest/manifest.cc",
"manifest/manifest_icon_selector.cc",
- "manifest/manifest_share_target_util.cc",
"message_port/cloneable_message.cc",
"message_port/cloneable_message_struct_traits.cc",
"message_port/cloneable_message_struct_traits.h",
@@ -37,7 +47,6 @@ jumbo_source_set("common") {
"message_port/transferable_message_struct_traits.cc",
"message_port/transferable_message_struct_traits.h",
"mime_util/mime_util.cc",
- "oom_intervention/oom_intervention_types.h",
"origin_policy/origin_policy.cc",
"origin_policy/origin_policy_parser.cc",
"origin_policy/origin_policy_parser.h",
@@ -64,6 +73,15 @@ jumbo_source_set("common") {
if (!is_ios) {
deps += [ "//media" ]
}
+
+ if (is_android) {
+ sources += [
+ "font_unique_name_lookup/font_table_matcher.cc",
+ "font_unique_name_lookup/icu_fold_case_util.cc",
+ ]
+
+ deps += [ "//third_party/icu" ]
+ }
}
test("blink_common_unittests") {
@@ -87,8 +105,8 @@ jumbo_source_set("common_unittests_sources") {
"device_memory/approximated_device_memory_unittest.cc",
"feature_policy/feature_policy_unittest.cc",
"frame/user_activation_state_unittest.cc",
+ "indexeddb/indexeddb_key_unittest.cc",
"manifest/manifest_icon_selector_unittest.cc",
- "manifest/manifest_share_target_util_unittest.cc",
"mime_util/mime_util_unittest.cc",
"origin_policy/origin_policy_unittest.cc",
"origin_trials/trial_token_unittest.cc",
@@ -96,13 +114,6 @@ jumbo_source_set("common_unittests_sources") {
"test/run_all_unittests.cc",
]
- if (!is_android) {
- # TODO(crbug.com/845384): Enable these tests also on Android. Currently
- # they are excluded as they require V8 environment but V8 snapshot is
- # not available in the current minimum test setting.
- sources += [ "message_port/string_message_codec_unittest.cc" ]
- }
-
deps = [
"//base",
"//base/test:test_support",
@@ -113,4 +124,17 @@ jumbo_source_set("common_unittests_sources") {
"//v8",
"//v8:v8_libplatform",
]
+
+ if (!is_android) {
+ # TODO(crbug.com/845384): Enable these tests also on Android. Currently
+ # they are excluded as they require V8 environment but V8 snapshot is
+ # not available in the current minimum test setting.
+ sources += [ "message_port/string_message_codec_unittest.cc" ]
+ } else {
+ # is_android
+ sources += [
+ "font_unique_name_lookup/font_table_matcher_unittest.cc",
+ "font_unique_name_lookup/icu_fold_case_util_unittest.cc",
+ ]
+ }
}
diff --git a/chromium/third_party/blink/common/DEPS b/chromium/third_party/blink/common/DEPS
index 2e888778edb..ddc8edbbefd 100644
--- a/chromium/third_party/blink/common/DEPS
+++ b/chromium/third_party/blink/common/DEPS
@@ -17,6 +17,7 @@ include_rules = [
"+third_party/blink/common",
"+third_party/blink/public/common",
"+third_party/blink/public/mojom",
+ "+third_party/icu/source/common/unicode/unistr.h",
"+ui/gfx/geometry",
"+url",
]
diff --git a/chromium/third_party/blink/common/associated_interfaces/associated_interface_provider.cc b/chromium/third_party/blink/common/associated_interfaces/associated_interface_provider.cc
new file mode 100644
index 00000000000..e87b89fd701
--- /dev/null
+++ b/chromium/third_party/blink/common/associated_interfaces/associated_interface_provider.cc
@@ -0,0 +1,83 @@
+// 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/common/associated_interfaces/associated_interface_provider.h"
+
+#include <map>
+
+#include "mojo/public/cpp/bindings/associated_binding.h"
+
+namespace blink {
+
+class AssociatedInterfaceProvider::LocalProvider
+ : public mojom::AssociatedInterfaceProvider {
+ public:
+ using Binder =
+ base::RepeatingCallback<void(mojo::ScopedInterfaceEndpointHandle)>;
+
+ LocalProvider(mojom::AssociatedInterfaceProviderAssociatedPtr* proxy,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner)
+ : associated_interface_provider_binding_(this) {
+ associated_interface_provider_binding_.Bind(
+ mojo::MakeRequestAssociatedWithDedicatedPipe(proxy),
+ std::move(task_runner));
+ }
+
+ ~LocalProvider() override {}
+
+ void SetBinderForName(const std::string& name, const Binder& binder) {
+ binders_[name] = binder;
+ }
+
+ private:
+ // mojom::AssociatedInterfaceProvider:
+ void GetAssociatedInterface(
+ const std::string& name,
+ mojom::AssociatedInterfaceAssociatedRequest request) override {
+ auto it = binders_.find(name);
+ if (it != binders_.end())
+ it->second.Run(request.PassHandle());
+ }
+
+ std::map<std::string, Binder> binders_;
+ mojo::AssociatedBinding<mojom::AssociatedInterfaceProvider>
+ associated_interface_provider_binding_;
+
+ DISALLOW_COPY_AND_ASSIGN(LocalProvider);
+};
+
+AssociatedInterfaceProvider::AssociatedInterfaceProvider(
+ mojom::AssociatedInterfaceProviderAssociatedPtr proxy,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner)
+ : proxy_(std::move(proxy)), task_runner_(std::move(task_runner)) {
+ DCHECK(proxy_.is_bound());
+}
+
+AssociatedInterfaceProvider::AssociatedInterfaceProvider(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner)
+ : local_provider_(std::make_unique<LocalProvider>(&proxy_, task_runner)),
+ task_runner_(std::move(task_runner)) {}
+
+AssociatedInterfaceProvider::~AssociatedInterfaceProvider() = default;
+
+void AssociatedInterfaceProvider::GetInterface(
+ const std::string& name,
+ mojo::ScopedInterfaceEndpointHandle handle) {
+ proxy_->GetAssociatedInterface(
+ name, mojom::AssociatedInterfaceAssociatedRequest(std::move(handle)));
+}
+
+void AssociatedInterfaceProvider::OverrideBinderForTesting(
+ const std::string& name,
+ const base::RepeatingCallback<void(mojo::ScopedInterfaceEndpointHandle)>&
+ binder) {
+ if (!local_provider_) {
+ DCHECK(proxy_.is_bound());
+ proxy_.reset();
+ local_provider_ = std::make_unique<LocalProvider>(&proxy_, task_runner_);
+ }
+ local_provider_->SetBinderForName(name, binder);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/common/associated_interfaces/associated_interface_registry.cc b/chromium/third_party/blink/common/associated_interfaces/associated_interface_registry.cc
new file mode 100644
index 00000000000..652296dc5c8
--- /dev/null
+++ b/chromium/third_party/blink/common/associated_interfaces/associated_interface_registry.cc
@@ -0,0 +1,38 @@
+// 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/common/associated_interfaces/associated_interface_registry.h"
+
+namespace blink {
+
+AssociatedInterfaceRegistry::AssociatedInterfaceRegistry() = default;
+
+AssociatedInterfaceRegistry::~AssociatedInterfaceRegistry() = default;
+
+void AssociatedInterfaceRegistry::AddInterface(const std::string& name,
+ const Binder& binder) {
+ auto result = interfaces_.emplace(name, binder);
+ DCHECK(result.second);
+}
+
+void AssociatedInterfaceRegistry::RemoveInterface(const std::string& name) {
+ interfaces_.erase(name);
+}
+
+bool AssociatedInterfaceRegistry::TryBindInterface(
+ const std::string& name,
+ mojo::ScopedInterfaceEndpointHandle* handle) {
+ auto it = interfaces_.find(name);
+ if (it == interfaces_.end())
+ return false;
+ it->second.Run(std::move(*handle));
+ return true;
+}
+
+base::WeakPtr<AssociatedInterfaceRegistry>
+AssociatedInterfaceRegistry::GetWeakPtr() {
+ return weak_ptr_factory_.GetWeakPtr();
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/common/cache_storage/OWNERS b/chromium/third_party/blink/common/cache_storage/OWNERS
new file mode 100644
index 00000000000..3ce03920c6f
--- /dev/null
+++ b/chromium/third_party/blink/common/cache_storage/OWNERS
@@ -0,0 +1,4 @@
+file://content/browser/cache_storage/OWNERS
+
+per-file *.mojom=set noparent
+per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/chromium/third_party/blink/common/cache_storage/cache_storage_utils.cc b/chromium/third_party/blink/common/cache_storage/cache_storage_utils.cc
new file mode 100644
index 00000000000..2955ceed7fc
--- /dev/null
+++ b/chromium/third_party/blink/common/cache_storage/cache_storage_utils.cc
@@ -0,0 +1,16 @@
+// 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/common/cache_storage/cache_storage_utils.h"
+
+namespace blink {
+namespace cache_storage {
+
+// TODO(crbug.com/877737): Remove this once the cache.addAll() duplicate
+// rejection finally ships.
+// static
+const char kDuplicateOperationBaseMessage[] = "duplicate requests";
+
+} // namespace cache_storage
+} // namespace blink
diff --git a/chromium/third_party/blink/common/features.cc b/chromium/third_party/blink/common/features.cc
index 867e24ab6b8..84733092f72 100644
--- a/chromium/third_party/blink/common/features.cc
+++ b/chromium/third_party/blink/common/features.cc
@@ -4,9 +4,14 @@
#include "third_party/blink/public/common/features.h"
+#include "build/build_config.h"
+
namespace blink {
namespace features {
+const base::Feature kAutofillPreviewStyleExperiment{
+ "AutofillPreviewStyleExperiment", base::FEATURE_DISABLED_BY_DEFAULT};
+
// Enable eagerly setting up a CacheStorage interface pointer and
// passing it to service workers on startup as an optimization.
const base::Feature kEagerCacheStorageSetupForServiceWorkers{
@@ -25,10 +30,51 @@ const base::Feature kMojoBlobURLs{"MojoBlobURLs",
const base::Feature kNestedWorkers{"NestedWorkers",
base::FEATURE_ENABLED_BY_DEFAULT};
+const base::Feature kServiceWorkerImportedScriptUpdateCheck{
+ "ServiceWorkerImportedScriptUpdateCheck",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
// Enable new service worker glue for NetworkService. Can be
// enabled independently of NetworkService.
const base::Feature kServiceWorkerServicification{
"ServiceWorkerServicification", base::FEATURE_DISABLED_BY_DEFAULT};
+// Used to control the collection of anchor element metrics (crbug.com/856683).
+// If kRecordAnchorMetricsClicked is enabled, then metrics of anchor elements
+// clicked by the user will be extracted and recorded.
+// If kRecordAnchorMetricsVisible is enabled, then metrics of anchor elements
+// in the first viewport after the page load will be extracted and recorded.
+const base::Feature kRecordAnchorMetricsClicked{
+ "RecordAnchorMetricsClicked", base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kRecordAnchorMetricsVisible{
+ "RecordAnchorMetricsVisible", base::FEATURE_DISABLED_BY_DEFAULT};
+
+// Enable Portals. https://crbug.com/865123.
+const base::Feature kPortals{"Portals", base::FEATURE_DISABLED_BY_DEFAULT};
+
+// Freeze scheduler task queues in background after allowed grace time.
+// "stop" is a legacy name.
+const base::Feature kStopInBackground {
+ "stop-in-background",
+#if defined(OS_ANDROID)
+ base::FEATURE_ENABLED_BY_DEFAULT
+#else
+ base::FEATURE_DISABLED_BY_DEFAULT
+#endif
+};
+
+// Freeze non-timer task queues in background, after allowed grace time. Launch
+// bug: https://crbug.com/822954. "stop" is a legacy name.
+const base::Feature kStopNonTimersInBackground{
+ "stop-non-timers-in-background", base::FEATURE_DISABLED_BY_DEFAULT};
+
+// Writable files and native filesystem access. https://crbug.com/853326
+const base::Feature kWritableFilesAPI{"WritableFilesAPI",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
+const char kAutofillPreviewStyleExperimentBgColorParameterName[] = "bg_color";
+
+const char kAutofillPreviewStyleExperimentColorParameterName[] = "color";
+
} // namespace features
} // namespace blink
diff --git a/chromium/third_party/blink/common/font_unique_name_lookup/font_table_matcher.cc b/chromium/third_party/blink/common/font_unique_name_lookup/font_table_matcher.cc
new file mode 100644
index 00000000000..b647d2689ba
--- /dev/null
+++ b/chromium/third_party/blink/common/font_unique_name_lookup/font_table_matcher.cc
@@ -0,0 +1,70 @@
+// 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/common/font_unique_name_lookup/font_table_matcher.h"
+#include "base/strings/utf_string_conversions.h"
+#include "third_party/blink/public/common/font_unique_name_lookup/icu_fold_case_util.h"
+
+#include <algorithm>
+
+namespace blink {
+
+FontTableMatcher::FontTableMatcher(
+ const base::ReadOnlySharedMemoryMapping& mapping) {
+ font_table_.ParseFromArray(mapping.memory(), mapping.size());
+}
+
+// static
+base::ReadOnlySharedMemoryMapping
+FontTableMatcher::MemoryMappingFromFontUniqueNameTable(
+ const FontUniqueNameTable& font_unique_name_table) {
+ size_t serialization_size = font_unique_name_table.ByteSizeLong();
+ CHECK(serialization_size);
+ base::MappedReadOnlyRegion mapped_region =
+ base::ReadOnlySharedMemoryRegion::Create(serialization_size);
+ font_unique_name_table.SerializeToArray(mapped_region.mapping.memory(),
+ mapped_region.mapping.mapped_size());
+ return mapped_region.region.Map();
+}
+
+base::Optional<FontTableMatcher::MatchResult> FontTableMatcher::MatchName(
+ const std::string& name_request) const {
+ std::string folded_name_request = IcuFoldCase(name_request);
+ const auto& font_entries = font_table_.font_entries();
+ auto find_result = std::find_if(
+ font_entries.begin(), font_entries.end(),
+ [&folded_name_request](
+ const FontUniqueNameTable_FontUniqueNameEntry& entry) {
+ return !entry.postscript_name().compare(folded_name_request) ||
+ !entry.full_name().compare(folded_name_request);
+ });
+ if (find_result != font_entries.end()) {
+ return base::Optional<MatchResult>(
+ {find_result->file_path(), find_result->ttc_index()});
+ }
+ return {};
+}
+
+size_t FontTableMatcher::AvailableFonts() const {
+ return font_table_.font_entries_size();
+}
+
+bool FontTableMatcher::FontListIsDisjointFrom(
+ const FontTableMatcher& other) const {
+ std::vector<std::string> paths_self, paths_other, intersection_result;
+ for (const auto& indexed_font : font_table_.font_entries()) {
+ paths_self.push_back(indexed_font.file_path());
+ }
+ for (const auto& indexed_font_other : other.font_table_.font_entries()) {
+ paths_other.push_back(indexed_font_other.file_path());
+ }
+ std::sort(paths_self.begin(), paths_self.end());
+ std::sort(paths_other.begin(), paths_other.end());
+ std::set_intersection(paths_self.begin(), paths_self.end(),
+ paths_other.begin(), paths_other.end(),
+ std::back_inserter(intersection_result));
+ return intersection_result.empty();
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/common/font_unique_name_lookup/font_table_matcher_unittest.cc b/chromium/third_party/blink/common/font_unique_name_lookup/font_table_matcher_unittest.cc
new file mode 100644
index 00000000000..6fd6fb9c6b2
--- /dev/null
+++ b/chromium/third_party/blink/common/font_unique_name_lookup/font_table_matcher_unittest.cc
@@ -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.
+
+#include "third_party/blink/public/common/font_unique_name_lookup/font_table_matcher.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/font_unique_name_lookup/icu_fold_case_util.h"
+
+namespace {
+const char kTestFilePath1[] = "tmp/test/font1.ttf";
+const char kDummyAndroidBuildFingerPrint[] = "A";
+
+void PopulateFontUniqueNameEntry(
+ blink::FontUniqueNameTable_FontUniqueNameEntry* entry,
+ const std::string& path,
+ int32_t ttc_index,
+ const std::string& full_name,
+ const std::string& postscript_name) {
+ entry->set_file_path(path);
+ entry->set_ttc_index(ttc_index);
+ entry->set_full_name(blink::IcuFoldCase(full_name));
+ entry->set_postscript_name(blink::IcuFoldCase(postscript_name));
+}
+
+} // namespace
+
+namespace blink {
+
+class FontTableMatcherTest : public ::testing::Test {
+ protected:
+ void SetUp() override {
+ FontUniqueNameTable font_unique_name_table;
+ font_unique_name_table.set_stored_for_android_build_fp(
+ kDummyAndroidBuildFingerPrint);
+ PopulateFontUniqueNameEntry(font_unique_name_table.add_font_entries(),
+ kTestFilePath1, 0, "FONT NAME UPPERCASE",
+ "FONT-NAME-UPPERCASE");
+ base::ReadOnlySharedMemoryMapping mapping =
+ FontTableMatcher::MemoryMappingFromFontUniqueNameTable(
+ std::move(font_unique_name_table));
+
+ matcher_ = std::make_unique<FontTableMatcher>(mapping);
+ }
+
+ std::unique_ptr<FontTableMatcher> matcher_;
+};
+
+TEST_F(FontTableMatcherTest, CaseInsensitiveMatchingBothNames) {
+ ASSERT_EQ(matcher_->AvailableFonts(), 1u);
+ base::Optional<FontTableMatcher::MatchResult> result =
+ matcher_->MatchName("font name uppercase");
+ ASSERT_TRUE(result.has_value());
+ ASSERT_EQ(result->font_path, kTestFilePath1);
+ ASSERT_EQ(result->ttc_index, 0u);
+
+ result = matcher_->MatchName("font-name-uppercase");
+ ASSERT_TRUE(result.has_value());
+ ASSERT_EQ(result->font_path, kTestFilePath1);
+ ASSERT_EQ(result->ttc_index, 0u);
+}
+
+TEST_F(FontTableMatcherTest, NoSubStringMatching) {
+ ASSERT_EQ(matcher_->AvailableFonts(), 1u);
+ base::Optional<FontTableMatcher::MatchResult> result =
+ matcher_->MatchName("font name");
+ ASSERT_FALSE(result.has_value());
+
+ result = matcher_->MatchName("font-name");
+ ASSERT_FALSE(result.has_value());
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/common/font_unique_name_lookup/icu_fold_case_util.cc b/chromium/third_party/blink/common/font_unique_name_lookup/icu_fold_case_util.cc
new file mode 100644
index 00000000000..048679cf1fa
--- /dev/null
+++ b/chromium/third_party/blink/common/font_unique_name_lookup/icu_fold_case_util.cc
@@ -0,0 +1,19 @@
+// 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/common/font_unique_name_lookup/icu_fold_case_util.h"
+#include "third_party/icu/source/common/unicode/unistr.h"
+
+namespace blink {
+
+std::string IcuFoldCase(const std::string& name_request) {
+ icu_62::UnicodeString name_request_unicode =
+ icu_62::UnicodeString::fromUTF8(name_request);
+ name_request_unicode.foldCase();
+ std::string name_request_lower;
+ name_request_unicode.toUTF8String(name_request_lower);
+ return name_request_lower;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/common/font_unique_name_lookup/icu_fold_case_util_unittest.cc b/chromium/third_party/blink/common/font_unique_name_lookup/icu_fold_case_util_unittest.cc
new file mode 100644
index 00000000000..12b3d5ddcf5
--- /dev/null
+++ b/chromium/third_party/blink/common/font_unique_name_lookup/icu_fold_case_util_unittest.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/public/common/font_unique_name_lookup/icu_fold_case_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace blink {
+
+TEST(IcuFoldCaseUtilTest, FoldingExamples) {
+ ASSERT_EQ(IcuFoldCase("Roboto Condensed Bold Italic"),
+ IcuFoldCase("roboto condensed bold italic"));
+ ASSERT_EQ(IcuFoldCase("NotoSansDevanagariUI-Bold"),
+ IcuFoldCase("notosansdevanagariui-bold"));
+ ASSERT_EQ(IcuFoldCase(""), IcuFoldCase(""));
+ ASSERT_EQ(IcuFoldCase("12345"), IcuFoldCase("12345"));
+ ASSERT_EQ(IcuFoldCase("СКОРБЬ СХОДИТ ЩЕДРОТ"),
+ IcuFoldCase("скорбь сходит щедрот"));
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/common/frame/user_activation_state.cc b/chromium/third_party/blink/common/frame/user_activation_state.cc
index ddba4e350a5..ff8b4fa3bcd 100644
--- a/chromium/third_party/blink/common/frame/user_activation_state.cc
+++ b/chromium/third_party/blink/common/frame/user_activation_state.cc
@@ -6,12 +6,11 @@
namespace blink {
-// This is a tentative timespan, which should be more than the current limit of
-// 1 sec (in UGI) because we want a reasonable value that works even for a slow
-// network. Currently we are experimenting with a vary large value (eqvt to no
-// expiry): https://crbug.com/776404.
+// The expiry time should be long enough to allow network round trips even in a
+// very slow connection (to support xhr-like calls with user activation), yet
+// not too long to make an "unattneded" page feel activated.
constexpr base::TimeDelta kActivationLifespan =
- base::TimeDelta::FromSeconds(3600);
+ base::TimeDelta::FromSeconds(30);
void UserActivationState::Activate() {
has_been_active_ = true;
diff --git a/chromium/third_party/blink/common/frame/user_activation_state_unittest.cc b/chromium/third_party/blink/common/frame/user_activation_state_unittest.cc
index 4b189ce328c..1968ed10391 100644
--- a/chromium/third_party/blink/common/frame/user_activation_state_unittest.cc
+++ b/chromium/third_party/blink/common/frame/user_activation_state_unittest.cc
@@ -65,7 +65,7 @@ TEST_F(UserActivationStateTest, ExpirationTest) {
user_activation_state.Activate();
// Right before activation expiry, both bits remain set.
- AdvanceClock(base::TimeDelta::FromSeconds(3599));
+ AdvanceClock(base::TimeDelta::FromSeconds(29));
EXPECT_TRUE(user_activation_state.HasBeenActive());
EXPECT_TRUE(user_activation_state.IsActive());
@@ -99,7 +99,7 @@ TEST_F(UserActivationStateTest, ConsumptionPlusExpirationTest) {
// An activation is not consumable after expiry.
user_activation_state.Activate();
- AdvanceClock(base::TimeDelta::FromSeconds(3600));
+ AdvanceClock(base::TimeDelta::FromSeconds(30));
EXPECT_FALSE(user_activation_state.ConsumeIfActive());
// Consecutive activations within expiry is consumable only once.
diff --git a/chromium/third_party/blink/common/indexeddb/OWNERS b/chromium/third_party/blink/common/indexeddb/OWNERS
new file mode 100644
index 00000000000..3b5f7f58e91
--- /dev/null
+++ b/chromium/third_party/blink/common/indexeddb/OWNERS
@@ -0,0 +1,9 @@
+file://content/browser/indexed_db/OWNERS
+
+per-file *_struct_traits*.*=set noparent
+per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS
+per-file *.typemap=set noparent
+per-file *.typemap=file://ipc/SECURITY_OWNERS
+
+# TEAM: storage-dev@chromium.org
+# COMPONENT: Blink>Storage>IndexedDB
diff --git a/chromium/third_party/blink/common/indexeddb/indexeddb_key.cc b/chromium/third_party/blink/common/indexeddb/indexeddb_key.cc
new file mode 100644
index 00000000000..9f5e6fe2bff
--- /dev/null
+++ b/chromium/third_party/blink/common/indexeddb/indexeddb_key.cc
@@ -0,0 +1,143 @@
+// 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/public/common/indexeddb/indexeddb_key.h"
+
+#include <string>
+
+namespace blink {
+
+using blink::WebIDBKeyType;
+using blink::kWebIDBKeyTypeArray;
+using blink::kWebIDBKeyTypeBinary;
+using blink::kWebIDBKeyTypeDate;
+using blink::kWebIDBKeyTypeInvalid;
+using blink::kWebIDBKeyTypeMin;
+using blink::kWebIDBKeyTypeNull;
+using blink::kWebIDBKeyTypeNumber;
+using blink::kWebIDBKeyTypeString;
+
+namespace {
+
+// Very rough estimate of minimum key size overhead.
+const size_t kOverheadSize = 16;
+
+static size_t CalculateArraySize(const IndexedDBKey::KeyArray& keys) {
+ size_t size(0);
+ for (size_t i = 0; i < keys.size(); ++i)
+ size += keys[i].size_estimate();
+ return size;
+}
+
+template <typename T>
+int Compare(const T& a, const T& b) {
+ // Using '<' for both comparisons here is as generic as possible (for e.g.
+ // objects which only define operator<() and not operator>() or operator==())
+ // and also allows e.g. floating point NaNs to compare equal.
+ if (a < b)
+ return -1;
+ return (b < a) ? 1 : 0;
+}
+
+template <typename T>
+static IndexedDBKey::KeyArray CopyKeyArray(const T& array) {
+ IndexedDBKey::KeyArray result;
+ result.reserve(array.size());
+ for (size_t i = 0; i < array.size(); ++i) {
+ result.push_back(IndexedDBKey(array[i]));
+ }
+ return result;
+}
+
+} // namespace
+
+IndexedDBKey::IndexedDBKey()
+ : type_(kWebIDBKeyTypeNull), size_estimate_(kOverheadSize) {}
+
+IndexedDBKey::IndexedDBKey(WebIDBKeyType type)
+ : type_(type), size_estimate_(kOverheadSize) {
+ DCHECK(type == kWebIDBKeyTypeNull || type == kWebIDBKeyTypeInvalid);
+}
+
+IndexedDBKey::IndexedDBKey(double number, WebIDBKeyType type)
+ : type_(type),
+ number_(number),
+ size_estimate_(kOverheadSize + sizeof(number)) {
+ DCHECK(type == kWebIDBKeyTypeNumber || type == kWebIDBKeyTypeDate);
+}
+
+IndexedDBKey::IndexedDBKey(const KeyArray& array)
+ : type_(kWebIDBKeyTypeArray),
+ array_(CopyKeyArray(array)),
+ size_estimate_(kOverheadSize + CalculateArraySize(array)) {}
+
+IndexedDBKey::IndexedDBKey(const std::string& binary)
+ : type_(kWebIDBKeyTypeBinary),
+ binary_(binary),
+ size_estimate_(kOverheadSize +
+ (binary.length() * sizeof(std::string::value_type))) {}
+
+IndexedDBKey::IndexedDBKey(const base::string16& string)
+ : type_(kWebIDBKeyTypeString),
+ string_(string),
+ size_estimate_(kOverheadSize +
+ (string.length() * sizeof(base::string16::value_type))) {}
+
+IndexedDBKey::IndexedDBKey(const IndexedDBKey& other) = default;
+IndexedDBKey::~IndexedDBKey() = default;
+IndexedDBKey& IndexedDBKey::operator=(const IndexedDBKey& other) = default;
+
+bool IndexedDBKey::IsValid() const {
+ if (type_ == kWebIDBKeyTypeInvalid || type_ == kWebIDBKeyTypeNull)
+ return false;
+
+ if (type_ == kWebIDBKeyTypeArray) {
+ for (size_t i = 0; i < array_.size(); i++) {
+ if (!array_[i].IsValid())
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool IndexedDBKey::IsLessThan(const IndexedDBKey& other) const {
+ return CompareTo(other) < 0;
+}
+
+bool IndexedDBKey::Equals(const IndexedDBKey& other) const {
+ return !CompareTo(other);
+}
+
+int IndexedDBKey::CompareTo(const IndexedDBKey& other) const {
+ DCHECK(IsValid());
+ DCHECK(other.IsValid());
+ if (type_ != other.type_)
+ return type_ > other.type_ ? -1 : 1;
+
+ switch (type_) {
+ case kWebIDBKeyTypeArray:
+ for (size_t i = 0; i < array_.size() && i < other.array_.size(); ++i) {
+ int result = array_[i].CompareTo(other.array_[i]);
+ if (result != 0)
+ return result;
+ }
+ return Compare(array_.size(), other.array_.size());
+ case kWebIDBKeyTypeBinary:
+ return binary_.compare(other.binary_);
+ case kWebIDBKeyTypeString:
+ return string_.compare(other.string_);
+ case kWebIDBKeyTypeDate:
+ case kWebIDBKeyTypeNumber:
+ return Compare(number_, other.number_);
+ case kWebIDBKeyTypeInvalid:
+ case kWebIDBKeyTypeNull:
+ case kWebIDBKeyTypeMin:
+ default:
+ NOTREACHED();
+ return 0;
+ }
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/common/indexeddb/indexeddb_key_path.cc b/chromium/third_party/blink/common/indexeddb/indexeddb_key_path.cc
new file mode 100644
index 00000000000..25699ec9103
--- /dev/null
+++ b/chromium/third_party/blink/common/indexeddb/indexeddb_key_path.cc
@@ -0,0 +1,57 @@
+// 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/public/common/indexeddb/indexeddb_key_path.h"
+
+#include "base/logging.h"
+
+namespace blink {
+
+using blink::kWebIDBKeyPathTypeArray;
+using blink::kWebIDBKeyPathTypeNull;
+using blink::kWebIDBKeyPathTypeString;
+
+IndexedDBKeyPath::IndexedDBKeyPath() : type_(kWebIDBKeyPathTypeNull) {}
+
+IndexedDBKeyPath::IndexedDBKeyPath(const base::string16& string)
+ : type_(kWebIDBKeyPathTypeString), string_(string) {}
+
+IndexedDBKeyPath::IndexedDBKeyPath(const std::vector<base::string16>& array)
+ : type_(kWebIDBKeyPathTypeArray), array_(array) {}
+
+IndexedDBKeyPath::IndexedDBKeyPath(const IndexedDBKeyPath& other) = default;
+IndexedDBKeyPath::IndexedDBKeyPath(IndexedDBKeyPath&& other) = default;
+IndexedDBKeyPath::~IndexedDBKeyPath() = default;
+IndexedDBKeyPath& IndexedDBKeyPath::operator=(const IndexedDBKeyPath& other) =
+ default;
+IndexedDBKeyPath& IndexedDBKeyPath::operator=(IndexedDBKeyPath&& other) =
+ default;
+
+const std::vector<base::string16>& IndexedDBKeyPath::array() const {
+ DCHECK(type_ == blink::kWebIDBKeyPathTypeArray);
+ return array_;
+}
+
+const base::string16& IndexedDBKeyPath::string() const {
+ DCHECK(type_ == blink::kWebIDBKeyPathTypeString);
+ return string_;
+}
+
+bool IndexedDBKeyPath::operator==(const IndexedDBKeyPath& other) const {
+ if (type_ != other.type_)
+ return false;
+
+ switch (type_) {
+ case kWebIDBKeyPathTypeNull:
+ return true;
+ case kWebIDBKeyPathTypeString:
+ return string_ == other.string_;
+ case kWebIDBKeyPathTypeArray:
+ return array_ == other.array_;
+ }
+ NOTREACHED();
+ return false;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/common/indexeddb/indexeddb_key_range.cc b/chromium/third_party/blink/common/indexeddb/indexeddb_key_range.cc
new file mode 100644
index 00000000000..6e64a12558d
--- /dev/null
+++ b/chromium/third_party/blink/common/indexeddb/indexeddb_key_range.cc
@@ -0,0 +1,44 @@
+// 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/public/common/indexeddb/indexeddb_key_range.h"
+
+#include "base/logging.h"
+#include "third_party/blink/public/common/indexeddb/web_idb_types.h"
+
+namespace blink {
+
+IndexedDBKeyRange::IndexedDBKeyRange() = default;
+
+IndexedDBKeyRange::IndexedDBKeyRange(const blink::IndexedDBKey& lower,
+ const blink::IndexedDBKey& upper,
+ bool lower_open,
+ bool upper_open)
+ : lower_(lower),
+ upper_(upper),
+ lower_open_(lower_open),
+ upper_open_(upper_open) {}
+
+IndexedDBKeyRange::IndexedDBKeyRange(const blink::IndexedDBKey& key)
+ : lower_(key), upper_(key) {}
+
+IndexedDBKeyRange::IndexedDBKeyRange(const IndexedDBKeyRange& other) = default;
+IndexedDBKeyRange::~IndexedDBKeyRange() = default;
+IndexedDBKeyRange& IndexedDBKeyRange::operator=(
+ const IndexedDBKeyRange& other) = default;
+
+bool IndexedDBKeyRange::IsOnlyKey() const {
+ if (lower_open_ || upper_open_)
+ return false;
+ if (IsEmpty())
+ return false;
+
+ return lower_.Equals(upper_);
+}
+
+bool IndexedDBKeyRange::IsEmpty() const {
+ return !lower_.IsValid() && !upper_.IsValid();
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/common/indexeddb/indexeddb_key_unittest.cc b/chromium/third_party/blink/common/indexeddb/indexeddb_key_unittest.cc
new file mode 100644
index 00000000000..ea3199deb76
--- /dev/null
+++ b/chromium/third_party/blink/common/indexeddb/indexeddb_key_unittest.cc
@@ -0,0 +1,59 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/public/common/indexeddb/indexeddb_key.h"
+
+#include <stddef.h>
+
+#include <vector>
+
+#include "base/strings/string16.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace blink {
+
+namespace {
+
+TEST(IndexedDBKeyTest, KeySizeEstimates) {
+ std::vector<IndexedDBKey> keys;
+ std::vector<size_t> estimates;
+
+ keys.push_back(IndexedDBKey());
+ estimates.push_back(16u); // Overhead.
+
+ keys.push_back(IndexedDBKey(blink::kWebIDBKeyTypeNull));
+ estimates.push_back(16u);
+
+ double number = 3.14159;
+ keys.push_back(IndexedDBKey(number, blink::kWebIDBKeyTypeNumber));
+ estimates.push_back(24u); // Overhead + sizeof(double).
+
+ double date = 1370884329.0;
+ keys.push_back(IndexedDBKey(date, blink::kWebIDBKeyTypeDate));
+ estimates.push_back(24u); // Overhead + sizeof(double).
+
+ const base::string16 string(1024, static_cast<base::char16>('X'));
+ keys.push_back(IndexedDBKey(string));
+ // Overhead + string length * sizeof(base::char16).
+ estimates.push_back(2064u);
+
+ const size_t array_size = 1024;
+ IndexedDBKey::KeyArray array;
+ double value = 123.456;
+ for (size_t i = 0; i < array_size; ++i) {
+ array.push_back(IndexedDBKey(value, blink::kWebIDBKeyTypeNumber));
+ }
+ keys.push_back(IndexedDBKey(array));
+ // Overhead + array length * (Overhead + sizeof(double)).
+ estimates.push_back(24592u);
+
+ ASSERT_EQ(keys.size(), estimates.size());
+ for (size_t i = 0; i < keys.size(); ++i) {
+ EXPECT_EQ(estimates[i], keys[i].size_estimate());
+ }
+}
+
+} // namespace
+
+} // namespace blink
diff --git a/chromium/third_party/blink/common/indexeddb/indexeddb_metadata.cc b/chromium/third_party/blink/common/indexeddb/indexeddb_metadata.cc
new file mode 100644
index 00000000000..9349732048a
--- /dev/null
+++ b/chromium/third_party/blink/common/indexeddb/indexeddb_metadata.cc
@@ -0,0 +1,106 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/public/common/indexeddb/indexeddb_metadata.h"
+
+using blink::IndexedDBKeyPath;
+
+namespace blink {
+
+IndexedDBIndexMetadata::IndexedDBIndexMetadata() = default;
+
+IndexedDBIndexMetadata::IndexedDBIndexMetadata(const base::string16& name,
+ int64_t id,
+ const IndexedDBKeyPath& key_path,
+ bool unique,
+ bool multi_entry)
+ : name(name),
+ id(id),
+ key_path(key_path),
+ unique(unique),
+ multi_entry(multi_entry) {}
+
+IndexedDBIndexMetadata::IndexedDBIndexMetadata(
+ const IndexedDBIndexMetadata& other) = default;
+IndexedDBIndexMetadata::IndexedDBIndexMetadata(IndexedDBIndexMetadata&& other) =
+ default;
+
+IndexedDBIndexMetadata::~IndexedDBIndexMetadata() = default;
+
+IndexedDBIndexMetadata& IndexedDBIndexMetadata::operator=(
+ const IndexedDBIndexMetadata& other) = default;
+IndexedDBIndexMetadata& IndexedDBIndexMetadata::operator=(
+ IndexedDBIndexMetadata&& other) = default;
+
+bool IndexedDBIndexMetadata::operator==(
+ const IndexedDBIndexMetadata& other) const {
+ return name == other.name && id == other.id && key_path == other.key_path &&
+ unique == other.unique && multi_entry == other.multi_entry;
+}
+
+IndexedDBObjectStoreMetadata::IndexedDBObjectStoreMetadata(
+ const base::string16& name,
+ int64_t id,
+ const IndexedDBKeyPath& key_path,
+ bool auto_increment,
+ int64_t max_index_id)
+ : name(name),
+ id(id),
+ key_path(key_path),
+ auto_increment(auto_increment),
+ max_index_id(max_index_id) {}
+
+IndexedDBObjectStoreMetadata::IndexedDBObjectStoreMetadata() = default;
+
+IndexedDBObjectStoreMetadata::IndexedDBObjectStoreMetadata(
+ const IndexedDBObjectStoreMetadata& other) = default;
+IndexedDBObjectStoreMetadata::IndexedDBObjectStoreMetadata(
+ IndexedDBObjectStoreMetadata&& other) = default;
+
+IndexedDBObjectStoreMetadata::~IndexedDBObjectStoreMetadata() = default;
+
+IndexedDBObjectStoreMetadata& IndexedDBObjectStoreMetadata::operator=(
+ const IndexedDBObjectStoreMetadata& other) = default;
+IndexedDBObjectStoreMetadata& IndexedDBObjectStoreMetadata::operator=(
+ IndexedDBObjectStoreMetadata&& other) = default;
+
+bool IndexedDBObjectStoreMetadata::operator==(
+ const IndexedDBObjectStoreMetadata& other) const {
+ return name == other.name && id == other.id && key_path == other.key_path &&
+ auto_increment == other.auto_increment &&
+ max_index_id == other.max_index_id && indexes == other.indexes;
+}
+
+IndexedDBDatabaseMetadata::IndexedDBDatabaseMetadata() : version(NO_VERSION) {}
+
+IndexedDBDatabaseMetadata::IndexedDBDatabaseMetadata(
+ const base::string16& name,
+ int64_t id,
+ int64_t version,
+ int64_t max_object_store_id)
+ : name(name),
+ id(id),
+ version(version),
+ max_object_store_id(max_object_store_id) {}
+
+IndexedDBDatabaseMetadata::IndexedDBDatabaseMetadata(
+ const IndexedDBDatabaseMetadata& other) = default;
+IndexedDBDatabaseMetadata::IndexedDBDatabaseMetadata(
+ IndexedDBDatabaseMetadata&& other) = default;
+
+IndexedDBDatabaseMetadata::~IndexedDBDatabaseMetadata() = default;
+
+IndexedDBDatabaseMetadata& IndexedDBDatabaseMetadata::operator=(
+ const IndexedDBDatabaseMetadata& other) = default;
+IndexedDBDatabaseMetadata& IndexedDBDatabaseMetadata::operator=(
+ IndexedDBDatabaseMetadata&& other) = default;
+
+bool IndexedDBDatabaseMetadata::operator==(
+ const IndexedDBDatabaseMetadata& other) const {
+ return name == other.name && id == other.id && version == other.version &&
+ max_object_store_id == other.max_object_store_id &&
+ object_stores == other.object_stores;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/common/indexeddb/indexeddb_struct_traits.cc b/chromium/third_party/blink/common/indexeddb/indexeddb_struct_traits.cc
new file mode 100644
index 00000000000..123e9bbb698
--- /dev/null
+++ b/chromium/third_party/blink/common/indexeddb/indexeddb_struct_traits.cc
@@ -0,0 +1,456 @@
+// 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/common/indexeddb/indexeddb_struct_traits.h"
+
+#include "base/stl_util.h"
+#include "mojo/public/cpp/base/string16_mojom_traits.h"
+#include "third_party/blink/public/common/indexeddb/indexeddb_key.h"
+#include "third_party/blink/public/common/indexeddb/indexeddb_key_range.h"
+#include "third_party/blink/public/common/indexeddb/indexeddb_metadata.h"
+
+namespace mojo {
+
+using blink::mojom::IDBCursorDirection;
+using blink::mojom::IDBDataLoss;
+using blink::mojom::IDBOperationType;
+
+// static
+IDBCursorDirection
+EnumTraits<IDBCursorDirection, blink::WebIDBCursorDirection>::ToMojom(
+ blink::WebIDBCursorDirection input) {
+ switch (input) {
+ case blink::kWebIDBCursorDirectionNext:
+ return IDBCursorDirection::Next;
+ case blink::kWebIDBCursorDirectionNextNoDuplicate:
+ return IDBCursorDirection::NextNoDuplicate;
+ case blink::kWebIDBCursorDirectionPrev:
+ return IDBCursorDirection::Prev;
+ case blink::kWebIDBCursorDirectionPrevNoDuplicate:
+ return IDBCursorDirection::PrevNoDuplicate;
+ }
+ NOTREACHED();
+ return IDBCursorDirection::Next;
+}
+
+// static
+bool EnumTraits<IDBCursorDirection, blink::WebIDBCursorDirection>::FromMojom(
+ IDBCursorDirection input,
+ blink::WebIDBCursorDirection* output) {
+ switch (input) {
+ case IDBCursorDirection::Next:
+ *output = blink::kWebIDBCursorDirectionNext;
+ return true;
+ case IDBCursorDirection::NextNoDuplicate:
+ *output = blink::kWebIDBCursorDirectionNextNoDuplicate;
+ return true;
+ case IDBCursorDirection::Prev:
+ *output = blink::kWebIDBCursorDirectionPrev;
+ return true;
+ case IDBCursorDirection::PrevNoDuplicate:
+ *output = blink::kWebIDBCursorDirectionPrevNoDuplicate;
+ return true;
+ }
+ return false;
+}
+
+// static
+IDBDataLoss EnumTraits<IDBDataLoss, blink::WebIDBDataLoss>::ToMojom(
+ blink::WebIDBDataLoss input) {
+ switch (input) {
+ case blink::kWebIDBDataLossNone:
+ return IDBDataLoss::None;
+ case blink::kWebIDBDataLossTotal:
+ return IDBDataLoss::Total;
+ }
+ NOTREACHED();
+ return IDBDataLoss::None;
+}
+
+// static
+bool EnumTraits<IDBDataLoss, blink::WebIDBDataLoss>::FromMojom(
+ IDBDataLoss input,
+ blink::WebIDBDataLoss* output) {
+ switch (input) {
+ case IDBDataLoss::None:
+ *output = blink::kWebIDBDataLossNone;
+ return true;
+ case IDBDataLoss::Total:
+ *output = blink::kWebIDBDataLossTotal;
+ return true;
+ }
+ return false;
+}
+
+// static
+bool StructTraits<blink::mojom::IDBDatabaseMetadataDataView,
+ blink::IndexedDBDatabaseMetadata>::
+ Read(blink::mojom::IDBDatabaseMetadataDataView data,
+ blink::IndexedDBDatabaseMetadata* out) {
+ out->id = data.id();
+ if (!data.ReadName(&out->name))
+ return false;
+ out->version = data.version();
+ out->max_object_store_id = data.max_object_store_id();
+ ArrayDataView<blink::mojom::IDBObjectStoreMetadataDataView> object_stores;
+ data.GetObjectStoresDataView(&object_stores);
+ for (size_t i = 0; i < object_stores.size(); ++i) {
+ blink::mojom::IDBObjectStoreMetadataDataView object_store;
+ object_stores.GetDataView(i, &object_store);
+ DCHECK(!base::ContainsKey(out->object_stores, object_store.id()));
+ if (!StructTraits<blink::mojom::IDBObjectStoreMetadataDataView,
+ blink::IndexedDBObjectStoreMetadata>::
+ Read(object_store, &out->object_stores[object_store.id()]))
+ return false;
+ }
+ return true;
+}
+
+// static
+bool StructTraits<
+ blink::mojom::IDBIndexKeysDataView,
+ blink::IndexedDBIndexKeys>::Read(blink::mojom::IDBIndexKeysDataView data,
+ blink::IndexedDBIndexKeys* out) {
+ out->first = data.index_id();
+ return data.ReadIndexKeys(&out->second);
+}
+
+// static
+bool StructTraits<blink::mojom::IDBIndexMetadataDataView,
+ blink::IndexedDBIndexMetadata>::
+ Read(blink::mojom::IDBIndexMetadataDataView data,
+ blink::IndexedDBIndexMetadata* out) {
+ out->id = data.id();
+ if (!data.ReadName(&out->name))
+ return false;
+ if (!data.ReadKeyPath(&out->key_path))
+ return false;
+ out->unique = data.unique();
+ out->multi_entry = data.multi_entry();
+ return true;
+}
+
+// static
+blink::mojom::IDBKeyDataPtr
+StructTraits<blink::mojom::IDBKeyDataView, blink::IndexedDBKey>::data(
+ const blink::IndexedDBKey& key) {
+ auto data = blink::mojom::IDBKeyData::New();
+ switch (key.type()) {
+ case blink::kWebIDBKeyTypeInvalid:
+ data->set_other(blink::mojom::IDBDatalessKeyType::Invalid);
+ return data;
+ case blink::kWebIDBKeyTypeArray:
+ data->set_key_array(key.array());
+ return data;
+ case blink::kWebIDBKeyTypeBinary:
+ data->set_binary(std::vector<uint8_t>(
+ key.binary().data(), key.binary().data() + key.binary().size()));
+ return data;
+ case blink::kWebIDBKeyTypeString:
+ data->set_string(key.string());
+ return data;
+ case blink::kWebIDBKeyTypeDate:
+ data->set_date(key.date());
+ return data;
+ case blink::kWebIDBKeyTypeNumber:
+ data->set_number(key.number());
+ return data;
+ case blink::kWebIDBKeyTypeNull:
+ data->set_other(blink::mojom::IDBDatalessKeyType::Null);
+ return data;
+ case blink::kWebIDBKeyTypeMin:
+ break;
+ }
+ NOTREACHED();
+ return data;
+}
+
+// static
+bool StructTraits<blink::mojom::IDBKeyDataView, blink::IndexedDBKey>::Read(
+ blink::mojom::IDBKeyDataView data,
+ blink::IndexedDBKey* out) {
+ blink::mojom::IDBKeyDataDataView data_view;
+ data.GetDataDataView(&data_view);
+
+ switch (data_view.tag()) {
+ case blink::mojom::IDBKeyDataDataView::Tag::KEY_ARRAY: {
+ std::vector<blink::IndexedDBKey> array;
+ if (!data_view.ReadKeyArray(&array))
+ return false;
+ *out = blink::IndexedDBKey(array);
+ return true;
+ }
+ case blink::mojom::IDBKeyDataDataView::Tag::BINARY: {
+ std::vector<uint8_t> binary;
+ if (!data_view.ReadBinary(&binary))
+ return false;
+ *out = blink::IndexedDBKey(
+ std::string(binary.data(), binary.data() + binary.size()));
+ return true;
+ }
+ case blink::mojom::IDBKeyDataDataView::Tag::STRING: {
+ base::string16 string;
+ if (!data_view.ReadString(&string))
+ return false;
+ *out = blink::IndexedDBKey(string);
+ return true;
+ }
+ case blink::mojom::IDBKeyDataDataView::Tag::DATE:
+ *out = blink::IndexedDBKey(data_view.date(), blink::kWebIDBKeyTypeDate);
+ return true;
+ case blink::mojom::IDBKeyDataDataView::Tag::NUMBER:
+ *out =
+ blink::IndexedDBKey(data_view.number(), blink::kWebIDBKeyTypeNumber);
+ return true;
+ case blink::mojom::IDBKeyDataDataView::Tag::OTHER:
+ switch (data_view.other()) {
+ case blink::mojom::IDBDatalessKeyType::Invalid:
+ *out = blink::IndexedDBKey(blink::kWebIDBKeyTypeInvalid);
+ return true;
+ case blink::mojom::IDBDatalessKeyType::Null:
+ *out = blink::IndexedDBKey(blink::kWebIDBKeyTypeNull);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// static
+blink::mojom::IDBKeyPathDataPtr
+StructTraits<blink::mojom::IDBKeyPathDataView, blink::IndexedDBKeyPath>::data(
+ const blink::IndexedDBKeyPath& key_path) {
+ if (key_path.IsNull())
+ return nullptr;
+
+ auto data = blink::mojom::IDBKeyPathData::New();
+ switch (key_path.type()) {
+ case blink::kWebIDBKeyPathTypeString:
+ data->set_string(key_path.string());
+ return data;
+ case blink::kWebIDBKeyPathTypeArray:
+ data->set_string_array(key_path.array());
+ return data;
+
+ // The following key path types are not used.
+ case blink::kWebIDBKeyPathTypeNull:; // No-op, fall out of switch block to
+ // NOTREACHED().
+ }
+ NOTREACHED();
+ return data;
+}
+
+// static
+bool StructTraits<blink::mojom::IDBKeyPathDataView, blink::IndexedDBKeyPath>::
+ Read(blink::mojom::IDBKeyPathDataView data, blink::IndexedDBKeyPath* out) {
+ blink::mojom::IDBKeyPathDataDataView data_view;
+ data.GetDataDataView(&data_view);
+
+ if (data_view.is_null()) {
+ *out = blink::IndexedDBKeyPath();
+ return true;
+ }
+
+ switch (data_view.tag()) {
+ case blink::mojom::IDBKeyPathDataDataView::Tag::STRING: {
+ base::string16 string;
+ if (!data_view.ReadString(&string))
+ return false;
+ *out = blink::IndexedDBKeyPath(string);
+ return true;
+ }
+ case blink::mojom::IDBKeyPathDataDataView::Tag::STRING_ARRAY: {
+ std::vector<base::string16> array;
+ if (!data_view.ReadStringArray(&array))
+ return false;
+ *out = blink::IndexedDBKeyPath(array);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// static
+bool StructTraits<blink::mojom::IDBKeyRangeDataView, blink::IndexedDBKeyRange>::
+ Read(blink::mojom::IDBKeyRangeDataView data,
+ blink::IndexedDBKeyRange* out) {
+ blink::IndexedDBKey lower;
+ blink::IndexedDBKey upper;
+ if (!data.ReadLower(&lower) || !data.ReadUpper(&upper))
+ return false;
+
+ *out = blink::IndexedDBKeyRange(lower, upper, data.lower_open(),
+ data.upper_open());
+ return true;
+}
+
+// static
+bool StructTraits<blink::mojom::IDBObjectStoreMetadataDataView,
+ blink::IndexedDBObjectStoreMetadata>::
+ Read(blink::mojom::IDBObjectStoreMetadataDataView data,
+ blink::IndexedDBObjectStoreMetadata* out) {
+ out->id = data.id();
+ if (!data.ReadName(&out->name))
+ return false;
+ if (!data.ReadKeyPath(&out->key_path))
+ return false;
+ out->auto_increment = data.auto_increment();
+ out->max_index_id = data.max_index_id();
+ ArrayDataView<blink::mojom::IDBIndexMetadataDataView> indexes;
+ data.GetIndexesDataView(&indexes);
+ for (size_t i = 0; i < indexes.size(); ++i) {
+ blink::mojom::IDBIndexMetadataDataView index;
+ indexes.GetDataView(i, &index);
+ DCHECK(!base::ContainsKey(out->indexes, index.id()));
+ if (!StructTraits<
+ blink::mojom::IDBIndexMetadataDataView,
+ blink::IndexedDBIndexMetadata>::Read(index,
+ &out->indexes[index.id()]))
+ return false;
+ }
+ return true;
+}
+
+// static
+IDBOperationType
+EnumTraits<IDBOperationType, blink::WebIDBOperationType>::ToMojom(
+ blink::WebIDBOperationType input) {
+ switch (input) {
+ case blink::kWebIDBAdd:
+ return IDBOperationType::Add;
+ case blink::kWebIDBPut:
+ return IDBOperationType::Put;
+ case blink::kWebIDBDelete:
+ return IDBOperationType::Delete;
+ case blink::kWebIDBClear:
+ return IDBOperationType::Clear;
+ case blink::kWebIDBOperationTypeCount:
+ // WebIDBOperationTypeCount is not a valid option.
+ break;
+ }
+ NOTREACHED();
+ return IDBOperationType::Add;
+}
+
+// static
+bool EnumTraits<IDBOperationType, blink::WebIDBOperationType>::FromMojom(
+ IDBOperationType input,
+ blink::WebIDBOperationType* output) {
+ switch (input) {
+ case IDBOperationType::Add:
+ *output = blink::kWebIDBAdd;
+ return true;
+ case IDBOperationType::Put:
+ *output = blink::kWebIDBPut;
+ return true;
+ case IDBOperationType::Delete:
+ *output = blink::kWebIDBDelete;
+ return true;
+ case IDBOperationType::Clear:
+ *output = blink::kWebIDBClear;
+ return true;
+ }
+ return false;
+}
+
+// static
+blink::mojom::IDBPutMode
+EnumTraits<blink::mojom::IDBPutMode, blink::WebIDBPutMode>::ToMojom(
+ blink::WebIDBPutMode input) {
+ switch (input) {
+ case blink::kWebIDBPutModeAddOrUpdate:
+ return blink::mojom::IDBPutMode::AddOrUpdate;
+ case blink::kWebIDBPutModeAddOnly:
+ return blink::mojom::IDBPutMode::AddOnly;
+ case blink::kWebIDBPutModeCursorUpdate:
+ return blink::mojom::IDBPutMode::CursorUpdate;
+ }
+ NOTREACHED();
+ return blink::mojom::IDBPutMode::AddOrUpdate;
+}
+
+// static
+bool EnumTraits<blink::mojom::IDBPutMode, blink::WebIDBPutMode>::FromMojom(
+ blink::mojom::IDBPutMode input,
+ blink::WebIDBPutMode* output) {
+ switch (input) {
+ case blink::mojom::IDBPutMode::AddOrUpdate:
+ *output = blink::kWebIDBPutModeAddOrUpdate;
+ return true;
+ case blink::mojom::IDBPutMode::AddOnly:
+ *output = blink::kWebIDBPutModeAddOnly;
+ return true;
+ case blink::mojom::IDBPutMode::CursorUpdate:
+ *output = blink::kWebIDBPutModeCursorUpdate;
+ return true;
+ }
+ return false;
+}
+
+// static
+blink::mojom::IDBTaskType
+EnumTraits<blink::mojom::IDBTaskType, blink::WebIDBTaskType>::ToMojom(
+ blink::WebIDBTaskType input) {
+ switch (input) {
+ case blink::kWebIDBTaskTypeNormal:
+ return blink::mojom::IDBTaskType::Normal;
+ case blink::kWebIDBTaskTypePreemptive:
+ return blink::mojom::IDBTaskType::Preemptive;
+ }
+ NOTREACHED();
+ return blink::mojom::IDBTaskType::Normal;
+}
+
+// static
+bool EnumTraits<blink::mojom::IDBTaskType, blink::WebIDBTaskType>::FromMojom(
+ blink::mojom::IDBTaskType input,
+ blink::WebIDBTaskType* output) {
+ switch (input) {
+ case blink::mojom::IDBTaskType::Normal:
+ *output = blink::kWebIDBTaskTypeNormal;
+ return true;
+ case blink::mojom::IDBTaskType::Preemptive:
+ *output = blink::kWebIDBTaskTypePreemptive;
+ return true;
+ }
+ return false;
+}
+
+// static
+blink::mojom::IDBTransactionMode EnumTraits<
+ blink::mojom::IDBTransactionMode,
+ blink::WebIDBTransactionMode>::ToMojom(blink::WebIDBTransactionMode input) {
+ switch (input) {
+ case blink::kWebIDBTransactionModeReadOnly:
+ return blink::mojom::IDBTransactionMode::ReadOnly;
+ case blink::kWebIDBTransactionModeReadWrite:
+ return blink::mojom::IDBTransactionMode::ReadWrite;
+ case blink::kWebIDBTransactionModeVersionChange:
+ return blink::mojom::IDBTransactionMode::VersionChange;
+ }
+ NOTREACHED();
+ return blink::mojom::IDBTransactionMode::ReadOnly;
+}
+
+// static
+bool EnumTraits<blink::mojom::IDBTransactionMode,
+ blink::WebIDBTransactionMode>::
+ FromMojom(blink::mojom::IDBTransactionMode input,
+ blink::WebIDBTransactionMode* output) {
+ switch (input) {
+ case blink::mojom::IDBTransactionMode::ReadOnly:
+ *output = blink::kWebIDBTransactionModeReadOnly;
+ return true;
+ case blink::mojom::IDBTransactionMode::ReadWrite:
+ *output = blink::kWebIDBTransactionModeReadWrite;
+ return true;
+ case blink::mojom::IDBTransactionMode::VersionChange:
+ *output = blink::kWebIDBTransactionModeVersionChange;
+ return true;
+ }
+ return false;
+}
+
+} // namespace mojo
diff --git a/chromium/third_party/blink/common/manifest/manifest.cc b/chromium/third_party/blink/common/manifest/manifest.cc
index ecb51f038cb..dc5e6259d44 100644
--- a/chromium/third_party/blink/common/manifest/manifest.cc
+++ b/chromium/third_party/blink/common/manifest/manifest.cc
@@ -17,6 +17,10 @@ bool Manifest::ImageResource::operator==(
return src == other.src && type == other.type && sizes == other.sizes;
}
+Manifest::ShareTargetParams::ShareTargetParams() = default;
+
+Manifest::ShareTargetParams::~ShareTargetParams() = default;
+
Manifest::ShareTarget::ShareTarget() = default;
Manifest::ShareTarget::~ShareTarget() = default;
diff --git a/chromium/third_party/blink/common/manifest/manifest_mojom_traits.cc b/chromium/third_party/blink/common/manifest/manifest_mojom_traits.cc
index 8dceaf0c4fd..d5b27431404 100644
--- a/chromium/third_party/blink/common/manifest/manifest_mojom_traits.cc
+++ b/chromium/third_party/blink/common/manifest/manifest_mojom_traits.cc
@@ -137,11 +137,33 @@ bool StructTraits<blink::mojom::ManifestRelatedApplicationDataView,
return !(out->url.is_empty() && out->id.is_null());
}
+bool StructTraits<blink::mojom::ManifestShareTargetParamsDataView,
+ ::blink::Manifest::ShareTargetParams>::
+ Read(blink::mojom::ManifestShareTargetParamsDataView data,
+ ::blink::Manifest::ShareTargetParams* out) {
+ TruncatedString16 string;
+ if (!data.ReadText(&string))
+ return false;
+ out->text = base::NullableString16(std::move(string.string));
+
+ if (!data.ReadTitle(&string))
+ return false;
+ out->title = base::NullableString16(std::move(string.string));
+
+ if (!data.ReadUrl(&string))
+ return false;
+ out->url = base::NullableString16(std::move(string.string));
+
+ return true;
+}
+
bool StructTraits<blink::mojom::ManifestShareTargetDataView,
::blink::Manifest::ShareTarget>::
Read(blink::mojom::ManifestShareTargetDataView data,
::blink::Manifest::ShareTarget* out) {
- return data.ReadUrlTemplate(&out->url_template);
+ if (!data.ReadAction(&out->action))
+ return false;
+ return data.ReadParams(&out->params);
}
} // namespace mojo
diff --git a/chromium/third_party/blink/common/manifest/manifest_share_target_util.cc b/chromium/third_party/blink/common/manifest/manifest_share_target_util.cc
deleted file mode 100644
index 7d71b6116f6..00000000000
--- a/chromium/third_party/blink/common/manifest/manifest_share_target_util.cc
+++ /dev/null
@@ -1,128 +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/common/manifest/manifest_share_target_util.h"
-
-#include <map>
-
-#include "base/strings/strcat.h"
-#include "base/strings/string_util.h"
-#include "net/base/escape.h"
-#include "url/gurl.h"
-
-namespace blink {
-namespace {
-
-// Determines whether a character is allowed in a URL template placeholder.
-bool IsIdentifier(char c) {
- return base::IsAsciiAlpha(c) || base::IsAsciiDigit(c) || c == '-' || c == '_';
-}
-
-// Returns to |out| the result of running the "replace placeholders"
-// algorithm on |url_template|. The algorithm is specified at
-// https://wicg.github.io/web-share-target/#dfn-replace-placeholders
-// Does not copy any string data. The resulting vector can be concatenated
-// together with base::StrCat to produce the final string.
-bool ReplacePlaceholders(base::StringPiece template_string,
- const std::map<base::StringPiece, std::string>& data,
- std::vector<base::StringPiece>* out) {
- DCHECK(out);
-
- bool last_saw_open = false;
- size_t start_index_to_copy = 0;
- for (size_t i = 0; i < template_string.size(); ++i) {
- if (last_saw_open) {
- if (template_string[i] == '}') {
- base::StringPiece placeholder = template_string.substr(
- start_index_to_copy + 1, i - 1 - start_index_to_copy);
- auto it = data.find(placeholder);
- if (it != data.end()) {
- // Replace the placeholder text with the parameter value.
- out->push_back(it->second);
- }
-
- last_saw_open = false;
- start_index_to_copy = i + 1;
- } else if (!IsIdentifier(template_string[i])) {
- // Error: Non-identifier character seen after open.
- return false;
- }
- } else {
- if (template_string[i] == '}') {
- // Error: Saw close, with no corresponding open.
- return false;
- }
- if (template_string[i] == '{') {
- out->push_back(template_string.substr(start_index_to_copy,
- i - start_index_to_copy));
-
- last_saw_open = true;
- start_index_to_copy = i;
- }
- }
- }
- if (last_saw_open) {
- // Error: Saw open that was never closed.
- return false;
- }
- out->push_back(template_string.substr(
- start_index_to_copy, template_string.size() - start_index_to_copy));
- return true;
-}
-
-} // namespace
-
-bool ValidateWebShareUrlTemplate(const GURL& url_template) {
- return ReplaceWebShareUrlPlaceholders(url_template, /*title=*/"", /*text=*/"",
- /*share_url=*/GURL(),
- /*url_template_filled=*/nullptr);
-}
-
-bool ReplaceWebShareUrlPlaceholders(const GURL& url_template,
- base::StringPiece title,
- base::StringPiece text,
- const GURL& share_url,
- GURL* url_template_filled) {
- constexpr char kTitlePlaceholder[] = "title";
- constexpr char kTextPlaceholder[] = "text";
- constexpr char kUrlPlaceholder[] = "url";
- std::map<base::StringPiece, std::string> replacements;
- replacements[kTitlePlaceholder] = net::EscapeQueryParamValue(title, false);
- replacements[kTextPlaceholder] = net::EscapeQueryParamValue(text, false);
- replacements[kUrlPlaceholder] =
- net::EscapeQueryParamValue(share_url.spec(), false);
-
- std::vector<base::StringPiece> new_query_split;
- std::vector<base::StringPiece> new_ref_split;
- if (!ReplacePlaceholders(url_template.query_piece(), replacements,
- &new_query_split) ||
- !ReplacePlaceholders(url_template.ref_piece(), replacements,
- &new_ref_split)) {
- return false;
- }
-
- // Early-return optimization, since ReplaceWebShareUrlPlaceholders() is called
- // at manifest parse time just to get the success boolean, ignoring the
- // result.
- if (!url_template_filled)
- return true;
-
- // Ensure that the replacements are not deleted prior to
- // GURL::ReplaceComponents() being called. GURL::Replacements::SetQueryStr()
- // does not make a copy.
- std::string new_query = base::StrCat(new_query_split);
- std::string new_ref = base::StrCat(new_ref_split);
-
- // Check whether |url_template| has a query in order to preserve the '?' in
- // a URL with an empty query. e.g. http://www.google.com/?
- GURL::Replacements url_replacements;
- if (url_template.has_query())
- url_replacements.SetQueryStr(new_query);
- if (url_template.has_ref())
- url_replacements.SetRefStr(new_ref);
- *url_template_filled = url_template.ReplaceComponents(url_replacements);
- return true;
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/common/manifest/manifest_share_target_util_unittest.cc b/chromium/third_party/blink/common/manifest/manifest_share_target_util_unittest.cc
deleted file mode 100644
index 886ff73b1a7..00000000000
--- a/chromium/third_party/blink/common/manifest/manifest_share_target_util_unittest.cc
+++ /dev/null
@@ -1,266 +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 <map>
-#include <utility>
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/common/manifest/manifest_share_target_util.h"
-#include "url/gurl.h"
-
-namespace blink {
-namespace {
-
-constexpr char kTitle[] = "My title";
-constexpr char kText[] = "My text";
-constexpr char kUrlSpec[] = "https://www.google.com/";
-
-} // namespace
-
-TEST(ManifestShareTargetUtilTest, ReplaceUrlPlaceholdersInvalidTemplate) {
- // Badly nested placeholders.
- GURL url_template = GURL("http://example.com/?q={");
- EXPECT_FALSE(ValidateWebShareUrlTemplate(url_template));
- EXPECT_FALSE(
- ReplaceWebShareUrlPlaceholders(url_template, "", "", GURL(), nullptr));
-
- url_template = GURL("http://example.com/?q={title");
- EXPECT_FALSE(ValidateWebShareUrlTemplate(url_template));
- EXPECT_FALSE(
- ReplaceWebShareUrlPlaceholders(url_template, "", "", GURL(), nullptr));
-
- url_template = GURL("http://example.com/?q={title{text}}");
- EXPECT_FALSE(ValidateWebShareUrlTemplate(url_template));
- EXPECT_FALSE(
- ReplaceWebShareUrlPlaceholders(url_template, "", "", GURL(), nullptr));
-
- url_template = GURL("http://example.com/?q={title{}");
- EXPECT_FALSE(ValidateWebShareUrlTemplate(url_template));
- EXPECT_FALSE(
- ReplaceWebShareUrlPlaceholders(url_template, "", "", GURL(), nullptr));
-
- url_template = GURL("http://example.com/?q={{title}}");
- EXPECT_FALSE(ValidateWebShareUrlTemplate(url_template));
- EXPECT_FALSE(
- ReplaceWebShareUrlPlaceholders(url_template, "", "", GURL(), nullptr));
-
- // Placeholder with non-identifier character.
- url_template = GURL("http://example.com/?q={title?}");
- EXPECT_FALSE(ValidateWebShareUrlTemplate(url_template));
- EXPECT_FALSE(
- ReplaceWebShareUrlPlaceholders(url_template, "", "", GURL(), nullptr));
-
- // Placeholder with digit character.
- url_template = GURL("http://example.com/?q={title1}");
- EXPECT_TRUE(ValidateWebShareUrlTemplate(url_template));
- EXPECT_TRUE(
- ReplaceWebShareUrlPlaceholders(url_template, "", "", GURL(), nullptr));
-
- // Empty placeholder.
- url_template = GURL("http://example.com/?q={}");
- EXPECT_TRUE(ValidateWebShareUrlTemplate(url_template));
- EXPECT_TRUE(
- ReplaceWebShareUrlPlaceholders(url_template, "", "", GURL(), nullptr));
-
- // Invalid placeholder in URL fragment.
- url_template = GURL("http://example.com/#{title?}");
- EXPECT_FALSE(ValidateWebShareUrlTemplate(url_template));
- EXPECT_FALSE(
- ReplaceWebShareUrlPlaceholders(url_template, "", "", GURL(), nullptr));
-
- // { in path.
- url_template = GURL("http://example.com/subpath{/");
- EXPECT_TRUE(ValidateWebShareUrlTemplate(url_template));
- EXPECT_TRUE(
- ReplaceWebShareUrlPlaceholders(url_template, "", "", GURL(), nullptr));
-
- // Invalid placeholder. Non-empty title, text, share URL and non-empty output
- // parameter.
- GURL url_template_filled;
- url_template = GURL("http://example.com/?q={");
- EXPECT_FALSE(ReplaceWebShareUrlPlaceholders(url_template, "text", "title",
- GURL("http://www.google.com"),
- &url_template_filled));
-}
-
-TEST(ManifestShareTargetUtilTest, ReplaceWebShareUrlPlaceholders) {
- const GURL kUrl(kUrlSpec);
-
- // No placeholders.
- GURL url_template = GURL("http://example.com/?q=a#a");
- GURL url_template_filled;
- bool succeeded = ReplaceWebShareUrlPlaceholders(url_template, kTitle, kText,
- kUrl, &url_template_filled);
- EXPECT_TRUE(succeeded);
- EXPECT_EQ(url_template, url_template_filled);
-
- // One title placeholder.
- url_template = GURL("http://example.com/#{title}");
- succeeded = ReplaceWebShareUrlPlaceholders(url_template, kTitle, kText, kUrl,
- &url_template_filled);
- EXPECT_TRUE(succeeded);
- EXPECT_EQ("http://example.com/#My%20title", url_template_filled.spec());
-
- // One text placeholder.
- url_template = GURL("http://example.com/#{text}");
- succeeded = ReplaceWebShareUrlPlaceholders(url_template, kTitle, kText, kUrl,
- &url_template_filled);
- EXPECT_TRUE(succeeded);
- EXPECT_EQ("http://example.com/#My%20text", url_template_filled.spec());
-
- // One url placeholder.
- url_template = GURL("http://example.com/#{url}");
- succeeded = ReplaceWebShareUrlPlaceholders(url_template, kTitle, kText, kUrl,
- &url_template_filled);
- EXPECT_TRUE(succeeded);
- EXPECT_EQ("http://example.com/#https%3A%2F%2Fwww.google.com%2F",
- url_template_filled.spec());
-
- // One of each placeholder, in title, text, url order.
- url_template = GURL("http://example.com/#{title}{text}{url}");
- succeeded = ReplaceWebShareUrlPlaceholders(url_template, kTitle, kText, kUrl,
- &url_template_filled);
- EXPECT_TRUE(succeeded);
- EXPECT_EQ(
- "http://example.com/#My%20titleMy%20texthttps%3A%2F%2Fwww.google.com%2F",
- url_template_filled.spec());
-
- // One of each placeholder, in url, text, title order.
- url_template = GURL("http://example.com/#{url}{text}{title}");
- succeeded = ReplaceWebShareUrlPlaceholders(url_template, kTitle, kText, kUrl,
- &url_template_filled);
- EXPECT_TRUE(succeeded);
- EXPECT_EQ(
- "http://example.com/#https%3A%2F%2Fwww.google.com%2FMy%20textMy%20title",
- url_template_filled.spec());
-
- // Two of each placeholder, some next to each other, others not.
- url_template =
- GURL("http://example.com/#{title}{url}{text}{text}{title}{url}");
- succeeded = ReplaceWebShareUrlPlaceholders(url_template, kTitle, kText, kUrl,
- &url_template_filled);
- EXPECT_TRUE(succeeded);
- EXPECT_EQ(
- "http://example.com/"
- "#My%20titlehttps%3A%2F%2Fwww.google.com%2FMy%20textMy%20textMy%"
- "20titlehttps%3A%2F%2Fwww.google.com%2F",
- url_template_filled.spec());
-
- // Placeholders are in a query string, as values. The expected use case.
- // Two of each placeholder, some next to each other, others not.
- url_template = GURL(
- "http://example.com?title={title}&url={url}&text={text}&text={text}&"
- "title={title}&url={url}");
- succeeded = ReplaceWebShareUrlPlaceholders(url_template, kTitle, kText, kUrl,
- &url_template_filled);
- EXPECT_TRUE(succeeded);
- EXPECT_EQ(
- "http://"
- "example.com/?title=My%20title&url=https%3A%2F%2Fwww.google.com%2F&"
- "text=My%20text&"
- "text=My%20text&title=My%20title&url=https%3A%2F%2Fwww.google.com%2F",
- url_template_filled.spec());
-
- // Empty placeholder.
- url_template = GURL("http://example.com/#{}");
- succeeded = ReplaceWebShareUrlPlaceholders(url_template, kTitle, kText, kUrl,
- &url_template_filled);
- EXPECT_TRUE(succeeded);
- EXPECT_EQ("http://example.com/#", url_template_filled.spec());
-
- // Unexpected placeholders.
- url_template = GURL("http://example.com/#{nonexistentplaceholder}");
- succeeded = ReplaceWebShareUrlPlaceholders(url_template, kTitle, kText, kUrl,
- &url_template_filled);
- EXPECT_TRUE(succeeded);
- EXPECT_EQ("http://example.com/#", url_template_filled.spec());
-
- // Placeholders should only be replaced in query and fragment.
- url_template = GURL("http://example.com/subpath{title}/?q={title}#{title}");
- succeeded = ReplaceWebShareUrlPlaceholders(url_template, kTitle, kText, kUrl,
- &url_template_filled);
- EXPECT_TRUE(succeeded);
- EXPECT_EQ("http://example.com/subpath%7Btitle%7D/?q=My%20title#My%20title",
- url_template_filled.spec());
-
- // Braces in the path, which would be invalid, but should parse fine as they
- // are escaped.
- url_template = GURL("http://example.com/subpath{/?q={title}");
- succeeded = ReplaceWebShareUrlPlaceholders(url_template, kTitle, kText, kUrl,
- &url_template_filled);
- EXPECT_TRUE(succeeded);
- EXPECT_EQ("http://example.com/subpath%7B/?q=My%20title",
- url_template_filled.spec());
-
- // |url_template| with % escapes.
- url_template = GURL("http://example.com#%20{title}%20");
- succeeded = ReplaceWebShareUrlPlaceholders(url_template, kTitle, kText, kUrl,
- &url_template_filled);
- EXPECT_TRUE(succeeded);
- EXPECT_EQ("http://example.com/#%20My%20title%20", url_template_filled.spec());
-}
-
-// Test URL escaping done by ReplaceWebShareUrlPlaceholders().
-TEST(ManifestShareTargetUtilTest, ReplaceWebShareUrlPlaceholders_Escaping) {
- const GURL kUrl(kUrlSpec);
- const GURL kUrlTemplate("http://example.com/#{title}");
-
- // Share data that contains percent escapes.
- GURL url_template_filled;
- bool succeeded = ReplaceWebShareUrlPlaceholders(
- kUrlTemplate, "My%20title", kText, kUrl, &url_template_filled);
- EXPECT_TRUE(succeeded);
- EXPECT_EQ("http://example.com/#My%2520title", url_template_filled.spec());
-
- // Share data that contains placeholders. These should not be replaced.
- succeeded = ReplaceWebShareUrlPlaceholders(kUrlTemplate, "{title}", kText,
- kUrl, &url_template_filled);
- EXPECT_TRUE(succeeded);
- EXPECT_EQ("http://example.com/#%7Btitle%7D", url_template_filled.spec());
-
- // All characters that shouldn't be escaped.
- succeeded = ReplaceWebShareUrlPlaceholders(kUrlTemplate,
- "-_.!~*'()0123456789"
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "abcdefghijklmnopqrstuvwxyz",
- kText, kUrl, &url_template_filled);
- EXPECT_TRUE(succeeded);
- EXPECT_EQ(
- "http://example.com/#-_.!~*'()0123456789"
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "abcdefghijklmnopqrstuvwxyz",
- url_template_filled.spec());
-
- // All characters that should be escaped.
- succeeded =
- ReplaceWebShareUrlPlaceholders(kUrlTemplate, " \"#$%&+,/:;<=>?@[\\]^`{|}",
- kText, kUrl, &url_template_filled);
- EXPECT_TRUE(succeeded);
- EXPECT_EQ(
- "http://example.com/"
- "#%20%22%23%24%25%26%2B%2C%2F%3A%3B%3C%3D%3E%3F%40%5B%5C%5D%5E%60%7B%7C%"
- "7D",
- url_template_filled.spec());
-
- // Unicode chars.
- // U+263B
- succeeded = ReplaceWebShareUrlPlaceholders(kUrlTemplate, "\xe2\x98\xbb",
- kText, kUrl, &url_template_filled);
- EXPECT_TRUE(succeeded);
- EXPECT_EQ("http://example.com/#%E2%98%BB", url_template_filled.spec());
-
- // U+00E9
- succeeded = ReplaceWebShareUrlPlaceholders(kUrlTemplate, "\xc3\xa9", kText,
- kUrl, &url_template_filled);
- EXPECT_TRUE(succeeded);
- EXPECT_EQ("http://example.com/#%C3%A9", url_template_filled.spec());
-
- // U+1F4A9
- succeeded = ReplaceWebShareUrlPlaceholders(kUrlTemplate, "\xf0\x9f\x92\xa9",
- kText, kUrl, &url_template_filled);
- EXPECT_TRUE(succeeded);
- EXPECT_EQ("http://example.com/#%F0%9F%92%A9", url_template_filled.spec());
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/common/message_port/cloneable_message_struct_traits.cc b/chromium/third_party/blink/common/message_port/cloneable_message_struct_traits.cc
index 4cc6f31acdd..0d62abcdde1 100644
--- a/chromium/third_party/blink/common/message_port/cloneable_message_struct_traits.cc
+++ b/chromium/third_party/blink/common/message_port/cloneable_message_struct_traits.cc
@@ -20,7 +20,9 @@ bool StructTraits<blink::mojom::CloneableMessage::DataView,
Read(blink::mojom::CloneableMessage::DataView data,
blink::CloneableMessage* out) {
mojo_base::BigBufferView message_view;
- if (!data.ReadEncodedMessage(&message_view) || !data.ReadBlobs(&out->blobs)) {
+ base::Optional<base::UnguessableToken> locked_agent_cluster_id;
+ if (!data.ReadEncodedMessage(&message_view) || !data.ReadBlobs(&out->blobs) ||
+ !data.ReadLockedAgentClusterId(&locked_agent_cluster_id)) {
return false;
}
@@ -30,6 +32,7 @@ bool StructTraits<blink::mojom::CloneableMessage::DataView,
out->stack_trace_id = data.stack_trace_id();
out->stack_trace_debugger_id_first = data.stack_trace_debugger_id_first();
out->stack_trace_debugger_id_second = data.stack_trace_debugger_id_second();
+ out->locked_agent_cluster_id = locked_agent_cluster_id;
return true;
}
diff --git a/chromium/third_party/blink/common/message_port/cloneable_message_struct_traits.h b/chromium/third_party/blink/common/message_port/cloneable_message_struct_traits.h
index 483224f0755..27860b83985 100644
--- a/chromium/third_party/blink/common/message_port/cloneable_message_struct_traits.h
+++ b/chromium/third_party/blink/common/message_port/cloneable_message_struct_traits.h
@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_COMMON_MESSAGE_PORT_CLONEABLE_MESSAGE_STRUCT_TRAITS_H_
#include "mojo/public/cpp/base/big_buffer.h"
+#include "mojo/public/cpp/base/unguessable_token_mojom_traits.h"
#include "third_party/blink/public/common/message_port/cloneable_message.h"
#include "third_party/blink/public/mojom/message_port/message_port.mojom.h"
@@ -23,19 +24,25 @@ struct BLINK_COMMON_EXPORT
return input.blobs;
}
- static uint64_t stack_trace_id(blink::CloneableMessage& input) {
+ static uint64_t stack_trace_id(const blink::CloneableMessage& input) {
return input.stack_trace_id;
}
- static int64_t stack_trace_debugger_id_first(blink::CloneableMessage& input) {
+ static int64_t stack_trace_debugger_id_first(
+ const blink::CloneableMessage& input) {
return input.stack_trace_debugger_id_first;
}
static int64_t stack_trace_debugger_id_second(
- blink::CloneableMessage& input) {
+ const blink::CloneableMessage& input) {
return input.stack_trace_debugger_id_second;
}
+ static const base::Optional<base::UnguessableToken>& locked_agent_cluster_id(
+ const blink::CloneableMessage& input) {
+ return input.locked_agent_cluster_id;
+ }
+
static bool Read(blink::mojom::CloneableMessage::DataView data,
blink::CloneableMessage* out);
};
diff --git a/chromium/third_party/blink/common/message_port/string_message_codec_unittest.cc b/chromium/third_party/blink/common/message_port/string_message_codec_unittest.cc
index 42435ca6882..374d8656b5d 100644
--- a/chromium/third_party/blink/common/message_port/string_message_codec_unittest.cc
+++ b/chromium/third_party/blink/common/message_port/string_message_codec_unittest.cc
@@ -36,7 +36,8 @@ base::string16 DecodeWithV8(const std::vector<uint8_t>& encoded) {
v8::Local<v8::String> str = value->ToString(context).ToLocalChecked();
result.resize(str->Length());
- str->Write(reinterpret_cast<uint16_t*>(&result[0]), 0, result.size());
+ str->Write(isolate, reinterpret_cast<uint16_t*>(&result[0]), 0,
+ result.size());
}
isolate->Dispose();
delete params.array_buffer_allocator;
diff --git a/chromium/third_party/blink/common/message_port/transferable_message_struct_traits.cc b/chromium/third_party/blink/common/message_port/transferable_message_struct_traits.cc
index 38674b298c3..fba548a64ab 100644
--- a/chromium/third_party/blink/common/message_port/transferable_message_struct_traits.cc
+++ b/chromium/third_party/blink/common/message_port/transferable_message_struct_traits.cc
@@ -17,7 +17,8 @@ bool StructTraits<blink::mojom::TransferableMessage::DataView,
if (!data.ReadMessage(static_cast<blink::CloneableMessage*>(out)) ||
!data.ReadArrayBufferContentsArray(&out->array_buffer_contents_array) ||
!data.ReadImageBitmapContentsArray(&out->image_bitmap_contents_array) ||
- !data.ReadPorts(&ports)) {
+ !data.ReadPorts(&ports) ||
+ !data.ReadUserActivation(&out->user_activation)) {
return false;
}
diff --git a/chromium/third_party/blink/common/message_port/transferable_message_struct_traits.h b/chromium/third_party/blink/common/message_port/transferable_message_struct_traits.h
index ff17a2d12bf..2bf79e69c32 100644
--- a/chromium/third_party/blink/common/message_port/transferable_message_struct_traits.h
+++ b/chromium/third_party/blink/common/message_port/transferable_message_struct_traits.h
@@ -40,6 +40,11 @@ struct BLINK_COMMON_EXPORT
return input.has_user_gesture;
}
+ static const blink::mojom::UserActivationSnapshotPtr& user_activation(
+ blink::TransferableMessage& input) {
+ return input.user_activation;
+ }
+
static bool Read(blink::mojom::TransferableMessage::DataView data,
blink::TransferableMessage* out);
};
diff --git a/chromium/third_party/blink/common/oom_intervention/oom_intervention_types.h b/chromium/third_party/blink/common/oom_intervention/oom_intervention_types.h
deleted file mode 100644
index 9de433d6d31..00000000000
--- a/chromium/third_party/blink/common/oom_intervention/oom_intervention_types.h
+++ /dev/null
@@ -1,25 +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_COMMON_OOM_INTERVENTION_OOM_INTERVENTION_TYPES_H_
-#define THIRD_PARTY_BLINK_COMMON_OOM_INTERVENTION_OOM_INTERVENTION_TYPES_H_
-
-#include <stdint.h>
-
-namespace blink {
-
-// The struct with renderer metrics that are used to detect OOMs. This is stored
-// in shared memory so that browser can read it even after the renderer dies.
-struct OomInterventionMetrics {
- uint64_t current_private_footprint_kb;
- uint64_t current_swap_kb;
- uint64_t current_vm_size_kb;
-
- // Stores the total of V8, BlinkGC and PartitionAlloc memory usage.
- uint64_t current_blink_usage_kb;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_COMMON_OOM_INTERVENTION_OOM_INTERVENTION_TYPES_H_
diff --git a/chromium/third_party/blink/common/service_worker/service_worker_status_code.cc b/chromium/third_party/blink/common/service_worker/service_worker_status_code.cc
index 71ea91a7772..e5b95e8fd54 100644
--- a/chromium/third_party/blink/common/service_worker/service_worker_status_code.cc
+++ b/chromium/third_party/blink/common/service_worker/service_worker_status_code.cc
@@ -49,6 +49,8 @@ const char* ServiceWorkerStatusToString(ServiceWorkerStatusCode status) {
return "Redundant worker";
case ServiceWorkerStatusCode::kErrorDisallowed:
return "Worker disallowed";
+ case ServiceWorkerStatusCode::kErrorInvalidArguments:
+ return "Invalid arguments";
}
NOTREACHED();
return "";
diff --git a/chromium/third_party/blink/common/service_worker/service_worker_utils.cc b/chromium/third_party/blink/common/service_worker/service_worker_utils.cc
index 19089af28dd..46e457a3187 100644
--- a/chromium/third_party/blink/common/service_worker/service_worker_utils.cc
+++ b/chromium/third_party/blink/common/service_worker/service_worker_utils.cc
@@ -17,4 +17,9 @@ bool ServiceWorkerUtils::IsServicificationEnabled() {
blink::features::kServiceWorkerServicification);
}
+bool ServiceWorkerUtils::IsImportedScriptUpdateCheckEnabled() {
+ return base::FeatureList::IsEnabled(
+ blink::features::kServiceWorkerImportedScriptUpdateCheck);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/public/BUILD.gn b/chromium/third_party/blink/public/BUILD.gn
index c0a915fd2d7..18ab3698956 100644
--- a/chromium/third_party/blink/public/BUILD.gn
+++ b/chromium/third_party/blink/public/BUILD.gn
@@ -118,6 +118,7 @@ source_set("test_headers") {
source_set("blink_headers") {
sources = [
"platform/blame_context.h",
+ "platform/code_cache_loader.h",
"platform/cors_status.h",
"platform/file_path_conversion.h",
"platform/interface_provider.h",
@@ -126,9 +127,7 @@ source_set("blink_headers") {
"platform/linux/web_sandbox_support.h",
"platform/mac/web_sandbox_support.h",
"platform/mac/web_scrollbar_theme.h",
- "platform/modules/background_fetch/web_background_fetch_settled_fetch.h",
- "platform/modules/device_orientation/web_device_motion_listener.h",
- "platform/modules/device_orientation/web_device_orientation_listener.h",
+ "platform/modules/background_fetch/web_background_fetch_registration.h",
"platform/modules/indexeddb/web_idb_callbacks.h",
"platform/modules/indexeddb/web_idb_cursor.h",
"platform/modules/indexeddb/web_idb_database.h",
@@ -141,7 +140,6 @@ source_set("blink_headers") {
"platform/modules/indexeddb/web_idb_key_range.h",
"platform/modules/indexeddb/web_idb_metadata.h",
"platform/modules/indexeddb/web_idb_observation.h",
- "platform/modules/indexeddb/web_idb_types.h",
"platform/modules/indexeddb/web_idb_value.h",
"platform/modules/installedapp/web_related_application.h",
"platform/modules/installedapp/web_related_apps_fetcher.h",
@@ -152,7 +150,6 @@ source_set("blink_headers") {
"platform/modules/notifications/web_notification_action.h",
"platform/modules/notifications/web_notification_constants.h",
"platform/modules/notifications/web_notification_data.h",
- "platform/modules/notifications/web_notification_resources.h",
"platform/modules/payments/web_payment_currency_amount.h",
"platform/modules/payments/web_payment_details_modifier.h",
"platform/modules/payments/web_payment_handler_response.h",
@@ -192,7 +189,7 @@ source_set("blink_headers") {
"platform/scheduler/child/webthread_base.h",
"platform/scheduler/renderer_process_type.h",
"platform/scheduler/single_thread_idle_task_runner.h",
- "platform/scheduler/web_main_thread_scheduler.h",
+ "platform/scheduler/web_rail_mode_observer.h",
"platform/scheduler/web_render_widget_scheduling_state.h",
"platform/scheduler/web_resource_loading_task_runner_handle.h",
"platform/scheduler/web_thread_scheduler.h",
@@ -319,7 +316,6 @@ source_set("blink_headers") {
"platform/web_native_scroll_behavior.h",
"platform/web_network_state_notifier.h",
"platform/web_platform_event_listener.h",
- "platform/web_platform_event_type.h",
"platform/web_point.h",
"platform/web_pointer_event.h",
"platform/web_pointer_properties.h",
@@ -332,9 +328,7 @@ source_set("blink_headers") {
"platform/web_resource_timing_info.h",
"platform/web_rtc_answer_options.h",
"platform/web_rtc_api_name.h",
- "platform/web_rtc_certificate.h",
"platform/web_rtc_certificate_generator.h",
- "platform/web_rtc_configuration.h",
"platform/web_rtc_data_channel_handler.h",
"platform/web_rtc_data_channel_handler_client.h",
"platform/web_rtc_data_channel_init.h",
@@ -421,6 +415,7 @@ source_set("blink_headers") {
"web/web_associated_url_loader_options.h",
"web/web_autofill_client.h",
"web/web_autofill_state.h",
+ "web/web_ax_context.h",
"web/web_ax_enums.h",
"web/web_ax_object.h",
"web/web_blob.h",
@@ -569,7 +564,7 @@ source_set("blink_headers") {
public_deps = [
"//net",
"//services/service_manager/public/cpp",
- "//services/ui/public/interfaces/ime",
+ "//services/ws/public/mojom/ime",
"//skia",
"//third_party/blink/public/common",
"//third_party/webrtc/api:libjingle_peerconnection_api",
@@ -682,7 +677,7 @@ repack("scaled_resources_200_percent") {
]
}
-# TODO: Move these into WebKit/public/mojom.
+# TODO: Move these into blink/public/mojom.
mojom("mojo_bindings") {
visibility = [
"//content/*",
@@ -700,11 +695,9 @@ mojom("mojo_bindings") {
"platform/modules/background_fetch/background_fetch.mojom",
"platform/modules/background_sync/background_sync.mojom",
"platform/modules/bluetooth/web_bluetooth.mojom",
- "platform/modules/budget_service/budget_service.mojom",
"platform/modules/cache_storage/cache_storage.mojom",
"platform/modules/credentialmanager/credential_manager.mojom",
"platform/modules/fetch/fetch_api_request.mojom",
- "platform/modules/fetch/fetch_api_response.mojom",
"platform/modules/geolocation/geolocation_service.mojom",
"platform/modules/hyphenation/hyphenation.mojom",
"platform/modules/insecure_input/insecure_input_service.mojom",
@@ -712,11 +705,9 @@ mojom("mojo_bindings") {
"platform/modules/locks/lock_manager.mojom",
"platform/modules/notifications/notification.mojom",
"platform/modules/notifications/notification_service.mojom",
- "platform/modules/payments/payment_app.mojom",
"platform/modules/permissions/permission.mojom",
"platform/modules/permissions/permission_status.mojom",
- "platform/modules/presentation/presentation.mojom",
- "platform/modules/webauth/virtual_authenticator.mojom",
+ "platform/modules/webauthn/virtual_authenticator.mojom",
"platform/modules/webdatabase/web_database.mojom",
"platform/oom_intervention.mojom",
"platform/referrer.mojom",
@@ -735,7 +726,6 @@ mojom("mojo_bindings") {
":android_mojo_bindings",
":web_client_hints_types_mojo_bindings",
":web_feature_mojo_bindings",
- "//components/payments/mojom",
"//components/services/font/public/interfaces",
"//device/bluetooth/public/mojom",
"//mojo/public/mojom/base",
@@ -775,17 +765,16 @@ mojom("android_mojo_bindings") {
"platform/input_host.mojom",
"platform/input_messages.mojom",
"platform/modules/document_metadata/copyless_paste.mojom",
+ "platform/modules/font_unique_name_lookup/font_unique_name_lookup.mojom",
"platform/modules/installation/installation.mojom",
"platform/modules/installedapp/installed_app_provider.mojom",
"platform/modules/installedapp/related_application.mojom",
"platform/modules/mediasession/media_session.mojom",
- "platform/modules/payments/payment_request.mojom",
- "platform/modules/webauth/authenticator.mojom",
+ "platform/modules/webauthn/authenticator.mojom",
"platform/modules/webshare/webshare.mojom",
"web/remote_objects.mojom",
]
public_deps = [
- "//components/payments/mojom",
"//mojo/public/mojom/base",
"//ui/gfx/geometry/mojo",
"//url/mojom:url_mojom_gurl",
@@ -886,13 +875,13 @@ group("generate_mojo_bindings") {
# Blink public API exposes a number of Mojo interfaces; omitting it will
# cause non-deterministic compile failures for code that uses the regular
# variant of the generated files.
- ":core_mojo_bindings__generator",
- ":core_mojo_bindings_blink__generator",
- ":embedded_frame_sink_mojo_bindings_blink__generator",
- ":media_devices_mojo_bindings__generator",
- ":media_devices_mojo_bindings_blink__generator",
- ":mojo_bindings__generator",
- ":mojo_bindings_blink__generator",
+ ":core_mojo_bindings_blink_headers",
+ ":core_mojo_bindings_headers",
+ ":embedded_frame_sink_mojo_bindings_blink_headers",
+ ":media_devices_mojo_bindings_blink_headers",
+ ":media_devices_mojo_bindings_headers",
+ ":mojo_bindings_blink_headers",
+ ":mojo_bindings_headers",
]
}
@@ -925,7 +914,7 @@ source_set("shared_typemap_traits") {
]
deps = [
":blink_headers",
- ":mojo_bindings_shared__generator",
+ ":mojo_bindings_headers",
"//mojo/public/cpp/bindings:struct_traits",
]
}
diff --git a/chromium/third_party/blink/public/OWNERS b/chromium/third_party/blink/public/OWNERS
index 69861f50ee4..afff5d326ae 100644
--- a/chromium/third_party/blink/public/OWNERS
+++ b/chromium/third_party/blink/public/OWNERS
@@ -1,5 +1,6 @@
chrishtr@chromium.org
dcheng@chromium.org
+dgozman@chromium.org
dstockwell@chromium.org
foolip@chromium.org
haraken@chromium.org
diff --git a/chromium/third_party/blink/public/blink_typemaps.gni b/chromium/third_party/blink/public/blink_typemaps.gni
index 91736379713..97e2b6dba0a 100644
--- a/chromium/third_party/blink/public/blink_typemaps.gni
+++ b/chromium/third_party/blink/public/blink_typemaps.gni
@@ -5,6 +5,7 @@
typemaps = [
"//gpu/ipc/common/mailbox_holder_for_blink.typemap",
"//gpu/ipc/common/sync_token.typemap",
+ "//mojo/public/cpp/base/file_error.typemap",
"//services/viz/public/cpp/compositing/begin_frame_args_for_blink.typemap",
"//services/viz/public/cpp/compositing/compositor_frame_for_blink.typemap",
"//services/viz/public/cpp/compositing/frame_sink_id.typemap",
diff --git a/chromium/third_party/blink/public/common/BUILD.gn b/chromium/third_party/blink/public/common/BUILD.gn
index 9f6ac752255..995656b9639 100644
--- a/chromium/third_party/blink/public/common/BUILD.gn
+++ b/chromium/third_party/blink/public/common/BUILD.gn
@@ -6,6 +6,7 @@ import("//build/buildflag_header.gni")
import("//build/config/compiler/compiler.gni")
import("//build/config/features.gni")
import("//testing/test.gni")
+import("//third_party/protobuf/proto_library.gni")
# Public common API headers, mojom and libraries that can be linked and
# referenced both by browser-side and renderer-side components.
@@ -35,6 +36,7 @@ source_set("headers") {
"associated_interfaces/associated_interface_provider.h",
"associated_interfaces/associated_interface_registry.h",
"blob/blob_utils.h",
+ "cache_storage/cache_storage_utils.h",
"client_hints/client_hints.h",
"device_memory/approximated_device_memory.h",
"experiments/memory_ablation_experiment.h",
@@ -45,20 +47,27 @@ source_set("headers") {
"frame/user_activation_state.h",
"frame/user_activation_update_source.h",
"frame/user_activation_update_type.h",
+ "indexeddb/indexeddb_key.h",
+ "indexeddb/indexeddb_key_path.h",
+ "indexeddb/indexeddb_key_range.h",
+ "indexeddb/indexeddb_metadata.h",
+ "indexeddb/indexeddb_struct_traits.h",
+ "indexeddb/web_idb_types.h",
"manifest/manifest.h",
"manifest/manifest_icon_selector.h",
- "manifest/manifest_share_target_util.h",
"manifest/web_display_mode.h",
"message_port/cloneable_message.h",
"message_port/message_port_channel.h",
"message_port/string_message_codec.h",
"message_port/transferable_message.h",
"mime_util/mime_util.h",
+ "oom_intervention/oom_intervention_types.h",
"origin_policy/origin_policy.h",
"origin_trials/origin_trial_policy.h",
"origin_trials/trial_token.h",
"origin_trials/trial_token_validator.h",
"page/launching_process_state.h",
+ "picture_in_picture/picture_in_picture_control_info.h",
"privacy_preferences.h",
"screen_orientation/web_screen_orientation_enum_traits.h",
"screen_orientation/web_screen_orientation_lock_type.h",
@@ -69,7 +78,8 @@ source_set("headers") {
]
public_deps = [
- "//third_party/blink/public/mojom:mojom_core",
+ "//skia",
+ "//third_party/blink/public/mojom:mojom_core_headers",
]
deps = [
@@ -82,4 +92,20 @@ source_set("headers") {
if (!is_ios) {
deps += [ "//media" ]
}
+
+ if (is_android) {
+ sources += [
+ "font_unique_name_lookup/font_table_matcher.h",
+ "font_unique_name_lookup/icu_fold_case_util.h",
+ ]
+ deps += [ ":font_unique_name_table_proto" ]
+ }
+}
+
+if (is_android) {
+ proto_library("font_unique_name_table_proto") {
+ sources = [
+ "font_unique_name_lookup/font_unique_name_table.proto",
+ ]
+ }
}
diff --git a/chromium/third_party/blink/public/common/associated_interfaces/associated_interface_provider.h b/chromium/third_party/blink/public/common/associated_interfaces/associated_interface_provider.h
index 06d7d1b3c50..72eba5d2c5d 100644
--- a/chromium/third_party/blink/public/common/associated_interfaces/associated_interface_provider.h
+++ b/chromium/third_party/blink/public/common/associated_interfaces/associated_interface_provider.h
@@ -7,9 +7,15 @@
#include <string>
+#include "base/callback.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/single_thread_task_runner.h"
#include "mojo/public/cpp/bindings/associated_interface_ptr.h"
#include "mojo/public/cpp/bindings/associated_interface_request.h"
#include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
+#include "third_party/blink/common/common_export.h"
+#include "third_party/blink/public/mojom/associated_interfaces/associated_interfaces.mojom.h"
namespace blink {
@@ -26,26 +32,57 @@ namespace blink {
// example, RenderFrameHost exposes an instance of this class for which all
// interfaces are associated with the IPC::ChannelProxy to the render process
// which hosts its corresponding RenderFrame.
-class AssociatedInterfaceProvider {
+class BLINK_COMMON_EXPORT AssociatedInterfaceProvider {
public:
- virtual ~AssociatedInterfaceProvider() {}
+ // Binds this to a remote mojom::AssociatedInterfaceProvider.
+ //
+ // |task_runner| must belong to the same thread. It will be used to dispatch
+ // all callbacks and connection error notification.
+ explicit AssociatedInterfaceProvider(
+ mojom::AssociatedInterfaceProviderAssociatedPtr proxy,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner = nullptr);
+
+ // Constructs a local provider with no remote interfaces. This is useful in
+ // conjunction with OverrideBinderForTesting(), in test environments where
+ // there may not be a remote |mojom::AssociatedInterfaceProvider| available.
+ //
+ // |task_runner| must belong to the same thread. It will be used to dispatch
+ // all callbacks and connection error notification.
+ explicit AssociatedInterfaceProvider(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner);
+
+ ~AssociatedInterfaceProvider();
// Passes an associated endpoint handle to the remote end to be bound to a
// Channel-associated interface named |name|.
- virtual void GetInterface(const std::string& name,
- mojo::ScopedInterfaceEndpointHandle handle) = 0;
+ void GetInterface(const std::string& name,
+ mojo::ScopedInterfaceEndpointHandle handle);
- // Templated helper for GetInterface().
+ // Templated helpers for GetInterface().
template <typename Interface>
- void GetInterface(mojo::AssociatedInterfacePtr<Interface>* proxy) {
- auto request = mojo::MakeRequest(proxy);
+ void GetInterface(mojo::AssociatedInterfaceRequest<Interface> request) {
GetInterface(Interface::Name_, request.PassHandle());
}
- virtual void OverrideBinderForTesting(
+ template <typename Interface>
+ void GetInterface(mojo::AssociatedInterfacePtr<Interface>* proxy) {
+ GetInterface(mojo::MakeRequest(proxy));
+ }
+
+ void OverrideBinderForTesting(
const std::string& name,
const base::RepeatingCallback<void(mojo::ScopedInterfaceEndpointHandle)>&
- binder) = 0;
+ binder);
+
+ private:
+ class LocalProvider;
+
+ mojom::AssociatedInterfaceProviderAssociatedPtr proxy_;
+
+ std::unique_ptr<LocalProvider> local_provider_;
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+
+ DISALLOW_COPY_AND_ASSIGN(AssociatedInterfaceProvider);
};
} // namespace blink
diff --git a/chromium/third_party/blink/public/common/associated_interfaces/associated_interface_registry.h b/chromium/third_party/blink/public/common/associated_interfaces/associated_interface_registry.h
index 53d4eb086d0..590786fa97a 100644
--- a/chromium/third_party/blink/public/common/associated_interfaces/associated_interface_registry.h
+++ b/chromium/third_party/blink/public/common/associated_interfaces/associated_interface_registry.h
@@ -5,12 +5,16 @@
#ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_ASSOCIATED_INTERFACES_ASSOCIATED_INTERFACE_REGISTRY_H_
#define THIRD_PARTY_BLINK_PUBLIC_COMMON_ASSOCIATED_INTERFACES_ASSOCIATED_INTERFACE_REGISTRY_H_
+#include <map>
#include <string>
#include "base/bind.h"
#include "base/callback.h"
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
#include "mojo/public/cpp/bindings/associated_interface_request.h"
#include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
+#include "third_party/blink/common/common_export.h"
namespace blink {
@@ -26,18 +30,26 @@ namespace blink {
// configuration of the specific AssociatedInterfaceRegistry instance. For
// example, RenderFrame exposes an instance of this class for which all
// interfaces are associated with the IPC::SyncChannel to the browser.
-class AssociatedInterfaceRegistry {
+class BLINK_COMMON_EXPORT AssociatedInterfaceRegistry {
public:
using Binder =
base::RepeatingCallback<void(mojo::ScopedInterfaceEndpointHandle)>;
- virtual ~AssociatedInterfaceRegistry() {}
+ AssociatedInterfaceRegistry();
+ ~AssociatedInterfaceRegistry();
// Adds an interface binder to the registry.
- virtual void AddInterface(const std::string& name, const Binder& binder) = 0;
+ void AddInterface(const std::string& name, const Binder& binder);
// Removes an interface binder from the registry.
- virtual void RemoveInterface(const std::string& name) = 0;
+ void RemoveInterface(const std::string& name);
+
+ // Attempts to bind an interface named |interface_name| using a registered
+ // binder. If no matching binder exists, this returns |false| and |*handle| is
+ // untouched. Otherwise this returns |true| and ownership of |*handle| is
+ // taken.
+ bool TryBindInterface(const std::string& name,
+ mojo::ScopedInterfaceEndpointHandle* handle);
template <typename Interface>
using InterfaceBinder = base::RepeatingCallback<void(
@@ -50,12 +62,19 @@ class AssociatedInterfaceRegistry {
base::BindRepeating(&BindInterface<Interface>, binder));
}
+ base::WeakPtr<AssociatedInterfaceRegistry> GetWeakPtr();
+
private:
template <typename Interface>
static void BindInterface(const InterfaceBinder<Interface>& binder,
mojo::ScopedInterfaceEndpointHandle handle) {
binder.Run(mojo::AssociatedInterfaceRequest<Interface>(std::move(handle)));
}
+
+ std::map<std::string, Binder> interfaces_;
+ base::WeakPtrFactory<AssociatedInterfaceRegistry> weak_ptr_factory_{this};
+
+ DISALLOW_COPY_AND_ASSIGN(AssociatedInterfaceRegistry);
};
} // namespace blink
diff --git a/chromium/third_party/blink/public/common/cache_storage/OWNERS b/chromium/third_party/blink/public/common/cache_storage/OWNERS
new file mode 100644
index 00000000000..a227a76b69c
--- /dev/null
+++ b/chromium/third_party/blink/public/common/cache_storage/OWNERS
@@ -0,0 +1,7 @@
+file://content/browser/cache_storage/OWNERS
+
+per-file *.mojom=set noparent
+per-file *.mojom=file://ipc/SECURITY_OWNERS
+
+# TEAM: storage-dev@chromium.org
+# COMPONENT: Blink>Storage>CacheStorage
diff --git a/chromium/third_party/blink/public/common/cache_storage/cache_storage_utils.h b/chromium/third_party/blink/public/common/cache_storage/cache_storage_utils.h
new file mode 100644
index 00000000000..c7234bae8d3
--- /dev/null
+++ b/chromium/third_party/blink/public/common/cache_storage/cache_storage_utils.h
@@ -0,0 +1,24 @@
+// 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_PUBLIC_COMMON_CACHE_STORAGE_CACHE_STORAGE_UTILS_H_
+#define THIRD_PARTY_BLINK_PUBLIC_COMMON_CACHE_STORAGE_CACHE_STORAGE_UTILS_H_
+
+#include "third_party/blink/common/common_export.h"
+
+namespace blink {
+namespace cache_storage {
+
+// Define the base message used when a batch operation, like addAll(),
+// has duplicate requests in its argument list. This is populated by
+// content on the browser side. The blink code in the renderer looks
+// for the message to record a UseCounter event.
+// TODO(crbug.com/877737): Remove this once the cache.addAll()
+// duplicate rejection finally ships.
+BLINK_COMMON_EXPORT extern const char kDuplicateOperationBaseMessage[];
+
+} // namespace cache_storage
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_CACHE_STORAGE_CACHE_STORAGE_UTILS_H_
diff --git a/chromium/third_party/blink/public/common/features.h b/chromium/third_party/blink/public/common/features.h
index 635ec991541..161ea5dc14b 100644
--- a/chromium/third_party/blink/public/common/features.h
+++ b/chromium/third_party/blink/public/common/features.h
@@ -11,12 +11,26 @@
namespace blink {
namespace features {
+BLINK_COMMON_EXPORT extern const base::Feature kAutofillPreviewStyleExperiment;
BLINK_COMMON_EXPORT extern const base::Feature
kEagerCacheStorageSetupForServiceWorkers;
BLINK_COMMON_EXPORT extern const base::Feature kLayoutNG;
BLINK_COMMON_EXPORT extern const base::Feature kMojoBlobURLs;
+BLINK_COMMON_EXPORT extern const base::Feature
+ kServiceWorkerImportedScriptUpdateCheck;
BLINK_COMMON_EXPORT extern const base::Feature kServiceWorkerServicification;
BLINK_COMMON_EXPORT extern const base::Feature kNestedWorkers;
+BLINK_COMMON_EXPORT extern const base::Feature kRecordAnchorMetricsClicked;
+BLINK_COMMON_EXPORT extern const base::Feature kRecordAnchorMetricsVisible;
+BLINK_COMMON_EXPORT extern const base::Feature kPortals;
+BLINK_COMMON_EXPORT extern const base::Feature kStopInBackground;
+BLINK_COMMON_EXPORT extern const base::Feature kStopNonTimersInBackground;
+BLINK_COMMON_EXPORT extern const base::Feature kWritableFilesAPI;
+
+BLINK_COMMON_EXPORT extern const char
+ kAutofillPreviewStyleExperimentBgColorParameterName[];
+BLINK_COMMON_EXPORT extern const char
+ kAutofillPreviewStyleExperimentColorParameterName[];
} // namespace features
} // namespace blink
diff --git a/chromium/third_party/blink/public/common/font_unique_name_lookup/font_table_matcher.h b/chromium/third_party/blink/public/common/font_unique_name_lookup/font_table_matcher.h
new file mode 100644
index 00000000000..290f6c045f1
--- /dev/null
+++ b/chromium/third_party/blink/public/common/font_unique_name_lookup/font_table_matcher.h
@@ -0,0 +1,63 @@
+// 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_PUBLIC_COMMON_FONT_UNIQUE_NAME_LOOKUP_FONT_TABLE_MATCHER_H_
+#define THIRD_PARTY_BLINK_PUBLIC_COMMON_FONT_UNIQUE_NAME_LOOKUP_FONT_TABLE_MATCHER_H_
+
+#include "base/memory/read_only_shared_memory_region.h"
+#include "third_party/blink/common/common_export.h"
+#include "third_party/blink/public/common/font_unique_name_lookup/font_unique_name_table.pb.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace blink {
+
+// Parses a protobuf received in memory_mapping to build a font lookup
+// structure. Allows case-insensitively matching full font names or postscript
+// font names against the parsed table by calling MatchName. Used in Blink for
+// looking up
+// @font-face { src: local(<font_name>) } CSS font face src references.
+class BLINK_COMMON_EXPORT FontTableMatcher {
+ public:
+ // Constructs a FontTableMatcher from a ReadOnlySharedMemoryMapping returned
+ // by FontUniqueNameLookup. Internally parses the Protobuf structure in
+ // memory_mapping to build a list of unique font names, which can then be
+ // matched using the MatchName method. The ReadOnlySharedMemoryMapping passed
+ // in memory_mapping only needs to be alive for the initial construction of
+ // FontTableMatcher. After that, FontTableMatcher no longer accesses it.
+ explicit FontTableMatcher(
+ const base::ReadOnlySharedMemoryMapping& memory_mapping);
+
+ // Takes a FontUniqueNameTable protobuf and serializes it into a newly created
+ // ReadonlySharedMemoryMapping. Used only for testing.
+ static base::ReadOnlySharedMemoryMapping MemoryMappingFromFontUniqueNameTable(
+ const FontUniqueNameTable& font_unique_name_table);
+
+ struct MatchResult {
+ std::string font_path;
+ uint32_t ttc_index;
+ };
+
+ // Given a font full name or font potscript name, match case insensitively
+ // against the internal list of unique font names.
+ // Return a font filesystem path and a TrueType collection index to identify a
+ // font binary to uniquely identify instantiate a font.
+ base::Optional<MatchResult> MatchName(const std::string& name_request) const;
+
+ // Returns the number of fonts available after parsing the
+ // ReadOnlySharedMemoryMapping.
+ size_t AvailableFonts() const;
+
+ // Compares this FontTableMatcher to other for whether
+ // their internal list of fonts is disjoint. Used only for testing.
+ bool FontListIsDisjointFrom(const FontTableMatcher& other) const;
+
+ private:
+ FontUniqueNameTable font_table_;
+};
+
+} // namespace blink
+
+#endif // CONTENT_BROWSER_FONT_UNIQUE_NAME_LOOKUP_FONT_TABLE_MATCHER_H_
diff --git a/chromium/third_party/blink/public/common/font_unique_name_lookup/font_unique_name_table.proto b/chromium/third_party/blink/public/common/font_unique_name_lookup/font_unique_name_table.proto
new file mode 100644
index 00000000000..4d9ae3c1aef
--- /dev/null
+++ b/chromium/third_party/blink/public/common/font_unique_name_lookup/font_unique_name_table.proto
@@ -0,0 +1,23 @@
+// 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.
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+package blink;
+
+message FontUniqueNameTable {
+ // The Android build fingerprint for which this font list is stored.
+ required string stored_for_android_build_fp = 1;
+
+ message FontUniqueNameEntry {
+ required string file_path = 10;
+ required uint32 ttc_index = 20;
+ optional string full_name = 30;
+ optional string postscript_name = 40;
+ }
+
+ repeated FontUniqueNameEntry font_entries = 10;
+} \ No newline at end of file
diff --git a/chromium/third_party/blink/public/common/font_unique_name_lookup/icu_fold_case_util.h b/chromium/third_party/blink/public/common/font_unique_name_lookup/icu_fold_case_util.h
new file mode 100644
index 00000000000..86c943894ca
--- /dev/null
+++ b/chromium/third_party/blink/public/common/font_unique_name_lookup/icu_fold_case_util.h
@@ -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.
+
+#ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_FONT_UNIQUE_NAME_LOOKUP_ICU_FOLD_CASE_UTIL_H_
+#define THIRD_PARTY_BLINK_PUBLIC_COMMON_FONT_UNIQUE_NAME_LOOKUP_ICU_FOLD_CASE_UTIL_H_
+
+#include <string>
+#include "third_party/blink/common/common_export.h"
+
+namespace blink {
+
+// Executes ICU's UnicodeString locale-independent foldCase method on
+// |name_request| and returns a case folded string suitable for case-insensitive
+// bitwise comparison. Used by FontTableMatcher and FontUniqueNameLookup for
+// storing and comparing case folded font names.
+std::string BLINK_COMMON_EXPORT IcuFoldCase(const std::string& name_request);
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_FONT_UNIQUE_NAME_LOOKUP_ICU_FOLD_CASE_UTIL_H_
diff --git a/chromium/third_party/blink/public/common/indexeddb/OWNERS b/chromium/third_party/blink/public/common/indexeddb/OWNERS
new file mode 100644
index 00000000000..3b5f7f58e91
--- /dev/null
+++ b/chromium/third_party/blink/public/common/indexeddb/OWNERS
@@ -0,0 +1,9 @@
+file://content/browser/indexed_db/OWNERS
+
+per-file *_struct_traits*.*=set noparent
+per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS
+per-file *.typemap=set noparent
+per-file *.typemap=file://ipc/SECURITY_OWNERS
+
+# TEAM: storage-dev@chromium.org
+# COMPONENT: Blink>Storage>IndexedDB
diff --git a/chromium/third_party/blink/public/common/indexeddb/indexeddb.typemap b/chromium/third_party/blink/public/common/indexeddb/indexeddb.typemap
new file mode 100644
index 00000000000..85223b65638
--- /dev/null
+++ b/chromium/third_party/blink/public/common/indexeddb/indexeddb.typemap
@@ -0,0 +1,29 @@
+# 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 = "//third_party/blink/public/mojom/indexeddb/indexeddb.mojom"
+public_headers = [
+ "//third_party/blink/public/common/indexeddb/indexeddb_key.h",
+ "//third_party/blink/public/common/indexeddb/indexeddb_key_path.h",
+ "//third_party/blink/public/common/indexeddb/indexeddb_key_range.h",
+ "//third_party/blink/public/common/indexeddb/indexeddb_metadata.h",
+ "//third_party/blink/public/common/indexeddb/web_idb_types.h",
+]
+traits_headers =
+ [ "//third_party/blink/public/common/indexeddb/indexeddb_struct_traits.h" ]
+type_mappings = [
+ "blink.mojom.IDBCursorDirection=blink::WebIDBCursorDirection",
+ "blink.mojom.IDBDataLoss=blink::WebIDBDataLoss",
+ "blink.mojom.IDBDatabaseMetadata=blink::IndexedDBDatabaseMetadata",
+ "blink.mojom.IDBIndexKeys=blink::IndexedDBIndexKeys",
+ "blink.mojom.IDBIndexMetadata=blink::IndexedDBIndexMetadata",
+ "blink.mojom.IDBKey=blink::IndexedDBKey",
+ "blink.mojom.IDBKeyPath=blink::IndexedDBKeyPath",
+ "blink.mojom.IDBKeyRange=blink::IndexedDBKeyRange",
+ "blink.mojom.IDBObjectStoreMetadata=blink::IndexedDBObjectStoreMetadata",
+ "blink.mojom.IDBOperationType=blink::WebIDBOperationType",
+ "blink.mojom.IDBPutMode=blink::WebIDBPutMode",
+ "blink.mojom.IDBTaskType=blink::WebIDBTaskType",
+ "blink.mojom.IDBTransactionMode=blink::WebIDBTransactionMode",
+]
diff --git a/chromium/third_party/blink/public/common/indexeddb/indexeddb_key.h b/chromium/third_party/blink/public/common/indexeddb/indexeddb_key.h
new file mode 100644
index 00000000000..78e891e3171
--- /dev/null
+++ b/chromium/third_party/blink/public/common/indexeddb/indexeddb_key.h
@@ -0,0 +1,81 @@
+// 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.
+
+#ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_INDEXEDDB_INDEXEDDB_KEY_H_
+#define THIRD_PARTY_BLINK_PUBLIC_COMMON_INDEXEDDB_INDEXEDDB_KEY_H_
+
+#include <stddef.h>
+
+#include <string>
+#include <vector>
+
+#include "base/logging.h"
+#include "base/strings/string16.h"
+#include "third_party/blink/common/common_export.h"
+#include "third_party/blink/public/common/indexeddb/web_idb_types.h"
+
+namespace blink {
+
+class BLINK_COMMON_EXPORT IndexedDBKey {
+ public:
+ typedef std::vector<IndexedDBKey> KeyArray;
+
+ IndexedDBKey(); // Defaults to blink::WebIDBKeyTypeInvalid.
+ explicit IndexedDBKey(blink::WebIDBKeyType); // must be Null or Invalid
+ explicit IndexedDBKey(const KeyArray& array);
+ explicit IndexedDBKey(const std::string& binary);
+ explicit IndexedDBKey(const base::string16& string);
+ IndexedDBKey(double number,
+ blink::WebIDBKeyType type); // must be date or number
+ IndexedDBKey(const IndexedDBKey& other);
+ ~IndexedDBKey();
+ IndexedDBKey& operator=(const IndexedDBKey& other);
+
+ bool IsValid() const;
+
+ bool IsLessThan(const IndexedDBKey& other) const;
+ bool Equals(const IndexedDBKey& other) const;
+
+ blink::WebIDBKeyType type() const { return type_; }
+ const std::vector<IndexedDBKey>& array() const {
+ DCHECK_EQ(type_, blink::kWebIDBKeyTypeArray);
+ return array_;
+ }
+ const std::string& binary() const {
+ DCHECK_EQ(type_, blink::kWebIDBKeyTypeBinary);
+ return binary_;
+ }
+ const base::string16& string() const {
+ DCHECK_EQ(type_, blink::kWebIDBKeyTypeString);
+ return string_;
+ }
+ double date() const {
+ DCHECK_EQ(type_, blink::kWebIDBKeyTypeDate);
+ return number_;
+ }
+ double number() const {
+ DCHECK_EQ(type_, blink::kWebIDBKeyTypeNumber);
+ return number_;
+ }
+
+ size_t size_estimate() const { return size_estimate_; }
+
+ private:
+ int CompareTo(const IndexedDBKey& other) const;
+
+ blink::WebIDBKeyType type_;
+ std::vector<IndexedDBKey> array_;
+ std::string binary_;
+ base::string16 string_;
+ double number_ = 0;
+
+ size_t size_estimate_;
+};
+
+// An index id, and corresponding set of keys to insert.
+using IndexedDBIndexKeys = std::pair<int64_t, std::vector<IndexedDBKey>>;
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_INDEXEDDB_INDEXEDDB_KEY_H_
diff --git a/chromium/third_party/blink/public/common/indexeddb/indexeddb_key_path.h b/chromium/third_party/blink/public/common/indexeddb/indexeddb_key_path.h
new file mode 100644
index 00000000000..cce15fd4a1e
--- /dev/null
+++ b/chromium/third_party/blink/public/common/indexeddb/indexeddb_key_path.h
@@ -0,0 +1,44 @@
+// 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.
+
+#ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_INDEXEDDB_INDEXEDDB_KEY_PATH_H_
+#define THIRD_PARTY_BLINK_PUBLIC_COMMON_INDEXEDDB_INDEXEDDB_KEY_PATH_H_
+
+#include <string>
+#include <vector>
+
+#include "base/logging.h"
+#include "base/strings/string16.h"
+#include "third_party/blink/common/common_export.h"
+#include "third_party/blink/public/common/indexeddb/web_idb_types.h"
+
+namespace blink {
+
+class BLINK_COMMON_EXPORT IndexedDBKeyPath {
+ public:
+ IndexedDBKeyPath(); // Defaults to blink::WebIDBKeyPathTypeNull.
+ explicit IndexedDBKeyPath(const base::string16&);
+ explicit IndexedDBKeyPath(const std::vector<base::string16>&);
+ IndexedDBKeyPath(const IndexedDBKeyPath& other);
+ IndexedDBKeyPath(IndexedDBKeyPath&& other);
+ ~IndexedDBKeyPath();
+ IndexedDBKeyPath& operator=(const IndexedDBKeyPath& other);
+ IndexedDBKeyPath& operator=(IndexedDBKeyPath&& other);
+
+ bool IsNull() const { return type_ == blink::kWebIDBKeyPathTypeNull; }
+ bool operator==(const IndexedDBKeyPath& other) const;
+
+ blink::WebIDBKeyPathType type() const { return type_; }
+ const std::vector<base::string16>& array() const;
+ const base::string16& string() const;
+
+ private:
+ blink::WebIDBKeyPathType type_;
+ base::string16 string_;
+ std::vector<base::string16> array_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_INDEXEDDB_INDEXEDDB_KEY_PATH_H_
diff --git a/chromium/third_party/blink/public/common/indexeddb/indexeddb_key_range.h b/chromium/third_party/blink/public/common/indexeddb/indexeddb_key_range.h
new file mode 100644
index 00000000000..e78f733d187
--- /dev/null
+++ b/chromium/third_party/blink/public/common/indexeddb/indexeddb_key_range.h
@@ -0,0 +1,42 @@
+// 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.
+
+#ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_INDEXEDDB_INDEXEDDB_KEY_RANGE_H_
+#define THIRD_PARTY_BLINK_PUBLIC_COMMON_INDEXEDDB_INDEXEDDB_KEY_RANGE_H_
+
+#include "third_party/blink/common/common_export.h"
+#include "third_party/blink/public/common/indexeddb/indexeddb_key.h"
+
+namespace blink {
+
+class BLINK_COMMON_EXPORT IndexedDBKeyRange {
+ public:
+ IndexedDBKeyRange();
+ explicit IndexedDBKeyRange(const blink::IndexedDBKey& key);
+ IndexedDBKeyRange(const blink::IndexedDBKey& lower,
+ const blink::IndexedDBKey& upper,
+ bool lower_open,
+ bool upper_open);
+ IndexedDBKeyRange(const IndexedDBKeyRange& other);
+ ~IndexedDBKeyRange();
+ IndexedDBKeyRange& operator=(const IndexedDBKeyRange& other);
+
+ const blink::IndexedDBKey& lower() const { return lower_; }
+ const blink::IndexedDBKey& upper() const { return upper_; }
+ bool lower_open() const { return lower_open_; }
+ bool upper_open() const { return upper_open_; }
+
+ bool IsOnlyKey() const;
+ bool IsEmpty() const;
+
+ private:
+ blink::IndexedDBKey lower_ = blink::IndexedDBKey(blink::kWebIDBKeyTypeNull);
+ blink::IndexedDBKey upper_ = blink::IndexedDBKey(blink::kWebIDBKeyTypeNull);
+ bool lower_open_ = false;
+ bool upper_open_ = false;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_INDEXEDDB_INDEXEDDB_KEY_RANGE_H_
diff --git a/chromium/third_party/blink/public/common/indexeddb/indexeddb_metadata.h b/chromium/third_party/blink/public/common/indexeddb/indexeddb_metadata.h
new file mode 100644
index 00000000000..c4aa60771f7
--- /dev/null
+++ b/chromium/third_party/blink/public/common/indexeddb/indexeddb_metadata.h
@@ -0,0 +1,95 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_INDEXEDDB_INDEXEDDB_METADATA_H_
+#define THIRD_PARTY_BLINK_PUBLIC_COMMON_INDEXEDDB_INDEXEDDB_METADATA_H_
+
+#include <stdint.h>
+
+#include <map>
+#include <string>
+
+#include "base/strings/string16.h"
+#include "third_party/blink/common/common_export.h"
+#include "third_party/blink/public/common/indexeddb/indexeddb_key_path.h"
+
+namespace blink {
+
+struct BLINK_COMMON_EXPORT IndexedDBIndexMetadata {
+ static const int64_t kInvalidId = -1;
+
+ IndexedDBIndexMetadata();
+ IndexedDBIndexMetadata(const base::string16& name,
+ int64_t id,
+ const blink::IndexedDBKeyPath& key_path,
+ bool unique,
+ bool multi_entry);
+ IndexedDBIndexMetadata(const IndexedDBIndexMetadata& other);
+ IndexedDBIndexMetadata(IndexedDBIndexMetadata&& other);
+ ~IndexedDBIndexMetadata();
+ IndexedDBIndexMetadata& operator=(const IndexedDBIndexMetadata& other);
+ IndexedDBIndexMetadata& operator=(IndexedDBIndexMetadata&& other);
+ bool operator==(const IndexedDBIndexMetadata& other) const;
+
+ base::string16 name;
+ int64_t id;
+ blink::IndexedDBKeyPath key_path;
+ bool unique;
+ bool multi_entry;
+};
+
+struct BLINK_COMMON_EXPORT IndexedDBObjectStoreMetadata {
+ static const int64_t kInvalidId = -1;
+ static const int64_t kMinimumIndexId = 30;
+
+ IndexedDBObjectStoreMetadata();
+ IndexedDBObjectStoreMetadata(const base::string16& name,
+ int64_t id,
+ const blink::IndexedDBKeyPath& key_path,
+ bool auto_increment,
+ int64_t max_index_id);
+ IndexedDBObjectStoreMetadata(const IndexedDBObjectStoreMetadata& other);
+ IndexedDBObjectStoreMetadata(IndexedDBObjectStoreMetadata&& other);
+ ~IndexedDBObjectStoreMetadata();
+ IndexedDBObjectStoreMetadata& operator=(
+ const IndexedDBObjectStoreMetadata& other);
+ IndexedDBObjectStoreMetadata& operator=(IndexedDBObjectStoreMetadata&& other);
+ bool operator==(const IndexedDBObjectStoreMetadata& other) const;
+
+ base::string16 name;
+ int64_t id;
+ blink::IndexedDBKeyPath key_path;
+ bool auto_increment;
+ int64_t max_index_id;
+
+ std::map<int64_t, IndexedDBIndexMetadata> indexes;
+};
+
+struct BLINK_COMMON_EXPORT IndexedDBDatabaseMetadata {
+ // TODO(jsbell): These can probably be collapsed into 0.
+ enum { NO_VERSION = -1, DEFAULT_VERSION = 0 };
+
+ IndexedDBDatabaseMetadata();
+ IndexedDBDatabaseMetadata(const base::string16& name,
+ int64_t id,
+ int64_t version,
+ int64_t max_object_store_id);
+ IndexedDBDatabaseMetadata(const IndexedDBDatabaseMetadata& other);
+ IndexedDBDatabaseMetadata(IndexedDBDatabaseMetadata&& other);
+ ~IndexedDBDatabaseMetadata();
+ IndexedDBDatabaseMetadata& operator=(const IndexedDBDatabaseMetadata& other);
+ IndexedDBDatabaseMetadata& operator=(IndexedDBDatabaseMetadata&& other);
+ bool operator==(const IndexedDBDatabaseMetadata& other) const;
+
+ base::string16 name;
+ int64_t id;
+ int64_t version;
+ int64_t max_object_store_id;
+
+ std::map<int64_t, IndexedDBObjectStoreMetadata> object_stores;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_INDEXEDDB_INDEXEDDB_METADATA_H_
diff --git a/chromium/third_party/blink/public/common/indexeddb/indexeddb_struct_traits.h b/chromium/third_party/blink/public/common/indexeddb/indexeddb_struct_traits.h
new file mode 100644
index 00000000000..8e29eeae342
--- /dev/null
+++ b/chromium/third_party/blink/public/common/indexeddb/indexeddb_struct_traits.h
@@ -0,0 +1,197 @@
+// 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_PUBLIC_COMMON_INDEXEDDB_INDEXEDDB_STRUCT_TRAITS_H_
+#define THIRD_PARTY_BLINK_PUBLIC_COMMON_INDEXEDDB_INDEXEDDB_STRUCT_TRAITS_H_
+
+#include "third_party/blink/common/common_export.h"
+#include "third_party/blink/public/common/indexeddb/indexeddb_key.h"
+#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h"
+
+namespace mojo {
+
+template <>
+struct BLINK_COMMON_EXPORT
+ EnumTraits<blink::mojom::IDBCursorDirection, blink::WebIDBCursorDirection> {
+ static blink::mojom::IDBCursorDirection ToMojom(
+ blink::WebIDBCursorDirection input);
+ static bool FromMojom(blink::mojom::IDBCursorDirection input,
+ blink::WebIDBCursorDirection* output);
+};
+
+template <>
+struct BLINK_COMMON_EXPORT
+ EnumTraits<blink::mojom::IDBDataLoss, blink::WebIDBDataLoss> {
+ static blink::mojom::IDBDataLoss ToMojom(blink::WebIDBDataLoss input);
+ static bool FromMojom(blink::mojom::IDBDataLoss input,
+ blink::WebIDBDataLoss* output);
+};
+
+template <>
+struct BLINK_COMMON_EXPORT
+ StructTraits<blink::mojom::IDBDatabaseMetadataDataView,
+ blink::IndexedDBDatabaseMetadata> {
+ static int64_t id(const blink::IndexedDBDatabaseMetadata& metadata) {
+ return metadata.id;
+ }
+ static base::string16 name(const blink::IndexedDBDatabaseMetadata& metadata) {
+ return metadata.name;
+ }
+ static int64_t version(const blink::IndexedDBDatabaseMetadata& metadata) {
+ return metadata.version;
+ }
+ static int64_t max_object_store_id(
+ const blink::IndexedDBDatabaseMetadata& metadata) {
+ return metadata.max_object_store_id;
+ }
+ static MapValuesArrayView<int64_t, blink::IndexedDBObjectStoreMetadata>
+ object_stores(const blink::IndexedDBDatabaseMetadata& metadata) {
+ return MapValuesToArray(metadata.object_stores);
+ }
+ static bool Read(blink::mojom::IDBDatabaseMetadataDataView data,
+ blink::IndexedDBDatabaseMetadata* out);
+};
+
+template <>
+struct BLINK_COMMON_EXPORT StructTraits<blink::mojom::IDBIndexKeysDataView,
+ blink::IndexedDBIndexKeys> {
+ static int64_t index_id(const blink::IndexedDBIndexKeys& index_keys) {
+ return index_keys.first;
+ }
+ static const std::vector<blink::IndexedDBKey>& index_keys(
+ const blink::IndexedDBIndexKeys& index_keys) {
+ return index_keys.second;
+ }
+ static bool Read(blink::mojom::IDBIndexKeysDataView data,
+ blink::IndexedDBIndexKeys* out);
+};
+
+template <>
+struct BLINK_COMMON_EXPORT StructTraits<blink::mojom::IDBIndexMetadataDataView,
+ blink::IndexedDBIndexMetadata> {
+ static int64_t id(const blink::IndexedDBIndexMetadata& metadata) {
+ return metadata.id;
+ }
+ static base::string16 name(const blink::IndexedDBIndexMetadata& metadata) {
+ return metadata.name;
+ }
+ static const blink::IndexedDBKeyPath& key_path(
+ const blink::IndexedDBIndexMetadata& metadata) {
+ return metadata.key_path;
+ }
+ static bool unique(const blink::IndexedDBIndexMetadata& metadata) {
+ return metadata.unique;
+ }
+ static bool multi_entry(const blink::IndexedDBIndexMetadata& metadata) {
+ return metadata.multi_entry;
+ }
+ static bool Read(blink::mojom::IDBIndexMetadataDataView data,
+ blink::IndexedDBIndexMetadata* out);
+};
+
+template <>
+struct BLINK_COMMON_EXPORT
+ StructTraits<blink::mojom::IDBKeyDataView, blink::IndexedDBKey> {
+ static blink::mojom::IDBKeyDataPtr data(const blink::IndexedDBKey& key);
+ static bool Read(blink::mojom::IDBKeyDataView data, blink::IndexedDBKey* out);
+};
+
+template <>
+struct BLINK_COMMON_EXPORT
+ StructTraits<blink::mojom::IDBKeyPathDataView, blink::IndexedDBKeyPath> {
+ static blink::mojom::IDBKeyPathDataPtr data(
+ const blink::IndexedDBKeyPath& key_path);
+ static bool Read(blink::mojom::IDBKeyPathDataView data,
+ blink::IndexedDBKeyPath* out);
+};
+
+template <>
+struct BLINK_COMMON_EXPORT
+ StructTraits<blink::mojom::IDBKeyRangeDataView, blink::IndexedDBKeyRange> {
+ static const blink::IndexedDBKey& lower(
+ const blink::IndexedDBKeyRange& key_range) {
+ return key_range.lower();
+ }
+ static const blink::IndexedDBKey& upper(
+ const blink::IndexedDBKeyRange& key_range) {
+ return key_range.upper();
+ }
+ static bool lower_open(const blink::IndexedDBKeyRange& key_range) {
+ return key_range.lower_open();
+ }
+ static bool upper_open(const blink::IndexedDBKeyRange& key_range) {
+ return key_range.upper_open();
+ }
+ static bool Read(blink::mojom::IDBKeyRangeDataView data,
+ blink::IndexedDBKeyRange* out);
+};
+
+template <>
+struct BLINK_COMMON_EXPORT
+ StructTraits<blink::mojom::IDBObjectStoreMetadataDataView,
+ blink::IndexedDBObjectStoreMetadata> {
+ static int64_t id(const blink::IndexedDBObjectStoreMetadata& metadata) {
+ return metadata.id;
+ }
+ static base::string16 name(
+ const blink::IndexedDBObjectStoreMetadata& metadata) {
+ return metadata.name;
+ }
+ static const blink::IndexedDBKeyPath& key_path(
+ const blink::IndexedDBObjectStoreMetadata& metadata) {
+ return metadata.key_path;
+ }
+ static bool auto_increment(
+ const blink::IndexedDBObjectStoreMetadata& metadata) {
+ return metadata.auto_increment;
+ }
+ static int64_t max_index_id(
+ const blink::IndexedDBObjectStoreMetadata& metadata) {
+ return metadata.max_index_id;
+ }
+ static MapValuesArrayView<int64_t, blink::IndexedDBIndexMetadata> indexes(
+ const blink::IndexedDBObjectStoreMetadata& metadata) {
+ return MapValuesToArray(metadata.indexes);
+ }
+ static bool Read(blink::mojom::IDBObjectStoreMetadataDataView data,
+ blink::IndexedDBObjectStoreMetadata* out);
+};
+
+template <>
+struct BLINK_COMMON_EXPORT
+ EnumTraits<blink::mojom::IDBOperationType, blink::WebIDBOperationType> {
+ static blink::mojom::IDBOperationType ToMojom(
+ blink::WebIDBOperationType input);
+ static bool FromMojom(blink::mojom::IDBOperationType input,
+ blink::WebIDBOperationType* output);
+};
+
+template <>
+struct BLINK_COMMON_EXPORT
+ EnumTraits<blink::mojom::IDBPutMode, blink::WebIDBPutMode> {
+ static blink::mojom::IDBPutMode ToMojom(blink::WebIDBPutMode input);
+ static bool FromMojom(blink::mojom::IDBPutMode input,
+ blink::WebIDBPutMode* output);
+};
+
+template <>
+struct BLINK_COMMON_EXPORT
+ EnumTraits<blink::mojom::IDBTaskType, blink::WebIDBTaskType> {
+ static blink::mojom::IDBTaskType ToMojom(blink::WebIDBTaskType input);
+ static bool FromMojom(blink::mojom::IDBTaskType input,
+ blink::WebIDBTaskType* output);
+};
+
+template <>
+struct BLINK_COMMON_EXPORT
+ EnumTraits<blink::mojom::IDBTransactionMode, blink::WebIDBTransactionMode> {
+ static blink::mojom::IDBTransactionMode ToMojom(
+ blink::WebIDBTransactionMode input);
+ static bool FromMojom(blink::mojom::IDBTransactionMode input,
+ blink::WebIDBTransactionMode* output);
+};
+
+} // namespace mojo
+
+#endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_INDEXEDDB_INDEXEDDB_STRUCT_TRAITS_H_
diff --git a/chromium/third_party/blink/public/platform/modules/indexeddb/web_idb_types.h b/chromium/third_party/blink/public/common/indexeddb/web_idb_types.h
index 08981cf799d..2728e86e5e6 100644
--- a/chromium/third_party/blink/public/platform/modules/indexeddb/web_idb_types.h
+++ b/chromium/third_party/blink/public/common/indexeddb/web_idb_types.h
@@ -23,11 +23,13 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_INDEXEDDB_WEB_IDB_TYPES_H_
-#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_INDEXEDDB_WEB_IDB_TYPES_H_
+#ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_INDEXEDDB_WEB_IDB_TYPES_H_
+#define THIRD_PARTY_BLINK_PUBLIC_COMMON_INDEXEDDB_WEB_IDB_TYPES_H_
namespace blink {
+// TODO(cmp): Deprecate these in favor of the blink.mojom.IDB* enum types.
+
enum WebIDBKeyType {
kWebIDBKeyTypeInvalid = 0,
kWebIDBKeyTypeArray,
@@ -84,4 +86,4 @@ enum WebIDBTransactionMode {
} // namespace blink
-#endif // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_INDEXEDDB_WEB_IDB_TYPES_H_
+#endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_INDEXEDDB_WEB_IDB_TYPES_H_
diff --git a/chromium/third_party/blink/public/common/manifest/manifest.h b/chromium/third_party/blink/public/common/manifest/manifest.h
index 00d762227fe..079a81dee72 100644
--- a/chromium/third_party/blink/public/common/manifest/manifest.h
+++ b/chromium/third_party/blink/public/common/manifest/manifest.h
@@ -61,14 +61,25 @@ struct BLINK_COMMON_EXPORT Manifest {
std::vector<Purpose> purpose;
};
+ // Structure representing a Web Share target's query parameter keys.
+ struct BLINK_COMMON_EXPORT ShareTargetParams {
+ ShareTargetParams();
+ ~ShareTargetParams();
+
+ base::NullableString16 title;
+ base::NullableString16 text;
+ base::NullableString16 url;
+ };
+
// Structure representing how a Web Share target handles an incoming share.
struct BLINK_COMMON_EXPORT ShareTarget {
ShareTarget();
~ShareTarget();
- // The URL template that contains placeholders to be replaced with shared
- // data. Empty if the parsing failed.
- GURL url_template;
+ // The URL used for sharing. Query parameters are added to this comprised of
+ // keys from |params| and values from the shared data.
+ GURL action;
+ ShareTargetParams params;
};
// Structure representing a related application.
diff --git a/chromium/third_party/blink/public/common/manifest/manifest_mojom_traits.h b/chromium/third_party/blink/public/common/manifest/manifest_mojom_traits.h
index a4350bc83ad..dce58314c94 100644
--- a/chromium/third_party/blink/public/common/manifest/manifest_mojom_traits.h
+++ b/chromium/third_party/blink/public/common/manifest/manifest_mojom_traits.h
@@ -167,11 +167,35 @@ struct BLINK_COMMON_EXPORT
template <>
struct BLINK_COMMON_EXPORT
+ StructTraits<blink::mojom::ManifestShareTargetParamsDataView,
+ ::blink::Manifest::ShareTargetParams> {
+ static const base::Optional<base::StringPiece16> text(
+ const ::blink::Manifest::ShareTargetParams& share_target_params) {
+ return internal::TruncateNullableString16(share_target_params.text);
+ }
+ static const base::Optional<base::StringPiece16> title(
+ const ::blink::Manifest::ShareTargetParams& share_target_params) {
+ return internal::TruncateNullableString16(share_target_params.title);
+ }
+ static const base::Optional<base::StringPiece16> url(
+ const ::blink::Manifest::ShareTargetParams& share_target_params) {
+ return internal::TruncateNullableString16(share_target_params.url);
+ }
+ static bool Read(blink::mojom::ManifestShareTargetParamsDataView data,
+ ::blink::Manifest::ShareTargetParams* out);
+};
+
+template <>
+struct BLINK_COMMON_EXPORT
StructTraits<blink::mojom::ManifestShareTargetDataView,
::blink::Manifest::ShareTarget> {
- static const GURL& url_template(
+ static const GURL& action(
+ const ::blink::Manifest::ShareTarget& share_target) {
+ return share_target.action;
+ }
+ static const ::blink::Manifest::ShareTargetParams& params(
const ::blink::Manifest::ShareTarget& share_target) {
- return share_target.url_template;
+ return share_target.params;
}
static bool Read(blink::mojom::ManifestShareTargetDataView data,
::blink::Manifest::ShareTarget* out);
diff --git a/chromium/third_party/blink/public/common/manifest/manifest_share_target_util.h b/chromium/third_party/blink/public/common/manifest/manifest_share_target_util.h
deleted file mode 100644
index b79def57d23..00000000000
--- a/chromium/third_party/blink/public/common/manifest/manifest_share_target_util.h
+++ /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.
-
-#ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_MANIFEST_MANIFEST_SHARE_TARGET_UTIL_H_
-#define THIRD_PARTY_BLINK_PUBLIC_COMMON_MANIFEST_MANIFEST_SHARE_TARGET_UTIL_H_
-
-#include <string>
-
-#include "base/strings/string_piece.h"
-#include "third_party/blink/common/common_export.h"
-
-class GURL;
-
-namespace blink {
-
-// Determines whether |url_template| is valid; that is, whether
-// ReplaceWebShareUrlPlaceholders() would succeed for the given template.
-BLINK_COMMON_EXPORT bool ValidateWebShareUrlTemplate(const GURL& url_template);
-
-// Writes to |url_template_filled|, a copy of |url_template| with all
-// instances of "{title}", "{text}", and "{url}" in the query and fragment
-// parts of the URL replaced with |title|, |text|, and |url| respectively.
-// Replaces instances of "{X}" where "X" is any string besides "title",
-// "text", and "url", with an empty string, for forwards compatibility.
-// Returns false, if there are badly nested placeholders.
-// This includes any case in which two "{" occur before a "}", or a "}"
-// occurs with no preceding "{".
-BLINK_COMMON_EXPORT bool ReplaceWebShareUrlPlaceholders(
- const GURL& url_template,
- base::StringPiece title,
- base::StringPiece text,
- const GURL& share_url,
- GURL* url_template_filled);
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_MANIFEST_MANIFEST_SHARE_TARGET_UTIL_H_
diff --git a/chromium/third_party/blink/public/common/message_port/cloneable_message.h b/chromium/third_party/blink/public/common/message_port/cloneable_message.h
index f7d981aeee3..8f6d3fceb52 100644
--- a/chromium/third_party/blink/public/common/message_port/cloneable_message.h
+++ b/chromium/third_party/blink/public/common/message_port/cloneable_message.h
@@ -9,6 +9,8 @@
#include "base/containers/span.h"
#include "base/macros.h"
+#include "base/optional.h"
+#include "base/unguessable_token.h"
#include "mojo/public/cpp/bindings/struct_ptr.h"
#include "third_party/blink/common/common_export.h"
#include "third_party/blink/public/mojom/blob/serialized_blob.mojom.h"
@@ -47,6 +49,11 @@ struct BLINK_COMMON_EXPORT CloneableMessage {
int64_t stack_trace_debugger_id_first = 0;
int64_t stack_trace_debugger_id_second = 0;
+ // If not null, this message is locked to the given agent cluster ID.
+ // See
+ // https://html.spec.whatwg.org/multipage/webappapis.html#integration-with-the-javascript-agent-cluster-formalism
+ base::Optional<base::UnguessableToken> locked_agent_cluster_id;
+
private:
DISALLOW_COPY_AND_ASSIGN(CloneableMessage);
};
diff --git a/chromium/third_party/blink/public/common/message_port/transferable_message.h b/chromium/third_party/blink/public/common/message_port/transferable_message.h
index 765978896bc..7ddd36b70d0 100644
--- a/chromium/third_party/blink/public/common/message_port/transferable_message.h
+++ b/chromium/third_party/blink/public/common/message_port/transferable_message.h
@@ -13,6 +13,7 @@
#include "third_party/blink/public/common/message_port/cloneable_message.h"
#include "third_party/blink/public/common/message_port/message_port_channel.h"
#include "third_party/blink/public/mojom/array_buffer/array_buffer_contents.mojom.h"
+#include "third_party/blink/public/mojom/message_port/user_activation_snapshot.mojom.h"
#include "third_party/skia/include/core/SkBitmap.h"
namespace blink {
@@ -37,6 +38,9 @@ struct BLINK_COMMON_EXPORT TransferableMessage : public CloneableMessage {
// message.
bool has_user_gesture = false;
+ // The state of user activation.
+ mojom::UserActivationSnapshotPtr user_activation;
+
private:
DISALLOW_COPY_AND_ASSIGN(TransferableMessage);
};
diff --git a/chromium/third_party/blink/public/common/oom_intervention/oom_intervention_types.h b/chromium/third_party/blink/public/common/oom_intervention/oom_intervention_types.h
new file mode 100644
index 00000000000..94e1f60a031
--- /dev/null
+++ b/chromium/third_party/blink/public/common/oom_intervention/oom_intervention_types.h
@@ -0,0 +1,34 @@
+// 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_PUBLIC_COMMON_OOM_INTERVENTION_OOM_INTERVENTION_TYPES_H_
+#define THIRD_PARTY_BLINK_PUBLIC_COMMON_OOM_INTERVENTION_OOM_INTERVENTION_TYPES_H_
+
+#include <stdint.h>
+
+namespace blink {
+
+// The struct with renderer metrics that are used to detect OOMs. This is stored
+// in shared memory so that browser can read it even after the renderer dies.
+// Use uint64_t for this struct in order to keep the memory layout exactly the
+// same across architectures, since it is possible on Android to have browser in
+// the arm64 and renderer in the arm32.
+
+struct OomInterventionMetrics {
+ uint64_t current_private_footprint_kb;
+ uint64_t current_swap_kb;
+ uint64_t current_vm_size_kb;
+
+ // Stores the total of V8, BlinkGC and PartitionAlloc memory usage.
+ uint64_t current_blink_usage_kb;
+
+ // Indicates whether the crash was because of virtual address space OOM.
+ // This holds only 0 or 1 as a value but because of the reason stated above,
+ // uses uint64_t instead of boolean.
+ uint64_t virtual_memory_oom;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_OOM_INTERVENTION_OOM_INTERVENTION_TYPES_H_
diff --git a/chromium/third_party/blink/public/common/picture_in_picture/picture_in_picture_control_info.h b/chromium/third_party/blink/public/common/picture_in_picture/picture_in_picture_control_info.h
new file mode 100644
index 00000000000..e27a29e92e3
--- /dev/null
+++ b/chromium/third_party/blink/public/common/picture_in_picture/picture_in_picture_control_info.h
@@ -0,0 +1,38 @@
+// 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_PUBLIC_COMMON_PICTURE_IN_PICTURE_PICTURE_IN_PICTURE_CONTROL_INFO_H_
+#define THIRD_PARTY_BLINK_PUBLIC_COMMON_PICTURE_IN_PICTURE_PICTURE_IN_PICTURE_CONTROL_INFO_H_
+
+#include <string>
+#include <vector>
+#include "ui/gfx/geometry/size.h"
+#include "url/gurl.h"
+
+namespace blink {
+
+// PictureInPictureControlInfo passes information about the desired custom
+// controls for a Picture-in-Picture window from the Web API to the
+// OverlayWindow.
+struct PictureInPictureControlInfo {
+ // These vectors represent the members of a deserialized MediaImage.
+ struct Icon {
+ GURL src;
+ std::vector<gfx::Size> sizes;
+ std::string type;
+ };
+
+ // |id| is the unique name of the custom control.
+ std::string id;
+
+ // |label| is the descriptive text used for accessibility and hover text.
+ std::string label;
+
+ // |icons| contains the images used for the custom control.
+ std::vector<Icon> icons;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_PICTURE_IN_PICTURE_PICTURE_IN_PICTURE_CONTROL_INFO_H_
diff --git a/chromium/third_party/blink/public/common/service_worker/service_worker_status_code.h b/chromium/third_party/blink/public/common/service_worker/service_worker_status_code.h
index f74ee9bd191..31baf1c1a6b 100644
--- a/chromium/third_party/blink/public/common/service_worker/service_worker_status_code.h
+++ b/chromium/third_party/blink/public/common/service_worker/service_worker_status_code.h
@@ -75,11 +75,14 @@ enum class ServiceWorkerStatusCode {
// Obsolete.
// kErrorDisabledWorker = 19,
+ // The arguments to call the API were invalid.
+ kErrorInvalidArguments = 20,
+
// Add new status codes here and update kMaxValue and enums.xml. The next new
- // status code should be 20.
+ // status code should be 21.
// Note: kMaxValue is needed only for histograms.
- kMaxValue = kErrorDisallowed
+ kMaxValue = kErrorInvalidArguments
};
BLINK_COMMON_EXPORT const char* ServiceWorkerStatusToString(
diff --git a/chromium/third_party/blink/public/common/service_worker/service_worker_utils.h b/chromium/third_party/blink/public/common/service_worker/service_worker_utils.h
index 8aed3652cd0..2acc4338bf7 100644
--- a/chromium/third_party/blink/public/common/service_worker/service_worker_utils.h
+++ b/chromium/third_party/blink/public/common/service_worker/service_worker_utils.h
@@ -15,6 +15,8 @@ class ServiceWorkerUtils {
// the NetworkService or ServiceWorkerServicification feature is enabled).
// TODO(crbug.com/715640): Remove this after non-NetS13nSW is removed.
static bool BLINK_COMMON_EXPORT IsServicificationEnabled();
+
+ static bool BLINK_COMMON_EXPORT IsImportedScriptUpdateCheckEnabled();
};
} // namespace blink
diff --git a/chromium/third_party/blink/public/mojom/BUILD.gn b/chromium/third_party/blink/public/mojom/BUILD.gn
index 87fcdf89727..e3f0d9e8042 100644
--- a/chromium/third_party/blink/public/mojom/BUILD.gn
+++ b/chromium/third_party/blink/public/mojom/BUILD.gn
@@ -10,6 +10,7 @@ import("//mojo/public/tools/bindings/mojom.gni")
mojom("mojom_platform") {
sources = [
"array_buffer/array_buffer_contents.mojom",
+ "associated_interfaces/associated_interfaces.mojom",
"blob/blob.mojom",
"blob/blob_registry.mojom",
"blob/blob_url_store.mojom",
@@ -18,12 +19,17 @@ mojom("mojom_platform") {
"clipboard/clipboard.mojom",
"color_chooser/color_chooser.mojom",
"cookie_store/cookie_store.mojom",
+ "crash/crash_memory_metrics_reporter.mojom",
"dom_storage/session_storage_namespace.mojom",
"dom_storage/storage_area.mojom",
"dom_storage/storage_partition_service.mojom",
"feature_policy/feature_policy.mojom",
+ "fetch/fetch_api_response.mojom",
"file/file_utilities.mojom",
+ "filesystem/file_system.mojom",
+ "filesystem/file_writer.mojom",
"frame/find_in_page.mojom",
+ "indexeddb/indexeddb.mojom",
"leak_detector/leak_detector.mojom",
"loader/navigation_predictor.mojom",
"loader/pause_subresource_loading_handle.mojom",
@@ -34,7 +40,9 @@ mojom("mojom_platform") {
"net/ip_address_space.mojom",
"page/display_cutout.mojom",
"page/page_visibility_state.mojom",
+ "payments/payment_app.mojom",
"plugins/plugin_registry.mojom",
+ "presentation/presentation.mojom",
"quota/quota_dispatcher_host.mojom",
"quota/quota_types.mojom",
"service_worker/dispatch_fetch_event_params.mojom",
@@ -42,6 +50,7 @@ mojom("mojom_platform") {
"service_worker/service_worker_client.mojom",
"service_worker/service_worker_error_type.mojom",
"service_worker/service_worker_event_status.mojom",
+ "service_worker/service_worker_fetch_response_callback.mojom",
"service_worker/service_worker_installed_scripts_manager.mojom",
"service_worker/service_worker_provider_type.mojom",
"service_worker/service_worker_state.mojom",
@@ -53,10 +62,14 @@ mojom("mojom_platform") {
"speech/speech_recognizer.mojom",
"use_counter/css_property_id.mojom",
"web_package/web_package_internals.mojom",
+ "webaudio/audio_context_manager.mojom",
]
public_deps = [
+ ":android_mojo_bindings",
":speech_recognition_error_code",
+ "//components/payments/mojom",
+ "//components/services/filesystem/public/interfaces",
"//mojo/public/mojom/base",
"//services/device/public/mojom",
"//services/network/public/mojom",
@@ -65,6 +78,7 @@ mojom("mojom_platform") {
# get fixed.
"//services/network/public/mojom:data_pipe_interfaces",
"//skia/public/interfaces",
+ "//third_party/blink/public/mojom/usb",
"//ui/gfx/geometry/mojo",
"//url/mojom:url_mojom_gurl",
"//url/mojom:url_mojom_origin",
@@ -79,6 +93,26 @@ mojom("mojom_platform") {
export_header_blink = "third_party/blink/renderer/platform/platform_export.h"
}
+# Kept separate from "mojom_platform" because the Java bindings are specifically
+# needed by Android's implementation of payments
+# (in components/payments/content/android and chrome/android/).
+mojom("android_mojo_bindings") {
+ sources = [
+ "payments/payment_request.mojom",
+ ]
+ public_deps = [
+ "//components/payments/mojom",
+ ]
+
+ export_class_attribute = "BLINK_COMMON_EXPORT"
+ export_define = "BLINK_COMMON_IMPLEMENTATION=1"
+ export_header = "third_party/blink/common/common_export.h"
+
+ export_class_attribute_blink = "PLATFORM_EXPORT"
+ export_define_blink = "BLINK_PLATFORM_IMPLEMENTATION=1"
+ export_header_blink = "third_party/blink/renderer/platform/platform_export.h"
+}
+
# Kept separate from "mojom_platform" because the Java bindings are needed by
# Android's implementation of speech recognition.
mojom("speech_recognition_error_code") {
@@ -100,6 +134,8 @@ mojom("speech_recognition_error_code") {
mojom("mojom_core") {
sources = [
"message_port/message_port.mojom",
+ "message_port/user_activation_snapshot.mojom",
+ "portal/portal.mojom",
"service_worker/service_worker.mojom",
"service_worker/service_worker_object.mojom",
"service_worker/service_worker_registration.mojom",
diff --git a/chromium/third_party/blink/public/mojom/associated_interfaces/OWNERS b/chromium/third_party/blink/public/mojom/associated_interfaces/OWNERS
new file mode 100644
index 00000000000..08850f42120
--- /dev/null
+++ b/chromium/third_party/blink/public/mojom/associated_interfaces/OWNERS
@@ -0,0 +1,2 @@
+per-file *.mojom=set noparent
+per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/chromium/third_party/blink/public/mojom/associated_interfaces/associated_interfaces.mojom b/chromium/third_party/blink/public/mojom/associated_interfaces/associated_interfaces.mojom
new file mode 100644
index 00000000000..20ce5b370d2
--- /dev/null
+++ b/chromium/third_party/blink/public/mojom/associated_interfaces/associated_interfaces.mojom
@@ -0,0 +1,15 @@
+// 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 blink.mojom;
+
+// A generic, nominal interface to support transitional Channel-associated
+// interfaces not known to Blink.
+interface AssociatedInterface {};
+
+// Analogous to the generic InterfaceProvider interface, but for content
+// AssociatedInterfaces.
+interface AssociatedInterfaceProvider {
+ GetAssociatedInterface(string name, associated AssociatedInterface& request);
+};
diff --git a/chromium/third_party/blink/public/mojom/crash/OWNERS b/chromium/third_party/blink/public/mojom/crash/OWNERS
new file mode 100644
index 00000000000..faea83280c9
--- /dev/null
+++ b/chromium/third_party/blink/public/mojom/crash/OWNERS
@@ -0,0 +1,5 @@
+per-file *.mojom=set noparent
+per-file *.mojom=file://ipc/SECURITY_OWNERS
+
+yuzus@chromium.org
+
diff --git a/chromium/third_party/blink/public/mojom/crash/crash_memory_metrics_reporter.mojom b/chromium/third_party/blink/public/mojom/crash/crash_memory_metrics_reporter.mojom
new file mode 100644
index 00000000000..ab0febc5af4
--- /dev/null
+++ b/chromium/third_party/blink/public/mojom/crash/crash_memory_metrics_reporter.mojom
@@ -0,0 +1,16 @@
+// 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.
+
+module blink.mojom;
+
+import "mojo/public/mojom/base/shared_memory.mojom";
+
+// Renderer side interface for CrashMemoryMetricsReporter.
+interface CrashMemoryMetricsReporter {
+ // This method is called by the browser process, and sets shared memory that
+ // will be filled with renderer memory metrics and will be reported back to
+ // the browser process.
+ // TODO(crbug.com/873076): Use WritableSharedMemoryRegion when it's possible.
+ SetSharedMemory(mojo_base.mojom.UnsafeSharedMemoryRegion shared_metrics_buffer);
+};
diff --git a/chromium/third_party/blink/public/mojom/dom_storage/OWNERS b/chromium/third_party/blink/public/mojom/dom_storage/OWNERS
index 645e7a9fd60..c9d038d9be0 100644
--- a/chromium/third_party/blink/public/mojom/dom_storage/OWNERS
+++ b/chromium/third_party/blink/public/mojom/dom_storage/OWNERS
@@ -1,5 +1,4 @@
-mek@chromium.org
-dmurph@chromium.org
+file://content/browser/dom_storage/OWNERS
per-file *.mojom=set noparent
per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/chromium/third_party/blink/public/mojom/dom_storage/storage_area.mojom b/chromium/third_party/blink/public/mojom/dom_storage/storage_area.mojom
index a7aeaef381d..33de2bb0f44 100644
--- a/chromium/third_party/blink/public/mojom/dom_storage/storage_area.mojom
+++ b/chromium/third_party/blink/public/mojom/dom_storage/storage_area.mojom
@@ -38,6 +38,16 @@ interface StorageAreaGetAllCallback {
// The mojo interface representing the connection to a single DOMStorage Area.
interface StorageArea {
+ // The quota for each storage area.
+ // This value is enforced in renderer processes and the browser process.
+ const uint32 kPerStorageAreaQuota = 10485760; // 10 MiB
+
+ // In the browser process we allow some overage to
+ // accommodate concurrent writes from different renderers
+ // that were allowed because the limit imposed in the renderer
+ // wasn't exceeded.
+ const uint32 kPerStorageAreaOverQuotaAllowance = 102400; // 100 KiB
+
AddObserver(associated StorageAreaObserver observer);
// Set the database entry for |key| to |value|.
diff --git a/chromium/third_party/blink/public/mojom/fetch/OWNERS b/chromium/third_party/blink/public/mojom/fetch/OWNERS
new file mode 100644
index 00000000000..2eaf30a9c19
--- /dev/null
+++ b/chromium/third_party/blink/public/mojom/fetch/OWNERS
@@ -0,0 +1,7 @@
+file://third_party/blink/renderer/core/fetch/OWNERS
+
+per-file *.mojom=set noparent
+per-file *.mojom=file://ipc/SECURITY_OWNERS
+
+# TEAM: blink-network-dev@chromium.org
+# COMPONENT: Blink>Network>FetchAPI
diff --git a/chromium/third_party/blink/public/mojom/fetch/README.md b/chromium/third_party/blink/public/mojom/fetch/README.md
new file mode 100644
index 00000000000..1dfa89b1407
--- /dev/null
+++ b/chromium/third_party/blink/public/mojom/fetch/README.md
@@ -0,0 +1,2 @@
+Public mojom files that are referenced both from browser-side and renderer-side
+for [Fetch API](https://fetch.spec.whatwg.org/#fetch-api).
diff --git a/chromium/third_party/blink/public/platform/modules/fetch/fetch_api_response.mojom b/chromium/third_party/blink/public/mojom/fetch/fetch_api_response.mojom
index 21d7ec93fcb..9f2482ebe80 100644
--- a/chromium/third_party/blink/public/platform/modules/fetch/fetch_api_response.mojom
+++ b/chromium/third_party/blink/public/mojom/fetch/fetch_api_response.mojom
@@ -10,10 +10,12 @@ import "third_party/blink/public/mojom/blob/serialized_blob.mojom";
import "third_party/blink/public/mojom/service_worker/service_worker_error_type.mojom";
import "url/mojom/url.mojom";
-// Represents a response to a fetch operation. ServiceWorker uses this to
-// respond to a FetchEvent dispatched by the browser. It is currently used by
-// the Cache API, and the plan is for the fetch() API to also use it. It's
-// currently typemapped to content::ServiceWorkerResponse.
+// Describes a Response in terms of the concept from the Fetch spec.
+// https://fetch.spec.whatwg.org/#response-class
+// It is currently used by Cache Storage and Service Worker, and the plan is to
+// use it also in Background Fetch to replace content::ServiceWorkerResponse.
+// Note: Be sure to update CacheStorageCache::EstimatedResponseSizeWithoutBlob()
+// when adding or removing members.
struct FetchAPIResponse {
// List of URLs that originally generated this response, it includes all URLs
// in case of HTTP redirect, first URL on redirect chain is on position 0.
@@ -22,14 +24,17 @@ struct FetchAPIResponse {
array<url.mojom.Url> url_list;
// Status code as number, e.g.: 200, 404.
- int32 status_code;
+ // Zero status code indicates an error happened and the request was not
+ // handled.
+ int32 status_code = 0;
// Status code as text. e.g.: "OK", "Not Found".
string status_text;
// Corresponds to response types from the Fetch spec:
// https://fetch.spec.whatwg.org/#concept-response-type
- network.mojom.FetchResponseType response_type;
+ network.mojom.FetchResponseType response_type =
+ network.mojom.FetchResponseType.kOpaque;
// The response headers. It's case insensitive for header name as key.
map<string, string> headers;
@@ -37,8 +42,9 @@ struct FetchAPIResponse {
// Mojo interface to read the response payload.
SerializedBlob? blob;
- // Error codes for service worker APIs. This enum is used by
- ServiceWorkerResponseError error;
+ // Error codes for service worker APIs.
+ ServiceWorkerResponseError error =
+ blink.mojom.ServiceWorkerResponseError.kUnknown;
// The time at which the response headers were received. For cached
// responses, this time could be "far" in the past.
diff --git a/chromium/third_party/blink/public/mojom/filesystem/OWNERS b/chromium/third_party/blink/public/mojom/filesystem/OWNERS
new file mode 100644
index 00000000000..4de3ede8172
--- /dev/null
+++ b/chromium/third_party/blink/public/mojom/filesystem/OWNERS
@@ -0,0 +1,7 @@
+file://third_party/blink/renderer/modules/filesystem/OWNERS
+
+per-file *.mojom=set noparent
+per-file *.mojom=file://ipc/SECURITY_OWNERS
+
+# TEAM: storage-dev@chromium.org
+# COMPONENT: Blink>Storage>FileSystem
diff --git a/chromium/third_party/blink/public/mojom/filesystem/file_system.mojom b/chromium/third_party/blink/public/mojom/filesystem/file_system.mojom
new file mode 100644
index 00000000000..8a03eb65ae7
--- /dev/null
+++ b/chromium/third_party/blink/public/mojom/filesystem/file_system.mojom
@@ -0,0 +1,227 @@
+// 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.
+
+module blink.mojom;
+
+import "components/services/filesystem/public/interfaces/types.mojom";
+import "url/mojom/url.mojom";
+import "mojo/public/mojom/base/file_error.mojom";
+import "mojo/public/mojom/base/file_path.mojom";
+import "mojo/public/mojom/base/file_info.mojom";
+import "mojo/public/mojom/base/time.mojom";
+import "third_party/blink/public/mojom/filesystem/file_writer.mojom";
+
+enum FileSystemType {
+ kTemporary,
+ kPersistent,
+ kIsolated,
+ kExternal
+};
+
+struct FileSystemInfo {
+ string name;
+ url.mojom.Url root_url;
+ FileSystemType mount_type = kTemporary;
+};
+
+// Entries as returned by the ChooseEntry method below. Each entry is
+// represented by the ID of the isolated filesystem containing the entry and
+// the name of the file in that filesystem.
+struct FileSystemEntry {
+ string file_system_id;
+ string base_name;
+};
+
+// Interface for renderers to cancel running file system operations. A
+// FileSystemCancellableOperationRequest is passed as a parameter for any
+// operation that can be cancelled.
+interface FileSystemCancellableOperation {
+ // Cancels the associated operation. It may not always be possible to cancel
+ // an operation, and partial writes are possible. |error_code| indicates if
+ // the operation was successfully canceled.
+ Cancel() => (mojo_base.mojom.FileError error_code);
+};
+
+// Operations that need to repeatedly call a particular callback use this
+// interface. For example, the Write operation needs to call DidWrite
+// repeatedly, and uses a FileSystemOperationListenerPtr passed from the
+// renderer to call it.
+// Note: For operations that only need a callback called once, we can directly
+// use mojo return value callbacks.
+interface FileSystemOperationListener {
+ // Called by ReadDirectory when entries have been obtained. |has_more| is
+ // false when all the entries are obtained, and indicates that the callback
+ // will not be called again.
+ ResultsRetrieved(array<filesystem.mojom.DirectoryEntry> entries,
+ bool has_more);
+
+ // Called repeatedly by Write to indicate progress. If |complete| is true,
+ // the operation is complete and the callback will not be called again.
+ DidWrite(int64 byte_count, bool complete);
+
+ // Called by all operations that use a listener to indicate an error. No
+ // other listener callbacks will be called after this.
+ ErrorOccurred(mojo_base.mojom.FileError error_code);
+};
+
+// Used by the renderer to notify the browser that it has received a snapshot
+// after calling CreateSnapshotFile. The browser sends an interface ptr along
+// with the result of the CreateSnapshotFile call.
+interface ReceivedSnapshotListener {
+ DidReceiveSnapshotFile();
+};
+
+// Interface provided by the browser to the renderer to carry out filesystem
+// operations. All [Sync] methods should only be called synchronously on worker
+// threads (and asynchronously otherwise).
+interface FileSystemManager {
+ // Opens a new filesystem and returns a name and root path for the requested
+ // filesystem and a success error code if the operation succeeds. If the
+ // operation fails, |error_code| indicates the reason for failure.
+ // TODO(https://crbug.com/873661): Make interface per frame/worker and remove
+ // |origin_url|.
+ [Sync]
+ Open(url.mojom.Url origin_url, blink.mojom.FileSystemType file_system_type) =>
+ (string name,
+ url.mojom.Url root_url,
+ mojo_base.mojom.FileError error_code);
+
+ // Resolves a filesystem URL and returns the filesystem information and
+ // metadata (file path and type) if the operation is successful. |error_code|
+ // indicates the reason for failure if the operation fails.
+ [Sync]
+ ResolveURL(url.mojom.Url filesystem_url) =>
+ (FileSystemInfo info,
+ mojo_base.mojom.FilePath file_path,
+ bool is_directory,
+ mojo_base.mojom.FileError error_code);
+
+ // Moves a file or directory at |src_path| to |dest_path|. Returns
+ // |error_code| after completion to indicate if the operation succeeded or
+ // failed.
+ [Sync]
+ Move(url.mojom.Url src_path, url.mojom.Url dest_path) =>
+ (mojo_base.mojom.FileError error_code);
+
+ // Copies a file or directory at |src_path| to |dest_path|. Returns
+ // |error_code| after completion to indicate if the operation succeeded or
+ // failed.
+ [Sync]
+ Copy(url.mojom.Url src_path, url.mojom.Url dest_path) =>
+ (mojo_base.mojom.FileError error_code);
+
+ // Deletes a file or directory at the given |path|. To delete recursively, set
+ // |recursive| to true. Returns |error_code| after completion to indicate if
+ // the operation succeeded or failed.
+ [Sync]
+ Remove(url.mojom.Url path, bool recursive) =>
+ (mojo_base.mojom.FileError error_code);
+
+ // Retrieves the metadata information of the file or directory at the given
+ // |path|. This may not always return the local platform path in remote
+ // filesystem cases. Returns valid metadata if the retrieval is successful,
+ // and uses |error_code| to indicate if the operation was successful.
+ [Sync]
+ ReadMetadata(url.mojom.Url path) =>
+ (mojo_base.mojom.FileInfo file_info,
+ mojo_base.mojom.FileError error_code);
+
+ // Creates a file or directory at the given |path| (based on |is_directory|).
+ // If |exclusive| is true, the operation fails if the |path| already exists.
+ // Returns |error_code| after completion to indicate if the operation
+ // succeeded or failed.
+ [Sync]
+ Create(url.mojom.Url path,
+ bool exclusive,
+ bool is_directory,
+ bool recursive) =>
+ (mojo_base.mojom.FileError error_code);
+
+ // Checks if a file exists at the given |path| if |is_directory| is false or
+ // checks if a directory exists at the given |path| otherwise. Returns
+ // |error_code| to indicate if the file was successfully found or if an error
+ // occurred.
+ [Sync]
+ Exists(url.mojom.Url path, bool is_directory) =>
+ (mojo_base.mojom.FileError error_code);
+
+ // Reads directory entries of a given directory at |path|. Calls
+ // ResultsRetrieved on |listener| when results are ready, or ErrorOccurred
+ // if the operation fails.
+ ReadDirectory(url.mojom.Url path, FileSystemOperationListener listener);
+ [Sync]
+ ReadDirectorySync(url.mojom.Url path) =>
+ (array<filesystem.mojom.DirectoryEntry> entries,
+ mojo_base.mojom.FileError error_code);
+
+ // Write data (indicated by |blob_uuid|) to the given file at |file_path|,
+ // at |position|. Calls DidWrite on |listener| to provide progress updates on
+ // the write, and |ErrorOccurred| if the operation fails. The operation can
+ // also be cancelled using the interface ptr associated with |op_request|.
+ Write(url.mojom.Url file_path,
+ string blob_uuid,
+ int64 position,
+ FileSystemCancellableOperation& op_request,
+ FileSystemOperationListener listener);
+ [Sync]
+ WriteSync(url.mojom.Url file_path, string blob_uuid, int64 position) =>
+ (int64 byte_count, mojo_base.mojom.FileError error_code);
+
+ // Changes the file length of the file at |file_path| to the |length|
+ // indicated. Returns |error_code| after completion to indicate if the
+ // operation succeeded or failed. The operation can also be cancelled using
+ // the interface ptr associated with |op_request|.
+ Truncate(url.mojom.Url file_path,
+ int64 length,
+ FileSystemCancellableOperation& op_request) =>
+ (mojo_base.mojom.FileError error_code);
+ [Sync]
+ TruncateSync(url.mojom.Url file_path, int64 length) =>
+ (mojo_base.mojom.FileError error_code);
+
+ TouchFile(url.mojom.Url path,
+ mojo_base.mojom.Time last_access_time,
+ mojo_base.mojom.Time last_modified_time) =>
+ (mojo_base.mojom.FileError error_code);
+
+ // Creates a snapshot file for a given file specified by |file_path|. Returns
+ // the metadata of the created snapshot file, which also includes a local
+ // platform path to the snapshot image (|platform_path|).
+ //
+ // In local filesystem cases the backend may simply return the metadata of the
+ // file itself (exactly like ReadMetadata would), while in remote filesystem
+ // cases, the backend may download the file into a temporary snapshot file and
+ // return the metadata of the temporary file.
+ //
+ // If |snapshot_listener| is provided, the renderer is expected to call
+ // DidReceiveSnapshotFile on the listener (which allows the backend to drop
+ // a ref to the temporary snapshot file).
+ [Sync]
+ CreateSnapshotFile(url.mojom.Url file_path) =>
+ (mojo_base.mojom.FileInfo file_info,
+ mojo_base.mojom.FilePath platform_path,
+ mojo_base.mojom.FileError error_code,
+ ReceivedSnapshotListener? snapshot_listener);
+
+ // Synchronously gets the platform path for the given |file_path|.
+ [Sync]
+ GetPlatformPath(url.mojom.Url file_path) =>
+ (mojo_base.mojom.FilePath platform_path);
+
+ // Creates a writer for the given file at |file_path|.
+ CreateWriter(url.mojom.Url file_path) =>
+ (mojo_base.mojom.FileError result,
+ blink.mojom.FileWriter? writer);
+
+ // Prompts the user to select a file from the native filesystem. Returns an
+ // error code if something failed, or a list of the selected entries on
+ // success.
+ // TODO(https://crbug.com/878581): Add more options to this method to support
+ // multiple files, directories, "open" vs "save" dialogs, etc.
+ // TODO(https://crbug.com/873661): Make interface per frame/worker and remove
+ // |render_frame_id|.
+ ChooseEntry(int32 render_frame_id) =>
+ (mojo_base.mojom.FileError error_code,
+ array<FileSystemEntry> entries);
+};
diff --git a/chromium/third_party/blink/public/mojom/filesystem/file_writer.mojom b/chromium/third_party/blink/public/mojom/filesystem/file_writer.mojom
new file mode 100644
index 00000000000..14ec83ed110
--- /dev/null
+++ b/chromium/third_party/blink/public/mojom/filesystem/file_writer.mojom
@@ -0,0 +1,24 @@
+// 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.
+
+module blink.mojom;
+
+import "mojo/public/mojom/base/file_error.mojom";
+import "third_party/blink/public/mojom/blob/blob.mojom";
+
+// Interface provided to the renderer to let a renderer write data to a file.
+interface FileWriter {
+ // Write data from |blob| to the given |position| in the file being written
+ // to. Returns whether the operation succeeded and if so how many bytes were
+ // written.
+ // TODO(mek): This might need some way of reporting progress events back to
+ // the renderer.
+ Write(uint64 position, Blob blob) => (mojo_base.mojom.FileError result,
+ uint64 bytes_written);
+
+ // Changes the length of the file to be |length|. If |length| is larger than
+ // the current size of the file, the file will be extended, and the extended
+ // part is filled with null bytes.
+ Truncate(uint64 length) => (mojo_base.mojom.FileError result);
+};
diff --git a/chromium/third_party/blink/public/mojom/frame/find_in_page.mojom b/chromium/third_party/blink/public/mojom/frame/find_in_page.mojom
index da7ca3e37a4..177e18855f9 100644
--- a/chromium/third_party/blink/public/mojom/frame/find_in_page.mojom
+++ b/chromium/third_party/blink/public/mojom/frame/find_in_page.mojom
@@ -7,6 +7,13 @@ module blink.mojom;
import "ui/gfx/geometry/mojo/geometry.mojom";
interface FindInPage {
+ // If |options.find_next| is false, this is a "Start Find" call.
+ // It starts a new find-in-page session with id |request_id|.
+ // If |options.find_next| is true, this is a "Find Next" call.
+ // It asks the active/highlighted match for session with id |request_id|
+ // to be moved either forward if |options.forward| is true, or backwards
+ // if |options.forward| is false.
+ Find(int32 request_id, string search_text, FindOptions options);
// Notifies the frame that we are no longer interested in searching. This
// will abort any asynchronous scoping effort already under way and erase
@@ -24,26 +31,16 @@ interface FindInPage {
GetNearestFindResult(gfx.mojom.PointF point) => (float distance);
// Activates a find result nearest to |point|, which is in fractions of the
- // content document's width and height.
- //
- // Return values:
- //
- // |active_match_rect| will contain the bounding box of the activated
- // find-in-page match marker. Might be an empty rect if there is none.
- //
- // |number_of_matches| is the current number of matches, or -1 if we
- // shouldn't update number of matches.
- //
- // |active_match_ordinal| will contain the activated match's ordinal
- // or -1 if we shouldn't update the active match ordinal.
- //
- // |final_update| is true if it's the final find reply for the frame.
- //
- ActivateNearestFindResult(gfx.mojom.PointF point) =>
- (gfx.mojom.Rect active_match_rect,
- int32 number_of_matches,
- int32 active_match_ordinal,
- bool final_update);
+ // content document's width and height. This function will call either the
+ // SetActiveMatch or SetNumberOfMatches on the FindInPageClient for this
+ // FindInPage instance.
+ // TODO(rakina): Find a way to remove |request_id|
+ ActivateNearestFindResult(int32 request_id, gfx.mojom.PointF point);
+
+ // Sets the client for this FindInPage instance. Should be called before
+ // calling ActivateNearestFindResult.
+ // TODO(rakina): Remove the need for this?
+ SetClient(FindInPageClient client);
// Returns the bounding boxes of the find-in-page match markers from the
// frame. The bounding boxes are returned in find-in-page coordinates.
@@ -68,6 +65,22 @@ interface FindInPage {
gfx.mojom.RectF active_match_rect);
};
+// Per-frame client of FindInPage.
+interface FindInPageClient {
+ // Sets the number of matches of the frame to |number_of_matches|.
+ // If |final_update| is kFinalUpdate, there will be no more update to the
+ // number of matches or active match for this frame.
+ SetNumberOfMatches(int32 request_id, uint32 number_of_matches,
+ FindMatchUpdateType update_type);
+
+ // Sets the current active match rect and ordinal.
+ // If |final_update| is kFinalUpdate, there will be no more update to the
+ // number of matches or active match for this frame.
+ SetActiveMatch(int32 request_id, gfx.mojom.Rect active_match_rect,
+ int32 active_match_ordinal,
+ FindMatchUpdateType update_type);
+};
+
// This enum defines what actions the renderer should take next when
// the user has completed a find-in-page;
enum StopFindAction {
@@ -78,3 +91,28 @@ enum StopFindAction {
// The active match selection will be activated.
kStopFindActionActivateSelection
};
+
+// Type of updates for FindInPageClient::SetNumberOfMatches
+enum FindMatchUpdateType {
+ kFinalUpdate,
+ kMoreUpdatesComing
+};
+
+struct FindOptions {
+ // Whether to search forward or backward within the page.
+ bool forward;
+
+ // Whether search should be case-sensitive.
+ bool match_case;
+
+ // Whether this operation is the first request or a follow-up.
+ bool find_next;
+
+ // Force a re-search of the frame: typically used when forcing a re-search
+ // after the frame navigates.
+ bool force;
+
+ // Signifies whether we should force text scoping to happen immediately
+ // or not. Only used for testing purposes.
+ bool run_synchronously_for_testing;
+};
diff --git a/chromium/third_party/blink/public/mojom/indexeddb/OWNERS b/chromium/third_party/blink/public/mojom/indexeddb/OWNERS
new file mode 100644
index 00000000000..d43b54a7abf
--- /dev/null
+++ b/chromium/third_party/blink/public/mojom/indexeddb/OWNERS
@@ -0,0 +1,7 @@
+file://storage/browser/blob/OWNERS
+
+per-file *.mojom=set noparent
+per-file *.mojom=file://ipc/SECURITY_OWNERS
+
+# TEAM: storage-dev@chromium.org
+# COMPONENT: Blink>Storage>IndexedDB
diff --git a/chromium/third_party/blink/public/mojom/indexeddb/indexeddb.mojom b/chromium/third_party/blink/public/mojom/indexeddb/indexeddb.mojom
new file mode 100644
index 00000000000..8de66ed3dd2
--- /dev/null
+++ b/chromium/third_party/blink/public/mojom/indexeddb/indexeddb.mojom
@@ -0,0 +1,360 @@
+// 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 blink.mojom;
+
+import "mojo/public/mojom/base/file_path.mojom";
+import "mojo/public/mojom/base/string16.mojom";
+import "mojo/public/mojom/base/string16.mojom";
+import "mojo/public/mojom/base/time.mojom";
+import "third_party/blink/public/mojom/blob/blob.mojom";
+import "url/mojom/origin.mojom";
+
+// kIDBMaxMessageSize is 128MB, originally based on
+// IPC::Channel::kMaximumMessageSize. The "usable" size is this value less
+// the overhead size.
+const int32 kIDBMaxMessageSize = 134217728;
+
+// kIDBMaxMessageOverhead is the size we expect to be used for the rest of
+// the message we will send. The "usable" size is the max size less this value.
+const int32 kIDBMaxMessageOverhead = 1048576; // 1MB; arbitrarily chosen.
+
+enum IDBCursorDirection {
+ Next,
+ NextNoDuplicate,
+ Prev,
+ PrevNoDuplicate,
+};
+
+enum IDBDataLoss {
+ None,
+ Total,
+};
+
+// Represents key types that hold no data and so cannot be options in the
+// IDBKeyData union.
+// TODO(jsbell): These types should be cleaned up end-to-end, leaving only the
+// dataful options.
+enum IDBDatalessKeyType {
+ Invalid,
+ Null,
+};
+
+union IDBKeyData {
+ array<IDBKey> key_array;
+ array<uint8> binary;
+ mojo_base.mojom.String16 string;
+ double date;
+ double number;
+ IDBDatalessKeyType other;
+};
+
+// Defined as a structure so that it can by typemapped with StructTraits.
+struct IDBKey {
+ IDBKeyData data;
+};
+
+// Represents WebIDBKeyPathTypeString and WebIDBKeyPathTypeArray in a key path.
+union IDBKeyPathData {
+ mojo_base.mojom.String16 string;
+ array<mojo_base.mojom.String16> string_array;
+};
+
+struct IDBKeyPath {
+ // A null value here corresponds to WebIDBKeyPathTypeNull.
+ IDBKeyPathData? data;
+};
+
+struct IDBKeyRange {
+ IDBKey lower;
+ IDBKey upper;
+ bool lower_open;
+ bool upper_open;
+};
+
+enum IDBOperationType {
+ Add,
+ Put,
+ Delete,
+ Clear,
+};
+
+enum IDBPutMode {
+ AddOrUpdate,
+ AddOnly,
+ CursorUpdate,
+};
+
+enum IDBTaskType {
+ Normal,
+ Preemptive,
+};
+
+enum IDBTransactionMode {
+ ReadOnly,
+ ReadWrite,
+ VersionChange,
+};
+
+enum IDBStatus {
+ OK,
+ NotFound,
+ Corruption,
+ NotSupported,
+ InvalidArgument,
+ IOError,
+};
+
+struct IDBIndexMetadata {
+ int64 id;
+ mojo_base.mojom.String16 name;
+ IDBKeyPath key_path;
+ bool unique;
+ bool multi_entry;
+};
+
+struct IDBObjectStoreMetadata {
+ int64 id;
+ mojo_base.mojom.String16 name;
+ IDBKeyPath key_path;
+ bool auto_increment;
+ int64 max_index_id;
+ array<IDBIndexMetadata> indexes;
+};
+
+struct IDBDatabaseMetadata {
+ int64 id;
+ mojo_base.mojom.String16 name;
+ int64 version;
+ int64 max_object_store_id;
+ array<IDBObjectStoreMetadata> object_stores;
+};
+
+struct IDBIndexKeys {
+ int64 index_id;
+ array<IDBKey> index_keys;
+};
+
+struct IDBFileInfo {
+ mojo_base.mojom.FilePath path;
+ mojo_base.mojom.String16 name;
+ mojo_base.mojom.Time last_modified;
+};
+
+struct IDBBlobInfo {
+ blink.mojom.Blob blob;
+ string uuid;
+ mojo_base.mojom.String16 mime_type;
+ int64 size;
+ IDBFileInfo? file;
+};
+
+struct IDBValue {
+ string bits;
+ array<IDBBlobInfo> blob_or_file_info;
+};
+
+struct IDBReturnValue {
+ IDBValue value;
+ IDBKey primary_key;
+ IDBKeyPath key_path;
+};
+
+struct IDBObservation {
+ int64 object_store_id;
+ IDBOperationType type;
+ IDBKeyRange key_range;
+ IDBValue? value;
+};
+
+struct IDBObserverTransaction {
+ int64 id;
+ array<int64> scope;
+};
+
+struct IDBObserverChanges {
+ map<int32, array<int32>> observation_index_map;
+ map<int32, IDBObserverTransaction> transaction_map;
+ array<IDBObservation> observations;
+};
+
+// The IDBCallbacks interface is used to return results for individual requests.
+// Some requests may return multiple results before completion, such as
+// UpgradeNeeded before SuccessDatabase.
+//
+// TODO(https://crbug.com/627484): Many of these could be replaced with
+// replies associated with particular messages.
+interface IDBCallbacks {
+ Error(int32 code, mojo_base.mojom.String16 message);
+
+ // Factory::GetDatabaseNames
+ SuccessStringList(array<mojo_base.mojom.String16> value);
+
+ // Factory::Open / DeleteDatabase
+ Blocked(int64 existing_version);
+
+ // Factory::Open
+ UpgradeNeeded(associated IDBDatabase database, int64 old_version,
+ IDBDataLoss data_loss, string data_loss_message,
+ IDBDatabaseMetadata db_metadata);
+ SuccessDatabase(associated IDBDatabase? database,
+ IDBDatabaseMetadata metadata);
+
+ // Database::OpenCursor
+ SuccessCursor(associated IDBCursor cursor,
+ IDBKey key,
+ IDBKey primary_key,
+ IDBValue? value);
+
+ // Database::Get / Cursor::Advance
+ SuccessValue(IDBReturnValue? value);
+
+ // Cursor::Continue / Advance
+ SuccessCursorContinue(IDBKey key, IDBKey primary_key, IDBValue? value);
+
+ // Cursor::Prefetch
+ SuccessCursorPrefetch(array<IDBKey> keys,
+ array<IDBKey> primary_keys,
+ array<IDBValue> values);
+
+ // Database::GetAll
+ SuccessArray(array<IDBReturnValue> values);
+
+ // Database::Put / Cursor::Update
+ SuccessKey(IDBKey key);
+
+ // Database::Count / DeleteRange
+ // Factory::DeleteDatabase
+ SuccessInteger(int64 value);
+
+ // Cursor::Continue / Advance
+ Success();
+};
+
+// The IDBDatabaseCallbacks interface is used to notification of events out of
+// band to individual requests. A single instance is used for the lifetime of
+// a database connection.
+interface IDBDatabaseCallbacks {
+ ForcedClose();
+ VersionChange(int64 old_version, int64 new_version);
+ Abort(int64 transaction_id, int32 code,
+ mojo_base.mojom.String16 message);
+ Complete(int64 transaction_id);
+ Changes(IDBObserverChanges changes);
+};
+
+interface IDBCursor {
+ Advance(uint32 count, associated IDBCallbacks callbacks);
+ // Avoid calling the following function "Continue" since the Mojo
+ // Java bindings generate incorrect Java as a result. We've named
+ // the following funciton "CursorContinue" as a workaround.
+ CursorContinue(IDBKey key,
+ IDBKey primary_key,
+ associated IDBCallbacks callbacks);
+ Prefetch(int32 count, associated IDBCallbacks callbacks);
+ PrefetchReset(int32 used_prefetches, int32 unused_prefetches);
+};
+
+interface IDBDatabase {
+ CreateObjectStore(int64 transaction_id,
+ int64 object_store_id,
+ mojo_base.mojom.String16 name,
+ IDBKeyPath key_path,
+ bool auto_increment);
+ DeleteObjectStore(int64 transaction_id,
+ int64 object_store_id);
+ RenameObjectStore(int64 transaction_id,
+ int64 object_store_id,
+ mojo_base.mojom.String16 new_name);
+ CreateTransaction(int64 transaction_id,
+ array<int64> object_store_ids,
+ IDBTransactionMode mode);
+ Close();
+ VersionChangeIgnored();
+ AddObserver(int64 transaction_id,
+ int32 observer_id,
+ bool include_transaction,
+ bool no_records,
+ bool values,
+ uint16 operation_types);
+ RemoveObservers(array<int32> observers);
+ Get(int64 transaction_id,
+ int64 object_store_id,
+ int64 index_id,
+ IDBKeyRange key_range,
+ bool key_only,
+ associated IDBCallbacks callbacks);
+ GetAll(int64 transaction_id,
+ int64 object_store_id,
+ int64 index_id,
+ IDBKeyRange key_range,
+ bool key_only,
+ int64 max_count,
+ associated IDBCallbacks callbacks);
+ Put(int64 transaction_id,
+ int64 object_store_id,
+ IDBValue value,
+ IDBKey key,
+ IDBPutMode mode,
+ array<IDBIndexKeys> index_keys,
+ associated IDBCallbacks callbacks);
+ SetIndexKeys(int64 transaction_id,
+ int64 object_store_id,
+ IDBKey primary_key,
+ array<IDBIndexKeys> index_keys);
+ SetIndexesReady(int64 transaction_id,
+ int64 object_store_id,
+ array<int64> index_ids);
+ OpenCursor(int64 transaction_id,
+ int64 object_store_id,
+ int64 index_id,
+ IDBKeyRange key_range,
+ IDBCursorDirection direction,
+ bool key_only,
+ IDBTaskType task_type,
+ associated IDBCallbacks callbacks);
+ Count(int64 transaction_id,
+ int64 object_store_id,
+ int64 index_id,
+ IDBKeyRange key_range,
+ associated IDBCallbacks callbacks);
+ DeleteRange(int64 transaction_id,
+ int64 object_store_id,
+ IDBKeyRange key_range,
+ associated IDBCallbacks callbacks);
+ Clear(int64 transaction_id,
+ int64 object_store_id,
+ associated IDBCallbacks callbacks);
+ CreateIndex(int64 transaction_id,
+ int64 object_store_id,
+ int64 index_id,
+ mojo_base.mojom.String16 name,
+ IDBKeyPath key_path,
+ bool unique,
+ bool multi_entry);
+ DeleteIndex(int64 transaction_id,
+ int64 object_store_id,
+ int64 index_id);
+ RenameIndex(int64 transaction_id,
+ int64 object_store_id,
+ int64 index_id,
+ mojo_base.mojom.String16 new_name);
+ Abort(int64 transaction_id);
+ Commit(int64 transaction_id);
+};
+
+interface IDBFactory {
+ GetDatabaseNames(associated IDBCallbacks callbacks, url.mojom.Origin origin);
+ Open(associated IDBCallbacks callbacks,
+ associated IDBDatabaseCallbacks database_callbacks,
+ url.mojom.Origin origin,
+ mojo_base.mojom.String16 name,
+ int64 version,
+ int64 transaction_id);
+ DeleteDatabase(associated IDBCallbacks callbacks, url.mojom.Origin origin,
+ mojo_base.mojom.String16 name, bool force_close);
+ AbortTransactionsAndCompactDatabase(url.mojom.Origin origin) =>
+ (IDBStatus status);
+ AbortTransactionsForDatabase(url.mojom.Origin origin) => (IDBStatus status);
+};
diff --git a/chromium/third_party/blink/public/mojom/loader/navigation_predictor.mojom b/chromium/third_party/blink/public/mojom/loader/navigation_predictor.mojom
index 4f61f9ecfa8..30291176148 100644
--- a/chromium/third_party/blink/public/mojom/loader/navigation_predictor.mojom
+++ b/chromium/third_party/blink/public/mojom/loader/navigation_predictor.mojom
@@ -6,25 +6,49 @@ module blink.mojom;
import "url/mojom/url.mojom";
+// This mojom file is for user navigation prediction experiment, using anchor
+// element metrics gathered from the renderer process. See crbug.com/850624.
+
// Struct holding metrics of an anchor element extracted in the renderer
// process.
struct AnchorElementMetrics {
- // The ratio between the clickable region area of an anchor element, and the
- // viewport area. The value is capped at 1.
+ // The ratio between the absolute/visible clickable region area of an anchor
+ // element, and the viewport area. The values are capped at 1.
float ratio_area;
+ float ratio_visible_area;
+
+ // The distance between the top/center of the clickable region of an anchor
+ // element and the top edge of the visible region, divided by the viewport
+ // height.
+ float ratio_distance_top_to_visible_top;
+ float ratio_distance_center_to_visible_top;
// The distance between the top of the clickable region of an anchor element
// and the top edge of the root frame, divided by the viewport height.
float ratio_distance_root_top;
- // The distance between the center of the clickable region of an anchor
- // element and the top edge of the visible region, divided by the viewport
+ // The distance between the bottom of the clickable region of an anchor
+ // element and the bottom edge of the root frame, divided by the viewport
// height.
- float ratio_distance_center_to_visible_top;
+ float ratio_distance_root_bottom;
+
+ // Whether the anchor element is within an iframe.
+ bool is_in_iframe;
+
+ // Whether the anchor element contains an image element.
+ bool contains_image;
- // The host of the target link (href) specified by the anchor element.
- // Url sent from a renderer process is not trustable, however it is intended
- // here since it is only used for metrics calculation.
+ // Whether the link target has the same host as the root document.
+ bool is_same_host;
+
+ // Whether the target URL and the host URL only differ by one number,
+ // and the number in target URL equals the one in host URL plus one.
+ bool is_url_incremented_by_one;
+
+ // The source URL of the root document and the target URL (href) specified by
+ // the anchor element. URLs sent from a renderer process are not trusted,
+ // however it is intended here since it is only used for metrics calculation.
+ url.mojom.Url source_url;
url.mojom.Url target_url;
};
@@ -32,6 +56,11 @@ struct AnchorElementMetrics {
// the renderer process to the implementation of this interface living in the
// browser process.
interface AnchorElementMetricsHost {
- // This is called when an anchor element is clicked.
- UpdateAnchorElementMetrics(AnchorElementMetrics metrics);
+ // This is called when an anchor element is clicked. The renderer extracts and sends
+ // |metrics| of the clicked anchor element.
+ ReportAnchorElementMetricsOnClick(AnchorElementMetrics metrics);
+
+ // This is called after a web page is loaded. The renderer extracts and sends
+ // |metrics| of anchor elements in the first viewport.
+ ReportAnchorElementMetricsOnLoad(array<AnchorElementMetrics> metrics);
};
diff --git a/chromium/third_party/blink/public/mojom/manifest/manifest.mojom b/chromium/third_party/blink/public/mojom/manifest/manifest.mojom
index 3a79ab2d31b..74f2afb9bd7 100644
--- a/chromium/third_party/blink/public/mojom/manifest/manifest.mojom
+++ b/chromium/third_party/blink/public/mojom/manifest/manifest.mojom
@@ -97,11 +97,21 @@ struct ManifestRelatedApplication {
mojo_base.mojom.String16? id;
};
+
+// Structure representing how a Web Share target fills query parameters of an
+// incoming share. These fields contain the names of the query parameters that
+// will hold the value of the corresponding share data.
+struct ManifestShareTargetParams {
+ mojo_base.mojom.String16? title;
+ mojo_base.mojom.String16? text;
+ mojo_base.mojom.String16? url;
+};
+
// Structure representing how a Web Share target handles an incoming share.
struct ManifestShareTarget {
- // The URL template that contains placeholders to be replaced with shared
- // data. Empty if the parsing failed.
- url.mojom.Url? url_template;
+ // The URL that will be opened when the share target is invoked.
+ url.mojom.Url action;
+ ManifestShareTargetParams params;
};
// Debug information for a parsed manifest.
diff --git a/chromium/third_party/blink/public/mojom/message_port/message_port.mojom b/chromium/third_party/blink/public/mojom/message_port/message_port.mojom
index 69faa050a32..fad68a35c70 100644
--- a/chromium/third_party/blink/public/mojom/message_port/message_port.mojom
+++ b/chromium/third_party/blink/public/mojom/message_port/message_port.mojom
@@ -5,8 +5,10 @@
module blink.mojom;
import "mojo/public/mojom/base/big_buffer.mojom";
+import "mojo/public/mojom/base/unguessable_token.mojom";
import "third_party/blink/public/mojom/array_buffer/array_buffer_contents.mojom";
import "third_party/blink/public/mojom/blob/serialized_blob.mojom";
+import "third_party/blink/public/mojom/message_port/user_activation_snapshot.mojom";
import "skia/public/interfaces/bitmap.mojom";
// A MessagePort is represented as a raw mojo message pipe, as such no interface
@@ -28,6 +30,9 @@ struct CloneableMessage {
uint64 stack_trace_id;
int64 stack_trace_debugger_id_first;
int64 stack_trace_debugger_id_second;
+ // If not null, this message is locked to the given agent cluster ID.
+ // See https://html.spec.whatwg.org/multipage/webappapis.html#integration-with-the-javascript-agent-cluster-formalism
+ mojo_base.mojom.UnguessableToken? locked_agent_cluster_id;
};
// This struct combines the cloneable part of a message with the parts of the
@@ -45,4 +50,6 @@ struct TransferableMessage {
// Whether the recipient should have a user gesture when it processes this
// message.
bool has_user_gesture;
+ // The user activation state, null if the frame isn't providing it.
+ UserActivationSnapshot? user_activation;
};
diff --git a/chromium/third_party/blink/public/mojom/message_port/user_activation_snapshot.mojom b/chromium/third_party/blink/public/mojom/message_port/user_activation_snapshot.mojom
new file mode 100644
index 00000000000..38d1851a5f1
--- /dev/null
+++ b/chromium/third_party/blink/public/mojom/message_port/user_activation_snapshot.mojom
@@ -0,0 +1,12 @@
+// 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.
+
+module blink.mojom;
+
+// This struct represents the UserActivation state at the time which the message
+// was sent.
+struct UserActivationSnapshot {
+ bool has_been_active;
+ bool was_active;
+};
diff --git a/chromium/third_party/blink/public/mojom/payments/OWNERS b/chromium/third_party/blink/public/mojom/payments/OWNERS
new file mode 100644
index 00000000000..156471cda0d
--- /dev/null
+++ b/chromium/third_party/blink/public/mojom/payments/OWNERS
@@ -0,0 +1,10 @@
+# TEAM: paymentrequest@chromium.org
+# COMPONENT: Blink>Payments
+
+jinho.bang@samsung.com
+mathp@chromium.org
+mek@chromium.org
+rouslan@chromium.org
+
+per-file *.mojom=set noparent
+per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/chromium/third_party/blink/public/platform/modules/payments/payment_app.mojom b/chromium/third_party/blink/public/mojom/payments/payment_app.mojom
index 82829eadfb1..ab7bf310fc4 100644
--- a/chromium/third_party/blink/public/platform/modules/payments/payment_app.mojom
+++ b/chromium/third_party/blink/public/mojom/payments/payment_app.mojom
@@ -7,7 +7,7 @@ module payments.mojom;
import "components/payments/mojom/payment_request_data.mojom";
import "mojo/public/mojom/base/time.mojom";
import "third_party/blink/public/mojom/manifest/manifest.mojom";
-import "third_party/blink/public/platform/modules/payments/payment_request.mojom";
+import "third_party/blink/public/mojom/payments/payment_request.mojom";
import "url/mojom/url.mojom";
enum PaymentHandlerStatus {
diff --git a/chromium/third_party/blink/public/platform/modules/payments/payment_request.mojom b/chromium/third_party/blink/public/mojom/payments/payment_request.mojom
index 4ae9d5ad3dc..7c8cf67991b 100644
--- a/chromium/third_party/blink/public/platform/modules/payments/payment_request.mojom
+++ b/chromium/third_party/blink/public/mojom/payments/payment_request.mojom
@@ -30,7 +30,8 @@ struct PaymentResponse {
enum PaymentErrorReason {
UNKNOWN,
USER_CANCEL,
- NOT_SUPPORTED
+ NOT_SUPPORTED,
+ ALREADY_SHOWING
};
enum CanMakePaymentQueryResult {
@@ -205,6 +206,12 @@ interface PaymentRequest {
// Closes the payment user interface.
Complete(PaymentComplete result);
+ // Called when the merchant calls explicitly retry() method in JavaScript.
+ // The |errors| contains merchant-defined error message strings. They are
+ // used to indicate to the end-user that something is wrong with the data of
+ // the payment response.
+ Retry(PaymentValidationErrors errors);
+
// Queries whether the user has a form of payment on file.
CanMakePayment();
};
diff --git a/chromium/third_party/blink/public/mojom/portal/OWNERS b/chromium/third_party/blink/public/mojom/portal/OWNERS
new file mode 100644
index 00000000000..08850f42120
--- /dev/null
+++ b/chromium/third_party/blink/public/mojom/portal/OWNERS
@@ -0,0 +1,2 @@
+per-file *.mojom=set noparent
+per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/chromium/third_party/blink/public/mojom/portal/portal.mojom b/chromium/third_party/blink/public/mojom/portal/portal.mojom
new file mode 100644
index 00000000000..625131a8b66
--- /dev/null
+++ b/chromium/third_party/blink/public/mojom/portal/portal.mojom
@@ -0,0 +1,19 @@
+// 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.
+
+module blink.mojom;
+
+import "mojo/public/mojom/base/unguessable_token.mojom";
+import "url/mojom/url.mojom";
+
+// The Portal interface is used by the renderer to interact with the Portal.
+interface Portal {
+ // Initializes a portal. Must be called immediately after creating the
+ // interface. |token| is the unique token representing the portal. This token
+ // will be used by the content layer when referencing the portal.
+ Init() => (mojo_base.mojom.UnguessableToken token);
+
+ // Navigates the portal to |url|.
+ Navigate(url.mojom.Url url);
+};
diff --git a/chromium/third_party/blink/public/mojom/presentation/OWNERS b/chromium/third_party/blink/public/mojom/presentation/OWNERS
new file mode 100644
index 00000000000..8ea84b001b2
--- /dev/null
+++ b/chromium/third_party/blink/public/mojom/presentation/OWNERS
@@ -0,0 +1,5 @@
+# Include a reviewer from this file for semantic/non-trivial changes.
+file://third_party/blink/renderer/modules/presentation/OWNERS
+
+per-file *.mojom=set noparent
+per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/chromium/third_party/blink/public/platform/modules/presentation/presentation.mojom b/chromium/third_party/blink/public/mojom/presentation/presentation.mojom
index bde96e2c7db..ad1cdf19a1f 100644
--- a/chromium/third_party/blink/public/platform/modules/presentation/presentation.mojom
+++ b/chromium/third_party/blink/public/mojom/presentation/presentation.mojom
@@ -66,16 +66,28 @@ union PresentationConnectionMessage {
// as a intermediary to forward/receive the messages to/from a remote user
// agent.
interface PresentationConnection {
- // Called when a message is sent by the target connection.
- // TODO(crbug.com/749327): Remove the return value since it is no longer
- // used.
- OnMessage(PresentationConnectionMessage message) => (bool success);
+ // Called when a message is sent by the target connection.
+ // TODO(crbug.com/749327): Remove the return value since it is no longer
+ // used.
+ OnMessage(PresentationConnectionMessage message) => (bool success);
- // Called when target connection notifies connection state change.
- DidChangeState(PresentationConnectionState state);
+ // Called when target connection notifies connection state change.
+ DidChangeState(PresentationConnectionState state);
- // Called when target connection calls close().
- RequestClose();
+ // Called when target connection calls close().
+ RequestClose();
+};
+
+// Holds result from successfully starting or reconnecting to a presentation
+// with a pair of Mojo pipes to communicate with the presentation page.
+// |presentation_info| holds the URL and ID of the presentation.
+// |connection_ptr| holds the connection from the presentation to the
+// controlling frame. |connection_request| is fulfilled by the controlling
+// frame with a new connection to return to the presentation.
+struct PresentationConnectionResult {
+ PresentationInfo presentation_info;
+ PresentationConnection connection_ptr;
+ PresentationConnection& connection_request;
};
// Service provided by the browser process to implement parts of the
@@ -120,32 +132,20 @@ interface PresentationService {
StopListeningForScreenAvailability(url.mojom.Url availability_url);
// Called when start() is called by the frame. The result callback
- // will return a non-null and valid PresentationInfo if starting the
- // presentation succeeded, or null with a PresentationError if starting the
- // presentation failed.
+ // will return a non-null and valid PresentationConnectionResult if starting
+ // the presentation succeeded, or null with a PresentationError if starting
+ // the presentation failed.
StartPresentation(array<url.mojom.Url> presentation_urls)
- => (PresentationInfo? presentation_info, PresentationError? error);
+ => (PresentationConnectionResult? result,
+ PresentationError? error);
// Called when reconnect() is called by the frame. The result callback
// works the same as for the method above. reconnect() will create a new
// connection to a presentation with the matching URL and id.
- ReconnectPresentation(array<url.mojom.Url> presentation_urls, string presentation_id)
- => (PresentationInfo? presentation_info, PresentationError? error);
-
- // Notifies the service that a PresentationConnection has been started.
- // |controller_connection_ptr| is a handle to a PresentationConnection in
- // the page that started the presentation (aka the "controller"). This can be
- // used by PresentationService to send messages to the controller
- // PresentationConnection, for example.
- // |receiver_connection_request| will be bound to a PresentationConnection
- // implementation in order to receive messages and commands issued by the
- // controller PresentationConnection. The process in which the receiver
- // connection resides depends on whether the presentation is 1-UA or 2-UA:
- // see PresentationConnection interface for more info.
- SetPresentationConnection(
- PresentationInfo presentation_info,
- PresentationConnection controller_connection_ptr,
- PresentationConnection& receiver_connection_request);
+ ReconnectPresentation(array<url.mojom.Url> presentation_urls,
+ string presentation_id)
+ => (PresentationConnectionResult? result,
+ PresentationError? error);
// Called when close() is called by the frame.
// TODO(crbug.com/749327): Move this method into a separate interface that
@@ -172,7 +172,7 @@ interface PresentationController {
ScreenAvailability availability);
// See PresentationService::SetDefaultPresentationURL.
- OnDefaultPresentationStarted(PresentationInfo presentation_info);
+ OnDefaultPresentationStarted(PresentationConnectionResult result);
// Called when the state of PresentationConnection |connection| started on
// this frame has changed to |newState|.
@@ -188,9 +188,7 @@ interface PresentationController {
// Implemented by a render frame that uses Presentation Receiver API.
// Receives updates of receiver PresentationConnections becoming available as
-// a result of a controller initiating a 1-UA presentation and calling
-// PresentationService::SetPresentationConnection (i.e. the connection ptr /
-// requests are routed to the receiver page to be bound there).
+// a result of a controller initiating a 1-UA presentation.
interface PresentationReceiver {
// Notifies the PresentationReceiver that a receiver connection has become
// available.
@@ -198,6 +196,7 @@ interface PresentationReceiver {
// |controller_connection|: Ptr to the corresponding controller connection.
// |receiver_connection_request|: Interface request to be bound to a receiver
// connection implementation.
+ // TODO(btolsch): Convert this to take a PresentationConnectionResult.
OnReceiverConnectionAvailable(
PresentationInfo info,
PresentationConnection controller_connection,
diff --git a/chromium/third_party/blink/public/mojom/service_worker/service_worker_fetch_response_callback.mojom b/chromium/third_party/blink/public/mojom/service_worker/service_worker_fetch_response_callback.mojom
new file mode 100644
index 00000000000..9c184742379
--- /dev/null
+++ b/chromium/third_party/blink/public/mojom/service_worker/service_worker_fetch_response_callback.mojom
@@ -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.
+
+module blink.mojom;
+
+import "mojo/public/mojom/base/time.mojom";
+import "third_party/blink/public/mojom/blob/blob.mojom";
+import "third_party/blink/public/mojom/fetch/fetch_api_response.mojom";
+import "third_party/blink/public/mojom/service_worker/service_worker_stream_handle.mojom";
+
+// Callback interface which is passed to a controller service worker through
+// DispatchFetchEvent (either via ServiceWorker or via ControllerServiceWorker
+// interface).
+// The receiver service worker uses this interface to respond to a fetch event.
+interface ServiceWorkerFetchResponseCallback {
+ // Responds to the request with |response|.
+ OnResponse(FetchAPIResponse response,
+ mojo_base.mojom.Time dispatch_event_time);
+ // Responds to the request with |response|. |response.blob| should be empty
+ // since the body is provided as a stream.
+ OnResponseStream(FetchAPIResponse response,
+ ServiceWorkerStreamHandle body_as_stream,
+ mojo_base.mojom.Time dispatch_event_time);
+ // Provides no response to the request. The callee should fall back to the
+ // network.
+ OnFallback(mojo_base.mojom.Time dispatch_event_time);
+};
diff --git a/chromium/third_party/blink/public/mojom/usb/BUILD.gn b/chromium/third_party/blink/public/mojom/usb/BUILD.gn
new file mode 100644
index 00000000000..0e8769dfb28
--- /dev/null
+++ b/chromium/third_party/blink/public/mojom/usb/BUILD.gn
@@ -0,0 +1,36 @@
+# 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.
+
+import("//mojo/public/tools/bindings/mojom.gni")
+
+mojom("usb") {
+ # Ideally, this mojom file should be compiled directly in "mojom_platform"
+ # target in the parent directory. But as we need |scramble_message_ids| to
+ # be "false" for its mojom JS file will be used in external WPT layout tests.
+ # To limit this option's influence scope, we make it a separate target.
+ sources = [
+ "web_usb_service.mojom",
+ ]
+
+ deps = [
+ "//mojo/public/mojom/base",
+
+ # TODO(donna.wu@intel.com): Change the following line to //service/device/
+ # after it has been moved to //services/device.
+ "//device/usb/public/mojom",
+ ]
+
+ # USB Mojom interfaces are exposed publicly to layout tests which use
+ # prepackaged redistributable JS bindings. It is therefore not desirable to
+ # scramble these messages.
+ scramble_message_ids = false
+
+ export_class_attribute = "BLINK_COMMON_EXPORT"
+ export_define = "BLINK_COMMON_IMPLEMENTATION=1"
+ export_header = "third_party/blink/common/common_export.h"
+
+ export_class_attribute_blink = "PLATFORM_EXPORT"
+ export_define_blink = "BLINK_PLATFORM_IMPLEMENTATION=1"
+ export_header_blink = "third_party/blink/renderer/platform/platform_export.h"
+}
diff --git a/chromium/third_party/blink/public/mojom/usb/OWNERS b/chromium/third_party/blink/public/mojom/usb/OWNERS
new file mode 100644
index 00000000000..08850f42120
--- /dev/null
+++ b/chromium/third_party/blink/public/mojom/usb/OWNERS
@@ -0,0 +1,2 @@
+per-file *.mojom=set noparent
+per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/chromium/third_party/blink/public/mojom/usb/web_usb_service.mojom b/chromium/third_party/blink/public/mojom/usb/web_usb_service.mojom
new file mode 100644
index 00000000000..0c9fdd3e922
--- /dev/null
+++ b/chromium/third_party/blink/public/mojom/usb/web_usb_service.mojom
@@ -0,0 +1,32 @@
+// 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.
+
+module blink.mojom;
+
+import "device/usb/public/mojom/device.mojom";
+import "device/usb/public/mojom/device_manager.mojom";
+
+// This is a parallel interface with UsbDeviceManager aimed to handle extra work
+// such as permission checking, chooser showing, etc. in browser.
+// WebUsbServiceImpl in //chrome/browser/usb will implement this interface, and
+// it will be used by webusb module in //third_party/blink/renderer/modules/.
+interface WebUsbService {
+ // Retrieves information about all devices available.
+ GetDevices() => (array<device.mojom.UsbDeviceInfo> results);
+
+ // Requests a device by guid.
+ GetDevice(string guid, device.mojom.UsbDevice& device_requestd);
+
+ // Get permission from user to use a device.
+ //
+ // |device_filters| filters the available devices and the filtered
+ // devices will be listed for user to grant permission.
+ //
+ // |result| is the device that user grants permission to use.
+ GetPermission(array<device.mojom.UsbDeviceFilter> device_filters)
+ => (device.mojom.UsbDeviceInfo? result);
+
+ // Sets the client for this WebUsbService.
+ SetClient(device.mojom.UsbDeviceManagerClient client);
+};
diff --git a/chromium/third_party/blink/public/mojom/webaudio/OWNERS b/chromium/third_party/blink/public/mojom/webaudio/OWNERS
new file mode 100644
index 00000000000..c7c1217b39e
--- /dev/null
+++ b/chromium/third_party/blink/public/mojom/webaudio/OWNERS
@@ -0,0 +1,6 @@
+file://third_party/blink/renderer/modules/webaudio/OWNERS
+
+# COMPONENT: Blink>WebAudio
+
+per-file *.mojom=set noparent
+per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/chromium/third_party/blink/public/mojom/webaudio/audio_context_manager.mojom b/chromium/third_party/blink/public/mojom/webaudio/audio_context_manager.mojom
new file mode 100644
index 00000000000..5ea8602a958
--- /dev/null
+++ b/chromium/third_party/blink/public/mojom/webaudio/audio_context_manager.mojom
@@ -0,0 +1,19 @@
+// 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.
+
+module blink.mojom;
+
+// Interface for allowing a real-time AudioContext to send
+// notifications to browser that the AudioContext has started (or
+// stopped) playing audible sounds. Audibility is computed by the
+// AudioContext.
+interface AudioContextManager {
+ // AudioContext started producing audible sound. The id is the ID
+ // of the AudioContext.
+ AudioContextAudiblePlaybackStarted(int32 id);
+
+ // AudioContext stopped producing audible sound. The id is the ID
+ // of the AudioContext.
+ AudioContextAudiblePlaybackStopped(int32 id);
+};
diff --git a/chromium/third_party/blink/public/platform/DEPS b/chromium/third_party/blink/public/platform/DEPS
index 12f2c70e546..efa764a406e 100644
--- a/chromium/third_party/blink/public/platform/DEPS
+++ b/chromium/third_party/blink/public/platform/DEPS
@@ -3,6 +3,7 @@ include_rules = [
"+base/callback_forward.h",
"+base/containers/flat_set.h",
"+base/containers/span.h",
+ "+base/files/file.h",
"+base/location.h",
"+base/logging.h",
"+base/memory/ref_counted.h",
@@ -15,6 +16,7 @@ include_rules = [
"+base/threading/thread.h",
"+base/time",
"+base/trace_event",
+ "+build/build_config.h",
"+cc",
"+components/viz/common",
"+media/base/video_rotation.h",
diff --git a/chromium/third_party/blink/public/platform/OWNERS b/chromium/third_party/blink/public/platform/OWNERS
index 1c3eff26416..65e1bbf93b9 100644
--- a/chromium/third_party/blink/public/platform/OWNERS
+++ b/chromium/third_party/blink/public/platform/OWNERS
@@ -13,4 +13,4 @@ per-file *.typemap=set noparent
per-file *.typemap=file://ipc/SECURITY_OWNERS
per-file web_rtc_*=hbos@chromium.org
-per-file web_media_player_*=mlamouri@chromium.org
+per-file web_media_player*=mlamouri@chromium.org
diff --git a/chromium/third_party/blink/public/platform/autoplay.mojom b/chromium/third_party/blink/public/platform/autoplay.mojom
index 6dfc749283c..2198b49c2f5 100644
--- a/chromium/third_party/blink/public/platform/autoplay.mojom
+++ b/chromium/third_party/blink/public/platform/autoplay.mojom
@@ -14,6 +14,10 @@ const int32 kAutoplayFlagHighMediaEngagement = 0x00001;
// This flag indicates a page should always be allowed to autoplay.
const int32 kAutoplayFlagForceAllow = 0x00002;
+// This flag indicates a page should be allowed to autoplay because the
+// user has added an exception for it.
+const int32 kAutoplayFlagUserException = 0x00004;
+
interface AutoplayConfigurationClient {
// The browser tells the renderer that an origin has specific autoplay flags.
AddAutoplayFlags(url.mojom.Origin origin, int32 flags);
diff --git a/chromium/third_party/blink/public/platform/code_cache_loader.h b/chromium/third_party/blink/public/platform/code_cache_loader.h
new file mode 100644
index 00000000000..2d5741ea4a6
--- /dev/null
+++ b/chromium/third_party/blink/public/platform/code_cache_loader.h
@@ -0,0 +1,33 @@
+// 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_PUBLIC_PLATFORM_CODE_CACHE_LOADER_H_
+#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_CODE_CACHE_LOADER_H_
+
+#include "base/callback.h"
+#include "url/gurl.h"
+
+namespace blink {
+
+// CodeCacheLoader is an abstract class that provides the interface
+// for fetching the data from code cache.
+class CodeCacheLoader {
+ public:
+ using FetchCodeCacheCallback =
+ base::OnceCallback<void(const base::Time&, const std::vector<uint8_t>&)>;
+ virtual ~CodeCacheLoader() = default;
+
+ // Fetched code cache corresponding to |url| synchronously and returns
+ // response in |response_time_out| and |data_out|. |response_time_out| and
+ // |data_out| cannot be nullptrs.
+ virtual void FetchFromCodeCacheSynchronously(
+ const GURL& url,
+ base::Time* response_time_out,
+ std::vector<uint8_t>* data_out) = 0;
+ virtual void FetchFromCodeCache(const GURL& url, FetchCodeCacheCallback) = 0;
+};
+
+} // namespace blink
+
+#endif
diff --git a/chromium/third_party/blink/public/platform/mac/web_scrollbar_theme.h b/chromium/third_party/blink/public/platform/mac/web_scrollbar_theme.h
index efdfeab9f00..639e9608ca6 100644
--- a/chromium/third_party/blink/public/platform/mac/web_scrollbar_theme.h
+++ b/chromium/third_party/blink/public/platform/mac/web_scrollbar_theme.h
@@ -36,6 +36,10 @@
namespace blink {
+#if INSIDE_BLINK
+class WebScrollbarThemeClient;
+#endif
+
// This enum must match NSScrollerStyle in the 10.7 SDK.
enum ScrollerStyle { kScrollerStyleLegacy = 0, kScrollerStyleOverlay = 1 };
@@ -49,16 +53,25 @@ class WebScrollbarTheme {
// |preferredScrollerStyle| is the current value of +[NSScroller
// preferredScrollerStyle].
// |redraw| is true if the update requires a redraw to include the change.
- // |WebScrollbarButtonsPlacement| is the current value of
- // AppleScrollBarVariant. |jump_on_track_click| is the current value of
- // AppleScrollerPagingBehavior.
+ // |jump_on_track_click| is the current value of AppleScrollerPagingBehavior.
BLINK_EXPORT static void UpdateScrollbarsWithNSDefaults(
float initial_button_delay,
float autoscroll_button_delay,
ScrollerStyle preferred_scroller_style,
bool redraw,
- WebScrollbarButtonsPlacement,
bool jump_on_track_click);
+
+// Registered clients will receive a callback whenever
+// UpdateScrollbarsWithNSDefaults is called.
+#if INSIDE_BLINK
+ static float InitialButtonDelay();
+ static float AutoscrollButtonDelay();
+ static ScrollerStyle PreferredScrollerStyle();
+ static bool JumpOnTrackClick();
+
+ static void RegisterClient(WebScrollbarThemeClient& client);
+ static void UnregisterClient(WebScrollbarThemeClient& client);
+#endif
};
} // namespace blink
diff --git a/chromium/third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom b/chromium/third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom
index af3a52398a3..ca194540297 100644
--- a/chromium/third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom
+++ b/chromium/third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom
@@ -5,7 +5,9 @@
module blink.mojom;
import "skia/public/interfaces/bitmap.mojom";
+import "third_party/blink/public/platform/modules/cache_storage/cache_storage.mojom";
import "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom";
+import "third_party/blink/public/mojom/fetch/fetch_api_response.mojom";
import "third_party/blink/public/mojom/manifest/manifest.mojom";
import "ui/gfx/geometry/mojo/geometry.mojom";
@@ -15,7 +17,45 @@ enum BackgroundFetchError {
INVALID_ARGUMENT,
INVALID_ID,
STORAGE_ERROR,
- SERVICE_WORKER_UNAVAILABLE
+ SERVICE_WORKER_UNAVAILABLE,
+ QUOTA_EXCEEDED,
+ PERMISSION_DENIED
+};
+
+// Struct representing completed Background Fetch requests, along with their
+// responses.
+struct BackgroundFetchSettledFetch {
+ FetchAPIRequest request;
+ FetchAPIResponse? response;
+};
+
+enum BackgroundFetchState {
+ PENDING,
+ FAILURE,
+ SUCCESS
+};
+
+// https://wicg.github.io/background-fetch/#enumdef-backgroundfetchfailurereason
+enum BackgroundFetchFailureReason {
+ // "":
+ NONE = 0,
+
+ // "aborted":
+ CANCELLED_FROM_UI = 1,
+ CANCELLED_BY_DEVELOPER = 2,
+
+ // "bad-status":
+ BAD_STATUS = 3,
+
+ // "fetch-error":
+ FETCH_ERROR = 4,
+ SERVICE_WORKER_UNAVAILABLE = 5,
+
+ // "quota-exceeded":
+ QUOTA_EXCEEDED = 6,
+
+ // "total-download-exceeded":
+ TOTAL_DOWNLOAD_SIZE_EXCEEDED = 7,
};
// Represents the optional options a developer can provide when starting a new
@@ -43,6 +83,8 @@ struct BackgroundFetchRegistration {
uint64 uploaded;
uint64 download_total;
uint64 downloaded;
+ BackgroundFetchState state;
+ BackgroundFetchFailureReason failure_reason;
};
interface BackgroundFetchRegistrationObserver {
@@ -73,7 +115,8 @@ interface BackgroundFetchService {
UpdateUI(int64 service_worker_registration_id,
string developer_id,
string unique_id,
- string title)
+ string? title,
+ skia.mojom.Bitmap? icon)
=> (BackgroundFetchError error);
// Aborts the Background Fetch registration identified by |unique_id| and
@@ -100,6 +143,18 @@ interface BackgroundFetchService {
GetIconDisplaySize()
=> (gfx.mojom.Size icon_size_pixels);
+ // Gets matching {request, response} pairs for the completed fetches associated
+ // with |service_worker_registration_id|, |developer_id|, and |unique_id|.
+ // TODO(crbug.com/866874): Create a mojo interface for
+ // BackgroundFetchRegistrationId, so we can avoid having to pass the first
+ // three arguments in multiple methods.
+ MatchRequests(int64 service_worker_registration_id,
+ string developer_id,
+ string unique_id,
+ FetchAPIRequest? request_to_match,
+ QueryParams? cache_query_params,
+ bool match_all) => (array<BackgroundFetchSettledFetch> fetches);
+
// Registers the |observer| to receive events for the given registration
// that is identified by the |unique_id|.
AddRegistrationObserver(string unique_id,
diff --git a/chromium/third_party/blink/public/platform/modules/background_fetch/web_background_fetch_registration.h b/chromium/third_party/blink/public/platform/modules/background_fetch/web_background_fetch_registration.h
new file mode 100644
index 00000000000..f0c3bc32abe
--- /dev/null
+++ b/chromium/third_party/blink/public/platform/modules/background_fetch/web_background_fetch_registration.h
@@ -0,0 +1,50 @@
+// 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_PUBLIC_PLATFORM_MODULES_BACKGROUND_FETCH_WEB_BACKGROUND_FETCH_REGISTRATION_H_
+#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_BACKGROUND_FETCH_WEB_BACKGROUND_FETCH_REGISTRATION_H_
+
+#include "third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom-shared.h"
+#include "third_party/blink/public/platform/web_common.h"
+#include "third_party/blink/public/platform/web_string.h"
+
+namespace blink {
+
+// Represents a BackgroundFetchRegistration object, added mainly for layering.
+// Analogous to the following structure in the spec:
+// https://wicg.github.io/background-fetch/#background-fetch-registration
+struct WebBackgroundFetchRegistration {
+ WebBackgroundFetchRegistration(
+ const WebString& developer_id,
+ const WebString& unique_id,
+ uint64_t upload_total,
+ uint64_t uploaded,
+ uint64_t download_total,
+ uint64_t downloaded,
+ mojom::BackgroundFetchState state,
+ mojom::BackgroundFetchFailureReason failure_reason)
+ : developer_id(developer_id),
+ unique_id(unique_id),
+ upload_total(upload_total),
+ uploaded(uploaded),
+ download_total(download_total),
+ downloaded(downloaded),
+ state(state),
+ failure_reason(failure_reason) {}
+
+ ~WebBackgroundFetchRegistration() = default;
+
+ WebString developer_id;
+ WebString unique_id;
+ uint64_t upload_total;
+ uint64_t uploaded;
+ uint64_t download_total;
+ uint64_t downloaded;
+ mojom::BackgroundFetchState state;
+ mojom::BackgroundFetchFailureReason failure_reason;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_BACKGROUND_FETCH_WEB_BACKGROUND_FETCH_REGISTRATION_H_
diff --git a/chromium/third_party/blink/public/platform/modules/background_fetch/web_background_fetch_settled_fetch.h b/chromium/third_party/blink/public/platform/modules/background_fetch/web_background_fetch_settled_fetch.h
deleted file mode 100644
index b48a74ace59..00000000000
--- a/chromium/third_party/blink/public/platform/modules/background_fetch/web_background_fetch_settled_fetch.h
+++ /dev/null
@@ -1,27 +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_PUBLIC_PLATFORM_MODULES_BACKGROUND_FETCH_WEB_BACKGROUND_FETCH_SETTLED_FETCH_H_
-#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_BACKGROUND_FETCH_WEB_BACKGROUND_FETCH_SETTLED_FETCH_H_
-
-#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_request.h"
-#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_response.h"
-#include "third_party/blink/public/platform/web_common.h"
-
-namespace blink {
-
-// Represents a request/response pair for a settled Background Fetch.
-// Analogous to the following structure in the spec:
-// http://wicg.github.io/background-fetch/#backgroundfetchsettledfetch
-struct WebBackgroundFetchSettledFetch {
- WebBackgroundFetchSettledFetch() = default;
- ~WebBackgroundFetchSettledFetch() = default;
-
- WebServiceWorkerRequest request;
- WebServiceWorkerResponse response;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_BACKGROUND_FETCH_WEB_BACKGROUND_FETCH_SETTLED_FETCH_H_
diff --git a/chromium/third_party/blink/public/platform/modules/budget_service/OWNERS b/chromium/third_party/blink/public/platform/modules/budget_service/OWNERS
deleted file mode 100644
index 461dee04245..00000000000
--- a/chromium/third_party/blink/public/platform/modules/budget_service/OWNERS
+++ /dev/null
@@ -1,7 +0,0 @@
-peter@chromium.org
-
-per-file *.mojom=set noparent
-per-file *.mojom=file://ipc/SECURITY_OWNERS
-
-# TEAM: platform-capabilities@chromium.org
-# COMPONENT: Blink>PushAPI
diff --git a/chromium/third_party/blink/public/platform/modules/budget_service/budget_service.mojom b/chromium/third_party/blink/public/platform/modules/budget_service/budget_service.mojom
deleted file mode 100644
index 8633f1ed71c..00000000000
--- a/chromium/third_party/blink/public/platform/modules/budget_service/budget_service.mojom
+++ /dev/null
@@ -1,39 +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.
-
-module blink.mojom;
-
-enum BudgetOperationType {
- SILENT_PUSH,
- INVALID_OPERATION
-};
-
-enum BudgetServiceErrorType {
- NONE,
- // Returned if there is an issue reading or writing the budget database.
- DATABASE_ERROR,
- // Returned if functionality is called which is not yet implemented.
- NOT_SUPPORTED
-};
-
-// Structure representing the budget at points in time in the future.
-struct BudgetState {
- // Amount of budget that will be available. This should be the lower bound of
- // the budget between this time and the previous time.
- double budget_at;
-
- // Time at which the budget is available, in milliseconds since 00:00:00 UTC
- // on 1 January 1970, at which the budget_at will be valid.
- double time;
-};
-
-// Service through which Blink can query for the cost of particular actions and
-// for the budget available for an origin.
-interface BudgetService {
- GetCost(BudgetOperationType operation) => (double cost);
- GetBudget() => (BudgetServiceErrorType error_type, array<BudgetState> budget);
- Reserve(BudgetOperationType operation)
- => (BudgetServiceErrorType error_type, bool success);
-};
-
diff --git a/chromium/third_party/blink/public/platform/modules/cache_storage/cache_storage.mojom b/chromium/third_party/blink/public/platform/modules/cache_storage/cache_storage.mojom
index 0cfadd652d2..1b4399809be 100644
--- a/chromium/third_party/blink/public/platform/modules/cache_storage/cache_storage.mojom
+++ b/chromium/third_party/blink/public/platform/modules/cache_storage/cache_storage.mojom
@@ -4,8 +4,8 @@
module blink.mojom;
+import "third_party/blink/public/mojom/fetch/fetch_api_response.mojom";
import "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom";
-import "third_party/blink/public/platform/modules/fetch/fetch_api_response.mojom";
import "mojo/public/mojom/base/string16.mojom";
// This enum is used in histograms, so do not change the ordering and always
@@ -21,9 +21,20 @@ enum CacheStorageError {
kErrorQueryTooLarge = 6,
// TODO(cmumford): kErrorNotImplemented is deprecated. Remove use in code.
kErrorNotImplemented = 7,
+ kErrorDuplicateOperation = 8,
// Add new values here.
};
+// A result value that may include an optional message string. The renderer
+// may prepend the API method name that produced this result. If the main
+// result value is kSuccess the message may be reported to the console as
+// a warning. If the result value is a failure code then the message string
+// will be set as the DOMException's message directly.
+struct CacheStorageVerboseError {
+ CacheStorageError value;
+ string? message;
+};
+
// Controls how requests are matched in the Cache API.
struct QueryParams {
bool ignore_search;
@@ -98,7 +109,8 @@ interface CacheStorageCache {
=> (CacheKeysResult result);
// Perform a batch of operations, used for PUT and DELETE operations.
- Batch(array<BatchOperation> batch_operations) => (CacheStorageError result);
+ Batch(array<BatchOperation> batch_operations, bool fail_on_duplicates)
+ => (CacheStorageVerboseError result);
};
// Handles global CacheStorage methods, directly relates to methods available on
diff --git a/chromium/third_party/blink/public/platform/modules/device_orientation/OWNERS b/chromium/third_party/blink/public/platform/modules/device_orientation/OWNERS
deleted file mode 100644
index 7b1e4f284f7..00000000000
--- a/chromium/third_party/blink/public/platform/modules/device_orientation/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-timvolodine@chromium.org
-
-# COMPONENT: Blink>Sensor>DeviceOrientation
-# TEAM: device-dev@chromium.org
diff --git a/chromium/third_party/blink/public/platform/modules/device_orientation/web_device_motion_listener.h b/chromium/third_party/blink/public/platform/modules/device_orientation/web_device_motion_listener.h
deleted file mode 100644
index ba9efd895b1..00000000000
--- a/chromium/third_party/blink/public/platform/modules/device_orientation/web_device_motion_listener.h
+++ /dev/null
@@ -1,50 +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.
- */
-
-#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_DEVICE_ORIENTATION_WEB_DEVICE_MOTION_LISTENER_H_
-#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_DEVICE_ORIENTATION_WEB_DEVICE_MOTION_LISTENER_H_
-
-#include "third_party/blink/public/platform/web_platform_event_listener.h"
-
-namespace blink {
-
-class DeviceMotionData;
-
-class WebDeviceMotionListener : public WebPlatformEventListener {
- public:
- // This method is called every time new device motion data is available.
- virtual void DidChangeDeviceMotion(DeviceMotionData*) = 0;
-
- ~WebDeviceMotionListener() override = default;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_DEVICE_ORIENTATION_WEB_DEVICE_MOTION_LISTENER_H_
diff --git a/chromium/third_party/blink/public/platform/modules/device_orientation/web_device_orientation_listener.h b/chromium/third_party/blink/public/platform/modules/device_orientation/web_device_orientation_listener.h
deleted file mode 100644
index 99800cbe0ba..00000000000
--- a/chromium/third_party/blink/public/platform/modules/device_orientation/web_device_orientation_listener.h
+++ /dev/null
@@ -1,52 +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.
- */
-
-#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_DEVICE_ORIENTATION_WEB_DEVICE_ORIENTATION_LISTENER_H_
-#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_DEVICE_ORIENTATION_WEB_DEVICE_ORIENTATION_LISTENER_H_
-
-#include "third_party/blink/public/platform/web_platform_event_listener.h"
-
-namespace device {
-class OrientationData;
-}
-
-namespace blink {
-
-class WebDeviceOrientationListener : public WebPlatformEventListener {
- public:
- // This method is called every time new device orientation data is available.
- virtual void DidChangeDeviceOrientation(const device::OrientationData&) = 0;
-
- ~WebDeviceOrientationListener() override = default;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_DEVICE_ORIENTATION_WEB_DEVICE_ORIENTATION_LISTENER_H_
diff --git a/chromium/third_party/blink/public/platform/modules/font_unique_name_lookup/OWNERS b/chromium/third_party/blink/public/platform/modules/font_unique_name_lookup/OWNERS
new file mode 100644
index 00000000000..78efc30ac24
--- /dev/null
+++ b/chromium/third_party/blink/public/platform/modules/font_unique_name_lookup/OWNERS
@@ -0,0 +1,4 @@
+drott@chromium.org
+
+per-file *.mojom=set noparent
+per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/chromium/third_party/blink/public/platform/modules/font_unique_name_lookup/font_unique_name_lookup.mojom b/chromium/third_party/blink/public/platform/modules/font_unique_name_lookup/font_unique_name_lookup.mojom
new file mode 100644
index 00000000000..e26d2c30a7c
--- /dev/null
+++ b/chromium/third_party/blink/public/platform/modules/font_unique_name_lookup/font_unique_name_lookup.mojom
@@ -0,0 +1,17 @@
+// 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.
+
+module blink.mojom;
+
+import "mojo/public/mojom/base/file_path.mojom";
+import "mojo/public/mojom/base/shared_memory.mojom";
+
+interface FontUniqueNameLookup {
+
+ // Make the protobuf structured lookup list of
+ // (full_font_name|postscript_name) => (font_file + ttc_index) available to
+ // the renderer process.
+ [Sync] GetUniqueNameLookupTable() =>
+ (mojo_base.mojom.ReadOnlySharedMemoryRegion font_lookup_table);
+};
diff --git a/chromium/third_party/blink/public/platform/modules/indexeddb/web_idb_cursor.h b/chromium/third_party/blink/public/platform/modules/indexeddb/web_idb_cursor.h
index b436b9fa0e0..248df14cdd0 100644
--- a/chromium/third_party/blink/public/platform/modules/indexeddb/web_idb_cursor.h
+++ b/chromium/third_party/blink/public/platform/modules/indexeddb/web_idb_cursor.h
@@ -26,9 +26,9 @@
#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_INDEXEDDB_WEB_IDB_CURSOR_H_
#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_INDEXEDDB_WEB_IDB_CURSOR_H_
+#include "third_party/blink/public/common/indexeddb/web_idb_types.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_callbacks.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_key.h"
-#include "third_party/blink/public/platform/modules/indexeddb/web_idb_types.h"
#include "third_party/blink/public/platform/web_common.h"
#include "third_party/blink/public/platform/web_string.h"
@@ -49,9 +49,9 @@ class WebIDBCursor {
//
// The keys pointed to by WebIDBKeyView are only guaranteed to be alive for
// the duration of the call.
- virtual void Continue(WebIDBKeyView,
- WebIDBKeyView primary_key,
- WebIDBCallbacks*) = 0;
+ virtual void CursorContinue(WebIDBKeyView,
+ WebIDBKeyView primary_key,
+ WebIDBCallbacks*) = 0;
// Called after a cursor request's success handler is executed.
//
diff --git a/chromium/third_party/blink/public/platform/modules/indexeddb/web_idb_database.h b/chromium/third_party/blink/public/platform/modules/indexeddb/web_idb_database.h
index c6529503ee2..0db2c387502 100644
--- a/chromium/third_party/blink/public/platform/modules/indexeddb/web_idb_database.h
+++ b/chromium/third_party/blink/public/platform/modules/indexeddb/web_idb_database.h
@@ -26,9 +26,9 @@
#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_INDEXEDDB_WEB_IDB_DATABASE_H_
#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_INDEXEDDB_WEB_IDB_DATABASE_H_
+#include "third_party/blink/public/common/indexeddb/web_idb_types.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_cursor.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_metadata.h"
-#include "third_party/blink/public/platform/modules/indexeddb/web_idb_types.h"
#include "third_party/blink/public/platform/web_blob_info.h"
#include "third_party/blink/public/platform/web_common.h"
diff --git a/chromium/third_party/blink/public/platform/modules/indexeddb/web_idb_factory.h b/chromium/third_party/blink/public/platform/modules/indexeddb/web_idb_factory.h
index f8788ce061d..5739a5ef119 100644
--- a/chromium/third_party/blink/public/platform/modules/indexeddb/web_idb_factory.h
+++ b/chromium/third_party/blink/public/platform/modules/indexeddb/web_idb_factory.h
@@ -29,6 +29,7 @@
#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_INDEXEDDB_WEB_IDB_FACTORY_H_
#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_INDEXEDDB_WEB_IDB_FACTORY_H_
+#include "base/single_thread_task_runner.h"
#include "third_party/blink/public/platform/web_common.h"
namespace base {
diff --git a/chromium/third_party/blink/public/platform/modules/indexeddb/web_idb_key.h b/chromium/third_party/blink/public/platform/modules/indexeddb/web_idb_key.h
index 22c204aedaf..dafbc10912c 100644
--- a/chromium/third_party/blink/public/platform/modules/indexeddb/web_idb_key.h
+++ b/chromium/third_party/blink/public/platform/modules/indexeddb/web_idb_key.h
@@ -28,7 +28,7 @@
#include <memory>
-#include "third_party/blink/public/platform/modules/indexeddb/web_idb_types.h"
+#include "third_party/blink/public/common/indexeddb/web_idb_types.h"
#include "third_party/blink/public/platform/web_common.h"
#include "third_party/blink/public/platform/web_data.h"
#include "third_party/blink/public/platform/web_private_ptr.h"
diff --git a/chromium/third_party/blink/public/platform/modules/indexeddb/web_idb_key_path.h b/chromium/third_party/blink/public/platform/modules/indexeddb/web_idb_key_path.h
index c1e3d5c9827..3ceceab17f1 100644
--- a/chromium/third_party/blink/public/platform/modules/indexeddb/web_idb_key_path.h
+++ b/chromium/third_party/blink/public/platform/modules/indexeddb/web_idb_key_path.h
@@ -26,7 +26,7 @@
#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_INDEXEDDB_WEB_IDB_KEY_PATH_H_
#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_INDEXEDDB_WEB_IDB_KEY_PATH_H_
-#include "third_party/blink/public/platform/modules/indexeddb/web_idb_types.h"
+#include "third_party/blink/public/common/indexeddb/web_idb_types.h"
#include "third_party/blink/public/platform/web_common.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_vector.h"
diff --git a/chromium/third_party/blink/public/platform/modules/indexeddb/web_idb_observation.h b/chromium/third_party/blink/public/platform/modules/indexeddb/web_idb_observation.h
index 6b11b5cd3a9..dd0a1903630 100644
--- a/chromium/third_party/blink/public/platform/modules/indexeddb/web_idb_observation.h
+++ b/chromium/third_party/blink/public/platform/modules/indexeddb/web_idb_observation.h
@@ -5,8 +5,8 @@
#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_INDEXEDDB_WEB_IDB_OBSERVATION_H_
#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_INDEXEDDB_WEB_IDB_OBSERVATION_H_
+#include "third_party/blink/public/common/indexeddb/web_idb_types.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_key_range.h"
-#include "third_party/blink/public/platform/modules/indexeddb/web_idb_types.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_value.h"
namespace blink {
diff --git a/chromium/third_party/blink/public/platform/modules/locks/lock_manager.mojom b/chromium/third_party/blink/public/platform/modules/locks/lock_manager.mojom
index e0eae77ed52..fa4fa2c9a49 100644
--- a/chromium/third_party/blink/public/platform/modules/locks/lock_manager.mojom
+++ b/chromium/third_party/blink/public/platform/modules/locks/lock_manager.mojom
@@ -46,7 +46,7 @@ struct LockInfo {
// availablility and options. Once granted, the lock will be held until
// explicitly released or the holding context is terminated.
//
-// Proposal: https://github.com/inexorabletash/web-locks
+// Proposal: https://wicg.github.io/web-locks
interface LockManager {
// PREEMPT corresponds to the |steal| option in the API; if used then
diff --git a/chromium/third_party/blink/public/platform/modules/notifications/notification.mojom b/chromium/third_party/blink/public/platform/modules/notifications/notification.mojom
index d524a685473..1fee2173531 100644
--- a/chromium/third_party/blink/public/platform/modules/notifications/notification.mojom
+++ b/chromium/third_party/blink/public/platform/modules/notifications/notification.mojom
@@ -49,7 +49,7 @@ struct NotificationData {
mojo_base.mojom.String16 title;
// Hint to determine the directionality of the displayed notification.
- NotificationDirection direction;
+ NotificationDirection direction = LEFT_TO_RIGHT;
// BCP 47 language tag describing the notification's contents. Optional.
string? lang;
@@ -82,24 +82,24 @@ struct NotificationData {
// The time at which the event the notification represents took place,
// in milliseconds since the Unix epoch.
// TODO(https://crbug.com/797306): Use base::TimeTicks instead of a double.
- double timestamp;
+ double timestamp = 0;
// Whether default notification indicators (sound, vibration, light) should
// be played again if the notification is replacing an older notification.
- bool renotify;
+ bool renotify = false;
// Whether default notification indicators (sound, vibration, light) should
// be suppressed.
- bool silent;
+ bool silent = false;
// Whether the notification should remain onscreen indefinitely, rather than
// being auto-minimized to the notification center (if allowed by platform).
- bool require_interaction;
+ bool require_interaction = false;
// Developer-provided data associated with the notification, in the form of
// a serialized string. Must not exceed the number of bytes specified by
// |kMaximumDeveloperDataSize|.
- array<int8>? data;
+ array<uint8>? data;
// Actions that should be shown as buttons on the notification.
array<NotificationAction>? actions;
diff --git a/chromium/third_party/blink/public/platform/modules/notifications/notification_types.typemap b/chromium/third_party/blink/public/platform/modules/notifications/notification_types.typemap
deleted file mode 100644
index 4ad86b66086..00000000000
--- a/chromium/third_party/blink/public/platform/modules/notifications/notification_types.typemap
+++ /dev/null
@@ -1,16 +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.
-
-mojom = "//third_party/blink/public/platform/modules/notifications/notification.mojom"
-public_headers = [
- "//third_party/blink/public/platform/modules/notifications/web_notification_data.h",
- "//third_party/blink/public/platform/modules/notifications/web_notification_resources.h",
-]
-traits_headers = [
- "//third_party/blink/renderer/platform/mojo/notification_struct_traits.h",
-]
-type_mappings = [
- "blink.mojom.NotificationData=::blink::WebNotificationData",
- "blink.mojom.NotificationResources=::blink::WebNotificationResources",
-]
diff --git a/chromium/third_party/blink/public/platform/modules/notifications/web_notification_data.h b/chromium/third_party/blink/public/platform/modules/notifications/web_notification_data.h
index 25d3d45ea63..6c100ef679b 100644
--- a/chromium/third_party/blink/public/platform/modules/notifications/web_notification_data.h
+++ b/chromium/third_party/blink/public/platform/modules/notifications/web_notification_data.h
@@ -13,6 +13,13 @@
namespace blink {
// Structure representing the data associated with a Web Notification.
+// Currently we're using the corresponding mojom struct
+// blink::mojom::blink::NotificationData everywhere inside Blink,
+// WebNotificationData is only used to carry notification data across the
+// boundary between Content layer and Blink (the only two functions:
+// WebServiceWorkerContextProxy::DispatchNotification{Click, Close}Event),
+// ultimately WebNotificationData will also be replaced by the mojom one there
+// via Onion Soup effort.
struct WebNotificationData {
enum Direction {
kDirectionLeftToRight,
diff --git a/chromium/third_party/blink/public/platform/modules/notifications/web_notification_resources.h b/chromium/third_party/blink/public/platform/modules/notifications/web_notification_resources.h
deleted file mode 100644
index 84e0a843fa9..00000000000
--- a/chromium/third_party/blink/public/platform/modules/notifications/web_notification_resources.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_PUBLIC_PLATFORM_MODULES_NOTIFICATIONS_WEB_NOTIFICATION_RESOURCES_H_
-#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_NOTIFICATIONS_WEB_NOTIFICATION_RESOURCES_H_
-
-#include "third_party/blink/public/platform/web_vector.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-
-namespace blink {
-
-// Structure representing the resources associated with a Web Notification.
-struct WebNotificationResources {
- // Content image for the notification. The bitmap may be empty if the
- // developer did not provide an image, or fetching of the image failed.
- SkBitmap image;
-
- // Main icon for the notification. The bitmap may be empty if the developer
- // did not provide an icon, or fetching of the icon failed.
- SkBitmap icon;
-
- // Badge for the notification. The bitmap may be empty if the developer
- // did not provide a badge, or fetching of the badge failed.
- SkBitmap badge;
-
- // Icons for the actions. A bitmap may be empty if the developer did not
- // provide an icon, or fetching of the icon failed.
- WebVector<SkBitmap> action_icons;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_NOTIFICATIONS_WEB_NOTIFICATION_RESOURCES_H_
diff --git a/chromium/third_party/blink/public/platform/modules/presentation/OWNERS b/chromium/third_party/blink/public/platform/modules/presentation/OWNERS
index 5649b73f314..00b27feb53b 100644
--- a/chromium/third_party/blink/public/platform/modules/presentation/OWNERS
+++ b/chromium/third_party/blink/public/platform/modules/presentation/OWNERS
@@ -1,4 +1 @@
file://third_party/blink/renderer/modules/presentation/OWNERS
-
-per-file *.mojom=set noparent
-per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/chromium/third_party/blink/public/platform/modules/service_worker/web_service_worker_request.h b/chromium/third_party/blink/public/platform/modules/service_worker/web_service_worker_request.h
index 567e47ee357..be7faa80909 100644
--- a/chromium/third_party/blink/public/platform/modules/service_worker/web_service_worker_request.h
+++ b/chromium/third_party/blink/public/platform/modules/service_worker/web_service_worker_request.h
@@ -84,6 +84,9 @@ class BLINK_PLATFORM_EXPORT WebServiceWorkerRequest {
void SetIntegrity(const WebString&);
const WebString& Integrity() const;
+ void SetPriority(WebURLRequest::Priority);
+ WebURLRequest::Priority Priority() const;
+
void SetCacheMode(mojom::FetchCacheMode);
mojom::FetchCacheMode CacheMode() const;
diff --git a/chromium/third_party/blink/public/platform/modules/webauth/OWNERS b/chromium/third_party/blink/public/platform/modules/webauthn/OWNERS
index dd7ddf4733b..dd7ddf4733b 100644
--- a/chromium/third_party/blink/public/platform/modules/webauth/OWNERS
+++ b/chromium/third_party/blink/public/platform/modules/webauthn/OWNERS
diff --git a/chromium/third_party/blink/public/platform/modules/webauth/authenticator.mojom b/chromium/third_party/blink/public/platform/modules/webauthn/authenticator.mojom
index 17f9a84882d..435889a550e 100644
--- a/chromium/third_party/blink/public/platform/modules/webauth/authenticator.mojom
+++ b/chromium/third_party/blink/public/platform/modules/webauthn/authenticator.mojom
@@ -65,11 +65,10 @@ struct GetAssertionAuthenticatorResponse {
array<uint8>? user_handle;
// True if getClientExtensionResults() called on the returned
- // PublicKeyCredential instance should yield an
- // AuthenticationExtensionsClientOutputs dictionary that contains the `appid:
- // true` extension output, which indicates to the relying party that the
- // `appid` extension was acted upon.
+ // PublicKeyCredential instance should contain an `appid` extension output.
+ // If so, |appid_extension| contains the actual value.
bool echo_appid_extension;
+ bool appid_extension;
};
// Information about the relying party. These fields take arbitrary input.
@@ -267,6 +266,8 @@ enum AuthenticatorTransport {
USB,
NFC,
BLE,
+ CABLE,
+ INTERNAL,
};
// Interface to direct authenticators to create or use a public key credential.
diff --git a/chromium/third_party/blink/public/platform/modules/webauth/virtual_authenticator.mojom b/chromium/third_party/blink/public/platform/modules/webauthn/virtual_authenticator.mojom
index 63f54aef071..95f8458d901 100644
--- a/chromium/third_party/blink/public/platform/modules/webauth/virtual_authenticator.mojom
+++ b/chromium/third_party/blink/public/platform/modules/webauthn/virtual_authenticator.mojom
@@ -5,7 +5,7 @@
module blink.test.mojom;
import "url/mojom/url.mojom";
-import "third_party/blink/public/platform/modules/webauth/authenticator.mojom";
+import "third_party/blink/public/platform/modules/webauthn/authenticator.mojom";
// Application protocol that the virtual authenticator should simulate.
enum ClientToAuthenticatorProtocol {
diff --git a/chromium/third_party/blink/public/platform/oom_intervention.mojom b/chromium/third_party/blink/public/platform/oom_intervention.mojom
index 8eb710b9752..b6aca16ad34 100644
--- a/chromium/third_party/blink/public/platform/oom_intervention.mojom
+++ b/chromium/third_party/blink/public/platform/oom_intervention.mojom
@@ -17,9 +17,8 @@ import "mojo/public/mojom/base/shared_memory.mojom";
// Browser side interface for OOM intervention. This interface is used to check
// high memory usage in a renderer.
interface OomInterventionHost {
- // Called when a renderer detects high memory usage. |intervention_triggered|
- // is set to true when the OOM intervention is activated in the renderer.
- OnHighMemoryUsage(bool intervention_triggered);
+ // Called when a renderer detects high memory usage.
+ OnHighMemoryUsage();
};
// Arguments set by field trials to configure various thresholds for detecting
@@ -44,13 +43,12 @@ struct DetectionArgs {
// It monitors memory usage in renderer side to detect near-OOM situation.
interface OomIntervention {
// Starts monitoring memory usage in renderer side. When the renderer's
- // memory usage exceeds |memory_workload_threshold| (in bytes) the renderer
- // calls host->OnHighMemoryUsage(). The renderer also triggers OOM
- // intervention when |trigger_intervention| is true. |shared_metrics_buffer|
- // stores the OomInterventionMetrics struct in shared memory. The buffer is
- // expected to be upated very often with memory metrics.
+ // memory usage exceeds |detection_args| memory thresholds (pmf, swap, virtual
+ // memory usage and blink memory usage), the renderer calls
+ // host->OnHighMemoryUsage(). The renderer also triggers OOM intervention when
+ // |renderer_pause_enabled| or |navigate_ads_enabled| is true.
StartDetection(OomInterventionHost host,
- mojo_base.mojom.UnsafeSharedMemoryRegion shared_metrics_buffer,
DetectionArgs detection_args,
- bool trigger_intervention);
+ bool renderer_pause_enabled,
+ bool navigate_ads_enabled);
};
diff --git a/chromium/third_party/blink/public/platform/platform.h b/chromium/third_party/blink/public/platform/platform.h
index f927253a7e0..3e8fae91612 100644
--- a/chromium/third_party/blink/public/platform/platform.h
+++ b/chromium/third_party/blink/public/platform/platform.h
@@ -47,15 +47,15 @@
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "third_party/blink/public/common/feature_policy/feature_policy.h"
#include "third_party/blink/public/platform/blame_context.h"
+#include "third_party/blink/public/platform/code_cache_loader.h"
+#include "third_party/blink/public/platform/modules/indexeddb/web_idb_factory.h"
#include "third_party/blink/public/platform/user_metrics_action.h"
#include "third_party/blink/public/platform/web_audio_device.h"
#include "third_party/blink/public/platform/web_common.h"
#include "third_party/blink/public/platform/web_data.h"
#include "third_party/blink/public/platform/web_data_consumer_handle.h"
-#include "third_party/blink/public/platform/web_gamepad_listener.h"
#include "third_party/blink/public/platform/web_gesture_device.h"
#include "third_party/blink/public/platform/web_localized_string.h"
-#include "third_party/blink/public/platform/web_platform_event_type.h"
#include "third_party/blink/public/platform/web_rtc_api_name.h"
#include "third_party/blink/public/platform/web_size.h"
#include "third_party/blink/public/platform/web_speech_synthesizer.h"
@@ -63,19 +63,20 @@
#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_factory.h"
+#include "third_party/webrtc/p2p/base/portallocator.h"
namespace base {
class SingleThreadTaskRunner;
}
-namespace device {
-class Gamepads;
-}
-
namespace gpu {
class GpuMemoryBufferManager;
}
+namespace rtc {
+class Thread;
+}
+
namespace service_manager {
class Connector;
class InterfaceProvider;
@@ -101,11 +102,10 @@ class WebCanvasCaptureHandler;
class WebCookieJar;
class WebCrypto;
class WebDatabaseObserver;
-class WebPlatformEventListener;
class WebFileSystem;
class WebGraphicsContext3DProvider;
-class WebIDBFactory;
class WebImageCaptureFrameGrabber;
+class WebLocalFrame;
class WebMIDIAccessor;
class WebMIDIAccessorClient;
class WebMediaCapabilitiesClient;
@@ -122,7 +122,6 @@ class WebRTCPeerConnectionHandler;
class WebRTCPeerConnectionHandlerClient;
class WebSandboxSupport;
class WebSecurityOrigin;
-class WebSocketHandshakeThrottle;
class WebSpeechSynthesizer;
class WebSpeechSynthesizerClient;
class WebStorageNamespace;
@@ -146,13 +145,31 @@ class BLINK_PLATFORM_EXPORT Platform {
// Initialize platform and wtf. If you need to initialize the entire Blink,
// you should use blink::Initialize.
- static void Initialize(Platform*);
+ static void Initialize(Platform*, WebThread* main_thread);
static Platform* Current();
+ // This is another entry point for embedders that only require single-
+ // threaded execution of Blink. This version automatically sets up Blink
+ // with a minimally viable implementation of WebThread for the main thread.
+ // The WebThread object is returned by Platform::CurrentThread(), therefore
+ // embedders do not need to override CurrentThread().
+ //
+ // When this function is used, the WebThread instance for the main thread
+ // is owned by Platform (unlike Initialize()).
+ //
+ // In the future, we would like to let Platform own the WebThread object for
+ // the main thread in all cases, as part of Blink Thread Initialization
+ // Cleanup project:
+ // https://docs.google.com/document/d/1ehd6Lp5czBzOCHWrDkL9x62gjdlrtbMtJqt_eRaauYo/edit?usp=sharing
+ static void CreateMainThreadAndInitialize(Platform*);
+
// Used to switch the current platform only for testing.
// You should not pass in a Platform object that is not fully instantiated.
static void SetCurrentPlatformForTesting(Platform*);
+ Platform();
+ virtual ~Platform();
+
// May return null.
virtual WebCookieJar* CookieJar() { return nullptr; }
@@ -267,11 +284,7 @@ class BLINK_PLATFORM_EXPORT Platform {
// IndexedDB ----------------------------------------------------------
// Must return non-null.
- virtual WebIDBFactory* IdbFactory() { return nullptr; }
-
- // Gamepad -------------------------------------------------------------
-
- virtual void SampleGamepads(device::Gamepads& into) {}
+ virtual std::unique_ptr<WebIDBFactory> CreateIdbFactory() { return nullptr; }
// History -------------------------------------------------------------
@@ -325,6 +338,13 @@ class BLINK_PLATFORM_EXPORT Platform {
return nullptr;
}
+ // Returns the CodeCacheLoader that is used to fetch data from code caches.
+ // It is OK to return a nullptr. When a nullptr is returned, data would not
+ // be fetched from code cache.
+ virtual std::unique_ptr<CodeCacheLoader> CreateCodeCacheLoader() {
+ return nullptr;
+ }
+
// Returns a new WebURLLoaderFactory that wraps the given
// network::mojom::URLLoaderFactory.
virtual std::unique_ptr<WebURLLoaderFactory> WrapURLLoaderFactory(
@@ -358,6 +378,12 @@ class BLINK_PLATFORM_EXPORT Platform {
const char* data,
size_t data_size) {}
+ // A request to fetch contents associated with this URL from metadata cache.
+ virtual void FetchCachedCode(
+ const GURL&,
+ base::OnceCallback<void(base::Time, const std::vector<uint8_t>&)>) {}
+ virtual void ClearCodeCacheEntry(const GURL&) {}
+
// A suggestion to cache this metadata in association with this URL which
// resource is in CacheStorage.
virtual void CacheMetadataInCacheStorage(
@@ -399,9 +425,13 @@ class BLINK_PLATFORM_EXPORT Platform {
// for any other purpose.
virtual std::unique_ptr<WebThread> CreateWebAudioThread();
- // Returns an interface to the current thread. This is owned by the
- // embedder.
- virtual WebThread* CurrentThread() { return nullptr; }
+ // Returns an interface to the current thread. This is usually owned by the
+ // embedder, except when CreateMainThreadAndInitialize() is used. See comments
+ // above for details.
+ //
+ // The default implementation works only if CreateMainThreadAndInitialize() is
+ // used. Otherwise, the embedder *must* implement their own version.
+ virtual WebThread* CurrentThread();
// Returns a blame context for attributing top-level work which does not
// belong to a particular frame scope.
@@ -496,8 +526,9 @@ class BLINK_PLATFORM_EXPORT Platform {
kWebGL2ContextType, // WebGL 2.0 context, use only for WebGL canvases
kWebGL2ComputeContextType, // WebGL 2.0 Compute context, use only for WebGL
// canvases
- kGLES2ContextType, // GLES 2.0 context, default, good for using skia
- kGLES3ContextType, // GLES 3.0 context
+ kGLES2ContextType, // GLES 2.0 context, default, good for using skia
+ kGLES3ContextType, // GLES 3.0 context
+ kWebGPUContextType, // WebGPU context
};
struct ContextAttributes {
bool fail_if_major_performance_caveat = false;
@@ -544,6 +575,13 @@ class BLINK_PLATFORM_EXPORT Platform {
virtual std::unique_ptr<WebGraphicsContext3DProvider>
CreateSharedOffscreenGraphicsContext3DProvider();
+ // Returns a newly allocated and initialized WebGPU context provider,
+ // backed by an independent context. Returns null if the context cannot be
+ // created or initialized.
+ virtual std::unique_ptr<WebGraphicsContext3DProvider>
+ CreateWebGPUGraphicsContext3DProvider(const WebURL& top_document_url,
+ GraphicsInfo*);
+
virtual gpu::GpuMemoryBufferManager* GetGpuMemoryBufferManager() {
return nullptr;
}
@@ -584,6 +622,24 @@ class BLINK_PLATFORM_EXPORT Platform {
// resources.
virtual std::unique_ptr<WebMediaStreamCenter> CreateMediaStreamCenter();
+ // Returns the SingleThreadTaskRunner suitable for running WebRTC networking.
+ // An rtc::Thread will have already been created.
+ // May return null if WebRTC functionality is not implemented.
+ virtual scoped_refptr<base::SingleThreadTaskRunner> GetWebRtcWorkerThread() {
+ return nullptr;
+ }
+
+ // Returns the rtc::Thread instance associated with the WebRTC worker thread.
+ // TODO(bugs.webrtc.org/9419): Remove once WebRTC can be built as a component.
+ // May return null if WebRTC functionality is not implemented.
+ virtual rtc::Thread* GetWebRtcWorkerThreadRtcThread() { return nullptr; }
+
+ // May return null if WebRTC functionality is not implemented.
+ virtual std::unique_ptr<cricket::PortAllocator> CreateWebRtcPortAllocator(
+ WebLocalFrame* frame) {
+ return nullptr;
+ }
+
// Creates a WebCanvasCaptureHandler to capture Canvas output.
virtual std::unique_ptr<WebCanvasCaptureHandler>
CreateCanvasCaptureHandler(const WebSize&, double, WebMediaStreamTrack*);
@@ -611,15 +667,6 @@ class BLINK_PLATFORM_EXPORT Platform {
virtual void UpdateWebRTCAPICount(WebRTCAPIName api_name) {}
- // WebSocket ----------------------------------------------------------
-
- // If this method returns non-null the returned object will be used to
- // determine if/when a new WebSocket connection can be exposed to Javascript.
- // TODO(nhiroki): Remove this once the off-main-thread WebSocket is enabled by
- // default (https://crbug.com/825740).
- virtual std::unique_ptr<WebSocketHandshakeThrottle>
- CreateWebSocketHandshakeThrottle();
-
// WebWorker ----------------------------------------------------------
virtual void DidStartWorkerThread() {}
@@ -641,18 +688,6 @@ class BLINK_PLATFORM_EXPORT Platform {
virtual const char* GetBrowserServiceName() const { return ""; }
- // Platform events -----------------------------------------------------
- // Device Orientation, Device Motion, Battery, Gamepad.
-
- // Request the platform to start listening to the events of the specified
- // type and notify the given listener (if not null) when there is an update.
- virtual void StartListening(WebPlatformEventType type,
- WebPlatformEventListener* listener) {}
-
- // Request the platform to stop listening to the specified event and no
- // longer notify the listener, if any.
- virtual void StopListening(WebPlatformEventType type) {}
-
// This method converts from the supplied DOM code enum to the
// embedder's DOM code value for the key pressed. |dom_code| values are
// based on the value defined in
@@ -711,10 +746,18 @@ class BLINK_PLATFORM_EXPORT Platform {
virtual bool IsTakingV8ContextSnapshot() { return false; }
protected:
- Platform();
- virtual ~Platform();
-
WebThread* main_thread_;
+
+ private:
+ static void InitializeCommon(Platform* platform);
+
+ // We eventually want to let Platform own the main thread WebThread, but
+ // currently the main thread is owned in a few selected cases. This variable
+ // is non-null when the main thread is owned by Platform. The pointer value
+ // is the same as main_thread_.
+ //
+ // For details, see comments around CreateMainThreadAndInitialize() above.
+ std::unique_ptr<WebThread> owned_main_thread_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/public/platform/reporting.mojom b/chromium/third_party/blink/public/platform/reporting.mojom
index 398f8217285..c9e91275a32 100644
--- a/chromium/third_party/blink/public/platform/reporting.mojom
+++ b/chromium/third_party/blink/public/platform/reporting.mojom
@@ -45,4 +45,15 @@ interface ReportingServiceProxy {
string? source_file,
int32 status_code,
string script_sample);
+
+ // Attempts to queue a Feature Policy violation report using the Reporting API.
+ //
+ // (See //third_party/blink/renderer/core/frame/feature_policy_violation_report_body.h.)
+ QueueFeaturePolicyViolationReport(url.mojom.Url url,
+ string policy,
+ string message,
+ string? source_file,
+ int32 line_number,
+ int32 column_number);
+
};
diff --git a/chromium/third_party/blink/public/platform/scheduler/child/webthread_base.h b/chromium/third_party/blink/public/platform/scheduler/child/webthread_base.h
index 677dabb1f68..59b7cce3ab1 100644
--- a/chromium/third_party/blink/public/platform/scheduler/child/webthread_base.h
+++ b/chromium/third_party/blink/public/platform/scheduler/child/webthread_base.h
@@ -33,8 +33,6 @@ class BLINK_PLATFORM_EXPORT WebThreadBase : public WebThread {
const WebThreadCreationParams& params);
static std::unique_ptr<WebThreadBase> CreateCompositorThread(
const WebThreadCreationParams& params);
- // Must be called on utility thread.
- static std::unique_ptr<WebThreadBase> InitializeUtilityThread();
// WebThread implementation.
bool IsCurrentThread() const override;
diff --git a/chromium/third_party/blink/public/platform/scheduler/web_rail_mode_observer.h b/chromium/third_party/blink/public/platform/scheduler/web_rail_mode_observer.h
new file mode 100644
index 00000000000..8768f40c2d2
--- /dev/null
+++ b/chromium/third_party/blink/public/platform/scheduler/web_rail_mode_observer.h
@@ -0,0 +1,23 @@
+// 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_PUBLIC_PLATFORM_SCHEDULER_WEB_RAIL_MODE_OBSERVER_H_
+#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_SCHEDULER_WEB_RAIL_MODE_OBSERVER_H_
+
+#include "third_party/blink/public/platform/web_common.h"
+#include "v8/include/v8.h"
+
+namespace blink {
+namespace scheduler {
+
+class BLINK_PLATFORM_EXPORT WebRAILModeObserver {
+ public:
+ virtual ~WebRAILModeObserver() = default;
+ virtual void OnRAILModeChanged(v8::RAILMode rail_mode) = 0;
+};
+
+} // namespace scheduler
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_SCHEDULER_WEB_RAIL_MODE_OBSERVER_H_
diff --git a/chromium/third_party/blink/public/platform/scheduler/web_thread_scheduler.h b/chromium/third_party/blink/public/platform/scheduler/web_thread_scheduler.h
index aa6b2f06f1c..d02b7c7800a 100644
--- a/chromium/third_party/blink/public/platform/scheduler/web_thread_scheduler.h
+++ b/chromium/third_party/blink/public/platform/scheduler/web_thread_scheduler.h
@@ -12,6 +12,7 @@
#include "base/time/time.h"
#include "build/build_config.h"
#include "third_party/blink/public/platform/scheduler/single_thread_idle_task_runner.h"
+#include "third_party/blink/public/platform/scheduler/web_rail_mode_observer.h"
#include "third_party/blink/public/platform/scheduler/web_render_widget_scheduling_state.h"
#include "third_party/blink/public/platform/web_common.h"
#include "third_party/blink/public/platform/web_input_event_result.h"
@@ -40,12 +41,6 @@ enum class RendererProcessType;
class BLINK_PLATFORM_EXPORT WebThreadScheduler {
public:
- class BLINK_PLATFORM_EXPORT RAILModeObserver {
- public:
- virtual ~RAILModeObserver();
- virtual void OnRAILModeChanged(v8::RAILMode rail_mode) = 0;
- };
-
virtual ~WebThreadScheduler();
// ==== Functions for any scheduler =========================================
@@ -89,6 +84,9 @@ class BLINK_PLATFORM_EXPORT WebThreadScheduler {
virtual scoped_refptr<base::SingleThreadTaskRunner> IPCTaskRunner();
+ // Returns the cleanup task runner, which is for cleaning up.
+ virtual scoped_refptr<base::SingleThreadTaskRunner> CleanupTaskRunner();
+
// Creates a WebThread implementation for the renderer main thread.
virtual std::unique_ptr<WebThread> CreateMainThread();
@@ -211,7 +209,7 @@ class BLINK_PLATFORM_EXPORT WebThreadScheduler {
// called on the main thread and must outlive this class.
// [1]
// https://developers.google.com/web/tools/chrome-devtools/profile/evaluate-performance/rail
- virtual void AddRAILModeObserver(RAILModeObserver* observer);
+ virtual void AddRAILModeObserver(WebRAILModeObserver* observer);
// Sets the kind of renderer process. Should be called on the main thread
// once.
diff --git a/chromium/third_party/blink/public/platform/task_type.h b/chromium/third_party/blink/public/platform/task_type.h
index 4e2693569fc..690de3229b4 100644
--- a/chromium/third_party/blink/public/platform/task_type.h
+++ b/chromium/third_party/blink/public/platform/task_type.h
@@ -191,13 +191,14 @@ enum class TaskType : unsigned {
kMainThreadTaskQueueIdle = 41,
kMainThreadTaskQueueIPC = 42,
kMainThreadTaskQueueControl = 43,
+ kMainThreadTaskQueueCleanup = 52,
kCompositorThreadTaskQueueDefault = 45,
kCompositorThreadTaskQueueInput = 49,
kWorkerThreadTaskQueueDefault = 46,
kWorkerThreadTaskQueueV8 = 47,
kWorkerThreadTaskQueueCompositor = 48,
- kCount = 52,
+ kCount = 53,
};
} // namespace blink
diff --git a/chromium/third_party/blink/public/platform/web_content_security_policy.h b/chromium/third_party/blink/public/platform/web_content_security_policy.h
index 3089f56fbb0..4d94b012e20 100644
--- a/chromium/third_party/blink/public/platform/web_content_security_policy.h
+++ b/chromium/third_party/blink/public/platform/web_content_security_policy.h
@@ -44,7 +44,9 @@ enum WebContentSecurityPolicyType {
enum WebContentSecurityPolicySource {
kWebContentSecurityPolicySourceHTTP,
kWebContentSecurityPolicySourceMeta,
- kWebContentSecurityPolicySourceLast = kWebContentSecurityPolicySourceMeta
+ kWebContentSecurityPolicySourceOriginPolicy,
+ kWebContentSecurityPolicySourceLast =
+ kWebContentSecurityPolicySourceOriginPolicy
};
enum WebContentSecurityPolicyDisposition {
diff --git a/chromium/third_party/blink/public/platform/web_cors.h b/chromium/third_party/blink/public/platform/web_cors.h
index a24e28446ff..31b92009bfa 100644
--- a/chromium/third_party/blink/public/platform/web_cors.h
+++ b/chromium/third_party/blink/public/platform/web_cors.h
@@ -39,23 +39,9 @@
namespace blink {
class WebURLResponse;
-class WebSecurityOrigin;
-struct ResourceLoaderOptions;
namespace WebCORS {
-// TODO(toyoshim): Using platform/loader/fetch/ResourceLoaderOptions violates
-// the DEPS rule. This will be fixed soon by making HandleRedirect() not
-// depending on ResourceLoaderOptions.
-BLINK_PLATFORM_EXPORT base::Optional<network::CORSErrorStatus> HandleRedirect(
- WebSecurityOrigin&,
- WebURLRequest&,
- const WebURL,
- const int redirect_response_status_code,
- const WebHTTPHeaderMap&,
- network::mojom::FetchCredentialsMode,
- ResourceLoaderOptions&);
-
BLINK_PLATFORM_EXPORT WebHTTPHeaderSet
ExtractCorsExposedHeaderNamesList(network::mojom::FetchCredentialsMode,
const WebURLResponse&);
diff --git a/chromium/third_party/blink/public/platform/web_feature.mojom b/chromium/third_party/blink/public/platform/web_feature.mojom
index 40516ff9b5f..2c60954a023 100644
--- a/chromium/third_party/blink/public/platform/web_feature.mojom
+++ b/chromium/third_party/blink/public/platform/web_feature.mojom
@@ -17,7 +17,6 @@ enum WebFeature {
kOBSOLETE_PageDestruction = 0,
kWorkerStart = 4,
kSharedWorkerStart = 5,
- kUnprefixedIndexedDB = 9,
kOpenWebDatabase = 10,
kUnprefixedRequestAnimationFrame = 13,
kPrefixedRequestAnimationFrame = 14,
@@ -1692,7 +1691,6 @@ enum WebFeature {
kReplaceCharsetInXHR = 2230,
kRespondToSameOriginRequestWithCrossOriginResponse = 2231, // Obsolete.
kLinkRelModulePreload = 2232,
- kHTMLFrameSetElementNonNullAnonymousNamedGetter = 2235,
kCSPWithUnsafeEval = 2236,
kWebAssemblyInstantiation = 2237,
kV8IndexAccessor = 2238,
@@ -1799,11 +1797,9 @@ enum WebFeature {
kScrollToFragmentSucceedWithASCII = 2337,
kScrollToFragmentSucceedWithUTF8 = 2338,
kScrollToFragmentSucceedWithIsomorphic = 2339,
- kScrollToFragmentSucceedWithMixed = 2340,
kScrollToFragmentFailWithASCII = 2341,
kScrollToFragmentFailWithUTF8 = 2342,
kScrollToFragmentFailWithIsomorphic = 2343,
- kScrollToFragmentFailWithMixed = 2344,
kScrollToFragmentFailWithInvalidEncoding = 2345,
kRTCPeerConnectionWithActiveCsp = 2346,
// The above items are available as of the M65 branch.
@@ -1922,7 +1918,6 @@ enum WebFeature {
kShapeOutsideContentBoxDifferentFromMarginBox = 2461,
kShapeOutsidePaddingBoxDifferentFromMarginBox = 2462,
kCSSContainLayoutPositionedDescendants = 2463,
- kHTMLFrameSetElementAnonymousNamedGetter = 2464,
kCanvasConvertToBlob = 2465,
kPolymerV1Detected = 2466,
kPolymerV2Detected = 2467,
@@ -1974,6 +1969,27 @@ enum WebFeature {
kV8RTCPeerConnection_AddTransceiver_Method = 2513,
kV8RTCRtpTransceiver_Direction_AttributeGetter = 2514,
kV8RTCRtpTransceiver_Direction_AttributeSetter = 2515,
+ kHTMLLinkElementDisabledByParser = 2516,
+ kRequestIsHistoryNavigation = 2517,
+ kAddDocumentLevelPassiveTrueWheelEventListener = 2518,
+ kAddDocumentLevelPassiveFalseWheelEventListener = 2519,
+ kAddDocumentLevelPassiveDefaultWheelEventListener = 2520,
+ kDocumentLevelPassiveDefaultEventListenerPreventedWheel = 2521,
+ kShapeDetectionAPI = 2522,
+ kV8SourceBuffer_ChangeType_Method = 2523,
+ kPPAPIWebSocket = 2524,
+ kV8MediaStreamTrack_ContentHint_AttributeGetter = 2525,
+ kV8MediaStreamTrack_ContentHint_AttributeSetter = 2526,
+ kV8IDBFactory_Open_Method = 2527,
+ kEvaluateScriptMovedBetweenDocuments = 2528,
+ kReportingObserver = 2529,
+ kDeprecationReport = 2530,
+ kInterventionReport = 2531,
+ kV8WasmSharedMemory = 2532,
+ kV8WasmThreadOpcodes = 2533,
+ kCacheStorageAddAllSuccessWithDuplicate = 2534,
+ kLegendDelegateFocusOrAccessKey = 2535,
+ kFeaturePolicyReport = 2536,
// Add new features immediately above this line. Don't change assigned
// numbers of any item, and don't reuse removed slots.
diff --git a/chromium/third_party/blink/public/platform/web_file_system.h b/chromium/third_party/blink/public/platform/web_file_system.h
index 2109a6bf35c..29837d05493 100644
--- a/chromium/third_party/blink/public/platform/web_file_system.h
+++ b/chromium/third_party/blink/public/platform/web_file_system.h
@@ -31,6 +31,9 @@
#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_FILE_SYSTEM_H_
#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_FILE_SYSTEM_H_
+#include "base/files/file.h"
+#include "mojo/public/cpp/system/message_pipe.h"
+#include "third_party/blink/public/platform/web_callbacks.h"
#include "third_party/blink/public/platform/web_common.h"
#include "third_party/blink/public/platform/web_file_system_callbacks.h"
#include "third_party/blink/public/platform/web_file_system_type.h"
@@ -40,6 +43,7 @@ namespace blink {
class WebFileWriter;
class WebFileWriterClient;
+class WebFrame;
class WebFileSystem {
public:
@@ -171,6 +175,14 @@ class WebFileSystem {
WebFileWriterClient*,
WebFileSystemCallbacks) = 0;
+ // Creates a blink::mojom::FileWriter that can be used to write to the given
+ // file. The resulting FileWriter is passed as a ScopedMessagePipeHandle to
+ // deal with converting between non-blink and blink mojom bindings variants.
+ using CreateFileWriterCallbacks =
+ WebCallbacks<mojo::ScopedMessagePipeHandle, base::File::Error>;
+ virtual void CreateFileWriter(const WebURL& path,
+ std::unique_ptr<CreateFileWriterCallbacks>) = 0;
+
// Creates a snapshot file for a given file specified by |path|. It returns
// the metadata of the created snapshot file. The returned metadata should
// include a local platform path to the snapshot image. In local filesystem
@@ -187,12 +199,18 @@ class WebFileSystem {
virtual void CreateSnapshotFileAndReadMetadata(const WebURL& path,
WebFileSystemCallbacks) = 0;
- // Waits for additional results returned for the method call and returns true
- // if possible.
- // Returns false if there is no running method call corresponding for the
- // given ID.
- // |callbacks_id| must be the value returned by the original method call.
- virtual bool WaitForAdditionalResult(int callbacks_id) = 0;
+ struct FileSystemEntry {
+ WebString file_system_id;
+ WebString base_name;
+ };
+
+ // Prompts the user to select a file from the native filesystem. Returns an
+ // error code if something failed, or a list of the selected entries on
+ // success.
+ using ChooseEntryCallbacks =
+ WebCallbacks<WebVector<FileSystemEntry>, base::File::Error>;
+ virtual void ChooseEntry(WebFrame* frame,
+ std::unique_ptr<ChooseEntryCallbacks>) = 0;
protected:
virtual ~WebFileSystem() = default;
diff --git a/chromium/third_party/blink/public/platform/web_gamepad_listener.h b/chromium/third_party/blink/public/platform/web_gamepad_listener.h
index ae68610a31d..0586c0b893c 100644
--- a/chromium/third_party/blink/public/platform/web_gamepad_listener.h
+++ b/chromium/third_party/blink/public/platform/web_gamepad_listener.h
@@ -15,8 +15,22 @@ namespace blink {
class WebGamepadListener : public WebPlatformEventListener {
public:
- virtual void DidConnectGamepad(unsigned index, const device::Gamepad&) = 0;
- virtual void DidDisconnectGamepad(unsigned index, const device::Gamepad&) = 0;
+ // Called when a gamepad is connected. |index| is the index of the gamepad in
+ // the gamepad array, and |gamepad| is a reference to the connected gamepad.
+ virtual void DidConnectGamepad(uint32_t index,
+ const device::Gamepad& gamepad) = 0;
+
+ // Called when a gamepad is disconnected. |index| is the former index of the
+ // gamepad in the gamepad array, and |gamepad| is a reference to the
+ // connected gamepad.
+ virtual void DidDisconnectGamepad(uint32_t index,
+ const device::Gamepad& gamepad) = 0;
+
+ // Called when a button or axis is changed on a connected gamepad. |index| is
+ // the index of the gamepad in the gamepad array, and |gamepad| is a reference
+ // to the gamepad.
+ virtual void ButtonOrAxisDidChange(uint32_t index,
+ const device::Gamepad& gamepad) = 0;
protected:
~WebGamepadListener() override = default;
diff --git a/chromium/third_party/blink/public/platform/web_graphics_context_3d_provider.h b/chromium/third_party/blink/public/platform/web_graphics_context_3d_provider.h
index a6e2e16dbd9..955dc99736a 100644
--- a/chromium/third_party/blink/public/platform/web_graphics_context_3d_provider.h
+++ b/chromium/third_party/blink/public/platform/web_graphics_context_3d_provider.h
@@ -31,6 +31,7 @@
#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_GRAPHICS_CONTEXT_3D_PROVIDER_H_
#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_GRAPHICS_CONTEXT_3D_PROVIDER_H_
+#include <cstdint>
#include "base/callback_forward.h"
class GrContext;
@@ -46,6 +47,10 @@ struct GpuFeatureInfo;
namespace gles2 {
class GLES2Interface;
}
+
+namespace webgpu {
+class WebGPUInterface;
+}
}
namespace viz {
@@ -59,6 +64,7 @@ class WebGraphicsContext3DProvider {
virtual ~WebGraphicsContext3DProvider() = default;
virtual gpu::gles2::GLES2Interface* ContextGL() = 0;
+ virtual gpu::webgpu::WebGPUInterface* WebGPUInterface() = 0;
virtual bool BindToCurrentThread() = 0;
virtual GrContext* GetGrContext() = 0;
virtual const gpu::Capabilities& GetCapabilities() const = 0;
diff --git a/chromium/third_party/blink/public/platform/web_input_event.h b/chromium/third_party/blink/public/platform/web_input_event.h
index 7b26692e7fc..3c6b0898504 100644
--- a/chromium/third_party/blink/public/platform/web_input_event.h
+++ b/chromium/third_party/blink/public/platform/web_input_event.h
@@ -188,6 +188,7 @@ class WebInputEvent {
kPointerTypeFirst = kPointerDown,
kPointerUp,
kPointerMove,
+ kPointerRawMove, // To be only used within blink.
kPointerCancel,
kPointerCausedUaAction,
kPointerTypeLast = kPointerCausedUaAction,
@@ -362,6 +363,11 @@ class WebInputEvent {
return kGesturePinchTypeFirst <= type && type <= kGesturePinchTypeLast;
}
+ // Returns true if the WebInputEvent |type| is a fling gesture event.
+ static bool IsFlingGestureEventType(WebInputEvent::Type type) {
+ return kGestureFlingStart <= type && type <= kGestureFlingCancel;
+ }
+
static const char* GetName(WebInputEvent::Type type) {
#define CASE_TYPE(t) \
case WebInputEvent::k##t: \
@@ -404,6 +410,7 @@ class WebInputEvent {
CASE_TYPE(PointerDown);
CASE_TYPE(PointerUp);
CASE_TYPE(PointerMove);
+ CASE_TYPE(PointerRawMove);
CASE_TYPE(PointerCancel);
CASE_TYPE(PointerCausedUaAction);
}
diff --git a/chromium/third_party/blink/public/platform/web_layer_tree_view.h b/chromium/third_party/blink/public/platform/web_layer_tree_view.h
index a4ed392ae85..517b1b4ac55 100644
--- a/chromium/third_party/blink/public/platform/web_layer_tree_view.h
+++ b/chromium/third_party/blink/public/platform/web_layer_tree_view.h
@@ -145,9 +145,6 @@ class WebLayerTreeView {
// dirty.
virtual void SetNeedsBeginFrame() {}
- // Relays the end of a fling animation.
- virtual void DidStopFlinging() {}
-
// Run layout and paint of all pending document changes asynchronously.
virtual void LayoutAndPaintAsync(base::OnceClosure callback) {}
@@ -166,7 +163,7 @@ class WebLayerTreeView {
virtual void SetDeferCommits(bool defer_commits) {}
struct ViewportLayers {
- scoped_refptr<cc::Layer> overscroll_elasticity;
+ cc::ElementId overscroll_elasticity_element_id;
scoped_refptr<cc::Layer> page_scale;
scoped_refptr<cc::Layer> inner_viewport_container;
scoped_refptr<cc::Layer> outer_viewport_container;
diff --git a/chromium/third_party/blink/public/platform/web_localized_string.h b/chromium/third_party/blink/public/platform/web_localized_string.h
index f7d9cd1a4dd..78566722724 100644
--- a/chromium/third_party/blink/public/platform/web_localized_string.h
+++ b/chromium/third_party/blink/public/platform/web_localized_string.h
@@ -62,6 +62,8 @@ struct WebLocalizedString {
kAXMediaHideClosedCaptionsButtonHelp,
kAXMediaMuteButton,
kAXMediaMuteButtonHelp,
+ kAXMediaDisplayCutoutFullscreenButton,
+ kAXMediaDisplayCutoutFullscreenButtonHelp,
kAXMediaOverflowButton,
kAXMediaOverflowButtonHelp,
kAXMediaPauseButton,
diff --git a/chromium/third_party/blink/public/platform/web_media_constraints.h b/chromium/third_party/blink/public/platform/web_media_constraints.h
index d227066ee0d..90ca7f10cc1 100644
--- a/chromium/third_party/blink/public/platform/web_media_constraints.h
+++ b/chromium/third_party/blink/public/platform/web_media_constraints.h
@@ -61,48 +61,50 @@ class BLINK_PLATFORM_EXPORT BaseConstraint {
const char* name_;
};
+// Note this class refers to the "long" WebIDL definition which is
+// equivalent to int32_t.
class BLINK_PLATFORM_EXPORT LongConstraint : public BaseConstraint {
public:
explicit LongConstraint(const char* name);
- void SetMin(long value) {
+ void SetMin(int32_t value) {
min_ = value;
has_min_ = true;
}
- void SetMax(long value) {
+ void SetMax(int32_t value) {
max_ = value;
has_max_ = true;
}
- void SetExact(long value) {
+ void SetExact(int32_t value) {
exact_ = value;
has_exact_ = true;
}
- void SetIdeal(long value) {
+ void SetIdeal(int32_t value) {
ideal_ = value;
has_ideal_ = true;
}
- bool Matches(long value) const;
+ bool Matches(int32_t value) const;
bool IsEmpty() const override;
bool HasMandatory() const override;
WebString ToString() const override;
bool HasMin() const { return has_min_; }
- long Min() const { return min_; }
+ int32_t Min() const { return min_; }
bool HasMax() const { return has_max_; }
- long Max() const { return max_; }
+ int32_t Max() const { return max_; }
bool HasExact() const { return has_exact_; }
- long Exact() const { return exact_; }
+ int32_t Exact() const { return exact_; }
bool HasIdeal() const { return has_ideal_; }
- long Ideal() const { return ideal_; }
+ int32_t Ideal() const { return ideal_; }
private:
- long min_;
- long max_;
- long exact_;
- long ideal_;
+ int32_t min_;
+ int32_t max_;
+ int32_t exact_;
+ int32_t ideal_;
unsigned has_min_ : 1;
unsigned has_max_ : 1;
unsigned has_exact_ : 1;
diff --git a/chromium/third_party/blink/public/platform/web_media_player.h b/chromium/third_party/blink/public/platform/web_media_player.h
index caab45ce35a..ce91f5e1476 100644
--- a/chromium/third_party/blink/public/platform/web_media_player.h
+++ b/chromium/third_party/blink/public/platform/web_media_player.h
@@ -60,6 +60,7 @@ class WebURL;
enum class WebFullscreenVideoStatus;
struct WebRect;
struct WebSize;
+struct PictureInPictureControlInfo;
class WebMediaPlayer {
public:
@@ -148,6 +149,9 @@ class WebMediaPlayer {
virtual void EnterPictureInPicture(PipWindowOpenedCallback) = 0;
// Exit Picture-in-Picture and notifies Blink when it's done.
virtual void ExitPictureInPicture(PipWindowClosedCallback) = 0;
+ // Assign custom controls to the Picture-in-Picture window.
+ virtual void SetPictureInPictureCustomControls(
+ const std::vector<PictureInPictureControlInfo>&) = 0;
// Register a callback that will be run when the Picture-in-Picture window
// is resized.
virtual void RegisterPictureInPictureWindowResizeCallback(
@@ -212,17 +216,17 @@ class WebMediaPlayer {
virtual unsigned DecodedFrameCount() const = 0;
virtual unsigned DroppedFrameCount() const = 0;
virtual unsigned CorruptedFrameCount() const { return 0; }
- virtual size_t AudioDecodedByteCount() const = 0;
- virtual size_t VideoDecodedByteCount() const = 0;
+ virtual uint64_t AudioDecodedByteCount() const = 0;
+ virtual uint64_t VideoDecodedByteCount() const = 0;
- // |out_metadata|, if set, is used to return metadata about the frame
- // that is uploaded during this call.
// |already_uploaded_id| indicates the unique_id of the frame last uploaded
// to this destination. It should only be set by the caller if the contents
// of the destination are known not to have changed since that upload.
// - If |out_metadata| is not null, |already_uploaded_id| is compared with
// the unique_id of the frame being uploaded. If it's the same, the
// upload may be skipped and considered to be successful.
+ // |out_metadata|, if not null, is used to return metadata about the frame
+ // that is uploaded during this call.
virtual void Paint(cc::PaintCanvas*,
const WebRect&,
cc::PaintFlags&,
@@ -231,17 +235,18 @@ class WebMediaPlayer {
// Do a GPU-GPU texture copy of the current video frame to |texture|,
// reallocating |texture| at the appropriate size with given internal
- // format, format, and type if necessary. If the copy is impossible
- // or fails, it returns false.
+ // format, format, and type if necessary.
+ //
+ // Returns true iff the copy succeeded.
//
- // |out_metadata|, if set, is used to return metadata about the frame
- // that is uploaded during this call.
// |already_uploaded_id| indicates the unique_id of the frame last uploaded
// to this destination. It should only be set by the caller if the contents
// of the destination are known not to have changed since that upload.
// - If |out_metadata| is not null, |already_uploaded_id| is compared with
// the unique_id of the frame being uploaded. If it's the same, the
// upload may be skipped and considered to be successful.
+ // |out_metadata|, if not null, is used to return metadata about the frame
+ // that is uploaded during this call.
virtual bool CopyVideoTextureToPlatformTexture(
gpu::gles2::GLES2Interface*,
unsigned target,
@@ -252,13 +257,43 @@ class WebMediaPlayer {
int level,
bool premultiply_alpha,
bool flip_y,
- int already_uploaded_id = -1,
- VideoFrameUploadMetadata* out_metadata = nullptr) {
+ int already_uploaded_id,
+ VideoFrameUploadMetadata* out_metadata) {
+ return false;
+ }
+
+ // Do a CPU-GPU, YUV-RGB upload of the current video frame to |texture|,
+ // reallocating |texture| at the appropriate size with given internal
+ // format, format, and type if necessary.
+ //
+ // Returns true iff the copy succeeded.
+ //
+ // |already_uploaded_id| indicates the unique_id of the frame last uploaded
+ // to this destination. It should only be set by the caller if the contents
+ // of the destination are known not to have changed since that upload.
+ // - If |out_metadata| is not null, |already_uploaded_id| is compared with
+ // the unique_id of the frame being uploaded. If it's the same, the
+ // upload may be skipped and considered to be successful.
+ // |out_metadata|, if not null, is used to return metadata about the frame
+ // that is uploaded during this call.
+ virtual bool CopyVideoYUVDataToPlatformTexture(
+ gpu::gles2::GLES2Interface*,
+ unsigned target,
+ unsigned texture,
+ unsigned internal_format,
+ unsigned format,
+ unsigned type,
+ int level,
+ bool premultiply_alpha,
+ bool flip_y,
+ int already_uploaded_id,
+ VideoFrameUploadMetadata* out_metadata) {
return false;
}
- // Copy sub video frame texture to |texture|. If the copy is impossible or
- // fails, it returns false.
+ // Copy sub video frame texture to |texture|.
+ //
+ // Returns true iff the copy succeeded.
virtual bool CopyVideoSubTextureToPlatformTexture(gpu::gles2::GLES2Interface*,
unsigned target,
unsigned texture,
@@ -343,8 +378,13 @@ class WebMediaPlayer {
virtual void OnHasNativeControlsChanged(bool) {}
enum class DisplayType {
+ // Playback is happening inline.
kInline,
+ // Playback is happening either with the video fullscreen. It may also be
+ // set when Blink detects that the video is effectively fullscreen even if
+ // the element is not.
kFullscreen,
+ // Playback is happening in a Picture-in-Picture window.
kPictureInPicture,
};
diff --git a/chromium/third_party/blink/public/platform/web_media_stream_source.h b/chromium/third_party/blink/public/platform/web_media_stream_source.h
index 6c199fe2d5e..f4a25600cee 100644
--- a/chromium/third_party/blink/public/platform/web_media_stream_source.h
+++ b/chromium/third_party/blink/public/platform/web_media_stream_source.h
@@ -44,7 +44,6 @@ namespace blink {
class MediaStreamSource;
class WebAudioDestinationConsumer;
-class WebMediaConstraints;
class WebString;
class WebMediaStreamSource {
@@ -79,8 +78,8 @@ class WebMediaStreamSource {
struct Capabilities {
// WebVector is used to store an optional range for the below numeric
// fields. All of them should have 0 or 2 values representing min/max.
- WebVector<long> width;
- WebVector<long> height;
+ WebVector<uint32_t> width;
+ WebVector<uint32_t> height;
WebVector<double> aspect_ratio;
WebVector<double> frame_rate;
WebVector<bool> echo_cancellation;
@@ -138,8 +137,6 @@ class WebMediaStreamSource {
bool auto_gain_control,
bool noise_supression);
- BLINK_PLATFORM_EXPORT WebMediaConstraints Constraints();
-
BLINK_PLATFORM_EXPORT void SetCapabilities(const Capabilities&);
// Only used if if this is a WebAudio source.
diff --git a/chromium/third_party/blink/public/platform/web_media_stream_track.h b/chromium/third_party/blink/public/platform/web_media_stream_track.h
index a2650bfd2f9..7db252e4b6c 100644
--- a/chromium/third_party/blink/public/platform/web_media_stream_track.h
+++ b/chromium/third_party/blink/public/platform/web_media_stream_track.h
@@ -63,8 +63,8 @@ class WebMediaStreamTrack {
// The variables are read from
// MediaStreamTrack::GetSettings only.
double frame_rate = -1.0;
- long width = -1;
- long height = -1;
+ int32_t width = -1;
+ int32_t height = -1;
double aspect_ratio = -1.0;
WebString device_id;
WebString group_id;
@@ -73,9 +73,9 @@ class WebMediaStreamTrack {
base::Optional<bool> auto_gain_control;
base::Optional<bool> noise_supression;
WebString echo_cancellation_type;
- long sample_rate = -1;
- long sample_size = -1;
- long channel_count = -1;
+ int32_t sample_rate = -1;
+ int32_t sample_size = -1;
+ int32_t channel_count = -1;
double latency = -1.0;
double volume = -1.0;
diff --git a/chromium/third_party/blink/public/platform/web_platform_event_type.h b/chromium/third_party/blink/public/platform/web_platform_event_type.h
deleted file mode 100644
index 91c1e2f5bb3..00000000000
--- a/chromium/third_party/blink/public/platform/web_platform_event_type.h
+++ /dev/null
@@ -1,19 +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_PUBLIC_PLATFORM_WEB_PLATFORM_EVENT_TYPE_H_
-#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_PLATFORM_EVENT_TYPE_H_
-
-namespace blink {
-
-enum WebPlatformEventType {
- kWebPlatformEventTypeDeviceMotion,
- kWebPlatformEventTypeDeviceOrientation,
- kWebPlatformEventTypeDeviceOrientationAbsolute,
- kWebPlatformEventTypeGamepad,
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_PLATFORM_EVENT_TYPE_H_
diff --git a/chromium/third_party/blink/public/platform/web_rtc_api_name.h b/chromium/third_party/blink/public/platform/web_rtc_api_name.h
index d0507408c2d..2267be3bd14 100644
--- a/chromium/third_party/blink/public/platform/web_rtc_api_name.h
+++ b/chromium/third_party/blink/public/platform/web_rtc_api_name.h
@@ -19,6 +19,7 @@ enum class WebRTCAPIName {
kMediaStreamRecorder,
kCanvasCaptureStream,
kVideoCaptureStream,
+ kGetDisplayMedia,
kInvalidName
};
diff --git a/chromium/third_party/blink/public/platform/web_rtc_certificate.h b/chromium/third_party/blink/public/platform/web_rtc_certificate.h
deleted file mode 100644
index 7d7341987c2..00000000000
--- a/chromium/third_party/blink/public/platform/web_rtc_certificate.h
+++ /dev/null
@@ -1,79 +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_PUBLIC_PLATFORM_WEB_RTC_CERTIFICATE_H_
-#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_RTC_CERTIFICATE_H_
-
-#include "third_party/blink/public/platform/web_vector.h"
-
-#include "third_party/blink/public/platform/web_rtc_key_params.h"
-#include "third_party/blink/public/platform/web_string.h"
-
-#include <memory>
-
-namespace blink {
-
-// https://w3c.github.io/webrtc-pc/#rtcdtlsfingerprint*
-class WebRTCDtlsFingerprint {
- public:
- WebRTCDtlsFingerprint(WebString algorithm, WebString value)
- : algorithm_(algorithm), value_(value) {}
-
- WebString Algorithm() const { return algorithm_; }
- WebString Value() const { return value_; }
-
- private:
- WebString algorithm_;
- WebString value_;
-};
-
-// Corresponds to |rtc::RTCCertificatePEM| in WebRTC.
-// See |WebRTCCertificate::ToPEM| and |WebRTCCertificateGenerator::FromPEM|.
-class WebRTCCertificatePEM {
- public:
- WebRTCCertificatePEM(WebString private_key, WebString certificate)
- : private_key_(private_key), certificate_(certificate) {}
-
- WebString PrivateKey() const { return private_key_; }
- WebString Certificate() const { return certificate_; }
-
- private:
- WebString private_key_;
- WebString certificate_;
-};
-
-// WebRTCCertificate is an interface defining what Blink needs to know about
-// certificates, hiding Chromium and WebRTC layer implementation details. It is
-// possible to create shallow copies of the WebRTCCertificate. When all copies
-// are destroyed, the implementation specific data must be freed.
-// WebRTCCertificate objects thus act as references to the reference counted
-// internal data.
-class WebRTCCertificate {
- public:
- WebRTCCertificate() = default;
- virtual ~WebRTCCertificate() = default;
-
- // Copies the WebRTCCertificate object without copying the underlying
- // implementation specific (WebRTC layer) certificate. When all copies are
- // destroyed the underlying data is freed.
- virtual std::unique_ptr<WebRTCCertificate> ShallowCopy() const = 0;
-
- // Returns the expiration time in ms relative to epoch, 1970-01-01T00:00:00Z.
- virtual uint64_t Expires() const = 0;
- virtual WebVector<WebRTCDtlsFingerprint> GetFingerprints() const = 0;
- // Creates a PEM strings representation of the certificate. See also
- // |WebRTCCertificateGenerator::FromPEM|.
- virtual WebRTCCertificatePEM ToPEM() const = 0;
- // Checks if the two certificate objects represent the same certificate value,
- // as should be the case for a clone and the original.
- virtual bool Equals(const WebRTCCertificate& other) const = 0;
-
- private:
- WebRTCCertificate(const WebRTCCertificate&) = delete;
- WebRTCCertificate& operator=(const WebRTCCertificate&) = delete;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_RTC_CERTIFICATE_H_
diff --git a/chromium/third_party/blink/public/platform/web_rtc_certificate_generator.h b/chromium/third_party/blink/public/platform/web_rtc_certificate_generator.h
index 4cde8d8aebc..f5940a3d908 100644
--- a/chromium/third_party/blink/public/platform/web_rtc_certificate_generator.h
+++ b/chromium/third_party/blink/public/platform/web_rtc_certificate_generator.h
@@ -32,9 +32,9 @@
#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_RTC_CERTIFICATE_GENERATOR_H_
#include "third_party/blink/public/platform/web_callbacks.h"
-#include "third_party/blink/public/platform/web_rtc_certificate.h"
#include "third_party/blink/public/platform/web_rtc_key_params.h"
#include "third_party/blink/public/platform/web_string.h"
+#include "third_party/webrtc/api/peerconnectioninterface.h"
#include <memory>
@@ -45,7 +45,7 @@ class SingleThreadTaskRunner;
namespace blink {
using WebRTCCertificateCallback =
- WebCallbacks<std::unique_ptr<WebRTCCertificate>, void>;
+ WebCallbacks<rtc::scoped_refptr<rtc::RTCCertificate>, void>;
// Interface defining a class that can generate WebRTCCertificates
// asynchronously.
@@ -72,8 +72,8 @@ class WebRTCCertificateGenerator {
virtual bool IsSupportedKeyParams(const WebRTCKeyParams&) = 0;
// Creates a certificate from the PEM strings. See also
- // |WebRTCCertificate::ToPEM|.
- virtual std::unique_ptr<WebRTCCertificate> FromPEM(
+ // |rtc::RTCCertificate::ToPEM|.
+ virtual rtc::scoped_refptr<rtc::RTCCertificate> FromPEM(
blink::WebString pem_private_key,
blink::WebString pem_certificate) = 0;
};
diff --git a/chromium/third_party/blink/public/platform/web_rtc_configuration.h b/chromium/third_party/blink/public/platform/web_rtc_configuration.h
deleted file mode 100644
index b3b36f0d99a..00000000000
--- a/chromium/third_party/blink/public/platform/web_rtc_configuration.h
+++ /dev/null
@@ -1,72 +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_PUBLIC_PLATFORM_WEB_RTC_CONFIGURATION_H_
-#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_RTC_CONFIGURATION_H_
-
-#include "third_party/blink/public/platform/web_common.h"
-#include "third_party/blink/public/platform/web_rtc_certificate.h"
-#include "third_party/blink/public/platform/web_url.h"
-#include "third_party/blink/public/platform/web_vector.h"
-
-#include <memory>
-
-namespace blink {
-
-class WebString;
-
-struct WebRTCIceServer {
- WebURL url;
- WebString username;
- WebString credential;
-};
-
-enum class WebRTCIceTransportPolicy { kRelay, kAll };
-
-enum class WebRTCBundlePolicy { kBalanced, kMaxCompat, kMaxBundle };
-
-enum class WebRTCRtcpMuxPolicy { kNegotiate, kRequire };
-
-enum class WebRTCSdpSemantics { kDefault, kPlanB, kUnifiedPlan };
-
-struct WebRTCConfiguration {
- WebVector<WebRTCIceServer> ice_servers;
- WebRTCIceTransportPolicy ice_transport_policy =
- WebRTCIceTransportPolicy::kAll;
- WebRTCBundlePolicy bundle_policy = WebRTCBundlePolicy::kBalanced;
- WebRTCRtcpMuxPolicy rtcp_mux_policy = WebRTCRtcpMuxPolicy::kRequire;
- WebVector<std::unique_ptr<WebRTCCertificate>> certificates;
- int ice_candidate_pool_size = 0;
- WebRTCSdpSemantics sdp_semantics = WebRTCSdpSemantics::kDefault;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_RTC_CONFIGURATION_H_
diff --git a/chromium/third_party/blink/public/platform/web_rtc_peer_connection_handler.h b/chromium/third_party/blink/public/platform/web_rtc_peer_connection_handler.h
index 9c0e27aa3d7..bba64b58bae 100644
--- a/chromium/third_party/blink/public/platform/web_rtc_peer_connection_handler.h
+++ b/chromium/third_party/blink/public/platform/web_rtc_peer_connection_handler.h
@@ -31,11 +31,11 @@
#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_RTC_PEER_CONNECTION_HANDLER_H_
#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_RTC_PEER_CONNECTION_HANDLER_H_
-#include "third_party/blink/public/platform/web_rtc_configuration.h"
#include "third_party/blink/public/platform/web_rtc_ice_candidate.h"
#include "third_party/blink/public/platform/web_rtc_rtp_transceiver.h"
#include "third_party/blink/public/platform/web_rtc_stats.h"
#include "third_party/blink/public/platform/web_vector.h"
+#include "third_party/webrtc/api/peerconnectioninterface.h"
#include "third_party/webrtc/api/rtcerror.h"
#include "third_party/webrtc/api/rtptransceiverinterface.h"
@@ -57,16 +57,15 @@ class WebRTCSessionDescriptionRequest;
class WebRTCStatsRequest;
class WebRTCVoidRequest;
class WebString;
-struct WebRTCConfiguration;
struct WebRTCDataChannelInit;
class WebRTCPeerConnectionHandler {
public:
virtual ~WebRTCPeerConnectionHandler() = default;
- virtual bool Initialize(const WebRTCConfiguration&,
- const WebMediaConstraints&,
- WebRTCSdpSemantics original_sdp_semantics_value) = 0;
+ virtual bool Initialize(
+ const webrtc::PeerConnectionInterface::RTCConfiguration&,
+ const WebMediaConstraints&) = 0;
virtual void CreateOffer(const WebRTCSessionDescriptionRequest&,
const WebMediaConstraints&) = 0;
@@ -82,7 +81,14 @@ class WebRTCPeerConnectionHandler {
const WebRTCSessionDescription&) = 0;
virtual WebRTCSessionDescription LocalDescription() = 0;
virtual WebRTCSessionDescription RemoteDescription() = 0;
- virtual webrtc::RTCErrorType SetConfiguration(const WebRTCConfiguration&) = 0;
+ virtual WebRTCSessionDescription CurrentLocalDescription() = 0;
+ virtual WebRTCSessionDescription CurrentRemoteDescription() = 0;
+ virtual WebRTCSessionDescription PendingLocalDescription() = 0;
+ virtual WebRTCSessionDescription PendingRemoteDescription() = 0;
+ virtual const webrtc::PeerConnectionInterface::RTCConfiguration&
+ GetConfiguration() const = 0;
+ virtual webrtc::RTCErrorType SetConfiguration(
+ const webrtc::PeerConnectionInterface::RTCConfiguration&) = 0;
// DEPRECATED
virtual bool AddICECandidate(scoped_refptr<WebRTCICECandidate>) {
diff --git a/chromium/third_party/blink/public/platform/web_rtc_peer_connection_handler_client.h b/chromium/third_party/blink/public/platform/web_rtc_peer_connection_handler_client.h
index 134f34d4259..49d72e040db 100644
--- a/chromium/third_party/blink/public/platform/web_rtc_peer_connection_handler_client.h
+++ b/chromium/third_party/blink/public/platform/web_rtc_peer_connection_handler_client.h
@@ -79,6 +79,7 @@ class BLINK_PLATFORM_EXPORT WebRTCPeerConnectionHandlerClient {
std::vector<std::unique_ptr<WebRTCRtpTransceiver>>,
bool is_remote_description) = 0;
virtual void DidAddRemoteDataChannel(WebRTCDataChannelHandler*) = 0;
+ virtual void DidNoteInterestingUsage(int usage_pattern) = 0;
virtual void ReleasePeerConnectionHandler() = 0;
virtual void ClosePeerConnection();
};
diff --git a/chromium/third_party/blink/public/platform/web_runtime_features.h b/chromium/third_party/blink/public/platform/web_runtime_features.h
index 895bd6cb191..768581d6ead 100644
--- a/chromium/third_party/blink/public/platform/web_runtime_features.h
+++ b/chromium/third_party/blink/public/platform/web_runtime_features.h
@@ -78,6 +78,7 @@ class WebRuntimeFeatures {
BLINK_PLATFORM_EXPORT static void EnableBlinkHeapIncrementalMarking(bool);
BLINK_PLATFORM_EXPORT static void EnableBloatedRendererDetection(bool);
BLINK_PLATFORM_EXPORT static void EnableCacheInlineScriptCode(bool);
+ BLINK_PLATFORM_EXPORT static void EnableIsolatedCodeCache(bool);
BLINK_PLATFORM_EXPORT static void EnableCanvas2dImageChromium(bool);
BLINK_PLATFORM_EXPORT static void EnableCSSHexAlphaColor(bool);
BLINK_PLATFORM_EXPORT static void EnableCSSFragmentIdentifiers(bool);
@@ -98,6 +99,8 @@ class WebRuntimeFeatures {
BLINK_PLATFORM_EXPORT static void EnableLayoutNG(bool);
BLINK_PLATFORM_EXPORT static void EnableLazyFrameLoading(bool);
BLINK_PLATFORM_EXPORT static void EnableLazyFrameVisibleLoadTimeMetrics(bool);
+ BLINK_PLATFORM_EXPORT static void EnableLazyImageLoading(bool);
+ BLINK_PLATFORM_EXPORT static void EnableLazyImageVisibleLoadTimeMetrics(bool);
BLINK_PLATFORM_EXPORT static void EnableLazyParseCSS(bool);
BLINK_PLATFORM_EXPORT static void EnableMediaCapture(bool);
BLINK_PLATFORM_EXPORT static void EnableMediaSession(bool);
@@ -114,18 +117,20 @@ class WebRuntimeFeatures {
BLINK_PLATFORM_EXPORT static void EnableNotifications(bool);
BLINK_PLATFORM_EXPORT static void EnableOnDeviceChange(bool);
BLINK_PLATFORM_EXPORT static void EnableOrientationEvent(bool);
- BLINK_PLATFORM_EXPORT static void EnableOriginPolicy(bool);
BLINK_PLATFORM_EXPORT static void EnableOverflowIconsForMediaControls(bool);
BLINK_PLATFORM_EXPORT static void EnableOverlayScrollbars(bool);
BLINK_PLATFORM_EXPORT static void EnableOutOfBlinkCORS(bool);
BLINK_PLATFORM_EXPORT static void EnablePageLifecycle(bool);
BLINK_PLATFORM_EXPORT static void EnablePagePopup(bool);
BLINK_PLATFORM_EXPORT static void EnablePassiveDocumentEventListeners(bool);
+ BLINK_PLATFORM_EXPORT static void EnablePassiveDocumentWheelEventListeners(
+ bool);
BLINK_PLATFORM_EXPORT static void EnablePaymentApp(bool);
BLINK_PLATFORM_EXPORT static void EnablePaymentRequest(bool);
BLINK_PLATFORM_EXPORT static void EnablePermissionsAPI(bool);
BLINK_PLATFORM_EXPORT static void EnablePictureInPicture(bool);
BLINK_PLATFORM_EXPORT static void EnablePictureInPictureAPI(bool);
+ BLINK_PLATFORM_EXPORT static void EnablePortals(bool);
BLINK_PLATFORM_EXPORT static void EnablePreciseMemoryInfo(bool);
BLINK_PLATFORM_EXPORT static void EnablePreloadDefaultIsMetadata(bool);
BLINK_PLATFORM_EXPORT static void EnablePreloadImageSrcSetEnabled(bool);
@@ -145,6 +150,7 @@ class WebRuntimeFeatures {
bool);
BLINK_PLATFORM_EXPORT static void EnableSharedArrayBuffer(bool);
BLINK_PLATFORM_EXPORT static void EnableSharedWorker(bool);
+ BLINK_PLATFORM_EXPORT static void EnableSignedHTTPExchange(bool);
BLINK_PLATFORM_EXPORT static void EnableSlimmingPaintV2(bool);
BLINK_PLATFORM_EXPORT static void EnableTouchEventFeatureDetection(bool);
BLINK_PLATFORM_EXPORT static void EnableUserActivationV2(bool);
@@ -165,7 +171,6 @@ class WebRuntimeFeatures {
BLINK_PLATFORM_EXPORT static void EnableWebXRGamepadSupport(bool);
BLINK_PLATFORM_EXPORT static void EnableXSLT(bool);
BLINK_PLATFORM_EXPORT static void ForceOverlayFullscreenVideo(bool);
- BLINK_PLATFORM_EXPORT static void EnableAutoplayMutedVideos(bool);
BLINK_PLATFORM_EXPORT static void EnableTimerThrottlingForBackgroundTabs(
bool);
BLINK_PLATFORM_EXPORT static void EnableTimerThrottlingForHiddenFrames(bool);
@@ -191,14 +196,14 @@ class WebRuntimeFeatures {
BLINK_PLATFORM_EXPORT static void EnableV8ContextSnapshot(bool);
BLINK_PLATFORM_EXPORT static void EnableAutomationControlled(bool);
BLINK_PLATFORM_EXPORT static void EnableWorkStealingInScriptRunner(bool);
- BLINK_PLATFORM_EXPORT static void EnableStopInBackground(bool);
- BLINK_PLATFORM_EXPORT static void EnableStopNonTimersInBackground(bool);
+ BLINK_PLATFORM_EXPORT static void EnableScheduledScriptStreaming(bool);
BLINK_PLATFORM_EXPORT static void EnablePWAFullCodeCache(bool);
BLINK_PLATFORM_EXPORT static void EnableOffMainThreadWebSocket(bool);
BLINK_PLATFORM_EXPORT static void EnableExperimentalProductivityFeatures(
bool);
BLINK_PLATFORM_EXPORT static void EnableAutoplayIgnoresWebAudio(bool);
BLINK_PLATFORM_EXPORT static void EnableMediaControlsExpandGesture(bool);
+ BLINK_PLATFORM_EXPORT static void EnableHrefTranslate(bool);
private:
WebRuntimeFeatures();
diff --git a/chromium/third_party/blink/public/platform/web_scoped_virtual_time_pauser.h b/chromium/third_party/blink/public/platform/web_scoped_virtual_time_pauser.h
index 9649ff8f375..13ba101c005 100644
--- a/chromium/third_party/blink/public/platform/web_scoped_virtual_time_pauser.h
+++ b/chromium/third_party/blink/public/platform/web_scoped_virtual_time_pauser.h
@@ -14,8 +14,13 @@ namespace scheduler {
class MainThreadSchedulerImpl;
} // namespace scheduler
-// A move only RAII style helper which makes it easier for subsystems to pause
-// virtual time while performing an asynchronous operation.
+// VirtualTime is a headless feature which is intended to make renders (more)
+// deterministic by pausing task execution in the Blink main thread (and pausing
+// the clock) while certain asynchronous operations are pending, e.g. fetching
+// resources. Generally new instances of WebScopedVirtualTimePauser should only
+// be added if there are determinism problems with renders on certain pages.
+// The WebScopedVirtualTimePauser itself is a move only RAII style helper which
+// makes it easier for subsystems to robustly pause and unpause virtual time.
class BLINK_PLATFORM_EXPORT WebScopedVirtualTimePauser {
public:
enum class VirtualTaskDuration {
@@ -25,6 +30,11 @@ class BLINK_PLATFORM_EXPORT WebScopedVirtualTimePauser {
// Note simply creating a WebScopedVirtualTimePauser doesn't cause VirtualTime
// to pause, instead you need to call PauseVirtualTime.
+ // By default VirtualTaskDuration::kInstant should be used unless there is a
+ // risk of virtual time getting stalled (e.g. if a page requests a
+ // non-existent resource and it has an error handler which always fetches
+ // another non-existent resource, then there is a risk that virtual time will
+ // be blocked forever unless we use VirtualTaskDuration::kNonInstant).
WebScopedVirtualTimePauser(scheduler::MainThreadSchedulerImpl*,
VirtualTaskDuration,
const WebString& debug_name);
diff --git a/chromium/third_party/blink/public/platform/web_scroll_into_view_params.h b/chromium/third_party/blink/public/platform/web_scroll_into_view_params.h
index d6b7adb586e..9c61ba48311 100644
--- a/chromium/third_party/blink/public/platform/web_scroll_into_view_params.h
+++ b/chromium/third_party/blink/public/platform/web_scroll_into_view_params.h
@@ -37,7 +37,7 @@ struct WebScrollIntoViewParams {
struct Alignment {
Alignment() = default;
#if INSIDE_BLINK
- BLINK_PLATFORM_EXPORT Alignment(const ScrollAlignment&);
+ BLINK_EXPORT Alignment(const ScrollAlignment&);
#endif
AlignmentBehavior rect_visible = kNoScroll;
AlignmentBehavior rect_hidden = kCenter;
@@ -89,7 +89,7 @@ struct WebScrollIntoViewParams {
WebScrollIntoViewParams() = default;
#if INSIDE_BLINK
- BLINK_PLATFORM_EXPORT WebScrollIntoViewParams(
+ BLINK_EXPORT WebScrollIntoViewParams(
ScrollAlignment,
ScrollAlignment,
ScrollType scroll_type = kProgrammaticScroll,
@@ -98,13 +98,13 @@ struct WebScrollIntoViewParams {
bool is_for_scroll_sequence = false,
bool zoom_into_rect = false);
- BLINK_PLATFORM_EXPORT ScrollAlignment GetScrollAlignmentX() const;
+ BLINK_EXPORT ScrollAlignment GetScrollAlignmentX() const;
- BLINK_PLATFORM_EXPORT ScrollAlignment GetScrollAlignmentY() const;
+ BLINK_EXPORT ScrollAlignment GetScrollAlignmentY() const;
- BLINK_PLATFORM_EXPORT ScrollType GetScrollType() const;
+ BLINK_EXPORT ScrollType GetScrollType() const;
- BLINK_PLATFORM_EXPORT ScrollBehavior GetScrollBehavior() const;
+ BLINK_EXPORT ScrollBehavior GetScrollBehavior() const;
#endif
};
diff --git a/chromium/third_party/blink/public/platform/web_url_request.h b/chromium/third_party/blink/public/platform/web_url_request.h
index cd6d8a0a2df..f11ef44c1be 100644
--- a/chromium/third_party/blink/public/platform/web_url_request.h
+++ b/chromium/third_party/blink/public/platform/web_url_request.h
@@ -141,7 +141,9 @@ class WebURLRequest {
kResourceLoadingHintsOn = 1 << 7, // Request that resource loading hints be
// used during pageload.
kOfflinePageOn = 1 << 8,
- kPreviewsStateLast = kOfflinePageOn
+ kLitePageRedirectOn = 1 << 9, // Allow the browser to redirect the resource
+ // to a Lite Page server.
+ kPreviewsStateLast = kLitePageRedirectOn
};
class ExtraData {
@@ -307,13 +309,6 @@ class WebURLRequest {
BLINK_PLATFORM_EXPORT Priority GetPriority() const;
BLINK_PLATFORM_EXPORT void SetPriority(Priority);
- // PlzNavigate: whether the FrameLoader should try to send the request to
- // the browser (if browser-side navigations are enabled).
- // Note: WebURLRequests created by RenderFrameImpl::OnCommitNavigation must
- // not be sent to the browser.
- BLINK_PLATFORM_EXPORT bool CheckForBrowserSideNavigation() const;
- BLINK_PLATFORM_EXPORT void SetCheckForBrowserSideNavigation(bool);
-
BLINK_PLATFORM_EXPORT bool WasDiscarded() const;
BLINK_PLATFORM_EXPORT void SetWasDiscarded(bool);
diff --git a/chromium/third_party/blink/public/platform/web_url_response.h b/chromium/third_party/blink/public/platform/web_url_response.h
index 79ed9409685..e6dc8262560 100644
--- a/chromium/third_party/blink/public/platform/web_url_response.h
+++ b/chromium/third_party/blink/public/platform/web_url_response.h
@@ -228,12 +228,9 @@ class WebURLResponse {
// details.
BLINK_PLATFORM_EXPORT void SetWasFallbackRequiredByServiceWorker(bool);
- // The type of the response, if it was returned by a service worker. This is
- // kDefault if the response was not returned by a service worker.
- BLINK_PLATFORM_EXPORT void SetResponseTypeViaServiceWorker(
- network::mojom::FetchResponseType);
- BLINK_PLATFORM_EXPORT network::mojom::FetchResponseType
- ResponseTypeViaServiceWorker() const;
+ // https://fetch.spec.whatwg.org/#concept-response-type
+ BLINK_PLATFORM_EXPORT void SetType(network::mojom::FetchResponseType);
+ BLINK_PLATFORM_EXPORT network::mojom::FetchResponseType GetType() const;
// The URL list of the Response object the ServiceWorker passed to
// respondWith(). See ServiceWorkerResponseInfo::url_list_via_service_worker()
diff --git a/chromium/third_party/blink/public/platform/web_vector.h b/chromium/third_party/blink/public/platform/web_vector.h
index caf17ed1811..3c030cfb42a 100644
--- a/chromium/third_party/blink/public/platform/web_vector.h
+++ b/chromium/third_party/blink/public/platform/web_vector.h
@@ -32,6 +32,7 @@
#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_VECTOR_H_
#include "base/logging.h"
+#include "build/build_config.h"
#include "third_party/blink/public/platform/web_common.h"
#include <vector>
@@ -80,8 +81,14 @@ class WebVector {
// The vector can be populated using reserve() and emplace_back().
WebVector() = default;
- // Create a vector with |size| default-constructed elements.
+#if defined(ARCH_CPU_64_BITS)
+ // Create a vector with |size| default-constructed elements. We define
+ // a constructor with size_t otherwise we'd have a duplicate define.
explicit WebVector(size_t size) : data_(size) {}
+#endif
+
+ // Create a vector with |size| default-constructed elements.
+ explicit WebVector(uint32_t size) : data_(size) {}
template <typename U>
WebVector(const U* values, size_t size) : data_(values, values + size) {}
diff --git a/chromium/third_party/blink/public/platform/web_video_frame_submitter.h b/chromium/third_party/blink/public/platform/web_video_frame_submitter.h
index 0782fb493e5..f2ff8aa3102 100644
--- a/chromium/third_party/blink/public/platform/web_video_frame_submitter.h
+++ b/chromium/third_party/blink/public/platform/web_video_frame_submitter.h
@@ -14,17 +14,20 @@ namespace cc {
class LayerTreeSettings;
}
-namespace ui {
-class ContextProviderCommandBuffer;
-} // namespace ui
+namespace viz {
+class ContextProvider;
+} // namespace viz
namespace blink {
+// Sets the proper context_provider and compositing mode onto the Submitter.
+using WebSubmitterConfigurationCallback =
+ base::OnceCallback<void(bool, scoped_refptr<viz::ContextProvider>)>;
// Callback to obtain the media ContextProvider and a bool indicating whether
// we are in software compositing mode.
-using WebContextProviderCallback = base::RepeatingCallback<void(
- base::OnceCallback<void(bool,
- scoped_refptr<ui::ContextProviderCommandBuffer>)>)>;
+using WebContextProviderCallback =
+ base::RepeatingCallback<void(scoped_refptr<viz::ContextProvider>,
+ WebSubmitterConfigurationCallback)>;
using WebFrameSinkDestroyedCallback = base::RepeatingCallback<void()>;
// Exposes the VideoFrameSubmitter, which submits CompositorFrames containing
@@ -35,7 +38,8 @@ class BLINK_PLATFORM_EXPORT WebVideoFrameSubmitter
public:
static std::unique_ptr<WebVideoFrameSubmitter> Create(
WebContextProviderCallback,
- const cc::LayerTreeSettings&);
+ const cc::LayerTreeSettings&,
+ bool use_sync_primitives);
~WebVideoFrameSubmitter() override = default;
// Intialize must be called before submissions occur, pulled out of
diff --git a/chromium/third_party/blink/public/platform/web_worker_fetch_context.h b/chromium/third_party/blink/public/platform/web_worker_fetch_context.h
index ac2f45792dd..1a0ba062ad9 100644
--- a/chromium/third_party/blink/public/platform/web_worker_fetch_context.h
+++ b/chromium/third_party/blink/public/platform/web_worker_fetch_context.h
@@ -9,6 +9,7 @@
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom-shared.h"
+#include "third_party/blink/public/platform/code_cache_loader.h"
#include "third_party/blink/public/platform/web_application_cache_host.h"
#include "third_party/blink/public/platform/web_document_subresource_filter.h"
#include "third_party/blink/public/platform/web_url.h"
@@ -55,6 +56,13 @@ class WebWorkerFetchContext {
virtual std::unique_ptr<WebURLLoaderFactory> WrapURLLoaderFactory(
mojo::ScopedMessagePipeHandle url_loader_factory_handle) = 0;
+ // Returns a CodeCacheLoader that fetches data from code caches. If
+ // a nullptr is returned then data would not be fetched from the code
+ // cache.
+ virtual std::unique_ptr<CodeCacheLoader> CreateCodeCacheLoader() {
+ return nullptr;
+ };
+
// Returns a new WebURLLoaderFactory for loading scripts in this worker
// context. Unlike CreateURLLoaderFactory(), this may return nullptr even on
// the first call.
diff --git a/chromium/third_party/blink/public/public_typemaps.gni b/chromium/third_party/blink/public/public_typemaps.gni
index b6175f87c02..7912f689c16 100644
--- a/chromium/third_party/blink/public/public_typemaps.gni
+++ b/chromium/third_party/blink/public/public_typemaps.gni
@@ -6,6 +6,7 @@
typemaps = [
"//third_party/blink/public/platform/content_security_policy.typemap",
"//third_party/blink/public/platform/referrer_policy.typemap",
+ "//third_party/blink/public/common/indexeddb/indexeddb.typemap",
"//third_party/blink/public/common/screen_orientation/screen_orientation_lock_types.typemap",
"//third_party/blink/public/common/manifest/display_mode.typemap",
"//third_party/blink/public/common/manifest/manifest.typemap",
diff --git a/chromium/third_party/blink/public/web/DEPS b/chromium/third_party/blink/public/web/DEPS
index 31473f67708..368f8834e98 100644
--- a/chromium/third_party/blink/public/web/DEPS
+++ b/chromium/third_party/blink/public/web/DEPS
@@ -9,11 +9,11 @@ include_rules = [
"+cc/paint/paint_canvas.h",
"+cc/paint/paint_flags.h",
"+mojo/public",
- # Enforce to use mojom-shared.h in blink/public so that it can compile
- # inside and outside Blink.
- "+services/ui/public/interfaces/ime/ime.mojom-shared.h",
"+services/network/public/mojom/cors.mojom-shared.h",
"+services/service_manager/public",
+ # Enforce to use mojom-shared.h in blink/public so that it can compile
+ # inside and outside Blink.
+ "+services/ws/public/mojom/ime/ime.mojom-shared.h",
"+third_party/blink/public/platform",
"+third_party/blink/public/web",
diff --git a/chromium/third_party/blink/public/web/blink.h b/chromium/third_party/blink/public/web/blink.h
index e48e0e9dd5e..322a311b31f 100644
--- a/chromium/third_party/blink/public/web/blink.h
+++ b/chromium/third_party/blink/public/web/blink.h
@@ -43,7 +43,21 @@ namespace blink {
// Must be called on the thread that will be the main thread before
// using any other public APIs. The provided Platform; must be
// non-null and must remain valid until the current thread calls shutdown.
-BLINK_EXPORT void Initialize(Platform*, service_manager::BinderRegistry*);
+BLINK_EXPORT void Initialize(Platform*,
+ service_manager::BinderRegistry*,
+ WebThread* main_thread);
+
+// The same as above, but this only supports simple single-threaded execution
+// environment. The main thread WebThread object is owned by Platform when this
+// version is used. This version is mainly for tests and other components
+// requiring only the simple environment.
+//
+// When this version is used, your Platform implementation needs to follow
+// a certain convention on CurrentThread(); see the comments at
+// Platform::CreateMainThreadAndInitialize().
+BLINK_EXPORT void CreateMainThreadAndInitialize(
+ Platform*,
+ service_manager::BinderRegistry*);
// Get the V8 Isolate for the main thread.
// initialize must have been called first.
diff --git a/chromium/third_party/blink/public/web/devtools_agent.mojom b/chromium/third_party/blink/public/web/devtools_agent.mojom
index ab6f459607b..6cf36591f0b 100644
--- a/chromium/third_party/blink/public/web/devtools_agent.mojom
+++ b/chromium/third_party/blink/public/web/devtools_agent.mojom
@@ -38,8 +38,8 @@ interface DevToolsAgent {
// e.g. requesting a pause. There is no ordering guarantee relative to
// regular |session|.
//
- // If |reattach_state| is present, restores the state of the session to
- // previously saved one (see DevToolsSessionHost). This is useful when
+ // If |reattach_session_state| is present, restores the state of the session
+ // to previously saved one (see DevToolsSessionHost). This is useful when
// transferring a session from one agent to another while preserving the
// state. For example, cross-process navigation in a frame creates a new
// DevToolsAgent (in a different process), but we can preserve the state of
@@ -65,7 +65,7 @@ interface DevToolsAgent {
AttachDevToolsSession(associated DevToolsSessionHost host,
associated DevToolsSession& session,
DevToolsSession& io_session,
- string? reattach_state);
+ DevToolsSessionState? reattach_session_state);
// Requests an element at specific position to be inspected in every
// attached session (or the next attached one if none yet).
@@ -96,13 +96,24 @@ interface DevToolsSession {
interface DevToolsSessionHost {
// Dispatches protocol command response to a remote debugging client.
// |call_id| is a command id as defined in protocol.
- // |state| is a state for future reattach (see DevToolsAgent),
- // may be missing if the state did not change since last time.
+ // |updates| are the session state deltas for future reattach (see
+ // DevToolsAgent), may be missing if the state did not change since
+ // last time.
DispatchProtocolResponse(mojo_base.mojom.BigString message,
int32 call_id,
- string? state);
+ DevToolsSessionState? updates);
// Dispatches protocol notification to a remote debugging client.
DispatchProtocolNotification(mojo_base.mojom.BigString message,
- string? state);
+ DevToolsSessionState? updates);
+};
+
+// The session state is a mapping from keys to either values or missing
+// values. Missing values are only used when updates are sent; that's
+// in DispatchProtocolResponse and DispatchProtocolNotification. The
+// DevToolsSession will then interpret these missing values by deleting
+// the respective key when its applying the updates in
+// DevToolsSession::ApplySessionStateUpdates.
+struct DevToolsSessionState {
+ map<string, string?> entries;
};
diff --git a/chromium/third_party/blink/public/web/modules/service_worker/web_service_worker_context_client.h b/chromium/third_party/blink/public/web/modules/service_worker/web_service_worker_context_client.h
index 2706d71aeef..faf2e39252f 100644
--- a/chromium/third_party/blink/public/web/modules/service_worker/web_service_worker_context_client.h
+++ b/chromium/third_party/blink/public/web/modules/service_worker/web_service_worker_context_client.h
@@ -102,6 +102,10 @@ class WebServiceWorkerContextClient {
// completed. Called on the main thread.
virtual void WorkerContextFailedToStart() {}
+ // The worker started but it could not execute because loading the
+ // installed script failed.
+ virtual void FailedToLoadInstalledScript() {}
+
// The worker script successfully loaded. Called on the main thread when the
// script is served from ResourceLoader or on the worker thread when the
// script is served via WebServiceWorkerInstalledScriptsManager.
@@ -186,9 +190,10 @@ class WebServiceWorkerContextClient {
int event_id,
mojom::ServiceWorkerEventStatus,
double event_dispatch_time) {}
- virtual void DidHandleBackgroundFetchedEvent(int event_id,
- mojom::ServiceWorkerEventStatus,
- double event_dispatch_time) {}
+ virtual void DidHandleBackgroundFetchSuccessEvent(
+ int event_id,
+ mojom::ServiceWorkerEventStatus,
+ double event_dispatch_time) {}
// Called after 'cookiechange' events are handled by the service worker.
virtual void DidHandleCookieChangeEvent(int event_id,
diff --git a/chromium/third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h b/chromium/third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h
index 58857151774..23b8e557f7f 100644
--- a/chromium/third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h
+++ b/chromium/third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h
@@ -33,6 +33,8 @@
#include "base/time/time.h"
#include "third_party/blink/public/common/message_port/transferable_message.h"
+#include "third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom-shared.h"
+#include "third_party/blink/public/platform/modules/background_fetch/web_background_fetch_registration.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_registration.h"
#include "third_party/blink/public/platform/web_canonical_cookie.h"
@@ -41,7 +43,6 @@
namespace blink {
-struct WebBackgroundFetchSettledFetch;
struct WebCanMakePaymentEventData;
class WebDataConsumerHandle;
class WebSecurityOrigin;
@@ -67,27 +68,18 @@ class WebServiceWorkerContextProxy {
virtual void DispatchActivateEvent(int event_id) = 0;
- enum class BackgroundFetchState { kPending, kSucceeded, kFailed };
-
virtual void DispatchBackgroundFetchAbortEvent(
int event_id,
- const WebString& developer_id,
- const WebString& unique_id,
- const WebVector<WebBackgroundFetchSettledFetch>& fetches) = 0;
+ const WebBackgroundFetchRegistration& registration) = 0;
virtual void DispatchBackgroundFetchClickEvent(
int event_id,
- const WebString& developer_id,
- BackgroundFetchState status) = 0;
+ const WebBackgroundFetchRegistration& registration) = 0;
virtual void DispatchBackgroundFetchFailEvent(
int event_id,
- const WebString& developer_id,
- const WebString& unique_id,
- const WebVector<WebBackgroundFetchSettledFetch>& fetches) = 0;
- virtual void DispatchBackgroundFetchedEvent(
+ const WebBackgroundFetchRegistration& registration) = 0;
+ virtual void DispatchBackgroundFetchSuccessEvent(
int event_id,
- const WebString& developer_id,
- const WebString& unique_id,
- const WebVector<WebBackgroundFetchSettledFetch>& fetches) = 0;
+ const WebBackgroundFetchRegistration& registration) = 0;
virtual void DispatchCookieChangeEvent(
int event_id,
const WebCanonicalCookie& cookie,
diff --git a/chromium/third_party/blink/public/web/web_associated_url_loader_options.h b/chromium/third_party/blink/public/web/web_associated_url_loader_options.h
index c4b30a4e5ca..120995c6ae0 100644
--- a/chromium/third_party/blink/public/web/web_associated_url_loader_options.h
+++ b/chromium/third_party/blink/public/web/web_associated_url_loader_options.h
@@ -36,21 +36,19 @@
namespace blink {
struct WebAssociatedURLLoaderOptions {
- WebAssociatedURLLoaderOptions()
- : untrusted_http(false),
- expose_all_response_headers(false),
- preflight_policy(
- network::mojom::CORSPreflightPolicy::kConsiderPreflight) {}
-
// Whether to validate the method and headers as if this was an
// XMLHttpRequest.
- bool untrusted_http;
+ bool untrusted_http = false;
// If policy is to use access control, whether to expose non-whitelisted
// response headers to the client.
- bool expose_all_response_headers;
+ bool expose_all_response_headers = false;
+
+ // When true, omit origin related checks. USE WITH CARE.
+ bool grant_universal_access = false;
- network::mojom::CORSPreflightPolicy preflight_policy;
+ network::mojom::CORSPreflightPolicy preflight_policy =
+ network::mojom::CORSPreflightPolicy::kConsiderPreflight;
};
} // namespace blink
diff --git a/chromium/third_party/blink/public/web/web_ax_context.h b/chromium/third_party/blink/public/web/web_ax_context.h
new file mode 100644
index 00000000000..c3e1728d463
--- /dev/null
+++ b/chromium/third_party/blink/public/web/web_ax_context.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_PUBLIC_WEB_WEB_AX_CONTEXT_H_
+#define THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_AX_CONTEXT_H_
+
+#include "third_party/blink/public/web/web_ax_object.h"
+#include "third_party/blink/public/web/web_document.h"
+
+namespace blink {
+
+class AXContext;
+
+// An instance of this class, while kept alive, enables accessibility
+// support for the given document.
+class WebAXContext {
+ public:
+ BLINK_EXPORT explicit WebAXContext(WebDocument document);
+ BLINK_EXPORT ~WebAXContext();
+
+ // Returns the root element of the document's accessibility tree.
+ BLINK_EXPORT WebAXObject Root() const;
+
+ private:
+ std::unique_ptr<AXContext> private_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_AX_CONTEXT_H_
diff --git a/chromium/third_party/blink/public/web/web_ax_object.h b/chromium/third_party/blink/public/web/web_ax_object.h
index 88b229a9a8e..88cd2300c9f 100644
--- a/chromium/third_party/blink/public/web/web_ax_object.h
+++ b/chromium/third_party/blink/public/web/web_ax_object.h
@@ -44,7 +44,6 @@ class SkMatrix44;
namespace blink {
class AXObject;
-class ScopedAXObjectCache;
class WebAXObject;
class WebNode;
class WebDocument;
@@ -67,20 +66,6 @@ class BLINK_EXPORT WebAXSparseAttributeClient {
const WebVector<WebAXObject>&) = 0;
};
-// An instance of this class, while kept alive, indicates that accessibility
-// should be temporarily enabled. If accessibility was enabled globally
-// (WebSettings::setAccessibilityEnabled), this will have no effect.
-class WebScopedAXContext {
- public:
- BLINK_EXPORT WebScopedAXContext(WebDocument& root_document);
- BLINK_EXPORT ~WebScopedAXContext();
-
- BLINK_EXPORT WebAXObject Root() const;
-
- private:
- std::unique_ptr<ScopedAXObjectCache> private_;
-};
-
// A container for passing around a reference to AXObject.
class WebAXObject {
public:
@@ -131,6 +116,7 @@ class WebAXObject {
BLINK_EXPORT void GetSparseAXAttributes(WebAXSparseAttributeClient&) const;
BLINK_EXPORT bool IsAnchor() const;
+ BLINK_EXPORT bool IsAutofillAvailable() const;
BLINK_EXPORT WebAXCheckedState CheckedState() const;
BLINK_EXPORT bool IsCheckable() const;
BLINK_EXPORT bool IsClickable() const;
diff --git a/chromium/third_party/blink/public/web/web_document_loader.h b/chromium/third_party/blink/public/web/web_document_loader.h
index 3b4c95a94d4..632bf509c4b 100644
--- a/chromium/third_party/blink/public/web/web_document_loader.h
+++ b/chromium/third_party/blink/public/web/web_document_loader.h
@@ -119,15 +119,8 @@ class BLINK_EXPORT WebDocumentLoader {
virtual WebServiceWorkerNetworkProvider*
GetServiceWorkerNetworkProvider() = 0;
- // PlzNavigate
- // Allows to specify the SourceLocation that triggered the navigation.
- virtual void SetSourceLocation(const WebSourceLocation&) = 0;
virtual void ResetSourceLocation() = 0;
- // Mark that the load was user activated. This is meant to be used for browser
- // initiated loads that may have had a user activation from the browser UI.
- virtual void SetUserActivated() = 0;
-
// Can be used to temporarily suspend feeding the parser with new data. The
// parser will be allowed to read new data when ResumeParser() is called the
// same number of time than BlockParser().
diff --git a/chromium/third_party/blink/public/web/web_file_chooser_params.h b/chromium/third_party/blink/public/web/web_file_chooser_params.h
index 358fb186698..14ee90b8fa3 100644
--- a/chromium/third_party/blink/public/web/web_file_chooser_params.h
+++ b/chromium/third_party/blink/public/web/web_file_chooser_params.h
@@ -34,17 +34,16 @@
#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_vector.h"
-#include "third_party/blink/public/web/web_file_chooser_completion.h"
namespace blink {
struct WebFileChooserParams {
- // If |multiSelect| is true, the dialog allows the user to select multiple
+ // If |multi_select| is true, the dialog allows the user to select multiple
// files.
bool multi_select;
// If |directory| is true, the dialog allows the user to select a directory.
bool directory;
- // If |saveAs| is true, the dialog allows the user to select a possibly
+ // If |save_as| is true, the dialog allows the user to select a possibly
// non-existent file. This can be used for a "Save As" dialog.
bool save_as;
// |title| is the title for a file chooser dialog. It can be an empty string.
@@ -56,19 +55,17 @@ struct WebFileChooserParams {
// This list comes from an 'accept' attribute value of an INPUT element, and
// it contains only lower-cased MIME type strings and file extensions.
WebVector<WebString> accept_types;
- // |selectedFiles| has filenames which a file upload control already selected.
- // A WebViewClient implementation may ask a user to select
+ // |selected_files| has filenames which a file upload control already
+ // selected. A WebLocalFrameClient implementation may ask a user to select
// - removing a file from the selected files,
// - appending other files, or
// - replacing with other files
// before opening a file chooser dialog.
WebVector<WebString> selected_files;
// See http://www.w3.org/TR/html-media-capture/ for the semantics of the
- // capture attribute. If |useMediaCapture| is true, the media types
- // indicated in |acceptTypes| should be obtained from the device's
- // environment using a media capture mechanism. |capture| is deprecated and
- // provided for compatibility reasons.
- WebString capture;
+ // capture attribute. If |use_media_capture| is true, the media types
+ // indicated in |accept_types| should be obtained from the device's
+ // environment using a media capture mechanism.
bool use_media_capture;
// Whether WebFileChooserCompletion needs local paths or not. If the result
// of file chooser is handled by the implementation of
diff --git a/chromium/third_party/blink/public/web/web_find_options.h b/chromium/third_party/blink/public/web/web_find_options.h
index 0e7d2319425..68fd1a00dd3 100644
--- a/chromium/third_party/blink/public/web/web_find_options.h
+++ b/chromium/third_party/blink/public/web/web_find_options.h
@@ -46,25 +46,20 @@ struct WebFindOptions {
// Whether this operation is the first request or a follow-up.
bool find_next;
- // Whether this operation should look for matches only at the start of words.
- bool word_start;
-
- // When combined with wordStart, accepts a match in the middle of a word if
- // the match begins with an uppercase letter followed by a lowercase or
- // non-letter. Accepts several other intra-word matches.
- bool medial_capital_as_word_start;
-
// Force a re-search of the frame: typically used when forcing a re-search
// after the frame navigates.
bool force;
+ // Signifies whether we should force text scoping to happen immediately
+ // or not. Only used for testing purposes.
+ bool run_synchronously_for_testing;
+
WebFindOptions()
: forward(true),
match_case(false),
find_next(false),
- word_start(false),
- medial_capital_as_word_start(false),
- force(false) {}
+ force(false),
+ run_synchronously_for_testing(false) {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/public/web/web_frame_widget.h b/chromium/third_party/blink/public/web/web_frame_widget.h
index 8e0f20151ca..5c1a414a0a4 100644
--- a/chromium/third_party/blink/public/web/web_frame_widget.h
+++ b/chromium/third_party/blink/public/web/web_frame_widget.h
@@ -116,10 +116,11 @@ class WebFrameWidget : public WebWidget {
// ended.
virtual void DragSourceSystemDragEnded() = 0;
- // Constrains the viewport intersection for use by IntersectionObserver.
- // This is needed for out-of-process iframes to know if they are clipped
- // by ancestor frames in another process.
- virtual void SetRemoteViewportIntersection(const WebRect&) {}
+ // Constrains the viewport intersection for use by IntersectionObserver,
+ // and indicates whether the frame may be painted over or obscured in the
+ // parent. This is needed for out-of-process iframes to know if they are
+ // clipped or obscured by ancestor frames in another process.
+ virtual void SetRemoteViewportIntersection(const WebRect&, bool) {}
// Sets the inert bit on an out-of-process iframe, causing it to ignore
// input.
diff --git a/chromium/third_party/blink/public/web/web_hit_test_result.h b/chromium/third_party/blink/public/web/web_hit_test_result.h
index c88ba0683ab..72645e2c24d 100644
--- a/chromium/third_party/blink/public/web/web_hit_test_result.h
+++ b/chromium/third_party/blink/public/web/web_hit_test_result.h
@@ -56,6 +56,10 @@ class WebHitTestResult {
// Coordinates of the point that was hit. Relative to the node.
BLINK_EXPORT WebPoint LocalPoint() const;
+ // Coordinates of the point that was hit. Relative to the node, but with
+ // ContentBoxOffset removed if the node has box layout.
+ BLINK_EXPORT WebPoint LocalPointWithoutContentBoxOffset() const;
+
// If a link (eg. anchor or area tag) is hit, return the element.
// Return null otheriwse.
BLINK_EXPORT WebElement UrlElement() const;
diff --git a/chromium/third_party/blink/public/web/web_ime_text_span.h b/chromium/third_party/blink/public/web/web_ime_text_span.h
index fe790f8d2e4..ddc47575a84 100644
--- a/chromium/third_party/blink/public/web/web_ime_text_span.h
+++ b/chromium/third_party/blink/public/web/web_ime_text_span.h
@@ -34,7 +34,7 @@
#include <string>
#include <vector>
-#include "services/ui/public/interfaces/ime/ime.mojom-shared.h"
+#include "services/ws/public/mojom/ime/ime.mojom-shared.h"
#include "third_party/skia/include/core/SkColor.h"
namespace blink {
@@ -58,7 +58,7 @@ struct WebImeTextSpan {
: type(Type::kComposition),
start_offset(0),
end_offset(0),
- thickness(ui::mojom::ImeTextSpanThickness::kThin),
+ thickness(ws::mojom::ImeTextSpanThickness::kThin),
background_color(0),
suggestion_highlight_color(0),
suggestions(std::vector<std::string>()) {}
@@ -67,7 +67,7 @@ struct WebImeTextSpan {
Type ty,
unsigned s,
unsigned e,
- ui::mojom::ImeTextSpanThickness th,
+ ws::mojom::ImeTextSpanThickness th,
SkColor bc,
SkColor shc = 0,
const std::vector<std::string>& su = std::vector<std::string>())
@@ -91,7 +91,7 @@ struct WebImeTextSpan {
unsigned start_offset;
unsigned end_offset;
SkColor underline_color = SK_ColorTRANSPARENT;
- ui::mojom::ImeTextSpanThickness thickness;
+ ws::mojom::ImeTextSpanThickness thickness;
SkColor background_color;
SkColor suggestion_highlight_color;
std::vector<std::string> suggestions;
diff --git a/chromium/third_party/blink/public/web/web_local_frame.h b/chromium/third_party/blink/public/web/web_local_frame.h
index 437e8b22c0f..e2f071b74c1 100644
--- a/chromium/third_party/blink/public/web/web_local_frame.h
+++ b/chromium/third_party/blink/public/web/web_local_frame.h
@@ -27,7 +27,7 @@
#include "third_party/blink/public/web/web_frame_load_type.h"
#include "third_party/blink/public/web/web_history_item.h"
#include "third_party/blink/public/web/web_ime_text_span.h"
-#include "third_party/blink/public/web/web_navigation_timings.h"
+#include "third_party/blink/public/web/web_navigation_params.h"
#include "third_party/blink/public/web/web_text_direction.h"
#include "v8/include/v8.h"
@@ -46,7 +46,6 @@ class WebLocalFrameClient;
class WebFrameWidget;
class WebInputMethodController;
class WebPerformance;
-class WebPlugin;
class WebRange;
class WebSecurityOrigin;
class WebScriptExecutionCallback;
@@ -60,6 +59,7 @@ enum class WebTreeScopeType;
struct WebAssociatedURLLoaderOptions;
struct WebConsoleMessage;
struct WebContentSecurityPolicyViolation;
+struct WebNavigationParams;
struct WebFindOptions;
struct WebMediaPlayerAction;
struct WebPrintParams;
@@ -216,8 +216,8 @@ class WebLocalFrame : public WebFrame {
const WebHistoryItem&,
bool is_client_redirect,
const base::UnguessableToken& devtools_navigation_token,
- std::unique_ptr<WebDocumentLoader::ExtraData> extra_data,
- const WebNavigationTimings& navigation_timings) = 0;
+ std::unique_ptr<WebNavigationParams> navigation_params,
+ std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) = 0;
// Commits a same-document navigation in the frame. For history navigations, a
// valid WebHistoryItem should be provided. Returns CommitResult::Ok if the
@@ -239,14 +239,17 @@ class WebLocalFrame : public WebFrame {
const WebURL& unreachable_url = WebURL(),
bool replace = false) = 0;
- // Navigates to the given data with specific mime type and optional text
- // encoding. For HTML data, baseURL indicates the security origin of
- // the document and is used to resolve links. If specified,
- // unreachableURL is reported via WebDocumentLoader::unreachableURL. If
- // replace is false, then this data will be loaded as a normal
- // navigation. Otherwise, the current history item will be replaced.
+ // Calls CommitDataNavigationWithRequest with a WebURLRequest that is built
+ // either 1) based on the previous, provisional request (if |replace| is true
+ // and |unreachable_url| is present) or 2) constructed from scratch otherwise.
+ //
+ // |base_url| indicates the security origin and is used to resolve links in
+ // the committed document.
+ //
+ // Please see documentation of CommitDataNavigationWithRequest for description
+ // of other parameters.
virtual void CommitDataNavigation(
- const WebData&,
+ const WebData& data,
const WebString& mime_type,
const WebString& text_encoding,
const WebURL& base_url,
@@ -255,8 +258,33 @@ class WebLocalFrame : public WebFrame {
WebFrameLoadType,
const WebHistoryItem&,
bool is_client_redirect,
- std::unique_ptr<WebDocumentLoader::ExtraData> navigation_data,
- const WebNavigationTimings& navigation_timings) = 0;
+ std::unique_ptr<WebNavigationParams> navigation_params,
+ std::unique_ptr<WebDocumentLoader::ExtraData> navigation_data) = 0;
+
+ // Navigates to the given |data| with specified |mime_type| and optional
+ // |text_encoding|.
+ //
+ // If specified, |unreachable_url| is reported via
+ // WebDocumentLoader::UnreachableURL.
+ //
+ // If |replace| is false, then this data will be loaded as a normal
+ // navigation. Otherwise, the current history item will be replaced.
+ //
+ // This method can be called instead of CommitDataNavigation when a
+ // ResourceRequest has already been precomputed (e.g. when trying to commit an
+ // error page, while mimicking the original failed request).
+ virtual void CommitDataNavigationWithRequest(
+ const WebURLRequest&,
+ const WebData&,
+ const WebString& mime_type,
+ const WebString& text_encoding,
+ const WebURL& unreachable_url,
+ bool replace,
+ WebFrameLoadType,
+ const WebHistoryItem&,
+ bool is_client_redirect,
+ std::unique_ptr<WebNavigationParams> navigation_params,
+ std::unique_ptr<WebDocumentLoader::ExtraData> navigation_data) = 0;
// Returns the document loader that is currently loading. May be null.
virtual WebDocumentLoader* GetProvisionalDocumentLoader() const = 0;
@@ -651,12 +679,6 @@ class WebLocalFrame : public WebFrame {
// Find-in-page -----------------------------------------------------------
- // Begins a find request, which includes finding the next find match (using
- // find()) and scoping the frame for find matches if needed.
- virtual void RequestFind(int identifier,
- const WebString& search_text,
- const WebFindOptions&) = 0;
-
// Searches a frame for a given string.
//
// If a match is found, this function will select it (scrolling down to
@@ -686,8 +708,6 @@ class WebLocalFrame : public WebFrame {
// default behavior will be restored.
virtual void SetTickmarks(const WebVector<WebRect>&) = 0;
- virtual WebPlugin* GetWebPluginForFind() = 0;
-
// Context menu -----------------------------------------------------------
// Returns the node that the context menu opened over.
diff --git a/chromium/third_party/blink/public/web/web_local_frame_client.h b/chromium/third_party/blink/public/web/web_local_frame_client.h
index cdb5e79443e..ce42ab89a09 100644
--- a/chromium/third_party/blink/public/web/web_local_frame_client.h
+++ b/chromium/third_party/blink/public/web/web_local_frame_client.h
@@ -332,8 +332,6 @@ class BLINK_EXPORT WebLocalFrameClient {
// defaultPolicy should just be returned.
struct NavigationPolicyInfo {
- WebDocumentLoader::ExtraData* extra_data;
-
// Note: if browser side navigations are enabled, the client may modify
// the urlRequest. However, should this happen, the client should change
// the WebNavigationPolicy to WebNavigationPolicyIgnore, and the load
@@ -352,6 +350,7 @@ class BLINK_EXPORT WebLocalFrameClient {
WebContentSecurityPolicyDisposition
should_check_main_world_content_security_policy;
mojo::ScopedMessagePipeHandle blob_url_token;
+ base::TimeTicks input_start;
// Specify whether or not a MHTML Archive can be used to load a subframe
// resource instead of doing a network request.
@@ -359,8 +358,7 @@ class BLINK_EXPORT WebLocalFrameClient {
ArchiveStatus archive_status;
explicit NavigationPolicyInfo(WebURLRequest& url_request)
- : extra_data(nullptr),
- url_request(url_request),
+ : url_request(url_request),
navigation_type(kWebNavigationTypeOther),
default_policy(kWebNavigationPolicyIgnore),
replaces_current_history_item(false),
@@ -699,25 +697,6 @@ class BLINK_EXPORT WebLocalFrameClient {
WebScrollDirection direction,
WebScrollGranularity granularity) {}
- // Find-in-page notifications ------------------------------------------
-
- // Notifies how many matches have been found in this frame so far, for a
- // given identifier. |finalUpdate| specifies whether this is the last
- // update for this frame.
- virtual void ReportFindInPageMatchCount(int identifier,
- int count,
- bool final_update) {}
-
- // Notifies what tick-mark rect is currently selected. The given
- // identifier lets the client know which request this message belongs
- // to, so that it can choose to ignore the message if it has moved on
- // to other things. The selection rect is expected to have coordinates
- // relative to the top left corner of the web page area and represent
- // where on the screen the selection rect is currently located.
- virtual void ReportFindInPageSelection(int identifier,
- int active_match_ordinal,
- const WebRect& selection) {}
-
// MediaStream -----------------------------------------------------
// A new WebRTCPeerConnectionHandler is created.
@@ -841,6 +820,15 @@ class BLINK_EXPORT WebLocalFrameClient {
CreateWebSocketHandshakeThrottle() {
return nullptr;
}
+
+ // 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.
+ virtual bool IsPluginHandledExternally(const WebElement& plugin_element,
+ const WebURL& url,
+ const WebString& suggested_mime_type) {
+ return false;
+ }
};
} // namespace blink
diff --git a/chromium/third_party/blink/public/web/web_navigation_params.h b/chromium/third_party/blink/public/web/web_navigation_params.h
new file mode 100644
index 00000000000..3ab4c5bd757
--- /dev/null
+++ b/chromium/third_party/blink/public/web/web_navigation_params.h
@@ -0,0 +1,30 @@
+// 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_PUBLIC_WEB_WEB_NAVIGATION_PARAMS_H_
+#define THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_NAVIGATION_PARAMS_H_
+
+#include <memory>
+
+#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_network_provider.h"
+#include "third_party/blink/public/platform/web_source_location.h"
+#include "third_party/blink/public/web/web_navigation_timings.h"
+
+namespace blink {
+
+// This structure holds all information provided by the embedder that is
+// needed for blink to load a Document. This is hence different from
+// WebDocumentLoader::ExtraData, which is an opaque structure stored in the
+// DocumentLoader and used by the embedder.
+struct WebNavigationParams {
+ WebNavigationTimings navigation_timings;
+ WebSourceLocation source_location;
+ bool is_user_activated = false;
+ std::unique_ptr<blink::WebServiceWorkerNetworkProvider>
+ service_worker_network_provider;
+};
+
+} // namespace blink
+
+#endif
diff --git a/chromium/third_party/blink/public/web/web_navigation_timings.h b/chromium/third_party/blink/public/web/web_navigation_timings.h
index cfa6a701b12..f942a510b0d 100644
--- a/chromium/third_party/blink/public/web/web_navigation_timings.h
+++ b/chromium/third_party/blink/public/web/web_navigation_timings.h
@@ -10,6 +10,7 @@
namespace blink {
struct WebNavigationTimings {
+ base::TimeTicks input_start;
base::TimeTicks navigation_start;
base::TimeTicks redirect_start;
base::TimeTicks redirect_end;
diff --git a/chromium/third_party/blink/public/web/web_performance.h b/chromium/third_party/blink/public/web/web_performance.h
index 7a399814541..e6af94667ff 100644
--- a/chromium/third_party/blink/public/web/web_performance.h
+++ b/chromium/third_party/blink/public/web/web_performance.h
@@ -64,6 +64,7 @@ class WebPerformance {
BLINK_EXPORT WebNavigationType GetNavigationType() const;
// These functions return time in seconds (not milliseconds) since the epoch.
+ BLINK_EXPORT double InputForNavigationStart() const;
BLINK_EXPORT double NavigationStart() const;
BLINK_EXPORT double UnloadEventEnd() const;
BLINK_EXPORT double RedirectStart() const;
diff --git a/chromium/third_party/blink/public/web/web_plugin_container.h b/chromium/third_party/blink/public/web/web_plugin_container.h
index b85272a8e59..2060c5a3850 100644
--- a/chromium/third_party/blink/public/web/web_plugin_container.h
+++ b/chromium/third_party/blink/public/web/web_plugin_container.h
@@ -138,6 +138,11 @@ class WebPluginContainer {
// Sets |this| as find handler for the associated frame.
virtual void UsePluginAsFindHandler() = 0;
+ virtual void ReportFindInPageMatchCount(int identifier,
+ int total,
+ bool final_update) = 0;
+ virtual void ReportFindInPageSelection(int identifier, int index) = 0;
+
virtual float DeviceScaleFactor() = 0;
virtual float PageScaleFactor() = 0;
virtual float PageZoomFactor() = 0;
diff --git a/chromium/third_party/blink/public/web/web_print_params.h b/chromium/third_party/blink/public/web/web_print_params.h
index 11ec70a8d13..1809e2574e3 100644
--- a/chromium/third_party/blink/public/web/web_print_params.h
+++ b/chromium/third_party/blink/public/web/web_print_params.h
@@ -49,7 +49,7 @@ struct WebPrintParams {
WebSize paper_size;
// Specifies user selected DPI for printing.
- int printer_dpi;
+ int printer_dpi = 72;
// Specifies the scale factor in percent. 100 is 1:1 (default scaling).
int scale_factor = 100;
@@ -59,48 +59,26 @@ struct WebPrintParams {
// Specifies whether to reduce/enlarge/retain the print contents to fit the
// printable area. (This is used only by plugin printing).
- WebPrintScalingOption print_scaling_option;
+ WebPrintScalingOption print_scaling_option =
+ kWebPrintScalingOptionFitToPrintableArea;
// Specifies whether printing layout needs to be applied.
- bool use_printing_layout;
+ bool use_printing_layout = true;
// Specifies how many pages per sheet. This parameter is for N-up mode.
- size_t pages_per_sheet;
+ size_t pages_per_sheet = 1;
- WebPrintParams()
- : printer_dpi(72),
- print_scaling_option(kWebPrintScalingOptionFitToPrintableArea),
- use_printing_layout(true),
- pages_per_sheet(1) {}
+ WebPrintParams() = default;
WebPrintParams(const WebSize& paper_size)
: WebPrintParams(paper_size, true) {}
WebPrintParams(const WebSize& paper_size, bool use_printing_layout)
: print_content_area(WebRect(0, 0, paper_size.width, paper_size.height)),
- printable_area(WebRect(0, 0, paper_size.width, paper_size.height)),
+ printable_area(print_content_area),
paper_size(paper_size),
- printer_dpi(72),
print_scaling_option(kWebPrintScalingOptionSourceSize),
- use_printing_layout(use_printing_layout),
- pages_per_sheet(1) {}
-
- WebPrintParams(const WebRect& print_content_area,
- const WebRect& printable_area,
- const WebSize& paper_size,
- int printer_dpi,
- int scale_factor,
- WebPrintScalingOption print_scaling_option,
- bool use_printing_layout,
- int pages_per_sheet)
- : print_content_area(print_content_area),
- printable_area(printable_area),
- paper_size(paper_size),
- printer_dpi(printer_dpi),
- scale_factor(scale_factor),
- print_scaling_option(print_scaling_option),
- use_printing_layout(use_printing_layout),
- pages_per_sheet(pages_per_sheet) {}
+ use_printing_layout(use_printing_layout) {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/public/web/web_remote_frame_client.h b/chromium/third_party/blink/public/web/web_remote_frame_client.h
index afefb61736c..de85c479a3c 100644
--- a/chromium/third_party/blink/public/web/web_remote_frame_client.h
+++ b/chromium/third_party/blink/public/web/web_remote_frame_client.h
@@ -13,8 +13,6 @@
#include "third_party/blink/public/web/web_frame.h"
namespace blink {
-enum class ClientRedirectPolicy;
-enum class WebFrameLoadType;
class WebURLRequest;
struct WebRect;
@@ -42,13 +40,13 @@ class WebRemoteFrameClient {
virtual void Navigate(const WebURLRequest& request,
bool should_replace_current_entry,
mojo::ScopedMessagePipeHandle blob_url_token) {}
- virtual void Reload(WebFrameLoadType, ClientRedirectPolicy) {}
virtual void FrameRectsChanged(const WebRect& local_frame_rect,
const WebRect& screen_space_rect) {}
virtual void UpdateRemoteViewportIntersection(
- const WebRect& viewport_intersection) {}
+ const WebRect& viewport_intersection,
+ bool occluded_or_obscured) {}
virtual void VisibilityChanged(bool visible) {}
diff --git a/chromium/third_party/blink/public/web/web_security_policy.h b/chromium/third_party/blink/public/web/web_security_policy.h
index e5f6f270e3d..6e1673cf639 100644
--- a/chromium/third_party/blink/public/web/web_security_policy.h
+++ b/chromium/third_party/blink/public/web/web_security_policy.h
@@ -64,36 +64,21 @@ class WebSecurityPolicy {
BLINK_EXPORT static void RegisterURLSchemeAsFirstPartyWhenTopLevel(
const WebString&);
- // Support for whitelisting access to origins beyond the same-origin policy.
- BLINK_EXPORT static void AddOriginAccessWhitelistEntry(
+ // Support for managing allow/block access lists to origins beyond the
+ // same-origin policy. The block list takes priority over the allow list.
+ BLINK_EXPORT static void AddOriginAccessAllowListEntry(
const WebURL& source_origin,
const WebString& destination_protocol,
const WebString& destination_host,
bool allow_destination_subdomains);
- BLINK_EXPORT static void RemoveOriginAccessWhitelistEntry(
- const WebURL& source_origin,
- const WebString& destination_protocol,
- const WebString& destination_host,
- bool allow_destination_subdomains);
- BLINK_EXPORT static void RemoveAllOriginAccessWhitelistEntriesForOrigin(
+ BLINK_EXPORT static void ClearOriginAccessAllowListForOrigin(
const WebURL& source_origin);
- BLINK_EXPORT static void ResetOriginAccessWhitelists();
-
- // Support for restricting the whitelists, in order to allow for broad
- // whitelist access (e.g., "chromium.org") while protecting a subset of hosts
- // (e.g., "secure.chromium.org"). If an origin is in both the whitelist and
- // the blacklist, it is disallowed access.
- BLINK_EXPORT static void AddOriginAccessBlacklistEntry(
+ BLINK_EXPORT static void ClearOriginAccessAllowList();
+ BLINK_EXPORT static void AddOriginAccessBlockListEntry(
const WebURL& source_origin,
const WebString& destination_protocol,
const WebString& destination_host,
bool disallow_destination_subdomains);
- BLINK_EXPORT static void RemoveOriginAccessBlacklistEntry(
- const WebURL& source_origin,
- const WebString& destination_protocol,
- const WebString& destination_host,
- bool allow_destination_subdomains);
- BLINK_EXPORT static void ResetOriginAccessBlacklists();
// Support for whitelisting origins or hostname patterns to treat them as
// trustworthy. This method does not do any canonicalization; the caller is
diff --git a/chromium/third_party/blink/public/web/web_settings.h b/chromium/third_party/blink/public/web/web_settings.h
index 5c7b6cb74ae..e39112b0256 100644
--- a/chromium/third_party/blink/public/web/web_settings.h
+++ b/chromium/third_party/blink/public/web/web_settings.h
@@ -134,7 +134,6 @@ class WebSettings {
// contents at an insecure URL. Otherwise, disallows it. The
// LocalFrameClient set to the frame may override the value set by this
// method.
- virtual void SetAccessibilityEnabled(bool) = 0;
virtual void SetAccessibilityPasswordValuesEnabled(bool) = 0;
virtual void SetAllowFileAccessFromFileURLs(bool) = 0;
virtual void SetAllowCustomScrollbarInMainFrame(bool) = 0;
@@ -171,15 +170,13 @@ class WebSettings {
virtual void SetEnableScrollAnimator(bool) = 0;
virtual void SetEnableTouchAdjustment(bool) = 0;
virtual void SetSmoothScrollForFindEnabled(bool) = 0;
- virtual bool MultiTargetTapNotificationEnabled() = 0;
- virtual void SetMultiTargetTapNotificationEnabled(bool) = 0;
virtual void SetWebGL1Enabled(bool) = 0;
virtual void SetWebGL2Enabled(bool) = 0;
virtual void SetFantasyFontFamily(const WebString&,
UScriptCode = USCRIPT_COMMON) = 0;
virtual void SetFixedFontFamily(const WebString&,
UScriptCode = USCRIPT_COMMON) = 0;
- virtual void SetFMPNetworkQuietTimeout(double timeout) = 0;
+ virtual void SetNetworkQuietTimeout(double timeout) = 0;
virtual void SetForceMainWorldInitialization(bool) = 0;
virtual void SetForcePreloadNoneForMediaElements(bool) = 0;
virtual void SetForceZeroLayoutHeight(bool) = 0;
@@ -306,6 +303,12 @@ class WebSettings {
virtual void SetLazyFrameLoadingDistanceThresholdPx2G(int) = 0;
virtual void SetLazyFrameLoadingDistanceThresholdPx3G(int) = 0;
virtual void SetLazyFrameLoadingDistanceThresholdPx4G(int) = 0;
+ virtual void SetLazyImageLoadingDistanceThresholdPxUnknown(int) = 0;
+ virtual void SetLazyImageLoadingDistanceThresholdPxOffline(int) = 0;
+ virtual void SetLazyImageLoadingDistanceThresholdPxSlow2G(int) = 0;
+ virtual void SetLazyImageLoadingDistanceThresholdPx2G(int) = 0;
+ virtual void SetLazyImageLoadingDistanceThresholdPx3G(int) = 0;
+ virtual void SetLazyImageLoadingDistanceThresholdPx4G(int) = 0;
protected:
~WebSettings() = default;
diff --git a/chromium/third_party/blink/public/web/web_user_media_request.h b/chromium/third_party/blink/public/web/web_user_media_request.h
index f7d6242f6db..0196f53f6f5 100644
--- a/chromium/third_party/blink/public/web/web_user_media_request.h
+++ b/chromium/third_party/blink/public/web/web_user_media_request.h
@@ -60,6 +60,11 @@ class BLINK_EXPORT WebUserMediaRequest {
kKillSwitchOn
};
+ enum class MediaType {
+ kUserMedia,
+ kDisplayMedia,
+ };
+
WebUserMediaRequest() = default;
WebUserMediaRequest(const WebUserMediaRequest& request) { Assign(request); }
~WebUserMediaRequest() { Reset(); }
@@ -74,6 +79,7 @@ class BLINK_EXPORT WebUserMediaRequest {
bool Equals(const WebUserMediaRequest&) const;
void Assign(const WebUserMediaRequest&);
+ MediaType MediaRequestType() const;
bool Audio() const;
bool Video() const;
WebMediaConstraints AudioConstraints() const;
diff --git a/chromium/third_party/blink/public/web/web_view.h b/chromium/third_party/blink/public/web/web_view.h
index fcba3388093..bafddd24135 100644
--- a/chromium/third_party/blink/public/web/web_view.h
+++ b/chromium/third_party/blink/public/web/web_view.h
@@ -72,6 +72,7 @@ class WebView : protected WebWidget {
// WebWidget overrides.
using WebWidget::Close;
+ using WebWidget::LifecycleUpdate;
using WebWidget::Size;
using WebWidget::Resize;
using WebWidget::ResizeVisualViewport;
@@ -79,8 +80,8 @@ class WebView : protected WebWidget {
using WebWidget::DidExitFullscreen;
using WebWidget::BeginFrame;
using WebWidget::UpdateAllLifecyclePhases;
+ using WebWidget::UpdateLifecycle;
using WebWidget::PaintContent;
- using WebWidget::PaintContentIgnoringCompositing;
using WebWidget::LayoutAndPaintAsync;
using WebWidget::CompositeAndReadbackAsync;
using WebWidget::ThemeChanged;
@@ -191,11 +192,6 @@ class WebView : protected WebWidget {
WebRemoteFrame* from,
WebLocalFrame* to) {}
- // Animate a scale into the specified rect where multiple targets were
- // found from previous tap gesture.
- // Returns false if it doesn't do any zooming.
- virtual bool ZoomToMultipleTargetsRect(const WebRect&) = 0;
-
// Zoom ----------------------------------------------------------------
// Returns the current zoom level. 0 is "original size", and each increment
@@ -234,6 +230,11 @@ class WebView : protected WebWidget {
// Scales the page without affecting layout by using the visual viewport.
virtual void SetPageScaleFactor(float) = 0;
+ // Minimum and Maximum as computed as a combination of default, page defined,
+ // UA, etc. constraints.
+ virtual float MinimumPageScaleFactor() const = 0;
+ virtual float MaximumPageScaleFactor() const = 0;
+
// Sets the offset of the visual viewport within the main frame, in
// partial CSS pixels. The offset will be clamped so the visual viewport
// stays within the frame's bounds.
@@ -272,7 +273,8 @@ class WebView : protected WebWidget {
// Returns the "preferred" contents size, defined as the preferred minimum
// width of the main document's contents and the minimum height required to
// display the main document without scrollbars. The returned size has the
- // page zoom factor applied.
+ // page zoom factor applied. The lifecycle must be updated to at least layout
+ // before calling this (see: |UpdateLifecycle|).
virtual WebSize ContentsPreferredMinimumSize() = 0;
// Sets the display mode of the web app.
@@ -358,12 +360,6 @@ class WebView : protected WebWidget {
// Hides any popup (suggestions, selects...) that might be showing.
virtual void HidePopups() = 0;
- // Generate a synthetic touch event applying the result of a tap
- // disambiguation popup.
- virtual void ResolveTapDisambiguation(base::TimeTicks timestamp,
- WebPoint tap_viewport_offset,
- bool is_long_press) = 0;
-
// Visited link state --------------------------------------------------
// Tells all WebView instances to update the visited link state for the
diff --git a/chromium/third_party/blink/public/web/web_view_client.h b/chromium/third_party/blink/public/web/web_view_client.h
index 8743fd45671..3447793373c 100644
--- a/chromium/third_party/blink/public/web/web_view_client.h
+++ b/chromium/third_party/blink/public/web/web_view_client.h
@@ -150,10 +150,10 @@ class WebViewClient {
// Indicates two things:
// 1) This view may have a new layout now.
- // 2) Calling layout() is a no-op.
- // After calling WebWidget::layout(), expect to get this notification
- // unless the view did not need a layout.
- virtual void DidUpdateLayout() {}
+ // 2) Layout is up-to-date.
+ // After calling WebWidget::updateAllLifecyclePhases(), expect to get this
+ // notification unless the view did not need a layout.
+ virtual void DidUpdateMainFrameLayout() {}
// Return true to swallow the input event if the embedder will start a
// disambiguation popup
diff --git a/chromium/third_party/blink/public/web/web_widget.h b/chromium/third_party/blink/public/web/web_widget.h
index ade50b6956a..069c5313d7f 100644
--- a/chromium/third_party/blink/public/web/web_widget.h
+++ b/chromium/third_party/blink/public/web/web_widget.h
@@ -92,10 +92,10 @@ class WebWidget {
// and it may result in calls to WebWidgetClient::didInvalidateRect.
virtual void UpdateAllLifecyclePhases() { UpdateLifecycle(); }
- // Selectively runs all lifecycle phases or all phases excluding paint. The
- // latter can be used to trigger side effects of updating layout and
- // animations if painting is not required.
- enum class LifecycleUpdate { kPrePaint, kAll };
+ // By default, all phases are updated by |UpdateLifecycle| (e.g., style,
+ // layout, prepaint, paint, etc. See: document_lifecycle.h). |LifecycleUpdate|
+ // can be used to only update to a specific lifecycle phase.
+ enum class LifecycleUpdate { kLayout, kPrePaint, kAll };
virtual void UpdateLifecycle(
LifecycleUpdate requested_update = LifecycleUpdate::kAll) {}
diff --git a/chromium/third_party/blink/public/web/web_widget_client.h b/chromium/third_party/blink/public/web/web_widget_client.h
index c9bf7194f54..5baca13e07f 100644
--- a/chromium/third_party/blink/public/web/web_widget_client.h
+++ b/chromium/third_party/blink/public/web/web_widget_client.h
@@ -144,6 +144,9 @@ class WebWidgetClient {
const WebFloatSize& velocity_in_viewport,
const cc::OverscrollBehavior& behavior) {}
+ // Called to update if pointerrawmove events should be sent.
+ virtual void HasPointerRawMoveEventHandlers(bool) {}
+
// Called to update if touch events should be sent.
virtual void HasTouchEventHandlers(bool) {}
diff --git a/chromium/third_party/blink/renderer/DEPS b/chromium/third_party/blink/renderer/DEPS
index 0659cd7c48a..8e7c3e91df1 100644
--- a/chromium/third_party/blink/renderer/DEPS
+++ b/chromium/third_party/blink/renderer/DEPS
@@ -1,5 +1,6 @@
include_rules = [
"+base/auto_reset.h",
+ "+base/bit_cast.h",
"+base/callback.h",
"+base/callback_forward.h",
"+base/containers/span.h",
@@ -12,6 +13,7 @@ include_rules = [
"+base/memory/ptr_util.h",
"+base/memory/weak_ptr.h",
"+base/metrics/histogram_macros.h",
+ "+base/metrics/field_trial_params.h",
"+base/numerics/checked_math.h",
"+base/numerics/safe_conversions.h",
"+base/optional.h",
@@ -21,7 +23,8 @@ include_rules = [
"+base/stl_util.h",
"+base/sys_byteorder.h",
"+base/sys_info.h",
- "+base/task_scheduler/post_task.h",
+ "+base/task/post_task.h",
+ "+base/test/metrics/histogram_tester.h",
"+base/test/scoped_feature_list.h",
"+base/thread_annotations.h",
"+base/threading/thread_checker.h",
diff --git a/chromium/third_party/blink/renderer/README.md b/chromium/third_party/blink/renderer/README.md
index 5f1eb64bb05..e8077e302f2 100644
--- a/chromium/third_party/blink/renderer/README.md
+++ b/chromium/third_party/blink/renderer/README.md
@@ -1,6 +1,10 @@
+## Blink architecture overview
+
+See [this "How Blink works" document](https://docs.google.com/document/d/1aitSOucL0VHZa9Z2vbRJSyAIsAz24kX8LFByQ5xQnUg/edit#).
+
## `blink/renderer` directory structure
-This document describes a high-level architecture of `blink/renderer`,
+This section describes a high-level architecture of `blink/renderer`,
which contains most of the Web Platform implementation, and runs exclusively
in the renderer process.
On the other hand, [`common/`](../common) and [`public/common`](../public/common)
diff --git a/chromium/third_party/blink/renderer/bindings/IDLExtendedAttributes.md b/chromium/third_party/blink/renderer/bindings/IDLExtendedAttributes.md
index 1370c710cb3..6464d7b709e 100644
--- a/chromium/third_party/blink/renderer/bindings/IDLExtendedAttributes.md
+++ b/chromium/third_party/blink/renderer/bindings/IDLExtendedAttributes.md
@@ -1036,16 +1036,6 @@ For more information, see [RuntimeEnabledFeatures](https://code.google.com/p/chr
**FIXME:** Currently, `[OriginTrialEnabled]` can only be applied to interfaces, attributes, and constants. Methods (including those generated by `iterable`, `setlike`, `maplike`, `serializer` and `stringifier`) are not supported. See [Bug 621641](https://crbug.com/621641).
***
-### [PostMessage] _(m)_
-
-Summary: Tells the code generator to generate postMessage method used in Workers, Service Workers etc.
-
-Usage: `[PostMessage]` can be specified on methods
-
-```webidl
-[PostMessage] void postMessage(any message, optional sequence<Transferable> transfer);
-```
-
### [RaisesException] _(i, m, a)_
Summary: Tells the code generator to append an `ExceptionState&` argument when calling the Blink implementation.
diff --git a/chromium/third_party/blink/renderer/bindings/IDLExtendedAttributes.txt b/chromium/third_party/blink/renderer/bindings/IDLExtendedAttributes.txt
index ac0bab0228a..980ae477f8b 100644
--- a/chromium/third_party/blink/renderer/bindings/IDLExtendedAttributes.txt
+++ b/chromium/third_party/blink/renderer/bindings/IDLExtendedAttributes.txt
@@ -79,7 +79,6 @@ OverrideBuiltins
PartialInterfaceImplementedAs=*
PermissiveDictionaryConversion
PerWorldBindings
-PostMessage
PrimaryGlobal=|*
PutForwards=*
RaisesException=|Getter|Setter|Constructor
diff --git a/chromium/third_party/blink/renderer/bindings/bindings.gni b/chromium/third_party/blink/renderer/bindings/bindings.gni
index f58f106e41a..b192bffe269 100644
--- a/chromium/third_party/blink/renderer/bindings/bindings.gni
+++ b/chromium/third_party/blink/renderer/bindings/bindings.gni
@@ -30,6 +30,8 @@ bindings_core_v8_files =
"core/v8/binding_security.cc",
"core/v8/binding_security.h",
"core/v8/callback_promise_adapter.h",
+ "core/v8/custom_wrappable_adapter.cc",
+ "core/v8/custom_wrappable_adapter.h",
"core/v8/dictionary.cc",
"core/v8/dictionary.h",
"core/v8/dictionary_helper_for_core.cc",
@@ -110,8 +112,8 @@ bindings_core_v8_files =
"core/v8/v8_embedder_graph_builder.h",
"core/v8/v8_error_handler.cc",
"core/v8/v8_error_handler.h",
- "core/v8/v8_event_listener.cc",
- "core/v8/v8_event_listener.h",
+ "core/v8/v8_event_listener_or_event_handler.cc",
+ "core/v8/v8_event_listener_or_event_handler.h",
"core/v8/v8_event_listener_helper.cc",
"core/v8/v8_event_listener_helper.h",
"core/v8/v8_event_listener_info.h",
@@ -148,14 +150,14 @@ bindings_core_v8_files =
"core/v8/v8_v0_custom_element_lifecycle_callbacks.h",
"core/v8/v8_wasm_response_extensions.cc",
"core/v8/v8_wasm_response_extensions.h",
- "core/v8/v8_worker_or_worklet_event_listener.cc",
- "core/v8/v8_worker_or_worklet_event_listener.h",
"core/v8/window_proxy.cc",
"core/v8/window_proxy.h",
"core/v8/window_proxy_manager.cc",
"core/v8/window_proxy_manager.h",
"core/v8/worker_or_worklet_script_controller.cc",
"core/v8/worker_or_worklet_script_controller.h",
+ "core/v8/serialization/post_message_helper.cc",
+ "core/v8/serialization/post_message_helper.h",
"core/v8/serialization/serialized_color_params.cc",
"core/v8/serialization/serialized_color_params.h",
"core/v8/serialization/serialization_tag.h",
@@ -196,6 +198,7 @@ bindings_unittest_files =
"core/v8/script_promise_test.cc",
"core/v8/script_streamer_test.cc",
"core/v8/script_wrappable_marking_visitor_test.cc",
+ "core/v8/script_wrappable_v8_gc_integration_test.cc",
"core/v8/script_wrappable_visitor_test.cc",
"core/v8/to_v8_test.cc",
"core/v8/trace_wrapper_member_test.cc",
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 8648fa717cd..12af3e22fbc 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/BUILD.gn
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/BUILD.gn
@@ -23,8 +23,8 @@ bindings_core_generated_union_type_files = [
"$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_composite_operation_or_null_sequence.cc",
- "$bindings_core_v8_output_dir/composite_operation_or_composite_operation_or_null_sequence.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",
@@ -90,6 +90,8 @@ bindings_core_generated_union_type_files = [
"$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_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",
@@ -128,6 +130,8 @@ generated_core_callback_function_files = [
"$bindings_core_v8_output_dir/v8_blob_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",
@@ -146,6 +150,12 @@ generated_core_callback_function_files = [
"$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_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_void_function.cc",
"$bindings_core_v8_output_dir/v8_void_function.h",
]
@@ -257,8 +267,10 @@ source_set("testing") {
[ "//third_party/blink/renderer/core:config" ]
deps = [
- ":bindings_core_impl_generated",
+ ":bindings_core_v8_generated",
"//skia",
+ "//third_party/blink/public:generate_mojo_bindings",
+ "//third_party/blink/renderer/core:all_generators",
"//third_party/blink/renderer/platform",
"//v8",
]
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/activity_logger_test.cc b/chromium/third_party/blink/renderer/bindings/core/v8/activity_logger_test.cc
index 3b6fbe59502..bffb605aa8a 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/activity_logger_test.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/activity_logger_test.cc
@@ -90,14 +90,14 @@ class ActivityLoggerTest : public testing::Test {
void ExecuteScriptInMainWorld(const String& script) const {
v8::HandleScope scope(v8::Isolate::GetCurrent());
script_controller_->ExecuteScriptInMainWorld(script);
- PumpPendingRequestsForFrameToLoad();
+ PumpPendingRequestsForFrameToLoad(web_view_helper_.LocalMainFrame());
}
void ExecuteScriptInIsolatedWorld(const String& script) const {
v8::HandleScope scope(v8::Isolate::GetCurrent());
script_controller_->ExecuteScriptInIsolatedWorld(kIsolatedWorldId,
ScriptSourceCode(script));
- PumpPendingRequestsForFrameToLoad();
+ PumpPendingRequestsForFrameToLoad(web_view_helper_.LocalMainFrame());
}
bool VerifyActivities(const String& activities) {
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/array_value.cc b/chromium/third_party/blink/renderer/bindings/core/v8/array_value.cc
index f87b14363af..5a02a8150f7 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/array_value.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/array_value.cc
@@ -36,7 +36,7 @@ bool ArrayValue::IsUndefinedOrNull() const {
return blink::IsUndefinedOrNull(array_);
}
-bool ArrayValue::length(size_t& length) const {
+bool ArrayValue::length(uint32_t& length) const {
if (IsUndefinedOrNull())
return false;
@@ -44,7 +44,7 @@ bool ArrayValue::length(size_t& length) const {
return true;
}
-bool ArrayValue::Get(size_t index, Dictionary& value) const {
+bool ArrayValue::Get(uint32_t index, Dictionary& value) const {
if (IsUndefinedOrNull())
return false;
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/array_value.h b/chromium/third_party/blink/renderer/bindings/core/v8/array_value.h
index 2526e61c395..2b7dc711db6 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/array_value.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/array_value.h
@@ -49,8 +49,8 @@ class CORE_EXPORT ArrayValue final {
bool IsUndefinedOrNull() const;
- bool length(size_t&) const;
- bool Get(size_t index, Dictionary&) const;
+ bool length(uint32_t&) const;
+ bool Get(uint32_t index, Dictionary&) const;
private:
v8::Local<v8::Array> array_;
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_message_event_custom.cc b/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_message_event_custom.cc
index e5e6016f2f8..ff1de20e626 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_message_event_custom.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_message_event_custom.cc
@@ -59,6 +59,10 @@ void V8MessageEvent::dataAttributeGetterCustom(
v8::Local<v8::Value> result;
switch (event->GetDataType()) {
+ case MessageEvent::kDataTypeNull:
+ result = v8::Null(isolate);
+ break;
+
case MessageEvent::kDataTypeScriptValue:
result =
event->DataAsScriptValue().V8ValueFor(ScriptState::Current(isolate));
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 5871aa0a384..61a39188ccd 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
@@ -35,7 +35,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/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_or_event_handler.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_html_collection.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_node.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/custom_wrappable_adapter.cc b/chromium/third_party/blink/renderer/bindings/core/v8/custom_wrappable_adapter.cc
new file mode 100644
index 00000000000..c914e8ba00c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/custom_wrappable_adapter.cc
@@ -0,0 +1,79 @@
+// 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/bindings/core/v8/custom_wrappable_adapter.h"
+
+#include "third_party/blink/renderer/bindings/core/v8/v8_dom_configuration.h"
+#include "third_party/blink/renderer/platform/bindings/script_state.h"
+#include "third_party/blink/renderer/platform/bindings/v8_dom_wrapper.h"
+#include "third_party/blink/renderer/platform/bindings/wrapper_type_info.h"
+
+namespace blink {
+
+namespace {
+
+v8::Local<v8::FunctionTemplate> CreateCustomWrappableTemplate(
+ v8::Isolate* isolate,
+ const DOMWrapperWorld& world);
+
+const WrapperTypeInfo custom_wrappable_info = {
+ gin::kEmbedderBlink,
+ CreateCustomWrappableTemplate,
+ nullptr,
+ "CustomWrappableAdapter",
+ nullptr,
+ WrapperTypeInfo::kWrapperTypeNoPrototype,
+ WrapperTypeInfo::kCustomWrappableId,
+ WrapperTypeInfo::kNotInheritFromActiveScriptWrappable,
+};
+
+void InstallCustomWrappableTemplate(
+ v8::Isolate* isolate,
+ const DOMWrapperWorld& world,
+ v8::Local<v8::FunctionTemplate> interfaceTemplate) {
+ V8DOMConfiguration::InitializeDOMInterfaceTemplate(
+ isolate, interfaceTemplate, custom_wrappable_info.interface_name,
+ v8::Local<v8::FunctionTemplate>(), kV8DefaultWrapperInternalFieldCount);
+}
+
+v8::Local<v8::FunctionTemplate> CreateCustomWrappableTemplate(
+ v8::Isolate* isolate,
+ const DOMWrapperWorld& world) {
+ return V8DOMConfiguration::DomClassTemplate(
+ isolate, world, const_cast<WrapperTypeInfo*>(&custom_wrappable_info),
+ InstallCustomWrappableTemplate);
+}
+
+} // namespace
+
+CustomWrappableAdapter* CustomWrappableAdapter::LookupInternal(
+ v8::Local<v8::Object> object,
+ const V8PrivateProperty::Symbol& property) {
+ v8::Local<v8::Value> custom_wrappable_adapter_value;
+ if (!property.GetOrUndefined(object).ToLocal(&custom_wrappable_adapter_value))
+ return nullptr;
+
+ if (!custom_wrappable_adapter_value->IsUndefined()) {
+ return static_cast<CustomWrappableAdapter*>(
+ ToCustomWrappable(custom_wrappable_adapter_value.As<v8::Object>()));
+ }
+ return nullptr;
+}
+
+void CustomWrappableAdapter::Attach(ScriptState* script_state,
+ v8::Local<v8::Object> object,
+ const V8PrivateProperty::Symbol& property,
+ CustomWrappableAdapter* adapter) {
+ DCHECK(wrapper_.IsEmpty());
+ v8::Isolate* isolate = script_state->GetIsolate();
+ v8::Local<v8::Object> wrapper_object = V8DOMWrapper::CreateWrapper(
+ isolate, script_state->GetContext()->Global(), &custom_wrappable_info);
+ V8DOMWrapper::AssociateObjectWithWrapper(
+ isolate, adapter, &custom_wrappable_info, wrapper_object);
+ property.Set(object, wrapper_object);
+ wrapper_.Set(isolate, wrapper_object);
+ custom_wrappable_info.ConfigureWrapper(&wrapper_.Get());
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/custom_wrappable_adapter.h b/chromium/third_party/blink/renderer/bindings/core/v8/custom_wrappable_adapter.h
new file mode 100644
index 00000000000..2a5e4063ae7
--- /dev/null
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/custom_wrappable_adapter.h
@@ -0,0 +1,63 @@
+// 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_BINDINGS_CORE_V8_CUSTOM_WRAPPABLE_ADAPTER_H_
+#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_CUSTOM_WRAPPABLE_ADAPTER_H_
+
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/bindings/custom_wrappable.h"
+#include "third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h"
+#include "third_party/blink/renderer/platform/bindings/v8_private_property.h"
+#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "v8/include/v8.h"
+
+namespace blink {
+
+class ScriptState;
+
+// CustomWrappableAdapter establishes a link from a given JavaScript object to
+// the Blink object inheriting from CustomWrappableAdapter. The link is known to
+// garbage collectors and the lifetime of the V8 and Blink objects will be tied
+// together. The adapter can be used to model liveness across V8 and Blink
+// component boundaries. In contrast to ScriptWrappable, no IDL definitions are
+// required.
+//
+// The intended use case is binding the lifetime of a Blink object to a
+// user-provided JavaScript object.
+class CORE_EXPORT CustomWrappableAdapter : public CustomWrappable {
+ public:
+ // Lookup the CustomWrappableAdapter implementation on a given |object|'s
+ // |property|. Returns nullptr if no adapter has been attached. See Attach.
+ template <typename T>
+ static T* Lookup(v8::Local<v8::Object> object,
+ const V8PrivateProperty::Symbol& property) {
+ return static_cast<T*>(LookupInternal(object, property));
+ }
+
+ // Attaches a given |adapter| to |object|'s |property|.
+ void Attach(ScriptState*,
+ v8::Local<v8::Object> object,
+ const V8PrivateProperty::Symbol& property,
+ CustomWrappableAdapter* adapter);
+
+ ~CustomWrappableAdapter() override = default;
+
+ void Trace(Visitor* visitor) override {
+ visitor->Trace(wrapper_);
+ CustomWrappable::Trace(visitor);
+ }
+
+ private:
+ static CustomWrappableAdapter* LookupInternal(
+ v8::Local<v8::Object>,
+ const V8PrivateProperty::Symbol&);
+
+ // Internal wrapper reference is needed as Oilpan looks up its roots from V8
+ // by following all configured wrapper references.
+ TraceWrapperV8Reference<v8::Object> wrapper_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_CUSTOM_WRAPPABLE_ADAPTER_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 55f985060e4..ead42a890c9 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
@@ -58,10 +58,14 @@ bool IsCallbackFunctionRunnable(
// the incumbent context which originally schedules the currently-running
// callback to see whether the script setting is disabled before invoking
// the callback.
+ // TODO(crbug.com/608641): move IsMainWorld check into
+ // ExecutionContext::CanExecuteScripts()
return incumbent_execution_context &&
!incumbent_execution_context->IsContextPaused() &&
!incumbent_execution_context->IsContextDestroyed() &&
- incumbent_execution_context->CanExecuteScripts(kAboutToExecuteScript);
+ (!incumbent_script_state->World().IsMainWorld() ||
+ incumbent_execution_context->CanExecuteScripts(
+ kAboutToExecuteScript));
}
} // namespace blink
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 cbd9f811d97..e148eda2960 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
@@ -385,17 +385,17 @@ void LocalWindowProxy::SetSecurityToken(const SecurityOrigin* origin) {
->IsDisplayingInitialEmptyDocument() ||
origin->DomainWasSetInDOM());
if (origin && !use_default_security_token)
- token = origin->ToString();
+ token = origin->ToTokenForFastCheck();
- // 3. The ToString() method on SecurityOrigin returns the string "null" for
+ // 3. The ToTokenForFastCheck method on SecurityOrigin returns null string for
// empty security origins and for security origins that should only allow
// access to themselves (i.e. opaque origins). Using the default security
// token serves for two purposes: it allows fast-path security checks for
// accesses inside the same context, and forces a full CanAccess() check
- // for contexts that don't inherit the same origin, which will always fail.
+ // for contexts that don't inherit the same origin.
v8::HandleScope handle_scope(GetIsolate());
v8::Local<v8::Context> context = script_state_->GetContext();
- if (token.IsEmpty() || token == "null") {
+ if (token.IsNull()) {
context->UseDefaultSecurityToken();
return;
}
@@ -403,14 +403,14 @@ void LocalWindowProxy::SetSecurityToken(const SecurityOrigin* origin) {
if (world_->IsIsolatedWorld()) {
const SecurityOrigin* frame_security_origin =
GetFrame()->GetDocument()->GetSecurityOrigin();
- String frame_security_token = frame_security_origin->ToString();
+ String frame_security_token = frame_security_origin->ToTokenForFastCheck();
// We need to check the return value of domainWasSetInDOM() on the
// frame's SecurityOrigin because, if that's the case, only
// SecurityOrigin::domain_ would have been modified.
// domain_ is not used by SecurityOrigin::toString(), so we would end
// up generating the same token that was already set.
if (frame_security_origin->DomainWasSetInDOM() ||
- frame_security_token.IsEmpty() || frame_security_token == "null") {
+ frame_security_token.IsNull()) {
context->UseDefaultSecurityToken();
return;
}
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 6cf10aeb8ec..a3ef60fb95f 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
@@ -145,7 +145,9 @@ TEST(NativeValueTraitsImplTest, IDLRecord) {
EXPECT_TRUE(
V8String(scope.GetIsolate(), "bogus!")
->Equals(
- v8_exception->ToString(scope.GetContext()).ToLocalChecked()));
+ scope.GetContext(),
+ v8_exception->ToString(scope.GetContext()).ToLocalChecked())
+ .ToChecked());
}
{
v8::Local<v8::Object> v8_object = v8::Object::New(scope.GetIsolate());
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/referrer_script_info.cc b/chromium/third_party/blink/renderer/bindings/core/v8/referrer_script_info.cc
index e1ec82bd2ca..4768bf10179 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/referrer_script_info.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/referrer_script_info.cc
@@ -29,28 +29,31 @@ ReferrerScriptInfo ReferrerScriptInfo::FromV8HostDefinedOptions(
return ReferrerScriptInfo();
}
- v8::Local<v8::Primitive> base_url_value = host_defined_options->Get(kBaseURL);
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::Local<v8::Primitive> base_url_value =
+ host_defined_options->Get(isolate, kBaseURL);
String base_url_string =
ToCoreStringWithNullCheck(v8::Local<v8::String>::Cast(base_url_value));
KURL base_url = base_url_string.IsEmpty() ? KURL() : KURL(base_url_string);
DCHECK(base_url.IsNull() || base_url.IsValid());
v8::Local<v8::Primitive> credentials_mode_value =
- host_defined_options->Get(kCredentialsMode);
+ host_defined_options->Get(isolate, kCredentialsMode);
auto credentials_mode = static_cast<network::mojom::FetchCredentialsMode>(
credentials_mode_value->IntegerValue(context).ToChecked());
- v8::Local<v8::Primitive> nonce_value = host_defined_options->Get(kNonce);
+ v8::Local<v8::Primitive> nonce_value =
+ host_defined_options->Get(isolate, kNonce);
String nonce =
ToCoreStringWithNullCheck(v8::Local<v8::String>::Cast(nonce_value));
v8::Local<v8::Primitive> parser_state_value =
- host_defined_options->Get(kParserState);
+ host_defined_options->Get(isolate, kParserState);
ParserDisposition parser_state = static_cast<ParserDisposition>(
parser_state_value->IntegerValue(context).ToChecked());
v8::Local<v8::Primitive> referrer_policy_value =
- host_defined_options->Get(kReferrerPolicy);
+ host_defined_options->Get(isolate, kReferrerPolicy);
ReferrerPolicy referrer_policy = static_cast<ReferrerPolicy>(
referrer_policy_value->IntegerValue(context).ToChecked());
@@ -68,25 +71,27 @@ v8::Local<v8::PrimitiveArray> ReferrerScriptInfo::ToV8HostDefinedOptions(
v8::Local<v8::Primitive> base_url_value =
V8String(isolate, base_url_.GetString());
- host_defined_options->Set(HostDefinedOptionsIndex::kBaseURL, base_url_value);
+ host_defined_options->Set(isolate, HostDefinedOptionsIndex::kBaseURL,
+ base_url_value);
v8::Local<v8::Primitive> credentials_mode_value =
v8::Integer::NewFromUnsigned(isolate,
static_cast<uint32_t>(credentials_mode_));
- host_defined_options->Set(HostDefinedOptionsIndex::kCredentialsMode,
+ host_defined_options->Set(isolate, HostDefinedOptionsIndex::kCredentialsMode,
credentials_mode_value);
v8::Local<v8::Primitive> nonce_value = V8String(isolate, nonce_);
- host_defined_options->Set(HostDefinedOptionsIndex::kNonce, nonce_value);
+ host_defined_options->Set(isolate, HostDefinedOptionsIndex::kNonce,
+ nonce_value);
v8::Local<v8::Primitive> parser_state_value = v8::Integer::NewFromUnsigned(
isolate, static_cast<uint32_t>(parser_state_));
- host_defined_options->Set(HostDefinedOptionsIndex::kParserState,
+ host_defined_options->Set(isolate, HostDefinedOptionsIndex::kParserState,
parser_state_value);
v8::Local<v8::Primitive> referrer_policy_value = v8::Integer::NewFromUnsigned(
isolate, static_cast<uint32_t>(referrer_policy_));
- host_defined_options->Set(HostDefinedOptionsIndex::kReferrerPolicy,
+ host_defined_options->Set(isolate, HostDefinedOptionsIndex::kReferrerPolicy,
referrer_policy_value);
return host_defined_options;
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 7294894f729..d19d56b970b 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
@@ -76,7 +76,7 @@ class RejectedPromises::Message final {
script_state_, EventTypeNames::unhandledrejection, init);
// Log to console if event was not canceled.
should_log_to_console_ =
- target->DispatchEvent(event) == DispatchEventResult::kNotCanceled;
+ target->DispatchEvent(*event) == DispatchEventResult::kNotCanceled;
}
if (should_log_to_console_) {
@@ -113,7 +113,7 @@ class RejectedPromises::Message final {
init.setReason(ScriptValue(script_state_, reason));
PromiseRejectionEvent* event = PromiseRejectionEvent::Create(
script_state_, EventTypeNames::rejectionhandled, init);
- target->DispatchEvent(event);
+ target->DispatchEvent(*event);
}
if (should_log_to_console_ && promise_rejection_id_) {
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_event_listener.cc b/chromium/third_party/blink/renderer/bindings/core/v8/script_event_listener.cc
index c0f3e4751d9..3450578d7e1 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/script_event_listener.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_event_listener.cc
@@ -33,12 +33,11 @@
#include "third_party/blink/renderer/bindings/core/v8/scheduled_action.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/v8_abstract_event_listener.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_lazy_event_listener.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/dom/document_parser.h"
-#include "third_party/blink/renderer/core/dom/events/event_listener.h"
#include "third_party/blink/renderer/core/dom/qualified_name.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
@@ -46,7 +45,7 @@
namespace blink {
-V8LazyEventListener* CreateAttributeEventListener(
+EventListener* CreateAttributeEventListener(
Node* node,
const QualifiedName& name,
const AtomicString& value,
@@ -74,7 +73,7 @@ V8LazyEventListener* CreateAttributeEventListener(
isolate);
}
-V8LazyEventListener* CreateAttributeEventListener(
+EventListener* CreateAttributeEventListener(
LocalFrame* frame,
const QualifiedName& name,
const AtomicString& value,
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_event_listener.h b/chromium/third_party/blink/renderer/bindings/core/v8/script_event_listener.h
index 2ce7ca60a47..f55adff7187 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/script_event_listener.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_event_listener.h
@@ -33,23 +33,20 @@
#include <memory>
-#include "third_party/blink/renderer/bindings/core/v8/v8_lazy_event_listener.h"
+#include "third_party/blink/renderer/core/dom/events/event_listener.h"
namespace blink {
-class EventListener;
-class ExecutionContext;
class LocalFrame;
-class Node;
class QualifiedName;
class SourceLocation;
-V8LazyEventListener* CreateAttributeEventListener(
+EventListener* CreateAttributeEventListener(
Node*,
const QualifiedName&,
const AtomicString& value,
const AtomicString& event_parameter_name);
-V8LazyEventListener* CreateAttributeEventListener(
+EventListener* CreateAttributeEventListener(
LocalFrame*,
const QualifiedName&,
const AtomicString& value,
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 47dad5beec1..f9f16efb1f5 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
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/bindings/core/v8/script_function.h"
#include "third_party/blink/renderer/platform/bindings/v8_binding.h"
+#include "third_party/blink/renderer/platform/wtf/assertions.h"
namespace blink {
@@ -26,6 +27,16 @@ v8::Local<v8::Function> ScriptFunction::BindToV8Function() {
.ToLocalChecked();
}
+ScriptValue ScriptFunction::Call(ScriptValue) {
+ NOTREACHED();
+ return ScriptValue();
+}
+
+void ScriptFunction::CallRaw(const v8::FunctionCallbackInfo<v8::Value>& args) {
+ ScriptValue result = Call(ScriptValue(GetScriptState(), args[0]));
+ V8SetReturnValue(args, result.V8Value());
+}
+
void ScriptFunction::CallCallback(
const v8::FunctionCallbackInfo<v8::Value>& args) {
DCHECK(args.Data()->IsExternal());
@@ -33,9 +44,7 @@ void ScriptFunction::CallCallback(
"Blink_CallCallback");
ScriptFunction* script_function = static_cast<ScriptFunction*>(
v8::Local<v8::External>::Cast(args.Data())->Value());
- ScriptValue result = script_function->Call(
- ScriptValue(script_function->GetScriptState(), args[0]));
- V8SetReturnValue(args, result.V8Value());
+ script_function->CallRaw(args);
}
} // namespace blink
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 54c3055c439..ef0ebb9ea3d 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
@@ -41,14 +41,13 @@ namespace blink {
// A common way of using ScriptFunction is as follows:
//
// class DerivedFunction : public ScriptFunction {
-// // This returns a V8 function which the DerivedFunction is bound to.
-// // The DerivedFunction is destructed when the V8 function is
-// // garbage-collected.
-// static v8::Local<v8::Function> createFunction(ScriptState* scriptState)
-// {
-// DerivedFunction* self = new DerivedFunction(scriptState);
-// return self->bindToV8Function();
-// }
+// // This returns a V8 function which the DerivedFunction is bound to.
+// // The DerivedFunction is destroyed when the V8 function is
+// // garbage-collected.
+// static v8::Local<v8::Function> CreateFunction(ScriptState* script_state) {
+// DerivedFunction* self = new DerivedFunction(script_state);
+// return self->BindToV8Function();
+// }
// };
class CORE_EXPORT ScriptFunction
: public GarbageCollectedFinalized<ScriptFunction> {
@@ -65,7 +64,14 @@ class CORE_EXPORT ScriptFunction
v8::Local<v8::Function> BindToV8Function();
private:
- virtual ScriptValue Call(ScriptValue) = 0;
+ // Subclasses should implement one of Call() or CallRaw(). Most will implement
+ // Call().
+ virtual ScriptValue Call(ScriptValue);
+
+ // To support more than one argument, or for low-level access to the V8 API,
+ // implement CallRaw(). The default implementation delegates to Call().
+ virtual void CallRaw(const v8::FunctionCallbackInfo<v8::Value>&);
+
static void CallCallback(const v8::FunctionCallbackInfo<v8::Value>&);
Member<ScriptState> script_state_;
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 15165c8c30e..0bde57d4c49 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
@@ -36,6 +36,7 @@
#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/instance_counters.h"
+#include "third_party/blink/renderer/platform/wtf/compiler.h"
#include "v8/include/v8.h"
namespace blink {
@@ -170,7 +171,10 @@ class PromiseAllHandler final
ScriptPromise::InternalResolver::InternalResolver(ScriptState* script_state)
: resolver_(script_state,
- v8::Promise::Resolver::New(script_state->GetContext())) {}
+ v8::Promise::Resolver::New(script_state->GetContext())) {
+ // |resolver| can be empty when the thread is being terminated. We ignore such
+ // errors.
+}
v8::Local<v8::Promise> ScriptPromise::InternalResolver::V8Promise() const {
if (resolver_.IsEmpty())
@@ -187,20 +191,26 @@ ScriptPromise ScriptPromise::InternalResolver::Promise() const {
void ScriptPromise::InternalResolver::Resolve(v8::Local<v8::Value> value) {
if (resolver_.IsEmpty())
return;
- resolver_.V8Value()
- .As<v8::Promise::Resolver>()
- ->Resolve(resolver_.GetContext(), value)
- .ToChecked();
+ v8::Maybe<bool> result =
+ resolver_.V8Value().As<v8::Promise::Resolver>()->Resolve(
+ resolver_.GetContext(), value);
+ // |result| can be empty when the thread is being terminated. We ignore such
+ // errors.
+ ALLOW_UNUSED_LOCAL(result);
+
Clear();
}
void ScriptPromise::InternalResolver::Reject(v8::Local<v8::Value> value) {
if (resolver_.IsEmpty())
return;
- resolver_.V8Value()
- .As<v8::Promise::Resolver>()
- ->Reject(resolver_.GetContext(), value)
- .ToChecked();
+ v8::Maybe<bool> result =
+ resolver_.V8Value().As<v8::Promise::Resolver>()->Reject(
+ resolver_.GetContext(), value);
+ // |result| can be empty when the thread is being terminated. We ignore such
+ // errors.
+ ALLOW_UNUSED_LOCAL(result);
+
Clear();
}
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 842ff45ebeb..4d5416c9e4d 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
@@ -49,6 +49,9 @@ class ExceptionState;
// So holding a ScriptPromise as a member variable in DOM object causes
// memory leaks since it has a reference from C++ to V8.
//
+// There are cases where promises cannot work (e.g., where the thread is being
+// terminated). In such cases operations will silently fail, so you should not
+// use promises for critical use such as releasing a resource.
class CORE_EXPORT ScriptPromise final {
DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
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 643a43dea71..c9edbdb7d0c 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
@@ -14,9 +14,6 @@ ScriptPromiseResolver::ScriptPromiseResolver(ScriptState* script_state)
: PausableObject(ExecutionContext::From(script_state)),
state_(kPending),
script_state_(script_state),
- timer_(GetExecutionContext()->GetTaskRunner(TaskType::kMicrotask),
- this,
- &ScriptPromiseResolver::OnTimerFired),
resolver_(script_state) {
if (GetExecutionContext()->IsContextDestroyed()) {
state_ = kDetached;
@@ -31,18 +28,18 @@ void ScriptPromiseResolver::Reject(ExceptionState& exception_state) {
}
void ScriptPromiseResolver::Pause() {
- timer_.Stop();
+ deferred_resolve_task_.Cancel();
}
void ScriptPromiseResolver::Unpause() {
if (state_ == kResolving || state_ == kRejecting)
- timer_.StartOneShot(TimeDelta(), FROM_HERE);
+ ScheduleResolveOrReject();
}
void ScriptPromiseResolver::Detach() {
if (state_ == kDetached)
return;
- timer_.Stop();
+ deferred_resolve_task_.Cancel();
state_ = kDetached;
resolver_.Clear();
value_.Clear();
@@ -61,17 +58,6 @@ void ScriptPromiseResolver::KeepAliveWhilePending() {
keep_alive_ = this;
}
-void ScriptPromiseResolver::OnTimerFired(TimerBase*) {
- DCHECK(state_ == kResolving || state_ == kRejecting);
- if (!GetScriptState()->ContextIsValid()) {
- Detach();
- return;
- }
-
- ScriptState::Scope scope(script_state_);
- ResolveOrRejectImmediately();
-}
-
void ScriptPromiseResolver::ResolveOrRejectImmediately() {
DCHECK(!GetExecutionContext()->IsContextDestroyed());
DCHECK(!GetExecutionContext()->IsContextPaused());
@@ -86,6 +72,24 @@ void ScriptPromiseResolver::ResolveOrRejectImmediately() {
Detach();
}
+void ScriptPromiseResolver::ScheduleResolveOrReject() {
+ deferred_resolve_task_ = PostCancellableTask(
+ *GetExecutionContext()->GetTaskRunner(TaskType::kMicrotask), FROM_HERE,
+ WTF::Bind(&ScriptPromiseResolver::ResolveOrRejectDeferred,
+ WrapPersistent(this)));
+}
+
+void ScriptPromiseResolver::ResolveOrRejectDeferred() {
+ DCHECK(state_ == kResolving || state_ == kRejecting);
+ if (!GetScriptState()->ContextIsValid()) {
+ Detach();
+ return;
+ }
+
+ ScriptState::Scope scope(script_state_);
+ ResolveOrRejectImmediately();
+}
+
void ScriptPromiseResolver::Trace(blink::Visitor* visitor) {
visitor->Trace(script_state_);
PausableObject::Trace(visitor);
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 4eb63b82905..0ab94180113 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
@@ -15,7 +15,7 @@
#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/self_keep_alive.h"
-#include "third_party/blink/renderer/platform/timer.h"
+#include "third_party/blink/renderer/platform/web_task_runner.h"
#include "v8/include/v8.h"
namespace blink {
@@ -28,6 +28,9 @@ namespace blink {
// ExecutionContext state. When the ExecutionContext is suspended,
// resolve or reject will be delayed. When it is stopped, resolve or reject
// will be ignored.
+//
+// There are cases where promises cannot work (e.g., where the thread is being
+// terminated). In such cases operations will silently fail.
class CORE_EXPORT ScriptPromiseResolver
: public GarbageCollectedFinalized<ScriptPromiseResolver>,
public PausableObject {
@@ -153,20 +156,19 @@ class CORE_EXPORT ScriptPromiseResolver
// resolve.
// See: http://crbug.com/663476
if (ScriptForbiddenScope::IsScriptForbidden()) {
- // Retain this object until it is actually resolved or rejected.
- KeepAliveWhilePending();
- timer_.StartOneShot(TimeDelta(), FROM_HERE);
+ ScheduleResolveOrReject();
return;
}
ResolveOrRejectImmediately();
}
void ResolveOrRejectImmediately();
- void OnTimerFired(TimerBase*);
+ void ScheduleResolveOrReject();
+ void ResolveOrRejectDeferred();
ResolutionState state_;
const Member<ScriptState> script_state_;
- TaskRunnerTimer<ScriptPromiseResolver> timer_;
+ TaskHandle deferred_resolve_task_;
Resolver resolver_;
ScopedPersistent<v8::Value> value_;
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 7b5bd831926..746517c5b38 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
@@ -10,7 +10,7 @@ namespace blink {
namespace {
-MovableString TreatNullSourceAsEmpty(const MovableString& source) {
+ParkableString TreatNullSourceAsEmpty(const ParkableString& source) {
// ScriptSourceCode allows for the representation of the null/not-there-really
// ScriptSourceCode value. Encoded by way of a source_.IsNull() being true,
// with the nullary constructor to be used to construct such a value.
@@ -20,7 +20,7 @@ MovableString TreatNullSourceAsEmpty(const MovableString& source) {
// between such null string occurrences. Do that by converting the latter
// case's null strings into empty ones.
if (source.IsNull())
- return MovableString();
+ return ParkableString();
return source;
}
@@ -49,13 +49,14 @@ String SourceMapUrlFromResponse(const ResourceResponse& response) {
} // namespace
ScriptSourceCode::ScriptSourceCode(
- const MovableString& source,
+ const ParkableString& source,
ScriptSourceLocationType source_location_type,
SingleCachedMetadataHandler* cache_handler,
const KURL& url,
const TextPosition& start_position)
: source_(TreatNullSourceAsEmpty(source)),
cache_handler_(cache_handler),
+ not_streaming_reason_(ScriptStreamer::kInlineScript),
url_(StripFragmentIdentifier(url)),
start_position_(start_position),
source_location_type_(source_location_type) {
@@ -69,21 +70,25 @@ ScriptSourceCode::ScriptSourceCode(
SingleCachedMetadataHandler* cache_handler,
const KURL& url,
const TextPosition& start_position)
- : ScriptSourceCode(MovableString(source.Impl()),
+ : ScriptSourceCode(ParkableString(source.Impl()),
source_location_type,
cache_handler,
url,
start_position) {}
ScriptSourceCode::ScriptSourceCode(ScriptStreamer* streamer,
- ScriptResource* resource)
+ ScriptResource* resource,
+ ScriptStreamer::NotStreamingReason reason)
: source_(TreatNullSourceAsEmpty(resource->SourceText())),
cache_handler_(resource->CacheHandler()),
streamer_(streamer),
+ not_streaming_reason_(reason),
url_(StripFragmentIdentifier(resource->GetResponse().Url())),
source_map_url_(SourceMapUrlFromResponse(resource->GetResponse())),
start_position_(TextPosition::MinimumPosition()),
- source_location_type_(ScriptSourceLocationType::kExternalFile) {}
+ source_location_type_(ScriptSourceLocationType::kExternalFile) {
+ DCHECK_EQ(!streamer, reason != ScriptStreamer::NotStreamingReason::kInvalid);
+}
ScriptSourceCode::~ScriptSourceCode() = default;
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 0dde36ca293..04a6480225a 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
@@ -34,9 +34,9 @@
#include "third_party/blink/renderer/bindings/core/v8/script_source_location_type.h"
#include "third_party/blink/renderer/bindings/core/v8/script_streamer.h"
#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/bindings/parkable_string.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/text/movable_string.h"
#include "third_party/blink/renderer/platform/wtf/text/text_position.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -58,7 +58,7 @@ class CORE_EXPORT ScriptSourceCode final {
const TextPosition& = TextPosition::MinimumPosition());
ScriptSourceCode(
- const MovableString& source,
+ const ParkableString& source,
ScriptSourceLocationType = ScriptSourceLocationType::kUnknown,
SingleCachedMetadataHandler* cache_handler = nullptr,
const KURL& = KURL(),
@@ -68,12 +68,14 @@ class CORE_EXPORT ScriptSourceCode final {
//
// We lose the encoding information from ScriptResource.
// Not sure if that matters.
- ScriptSourceCode(ScriptStreamer*, ScriptResource*);
+ ScriptSourceCode(ScriptStreamer*,
+ ScriptResource*,
+ ScriptStreamer::NotStreamingReason);
~ScriptSourceCode();
void Trace(blink::Visitor*);
- const MovableString& Source() const { return source_; }
+ const ParkableString& Source() const { return source_; }
SingleCachedMetadataHandler* CacheHandler() const { return cache_handler_; }
const KURL& Url() const { return url_; }
const TextPosition& StartPosition() const { return start_position_; }
@@ -83,11 +85,15 @@ class CORE_EXPORT ScriptSourceCode final {
const String& SourceMapUrl() const { return source_map_url_; }
ScriptStreamer* Streamer() const { return streamer_; }
+ ScriptStreamer::NotStreamingReason NotStreamingReason() const {
+ return not_streaming_reason_;
+ }
private:
- const MovableString source_;
+ const ParkableString source_;
Member<SingleCachedMetadataHandler> cache_handler_;
Member<ScriptStreamer> streamer_;
+ ScriptStreamer::NotStreamingReason not_streaming_reason_;
// The URL of the source code, which is primarily intended for DevTools
// javascript debugger.
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 70f3cbdd736..d2f490e8a18 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
@@ -13,12 +13,14 @@
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/html/parser/text_resource_decoder.h"
+#include "third_party/blink/renderer/core/inspector/inspector_trace_events.h"
#include "third_party/blink/renderer/core/script/classic_pending_script.h"
#include "third_party/blink/renderer/platform/cross_thread_functional.h"
-#include "third_party/blink/renderer/platform/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/loader/fetch/cached_metadata.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+#include "third_party/blink/renderer/platform/scheduler/public/background_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
#include "third_party/blink/renderer/platform/shared_buffer.h"
#include "third_party/blink/renderer/platform/wtf/deque.h"
@@ -26,84 +28,6 @@
namespace blink {
-namespace {
-
-void RecordStartedStreamingHistogram(ScriptStreamer::Type script_type,
- int reason) {
- switch (script_type) {
- case ScriptStreamer::kParsingBlocking: {
- DEFINE_STATIC_LOCAL(
- EnumerationHistogram, parse_blocking_histogram,
- ("WebCore.Scripts.ParsingBlocking.StartedStreaming", 2));
- parse_blocking_histogram.Count(reason);
- break;
- }
- case ScriptStreamer::kDeferred: {
- DEFINE_STATIC_LOCAL(EnumerationHistogram, deferred_histogram,
- ("WebCore.Scripts.Deferred.StartedStreaming", 2));
- deferred_histogram.Count(reason);
- break;
- }
- case ScriptStreamer::kAsync: {
- DEFINE_STATIC_LOCAL(EnumerationHistogram, async_histogram,
- ("WebCore.Scripts.Async.StartedStreaming", 2));
- async_histogram.Count(reason);
- break;
- }
- default:
- NOTREACHED();
- break;
- }
-}
-
-// For tracking why some scripts are not streamed. Not streaming is part of
-// normal operation (e.g., script already loaded, script too small) and doesn't
-// necessarily indicate a failure.
-enum NotStreamingReason {
- kAlreadyLoaded, // DEPRECATED
- kNotHTTP,
- kReload,
- kContextNotValid,
- kEncodingNotSupported,
- kThreadBusy,
- kV8CannotStream,
- kScriptTooSmall,
- kNoResourceBuffer,
- kNotStreamingReasonEnd
-};
-
-void RecordNotStreamingReasonHistogram(ScriptStreamer::Type script_type,
- NotStreamingReason reason) {
- switch (script_type) {
- case ScriptStreamer::kParsingBlocking: {
- DEFINE_STATIC_LOCAL(EnumerationHistogram, parse_blocking_histogram,
- ("WebCore.Scripts.ParsingBlocking.NotStreamingReason",
- kNotStreamingReasonEnd));
- parse_blocking_histogram.Count(reason);
- break;
- }
- case ScriptStreamer::kDeferred: {
- DEFINE_STATIC_LOCAL(EnumerationHistogram, deferred_histogram,
- ("WebCore.Scripts.Deferred.NotStreamingReason",
- kNotStreamingReasonEnd));
- deferred_histogram.Count(reason);
- break;
- }
- case ScriptStreamer::kAsync: {
- DEFINE_STATIC_LOCAL(
- EnumerationHistogram, async_histogram,
- ("WebCore.Scripts.Async.NotStreamingReason", kNotStreamingReasonEnd));
- async_histogram.Count(reason);
- break;
- }
- default:
- NOTREACHED();
- break;
- }
-}
-
-} // namespace
-
// For passing data between the main thread (producer) and the streamer thread
// (consumer). The main thread prepares the data (copies it from Resource) and
// the streamer thread feeds it to V8.
@@ -142,9 +66,7 @@ class SourceStreamDataQueue {
private:
bool TryGetData(const uint8_t** data, size_t* length) {
-#if DCHECK_IS_ON()
- DCHECK(mutex_.Locked());
-#endif
+ mutex_.AssertAcquired();
if (!data_.IsEmpty()) {
std::pair<const uint8_t*, size_t> next_data = data_.TakeFirst();
*data = next_data.first;
@@ -249,22 +171,11 @@ class SourceStream : public v8::ScriptCompiler::ExternalSourceStream {
// waiting).
DCHECK(resource);
- if (!resource->GetResponse().CacheStorageCacheName().IsNull()) {
- streamer->SuppressStreaming();
- Cancel();
- return;
- }
-
- SingleCachedMetadataHandler* cache_handler = resource->CacheHandler();
- scoped_refptr<CachedMetadata> code_cache(
- cache_handler ? cache_handler->GetCachedMetadata(
- V8CodeCache::TagForCodeCache(cache_handler))
- : nullptr);
- if (code_cache.get()) {
- // The resource has a code cache, so it's unnecessary to stream and
- // parse the code. Cancel the streaming and resume the non-streaming
- // code path.
- streamer->SuppressStreaming();
+ if (V8CodeCache::HasCodeCache(resource->CacheHandler())) {
+ // The resource has a code cache entry, so it's unnecessary to stream
+ // and parse the code. Cancel the streaming and resume the non-streaming
+ // code path which will consume the code cache.
+ streamer->SuppressStreaming(ScriptStreamer::kHasCodeCache);
Cancel();
return;
}
@@ -384,12 +295,57 @@ void ScriptStreamer::Cancel() {
stream_->Cancel();
}
-void ScriptStreamer::SuppressStreaming() {
+void ScriptStreamer::SuppressStreaming(NotStreamingReason reason) {
DCHECK(IsMainThread());
DCHECK(!loading_finished_);
+ DCHECK_NE(reason, NotStreamingReason::kInvalid);
+
// It can be that the parsing task has already finished (e.g., if there was
// a parse error).
streaming_suppressed_ = true;
+ suppressed_reason_ = reason;
+}
+
+namespace {
+
+void RunScriptStreamingTask(
+ std::unique_ptr<v8::ScriptCompiler::ScriptStreamingTask> task,
+ ScriptStreamer* streamer) {
+ TRACE_EVENT1(
+ "v8,devtools.timeline", "v8.parseOnBackground", "data",
+ InspectorParseScriptEvent::Data(streamer->ScriptResourceIdentifier(),
+ streamer->ScriptURLString()));
+ // Running the task can and will block: SourceStream::GetSomeData will get
+ // called and it will block and wait for data from the network.
+ task->Run();
+ streamer->StreamingCompleteOnBackgroundThread();
+}
+
+void RunBlockingScriptStreamingTask(
+ std::unique_ptr<v8::ScriptCompiler::ScriptStreamingTask> task,
+ ScriptStreamer* streamer,
+ std::atomic_flag* blocking_task_started_or_cancelled) {
+ if (blocking_task_started_or_cancelled->test_and_set())
+ return;
+ RunScriptStreamingTask(std::move(task), streamer);
+}
+
+void RunNonBlockingScriptStreamingTask(
+ std::unique_ptr<v8::ScriptCompiler::ScriptStreamingTask> task,
+ ScriptStreamer* streamer) {
+ RunScriptStreamingTask(std::move(task), streamer);
+}
+
+} // namespace
+
+bool ScriptStreamer::HasEnoughDataForStreaming(size_t resource_buffer_size) {
+ if (RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled()) {
+ // Enable streaming for small scripts, but we must still check the BOM
+ // before starting streaming.
+ return resource_buffer_size >= kMaximumLengthOfBOM;
+ }
+ // Only stream larger scripts.
+ return resource_buffer_size >= small_script_threshold_;
}
void ScriptStreamer::NotifyAppendData(ScriptResource* resource) {
@@ -401,14 +357,13 @@ void ScriptStreamer::NotifyAppendData(ScriptResource* resource) {
// enough - wait until the next data chunk comes before deciding whether
// to start the streaming.
DCHECK(resource->ResourceBuffer());
- if (resource->ResourceBuffer()->size() < small_script_threshold_)
+ if (!HasEnoughDataForStreaming(resource->ResourceBuffer()->size()))
return;
have_enough_data_for_streaming_ = true;
{
// Check for BOM (byte order marks), because that might change our
// understanding of the data encoding.
- constexpr size_t kMaximumLengthOfBOM = 4;
char maybe_bom[kMaximumLengthOfBOM] = {};
if (!resource->ResourceBuffer()->GetBytes(maybe_bom,
kMaximumLengthOfBOM)) {
@@ -429,28 +384,23 @@ void ScriptStreamer::NotifyAppendData(ScriptResource* resource) {
// Also note that have at least s_smallScriptThreshold worth of
// data, which is more than enough for detecting a BOM.
if (!ConvertEncoding(decoder->Encoding().GetName(), &encoding_)) {
- SuppressStreaming();
- RecordNotStreamingReasonHistogram(script_type_, kEncodingNotSupported);
- RecordStartedStreamingHistogram(script_type_, 0);
+ SuppressStreaming(kEncodingNotSupported);
return;
}
}
- if (ScriptStreamerThread::Shared()->IsRunningTask()) {
- // At the moment we only have one thread for running the tasks. A
- // new task shouldn't be queued before the running task completes,
- // because the running task can block and wait for data from the
- // network.
- SuppressStreaming();
- RecordNotStreamingReasonHistogram(script_type_, kThreadBusy);
- RecordStartedStreamingHistogram(script_type_, 0);
+ if (!RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled() &&
+ ScriptStreamerThread::Shared()->IsRunningTask()) {
+ // If scheduled script streaming is disabled, we only have one thread for
+ // running the tasks. A new task shouldn't be queued before the running
+ // task completes, because the running task can block and wait for data
+ // from the network.
+ SuppressStreaming(kThreadBusy);
return;
}
if (!script_state_->ContextIsValid()) {
- SuppressStreaming();
- RecordNotStreamingReasonHistogram(script_type_, kContextNotValid);
- RecordStartedStreamingHistogram(script_type_, 0);
+ SuppressStreaming(kContextNotValid);
return;
}
@@ -468,19 +418,37 @@ void ScriptStreamer::NotifyAppendData(ScriptResource* resource) {
script_state_->GetIsolate(), source_.get(), compile_options_)));
if (!script_streaming_task) {
// V8 cannot stream the script.
- SuppressStreaming();
+ SuppressStreaming(kV8CannotStream);
stream_ = nullptr;
source_.reset();
- RecordNotStreamingReasonHistogram(script_type_, kV8CannotStream);
- RecordStartedStreamingHistogram(script_type_, 0);
return;
}
- ScriptStreamerThread::Shared()->PostTask(
- CrossThreadBind(&ScriptStreamerThread::RunScriptStreamingTask,
- WTF::Passed(std::move(script_streaming_task)),
- WrapCrossThreadPersistent(this)));
- RecordStartedStreamingHistogram(script_type_, 1);
+ if (RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled()) {
+ // Script streaming tasks are high priority, as they can block the parser,
+ // and they can (and probably will) block during their own execution as
+ // they wait for more input.
+ //
+ // Pass through the atomic cancellation token which is set to true by the
+ // task when it is started, or set to true by the streamer if it wants to
+ // cancel the task.
+ //
+ // TODO(leszeks): Decrease the priority of these tasks where possible.
+ BackgroundScheduler::PostOnBackgroundThreadWithTraits(
+ FROM_HERE, {base::TaskPriority::USER_BLOCKING, base::MayBlock()},
+ CrossThreadBind(RunBlockingScriptStreamingTask,
+ WTF::Passed(std::move(script_streaming_task)),
+ WrapCrossThreadPersistent(this),
+ WTF::CrossThreadUnretained(
+ &blocking_task_started_or_cancelled_)));
+ } else {
+ blocking_task_started_or_cancelled_.test_and_set();
+ ScriptStreamerThread::Shared()->PostTask(
+ CrossThreadBind(&ScriptStreamerThread::RunScriptStreamingTask,
+ WTF::Passed(std::move(script_streaming_task)),
+ WrapCrossThreadPersistent(this)));
+ }
+
}
if (stream_)
stream_->DidReceiveData(resource, this);
@@ -493,12 +461,37 @@ void ScriptStreamer::NotifyFinished() {
// be a "parsing complete" notification either, and we should not wait for
// it.
if (!have_enough_data_for_streaming_) {
- RecordNotStreamingReasonHistogram(script_type_, kScriptTooSmall);
- RecordStartedStreamingHistogram(script_type_, 0);
- SuppressStreaming();
+ SuppressStreaming(kScriptTooSmall);
}
- if (stream_)
+
+ if (stream_) {
+ // If the corresponding blocking task hasn't started yet, cancel it and post
+ // a non-blocking task, since we know now that all the data is received and
+ // we will no longer block.
+ //
+ // TODO(874080): Once we have mutable task traits, simply unmark the
+ // existing task as no longer MayBlock.
+ if (RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled() &&
+ !blocking_task_started_or_cancelled_.test_and_set()) {
+ ScriptState::Scope scope(script_state_);
+ std::unique_ptr<v8::ScriptCompiler::ScriptStreamingTask>
+ script_streaming_task(
+ base::WrapUnique(v8::ScriptCompiler::StartStreamingScript(
+ script_state_->GetIsolate(), source_.get(),
+ compile_options_)));
+
+ // The task creation shouldn't fail, since it didn't fail before during
+ // NotifyAppendData.
+ CHECK(script_streaming_task);
+ BackgroundScheduler::PostOnBackgroundThreadWithTraits(
+ FROM_HERE, {base::TaskPriority::USER_BLOCKING},
+ CrossThreadBind(RunNonBlockingScriptStreamingTask,
+ WTF::Passed(std::move(script_streaming_task)),
+ WrapCrossThreadPersistent(this)));
+ }
+
stream_->DidFinishLoading();
+ }
loading_finished_ = true;
NotifyFinishedToClient();
@@ -506,7 +499,6 @@ void ScriptStreamer::NotifyFinished() {
ScriptStreamer::ScriptStreamer(
ClassicPendingScript* script,
- Type script_type,
ScriptState* script_state,
v8::ScriptCompiler::CompileOptions compile_options,
scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner)
@@ -517,9 +509,9 @@ ScriptStreamer::ScriptStreamer(
parsing_finished_(false),
have_enough_data_for_streaming_(false),
streaming_suppressed_(false),
+ suppressed_reason_(kInvalid),
compile_options_(compile_options),
script_state_(script_state),
- script_type_(script_type),
script_url_string_(script->GetResource()->Url().Copy().GetString()),
script_resource_identifier_(script->GetResource()->Identifier()),
// Unfortunately there's no dummy encoding value in the enum; let's use
@@ -569,32 +561,30 @@ void ScriptStreamer::NotifyFinishedToClient() {
void ScriptStreamer::StartStreaming(
ClassicPendingScript* script,
- Type script_type,
Settings* settings,
ScriptState* script_state,
- scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner) {
+ scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner,
+ NotStreamingReason* not_streaming_reason) {
DCHECK(IsMainThread());
DCHECK(script_state->ContextIsValid());
+ *not_streaming_reason = kInvalid;
ScriptResource* resource = ToScriptResource(script->GetResource());
if (!resource->Url().ProtocolIsInHTTPFamily()) {
- RecordNotStreamingReasonHistogram(script_type, kNotHTTP);
- RecordStartedStreamingHistogram(script_type, 0);
+ *not_streaming_reason = kNotHTTP;
return;
}
if (resource->IsCacheValidator()) {
- RecordNotStreamingReasonHistogram(script_type, kReload);
- RecordStartedStreamingHistogram(script_type, 0);
// This happens e.g., during reloads. We're actually not going to load
// the current Resource of the ClassicPendingScript but switch to another
// Resource -> don't stream.
+ *not_streaming_reason = kReload;
return;
}
if (resource->IsLoaded() && !resource->ResourceBuffer()) {
// This happens for already loaded resources, e.g. if resource
// validation fails. In that case, the loading subsystem will discard
// the resource buffer.
- RecordNotStreamingReasonHistogram(script_type, kNoResourceBuffer);
- RecordStartedStreamingHistogram(script_type, 0);
+ *not_streaming_reason = kNoResourceBuffer;
return;
}
// We cannot filter out short scripts, even if we wait for the HTTP headers
@@ -602,7 +592,7 @@ void ScriptStreamer::StartStreaming(
// downloads.
ScriptStreamer* streamer = new ScriptStreamer(
- script, script_type, script_state, v8::ScriptCompiler::kNoCompileOptions,
+ script, script_state, v8::ScriptCompiler::kNoCompileOptions,
std::move(loading_task_runner));
// If this script was ready when streaming began, no callbacks will be
@@ -614,8 +604,10 @@ void ScriptStreamer::StartStreaming(
if (script->IsReady()) {
DCHECK(resource->IsLoaded());
streamer->NotifyAppendData(resource);
- if (streamer->StreamingSuppressed())
+ if (streamer->StreamingSuppressed()) {
+ *not_streaming_reason = streamer->StreamingSuppressedReason();
return;
+ }
}
// The Resource might go out of scope if the script is no longer needed.
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 b7399f5b3bb..578fb0b45dd 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
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SCRIPT_STREAMER_H_
#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SCRIPT_STREAMER_H_
+#include <atomic>
#include <memory>
#include "base/single_thread_task_runner.h"
@@ -34,7 +35,29 @@ class CORE_EXPORT ScriptStreamer final
WTF_MAKE_NONCOPYABLE(ScriptStreamer);
public:
- enum Type { kParsingBlocking, kDeferred, kAsync };
+ // For tracking why some scripts are not streamed. Not streaming is part of
+ // normal operation (e.g., script already loaded, script too small) and
+ // doesn't necessarily indicate a failure.
+ enum NotStreamingReason {
+ kAlreadyLoaded, // DEPRECATED
+ kNotHTTP,
+ kReload,
+ kContextNotValid,
+ kEncodingNotSupported,
+ kThreadBusy,
+ kV8CannotStream,
+ kScriptTooSmall,
+ kNoResourceBuffer,
+ kHasCodeCache,
+ kStreamerNotReadyOnGetSource,
+ kInlineScript,
+ kDidntTryToStartStreaming,
+ kErrorOccurred,
+
+ // Pseudo values that should never be seen in reported metrics
+ kCount,
+ kInvalid = -1,
+ };
~ScriptStreamer();
void Trace(blink::Visitor*);
@@ -42,10 +65,10 @@ class CORE_EXPORT ScriptStreamer final
// Launches a task (on a background thread) which will stream the given
// ClassicPendingScript into V8 as it loads.
static void StartStreaming(ClassicPendingScript*,
- Type,
Settings*,
ScriptState*,
- scoped_refptr<base::SingleThreadTaskRunner>);
+ scoped_refptr<base::SingleThreadTaskRunner>,
+ NotStreamingReason* not_streaming_reason);
// Returns false if we cannot stream the given encoding.
static bool ConvertEncoding(const char* encoding_name,
@@ -68,8 +91,15 @@ class CORE_EXPORT ScriptStreamer final
// started streaming but then we detect we don't want to stream (e.g., when
// we have the code cache for the script) and we still want to parse and
// execute it when it has finished loading.
- void SuppressStreaming();
- bool StreamingSuppressed() const { return streaming_suppressed_; }
+ void SuppressStreaming(NotStreamingReason reason);
+ bool StreamingSuppressed() const {
+ DCHECK(!streaming_suppressed_ || suppressed_reason_ != kInvalid);
+ return streaming_suppressed_;
+ }
+ NotStreamingReason StreamingSuppressedReason() const {
+ DCHECK(streaming_suppressed_ || suppressed_reason_ == kInvalid);
+ return suppressed_reason_;
+ }
// Called by ClassicPendingScript when data arrives from the network.
void NotifyAppendData(ScriptResource*);
@@ -92,15 +122,17 @@ class CORE_EXPORT ScriptStreamer final
// Scripts whose first data chunk is smaller than this constant won't be
// streamed. Non-const for testing.
static size_t small_script_threshold_;
+ // Maximum size of the BOM marker.
+ static constexpr size_t kMaximumLengthOfBOM = 4;
ScriptStreamer(ClassicPendingScript*,
- Type,
ScriptState*,
v8::ScriptCompiler::CompileOptions,
scoped_refptr<base::SingleThreadTaskRunner>);
void StreamingComplete();
void NotifyFinishedToClient();
+ bool HasEnoughDataForStreaming(size_t resource_buffer_size);
Member<ClassicPendingScript> pending_script_;
// Whether ScriptStreamer is detached from the Resource. In those cases, the
@@ -115,18 +147,21 @@ class CORE_EXPORT ScriptStreamer final
// Whether we have received enough data to start the streaming.
bool have_enough_data_for_streaming_;
+ // Flag used to allow atomic cancelling and reposting of the streaming task
+ // when the load completes without the task yet starting.
+ // TODO(874080): Remove once we can mutate task traits.
+ std::atomic_flag blocking_task_started_or_cancelled_ = ATOMIC_FLAG_INIT;
+
// Whether the script source code should be retrieved from the Resource
// instead of the ScriptStreamer.
bool streaming_suppressed_;
+ NotStreamingReason suppressed_reason_;
// What kind of cached data V8 produces during streaming.
v8::ScriptCompiler::CompileOptions compile_options_;
Member<ScriptState> script_state_;
- // For recording metrics for different types of scripts separately.
- Type script_type_;
-
// Keep the script URL string for event tracing.
const String script_url_string_;
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 0ea5e530206..7ec1d5270e3 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
@@ -57,6 +57,7 @@ class ScriptStreamingTest : public testing::Test {
pending_script_ = ClassicPendingScript::Fetch(
url, dummy_page_holder_->GetDocument(), ScriptFetchOptions(),
UTF8Encoding(), element, FetchParameters::kNoDefer);
+ pending_script_->SetSchedulingType(ScriptSchedulingType::kParserBlocking);
ScriptStreamer::SetSmallScriptThresholdForTesting(0);
Platform::Current()->GetURLLoaderMockFactory()->UnregisterURL(url);
@@ -74,6 +75,12 @@ class ScriptStreamingTest : public testing::Test {
return pending_script_.Get();
}
+ ScriptSourceCode GetScriptSourceCode() const {
+ ClassicScript* classic_script = GetPendingScript()->GetSource(NullURL());
+ DCHECK(classic_script);
+ return classic_script->GetScriptSourceCode();
+ }
+
Settings* GetSettings() const {
return &dummy_page_holder_->GetPage().GetSettings();
}
@@ -108,8 +115,10 @@ class ScriptStreamingTest : public testing::Test {
}
void ProcessTasksUntilStreamingComplete() {
- while (ScriptStreamerThread::Shared()->IsRunningTask()) {
- test::RunPendingTasks();
+ if (!RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled()) {
+ while (ScriptStreamerThread::Shared()->IsRunningTask()) {
+ test::RunPendingTasks();
+ }
}
// Once more, because the "streaming complete" notification might only
// now be in the task queue.
@@ -142,9 +151,11 @@ class TestPendingScriptClient final
TEST_F(ScriptStreamingTest, CompilingStreamedScript) {
// Test that we can successfully compile a streamed script.
V8TestingScope scope;
- ScriptStreamer::StartStreaming(
- GetPendingScript(), ScriptStreamer::kParsingBlocking, GetSettings(),
- scope.GetScriptState(), loading_task_runner_);
+ ScriptStreamer::NotStreamingReason reason;
+ ScriptStreamer::StartStreaming(GetPendingScript(), GetSettings(),
+ scope.GetScriptState(), loading_task_runner_,
+ &reason);
+ GetPendingScript()->SetNotStreamingReasonForTest(reason);
TestPendingScriptClient* client = new TestPendingScriptClient;
GetPendingScript()->WatchForLoad(client);
@@ -160,11 +171,7 @@ TEST_F(ScriptStreamingTest, CompilingStreamedScript) {
// has completed its tasks.
ProcessTasksUntilStreamingComplete();
EXPECT_TRUE(client->Finished());
- bool error_occurred = false;
- ScriptSourceCode source_code = GetPendingScript()
- ->GetSource(NullURL(), error_occurred)
- ->GetScriptSourceCode();
- EXPECT_FALSE(error_occurred);
+ ScriptSourceCode source_code = GetScriptSourceCode();
EXPECT_TRUE(source_code.Streamer());
v8::TryCatch try_catch(scope.GetIsolate());
v8::Local<v8::Script> script;
@@ -185,9 +192,11 @@ TEST_F(ScriptStreamingTest, CompilingStreamedScriptWithParseError) {
// the V8 side typically finished before loading finishes: make sure we
// handle it gracefully.
V8TestingScope scope;
- ScriptStreamer::StartStreaming(
- GetPendingScript(), ScriptStreamer::kParsingBlocking, GetSettings(),
- scope.GetScriptState(), loading_task_runner_);
+ ScriptStreamer::NotStreamingReason reason;
+ ScriptStreamer::StartStreaming(GetPendingScript(), GetSettings(),
+ scope.GetScriptState(), loading_task_runner_,
+ &reason);
+ GetPendingScript()->SetNotStreamingReasonForTest(reason);
TestPendingScriptClient* client = new TestPendingScriptClient;
GetPendingScript()->WatchForLoad(client);
AppendData("function foo() {");
@@ -205,11 +214,7 @@ TEST_F(ScriptStreamingTest, CompilingStreamedScriptWithParseError) {
Finish();
EXPECT_TRUE(client->Finished());
- bool error_occurred = false;
- ScriptSourceCode source_code = GetPendingScript()
- ->GetSource(NullURL(), error_occurred)
- ->GetScriptSourceCode();
- EXPECT_FALSE(error_occurred);
+ ScriptSourceCode source_code = GetScriptSourceCode();
EXPECT_TRUE(source_code.Streamer());
v8::TryCatch try_catch(scope.GetIsolate());
v8::Local<v8::Script> script;
@@ -229,9 +234,11 @@ TEST_F(ScriptStreamingTest, CancellingStreaming) {
// Test that the upper layers (PendingScript and up) can be ramped down
// while streaming is ongoing, and ScriptStreamer handles it gracefully.
V8TestingScope scope;
- ScriptStreamer::StartStreaming(
- GetPendingScript(), ScriptStreamer::kParsingBlocking, GetSettings(),
- scope.GetScriptState(), loading_task_runner_);
+ ScriptStreamer::NotStreamingReason reason;
+ ScriptStreamer::StartStreaming(GetPendingScript(), GetSettings(),
+ scope.GetScriptState(), loading_task_runner_,
+ &reason);
+ GetPendingScript()->SetNotStreamingReasonForTest(reason);
TestPendingScriptClient* client = new TestPendingScriptClient;
GetPendingScript()->WatchForLoad(client);
AppendData("function foo() {");
@@ -258,9 +265,11 @@ TEST_F(ScriptStreamingTest, SuppressingStreaming) {
// upper layer (ScriptResourceClient) should get a notification when the
// script is loaded.
V8TestingScope scope;
- ScriptStreamer::StartStreaming(
- GetPendingScript(), ScriptStreamer::kParsingBlocking, GetSettings(),
- scope.GetScriptState(), loading_task_runner_);
+ ScriptStreamer::NotStreamingReason reason;
+ ScriptStreamer::StartStreaming(GetPendingScript(), GetSettings(),
+ scope.GetScriptState(), loading_task_runner_,
+ &reason);
+ GetPendingScript()->SetNotStreamingReasonForTest(reason);
TestPendingScriptClient* client = new TestPendingScriptClient;
GetPendingScript()->WatchForLoad(client);
AppendData("function foo() {");
@@ -277,11 +286,7 @@ TEST_F(ScriptStreamingTest, SuppressingStreaming) {
ProcessTasksUntilStreamingComplete();
EXPECT_TRUE(client->Finished());
- bool error_occurred = false;
- ScriptSourceCode source_code = GetPendingScript()
- ->GetSource(NullURL(), error_occurred)
- ->GetScriptSourceCode();
- EXPECT_FALSE(error_occurred);
+ ScriptSourceCode source_code = GetScriptSourceCode();
// ScriptSourceCode doesn't refer to the streamer, since we have suppressed
// the streaming and resumed the non-streaming code path for script
// compilation.
@@ -293,9 +298,11 @@ TEST_F(ScriptStreamingTest, EmptyScripts) {
// (ScriptResourceClient) should be notified when an empty script has been
// loaded.
V8TestingScope scope;
- ScriptStreamer::StartStreaming(
- GetPendingScript(), ScriptStreamer::kParsingBlocking, GetSettings(),
- scope.GetScriptState(), loading_task_runner_);
+ ScriptStreamer::NotStreamingReason reason;
+ ScriptStreamer::StartStreaming(GetPendingScript(), GetSettings(),
+ scope.GetScriptState(), loading_task_runner_,
+ &reason);
+ GetPendingScript()->SetNotStreamingReasonForTest(reason);
TestPendingScriptClient* client = new TestPendingScriptClient;
GetPendingScript()->WatchForLoad(client);
@@ -305,11 +312,7 @@ TEST_F(ScriptStreamingTest, EmptyScripts) {
// through a background thread.
EXPECT_TRUE(client->Finished());
- bool error_occurred = false;
- ScriptSourceCode source_code = GetPendingScript()
- ->GetSource(NullURL(), error_occurred)
- ->GetScriptSourceCode();
- EXPECT_FALSE(error_occurred);
+ ScriptSourceCode source_code = GetScriptSourceCode();
EXPECT_FALSE(source_code.Streamer());
}
@@ -318,9 +321,11 @@ TEST_F(ScriptStreamingTest, SmallScripts) {
V8TestingScope scope;
ScriptStreamer::SetSmallScriptThresholdForTesting(100);
- ScriptStreamer::StartStreaming(
- GetPendingScript(), ScriptStreamer::kParsingBlocking, GetSettings(),
- scope.GetScriptState(), loading_task_runner_);
+ ScriptStreamer::NotStreamingReason reason;
+ ScriptStreamer::StartStreaming(GetPendingScript(), GetSettings(),
+ scope.GetScriptState(), loading_task_runner_,
+ &reason);
+ GetPendingScript()->SetNotStreamingReasonForTest(reason);
TestPendingScriptClient* client = new TestPendingScriptClient;
GetPendingScript()->WatchForLoad(client);
@@ -332,11 +337,7 @@ TEST_F(ScriptStreamingTest, SmallScripts) {
// through a background thread.
EXPECT_TRUE(client->Finished());
- bool error_occurred = false;
- ScriptSourceCode source_code = GetPendingScript()
- ->GetSource(NullURL(), error_occurred)
- ->GetScriptSourceCode();
- EXPECT_FALSE(error_occurred);
+ ScriptSourceCode source_code = GetScriptSourceCode();
EXPECT_FALSE(source_code.Streamer());
}
@@ -346,9 +347,11 @@ TEST_F(ScriptStreamingTest, ScriptsWithSmallFirstChunk) {
V8TestingScope scope;
ScriptStreamer::SetSmallScriptThresholdForTesting(100);
- ScriptStreamer::StartStreaming(
- GetPendingScript(), ScriptStreamer::kParsingBlocking, GetSettings(),
- scope.GetScriptState(), loading_task_runner_);
+ ScriptStreamer::NotStreamingReason reason;
+ ScriptStreamer::StartStreaming(GetPendingScript(), GetSettings(),
+ scope.GetScriptState(), loading_task_runner_,
+ &reason);
+ GetPendingScript()->SetNotStreamingReasonForTest(reason);
TestPendingScriptClient* client = new TestPendingScriptClient;
GetPendingScript()->WatchForLoad(client);
@@ -362,11 +365,7 @@ TEST_F(ScriptStreamingTest, ScriptsWithSmallFirstChunk) {
ProcessTasksUntilStreamingComplete();
EXPECT_TRUE(client->Finished());
- bool error_occurred = false;
- ScriptSourceCode source_code = GetPendingScript()
- ->GetSource(NullURL(), error_occurred)
- ->GetScriptSourceCode();
- EXPECT_FALSE(error_occurred);
+ ScriptSourceCode source_code = GetScriptSourceCode();
EXPECT_TRUE(source_code.Streamer());
v8::TryCatch try_catch(scope.GetIsolate());
v8::Local<v8::Script> script;
@@ -388,9 +387,11 @@ TEST_F(ScriptStreamingTest, EncodingChanges) {
V8TestingScope scope;
GetResource()->SetEncodingForTest("windows-1252");
- ScriptStreamer::StartStreaming(
- GetPendingScript(), ScriptStreamer::kParsingBlocking, GetSettings(),
- scope.GetScriptState(), loading_task_runner_);
+ ScriptStreamer::NotStreamingReason reason;
+ ScriptStreamer::StartStreaming(GetPendingScript(), GetSettings(),
+ scope.GetScriptState(), loading_task_runner_,
+ &reason);
+ GetPendingScript()->SetNotStreamingReasonForTest(reason);
TestPendingScriptClient* client = new TestPendingScriptClient;
GetPendingScript()->WatchForLoad(client);
@@ -404,11 +405,7 @@ TEST_F(ScriptStreamingTest, EncodingChanges) {
ProcessTasksUntilStreamingComplete();
EXPECT_TRUE(client->Finished());
- bool error_occurred = false;
- ScriptSourceCode source_code = GetPendingScript()
- ->GetSource(NullURL(), error_occurred)
- ->GetScriptSourceCode();
- EXPECT_FALSE(error_occurred);
+ ScriptSourceCode source_code = GetScriptSourceCode();
EXPECT_TRUE(source_code.Streamer());
v8::TryCatch try_catch(scope.GetIsolate());
v8::Local<v8::Script> script;
@@ -432,9 +429,11 @@ TEST_F(ScriptStreamingTest, EncodingFromBOM) {
// This encoding is wrong on purpose.
GetResource()->SetEncodingForTest("windows-1252");
- ScriptStreamer::StartStreaming(
- GetPendingScript(), ScriptStreamer::kParsingBlocking, GetSettings(),
- scope.GetScriptState(), loading_task_runner_);
+ ScriptStreamer::NotStreamingReason reason;
+ ScriptStreamer::StartStreaming(GetPendingScript(), GetSettings(),
+ scope.GetScriptState(), loading_task_runner_,
+ &reason);
+ GetPendingScript()->SetNotStreamingReasonForTest(reason);
TestPendingScriptClient* client = new TestPendingScriptClient;
GetPendingScript()->WatchForLoad(client);
@@ -447,11 +446,7 @@ TEST_F(ScriptStreamingTest, EncodingFromBOM) {
Finish();
ProcessTasksUntilStreamingComplete();
EXPECT_TRUE(client->Finished());
- bool error_occurred = false;
- ScriptSourceCode source_code = GetPendingScript()
- ->GetSource(NullURL(), error_occurred)
- ->GetScriptSourceCode();
- EXPECT_FALSE(error_occurred);
+ ScriptSourceCode source_code = GetScriptSourceCode();
EXPECT_TRUE(source_code.Streamer());
v8::TryCatch try_catch(scope.GetIsolate());
v8::Local<v8::Script> script;
@@ -470,9 +465,11 @@ TEST_F(ScriptStreamingTest, EncodingFromBOM) {
// A test for crbug.com/711703. Should not crash.
TEST_F(ScriptStreamingTest, GarbageCollectDuringStreaming) {
V8TestingScope scope;
- ScriptStreamer::StartStreaming(
- GetPendingScript(), ScriptStreamer::kParsingBlocking, GetSettings(),
- scope.GetScriptState(), loading_task_runner_);
+ ScriptStreamer::NotStreamingReason reason;
+ ScriptStreamer::StartStreaming(GetPendingScript(), GetSettings(),
+ scope.GetScriptState(), loading_task_runner_,
+ &reason);
+ GetPendingScript()->SetNotStreamingReasonForTest(reason);
TestPendingScriptClient* client = new TestPendingScriptClient;
GetPendingScript()->WatchForLoad(client);
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_streamer_thread.cc b/chromium/third_party/blink/renderer/bindings/core/v8/script_streamer_thread.cc
index a197c9de6b8..9051edde3d2 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/script_streamer_thread.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_streamer_thread.cc
@@ -11,6 +11,7 @@
#include "third_party/blink/renderer/bindings/core/v8/script_streamer.h"
#include "third_party/blink/renderer/core/inspector/inspector_trace_events.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/web_task_runner.h"
namespace blink {
@@ -22,19 +23,24 @@ static ScriptStreamerThread* g_shared_thread = nullptr;
static Mutex* g_mutex = nullptr;
void ScriptStreamerThread::Init() {
- DCHECK(!g_shared_thread);
- DCHECK(IsMainThread());
- // This is called in the main thread before any tasks are created, so no
- // locking is needed.
- g_mutex = new Mutex();
- g_shared_thread = new ScriptStreamerThread();
+ // Only enabled when ScheduledScriptStreaming is disabled.
+ if (!RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled()) {
+ DCHECK(!g_shared_thread);
+ DCHECK(IsMainThread());
+ // This is called in the main thread before any tasks are created, so no
+ // locking is needed.
+ g_mutex = new Mutex();
+ g_shared_thread = new ScriptStreamerThread();
+ }
}
ScriptStreamerThread* ScriptStreamerThread::Shared() {
+ DCHECK(!RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled());
return g_shared_thread;
}
void ScriptStreamerThread::PostTask(CrossThreadClosure task) {
+ DCHECK(!RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled());
DCHECK(IsMainThread());
MutexLocker locker(mutex_);
DCHECK(!running_task_);
@@ -60,6 +66,7 @@ WebThread& ScriptStreamerThread::PlatformThread() {
void ScriptStreamerThread::RunScriptStreamingTask(
std::unique_ptr<v8::ScriptCompiler::ScriptStreamingTask> task,
ScriptStreamer* streamer) {
+ DCHECK(!RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled());
TRACE_EVENT1(
"v8,devtools.timeline", "v8.parseOnBackground", "data",
InspectorParseScriptEvent::Data(streamer->ScriptResourceIdentifier(),
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_wrappable_marking_visitor_test.cc b/chromium/third_party/blink/renderer/bindings/core/v8/script_wrappable_marking_visitor_test.cc
index f3702be4a01..576c9f6e947 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/script_wrappable_marking_visitor_test.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_wrappable_marking_visitor_test.cc
@@ -16,31 +16,120 @@
namespace blink {
-static void PreciselyCollectGarbage() {
+namespace {
+
+// Temporarily swaps out the underlying ScriptWrappableMarkingVisitor from a
+// given v8::Isolate. Gracefully finalized potentially running garbage
+// collections.
+class TemporaryScriptWrappableVisitorScope {
+ WTF_MAKE_NONCOPYABLE(TemporaryScriptWrappableVisitorScope);
+ STACK_ALLOCATED();
+
+ public:
+ TemporaryScriptWrappableVisitorScope(
+ v8::Isolate* isolate,
+ std::unique_ptr<ScriptWrappableMarkingVisitor> controller)
+ : isolate_(isolate), saved_controller_(std::move(controller)) {
+ SwapWithV8PerIsolateDataVisitor();
+ }
+ ~TemporaryScriptWrappableVisitorScope() { SwapWithV8PerIsolateDataVisitor(); }
+
+ ScriptWrappableMarkingVisitor* CurrentVisitor() {
+ return V8PerIsolateData::From(isolate_)->GetScriptWrappableMarkingVisitor();
+ }
+
+ private:
+ void SwapWithV8PerIsolateDataVisitor() {
+ ScriptWrappableMarkingVisitor* current = CurrentVisitor();
+ if (current)
+ ScriptWrappableMarkingVisitor::PerformCleanup(isolate_);
+
+ V8PerIsolateData::From(isolate_)->SwapScriptWrappableMarkingVisitor(
+ saved_controller_);
+ isolate_->SetEmbedderHeapTracer(CurrentVisitor());
+ }
+
+ v8::Isolate* const isolate_;
+ std::unique_ptr<ScriptWrappableMarkingVisitor> saved_controller_;
+};
+
+class InterceptingScriptWrappableMarkingVisitor
+ : public blink::ScriptWrappableMarkingVisitor {
+ public:
+ InterceptingScriptWrappableMarkingVisitor()
+ : ScriptWrappableMarkingVisitor(ThreadState::Current()),
+ marked_wrappers_(new size_t(0)) {}
+ ~InterceptingScriptWrappableMarkingVisitor() override {
+ delete marked_wrappers_;
+ }
+
+ void Visit(const TraceWrapperV8Reference<v8::Value>&) override {
+ *marked_wrappers_ += 1;
+ // Do not actually mark this visitor, as this would call into v8, which
+ // would require executing an actual GC.
+ }
+
+ size_t NumberOfMarkedWrappers() const { return *marked_wrappers_; }
+
+ void Start() { TracePrologue(); }
+
+ void end() {
+ // Gracefully terminate tracing.
+ AdvanceTracing(std::numeric_limits<double>::infinity());
+ AbortTracing();
+ }
+
+ private:
+ size_t* marked_wrappers_; // Indirection required because of const override.
+};
+
+class InterceptingScriptWrappableMarkingVisitorScope
+ : public TemporaryScriptWrappableVisitorScope {
+ WTF_MAKE_NONCOPYABLE(InterceptingScriptWrappableMarkingVisitorScope);
+ STACK_ALLOCATED();
+
+ public:
+ InterceptingScriptWrappableMarkingVisitorScope(v8::Isolate* isolate)
+ : TemporaryScriptWrappableVisitorScope(
+ isolate,
+ std::unique_ptr<InterceptingScriptWrappableMarkingVisitor>(
+ new InterceptingScriptWrappableMarkingVisitor())) {
+ Visitor()->Start();
+ }
+
+ virtual ~InterceptingScriptWrappableMarkingVisitorScope() {
+ Visitor()->end();
+ }
+
+ InterceptingScriptWrappableMarkingVisitor* Visitor() {
+ return reinterpret_cast<InterceptingScriptWrappableMarkingVisitor*>(
+ CurrentVisitor());
+ }
+};
+
+void PreciselyCollectGarbage() {
ThreadState::Current()->CollectAllGarbage();
}
-static void RunV8Scavenger(v8::Isolate* isolate) {
- V8GCController::CollectGarbage(isolate, true);
-}
+} // namespace
-static void RunV8FullGc(v8::Isolate* isolate) {
- V8GCController::CollectGarbage(isolate, false);
-}
+// =============================================================================
+// Wrapper tracing tests for Blink handling. ===================================
+// =============================================================================
TEST(ScriptWrappableMarkingVisitorTest,
ScriptWrappableMarkingVisitorTracesWrappers) {
V8TestingScope scope;
- ScriptWrappableMarkingVisitor* visitor =
- V8PerIsolateData::From(scope.GetIsolate())
- ->GetScriptWrappableMarkingVisitor();
+
DeathAwareScriptWrappable* target = DeathAwareScriptWrappable::Create();
DeathAwareScriptWrappable* dependency = DeathAwareScriptWrappable::Create();
target->SetWrappedDependency(dependency);
// The graph needs to be set up before starting tracing as otherwise the
// conservative write barrier would trigger.
- visitor->TracePrologue();
+ InterceptingScriptWrappableMarkingVisitorScope intercepting_scope(
+ scope.GetIsolate());
+ ScriptWrappableMarkingVisitor* visitor = intercepting_scope.Visitor();
HeapObjectHeader* target_header = HeapObjectHeader::FromPayload(target);
HeapObjectHeader* dependency_header =
@@ -55,109 +144,10 @@ TEST(ScriptWrappableMarkingVisitorTest,
visitor->RegisterV8Reference(pair);
EXPECT_EQ(visitor->MarkingDeque()->size(), 1ul);
- visitor->AdvanceTracing(
- 0, v8::EmbedderHeapTracer::AdvanceTracingActions(
- v8::EmbedderHeapTracer::ForceCompletionAction::FORCE_COMPLETION));
+ visitor->AdvanceTracing(std::numeric_limits<double>::infinity());
EXPECT_EQ(visitor->MarkingDeque()->size(), 0ul);
EXPECT_TRUE(target_header->IsWrapperHeaderMarked());
EXPECT_TRUE(dependency_header->IsWrapperHeaderMarked());
-
- visitor->AbortTracing();
-}
-
-TEST(ScriptWrappableMarkingVisitorTest,
- OilpanCollectObjectsNotReachableFromV8) {
- V8TestingScope scope;
- v8::Isolate* isolate = scope.GetIsolate();
-
- {
- v8::HandleScope handle_scope(isolate);
- DeathAwareScriptWrappable* object = DeathAwareScriptWrappable::Create();
- DeathAwareScriptWrappable::ObserveDeathsOf(object);
-
- // Creates new V8 wrapper and associates it with global scope
- ToV8(object, scope.GetContext()->Global(), isolate);
- }
-
- RunV8Scavenger(isolate);
- RunV8FullGc(isolate);
- PreciselyCollectGarbage();
-
- EXPECT_TRUE(DeathAwareScriptWrappable::HasDied());
-}
-
-TEST(ScriptWrappableMarkingVisitorTest,
- OilpanDoesntCollectObjectsReachableFromV8) {
- V8TestingScope scope;
- v8::Isolate* isolate = scope.GetIsolate();
- v8::HandleScope handle_scope(isolate);
- DeathAwareScriptWrappable* object = DeathAwareScriptWrappable::Create();
- DeathAwareScriptWrappable::ObserveDeathsOf(object);
-
- // Creates new V8 wrapper and associates it with global scope
- ToV8(object, scope.GetContext()->Global(), isolate);
-
- RunV8Scavenger(isolate);
- RunV8FullGc(isolate);
- PreciselyCollectGarbage();
-
- EXPECT_FALSE(DeathAwareScriptWrappable::HasDied());
-}
-
-TEST(ScriptWrappableMarkingVisitorTest, V8ReportsLiveObjectsDuringScavenger) {
- V8TestingScope scope;
- v8::Isolate* isolate = scope.GetIsolate();
- v8::HandleScope handle_scope(isolate);
- DeathAwareScriptWrappable* object = DeathAwareScriptWrappable::Create();
- DeathAwareScriptWrappable::ObserveDeathsOf(object);
-
- v8::Local<v8::Value> wrapper =
- ToV8(object, scope.GetContext()->Global(), isolate);
- EXPECT_TRUE(wrapper->IsObject());
- v8::Local<v8::Object> wrapper_object = wrapper->ToObject();
- // V8 collects wrappers with unmodified maps (as they can be recreated
- // without loosing any data if needed). We need to create some property on
- // wrapper so V8 will not see it as unmodified.
- EXPECT_TRUE(wrapper_object->CreateDataProperty(scope.GetContext(), 1, wrapper)
- .IsJust());
-
- RunV8Scavenger(isolate);
- PreciselyCollectGarbage();
-
- EXPECT_FALSE(DeathAwareScriptWrappable::HasDied());
-}
-
-TEST(ScriptWrappableMarkingVisitorTest, V8ReportsLiveObjectsDuringFullGc) {
- V8TestingScope scope;
- v8::Isolate* isolate = scope.GetIsolate();
- v8::HandleScope handle_scope(isolate);
- DeathAwareScriptWrappable* object = DeathAwareScriptWrappable::Create();
- DeathAwareScriptWrappable::ObserveDeathsOf(object);
-
- ToV8(object, scope.GetContext()->Global(), isolate);
-
- RunV8Scavenger(isolate);
- RunV8FullGc(isolate);
- PreciselyCollectGarbage();
-
- EXPECT_FALSE(DeathAwareScriptWrappable::HasDied());
-}
-
-TEST(ScriptWrappableMarkingVisitorTest, OilpanClearsHeadersWhenObjectDied) {
- V8TestingScope scope;
-
- DeathAwareScriptWrappable* object = DeathAwareScriptWrappable::Create();
- ScriptWrappableMarkingVisitor* visitor =
- V8PerIsolateData::From(scope.GetIsolate())
- ->GetScriptWrappableMarkingVisitor();
- visitor->TracePrologue();
- auto* header = HeapObjectHeader::FromPayload(object);
- visitor->headers_to_unmark_.push_back(header);
-
- PreciselyCollectGarbage();
-
- EXPECT_FALSE(visitor->headers_to_unmark_.Contains(header));
- visitor->AbortTracing();
}
TEST(ScriptWrappableMarkingVisitorTest,
@@ -165,10 +155,9 @@ TEST(ScriptWrappableMarkingVisitorTest,
V8TestingScope scope;
DeathAwareScriptWrappable* object = DeathAwareScriptWrappable::Create();
- ScriptWrappableMarkingVisitor* visitor =
- V8PerIsolateData::From(scope.GetIsolate())
- ->GetScriptWrappableMarkingVisitor();
- visitor->TracePrologue();
+ InterceptingScriptWrappableMarkingVisitorScope intercepting_scope(
+ scope.GetIsolate());
+ ScriptWrappableMarkingVisitor* visitor = intercepting_scope.Visitor();
visitor->TraceWithWrappers(object);
@@ -177,18 +166,15 @@ TEST(ScriptWrappableMarkingVisitorTest,
PreciselyCollectGarbage();
EXPECT_EQ(visitor->MarkingDeque()->front().RawObjectPointer(), nullptr);
-
- visitor->AbortTracing();
}
TEST(ScriptWrappableMarkingVisitorTest,
MarkedObjectDoesNothingOnWriteBarrierHitWhenDependencyIsMarkedToo) {
V8TestingScope scope;
- ScriptWrappableMarkingVisitor* visitor =
- V8PerIsolateData::From(scope.GetIsolate())
- ->GetScriptWrappableMarkingVisitor();
- visitor->TracePrologue();
+ InterceptingScriptWrappableMarkingVisitorScope intercepting_scope(
+ scope.GetIsolate());
+ ScriptWrappableMarkingVisitor* visitor = intercepting_scope.Visitor();
DeathAwareScriptWrappable* target = DeathAwareScriptWrappable::Create();
DeathAwareScriptWrappable* dependencies[] = {
@@ -207,17 +193,15 @@ TEST(ScriptWrappableMarkingVisitorTest,
target->AddWrappedHashMapDependency(dependencies[2], dependencies[3]);
EXPECT_TRUE(visitor->MarkingDeque()->IsEmpty());
- visitor->AbortTracing();
}
TEST(ScriptWrappableMarkingVisitorTest,
MarkedObjectMarksDependencyOnWriteBarrierHitWhenNotMarked) {
V8TestingScope scope;
- ScriptWrappableMarkingVisitor* visitor =
- V8PerIsolateData::From(scope.GetIsolate())
- ->GetScriptWrappableMarkingVisitor();
- visitor->TracePrologue();
+ InterceptingScriptWrappableMarkingVisitorScope intercepting_scope(
+ scope.GetIsolate());
+ ScriptWrappableMarkingVisitor* visitor = intercepting_scope.Visitor();
DeathAwareScriptWrappable* target = DeathAwareScriptWrappable::Create();
DeathAwareScriptWrappable* dependencies[] = {
@@ -235,8 +219,6 @@ TEST(ScriptWrappableMarkingVisitorTest,
for (int i = 0; i < 4; i++) {
EXPECT_TRUE(visitor->MarkingDequeContains(dependencies[i]));
}
-
- visitor->AbortTracing();
}
namespace {
@@ -261,63 +243,6 @@ class HandleContainer
TraceWrapperV8Reference<v8::String> handle_;
};
-class InterceptingScriptWrappableMarkingVisitor
- : public blink::ScriptWrappableMarkingVisitor {
- public:
- InterceptingScriptWrappableMarkingVisitor(v8::Isolate* isolate)
- : ScriptWrappableMarkingVisitor(isolate),
- marked_wrappers_(new size_t(0)) {}
- ~InterceptingScriptWrappableMarkingVisitor() override {
- delete marked_wrappers_;
- }
-
- void Visit(const TraceWrapperV8Reference<v8::Value>&) override {
- *marked_wrappers_ += 1;
- // Do not actually mark this visitor, as this would call into v8, which
- // would require executing an actual GC.
- }
-
- size_t NumberOfMarkedWrappers() const { return *marked_wrappers_; }
-
- void Start() { TracePrologue(); }
-
- void end() {
- // Gracefully terminate tracing.
- AdvanceTracing(
- 0,
- v8::EmbedderHeapTracer::AdvanceTracingActions(
- v8::EmbedderHeapTracer::ForceCompletionAction::FORCE_COMPLETION));
- AbortTracing();
- }
-
- private:
- size_t* marked_wrappers_; // Indirection required because of const override.
-};
-
-class InterceptingScriptWrappableMarkingVisitorScope
- : public V8PerIsolateData::TemporaryScriptWrappableVisitorScope {
- WTF_MAKE_NONCOPYABLE(InterceptingScriptWrappableMarkingVisitorScope);
- STACK_ALLOCATED();
-
- public:
- InterceptingScriptWrappableMarkingVisitorScope(v8::Isolate* isolate)
- : V8PerIsolateData::TemporaryScriptWrappableVisitorScope(
- isolate,
- std::unique_ptr<InterceptingScriptWrappableMarkingVisitor>(
- new InterceptingScriptWrappableMarkingVisitor(isolate))) {
- Visitor()->Start();
- }
-
- virtual ~InterceptingScriptWrappableMarkingVisitorScope() {
- Visitor()->end();
- }
-
- InterceptingScriptWrappableMarkingVisitor* Visitor() {
- return reinterpret_cast<InterceptingScriptWrappableMarkingVisitor*>(
- CurrentVisitor());
- }
-};
-
} // namespace
TEST(ScriptWrappableMarkingVisitorTest, WriteBarrierOnUnmarkedContainer) {
@@ -360,9 +285,8 @@ TEST(ScriptWrappableMarkingVisitorTest, VtableAtObjectStart) {
// at the start of a ScriptWrappableMarkingVisitor object. We do this to
// mitigate potential problems that could be caused by LTO when passing
// v8::EmbedderHeapTracer across the API boundary.
- V8TestingScope scope;
std::unique_ptr<blink::ScriptWrappableMarkingVisitor> visitor(
- new ScriptWrappableMarkingVisitor(scope.GetIsolate()));
+ new ScriptWrappableMarkingVisitor(ThreadState::Current()));
CHECK_EQ(
static_cast<void*>(visitor.get()),
static_cast<void*>(dynamic_cast<v8::EmbedderHeapTracer*>(visitor.get())));
@@ -395,9 +319,6 @@ TEST(ScriptWrappableMarkingVisitor, WriteBarrierForScriptWrappable) {
TEST(ScriptWrappableMarkingVisitorTest, WriteBarrierOnHeapVectorSwap1) {
V8TestingScope scope;
- ScriptWrappableMarkingVisitor* visitor =
- V8PerIsolateData::From(scope.GetIsolate())
- ->GetScriptWrappableMarkingVisitor();
HeapVector<DeathAwareScriptWrappable::Wrapper> vector1;
DeathAwareScriptWrappable* entry1 = DeathAwareScriptWrappable::Create();
@@ -406,22 +327,19 @@ TEST(ScriptWrappableMarkingVisitorTest, WriteBarrierOnHeapVectorSwap1) {
DeathAwareScriptWrappable* entry2 = DeathAwareScriptWrappable::Create();
vector2.push_back(entry2);
- visitor->TracePrologue();
+ InterceptingScriptWrappableMarkingVisitorScope intercepting_scope(
+ scope.GetIsolate());
+ ScriptWrappableMarkingVisitor* visitor = intercepting_scope.Visitor();
EXPECT_TRUE(visitor->MarkingDeque()->IsEmpty());
swap(vector1, vector2);
EXPECT_TRUE(visitor->MarkingDequeContains(entry1));
EXPECT_TRUE(visitor->MarkingDequeContains(entry2));
-
- visitor->AbortTracing();
}
TEST(ScriptWrappableMarkingVisitorTest, WriteBarrierOnHeapVectorSwap2) {
V8TestingScope scope;
- ScriptWrappableMarkingVisitor* visitor =
- V8PerIsolateData::From(scope.GetIsolate())
- ->GetScriptWrappableMarkingVisitor();
HeapVector<DeathAwareScriptWrappable::Wrapper> vector1;
DeathAwareScriptWrappable* entry1 = DeathAwareScriptWrappable::Create();
@@ -430,7 +348,9 @@ TEST(ScriptWrappableMarkingVisitorTest, WriteBarrierOnHeapVectorSwap2) {
DeathAwareScriptWrappable* entry2 = DeathAwareScriptWrappable::Create();
vector2.push_back(entry2);
- visitor->TracePrologue();
+ InterceptingScriptWrappableMarkingVisitorScope intercepting_scope(
+ scope.GetIsolate());
+ ScriptWrappableMarkingVisitor* visitor = intercepting_scope.Visitor();
EXPECT_TRUE(visitor->MarkingDeque()->IsEmpty());
swap(vector1, vector2);
@@ -438,8 +358,6 @@ TEST(ScriptWrappableMarkingVisitorTest, WriteBarrierOnHeapVectorSwap2) {
// Only entry2 is held alive by TraceWrapperMember, so we only expect this
// barrier to fire.
EXPECT_TRUE(visitor->MarkingDequeContains(entry2));
-
- visitor->AbortTracing();
}
namespace {
@@ -494,9 +412,6 @@ class Base : public blink::GarbageCollected<Base>,
TEST(ScriptWrappableMarkingVisitorTest, MixinTracing) {
V8TestingScope scope;
- ScriptWrappableMarkingVisitor* visitor =
- V8PerIsolateData::From(scope.GetIsolate())
- ->GetScriptWrappableMarkingVisitor();
DeathAwareScriptWrappable* base_wrapper = DeathAwareScriptWrappable::Create();
DeathAwareScriptWrappable* mixin_wrapper =
@@ -509,7 +424,9 @@ TEST(ScriptWrappableMarkingVisitorTest, MixinTracing) {
// Make sure that mixin does not point to the object header.
EXPECT_NE(static_cast<void*>(base), static_cast<void*>(mixin));
- visitor->TracePrologue();
+ InterceptingScriptWrappableMarkingVisitorScope intercepting_scope(
+ scope.GetIsolate());
+ ScriptWrappableMarkingVisitor* visitor = intercepting_scope.Visitor();
EXPECT_TRUE(visitor->MarkingDeque()->IsEmpty());
@@ -519,9 +436,7 @@ TEST(ScriptWrappableMarkingVisitorTest, MixinTracing) {
EXPECT_FALSE(visitor->MarkingDeque()->IsEmpty());
EXPECT_TRUE(visitor->MarkingDequeContains(base));
- visitor->AdvanceTracing(
- 0, v8::EmbedderHeapTracer::AdvanceTracingActions(
- v8::EmbedderHeapTracer::ForceCompletionAction::FORCE_COMPLETION));
+ visitor->AdvanceTracing(std::numeric_limits<double>::infinity());
EXPECT_EQ(visitor->MarkingDeque()->size(), 0ul);
EXPECT_TRUE(base_header->IsWrapperHeaderMarked());
EXPECT_TRUE(
@@ -530,7 +445,22 @@ TEST(ScriptWrappableMarkingVisitorTest, MixinTracing) {
HeapObjectHeader::FromPayload(mixin_wrapper)->IsWrapperHeaderMarked());
mixin_handle = nullptr;
- visitor->AbortTracing();
+}
+
+TEST(ScriptWrappableMarkingVisitorTest, OilpanClearsHeadersWhenObjectDied) {
+ V8TestingScope scope;
+
+ DeathAwareScriptWrappable* object = DeathAwareScriptWrappable::Create();
+ InterceptingScriptWrappableMarkingVisitorScope intercepting_scope(
+ scope.GetIsolate());
+ ScriptWrappableMarkingVisitor* visitor = intercepting_scope.Visitor();
+ auto* header = HeapObjectHeader::FromPayload(object);
+ visitor->headers_to_unmark_.push_back(header);
+ object = nullptr;
+
+ PreciselyCollectGarbage();
+
+ EXPECT_FALSE(visitor->headers_to_unmark_.Contains(header));
}
} // namespace blink
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
new file mode 100644
index 00000000000..e2f550d54ec
--- /dev/null
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_wrappable_v8_gc_integration_test.cc
@@ -0,0 +1,133 @@
+// 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 "testing/gtest/include/gtest/gtest.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_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 "v8/include/v8.h"
+
+namespace blink {
+
+namespace v8_gc_integration_test {
+
+void PreciselyCollectGarbage() {
+ ThreadState::Current()->CollectAllGarbage();
+}
+
+void RunV8Scavenger(v8::Isolate* isolate) {
+ V8GCController::CollectGarbage(isolate, true);
+}
+
+void RunV8FullGc(v8::Isolate* isolate) {
+ V8GCController::CollectGarbage(isolate, false);
+}
+
+} // namespace v8_gc_integration_test
+
+// =============================================================================
+// Tests that ScriptWrappable and its wrapper survive or are reclaimed in
+// certain garbage collection scenarios.
+// =============================================================================
+
+TEST(ScriptWrappableV8GCIntegrationTest, V8ReportsLiveObjectsDuringFullGc) {
+ V8TestingScope scope;
+ v8::Isolate* isolate = scope.GetIsolate();
+
+ v8::Persistent<v8::Value> holder;
+ GCObjectLivenessObserver<DeathAwareScriptWrappable> observer;
+ {
+ v8::HandleScope handle_scope(isolate);
+ DeathAwareScriptWrappable* object = DeathAwareScriptWrappable::Create();
+ observer.Observe(object);
+
+ holder.Reset(isolate, ToV8(object, scope.GetContext()->Global(), isolate));
+ }
+
+ v8_gc_integration_test::RunV8FullGc(isolate);
+ v8_gc_integration_test::PreciselyCollectGarbage();
+ EXPECT_FALSE(observer.WasCollected());
+ holder.Reset();
+}
+
+TEST(ScriptWrappableV8GCIntegrationTest, V8ReportsLiveObjectsDuringScavenger) {
+ V8TestingScope scope;
+ v8::Isolate* isolate = scope.GetIsolate();
+
+ GCObjectLivenessObserver<DeathAwareScriptWrappable> observer;
+ {
+ v8::HandleScope handle_scope(isolate);
+ DeathAwareScriptWrappable* object = DeathAwareScriptWrappable::Create();
+ observer.Observe(object);
+
+ v8::Local<v8::Value> wrapper =
+ ToV8(object, scope.GetContext()->Global(), isolate);
+ EXPECT_TRUE(wrapper->IsObject());
+ v8::Local<v8::Object> wrapper_object =
+ wrapper->ToObject(scope.GetContext()).ToLocalChecked();
+ // V8 collects wrappers with unmodified maps (as they can be recreated
+ // without losing any data if needed). We need to create some property on
+ // wrapper so V8 will not see it as unmodified.
+ EXPECT_TRUE(
+ wrapper_object->CreateDataProperty(scope.GetContext(), 1, wrapper)
+ .IsJust());
+ }
+
+ // Scavenger should not collect JavaScript wrappers that are modified, even if
+ // they are otherwise unreachable.
+ v8_gc_integration_test::RunV8Scavenger(isolate);
+ v8_gc_integration_test::PreciselyCollectGarbage();
+
+ EXPECT_FALSE(observer.WasCollected());
+}
+
+TEST(ScriptWrappableV8GCIntegrationTest,
+ OilpanDoesntCollectObjectsReachableFromV8) {
+ V8TestingScope scope;
+ v8::Isolate* isolate = scope.GetIsolate();
+
+ v8::Persistent<v8::Value> holder;
+ GCObjectLivenessObserver<DeathAwareScriptWrappable> observer;
+ {
+ v8::HandleScope handle_scope(isolate);
+ DeathAwareScriptWrappable* object = DeathAwareScriptWrappable::Create();
+ observer.Observe(object);
+
+ // Creates new V8 wrapper and associates it with global scope
+ holder.Reset(isolate, ToV8(object, scope.GetContext()->Global(), isolate));
+ }
+
+ v8_gc_integration_test::RunV8Scavenger(isolate);
+ v8_gc_integration_test::RunV8FullGc(isolate);
+ v8_gc_integration_test::PreciselyCollectGarbage();
+
+ EXPECT_FALSE(observer.WasCollected());
+ holder.Reset();
+}
+
+TEST(ScriptWrappableV8GCIntegrationTest,
+ OilpanCollectObjectsNotReachableFromV8) {
+ V8TestingScope scope;
+ v8::Isolate* isolate = scope.GetIsolate();
+
+ GCObjectLivenessObserver<DeathAwareScriptWrappable> observer;
+ {
+ v8::HandleScope handle_scope(isolate);
+ DeathAwareScriptWrappable* object = DeathAwareScriptWrappable::Create();
+ observer.Observe(object);
+
+ // Creates new V8 wrapper and associates it with global scope
+ ToV8(object, scope.GetContext()->Global(), isolate);
+ }
+
+ v8_gc_integration_test::RunV8Scavenger(isolate);
+ v8_gc_integration_test::RunV8FullGc(isolate);
+ v8_gc_integration_test::PreciselyCollectGarbage();
+
+ EXPECT_TRUE(observer.WasCollected());
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_wrappable_visitor_test.cc b/chromium/third_party/blink/renderer/bindings/core/v8/script_wrappable_visitor_test.cc
index 415b8a43188..dafb813dd21 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/script_wrappable_visitor_test.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_wrappable_visitor_test.cc
@@ -13,6 +13,9 @@ namespace {
class VerifyingScriptWrappableVisitor : public ScriptWrappableVisitor {
public:
+ VerifyingScriptWrappableVisitor()
+ : ScriptWrappableVisitor(ThreadState::Current()) {}
+
// Visitor interface.
void Visit(const TraceWrapperV8Reference<v8::Value>&) override {}
void Visit(DOMWrapperMap<ScriptWrappable>*,
@@ -25,6 +28,8 @@ class VerifyingScriptWrappableVisitor : public ScriptWrappableVisitor {
void VisitBackingStoreStrongly(void* object,
void** object_slot,
TraceDescriptor desc) override {
+ if (!object)
+ return;
desc.callback(this, desc.base_object_payload);
}
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
new file mode 100644
index 00000000000..25efed8921a
--- /dev/null
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.cc
@@ -0,0 +1,103 @@
+// 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/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/core/frame/frame.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
+#include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
+#include "third_party/blink/renderer/core/messaging/post_message_options.h"
+
+namespace blink {
+
+scoped_refptr<SerializedScriptValue> PostMessageHelper::SerializeMessageByMove(
+ v8::Isolate* isolate,
+ const ScriptValue& message,
+ const PostMessageOptions& options,
+ Transferables& transferables,
+ ExceptionState& exception_state) {
+ if (options.hasTransfer() && !options.transfer().IsEmpty()) {
+ if (!SerializedScriptValue::ExtractTransferables(
+ isolate, options.transfer(), transferables, exception_state)) {
+ return nullptr;
+ }
+ }
+
+ SerializedScriptValue::SerializeOptions serialize_options;
+ serialize_options.transferables = &transferables;
+ scoped_refptr<SerializedScriptValue> serialized_message =
+ SerializedScriptValue::Serialize(isolate, message.V8Value(),
+ serialize_options, exception_state);
+ if (exception_state.HadException())
+ return nullptr;
+
+ serialized_message->UnregisterMemoryAllocatedWithCurrentScriptContext();
+ return serialized_message;
+}
+
+scoped_refptr<SerializedScriptValue> PostMessageHelper::SerializeMessageByCopy(
+ v8::Isolate* isolate,
+ const ScriptValue& message,
+ const PostMessageOptions& options,
+ Transferables& transferables,
+ ExceptionState& exception_state) {
+ if (options.hasTransfer() && !options.transfer().IsEmpty()) {
+ if (!SerializedScriptValue::ExtractTransferables(
+ isolate, options.transfer(), transferables, exception_state)) {
+ return nullptr;
+ }
+ }
+
+ // Copying the transferables by move semantics is not supported for the
+ // caller of this function so emulate it by copy-and-neuter semantics
+ // that sends array buffers and image
+ // bitmaps via structured clone and then neuters the original objects.
+ // Clear references to array buffers and image bitmaps from transferables
+ // so that the serializer can consider the array buffers as
+ // non-transferable and serialize them into the message.
+ ArrayBufferArray transferable_array_buffers =
+ SerializedScriptValue::ExtractNonSharedArrayBuffers(transferables);
+ ImageBitmapArray transferable_image_bitmaps = transferables.image_bitmaps;
+ transferables.image_bitmaps.clear();
+ SerializedScriptValue::SerializeOptions serialize_options;
+ serialize_options.transferables = &transferables;
+ scoped_refptr<SerializedScriptValue> serialized_message =
+ SerializedScriptValue::Serialize(isolate, message.V8Value(),
+ serialize_options, exception_state);
+ if (exception_state.HadException())
+ return nullptr;
+
+ // Neuter the original array buffers on the sender context.
+ SerializedScriptValue::TransferArrayBufferContents(
+ isolate, transferable_array_buffers, exception_state);
+ if (exception_state.HadException())
+ return nullptr;
+ // Neuter the original image bitmaps on the sender context.
+ SerializedScriptValue::TransferImageBitmapContents(
+ isolate, transferable_image_bitmaps, exception_state);
+ if (exception_state.HadException())
+ return nullptr;
+
+ serialized_message->UnregisterMemoryAllocatedWithCurrentScriptContext();
+ return serialized_message;
+}
+
+mojom::blink::UserActivationSnapshotPtr
+PostMessageHelper::CreateUserActivationSnapshot(
+ ExecutionContext* execution_context,
+ const PostMessageOptions& options) {
+ if (!options.includeUserActivation())
+ return nullptr;
+ if (LocalDOMWindow* dom_window = execution_context->ExecutingWindow()) {
+ if (LocalFrame* frame = dom_window->GetFrame()) {
+ return mojom::blink::UserActivationSnapshot::New(
+ frame->HasBeenActivated(),
+ Frame::HasTransientUserActivation(frame, false));
+ }
+ }
+ return nullptr;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.h b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.h
new file mode 100644
index 00000000000..4adfc46554d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.h
@@ -0,0 +1,50 @@
+// 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_BINDINGS_CORE_V8_SERIALIZATION_POST_MESSAGE_HELPER_H_
+#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SERIALIZATION_POST_MESSAGE_HELPER_H_
+
+#include "base/memory/scoped_refptr.h"
+#include "third_party/blink/public/mojom/message_port/message_port.mojom-blink.h"
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/wtf/allocator.h"
+#include "v8/include/v8.h"
+
+namespace blink {
+
+class ExecutionContext;
+class ExceptionState;
+class PostMessageOptions;
+class ScriptValue;
+class SerializedScriptValue;
+class Transferables;
+
+class CORE_EXPORT PostMessageHelper {
+ STATIC_ONLY(PostMessageHelper);
+
+ public:
+ static scoped_refptr<SerializedScriptValue> SerializeMessageByMove(
+ v8::Isolate*,
+ const ScriptValue& message,
+ const PostMessageOptions& options,
+ Transferables& transferables,
+ ExceptionState&);
+
+ static scoped_refptr<SerializedScriptValue> SerializeMessageByCopy(
+ v8::Isolate*,
+ const ScriptValue& message,
+ const PostMessageOptions& options,
+ Transferables& transferables,
+ ExceptionState&);
+
+ // Create a snapshot of the user activation state. Return null if this if the
+ // execution context is not a window.
+ static mojom::blink::UserActivationSnapshotPtr CreateUserActivationSnapshot(
+ ExecutionContext*,
+ const PostMessageOptions&);
+};
+
+} // namespace blink
+
+#endif
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 7bc9582efcc..adb208c929a 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
@@ -39,6 +39,8 @@ namespace blink {
enum SerializationTag {
kMessagePortTag = 'M', // index:int -> MessagePort. Fills the result with
// transferred MessagePort.
+ kMojoHandleTag = 'h', // index:int -> MojoHandle. Fills the result with
+ // transferred MojoHandle.
kBlobTag = 'b', // uuid:WebCoreString, type:WebCoreString, size:uint64_t ->
// Blob (ref)
kBlobIndexTag = 'i', // index:int32_t -> Blob (ref)
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 21e799892c5..33e3eed2151 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
@@ -45,6 +45,7 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_array_buffer.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_image_bitmap.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_message_port.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_mojo_handle.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_offscreen_canvas.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_shared_array_buffer.h"
#include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
@@ -469,6 +470,18 @@ bool SerializedScriptValue::ExtractTransferables(
return false;
}
transferables.message_ports.push_back(port);
+ } else if (V8MojoHandle::hasInstance(transferable_object, isolate)) {
+ MojoHandle* handle = V8MojoHandle::ToImpl(
+ v8::Local<v8::Object>::Cast(transferable_object));
+ // Check for duplicate MojoHandles.
+ if (transferables.mojo_handles.Contains(handle)) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kDataCloneError,
+ "Mojo handle at index " + String::Number(i) +
+ " is a duplicate of an earlier handle.");
+ return false;
+ }
+ transferables.mojo_handles.push_back(handle);
} else if (transferable_object->IsArrayBuffer()) {
DOMArrayBuffer* array_buffer = V8ArrayBuffer::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 e8218fb2cba..5dc7bbfa12f 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
@@ -38,6 +38,7 @@
#include "third_party/blink/renderer/bindings/core/v8/native_value_traits.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/transferables.h"
#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/mojo/mojo_handle.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
#include "third_party/blink/renderer/platform/wtf/allocator/partitions.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
@@ -59,6 +60,7 @@ class UnpackedSerializedScriptValue;
class WebBlobInfo;
typedef HashMap<String, scoped_refptr<BlobDataHandle>> BlobDataHandleMap;
+typedef Vector<mojo::ScopedHandle> MojoScopedHandleArray;
typedef Vector<WebBlobInfo> WebBlobInfoArray;
typedef HeapVector<Member<DOMSharedArrayBuffer>> SharedArrayBufferArray;
@@ -113,13 +115,15 @@ class CORE_EXPORT SerializedScriptValue
};
struct SerializeOptions {
+ STACK_ALLOCATED();
+
+ public:
enum WasmSerializationPolicy {
kUnspecified, // Invalid value, used as default initializer.
kTransfer, // In-memory transfer without (necessarily) serializing.
kSerialize, // Serialize to a byte stream.
kBlockedInNonSecureContext // Block transfer or serialization.
};
- STACK_ALLOCATED();
SerializeOptions() = default;
explicit SerializeOptions(StoragePolicy for_storage)
@@ -159,6 +163,8 @@ class CORE_EXPORT SerializedScriptValue
// case of failure.
struct DeserializeOptions {
STACK_ALLOCATED();
+
+ public:
MessagePortArray* message_ports = nullptr;
const WebBlobInfoArray* blob_info = nullptr;
bool read_wasm_from_stream = false;
@@ -235,6 +241,7 @@ class CORE_EXPORT SerializedScriptValue
return shared_array_buffers_contents_;
}
BlobDataHandleMap& BlobDataHandles() { return blob_data_handles_; }
+ MojoScopedHandleArray& MojoHandles() { return mojo_handles_; }
ArrayBufferContentsArray& GetArrayBufferContentsArray() {
return array_buffer_contents_array_;
}
@@ -246,6 +253,11 @@ class CORE_EXPORT SerializedScriptValue
}
void SetImageBitmapContentsArray(ImageBitmapContentsArray contents);
+ bool IsLockedToAgentCluster() const {
+ return !wasm_modules_.IsEmpty() ||
+ !shared_array_buffers_contents_.IsEmpty();
+ }
+
private:
friend class ScriptValueSerializer;
friend class V8ScriptValueSerializer;
@@ -287,6 +299,7 @@ class CORE_EXPORT SerializedScriptValue
// These do not have one-use transferred contents, like the above.
TransferredWasmModulesArray wasm_modules_;
BlobDataHandleMap blob_data_handles_;
+ MojoScopedHandleArray mojo_handles_;
SharedArrayBufferContentsArray shared_array_buffers_contents_;
bool has_registered_external_allocation_;
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_threaded_test.cc b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_threaded_test.cc
index 3f69e6542e1..1fd3bfde147 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_threaded_test.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_threaded_test.cc
@@ -24,7 +24,7 @@ TEST(SerializedScriptValueThreadedTest,
// Start a worker.
WorkerReportingProxy proxy;
- WorkerThreadForTest worker_thread(nullptr, proxy);
+ WorkerThreadForTest worker_thread(proxy);
ParentExecutionContextTaskRunners* parent_execution_context_task_runners =
ParentExecutionContextTaskRunners::Create(&scope.GetDocument());
worker_thread.StartWithSourceCode(scope.GetDocument().GetSecurityOrigin(),
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/transferables.h b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/transferables.h
index b76464d13bb..736199db43a 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/transferables.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/transferables.h
@@ -15,11 +15,13 @@ class DOMArrayBufferBase;
class ImageBitmap;
class OffscreenCanvas;
class MessagePort;
+class MojoHandle;
using ArrayBufferArray = HeapVector<Member<DOMArrayBufferBase>>;
using ImageBitmapArray = HeapVector<Member<ImageBitmap>>;
using OffscreenCanvasArray = HeapVector<Member<OffscreenCanvas>>;
using MessagePortArray = HeapVector<Member<MessagePort>>;
+using MojoHandleArray = HeapVector<Member<blink::MojoHandle>>;
class CORE_EXPORT Transferables final {
STACK_ALLOCATED();
@@ -32,6 +34,7 @@ class CORE_EXPORT Transferables final {
ImageBitmapArray image_bitmaps;
OffscreenCanvasArray offscreen_canvases;
MessagePortArray message_ports;
+ MojoHandleArray mojo_handles;
};
// Along with extending |Transferables| to hold a new kind of transferable
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 f5acf9a4523..a7f18c5ad7d 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
@@ -23,6 +23,7 @@
#include "third_party/blink/renderer/core/html/canvas/image_data.h"
#include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
#include "third_party/blink/renderer/core/messaging/message_port.h"
+#include "third_party/blink/renderer/core/mojo/mojo_handle.h"
#include "third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.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"
@@ -480,6 +481,15 @@ ScriptWrappable* V8ScriptValueDeserializer::ReadDOMObject(
return nullptr;
return (*transferred_message_ports_)[index].Get();
}
+ case kMojoHandleTag: {
+ uint32_t index = 0;
+ if (!RuntimeEnabledFeatures::MojoJSEnabled() || !ReadUint32(&index) ||
+ index >= serialized_script_value_->MojoHandles().size()) {
+ return nullptr;
+ }
+ return MojoHandle::Create(
+ std::move(serialized_script_value_->MojoHandles()[index]));
+ }
case kOffscreenCanvasTransferTag: {
uint32_t width = 0, height = 0, canvas_id = 0, client_id = 0, sink_id = 0;
if (!ReadUint32(&width) || !ReadUint32(&height) ||
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 292660efd7d..9c23be48326 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
@@ -20,6 +20,7 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_image_bitmap.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_image_data.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_message_port.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_mojo_handle.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_offscreen_canvas.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_shared_array_buffer.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h"
@@ -31,7 +32,9 @@
#include "third_party/blink/renderer/core/geometry/dom_rect.h"
#include "third_party/blink/renderer/core/geometry/dom_rect_read_only.h"
#include "third_party/blink/renderer/core/html/canvas/image_data.h"
+#include "third_party/blink/renderer/core/mojo/mojo_handle.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_base.h"
+#include "third_party/blink/renderer/platform/file_metadata.h"
#include "third_party/blink/renderer/platform/wtf/allocator/partitions.h"
#include "third_party/blink/renderer/platform/wtf/date_math.h"
#include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h"
@@ -395,6 +398,26 @@ bool V8ScriptValueSerializer::WriteDOMObject(ScriptWrappable* wrappable,
WriteUint32(static_cast<uint32_t>(index));
return true;
}
+ if (wrapper_type_info == &V8MojoHandle::wrapperTypeInfo &&
+ RuntimeEnabledFeatures::MojoJSEnabled()) {
+ MojoHandle* mojo_handle = wrappable->ToImpl<MojoHandle>();
+ size_t index = kNotFound;
+ if (transferables_)
+ index = transferables_->mojo_handles.Find(mojo_handle);
+ if (index == kNotFound) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kDataCloneError,
+ "A MojoHandle could not be cloned because it was not transferred.");
+ return false;
+ }
+ DCHECK_LE(index, std::numeric_limits<uint32_t>::max());
+ serialized_script_value_->MojoHandles().push_back(
+ mojo_handle->TakeHandle());
+ index = serialized_script_value_->MojoHandles().size() - 1;
+ WriteTag(kMojoHandleTag);
+ WriteUint32(static_cast<uint32_t>(index));
+ return true;
+ }
if (wrapper_type_info == &V8OffscreenCanvas::wrapperTypeInfo) {
OffscreenCanvas* canvas = wrappable->ToImpl<OffscreenCanvas>();
size_t index = kNotFound;
@@ -543,6 +566,18 @@ v8::Maybe<uint32_t> V8ScriptValueSerializer::GetSharedArrayBufferId(
v8::Maybe<uint32_t> V8ScriptValueSerializer::GetWasmModuleTransferId(
v8::Isolate* isolate,
v8::Local<v8::WasmCompiledModule> module) {
+ if (for_storage_) {
+ DCHECK(exception_state_);
+ DCHECK_EQ(isolate, script_state_->GetIsolate());
+ ExceptionState exception_state(isolate, exception_state_->Context(),
+ exception_state_->InterfaceName(),
+ exception_state_->PropertyName());
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kDataCloneError,
+ "A WebAssembly.Module can not be serialized for storage.");
+ return v8::Nothing<uint32_t>();
+ }
+
switch (wasm_policy_) {
case Options::kSerialize:
return v8::Nothing<uint32_t>();
@@ -581,8 +616,8 @@ void* V8ScriptValueSerializer::ReallocateBufferMemory(void* old_buffer,
size_t size,
size_t* actual_size) {
*actual_size = WTF::Partitions::BufferActualSize(size);
- return WTF::Partitions::BufferRealloc(old_buffer, *actual_size,
- "SerializedScriptValue buffer");
+ return WTF::Partitions::BufferTryRealloc(old_buffer, *actual_size,
+ "SerializedScriptValue buffer");
}
void V8ScriptValueSerializer::FreeBufferMemory(void* buffer) {
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 7d74e07672e..7d8031fd428 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
@@ -93,6 +93,9 @@ class CORE_EXPORT V8ScriptValueSerializer
v8::Maybe<uint32_t> GetWasmModuleTransferId(
v8::Isolate*,
v8::Local<v8::WasmCompiledModule>) override;
+ // Reallocates memory at |ptr| to the new size and returns the new pointer or
+ // nullptr on failure. |actual_size| will hold the actual size of allocation
+ // requested.
void* ReallocateBufferMemory(void* old_buffer,
size_t,
size_t* actual_size) override;
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 a32e43c7948..5e3a9cb8b29 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
@@ -28,6 +28,7 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_image_bitmap.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_image_data.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_message_port.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_mojo_handle.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_offscreen_canvas.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_string_resource.h"
#include "third_party/blink/renderer/core/fileapi/blob.h"
@@ -43,8 +44,10 @@
#include "third_party/blink/renderer/core/geometry/dom_rect_read_only.h"
#include "third_party/blink/renderer/core/html/canvas/image_data.h"
#include "third_party/blink/renderer/core/messaging/message_port.h"
+#include "third_party/blink/renderer/core/mojo/mojo_handle.h"
#include "third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.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/graphics/static_bitmap_image.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
#include "third_party/blink/renderer/platform/wtf/date_math.h"
@@ -851,10 +854,10 @@ TEST(V8ScriptValueSerializerTest, DecodeImageDataV18) {
}
MessagePort* MakeMessagePort(ExecutionContext* execution_context,
- MojoHandle* unowned_handle_out = nullptr) {
+ ::MojoHandle* unowned_handle_out = nullptr) {
MessagePort* port = MessagePort::Create(*execution_context);
mojo::MessagePipe pipe;
- MojoHandle unowned_handle = pipe.handle0.get().value();
+ ::MojoHandle unowned_handle = pipe.handle0.get().value();
port->Entangle(std::move(pipe.handle0));
EXPECT_TRUE(port->IsEntangled());
EXPECT_EQ(unowned_handle, port->EntangledHandleForTesting());
@@ -866,7 +869,7 @@ MessagePort* MakeMessagePort(ExecutionContext* execution_context,
TEST(V8ScriptValueSerializerTest, RoundTripMessagePort) {
V8TestingScope scope;
- MojoHandle unowned_handle;
+ ::MojoHandle unowned_handle;
MessagePort* port =
MakeMessagePort(scope.GetExecutionContext(), &unowned_handle);
v8::Local<v8::Value> wrapper = ToV8(port, scope.GetScriptState());
@@ -951,8 +954,43 @@ TEST(V8ScriptValueSerializerTest, OutOfRangeMessagePortIndex) {
}
}
+TEST(V8ScriptValueSerializerTest, RoundTripMojoHandle) {
+ V8TestingScope scope;
+
+ mojo::MessagePipe pipe;
+ MojoHandle* handle =
+ MojoHandle::Create(mojo::ScopedHandle::From(std::move(pipe.handle0)));
+ v8::Local<v8::Value> wrapper = ToV8(handle, scope.GetScriptState());
+ Transferables transferables;
+ transferables.mojo_handles.push_back(handle);
+
+ v8::Local<v8::Value> result =
+ RoundTrip(wrapper, scope, nullptr, &transferables);
+ ASSERT_TRUE(V8MojoHandle::hasInstance(result, scope.GetIsolate()));
+ MojoHandle* new_handle = V8MojoHandle::ToImpl(result.As<v8::Object>());
+ EXPECT_FALSE(handle->TakeHandle().is_valid());
+ EXPECT_TRUE(new_handle->TakeHandle().is_valid());
+}
+
+TEST(V8ScriptValueSerializerTest, UntransferredMojoHandleThrowsDataCloneError) {
+ V8TestingScope scope;
+ ExceptionState exception_state(scope.GetIsolate(),
+ ExceptionState::kExecutionContext, "Window",
+ "postMessage");
+
+ mojo::MessagePipe pipe;
+ MojoHandle* handle =
+ MojoHandle::Create(mojo::ScopedHandle::From(std::move(pipe.handle0)));
+ v8::Local<v8::Value> wrapper = ToV8(handle, scope.GetScriptState());
+ Transferables transferables;
+
+ RoundTrip(wrapper, scope, &exception_state, &transferables);
+ ASSERT_TRUE(HadDOMExceptionInCoreTest(
+ "DataCloneError", scope.GetScriptState(), exception_state));
+}
+
// Decode tests for backward compatibility are not required for message ports
-// because they cannot be persisted to disk.
+// and Mojo handles because they cannot be persisted to disk.
// A more exhaustive set of ImageBitmap cases are covered by LayoutTests.
TEST(V8ScriptValueSerializerTest, RoundTripImageBitmap) {
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 1b1c6567387..216a21763fd 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
@@ -89,7 +89,7 @@ std::unique_ptr<SourceLocation> SourceLocation::FromMessage(
int script_id = message->GetScriptOrigin().ScriptID()->Value();
if (!stack.IsEmpty() && stack->GetFrameCount() > 0) {
- int top_script_id = stack->GetFrame(0)->GetScriptId();
+ int top_script_id = stack->GetFrame(isolate, 0)->GetScriptId();
if (top_script_id == script_id)
script_id = 0;
}
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 4e1ca0dc93d..022abeb976f 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
@@ -245,12 +245,14 @@ TEST(ToV8Test, pairHeapVector) {
result->Get(context, V8String(scope.GetIsolate(), "one"))
.ToLocalChecked();
EXPECT_TRUE(one->IsObject());
- EXPECT_EQ(String("foo"), ToCoreString(one->ToString()));
+ EXPECT_EQ(String("foo"),
+ ToCoreString(one->ToString(context).ToLocalChecked()));
v8::Local<v8::Value> two =
result->Get(context, V8String(scope.GetIsolate(), "two"))
.ToLocalChecked();
EXPECT_TRUE(two->IsObject());
- EXPECT_EQ(String("bar"), ToCoreString(two->ToString()));
+ EXPECT_EQ(String("bar"),
+ ToCoreString(two->ToString(context).ToLocalChecked()));
}
TEST(ToV8Test, stringVectorVector) {
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 3daee534b8b..170c063b8c7 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
@@ -151,6 +151,12 @@ void UseCounterCallback(v8::Isolate* isolate,
case v8::Isolate::kFunctionTokenOffsetTooLongForToString:
blink_feature = WebFeature::kV8FunctionTokenOffsetTooLongForToString;
break;
+ case v8::Isolate::kWasmSharedMemory:
+ blink_feature = WebFeature::kV8WasmSharedMemory;
+ break;
+ case v8::Isolate::kWasmThreadOpcodes:
+ blink_feature = WebFeature::kV8WasmThreadOpcodes;
+ break;
default:
// This can happen if V8 has added counters that this version of Blink
// does not know about. It's harmless.
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_abstract_event_listener.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_abstract_event_listener.cc
index 250fff39735..2c686f39546 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_abstract_event_listener.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_abstract_event_listener.cc
@@ -54,21 +54,23 @@ V8AbstractEventListener::V8AbstractEventListener(v8::Isolate* isolate,
: EventListener(kJSEventListenerType),
is_attribute_(is_attribute),
world_(&world),
- isolate_(isolate),
- worker_or_worklet_global_scope_(nullptr) {
+ isolate_(isolate) {
if (IsMainThread())
InstanceCounters::IncrementCounter(
InstanceCounters::kJSEventListenerCounter);
- else
- worker_or_worklet_global_scope_ =
- ToWorkerOrWorkletGlobalScope(CurrentExecutionContext(isolate));
}
V8AbstractEventListener::~V8AbstractEventListener() {
- DCHECK(listener_.IsEmpty());
- if (IsMainThread())
+ // For non-main threads a termination garbage collection clears out the
+ // wrapper links to CustomWrappable which result in CustomWrappable not being
+ // rooted by JavaScript objects anymore. This means that
+ // V8AbstractEventListener can be collected without while still holding a
+ // valid weak references.
+ if (IsMainThread()) {
+ DCHECK(listener_.IsEmpty());
InstanceCounters::DecrementCounter(
InstanceCounters::kJSEventListenerCounter);
+ }
}
// static
@@ -78,8 +80,8 @@ v8::Local<v8::Value> V8AbstractEventListener::GetListenerOrNull(
EventListener* listener) {
if (listener && listener->GetType() == kJSEventListenerType) {
v8::Local<v8::Object> v8_listener =
- static_cast<V8AbstractEventListener*>(listener)->GetListenerObject(
- event_target->GetExecutionContext());
+ static_cast<V8AbstractEventListener*>(listener)
+ ->GetListenerObjectInternal(event_target->GetExecutionContext());
if (!v8_listener.IsEmpty())
return v8_listener;
}
@@ -122,15 +124,12 @@ void V8AbstractEventListener::HandleEvent(ScriptState* script_state,
}
void V8AbstractEventListener::SetListenerObject(
- v8::Local<v8::Object> listener) {
+ ScriptState* script_state,
+ v8::Local<v8::Object> listener,
+ const V8PrivateProperty::Symbol& property) {
DCHECK(listener_.IsEmpty());
- // Balanced in WrapperCleared xor ClearListenerObject.
- if (worker_or_worklet_global_scope_) {
- worker_or_worklet_global_scope_->RegisterEventListener(this);
- } else {
- keep_alive_ = this;
- }
listener_.Set(GetIsolate(), listener, this, &WrapperCleared);
+ Attach(script_state, listener, property, this);
}
void V8AbstractEventListener::InvokeEventHandler(
@@ -170,7 +169,7 @@ void V8AbstractEventListener::InvokeEventHandler(
return_value = CallListenerFunction(script_state, js_event, event);
if (try_catch.HasCaught())
- event->target()->UncaughtExceptionInEventHandler();
+ event->LegacySetDidListenersThrowFlag();
if (!try_catch.CanContinue()) { // Result of TerminateExecution().
ExecutionContext* execution_context = ToExecutionContext(context);
@@ -211,14 +210,15 @@ void V8AbstractEventListener::InvokeEventHandler(
ToBeforeUnloadEvent(event)->setReturnValue(string_return_value);
}
}
- } else if (ShouldPreventDefault(return_value) &&
+ } else if (ShouldPreventDefault(return_value, event) &&
event->type() != EventTypeNames::beforeunload) {
event->preventDefault();
}
}
bool V8AbstractEventListener::ShouldPreventDefault(
- v8::Local<v8::Value> return_value) {
+ v8::Local<v8::Value> return_value,
+ Event*) {
// Prevent default action if the return value is false in accord with the spec
// http://www.w3.org/TR/html5/webappapis.html#event-handler-attributes
return return_value->IsBoolean() && !return_value.As<v8::Boolean>()->Value();
@@ -261,11 +261,6 @@ void V8AbstractEventListener::ClearListenerObject() {
return;
probe::AsyncTaskCanceled(GetIsolate(), this);
listener_.Clear();
- if (worker_or_worklet_global_scope_) {
- worker_or_worklet_global_scope_->DeregisterEventListener(this);
- } else {
- keep_alive_.Clear();
- }
}
void V8AbstractEventListener::WrapperCleared(
@@ -275,7 +270,6 @@ void V8AbstractEventListener::WrapperCleared(
void V8AbstractEventListener::Trace(blink::Visitor* visitor) {
visitor->Trace(listener_.Cast<v8::Value>());
- visitor->Trace(worker_or_worklet_global_scope_);
EventListener::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_abstract_event_listener.h b/chromium/third_party/blink/renderer/bindings/core/v8/v8_abstract_event_listener.h
index cbd188ca77d..7ecb25f9e2c 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_abstract_event_listener.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_abstract_event_listener.h
@@ -34,7 +34,6 @@
#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/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/heap/self_keep_alive.h"
#include "v8/include/v8.h"
@@ -43,7 +42,6 @@ namespace blink {
class Event;
class EventTarget;
-class WorkerOrWorkletGlobalScope;
// There are two kinds of event listeners: HTML or non-HMTL. onload,
// onfocus, etc (attributes) are always HTML event handler type; Event
@@ -84,6 +82,11 @@ class CORE_EXPORT V8AbstractEventListener : public EventListener {
// Returns the listener object, either a function or an object, or the empty
// handle if the user script is not compilable. No exception will be thrown
// even if the user script is not compilable.
+ v8::Local<v8::Object> GetListenerObjectForInspector(
+ ExecutionContext* execution_context) final {
+ return GetListenerObjectInternal(execution_context);
+ }
+
v8::Local<v8::Object> GetListenerObject(ExecutionContext* execution_context) {
return GetListenerObjectInternal(execution_context);
}
@@ -107,7 +110,7 @@ class CORE_EXPORT V8AbstractEventListener : public EventListener {
bool IsAttribute() const final { return is_attribute_; }
v8::Isolate* GetIsolate() const { return isolate_; }
- DOMWrapperWorld& World() const { return *world_; }
+ DOMWrapperWorld* GetWorldForInspector() const final { return world_.get(); }
void Trace(blink::Visitor*) override;
@@ -119,12 +122,15 @@ class CORE_EXPORT V8AbstractEventListener : public EventListener {
return GetExistingListenerObject();
}
- void SetListenerObject(v8::Local<v8::Object>);
+ void SetListenerObject(ScriptState*,
+ v8::Local<v8::Object>,
+ const V8PrivateProperty::Symbol&);
void InvokeEventHandler(ScriptState*, Event*, v8::Local<v8::Value>);
// Get the receiver object to use for event listener call.
v8::Local<v8::Object> GetReceiverObject(ScriptState*, Event*);
+ DOMWrapperWorld& World() const { return *world_; }
private:
// This could return an empty handle and callers need to check return value.
@@ -132,7 +138,7 @@ class CORE_EXPORT V8AbstractEventListener : public EventListener {
virtual v8::Local<v8::Value>
CallListenerFunction(ScriptState*, v8::Local<v8::Value> jsevent, Event*) = 0;
- virtual bool ShouldPreventDefault(v8::Local<v8::Value> return_value);
+ virtual bool ShouldPreventDefault(v8::Local<v8::Value> return_value, Event*);
static void WrapperCleared(
const v8::WeakCallbackInfo<V8AbstractEventListener>&);
@@ -144,11 +150,6 @@ class CORE_EXPORT V8AbstractEventListener : public EventListener {
scoped_refptr<DOMWrapperWorld> world_;
v8::Isolate* isolate_;
-
- // nullptr unless this listener belongs to a worker or worklet.
- Member<WorkerOrWorkletGlobalScope> worker_or_worklet_global_scope_;
-
- SelfKeepAlive<V8AbstractEventListener> keep_alive_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_code_cache.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_code_cache.cc
index ad3eca49af9..727c3ee45e1 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
@@ -62,6 +62,14 @@ bool IsResourceHotForCaching(SingleCachedMetadataHandler* cache_handler,
} // namespace
+bool V8CodeCache::HasCodeCache(SingleCachedMetadataHandler* cache_handler) {
+ if (!cache_handler)
+ return false;
+
+ uint32_t code_cache_tag = V8CodeCache::TagForCodeCache(cache_handler);
+ return cache_handler->GetCachedMetadata(code_cache_tag).get();
+}
+
v8::ScriptCompiler::CachedData* V8CodeCache::CreateCachedData(
SingleCachedMetadataHandler* cache_handler) {
DCHECK(cache_handler);
@@ -124,10 +132,7 @@ V8CodeCache::GetCompileOptions(V8CacheOptions cache_options,
no_cache_reason);
}
- uint32_t code_cache_tag = V8CodeCache::TagForCodeCache(cache_handler);
- scoped_refptr<CachedMetadata> code_cache =
- cache_handler->GetCachedMetadata(code_cache_tag);
- if (code_cache) {
+ if (HasCodeCache(cache_handler)) {
return std::make_tuple(v8::ScriptCompiler::kConsumeCodeCache,
ProduceCacheOptions::kNoProduceCache,
no_cache_reason);
@@ -225,7 +230,7 @@ void V8CodeCache::ProduceCache(
compile_options, cached_data ? cached_data->length : 0),
base::Optional<InspectorCompileScriptEvent::V8CacheResult::
ConsumeResult>()),
- source.Streamer()));
+ source.Streamer(), source.NotStreamingReason()));
break;
}
case ProduceCacheOptions::kNoProduceCache:
@@ -314,7 +319,7 @@ scoped_refptr<CachedMetadata> V8CodeCache::GenerateFullCodeCache(
cached_data ? cached_data->length : 0),
base::Optional<
InspectorCompileScriptEvent::V8CacheResult::ConsumeResult>()),
- false));
+ false, ScriptStreamer::kHasCodeCache));
return cached_metadata;
}
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_code_cache.h b/chromium/third_party/blink/renderer/bindings/core/v8/v8_code_cache.h
index 8f85911f4b5..ddeaef84779 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_code_cache.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_code_cache.h
@@ -45,6 +45,10 @@ class CORE_EXPORT V8CodeCache final {
static uint32_t TagForTimeStamp(SingleCachedMetadataHandler*);
static void SetCacheTimeStamp(SingleCachedMetadataHandler*);
+ // Returns true iff the SingleCachedMetadataHandler contains a code cache
+ // that can be consumed by V8.
+ static bool HasCodeCache(SingleCachedMetadataHandler*);
+
static std::tuple<v8::ScriptCompiler::CompileOptions,
ProduceCacheOptions,
v8::ScriptCompiler::NoCacheReason>
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 41ef61f57bb..374e9031bbc 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,6 +114,8 @@ const WrapperTypeInfo* FieldTypeToWrapperTypeInfo(InternalFieldType type) {
struct DataForDeserializer {
STACK_ALLOCATED();
+
+ public:
Member<Document> document;
};
@@ -249,12 +251,19 @@ void V8ContextSnapshot::EnsureInterfaceTemplates(v8::Isolate* isolate) {
}
v8::HandleScope handle_scope(isolate);
+ // Update the install functions for V8Window and V8Document to work for their
+ // partial interfaces.
SnapshotInterface& snapshot_window = g_snapshot_interfaces[0];
DCHECK(V8Window::wrapperTypeInfo.Equals(snapshot_window.wrapper_type_info));
- // Update the install function for V8Window to work for partial interfaces.
snapshot_window.install_function =
V8Window::install_runtime_enabled_features_on_template_function_;
+ SnapshotInterface& snapshot_document = g_snapshot_interfaces[4];
+ DCHECK(
+ V8Document::wrapperTypeInfo.Equals(snapshot_document.wrapper_type_info));
+ snapshot_document.install_function =
+ V8Document::install_runtime_enabled_features_on_template_function_;
+
EnsureInterfaceTemplatesForWorld(isolate, DOMWrapperWorld::MainWorld());
// Any world types other than |kMain| are acceptable for this.
scoped_refptr<DOMWrapperWorld> isolated_world = DOMWrapperWorld::Create(
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 ed999f3f773..02c13e9fa53 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
@@ -52,6 +52,67 @@ bool WorldConfigurationApplies(
return true;
}
+void DoInstallAttribute(
+ v8::Local<v8::ObjectTemplate> object_template,
+ v8::Local<v8::Name> name,
+ const V8DOMConfiguration::AttributeConfiguration& attribute) {
+ v8::SideEffectType getter_side_effect_type =
+ attribute.getter_side_effect_type == V8DOMConfiguration::kHasNoSideEffect
+ ? v8::SideEffectType::kHasNoSideEffect
+ : v8::SideEffectType::kHasSideEffect;
+ switch (static_cast<V8DOMConfiguration::AttributeGetterBehavior>(
+ attribute.getter_behavior)) {
+ case V8DOMConfiguration::kAlwaysCallGetter:
+ object_template->SetNativeDataProperty(
+ name, attribute.getter, attribute.setter, v8::Local<v8::Value>(),
+ static_cast<v8::PropertyAttribute>(attribute.attribute),
+ v8::Local<v8::AccessorSignature>(), v8::AccessControl::DEFAULT,
+ getter_side_effect_type);
+ break;
+ case V8DOMConfiguration::kReplaceWithDataProperty:
+ DCHECK(!attribute.setter);
+ DCHECK_EQ(attribute.world_configuration, V8DOMConfiguration::kAllWorlds);
+ object_template->SetLazyDataProperty(
+ name, attribute.getter, v8::Local<v8::Value>(),
+ static_cast<v8::PropertyAttribute>(attribute.attribute),
+ getter_side_effect_type);
+ break;
+ }
+}
+
+void DoInstallAttribute(
+ v8::Local<v8::Context> context,
+ v8::Local<v8::Object> object,
+ v8::Local<v8::Name> name,
+ const V8DOMConfiguration::AttributeConfiguration& attribute) {
+ v8::SideEffectType getter_side_effect_type =
+ attribute.getter_side_effect_type == V8DOMConfiguration::kHasNoSideEffect
+ ? v8::SideEffectType::kHasNoSideEffect
+ : v8::SideEffectType::kHasSideEffect;
+ switch (static_cast<V8DOMConfiguration::AttributeGetterBehavior>(
+ attribute.getter_behavior)) {
+ case V8DOMConfiguration::kAlwaysCallGetter:
+ object
+ ->SetNativeDataProperty(
+ context, name, attribute.getter, attribute.setter,
+ v8::Local<v8::Value>(),
+ static_cast<v8::PropertyAttribute>(attribute.attribute),
+ getter_side_effect_type)
+ .ToChecked();
+ break;
+ case V8DOMConfiguration::kReplaceWithDataProperty:
+ DCHECK(!attribute.setter);
+ DCHECK_EQ(attribute.world_configuration, V8DOMConfiguration::kAllWorlds);
+ object
+ ->SetLazyDataProperty(
+ context, name, attribute.getter, v8::Local<v8::Value>(),
+ static_cast<v8::PropertyAttribute>(attribute.attribute),
+ getter_side_effect_type)
+ .ToChecked();
+ break;
+ }
+}
+
void InstallAttributeInternal(
v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> instance_template,
@@ -62,32 +123,13 @@ void InstallAttributeInternal(
return;
v8::Local<v8::Name> name = V8AtomicString(isolate, attribute.name);
- v8::AccessorNameGetterCallback getter = attribute.getter;
- v8::AccessorNameSetterCallback setter = attribute.setter;
-
- v8::SideEffectType getter_side_effect_type =
- attribute.getter_side_effect_type == V8DOMConfiguration::kHasNoSideEffect
- ? v8::SideEffectType::kHasNoSideEffect
- : v8::SideEffectType::kHasSideEffect;
- DCHECK(attribute.property_location_configuration);
- if (attribute.property_location_configuration &
- V8DOMConfiguration::kOnInstance) {
- instance_template->SetNativeDataProperty(
- name, getter, setter, v8::Local<v8::Value>(),
- static_cast<v8::PropertyAttribute>(attribute.attribute),
- v8::Local<v8::AccessorSignature>(), v8::AccessControl::DEFAULT,
- getter_side_effect_type);
- }
- if (attribute.property_location_configuration &
- V8DOMConfiguration::kOnPrototype) {
- prototype_template->SetNativeDataProperty(
- name, getter, setter, v8::Local<v8::Value>(),
- static_cast<v8::PropertyAttribute>(attribute.attribute),
- v8::Local<v8::AccessorSignature>(), v8::AccessControl::DEFAULT,
- getter_side_effect_type);
- }
- if (attribute.property_location_configuration &
- V8DOMConfiguration::kOnInterface)
+ const unsigned location = attribute.property_location_configuration;
+ DCHECK(location);
+ if (location & V8DOMConfiguration::kOnInstance)
+ DoInstallAttribute(instance_template, name, attribute);
+ if (location & V8DOMConfiguration::kOnPrototype)
+ DoInstallAttribute(prototype_template, name, attribute);
+ if (location & V8DOMConfiguration::kOnInterface)
NOTREACHED();
}
@@ -102,71 +144,17 @@ void InstallAttributeInternal(
return;
v8::Local<v8::Name> name = V8AtomicString(isolate, config.name);
- v8::AccessorNameGetterCallback getter = config.getter;
- v8::AccessorNameSetterCallback setter = config.setter;
- v8::PropertyAttribute attribute =
- static_cast<v8::PropertyAttribute>(config.attribute);
const unsigned location = config.property_location_configuration;
DCHECK(location);
-
- v8::SideEffectType getter_side_effect_type =
- config.getter_side_effect_type == V8DOMConfiguration::kHasNoSideEffect
- ? v8::SideEffectType::kHasNoSideEffect
- : v8::SideEffectType::kHasSideEffect;
v8::Local<v8::Context> context = isolate->GetCurrentContext();
- if (location & V8DOMConfiguration::kOnInstance && !instance.IsEmpty()) {
- instance
- ->SetNativeDataProperty(context, name, getter, setter,
- v8::Local<v8::Value>(), attribute,
- getter_side_effect_type)
- .ToChecked();
- }
- if (location & V8DOMConfiguration::kOnPrototype && !prototype.IsEmpty()) {
- prototype
- ->SetNativeDataProperty(context, name, getter, setter,
- v8::Local<v8::Value>(), attribute,
- getter_side_effect_type)
- .ToChecked();
- }
+ if (location & V8DOMConfiguration::kOnInstance && !instance.IsEmpty())
+ DoInstallAttribute(context, instance, name, config);
+ if (location & V8DOMConfiguration::kOnPrototype && !prototype.IsEmpty())
+ DoInstallAttribute(context, prototype, name, config);
if (location & V8DOMConfiguration::kOnInterface)
NOTREACHED();
}
-void InstallLazyDataAttributeInternal(
- v8::Isolate* isolate,
- v8::Local<v8::ObjectTemplate> instance_template,
- v8::Local<v8::ObjectTemplate> prototype_template,
- const V8DOMConfiguration::AttributeConfiguration& attribute,
- const DOMWrapperWorld& world) {
- v8::Local<v8::Name> name = V8AtomicString(isolate, attribute.name);
- v8::AccessorNameGetterCallback getter = attribute.getter;
- DCHECK(!attribute.setter);
- DCHECK_EQ(attribute.world_configuration, V8DOMConfiguration::kAllWorlds);
-
- v8::SideEffectType getter_side_effect_type =
- attribute.getter_side_effect_type == V8DOMConfiguration::kHasNoSideEffect
- ? v8::SideEffectType::kHasNoSideEffect
- : v8::SideEffectType::kHasSideEffect;
- DCHECK(attribute.property_location_configuration);
- if (attribute.property_location_configuration &
- V8DOMConfiguration::kOnInstance) {
- instance_template->SetLazyDataProperty(
- name, getter, v8::Local<v8::Value>(),
- static_cast<v8::PropertyAttribute>(attribute.attribute),
- getter_side_effect_type);
- }
- if (attribute.property_location_configuration &
- V8DOMConfiguration::kOnPrototype) {
- prototype_template->SetLazyDataProperty(
- name, getter, v8::Local<v8::Value>(),
- static_cast<v8::PropertyAttribute>(attribute.attribute),
- getter_side_effect_type);
- }
- if (attribute.property_location_configuration &
- V8DOMConfiguration::kOnInterface)
- NOTREACHED();
-}
-
template <class FunctionOrTemplate>
v8::Local<FunctionOrTemplate> CreateAccessorFunctionOrTemplate(
v8::Isolate*,
@@ -265,6 +253,7 @@ void InstallAccessorInternal(
DCHECK(!IsObjectAndEmpty(instance_or_template) ||
!IsObjectAndEmpty(prototype_or_template) ||
!IsObjectAndEmpty(interface_or_template));
+ DCHECK_EQ(config.getter_behavior, V8DOMConfiguration::kAlwaysCallGetter);
if (!WorldConfigurationApplies(config, world))
return;
@@ -598,19 +587,6 @@ void V8DOMConfiguration::InstallAttribute(
InstallAttributeInternal(isolate, instance, prototype, attribute, world);
}
-void V8DOMConfiguration::InstallLazyDataAttributes(
- v8::Isolate* isolate,
- const DOMWrapperWorld& world,
- v8::Local<v8::ObjectTemplate> instance_template,
- v8::Local<v8::ObjectTemplate> prototype_template,
- const AttributeConfiguration* attributes,
- size_t attribute_count) {
- for (size_t i = 0; i < attribute_count; ++i) {
- InstallLazyDataAttributeInternal(isolate, instance_template,
- prototype_template, attributes[i], world);
- }
-}
-
void V8DOMConfiguration::InstallAccessors(
v8::Isolate* isolate,
const DOMWrapperWorld& world,
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 db207052d54..e41cea3c713 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
@@ -71,6 +71,14 @@ class CORE_EXPORT V8DOMConfiguration final {
kHasNoSideEffect,
};
+ enum AttributeGetterBehavior : unsigned {
+ // The getter will be called each time the property is gotten.
+ kAlwaysCallGetter,
+ // After the first access, the property will be turned into a plain data
+ // property, taking the value returned by the getter.
+ kReplaceWithDataProperty,
+ };
+
// Bit field to select which worlds the member will be defined in.
enum WorldConfiguration : unsigned {
kMainWorld = 1 << 0,
@@ -95,6 +103,8 @@ class CORE_EXPORT V8DOMConfiguration final {
unsigned holder_check_configuration : 1;
// SideEffectConfiguration
unsigned getter_side_effect_type : 1;
+ // AttributeGetterBehavior
+ unsigned getter_behavior : 1;
// WorldConfiguration
unsigned world_configuration : 2;
};
@@ -126,20 +136,6 @@ class CORE_EXPORT V8DOMConfiguration final {
v8::Local<v8::Object> prototype,
const AttributeConfiguration&);
- // A lazy data attribute is like one of the attributes added via
- // installAttributes(), however, V8 will attempt to replace it with the value
- // returned by the getter callback, turning it into a real data value.
- //
- // This also means that the AttributeConfiguration must not specify a setter,
- // nor any non-default attributes.
- static void InstallLazyDataAttributes(
- v8::Isolate*,
- const DOMWrapperWorld&,
- v8::Local<v8::ObjectTemplate> instance_template,
- v8::Local<v8::ObjectTemplate> prototype_template,
- const AttributeConfiguration*,
- size_t attribute_count);
-
// AccessorConfiguration translates into calls to SetAccessorProperty() on
// either of instance, prototype, or interface object (or their object
// template).
@@ -159,6 +155,8 @@ class CORE_EXPORT V8DOMConfiguration final {
unsigned holder_check_configuration : 1;
// SideEffectConfiguration
unsigned getter_side_effect_type : 1;
+ // AttributeGetterBehavior (should always be kReplaceWithDataProperty)
+ unsigned getter_behavior : 1;
// WorldConfiguration
unsigned world_configuration : 2;
};
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_embedder_graph_builder.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_embedder_graph_builder.cc
index 016b2461d4a..f3e3cf22faa 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
@@ -17,7 +17,10 @@ namespace blink {
V8EmbedderGraphBuilder::V8EmbedderGraphBuilder(v8::Isolate* isolate,
Graph* graph)
- : isolate_(isolate), current_parent_(nullptr), graph_(graph) {}
+ : ScriptWrappableVisitor(ThreadState::Current()),
+ isolate_(isolate),
+ current_parent_(nullptr),
+ graph_(graph) {}
void V8EmbedderGraphBuilder::BuildEmbedderGraphCallback(
v8::Isolate* isolate,
@@ -156,6 +159,8 @@ void V8EmbedderGraphBuilder::VisitWithWrappers(
void V8EmbedderGraphBuilder::VisitBackingStoreStrongly(void* object,
void** object_slot,
TraceDescriptor desc) {
+ if (!object)
+ return;
desc.callback(this, desc.base_object_payload);
}
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_error_handler.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_error_handler.cc
index 005c55c13e0..24f422f2818 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_error_handler.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_error_handler.cc
@@ -40,23 +40,22 @@
namespace blink {
V8ErrorHandler::V8ErrorHandler(bool is_inline, ScriptState* script_state)
- : V8EventListener(is_inline, script_state) {}
+ : V8EventListenerOrEventHandler(is_inline, script_state) {}
v8::Local<v8::Value> V8ErrorHandler::CallListenerFunction(
ScriptState* script_state,
v8::Local<v8::Value> js_event,
Event* event) {
DCHECK(!js_event.IsEmpty());
- if (!event->HasInterface(EventNames::ErrorEvent))
- return V8EventListener::CallListenerFunction(script_state, js_event, event);
+ if (!event->HasInterface(EventNames::ErrorEvent)) {
+ return V8EventListenerOrEventHandler::CallListenerFunction(script_state,
+ js_event, event);
+ }
ErrorEvent* error_event = static_cast<ErrorEvent*>(event);
- if (error_event->World() && error_event->World() != &World())
- return v8::Null(GetIsolate());
-
v8::Local<v8::Context> context = script_state->GetContext();
ExecutionContext* execution_context = ToExecutionContext(context);
- v8::Local<v8::Object> listener = GetListenerObject(execution_context);
+ v8::Local<v8::Object> listener = GetListenerObjectInternal(execution_context);
if (listener.IsEmpty() || !listener->IsFunction())
return v8::Null(GetIsolate());
@@ -130,8 +129,15 @@ v8::Local<v8::Value> V8ErrorHandler::LoadExceptionFromErrorEventWrapper(
return error;
}
-bool V8ErrorHandler::ShouldPreventDefault(v8::Local<v8::Value> return_value) {
- return return_value->IsBoolean() && return_value.As<v8::Boolean>()->Value();
+bool V8ErrorHandler::ShouldPreventDefault(v8::Local<v8::Value> return_value,
+ Event* event) {
+ // Special event handling should be done here according to HTML Standard:
+ // https://html.spec.whatwg.org/multipage/webappapis.html#the-event-handler-processing-algorithm
+ // We do not need to check current target of event because it must be window
+ // or worker on calling this method.
+ if (event->HasInterface(EventNames::ErrorEvent) && event->type() == "error")
+ return return_value->IsBoolean() && return_value.As<v8::Boolean>()->Value();
+ return return_value->IsBoolean() && !return_value.As<v8::Boolean>()->Value();
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_error_handler.h b/chromium/third_party/blink/renderer/bindings/core/v8/v8_error_handler.h
index 39b09623b04..7a5d197dabe 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_error_handler.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_error_handler.h
@@ -32,21 +32,22 @@
#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_V8_ERROR_HANDLER_H_
#include "base/memory/scoped_refptr.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_event_listener.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_event_listener_or_event_handler.h"
#include "v8/include/v8.h"
namespace blink {
class ErrorEvent;
-class V8ErrorHandler final : public V8EventListener {
+class V8ErrorHandler final : public V8EventListenerOrEventHandler {
public:
static V8ErrorHandler* Create(v8::Local<v8::Object> listener,
bool is_inline,
- ScriptState* script_state) {
+ ScriptState* script_state,
+ const V8PrivateProperty::Symbol& property) {
V8ErrorHandler* event_listener =
new V8ErrorHandler(is_inline, script_state);
- event_listener->SetListenerObject(listener);
+ event_listener->SetListenerObject(script_state, listener, property);
return event_listener;
}
static void StoreExceptionOnErrorEventWrapper(
@@ -64,7 +65,7 @@ class V8ErrorHandler final : public V8EventListener {
v8::Local<v8::Value> CallListenerFunction(ScriptState*,
v8::Local<v8::Value>,
Event*) override;
- bool ShouldPreventDefault(v8::Local<v8::Value> return_value) override;
+ bool ShouldPreventDefault(v8::Local<v8::Value> return_value, Event*) override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener_helper.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener_helper.cc
index 53983941d66..45c29da9c77 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener_helper.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener_helper.cc
@@ -30,11 +30,11 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_event_listener_helper.h"
+#include "third_party/blink/renderer/bindings/core/v8/custom_wrappable_adapter.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_error_handler.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_event_listener.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_event_listener_or_event_handler.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_window.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_worker_or_worklet_event_listener.h"
#include "third_party/blink/renderer/platform/bindings/v8_private_property.h"
namespace blink {
@@ -42,34 +42,24 @@ namespace {
template <typename ListenerType, typename ListenerFactory>
ListenerType* GetEventListenerInternal(
- v8::Isolate* isolate,
+ ScriptState* script_state,
v8::Local<v8::Object> object,
const V8PrivateProperty::Symbol& listener_property,
ListenerLookupType lookup,
const ListenerFactory& listener_factory) {
- DCHECK(isolate->InContext());
- v8::Local<v8::Value> listener_value;
- if (!listener_property.GetOrUndefined(object).ToLocal(&listener_value))
- return nullptr;
+ DCHECK(script_state->GetIsolate()->InContext());
ListenerType* listener =
- listener_value->IsUndefined()
- ? nullptr
- : static_cast<ListenerType*>(
- listener_value.As<v8::External>()->Value());
+ CustomWrappableAdapter::Lookup<ListenerType>(object, listener_property);
if (listener || lookup == kListenerFindOnly)
return listener;
- listener = listener_factory();
- if (listener)
- listener_property.Set(object, v8::External::New(isolate, listener));
-
- return listener;
+ return listener_factory();
}
} // namespace
// static
-V8EventListener* V8EventListenerHelper::GetEventListener(
+EventListener* V8EventListenerHelper::GetEventListener(
ScriptState* script_state,
v8::Local<v8::Value> value,
bool is_attribute,
@@ -83,22 +73,21 @@ V8EventListener* V8EventListenerHelper::GetEventListener(
v8::Isolate* isolate = script_state->GetIsolate();
V8PrivateProperty::Symbol listener_property =
is_attribute
- ? V8PrivateProperty::GetV8EventListenerAttributeListener(isolate)
- : V8PrivateProperty::GetV8EventListenerListener(isolate);
+ ? V8PrivateProperty::
+ GetV8EventListenerOrEventHandlerAttributeListener(isolate)
+ : V8PrivateProperty::GetV8EventListenerOrEventHandlerListener(
+ isolate);
- return GetEventListenerInternal<V8EventListener>(
- isolate, object, listener_property, lookup,
- [object, is_attribute, script_state]() {
- return script_state->World().IsWorkerWorld()
- ? V8WorkerOrWorkletEventListener::Create(
- object, is_attribute, script_state)
- : V8EventListener::Create(object, is_attribute,
- script_state);
+ return GetEventListenerInternal<V8AbstractEventListener>(
+ script_state, object, listener_property, lookup,
+ [object, is_attribute, script_state, listener_property]() {
+ return V8EventListenerOrEventHandler::Create(
+ object, is_attribute, script_state, listener_property);
});
}
// static
-V8ErrorHandler* V8EventListenerHelper::EnsureErrorHandler(
+EventListener* V8EventListenerHelper::EnsureErrorHandler(
ScriptState* script_state,
v8::Local<v8::Value> value) {
if (!value->IsObject())
@@ -109,10 +98,11 @@ V8ErrorHandler* V8EventListenerHelper::EnsureErrorHandler(
V8PrivateProperty::GetV8ErrorHandlerErrorHandler(isolate);
return GetEventListenerInternal<V8ErrorHandler>(
- isolate, object, listener_property, kListenerFindOrCreate,
- [object, script_state]() {
+ script_state, object, listener_property, kListenerFindOrCreate,
+ [object, script_state, listener_property]() {
const bool is_attribute = true;
- return V8ErrorHandler::Create(object, is_attribute, script_state);
+ return V8ErrorHandler::Create(object, is_attribute, script_state,
+ listener_property);
});
}
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener_helper.h b/chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener_helper.h
index b1e1dc0746b..e1052102cd9 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener_helper.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener_helper.h
@@ -32,34 +32,30 @@
#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_V8_EVENT_LISTENER_HELPER_H_
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_event_listener.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
#include "v8/include/v8.h"
namespace blink {
-class V8EventListener;
-class V8ErrorHandler;
-
enum ListenerLookupType {
kListenerFindOnly,
kListenerFindOrCreate,
};
-// This is a container for V8EventListener objects that uses hidden properties
-// of v8::Object to speed up lookups.
+// This is a container for V8EventListenerOrEventHandler objects that uses
+// hidden properties of v8::Object to speed up lookups.
class V8EventListenerHelper {
STATIC_ONLY(V8EventListenerHelper);
public:
- CORE_EXPORT static V8EventListener* GetEventListener(ScriptState*,
- v8::Local<v8::Value>,
- bool is_attribute,
- ListenerLookupType);
+ CORE_EXPORT static EventListener* GetEventListener(ScriptState*,
+ v8::Local<v8::Value>,
+ bool is_attribute,
+ ListenerLookupType);
- CORE_EXPORT static V8ErrorHandler* EnsureErrorHandler(ScriptState*,
- v8::Local<v8::Value>);
+ CORE_EXPORT static EventListener* EnsureErrorHandler(ScriptState*,
+ v8::Local<v8::Value>);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener_or_event_handler.cc
index 9770f7f62e4..4a87e264292 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener_or_event_handler.cc
@@ -28,7 +28,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "third_party/blink/renderer/bindings/core/v8/v8_event_listener.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_event_listener_or_event_handler.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"
@@ -39,15 +39,17 @@
namespace blink {
-V8EventListener::V8EventListener(bool is_attribute, ScriptState* script_state)
+V8EventListenerOrEventHandler::V8EventListenerOrEventHandler(
+ bool is_attribute,
+ ScriptState* script_state)
: V8AbstractEventListener(script_state->GetIsolate(),
is_attribute,
script_state->World()) {}
-v8::Local<v8::Function> V8EventListener::GetListenerFunction(
+v8::Local<v8::Function> V8EventListenerOrEventHandler::GetListenerFunction(
ScriptState* script_state) {
v8::Local<v8::Object> listener =
- GetListenerObject(ExecutionContext::From(script_state));
+ GetListenerObjectInternal(ExecutionContext::From(script_state));
// Has the listener been disposed?
if (listener.IsEmpty())
@@ -85,7 +87,7 @@ v8::Local<v8::Function> V8EventListener::GetListenerFunction(
return v8::Local<v8::Function>();
}
-v8::Local<v8::Value> V8EventListener::CallListenerFunction(
+v8::Local<v8::Value> V8EventListenerOrEventHandler::CallListenerFunction(
ScriptState* script_state,
v8::Local<v8::Value> js_event,
Event* event) {
@@ -97,12 +99,6 @@ v8::Local<v8::Value> V8EventListener::CallListenerFunction(
ExecutionContext* execution_context =
ToExecutionContext(script_state->GetContext());
- if (!execution_context->IsDocument())
- return v8::Local<v8::Value>();
-
- LocalFrame* frame = ToDocument(execution_context)->GetFrame();
- if (!frame)
- return v8::Local<v8::Value>();
// TODO(jochen): Consider moving this check into canExecuteScripts.
// http://crbug.com/608641
@@ -112,7 +108,7 @@ v8::Local<v8::Value> V8EventListener::CallListenerFunction(
v8::Local<v8::Value> parameters[1] = {js_event};
v8::Local<v8::Value> result;
- if (!V8ScriptRunner::CallFunction(handler_function, frame->GetDocument(),
+ if (!V8ScriptRunner::CallFunction(handler_function, execution_context,
receiver, base::size(parameters),
parameters, script_state->GetIsolate())
.ToLocal(&result))
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener.h b/chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener_or_event_handler.h
index 0bf5edf137f..c6c968023d7 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener_or_event_handler.h
@@ -28,8 +28,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_V8_EVENT_LISTENER_H_
-#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_V8_EVENT_LISTENER_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_V8_EVENT_LISTENER_OR_EVENT_HANDLER_H_
+#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_V8_EVENT_LISTENER_OR_EVENT_HANDLER_H_
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_abstract_event_listener.h"
@@ -39,22 +39,24 @@ namespace blink {
class Event;
-// V8EventListener is a wrapper of a JS object implements EventListener
-// interface (has handleEvent(event) method), or a JS function that can handle
-// the event.
-class V8EventListener : public V8AbstractEventListener {
+// V8EventListenerOrEventHandler is a wrapper of a JS object implements
+// EventListener interface (has handleEvent(event) method), or a JS function
+// that can handle the event.
+class V8EventListenerOrEventHandler : public V8AbstractEventListener {
public:
- static V8EventListener* Create(v8::Local<v8::Object> listener,
- bool is_attribute,
- ScriptState* script_state) {
- V8EventListener* event_listener =
- new V8EventListener(is_attribute, script_state);
- event_listener->SetListenerObject(listener);
+ static V8EventListenerOrEventHandler* Create(
+ v8::Local<v8::Object> listener,
+ bool is_attribute,
+ ScriptState* script_state,
+ const V8PrivateProperty::Symbol& property) {
+ V8EventListenerOrEventHandler* event_listener =
+ new V8EventListenerOrEventHandler(is_attribute, script_state);
+ event_listener->SetListenerObject(script_state, listener, property);
return event_listener;
}
protected:
- V8EventListener(bool is_attribute, ScriptState*);
+ V8EventListenerOrEventHandler(bool is_attribute, ScriptState*);
v8::Local<v8::Function> GetListenerFunction(ScriptState*);
v8::Local<v8::Value> CallListenerFunction(ScriptState*,
v8::Local<v8::Value>,
@@ -63,4 +65,4 @@ class V8EventListener : public V8AbstractEventListener {
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_V8_EVENT_LISTENER_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_V8_EVENT_LISTENER_OR_EVENT_HANDLER_H_
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_gc_controller.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_gc_controller.cc
index ff242d1984c..af266464044 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_gc_controller.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_gc_controller.cc
@@ -75,6 +75,12 @@ Node* V8GCController::OpaqueRootForGC(v8::Isolate*, Node* node) {
return node;
}
+bool IsDOMWrapperClassId(uint16_t class_id) {
+ return class_id == WrapperTypeInfo::kNodeClassId ||
+ class_id == WrapperTypeInfo::kObjectClassId ||
+ class_id == WrapperTypeInfo::kCustomWrappableId;
+}
+
class MinorGCUnmodifiedWrapperVisitor : public v8::PersistentHandleVisitor {
public:
explicit MinorGCUnmodifiedWrapperVisitor(v8::Isolate* isolate)
@@ -82,8 +88,11 @@ class MinorGCUnmodifiedWrapperVisitor : public v8::PersistentHandleVisitor {
void VisitPersistentHandle(v8::Persistent<v8::Value>* value,
uint16_t class_id) override {
- if (class_id != WrapperTypeInfo::kNodeClassId &&
- class_id != WrapperTypeInfo::kObjectClassId) {
+ if (!IsDOMWrapperClassId(class_id))
+ return;
+
+ if (class_id == WrapperTypeInfo::kCustomWrappableId) {
+ v8::Persistent<v8::Object>::Cast(*value).MarkActive();
return;
}
@@ -331,12 +340,19 @@ class DOMWrapperTracer final : public v8::PersistentHandleVisitor {
void VisitPersistentHandle(v8::Persistent<v8::Value>* value,
uint16_t class_id) final {
- if (class_id != WrapperTypeInfo::kNodeClassId &&
- class_id != WrapperTypeInfo::kObjectClassId)
+ if (!IsDOMWrapperClassId(class_id))
+ return;
+
+ WrapperTypeInfo* wrapper_type_info = const_cast<WrapperTypeInfo*>(
+ ToWrapperTypeInfo(v8::Persistent<v8::Object>::Cast(*value)));
+
+ // WrapperTypeInfo pointer may have been cleared before termination GCs on
+ // worker threads.
+ if (!wrapper_type_info)
return;
- visitor_->Trace(
- ToScriptWrappable(v8::Persistent<v8::Object>::Cast(*value)));
+ wrapper_type_info->Trace(
+ visitor_, ToUntypedWrappable(v8::Persistent<v8::Object>::Cast(*value)));
}
private:
@@ -351,8 +367,7 @@ class DOMWrapperPurger final : public v8::PersistentHandleVisitor {
void VisitPersistentHandle(v8::Persistent<v8::Value>* value,
uint16_t class_id) final {
- if (class_id != WrapperTypeInfo::kNodeClassId &&
- class_id != WrapperTypeInfo::kObjectClassId)
+ if (!IsDOMWrapperClassId(class_id))
return;
// Clear out wrapper type information, essentially disconnecting the Blink
@@ -364,7 +379,6 @@ class DOMWrapperPurger final : public v8::PersistentHandleVisitor {
isolate_, v8::Persistent<v8::Object>::Cast(*value));
wrapper->SetAlignedPointerInInternalFields(base::size(indices), indices,
values);
- value->Reset();
}
private:
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_gc_for_context_dispose.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_gc_for_context_dispose.cc
index 948e9827edd..ca7df9ddace 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_gc_for_context_dispose.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_gc_for_context_dispose.cc
@@ -76,8 +76,9 @@ void V8GCForContextDispose::NotifyContextDisposed(
// memory use and trigger a V8+Blink GC. However, on Android, if the frame
// will not be reused, the process will likely to be killed soon so skip this.
if (is_main_frame && frame_reuse_status == WindowProxy::kFrameWillBeReused &&
- MemoryCoordinator::IsLowEndDevice() &&
- MemoryCoordinator::IsCurrentlyLowMemory()) {
+ ((MemoryCoordinator::IsLowEndDevice() &&
+ MemoryCoordinator::IsCurrentlyLowMemory()) ||
+ force_page_navigation_gc_)) {
size_t pre_gc_memory_usage = GetMemoryUsage();
V8PerIsolateData::MainThreadIsolate()->MemoryPressureNotification(
v8::MemoryPressureLevel::kCritical);
@@ -88,6 +89,8 @@ void V8GCForContextDispose::NotifyContextDisposed(
CustomCountHistogram, reduction_histogram,
("BlinkGC.LowMemoryPageNavigationGC.Reduction", 1, 512, 50));
reduction_histogram.Count(reduction / 1024 / 1024);
+
+ force_page_navigation_gc_ = false;
}
#endif
V8PerIsolateData::MainThreadIsolate()->ContextDisposedNotification(
@@ -120,4 +123,8 @@ void V8GCForContextDispose::Reset() {
last_context_disposal_time_ = -1;
}
+void V8GCForContextDispose::SetForcePageNavigationGC() {
+ force_page_navigation_gc_ = true;
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_gc_for_context_dispose.h b/chromium/third_party/blink/renderer/bindings/core/v8/v8_gc_for_context_dispose.h
index 6e6dc408048..a47b1817ad0 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_gc_for_context_dispose.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_gc_for_context_dispose.h
@@ -32,6 +32,7 @@
#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_V8_GC_FOR_CONTEXT_DISPOSE_H_
#include "third_party/blink/renderer/bindings/core/v8/window_proxy.h"
+#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/timer.h"
namespace blink {
@@ -44,7 +45,12 @@ class V8GCForContextDispose {
void NotifyContextDisposed(bool is_main_frame, WindowProxy::FrameReuseStatus);
void NotifyIdle();
- static V8GCForContextDispose& Instance();
+ CORE_EXPORT static V8GCForContextDispose& Instance();
+
+ // Called by OomInterventionImpl. If intervention runs on the previous page,
+ // it means that the memory usage is high and needs gc during navigation to
+ // the next page, so that the memory usage of the two pages would not overlap.
+ CORE_EXPORT void SetForcePageNavigationGC();
private:
V8GCForContextDispose(); // Use instance() instead.
@@ -54,6 +60,7 @@ class V8GCForContextDispose {
TaskRunnerTimer<V8GCForContextDispose> pseudo_idle_timer_;
bool did_dispose_context_for_main_frame_;
double last_context_disposal_time_;
+ bool force_page_navigation_gc_;
};
} // namespace blink
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 83a6639306a..de5c4b11829 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
@@ -58,11 +58,11 @@
#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/inspector/main_thread_debugger.h"
+#include "third_party/blink/renderer/core/origin_trials/origin_trials.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/script/modulator.h"
#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
#include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h"
-#include "third_party/blink/renderer/platform/bindings/script_wrappable_marking_visitor.h"
#include "third_party/blink/renderer/platform/bindings/v8_per_context_data.h"
#include "third_party/blink/renderer/platform/bindings/v8_private_property.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
@@ -73,6 +73,7 @@
#include "third_party/blink/renderer/platform/weborigin/security_violation_reporting_policy.h"
#include "third_party/blink/renderer/platform/wtf/address_sanitizer.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
+#include "third_party/blink/renderer/platform/wtf/stack_util.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.h"
#include "v8/include/v8-profiler.h"
@@ -505,6 +506,14 @@ static bool WasmCodeGenerationCheckCallbackInMainThread(
return false;
}
+static bool WasmThreadsEnabledCallback(v8::Local<v8::Context> context) {
+ ExecutionContext* execution_context = ToExecutionContext(context);
+ if (!execution_context)
+ return false;
+
+ return OriginTrials::WebAssemblyThreadsEnabled(execution_context);
+}
+
v8::Local<v8::Value> NewRangeException(v8::Isolate* isolate,
const char* message) {
return v8::Exception::RangeError(
@@ -552,8 +561,7 @@ static bool WasmInstanceOverride(
v8::Local<v8::WasmCompiledModule> module =
v8::Local<v8::WasmCompiledModule>::Cast(source);
- if (static_cast<size_t>(module->GetWasmWireBytes()->Length()) >
- kWasmWireBytesLimit) {
+ if (module->GetWasmWireBytesRef().size > kWasmWireBytesLimit) {
ThrowRangeException(
args.GetIsolate(),
"WebAssembly.Instance is disallowed on the main thread, "
@@ -623,10 +631,7 @@ static void HostGetImportMetaProperties(v8::Local<v8::Context> context,
static void InitializeV8Common(v8::Isolate* isolate) {
isolate->AddGCPrologueCallback(V8GCController::GcPrologue);
isolate->AddGCEpilogueCallback(V8GCController::GcEpilogue);
- std::unique_ptr<ScriptWrappableMarkingVisitor> visitor(
- new ScriptWrappableMarkingVisitor(isolate));
- V8PerIsolateData::From(isolate)->SetScriptWrappableMarkingVisitor(
- std::move(visitor));
+
isolate->SetEmbedderHeapTracer(
V8PerIsolateData::From(isolate)->GetScriptWrappableMarkingVisitor());
@@ -635,6 +640,7 @@ static void InitializeV8Common(v8::Isolate* isolate) {
isolate->SetUseCounterCallback(&UseCounterCallback);
isolate->SetWasmModuleCallback(WasmModuleOverride);
isolate->SetWasmInstanceCallback(WasmInstanceOverride);
+ isolate->SetWasmThreadsEnabledCallback(WasmThreadsEnabledCallback);
if (RuntimeEnabledFeatures::ModuleScriptsDynamicImportEnabled()) {
isolate->SetHostImportModuleDynamicallyCallback(
HostImportModuleDynamically);
@@ -783,11 +789,6 @@ static void ReportFatalErrorInWorker(const char* location,
// base/threading/platform_thread_mac.mm for details.
static const int kWorkerMaxStackSize = 500 * 1024;
-// This function uses a local stack variable to determine the isolate's stack
-// limit. AddressSanitizer may relocate that local variable to a fake stack,
-// which may lead to problems during JavaScript execution. Therefore we disable
-// AddressSanitizer for V8Initializer::initializeWorker().
-NO_SANITIZE_ADDRESS
void V8Initializer::InitializeWorker(v8::Isolate* isolate) {
InitializeV8Common(isolate);
@@ -798,9 +799,7 @@ void V8Initializer::InitializeWorker(v8::Isolate* isolate) {
v8::Isolate::kMessageLog);
isolate->SetFatalErrorHandler(ReportFatalErrorInWorker);
- uint32_t here;
- isolate->SetStackLimit(reinterpret_cast<uintptr_t>(&here) -
- kWorkerMaxStackSize);
+ isolate->SetStackLimit(WTF::GetCurrentStackPosition() - kWorkerMaxStackSize);
isolate->SetPromiseRejectCallback(PromiseRejectHandlerInWorker);
if (RuntimeEnabledFeatures::BloatedRendererDetectionEnabled()) {
isolate->AddNearHeapLimitCallback(NearHeapLimitCallbackOnWorkerThread,
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_lazy_event_listener.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_lazy_event_listener.cc
index 0313cfc9ed6..8f79c2fea09 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_lazy_event_listener.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_lazy_event_listener.cc
@@ -90,7 +90,8 @@ v8::Local<v8::Value> V8LazyEventListener::CallListenerFunction(
DCHECK(!js_event.IsEmpty());
ExecutionContext* execution_context =
ToExecutionContext(script_state->GetContext());
- v8::Local<v8::Object> listener_object = GetListenerObject(execution_context);
+ v8::Local<v8::Object> listener_object =
+ GetListenerObjectInternal(execution_context);
if (listener_object.IsEmpty())
return v8::Local<v8::Value>();
@@ -203,7 +204,9 @@ void V8LazyEventListener::CompileScript(ScriptState* script_state,
wrapped_function->SetName(V8String(GetIsolate(), function_name_));
- SetListenerObject(wrapped_function);
+ SetListenerObject(script_state, wrapped_function,
+ V8PrivateProperty::GetV8EventListenerOrEventHandlerListener(
+ GetIsolate()));
}
void V8LazyEventListener::FireErrorEvent(v8::Local<v8::Context> v8_context,
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 75f4589d174..4388d8fc3cc 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
@@ -215,10 +215,10 @@ v8::MaybeLocal<v8::Script> V8ScriptRunner::CompileScript(
v8::MaybeLocal<v8::Script> script =
CompileScriptInternal(isolate, execution_context, source, origin,
compile_options, no_cache_reason, &cache_result);
- TRACE_EVENT_END1(
- kTraceEventCategoryGroup, "v8.compile", "data",
- InspectorCompileScriptEvent::Data(file_name, script_start_position,
- cache_result, source.Streamer()));
+ TRACE_EVENT_END1(kTraceEventCategoryGroup, "v8.compile", "data",
+ InspectorCompileScriptEvent::Data(
+ file_name, script_start_position, cache_result,
+ source.Streamer(), source.NotStreamingReason()));
return script;
}
@@ -280,7 +280,7 @@ v8::MaybeLocal<v8::Value> V8ScriptRunner::RunCompiledScript(
v8::MicrotasksScope::kRunMicrotasks);
// ToCoreString here should be zero copy due to externalized string
// unpacked.
- String script_url = ToCoreString(script_name->ToString());
+ String script_url = ToCoreString(script_name->ToString(isolate));
probe::ExecuteScript probe(context, script_url);
result = script->Run(isolate->GetCurrentContext());
}
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 8e87ed69554..0f989bb09ec 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
@@ -130,7 +130,8 @@ TEST_F(V8ScriptRunnerTest, emptyResourceDoesNotHaveCacheHandler) {
TEST_F(V8ScriptRunnerTest, codeOption) {
V8TestingScope scope;
- ScriptSourceCode source_code(nullptr, CreateResource(UTF8Encoding()));
+ ScriptSourceCode source_code(nullptr, CreateResource(UTF8Encoding()),
+ ScriptStreamer::kScriptTooSmall);
SingleCachedMetadataHandler* cache_handler = source_code.CacheHandler();
SetCacheTimeStamp(cache_handler);
@@ -147,7 +148,8 @@ TEST_F(V8ScriptRunnerTest, codeOption) {
TEST_F(V8ScriptRunnerTest, consumeCodeOption) {
V8TestingScope scope;
- ScriptSourceCode source_code(nullptr, CreateResource(UTF8Encoding()));
+ ScriptSourceCode source_code(nullptr, CreateResource(UTF8Encoding()),
+ ScriptStreamer::kScriptTooSmall);
// Set timestamp to simulate a warm run.
SingleCachedMetadataHandler* cache_handler = source_code.CacheHandler();
SetCacheTimeStamp(cache_handler);
@@ -177,7 +179,8 @@ TEST_F(V8ScriptRunnerTest, consumeCodeOption) {
TEST_F(V8ScriptRunnerTest, produceAndConsumeCodeOption) {
V8TestingScope scope;
- ScriptSourceCode source_code(nullptr, CreateResource(UTF8Encoding()));
+ ScriptSourceCode source_code(nullptr, CreateResource(UTF8Encoding()),
+ ScriptStreamer::kScriptTooSmall);
SingleCachedMetadataHandler* cache_handler = source_code.CacheHandler();
// Cold run - should set the timestamp
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 26154edc309..fd56d312f37 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
@@ -20,6 +20,103 @@ namespace blink {
namespace {
+// The |FetchDataLoader| for streaming compilation of WebAssembly code. The
+// received bytes get forwarded to the V8 API class |WasmStreaming|.
+class FetchDataLoaderForWasmStreaming final : public FetchDataLoader,
+ public BytesConsumer::Client {
+ USING_GARBAGE_COLLECTED_MIXIN(FetchDataLoaderForWasmStreaming);
+
+ public:
+ FetchDataLoaderForWasmStreaming(ScriptState* script_state,
+ std::shared_ptr<v8::WasmStreaming> streaming)
+ : streaming_(std::move(streaming)), script_state_(script_state) {}
+
+ void Start(BytesConsumer* consumer,
+ FetchDataLoader::Client* client) override {
+ DCHECK(!consumer_);
+ DCHECK(!client_);
+ client_ = client;
+ consumer_ = consumer;
+ consumer_->SetClient(this);
+ OnStateChange();
+ }
+
+ void OnStateChange() override {
+ while (true) {
+ // |buffer| is owned by |consumer_|.
+ const char* buffer = nullptr;
+ size_t available = 0;
+ BytesConsumer::Result result = consumer_->BeginRead(&buffer, &available);
+
+ if (result == BytesConsumer::Result::kShouldWait)
+ return;
+ if (result == BytesConsumer::Result::kOk) {
+ if (available > 0) {
+ DCHECK_NE(buffer, nullptr);
+ streaming_->OnBytesReceived(reinterpret_cast<const uint8_t*>(buffer),
+ available);
+ }
+ result = consumer_->EndRead(available);
+ }
+ switch (result) {
+ case BytesConsumer::Result::kShouldWait:
+ NOTREACHED();
+ return;
+ case BytesConsumer::Result::kOk: {
+ break;
+ }
+ case BytesConsumer::Result::kDone: {
+ streaming_->Finish();
+ client_->DidFetchDataLoadedCustomFormat();
+ return;
+ }
+ case BytesConsumer::Result::kError: {
+ return AbortCompilation();
+ }
+ }
+ }
+ }
+
+ String DebugName() const override { return "FetchDataLoaderForWasmModule"; }
+
+ void Cancel() override {
+ consumer_->Cancel();
+ return AbortCompilation();
+ }
+
+ void Trace(blink::Visitor* visitor) override {
+ visitor->Trace(consumer_);
+ visitor->Trace(client_);
+ visitor->Trace(script_state_);
+ FetchDataLoader::Trace(visitor);
+ BytesConsumer::Client::Trace(visitor);
+ }
+
+ private:
+ // TODO(ahaas): replace with spec-ed error types, once spec clarifies
+ // what they are.
+ void AbortCompilation() {
+ if (script_state_->ContextIsValid()) {
+ ScriptState::Scope scope(script_state_);
+ streaming_->Abort(V8ThrowException::CreateTypeError(
+ script_state_->GetIsolate(), "Could not download wasm module"));
+ } else {
+ // We are not allowed to execute a script, which indicates that we should
+ // not reject the promise of the streaming compilation. By passing no
+ // abort reason, we indicate the V8 side that the promise should not get
+ // rejected.
+ streaming_->Abort(v8::Local<v8::Value>());
+ }
+ }
+ Member<BytesConsumer> consumer_;
+ Member<FetchDataLoader::Client> client_;
+ std::shared_ptr<v8::WasmStreaming> streaming_;
+ const Member<ScriptState> script_state_;
+};
+
+// TODO(ahaas): Remove |FetchDataLoaderAsWasmModule| once the
+// |SetWasmCompileStreamingCallback| API is successfully replaced by the
+// |SetWasmStreamingCallback| API.
class FetchDataLoaderAsWasmModule final : public FetchDataLoader,
public BytesConsumer::Client {
USING_GARBAGE_COLLECTED_MIXIN(FetchDataLoaderAsWasmModule);
@@ -42,7 +139,7 @@ class FetchDataLoaderAsWasmModule final : public FetchDataLoader,
void OnStateChange() override {
while (true) {
- // {buffer} is owned by {m_consumer}.
+ // |buffer| is owned by |consumer_|.
const char* buffer = nullptr;
size_t available = 0;
BytesConsumer::Result result = consumer_->BeginRead(&buffer, &available);
@@ -96,8 +193,8 @@ class FetchDataLoaderAsWasmModule final : public FetchDataLoader,
// TODO(mtrofin): replace with spec-ed error types, once spec clarifies
// what they are.
void AbortCompilation() {
- ScriptState::Scope scope(script_state_);
- if (!ExecutionContext::From(script_state_)->IsContextDestroyed()) {
+ if (script_state_->ContextIsValid()) {
+ ScriptState::Scope scope(script_state_);
builder_.Abort(V8ThrowException::CreateTypeError(
script_state_->GetIsolate(), "Could not download wasm module"));
} else {
@@ -135,6 +232,97 @@ class WasmDataLoaderClient final
}
};
+// ExceptionToAbortStreamingScope converts a possible exception to an abort
+// message for WasmStreaming instead of throwing the exception.
+//
+// All exceptions which happen in the setup of WebAssembly streaming compilation
+// have to be passed as an abort message to V8 so that V8 can reject the promise
+// associated to the streaming compilation.
+class ExceptionToAbortStreamingScope {
+ STACK_ALLOCATED();
+ WTF_MAKE_NONCOPYABLE(ExceptionToAbortStreamingScope);
+
+ public:
+ ExceptionToAbortStreamingScope(std::shared_ptr<v8::WasmStreaming> streaming,
+ ExceptionState& exception_state)
+ : streaming_(streaming), exception_state_(exception_state) {}
+
+ ~ExceptionToAbortStreamingScope() {
+ if (!exception_state_.HadException())
+ return;
+
+ streaming_->Abort(exception_state_.GetException());
+ exception_state_.ClearException();
+ }
+
+ private:
+ std::shared_ptr<v8::WasmStreaming> streaming_;
+ ExceptionState& exception_state_;
+};
+
+void StreamFromResponseCallback(
+ const v8::FunctionCallbackInfo<v8::Value>& args) {
+ ExceptionState exception_state(args.GetIsolate(),
+ ExceptionState::kExecutionContext,
+ "WebAssembly", "compile");
+ std::shared_ptr<v8::WasmStreaming> streaming =
+ v8::WasmStreaming::Unpack(args.GetIsolate(), args.Data());
+ ExceptionToAbortStreamingScope exception_scope(streaming, exception_state);
+
+ ScriptState* script_state = ScriptState::ForCurrentRealm(args);
+ if (!script_state->ContextIsValid()) {
+ // We do not have an execution context, we just abort streaming compilation
+ // immediately without error.
+ streaming->Abort(v8::Local<v8::Value>());
+ return;
+ }
+
+ Response* response =
+ V8Response::ToImplWithTypeCheck(args.GetIsolate(), args[0]);
+ if (!response) {
+ exception_state.ThrowTypeError(
+ "An argument must be provided, which must be a "
+ "Response or Promise<Response> object");
+ return;
+ }
+
+ if (!response->ok()) {
+ exception_state.ThrowTypeError("HTTP status code is not ok");
+ return;
+ }
+
+ if (response->MimeType() != "application/wasm") {
+ exception_state.ThrowTypeError(
+ "Incorrect response MIME type. Expected 'application/wasm'.");
+ return;
+ }
+
+ Body::BodyLocked body_locked = response->IsBodyLocked(exception_state);
+ if (body_locked == Body::BodyLocked::kBroken)
+ return;
+
+ if (body_locked == Body::BodyLocked::kLocked ||
+ response->IsBodyUsed(exception_state) == Body::BodyUsed::kUsed) {
+ DCHECK(!exception_state.HadException());
+ exception_state.ThrowTypeError(
+ "Cannot compile WebAssembly.Module from an already read Response");
+ return;
+ }
+
+ if (exception_state.HadException())
+ return;
+
+ if (!response->BodyBuffer()) {
+ exception_state.ThrowTypeError("Response object has a null body.");
+ return;
+ }
+
+ FetchDataLoaderForWasmStreaming* loader =
+ new FetchDataLoaderForWasmStreaming(script_state, streaming);
+ response->BodyBuffer()->StartLoading(loader, new WasmDataLoaderClient(),
+ exception_state);
+}
+
// This callback may be entered as a promise is resolved, or directly
// from the overload callback.
// See
@@ -147,7 +335,7 @@ void CompileFromResponseCallback(
ExceptionToRejectPromiseScope reject_promise_scope(args, exception_state);
ScriptState* script_state = ScriptState::ForCurrentRealm(args);
- if (!ExecutionContext::From(script_state)) {
+ if (!script_state->ContextIsValid()) {
V8SetReturnValue(args, ScriptPromise().V8Value());
return;
}
@@ -172,13 +360,18 @@ void CompileFromResponseCallback(
return;
}
- if (response->IsBodyLocked(exception_state) == Body::BodyLocked::kLocked ||
+ Body::BodyLocked body_locked = response->IsBodyLocked(exception_state);
+ if (body_locked == Body::BodyLocked::kBroken)
+ return;
+
+ if (body_locked == Body::BodyLocked::kLocked ||
response->IsBodyUsed(exception_state) == Body::BodyUsed::kUsed) {
DCHECK(!exception_state.HadException());
exception_state.ThrowTypeError(
"Cannot compile WebAssembly.Module from an already read Response");
return;
}
+
if (exception_state.HadException())
return;
@@ -234,6 +427,7 @@ void WasmCompileStreamingImpl(const v8::FunctionCallbackInfo<v8::Value>& args) {
void WasmResponseExtensions::Initialize(v8::Isolate* isolate) {
if (RuntimeEnabledFeatures::WebAssemblyStreamingEnabled()) {
isolate->SetWasmCompileStreamingCallback(WasmCompileStreamingImpl);
+ isolate->SetWasmStreamingCallback(StreamFromResponseCallback);
}
}
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_worker_or_worklet_event_listener.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_worker_or_worklet_event_listener.cc
deleted file mode 100644
index 73bf9c6ddbe..00000000000
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_worker_or_worklet_event_listener.cc
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2008, 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_worker_or_worklet_event_listener.h"
-
-#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_event.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_event_target.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_gc_controller.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_script_runner.h"
-#include "third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.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"
-#include "third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h"
-#include "third_party/blink/renderer/platform/bindings/v8_dom_wrapper.h"
-
-namespace blink {
-
-V8WorkerOrWorkletEventListener::V8WorkerOrWorkletEventListener(
- bool is_inline,
- ScriptState* script_state)
- : V8EventListener(is_inline, script_state) {}
-
-void V8WorkerOrWorkletEventListener::HandleEvent(ScriptState* script_state,
- Event* event) {
- v8::Local<v8::Context> context = script_state->GetContext();
- WorkerOrWorkletScriptController* script_controller =
- ToWorkerOrWorkletGlobalScope(ToExecutionContext(context))
- ->ScriptController();
- if (!script_controller)
- return;
-
- ScriptState::Scope scope(script_state);
-
- // Get the V8 wrapper for the event object.
- v8::Local<v8::Value> js_event = ToV8(event, context->Global(), GetIsolate());
- if (js_event.IsEmpty())
- return;
-
- InvokeEventHandler(script_state, event,
- v8::Local<v8::Value>::New(GetIsolate(), js_event));
-}
-
-v8::Local<v8::Value> V8WorkerOrWorkletEventListener::CallListenerFunction(
- ScriptState* script_state,
- v8::Local<v8::Value> js_event,
- Event* event) {
- DCHECK(!js_event.IsEmpty());
- v8::Local<v8::Function> handler_function = GetListenerFunction(script_state);
- v8::Local<v8::Object> receiver = GetReceiverObject(script_state, event);
- if (handler_function.IsEmpty() || receiver.IsEmpty())
- return v8::Local<v8::Value>();
-
- v8::Local<v8::Value> parameters[1] = {js_event};
- v8::MaybeLocal<v8::Value> maybe_result = V8ScriptRunner::CallFunction(
- handler_function, ToExecutionContext(script_state->GetContext()),
- receiver, base::size(parameters), parameters, GetIsolate());
-
- v8::Local<v8::Value> result;
- if (!maybe_result.ToLocal(&result))
- return v8::Local<v8::Value>();
- return result;
-}
-
-// FIXME: Remove getReceiverObject().
-// This is almost identical to V8AbstractEventListener::getReceiverObject().
-v8::Local<v8::Object> V8WorkerOrWorkletEventListener::GetReceiverObject(
- ScriptState* script_state,
- Event* event) {
- v8::Local<v8::Object> listener =
- GetListenerObject(ExecutionContext::From(script_state));
-
- if (!listener.IsEmpty() && !listener->IsFunction())
- return listener;
-
- EventTarget* target = event->currentTarget();
- v8::Local<v8::Value> value =
- ToV8(target, script_state->GetContext()->Global(), GetIsolate());
- if (value.IsEmpty())
- return v8::Local<v8::Object>();
- return v8::Local<v8::Object>::New(GetIsolate(),
- v8::Local<v8::Object>::Cast(value));
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_worker_or_worklet_event_listener.h b/chromium/third_party/blink/renderer/bindings/core/v8/v8_worker_or_worklet_event_listener.h
deleted file mode 100644
index fa8e2b98cb9..00000000000
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_worker_or_worklet_event_listener.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2008, 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_WORKER_OR_WORKLET_EVENT_LISTENER_H_
-#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_V8_WORKER_OR_WORKLET_EVENT_LISTENER_H_
-
-#include "base/memory/scoped_refptr.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_event_listener.h"
-#include "v8/include/v8.h"
-
-namespace blink {
-
-class Event;
-
-class V8WorkerOrWorkletEventListener final : public V8EventListener {
- public:
- static V8WorkerOrWorkletEventListener* Create(v8::Local<v8::Object> listener,
- bool is_inline,
- ScriptState* script_state) {
- V8WorkerOrWorkletEventListener* event_listener =
- new V8WorkerOrWorkletEventListener(is_inline, script_state);
- event_listener->SetListenerObject(listener);
- return event_listener;
- }
-
- void HandleEvent(ScriptState*, Event*) override;
-
- protected:
- V8WorkerOrWorkletEventListener(bool is_inline, ScriptState*);
-
- private:
- v8::Local<v8::Value> CallListenerFunction(ScriptState*,
- v8::Local<v8::Value>,
- Event*) override;
- v8::Local<v8::Object> GetReceiverObject(ScriptState*, Event*);
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_V8_WORKER_OR_WORKLET_EVENT_LISTENER_H_
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 6a5c351eaf0..73fca4f4623 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
@@ -129,8 +129,7 @@ void WorkerOrWorkletScriptController::DisposeContextIfNeeded() {
if (!IsContextInitialized())
return;
- if (global_scope_->IsWorkerGlobalScope() ||
- global_scope_->IsThreadedWorkletGlobalScope()) {
+ if (!global_scope_->IsMainThreadWorkletGlobalScope()) {
ScriptState::Scope scope(script_state_);
WorkerThreadDebugger* debugger = WorkerThreadDebugger::From(isolate_);
debugger->ContextWillBeDestroyed(global_scope_->GetThread(),
@@ -142,7 +141,8 @@ void WorkerOrWorkletScriptController::DisposeContextIfNeeded() {
}
bool WorkerOrWorkletScriptController::InitializeContextIfNeeded(
- const String& human_readable_name) {
+ const String& human_readable_name,
+ const KURL& url_for_debugger) {
v8::HandleScope handle_scope(isolate_);
if (IsContextInitialized())
@@ -230,19 +230,19 @@ bool WorkerOrWorkletScriptController::InitializeContextIfNeeded(
// So we explicitly call constructorForType for the global object.
V8PerContextData::From(context)->ConstructorForType(wrapper_type_info);
- // Name new context for debugging. For main thread worklet global scopes
- // this is done once the context is initialized.
- if (global_scope_->IsWorkerGlobalScope() ||
- global_scope_->IsThreadedWorkletGlobalScope()) {
+ if (global_scope_->IsMainThreadWorkletGlobalScope()) {
+ // Set the human readable name for the world if the call passes an actual
+ // |human_readable name|.
+ if (!human_readable_name.IsEmpty()) {
+ world_->SetNonMainWorldHumanReadableName(world_->GetWorldId(),
+ human_readable_name);
+ }
+ } else {
+ // Name new context for debugging. For main thread worklet global scopes
+ // this is done once the context is initialized.
WorkerThreadDebugger* debugger = WorkerThreadDebugger::From(isolate_);
- debugger->ContextCreated(global_scope_->GetThread(), context);
- }
-
- // Set the human readable name for the world if the call passes an actual
- // |human_readable name|.
- if (!human_readable_name.IsEmpty()) {
- world_->SetNonMainWorldHumanReadableName(world_->GetWorldId(),
- human_readable_name);
+ debugger->ContextCreated(global_scope_->GetThread(), url_for_debugger,
+ context);
}
wrapper_type_info->InstallConditionalFeatures(
@@ -262,11 +262,11 @@ bool WorkerOrWorkletScriptController::InitializeContextIfNeeded(
ScriptValue WorkerOrWorkletScriptController::EvaluateInternal(
const ScriptSourceCode& source_code,
V8CacheOptions v8_cache_options) {
+ DCHECK(IsContextInitialized());
+
TRACE_EVENT1("devtools.timeline", "EvaluateScript", "data",
InspectorEvaluateScriptEvent::Data(nullptr, source_code.Url(),
source_code.StartPosition()));
- if (!InitializeContextIfNeeded(String()))
- return ScriptValue();
ScriptState::Scope scope(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 354f96a80a7..9d405829580 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
@@ -69,7 +69,12 @@ class CORE_EXPORT WorkerOrWorkletScriptController final
// Used by WorkerThread. Returns true if the context is successfully
// initialized or already initialized.
- bool InitializeContextIfNeeded(const String& human_readable_name);
+ // For WorkerGlobalScope and ThreadedWorkletGlobalScope, |url_for_debugger| is
+ // and should be used only for setting name/origin that appears in DevTools.
+ // For other global scopes, |human_readable_name| is used for setting
+ // DOMWrapperWorld's human readable name.
+ bool InitializeContextIfNeeded(const String& human_readable_name,
+ const KURL& url_for_debugger);
// Used by WorkerGlobalScope:
void RethrowExceptionFromImportedScript(ErrorEvent*, ExceptionState&);
diff --git a/chromium/third_party/blink/renderer/bindings/modules/BUILD.gn b/chromium/third_party/blink/renderer/bindings/modules/BUILD.gn
index 1fe835bcdd0..a8b704c606b 100644
--- a/chromium/third_party/blink/renderer/bindings/modules/BUILD.gn
+++ b/chromium/third_party/blink/renderer/bindings/modules/BUILD.gn
@@ -19,10 +19,8 @@ group("bindings_modules_generated") {
generate_event_interfaces("modules_bindings_generated_event_interfaces") {
sources = [
"//third_party/blink/renderer/modules/app_banner/before_install_prompt_event.idl",
- "//third_party/blink/renderer/modules/background_fetch/background_fetch_click_event.idl",
"//third_party/blink/renderer/modules/background_fetch/background_fetch_event.idl",
- "//third_party/blink/renderer/modules/background_fetch/background_fetch_fail_event.idl",
- "//third_party/blink/renderer/modules/background_fetch/background_fetched_event.idl",
+ "//third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.idl",
"//third_party/blink/renderer/modules/background_sync/sync_event.idl",
"//third_party/blink/renderer/modules/cookie_store/cookie_change_event.idl",
"//third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.idl",
@@ -43,6 +41,7 @@ generate_event_interfaces("modules_bindings_generated_event_interfaces") {
"//third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.idl",
"//third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.idl",
"//third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.idl",
+ "//third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.idl",
"//third_party/blink/renderer/modules/presentation/presentation_connection_available_event.idl",
"//third_party/blink/renderer/modules/presentation/presentation_connection_close_event.idl",
"//third_party/blink/renderer/modules/push_messaging/push_event.idl",
@@ -77,7 +76,10 @@ make_event_factory("event_modules") {
"$blink_modules_output_dir/event_modules_factory.cc",
]
deps = make_core_generated_deps + [ "//third_party/blink/renderer/bindings/modules:modules_bindings_generated_event_interfaces" ]
- deps += [ "//media/midi:mojo_blink" ]
+ deps += [
+ "//device/gamepad/public/mojom:mojom_blink",
+ "//media/midi:mojo_blink",
+ ]
}
make_names("event_modules_names") {
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 3438122010c..47a5d5372d1 100644
--- a/chromium/third_party/blink/renderer/bindings/modules/v8/BUILD.gn
+++ b/chromium/third_party/blink/renderer/bindings/modules/v8/BUILD.gn
@@ -95,14 +95,14 @@ group("generate_mojo_bindings") {
visibility = [ ":*" ]
deps = [
- "//device/gamepad/public/mojom:mojom_blink__generator",
- "//device/usb/public/mojom:mojom_blink__generator",
- "//device/vr/public/mojom:mojom_blink__generator",
- "//media/capture/mojom:image_capture_blink__generator",
- "//services/device/public/mojom:generic_sensor__generator",
- "//services/device/public/mojom:mojom_blink__generator",
- "//services/shape_detection/public/mojom:mojom_blink__generator",
- "//third_party/blink/public:media_devices_mojo_bindings_blink__generator",
+ "//device/gamepad/public/mojom:mojom_blink_headers",
+ "//device/usb/public/mojom:mojom_blink_headers",
+ "//device/vr/public/mojom:mojom_blink_headers",
+ "//media/capture/mojom:image_capture_blink_headers",
+ "//services/device/public/mojom:generic_sensor_headers",
+ "//services/device/public/mojom:mojom_blink_headers",
+ "//services/shape_detection/public/mojom:mojom_blink_headers",
+ "//third_party/blink/public:media_devices_mojo_bindings_blink_headers",
]
}
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 4f0ccb0740d..57358a96690 100644
--- a/chromium/third_party/blink/renderer/bindings/modules/v8/generated.gni
+++ b/chromium/third_party/blink/renderer/bindings/modules/v8/generated.gni
@@ -54,6 +54,8 @@ bindings_modules_generated_union_type_files = [
"$bindings_modules_v8_output_dir/media_stream_track_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/path_2d_or_string.cc",
+ "$bindings_modules_v8_output_dir/path_2d_or_string.h",
"$bindings_modules_v8_output_dir/password_credential_data_or_html_form_element.cc",
"$bindings_modules_v8_output_dir/password_credential_data_or_html_form_element.h",
"$bindings_modules_v8_output_dir/point_2d_sequence_or_constrain_point_2d_parameters.cc",
diff --git a/chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.cc b/chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.cc
index 800f0375080..10e3e7af356 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
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.h"
+#include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_crypto.h"
#include "third_party/blink/public/platform/web_crypto_key_algorithm.h"
@@ -13,7 +14,6 @@
#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/peerconnection/rtc_certificate.h"
-#include "third_party/blink/renderer/platform/file_system_type.h"
namespace blink {
@@ -32,12 +32,14 @@ ScriptWrappable* V8ScriptValueDeserializerForModules::ReadDOMObject(
uint32_t raw_type;
String name;
String root_url;
- if (!ReadUint32(&raw_type) || raw_type > kFileSystemTypeLast ||
+ if (!ReadUint32(&raw_type) ||
+ raw_type >
+ static_cast<int32_t>(mojom::blink::FileSystemType::kMaxValue) ||
!ReadUTF8String(&name) || !ReadUTF8String(&root_url))
return nullptr;
- return DOMFileSystem::Create(ExecutionContext::From(GetScriptState()),
- name, static_cast<FileSystemType>(raw_type),
- KURL(root_url));
+ return DOMFileSystem::Create(
+ ExecutionContext::From(GetScriptState()), name,
+ static_cast<mojom::blink::FileSystemType>(raw_type), KURL(root_url));
}
case kRTCCertificateTag: {
String pem_private_key;
@@ -49,7 +51,7 @@ ScriptWrappable* V8ScriptValueDeserializerForModules::ReadDOMObject(
Platform::Current()->CreateRTCCertificateGenerator());
if (!certificate_generator)
return nullptr;
- std::unique_ptr<WebRTCCertificate> certificate =
+ rtc::scoped_refptr<rtc::RTCCertificate> certificate =
certificate_generator->FromPEM(pem_private_key, pem_certificate);
if (!certificate)
return nullptr;
diff --git a/chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules.cc b/chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules.cc
index bb02b02bd42..963f9e0b2e1 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
@@ -13,7 +13,6 @@
#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/platform/bindings/script_wrappable.h"
-#include "third_party/blink/renderer/platform/file_system_type.h"
namespace blink {
@@ -49,10 +48,10 @@ bool V8ScriptValueSerializerForModules::WriteDOMObject(
}
if (wrapper_type_info == &V8RTCCertificate::wrapperTypeInfo) {
RTCCertificate* certificate = wrappable->ToImpl<RTCCertificate>();
- WebRTCCertificatePEM pem = certificate->Certificate().ToPEM();
+ rtc::RTCCertificatePEM pem = certificate->Certificate()->ToPEM();
WriteTag(kRTCCertificateTag);
- WriteUTF8String(pem.PrivateKey());
- WriteUTF8String(pem.Certificate());
+ WriteUTF8String(pem.private_key().c_str());
+ WriteUTF8String(pem.certificate().c_str());
return true;
}
return false;
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 4b4948abbbf..6fd7f327fa0 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
@@ -157,7 +157,7 @@ TEST(V8ScriptValueSerializerForModulesTest, RoundTripRTCCertificate) {
V8TestingScope scope;
// Make a certificate with the existing key above.
- std::unique_ptr<WebRTCCertificate> web_certificate =
+ rtc::scoped_refptr<rtc::RTCCertificate> web_certificate =
certificate_generator->FromPEM(
WebString::FromUTF8(kEcdsaPrivateKey, sizeof(kEcdsaPrivateKey)),
WebString::FromUTF8(kEcdsaCertificate, sizeof(kEcdsaCertificate)));
@@ -171,9 +171,9 @@ TEST(V8ScriptValueSerializerForModulesTest, RoundTripRTCCertificate) {
ASSERT_TRUE(V8RTCCertificate::hasInstance(result, scope.GetIsolate()));
RTCCertificate* new_certificate =
V8RTCCertificate::ToImpl(result.As<v8::Object>());
- WebRTCCertificatePEM pem = new_certificate->Certificate().ToPEM();
- EXPECT_EQ(kEcdsaPrivateKey, pem.PrivateKey());
- EXPECT_EQ(kEcdsaCertificate, pem.Certificate());
+ rtc::RTCCertificatePEM pem = new_certificate->Certificate()->ToPEM();
+ EXPECT_EQ(kEcdsaPrivateKey, pem.private_key());
+ EXPECT_EQ(kEcdsaCertificate, pem.certificate());
}
TEST(V8ScriptValueSerializerForModulesTest, DecodeRTCCertificate) {
@@ -198,9 +198,9 @@ TEST(V8ScriptValueSerializerForModulesTest, DecodeRTCCertificate) {
ASSERT_TRUE(V8RTCCertificate::hasInstance(result, scope.GetIsolate()));
RTCCertificate* new_certificate =
V8RTCCertificate::ToImpl(result.As<v8::Object>());
- WebRTCCertificatePEM pem = new_certificate->Certificate().ToPEM();
- EXPECT_EQ(kEcdsaPrivateKey, pem.PrivateKey());
- EXPECT_EQ(kEcdsaCertificate, pem.Certificate());
+ rtc::RTCCertificatePEM pem = new_certificate->Certificate()->ToPEM();
+ EXPECT_EQ(kEcdsaPrivateKey, pem.private_key());
+ EXPECT_EQ(kEcdsaCertificate, pem.certificate());
}
TEST(V8ScriptValueSerializerForModulesTest, DecodeInvalidRTCCertificate) {
@@ -874,6 +874,16 @@ TEST(V8ScriptValueSerializerForModulesTest, DecodeCryptoKeyInvalid) {
0x0e, 0x01, 0x01, 0x4b, 0x00, 0x00}))
.Deserialize()
->IsNull());
+
+ // Public RSA key with invalid key data.
+ // The key data is a single byte (0x00), which is not a valid SPKI.
+ EXPECT_TRUE(
+ V8ScriptValueDeserializerForModules(
+ script_state, SerializedValue({0xff, 0x09, 0x3f, 0x00, 0x4b, 0x04,
+ 0x0d, 0x01, 0x80, 0x08, 0x03, 0x01,
+ 0x00, 0x01, 0x06, 0x11, 0x01, 0x00}))
+ .Deserialize()
+ ->IsNull());
}
TEST(V8ScriptValueSerializerForModulesTest, RoundTripDOMFileSystem) {
@@ -881,7 +891,7 @@ TEST(V8ScriptValueSerializerForModulesTest, RoundTripDOMFileSystem) {
DOMFileSystem* fs = DOMFileSystem::Create(
scope.GetExecutionContext(), "http_example.com_0:Persistent",
- kFileSystemTypePersistent,
+ mojom::blink::FileSystemType::kPersistent,
KURL("filesystem:http://example.com/persistent/"));
// At time of writing, this can only happen for filesystems from PPAPI.
fs->MakeClonable();
@@ -891,7 +901,7 @@ TEST(V8ScriptValueSerializerForModulesTest, RoundTripDOMFileSystem) {
ASSERT_TRUE(V8DOMFileSystem::hasInstance(result, scope.GetIsolate()));
DOMFileSystem* new_fs = V8DOMFileSystem::ToImpl(result.As<v8::Object>());
EXPECT_EQ("http_example.com_0:Persistent", new_fs->name());
- EXPECT_EQ(kFileSystemTypePersistent, new_fs->GetType());
+ EXPECT_EQ(mojom::blink::FileSystemType::kPersistent, new_fs->GetType());
EXPECT_EQ("filesystem:http://example.com/persistent/",
new_fs->RootURL().GetString());
}
@@ -904,7 +914,7 @@ TEST(V8ScriptValueSerializerForModulesTest, RoundTripDOMFileSystemNotClonable) {
DOMFileSystem* fs = DOMFileSystem::Create(
scope.GetExecutionContext(), "http_example.com_0:Persistent",
- kFileSystemTypePersistent,
+ mojom::blink::FileSystemType::kPersistent,
KURL("filesystem:http://example.com/persistent/0/"));
ASSERT_FALSE(fs->Clonable());
v8::Local<v8::Value> wrapper = ToV8(fs, scope.GetScriptState());
@@ -934,7 +944,7 @@ TEST(V8ScriptValueSerializerForModulesTest, DecodeDOMFileSystem) {
ASSERT_TRUE(V8DOMFileSystem::hasInstance(result, scope.GetIsolate()));
DOMFileSystem* new_fs = V8DOMFileSystem::ToImpl(result.As<v8::Object>());
EXPECT_EQ("http_example.com_0:Persistent", new_fs->name());
- EXPECT_EQ(kFileSystemTypePersistent, new_fs->GetType());
+ EXPECT_EQ(mojom::blink::FileSystemType::kPersistent, new_fs->GetType());
EXPECT_EQ("filesystem:http://example.com/persistent/",
new_fs->RootURL().GetString());
}
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 4c645d47b3e..cf202b3ec0a 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/idl_types.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/idl_types.py
@@ -84,9 +84,11 @@ STRING_TYPES = frozenset([
'USVString',
])
-STANDARD_CALLBACK_FUNCTIONS = frozenset([
- # http://heycam.github.io/webidl/#common-Function
- 'Function',
+NON_STANDARD_CALLBACK_FUNCTIONS = frozenset([
+ # |CallbackFunctionTreatedAsScriptValue| is interpreted as a callback
+ # function type, but converted to |ScriptValue| instead of a subclass of
+ # |CallbackFunctionBase|.
+ 'CallbackFunctionTreatedAsScriptValue',
])
@@ -171,12 +173,13 @@ class IdlType(IdlTypeBase):
@property
def is_callback_function(self): # pylint: disable=C0103
- return self.base_type in IdlType.callback_functions or self.base_type in STANDARD_CALLBACK_FUNCTIONS
+ return self.base_type in IdlType.callback_functions or self.base_type in NON_STANDARD_CALLBACK_FUNCTIONS
@property
def is_custom_callback_function(self):
- # Treat standard callback functions as custom as they aren't generated.
- if self.base_type in STANDARD_CALLBACK_FUNCTIONS:
+ # Treat non standard callback functions as custom as they have different
+ # cpp_type, etc.
+ if self.base_type in NON_STANDARD_CALLBACK_FUNCTIONS:
return True
entry = IdlType.callback_functions.get(self.base_type)
callback_function = entry.get('callback_function')
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 082c09b1f2f..734c72ef09f 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/v8_attributes.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/v8_attributes.py
@@ -124,6 +124,14 @@ def attribute_context(interface, attribute, interfaces):
if 'LogActivity' in extended_attributes:
includes.add('platform/bindings/v8_per_context_data.h')
+ # [DeprecateAs], [MeasureAs]
+ deprecate_as = v8_utilities.deprecate_as(attribute)
+ measure_as = v8_utilities.measure_as(attribute, interface)
+
+ is_lazy_data_attribute = \
+ (constructor_type and not (measure_as or deprecate_as)) or \
+ (str(idl_type) == 'Window' and attribute.name in ('frames', 'self', 'window'))
+
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]
@@ -134,7 +142,7 @@ def attribute_context(interface, attribute, interfaces):
'cpp_name': cpp_name(attribute),
'cpp_type': idl_type.cpp_type,
'cpp_type_initializer': idl_type.cpp_type_initializer,
- 'deprecate_as': v8_utilities.deprecate_as(attribute), # [DeprecateAs]
+ 'deprecate_as': deprecate_as,
'enum_type': idl_type.enum_type,
'enum_values': idl_type.enum_values,
'exposed_test': v8_utilities.exposed(attribute, interface), # [Exposed]
@@ -161,6 +169,7 @@ def attribute_context(interface, attribute, interfaces):
'RaisesException' in extended_attributes and
extended_attributes['RaisesException'] in (None, 'Getter'),
'is_keep_alive_for_gc': keep_alive_for_gc,
+ 'is_lazy_data_attribute': is_lazy_data_attribute,
'is_lenient_setter': 'LenientSetter' in extended_attributes,
'is_lenient_this': 'LenientThis' in extended_attributes,
'is_nullable': idl_type.is_nullable,
@@ -182,7 +191,7 @@ def attribute_context(interface, attribute, interfaces):
'on_prototype': v8_utilities.on_prototype(interface, attribute),
'origin_trial_feature_name': v8_utilities.origin_trial_feature_name(attribute), # [OriginTrialEnabled]
'use_output_parameter_for_result': idl_type.use_output_parameter_for_result,
- 'measure_as': v8_utilities.measure_as(attribute, interface), # [MeasureAs]
+ 'measure_as': measure_as,
'name': attribute.name,
'property_attributes': property_attributes(interface, attribute),
'reflect_empty': extended_attributes.get('ReflectEmpty'),
@@ -261,20 +270,8 @@ def is_data_attribute(attribute):
attribute['is_data_type_property'])
-def is_lazy_data_attribute(attribute):
- return ((attribute['constructor_type'] and not
- (attribute['measure_as'] or attribute['deprecate_as'])) or
- (attribute['idl_type'] == 'Window' and attribute['name'] == 'frames') or
- (attribute['idl_type'] == 'Window' and attribute['name'] == 'self') or
- (attribute['idl_type'] == 'Window' and attribute['name'] == 'window'))
-
-
def filter_data_attributes(attributes):
- return [attribute for attribute in attributes if is_data_attribute(attribute) and not is_lazy_data_attribute(attribute)]
-
-
-def filter_lazy_data_attributes(attributes):
- return [attribute for attribute in attributes if is_data_attribute(attribute) and is_lazy_data_attribute(attribute)]
+ return [attribute for attribute in attributes if is_data_attribute(attribute)]
def filter_runtime_enabled(attributes):
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 8b9288b82b8..3e9827f8b84 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
@@ -8,6 +8,7 @@ Design doc: http://www.chromium.org/developers/design-documents/idl-compiler
"""
from v8_globals import includes
+import v8_types
CALLBACK_FUNCTION_H_INCLUDES = frozenset([
'platform/bindings/callback_function_base.h',
@@ -45,17 +46,10 @@ def callback_function_context(callback_function):
'forward_declarations': sorted(forward_declarations(callback_function)),
'header_includes': sorted(CALLBACK_FUNCTION_H_INCLUDES),
'idl_type': idl_type_str,
+ 'native_value_traits_tag': v8_types.idl_type_to_native_value_traits_tag(idl_type),
'return_cpp_type': idl_type.cpp_type,
}
- if idl_type_str != 'void':
- context.update({
- 'return_value_conversion': idl_type.v8_value_to_local_cpp_value(
- callback_function.extended_attributes,
- 'call_result', 'native_result', isolate='GetIsolate()',
- bailout_return_value='v8::Nothing<%s>()' % context['return_cpp_type']),
- })
-
context.update(arguments_context(callback_function.arguments))
return context
@@ -85,13 +79,21 @@ def arguments_context(arguments):
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,
}
+ def argument_cpp_type(argument):
+ cpp_type = argument.idl_type.callback_cpp_type
+ if argument.is_variadic:
+ return 'const Vector<%s>&' % cpp_type
+ else:
+ return cpp_type
+
argument_declarations = ['ScriptWrappable* callback_this_value']
argument_declarations.extend(
- '%s %s' % (argument.idl_type.callback_cpp_type, argument.name)
+ '%s %s' % (argument_cpp_type(argument), argument.name)
for argument in arguments)
return {
'argument_declarations': argument_declarations,
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 d3d8728ce67..025650ce08a 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
@@ -145,24 +145,12 @@ def method_context(operation):
idl_type = operation.idl_type
idl_type_str = str(idl_type)
- # TODO(yukishiino,peria,rakuco): We should have this mapping as part of the
- # bindings generator's infrastructure.
- native_value_traits_tag_map = {
- 'boolean': 'IDLBoolean',
- 'unsigned short': 'IDLUnsignedShort',
- 'void': None,
- }
- if idl_type_str in native_value_traits_tag_map:
- native_value_traits_tag_name = native_value_traits_tag_map[idl_type_str]
- else:
- raise Exception("Callback that returns type `%s' is not supported." % idl_type_str)
-
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': native_value_traits_tag_name,
+ 'native_value_traits_tag': v8_types.idl_type_to_native_value_traits_tag(idl_type),
}
context.update(arguments_context(operation.arguments))
return context
@@ -176,6 +164,7 @@ def arguments_context(arguments):
creation_context='argument_creation_context'),
'handle': '%sHandle' % argument.name,
'name': argument.name,
+ 'v8_name': 'v8_' + argument.name,
}
argument_declarations = ['ScriptWrappable* callback_this_value']
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 12b5fa32d9c..f4f67a9b1df 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/v8_interface.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/v8_interface.py
@@ -402,7 +402,6 @@ def interface_context(interface, interfaces):
# Elements in attributes are broken in following members.
'accessors': v8_attributes.filter_accessors(attributes),
'data_attributes': v8_attributes.filter_data_attributes(attributes),
- 'lazy_data_attributes': v8_attributes.filter_lazy_data_attributes(attributes),
'runtime_enabled_attributes': v8_attributes.filter_runtime_enabled(attributes),
})
@@ -682,7 +681,8 @@ def methods_context(interface):
# void forEach(Function callback, [Default=Undefined] optional any thisArg)
generated_method(IdlType('void'), 'forEach',
- arguments=[generated_argument(IdlType('Function'), 'callback'),
+ # TODO(yukishiino): |callback| should be type of Function.
+ arguments=[generated_argument(IdlType('CallbackFunctionTreatedAsScriptValue'), 'callback'),
generated_argument(IdlType('any'), 'thisArg',
is_optional=True,
extended_attributes={'Default': 'Undefined'})],
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 4e5e7379e65..824bcae827c 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/v8_methods.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/v8_methods.py
@@ -163,12 +163,6 @@ def method_context(interface, method, is_visible=True):
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')
- is_post_message = 'PostMessage' in extended_attributes
- if is_post_message:
- includes.add('bindings/core/v8/serialization/serialized_script_value_factory.h')
- includes.add('bindings/core/v8/serialization/transferables.h')
- includes.add('core/typed_arrays/dom_array_buffer_base.h')
- includes.add('core/imagebitmap/image_bitmap.h')
if 'LenientThis' in extended_attributes:
raise Exception('[LenientThis] is not supported for operations.')
@@ -224,7 +218,6 @@ def method_context(interface, method, is_visible=True):
'is_partial_interface_member':
'PartialInterfaceImplementedAs' in extended_attributes,
'is_per_world_bindings': 'PerWorldBindings' in extended_attributes,
- 'is_post_message': is_post_message,
'is_raises_exception': is_raises_exception,
'is_static': is_static,
'is_unforgeable': is_unforgeable(interface, method),
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 dd76e7091a5..84f53633b39 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/v8_types.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/v8_types.py
@@ -280,9 +280,12 @@ def cpp_type(idl_type, extended_attributes=None, raw_type=False, used_as_rvalue_
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
if idl_type.is_custom_callback_function:
- return 'V8%s' % base_idl_type
- return 'V8%s*' % base_idl_type
+ return v8_type_name
+ if not used_in_cpp_sequence:
+ return v8_type_name + '*'
+ return cpp_template_type('TraceWrapperMember', v8_type_name)
if base_idl_type == 'void':
return base_idl_type
@@ -387,7 +390,7 @@ IdlTypeBase.is_gc_type = property(is_gc_type)
def is_traceable(idl_type):
- return (idl_type.is_garbage_collected or idl_type.is_dictionary)
+ return idl_type.is_garbage_collected or idl_type.is_dictionary or idl_type.is_callback_function
IdlTypeBase.is_traceable = property(is_traceable)
IdlUnionType.is_traceable = property(lambda self: True)
@@ -520,6 +523,10 @@ def impl_includes_for_type(idl_type, interfaces_info):
base_idl_type = idl_type.base_type
if idl_type.is_string_type:
includes_for_type.add('platform/wtf/text/wtf_string.h')
+ if idl_type.is_callback_function:
+ component = IdlType.callback_functions[base_idl_type]['component_dir']
+ return set(['bindings/%s/v8/%s' % (component, binding_header_filename(base_idl_type)),
+ 'platform/bindings/trace_wrapper_member.h'])
if base_idl_type in interfaces_info:
interface_info = interfaces_info[base_idl_type]
includes_for_type.add(interface_info['include_path'])
@@ -1109,6 +1116,26 @@ 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',
+ 'any': 'ScriptValue',
+ 'boolean': 'IDLBoolean',
+ 'long': 'IDLLong',
+ 'sequence<DOMString>': 'IDLSequence<IDLString>',
+ 'unsigned short': 'IDLUnsignedShort',
+ 'void': None,
+}
+
+
+def idl_type_to_native_value_traits_tag(idl_type):
+ idl_type_str = str(idl_type)
+ if idl_type_str in _IDL_TYPE_TO_NATIVE_VALUE_TRAITS_TAG_MAP:
+ return _IDL_TYPE_TO_NATIVE_VALUE_TRAITS_TAG_MAP[idl_type_str]
+ else:
+ raise Exception("Type `%s' is not supported." % idl_type_str)
+
+
################################################################################
# Utility properties for nullable types
################################################################################
diff --git a/chromium/third_party/blink/renderer/bindings/templates/attributes.cpp.tmpl b/chromium/third_party/blink/renderer/bindings/templates/attributes.cpp.tmpl
index 050de28af93..7e54f95c8b1 100644
--- a/chromium/third_party/blink/renderer/bindings/templates/attributes.cpp.tmpl
+++ b/chromium/third_party/blink/renderer/bindings/templates/attributes.cpp.tmpl
@@ -533,6 +533,8 @@ const v8::FunctionCallbackInfo<v8::Value>& info
else 'V8DOMConfiguration::kCheckHolder' %}
{% set getter_side_effect_type = 'V8DOMConfiguration::kHasNoSideEffect'
if attribute.getter_has_no_side_effect else 'V8DOMConfiguration::kHasSideEffect' %}
+{% set getter_behavior = 'V8DOMConfiguration::kAlwaysCallGetter'
+ if not attribute.is_lazy_data_attribute else 'V8DOMConfiguration::kReplaceWithDataProperty' %}
{% if attribute.is_per_world_bindings %}
{% set getter_callback_for_main_world = '%sForMainWorld' % getter_callback %}
{% set setter_callback_for_main_world =
@@ -556,6 +558,7 @@ const v8::FunctionCallbackInfo<v8::Value>& info
property_location(attribute),
holder_check,
getter_side_effect_type,
+ getter_behavior,
] %}
{% if attribute.is_per_world_bindings %}
diff --git a/chromium/third_party/blink/renderer/bindings/templates/callback_function.cpp.tmpl b/chromium/third_party/blink/renderer/bindings/templates/callback_function.cpp.tmpl
index b4e90663660..a32046bf39e 100644
--- a/chromium/third_party/blink/renderer/bindings/templates/callback_function.cpp.tmpl
+++ b/chromium/third_party/blink/renderer/bindings/templates/callback_function.cpp.tmpl
@@ -1,4 +1,4 @@
-{% from 'utilities.cpp.tmpl' import declare_enum_validation_variable, v8_value_to_local_cpp_value %}
+{% from 'callback_invoke.cc.tmpl' import callback_invoke %}
{% filter format_blink_cpp_source_code %}
{% include 'copyright_block.txt' %}
@@ -16,124 +16,27 @@ const char* {{cpp_class}}::NameInHeapSnapshot() const {
}
v8::Maybe<{{return_cpp_type}}> {{cpp_class}}::Invoke({{argument_declarations | join(', ')}}) {
- // This function implements "invoke" algorithm defined in
- // "3.10. Invoking callback functions".
- // https://heycam.github.io/webidl/#es-invoking-callback-functions
-
- {# TODO(yukishiino): This implementation does not support a return type of
- promise type, in which case this function needs to convert any exception
- into a rejected promise. See also step 14.4. to 14.6. #}
-
- if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState(),
- IncumbentScriptState())) {
- // Wrapper-tracing for the callback function makes the function object and
- // its creation context alive. Thus it's safe to use the creation context
- // of the callback function here.
- v8::HandleScope handle_scope(GetIsolate());
- CHECK(!CallbackFunction().IsEmpty());
- v8::Context::Scope context_scope(CallbackFunction()->CreationContext());
- V8ThrowException::ThrowError(
- GetIsolate(),
- ExceptionMessages::FailedToExecute(
- "invoke",
- "{{callback_function_name}}",
- "The provided callback is no longer runnable."));
- return v8::Nothing<{{return_cpp_type}}>();
- }
-
- // step 4. If ! IsCallable(F) is false:
- //
- // As Blink no longer supports [TreatNonObjectAsNull], there must be no such a
- // case.
-#if DCHECK_IS_ON()
- {
- v8::HandleScope handle_scope(GetIsolate());
- DCHECK(CallbackFunction()->IsFunction());
- }
-#endif
-
- // step 8. Prepare to run script with relevant settings.
- ScriptState::Scope callback_relevant_context_scope(
- CallbackRelevantScriptState());
- // step 9. Prepare to run a callback with stored settings.
- v8::Context::BackupIncumbentScope backup_incumbent_scope(
- IncumbentScriptState()->GetContext());
-
- v8::Local<v8::Value> this_arg = ToV8(callback_this_value,
- CallbackRelevantScriptState());
-
- {% for argument in arguments if argument.enum_values %}
- // Enum values provided by Blink must be valid, otherwise typo.
-#if DCHECK_IS_ON()
- {
- {% set valid_enum_variables = 'valid_' + argument.name + '_values' %}
- {{declare_enum_validation_variable(argument.enum_values, valid_enum_variables) | trim | indent(4)}}
- ExceptionState exception_state(GetIsolate(),
- ExceptionState::kExecutionContext,
- "{{callback_function_name}}",
- "invoke");
- if (!IsValidEnum({{argument.name}}, {{valid_enum_variables}}, base::size({{valid_enum_variables}}), "{{argument.enum_type}}", exception_state)) {
- NOTREACHED();
- return v8::Nothing<{{return_cpp_type}}>();
- }
- }
-#endif
-
- {% endfor %}
-
- // step 10. Let esArgs be the result of converting args to an ECMAScript
- // arguments list. If this throws an exception, set completion to the
- // completion value representing the thrown exception and jump to the step
- // labeled return.
- {% if arguments %}
- v8::Local<v8::Object> argument_creation_context =
- CallbackRelevantScriptState()->GetContext()->Global();
- ALLOW_UNUSED_LOCAL(argument_creation_context);
- {% for argument in arguments %}
- v8::Local<v8::Value> {{argument.v8_name}} = {{argument.cpp_value_to_v8_value}};
- {% endfor %}
- v8::Local<v8::Value> argv[] = { {{arguments | join(', ', 'v8_name')}} };
- {% else %}
- {# Zero-length arrays are ill-formed in C++. #}
- v8::Local<v8::Value> *argv = nullptr;
- {% endif %}
-
- // step 11. Let callResult be Call(X, thisArg, esArgs).
- v8::Local<v8::Value> call_result;
- if (!V8ScriptRunner::CallFunction(
- CallbackFunction(),
- ExecutionContext::From(CallbackRelevantScriptState()),
- this_arg,
- {{arguments | length}},
- argv,
- GetIsolate()).ToLocal(&call_result)) {
- // step 12. If callResult is an abrupt completion, set completion to
- // callResult and jump to the step labeled return.
- return v8::Nothing<{{return_cpp_type}}>();
- }
+{{callback_invoke(
+ 'callback function', 'invoke',
+ return_cpp_type, native_value_traits_tag, arguments,
+ callback_function_name, 'invoke')}}
+}
- // step 13. Set completion to the result of converting callResult.[[Value]] to
- // an IDL value of the same type as the operation's return type.
- {% if idl_type == 'void' %}
- return v8::JustVoid();
- {% else %}
- {
- ExceptionState exceptionState(GetIsolate(),
- ExceptionState::kExecutionContext,
- "{{callback_function_name}}",
- "invoke");
- {{v8_value_to_local_cpp_value(return_value_conversion) | trim | indent(4)}}
- return v8::Just<{{return_cpp_type}}>(native_result);
- }
- {% endif %}
+{% if idl_type == 'any' %}
+v8::Maybe<{{return_cpp_type}}> {{cpp_class}}::Construct({{argument_declarations[1:] | join(', ')}}) {
+{{callback_invoke(
+ 'callback function', 'construct',
+ return_cpp_type, native_value_traits_tag, arguments,
+ callback_function_name, 'construct')}}
}
+{% endif %}
-{% if idl_type == 'void' %}
+{% if idl_type == 'void' or callback_function_name == 'Function' %}
void {{cpp_class}}::InvokeAndReportException({{argument_declarations | join(', ')}}) {
v8::TryCatch try_catch(GetIsolate());
try_catch.SetVerbose(true);
- v8::Maybe<void> maybe_result =
+ v8::Maybe<{{return_cpp_type}}> maybe_result =
Invoke({{
(['callback_this_value'] +
(arguments|map(attribute='name')|list)
@@ -153,7 +56,7 @@ v8::Maybe<{{return_cpp_type}}> V8PersistentCallbackFunction<{{cpp_class}}>::Invo
}});
}
-{% if idl_type == 'void' %}
+{% if idl_type == 'void' or callback_function_name == 'Function' %}
void V8PersistentCallbackFunction<{{cpp_class}}>::InvokeAndReportException({{argument_declarations | join(', ')}}) {
Proxy()->InvokeAndReportException(
{{
diff --git a/chromium/third_party/blink/renderer/bindings/templates/callback_function.h.tmpl b/chromium/third_party/blink/renderer/bindings/templates/callback_function.h.tmpl
index 44b5414376d..80dc70c9c77 100644
--- a/chromium/third_party/blink/renderer/bindings/templates/callback_function.h.tmpl
+++ b/chromium/third_party/blink/renderer/bindings/templates/callback_function.h.tmpl
@@ -30,7 +30,18 @@ class {{exported}}{{cpp_class}} final : public CallbackFunctionBase {
// https://heycam.github.io/webidl/#es-invoking-callback-functions
v8::Maybe<{{return_cpp_type}}> Invoke({{argument_declarations | join(', ')}}) WARN_UNUSED_RESULT;
-{% if idl_type == 'void' %}
+{# Web IDL does not distinguish callback constructors from callback functions.
+ If the return type is 'any', then it\'s likely to be used as a callback
+ constructor. #}
+{% if idl_type == 'any' %}
+ // Performs "construct".
+ // https://heycam.github.io/webidl/#construct-a-callback-function
+ v8::Maybe<{{return_cpp_type}}> Construct({{argument_declarations[1:] | join(', ')}}) WARN_UNUSED_RESULT;
+{% endif %}
+
+{# Type Function is often used as a sort of wild cards, and its return value is
+ often discarded. So, this provides some convenience. #}
+{% if idl_type == 'void' or callback_function_name == 'Function' %}
// Performs "invoke", and then reports an exception, if any, to the global
// error handler such as DevTools' console.
void InvokeAndReportException({{argument_declarations | join(', ')}});
@@ -52,7 +63,7 @@ class V8PersistentCallbackFunction<{{cpp_class}}> final : public V8PersistentCal
V8CallbackFunction* ToNonV8Persistent() { return Proxy(); }
v8::Maybe<{{return_cpp_type}}> Invoke({{argument_declarations | join(', ')}}) WARN_UNUSED_RESULT;
-{% if idl_type == 'void' %}
+{% if idl_type == 'void' or callback_function_name == 'Function' %}
{{exported}}void InvokeAndReportException({{argument_declarations | join(', ')}});
{% endif %}
diff --git a/chromium/third_party/blink/renderer/bindings/templates/callback_interface.cpp.tmpl b/chromium/third_party/blink/renderer/bindings/templates/callback_interface.cpp.tmpl
index bd507150c47..012652e7648 100644
--- a/chromium/third_party/blink/renderer/bindings/templates/callback_interface.cpp.tmpl
+++ b/chromium/third_party/blink/renderer/bindings/templates/callback_interface.cpp.tmpl
@@ -1,3 +1,4 @@
+{% from 'callback_invoke.cc.tmpl' import callback_invoke %}
{% filter format_blink_cpp_source_code %}
{% include 'copyright_block.txt' %}
@@ -70,145 +71,10 @@ const char* {{v8_class}}::NameInHeapSnapshot() const {
{% for method in methods %}
v8::Maybe<{{method.cpp_type}}> {{v8_class}}::{{method.name}}({{method.argument_declarations | join(', ')}}) {
- // This function implements "call a user object's operation".
- // https://heycam.github.io/webidl/#call-a-user-objects-operation
-
- if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState(),
- IncumbentScriptState())) {
- // Wrapper-tracing for the callback function makes the function object and
- // its creation context alive. Thus it's safe to use the creation context
- // of the callback function here.
- v8::HandleScope handle_scope(GetIsolate());
- CHECK(!CallbackObject().IsEmpty());
- v8::Context::Scope context_scope(CallbackObject()->CreationContext());
- V8ThrowException::ThrowError(
- GetIsolate(),
- ExceptionMessages::FailedToExecute(
- "{{method.name}}",
- "{{cpp_class}}",
- "The provided callback is no longer runnable."));
- return v8::Nothing<{{method.cpp_type}}>();
- }
-
- // step 7. Prepare to run script with relevant settings.
- ScriptState::Scope callback_relevant_context_scope(
- CallbackRelevantScriptState());
- // step 8. Prepare to run a callback with stored settings.
- v8::Context::BackupIncumbentScope backup_incumbent_scope(
- IncumbentScriptState()->GetContext());
-
- v8::Local<v8::Function> function;
- if (IsCallbackObjectCallable()) {
- // step 9.1. If value's interface is a single operation callback interface
- // and !IsCallable(O) is true, then set X to O.
- function = CallbackObject().As<v8::Function>();
- } else {
- // step 9.2.1. Let getResult be Get(O, opName).
- // step 9.2.2. If getResult is an abrupt completion, set completion to
- // getResult and jump to the step labeled return.
- v8::Local<v8::Value> value;
- if (!CallbackObject()->Get(CallbackRelevantScriptState()->GetContext(),
- V8String(GetIsolate(), "{{method.name}}"))
- .ToLocal(&value)) {
- return v8::Nothing<{{method.cpp_type}}>();
- }
- // step 10. If !IsCallable(X) is false, then set completion to a new
- // Completion{[[Type]]: throw, [[Value]]: a newly created TypeError
- // object, [[Target]]: empty}, and jump to the step labeled return.
- if (!value->IsFunction()) {
- V8ThrowException::ThrowTypeError(
- GetIsolate(),
- ExceptionMessages::FailedToExecute(
- "{{method.name}}",
- "{{cpp_class}}",
- "The provided callback is not callable."));
- return v8::Nothing<{{method.cpp_type}}>();
- }
- function = value.As<v8::Function>();
- }
-
- v8::Local<v8::Value> this_arg;
- if (!IsCallbackObjectCallable()) {
- // step 11. If value's interface is not a single operation callback
- // interface, or if !IsCallable(O) is false, set thisArg to O (overriding
- // the provided value).
- this_arg = CallbackObject();
- } else if (!callback_this_value) {
- // step 2. If thisArg was not given, let thisArg be undefined.
- this_arg = v8::Undefined(GetIsolate());
- } else {
- this_arg = ToV8(callback_this_value, CallbackRelevantScriptState());
- }
-
- {% for argument in arguments if argument.enum_values %}
- // Enum values provided by Blink must be valid, otherwise typo.
-#if DCHECK_IS_ON()
- {
- {% set valid_enum_variables = 'valid_' + argument.name + '_values' %}
- {{declare_enum_validation_variable(argument.enum_values, valid_enum_variables) | trim | indent(4)}}
- ExceptionState exception_state(GetIsolate(),
- ExceptionState::kExecutionContext,
- "{{cpp_class}}",
- "{{method.name}}");
- if (!IsValidEnum({{argument.name}}, {{valid_enum_variables}}, base::size({{valid_enum_variables}}), "{{argument.enum_type}}", exception_state)) { //
- NOTREACHED();
- return v8::Nothing<{{method.cpp_type}}>();
- }
- }
-#endif
-
- {% endfor %}
-
- // step 12. Let esArgs be the result of converting args to an ECMAScript
- // arguments list. If this throws an exception, set completion to the
- // completion value representing the thrown exception and jump to the step
- // labeled return.
- {% if method.arguments %}
- v8::Local<v8::Object> argument_creation_context =
- CallbackRelevantScriptState()->GetContext()->Global();
- ALLOW_UNUSED_LOCAL(argument_creation_context);
- {% for argument in method.arguments %}
- v8::Local<v8::Value> {{argument.handle}} = {{argument.cpp_value_to_v8_value}};
- {% endfor %}
- v8::Local<v8::Value> argv[] = { {{method.arguments | join(', ', 'handle')}} };
- {% else %}
- {# Zero-length arrays are ill-formed in C++. #}
- v8::Local<v8::Value> *argv = nullptr;
- {% endif %}
-
- // step 13. Let callResult be Call(X, thisArg, esArgs).
- v8::Local<v8::Value> call_result;
- if (!V8ScriptRunner::CallFunction(
- function,
- ExecutionContext::From(CallbackRelevantScriptState()),
- this_arg,
- {{method.arguments | length}},
- argv,
- GetIsolate()).ToLocal(&call_result)) {
- // step 14. If callResult is an abrupt completion, set completion to
- // callResult and jump to the step labeled return.
- return v8::Nothing<{{method.cpp_type}}>();
- }
-
- // step 15. Set completion to the result of converting callResult.[[Value]] to
- // an IDL value of the same type as the operation's return type.
- {% if method.idl_type == 'void' %}
- return v8::JustVoid();
- {% else %}
- {
- ExceptionState exception_state(GetIsolate(),
- ExceptionState::kExecutionContext,
- "{{cpp_class}}",
- "{{method.name}}");
- auto native_result =
- NativeValueTraits<{{method.native_value_traits_tag}}>::NativeValue(
- GetIsolate(), call_result, exception_state);
- if (exception_state.HadException())
- return v8::Nothing<{{method.cpp_type}}>();
- else
- return v8::Just<{{method.cpp_type}}>(native_result);
- }
- {% endif %}
+{{callback_invoke(
+ 'callback interface', None,
+ method.cpp_type, method.native_value_traits_tag, method.arguments,
+ interface_name, method.name)}}
}
{% endfor %}
diff --git a/chromium/third_party/blink/renderer/bindings/templates/callback_invoke.cc.tmpl b/chromium/third_party/blink/renderer/bindings/templates/callback_invoke.cc.tmpl
new file mode 100644
index 00000000000..6127fe04de4
--- /dev/null
+++ b/chromium/third_party/blink/renderer/bindings/templates/callback_invoke.cc.tmpl
@@ -0,0 +1,229 @@
+{% from 'utilities.cpp.tmpl' import declare_enum_validation_variable %}
+
+{# Implements callback interface\'s "call a user object's operation", or
+ callback function\'s "invoke" and/or "construct".
+ https://heycam.github.io/webidl/#call-a-user-objects-operation
+ https://heycam.github.io/webidl/#es-invoking-callback-functions
+
+ Args:
+ interface_or_function = 'callback interface' or 'callback function'
+ invoke_or_construct = 'invoke', 'construct', or None
+ return_cpp_type = Blink (C++) return type
+ return_native_value_traits_tag = tag of NativeValueTraits for return type
+ arguments = dict of arguments\' info
+ interface_name = interface name used for exception
+ operation_name = interface name used for exception and property lookup
+#}
+{% macro callback_invoke(
+ interface_or_function, invoke_or_construct,
+ return_cpp_type, return_native_value_traits_tag, arguments,
+ interface_name, operation_name) %}
+ if (!IsCallbackFunctionRunnable(CallbackRelevantScriptState(),
+ IncumbentScriptState())) {
+ // Wrapper-tracing for the callback function makes the function object and
+ // its creation context alive. Thus it's safe to use the creation context
+ // of the callback function here.
+ v8::HandleScope handle_scope(GetIsolate());
+ {% if interface_or_function == 'callback function' %}
+ v8::Local<v8::Object> callback_object = CallbackFunction();
+ {% else %}
+ v8::Local<v8::Object> callback_object = CallbackObject();
+ {% endif %}
+ CHECK(!callback_object.IsEmpty());
+ v8::Context::Scope context_scope(callback_object->CreationContext());
+ V8ThrowException::ThrowError(
+ GetIsolate(),
+ ExceptionMessages::FailedToExecute(
+ "{{operation_name}}",
+ "{{interface_name}}",
+ "The provided callback is no longer runnable."));
+ return v8::Nothing<{{return_cpp_type}}>();
+ }
+
+ // step: Prepare to run script with relevant settings.
+ ScriptState::Scope callback_relevant_context_scope(
+ CallbackRelevantScriptState());
+ // step: Prepare to run a callback with stored settings.
+ v8::Context::BackupIncumbentScope backup_incumbent_scope(
+ IncumbentScriptState()->GetContext());
+
+ {% if invoke_or_construct == 'construct' %}
+ // step 3. If ! IsConstructor(F) is false, throw a TypeError exception.
+ //
+ // Note that step 7. and 8. are side effect free (except for a very rare
+ // exception due to no incumbent realm), so it's okay to put step 3. after
+ // step 7. and 8.
+ if (!CallbackFunction()->IsConstructor()) {
+ V8ThrowException::ThrowTypeError(
+ GetIsolate(),
+ ExceptionMessages::FailedToExecute(
+ "{{operation_name}}",
+ "{{interface_name}}",
+ "The provided callback is not a constructor."));
+ return v8::Nothing<{{return_cpp_type}}>();
+ }
+ {% endif %}
+
+ v8::Local<v8::Function> function;
+ {# Fill |function|. #}
+ {% if interface_or_function == 'callback function' %}
+ // callback function\'s invoke:
+ // step 4. If ! IsCallable(F) is false:
+ //
+ // As Blink no longer supports [TreatNonObjectAsNull], there must be no such a
+ // case.
+ DCHECK(CallbackFunction()->IsFunction());
+ function = CallbackFunction();
+ {% else %}
+ if (IsCallbackObjectCallable()) {
+ // step 9.1. If value's interface is a single operation callback interface
+ // and !IsCallable(O) is true, then set X to O.
+ function = CallbackObject().As<v8::Function>();
+ } else {
+ // step 9.2.1. Let getResult be Get(O, opName).
+ // step 9.2.2. If getResult is an abrupt completion, set completion to
+ // getResult and jump to the step labeled return.
+ v8::Local<v8::Value> value;
+ if (!CallbackObject()->Get(CallbackRelevantScriptState()->GetContext(),
+ V8String(GetIsolate(), "{{operation_name}}"))
+ .ToLocal(&value)) {
+ return v8::Nothing<{{return_cpp_type}}>();
+ }
+ // step 10. If !IsCallable(X) is false, then set completion to a new
+ // Completion{[[Type]]: throw, [[Value]]: a newly created TypeError
+ // object, [[Target]]: empty}, and jump to the step labeled return.
+ if (!value->IsFunction()) {
+ V8ThrowException::ThrowTypeError(
+ GetIsolate(),
+ ExceptionMessages::FailedToExecute(
+ "{{operation_name}}",
+ "{{interface_name}}",
+ "The provided callback is not callable."));
+ return v8::Nothing<{{return_cpp_type}}>();
+ }
+ function = value.As<v8::Function>();
+ }
+ {% endif %}
+
+ {% if invoke_or_construct != 'construct' %}
+ v8::Local<v8::Value> this_arg;
+ {% endif %}
+ {# Fill |this_arg|. #}
+ {% if invoke_or_construct == 'invoke' %}
+ this_arg = ToV8(callback_this_value, CallbackRelevantScriptState());
+ {% elif interface_or_function == 'callback interface' %}
+ if (!IsCallbackObjectCallable()) {
+ // step 11. If value's interface is not a single operation callback
+ // interface, or if !IsCallable(O) is false, set thisArg to O (overriding
+ // the provided value).
+ this_arg = CallbackObject();
+ } else if (!callback_this_value) {
+ // step 2. If thisArg was not given, let thisArg be undefined.
+ this_arg = v8::Undefined(GetIsolate());
+ } else {
+ this_arg = ToV8(callback_this_value, CallbackRelevantScriptState());
+ }
+ {% endif %}
+
+ {% for argument in arguments if argument.enum_values %}
+ // Enum values provided by Blink must be valid, otherwise typo.
+#if DCHECK_IS_ON()
+ {
+ {% set valid_enum_variables = 'valid_' + argument.name + '_values' %}
+ {{declare_enum_validation_variable(argument.enum_values, valid_enum_variables) | trim | indent(4)}}
+ ExceptionState exception_state(GetIsolate(),
+ ExceptionState::kExecutionContext,
+ "{{interface_name}}",
+ "{{operation_name}}");
+ if (!IsValidEnum({{argument.name}}, {{valid_enum_variables}}, base::size({{valid_enum_variables}}), "{{argument.enum_type}}", exception_state)) { //
+ NOTREACHED();
+ return v8::Nothing<{{return_cpp_type}}>();
+ }
+ }
+#endif
+ {% endfor %}
+
+ // step: Let esArgs be the result of converting args to an ECMAScript
+ // arguments list. If this throws an exception, set completion to the
+ // completion value representing the thrown exception and jump to the step
+ // labeled return.
+ {% if arguments %}
+ v8::Local<v8::Object> argument_creation_context =
+ CallbackRelevantScriptState()->GetContext()->Global();
+ ALLOW_UNUSED_LOCAL(argument_creation_context);
+ {% set has_variadic_argument = arguments[-1].is_variadic %}
+ {% set non_variadic_arguments = arguments | rejectattr('is_variadic') | list %}
+ {% set variadic_argument = arguments[-1] if has_variadic_argument else None %}
+ {% set arguments_length = '%d + %s.size()' % (non_variadic_arguments|length, variadic_argument.name) if has_variadic_argument else non_variadic_arguments|length %}
+ {% for argument in non_variadic_arguments %}
+ v8::Local<v8::Value> {{argument.v8_name}} = {{argument.cpp_value_to_v8_value}};
+ {% endfor %}
+ {% if has_variadic_argument %}
+ const int argc = {{arguments_length}};
+ v8::Local<v8::Value> argv[argc];
+ {% for argument in non_variadic_arguments %}
+ argv[{{loop.index0}}] = {{argument.v8_name}};
+ {% endfor %}
+ for (wtf_size_t i = 0; i < {{variadic_argument.name}}.size(); ++i) {
+ argv[{{non_variadic_arguments|length}} + i] = ToV8({{variadic_argument.name}}[i], argument_creation_context, GetIsolate());
+ }
+ {% else %}{# if has_variadic_argument #}
+ constexpr int argc = {{arguments_length}};
+ v8::Local<v8::Value> argv[] = { {{non_variadic_arguments | join(', ', 'v8_name')}} };
+ static_assert(static_cast<size_t>(argc) == base::size(argv), "size mismatch");
+ {% endif %}
+ {% else %}{# if arguments #}
+ const int argc = 0;
+ {# Zero-length arrays are ill-formed in C++. #}
+ v8::Local<v8::Value> *argv = nullptr;
+ {% endif %}
+
+ v8::Local<v8::Value> call_result;
+ {# Fill |call_result|. #}
+ {% if invoke_or_construct == 'construct' %}
+ if (!V8ScriptRunner::CallAsConstructor(
+ GetIsolate(),
+ function,
+ ExecutionContext::From(CallbackRelevantScriptState()),
+ argc,
+ argv).ToLocal(&call_result)) {
+ // step 11. If callResult is an abrupt completion, set completion to
+ // callResult and jump to the step labeled return.
+ return v8::Nothing<{{return_cpp_type}}>();
+ }
+ {% else %}
+ // step: Let callResult be Call(X, thisArg, esArgs).
+ if (!V8ScriptRunner::CallFunction(
+ function,
+ ExecutionContext::From(CallbackRelevantScriptState()),
+ this_arg,
+ argc,
+ argv,
+ GetIsolate()).ToLocal(&call_result)) {
+ // step: If callResult is an abrupt completion, set completion to callResult
+ // and jump to the step labeled return.
+ return v8::Nothing<{{return_cpp_type}}>();
+ }
+ {% endif %}
+
+
+ // step: Set completion to the result of converting callResult.[[Value]] to
+ // an IDL value of the same type as the operation's return type.
+ {% if return_cpp_type == 'void' %}
+ return v8::JustVoid();
+ {% else %}
+ {
+ ExceptionState exception_state(GetIsolate(),
+ ExceptionState::kExecutionContext,
+ "{{interface_name}}",
+ "{{operation_name}}");
+ auto native_result =
+ NativeValueTraits<{{return_native_value_traits_tag}}>::NativeValue(
+ GetIsolate(), call_result, exception_state);
+ if (exception_state.HadException())
+ return v8::Nothing<{{return_cpp_type}}>();
+ else
+ return v8::Just<{{return_cpp_type}}>(native_result);
+ }
+ {% endif %}
+{% endmacro %}
diff --git a/chromium/third_party/blink/renderer/bindings/templates/interface.cpp.tmpl b/chromium/third_party/blink/renderer/bindings/templates/interface.cpp.tmpl
index 9bd26814261..e67dd55a04c 100644
--- a/chromium/third_party/blink/renderer/bindings/templates/interface.cpp.tmpl
+++ b/chromium/third_party/blink/renderer/bindings/templates/interface.cpp.tmpl
@@ -886,10 +886,10 @@ static const V8DOMConfiguration::AttributeConfiguration {{method.name}}OriginSaf
{% set getter_callback_for_main_world = '%sForMainWorld' % getter_callback %}
{% set setter_callback_for_main_world = '%sForMainWorld' % setter_callback
if not method.is_unforgeable else 'nullptr' %}
- {"{{method.name}}", {{getter_callback_for_main_world}}, {{setter_callback_for_main_world}}, {{property_attribute}}, {{property_location(method)}}, {{holder_check}}, V8DOMConfiguration::kHasSideEffect, V8DOMConfiguration::MainWorld},
- {"{{method.name}}", {{getter_callback}}, {{setter_callback}}, {{property_attribute}}, {{property_location(method)}}, {{holder_check}}, V8DOMConfiguration::kHasSideEffect, V8DOMConfiguration::NonMainWorlds}}
+ {"{{method.name}}", {{getter_callback_for_main_world}}, {{setter_callback_for_main_world}}, {{property_attribute}}, {{property_location(method)}}, {{holder_check}}, V8DOMConfiguration::kHasSideEffect, V8DOMConfiguration::kAlwaysCallGetter, V8DOMConfiguration::MainWorld},
+ {"{{method.name}}", {{getter_callback}}, {{setter_callback}}, {{property_attribute}}, {{property_location(method)}}, {{holder_check}}, V8DOMConfiguration::kHasSideEffect, V8DOMConfiguration::kAlwaysCallGetter, V8DOMConfiguration::NonMainWorlds}}
{% else %}
- {"{{method.name}}", {{getter_callback}}, {{setter_callback}}, {{property_attribute}}, {{property_location(method)}}, {{holder_check}}, V8DOMConfiguration::kHasSideEffect, V8DOMConfiguration::kAllWorlds}
+ {"{{method.name}}", {{getter_callback}}, {{setter_callback}}, {{property_attribute}}, {{property_location(method)}}, {{holder_check}}, V8DOMConfiguration::kHasSideEffect, V8DOMConfiguration::kAlwaysCallGetter, V8DOMConfiguration::kAllWorlds}
{% endif %}
};
for (const auto& attributeConfig : {{method.name}}OriginSafeAttributeConfiguration)
@@ -1050,7 +1050,8 @@ v8::Local<v8::Object> {{v8_class}}::findInstanceInPrototypeChain(v8::Local<v8::V
v8Contents.Data(),
v8Contents.ByteLength(),
kind,
- WTF::ArrayBufferContents::FreeMemory);
+ v8Contents.Deleter(),
+ v8Contents.DeleterData());
WTF::ArrayBufferContents contents(std::move(data), WTF::ArrayBufferContents::k{% if interface_name == 'ArrayBuffer' %}Not{% endif %}Shared);
{{cpp_class}}* buffer = {{cpp_class}}::Create(contents);
v8::Local<v8::Object> associatedWrapper = buffer->AssociateWithWrapper(v8::Isolate::GetCurrent(), buffer->GetWrapperTypeInfo(), object);
diff --git a/chromium/third_party/blink/renderer/bindings/templates/interface_base.cpp.tmpl b/chromium/third_party/blink/renderer/bindings/templates/interface_base.cpp.tmpl
index afa46eb913e..af6790dfa52 100644
--- a/chromium/third_party/blink/renderer/bindings/templates/interface_base.cpp.tmpl
+++ b/chromium/third_party/blink/renderer/bindings/templates/interface_base.cpp.tmpl
@@ -101,17 +101,13 @@ static void (*{{method.name}}MethodForPartialInterface)(const v8::FunctionCallba
{# Methods #}
{% from 'methods.cpp.tmpl' import generate_method, overload_resolution_method,
origin_safe_method_getter, generate_constructor,
- generate_post_message_impl, runtime_determined_length_method,
- runtime_determined_maxarg_method
+ runtime_determined_length_method, runtime_determined_maxarg_method
with context %}
{% for method in methods %}
{% for world_suffix in method.world_suffixes %}
-{% if not method.is_custom and not method.is_post_message and method.visible %}
+{% if not method.is_custom and method.visible %}
{{generate_method(method, world_suffix)}}
{% endif %}
-{% if method.is_post_message and not is_partial %}
-{{generate_post_message_impl(method)}}
-{% endif %}
{% if method.overloads and method.overloads.visible %}
{% if method.overloads.runtime_determined_lengths %}
{{runtime_determined_length_method(method.overloads)}}
@@ -374,27 +370,6 @@ static const V8DOMConfiguration::AttributeConfiguration {{v8_class}}Attributes[]
{% endif %}
{% endblock %}
{##############################################################################}
-{% block install_lazy_data_attributes %}
-{% from 'attributes.cpp.tmpl' import attribute_configuration with context %}
-{% if lazy_data_attributes %}
-// Suppress warning: global constructors, because AttributeConfiguration is trivial
-// and does not depend on another global objects.
-#if defined(COMPONENT_BUILD) && defined(WIN32) && defined(__clang__)
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wglobal-constructors"
-#endif
-static const V8DOMConfiguration::AttributeConfiguration {{v8_class}}LazyDataAttributes[] = {
- {% for data_attribute in lazy_data_attributes %}
- {{attribute_configuration(data_attribute) | trim | indent(4)}},
- {% endfor %}
-};
-#if defined(COMPONENT_BUILD) && defined(WIN32) && defined(__clang__)
-#pragma clang diagnostic pop
-#endif
-
-{% endif %}
-{% endblock %}
-{##############################################################################}
{% block install_accessors %}
{% from 'attributes.cpp.tmpl' import accessor_configuration with context %}
{% if accessors %}
@@ -496,11 +471,6 @@ static void install{{v8_class}}Template(
isolate, world, instanceTemplate, prototypeTemplate,
{{'%sAttributes' % v8_class}}, {{'base::size(%sAttributes)' % v8_class}});
{% endif %}
- {% if lazy_data_attributes %}
- V8DOMConfiguration::InstallLazyDataAttributes(
- isolate, world, instanceTemplate, prototypeTemplate,
- {{'%sLazyDataAttributes' % v8_class}}, {{'base::size(%sLazyDataAttributes)' % v8_class}});
- {% endif %}
{% if accessors %}
V8DOMConfiguration::InstallAccessors(
isolate, world, instanceTemplate, prototypeTemplate, interfaceTemplate,
diff --git a/chromium/third_party/blink/renderer/bindings/templates/methods.cpp.tmpl b/chromium/third_party/blink/renderer/bindings/templates/methods.cpp.tmpl
index 1c81b4fc347..ec8eaaadd48 100644
--- a/chromium/third_party/blink/renderer/bindings/templates/methods.cpp.tmpl
+++ b/chromium/third_party/blink/renderer/bindings/templates/methods.cpp.tmpl
@@ -212,6 +212,20 @@ 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.name}} = ScriptValue(ScriptState::Current(info.GetIsolate()), v8::Null(info.GetIsolate()));
+{% elif argument.is_optional %}
+} else if (info[{{argument.index}}]->IsUndefined()) {
+ {{argument.name}} = ScriptValue(ScriptState::Current(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 #}
@@ -458,66 +472,6 @@ if ({{test}}) {
{% endmacro %}
-{##############################################################################}
-{% macro generate_post_message_impl(method) %}
-static void postMessageImpl(const char* interfaceName, {{cpp_class}}* instance, const v8::FunctionCallbackInfo<v8::Value>& info) {
- ExceptionState exceptionState(info.GetIsolate(), ExceptionState::kExecutionContext, interfaceName, "postMessage");
- if (UNLIKELY(info.Length() < {{method.number_of_required_arguments}})) {
- exceptionState.ThrowTypeError(ExceptionMessages::NotEnoughArguments({{method.number_of_required_arguments}}, info.Length()));
- return;
- }
-
- Transferables transferables;
- if (info.Length() > 1) {
- const int transferablesArgIndex = 1;
- if (!SerializedScriptValue::ExtractTransferables(info.GetIsolate(), info[transferablesArgIndex], transferablesArgIndex, transferables, exceptionState)) {
- return;
- }
- }
-
- scoped_refptr<SerializedScriptValue> message;
- if (instance->CanTransferArrayBuffersAndImageBitmaps()) {
- // This instance supports sending array buffers by move semantics.
- SerializedScriptValue::SerializeOptions options;
- options.transferables = &transferables;
- message = SerializedScriptValue::Serialize(info.GetIsolate(), info[0], options, exceptionState);
- if (exceptionState.HadException())
- return;
- } else {
- // This instance doesn't support sending array buffers and image bitmaps
- // by move semantics. Emulate it by copy-and-neuter semantics that sends
- // array buffers and image bitmaps via structured clone and then neuters
- // the original objects
-
- // Clear references to array buffers and image bitmaps from transferables
- // so that the serializer can consider the array buffers as
- // non-transferable and serialize them into the message.
- ArrayBufferArray transferableArrayBuffers = SerializedScriptValue::ExtractNonSharedArrayBuffers(transferables);
- ImageBitmapArray transferableImageBitmaps = transferables.image_bitmaps;
- transferables.image_bitmaps.clear();
- SerializedScriptValue::SerializeOptions options;
- options.transferables = &transferables;
- message = SerializedScriptValue::Serialize(info.GetIsolate(), info[0], options, exceptionState);
- if (exceptionState.HadException())
- return;
-
- // Neuter the original array buffers on the sender context.
- SerializedScriptValue::TransferArrayBufferContents(info.GetIsolate(), transferableArrayBuffers, exceptionState);
- if (exceptionState.HadException())
- return;
- // Neuter the original image bitmaps on the sender context.
- SerializedScriptValue::TransferImageBitmapContents(info.GetIsolate(), transferableImageBitmaps, exceptionState);
- if (exceptionState.HadException())
- return;
- }
-
- // FIXME: Only pass scriptState/exceptionState if instance really requires it.
- ScriptState* scriptState = ScriptState::Current(info.GetIsolate());
- message->UnregisterMemoryAllocatedWithCurrentScriptContext();
- instance->postMessage(scriptState, std::move(message), transferables.message_ports, exceptionState);
-}
-{% endmacro %}
-
{##############################################################################}
{% macro method_callback(method, world_suffix) %}
@@ -548,8 +502,6 @@ void {{v8_class_or_partial}}::{{method.name}}MethodCallback{{world_suffix}}(cons
{% endif %}
{% if method.is_custom %}
{{v8_class}}::{{method.name}}MethodCustom(info);
- {% elif method.is_post_message %}
- {{cpp_class_or_partial}}V8Internal::postMessageImpl("{{interface_name}}", {{v8_class}}::ToImpl(info.Holder()), info);
{% else %}
{{cpp_class_or_partial}}V8Internal::{{method.name}}Method{{world_suffix}}(info);
{% endif %}
diff --git a/chromium/third_party/blink/renderer/bindings/templates/templates.gni b/chromium/third_party/blink/renderer/bindings/templates/templates.gni
index 8cd38ce9611..b6c270e5e03 100644
--- a/chromium/third_party/blink/renderer/bindings/templates/templates.gni
+++ b/chromium/third_party/blink/renderer/bindings/templates/templates.gni
@@ -10,11 +10,12 @@ code_generator_template_files =
"callback_function.h.tmpl",
"callback_interface.cpp.tmpl",
"callback_interface.h.tmpl",
+ "callback_invoke.cc.tmpl",
"constants.cpp.tmpl",
"copyright_block.txt",
"dictionary_impl.cpp.tmpl",
- "dictionary_impl_common.cpp.tmpl",
"dictionary_impl.h.tmpl",
+ "dictionary_impl_common.cpp.tmpl",
"dictionary_v8.cpp.tmpl",
"dictionary_v8.h.tmpl",
"external_reference_table.cpp.tmpl",
diff --git a/chromium/third_party/blink/renderer/bindings/templates/union_container.cpp.tmpl b/chromium/third_party/blink/renderer/bindings/templates/union_container.cpp.tmpl
index f01f7b1ec8d..2b6b64ce60e 100644
--- a/chromium/third_party/blink/renderer/bindings/templates/union_container.cpp.tmpl
+++ b/chromium/third_party/blink/renderer/bindings/templates/union_container.cpp.tmpl
@@ -192,7 +192,7 @@ void {{v8_class}}::ToImpl(v8::Isolate* isolate, v8::Local<v8::Value> v8Value, {{
{# 16. Boolean (fallback) #}
{% elif boolean_type %}
{
- impl.SetBoolean(v8Value->BooleanValue());
+ impl.SetBoolean(v8Value->BooleanValue(isolate->GetCurrentContext()).ToChecked());
return;
}
diff --git a/chromium/third_party/blink/renderer/build/scripts/core/css/templates/cssom_types.cc.tmpl b/chromium/third_party/blink/renderer/build/scripts/core/css/templates/cssom_types.cc.tmpl
index 425b9d20148..79fea233825 100644
--- a/chromium/third_party/blink/renderer/build/scripts/core/css/templates/cssom_types.cc.tmpl
+++ b/chromium/third_party/blink/renderer/build/scripts/core/css/templates/cssom_types.cc.tmpl
@@ -7,73 +7,77 @@
#include "third_party/blink/renderer/core/css/cssom/cssom_types.h"
-#include "third_party/blink/renderer/core/css/cssom/cssom_keywords.h"
#include "third_party/blink/renderer/core/css/cssom/css_keyword_value.h"
#include "third_party/blink/renderer/core/css/cssom/css_numeric_value.h"
#include "third_party/blink/renderer/core/css/cssom/css_style_value.h"
#include "third_party/blink/renderer/core/css/cssom/css_unsupported_style_value.h"
+#include "third_party/blink/renderer/core/css/cssom/cssom_keywords.h"
#include "third_party/blink/renderer/core/css/properties/css_property.h"
+#include "third_party/blink/renderer/core/css/property_registration.h"
namespace blink {
-namespace {
-
-bool IsCSSStyleValueLength(const CSSStyleValue& value) {
+bool CSSOMTypes::IsCSSStyleValueLength(const CSSStyleValue& value) {
if (!value.IsNumericValue())
return false;
return static_cast<const CSSNumericValue&>(value).Type().
MatchesBaseType(CSSNumericValueType::BaseType::kLength);
}
-bool IsCSSStyleValueNumber(const CSSStyleValue& value) {
+bool CSSOMTypes::IsCSSStyleValueNumber(const CSSStyleValue& value) {
if (!value.IsNumericValue())
return false;
return static_cast<const CSSNumericValue&>(value).Type().
MatchesNumber();
}
-bool IsCSSStyleValueTime(const CSSStyleValue& value) {
+bool CSSOMTypes::IsCSSStyleValueTime(const CSSStyleValue& value) {
if (!value.IsNumericValue())
return false;
return static_cast<const CSSNumericValue&>(value).Type().
MatchesBaseType(CSSNumericValueType::BaseType::kTime);
}
-bool IsCSSStyleValueAngle(const CSSStyleValue& value) {
+bool CSSOMTypes::IsCSSStyleValueAngle(const CSSStyleValue& value) {
if (!value.IsNumericValue())
return false;
return static_cast<const CSSNumericValue&>(value).Type().
MatchesBaseType(CSSNumericValueType::BaseType::kAngle);
}
-bool IsCSSStyleValuePercentage(const CSSStyleValue& value) {
+bool CSSOMTypes::IsCSSStyleValuePercentage(const CSSStyleValue& value) {
if (!value.IsNumericValue())
return false;
return static_cast<const CSSNumericValue&>(value).Type().
MatchesPercentage();
}
-bool IsCSSStyleValueFlex(const CSSStyleValue& value) {
+bool CSSOMTypes::IsCSSStyleValueResolution(const CSSStyleValue& value) {
+ if (!value.IsNumericValue())
+ return false;
+ return static_cast<const CSSNumericValue&>(value).Type().
+ MatchesBaseType(CSSNumericValueType::BaseType::kResolution);
+}
+
+bool CSSOMTypes::IsCSSStyleValueFlex(const CSSStyleValue& value) {
if (!value.IsNumericValue())
return false;
return static_cast<const CSSNumericValue&>(value).Type().
MatchesBaseType(CSSNumericValueType::BaseType::kFlex);
}
-bool IsCSSStyleValueImage(const CSSStyleValue& value) {
+bool CSSOMTypes::IsCSSStyleValueImage(const CSSStyleValue& value) {
return value.GetType() == CSSStyleValue::kURLImageType;
}
-bool IsCSSStyleValueTransform(const CSSStyleValue& value) {
+bool CSSOMTypes::IsCSSStyleValueTransform(const CSSStyleValue& value) {
return value.GetType() == CSSStyleValue::kTransformType;
}
-bool IsCSSStyleValuePosition(const CSSStyleValue& value) {
+bool CSSOMTypes::IsCSSStyleValuePosition(const CSSStyleValue& value) {
return value.GetType() == CSSStyleValue::kPositionType;
}
-}
-
bool CSSOMTypes::IsPropertySupported(CSSPropertyID id) {
switch (id) {
case CSSPropertyVariable:
@@ -87,7 +91,13 @@ bool CSSOMTypes::IsPropertySupported(CSSPropertyID id) {
}
bool CSSOMTypes::PropertyCanTake(CSSPropertyID id,
+ const PropertyRegistration* registration,
const CSSStyleValue& value) {
+
+ if (id == CSSPropertyVariable && registration) {
+ return registration->Syntax().CanTake(value);
+ }
+
if (value.GetType() == CSSStyleValue::kKeywordType) {
return CSSOMKeywords::ValidKeywordForProperty(
id, ToCSSKeywordValue(value));
@@ -107,7 +117,7 @@ bool CSSOMTypes::PropertyCanTake(CSSPropertyID id,
case {{property.property_id}}:
return (
{% for type in property.typedom_types if type != 'Keyword' %}
- {{ "|| " if not loop.first }}IsCSSStyleValue{{type}}(value)
+ {{ "|| " if not loop.first }}CSSOMTypes::IsCSSStyleValue{{type}}(value)
{% endfor %}
);
{% endif %}
diff --git a/chromium/third_party/blink/renderer/build/scripts/core/css/templates/style_property_shorthand.cc.tmpl b/chromium/third_party/blink/renderer/build/scripts/core/css/templates/style_property_shorthand.cc.tmpl
index aef5305626d..f17e0f58f03 100644
--- a/chromium/third_party/blink/renderer/build/scripts/core/css/templates/style_property_shorthand.cc.tmpl
+++ b/chromium/third_party/blink/renderer/build/scripts/core/css/templates/style_property_shorthand.cc.tmpl
@@ -83,7 +83,8 @@ void getMatchingShorthandsForLonghand(
{% for longhand_id, shorthands in longhands_dictionary.items() %}
case {{longhand_id}}: {
{% for shorthand in shorthands %}
- result->UncheckedAppend({{shorthand.name.to_lower_camel_case()}}Shorthand());
+ if (CSSProperty::Get({{shorthand.property_id}}).IsEnabled())
+ result->UncheckedAppend({{shorthand.name.to_lower_camel_case()}}Shorthand());
{% endfor %}
break;
}
diff --git a/chromium/third_party/blink/renderer/build/scripts/templates/InstrumentingProbesInl.h.tmpl b/chromium/third_party/blink/renderer/build/scripts/templates/InstrumentingProbesInl.h.tmpl
index 1fa858b634c..d465ddbcf4d 100644
--- a/chromium/third_party/blink/renderer/build/scripts/templates/InstrumentingProbesInl.h.tmpl
+++ b/chromium/third_party/blink/renderer/build/scripts/templates/InstrumentingProbesInl.h.tmpl
@@ -9,6 +9,7 @@
#define {{file.header_name}}_h
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_source_code.h"
{% for include in config["settings"]["includes"] %}
#include "{{include}}"
{% endfor %}
diff --git a/chromium/third_party/blink/renderer/controller/BUILD.gn b/chromium/third_party/blink/renderer/controller/BUILD.gn
index 20d1994e156..c9f9a18f118 100644
--- a/chromium/third_party/blink/renderer/controller/BUILD.gn
+++ b/chromium/third_party/blink/renderer/controller/BUILD.gn
@@ -47,6 +47,8 @@ component("controller") {
if (is_android) {
sources += [
+ "crash_memory_metrics_reporter_impl.cc",
+ "crash_memory_metrics_reporter_impl.h",
"oom_intervention_impl.cc",
"oom_intervention_impl.h",
]
diff --git a/chromium/third_party/blink/renderer/controller/blink_initializer.cc b/chromium/third_party/blink/renderer/controller/blink_initializer.cc
index 3c95d67dff2..27ad5077b22 100644
--- a/chromium/third_party/blink/renderer/controller/blink_initializer.cc
+++ b/chromium/third_party/blink/renderer/controller/blink_initializer.cc
@@ -57,6 +57,7 @@
#include "v8/include/v8.h"
#if defined(OS_ANDROID)
+#include "third_party/blink/renderer/controller/crash_memory_metrics_reporter_impl.h"
#include "third_party/blink/renderer/controller/oom_intervention_impl.h"
#endif
@@ -73,20 +74,16 @@ class EndOfTaskRunner : public WebThread::TaskObserver {
}
};
-} // namespace
-
-static WebThread::TaskObserver* g_end_of_task_runner = nullptr;
+WebThread::TaskObserver* g_end_of_task_runner = nullptr;
-static BlinkInitializer& GetBlinkInitializer() {
+BlinkInitializer& GetBlinkInitializer() {
DEFINE_STATIC_LOCAL(std::unique_ptr<BlinkInitializer>, initializer,
(std::make_unique<BlinkInitializer>()));
return *initializer;
}
-void Initialize(Platform* platform, service_manager::BinderRegistry* registry) {
- DCHECK(registry);
- Platform::Initialize(platform);
-
+void InitializeCommon(Platform* platform,
+ service_manager::BinderRegistry* registry) {
#if !defined(ARCH_CPU_X86_64) && !defined(ARCH_CPU_ARM64) && defined(OS_WIN)
// Reserve address space on 32 bit Windows, to make it likelier that large
// array buffer allocations succeed.
@@ -139,6 +136,23 @@ void Initialize(Platform* platform, service_manager::BinderRegistry* registry) {
}
}
+} // namespace
+
+void Initialize(Platform* platform,
+ service_manager::BinderRegistry* registry,
+ WebThread* main_thread) {
+ DCHECK(registry);
+ Platform::Initialize(platform, main_thread);
+ InitializeCommon(platform, registry);
+}
+
+void CreateMainThreadAndInitialize(Platform* platform,
+ service_manager::BinderRegistry* registry) {
+ DCHECK(registry);
+ Platform::CreateMainThreadAndInitialize(platform);
+ InitializeCommon(platform, registry);
+}
+
void BlinkInitializer::RegisterInterfaces(
service_manager::BinderRegistry& registry) {
ModulesInitializer::RegisterInterfaces(registry);
@@ -152,6 +166,10 @@ void BlinkInitializer::RegisterInterfaces(
registry.AddInterface(
ConvertToBaseCallback(CrossThreadBind(&OomInterventionImpl::Create)),
main_thread->GetTaskRunner());
+
+ registry.AddInterface(ConvertToBaseCallback(CrossThreadBind(
+ &CrashMemoryMetricsReporterImpl::Bind)),
+ main_thread->GetTaskRunner());
#endif
registry.AddInterface(
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
new file mode 100644
index 00000000000..d7f181318f9
--- /dev/null
+++ b/chromium/third_party/blink/renderer/controller/crash_memory_metrics_reporter_impl.cc
@@ -0,0 +1,161 @@
+// 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/controller/crash_memory_metrics_reporter_impl.h"
+
+#include <ctype.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "base/metrics/histogram_macros.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "third_party/blink/public/platform/platform.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"
+
+namespace blink {
+
+namespace {
+
+constexpr uint32_t kMaxLineSize = 4096;
+bool ReadFileContents(int fd, char contents[kMaxLineSize]) {
+ lseek(fd, 0, SEEK_SET);
+ int res = read(fd, contents, kMaxLineSize - 1);
+ if (res <= 0)
+ return false;
+ contents[res] = '\0';
+ return true;
+}
+
+// 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 CalculateProcessMemoryFootprint(int statm_fd,
+ int status_fd,
+ uint64_t* private_footprint,
+ uint64_t* swap_footprint,
+ uint64_t* vm_size) {
+ // Get total resident and shared sizes from statm file.
+ static size_t page_size = getpagesize();
+ uint64_t resident_pages;
+ uint64_t shared_pages;
+ uint64_t vm_size_pages;
+ char line[kMaxLineSize];
+ if (!ReadFileContents(statm_fd, line))
+ return false;
+ int num_scanned = sscanf(line, "%" SCNu64 " %" SCNu64 " %" SCNu64,
+ &vm_size_pages, &resident_pages, &shared_pages);
+ if (num_scanned != 3)
+ return false;
+
+ // Get swap size from status file. The format is: VmSwap : 10 kB.
+ if (!ReadFileContents(status_fd, line))
+ return false;
+ char* swap_line = strstr(line, "VmSwap");
+ if (!swap_line)
+ return false;
+ num_scanned = sscanf(swap_line, "VmSwap: %" SCNu64 " kB", swap_footprint);
+ if (num_scanned != 1)
+ return false;
+
+ *swap_footprint *= 1024;
+ *private_footprint =
+ (resident_pages - shared_pages) * page_size + *swap_footprint;
+ *vm_size = vm_size_pages * page_size;
+ return true;
+}
+
+// Roughly calculates amount of memory which is used to execute pages.
+uint64_t BlinkMemoryWorkloadCalculator() {
+ v8::Isolate* isolate = V8PerIsolateData::MainThreadIsolate();
+ DCHECK(isolate);
+ v8::HeapStatistics heap_statistics;
+ isolate->GetHeapStatistics(&heap_statistics);
+ // TODO: Add memory usage for worker threads.
+ size_t v8_size =
+ heap_statistics.total_heap_size() + heap_statistics.malloced_memory();
+ size_t blink_gc_size = ProcessHeap::TotalAllocatedObjectSize() +
+ ProcessHeap::TotalMarkedObjectSize();
+ size_t partition_alloc_size = WTF::Partitions::TotalSizeOfCommittedPages();
+ return v8_size + blink_gc_size + partition_alloc_size;
+}
+} // namespace
+
+// static
+void CrashMemoryMetricsReporterImpl::Bind(
+ mojom::blink::CrashMemoryMetricsReporterRequest request) {
+ // This should be called only once per process on RenderProcessWillLaunch.
+ DCHECK(!CrashMemoryMetricsReporterImpl::Instance().binding_.is_bound());
+ CrashMemoryMetricsReporterImpl::Instance().binding_.Bind(std::move(request));
+}
+
+CrashMemoryMetricsReporterImpl& CrashMemoryMetricsReporterImpl::Instance() {
+ DEFINE_STATIC_LOCAL(CrashMemoryMetricsReporterImpl,
+ crash_memory_metrics_reporter_impl, ());
+ return crash_memory_metrics_reporter_impl;
+}
+
+CrashMemoryMetricsReporterImpl::CrashMemoryMetricsReporterImpl()
+ : binding_(this) {}
+
+CrashMemoryMetricsReporterImpl::~CrashMemoryMetricsReporterImpl() = default;
+
+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();
+}
+
+void CrashMemoryMetricsReporterImpl::WriteIntoSharedMemory(
+ const OomInterventionMetrics& metrics) {
+ if (!shared_metrics_mapping_.IsValid())
+ return;
+ auto* metrics_shared =
+ shared_metrics_mapping_.GetMemoryAs<OomInterventionMetrics>();
+ memcpy(metrics_shared, &metrics, sizeof(OomInterventionMetrics));
+}
+
+void CrashMemoryMetricsReporterImpl::OnVirtualMemoryOOMCallback(
+ bool virtual_memory_oom) {
+ // If shared_metrics_mapping_ is not set, it means OnNoMemory happened before
+ // initializing render process host sets the shared memory.
+ if (!shared_metrics_mapping_.IsValid())
+ return;
+ // Else, we can send the virtual_memory_oom_oom bool.
+ OomInterventionMetrics metrics;
+ metrics.virtual_memory_oom = 1; // true
+ WriteIntoSharedMemory(metrics);
+}
+
+OomInterventionMetrics
+CrashMemoryMetricsReporterImpl::GetCurrentMemoryMetrics() {
+ // This can only be called after ResetFileDescriptors().
+ DCHECK(statm_fd_.is_valid() && status_fd_.is_valid());
+
+ OomInterventionMetrics metrics = {};
+ metrics.current_blink_usage_kb = BlinkMemoryWorkloadCalculator() / 1024;
+ uint64_t private_footprint, swap, vm_size;
+ if (CalculateProcessMemoryFootprint(statm_fd_.get(), status_fd_.get(),
+ &private_footprint, &swap, &vm_size)) {
+ metrics.current_private_footprint_kb = private_footprint / 1024;
+ metrics.current_swap_kb = swap / 1024;
+ metrics.current_vm_size_kb = vm_size / 1024;
+ }
+ metrics.virtual_memory_oom = 0; // false
+ return metrics;
+}
+
+bool CrashMemoryMetricsReporterImpl::ResetFileDiscriptors() {
+ // See https://goo.gl/KjWnZP For details about why we read these files from
+ // sandboxed renderer. Keep these files open when detection is enabled.
+ if (!statm_fd_.is_valid())
+ statm_fd_.reset(open("/proc/self/statm", O_RDONLY));
+ if (!status_fd_.is_valid())
+ status_fd_.reset(open("/proc/self/status", O_RDONLY));
+ return !statm_fd_.is_valid() || !status_fd_.is_valid();
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..060db1cae07
--- /dev/null
+++ b/chromium/third_party/blink/renderer/controller/crash_memory_metrics_reporter_impl.h
@@ -0,0 +1,55 @@
+// 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_CONTROLLER_CRASH_MEMORY_METRICS_REPORTER_IMPL_H_
+#define THIRD_PARTY_BLINK_RENDERER_CONTROLLER_CRASH_MEMORY_METRICS_REPORTER_IMPL_H_
+
+#include "base/files/scoped_file.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "third_party/blink/public/common/oom_intervention/oom_intervention_types.h"
+#include "third_party/blink/public/mojom/crash/crash_memory_metrics_reporter.mojom-blink.h"
+#include "third_party/blink/renderer/controller/controller_export.h"
+
+namespace blink {
+
+// Writes data about renderer into shared memory that will be read by browser.
+class CONTROLLER_EXPORT CrashMemoryMetricsReporterImpl
+ : public mojom::blink::CrashMemoryMetricsReporter {
+ public:
+ static CrashMemoryMetricsReporterImpl& Instance();
+ static void Bind(mojom::blink::CrashMemoryMetricsReporterRequest);
+
+ ~CrashMemoryMetricsReporterImpl() override;
+
+ // mojom::CrashMemoryMetricsReporter implementations:
+ void SetSharedMemory(
+ base::UnsafeSharedMemoryRegion shared_metrics_buffer) override;
+
+ void WriteIntoSharedMemory(const OomInterventionMetrics& metrics);
+
+ void OnVirtualMemoryOOMCallback(bool virtual_memory_oom);
+
+ // This function needs to be called after ResetFileDescriptors.
+ OomInterventionMetrics GetCurrentMemoryMetrics();
+
+ // This function resets statm_fd_ & status_fd_ to prepare for getting metrics.
+ bool ResetFileDiscriptors();
+
+ protected:
+ CrashMemoryMetricsReporterImpl();
+
+ private:
+ FRIEND_TEST_ALL_PREFIXES(OomInterventionImplTest, CalculateProcessFootprint);
+
+ base::WritableSharedMemoryMapping shared_metrics_mapping_;
+ mojo::Binding<mojom::blink::CrashMemoryMetricsReporter> binding_;
+
+ // The file descriptor to current process proc files. The files are kept open
+ // when detection is on to reduce measurement overhead.
+ base::ScopedFD statm_fd_;
+ base::ScopedFD status_fd_;
+};
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CONTROLLER_CRASH_MEMORY_METRICS_REPORTER_IMPL_H_
diff --git a/chromium/third_party/blink/renderer/controller/oom_intervention_impl.cc b/chromium/third_party/blink/renderer/controller/oom_intervention_impl.cc
index 4d9b60c78b1..1ab1444f9ce 100644
--- a/chromium/third_party/blink/renderer/controller/oom_intervention_impl.cc
+++ b/chromium/third_party/blink/renderer/controller/oom_intervention_impl.cc
@@ -4,101 +4,17 @@
#include "third_party/blink/renderer/controller/oom_intervention_impl.h"
-#include <ctype.h>
-#include <fcntl.h>
-#include <unistd.h>
-
#include "base/metrics/histogram_macros.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "third_party/blink/public/platform/platform.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/bindings/core/v8/v8_gc_for_context_dispose.h"
+#include "third_party/blink/renderer/controller/crash_memory_metrics_reporter_impl.h"
+#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/platform/web_task_runner.h"
#include "third_party/blink/renderer/platform/wtf/allocator/partitions.h"
namespace blink {
-namespace {
-
-constexpr uint32_t kMaxLineSize = 4096;
-bool ReadFileContents(int fd, char contents[kMaxLineSize]) {
- lseek(fd, 0, SEEK_SET);
- int res = read(fd, contents, kMaxLineSize - 1);
- if (res <= 0)
- return false;
- contents[res] = '\0';
- return true;
-}
-
-// 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 CalculateProcessMemoryFootprint(int statm_fd,
- int status_fd,
- uint64_t* private_footprint,
- uint64_t* swap_footprint,
- uint64_t* vm_size) {
- // Get total resident and shared sizes from statm file.
- static size_t page_size = getpagesize();
- uint64_t resident_pages;
- uint64_t shared_pages;
- uint64_t vm_size_pages;
- char line[kMaxLineSize];
- if (!ReadFileContents(statm_fd, line))
- return false;
- int num_scanned = sscanf(line, "%" SCNu64 " %" SCNu64 " %" SCNu64,
- &vm_size_pages, &resident_pages, &shared_pages);
- if (num_scanned != 3)
- return false;
-
- // Get swap size from status file. The format is: VmSwap : 10 kB.
- if (!ReadFileContents(status_fd, line))
- return false;
- char* swap_line = strstr(line, "VmSwap");
- if (!swap_line)
- return false;
- num_scanned = sscanf(swap_line, "VmSwap: %" SCNu64 " kB", swap_footprint);
- if (num_scanned != 1)
- return false;
-
- *swap_footprint *= 1024;
- *private_footprint =
- (resident_pages - shared_pages) * page_size + *swap_footprint;
- *vm_size = vm_size_pages * page_size;
- return true;
-}
-
-// Roughly caclculates amount of memory which is used to execute pages.
-uint64_t BlinkMemoryWorkloadCaculator() {
- v8::Isolate* isolate = V8PerIsolateData::MainThreadIsolate();
- DCHECK(isolate);
- v8::HeapStatistics heap_statistics;
- isolate->GetHeapStatistics(&heap_statistics);
- // TODO: Add memory usage for worker threads.
- size_t v8_size =
- heap_statistics.total_heap_size() + heap_statistics.malloced_memory();
- size_t blink_gc_size = ProcessHeap::TotalAllocatedObjectSize() +
- ProcessHeap::TotalMarkedObjectSize();
- size_t partition_alloc_size = WTF::Partitions::TotalSizeOfCommittedPages();
- return v8_size + blink_gc_size + partition_alloc_size;
-}
-
-// These values are persisted to logs. Entries should not be renumbered and
-// numeric values should never be reused.
-enum class RendererInterventionEnabledStatus {
- kDetectionOnlyEnabled = 0,
- kTriggerEnabled = 1,
- kDisabledFailedMemoryMetricsFetch = 2,
- kMaxValue = kDisabledFailedMemoryMetricsFetch
-};
-
-void RecordEnabledStatus(RendererInterventionEnabledStatus status) {
- UMA_HISTOGRAM_ENUMERATION(
- "Memory.Experimental.OomIntervention.RendererEnabledStatus", status);
-}
-
-} // namespace
-
// static
void OomInterventionImpl::Create(mojom::blink::OomInterventionRequest request) {
mojo::MakeStrongBinding(std::make_unique<OomInterventionImpl>(),
@@ -114,52 +30,29 @@ OomInterventionImpl::~OomInterventionImpl() {}
void OomInterventionImpl::StartDetection(
mojom::blink::OomInterventionHostPtr host,
- base::UnsafeSharedMemoryRegion shared_metrics_buffer,
mojom::blink::DetectionArgsPtr detection_args,
- bool trigger_intervention) {
+ bool renderer_pause_enabled,
+ bool navigate_ads_enabled) {
host_ = std::move(host);
- shared_metrics_buffer_ = shared_metrics_buffer.Map();
-
- // See https://goo.gl/KjWnZP For details about why we read these files from
- // sandboxed renderer. Keep these files open when detection is enabled.
- if (!statm_fd_.is_valid())
- statm_fd_.reset(open("/proc/self/statm", O_RDONLY));
- if (!status_fd_.is_valid())
- status_fd_.reset(open("/proc/self/status", O_RDONLY));
+
// Disable intervention if we cannot get memory details of current process.
- if (!statm_fd_.is_valid() || !status_fd_.is_valid()) {
- RecordEnabledStatus(
- RendererInterventionEnabledStatus::kDisabledFailedMemoryMetricsFetch);
+ if (CrashMemoryMetricsReporterImpl::Instance().ResetFileDiscriptors())
return;
- }
- RecordEnabledStatus(
- trigger_intervention
- ? RendererInterventionEnabledStatus::kTriggerEnabled
- : RendererInterventionEnabledStatus::kDetectionOnlyEnabled);
detection_args_ = std::move(detection_args);
- trigger_intervention_ = trigger_intervention;
+ renderer_pause_enabled_ = renderer_pause_enabled;
+ navigate_ads_enabled_ = navigate_ads_enabled;
timer_.Start(TimeDelta(), TimeDelta::FromSeconds(1), FROM_HERE);
}
OomInterventionMetrics OomInterventionImpl::GetCurrentMemoryMetrics() {
- OomInterventionMetrics metrics = {};
- metrics.current_blink_usage_kb = BlinkMemoryWorkloadCaculator() / 1024;
- uint64_t private_footprint, swap, vm_size;
- if (CalculateProcessMemoryFootprint(statm_fd_.get(), status_fd_.get(),
- &private_footprint, &swap, &vm_size)) {
- metrics.current_private_footprint_kb = private_footprint / 1024;
- metrics.current_swap_kb = swap / 1024;
- metrics.current_vm_size_kb = vm_size / 1024;
- }
- return metrics;
+ return CrashMemoryMetricsReporterImpl::Instance().GetCurrentMemoryMetrics();
}
void OomInterventionImpl::Check(TimerBase*) {
DCHECK(host_);
- DCHECK(statm_fd_.is_valid());
- DCHECK(status_fd_.is_valid());
+ DCHECK(renderer_pause_enabled_ || navigate_ads_enabled_);
OomInterventionMetrics current_memory = GetCurrentMemoryMetrics();
bool oom_detected = false;
@@ -178,18 +71,29 @@ void OomInterventionImpl::Check(TimerBase*) {
detection_args_->virtual_memory_thresold;
if (oom_detected) {
- host_->OnHighMemoryUsage(trigger_intervention_);
+ if (navigate_ads_enabled_) {
+ for (const auto& page : Page::OrdinaryPages()) {
+ if (page->MainFrame()->IsLocalFrame()) {
+ ToLocalFrame(page->MainFrame())
+ ->GetDocument()
+ ->NavigateLocalAdsFrames();
+ }
+ }
+ }
- if (trigger_intervention_) {
+ if (renderer_pause_enabled_) {
// The ScopedPagePauser is destroyed when the intervention is declined and
// mojo strong binding is disconnected.
pauser_.reset(new ScopedPagePauser);
}
+ host_->OnHighMemoryUsage();
+ timer_.Stop();
+ // Notify V8GCForContextDispose that page navigation gc is needed when
+ // intervention runs, as it indicates that memory usage is high.
+ V8GCForContextDispose::Instance().SetForcePageNavigationGC();
}
-
- OomInterventionMetrics* metrics_shared =
- static_cast<OomInterventionMetrics*>(shared_metrics_buffer_.memory());
- memcpy(metrics_shared, &current_memory, sizeof(OomInterventionMetrics));
+ CrashMemoryMetricsReporterImpl::Instance().WriteIntoSharedMemory(
+ current_memory);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/controller/oom_intervention_impl.h b/chromium/third_party/blink/renderer/controller/oom_intervention_impl.h
index 4d548e15c90..a2113ac204f 100644
--- a/chromium/third_party/blink/renderer/controller/oom_intervention_impl.h
+++ b/chromium/third_party/blink/renderer/controller/oom_intervention_impl.h
@@ -6,9 +6,10 @@
#define THIRD_PARTY_BLINK_RENDERER_CONTROLLER_OOM_INTERVENTION_IMPL_H_
#include "base/files/scoped_file.h"
-#include "third_party/blink/common/oom_intervention/oom_intervention_types.h"
+#include "third_party/blink/public/common/oom_intervention/oom_intervention_types.h"
#include "third_party/blink/public/platform/oom_intervention.mojom-blink.h"
#include "third_party/blink/renderer/controller/controller_export.h"
+#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/page/scoped_page_pauser.h"
#include "third_party/blink/renderer/platform/timer.h"
@@ -28,30 +29,27 @@ class CONTROLLER_EXPORT OomInterventionImpl
// mojom::blink::OomIntervention:
void StartDetection(mojom::blink::OomInterventionHostPtr,
- base::UnsafeSharedMemoryRegion shared_metrics_buffer,
mojom::blink::DetectionArgsPtr detection_args,
- bool trigger_intervention) override;
-
- protected:
- // Overridden by test.
- virtual OomInterventionMetrics GetCurrentMemoryMetrics();
+ bool renderer_pause_enabled,
+ bool navigate_ads_enabled) override;
private:
FRIEND_TEST_ALL_PREFIXES(OomInterventionImplTest, DetectedAndDeclined);
FRIEND_TEST_ALL_PREFIXES(OomInterventionImplTest, CalculateProcessFootprint);
+ FRIEND_TEST_ALL_PREFIXES(OomInterventionImplTest, StopWatchingAfterDetection);
+ FRIEND_TEST_ALL_PREFIXES(OomInterventionImplTest,
+ ContinueWatchingWithoutDetection);
+ FRIEND_TEST_ALL_PREFIXES(OomInterventionImplTest, V1DetectionAdsNavigation);
+ // Overridden by test.
+ virtual OomInterventionMetrics GetCurrentMemoryMetrics();
void Check(TimerBase*);
- // The file descriptor to current process proc files. The files are kept open
- // when detection is on to reduce measurement overhead.
- base::ScopedFD statm_fd_;
- base::ScopedFD status_fd_;
-
mojom::blink::DetectionArgsPtr detection_args_;
- base::WritableSharedMemoryMapping shared_metrics_buffer_;
mojom::blink::OomInterventionHostPtr host_;
- bool trigger_intervention_ = false;
+ bool renderer_pause_enabled_ = false;
+ bool navigate_ads_enabled_ = false;
TaskRunnerTimer<OomInterventionImpl> timer_;
std::unique_ptr<ScopedPagePauser> pauser_;
};
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 b49e173ea24..aeb5f8945cc 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
@@ -10,14 +10,18 @@
#include "mojo/public/cpp/bindings/binding.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/common/oom_intervention/oom_intervention_types.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"
#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_frame.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/page/page.h"
#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
+#include "third_party/blink/renderer/core/testing/sim/sim_request.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
+#include "third_party/blink/renderer/platform/testing/url_test_helpers.h"
namespace blink {
@@ -34,7 +38,7 @@ class MockOomInterventionHost : public mojom::blink::OomInterventionHost {
: binding_(this, std::move(request)) {}
~MockOomInterventionHost() override = default;
- void OnHighMemoryUsage(bool intervention_triggered) override {}
+ void OnHighMemoryUsage() override {}
private:
mojo::Binding<mojom::blink::OomInterventionHost> binding_;
@@ -58,7 +62,7 @@ class MockOomInterventionImpl : public OomInterventionImpl {
OomInterventionMetrics GetCurrentMemoryMetrics() override {
if (metrics_)
return *metrics_;
- return OomInterventionImpl::GetCurrentMemoryMetrics();
+ return CrashMemoryMetricsReporterImpl::Instance().GetCurrentMemoryMetrics();
}
std::unique_ptr<OomInterventionMetrics> metrics_;
@@ -73,13 +77,16 @@ class OomInterventionImplTest : public testing::Test {
}
Page* DetectOnceOnBlankPage() {
- WebViewImpl* web_view = web_view_helper_.InitializeAndLoad("about::blank");
+ WebViewImpl* web_view = web_view_helper_.InitializeAndLoad("about:blank");
Page* page = web_view->MainFrameImpl()->GetFrame()->GetPage();
EXPECT_FALSE(page->Paused());
+ RunDetection(true, false);
+ return page;
+ }
+
+ void RunDetection(bool renderer_pause_enabled, bool navigate_ads_enabled) {
mojom::blink::OomInterventionHostPtr host_ptr;
MockOomInterventionHost mock_host(mojo::MakeRequest(&host_ptr));
- base::UnsafeSharedMemoryRegion shm =
- base::UnsafeSharedMemoryRegion::Create(sizeof(OomInterventionMetrics));
mojom::blink::DetectionArgsPtr args(mojom::blink::DetectionArgs::New());
args->blink_workload_threshold = kTestBlinkThreshold;
@@ -87,16 +94,15 @@ class OomInterventionImplTest : public testing::Test {
args->swap_threshold = kTestSwapThreshold;
args->virtual_memory_thresold = kTestVmSizeThreshold;
- intervention_->StartDetection(std::move(host_ptr), std::move(shm),
- std::move(args),
- true /*trigger_intervention*/);
+ intervention_->StartDetection(std::move(host_ptr), std::move(args),
+ renderer_pause_enabled, navigate_ads_enabled);
test::RunDelayedTasks(TimeDelta::FromSeconds(1));
- return page;
}
protected:
std::unique_ptr<MockOomInterventionImpl> intervention_;
FrameTestHelpers::WebViewHelper web_view_helper_;
+ std::unique_ptr<SimRequest> main_resource_;
};
TEST_F(OomInterventionImplTest, NoDetectionOnBelowThreshold) {
@@ -177,6 +183,34 @@ TEST_F(OomInterventionImplTest, VmSizeThresholdDetection) {
EXPECT_FALSE(page->Paused());
}
+TEST_F(OomInterventionImplTest, StopWatchingAfterDetection) {
+ OomInterventionMetrics mock_metrics = {};
+ // Set value more than the threshold to trigger intervention.
+ mock_metrics.current_blink_usage_kb = (kTestBlinkThreshold / 1024) + 1;
+ mock_metrics.current_private_footprint_kb = (kTestPMFThreshold / 1024) - 1;
+ mock_metrics.current_swap_kb = (kTestSwapThreshold / 1024) - 1;
+ mock_metrics.current_vm_size_kb = (kTestVmSizeThreshold / 1024) - 1;
+ intervention_->SetMetrics(mock_metrics);
+
+ DetectOnceOnBlankPage();
+
+ EXPECT_FALSE(intervention_->timer_.IsActive());
+}
+
+TEST_F(OomInterventionImplTest, ContinueWatchingWithoutDetection) {
+ OomInterventionMetrics mock_metrics = {};
+ // Set value less than the threshold to not trigger intervention.
+ mock_metrics.current_blink_usage_kb = (kTestBlinkThreshold / 1024) - 1;
+ mock_metrics.current_private_footprint_kb = (kTestPMFThreshold / 1024) - 1;
+ mock_metrics.current_swap_kb = (kTestSwapThreshold / 1024) - 1;
+ mock_metrics.current_vm_size_kb = (kTestVmSizeThreshold / 1024) - 1;
+ intervention_->SetMetrics(mock_metrics);
+
+ DetectOnceOnBlankPage();
+
+ EXPECT_TRUE(intervention_->timer_.IsActive());
+}
+
TEST_F(OomInterventionImplTest, CalculateProcessFootprint) {
const char kStatusFile[] =
"First: 1\n Second: 2 kB\nVmSwap: 10 kB \n Third: 10 kB\n Last: 8";
@@ -199,25 +233,75 @@ TEST_F(OomInterventionImplTest, CalculateProcessFootprint) {
base::File status_file(status_path,
base::File::FLAG_OPEN | base::File::FLAG_READ);
- intervention_->statm_fd_.reset(statm_file.TakePlatformFile());
- intervention_->status_fd_.reset(status_file.TakePlatformFile());
+ CrashMemoryMetricsReporterImpl::Instance().statm_fd_.reset(
+ statm_file.TakePlatformFile());
+ CrashMemoryMetricsReporterImpl::Instance().status_fd_.reset(
+ status_file.TakePlatformFile());
mojom::blink::OomInterventionHostPtr host_ptr;
MockOomInterventionHost mock_host(mojo::MakeRequest(&host_ptr));
+ mojom::blink::DetectionArgsPtr args(mojom::blink::DetectionArgs::New());
+ intervention_->StartDetection(std::move(host_ptr), std::move(args),
+ true /*renderer_pause_enabled*/,
+ true /*navigate_ads_enabled*/);
+ // Create unsafe shared memory region to write metrics in reporter.
base::UnsafeSharedMemoryRegion shm =
base::UnsafeSharedMemoryRegion::Create(sizeof(OomInterventionMetrics));
- mojom::blink::DetectionArgsPtr args(mojom::blink::DetectionArgs::New());
- intervention_->StartDetection(std::move(host_ptr), std::move(shm),
- std::move(args),
- false /*trigger_intervention*/);
+ CrashMemoryMetricsReporterImpl::Instance().shared_metrics_mapping_ =
+ shm.Map();
+ EXPECT_TRUE(CrashMemoryMetricsReporterImpl::Instance()
+ .shared_metrics_mapping_.IsValid());
intervention_->Check(nullptr);
OomInterventionMetrics* metrics = static_cast<OomInterventionMetrics*>(
- intervention_->shared_metrics_buffer_.memory());
+ CrashMemoryMetricsReporterImpl::Instance()
+ .shared_metrics_mapping_.memory());
EXPECT_EQ(expected_private_footprint_kb,
metrics->current_private_footprint_kb);
EXPECT_EQ(expected_swap_kb, metrics->current_swap_kb);
EXPECT_EQ(expected_vm_size_kb, metrics->current_vm_size_kb);
}
+// TODO(yuzus): Once OOPIF unit test infrastructure is ready, add a test case
+// with OOPIF enabled.
+TEST_F(OomInterventionImplTest, V1DetectionAdsNavigation) {
+ OomInterventionMetrics mock_metrics = {};
+ mock_metrics.current_blink_usage_kb = (kTestBlinkThreshold / 1024) - 1;
+ mock_metrics.current_private_footprint_kb = (kTestPMFThreshold / 1024) - 1;
+ mock_metrics.current_swap_kb = (kTestSwapThreshold / 1024) - 1;
+ // Set value more than the threshold to trigger intervention.
+ mock_metrics.current_vm_size_kb = (kTestVmSizeThreshold / 1024) + 1;
+ intervention_->SetMetrics(mock_metrics);
+
+ 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,'>");
+
+ WebFrame* ad_iframe = web_view_helper_.LocalMainFrame()->FindFrameByName(
+ WebString::FromUTF8("ad"));
+ WebFrame* non_ad_iframe = web_view_helper_.LocalMainFrame()->FindFrameByName(
+ WebString::FromUTF8("non-ad"));
+
+ LocalFrame* local_adframe = ToLocalFrame(WebFrame::ToCoreFrame(*ad_iframe));
+ local_adframe->SetIsAdSubframe();
+ LocalFrame* local_non_adframe =
+ ToLocalFrame(WebFrame::ToCoreFrame(*non_ad_iframe));
+
+ EXPECT_TRUE(local_adframe->IsAdSubframe());
+ EXPECT_FALSE(local_non_adframe->IsAdSubframe());
+
+ RunDetection(true, true);
+
+ EXPECT_EQ(local_adframe->GetDocument()->Url().GetString(), "about:blank");
+ EXPECT_NE(local_non_adframe->GetDocument()->Url().GetString(), "about:blank");
+ EXPECT_TRUE(page->Paused());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/BUILD.gn b/chromium/third_party/blink/renderer/core/BUILD.gn
index fa4dccf5768..a3d5f794373 100644
--- a/chromium/third_party/blink/renderer/core/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/BUILD.gn
@@ -31,6 +31,9 @@ config("config") {
if (is_chromecast) {
defines += [ "BLINK_MEDIA_LOG=LOG(INFO)" ]
}
+ if (blink_animation_use_time_delta) {
+ defines += [ "BLINK_ANIMATION_USE_TIME_DELTA" ]
+ }
}
config("core_include_dirs") {
@@ -101,7 +104,7 @@ source_set("prerequisites") {
public_deps = [
"//services/network/public/cpp:cpp",
"//services/service_manager/public/cpp",
- "//services/ui/public/interfaces/ime",
+ "//services/ws/public/mojom/ime",
"//skia",
"//third_party/angle:translator",
"//third_party/blink/public:core_mojo_bindings_blink",
@@ -193,6 +196,7 @@ component("core") {
"//third_party/blink/renderer/core/input",
"//third_party/blink/renderer/core/inspector",
"//third_party/blink/renderer/core/intersection_observer",
+ "//third_party/blink/renderer/core/invisible_dom",
"//third_party/blink/renderer/core/layout",
"//third_party/blink/renderer/core/layout/svg:svg_layout",
"//third_party/blink/renderer/core/loader",
@@ -206,6 +210,7 @@ component("core") {
"//third_party/blink/renderer/core/probe",
"//third_party/blink/renderer/core/resize_observer",
"//third_party/blink/renderer/core/script",
+ "//third_party/blink/renderer/core/scroll",
"//third_party/blink/renderer/core/streams",
"//third_party/blink/renderer/core/style:rendering",
"//third_party/blink/renderer/core/style:svg_style",
@@ -273,6 +278,7 @@ jumbo_source_set("testing") {
"testing/dummy_page_holder.h",
"testing/garbage_collected_script_wrappable.cc",
"testing/garbage_collected_script_wrappable.h",
+ "testing/gc_object_liveness_observer.h",
"testing/gc_observation.cc",
"testing/gc_observation.h",
"testing/internal_settings.cc",
@@ -357,6 +363,7 @@ generate_event_interfaces("core_event_interfaces") {
"events/wheel_event.idl",
"html/forms/form_data_event.idl",
"html/track/track_event.idl",
+ "invisible_dom/activate_invisible_event.idl",
"mojo/test/mojo_interface_request_event.idl",
]
output_file = "core/event_names.json5"
@@ -510,6 +517,7 @@ css_properties("make_core_generated_css_longhand_property_classes") {
"../build/scripts/core/css/properties/make_css_property_subclasses.py"
in_files = [ "css/properties/CSSPropertyMethods.json5" ]
other_inputs = [
+ "css/CSSProperties.json5",
"../build/scripts/core/css/properties/templates/css_property_subclass.h.tmpl",
"../build/scripts/core/css/properties/templates/css_property_subclass.cc.tmpl",
]
@@ -553,6 +561,12 @@ css_properties("make_core_generated_css_longhand_property_classes") {
"$blink_core_output_dir/css/properties/longhands/background_size.cc",
"$blink_core_output_dir/css/properties/longhands/baseline_shift.h",
"$blink_core_output_dir/css/properties/longhands/block_size.h",
+ "$blink_core_output_dir/css/properties/longhands/border_block_end_color.h",
+ "$blink_core_output_dir/css/properties/longhands/border_block_end_style.h",
+ "$blink_core_output_dir/css/properties/longhands/border_block_end_width.h",
+ "$blink_core_output_dir/css/properties/longhands/border_block_start_color.h",
+ "$blink_core_output_dir/css/properties/longhands/border_block_start_style.h",
+ "$blink_core_output_dir/css/properties/longhands/border_block_start_width.h",
"$blink_core_output_dir/css/properties/longhands/border_bottom_color.h",
"$blink_core_output_dir/css/properties/longhands/border_bottom_color.cc",
"$blink_core_output_dir/css/properties/longhands/border_bottom_left_radius.h",
@@ -565,6 +579,12 @@ css_properties("make_core_generated_css_longhand_property_classes") {
"$blink_core_output_dir/css/properties/longhands/border_image_slice.h",
"$blink_core_output_dir/css/properties/longhands/border_image_source.h",
"$blink_core_output_dir/css/properties/longhands/border_image_width.h",
+ "$blink_core_output_dir/css/properties/longhands/border_inline_end_color.h",
+ "$blink_core_output_dir/css/properties/longhands/border_inline_end_style.h",
+ "$blink_core_output_dir/css/properties/longhands/border_inline_end_width.h",
+ "$blink_core_output_dir/css/properties/longhands/border_inline_start_color.h",
+ "$blink_core_output_dir/css/properties/longhands/border_inline_start_style.h",
+ "$blink_core_output_dir/css/properties/longhands/border_inline_start_width.h",
"$blink_core_output_dir/css/properties/longhands/border_left_color.h",
"$blink_core_output_dir/css/properties/longhands/border_left_color.cc",
"$blink_core_output_dir/css/properties/longhands/border_left_style.h",
@@ -670,6 +690,10 @@ css_properties("make_core_generated_css_longhand_property_classes") {
"$blink_core_output_dir/css/properties/longhands/image_orientation.h",
"$blink_core_output_dir/css/properties/longhands/image_rendering.h",
"$blink_core_output_dir/css/properties/longhands/inline_size.h",
+ "$blink_core_output_dir/css/properties/longhands/inset_block_end.h",
+ "$blink_core_output_dir/css/properties/longhands/inset_block_start.h",
+ "$blink_core_output_dir/css/properties/longhands/inset_inline_end.h",
+ "$blink_core_output_dir/css/properties/longhands/inset_inline_start.h",
"$blink_core_output_dir/css/properties/longhands/isolation.h",
"$blink_core_output_dir/css/properties/longhands/justify_content.h",
"$blink_core_output_dir/css/properties/longhands/justify_items.h",
@@ -683,7 +707,11 @@ css_properties("make_core_generated_css_longhand_property_classes") {
"$blink_core_output_dir/css/properties/longhands/list_style_image.h",
"$blink_core_output_dir/css/properties/longhands/list_style_position.h",
"$blink_core_output_dir/css/properties/longhands/list_style_type.h",
+ "$blink_core_output_dir/css/properties/longhands/margin_block_start.h",
+ "$blink_core_output_dir/css/properties/longhands/margin_block_end.h",
"$blink_core_output_dir/css/properties/longhands/margin_bottom.h",
+ "$blink_core_output_dir/css/properties/longhands/margin_inline_start.h",
+ "$blink_core_output_dir/css/properties/longhands/margin_inline_end.h",
"$blink_core_output_dir/css/properties/longhands/margin_left.h",
"$blink_core_output_dir/css/properties/longhands/margin_right.h",
"$blink_core_output_dir/css/properties/longhands/margin_top.h",
@@ -727,7 +755,11 @@ css_properties("make_core_generated_css_longhand_property_classes") {
"$blink_core_output_dir/css/properties/longhands/overflow_y.h",
"$blink_core_output_dir/css/properties/longhands/overscroll_behavior_x.h",
"$blink_core_output_dir/css/properties/longhands/overscroll_behavior_y.h",
+ "$blink_core_output_dir/css/properties/longhands/padding_block_start.h",
+ "$blink_core_output_dir/css/properties/longhands/padding_block_end.h",
"$blink_core_output_dir/css/properties/longhands/padding_bottom.h",
+ "$blink_core_output_dir/css/properties/longhands/padding_inline_start.h",
+ "$blink_core_output_dir/css/properties/longhands/padding_inline_end.h",
"$blink_core_output_dir/css/properties/longhands/padding_left.h",
"$blink_core_output_dir/css/properties/longhands/padding_right.h",
"$blink_core_output_dir/css/properties/longhands/padding_top.h",
@@ -992,16 +1024,31 @@ css_properties("make_core_generated_css_shorthand_property_classes") {
script =
"../build/scripts/core/css/properties/make_css_property_subclasses.py"
in_files = [ "css/properties/CSSPropertyMethods.json5" ]
- other_inputs = [ "../build/scripts/core/css/properties/templates/css_property_subclass.h.tmpl" ]
+ other_inputs = [
+ "css/CSSProperties.json5",
+ "../build/scripts/core/css/properties/templates/css_property_subclass.h.tmpl",
+ ]
outputs = [
"$blink_core_output_dir/css/properties/shorthands/animation.h",
"$blink_core_output_dir/css/properties/shorthands/background.h",
"$blink_core_output_dir/css/properties/shorthands/background_position.h",
"$blink_core_output_dir/css/properties/shorthands/background_repeat.h",
"$blink_core_output_dir/css/properties/shorthands/border.h",
+ "$blink_core_output_dir/css/properties/shorthands/border_block.h",
+ "$blink_core_output_dir/css/properties/shorthands/border_block_color.h",
+ "$blink_core_output_dir/css/properties/shorthands/border_block_end.h",
+ "$blink_core_output_dir/css/properties/shorthands/border_block_start.h",
+ "$blink_core_output_dir/css/properties/shorthands/border_block_style.h",
+ "$blink_core_output_dir/css/properties/shorthands/border_block_width.h",
"$blink_core_output_dir/css/properties/shorthands/border_bottom.h",
"$blink_core_output_dir/css/properties/shorthands/border_color.h",
"$blink_core_output_dir/css/properties/shorthands/border_image.h",
+ "$blink_core_output_dir/css/properties/shorthands/border_inline.h",
+ "$blink_core_output_dir/css/properties/shorthands/border_inline_color.h",
+ "$blink_core_output_dir/css/properties/shorthands/border_inline_end.h",
+ "$blink_core_output_dir/css/properties/shorthands/border_inline_start.h",
+ "$blink_core_output_dir/css/properties/shorthands/border_inline_style.h",
+ "$blink_core_output_dir/css/properties/shorthands/border_inline_width.h",
"$blink_core_output_dir/css/properties/shorthands/border_left.h",
"$blink_core_output_dir/css/properties/shorthands/border_radius.h",
"$blink_core_output_dir/css/properties/shorthands/border_right.h",
@@ -1025,14 +1072,21 @@ css_properties("make_core_generated_css_shorthand_property_classes") {
"$blink_core_output_dir/css/properties/shorthands/grid_gap.h",
"$blink_core_output_dir/css/properties/shorthands/grid_row.h",
"$blink_core_output_dir/css/properties/shorthands/grid_template.h",
+ "$blink_core_output_dir/css/properties/shorthands/inset.h",
+ "$blink_core_output_dir/css/properties/shorthands/inset_block.h",
+ "$blink_core_output_dir/css/properties/shorthands/inset_inline.h",
"$blink_core_output_dir/css/properties/shorthands/list_style.h",
"$blink_core_output_dir/css/properties/shorthands/margin.h",
+ "$blink_core_output_dir/css/properties/shorthands/margin_block.h",
+ "$blink_core_output_dir/css/properties/shorthands/margin_inline.h",
"$blink_core_output_dir/css/properties/shorthands/marker.h",
"$blink_core_output_dir/css/properties/shorthands/offset.h",
"$blink_core_output_dir/css/properties/shorthands/outline.h",
"$blink_core_output_dir/css/properties/shorthands/overflow.h",
"$blink_core_output_dir/css/properties/shorthands/overscroll_behavior.h",
"$blink_core_output_dir/css/properties/shorthands/padding.h",
+ "$blink_core_output_dir/css/properties/shorthands/padding_block.h",
+ "$blink_core_output_dir/css/properties/shorthands/padding_inline.h",
"$blink_core_output_dir/css/properties/shorthands/page_break_after.h",
"$blink_core_output_dir/css/properties/shorthands/page_break_before.h",
"$blink_core_output_dir/css/properties/shorthands/page_break_inside.h",
@@ -1273,6 +1327,11 @@ make_names("make_core_generated_input_mode_names") {
output_dir = blink_core_output_dir
}
+make_names("make_core_generated_performance_entry_names") {
+ in_files = [ "timing/performance_entry_names.json5" ]
+ output_dir = blink_core_output_dir
+}
+
# make_qualified_names ---------------------------------------------------------
make_qualified_names("make_core_generated_math_ml_names") {
@@ -1533,6 +1592,7 @@ targets_generating_sources = [
":make_core_generated_math_ml_names",
":make_core_generated_media_feature_names",
":make_core_generated_media_type_names",
+ ":make_core_generated_performance_entry_names",
":make_core_generated_origin_trials",
":make_core_generated_style_property_shorthand",
":make_core_generated_svg_names",
@@ -1639,6 +1699,7 @@ jumbo_source_set("unit_tests") {
"animation/animation_test.cc",
"animation/animation_test_helper.cc",
"animation/animation_test_helper.h",
+ "animation/animation_time_delta_test.cc",
"animation/compositor_animations_test.cc",
"animation/css/css_animations_test.cc",
"animation/css/css_transition_data_test.cc",
@@ -1704,7 +1765,6 @@ jumbo_source_set("unit_tests") {
"css/resolver/font_builder_test.cc",
"css/resolver/font_style_resolver_test.cc",
"css/resolver/match_result_test.cc",
- "css/resolver/scoped_style_resolver_test.cc",
"css/resolver/style_adjuster_test.cc",
"css/rule_feature_set_test.cc",
"css/rule_set_test.cc",
@@ -1728,7 +1788,6 @@ jumbo_source_set("unit_tests") {
"dom/events/event_target_test.cc",
"dom/events/listener_leak_test.cc",
"dom/first_letter_pseudo_element_test.cc",
- "dom/flat_tree_traversal_ng_test.cc",
"dom/flat_tree_traversal_test.cc",
"dom/idle_deadline_test.cc",
"dom/layout_tree_builder_traversal_test.cc",
@@ -1821,6 +1880,7 @@ jumbo_source_set("unit_tests") {
"frame/rotation_viewport_anchor_test.cc",
"frame/use_counter_test.cc",
"frame/visual_viewport_test.cc",
+ "fullscreen/scoped_allow_fullscreen_test.cc",
"geometry/dom_matrix_test.cc",
"html/anchor_element_metrics_test.cc",
"html/canvas/canvas_async_blob_creator_test.cc",
@@ -1853,6 +1913,7 @@ jumbo_source_set("unit_tests") {
"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",
@@ -1878,7 +1939,6 @@ jumbo_source_set("unit_tests") {
"html/media_element_filling_viewport_test.cc",
"html/parser/atomic_html_token_test.cc",
"html/parser/compact_html_token_test.cc",
- "html/parser/css_preload_scanner_test.cc",
"html/parser/html_document_parser_loading_test.cc",
"html/parser/html_document_parser_test.cc",
"html/parser/html_entity_parser_test.cc",
@@ -1903,12 +1963,14 @@ jumbo_source_set("unit_tests") {
"input/scroll_snap_test.cc",
"input/touch_action_test.cc",
"input/touch_event_manager_test.cc",
+ "inspector/inspector_session_state_test.cc",
"inspector/main_thread_debugger_test.cc",
"inspector/protocol_parser_test.cc",
"intersection_observer/intersection_observer_test.cc",
"layout/api/selection_state_test.cc",
"layout/collapsed_border_value_test.cc",
"layout/custom/layout_worklet_test.cc",
+ "layout/grid_test.cc",
"layout/jank_tracker_test.cc",
"layout/layout_block_test.cc",
"layout/layout_box_model_object_test.cc",
@@ -1982,16 +2044,17 @@ jumbo_source_set("unit_tests") {
"loader/base_fetch_context_test.cc",
"loader/document_load_timing_test.cc",
"loader/document_loader_test.cc",
- "loader/document_threadable_loader_test.cc",
"loader/frame_fetch_context_test.cc",
"loader/idleness_detector_test.cc",
"loader/interactive_detector_test.cc",
"loader/link_loader_test.cc",
+ "loader/long_task_detector_test.cc",
"loader/mixed_content_checker_test.cc",
"loader/modulescript/module_script_loader_test.cc",
"loader/modulescript/module_tree_linker_test.cc",
"loader/navigation_policy_test.cc",
"loader/ping_loader_test.cc",
+ "loader/previews_resource_loading_hints_test.cc",
"loader/programmatic_scroll_test.cc",
"loader/progress_tracker_test.cc",
"loader/resource/css_style_sheet_resource_test.cc",
@@ -2079,7 +2142,10 @@ jumbo_source_set("unit_tests") {
"script/module_map_test.cc",
"script/script_module_resolver_impl_test.cc",
"script/script_runner_test.cc",
+ "scroll/scrollable_area_test.cc",
+ "scroll/scrollbar_theme_overlay_test.cc",
"streams/readable_stream_operations_test.cc",
+ "streams/transform_stream_test.cc",
"style/border_value_test.cc",
"style/computed_style_test.cc",
"style/filter_operations_test.cc",
@@ -2110,6 +2176,7 @@ jumbo_source_set("unit_tests") {
"timing/performance_observer_test.cc",
"timing/performance_resource_timing_test.cc",
"timing/performance_test.cc",
+ "timing/time_clamper_test.cc",
"timing/window_performance_test.cc",
"url/url_search_params_test.cc",
"workers/dedicated_worker_test.cc",
@@ -2144,6 +2211,18 @@ jumbo_source_set("unit_tests") {
if (!is_android) {
deps += [ "//third_party/blink/renderer/core/mojo:unit_tests" ]
}
+
+ if (!is_mac) {
+ sources += [ "scroll/scroll_animator_test.cc" ]
+ }
+
+ if (use_default_render_theme) {
+ sources += [ "scroll/scrollbar_theme_aura_test.cc" ]
+ }
+
+ if (blink_animation_use_time_delta) {
+ defines = [ "BLINK_ANIMATION_USE_TIME_DELTA" ]
+ }
}
jumbo_source_set("perf_tests") {
diff --git a/chromium/third_party/blink/renderer/core/DEPS b/chromium/third_party/blink/renderer/core/DEPS
index 0b8a51e8598..03e5d763244 100644
--- a/chromium/third_party/blink/renderer/core/DEPS
+++ b/chromium/third_party/blink/renderer/core/DEPS
@@ -1,15 +1,23 @@
include_rules = [
"+base/atomic_sequence_num.h",
+ "+base/files/file.h",
"+base/memory/scoped_refptr.h",
"+base/synchronization/waitable_event.h",
"+base/task/sequence_manager/task_time_observer.h",
"+base/unguessable_token.h",
"+build/mac",
"+build/win",
+ "+cc/animation/animation_curve.h",
+ "+cc/animation/scroll_offset_animations.h",
+ "+cc/animation/scroll_offset_animation_curve.h",
+ "+cc/animation/scroll_state.h",
"+cc/base/region.h",
"+cc/input/browser_controls_state.h",
"+cc/input/event_listener_properties.h",
+ "+cc/input/layer_selection_bound.h",
"+cc/input/overscroll_behavior.h",
+ "+cc/input/scrollbar.h",
+ "+cc/input/scroll_state.h",
"+cc/layers/content_layer_client.h",
"+cc/layers/layer.h",
"+cc/layers/layer_position_constraint.h",
@@ -32,8 +40,9 @@ include_rules = [
"+services/network/public/mojom",
"+services/resource_coordinator/public/cpp/resource_coordinator_features.h",
"+services/service_manager/public",
- "+services/ui/public/interfaces/ime/ime.mojom-shared.h",
+ "+services/ws/public/mojom/ime/ime.mojom-shared.h",
"+skia/public/interfaces/bitmap_skbitmap_struct_traits.h",
+ "+skia/ext/skia_utils_mac.h",
"+third_party/blink/public/common",
"+third_party/blink/public/mojom",
"+third_party/blink/public/public_buildflags.h",
@@ -44,6 +53,7 @@ include_rules = [
"-third_party/blink/renderer/modules",
"+third_party/skia/include",
"+ui/gfx/geometry",
+ "+ui/gfx/skia_util.h",
"-web",
# We do not want any new dependencies into core/exported until we resolve
# controller layer.
@@ -57,6 +67,7 @@ include_rules = [
specific_include_rules = {
# Additional allowed includes for tests.
".*_test(_.*)?\.(cc|h)" : [
+ "+base/message_loop/message_loop.h",
# Test harness may use cc directly instead of going through WebViewImpl etc.
"+cc",
# TODO(crbug.com/838693): Test harnesses use LayerTreeView
diff --git a/chromium/third_party/blink/renderer/core/OWNERS b/chromium/third_party/blink/renderer/core/OWNERS
index cad509d87b5..995cd607f52 100644
--- a/chromium/third_party/blink/renderer/core/OWNERS
+++ b/chromium/third_party/blink/renderer/core/OWNERS
@@ -60,7 +60,6 @@ rob.buis@samsung.com
robhogan@gmail.com
schenney@chromium.org
senorblanco@chromium.org
-sashab@chromium.org
skobes@chromium.org
svillar@igalia.com
szager@chromium.org
diff --git a/chromium/third_party/blink/renderer/core/accessibility/BUILD.gn b/chromium/third_party/blink/renderer/core/accessibility/BUILD.gn
index 285ef59c189..dbff6a41a1a 100644
--- a/chromium/third_party/blink/renderer/core/accessibility/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/accessibility/BUILD.gn
@@ -6,6 +6,8 @@ import("//third_party/blink/renderer/core/core.gni")
blink_core_sources("accessibility") {
sources = [
+ "ax_context.cc",
+ "ax_context.h",
"ax_object_cache.cc",
"ax_object_cache.h",
"ax_object_cache_base.cc",
diff --git a/chromium/third_party/blink/renderer/core/accessibility/ax_context.cc b/chromium/third_party/blink/renderer/core/accessibility/ax_context.cc
new file mode 100644
index 00000000000..0e8ea630b43
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/accessibility/ax_context.cc
@@ -0,0 +1,28 @@
+// 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/accessibility/ax_context.h"
+#include "third_party/blink/renderer/core/dom/document.h"
+
+namespace blink {
+
+class AXObjectCache;
+
+AXContext::AXContext(Document& document) : document_(&document) {
+ DCHECK(document_);
+ document_->AddAXContext(this);
+}
+
+AXContext::~AXContext() {
+ if (document_)
+ document_->RemoveAXContext(this);
+}
+
+AXObjectCache& AXContext::GetAXObjectCache() {
+ DCHECK(document_);
+ DCHECK(document_->IsActive());
+ return *document_->ExistingAXObjectCache();
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/accessibility/ax_context.h b/chromium/third_party/blink/renderer/core/accessibility/ax_context.h
new file mode 100644
index 00000000000..48606e00700
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/accessibility/ax_context.h
@@ -0,0 +1,38 @@
+// 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_ACCESSIBILITY_AX_CONTEXT_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_ACCESSIBILITY_AX_CONTEXT_H_
+
+#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/platform/heap/persistent.h"
+
+namespace blink {
+
+class AXObjectCache;
+
+// An AXContext enables accessibility support in a Document for as
+// long as the AXContext is alive. While the AXContext exists,
+// Document::ExistingAXObjectCache will always return a valid
+// AXObjectCache if the document is still active.
+class CORE_EXPORT AXContext {
+ public:
+ explicit AXContext(Document& document);
+ virtual ~AXContext();
+
+ // Note: it's an error to call this after |document| is no longer active.
+ // The caller should check this.
+ AXObjectCache& GetAXObjectCache();
+
+ protected:
+ WeakPersistent<Document> document_;
+
+ DISALLOW_COPY_AND_ASSIGN(AXContext);
+};
+
+} // namespace blink
+
+#endif
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 210f4af6a8d..8910b9bfed6 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
@@ -60,30 +60,6 @@ AXObjectCache::AXObjectCache(Document& document)
AXObjectCache::~AXObjectCache() = default;
-std::unique_ptr<ScopedAXObjectCache> ScopedAXObjectCache::Create(
- Document& document) {
- return base::WrapUnique(new ScopedAXObjectCache(document));
-}
-
-ScopedAXObjectCache::ScopedAXObjectCache(Document& document)
- : document_(&document) {
- if (!document_->GetOrCreateAXObjectCache())
- cache_ = AXObjectCache::Create(*document_);
-}
-
-ScopedAXObjectCache::~ScopedAXObjectCache() {
- if (cache_)
- cache_->Dispose();
-}
-
-AXObjectCache* ScopedAXObjectCache::Get() {
- if (cache_)
- return cache_.Get();
- AXObjectCache* cache = document_->GetOrCreateAXObjectCache();
- DCHECK(cache);
- return cache;
-}
-
namespace {
typedef HashSet<String, CaseFoldingHash> ARIAWidgetSet;
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 b651d3867d1..3c5dc9622c0 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
@@ -102,6 +102,7 @@ class CORE_EXPORT AXObjectCache
virtual void HandleLoadComplete(Document*) = 0;
virtual void HandleLayoutComplete(Document*) = 0;
virtual void HandleClicked(Node*) = 0;
+ virtual void HandleAutofillStateChanged(Element*, bool) = 0;
// Changes to virtual Accessibility Object Model nodes.
virtual void HandleAttributeChanged(const QualifiedName& attr_name,
@@ -143,23 +144,6 @@ class CORE_EXPORT AXObjectCache
DISALLOW_COPY_AND_ASSIGN(AXObjectCache);
};
-class CORE_EXPORT ScopedAXObjectCache {
- USING_FAST_MALLOC(ScopedAXObjectCache);
-
- public:
- static std::unique_ptr<ScopedAXObjectCache> Create(Document&);
- ~ScopedAXObjectCache();
-
- AXObjectCache* Get();
-
- private:
- explicit ScopedAXObjectCache(Document&);
-
- Persistent<Document> document_;
- Persistent<AXObjectCache> cache_;
- DISALLOW_COPY_AND_ASSIGN(ScopedAXObjectCache);
-};
-
} // namespace blink
#endif
diff --git a/chromium/third_party/blink/renderer/core/animation/BUILD.gn b/chromium/third_party/blink/renderer/core/animation/BUILD.gn
index 79d77d4ffcf..53c2402d6f2 100644
--- a/chromium/third_party/blink/renderer/core/animation/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/animation/BUILD.gn
@@ -25,6 +25,8 @@ blink_core_sources("animation") {
"animation_effect_owner.h",
"animation_input_helpers.cc",
"animation_input_helpers.h",
+ "animation_time_delta.cc",
+ "animation_time_delta.h",
"animation_timeline.h",
"basic_shape_interpolation_functions.cc",
"basic_shape_interpolation_functions.h",
diff --git a/chromium/third_party/blink/renderer/core/animation/animatable/animatable_double.cc b/chromium/third_party/blink/renderer/core/animation/animatable/animatable_double.cc
index ee20c9301f6..a06df5ca9bf 100644
--- a/chromium/third_party/blink/renderer/core/animation/animatable/animatable_double.cc
+++ b/chromium/third_party/blink/renderer/core/animation/animatable/animatable_double.cc
@@ -35,9 +35,8 @@
namespace blink {
-scoped_refptr<AnimatableValue> AnimatableDouble::InterpolateTo(
- const AnimatableValue* value,
- double fraction) const {
+AnimatableValue* AnimatableDouble::InterpolateTo(const AnimatableValue* value,
+ double fraction) const {
const AnimatableDouble* other = ToAnimatableDouble(value);
return AnimatableDouble::Create(Blend(number_, other->number_, fraction));
}
diff --git a/chromium/third_party/blink/renderer/core/animation/animatable/animatable_double.h b/chromium/third_party/blink/renderer/core/animation/animatable/animatable_double.h
index 1f9bee6cb19..aba5ff02ad4 100644
--- a/chromium/third_party/blink/renderer/core/animation/animatable/animatable_double.h
+++ b/chromium/third_party/blink/renderer/core/animation/animatable/animatable_double.h
@@ -40,15 +40,15 @@ class CORE_EXPORT AnimatableDouble final : public AnimatableValue {
public:
~AnimatableDouble() override = default;
- static scoped_refptr<AnimatableDouble> Create(double number) {
- return base::AdoptRef(new AnimatableDouble(number));
+ static AnimatableDouble* Create(double number) {
+ return new AnimatableDouble(number);
}
double ToDouble() const { return number_; }
protected:
- scoped_refptr<AnimatableValue> InterpolateTo(const AnimatableValue*,
- double fraction) const override;
+ AnimatableValue* InterpolateTo(const AnimatableValue*,
+ double fraction) const override;
private:
AnimatableDouble(double number) : number_(number) {}
diff --git a/chromium/third_party/blink/renderer/core/animation/animatable/animatable_filter_operations.cc b/chromium/third_party/blink/renderer/core/animation/animatable/animatable_filter_operations.cc
index 7a24d68a712..41b5f4232da 100644
--- a/chromium/third_party/blink/renderer/core/animation/animatable/animatable_filter_operations.cc
+++ b/chromium/third_party/blink/renderer/core/animation/animatable/animatable_filter_operations.cc
@@ -34,7 +34,7 @@
namespace blink {
-scoped_refptr<AnimatableValue> AnimatableFilterOperations::InterpolateTo(
+AnimatableValue* AnimatableFilterOperations::InterpolateTo(
const AnimatableValue* value,
double fraction) const {
const AnimatableFilterOperations* target =
@@ -64,4 +64,9 @@ scoped_refptr<AnimatableValue> AnimatableFilterOperations::InterpolateTo(
return AnimatableFilterOperations::Create(result);
}
+void AnimatableFilterOperations::Trace(Visitor* visitor) {
+ visitor->Trace(operation_wrapper_);
+ AnimatableValue::Trace(visitor);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/animation/animatable/animatable_filter_operations.h b/chromium/third_party/blink/renderer/core/animation/animatable/animatable_filter_operations.h
index ce012b81720..766d1e13e1a 100644
--- a/chromium/third_party/blink/renderer/core/animation/animatable/animatable_filter_operations.h
+++ b/chromium/third_party/blink/renderer/core/animation/animatable/animatable_filter_operations.h
@@ -38,9 +38,9 @@ namespace blink {
class AnimatableFilterOperations final : public AnimatableValue {
public:
- static scoped_refptr<AnimatableFilterOperations> Create(
+ static AnimatableFilterOperations* Create(
const FilterOperations& operations) {
- return base::AdoptRef(new AnimatableFilterOperations(operations));
+ return new AnimatableFilterOperations(operations);
}
~AnimatableFilterOperations() override = default;
@@ -49,9 +49,11 @@ class AnimatableFilterOperations final : public AnimatableValue {
return operation_wrapper_->Operations();
}
+ void Trace(Visitor*) override;
+
protected:
- scoped_refptr<AnimatableValue> InterpolateTo(const AnimatableValue*,
- double fraction) const override;
+ AnimatableValue* InterpolateTo(const AnimatableValue*,
+ double fraction) const override;
private:
AnimatableFilterOperations(const FilterOperations& operations)
@@ -59,7 +61,7 @@ class AnimatableFilterOperations final : public AnimatableValue {
AnimatableType GetType() const override { return kTypeFilterOperations; }
- Persistent<FilterOperationsWrapper> operation_wrapper_;
+ Member<FilterOperationsWrapper> operation_wrapper_;
};
DEFINE_ANIMATABLE_VALUE_TYPE_CASTS(AnimatableFilterOperations,
diff --git a/chromium/third_party/blink/renderer/core/animation/animatable/animatable_transform.cc b/chromium/third_party/blink/renderer/core/animation/animatable/animatable_transform.cc
index 04e5c4ef84c..247a8acd7e2 100644
--- a/chromium/third_party/blink/renderer/core/animation/animatable/animatable_transform.cc
+++ b/chromium/third_party/blink/renderer/core/animation/animatable/animatable_transform.cc
@@ -34,7 +34,7 @@
namespace blink {
-scoped_refptr<AnimatableValue> AnimatableTransform::InterpolateTo(
+AnimatableValue* AnimatableTransform::InterpolateTo(
const AnimatableValue* value,
double fraction) const {
const AnimatableTransform& transform = ToAnimatableTransform(*value);
diff --git a/chromium/third_party/blink/renderer/core/animation/animatable/animatable_transform.h b/chromium/third_party/blink/renderer/core/animation/animatable/animatable_transform.h
index 6a40d6f9a4a..10842bf4e4c 100644
--- a/chromium/third_party/blink/renderer/core/animation/animatable/animatable_transform.h
+++ b/chromium/third_party/blink/renderer/core/animation/animatable/animatable_transform.h
@@ -40,10 +40,9 @@ namespace blink {
class CORE_EXPORT AnimatableTransform final : public AnimatableValue {
public:
~AnimatableTransform() override = default;
- static scoped_refptr<AnimatableTransform> Create(
- const TransformOperations& transform,
- double zoom) {
- return base::AdoptRef(new AnimatableTransform(transform, zoom));
+ static AnimatableTransform* Create(const TransformOperations& transform,
+ double zoom) {
+ return new AnimatableTransform(transform, zoom);
}
const TransformOperations& GetTransformOperations() const {
return transform_;
@@ -51,8 +50,8 @@ class CORE_EXPORT AnimatableTransform final : public AnimatableValue {
double Zoom() const { return zoom_; }
protected:
- scoped_refptr<AnimatableValue> InterpolateTo(const AnimatableValue*,
- double fraction) const override;
+ AnimatableValue* InterpolateTo(const AnimatableValue*,
+ double fraction) const override;
private:
explicit AnimatableTransform(const TransformOperations& transform,
diff --git a/chromium/third_party/blink/renderer/core/animation/animatable/animatable_value.cc b/chromium/third_party/blink/renderer/core/animation/animatable/animatable_value.cc
index 5502d297838..322b1e41dc0 100644
--- a/chromium/third_party/blink/renderer/core/animation/animatable/animatable_value.cc
+++ b/chromium/third_party/blink/renderer/core/animation/animatable/animatable_value.cc
@@ -35,10 +35,9 @@
namespace blink {
-scoped_refptr<AnimatableValue> AnimatableValue::Interpolate(
- const AnimatableValue* left,
- const AnimatableValue* right,
- double fraction) {
+AnimatableValue* AnimatableValue::Interpolate(const AnimatableValue* left,
+ const AnimatableValue* right,
+ double fraction) {
DCHECK(left);
DCHECK(right);
diff --git a/chromium/third_party/blink/renderer/core/animation/animatable/animatable_value.h b/chromium/third_party/blink/renderer/core/animation/animatable/animatable_value.h
index a76a1889117..6d62f1cf45b 100644
--- a/chromium/third_party/blink/renderer/core/animation/animatable/animatable_value.h
+++ b/chromium/third_party/blink/renderer/core/animation/animatable/animatable_value.h
@@ -34,17 +34,17 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/css/css_value.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/wtf/ref_counted.h"
namespace blink {
-class CORE_EXPORT AnimatableValue : public RefCounted<AnimatableValue> {
+class CORE_EXPORT AnimatableValue
+ : public GarbageCollectedFinalized<AnimatableValue> {
public:
virtual ~AnimatableValue() = default;
- static scoped_refptr<AnimatableValue> Interpolate(const AnimatableValue*,
- const AnimatableValue*,
- double fraction);
+ static AnimatableValue* Interpolate(const AnimatableValue*,
+ const AnimatableValue*,
+ double fraction);
bool IsDouble() const { return GetType() == kTypeDouble; }
bool IsFilterOperations() const { return GetType() == kTypeFilterOperations; }
bool IsTransform() const { return GetType() == kTypeTransform; }
@@ -55,6 +55,8 @@ class CORE_EXPORT AnimatableValue : public RefCounted<AnimatableValue> {
return value->GetType() == GetType();
}
+ virtual void Trace(Visitor*) {}
+
protected:
enum AnimatableType {
kTypeDouble,
@@ -63,21 +65,15 @@ class CORE_EXPORT AnimatableValue : public RefCounted<AnimatableValue> {
kTypeUnknown,
};
- virtual scoped_refptr<AnimatableValue> InterpolateTo(const AnimatableValue*,
- double fraction) const {
+ virtual AnimatableValue* InterpolateTo(const AnimatableValue*,
+ double fraction) const {
NOTREACHED();
return nullptr;
}
- static scoped_refptr<AnimatableValue> DefaultInterpolateTo(
- const AnimatableValue* left,
- const AnimatableValue* right,
- double fraction) {
- return TakeConstRef((fraction < 0.5) ? left : right);
- }
-
- template <class T>
- static scoped_refptr<T> TakeConstRef(const T* value) {
- return scoped_refptr<T>(const_cast<T*>(value));
+ static AnimatableValue* DefaultInterpolateTo(const AnimatableValue* left,
+ const AnimatableValue* right,
+ double fraction) {
+ return const_cast<AnimatableValue*>((fraction < 0.5) ? left : right);
}
private:
diff --git a/chromium/third_party/blink/renderer/core/animation/animation.cc b/chromium/third_party/blink/renderer/core/animation/animation.cc
index 9dcdf4402b8..0d5538ef6ea 100644
--- a/chromium/third_party/blink/renderer/core/animation/animation.cc
+++ b/chromium/third_party/blink/renderer/core/animation/animation.cc
@@ -728,8 +728,8 @@ void Animation::ContextDestroyed(ExecutionContext*) {
pending_finished_event_ = nullptr;
}
-DispatchEventResult Animation::DispatchEventInternal(Event* event) {
- if (pending_finished_event_ == event)
+DispatchEventResult Animation::DispatchEventInternal(Event& event) {
+ if (pending_finished_event_ == &event)
pending_finished_event_ = nullptr;
return EventTargetWithInlineData::DispatchEventInternal(event);
}
@@ -797,18 +797,17 @@ CompositorAnimations::FailureCode Animation::CheckCanStartAnimationOnCompositor(
const base::Optional<CompositorElementIdSet>& composited_element_ids)
const {
CompositorAnimations::FailureCode code =
- CheckCanStartAnimationOnCompositorInternal(composited_element_ids);
+ CheckCanStartAnimationOnCompositorInternal();
if (!code.Ok()) {
return code;
}
return ToKeyframeEffect(content_.Get())
- ->CheckCanStartAnimationOnCompositor(playback_rate_);
+ ->CheckCanStartAnimationOnCompositor(composited_element_ids,
+ playback_rate_);
}
CompositorAnimations::FailureCode
-Animation::CheckCanStartAnimationOnCompositorInternal(
- const base::Optional<CompositorElementIdSet>& composited_element_ids)
- const {
+Animation::CheckCanStartAnimationOnCompositorInternal() const {
if (is_composited_animation_disabled_for_testing_) {
return CompositorAnimations::FailureCode::NonActionable(
"Accelerated animations disabled for testing");
@@ -849,35 +848,6 @@ Animation::CheckCanStartAnimationOnCompositorInternal(
"Animation effect is not keyframe-based");
}
- // If the optional element id set has no value we must be in SPv1 mode in
- // which case we trust the compositing logic will create a layer if needed.
- if (composited_element_ids) {
- DCHECK(RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled() ||
- RuntimeEnabledFeatures::SlimmingPaintV2Enabled());
- Element* target_element = ToKeyframeEffect(content_.Get())->target();
- if (!target_element) {
- return CompositorAnimations::FailureCode::Actionable(
- "Animation is not attached to an element");
- }
-
- bool has_own_layer_id = false;
- if (target_element->GetLayoutObject() &&
- target_element->GetLayoutObject()->IsBoxModelObject() &&
- target_element->GetLayoutObject()->HasLayer()) {
- CompositorElementId target_element_id =
- CompositorElementIdFromUniqueObjectId(
- target_element->GetLayoutObject()->UniqueId(),
- CompositorElementIdNamespace::kPrimary);
- if (composited_element_ids->Contains(target_element_id)) {
- has_own_layer_id = true;
- }
- }
- if (!has_own_layer_id) {
- return CompositorAnimations::FailureCode::NonActionable(
- "Target element does not have its own compositing layer");
- }
- }
-
if (!Playing()) {
return CompositorAnimations::FailureCode::Actionable(
"Animation is not playing");
@@ -907,6 +877,7 @@ void Animation::StartAnimationOnCompositor(
DCHECK(!start_time || !IsNull(start_time.value()));
DCHECK_NE(compositor_group_, 0);
+ DCHECK(ToKeyframeEffect(content_.Get()));
ToKeyframeEffect(content_.Get())
->StartAnimationOnCompositor(compositor_group_, start_time, time_offset,
playback_rate_);
diff --git a/chromium/third_party/blink/renderer/core/animation/animation.h b/chromium/third_party/blink/renderer/core/animation/animation.h
index 1bbb016bcb8..8aa2047cd1a 100644
--- a/chromium/third_party/blink/renderer/core/animation/animation.h
+++ b/chromium/third_party/blink/renderer/core/animation/animation.h
@@ -228,7 +228,7 @@ class CORE_EXPORT Animation final : public EventTargetWithInlineData,
bool CompositorPendingForTesting() const { return compositor_pending_; }
protected:
- DispatchEventResult DispatchEventInternal(Event*) override;
+ DispatchEventResult DispatchEventInternal(Event&) override;
void AddedEventListener(const AtomicString& event_type,
RegisteredEventListener&) override;
@@ -253,8 +253,8 @@ class CORE_EXPORT Animation final : public EventTargetWithInlineData,
void BeginUpdatingState();
void EndUpdatingState();
- CompositorAnimations::FailureCode CheckCanStartAnimationOnCompositorInternal(
- const base::Optional<CompositorElementIdSet>&) const;
+ CompositorAnimations::FailureCode CheckCanStartAnimationOnCompositorInternal()
+ const;
void CreateCompositorAnimation();
void DestroyCompositorAnimation();
void AttachCompositorTimeline();
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 56acf864e0b..92760ef3c4b 100644
--- a/chromium/third_party/blink/renderer/core/animation/animation_effect.cc
+++ b/chromium/third_party/blink/renderer/core/animation/animation_effect.cc
@@ -79,20 +79,11 @@ double AnimationEffect::RepeatedDuration() const {
return result;
}
-double AnimationEffect::ActiveDurationInternal() const {
- const double result =
- timing_.playback_rate
- ? RepeatedDuration() / std::abs(timing_.playback_rate)
- : std::numeric_limits<double>::infinity();
- DCHECK_GE(result, 0);
- return result;
-}
-
double AnimationEffect::EndTimeInternal() const {
// Per the spec, the end time has a lower bound of 0.0:
// https://drafts.csswg.org/web-animations-1/#end-time
- return std::max(
- timing_.start_delay + ActiveDurationInternal() + timing_.end_delay, 0.0);
+ return std::max(timing_.start_delay + RepeatedDuration() + timing_.end_delay,
+ 0.0);
}
void AnimationEffect::UpdateSpecifiedTiming(const Timing& timing) {
@@ -129,7 +120,7 @@ void AnimationEffect::getComputedTiming(
ComputedEffectTiming& computed_timing) const {
// ComputedEffectTiming members.
computed_timing.setEndTime(EndTimeInternal() * 1000);
- computed_timing.setActiveDuration(ActiveDurationInternal() * 1000);
+ computed_timing.setActiveDuration(RepeatedDuration() * 1000);
if (IsNull(EnsureCalculated().local_time)) {
computed_timing.setLocalTimeToNull();
@@ -193,7 +184,7 @@ void AnimationEffect::UpdateInheritedTime(double inherited_time,
const double local_time = inherited_time;
double time_to_next_iteration = std::numeric_limits<double>::infinity();
if (needs_update) {
- const double active_duration = this->ActiveDurationInternal();
+ const double active_duration = RepeatedDuration();
const Phase current_phase =
CalculatePhase(active_duration, local_time, timing_);
@@ -210,14 +201,14 @@ void AnimationEffect::UpdateInheritedTime(double inherited_time,
const double start_offset = MultiplyZeroAlwaysGivesZero(
timing_.iteration_start, iteration_duration);
DCHECK_GE(start_offset, 0);
- const double scaled_active_time = CalculateScaledActiveTime(
- active_duration, active_time, start_offset, timing_);
+ const double offset_active_time =
+ CalculateOffsetActiveTime(active_duration, active_time, start_offset);
const double iteration_time = CalculateIterationTime(
- iteration_duration, RepeatedDuration(), scaled_active_time,
- start_offset, current_phase, timing_);
+ iteration_duration, active_duration, offset_active_time, start_offset,
+ current_phase, timing_);
current_iteration = CalculateCurrentIteration(
- iteration_duration, iteration_time, scaled_active_time, timing_);
+ iteration_duration, iteration_time, offset_active_time, timing_);
const base::Optional<double> transformed_time = CalculateTransformedTime(
current_iteration, iteration_duration, iteration_time, timing_);
@@ -231,20 +222,14 @@ void AnimationEffect::UpdateInheritedTime(double inherited_time,
progress = transformed_time.value() / iteration_duration;
if (!IsNull(iteration_time)) {
- time_to_next_iteration = (iteration_duration - iteration_time) /
- std::abs(timing_.playback_rate);
+ time_to_next_iteration = iteration_duration - iteration_time;
if (active_duration - active_time < time_to_next_iteration)
time_to_next_iteration = std::numeric_limits<double>::infinity();
}
} else {
const double kLocalIterationDuration = 1;
- const double local_repeated_duration =
- kLocalIterationDuration * timing_.iteration_count;
- DCHECK_GE(local_repeated_duration, 0);
const double local_active_duration =
- timing_.playback_rate
- ? local_repeated_duration / std::abs(timing_.playback_rate)
- : std::numeric_limits<double>::infinity();
+ kLocalIterationDuration * timing_.iteration_count;
DCHECK_GE(local_active_duration, 0);
const double local_local_time =
local_time < timing_.start_delay
@@ -259,14 +244,14 @@ void AnimationEffect::UpdateInheritedTime(double inherited_time,
const double start_offset =
timing_.iteration_start * kLocalIterationDuration;
DCHECK_GE(start_offset, 0);
- const double scaled_active_time = CalculateScaledActiveTime(
- local_active_duration, local_active_time, start_offset, timing_);
+ const double offset_active_time = CalculateOffsetActiveTime(
+ local_active_duration, local_active_time, start_offset);
const double iteration_time = CalculateIterationTime(
- kLocalIterationDuration, local_repeated_duration, scaled_active_time,
+ kLocalIterationDuration, local_active_duration, offset_active_time,
start_offset, current_phase, timing_);
current_iteration = CalculateCurrentIteration(
- kLocalIterationDuration, iteration_time, scaled_active_time, timing_);
+ kLocalIterationDuration, iteration_time, offset_active_time, timing_);
progress = CalculateTransformedTime(
current_iteration, kLocalIterationDuration, iteration_time, timing_);
}
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 c2c2842f9e2..d90030ebdc9 100644
--- a/chromium/third_party/blink/renderer/core/animation/animation_effect.h
+++ b/chromium/third_party/blink/renderer/core/animation/animation_effect.h
@@ -113,7 +113,7 @@ class CORE_EXPORT AnimationEffect : public ScriptWrappable {
}
double IterationDuration() const;
- double ActiveDurationInternal() const;
+ double RepeatedDuration() const;
double EndTimeInternal() const;
const Timing& SpecifiedTiming() const { return timing_; }
@@ -152,8 +152,6 @@ class CORE_EXPORT AnimationEffect : public ScriptWrappable {
}
void ClearEventDelegate() { event_delegate_ = nullptr; }
- double RepeatedDuration() const;
-
virtual void UpdateChildrenAndEffects() const = 0;
virtual double IntrinsicIterationDuration() const { return 0; }
virtual double CalculateTimeToEffectChange(
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 13913015aa6..ba175ec7f7e 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
@@ -137,7 +137,7 @@ TEST(AnimationAnimationEffectTest, Sanity) {
EXPECT_TRUE(animation_node->IsCurrent());
EXPECT_TRUE(animation_node->IsInEffect());
EXPECT_EQ(0, animation_node->CurrentIteration());
- EXPECT_EQ(2, animation_node->ActiveDurationInternal());
+ EXPECT_EQ(2, animation_node->RepeatedDuration());
EXPECT_EQ(0, animation_node->Progress());
animation_node->UpdateInheritedTime(1);
@@ -147,7 +147,7 @@ TEST(AnimationAnimationEffectTest, Sanity) {
EXPECT_TRUE(animation_node->IsCurrent());
EXPECT_TRUE(animation_node->IsInEffect());
EXPECT_EQ(0, animation_node->CurrentIteration());
- EXPECT_EQ(2, animation_node->ActiveDurationInternal());
+ EXPECT_EQ(2, animation_node->RepeatedDuration());
EXPECT_EQ(0.5, animation_node->Progress());
animation_node->UpdateInheritedTime(2);
@@ -157,7 +157,7 @@ TEST(AnimationAnimationEffectTest, Sanity) {
EXPECT_FALSE(animation_node->IsCurrent());
EXPECT_TRUE(animation_node->IsInEffect());
EXPECT_EQ(0, animation_node->CurrentIteration());
- EXPECT_EQ(2, animation_node->ActiveDurationInternal());
+ EXPECT_EQ(2, animation_node->RepeatedDuration());
EXPECT_EQ(1, animation_node->Progress());
animation_node->UpdateInheritedTime(3);
@@ -167,7 +167,7 @@ TEST(AnimationAnimationEffectTest, Sanity) {
EXPECT_FALSE(animation_node->IsCurrent());
EXPECT_TRUE(animation_node->IsInEffect());
EXPECT_EQ(0, animation_node->CurrentIteration());
- EXPECT_EQ(2, animation_node->ActiveDurationInternal());
+ EXPECT_EQ(2, animation_node->RepeatedDuration());
EXPECT_EQ(1, animation_node->Progress());
}
@@ -247,12 +247,12 @@ TEST(AnimationAnimationEffectTest, ZeroIteration) {
TestAnimationEffect* animation_node = TestAnimationEffect::Create(timing);
animation_node->UpdateInheritedTime(-1);
- EXPECT_EQ(0, animation_node->ActiveDurationInternal());
+ EXPECT_EQ(0, animation_node->RepeatedDuration());
EXPECT_TRUE(IsNull(animation_node->CurrentIteration()));
EXPECT_FALSE(animation_node->Progress());
animation_node->UpdateInheritedTime(0);
- EXPECT_EQ(0, animation_node->ActiveDurationInternal());
+ EXPECT_EQ(0, animation_node->RepeatedDuration());
EXPECT_EQ(0, animation_node->CurrentIteration());
EXPECT_EQ(0, animation_node->Progress());
}
@@ -269,7 +269,7 @@ TEST(AnimationAnimationEffectTest, InfiniteIteration) {
EXPECT_FALSE(animation_node->Progress());
EXPECT_EQ(std::numeric_limits<double>::infinity(),
- animation_node->ActiveDurationInternal());
+ animation_node->RepeatedDuration());
animation_node->UpdateInheritedTime(0);
EXPECT_EQ(0, animation_node->CurrentIteration());
@@ -375,7 +375,7 @@ TEST(AnimationAnimationEffectTest, ZeroDurationSanity) {
EXPECT_FALSE(animation_node->IsCurrent());
EXPECT_TRUE(animation_node->IsInEffect());
EXPECT_EQ(0, animation_node->CurrentIteration());
- EXPECT_EQ(0, animation_node->ActiveDurationInternal());
+ EXPECT_EQ(0, animation_node->RepeatedDuration());
EXPECT_EQ(1, animation_node->Progress());
animation_node->UpdateInheritedTime(1);
@@ -385,7 +385,7 @@ TEST(AnimationAnimationEffectTest, ZeroDurationSanity) {
EXPECT_FALSE(animation_node->IsCurrent());
EXPECT_TRUE(animation_node->IsInEffect());
EXPECT_EQ(0, animation_node->CurrentIteration());
- EXPECT_EQ(0, animation_node->ActiveDurationInternal());
+ EXPECT_EQ(0, animation_node->RepeatedDuration());
EXPECT_EQ(1, animation_node->Progress());
}
@@ -476,12 +476,12 @@ TEST(AnimationAnimationEffectTest, ZeroDurationInfiniteIteration) {
TestAnimationEffect* animation_node = TestAnimationEffect::Create(timing);
animation_node->UpdateInheritedTime(-1);
- EXPECT_EQ(0, animation_node->ActiveDurationInternal());
+ EXPECT_EQ(0, animation_node->RepeatedDuration());
EXPECT_TRUE(IsNull(animation_node->CurrentIteration()));
EXPECT_FALSE(animation_node->Progress());
animation_node->UpdateInheritedTime(0);
- EXPECT_EQ(0, animation_node->ActiveDurationInternal());
+ EXPECT_EQ(0, animation_node->RepeatedDuration());
EXPECT_EQ(std::numeric_limits<double>::infinity(),
animation_node->CurrentIteration());
EXPECT_EQ(1, animation_node->Progress());
@@ -575,7 +575,7 @@ TEST(AnimationAnimationEffectTest, InfiniteDurationSanity) {
animation_node->UpdateInheritedTime(0);
EXPECT_EQ(std::numeric_limits<double>::infinity(),
- animation_node->ActiveDurationInternal());
+ animation_node->RepeatedDuration());
EXPECT_EQ(AnimationEffect::kPhaseActive, animation_node->GetPhase());
EXPECT_TRUE(animation_node->IsInPlay());
EXPECT_TRUE(animation_node->IsCurrent());
@@ -586,7 +586,7 @@ TEST(AnimationAnimationEffectTest, InfiniteDurationSanity) {
animation_node->UpdateInheritedTime(1);
EXPECT_EQ(std::numeric_limits<double>::infinity(),
- animation_node->ActiveDurationInternal());
+ animation_node->RepeatedDuration());
EXPECT_EQ(AnimationEffect::kPhaseActive, animation_node->GetPhase());
EXPECT_TRUE(animation_node->IsInPlay());
EXPECT_TRUE(animation_node->IsCurrent());
@@ -604,7 +604,7 @@ TEST(AnimationAnimationEffectTest, InfiniteDurationZeroIterations) {
animation_node->UpdateInheritedTime(0);
- EXPECT_EQ(0, animation_node->ActiveDurationInternal());
+ EXPECT_EQ(0, animation_node->RepeatedDuration());
EXPECT_EQ(AnimationEffect::kPhaseAfter, animation_node->GetPhase());
EXPECT_FALSE(animation_node->IsInPlay());
EXPECT_FALSE(animation_node->IsCurrent());
@@ -632,7 +632,7 @@ TEST(AnimationAnimationEffectTest, InfiniteDurationInfiniteIterations) {
animation_node->UpdateInheritedTime(0);
EXPECT_EQ(std::numeric_limits<double>::infinity(),
- animation_node->ActiveDurationInternal());
+ animation_node->RepeatedDuration());
EXPECT_EQ(AnimationEffect::kPhaseActive, animation_node->GetPhase());
EXPECT_TRUE(animation_node->IsInPlay());
EXPECT_TRUE(animation_node->IsCurrent());
@@ -643,7 +643,7 @@ TEST(AnimationAnimationEffectTest, InfiniteDurationInfiniteIterations) {
animation_node->UpdateInheritedTime(1);
EXPECT_EQ(std::numeric_limits<double>::infinity(),
- animation_node->ActiveDurationInternal());
+ animation_node->RepeatedDuration());
EXPECT_EQ(AnimationEffect::kPhaseActive, animation_node->GetPhase());
EXPECT_TRUE(animation_node->IsInPlay());
EXPECT_TRUE(animation_node->IsCurrent());
@@ -652,35 +652,6 @@ TEST(AnimationAnimationEffectTest, InfiniteDurationInfiniteIterations) {
EXPECT_EQ(0, animation_node->Progress());
}
-TEST(AnimationAnimationEffectTest, InfiniteDurationZeroPlaybackRate) {
- Timing timing;
- timing.iteration_duration = std::numeric_limits<double>::infinity();
- timing.playback_rate = 0;
- TestAnimationEffect* animation_node = TestAnimationEffect::Create(timing);
-
- animation_node->UpdateInheritedTime(0);
-
- EXPECT_EQ(std::numeric_limits<double>::infinity(),
- animation_node->ActiveDurationInternal());
- EXPECT_EQ(AnimationEffect::kPhaseActive, animation_node->GetPhase());
- EXPECT_TRUE(animation_node->IsInPlay());
- EXPECT_TRUE(animation_node->IsCurrent());
- EXPECT_TRUE(animation_node->IsInEffect());
- EXPECT_EQ(0, animation_node->CurrentIteration());
- EXPECT_EQ(0, animation_node->Progress());
-
- animation_node->UpdateInheritedTime(std::numeric_limits<double>::infinity());
-
- EXPECT_EQ(std::numeric_limits<double>::infinity(),
- animation_node->ActiveDurationInternal());
- EXPECT_EQ(AnimationEffect::kPhaseAfter, animation_node->GetPhase());
- EXPECT_FALSE(animation_node->IsInPlay());
- EXPECT_FALSE(animation_node->IsCurrent());
- EXPECT_TRUE(animation_node->IsInEffect());
- EXPECT_EQ(0, animation_node->CurrentIteration());
- EXPECT_EQ(0, animation_node->Progress());
-}
-
TEST(AnimationAnimationEffectTest, EndTime) {
Timing timing;
timing.start_delay = 1;
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 345f1d40be8..e86b8616d52 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
@@ -66,12 +66,12 @@ TEST_F(AnimationSimTest, CustomPropertyBaseComputedStyle) {
EXPECT_FALSE(exception_state.HadException());
// target.animate({'--x': '100%'}, 1000);
- scoped_refptr<StringKeyframe> keyframe = StringKeyframe::Create();
+ StringKeyframe* keyframe = StringKeyframe::Create();
keyframe->SetCSSPropertyValue("--x", GetDocument().GetPropertyRegistry(),
"100%", GetDocument().GetSecureContextMode(),
GetDocument().ElementSheet().Contents());
StringKeyframeVector keyframes;
- keyframes.push_back(std::move(keyframe));
+ keyframes.push_back(keyframe);
Timing timing;
timing.iteration_duration = 1; // Seconds.
ElementAnimation::animateInternal(
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 b36783cd172..a0b63b909cf 100644
--- a/chromium/third_party/blink/renderer/core/animation/animation_test.cc
+++ b/chromium/third_party/blink/renderer/core/animation/animation_test.cc
@@ -32,7 +32,9 @@
#include <memory>
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/core/animation/animatable/animatable_double.h"
#include "third_party/blink/renderer/core/animation/animation_clock.h"
+#include "third_party/blink/renderer/core/animation/css_number_interpolation_type.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"
@@ -73,6 +75,34 @@ class AnimationAnimationTest : public RenderingTest {
void StartTimeline() { SimulateFrame(0); }
+ KeyframeEffectModelBase* MakeSimpleEffectModel() {
+ PropertyHandle PropertyHandleOpacity(GetCSSPropertyOpacity());
+ TransitionKeyframe* start_keyframe =
+ TransitionKeyframe::Create(PropertyHandleOpacity);
+ start_keyframe->SetValue(TypedInterpolationValue::Create(
+ CSSNumberInterpolationType(PropertyHandleOpacity),
+ InterpolableNumber::Create(1.0)));
+ start_keyframe->SetOffset(0.0);
+ // Egregious hack: Sideload the compositor value.
+ // This is usually set in a part of the rendering process SimulateFrame
+ // doesn't call.
+ start_keyframe->SetCompositorValue(AnimatableDouble::Create(1.0));
+ TransitionKeyframe* end_keyframe =
+ TransitionKeyframe::Create(PropertyHandleOpacity);
+ end_keyframe->SetValue(TypedInterpolationValue::Create(
+ CSSNumberInterpolationType(PropertyHandleOpacity),
+ InterpolableNumber::Create(0.0)));
+ end_keyframe->SetOffset(1.0);
+ // Egregious hack: Sideload the compositor value.
+ end_keyframe->SetCompositorValue(AnimatableDouble::Create(0.0));
+
+ TransitionKeyframeVector keyframes;
+ keyframes.push_back(start_keyframe);
+ keyframes.push_back(end_keyframe);
+
+ return TransitionKeyframeEffectModel::Create(keyframes);
+ }
+
void ResetWithCompositedAnimation() {
// Get rid of the default animation.
animation->cancel();
@@ -85,11 +115,11 @@ class AnimationAnimationTest : public RenderingTest {
Timing timing;
timing.iteration_duration = 30;
- scoped_refptr<StringKeyframe> start_keyframe = StringKeyframe::Create();
+ Persistent<StringKeyframe> start_keyframe = StringKeyframe::Create();
start_keyframe->SetCSSPropertyValue(CSSPropertyOpacity, "1.0",
SecureContextMode::kInsecureContext,
nullptr);
- scoped_refptr<StringKeyframe> end_keyframe = StringKeyframe::Create();
+ Persistent<StringKeyframe> end_keyframe = StringKeyframe::Create();
end_keyframe->SetCSSPropertyValue(CSSPropertyOpacity, "0.0",
SecureContextMode::kInsecureContext,
nullptr);
@@ -115,11 +145,9 @@ class AnimationAnimationTest : public RenderingTest {
return StringKeyframeEffectModel::Create(StringKeyframeVector());
}
- KeyframeEffect* MakeAnimation(double duration = 30,
- double playback_rate = 1) {
+ KeyframeEffect* MakeAnimation(double duration = 30) {
Timing timing;
timing.iteration_duration = duration;
- timing.playback_rate = playback_rate;
return KeyframeEffect::Create(nullptr, MakeEmptyEffectModel(), timing);
}
@@ -860,25 +888,24 @@ TEST_F(AnimationAnimationTest, NoCompositeWithoutCompositedElementId) {
Timing timing;
timing.iteration_duration = 30;
- timing.playback_rate = 1;
KeyframeEffect* keyframe_effect_composited = KeyframeEffect::Create(
- ToElement(object_composited->GetNode()), MakeEmptyEffectModel(), timing);
+ ToElement(object_composited->GetNode()), MakeSimpleEffectModel(), timing);
Animation* animation_composited = timeline->Play(keyframe_effect_composited);
KeyframeEffect* keyframe_effect_not_composited =
KeyframeEffect::Create(ToElement(object_not_composited->GetNode()),
- MakeEmptyEffectModel(), timing);
+ MakeSimpleEffectModel(), timing);
Animation* animation_not_composited =
timeline->Play(keyframe_effect_not_composited);
SimulateFrame(0, composited_element_ids);
EXPECT_TRUE(
- animation_composited
- ->CheckCanStartAnimationOnCompositorInternal(composited_element_ids)
- .Ok());
- EXPECT_FALSE(
- animation_not_composited
- ->CheckCanStartAnimationOnCompositorInternal(composited_element_ids)
- .Ok());
+ animation_composited->CheckCanStartAnimationOnCompositorInternal().Ok());
+ EXPECT_TRUE(animation_composited
+ ->CheckCanStartAnimationOnCompositor(composited_element_ids)
+ .Ok());
+ EXPECT_FALSE(animation_not_composited
+ ->CheckCanStartAnimationOnCompositor(composited_element_ids)
+ .Ok());
}
// Regression test for http://crbug.com/819591 . If a compositable animation is
@@ -925,10 +952,10 @@ TEST_F(AnimationAnimationTest, SetKeyframesCausesCompositorPending) {
// Now change the keyframes; this should mark the animation as compositor
// pending as we need to sync the compositor side.
- scoped_refptr<StringKeyframe> start_keyframe = StringKeyframe::Create();
+ Persistent<StringKeyframe> start_keyframe = StringKeyframe::Create();
start_keyframe->SetCSSPropertyValue(
CSSPropertyOpacity, "0.0", SecureContextMode::kInsecureContext, nullptr);
- scoped_refptr<StringKeyframe> end_keyframe = StringKeyframe::Create();
+ Persistent<StringKeyframe> end_keyframe = StringKeyframe::Create();
end_keyframe->SetCSSPropertyValue(
CSSPropertyOpacity, "1.0", SecureContextMode::kInsecureContext, nullptr);
diff --git a/chromium/third_party/blink/renderer/core/animation/animation_time_delta.cc b/chromium/third_party/blink/renderer/core/animation/animation_time_delta.cc
new file mode 100644
index 00000000000..1b25469c7f2
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/animation/animation_time_delta.cc
@@ -0,0 +1,15 @@
+// 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/animation/animation_time_delta.h"
+
+namespace blink {
+
+#if !defined(BLINK_ANIMATION_USE_TIME_DELTA)
+std::ostream& operator<<(std::ostream& os, AnimationTimeDelta time) {
+ return os << time.InSecondsF() << " s";
+}
+#endif
+
+} // namespace blink
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
new file mode 100644
index 00000000000..1903c1150d3
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/animation/animation_time_delta.h
@@ -0,0 +1,127 @@
+// 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_ANIMATION_ANIMATION_TIME_DELTA_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_ANIMATION_TIME_DELTA_H_
+
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/wtf/allocator.h"
+
+#include <limits>
+#include <ostream>
+
+#if defined(BLINK_ANIMATION_USE_TIME_DELTA)
+#include "third_party/blink/renderer/platform/wtf/time.h"
+#endif
+
+namespace blink {
+
+// AnimationTimeDelta exists to ease the transition of Blink animations from
+// double-based time values to base::TimeDelta-based time values (see
+// http://crbug.com/737867.
+//
+// It represents a delta between two times, analogous to base::TimeDelta. It is
+// provided in two modes, based on a compiler flag. The first is the traditional
+// (and default) double mode, where time deltas are represented using seconds in
+// double-precision. The second mode uses base::TimeDelta to represent time
+// instead.
+
+#if !defined(BLINK_ANIMATION_USE_TIME_DELTA)
+
+// The double-based version of AnimationTimeDelta. Internally, time is stored as
+// double-precision seconds.
+//
+// This class is modelled on the API from base::TimeDelta, with a lot of
+// unnecessary methods stripped out.
+class CORE_EXPORT AnimationTimeDelta {
+ USING_FAST_MALLOC(AnimationTimeDelta);
+
+ public:
+ constexpr AnimationTimeDelta() : delta_(0) {}
+
+ static AnimationTimeDelta FromSecondsD(double time_s) {
+ DCHECK(!std::isnan(time_s));
+ return AnimationTimeDelta(time_s);
+ }
+ static AnimationTimeDelta FromMillisecondsD(double time_ms) {
+ DCHECK(!std::isnan(time_ms));
+ return AnimationTimeDelta(time_ms / 1000);
+ }
+
+ static constexpr AnimationTimeDelta Max() {
+ return AnimationTimeDelta(std::numeric_limits<double>::infinity());
+ }
+
+ double InSecondsF() const { return delta_; }
+ double InMillisecondsF() const { return delta_ * 1000; }
+
+ bool is_max() const {
+ return delta_ == std::numeric_limits<double>::infinity();
+ }
+ bool is_zero() const { return delta_ == 0; }
+
+ AnimationTimeDelta operator+(AnimationTimeDelta other) const {
+ return AnimationTimeDelta(delta_ + other.delta_);
+ }
+ AnimationTimeDelta& operator+=(AnimationTimeDelta other) {
+ return *this = (*this + other);
+ }
+ template <typename T>
+ AnimationTimeDelta operator*(T a) const {
+ return AnimationTimeDelta(delta_ * a);
+ }
+ template <typename V>
+ AnimationTimeDelta& operator*=(V a) {
+ return *this = (*this * a);
+ }
+
+ protected:
+ constexpr explicit AnimationTimeDelta(double delta) : delta_(delta) {}
+
+ // The time delta represented by this |AnimationTimeDelta|, in seconds. May be
+ // negative, in which case the end of the delta is before the start.
+ double delta_;
+};
+
+template <typename T>
+AnimationTimeDelta operator*(T a, AnimationTimeDelta td) {
+ return td * a;
+}
+
+// Comparison operators on AnimationTimeDelta.
+constexpr bool CORE_EXPORT operator==(const AnimationTimeDelta& lhs,
+ const AnimationTimeDelta& rhs) {
+ return lhs.InSecondsF() == rhs.InSecondsF();
+}
+constexpr bool CORE_EXPORT operator!=(const AnimationTimeDelta& lhs,
+ const AnimationTimeDelta& rhs) {
+ return lhs.InSecondsF() != rhs.InSecondsF();
+}
+constexpr bool CORE_EXPORT operator>(const AnimationTimeDelta& lhs,
+ const AnimationTimeDelta& rhs) {
+ return lhs.InSecondsF() > rhs.InSecondsF();
+}
+constexpr bool CORE_EXPORT operator>=(const AnimationTimeDelta& lhs,
+ const AnimationTimeDelta& rhs) {
+ return lhs.InSecondsF() >= rhs.InSecondsF();
+}
+constexpr bool CORE_EXPORT operator<=(const AnimationTimeDelta& lhs,
+ const AnimationTimeDelta& rhs) {
+ return lhs.InSecondsF() <= rhs.InSecondsF();
+}
+
+// Defined to allow DCHECK_EQ/etc to work with the class.
+CORE_EXPORT std::ostream& operator<<(std::ostream& os, AnimationTimeDelta time);
+
+#else // !defined(BLINK_ANIMATION_USE_TIME_DELTA)
+
+// When compiling in TimeDelta-based mode, AnimationTimeDelta is equivalent to
+// base::TimeDelta.
+using AnimationTimeDelta = TimeDelta;
+
+#endif
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_ANIMATION_TIME_DELTA_H_
diff --git a/chromium/third_party/blink/renderer/core/animation/animation_time_delta_test.cc b/chromium/third_party/blink/renderer/core/animation/animation_time_delta_test.cc
new file mode 100644
index 00000000000..627b9b164aa
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/animation/animation_time_delta_test.cc
@@ -0,0 +1,91 @@
+// 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/animation/animation_time_delta.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+#include <limits>
+
+namespace blink {
+
+TEST(AnimationTimeDeltaTest, Construction) {
+ // The default constructor is a zero-length delta.
+ EXPECT_EQ(AnimationTimeDelta(), AnimationTimeDelta::FromSecondsD(0));
+ EXPECT_EQ(AnimationTimeDelta(), AnimationTimeDelta::FromMillisecondsD(0));
+
+ EXPECT_EQ(AnimationTimeDelta::FromSecondsD(5.5),
+ AnimationTimeDelta::FromMillisecondsD(5500));
+ EXPECT_EQ(AnimationTimeDelta::FromSecondsD(-2),
+ AnimationTimeDelta::FromMillisecondsD(-2000));
+}
+
+TEST(AnimationTimeDeltaTest, Conversion) {
+ AnimationTimeDelta delta = AnimationTimeDelta::FromSecondsD(5);
+ EXPECT_EQ(delta.InSecondsF(), 5);
+ EXPECT_EQ(delta.InMillisecondsF(), 5000);
+
+ delta = AnimationTimeDelta::FromMillisecondsD(1234);
+ EXPECT_EQ(delta.InSecondsF(), 1.234);
+ EXPECT_EQ(delta.InMillisecondsF(), 1234);
+}
+
+TEST(AnimationTimeDeltaTest, Max) {
+ AnimationTimeDelta max_delta = AnimationTimeDelta::Max();
+ EXPECT_TRUE(max_delta.is_max());
+ EXPECT_EQ(max_delta, AnimationTimeDelta::Max());
+ EXPECT_GT(max_delta, AnimationTimeDelta::FromSecondsD(365 * 24 * 60 * 60));
+
+ EXPECT_EQ(max_delta.InSecondsF(), std::numeric_limits<double>::infinity());
+ EXPECT_EQ(max_delta.InMillisecondsF(),
+ std::numeric_limits<double>::infinity());
+}
+
+TEST(AnimationTimeDeltaTest, Zero) {
+ EXPECT_TRUE(AnimationTimeDelta().is_zero());
+ EXPECT_TRUE(AnimationTimeDelta::FromSecondsD(0).is_zero());
+ EXPECT_TRUE(AnimationTimeDelta::FromMillisecondsD(0).is_zero());
+
+ EXPECT_FALSE(AnimationTimeDelta::FromSecondsD(54.5).is_zero());
+ EXPECT_FALSE(AnimationTimeDelta::FromSecondsD(-0.5).is_zero());
+ EXPECT_FALSE(AnimationTimeDelta::FromMillisecondsD(123.45).is_zero());
+}
+
+TEST(AnimationTimeDeltaTest, Computation) {
+ EXPECT_EQ(AnimationTimeDelta::FromSecondsD(4.5) +
+ AnimationTimeDelta::FromMillisecondsD(500),
+ AnimationTimeDelta::FromSecondsD(5));
+ EXPECT_EQ(AnimationTimeDelta::FromSecondsD(100) +
+ AnimationTimeDelta::FromMillisecondsD(-850),
+ AnimationTimeDelta::FromSecondsD(99.15));
+
+ EXPECT_EQ(AnimationTimeDelta::FromSecondsD(5) * 20,
+ AnimationTimeDelta::FromSecondsD(100));
+ EXPECT_EQ(AnimationTimeDelta::FromSecondsD(10) * 1.5,
+ AnimationTimeDelta::FromSecondsD(15));
+ EXPECT_EQ(AnimationTimeDelta::FromSecondsD(2.5) * -2,
+ AnimationTimeDelta::FromSecondsD(-5));
+
+ EXPECT_EQ(20 * AnimationTimeDelta::FromSecondsD(5),
+ AnimationTimeDelta::FromSecondsD(100));
+}
+
+TEST(AnimationTimeDeltaTest, Comparison) {
+ EXPECT_TRUE(AnimationTimeDelta::FromSecondsD(10) ==
+ AnimationTimeDelta::FromSecondsD(10));
+ EXPECT_TRUE(AnimationTimeDelta::FromSecondsD(10) !=
+ AnimationTimeDelta::FromSecondsD(50));
+ EXPECT_TRUE(AnimationTimeDelta::FromSecondsD(50) >
+ AnimationTimeDelta::FromSecondsD(49.999));
+ EXPECT_TRUE(AnimationTimeDelta::FromSecondsD(50) >=
+ AnimationTimeDelta::FromSecondsD(49.999));
+ EXPECT_TRUE(AnimationTimeDelta::FromSecondsD(50) >=
+ AnimationTimeDelta::FromSecondsD(50));
+ EXPECT_TRUE(AnimationTimeDelta::FromSecondsD(50) <=
+ AnimationTimeDelta::FromSecondsD(50));
+ EXPECT_TRUE(AnimationTimeDelta::FromSecondsD(50) <=
+ AnimationTimeDelta::FromSecondsD(100));
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/animation/base_keyframe.idl b/chromium/third_party/blink/renderer/core/animation/base_keyframe.idl
index c65c8a5946c..e27109f1fde 100644
--- a/chromium/third_party/blink/renderer/core/animation/base_keyframe.idl
+++ b/chromium/third_party/blink/renderer/core/animation/base_keyframe.idl
@@ -4,8 +4,10 @@
// https://drafts.csswg.org/web-animations/#dictdef-basekeyframe
+enum CompositeOperationOrAuto {"replace", "add", "accumulate", "auto"};
+
dictionary BaseKeyframe {
double? offset = null;
DOMString easing = "linear";
- CompositeOperation? composite = null;
+ CompositeOperationOrAuto composite = "auto";
};
diff --git a/chromium/third_party/blink/renderer/core/animation/base_property_indexed_keyframe.idl b/chromium/third_party/blink/renderer/core/animation/base_property_indexed_keyframe.idl
index 305176b8894..cc71757f670 100644
--- a/chromium/third_party/blink/renderer/core/animation/base_property_indexed_keyframe.idl
+++ b/chromium/third_party/blink/renderer/core/animation/base_property_indexed_keyframe.idl
@@ -7,5 +7,5 @@
dictionary BasePropertyIndexedKeyframe {
(double? or sequence<double?>) offset = [];
(DOMString or sequence<DOMString>) easing = [];
- (CompositeOperation? or sequence<CompositeOperation?>) composite = [];
+ (CompositeOperationOrAuto or sequence<CompositeOperationOrAuto>) composite = [];
};
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 c9013c9c8fa..0cc8227e3bc 100644
--- a/chromium/third_party/blink/renderer/core/animation/compositor_animations.cc
+++ b/chromium/third_party/blink/renderer/core/animation/compositor_animations.cc
@@ -151,6 +151,7 @@ CompositorAnimations::CheckCanStartEffectOnCompositor(
const Element& target_element,
const Animation* animation_to_add,
const EffectModel& effect,
+ const base::Optional<CompositorElementIdSet>& composited_element_ids,
double animation_playback_rate) {
const KeyframeEffectModelBase& keyframe_effect =
ToKeyframeEffectModelBase(effect);
@@ -160,6 +161,16 @@ CompositorAnimations::CheckCanStartEffectOnCompositor(
return FailureCode::Actionable("Animation does not affect any properties");
}
+ if (composited_element_ids) {
+ // If we are going to check that we can animate these below, we need
+ // to have the UniqueID to compute the target ID. Let's check it
+ // once in common in advance.
+ if (!target_element.GetLayoutObject() ||
+ !target_element.GetLayoutObject()->UniqueId()) {
+ return FailureCode::NonActionable("Target element has no layout");
+ }
+ }
+
unsigned transform_property_count = 0;
for (const auto& property : properties) {
if (!property.IsCSSProperty()) {
@@ -167,6 +178,7 @@ CompositorAnimations::CheckCanStartEffectOnCompositor(
}
if (IsTransformRelatedCSSProperty(property)) {
+ // We use this later in computing element IDs too.
if (target_element.GetLayoutObject() &&
!target_element.GetLayoutObject()->IsTransformApplicable()) {
return FailureCode::Actionable(
@@ -192,6 +204,8 @@ CompositorAnimations::CheckCanStartEffectOnCompositor(
"Accelerated keyframe value could not be computed");
}
+ CompositorElementIdNamespace property_namespace =
+ CompositorElementIdNamespace::kPrimary;
// FIXME: Determine candidacy based on the CSSValue instead of a snapshot
// AnimatableValue.
switch (property.GetCSSProperty().PropertyID()) {
@@ -218,6 +232,7 @@ CompositorAnimations::CheckCanStartEffectOnCompositor(
return FailureCode::Actionable(
"Filter-related property may affect surrounding pixels");
}
+ property_namespace = CompositorElementIdNamespace::kEffectFilter;
break;
}
default:
@@ -231,6 +246,17 @@ CompositorAnimations::CheckCanStartEffectOnCompositor(
}
return FailureCode::Actionable(builder.ToString());
}
+ if (composited_element_ids) {
+ CompositorElementId target_element_id =
+ CompositorElementIdFromUniqueObjectId(
+ target_element.GetLayoutObject()->UniqueId(),
+ property_namespace);
+ DCHECK(target_element_id);
+ if (!composited_element_ids->Contains(target_element_id)) {
+ return FailureCode::NonActionable(
+ "Target element does not have its own compositing layer");
+ }
+ }
}
}
@@ -274,6 +300,7 @@ CompositorAnimations::CheckCanStartElementOnCompositor(
// the DCHECK below.
// DCHECK(document().lifecycle().state() >=
// DocumentLifecycle::PrePaintClean);
+ DCHECK(target_element.GetLayoutObject());
if (const auto* paint_properties = target_element.GetLayoutObject()
->FirstFragment()
.PaintProperties()) {
@@ -309,10 +336,11 @@ CompositorAnimations::CheckCanStartAnimationOnCompositor(
const Element& target_element,
const Animation* animation_to_add,
const EffectModel& effect,
+ const base::Optional<CompositorElementIdSet>& composited_element_ids,
double animation_playback_rate) {
- FailureCode code =
- CheckCanStartEffectOnCompositor(timing, target_element, animation_to_add,
- effect, animation_playback_rate);
+ FailureCode code = CheckCanStartEffectOnCompositor(
+ timing, target_element, animation_to_add, effect, composited_element_ids,
+ animation_playback_rate);
if (!code.Ok()) {
return code;
}
@@ -370,8 +398,11 @@ void CompositorAnimations::StartAnimationOnCompositor(
Vector<int>& started_keyframe_model_ids,
double animation_playback_rate) {
DCHECK(started_keyframe_model_ids.IsEmpty());
- DCHECK(CheckCanStartAnimationOnCompositor(timing, element, animation, effect,
- animation_playback_rate)
+ // TODO(petermayo): Find and pass the set of valid compositor elements before
+ // BlinkGenPropertyTrees is always on.
+ DCHECK(CheckCanStartAnimationOnCompositor(
+ timing, element, animation, effect,
+ base::Optional<CompositorElementIdSet>(), animation_playback_rate)
.Ok());
const KeyframeEffectModelBase& keyframe_effect =
@@ -475,7 +506,7 @@ bool CompositorAnimations::ConvertTimingForCompositor(
// 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 = timing.playback_rate * animation_playback_rate;
+ out.playback_rate = animation_playback_rate;
out.fill_mode = timing.fill_mode == Timing::FillMode::AUTO
? Timing::FillMode::NONE
: timing.fill_mode;
@@ -532,7 +563,7 @@ void AddKeyframeToCurve(CompositorTransformAnimationCurve& curve,
template <typename PlatformAnimationCurveType>
void AddKeyframesToCurve(PlatformAnimationCurveType& curve,
const PropertySpecificKeyframeVector& keyframes) {
- auto* last_keyframe = keyframes.back().get();
+ Keyframe::PropertySpecificKeyframe* last_keyframe = keyframes.back();
for (const auto& keyframe : keyframes) {
const TimingFunction* keyframe_timing_function = nullptr;
// Ignore timing function of last frame.
@@ -542,7 +573,7 @@ void AddKeyframesToCurve(PlatformAnimationCurveType& curve,
keyframe_timing_function = &keyframe->Easing();
const AnimatableValue* value = keyframe->GetAnimatableValue();
- AddKeyframeToCurve(curve, keyframe.get(), value, *keyframe_timing_function);
+ AddKeyframeToCurve(curve, keyframe, value, *keyframe_timing_function);
}
}
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 1739effe9d1..8f0410e003d 100644
--- a/chromium/third_party/blink/renderer/core/animation/compositor_animations.h
+++ b/chromium/third_party/blink/renderer/core/animation/compositor_animations.h
@@ -36,6 +36,7 @@
#include "third_party/blink/renderer/core/animation/timing.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/animation/timing_function.h"
+#include "third_party/blink/renderer/platform/graphics/compositor_element_id.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -85,6 +86,7 @@ class CORE_EXPORT CompositorAnimations {
const Element&,
const Animation*,
const EffectModel&,
+ const base::Optional<CompositorElementIdSet>& composited_element_ids,
double animation_playback_rate);
static void CancelIncompatibleAnimationsOnCompositor(const Element&,
const Animation&,
@@ -140,6 +142,7 @@ class CORE_EXPORT CompositorAnimations {
const Element&,
const Animation*,
const EffectModel&,
+ const base::Optional<CompositorElementIdSet>& composited_element_ids,
double animation_playback_rate);
static FailureCode CheckCanStartElementOnCompositor(const Element&);
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 d1fcc00f2ea..1b176054aa9 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
@@ -82,9 +82,9 @@ class AnimationCompositorAnimationsTest : public RenderingTest {
Timing timing_;
CompositorAnimations::CompositorTiming compositor_timing_;
- std::unique_ptr<StringKeyframeVector> keyframe_vector2_;
+ PersistentHeapVector<Member<StringKeyframe>> keyframe_vector2_;
Persistent<StringKeyframeEffectModel> keyframe_animation_effect2_;
- std::unique_ptr<StringKeyframeVector> keyframe_vector5_;
+ PersistentHeapVector<Member<StringKeyframe>> keyframe_vector5_;
Persistent<StringKeyframeEffectModel> keyframe_animation_effect5_;
Persistent<Element> element_;
@@ -110,11 +110,11 @@ class AnimationCompositorAnimationsTest : public RenderingTest {
keyframe_vector2_ = CreateCompositableFloatKeyframeVector(2);
keyframe_animation_effect2_ =
- StringKeyframeEffectModel::Create(*keyframe_vector2_);
+ StringKeyframeEffectModel::Create(keyframe_vector2_);
keyframe_vector5_ = CreateCompositableFloatKeyframeVector(5);
keyframe_animation_effect5_ =
- StringKeyframeEffectModel::Create(*keyframe_vector5_);
+ StringKeyframeEffectModel::Create(keyframe_vector5_);
GetAnimationClock().ResetTimeForTesting();
@@ -131,18 +131,31 @@ class AnimationCompositorAnimationsTest : public RenderingTest {
CompositorAnimations::CompositorTiming& out) {
return CompositorAnimations::ConvertTimingForCompositor(t, 0, out, 1);
}
+
bool CanStartEffectOnCompositor(const Timing& timing,
const KeyframeEffectModelBase& effect) {
// As the compositor code only understands AnimatableValues, we must
// snapshot the effect to make those available.
+ base::Optional<CompositorElementIdSet> none;
// TODO(crbug.com/725385): Remove once compositor uses InterpolationTypes.
auto style = ComputedStyle::Create();
effect.SnapshotAllCompositorKeyframesIfNecessary(*element_.Get(), *style,
nullptr);
+ return CheckCanStartEffectOnCompositor(timing, *element_.Get(), nullptr,
+ effect, none);
+ }
+ bool CheckCanStartEffectOnCompositor(
+ const Timing& timing,
+ const Element& element,
+ const Animation* animation,
+ const EffectModel& effect_model,
+ const base::Optional<CompositorElementIdSet>& composited_element_ids) {
return CompositorAnimations::CheckCanStartEffectOnCompositor(
- timing, *element_.Get(), nullptr, effect, 1)
+ timing, element, animation, effect_model, composited_element_ids,
+ 1)
.Ok();
}
+
void GetAnimationOnCompositor(
Timing& timing,
StringKeyframeEffectModel& effect,
@@ -163,10 +176,10 @@ class AnimationCompositorAnimationsTest : public RenderingTest {
StringKeyframe* frame) {
EXPECT_EQ(frame->CheckedOffset(), 0);
StringKeyframeVector frames;
- scoped_refptr<Keyframe> second = frame->CloneWithOffset(1);
+ Keyframe* second = frame->CloneWithOffset(1);
frames.push_back(frame);
- frames.push_back(ToStringKeyframe(second.get()));
+ frames.push_back(ToStringKeyframe(second));
return CanStartEffectOnCompositor(
timing_, *StringKeyframeEffectModel::Create(frames));
}
@@ -180,16 +193,15 @@ class AnimationCompositorAnimationsTest : public RenderingTest {
timing.iteration_start = 0;
timing.iteration_count = 1;
timing.iteration_duration = 1.0;
- timing.playback_rate = 1.0;
timing.direction = Timing::PlaybackDirection::NORMAL;
timing.timing_function = linear_timing_function_;
return timing;
}
- scoped_refptr<StringKeyframe> CreateReplaceOpKeyframe(CSSPropertyID id,
- const String& value,
- double offset = 0) {
- scoped_refptr<StringKeyframe> keyframe = StringKeyframe::Create();
+ StringKeyframe* CreateReplaceOpKeyframe(CSSPropertyID id,
+ const String& value,
+ double offset = 0) {
+ StringKeyframe* keyframe = StringKeyframe::Create();
keyframe->SetCSSPropertyValue(id, value,
SecureContextMode::kInsecureContext, nullptr);
keyframe->SetComposite(EffectModel::kCompositeReplace);
@@ -198,24 +210,22 @@ class AnimationCompositorAnimationsTest : public RenderingTest {
return keyframe;
}
- scoped_refptr<StringKeyframe> CreateDefaultKeyframe(
- CSSPropertyID id,
- EffectModel::CompositeOperation op,
- double offset = 0) {
+ StringKeyframe* CreateDefaultKeyframe(CSSPropertyID id,
+ EffectModel::CompositeOperation op,
+ double offset = 0) {
String value = "0.1";
if (id == CSSPropertyTransform)
value = "none"; // AnimatableTransform::Create(TransformOperations(), 1);
else if (id == CSSPropertyColor)
value = "red";
- scoped_refptr<StringKeyframe> keyframe =
- CreateReplaceOpKeyframe(id, value, offset);
+ StringKeyframe* keyframe = CreateReplaceOpKeyframe(id, value, offset);
keyframe->SetComposite(op);
return keyframe;
}
- std::unique_ptr<StringKeyframeVector> CreateCompositableFloatKeyframeVector(
- size_t n) {
+ PersistentHeapVector<Member<StringKeyframe>>
+ CreateCompositableFloatKeyframeVector(size_t n) {
Vector<double> values;
for (size_t i = 0; i < n; i++) {
values.push_back(static_cast<double>(i));
@@ -223,37 +233,134 @@ class AnimationCompositorAnimationsTest : public RenderingTest {
return CreateCompositableFloatKeyframeVector(values);
}
- std::unique_ptr<StringKeyframeVector> CreateCompositableFloatKeyframeVector(
- Vector<double>& values) {
- std::unique_ptr<StringKeyframeVector> frames =
- base::WrapUnique(new StringKeyframeVector);
+ PersistentHeapVector<Member<StringKeyframe>>
+ CreateCompositableFloatKeyframeVector(Vector<double>& values) {
+ PersistentHeapVector<Member<StringKeyframe>> frames;
for (size_t i = 0; i < values.size(); i++) {
double offset = 1.0 / (values.size() - 1) * i;
String value = String::Number(values[i]);
- frames->push_back(
- CreateReplaceOpKeyframe(CSSPropertyOpacity, value, offset).get());
+ frames.push_back(
+ CreateReplaceOpKeyframe(CSSPropertyOpacity, value, offset));
}
return frames;
}
- std::unique_ptr<StringKeyframeVector>
- CreateCompositableTransformKeyframeVector(const Vector<String>& values) {
- std::unique_ptr<StringKeyframeVector> frames =
- base::WrapUnique(new StringKeyframeVector);
+ // This class exists to dodge the interlock between creating animatable
+ // values iff we can animate them on the compositor, and hence can
+ // start their animations on it. i.e. two far away switch statements
+ // have matching non-default values, preventing us from testing the
+ // default.
+ class AnimatableMockStringKeyframe : public StringKeyframe {
+ public:
+ static StringKeyframe* Create(double offset) {
+ return new AnimatableMockStringKeyframe(offset);
+ }
+ Keyframe::PropertySpecificKeyframe* CreatePropertySpecificKeyframe(
+ const PropertyHandle&,
+ EffectModel::CompositeOperation,
+ double) const final {
+ return property_specific_; // We know a shortcut.
+ }
+
+ void Trace(Visitor* visitor) override {
+ visitor->Trace(property_specific_);
+ StringKeyframe::Trace(visitor);
+ }
+
+ private:
+ class AnimatableMockPropertySpecificStringKeyframe
+ : public PropertySpecificKeyframe {
+ public:
+ // Pretend to have an animatable value. Pick the offset for
+ // pure convenience: it matters not what it is.
+ AnimatableMockPropertySpecificStringKeyframe(double offset)
+ : PropertySpecificKeyframe(offset,
+ LinearTimingFunction::Shared(),
+ EffectModel::kCompositeReplace),
+ animatable_offset_(AnimatableDouble::Create(offset)) {}
+ bool IsNeutral() const final { return true; }
+ PropertySpecificKeyframe* CloneWithOffset(double) const final {
+ NOTREACHED();
+ return nullptr;
+ }
+ bool PopulateAnimatableValue(
+ const CSSProperty&,
+ Element&,
+ const ComputedStyle& base_style,
+ const ComputedStyle* parent_style) const final {
+ return true;
+ }
+ const AnimatableValue* GetAnimatableValue() const final {
+ return animatable_offset_;
+ }
+ bool IsAnimatableValuePropertySpecificKeyframe() const final {
+ return true;
+ }
+ PropertySpecificKeyframe* NeutralKeyframe(
+ double,
+ scoped_refptr<TimingFunction>) const final {
+ NOTREACHED();
+ return nullptr;
+ }
+
+ void Trace(Visitor* visitor) override {
+ visitor->Trace(animatable_offset_);
+ PropertySpecificKeyframe::Trace(visitor);
+ }
+
+ private:
+ Member<AnimatableDouble> animatable_offset_;
+ };
+
+ Member<PropertySpecificKeyframe> property_specific_;
+ AnimatableMockStringKeyframe(double offset)
+ : StringKeyframe(),
+ property_specific_(
+ new AnimatableMockPropertySpecificStringKeyframe(offset)) {
+ SetOffset(offset);
+ }
+ };
+
+ StringKeyframe* CreateAnimatableReplaceKeyframe(CSSPropertyID id,
+ const String& value,
+ double offset) {
+ StringKeyframe* keyframe = AnimatableMockStringKeyframe::Create(offset);
+ keyframe->SetCSSPropertyValue(id, value,
+ SecureContextMode::kInsecureContext, nullptr);
+ keyframe->SetComposite(EffectModel::kCompositeReplace);
+ keyframe->SetEasing(LinearTimingFunction::Shared());
+
+ return keyframe;
+ }
+
+ StringKeyframeVector* CreateCompositableTransformKeyframeVector(
+ const Vector<String>& values) {
+ StringKeyframeVector* frames = new StringKeyframeVector;
for (size_t i = 0; i < values.size(); ++i) {
double offset = 1.0f / (values.size() - 1) * i;
frames->push_back(
- CreateReplaceOpKeyframe(CSSPropertyTransform, values[i], offset)
- .get());
+ CreateReplaceOpKeyframe(CSSPropertyTransform, values[i], offset));
}
return frames;
}
+ StringKeyframe* CreateSVGKeyframe(const QualifiedName& name,
+ const String& value,
+ double offset) {
+ StringKeyframe* keyframe = StringKeyframe::Create();
+ keyframe->SetSVGAttributeValue(name, value);
+ keyframe->SetComposite(EffectModel::kCompositeReplace);
+ keyframe->SetOffset(offset);
+ keyframe->SetEasing(LinearTimingFunction::Shared());
+
+ return keyframe;
+ }
+
StringKeyframeEffectModel* CreateKeyframeEffectModel(
- scoped_refptr<StringKeyframe> from,
- scoped_refptr<StringKeyframe> to,
- scoped_refptr<StringKeyframe> c = nullptr,
- scoped_refptr<StringKeyframe> d = nullptr) {
+ StringKeyframe* from,
+ StringKeyframe* to,
+ StringKeyframe* c = nullptr,
+ StringKeyframe* d = nullptr) {
EXPECT_EQ(from->CheckedOffset(), 0);
StringKeyframeVector frames;
frames.push_back(from);
@@ -357,6 +464,11 @@ class LayoutObjectProxy : public LayoutObject {
return FloatRect();
}
+ void EnsureIdForTestingProxy() {
+ // We need Ids of proxies to be valid.
+ EnsureIdForTesting();
+ }
+
private:
explicit LayoutObjectProxy(Node* node) : LayoutObject(node) {}
};
@@ -366,76 +478,70 @@ class LayoutObjectProxy : public LayoutObject {
TEST_F(AnimationCompositorAnimationsTest,
CanStartEffectOnCompositorKeyframeMultipleCSSProperties) {
- scoped_refptr<StringKeyframe> keyframe_good_multiple =
+ StringKeyframe* keyframe_good_multiple =
CreateDefaultKeyframe(CSSPropertyOpacity, EffectModel::kCompositeReplace);
keyframe_good_multiple->SetCSSPropertyValue(
CSSPropertyTransform, "none", SecureContextMode::kInsecureContext,
nullptr);
EXPECT_TRUE(DuplicateSingleKeyframeAndTestIsCandidateOnResult(
- keyframe_good_multiple.get()));
+ keyframe_good_multiple));
- scoped_refptr<StringKeyframe> keyframe_bad_multiple_id =
+ StringKeyframe* keyframe_bad_multiple_id =
CreateDefaultKeyframe(CSSPropertyColor, EffectModel::kCompositeReplace);
keyframe_bad_multiple_id->SetCSSPropertyValue(
CSSPropertyOpacity, "0.1", SecureContextMode::kInsecureContext, nullptr);
EXPECT_FALSE(DuplicateSingleKeyframeAndTestIsCandidateOnResult(
- keyframe_bad_multiple_id.get()));
+ keyframe_bad_multiple_id));
}
TEST_F(AnimationCompositorAnimationsTest,
isNotCandidateForCompositorAnimationTransformDependsOnBoxSize) {
// Absolute transforms can be animated on the compositor.
String transform = "translateX(2px) translateY(2px)";
- scoped_refptr<StringKeyframe> good_keyframe =
+ StringKeyframe* good_keyframe =
CreateReplaceOpKeyframe(CSSPropertyTransform, transform);
- EXPECT_TRUE(
- DuplicateSingleKeyframeAndTestIsCandidateOnResult(good_keyframe.get()));
+ EXPECT_TRUE(DuplicateSingleKeyframeAndTestIsCandidateOnResult(good_keyframe));
// Transforms that rely on the box size, such as percent calculations, cannot
// be animated on the compositor (as the box size may change).
String transform2 = "translateX(50%) translateY(2px)";
- scoped_refptr<StringKeyframe> bad_keyframe =
+ StringKeyframe* bad_keyframe =
CreateReplaceOpKeyframe(CSSPropertyTransform, transform2);
- EXPECT_FALSE(
- DuplicateSingleKeyframeAndTestIsCandidateOnResult(bad_keyframe.get()));
+ EXPECT_FALSE(DuplicateSingleKeyframeAndTestIsCandidateOnResult(bad_keyframe));
// Similarly, calc transforms cannot be animated on the compositor.
String transform3 = "translateX(calc(100% + (0.5 * 100px)))";
- scoped_refptr<StringKeyframe> bad_keyframe2 =
+ StringKeyframe* bad_keyframe2 =
CreateReplaceOpKeyframe(CSSPropertyTransform, transform3);
EXPECT_FALSE(
- DuplicateSingleKeyframeAndTestIsCandidateOnResult(bad_keyframe2.get()));
+ DuplicateSingleKeyframeAndTestIsCandidateOnResult(bad_keyframe2));
}
TEST_F(AnimationCompositorAnimationsTest,
CanStartEffectOnCompositorKeyframeEffectModel) {
StringKeyframeVector frames_same;
- frames_same.push_back(CreateDefaultKeyframe(CSSPropertyColor,
- EffectModel::kCompositeReplace,
- 0.0)
- .get());
- frames_same.push_back(CreateDefaultKeyframe(CSSPropertyColor,
- EffectModel::kCompositeReplace,
- 1.0)
- .get());
+ frames_same.push_back(CreateDefaultKeyframe(
+ CSSPropertyColor, EffectModel::kCompositeReplace, 0.0));
+ frames_same.push_back(CreateDefaultKeyframe(
+ CSSPropertyColor, EffectModel::kCompositeReplace, 1.0));
EXPECT_FALSE(CanStartEffectOnCompositor(
timing_, *StringKeyframeEffectModel::Create(frames_same)));
StringKeyframeVector frames_mixed_properties;
- scoped_refptr<StringKeyframe> keyframe = StringKeyframe::Create();
+ StringKeyframe* keyframe = StringKeyframe::Create();
keyframe->SetOffset(0);
keyframe->SetCSSPropertyValue(CSSPropertyColor, "red",
SecureContextMode::kInsecureContext, nullptr);
keyframe->SetCSSPropertyValue(CSSPropertyOpacity, "0",
SecureContextMode::kInsecureContext, nullptr);
- frames_mixed_properties.push_back(std::move(keyframe));
+ frames_mixed_properties.push_back(keyframe);
keyframe = StringKeyframe::Create();
keyframe->SetOffset(1);
keyframe->SetCSSPropertyValue(CSSPropertyColor, "green",
SecureContextMode::kInsecureContext, nullptr);
keyframe->SetCSSPropertyValue(CSSPropertyOpacity, "1",
SecureContextMode::kInsecureContext, nullptr);
- frames_mixed_properties.push_back(std::move(keyframe));
+ frames_mixed_properties.push_back(keyframe);
EXPECT_FALSE(CanStartEffectOnCompositor(
timing_, *StringKeyframeEffectModel::Create(frames_mixed_properties)));
}
@@ -500,21 +606,6 @@ TEST_F(AnimationCompositorAnimationsTest,
EXPECT_TRUE(ConvertTimingForCompositor(timing_, compositor_timing_));
}
-TEST_F(AnimationCompositorAnimationsTest,
- ConvertTimingForCompositorPlaybackRate) {
- timing_.playback_rate = 1.0;
- EXPECT_TRUE(ConvertTimingForCompositor(timing_, compositor_timing_));
- EXPECT_DOUBLE_EQ(1.0, compositor_timing_.playback_rate);
-
- timing_.playback_rate = -2.3;
- EXPECT_TRUE(ConvertTimingForCompositor(timing_, compositor_timing_));
- EXPECT_DOUBLE_EQ(-2.3, compositor_timing_.playback_rate);
-
- timing_.playback_rate = 1.6;
- EXPECT_TRUE(ConvertTimingForCompositor(timing_, compositor_timing_));
- EXPECT_DOUBLE_EQ(1.6, compositor_timing_.playback_rate);
-}
-
TEST_F(AnimationCompositorAnimationsTest, ConvertTimingForCompositorDirection) {
timing_.direction = Timing::PlaybackDirection::NORMAL;
EXPECT_TRUE(ConvertTimingForCompositor(timing_, compositor_timing_));
@@ -630,13 +721,13 @@ TEST_F(AnimationCompositorAnimationsTest,
TEST_F(AnimationCompositorAnimationsTest,
CanStartEffectOnCompositorNonLinearTimingFunctionOnFirstOrLastFrame) {
- (*keyframe_vector2_)[0]->SetEasing(cubic_ease_timing_function_.get());
+ keyframe_vector2_[0]->SetEasing(cubic_ease_timing_function_.get());
keyframe_animation_effect2_ =
- StringKeyframeEffectModel::Create(*keyframe_vector2_);
+ StringKeyframeEffectModel::Create(keyframe_vector2_);
- (*keyframe_vector5_)[3]->SetEasing(cubic_ease_timing_function_.get());
+ keyframe_vector5_[3]->SetEasing(cubic_ease_timing_function_.get());
keyframe_animation_effect5_ =
- StringKeyframeEffectModel::Create(*keyframe_vector5_);
+ StringKeyframeEffectModel::Create(keyframe_vector5_);
timing_.timing_function = cubic_ease_timing_function_;
EXPECT_TRUE(
@@ -652,107 +743,418 @@ TEST_F(AnimationCompositorAnimationsTest,
}
TEST_F(AnimationCompositorAnimationsTest,
+ CanStartEffectOnCompositorFailuresProperties) {
+ // An effect with no keyframes has no Properties, so can not be composited.
+ StringKeyframeVector empty_keyframe_vector;
+ EXPECT_FALSE(CanStartEffectOnCompositor(
+ timing_, *StringKeyframeEffectModel::Create(empty_keyframe_vector)));
+}
+
+TEST_F(AnimationCompositorAnimationsTest,
+ CanStartElementOnCompositorEffectOpacity) {
+ Persistent<Element> element = GetDocument().CreateElementForBinding("shared");
+
+ LayoutObjectProxy* layout_object = LayoutObjectProxy::Create(element.Get());
+ layout_object->EnsureIdForTestingProxy();
+ element->SetLayoutObject(layout_object);
+
+ CompositorElementIdSet compositor_ids;
+ compositor_ids.insert(CompositorElementIdFromUniqueObjectId(
+ layout_object->UniqueId(), CompositorElementIdNamespace::kPrimary));
+
+ // We need an ID to be in the set, but not the same.
+ CompositorElementId different_id = CompositorElementIdFromUniqueObjectId(
+ layout_object->UniqueId(), CompositorElementIdNamespace::kEffectClipPath);
+ // Check that we got something effectively different.
+ EXPECT_FALSE(compositor_ids.Contains(different_id));
+ CompositorElementIdSet disjoint_ids;
+ compositor_ids.insert(different_id);
+
+ StringKeyframeVector key_frames;
+ key_frames.push_back(CreateDefaultKeyframe(
+ CSSPropertyOpacity, EffectModel::kCompositeReplace, 0.0));
+ key_frames.push_back(CreateDefaultKeyframe(
+ CSSPropertyOpacity, EffectModel::kCompositeReplace, 1.0));
+ KeyframeEffectModelBase* animation_effect =
+ StringKeyframeEffectModel::Create(key_frames);
+
+ Timing timing;
+ timing.iteration_duration = 1.f;
+ base::Optional<CompositorElementIdSet> none;
+
+ // The first animation for opacity is ok to run on compositor.
+ KeyframeEffect* keyframe_effect1 =
+ KeyframeEffect::Create(element.Get(), animation_effect, timing);
+ Animation* animation = timeline_->Play(keyframe_effect1);
+ auto style = ComputedStyle::Create();
+ animation_effect->SnapshotAllCompositorKeyframesIfNecessary(*element_.Get(),
+ *style, nullptr);
+
+ // Now we can check that we are set up correctly.
+ EXPECT_TRUE(CheckCanStartEffectOnCompositor(timing, *element.Get(), animation,
+ *animation_effect, none));
+ // ... and still true if we enable the checks for Composited ID.
+ EXPECT_TRUE(CheckCanStartEffectOnCompositor(
+ timing, *element.Get(), animation, *animation_effect, compositor_ids));
+
+ // Check out the failure modes. Now that the setup is done and tested,
+ // we get to exercising the failure paths without distraction.
+
+ // id not in set.
+ EXPECT_FALSE(CheckCanStartEffectOnCompositor(
+ timing, *element.Get(), animation, *animation_effect, disjoint_ids));
+
+ // No Layout Object
+ element->SetLayoutObject(nullptr);
+ EXPECT_FALSE(CheckCanStartEffectOnCompositor(
+ timing, *element.Get(), animation, *animation_effect, compositor_ids));
+ LayoutObjectProxy::Dispose(layout_object);
+ layout_object = nullptr;
+
+ // No layout Object Id
+ LayoutObjectProxy* new_layout_object =
+ LayoutObjectProxy::Create(element.Get());
+ element->SetLayoutObject(new_layout_object);
+ EXPECT_FALSE(CheckCanStartEffectOnCompositor(
+ timing, *element.Get(), animation, *animation_effect, compositor_ids));
+ new_layout_object->EnsureIdForTestingProxy();
+
+ // And back to the baseline.
+ EXPECT_TRUE(CheckCanStartEffectOnCompositor(timing, *element.Get(), animation,
+ *animation_effect, none));
+
+ // Timings have to be convertible for compostor.
+ compositor_ids.insert(CompositorElementIdFromUniqueObjectId(
+ new_layout_object->UniqueId(), CompositorElementIdNamespace::kPrimary));
+ EXPECT_TRUE(CheckCanStartEffectOnCompositor(
+ timing, *element.Get(), animation, *animation_effect, compositor_ids));
+ timing.end_delay = 1.0;
+ EXPECT_FALSE(CheckCanStartEffectOnCompositor(
+ timing, *element.Get(), animation, *animation_effect, compositor_ids));
+ EXPECT_FALSE(CheckCanStartEffectOnCompositor(
+ timing, *element.Get(), animation, *animation_effect, none));
+ element->SetLayoutObject(nullptr);
+ LayoutObjectProxy::Dispose(new_layout_object);
+}
+
+TEST_F(AnimationCompositorAnimationsTest,
+ CanStartElementOnCompositorEffectInvalid) {
+ base::Optional<CompositorElementIdSet> none;
+ auto style = ComputedStyle::Create();
+
+ Persistent<Element> element = GetDocument().CreateElementForBinding("shared");
+
+ LayoutObjectProxy* layout_object = LayoutObjectProxy::Create(element.Get());
+ layout_object->EnsureIdForTestingProxy();
+ element->SetLayoutObject(layout_object);
+
+ CompositorElementIdSet compositor_ids;
+ compositor_ids.insert(CompositorElementIdFromUniqueObjectId(
+ layout_object->UniqueId(), CompositorElementIdNamespace::kPrimary));
+
+ // Check that we notice the value is not animatable correctly.
+ const CSSProperty& target_property1(GetCSSPropertyOutlineStyle());
+ PropertyHandle target_property1h(target_property1);
+ StringKeyframeEffectModel* effect1 = CreateKeyframeEffectModel(
+ CreateReplaceOpKeyframe(target_property1.PropertyID(), "dotted", 0),
+ CreateReplaceOpKeyframe(target_property1.PropertyID(), "dashed", 1.0));
+
+ KeyframeEffect* keyframe_effect1 =
+ KeyframeEffect::Create(element.Get(), effect1, timing_);
+
+ Animation* animation1 = timeline_->Play(keyframe_effect1);
+ effect1->SnapshotAllCompositorKeyframesIfNecessary(*element_.Get(), *style,
+ nullptr);
+
+ EXPECT_EQ(2u,
+ effect1->GetPropertySpecificKeyframes(target_property1h).size());
+ EXPECT_FALSE(effect1->GetPropertySpecificKeyframes(target_property1h)[0]
+ ->GetAnimatableValue());
+ EXPECT_EQ(1u, effect1->Properties().size());
+ EXPECT_FALSE(CheckCanStartEffectOnCompositor(timing_, *element.Get(),
+ animation1, *effect1, none));
+
+ // Check that we notice the Property is not animatable correctly.
+ const CSSProperty& target_property2(GetCSSPropertyScale());
+ PropertyHandle target_property2h(target_property2);
+ StringKeyframeEffectModel* effect2 = CreateKeyframeEffectModel(
+ CreateReplaceOpKeyframe(target_property2.PropertyID(), "1", 0),
+ CreateReplaceOpKeyframe(target_property2.PropertyID(), "3", 1.0));
+
+ KeyframeEffect* keyframe_effect2 =
+ KeyframeEffect::Create(element.Get(), effect2, timing_);
+
+ Animation* animation2 = timeline_->Play(keyframe_effect2);
+ effect2->SnapshotAllCompositorKeyframesIfNecessary(*element_.Get(), *style,
+ nullptr);
+
+ EXPECT_EQ(2u,
+ effect2->GetPropertySpecificKeyframes(target_property2h).size());
+ EXPECT_TRUE(effect2->GetPropertySpecificKeyframes(target_property2h)[0]
+ ->GetAnimatableValue());
+ EXPECT_EQ(1u, effect2->Properties().size());
+ EXPECT_FALSE(CheckCanStartEffectOnCompositor(timing_, *element.Get(),
+ animation2, *effect2, none));
+
+ // Check that we notice the Property is not animatable correctly.
+ // These ones claim to have animatable values, but we can't composite
+ // the property. We also don't know the ID domain.
+ const CSSProperty& target_property3(GetCSSPropertyWidth());
+ PropertyHandle target_property3h(target_property3);
+ StringKeyframeEffectModel* effect3 = CreateKeyframeEffectModel(
+ CreateAnimatableReplaceKeyframe(target_property3.PropertyID(), "10px",
+ 0.0),
+ CreateAnimatableReplaceKeyframe(target_property3.PropertyID(), "20px",
+ 1.0));
+
+ KeyframeEffect* keyframe_effect3 =
+ KeyframeEffect::Create(element.Get(), effect3, timing_);
+
+ Animation* animation3 = timeline_->Play(keyframe_effect3);
+ effect3->SnapshotAllCompositorKeyframesIfNecessary(*element_.Get(), *style,
+ nullptr);
+
+ EXPECT_EQ(2u,
+ effect3->GetPropertySpecificKeyframes(target_property3h).size());
+ EXPECT_TRUE(effect3->GetPropertySpecificKeyframes(target_property3h)[0]
+ ->GetAnimatableValue());
+ EXPECT_EQ(1u, effect3->Properties().size());
+ EXPECT_FALSE(CheckCanStartEffectOnCompositor(timing_, *element.Get(),
+ animation3, *effect3, none));
+
+ element->SetLayoutObject(nullptr);
+ LayoutObjectProxy::Dispose(layout_object);
+}
+
+TEST_F(AnimationCompositorAnimationsTest,
+ CanStartElementOnCompositorEffectFilter) {
+ base::Optional<CompositorElementIdSet> none;
+
+ Persistent<Element> element = GetDocument().CreateElementForBinding("shared");
+
+ LayoutObjectProxy* layout_object = LayoutObjectProxy::Create(element.Get());
+ layout_object->EnsureIdForTestingProxy();
+ element->SetLayoutObject(layout_object);
+
+ CompositorElementIdSet compositor_ids;
+ compositor_ids.insert(CompositorElementIdFromUniqueObjectId(
+ layout_object->UniqueId(), CompositorElementIdNamespace::kEffectFilter));
+
+ CompositorElementId different_id = CompositorElementIdFromUniqueObjectId(
+ layout_object->UniqueId(), CompositorElementIdNamespace::kPrimary);
+ // Check that we got something effectively different.
+ EXPECT_FALSE(compositor_ids.Contains(different_id));
+ CompositorElementIdSet disjoint_ids;
+ compositor_ids.insert(different_id);
+
+ // Filter Properties use a different ID namespace
+ StringKeyframeEffectModel* effect1 = CreateKeyframeEffectModel(
+ CreateReplaceOpKeyframe(CSSPropertyFilter, "none", 0),
+ CreateReplaceOpKeyframe(CSSPropertyFilter, "sepia(50%)", 1.0));
+
+ KeyframeEffect* keyframe_effect1 =
+ KeyframeEffect::Create(element.Get(), effect1, timing_);
+
+ Animation* animation1 = timeline_->Play(keyframe_effect1);
+ auto style = ComputedStyle::Create();
+ effect1->SnapshotAllCompositorKeyframesIfNecessary(*element_.Get(), *style,
+ nullptr);
+
+ // Now we can check that we are set up correctly.
+ EXPECT_TRUE(CheckCanStartEffectOnCompositor(timing_, *element.Get(),
+ animation1, *effect1, none));
+ // ... and still true if we enable the checks for Composited ID.
+ EXPECT_TRUE(CheckCanStartEffectOnCompositor(
+ timing_, *element.Get(), animation1, *effect1, compositor_ids));
+ // ... but not if we are not in the set.
+ EXPECT_FALSE(CheckCanStartEffectOnCompositor(
+ timing_, *element.Get(), animation1, *effect1, disjoint_ids));
+
+ // Filters that affect neighboring pixels can't be composited.
+ StringKeyframeEffectModel* effect2 = CreateKeyframeEffectModel(
+ CreateReplaceOpKeyframe(CSSPropertyFilter, "none", 0),
+ CreateReplaceOpKeyframe(CSSPropertyFilter, "blur(10px)", 1.0));
+
+ KeyframeEffect* keyframe_effect2 =
+ KeyframeEffect::Create(element.Get(), effect2, timing_);
+
+ Animation* animation2 = timeline_->Play(keyframe_effect2);
+ effect2->SnapshotAllCompositorKeyframesIfNecessary(*element_.Get(), *style,
+ nullptr);
+ EXPECT_FALSE(CheckCanStartEffectOnCompositor(
+ timing_, *element.Get(), animation2, *effect2, compositor_ids));
+
+ EXPECT_FALSE(CheckCanStartEffectOnCompositor(timing_, *element.Get(),
+ animation2, *effect2, none));
+
+ element->SetLayoutObject(nullptr);
+ LayoutObjectProxy::Dispose(layout_object);
+}
+
+TEST_F(AnimationCompositorAnimationsTest,
+ CanStartElementOnCompositorEffectTransform) {
+ Persistent<Element> element = GetDocument().CreateElementForBinding("shared");
+
+ LayoutObjectProxy* layout_object = LayoutObjectProxy::Create(element.Get());
+ layout_object->EnsureIdForTestingProxy();
+ element->SetLayoutObject(layout_object);
+
+ CompositorElementIdSet compositor_ids;
+ compositor_ids.insert(CompositorElementIdFromUniqueObjectId(
+ layout_object->UniqueId(), CompositorElementIdNamespace::kPrimary));
+
+ CompositorElementId different_id = CompositorElementIdFromUniqueObjectId(
+ layout_object->UniqueId(), CompositorElementIdNamespace::kEffectFilter);
+ // Check that we got something effectively different.
+ EXPECT_FALSE(compositor_ids.Contains(different_id));
+ CompositorElementIdSet disjoint_ids;
+ compositor_ids.insert(different_id);
+
+ base::Optional<CompositorElementIdSet> none;
+ auto style = ComputedStyle::Create();
+
+ StringKeyframeEffectModel* effect1 = CreateKeyframeEffectModel(
+ CreateReplaceOpKeyframe(CSSPropertyTransform, "none", 0),
+ CreateReplaceOpKeyframe(CSSPropertyTransform, "rotate(45deg)", 1.0));
+
+ KeyframeEffect* keyframe_effect1 =
+ KeyframeEffect::Create(element.Get(), effect1, timing_);
+
+ Animation* animation1 = timeline_->Play(keyframe_effect1);
+ effect1->SnapshotAllCompositorKeyframesIfNecessary(*element_.Get(), *style,
+ nullptr);
+
+ // our Layout object is not TransformApplicable
+ EXPECT_FALSE(layout_object->IsBox());
+ EXPECT_FALSE(CheckCanStartEffectOnCompositor(timing_, *element.Get(),
+ animation1, *effect1, none));
+ // Now we can check that we are set up correctly.
+ layout_object->SetIsBox();
+ EXPECT_TRUE(CheckCanStartEffectOnCompositor(timing_, *element.Get(),
+ animation1, *effect1, none));
+ // ... and still true if we enable the checks for Composited ID.
+ EXPECT_TRUE(CheckCanStartEffectOnCompositor(
+ timing_, *element.Get(), animation1, *effect1, compositor_ids));
+ // ... but not if we are not in the set.
+ EXPECT_FALSE(CheckCanStartEffectOnCompositor(
+ timing_, *element.Get(), animation1, *effect1, disjoint_ids));
+
+ StringKeyframeEffectModel* effect2 = CreateKeyframeEffectModel(
+ CreateReplaceOpKeyframe(CSSPropertyTransform, "translateX(-45px)", 0),
+ CreateReplaceOpKeyframe(CSSPropertyRotate, "none", 0),
+ CreateReplaceOpKeyframe(CSSPropertyTransform, "translateX(45px)", 1.0),
+ CreateReplaceOpKeyframe(CSSPropertyRotate, "45deg", 1.0));
+
+ KeyframeEffect* keyframe_effect2 =
+ KeyframeEffect::Create(element.Get(), effect2, timing_);
+
+ Animation* animation2 = timeline_->Play(keyframe_effect2);
+ effect2->SnapshotAllCompositorKeyframesIfNecessary(*element_.Get(), *style,
+ nullptr);
+
+ // our Layout object is not TransformApplicable
+ EXPECT_FALSE(CheckCanStartEffectOnCompositor(timing_, *element.Get(),
+ animation2, *effect2, none));
+ // ... and still declined if we enable the checks for Composited ID.
+ EXPECT_FALSE(CheckCanStartEffectOnCompositor(
+ timing_, *element.Get(), animation2, *effect2, compositor_ids));
+
+ element->SetLayoutObject(nullptr);
+ LayoutObjectProxy::Dispose(layout_object);
+}
+
+TEST_F(AnimationCompositorAnimationsTest,
CanStartEffectOnCompositorTimingFunctionChainedCubicMatchingOffsets) {
- (*keyframe_vector2_)[0]->SetEasing(cubic_ease_timing_function_.get());
+ keyframe_vector2_[0]->SetEasing(cubic_ease_timing_function_.get());
keyframe_animation_effect2_ =
- StringKeyframeEffectModel::Create(*keyframe_vector2_);
+ StringKeyframeEffectModel::Create(keyframe_vector2_);
EXPECT_TRUE(
CanStartEffectOnCompositor(timing_, *keyframe_animation_effect2_));
- (*keyframe_vector2_)[0]->SetEasing(cubic_custom_timing_function_.get());
+ keyframe_vector2_[0]->SetEasing(cubic_custom_timing_function_.get());
keyframe_animation_effect2_ =
- StringKeyframeEffectModel::Create(*keyframe_vector2_);
+ StringKeyframeEffectModel::Create(keyframe_vector2_);
EXPECT_TRUE(
CanStartEffectOnCompositor(timing_, *keyframe_animation_effect2_));
- (*keyframe_vector5_)[0]->SetEasing(cubic_ease_timing_function_.get());
- (*keyframe_vector5_)[1]->SetEasing(cubic_custom_timing_function_.get());
- (*keyframe_vector5_)[2]->SetEasing(cubic_custom_timing_function_.get());
- (*keyframe_vector5_)[3]->SetEasing(cubic_custom_timing_function_.get());
+ keyframe_vector5_[0]->SetEasing(cubic_ease_timing_function_.get());
+ keyframe_vector5_[1]->SetEasing(cubic_custom_timing_function_.get());
+ keyframe_vector5_[2]->SetEasing(cubic_custom_timing_function_.get());
+ keyframe_vector5_[3]->SetEasing(cubic_custom_timing_function_.get());
keyframe_animation_effect5_ =
- StringKeyframeEffectModel::Create(*keyframe_vector5_);
+ StringKeyframeEffectModel::Create(keyframe_vector5_);
EXPECT_TRUE(
CanStartEffectOnCompositor(timing_, *keyframe_animation_effect5_));
}
TEST_F(AnimationCompositorAnimationsTest,
CanStartEffectOnCompositorTimingFunctionMixedGood) {
- (*keyframe_vector5_)[0]->SetEasing(linear_timing_function_.get());
- (*keyframe_vector5_)[1]->SetEasing(cubic_ease_timing_function_.get());
- (*keyframe_vector5_)[2]->SetEasing(cubic_ease_timing_function_.get());
- (*keyframe_vector5_)[3]->SetEasing(linear_timing_function_.get());
+ keyframe_vector5_[0]->SetEasing(linear_timing_function_.get());
+ keyframe_vector5_[1]->SetEasing(cubic_ease_timing_function_.get());
+ keyframe_vector5_[2]->SetEasing(cubic_ease_timing_function_.get());
+ keyframe_vector5_[3]->SetEasing(linear_timing_function_.get());
keyframe_animation_effect5_ =
- StringKeyframeEffectModel::Create(*keyframe_vector5_);
+ StringKeyframeEffectModel::Create(keyframe_vector5_);
EXPECT_TRUE(
CanStartEffectOnCompositor(timing_, *keyframe_animation_effect5_));
}
TEST_F(AnimationCompositorAnimationsTest,
CanStartEffectOnCompositorTimingFunctionWithStepOrFrameOkay) {
- (*keyframe_vector2_)[0]->SetEasing(step_timing_function_.get());
+ keyframe_vector2_[0]->SetEasing(step_timing_function_.get());
keyframe_animation_effect2_ =
- StringKeyframeEffectModel::Create(*keyframe_vector2_);
+ StringKeyframeEffectModel::Create(keyframe_vector2_);
EXPECT_TRUE(
CanStartEffectOnCompositor(timing_, *keyframe_animation_effect2_));
- (*keyframe_vector2_)[0]->SetEasing(frames_timing_function_.get());
+ keyframe_vector2_[0]->SetEasing(frames_timing_function_.get());
keyframe_animation_effect2_ =
- StringKeyframeEffectModel::Create(*keyframe_vector2_);
+ StringKeyframeEffectModel::Create(keyframe_vector2_);
EXPECT_TRUE(
CanStartEffectOnCompositor(timing_, *keyframe_animation_effect2_));
- (*keyframe_vector5_)[0]->SetEasing(step_timing_function_.get());
- (*keyframe_vector5_)[1]->SetEasing(linear_timing_function_.get());
- (*keyframe_vector5_)[2]->SetEasing(cubic_ease_timing_function_.get());
- (*keyframe_vector5_)[3]->SetEasing(frames_timing_function_.get());
+ keyframe_vector5_[0]->SetEasing(step_timing_function_.get());
+ keyframe_vector5_[1]->SetEasing(linear_timing_function_.get());
+ keyframe_vector5_[2]->SetEasing(cubic_ease_timing_function_.get());
+ keyframe_vector5_[3]->SetEasing(frames_timing_function_.get());
keyframe_animation_effect5_ =
- StringKeyframeEffectModel::Create(*keyframe_vector5_);
+ StringKeyframeEffectModel::Create(keyframe_vector5_);
EXPECT_TRUE(
CanStartEffectOnCompositor(timing_, *keyframe_animation_effect5_));
- (*keyframe_vector5_)[0]->SetEasing(frames_timing_function_.get());
- (*keyframe_vector5_)[1]->SetEasing(step_timing_function_.get());
- (*keyframe_vector5_)[2]->SetEasing(cubic_ease_timing_function_.get());
- (*keyframe_vector5_)[3]->SetEasing(linear_timing_function_.get());
+ keyframe_vector5_[0]->SetEasing(frames_timing_function_.get());
+ keyframe_vector5_[1]->SetEasing(step_timing_function_.get());
+ keyframe_vector5_[2]->SetEasing(cubic_ease_timing_function_.get());
+ keyframe_vector5_[3]->SetEasing(linear_timing_function_.get());
keyframe_animation_effect5_ =
- StringKeyframeEffectModel::Create(*keyframe_vector5_);
+ StringKeyframeEffectModel::Create(keyframe_vector5_);
EXPECT_TRUE(
CanStartEffectOnCompositor(timing_, *keyframe_animation_effect5_));
- (*keyframe_vector5_)[0]->SetEasing(linear_timing_function_.get());
- (*keyframe_vector5_)[1]->SetEasing(frames_timing_function_.get());
- (*keyframe_vector5_)[2]->SetEasing(cubic_ease_timing_function_.get());
- (*keyframe_vector5_)[3]->SetEasing(step_timing_function_.get());
+ keyframe_vector5_[0]->SetEasing(linear_timing_function_.get());
+ keyframe_vector5_[1]->SetEasing(frames_timing_function_.get());
+ keyframe_vector5_[2]->SetEasing(cubic_ease_timing_function_.get());
+ keyframe_vector5_[3]->SetEasing(step_timing_function_.get());
keyframe_animation_effect5_ =
- StringKeyframeEffectModel::Create(*keyframe_vector5_);
+ StringKeyframeEffectModel::Create(keyframe_vector5_);
EXPECT_TRUE(
CanStartEffectOnCompositor(timing_, *keyframe_animation_effect5_));
}
-TEST_F(AnimationCompositorAnimationsTest, CanStartEffectOnCompositor) {
+TEST_F(AnimationCompositorAnimationsTest, CanStartEffectOnCompositorBasic) {
StringKeyframeVector basic_frames_vector;
- basic_frames_vector.push_back(
- CreateDefaultKeyframe(CSSPropertyOpacity, EffectModel::kCompositeReplace,
- 0.0)
- .get());
- basic_frames_vector.push_back(
- CreateDefaultKeyframe(CSSPropertyOpacity, EffectModel::kCompositeReplace,
- 1.0)
- .get());
+ basic_frames_vector.push_back(CreateDefaultKeyframe(
+ CSSPropertyOpacity, EffectModel::kCompositeReplace, 0.0));
+ basic_frames_vector.push_back(CreateDefaultKeyframe(
+ CSSPropertyOpacity, EffectModel::kCompositeReplace, 1.0));
StringKeyframeVector non_basic_frames_vector;
- non_basic_frames_vector.push_back(
- CreateDefaultKeyframe(CSSPropertyOpacity, EffectModel::kCompositeReplace,
- 0.0)
- .get());
- non_basic_frames_vector.push_back(
- CreateDefaultKeyframe(CSSPropertyOpacity, EffectModel::kCompositeReplace,
- 0.5)
- .get());
- non_basic_frames_vector.push_back(
- CreateDefaultKeyframe(CSSPropertyOpacity, EffectModel::kCompositeReplace,
- 1.0)
- .get());
+ non_basic_frames_vector.push_back(CreateDefaultKeyframe(
+ CSSPropertyOpacity, EffectModel::kCompositeReplace, 0.0));
+ non_basic_frames_vector.push_back(CreateDefaultKeyframe(
+ CSSPropertyOpacity, EffectModel::kCompositeReplace, 0.5));
+ non_basic_frames_vector.push_back(CreateDefaultKeyframe(
+ CSSPropertyOpacity, EffectModel::kCompositeReplace, 1.0));
basic_frames_vector[0]->SetEasing(linear_timing_function_.get());
StringKeyframeEffectModel* basic_frames =
@@ -770,6 +1172,33 @@ TEST_F(AnimationCompositorAnimationsTest, CanStartEffectOnCompositor) {
StringKeyframeEffectModel* non_basic_frames =
StringKeyframeEffectModel::Create(non_basic_frames_vector);
EXPECT_TRUE(CanStartEffectOnCompositor(timing_, *non_basic_frames));
+
+ StringKeyframeVector non_allowed_frames_vector;
+ non_allowed_frames_vector.push_back(CreateDefaultKeyframe(
+ CSSPropertyOpacity, EffectModel::kCompositeAdd, 0.1));
+ non_allowed_frames_vector.push_back(CreateDefaultKeyframe(
+ CSSPropertyOpacity, EffectModel::kCompositeAdd, 0.25));
+ StringKeyframeEffectModel* non_allowed_frames =
+ StringKeyframeEffectModel::Create(non_allowed_frames_vector);
+ EXPECT_FALSE(CanStartEffectOnCompositor(timing_, *non_allowed_frames));
+
+ StringKeyframeVector empty_frames_vector;
+ StringKeyframeEffectModel* empty_frames =
+ StringKeyframeEffectModel::Create(empty_frames_vector);
+ EXPECT_FALSE(CanStartEffectOnCompositor(timing_, *empty_frames));
+
+ // Set SVGAttribute keeps a pointer to this thing for the lifespan of
+ // the Keyframe. This is ugly but sufficient to work around it.
+ QualifiedName fake_name("prefix", "local", "uri");
+
+ StringKeyframeVector non_css_frames_vector;
+ non_css_frames_vector.push_back(CreateSVGKeyframe(fake_name, "cargo", 0.0));
+ non_css_frames_vector.push_back(CreateSVGKeyframe(fake_name, "cargo", 1.0));
+ StringKeyframeEffectModel* non_css_frames =
+ StringKeyframeEffectModel::Create(non_css_frames_vector);
+ EXPECT_FALSE(CanStartEffectOnCompositor(timing_, *non_css_frames));
+ // NB: Important that non_css_frames_vector goes away and cleans up
+ // before fake_name.
}
// -----------------------------------------------------------------------
@@ -842,10 +1271,9 @@ TEST_F(AnimationCompositorAnimationsTest,
timing_.iteration_count = 5;
timing_.direction = Timing::PlaybackDirection::ALTERNATE_NORMAL;
- timing_.playback_rate = 2.0;
std::unique_ptr<CompositorKeyframeModel> keyframe_model =
- ConvertToCompositorAnimation(*effect);
+ ConvertToCompositorAnimation(*effect, 2.0);
EXPECT_EQ(CompositorTargetProperty::OPACITY,
keyframe_model->TargetProperty());
EXPECT_EQ(5.0, keyframe_model->Iterations());
@@ -1064,37 +1492,6 @@ TEST_F(AnimationCompositorAnimationsTest,
}
TEST_F(AnimationCompositorAnimationsTest,
- createSimpleOpacityAnimationPlaybackRates) {
- // KeyframeEffect to convert
- StringKeyframeEffectModel* effect = CreateKeyframeEffectModel(
- CreateReplaceOpKeyframe(CSSPropertyOpacity, "0.2", 0),
- CreateReplaceOpKeyframe(CSSPropertyOpacity, "0.5", 1.0));
-
- const double kPlaybackRate = 2;
- const double kAnimationPlaybackRate = -1.5;
-
- timing_.playback_rate = kPlaybackRate;
-
- std::unique_ptr<CompositorKeyframeModel> keyframe_model =
- ConvertToCompositorAnimation(*effect, kAnimationPlaybackRate);
- EXPECT_EQ(CompositorTargetProperty::OPACITY,
- keyframe_model->TargetProperty());
- EXPECT_EQ(1.0, keyframe_model->Iterations());
- EXPECT_EQ(0, keyframe_model->TimeOffset());
- EXPECT_EQ(CompositorKeyframeModel::Direction::NORMAL,
- keyframe_model->GetDirection());
- EXPECT_EQ(kPlaybackRate * kAnimationPlaybackRate,
- keyframe_model->PlaybackRate());
-
- std::unique_ptr<CompositorFloatAnimationCurve> keyframed_float_curve =
- keyframe_model->FloatCurveForTesting();
-
- CompositorFloatAnimationCurve::Keyframes keyframes =
- keyframed_float_curve->KeyframesForTesting();
- ASSERT_EQ(2UL, keyframes.size());
-}
-
-TEST_F(AnimationCompositorAnimationsTest,
createSimpleOpacityAnimationFillModeNone) {
// KeyframeEffect to convert
StringKeyframeEffectModel* effect = CreateKeyframeEffectModel(
@@ -1177,19 +1574,17 @@ TEST_F(AnimationCompositorAnimationsTest,
TEST_F(AnimationCompositorAnimationsTest,
cancelIncompatibleCompositorAnimations) {
Persistent<Element> element = GetDocument().CreateElementForBinding("shared");
+ base::Optional<CompositorElementIdSet> none;
LayoutObjectProxy* layout_object = LayoutObjectProxy::Create(element.Get());
+ layout_object->EnsureIdForTestingProxy();
element->SetLayoutObject(layout_object);
- StringKeyframeVector key_frames;
- key_frames.push_back(CreateDefaultKeyframe(CSSPropertyOpacity,
- EffectModel::kCompositeReplace,
- 0.0)
- .get());
- key_frames.push_back(CreateDefaultKeyframe(CSSPropertyOpacity,
- EffectModel::kCompositeReplace,
- 1.0)
- .get());
+ PersistentHeapVector<Member<StringKeyframe>> key_frames;
+ key_frames.push_back(CreateDefaultKeyframe(
+ CSSPropertyOpacity, EffectModel::kCompositeReplace, 0.0));
+ key_frames.push_back(CreateDefaultKeyframe(
+ CSSPropertyOpacity, EffectModel::kCompositeReplace, 1.0));
KeyframeEffectModelBase* animation_effect1 =
StringKeyframeEffectModel::Create(key_frames);
KeyframeEffectModelBase* animation_effect2 =
@@ -1205,9 +1600,8 @@ TEST_F(AnimationCompositorAnimationsTest,
auto style = ComputedStyle::Create();
animation_effect1->SnapshotAllCompositorKeyframesIfNecessary(*element_.Get(),
*style, nullptr);
- EXPECT_TRUE(CompositorAnimations::CheckCanStartEffectOnCompositor(
- timing, *element.Get(), animation1, *animation_effect1, 1)
- .Ok());
+ EXPECT_TRUE(CheckCanStartEffectOnCompositor(
+ timing, *element.Get(), animation1, *animation_effect1, none));
// simulate KeyframeEffect::maybeStartAnimationOnCompositor
Vector<int> compositor_keyframe_model_ids;
@@ -1222,9 +1616,8 @@ TEST_F(AnimationCompositorAnimationsTest,
Animation* animation2 = timeline_->Play(keyframe_effect2);
animation_effect2->SnapshotAllCompositorKeyframesIfNecessary(*element_.Get(),
*style, nullptr);
- EXPECT_FALSE(CompositorAnimations::CheckCanStartEffectOnCompositor(
- timing, *element.Get(), animation2, *animation_effect2, 1)
- .Ok());
+ EXPECT_FALSE(CheckCanStartEffectOnCompositor(
+ timing, *element.Get(), animation2, *animation_effect2, none));
EXPECT_FALSE(animation2->HasActiveAnimationsOnCompositor());
// A fallback to blink implementation needed, so cancel all compositor-side
@@ -1268,6 +1661,7 @@ TEST_F(AnimationCompositorAnimationsTest,
canStartElementOnCompositorTransformSPv2) {
Persistent<Element> element = GetDocument().CreateElementForBinding("shared");
LayoutObjectProxy* layout_object = LayoutObjectProxy::Create(element.Get());
+ layout_object->EnsureIdForTestingProxy();
element->SetLayoutObject(layout_object);
ScopedSlimmingPaintV2ForTest enable_s_pv2(true);
@@ -1300,6 +1694,7 @@ TEST_F(AnimationCompositorAnimationsTest,
canStartElementOnCompositorEffectSPv2) {
Persistent<Element> element = GetDocument().CreateElementForBinding("shared");
LayoutObjectProxy* layout_object = LayoutObjectProxy::Create(element.Get());
+ layout_object->EnsureIdForTestingProxy();
element->SetLayoutObject(layout_object);
ScopedSlimmingPaintV2ForTest enable_s_pv2(true);
diff --git a/chromium/third_party/blink/renderer/core/animation/css/css_animatable_value_factory.cc b/chromium/third_party/blink/renderer/core/animation/css/css_animatable_value_factory.cc
index 572fa057055..c8dee3ece6c 100644
--- a/chromium/third_party/blink/renderer/core/animation/css/css_animatable_value_factory.cc
+++ b/chromium/third_party/blink/renderer/core/animation/css/css_animatable_value_factory.cc
@@ -39,7 +39,7 @@
namespace blink {
-static scoped_refptr<AnimatableValue> CreateFromTransformProperties(
+static AnimatableValue* CreateFromTransformProperties(
scoped_refptr<TransformOperation> transform,
double zoom,
scoped_refptr<TransformOperation> initial_transform) {
@@ -52,9 +52,8 @@ static scoped_refptr<AnimatableValue> CreateFromTransformProperties(
return AnimatableTransform::Create(operation, has_transform ? zoom : 1);
}
-scoped_refptr<AnimatableValue> CSSAnimatableValueFactory::Create(
- const CSSProperty& property,
- const ComputedStyle& style) {
+AnimatableValue* CSSAnimatableValueFactory::Create(const CSSProperty& property,
+ const ComputedStyle& style) {
DCHECK(property.IsInterpolable());
DCHECK(property.IsCompositableProperty());
switch (property.PropertyID()) {
diff --git a/chromium/third_party/blink/renderer/core/animation/css/css_animatable_value_factory.h b/chromium/third_party/blink/renderer/core/animation/css/css_animatable_value_factory.h
index 8fc0934c678..1ef40807fd3 100644
--- a/chromium/third_party/blink/renderer/core/animation/css/css_animatable_value_factory.h
+++ b/chromium/third_party/blink/renderer/core/animation/css/css_animatable_value_factory.h
@@ -31,7 +31,6 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_CSS_ANIMATABLE_VALUE_FACTORY_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_CSS_ANIMATABLE_VALUE_FACTORY_H_
-#include "base/memory/scoped_refptr.h"
#include "third_party/blink/renderer/core/animation/animatable/animatable_value.h"
#include "third_party/blink/renderer/core/css/properties/css_property.h"
#include "third_party/blink/renderer/core/css_property_names.h"
@@ -45,8 +44,7 @@ class CSSAnimatableValueFactory {
STATIC_ONLY(CSSAnimatableValueFactory);
public:
- static scoped_refptr<AnimatableValue> Create(const CSSProperty&,
- const ComputedStyle&);
+ static AnimatableValue* Create(const CSSProperty&, const ComputedStyle&);
};
} // 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 0b795b63b0f..3c3d982707c 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
@@ -258,6 +258,10 @@ class CSSAnimationUpdate final {
visitor->Trace(suppressed_animations_);
visitor->Trace(animations_with_updates_);
visitor->Trace(updated_compositor_keyframes_);
+ visitor->Trace(active_interpolations_for_custom_animations_);
+ visitor->Trace(active_interpolations_for_standard_animations_);
+ visitor->Trace(active_interpolations_for_custom_transitions_);
+ visitor->Trace(active_interpolations_for_standard_transitions_);
}
private:
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 b78f42e859a..9e3efa072e5 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
@@ -56,6 +56,7 @@
#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/element.h"
+#include "third_party/blink/renderer/core/dom/events/event_path.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/dom/pseudo_element.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
@@ -99,7 +100,7 @@ StringKeyframeEffectModel* CreateKeyframeEffectModel(
PropertySet specified_properties_for_use_counter;
for (size_t i = 0; i < style_keyframes.size(); ++i) {
const StyleRuleKeyframe* style_keyframe = style_keyframes[i].Get();
- scoped_refptr<StringKeyframe> keyframe = StringKeyframe::Create();
+ StringKeyframe* keyframe = StringKeyframe::Create();
const Vector<double>& offsets = style_keyframe->Keys();
DCHECK(!offsets.IsEmpty());
keyframe->SetOffset(offsets[0]);
@@ -130,7 +131,7 @@ StringKeyframeEffectModel* CreateKeyframeEffectModel(
// The last keyframe specified at a given offset is used.
for (size_t j = 1; j < offsets.size(); ++j) {
keyframes.push_back(
- ToStringKeyframe(keyframe->CloneWithOffset(offsets[j]).get()));
+ ToStringKeyframe(keyframe->CloneWithOffset(offsets[j])));
}
}
@@ -148,11 +149,10 @@ StringKeyframeEffectModel* CreateKeyframeEffectModel(
}
// Merge duplicate keyframes.
- std::stable_sort(
- keyframes.begin(), keyframes.end(),
- [](const scoped_refptr<Keyframe>& a, const scoped_refptr<Keyframe>& b) {
- return a->CheckedOffset() < b->CheckedOffset();
- });
+ std::stable_sort(keyframes.begin(), keyframes.end(),
+ [](const Member<Keyframe>& a, const Member<Keyframe>& b) {
+ return a->CheckedOffset() < b->CheckedOffset();
+ });
size_t target_index = 0;
for (size_t i = 1; i < keyframes.size(); i++) {
if (keyframes[i]->CheckedOffset() ==
@@ -171,15 +171,14 @@ StringKeyframeEffectModel* CreateKeyframeEffectModel(
keyframes.Shrink(target_index + 1);
// Add 0% and 100% keyframes if absent.
- scoped_refptr<StringKeyframe> start_keyframe =
- keyframes.IsEmpty() ? nullptr : keyframes[0];
+ StringKeyframe* start_keyframe = keyframes.IsEmpty() ? nullptr : keyframes[0];
if (!start_keyframe || keyframes[0]->CheckedOffset() != 0) {
start_keyframe = StringKeyframe::Create();
start_keyframe->SetOffset(0);
start_keyframe->SetEasing(default_timing_function);
keyframes.push_front(start_keyframe);
}
- scoped_refptr<StringKeyframe> end_keyframe = keyframes[keyframes.size() - 1];
+ StringKeyframe* end_keyframe = keyframes[keyframes.size() - 1];
if (end_keyframe->CheckedOffset() != 1) {
end_keyframe = StringKeyframe::Create();
end_keyframe->SetOffset(1);
@@ -207,7 +206,7 @@ std::unique_ptr<TypedInterpolationValue> SampleAnimation(
KeyframeEffect* effect = ToKeyframeEffect(animation->effect());
InertEffect* inert_animation_for_sampling = InertEffect::Create(
effect->Model(), effect->SpecifiedTiming(), false, inherited_time);
- Vector<scoped_refptr<Interpolation>> sample;
+ HeapVector<Member<Interpolation>> sample;
inert_animation_for_sampling->Sample(sample);
// Transition animation has only animated a single property or is not in
// effect.
@@ -502,10 +501,11 @@ void CSSAnimations::MaybeApplyPendingUpdate(Element* element) {
animation->SetCompositorPending(true);
for (const auto& entry : pending_update_.AnimationsWithUpdates()) {
- KeyframeEffect* effect = ToKeyframeEffect(entry.animation->effect());
-
- effect->SetModel(entry.effect->Model());
- effect->UpdateSpecifiedTiming(entry.effect->SpecifiedTiming());
+ if (entry.animation->effect()) {
+ KeyframeEffect* effect = ToKeyframeEffect(entry.animation->effect());
+ effect->SetModel(entry.effect->Model());
+ effect->UpdateSpecifiedTiming(entry.effect->SpecifiedTiming());
+ }
running_animations_[entry.index]->Update(entry);
}
@@ -795,16 +795,14 @@ void CSSAnimations::CalculateTransitionUpdateForProperty(
timing.start_delay = 0;
}
- scoped_refptr<TransitionKeyframe> delay_keyframe =
- TransitionKeyframe::Create(property);
+ TransitionKeyframe* delay_keyframe = TransitionKeyframe::Create(property);
delay_keyframe->SetValue(TypedInterpolationValue::Create(
*transition_type, start.interpolable_value->Clone(),
start.non_interpolable_value));
delay_keyframe->SetOffset(0);
keyframes.push_back(delay_keyframe);
- scoped_refptr<TransitionKeyframe> start_keyframe =
- TransitionKeyframe::Create(property);
+ TransitionKeyframe* start_keyframe = TransitionKeyframe::Create(property);
start_keyframe->SetValue(TypedInterpolationValue::Create(
*transition_type, start.interpolable_value->Clone(),
start.non_interpolable_value));
@@ -813,8 +811,7 @@ void CSSAnimations::CalculateTransitionUpdateForProperty(
timing.timing_function = LinearTimingFunction::Shared();
keyframes.push_back(start_keyframe);
- scoped_refptr<TransitionKeyframe> end_keyframe =
- TransitionKeyframe::Create(property);
+ TransitionKeyframe* end_keyframe = TransitionKeyframe::Create(property);
end_keyframe->SetValue(TypedInterpolationValue::Create(
*transition_type, end.interpolable_value->Clone(),
end.non_interpolable_value));
@@ -822,9 +819,9 @@ void CSSAnimations::CalculateTransitionUpdateForProperty(
keyframes.push_back(end_keyframe);
if (property.GetCSSProperty().IsCompositableProperty()) {
- scoped_refptr<AnimatableValue> from = CSSAnimatableValueFactory::Create(
+ AnimatableValue* from = CSSAnimatableValueFactory::Create(
property.GetCSSProperty(), state.old_style);
- scoped_refptr<AnimatableValue> to = CSSAnimatableValueFactory::Create(
+ AnimatableValue* to = CSSAnimatableValueFactory::Create(
property.GetCSSProperty(), state.style);
delay_keyframe->SetCompositorValue(from);
start_keyframe->SetCompositorValue(from);
@@ -865,7 +862,8 @@ void CSSAnimations::CalculateTransitionUpdateForCustomProperty(
void CSSAnimations::CalculateTransitionUpdateForStandardProperty(
TransitionUpdateState& state,
const CSSTransitionData::TransitionProperty& transition_property,
- size_t transition_index) {
+ size_t transition_index,
+ const ComputedStyle& style) {
if (transition_property.property_type !=
CSSTransitionData::kTransitionKnownProperty) {
return;
@@ -884,7 +882,10 @@ void CSSAnimations::CalculateTransitionUpdateForStandardProperty(
property_list.length() ? property_list.properties()[i]->PropertyID()
: resolved_id;
DCHECK_GE(longhand_id, firstCSSProperty);
- const CSSProperty& property = CSSProperty::Get(longhand_id);
+ const CSSProperty& property =
+ CSSProperty::Get(longhand_id)
+ .ResolveDirectionAwareProperty(style.Direction(),
+ style.GetWritingMode());
PropertyHandle property_handle = PropertyHandle(property);
if (!animate_all && !property.IsInterpolable()) {
@@ -939,7 +940,7 @@ void CSSAnimations::CalculateTransitionUpdate(CSSAnimationUpdate& update,
} else {
DCHECK_EQ(property_pass, PropertyPass::kStandard);
CalculateTransitionUpdateForStandardProperty(state, transition_property,
- transition_index);
+ transition_index, style);
}
}
}
@@ -1172,9 +1173,10 @@ void CSSAnimations::AnimationEventDelegate::OnEventCondition(
}
if (current_phase == AnimationEffect::kPhaseAfter &&
- previous_phase_ != AnimationEffect::kPhaseAfter)
+ previous_phase_ != AnimationEffect::kPhaseAfter) {
MaybeDispatch(Document::kAnimationEndListener, EventTypeNames::animationend,
- animation_node.ActiveDurationInternal());
+ animation_node.RepeatedDuration());
+ }
previous_phase_ = current_phase;
previous_iteration_ = current_iteration;
@@ -1298,6 +1300,8 @@ void CSSAnimations::Trace(blink::Visitor* visitor) {
visitor->Trace(transitions_);
visitor->Trace(pending_update_);
visitor->Trace(running_animations_);
+ visitor->Trace(previous_active_interpolations_for_standard_animations_);
+ visitor->Trace(previous_active_interpolations_for_custom_animations_);
}
} // namespace blink
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 4aa84f96ba4..607cf5e92fa 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
@@ -165,6 +165,8 @@ class CSSAnimations final {
struct TransitionUpdateState {
STACK_ALLOCATED();
+
+ public:
CSSAnimationUpdate& update;
Member<const Element> animating_element;
const ComputedStyle& old_style;
@@ -183,7 +185,8 @@ class CSSAnimations final {
static void CalculateTransitionUpdateForStandardProperty(
TransitionUpdateState&,
const CSSTransitionData::TransitionProperty&,
- size_t transition_index);
+ size_t transition_index,
+ const ComputedStyle&);
static void CalculateTransitionUpdateForProperty(TransitionUpdateState&,
const PropertyHandle&,
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 3183baad2fa..59d5c1a6bc2 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
@@ -9,33 +9,27 @@
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
#include "third_party/blink/renderer/platform/animation/compositor_animation_delegate.h"
-#include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h"
namespace blink {
-namespace {
-
-class TestingPlatformSupportWithMockSchedulerAndThreadedAnimations
- : public TestingPlatformSupportWithMockScheduler {
- public:
- bool IsThreadedAnimationEnabled() override { return true; }
-};
-
-} // namespace
-
class CSSAnimationsTest : public RenderingTest {
public:
+ CSSAnimationsTest() {
+ EnablePlatform();
+ platform()->SetThreadedAnimationEnabled(true);
+ }
+
void SetUp() override {
- platform_->SetAutoAdvanceNowToPendingTasks(false);
+ platform()->SetAutoAdvanceNowToPendingTasks(false);
// Advance timer manually as RenderingTest expects the time to be non-zero.
- platform_->AdvanceClockSeconds(1.);
+ platform()->AdvanceClockSeconds(1.);
RenderingTest::SetUp();
EnableCompositing();
}
void TearDown() override {
- platform_->SetAutoAdvanceNowToPendingTasks(true);
- platform_->RunUntilIdle();
+ platform()->SetAutoAdvanceNowToPendingTasks(true);
+ platform()->RunUntilIdle();
}
void StartAnimationOnCompositor(Animation* animation) {
@@ -46,8 +40,8 @@ class CSSAnimationsTest : public RenderingTest {
}
void AdvanceClockSeconds(double seconds) {
- platform_->AdvanceClockSeconds(seconds);
- platform_->RunUntilIdle();
+ platform()->AdvanceClockSeconds(seconds);
+ platform()->RunUntilIdle();
}
double GetContrastFilterAmount(Element* element) {
@@ -58,11 +52,6 @@ class CSSAnimationsTest : public RenderingTest {
return static_cast<const BasicComponentTransferFilterOperation*>(filter)
->Amount();
}
-
- private:
- ScopedTestingPlatformSupport<
- TestingPlatformSupportWithMockSchedulerAndThreadedAnimations>
- platform_;
};
// Verify that a composited animation is retargeted according to its composited
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 51c777733db..c1e352fae53 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
@@ -152,7 +152,8 @@ PairwiseInterpolationValue CSSImageListInterpolationType::MaybeMergeSingles(
return ListInterpolationFunctions::MaybeMergeSingles(
std::move(start), std::move(end),
ListInterpolationFunctions::LengthMatchingStrategy::kLowestCommonMultiple,
- CSSImageInterpolationType::StaticMergeSingleConversions);
+ WTF::BindRepeating(
+ CSSImageInterpolationType::StaticMergeSingleConversions));
}
InterpolationValue
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 5d76ade2851..33e62a8df2a 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
@@ -420,8 +420,7 @@ CSSInterpolationTypesMap::CreateInterpolationTypesForCSSSyntax(
property, &registration));
break;
case CSSSyntaxType::kImage:
- result.push_back(std::make_unique<CSSImageInterpolationType>(
- property, &registration));
+ // TODO(andruud): Implement smooth interpolation for gradients.
break;
case CSSSyntaxType::kInteger:
result.push_back(std::make_unique<CSSNumberInterpolationType>(
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 6afb7f99b34..dbfcf4af3d2 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
@@ -128,7 +128,7 @@ PairwiseInterpolationValue CSSLengthListInterpolationType::MaybeMergeSingles(
return ListInterpolationFunctions::MaybeMergeSingles(
std::move(start), std::move(end),
ListInterpolationFunctions::LengthMatchingStrategy::kLowestCommonMultiple,
- LengthInterpolationFunctions::MergeSingles);
+ WTF::BindRepeating(LengthInterpolationFunctions::MergeSingles));
}
InterpolationValue
@@ -149,8 +149,9 @@ void CSSLengthListInterpolationType::Composite(
ListInterpolationFunctions::Composite(
underlying_value_owner, underlying_fraction, *this, value,
ListInterpolationFunctions::LengthMatchingStrategy::kLowestCommonMultiple,
- LengthInterpolationFunctions::NonInterpolableValuesAreCompatible,
- LengthInterpolationFunctions::Composite);
+ WTF::BindRepeating(
+ LengthInterpolationFunctions::NonInterpolableValuesAreCompatible),
+ WTF::BindRepeating(LengthInterpolationFunctions::Composite));
}
void CSSLengthListInterpolationType::ApplyStandardPropertyValue(
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 056643a3230..1a060ef3ceb 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
@@ -133,7 +133,7 @@ PairwiseInterpolationValue CSSShadowListInterpolationType::MaybeMergeSingles(
return ListInterpolationFunctions::MaybeMergeSingles(
std::move(start), std::move(end),
ListInterpolationFunctions::LengthMatchingStrategy::kPadToLargest,
- ShadowInterpolationFunctions::MaybeMergeSingles);
+ WTF::BindRepeating(ShadowInterpolationFunctions::MaybeMergeSingles));
}
InterpolationValue
@@ -151,8 +151,9 @@ void CSSShadowListInterpolationType::Composite(
ListInterpolationFunctions::Composite(
underlying_value_owner, underlying_fraction, *this, value,
ListInterpolationFunctions::LengthMatchingStrategy::kPadToLargest,
- ShadowInterpolationFunctions::NonInterpolableValuesAreCompatible,
- ShadowInterpolationFunctions::Composite);
+ WTF::BindRepeating(
+ ShadowInterpolationFunctions::NonInterpolableValuesAreCompatible),
+ WTF::BindRepeating(ShadowInterpolationFunctions::Composite));
}
static scoped_refptr<ShadowList> CreateShadowList(
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 167a785147d..04dfbbb0be0 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
@@ -157,7 +157,7 @@ PairwiseInterpolationValue CSSSizeListInterpolationType::MaybeMergeSingles(
return ListInterpolationFunctions::MaybeMergeSingles(
std::move(start), std::move(end),
ListInterpolationFunctions::LengthMatchingStrategy::kLowestCommonMultiple,
- SizeInterpolationFunctions::MaybeMergeSingles);
+ WTF::BindRepeating(SizeInterpolationFunctions::MaybeMergeSingles));
}
InterpolationValue
@@ -176,9 +176,9 @@ void CSSSizeListInterpolationType::Composite(
ListInterpolationFunctions::Composite(
underlying_value_owner, underlying_fraction, *this, value,
ListInterpolationFunctions::LengthMatchingStrategy::kLowestCommonMultiple,
-
- SizeInterpolationFunctions::NonInterpolableValuesAreCompatible,
- SizeInterpolationFunctions::Composite);
+ WTF::BindRepeating(
+ SizeInterpolationFunctions::NonInterpolableValuesAreCompatible),
+ WTF::BindRepeating(SizeInterpolationFunctions::Composite));
}
void CSSSizeListInterpolationType::ApplyStandardPropertyValue(
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 8e70ccd3141..5c05200369c 100644
--- a/chromium/third_party/blink/renderer/core/animation/document_animations.cc
+++ b/chromium/third_party/blink/renderer/core/animation/document_animations.cc
@@ -70,7 +70,7 @@ void DocumentAnimations::UpdateAnimationTimingIfNeeded(Document& document) {
void DocumentAnimations::UpdateAnimations(
Document& document,
DocumentLifecycle::LifecycleState required_lifecycle_state,
- base::Optional<CompositorElementIdSet>& composited_element_ids) {
+ const base::Optional<CompositorElementIdSet>& composited_element_ids) {
DCHECK(document.Lifecycle().GetState() >= required_lifecycle_state);
if (document.GetPendingAnimations().Update(composited_element_ids)) {
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 9dd99b7c819..a0da056eb37 100644
--- a/chromium/third_party/blink/renderer/core/animation/document_animations.h
+++ b/chromium/third_party/blink/renderer/core/animation/document_animations.h
@@ -52,7 +52,7 @@ class DocumentAnimations {
static void UpdateAnimations(
Document&,
DocumentLifecycle::LifecycleState required_lifecycle_state,
- base::Optional<CompositorElementIdSet>&);
+ const base::Optional<CompositorElementIdSet>&);
private:
DocumentAnimations() = default;
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 f907702ba1d..a3e0de9162a 100644
--- a/chromium/third_party/blink/renderer/core/animation/document_timeline.cc
+++ b/chromium/third_party/blink/renderer/core/animation/document_timeline.cc
@@ -95,7 +95,7 @@ DocumentTimeline::DocumentTimeline(Document* document,
}
bool DocumentTimeline::IsActive() {
- return document_ && document_->GetPage();
+ return document_->GetPage();
}
void DocumentTimeline::AnimationAttached(Animation& animation) {
@@ -105,9 +105,6 @@ void DocumentTimeline::AnimationAttached(Animation& animation) {
}
Animation* DocumentTimeline::Play(AnimationEffect* child) {
- if (!document_)
- return nullptr;
-
Animation* animation = Animation::Create(child, this);
DCHECK(animations_.Contains(animation));
@@ -197,7 +194,7 @@ void DocumentTimeline::DocumentTimelineTiming::WakeAfter(double duration) {
}
void DocumentTimeline::DocumentTimelineTiming::ServiceOnNextFrame() {
- if (timeline_->document_ && timeline_->document_->View())
+ if (timeline_->document_->View())
timeline_->document_->View()->ScheduleAnimation();
}
@@ -207,7 +204,7 @@ void DocumentTimeline::DocumentTimelineTiming::Trace(blink::Visitor* visitor) {
}
TimeTicks DocumentTimeline::ZeroTime() {
- if (!zero_time_initialized_ && document_ && document_->Loader()) {
+ if (!zero_time_initialized_ && document_->Loader()) {
zero_time_ = document_->Loader()->GetTiming().ReferenceMonotonicTime() +
origin_time_;
zero_time_initialized_ = true;
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 8efe98ee197..51b48b5bd2d 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
@@ -150,6 +150,27 @@ TEST_F(AnimationDocumentTimelineTest, ZeroTime) {
EXPECT_FALSE(is_null);
}
+// EffectiveTime is identical to CurrentTimeInternal except that it returns 0
+// when the timeline is inactive.
+TEST_F(AnimationDocumentTimelineTest, EffectiveTime) {
+ GetAnimationClock().UpdateTime(base::TimeTicks() +
+ base::TimeDelta::FromSecondsD(200));
+ EXPECT_EQ(200, timeline->EffectiveTime());
+ EXPECT_EQ(200, timeline->CurrentTimeInternal());
+ bool is_null;
+ EXPECT_EQ(200, timeline->CurrentTimeInternal(is_null));
+ EXPECT_FALSE(is_null);
+
+ Document* document_without_frame = Document::CreateForTest();
+ DocumentTimeline* inactive_timeline = DocumentTimeline::Create(
+ document_without_frame, TimeDelta(), platform_timing);
+
+ EXPECT_EQ(0, inactive_timeline->EffectiveTime());
+ is_null = false;
+ inactive_timeline->CurrentTimeInternal(is_null);
+ EXPECT_TRUE(is_null);
+}
+
TEST_F(AnimationDocumentTimelineTest, PlaybackRateNormal) {
TimeTicks zero_time = timeline->ZeroTime();
bool is_null;
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 8601e570b95..b45f3b1d2bb 100644
--- a/chromium/third_party/blink/renderer/core/animation/effect_input.cc
+++ b/chromium/third_party/blink/renderer/core/animation/effect_input.cc
@@ -61,31 +61,22 @@ namespace blink {
namespace {
// Converts the composite property of a BasePropertyIndexedKeyframe into a
-// vector of EffectModel::CompositeOperation enums.
+// vector of base::Optional<EffectModel::CompositeOperation> enums.
Vector<base::Optional<EffectModel::CompositeOperation>> ParseCompositeProperty(
const BasePropertyIndexedKeyframe& keyframe) {
- const CompositeOperationOrCompositeOperationOrNullSequence& composite =
+ const CompositeOperationOrAutoOrCompositeOperationOrAutoSequence& composite =
keyframe.composite();
- // This handles the case where we have 'composite: null'. The null value is
- // lifted to the union level in the bindings code.
- if (composite.IsNull())
- return {base::nullopt};
-
- if (composite.IsCompositeOperation()) {
+ if (composite.IsCompositeOperationOrAuto()) {
return {EffectModel::StringToCompositeOperation(
- composite.GetAsCompositeOperation())};
+ composite.GetAsCompositeOperationOrAuto())};
}
Vector<base::Optional<EffectModel::CompositeOperation>> result;
for (const String& composite_operation_string :
- composite.GetAsCompositeOperationOrNullSequence()) {
- if (composite_operation_string.IsNull()) {
- result.push_back(base::nullopt);
- } else {
- result.push_back(
- EffectModel::StringToCompositeOperation(composite_operation_string));
- }
+ composite.GetAsCompositeOperationOrAutoSequence()) {
+ result.push_back(
+ EffectModel::StringToCompositeOperation(composite_operation_string));
}
return result;
}
@@ -186,7 +177,7 @@ bool ValidatePartialKeyframes(const StringKeyframeVector& keyframes) {
// StringKeyframe and the current runtime flags.
EffectModel::CompositeOperation ResolveCompositeOperationForKeyframe(
EffectModel::CompositeOperation composite,
- const scoped_refptr<StringKeyframe>& keyframe) {
+ StringKeyframe* keyframe) {
if (!RuntimeEnabledFeatures::CSSAdditiveAnimationsEnabled() &&
keyframe->HasCssProperty() && composite == EffectModel::kCompositeAdd) {
return EffectModel::kCompositeReplace;
@@ -354,7 +345,7 @@ StringKeyframeVector ConvertArrayForm(Element* element,
// Now we create the actual Keyframe object. We start by assigning the
// offset and composite values; conceptually these were actually added in
// step 5 above but we didn't have a keyframe object then.
- scoped_refptr<StringKeyframe> keyframe = StringKeyframe::Create();
+ StringKeyframe* keyframe = StringKeyframe::Create();
if (processed_keyframe.base_keyframe.hasOffset()) {
keyframe->SetOffset(processed_keyframe.base_keyframe.offset());
}
@@ -363,15 +354,16 @@ StringKeyframeVector ConvertArrayForm(Element* element,
// using the syntax specified for that property.
for (const auto& pair : processed_keyframe.property_value_pairs) {
// TODO(crbug.com/777971): Make parsing of property values spec-compliant.
- SetKeyframeValue(element, document, *keyframe.get(), pair.first,
- pair.second, execution_context);
+ SetKeyframeValue(element, document, *keyframe, pair.first, pair.second,
+ execution_context);
}
- if (processed_keyframe.base_keyframe.hasComposite()) {
- keyframe->SetComposite(ResolveCompositeOperationForKeyframe(
- EffectModel::StringToCompositeOperation(
- processed_keyframe.base_keyframe.composite()),
- keyframe));
+ base::Optional<EffectModel::CompositeOperation> composite =
+ EffectModel::StringToCompositeOperation(
+ processed_keyframe.base_keyframe.composite());
+ if (composite) {
+ keyframe->SetComposite(
+ ResolveCompositeOperationForKeyframe(composite.value(), keyframe));
}
// 8.2. Let the timing function of frame be the result of parsing the
@@ -489,7 +481,7 @@ StringKeyframeVector ConvertObjectForm(Element* element,
//
// This is equivalent to just keeping a hashmap from computed offset to a
// single keyframe, which simplifies the parsing logic.
- HashMap<double, scoped_refptr<StringKeyframe>> keyframes;
+ HeapHashMap<double, Member<StringKeyframe>> keyframes;
// By spec, we must sort the properties in "ascending order by the Unicode
// codepoints that define each property name."
@@ -530,8 +522,8 @@ StringKeyframeVector ConvertObjectForm(Element* element,
if (result.is_new_entry)
result.stored_value->value = StringKeyframe::Create();
- SetKeyframeValue(element, document, *result.stored_value->value.get(),
- property, values[i], execution_context);
+ SetKeyframeValue(element, document, *result.stored_value->value, property,
+ values[i], execution_context);
}
}
@@ -734,7 +726,7 @@ EffectModel::CompositeOperation EffectInput::ResolveCompositeOperation(
EffectModel::CompositeOperation composite,
const StringKeyframeVector& keyframes) {
EffectModel::CompositeOperation result = composite;
- for (const scoped_refptr<StringKeyframe>& keyframe : keyframes) {
+ for (const Member<StringKeyframe>& keyframe : keyframes) {
// Replace is always supported, so we can early-exit if and when we have
// that as our composite value.
if (result == EffectModel::kCompositeReplace)
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 216d5dcdd70..ed3a9025193 100644
--- a/chromium/third_party/blink/renderer/core/animation/effect_model.cc
+++ b/chromium/third_party/blink/renderer/core/animation/effect_model.cc
@@ -9,19 +9,23 @@
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
namespace blink {
-EffectModel::CompositeOperation EffectModel::StringToCompositeOperation(
- const String& composite_string) {
+base::Optional<EffectModel::CompositeOperation>
+EffectModel::StringToCompositeOperation(const String& composite_string) {
DCHECK(composite_string == "replace" || composite_string == "add" ||
- composite_string == "accumulate");
- if (composite_string == "add") {
+ composite_string == "accumulate" || composite_string == "auto");
+ if (composite_string == "auto")
+ return base::nullopt;
+ if (composite_string == "add")
return kCompositeAdd;
- }
// TODO(crbug.com/788440): Support accumulate.
return kCompositeReplace;
}
-String EffectModel::CompositeOperationToString(CompositeOperation composite) {
- switch (composite) {
+String EffectModel::CompositeOperationToString(
+ base::Optional<CompositeOperation> composite) {
+ if (!composite)
+ return "auto";
+ switch (composite.value()) {
case EffectModel::kCompositeAdd:
return "add";
case EffectModel::kCompositeReplace:
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 77fdae6dbac..8329db1bdd3 100644
--- a/chromium/third_party/blink/renderer/core/animation/effect_model.h
+++ b/chromium/third_party/blink/renderer/core/animation/effect_model.h
@@ -50,15 +50,16 @@ class CORE_EXPORT EffectModel : public GarbageCollectedFinalized<EffectModel> {
kCompositeReplace,
kCompositeAdd,
};
- static CompositeOperation StringToCompositeOperation(const String&);
- static String CompositeOperationToString(CompositeOperation);
+ static base::Optional<CompositeOperation> StringToCompositeOperation(
+ const String&);
+ static String CompositeOperationToString(base::Optional<CompositeOperation>);
EffectModel() = default;
virtual ~EffectModel() = default;
virtual bool Sample(int iteration,
double fraction,
double iteration_duration,
- Vector<scoped_refptr<Interpolation>>&) const = 0;
+ HeapVector<Member<Interpolation>>&) const = 0;
virtual bool Affects(const PropertyHandle&) const { return false; }
virtual bool AffectedByUnderlyingAnimations() const = 0;
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 5395bf4c744..84b04e03413 100644
--- a/chromium/third_party/blink/renderer/core/animation/effect_stack.cc
+++ b/chromium/third_party/blink/renderer/core/animation/effect_stack.cc
@@ -41,7 +41,7 @@ namespace blink {
namespace {
void CopyToActiveInterpolationsMap(
- const Vector<scoped_refptr<Interpolation>>& source,
+ const HeapVector<Member<Interpolation>>& source,
EffectStack::PropertyHandleFilter property_handle_filter,
ActiveInterpolationsMap& target) {
for (const auto& interpolation : source) {
@@ -57,9 +57,9 @@ void CopyToActiveInterpolationsMap(
interpolation->IsInvalidatableInterpolation() &&
ToInvalidatableInterpolation(*interpolation)
.DependsOnUnderlyingValue()) {
- active_interpolations.push_back(interpolation.get());
+ active_interpolations.push_back(interpolation);
} else {
- active_interpolations.at(0) = interpolation.get();
+ active_interpolations.at(0) = interpolation;
}
}
}
@@ -75,7 +75,7 @@ void CopyNewAnimationsToActiveInterpolationsMap(
EffectStack::PropertyHandleFilter property_handle_filter,
ActiveInterpolationsMap& result) {
for (const auto& new_animation : new_animations) {
- Vector<scoped_refptr<Interpolation>> sample;
+ HeapVector<Member<Interpolation>> sample;
new_animation->Sample(sample);
if (!sample.IsEmpty())
CopyToActiveInterpolationsMap(sample, property_handle_filter, result);
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 aa65718560f..fc51f27824a 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
@@ -172,42 +172,52 @@ TEST_F(AnimationEffectStackTest, ForwardsFillDiscarding) {
Play(MakeKeyframeEffect(MakeEffectModel(CSSPropertyFontSize, "3px")), 4);
GetDocument().GetPendingAnimations().Update(
base::Optional<CompositorElementIdSet>());
- ActiveInterpolationsMap interpolations;
+
+ // Because we will be forcing a naive GC that assumes there are no Oilpan
+ // objects on the stack (e.g. passes BlinkGC::kNoHeapPointersOnStack), we have
+ // to keep the ActiveInterpolationsMap in a Persistent.
+ // TODO(crbug.com/876331): We should be able to use a PersistentHeapHashMap
+ // here, but the operator=, copy, and move overloads do not work properly.
+ Persistent<ActiveInterpolationsMap> interpolations;
UpdateTimeline(TimeDelta::FromSeconds(11));
ThreadState::Current()->CollectAllGarbage();
- interpolations = EffectStack::ActiveInterpolations(
- &element->GetElementAnimations()->GetEffectStack(), nullptr, nullptr,
- KeyframeEffect::kDefaultPriority);
- EXPECT_EQ(1u, interpolations.size());
- EXPECT_EQ(GetFontSizeValue(interpolations), 3);
+ interpolations =
+ new ActiveInterpolationsMap(EffectStack::ActiveInterpolations(
+ &element->GetElementAnimations()->GetEffectStack(), nullptr, nullptr,
+ KeyframeEffect::kDefaultPriority));
+ EXPECT_EQ(1u, interpolations->size());
+ EXPECT_EQ(GetFontSizeValue(*interpolations), 3);
EXPECT_EQ(3u, SampledEffectCount());
UpdateTimeline(TimeDelta::FromSeconds(13));
ThreadState::Current()->CollectAllGarbage();
- interpolations = EffectStack::ActiveInterpolations(
- &element->GetElementAnimations()->GetEffectStack(), nullptr, nullptr,
- KeyframeEffect::kDefaultPriority);
- EXPECT_EQ(1u, interpolations.size());
- EXPECT_EQ(GetFontSizeValue(interpolations), 3);
+ interpolations =
+ new ActiveInterpolationsMap(EffectStack::ActiveInterpolations(
+ &element->GetElementAnimations()->GetEffectStack(), nullptr, nullptr,
+ KeyframeEffect::kDefaultPriority));
+ EXPECT_EQ(1u, interpolations->size());
+ EXPECT_EQ(GetFontSizeValue(*interpolations), 3);
EXPECT_EQ(3u, SampledEffectCount());
UpdateTimeline(TimeDelta::FromSeconds(15));
ThreadState::Current()->CollectAllGarbage();
- interpolations = EffectStack::ActiveInterpolations(
- &element->GetElementAnimations()->GetEffectStack(), nullptr, nullptr,
- KeyframeEffect::kDefaultPriority);
- EXPECT_EQ(1u, interpolations.size());
- EXPECT_EQ(GetFontSizeValue(interpolations), 3);
+ interpolations =
+ new ActiveInterpolationsMap(EffectStack::ActiveInterpolations(
+ &element->GetElementAnimations()->GetEffectStack(), nullptr, nullptr,
+ KeyframeEffect::kDefaultPriority));
+ EXPECT_EQ(1u, interpolations->size());
+ EXPECT_EQ(GetFontSizeValue(*interpolations), 3);
EXPECT_EQ(2u, SampledEffectCount());
UpdateTimeline(TimeDelta::FromSeconds(17));
ThreadState::Current()->CollectAllGarbage();
- interpolations = EffectStack::ActiveInterpolations(
- &element->GetElementAnimations()->GetEffectStack(), nullptr, nullptr,
- KeyframeEffect::kDefaultPriority);
- EXPECT_EQ(1u, interpolations.size());
- EXPECT_EQ(GetFontSizeValue(interpolations), 3);
+ interpolations =
+ new ActiveInterpolationsMap(EffectStack::ActiveInterpolations(
+ &element->GetElementAnimations()->GetEffectStack(), nullptr, nullptr,
+ KeyframeEffect::kDefaultPriority));
+ EXPECT_EQ(1u, interpolations->size());
+ EXPECT_EQ(GetFontSizeValue(*interpolations), 3);
EXPECT_EQ(1u, SampledEffectCount());
}
diff --git a/chromium/third_party/blink/renderer/core/animation/element_animation.cc b/chromium/third_party/blink/renderer/core/animation/element_animation.cc
index 4369fa97758..112c286fb8a 100644
--- a/chromium/third_party/blink/renderer/core/animation/element_animation.cc
+++ b/chromium/third_party/blink/renderer/core/animation/element_animation.cc
@@ -28,7 +28,8 @@ Animation* ElementAnimation::animate(
EffectModel::CompositeOperation composite = EffectModel::kCompositeReplace;
if (options.IsKeyframeAnimationOptions()) {
composite = EffectModel::StringToCompositeOperation(
- options.GetAsKeyframeAnimationOptions().composite());
+ options.GetAsKeyframeAnimationOptions().composite())
+ .value();
}
KeyframeEffectModelBase* effect = EffectInput::Convert(
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 86aa5099995..7d82f71e8ab 100644
--- a/chromium/third_party/blink/renderer/core/animation/inert_effect.cc
+++ b/chromium/third_party/blink/renderer/core/animation/inert_effect.cc
@@ -50,7 +50,7 @@ InertEffect::InertEffect(KeyframeEffectModelBase* model,
paused_(paused),
inherited_time_(inherited_time) {}
-void InertEffect::Sample(Vector<scoped_refptr<Interpolation>>& result) const {
+void InertEffect::Sample(HeapVector<Member<Interpolation>>& result) const {
UpdateInheritedTime(inherited_time_, kTimingUpdateOnDemand);
if (!IsInEffect()) {
result.clear();
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 5567104f596..c5d52dcc365 100644
--- a/chromium/third_party/blink/renderer/core/animation/inert_effect.h
+++ b/chromium/third_party/blink/renderer/core/animation/inert_effect.h
@@ -31,7 +31,6 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_INERT_EFFECT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_INERT_EFFECT_H_
-#include "base/memory/scoped_refptr.h"
#include "third_party/blink/renderer/core/animation/animation_effect.h"
#include "third_party/blink/renderer/core/animation/keyframe_effect_model.h"
#include "third_party/blink/renderer/core/core_export.h"
@@ -47,7 +46,7 @@ class CORE_EXPORT InertEffect final : public AnimationEffect {
const Timing&,
bool paused,
double inherited_time);
- void Sample(Vector<scoped_refptr<Interpolation>>&) const;
+ void Sample(HeapVector<Member<Interpolation>>&) const;
KeyframeEffectModelBase* Model() const { return model_.Get(); }
bool Paused() const { return paused_; }
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 029afde53de..89ab7f38725 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
@@ -24,7 +24,7 @@ class AnimationInterpolableValueTest : public testing::Test {
CSSNumberInterpolationType interpolation_type(property_handle);
InterpolationValue start(InterpolableNumber::Create(a));
InterpolationValue end(InterpolableNumber::Create(b));
- scoped_refptr<TransitionInterpolation> i = TransitionInterpolation::Create(
+ TransitionInterpolation* i = TransitionInterpolation::Create(
property_handle, interpolation_type, std::move(start), std::move(end),
nullptr, nullptr);
@@ -53,7 +53,7 @@ class AnimationInterpolableValueTest : public testing::Test {
CSSLengthInterpolationType interpolation_type(property_handle);
InterpolationValue start(std::move(list_a));
InterpolationValue end(std::move(list_b));
- scoped_refptr<TransitionInterpolation> i = TransitionInterpolation::Create(
+ TransitionInterpolation* i = TransitionInterpolation::Create(
property_handle, interpolation_type, std::move(start), std::move(end),
nullptr, nullptr);
i->Interpolate(0, progress);
diff --git a/chromium/third_party/blink/renderer/core/animation/interpolation.h b/chromium/third_party/blink/renderer/core/animation/interpolation.h
index 89f50b966a9..2db04b42eea 100644
--- a/chromium/third_party/blink/renderer/core/animation/interpolation.h
+++ b/chromium/third_party/blink/renderer/core/animation/interpolation.h
@@ -11,8 +11,8 @@
#include "third_party/blink/renderer/core/animation/interpolable_value.h"
#include "third_party/blink/renderer/core/animation/property_handle.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/ref_counted.h"
namespace blink {
@@ -57,9 +57,10 @@ namespace blink {
// The interpolation's effect at its current timing state is applied to the
// element. How this is done depends on the subclass of Interpolation. See
// the subclass documentation for more.
-class CORE_EXPORT Interpolation : public RefCounted<Interpolation> {
+class CORE_EXPORT Interpolation
+ : public GarbageCollectedFinalized<Interpolation> {
public:
- virtual ~Interpolation() = default;
+ virtual ~Interpolation() {}
virtual void Interpolate(int iteration, double fraction) = 0;
@@ -74,13 +75,16 @@ class CORE_EXPORT Interpolation : public RefCounted<Interpolation> {
// optimise away computing underlying values.
virtual bool DependsOnUnderlyingValue() const { return false; }
+ virtual void Trace(Visitor*) {}
+
protected:
Interpolation() = default;
DISALLOW_COPY_AND_ASSIGN(Interpolation);
};
-using ActiveInterpolations = Vector<scoped_refptr<Interpolation>, 1>;
-using ActiveInterpolationsMap = HashMap<PropertyHandle, ActiveInterpolations>;
+using ActiveInterpolations = HeapVector<Member<Interpolation>, 1>;
+using ActiveInterpolationsMap =
+ HeapHashMap<PropertyHandle, ActiveInterpolations>;
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/animation/interpolation_effect.cc b/chromium/third_party/blink/renderer/core/animation/interpolation_effect.cc
index 2c5213193b6..7f42c27df03 100644
--- a/chromium/third_party/blink/renderer/core/animation/interpolation_effect.cc
+++ b/chromium/third_party/blink/renderer/core/animation/interpolation_effect.cc
@@ -11,18 +11,18 @@ namespace blink {
void InterpolationEffect::GetActiveInterpolations(
double fraction,
double iteration_duration,
- Vector<scoped_refptr<Interpolation>>& result) const {
+ HeapVector<Member<Interpolation>>& result) const {
size_t existing_size = result.size();
size_t result_index = 0;
for (const auto& record : interpolations_) {
- if (fraction >= record.apply_from_ && fraction < record.apply_to_) {
- scoped_refptr<Interpolation> interpolation = record.interpolation_;
- double record_length = record.end_ - record.start_;
+ if (fraction >= record->apply_from_ && fraction < record->apply_to_) {
+ Interpolation* interpolation = record->interpolation_;
+ double record_length = record->end_ - record->start_;
double local_fraction =
- record_length ? (fraction - record.start_) / record_length : 0.0;
- if (record.easing_)
- local_fraction = record.easing_->Evaluate(
+ record_length ? (fraction - record->start_) / record_length : 0.0;
+ if (record->easing_)
+ local_fraction = record->easing_->Evaluate(
local_fraction, AccuracyForDuration(iteration_duration));
interpolation->Interpolate(0, local_fraction);
if (result_index < existing_size)
@@ -46,4 +46,8 @@ void InterpolationEffect::AddInterpolationsFromKeyframes(
keyframe_b.Offset(), apply_from, apply_to);
}
+void InterpolationEffect::Trace(Visitor* visitor) {
+ visitor->Trace(interpolations_);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/animation/interpolation_effect.h b/chromium/third_party/blink/renderer/core/animation/interpolation_effect.h
index 335800e8d71..1b261ec0d4b 100644
--- a/chromium/third_party/blink/renderer/core/animation/interpolation_effect.h
+++ b/chromium/third_party/blink/renderer/core/animation/interpolation_effect.h
@@ -9,15 +9,15 @@
#include "third_party/blink/renderer/core/animation/keyframe.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/animation/timing_function.h"
+#include "third_party/blink/renderer/platform/heap/handle.h"
namespace blink {
// Stores all adjacent pairs of keyframes (represented by Interpolations) in a
// KeyframeEffectModel with keyframe offset data preprocessed for more efficient
// active keyframe pair sampling.
-class CORE_EXPORT InterpolationEffect {
- DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
-
+class CORE_EXPORT InterpolationEffect
+ : public GarbageCollected<InterpolationEffect> {
public:
InterpolationEffect() : is_populated_(false) {}
@@ -31,17 +31,16 @@ class CORE_EXPORT InterpolationEffect {
void GetActiveInterpolations(double fraction,
double iteration_duration,
- Vector<scoped_refptr<Interpolation>>&) const;
+ HeapVector<Member<Interpolation>>&) const;
- void AddInterpolation(scoped_refptr<Interpolation> interpolation,
+ void AddInterpolation(Interpolation* interpolation,
scoped_refptr<TimingFunction> easing,
double start,
double end,
double apply_from,
double apply_to) {
- interpolations_.push_back(InterpolationRecord(std::move(interpolation),
- std::move(easing), start, end,
- apply_from, apply_to));
+ interpolations_.push_back(new InterpolationRecord(
+ interpolation, std::move(easing), start, end, apply_from, apply_to));
}
void AddInterpolationsFromKeyframes(
@@ -51,31 +50,37 @@ class CORE_EXPORT InterpolationEffect {
double apply_from,
double apply_to);
+ void Trace(Visitor*);
+
private:
- struct InterpolationRecord {
- InterpolationRecord(scoped_refptr<Interpolation> interpolation,
+ class InterpolationRecord
+ : public GarbageCollectedFinalized<InterpolationRecord> {
+ public:
+ InterpolationRecord(Interpolation* interpolation,
scoped_refptr<TimingFunction> easing,
double start,
double end,
double apply_from,
double apply_to)
- : interpolation_(std::move(interpolation)),
+ : interpolation_(interpolation),
easing_(std::move(easing)),
start_(start),
end_(end),
apply_from_(apply_from),
apply_to_(apply_to) {}
- scoped_refptr<Interpolation> interpolation_;
+ Member<Interpolation> interpolation_;
scoped_refptr<TimingFunction> easing_;
double start_;
double end_;
double apply_from_;
double apply_to_;
+
+ void Trace(Visitor* visitor) { visitor->Trace(interpolation_); }
};
bool is_populated_;
- Vector<InterpolationRecord> interpolations_;
+ HeapVector<Member<InterpolationRecord>> interpolations_;
};
} // 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 0e924d7b190..2c978b28da5 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
@@ -15,16 +15,15 @@ namespace {
const double kInterpolationTestDuration = 1.0;
-double GetInterpolableNumber(scoped_refptr<Interpolation> value) {
- TransitionInterpolation& interpolation =
- ToTransitionInterpolation(*value.get());
+double GetInterpolableNumber(Interpolation* value) {
+ TransitionInterpolation* interpolation = ToTransitionInterpolation(value);
std::unique_ptr<TypedInterpolationValue> interpolated_value =
- interpolation.GetInterpolatedValue();
+ interpolation->GetInterpolatedValue();
return ToInterpolableNumber(interpolated_value->GetInterpolableValue())
.Value();
}
-scoped_refptr<Interpolation> CreateInterpolation(int from, int to) {
+Interpolation* CreateInterpolation(int from, int to) {
// We require a property that maps to CSSNumberInterpolationType. 'z-index'
// suffices for this, and also means we can ignore the AnimatableValues for
// the compositor (as z-index isn't compositor-compatible).
@@ -40,84 +39,86 @@ scoped_refptr<Interpolation> CreateInterpolation(int from, int to) {
} // namespace
TEST(AnimationInterpolationEffectTest, SingleInterpolation) {
- InterpolationEffect interpolation_effect;
- interpolation_effect.AddInterpolation(
+ Persistent<InterpolationEffect> interpolation_effect =
+ new InterpolationEffect;
+ interpolation_effect->AddInterpolation(
CreateInterpolation(0, 10), scoped_refptr<TimingFunction>(), 0, 1, -1, 2);
- Vector<scoped_refptr<Interpolation>> active_interpolations;
- interpolation_effect.GetActiveInterpolations(-2, kInterpolationTestDuration,
- active_interpolations);
+ HeapVector<Member<Interpolation>> active_interpolations;
+ interpolation_effect->GetActiveInterpolations(-2, kInterpolationTestDuration,
+ active_interpolations);
EXPECT_EQ(0ul, active_interpolations.size());
- interpolation_effect.GetActiveInterpolations(-0.5, kInterpolationTestDuration,
- active_interpolations);
+ interpolation_effect->GetActiveInterpolations(
+ -0.5, kInterpolationTestDuration, active_interpolations);
EXPECT_EQ(1ul, active_interpolations.size());
EXPECT_EQ(-5, GetInterpolableNumber(active_interpolations.at(0)));
- interpolation_effect.GetActiveInterpolations(0.5, kInterpolationTestDuration,
- active_interpolations);
+ interpolation_effect->GetActiveInterpolations(0.5, kInterpolationTestDuration,
+ active_interpolations);
EXPECT_EQ(1ul, active_interpolations.size());
EXPECT_FLOAT_EQ(5, GetInterpolableNumber(active_interpolations.at(0)));
- interpolation_effect.GetActiveInterpolations(1.5, kInterpolationTestDuration,
- active_interpolations);
+ interpolation_effect->GetActiveInterpolations(1.5, kInterpolationTestDuration,
+ active_interpolations);
EXPECT_EQ(1ul, active_interpolations.size());
EXPECT_FLOAT_EQ(15, GetInterpolableNumber(active_interpolations.at(0)));
- interpolation_effect.GetActiveInterpolations(3, kInterpolationTestDuration,
- active_interpolations);
+ interpolation_effect->GetActiveInterpolations(3, kInterpolationTestDuration,
+ active_interpolations);
EXPECT_EQ(0ul, active_interpolations.size());
}
TEST(AnimationInterpolationEffectTest, MultipleInterpolations) {
- InterpolationEffect interpolation_effect;
- interpolation_effect.AddInterpolation(
+ Persistent<InterpolationEffect> interpolation_effect =
+ new InterpolationEffect;
+ interpolation_effect->AddInterpolation(
CreateInterpolation(10, 15), scoped_refptr<TimingFunction>(), 1, 2, 1, 3);
- interpolation_effect.AddInterpolation(
+ interpolation_effect->AddInterpolation(
CreateInterpolation(0, 1), LinearTimingFunction::Shared(), 0, 1, 0, 1);
- interpolation_effect.AddInterpolation(
+ interpolation_effect->AddInterpolation(
CreateInterpolation(1, 6),
CubicBezierTimingFunction::Preset(
CubicBezierTimingFunction::EaseType::EASE),
0.5, 1.5, 0.5, 1.5);
- Vector<scoped_refptr<Interpolation>> active_interpolations;
- interpolation_effect.GetActiveInterpolations(-0.5, kInterpolationTestDuration,
- active_interpolations);
+ HeapVector<Member<Interpolation>> active_interpolations;
+ interpolation_effect->GetActiveInterpolations(
+ -0.5, kInterpolationTestDuration, active_interpolations);
EXPECT_EQ(0ul, active_interpolations.size());
- interpolation_effect.GetActiveInterpolations(0, kInterpolationTestDuration,
- active_interpolations);
+ interpolation_effect->GetActiveInterpolations(0, kInterpolationTestDuration,
+ active_interpolations);
EXPECT_EQ(1ul, active_interpolations.size());
EXPECT_FLOAT_EQ(0, GetInterpolableNumber(active_interpolations.at(0)));
- interpolation_effect.GetActiveInterpolations(0.5, kInterpolationTestDuration,
- active_interpolations);
+ interpolation_effect->GetActiveInterpolations(0.5, kInterpolationTestDuration,
+ active_interpolations);
EXPECT_EQ(2ul, active_interpolations.size());
EXPECT_FLOAT_EQ(0.5f, GetInterpolableNumber(active_interpolations.at(0)));
EXPECT_FLOAT_EQ(1, GetInterpolableNumber(active_interpolations.at(1)));
- interpolation_effect.GetActiveInterpolations(1, kInterpolationTestDuration,
- active_interpolations);
+ interpolation_effect->GetActiveInterpolations(1, kInterpolationTestDuration,
+ active_interpolations);
EXPECT_EQ(2ul, active_interpolations.size());
EXPECT_FLOAT_EQ(10, GetInterpolableNumber(active_interpolations.at(0)));
EXPECT_FLOAT_EQ(5.0282884f,
GetInterpolableNumber(active_interpolations.at(1)));
- interpolation_effect.GetActiveInterpolations(
+ interpolation_effect->GetActiveInterpolations(
1, kInterpolationTestDuration * 1000, active_interpolations);
EXPECT_EQ(2ul, active_interpolations.size());
EXPECT_FLOAT_EQ(10, GetInterpolableNumber(active_interpolations.at(0)));
EXPECT_FLOAT_EQ(5.0120168f,
GetInterpolableNumber(active_interpolations.at(1)));
- interpolation_effect.GetActiveInterpolations(1.5, kInterpolationTestDuration,
- active_interpolations);
+ interpolation_effect->GetActiveInterpolations(1.5, kInterpolationTestDuration,
+ active_interpolations);
EXPECT_EQ(1ul, active_interpolations.size());
EXPECT_FLOAT_EQ(12.5f, GetInterpolableNumber(active_interpolations.at(0)));
- interpolation_effect.GetActiveInterpolations(2, kInterpolationTestDuration,
- active_interpolations);
+ interpolation_effect->GetActiveInterpolations(2, kInterpolationTestDuration,
+ active_interpolations);
EXPECT_EQ(1ul, active_interpolations.size());
EXPECT_FLOAT_EQ(15, GetInterpolableNumber(active_interpolations.at(0)));
}
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 16fc7492c6f..5f7fdc569cc 100644
--- a/chromium/third_party/blink/renderer/core/animation/invalidatable_interpolation.h
+++ b/chromium/third_party/blink/renderer/core/animation/invalidatable_interpolation.h
@@ -31,12 +31,12 @@ namespace blink {
// objects.
class CORE_EXPORT InvalidatableInterpolation : public Interpolation {
public:
- static scoped_refptr<InvalidatableInterpolation> Create(
+ static InvalidatableInterpolation* Create(
const PropertyHandle& property,
- scoped_refptr<PropertySpecificKeyframe> start_keyframe,
- scoped_refptr<PropertySpecificKeyframe> end_keyframe) {
- return base::AdoptRef(new InvalidatableInterpolation(
- property, std::move(start_keyframe), std::move(end_keyframe)));
+ PropertySpecificKeyframe* start_keyframe,
+ PropertySpecificKeyframe* end_keyframe) {
+ return new InvalidatableInterpolation(property, start_keyframe,
+ end_keyframe);
}
const PropertyHandle& GetProperty() const final { return property_; }
@@ -51,17 +51,22 @@ class CORE_EXPORT InvalidatableInterpolation : public Interpolation {
return cached_value_.get();
}
+ void Trace(Visitor* visitor) override {
+ visitor->Trace(start_keyframe_);
+ visitor->Trace(end_keyframe_);
+ Interpolation::Trace(visitor);
+ }
+
private:
- InvalidatableInterpolation(
- const PropertyHandle& property,
- scoped_refptr<PropertySpecificKeyframe> start_keyframe,
- scoped_refptr<PropertySpecificKeyframe> end_keyframe)
+ InvalidatableInterpolation(const PropertyHandle& property,
+ PropertySpecificKeyframe* start_keyframe,
+ PropertySpecificKeyframe* end_keyframe)
: Interpolation(),
property_(property),
interpolation_types_(nullptr),
interpolation_types_version_(0),
- start_keyframe_(std::move(start_keyframe)),
- end_keyframe_(std::move(end_keyframe)),
+ start_keyframe_(start_keyframe),
+ end_keyframe_(end_keyframe),
current_fraction_(std::numeric_limits<double>::quiet_NaN()),
is_conversion_cached_(false) {}
@@ -92,8 +97,8 @@ class CORE_EXPORT InvalidatableInterpolation : public Interpolation {
const PropertyHandle property_;
mutable const InterpolationTypes* interpolation_types_;
mutable size_t interpolation_types_version_;
- scoped_refptr<PropertySpecificKeyframe> start_keyframe_;
- scoped_refptr<PropertySpecificKeyframe> end_keyframe_;
+ Member<PropertySpecificKeyframe> start_keyframe_;
+ Member<PropertySpecificKeyframe> end_keyframe_;
double current_fraction_;
mutable bool is_conversion_cached_;
mutable std::unique_ptr<PrimitiveInterpolation> cached_pair_conversion_;
diff --git a/chromium/third_party/blink/renderer/core/animation/keyframe.cc b/chromium/third_party/blink/renderer/core/animation/keyframe.cc
index c841d809d76..eceb25edfd8 100644
--- a/chromium/third_party/blink/renderer/core/animation/keyframe.cc
+++ b/chromium/third_party/blink/renderer/core/animation/keyframe.cc
@@ -20,8 +20,7 @@ Keyframe::PropertySpecificKeyframe::PropertySpecificKeyframe(
easing_ = LinearTimingFunction::Shared();
}
-scoped_refptr<Interpolation>
-Keyframe::PropertySpecificKeyframe::CreateInterpolation(
+Interpolation* Keyframe::PropertySpecificKeyframe::CreateInterpolation(
const PropertyHandle& property_handle,
const Keyframe::PropertySpecificKeyframe& end) const {
// const_cast to take refs.
@@ -38,13 +37,8 @@ void Keyframe::AddKeyframePropertiesToV8Object(
object_builder.AddNull("offset");
}
object_builder.Add("easing", easing_->ToString());
- if (composite_) {
- object_builder.AddString(
- "composite",
- EffectModel::CompositeOperationToString(composite_.value()));
- } else {
- object_builder.AddNull("composite");
- }
+ object_builder.AddString("composite",
+ EffectModel::CompositeOperationToString(composite_));
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/animation/keyframe.h b/chromium/third_party/blink/renderer/core/animation/keyframe.h
index 661b3be58cc..1baf81ce4ee 100644
--- a/chromium/third_party/blink/renderer/core/animation/keyframe.h
+++ b/chromium/third_party/blink/renderer/core/animation/keyframe.h
@@ -13,9 +13,9 @@
#include "third_party/blink/renderer/core/animation/effect_model.h"
#include "third_party/blink/renderer/core/animation/property_handle.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.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
-#include "third_party/blink/renderer/platform/wtf/ref_counted.h"
namespace blink {
@@ -35,9 +35,9 @@ class V8ObjectBuilder;
// * A non-null timing function, which applies to the period of time between
// this keyframe and the next keyframe in the same effect and influences
// the interpolation between them.
-// * An possibly-null keyframe-specific composite operation, which specifies a
-// specific composite operation used to combine values in this keyframe with
-// an underlying value. If this is null, the keyframe effect composite
+// * An keyframe-specific composite operation, which specifies a specific
+// composite operation used to combine values in this keyframe with an
+// underlying value. If this is 'auto', the keyframe effect composite
// operation is used instead.
//
// For spec details, refer to: https://drafts.csswg.org/web-animations/#keyframe
@@ -60,9 +60,7 @@ class V8ObjectBuilder;
// from the keyframe effect. See KeyframeEffectModelBase::EnsureKeyframeGroups.
//
// FIXME: Make Keyframe immutable
-class CORE_EXPORT Keyframe : public RefCounted<Keyframe> {
- USING_FAST_MALLOC(Keyframe);
-
+class CORE_EXPORT Keyframe : public GarbageCollectedFinalized<Keyframe> {
public:
virtual ~Keyframe() = default;
@@ -97,11 +95,11 @@ class CORE_EXPORT Keyframe : public RefCounted<Keyframe> {
// The clone should have the same (property, value) pairs, offset value,
// composite operation, and timing function, as well as any other
// subclass-specific data.
- virtual scoped_refptr<Keyframe> Clone() const = 0;
+ virtual Keyframe* Clone() const = 0;
// Helper function to create a clone of this keyframe with a specific offset.
- scoped_refptr<Keyframe> CloneWithOffset(double offset) const {
- scoped_refptr<Keyframe> the_clone = Clone();
+ Keyframe* CloneWithOffset(double offset) const {
+ Keyframe* the_clone = Clone();
the_clone->SetOffset(offset);
return the_clone;
}
@@ -115,11 +113,12 @@ class CORE_EXPORT Keyframe : public RefCounted<Keyframe> {
virtual bool IsStringKeyframe() const { return false; }
virtual bool IsTransitionKeyframe() const { return false; }
+ virtual void Trace(Visitor*) {}
+
// Represents a property-specific keyframe as defined in the spec. Refer to
// the Keyframe class-level documentation for more details.
- class PropertySpecificKeyframe : public RefCounted<PropertySpecificKeyframe> {
- USING_FAST_MALLOC(PropertySpecificKeyframe);
-
+ class CORE_EXPORT PropertySpecificKeyframe
+ : public GarbageCollectedFinalized<PropertySpecificKeyframe> {
public:
virtual ~PropertySpecificKeyframe() = default;
double Offset() const { return offset_; }
@@ -129,8 +128,7 @@ class CORE_EXPORT Keyframe : public RefCounted<Keyframe> {
return composite_ == EffectModel::kCompositeReplace ? 0 : 1;
}
virtual bool IsNeutral() const = 0;
- virtual scoped_refptr<PropertySpecificKeyframe> CloneWithOffset(
- double offset) const = 0;
+ virtual PropertySpecificKeyframe* CloneWithOffset(double offset) const = 0;
// FIXME: Remove this once CompositorAnimations no longer depends on
// AnimatableValues
@@ -150,13 +148,15 @@ class CORE_EXPORT Keyframe : public RefCounted<Keyframe> {
virtual bool IsSVGPropertySpecificKeyframe() const { return false; }
virtual bool IsTransitionPropertySpecificKeyframe() const { return false; }
- virtual scoped_refptr<PropertySpecificKeyframe> NeutralKeyframe(
+ virtual PropertySpecificKeyframe* NeutralKeyframe(
double offset,
scoped_refptr<TimingFunction> easing) const = 0;
- virtual scoped_refptr<Interpolation> CreateInterpolation(
+ virtual Interpolation* CreateInterpolation(
const PropertyHandle&,
const Keyframe::PropertySpecificKeyframe& end) const;
+ virtual void Trace(Visitor*){};
+
protected:
PropertySpecificKeyframe(double offset,
scoped_refptr<TimingFunction> easing,
@@ -180,8 +180,7 @@ class CORE_EXPORT Keyframe : public RefCounted<Keyframe> {
// PropertySpecificKeyframe. For CSS Transitions and CSS Animations, this is
// the normal offset from the keyframe itself. However in web-animations this
// will be a computed offset value which may differ from the keyframe offset.
- virtual scoped_refptr<PropertySpecificKeyframe>
- CreatePropertySpecificKeyframe(
+ virtual PropertySpecificKeyframe* CreatePropertySpecificKeyframe(
const PropertyHandle&,
EffectModel::CompositeOperation effect_composite,
double offset) const = 0;
@@ -198,6 +197,9 @@ class CORE_EXPORT Keyframe : public RefCounted<Keyframe> {
}
base::Optional<double> offset_;
+ // To avoid having multiple CompositeOperation enums internally (one with
+ // 'auto' and one without), we use a base::Optional for composite_. A
+ // base::nullopt value represents 'auto'.
base::Optional<EffectModel::CompositeOperation> composite_;
scoped_refptr<TimingFunction> easing_;
DISALLOW_COPY_AND_ASSIGN(Keyframe);
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 7c6607bcfd8..65f3c66962e 100644
--- a/chromium/third_party/blink/renderer/core/animation/keyframe_effect.cc
+++ b/chromium/third_party/blink/renderer/core/animation/keyframe_effect.cc
@@ -76,7 +76,8 @@ KeyframeEffect* KeyframeEffect::Create(
EffectModel::CompositeOperation composite = EffectModel::kCompositeReplace;
if (options.IsKeyframeEffectOptions()) {
composite = EffectModel::StringToCompositeOperation(
- options.GetAsKeyframeEffectOptions().composite());
+ options.GetAsKeyframeEffectOptions().composite())
+ .value();
}
KeyframeEffectModelBase* model = EffectInput::Convert(
@@ -128,13 +129,24 @@ KeyframeEffect::KeyframeEffect(Element* target,
KeyframeEffect::~KeyframeEffect() = default;
+void KeyframeEffect::setTarget(Element* target) {
+ if (target_ == target)
+ return;
+
+ DetachTarget(GetAnimation());
+ target_ = target;
+ AttachTarget(GetAnimation());
+
+ InvalidateAndNotifyOwner();
+}
+
String KeyframeEffect::composite() const {
return EffectModel::CompositeOperationToString(CompositeInternal());
}
void KeyframeEffect::setComposite(String composite_string) {
Model()->SetComposite(
- EffectModel::StringToCompositeOperation(composite_string));
+ EffectModel::StringToCompositeOperation(composite_string).value());
}
Vector<ScriptValue> KeyframeEffect::getKeyframes(ScriptState* script_state) {
@@ -191,8 +203,7 @@ void KeyframeEffect::SetKeyframes(StringKeyframeVector keyframes) {
// Changing the keyframes will invalidate any sampled effect, as well as
// potentially affect the effect owner.
- if (sampled_effect_)
- ClearEffects();
+ ClearEffects();
InvalidateAndNotifyOwner();
}
@@ -206,6 +217,7 @@ void KeyframeEffect::NotifySampledEffectRemovedFromEffectStack() {
CompositorAnimations::FailureCode
KeyframeEffect::CheckCanStartAnimationOnCompositor(
+ const base::Optional<CompositorElementIdSet>& composited_element_ids,
double animation_playback_rate) const {
if (!model_->HasFrames()) {
return CompositorAnimations::FailureCode::Actionable(
@@ -232,7 +244,7 @@ KeyframeEffect::CheckCanStartAnimationOnCompositor(
return CompositorAnimations::CheckCanStartAnimationOnCompositor(
SpecifiedTiming(), *target_, GetAnimation(), *Model(),
- animation_playback_rate);
+ composited_element_ids, animation_playback_rate);
}
void KeyframeEffect::StartAnimationOnCompositor(
@@ -242,11 +254,15 @@ void KeyframeEffect::StartAnimationOnCompositor(
double animation_playback_rate,
CompositorAnimation* compositor_animation) {
DCHECK(!HasActiveAnimationsOnCompositor());
- DCHECK(CheckCanStartAnimationOnCompositor(animation_playback_rate).Ok());
+ // TODO(petermayo): Maybe we should recheck that we can start on the
+ // compositor if we have the compositable IDs somewhere.
if (!compositor_animation)
compositor_animation = GetAnimation()->GetCompositorAnimation();
+
DCHECK(compositor_animation);
+ DCHECK(target_);
+ DCHECK(Model());
CompositorAnimations::StartAnimationOnCompositor(
*target_, group, start_time, current_time, SpecifiedTiming(),
@@ -345,7 +361,7 @@ void KeyframeEffect::ApplyEffects() {
IterationDuration(),
sampled_effect_->MutableInterpolations());
} else {
- Vector<scoped_refptr<Interpolation>> interpolations;
+ HeapVector<Member<Interpolation>> interpolations;
model_->Sample(clampTo<int>(iteration, 0), Progress().value(),
IterationDuration(), interpolations);
if (!interpolations.IsEmpty()) {
@@ -369,8 +385,8 @@ void KeyframeEffect::ApplyEffects() {
}
void KeyframeEffect::ClearEffects() {
- DCHECK(sampled_effect_);
-
+ if (!sampled_effect_)
+ return;
sampled_effect_->Clear();
sampled_effect_ = nullptr;
if (GetAnimation())
@@ -388,36 +404,46 @@ void KeyframeEffect::UpdateChildrenAndEffects() const {
DCHECK(owner_);
if (IsInEffect() && !owner_->EffectSuppressed())
const_cast<KeyframeEffect*>(this)->ApplyEffects();
- else if (sampled_effect_)
+ else
const_cast<KeyframeEffect*>(this)->ClearEffects();
}
void KeyframeEffect::Attach(AnimationEffectOwner* owner) {
- if (target_ && owner->GetAnimation()) {
- target_->EnsureElementAnimations().Animations().insert(
- owner->GetAnimation());
- target_->SetNeedsAnimationStyleRecalc();
- if (RuntimeEnabledFeatures::WebAnimationsSVGEnabled() &&
- target_->IsSVGElement())
- ToSVGElement(target_)->SetWebAnimationsPending();
- }
+ AttachTarget(owner->GetAnimation());
AnimationEffect::Attach(owner);
}
void KeyframeEffect::Detach() {
- if (target_ && GetAnimation())
- target_->GetElementAnimations()->Animations().erase(GetAnimation());
- if (sampled_effect_)
- ClearEffects();
+ DetachTarget(GetAnimation());
AnimationEffect::Detach();
}
+void KeyframeEffect::AttachTarget(Animation* animation) {
+ if (!target_ || !animation)
+ return;
+ target_->EnsureElementAnimations().Animations().insert(animation);
+ target_->SetNeedsAnimationStyleRecalc();
+ if (RuntimeEnabledFeatures::WebAnimationsSVGEnabled() &&
+ target_->IsSVGElement())
+ ToSVGElement(target_)->SetWebAnimationsPending();
+}
+
+void KeyframeEffect::DetachTarget(Animation* animation) {
+ if (target_ && animation)
+ 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
+ // update on the compositor.
+ ClearEffects();
+}
+
double KeyframeEffect::CalculateTimeToEffectChange(
bool forwards,
double local_time,
double time_to_next_iteration) const {
const double start_time = SpecifiedTiming().start_delay;
- const double end_time_minus_end_delay = start_time + ActiveDurationInternal();
+ const double end_time_minus_end_delay = start_time + RepeatedDuration();
const double end_time =
end_time_minus_end_delay + SpecifiedTiming().end_delay;
const double after_time = std::min(end_time_minus_end_delay, end_time);
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 e0689019c56..d36560a4b65 100644
--- a/chromium/third_party/blink/renderer/core/animation/keyframe_effect.h
+++ b/chromium/third_party/blink/renderer/core/animation/keyframe_effect.h
@@ -77,6 +77,7 @@ class CORE_EXPORT KeyframeEffect final : public AnimationEffect {
// IDL implementation.
Element* target() const { return target_; }
+ void setTarget(Element*);
String composite() const;
void setComposite(String);
Vector<ScriptValue> getKeyframes(ScriptState*);
@@ -98,6 +99,7 @@ class CORE_EXPORT KeyframeEffect final : public AnimationEffect {
void NotifySampledEffectRemovedFromEffectStack();
CompositorAnimations::FailureCode CheckCanStartAnimationOnCompositor(
+ const base::Optional<CompositorElementIdSet>& composited_element_ids,
double animation_playback_rate) const;
// Must only be called once.
void StartAnimationOnCompositor(int group,
@@ -139,6 +141,8 @@ class CORE_EXPORT KeyframeEffect final : public AnimationEffect {
void UpdateChildrenAndEffects() const override;
void Attach(AnimationEffectOwner*) override;
void Detach() override;
+ void AttachTarget(Animation*);
+ void DetachTarget(Animation*);
double CalculateTimeToEffectChange(
bool forwards,
double inherited_time,
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 2bf57483896..79a90965ede 100644
--- a/chromium/third_party/blink/renderer/core/animation/keyframe_effect.idl
+++ b/chromium/third_party/blink/renderer/core/animation/keyframe_effect.idl
@@ -39,7 +39,7 @@ enum CompositeOperation { "replace", "add", "accumulate" };
RaisesException=Constructor,
RuntimeEnabled=WebAnimationsAPI
] interface KeyframeEffect : AnimationEffect {
- readonly attribute Element? target;
+ attribute Element? target;
attribute CompositeOperation composite;
[CallWith=ScriptState] sequence<object> getKeyframes();
[CallWith=ScriptState, RaisesException] void setKeyframes(object? keyframes);
diff --git a/chromium/third_party/blink/renderer/core/animation/keyframe_effect_model.cc b/chromium/third_party/blink/renderer/core/animation/keyframe_effect_model.cc
index e2c6e39248e..bcd09786495 100644
--- a/chromium/third_party/blink/renderer/core/animation/keyframe_effect_model.cc
+++ b/chromium/third_party/blink/renderer/core/animation/keyframe_effect_model.cc
@@ -57,26 +57,26 @@ PropertyHandleSet KeyframeEffectModelBase::Properties() const {
}
template <class K>
-void KeyframeEffectModelBase::SetFrames(Vector<K>& keyframes) {
+void KeyframeEffectModelBase::SetFrames(HeapVector<K>& keyframes) {
// TODO(samli): Should also notify/invalidate the animation
keyframes_.clear();
keyframe_groups_ = nullptr;
- interpolation_effect_.Clear();
+ interpolation_effect_->Clear();
last_fraction_ = std::numeric_limits<double>::quiet_NaN();
keyframes_.AppendVector(keyframes);
needs_compositor_keyframes_snapshot_ = true;
}
template CORE_EXPORT void KeyframeEffectModelBase::SetFrames(
- Vector<scoped_refptr<Keyframe>>& keyframes);
+ HeapVector<Member<Keyframe>>& keyframes);
template CORE_EXPORT void KeyframeEffectModelBase::SetFrames(
- Vector<scoped_refptr<StringKeyframe>>& keyframes);
+ HeapVector<Member<StringKeyframe>>& keyframes);
bool KeyframeEffectModelBase::Sample(
int iteration,
double fraction,
double iteration_duration,
- Vector<scoped_refptr<Interpolation>>& result) const {
+ HeapVector<Member<Interpolation>>& result) const {
DCHECK_GE(iteration, 0);
EnsureKeyframeGroups();
EnsureInterpolationEffectPopulated();
@@ -86,8 +86,8 @@ bool KeyframeEffectModelBase::Sample(
last_iteration_ = iteration;
last_fraction_ = fraction;
last_iteration_duration_ = iteration_duration;
- interpolation_effect_.GetActiveInterpolations(fraction, iteration_duration,
- result);
+ interpolation_effect_->GetActiveInterpolations(fraction, iteration_duration,
+ result);
return changed;
}
@@ -165,7 +165,7 @@ bool KeyframeEffectModelBase::SnapshotAllCompositorKeyframesIfNecessary(
template <class K>
Vector<double> KeyframeEffectModelBase::GetComputedOffsets(
- const Vector<K>& keyframes) {
+ const HeapVector<K>& keyframes) {
// To avoid having to create two vectors when converting from the nullable
// offsets to the non-nullable computed offsets, we keep the convention in
// this function that std::numeric_limits::quiet_NaN() represents null.
@@ -212,9 +212,9 @@ Vector<double> KeyframeEffectModelBase::GetComputedOffsets(
}
template CORE_EXPORT Vector<double> KeyframeEffectModelBase::GetComputedOffsets(
- const Vector<scoped_refptr<Keyframe>>& keyframes);
+ const HeapVector<Member<Keyframe>>& keyframes);
template CORE_EXPORT Vector<double> KeyframeEffectModelBase::GetComputedOffsets(
- const Vector<scoped_refptr<StringKeyframe>>& keyframes);
+ const HeapVector<Member<StringKeyframe>>& keyframes);
bool KeyframeEffectModelBase::IsTransformRelatedEffect() const {
return Affects(PropertyHandle(GetCSSPropertyTransform())) ||
@@ -223,11 +223,18 @@ bool KeyframeEffectModelBase::IsTransformRelatedEffect() const {
Affects(PropertyHandle(GetCSSPropertyTranslate()));
}
+void KeyframeEffectModelBase::Trace(Visitor* visitor) {
+ visitor->Trace(keyframes_);
+ visitor->Trace(keyframe_groups_);
+ visitor->Trace(interpolation_effect_);
+ EffectModel::Trace(visitor);
+}
+
void KeyframeEffectModelBase::EnsureKeyframeGroups() const {
if (keyframe_groups_)
return;
- keyframe_groups_ = std::make_unique<KeyframeGroupMap>();
+ keyframe_groups_ = new KeyframeGroupMap;
scoped_refptr<TimingFunction> zero_offset_easing = default_keyframe_easing_;
Vector<double> computed_offsets = GetComputedOffsets(keyframes_);
DCHECK_EQ(computed_offsets.size(), keyframes_.size());
@@ -243,11 +250,10 @@ void KeyframeEffectModelBase::EnsureKeyframeGroups() const {
PropertySpecificKeyframeGroup* group;
if (group_iter == keyframe_groups_->end()) {
group = keyframe_groups_
- ->insert(property,
- std::make_unique<PropertySpecificKeyframeGroup>())
- .stored_value->value.get();
+ ->insert(property, new PropertySpecificKeyframeGroup)
+ .stored_value->value.Get();
} else {
- group = group_iter->value.get();
+ group = group_iter->value.Get();
}
group->AppendKeyframe(keyframe->CreatePropertySpecificKeyframe(
@@ -266,7 +272,7 @@ void KeyframeEffectModelBase::EnsureKeyframeGroups() const {
}
void KeyframeEffectModelBase::EnsureInterpolationEffectPopulated() const {
- if (interpolation_effect_.IsPopulated())
+ if (interpolation_effect_->IsPopulated())
return;
for (const auto& entry : *keyframe_groups_) {
@@ -297,7 +303,7 @@ void KeyframeEffectModelBase::EnsureInterpolationEffectPopulated() const {
}
if (apply_from != apply_to) {
- interpolation_effect_.AddInterpolationsFromKeyframes(
+ interpolation_effect_->AddInterpolationsFromKeyframes(
entry.key, *keyframes[start_index], *keyframes[end_index],
apply_from, apply_to);
}
@@ -305,7 +311,7 @@ void KeyframeEffectModelBase::EnsureInterpolationEffectPopulated() const {
}
}
- interpolation_effect_.SetPopulated();
+ interpolation_effect_->SetPopulated();
}
bool KeyframeEffectModelBase::IsReplaceOnly() const {
@@ -320,7 +326,7 @@ bool KeyframeEffectModelBase::IsReplaceOnly() const {
}
void KeyframeEffectModelBase::PropertySpecificKeyframeGroup::AppendKeyframe(
- scoped_refptr<Keyframe::PropertySpecificKeyframe> keyframe) {
+ Keyframe::PropertySpecificKeyframe* keyframe) {
DCHECK(keyframes_.IsEmpty() ||
keyframes_.back()->Offset() <= keyframe->Offset());
keyframes_.push_back(std::move(keyframe));
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 4aed7b4cb5f..cf8364bd3d1 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
@@ -56,14 +56,17 @@ class CORE_EXPORT KeyframeEffectModelBase : public EffectModel {
// FIXME: Implement accumulation.
using PropertySpecificKeyframeVector =
- Vector<scoped_refptr<Keyframe::PropertySpecificKeyframe>>;
- class PropertySpecificKeyframeGroup {
+ HeapVector<Member<Keyframe::PropertySpecificKeyframe>>;
+ class PropertySpecificKeyframeGroup
+ : public GarbageCollected<PropertySpecificKeyframeGroup> {
public:
- void AppendKeyframe(scoped_refptr<Keyframe::PropertySpecificKeyframe>);
+ void AppendKeyframe(Keyframe::PropertySpecificKeyframe*);
const PropertySpecificKeyframeVector& Keyframes() const {
return keyframes_;
}
+ void Trace(Visitor* visitor) { visitor->Trace(keyframes_); }
+
private:
void RemoveRedundantKeyframes();
bool AddSyntheticKeyframeIfRequired(
@@ -79,11 +82,11 @@ class CORE_EXPORT KeyframeEffectModelBase : public EffectModel {
PropertyHandleSet Properties() const;
- using KeyframeVector = Vector<scoped_refptr<Keyframe>>;
+ using KeyframeVector = HeapVector<Member<Keyframe>>;
const KeyframeVector& GetFrames() const { return keyframes_; }
bool HasFrames() const { return !keyframes_.IsEmpty(); }
template <class K>
- void SetFrames(Vector<K>& keyframes);
+ void SetFrames(HeapVector<K>& keyframes);
CompositeOperation Composite() const { return composite_; }
void SetComposite(CompositeOperation composite) { composite_ = composite; }
@@ -95,7 +98,7 @@ class CORE_EXPORT KeyframeEffectModelBase : public EffectModel {
}
using KeyframeGroupMap =
- HashMap<PropertyHandle, std::unique_ptr<PropertySpecificKeyframeGroup>>;
+ HeapHashMap<PropertyHandle, Member<PropertySpecificKeyframeGroup>>;
const KeyframeGroupMap& GetPropertySpecificKeyframeGroups() const {
EnsureKeyframeGroups();
return *keyframe_groups_;
@@ -105,7 +108,7 @@ class CORE_EXPORT KeyframeEffectModelBase : public EffectModel {
bool Sample(int iteration,
double fraction,
double iteration_duration,
- Vector<scoped_refptr<Interpolation>>&) const override;
+ HeapVector<Member<Interpolation>>&) const override;
bool IsKeyframeEffectModel() const override { return true; }
@@ -133,7 +136,7 @@ class CORE_EXPORT KeyframeEffectModelBase : public EffectModel {
const ComputedStyle* parent_style) const;
template <class K>
- static Vector<double> GetComputedOffsets(const Vector<K>& keyframes);
+ static Vector<double> GetComputedOffsets(const HeapVector<K>& keyframes);
bool Affects(const PropertyHandle& property) const override {
EnsureKeyframeGroups();
@@ -144,10 +147,13 @@ class CORE_EXPORT KeyframeEffectModelBase : public EffectModel {
virtual KeyframeEffectModelBase* Clone() = 0;
+ void Trace(Visitor*) override;
+
protected:
KeyframeEffectModelBase(CompositeOperation composite,
scoped_refptr<TimingFunction> default_keyframe_easing)
- : last_iteration_(0),
+ : interpolation_effect_(new InterpolationEffect),
+ last_iteration_(0),
last_fraction_(std::numeric_limits<double>::quiet_NaN()),
last_iteration_duration_(0),
composite_(composite),
@@ -163,8 +169,8 @@ class CORE_EXPORT KeyframeEffectModelBase : public EffectModel {
// The spec describes filtering the normalized keyframes at sampling time
// to get the 'property-specific keyframes'. For efficiency, we cache the
// property-specific lists.
- mutable std::unique_ptr<KeyframeGroupMap> keyframe_groups_;
- mutable InterpolationEffect interpolation_effect_;
+ mutable Member<KeyframeGroupMap> keyframe_groups_;
+ mutable Member<InterpolationEffect> interpolation_effect_;
mutable int last_iteration_;
mutable double last_fraction_;
mutable double last_iteration_duration_;
@@ -181,7 +187,7 @@ class CORE_EXPORT KeyframeEffectModelBase : public EffectModel {
template <class K>
class KeyframeEffectModel final : public KeyframeEffectModelBase {
public:
- using KeyframeVector = Vector<scoped_refptr<K>>;
+ using KeyframeVector = HeapVector<Member<K>>;
static KeyframeEffectModel<K>* Create(
const KeyframeVector& keyframes,
CompositeOperation composite = kCompositeReplace,
@@ -193,9 +199,8 @@ class KeyframeEffectModel final : public KeyframeEffectModelBase {
KeyframeEffectModelBase* Clone() override {
KeyframeVector keyframes;
for (const auto& keyframe : GetFrames()) {
- scoped_refptr<Keyframe> new_keyframe = keyframe->Clone();
- keyframes.push_back(
- scoped_refptr<K>(static_cast<K*>(new_keyframe.get())));
+ Keyframe* new_keyframe = keyframe->Clone();
+ keyframes.push_back(static_cast<K*>(new_keyframe));
}
return Create(keyframes, composite_, default_keyframe_easing_);
}
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 89d88f02240..8686c695914 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
@@ -52,13 +52,13 @@ class AnimationKeyframeEffectModel : public PageTestBase {
}
void ExpectLengthValue(double expected_value,
- scoped_refptr<Interpolation> interpolation_value) {
+ Interpolation* interpolation_value) {
ActiveInterpolations interpolations;
interpolations.push_back(interpolation_value);
EnsureInterpolatedValueCached(interpolations, GetDocument(), element);
const TypedInterpolationValue* typed_value =
- ToInvalidatableInterpolation(interpolation_value.get())
+ ToInvalidatableInterpolation(interpolation_value)
->GetCachedValueForTesting();
// Length values are stored as a list of values; here we assume pixels.
EXPECT_TRUE(typed_value->GetInterpolableValue().IsList());
@@ -68,15 +68,14 @@ class AnimationKeyframeEffectModel : public PageTestBase {
ToInterpolableNumber(list->Get(0))->Value());
}
- void ExpectNonInterpolableValue(
- const String& expected_value,
- scoped_refptr<Interpolation> interpolation_value) {
+ void ExpectNonInterpolableValue(const String& expected_value,
+ Interpolation* interpolation_value) {
ActiveInterpolations interpolations;
interpolations.push_back(interpolation_value);
EnsureInterpolatedValueCached(interpolations, GetDocument(), element);
const TypedInterpolationValue* typed_value =
- ToInvalidatableInterpolation(interpolation_value.get())
+ ToInvalidatableInterpolation(interpolation_value)
->GetCachedValueForTesting();
const NonInterpolableValue* non_interpolable_value =
typed_value->GetNonInterpolableValue();
@@ -108,22 +107,22 @@ StringKeyframeVector KeyframesAtZeroAndOne(CSSPropertyID property,
}
void ExpectProperty(CSSPropertyID property,
- scoped_refptr<Interpolation> interpolation_value) {
+ Interpolation* interpolation_value) {
InvalidatableInterpolation* interpolation =
- ToInvalidatableInterpolation(interpolation_value.get());
+ ToInvalidatableInterpolation(interpolation_value);
const PropertyHandle& property_handle = interpolation->GetProperty();
ASSERT_TRUE(property_handle.IsCSSProperty());
ASSERT_EQ(property, property_handle.GetCSSProperty().PropertyID());
}
-Interpolation* FindValue(Vector<scoped_refptr<Interpolation>>& values,
+Interpolation* FindValue(HeapVector<Member<Interpolation>>& values,
CSSPropertyID id) {
for (auto& value : values) {
const PropertyHandle& property =
- ToInvalidatableInterpolation(value.get())->GetProperty();
+ ToInvalidatableInterpolation(value)->GetProperty();
if (property.IsCSSProperty() &&
property.GetCSSProperty().PropertyID() == id)
- return value.get();
+ return value;
}
return nullptr;
}
@@ -133,7 +132,7 @@ TEST_F(AnimationKeyframeEffectModel, BasicOperation) {
KeyframesAtZeroAndOne(CSSPropertyFontFamily, "serif", "cursive");
StringKeyframeEffectModel* effect =
StringKeyframeEffectModel::Create(keyframes);
- Vector<scoped_refptr<Interpolation>> values;
+ HeapVector<Member<Interpolation>> values;
effect->Sample(0, 0.6, kDuration, values);
ASSERT_EQ(1UL, values.size());
ExpectProperty(CSSPropertyFontFamily, values.at(0));
@@ -147,7 +146,7 @@ TEST_F(AnimationKeyframeEffectModel, CompositeReplaceNonInterpolable) {
keyframes[1]->SetComposite(EffectModel::kCompositeReplace);
StringKeyframeEffectModel* effect =
StringKeyframeEffectModel::Create(keyframes);
- Vector<scoped_refptr<Interpolation>> values;
+ HeapVector<Member<Interpolation>> values;
effect->Sample(0, 0.6, kDuration, values);
ExpectNonInterpolableValue("cursive", values.at(0));
}
@@ -159,7 +158,7 @@ TEST_F(AnimationKeyframeEffectModel, CompositeReplace) {
keyframes[1]->SetComposite(EffectModel::kCompositeReplace);
StringKeyframeEffectModel* effect =
StringKeyframeEffectModel::Create(keyframes);
- Vector<scoped_refptr<Interpolation>> values;
+ HeapVector<Member<Interpolation>> values;
effect->Sample(0, 0.6, kDuration, values);
ExpectLengthValue(3.0 * 0.4 + 5.0 * 0.6, values.at(0));
}
@@ -172,7 +171,7 @@ TEST_F(AnimationKeyframeEffectModel, DISABLED_CompositeAdd) {
keyframes[1]->SetComposite(EffectModel::kCompositeAdd);
StringKeyframeEffectModel* effect =
StringKeyframeEffectModel::Create(keyframes);
- Vector<scoped_refptr<Interpolation>> values;
+ HeapVector<Member<Interpolation>> values;
effect->Sample(0, 0.6, kDuration, values);
ExpectLengthValue((7.0 + 3.0) * 0.4 + (7.0 + 5.0) * 0.6, values.at(0));
}
@@ -186,7 +185,7 @@ TEST_F(AnimationKeyframeEffectModel, CompositeEaseIn) {
keyframes[1]->SetComposite(EffectModel::kCompositeReplace);
StringKeyframeEffectModel* effect =
StringKeyframeEffectModel::Create(keyframes);
- Vector<scoped_refptr<Interpolation>> values;
+ HeapVector<Member<Interpolation>> values;
effect->Sample(0, 0.6, kDuration, values);
ExpectLengthValue(3.8579516, values.at(0));
effect->Sample(0, 0.6, kDuration * 100, values);
@@ -201,7 +200,7 @@ TEST_F(AnimationKeyframeEffectModel, CompositeCubicBezier) {
keyframes[1]->SetComposite(EffectModel::kCompositeReplace);
StringKeyframeEffectModel* effect =
StringKeyframeEffectModel::Create(keyframes);
- Vector<scoped_refptr<Interpolation>> values;
+ HeapVector<Member<Interpolation>> values;
effect->Sample(0, 0.6, kDuration, values);
ExpectLengthValue(4.3363357, values.at(0));
effect->Sample(0, 0.6, kDuration * 1000, values);
@@ -215,7 +214,7 @@ TEST_F(AnimationKeyframeEffectModel, ExtrapolateReplaceNonInterpolable) {
keyframes[1]->SetComposite(EffectModel::kCompositeReplace);
StringKeyframeEffectModel* effect =
StringKeyframeEffectModel::Create(keyframes);
- Vector<scoped_refptr<Interpolation>> values;
+ HeapVector<Member<Interpolation>> values;
effect->Sample(0, 1.6, kDuration, values);
ExpectNonInterpolableValue("cursive", values.at(0));
}
@@ -227,7 +226,7 @@ TEST_F(AnimationKeyframeEffectModel, ExtrapolateReplace) {
StringKeyframeEffectModel::Create(keyframes);
keyframes[0]->SetComposite(EffectModel::kCompositeReplace);
keyframes[1]->SetComposite(EffectModel::kCompositeReplace);
- Vector<scoped_refptr<Interpolation>> values;
+ HeapVector<Member<Interpolation>> values;
effect->Sample(0, 1.6, kDuration, values);
ExpectLengthValue(3.0 * -0.6 + 5.0 * 1.6, values.at(0));
}
@@ -240,7 +239,7 @@ TEST_F(AnimationKeyframeEffectModel, DISABLED_ExtrapolateAdd) {
keyframes[1]->SetComposite(EffectModel::kCompositeAdd);
StringKeyframeEffectModel* effect =
StringKeyframeEffectModel::Create(keyframes);
- Vector<scoped_refptr<Interpolation>> values;
+ HeapVector<Member<Interpolation>> values;
effect->Sample(0, 1.6, kDuration, values);
ExpectLengthValue((7.0 + 3.0) * -0.6 + (7.0 + 5.0) * 1.6, values.at(0));
}
@@ -248,7 +247,7 @@ TEST_F(AnimationKeyframeEffectModel, DISABLED_ExtrapolateAdd) {
TEST_F(AnimationKeyframeEffectModel, ZeroKeyframes) {
StringKeyframeEffectModel* effect =
StringKeyframeEffectModel::Create(StringKeyframeVector());
- Vector<scoped_refptr<Interpolation>> values;
+ HeapVector<Member<Interpolation>> values;
effect->Sample(0, 0.5, kDuration, values);
EXPECT_TRUE(values.IsEmpty());
}
@@ -264,7 +263,7 @@ TEST_F(AnimationKeyframeEffectModel, DISABLED_SingleKeyframeAtOffsetZero) {
StringKeyframeEffectModel* effect =
StringKeyframeEffectModel::Create(keyframes);
- Vector<scoped_refptr<Interpolation>> values;
+ HeapVector<Member<Interpolation>> values;
effect->Sample(0, 0.6, kDuration, values);
ExpectNonInterpolableValue("serif", values.at(0));
}
@@ -279,7 +278,7 @@ TEST_F(AnimationKeyframeEffectModel, DISABLED_SingleKeyframeAtOffsetOne) {
StringKeyframeEffectModel* effect =
StringKeyframeEffectModel::Create(keyframes);
- Vector<scoped_refptr<Interpolation>> values;
+ HeapVector<Member<Interpolation>> values;
effect->Sample(0, 0.6, kDuration, values);
ExpectLengthValue(7.0 * 0.4 + 5.0 * 0.6, values.at(0));
}
@@ -304,7 +303,7 @@ TEST_F(AnimationKeyframeEffectModel, MoreThanTwoKeyframes) {
StringKeyframeEffectModel* effect =
StringKeyframeEffectModel::Create(keyframes);
- Vector<scoped_refptr<Interpolation>> values;
+ HeapVector<Member<Interpolation>> values;
effect->Sample(0, 0.3, kDuration, values);
ExpectNonInterpolableValue("sans-serif", values.at(0));
effect->Sample(0, 0.8, kDuration, values);
@@ -329,7 +328,7 @@ TEST_F(AnimationKeyframeEffectModel, EndKeyframeOffsetsUnspecified) {
StringKeyframeEffectModel* effect =
StringKeyframeEffectModel::Create(keyframes);
- Vector<scoped_refptr<Interpolation>> values;
+ HeapVector<Member<Interpolation>> values;
effect->Sample(0, 0.1, kDuration, values);
ExpectNonInterpolableValue("serif", values.at(0));
effect->Sample(0, 0.6, kDuration, values);
@@ -358,7 +357,7 @@ TEST_F(AnimationKeyframeEffectModel, SampleOnKeyframe) {
StringKeyframeEffectModel* effect =
StringKeyframeEffectModel::Create(keyframes);
- Vector<scoped_refptr<Interpolation>> values;
+ HeapVector<Member<Interpolation>> values;
effect->Sample(0, 0.0, kDuration, values);
ExpectNonInterpolableValue("serif", values.at(0));
effect->Sample(0, 0.5, kDuration, values);
@@ -417,7 +416,7 @@ TEST_F(AnimationKeyframeEffectModel, MultipleKeyframesWithSameOffset) {
StringKeyframeEffectModel* effect =
StringKeyframeEffectModel::Create(keyframes);
- Vector<scoped_refptr<Interpolation>> values;
+ HeapVector<Member<Interpolation>> values;
effect->Sample(0, 0.0, kDuration, values);
ExpectNonInterpolableValue("serif", values.at(0));
effect->Sample(0, 0.2, kDuration, values);
@@ -449,7 +448,7 @@ TEST_F(AnimationKeyframeEffectModel, DISABLED_PerKeyframeComposite) {
StringKeyframeEffectModel* effect =
StringKeyframeEffectModel::Create(keyframes);
- Vector<scoped_refptr<Interpolation>> values;
+ HeapVector<Member<Interpolation>> values;
effect->Sample(0, 0.6, kDuration, values);
ExpectLengthValue(3.0 * 0.4 + (7.0 + 5.0) * 0.6, values.at(0));
}
@@ -475,7 +474,7 @@ TEST_F(AnimationKeyframeEffectModel, MultipleProperties) {
StringKeyframeEffectModel* effect =
StringKeyframeEffectModel::Create(keyframes);
- Vector<scoped_refptr<Interpolation>> values;
+ HeapVector<Member<Interpolation>> values;
effect->Sample(0, 0.6, kDuration, values);
EXPECT_EQ(2UL, values.size());
Interpolation* left_value = FindValue(values, CSSPropertyFontFamily);
@@ -494,7 +493,7 @@ TEST_F(AnimationKeyframeEffectModel, DISABLED_RecompositeCompositableValue) {
keyframes[1]->SetComposite(EffectModel::kCompositeAdd);
StringKeyframeEffectModel* effect =
StringKeyframeEffectModel::Create(keyframes);
- Vector<scoped_refptr<Interpolation>> values;
+ HeapVector<Member<Interpolation>> values;
effect->Sample(0, 0.6, kDuration, values);
ExpectLengthValue((7.0 + 3.0) * 0.4 + (7.0 + 5.0) * 0.6, values.at(0));
ExpectLengthValue((9.0 + 3.0) * 0.4 + (9.0 + 5.0) * 0.6, values.at(1));
@@ -505,7 +504,7 @@ TEST_F(AnimationKeyframeEffectModel, MultipleIterations) {
KeyframesAtZeroAndOne(CSSPropertyLeft, "1px", "3px");
StringKeyframeEffectModel* effect =
StringKeyframeEffectModel::Create(keyframes);
- Vector<scoped_refptr<Interpolation>> values;
+ HeapVector<Member<Interpolation>> values;
effect->Sample(0, 0.5, kDuration, values);
ExpectLengthValue(2.0, values.at(0));
effect->Sample(1, 0.5, kDuration, values);
@@ -533,7 +532,7 @@ TEST_F(AnimationKeyframeEffectModel, DISABLED_DependsOnUnderlyingValue) {
StringKeyframeEffectModel* effect =
StringKeyframeEffectModel::Create(keyframes);
- Vector<scoped_refptr<Interpolation>> values;
+ HeapVector<Member<Interpolation>> values;
effect->Sample(0, 0, kDuration, values);
EXPECT_TRUE(values.at(0));
effect->Sample(0, 0.1, kDuration, values);
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 8f70fa7f54a..cbb634293ca 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
@@ -108,10 +108,10 @@ TEST_F(AnimationKeyframeEffectV8Test, CanCreateAnAnimation) {
EXPECT_EQ(1, keyframes[1]->CheckedOffset());
const CSSValue& keyframe1_width =
- ToStringKeyframe(keyframes[0].get())
+ ToStringKeyframe(keyframes[0])
->CssPropertyValue(PropertyHandle(GetCSSPropertyWidth()));
const CSSValue& keyframe2_width =
- ToStringKeyframe(keyframes[1].get())
+ ToStringKeyframe(keyframes[1])
->CssPropertyValue(PropertyHandle(GetCSSPropertyWidth()));
EXPECT_EQ("100px", keyframe1_width.CssText());
@@ -358,69 +358,4 @@ TEST_F(KeyframeEffectTest, TimeToEffectChange) {
EXPECT_EQ(100, keyframe_effect->TimeToReverseEffectChange());
}
-TEST_F(KeyframeEffectTest, TimeToEffectChangeWithPlaybackRate) {
- Timing timing;
- timing.iteration_duration = 100;
- timing.start_delay = 100;
- timing.end_delay = 100;
- timing.playback_rate = 2;
- timing.fill_mode = Timing::FillMode::NONE;
- KeyframeEffect* keyframe_effect =
- KeyframeEffect::Create(nullptr, CreateEmptyEffectModel(), timing);
- Animation* animation = GetDocument().Timeline().Play(keyframe_effect);
- double inf = std::numeric_limits<double>::infinity();
-
- EXPECT_EQ(100, keyframe_effect->TimeToForwardsEffectChange());
- EXPECT_EQ(inf, keyframe_effect->TimeToReverseEffectChange());
-
- animation->SetCurrentTimeInternal(100);
- EXPECT_EQ(50, keyframe_effect->TimeToForwardsEffectChange());
- EXPECT_EQ(0, keyframe_effect->TimeToReverseEffectChange());
-
- animation->SetCurrentTimeInternal(149);
- EXPECT_EQ(1, keyframe_effect->TimeToForwardsEffectChange());
- EXPECT_EQ(0, keyframe_effect->TimeToReverseEffectChange());
-
- animation->SetCurrentTimeInternal(150);
- // End-exclusive.
- EXPECT_EQ(inf, keyframe_effect->TimeToForwardsEffectChange());
- EXPECT_EQ(0, keyframe_effect->TimeToReverseEffectChange());
-
- animation->SetCurrentTimeInternal(200);
- EXPECT_EQ(inf, keyframe_effect->TimeToForwardsEffectChange());
- EXPECT_EQ(50, keyframe_effect->TimeToReverseEffectChange());
-}
-
-TEST_F(KeyframeEffectTest, TimeToEffectChangeWithNegativePlaybackRate) {
- Timing timing;
- timing.iteration_duration = 100;
- timing.start_delay = 100;
- timing.end_delay = 100;
- timing.playback_rate = -2;
- timing.fill_mode = Timing::FillMode::NONE;
- KeyframeEffect* keyframe_effect =
- KeyframeEffect::Create(nullptr, CreateEmptyEffectModel(), timing);
- Animation* animation = GetDocument().Timeline().Play(keyframe_effect);
- double inf = std::numeric_limits<double>::infinity();
-
- EXPECT_EQ(100, keyframe_effect->TimeToForwardsEffectChange());
- EXPECT_EQ(inf, keyframe_effect->TimeToReverseEffectChange());
-
- animation->SetCurrentTimeInternal(100);
- EXPECT_EQ(50, keyframe_effect->TimeToForwardsEffectChange());
- EXPECT_EQ(0, keyframe_effect->TimeToReverseEffectChange());
-
- animation->SetCurrentTimeInternal(149);
- EXPECT_EQ(1, keyframe_effect->TimeToForwardsEffectChange());
- EXPECT_EQ(0, keyframe_effect->TimeToReverseEffectChange());
-
- animation->SetCurrentTimeInternal(150);
- EXPECT_EQ(inf, keyframe_effect->TimeToForwardsEffectChange());
- EXPECT_EQ(0, keyframe_effect->TimeToReverseEffectChange());
-
- animation->SetCurrentTimeInternal(200);
- EXPECT_EQ(inf, keyframe_effect->TimeToForwardsEffectChange());
- EXPECT_EQ(50, keyframe_effect->TimeToReverseEffectChange());
-}
-
} // namespace blink
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 443cb687710..59853983d96 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
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/animation/list_interpolation_functions.h"
#include <memory>
+#include "base/callback.h"
#include "third_party/blink/renderer/core/animation/underlying_value_owner.h"
#include "third_party/blink/renderer/core/css/css_value_list.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
@@ -132,7 +133,7 @@ PairwiseInterpolationValue ListInterpolationFunctions::MaybeMergeSingles(
InterpolationValue end(end_interpolable_list.Get(i % end_length)->Clone(),
end_non_interpolable_list.Get(i % end_length));
PairwiseInterpolationValue result =
- merge_single_item_conversions(std::move(start), std::move(end));
+ merge_single_item_conversions.Run(std::move(start), std::move(end));
if (!result)
return nullptr;
result_start_interpolable_list->Set(
@@ -242,8 +243,8 @@ static bool NonInterpolableListsAreCompatible(
ListInterpolationFunctions::LengthMatchingStrategy::
kLowestCommonMultiple ||
(i < a.length() && i < b.length())) {
- if (!non_interpolable_values_are_compatible(a.Get(i % a.length()),
- b.Get(i % b.length()))) {
+ if (!non_interpolable_values_are_compatible.Run(a.Get(i % a.length()),
+ b.Get(i % b.length()))) {
return false;
}
}
@@ -304,11 +305,11 @@ void ListInterpolationFunctions::Composite(
ToNonInterpolableList(*underlying_value.non_interpolable_value);
for (size_t i = 0; i < final_length; i++) {
- composite_item(underlying_interpolable_list.GetMutable(i),
- underlying_non_interpolable_list.GetMutable(i),
- underlying_fraction,
- *interpolable_list.Get(i % value_length),
- non_interpolable_list.Get(i % value_length));
+ composite_item.Run(underlying_interpolable_list.GetMutable(i),
+ underlying_non_interpolable_list.GetMutable(i),
+ underlying_fraction,
+ *interpolable_list.Get(i % value_length),
+ non_interpolable_list.Get(i % value_length));
}
} else {
DCHECK_EQ(length_matching_strategy, LengthMatchingStrategy::kPadToLargest);
@@ -322,10 +323,10 @@ void ListInterpolationFunctions::Composite(
ToNonInterpolableList(*underlying_value.non_interpolable_value);
for (size_t i = 0; i < value_length; i++) {
- composite_item(underlying_interpolable_list.GetMutable(i),
- underlying_non_interpolable_list.GetMutable(i),
- underlying_fraction, *interpolable_list.Get(i),
- non_interpolable_list.Get(i));
+ composite_item.Run(underlying_interpolable_list.GetMutable(i),
+ underlying_non_interpolable_list.GetMutable(i),
+ underlying_fraction, *interpolable_list.Get(i),
+ non_interpolable_list.Get(i));
}
for (size_t i = value_length; i < final_length; i++) {
underlying_interpolable_list.GetMutable(i)->Scale(underlying_fraction);
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 252b2a69c49..721610409cf 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
@@ -26,8 +26,9 @@ class ListInterpolationFunctions {
enum class LengthMatchingStrategy { kLowestCommonMultiple, kPadToLargest };
using MergeSingleItemConversionsCallback =
- PairwiseInterpolationValue (*)(InterpolationValue&& start,
- InterpolationValue&& end);
+ base::RepeatingCallback<PairwiseInterpolationValue(InterpolationValue&&,
+ InterpolationValue&&)>;
+
static PairwiseInterpolationValue MaybeMergeSingles(
InterpolationValue&& start,
InterpolationValue&& end,
@@ -41,12 +42,14 @@ class ListInterpolationFunctions {
EqualNonInterpolableValuesCallback);
using NonInterpolableValuesAreCompatibleCallback =
- bool (*)(const NonInterpolableValue*, const NonInterpolableValue*);
- using CompositeItemCallback = void (*)(std::unique_ptr<InterpolableValue>&,
- scoped_refptr<NonInterpolableValue>&,
- double underlying_fraction,
- const InterpolableValue&,
- const NonInterpolableValue*);
+ base::RepeatingCallback<bool(const NonInterpolableValue*,
+ const NonInterpolableValue*)>;
+ using CompositeItemCallback =
+ base::RepeatingCallback<void(std::unique_ptr<InterpolableValue>&,
+ scoped_refptr<NonInterpolableValue>&,
+ double underlying_fraction,
+ const InterpolableValue&,
+ const NonInterpolableValue*)>;
static void Composite(UnderlyingValueOwner&,
double underlying_fraction,
const InterpolationType&,
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 e0f74eabda8..89472a8b0bd 100644
--- a/chromium/third_party/blink/renderer/core/animation/sampled_effect.cc
+++ b/chromium/third_party/blink/renderer/core/animation/sampled_effect.cc
@@ -24,12 +24,12 @@ bool SampledEffect::WillNeverChange() const {
void SampledEffect::RemoveReplacedInterpolations(
const HashSet<PropertyHandle>& replaced_properties) {
- size_t new_size = 0;
- for (auto& interpolation : interpolations_) {
- if (!replaced_properties.Contains(interpolation->GetProperty()))
- interpolations_[new_size++].swap(interpolation);
- }
- interpolations_.Shrink(new_size);
+ auto* new_end = std::remove_if(
+ interpolations_.begin(), interpolations_.end(),
+ [&](const auto& interpolation) {
+ return replaced_properties.Contains(interpolation->GetProperty());
+ });
+ interpolations_.Shrink(new_end - interpolations_.begin());
}
void SampledEffect::UpdateReplacedProperties(
@@ -42,6 +42,7 @@ void SampledEffect::UpdateReplacedProperties(
void SampledEffect::Trace(blink::Visitor* visitor) {
visitor->Trace(effect_);
+ visitor->Trace(interpolations_);
}
} // namespace blink
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 be12c59a22b..db153c4c39a 100644
--- a/chromium/third_party/blink/renderer/core/animation/sampled_effect.h
+++ b/chromium/third_party/blink/renderer/core/animation/sampled_effect.h
@@ -25,10 +25,10 @@ class SampledEffect : public GarbageCollectedFinalized<SampledEffect> {
void Clear();
- const Vector<scoped_refptr<Interpolation>>& Interpolations() const {
+ const HeapVector<Member<Interpolation>>& Interpolations() const {
return interpolations_;
}
- Vector<scoped_refptr<Interpolation>>& MutableInterpolations() {
+ HeapVector<Member<Interpolation>>& MutableInterpolations() {
return interpolations_;
}
@@ -45,7 +45,7 @@ class SampledEffect : public GarbageCollectedFinalized<SampledEffect> {
SampledEffect(KeyframeEffect*, unsigned sequence_number);
WeakMember<KeyframeEffect> effect_;
- Vector<scoped_refptr<Interpolation>> interpolations_;
+ HeapVector<Member<Interpolation>> interpolations_;
const unsigned sequence_number_;
KeyframeEffect::Priority priority_;
DISALLOW_COPY_AND_ASSIGN(SampledEffect);
diff --git a/chromium/third_party/blink/renderer/core/animation/string_keyframe.cc b/chromium/third_party/blink/renderer/core/animation/string_keyframe.cc
index d4b79dfe286..8fcfbe35163 100644
--- a/chromium/third_party/blink/renderer/core/animation/string_keyframe.cc
+++ b/chromium/third_party/blink/renderer/core/animation/string_keyframe.cc
@@ -134,11 +134,17 @@ void StringKeyframe::AddKeyframePropertiesToV8Object(
}
}
-scoped_refptr<Keyframe> StringKeyframe::Clone() const {
- return base::AdoptRef(new StringKeyframe(*this));
+void StringKeyframe::Trace(Visitor* visitor) {
+ visitor->Trace(css_property_map_);
+ visitor->Trace(presentation_attribute_map_);
+ Keyframe::Trace(visitor);
}
-scoped_refptr<Keyframe::PropertySpecificKeyframe>
+Keyframe* StringKeyframe::Clone() const {
+ return new StringKeyframe(*this);
+}
+
+Keyframe::PropertySpecificKeyframe*
StringKeyframe::CreatePropertySpecificKeyframe(
const PropertyHandle& property,
EffectModel::CompositeOperation effect_composite,
@@ -172,28 +178,34 @@ bool StringKeyframe::CSSPropertySpecificKeyframe::PopulateAnimatableValue(
return true;
}
-scoped_refptr<Keyframe::PropertySpecificKeyframe>
+Keyframe::PropertySpecificKeyframe*
StringKeyframe::CSSPropertySpecificKeyframe::NeutralKeyframe(
double offset,
scoped_refptr<TimingFunction> easing) const {
return Create(offset, std::move(easing), nullptr, EffectModel::kCompositeAdd);
}
-scoped_refptr<Keyframe::PropertySpecificKeyframe>
+void StringKeyframe::CSSPropertySpecificKeyframe::Trace(Visitor* visitor) {
+ visitor->Trace(value_);
+ visitor->Trace(animatable_value_cache_);
+ Keyframe::PropertySpecificKeyframe::Trace(visitor);
+}
+
+Keyframe::PropertySpecificKeyframe*
StringKeyframe::CSSPropertySpecificKeyframe::CloneWithOffset(
double offset) const {
- scoped_refptr<CSSPropertySpecificKeyframe> clone =
+ CSSPropertySpecificKeyframe* clone =
Create(offset, easing_, value_.Get(), composite_);
clone->animatable_value_cache_ = animatable_value_cache_;
return clone;
}
-scoped_refptr<Keyframe::PropertySpecificKeyframe>
+Keyframe::PropertySpecificKeyframe*
SVGPropertySpecificKeyframe::CloneWithOffset(double offset) const {
return Create(offset, easing_, value_, composite_);
}
-scoped_refptr<Keyframe::PropertySpecificKeyframe>
+Keyframe::PropertySpecificKeyframe*
SVGPropertySpecificKeyframe::NeutralKeyframe(
double offset,
scoped_refptr<TimingFunction> easing) const {
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 7721780f859..c503feaf784 100644
--- a/chromium/third_party/blink/renderer/core/animation/string_keyframe.h
+++ b/chromium/third_party/blink/renderer/core/animation/string_keyframe.h
@@ -27,9 +27,7 @@ class StyleSheetContents;
// expand shorthand properties; that is done for computed keyframes.
class CORE_EXPORT StringKeyframe : public Keyframe {
public:
- static scoped_refptr<StringKeyframe> Create() {
- return base::AdoptRef(new StringKeyframe);
- }
+ static StringKeyframe* Create() { return new StringKeyframe; }
MutableCSSPropertyValueSet::SetResult SetCSSPropertyValue(
const AtomicString& property_name,
@@ -80,16 +78,18 @@ class CORE_EXPORT StringKeyframe : public Keyframe {
void AddKeyframePropertiesToV8Object(V8ObjectBuilder&) const override;
+ void Trace(Visitor*) override;
+
class CSSPropertySpecificKeyframe
: public Keyframe::PropertySpecificKeyframe {
public:
- static scoped_refptr<CSSPropertySpecificKeyframe> Create(
+ static CSSPropertySpecificKeyframe* Create(
double offset,
scoped_refptr<TimingFunction> easing,
const CSSValue* value,
EffectModel::CompositeOperation composite) {
- return base::AdoptRef(new CSSPropertySpecificKeyframe(
- offset, std::move(easing), value, composite));
+ return new CSSPropertySpecificKeyframe(offset, std::move(easing), value,
+ composite);
}
const CSSValue* Value() const { return value_.Get(); }
@@ -99,14 +99,16 @@ class CORE_EXPORT StringKeyframe : public Keyframe {
const ComputedStyle& base_style,
const ComputedStyle* parent_style) const final;
const AnimatableValue* GetAnimatableValue() const final {
- return animatable_value_cache_.get();
+ return animatable_value_cache_;
}
bool IsNeutral() const final { return !value_; }
- scoped_refptr<Keyframe::PropertySpecificKeyframe> NeutralKeyframe(
+ Keyframe::PropertySpecificKeyframe* NeutralKeyframe(
double offset,
scoped_refptr<TimingFunction> easing) const final;
+ void Trace(Visitor*) override;
+
private:
CSSPropertySpecificKeyframe(double offset,
scoped_refptr<TimingFunction> easing,
@@ -117,35 +119,34 @@ class CORE_EXPORT StringKeyframe : public Keyframe {
composite),
value_(value) {}
- scoped_refptr<Keyframe::PropertySpecificKeyframe> CloneWithOffset(
+ Keyframe::PropertySpecificKeyframe* CloneWithOffset(
double offset) const override;
bool IsCSSPropertySpecificKeyframe() const override { return true; }
- Persistent<const CSSValue> value_;
- mutable scoped_refptr<AnimatableValue> animatable_value_cache_;
+ Member<const CSSValue> value_;
+ mutable Member<AnimatableValue> animatable_value_cache_;
};
class SVGPropertySpecificKeyframe
: public Keyframe::PropertySpecificKeyframe {
public:
- static scoped_refptr<SVGPropertySpecificKeyframe> Create(
+ static SVGPropertySpecificKeyframe* Create(
double offset,
scoped_refptr<TimingFunction> easing,
const String& value,
EffectModel::CompositeOperation composite) {
- return base::AdoptRef(new SVGPropertySpecificKeyframe(
- offset, std::move(easing), value, composite));
+ return new SVGPropertySpecificKeyframe(offset, std::move(easing), value,
+ composite);
}
const String& Value() const { return value_; }
- scoped_refptr<PropertySpecificKeyframe> CloneWithOffset(
- double offset) const final;
+ PropertySpecificKeyframe* CloneWithOffset(double offset) const final;
const AnimatableValue* GetAnimatableValue() const final { return nullptr; }
bool IsNeutral() const final { return value_.IsNull(); }
- scoped_refptr<PropertySpecificKeyframe> NeutralKeyframe(
+ PropertySpecificKeyframe* NeutralKeyframe(
double offset,
scoped_refptr<TimingFunction> easing) const final;
@@ -164,26 +165,26 @@ class CORE_EXPORT StringKeyframe : public Keyframe {
String value_;
};
- private:
+ protected:
StringKeyframe()
: css_property_map_(
MutableCSSPropertyValueSet::Create(kHTMLStandardMode)),
presentation_attribute_map_(
MutableCSSPropertyValueSet::Create(kHTMLStandardMode)) {}
+ private:
StringKeyframe(const StringKeyframe& copy_from);
- scoped_refptr<Keyframe> Clone() const override;
- scoped_refptr<Keyframe::PropertySpecificKeyframe>
- CreatePropertySpecificKeyframe(
+ Keyframe* Clone() const override;
+ Keyframe::PropertySpecificKeyframe* CreatePropertySpecificKeyframe(
const PropertyHandle&,
EffectModel::CompositeOperation effect_composite,
double offset) const override;
bool IsStringKeyframe() const override { return true; }
- Persistent<MutableCSSPropertyValueSet> css_property_map_;
- Persistent<MutableCSSPropertyValueSet> presentation_attribute_map_;
+ Member<MutableCSSPropertyValueSet> css_property_map_;
+ Member<MutableCSSPropertyValueSet> presentation_attribute_map_;
HashMap<const QualifiedName*, String> svg_attribute_map_;
};
diff --git a/chromium/third_party/blink/renderer/core/animation/timing.h b/chromium/third_party/blink/renderer/core/animation/timing.h
index 44b1fd03d51..1418fbfef07 100644
--- a/chromium/third_party/blink/renderer/core/animation/timing.h
+++ b/chromium/third_party/blink/renderer/core/animation/timing.h
@@ -62,7 +62,6 @@ struct Timing {
iteration_start(0),
iteration_count(1),
iteration_duration(std::numeric_limits<double>::quiet_NaN()),
- playback_rate(1),
direction(PlaybackDirection::NORMAL),
timing_function(LinearTimingFunction::Shared()) {}
@@ -73,7 +72,6 @@ struct Timing {
DCHECK_GE(iteration_start, 0);
DCHECK_GE(iteration_count, 0);
DCHECK(std::isnan(iteration_duration) || iteration_duration >= 0);
- DCHECK(std::isfinite(playback_rate));
DCHECK(timing_function);
}
@@ -85,7 +83,6 @@ struct Timing {
((std::isnan(iteration_duration) &&
std::isnan(other.iteration_duration)) ||
iteration_duration == other.iteration_duration) &&
- playback_rate == other.playback_rate &&
direction == other.direction &&
DataEquivalent(timing_function.get(), other.timing_function.get());
}
@@ -99,8 +96,6 @@ struct Timing {
double iteration_count;
double iteration_duration;
- // TODO(crbug.com/630915) Remove playbackRate
- double playback_rate;
PlaybackDirection direction;
scoped_refptr<TimingFunction> timing_function;
};
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 c777bed483f..781f6598134 100644
--- a/chromium/third_party/blink/renderer/core/animation/timing_calculations.h
+++ b/chromium/third_party/blink/renderer/core/animation/timing_calculations.h
@@ -110,10 +110,9 @@ static inline double CalculateActiveTime(double active_duration,
}
}
-static inline double CalculateScaledActiveTime(double active_duration,
+static inline double CalculateOffsetActiveTime(double active_duration,
double active_time,
- double start_offset,
- const Timing& specified) {
+ double start_offset) {
DCHECK_GE(active_duration, 0);
DCHECK_GE(start_offset, 0);
@@ -122,17 +121,10 @@ static inline double CalculateScaledActiveTime(double active_duration,
DCHECK(active_time >= 0 && active_time <= active_duration);
- if (specified.playback_rate == 0)
- return start_offset;
-
if (!std::isfinite(active_time))
return std::numeric_limits<double>::infinity();
- return MultiplyZeroAlwaysGivesZero(specified.playback_rate < 0
- ? active_time - active_duration
- : active_time,
- specified.playback_rate) +
- start_offset;
+ return active_time + start_offset;
}
static inline bool EndsOnIterationBoundary(double iteration_count,
@@ -145,7 +137,7 @@ static inline bool EndsOnIterationBoundary(double iteration_count,
// text.
static inline double CalculateIterationTime(double iteration_duration,
double repeated_duration,
- double scaled_active_time,
+ double offset_active_time,
double start_offset,
AnimationEffect::Phase phase,
const Timing& specified) {
@@ -154,26 +146,26 @@ static inline double CalculateIterationTime(double iteration_duration,
MultiplyZeroAlwaysGivesZero(iteration_duration,
specified.iteration_count));
- if (IsNull(scaled_active_time))
+ if (IsNull(offset_active_time))
return NullValue();
- DCHECK_GE(scaled_active_time, 0);
- DCHECK_LE(scaled_active_time, repeated_duration + start_offset);
+ DCHECK_GE(offset_active_time, 0);
+ DCHECK_LE(offset_active_time, repeated_duration + start_offset);
- if (!std::isfinite(scaled_active_time) ||
- (scaled_active_time - start_offset == repeated_duration &&
+ if (!std::isfinite(offset_active_time) ||
+ (offset_active_time - start_offset == repeated_duration &&
specified.iteration_count &&
EndsOnIterationBoundary(specified.iteration_count,
specified.iteration_start)))
return iteration_duration;
- DCHECK(std::isfinite(scaled_active_time));
- double iteration_time = fmod(scaled_active_time, iteration_duration);
+ DCHECK(std::isfinite(offset_active_time));
+ double iteration_time = fmod(offset_active_time, iteration_duration);
// This implements step 3 of
// https://drafts.csswg.org/web-animations/#calculating-the-simple-iteration-progress
if (iteration_time == 0 && phase == AnimationEffect::kPhaseAfter &&
- repeated_duration != 0 && scaled_active_time != 0)
+ repeated_duration != 0 && offset_active_time != 0)
return iteration_duration;
return iteration_time;
@@ -181,25 +173,25 @@ static inline double CalculateIterationTime(double iteration_duration,
static inline double CalculateCurrentIteration(double iteration_duration,
double iteration_time,
- double scaled_active_time,
+ double offset_active_time,
const Timing& specified) {
DCHECK_GT(iteration_duration, 0);
DCHECK(IsNull(iteration_time) || iteration_time >= 0);
- if (IsNull(scaled_active_time))
+ if (IsNull(offset_active_time))
return NullValue();
DCHECK_GE(iteration_time, 0);
DCHECK_LE(iteration_time, iteration_duration);
- DCHECK_GE(scaled_active_time, 0);
+ DCHECK_GE(offset_active_time, 0);
- if (!scaled_active_time)
+ if (!offset_active_time)
return 0;
if (iteration_time == iteration_duration)
return specified.iteration_start + specified.iteration_count - 1;
- return floor(scaled_active_time / iteration_duration);
+ return floor(offset_active_time / iteration_duration);
}
static inline double CalculateDirectedTime(double current_iteration,
diff --git a/chromium/third_party/blink/renderer/core/animation/timing_calculations_test.cc b/chromium/third_party/blink/renderer/core/animation/timing_calculations_test.cc
index 2ee1ba6bd0e..8e6ea85070f 100644
--- a/chromium/third_party/blink/renderer/core/animation/timing_calculations_test.cc
+++ b/chromium/third_party/blink/renderer/core/animation/timing_calculations_test.cc
@@ -98,39 +98,18 @@ TEST(AnimationTimingCalculationsTest, ActiveTime) {
AnimationEffect::kPhaseNone, timing)));
}
-TEST(AnimationTimingCalculationsTest, ScaledActiveTime) {
- Timing timing;
-
- // calculateScaledActiveTime(activeDuration, activeTime, startOffset, timing)
-
+TEST(AnimationTimingCalculationsTest, OffsetActiveTime) {
// if the active time is null
- EXPECT_TRUE(IsNull(CalculateScaledActiveTime(4, NullValue(), 5, timing)));
+ EXPECT_TRUE(IsNull(CalculateOffsetActiveTime(4, NullValue(), 5)));
- // if the playback rate is negative
- timing.playback_rate = -1;
- EXPECT_EQ(35, CalculateScaledActiveTime(40, 10, 5, timing));
-
- // otherwise
- timing.playback_rate = 0;
- EXPECT_EQ(5, CalculateScaledActiveTime(40, 10, 5, timing));
- timing.playback_rate = 1;
- EXPECT_EQ(15, CalculateScaledActiveTime(40, 10, 5, timing));
+ // normal case
+ EXPECT_EQ(15, CalculateOffsetActiveTime(40, 10, 5));
// infinte activeTime
- timing.playback_rate = 0;
- EXPECT_EQ(0, CalculateScaledActiveTime(
- std::numeric_limits<double>::infinity(),
- std::numeric_limits<double>::infinity(), 0, timing));
- timing.playback_rate = 1;
- EXPECT_EQ(std::numeric_limits<double>::infinity(),
- CalculateScaledActiveTime(std::numeric_limits<double>::infinity(),
- std::numeric_limits<double>::infinity(),
- 0, timing));
- timing.playback_rate = -1;
- EXPECT_EQ(std::numeric_limits<double>::infinity(),
- CalculateScaledActiveTime(std::numeric_limits<double>::infinity(),
- std::numeric_limits<double>::infinity(),
- 0, timing));
+ EXPECT_EQ(
+ std::numeric_limits<double>::infinity(),
+ CalculateOffsetActiveTime(std::numeric_limits<double>::infinity(),
+ std::numeric_limits<double>::infinity(), 0));
}
TEST(AnimationTimingCalculationsTest, IterationTime) {
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 d70c3df8f8c..1163021ea01 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
@@ -451,7 +451,6 @@ TEST_F(AnimationTimingInputTest, TimingInputEmpty) {
EXPECT_EQ(control_timing.iteration_start, updated_timing.iteration_start);
EXPECT_EQ(control_timing.iteration_count, updated_timing.iteration_count);
EXPECT_TRUE(std::isnan(updated_timing.iteration_duration));
- EXPECT_EQ(control_timing.playback_rate, updated_timing.playback_rate);
EXPECT_EQ(control_timing.direction, updated_timing.direction);
EXPECT_EQ(*control_timing.timing_function, *updated_timing.timing_function);
}
@@ -471,7 +470,6 @@ TEST_F(AnimationTimingInputTest, TimingInputEmptyKeyframeAnimationOptions) {
EXPECT_EQ(control_timing.iteration_start, updated_timing.iteration_start);
EXPECT_EQ(control_timing.iteration_count, updated_timing.iteration_count);
EXPECT_TRUE(std::isnan(updated_timing.iteration_duration));
- EXPECT_EQ(control_timing.playback_rate, updated_timing.playback_rate);
EXPECT_EQ(control_timing.direction, updated_timing.direction);
EXPECT_EQ(*control_timing.timing_function, *updated_timing.timing_function);
}
diff --git a/chromium/third_party/blink/renderer/core/animation/transition_interpolation.cc b/chromium/third_party/blink/renderer/core/animation/transition_interpolation.cc
index 01871569ba4..b2818c722fe 100644
--- a/chromium/third_party/blink/renderer/core/animation/transition_interpolation.cc
+++ b/chromium/third_party/blink/renderer/core/animation/transition_interpolation.cc
@@ -59,10 +59,10 @@ TransitionInterpolation::GetInterpolatedValue() const {
type_, CurrentInterpolableValue().Clone(), CurrentNonInterpolableValue());
}
-scoped_refptr<AnimatableValue>
-TransitionInterpolation::GetInterpolatedCompositorValue() const {
- return AnimatableValue::Interpolate(compositor_start_.get(),
- compositor_end_.get(), cached_fraction_);
+AnimatableValue* TransitionInterpolation::GetInterpolatedCompositorValue()
+ const {
+ return AnimatableValue::Interpolate(compositor_start_, compositor_end_,
+ cached_fraction_);
}
} // namespace blink
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 4bca63a9ddb..2eba87a952f 100644
--- a/chromium/third_party/blink/renderer/core/animation/transition_interpolation.h
+++ b/chromium/third_party/blink/renderer/core/animation/transition_interpolation.h
@@ -39,16 +39,15 @@ class InterpolationType;
// function.
class CORE_EXPORT TransitionInterpolation : public Interpolation {
public:
- static scoped_refptr<TransitionInterpolation> Create(
- const PropertyHandle& property,
- const InterpolationType& type,
- InterpolationValue&& start,
- InterpolationValue&& end,
- const scoped_refptr<AnimatableValue> compositor_start,
- const scoped_refptr<AnimatableValue> compositor_end) {
- return base::AdoptRef(new TransitionInterpolation(
- property, type, std::move(start), std::move(end),
- std::move(compositor_start), std::move(compositor_end)));
+ static TransitionInterpolation* Create(const PropertyHandle& property,
+ const InterpolationType& type,
+ InterpolationValue&& start,
+ InterpolationValue&& end,
+ AnimatableValue* compositor_start,
+ AnimatableValue* compositor_end) {
+ return new TransitionInterpolation(property, type, std::move(start),
+ std::move(end), compositor_start,
+ compositor_end);
}
void Apply(StyleResolverState&) const;
@@ -59,26 +58,39 @@ class CORE_EXPORT TransitionInterpolation : public Interpolation {
std::unique_ptr<TypedInterpolationValue> GetInterpolatedValue() const;
- scoped_refptr<AnimatableValue> GetInterpolatedCompositorValue() const;
+ AnimatableValue* GetInterpolatedCompositorValue() const;
void Interpolate(int iteration, double fraction) final;
+ void Trace(Visitor* visitor) override {
+ visitor->Trace(compositor_start_);
+ visitor->Trace(compositor_end_);
+ Interpolation::Trace(visitor);
+ }
+
protected:
TransitionInterpolation(const PropertyHandle& property,
const InterpolationType& type,
InterpolationValue&& start,
InterpolationValue&& end,
- const scoped_refptr<AnimatableValue> compositor_start,
- const scoped_refptr<AnimatableValue> compositor_end)
+ AnimatableValue* compositor_start,
+ AnimatableValue* compositor_end)
: property_(property),
type_(type),
start_(std::move(start)),
end_(std::move(end)),
merge_(type.MaybeMergeSingles(start_.Clone(), end_.Clone())),
- compositor_start_(std::move(compositor_start)),
- compositor_end_(std::move(compositor_end)),
- cached_interpolable_value_(merge_.start_interpolable_value->Clone()) {
- DCHECK(merge_);
+ compositor_start_(compositor_start),
+ compositor_end_(compositor_end) {
+ // Incredibly speculative CHECKs, to try and get any insight on
+ // crbug.com/826627. Somehow a crash is happening in this constructor, which
+ // we believe is based on |start_| having no interpolable value. However a
+ // CHECK added in TransitionKeyframe::SetValue isn't firing, so doing some
+ // speculation here to try and broaden our understanding.
+ // TODO(crbug.com/826627): Revert once bug is fixed.
+ CHECK(start_);
+ CHECK(merge_);
+ cached_interpolable_value_ = merge_.start_interpolable_value->Clone();
DCHECK_EQ(compositor_start_ && compositor_end_,
property_.GetCSSProperty().IsCompositableProperty());
}
@@ -92,8 +104,8 @@ class CORE_EXPORT TransitionInterpolation : public Interpolation {
const InterpolationValue start_;
const InterpolationValue end_;
const PairwiseInterpolationValue merge_;
- const scoped_refptr<AnimatableValue> compositor_start_;
- const scoped_refptr<AnimatableValue> compositor_end_;
+ const Member<AnimatableValue> compositor_start_;
+ const Member<AnimatableValue> compositor_end_;
mutable double cached_fraction_ = 0;
mutable int cached_iteration_ = 0;
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 7185d62b646..b88829a520c 100644
--- a/chromium/third_party/blink/renderer/core/animation/transition_keyframe.cc
+++ b/chromium/third_party/blink/renderer/core/animation/transition_keyframe.cc
@@ -12,11 +12,10 @@
namespace blink {
-void TransitionKeyframe::SetCompositorValue(
- scoped_refptr<AnimatableValue> compositor_value) {
+void TransitionKeyframe::SetCompositorValue(AnimatableValue* compositor_value) {
DCHECK_EQ(property_.GetCSSProperty().IsCompositableProperty(),
- static_cast<bool>(compositor_value.get()));
- compositor_value_ = std::move(compositor_value);
+ static_cast<bool>(compositor_value));
+ compositor_value_ = compositor_value;
}
PropertyHandleSet TransitionKeyframe::Properties() const {
@@ -31,7 +30,12 @@ void TransitionKeyframe::AddKeyframePropertiesToV8Object(
// TODO(crbug.com/777971): Add in the property/value for TransitionKeyframe.
}
-scoped_refptr<Keyframe::PropertySpecificKeyframe>
+void TransitionKeyframe::Trace(Visitor* visitor) {
+ visitor->Trace(compositor_value_);
+ Keyframe::Trace(visitor);
+}
+
+Keyframe::PropertySpecificKeyframe*
TransitionKeyframe::CreatePropertySpecificKeyframe(
const PropertyHandle& property,
EffectModel::CompositeOperation effect_composite,
@@ -44,7 +48,7 @@ TransitionKeyframe::CreatePropertySpecificKeyframe(
value_->Clone(), compositor_value_);
}
-scoped_refptr<Interpolation>
+Interpolation*
TransitionKeyframe::PropertySpecificKeyframe::CreateInterpolation(
const PropertyHandle& property,
const Keyframe::PropertySpecificKeyframe& other_super_class) const {
@@ -57,4 +61,9 @@ TransitionKeyframe::PropertySpecificKeyframe::CreateInterpolation(
other.compositor_value_);
}
+void TransitionKeyframe::PropertySpecificKeyframe::Trace(Visitor* visitor) {
+ visitor->Trace(compositor_value_);
+ Keyframe::PropertySpecificKeyframe::Trace(visitor);
+}
+
} // namespace blink
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 2df1f4a767b..768bdf86899 100644
--- a/chromium/third_party/blink/renderer/core/animation/transition_keyframe.h
+++ b/chromium/third_party/blink/renderer/core/animation/transition_keyframe.h
@@ -20,10 +20,9 @@ namespace blink {
// attributes) or an AtomicString (for custom CSS properties).
class CORE_EXPORT TransitionKeyframe : public Keyframe {
public:
- static scoped_refptr<TransitionKeyframe> Create(
- const PropertyHandle& property) {
+ static TransitionKeyframe* Create(const PropertyHandle& property) {
DCHECK(!property.IsSVGAttribute());
- return base::AdoptRef(new TransitionKeyframe(property));
+ return new TransitionKeyframe(property);
}
void SetValue(std::unique_ptr<TypedInterpolationValue> value) {
// Speculative CHECK to help investigate crbug.com/826627. The theory is
@@ -34,61 +33,64 @@ class CORE_EXPORT TransitionKeyframe : public Keyframe {
CHECK(!!value->Value());
value_ = std::move(value);
}
- void SetCompositorValue(scoped_refptr<AnimatableValue>);
+ void SetCompositorValue(AnimatableValue*);
PropertyHandleSet Properties() const final;
void AddKeyframePropertiesToV8Object(V8ObjectBuilder&) const override;
+ void Trace(Visitor*) override;
+
class PropertySpecificKeyframe : public Keyframe::PropertySpecificKeyframe {
public:
- static scoped_refptr<PropertySpecificKeyframe> Create(
+ static PropertySpecificKeyframe* Create(
double offset,
scoped_refptr<TimingFunction> easing,
EffectModel::CompositeOperation composite,
std::unique_ptr<TypedInterpolationValue> value,
- scoped_refptr<AnimatableValue> compositor_value) {
- return base::AdoptRef(new PropertySpecificKeyframe(
- offset, std::move(easing), composite, std::move(value),
- std::move(compositor_value)));
+ AnimatableValue* compositor_value) {
+ return new PropertySpecificKeyframe(offset, std::move(easing), composite,
+ std::move(value), compositor_value);
}
const AnimatableValue* GetAnimatableValue() const final {
- return compositor_value_.get();
+ return compositor_value_;
}
bool IsNeutral() const final { return false; }
- scoped_refptr<Keyframe::PropertySpecificKeyframe> NeutralKeyframe(
+ Keyframe::PropertySpecificKeyframe* NeutralKeyframe(
double offset,
scoped_refptr<TimingFunction> easing) const final {
NOTREACHED();
return nullptr;
}
- scoped_refptr<Interpolation> CreateInterpolation(
+ Interpolation* CreateInterpolation(
const PropertyHandle&,
const Keyframe::PropertySpecificKeyframe& other) const final;
bool IsTransitionPropertySpecificKeyframe() const final { return true; }
+ void Trace(Visitor*) override;
+
private:
PropertySpecificKeyframe(double offset,
scoped_refptr<TimingFunction> easing,
EffectModel::CompositeOperation composite,
std::unique_ptr<TypedInterpolationValue> value,
- scoped_refptr<AnimatableValue> compositor_value)
+ AnimatableValue* compositor_value)
: Keyframe::PropertySpecificKeyframe(offset,
std::move(easing),
composite),
value_(std::move(value)),
- compositor_value_(std::move(compositor_value)) {}
+ compositor_value_(compositor_value) {}
- scoped_refptr<Keyframe::PropertySpecificKeyframe> CloneWithOffset(
+ Keyframe::PropertySpecificKeyframe* CloneWithOffset(
double offset) const final {
return Create(offset, easing_, composite_, value_->Clone(),
compositor_value_);
}
std::unique_ptr<TypedInterpolationValue> value_;
- scoped_refptr<AnimatableValue> compositor_value_;
+ Member<AnimatableValue> compositor_value_;
};
private:
@@ -102,19 +104,16 @@ class CORE_EXPORT TransitionKeyframe : public Keyframe {
bool IsTransitionKeyframe() const final { return true; }
- scoped_refptr<Keyframe> Clone() const final {
- return base::AdoptRef(new TransitionKeyframe(*this));
- }
+ Keyframe* Clone() const final { return new TransitionKeyframe(*this); }
- scoped_refptr<Keyframe::PropertySpecificKeyframe>
- CreatePropertySpecificKeyframe(
+ Keyframe::PropertySpecificKeyframe* CreatePropertySpecificKeyframe(
const PropertyHandle&,
EffectModel::CompositeOperation effect_composite,
double offset) const final;
PropertyHandle property_;
std::unique_ptr<TypedInterpolationValue> value_;
- scoped_refptr<AnimatableValue> compositor_value_;
+ Member<AnimatableValue> compositor_value_;
};
using TransitionPropertySpecificKeyframe =
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 279ec28f042..6c4a97c9f3e 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
@@ -9,6 +9,7 @@
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/web/web_local_frame_client.h"
+#include "third_party/blink/renderer/core/accessibility/ax_context.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/dom/frame_request_callback_collection.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -53,7 +54,8 @@ ComputedAccessibleNodePromiseResolver::ComputedAccessibleNodePromiseResolver(
Element& element)
: element_(element),
resolver_(ScriptPromiseResolver::Create(script_state)),
- resolve_with_node_(false) {}
+ resolve_with_node_(false),
+ ax_context_(std::make_unique<AXContext>(element_->GetDocument())) {}
ScriptPromise ComputedAccessibleNodePromiseResolver::Promise() {
return resolver_->Promise();
@@ -94,9 +96,8 @@ void ComputedAccessibleNodePromiseResolver::UpdateTreeAndResolve() {
Document& document = element_->GetDocument();
document.View()->UpdateLifecycleToCompositingCleanPlusScrolling();
- AXObjectCache* cache = element_->GetDocument().GetOrCreateAXObjectCache();
- DCHECK(cache);
- AXID ax_id = cache->GetAXID(element_);
+ AXObjectCache& cache = ax_context_->GetAXObjectCache();
+ AXID ax_id = cache.GetAXID(element_);
ComputedAccessibleNode* accessible_node =
local_frame->GetOrCreateComputedAccessibleNode(ax_id, tree);
@@ -114,7 +115,10 @@ ComputedAccessibleNode* ComputedAccessibleNode::Create(AXID ax_id,
ComputedAccessibleNode::ComputedAccessibleNode(AXID ax_id,
WebComputedAXTree* tree,
LocalFrame* frame)
- : ax_id_(ax_id), tree_(tree), frame_(frame) {}
+ : ax_id_(ax_id),
+ tree_(tree),
+ frame_(frame),
+ ax_context_(std::make_unique<AXContext>(*frame->GetDocument())) {}
ComputedAccessibleNode::~ComputedAccessibleNode() {}
@@ -124,7 +128,8 @@ bool ComputedAccessibleNode::atomic(bool& is_null) const {
ScriptPromise ComputedAccessibleNode::ensureUpToDate(
ScriptState* script_state) {
- AXObjectCache* cache = frame_->GetDocument()->GetOrCreateAXObjectCache();
+ AXObjectCache* cache = frame_->GetDocument()->ExistingAXObjectCache();
+ DCHECK(cache);
Element* element = cache->GetElementFromAXID(ax_id_);
ComputedAccessibleNodePromiseResolver* resolver =
ComputedAccessibleNodePromiseResolver::Create(script_state, *element);
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 616fb5caea3..d56b6725fae 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
@@ -8,6 +8,7 @@
#include "third_party/blink/public/platform/web_computed_ax_tree.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/accessibility/ax_context.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/dom/events/event_target.h"
@@ -39,6 +40,7 @@ class ComputedAccessibleNodePromiseResolver final
Member<Element> element_;
Member<ScriptPromiseResolver> resolver_;
bool resolve_with_node_;
+ std::unique_ptr<AXContext> ax_context_;
};
class ComputedAccessibleNode : public ScriptWrappable {
@@ -105,6 +107,7 @@ class ComputedAccessibleNode : public ScriptWrappable {
// This tree is owned by the RenderFrame.
blink::WebComputedAXTree* tree_;
Member<LocalFrame> frame_;
+ std::unique_ptr<AXContext> ax_context_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/clipboard/BUILD.gn b/chromium/third_party/blink/renderer/core/clipboard/BUILD.gn
index 65c6f844073..e5e8a6acbe5 100644
--- a/chromium/third_party/blink/renderer/core/clipboard/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/clipboard/BUILD.gn
@@ -23,6 +23,7 @@ blink_core_sources("clipboard") {
"data_transfer_item_list.h",
"dragged_isolated_file_system.cc",
"dragged_isolated_file_system.h",
+ "paste_mode.h",
"system_clipboard.cc",
"system_clipboard.h",
]
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 b81a304f550..c21316cbcbd 100644
--- a/chromium/third_party/blink/renderer/core/clipboard/data_object.cc
+++ b/chromium/third_party/blink/renderer/core/clipboard/data_object.cc
@@ -35,8 +35,9 @@
#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/dragged_isolated_file_system.h"
+#include "third_party/blink/renderer/core/clipboard/paste_mode.h"
#include "third_party/blink/renderer/core/clipboard/system_clipboard.h"
-#include "third_party/blink/renderer/platform/paste_mode.h"
+#include "third_party/blink/renderer/platform/file_metadata.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
namespace blink {
@@ -72,17 +73,17 @@ DataObject* DataObject::Create() {
DataObject::~DataObject() = default;
-size_t DataObject::length() const {
+uint32_t DataObject::length() const {
return item_list_.size();
}
-DataObjectItem* DataObject::Item(unsigned long index) {
+DataObjectItem* DataObject::Item(uint32_t index) {
if (index >= length())
return nullptr;
return item_list_[index];
}
-void DataObject::DeleteItem(unsigned long index) {
+void DataObject::DeleteItem(uint32_t index) {
if (index >= length())
return;
item_list_.EraseAt(index);
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 eb346a53f5c..63549f6671a 100644
--- a/chromium/third_party/blink/renderer/core/clipboard/data_object.h
+++ b/chromium/third_party/blink/renderer/core/clipboard/data_object.h
@@ -71,11 +71,11 @@ class CORE_EXPORT DataObject : public GarbageCollectedFinalized<DataObject>,
virtual ~DataObject();
// DataTransferItemList support.
- size_t length() const;
- DataObjectItem* Item(unsigned long index);
+ uint32_t length() const;
+ DataObjectItem* Item(uint32_t index);
// FIXME: Implement V8DataTransferItemList::indexedPropertyDeleter to get this
// called.
- void DeleteItem(unsigned long index);
+ void DeleteItem(uint32_t index);
void ClearAll();
// Returns null if an item already exists with the provided type.
DataObjectItem* Add(const String& data, const String& type);
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 a28fa6516c6..64f75a72633 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
@@ -6,6 +6,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/core/clipboard/data_object_item.h"
+#include "third_party/blink/renderer/platform/file_metadata.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
namespace blink {
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 43f6f8bdc1c..f4f23abbf03 100644
--- a/chromium/third_party/blink/renderer/core/clipboard/data_transfer.cc
+++ b/chromium/third_party/blink/renderer/core/clipboard/data_transfer.cc
@@ -126,7 +126,6 @@ class DraggedNodeImageBuilder {
kGlobalPaintFlattenCompositingLayers,
LayoutSize());
PaintLayerFlags flags = kPaintLayerHaveTransparency |
- kPaintLayerAppliedTransform |
kPaintLayerUncachedClipRects;
PaintRecordBuilder builder;
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 1dac9f36f16..6984e0c6f36 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
@@ -38,13 +38,13 @@ DataTransferItemList* DataTransferItemList::Create(DataTransfer* data_transfer,
return new DataTransferItemList(data_transfer, list);
}
-size_t DataTransferItemList::length() const {
+uint32_t DataTransferItemList::length() const {
if (!data_transfer_->CanReadTypes())
return 0;
return data_object_->length();
}
-DataTransferItem* DataTransferItemList::item(unsigned long index) {
+DataTransferItem* DataTransferItemList::item(uint32_t index) {
if (!data_transfer_->CanReadTypes())
return nullptr;
DataObjectItem* item = data_object_->Item(index);
@@ -54,7 +54,7 @@ DataTransferItem* DataTransferItemList::item(unsigned long index) {
return DataTransferItem::Create(data_transfer_, item);
}
-void DataTransferItemList::deleteItem(unsigned long index,
+void DataTransferItemList::deleteItem(uint32_t index,
ExceptionState& exception_state) {
if (!data_transfer_->CanWriteData()) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
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 72805c51980..971b9c1fe68 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
@@ -51,9 +51,9 @@ class CORE_EXPORT DataTransferItemList final : public ScriptWrappable {
public:
static DataTransferItemList* Create(DataTransfer*, DataObject*);
- size_t length() const;
- DataTransferItem* item(unsigned long index);
- void deleteItem(unsigned long index, ExceptionState&);
+ uint32_t length() const;
+ DataTransferItem* item(uint32_t index);
+ void deleteItem(uint32_t index, ExceptionState&);
void clear();
DataTransferItem* add(const String& data,
const String& type,
diff --git a/chromium/third_party/blink/renderer/platform/paste_mode.h b/chromium/third_party/blink/renderer/core/clipboard/paste_mode.h
index f20b28d7adf..9965ed23328 100644
--- a/chromium/third_party/blink/renderer/platform/paste_mode.h
+++ b/chromium/third_party/blink/renderer/core/clipboard/paste_mode.h
@@ -28,8 +28,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_PASTE_MODE_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PASTE_MODE_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CLIPBOARD_PASTE_MODE_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_CLIPBOARD_PASTE_MODE_H_
namespace blink {
@@ -40,4 +40,4 @@ enum class PasteMode {
} // namespace blink
-#endif
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_CLIPBOARD_PASTE_MODE_H_
diff --git a/chromium/third_party/blink/renderer/core/core.gni b/chromium/third_party/blink/renderer/core/core.gni
index 3b55bc812a4..1d9bdd1d72f 100644
--- a/chromium/third_party/blink/renderer/core/core.gni
+++ b/chromium/third_party/blink/renderer/core/core.gni
@@ -125,3 +125,9 @@ set_defaults("blink_core_sources") {
# support, for lower Windows build times.
configs += [ "//third_party/blink/renderer/core:blink_core_pch" ]
}
+
+declare_args() {
+ # Use base::TimeDelta to represent time in renderer/core/animations. See
+ # http://crbug.com/737867
+ blink_animation_use_time_delta = false
+}
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 34474a9663b..5e1abc7a177 100644
--- a/chromium/third_party/blink/renderer/core/core_idl_files.gni
+++ b/chromium/third_party/blink/renderer/core/core_idl_files.gni
@@ -134,8 +134,11 @@ core_idl_files =
"dom/events/event.idl",
"dom/events/event_target.idl",
"trustedtypes/trusted_html.idl",
+ "trustedtypes/trusted_script.idl",
"trustedtypes/trusted_script_url.idl",
"trustedtypes/trusted_url.idl",
+ "trustedtypes/trusted_type_policy.idl",
+ "trustedtypes/trusted_type_policy_factory.idl",
"editing/selection.idl",
"events/animation_event.idl",
"events/animation_playback_event.idl",
@@ -177,12 +180,14 @@ core_idl_files =
"frame/bar_prop.idl",
"frame/deprecation_report_body.idl",
"frame/external.idl",
+ "frame/feature_policy_violation_report_body.idl",
"frame/history.idl",
"frame/intervention_report_body.idl",
"frame/location.idl",
"frame/report.idl",
"frame/report_body.idl",
"frame/reporting_observer.idl",
+ "frame/test_report_body.idl",
"frame/user_activation.idl",
"frame/visual_viewport.idl",
"geometry/dom_matrix.idl",
@@ -275,6 +280,7 @@ core_idl_files =
"html/forms/validity_state.idl",
"html/media/html_audio_element.idl",
"html/media/media_error.idl",
+ "html/portal/html_portal_element.idl",
"html/track/audio_track_list.idl",
"html/track/html_track_element.idl",
"html/track/text_track.idl",
@@ -292,6 +298,7 @@ core_idl_files =
"inspector/inspector_overlay_host.idl",
"intersection_observer/intersection_observer.idl",
"intersection_observer/intersection_observer_entry.idl",
+ "invisible_dom/activate_invisible_event.idl",
"layout/custom/layout_constraints.idl",
"layout/custom/layout_fragment.idl",
"layout/custom/layout_fragment_request.idl",
@@ -629,6 +636,7 @@ core_dictionary_idl_files =
"geometry/dom_rect_init.idl",
"html/focus_options.idl",
"html/assigned_nodes_options.idl",
+ "html/canvas/baselines.idl",
"html/canvas/image_data_color_settings.idl",
"html/canvas/image_encode_options.idl",
"html/track/track_event_init.idl",
@@ -638,6 +646,7 @@ core_dictionary_idl_files =
"intersection_observer/intersection_observer_init.idl",
"layout/custom/custom_layout_constraints_options.idl",
"layout/custom/fragment_result_options.idl",
+ "messaging/post_message_options.idl",
"mojo/mojo_create_data_pipe_options.idl",
"mojo/mojo_create_data_pipe_result.idl",
"mojo/mojo_create_message_pipe_result.idl",
@@ -657,6 +666,7 @@ core_dictionary_idl_files =
"timing/performance_mark_options.idl",
"timing/performance_measure_options.idl",
"timing/performance_observer_init.idl",
+ "trustedtypes/trusted_type_policy_options.idl",
"workers/worker_options.idl",
"workers/worklet_options.idl",
],
diff --git a/chromium/third_party/blink/renderer/core/core_initializer.cc b/chromium/third_party/blink/renderer/core/core_initializer.cc
index 2737c9b2b68..f2d0f9d597c 100644
--- a/chromium/third_party/blink/renderer/core/core_initializer.cc
+++ b/chromium/third_party/blink/renderer/core/core_initializer.cc
@@ -49,6 +49,7 @@
#include "third_party/blink/renderer/core/input_type_names.h"
#include "third_party/blink/renderer/core/mathml_names.h"
#include "third_party/blink/renderer/core/media_type_names.h"
+#include "third_party/blink/renderer/core/performance_entry_names.h"
#include "third_party/blink/renderer/core/svg_names.h"
#include "third_party/blink/renderer/core/workers/worker_thread.h"
#include "third_party/blink/renderer/core/xlink_names.h"
@@ -104,7 +105,8 @@ void CoreInitializer::Initialize() {
InputModeNames::InputModeNamesCount +
InputTypeNames::InputTypeNamesCount +
MediaFeatureNames::MediaFeatureNamesCount +
- MediaTypeNames::MediaTypeNamesCount;
+ MediaTypeNames::MediaTypeNamesCount +
+ PerformanceEntryNames::PerformanceEntryNamesCount;
StringImpl::ReserveStaticStringsCapacityForSize(
kCoreStaticStringsCount + StringImpl::AllStaticStrings().size());
@@ -130,6 +132,7 @@ void CoreInitializer::Initialize() {
InputTypeNames::init();
MediaFeatureNames::init();
MediaTypeNames::init();
+ PerformanceEntryNames::init();
MediaQueryEvaluator::Init();
CSSParserTokenRange::InitStaticEOFToken();
diff --git a/chromium/third_party/blink/renderer/core/css/CSSProperties.json5 b/chromium/third_party/blink/renderer/core/css/CSSProperties.json5
index c4478b93cf9..3af6d89fe41 100644
--- a/chromium/third_party/blink/renderer/core/css/CSSProperties.json5
+++ b/chromium/third_party/blink/renderer/core/css/CSSProperties.json5
@@ -791,7 +791,7 @@
inherited: true,
font: true,
type_name: "TextRenderingMode",
- keywords: ["auto", "optimizeSpeed", "optimizeLegibility", "geometricPrecision"],
+ keywords: ["auto", "optimizespeed", "optimizelegibility", "geometricprecision"],
typedom_types: ["Keyword"],
priority: "High",
},
@@ -1393,6 +1393,7 @@
keywords: ["none", "left", "right", "both"],
typedom_types: ["Keyword"],
default_value: "none",
+ style_builder_custom_functions: ["value"],
},
{
name: "clip",
@@ -1452,7 +1453,7 @@
property_methods: ["CSSValueFromComputedStyleInternal"],
inherited: true,
svg: true,
- keywords: ["auto", "optimizeSpeed", "optimizeQuality"],
+ keywords: ["auto", "optimizespeed", "optimizequality"],
typedom_types: ["Keyword"],
},
{
@@ -1691,6 +1692,7 @@
default_value: "none",
name_for_methods: "Floating",
type_name: "EFloat",
+ style_builder_custom_functions: ["value"],
},
{
name: "flood-color",
@@ -1870,7 +1872,7 @@
field_group: "*",
field_template: "keyword",
keywords: [
- "auto", "optimizeSpeed", "optimizeQuality",
+ "auto", "optimizespeed", "optimizequality",
"-webkit-optimize-contrast", "pixelated"
],
typedom_types: ["Keyword"],
@@ -2420,7 +2422,6 @@
{
name: "overscroll-behavior-x",
property_methods: ["CSSValueFromComputedStyleInternal"],
- runtime_flag: "CSSOverscrollBehavior",
field_template: "keyword",
keywords: ["auto", "contain", "none"],
default_value: "auto",
@@ -2430,7 +2431,6 @@
{
name: "overscroll-behavior-y",
property_methods: ["CSSValueFromComputedStyleInternal"],
- runtime_flag: "CSSOverscrollBehavior",
field_template: "keyword",
keywords: ["auto", "contain", "none"],
default_value: "auto",
@@ -2633,7 +2633,7 @@
field_size: 4,
field_template: "primitive",
default_value: "ScrollCustomization::kScrollDirectionNone",
- include_paths: ["third_party/blink/renderer/platform/scroll/scroll_customization.h"],
+ include_paths: ["third_party/blink/renderer/core/scroll/scroll_customization.h"],
runtime_flag: "ScrollCustomization",
},
{
@@ -2881,7 +2881,7 @@
property_methods: ["CSSValueFromComputedStyleInternal"],
inherited: true,
svg: true,
- keywords: ["auto", "optimizeSpeed", "crispEdges", "geometricPrecision"],
+ keywords: ["auto", "optimizespeed", "crispedges", "geometricprecision"],
typedom_types: ["Keyword"],
},
{
@@ -3246,7 +3246,6 @@
{
name: "transform-box",
property_methods: ["CSSValueFromComputedStyleInternal"],
- runtime_flag: "CSSTransformBox",
field_template: "keyword",
keywords: ["fill-box", "view-box"],
default_value: "view-box",
@@ -4205,6 +4204,7 @@
{
name: "border-inline-start-color",
property_methods: ["ParseSingleValue"],
+ valid_for_visited_link: true,
direction_aware_options: {
logical_side: "start",
shorthand_for_physical_side: "borderColorShorthand",
@@ -4228,6 +4228,7 @@
{
name: "border-inline-end-color",
property_methods: ["ParseSingleValue"],
+ valid_for_visited_link: true,
direction_aware_options: {
logical_side: "end",
shorthand_for_physical_side: "borderColorShorthand",
@@ -4251,6 +4252,7 @@
{
name: "border-block-start-color",
property_methods: ["ParseSingleValue"],
+ valid_for_visited_link: true,
direction_aware_options: {
logical_side: "before",
shorthand_for_physical_side: "borderColorShorthand",
@@ -4274,6 +4276,7 @@
{
name: "border-block-end-color",
property_methods: ["ParseSingleValue"],
+ valid_for_visited_link: true,
direction_aware_options: {
logical_side: "after",
shorthand_for_physical_side: "borderColorShorthand",
@@ -4535,14 +4538,17 @@
},
{
name: "border-block",
- longhands: ["border-block-start", "border-block-end"],
- property_methods: ["ParseShorthand"],
+ longhands: [
+ "border-block-start-color", "border-block-start-style", "border-block-start-width",
+ "border-block-end-color", "border-block-end-style", "border-block-end-width"
+ ],
+ property_methods: ["ParseShorthand", "CSSValueFromComputedStyleInternal"],
runtime_flag: "CSSLogical",
},
{
name: "border-block-color",
longhands: ["border-block-start-color", "border-block-end-color"],
- property_methods: ["ParseShorthand"],
+ property_methods: ["ParseShorthand", "CSSValueFromComputedStyleInternal"],
runtime_flag: "CSSLogical",
},
{
@@ -4572,13 +4578,13 @@
{
name: "border-block-style",
longhands: ["border-block-start-style", "border-block-end-style"],
- property_methods: ["ParseShorthand"],
+ property_methods: ["ParseShorthand", "CSSValueFromComputedStyleInternal"],
runtime_flag: "CSSLogical",
},
{
name: "border-block-width",
longhands: ["border-block-start-width", "border-block-end-width"],
- property_methods: ["ParseShorthand"],
+ property_methods: ["ParseShorthand", "CSSValueFromComputedStyleInternal"],
runtime_flag: "CSSLogical",
},
{
@@ -4606,14 +4612,17 @@
},
{
name: "border-inline",
- longhands: ["border-inline-start", "border-inline-end"],
- property_methods: ["ParseShorthand"],
+ longhands: [
+ "border-inline-start-color", "border-inline-start-style", "border-inline-start-width",
+ "border-inline-end-color", "border-inline-end-style", "border-inline-end-width"
+ ],
+ property_methods: ["ParseShorthand", "CSSValueFromComputedStyleInternal"],
runtime_flag: "CSSLogical",
},
{
name: "border-inline-color",
longhands: ["border-inline-start-color", "border-inline-end-color"],
- property_methods: ["ParseShorthand"],
+ property_methods: ["ParseShorthand", "CSSValueFromComputedStyleInternal"],
runtime_flag: "CSSLogical",
},
{
@@ -4643,13 +4652,13 @@
{
name: "border-inline-style",
longhands: ["border-inline-start-style", "border-inline-end-style"],
- property_methods: ["ParseShorthand"],
+ property_methods: ["ParseShorthand", "CSSValueFromComputedStyleInternal"],
runtime_flag: "CSSLogical",
},
{
name: "border-inline-width",
longhands: ["border-inline-start-width", "border-inline-end-width"],
- property_methods: ["ParseShorthand"],
+ property_methods: ["ParseShorthand", "CSSValueFromComputedStyleInternal"],
runtime_flag: "CSSLogical",
},
{
@@ -4802,21 +4811,21 @@
layout_dependent: true,
},
{
+ name: "inset",
+ longhands: ["top", "right", "bottom", "left"],
+ property_methods: ["ParseShorthand", "CSSValueFromComputedStyleInternal"],
+ runtime_flag: "CSSLogical",
+ },
+ {
name: "inset-block",
longhands: ["inset-block-start", "inset-block-end"],
- property_methods: ["ParseShorthand"],
+ property_methods: ["ParseShorthand", "CSSValueFromComputedStyleInternal"],
runtime_flag: "CSSLogical",
},
{
name: "inset-inline",
longhands: ["inset-inline-start", "inset-inline-end"],
- property_methods: ["ParseShorthand"],
- runtime_flag: "CSSLogical",
- },
- {
- name: "inset",
- longhands: ["top", "right", "bottom", "left"],
- property_methods: ["ParseShorthand"],
+ property_methods: ["ParseShorthand", "CSSValueFromComputedStyleInternal"],
runtime_flag: "CSSLogical",
},
{
@@ -4833,13 +4842,13 @@
{
name: "margin-block",
longhands: ["margin-block-start", "margin-block-end"],
- property_methods: ["ParseShorthand"],
+ property_methods: ["ParseShorthand", "CSSValueFromComputedStyleInternal"],
runtime_flag: "CSSLogical",
},
{
name: "margin-inline",
longhands: ["margin-inline-start", "margin-inline-end"],
- property_methods: ["ParseShorthand"],
+ property_methods: ["ParseShorthand", "CSSValueFromComputedStyleInternal"],
runtime_flag: "CSSLogical",
},
{
@@ -4869,7 +4878,6 @@
name: "overscroll-behavior",
longhands: ["overscroll-behavior-x", "overscroll-behavior-y"],
property_methods: ["ParseShorthand", "CSSValueFromComputedStyleInternal"],
- runtime_flag: "CSSOverscrollBehavior",
},
{
name: "padding",
@@ -4882,13 +4890,13 @@
{
name: "padding-block",
longhands: ["padding-block-start", "padding-block-end"],
- property_methods: ["ParseShorthand"],
+ property_methods: ["ParseShorthand", "CSSValueFromComputedStyleInternal"],
runtime_flag: "CSSLogical",
},
{
name: "padding-inline",
longhands: ["padding-inline-start", "padding-inline-end"],
- property_methods: ["ParseShorthand"],
+ property_methods: ["ParseShorthand", "CSSValueFromComputedStyleInternal"],
runtime_flag: "CSSLogical",
},
{
diff --git a/chromium/third_party/blink/renderer/core/css/CSSValueKeywords.json5 b/chromium/third_party/blink/renderer/core/css/CSSValueKeywords.json5
index 45113bac35b..b944b4c8ef4 100644
--- a/chromium/third_party/blink/renderer/core/css/CSSValueKeywords.json5
+++ b/chromium/third_party/blink/renderer/core/css/CSSValueKeywords.json5
@@ -265,6 +265,8 @@
"-webkit-auto",
"left",
"right",
+ "inline-start",
+ "inline-end",
"center",
"justify",
"-webkit-left",
@@ -824,9 +826,15 @@
// text-rendering
//auto
- "optimizeSpeed",
- "optimizeLegibility",
- "geometricPrecision",
+ "optimizespeed",
+ "optimizelegibility",
+ "geometricprecision",
+
+ // shape-rendering
+ //auto
+ //optimizespeed
+ //geometricprecision
+ "crispedges",
// -webkit-color-adjust
"economy",
@@ -887,8 +895,8 @@
// image-rendering
//auto
- //optimizeSpeed
- "optimizeQuality",
+ //optimizespeed
+ "optimizequality",
"pixelated",
"-webkit-optimize-contrast",
diff --git a/chromium/third_party/blink/renderer/core/css/ComputedStyleDiffFunctions.json5 b/chromium/third_party/blink/renderer/core/css/ComputedStyleDiffFunctions.json5
index c4866b38718..4cae09bf50f 100644
--- a/chromium/third_party/blink/renderer/core/css/ComputedStyleDiffFunctions.json5
+++ b/chromium/third_party/blink/renderer/core/css/ComputedStyleDiffFunctions.json5
@@ -233,7 +233,6 @@
name: "DiffNeedsPaintInvalidationSubtree",
fields_to_diff: ["mix-blend-mode", "isolation", "Mask", "MaskBoxImage"],
},
-
{
name: "DiffNeedsPaintInvalidationObject",
fields_to_diff: ["-webkit-user-modify", "user-select", "image-rendering",
@@ -365,6 +364,10 @@
]
},
{
+ name: "UpdatePropertySpecificDifferencesMask",
+ fields_to_diff: ["Mask", "MaskBoxImage"],
+ },
+ {
name: "UpdatePropertySpecificDifferencesNeedsRecomputeOverflow",
predicates_to_test: [
{
diff --git a/chromium/third_party/blink/renderer/core/css/SVGCSSValueKeywords.json5 b/chromium/third_party/blink/renderer/core/css/SVGCSSValueKeywords.json5
index 719ae3e67c3..5f4007bce88 100644
--- a/chromium/third_party/blink/renderer/core/css/SVGCSSValueKeywords.json5
+++ b/chromium/third_party/blink/renderer/core/css/SVGCSSValueKeywords.json5
@@ -193,8 +193,8 @@
// CSS_PROP_COLOR_RENDERING
//auto
- //optimizeSpeed
- //optimizeQuality
+ //optimizespeed
+ //optimizequality
//// CSS_PROP_FILL
//currentColor
@@ -206,8 +206,8 @@
// CSS_PROP_IMAGE_RENDERING
//auto
- //optimizeSpeed
- //optimizeQuality
+ //optimizespeed
+ //optimizequality
// CSS_PROP_MARKER
// CSS_PROP_MARKER_END
@@ -215,9 +215,9 @@
// CSS_PROP_MARKER_START
// CSS_PROP_SHAPE_RENDERING
//auto
- //optimizeSpeed
- "crispEdges",
- //geometricPrecision
+ //optimizespeed
+ //crispedges
+ //geometricprecision
// CSS_PROP_STROKE
// CSS_PROP_STROKE_DASHARRAY
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 f640c1454e8..9b9a9917de4 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
@@ -60,8 +60,7 @@ TEST_F(CSSComputedStyleDeclarationTest, CleanShadowAncestorsNoRecalc) {
EXPECT_STREQ("rgb(0, 128, 0)",
computed->GetPropertyValue(CSSPropertyColor).Utf8().data());
- EXPECT_EQ(RuntimeEnabledFeatures::SlotInFlatTreeEnabled(),
- GetDocument().NeedsLayoutTreeUpdate());
+ EXPECT_TRUE(GetDocument().NeedsLayoutTreeUpdate());
}
} // namespace blink
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 162d2cdf0f7..32d5722cc46 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
@@ -12,7 +12,7 @@
namespace blink {
-class CSSCustomPropertyDeclaration : public CSSValue {
+class CORE_EXPORT CSSCustomPropertyDeclaration : public CSSValue {
public:
static CSSCustomPropertyDeclaration* Create(
const AtomicString& name,
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 c3c219f7126..44f7f400cb9 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
@@ -170,6 +170,7 @@ struct GradientStop {
struct CSSGradientValue::GradientDesc {
STACK_ALLOCATED();
+ public:
GradientDesc(const FloatPoint& p0,
const FloatPoint& p1,
GradientSpreadMethod spread_method)
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 e63b21773fb..a5d7fff7838 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
@@ -102,7 +102,7 @@ StyleImage* CSSImageSetValue::CachedImage(float device_scale_factor) const {
StyleImage* CSSImageSetValue::CacheImage(
const Document& document,
float device_scale_factor,
- FetchParameters::PlaceholderImageRequestType placeholder_image_request_type,
+ FetchParameters::ImageRequestOptimization image_request_optimization,
CrossOriginAttributeValue cross_origin) {
if (!images_in_set_.size())
FillImageSet();
@@ -127,8 +127,10 @@ StyleImage* CSSImageSetValue::CacheImage(
}
if (document.GetFrame() &&
- placeholder_image_request_type == FetchParameters::kAllowPlaceholder)
- document.GetFrame()->MaybeAllowImagePlaceholder(params);
+ image_request_optimization == FetchParameters::kAllowPlaceholder &&
+ document.GetFrame()->IsClientLoFiAllowed(params.GetResourceRequest())) {
+ params.SetClientLoFiPlaceholder();
+ }
cached_image_ = StyleFetchedImageSet::Create(
ImageResourceContent::Fetch(params, document.Fetcher()),
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 5f61f498f03..43477d0d48c 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
@@ -50,7 +50,7 @@ class CSSImageSetValue : public CSSValueList {
StyleImage* CacheImage(
const Document&,
float device_scale_factor,
- FetchParameters::PlaceholderImageRequestType,
+ FetchParameters::ImageRequestOptimization,
CrossOriginAttributeValue = kCrossOriginAttributeNotSet);
String CustomCSSText() const;
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 68d139837da..8cafaa9575a 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
@@ -54,7 +54,7 @@ CSSImageValue::~CSSImageValue() = default;
StyleImage* CSSImageValue::CacheImage(
const Document& document,
- FetchParameters::PlaceholderImageRequestType placeholder_image_request_type,
+ FetchParameters::ImageRequestOptimization image_request_optimization,
CrossOriginAttributeValue cross_origin) {
if (!cached_image_) {
if (absolute_url_.IsEmpty())
@@ -74,10 +74,13 @@ StyleImage* CSSImageValue::CacheImage(
}
if (document.GetFrame() &&
- placeholder_image_request_type == FetchParameters::kAllowPlaceholder)
- document.GetFrame()->MaybeAllowImagePlaceholder(params);
-
- cached_image_ = StyleFetchedImage::Create(document, params);
+ image_request_optimization == FetchParameters::kAllowPlaceholder &&
+ document.GetFrame()->IsClientLoFiAllowed(params.GetResourceRequest())) {
+ params.SetClientLoFiPlaceholder();
+ }
+ cached_image_ = StyleFetchedImage::Create(
+ document, params,
+ image_request_optimization == FetchParameters::kDeferImageLoad);
}
return cached_image_.Get();
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 aea13b6c357..6124f79d61f 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
@@ -69,7 +69,7 @@ class CORE_EXPORT CSSImageValue : public CSSValue {
}
StyleImage* CacheImage(
const Document&,
- FetchParameters::PlaceholderImageRequestType,
+ FetchParameters::ImageRequestOptimization,
CrossOriginAttributeValue = kCrossOriginAttributeNotSet);
const String& Url() const { return absolute_url_; }
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 cc46ccb8dee..24e7c515c51 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
@@ -37,6 +37,8 @@
#include "third_party/blink/renderer/core/css/css_reflection_direction.h"
#include "third_party/blink/renderer/core/css/css_to_length_conversion_data.h"
#include "third_party/blink/renderer/core/css_value_keywords.h"
+#include "third_party/blink/renderer/core/scroll/scroll_customization.h"
+#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
#include "third_party/blink/renderer/core/style/computed_style_constants.h"
#include "third_party/blink/renderer/core/style/svg_computed_style_defs.h"
#include "third_party/blink/renderer/platform/fonts/font_description.h"
@@ -45,8 +47,6 @@
#include "third_party/blink/renderer/platform/graphics/graphics_types.h"
#include "third_party/blink/renderer/platform/graphics/touch_action.h"
#include "third_party/blink/renderer/platform/length.h"
-#include "third_party/blink/renderer/platform/scroll/scroll_customization.h"
-#include "third_party/blink/renderer/platform/scroll/scrollable_area.h"
#include "third_party/blink/renderer/platform/text/text_run.h"
#include "third_party/blink/renderer/platform/text/writing_mode.h"
#include "third_party/blink/renderer/platform/theme_types.h"
@@ -888,13 +888,13 @@ inline CSSIdentifierValue::CSSIdentifierValue(TextRenderingMode e)
value_id_ = CSSValueAuto;
break;
case kOptimizeSpeed:
- value_id_ = CSSValueOptimizeSpeed;
+ value_id_ = CSSValueOptimizespeed;
break;
case kOptimizeLegibility:
- value_id_ = CSSValueOptimizeLegibility;
+ value_id_ = CSSValueOptimizelegibility;
break;
case kGeometricPrecision:
- value_id_ = CSSValueGeometricPrecision;
+ value_id_ = CSSValueGeometricprecision;
break;
}
}
@@ -904,11 +904,11 @@ inline TextRenderingMode CSSIdentifierValue::ConvertTo() const {
switch (value_id_) {
case CSSValueAuto:
return kAutoTextRendering;
- case CSSValueOptimizeSpeed:
+ case CSSValueOptimizespeed:
return kOptimizeSpeed;
- case CSSValueOptimizeLegibility:
+ case CSSValueOptimizelegibility:
return kOptimizeLegibility;
- case CSSValueGeometricPrecision:
+ case CSSValueGeometricprecision:
return kGeometricPrecision;
default:
break;
@@ -1192,10 +1192,10 @@ inline CSSIdentifierValue::CSSIdentifierValue(EColorRendering e)
value_id_ = CSSValueAuto;
break;
case CR_OPTIMIZESPEED:
- value_id_ = CSSValueOptimizeSpeed;
+ value_id_ = CSSValueOptimizespeed;
break;
case CR_OPTIMIZEQUALITY:
- value_id_ = CSSValueOptimizeQuality;
+ value_id_ = CSSValueOptimizequality;
break;
}
}
@@ -1203,9 +1203,9 @@ inline CSSIdentifierValue::CSSIdentifierValue(EColorRendering e)
template <>
inline EColorRendering CSSIdentifierValue::ConvertTo() const {
switch (value_id_) {
- case CSSValueOptimizeSpeed:
+ case CSSValueOptimizespeed:
return CR_OPTIMIZESPEED;
- case CSSValueOptimizeQuality:
+ case CSSValueOptimizequality:
return CR_OPTIMIZEQUALITY;
case CSSValueAuto:
return CR_AUTO;
@@ -1303,13 +1303,13 @@ inline CSSIdentifierValue::CSSIdentifierValue(EShapeRendering e)
value_id_ = CSSValueAuto;
break;
case SR_OPTIMIZESPEED:
- value_id_ = CSSValueOptimizeSpeed;
+ value_id_ = CSSValueOptimizespeed;
break;
case SR_CRISPEDGES:
- value_id_ = CSSValueCrispEdges;
+ value_id_ = CSSValueCrispedges;
break;
case SR_GEOMETRICPRECISION:
- value_id_ = CSSValueGeometricPrecision;
+ value_id_ = CSSValueGeometricprecision;
break;
}
}
@@ -1319,11 +1319,11 @@ inline EShapeRendering CSSIdentifierValue::ConvertTo() const {
switch (value_id_) {
case CSSValueAuto:
return SR_AUTO;
- case CSSValueOptimizeSpeed:
+ case CSSValueOptimizespeed:
return SR_OPTIMIZESPEED;
- case CSSValueCrispEdges:
+ case CSSValueCrispedges:
return SR_CRISPEDGES;
- case CSSValueGeometricPrecision:
+ case CSSValueGeometricprecision:
return SR_GEOMETRICPRECISION;
default:
break;
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 7af9a184053..a8c013f8074 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
@@ -92,11 +92,6 @@ const Document* CSSStyleSheet::SingleOwnerDocument(
}
CSSStyleSheet* CSSStyleSheet::Create(Document& document,
- ExceptionState& exception_state) {
- return CSSStyleSheet::Create(document, CSSStyleSheetInit(), exception_state);
-}
-
-CSSStyleSheet* CSSStyleSheet::Create(Document& document,
const CSSStyleSheetInit& options,
ExceptionState& exception_state) {
if (!RuntimeEnabledFeatures::ConstructableStylesheetsEnabled()) {
@@ -214,14 +209,6 @@ void CSSStyleSheet::DidMutateRules() {
ownerNode()->GetTreeScope());
if (StyleResolver* resolver = owner->GetStyleEngine().Resolver())
resolver->InvalidateMatchedPropertiesCache();
- } else if (!constructed_tree_scopes_.IsEmpty()) {
- for (auto tree_scope : constructed_tree_scopes_) {
- tree_scope->GetDocument().GetStyleEngine().SetNeedsActiveStyleUpdate(
- *tree_scope);
- if (StyleResolver* resolver =
- tree_scope->GetDocument().GetStyleEngine().Resolver())
- resolver->InvalidateMatchedPropertiesCache();
- }
}
}
@@ -576,7 +563,6 @@ void CSSStyleSheet::Trace(blink::Visitor* visitor) {
visitor->Trace(contents_);
visitor->Trace(owner_node_);
visitor->Trace(owner_rule_);
- visitor->Trace(constructed_tree_scopes_);
visitor->Trace(media_cssom_wrapper_);
visitor->Trace(child_rule_cssom_wrappers_);
visitor->Trace(rule_list_cssom_wrapper_);
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 2a3fd74c6f8..7dc0acea8a4 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
@@ -53,7 +53,6 @@ class CORE_EXPORT CSSStyleSheet final : public StyleSheet {
public:
static const Document* SingleOwnerDocument(const CSSStyleSheet*);
- static CSSStyleSheet* Create(Document&, ExceptionState&);
static CSSStyleSheet* Create(Document&,
const CSSStyleSheetInit&,
ExceptionState&);
@@ -127,14 +126,6 @@ class CORE_EXPORT CSSStyleSheet final : public StyleSheet {
void SetAllowRuleAccessFromOrigin(
scoped_refptr<const SecurityOrigin> allowed_origin);
- void AddedConstructedToTreeScope(TreeScope* tree_scope) {
- constructed_tree_scopes_.insert(tree_scope);
- }
-
- void RemovedConstructedFromTreeScope(TreeScope* tree_scope) {
- constructed_tree_scopes_.erase(tree_scope);
- }
-
class RuleMutationScope {
STACK_ALLOCATED();
@@ -204,6 +195,11 @@ class CORE_EXPORT CSSStyleSheet final : public StyleSheet {
FRIEND_TEST_ALL_PREFIXES(
CSSStyleSheetTest,
CSSStyleSheetConstructionWithNonEmptyCSSStyleSheetInit);
+ FRIEND_TEST_ALL_PREFIXES(CSSStyleSheetTest,
+ CreateEmptyCSSStyleSheetWithEmptyCSSStyleSheetInit);
+ FRIEND_TEST_ALL_PREFIXES(
+ CSSStyleSheetTest,
+ CreateEmptyCSSStyleSheetWithNonEmptyCSSStyleSheetInit);
FRIEND_TEST_ALL_PREFIXES(
CSSStyleSheetTest,
CreateCSSStyleSheetWithEmptyCSSStyleSheetInitAndText);
@@ -230,7 +226,6 @@ class CORE_EXPORT CSSStyleSheet final : public StyleSheet {
Member<Node> owner_node_;
Member<CSSRule> owner_rule_;
- HeapHashSet<Member<TreeScope>> constructed_tree_scopes_;
TextPosition start_position_;
Member<MediaList> media_cssom_wrapper_;
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 b70b9fe6a46..1251d19c8c3 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,9 +21,6 @@
// https://drafts.csswg.org/cssom/#the-cssstylesheet-interface
[
- ConstructorCallWith=Document,
- RaisesException=Constructor,
- Constructor(optional CSSStyleSheetInit options),
Exposed=Window
] interface CSSStyleSheet : StyleSheet {
readonly attribute CSSRule? ownerRule;
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 d4b1bf77a1a..234c6883238 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
@@ -49,13 +49,41 @@ class CSSStyleSheetTest : public PageTestBase {
TEST_F(CSSStyleSheetTest, ConstructorWithoutRuntimeFlagThrowsException) {
DummyExceptionStateForTesting exception_state;
RuntimeEnabledFeatures::SetConstructableStylesheetsEnabled(false);
- EXPECT_EQ(CSSStyleSheet::Create(GetDocument(), exception_state), nullptr);
+ EXPECT_EQ(CSSStyleSheet::Create(GetDocument(), CSSStyleSheetInit(),
+ exception_state),
+ nullptr);
ASSERT_TRUE(exception_state.HadException());
}
-TEST_F(CSSStyleSheetTest, CSSStyleSheetConstructionWithEmptyCSSStyleSheetInit) {
+TEST_F(CSSStyleSheetTest,
+ CSSStyleSheetConstructionWithNonEmptyCSSStyleSheetInit) {
+ DummyExceptionStateForTesting exception_state;
+ CSSStyleSheetInit init;
+ init.setMedia(MediaListOrString::FromString("screen, print"));
+ init.setTitle("test");
+ init.setAlternate(true);
+ init.setDisabled(true);
+ CSSStyleSheet* sheet =
+ CSSStyleSheet::Create(GetDocument(), init, exception_state);
+ ASSERT_FALSE(exception_state.HadException());
+ EXPECT_TRUE(sheet->href().IsNull());
+ EXPECT_EQ(sheet->parentStyleSheet(), nullptr);
+ 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->title(), init.title());
+ EXPECT_TRUE(sheet->AlternateFromConstructor());
+ EXPECT_TRUE(sheet->disabled());
+ EXPECT_EQ(sheet->cssRules(exception_state)->length(), 0U);
+ ASSERT_FALSE(exception_state.HadException());
+}
+
+TEST_F(CSSStyleSheetTest, CreateEmptyCSSStyleSheetWithEmptyCSSStyleSheetInit) {
+ V8TestingScope scope;
DummyExceptionStateForTesting exception_state;
- CSSStyleSheet* sheet = CSSStyleSheet::Create(GetDocument(), exception_state);
+ CSSStyleSheet* sheet = GetDocument().createEmptyCSSStyleSheet(
+ scope.GetScriptState(), CSSStyleSheetInit(), exception_state);
ASSERT_FALSE(exception_state.HadException());
EXPECT_TRUE(sheet->href().IsNull());
EXPECT_EQ(sheet->parentStyleSheet(), nullptr);
@@ -70,15 +98,16 @@ TEST_F(CSSStyleSheetTest, CSSStyleSheetConstructionWithEmptyCSSStyleSheetInit) {
}
TEST_F(CSSStyleSheetTest,
- CSSStyleSheetConstructionWithNonEmptyCSSStyleSheetInit) {
- DummyExceptionStateForTesting exception_state;
+ CreateEmptyCSSStyleSheetWithNonEmptyCSSStyleSheetInit) {
CSSStyleSheetInit init;
init.setMedia(MediaListOrString::FromString("screen, print"));
init.setTitle("test");
init.setAlternate(true);
init.setDisabled(true);
- CSSStyleSheet* sheet =
- CSSStyleSheet::Create(GetDocument(), init, exception_state);
+ V8TestingScope scope;
+ DummyExceptionStateForTesting exception_state;
+ CSSStyleSheet* sheet = GetDocument().createEmptyCSSStyleSheet(
+ scope.GetScriptState(), init, exception_state);
ASSERT_FALSE(exception_state.HadException());
EXPECT_TRUE(sheet->href().IsNull());
EXPECT_EQ(sheet->parentStyleSheet(), nullptr);
@@ -89,7 +118,6 @@ TEST_F(CSSStyleSheetTest,
EXPECT_EQ(sheet->title(), init.title());
EXPECT_TRUE(sheet->AlternateFromConstructor());
EXPECT_TRUE(sheet->disabled());
- EXPECT_EQ(sheet->cssRules(exception_state)->length(), 0U);
ASSERT_FALSE(exception_state.HadException());
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_syntax_descriptor.cc b/chromium/third_party/blink/renderer/core/css/css_syntax_descriptor.cc
index ddbbb08ac54..136020dc065 100644
--- a/chromium/third_party/blink/renderer/core/css/css_syntax_descriptor.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_syntax_descriptor.cc
@@ -8,6 +8,9 @@
#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/css_variable_reference_value.h"
+#include "third_party/blink/renderer/core/css/cssom/css_keyword_value.h"
+#include "third_party/blink/renderer/core/css/cssom/css_style_value.h"
+#include "third_party/blink/renderer/core/css/cssom/cssom_types.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_idioms.h"
#include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h"
#include "third_party/blink/renderer/core/css/parser/css_variable_parser.h"
@@ -223,6 +226,64 @@ const CSSValue* ConsumeSyntaxComponent(const CSSSyntaxComponent& syntax,
return result;
}
+bool CSSSyntaxComponent::CanTake(const CSSStyleValue& value) const {
+ switch (type_) {
+ case CSSSyntaxType::kTokenStream:
+ return value.GetType() == CSSStyleValue::kUnparsedType;
+ case CSSSyntaxType::kIdent:
+ return value.GetType() == CSSStyleValue::kKeywordType &&
+ static_cast<const CSSKeywordValue&>(value).value() == string_;
+ case CSSSyntaxType::kLength:
+ return CSSOMTypes::IsCSSStyleValueLength(value);
+ case CSSSyntaxType::kInteger:
+ // TODO(andruud): Support rounding.
+ // https://drafts.css-houdini.org/css-typed-om-1/#numeric-objects
+ FALLTHROUGH;
+ case CSSSyntaxType::kNumber:
+ return CSSOMTypes::IsCSSStyleValueNumber(value);
+ case CSSSyntaxType::kPercentage:
+ return CSSOMTypes::IsCSSStyleValuePercentage(value);
+ case CSSSyntaxType::kLengthPercentage:
+ // TODO(andruud): Support calc(X% + Ypx).
+ return CSSOMTypes::IsCSSStyleValueLength(value) ||
+ CSSOMTypes::IsCSSStyleValuePercentage(value);
+ case CSSSyntaxType::kColor:
+ // TODO(andruud): Support custom properties in CSSUnsupportedStyleValue.
+ return false;
+ case CSSSyntaxType::kImage:
+ case CSSSyntaxType::kUrl:
+ return value.GetType() == CSSStyleValue::kURLImageType;
+ case CSSSyntaxType::kAngle:
+ return CSSOMTypes::IsCSSStyleValueAngle(value);
+ case CSSSyntaxType::kTime:
+ return CSSOMTypes::IsCSSStyleValueTime(value);
+ case CSSSyntaxType::kResolution:
+ return CSSOMTypes::IsCSSStyleValueResolution(value);
+ case CSSSyntaxType::kTransformFunction:
+ // TODO(andruud): Currently not supported by Typed OM.
+ // https://github.com/w3c/css-houdini-drafts/issues/290
+ // For now, this should accept a CSSUnsupportedStyleValue, such that
+ // <transform-function> values can be moved from one registered property
+ // to another.
+ // TODO(andruud): Support custom properties in CSSUnsupportedStyleValue.
+ return false;
+ case CSSSyntaxType::kTransformList:
+ return value.GetType() == CSSStyleValue::kTransformType;
+ case CSSSyntaxType::kCustomIdent:
+ return value.GetType() == CSSStyleValue::kKeywordType;
+ default:
+ return false;
+ }
+}
+
+bool CSSSyntaxDescriptor::CanTake(const CSSStyleValue& value) const {
+ for (const CSSSyntaxComponent& component : syntax_components_) {
+ if (component.CanTake(value))
+ return true;
+ }
+ return false;
+}
+
const CSSValue* CSSSyntaxDescriptor::Parse(CSSParserTokenRange range,
const CSSParserContext* context,
bool is_animation_tainted) const {
diff --git a/chromium/third_party/blink/renderer/core/css/css_syntax_descriptor.h b/chromium/third_party/blink/renderer/core/css/css_syntax_descriptor.h
index 4e5c42491ce..ec88ced9391 100644
--- a/chromium/third_party/blink/renderer/core/css/css_syntax_descriptor.h
+++ b/chromium/third_party/blink/renderer/core/css/css_syntax_descriptor.h
@@ -10,6 +10,7 @@
namespace blink {
class CSSParserContext;
+class CSSStyleValue;
class CSSValue;
enum class CSSSyntaxType {
@@ -45,6 +46,8 @@ struct CSSSyntaxComponent {
bool IsRepeatable() const { return repeat_ != CSSSyntaxRepeat::kNone; }
+ bool CanTake(const CSSStyleValue&) const;
+
CSSSyntaxType type_;
String string_; // Only used when type_ is CSSSyntaxType::kIdent
CSSSyntaxRepeat repeat_;
@@ -57,6 +60,7 @@ class CORE_EXPORT CSSSyntaxDescriptor {
const CSSValue* Parse(CSSParserTokenRange,
const CSSParserContext*,
bool is_animation_tainted) const;
+ bool CanTake(const CSSStyleValue&) const;
bool IsValid() const { return !syntax_components_.IsEmpty(); }
bool IsTokenStream() const {
return syntax_components_.size() == 1 &&
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 a7cd8edfd88..84b6e122740 100644
--- a/chromium/third_party/blink/renderer/core/css/css_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_value.h
@@ -274,16 +274,16 @@ class CORE_EXPORT CSSValue : public GarbageCollectedFinalized<CSSValue> {
unsigned class_type_ : kClassTypeBits; // ClassType
};
-template <typename CSSValueType, size_t inlineCapacity>
+template <typename CSSValueType, wtf_size_t inlineCapacity>
inline bool CompareCSSValueVector(
const HeapVector<Member<CSSValueType>, inlineCapacity>& first_vector,
const HeapVector<Member<CSSValueType>, inlineCapacity>& second_vector) {
- size_t size = first_vector.size();
+ wtf_size_t size = first_vector.size();
if (size != second_vector.size()) {
return false;
}
- for (size_t i = 0; i < size; i++) {
+ for (wtf_size_t i = 0; i < size; i++) {
if (!DataEquivalent(first_vector[i], second_vector[i])) {
return false;
}
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 4c4706cfe0b..88c19d9655b 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
@@ -14,6 +14,8 @@
namespace blink {
+class PropertyRegistration;
+
namespace {
CSSStyleValueVector ParseCSSStyleValue(
@@ -28,8 +30,10 @@ CSSStyleValueVector ParseCSSStyleValue(
return CSSStyleValueVector();
}
+ // TODO(andruud): Actually get PropertyRegistration and pass it.
const auto style_values = StyleValueFactory::FromString(
- property_id, value, CSSParserContext::Create(*execution_context));
+ property_id, nullptr, value,
+ CSSParserContext::Create(*execution_context));
if (style_values.IsEmpty()) {
exception_state.ThrowTypeError("The value provided ('" + value +
"') could not be parsed as a '" +
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/cssom_types.h b/chromium/third_party/blink/renderer/core/css/cssom/cssom_types.h
index 701a5414349..6ad9dbec2e6 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/cssom_types.h
+++ b/chromium/third_party/blink/renderer/core/css/cssom/cssom_types.h
@@ -11,6 +11,8 @@
namespace blink {
+class PropertyRegistration;
+
// This class provides utility functions for determining whether a property
// can accept a CSSStyleValue type or instance. Its implementation is generated
// using input from CSSProperties.json5 and the script
@@ -19,9 +21,21 @@ class CSSOMTypes {
STATIC_ONLY(CSSOMTypes);
public:
+ static bool IsCSSStyleValueLength(const CSSStyleValue&);
+ static bool IsCSSStyleValueNumber(const CSSStyleValue&);
+ static bool IsCSSStyleValueTime(const CSSStyleValue&);
+ static bool IsCSSStyleValueAngle(const CSSStyleValue&);
+ static bool IsCSSStyleValuePercentage(const CSSStyleValue&);
+ static bool IsCSSStyleValueResolution(const CSSStyleValue&);
+ static bool IsCSSStyleValueFlex(const CSSStyleValue&);
+ static bool IsCSSStyleValueImage(const CSSStyleValue&);
+ static bool IsCSSStyleValueTransform(const CSSStyleValue&);
+ static bool IsCSSStyleValuePosition(const CSSStyleValue&);
+
static bool IsPropertySupported(CSSPropertyID);
- static bool PropertyCanTake(CSSPropertyID, const CSSStyleValue&);
- static bool PropertyCanTakeType(CSSPropertyID, CSSStyleValue::StyleValueType);
+ static bool PropertyCanTake(CSSPropertyID,
+ const PropertyRegistration*,
+ const CSSStyleValue&);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/inline_style_property_map.cc b/chromium/third_party/blink/renderer/core/css/cssom/inline_style_property_map.cc
index 65e9ed9260c..8eb68d3f0d7 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/inline_style_property_map.cc
+++ b/chromium/third_party/blink/renderer/core/css/cssom/inline_style_property_map.cc
@@ -7,6 +7,7 @@
#include "third_party/blink/renderer/core/css/css_custom_property_declaration.h"
#include "third_party/blink/renderer/core/css/css_property_value_set.h"
#include "third_party/blink/renderer/core/css/css_variable_reference_value.h"
+#include "third_party/blink/renderer/core/css/property_registry.h"
#include "third_party/blink/renderer/core/css/style_property_serializer.h"
namespace blink {
@@ -25,8 +26,10 @@ const CSSValue* InlineStylePropertyMap::GetProperty(CSSPropertyID property_id) {
const CSSValue* InlineStylePropertyMap::GetCustomProperty(
AtomicString property_name) {
const CSSPropertyValueSet* inline_style = owner_element_->InlineStyle();
- return inline_style ? inline_style->GetPropertyCSSValue(property_name)
- : nullptr;
+ const CSSValue* value =
+ inline_style ? inline_style->GetPropertyCSSValue(property_name) : nullptr;
+ return PropertyRegistry::ParseIfRegistered(owner_element_->GetDocument(),
+ property_name, value);
}
void InlineStylePropertyMap::SetProperty(CSSPropertyID property_id,
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 0ec4c0624a5..8bc28e37f11 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
@@ -12,7 +12,9 @@
#include "third_party/blink/renderer/core/css/cssom/style_value_factory.h"
#include "third_party/blink/renderer/core/css/parser/css_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/css/properties/css_property.h"
+#include "third_party/blink/renderer/core/css/property_registry.h"
#include "third_party/blink/renderer/core/style_property_shorthand.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -38,10 +40,11 @@ CSSValueList* CssValueListForPropertyID(CSSPropertyID property_id) {
const CSSValue* StyleValueToCSSValue(
const CSSProperty& property,
+ const PropertyRegistration* registration,
const CSSStyleValue& style_value,
const ExecutionContext& execution_context) {
const CSSPropertyID property_id = property.PropertyID();
- if (!CSSOMTypes::PropertyCanTake(property_id, style_value))
+ if (!CSSOMTypes::PropertyCanTake(property_id, registration, style_value))
return nullptr;
if (style_value.GetType() == CSSStyleValue::kUnknownType) {
@@ -54,6 +57,18 @@ const CSSValue* StyleValueToCSSValue(
// TODO(https://crbug.com/545324): Move this into a method on
// CSSProperty when there are more of these cases.
switch (property_id) {
+ case CSSPropertyVariable:
+ if (registration &&
+ style_value.GetType() != CSSStyleValue::kUnparsedType) {
+ CSSTokenizer tokenizer(style_value.toString());
+ const auto tokens = tokenizer.TokenizeToEOF();
+ CSSParserTokenRange range(tokens);
+ CSSParserContext* context = CSSParserContext::Create(execution_context);
+ scoped_refptr<CSSVariableData> variable_data = CSSVariableData::Create(
+ range, false, false, context->BaseURL(), context->Charset());
+ return CSSVariableReferenceValue::Create(variable_data, *context);
+ }
+ break;
case CSSPropertyBorderBottomLeftRadius:
case CSSPropertyBorderBottomRightRadius:
case CSSPropertyBorderTopLeftRadius:
@@ -179,6 +194,7 @@ const CSSValue* StyleValueToCSSValue(
const CSSValue* CoerceStyleValueOrString(
const CSSProperty& property,
+ const PropertyRegistration* registration,
const CSSStyleValueOrString& value,
const ExecutionContext& execution_context) {
DCHECK(!property.IsRepeated());
@@ -187,17 +203,18 @@ const CSSValue* CoerceStyleValueOrString(
if (!value.GetAsCSSStyleValue())
return nullptr;
- return StyleValueToCSSValue(property, *value.GetAsCSSStyleValue(),
- execution_context);
+ return StyleValueToCSSValue(property, registration,
+ *value.GetAsCSSStyleValue(), execution_context);
} else {
DCHECK(value.IsString());
const auto values = StyleValueFactory::FromString(
- property.PropertyID(), value.GetAsString(),
+ property.PropertyID(), registration, value.GetAsString(),
CSSParserContext::Create(execution_context));
if (values.size() != 1U)
return nullptr;
- return StyleValueToCSSValue(property, *values[0], execution_context);
+ return StyleValueToCSSValue(property, registration, *values[0],
+ execution_context);
}
}
@@ -218,21 +235,21 @@ const CSSValue* CoerceStyleValuesOrStrings(
return nullptr;
css_values.push_back(StyleValueToCSSValue(
- property, *value.GetAsCSSStyleValue(), execution_context));
+ property, nullptr, *value.GetAsCSSStyleValue(), execution_context));
} else {
DCHECK(value.IsString());
if (!parser_context)
parser_context = CSSParserContext::Create(execution_context);
const auto subvalues = StyleValueFactory::FromString(
- property.PropertyID(), value.GetAsString(), parser_context);
+ property.PropertyID(), nullptr, value.GetAsString(), parser_context);
if (subvalues.IsEmpty())
return nullptr;
for (const auto& subvalue : subvalues) {
DCHECK(subvalue);
- css_values.push_back(
- StyleValueToCSSValue(property, *subvalue, execution_context));
+ css_values.push_back(StyleValueToCSSValue(property, nullptr, *subvalue,
+ execution_context));
}
}
}
@@ -273,8 +290,10 @@ void StylePropertyMap::set(const ExecutionContext* execution_context,
String css_text;
if (values[0].IsCSSStyleValue()) {
CSSStyleValue* style_value = values[0].GetAsCSSStyleValue();
- if (style_value && CSSOMTypes::PropertyCanTake(property_id, *style_value))
+ if (style_value &&
+ CSSOMTypes::PropertyCanTake(property_id, nullptr, *style_value)) {
css_text = style_value->toString();
+ }
} else {
css_text = values[0].GetAsString();
}
@@ -287,11 +306,23 @@ void StylePropertyMap::set(const ExecutionContext* execution_context,
return;
}
+ const PropertyRegistration* registration = nullptr;
+
+ if (property_id == CSSPropertyVariable && execution_context->IsDocument()) {
+ const PropertyRegistry* registry =
+ ToDocument(*execution_context).GetPropertyRegistry();
+ if (registry) {
+ registration = registry->Registration(AtomicString(property_name));
+ }
+ }
+
const CSSValue* result = nullptr;
- if (property.IsRepeated())
+ if (property.IsRepeated()) {
result = CoerceStyleValuesOrStrings(property, values, *execution_context);
- else if (values.size() == 1U)
- result = CoerceStyleValueOrString(property, values[0], *execution_context);
+ } else if (values.size() == 1U) {
+ result = CoerceStyleValueOrString(property, registration, values[0],
+ *execution_context);
+ }
if (!result) {
exception_state.ThrowTypeError("Invalid type for property");
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 52601ae6f96..1733f89477c 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
@@ -24,6 +24,7 @@
#include "third_party/blink/renderer/core/css/parser/css_tokenizer.h"
#include "third_party/blink/renderer/core/css/parser/css_variable_parser.h"
#include "third_party/blink/renderer/core/css/properties/css_property.h"
+#include "third_party/blink/renderer/core/css/property_registration.h"
#include "third_party/blink/renderer/core/style_property_shorthand.h"
namespace blink {
@@ -226,6 +227,7 @@ CSSStyleValueVector UnsupportedCSSValue(CSSPropertyID property_id,
CSSStyleValueVector StyleValueFactory::FromString(
CSSPropertyID property_id,
+ const PropertyRegistration* registration,
const String& css_text,
const CSSParserContext* parser_context) {
DCHECK_NE(property_id, CSSPropertyInvalid);
@@ -253,6 +255,16 @@ CSSStyleValueVector StyleValueFactory::FromString(
return result;
}
+ if (property_id == CSSPropertyVariable && registration) {
+ const bool is_animation_tainted = false;
+ const CSSValue* value = registration->Syntax().Parse(tokens, parser_context,
+ is_animation_tainted);
+ if (!value)
+ return CSSStyleValueVector();
+
+ return StyleValueFactory::CssValueToStyleValueVector(property_id, *value);
+ }
+
if ((property_id == CSSPropertyVariable && !tokens.IsEmpty()) ||
CSSVariableParser::ContainsValidVariableReferences(range)) {
const auto variable_data = CSSVariableData::Create(
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/style_value_factory.h b/chromium/third_party/blink/renderer/core/css/cssom/style_value_factory.h
index be8c1289961..a39f0ec2edd 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/style_value_factory.h
+++ b/chromium/third_party/blink/renderer/core/css/cssom/style_value_factory.h
@@ -13,12 +13,14 @@ namespace blink {
class CSSParserContext;
class CSSValue;
+class PropertyRegistration;
class CORE_EXPORT StyleValueFactory {
STATIC_ONLY(StyleValueFactory);
public:
static CSSStyleValueVector FromString(CSSPropertyID,
+ const PropertyRegistration*,
const String&,
const CSSParserContext*);
static CSSStyleValue* CssValueToStyleValue(CSSPropertyID, const CSSValue&);
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 e6c58c440fc..1eba6c3480f 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
@@ -115,7 +115,7 @@ static bool RulesApplicableInCurrentTreeScope(
template <typename RuleDataListType>
void ElementRuleCollector::CollectMatchingRulesForList(
const RuleDataListType* rules,
- CascadeOrder cascade_order,
+ ShadowV0CascadeOrder cascade_order,
const MatchRequest& match_request,
PartNames* part_names) {
if (!rules)
@@ -188,7 +188,7 @@ void ElementRuleCollector::CollectMatchingRulesForList(
DISABLE_CFI_PERF
void ElementRuleCollector::CollectMatchingRules(
const MatchRequest& match_request,
- CascadeOrder cascade_order,
+ ShadowV0CascadeOrder cascade_order,
bool matching_tree_boundary_rules) {
DCHECK(match_request.rule_set);
DCHECK(context_.GetElement());
@@ -244,7 +244,7 @@ void ElementRuleCollector::CollectMatchingRules(
void ElementRuleCollector::CollectMatchingShadowHostRules(
const MatchRequest& match_request,
- CascadeOrder cascade_order) {
+ ShadowV0CascadeOrder cascade_order) {
CollectMatchingRulesForList(match_request.rule_set->ShadowHostRules(),
cascade_order, match_request);
}
@@ -252,7 +252,7 @@ void ElementRuleCollector::CollectMatchingShadowHostRules(
void ElementRuleCollector::CollectMatchingPartPseudoRules(
const MatchRequest& match_request,
PartNames& part_names,
- CascadeOrder cascade_order) {
+ ShadowV0CascadeOrder cascade_order) {
if (!RuntimeEnabledFeatures::CSSPartPseudoElementEnabled())
return;
CollectMatchingRulesForList(match_request.rule_set->PartPseudoRules(),
@@ -330,7 +330,7 @@ void ElementRuleCollector::SortAndTransferMatchedRules() {
void ElementRuleCollector::DidMatchRule(
const RuleData& rule_data,
const SelectorChecker::MatchResult& result,
- CascadeOrder cascade_order,
+ ShadowV0CascadeOrder cascade_order,
const MatchRequest& match_request) {
PseudoId dynamic_pseudo = result.dynamic_pseudo;
// If we're matching normal rules, set a pseudo bit if we really just matched
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 51246f27b50..270f0e4c2f3 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
@@ -43,11 +43,11 @@ class SelectorFilter;
class StaticCSSRuleList;
class StyleRuleUsageTracker;
-// TODO(kochi): CascadeOrder is used only for Shadow DOM V0 bug-compatible
-// cascading order. Once Shadow DOM V0 implementation is gone, remove this
-// completely.
-using CascadeOrder = unsigned;
-const CascadeOrder kIgnoreCascadeOrder = 0;
+// TODO(kochi): ShadowV0CascadeOrder is used only for Shadow DOM V0
+// bug-compatible cascading order. Once Shadow DOM V0 implementation is gone,
+// remove this completely.
+using ShadowV0CascadeOrder = unsigned;
+const ShadowV0CascadeOrder kIgnoreCascadeOrder = 0;
class MatchedRule {
DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
@@ -55,7 +55,7 @@ class MatchedRule {
public:
MatchedRule(const RuleData* rule_data,
unsigned specificity,
- CascadeOrder cascade_order,
+ ShadowV0CascadeOrder cascade_order,
unsigned style_sheet_index,
const CSSStyleSheet* parent_style_sheet)
: rule_data_(rule_data),
@@ -129,13 +129,15 @@ class ElementRuleCollector {
CSSRuleList* MatchedCSSRuleList();
void CollectMatchingRules(const MatchRequest&,
- CascadeOrder = kIgnoreCascadeOrder,
+ ShadowV0CascadeOrder = kIgnoreCascadeOrder,
bool matching_tree_boundary_rules = false);
- void CollectMatchingShadowHostRules(const MatchRequest&,
- CascadeOrder = kIgnoreCascadeOrder);
- void CollectMatchingPartPseudoRules(const MatchRequest&,
- PartNames&,
- CascadeOrder = kIgnoreCascadeOrder);
+ void CollectMatchingShadowHostRules(
+ const MatchRequest&,
+ ShadowV0CascadeOrder = kIgnoreCascadeOrder);
+ void CollectMatchingPartPseudoRules(
+ const MatchRequest&,
+ PartNames&,
+ ShadowV0CascadeOrder = kIgnoreCascadeOrder);
void SortAndTransferMatchedRules();
void ClearMatchedRules();
void AddElementStyleProperties(const CSSPropertyValueSet*,
@@ -158,13 +160,13 @@ class ElementRuleCollector {
private:
template <typename RuleDataListType>
void CollectMatchingRulesForList(const RuleDataListType*,
- CascadeOrder,
+ ShadowV0CascadeOrder,
const MatchRequest&,
PartNames* = nullptr);
void DidMatchRule(const RuleData&,
const SelectorChecker::MatchResult&,
- CascadeOrder,
+ ShadowV0CascadeOrder,
const MatchRequest&);
template <class CSSRuleCollection>
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 0e6a0f15b07..b80e2624494 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
@@ -222,7 +222,8 @@ FontSelectionRange ExpectedRangeForChoice(
}
}
-TEST_F(FontFaceCacheTest, MatchCombinations) {
+// Flaky; https://crbug.com/871812
+TEST_F(FontFaceCacheTest, DISABLED_MatchCombinations) {
CSSValue* widths[] = {CSSIdentifierValue::Create(CSSValueCondensed),
CSSIdentifierValue::Create(CSSValueExpanded)};
CSSValue* slopes[] = {CSSIdentifierValue::Create(CSSValueNormal),
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 3dcf1156d14..573b2d7ccb6 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
@@ -39,7 +39,7 @@ void FontFaceSet::FireLoadingEvent() {
if (should_fire_loading_event_) {
should_fire_loading_event_ = false;
DispatchEvent(
- FontFaceSetLoadEvent::CreateForFontFaces(EventTypeNames::loading));
+ *FontFaceSetLoadEvent::CreateForFontFaces(EventTypeNames::loading));
}
}
@@ -244,9 +244,9 @@ void FontFaceSet::FireDoneEvent() {
failed_fonts_.clear();
}
is_loading_ = false;
- DispatchEvent(done_event);
+ DispatchEvent(*done_event);
if (error_event)
- DispatchEvent(error_event);
+ DispatchEvent(*error_event);
}
if (ready_->GetState() == ReadyProperty::kPending)
diff --git a/chromium/third_party/blink/renderer/core/css/html.css b/chromium/third_party/blink/renderer/core/css/html.css
index d5305dee6da..22d560b7fcb 100644
--- a/chromium/third_party/blink/renderer/core/css/html.css
+++ b/chromium/third_party/blink/renderer/core/css/html.css
@@ -390,7 +390,7 @@ fieldset {
-webkit-padding-end: 0.75em;
-webkit-padding-after: 0.625em;
border: 2px groove ThreeDFace;
- min-width: -webkit-min-content;
+ min-inline-size: min-content;
}
button {
@@ -555,12 +555,6 @@ input[type="image" i] {
cursor: pointer;
}
-input:-webkit-autofill, textarea:-webkit-autofill, select:-webkit-autofill {
- background-color: #FAFFBD !important;
- background-image:none !important;
- color: #000000 !important;
-}
-
input[type="radio" i], input[type="checkbox" i] {
margin: 3px 0.5ex;
padding: initial;
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 d849eb9d07a..1051232f6a7 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
@@ -3,11 +3,10 @@
// found in the LICENSE file.
#include "third_party/blink/renderer/core/css/parser/css_lazy_parsing_state.h"
-#include "third_party/blink/renderer/core/css/parser/css_lazy_property_parser_impl.h"
+
#include "third_party/blink/renderer/core/css/parser/css_parser_token_stream.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/frame/use_counter.h"
-#include "third_party/blink/renderer/platform/histogram.h"
namespace blink {
@@ -17,22 +16,8 @@ CSSLazyParsingState::CSSLazyParsingState(const CSSParserContext* context,
: context_(context),
sheet_text_(sheet_text),
owning_contents_(contents),
- parsed_style_rules_(0),
- total_style_rules_(0),
- style_rules_needed_for_next_milestone_(0),
- usage_(kUsageGe0),
should_use_count_(context_->IsUseCounterRecordingEnabled()) {}
-void CSSLazyParsingState::FinishInitialParsing() {
- RecordUsageMetrics();
-}
-
-CSSLazyPropertyParserImpl* CSSLazyParsingState::CreateLazyParser(
- const size_t offset) {
- ++total_style_rules_;
- return new CSSLazyPropertyParserImpl(offset, this);
-}
-
const CSSParserContext* CSSLazyParsingState::Context() {
DCHECK(owning_contents_);
if (!should_use_count_) {
@@ -50,15 +35,6 @@ const CSSParserContext* CSSLazyParsingState::Context() {
return context_;
}
-void CSSLazyParsingState::CountRuleParsed() {
- ++parsed_style_rules_;
- while (parsed_style_rules_ > style_rules_needed_for_next_milestone_) {
- DCHECK_NE(kUsageAll, usage_);
- ++usage_;
- RecordUsageMetrics();
- }
-}
-
bool CSSLazyParsingState::ShouldLazilyParseProperties(
const CSSSelectorList& selectors) const {
// Disallow lazy parsing for blocks which have before/after in their selector
@@ -80,42 +56,6 @@ bool CSSLazyParsingState::ShouldLazilyParseProperties(
return true;
}
-void CSSLazyParsingState::RecordUsageMetrics() {
- DEFINE_STATIC_LOCAL(EnumerationHistogram, usage_histogram,
- ("Style.LazyUsage.Percent", kUsageLastValue));
- DEFINE_STATIC_LOCAL(CustomCountHistogram, total_rules_histogram,
- ("Style.TotalLazyRules", 0, 100000, 50));
- DEFINE_STATIC_LOCAL(CustomCountHistogram, total_rules_full_usage_histogram,
- ("Style.TotalLazyRules.FullUsage", 0, 100000, 50));
- switch (usage_) {
- case kUsageGe0:
- total_rules_histogram.Count(total_style_rules_);
- style_rules_needed_for_next_milestone_ = total_style_rules_ * .1;
- break;
- case kUsageGt10:
- style_rules_needed_for_next_milestone_ = total_style_rules_ * .25;
- break;
- case kUsageGt25:
- style_rules_needed_for_next_milestone_ = total_style_rules_ * .5;
- break;
- case kUsageGt50:
- style_rules_needed_for_next_milestone_ = total_style_rules_ * .75;
- break;
- case kUsageGt75:
- style_rules_needed_for_next_milestone_ = total_style_rules_ * .9;
- break;
- case kUsageGt90:
- style_rules_needed_for_next_milestone_ = total_style_rules_ - 1;
- break;
- case kUsageAll:
- total_rules_full_usage_histogram.Count(total_style_rules_);
- style_rules_needed_for_next_milestone_ = total_style_rules_;
- break;
- }
-
- usage_histogram.Count(usage_);
-}
-
void CSSLazyParsingState::Trace(blink::Visitor* visitor) {
visitor->Trace(owning_contents_);
visitor->Trace(document_);
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 94eb06b8825..1e50644f8ea 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
@@ -12,8 +12,6 @@
namespace blink {
-class CSSLazyPropertyParserImpl;
-
// This class helps lazy parsing by retaining necessary state. It should not
// outlive the StyleSheetContents that initiated the parse, as it retains a raw
// reference to the UseCounter associated with the style sheet.
@@ -30,38 +28,13 @@ class CSSLazyParsingState
const String& sheet_text,
StyleSheetContents*);
- // Called when all lazy property parsers are initialized. At this point we
- // know the total number of style rules that deferred parsing.
- void FinishInitialParsing();
-
- // Helper method used to bump total_style_rules_.
- CSSLazyPropertyParserImpl* CreateLazyParser(size_t offset);
-
const CSSParserContext* Context();
const String& SheetText() const { return sheet_text_; }
- void CountRuleParsed();
bool ShouldLazilyParseProperties(const CSSSelectorList&) const;
void Trace(blink::Visitor*);
- // Exposed for tests. This enum is used to back a histogram, so new values
- // must be appended to the end, before UsageLastValue.
- enum CSSRuleUsage {
- kUsageGe0 = 0,
- kUsageGt10 = 1,
- kUsageGt25 = 2,
- kUsageGt50 = 3,
- kUsageGt75 = 4,
- kUsageGt90 = 5,
- kUsageAll = 6,
-
- // This value must be last.
- kUsageLastValue = 7
- };
-
private:
- void RecordUsageMetrics();
-
Member<const CSSParserContext> context_;
// Also referenced on the css resource.
String sheet_text_;
@@ -74,14 +47,6 @@ class CSSLazyParsingState
// UseCounter per every property parse is a bit more expensive.
WeakMember<Document> document_;
- // Used for calculating the % of rules that ended up being parsed.
- int parsed_style_rules_;
- int total_style_rules_;
-
- int style_rules_needed_for_next_milestone_;
-
- int usage_;
-
// Whether or not use counting is enabled for parsing. This will usually be
// true, except for when stylesheets with @imports are removed from the page.
// See StyleRuleImport::setCSSStyleSheet.
diff --git a/chromium/third_party/blink/renderer/core/css/parser/css_lazy_parsing_test.cc b/chromium/third_party/blink/renderer/core/css/parser/css_lazy_parsing_test.cc
index c5415024fad..077033435c5 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/css_lazy_parsing_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/parser/css_lazy_parsing_test.cc
@@ -13,7 +13,6 @@
#include "third_party/blink/renderer/core/page/page.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/histogram_tester.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
@@ -29,7 +28,6 @@ class CSSLazyParsingTest : public testing::Test {
}
protected:
- HistogramTester histogram_tester_;
Persistent<StyleSheetContents> cached_contents_;
};
@@ -170,70 +168,4 @@ TEST_F(CSSLazyParsingTest, ChangeDocuments) {
EXPECT_FALSE(use_counter2.IsCounted(CSSPropertyBackgroundColor));
}
-TEST_F(CSSLazyParsingTest, SimpleRuleUsagePercent) {
- CSSParserContext* context = CSSParserContext::Create(
- kHTMLStandardMode, SecureContextMode::kInsecureContext);
- StyleSheetContents* style_sheet = StyleSheetContents::Create(context);
-
- std::string usage_metric = "Style.LazyUsage.Percent";
- std::string total_rules_metric = "Style.TotalLazyRules";
- std::string total_rules_full_usage_metric = "Style.TotalLazyRules.FullUsage";
- histogram_tester_.ExpectTotalCount(usage_metric, 0);
-
- String sheet_text =
- "body { background-color: red; }"
- "p { color: blue; }"
- "a { color: yellow; }"
- "#id { color: blue; }"
- "div { color: grey; }";
- CSSParser::ParseSheet(context, style_sheet, sheet_text,
- true /* lazy parse */);
-
- histogram_tester_.ExpectTotalCount(total_rules_metric, 1);
- histogram_tester_.ExpectUniqueSample(total_rules_metric, 5, 1);
-
- // Only log the full usage metric when all the rules have been actually
- // parsed.
- histogram_tester_.ExpectTotalCount(total_rules_full_usage_metric, 0);
-
- histogram_tester_.ExpectTotalCount(usage_metric, 1);
- histogram_tester_.ExpectUniqueSample(usage_metric,
- CSSLazyParsingState::kUsageGe0, 1);
-
- RuleAt(style_sheet, 0)->Properties();
- histogram_tester_.ExpectTotalCount(usage_metric, 2);
- histogram_tester_.ExpectBucketCount(usage_metric,
- CSSLazyParsingState::kUsageGt10, 1);
-
- RuleAt(style_sheet, 1)->Properties();
- histogram_tester_.ExpectTotalCount(usage_metric, 3);
- histogram_tester_.ExpectBucketCount(usage_metric,
- CSSLazyParsingState::kUsageGt25, 1);
-
- RuleAt(style_sheet, 2)->Properties();
- histogram_tester_.ExpectTotalCount(usage_metric, 4);
- histogram_tester_.ExpectBucketCount(usage_metric,
- CSSLazyParsingState::kUsageGt50, 1);
-
- RuleAt(style_sheet, 3)->Properties();
- histogram_tester_.ExpectTotalCount(usage_metric, 5);
- histogram_tester_.ExpectBucketCount(usage_metric,
- CSSLazyParsingState::kUsageGt75, 1);
-
- // Only log the full usage metric when all the rules have been actually
- // parsed.
- histogram_tester_.ExpectTotalCount(total_rules_full_usage_metric, 0);
-
- // Parsing the last rule bumps both Gt90 and All buckets.
- RuleAt(style_sheet, 4)->Properties();
- histogram_tester_.ExpectTotalCount(usage_metric, 7);
- histogram_tester_.ExpectBucketCount(usage_metric,
- CSSLazyParsingState::kUsageGt90, 1);
- histogram_tester_.ExpectBucketCount(usage_metric,
- CSSLazyParsingState::kUsageAll, 1);
-
- histogram_tester_.ExpectTotalCount(total_rules_full_usage_metric, 1);
- histogram_tester_.ExpectUniqueSample(total_rules_full_usage_metric, 5, 1);
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/parser/css_lazy_property_parser_impl.cc b/chromium/third_party/blink/renderer/core/css/parser/css_lazy_property_parser_impl.cc
index 1f44accefc9..d43f0e7c53d 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/css_lazy_property_parser_impl.cc
+++ b/chromium/third_party/blink/renderer/core/css/parser/css_lazy_property_parser_impl.cc
@@ -14,7 +14,6 @@ CSSLazyPropertyParserImpl::CSSLazyPropertyParserImpl(size_t offset,
: CSSLazyPropertyParser(), offset_(offset), lazy_state_(state) {}
CSSPropertyValueSet* CSSLazyPropertyParserImpl::ParseProperties() {
- lazy_state_->CountRuleParsed();
return CSSParserImpl::ParseDeclarationListForLazyStyle(
lazy_state_->SheetText(), offset_, lazy_state_->Context());
}
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 3fa20d6a895..5b80d528553 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
@@ -583,7 +583,10 @@ bool CSSParserFastPaths::IsValidKeywordPropertyAndValue(
return value_id == CSSValueTop || value_id == CSSValueBottom;
case CSSPropertyClear:
return value_id == CSSValueNone || value_id == CSSValueLeft ||
- value_id == CSSValueRight || value_id == CSSValueBoth;
+ value_id == CSSValueRight || value_id == CSSValueBoth ||
+ (RuntimeEnabledFeatures::CSSLogicalEnabled() &&
+ (value_id == CSSValueInlineStart ||
+ value_id == CSSValueInlineEnd));
case CSSPropertyClipRule:
case CSSPropertyFillRule:
return value_id == CSSValueNonzero || value_id == CSSValueEvenodd;
@@ -592,8 +595,8 @@ bool CSSParserFastPaths::IsValidKeywordPropertyAndValue(
return value_id == CSSValueAuto || value_id == CSSValueSRGB ||
value_id == CSSValueLinearRGB;
case CSSPropertyColorRendering:
- return value_id == CSSValueAuto || value_id == CSSValueOptimizeSpeed ||
- value_id == CSSValueOptimizeQuality;
+ return value_id == CSSValueAuto || value_id == CSSValueOptimizespeed ||
+ value_id == CSSValueOptimizequality;
case CSSPropertyDirection:
return value_id == CSSValueLtr || value_id == CSSValueRtl;
case CSSPropertyDisplay:
@@ -601,8 +604,7 @@ bool CSSParserFastPaths::IsValidKeywordPropertyAndValue(
value_id == CSSValueWebkitFlex ||
value_id == CSSValueWebkitInlineFlex || value_id == CSSValueNone ||
value_id == CSSValueGrid || value_id == CSSValueInlineGrid ||
- (RuntimeEnabledFeatures::CSSDisplayContentsEnabled() &&
- value_id == CSSValueContents);
+ value_id == CSSValueContents;
case CSSPropertyDominantBaseline:
return value_id == CSSValueAuto || value_id == CSSValueAlphabetic ||
value_id == CSSValueMiddle ||
@@ -612,6 +614,9 @@ bool CSSParserFastPaths::IsValidKeywordPropertyAndValue(
return value_id == CSSValueShow || value_id == CSSValueHide;
case CSSPropertyFloat:
return value_id == CSSValueLeft || value_id == CSSValueRight ||
+ (RuntimeEnabledFeatures::CSSLogicalEnabled() &&
+ (value_id == CSSValueInlineStart ||
+ value_id == CSSValueInlineEnd)) ||
value_id == CSSValueNone;
case CSSPropertyImageRendering:
return value_id == CSSValueAuto ||
@@ -669,14 +674,16 @@ bool CSSParserFastPaths::IsValidKeywordPropertyAndValue(
case CSSPropertyResize:
return value_id == CSSValueNone || value_id == CSSValueBoth ||
value_id == CSSValueHorizontal || value_id == CSSValueVertical ||
+ (RuntimeEnabledFeatures::CSSLogicalEnabled() &&
+ (value_id == CSSValueBlock || value_id == CSSValueInline)) ||
value_id == CSSValueAuto;
case CSSPropertyScrollBehavior:
DCHECK(RuntimeEnabledFeatures::CSSOMSmoothScrollEnabled());
return value_id == CSSValueAuto || value_id == CSSValueSmooth;
case CSSPropertyShapeRendering:
- return value_id == CSSValueAuto || value_id == CSSValueOptimizeSpeed ||
- value_id == CSSValueCrispEdges ||
- value_id == CSSValueGeometricPrecision;
+ return value_id == CSSValueAuto || value_id == CSSValueOptimizespeed ||
+ value_id == CSSValueCrispedges ||
+ value_id == CSSValueGeometricprecision;
case CSSPropertySpeak:
return value_id == CSSValueNone || value_id == CSSValueNormal ||
value_id == CSSValueSpellOut || value_id == CSSValueDigits ||
@@ -723,9 +730,9 @@ bool CSSParserFastPaths::IsValidKeywordPropertyAndValue(
case CSSPropertyTextOverflow:
return value_id == CSSValueClip || value_id == CSSValueEllipsis;
case CSSPropertyTextRendering:
- return value_id == CSSValueAuto || value_id == CSSValueOptimizeSpeed ||
- value_id == CSSValueOptimizeLegibility ||
- value_id == CSSValueGeometricPrecision;
+ return value_id == CSSValueAuto || value_id == CSSValueOptimizespeed ||
+ value_id == CSSValueOptimizelegibility ||
+ value_id == CSSValueGeometricprecision;
case CSSPropertyTextTransform: // capitalize | uppercase | lowercase | none
return (value_id >= CSSValueCapitalize &&
value_id <= CSSValueLowercase) ||
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 22c6edb189e..abce963a1d4 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
@@ -266,8 +266,6 @@ void CSSParserImpl::ParseStyleSheet(const String& string,
style_sheet->ParserAppendRule(rule);
});
style_sheet->SetHasSyntacticallyValidCSSHeader(first_rule_valid);
- if (parser.lazy_state_)
- parser.lazy_state_->FinishInitialParsing();
TRACE_EVENT_END0("blink,blink_style", "CSSParserImpl::parseStyleSheet.parse");
TRACE_EVENT_END2("blink,blink_style", "CSSParserImpl::parseStyleSheet",
@@ -822,7 +820,7 @@ StyleRule* CSSParserImpl::ConsumeStyleRule(CSSParserTokenStream& stream) {
DCHECK(style_sheet_);
return StyleRule::CreateLazy(
std::move(selector_list),
- lazy_state_->CreateLazyParser(stream.Offset() - 1));
+ new CSSLazyPropertyParserImpl(stream.Offset() - 1, lazy_state_));
}
ConsumeDeclarationList(stream, StyleRule::kStyle);
diff --git a/chromium/third_party/blink/renderer/core/css/parser/css_parser_token_range.h b/chromium/third_party/blink/renderer/core/css/parser/css_parser_token_range.h
index 24761254544..2d5b74e2c08 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/css_parser_token_range.h
+++ b/chromium/third_party/blink/renderer/core/css/parser/css_parser_token_range.h
@@ -21,7 +21,7 @@ class CORE_EXPORT CSSParserTokenRange {
DISALLOW_NEW();
public:
- template <size_t InlineBuffer>
+ template <wtf_size_t InlineBuffer>
CSSParserTokenRange(const Vector<CSSParserToken, InlineBuffer>& vector)
: first_(vector.begin()), last_(vector.end()) {}
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 218c46468cc..deb3c170d54 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
@@ -1565,7 +1565,7 @@ CSSValue* ConsumeGridBreadth(CSSParserTokenRange& range,
}
return CSSPropertyParserHelpers::ConsumeLengthOrPercent(
range, css_parser_mode, kValueRangeNonNegative,
- CSSPropertyParserHelpers::UnitlessQuirk::kAllow);
+ CSSPropertyParserHelpers::UnitlessQuirk::kForbid);
}
CSSValue* ConsumeFitContent(CSSParserTokenRange& range,
diff --git a/chromium/third_party/blink/renderer/core/css/properties/longhands/clear_custom.cc b/chromium/third_party/blink/renderer/core/css/properties/longhands/clear_custom.cc
index 2764653f7d2..0fa6c74e360 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/longhands/clear_custom.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/longhands/clear_custom.cc
@@ -16,5 +16,27 @@ const CSSValue* Clear::CSSValueFromComputedStyleInternal(
return CSSIdentifierValue::Create(style.Clear());
}
+void Clear::ApplyValue(StyleResolverState& state, const CSSValue& value) const {
+ const CSSIdentifierValue& identifier_value = ToCSSIdentifierValue(value);
+
+ EClear c;
+ CSSValueID id = identifier_value.GetValueID();
+ switch (id) {
+ case CSSValueInlineStart:
+ case CSSValueInlineEnd:
+ if ((id == CSSValueInlineStart) ==
+ (state.Style()->Direction() == TextDirection::kLtr)) {
+ c = EClear::kLeft;
+ } else {
+ c = EClear::kRight;
+ }
+ break;
+ default:
+ c = identifier_value.ConvertTo<EClear>();
+ break;
+ }
+ state.Style()->SetClear(c);
+}
+
} // namespace CSSLonghand
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/properties/longhands/float_custom.cc b/chromium/third_party/blink/renderer/core/css/properties/longhands/float_custom.cc
index 1f9c40b5395..37c2bd54e46 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/longhands/float_custom.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/longhands/float_custom.cc
@@ -20,5 +20,27 @@ const CSSValue* Float::CSSValueFromComputedStyleInternal(
return CSSIdentifierValue::Create(style.Floating());
}
+void Float::ApplyValue(StyleResolverState& state, const CSSValue& value) const {
+ const CSSIdentifierValue& identifier_value = ToCSSIdentifierValue(value);
+
+ EFloat f;
+ CSSValueID id = identifier_value.GetValueID();
+ switch (id) {
+ case CSSValueInlineStart:
+ case CSSValueInlineEnd:
+ if ((id == CSSValueInlineStart) ==
+ (state.Style()->Direction() == TextDirection::kLtr)) {
+ f = EFloat::kLeft;
+ } else {
+ f = EFloat::kRight;
+ }
+ break;
+ default:
+ f = identifier_value.ConvertTo<EFloat>();
+ break;
+ }
+ state.Style()->SetFloating(f);
+}
+
} // namespace CSSLonghand
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/properties/longhands/resize_custom.cc b/chromium/third_party/blink/renderer/core/css/properties/longhands/resize_custom.cc
index 646a4d6da2e..9068e5b207f 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/longhands/resize_custom.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/longhands/resize_custom.cc
@@ -25,14 +25,27 @@ void Resize::ApplyValue(StyleResolverState& state,
const CSSIdentifierValue& identifier_value = ToCSSIdentifierValue(value);
EResize r = EResize::kNone;
- if (identifier_value.GetValueID() == CSSValueAuto) {
- if (Settings* settings = state.GetDocument().GetSettings()) {
- r = settings->GetTextAreasAreResizable() ? EResize::kBoth
- : EResize::kNone;
- }
- UseCounter::Count(state.GetDocument(), WebFeature::kCSSResizeAuto);
- } else {
- r = identifier_value.ConvertTo<EResize>();
+ CSSValueID id = identifier_value.GetValueID();
+ switch (id) {
+ case CSSValueAuto:
+ if (Settings* settings = state.GetDocument().GetSettings()) {
+ r = settings->GetTextAreasAreResizable() ? EResize::kBoth
+ : EResize::kNone;
+ }
+ UseCounter::Count(state.GetDocument(), WebFeature::kCSSResizeAuto);
+ break;
+ case CSSValueBlock:
+ case CSSValueInline:
+ if ((id == CSSValueBlock) ==
+ IsHorizontalWritingMode(state.Style()->GetWritingMode())) {
+ r = EResize::kVertical;
+ } else {
+ r = EResize::kHorizontal;
+ }
+ break;
+ default:
+ r = identifier_value.ConvertTo<EResize>();
+ break;
}
state.Style()->SetResize(r);
}
diff --git a/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_block_end_custom.cc b/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_block_end_custom.cc
index 2e2217708e5..29fbe3c76c6 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_block_end_custom.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_block_end_custom.cc
@@ -17,7 +17,7 @@ const CSSValue* ScrollMarginBlockEnd::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return ConsumeLength(range, context.Mode(), kValueRangeAll,
- CSSPropertyParserHelpers::UnitlessQuirk::kAllow);
+ CSSPropertyParserHelpers::UnitlessQuirk::kForbid);
}
} // namespace CSSLonghand
diff --git a/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_block_start_custom.cc b/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_block_start_custom.cc
index b8fdfd2e796..e6ba6321476 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_block_start_custom.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_block_start_custom.cc
@@ -17,7 +17,7 @@ const CSSValue* ScrollMarginBlockStart::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return ConsumeLength(range, context.Mode(), kValueRangeAll,
- CSSPropertyParserHelpers::UnitlessQuirk::kAllow);
+ CSSPropertyParserHelpers::UnitlessQuirk::kForbid);
}
} // namespace CSSLonghand
diff --git a/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_bottom_custom.cc b/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_bottom_custom.cc
index 305a1d76bf7..5583fdc311e 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_bottom_custom.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_bottom_custom.cc
@@ -17,7 +17,7 @@ const CSSValue* ScrollMarginBottom::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return ConsumeLength(range, context.Mode(), kValueRangeAll,
- CSSPropertyParserHelpers::UnitlessQuirk::kAllow);
+ CSSPropertyParserHelpers::UnitlessQuirk::kForbid);
}
const CSSValue* ScrollMarginBottom::CSSValueFromComputedStyleInternal(
diff --git a/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_inline_end_custom.cc b/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_inline_end_custom.cc
index e763ddecfff..bb8b8236c77 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_inline_end_custom.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_inline_end_custom.cc
@@ -17,7 +17,7 @@ const CSSValue* ScrollMarginInlineEnd::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return ConsumeLength(range, context.Mode(), kValueRangeAll,
- CSSPropertyParserHelpers::UnitlessQuirk::kAllow);
+ CSSPropertyParserHelpers::UnitlessQuirk::kForbid);
}
} // namespace CSSLonghand
diff --git a/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_inline_start_custom.cc b/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_inline_start_custom.cc
index 91a0c0083f5..0a2668ca02c 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_inline_start_custom.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_inline_start_custom.cc
@@ -17,7 +17,7 @@ const CSSValue* ScrollMarginInlineStart::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return ConsumeLength(range, context.Mode(), kValueRangeAll,
- CSSPropertyParserHelpers::UnitlessQuirk::kAllow);
+ CSSPropertyParserHelpers::UnitlessQuirk::kForbid);
}
} // namespace CSSLonghand
diff --git a/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_left_custom.cc b/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_left_custom.cc
index 9a47a792b3e..362208441c8 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_left_custom.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_left_custom.cc
@@ -17,7 +17,7 @@ const CSSValue* ScrollMarginLeft::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return ConsumeLength(range, context.Mode(), kValueRangeAll,
- CSSPropertyParserHelpers::UnitlessQuirk::kAllow);
+ CSSPropertyParserHelpers::UnitlessQuirk::kForbid);
}
const CSSValue* ScrollMarginLeft::CSSValueFromComputedStyleInternal(
diff --git a/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_right_custom.cc b/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_right_custom.cc
index 77bc7ab51ad..2ce02b1564d 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_right_custom.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_right_custom.cc
@@ -17,7 +17,7 @@ const CSSValue* ScrollMarginRight::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return ConsumeLength(range, context.Mode(), kValueRangeAll,
- CSSPropertyParserHelpers::UnitlessQuirk::kAllow);
+ CSSPropertyParserHelpers::UnitlessQuirk::kForbid);
}
const CSSValue* ScrollMarginRight::CSSValueFromComputedStyleInternal(
diff --git a/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_top_custom.cc b/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_top_custom.cc
index ac66acfd767..e6ce2a2b4b9 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_top_custom.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_top_custom.cc
@@ -17,7 +17,7 @@ const CSSValue* ScrollMarginTop::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return ConsumeLength(range, context.Mode(), kValueRangeAll,
- CSSPropertyParserHelpers::UnitlessQuirk::kAllow);
+ CSSPropertyParserHelpers::UnitlessQuirk::kForbid);
}
const CSSValue* ScrollMarginTop::CSSValueFromComputedStyleInternal(
diff --git a/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_block_end_custom.cc b/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_block_end_custom.cc
index bbb2a9c2d0e..1f66c7e803b 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_block_end_custom.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_block_end_custom.cc
@@ -18,7 +18,7 @@ const CSSValue* ScrollPaddingBlockEnd::ParseSingleValue(
const CSSParserLocalContext&) const {
return ConsumeLengthOrPercent(
range, context.Mode(), kValueRangeNonNegative,
- CSSPropertyParserHelpers::UnitlessQuirk::kAllow);
+ CSSPropertyParserHelpers::UnitlessQuirk::kForbid);
}
} // namespace CSSLonghand
diff --git a/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_block_start_custom.cc b/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_block_start_custom.cc
index 7cc55eea628..3c93e003db6 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_block_start_custom.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_block_start_custom.cc
@@ -18,7 +18,7 @@ const CSSValue* ScrollPaddingBlockStart::ParseSingleValue(
const CSSParserLocalContext&) const {
return ConsumeLengthOrPercent(
range, context.Mode(), kValueRangeNonNegative,
- CSSPropertyParserHelpers::UnitlessQuirk::kAllow);
+ CSSPropertyParserHelpers::UnitlessQuirk::kForbid);
}
} // namespace CSSLonghand
diff --git a/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_bottom_custom.cc b/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_bottom_custom.cc
index 23eb0304340..862abd5a324 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_bottom_custom.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_bottom_custom.cc
@@ -17,7 +17,7 @@ const CSSValue* ScrollPaddingBottom::ParseSingleValue(
const CSSParserLocalContext&) const {
return ConsumeLengthOrPercent(
range, context.Mode(), kValueRangeNonNegative,
- CSSPropertyParserHelpers::UnitlessQuirk::kAllow);
+ CSSPropertyParserHelpers::UnitlessQuirk::kForbid);
}
const CSSValue* ScrollPaddingBottom::CSSValueFromComputedStyleInternal(
diff --git a/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_inline_end_custom.cc b/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_inline_end_custom.cc
index 5e9f0e48bda..adaadd255d2 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_inline_end_custom.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_inline_end_custom.cc
@@ -18,7 +18,7 @@ const CSSValue* ScrollPaddingInlineEnd::ParseSingleValue(
const CSSParserLocalContext&) const {
return ConsumeLengthOrPercent(
range, context.Mode(), kValueRangeNonNegative,
- CSSPropertyParserHelpers::UnitlessQuirk::kAllow);
+ CSSPropertyParserHelpers::UnitlessQuirk::kForbid);
}
} // namespace CSSLonghand
diff --git a/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_inline_start_custom.cc b/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_inline_start_custom.cc
index 78075782165..7a98a9b3f96 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_inline_start_custom.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_inline_start_custom.cc
@@ -18,7 +18,7 @@ const CSSValue* ScrollPaddingInlineStart::ParseSingleValue(
const CSSParserLocalContext&) const {
return ConsumeLengthOrPercent(
range, context.Mode(), kValueRangeNonNegative,
- CSSPropertyParserHelpers::UnitlessQuirk::kAllow);
+ CSSPropertyParserHelpers::UnitlessQuirk::kForbid);
}
} // namespace CSSLonghand
diff --git a/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_left_custom.cc b/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_left_custom.cc
index 730472c3493..ee232f22c70 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_left_custom.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_left_custom.cc
@@ -17,7 +17,7 @@ const CSSValue* ScrollPaddingLeft::ParseSingleValue(
const CSSParserLocalContext&) const {
return ConsumeLengthOrPercent(
range, context.Mode(), kValueRangeNonNegative,
- CSSPropertyParserHelpers::UnitlessQuirk::kAllow);
+ CSSPropertyParserHelpers::UnitlessQuirk::kForbid);
}
const CSSValue* ScrollPaddingLeft::CSSValueFromComputedStyleInternal(
diff --git a/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_right_custom.cc b/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_right_custom.cc
index d4c0bd067ba..089a2302b7a 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_right_custom.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_right_custom.cc
@@ -17,7 +17,7 @@ const CSSValue* ScrollPaddingRight::ParseSingleValue(
const CSSParserLocalContext&) const {
return ConsumeLengthOrPercent(
range, context.Mode(), kValueRangeNonNegative,
- CSSPropertyParserHelpers::UnitlessQuirk::kAllow);
+ CSSPropertyParserHelpers::UnitlessQuirk::kForbid);
}
const CSSValue* ScrollPaddingRight::CSSValueFromComputedStyleInternal(
diff --git a/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_top_custom.cc b/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_top_custom.cc
index 5994a9ebf9c..80886a1b94c 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_top_custom.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_top_custom.cc
@@ -17,7 +17,7 @@ const CSSValue* ScrollPaddingTop::ParseSingleValue(
const CSSParserLocalContext&) const {
return ConsumeLengthOrPercent(
range, context.Mode(), kValueRangeNonNegative,
- CSSPropertyParserHelpers::UnitlessQuirk::kAllow);
+ CSSPropertyParserHelpers::UnitlessQuirk::kForbid);
}
const CSSValue* ScrollPaddingTop::CSSValueFromComputedStyleInternal(
diff --git a/chromium/third_party/blink/renderer/core/css/properties/shorthands/border_block_color_custom.cc b/chromium/third_party/blink/renderer/core/css/properties/shorthands/border_block_color_custom.cc
index a067b26f7a8..c1ab6852b74 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/shorthands/border_block_color_custom.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/shorthands/border_block_color_custom.cc
@@ -5,6 +5,8 @@
#include "third_party/blink/renderer/core/css/properties/shorthands/border_block_color.h"
#include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h"
+#include "third_party/blink/renderer/core/css/properties/computed_style_utils.h"
+#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/core/style_property_shorthand.h"
namespace blink {
@@ -20,5 +22,16 @@ bool BorderBlockColor::ParseShorthand(
borderBlockColorShorthand(), important, context, range, properties);
}
+const CSSValue* BorderBlockColor::CSSValueFromComputedStyleInternal(
+ const ComputedStyle& style,
+ const SVGComputedStyle&,
+ const LayoutObject* layout_object,
+ Node* styled_node,
+ bool allow_visited_style) const {
+ return ComputedStyleUtils::ValuesForInlineBlockShorthand(
+ borderBlockColorShorthand(), style, layout_object, styled_node,
+ allow_visited_style);
+}
+
} // namespace CSSShorthand
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/properties/shorthands/border_block_custom.cc b/chromium/third_party/blink/renderer/core/css/properties/shorthands/border_block_custom.cc
index 111168bdb9b..d18442f8e88 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/shorthands/border_block_custom.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/shorthands/border_block_custom.cc
@@ -35,5 +35,23 @@ bool BorderBlock::ParseShorthand(
return range.AtEnd();
}
+const CSSValue* BorderBlock::CSSValueFromComputedStyleInternal(
+ const ComputedStyle& style,
+ const SVGComputedStyle&,
+ const LayoutObject* layout_object,
+ Node* styled_node,
+ bool allow_visited_style) const {
+ const CSSValue* value_start =
+ GetCSSPropertyBorderBlockStart().CSSValueFromComputedStyle(
+ style, layout_object, styled_node, allow_visited_style);
+ const CSSValue* value_end =
+ GetCSSPropertyBorderBlockEnd().CSSValueFromComputedStyle(
+ style, layout_object, styled_node, allow_visited_style);
+ if (!DataEquivalent(value_start, value_end)) {
+ return nullptr;
+ }
+ return value_start;
+}
+
} // namespace CSSShorthand
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/properties/shorthands/border_block_style_custom.cc b/chromium/third_party/blink/renderer/core/css/properties/shorthands/border_block_style_custom.cc
index 9258ef733cb..d873dee0a73 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/shorthands/border_block_style_custom.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/shorthands/border_block_style_custom.cc
@@ -5,6 +5,8 @@
#include "third_party/blink/renderer/core/css/properties/shorthands/border_block_style.h"
#include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h"
+#include "third_party/blink/renderer/core/css/properties/computed_style_utils.h"
+#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/core/style_property_shorthand.h"
namespace blink {
@@ -20,5 +22,16 @@ bool BorderBlockStyle::ParseShorthand(
borderBlockStyleShorthand(), important, context, range, properties);
}
+const CSSValue* BorderBlockStyle::CSSValueFromComputedStyleInternal(
+ const ComputedStyle& style,
+ const SVGComputedStyle&,
+ const LayoutObject* layout_object,
+ Node* styled_node,
+ bool allow_visited_style) const {
+ return ComputedStyleUtils::ValuesForInlineBlockShorthand(
+ borderBlockStyleShorthand(), style, layout_object, styled_node,
+ allow_visited_style);
+}
+
} // namespace CSSShorthand
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/properties/shorthands/border_block_width_custom.cc b/chromium/third_party/blink/renderer/core/css/properties/shorthands/border_block_width_custom.cc
index da619397494..7d3523291bf 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/shorthands/border_block_width_custom.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/shorthands/border_block_width_custom.cc
@@ -5,6 +5,8 @@
#include "third_party/blink/renderer/core/css/properties/shorthands/border_block_width.h"
#include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h"
+#include "third_party/blink/renderer/core/css/properties/computed_style_utils.h"
+#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/core/style_property_shorthand.h"
namespace blink {
@@ -20,5 +22,16 @@ bool BorderBlockWidth::ParseShorthand(
borderBlockWidthShorthand(), important, context, range, properties);
}
+const CSSValue* BorderBlockWidth::CSSValueFromComputedStyleInternal(
+ const ComputedStyle& style,
+ const SVGComputedStyle&,
+ const LayoutObject* layout_object,
+ Node* styled_node,
+ bool allow_visited_style) const {
+ return ComputedStyleUtils::ValuesForInlineBlockShorthand(
+ borderBlockWidthShorthand(), style, layout_object, styled_node,
+ allow_visited_style);
+}
+
} // namespace CSSShorthand
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/properties/shorthands/border_inline_color_custom.cc b/chromium/third_party/blink/renderer/core/css/properties/shorthands/border_inline_color_custom.cc
index 315135b5f34..15ebaa985e9 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/shorthands/border_inline_color_custom.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/shorthands/border_inline_color_custom.cc
@@ -5,6 +5,8 @@
#include "third_party/blink/renderer/core/css/properties/shorthands/border_inline_color.h"
#include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h"
+#include "third_party/blink/renderer/core/css/properties/computed_style_utils.h"
+#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/core/style_property_shorthand.h"
namespace blink {
@@ -20,5 +22,16 @@ bool BorderInlineColor::ParseShorthand(
borderInlineColorShorthand(), important, context, range, properties);
}
+const CSSValue* BorderInlineColor::CSSValueFromComputedStyleInternal(
+ const ComputedStyle& style,
+ const SVGComputedStyle&,
+ const LayoutObject* layout_object,
+ Node* styled_node,
+ bool allow_visited_style) const {
+ return ComputedStyleUtils::ValuesForInlineBlockShorthand(
+ borderInlineColorShorthand(), style, layout_object, styled_node,
+ allow_visited_style);
+}
+
} // namespace CSSShorthand
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/properties/shorthands/border_inline_custom.cc b/chromium/third_party/blink/renderer/core/css/properties/shorthands/border_inline_custom.cc
index 67d5695906d..b08fe2e7f51 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/shorthands/border_inline_custom.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/shorthands/border_inline_custom.cc
@@ -35,5 +35,23 @@ bool BorderInline::ParseShorthand(
return range.AtEnd();
}
+const CSSValue* BorderInline::CSSValueFromComputedStyleInternal(
+ const ComputedStyle& style,
+ const SVGComputedStyle&,
+ const LayoutObject* layout_object,
+ Node* styled_node,
+ bool allow_visited_style) const {
+ const CSSValue* value_start =
+ GetCSSPropertyBorderInlineStart().CSSValueFromComputedStyle(
+ style, layout_object, styled_node, allow_visited_style);
+ const CSSValue* value_end =
+ GetCSSPropertyBorderInlineEnd().CSSValueFromComputedStyle(
+ style, layout_object, styled_node, allow_visited_style);
+ if (!DataEquivalent(value_start, value_end)) {
+ return nullptr;
+ }
+ return value_start;
+}
+
} // namespace CSSShorthand
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/properties/shorthands/border_inline_style_custom.cc b/chromium/third_party/blink/renderer/core/css/properties/shorthands/border_inline_style_custom.cc
index 83859ed8424..b30e9c2047d 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/shorthands/border_inline_style_custom.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/shorthands/border_inline_style_custom.cc
@@ -5,6 +5,8 @@
#include "third_party/blink/renderer/core/css/properties/shorthands/border_inline_style.h"
#include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h"
+#include "third_party/blink/renderer/core/css/properties/computed_style_utils.h"
+#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/core/style_property_shorthand.h"
namespace blink {
@@ -20,5 +22,16 @@ bool BorderInlineStyle::ParseShorthand(
borderInlineStyleShorthand(), important, context, range, properties);
}
+const CSSValue* BorderInlineStyle::CSSValueFromComputedStyleInternal(
+ const ComputedStyle& style,
+ const SVGComputedStyle&,
+ const LayoutObject* layout_object,
+ Node* styled_node,
+ bool allow_visited_style) const {
+ return ComputedStyleUtils::ValuesForInlineBlockShorthand(
+ borderInlineStyleShorthand(), style, layout_object, styled_node,
+ allow_visited_style);
+}
+
} // namespace CSSShorthand
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/properties/shorthands/border_inline_width_custom.cc b/chromium/third_party/blink/renderer/core/css/properties/shorthands/border_inline_width_custom.cc
index 1fdacb111d4..a0e10839891 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/shorthands/border_inline_width_custom.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/shorthands/border_inline_width_custom.cc
@@ -5,6 +5,8 @@
#include "third_party/blink/renderer/core/css/properties/shorthands/border_inline_width.h"
#include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h"
+#include "third_party/blink/renderer/core/css/properties/computed_style_utils.h"
+#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/core/style_property_shorthand.h"
namespace blink {
@@ -20,5 +22,16 @@ bool BorderInlineWidth::ParseShorthand(
borderInlineWidthShorthand(), important, context, range, properties);
}
+const CSSValue* BorderInlineWidth::CSSValueFromComputedStyleInternal(
+ const ComputedStyle& style,
+ const SVGComputedStyle&,
+ const LayoutObject* layout_object,
+ Node* styled_node,
+ bool allow_visited_style) const {
+ return ComputedStyleUtils::ValuesForInlineBlockShorthand(
+ borderInlineWidthShorthand(), style, layout_object, styled_node,
+ allow_visited_style);
+}
+
} // namespace CSSShorthand
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/properties/shorthands/inset_block_custom.cc b/chromium/third_party/blink/renderer/core/css/properties/shorthands/inset_block_custom.cc
index d9616b4405f..c60122b98b7 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/shorthands/inset_block_custom.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/shorthands/inset_block_custom.cc
@@ -5,6 +5,8 @@
#include "third_party/blink/renderer/core/css/properties/shorthands/inset_block.h"
#include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h"
+#include "third_party/blink/renderer/core/css/properties/computed_style_utils.h"
+#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/core/style_property_shorthand.h"
namespace blink {
@@ -20,5 +22,16 @@ bool InsetBlock::ParseShorthand(
insetBlockShorthand(), important, context, range, properties);
}
+const CSSValue* InsetBlock::CSSValueFromComputedStyleInternal(
+ const ComputedStyle& style,
+ const SVGComputedStyle&,
+ const LayoutObject* layout_object,
+ Node* styled_node,
+ bool allow_visited_style) const {
+ return ComputedStyleUtils::ValuesForInlineBlockShorthand(
+ insetBlockShorthand(), style, layout_object, styled_node,
+ allow_visited_style);
+}
+
} // namespace CSSShorthand
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/properties/shorthands/inset_custom.cc b/chromium/third_party/blink/renderer/core/css/properties/shorthands/inset_custom.cc
index 06744cb17c8..e76065f6e0b 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/shorthands/inset_custom.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/shorthands/inset_custom.cc
@@ -5,6 +5,8 @@
#include "third_party/blink/renderer/core/css/properties/shorthands/inset.h"
#include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h"
+#include "third_party/blink/renderer/core/css/properties/computed_style_utils.h"
+#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/core/style_property_shorthand.h"
namespace blink {
@@ -20,5 +22,15 @@ bool Inset::ParseShorthand(
insetShorthand(), important, context, range, properties);
}
+const CSSValue* Inset::CSSValueFromComputedStyleInternal(
+ const ComputedStyle& style,
+ const SVGComputedStyle&,
+ const LayoutObject* layout_object,
+ Node* styled_node,
+ bool allow_visited_style) const {
+ return ComputedStyleUtils::ValuesForSidesShorthand(
+ insetShorthand(), style, layout_object, styled_node, allow_visited_style);
+}
+
} // namespace CSSShorthand
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/properties/shorthands/inset_inline_custom.cc b/chromium/third_party/blink/renderer/core/css/properties/shorthands/inset_inline_custom.cc
index 2ae7dce5d07..7a6e6d27ec0 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/shorthands/inset_inline_custom.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/shorthands/inset_inline_custom.cc
@@ -5,6 +5,8 @@
#include "third_party/blink/renderer/core/css/properties/shorthands/inset_inline.h"
#include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h"
+#include "third_party/blink/renderer/core/css/properties/computed_style_utils.h"
+#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/core/style_property_shorthand.h"
namespace blink {
@@ -20,5 +22,16 @@ bool InsetInline::ParseShorthand(
insetInlineShorthand(), important, context, range, properties);
}
+const CSSValue* InsetInline::CSSValueFromComputedStyleInternal(
+ const ComputedStyle& style,
+ const SVGComputedStyle&,
+ const LayoutObject* layout_object,
+ Node* styled_node,
+ bool allow_visited_style) const {
+ return ComputedStyleUtils::ValuesForInlineBlockShorthand(
+ insetInlineShorthand(), style, layout_object, styled_node,
+ allow_visited_style);
+}
+
} // namespace CSSShorthand
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/properties/shorthands/margin_block_custom.cc b/chromium/third_party/blink/renderer/core/css/properties/shorthands/margin_block_custom.cc
index 3d91f6d7c46..aa8384ab05c 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/shorthands/margin_block_custom.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/shorthands/margin_block_custom.cc
@@ -5,6 +5,8 @@
#include "third_party/blink/renderer/core/css/properties/shorthands/margin_block.h"
#include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h"
+#include "third_party/blink/renderer/core/css/properties/computed_style_utils.h"
+#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/core/style_property_shorthand.h"
namespace blink {
@@ -20,5 +22,16 @@ bool MarginBlock::ParseShorthand(
marginBlockShorthand(), important, context, range, properties);
}
+const CSSValue* MarginBlock::CSSValueFromComputedStyleInternal(
+ const ComputedStyle& style,
+ const SVGComputedStyle&,
+ const LayoutObject* layout_object,
+ Node* styled_node,
+ bool allow_visited_style) const {
+ return ComputedStyleUtils::ValuesForInlineBlockShorthand(
+ marginBlockShorthand(), style, layout_object, styled_node,
+ allow_visited_style);
+}
+
} // namespace CSSShorthand
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/properties/shorthands/margin_inline_custom.cc b/chromium/third_party/blink/renderer/core/css/properties/shorthands/margin_inline_custom.cc
index 3dabd4b34d5..f6ad3c6ff84 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/shorthands/margin_inline_custom.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/shorthands/margin_inline_custom.cc
@@ -5,6 +5,8 @@
#include "third_party/blink/renderer/core/css/properties/shorthands/margin_inline.h"
#include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h"
+#include "third_party/blink/renderer/core/css/properties/computed_style_utils.h"
+#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/core/style_property_shorthand.h"
namespace blink {
@@ -20,5 +22,16 @@ bool MarginInline::ParseShorthand(
marginInlineShorthand(), important, context, range, properties);
}
+const CSSValue* MarginInline::CSSValueFromComputedStyleInternal(
+ const ComputedStyle& style,
+ const SVGComputedStyle&,
+ const LayoutObject* layout_object,
+ Node* styled_node,
+ bool allow_visited_style) const {
+ return ComputedStyleUtils::ValuesForInlineBlockShorthand(
+ marginInlineShorthand(), style, layout_object, styled_node,
+ allow_visited_style);
+}
+
} // namespace CSSShorthand
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/properties/shorthands/padding_block_custom.cc b/chromium/third_party/blink/renderer/core/css/properties/shorthands/padding_block_custom.cc
index 959c9ed651e..036c17e0815 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/shorthands/padding_block_custom.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/shorthands/padding_block_custom.cc
@@ -5,6 +5,8 @@
#include "third_party/blink/renderer/core/css/properties/shorthands/padding_block.h"
#include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h"
+#include "third_party/blink/renderer/core/css/properties/computed_style_utils.h"
+#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/core/style_property_shorthand.h"
namespace blink {
@@ -20,5 +22,16 @@ bool PaddingBlock::ParseShorthand(
paddingBlockShorthand(), important, context, range, properties);
}
+const CSSValue* PaddingBlock::CSSValueFromComputedStyleInternal(
+ const ComputedStyle& style,
+ const SVGComputedStyle&,
+ const LayoutObject* layout_object,
+ Node* styled_node,
+ bool allow_visited_style) const {
+ return ComputedStyleUtils::ValuesForInlineBlockShorthand(
+ paddingBlockShorthand(), style, layout_object, styled_node,
+ allow_visited_style);
+}
+
} // namespace CSSShorthand
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/properties/shorthands/padding_inline_custom.cc b/chromium/third_party/blink/renderer/core/css/properties/shorthands/padding_inline_custom.cc
index 79c0a3b0ef1..73c747b6a4d 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/shorthands/padding_inline_custom.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/shorthands/padding_inline_custom.cc
@@ -5,6 +5,8 @@
#include "third_party/blink/renderer/core/css/properties/shorthands/padding_inline.h"
#include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h"
+#include "third_party/blink/renderer/core/css/properties/computed_style_utils.h"
+#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/core/style_property_shorthand.h"
namespace blink {
@@ -20,5 +22,16 @@ bool PaddingInline::ParseShorthand(
paddingInlineShorthand(), important, context, range, properties);
}
+const CSSValue* PaddingInline::CSSValueFromComputedStyleInternal(
+ const ComputedStyle& style,
+ const SVGComputedStyle&,
+ const LayoutObject* layout_object,
+ Node* styled_node,
+ bool allow_visited_style) const {
+ return ComputedStyleUtils::ValuesForInlineBlockShorthand(
+ paddingInlineShorthand(), style, layout_object, styled_node,
+ allow_visited_style);
+}
+
} // namespace CSSShorthand
} // namespace blink
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 9e7fe70b1a6..9c9d1f40d26 100644
--- a/chromium/third_party/blink/renderer/core/css/property_registration.cc
+++ b/chromium/third_party/blink/renderer/core/css/property_registration.cc
@@ -22,6 +22,16 @@
namespace blink {
+PropertyRegistration* PropertyRegistration::Create(
+ const AtomicString& name,
+ const CSSSyntaxDescriptor& syntax,
+ bool inherits,
+ const CSSValue* initial,
+ scoped_refptr<CSSVariableData> initial_variable_data) {
+ return new PropertyRegistration(name, syntax, inherits, initial,
+ initial_variable_data);
+}
+
PropertyRegistration::PropertyRegistration(
const AtomicString& name,
const CSSSyntaxDescriptor& syntax,
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 a6d14390565..fb29166efdb 100644
--- a/chromium/third_party/blink/renderer/core/css/property_registration.h
+++ b/chromium/third_party/blink/renderer/core/css/property_registration.h
@@ -29,6 +29,13 @@ class CORE_EXPORT PropertyRegistration
const PropertyDescriptor&,
ExceptionState&);
+ static PropertyRegistration* Create(
+ const AtomicString& name,
+ const CSSSyntaxDescriptor&,
+ bool inherits,
+ const CSSValue* initial,
+ scoped_refptr<CSSVariableData> initial_variable_data);
+
const CSSSyntaxDescriptor& Syntax() const { return syntax_; }
bool Inherits() const { return inherits_; }
const CSSValue* Initial() const { return initial_; }
diff --git a/chromium/third_party/blink/renderer/core/css/property_registry.cc b/chromium/third_party/blink/renderer/core/css/property_registry.cc
index 30da6b75c82..5f7198780cf 100644
--- a/chromium/third_party/blink/renderer/core/css/property_registry.cc
+++ b/chromium/third_party/blink/renderer/core/css/property_registry.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "third_party/blink/renderer/core/css/property_registry.h"
+#include "third_party/blink/renderer/core/css/css_custom_property_declaration.h"
namespace blink {
@@ -17,4 +18,35 @@ const PropertyRegistration* PropertyRegistry::Registration(
return registrations_.at(name);
}
+const CSSValue* PropertyRegistry::ParseIfRegistered(
+ const Document& document,
+ const AtomicString& property_name,
+ const CSSValue* value) {
+ if (!value)
+ return nullptr;
+
+ const PropertyRegistry* registry = document.GetPropertyRegistry();
+
+ if (!registry)
+ return value;
+
+ const PropertyRegistration* registration =
+ registry->Registration(property_name);
+
+ if (!registration)
+ return value;
+ if (!value->IsCustomPropertyDeclaration())
+ return value;
+
+ CSSVariableData* tokens = ToCSSCustomPropertyDeclaration(value)->Value();
+
+ if (!tokens || tokens->NeedsVariableResolution())
+ return value;
+
+ const CSSValue* parsed_value = tokens->ParseForSyntax(
+ registration->Syntax(), document.GetSecureContextMode());
+
+ return parsed_value ? parsed_value : value;
+}
+
} // namespace blink
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 55649f30d1f..4b76a74307d 100644
--- a/chromium/third_party/blink/renderer/core/css/property_registry.h
+++ b/chromium/third_party/blink/renderer/core/css/property_registry.h
@@ -11,7 +11,7 @@
namespace blink {
-class PropertyRegistry : public GarbageCollected<PropertyRegistry> {
+class CORE_EXPORT PropertyRegistry : public GarbageCollected<PropertyRegistry> {
public:
static PropertyRegistry* Create() { return new PropertyRegistry(); }
@@ -21,6 +21,15 @@ class PropertyRegistry : public GarbageCollected<PropertyRegistry> {
void Trace(blink::Visitor* visitor) { visitor->Trace(registrations_); }
+ // Parse the incoming value and return the parsed result, if:
+ // 1. A registration with the specified name exists, and
+ // 2. The incoming value is a CSSCustomPropertyDeclaration, has no
+ // unresolved var-references and matches the registered syntax.
+ // Otherwise the incoming value is returned.
+ static const CSSValue* ParseIfRegistered(const Document& document,
+ const AtomicString& property_name,
+ const CSSValue*);
+
private:
HeapHashMap<AtomicString, Member<PropertyRegistration>> registrations_;
};
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 b9cb5ae8a62..9a54edd06e8 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
@@ -387,14 +387,16 @@ void CSSVariableResolver::ResolveVariableDefinitions() {
return;
int variable_count = 0;
- if (inherited_variables_) {
+ if (inherited_variables_ && inherited_variables_->NeedsResolution()) {
for (auto& variable : inherited_variables_->data_)
ValueForCustomProperty(variable.key);
+ inherited_variables_->ClearNeedsResolution();
variable_count += inherited_variables_->data_.size();
}
- if (non_inherited_variables_) {
+ if (non_inherited_variables_ && non_inherited_variables_->NeedsResolution()) {
for (auto& variable : non_inherited_variables_->data_)
ValueForCustomProperty(variable.key);
+ non_inherited_variables_->ClearNeedsResolution();
variable_count += non_inherited_variables_->data_.size();
}
INCREMENT_STYLE_STATS_COUNTER(state_.GetDocument().GetStyleEngine(),
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 e5a574cc59c..1155aca319f 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
@@ -29,7 +29,7 @@ class StyleInheritedVariables;
class StyleNonInheritedVariables;
class StyleResolverState;
-class CSSVariableResolver {
+class CORE_EXPORT CSSVariableResolver {
STACK_ALLOCATED();
public:
@@ -52,6 +52,7 @@ class CSSVariableResolver {
struct Options {
STACK_ALLOCATED();
+ public:
// Treat any references to animation-tainted custom properties as invalid.
//
// Custom properties used in @keyframe rules become 'animation-tainted'
@@ -83,6 +84,7 @@ class CSSVariableResolver {
struct Result {
STACK_ALLOCATED();
+ public:
Vector<CSSParserToken> tokens;
Vector<String> backing_strings;
bool is_animation_tainted = false;
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 6179efcdc16..64ef8988720 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
@@ -2,7 +2,18 @@
// Use 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/css_variable_resolver.h"
+#include "third_party/blink/renderer/core/css/css_custom_property_declaration.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"
+#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/properties/css_property.h"
+#include "third_party/blink/renderer/core/css/properties/longhand.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/resolver/style_resolver_state.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/html/html_element.h"
@@ -48,6 +59,19 @@ class CSSVariableResolverTest : public PageTestBase {
"</div>");
GetDocument().View()->UpdateAllLifecyclePhases();
}
+
+ const CSSCustomPropertyDeclaration* CreateCustomProperty(
+ const String& value) {
+ return CreateCustomProperty("--unused", value);
+ }
+
+ const CSSCustomPropertyDeclaration* CreateCustomProperty(
+ const AtomicString& name,
+ const String& value) {
+ const auto tokens = CSSTokenizer(value).TokenizeToEOF();
+ return CSSVariableParser::ParseDeclarationValue(
+ name, tokens, false, *CSSParserContext::Create(GetDocument()));
+ }
};
TEST_F(CSSVariableResolverTest, ParseEnvVariable_Missing_NestedVar) {
@@ -116,4 +140,141 @@ TEST_F(CSSVariableResolverTest, ParseEnvVariable_WhenNested_WillFallback) {
GetCSSPropertyBackgroundColor()));
}
+TEST_F(CSSVariableResolverTest, NoResolutionWithoutVar) {
+ scoped_refptr<StyleInheritedVariables> inherited_variables =
+ StyleInheritedVariables::Create();
+ std::unique_ptr<StyleNonInheritedVariables> non_inherited_variables =
+ StyleNonInheritedVariables::Create();
+
+ EXPECT_FALSE(inherited_variables->NeedsResolution());
+ EXPECT_FALSE(non_inherited_variables->NeedsResolution());
+
+ const auto* prop = CreateCustomProperty("#fefefe");
+
+ inherited_variables->SetVariable("--prop", prop->Value());
+ non_inherited_variables->SetVariable("--prop", prop->Value());
+
+ EXPECT_FALSE(inherited_variables->NeedsResolution());
+ EXPECT_FALSE(non_inherited_variables->NeedsResolution());
+}
+
+TEST_F(CSSVariableResolverTest, VarNeedsResolution) {
+ scoped_refptr<StyleInheritedVariables> inherited_variables =
+ StyleInheritedVariables::Create();
+ std::unique_ptr<StyleNonInheritedVariables> non_inherited_variables =
+ StyleNonInheritedVariables::Create();
+
+ EXPECT_FALSE(inherited_variables->NeedsResolution());
+ EXPECT_FALSE(non_inherited_variables->NeedsResolution());
+
+ const auto* prop1 = CreateCustomProperty("var(--prop2)");
+ const auto* prop2 = CreateCustomProperty("#fefefe");
+
+ inherited_variables->SetVariable("--prop1", prop1->Value());
+ non_inherited_variables->SetVariable("--prop1", prop1->Value());
+
+ EXPECT_TRUE(inherited_variables->NeedsResolution());
+ EXPECT_TRUE(non_inherited_variables->NeedsResolution());
+
+ // While NeedsResolution() == true, add some properties without
+ // var()-references.
+ inherited_variables->SetVariable("--prop2", prop2->Value());
+ non_inherited_variables->SetVariable("--prop2", prop2->Value());
+
+ // We should still need resolution even after adding properties that don't
+ // have var-references.
+ EXPECT_TRUE(inherited_variables->NeedsResolution());
+ EXPECT_TRUE(non_inherited_variables->NeedsResolution());
+
+ inherited_variables->ClearNeedsResolution();
+ non_inherited_variables->ClearNeedsResolution();
+
+ EXPECT_FALSE(inherited_variables->NeedsResolution());
+ EXPECT_FALSE(non_inherited_variables->NeedsResolution());
+}
+
+TEST_F(CSSVariableResolverTest, UrlNeedsResolution) {
+ scoped_refptr<StyleInheritedVariables> inherited_variables =
+ StyleInheritedVariables::Create();
+ std::unique_ptr<StyleNonInheritedVariables> non_inherited_variables =
+ StyleNonInheritedVariables::Create();
+
+ EXPECT_FALSE(inherited_variables->NeedsResolution());
+ EXPECT_FALSE(non_inherited_variables->NeedsResolution());
+
+ const auto* prop = CreateCustomProperty("url(a)");
+
+ inherited_variables->SetVariable("--prop", prop->Value());
+ non_inherited_variables->SetVariable("--prop", prop->Value());
+
+ EXPECT_TRUE(inherited_variables->NeedsResolution());
+ EXPECT_TRUE(non_inherited_variables->NeedsResolution());
+}
+
+TEST_F(CSSVariableResolverTest, CopiedVariablesRetainNeedsResolution) {
+ scoped_refptr<StyleInheritedVariables> inherited_variables =
+ StyleInheritedVariables::Create();
+ std::unique_ptr<StyleNonInheritedVariables> non_inherited_variables =
+ StyleNonInheritedVariables::Create();
+
+ const auto* prop = CreateCustomProperty("var(--x)");
+
+ inherited_variables->SetVariable("--prop", prop->Value());
+ non_inherited_variables->SetVariable("--prop", prop->Value());
+
+ EXPECT_TRUE(inherited_variables->NeedsResolution());
+ EXPECT_TRUE(non_inherited_variables->NeedsResolution());
+ EXPECT_TRUE(inherited_variables->Copy()->NeedsResolution());
+ EXPECT_TRUE(non_inherited_variables->Clone()->NeedsResolution());
+
+ inherited_variables->ClearNeedsResolution();
+ non_inherited_variables->ClearNeedsResolution();
+
+ EXPECT_FALSE(inherited_variables->NeedsResolution());
+ EXPECT_FALSE(non_inherited_variables->NeedsResolution());
+ EXPECT_FALSE(inherited_variables->Copy()->NeedsResolution());
+ EXPECT_FALSE(non_inherited_variables->Clone()->NeedsResolution());
+}
+
+TEST_F(CSSVariableResolverTest, NeedsResolutionClearedByResolver) {
+ const ComputedStyle* initial = &ComputedStyle::InitialStyle();
+ StyleResolverState state(GetDocument(), nullptr, initial, initial);
+
+ scoped_refptr<ComputedStyle> style = ComputedStyle::Create();
+ style->InheritFrom(*initial);
+ state.SetStyle(std::move(style));
+
+ const auto* prop1 = CreateCustomProperty("--prop1", "var(--prop2)");
+ const auto* prop2 = CreateCustomProperty("--prop2", "#fefefe");
+ const auto* prop3 = CreateCustomProperty("--prop3", "var(--prop2)");
+
+ // Register prop3 to make it non-inherited.
+ CSSSyntaxDescriptor token_syntax("*");
+ String initial_value_str("foo");
+ const auto tokens = CSSTokenizer(initial_value_str).TokenizeToEOF();
+ const CSSParserContext* context = CSSParserContext::Create(GetDocument());
+ const CSSValue* initial_value =
+ token_syntax.Parse(CSSParserTokenRange(tokens), context, false);
+ ASSERT_TRUE(initial_value);
+ ASSERT_TRUE(initial_value->IsVariableReferenceValue());
+ PropertyRegistration* registration = PropertyRegistration::Create(
+ "--prop3", token_syntax, false, initial_value,
+ ToCSSVariableReferenceValue(*initial_value).VariableDataValue());
+ ASSERT_TRUE(GetDocument().GetPropertyRegistry());
+ GetDocument().GetPropertyRegistry()->RegisterProperty("--prop3",
+ *registration);
+
+ ToLonghand(GetCSSPropertyVariable()).ApplyValue(state, *prop1);
+ ToLonghand(GetCSSPropertyVariable()).ApplyValue(state, *prop2);
+ ToLonghand(GetCSSPropertyVariable()).ApplyValue(state, *prop3);
+
+ EXPECT_TRUE(state.Style()->InheritedVariables()->NeedsResolution());
+ EXPECT_TRUE(state.Style()->NonInheritedVariables()->NeedsResolution());
+
+ CSSVariableResolver(state).ResolveVariableDefinitions();
+
+ EXPECT_FALSE(state.Style()->InheritedVariables()->NeedsResolution());
+ EXPECT_FALSE(state.Style()->NonInheritedVariables()->NeedsResolution());
+}
+
} // namespace blink
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 cadb825a69c..8ff4e6140c7 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
@@ -28,7 +28,10 @@
#include "third_party/blink/renderer/core/css/css_uri_value.h"
#include "third_party/blink/renderer/core/css_property_names.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/tree_scope.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
+#include "third_party/blink/renderer/core/html/lazy_load_image_observer.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/core/style/content_data.h"
#include "third_party/blink/renderer/core/style/cursor_data.h"
@@ -47,9 +50,9 @@
namespace blink {
-ElementStyleResources::ElementStyleResources(Document& document,
+ElementStyleResources::ElementStyleResources(Element& element,
float device_scale_factor)
- : document_(&document), device_scale_factor_(device_scale_factor) {}
+ : element_(&element), device_scale_factor_(device_scale_factor) {}
StyleImage* ElementStyleResources::GetStyleImage(CSSPropertyID property,
const CSSValue& value) {
@@ -93,7 +96,7 @@ StyleImage* ElementStyleResources::CachedOrPendingFromValue(
pending_image_properties_.insert(property);
return StylePendingImage::Create(value);
}
- value.RestoreCachedResourceIfNeeded(*document_);
+ value.RestoreCachedResourceIfNeeded(element_->GetDocument());
return value.CachedImage();
}
@@ -101,7 +104,7 @@ SVGResource* ElementStyleResources::GetSVGResourceFromValue(
TreeScope& tree_scope,
const CSSURIValue& value,
AllowExternal allow_external) const {
- if (value.IsLocal(*document_)) {
+ if (value.IsLocal(element_->GetDocument())) {
SVGTreeScopeResources& tree_scope_resources =
tree_scope.EnsureSVGTreeScopedResources();
AtomicString decoded_fragment(
@@ -125,7 +128,7 @@ void ElementStyleResources::LoadPendingSVGResources(
ReferenceFilterOperation& reference_operation =
ToReferenceFilterOperation(*filter_operation);
if (SVGResource* resource = reference_operation.Resource())
- resource->Load(*document_);
+ resource->Load(element_->GetDocument());
}
}
@@ -142,11 +145,11 @@ static bool BackgroundLayerMayBeSprite(const FillLayer& background_layer) {
StyleImage* ElementStyleResources::LoadPendingImage(
ComputedStyle* style,
StylePendingImage* pending_image,
- FetchParameters::PlaceholderImageRequestType placeholder_image_request_type,
+ FetchParameters::ImageRequestOptimization image_request_optimization,
CrossOriginAttributeValue cross_origin) {
if (CSSImageValue* image_value = pending_image->CssImageValue()) {
- return image_value->CacheImage(*document_, placeholder_image_request_type,
- cross_origin);
+ return image_value->CacheImage(element_->GetDocument(),
+ image_request_optimization, cross_origin);
}
if (CSSPaintValue* paint_value = pending_image->CssPaintValue()) {
@@ -157,14 +160,14 @@ StyleImage* ElementStyleResources::LoadPendingImage(
if (CSSImageGeneratorValue* image_generator_value =
pending_image->CssImageGeneratorValue()) {
- image_generator_value->LoadSubimages(*document_);
+ image_generator_value->LoadSubimages(element_->GetDocument());
return StyleGeneratedImage::Create(*image_generator_value);
}
if (CSSImageSetValue* image_set_value = pending_image->CssImageSetValue()) {
- return image_set_value->CacheImage(*document_, device_scale_factor_,
- placeholder_image_request_type,
- cross_origin);
+ return image_set_value->CacheImage(
+ element_->GetDocument(), device_scale_factor_,
+ image_request_optimization, cross_origin);
}
NOTREACHED();
@@ -195,13 +198,28 @@ void ElementStyleResources::LoadPendingImages(ComputedStyle* style) {
case CSSPropertyBackgroundImage: {
for (FillLayer* background_layer = &style->AccessBackgroundLayers();
background_layer; background_layer = background_layer->Next()) {
- if (background_layer->GetImage() &&
- background_layer->GetImage()->IsPendingImage()) {
- background_layer->SetImage(LoadPendingImage(
- style, ToStylePendingImage(background_layer->GetImage()),
- BackgroundLayerMayBeSprite(*background_layer)
- ? FetchParameters::kDisallowPlaceholder
- : FetchParameters::kAllowPlaceholder));
+ StyleImage* background_image = background_layer->GetImage();
+ if (background_image && background_image->IsPendingImage()) {
+ FetchParameters::ImageRequestOptimization
+ image_request_optimization = FetchParameters::kNone;
+ if (!BackgroundLayerMayBeSprite(*background_layer)) {
+ if (element_->GetDocument()
+ .GetFrame()
+ ->IsLazyLoadingImageAllowed()) {
+ background_image->SetIsLazyloadPossiblyDeferred(true);
+ image_request_optimization = FetchParameters::kDeferImageLoad;
+ } else {
+ image_request_optimization = FetchParameters::kAllowPlaceholder;
+ }
+ }
+ StyleImage* new_image =
+ LoadPendingImage(style, ToStylePendingImage(background_image),
+ image_request_optimization);
+ if (new_image && new_image->IsImageResource() &&
+ ToStyleFetchedImage(new_image)->IsLazyloadPossiblyDeferred()) {
+ LazyLoadImageObserver::StartMonitoring(element_);
+ }
+ background_layer->SetImage(new_image);
}
}
break;
@@ -229,9 +247,8 @@ void ElementStyleResources::LoadPendingImages(ComputedStyle* style) {
if (StyleImage* image = current_cursor.GetImage()) {
if (image->IsPendingImage()) {
// cursor images shouldn't be replaced with placeholders
- current_cursor.SetImage(
- LoadPendingImage(style, ToStylePendingImage(image),
- FetchParameters::kDisallowPlaceholder));
+ current_cursor.SetImage(LoadPendingImage(
+ style, ToStylePendingImage(image), FetchParameters::kNone));
}
}
}
@@ -244,7 +261,7 @@ void ElementStyleResources::LoadPendingImages(ComputedStyle* style) {
// List style images shouldn't be replaced with placeholders
style->SetListStyleImage(LoadPendingImage(
style, ToStylePendingImage(style->ListStyleImage()),
- FetchParameters::kDisallowPlaceholder));
+ FetchParameters::kNone));
}
break;
}
@@ -254,7 +271,7 @@ void ElementStyleResources::LoadPendingImages(ComputedStyle* style) {
// Border images shouldn't be replaced with placeholders
style->SetBorderImageSource(LoadPendingImage(
style, ToStylePendingImage(style->BorderImageSource()),
- FetchParameters::kDisallowPlaceholder));
+ FetchParameters::kNone));
}
break;
}
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 629c923f2f3..08ebe761f06 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
@@ -42,7 +42,7 @@ class CSSImageValue;
class CSSURIValue;
class CSSValue;
class ComputedStyle;
-class Document;
+class Element;
class SVGResource;
class StyleImage;
class StylePendingImage;
@@ -54,7 +54,7 @@ class ElementStyleResources {
STACK_ALLOCATED();
public:
- ElementStyleResources(Document&, float device_scale_factor);
+ ElementStyleResources(Element&, float device_scale_factor);
StyleImage* GetStyleImage(CSSPropertyID, const CSSValue&);
StyleImage* CachedOrPendingFromValue(CSSPropertyID, const CSSImageValue&);
@@ -78,10 +78,10 @@ class ElementStyleResources {
StyleImage* LoadPendingImage(
ComputedStyle*,
StylePendingImage*,
- FetchParameters::PlaceholderImageRequestType,
+ FetchParameters::ImageRequestOptimization,
CrossOriginAttributeValue = kCrossOriginAttributeNotSet);
- Member<Document> document_;
+ Member<Element> element_;
HashSet<CSSPropertyID> pending_image_properties_;
float device_scale_factor_;
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 feb1b80c2d2..dac42173c4e 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
@@ -344,7 +344,7 @@ void FontBuilder::UpdateAdjustedSize(FontDescription& font_description,
font_description, style.EffectiveZoom(), adjusted_size);
adjusted_size = TextAutosizer::ComputeAutosizedFontSize(
- adjusted_size, style.TextAutosizingMultiplier());
+ adjusted_size, style.TextAutosizingMultiplier(), style.EffectiveZoom());
font_description.SetAdjustedSize(adjusted_size);
}
@@ -354,7 +354,7 @@ void FontBuilder::UpdateComputedSize(FontDescription& font_description,
GetComputedSizeFromSpecifiedSize(font_description, style.EffectiveZoom(),
font_description.SpecifiedSize());
computed_size = TextAutosizer::ComputeAutosizedFontSize(
- computed_size, style.TextAutosizingMultiplier());
+ computed_size, style.TextAutosizingMultiplier(), style.EffectiveZoom());
font_description.SetComputedSize(computed_size);
}
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 288b55a4519..d2c212220a6 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
@@ -216,7 +216,7 @@ void ScopedStyleResolver::KeyframesRulesAdded(const TreeScope& tree_scope) {
void ScopedStyleResolver::CollectMatchingAuthorRules(
ElementRuleCollector& collector,
- CascadeOrder cascade_order) {
+ ShadowV0CascadeOrder cascade_order) {
size_t sheet_index = 0;
for (auto sheet : author_style_sheets_) {
if (!RuntimeEnabledFeatures::ConstructableStylesheetsEnabled())
@@ -229,7 +229,7 @@ void ScopedStyleResolver::CollectMatchingAuthorRules(
void ScopedStyleResolver::CollectMatchingShadowHostRules(
ElementRuleCollector& collector,
- CascadeOrder cascade_order) {
+ ShadowV0CascadeOrder cascade_order) {
size_t sheet_index = 0;
for (auto sheet : author_style_sheets_) {
if (!RuntimeEnabledFeatures::ConstructableStylesheetsEnabled())
@@ -242,7 +242,7 @@ void ScopedStyleResolver::CollectMatchingShadowHostRules(
void ScopedStyleResolver::CollectMatchingSlottedRules(
ElementRuleCollector& collector,
- CascadeOrder cascade_order) {
+ ShadowV0CascadeOrder cascade_order) {
if (!slotted_rule_set_)
return;
@@ -255,7 +255,7 @@ void ScopedStyleResolver::CollectMatchingSlottedRules(
void ScopedStyleResolver::CollectMatchingTreeBoundaryCrossingRules(
ElementRuleCollector& collector,
- CascadeOrder cascade_order) {
+ ShadowV0CascadeOrder cascade_order) {
if (!tree_boundary_crossing_rule_set_)
return;
@@ -269,7 +269,7 @@ void ScopedStyleResolver::CollectMatchingTreeBoundaryCrossingRules(
void ScopedStyleResolver::CollectMatchingPartPseudoRules(
ElementRuleCollector& collector,
PartNames& part_names,
- CascadeOrder cascade_order) {
+ ShadowV0CascadeOrder cascade_order) {
if (!RuntimeEnabledFeatures::CSSPartPseudoElementEnabled())
return;
size_t sheet_index = 0;
@@ -385,28 +385,6 @@ void ScopedStyleResolver::AddSlottedRules(const RuleSet& author_rules,
RuleSubSet::Create(parent_style_sheet, sheet_index, slotted_rule_set));
}
-bool ScopedStyleResolver::HaveSameStyles(const ScopedStyleResolver* first,
- const ScopedStyleResolver* second) {
- // This method will return true if the two resolvers are either both empty, or
- // if they contain the same active stylesheets by sharing the same
- // StyleSheetContents. It is used to check if we can share ComputedStyle
- // between two shadow hosts. This typically works when we have multiple
- // instantiations of the same web component where the style elements are in
- // the same order and contain the exact same source string in which case we
- // will get a cache hit for sharing StyleSheetContents.
-
- size_t first_count = first ? first->author_style_sheets_.size() : 0;
- size_t second_count = second ? second->author_style_sheets_.size() : 0;
- if (first_count != second_count)
- return false;
- while (first_count--) {
- if (first->author_style_sheets_[first_count]->Contents() !=
- second->author_style_sheets_[first_count]->Contents())
- return false;
- }
- return true;
-}
-
void ScopedStyleResolver::RuleSubSet::Trace(blink::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 b426d4932f9..acda21dc2e5 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
@@ -63,17 +63,19 @@ class ScopedStyleResolver final
void AppendActiveStyleSheets(unsigned index, const ActiveStyleSheetVector&);
void CollectMatchingAuthorRules(ElementRuleCollector&,
- CascadeOrder = kIgnoreCascadeOrder);
- void CollectMatchingShadowHostRules(ElementRuleCollector&,
- CascadeOrder = kIgnoreCascadeOrder);
+ ShadowV0CascadeOrder = kIgnoreCascadeOrder);
+ void CollectMatchingShadowHostRules(
+ ElementRuleCollector&,
+ ShadowV0CascadeOrder = kIgnoreCascadeOrder);
void CollectMatchingSlottedRules(ElementRuleCollector&,
- CascadeOrder = kIgnoreCascadeOrder);
+ ShadowV0CascadeOrder = kIgnoreCascadeOrder);
void CollectMatchingTreeBoundaryCrossingRules(
ElementRuleCollector&,
- CascadeOrder = kIgnoreCascadeOrder);
- void CollectMatchingPartPseudoRules(ElementRuleCollector&,
- PartNames& part_names,
- CascadeOrder = kIgnoreCascadeOrder);
+ ShadowV0CascadeOrder = kIgnoreCascadeOrder);
+ void CollectMatchingPartPseudoRules(
+ ElementRuleCollector&,
+ PartNames& part_names,
+ ShadowV0CascadeOrder = kIgnoreCascadeOrder);
void MatchPageRules(PageRuleCollector&);
void CollectFeaturesTo(RuleFeatureSet&,
HeapHashSet<Member<const StyleSheetContents>>&
@@ -87,8 +89,6 @@ class ScopedStyleResolver final
void SetNeedsAppendAllSheets() { needs_append_all_sheets_ = true; }
static void KeyframesRulesAdded(const TreeScope&);
static ContainerNode& InvalidationRootForTreeScope(const TreeScope&);
- CORE_EXPORT static bool HaveSameStyles(const ScopedStyleResolver*,
- const ScopedStyleResolver*);
void V0ShadowAddedOnV1Document();
void Trace(blink::Visitor*);
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/scoped_style_resolver_test.cc b/chromium/third_party/blink/renderer/core/css/resolver/scoped_style_resolver_test.cc
deleted file mode 100644
index c98d5ef1895..00000000000
--- a/chromium/third_party/blink/renderer/core/css/resolver/scoped_style_resolver_test.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/css/resolver/scoped_style_resolver.h"
-
-#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/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"
-
-namespace blink {
-
-class ScopedStyleResolverTest : public PageTestBase {
- protected:
- StyleEngine& GetStyleEngine() { return GetDocument().GetStyleEngine(); }
-};
-
-TEST_F(ScopedStyleResolverTest, HasSameStylesNullNull) {
- EXPECT_TRUE(ScopedStyleResolver::HaveSameStyles(nullptr, nullptr));
-}
-
-TEST_F(ScopedStyleResolverTest, HasSameStylesNullEmpty) {
- ScopedStyleResolver& resolver = GetDocument().EnsureScopedStyleResolver();
- EXPECT_TRUE(ScopedStyleResolver::HaveSameStyles(nullptr, &resolver));
- EXPECT_TRUE(ScopedStyleResolver::HaveSameStyles(&resolver, nullptr));
-}
-
-TEST_F(ScopedStyleResolverTest, HasSameStylesEmptyEmpty) {
- ScopedStyleResolver& resolver = GetDocument().EnsureScopedStyleResolver();
- EXPECT_TRUE(ScopedStyleResolver::HaveSameStyles(&resolver, &resolver));
-}
-
-TEST_F(ScopedStyleResolverTest, HasSameStylesNonEmpty) {
- GetDocument().body()->SetInnerHTMLFromString(
- "<div id=host1></div><div id=host2></div>");
- Element* host1 = GetDocument().getElementById("host1");
- Element* host2 = GetDocument().getElementById("host2");
- ASSERT_TRUE(host1);
- ASSERT_TRUE(host2);
- ShadowRoot& root1 = host1->AttachShadowRootInternal(ShadowRootType::kOpen);
- ShadowRoot& root2 = host2->AttachShadowRootInternal(ShadowRootType::kOpen);
- root1.SetInnerHTMLFromString("<style>::slotted(#dummy){color:pink}</style>");
- root2.SetInnerHTMLFromString("<style>::slotted(#dummy){color:pink}</style>");
- GetDocument().View()->UpdateAllLifecyclePhases();
- EXPECT_TRUE(ScopedStyleResolver::HaveSameStyles(
- &root1.EnsureScopedStyleResolver(), &root2.EnsureScopedStyleResolver()));
-}
-
-TEST_F(ScopedStyleResolverTest, HasSameStylesDifferentSheetCount) {
- GetDocument().body()->SetInnerHTMLFromString(
- "<div id=host1></div><div id=host2></div>");
- Element* host1 = GetDocument().getElementById("host1");
- Element* host2 = GetDocument().getElementById("host2");
- ASSERT_TRUE(host1);
- ASSERT_TRUE(host2);
- ShadowRoot& root1 = host1->AttachShadowRootInternal(ShadowRootType::kOpen);
- ShadowRoot& root2 = host2->AttachShadowRootInternal(ShadowRootType::kOpen);
- root1.SetInnerHTMLFromString(
- "<style>::slotted(#dummy){color:pink}</style><style>div{}</style>");
- root2.SetInnerHTMLFromString("<style>::slotted(#dummy){color:pink}</style>");
- GetDocument().View()->UpdateAllLifecyclePhases();
- EXPECT_FALSE(ScopedStyleResolver::HaveSameStyles(
- &root1.EnsureScopedStyleResolver(), &root2.EnsureScopedStyleResolver()));
-}
-
-TEST_F(ScopedStyleResolverTest, HasSameStylesCacheMiss) {
- GetDocument().body()->SetInnerHTMLFromString(
- "<div id=host1></div><div id=host2></div>");
- Element* host1 = GetDocument().getElementById("host1");
- Element* host2 = GetDocument().getElementById("host2");
- ASSERT_TRUE(host1);
- ASSERT_TRUE(host2);
- ShadowRoot& root1 = host1->AttachShadowRootInternal(ShadowRootType::kOpen);
- ShadowRoot& root2 = host2->AttachShadowRootInternal(ShadowRootType::kOpen);
- // Style equality is detected when StyleSheetContents is shared. That is only
- // the case when the source text is the same. The comparison will fail when
- // adding an extra space to one of the sheets.
- root1.SetInnerHTMLFromString("<style>::slotted(#dummy){color:pink}</style>");
- root2.SetInnerHTMLFromString("<style>::slotted(#dummy){ color:pink}</style>");
- GetDocument().View()->UpdateAllLifecyclePhases();
- EXPECT_FALSE(ScopedStyleResolver::HaveSameStyles(
- &root1.EnsureScopedStyleResolver(), &root2.EnsureScopedStyleResolver()));
-}
-
-} // namespace blink
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 21d9eeac7e9..a3289f9994a 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
@@ -88,6 +88,63 @@ bool IsImageOrVideoElement(const Element* element) {
return true;
return false;
}
+
+bool ShouldForceLegacyLayout(const ComputedStyle& style,
+ const ComputedStyle& layout_parent_style,
+ const Element& element) {
+ // Form controls are not supported yet.
+ if (element.ShouldForceLegacyLayout())
+ return true;
+
+ // When the actual parent (to inherit style from) doesn't have a layout box
+ // (display:contents), it may not have been switched over to forcing legacy
+ // layout, even if it's inside a subtree that should use legacy. Check with
+ // the layout parent as well, so that we don't risk switching back to LayoutNG
+ // when we shouldn't.
+ if (layout_parent_style.ForceLegacyLayout())
+ return true;
+
+ const Document& document = element.GetDocument();
+
+ // TODO(layout-dev): Once LayoutNG handles inline content editable, we
+ // should get rid of following code fragment.
+ if (!RuntimeEnabledFeatures::EditingNGEnabled()) {
+ if (style.UserModify() != EUserModify::kReadOnly || document.InDesignMode())
+ return true;
+ }
+
+ if (style.Display() == EDisplay::kWebkitBox ||
+ style.Display() == EDisplay::kWebkitInlineBox)
+ return true;
+
+ if (!RuntimeEnabledFeatures::LayoutNGBlockFragmentationEnabled()) {
+ // Disable NG for the entire subtree if we're establishing a block
+ // fragmentation context.
+ if (style.SpecifiesColumns() ||
+ (style.IsOverflowPaged() &&
+ &element != document.ViewportDefiningElement()))
+ return true;
+ if (document.Printing()) {
+ // This needs to be discovered on the root element.
+ DCHECK_EQ(element, document.documentElement());
+ return true;
+ }
+ }
+
+ // The custom container is laid out by the legacy engine. Its children may
+ // not establish new formatting contexts, so we need to protect against
+ // re-entering LayoutNG there.
+ if (style.Display() == EDisplay::kLayoutCustom ||
+ style.Display() == EDisplay::kInlineLayoutCustom)
+ return true;
+
+ // 'text-combine-upright' property is not supported yet.
+ if (style.HasTextCombine() && !style.IsHorizontalWritingMode())
+ return true;
+
+ return false;
+}
+
} // namespace
static EDisplay EquivalentBlockDisplay(EDisplay display) {
@@ -506,11 +563,14 @@ void StyleAdjuster::AdjustComputedStyle(StyleResolverState& state,
const ComputedStyle& parent_style = *state.ParentStyle();
const ComputedStyle& layout_parent_style = *state.LayoutParentStyle();
- if (element &&
- (style.Display() != EDisplay::kNone ||
- element->LayoutObjectIsNeeded(style)) &&
- element->IsHTMLElement()) {
- AdjustStyleForHTMLElement(style, ToHTMLElement(*element));
+ if (element && (style.Display() != EDisplay::kNone ||
+ element->LayoutObjectIsNeeded(style))) {
+ // TODO(rakina): Move this attribute check somewhere else.
+ if (RuntimeEnabledFeatures::InvisibleDOMEnabled() &&
+ !element->invisible().IsNull())
+ style.SetDisplay(EDisplay::kNone);
+ else if (element->IsHTMLElement())
+ AdjustStyleForHTMLElement(style, ToHTMLElement(*element));
}
if (style.Display() != EDisplay::kNone) {
bool is_document_element =
@@ -672,40 +732,9 @@ void StyleAdjuster::AdjustComputedStyle(StyleResolverState& state,
}
if (RuntimeEnabledFeatures::LayoutNGEnabled() && !style.ForceLegacyLayout() &&
- element) {
- const Document& document = element->GetDocument();
- if (element->ShouldForceLegacyLayout()) {
- // Form controls are not supported yet.
- style.SetForceLegacyLayout(true);
- } else if (style.UserModify() != EUserModify::kReadOnly ||
- document.InDesignMode() ||
- style.Display() == EDisplay::kWebkitBox ||
- style.Display() == EDisplay::kWebkitInlineBox) {
- // TODO(layout-dev): Once LayoutNG handles inline content editable, we
- // should get rid of following code fragment.
- style.SetForceLegacyLayout(true);
-
- } else if (!RuntimeEnabledFeatures::LayoutNGBlockFragmentationEnabled()) {
- // Disable NG for the entire subtree if we're establishing a block
- // fragmentation context.
- if (style.SpecifiesColumns() ||
- (style.IsOverflowPaged() &&
- element != document.ViewportDefiningElement())) {
- style.SetForceLegacyLayout(true);
- } else if (document.Printing()) {
- // This needs to be discovered on the root element.
- DCHECK_EQ(element, document.documentElement());
- style.SetForceLegacyLayout(true);
- }
- }
- if (!style.ForceLegacyLayout()) {
- // The custom container is laid out by the legacy engine. Its children may
- // not establish new formatting contexts, so we need to protect against
- // re-entering LayoutNG there.
- if (style.Display() == EDisplay::kLayoutCustom ||
- style.Display() == EDisplay::kInlineLayoutCustom)
- style.SetForceLegacyLayout(true);
- }
+ element &&
+ ShouldForceLegacyLayout(style, layout_parent_style, *element)) {
+ style.SetForceLegacyLayout(true);
}
// If intrinsically sized images or videos are disallowed by feature policy,
@@ -713,12 +742,20 @@ void StyleAdjuster::AdjustComputedStyle(StyleResolverState& state,
if (IsImageOrVideoElement(element)) {
if (RuntimeEnabledFeatures::ExperimentalProductivityFeaturesEnabled() &&
element->GetDocument().GetFrame() &&
- !element->GetDocument().GetFrame()->IsFeatureEnabled(
- mojom::FeaturePolicyFeature::kUnsizedMedia)) {
- if (!style.Width().IsSpecified())
- style.SetLogicalWidth(Length(LayoutReplaced::kDefaultWidth, kFixed));
- if (!style.Height().IsSpecified())
- style.SetLogicalHeight(Length(LayoutReplaced::kDefaultHeight, kFixed));
+ (!style.Width().IsSpecified() || !style.Height().IsSpecified())) {
+ // This check will trigger reporting, so only do it if either width or
+ // height is unspecified.
+ if (!element->GetDocument().GetFrame()->IsFeatureEnabled(
+ mojom::FeaturePolicyFeature::kUnsizedMedia,
+ ReportOptions::kReportOnFailure)) {
+ if (!style.Width().IsSpecified()) {
+ style.SetLogicalWidth(Length(LayoutReplaced::kDefaultWidth, kFixed));
+ }
+ if (!style.Height().IsSpecified()) {
+ style.SetLogicalHeight(
+ Length(LayoutReplaced::kDefaultHeight, kFixed));
+ }
+ }
}
}
}
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 2721c53f4eb..ee51cd11486 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
@@ -403,7 +403,7 @@ void StyleResolver::MatchAuthorRulesV0(const Element& element,
ElementRuleCollector& collector) {
collector.ClearMatchedRules();
- CascadeOrder cascade_order = 0;
+ ShadowV0CascadeOrder cascade_order = 0;
HeapVector<Member<ScopedStyleResolver>, 8> resolvers_in_shadow_tree;
CollectScopedResolversForHostedShadowTrees(element, resolvers_in_shadow_tree);
@@ -527,9 +527,11 @@ void StyleResolver::CollectTreeBoundaryCrossingRulesV0CascadeOrder(
return;
// When comparing rules declared in outer treescopes, outer's rules win.
- CascadeOrder outer_cascade_order = tree_boundary_crossing_scopes.size() * 2;
+ ShadowV0CascadeOrder outer_cascade_order =
+ tree_boundary_crossing_scopes.size() * 2;
// When comparing rules declared in inner treescopes, inner's rules win.
- CascadeOrder inner_cascade_order = tree_boundary_crossing_scopes.size();
+ ShadowV0CascadeOrder inner_cascade_order =
+ tree_boundary_crossing_scopes.size();
for (const auto& scoping_node : tree_boundary_crossing_scopes) {
// Skip rule collection for element when tree boundary crossing rules of
@@ -540,7 +542,7 @@ void StyleResolver::CollectTreeBoundaryCrossingRulesV0CascadeOrder(
if (!ShouldCheckScope(element, *scoping_node, is_inner_tree_scope))
continue;
- CascadeOrder cascade_order =
+ ShadowV0CascadeOrder cascade_order =
is_inner_tree_scope ? inner_cascade_order : outer_cascade_order;
scoping_node->GetTreeScope()
.GetScopedStyleResolver()
@@ -783,7 +785,7 @@ scoped_refptr<ComputedStyle> StyleResolver::StyleForElement(
// TODO(alancutter): Create compositor keyframe values directly instead of
// intermediate AnimatableValues.
-scoped_refptr<AnimatableValue> StyleResolver::CreateAnimatableValueSnapshot(
+AnimatableValue* StyleResolver::CreateAnimatableValueSnapshot(
Element& element,
const ComputedStyle& base_style,
const ComputedStyle* parent_style,
@@ -1713,7 +1715,7 @@ void StyleResolver::ApplyCustomProperties(StyleResolverState& state,
if (apply_animations == kIncludeAnimations) {
ApplyAnimatedCustomProperties(state);
}
- // TODO(leviw): stop recalculating every time
+
CSSVariableResolver(state).ResolveVariableDefinitions();
}
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 2d63cf39116..b3e6ff8432f 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
@@ -75,7 +75,7 @@ class CORE_EXPORT StyleResolver final
const ComputedStyle* layout_parent_style = nullptr,
RuleMatchingBehavior = kMatchAllRules);
- static scoped_refptr<AnimatableValue> CreateAnimatableValueSnapshot(
+ static AnimatableValue* CreateAnimatableValueSnapshot(
Element&,
const ComputedStyle& base_style,
const ComputedStyle* parent_style,
@@ -179,6 +179,8 @@ class CORE_EXPORT StyleResolver final
struct CacheSuccess {
STACK_ALLOCATED();
+
+ public:
bool is_inherited_cache_hit;
bool is_non_inherited_cache_hit;
unsigned cache_hash;
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 0e90884e6f2..27faa263a84 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
@@ -46,7 +46,7 @@ StyleResolverState::StyleResolverState(
apply_property_to_visited_link_style_(false),
has_dir_auto_attribute_(false),
font_builder_(&document),
- element_style_resources_(document, document.DevicePixelRatio()) {
+ element_style_resources_(*GetElement(), document.DevicePixelRatio()) {
DCHECK(!!parent_style_ == !!layout_parent_style_);
if (!parent_style_) {
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 ea861fe1579..2b913137c01 100644
--- a/chromium/third_party/blink/renderer/core/css/selector_checker.cc
+++ b/chromium/third_party/blink/renderer/core/css/selector_checker.cc
@@ -59,10 +59,10 @@
#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/scroll/scrollable_area.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
-#include "third_party/blink/renderer/platform/scroll/scrollable_area.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h"
namespace blink {
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 2a9b0121144..014dd143ebf 100644
--- a/chromium/third_party/blink/renderer/core/css/selector_checker.h
+++ b/chromium/third_party/blink/renderer/core/css/selector_checker.h
@@ -132,6 +132,8 @@ class SelectorChecker {
struct MatchResult {
STACK_ALLOCATED();
+
+ public:
MatchResult() : dynamic_pseudo(kPseudoIdNone), specificity(0) {}
PseudoId dynamic_pseudo;
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 a457e9fb3ea..a8ff0fa0fa8 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
@@ -30,6 +30,7 @@ const char kInlineCSSStyleMutated[] =
"Inline CSS style declaration was mutated";
const char kInspector[] = "Inspector";
const char kLanguage[] = "Language";
+const char kInvisibleChange[] = "InvisibleChange";
const char kLinkColorChange[] = "LinkColorChange";
const char kPlatformColorChange[] = "PlatformColorChange";
const char kPolicyViolation[] = "Feature Policy Violation";
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 3288796db13..06d03249ab5 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
@@ -30,6 +30,7 @@ extern const char kInheritedStyleChangeFromParentFrame[];
extern const char kInline[];
extern const char kInlineCSSStyleMutated[];
extern const char kInspector[];
+extern const char kInvisibleChange[];
extern const char kLanguage[];
extern const char kLinkColorChange[];
extern const char kPlatformColorChange[];
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 42c6d158a04..e3f0970c136 100644
--- a/chromium/third_party/blink/renderer/core/css/style_engine.cc
+++ b/chromium/third_party/blink/renderer/core/css/style_engine.cc
@@ -45,6 +45,7 @@
#include "third_party/blink/renderer/core/css/style_sheet_contents.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/layout_tree_builder_traversal.h"
#include "third_party/blink/renderer/core/dom/processing_instruction.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
#include "third_party/blink/renderer/core/frame/settings.h"
@@ -1406,8 +1407,10 @@ void StyleEngine::EnvironmentVariableChanged() {
void StyleEngine::MarkForWhitespaceReattachment() {
for (auto element : whitespace_reattach_set_) {
- if (!element->GetLayoutObject())
+ if (element->NeedsReattachLayoutTree() || !element->GetLayoutObject() ||
+ !LayoutTreeBuilderTraversal::FirstChild(*element)) {
continue;
+ }
element->SetChildNeedsReattachLayoutTree();
element->MarkAncestorsWithChildNeedsReattachLayoutTree();
}
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 53346fb3edf..f7cf4dd4b39 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
@@ -91,7 +91,7 @@ TEST_F(StyleEngineTest, AnalyzedInject) {
<style>
@font-face {
font-family: 'Cool Font';
- src: local(monospace);
+ src: url(dummy);
font-weight: bold;
}
:root {
@@ -249,11 +249,10 @@ TEST_F(StyleEngineTest, AnalyzedInject) {
font_face_parsed_sheet->ParseString(
"@font-face {"
" font-family: 'Cool Font';"
- " src: local(monospace);"
+ " src: url(dummy);"
" font-weight: bold;"
" font-style: italic;"
- "}"
- );
+ "}");
StyleSheetKey font_face_key("font_face");
GetStyleEngine().InjectSheet(font_face_key, font_face_parsed_sheet,
WebDocument::kUserOrigin);
@@ -278,11 +277,10 @@ TEST_F(StyleEngineTest, AnalyzedInject) {
style_element->SetInnerHTMLFromString(
"@font-face {"
" font-family: 'Cool Font';"
- " src: local(monospace);"
+ " src: url(dummy);"
" font-weight: normal;"
" font-style: italic;"
- "}"
- );
+ "}");
GetDocument().body()->AppendChild(style_element);
GetDocument().View()->UpdateAllLifecyclePhases();
@@ -1455,4 +1453,95 @@ TEST_F(StyleEngineTest, ShadowRootStyleRecalcCrash) {
GetDocument().View()->UpdateAllLifecyclePhases();
}
+TEST_F(StyleEngineTest, GetComputedStyleOutsideFlatTreeCrash) {
+ GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ <style>
+ body, div { display: contents }
+ div::before { display: contents; content: "" }
+ </style>
+ <div id=inner></div>
+ )HTML");
+
+ GetDocument().documentElement()->CreateV0ShadowRootForTesting();
+ GetDocument().View()->UpdateAllLifecyclePhases();
+ GetDocument().body()->EnsureComputedStyle();
+ GetDocument().getElementById("inner")->SetInlineStyleProperty(
+ CSSPropertyColor, "blue");
+ GetDocument().View()->UpdateAllLifecyclePhases();
+}
+
+TEST_F(StyleEngineTest, RejectSelectorForPseudoElement) {
+ GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ <style>
+ div::before { content: "" }
+ .not-in-filter div::before { color: red }
+ </style>
+ <div class='not-in-filter'></div>
+ )HTML");
+ GetDocument().View()->UpdateAllLifecyclePhases();
+
+ StyleEngine& engine = GetDocument().GetStyleEngine();
+ engine.SetStatsEnabled(true);
+
+ StyleResolverStats* stats = engine.Stats();
+ ASSERT_TRUE(stats);
+
+ Element* div = GetDocument().QuerySelector("div");
+ ASSERT_TRUE(div);
+ div->SetInlineStyleProperty(CSSPropertyColor, "green");
+
+ GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kInStyleRecalc);
+ GetDocument().documentElement()->RecalcStyle(kNoChange);
+
+ // Should fast reject ".not-in-filter div::before {}" for both the div and its
+ // ::before pseudo element.
+ EXPECT_EQ(2u, stats->rules_fast_rejected);
+}
+
+TEST_F(StyleEngineTest, MarkForWhitespaceReattachment) {
+ GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ <div id=d1><span></span></div>
+ <div id=d2><span></span><span></span></div>
+ <div id=d3><span></span><span></span></div>
+ )HTML");
+
+ Element* d1 = GetDocument().getElementById("d1");
+ Element* d2 = GetDocument().getElementById("d2");
+ Element* d3 = GetDocument().getElementById("d3");
+
+ GetDocument().View()->UpdateAllLifecyclePhases();
+
+ d1->firstChild()->remove();
+ EXPECT_TRUE(GetDocument().GetStyleEngine().NeedsWhitespaceReattachment(d1));
+ EXPECT_FALSE(GetDocument().ChildNeedsStyleInvalidation());
+ EXPECT_FALSE(GetDocument().ChildNeedsStyleRecalc());
+ EXPECT_FALSE(GetDocument().ChildNeedsReattachLayoutTree());
+
+ GetDocument().GetStyleEngine().MarkForWhitespaceReattachment();
+ EXPECT_FALSE(GetDocument().ChildNeedsReattachLayoutTree());
+
+ GetDocument().View()->UpdateAllLifecyclePhases();
+
+ d2->firstChild()->remove();
+ d2->firstChild()->remove();
+ EXPECT_TRUE(GetDocument().GetStyleEngine().NeedsWhitespaceReattachment(d2));
+ EXPECT_FALSE(GetDocument().ChildNeedsStyleInvalidation());
+ EXPECT_FALSE(GetDocument().ChildNeedsStyleRecalc());
+ EXPECT_FALSE(GetDocument().ChildNeedsReattachLayoutTree());
+
+ GetDocument().GetStyleEngine().MarkForWhitespaceReattachment();
+ EXPECT_FALSE(GetDocument().ChildNeedsReattachLayoutTree());
+
+ GetDocument().View()->UpdateAllLifecyclePhases();
+
+ d3->firstChild()->remove();
+ EXPECT_TRUE(GetDocument().GetStyleEngine().NeedsWhitespaceReattachment(d3));
+ EXPECT_FALSE(GetDocument().ChildNeedsStyleInvalidation());
+ EXPECT_FALSE(GetDocument().ChildNeedsStyleRecalc());
+ EXPECT_FALSE(GetDocument().ChildNeedsReattachLayoutTree());
+
+ GetDocument().GetStyleEngine().MarkForWhitespaceReattachment();
+ EXPECT_TRUE(GetDocument().ChildNeedsReattachLayoutTree());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/style_property_serializer.cc b/chromium/third_party/blink/renderer/core/css/style_property_serializer.cc
index 17cefa36905..2344a9fe91f 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
@@ -422,7 +422,8 @@ String StylePropertySerializer::SerializeShorthand(
case CSSPropertyBackground:
return GetLayeredShorthandValue(backgroundShorthand());
case CSSPropertyBorder:
- return BorderPropertyValue();
+ return BorderPropertyValue(borderWidthShorthand(), borderStyleShorthand(),
+ borderColorShorthand());
case CSSPropertyBorderImage:
return BorderImagePropertyValue();
case CSSPropertyBorderTop:
@@ -433,10 +434,30 @@ String StylePropertySerializer::SerializeShorthand(
return GetShorthandValue(borderBottomShorthand());
case CSSPropertyBorderLeft:
return GetShorthandValue(borderLeftShorthand());
+ case CSSPropertyBorderBlock:
+ return BorderPropertyValue(borderBlockWidthShorthand(),
+ borderBlockStyleShorthand(),
+ borderBlockColorShorthand());
+ case CSSPropertyBorderBlockColor:
+ return Get2Values(borderBlockColorShorthand());
+ case CSSPropertyBorderBlockStyle:
+ return Get2Values(borderBlockStyleShorthand());
+ case CSSPropertyBorderBlockWidth:
+ return Get2Values(borderBlockWidthShorthand());
case CSSPropertyBorderBlockStart:
return GetShorthandValue(borderBlockStartShorthand());
case CSSPropertyBorderBlockEnd:
return GetShorthandValue(borderBlockEndShorthand());
+ case CSSPropertyBorderInline:
+ return BorderPropertyValue(borderInlineWidthShorthand(),
+ borderInlineStyleShorthand(),
+ borderInlineColorShorthand());
+ case CSSPropertyBorderInlineColor:
+ return Get2Values(borderInlineColorShorthand());
+ case CSSPropertyBorderInlineStyle:
+ return Get2Values(borderInlineStyleShorthand());
+ case CSSPropertyBorderInlineWidth:
+ return Get2Values(borderInlineWidthShorthand());
case CSSPropertyBorderInlineStart:
return GetShorthandValue(borderInlineStartShorthand());
case CSSPropertyBorderInlineEnd:
@@ -465,6 +486,12 @@ String StylePropertySerializer::SerializeShorthand(
return GetShorthandValue(gridAreaShorthand(), " / ");
case CSSPropertyGap:
return GetShorthandValue(gapShorthand());
+ case CSSPropertyInset:
+ return Get4Values(insetShorthand());
+ case CSSPropertyInsetBlock:
+ return Get2Values(insetBlockShorthand());
+ case CSSPropertyInsetInline:
+ return Get2Values(insetInlineShorthand());
case CSSPropertyPlaceContent:
return Get2Values(placeContentShorthand());
case CSSPropertyPlaceItems:
@@ -477,6 +504,10 @@ String StylePropertySerializer::SerializeShorthand(
return FontVariantValue();
case CSSPropertyMargin:
return Get4Values(marginShorthand());
+ case CSSPropertyMarginBlock:
+ return Get2Values(marginBlockShorthand());
+ case CSSPropertyMarginInline:
+ return Get2Values(marginInlineShorthand());
case CSSPropertyOffset:
return OffsetValue();
case CSSPropertyWebkitMarginCollapse:
@@ -487,6 +518,10 @@ String StylePropertySerializer::SerializeShorthand(
return GetShorthandValue(overscrollBehaviorShorthand());
case CSSPropertyPadding:
return Get4Values(paddingShorthand());
+ case CSSPropertyPaddingBlock:
+ return Get2Values(paddingBlockShorthand());
+ case CSSPropertyPaddingInline:
+ return Get2Values(paddingInlineShorthand());
case CSSPropertyTextDecoration:
return GetShorthandValue(textDecorationShorthand());
case CSSPropertyTransition:
@@ -996,9 +1031,11 @@ String StylePropertySerializer::GetCommonValue(
return res;
}
-String StylePropertySerializer::BorderPropertyValue() const {
- const StylePropertyShorthand properties[3] = {
- borderWidthShorthand(), borderStyleShorthand(), borderColorShorthand()};
+String StylePropertySerializer::BorderPropertyValue(
+ const StylePropertyShorthand& width,
+ const StylePropertyShorthand& style,
+ const StylePropertyShorthand& color) const {
+ const StylePropertyShorthand properties[3] = {width, style, color};
StringBuilder result;
for (size_t i = 0; i < arraysize(properties); ++i) {
String value = GetCommonValue(properties[i]);
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 addd6aa900b..59329fd8b3f 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
@@ -44,7 +44,9 @@ class StylePropertySerializer {
private:
String GetCommonValue(const StylePropertyShorthand&) const;
- String BorderPropertyValue() const;
+ String BorderPropertyValue(const StylePropertyShorthand&,
+ const StylePropertyShorthand&,
+ const StylePropertyShorthand&) const;
String BorderImagePropertyValue() const;
String GetLayeredShorthandValue(const StylePropertyShorthand&) const;
String Get2Values(const StylePropertyShorthand&) const;
diff --git a/chromium/third_party/blink/renderer/core/css/themeWin.css b/chromium/third_party/blink/renderer/core/css/themeWin.css
index 2616d89e2a5..ed659eed4df 100644
--- a/chromium/third_party/blink/renderer/core/css/themeWin.css
+++ b/chromium/third_party/blink/renderer/core/css/themeWin.css
@@ -32,13 +32,12 @@
WebCore/css/html.css. So far we have used this file exclusively for
making our form elements match Firefox's. */
-input:not([type]),
-input[type="email" i],
-input[type="number" i],
-input[type="password" i],
-input[type="tel" i],
-input[type="url" i],
-input[type="text" i] {
+/*
+ * Update padding for all text-like types including unknown types.
+ * Non-text types have input[type="foo" i] with padding properties in
+ * html.css or themeInputMultipleFields.css.
+ */
+input {
padding:1px 0;
}
@@ -58,30 +57,25 @@ input[type="range" i] {
color: #c4c4c4;
}
-/* Not sure this is the right color. #EBEBE4 is what Firefox uses.
- FIXME: Figure out how to support legacy input rendering.
- FIXME: Add input[type="file" i] once we figure out our file inputs.
- FIXME: Add input[type="image" i] once we figure out our image inputs.
- FIXME: We probably do the wrong thing if you put an invalid input type.
- do we care?
-*/
+/* Not sure this is the right color. #EBEBE4 is what Firefox uses. */
textarea:disabled,
-input:not([type]):disabled,
-input[type="color" i]:disabled,
-input[type="date" i]:disabled,
-input[type="datetime" i]:disabled,
-input[type="datetime-local" i]:disabled,
-input[type="email" i]:disabled,
-input[type="month" i]:disabled,
-input[type="password" i]:disabled,
-input[type="number" i]:disabled,
-input[type="search" i]:disabled,
-input[type="tel" i]:disabled,
-input[type="text" i]:disabled,
-input[type="time" i]:disabled,
-input[type="url" i]:disabled,
-input[type="week" i]:disabled {
- background-color: #EBEBE4;
+input:disabled {
+ background-color: #EBEBE4;
+}
+
+/* Cancel the above rule set for some input types. */
+input[type="button" i]:disabled,
+input[type="reset" i]:disabled,
+input[type="submit" i]:disabled {
+ background-color: ButtonFace;
+}
+input[type="checkbox" i]:disabled,
+input[type="file" i]:disabled,
+input[type="hidden" i]:disabled,
+input[type="image" i]:disabled,
+input[type="radio" i]:disabled,
+input[type="range" i]:disabled {
+ background-color: initial;
}
input[type="search" i]::-webkit-search-cancel-button {
diff --git a/chromium/third_party/blink/renderer/core/dom/BUILD.gn b/chromium/third_party/blink/renderer/core/dom/BUILD.gn
index 740a785228d..fa23d84b2ef 100644
--- a/chromium/third_party/blink/renderer/core/dom/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/dom/BUILD.gn
@@ -140,8 +140,6 @@ blink_core_sources("dom") {
"first_letter_pseudo_element.h",
"flat_tree_traversal.cc",
"flat_tree_traversal.h",
- "flat_tree_traversal_ng.cc",
- "flat_tree_traversal_ng.h",
"frame_request_callback_collection.cc",
"frame_request_callback_collection.h",
"global_event_handlers.h",
@@ -153,6 +151,7 @@ blink_core_sources("dom") {
"id_target_observer_registry.h",
"idle_deadline.cc",
"idle_deadline.h",
+ "ignore_opens_during_unload_count_incrementer.h",
"increment_load_event_delay_count.cc",
"increment_load_event_delay_count.h",
"iterator.h",
diff --git a/chromium/third_party/blink/renderer/core/dom/README.md b/chromium/third_party/blink/renderer/core/dom/README.md
index 6a315e94658..a0430a7dac6 100644
--- a/chromium/third_party/blink/renderer/core/dom/README.md
+++ b/chromium/third_party/blink/renderer/core/dom/README.md
@@ -4,15 +4,15 @@
Author: hayato@chromium.org
-The `Source/core/dom` directory contains the implementation of [DOM].
+The `renderer/core/dom` directory contains the implementation of [DOM].
[dom]: https://dom.spec.whatwg.org/
[dom standard]: https://dom.spec.whatwg.org/
Basically, this directory should contain only a file which is related to [DOM
-Standard]. However, for historical reasons, `Source/core/dom` directory has been
-used as if it were _misc_ directory. As a result, unfortunately, this directory
-contains a lot of files which are not directly related to DOM.
+Standard]. However, for historical reasons, `renderer/core/dom` directory has
+been used as if it were _misc_ directory. As a result, unfortunately, this
+directory contains a lot of files which are not directly related to DOM.
Please don't add unrelated files to this directory any more. We are trying to
organize the files so that developers wouldn't get confused at seeing this
@@ -30,8 +30,8 @@ directory.
# Node and Node Tree
-In this README, we draw a tree in left-to-right direction. `A` is the root of
-the tree.
+In this README, we draw a tree in left-to-right direction in _ascii-art_
+notation. `A` is the root of the tree.
```text
A
@@ -62,6 +62,8 @@ That means:
child.
- Parent can't tell how many children it has in O(1).
+![next sibling and previous sibling](https://hayato.io/2017/dom/next-sibling.svg)
+
Further info:
- `Node`, `ContainerNode`
@@ -89,6 +91,10 @@ void foo(const Node& node) {
}
```
+Tree order is:
+
+![tree order](https://hayato.io/2017/dom/tree-order.svg)
+
However, traversing a tree in this way might be error-prone. Instead, you can
use `NodeTraversal` and `ElementTraversal`. They provides a C++11's range-based
for loops, such as:
@@ -110,10 +116,8 @@ for (Node& node : NodeTraversal::startsAt(root)) {
```
e.g. Given the root _A_, this traverses _A_, _B_, _C_, _D_, _E_, and _F_ in this
-order.
-
-There are several other useful range-based for loops for each purpose. The cost
-of using range-based for loops is zero because everything can be inlined.
+order.There are several other useful range-based for loops for each purpose. The
+cost of using range-based for loops is zero because everything can be inlined.
Further info:
@@ -133,6 +137,8 @@ host**, or just a **host** if the context is clear.
- The node tree of a shadow root’s host is sometimes referred to as the **light
tree**.
+![shadow tree](https://hayato.io/2017/dom/shadow-tree.svg)
+
For example, given the example node tree:
```text
@@ -208,8 +214,8 @@ and `ShadowRoot` implements `TreeScope`.
`TreeScope` maintains a lot of information about the underlying tree for
efficiency. For example, TreeScope has a _id-to-element_ mapping, as
-[`TreeOrderedMap`](./TreeOrderedMap.h), so that `querySelector('#foo')` can find
-an element whose id attribute is "foo" in O(1). In other words,
+[`TreeOrderedMap`](./tree_ordered_map.h), so that `querySelector('#foo')` can
+find an element whose id attribute is "foo" in O(1). In other words,
`root.querySelector('#foo')` can be slow if that is used in a node tree whose
root is not `TreeScope`.
@@ -276,14 +282,19 @@ document-fragment
Further Info:
-- [`TreeScope.h`](./TreeScope.h), [`TreeScope.cpp`](./TreeScope.cpp)
+- [`tree_scope.h`](./tree_scope.h), [`tree_scope.cc`](./tree_scope.cc)
- `Node#GetTreeScope()`, `Node#ContainingTreeScope()`, `Node#IsInTreeScope()`
# Composed Tree (a tree of node trees)
In the previous picture, you might think that more than one node trees, a
document tree and a shadow tree, were _connected_ to each other. That is _true_
-in some sense. The following is a more complex example:
+in some sense. We call this _super tree_ as _composed tree_, which is a _tree of
+trees_.
+
+![super tree](https://hayato.io/2017/dom/super-tree.svg)
+
+The following is a complex example:
```text
document
@@ -470,6 +481,8 @@ composed of multiple node trees, instead of a single node tree. That means We
have to _flatten_ the composed tree to the one node tree, called a _flat tree_,
from which a layout tree is constructed.
+![flat tree](https://hayato.io/2017/dom/flat-tree.svg)
+
For example, given the following composed tree,
```text
@@ -530,25 +543,311 @@ flat tree can be defined as:
- If _A_ is a shadow host, its shadow root's children
- Otherwise, _A_'s children
-# Distribution and slots
+# Slots and node assignments
-TODO(hayato): Explain.
+Please see this
+[nice article](https://developers.google.com/web/fundamentals/web-components/shadowdom)
+how `<slot>` elements work in general.
+
+> _Slots_ are placeholders inside your component that users can fill with their
+> own markup.
+
+Here, I'll show some examples.
+
+## Example 1
-In the meantime, please see
-[Incremental Shadow DOM](https://docs.google.com/document/d/1R9J8CVaSub_nbaVQwwm3NjCoZye4feJ7ft7tVe5QerM/edit?usp=sharing).
+Given the following composed tree and slot assignments,
+
+Composed tree:
+
+```text
+A
+├──/shadowRoot1
+│ ├── slot1
+│ └── slot2
+├── B
+└── C
+```
+
+Slot Assignments:
+
+| slot | slot's assigned nodes |
+| ----- | --------------------- |
+| slot1 | [C] |
+| slot2 | [B] |
+
+The flat tree would be:
+
+```text
+A
+├── slot1
+│ └── C
+└── slot2
+ └── B
+```
+
+## Example 2
+
+More complex example is here.
+
+Composed tree:
+
+```text
+A
+├──/shadowRoot1
+│ ├── B
+│ │ └── slot1
+│ ├── slot2
+│ │ └── C
+│ ├── D
+│ └── slot3
+│ ├── E
+│ └── F
+├── G
+├── H
+├── I
+└── J
+```
+
+Slot Assignments:
+
+| slot | slot's assigned nodes |
+| ----- | ------------------------ |
+| slot1 | [H] |
+| slot2 | [G, I] |
+| slot3 | [] (nothing is assigned) |
+
+The flat tree would be:
+
+```text
+A
+├── B
+│ └── slot1
+│ └── H
+├── slot2
+│ ├── G
+│ └── I
+├── D
+└── slot3
+ ├── E
+ └── F
+```
+
+- `slot2`'s child, `C`, is not shown in this flat tree because `slot2` has
+ non-empty assigned nodes, `[G, I]`, which are used as `slot2`'s children in
+ the flat tree.
+- If a slots doesn't have any assigned nodes, the slot's children are used as
+ _fallback contents_ in the flat tree. e.g. `slot3`s children in the flat tree
+ are `E` and `F`.
+- If a host's child node is assigned to nowhere, the child is not used. e.g. `J`
+
+## Example 3
+
+A slot itself can be assigned to another slot.
+
+For example, if we attach a shadow root to `B`, and put a `<slot>`, `slot4`,
+inside of the shadow tree.
+
+```text
+A
+├──/shadowRoot1
+│ ├── B
+│ │ ├──/shadowRoot2
+│ │ │ └── K
+│ │ │ └── slot4
+│ │ └── slot1
+│ ├── slot2
+│ │ └── C
+│ ├── D
+│ └── slot3
+│ ├── E
+│ └── F
+├── G
+├── H
+├── I
+└── J
+```
+
+| slot | slot's assigned nodes |
+| ----- | ------------------------ |
+| slot1 | [H] |
+| slot2 | [G, I] |
+| slot3 | [] (nothing is assigned) |
+| slot4 | [slot1] |
+
+The flat tree would be:
+
+```text
+A
+├── B
+│ └── K
+│ └── slot4
+│ └── slot1
+│ └── H
+├── slot2
+│ ├── G
+│ └── I
+├── D
+└── slot3
+ ├── E
+ └── F
+```
+
+# Slot Assignment Recalc
+
+Please see
+[Incremental Shadow DOM](https://docs.google.com/document/d/1R9J8CVaSub_nbaVQwwm3NjCoZye4feJ7ft7tVe5QerM/edit?usp=sharing)
+to know how assignments are recalc-ed.
# FlatTreeTraversal
+Blink doesn't store nor maintain a flat tree data structure in the memory.
+Instead, Blink provides a utility class,
+[`FlatTreeTraversal`](./flat_tree_traversal.h), which traverses a composed tree
+_in a flat tree order_.
+
+e.g. in the above example 3,
+
+- `FlatTreeTraversal::firstChild(slot1)` returns `H`
+- `FlatTreeTraversal::parent(H)` returns `slot1`
+- `FlatTreeTraversal::nextSibling(G)` returns `I`
+- `FlatTreeTraversal::previousSibling(I)` returns `G`
+
+The APIs which `FlatTreeTraversal` provides are very similar to ones other
+traversal utility classes provide, such as `NodeTraversal` and
+`ElementTraversal`.
+
+## Warning
+
+For historical reasons, Blink still supports Shadow DOM v0, where the different
+node distribution mechanism is still used. To support v0, you need to call
+`Node::UpdateDistributionForFlatTreeTraversal` before calling any function of
+`FlatTreeTraversal`.
+
+If you use `FlatTreeTraversal` without updating distribution, you would hit
+DCHECK. :(
+
+Since `Node::UpdateDistributionForFlatTreeTraversal` can take O(N) in the worst
+case (_even if the distribution flag is clean!_), you should be careful not to
+call it in hot code paths. If you are not sure, please contact
+dom-dev@chromium.org, or add hayato@chromium.org to reviewers.
+
+Once Blink removes Shadow DOM v0 in the future, you don't need to call
+`Node::UpdateDistributionForFlatTreeTraversal` before using `FlatTreeTraversal`
+beforehand in most cases, however, that wouldn't happen soon.
+
+# Event path and Event Retargeting
+
+<!-- Old doc: https://www.w3.org/TR/2014/WD-shadow-dom-20140617/ -->
+
+[DOM Standard] defines how an event should be dispatched
+[here](https://dom.spec.whatwg.org/#concept-event-dispatch), including how
+[event path](https://dom.spec.whatwg.org/#event-path) should be calculated,
+however, I wouldn't be surprised if the steps described there might look a kind
+of cryptogram to you.
+
+In this README, I'll explain how an event is dispatched and how its event path
+is calculated briefly by using some relatively-understandable examples.
+
+Basically, an event is dispatched across shadow trees.
+
+![event dispatch](https://hayato.io/2017/dom/event-dispatch.svg)
+
+Let me show more complex example composed tree, involving a slot:
+
+```text
+A
+└── B
+ ├──/shadowroot-C
+ │ └── D
+ │ ├──/shadowroot-E
+ │ │ └── F
+ │ │ └── slot-G
+ │ └── H
+ │ └── I
+ │ ├──/shadowroot-J
+ │ │ └── K
+ │ │ ├──/shadowroot-L
+ │ │ │ └── M
+ │ │ │ ├──/shadowroot-N
+ │ │ │ │ └── slot-O
+ │ │ │ └── slot-P
+ │ │ └── Q
+ │ │ └── slot-R
+ │ └── slot-S
+ └── T
+ └── U
+```
+
+Slot Assignments:
+
+| slot | slot's assigned nodes |
+| ------ | --------------------- |
+| slot-G | [H] |
+| slot-O | [slot-P] |
+| slot-P | [O] |
+| slot-R | [slot-S] |
+| slot-S | [T] |
+
+Given that, suppose that an event is fired on `U`, an event path would be (in
+reverse order):
+
+```text
+[U => T => slot-S => slot-R => Q => slot-P => slot-O => shadowroot-N => M
+=> shadowroot-L => K => shadowroot-J => I => H => slot-G => F => shadowroot-E
+=> D => shadowroot-C => B => A]
+```
+
+Roughly speaking, an event's _parent_ (the next node in event path) is
+calculated as follows:
+
+- If a node is assigned to a slot, the _parent_ is the node's asigned slot.
+- If a node is a shadow root, the _parent_ is its shadow host.
+- In other cases, the _parent_ is node's parent.
+
+In the above case, `event.target`, `U`, doesn't change in its lifetime because
+`U` can be _seen_ from every nodes there. However, if an event is fired on node
+`Q`, for example, `event.target` would be adjusted for some nodes in event path
+to honer encapsulation. That is called _event re-targeting_.
+
+Here is an event path for an event which is fired on `Q` :
+
+| event.currenttarget | (re-targeted) event.target |
+| ------------------- | -------------------------- |
+| Q | Q |
+| slot-P | Q |
+| slot-O | Q |
+| shadowroot-N | Q |
+| M | Q |
+| shadowroot-L | Q |
+| K | Q |
+| shadowroot-J | Q |
+| I | I |
+| H | I |
+| slot-G | I |
+| F | I |
+| shadowroot-E | I |
+| D | I |
+| shadowroot-C | I |
+| B | B |
+| A | B |
+
+# Design goal of event path calculation
+
TODO(hayato): Explain.
-# DOM mutations
+# Composed events
TODO(hayato): Explain.
-# Related flags
+# Event path and related targets
TODO(hayato): Explain.
-# Event path and Event Retargeting
+# DOM mutations
+
+TODO(hayato): Explain.
+
+# Related flags
TODO(hayato): Explain.
diff --git a/chromium/third_party/blink/renderer/core/dom/abort_signal.cc b/chromium/third_party/blink/renderer/core/dom/abort_signal.cc
index e0283241bd6..b088e008562 100644
--- a/chromium/third_party/blink/renderer/core/dom/abort_signal.cc
+++ b/chromium/third_party/blink/renderer/core/dom/abort_signal.cc
@@ -12,6 +12,7 @@
#include "third_party/blink/renderer/core/event_type_names.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.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/atomic_string.h"
namespace blink {
@@ -42,7 +43,7 @@ void AbortSignal::SignalAbort() {
std::move(closure).Run();
}
abort_algorithms_.clear();
- DispatchEvent(Event::Create(EventTypeNames::abort));
+ DispatchEvent(*Event::Create(EventTypeNames::abort));
}
void AbortSignal::Follow(AbortSignal* parentSignal) {
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 4fe5a46d7a7..8530b0e823e 100644
--- a/chromium/third_party/blink/renderer/core/dom/character_data.cc
+++ b/chromium/third_party/blink/renderer/core/dom/character_data.cc
@@ -41,11 +41,9 @@ void CharacterData::Atomize() {
}
void CharacterData::setData(const String& data) {
- const String& non_null_data = !data.IsNull() ? data : g_empty_string;
unsigned old_length = length();
- SetDataAndUpdate(non_null_data, 0, old_length, non_null_data.length(),
- kUpdateFromNonParser);
+ SetDataAndUpdate(data, 0, old_length, data.length(), kUpdateFromNonParser);
GetDocument().DidRemoveText(*this, 0, old_length);
}
@@ -171,7 +169,7 @@ bool CharacterData::ContainsOnlyWhitespace() const {
}
void CharacterData::setNodeValue(const String& node_value) {
- setData(node_value);
+ setData(!node_value.IsNull() ? node_value : g_empty_string);
}
void CharacterData::SetDataAndUpdate(const String& new_data,
@@ -217,7 +215,7 @@ void CharacterData::DidModifyData(const String& old_data, UpdateSource source) {
if (source != kUpdateFromParser && !IsInShadowTree()) {
if (GetDocument().HasListenerType(
Document::kDOMCharacterDataModifiedListener)) {
- DispatchScopedEvent(MutationEvent::Create(
+ DispatchScopedEvent(*MutationEvent::Create(
EventTypeNames::DOMCharacterDataModified, Event::Bubbles::kYes,
nullptr, old_data, data_));
}
diff --git a/chromium/third_party/blink/renderer/core/dom/character_data.idl b/chromium/third_party/blink/renderer/core/dom/character_data.idl
index 1d216114e5f..30b22212172 100644
--- a/chromium/third_party/blink/renderer/core/dom/character_data.idl
+++ b/chromium/third_party/blink/renderer/core/dom/character_data.idl
@@ -20,7 +20,7 @@
// https://dom.spec.whatwg.org/#interface-characterdata
interface CharacterData : Node {
- attribute [TreatNullAs=NullString] DOMString data;
+ attribute [TreatNullAs=EmptyString] DOMString data;
readonly attribute unsigned long length;
[RaisesException] DOMString substringData(unsigned long offset, unsigned long count);
void appendData(DOMString data);
diff --git a/chromium/third_party/blink/renderer/core/dom/comment.h b/chromium/third_party/blink/renderer/core/dom/comment.h
index f4f81ad3519..5b1579ba869 100644
--- a/chromium/third_party/blink/renderer/core/dom/comment.h
+++ b/chromium/third_party/blink/renderer/core/dom/comment.h
@@ -27,7 +27,7 @@
namespace blink {
-class Comment final : public CharacterData {
+class CORE_EXPORT Comment final : public CharacterData {
DEFINE_WRAPPERTYPEINFO();
public:
@@ -39,6 +39,7 @@ class Comment final : public CharacterData {
String nodeName() const override;
NodeType getNodeType() const override;
Node* Clone(Document&, CloneChildrenFlag) const override;
+ void DetachLayoutTree(const AttachContext&) final {}
};
DEFINE_NODE_TYPE_CASTS(Comment, getNodeType() == Node::kCommentNode);
diff --git a/chromium/third_party/blink/renderer/core/dom/common_definitions.idl b/chromium/third_party/blink/renderer/core/dom/common_definitions.idl
index d9e3f29334c..60c8b6ec8d1 100644
--- a/chromium/third_party/blink/renderer/core/dom/common_definitions.idl
+++ b/chromium/third_party/blink/renderer/core/dom/common_definitions.idl
@@ -7,6 +7,12 @@
typedef (ArrayBuffer or ArrayBufferView) BufferSource;
typedef unsigned long long DOMTimeStamp;
+
+// https://heycam.github.io/webidl/#Function
+
+callback Function = any (any... arguments);
+
+
// typedefs used in multiple files.
typedef object JSON;
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 31c96bdc0fb..659d355a779 100644
--- a/chromium/third_party/blink/renderer/core/dom/container_node.cc
+++ b/chromium/third_party/blink/renderer/core/dom/container_node.cc
@@ -354,7 +354,7 @@ void ContainerNode::DidInsertNodeVector(
}
DispatchSubtreeModifiedEvent();
- if (AXObjectCache* cache = GetDocument().GetOrCreateAXObjectCache())
+ if (AXObjectCache* cache = GetDocument().ExistingAXObjectCache())
cache->DidInsertChildrenOfNode(this);
}
@@ -700,14 +700,15 @@ Node* ContainerNode::RemoveChild(Node* old_child,
}
{
- SlotAssignmentRecalcForbiddenScope forbid_slot_recalc(GetDocument());
HTMLFrameOwnerElement::PluginDisposeSuspendScope suspend_plugin_dispose;
TreeOrderedMap::RemoveScope tree_remove_scope;
-
Node* prev = child->previousSibling();
Node* next = child->nextSibling();
- RemoveBetween(prev, next, *child);
- NotifyNodeRemoved(*child);
+ {
+ SlotAssignmentRecalcForbiddenScope forbid_slot_recalc(GetDocument());
+ RemoveBetween(prev, next, *child);
+ NotifyNodeRemoved(*child);
+ }
ChildrenChanged(ChildrenChange::ForRemoval(*child, prev, next,
kChildrenChangeSourceAPI));
}
@@ -926,7 +927,7 @@ void ContainerNode::NotifyNodeInsertedInternal(
if (!isConnected() && !IsInShadowTree() && !node.IsContainerNode())
continue;
if (Node::kInsertionShouldCallDidNotifySubtreeInsertions ==
- node.InsertedInto(this))
+ node.InsertedInto(*this))
post_insertion_notification_targets.push_back(&node);
if (ShadowRoot* shadow_root = node.GetShadowRoot())
NotifyNodeInsertedInternal(*shadow_root,
@@ -944,17 +945,40 @@ void ContainerNode::NotifyNodeRemoved(Node& root) {
// since the virtual call to removedFrom is not needed.
if (!node.IsContainerNode() && !node.IsInTreeScope())
continue;
- node.RemovedFrom(this);
+ node.RemovedFrom(*this);
if (ShadowRoot* shadow_root = node.GetShadowRoot())
NotifyNodeRemoved(*shadow_root);
}
}
+#if DCHECK_IS_ON()
+namespace {
+
+bool AttachedAllowedWhenAttaching(Node* node) {
+ return node->getNodeType() == Node::kCommentNode ||
+ node->getNodeType() == Node::kProcessingInstructionNode;
+}
+
+bool ChildAttachedAllowedWhenAttachingChildren(ContainerNode* node) {
+ if (node->IsShadowRoot())
+ return true;
+ if (node->IsV0InsertionPoint())
+ return true;
+ if (IsHTMLSlotElement(node))
+ return true;
+ if (IsShadowHost(node))
+ return true;
+ return false;
+}
+
+} // namespace
+#endif
+
DISABLE_CFI_PERF
void ContainerNode::AttachLayoutTree(AttachContext& context) {
for (Node* child = firstChild(); child; child = child->nextSibling()) {
#if DCHECK_IS_ON()
- DCHECK(child->NeedsAttach() ||
+ DCHECK(child->NeedsAttach() || AttachedAllowedWhenAttaching(child) ||
ChildAttachedAllowedWhenAttachingChildren(this));
#endif
if (child->NeedsAttach())
@@ -981,11 +1005,10 @@ void ContainerNode::ChildrenChanged(const ChildrenChange& change) {
GetDocument().IncDOMTreeVersion();
GetDocument().NotifyChangeChildren(*this);
InvalidateNodeListCachesInAncestors(nullptr, nullptr, &change);
- if (change.IsChildInsertion()) {
- if (!ChildNeedsStyleRecalc()) {
- SetChildNeedsStyleRecalc();
- MarkAncestorsWithChildNeedsStyleRecalc();
- }
+ if (!ChildNeedsStyleRecalc() && change.IsChildInsertion() &&
+ change.sibling_changed->NeedsStyleRecalc()) {
+ SetChildNeedsStyleRecalc();
+ MarkAncestorsWithChildNeedsStyleRecalc();
}
}
@@ -1277,15 +1300,15 @@ static void DispatchChildInsertionEvents(Node& child) {
if (c->parentNode() &&
document->HasListenerType(Document::kDOMNodeInsertedListener)) {
c->DispatchScopedEvent(
- MutationEvent::Create(EventTypeNames::DOMNodeInserted,
- Event::Bubbles::kYes, c->parentNode()));
+ *MutationEvent::Create(EventTypeNames::DOMNodeInserted,
+ Event::Bubbles::kYes, c->parentNode()));
}
// dispatch the DOMNodeInsertedIntoDocument event to all descendants
if (c->isConnected() && document->HasListenerType(
Document::kDOMNodeInsertedIntoDocumentListener)) {
for (; c; c = NodeTraversal::Next(*c, &child)) {
- c->DispatchScopedEvent(MutationEvent::Create(
+ c->DispatchScopedEvent(*MutationEvent::Create(
EventTypeNames::DOMNodeInsertedIntoDocument, Event::Bubbles::kNo));
}
}
@@ -1319,7 +1342,7 @@ static void DispatchChildRemovalEvents(Node& child) {
Document::InDOMNodeRemovedHandlerState::kDOMNodeRemoved);
}
NodeChildRemovalTracker scope(child);
- c->DispatchScopedEvent(MutationEvent::Create(
+ c->DispatchScopedEvent(*MutationEvent::Create(
EventTypeNames::DOMNodeRemoved, Event::Bubbles::kYes, c->parentNode()));
document.SetInDOMNodeRemovedHandlerState(original_document_state);
c->SetInDOMNodeRemovedHandler(original_node_flag);
@@ -1340,7 +1363,7 @@ static void DispatchChildRemovalEvents(Node& child) {
}
NodeChildRemovalTracker scope(child);
for (; c; c = NodeTraversal::Next(*c, &child)) {
- c->DispatchScopedEvent(MutationEvent::Create(
+ c->DispatchScopedEvent(*MutationEvent::Create(
EventTypeNames::DOMNodeRemovedFromDocument, Event::Bubbles::kNo));
}
document.SetInDOMNodeRemovedHandlerState(original_document_state);
@@ -1444,7 +1467,6 @@ void ContainerNode::RebuildChildrenLayoutTrees(
// This is done in ContainerNode::AttachLayoutTree but will never be cleared
// if we don't enter ContainerNode::AttachLayoutTree so we do it here.
ClearChildNeedsStyleRecalc();
- ClearChildNeedsReattachLayoutTree();
}
void ContainerNode::CheckForSiblingStyleChanges(SiblingCheckType change_type,
@@ -1621,22 +1643,4 @@ NodeListsNodeData& ContainerNode::EnsureNodeLists() {
return EnsureRareData().EnsureNodeLists();
}
-#if DCHECK_IS_ON()
-bool ChildAttachedAllowedWhenAttachingChildren(ContainerNode* node) {
- if (node->IsShadowRoot())
- return true;
-
- if (node->IsV0InsertionPoint())
- return true;
-
- if (IsHTMLSlotElement(node))
- return true;
-
- if (IsShadowHost(node))
- return true;
-
- return false;
-}
-#endif
-
} // namespace blink
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 dea345ca2d3..578665e17db 100644
--- a/chromium/third_party/blink/renderer/core/dom/container_node.h
+++ b/chromium/third_party/blink/renderer/core/dom/container_node.h
@@ -456,10 +456,6 @@ class CORE_EXPORT ContainerNode : public Node {
TraceWrapperMember<Node> last_child_;
};
-#if DCHECK_IS_ON()
-bool ChildAttachedAllowedWhenAttachingChildren(ContainerNode*);
-#endif
-
WILL_NOT_BE_EAGERLY_TRACED_CLASS(ContainerNode);
DEFINE_NODE_TYPE_CASTS(ContainerNode, IsContainerNode());
diff --git a/chromium/third_party/blink/renderer/core/dom/document.cc b/chromium/third_party/blink/renderer/core/dom/document.cc
index 5bfe30b8b88..e628c1ab824 100644
--- a/chromium/third_party/blink/renderer/core/dom/document.cc
+++ b/chromium/third_party/blink/renderer/core/dom/document.cc
@@ -32,6 +32,7 @@
#include <memory>
#include "base/auto_reset.h"
+#include "base/optional.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"
@@ -49,12 +50,15 @@
#include "third_party/blink/public/platform/web_prerendering_support.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/script_controller.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/bindings/core/v8/source_location.h"
#include "third_party/blink/renderer/bindings/core/v8/string_or_dictionary.h"
#include "third_party/blink/renderer/bindings/core/v8/usv_string_or_trusted_url.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/window_proxy.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/document_animations.h"
#include "third_party/blink/renderer/core/animation/document_timeline.h"
@@ -64,6 +68,7 @@
#include "third_party/blink/renderer/core/css/css_property_value_set.h"
#include "third_party/blink/renderer/core/css/css_style_declaration.h"
#include "third_party/blink/renderer/core/css/css_style_sheet.h"
+#include "third_party/blink/renderer/core/css/css_style_sheet_init.h"
#include "third_party/blink/renderer/core/css/cssom/computed_style_property_map.h"
#include "third_party/blink/renderer/core/css/font_face_set_document.h"
#include "third_party/blink/renderer/core/css/invalidation/style_invalidator.h"
@@ -148,6 +153,7 @@
#include "third_party/blink/renderer/core/frame/use_counter.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/anchor_element_metrics.h"
#include "third_party/blink/renderer/core/html/canvas/canvas_font_cache.h"
#include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h"
#include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h"
@@ -179,6 +185,7 @@
#include "third_party/blink/renderer/core/html/html_unknown_element.h"
#include "third_party/blink/renderer/core/html/imports/html_import_loader.h"
#include "third_party/blink/renderer/core/html/imports/html_imports_controller.h"
+#include "third_party/blink/renderer/core/html/lazy_load_image_observer.h"
#include "third_party/blink/renderer/core/html/parser/html_document_parser.h"
#include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h"
#include "third_party/blink/renderer/core/html/parser/nesting_level_incrementer.h"
@@ -231,6 +238,7 @@
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/core/resize_observer/resize_observer_controller.h"
#include "third_party/blink/renderer/core/script/script_runner.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
#include "third_party/blink/renderer/core/svg/svg_document_extensions.h"
#include "third_party/blink/renderer/core/svg/svg_script_element.h"
#include "third_party/blink/renderer/core/svg/svg_title_element.h"
@@ -268,7 +276,6 @@
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h"
#include "third_party/blink/renderer/platform/text/platform_locale.h"
#include "third_party/blink/renderer/platform/weborigin/origin_access_entry.h"
#include "third_party/blink/renderer/platform/weborigin/scheme_registry.h"
@@ -558,7 +565,7 @@ class Document::NetworkStateObserver final
Document* document = ToDocument(GetExecutionContext());
if (!document->domWindow())
return;
- document->domWindow()->DispatchEvent(Event::Create(event_name));
+ document->domWindow()->DispatchEvent(*Event::Create(event_name));
probe::networkStateChanged(document->GetFrame(), on_line);
}
@@ -630,6 +637,7 @@ Document::Document(const DocumentInit& initializer,
contains_plugins_(false),
ignore_destructive_write_count_(0),
throw_on_dynamic_markup_insertion_count_(0),
+ ignore_opens_during_unload_count_(0),
markers_(new DocumentMarkerController(*this)),
update_focus_appearance_timer_(
GetTaskRunner(TaskType::kInternalUserInteraction),
@@ -692,7 +700,8 @@ Document::Document(const DocumentInit& initializer,
slot_assignment_recalc_forbidden_recursion_depth_(0),
#endif
needs_to_record_ukm_outlive_time_(false),
- viewport_data_(new ViewportData(*this)) {
+ viewport_data_(new ViewportData(*this)),
+ agent_cluster_id_(base::UnguessableToken::Create()) {
if (frame_) {
DCHECK(frame_->GetPage());
ProvideContextFeaturesToDocumentFrom(*this, *frame_->GetPage());
@@ -1139,6 +1148,20 @@ ScriptPromise Document::createCSSStyleSheet(ScriptState* script_state,
ScriptValue::From(script_state, sheet));
}
+CSSStyleSheet* Document::createEmptyCSSStyleSheet(
+ ScriptState* script_state,
+ const CSSStyleSheetInit& options,
+ ExceptionState& exception_state) {
+ return CSSStyleSheet::Create(*this, options, exception_state);
+}
+
+CSSStyleSheet* Document::createEmptyCSSStyleSheet(
+ ScriptState* script_state,
+ ExceptionState& exception_state) {
+ return Document::createEmptyCSSStyleSheet(script_state, CSSStyleSheetInit(),
+ exception_state);
+}
+
ScriptValue Document::registerElement(ScriptState* script_state,
const AtomicString& name,
const ElementRegistrationOptions& options,
@@ -1433,7 +1456,7 @@ void Document::SetReadyState(DocumentReadyState ready_state) {
}
ready_state_ = ready_state;
- DispatchEvent(Event::Create(EventTypeNames::readystatechange));
+ DispatchEvent(*Event::Create(EventTypeNames::readystatechange));
}
bool Document::IsLoadCompleted() const {
@@ -1475,6 +1498,15 @@ void Document::setXMLStandalone(bool standalone,
}
void Document::SetContent(const String& content) {
+ // Only set the content of the document if it is ready to be set. This method
+ // could be called at any time.
+ if (ScriptableDocumentParser* parser = GetScriptableDocumentParser()) {
+ if (parser->IsParsing() && parser->IsExecutingScript())
+ return;
+ }
+ if (ignore_opens_during_unload_count_)
+ return;
+
open();
parser_->Append(content);
close();
@@ -1623,7 +1655,7 @@ void Document::UpdateTitle(const String& title) {
return;
DispatchDidReceiveTitle();
- if (AXObjectCache* cache = GetOrCreateAXObjectCache())
+ if (AXObjectCache* cache = ExistingAXObjectCache())
cache->DocumentTitleChanged();
}
@@ -1760,9 +1792,9 @@ void Document::SetWasDiscarded(bool was_discarded) {
}
void Document::DidChangeVisibilityState() {
- DispatchEvent(Event::CreateBubble(EventTypeNames::visibilitychange));
+ DispatchEvent(*Event::CreateBubble(EventTypeNames::visibilitychange));
// Also send out the deprecated version until it can be removed.
- DispatchEvent(Event::CreateBubble(EventTypeNames::webkitvisibilitychange));
+ DispatchEvent(*Event::CreateBubble(EventTypeNames::webkitvisibilitychange));
if (GetPageVisibilityState() == mojom::PageVisibilityState::kVisible)
Timeline().SetAllCompositorPending();
@@ -1922,6 +1954,7 @@ void Document::UpdateStyleInvalidationIfNeeded() {
if (!ChildNeedsStyleInvalidation() && !NeedsStyleInvalidation())
return;
TRACE_EVENT0("blink", "Document::updateStyleInvalidationIfNeeded");
+ SCOPED_BLINK_UMA_HISTOGRAM_TIMER_HIGHRES("Style.InvalidationTime");
GetStyleEngine().InvalidateStyle();
}
@@ -2023,8 +2056,7 @@ void Document::PropagateStyleToViewport() {
EOverscrollBehavior overscroll_behavior_y =
overflow_style->OverscrollBehaviorY();
using OverscrollBehaviorType = cc::OverscrollBehavior::OverscrollBehaviorType;
- if (RuntimeEnabledFeatures::CSSOverscrollBehaviorEnabled() &&
- IsInMainFrame()) {
+ if (IsInMainFrame()) {
GetPage()->GetOverscrollController().SetOverscrollBehavior(
cc::OverscrollBehavior(
static_cast<OverscrollBehaviorType>(overscroll_behavior_x),
@@ -2092,13 +2124,6 @@ void Document::PropagateStyleToViewport() {
#if DCHECK_IS_ON()
static void AssertLayoutTreeUpdated(Node& root) {
for (Node& node : NodeTraversal::InclusiveDescendantsOf(root)) {
- // We leave some nodes with dirty bits in the tree because they don't
- // matter like Comment and ProcessingInstruction nodes.
- // TODO(esprehn): Don't even mark those nodes as needing recalcs in the
- // first place.
- if (!node.IsElementNode() && !node.IsTextNode() && !node.IsShadowRoot() &&
- !node.IsDocumentNode())
- continue;
DCHECK(!node.NeedsStyleRecalc());
DCHECK(!node.ChildNeedsStyleRecalc());
DCHECK(!node.NeedsReattachLayoutTree());
@@ -2237,7 +2262,6 @@ void Document::UpdateStyle() {
TRACE_EVENT_BEGIN0("blink,blink_style", "Document::updateStyle");
RUNTIME_CALL_TIMER_SCOPE(V8PerIsolateData::MainThreadIsolate(),
RuntimeCallStats::CounterId::kUpdateStyle);
- TimeTicks start_time = CurrentTimeTicks();
unsigned initial_element_count = GetStyleEngine().StyleForElementCount();
@@ -2278,11 +2302,9 @@ void Document::UpdateStyle() {
if (Element* document_element = documentElement()) {
if (document_element->ShouldCallRecalcStyle(change)) {
TRACE_EVENT0("blink,blink_style", "Document::recalcStyle");
+ SCOPED_BLINK_UMA_HISTOGRAM_TIMER_HIGHRES("Style.RecalcTime");
Element* viewport_defining = ViewportDefiningElement();
- ReattachLegacyLayoutObjectList legacy_layout_objects(*this);
- legacy_layout_objects.WillRecalcStyle();
document_element->RecalcStyle(change);
- legacy_layout_objects.DidRecalcStyle();
if (viewport_defining != ViewportDefiningElement())
ViewportDefiningElementDidChange();
}
@@ -2291,6 +2313,7 @@ void Document::UpdateStyle() {
if (document_element->NeedsReattachLayoutTree() ||
document_element->ChildNeedsReattachLayoutTree()) {
TRACE_EVENT0("blink,blink_style", "Document::rebuildLayoutTree");
+ SCOPED_BLINK_UMA_HISTOGRAM_TIMER_HIGHRES("Style.RebuildLayoutTreeTime");
ReattachLegacyLayoutObjectList legacy_layout_objects(*this);
WhitespaceAttacher whitespace_attacher;
document_element->RebuildLayoutTree(whitespace_attacher);
@@ -2322,10 +2345,6 @@ void Document::UpdateStyle() {
"blink,blink_style", "Document::updateStyle", "resolverAccessCount",
GetStyleEngine().StyleForElementCount() - initial_element_count);
}
-
- DEFINE_STATIC_LOCAL(CustomCountHistogram, update_histogram,
- ("Style.UpdateTime", 0, 10000000, 50));
- update_histogram.CountMicroseconds(CurrentTimeTicks() - start_time);
}
void Document::ViewportDefiningElementDidChange() {
@@ -2455,7 +2474,7 @@ void Document::LayoutUpdated() {
// 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() && GetFrame()->IsMainFrame())
- GetFrame()->GetPage()->GetChromeClient().LayoutUpdated();
+ GetFrame()->GetPage()->GetChromeClient().MainFrameLayoutUpdated();
Markers().InvalidateRectsForAllTextMatchMarkers();
@@ -2796,8 +2815,10 @@ void Document::Shutdown() {
}
sequential_focus_navigation_starting_point_ = nullptr;
- if (this == &AXObjectCacheOwner())
+ if (this == &AXObjectCacheOwner()) {
+ ax_contexts_.clear();
ClearAXObjectCache();
+ }
layout_view_ = nullptr;
ContainerNode::DetachLayoutTree();
@@ -2896,13 +2917,54 @@ Document& Document::AXObjectCacheOwner() const {
return *doc;
}
+void Document::AddAXContext(AXContext* context) {
+ // The only case when |&cache_owner| is not |this| is when this is a
+ // pop-up. We want pop-ups to share the AXObjectCache of their parent
+ // document. However, there's no valid reason to explicitly create an
+ // AXContext for a pop-up document, so check to make sure we're not
+ // trying to do that here.
+ DCHECK_EQ(&AXObjectCacheOwner(), this);
+
+ // If the document has already been detached, do not make a new AXObjectCache.
+ if (!GetLayoutView())
+ return;
+
+ ax_contexts_.push_back(context);
+ if (ax_contexts_.size() != 1)
+ return;
+
+ if (!ax_object_cache_)
+ ax_object_cache_ = AXObjectCache::Create(*this);
+}
+
+void Document::RemoveAXContext(AXContext* context) {
+ auto** iter =
+ std::find_if(ax_contexts_.begin(), ax_contexts_.end(),
+ [&context](const auto& item) { return item == context; });
+ if (iter != ax_contexts_.end())
+ ax_contexts_.erase(iter);
+ if (ax_contexts_.size() == 0)
+ ClearAXObjectCache();
+}
+
void Document::ClearAXObjectCache() {
DCHECK_EQ(&AXObjectCacheOwner(), this);
+
// Clear the cache member variable before calling delete because attempts
// are made to access it during destruction.
if (ax_object_cache_)
ax_object_cache_->Dispose();
ax_object_cache_.Clear();
+
+ // If there's at least one AXContext in scope and there's still a LayoutView
+ // around, recreate an empty AXObjectCache.
+ //
+ // TODO(dmazzoni): right now ClearAXObjectCache() is being used as a way
+ // to invalidate / reset the AXObjectCache while keeping it around. We
+ // should rewrite that as a method on AXObjectCache rather than destroying
+ // and recreating it here.
+ if (ax_contexts_.size() > 0 && GetLayoutView())
+ ax_object_cache_ = AXObjectCache::Create(*this);
}
AXObjectCache* Document::ExistingAXObjectCache() const {
@@ -2916,28 +2978,6 @@ AXObjectCache* Document::ExistingAXObjectCache() const {
return cache_owner.ax_object_cache_.Get();
}
-AXObjectCache* Document::GetOrCreateAXObjectCache() const {
- Settings* settings = GetSettings();
- if (!settings || !settings->GetAccessibilityEnabled())
- return nullptr;
-
- // Every document has its own AXObjectCache if accessibility is enabled,
- // except for page popups (such as select popups or context menus),
- // which share the AXObjectCache of their owner.
- //
- // See http://crbug.com/532249
- Document& cache_owner = AXObjectCacheOwner();
-
- // If the document has already been detached, do not make a new axObjectCache.
- if (!cache_owner.GetLayoutView())
- return nullptr;
-
- DCHECK(&cache_owner == this || !ax_object_cache_);
- if (!cache_owner.ax_object_cache_)
- cache_owner.ax_object_cache_ = AXObjectCache::Create(cache_owner);
- return cache_owner.ax_object_cache_.Get();
-}
-
CanvasFontCache* Document::GetCanvasFontCache() {
if (!canvas_font_cache_)
canvas_font_cache_ = CanvasFontCache::Create(*this);
@@ -2985,6 +3025,7 @@ void Document::SetPrinting(PrintingState state) {
}
}
+// https://html.spec.whatwg.org/C/dynamic-markup-insertion.html#document-open-steps
void Document::open(Document* entered_document,
ExceptionState& exception_state) {
if (ImportLoader()) {
@@ -2994,12 +3035,16 @@ void Document::open(Document* entered_document,
return;
}
+ // If |document| is an XML document, then throw an "InvalidStateError"
+ // DOMException exception.
if (!IsHTMLDocument()) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
"Only HTML documents support open().");
return;
}
+ // If |document|'s throw-on-dynamic-markup-insertion counter is greater than
+ // 0, then throw an "InvalidStateError" DOMException.
if (throw_on_dynamic_markup_insertion_count_) {
exception_state.ThrowDOMException(
DOMExceptionCode::kInvalidStateError,
@@ -3010,58 +3055,83 @@ void Document::open(Document* entered_document,
if (!AllowedToUseDynamicMarkUpInsertion("open", exception_state))
return;
- if (entered_document) {
- if (!GetSecurityOrigin()->IsSameSchemeHostPort(
- entered_document->GetSecurityOrigin())) {
- exception_state.ThrowSecurityError(
- "Can only call open() on same-origin documents.");
+ // If |document|'s origin is not same origin to the origin of the responsible
+ // document specified by the entry settings object, then throw a
+ // "SecurityError" DOMException.
+ if (entered_document && !GetSecurityOrigin()->IsSameSchemeHostPort(
+ entered_document->GetSecurityOrigin())) {
+ exception_state.ThrowSecurityError(
+ "Can only call open() on same-origin documents.");
+ return;
+ }
+
+ // If |document| has an active parser whose script nesting level is greater
+ // than 0, then return |document|.
+ if (ScriptableDocumentParser* parser = GetScriptableDocumentParser()) {
+ if (parser->IsParsing() && parser->IsExecutingScript())
return;
- }
- SetSecurityOrigin(entered_document->GetMutableSecurityOrigin());
+ }
- if (this != entered_document) {
- // Clear the hash fragment from the inherited URL to prevent a
- // scroll-into-view for any document.open()'d frame.
- KURL new_url = entered_document->Url();
- new_url.SetFragmentIdentifier(String());
- SetURL(new_url);
- SetReferrerPolicy(entered_document->GetReferrerPolicy());
- }
+ // Similarly, if |document|'s ignore-opens-during-unload counter is greater
+ // than 0, then return |document|.
+ if (ignore_opens_during_unload_count_)
+ return;
+
+ // Change |document|'s URL to the URL of the responsible document specified
+ // by the entry settings object.
+ if (entered_document && this != entered_document) {
+ // Clear the hash fragment from the inherited URL to prevent a
+ // scroll-into-view for any document.open()'d frame.
+ KURL new_url = entered_document->Url();
+ new_url.SetFragmentIdentifier(String());
+ SetURL(new_url);
- cookie_url_ = entered_document->CookieURL();
+ SetSecurityOrigin(entered_document->GetMutableSecurityOrigin());
+ SetReferrerPolicy(entered_document->GetReferrerPolicy());
+ SetCookieURL(entered_document->CookieURL());
}
open();
}
+// https://html.spec.whatwg.org/C/dynamic-markup-insertion.html#document-open-steps
void Document::open() {
DCHECK(!ImportLoader());
+ DCHECK(!ignore_opens_during_unload_count_);
+ if (ScriptableDocumentParser* parser = GetScriptableDocumentParser())
+ DCHECK(!parser->IsParsing() || !parser->IsExecutingScript());
- if (frame_) {
- if (ScriptableDocumentParser* parser = GetScriptableDocumentParser()) {
- if (parser->IsParsing()) {
- // FIXME: HTML5 doesn't tell us to check this, it might not be correct.
- if (parser->IsExecutingScript())
- return;
-
- if (!parser->WasCreatedByScript() && parser->HasInsertionPoint())
- return;
- }
- }
-
- if (frame_->Loader().HasProvisionalNavigation()) {
- frame_->Loader().StopAllLoaders();
- // Navigations handled by the client should also be cancelled.
- if (frame_->Client())
- frame_->Client()->AbortClientNavigation();
- }
+ // Abort |document|.
+ //
+ // TODO(timothygu): We are only aborting the document if there is a
+ // provisional navigation, unlike the spec.
+ if (frame_ && frame_->Loader().HasProvisionalNavigation()) {
+ frame_->Loader().StopAllLoaders();
+ // Navigations handled by the client should also be cancelled.
+ if (frame_ && frame_->Client())
+ frame_->Client()->AbortClientNavigation();
}
+ // For each shadow-including inclusive descendant |node| of |document|, erase
+ // all event listeners and handlers given |node|.
+ //
+ // Erase all event listeners and handlers given |window|.
+ //
+ // NB: Document::RemoveAllEventListeners() (called by
+ // RemoveAllEventListenersRecursively()) erases event listeners from the
+ // Window object as well.
RemoveAllEventListenersRecursively();
+
ResetTreeScope();
if (frame_)
frame_->Selection().Clear();
+
+ // Create a new HTML parser and associate it with |document|.
+ //
+ // Set the current document readiness of |document| to "loading".
ImplicitOpen(kForceSynchronousParsing);
+
+ // This is a script-created parser.
if (ScriptableDocumentParser* parser = GetScriptableDocumentParser())
parser->SetWasCreatedByScript(true);
@@ -3257,10 +3327,8 @@ DOMWindow* Document::open(LocalDOMWindow* current_window,
entered_window, exception_state);
}
+// https://html.spec.whatwg.org/C/dynamic-markup-insertion.html#dom-document-close
void Document::close(ExceptionState& exception_state) {
- // FIXME: We should follow the specification more closely:
- // http://www.whatwg.org/specs/web-apps/current-work/#dom-document-close
-
if (ImportLoader()) {
exception_state.ThrowDOMException(
DOMExceptionCode::kInvalidStateError,
@@ -3268,12 +3336,16 @@ void Document::close(ExceptionState& exception_state) {
return;
}
+ // If the Document object is an XML document, then throw an
+ // "InvalidStateError" DOMException.
if (!IsHTMLDocument()) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
"Only HTML documents support close().");
return;
}
+ // If the Document object's throw-on-dynamic-markup-insertion counter is
+ // greater than zero, then throw an "InvalidStateError" DOMException.
if (throw_on_dynamic_markup_insertion_count_) {
exception_state.ThrowDOMException(
DOMExceptionCode::kInvalidStateError,
@@ -3287,13 +3359,20 @@ void Document::close(ExceptionState& exception_state) {
close();
}
+// https://html.spec.whatwg.org/C/dynamic-markup-insertion.html#dom-document-close
void Document::close() {
+ // If there is no script-created parser associated with the document, then
+ // return.
if (!GetScriptableDocumentParser() ||
!GetScriptableDocumentParser()->WasCreatedByScript() ||
!GetScriptableDocumentParser()->IsParsing())
return;
+ // Insert an explicit "EOF" character at the end of the parser's input
+ // stream.
parser_->Finish();
+
+ // TODO(timothygu): We should follow the specification more closely.
if (!parser_ || !parser_->IsParsing())
SetReadyState(kComplete);
CheckCompleted();
@@ -3358,10 +3437,13 @@ void Document::ImplicitClose() {
View()->UpdateLayout();
}
+ if (View())
+ View()->ScrollAndFocusFragmentAnchor();
+
load_event_progress_ = kLoadEventCompleted;
if (GetFrame() && GetLayoutView()) {
- if (AXObjectCache* cache = GetOrCreateAXObjectCache()) {
+ if (AXObjectCache* cache = ExistingAXObjectCache()) {
if (this == &AXObjectCacheOwner())
cache->HandleLoadComplete(this);
else
@@ -3454,6 +3536,8 @@ bool Document::CheckCompletedInternal() {
DCHECK(ukm_binding.is_bound());
ukm_binding->SetDocumentSourceId(ukm_source_id_);
}
+
+ AnchorElementMetrics::MaybeReportViewportMetricsOnLoad(*this);
}
return true;
@@ -3471,8 +3555,8 @@ bool Document::DispatchBeforeUnloadEvent(ChromeClient& chrome_client,
if (ProcessingBeforeUnload())
return false;
- BeforeUnloadEvent* before_unload_event = BeforeUnloadEvent::Create();
- before_unload_event->initEvent(EventTypeNames::beforeunload, false, true);
+ BeforeUnloadEvent& before_unload_event = *BeforeUnloadEvent::Create();
+ before_unload_event.initEvent(EventTypeNames::beforeunload, false, true);
load_event_progress_ = kBeforeUnloadEventInProgress;
const TimeTicks beforeunload_event_start = CurrentTimeTicks();
dom_window_->DispatchEvent(before_unload_event, this);
@@ -3483,7 +3567,7 @@ bool Document::DispatchBeforeUnloadEvent(ChromeClient& chrome_client,
("DocumentEventTiming.BeforeUnloadDuration", 0, 10000000, 50));
beforeunload_histogram.CountMicroseconds(beforeunload_event_end -
beforeunload_event_start);
- if (!before_unload_event->defaultPrevented())
+ if (!before_unload_event.defaultPrevented())
DefaultEventHandler(before_unload_event);
enum BeforeUnloadDialogHistogramEnum {
@@ -3495,10 +3579,10 @@ bool Document::DispatchBeforeUnloadEvent(ChromeClient& chrome_client,
};
DEFINE_STATIC_LOCAL(EnumerationHistogram, beforeunload_dialog_histogram,
("Document.BeforeUnloadDialog", kDialogEnumMax));
- if (before_unload_event->returnValue().IsNull()) {
+ if (before_unload_event.returnValue().IsNull()) {
beforeunload_dialog_histogram.Count(kNoDialogNoText);
}
- if (!GetFrame() || before_unload_event->returnValue().IsNull())
+ if (!GetFrame() || before_unload_event.returnValue().IsNull())
return true;
if (!GetFrame()->HasBeenActivated()) {
@@ -3520,11 +3604,19 @@ bool Document::DispatchBeforeUnloadEvent(ChromeClient& chrome_client,
Intervention::GenerateReport(frame_, "BeforeUnloadMultiple", message);
return true;
}
- String text = before_unload_event->returnValue();
+ String text = before_unload_event.returnValue();
beforeunload_dialog_histogram.Count(
BeforeUnloadDialogHistogramEnum::kShowDialog);
- if (chrome_client.OpenBeforeUnloadConfirmPanel(text, frame_, is_reload)) {
- did_allow_navigation = true;
+ const TimeTicks beforeunload_confirmpanel_start = CurrentTimeTicks();
+ did_allow_navigation =
+ chrome_client.OpenBeforeUnloadConfirmPanel(text, frame_, is_reload);
+ const TimeTicks beforeunload_confirmpanel_end = CurrentTimeTicks();
+ if (did_allow_navigation) {
+ // Only record when a navigation occurs, since we want to understand
+ // the impact of the before unload dialog on overall input to navigation.
+ UMA_HISTOGRAM_MEDIUM_TIMES(
+ "DocumentEventTiming.BeforeUnloadDialogDuration.ByNavigation",
+ beforeunload_confirmpanel_end - beforeunload_confirmpanel_start);
return true;
}
@@ -3548,7 +3640,8 @@ void Document::DispatchUnloadEvents() {
if (LocalDOMWindow* window = domWindow()) {
const TimeTicks pagehide_event_start = CurrentTimeTicks();
window->DispatchEvent(
- PageTransitionEvent::Create(EventTypeNames::pagehide, false), this);
+ *PageTransitionEvent::Create(EventTypeNames::pagehide, false),
+ this);
const TimeTicks pagehide_event_end = CurrentTimeTicks();
DEFINE_STATIC_LOCAL(
CustomCountHistogram, pagehide_histogram,
@@ -3565,7 +3658,7 @@ void Document::DispatchUnloadEvents() {
// Dispatch visibilitychange event, but don't bother doing
// other notifications as we're about to be unloaded.
const TimeTicks pagevisibility_hidden_event_start = CurrentTimeTicks();
- DispatchEvent(Event::CreateBubble(EventTypeNames::visibilitychange));
+ DispatchEvent(*Event::CreateBubble(EventTypeNames::visibilitychange));
const TimeTicks pagevisibility_hidden_event_end = CurrentTimeTicks();
DEFINE_STATIC_LOCAL(CustomCountHistogram, pagevisibility_histogram,
("DocumentEventTiming.PageVibilityHiddenDuration",
@@ -3574,7 +3667,7 @@ void Document::DispatchUnloadEvents() {
pagevisibility_hidden_event_end -
pagevisibility_hidden_event_start);
DispatchEvent(
- Event::CreateBubble(EventTypeNames::webkitvisibilitychange));
+ *Event::CreateBubble(EventTypeNames::webkitvisibilitychange));
}
if (!frame_)
return;
@@ -3584,7 +3677,7 @@ void Document::DispatchUnloadEvents() {
DocumentLoader* document_loader =
frame_->Loader().GetProvisionalDocumentLoader();
load_event_progress_ = kUnloadEventInProgress;
- Event* unload_event(Event::Create(EventTypeNames::unload));
+ Event& unload_event = *Event::Create(EventTypeNames::unload);
if (document_loader &&
document_loader->GetTiming().UnloadEventStart().is_null() &&
document_loader->GetTiming().UnloadEventEnd().is_null()) {
@@ -3627,7 +3720,7 @@ void Document::DispatchFreezeEvent() {
DCHECK(RuntimeEnabledFeatures::PageLifecycleEnabled());
const TimeTicks freeze_event_start = CurrentTimeTicks();
SetFreezingInProgress(true);
- DispatchEvent(Event::Create(EventTypeNames::freeze));
+ DispatchEvent(*Event::Create(EventTypeNames::freeze));
SetFreezingInProgress(false);
const TimeTicks freeze_event_end = CurrentTimeTicks();
DEFINE_STATIC_LOCAL(CustomCountHistogram, freeze_histogram,
@@ -3748,19 +3841,22 @@ void Document::write(const String& text,
bool has_insertion_point = parser_ && parser_->HasInsertionPoint();
- if (!has_insertion_point && ignore_destructive_write_count_) {
- AddConsoleMessage(
- ConsoleMessage::Create(kJSMessageSource, kWarningMessageLevel,
- ExceptionMessages::FailedToExecute(
- "write", "Document",
- "It isn't possible to write into a document "
- "from an asynchronously-loaded external "
- "script unless it is explicitly opened.")));
- return;
- }
+ if (!has_insertion_point) {
+ if (ignore_destructive_write_count_) {
+ AddConsoleMessage(ConsoleMessage::Create(
+ kJSMessageSource, kWarningMessageLevel,
+ ExceptionMessages::FailedToExecute(
+ "write", "Document",
+ "It isn't possible to write into a document "
+ "from an asynchronously-loaded external "
+ "script unless it is explicitly opened.")));
+ return;
+ }
+ if (ignore_opens_during_unload_count_)
+ return;
- if (!has_insertion_point)
open(entered_document, ASSERT_NO_EXCEPTION);
+ }
DCHECK(parser_);
PerformanceMonitor::ReportGenericViolation(
@@ -4152,7 +4248,7 @@ ReferrerPolicy Document::GetReferrerPolicy() const {
// 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/multipage/browsers.html#set-up-a-browsing-context-environment-settings-object.
+ // https://html.spec.whatwg.org/multipage/window-object.html#set-up-a-window-environment-settings-object.
if (!frame_ || policy != kReferrerPolicyDefault || !IsSrcdocDocument()) {
return policy;
}
@@ -4674,7 +4770,7 @@ bool Document::SetFocusedElement(Element* new_focused_element,
if (!focus_change_blocked && focused_element_) {
// Create the AXObject cache in a focus change because Chromium relies on
// it.
- if (AXObjectCache* cache = GetOrCreateAXObjectCache()) {
+ if (AXObjectCache* cache = ExistingAXObjectCache()) {
cache->HandleFocusedUIElementChanged(old_focused_element,
new_focused_element);
}
@@ -4976,7 +5072,7 @@ const OriginAccessEntry& Document::AccessEntryFromURL() {
if (!access_entry_from_url_) {
access_entry_from_url_ = std::make_unique<OriginAccessEntry>(
Url().Protocol(), Url().Host(),
- OriginAccessEntry::kAllowRegisterableDomains);
+ network::cors::OriginAccessEntry::kAllowRegisterableDomains);
}
return *access_entry_from_url_;
}
@@ -5264,17 +5360,19 @@ void Document::setDomain(const String& raw_domain,
// string "null". https://crbug.com/733150
if (!RuntimeEnabledFeatures::NullableDocumentDomainEnabled() ||
new_domain != "null") {
- OriginAccessEntry access_entry(GetSecurityOrigin()->Protocol(), new_domain,
- OriginAccessEntry::kAllowSubdomains);
- OriginAccessEntry::MatchResult result =
+ OriginAccessEntry access_entry(
+ GetSecurityOrigin()->Protocol(), new_domain,
+ network::cors::OriginAccessEntry::kAllowSubdomains);
+ network::cors::OriginAccessEntry::MatchResult result =
access_entry.MatchesOrigin(*GetSecurityOrigin());
- if (result == OriginAccessEntry::kDoesNotMatchOrigin) {
+ if (result == network::cors::OriginAccessEntry::kDoesNotMatchOrigin) {
exception_state.ThrowSecurityError(
"'" + new_domain + "' is not a suffix of '" + domain() + "'.");
return;
}
- if (result == OriginAccessEntry::kMatchesOriginButIsPublicSuffix) {
+ if (result ==
+ network::cors::OriginAccessEntry::kMatchesOriginButIsPublicSuffix) {
exception_state.ThrowSecurityError("'" + new_domain +
"' is a top-level domain.");
return;
@@ -5359,12 +5457,16 @@ const KURL Document::SiteForCookies() const {
// document's SecurityOrigin. A sandboxed document has a unique opaque
// origin, but that shouldn't affect first-/third-party status for cookies
// and site data.
+ base::Optional<OriginAccessEntry> remote_entry;
+ if (!top.IsLocalFrame()) {
+ remote_entry.emplace(
+ top_document_url.Protocol(), top_document_url.Host(),
+ network::cors::OriginAccessEntry::kAllowRegisterableDomains);
+ }
const OriginAccessEntry& access_entry =
- top.IsLocalFrame()
- ? ToLocalFrame(top).GetDocument()->AccessEntryFromURL()
- : OriginAccessEntry(top_document_url.Protocol(),
- top_document_url.Host(),
- OriginAccessEntry::kAllowRegisterableDomains);
+ remote_entry ? *remote_entry
+ : ToLocalFrame(top).GetDocument()->AccessEntryFromURL();
+
const Frame* current_frame = GetFrame();
while (current_frame) {
// Skip over srcdoc documents, as they are always same-origin with their
@@ -5375,11 +5477,10 @@ const KURL Document::SiteForCookies() const {
DCHECK(current_frame);
// 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.
+ // login forms into HTTP pages; we should allow this kind of upgrade.
if (access_entry.MatchesDomain(
*current_frame->GetSecurityContext()->GetSecurityOrigin()) ==
- OriginAccessEntry::kDoesNotMatchOrigin)
+ network::cors::OriginAccessEntry::kDoesNotMatchOrigin)
return SecurityOrigin::UrlWithUniqueOpaqueOrigin();
current_frame = current_frame->Tree().Parent();
@@ -5861,7 +5962,7 @@ void Document::FinishedParsing() {
// dispatched in a queued task, see https://crbug.com/425790
if (document_timing_.DomContentLoadedEventStart().is_null())
document_timing_.MarkDomContentLoadedEventStart();
- DispatchEvent(Event::CreateBubble(EventTypeNames::DOMContentLoaded));
+ DispatchEvent(*Event::CreateBubble(EventTypeNames::DOMContentLoaded));
if (document_timing_.DomContentLoadedEventEnd().is_null())
document_timing_.MarkDomContentLoadedEventEnd();
SetParsingState(kFinishedParsing);
@@ -5928,8 +6029,6 @@ void Document::FinishedParsing() {
if (IsPrefetchOnly())
WebPrerenderingSupport::Current()->PrefetchFinished();
-
- FirstMeaningfulPaintDetector::From(*this).CheckNetworkStable();
}
void Document::ElementDataCacheClearTimerFired(TimerBase*) {
@@ -6084,6 +6183,10 @@ void Document::ApplyFeaturePolicy(const ParsedFeaturePolicy& declared_policy) {
InitializeFeaturePolicy(declared_policy, container_policy,
parent_feature_policy);
+ // At this point, the document will not have been installed in the frame's
+ // LocalDOMWindow, so we cannot call frame_->IsFeatureEnabled. This calls
+ // SecurityContext::IsFeatureEnabled instead, which cannot report, but we
+ // don't need reporting here in any case.
is_vertical_scroll_enforced_ =
RuntimeEnabledFeatures::ExperimentalProductivityFeaturesEnabled() &&
!GetFeaturePolicy()->IsFeatureEnabled(
@@ -6097,7 +6200,8 @@ bool Document::AllowedToUseDynamicMarkUpInsertion(
return true;
}
if (!frame_ ||
- frame_->IsFeatureEnabled(mojom::FeaturePolicyFeature::kDocumentWrite)) {
+ frame_->IsFeatureEnabled(mojom::FeaturePolicyFeature::kDocumentWrite,
+ ReportOptions::kReportOnFailure)) {
return true;
}
@@ -7396,6 +7500,7 @@ void Document::Trace(blink::Visitor* visitor) {
visitor->Trace(policy_);
visitor->Trace(slot_assignment_engine_);
visitor->Trace(viewport_data_);
+ visitor->Trace(lazy_load_image_observer_);
Supplementable<Document>::Trace(visitor);
TreeScope::Trace(visitor);
ContainerNode::Trace(visitor);
@@ -7442,6 +7547,22 @@ bool Document::NextFrameHasPendingRAF() const {
scripted_animation_controller_->NextFrameHasPendingRAF();
}
+void Document::NavigateLocalAdsFrames() {
+ // This navigates all the frames detected as an advertisement to about:blank.
+ DCHECK(frame_);
+ for (Frame* child = frame_->Tree().FirstChild(); child;
+ child = child->Tree().TraverseNext(frame_)) {
+ if (child->IsLocalFrame()) {
+ if (ToLocalFrame(child)->IsAdSubframe()) {
+ ToLocalFrame(child)->Navigate(
+ FrameLoadRequest(this, ResourceRequest(BlankURL())));
+ }
+ }
+ // TODO(yuzus): Once AdsTracker for remote frames is implemented and OOPIF
+ // is enabled on low-end devices, navigate remote ads as well.
+ }
+}
+
SlotAssignmentEngine& Document::GetSlotAssignmentEngine() {
if (!slot_assignment_engine_)
slot_assignment_engine_ = SlotAssignmentEngine::Create();
@@ -7458,6 +7579,12 @@ bool Document::IsSlotAssignmentOrLegacyDistributionDirty() {
return false;
}
+LazyLoadImageObserver& Document::EnsureLazyLoadImageObserver() {
+ if (!lazy_load_image_observer_)
+ lazy_load_image_observer_ = new LazyLoadImageObserver();
+ return *lazy_load_image_observer_;
+}
+
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 9fdbca84a36..a9c05b9bd37 100644
--- a/chromium/third_party/blink/renderer/core/dom/document.h
+++ b/chromium/third_party/blink/renderer/core/dom/document.h
@@ -36,10 +36,7 @@
#include "base/memory/scoped_refptr.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/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/css/css_style_sheet_init.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"
@@ -86,10 +83,12 @@ enum class PageVisibilityState : int32_t;
} // namespace mojom
class AnimationClock;
+class AXContext;
class AXObjectCache;
class Attr;
class CDATASection;
class CSSStyleSheet;
+class CSSStyleSheetInit;
class CanvasFontCache;
class ChromeClient;
class Comment;
@@ -138,6 +137,7 @@ class IntersectionObserverController;
class LayoutPoint;
class ReattachLegacyLayoutObjectList;
class LayoutView;
+class LazyLoadImageObserver;
class LiveNodeListBase;
class LocalDOMWindow;
class Locale;
@@ -159,6 +159,8 @@ class Range;
class ResizeObserverController;
class ResourceFetcher;
class RootScrollerController;
+class ScriptPromise;
+class ScriptValue;
class SVGDocumentExtensions;
class SVGUseElement;
class Text;
@@ -362,6 +364,12 @@ class CORE_EXPORT Document : public ContainerNode,
Element* CreateRawElement(const QualifiedName&,
const CreateElementFlags = CreateElementFlags());
+ CSSStyleSheet* createEmptyCSSStyleSheet(ScriptState*,
+ const CSSStyleSheetInit&,
+ ExceptionState&);
+
+ CSSStyleSheet* createEmptyCSSStyleSheet(ScriptState*, ExceptionState&);
+
ScriptPromise createCSSStyleSheet(ScriptState*,
const String&,
ExceptionState&);
@@ -586,9 +594,12 @@ class CORE_EXPORT Document : public ContainerNode,
LayoutView* GetLayoutView() const { return layout_view_; }
- Document& AXObjectCacheOwner() const;
+ // This will return an AXObjectCache only if there's one or more
+ // AXContext associated with this document. When all associated
+ // AXContexts are deleted, the AXObjectCache will be removed.
AXObjectCache* ExistingAXObjectCache() const;
- AXObjectCache* GetOrCreateAXObjectCache() const;
+
+ Document& AXObjectCacheOwner() const;
void ClearAXObjectCache();
// to get visually ordered hebrew and arabic pages right
@@ -702,6 +713,12 @@ class CORE_EXPORT Document : public ContainerNode,
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();
@@ -1427,6 +1444,7 @@ class CORE_EXPORT Document : public ContainerNode,
StylePropertyMapReadOnly* ComputedStyleMap(Element*);
void AddComputedStyleMapItem(Element*, StylePropertyMapReadOnly*);
StylePropertyMapReadOnly* RemoveComputedStyleMapItem(Element*);
+ void NavigateLocalAdsFrames();
SlotAssignmentEngine& GetSlotAssignmentEngine();
@@ -1445,6 +1463,20 @@ class CORE_EXPORT Document : public ContainerNode,
bool IsVerticalScrollEnforced() const { return is_vertical_scroll_enforced_; }
+ LazyLoadImageObserver& EnsureLazyLoadImageObserver();
+
+ // TODO(binji): See http://crbug.com/798572. This implementation shares the
+ // same agent cluster ID for any one document. The proper implementation of
+ // this function must follow the rules described here:
+ // https://html.spec.whatwg.org/multipage/webappapis.html#integration-with-the-javascript-agent-cluster-formalism.
+ //
+ // Even with this simple implementation, we can prevent sharing
+ // SharedArrayBuffers and WebAssembly modules with workers that happen to be
+ // in the same process.
+ const base::UnguessableToken& GetAgentClusterID() const final {
+ return agent_cluster_id_;
+ }
+
protected:
Document(const DocumentInit&, DocumentClassFlags = kDefaultDocumentClass);
@@ -1462,11 +1494,16 @@ class CORE_EXPORT Document : public ContainerNode,
private:
friend class IgnoreDestructiveWriteCountIncrementer;
friend class ThrowOnDynamicMarkupInsertionCountIncrementer;
+ friend class IgnoreOpensDuringUnloadCountIncrementer;
friend class NthIndexCache;
FRIEND_TEST_ALL_PREFIXES(FrameFetchContextSubresourceFilterTest,
DuringOnFreeze);
class NetworkStateObserver;
+ friend class AXContext;
+ void AddAXContext(AXContext*);
+ void RemoveAXContext(AXContext*);
+
bool IsDocumentFragment() const =
delete; // This will catch anyone doing an unnecessary check.
bool IsDocumentNode() const =
@@ -1687,15 +1724,18 @@ class CORE_EXPORT Document : public ContainerNode,
bool contains_validity_style_rules_;
bool contains_plugins_;
- // http://www.whatwg.org/specs/web-apps/current-work/#ignore-destructive-writes-counter
+ // https://html.spec.whatwg.org/C/dynamic-markup-insertion.html#ignore-destructive-writes-counter
unsigned ignore_destructive_write_count_;
- // https://html.spec.whatwg.org/#throw-on-dynamic-markup-insertion-counter
+ // https://html.spec.whatwg.org/C/dynamic-markup-insertion.html#throw-on-dynamic-markup-insertion-counter
unsigned throw_on_dynamic_markup_insertion_count_;
+ // https://html.spec.whatwg.org/C/dynamic-markup-insertion.html#ignore-opens-during-unload-counter
+ unsigned ignore_opens_during_unload_count_;
String title_;
String raw_title_;
Member<Element> title_element_;
+ Vector<AXContext*> ax_contexts_;
Member<AXObjectCache> ax_object_cache_;
Member<DocumentMarkerController> markers_;
@@ -1871,6 +1911,11 @@ class CORE_EXPORT Document : public ContainerNode,
// This is set through feature policy 'vertical-scroll'.
bool is_vertical_scroll_enforced_ = false;
+
+ Member<LazyLoadImageObserver> lazy_load_image_observer_;
+
+ // https://tc39.github.io/ecma262/#sec-agent-clusters
+ const base::UnguessableToken agent_cluster_id_;
};
extern template class CORE_EXTERN_TEMPLATE_EXPORT Supplement<Document>;
diff --git a/chromium/third_party/blink/renderer/core/dom/document.idl b/chromium/third_party/blink/renderer/core/dom/document.idl
index 7f86ca16454..7956e34b566 100644
--- a/chromium/third_party/blink/renderer/core/dom/document.idl
+++ b/chromium/third_party/blink/renderer/core/dom/document.idl
@@ -76,6 +76,8 @@ typedef (HTMLScriptElement or SVGScriptElement) HTMLOrSVGScriptElement;
[NewObject] Range createRange();
[CallWith=ScriptState, NewObject, RaisesException, RuntimeEnabled=ConstructableStylesheets] Promise<CSSStyleSheet> createCSSStyleSheet(DOMString text, optional CSSStyleSheetInit options);
+ [CallWith=ScriptState, NewObject, RaisesException, RuntimeEnabled=ConstructableStylesheets] CSSStyleSheet createEmptyCSSStyleSheet(optional CSSStyleSheetInit options);
+
// NodeFilter.SHOW_ALL = 0xFFFFFFFF
[NewObject] NodeIterator createNodeIterator(Node root, optional unsigned long whatToShow = 0xFFFFFFFF, optional NodeFilter? filter = null);
@@ -172,7 +174,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, MeasureAs=DocumentRegisterElement] CustomElementConstructor registerElement(DOMString type, optional ElementRegistrationOptions options);
+ [RuntimeEnabled=CustomElementsV0, CallWith=ScriptState, CustomElementCallbacks, RaisesException, DeprecateAs=DocumentRegisterElement] CustomElementConstructor registerElement(DOMString type, optional ElementRegistrationOptions options);
// https://w3c.github.io/webcomponents/spec/custom/#extensions-to-document-interface-to-instantiate
// FIXME: The typeExtension arguments should not be nullable.
[CustomElementCallbacks, PerWorldBindings, RaisesException, ImplementedAs=CreateElementForBinding] Element createElement(DOMString localName, (DOMString or Dictionary)? options);
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 0dbe2895684..b1793b5c8bb 100644
--- a/chromium/third_party/blink/renderer/core/dom/document_init.cc
+++ b/chromium/third_party/blink/renderer/core/dom/document_init.cc
@@ -40,10 +40,11 @@
namespace blink {
// FIXME: Broken with OOPI.
-static Document* ParentDocument(LocalFrame* frame) {
- DCHECK(frame);
+static Document* ParentDocument(DocumentLoader* loader) {
+ DCHECK(loader);
+ DCHECK(loader->GetFrame());
- Element* owner_element = frame->DeprecatedLocalOwner();
+ Element* owner_element = loader->GetFrame()->DeprecatedLocalOwner();
if (!owner_element)
return nullptr;
return &owner_element->GetDocument();
@@ -71,33 +72,37 @@ DocumentInit::DocumentInit(const DocumentInit&) = default;
DocumentInit::~DocumentInit() = default;
bool DocumentInit::ShouldSetURL() const {
- LocalFrame* frame = FrameForSecurityContext();
- return (frame && frame->Tree().Parent()) || !url_.IsEmpty();
+ DocumentLoader* loader = MasterDocumentLoader();
+ return (loader && loader->GetFrame()->Tree().Parent()) || !url_.IsEmpty();
}
bool DocumentInit::ShouldTreatURLAsSrcdocDocument() const {
return parent_document_ &&
- frame_->Loader().ShouldTreatURLAsSrcdocDocument(url_);
-}
-
-LocalFrame* DocumentInit::FrameForSecurityContext() const {
- if (frame_)
- return frame_;
- if (imports_controller_)
- return imports_controller_->Master()->GetFrame();
+ document_loader_->GetFrame()->Loader().ShouldTreatURLAsSrcdocDocument(
+ url_);
+}
+
+DocumentLoader* DocumentInit::MasterDocumentLoader() const {
+ if (document_loader_)
+ return document_loader_;
+ if (imports_controller_) {
+ return imports_controller_->Master()
+ ->GetFrame()
+ ->Loader()
+ .GetDocumentLoader();
+ }
return nullptr;
}
SandboxFlags DocumentInit::GetSandboxFlags() const {
- DCHECK(FrameForSecurityContext());
- FrameLoader* loader = &FrameForSecurityContext()->Loader();
- SandboxFlags flags = loader->EffectiveSandboxFlags();
+ DCHECK(MasterDocumentLoader());
+ DocumentLoader* loader = MasterDocumentLoader();
+ SandboxFlags flags = loader->GetFrame()->Loader().EffectiveSandboxFlags();
// If the load was blocked by CSP, force the Document's origin to be unique,
// so that the blocked document appears to be a normal cross-origin document's
// load per CSP spec: https://www.w3.org/TR/CSP3/#directive-frame-ancestors.
- if (loader->GetDocumentLoader() &&
- loader->GetDocumentLoader()->WasBlockedAfterCSP()) {
+ if (loader->WasBlockedAfterCSP()) {
flags |= kSandboxOrigin;
}
@@ -105,48 +110,50 @@ SandboxFlags DocumentInit::GetSandboxFlags() const {
}
WebInsecureRequestPolicy DocumentInit::GetInsecureRequestPolicy() const {
- DCHECK(FrameForSecurityContext());
- return FrameForSecurityContext()->Loader().GetInsecureRequestPolicy();
+ DCHECK(MasterDocumentLoader());
+ Frame* parent_frame = MasterDocumentLoader()->GetFrame()->Tree().Parent();
+ if (!parent_frame)
+ return kLeaveInsecureRequestsAlone;
+ return parent_frame->GetSecurityContext()->GetInsecureRequestPolicy();
}
SecurityContext::InsecureNavigationsSet*
DocumentInit::InsecureNavigationsToUpgrade() const {
- DCHECK(FrameForSecurityContext());
- return FrameForSecurityContext()->Loader().InsecureNavigationsToUpgrade();
+ DCHECK(MasterDocumentLoader());
+ Frame* parent_frame = MasterDocumentLoader()->GetFrame()->Tree().Parent();
+ if (!parent_frame)
+ return nullptr;
+ return parent_frame->GetSecurityContext()->InsecureNavigationsToUpgrade();
}
bool DocumentInit::IsHostedInReservedIPRange() const {
- if (LocalFrame* frame = FrameForSecurityContext()) {
- if (DocumentLoader* loader =
- frame->Loader().GetProvisionalDocumentLoader()
- ? frame->Loader().GetProvisionalDocumentLoader()
- : frame->Loader().GetDocumentLoader()) {
- if (!loader->GetResponse().RemoteIPAddress().IsEmpty())
- return NetworkUtils::IsReservedIPAddress(
- loader->GetResponse().RemoteIPAddress());
+ if (DocumentLoader* loader = MasterDocumentLoader()) {
+ if (!loader->GetResponse().RemoteIPAddress().IsEmpty()) {
+ return NetworkUtils::IsReservedIPAddress(
+ loader->GetResponse().RemoteIPAddress());
}
}
return false;
}
Settings* DocumentInit::GetSettings() const {
- DCHECK(FrameForSecurityContext());
- return FrameForSecurityContext()->GetSettings();
+ DCHECK(MasterDocumentLoader());
+ return MasterDocumentLoader()->GetFrame()->GetSettings();
}
-KURL DocumentInit::ParentBaseURL() const {
- return parent_document_->BaseURL();
-}
-
-DocumentInit& DocumentInit::WithFrame(LocalFrame* frame) {
- DCHECK(!frame_);
+DocumentInit& DocumentInit::WithDocumentLoader(DocumentLoader* loader) {
+ DCHECK(!document_loader_);
DCHECK(!imports_controller_);
- frame_ = frame;
- if (frame_)
- parent_document_ = ParentDocument(frame_);
+ document_loader_ = loader;
+ if (document_loader_)
+ parent_document_ = ParentDocument(document_loader_);
return *this;
}
+LocalFrame* DocumentInit::GetFrame() const {
+ return document_loader_ ? document_loader_->GetFrame() : nullptr;
+}
+
DocumentInit& DocumentInit::WithContextDocument(Document* context_document) {
DCHECK(!context_document_);
context_document_ = context_document;
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 6ebf5351f89..e3d0dff0d3d 100644
--- a/chromium/third_party/blink/renderer/core/dom/document_init.h
+++ b/chromium/third_party/blink/renderer/core/dom/document_init.h
@@ -41,6 +41,7 @@
namespace blink {
class Document;
+class DocumentLoader;
class LocalFrame;
class HTMLImportsController;
class Settings;
@@ -56,7 +57,7 @@ class CORE_EXPORT DocumentInit final {
// Example:
//
// DocumentInit init = DocumentInit::Create()
- // .WithFrame(frame)
+ // .WithDocumentLoader(loader)
// .WithContextDocument(context_document)
// .WithURL(url);
// Document* document = Document::Create(init);
@@ -70,21 +71,18 @@ class CORE_EXPORT DocumentInit final {
return imports_controller_;
}
- bool HasSecurityContext() const { return FrameForSecurityContext(); }
+ bool HasSecurityContext() const { return MasterDocumentLoader(); }
bool ShouldTreatURLAsSrcdocDocument() const;
bool ShouldSetURL() const;
- bool IsSeamlessAllowedFor(Document* child) const;
SandboxFlags GetSandboxFlags() const;
bool IsHostedInReservedIPRange() const;
WebInsecureRequestPolicy GetInsecureRequestPolicy() const;
SecurityContext::InsecureNavigationsSet* InsecureNavigationsToUpgrade() const;
- KURL ParentBaseURL() const;
- LocalFrame* OwnerFrame() const;
Settings* GetSettings() const;
- DocumentInit& WithFrame(LocalFrame*);
- LocalFrame* GetFrame() const { return frame_; }
+ DocumentInit& WithDocumentLoader(DocumentLoader*);
+ LocalFrame* GetFrame() const;
// Used by the DOMImplementation and DOMParser to pass their parent Document
// so that the created Document will return the Document when the
@@ -106,9 +104,13 @@ class CORE_EXPORT DocumentInit final {
private:
DocumentInit(HTMLImportsController*);
- LocalFrame* FrameForSecurityContext() const;
+ // For a Document associated directly with a frame, this will be the
+ // DocumentLoader driving the commit. For an import, XSLT-generated
+ // document, etc., it will be the DocumentLoader that drove the commit
+ // of its owning Document.
+ DocumentLoader* MasterDocumentLoader() const;
- Member<LocalFrame> frame_;
+ Member<DocumentLoader> document_loader_;
Member<Document> parent_document_;
Member<HTMLImportsController> imports_controller_;
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 723e114dc87..5dd461ec82f 100644
--- a/chromium/third_party/blink/renderer/core/dom/document_test.cc
+++ b/chromium/third_party/blink/renderer/core/dom/document_test.cc
@@ -812,7 +812,7 @@ TEST_F(DocumentTest, ValidationMessageCleanup) {
MockDocumentValidationMessageClient* mock_client =
new MockDocumentValidationMessageClient();
GetDocument().GetSettings()->SetScriptEnabled(true);
- GetPage().SetValidationMessageClient(mock_client);
+ GetPage().SetValidationMessageClientForTesting(mock_client);
// ImplicitOpen()-CancelParsing() makes Document.loadEventFinished()
// true. It's necessary to kick unload process.
GetDocument().ImplicitOpen(kForceSynchronousParsing);
@@ -839,7 +839,7 @@ TEST_F(DocumentTest, ValidationMessageCleanup) {
// Unload handler tried to show a validation message, but it should fail.
EXPECT_FALSE(mock_client->show_validation_message_was_called);
- GetPage().SetValidationMessageClient(original_client);
+ GetPage().SetValidationMessageClientForTesting(original_client);
}
TEST_F(DocumentTest, SandboxDisablesAppCache) {
diff --git a/chromium/third_party/blink/renderer/core/dom/document_type.cc b/chromium/third_party/blink/renderer/core/dom/document_type.cc
index 805509670c0..e28838c6399 100644
--- a/chromium/third_party/blink/renderer/core/dom/document_type.cc
+++ b/chromium/third_party/blink/renderer/core/dom/document_type.cc
@@ -49,7 +49,7 @@ Node* DocumentType::Clone(Document& factory, CloneChildrenFlag) const {
}
Node::InsertionNotificationRequest DocumentType::InsertedInto(
- ContainerNode* insertion_point) {
+ ContainerNode& insertion_point) {
Node::InsertedInto(insertion_point);
// DocumentType can only be inserted into a Document.
@@ -60,7 +60,7 @@ Node::InsertionNotificationRequest DocumentType::InsertedInto(
return kInsertionDone;
}
-void DocumentType::RemovedFrom(ContainerNode* insertion_point) {
+void DocumentType::RemovedFrom(ContainerNode& insertion_point) {
GetDocument().SetDoctype(nullptr);
Node::RemovedFrom(insertion_point);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/document_type.h b/chromium/third_party/blink/renderer/core/dom/document_type.h
index 229d94530f9..2a3648cf904 100644
--- a/chromium/third_party/blink/renderer/core/dom/document_type.h
+++ b/chromium/third_party/blink/renderer/core/dom/document_type.h
@@ -53,8 +53,9 @@ class DocumentType final : public Node {
NodeType getNodeType() const override;
Node* Clone(Document&, CloneChildrenFlag) const override;
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
- void RemovedFrom(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
+ void RemovedFrom(ContainerNode&) override;
+ void DetachLayoutTree(const AttachContext&) final {}
String name_;
String public_id_;
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 a2fbf84747a..c360933eb10 100644
--- a/chromium/third_party/blink/renderer/core/dom/dom_implementation.cc
+++ b/chromium/third_party/blink/renderer/core/dom/dom_implementation.cc
@@ -262,8 +262,10 @@ Document* DOMImplementation::createDocument(const String& type,
init, plugin_data->PluginBackgroundColorForMimeType(type));
}
// multipart/x-mixed-replace is only supported for images.
- if (Image::SupportsType(type) || type == "multipart/x-mixed-replace")
+ if (MIMETypeRegistry::IsSupportedImageResourceMIMEType(type) ||
+ type == "multipart/x-mixed-replace") {
return ImageDocument::Create(init);
+ }
// Check to see if the type can be played by our media player, if so create a
// MediaDocument
diff --git a/chromium/third_party/blink/renderer/core/dom/dom_string_list.cc b/chromium/third_party/blink/renderer/core/dom/dom_string_list.cc
index 6d85109886b..b68fd084575 100644
--- a/chromium/third_party/blink/renderer/core/dom/dom_string_list.cc
+++ b/chromium/third_party/blink/renderer/core/dom/dom_string_list.cc
@@ -29,7 +29,7 @@
namespace blink {
-String DOMStringList::item(unsigned index) const {
+String DOMStringList::item(uint32_t index) const {
if (index >= strings_.size())
return String();
return strings_[index];
diff --git a/chromium/third_party/blink/renderer/core/dom/dom_string_list.h b/chromium/third_party/blink/renderer/core/dom/dom_string_list.h
index 903f3a25141..adb66dfa73f 100644
--- a/chromium/third_party/blink/renderer/core/dom/dom_string_list.h
+++ b/chromium/third_party/blink/renderer/core/dom/dom_string_list.h
@@ -48,9 +48,9 @@ class CORE_EXPORT DOMStringList final : public ScriptWrappable {
void Sort();
// Implements the IDL.
- size_t length() const { return strings_.size(); }
+ uint32_t length() const { return strings_.size(); }
- String item(unsigned index) const;
+ String item(uint32_t index) const;
bool contains(const String&) const;
operator const Vector<String>&() const { return strings_; }
diff --git a/chromium/third_party/blink/renderer/core/dom/element.cc b/chromium/third_party/blink/renderer/core/dom/element.cc
index 54a70a4fd9d..9ebd8b8d797 100644
--- a/chromium/third_party/blink/renderer/core/dom/element.cc
+++ b/chromium/third_party/blink/renderer/core/dom/element.cc
@@ -34,6 +34,7 @@
#include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_html.h"
#include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_script_url.h"
#include "third_party/blink/renderer/bindings/core/v8/usv_string_or_trusted_url.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"
#include "third_party/blink/renderer/core/aom/computed_accessible_node.h"
@@ -81,7 +82,6 @@
#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/frame_selection.h"
-#include "third_party/blink/renderer/core/editing/iterators/text_iterator.h"
#include "third_party/blink/renderer/core/editing/selection_template.h"
#include "third_party/blink/renderer/core/editing/serializers/serialization.h"
#include "third_party/blink/renderer/core/editing/set_selection_options.h"
@@ -119,6 +119,7 @@
#include "third_party/blink/renderer/core/html/parser/nesting_level_incrementer.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/invisible_dom/activate_invisible_event.h"
#include "third_party/blink/renderer/core/layout/adjust_for_absolute_zoom.h"
#include "third_party/blink/renderer/core/layout/layout_text_fragment.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
@@ -139,6 +140,8 @@
#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_observation.h"
+#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
+#include "third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.h"
#include "third_party/blink/renderer/core/svg/svg_a_element.h"
#include "third_party/blink/renderer/core/svg/svg_element.h"
#include "third_party/blink/renderer/core/svg_names.h"
@@ -153,8 +156,6 @@
#include "third_party/blink/renderer/platform/bindings/v8_per_context_data.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/scroll/scrollable_area.h"
-#include "third_party/blink/renderer/platform/scroll/smooth_scroll_sequencer.h"
#include "third_party/blink/renderer/platform/wtf/bit_vector.h"
#include "third_party/blink/renderer/platform/wtf/hash_functions.h"
#include "third_party/blink/renderer/platform/wtf/text/cstring.h"
@@ -1403,17 +1404,21 @@ DOMRect* Element::getBoundingClientRect() {
}
const AtomicString& Element::computedRole() {
- GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
- std::unique_ptr<ScopedAXObjectCache> cache =
- ScopedAXObjectCache::Create(GetDocument());
- return cache->Get()->ComputedRoleForNode(this);
+ Document& document = GetDocument();
+ if (!document.IsActive())
+ return g_null_atom;
+ document.UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+ AXContext ax_context(document);
+ return ax_context.GetAXObjectCache().ComputedRoleForNode(this);
}
String Element::computedName() {
- GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
- std::unique_ptr<ScopedAXObjectCache> cache =
- ScopedAXObjectCache::Create(GetDocument());
- return cache->Get()->ComputedNameForNode(this);
+ Document& document = GetDocument();
+ if (!document.IsActive())
+ return String();
+ document.UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+ AXContext ax_context(document);
+ return ax_context.GetAXObjectCache().ComputedNameForNode(this);
}
AccessibleNode* Element::ExistingAccessibleNode() const {
@@ -1434,6 +1439,57 @@ AccessibleNode* Element::accessibleNode() {
return rare_data.EnsureAccessibleNode(this);
}
+const AtomicString& Element::invisible() const {
+ return FastGetAttribute(invisibleAttr);
+}
+
+void Element::setInvisible(const AtomicString& value) {
+ setAttribute(invisibleAttr, value);
+}
+
+void Element::DispatchActivateInvisibleEventIfNeeded() {
+ if (!RuntimeEnabledFeatures::InvisibleDOMEnabled())
+ return;
+ // Traverse all inclusive flat-tree ancestor and send activateinvisible
+ // on the ones that have the invisible attribute. Default event handler
+ // will remove invisible attribute of all invisible element if the event is
+ // not canceled, making this element and all ancestors visible again.
+ // We're saving them and the retargeted activated element as DOM structure
+ // may change due to event handlers.
+ HeapVector<Member<Element>> invisible_ancestors;
+ HeapVector<Member<Element>> activated_elements;
+ for (Node& ancestor : FlatTreeTraversal::InclusiveAncestorsOf(*this)) {
+ if (ancestor.IsElementNode() && ToElement(ancestor).invisible()) {
+ invisible_ancestors.push_back(ToElement(ancestor));
+ activated_elements.push_back(ancestor.GetTreeScope().Retarget(*this));
+ }
+ }
+ auto* activated_element_iterator = activated_elements.begin();
+ for (Element* ancestor : invisible_ancestors) {
+ DCHECK(activated_element_iterator != activated_elements.end());
+ ancestor->DispatchEvent(
+ *ActivateInvisibleEvent::Create(*activated_element_iterator));
+ ++activated_element_iterator;
+ }
+}
+
+void Element::InvisibleAttributeChanged() {
+ SetNeedsStyleRecalc(
+ kLocalStyleChange,
+ StyleChangeReasonForTracing::Create(StyleChangeReason::kInvisibleChange));
+}
+
+void Element::DefaultEventHandler(Event& event) {
+ if (RuntimeEnabledFeatures::InvisibleDOMEnabled() &&
+ event.type() == EventTypeNames::activateinvisible &&
+ event.target() == this) {
+ removeAttribute(invisibleAttr);
+ event.SetDefaultHandled();
+ return;
+ }
+ ContainerNode::DefaultEventHandler(event);
+}
+
bool Element::toggleAttribute(const AtomicString& qualified_name,
ExceptionState& exception_state) {
// https://dom.spec.whatwg.org/#dom-element-toggleattribute
@@ -1581,19 +1637,11 @@ void Element::SetSynchronizedLazyAttribute(const QualifiedName& name,
void Element::setAttribute(const QualifiedName& name,
const StringOrTrustedHTML& stringOrHTML,
ExceptionState& exception_state) {
- DCHECK(stringOrHTML.IsString() ||
- RuntimeEnabledFeatures::TrustedDOMTypesEnabled());
- if (stringOrHTML.IsString() && GetDocument().RequireTrustedTypes()) {
- exception_state.ThrowTypeError(
- "This document requires `TrustedHTML` assignment.");
- return;
+ String valueString =
+ TrustedHTML::GetString(stringOrHTML, &GetDocument(), exception_state);
+ if (!exception_state.HadException()) {
+ setAttribute(name, AtomicString(valueString));
}
-
- String valueString = stringOrHTML.IsString()
- ? stringOrHTML.GetAsString()
- : stringOrHTML.GetAsTrustedHTML()->toString();
-
- setAttribute(name, AtomicString(valueString));
}
void Element::setAttribute(const QualifiedName& name,
@@ -1617,19 +1665,11 @@ void Element::setAttribute(const QualifiedName& name,
void Element::setAttribute(const QualifiedName& name,
const USVStringOrTrustedURL& stringOrURL,
ExceptionState& exception_state) {
- DCHECK(stringOrURL.IsUSVString() ||
- RuntimeEnabledFeatures::TrustedDOMTypesEnabled());
- if (stringOrURL.IsUSVString() && GetDocument().RequireTrustedTypes()) {
- exception_state.ThrowTypeError(
- "This document requires `TrustedURL` assignment.");
- return;
+ String url =
+ TrustedURL::GetString(stringOrURL, &GetDocument(), exception_state);
+ if (!exception_state.HadException()) {
+ setAttribute(name, AtomicString(url));
}
-
- String valueString = stringOrURL.IsUSVString()
- ? stringOrURL.GetAsUSVString()
- : stringOrURL.GetAsTrustedURL()->toString();
-
- setAttribute(name, AtomicString(valueString));
}
ALWAYS_INLINE void Element::SetAttributeInternal(
@@ -1722,6 +1762,10 @@ void Element::AttributeChanged(const AttributeModificationParams& params) {
GetElementData()->presentation_attribute_style_is_dirty_ = true;
SetNeedsStyleRecalc(kLocalStyleChange,
StyleChangeReasonForTracing::FromAttribute(name));
+ } else if (RuntimeEnabledFeatures::InvisibleDOMEnabled() &&
+ name == HTMLNames::invisibleAttr &&
+ params.old_value.IsNull() != params.new_value.IsNull()) {
+ InvisibleAttributeChanged();
}
}
@@ -1969,14 +2013,14 @@ LayoutObject* Element::CreateLayoutObject(const ComputedStyle& style) {
}
Node::InsertionNotificationRequest Element::InsertedInto(
- ContainerNode* insertion_point) {
+ ContainerNode& insertion_point) {
// need to do superclass processing first so isConnected() is true
// by the time we reach updateId
ContainerNode::InsertedInto(insertion_point);
DCHECK(!HasRareData() || !GetElementRareData()->HasPseudoElements());
- if (!insertion_point->IsInTreeScope())
+ if (!insertion_point.IsInTreeScope())
return kInsertionDone;
if (HasRareData()) {
@@ -1995,7 +2039,7 @@ Node::InsertionNotificationRequest Element::InsertedInto(
CustomElement::TryToUpgrade(this);
}
- TreeScope& scope = insertion_point->GetTreeScope();
+ TreeScope& scope = insertion_point.GetTreeScope();
if (scope != GetTreeScope())
return kInsertionDone;
@@ -2013,8 +2057,8 @@ Node::InsertionNotificationRequest Element::InsertedInto(
return kInsertionDone;
}
-void Element::RemovedFrom(ContainerNode* insertion_point) {
- bool was_in_document = insertion_point->isConnected();
+void Element::RemovedFrom(ContainerNode& insertion_point) {
+ bool was_in_document = insertion_point.isConnected();
if (HasRareData()) {
// If we detached the layout tree with LazyReattachIfAttached, we might not
// have cleared the pseudo elements if we remove the element before calling
@@ -2026,10 +2070,10 @@ void Element::RemovedFrom(ContainerNode* insertion_point) {
if (Fullscreen::IsFullscreenElement(*this)) {
SetContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(false);
- if (insertion_point->IsElementNode()) {
- ToElement(insertion_point)->SetContainsFullScreenElement(false);
+ if (insertion_point.IsElementNode()) {
+ ToElement(insertion_point).SetContainsFullScreenElement(false);
ToElement(insertion_point)
- ->SetContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(
+ .SetContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(
false);
}
}
@@ -2039,10 +2083,10 @@ void Element::RemovedFrom(ContainerNode* insertion_point) {
SetSavedLayerScrollOffset(ScrollOffset());
- if (insertion_point->IsInTreeScope() && GetTreeScope() == GetDocument()) {
+ if (insertion_point.IsInTreeScope() && GetTreeScope() == GetDocument()) {
const AtomicString& id_value = GetIdAttribute();
if (!id_value.IsNull())
- UpdateId(insertion_point->GetTreeScope(), id_value, g_null_atom);
+ UpdateId(insertion_point.GetTreeScope(), id_value, g_null_atom);
const AtomicString& name_value = GetNameAttribute();
if (!name_value.IsNull())
@@ -2057,7 +2101,7 @@ void Element::RemovedFrom(ContainerNode* insertion_point) {
if (GetCustomElementState() == CustomElementState::kCustom)
CustomElement::EnqueueDisconnectedCallback(this);
else if (IsUpgradedV0CustomElement())
- V0CustomElement::DidDetach(this, insertion_point->GetDocument());
+ V0CustomElement::DidDetach(this, insertion_point.GetDocument());
if (NeedsStyleInvalidation()) {
GetDocument()
@@ -2130,8 +2174,6 @@ void Element::AttachLayoutTree(AttachContext& context) {
rare_data->ClearPseudoElements();
}
- SelectorFilterParentScope filter_scope(*this);
-
AttachContext children_context(context);
LayoutObject* layout_object = GetLayoutObject();
@@ -2155,16 +2197,8 @@ void Element::AttachLayoutTree(AttachContext& context) {
AttachPseudoElement(kPseudoIdAfter, children_context);
AttachPseudoElement(kPseudoIdBackdrop, children_context);
- // We create the first-letter element after the :before, :after and
- // children are attached because the first letter text could come
- // from any of them.
- //
- // TODO(futhark@chromium.org: Replace with AttachPseudoElement when we create
- // ::first-letter elements during style recalc.
- if (PseudoElement* first_letter =
- CreatePseudoElementIfNeeded(kPseudoIdFirstLetter)) {
- first_letter->AttachLayoutTree(children_context);
- }
+ UpdateFirstLetterPseudoElement(StyleUpdatePhase::kAttachLayoutTree);
+ AttachPseudoElement(kPseudoIdFirstLetter, children_context);
if (layout_object) {
if (!layout_object->IsFloatingOrOutOfFlowPositioned())
@@ -2180,9 +2214,7 @@ void Element::DetachLayoutTree(const AttachContext& context) {
RemoveCallbackSelectors();
if (HasRareData()) {
ElementRareData* data = GetElementRareData();
- if (context.performing_reattach)
- data->SetPseudoElement(kPseudoIdFirstLetter, nullptr);
- else
+ if (!context.performing_reattach)
data->ClearPseudoElements();
// attachLayoutTree() will clear the computed style for us when inside
@@ -2217,6 +2249,7 @@ void Element::DetachLayoutTree(const AttachContext& context) {
DetachPseudoElement(kPseudoIdAfter, context);
DetachPseudoElement(kPseudoIdBackdrop, context);
+ DetachPseudoElement(kPseudoIdFirstLetter, context);
if (!context.performing_reattach && IsUserActionElement()) {
if (IsHovered())
@@ -2251,8 +2284,7 @@ scoped_refptr<ComputedStyle> Element::StyleForLayoutObject() {
? CustomStyleForLayoutObject()
: OriginalStyleForLayoutObject();
if (!style) {
- DCHECK(IsBeforePseudoElement() || IsAfterPseudoElement() ||
- GetPseudoId() == kPseudoIdBackdrop);
+ DCHECK(IsPseudoElement());
return nullptr;
}
@@ -2299,7 +2331,16 @@ bool Element::ShouldCallRecalcStyleForChildren(StyleRecalcChange change) {
void Element::RecalcStyle(StyleRecalcChange change) {
DCHECK(GetDocument().InStyleRecalc());
DCHECK(!GetDocument().Lifecycle().InDetach());
- DCHECK(!ParentOrShadowHostNode()->NeedsStyleRecalc());
+ // If we are re-attaching in a Shadow DOM v0 tree, we recalc down to the
+ // distributed nodes to propagate kReattach down the flat tree (See
+ // V0InsertionPoint::DidRecalcStyle). That means we may have a shadow-
+ // including parent (V0InsertionPoint) with dirty recalc bit in the case where
+ // fallback content has been redistributed to a different insertion point.
+ // This will not happen for Shadow DOM v1 because we walk assigned nodes and
+ // slots themselves are assigned and part of the flat tree.
+ DCHECK(
+ !ParentOrShadowHostNode()->NeedsStyleRecalc() ||
+ (ParentOrShadowHostNode()->IsV0InsertionPoint() && change == kReattach));
DCHECK(InActiveDocument());
if (HasCustomStyleCallbacks())
@@ -2348,6 +2389,8 @@ void Element::RecalcStyle(StyleRecalcChange change) {
change = kReattach;
if (change == kReattach)
SetNeedsReattachLayoutTree();
+ else if (GetStyleChangeType() == kSubtreeStyleChange)
+ change = kForce;
}
// Needed because the RebuildLayoutTree code needs to see what the
@@ -2365,14 +2408,11 @@ void Element::RecalcStyle(StyleRecalcChange change) {
}
if (ShouldCallRecalcStyleForChildren(change)) {
- // TODO(futhark@chromium.org): Pseudo elements are feature-less and match
- // the same features as their originating element. Move the filter scope
- // inside the if-block for shadow-including descendants below.
- SelectorFilterParentScope filter_scope(*this);
UpdatePseudoElement(kPseudoIdBefore, change);
if (change > kUpdatePseudoElements || ChildNeedsStyleRecalc()) {
+ SelectorFilterParentScope filter_scope(*this);
if (ShadowRoot* root = GetShadowRoot()) {
if (root->ShouldCallRecalcStyle(change))
root->RecalcStyle(change);
@@ -2382,13 +2422,11 @@ void Element::RecalcStyle(StyleRecalcChange change) {
UpdatePseudoElement(kPseudoIdAfter, change);
- // If our children have changed then we need to force the first-letter
- // checks as we don't know if they effected the first letter or not.
- // This can be seen when a child transitions from floating to
- // non-floating we have to take it into account for the first letter.
- UpdatePseudoElement(
- kPseudoIdFirstLetter,
- change < kForce && ChildNeedsStyleRecalc() ? kForce : change);
+ // If we are re-attaching us or any of our descendants, we need to attach
+ // the descendants before we know if this element generates a ::first-letter
+ // and which element the ::first-letter inherits style from.
+ if (change < kReattach && !ChildNeedsReattachLayoutTree())
+ UpdateFirstLetterPseudoElement(StyleUpdatePhase::kRecalc);
ClearChildNeedsStyleRecalc();
}
@@ -2421,7 +2459,6 @@ scoped_refptr<ComputedStyle> Element::PropagateInheritedProperties(
StyleRecalcChange Element::RecalcOwnStyle(StyleRecalcChange change) {
DCHECK(GetDocument().InStyleRecalc());
- DCHECK(!ParentOrShadowHostNode()->NeedsStyleRecalc());
DCHECK(change >= kIndependentInherit || NeedsStyleRecalc());
DCHECK(ParentComputedStyle());
DCHECK(!GetNonAttachedStyle());
@@ -2519,7 +2556,6 @@ void Element::RebuildLayoutTree(WhitespaceAttacher& whitespace_attacher) {
whitespace_attacher.DidReattachElement(this,
reattach_context.previous_in_flow);
} else {
- SelectorFilterParentScope filter_scope(*this);
// We create a local WhitespaceAttacher when rebuilding children of an
// element with a LayoutObject since whitespace nodes do not rely on layout
// objects further up the tree. Also, if this Element's layout object is an
@@ -2545,7 +2581,8 @@ void Element::RebuildLayoutTree(WhitespaceAttacher& whitespace_attacher) {
RebuildChildrenLayoutTrees(*child_attacher);
RebuildPseudoElementLayoutTree(kPseudoIdBefore, *child_attacher);
RebuildPseudoElementLayoutTree(kPseudoIdBackdrop, *child_attacher);
- RebuildPseudoElementLayoutTree(kPseudoIdFirstLetter, *child_attacher);
+ RebuildFirstLetterLayoutTree();
+ ClearChildNeedsReattachLayoutTree();
}
DCHECK(!NeedsStyleRecalc());
DCHECK(!ChildNeedsStyleRecalc());
@@ -2565,30 +2602,33 @@ void Element::RebuildShadowRootLayoutTree(
void Element::RebuildPseudoElementLayoutTree(
PseudoId pseudo_id,
WhitespaceAttacher& whitespace_attacher) {
- PseudoElement* element = GetPseudoElement(pseudo_id);
- if (pseudo_id == kPseudoIdFirstLetter) {
- // Need to create a ::first-letter element here for the following case:
- //
- // <style>#outer::first-letter {...}</style>
- // <div id=outer><div id=inner style="display:none">Text</div></div>
- // <script> outer.offsetTop; inner.style.display = "block" </script>
- //
- // The creation of FirstLetterPseudoElement relies on the layout tree of the
- // block contents. In this case, the ::first-letter element is not created
- // initially since the #inner div is not displayed. On RecalcStyle it's not
- // created since the layout tree is still not built, and AttachLayoutTree
- // for #inner will not update the ::first-letter of outer. However, we end
- // up here for #outer after AttachLayoutTree is called on #inner at which
- // point the layout sub-tree is available for deciding on creating the
- // ::first-letter.
- if (!element)
- element = CreatePseudoElementIfNeeded(pseudo_id);
- else if (UpdateFirstLetter(element))
- return;
+ if (PseudoElement* element = GetPseudoElement(pseudo_id)) {
+ if (element->NeedsRebuildLayoutTree(whitespace_attacher))
+ element->RebuildLayoutTree(whitespace_attacher);
}
+}
- if (element && element->NeedsRebuildLayoutTree(whitespace_attacher))
- element->RebuildLayoutTree(whitespace_attacher);
+void Element::RebuildFirstLetterLayoutTree() {
+ // Need to create a ::first-letter element here for the following case:
+ //
+ // <style>#outer::first-letter {...}</style>
+ // <div id=outer><div id=inner style="display:none">Text</div></div>
+ // <script> outer.offsetTop; inner.style.display = "block" </script>
+ //
+ // The creation of FirstLetterPseudoElement relies on the layout tree of the
+ // block contents. In this case, the ::first-letter element is not created
+ // initially since the #inner div is not displayed. On RecalcStyle it's not
+ // created since the layout tree is still not built, and AttachLayoutTree
+ // for #inner will not update the ::first-letter of outer. However, we end
+ // up here for #outer after AttachLayoutTree is called on #inner at which
+ // point the layout sub-tree is available for deciding on creating the
+ // ::first-letter.
+ UpdateFirstLetterPseudoElement(StyleUpdatePhase::kRebuildLayoutTree);
+ if (PseudoElement* element = GetPseudoElement(kPseudoIdFirstLetter)) {
+ WhitespaceAttacher whitespace_attacher;
+ if (element->NeedsRebuildLayoutTree(whitespace_attacher))
+ element->RebuildLayoutTree(whitespace_attacher);
+ }
}
void Element::UpdateCallbackSelectors(const ComputedStyle* old_style,
@@ -2642,7 +2682,7 @@ ShadowRoot& Element::CreateAndAttachShadowRoot(ShadowRootType type) {
shadow_root->SetNeedsDistributionRecalc();
}
- shadow_root->InsertedInto(this);
+ shadow_root->InsertedInto(*this);
SetChildNeedsStyleRecalc();
SetNeedsStyleRecalc(kSubtreeStyleChange, StyleChangeReasonForTracing::Create(
StyleChangeReason::kShadow));
@@ -2827,7 +2867,8 @@ 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();
- return &AttachShadowRootInternal(type, delegates_focus);
+ bool manual_slotting = shadow_root_init_dict.slotting() == "manual";
+ return &AttachShadowRootInternal(type, delegates_focus, manual_slotting);
}
ShadowRoot& Element::CreateShadowRootInternal() {
@@ -2844,7 +2885,8 @@ ShadowRoot& Element::CreateUserAgentShadowRoot() {
}
ShadowRoot& Element::AttachShadowRootInternal(ShadowRootType type,
- bool delegates_focus) {
+ bool delegates_focus,
+ bool manual_slotting) {
// SVG <use> is a special case for using this API to create a closed shadow
// root.
DCHECK(CanAttachShadowRoot() || IsSVGUseElement(*this));
@@ -2855,6 +2897,8 @@ 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);
return shadow_root;
}
@@ -2955,7 +2999,6 @@ void Element::ChildrenChanged(const ChildrenChange& change) {
ToElement(change.sibling_changed), change.sibling_before_change,
change.sibling_after_change);
- // TODO(hayato): Confirm that we can skip this if a shadow tree is v1.
if (ShadowRoot* shadow_root = GetShadowRoot())
shadow_root->SetNeedsDistributionRecalcWillBeSetNeedsAssignmentRecalc();
}
@@ -3400,17 +3443,17 @@ Element* Element::AdjustedFocusedElementInTreeScope() const {
void Element::DispatchFocusEvent(Element* old_focused_element,
WebFocusType type,
InputDeviceCapabilities* source_capabilities) {
- DispatchEvent(FocusEvent::Create(EventTypeNames::focus, Event::Bubbles::kNo,
- GetDocument().domWindow(), 0,
- old_focused_element, source_capabilities));
+ DispatchEvent(*FocusEvent::Create(EventTypeNames::focus, Event::Bubbles::kNo,
+ GetDocument().domWindow(), 0,
+ old_focused_element, source_capabilities));
}
void Element::DispatchBlurEvent(Element* new_focused_element,
WebFocusType type,
InputDeviceCapabilities* source_capabilities) {
- DispatchEvent(FocusEvent::Create(EventTypeNames::blur, Event::Bubbles::kNo,
- GetDocument().domWindow(), 0,
- new_focused_element, source_capabilities));
+ DispatchEvent(*FocusEvent::Create(EventTypeNames::blur, Event::Bubbles::kNo,
+ GetDocument().domWindow(), 0,
+ new_focused_element, source_capabilities));
}
void Element::DispatchFocusInEvent(
@@ -3423,7 +3466,7 @@ void Element::DispatchFocusInEvent(
#endif
DCHECK(event_type == EventTypeNames::focusin ||
event_type == EventTypeNames::DOMFocusIn);
- DispatchScopedEvent(FocusEvent::Create(
+ DispatchScopedEvent(*FocusEvent::Create(
event_type, Event::Bubbles::kYes, GetDocument().domWindow(), 0,
old_focused_element, source_capabilities));
}
@@ -3437,7 +3480,7 @@ void Element::DispatchFocusOutEvent(
#endif
DCHECK(event_type == EventTypeNames::focusout ||
event_type == EventTypeNames::DOMFocusOut);
- DispatchScopedEvent(FocusEvent::Create(
+ DispatchScopedEvent(*FocusEvent::Create(
event_type, Event::Bubbles::kYes, GetDocument().domWindow(), 0,
new_focused_element, source_capabilities));
}
@@ -3480,20 +3523,11 @@ void Element::SetInnerHTMLFromString(const String& html) {
void Element::setInnerHTML(const StringOrTrustedHTML& string_or_html,
ExceptionState& exception_state) {
- DCHECK(string_or_html.IsString() ||
- RuntimeEnabledFeatures::TrustedDOMTypesEnabled());
-
- if (string_or_html.IsString() && GetDocument().RequireTrustedTypes()) {
- exception_state.ThrowTypeError(
- "This document requires `TrustedHTML` assignment.");
- return;
+ String html =
+ TrustedHTML::GetString(string_or_html, &GetDocument(), exception_state);
+ if (!exception_state.HadException()) {
+ SetInnerHTMLFromString(html, exception_state);
}
-
- String html = string_or_html.IsString()
- ? string_or_html.GetAsString()
- : string_or_html.GetAsTrustedHTML()->toString();
-
- SetInnerHTMLFromString(html, exception_state);
}
void Element::setInnerHTML(const StringOrTrustedHTML& string_or_html) {
@@ -3537,20 +3571,11 @@ void Element::SetOuterHTMLFromString(const String& html,
void Element::setOuterHTML(const StringOrTrustedHTML& string_or_html,
ExceptionState& exception_state) {
- DCHECK(string_or_html.IsString() ||
- RuntimeEnabledFeatures::TrustedDOMTypesEnabled());
-
- if (string_or_html.IsString() && GetDocument().RequireTrustedTypes()) {
- exception_state.ThrowTypeError(
- "This document requires `TrustedHTML` assignment.");
- return;
+ String html =
+ TrustedHTML::GetString(string_or_html, &GetDocument(), exception_state);
+ if (!exception_state.HadException()) {
+ SetOuterHTMLFromString(html, exception_state);
}
-
- String html = string_or_html.IsString()
- ? string_or_html.GetAsString()
- : string_or_html.GetAsTrustedHTML()->toString();
-
- SetOuterHTMLFromString(html, exception_state);
}
Node* Element::InsertAdjacent(const String& where,
@@ -3697,20 +3722,11 @@ void Element::insertAdjacentHTML(const String& where,
void Element::insertAdjacentHTML(const String& where,
const StringOrTrustedHTML& string_or_html,
ExceptionState& exception_state) {
- DCHECK(string_or_html.IsString() ||
- RuntimeEnabledFeatures::TrustedDOMTypesEnabled());
-
- if (string_or_html.IsString() && GetDocument().RequireTrustedTypes()) {
- exception_state.ThrowTypeError(
- "This document requires `TrustedHTML` assignment.");
- return;
+ String markup =
+ TrustedHTML::GetString(string_or_html, &GetDocument(), exception_state);
+ if (!exception_state.HadException()) {
+ insertAdjacentHTML(where, markup, exception_state);
}
-
- String markup = string_or_html.IsString()
- ? string_or_html.GetAsString()
- : string_or_html.GetAsTrustedHTML()->toString();
-
- insertAdjacentHTML(where, markup, exception_state);
}
void Element::setPointerCapture(int pointer_id,
@@ -3760,19 +3776,6 @@ bool Element::HasProcessedPointerCapture(int pointer_id) const {
pointer_id, this);
}
-String Element::innerText() {
- // We need to update layout, since plainText uses line boxes in the layout
- // tree.
- GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
-
- if (!GetLayoutObject() && !HasDisplayContentsStyle())
- return textContent(true);
-
- return PlainText(
- EphemeralRange::RangeOfContents(*this),
- TextIteratorBehavior::Builder().SetForInnerText(true).Build());
-}
-
String Element::outerText() {
// Getting outerText is the same as getting innerText, only
// setting is different. You would think this should get the plain
@@ -3979,35 +3982,99 @@ void Element::CancelFocusAppearanceUpdate() {
GetDocument().CancelFocusAppearanceUpdate();
}
-void Element::UpdatePseudoElement(PseudoId pseudo_id,
- StyleRecalcChange change) {
- // TODO(futhark@chromium.org): Update ::first-letter pseudo elements and style
- // as part of style recalc also when re-attaching.
- if (change == kReattach && pseudo_id == kPseudoIdFirstLetter)
+void Element::UpdateFirstLetterPseudoElement(StyleUpdatePhase phase) {
+ // Update the ::first-letter pseudo elements presence and its style. This
+ // method may be called from style recalc or layout tree rebuilding/
+ // reattachment. In order to know if an element generates a ::first-letter
+ // element, we need to know if:
+ //
+ // * The element generates a block level box to which ::first-letter applies.
+ // * The element's layout subtree generates any first letter text.
+ // * None of the descendant blocks generate a ::first-letter element.
+ // (This is not correct according to spec as all block containers should be
+ // able to generate ::first-letter elements around the first letter of the
+ // first formatted text, but Blink is only supporting a single
+ // ::first-letter element which is the innermost block generating a
+ // ::first-letter).
+ //
+ // We do not always do this at style recalc time as that would have required
+ // us to collect the information about how the layout tree will look like
+ // after the layout tree is attached. So, instead we will wait until we have
+ // an up-to-date layout sub-tree for the element we are considering for
+ // ::first-letter.
+ //
+ // The StyleUpdatePhase tells where we are in the process of updating style
+ // and layout tree.
+
+ PseudoElement* element = GetPseudoElement(kPseudoIdFirstLetter);
+ if (!element) {
+ element = CreatePseudoElementIfNeeded(kPseudoIdFirstLetter);
+ // If we are in Element::AttachLayoutTree, don't mess up the ancestor flags
+ // for layout tree attachment/rebuilding. We will unconditionally call
+ // AttachLayoutTree for the created pseudo element immediately after this
+ // call.
+ if (element && phase != StyleUpdatePhase::kAttachLayoutTree)
+ element->SetNeedsReattachLayoutTree();
+ return;
+ }
+
+ if (phase == StyleUpdatePhase::kRebuildLayoutTree &&
+ element->NeedsReattachLayoutTree()) {
+ // We were already updated in RecalcStyle and ready for reattach.
+ DCHECK(element->GetNonAttachedStyle());
+ return;
+ }
+
+ if (!CanGeneratePseudoElement(kPseudoIdFirstLetter)) {
+ GetElementRareData()->SetPseudoElement(kPseudoIdFirstLetter, nullptr);
+ return;
+ }
+
+ LayoutObject* remaining_text_layout_object =
+ FirstLetterPseudoElement::FirstLetterTextLayoutObject(*element);
+
+ if (!remaining_text_layout_object) {
+ GetElementRareData()->SetPseudoElement(kPseudoIdFirstLetter, nullptr);
+ return;
+ }
+
+ bool text_node_changed =
+ remaining_text_layout_object !=
+ ToFirstLetterPseudoElement(element)->RemainingTextLayoutObject();
+
+ if (phase == StyleUpdatePhase::kAttachLayoutTree) {
+ // RemainingTextLayoutObject should have been cleared from DetachLayoutTree.
+ DCHECK(!ToFirstLetterPseudoElement(element)->RemainingTextLayoutObject());
+ DCHECK(text_node_changed);
+ scoped_refptr<ComputedStyle> pseudo_style = element->StyleForLayoutObject();
+ if (PseudoElementLayoutObjectIsNeeded(pseudo_style.get()))
+ element->SetNonAttachedStyle(std::move(pseudo_style));
+ else
+ GetElementRareData()->SetPseudoElement(kPseudoIdFirstLetter, nullptr);
return;
+ }
+
+ element->RecalcStyle(text_node_changed ? kReattach : kForce);
+
+ if (element->NeedsReattachLayoutTree() &&
+ !PseudoElementLayoutObjectIsNeeded(element->GetNonAttachedStyle())) {
+ GetElementRareData()->SetPseudoElement(kPseudoIdFirstLetter, nullptr);
+ }
+}
+void Element::UpdatePseudoElement(PseudoId pseudo_id,
+ StyleRecalcChange change) {
PseudoElement* element = GetPseudoElement(pseudo_id);
if (!element) {
- if (change >= kUpdatePseudoElements)
- element = CreatePseudoElementIfNeeded(pseudo_id);
- // TODO(futhark@chromium.org): We cannot SetNeedsReattachLayoutTree() for
- // ::first-letter inside CreatePseudoElementIfNeeded() because it may be
- // called from layout tree attachment.
- if (element && pseudo_id == kPseudoIdFirstLetter)
+ if (change < kUpdatePseudoElements)
+ return;
+ if ((element = CreatePseudoElementIfNeeded(pseudo_id)))
element->SetNeedsReattachLayoutTree();
return;
}
if (change == kUpdatePseudoElements ||
element->ShouldCallRecalcStyle(change)) {
- if (pseudo_id == kPseudoIdFirstLetter) {
- if (UpdateFirstLetter(element))
- return;
- // Need to clear the cached style if the PseudoElement wants a recalc so
- // it computes a new style.
- if (element->NeedsStyleRecalc())
- MutableComputedStyle()->RemoveCachedPseudoStyle(kPseudoIdFirstLetter);
- }
if (CanGeneratePseudoElement(pseudo_id)) {
element->RecalcStyle(change == kUpdatePseudoElements ? kForce : change);
if (!element->NeedsReattachLayoutTree())
@@ -4016,54 +4083,22 @@ void Element::UpdatePseudoElement(PseudoId pseudo_id,
return;
}
GetElementRareData()->SetPseudoElement(pseudo_id, nullptr);
- } else if (pseudo_id == kPseudoIdFirstLetter &&
- change >= kUpdatePseudoElements &&
- !FirstLetterPseudoElement::FirstLetterTextLayoutObject(*element)) {
- // We can end up here if we change to a float, for example. We need to
- // cleanup the first-letter PseudoElement and then fix the text of the
- // original remaining text LayoutObject. This can be seen in Test 7 of
- // fast/css/first-letter-removed-added.html
- GetElementRareData()->SetPseudoElement(kPseudoIdFirstLetter, nullptr);
}
}
-// If we're updating first letter, and the current first letter layoutObject
-// is not the same as the one we're currently using we need to re-create
-// the first letter layoutObject.
-bool Element::UpdateFirstLetter(Element* element) {
- LayoutObject* remaining_text_layout_object =
- FirstLetterPseudoElement::FirstLetterTextLayoutObject(*element);
- if (!remaining_text_layout_object ||
- remaining_text_layout_object !=
- ToFirstLetterPseudoElement(element)->RemainingTextLayoutObject()) {
- // We have to clear out the old first letter here because when it is
- // disposed it will set the original text back on the remaining text
- // layoutObject. If we dispose after creating the new one we will get
- // incorrect results due to setting the first letter back.
- if (remaining_text_layout_object)
- element->ReattachLayoutTree();
- else
- GetElementRareData()->SetPseudoElement(kPseudoIdFirstLetter, nullptr);
- return true;
- }
- return false;
-}
-
PseudoElement* Element::CreatePseudoElementIfNeeded(PseudoId pseudo_id) {
if (IsPseudoElement())
return nullptr;
if (!CanGeneratePseudoElement(pseudo_id))
return nullptr;
if (pseudo_id == kPseudoIdFirstLetter) {
- if (IsSVGElement())
- return nullptr;
if (!FirstLetterPseudoElement::FirstLetterTextLayoutObject(*this))
return nullptr;
}
PseudoElement* pseudo_element = PseudoElement::Create(this, pseudo_id);
EnsureElementRareData().SetPseudoElement(pseudo_id, pseudo_element);
- pseudo_element->InsertedInto(this);
+ pseudo_element->InsertedInto(*this);
scoped_refptr<ComputedStyle> pseudo_style =
pseudo_element->StyleForLayoutObject();
@@ -4077,12 +4112,6 @@ PseudoElement* Element::CreatePseudoElementIfNeeded(PseudoId pseudo_id) {
pseudo_element->SetNonAttachedStyle(std::move(pseudo_style));
- // TODO(futhark@chromium.org): We cannot SetNeedsReattachLayoutTree() for
- // ::first-letter inside CreatePseudoElementIfNeeded() because it may be
- // called from layout tree attachment.
- if (pseudo_id != kPseudoIdFirstLetter)
- pseudo_element->SetNeedsReattachLayoutTree();
-
probe::pseudoElementCreated(pseudo_element);
return pseudo_element;
@@ -4143,9 +4172,14 @@ scoped_refptr<ComputedStyle> Element::StyleForPseudoElement(
if (is_before_or_after) {
const ComputedStyle* layout_parent_style = style;
if (style->Display() == EDisplay::kContents) {
- Node* layout_parent = LayoutTreeBuilderTraversal::LayoutParent(*this);
- DCHECK(layout_parent);
- layout_parent_style = layout_parent->GetComputedStyle();
+ // TODO(futhark@chromium.org): Calling getComputedStyle for elements
+ // outside the flat tree should return empty styles, but currently we do
+ // not. See issue https://crbug.com/831568. We can replace the if-test
+ // with DCHECK(layout_parent) when that issue is fixed.
+ if (Node* layout_parent =
+ LayoutTreeBuilderTraversal::LayoutParent(*this)) {
+ layout_parent_style = layout_parent->GetComputedStyle();
+ }
}
return GetDocument().EnsureStyleResolver().PseudoStyleForElement(
this, request, style, layout_parent_style);
@@ -4169,6 +4203,8 @@ scoped_refptr<ComputedStyle> Element::StyleForPseudoElement(
bool Element::CanGeneratePseudoElement(PseudoId pseudo_id) const {
if (pseudo_id == kPseudoIdBackdrop && !IsInTopLayer())
return false;
+ if (pseudo_id == kPseudoIdFirstLetter && IsSVGElement())
+ return false;
if (const ComputedStyle* style = GetComputedStyle())
return style->CanGeneratePseudoElement(pseudo_id);
return false;
@@ -4469,9 +4505,9 @@ inline void Element::UpdateId(TreeScope& scope,
DCHECK_NE(old_id, new_id);
if (!old_id.IsEmpty())
- scope.RemoveElementById(old_id, this);
+ scope.RemoveElementById(old_id, *this);
if (!new_id.IsEmpty())
- scope.AddElementById(new_id, this);
+ scope.AddElementById(new_id, *this);
NamedItemType type = GetNamedItemType();
if (type == NamedItemType::kNameOrId ||
@@ -4689,37 +4725,37 @@ void Element::DetachAllAttrNodesFromElement() {
}
Node::InsertionNotificationRequest Node::InsertedInto(
- ContainerNode* insertion_point) {
+ ContainerNode& insertion_point) {
DCHECK(!ChildNeedsStyleInvalidation());
DCHECK(!NeedsStyleInvalidation());
- DCHECK(insertion_point->isConnected() || insertion_point->IsInShadowTree() ||
+ DCHECK(insertion_point.isConnected() || insertion_point.IsInShadowTree() ||
IsContainerNode());
- if (insertion_point->isConnected()) {
+ if (insertion_point.isConnected()) {
SetFlag(kIsConnectedFlag);
- insertion_point->GetDocument().IncrementNodeCount();
+ insertion_point.GetDocument().IncrementNodeCount();
}
if (ParentOrShadowHostNode()->IsInShadowTree())
SetFlag(kIsInShadowTreeFlag);
if (ChildNeedsDistributionRecalc() &&
- !insertion_point->ChildNeedsDistributionRecalc())
- insertion_point->MarkAncestorsWithChildNeedsDistributionRecalc();
+ !insertion_point.ChildNeedsDistributionRecalc())
+ insertion_point.MarkAncestorsWithChildNeedsDistributionRecalc();
if (AXObjectCache* cache = GetDocument().ExistingAXObjectCache())
- cache->ChildrenChanged(insertion_point);
+ cache->ChildrenChanged(&insertion_point);
return kInsertionDone;
}
-void Node::RemovedFrom(ContainerNode* insertion_point) {
- DCHECK(insertion_point->isConnected() || IsContainerNode() ||
+void Node::RemovedFrom(ContainerNode& insertion_point) {
+ DCHECK(insertion_point.isConnected() || IsContainerNode() ||
IsInShadowTree());
- if (insertion_point->isConnected()) {
+ if (insertion_point.isConnected()) {
ClearFlag(kIsConnectedFlag);
- insertion_point->GetDocument().DecrementNodeCount();
+ insertion_point.GetDocument().DecrementNodeCount();
}
if (IsInShadowTree() && !ContainingTreeScope().RootNode().IsShadowRoot())
ClearFlag(kIsInShadowTreeFlag);
if (AXObjectCache* cache = GetDocument().ExistingAXObjectCache()) {
cache->Remove(this);
- cache->ChildrenChanged(insertion_point);
+ cache->ChildrenChanged(&insertion_point);
}
}
diff --git a/chromium/third_party/blink/renderer/core/dom/element.h b/chromium/third_party/blink/renderer/core/dom/element.h
index f7d403771c1..7bf4971b625 100644
--- a/chromium/third_party/blink/renderer/core/dom/element.h
+++ b/chromium/third_party/blink/renderer/core/dom/element.h
@@ -36,9 +36,9 @@
#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/resize_observer/resize_observer.h"
+#include "third_party/blink/renderer/core/scroll/scroll_customization.h"
#include "third_party/blink/renderer/platform/bindings/trace_wrapper_member.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/scroll/scroll_customization.h"
#include "third_party/blink/renderer/platform/scroll/scroll_types.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
@@ -121,6 +121,7 @@ enum class NamedItemType {
struct FocusParams {
STACK_ALLOCATED();
+ public:
FocusParams() = default;
FocusParams(SelectionBehaviorOnFocus selection,
WebFocusType focus_type,
@@ -315,6 +316,12 @@ class CORE_EXPORT Element : public ContainerNode {
AccessibleNode* ExistingAccessibleNode() const;
AccessibleNode* accessibleNode();
+ const AtomicString& invisible() const;
+ void setInvisible(const AtomicString&);
+ void DispatchActivateInvisibleEventIfNeeded();
+
+ void DefaultEventHandler(Event&) override;
+
void DidMoveToNewDocument(Document&) override;
void removeAttribute(const AtomicString& name);
@@ -421,6 +428,8 @@ class CORE_EXPORT Element : public ContainerNode {
enum class AttributeModificationReason { kDirectly, kByParser, kByCloning };
struct AttributeModificationParams {
STACK_ALLOCATED();
+
+ public:
AttributeModificationParams(const QualifiedName& qname,
const AtomicString& old_value,
const AtomicString& new_value,
@@ -511,7 +520,8 @@ class CORE_EXPORT Element : public ContainerNode {
}
ShadowRoot& CreateUserAgentShadowRoot();
ShadowRoot& AttachShadowRootInternal(ShadowRootType,
- bool delegates_focus = false);
+ bool delegates_focus = false,
+ bool manual_slotting = false);
// Returns the shadow root attached to this element if it is a shadow host.
ShadowRoot* GetShadowRoot() const;
@@ -653,7 +663,8 @@ class CORE_EXPORT Element : public ContainerNode {
Element* new_focused_element,
InputDeviceCapabilities* source_capabilities = nullptr);
- virtual String innerText();
+ // The implementation of |innerText()| is found in "element_inner_text.cc".
+ String innerText();
String outerText();
String InnerHTMLAsString() const;
String OuterHTMLAsString() const;
@@ -894,8 +905,8 @@ class CORE_EXPORT Element : public ContainerNode {
CSSPropertyID,
const CSSValue&);
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
- void RemovedFrom(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
+ void RemovedFrom(ContainerNode&) override;
void ChildrenChanged(const ChildrenChange&) override;
virtual void WillRecalcStyle(StyleRecalcChange);
@@ -964,6 +975,8 @@ class CORE_EXPORT Element : public ContainerNode {
void InlineStyleChanged();
void SetInlineStyleFromString(const AtomicString&);
+ void InvisibleAttributeChanged();
+
// If the only inherited changes in the parent element are independent,
// these changes can be directly propagated to this element (the child).
// If these conditions are met, propagates the changes to the current style
@@ -977,12 +990,20 @@ class CORE_EXPORT Element : public ContainerNode {
bool ShouldCallRecalcStyleForChildren(StyleRecalcChange);
void RebuildPseudoElementLayoutTree(PseudoId, WhitespaceAttacher&);
+ void RebuildFirstLetterLayoutTree();
void RebuildShadowRootLayoutTree(WhitespaceAttacher&);
inline void CheckForEmptyStyleChange(const Node* node_before_change,
const Node* node_after_change);
void UpdatePseudoElement(PseudoId, StyleRecalcChange);
- bool UpdateFirstLetter(Element*);
+
+ enum class StyleUpdatePhase {
+ kRecalc,
+ kRebuildLayoutTree,
+ kAttachLayoutTree,
+ };
+
+ void UpdateFirstLetterPseudoElement(StyleUpdatePhase);
inline PseudoElement* CreatePseudoElementIfNeeded(PseudoId);
void AttachPseudoElement(PseudoId, AttachContext&);
diff --git a/chromium/third_party/blink/renderer/core/dom/element.idl b/chromium/third_party/blink/renderer/core/dom/element.idl
index 534f5d1b009..8c6d62d2c88 100644
--- a/chromium/third_party/blink/renderer/core/dom/element.idl
+++ b/chromium/third_party/blink/renderer/core/dom/element.idl
@@ -125,7 +125,7 @@ interface Element : Node {
// Non-standard API
[MeasureAs=ElementScrollIntoViewIfNeeded] void scrollIntoViewIfNeeded(optional boolean centerIfNeeded);
- [RuntimeEnabled=ShadowDOMV0, RaisesException, MeasureAs=ElementCreateShadowRoot] ShadowRoot createShadowRoot();
+ [RuntimeEnabled=ShadowDOMV0, RaisesException, DeprecateAs=ElementCreateShadowRoot] ShadowRoot createShadowRoot();
[RuntimeEnabled=ShadowDOMV0] NodeList getDestinationInsertionPoints();
// Experimental accessibility API
@@ -135,6 +135,8 @@ interface Element : Node {
// Accessibility Object Model
[RuntimeEnabled=AccessibilityObjectModel] readonly attribute AccessibleNode? accessibleNode;
+ [RuntimeEnabled=InvisibleDOM, CEReactions, CustomElementCallbacks] attribute DOMString invisible;
+
// Event handler attributes
attribute EventHandler onbeforecopy;
attribute EventHandler onbeforecut;
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 14706ed5ef7..902d22a3f91 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
@@ -27,6 +27,7 @@
#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/core/event_names.h"
namespace blink {
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 bd42170486b..6668b23470f 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/event.cc
+++ b/chromium/third_party/blink/renderer/core/dom/events/event.cc
@@ -22,13 +22,17 @@
#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"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
+#include "third_party/blink/renderer/core/dom/events/window_event_context.h"
#include "third_party/blink/renderer/core/dom/static_node_list.h"
#include "third_party/blink/renderer/core/events/focus_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/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/use_counter.h"
#include "third_party/blink/renderer/core/svg/svg_element.h"
#include "third_party/blink/renderer/core/timing/dom_window_performance.h"
@@ -95,6 +99,7 @@ Event::Event(const AtomicString& event_type,
is_trusted_(false),
executed_listener_or_default_action_(false),
prevent_default_called_on_uncancelable_event_(false),
+ legacy_did_listeners_throw_flag_(false),
handling_passive_(PassiveMode::kNotPassiveDefault),
event_phase_(0),
current_target_(nullptr),
@@ -216,6 +221,10 @@ bool Event::IsCompositionEvent() const {
return false;
}
+bool Event::IsActivateInvisibleEvent() const {
+ return false;
+}
+
bool Event::IsClipboardEvent() const {
return false;
}
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 6c95dcf8773..4175d84ac4d 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/event.h
+++ b/chromium/third_party/blink/renderer/core/dom/events/event.h
@@ -26,19 +26,17 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENTS_EVENT_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/dom/dom_time_stamp.h"
-#include "third_party/blink/renderer/core/dom/events/event_dispatcher.h"
-#include "third_party/blink/renderer/core/dom/events/event_init.h"
-#include "third_party/blink/renderer/core/dom/events/event_path.h"
+#include "third_party/blink/renderer/core/dom/events/event_dispatch_result.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"
-#include "third_party/blink/renderer/platform/wtf/time.h"
namespace blink {
class DOMWrapperWorld;
+class EventDispatcher;
+class EventInit;
+class EventPath;
class EventTarget;
class ScriptState;
class ScriptValue;
@@ -190,6 +188,8 @@ class CORE_EXPORT Event : public ScriptWrappable {
virtual bool IsBeforeUnloadEvent() const;
+ virtual bool IsActivateInvisibleEvent() const;
+
bool PropagationStopped() const {
return propagation_stopped_ || immediate_propagation_stopped_;
}
@@ -259,6 +259,14 @@ class CORE_EXPORT Event : public ScriptWrappable {
executed_listener_or_default_action_ = true;
}
+ bool LegacyDidListenersThrow() const {
+ return legacy_did_listeners_throw_flag_;
+ }
+
+ void LegacySetDidListenersThrowFlag() {
+ legacy_did_listeners_throw_flag_ = true;
+ }
+
virtual DispatchEventResult DispatchEvent(EventDispatcher&);
void Trace(blink::Visitor*) override;
@@ -318,6 +326,12 @@ class CORE_EXPORT Event : public ScriptWrappable {
// Whether preventDefault was called on uncancelable event.
unsigned prevent_default_called_on_uncancelable_event_ : 1;
+ // Whether any of listeners have thrown an exception or not.
+ // Corresponds to |legacyOutputDidListenersThrowFlag| in DOM standard.
+ // https://dom.spec.whatwg.org/#dispatching-events
+ // https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke
+ unsigned legacy_did_listeners_throw_flag_ : 1;
+
PassiveMode handling_passive_;
unsigned short event_phase_;
Member<EventTarget> current_target_;
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 533a4ecef9b..2119960822a 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
@@ -33,6 +33,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/events/event_dispatch_forbidden_scope.h"
+#include "third_party/blink/renderer/core/dom/events/event_path.h"
#include "third_party/blink/renderer/core/dom/events/scoped_event_queue.h"
#include "third_party/blink/renderer/core/dom/events/window_event_context.h"
#include "third_party/blink/renderer/core/events/mouse_event.h"
@@ -49,27 +50,26 @@
namespace blink {
-DispatchEventResult EventDispatcher::DispatchEvent(Node& node, Event* event) {
+DispatchEventResult EventDispatcher::DispatchEvent(Node& node, Event& event) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("blink.debug"),
"EventDispatcher::dispatchEvent");
#if DCHECK_IS_ON()
DCHECK(!EventDispatchForbiddenScope::IsEventDispatchForbidden());
#endif
EventDispatcher dispatcher(node, event);
- return event->DispatchEvent(dispatcher);
+ return event.DispatchEvent(dispatcher);
}
-EventDispatcher::EventDispatcher(Node& node, Event* event)
+EventDispatcher::EventDispatcher(Node& node, Event& event)
: node_(node), event_(event) {
- DCHECK(event_.Get());
view_ = node.GetDocument().View();
event_->InitEventPath(*node_);
}
-void EventDispatcher::DispatchScopedEvent(Node& node, Event* event) {
+void EventDispatcher::DispatchScopedEvent(Node& node, Event& event) {
// We need to set the target here because it can go away by the time we
// actually fire the event.
- event->SetTarget(EventPath::EventTargetRespectingTargetRules(node));
+ event.SetTarget(EventPath::EventTargetRespectingTargetRules(node));
ScopedEventQueue::Instance()->EnqueueEvent(event);
}
@@ -95,20 +95,20 @@ void EventDispatcher::DispatchSimulatedClick(
nodes_dispatching_simulated_clicks.insert(&node);
if (mouse_event_options == kSendMouseOverUpDownEvents)
- EventDispatcher(node, MouseEvent::Create(EventTypeNames::mouseover,
- node.GetDocument().domWindow(),
- underlying_event, creation_scope))
+ EventDispatcher(node, *MouseEvent::Create(EventTypeNames::mouseover,
+ node.GetDocument().domWindow(),
+ underlying_event, creation_scope))
.Dispatch();
if (mouse_event_options != kSendNoEvents) {
- EventDispatcher(node, MouseEvent::Create(EventTypeNames::mousedown,
- node.GetDocument().domWindow(),
- underlying_event, creation_scope))
+ EventDispatcher(node, *MouseEvent::Create(EventTypeNames::mousedown,
+ node.GetDocument().domWindow(),
+ underlying_event, creation_scope))
.Dispatch();
node.SetActive(true);
- EventDispatcher(node, MouseEvent::Create(EventTypeNames::mouseup,
- node.GetDocument().domWindow(),
- underlying_event, creation_scope))
+ EventDispatcher(node, *MouseEvent::Create(EventTypeNames::mouseup,
+ node.GetDocument().domWindow(),
+ underlying_event, creation_scope))
.Dispatch();
}
// Some elements (e.g. the color picker) may set active state to true before
@@ -116,9 +116,9 @@ void EventDispatcher::DispatchSimulatedClick(
node.SetActive(false);
// always send click
- EventDispatcher(node, MouseEvent::Create(EventTypeNames::click,
- node.GetDocument().domWindow(),
- underlying_event, creation_scope))
+ EventDispatcher(node, *MouseEvent::Create(EventTypeNames::click,
+ node.GetDocument().domWindow(),
+ underlying_event, creation_scope))
.Dispatch();
nodes_dispatching_simulated_clicks.erase(&node);
@@ -207,7 +207,7 @@ inline EventDispatchContinuation EventDispatcher::DispatchEventPreProcess(
// legacy-pre-activation behavior.
if (activation_target) {
pre_dispatch_event_handler_result =
- activation_target->PreDispatchEventHandler(event_.Get());
+ activation_target->PreDispatchEventHandler(*event_);
}
return (event_->GetEventPath().IsEmpty() || event_->PropagationStopped())
? kDoneDispatching
@@ -293,7 +293,7 @@ inline void EventDispatcher::DispatchEventPostProcess(
// This may dispatch an event, and node_ and event_ might be altered.
if (activation_target) {
activation_target->PostDispatchEventHandler(
- event_.Get(), pre_dispatch_event_handler_result);
+ *event_, pre_dispatch_event_handler_result);
}
// TODO(tkent): Is it safe to kick DefaultEventHandler() with such altered
// event_?
@@ -325,7 +325,7 @@ inline void EventDispatcher::DispatchEventPostProcess(
// Non-bubbling events call only one default event handler, the one for the
// target.
node_->WillCallDefaultEventHandler(*event_);
- node_->DefaultEventHandler(event_.Get());
+ node_->DefaultEventHandler(*event_);
DCHECK(!event_->defaultPrevented());
// For bubbling events, call default event handlers on the same targets in
// the same order as the bubbling phase.
@@ -334,7 +334,7 @@ inline void EventDispatcher::DispatchEventPostProcess(
for (size_t i = 1; i < size; ++i) {
event_->GetEventPath()[i].GetNode()->WillCallDefaultEventHandler(
*event_);
- event_->GetEventPath()[i].GetNode()->DefaultEventHandler(event_.Get());
+ event_->GetEventPath()[i].GetNode()->DefaultEventHandler(*event_);
DCHECK(!event_->defaultPrevented());
if (event_->DefaultHandled())
break;
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 5504bea4c64..e09e49f4584 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
@@ -52,8 +52,8 @@ class EventDispatcher {
STACK_ALLOCATED();
public:
- static DispatchEventResult DispatchEvent(Node&, Event*);
- static void DispatchScopedEvent(Node&, Event*);
+ static DispatchEventResult DispatchEvent(Node&, Event&);
+ static void DispatchScopedEvent(Node&, Event&);
static void DispatchSimulatedClick(Node&,
Event* underlying_event,
@@ -65,7 +65,7 @@ class EventDispatcher {
Event& GetEvent() const { return *event_; }
private:
- EventDispatcher(Node&, Event*);
+ EventDispatcher(Node&, Event&);
EventDispatchContinuation DispatchEventPreProcess(
Node* activation_target,
diff --git a/chromium/third_party/blink/renderer/core/dom/events/event_listener.h b/chromium/third_party/blink/renderer/core/dom/events/event_listener.h
index 018acd55347..70942bb3d21 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/event_listener.h
+++ b/chromium/third_party/blink/renderer/core/dom/events/event_listener.h
@@ -21,6 +21,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENTS_EVENT_LISTENER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENTS_EVENT_LISTENER_H_
+#include "third_party/blink/renderer/bindings/core/v8/custom_wrappable_adapter.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/bindings/name_client.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -28,12 +29,11 @@
namespace blink {
+class DOMWrapperWorld;
class Event;
class ExecutionContext;
-class CORE_EXPORT EventListener
- : public GarbageCollectedFinalized<EventListener>,
- public NameClient {
+class CORE_EXPORT EventListener : public CustomWrappableAdapter {
public:
enum ListenerType {
kJSEventListenerType,
@@ -42,7 +42,7 @@ class CORE_EXPORT EventListener
kConditionEventListenerType,
};
- virtual ~EventListener() = default;
+ ~EventListener() override = default;
virtual bool operator==(const EventListener&) const = 0;
virtual void handleEvent(ExecutionContext*, Event*) = 0;
virtual const String& Code() const { return g_empty_string; }
@@ -52,9 +52,18 @@ class CORE_EXPORT EventListener
}
virtual bool IsAttribute() const { return false; }
+ // Only DevTools is allowed to use this method.
+ // This method may return an empty handle.
+ virtual v8::Local<v8::Object> GetListenerObjectForInspector(
+ ExecutionContext* execution_context) {
+ return v8::Local<v8::Object>();
+ }
+
+ // Only DevTools is allowed to use this method.
+ virtual DOMWrapperWorld* GetWorldForInspector() const { return nullptr; }
+
ListenerType GetType() const { return type_; }
- virtual void Trace(blink::Visitor* visitor) {}
const char* NameInHeapSnapshot() const override { return "EventListener"; }
protected:
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 f7c8c459c89..d4c14740d3c 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,7 @@
#include "third_party/blink/renderer/core/dom/events/event_listener_map.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"
#include "third_party/blink/renderer/platform/wtf/vector.h"
diff --git a/chromium/third_party/blink/renderer/core/dom/events/event_path.cc b/chromium/third_party/blink/renderer/core/dom/events/event_path.cc
index 1f29d1b8562..fecad3ad96c 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/event_path.cc
+++ b/chromium/third_party/blink/renderer/core/dom/events/event_path.cc
@@ -27,6 +27,7 @@
#include "third_party/blink/renderer/core/dom/events/event_path.h"
#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/dom/events/window_event_context.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
#include "third_party/blink/renderer/core/dom/v0_insertion_point.h"
#include "third_party/blink/renderer/core/event_names.h"
@@ -101,7 +102,7 @@ void EventPath::CalculatePath() {
nodes_in_path.push_back(current);
while (current) {
- if (event_ && current->KeepEventInNode(event_))
+ if (event_ && current->KeepEventInNode(*event_))
break;
HeapVector<Member<V0InsertionPoint>, 8> insertion_points;
CollectDestinationInsertionPoints(*current, insertion_points);
diff --git a/chromium/third_party/blink/renderer/core/dom/events/event_path.h b/chromium/third_party/blink/renderer/core/dom/events/event_path.h
index e66ea981547..27754e73c0b 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/event_path.h
+++ b/chromium/third_party/blink/renderer/core/dom/events/event_path.h
@@ -31,10 +31,7 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/events/node_event_context.h"
#include "third_party/blink/renderer/core/dom/events/tree_scope_event_context.h"
-#include "third_party/blink/renderer/core/dom/events/window_event_context.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/vector.h"
namespace blink {
@@ -44,6 +41,7 @@ class Node;
class TouchEvent;
class TouchList;
class TreeScope;
+class WindowEventContext;
class CORE_EXPORT EventPath final
: public GarbageCollectedFinalized<EventPath> {
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 53166a98285..78bea34c911 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
@@ -53,16 +53,16 @@ void EventQueue::Trace(blink::Visitor* visitor) {
ContextLifecycleObserver::Trace(visitor);
}
-bool EventQueue::EnqueueEvent(const base::Location& from_here, Event* event) {
+bool EventQueue::EnqueueEvent(const base::Location& from_here, Event& event) {
if (is_closed_)
return false;
- DCHECK(event->target());
+ DCHECK(event.target());
DCHECK(GetExecutionContext());
- probe::AsyncTaskScheduled(GetExecutionContext(), event->type(), event);
+ probe::AsyncTaskScheduled(GetExecutionContext(), event.type(), &event);
- bool was_added = queued_events_.insert(event).is_new_entry;
+ bool was_added = queued_events_.insert(&event).is_new_entry;
DCHECK(was_added); // It should not have already been in the list.
scoped_refptr<base::SingleThreadTaskRunner> task_runner =
@@ -72,7 +72,7 @@ bool EventQueue::EnqueueEvent(const base::Location& from_here, Event* event) {
// object like IDBTransaction as soon as possible.
task_runner->PostTask(
FROM_HERE, WTF::Bind(&EventQueue::DispatchEvent, WrapPersistent(this),
- WrapWeakPersistent(event)));
+ WrapWeakPersistent(&event)));
return true;
}
@@ -85,8 +85,8 @@ void EventQueue::CancelAllEvents() {
DoCancelAllEvents(GetExecutionContext());
}
-bool EventQueue::RemoveEvent(Event* event) {
- auto found = queued_events_.find(event);
+bool EventQueue::RemoveEvent(Event& event) {
+ auto found = queued_events_.find(&event);
if (found == queued_events_.end())
return false;
queued_events_.erase(found);
@@ -94,7 +94,7 @@ bool EventQueue::RemoveEvent(Event* event) {
}
void EventQueue::DispatchEvent(Event* event) {
- if (!event || !RemoveEvent(event))
+ if (!event || !RemoveEvent(*event))
return;
DCHECK(GetExecutionContext());
@@ -102,9 +102,9 @@ void EventQueue::DispatchEvent(Event* event) {
probe::AsyncTask async_task(GetExecutionContext(), event);
EventTarget* target = event->target();
if (LocalDOMWindow* window = target->ToLocalDOMWindow())
- window->DispatchEvent(event, nullptr);
+ window->DispatchEvent(*event, nullptr);
else
- target->DispatchEvent(event);
+ target->DispatchEvent(*event);
}
void EventQueue::ContextDestroyed(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 cc446451d61..1906634e688 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
@@ -46,14 +46,14 @@ class CORE_EXPORT EventQueue final
~EventQueue();
void Trace(blink::Visitor*) override;
- bool EnqueueEvent(const base::Location&, Event*);
+ bool EnqueueEvent(const base::Location&, Event&);
void CancelAllEvents();
bool HasPendingEvents() const;
private:
EventQueue(ExecutionContext*, TaskType);
- bool RemoveEvent(Event*);
+ bool RemoveEvent(Event&);
void DispatchEvent(Event*);
void ContextDestroyed(ExecutionContext*) override;
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 e934b6afe4e..80ceabc0900 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
@@ -39,6 +39,7 @@
#include "third_party/blink/renderer/bindings/core/v8/event_listener_options_or_boolean.h"
#include "third_party/blink/renderer/bindings/core/v8/script_event_listener.h"
#include "third_party/blink/renderer/bindings/core/v8/source_location.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_abstract_event_listener.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"
@@ -97,10 +98,14 @@ bool IsTouchScrollBlockingEvent(const AtomicString& event_type) {
event_type == EventTypeNames::touchmove;
}
+bool IsWheelScrollBlockingEvent(const AtomicString& event_type) {
+ return event_type == EventTypeNames::mousewheel ||
+ event_type == EventTypeNames::wheel;
+}
+
bool IsScrollBlockingEvent(const AtomicString& event_type) {
return IsTouchScrollBlockingEvent(event_type) ||
- event_type == EventTypeNames::mousewheel ||
- event_type == EventTypeNames::wheel;
+ IsWheelScrollBlockingEvent(event_type);
}
bool IsInstrumentedForAsyncStack(const AtomicString& event_type) {
@@ -109,17 +114,17 @@ bool IsInstrumentedForAsyncStack(const AtomicString& event_type) {
}
base::TimeDelta BlockedEventsWarningThreshold(ExecutionContext* context,
- const Event* event) {
- if (!event->cancelable())
+ const Event& event) {
+ if (!event.cancelable())
return base::TimeDelta();
- if (!IsScrollBlockingEvent(event->type()))
+ if (!IsScrollBlockingEvent(event.type()))
return base::TimeDelta();
return PerformanceMonitor::Threshold(context,
PerformanceMonitor::kBlockedEvent);
}
void ReportBlockedEvent(ExecutionContext* context,
- const Event* event,
+ const Event& event,
RegisteredEventListener* registered_listener,
base::TimeDelta delayed) {
if (registered_listener->Callback()->GetType() !=
@@ -131,7 +136,7 @@ void ReportBlockedEvent(ExecutionContext* context,
" ms due to main thread being busy. "
"Consider marking event handler as 'passive' to make the page more "
"responsive.",
- event->type().GetString().Utf8().data(), delayed.InMilliseconds());
+ event.type().GetString().Utf8().data(), delayed.InMilliseconds());
PerformanceMonitor::ReportGenericViolation(
context, PerformanceMonitor::kBlockedEvent, message_text, delayed,
@@ -141,11 +146,11 @@ void ReportBlockedEvent(ExecutionContext* context,
// UseCounts the event if it has the specified type. Returns true iff the event
// type matches.
-bool CheckTypeThenUseCount(const Event* event,
+bool CheckTypeThenUseCount(const Event& event,
const AtomicString& event_type_to_count,
const WebFeature feature,
const Document* document) {
- if (event->type() != event_type_to_count)
+ if (event.type() != event_type_to_count)
return false;
UseCounter::Count(*document, feature);
return true;
@@ -208,6 +213,22 @@ inline LocalDOMWindow* EventTarget::ExecutingWindow() {
return nullptr;
}
+bool EventTarget::IsTopLevelNode() {
+ if (ToLocalDOMWindow())
+ return true;
+
+ Node* node = ToNode();
+ if (!node)
+ return false;
+
+ if (node->IsDocumentNode() || node->GetDocument().documentElement() == node ||
+ node->GetDocument().body() == node) {
+ return true;
+ }
+
+ return false;
+}
+
void EventTarget::SetDefaultAddEventListenerOptions(
const AtomicString& event_type,
EventListener* event_listener,
@@ -232,16 +253,29 @@ void EventTarget::SetDefaultAddEventListenerOptions(
if (RuntimeEnabledFeatures::PassiveDocumentEventListenersEnabled() &&
IsTouchScrollBlockingEvent(event_type)) {
- if (!options.hasPassive()) {
- if (Node* node = ToNode()) {
- if (node->IsDocumentNode() ||
- node->GetDocument().documentElement() == node ||
- node->GetDocument().body() == node) {
- options.setPassive(true);
- options.SetPassiveForcedForDocumentTarget(true);
- return;
- }
- } else if (ToLocalDOMWindow()) {
+ if (!options.hasPassive() && IsTopLevelNode()) {
+ options.setPassive(true);
+ options.SetPassiveForcedForDocumentTarget(true);
+ return;
+ }
+ }
+
+ if (IsWheelScrollBlockingEvent(event_type) && IsTopLevelNode()) {
+ if (options.hasPassive()) {
+ if (executing_window) {
+ UseCounter::Count(
+ executing_window->document(),
+ options.passive()
+ ? WebFeature::kAddDocumentLevelPassiveTrueWheelEventListener
+ : WebFeature::kAddDocumentLevelPassiveFalseWheelEventListener);
+ }
+ } else { // !options.hasPassive()
+ if (executing_window) {
+ UseCounter::Count(
+ executing_window->document(),
+ WebFeature::kAddDocumentLevelPassiveDefaultWheelEventListener);
+ }
+ if (RuntimeEnabledFeatures::PassiveDocumentWheelEventListenersEnabled()) {
options.setPassive(true);
options.SetPassiveForcedForDocumentTarget(true);
return;
@@ -544,40 +578,38 @@ bool EventTarget::dispatchEventForBindings(Event* event,
// Return whether the event was cancelled or not to JS not that it
// might have actually been default handled; so check only against
// CanceledByEventHandler.
- return DispatchEventInternal(event) !=
+ return DispatchEventInternal(*event) !=
DispatchEventResult::kCanceledByEventHandler;
}
-DispatchEventResult EventTarget::DispatchEvent(Event* event) {
- event->SetTrusted(true);
+DispatchEventResult EventTarget::DispatchEvent(Event& event) {
+ event.SetTrusted(true);
return DispatchEventInternal(event);
}
-DispatchEventResult EventTarget::DispatchEventInternal(Event* event) {
- event->SetTarget(this);
- event->SetCurrentTarget(this);
- event->SetEventPhase(Event::kAtTarget);
+DispatchEventResult EventTarget::DispatchEventInternal(Event& event) {
+ event.SetTarget(this);
+ event.SetCurrentTarget(this);
+ event.SetEventPhase(Event::kAtTarget);
DispatchEventResult dispatch_result = FireEventListeners(event);
- event->SetEventPhase(0);
+ event.SetEventPhase(0);
return dispatch_result;
}
-void EventTarget::UncaughtExceptionInEventHandler() {}
-
-static const AtomicString& LegacyType(const Event* event) {
- if (event->type() == EventTypeNames::transitionend)
+static const AtomicString& LegacyType(const Event& event) {
+ if (event.type() == EventTypeNames::transitionend)
return EventTypeNames::webkitTransitionEnd;
- if (event->type() == EventTypeNames::animationstart)
+ if (event.type() == EventTypeNames::animationstart)
return EventTypeNames::webkitAnimationStart;
- if (event->type() == EventTypeNames::animationend)
+ if (event.type() == EventTypeNames::animationend)
return EventTypeNames::webkitAnimationEnd;
- if (event->type() == EventTypeNames::animationiteration)
+ if (event.type() == EventTypeNames::animationiteration)
return EventTypeNames::webkitAnimationIteration;
- if (event->type() == EventTypeNames::wheel)
+ if (event.type() == EventTypeNames::wheel)
return EventTypeNames::mousewheel;
return g_empty_atom;
@@ -632,12 +664,11 @@ void EventTarget::CountLegacyEvents(
}
}
-DispatchEventResult EventTarget::FireEventListeners(Event* event) {
+DispatchEventResult EventTarget::FireEventListeners(Event& event) {
#if DCHECK_IS_ON()
DCHECK(!EventDispatchForbiddenScope::IsEventDispatchForbidden());
#endif
- DCHECK(event);
- DCHECK(event->WasInitialized());
+ DCHECK(event.WasInitialized());
EventTargetData* d = GetEventTargetData();
if (!d)
@@ -649,33 +680,33 @@ DispatchEventResult EventTarget::FireEventListeners(Event* event) {
legacy_listeners_vector = d->event_listener_map.Find(legacy_type_name);
EventListenerVector* listeners_vector =
- d->event_listener_map.Find(event->type());
+ d->event_listener_map.Find(event.type());
bool fired_event_listeners = false;
if (listeners_vector) {
fired_event_listeners = FireEventListeners(event, d, *listeners_vector);
- } else if (event->isTrusted() && legacy_listeners_vector) {
- AtomicString unprefixed_type_name = event->type();
- event->SetType(legacy_type_name);
+ } else if (event.isTrusted() && legacy_listeners_vector) {
+ AtomicString unprefixed_type_name = event.type();
+ event.SetType(legacy_type_name);
fired_event_listeners =
FireEventListeners(event, d, *legacy_listeners_vector);
- event->SetType(unprefixed_type_name);
+ event.SetType(unprefixed_type_name);
}
// Only invoke the callback if event listeners were fired for this phase.
if (fired_event_listeners) {
- event->DoneDispatchingEventAtCurrentTarget();
- event->SetExecutedListenerOrDefaultAction();
+ event.DoneDispatchingEventAtCurrentTarget();
+ event.SetExecutedListenerOrDefaultAction();
// Only count uma metrics if we really fired an event listener.
Editor::CountEvent(GetExecutionContext(), event);
CountLegacyEvents(legacy_type_name, listeners_vector,
legacy_listeners_vector);
}
- return GetDispatchEventResult(*event);
+ return GetDispatchEventResult(event);
}
-bool EventTarget::FireEventListeners(Event* event,
+bool EventTarget::FireEventListeners(Event& event,
EventTargetData* d,
EventListenerVector& entry) {
// Fire all listeners registered for this event. Don't fire listeners removed
@@ -721,8 +752,8 @@ bool EventTarget::FireEventListeners(Event* event,
} else if (CheckTypeThenUseCount(event, EventTypeNames::pointerdown,
WebFeature::kPointerDownFired,
document)) {
- if (event->IsPointerEvent() &&
- static_cast<PointerEvent*>(event)->pointerType() == "touch") {
+ if (event.IsPointerEvent() &&
+ static_cast<PointerEvent&>(event).pointerType() == "touch") {
UseCounter::Count(*document, WebFeature::kPointerDownFiredForTouch);
}
} else if (CheckTypeThenUseCount(event, EventTypeNames::pointerenter,
@@ -737,8 +768,8 @@ bool EventTarget::FireEventListeners(Event* event,
} else if (CheckTypeThenUseCount(event, EventTypeNames::pointerout,
WebFeature::kPointerOverOutFired,
document)) {
- } else if (event->eventPhase() == Event::kCapturingPhase ||
- event->eventPhase() == Event::kBubblingPhase) {
+ } else if (event.eventPhase() == Event::kCapturingPhase ||
+ event.eventPhase() == Event::kBubblingPhase) {
if (CheckTypeThenUseCount(
event, EventTypeNames::DOMNodeRemoved,
WebFeature::kDOMNodeRemovedEventListenedAtNonTarget,
@@ -762,7 +793,7 @@ bool EventTarget::FireEventListeners(Event* event,
if (!d->firing_event_iterators)
d->firing_event_iterators = std::make_unique<FiringEventIteratorVector>();
d->firing_event_iterators->push_back(
- FiringEventIterator(event->type(), i, size));
+ FiringEventIterator(event.type(), i, size));
base::TimeDelta blocked_event_threshold =
BlockedEventsWarningThreshold(context, event);
@@ -771,7 +802,7 @@ bool EventTarget::FireEventListeners(Event* event,
if (!blocked_event_threshold.is_zero()) {
now = CurrentTimeTicks();
should_report_blocked_event =
- now - event->PlatformTimeStamp() > blocked_event_threshold;
+ now - event.PlatformTimeStamp() > blocked_event_threshold;
}
bool fired_listener = false;
@@ -783,10 +814,10 @@ bool EventTarget::FireEventListeners(Event* event,
// EventTarget::removeEventListener.
++i;
- if (event->eventPhase() == Event::kCapturingPhase &&
+ if (event.eventPhase() == Event::kCapturingPhase &&
!registered_listener.Capture())
continue;
- if (event->eventPhase() == Event::kBubblingPhase &&
+ if (event.eventPhase() == Event::kBubblingPhase &&
registered_listener.Capture())
continue;
@@ -795,25 +826,24 @@ bool EventTarget::FireEventListeners(Event* event,
// registeredListener, i and size are updated with the firing event iterator
// in case the listener is removed from the listener vector below.
if (registered_listener.Once())
- removeEventListener(event->type(), listener,
+ removeEventListener(event.type(), listener,
registered_listener.Capture());
// If stopImmediatePropagation has been called, we just break out
// immediately, without handling any more events on this target.
- if (event->ImmediatePropagationStopped())
+ if (event.ImmediatePropagationStopped())
break;
- event->SetHandlingPassive(EventPassiveMode(registered_listener));
+ event.SetHandlingPassive(EventPassiveMode(registered_listener));
bool passive_forced = registered_listener.PassiveForcedForDocumentTarget();
- probe::UserCallback probe(context, nullptr, event->type(), false, this);
- probe::AsyncTask async_task(
- context, V8AbstractEventListener::Cast(listener), "event",
- IsInstrumentedForAsyncStack(event->type()));
+ probe::UserCallback probe(context, nullptr, event.type(), false, this);
+ probe::AsyncTask async_task(context, listener, "event",
+ IsInstrumentedForAsyncStack(event.type()));
// To match Mozilla, the AT_TARGET phase fires both capturing and bubbling
// event listeners, even though that violates some versions of the DOM spec.
- listener->handleEvent(context, event);
+ listener->handleEvent(context, &event);
fired_listener = true;
// If we're about to report this event listener as blocking, make sure it
@@ -821,9 +851,9 @@ bool EventTarget::FireEventListeners(Event* event,
if (should_report_blocked_event && i > 0 &&
entry[i - 1].Callback() == listener && !entry[i - 1].Passive() &&
!entry[i - 1].BlockedEventWarningEmitted() &&
- !event->defaultPrevented()) {
+ !event.defaultPrevented()) {
ReportBlockedEvent(context, event, &entry[i - 1],
- now - event->PlatformTimeStamp());
+ now - event.PlatformTimeStamp());
}
if (passive_forced) {
@@ -831,13 +861,13 @@ bool EventTarget::FireEventListeners(Event* event,
("Event.PassiveForcedEventDispatchCancelled",
kPassiveForcedListenerResultTypeMax));
PassiveForcedListenerResultType breakage_type = kPreventDefaultNotCalled;
- if (event->PreventDefaultCalledDuringPassive())
+ if (event.PreventDefaultCalledDuringPassive())
breakage_type = kDocumentLevelTouchPreventDefaultCalled;
passive_forced_histogram.Count(breakage_type);
}
- event->SetHandlingPassive(Event::PassiveMode::kNotPassive);
+ event.SetHandlingPassive(Event::PassiveMode::kNotPassive);
CHECK_LE(i, size);
}
@@ -882,15 +912,15 @@ void EventTarget::RemoveAllEventListeners() {
}
}
-void EventTarget::EnqueueEvent(Event* event, TaskType task_type) {
+void EventTarget::EnqueueEvent(Event& event, TaskType task_type) {
ExecutionContext* context = GetExecutionContext();
if (!context)
return;
- probe::AsyncTaskScheduled(context, event->type(), event);
+ probe::AsyncTaskScheduled(context, event.type(), &event);
context->GetTaskRunner(task_type)->PostTask(
FROM_HERE,
WTF::Bind(&EventTarget::DispatchEnqueuedEvent, WrapPersistent(this),
- WrapPersistent(event), WrapPersistent(context)));
+ WrapPersistent(&event), WrapPersistent(context)));
}
void EventTarget::DispatchEnqueuedEvent(Event* event,
@@ -900,7 +930,7 @@ void EventTarget::DispatchEnqueuedEvent(Event* event,
return;
}
probe::AsyncTask async_task(context, event);
- DispatchEvent(event);
+ DispatchEvent(*event);
}
STATIC_ASSERT_ENUM(WebSettings::PassiveEventListenerDefault::kFalse,
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 eb021cc39e2..f8f2d5fa709 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
@@ -55,6 +55,7 @@ class DOMWindow;
class Event;
class EventListenerOptionsOrBoolean;
class ExceptionState;
+class ExecutionContext;
class LocalDOMWindow;
class MessagePort;
class Node;
@@ -153,15 +154,14 @@ class CORE_EXPORT EventTarget : public ScriptWrappable {
EventListenerOptions&);
virtual void RemoveAllEventListeners();
- DispatchEventResult DispatchEvent(Event*);
+ DispatchEventResult DispatchEvent(Event&);
- void EnqueueEvent(Event*, TaskType);
+ void EnqueueEvent(Event&, TaskType);
// dispatchEventForBindings is intended to only be called from
// javascript originated calls. This method will validate and may adjust
// the Event object before dispatching.
bool dispatchEventForBindings(Event*, ExceptionState&);
- virtual void UncaughtExceptionInEventHandler();
// Used for legacy "onEvent" attribute APIs.
bool SetAttributeEventListener(const AtomicString& event_type,
@@ -174,11 +174,15 @@ class CORE_EXPORT EventTarget : public ScriptWrappable {
EventListenerVector* GetEventListeners(const AtomicString& event_type);
Vector<AtomicString> EventTypes();
- DispatchEventResult FireEventListeners(Event*);
+ DispatchEventResult FireEventListeners(Event&);
static DispatchEventResult GetDispatchEventResult(const Event&);
- virtual bool KeepEventInNode(Event*) { return false; }
+ virtual bool KeepEventInNode(const Event&) const { return false; }
+
+ // Returns true if the target is window, window.document, or
+ // window.document.body.
+ bool IsTopLevelNode();
protected:
EventTarget();
@@ -199,7 +203,7 @@ class CORE_EXPORT EventTarget : public ScriptWrappable {
virtual void RemovedEventListener(const AtomicString& event_type,
const RegisteredEventListener&);
- virtual DispatchEventResult DispatchEventInternal(Event*);
+ virtual DispatchEventResult DispatchEventInternal(Event&);
// Subclasses should likely not override these themselves; instead, they
// should subclass EventTargetWithInlineData.
@@ -215,7 +219,7 @@ class CORE_EXPORT EventTarget : public ScriptWrappable {
RegisteredEventListener* GetAttributeRegisteredEventListener(
const AtomicString& event_type);
- bool FireEventListeners(Event*, EventTargetData*, EventListenerVector&);
+ bool FireEventListeners(Event&, EventTargetData*, EventListenerVector&);
void CountLegacyEvents(const AtomicString& legacy_type_name,
EventListenerVector*,
EventListenerVector*);
diff --git a/chromium/third_party/blink/renderer/core/dom/events/scoped_event_queue.cc b/chromium/third_party/blink/renderer/core/dom/events/scoped_event_queue.cc
index af89d3ba474..fc03321c529 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/scoped_event_queue.cc
+++ b/chromium/third_party/blink/renderer/core/dom/events/scoped_event_queue.cc
@@ -55,7 +55,7 @@ void ScopedEventQueue::Initialize() {
instance_ = instance.release();
}
-void ScopedEventQueue::EnqueueEvent(Event* event) {
+void ScopedEventQueue::EnqueueEvent(Event& event) {
if (ShouldQueueEvents())
queued_events_.push_back(event);
else
@@ -67,12 +67,12 @@ void ScopedEventQueue::DispatchAllEvents() {
queued_events.swap(queued_events_);
for (auto& event : queued_events)
- DispatchEvent(event);
+ DispatchEvent(*event);
}
-void ScopedEventQueue::DispatchEvent(Event* event) const {
- DCHECK(event->target());
- Node* node = event->target()->ToNode();
+void ScopedEventQueue::DispatchEvent(Event& event) const {
+ DCHECK(event.target());
+ Node* node = event.target()->ToNode();
EventDispatcher::DispatchEvent(*node, event);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/events/scoped_event_queue.h b/chromium/third_party/blink/renderer/core/dom/events/scoped_event_queue.h
index e91711d6e6a..a90b9a0188c 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/scoped_event_queue.h
+++ b/chromium/third_party/blink/renderer/core/dom/events/scoped_event_queue.h
@@ -46,7 +46,7 @@ class CORE_EXPORT ScopedEventQueue {
public:
~ScopedEventQueue();
- void EnqueueEvent(Event*);
+ void EnqueueEvent(Event&);
static ScopedEventQueue* Instance();
void IncrementScopingLevel();
@@ -57,7 +57,7 @@ class CORE_EXPORT ScopedEventQueue {
ScopedEventQueue();
static void Initialize();
void DispatchAllEvents();
- void DispatchEvent(Event*) const;
+ void DispatchEvent(Event&) const;
PersistentHeapVector<Member<Event>> queued_events_;
unsigned scoping_level_;
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 d5171971b5d..866c2a6d20d 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
@@ -27,9 +27,11 @@
#include "third_party/blink/renderer/core/dom/events/tree_scope_event_context.h"
#include "third_party/blink/renderer/core/dom/events/event_path.h"
+#include "third_party/blink/renderer/core/dom/events/window_event_context.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/events/touch_event_context.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/core/dom/events/window_event_context.cc b/chromium/third_party/blink/renderer/core/dom/events/window_event_context.cc
index ebddd9b5663..cf6ac7fe210 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/window_event_context.cc
+++ b/chromium/third_party/blink/renderer/core/dom/events/window_event_context.cc
@@ -53,7 +53,7 @@ bool WindowEventContext::HandleLocalEvents(Event& event) {
event.SetTarget(Target());
event.SetCurrentTarget(Window());
- window_->FireEventListeners(&event);
+ window_->FireEventListeners(event);
return true;
}
diff --git a/chromium/third_party/blink/renderer/core/dom/events/window_event_context.h b/chromium/third_party/blink/renderer/core/dom/events/window_event_context.h
index ffc31ba0f56..133a6096df6 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/window_event_context.h
+++ b/chromium/third_party/blink/renderer/core/dom/events/window_event_context.h
@@ -28,14 +28,13 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENTS_WINDOW_EVENT_CONTEXT_H_
#include "base/macros.h"
-#include "base/memory/scoped_refptr.h"
-#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
namespace blink {
class EventTarget;
class Event;
+class LocalDOMWindow;
class NodeEventContext;
class WindowEventContext : public GarbageCollected<WindowEventContext> {
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 ca96e0d1f9a..70d6fc35a7e 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
@@ -26,11 +26,13 @@
#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/dom/node_computed_style.h"
#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_object_inlines.h"
#include "third_party/blink/renderer/core/layout/layout_text.h"
#include "third_party/blink/renderer/core/layout/layout_text_fragment.h"
+#include "third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.h"
#include "third_party/blink/renderer/platform/text/text_break_iterator.h"
#include "third_party/blink/renderer/platform/wtf/text/unicode.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -94,7 +96,7 @@ static bool IsInvalidFirstLetterLayoutObject(const LayoutObject* obj) {
return (obj->IsBR() || (obj->IsText() && ToLayoutText(obj)->IsWordBreak()));
}
-LayoutObject* FirstLetterPseudoElement::FirstLetterTextLayoutObject(
+LayoutText* FirstLetterPseudoElement::FirstLetterTextLayoutObject(
const Element& element) {
LayoutObject* parent_layout_object = nullptr;
@@ -113,6 +115,10 @@ LayoutObject* FirstLetterPseudoElement::FirstLetterTextLayoutObject(
!parent_layout_object->BehavesLikeBlockContainer())
return nullptr;
+ LayoutObject* marker =
+ parent_layout_object->IsLayoutNGListItem()
+ ? ToLayoutNGListItem(parent_layout_object)->Marker()
+ : nullptr;
// Drill down into our children and look for our first text child.
LayoutObject* first_letter_text_layout_object =
parent_layout_object->SlowFirstChild();
@@ -139,7 +145,8 @@ LayoutObject* FirstLetterPseudoElement::FirstLetterTextLayoutObject(
break;
first_letter_text_layout_object =
first_letter_text_layout_object->NextSibling();
- } else if (first_letter_text_layout_object->IsListMarker()) {
+ } else if (first_letter_text_layout_object->IsListMarker() ||
+ first_letter_text_layout_object == marker) {
first_letter_text_layout_object =
first_letter_text_layout_object->NextSibling();
} else if (first_letter_text_layout_object
@@ -170,6 +177,9 @@ LayoutObject* FirstLetterPseudoElement::FirstLetterTextLayoutObject(
// setting up the first letter then.
return nullptr;
} else {
+ if (first_letter_text_layout_object->IsLayoutNGListItem())
+ marker = ToLayoutNGListItem(first_letter_text_layout_object)->Marker();
+
first_letter_text_layout_object =
first_letter_text_layout_object->SlowFirstChild();
}
@@ -184,7 +194,7 @@ LayoutObject* FirstLetterPseudoElement::FirstLetterTextLayoutObject(
IsInvalidFirstLetterLayoutObject(first_letter_text_layout_object))
return nullptr;
- return first_letter_text_layout_object;
+ return ToLayoutText(first_letter_text_layout_object);
}
FirstLetterPseudoElement::FirstLetterPseudoElement(Element* parent)
@@ -241,8 +251,10 @@ void FirstLetterPseudoElement::SetRemainingTextLayoutObject(
}
void FirstLetterPseudoElement::AttachLayoutTree(AttachContext& context) {
+ LayoutText* first_letter_text =
+ FirstLetterPseudoElement::FirstLetterTextLayoutObject(*this);
PseudoElement::AttachLayoutTree(context);
- AttachFirstLetterTextLayoutObjects();
+ AttachFirstLetterTextLayoutObjects(first_letter_text);
}
void FirstLetterPseudoElement::DetachLayoutTree(const AttachContext& context) {
@@ -260,51 +272,28 @@ void FirstLetterPseudoElement::DetachLayoutTree(const AttachContext& context) {
PseudoElement::DetachLayoutTree(context);
}
-ComputedStyle* FirstLetterPseudoElement::StyleForFirstLetter(
- LayoutObject* layout_object_container) {
- DCHECK(layout_object_container);
-
- LayoutObject* style_container =
- ParentOrShadowHostElement()->GetLayoutObject();
- DCHECK(style_container);
-
- // We always force the pseudo style to recompute as the first-letter style
- // computed by the style container may not have taken the layoutObjects styles
- // into account.
- style_container->MutableStyle()->RemoveCachedPseudoStyle(
- kPseudoIdFirstLetter);
-
- ComputedStyle* pseudo_style = style_container->GetCachedPseudoStyle(
- kPseudoIdFirstLetter, layout_object_container->FirstLineStyle());
- DCHECK(pseudo_style);
- pseudo_style->UpdateIsStackingContext(false /* is_document_element */,
- false /* is_in_top_layer */,
- false /* is_svg_stacking */);
- return pseudo_style;
+scoped_refptr<ComputedStyle>
+FirstLetterPseudoElement::CustomStyleForLayoutObject() {
+ LayoutObject* first_letter_text =
+ FirstLetterPseudoElement::FirstLetterTextLayoutObject(*this);
+ if (!first_letter_text)
+ return nullptr;
+ DCHECK(first_letter_text->Parent());
+ return ParentOrShadowHostElement()->StyleForPseudoElement(
+ PseudoStyleRequest(GetPseudoId()),
+ first_letter_text->Parent()->FirstLineStyle());
}
-void FirstLetterPseudoElement::AttachFirstLetterTextLayoutObjects() {
- LayoutObject* next_layout_object =
- FirstLetterPseudoElement::FirstLetterTextLayoutObject(*this);
- DCHECK(next_layout_object);
- DCHECK(next_layout_object->IsText());
+void FirstLetterPseudoElement::AttachFirstLetterTextLayoutObjects(LayoutText* first_letter_text) {
+ DCHECK(first_letter_text);
// The original string is going to be either a generated content string or a
// DOM node's string. We want the original string before it got transformed in
// case first-letter has no text-transform or a different text-transform
// applied to it.
- String old_text =
- ToLayoutText(next_layout_object)->IsTextFragment()
- ? ToLayoutTextFragment(next_layout_object)->CompleteText()
- : ToLayoutText(next_layout_object)->OriginalText();
+ String old_text = first_letter_text->IsTextFragment() ? ToLayoutTextFragment(first_letter_text)->CompleteText() : first_letter_text->OriginalText();
DCHECK(old_text.Impl());
- // :first-letter inherits from the parent of the text. It may not be
- // this->Parent() when e.g., <div><span>text</span></div>.
- ComputedStyle* pseudo_style =
- StyleForFirstLetter(next_layout_object->Parent());
- GetLayoutObject()->SetStyle(pseudo_style);
-
// FIXME: This would already have been calculated in firstLetterLayoutObject.
// Can we pass the length through?
unsigned length = FirstLetterPseudoElement::FirstLetterLength(old_text);
@@ -314,9 +303,9 @@ void FirstLetterPseudoElement::AttachFirstLetterTextLayoutObjects() {
// This text fragment might be empty.
LayoutTextFragment* remaining_text;
- if (next_layout_object->GetNode()) {
+ if (first_letter_text->GetNode()) {
remaining_text =
- new LayoutTextFragment(next_layout_object->GetNode(), old_text.Impl(),
+ new LayoutTextFragment(first_letter_text->GetNode(), old_text.Impl(),
length, remaining_length);
} else {
remaining_text = LayoutTextFragment::CreateAnonymous(
@@ -325,7 +314,7 @@ void FirstLetterPseudoElement::AttachFirstLetterTextLayoutObjects() {
remaining_text->SetFirstLetterPseudoElement(this);
remaining_text->SetIsRemainingTextLayoutObject(true);
- remaining_text->SetStyle(next_layout_object->MutableStyle());
+ remaining_text->SetStyle(first_letter_text->MutableStyle());
if (remaining_text->GetNode())
remaining_text->GetNode()->SetLayoutObject(remaining_text);
@@ -339,10 +328,10 @@ void FirstLetterPseudoElement::AttachFirstLetterTextLayoutObjects() {
LayoutTextFragment* letter =
LayoutTextFragment::CreateAnonymous(*this, old_text.Impl(), 0, length);
letter->SetFirstLetterPseudoElement(this);
- letter->SetStyle(pseudo_style);
+ letter->SetStyle(MutableComputedStyle());
GetLayoutObject()->AddChild(letter);
- next_layout_object->Destroy();
+ first_letter_text->Destroy();
}
void FirstLetterPseudoElement::DidRecalcStyle(StyleRecalcChange) {
@@ -350,30 +339,15 @@ void FirstLetterPseudoElement::DidRecalcStyle(StyleRecalcChange) {
if (!layout_object)
return;
- // :first-letter inherits from the parent of the text. It may not be
- // this->Parent() when e.g., <div><span>text</span></div>.
- DCHECK(remaining_text_layout_object_);
- ComputedStyle* pseudo_style =
- StyleForFirstLetter(remaining_text_layout_object_->Parent());
- DCHECK(pseudo_style);
- // TODO(kojii): While setting to GetLayoutObject() looks correct all the time,
- // as we do so in AttachFirstLetterTextLayoutObjects(), it is required only
- // when inline box has text children, and can break layout tree when changing
- // :first-letter to floats. The check in Element::UpdatePseudoElement() does
- // not catch all such cases.
- if (!pseudo_style->IsDisplayBlockContainer())
- layout_object->SetStyle(pseudo_style);
-
- // The layoutObjects inside pseudo elements are anonymous so they don't get
- // notified of recalcStyle and must have
- // the style propagated downward manually similar to
- // LayoutObject::propagateStyleToAnonymousChildren.
+ // The layout objects inside pseudo elements are anonymous so they don't get
+ // notified of RecalcStyle and must have the style propagated downward
+ // manually similar to LayoutObject::PropagateStyleToAnonymousChildren.
for (LayoutObject* child = layout_object->NextInPreOrder(layout_object);
child; child = child->NextInPreOrder(layout_object)) {
// We need to re-calculate the correct style for the first letter element
// and then apply that to the container and the text fragment inside.
if (child->Style()->StyleType() == kPseudoIdFirstLetter) {
- child->SetPseudoStyle(pseudo_style);
+ child->SetPseudoStyle(layout_object->MutableStyle());
continue;
}
diff --git a/chromium/third_party/blink/renderer/core/dom/first_letter_pseudo_element.h b/chromium/third_party/blink/renderer/core/dom/first_letter_pseudo_element.h
index d2794b029cd..6c8b5b1ccf8 100644
--- a/chromium/third_party/blink/renderer/core/dom/first_letter_pseudo_element.h
+++ b/chromium/third_party/blink/renderer/core/dom/first_letter_pseudo_element.h
@@ -33,7 +33,7 @@
namespace blink {
class Element;
-class LayoutObject;
+class LayoutText;
class LayoutTextFragment;
class CORE_EXPORT FirstLetterPseudoElement final : public PseudoElement {
@@ -44,7 +44,7 @@ class CORE_EXPORT FirstLetterPseudoElement final : public PseudoElement {
~FirstLetterPseudoElement() override;
- static LayoutObject* FirstLetterTextLayoutObject(const Element&);
+ static LayoutText* FirstLetterTextLayoutObject(const Element&);
static unsigned FirstLetterLength(const String&);
void SetRemainingTextLayoutObject(LayoutTextFragment*);
@@ -60,10 +60,10 @@ class CORE_EXPORT FirstLetterPseudoElement final : public PseudoElement {
private:
explicit FirstLetterPseudoElement(Element*);
+ scoped_refptr<ComputedStyle> CustomStyleForLayoutObject() override;
void DidRecalcStyle(StyleRecalcChange) override;
- void AttachFirstLetterTextLayoutObjects();
- ComputedStyle* StyleForFirstLetter(LayoutObject*);
+ void AttachFirstLetterTextLayoutObjects(LayoutText* first_letter_text);
LayoutTextFragment* remaining_text_layout_object_;
DISALLOW_COPY_AND_ASSIGN(FirstLetterPseudoElement);
diff --git a/chromium/third_party/blink/renderer/core/dom/flat_tree_traversal.cc b/chromium/third_party/blink/renderer/core/dom/flat_tree_traversal.cc
index 35b1842e3c6..f98a8b5775a 100644
--- a/chromium/third_party/blink/renderer/core/dom/flat_tree_traversal.cc
+++ b/chromium/third_party/blink/renderer/core/dom/flat_tree_traversal.cc
@@ -32,42 +32,36 @@
namespace blink {
+bool CanBeDistributedToV0InsertionPoint(const Node& node) {
+ return node.IsInV0ShadowTree() || node.IsChildOfV0ShadowHost();
+}
+
Node* FlatTreeTraversal::TraverseChild(const Node& node,
TraversalDirection direction) {
+ if (auto* slot = ToHTMLSlotElementIfSupportsAssignmentOrNull(node)) {
+ if (slot->AssignedNodes().IsEmpty()) {
+ return direction == kTraversalDirectionForward ? slot->firstChild()
+ : slot->lastChild();
+ }
+ return direction == kTraversalDirectionForward ? slot->FirstAssignedNode()
+ : slot->LastAssignedNode();
+ }
+ Node* child;
if (ShadowRoot* shadow_root = node.GetShadowRoot()) {
- return ResolveDistributionStartingAt(direction == kTraversalDirectionForward
- ? shadow_root->firstChild()
- : shadow_root->lastChild(),
- direction);
+ child = direction == kTraversalDirectionForward ? shadow_root->firstChild()
+ : shadow_root->lastChild();
+ } else {
+ child = direction == kTraversalDirectionForward ? node.firstChild()
+ : node.lastChild();
}
- return ResolveDistributionStartingAt(direction == kTraversalDirectionForward
- ? node.firstChild()
- : node.lastChild(),
- direction);
-}
-Node* FlatTreeTraversal::ResolveDistributionStartingAt(
- const Node* node,
- TraversalDirection direction) {
- if (!node)
+ if (!child)
return nullptr;
- for (const Node* sibling = node; sibling;
- sibling = (direction == kTraversalDirectionForward
- ? sibling->nextSibling()
- : sibling->previousSibling())) {
- if (const HTMLSlotElement* slot =
- ToHTMLSlotElementIfSupportsAssignmentOrNull(*sibling)) {
- if (Node* found = (direction == kTraversalDirectionForward
- ? slot->FirstDistributedNode()
- : slot->LastDistributedNode()))
- return found;
- continue;
- }
- if (node->IsInV0ShadowTree())
- return V0ResolveDistributionStartingAt(*sibling, direction);
- return const_cast<Node*>(sibling);
+
+ if (child->IsInV0ShadowTree()) {
+ return V0ResolveDistributionStartingAt(*child, direction);
}
- return nullptr;
+ return child;
}
Node* FlatTreeTraversal::V0ResolveDistributionStartingAt(
@@ -103,35 +97,29 @@ Node* FlatTreeTraversal::TraverseSiblings(const Node& node,
if (ShadowRootWhereNodeCanBeDistributedForV0(node))
return TraverseSiblingsForV0Distribution(node, direction);
- if (Node* found = ResolveDistributionStartingAt(
- direction == kTraversalDirectionForward ? node.nextSibling()
- : node.previousSibling(),
- direction))
- return found;
+ Node* sibling = direction == kTraversalDirectionForward
+ ? node.nextSibling()
+ : node.previousSibling();
- // Slotted nodes are already handled in traverseSiblingsForV1HostChild()
- // above, here is for fallback contents.
- if (auto* slot =
- ToHTMLSlotElementIfSupportsAssignmentOrNull(node.parentElement())) {
- if (slot->AssignedNodes().IsEmpty())
- return TraverseSiblings(*slot, direction);
- }
+ if (!node.IsInV0ShadowTree())
+ return sibling;
+ if (sibling) {
+ if (Node* found = V0ResolveDistributionStartingAt(*sibling, direction))
+ return found;
+ }
return nullptr;
}
Node* FlatTreeTraversal::TraverseSiblingsForV1HostChild(
const Node& node,
TraversalDirection direction) {
- HTMLSlotElement* slot = node.FinalDestinationSlot();
+ HTMLSlotElement* slot = node.AssignedSlot();
if (!slot)
return nullptr;
- if (Node* sibling_in_distributed_nodes =
- (direction == kTraversalDirectionForward
- ? slot->DistributedNodeNextTo(node)
- : slot->DistributedNodePreviousTo(node)))
- return sibling_in_distributed_nodes;
- return TraverseSiblings(*slot, direction);
+ return direction == kTraversalDirectionForward
+ ? slot->AssignedNodeNextTo(node)
+ : slot->AssignedNodePreviousTo(node);
}
Node* FlatTreeTraversal::TraverseSiblingsForV0Distribution(
@@ -155,18 +143,14 @@ ContainerNode* FlatTreeTraversal::TraverseParent(
if (node.IsPseudoElement())
return node.ParentOrShadowHostNode();
- if (node.IsChildOfV1ShadowHost()) {
- HTMLSlotElement* slot = node.FinalDestinationSlot();
- if (!slot)
- return nullptr;
- return TraverseParent(*slot);
- }
+ if (node.IsChildOfV1ShadowHost())
+ return node.AssignedSlot();
- if (auto* slot =
+ if (auto* parent_slot =
ToHTMLSlotElementIfSupportsAssignmentOrNull(node.parentElement())) {
- if (!slot->AssignedNodes().IsEmpty())
+ if (!parent_slot->AssignedNodes().IsEmpty())
return nullptr;
- return TraverseParent(*slot, details);
+ return parent_slot;
}
if (CanBeDistributedToV0InsertionPoint(node))
@@ -208,8 +192,6 @@ ContainerNode* FlatTreeTraversal::TraverseParentOrHost(const Node& node) {
}
Node* FlatTreeTraversal::ChildAt(const Node& node, unsigned index) {
- if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
- return FlatTreeTraversalNg::ChildAt(node, index);
AssertPrecondition(node);
Node* child = TraverseFirstChild(node);
while (child && index--)
@@ -219,8 +201,6 @@ Node* FlatTreeTraversal::ChildAt(const Node& node, unsigned index) {
}
Node* FlatTreeTraversal::NextSkippingChildren(const Node& node) {
- if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
- return FlatTreeTraversalNg::NextSkippingChildren(node);
if (Node* next_sibling = TraverseNextSibling(node))
return next_sibling;
return TraverseNextAncestorSibling(node);
@@ -229,8 +209,6 @@ Node* FlatTreeTraversal::NextSkippingChildren(const Node& node) {
bool FlatTreeTraversal::ContainsIncludingPseudoElement(
const ContainerNode& container,
const Node& node) {
- if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
- return FlatTreeTraversalNg::ContainsIncludingPseudoElement(container, node);
AssertPrecondition(container);
AssertPrecondition(node);
// This can be slower than FlatTreeTraversal::contains() because we
@@ -244,8 +222,6 @@ bool FlatTreeTraversal::ContainsIncludingPseudoElement(
}
Node* FlatTreeTraversal::PreviousSkippingChildren(const Node& node) {
- if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
- return FlatTreeTraversalNg::PreviousSkippingChildren(node);
if (Node* previous_sibling = TraversePreviousSibling(node))
return previous_sibling;
return TraversePreviousAncestorSibling(node);
@@ -269,8 +245,6 @@ Node* FlatTreeTraversal::PreviousAncestorSiblingPostOrder(
// between DOM tree traversal and flat tree tarversal.
Node* FlatTreeTraversal::PreviousPostOrder(const Node& current,
const Node* stay_within) {
- if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
- return FlatTreeTraversalNg::PreviousPostOrder(current, stay_within);
AssertPrecondition(current);
if (stay_within)
AssertPrecondition(*stay_within);
@@ -288,8 +262,6 @@ Node* FlatTreeTraversal::PreviousPostOrder(const Node& current,
}
bool FlatTreeTraversal::IsDescendantOf(const Node& node, const Node& other) {
- if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
- return FlatTreeTraversalNg::IsDescendantOf(node, other);
AssertPrecondition(node);
AssertPrecondition(other);
if (!HasChildren(other) || node.isConnected() != other.isConnected())
@@ -304,8 +276,6 @@ bool FlatTreeTraversal::IsDescendantOf(const Node& node, const Node& other) {
Node* FlatTreeTraversal::CommonAncestor(const Node& node_a,
const Node& node_b) {
- if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
- return FlatTreeTraversalNg::CommonAncestor(node_a, node_b);
AssertPrecondition(node_a);
AssertPrecondition(node_b);
Node* result = node_a.CommonAncestor(
@@ -335,8 +305,6 @@ Node* FlatTreeTraversal::TraversePreviousAncestorSibling(const Node& node) {
}
unsigned FlatTreeTraversal::Index(const Node& node) {
- if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
- return FlatTreeTraversalNg::Index(node);
AssertPrecondition(node);
unsigned count = 0;
for (Node* runner = TraversePreviousSibling(node); runner;
@@ -346,8 +314,6 @@ unsigned FlatTreeTraversal::Index(const Node& node) {
}
unsigned FlatTreeTraversal::CountChildren(const Node& node) {
- if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
- return FlatTreeTraversalNg::CountChildren(node);
AssertPrecondition(node);
unsigned count = 0;
for (Node* runner = TraverseFirstChild(node); runner;
@@ -357,8 +323,6 @@ unsigned FlatTreeTraversal::CountChildren(const Node& node) {
}
Node* FlatTreeTraversal::LastWithin(const Node& node) {
- if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
- return FlatTreeTraversalNg::LastWithin(node);
AssertPrecondition(node);
Node* descendant = TraverseLastChild(node);
for (Node* child = descendant; child; child = LastChild(*child))
@@ -368,8 +332,6 @@ Node* FlatTreeTraversal::LastWithin(const Node& node) {
}
Node& FlatTreeTraversal::LastWithinOrSelf(const Node& node) {
- if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
- return FlatTreeTraversalNg::LastWithinOrSelf(node);
AssertPrecondition(node);
Node* last_descendant = LastWithin(node);
Node& result = last_descendant ? *last_descendant : const_cast<Node&>(node);
diff --git a/chromium/third_party/blink/renderer/core/dom/flat_tree_traversal.h b/chromium/third_party/blink/renderer/core/dom/flat_tree_traversal.h
index 829bde11117..31054b6bba6 100644
--- a/chromium/third_party/blink/renderer/core/dom/flat_tree_traversal.h
+++ b/chromium/third_party/blink/renderer/core/dom/flat_tree_traversal.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/flat_tree_traversal_ng.h"
#include "third_party/blink/renderer/core/dom/layout_tree_builder_traversal.h"
#include "third_party/blink/renderer/core/dom/node_traversal.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
@@ -41,6 +40,8 @@ namespace blink {
class ContainerNode;
class Node;
+bool CanBeDistributedToV0InsertionPoint(const Node& node);
+
// Flat tree version of |NodeTraversal|.
//
// None of member functions takes a |ShadowRoot| or an active insertion point,
@@ -48,9 +49,6 @@ class Node;
// |InsertionPoint::isActive()| for details of active insertion points, since
// they aren't appeared in the flat tree. |assertPrecondition()| and
// |assertPostCondition()| check this condition.
-//
-// FIXME: Make some functions inline to optimise the performance.
-// https://bugs.webkit.org/show_bug.cgi?id=82702
class CORE_EXPORT FlatTreeTraversal {
STATIC_ONLY(FlatTreeTraversal);
@@ -98,8 +96,6 @@ class CORE_EXPORT FlatTreeTraversal {
static bool IsDescendantOf(const Node& /*node*/, const Node& other);
static bool Contains(const ContainerNode& container, const Node& node) {
- if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
- return FlatTreeTraversalNg::Contains(container, node);
AssertPrecondition(container);
AssertPrecondition(node);
return container == node || IsDescendantOf(node, container);
@@ -194,8 +190,6 @@ class CORE_EXPORT FlatTreeTraversal {
inline ContainerNode* FlatTreeTraversal::Parent(
const Node& node,
ParentTraversalDetails* details) {
- if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
- return FlatTreeTraversalNg::Parent(node, details);
AssertPrecondition(node);
ContainerNode* result = TraverseParent(node, details);
AssertPostcondition(result);
@@ -203,15 +197,11 @@ inline ContainerNode* FlatTreeTraversal::Parent(
}
inline Element* FlatTreeTraversal::ParentElement(const Node& node) {
- if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
- return FlatTreeTraversalNg::ParentElement(node);
ContainerNode* parent = FlatTreeTraversal::Parent(node);
return parent && parent->IsElementNode() ? ToElement(parent) : nullptr;
}
inline Node* FlatTreeTraversal::NextSibling(const Node& node) {
- if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
- return FlatTreeTraversalNg::NextSibling(node);
AssertPrecondition(node);
Node* result = TraverseSiblings(node, kTraversalDirectionForward);
AssertPostcondition(result);
@@ -219,8 +209,6 @@ inline Node* FlatTreeTraversal::NextSibling(const Node& node) {
}
inline Node* FlatTreeTraversal::PreviousSibling(const Node& node) {
- if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
- return FlatTreeTraversalNg::PreviousSibling(node);
AssertPrecondition(node);
Node* result = TraverseSiblings(node, kTraversalDirectionBackward);
AssertPostcondition(result);
@@ -228,8 +216,6 @@ inline Node* FlatTreeTraversal::PreviousSibling(const Node& node) {
}
inline Node* FlatTreeTraversal::Next(const Node& node) {
- if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
- return FlatTreeTraversalNg::Next(node);
AssertPrecondition(node);
Node* result = TraverseNext(node);
AssertPostcondition(result);
@@ -238,8 +224,6 @@ inline Node* FlatTreeTraversal::Next(const Node& node) {
inline Node* FlatTreeTraversal::Next(const Node& node,
const Node* stay_within) {
- if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
- return FlatTreeTraversalNg::Next(node, stay_within);
AssertPrecondition(node);
Node* result = TraverseNext(node, stay_within);
AssertPostcondition(result);
@@ -248,8 +232,6 @@ inline Node* FlatTreeTraversal::Next(const Node& node,
inline Node* FlatTreeTraversal::NextSkippingChildren(const Node& node,
const Node* stay_within) {
- if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
- return FlatTreeTraversalNg::NextSkippingChildren(node, stay_within);
AssertPrecondition(node);
Node* result = TraverseNextSkippingChildren(node, stay_within);
AssertPostcondition(result);
@@ -286,8 +268,6 @@ inline Node* FlatTreeTraversal::TraverseNextSkippingChildren(
}
inline Node* FlatTreeTraversal::Previous(const Node& node) {
- if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
- return FlatTreeTraversalNg::Previous(node);
AssertPrecondition(node);
Node* result = TraversePrevious(node);
AssertPostcondition(result);
@@ -304,8 +284,6 @@ inline Node* FlatTreeTraversal::TraversePrevious(const Node& node) {
}
inline Node* FlatTreeTraversal::FirstChild(const Node& node) {
- if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
- return FlatTreeTraversalNg::FirstChild(node);
AssertPrecondition(node);
Node* result = TraverseChild(node, kTraversalDirectionForward);
AssertPostcondition(result);
@@ -313,8 +291,6 @@ inline Node* FlatTreeTraversal::FirstChild(const Node& node) {
}
inline Node* FlatTreeTraversal::LastChild(const Node& node) {
- if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
- return FlatTreeTraversalNg::LastChild(node);
AssertPrecondition(node);
Node* result = TraverseLastChild(node);
AssertPostcondition(result);
@@ -360,4 +336,4 @@ FlatTreeTraversal::InclusiveAncestorsOf(const Node& node) {
} // namespace blink
-#endif
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_DOM_FLAT_TREE_TRAVERSAL_H_
diff --git a/chromium/third_party/blink/renderer/core/dom/flat_tree_traversal_ng.cc b/chromium/third_party/blink/renderer/core/dom/flat_tree_traversal_ng.cc
deleted file mode 100644
index c6500a0c739..00000000000
--- a/chromium/third_party/blink/renderer/core/dom/flat_tree_traversal_ng.cc
+++ /dev/null
@@ -1,368 +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.
- * * 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/dom/flat_tree_traversal_ng.h"
-
-#include "third_party/blink/renderer/core/dom/element.h"
-#include "third_party/blink/renderer/core/html/html_shadow_element.h"
-#include "third_party/blink/renderer/core/html/html_slot_element.h"
-
-namespace blink {
-
-bool CanBeDistributedToV0InsertionPoint(const Node& node) {
- return node.IsInV0ShadowTree() || node.IsChildOfV0ShadowHost();
-}
-
-Node* FlatTreeTraversalNg::TraverseChild(const Node& node,
- TraversalDirection direction) {
- if (auto* slot = ToHTMLSlotElementIfSupportsAssignmentOrNull(node)) {
- if (slot->AssignedNodes().IsEmpty()) {
- return direction == kTraversalDirectionForward ? slot->firstChild()
- : slot->lastChild();
- }
- return direction == kTraversalDirectionForward ? slot->FirstAssignedNode()
- : slot->LastAssignedNode();
- }
-
- Node* child;
- if (ShadowRoot* shadow_root = node.GetShadowRoot()) {
- child = direction == kTraversalDirectionForward ? shadow_root->firstChild()
- : shadow_root->lastChild();
- } else {
- child = direction == kTraversalDirectionForward ? node.firstChild()
- : node.lastChild();
- }
-
- if (!child)
- return nullptr;
-
- if (child->IsInV0ShadowTree()) {
- return V0ResolveDistributionStartingAt(*child, direction);
- }
- return child;
-}
-
-// This needs only for v0
-// Node* FlatTreeTraversalNg::ResolveDistributionStartingAt(
-// const Node* node,
-// TraversalDirection direction) {
-// if (!node)
-// return nullptr;
-// for (const Node* sibling = node; sibling;
-// sibling = (direction == kTraversalDirectionForward
-// ? sibling->nextSibling()
-// : sibling->previousSibling())) {
-// if (node->IsInV0ShadowTree())
-// return V0ResolveDistributionStartingAt(*sibling, direction);
-// return const_cast<Node*>(sibling);
-// }
-// return nullptr;
-// }
-
-Node* FlatTreeTraversalNg::V0ResolveDistributionStartingAt(
- const Node& node,
- TraversalDirection direction) {
- DCHECK(!ToHTMLSlotElementIfSupportsAssignmentOrNull(node));
- for (const Node* sibling = &node; sibling;
- sibling = (direction == kTraversalDirectionForward
- ? sibling->nextSibling()
- : sibling->previousSibling())) {
- if (!IsActiveV0InsertionPoint(*sibling))
- return const_cast<Node*>(sibling);
- const V0InsertionPoint& insertion_point = ToV0InsertionPoint(*sibling);
- if (Node* found = (direction == kTraversalDirectionForward
- ? insertion_point.FirstDistributedNode()
- : insertion_point.LastDistributedNode()))
- return found;
- DCHECK(IsHTMLShadowElement(insertion_point) ||
- (IsHTMLContentElement(insertion_point) &&
- !insertion_point.HasChildren()));
- }
- return nullptr;
-}
-
-// TODO(hayato): This may return a wrong result for a node which is not in a
-// document flat tree. See FlatTreeTraversalNgTest's redistribution test for
-// details.
-Node* FlatTreeTraversalNg::TraverseSiblings(const Node& node,
- TraversalDirection direction) {
- if (node.IsChildOfV1ShadowHost())
- return TraverseSiblingsForV1HostChild(node, direction);
-
- if (ShadowRootWhereNodeCanBeDistributedForV0(node))
- return TraverseSiblingsForV0Distribution(node, direction);
-
- Node* sibling = direction == kTraversalDirectionForward
- ? node.nextSibling()
- : node.previousSibling();
-
- if (!node.IsInV0ShadowTree())
- return sibling;
-
- if (sibling) {
- if (Node* found = V0ResolveDistributionStartingAt(*sibling, direction))
- return found;
- }
-
- // // Slotted nodes are already handled in traverseSiblingsForV1HostChild()
- // // above, here is for fallback contents.
- // if (auto* slot = ToHTMLSlotElementOrNull(node.parentElement())) {
- // if (slot->SupportsAssignment() && slot->AssignedNodes().IsEmpty())
- // return TraverseSiblings(*slot, direction);
- // }
- return nullptr;
-}
-
-Node* FlatTreeTraversalNg::TraverseSiblingsForV1HostChild(
- const Node& node,
- TraversalDirection direction) {
- HTMLSlotElement* slot = node.AssignedSlot();
- if (!slot)
- return nullptr;
- return direction == kTraversalDirectionForward
- ? slot->AssignedNodeNextTo(node)
- : slot->AssignedNodePreviousTo(node);
-}
-
-Node* FlatTreeTraversalNg::TraverseSiblingsForV0Distribution(
- const Node& node,
- TraversalDirection direction) {
- const V0InsertionPoint* final_destination = ResolveReprojection(&node);
- if (!final_destination)
- return nullptr;
- if (Node* found = (direction == kTraversalDirectionForward
- ? final_destination->DistributedNodeNextTo(&node)
- : final_destination->DistributedNodePreviousTo(&node)))
- return found;
- return TraverseSiblings(*final_destination, direction);
-}
-
-ContainerNode* FlatTreeTraversalNg::TraverseParent(
- const Node& node,
- ParentTraversalDetails* details) {
- // TODO(hayato): Stop this hack for a pseudo element because a pseudo element
- // is not a child of its parentOrShadowHostNode() in a flat tree.
- if (node.IsPseudoElement())
- return node.ParentOrShadowHostNode();
-
- if (node.IsChildOfV1ShadowHost())
- return node.AssignedSlot();
-
- if (auto* parent_slot =
- ToHTMLSlotElementIfSupportsAssignmentOrNull(node.parentElement())) {
- if (!parent_slot->AssignedNodes().IsEmpty())
- return nullptr;
- return parent_slot;
- }
-
- if (CanBeDistributedToV0InsertionPoint(node))
- return TraverseParentForV0(node, details);
-
- DCHECK(!ShadowRootWhereNodeCanBeDistributedForV0(node));
- return TraverseParentOrHost(node);
-}
-
-ContainerNode* FlatTreeTraversalNg::TraverseParentForV0(
- const Node& node,
- ParentTraversalDetails* details) {
- if (ShadowRootWhereNodeCanBeDistributedForV0(node)) {
- if (const V0InsertionPoint* insertion_point = ResolveReprojection(&node)) {
- if (details)
- details->DidTraverseInsertionPoint(insertion_point);
- // The node is distributed. But the distribution was stopped at this
- // insertion point.
- if (ShadowRootWhereNodeCanBeDistributedForV0(*insertion_point))
- return nullptr;
- return TraverseParent(*insertion_point);
- }
- return nullptr;
- }
- ContainerNode* parent = TraverseParentOrHost(node);
- if (IsActiveV0InsertionPoint(*parent))
- return nullptr;
- return parent;
-}
-
-ContainerNode* FlatTreeTraversalNg::TraverseParentOrHost(const Node& node) {
- ContainerNode* parent = node.parentNode();
- if (!parent)
- return nullptr;
- if (!parent->IsShadowRoot())
- return parent;
- ShadowRoot* shadow_root = ToShadowRoot(parent);
- return &shadow_root->host();
-}
-
-Node* FlatTreeTraversalNg::ChildAt(const Node& node, unsigned index) {
- AssertPrecondition(node);
- Node* child = TraverseFirstChild(node);
- while (child && index--)
- child = NextSibling(*child);
- AssertPostcondition(child);
- return child;
-}
-
-Node* FlatTreeTraversalNg::NextSkippingChildren(const Node& node) {
- if (Node* next_sibling = TraverseNextSibling(node))
- return next_sibling;
- return TraverseNextAncestorSibling(node);
-}
-
-bool FlatTreeTraversalNg::ContainsIncludingPseudoElement(
- const ContainerNode& container,
- const Node& node) {
- AssertPrecondition(container);
- AssertPrecondition(node);
- // This can be slower than FlatTreeTraversalNg::contains() because we
- // can't early exit even when container doesn't have children.
- for (const Node* current = &node; current;
- current = TraverseParent(*current)) {
- if (current == &container)
- return true;
- }
- return false;
-}
-
-Node* FlatTreeTraversalNg::PreviousSkippingChildren(const Node& node) {
- if (Node* previous_sibling = TraversePreviousSibling(node))
- return previous_sibling;
- return TraversePreviousAncestorSibling(node);
-}
-
-Node* FlatTreeTraversalNg::PreviousAncestorSiblingPostOrder(
- const Node& current,
- const Node* stay_within) {
- DCHECK(!FlatTreeTraversalNg::PreviousSibling(current));
- for (Node* parent = FlatTreeTraversalNg::Parent(current); parent;
- parent = FlatTreeTraversalNg::Parent(*parent)) {
- if (parent == stay_within)
- return nullptr;
- if (Node* previous_sibling = FlatTreeTraversalNg::PreviousSibling(*parent))
- return previous_sibling;
- }
- return nullptr;
-}
-
-// TODO(yosin) We should consider introducing template class to share code
-// between DOM tree traversal and flat tree tarversal.
-Node* FlatTreeTraversalNg::PreviousPostOrder(const Node& current,
- const Node* stay_within) {
- AssertPrecondition(current);
- if (stay_within)
- AssertPrecondition(*stay_within);
- if (Node* last_child = TraverseLastChild(current)) {
- AssertPostcondition(last_child);
- return last_child;
- }
- if (current == stay_within)
- return nullptr;
- if (Node* previous_sibling = TraversePreviousSibling(current)) {
- AssertPostcondition(previous_sibling);
- return previous_sibling;
- }
- return PreviousAncestorSiblingPostOrder(current, stay_within);
-}
-
-bool FlatTreeTraversalNg::IsDescendantOf(const Node& node, const Node& other) {
- AssertPrecondition(node);
- AssertPrecondition(other);
- if (!HasChildren(other) || node.isConnected() != other.isConnected())
- return false;
- for (const ContainerNode* n = TraverseParent(node); n;
- n = TraverseParent(*n)) {
- if (n == other)
- return true;
- }
- return false;
-}
-
-Node* FlatTreeTraversalNg::CommonAncestor(const Node& node_a,
- const Node& node_b) {
- AssertPrecondition(node_a);
- AssertPrecondition(node_b);
- Node* result = node_a.CommonAncestor(node_b, [](const Node& node) {
- return FlatTreeTraversalNg::Parent(node);
- });
- AssertPostcondition(result);
- return result;
-}
-
-Node* FlatTreeTraversalNg::TraverseNextAncestorSibling(const Node& node) {
- DCHECK(!TraverseNextSibling(node));
- for (Node* parent = TraverseParent(node); parent;
- parent = TraverseParent(*parent)) {
- if (Node* next_sibling = TraverseNextSibling(*parent))
- return next_sibling;
- }
- return nullptr;
-}
-
-Node* FlatTreeTraversalNg::TraversePreviousAncestorSibling(const Node& node) {
- DCHECK(!TraversePreviousSibling(node));
- for (Node* parent = TraverseParent(node); parent;
- parent = TraverseParent(*parent)) {
- if (Node* previous_sibling = TraversePreviousSibling(*parent))
- return previous_sibling;
- }
- return nullptr;
-}
-
-unsigned FlatTreeTraversalNg::Index(const Node& node) {
- AssertPrecondition(node);
- unsigned count = 0;
- for (Node* runner = TraversePreviousSibling(node); runner;
- runner = PreviousSibling(*runner))
- ++count;
- return count;
-}
-
-unsigned FlatTreeTraversalNg::CountChildren(const Node& node) {
- AssertPrecondition(node);
- unsigned count = 0;
- for (Node* runner = TraverseFirstChild(node); runner;
- runner = TraverseNextSibling(*runner))
- ++count;
- return count;
-}
-
-Node* FlatTreeTraversalNg::LastWithin(const Node& node) {
- AssertPrecondition(node);
- Node* descendant = TraverseLastChild(node);
- for (Node* child = descendant; child; child = LastChild(*child))
- descendant = child;
- AssertPostcondition(descendant);
- return descendant;
-}
-
-Node& FlatTreeTraversalNg::LastWithinOrSelf(const Node& node) {
- AssertPrecondition(node);
- Node* last_descendant = LastWithin(node);
- Node& result = last_descendant ? *last_descendant : const_cast<Node&>(node);
- AssertPostcondition(&result);
- return result;
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/dom/flat_tree_traversal_ng.h b/chromium/third_party/blink/renderer/core/dom/flat_tree_traversal_ng.h
deleted file mode 100644
index bb93d2a749f..00000000000
--- a/chromium/third_party/blink/renderer/core/dom/flat_tree_traversal_ng.h
+++ /dev/null
@@ -1,331 +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.
- * * 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_DOM_FLAT_TREE_TRAVERSAL_NG_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_FLAT_TREE_TRAVERSAL_NG_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/layout_tree_builder_traversal.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/dom/v0_insertion_point.h"
-#include "third_party/blink/renderer/platform/wtf/allocator.h"
-
-namespace blink {
-
-class ContainerNode;
-class Node;
-
-bool CanBeDistributedToV0InsertionPoint(const Node& node);
-
-// Flat tree version of |NodeTraversal|.
-//
-// None of member functions takes a |ShadowRoot| or an active insertion point,
-// e.g. roughly speaking <content> and <shadow> in the shadow tree, see
-// |InsertionPoint::isActive()| for details of active insertion points, since
-// they aren't appeared in the flat tree. |assertPrecondition()| and
-// |assertPostCondition()| check this condition.
-//
-// FIXME: Make some functions inline to optimise the performance.
-// https://bugs.webkit.org/show_bug.cgi?id=82702
-class CORE_EXPORT FlatTreeTraversalNg {
- STATIC_ONLY(FlatTreeTraversalNg);
-
- public:
- typedef LayoutTreeBuilderTraversal::ParentDetails ParentTraversalDetails;
- using TraversalNodeType = Node;
-
- static Node* Next(const Node&);
- static Node* Next(const Node&, const Node* stay_within);
- static Node* Previous(const Node&);
-
- static Node* FirstChild(const Node&);
- static Node* LastChild(const Node&);
- static bool HasChildren(const Node&);
-
- static ContainerNode* Parent(const Node&, ParentTraversalDetails* = nullptr);
- static Element* ParentElement(const Node&);
-
- static Node* NextSibling(const Node&);
- static Node* PreviousSibling(const Node&);
-
- // Returns a child node at |index|. If |index| is greater than or equal to
- // the children, this function returns |nullptr|.
- static Node* ChildAt(const Node&, unsigned index);
-
- // Flat tree version of |NodeTraversal::nextSkippingChildren()|. This
- // function is similar to |next()| but skips child nodes of a specified
- // node.
- static Node* NextSkippingChildren(const Node&);
- static Node* NextSkippingChildren(const Node&, const Node* stay_within);
-
- static Node* FirstWithin(const Node& current) { return FirstChild(current); }
-
- // Flat tree version of |NodeTraversal::previousSkippingChildren()|
- // similar to |previous()| but skipping child nodes of the specified node.
- static Node* PreviousSkippingChildren(const Node&);
-
- // Like previous, but visits parents before their children.
- static Node* PreviousPostOrder(const Node&,
- const Node* stay_within = nullptr);
-
- // Flat tree version of |Node::isDescendantOf(other)|. This function
- // returns true if |other| contains |node|, otherwise returns
- // false. If |other| is |node|, this function returns false.
- static bool IsDescendantOf(const Node& /*node*/, const Node& other);
-
- static bool Contains(const ContainerNode& container, const Node& node) {
- AssertPrecondition(container);
- AssertPrecondition(node);
- return container == node || IsDescendantOf(node, container);
- }
-
- static bool ContainsIncludingPseudoElement(const ContainerNode&, const Node&);
-
- // Returns a common ancestor of |nodeA| and |nodeB| if exists, otherwise
- // returns |nullptr|.
- static Node* CommonAncestor(const Node& node_a, const Node& node_b);
-
- // Flat tree version of |Node::nodeIndex()|. This function returns a
- // zero base position number of the specified node in child nodes list, or
- // zero if the specified node has no parent.
- static unsigned Index(const Node&);
-
- // Flat tree version of |ContainerNode::countChildren()|. This function
- // returns the number of the child nodes of the specified node in the
- // flat tree.
- static unsigned CountChildren(const Node&);
-
- static Node* LastWithin(const Node&);
- static Node& LastWithinOrSelf(const Node&);
-
- // Flat tree range helper functions for range based for statement.
- // TODO(dom-team): We should have following functions to match with
- // |NodeTraversal|:
- // - AncestorsOf()
- // - DescendantsOf()
- // - InclusiveAncestorsOf()
- // - InclusiveDescendantsOf()
- // - StartsAt()
- // - StartsAfter()
- static TraversalRange<TraversalChildrenIterator<FlatTreeTraversalNg>>
- ChildrenOf(const Node&);
-
- private:
- enum TraversalDirection {
- kTraversalDirectionForward,
- kTraversalDirectionBackward
- };
-
- static void AssertPrecondition(const Node& node) {
- DCHECK(!node.NeedsDistributionRecalc());
- DCHECK(node.CanParticipateInFlatTree());
- }
-
- static void AssertPostcondition(const Node* node) {
-#if DCHECK_IS_ON()
- if (node)
- AssertPrecondition(*node);
-#endif
- }
-
- // static Node* ResolveDistributionStartingAt(const Node*,
- // TraversalDirection);
- static Node* V0ResolveDistributionStartingAt(const Node&, TraversalDirection);
-
- static Node* TraverseNext(const Node&);
- static Node* TraverseNext(const Node&, const Node* stay_within);
- static Node* TraverseNextSkippingChildren(const Node&,
- const Node* stay_within);
- static Node* TraversePrevious(const Node&);
-
- static Node* TraverseFirstChild(const Node&);
- static Node* TraverseLastChild(const Node&);
- static Node* TraverseChild(const Node&, TraversalDirection);
-
- static ContainerNode* TraverseParent(const Node&,
- ParentTraversalDetails* = nullptr);
- // TODO(hayato): Make ParentTraversalDetails be aware of slot elements too.
- static ContainerNode* TraverseParentForV0(const Node&,
- ParentTraversalDetails* = nullptr);
- static ContainerNode* TraverseParentOrHost(const Node&);
-
- static Node* TraverseNextSibling(const Node&);
- static Node* TraversePreviousSibling(const Node&);
-
- static Node* TraverseSiblings(const Node&, TraversalDirection);
- static Node* TraverseSiblingsForV1HostChild(const Node&, TraversalDirection);
- static Node* TraverseSiblingsForV0Distribution(const Node&,
- TraversalDirection);
-
- static Node* TraverseNextAncestorSibling(const Node&);
- static Node* TraversePreviousAncestorSibling(const Node&);
- static Node* PreviousAncestorSiblingPostOrder(const Node& current,
- const Node* stay_within);
-};
-
-inline ContainerNode* FlatTreeTraversalNg::Parent(
- const Node& node,
- ParentTraversalDetails* details) {
- AssertPrecondition(node);
- ContainerNode* result = TraverseParent(node, details);
- AssertPostcondition(result);
- return result;
-}
-
-inline Element* FlatTreeTraversalNg::ParentElement(const Node& node) {
- ContainerNode* parent = FlatTreeTraversalNg::Parent(node);
- return parent && parent->IsElementNode() ? ToElement(parent) : nullptr;
-}
-
-inline Node* FlatTreeTraversalNg::NextSibling(const Node& node) {
- AssertPrecondition(node);
- Node* result = TraverseSiblings(node, kTraversalDirectionForward);
- AssertPostcondition(result);
- return result;
-}
-
-inline Node* FlatTreeTraversalNg::PreviousSibling(const Node& node) {
- AssertPrecondition(node);
- Node* result = TraverseSiblings(node, kTraversalDirectionBackward);
- AssertPostcondition(result);
- return result;
-}
-
-inline Node* FlatTreeTraversalNg::Next(const Node& node) {
- AssertPrecondition(node);
- Node* result = TraverseNext(node);
- AssertPostcondition(result);
- return result;
-}
-
-inline Node* FlatTreeTraversalNg::Next(const Node& node,
- const Node* stay_within) {
- AssertPrecondition(node);
- Node* result = TraverseNext(node, stay_within);
- AssertPostcondition(result);
- return result;
-}
-
-inline Node* FlatTreeTraversalNg::NextSkippingChildren(
- const Node& node,
- const Node* stay_within) {
- AssertPrecondition(node);
- Node* result = TraverseNextSkippingChildren(node, stay_within);
- AssertPostcondition(result);
- return result;
-}
-
-inline Node* FlatTreeTraversalNg::TraverseNext(const Node& node) {
- if (Node* next = TraverseFirstChild(node))
- return next;
- for (const Node* next = &node; next; next = TraverseParent(*next)) {
- if (Node* sibling = TraverseNextSibling(*next))
- return sibling;
- }
- return nullptr;
-}
-
-inline Node* FlatTreeTraversalNg::TraverseNext(const Node& node,
- const Node* stay_within) {
- if (Node* next = TraverseFirstChild(node))
- return next;
- return TraverseNextSkippingChildren(node, stay_within);
-}
-
-inline Node* FlatTreeTraversalNg::TraverseNextSkippingChildren(
- const Node& node,
- const Node* stay_within) {
- for (const Node* next = &node; next; next = TraverseParent(*next)) {
- if (next == stay_within)
- return nullptr;
- if (Node* sibling = TraverseNextSibling(*next))
- return sibling;
- }
- return nullptr;
-}
-
-inline Node* FlatTreeTraversalNg::Previous(const Node& node) {
- AssertPrecondition(node);
- Node* result = TraversePrevious(node);
- AssertPostcondition(result);
- return result;
-}
-
-inline Node* FlatTreeTraversalNg::TraversePrevious(const Node& node) {
- if (Node* previous = TraversePreviousSibling(node)) {
- while (Node* child = TraverseLastChild(*previous))
- previous = child;
- return previous;
- }
- return TraverseParent(node);
-}
-
-inline Node* FlatTreeTraversalNg::FirstChild(const Node& node) {
- AssertPrecondition(node);
- Node* result = TraverseChild(node, kTraversalDirectionForward);
- AssertPostcondition(result);
- return result;
-}
-
-inline Node* FlatTreeTraversalNg::LastChild(const Node& node) {
- AssertPrecondition(node);
- Node* result = TraverseLastChild(node);
- AssertPostcondition(result);
- return result;
-}
-
-inline bool FlatTreeTraversalNg::HasChildren(const Node& node) {
- return FirstChild(node);
-}
-
-inline Node* FlatTreeTraversalNg::TraverseNextSibling(const Node& node) {
- return TraverseSiblings(node, kTraversalDirectionForward);
-}
-
-inline Node* FlatTreeTraversalNg::TraversePreviousSibling(const Node& node) {
- return TraverseSiblings(node, kTraversalDirectionBackward);
-}
-
-inline Node* FlatTreeTraversalNg::TraverseFirstChild(const Node& node) {
- return TraverseChild(node, kTraversalDirectionForward);
-}
-
-inline Node* FlatTreeTraversalNg::TraverseLastChild(const Node& node) {
- return TraverseChild(node, kTraversalDirectionBackward);
-}
-
-// TraverseRange<T> implementations
-inline TraversalRange<TraversalChildrenIterator<FlatTreeTraversalNg>>
-FlatTreeTraversalNg::ChildrenOf(const Node& parent) {
- return TraversalRange<TraversalChildrenIterator<FlatTreeTraversalNg>>(
- &parent);
-}
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_DOM_FLAT_TREE_TRAVERSAL_NG_H_
diff --git a/chromium/third_party/blink/renderer/core/dom/flat_tree_traversal_ng_test.cc b/chromium/third_party/blink/renderer/core/dom/flat_tree_traversal_ng_test.cc
deleted file mode 100644
index 7f909cc882a..00000000000
--- a/chromium/third_party/blink/renderer/core/dom/flat_tree_traversal_ng_test.cc
+++ /dev/null
@@ -1,772 +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/dom/flat_tree_traversal_ng.h"
-
-#include <memory>
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/core/dom/document.h"
-#include "third_party/blink/renderer/core/dom/element.h"
-#include "third_party/blink/renderer/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/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"
-#include "third_party/blink/renderer/platform/bindings/exception_state.h"
-#include "third_party/blink/renderer/platform/geometry/int_size.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/wtf/compiler.h"
-#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
-#include "third_party/blink/renderer/platform/wtf/vector.h"
-
-namespace blink {
-// To avoid symbol collisions in jumbo builds.
-namespace flat_tree_traversal_ng_test {
-
-class FlatTreeTraversalNgTest : public PageTestBase,
- private ScopedSlotInFlatTreeForTest,
- ScopedIncrementalShadowDOMForTest {
- public:
- FlatTreeTraversalNgTest()
- : ScopedSlotInFlatTreeForTest(true),
- ScopedIncrementalShadowDOMForTest(true) {}
-
- protected:
- // Sets |mainHTML| to BODY element with |innerHTML| property and attaches
- // shadow root to child with |shadowHTML|, then update distribution for
- // calling member functions in |FlatTreeTraversalNg|.
- void SetupSampleHTML(const char* main_html,
- const char* shadow_html,
- unsigned);
-
- void SetupDocumentTree(const char* main_html);
-
- void AttachV0ShadowRoot(Element& shadow_host, const char* shadow_inner_html);
- void AttachOpenShadowRoot(Element& shadow_host,
- const char* shadow_inner_html);
-};
-
-void FlatTreeTraversalNgTest::SetupSampleHTML(const char* main_html,
- const char* shadow_html,
- unsigned index) {
- Element* body = GetDocument().body();
- body->SetInnerHTMLFromString(String::FromUTF8(main_html));
- Element* shadow_host = ToElement(NodeTraversal::ChildAt(*body, index));
- ShadowRoot& shadow_root = shadow_host->CreateV0ShadowRootForTesting();
- shadow_root.SetInnerHTMLFromString(String::FromUTF8(shadow_html));
- body->UpdateDistributionForFlatTreeTraversal();
-}
-
-void FlatTreeTraversalNgTest::SetupDocumentTree(const char* main_html) {
- Element* body = GetDocument().body();
- body->SetInnerHTMLFromString(String::FromUTF8(main_html));
-}
-
-void FlatTreeTraversalNgTest::AttachV0ShadowRoot(
- Element& shadow_host,
- const char* shadow_inner_html) {
- ShadowRoot& shadow_root = shadow_host.CreateV0ShadowRootForTesting();
- shadow_root.SetInnerHTMLFromString(String::FromUTF8(shadow_inner_html));
- GetDocument().body()->UpdateDistributionForFlatTreeTraversal();
-}
-
-void FlatTreeTraversalNgTest::AttachOpenShadowRoot(
- Element& shadow_host,
- const char* shadow_inner_html) {
- ShadowRoot& shadow_root =
- shadow_host.AttachShadowRootInternal(ShadowRootType::kOpen);
- shadow_root.SetInnerHTMLFromString(String::FromUTF8(shadow_inner_html));
- GetDocument().body()->UpdateDistributionForFlatTreeTraversal();
-}
-
-namespace {
-
-void TestCommonAncestor(Node* expected_result,
- const Node& node_a,
- const Node& node_b) {
- Node* result1 = FlatTreeTraversalNg::CommonAncestor(node_a, node_b);
- EXPECT_EQ(expected_result, result1)
- << "commonAncestor(" << node_a.textContent() << ","
- << node_b.textContent() << ")";
- Node* result2 = FlatTreeTraversalNg::CommonAncestor(node_b, node_a);
- EXPECT_EQ(expected_result, result2)
- << "commonAncestor(" << node_b.textContent() << ","
- << node_a.textContent() << ")";
-}
-
-} // namespace
-
-// Test case for
-// - childAt
-// - countChildren
-// - hasChildren
-// - index
-// - isDescendantOf
-TEST_F(FlatTreeTraversalNgTest, childAt) {
- const char* main_html =
- "<div id='m0'>"
- "<span id='m00'>m00</span>"
- "<span id='m01'>m01</span>"
- "</div>";
- const char* shadow_html =
- "<a id='s00'>s00</a>"
- "<content select='#m01'></content>"
- "<a id='s02'>s02</a>"
- "<a id='s03'><content select='#m00'></content></a>"
- "<a id='s04'>s04</a>";
- SetupSampleHTML(main_html, shadow_html, 0);
-
- Element* body = GetDocument().body();
- Element* m0 = body->QuerySelector("#m0");
- Element* m00 = m0->QuerySelector("#m00");
- Element* m01 = m0->QuerySelector("#m01");
-
- Element* shadow_host = m0;
- ShadowRoot* shadow_root = shadow_host->OpenShadowRoot();
- Element* s00 = shadow_root->QuerySelector("#s00");
- Element* s02 = shadow_root->QuerySelector("#s02");
- Element* s03 = shadow_root->QuerySelector("#s03");
- Element* s04 = shadow_root->QuerySelector("#s04");
-
- const unsigned kNumberOfChildNodes = 5;
- Node* expected_child_nodes[5] = {s00, m01, s02, s03, s04};
-
- ASSERT_EQ(kNumberOfChildNodes,
- FlatTreeTraversalNg::CountChildren(*shadow_host));
- EXPECT_TRUE(FlatTreeTraversalNg::HasChildren(*shadow_host));
-
- for (unsigned index = 0; index < kNumberOfChildNodes; ++index) {
- Node* child = FlatTreeTraversalNg::ChildAt(*shadow_host, index);
- EXPECT_EQ(expected_child_nodes[index], child)
- << "FlatTreeTraversalNg::childAt(*shadowHost, " << index << ")";
- EXPECT_EQ(index, FlatTreeTraversalNg::Index(*child))
- << "FlatTreeTraversalNg::index(FlatTreeTraversalNg(*shadowHost, "
- << index << "))";
- EXPECT_TRUE(FlatTreeTraversalNg::IsDescendantOf(*child, *shadow_host))
- << "FlatTreeTraversalNg::isDescendantOf(*FlatTreeTraversalNg(*"
- "shadowHost, "
- << index << "), *shadowHost)";
- }
- EXPECT_EQ(nullptr,
- FlatTreeTraversalNg::ChildAt(*shadow_host, kNumberOfChildNodes + 1))
- << "Out of bounds childAt() returns nullptr.";
-
- // Distribute node |m00| is child of node in shadow tree |s03|.
- EXPECT_EQ(m00, FlatTreeTraversalNg::ChildAt(*s03, 0));
-}
-
-TEST_F(FlatTreeTraversalNgTest, ChildrenOf) {
- SetupSampleHTML(
- "<p id=sample>ZERO<span slot=three>three</b><span "
- "slot=one>one</b>FOUR</p>",
- "zero<slot name=one></slot>two<slot name=three></slot>four", 0);
- Element* const sample = GetDocument().getElementById("sample");
-
- HeapVector<Member<Node>> expected_nodes;
- for (Node* runner = FlatTreeTraversalNg::FirstChild(*sample); runner;
- runner = FlatTreeTraversalNg::NextSibling(*runner)) {
- expected_nodes.push_back(runner);
- }
-
- HeapVector<Member<Node>> actual_nodes;
- for (Node& child : FlatTreeTraversalNg::ChildrenOf(*sample))
- actual_nodes.push_back(&child);
-
- EXPECT_EQ(expected_nodes, actual_nodes);
-}
-
-// Test case for
-// - commonAncestor
-// - isDescendantOf
-TEST_F(FlatTreeTraversalNgTest, commonAncestor) {
- // We build following flat tree:
- // ____BODY___
- // | | |
- // m0 m1 m2 m1 is shadow host having m10, m11, m12.
- // _|_ | __|__
- // | | | | |
- // m00 m01 | m20 m21
- // _____|_____________
- // | | | | |
- // s10 s11 s12 s13 s14
- // |
- // __|__
- // | | |
- // m12 m10 m11 <-- distributed
- // where: each symbol consists with prefix, child index, child-child index.
- // prefix "m" means node in main tree,
- // prefix "d" means node in main tree and distributed
- // prefix "s" means node in shadow tree
- const char* main_html =
- "<a id='m0'><b id='m00'>m00</b><b id='m01'>m01</b></a>"
- "<a id='m1'>"
- "<b id='m10'>m10</b>"
- "<b id='m11'>m11</b>"
- "<b id='m12'>m12</b>"
- "</a>"
- "<a id='m2'><b id='m20'>m20</b><b id='m21'>m21</b></a>";
- const char* shadow_html =
- "<a id='s10'>s10</a>"
- "<a id='s11'><content select='#m12'></content></a>"
- "<a id='s12'>s12</a>"
- "<a id='s13'>"
- "<content select='#m10'></content>"
- "<content select='#m11'></content>"
- "</a>"
- "<a id='s14'>s14</a>";
- SetupSampleHTML(main_html, shadow_html, 1);
- Element* body = GetDocument().body();
- Element* m0 = body->QuerySelector("#m0");
- Element* m1 = body->QuerySelector("#m1");
- Element* m2 = body->QuerySelector("#m2");
-
- Element* m00 = body->QuerySelector("#m00");
- Element* m01 = body->QuerySelector("#m01");
- Element* m10 = body->QuerySelector("#m10");
- Element* m11 = body->QuerySelector("#m11");
- Element* m12 = body->QuerySelector("#m12");
- Element* m20 = body->QuerySelector("#m20");
- Element* m21 = body->QuerySelector("#m21");
-
- ShadowRoot* shadow_root = m1->OpenShadowRoot();
- Element* s10 = shadow_root->QuerySelector("#s10");
- Element* s11 = shadow_root->QuerySelector("#s11");
- Element* s12 = shadow_root->QuerySelector("#s12");
- Element* s13 = shadow_root->QuerySelector("#s13");
- Element* s14 = shadow_root->QuerySelector("#s14");
-
- TestCommonAncestor(body, *m0, *m1);
- TestCommonAncestor(body, *m1, *m2);
- TestCommonAncestor(body, *m1, *m20);
- TestCommonAncestor(body, *s14, *m21);
-
- TestCommonAncestor(m0, *m0, *m0);
- TestCommonAncestor(m0, *m00, *m01);
-
- TestCommonAncestor(m1, *m1, *m1);
- TestCommonAncestor(m1, *s10, *s14);
- TestCommonAncestor(m1, *s10, *m12);
- TestCommonAncestor(m1, *s12, *m12);
- TestCommonAncestor(m1, *m10, *m12);
-
- TestCommonAncestor(m01, *m01, *m01);
- TestCommonAncestor(s11, *s11, *m12);
- TestCommonAncestor(s13, *m10, *m11);
-
- s12->remove(ASSERT_NO_EXCEPTION);
- TestCommonAncestor(s12, *s12, *s12);
- TestCommonAncestor(nullptr, *s12, *s11);
- TestCommonAncestor(nullptr, *s12, *m01);
- TestCommonAncestor(nullptr, *s12, *m20);
-
- m20->remove(ASSERT_NO_EXCEPTION);
- TestCommonAncestor(m20, *m20, *m20);
- TestCommonAncestor(nullptr, *m20, *s12);
- TestCommonAncestor(nullptr, *m20, *m1);
-}
-
-// Test case for
-// - nextSkippingChildren
-// - previousSkippingChildren
-TEST_F(FlatTreeTraversalNgTest, nextSkippingChildren) {
- const char* main_html =
- "<div id='m0'>m0</div>"
- "<div id='m1'>"
- "<span id='m10'>m10</span>"
- "<span id='m11'>m11</span>"
- "</div>"
- "<div id='m2'>m2</div>";
- const char* shadow_html =
- "<content select='#m11'></content>"
- "<a id='s11'>s11</a>"
- "<a id='s12'>"
- "<b id='s120'>s120</b>"
- "<content select='#m10'></content>"
- "</a>";
- SetupSampleHTML(main_html, shadow_html, 1);
-
- Element* body = GetDocument().body();
- Element* m0 = body->QuerySelector("#m0");
- Element* m1 = body->QuerySelector("#m1");
- Element* m2 = body->QuerySelector("#m2");
-
- Element* m10 = body->QuerySelector("#m10");
- Element* m11 = body->QuerySelector("#m11");
-
- ShadowRoot* shadow_root = m1->OpenShadowRoot();
- Element* s11 = shadow_root->QuerySelector("#s11");
- Element* s12 = shadow_root->QuerySelector("#s12");
- Element* s120 = shadow_root->QuerySelector("#s120");
-
- // Main tree node to main tree node
- EXPECT_EQ(*m1, FlatTreeTraversalNg::NextSkippingChildren(*m0));
- EXPECT_EQ(*m0, FlatTreeTraversalNg::PreviousSkippingChildren(*m1));
-
- // Distribute node to main tree node
- EXPECT_EQ(*m2, FlatTreeTraversalNg::NextSkippingChildren(*m10));
- EXPECT_EQ(*m1, FlatTreeTraversalNg::PreviousSkippingChildren(*m2));
-
- // Distribute node to node in shadow tree
- EXPECT_EQ(*s11, FlatTreeTraversalNg::NextSkippingChildren(*m11));
- EXPECT_EQ(*m11, FlatTreeTraversalNg::PreviousSkippingChildren(*s11));
-
- // Node in shadow tree to distributed node
- EXPECT_EQ(*s11, FlatTreeTraversalNg::NextSkippingChildren(*m11));
- EXPECT_EQ(*m11, FlatTreeTraversalNg::PreviousSkippingChildren(*s11));
-
- EXPECT_EQ(*m10, FlatTreeTraversalNg::NextSkippingChildren(*s120));
- EXPECT_EQ(*s120, FlatTreeTraversalNg::PreviousSkippingChildren(*m10));
-
- // Node in shadow tree to main tree
- EXPECT_EQ(*m2, FlatTreeTraversalNg::NextSkippingChildren(*s12));
- EXPECT_EQ(*m1, FlatTreeTraversalNg::PreviousSkippingChildren(*m2));
-}
-
-// Test case for
-// - lastWithin
-// - lastWithinOrSelf
-TEST_F(FlatTreeTraversalNgTest, lastWithin) {
- const char* main_html =
- "<div id='m0'>m0</div>"
- "<div id='m1'>"
- "<span id='m10'>m10</span>"
- "<span id='m11'>m11</span>"
- "<span id='m12'>m12</span>" // #m12 is not distributed.
- "</div>"
- "<div id='m2'></div>";
- const char* shadow_html =
- "<content select='#m11'></content>"
- "<a id='s11'>s11</a>"
- "<a id='s12'>"
- "<content select='#m10'></content>"
- "</a>";
- SetupSampleHTML(main_html, shadow_html, 1);
-
- Element* body = GetDocument().body();
- Element* m0 = body->QuerySelector("#m0");
- Element* m1 = body->QuerySelector("#m1");
- Element* m2 = body->QuerySelector("#m2");
-
- Element* m10 = body->QuerySelector("#m10");
-
- ShadowRoot* shadow_root = m1->OpenShadowRoot();
- Element* s11 = shadow_root->QuerySelector("#s11");
- Element* s12 = shadow_root->QuerySelector("#s12");
-
- EXPECT_EQ(m0->firstChild(), FlatTreeTraversalNg::LastWithin(*m0));
- EXPECT_EQ(*m0->firstChild(), FlatTreeTraversalNg::LastWithinOrSelf(*m0));
-
- EXPECT_EQ(m10->firstChild(), FlatTreeTraversalNg::LastWithin(*m1));
- EXPECT_EQ(*m10->firstChild(), FlatTreeTraversalNg::LastWithinOrSelf(*m1));
-
- EXPECT_EQ(nullptr, FlatTreeTraversalNg::LastWithin(*m2));
- EXPECT_EQ(*m2, FlatTreeTraversalNg::LastWithinOrSelf(*m2));
-
- EXPECT_EQ(s11->firstChild(), FlatTreeTraversalNg::LastWithin(*s11));
- EXPECT_EQ(*s11->firstChild(), FlatTreeTraversalNg::LastWithinOrSelf(*s11));
-
- EXPECT_EQ(m10->firstChild(), FlatTreeTraversalNg::LastWithin(*s12));
- EXPECT_EQ(*m10->firstChild(), FlatTreeTraversalNg::LastWithinOrSelf(*s12));
-}
-
-TEST_F(FlatTreeTraversalNgTest, previousPostOrder) {
- const char* main_html =
- "<div id='m0'>m0</div>"
- "<div id='m1'>"
- "<span id='m10'>m10</span>"
- "<span id='m11'>m11</span>"
- "</div>"
- "<div id='m2'>m2</div>";
- const char* shadow_html =
- "<content select='#m11'></content>"
- "<a id='s11'>s11</a>"
- "<a id='s12'>"
- "<b id='s120'>s120</b>"
- "<content select='#m10'></content>"
- "</a>";
- SetupSampleHTML(main_html, shadow_html, 1);
-
- Element* body = GetDocument().body();
- Element* m0 = body->QuerySelector("#m0");
- Element* m1 = body->QuerySelector("#m1");
- Element* m2 = body->QuerySelector("#m2");
-
- Element* m10 = body->QuerySelector("#m10");
- Element* m11 = body->QuerySelector("#m11");
-
- ShadowRoot* shadow_root = m1->OpenShadowRoot();
- Element* s11 = shadow_root->QuerySelector("#s11");
- Element* s12 = shadow_root->QuerySelector("#s12");
- Element* s120 = shadow_root->QuerySelector("#s120");
-
- EXPECT_EQ(*m0->firstChild(), FlatTreeTraversalNg::PreviousPostOrder(*m0));
- EXPECT_EQ(*s12, FlatTreeTraversalNg::PreviousPostOrder(*m1));
- EXPECT_EQ(*m10->firstChild(), FlatTreeTraversalNg::PreviousPostOrder(*m10));
- EXPECT_EQ(*s120, FlatTreeTraversalNg::PreviousPostOrder(*m10->firstChild()));
- EXPECT_EQ(*s120,
- FlatTreeTraversalNg::PreviousPostOrder(*m10->firstChild(), s12));
- EXPECT_EQ(*m11->firstChild(), FlatTreeTraversalNg::PreviousPostOrder(*m11));
- EXPECT_EQ(*m0, FlatTreeTraversalNg::PreviousPostOrder(*m11->firstChild()));
- EXPECT_EQ(nullptr,
- FlatTreeTraversalNg::PreviousPostOrder(*m11->firstChild(), m11));
- EXPECT_EQ(*m2->firstChild(), FlatTreeTraversalNg::PreviousPostOrder(*m2));
-
- EXPECT_EQ(*s11->firstChild(), FlatTreeTraversalNg::PreviousPostOrder(*s11));
- EXPECT_EQ(*m10, FlatTreeTraversalNg::PreviousPostOrder(*s12));
- EXPECT_EQ(*s120->firstChild(), FlatTreeTraversalNg::PreviousPostOrder(*s120));
- EXPECT_EQ(*s11, FlatTreeTraversalNg::PreviousPostOrder(*s120->firstChild()));
- EXPECT_EQ(nullptr,
- FlatTreeTraversalNg::PreviousPostOrder(*s120->firstChild(), s12));
-}
-
-TEST_F(FlatTreeTraversalNgTest, nextSiblingNotInDocumentFlatTree) {
- const char* main_html =
- "<div id='m0'>m0</div>"
- "<div id='m1'>"
- "<span id='m10'>m10</span>"
- "<span id='m11'>m11</span>"
- "</div>"
- "<div id='m2'>m2</div>";
- const char* shadow_html = "<content select='#m11'></content>";
- SetupSampleHTML(main_html, shadow_html, 1);
-
- Element* body = GetDocument().body();
- Element* m10 = body->QuerySelector("#m10");
-
- EXPECT_EQ(nullptr, FlatTreeTraversalNg::NextSibling(*m10));
- EXPECT_EQ(nullptr, FlatTreeTraversalNg::PreviousSibling(*m10));
-}
-
-TEST_F(FlatTreeTraversalNgTest, redistribution) {
- const char* main_html =
- "<div id='m0'>m0</div>"
- "<div id='m1'>"
- "<span id='m10'>m10</span>"
- "<span id='m11'>m11</span>"
- "</div>"
- "<div id='m2'>m2</div>";
- const char* shadow_html1 =
- "<div id='s1'>"
- "<content></content>"
- "</div>";
-
- SetupSampleHTML(main_html, shadow_html1, 1);
-
- const char* shadow_html2 =
- "<div id='s2'>"
- "<content select='#m10'></content>"
- "<span id='s21'>s21</span>"
- "</div>";
-
- Element* body = GetDocument().body();
- Element* m1 = body->QuerySelector("#m1");
- Element* m10 = body->QuerySelector("#m10");
-
- ShadowRoot* shadow_root1 = m1->OpenShadowRoot();
- Element* s1 = shadow_root1->QuerySelector("#s1");
-
- AttachV0ShadowRoot(*s1, shadow_html2);
-
- ShadowRoot* shadow_root2 = s1->OpenShadowRoot();
- Element* s21 = shadow_root2->QuerySelector("#s21");
-
- EXPECT_EQ(s21, FlatTreeTraversalNg::NextSibling(*m10));
- EXPECT_EQ(m10, FlatTreeTraversalNg::PreviousSibling(*s21));
-
- // FlatTreeTraversalNg::traverseSiblings does not work for a node which is not
- // in a document flat tree.
- // e.g. The following test fails. The result of
- // FlatTreeTraversalNg::previousSibling(*m11)) will be #m10, instead of
- // nullptr. Element* m11 = body->querySelector("#m11"); EXPECT_EQ(nullptr,
- // FlatTreeTraversalNg::previousSibling(*m11));
-}
-
-TEST_F(FlatTreeTraversalNgTest, v1Simple) {
- const char* main_html =
- "<div id='host'>"
- "<div id='child1' slot='slot1'></div>"
- "<div id='child2' slot='slot2'></div>"
- "</div>";
- const char* shadow_html =
- "<div id='shadow-child1'></div>"
- "<slot name='slot1'></slot>"
- "<slot name='slot2'></slot>"
- "<div id='shadow-child2'></div>";
-
- SetupDocumentTree(main_html);
- Element* body = GetDocument().body();
- Element* host = body->QuerySelector("#host");
- Element* child1 = body->QuerySelector("#child1");
- Element* child2 = body->QuerySelector("#child2");
-
- AttachOpenShadowRoot(*host, shadow_html);
- ShadowRoot* shadow_root = host->OpenShadowRoot();
- Element* slot1 = shadow_root->QuerySelector("[name=slot1]");
- Element* slot2 = shadow_root->QuerySelector("[name=slot2]");
- Element* shadow_child1 = shadow_root->QuerySelector("#shadow-child1");
- Element* shadow_child2 = shadow_root->QuerySelector("#shadow-child2");
-
- EXPECT_TRUE(slot1);
- EXPECT_TRUE(slot2);
- EXPECT_EQ(shadow_child1, FlatTreeTraversalNg::FirstChild(*host));
- EXPECT_EQ(slot1, FlatTreeTraversalNg::NextSibling(*shadow_child1));
- EXPECT_EQ(nullptr, FlatTreeTraversalNg::NextSibling(*child1));
- EXPECT_EQ(nullptr, FlatTreeTraversalNg::NextSibling(*child2));
- EXPECT_EQ(slot2, FlatTreeTraversalNg::NextSibling(*slot1));
- EXPECT_EQ(shadow_child2, FlatTreeTraversalNg::NextSibling(*slot2));
-}
-
-TEST_F(FlatTreeTraversalNgTest, v1Redistribution) {
- // composed tree:
- // d1
- // ├──/shadow-root
- // │ └── d1-1
- // │ ├──/shadow-root
- // │ │ ├── d1-1-1
- // │ │ ├── slot name=d1-1-s1
- // │ │ ├── slot name=d1-1-s2
- // │ │ └── d1-1-2
- // │ ├── d1-2
- // │ ├── slot id=d1-s0
- // │ ├── slot name=d1-s1 slot=d1-1-s1
- // │ ├── slot name=d1-s2
- // │ ├── d1-3
- // │ └── d1-4 slot=d1-1-s1
- // ├── d2 slot=d1-s1
- // ├── d3 slot=d1-s2
- // ├── d4 slot=nonexistent
- // └── d5
-
- // flat tree:
- // d1
- // └── d1-1
- // ├── d1-1-1
- // ├── slot name=d1-1-s1
- // │ ├── slot name=d1-s1 slot=d1-1-s1
- // │ │ └── d2 slot=d1-s1
- // │ └── d1-4 slot=d1-1-s1
- // ├── slot name=d1-1-s2
- // └── d1-1-2
- const char* main_html =
- "<div id='d1'>"
- "<div id='d2' slot='d1-s1'></div>"
- "<div id='d3' slot='d1-s2'></div>"
- "<div id='d4' slot='nonexistent'></div>"
- "<div id='d5'></div>"
- "</div>"
- "<div id='d6'></div>";
- const char* shadow_html1 =
- "<div id='d1-1'>"
- "<div id='d1-2'></div>"
- "<slot id='d1-s0'></slot>"
- "<slot name='d1-s1' slot='d1-1-s1'></slot>"
- "<slot name='d1-s2'></slot>"
- "<div id='d1-3'></div>"
- "<div id='d1-4' slot='d1-1-s1'></div>"
- "</div>";
- const char* shadow_html2 =
- "<div id='d1-1-1'></div>"
- "<slot name='d1-1-s1'></slot>"
- "<slot name='d1-1-s2'></slot>"
- "<div id='d1-1-2'></div>";
-
- SetupDocumentTree(main_html);
-
- Element* body = GetDocument().body();
- Element* d1 = body->QuerySelector("#d1");
- Element* d2 = body->QuerySelector("#d2");
- Element* d3 = body->QuerySelector("#d3");
- Element* d4 = body->QuerySelector("#d4");
- Element* d5 = body->QuerySelector("#d5");
- Element* d6 = body->QuerySelector("#d6");
-
- AttachOpenShadowRoot(*d1, shadow_html1);
- ShadowRoot* shadow_root1 = d1->OpenShadowRoot();
- Element* d11 = shadow_root1->QuerySelector("#d1-1");
- Element* d12 = shadow_root1->QuerySelector("#d1-2");
- Element* d13 = shadow_root1->QuerySelector("#d1-3");
- Element* d14 = shadow_root1->QuerySelector("#d1-4");
- Element* d1s0 = shadow_root1->QuerySelector("#d1-s0");
- Element* d1s1 = shadow_root1->QuerySelector("[name=d1-s1]");
- Element* d1s2 = shadow_root1->QuerySelector("[name=d1-s2]");
-
- AttachOpenShadowRoot(*d11, shadow_html2);
- ShadowRoot* shadow_root2 = d11->OpenShadowRoot();
- Element* d111 = shadow_root2->QuerySelector("#d1-1-1");
- Element* d112 = shadow_root2->QuerySelector("#d1-1-2");
- Element* d11s1 = shadow_root2->QuerySelector("[name=d1-1-s1]");
- Element* d11s2 = shadow_root2->QuerySelector("[name=d1-1-s2]");
-
- EXPECT_TRUE(d5);
- EXPECT_TRUE(d12);
- EXPECT_TRUE(d13);
- EXPECT_TRUE(d1s0);
- EXPECT_TRUE(d1s1);
- EXPECT_TRUE(d1s2);
- EXPECT_TRUE(d11s1);
- EXPECT_TRUE(d11s2);
-
- EXPECT_EQ(d11, FlatTreeTraversalNg::Next(*d1));
- EXPECT_EQ(d111, FlatTreeTraversalNg::Next(*d11));
- EXPECT_EQ(d11s1, FlatTreeTraversalNg::Next(*d111));
- EXPECT_EQ(d1s1, FlatTreeTraversalNg::Next(*d11s1));
- EXPECT_EQ(d2, FlatTreeTraversalNg::Next(*d1s1));
- EXPECT_EQ(d14, FlatTreeTraversalNg::Next(*d2));
- EXPECT_EQ(d11s2, FlatTreeTraversalNg::Next(*d14));
- EXPECT_EQ(d112, FlatTreeTraversalNg::Next(*d11s2));
- EXPECT_EQ(d6, FlatTreeTraversalNg::Next(*d112));
-
- EXPECT_EQ(d112, FlatTreeTraversalNg::Previous(*d6));
-
- EXPECT_EQ(d11, FlatTreeTraversalNg::Parent(*d111));
- EXPECT_EQ(d11, FlatTreeTraversalNg::Parent(*d112));
- EXPECT_EQ(d1s1, FlatTreeTraversalNg::Parent(*d2));
- EXPECT_EQ(d11s1, FlatTreeTraversalNg::Parent(*d14));
- EXPECT_EQ(d1s2, FlatTreeTraversalNg::Parent(*d3));
- EXPECT_EQ(nullptr, FlatTreeTraversalNg::Parent(*d4));
-}
-
-TEST_F(FlatTreeTraversalNgTest, v1SlotInDocumentTree) {
- const char* main_html =
- "<div id='parent'>"
- "<slot>"
- "<div id='child1'></div>"
- "<div id='child2'></div>"
- "</slot>"
- "</div>";
-
- SetupDocumentTree(main_html);
- Element* body = GetDocument().body();
- Element* parent = body->QuerySelector("#parent");
- Element* slot = body->QuerySelector("slot");
- Element* child1 = body->QuerySelector("#child1");
- Element* child2 = body->QuerySelector("#child2");
-
- EXPECT_EQ(slot, FlatTreeTraversalNg::FirstChild(*parent));
- EXPECT_EQ(child1, FlatTreeTraversalNg::FirstChild(*slot));
- EXPECT_EQ(child2, FlatTreeTraversalNg::NextSibling(*child1));
- EXPECT_EQ(nullptr, FlatTreeTraversalNg::NextSibling(*child2));
- EXPECT_EQ(slot, FlatTreeTraversalNg::Parent(*child1));
- EXPECT_EQ(slot, FlatTreeTraversalNg::Parent(*child2));
- EXPECT_EQ(parent, FlatTreeTraversalNg::Parent(*slot));
-}
-
-TEST_F(FlatTreeTraversalNgTest, v1FallbackContent) {
- const char* main_html = "<div id='d1'></div>";
- const char* shadow_html =
- "<div id='before'></div>"
- "<slot><p>fallback content</p></slot>"
- "<div id='after'></div>";
-
- SetupDocumentTree(main_html);
-
- Element* body = GetDocument().body();
- Element* d1 = body->QuerySelector("#d1");
-
- AttachOpenShadowRoot(*d1, shadow_html);
- ShadowRoot* shadow_root = d1->OpenShadowRoot();
- Element* before = shadow_root->QuerySelector("#before");
- Element* after = shadow_root->QuerySelector("#after");
- Element* fallback_content = shadow_root->QuerySelector("p");
- Element* slot = shadow_root->QuerySelector("slot");
-
- EXPECT_EQ(before, FlatTreeTraversalNg::FirstChild(*d1));
- EXPECT_EQ(after, FlatTreeTraversalNg::LastChild(*d1));
- EXPECT_EQ(slot, FlatTreeTraversalNg::Parent(*fallback_content));
-
- EXPECT_EQ(slot, FlatTreeTraversalNg::NextSibling(*before));
- EXPECT_EQ(after, FlatTreeTraversalNg::NextSibling(*slot));
- EXPECT_EQ(nullptr, FlatTreeTraversalNg::NextSibling(*fallback_content));
- EXPECT_EQ(nullptr, FlatTreeTraversalNg::NextSibling(*after));
-
- EXPECT_EQ(slot, FlatTreeTraversalNg::PreviousSibling(*after));
- EXPECT_EQ(before, FlatTreeTraversalNg::PreviousSibling(*slot));
- EXPECT_EQ(nullptr, FlatTreeTraversalNg::PreviousSibling(*fallback_content));
- EXPECT_EQ(nullptr, FlatTreeTraversalNg::PreviousSibling(*before));
-}
-
-TEST_F(FlatTreeTraversalNgTest, v1FallbackContentSkippedInTraversal) {
- const char* main_html = "<div id='d1'><span></span></div>";
- const char* shadow_html =
- "<div id='before'></div>"
- "<slot><p>fallback content</p></slot>"
- "<div id='after'></div>";
-
- SetupDocumentTree(main_html);
-
- Element* body = GetDocument().body();
- Element* d1 = body->QuerySelector("#d1");
- Element* span = body->QuerySelector("span");
-
- AttachOpenShadowRoot(*d1, shadow_html);
- ShadowRoot* shadow_root = d1->OpenShadowRoot();
- Element* before = shadow_root->QuerySelector("#before");
- Element* after = shadow_root->QuerySelector("#after");
- Element* fallback_content = shadow_root->QuerySelector("p");
- Element* slot = shadow_root->QuerySelector("slot");
-
- EXPECT_EQ(before, FlatTreeTraversalNg::FirstChild(*d1));
- EXPECT_EQ(after, FlatTreeTraversalNg::LastChild(*d1));
- EXPECT_EQ(slot, FlatTreeTraversalNg::Parent(*span));
- EXPECT_EQ(d1, FlatTreeTraversalNg::Parent(*slot));
-
- EXPECT_EQ(slot, FlatTreeTraversalNg::NextSibling(*before));
- EXPECT_EQ(after, FlatTreeTraversalNg::NextSibling(*slot));
- EXPECT_EQ(nullptr, FlatTreeTraversalNg::NextSibling(*after));
-
- EXPECT_EQ(slot, FlatTreeTraversalNg::PreviousSibling(*after));
- EXPECT_EQ(before, FlatTreeTraversalNg::PreviousSibling(*slot));
- EXPECT_EQ(nullptr, FlatTreeTraversalNg::PreviousSibling(*before));
-
- EXPECT_EQ(nullptr, FlatTreeTraversalNg::Parent(*fallback_content));
- EXPECT_EQ(nullptr, FlatTreeTraversalNg::NextSibling(*fallback_content));
- EXPECT_EQ(nullptr, FlatTreeTraversalNg::PreviousSibling(*fallback_content));
-}
-
-TEST_F(FlatTreeTraversalNgTest, v1AllFallbackContent) {
- const char* main_html = "<div id='d1'></div>";
- const char* shadow_html =
- "<slot name='a'><p id='x'>fallback content X</p></slot>"
- "<slot name='b'><p id='y'>fallback content Y</p></slot>"
- "<slot name='c'><p id='z'>fallback content Z</p></slot>";
-
- SetupDocumentTree(main_html);
-
- Element* body = GetDocument().body();
- Element* d1 = body->QuerySelector("#d1");
-
- AttachOpenShadowRoot(*d1, shadow_html);
- ShadowRoot* shadow_root = d1->OpenShadowRoot();
- Element* slot_a = shadow_root->QuerySelector("slot[name=a]");
- Element* slot_b = shadow_root->QuerySelector("slot[name=b]");
- Element* slot_c = shadow_root->QuerySelector("slot[name=c]");
- Element* fallback_x = shadow_root->QuerySelector("#x");
- Element* fallback_y = shadow_root->QuerySelector("#y");
- Element* fallback_z = shadow_root->QuerySelector("#z");
-
- EXPECT_EQ(slot_a, FlatTreeTraversalNg::FirstChild(*d1));
- EXPECT_EQ(slot_c, FlatTreeTraversalNg::LastChild(*d1));
-
- EXPECT_EQ(fallback_x, FlatTreeTraversalNg::FirstChild(*slot_a));
- EXPECT_EQ(fallback_y, FlatTreeTraversalNg::FirstChild(*slot_b));
- EXPECT_EQ(fallback_z, FlatTreeTraversalNg::FirstChild(*slot_c));
-
- EXPECT_EQ(slot_a, FlatTreeTraversalNg::Parent(*fallback_x));
- EXPECT_EQ(slot_b, FlatTreeTraversalNg::Parent(*fallback_y));
- EXPECT_EQ(slot_c, FlatTreeTraversalNg::Parent(*fallback_z));
- EXPECT_EQ(d1, FlatTreeTraversalNg::Parent(*slot_a));
-
- EXPECT_EQ(nullptr, FlatTreeTraversalNg::NextSibling(*fallback_x));
- EXPECT_EQ(nullptr, FlatTreeTraversalNg::NextSibling(*fallback_y));
- EXPECT_EQ(nullptr, FlatTreeTraversalNg::NextSibling(*fallback_z));
-
- EXPECT_EQ(nullptr, FlatTreeTraversalNg::PreviousSibling(*fallback_z));
- EXPECT_EQ(nullptr, FlatTreeTraversalNg::PreviousSibling(*fallback_y));
- EXPECT_EQ(nullptr, FlatTreeTraversalNg::PreviousSibling(*fallback_x));
-}
-
-} // namespace flat_tree_traversal_ng_test
-} // namespace blink
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 517360e43db..8c310ff0615 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
@@ -16,20 +16,20 @@
#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/geometry/int_size.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/wtf/compiler.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
+// To avoid symbol collisions in jumbo builds.
+namespace flat_tree_traversal_test {
class FlatTreeTraversalTest : public PageTestBase,
- private ScopedSlotInFlatTreeForTest,
ScopedIncrementalShadowDOMForTest {
public:
- FlatTreeTraversalTest()
- : ScopedSlotInFlatTreeForTest(false),
- ScopedIncrementalShadowDOMForTest(false) {}
+ FlatTreeTraversalTest() : ScopedIncrementalShadowDOMForTest(true) {}
protected:
// Sets |mainHTML| to BODY element with |innerHTML| property and attaches
@@ -142,7 +142,8 @@ TEST_F(FlatTreeTraversalTest, childAt) {
<< "FlatTreeTraversal::index(FlatTreeTraversal(*shadowHost, " << index
<< "))";
EXPECT_TRUE(FlatTreeTraversal::IsDescendantOf(*child, *shadow_host))
- << "FlatTreeTraversal::isDescendantOf(*FlatTreeTraversal(*shadowHost, "
+ << "FlatTreeTraversal::isDescendantOf(*FlatTreeTraversal(*"
+ "shadowHost, "
<< index << "), *shadowHost)";
}
EXPECT_EQ(nullptr,
@@ -508,9 +509,9 @@ TEST_F(FlatTreeTraversalTest, redistribution) {
// FlatTreeTraversal::traverseSiblings does not work for a node which is not
// in a document flat tree.
// e.g. The following test fails. The result of
- // FlatTreeTraversal::previousSibling(*m11)) will be #m10, instead of nullptr.
- // Element* m11 = body->querySelector("#m11");
- // EXPECT_EQ(nullptr, FlatTreeTraversal::previousSibling(*m11));
+ // FlatTreeTraversal::previousSibling(*m11)) will be #m10, instead of
+ // nullptr. Element* m11 = body->querySelector("#m11"); EXPECT_EQ(nullptr,
+ // FlatTreeTraversal::previousSibling(*m11));
}
TEST_F(FlatTreeTraversalTest, v1Simple) {
@@ -541,12 +542,44 @@ TEST_F(FlatTreeTraversalTest, v1Simple) {
EXPECT_TRUE(slot1);
EXPECT_TRUE(slot2);
EXPECT_EQ(shadow_child1, FlatTreeTraversal::FirstChild(*host));
- EXPECT_EQ(child1, FlatTreeTraversal::NextSibling(*shadow_child1));
- EXPECT_EQ(child2, FlatTreeTraversal::NextSibling(*child1));
- EXPECT_EQ(shadow_child2, FlatTreeTraversal::NextSibling(*child2));
+ EXPECT_EQ(slot1, FlatTreeTraversal::NextSibling(*shadow_child1));
+ EXPECT_EQ(nullptr, FlatTreeTraversal::NextSibling(*child1));
+ EXPECT_EQ(nullptr, FlatTreeTraversal::NextSibling(*child2));
+ EXPECT_EQ(slot2, FlatTreeTraversal::NextSibling(*slot1));
+ EXPECT_EQ(shadow_child2, FlatTreeTraversal::NextSibling(*slot2));
}
TEST_F(FlatTreeTraversalTest, v1Redistribution) {
+ // composed tree:
+ // d1
+ // ├──/shadow-root
+ // │ └── d1-1
+ // │ ├──/shadow-root
+ // │ │ ├── d1-1-1
+ // │ │ ├── slot name=d1-1-s1
+ // │ │ ├── slot name=d1-1-s2
+ // │ │ └── d1-1-2
+ // │ ├── d1-2
+ // │ ├── slot id=d1-s0
+ // │ ├── slot name=d1-s1 slot=d1-1-s1
+ // │ ├── slot name=d1-s2
+ // │ ├── d1-3
+ // │ └── d1-4 slot=d1-1-s1
+ // ├── d2 slot=d1-s1
+ // ├── d3 slot=d1-s2
+ // ├── d4 slot=nonexistent
+ // └── d5
+
+ // flat tree:
+ // d1
+ // └── d1-1
+ // ├── d1-1-1
+ // ├── slot name=d1-1-s1
+ // │ ├── slot name=d1-s1 slot=d1-1-s1
+ // │ │ └── d2 slot=d1-s1
+ // │ └── d1-4 slot=d1-1-s1
+ // ├── slot name=d1-1-s2
+ // └── d1-1-2
const char* main_html =
"<div id='d1'>"
"<div id='d2' slot='d1-s1'></div>"
@@ -605,20 +638,24 @@ TEST_F(FlatTreeTraversalTest, v1Redistribution) {
EXPECT_TRUE(d1s2);
EXPECT_TRUE(d11s1);
EXPECT_TRUE(d11s2);
+
EXPECT_EQ(d11, FlatTreeTraversal::Next(*d1));
EXPECT_EQ(d111, FlatTreeTraversal::Next(*d11));
- EXPECT_EQ(d2, FlatTreeTraversal::Next(*d111));
+ EXPECT_EQ(d11s1, FlatTreeTraversal::Next(*d111));
+ EXPECT_EQ(d1s1, FlatTreeTraversal::Next(*d11s1));
+ EXPECT_EQ(d2, FlatTreeTraversal::Next(*d1s1));
EXPECT_EQ(d14, FlatTreeTraversal::Next(*d2));
- EXPECT_EQ(d112, FlatTreeTraversal::Next(*d14));
+ EXPECT_EQ(d11s2, FlatTreeTraversal::Next(*d14));
+ EXPECT_EQ(d112, FlatTreeTraversal::Next(*d11s2));
EXPECT_EQ(d6, FlatTreeTraversal::Next(*d112));
EXPECT_EQ(d112, FlatTreeTraversal::Previous(*d6));
EXPECT_EQ(d11, FlatTreeTraversal::Parent(*d111));
EXPECT_EQ(d11, FlatTreeTraversal::Parent(*d112));
- EXPECT_EQ(d11, FlatTreeTraversal::Parent(*d2));
- EXPECT_EQ(d11, FlatTreeTraversal::Parent(*d14));
- EXPECT_EQ(nullptr, FlatTreeTraversal::Parent(*d3));
+ EXPECT_EQ(d1s1, FlatTreeTraversal::Parent(*d2));
+ EXPECT_EQ(d11s1, FlatTreeTraversal::Parent(*d14));
+ EXPECT_EQ(d1s2, FlatTreeTraversal::Parent(*d3));
EXPECT_EQ(nullptr, FlatTreeTraversal::Parent(*d4));
}
@@ -664,17 +701,20 @@ TEST_F(FlatTreeTraversalTest, v1FallbackContent) {
Element* before = shadow_root->QuerySelector("#before");
Element* after = shadow_root->QuerySelector("#after");
Element* fallback_content = shadow_root->QuerySelector("p");
+ Element* slot = shadow_root->QuerySelector("slot");
EXPECT_EQ(before, FlatTreeTraversal::FirstChild(*d1));
EXPECT_EQ(after, FlatTreeTraversal::LastChild(*d1));
- EXPECT_EQ(d1, FlatTreeTraversal::Parent(*fallback_content));
+ EXPECT_EQ(slot, FlatTreeTraversal::Parent(*fallback_content));
- EXPECT_EQ(fallback_content, FlatTreeTraversal::NextSibling(*before));
- EXPECT_EQ(after, FlatTreeTraversal::NextSibling(*fallback_content));
+ EXPECT_EQ(slot, FlatTreeTraversal::NextSibling(*before));
+ EXPECT_EQ(after, FlatTreeTraversal::NextSibling(*slot));
+ EXPECT_EQ(nullptr, FlatTreeTraversal::NextSibling(*fallback_content));
EXPECT_EQ(nullptr, FlatTreeTraversal::NextSibling(*after));
- EXPECT_EQ(fallback_content, FlatTreeTraversal::PreviousSibling(*after));
- EXPECT_EQ(before, FlatTreeTraversal::PreviousSibling(*fallback_content));
+ EXPECT_EQ(slot, FlatTreeTraversal::PreviousSibling(*after));
+ EXPECT_EQ(before, FlatTreeTraversal::PreviousSibling(*slot));
+ EXPECT_EQ(nullptr, FlatTreeTraversal::PreviousSibling(*fallback_content));
EXPECT_EQ(nullptr, FlatTreeTraversal::PreviousSibling(*before));
}
@@ -696,17 +736,19 @@ TEST_F(FlatTreeTraversalTest, v1FallbackContentSkippedInTraversal) {
Element* before = shadow_root->QuerySelector("#before");
Element* after = shadow_root->QuerySelector("#after");
Element* fallback_content = shadow_root->QuerySelector("p");
+ Element* slot = shadow_root->QuerySelector("slot");
EXPECT_EQ(before, FlatTreeTraversal::FirstChild(*d1));
EXPECT_EQ(after, FlatTreeTraversal::LastChild(*d1));
- EXPECT_EQ(d1, FlatTreeTraversal::Parent(*span));
+ EXPECT_EQ(slot, FlatTreeTraversal::Parent(*span));
+ EXPECT_EQ(d1, FlatTreeTraversal::Parent(*slot));
- EXPECT_EQ(span, FlatTreeTraversal::NextSibling(*before));
- EXPECT_EQ(after, FlatTreeTraversal::NextSibling(*span));
+ EXPECT_EQ(slot, FlatTreeTraversal::NextSibling(*before));
+ EXPECT_EQ(after, FlatTreeTraversal::NextSibling(*slot));
EXPECT_EQ(nullptr, FlatTreeTraversal::NextSibling(*after));
- EXPECT_EQ(span, FlatTreeTraversal::PreviousSibling(*after));
- EXPECT_EQ(before, FlatTreeTraversal::PreviousSibling(*span));
+ EXPECT_EQ(slot, FlatTreeTraversal::PreviousSibling(*after));
+ EXPECT_EQ(before, FlatTreeTraversal::PreviousSibling(*slot));
EXPECT_EQ(nullptr, FlatTreeTraversal::PreviousSibling(*before));
EXPECT_EQ(nullptr, FlatTreeTraversal::Parent(*fallback_content));
@@ -728,40 +770,33 @@ TEST_F(FlatTreeTraversalTest, v1AllFallbackContent) {
AttachOpenShadowRoot(*d1, shadow_html);
ShadowRoot* shadow_root = d1->OpenShadowRoot();
+ Element* slot_a = shadow_root->QuerySelector("slot[name=a]");
+ Element* slot_b = shadow_root->QuerySelector("slot[name=b]");
+ Element* slot_c = shadow_root->QuerySelector("slot[name=c]");
Element* fallback_x = shadow_root->QuerySelector("#x");
Element* fallback_y = shadow_root->QuerySelector("#y");
Element* fallback_z = shadow_root->QuerySelector("#z");
- EXPECT_EQ(fallback_x, FlatTreeTraversal::FirstChild(*d1));
- EXPECT_EQ(fallback_z, FlatTreeTraversal::LastChild(*d1));
- EXPECT_EQ(d1, FlatTreeTraversal::Parent(*fallback_x));
- EXPECT_EQ(d1, FlatTreeTraversal::Parent(*fallback_y));
- EXPECT_EQ(d1, FlatTreeTraversal::Parent(*fallback_z));
-
- EXPECT_EQ(fallback_y, FlatTreeTraversal::NextSibling(*fallback_x));
- EXPECT_EQ(fallback_z, FlatTreeTraversal::NextSibling(*fallback_y));
- EXPECT_EQ(nullptr, FlatTreeTraversal::NextSibling(*fallback_z));
-
- EXPECT_EQ(fallback_y, FlatTreeTraversal::PreviousSibling(*fallback_z));
- EXPECT_EQ(fallback_x, FlatTreeTraversal::PreviousSibling(*fallback_y));
- EXPECT_EQ(nullptr, FlatTreeTraversal::PreviousSibling(*fallback_x));
-}
+ EXPECT_EQ(slot_a, FlatTreeTraversal::FirstChild(*d1));
+ EXPECT_EQ(slot_c, FlatTreeTraversal::LastChild(*d1));
-TEST_F(FlatTreeTraversalTest, v0ParentDetailsInsertionPoint) {
- const char* main_html = "<div><span></span></div>";
- const char* shadow_html = "<content></content>";
+ EXPECT_EQ(fallback_x, FlatTreeTraversal::FirstChild(*slot_a));
+ EXPECT_EQ(fallback_y, FlatTreeTraversal::FirstChild(*slot_b));
+ EXPECT_EQ(fallback_z, FlatTreeTraversal::FirstChild(*slot_c));
- SetupSampleHTML(main_html, shadow_html, 0);
+ EXPECT_EQ(slot_a, FlatTreeTraversal::Parent(*fallback_x));
+ EXPECT_EQ(slot_b, FlatTreeTraversal::Parent(*fallback_y));
+ EXPECT_EQ(slot_c, FlatTreeTraversal::Parent(*fallback_z));
+ EXPECT_EQ(d1, FlatTreeTraversal::Parent(*slot_a));
- Element* span = GetDocument().body()->QuerySelector("span");
- ASSERT_TRUE(span);
-
- FlatTreeTraversal::ParentTraversalDetails details;
- EXPECT_FALSE(details.GetInsertionPoint());
+ EXPECT_EQ(nullptr, FlatTreeTraversal::NextSibling(*fallback_x));
+ EXPECT_EQ(nullptr, FlatTreeTraversal::NextSibling(*fallback_y));
+ EXPECT_EQ(nullptr, FlatTreeTraversal::NextSibling(*fallback_z));
- ContainerNode* parent = FlatTreeTraversal::Parent(*span, &details);
- ASSERT_TRUE(parent);
- EXPECT_TRUE(details.GetInsertionPoint());
+ EXPECT_EQ(nullptr, FlatTreeTraversal::PreviousSibling(*fallback_z));
+ EXPECT_EQ(nullptr, FlatTreeTraversal::PreviousSibling(*fallback_y));
+ EXPECT_EQ(nullptr, FlatTreeTraversal::PreviousSibling(*fallback_x));
}
+} // namespace flat_tree_traversal_test
} // namespace blink
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 eebf55d1b01..8dce1e2a79c 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
@@ -40,6 +40,7 @@ class GlobalEventHandlers {
public:
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(abort);
+ DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(activateinvisible);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(auxclick);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(blur);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(cancel);
@@ -93,6 +94,7 @@ class GlobalEventHandlers {
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointermove);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointerout);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointerover);
+ DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointerrawmove);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pointerup);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(progress);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(ratechange);
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 dfed8b89785..5490b6033e4 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
@@ -34,6 +34,7 @@
NoInterfaceObject // Always used on target of 'implements'
] interface GlobalEventHandlers {
attribute EventHandler onabort;
+ [RuntimeEnabled=InvisibleDOM] attribute EventHandler onactivateinvisible;
attribute EventHandler onblur;
attribute EventHandler oncancel;
attribute EventHandler oncanplay;
@@ -107,6 +108,7 @@
attribute EventHandler onlostpointercapture;
attribute EventHandler onpointerdown;
attribute EventHandler onpointermove;
+ [RuntimeEnabled=PointerRawMove] attribute EventHandler onpointerrawmove;
attribute EventHandler onpointerup;
attribute EventHandler onpointercancel;
attribute EventHandler onpointerover;
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 1759da148c5..dee6adfab2e 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
@@ -8,7 +8,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
-#include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h"
+#include "third_party/blink/renderer/platform/testing/testing_platform_support_with_custom_scheduler.h"
#include "third_party/blink/renderer/platform/testing/wtf/scoped_mock_clock.h"
#include "third_party/blink/renderer/platform/wtf/time.h"
@@ -51,8 +51,7 @@ class MockIdleDeadlineScheduler final : public ThreadScheduler {
void RemoveTaskObserver(
base::MessageLoop::TaskObserver* task_observer) override {}
- void AddRAILModeObserver(
- scheduler::WebThreadScheduler::RAILModeObserver*) override {}
+ void AddRAILModeObserver(scheduler::WebRAILModeObserver*) override {}
scheduler::NonMainThreadSchedulerImpl* AsNonMainThreadScheduler() override {
return nullptr;
@@ -62,29 +61,6 @@ class MockIdleDeadlineScheduler final : public ThreadScheduler {
DISALLOW_COPY_AND_ASSIGN(MockIdleDeadlineScheduler);
};
-class MockIdleDeadlineThread final : public WebThread {
- public:
- MockIdleDeadlineThread() = default;
- ~MockIdleDeadlineThread() override = default;
- bool IsCurrentThread() const override { return true; }
- ThreadScheduler* Scheduler() const override { return &scheduler_; }
-
- private:
- mutable MockIdleDeadlineScheduler scheduler_;
- DISALLOW_COPY_AND_ASSIGN(MockIdleDeadlineThread);
-};
-
-class MockIdleDeadlinePlatform : public TestingPlatformSupport {
- public:
- MockIdleDeadlinePlatform() = default;
- ~MockIdleDeadlinePlatform() override = default;
- WebThread* CurrentThread() override { return &thread_; }
-
- private:
- MockIdleDeadlineThread thread_;
- DISALLOW_COPY_AND_ASSIGN(MockIdleDeadlinePlatform);
-};
-
} // namespace
class IdleDeadlineTest : public testing::Test {
@@ -111,7 +87,10 @@ TEST_F(IdleDeadlineTest, deadlineInPast) {
}
TEST_F(IdleDeadlineTest, yieldForHighPriorityWork) {
- ScopedTestingPlatformSupport<MockIdleDeadlinePlatform> platform;
+ MockIdleDeadlineScheduler scheduler;
+ ScopedTestingPlatformSupport<TestingPlatformSupportWithCustomScheduler,
+ ThreadScheduler*>
+ platform(&scheduler);
IdleDeadline* deadline =
IdleDeadline::Create(TimeTicks() + TimeDelta::FromSecondsD(1.25),
diff --git a/chromium/third_party/blink/renderer/core/dom/ignore_opens_during_unload_count_incrementer.h b/chromium/third_party/blink/renderer/core/dom/ignore_opens_during_unload_count_incrementer.h
new file mode 100644
index 00000000000..0863a139a31
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/dom/ignore_opens_during_unload_count_incrementer.h
@@ -0,0 +1,39 @@
+// 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_DOM_IGNORE_OPENS_DURING_UNLOAD_COUNT_INCREMENTER_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_IGNORE_OPENS_DURING_UNLOAD_COUNT_INCREMENTER_H_
+
+#include "base/macros.h"
+#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/platform/wtf/allocator.h"
+
+namespace blink {
+
+class IgnoreOpensDuringUnloadCountIncrementer {
+ STACK_ALLOCATED();
+
+ public:
+ explicit IgnoreOpensDuringUnloadCountIncrementer(Document* document)
+ : count_(document ? &document->ignore_opens_during_unload_count_
+ : nullptr) {
+ if (!count_)
+ return;
+ ++(*count_);
+ }
+
+ ~IgnoreOpensDuringUnloadCountIncrementer() {
+ if (!count_)
+ return;
+ --(*count_);
+ }
+
+ private:
+ unsigned* count_;
+ DISALLOW_COPY_AND_ASSIGN(IgnoreOpensDuringUnloadCountIncrementer);
+};
+
+} // namespace blink
+
+#endif
diff --git a/chromium/third_party/blink/renderer/core/dom/layout_tree_builder.cc b/chromium/third_party/blink/renderer/core/dom/layout_tree_builder.cc
index e7ac71fa579..cc566ecbd7c 100644
--- a/chromium/third_party/blink/renderer/core/dom/layout_tree_builder.cc
+++ b/chromium/third_party/blink/renderer/core/dom/layout_tree_builder.cc
@@ -132,8 +132,10 @@ bool LayoutTreeBuilderForElement::ShouldCreateLayoutObject() const {
ComputedStyle& LayoutTreeBuilderForElement::Style() const {
if (!style_) {
- DCHECK(!node_->GetNonAttachedStyle());
- DCHECK(node_->IsFirstLetterPseudoElement());
+ // TODO(futhark@chromium.org): this should never happen, but we currently
+ // have crashes in the wild because of this (https://crbug.com/875796).
+ // Please report if you ever end up here.
+ NOTREACHED();
style_ = node_->StyleForLayoutObject();
}
return *style_;
@@ -282,7 +284,7 @@ void ReattachLegacyLayoutObjectList::AddForceLegacyAtBFCAncestor(
}
bool ReattachLegacyLayoutObjectList::IsCollecting() const {
- return state_ == State::kCollecting || state_ == State::kRecalcStyle;
+ return state_ == State::kCollecting;
}
void ReattachLegacyLayoutObjectList::ForceLegacyLayoutIfNeeded() {
@@ -303,26 +305,6 @@ void ReattachLegacyLayoutObjectList::ForceLegacyLayoutIfNeeded() {
state_ = State::kClosed;
}
-void ReattachLegacyLayoutObjectList::DidRecalcStyle() {
- const State state = state_;
- state_ = State::kClosed;
- if (state == State::kBuildingLegacyLayoutTree)
- return;
- DCHECK_EQ(state, State::kRecalcStyle);
- for (const LayoutObject* block : blocks_)
- ToElement(*block->GetNode()).LazyReattachIfAttached();
-}
-
-void ReattachLegacyLayoutObjectList::WillRecalcStyle() {
- // TODO(layout-dev): Once make |RecalcStyle()| not to create layout object,
- // we don't need to have |WillRecalcStyle()| and |DidRecalcStyle()|.
- // Note: "first-letter-removed-added.html" creates layout object during
- // style recalc. See http://crbug.com/847218
- if (state_ == State::kBuildingLegacyLayoutTree)
- return;
- state_ = State::kRecalcStyle;
-}
-
void ReattachLegacyLayoutObjectList::Trace(blink::Visitor* visitor) {
visitor->Trace(document_);
}
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 a3e30b2cd03..0f53a0781a8 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
@@ -158,9 +158,6 @@ class CORE_EXPORT ReattachLegacyLayoutObjectList final {
}
void ForceLegacyLayoutIfNeeded();
- void DidRecalcStyle();
- void WillRecalcStyle();
-
void Trace(blink::Visitor*);
private:
@@ -180,8 +177,6 @@ class CORE_EXPORT ReattachLegacyLayoutObjectList final {
kCollecting,
// Replaces LayoutNG objects to legacy layout objects.
kForcingLegacyLayout,
- // Doing style re-calculation.
- kRecalcStyle,
} state_ = State::kInvalid;
DISALLOW_COPY_AND_ASSIGN(ReattachLegacyLayoutObjectList);
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 f0b42f60ae6..8e00d68b145 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
@@ -123,39 +123,18 @@ Node* LayoutTreeBuilderTraversal::PreviousSibling(const Node& node) {
return nullptr;
}
-static Node* LastChild(const Node& node) {
- return FlatTreeTraversal::LastChild(node);
-}
-
-static Node* PseudoAwarePreviousSibling(const Node& node) {
- Node* previous_node = LayoutTreeBuilderTraversal::PreviousSibling(node);
- Node* parent_node = LayoutTreeBuilderTraversal::Parent(node);
-
- if (parent_node && parent_node->IsElementNode() && !previous_node) {
- if (node.IsAfterPseudoElement()) {
- if (Node* child = LastChild(*parent_node))
- return child;
- }
- if (!node.IsBeforePseudoElement())
- return ToElement(parent_node)->GetPseudoElement(kPseudoIdBefore);
- }
- return previous_node;
-}
+Node* LayoutTreeBuilderTraversal::LastChild(const Node& node) {
+ if (!node.IsElementNode())
+ return FlatTreeTraversal::LastChild(node);
-static Node* PseudoAwareLastChild(const Node& node) {
- if (node.IsElementNode()) {
- const Element& current_element = ToElement(node);
- Node* last = current_element.GetPseudoElement(kPseudoIdAfter);
- if (last)
- return last;
-
- last = LastChild(current_element);
- if (!last)
- last = current_element.GetPseudoElement(kPseudoIdBefore);
+ const Element& current_element = ToElement(node);
+ Node* last = current_element.GetPseudoElement(kPseudoIdAfter);
+ if (last)
return last;
- }
-
- return LastChild(node);
+ last = FlatTreeTraversal::LastChild(current_element);
+ if (!last)
+ last = current_element.GetPseudoElement(kPseudoIdBefore);
+ return last;
}
Node* LayoutTreeBuilderTraversal::Previous(const Node& node,
@@ -163,8 +142,8 @@ Node* LayoutTreeBuilderTraversal::Previous(const Node& node,
if (node == stay_within)
return nullptr;
- if (Node* previous_node = PseudoAwarePreviousSibling(node)) {
- while (Node* previous_last_child = PseudoAwareLastChild(*previous_node))
+ if (Node* previous_node = PreviousSibling(node)) {
+ while (Node* previous_last_child = LastChild(*previous_node))
previous_node = previous_last_child;
return previous_node;
}
@@ -172,48 +151,28 @@ Node* LayoutTreeBuilderTraversal::Previous(const Node& node,
}
Node* LayoutTreeBuilderTraversal::FirstChild(const Node& node) {
- return FlatTreeTraversal::FirstChild(node);
-}
-
-static Node* PseudoAwareNextSibling(const Node& node) {
- Node* parent_node = LayoutTreeBuilderTraversal::Parent(node);
- Node* next_node = LayoutTreeBuilderTraversal::NextSibling(node);
-
- if (parent_node && parent_node->IsElementNode() && !next_node) {
- if (node.IsBeforePseudoElement()) {
- if (Node* child = LayoutTreeBuilderTraversal::FirstChild(*parent_node))
- return child;
- }
- if (!node.IsAfterPseudoElement())
- return ToElement(parent_node)->GetPseudoElement(kPseudoIdAfter);
- }
- return next_node;
-}
+ if (!node.IsElementNode())
+ return FlatTreeTraversal::FirstChild(node);
-static Node* PseudoAwareFirstChild(const Node& node) {
- if (node.IsElementNode()) {
- const Element& current_element = ToElement(node);
- Node* first = current_element.GetPseudoElement(kPseudoIdBefore);
- if (first)
- return first;
- first = LayoutTreeBuilderTraversal::FirstChild(current_element);
- if (!first)
- first = current_element.GetPseudoElement(kPseudoIdAfter);
+ const Element& current_element = ToElement(node);
+ Node* first = current_element.GetPseudoElement(kPseudoIdBefore);
+ if (first)
return first;
- }
-
- return LayoutTreeBuilderTraversal::FirstChild(node);
+ first = FlatTreeTraversal::FirstChild(node);
+ if (!first)
+ first = current_element.GetPseudoElement(kPseudoIdAfter);
+ return first;
}
static Node* NextAncestorSibling(const Node& node, const Node* stay_within) {
- DCHECK(!PseudoAwareNextSibling(node));
+ DCHECK(!LayoutTreeBuilderTraversal::NextSibling(node));
DCHECK_NE(node, stay_within);
for (Node* parent_node = LayoutTreeBuilderTraversal::Parent(node);
parent_node;
parent_node = LayoutTreeBuilderTraversal::Parent(*parent_node)) {
if (parent_node == stay_within)
return nullptr;
- if (Node* next_node = PseudoAwareNextSibling(*parent_node))
+ if (Node* next_node = LayoutTreeBuilderTraversal::NextSibling(*parent_node))
return next_node;
}
return nullptr;
@@ -224,14 +183,14 @@ Node* LayoutTreeBuilderTraversal::NextSkippingChildren(
const Node* stay_within) {
if (node == stay_within)
return nullptr;
- if (Node* next_node = PseudoAwareNextSibling(node))
+ if (Node* next_node = NextSibling(node))
return next_node;
return NextAncestorSibling(node, stay_within);
}
Node* LayoutTreeBuilderTraversal::Next(const Node& node,
const Node* stay_within) {
- if (Node* child = PseudoAwareFirstChild(node))
+ if (Node* child = FirstChild(node))
return child;
return NextSkippingChildren(node, stay_within);
}
@@ -242,8 +201,8 @@ static Node* NextLayoutSiblingInternal(Node* node, int32_t& limit) {
if (!HasDisplayContentsStyle(*sibling))
return sibling;
- if (Node* inner =
- NextLayoutSiblingInternal(PseudoAwareFirstChild(*sibling), limit))
+ if (Node* inner = NextLayoutSiblingInternal(
+ LayoutTreeBuilderTraversal::FirstChild(*sibling), limit))
return inner;
if (limit == -1)
@@ -276,7 +235,7 @@ static Node* PreviousLayoutSiblingInternal(Node* node, int32_t& limit) {
return sibling;
if (Node* inner = PreviousLayoutSiblingInternal(
- PseudoAwareLastChild(*sibling), limit))
+ LayoutTreeBuilderTraversal::LastChild(*sibling), limit))
return inner;
if (limit == -1)
@@ -306,7 +265,7 @@ Node* LayoutTreeBuilderTraversal::PreviousLayoutSibling(const Node& node,
Node* LayoutTreeBuilderTraversal::FirstLayoutChild(const Node& node) {
int32_t limit = kTraverseAllSiblings;
- return NextLayoutSiblingInternal(PseudoAwareFirstChild(node), limit);
+ return NextLayoutSiblingInternal(FirstChild(node), limit);
}
LayoutObject* LayoutTreeBuilderTraversal::NextSiblingLayoutObject(
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 b73c21c00ee..be37bb84c45 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
@@ -62,6 +62,7 @@ class CORE_EXPORT LayoutTreeBuilderTraversal {
static ContainerNode* Parent(const Node&, ParentDetails* = nullptr);
static ContainerNode* LayoutParent(const Node&, ParentDetails* = nullptr);
static Node* FirstChild(const Node&);
+ static Node* LastChild(const Node&);
static Node* NextSibling(const Node&);
static Node* NextLayoutSibling(const Node& node) {
int32_t limit = kTraverseAllSiblings;
diff --git a/chromium/third_party/blink/renderer/core/dom/layout_tree_builder_traversal_test.cc b/chromium/third_party/blink/renderer/core/dom/layout_tree_builder_traversal_test.cc
index 19d58178472..ad34ed77ff8 100644
--- a/chromium/third_party/blink/renderer/core/dom/layout_tree_builder_traversal_test.cc
+++ b/chromium/third_party/blink/renderer/core/dom/layout_tree_builder_traversal_test.cc
@@ -40,7 +40,7 @@ TEST_F(LayoutTreeBuilderTraversalTest, pseudos) {
const char* const kHtml =
"<style>"
"#top::before { content: \"foo\"; }"
- "#top::before { content: \"bar\"; }"
+ "#top::after { content: \"bar\"; }"
"</style>"
"<div id='top'></div>";
SetupSampleHTML(kHtml);
@@ -51,6 +51,10 @@ TEST_F(LayoutTreeBuilderTraversalTest, pseudos) {
EXPECT_EQ(before, LayoutTreeBuilderTraversal::Next(*top, nullptr));
EXPECT_EQ(after, LayoutTreeBuilderTraversal::NextSibling(*before));
EXPECT_EQ(nullptr, LayoutTreeBuilderTraversal::PreviousSibling(*before));
+ EXPECT_EQ(nullptr, LayoutTreeBuilderTraversal::NextSibling(*after));
+ EXPECT_EQ(before, LayoutTreeBuilderTraversal::PreviousSibling(*after));
+ EXPECT_EQ(before, LayoutTreeBuilderTraversal::FirstChild(*top));
+ EXPECT_EQ(after, LayoutTreeBuilderTraversal::LastChild(*top));
}
TEST_F(LayoutTreeBuilderTraversalTest, emptyDisplayContents) {
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 5ba3f05cdf9..c6110494b41 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
@@ -82,14 +82,14 @@ Attr* NamedNodeMap::setNamedItemNS(Attr* attr,
return element_->setAttributeNodeNS(attr, exception_state);
}
-Attr* NamedNodeMap::item(unsigned index) const {
+Attr* NamedNodeMap::item(uint32_t index) const {
AttributeCollection attributes = element_->Attributes();
if (index >= attributes.size())
return nullptr;
return element_->EnsureAttr(attributes[index].GetName());
}
-size_t NamedNodeMap::length() const {
+uint32_t NamedNodeMap::length() const {
return element_->Attributes().size();
}
diff --git a/chromium/third_party/blink/renderer/core/dom/named_node_map.h b/chromium/third_party/blink/renderer/core/dom/named_node_map.h
index 7feaa384a17..905c349b782 100644
--- a/chromium/third_party/blink/renderer/core/dom/named_node_map.h
+++ b/chromium/third_party/blink/renderer/core/dom/named_node_map.h
@@ -58,8 +58,8 @@ class NamedNodeMap final : public ScriptWrappable {
Attr* setNamedItem(Attr*, ExceptionState&);
Attr* setNamedItemNS(Attr*, ExceptionState&);
- Attr* item(unsigned index) const;
- size_t length() const;
+ Attr* item(uint32_t index) const;
+ uint32_t length() const;
void NamedPropertyEnumerator(Vector<String>& names, ExceptionState&) const;
bool NamedPropertyQuery(const AtomicString&, ExceptionState&) const;
diff --git a/chromium/third_party/blink/renderer/core/dom/node.cc b/chromium/third_party/blink/renderer/core/dom/node.cc
index 5629f817085..32f58a1577b 100644
--- a/chromium/third_party/blink/renderer/core/dom/node.cc
+++ b/chromium/third_party/blink/renderer/core/dom/node.cc
@@ -876,10 +876,7 @@ static ContainerNode* GetReattachParent(Node& node) {
if (node.IsPseudoElement())
return node.ParentOrShadowHostNode();
if (node.IsChildOfV1ShadowHost()) {
- HTMLSlotElement* slot = RuntimeEnabledFeatures::SlotInFlatTreeEnabled()
- ? node.AssignedSlot()
- : node.FinalDestinationSlot();
- if (slot)
+ if (HTMLSlotElement* slot = node.AssignedSlot())
return slot;
}
if (node.IsInV0ShadowTree() || node.IsChildOfV0ShadowHost()) {
@@ -911,6 +908,8 @@ void Node::SetNeedsStyleRecalc(StyleChangeType change_type,
DCHECK(change_type != kNoStyleChange);
if (!InActiveDocument())
return;
+ if (!IsContainerNode() && !IsTextNode())
+ return;
TRACE_EVENT_INSTANT1(
TRACE_DISABLED_BY_DEFAULT("devtools.timeline.invalidationTracking"),
@@ -1120,7 +1119,7 @@ void Node::AttachLayoutTree(AttachContext& context) {
ClearNeedsStyleRecalc();
ClearNeedsReattachLayoutTree();
- if (AXObjectCache* cache = GetDocument().GetOrCreateAXObjectCache())
+ if (AXObjectCache* cache = GetDocument().ExistingAXObjectCache())
cache->UpdateCacheAfterNodeIsAttached(this);
}
@@ -1181,10 +1180,7 @@ bool Node::IsStyledElement() const {
bool Node::CanParticipateInFlatTree() const {
// TODO(hayato): Return false for pseudo elements.
- if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled()) {
return !IsShadowRoot() && !IsActiveV0InsertionPoint(*this);
- }
- return !IsShadowRoot() && !IsActiveSlotOrActiveV0InsertionPoint();
}
bool Node::IsActiveSlotOrActiveV0InsertionPoint() const {
@@ -2261,15 +2257,15 @@ void Node::HandleLocalEvents(Event& event) {
return;
}
- FireEventListeners(&event);
+ FireEventListeners(event);
}
-void Node::DispatchScopedEvent(Event* event) {
- event->SetTrusted(true);
+void Node::DispatchScopedEvent(Event& event) {
+ event.SetTrusted(true);
EventDispatcher::DispatchScopedEvent(*this, event);
}
-DispatchEventResult Node::DispatchEventInternal(Event* event) {
+DispatchEventResult Node::DispatchEventInternal(Event& event) {
return EventDispatcher::DispatchEvent(*this, event);
}
@@ -2284,8 +2280,8 @@ void Node::DispatchSubtreeModifiedEvent() {
if (!GetDocument().HasListenerType(Document::kDOMSubtreeModifiedListener))
return;
- DispatchScopedEvent(MutationEvent::Create(EventTypeNames::DOMSubtreeModified,
- Event::Bubbles::kYes));
+ DispatchScopedEvent(*MutationEvent::Create(EventTypeNames::DOMSubtreeModified,
+ Event::Bubbles::kYes));
}
DispatchEventResult Node::DispatchDOMActivateEvent(int detail,
@@ -2293,16 +2289,16 @@ DispatchEventResult Node::DispatchDOMActivateEvent(int detail,
#if DCHECK_IS_ON()
DCHECK(!EventDispatchForbiddenScope::IsEventDispatchForbidden());
#endif
- UIEvent* event = UIEvent::Create();
- event->initUIEvent(EventTypeNames::DOMActivate, true, true,
- GetDocument().domWindow(), detail);
- event->SetUnderlyingEvent(&underlying_event);
- event->SetComposed(underlying_event.composed());
+ UIEvent& event = *UIEvent::Create();
+ event.initUIEvent(EventTypeNames::DOMActivate, true, true,
+ GetDocument().domWindow(), detail);
+ event.SetUnderlyingEvent(&underlying_event);
+ event.SetComposed(underlying_event.composed());
DispatchScopedEvent(event);
// TODO(dtapuska): Dispatching scoped events shouldn't check the return
// type because the scoped event could get put off in the delayed queue.
- return EventTarget::GetDispatchEventResult(*event);
+ return EventTarget::GetDispatchEventResult(event);
}
void Node::CreateAndDispatchPointerEvent(const AtomicString& mouse_event_name,
@@ -2347,7 +2343,7 @@ void Node::CreateAndDispatchPointerEvent(const AtomicString& mouse_event_name,
static_cast<WebInputEvent::Modifiers>(mouse_event.GetModifiers()));
pointer_event_init.setView(view);
- DispatchEvent(PointerEvent::Create(pointer_event_name, pointer_event_init));
+ DispatchEvent(*PointerEvent::Create(pointer_event_name, pointer_event_init));
}
// TODO(crbug.com/665924): This function bypasses all Blink event path.
@@ -2385,7 +2381,7 @@ void Node::DispatchMouseEvent(const WebMouseEvent& event,
->FiresTouchEvents(event.FromTouch())
: nullptr);
- DispatchEvent(MouseEvent::Create(
+ DispatchEvent(*MouseEvent::Create(
mouse_event_type, initializer, event.TimeStamp(),
event.FromTouch() ? MouseEvent::kFromTouch
: MouseEvent::kRealOrIndistinguishable,
@@ -2401,42 +2397,43 @@ void Node::DispatchSimulatedClick(Event* underlying_event,
void Node::DispatchInputEvent() {
// Legacy 'input' event for forms set value and checked.
- DispatchScopedEvent(Event::CreateBubble(EventTypeNames::input));
+ DispatchScopedEvent(*Event::CreateBubble(EventTypeNames::input));
}
-void Node::DefaultEventHandler(Event* event) {
- if (event->target() != this)
+void Node::DefaultEventHandler(Event& event) {
+ if (event.target() != this)
return;
- const AtomicString& event_type = event->type();
+ const AtomicString& event_type = event.type();
if (event_type == EventTypeNames::keydown ||
event_type == EventTypeNames::keypress) {
- if (event->IsKeyboardEvent()) {
- if (LocalFrame* frame = GetDocument().GetFrame())
+ if (event.IsKeyboardEvent()) {
+ if (LocalFrame* frame = GetDocument().GetFrame()) {
frame->GetEventHandler().DefaultKeyboardEventHandler(
- ToKeyboardEvent(event));
+ ToKeyboardEvent(&event));
+ }
}
} else if (event_type == EventTypeNames::click) {
- int detail =
- event->IsUIEvent() ? static_cast<UIEvent*>(event)->detail() : 0;
- if (DispatchDOMActivateEvent(detail, *event) !=
+ int detail = event.IsUIEvent() ? ToUIEvent(event).detail() : 0;
+ if (DispatchDOMActivateEvent(detail, event) !=
DispatchEventResult::kNotCanceled)
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
} else if (event_type == EventTypeNames::contextmenu &&
- event->IsMouseEvent()) {
+ event.IsMouseEvent()) {
if (Page* page = GetDocument().GetPage()) {
page->GetContextMenuController().HandleContextMenuEvent(
- ToMouseEvent(event));
+ ToMouseEvent(&event));
}
} else if (event_type == EventTypeNames::textInput) {
- if (event->HasInterface(EventNames::TextEvent)) {
- if (LocalFrame* frame = GetDocument().GetFrame())
+ if (event.HasInterface(EventNames::TextEvent)) {
+ if (LocalFrame* frame = GetDocument().GetFrame()) {
frame->GetEventHandler().DefaultTextInputEventHandler(
- ToTextEvent(event));
+ ToTextEvent(&event));
+ }
}
} else if (RuntimeEnabledFeatures::MiddleClickAutoscrollEnabled() &&
- event_type == EventTypeNames::mousedown && event->IsMouseEvent()) {
- MouseEvent* mouse_event = ToMouseEvent(event);
- if (mouse_event->button() ==
+ event_type == EventTypeNames::mousedown && event.IsMouseEvent()) {
+ auto& mouse_event = ToMouseEvent(event);
+ if (mouse_event.button() ==
static_cast<short>(WebPointerProperties::Button::kMiddle)) {
if (EnclosingLinkEventParentOrSelf())
return;
@@ -2465,19 +2462,19 @@ void Node::DefaultEventHandler(Event* event) {
frame->GetEventHandler().StartMiddleClickAutoscroll(layout_object);
}
}
- } else if (event_type == EventTypeNames::mouseup && event->IsMouseEvent()) {
- MouseEvent* mouse_event = ToMouseEvent(event);
- if (mouse_event->button() ==
+ } else if (event_type == EventTypeNames::mouseup && event.IsMouseEvent()) {
+ auto& mouse_event = ToMouseEvent(event);
+ if (mouse_event.button() ==
static_cast<short>(WebPointerProperties::Button::kBack)) {
if (LocalFrame* frame = GetDocument().GetFrame()) {
if (frame->Client()->NavigateBackForward(-1))
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
}
- } else if (mouse_event->button() ==
+ } else if (mouse_event.button() ==
static_cast<short>(WebPointerProperties::Button::kForward)) {
if (LocalFrame* frame = GetDocument().GetFrame()) {
if (frame->Client()->NavigateBackForward(1))
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
}
}
}
diff --git a/chromium/third_party/blink/renderer/core/dom/node.h b/chromium/third_party/blink/renderer/core/dom/node.h
index 302eb60891c..0df2b7f1200 100644
--- a/chromium/third_party/blink/renderer/core/dom/node.h
+++ b/chromium/third_party/blink/renderer/core/dom/node.h
@@ -634,6 +634,8 @@ class CORE_EXPORT Node : public EventTarget {
struct AttachContext {
STACK_ALLOCATED();
+
+ public:
// Keep track of previously attached in-flow box during attachment so that
// we don't need to backtrack past display:none/contents and out of flow
// objects when we need to do whitespace re-attachment.
@@ -710,7 +712,7 @@ class CORE_EXPORT Node : public EventTarget {
};
virtual InsertionNotificationRequest InsertedInto(
- ContainerNode* insertion_point);
+ ContainerNode& insertion_point);
virtual void DidNotifySubtreeInsertionsToDocument() {}
// Notifies the node that it is no longer part of the tree.
@@ -719,7 +721,7 @@ class CORE_EXPORT Node : public EventTarget {
// DOMNodeRemovedFromDocument DOM event, but does not require the overhead of
// event dispatching, and is called _after_ the node is removed from the tree.
//
- virtual void RemovedFrom(ContainerNode* insertion_point);
+ virtual void RemovedFrom(ContainerNode& insertion_point);
// FIXME(dominicc): This method is not debug-only--it is used by
// Tracing--rename it to something indicative.
@@ -769,12 +771,12 @@ class CORE_EXPORT Node : public EventTarget {
// Handlers to do/undo actions on the target node before an event is
// dispatched to it and after the event has been dispatched. The data pointer
// is handed back by the preDispatch and passed to postDispatch.
- virtual EventDispatchHandlingState* PreDispatchEventHandler(Event*) {
+ virtual EventDispatchHandlingState* PreDispatchEventHandler(Event&) {
return nullptr;
}
- virtual void PostDispatchEventHandler(Event*, EventDispatchHandlingState*) {}
+ virtual void PostDispatchEventHandler(Event&, EventDispatchHandlingState*) {}
- void DispatchScopedEvent(Event*);
+ void DispatchScopedEvent(Event&);
virtual void HandleLocalEvents(Event&);
@@ -796,7 +798,7 @@ class CORE_EXPORT Node : public EventTarget {
void DispatchInputEvent();
// Perform the default action for an event.
- virtual void DefaultEventHandler(Event*);
+ virtual void DefaultEventHandler(Event&);
virtual void WillCallDefaultEventHandler(const Event&);
// Should return true if this Node has activation behavior.
// https://dom.spec.whatwg.org/#eventtarget-activation-behavior
@@ -930,7 +932,7 @@ class CORE_EXPORT Node : public EventTarget {
protected:
enum ConstructionType {
- kCreateOther = kDefaultNodeFlags,
+ kCreateOther = kIsFinishedParsingChildrenFlag,
kCreateText = kDefaultNodeFlags | kIsTextFlag,
kCreateContainer =
kDefaultNodeFlags | kChildNeedsStyleRecalcFlag | kIsContainerFlag,
@@ -957,7 +959,7 @@ class CORE_EXPORT Node : public EventTarget {
RegisteredEventListener&) override;
void RemovedEventListener(const AtomicString& event_type,
const RegisteredEventListener&) override;
- DispatchEventResult DispatchEventInternal(Event*) override;
+ DispatchEventResult DispatchEventInternal(Event&) override;
bool HasRareData() const { return GetFlag(kHasRareDataFlag); }
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 4e2a57ef638..2adc78d9813 100644
--- a/chromium/third_party/blink/renderer/core/dom/node_test.cc
+++ b/chromium/third_party/blink/renderer/core/dom/node_test.cc
@@ -6,9 +6,11 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/core/css/resolver/style_resolver.h"
+#include "third_party/blink/renderer/core/dom/comment.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/dom/flat_tree_traversal.h"
#include "third_party/blink/renderer/core/dom/layout_tree_builder.h"
+#include "third_party/blink/renderer/core/dom/processing_instruction.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/editing/testing/editing_test_base.h"
@@ -315,4 +317,21 @@ TEST_F(NodeTest, HasMediaControlAncestor_MediaControls) {
EXPECT_TRUE(InitializeUserAgentShadowTree(node)->HasMediaControlAncestor());
}
+TEST_F(NodeTest, appendChildProcessingInstructionNoStyleRecalc) {
+ GetDocument().View()->UpdateAllLifecyclePhases();
+ EXPECT_FALSE(GetDocument().ChildNeedsStyleRecalc());
+ ProcessingInstruction* pi =
+ ProcessingInstruction::Create(GetDocument(), "A", "B");
+ GetDocument().body()->appendChild(pi, ASSERT_NO_EXCEPTION);
+ EXPECT_FALSE(GetDocument().ChildNeedsStyleRecalc());
+}
+
+TEST_F(NodeTest, appendChildCommentNoStyleRecalc) {
+ GetDocument().View()->UpdateAllLifecyclePhases();
+ EXPECT_FALSE(GetDocument().ChildNeedsStyleRecalc());
+ Comment* comment = Comment::Create(GetDocument(), "comment");
+ GetDocument().body()->appendChild(comment, ASSERT_NO_EXCEPTION);
+ EXPECT_FALSE(GetDocument().ChildNeedsStyleRecalc());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/dom/node_traversal.h b/chromium/third_party/blink/renderer/core/dom/node_traversal.h
index abeec1b5e6a..b3f22e655cf 100644
--- a/chromium/third_party/blink/renderer/core/dom/node_traversal.h
+++ b/chromium/third_party/blink/renderer/core/dom/node_traversal.h
@@ -75,8 +75,9 @@ class NodeTraversal {
}
// Like next, but skips children and starts with the next sibling.
- static Node* NextSkippingChildren(const Node&);
- static Node* NextSkippingChildren(const Node&, const Node* stay_within);
+ CORE_EXPORT static Node* NextSkippingChildren(const Node&);
+ CORE_EXPORT static Node* NextSkippingChildren(const Node&,
+ const Node* stay_within);
static Node* FirstWithin(const Node& current) { return current.firstChild(); }
@@ -88,8 +89,9 @@ class NodeTraversal {
static Node* Previous(const Node&, const Node* stay_within = nullptr);
// Like previous, but skips children and starts with the next sibling.
- static Node* PreviousSkippingChildren(const Node&,
- const Node* stay_within = nullptr);
+ CORE_EXPORT static Node* PreviousSkippingChildren(
+ const Node&,
+ const Node* stay_within = nullptr);
// Like next, but visits parents after their children.
static Node* NextPostOrder(const Node&, const Node* stay_within = nullptr);
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 de81f256520..c20295e6608 100644
--- a/chromium/third_party/blink/renderer/core/dom/processing_instruction.cc
+++ b/chromium/third_party/blink/renderer/core/dom/processing_instruction.cc
@@ -157,6 +157,8 @@ void ProcessingInstruction::Process(const String& href, const String& charset) {
loading_ = true;
if (is_xsl_) {
DCHECK(RuntimeEnabledFeatures::XSLTEnabled());
+ params.MutableResourceRequest().SetFetchRequestMode(
+ network::mojom::FetchRequestMode::kSameOrigin);
XSLStyleSheetResource::Fetch(params, GetDocument().Fetcher(), this);
} else {
params.SetCharset(charset.IsEmpty() ? GetDocument().Encoding()
@@ -234,9 +236,9 @@ void ProcessingInstruction::NotifyFinished(Resource* resource) {
}
Node::InsertionNotificationRequest ProcessingInstruction::InsertedInto(
- ContainerNode* insertion_point) {
+ ContainerNode& insertion_point) {
CharacterData::InsertedInto(insertion_point);
- if (!insertion_point->isConnected())
+ if (!insertion_point.isConnected())
return kInsertionDone;
String href;
@@ -250,16 +252,16 @@ Node::InsertionNotificationRequest ProcessingInstruction::InsertedInto(
return kInsertionDone;
}
-void ProcessingInstruction::RemovedFrom(ContainerNode* insertion_point) {
+void ProcessingInstruction::RemovedFrom(ContainerNode& insertion_point) {
CharacterData::RemovedFrom(insertion_point);
- if (!insertion_point->isConnected())
+ if (!insertion_point.isConnected())
return;
// No need to remove XSLStyleSheet from StyleEngine.
if (!DocumentXSLT::ProcessingInstructionRemovedFromDocument(GetDocument(),
this)) {
GetDocument().GetStyleEngine().RemoveStyleSheetCandidateNode(
- *this, *insertion_point);
+ *this, insertion_point);
}
if (sheet_) {
diff --git a/chromium/third_party/blink/renderer/core/dom/processing_instruction.h b/chromium/third_party/blink/renderer/core/dom/processing_instruction.h
index 04f6a6376c8..66e8683eb92 100644
--- a/chromium/third_party/blink/renderer/core/dom/processing_instruction.h
+++ b/chromium/third_party/blink/renderer/core/dom/processing_instruction.h
@@ -32,8 +32,8 @@ namespace blink {
class StyleSheet;
class EventListener;
-class ProcessingInstruction final : public CharacterData,
- private ResourceClient {
+class CORE_EXPORT ProcessingInstruction final : public CharacterData,
+ private ResourceClient {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(ProcessingInstruction);
@@ -78,8 +78,9 @@ class ProcessingInstruction final : public CharacterData,
NodeType getNodeType() const override;
Node* Clone(Document&, CloneChildrenFlag) const override;
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
- void RemovedFrom(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
+ void RemovedFrom(ContainerNode&) override;
+ void DetachLayoutTree(const AttachContext&) final {}
bool CheckStyleSheet(String& href, String& charset);
void Process(const String& href, const String& charset);
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 ac5aae97a88..c4b5eae5654 100644
--- a/chromium/third_party/blink/renderer/core/dom/pseudo_element.cc
+++ b/chromium/third_party/blink/renderer/core/dom/pseudo_element.cc
@@ -142,7 +142,7 @@ void PseudoElement::Dispose() {
Element* parent = ParentOrShadowHostElement();
GetDocument().AdoptIfNeeded(*this);
SetParentOrShadowHostNode(nullptr);
- RemovedFrom(parent);
+ RemovedFrom(*parent);
}
void PseudoElement::AttachLayoutTree(AttachContext& context) {
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 335a846af5b..2ab87d442b5 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
@@ -85,7 +85,7 @@ inline PseudoElement* PseudoElementData::GetPseudoElement(
if (kPseudoIdAfter == pseudo_id)
return generated_after_;
// Workaround for CPU bug. This avoids compiler optimizing
-// this group of if conditions into switch. See crbug.com/855390.
+// this group of if conditions into switch. See http://crbug.com/855390.
#if defined(ARCH_CPU_ARMEL)
__asm__ volatile("");
#endif
diff --git a/chromium/third_party/blink/renderer/core/dom/range.cc b/chromium/third_party/blink/renderer/core/dom/range.cc
index 332ba077493..f9cad1341ac 100644
--- a/chromium/third_party/blink/renderer/core/dom/range.cc
+++ b/chromium/third_party/blink/renderer/core/dom/range.cc
@@ -45,6 +45,7 @@
#include "third_party/blink/renderer/core/editing/set_selection_options.h"
#include "third_party/blink/renderer/core/editing/visible_position.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/settings.h"
#include "third_party/blink/renderer/core/geometry/dom_rect.h"
#include "third_party/blink/renderer/core/geometry/dom_rect_list.h"
@@ -823,7 +824,16 @@ DocumentFragment* Range::extractContents(ExceptionState& exception_state) {
return nullptr;
EventQueueScope scope;
- return ProcessContents(EXTRACT_CONTENTS, exception_state);
+ DocumentFragment* fragment = ProcessContents(EXTRACT_CONTENTS,
+ exception_state);
+ // |extractContents| has extended attributes [NewObject, DoNotTestNewObject],
+ // so it's better to have a test that exercises the following condition:
+ //
+ // !fragment || DOMDataStore::GetWrapper(fragment, isolate).IsEmpty()
+ //
+ // however, there is no access to |isolate| so far. So, we simply omit the
+ // test so far.
+ return fragment;
}
DocumentFragment* Range::cloneContents(ExceptionState& exception_state) {
@@ -975,23 +985,16 @@ DocumentFragment* Range::createContextualFragment(
// Algorithm:
// http://domparsing.spec.whatwg.org/#extensions-to-the-range-interface
- DCHECK(string_or_html.IsString() ||
- RuntimeEnabledFeatures::TrustedDOMTypesEnabled());
DCHECK(!string_or_html.IsNull());
Document& document = start_.Container().GetDocument();
- if (string_or_html.IsString() && document.RequireTrustedTypes()) {
- exception_state.ThrowTypeError(
- "This document requires `TrustedHTML` assignment.");
- return nullptr;
+ String markup =
+ TrustedHTML::GetString(string_or_html, &document, exception_state);
+ if (!exception_state.HadException()) {
+ return createContextualFragmentFromString(markup, exception_state);
}
-
- String markup = string_or_html.IsString()
- ? string_or_html.GetAsString()
- : string_or_html.GetAsTrustedHTML()->toString();
-
- return createContextualFragmentFromString(markup, exception_state);
+ return nullptr;
}
DocumentFragment* Range::createContextualFragmentFromString(
diff --git a/chromium/third_party/blink/renderer/core/dom/range.idl b/chromium/third_party/blink/renderer/core/dom/range.idl
index 86dc09b4a38..09fcdd407c1 100644
--- a/chromium/third_party/blink/renderer/core/dom/range.idl
+++ b/chromium/third_party/blink/renderer/core/dom/range.idl
@@ -50,7 +50,7 @@
[RaisesException] short compareBoundaryPoints(unsigned short how, Range sourceRange);
[RaisesException, CEReactions, CustomElementCallbacks] void deleteContents();
- [NewObject, RaisesException, CEReactions, CustomElementCallbacks] DocumentFragment extractContents();
+ [NewObject, RaisesException, CEReactions, CustomElementCallbacks, DoNotTestNewObject] DocumentFragment extractContents();
[NewObject, RaisesException, CEReactions, CustomElementCallbacks] DocumentFragment cloneContents();
[RaisesException, CEReactions, CustomElementCallbacks] void insertNode(Node node);
[RaisesException, CEReactions, CustomElementCallbacks] void surroundContents(Node newParent);
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 7921474ad0b..5bdc1ac015a 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
@@ -120,9 +120,9 @@ void ScriptedAnimationController::DispatchEvents(
// tree.
probe::AsyncTask async_task(event_target->GetExecutionContext(), event);
if (LocalDOMWindow* window = event_target->ToLocalDOMWindow())
- window->DispatchEvent(event, nullptr);
+ window->DispatchEvent(*event, nullptr);
else
- event_target->DispatchEvent(event);
+ event_target->DispatchEvent(*event);
}
}
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 4e1d93ca401..fc562b24329 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
@@ -11,16 +11,18 @@
#include "third_party/blink/renderer/core/dom/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/testing_platform_support.h"
+#include "third_party/blink/renderer/platform/testing/testing_platform_support_with_custom_scheduler.h"
#include "third_party/blink/renderer/platform/wtf/time.h"
namespace blink {
namespace {
+enum class ShouldYield { YIELD, DONT_YIELD };
+
class MockScriptedIdleTaskControllerScheduler final : public ThreadScheduler {
public:
- MockScriptedIdleTaskControllerScheduler(bool should_yield)
- : should_yield_(should_yield) {}
+ explicit MockScriptedIdleTaskControllerScheduler(ShouldYield should_yield)
+ : should_yield_(should_yield == ShouldYield::YIELD) {}
~MockScriptedIdleTaskControllerScheduler() override = default;
// ThreadScheduler implementation:
@@ -57,8 +59,7 @@ class MockScriptedIdleTaskControllerScheduler final : public ThreadScheduler {
void RemoveTaskObserver(
base::MessageLoop::TaskObserver* task_observer) override {}
- void AddRAILModeObserver(
- scheduler::WebThreadScheduler::RAILModeObserver*) override {}
+ void AddRAILModeObserver(scheduler::WebRAILModeObserver*) override {}
scheduler::NonMainThreadSchedulerImpl* AsNonMainThreadScheduler() override {
return nullptr;
@@ -74,37 +75,6 @@ class MockScriptedIdleTaskControllerScheduler final : public ThreadScheduler {
DISALLOW_COPY_AND_ASSIGN(MockScriptedIdleTaskControllerScheduler);
};
-class MockScriptedIdleTaskControllerThread final : public WebThread {
- public:
- MockScriptedIdleTaskControllerThread(bool should_yield)
- : scheduler_(should_yield) {}
- ~MockScriptedIdleTaskControllerThread() override = default;
- bool IsCurrentThread() const override { return true; }
- ThreadScheduler* Scheduler() const override { return &scheduler_; }
-
- void RunIdleTask() { scheduler_.RunIdleTask(); }
- bool HasIdleTask() const { return scheduler_.HasIdleTask(); }
-
- private:
- mutable MockScriptedIdleTaskControllerScheduler scheduler_;
- DISALLOW_COPY_AND_ASSIGN(MockScriptedIdleTaskControllerThread);
-};
-
-class MockScriptedIdleTaskControllerPlatform : public TestingPlatformSupport {
- public:
- MockScriptedIdleTaskControllerPlatform(bool should_yield)
- : thread_(should_yield) {}
- ~MockScriptedIdleTaskControllerPlatform() override = default;
- WebThread* CurrentThread() override { return &thread_; }
-
- void RunIdleTask() { thread_.RunIdleTask(); }
- bool HasIdleTask() const { return thread_.HasIdleTask(); }
-
- private:
- MockScriptedIdleTaskControllerThread thread_;
- DISALLOW_COPY_AND_ASSIGN(MockScriptedIdleTaskControllerPlatform);
-};
-
class MockIdleTask : public ScriptedIdleTaskController::IdleTask {
public:
MOCK_METHOD1(invoke, void(IdleDeadline*));
@@ -120,28 +90,34 @@ class ScriptedIdleTaskControllerTest : public testing::Test {
};
TEST_F(ScriptedIdleTaskControllerTest, RunCallback) {
- ScopedTestingPlatformSupport<MockScriptedIdleTaskControllerPlatform, bool>
- platform(false);
+ MockScriptedIdleTaskControllerScheduler scheduler(ShouldYield::DONT_YIELD);
+ ScopedTestingPlatformSupport<TestingPlatformSupportWithCustomScheduler,
+ ThreadScheduler*>
+ platform(&scheduler);
+
NullExecutionContext execution_context;
ScriptedIdleTaskController* controller =
ScriptedIdleTaskController::Create(execution_context_);
Persistent<MockIdleTask> idle_task(new MockIdleTask());
IdleRequestOptions options;
- EXPECT_FALSE(platform->HasIdleTask());
+ EXPECT_FALSE(scheduler.HasIdleTask());
int id = controller->RegisterCallback(idle_task, options);
- EXPECT_TRUE(platform->HasIdleTask());
+ EXPECT_TRUE(scheduler.HasIdleTask());
EXPECT_NE(0, id);
EXPECT_CALL(*idle_task, invoke(testing::_));
- platform->RunIdleTask();
+ scheduler.RunIdleTask();
testing::Mock::VerifyAndClearExpectations(idle_task);
- EXPECT_FALSE(platform->HasIdleTask());
+ EXPECT_FALSE(scheduler.HasIdleTask());
}
TEST_F(ScriptedIdleTaskControllerTest, DontRunCallbackWhenAskedToYield) {
- ScopedTestingPlatformSupport<MockScriptedIdleTaskControllerPlatform, bool>
- platform(true);
+ MockScriptedIdleTaskControllerScheduler scheduler(ShouldYield::YIELD);
+ ScopedTestingPlatformSupport<TestingPlatformSupportWithCustomScheduler,
+ ThreadScheduler*>
+ platform(&scheduler);
+
NullExecutionContext execution_context;
ScriptedIdleTaskController* controller =
ScriptedIdleTaskController::Create(execution_context_);
@@ -152,11 +128,11 @@ TEST_F(ScriptedIdleTaskControllerTest, DontRunCallbackWhenAskedToYield) {
EXPECT_NE(0, id);
EXPECT_CALL(*idle_task, invoke(testing::_)).Times(0);
- platform->RunIdleTask();
+ scheduler.RunIdleTask();
testing::Mock::VerifyAndClearExpectations(idle_task);
// The idle task should have been reposted.
- EXPECT_TRUE(platform->HasIdleTask());
+ EXPECT_TRUE(scheduler.HasIdleTask());
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/dom/shadow_root.cc b/chromium/third_party/blink/renderer/core/dom/shadow_root.cc
index dfc0422362e..d2e04506991 100644
--- a/chromium/third_party/blink/renderer/core/dom/shadow_root.cc
+++ b/chromium/third_party/blink/renderer/core/dom/shadow_root.cc
@@ -74,6 +74,7 @@ ShadowRoot::ShadowRoot(Document& document, ShadowRootType type)
type_(static_cast<unsigned short>(type)),
registered_with_parent_shadow_root_(false),
delegates_focus_(false),
+ slotting_(static_cast<unsigned short>(ShadowRootSlotting::kAuto)),
needs_distribution_recalc_(false),
unused_(0) {
if (IsV0())
@@ -111,6 +112,10 @@ Node* ShadowRoot::Clone(Document&, CloneChildrenFlag) const {
return nullptr;
}
+void ShadowRoot::SetSlotting(ShadowRootSlotting slotting) {
+ slotting_ = static_cast<unsigned short>(slotting);
+}
+
String ShadowRoot::InnerHTMLAsString() const {
return CreateMarkup(this, kChildrenOnly);
}
@@ -129,20 +134,11 @@ void ShadowRoot::SetInnerHTMLFromString(const String& markup,
void ShadowRoot::setInnerHTML(const StringOrTrustedHTML& stringOrHtml,
ExceptionState& exception_state) {
- DCHECK(stringOrHtml.IsString() ||
- RuntimeEnabledFeatures::TrustedDOMTypesEnabled());
-
- if (stringOrHtml.IsString() && GetDocument().RequireTrustedTypes()) {
- exception_state.ThrowTypeError(
- "This document requires `TrustedHTML` assignment.");
- return;
+ String html =
+ TrustedHTML::GetString(stringOrHtml, &GetDocument(), exception_state);
+ if (!exception_state.HadException()) {
+ SetInnerHTMLFromString(html, exception_state);
}
-
- String html = stringOrHtml.IsString()
- ? stringOrHtml.GetAsString()
- : stringOrHtml.GetAsTrustedHTML()->toString();
-
- SetInnerHTMLFromString(html, exception_state);
}
void ShadowRoot::RecalcStyle(StyleRecalcChange change) {
@@ -186,10 +182,10 @@ void ShadowRoot::DetachLayoutTree(const AttachContext& context) {
}
Node::InsertionNotificationRequest ShadowRoot::InsertedInto(
- ContainerNode* insertion_point) {
+ ContainerNode& insertion_point) {
DocumentFragment::InsertedInto(insertion_point);
- if (!insertion_point->isConnected())
+ if (!insertion_point.isConnected())
return kInsertionDone;
if (RuntimeEnabledFeatures::IncrementalShadowDOMEnabled())
@@ -211,15 +207,15 @@ Node::InsertionNotificationRequest ShadowRoot::InsertedInto(
return kInsertionDone;
}
-void ShadowRoot::RemovedFrom(ContainerNode* insertion_point) {
- if (insertion_point->isConnected()) {
+void ShadowRoot::RemovedFrom(ContainerNode& insertion_point) {
+ if (insertion_point.isConnected()) {
if (NeedsSlotAssignmentRecalc())
GetDocument().GetSlotAssignmentEngine().Disconnected(*this);
GetDocument().GetStyleEngine().ShadowRootRemovedFromDocument(this);
if (registered_with_parent_shadow_root_) {
ShadowRoot* root = host().ContainingShadowRoot();
if (!root)
- root = insertion_point->ContainingShadowRoot();
+ root = insertion_point.ContainingShadowRoot();
if (root)
root->RemoveChildShadowRoot();
registered_with_parent_shadow_root_ = false;
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 fda132984ea..df9d2012820 100644
--- a/chromium/third_party/blink/renderer/core/dom/shadow_root.h
+++ b/chromium/third_party/blink/renderer/core/dom/shadow_root.h
@@ -48,6 +48,8 @@ class WhitespaceAttacher;
enum class ShadowRootType { V0, kOpen, kClosed, kUserAgent };
+enum class ShadowRootSlotting { kManual, kAuto };
+
class CORE_EXPORT ShadowRoot final : public DocumentFragment, public TreeScope {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(ShadowRoot);
@@ -106,8 +108,8 @@ class CORE_EXPORT ShadowRoot final : public DocumentFragment, public TreeScope {
void AttachLayoutTree(AttachContext&) override;
void DetachLayoutTree(const AttachContext& = AttachContext()) override;
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
- void RemovedFrom(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
+ void RemovedFrom(ContainerNode&) override;
void SetNeedsAssignmentRecalc();
bool NeedsSlotAssignmentRecalc() const;
@@ -156,6 +158,12 @@ class CORE_EXPORT ShadowRoot final : public DocumentFragment, public TreeScope {
void SetDelegatesFocus(bool flag) { delegates_focus_ = flag; }
bool delegatesFocus() const { return delegates_focus_; }
+ void SetSlotting(ShadowRootSlotting slotting);
+ bool IsManualSlotting() {
+ return slotting_ ==
+ static_cast<unsigned short>(ShadowRootSlotting::kManual);
+ }
+
bool ContainsShadowRoots() const { return child_shadow_root_count_; }
StyleSheetList& StyleSheets();
@@ -187,8 +195,9 @@ class CORE_EXPORT ShadowRoot final : public DocumentFragment, public TreeScope {
unsigned short type_ : 2;
unsigned short registered_with_parent_shadow_root_ : 1;
unsigned short delegates_focus_ : 1;
+ unsigned short slotting_ : 1;
unsigned short needs_distribution_recalc_ : 1;
- unsigned short unused_ : 11;
+ unsigned short unused_ : 10;
DISALLOW_COPY_AND_ASSIGN(ShadowRoot);
};
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 6bba7b9435c..0857f2ae500 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,8 +5,10 @@
// Spec: https://w3c.github.io/webcomponents/spec/shadow/#shadowrootinit-dictionary
enum ShadowRootMode { "open", "closed" };
+enum ShadowRootSlottingMode { "manual", "auto" };
dictionary ShadowRootInit {
required ShadowRootMode mode;
boolean delegatesFocus;
+ [RuntimeEnabled=ManualSlotting] ShadowRootSlottingMode slotting;
};
diff --git a/chromium/third_party/blink/renderer/core/dom/slot_assignment.cc b/chromium/third_party/blink/renderer/core/dom/slot_assignment.cc
index 4049af22401..8b3fe1c6e02 100644
--- a/chromium/third_party/blink/renderer/core/dom/slot_assignment.cc
+++ b/chromium/third_party/blink/renderer/core/dom/slot_assignment.cc
@@ -9,12 +9,10 @@
#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/dom/slot_assignment_engine.h"
-#include "third_party/blink/renderer/core/dom/v0_insertion_point.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_details_element.h"
#include "third_party/blink/renderer/core/html/html_slot_element.h"
-#include "third_party/blink/renderer/core/html_names.h"
namespace blink {
@@ -39,6 +37,10 @@ void SlotAssignment::DidAddSlot(HTMLSlotElement& slot) {
++slot_count_;
needs_collect_slots_ = true;
+ if (owner_->IsManualSlotting()) {
+ DidAddSlotInternalInManualMode(slot);
+ return;
+ }
DCHECK(!slot_map_->Contains(slot.GetName()) ||
GetCachedFirstSlotWithoutAccessingNodeTree(slot.GetName()));
@@ -56,6 +58,15 @@ void SlotAssignment::DidRemoveSlot(HTMLSlotElement& slot) {
DCHECK_GT(slot_count_, 0u);
--slot_count_;
+ if (owner_->IsManualSlotting()) {
+ DCHECK(!needs_collect_slots_);
+ CallSlotChangeIfNeeded(slot);
+ needs_collect_slots_ = true;
+ // TODO(crbug.com/869308):Avoid calling Slots in order not to hit the
+ // DCHECK(!needs_collect_slots_)
+ Slots();
+ return;
+ }
needs_collect_slots_ = true;
DCHECK(GetCachedFirstSlotWithoutAccessingNodeTree(slot.GetName()));
@@ -85,7 +96,7 @@ void SlotAssignment::DidAddSlotInternal(HTMLSlotElement& slot) {
DCHECK(!old_active || old_active != slot);
// This might invalidate the slot_map's cache.
- slot_map_->Add(slot_name, &slot);
+ slot_map_->Add(slot_name, slot);
// This also ensures that TreeOrderedMap has a cache for the first element.
HTMLSlotElement* new_active = FindSlotByName(slot_name);
@@ -113,6 +124,17 @@ void SlotAssignment::DidAddSlotInternal(HTMLSlotElement& slot) {
}
}
+void SlotAssignment::DidAddSlotInternalInManualMode(HTMLSlotElement& slot) {
+ for (Node& child : NodeTraversal::ChildrenOf(owner_->host())) {
+ auto* change_slot = FindSlotChange(slot, child);
+ if (change_slot) {
+ slot.SignalSlotChange();
+ if (change_slot != slot)
+ change_slot->SignalSlotChange();
+ }
+ }
+}
+
void SlotAssignment::DidRemoveSlotInternal(
HTMLSlotElement& slot,
const AtomicString& slot_name,
@@ -132,7 +154,7 @@ void SlotAssignment::DidRemoveSlotInternal(
HTMLSlotElement* old_active =
GetCachedFirstSlotWithoutAccessingNodeTree(slot_name);
DCHECK(old_active);
- slot_map_->Remove(slot_name, &slot);
+ slot_map_->Remove(slot_name, slot);
// This also ensures that TreeOrderedMap has a cache for the first element.
HTMLSlotElement* new_active = FindSlotByName(slot_name);
DCHECK(!new_active || new_active != slot);
@@ -243,7 +265,16 @@ void SlotAssignment::RecalcAssignment() {
HTMLSlotElement* slot = nullptr;
if (!is_user_agent) {
- slot = FindSlotByName(child.SlotName());
+ if (owner_->IsManualSlotting()) {
+ for (auto a_slot : Slots()) {
+ if (a_slot->ContainsInAssignedNodesCandidates(child)) {
+ slot = a_slot;
+ break;
+ }
+ }
+ } else {
+ slot = FindSlotByName(child.SlotName());
+ }
} else {
if (user_agent_custom_assign_slot && ShouldAssignToCustomSlot(child)) {
slot = user_agent_custom_assign_slot;
@@ -332,12 +363,14 @@ const HeapVector<Member<HTMLSlotElement>>& SlotAssignment::Slots() {
return slots_;
}
-HTMLSlotElement* SlotAssignment::FindSlot(const Node& node) const {
+HTMLSlotElement* SlotAssignment::FindSlot(const Node& node) {
if (!node.IsSlotable())
return nullptr;
if (owner_->IsUserAgent())
return FindSlotInUserAgentShadow(node);
- return FindSlotByName(node.SlotName());
+ return owner_->IsManualSlotting()
+ ? FindFirstAssignedSlot(const_cast<Node&>(node))
+ : FindSlotByName(node.SlotName());
}
HTMLSlotElement* SlotAssignment::FindSlotByName(
@@ -356,6 +389,43 @@ HTMLSlotElement* SlotAssignment::FindSlotInUserAgentShadow(
return user_agent_default_slot;
}
+HTMLSlotElement* SlotAssignment::FindSlotChange(HTMLSlotElement& slot,
+ Node& child) {
+ HTMLSlotElement* found_this_slot = nullptr;
+ for (auto a_slot : Slots()) {
+ if (a_slot == slot) {
+ found_this_slot = &slot;
+ continue;
+ }
+ if (a_slot->ContainsInAssignedNodesCandidates(child)) {
+ if (found_this_slot) {
+ // case2 in DidRemoveSlotChange or DidAddSlotChange
+ return a_slot;
+ }
+ // case3 in DidRemoveSlotChange or DidAddSlotChange
+ return nullptr;
+ }
+ }
+ // case1 in DidRemoveSlotChange or DidAddSlotChange or no slot for the child
+ return found_this_slot;
+}
+
+void SlotAssignment::CallSlotChangeIfNeeded(HTMLSlotElement& slot) {
+ for (Node& child : NodeTraversal::ChildrenOf(owner_->host())) {
+ auto* change_slot = FindSlotChange(slot, child);
+ if (change_slot && change_slot != slot)
+ change_slot->SignalSlotChange();
+ }
+}
+
+HTMLSlotElement* SlotAssignment::FindFirstAssignedSlot(Node& node) {
+ for (auto slot : Slots()) {
+ if (slot->ContainsInAssignedNodesCandidates(node))
+ return slot;
+ }
+ return nullptr;
+}
+
void SlotAssignment::CollectSlots() {
DCHECK(needs_collect_slots_);
slots_.clear();
diff --git a/chromium/third_party/blink/renderer/core/dom/slot_assignment.h b/chromium/third_party/blink/renderer/core/dom/slot_assignment.h
index 579df6a18e3..9b27563fd86 100644
--- a/chromium/third_party/blink/renderer/core/dom/slot_assignment.h
+++ b/chromium/third_party/blink/renderer/core/dom/slot_assignment.h
@@ -7,10 +7,7 @@
#include "third_party/blink/renderer/core/dom/tree_ordered_map.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
-#include "third_party/blink/renderer/platform/wtf/hash_map.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
-#include "third_party/blink/renderer/platform/wtf/text/atomic_string_hash.h"
namespace blink {
@@ -25,7 +22,7 @@ class SlotAssignment final : public GarbageCollected<SlotAssignment> {
}
// Relevant DOM Standard: https://dom.spec.whatwg.org/#find-a-slot
- HTMLSlotElement* FindSlot(const Node&) const;
+ HTMLSlotElement* FindSlot(const Node&);
HTMLSlotElement* FindSlotByName(const AtomicString& slot_name) const;
// DOM Standaard defines these two procedures:
@@ -46,6 +43,8 @@ class SlotAssignment final : public GarbageCollected<SlotAssignment> {
const AtomicString& new_value);
bool FindHostChildBySlotName(const AtomicString& slot_name) const;
+ void CallSlotChangeIfNeeded(HTMLSlotElement& slot);
+ HTMLSlotElement* FindSlotChange(HTMLSlotElement& slot, Node& child);
void Trace(blink::Visitor*);
@@ -67,11 +66,14 @@ class SlotAssignment final : public GarbageCollected<SlotAssignment> {
HTMLSlotElement* FindSlotInUserAgentShadow(const Node&) const;
+ HTMLSlotElement* FindFirstAssignedSlot(Node&);
+
void CollectSlots();
HTMLSlotElement* GetCachedFirstSlotWithoutAccessingNodeTree(
const AtomicString& slot_name);
void DidAddSlotInternal(HTMLSlotElement&);
+ void DidAddSlotInternalInManualMode(HTMLSlotElement&);
void DidRemoveSlotInternal(HTMLSlotElement&,
const AtomicString& slot_name,
SlotMutationType);
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
index 53e1eb052f3..c2c719883ce 100644
--- a/chromium/third_party/blink/renderer/core/dom/synchronous_mutation_notifier.cc
+++ b/chromium/third_party/blink/renderer/core/dom/synchronous_mutation_notifier.cc
@@ -46,14 +46,7 @@ void SynchronousMutationNotifier::NotifyUpdateCharacterData(
unsigned offset,
unsigned old_length,
unsigned new_length) {
- // Using ForEachObserverWithoutChecks() instead of ForEachObserver() is
- // necessary because DocumentMarkerController::DidUpdateCharacterData ends up
- // calling SynchronousMutationNotifier::RemoveObserver, which is unsafe and
- // can result in memory corruption.
- //
- // TODO(crbug.com/862900): Fix DocumentMarkerController and switch to
- // ForEachObsever() here.
- ForEachObserverWithoutChecks([&](SynchronousMutationObserver* observer) {
+ ForEachObserver([&](SynchronousMutationObserver* observer) {
observer->DidUpdateCharacterData(character_data, offset, old_length,
new_length);
});
diff --git a/chromium/third_party/blink/renderer/core/dom/tree_ordered_map.cc b/chromium/third_party/blink/renderer/core/dom/tree_ordered_map.cc
index 00bf1d306d1..726880a1755 100644
--- a/chromium/third_party/blink/renderer/core/dom/tree_ordered_map.cc
+++ b/chromium/third_party/blink/renderer/core/dom/tree_ordered_map.cc
@@ -76,9 +76,8 @@ inline bool KeyMatchesSlotName(const AtomicString& key,
ToHTMLSlotElement(element).GetName() == key;
}
-void TreeOrderedMap::Add(const AtomicString& key, Element* element) {
+void TreeOrderedMap::Add(const AtomicString& key, Element& element) {
DCHECK(key);
- DCHECK(element);
Map::AddResult add_result = map_.insert(key, new MapEntry(element));
if (add_result.is_new_entry)
@@ -91,9 +90,8 @@ void TreeOrderedMap::Add(const AtomicString& key, Element* element) {
entry->ordered_list.clear();
}
-void TreeOrderedMap::Remove(const AtomicString& key, Element* element) {
+void TreeOrderedMap::Remove(const AtomicString& key, Element& element) {
DCHECK(key);
- DCHECK(element);
Map::iterator it = map_.find(key);
if (it == map_.end())
diff --git a/chromium/third_party/blink/renderer/core/dom/tree_ordered_map.h b/chromium/third_party/blink/renderer/core/dom/tree_ordered_map.h
index 7598e47ea1a..8a5eba0d681 100644
--- a/chromium/third_party/blink/renderer/core/dom/tree_ordered_map.h
+++ b/chromium/third_party/blink/renderer/core/dom/tree_ordered_map.h
@@ -50,8 +50,8 @@ class TreeOrderedMap : public GarbageCollected<TreeOrderedMap> {
public:
static TreeOrderedMap* Create();
- void Add(const AtomicString&, Element*);
- void Remove(const AtomicString&, Element*);
+ void Add(const AtomicString&, Element&);
+ void Remove(const AtomicString&, Element&);
bool Contains(const AtomicString&) const;
bool ContainsMultiple(const AtomicString&) const;
@@ -98,7 +98,7 @@ class TreeOrderedMap : public GarbageCollected<TreeOrderedMap> {
class MapEntry : public GarbageCollected<MapEntry> {
public:
- explicit MapEntry(Element* first_element)
+ explicit MapEntry(Element& first_element)
: element(first_element), count(1) {}
void Trace(blink::Visitor*);
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 05b1cd910c2..ab7a51a9d28 100644
--- a/chromium/third_party/blink/renderer/core/dom/tree_scope.cc
+++ b/chromium/third_party/blink/renderer/core/dom/tree_scope.cc
@@ -137,7 +137,7 @@ const HeapVector<Member<Element>>& TreeScope::GetAllElementsById(
}
void TreeScope::AddElementById(const AtomicString& element_id,
- Element* element) {
+ Element& element) {
if (!elements_by_id_)
elements_by_id_ = TreeOrderedMap::Create();
elements_by_id_->Add(element_id, element);
@@ -145,7 +145,7 @@ void TreeScope::AddElementById(const AtomicString& element_id,
}
void TreeScope::RemoveElementById(const AtomicString& element_id,
- Element* element) {
+ Element& element) {
if (!elements_by_id_)
return;
elements_by_id_->Remove(element_id, element);
@@ -165,8 +165,8 @@ Node* TreeScope::AncestorInThisScope(Node* node) const {
return nullptr;
}
-void TreeScope::AddImageMap(HTMLMapElement* image_map) {
- const AtomicString& name = image_map->GetName();
+void TreeScope::AddImageMap(HTMLMapElement& image_map) {
+ const AtomicString& name = image_map.GetName();
if (!name)
return;
if (!image_maps_by_name_)
@@ -174,10 +174,10 @@ void TreeScope::AddImageMap(HTMLMapElement* image_map) {
image_maps_by_name_->Add(name, image_map);
}
-void TreeScope::RemoveImageMap(HTMLMapElement* image_map) {
+void TreeScope::RemoveImageMap(HTMLMapElement& image_map) {
if (!image_maps_by_name_)
return;
- const AtomicString& name = image_map->GetName();
+ const AtomicString& name = image_map.GetName();
if (!name)
return;
image_maps_by_name_->Remove(name, image_map);
diff --git a/chromium/third_party/blink/renderer/core/dom/tree_scope.h b/chromium/third_party/blink/renderer/core/dom/tree_scope.h
index 63d0cb9206d..4542fc70052 100644
--- a/chromium/third_party/blink/renderer/core/dom/tree_scope.h
+++ b/chromium/third_party/blink/renderer/core/dom/tree_scope.h
@@ -76,8 +76,8 @@ class CORE_EXPORT TreeScope : public GarbageCollectedMixin {
const AtomicString&) const;
bool HasElementWithId(const AtomicString& id) const;
bool ContainsMultipleElementsWithId(const AtomicString& id) const;
- void AddElementById(const AtomicString& element_id, Element*);
- void RemoveElementById(const AtomicString& element_id, Element*);
+ void AddElementById(const AtomicString& element_id, Element&);
+ void RemoveElementById(const AtomicString& element_id, Element&);
Document& GetDocument() const {
DCHECK(document_);
@@ -86,8 +86,8 @@ class CORE_EXPORT TreeScope : public GarbageCollectedMixin {
Node* AncestorInThisScope(Node*) const;
- void AddImageMap(HTMLMapElement*);
- void RemoveImageMap(HTMLMapElement*);
+ void AddImageMap(HTMLMapElement&);
+ void RemoveImageMap(HTMLMapElement&);
HTMLMapElement* GetImageMap(const String& url) const;
Element* ElementFromPoint(double x, double y) const;
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 59f1a048c3e..aef3967fea7 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
@@ -138,18 +138,25 @@ void V0InsertionPoint::RebuildDistributedChildrenLayoutTrees(
}
}
-void V0InsertionPoint::WillRecalcStyle(StyleRecalcChange change) {
- StyleChangeType style_change_type = kNoStyleChange;
-
- if (change > kInherit || GetStyleChangeType() > kLocalStyleChange)
- style_change_type = kSubtreeStyleChange;
- else if (change > kNoInherit)
- style_change_type = kLocalStyleChange;
- else
+void V0InsertionPoint::DidRecalcStyle(StyleRecalcChange change) {
+ if (!HasDistribution() || DistributedNodeAt(0)->parentNode() == this) {
+ // We either do not have distributed children or the distributed children
+ // are the fallback children. Fallback children have already been
+ // recalculated in ContainerNode::RecalcDescendantStyles().
return;
+ }
+
+ StyleChangeType style_change_type =
+ change == kForce ? kSubtreeStyleChange : kLocalStyleChange;
for (size_t i = 0; i < distributed_nodes_.size(); ++i) {
- distributed_nodes_.at(i)->SetNeedsStyleRecalc(
+ Node* node = distributed_nodes_.at(i);
+ if (change == kReattach && node->IsElementNode()) {
+ if (node->ShouldCallRecalcStyle(kReattach))
+ ToElement(node)->RecalcStyle(kReattach);
+ continue;
+ }
+ node->SetNeedsStyleRecalc(
style_change_type,
StyleChangeReasonForTracing::Create(
StyleChangeReason::kPropagateInheritChangeToDistributedNodes));
@@ -212,7 +219,7 @@ void V0InsertionPoint::ChildrenChanged(const ChildrenChange& change) {
}
Node::InsertionNotificationRequest V0InsertionPoint::InsertedInto(
- ContainerNode* insertion_point) {
+ ContainerNode& insertion_point) {
HTMLElement::InsertedInto(insertion_point);
if (ShadowRoot* root = ContainingShadowRoot()) {
if (!root->IsV1()) {
@@ -220,7 +227,7 @@ Node::InsertionNotificationRequest V0InsertionPoint::InsertedInto(
root->IsV1()))
root->SetNeedsDistributionRecalc();
if (CanBeActive() && !registered_with_shadow_root_ &&
- insertion_point->GetTreeScope().RootNode() == root) {
+ insertion_point.GetTreeScope().RootNode() == root) {
registered_with_shadow_root_ = true;
root->V0().DidAddInsertionPoint(this);
if (CanAffectSelector())
@@ -236,10 +243,10 @@ Node::InsertionNotificationRequest V0InsertionPoint::InsertedInto(
return kInsertionDone;
}
-void V0InsertionPoint::RemovedFrom(ContainerNode* insertion_point) {
+void V0InsertionPoint::RemovedFrom(ContainerNode& insertion_point) {
ShadowRoot* root = ContainingShadowRoot();
if (!root)
- root = insertion_point->ContainingShadowRoot();
+ root = insertion_point.ContainingShadowRoot();
if (root &&
!(RuntimeEnabledFeatures::IncrementalShadowDOMEnabled() && root->IsV1()))
@@ -250,7 +257,7 @@ void V0InsertionPoint::RemovedFrom(ContainerNode* insertion_point) {
ClearDistribution();
if (registered_with_shadow_root_ &&
- insertion_point->GetTreeScope().RootNode() == root) {
+ insertion_point.GetTreeScope().RootNode() == root) {
DCHECK(root);
registered_with_shadow_root_ = false;
root->V0().DidRemoveInsertionPoint(this);
diff --git a/chromium/third_party/blink/renderer/core/dom/v0_insertion_point.h b/chromium/third_party/blink/renderer/core/dom/v0_insertion_point.h
index 811fd7c0383..fde33dc516c 100644
--- a/chromium/third_party/blink/renderer/core/dom/v0_insertion_point.h
+++ b/chromium/third_party/blink/renderer/core/dom/v0_insertion_point.h
@@ -81,9 +81,9 @@ class CORE_EXPORT V0InsertionPoint : public HTMLElement {
V0InsertionPoint(const QualifiedName&, Document&);
bool LayoutObjectIsNeeded(const ComputedStyle&) const override;
void ChildrenChanged(const ChildrenChange&) override;
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
- void RemovedFrom(ContainerNode*) override;
- void WillRecalcStyle(StyleRecalcChange) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
+ void RemovedFrom(ContainerNode&) override;
+ void DidRecalcStyle(StyleRecalcChange) override;
private:
bool IsV0InsertionPoint() const =
diff --git a/chromium/third_party/blink/renderer/core/dom/visited_link_state.cc b/chromium/third_party/blink/renderer/core/dom/visited_link_state.cc
index 8045907b16d..5cedf79b315 100644
--- a/chromium/third_party/blink/renderer/core/dom/visited_link_state.cc
+++ b/chromium/third_party/blink/renderer/core/dom/visited_link_state.cc
@@ -35,6 +35,7 @@
#include "third_party/blink/renderer/core/dom/shadow_root.h"
#include "third_party/blink/renderer/core/html/html_anchor_element.h"
#include "third_party/blink/renderer/core/html_names.h"
+#include "third_party/blink/renderer/core/svg/svg_element.h"
#include "third_party/blink/renderer/core/svg/svg_uri_reference.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/core/editing/BUILD.gn b/chromium/third_party/blink/renderer/core/editing/BUILD.gn
index ea78e473a3d..131561eda78 100644
--- a/chromium/third_party/blink/renderer/core/editing/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/editing/BUILD.gn
@@ -105,6 +105,8 @@ blink_core_sources("editing") {
"commands/unlink_command.h",
"commands/wrap_contents_in_dummy_span_command.cc",
"commands/wrap_contents_in_dummy_span_command.h",
+ "compute_layer_selection.cc",
+ "compute_layer_selection.h",
"dom_selection.cc",
"dom_selection.h",
"drag_caret.cc",
@@ -125,6 +127,7 @@ blink_core_sources("editing") {
"editor.cc",
"editor.h",
"editor_key_bindings.cc",
+ "element_inner_text.cc",
"ephemeral_range.cc",
"ephemeral_range.h",
"finder/find_in_page_coordinates.cc",
@@ -237,8 +240,6 @@ blink_core_sources("editing") {
"position_with_affinity.h",
"relocatable_position.cc",
"relocatable_position.h",
- "rendered_position.cc",
- "rendered_position.h",
"reveal_selection_scope.cc",
"reveal_selection_scope.h",
"selection_adjuster.cc",
@@ -275,8 +276,8 @@ blink_core_sources("editing") {
"spellcheck/cold_mode_spell_check_requester.h",
"spellcheck/hot_mode_spell_check_requester.cc",
"spellcheck/hot_mode_spell_check_requester.h",
- "spellcheck/idle_spell_check_callback.cc",
- "spellcheck/idle_spell_check_callback.h",
+ "spellcheck/idle_spell_check_controller.cc",
+ "spellcheck/idle_spell_check_controller.h",
"spellcheck/spell_check_requester.cc",
"spellcheck/spell_check_requester.h",
"spellcheck/spell_checker.cc",
@@ -351,10 +352,12 @@ jumbo_source_set("unit_tests") {
"commands/set_character_data_command_test.cc",
"commands/split_text_node_command_test.cc",
"commands/typing_command_test.cc",
+ "compute_layer_selection_test.cc",
"editing_strategy_test.cc",
"editing_style_test.cc",
"editing_utilities_test.cc",
"editor_test.cc",
+ "element_inner_text_test.cc",
"ephemeral_range_test.cc",
"frame_caret_test.cc",
"frame_selection_test.cc",
@@ -394,7 +397,6 @@ jumbo_source_set("unit_tests") {
"position_test.cc",
"position_with_affinity_test.cc",
"relocatable_position_test.cc",
- "rendered_position_test.cc",
"selection_adjuster_test.cc",
"selection_controller_test.cc",
"selection_modifier_character_test.cc",
@@ -403,7 +405,7 @@ jumbo_source_set("unit_tests") {
"selection_template_test.cc",
"serializers/styled_markup_serializer_test.cc",
"set_selection_options_test.cc",
- "spellcheck/idle_spell_check_callback_test.cc",
+ "spellcheck/idle_spell_check_controller_test.cc",
"spellcheck/spell_check_test_base.cc",
"spellcheck/spell_check_test_base.h",
"spellcheck/spell_checker_test.cc",
diff --git a/chromium/third_party/blink/renderer/core/editing/caret_display_item_client.cc b/chromium/third_party/blink/renderer/core/editing/caret_display_item_client.cc
index 02b2bb4b2bd..616979afecb 100644
--- a/chromium/third_party/blink/renderer/core/editing/caret_display_item_client.cc
+++ b/chromium/third_party/blink/renderer/core/editing/caret_display_item_client.cc
@@ -143,7 +143,7 @@ void CaretDisplayItemClient::UpdateStyleAndLayoutIfNeeded(
LayoutBlock* new_layout_block = CaretLayoutBlock(caret_position.AnchorNode());
if (new_layout_block != layout_block_) {
if (layout_block_)
- layout_block_->SetMayNeedPaintInvalidation();
+ layout_block_->SetShouldCheckForPaintInvalidation();
layout_block_ = new_layout_block;
visual_rect_ = LayoutRect();
if (new_layout_block) {
@@ -181,7 +181,7 @@ void CaretDisplayItemClient::UpdateStyleAndLayoutIfNeeded(
}
if (needs_paint_invalidation_)
- new_layout_block->SetMayNeedPaintInvalidation();
+ new_layout_block->SetShouldCheckForPaintInvalidation();
}
void CaretDisplayItemClient::InvalidatePaint(
@@ -221,13 +221,6 @@ void CaretDisplayItemClient::InvalidatePaintInCurrentLayoutBlock(
if (!local_rect_.IsEmpty()) {
new_visual_rect = local_rect_;
context.MapLocalRectToVisualRect(*layout_block_, new_visual_rect);
-
- if (layout_block_->UsesCompositedScrolling()) {
- // The caret should use scrolling coordinate space.
- DCHECK(layout_block_ == context.paint_invalidation_container);
- new_visual_rect.Move(
- LayoutSize(layout_block_->ScrolledContentOffset()));
- }
}
} else {
new_visual_rect = visual_rect_;
@@ -241,8 +234,7 @@ void CaretDisplayItemClient::InvalidatePaintInCurrentLayoutBlock(
// The caret may change paint offset without changing visual rect, and we
// need to invalidate the display item client if the block is doing full
// paint invalidation.
- if (IsImmediateFullPaintInvalidationReason(
- layout_block_->FullPaintInvalidationReason())) {
+ if (layout_block_->ShouldDoFullPaintInvalidation()) {
object_invalidator.InvalidateDisplayItemClient(
*this, PaintInvalidationReason::kCaret);
}
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 19cc6e4369b..a94bb121f83 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
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/editing/caret_display_item_client.h"
+#include "testing/gmock/include/gmock/gmock-matchers.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "third_party/blink/renderer/core/editing/frame_selection.h"
#include "third_party/blink/renderer/core/editing/selection_template.h"
@@ -16,6 +17,8 @@
namespace blink {
+using PaintInvalidation = LocalFrameView::ObjectPaintInvalidation;
+using ::testing::ElementsAre;
using ::testing::UnorderedElementsAre;
class CaretDisplayItemClientTest : public PaintAndRasterInvalidationTest {
@@ -94,13 +97,9 @@ TEST_P(CaretDisplayItemClientTest, CaretPaintInvalidation) {
RasterInvalidationInfo{&GetCaretDisplayItemClient(), "Caret",
EnclosingIntRect(caret_visual_rect),
PaintInvalidationReason::kAppeared}));
-
- std::unique_ptr<JSONArray> object_invalidations =
- GetDocument().View()->TrackedObjectPaintInvalidationsAsJSON();
- ASSERT_EQ(1u, object_invalidations->size());
- String s;
- JSONObject::Cast(object_invalidations->at(0))->Get("object")->AsString(&s);
- EXPECT_EQ("Caret", s);
+ EXPECT_THAT(
+ *GetDocument().View()->TrackedObjectPaintInvalidations(),
+ ElementsAre(PaintInvalidation{"Caret", PaintInvalidationReason::kCaret}));
GetDocument().View()->SetTracksPaintInvalidations(false);
// Move the caret to the end of the text. Should invalidate both the old and
@@ -125,12 +124,9 @@ TEST_P(CaretDisplayItemClientTest, CaretPaintInvalidation) {
RasterInvalidationInfo{&GetCaretDisplayItemClient(), "Caret",
EnclosingIntRect(new_caret_visual_rect),
PaintInvalidationReason::kCaret}));
-
- object_invalidations =
- GetDocument().View()->TrackedObjectPaintInvalidationsAsJSON();
- ASSERT_EQ(1u, object_invalidations->size());
- JSONObject::Cast(object_invalidations->at(0))->Get("object")->AsString(&s);
- EXPECT_EQ("Caret", s);
+ EXPECT_THAT(
+ *GetDocument().View()->TrackedObjectPaintInvalidations(),
+ ElementsAre(PaintInvalidation{"Caret", PaintInvalidationReason::kCaret}));
GetDocument().View()->SetTracksPaintInvalidations(false);
// Remove selection. Should invalidate the old caret.
@@ -146,12 +142,9 @@ TEST_P(CaretDisplayItemClientTest, CaretPaintInvalidation) {
&GetCaretDisplayItemClient(), "Caret",
EnclosingIntRect(old_caret_visual_rect),
PaintInvalidationReason::kDisappeared}));
-
- object_invalidations =
- GetDocument().View()->TrackedObjectPaintInvalidationsAsJSON();
- ASSERT_EQ(1u, object_invalidations->size());
- JSONObject::Cast(object_invalidations->at(0))->Get("object")->AsString(&s);
- EXPECT_EQ("Caret", s);
+ EXPECT_THAT(
+ *GetDocument().View()->TrackedObjectPaintInvalidations(),
+ ElementsAre(PaintInvalidation{"Caret", PaintInvalidationReason::kCaret}));
GetDocument().View()->SetTracksPaintInvalidations(false);
}
@@ -198,10 +191,10 @@ TEST_P(CaretDisplayItemClientTest, CaretMovesBetweenBlocks) {
RasterInvalidationInfo{&GetCaretDisplayItemClient(), "Caret",
EnclosingIntRect(caret_visual_rect2),
PaintInvalidationReason::kCaret}));
-
- std::unique_ptr<JSONArray> object_invalidations =
- GetDocument().View()->TrackedObjectPaintInvalidationsAsJSON();
- ASSERT_EQ(2u, object_invalidations->size());
+ EXPECT_THAT(
+ *GetDocument().View()->TrackedObjectPaintInvalidations(),
+ ElementsAre(PaintInvalidation{"Caret", PaintInvalidationReason::kCaret},
+ PaintInvalidation{"Caret", PaintInvalidationReason::kCaret}));
GetDocument().View()->SetTracksPaintInvalidations(false);
// Move the caret back into block1.
@@ -224,10 +217,10 @@ TEST_P(CaretDisplayItemClientTest, CaretMovesBetweenBlocks) {
RasterInvalidationInfo{&GetCaretDisplayItemClient(), "Caret",
EnclosingIntRect(caret_visual_rect2),
PaintInvalidationReason::kCaret}));
-
- object_invalidations =
- GetDocument().View()->TrackedObjectPaintInvalidationsAsJSON();
- ASSERT_EQ(2u, object_invalidations->size());
+ EXPECT_THAT(
+ *GetDocument().View()->TrackedObjectPaintInvalidations(),
+ ElementsAre(PaintInvalidation{"Caret", PaintInvalidationReason::kCaret},
+ PaintInvalidation{"Caret", PaintInvalidationReason::kCaret}));
GetDocument().View()->SetTracksPaintInvalidations(false);
}
@@ -331,13 +324,9 @@ TEST_P(CaretDisplayItemClientTest, CaretHideMoveAndShow) {
RasterInvalidationInfo{&GetCaretDisplayItemClient(), "Caret",
EnclosingIntRect(new_caret_visual_rect),
PaintInvalidationReason::kCaret}));
-
- auto object_invalidations =
- GetDocument().View()->TrackedObjectPaintInvalidationsAsJSON();
- ASSERT_EQ(1u, object_invalidations->size());
- String s;
- JSONObject::Cast(object_invalidations->at(0))->Get("object")->AsString(&s);
- EXPECT_EQ("Caret", s);
+ EXPECT_THAT(
+ *GetDocument().View()->TrackedObjectPaintInvalidations(),
+ ElementsAre(PaintInvalidation{"Caret", PaintInvalidationReason::kCaret}));
GetDocument().View()->SetTracksPaintInvalidations(false);
}
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 66199c9a1a2..507972f33e0 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
@@ -89,14 +89,16 @@ void ApplyBlockElementCommand::DoApply(EditingState* editing_state) {
if (new_end.IsNotNull())
builder.Extend(new_end);
SetEndingSelection(SelectionForUndoStep::From(builder.Build()));
+ ABORT_EDITING_COMMAND_IF(EndingVisibleSelection().VisibleStart().IsNull());
+ ABORT_EDITING_COMMAND_IF(EndingVisibleSelection().VisibleEnd().IsNull());
}
VisibleSelection selection =
SelectionForParagraphIteration(EndingVisibleSelection());
VisiblePosition start_of_selection = selection.VisibleStart();
+ ABORT_EDITING_COMMAND_IF(start_of_selection.IsNull());
VisiblePosition end_of_selection = selection.VisibleEnd();
- DCHECK(!start_of_selection.IsNull());
- DCHECK(!end_of_selection.IsNull());
+ ABORT_EDITING_COMMAND_IF(end_of_selection.IsNull());
ContainerNode* start_scope = nullptr;
int start_index = IndexForVisiblePosition(start_of_selection, start_scope);
ContainerNode* end_scope = nullptr;
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 0c31debf868..8ad2938083f 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
@@ -37,12 +37,13 @@ TEST_F(ApplyBlockElementCommandTest, selectionCrossingOverBody) {
GetDocument().body()->setContentEditable("false", ASSERT_NO_EXCEPTION);
GetDocument().setDesignMode("on");
GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
- Selection().SetSelectionAndEndTyping(
+ Selection().SetSelection(
SelectionInDOMTree::Builder()
.SetBaseAndExtent(
Position(GetDocument().documentElement(), 1),
Position(GetDocument().getElementById("va")->firstChild(), 2))
- .Build());
+ .Build(),
+ SetSelectionOptions());
FormatBlockCommand* command =
FormatBlockCommand::Create(GetDocument(), HTMLNames::footerTag);
@@ -63,10 +64,11 @@ TEST_F(ApplyBlockElementCommandTest, visibilityChangeDuringCommand) {
GetDocument().setDesignMode("on");
UpdateAllLifecyclePhases();
- Selection().SetSelectionAndEndTyping(
+ Selection().SetSelection(
SelectionInDOMTree::Builder()
.Collapse(Position(GetDocument().QuerySelector("li"), 0))
- .Build());
+ .Build(),
+ SetSelectionOptions());
IndentOutdentCommand* command = IndentOutdentCommand::Create(
GetDocument(), IndentOutdentCommand::kIndent);
@@ -87,10 +89,11 @@ TEST_F(ApplyBlockElementCommandTest, IndentHeadingIntoBlockquote) {
"</div>");
Element* button = GetDocument().QuerySelector("button");
Element* object = GetDocument().QuerySelector("object");
- Selection().SetSelectionAndEndTyping(SelectionInDOMTree::Builder()
- .Collapse(Position(button, 0))
- .Extend(Position(object, 0))
- .Build());
+ Selection().SetSelection(SelectionInDOMTree::Builder()
+ .Collapse(Position(button, 0))
+ .Extend(Position(object, 0))
+ .Build(),
+ SetSelectionOptions());
IndentOutdentCommand* command = IndentOutdentCommand::Create(
GetDocument(), IndentOutdentCommand::kIndent);
@@ -113,8 +116,10 @@ TEST_F(ApplyBlockElementCommandTest, IndentHeadingIntoBlockquote) {
TEST_F(ApplyBlockElementCommandTest, InsertPlaceHolderAtDisconnectedPosition) {
GetDocument().setDesignMode("on");
InsertStyleElement(".input:nth-of-type(2n+1) { visibility:collapse; }");
- Selection().SetSelectionAndEndTyping(SetSelectionTextToBody(
- "^<input><input class=\"input\" style=\"position:absolute\">|"));
+ Selection().SetSelection(
+ SetSelectionTextToBody(
+ "^<input><input class=\"input\" style=\"position:absolute\">|"),
+ SetSelectionOptions());
FormatBlockCommand* command =
FormatBlockCommand::Create(GetDocument(), HTMLNames::preTag);
// Crash happens here.
@@ -124,4 +129,40 @@ TEST_F(ApplyBlockElementCommandTest, InsertPlaceHolderAtDisconnectedPosition) {
GetSelectionTextFromBody());
}
+// https://crbug.com/873084
+TEST_F(ApplyBlockElementCommandTest, FormatBlockCrossingUserModifyBoundary) {
+ InsertStyleElement("*{-webkit-user-modify:read-write}");
+ Selection().SetSelection(
+ SetSelectionTextToBody(
+ "^<b style=\"-webkit-user-modify:read-only\"><button></button></b>|"),
+ SetSelectionOptions());
+ FormatBlockCommand* command =
+ FormatBlockCommand::Create(GetDocument(), HTMLNames::preTag);
+ // Shouldn't crash here.
+ EXPECT_FALSE(command->Apply());
+ EXPECT_EQ(
+ "^<b style=\"-webkit-user-modify:read-only\"><button>|</button></b>",
+ GetSelectionTextFromBody());
+}
+
+// https://crbug.com/873084
+TEST_F(ApplyBlockElementCommandTest,
+ FormatBlockWithTableCrossingUserModifyBoundary) {
+ InsertStyleElement("*{-webkit-user-modify:read-write}");
+ Selection().SetSelection(
+ SetSelectionTextToBody("^<table></table>"
+ "<kbd "
+ "style=\"-webkit-user-modify:read-only\"><button><"
+ "/button></kbd>|"),
+ SetSelectionOptions());
+ FormatBlockCommand* command =
+ FormatBlockCommand::Create(GetDocument(), HTMLNames::preTag);
+ // Shouldn't crash here.
+ EXPECT_FALSE(command->Apply());
+ EXPECT_EQ(
+ "<table>^</table>"
+ "<kbd style=\"-webkit-user-modify:read-only\"><button>|</button></kbd>",
+ GetSelectionTextFromBody());
+}
+
} // namespace blink
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 93e43d87f64..edbe6e4ad38 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
@@ -35,10 +35,11 @@ TEST_F(ApplyStyleCommandTest, RemoveRedundantBlocksWithStarEditableStyle) {
Element* li = GetDocument().QuerySelector("li");
LocalFrame* frame = GetDocument().GetFrame();
- frame->Selection().SetSelectionAndEndTyping(
+ frame->Selection().SetSelection(
SelectionInDOMTree::Builder()
.Collapse(Position(li, PositionAnchorType::kBeforeAnchor))
- .Build());
+ .Build(),
+ SetSelectionOptions());
MutableCSSPropertyValueSet* style =
MutableCSSPropertyValueSet::Create(kHTMLQuirksMode);
@@ -82,8 +83,10 @@ TEST_F(ApplyStyleCommandTest, JustifyRightDetachesDestination) {
// This is a regression test for https://crbug.com/726992
TEST_F(ApplyStyleCommandTest, FontSizeDeltaWithSpanElement) {
- Selection().SetSelectionAndEndTyping(SetSelectionTextToBody(
- "<div contenteditable>^<div></div>a<span></span>|</div>"));
+ Selection().SetSelection(
+ SetSelectionTextToBody(
+ "<div contenteditable>^<div></div>a<span></span>|</div>"),
+ SetSelectionOptions());
MutableCSSPropertyValueSet* style =
MutableCSSPropertyValueSet::Create(kHTMLQuirksMode);
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 17f724a124f..4d665a45f9b 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
@@ -32,8 +32,10 @@
#include "third_party/blink/renderer/core/editing/commands/clipboard_commands.h"
#include "third_party/blink/renderer/core/clipboard/data_transfer_access_policy.h"
+#include "third_party/blink/renderer/core/clipboard/paste_mode.h"
#include "third_party/blink/renderer/core/clipboard/system_clipboard.h"
#include "third_party/blink/renderer/core/editing/commands/editing_commands_utilities.h"
+#include "third_party/blink/renderer/core/editing/editing_behavior.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"
@@ -42,11 +44,12 @@
#include "third_party/blink/renderer/core/events/clipboard_event.h"
#include "third_party/blink/renderer/core/events/text_event.h"
#include "third_party/blink/renderer/core/frame/content_settings_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/frame/settings.h"
#include "third_party/blink/renderer/core/html/forms/text_control_element.h"
#include "third_party/blink/renderer/core/html/html_image_element.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
-#include "third_party/blink/renderer/platform/paste_mode.h"
namespace blink {
@@ -114,7 +117,7 @@ bool ClipboardCommands::DispatchClipboardEvent(LocalFrame& frame,
: DataObject::CreateFromClipboard(paste_mode));
Event* const evt = ClipboardEvent::Create(event_type, data_transfer);
- target->DispatchEvent(evt);
+ target->DispatchEvent(*evt);
const bool no_default_processing = evt->defaultPrevented();
if (no_default_processing && policy == DataTransferAccessPolicy::kWritable) {
SystemClipboard::GetInstance().WriteDataObject(
@@ -327,7 +330,7 @@ void ClipboardCommands::PasteAsFragment(LocalFrame& frame,
Element* const target = FindEventTargetForClipboardEvent(frame, source);
if (!target)
return;
- target->DispatchEvent(TextEvent::CreateForFragmentPaste(
+ target->DispatchEvent(*TextEvent::CreateForFragmentPaste(
frame.DomWindow(), pasting_fragment, smart_replace, match_style));
}
@@ -337,7 +340,7 @@ void ClipboardCommands::PasteAsPlainTextFromClipboard(
Element* const target = FindEventTargetForClipboardEvent(frame, source);
if (!target)
return;
- target->DispatchEvent(TextEvent::CreateForPlainTextPaste(
+ target->DispatchEvent(*TextEvent::CreateForPlainTextPaste(
frame.DomWindow(), SystemClipboard::GetInstance().ReadPlainText(),
CanSmartReplaceInClipboard(frame)));
}
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 8929fb2727c..0adc0ef204e 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
@@ -135,8 +135,6 @@ bool CompositeEditCommand::Apply() {
case InputEvent::InputType::kNone:
break;
default:
- NOTREACHED() << "Not supported input type on plain-text only element:"
- << static_cast<int>(GetInputType());
return false;
}
}
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 77cb714ac9e..92d26c6f31c 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
@@ -37,11 +37,12 @@ TEST_F(DeleteSelectionCommandTest, deleteListFromTable) {
Element* br = GetDocument().QuerySelector("br");
LocalFrame* frame = GetDocument().GetFrame();
- frame->Selection().SetSelectionAndEndTyping(
+ frame->Selection().SetSelection(
SelectionInDOMTree::Builder()
.Collapse(Position(br, PositionAnchorType::kBeforeAnchor))
.Extend(Position(table, PositionAnchorType::kAfterAnchor))
- .Build());
+ .Build(),
+ SetSelectionOptions());
DeleteSelectionCommand* command =
DeleteSelectionCommand::Create(GetDocument(),
@@ -63,8 +64,9 @@ TEST_F(DeleteSelectionCommandTest, deleteListFromTable) {
TEST_F(DeleteSelectionCommandTest, ForwardDeleteWithFirstLetter) {
InsertStyleElement("p::first-letter {font-size:200%;}");
- Selection().SetSelectionAndEndTyping(
- SetSelectionTextToBody("<p contenteditable>a^b|c</p>"));
+ Selection().SetSelection(
+ SetSelectionTextToBody("<p contenteditable>a^b|c</p>"),
+ SetSelectionOptions());
DeleteSelectionCommand& command = *DeleteSelectionCommand::Create(
GetDocument(), DeleteSelectionOptions::Builder()
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 9cbe75b81b8..fcae634bd8f 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
@@ -35,6 +35,7 @@
#include "third_party/blink/renderer/core/editing/commands/editor_command.h"
#include "third_party/blink/renderer/core/editing/editing_tri_state.h"
#include "third_party/blink/renderer/core/editing/editor.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/use_counter.h"
#include "third_party/blink/renderer/core/html/forms/text_control_element.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
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 fe65f08ccef..c09a126fcf4 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
@@ -451,6 +451,7 @@ VisibleSelection SelectionForParagraphIteration(
// we'll want modify is the last one inside the table, not the table itself (a
// table is itself a paragraph).
if (Element* table = TableElementJustBefore(end_of_selection)) {
+ DCHECK(start_of_selection.IsNotNull()) << new_selection;
if (start_of_selection.DeepEquivalent().AnchorNode()->IsDescendantOf(
table)) {
const VisiblePosition& new_end =
@@ -475,6 +476,7 @@ VisibleSelection SelectionForParagraphIteration(
// want to modify is the first one inside the table, not the paragraph
// containing the table itself.
if (Element* table = TableElementJustAfter(start_of_selection)) {
+ DCHECK(end_of_selection.IsNotNull()) << new_selection;
if (end_of_selection.DeepEquivalent().AnchorNode()->IsDescendantOf(table)) {
const VisiblePosition new_start =
NextPositionOf(start_of_selection, kCannotCrossEditingBoundary);
@@ -579,11 +581,11 @@ void DispatchEditableContentChangedEvents(Element* start_root,
Element* end_root) {
if (start_root) {
start_root->DispatchEvent(
- Event::Create(EventTypeNames::webkitEditableContentChanged));
+ *Event::Create(EventTypeNames::webkitEditableContentChanged));
}
if (end_root && end_root != start_root) {
end_root->DispatchEvent(
- Event::Create(EventTypeNames::webkitEditableContentChanged));
+ *Event::Create(EventTypeNames::webkitEditableContentChanged));
}
}
@@ -597,7 +599,7 @@ static void DispatchInputEvent(Element* target,
// http://w3c.github.io/editing/input-events.html#dom-inputevent-inputtype
InputEvent* const input_event =
InputEvent::CreateInput(input_type, data, is_composing, nullptr);
- target->DispatchScopedEvent(input_event);
+ target->DispatchScopedEvent(*input_event);
}
void DispatchInputEventEditableContentChanged(
@@ -615,11 +617,8 @@ void DispatchInputEventEditableContentChanged(
SelectionInDOMTree CorrectedSelectionAfterCommand(
const SelectionForUndoStep& passed_selection,
const Document* document) {
- if (!passed_selection.Base().IsConnected() ||
- !passed_selection.Extent().IsConnected() ||
- passed_selection.Base().GetDocument() != document ||
- passed_selection.Base().GetDocument() !=
- passed_selection.Extent().GetDocument())
+ if (!passed_selection.Base().IsValidFor(*document) ||
+ !passed_selection.Extent().IsValidFor(*document))
return SelectionInDOMTree();
return passed_selection.AsSelection();
}
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 51df2dab237..9411126f9a8 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
@@ -64,9 +64,9 @@
#include "third_party/blink/renderer/core/input/event_handler.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/scrollbar.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/histogram.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
#include <iterator>
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 890caebb750..b36ae21d721 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
@@ -17,11 +17,11 @@ TEST_F(InsertIncrementalTextCommandTest, SurrogatePairsReplace) {
SetBodyContent("<div id=sample contenteditable><a>a</a>b&#x1F63A;</div>");
Element* const sample = GetDocument().getElementById("sample");
const String new_text(Vector<UChar>{0xD83D, 0xDE38}); // U+1F638
- Selection().SetSelectionAndEndTyping(
- SelectionInDOMTree::Builder()
- .Collapse(Position(sample->lastChild(), 1))
- .Extend(Position(sample->lastChild(), 3))
- .Build());
+ Selection().SetSelection(SelectionInDOMTree::Builder()
+ .Collapse(Position(sample->lastChild(), 1))
+ .Extend(Position(sample->lastChild(), 3))
+ .Build(),
+ SetSelectionOptions());
CompositeEditCommand* const command =
InsertIncrementalTextCommand::Create(GetDocument(), new_text);
command->Apply();
@@ -35,11 +35,11 @@ TEST_F(InsertIncrementalTextCommandTest, SurrogatePairsNoReplace) {
SetBodyContent("<div id=sample contenteditable><a>a</a>b&#x1F63A;</div>");
Element* const sample = GetDocument().getElementById("sample");
const String new_text(Vector<UChar>{0xD83D, 0xDE3A}); // U+1F63A
- Selection().SetSelectionAndEndTyping(
- SelectionInDOMTree::Builder()
- .Collapse(Position(sample->lastChild(), 1))
- .Extend(Position(sample->lastChild(), 3))
- .Build());
+ Selection().SetSelection(SelectionInDOMTree::Builder()
+ .Collapse(Position(sample->lastChild(), 1))
+ .Extend(Position(sample->lastChild(), 3))
+ .Build(),
+ SetSelectionOptions());
CompositeEditCommand* const command =
InsertIncrementalTextCommand::Create(GetDocument(), new_text);
command->Apply();
@@ -55,11 +55,11 @@ TEST_F(InsertIncrementalTextCommandTest, SurrogatePairsTwo) {
"<div id=sample contenteditable><a>a</a>b&#x1F63A;&#x1F63A;</div>");
Element* const sample = GetDocument().getElementById("sample");
const String new_text(Vector<UChar>{0xD83D, 0xDE38}); // U+1F638
- Selection().SetSelectionAndEndTyping(
- SelectionInDOMTree::Builder()
- .Collapse(Position(sample->lastChild(), 1))
- .Extend(Position(sample->lastChild(), 5))
- .Build());
+ Selection().SetSelection(SelectionInDOMTree::Builder()
+ .Collapse(Position(sample->lastChild(), 1))
+ .Extend(Position(sample->lastChild(), 5))
+ .Build(),
+ SetSelectionOptions());
CompositeEditCommand* const command =
InsertIncrementalTextCommand::Create(GetDocument(), new_text);
command->Apply();
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 66f7fb68e3a..e7a61e4a5dd 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
@@ -36,11 +36,12 @@ TEST_F(InsertListCommandTest, ShouldCleanlyRemoveSpuriousTextNode) {
GetDocument().body()->InsertBefore(empty_text,
GetDocument().body()->firstChild());
UpdateAllLifecyclePhases();
- GetDocument().GetFrame()->Selection().SetSelectionAndEndTyping(
+ GetDocument().GetFrame()->Selection().SetSelection(
SelectionInDOMTree::Builder()
.Collapse(Position(GetDocument().body(), 0))
.Extend(Position(GetDocument().body(), 2))
- .Build());
+ .Build(),
+ SetSelectionOptions());
InsertListCommand* command =
InsertListCommand::Create(GetDocument(), InsertListCommand::kOrderedList);
@@ -53,10 +54,11 @@ TEST_F(InsertListCommandTest, ShouldCleanlyRemoveSpuriousTextNode) {
// Refer https://crbug.com/794356
TEST_F(InsertListCommandTest, UnlistifyParagraphCrashOnVisuallyEmptyParagraph) {
GetDocument().setDesignMode("on");
- Selection().SetSelectionAndEndTyping(
+ Selection().SetSelection(
SetSelectionTextToBody("^<dl>"
"<textarea style='float:left;'></textarea>"
- "</dl>|"));
+ "</dl>|"),
+ SetSelectionOptions());
InsertListCommand* command = InsertListCommand::Create(
GetDocument(), InsertListCommand::kUnorderedList);
// Crash happens here.
@@ -75,9 +77,9 @@ TEST_F(InsertListCommandTest, CleanupNodeSameAsDestinationNode) {
"* { -webkit-appearance:checkbox; }"
"br { visibility:hidden; }"
"colgroup { -webkit-column-count:2; }");
- Selection().SetSelectionAndEndTyping(
- SetSelectionTextToBody("^<table><col></table>"
- "<button></button>|"));
+ Selection().SetSelection(SetSelectionTextToBody("^<table><col></table>"
+ "<button></button>|"),
+ SetSelectionOptions());
InsertListCommand* command = InsertListCommand::Create(
GetDocument(), InsertListCommand::kUnorderedList);
@@ -97,8 +99,8 @@ TEST_F(InsertListCommandTest, CleanupNodeSameAsDestinationNode) {
TEST_F(InsertListCommandTest, InsertListOnEmptyHiddenElements) {
GetDocument().setDesignMode("on");
InsertStyleElement("br { visibility:hidden; }");
- Selection().SetSelectionAndEndTyping(
- SetSelectionTextToBody("^<button></button>|"));
+ Selection().SetSelection(SetSelectionTextToBody("^<button></button>|"),
+ SetSelectionOptions());
InsertListCommand* command = InsertListCommand::Create(
GetDocument(), InsertListCommand::kUnorderedList);
@@ -118,7 +120,8 @@ TEST_F(InsertListCommandTest, InsertListWithCollapsedVisibility) {
"ul { visibility:collapse; }"
"dl { visibility:visible; }");
- Selection().SetSelectionAndEndTyping(SetSelectionTextToBody("^<dl>a</dl>|"));
+ Selection().SetSelection(SetSelectionTextToBody("^<dl>a</dl>|"),
+ SetSelectionOptions());
InsertListCommand* command =
InsertListCommand::Create(GetDocument(), InsertListCommand::kOrderedList);
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 fab7d125fbc..14e4e6fa77f 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
@@ -17,10 +17,12 @@ class InsertParagraphSeparatorCommandTest : public EditingTestBase {};
// http://crbug.com/777378
TEST_F(InsertParagraphSeparatorCommandTest,
CrashWithAppearanceStyleOnEmptyColgroup) {
- Selection().SetSelectionAndEndTyping(SetSelectionTextToBody(
- "<table contenteditable>"
- " <colgroup style='-webkit-appearance:radio;'><!--|--></colgroup>"
- "</table>"));
+ Selection().SetSelection(
+ SetSelectionTextToBody(
+ "<table contenteditable>"
+ " <colgroup style='-webkit-appearance:radio;'><!--|--></colgroup>"
+ "</table>"),
+ SetSelectionOptions());
InsertParagraphSeparatorCommand* command =
InsertParagraphSeparatorCommand::Create(GetDocument());
@@ -37,12 +39,13 @@ TEST_F(InsertParagraphSeparatorCommandTest,
// http://crbug.com/777378
TEST_F(InsertParagraphSeparatorCommandTest,
CrashWithAppearanceStyleOnEmptyColumn) {
- Selection().SetSelectionAndEndTyping(
+ Selection().SetSelection(
SetSelectionTextToBody("<table contenteditable>"
" <colgroup style='-webkit-appearance:radio;'>"
" <col><!--|--></col>"
" </colgroup>"
- "</table>"));
+ "</table>"),
+ SetSelectionOptions());
InsertParagraphSeparatorCommand* command =
InsertParagraphSeparatorCommand::Create(GetDocument());
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 0b712abc381..abfe0844040 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
@@ -17,8 +17,9 @@ class InsertTextCommandTest : public EditingTestBase {};
TEST_F(InsertTextCommandTest, WithTypingStyle) {
SetBodyContent("<div contenteditable=true><option id=sample></option></div>");
Element* const sample = GetDocument().getElementById("sample");
- Selection().SetSelectionAndEndTyping(
- SelectionInDOMTree::Builder().Collapse(Position(sample, 0)).Build());
+ Selection().SetSelection(
+ SelectionInDOMTree::Builder().Collapse(Position(sample, 0)).Build(),
+ SetSelectionOptions());
// Register typing style to make |InsertTextCommand| to attempt to apply
// style to inserted text.
GetDocument().execCommand("fontSizeDelta", false, "+3", ASSERT_NO_EXCEPTION);
@@ -35,8 +36,9 @@ TEST_F(InsertTextCommandTest, WithTypingStyle) {
// http://crbug.com/741826
TEST_F(InsertTextCommandTest, InsertChar) {
- Selection().SetSelectionAndEndTyping(
- SetSelectionTextToBody("<p contenteditable><span>\ta|c</span></p>"));
+ Selection().SetSelection(
+ SetSelectionTextToBody("<p contenteditable><span>\ta|c</span></p>"),
+ SetSelectionOptions());
GetDocument().execCommand("insertText", false, "B", ASSERT_NO_EXCEPTION);
EXPECT_EQ("<p contenteditable><span>\taB|c</span></p>",
GetSelectionTextFromBody())
@@ -45,8 +47,10 @@ TEST_F(InsertTextCommandTest, InsertChar) {
// http://crbug.com/741826
TEST_F(InsertTextCommandTest, InsertCharToWhiteSpacePre) {
- Selection().SetSelectionAndEndTyping(SetSelectionTextToBody(
- "<p contenteditable><span style='white-space:pre'>\ta|c</span></p>"));
+ Selection().SetSelection(
+ SetSelectionTextToBody(
+ "<p contenteditable><span style='white-space:pre'>\ta|c</span></p>"),
+ SetSelectionOptions());
GetDocument().execCommand("insertText", false, "B", ASSERT_NO_EXCEPTION);
EXPECT_EQ(
"<p contenteditable>"
@@ -60,8 +64,9 @@ TEST_F(InsertTextCommandTest, InsertCharToWhiteSpacePre) {
// http://crbug.com/741826
TEST_F(InsertTextCommandTest, InsertSpace) {
- Selection().SetSelectionAndEndTyping(
- SetSelectionTextToBody("<p contenteditable><span>\ta|c</span></p>"));
+ Selection().SetSelection(
+ SetSelectionTextToBody("<p contenteditable><span>\ta|c</span></p>"),
+ SetSelectionOptions());
GetDocument().execCommand("insertText", false, " ", ASSERT_NO_EXCEPTION);
EXPECT_EQ("<p contenteditable><span>\ta\xC2\xA0 |c</span></p>",
GetSelectionTextFromBody())
@@ -70,8 +75,10 @@ TEST_F(InsertTextCommandTest, InsertSpace) {
// http://crbug.com/741826
TEST_F(InsertTextCommandTest, InsertSpaceToWhiteSpacePre) {
- Selection().SetSelectionAndEndTyping(SetSelectionTextToBody(
- "<p contenteditable><span style='white-space:pre'>\ta|c</span></p>"));
+ Selection().SetSelection(
+ SetSelectionTextToBody(
+ "<p contenteditable><span style='white-space:pre'>\ta|c</span></p>"),
+ SetSelectionOptions());
GetDocument().execCommand("insertText", false, " ", ASSERT_NO_EXCEPTION);
EXPECT_EQ(
"<p contenteditable>"
@@ -84,8 +91,9 @@ TEST_F(InsertTextCommandTest, InsertSpaceToWhiteSpacePre) {
// http://crbug.com/741826
TEST_F(InsertTextCommandTest, InsertTab) {
- Selection().SetSelectionAndEndTyping(
- SetSelectionTextToBody("<p contenteditable><span>\ta|c</span></p>"));
+ Selection().SetSelection(
+ SetSelectionTextToBody("<p contenteditable><span>\ta|c</span></p>"),
+ SetSelectionOptions());
GetDocument().execCommand("insertText", false, "\t", ASSERT_NO_EXCEPTION);
EXPECT_EQ(
"<p contenteditable>"
@@ -96,8 +104,10 @@ TEST_F(InsertTextCommandTest, InsertTab) {
// http://crbug.com/741826
TEST_F(InsertTextCommandTest, InsertTabToWhiteSpacePre) {
- Selection().SetSelectionAndEndTyping(SetSelectionTextToBody(
- "<p contenteditable><span style='white-space:pre'>\ta|c</span></p>"));
+ Selection().SetSelection(
+ SetSelectionTextToBody(
+ "<p contenteditable><span style='white-space:pre'>\ta|c</span></p>"),
+ SetSelectionOptions());
GetDocument().execCommand("insertText", false, "\t", ASSERT_NO_EXCEPTION);
EXPECT_EQ(
"<p contenteditable><span style=\"white-space:pre\">\ta\t|c</span></p>",
@@ -106,40 +116,45 @@ TEST_F(InsertTextCommandTest, InsertTabToWhiteSpacePre) {
// http://crbug.com/752860
TEST_F(InsertTextCommandTest, WhitespaceFixupBeforeParagraph) {
- Selection().SetSelectionAndEndTyping(
- SetSelectionTextToBody("<div contenteditable>qux ^bar|<p>baz</p>"));
+ Selection().SetSelection(
+ SetSelectionTextToBody("<div contenteditable>qux ^bar|<p>baz</p>"),
+ SetSelectionOptions());
GetDocument().execCommand("insertText", false, "", ASSERT_NO_EXCEPTION);
// The space after "qux" should have been converted to a no-break space
// (U+00A0) to prevent it from being collapsed.
EXPECT_EQ("<div contenteditable>qux\xC2\xA0|<p>baz</p></div>",
GetSelectionTextFromBody());
- Selection().SetSelectionAndEndTyping(
- SetSelectionTextToBody("<div contenteditable>qux^ bar|<p>baz</p>"));
+ Selection().SetSelection(
+ SetSelectionTextToBody("<div contenteditable>qux^ bar|<p>baz</p>"),
+ SetSelectionOptions());
GetDocument().execCommand("insertText", false, " ", ASSERT_NO_EXCEPTION);
// The newly-inserted space should have been converted to a no-break space
// (U+00A0) to prevent it from being collapsed.
EXPECT_EQ("<div contenteditable>qux\xC2\xA0|<p>baz</p></div>",
GetSelectionTextFromBody());
- Selection().SetSelectionAndEndTyping(
- SetSelectionTextToBody("<div contenteditable>qux^bar| <p>baz</p>"));
+ Selection().SetSelection(
+ SetSelectionTextToBody("<div contenteditable>qux^bar| <p>baz</p>"),
+ SetSelectionOptions());
GetDocument().execCommand("insertText", false, "", ASSERT_NO_EXCEPTION);
// The space after "bar" was already being collapsed before the edit. It
// should not have been converted to a no-break space.
EXPECT_EQ("<div contenteditable>qux|<p>baz</p></div>",
GetSelectionTextFromBody());
- Selection().SetSelectionAndEndTyping(
- SetSelectionTextToBody("<div contenteditable>qux^bar |<p>baz</p>"));
+ Selection().SetSelection(
+ SetSelectionTextToBody("<div contenteditable>qux^bar |<p>baz</p>"),
+ SetSelectionOptions());
GetDocument().execCommand("insertText", false, " ", ASSERT_NO_EXCEPTION);
// The newly-inserted space should have been converted to a no-break space
// (U+00A0) to prevent it from being collapsed.
EXPECT_EQ("<div contenteditable>qux\xC2\xA0|<p>baz</p></div>",
GetSelectionTextFromBody());
- Selection().SetSelectionAndEndTyping(
- SetSelectionTextToBody("<div contenteditable>qux\t^bar|<p>baz</p>"));
+ Selection().SetSelection(
+ SetSelectionTextToBody("<div contenteditable>qux\t^bar|<p>baz</p>"),
+ SetSelectionOptions());
GetDocument().execCommand("insertText", false, "", ASSERT_NO_EXCEPTION);
// The tab should have been converted to a no-break space (U+00A0) to prevent
// it from being collapsed.
@@ -148,40 +163,45 @@ TEST_F(InsertTextCommandTest, WhitespaceFixupBeforeParagraph) {
}
TEST_F(InsertTextCommandTest, WhitespaceFixupAfterParagraph) {
- Selection().SetSelectionAndEndTyping(
- SetSelectionTextToBody("<div contenteditable><p>baz</p>^bar| qux"));
+ Selection().SetSelection(
+ SetSelectionTextToBody("<div contenteditable><p>baz</p>^bar| qux"),
+ SetSelectionOptions());
GetDocument().execCommand("insertText", false, "", ASSERT_NO_EXCEPTION);
// The space before "qux" should have been converted to a no-break space
// (U+00A0) to prevent it from being collapsed.
EXPECT_EQ("<div contenteditable><p>baz</p>|\xC2\xA0qux</div>",
GetSelectionTextFromBody());
- Selection().SetSelectionAndEndTyping(
- SetSelectionTextToBody("<div contenteditable><p>baz</p>^bar |qux"));
+ Selection().SetSelection(
+ SetSelectionTextToBody("<div contenteditable><p>baz</p>^bar |qux"),
+ SetSelectionOptions());
GetDocument().execCommand("insertText", false, " ", ASSERT_NO_EXCEPTION);
// The newly-inserted space should have been converted to a no-break space
// (U+00A0) to prevent it from being collapsed.
EXPECT_EQ("<div contenteditable><p>baz</p>\xC2\xA0|qux</div>",
GetSelectionTextFromBody());
- Selection().SetSelectionAndEndTyping(
- SetSelectionTextToBody("<div contenteditable><p>baz</p> ^bar|qux"));
+ Selection().SetSelection(
+ SetSelectionTextToBody("<div contenteditable><p>baz</p> ^bar|qux"),
+ SetSelectionOptions());
GetDocument().execCommand("insertText", false, "", ASSERT_NO_EXCEPTION);
// The space before "bar" was already being collapsed before the edit. It
// should not have been converted to a no-break space.
EXPECT_EQ("<div contenteditable><p>baz</p>|qux</div>",
GetSelectionTextFromBody());
- Selection().SetSelectionAndEndTyping(
- SetSelectionTextToBody("<div contenteditable><p>baz</p>^ bar|qux"));
+ Selection().SetSelection(
+ SetSelectionTextToBody("<div contenteditable><p>baz</p>^ bar|qux"),
+ SetSelectionOptions());
GetDocument().execCommand("insertText", false, " ", ASSERT_NO_EXCEPTION);
// The newly-inserted space should have been converted to a no-break space
// (U+00A0) to prevent it from being collapsed.
EXPECT_EQ("<div contenteditable><p>baz</p>\xC2\xA0|qux</div>",
GetSelectionTextFromBody());
- Selection().SetSelectionAndEndTyping(
- SetSelectionTextToBody("<div contenteditable><p>baz</p>^bar|\tqux"));
+ Selection().SetSelection(
+ SetSelectionTextToBody("<div contenteditable><p>baz</p>^bar|\tqux"),
+ SetSelectionOptions());
GetDocument().execCommand("insertText", false, "", ASSERT_NO_EXCEPTION);
// The tab should have been converted to a no-break space (U+00A0) to prevent
// it from being collapsed.
@@ -195,14 +215,15 @@ TEST_F(InsertTextCommandTest, NoVisibleSelectionAfterDeletingSelection) {
InsertStyleElement(
"ruby {display: inline-block; height: 100%}"
"navi {float: left}");
- Selection().SetSelectionAndEndTyping(
+ Selection().SetSelection(
SetSelectionTextToBody("<div contenteditable>"
" <ruby><strike>"
" <navi></navi>"
" <rtc>^&#xbbc3;&#xff17;&#x8e99;&#x1550;</rtc>"
" </strike></ruby>"
" <hr>|"
- "</div>"));
+ "</div>"),
+ SetSelectionOptions());
// Shouldn't crash inside
GetDocument().execCommand("insertText", false, "x", ASSERT_NO_EXCEPTION);
// This is only for recording the current behavior, which can be changed.
@@ -225,10 +246,11 @@ TEST_F(InsertTextCommandTest, CheckTabSpanElementNoCrash) {
body->parentNode()->appendChild(style);
GetDocument().setDesignMode("on");
- Selection().SetSelectionAndEndTyping(SelectionInDOMTree::Builder()
- .Collapse(Position(head, 0))
- .Extend(Position(body, 0))
- .Build());
+ Selection().SetSelection(SelectionInDOMTree::Builder()
+ .Collapse(Position(head, 0))
+ .Extend(Position(body, 0))
+ .Build(),
+ SetSelectionOptions());
// Shouldn't crash inside
GetDocument().execCommand("insertText", false, "\t", ASSERT_NO_EXCEPTION);
@@ -266,11 +288,12 @@ TEST_F(InsertTextCommandTest, AnchorElementWithBlockCrash) {
nested_anchor->AppendChild(iElement);
Node* const iElement_text_node = iElement->firstChild();
- Selection().SetSelectionAndEndTyping(
+ Selection().SetSelection(
SelectionInDOMTree::Builder()
.SetBaseAndExtent(Position(iElement_text_node, 0),
Position(iElement_text_node, 4))
- .Build());
+ .Build(),
+ SetSelectionOptions());
// Crash happens here with when '\n' is inserted.
GetDocument().execCommand("inserttext", false, "a\n", ASSERT_NO_EXCEPTION);
EXPECT_EQ(
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 01dbd04fe66..c9c11f8f260 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/renderer/core/editing/editing_behavior.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/frame_selection.h"
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 2832a98013d..6feb4955d17 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
@@ -212,7 +212,7 @@ ReplacementFragment::ReplacementFragment(Document* document,
String original_text = fragment_->textContent();
BeforeTextInsertedEvent* event =
BeforeTextInsertedEvent::Create(original_text);
- editable_root->DispatchEvent(event);
+ editable_root->DispatchEvent(*event);
if (original_text != event->GetText()) {
fragment_ = CreateFragmentFromText(
selection.ToNormalizedEphemeralRange(), event->GetText());
@@ -244,7 +244,7 @@ ReplacementFragment::ReplacementFragment(Document* document,
// Give the root a chance to change the text.
BeforeTextInsertedEvent* evt = BeforeTextInsertedEvent::Create(text);
- editable_root->DispatchEvent(evt);
+ editable_root->DispatchEvent(*evt);
if (text != evt->GetText() || !HasRichlyEditableStyle(*editable_root)) {
RestoreAndRemoveTestRenderingNodesToFragment(holder);
@@ -1788,7 +1788,13 @@ void ReplaceSelectionCommand::CompleteHTMLReplacement(
if (match_style_) {
DCHECK(insertion_style_);
+ // Since |ApplyStyle()| changes contents of anchor node of |start| and
+ // |end|, we should relocate them.
+ Range* const range = Range::Create(GetDocument(), start, end);
ApplyStyle(insertion_style_.Get(), start, end, editing_state);
+ start = range->StartPosition();
+ end = range->EndPosition();
+ range->Dispose();
if (editing_state->IsAborted())
return;
}
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 73bb44c8b50..7a716b1ecd5 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
@@ -33,10 +33,11 @@ TEST_F(ReplaceSelectionCommandTest, pastingEmptySpan) {
SetBodyContent("foo");
LocalFrame* frame = GetDocument().GetFrame();
- frame->Selection().SetSelectionAndEndTyping(
+ frame->Selection().SetSelection(
SelectionInDOMTree::Builder()
.Collapse(Position(GetDocument().body(), 0))
- .Build());
+ .Build(),
+ SetSelectionOptions());
DocumentFragment* fragment = GetDocument().createDocumentFragment();
fragment->AppendChild(GetDocument().CreateRawElement(HTMLNames::spanTag));
@@ -64,10 +65,11 @@ TEST_F(ReplaceSelectionCommandTest, pasteSpanInText) {
Element* b_element = GetDocument().QuerySelector("b");
LocalFrame* frame = GetDocument().GetFrame();
- frame->Selection().SetSelectionAndEndTyping(
+ frame->Selection().SetSelection(
SelectionInDOMTree::Builder()
.Collapse(Position(b_element->firstChild(), 1))
- .Build());
+ .Build(),
+ SetSelectionOptions());
DocumentFragment* fragment = GetDocument().createDocumentFragment();
fragment->ParseHTML("<span><div>bar</div></span>", b_element);
@@ -85,10 +87,11 @@ TEST_F(ReplaceSelectionCommandTest, pasteSpanInText) {
TEST_F(ReplaceSelectionCommandTest, styleTagsInPastedHeadIncludedInContent) {
GetDocument().setDesignMode("on");
UpdateAllLifecyclePhases();
- GetDummyPageHolder().GetFrame().Selection().SetSelectionAndEndTyping(
+ GetDummyPageHolder().GetFrame().Selection().SetSelection(
SelectionInDOMTree::Builder()
.Collapse(Position(GetDocument().body(), 0))
- .Build());
+ .Build(),
+ SetSelectionOptions());
DocumentFragment* fragment = GetDocument().createDocumentFragment();
fragment->ParseHTML(
@@ -137,11 +140,12 @@ TEST_F(ReplaceSelectionCommandTest, TextAutosizingDoesntInflateText) {
Element* span = GetDocument().QuerySelector("span");
// Select "bar".
- GetDocument().GetFrame()->Selection().SetSelectionAndEndTyping(
+ GetDocument().GetFrame()->Selection().SetSelection(
SelectionInDOMTree::Builder()
.Collapse(Position(span->firstChild(), 4))
.Extend(Position(span->firstChild(), 7))
- .Build());
+ .Build(),
+ SetSelectionOptions());
DocumentFragment* fragment = GetDocument().createDocumentFragment();
fragment->ParseHTML("baz", span);
@@ -160,8 +164,8 @@ TEST_F(ReplaceSelectionCommandTest, TextAutosizingDoesntInflateText) {
// This is a regression test for https://crbug.com/781282
TEST_F(ReplaceSelectionCommandTest, TrailingNonVisibleTextCrash) {
GetDocument().setDesignMode("on");
- Selection().SetSelectionAndEndTyping(
- SetSelectionTextToBody("<div>^foo|</div>"));
+ Selection().SetSelection(SetSelectionTextToBody("<div>^foo|</div>"),
+ SetSelectionOptions());
DocumentFragment* fragment = GetDocument().createDocumentFragment();
fragment->ParseHTML("<div>bar</div> ", GetDocument().QuerySelector("div"));
@@ -187,4 +191,27 @@ TEST_F(ReplaceSelectionCommandTest, CrashWithNoSelection) {
EXPECT_EQ("<div></div>", GetSelectionTextFromBody());
}
+// http://crbug.com/877127
+TEST_F(ReplaceSelectionCommandTest, SmartPlainTextPaste) {
+ // After typing "abc", Enter, "def".
+ Selection().SetSelection(
+ SetSelectionTextToBody("<div contenteditable>abc<div>def</div>|</div>"),
+ SetSelectionOptions());
+ DocumentFragment& fragment = *GetDocument().createDocumentFragment();
+ fragment.appendChild(Text::Create(GetDocument(), "XYZ"));
+ const ReplaceSelectionCommand::CommandOptions options =
+ ReplaceSelectionCommand::kPreventNesting |
+ ReplaceSelectionCommand::kSanitizeFragment |
+ ReplaceSelectionCommand::kMatchStyle |
+ ReplaceSelectionCommand::kSmartReplace;
+ ReplaceSelectionCommand& command =
+ *ReplaceSelectionCommand::Create(GetDocument(), &fragment, options,
+ InputEvent::InputType::kInsertFromPaste);
+
+ EXPECT_TRUE(command.Apply());
+ // Smart paste inserts a space before pasted text.
+ EXPECT_EQ(u8"<div contenteditable>abc<div>def XYZ|</div></div>",
+ GetSelectionTextFromBody());
+}
+
} // namespace blink
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 a4c4c14bed2..75e449b945f 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
@@ -58,7 +58,7 @@ void SplitTextNodeCommand::DoApply(EditingState*) {
text1_ = Text::Create(GetDocument(), prefix_text);
DCHECK(text1_);
- GetDocument().Markers().MoveMarkers(text2_.Get(), offset_, text1_.Get());
+ GetDocument().Markers().MoveMarkers(*text2_, offset_, *text1_);
InsertText1AndTrimText2();
}
@@ -74,8 +74,7 @@ void SplitTextNodeCommand::DoUnapply() {
text2_->insertData(0, prefix_text, ASSERT_NO_EXCEPTION);
GetDocument().UpdateStyleAndLayout();
- GetDocument().Markers().MoveMarkers(text1_.Get(), prefix_text.length(),
- text2_.Get());
+ GetDocument().Markers().MoveMarkers(*text1_, prefix_text.length(), *text2_);
text1_->remove(ASSERT_NO_EXCEPTION);
}
@@ -87,7 +86,7 @@ void SplitTextNodeCommand::DoReapply() {
if (!parent || !HasEditableStyle(*parent))
return;
- GetDocument().Markers().MoveMarkers(text2_.Get(), offset_, text1_.Get());
+ GetDocument().Markers().MoveMarkers(*text2_, offset_, *text1_);
InsertText1AndTrimText2();
}
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/split_text_node_command_test.cc b/chromium/third_party/blink/renderer/core/editing/commands/split_text_node_command_test.cc
index c3b9f0d28ea..25872e4b33c 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/split_text_node_command_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/split_text_node_command_test.cc
@@ -37,8 +37,8 @@ TEST_F(SplitTextNodeCommandTest, splitInMarkerInterior) {
EditingState editingState;
command->DoApply(&editingState);
- Node* text1 = ToText(div->firstChild());
- Node* text2 = ToText(text1->nextSibling());
+ const Text& text1 = ToText(*div->firstChild());
+ const Text& text2 = ToText(*text1.nextSibling());
// The first marker should end up in text1, the second marker should be
// truncated and end up text1, the third marker should end up in text2
@@ -60,7 +60,7 @@ TEST_F(SplitTextNodeCommandTest, splitInMarkerInterior) {
// Test undo
command->DoUnapply();
- Node* text = ToText(div->firstChild());
+ const Text& text = ToText(*div->firstChild());
EXPECT_EQ(3u, GetDocument().Markers().MarkersFor(text).size());
@@ -78,21 +78,21 @@ TEST_F(SplitTextNodeCommandTest, splitInMarkerInterior) {
// Test redo
command->DoReapply();
- text1 = ToText(div->firstChild());
- text2 = ToText(text1->nextSibling());
+ const Text& text3 = ToText(*div->firstChild());
+ const Text& text4 = ToText(*text3.nextSibling());
- EXPECT_EQ(2u, GetDocument().Markers().MarkersFor(text1).size());
+ EXPECT_EQ(2u, GetDocument().Markers().MarkersFor(text3).size());
- EXPECT_EQ(0u, GetDocument().Markers().MarkersFor(text1)[0]->StartOffset());
- EXPECT_EQ(5u, GetDocument().Markers().MarkersFor(text1)[0]->EndOffset());
+ EXPECT_EQ(0u, GetDocument().Markers().MarkersFor(text3)[0]->StartOffset());
+ EXPECT_EQ(5u, GetDocument().Markers().MarkersFor(text3)[0]->EndOffset());
- EXPECT_EQ(6u, GetDocument().Markers().MarkersFor(text1)[1]->StartOffset());
- EXPECT_EQ(7u, GetDocument().Markers().MarkersFor(text1)[1]->EndOffset());
+ EXPECT_EQ(6u, GetDocument().Markers().MarkersFor(text3)[1]->StartOffset());
+ EXPECT_EQ(7u, GetDocument().Markers().MarkersFor(text3)[1]->EndOffset());
- EXPECT_EQ(1u, GetDocument().Markers().MarkersFor(text2).size());
+ EXPECT_EQ(1u, GetDocument().Markers().MarkersFor(text4).size());
- EXPECT_EQ(4u, GetDocument().Markers().MarkersFor(text2)[0]->StartOffset());
- EXPECT_EQ(9u, GetDocument().Markers().MarkersFor(text2)[0]->EndOffset());
+ EXPECT_EQ(4u, GetDocument().Markers().MarkersFor(text4)[0]->StartOffset());
+ EXPECT_EQ(9u, GetDocument().Markers().MarkersFor(text4)[0]->EndOffset());
}
} // namespace blink
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 54be08d2d4d..2c2786203f0 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
@@ -36,6 +36,7 @@
#include "third_party/blink/renderer/core/css/css_property_value_set.h"
#include "third_party/blink/renderer/core/css/css_value_list.h"
#include "third_party/blink/renderer/core/editing/commands/apply_style_command.h"
+#include "third_party/blink/renderer/core/editing/editing_behavior.h"
#include "third_party/blink/renderer/core/editing/editing_style_utilities.h"
#include "third_party/blink/renderer/core/editing/editing_tri_state.h"
#include "third_party/blink/renderer/core/editing/editing_utilities.h"
@@ -44,6 +45,7 @@
#include "third_party/blink/renderer/core/editing/frame_selection.h"
#include "third_party/blink/renderer/core/editing/visible_position.h"
#include "third_party/blink/renderer/core/editing/writing_direction.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/html/html_font_element.h"
namespace blink {
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 302caa960bd..39d4fbb8335 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
@@ -37,6 +37,7 @@
#include "third_party/blink/renderer/core/editing/commands/insert_line_break_command.h"
#include "third_party/blink/renderer/core/editing/commands/insert_paragraph_separator_command.h"
#include "third_party/blink/renderer/core/editing/commands/insert_text_command.h"
+#include "third_party/blink/renderer/core/editing/editing_behavior.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"
@@ -49,6 +50,7 @@
#include "third_party/blink/renderer/core/editing/visible_units.h"
#include "third_party/blink/renderer/core/events/before_text_inserted_event.h"
#include "third_party/blink/renderer/core/events/text_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/html_br_element.h"
#include "third_party/blink/renderer/core/html_names.h"
@@ -73,7 +75,7 @@ String DispatchBeforeTextInsertedEvent(const String& text,
// necessary.
const Document& document = start_node->GetDocument();
BeforeTextInsertedEvent* evt = BeforeTextInsertedEvent::Create(text);
- RootEditableElement(*start_node)->DispatchEvent(evt);
+ RootEditableElement(*start_node)->DispatchEvent(*evt);
if (IsValidDocument(document) && selection.IsValidFor(document))
return evt->GetText();
// editing/inserting/webkitBeforeTextInserted-removes-frame.html
@@ -97,7 +99,7 @@ DispatchEventResult DispatchTextInputEvent(LocalFrame* frame,
TextEvent* event = TextEvent::Create(frame->DomWindow(), text,
kTextEventInputIncrementalInsertion);
event->SetUnderlyingEvent(nullptr);
- DispatchEventResult result = target->DispatchEvent(event);
+ DispatchEventResult result = target->DispatchEvent(*event);
if (IsValidDocument(document))
return result;
// editing/inserting/insert-text-remove-iframe-on-textInput-event.html
@@ -146,7 +148,7 @@ bool CanAppendNewLineFeedToSelection(const VisibleSelection& selection,
const Document& document = element->GetDocument();
BeforeTextInsertedEvent* event =
BeforeTextInsertedEvent::Create(String("\n"));
- element->DispatchEvent(event);
+ element->DispatchEvent(*event);
// event may invalidate frame or selection
if (IsValidDocument(document) && selection.IsValidFor(document))
return event->GetText().length();
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/typing_command_test.cc b/chromium/third_party/blink/renderer/core/editing/commands/typing_command_test.cc
index a684a21d29b..a020f988eae 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/typing_command_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/typing_command_test.cc
@@ -45,10 +45,11 @@ TEST_F(TypingCommandTest, insertLineBreakWithIllFormedHTML) {
div->AppendChild(tr);
LocalFrame* frame = GetDocument().GetFrame();
- frame->Selection().SetSelectionAndEndTyping(SelectionInDOMTree::Builder()
- .Collapse(Position(form, 0))
- .Extend(Position(header, 0))
- .Build());
+ frame->Selection().SetSelection(SelectionInDOMTree::Builder()
+ .Collapse(Position(form, 0))
+ .Extend(Position(header, 0))
+ .Build(),
+ SetSelectionOptions());
// Inserting line break should not crash or hit assertion.
TypingCommand::InsertLineBreak(GetDocument());
@@ -57,8 +58,9 @@ TEST_F(TypingCommandTest, insertLineBreakWithIllFormedHTML) {
// http://crbug.com/767599
TEST_F(TypingCommandTest,
DontCrashWhenReplaceSelectionCommandLeavesBadSelection) {
- Selection().SetSelectionAndEndTyping(
- SetSelectionTextToBody("<div contenteditable>^<h1>H1</h1>ello|</div>"));
+ Selection().SetSelection(
+ SetSelectionTextToBody("<div contenteditable>^<h1>H1</h1>ello|</div>"),
+ SetSelectionOptions());
// This call shouldn't crash.
TypingCommand::InsertText(
@@ -71,13 +73,15 @@ TEST_F(TypingCommandTest,
// crbug.com/794397
TEST_F(TypingCommandTest, ForwardDeleteInvalidatesSelection) {
GetDocument().setDesignMode("on");
- Selection().SetSelectionAndEndTyping(SetSelectionTextToBody(
- "<blockquote>^"
- "<q>"
- "<table contenteditable=\"false\"><colgroup width=\"-1\">\n</table>|"
- "</q>"
- "</blockquote>"
- "<q>\n<svg></svg></q>"));
+ Selection().SetSelection(
+ SetSelectionTextToBody(
+ "<blockquote>^"
+ "<q>"
+ "<table contenteditable=\"false\"><colgroup width=\"-1\">\n</table>|"
+ "</q>"
+ "</blockquote>"
+ "<q>\n<svg></svg></q>"),
+ SetSelectionOptions());
EditingState editing_state;
TypingCommand::ForwardDeleteKeyPressed(GetDocument(), &editing_state);
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 1a3613e23ea..a848cdb537a 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
@@ -12,6 +12,7 @@
#include "third_party/blink/renderer/core/editing/editor.h"
#include "third_party/blink/renderer/core/editing/selection_template.h"
#include "third_party/blink/renderer/core/editing/set_selection_options.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/core/editing/rendered_position.cc b/chromium/third_party/blink/renderer/core/editing/compute_layer_selection.cc
index c31eb28a12b..4f69de9c64b 100644
--- a/chromium/third_party/blink/renderer/core/editing/rendered_position.cc
+++ b/chromium/third_party/blink/renderer/core/editing/compute_layer_selection.cc
@@ -28,8 +28,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "third_party/blink/renderer/core/editing/rendered_position.h"
+#include "third_party/blink/renderer/core/editing/compute_layer_selection.h"
+#include "cc/layers/picture_layer.h"
#include "third_party/blink/renderer/core/editing/editing_utilities.h"
#include "third_party/blink/renderer/core/editing/frame_selection.h"
#include "third_party/blink/renderer/core/editing/local_caret_rect.h"
@@ -39,9 +40,9 @@
#include "third_party/blink/renderer/core/editing/visible_selection.h"
#include "third_party/blink/renderer/core/editing/visible_units.h"
#include "third_party/blink/renderer/core/html/forms/text_control_element.h"
-#include "third_party/blink/renderer/core/paint/compositing/composited_selection.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/graphics/graphics_layer.h"
#include <unicode/ubidi.h>
@@ -62,7 +63,7 @@ static GraphicsLayer* GetGraphicsLayerBacking(
}
// Convert a local point into the coordinate system of backing coordinates.
-static FloatPoint LocalToInvalidationBackingPoint(
+static gfx::Point LocalToInvalidationBackingPoint(
const LayoutPoint& local_point,
const LayoutObject& layout_object) {
const LayoutBoxModelObject& paint_invalidation_container =
@@ -77,7 +78,7 @@ static FloatPoint LocalToInvalidationBackingPoint(
// frame, or when forced compositing is disabled.
if (paint_invalidation_container.Layer()->GetCompositingState() ==
kNotComposited)
- return container_point;
+ return RoundedIntPoint(container_point);
PaintLayer::MapPointInPaintInvalidationContainerToBacking(
paint_invalidation_container, container_point);
@@ -93,7 +94,7 @@ static FloatPoint LocalToInvalidationBackingPoint(
->GetScrollOffset());
}
- return container_point;
+ return RoundedIntPoint(container_point);
}
std::pair<LayoutPoint, LayoutPoint> static GetLocalSelectionStartpoints(
@@ -157,83 +158,114 @@ static bool IsVisible(const LayoutObject& rect_layout_object,
return text_control_object->BorderBoxRect().Contains(position_in_input);
}
-static CompositedSelectionBound ComputeSelectionBound(
- const PositionWithAffinity& position,
+static base::Optional<cc::LayerSelectionBound> ComputeSelectionBound(
const LayoutObject& layout_object,
const LayoutPoint& edge_top_in_layer,
const LayoutPoint& edge_bottom_in_layer) {
- CompositedSelectionBound bound;
- bound.is_text_direction_rtl =
- layout_object.HasFlippedBlocksWritingMode() ||
- PrimaryDirectionOf(*position.AnchorNode()) == TextDirection::kRtl;
- bound.edge_top_in_layer =
+ cc::LayerSelectionBound bound;
+
+ bound.edge_top =
LocalToInvalidationBackingPoint(edge_top_in_layer, layout_object);
- bound.edge_bottom_in_layer =
+ bound.edge_bottom =
LocalToInvalidationBackingPoint(edge_bottom_in_layer, layout_object);
- bound.layer = GetGraphicsLayerBacking(layout_object);
+ GraphicsLayer* const layer = GetGraphicsLayerBacking(layout_object);
+ if (!layer)
+ return base::nullopt;
+ bound.layer_id = layer->CcLayer()->id();
bound.hidden =
!IsVisible(layout_object, edge_top_in_layer, edge_bottom_in_layer);
return bound;
}
-static CompositedSelectionBound StartPositionInGraphicsLayerBacking(
- const PositionWithAffinity& position) {
+// TODO(yoichio): Fix following weird implementation:
+// 1. IsTextDirectionRTL is computed from original Node and
+// LayoutObject from LocalCaretRectOfPosition.
+// 2. Current code can make both selection handles "LEFT".
+static inline bool IsTextDirectionRTL(const Node& node,
+ const LayoutObject& layout_object) {
+ return layout_object.HasFlippedBlocksWritingMode() ||
+ PrimaryDirectionOf(node) == TextDirection::kRtl;
+}
+
+static base::Optional<cc::LayerSelectionBound>
+StartPositionInGraphicsLayerBacking(const SelectionInDOMTree& selection) {
+ const PositionWithAffinity position(selection.ComputeStartPosition(),
+ selection.Affinity());
const LocalCaretRect& local_caret_rect = LocalCaretRectOfPosition(position);
const LayoutObject* const layout_object = local_caret_rect.layout_object;
if (!layout_object)
- return CompositedSelectionBound();
+ return base::nullopt;
LayoutPoint edge_top_in_layer, edge_bottom_in_layer;
std::tie(edge_top_in_layer, edge_bottom_in_layer) =
GetLocalSelectionStartpoints(local_caret_rect);
- return ComputeSelectionBound(position, *layout_object, edge_top_in_layer,
- edge_bottom_in_layer);
+ const auto& maybe = ComputeSelectionBound(*layout_object, edge_top_in_layer,
+ edge_bottom_in_layer);
+ if (!maybe.has_value())
+ return base::nullopt;
+ cc::LayerSelectionBound bound = maybe.value();
+ if (selection.IsRange()) {
+ bound.type = IsTextDirectionRTL(*position.AnchorNode(), *layout_object)
+ ? gfx::SelectionBound::Type::RIGHT
+ : gfx::SelectionBound::Type::LEFT;
+ } else {
+ bound.type = gfx::SelectionBound::Type::CENTER;
+ }
+ return bound;
}
-static CompositedSelectionBound EndPositionInGraphicsLayerBacking(
- const PositionWithAffinity& position) {
+static base::Optional<cc::LayerSelectionBound>
+EndPositionInGraphicsLayerBacking(const SelectionInDOMTree& selection) {
+ const PositionWithAffinity position(selection.ComputeEndPosition(),
+ selection.Affinity());
const LocalCaretRect& local_caret_rect = LocalCaretRectOfPosition(position);
const LayoutObject* const layout_object = local_caret_rect.layout_object;
if (!layout_object)
- return CompositedSelectionBound();
+ return base::nullopt;
LayoutPoint edge_top_in_layer, edge_bottom_in_layer;
std::tie(edge_top_in_layer, edge_bottom_in_layer) =
GetLocalSelectionEndpoints(local_caret_rect);
- return ComputeSelectionBound(position, *layout_object, edge_top_in_layer,
- edge_bottom_in_layer);
+ const auto& maybe = ComputeSelectionBound(*layout_object, edge_top_in_layer,
+ edge_bottom_in_layer);
+ if (!maybe.has_value())
+ return base::nullopt;
+ cc::LayerSelectionBound bound = maybe.value();
+ if (selection.IsRange()) {
+ bound.type = IsTextDirectionRTL(*position.AnchorNode(), *layout_object)
+ ? gfx::SelectionBound::Type::LEFT
+ : gfx::SelectionBound::Type::RIGHT;
+ } else {
+ bound.type = gfx::SelectionBound::Type::CENTER;
+ }
+ return bound;
}
-CompositedSelection ComputeCompositedSelection(
+cc::LayerSelection ComputeLayerSelection(
const FrameSelection& frame_selection) {
if (!frame_selection.IsHandleVisible() || frame_selection.IsHidden())
return {};
// TODO(yoichio): Compute SelectionInDOMTree w/o VS canonicalization.
// crbug.com/789870 for detail.
- const SelectionInDOMTree& visible_selection =
+ const SelectionInDOMTree& selection =
frame_selection.ComputeVisibleSelectionInDOMTree().AsSelection();
+ if (selection.IsNone())
+ return {};
// Non-editable caret selections lack any kind of UI affordance, and
// needn't be tracked by the client.
- if (visible_selection.IsCaret() &&
- !IsEditablePosition(visible_selection.ComputeStartPosition()))
+ if (selection.IsCaret() &&
+ !IsEditablePosition(selection.ComputeStartPosition()))
return {};
- CompositedSelection selection;
- selection.start = StartPositionInGraphicsLayerBacking(PositionWithAffinity(
- visible_selection.ComputeStartPosition(), visible_selection.Affinity()));
- if (!selection.start.layer)
+ const auto& maybe_start_bound =
+ StartPositionInGraphicsLayerBacking(selection);
+ if (!maybe_start_bound.has_value())
return {};
-
- selection.end = EndPositionInGraphicsLayerBacking(PositionWithAffinity(
- visible_selection.ComputeEndPosition(), visible_selection.Affinity()));
- if (!selection.end.layer)
+ const auto& maybe_end_bound = EndPositionInGraphicsLayerBacking(selection);
+ if (!maybe_end_bound.has_value())
return {};
-
- DCHECK(!visible_selection.IsNone());
- selection.type =
- visible_selection.IsRange() ? kRangeSelection : kCaretSelection;
- return selection;
+ return {maybe_start_bound.value(), maybe_end_bound.value()};
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/editing/rendered_position.h b/chromium/third_party/blink/renderer/core/editing/compute_layer_selection.h
index f048717c5a3..a7a6637b3ee 100644
--- a/chromium/third_party/blink/renderer/core/editing/rendered_position.h
+++ b/chromium/third_party/blink/renderer/core/editing/compute_layer_selection.h
@@ -28,22 +28,20 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_RENDERED_POSITION_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_RENDERED_POSITION_H_
-
-// TODO(editing-dev): Consider rename/move this file.
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_COMPUTE_LAYER_SELECTION_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_COMPUTE_LAYER_SELECTION_H_
+#include "cc/input/layer_selection_bound.h"
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/platform/wtf/allocator.h"
namespace blink {
class FrameSelection;
-struct CompositedSelection;
-CORE_EXPORT CompositedSelection
-ComputeCompositedSelection(const FrameSelection&);
+// Compute coodinates to paint selection handles on touch devices.
+CORE_EXPORT cc::LayerSelection ComputeLayerSelection(
+ const FrameSelection& frame_selection);
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_RENDERED_POSITION_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_COMPUTE_LAYER_SELECTION_H_
diff --git a/chromium/third_party/blink/renderer/core/editing/rendered_position_test.cc b/chromium/third_party/blink/renderer/core/editing/compute_layer_selection_test.cc
index f3c86170239..becf7b2e6ea 100644
--- a/chromium/third_party/blink/renderer/core/editing/rendered_position_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/compute_layer_selection_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/editing/rendered_position.h"
+#include "third_party/blink/renderer/core/editing/compute_layer_selection.h"
#include "build/build_config.h"
#include "third_party/blink/renderer/core/editing/frame_selection.h"
@@ -13,13 +13,12 @@
#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
#include "third_party/blink/renderer/core/html/forms/text_control_element.h"
#include "third_party/blink/renderer/core/layout/layout_box.h"
-#include "third_party/blink/renderer/core/paint/compositing/composited_selection.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
#include "third_party/blink/renderer/core/testing/use_mock_scrollbar_settings.h"
namespace blink {
-class RenderedPositionTest : public EditingTestBase {
+class ComputeLayerSelectionTest : public EditingTestBase {
public:
void SetUp() override {
EditingTestBase::SetUp();
@@ -46,7 +45,7 @@ class RenderedPositionTest : public EditingTestBase {
UseMockScrollbarSettings mock_scrollbars_;
};
-TEST_F(RenderedPositionTest, ComputeCompositedSelection) {
+TEST_F(ComputeLayerSelectionTest, ComputeLayerSelection) {
SetBodyContent(R"HTML(
<!DOCTYPE html>
input {
@@ -60,13 +59,13 @@ TEST_F(RenderedPositionTest, ComputeCompositedSelection) {
FocusAndSelectAll(ToHTMLInputElement(GetDocument().getElementById("target")));
- const CompositedSelection& composited_selection =
- ComputeCompositedSelection(Selection());
+ const cc::LayerSelection& composited_selection =
+ ComputeLayerSelection(Selection());
EXPECT_FALSE(composited_selection.start.hidden);
EXPECT_TRUE(composited_selection.end.hidden);
}
-TEST_F(RenderedPositionTest, PositionInScrollableRoot) {
+TEST_F(ComputeLayerSelectionTest, PositionInScrollableRoot) {
SetBodyContent(R"HTML(
<!DOCTYPE html>
<style>
@@ -97,21 +96,18 @@ TEST_F(RenderedPositionTest, PositionInScrollableRoot) {
UpdateAllLifecyclePhases();
- const CompositedSelection& composited_selection =
- ComputeCompositedSelection(Selection());
+ const cc::LayerSelection& composited_selection =
+ ComputeLayerSelection(Selection());
// Top-left corner should be around (1000, 905) - 10px centered in 20px
// height.
- EXPECT_EQ(FloatPoint(1000, 905),
- composited_selection.start.edge_top_in_layer);
- EXPECT_EQ(FloatPoint(1000, 915),
- composited_selection.start.edge_bottom_in_layer);
- EXPECT_EQ(FloatPoint(1369, 905), composited_selection.end.edge_top_in_layer);
- EXPECT_EQ(FloatPoint(1369, 915),
- composited_selection.end.edge_bottom_in_layer);
+ EXPECT_EQ(gfx::Point(1000, 905), composited_selection.start.edge_top);
+ EXPECT_EQ(gfx::Point(1000, 915), composited_selection.start.edge_bottom);
+ EXPECT_EQ(gfx::Point(1369, 905), composited_selection.end.edge_top);
+ EXPECT_EQ(gfx::Point(1369, 915), composited_selection.end.edge_bottom);
}
-TEST_F(RenderedPositionTest, PositionInScroller) {
+TEST_F(ComputeLayerSelectionTest, PositionInScroller) {
SetBodyContent(R"HTML(
<!DOCTYPE html>
<style>
@@ -163,59 +159,48 @@ TEST_F(RenderedPositionTest, PositionInScroller) {
UpdateAllLifecyclePhases();
- const CompositedSelection& composited_selection =
- ComputeCompositedSelection(Selection());
+ const cc::LayerSelection& composited_selection =
+ ComputeLayerSelection(Selection());
// Top-left corner should be around (1000, 905) - 10px centered in 20px
// height.
- EXPECT_EQ(FloatPoint(1000, 905),
- composited_selection.start.edge_top_in_layer);
- EXPECT_EQ(FloatPoint(1000, 915),
- composited_selection.start.edge_bottom_in_layer);
- EXPECT_EQ(FloatPoint(1369, 905), composited_selection.end.edge_top_in_layer);
- EXPECT_EQ(FloatPoint(1369, 915),
- composited_selection.end.edge_bottom_in_layer);
+ EXPECT_EQ(gfx::Point(1000, 905), composited_selection.start.edge_top);
+ EXPECT_EQ(gfx::Point(1000, 915), composited_selection.start.edge_bottom);
+ EXPECT_EQ(gfx::Point(1369, 905), composited_selection.end.edge_top);
+ EXPECT_EQ(gfx::Point(1369, 915), composited_selection.end.edge_bottom);
}
// crbug.com/807930
-TEST_F(RenderedPositionTest, ContentEditableLinebreak) {
+TEST_F(ComputeLayerSelectionTest, ContentEditableLinebreak) {
SetBodyContent(
"<div style='font: 10px/10px Ahem;' contenteditable>"
"test<br><br></div>");
Element* target = GetDocument().QuerySelector("div");
FocusAndSelectAll(target, *target);
- const CompositedSelection& composited_selection =
- ComputeCompositedSelection(Selection());
- EXPECT_EQ(composited_selection.start.edge_top_in_layer,
- FloatPoint(8.0f, 8.0f));
- EXPECT_EQ(composited_selection.start.edge_bottom_in_layer,
- FloatPoint(8.0f, 18.0f));
- EXPECT_EQ(composited_selection.end.edge_top_in_layer,
- FloatPoint(8.0f, 18.0f));
- EXPECT_EQ(composited_selection.end.edge_bottom_in_layer,
- FloatPoint(8.0f, 28.0f));
+ const cc::LayerSelection& composited_selection =
+ ComputeLayerSelection(Selection());
+ EXPECT_EQ(composited_selection.start.edge_top, gfx::Point(8, 8));
+ EXPECT_EQ(composited_selection.start.edge_bottom, gfx::Point(8, 18));
+ EXPECT_EQ(composited_selection.end.edge_top, gfx::Point(8, 18));
+ EXPECT_EQ(composited_selection.end.edge_bottom, gfx::Point(8, 28));
}
// crbug.com/807930
-TEST_F(RenderedPositionTest, TextAreaLinebreak) {
+TEST_F(ComputeLayerSelectionTest, TextAreaLinebreak) {
SetBodyContent(
"<textarea style='font: 10px/10px Ahem;'>"
"test\n</textarea>");
FocusAndSelectAll(ToTextControl(GetDocument().QuerySelector("textarea")));
- const CompositedSelection& composited_selection =
- ComputeCompositedSelection(Selection());
- EXPECT_EQ(composited_selection.start.edge_top_in_layer,
- FloatPoint(11.0f, 11.0f));
- EXPECT_EQ(composited_selection.start.edge_bottom_in_layer,
- FloatPoint(11.0f, 21.0f));
- EXPECT_EQ(composited_selection.end.edge_top_in_layer,
- FloatPoint(11.0f, 21.0f));
- EXPECT_EQ(composited_selection.end.edge_bottom_in_layer,
- FloatPoint(11.0f, 31.0f));
+ const cc::LayerSelection& composited_selection =
+ ComputeLayerSelection(Selection());
+ EXPECT_EQ(composited_selection.start.edge_top, gfx::Point(11, 11));
+ EXPECT_EQ(composited_selection.start.edge_bottom, gfx::Point(11, 21));
+ EXPECT_EQ(composited_selection.end.edge_top, gfx::Point(11, 21));
+ EXPECT_EQ(composited_selection.end.edge_bottom, gfx::Point(11, 31));
}
// crbug.com/815099
-TEST_F(RenderedPositionTest, CaretBeforeSoftWrap) {
+TEST_F(ComputeLayerSelectionTest, CaretBeforeSoftWrap) {
SetBodyContent(
"<div style='font: 10px/10px Ahem; width:20px;' "
"contenteditable>foo</div>");
@@ -229,19 +214,15 @@ TEST_F(RenderedPositionTest, CaretBeforeSoftWrap) {
.Build(),
SetSelectionOptions::Builder().SetShouldShowHandle(true).Build());
UpdateAllLifecyclePhases();
- const CompositedSelection& composited_selection =
- ComputeCompositedSelection(Selection());
- EXPECT_EQ(composited_selection.start.edge_top_in_layer,
- FloatPoint(27.0f, 8.0f));
- EXPECT_EQ(composited_selection.start.edge_bottom_in_layer,
- FloatPoint(27.0f, 18.0f));
- EXPECT_EQ(composited_selection.end.edge_top_in_layer,
- FloatPoint(27.0f, 8.0f));
- EXPECT_EQ(composited_selection.end.edge_bottom_in_layer,
- FloatPoint(27.0f, 18.0f));
+ const cc::LayerSelection& composited_selection =
+ ComputeLayerSelection(Selection());
+ EXPECT_EQ(composited_selection.start.edge_top, gfx::Point(27, 8));
+ EXPECT_EQ(composited_selection.start.edge_bottom, gfx::Point(27, 18));
+ EXPECT_EQ(composited_selection.end.edge_top, gfx::Point(27, 8));
+ EXPECT_EQ(composited_selection.end.edge_bottom, gfx::Point(27, 18));
}
-TEST_F(RenderedPositionTest, CaretAfterSoftWrap) {
+TEST_F(ComputeLayerSelectionTest, CaretAfterSoftWrap) {
SetBodyContent(
"<div style='font: 10px/10px Ahem; width:20px;' "
"contenteditable>foo</div>");
@@ -255,20 +236,16 @@ TEST_F(RenderedPositionTest, CaretAfterSoftWrap) {
.Build(),
SetSelectionOptions::Builder().SetShouldShowHandle(true).Build());
UpdateAllLifecyclePhases();
- const CompositedSelection& composited_selection =
- ComputeCompositedSelection(Selection());
- EXPECT_EQ(composited_selection.start.edge_top_in_layer,
- FloatPoint(8.0f, 18.0f));
- EXPECT_EQ(composited_selection.start.edge_bottom_in_layer,
- FloatPoint(8.0f, 28.0f));
- EXPECT_EQ(composited_selection.end.edge_top_in_layer,
- FloatPoint(8.0f, 18.0f));
- EXPECT_EQ(composited_selection.end.edge_bottom_in_layer,
- FloatPoint(8.0f, 28.0f));
+ const cc::LayerSelection& composited_selection =
+ ComputeLayerSelection(Selection());
+ EXPECT_EQ(composited_selection.start.edge_top, gfx::Point(8, 18));
+ EXPECT_EQ(composited_selection.start.edge_bottom, gfx::Point(8, 28));
+ EXPECT_EQ(composited_selection.end.edge_top, gfx::Point(8, 18));
+ EXPECT_EQ(composited_selection.end.edge_bottom, gfx::Point(8, 28));
}
// crbug.com/834686
-TEST_F(RenderedPositionTest, RangeBeginAtBlockEnd) {
+TEST_F(ComputeLayerSelectionTest, RangeBeginAtBlockEnd) {
const SelectionInDOMTree& selection = SetSelectionTextToBody(
"<div style='font: 10px/10px Ahem;'>"
"<div>foo\n^</div><div>ba|r</div></div>");
@@ -278,16 +255,12 @@ TEST_F(RenderedPositionTest, RangeBeginAtBlockEnd) {
Element* target = GetDocument().QuerySelector("div");
target->focus();
UpdateAllLifecyclePhases();
- const CompositedSelection& composited_selection =
- ComputeCompositedSelection(Selection());
- EXPECT_EQ(composited_selection.start.edge_top_in_layer,
- FloatPoint(38.0f, 8.0f));
- EXPECT_EQ(composited_selection.start.edge_bottom_in_layer,
- FloatPoint(38.0f, 18.0f));
- EXPECT_EQ(composited_selection.end.edge_top_in_layer,
- FloatPoint(28.0f, 18.0f));
- EXPECT_EQ(composited_selection.end.edge_bottom_in_layer,
- FloatPoint(28.0f, 28.0f));
+ const cc::LayerSelection& composited_selection =
+ ComputeLayerSelection(Selection());
+ EXPECT_EQ(composited_selection.start.edge_top, gfx::Point(38, 8));
+ EXPECT_EQ(composited_selection.start.edge_bottom, gfx::Point(38, 18));
+ EXPECT_EQ(composited_selection.end.edge_top, gfx::Point(28, 18));
+ EXPECT_EQ(composited_selection.end.edge_bottom, gfx::Point(28, 28));
}
} // namespace blink
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 85114d29c1b..e207f0b2cda 100644
--- a/chromium/third_party/blink/renderer/core/editing/editing_utilities.cc
+++ b/chromium/third_party/blink/renderer/core/editing/editing_utilities.cc
@@ -72,6 +72,7 @@
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/layout/layout_table_cell.h"
#include "third_party/blink/renderer/core/svg/svg_image_element.h"
+#include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
@@ -457,7 +458,7 @@ ContainerNode* HighestEditableRoot(const PositionInFlatTree& position) {
}
bool IsEditablePosition(const Position& position) {
- const Node* node = position.ParentAnchoredEquivalent().AnchorNode();
+ const Node* node = position.ComputeContainerNode();
if (!node)
return false;
DCHECK(node->GetDocument().IsActive());
@@ -1608,7 +1609,7 @@ DispatchEventResult DispatchBeforeInputInsertText(
input_type, data, InputTypeIsCancelable(input_type),
InputEvent::EventIsComposing::kNotComposing,
ranges ? ranges : TargetRangesForInputEvent(*target));
- return target->DispatchEvent(before_input_event);
+ return target->DispatchEvent(*before_input_event);
}
DispatchEventResult DispatchBeforeInputEditorCommand(
@@ -1620,7 +1621,7 @@ DispatchEventResult DispatchBeforeInputEditorCommand(
InputEvent* before_input_event = InputEvent::CreateBeforeInput(
input_type, g_null_atom, InputTypeIsCancelable(input_type),
InputEvent::EventIsComposing::kNotComposing, ranges);
- return target->DispatchEvent(before_input_event);
+ return target->DispatchEvent(*before_input_event);
}
DispatchEventResult DispatchBeforeInputDataTransfer(
@@ -1652,7 +1653,7 @@ DispatchEventResult DispatchBeforeInputDataTransfer(
InputEvent::EventIsComposing::kNotComposing,
TargetRangesForInputEvent(*target));
}
- return target->DispatchEvent(before_input_event);
+ return target->DispatchEvent(*before_input_event);
}
// |IsEmptyNonEditableNodeInEditable()| is introduced for fixing
@@ -1701,7 +1702,7 @@ static scoped_refptr<Image> ImageFromNode(const Node& node) {
if (layout_object->IsCanvas()) {
return ToHTMLCanvasElement(const_cast<Node&>(node))
- .CopiedImage(kFrontBuffer, kPreferNoAcceleration);
+ .Snapshot(kFrontBuffer, kPreferNoAcceleration);
}
if (!layout_object->IsImage())
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 64c533dc13e..6e7fc9e8b16 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
@@ -104,6 +104,22 @@ TEST_F(EditingUtilitiesTest, enclosingNodeOfType) {
EnclosingNodeOfType(PositionInFlatTree(one, 0), IsEnclosingBlock));
}
+// http://crbug.com/873088
+TEST_F(EditingUtilitiesTest, IsEditablePositionWithHr) {
+ SetBodyContent("<hr contenteditable id=target>");
+ Element& target = *GetDocument().getElementById("target");
+ EXPECT_FALSE(IsEditablePosition(Position::BeforeNode(target)));
+ EXPECT_TRUE(IsEditablePosition(Position(target, 0)));
+}
+
+// http://crbug.com/873088
+TEST_F(EditingUtilitiesTest, IsEditablePositionWithSpan) {
+ SetBodyContent("<span contenteditable id=target>abc</span>");
+ Element& target = *GetDocument().getElementById("target");
+ EXPECT_FALSE(IsEditablePosition(Position::BeforeNode(target)));
+ EXPECT_TRUE(IsEditablePosition(Position(target, 0)));
+}
+
TEST_F(EditingUtilitiesTest, isEditablePositionWithTable) {
// We would like to have below DOM tree without HTML, HEAD and BODY element.
// <table id=table><caption>foo</caption></table>
diff --git a/chromium/third_party/blink/renderer/core/editing/editor.cc b/chromium/third_party/blink/renderer/core/editing/editor.cc
index 381ef1b2cab..5357dc0ac19 100644
--- a/chromium/third_party/blink/renderer/core/editing/editor.cc
+++ b/chromium/third_party/blink/renderer/core/editing/editor.cc
@@ -49,6 +49,7 @@
#include "third_party/blink/renderer/core/editing/commands/simplify_markup_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_behavior.h"
#include "third_party/blink/renderer/core/editing/editing_style_utilities.h"
#include "third_party/blink/renderer/core/editing/editing_tri_state.h"
#include "third_party/blink/renderer/core/editing/editing_utilities.h"
@@ -237,9 +238,12 @@ bool Editor::CanCopy() const {
FrameSelection& selection = GetFrameSelection();
if (!selection.IsAvailable())
return false;
- return selection.ComputeVisibleSelectionInDOMTreeDeprecated().IsRange() &&
+ frame_->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+ const VisibleSelectionInFlatTree& visible_selection =
+ selection.ComputeVisibleSelectionInFlatTree();
+ return visible_selection.IsRange() &&
!IsInPasswordFieldWithUnrevealedPassword(
- selection.ComputeVisibleSelectionInDOMTree().Start());
+ ToPositionInDOMTree(visible_selection.Start()));
}
bool Editor::CanPaste() const {
@@ -406,12 +410,9 @@ EphemeralRange Editor::SelectedRange() {
}
void Editor::RespondToChangedContents(const Position& position) {
- if (GetFrame().GetSettings() &&
- GetFrame().GetSettings()->GetAccessibilityEnabled()) {
- Node* node = position.AnchorNode();
- if (AXObjectCache* cache =
- GetFrame().GetDocument()->ExistingAXObjectCache())
- cache->HandleEditableTextContentChanged(node);
+ if (AXObjectCache* cache =
+ GetFrame().GetDocument()->ExistingAXObjectCache()) {
+ cache->HandleEditableTextContentChanged(position.AnchorNode());
}
GetSpellChecker().RespondToChangedContents();
@@ -552,12 +553,12 @@ bool Editor::InsertParagraphSeparator() {
}
static void CountEditingEvent(ExecutionContext* execution_context,
- const Event* event,
+ const Event& event,
WebFeature feature_on_input,
WebFeature feature_on_text_area,
WebFeature feature_on_content_editable,
WebFeature feature_on_non_node) {
- EventTarget* event_target = event->target();
+ EventTarget* event_target = event.target();
Node* node = event_target->ToNode();
if (!node) {
UseCounter::Count(execution_context, feature_on_non_node);
@@ -589,11 +590,11 @@ static void CountEditingEvent(ExecutionContext* execution_context,
}
void Editor::CountEvent(ExecutionContext* execution_context,
- const Event* event) {
+ const Event& event) {
if (!execution_context)
return;
- if (event->type() == EventTypeNames::textInput) {
+ if (event.type() == EventTypeNames::textInput) {
CountEditingEvent(execution_context, event,
WebFeature::kTextInputEventOnInput,
WebFeature::kTextInputEventOnTextArea,
@@ -602,7 +603,7 @@ void Editor::CountEvent(ExecutionContext* execution_context,
return;
}
- if (event->type() == EventTypeNames::webkitBeforeTextInserted) {
+ if (event.type() == EventTypeNames::webkitBeforeTextInserted) {
CountEditingEvent(execution_context, event,
WebFeature::kWebkitBeforeTextInsertedOnInput,
WebFeature::kWebkitBeforeTextInsertedOnTextArea,
@@ -611,7 +612,7 @@ void Editor::CountEvent(ExecutionContext* execution_context,
return;
}
- if (event->type() == EventTypeNames::webkitEditableContentChanged) {
+ if (event.type() == EventTypeNames::webkitEditableContentChanged) {
CountEditingEvent(
execution_context, event,
WebFeature::kWebkitEditableContentChangedOnInput,
@@ -896,7 +897,7 @@ void Editor::SetMarkedTextMatchesAreHighlighted(bool flag) {
are_marked_text_matches_highlighted_ = flag;
GetFrame().GetDocument()->Markers().RepaintMarkers(
- DocumentMarker::kTextMatch);
+ DocumentMarker::MarkerTypes::TextMatch());
}
void Editor::RespondToChangedSelection() {
@@ -927,7 +928,7 @@ void Editor::ToggleOverwriteModeEnabled() {
void Editor::ReplaceSelection(const String& text) {
DCHECK(!GetFrame().GetDocument()->NeedsLayoutTreeUpdate());
bool select_replacement = Behavior().ShouldSelectReplacement();
- bool smart_replace = true;
+ bool smart_replace = false;
ReplaceSelectionWithText(text, select_replacement, smart_replace,
InputEvent::InputType::kInsertReplacementText);
}
diff --git a/chromium/third_party/blink/renderer/core/editing/editor.h b/chromium/third_party/blink/renderer/core/editing/editor.h
index 7b44ff8eacc..b98e652e261 100644
--- a/chromium/third_party/blink/renderer/core/editing/editor.h
+++ b/chromium/third_party/blink/renderer/core/editing/editor.h
@@ -30,7 +30,6 @@
#include "base/macros.h"
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/editing/editing_behavior.h"
#include "third_party/blink/renderer/core/editing/editing_style.h"
#include "third_party/blink/renderer/core/editing/finder/find_options.h"
#include "third_party/blink/renderer/core/editing/forward.h"
@@ -43,6 +42,7 @@ namespace blink {
class CompositeEditCommand;
class DragData;
+class EditingBehavior;
class EditorCommand;
class FrameSelection;
class LocalFrame;
@@ -82,7 +82,7 @@ class CORE_EXPORT Editor final : public GarbageCollectedFinalized<Editor> {
bool CanPaste() const;
bool CanDelete() const;
- static void CountEvent(ExecutionContext*, const Event*);
+ static void CountEvent(ExecutionContext*, const Event&);
void CopyImage(const HitTestResult&);
void RespondToChangedContents(const Position&);
@@ -129,7 +129,7 @@ class CORE_EXPORT Editor final : public GarbageCollectedFinalized<Editor> {
bool CanRedo();
void Redo();
- // Exposed for IdleSpellCheckCallback only.
+ // Exposed for IdleSpellCheckController only.
// Supposed to be used as |const UndoStack&|.
UndoStack& GetUndoStack() const { return *undo_stack_; }
@@ -193,7 +193,8 @@ class CORE_EXPORT Editor final : public GarbageCollectedFinalized<Editor> {
bool smart_replace,
InputEvent::InputType);
- // Implementation of WebLocalFrameImpl::replaceSelection.
+ // Implementation of WebLocalFrameImpl::ReplaceSelection. Does not use smart
+ // replacement.
void ReplaceSelection(const String&);
void ReplaceSelectionAfterDragging(DocumentFragment*,
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 fc3b5e56443..4e9cca888e2 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
@@ -28,6 +28,7 @@
#include "third_party/blink/public/platform/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"
#include "third_party/blink/renderer/core/editing/frame_selection.h"
#include "third_party/blink/renderer/core/events/keyboard_event.h"
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 42dc372e107..dd0b3ff9b7f 100644
--- a/chromium/third_party/blink/renderer/core/editing/editor_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/editor_test.cc
@@ -5,7 +5,10 @@
#include "third_party/blink/renderer/core/editing/editor.h"
#include "third_party/blink/renderer/core/clipboard/system_clipboard.h"
+#include "third_party/blink/renderer/core/dom/text.h"
#include "third_party/blink/renderer/core/editing/commands/editor_command.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"
#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
@@ -26,6 +29,13 @@ class EditorTest : public EditingTestBase {
}
};
+TEST_F(EditorTest, CanCopyCrossingShadowBoundary) {
+ const SelectionInDOMTree selection = SetSelectionTextToBody(
+ "<p><template data-mode=open>^abc</template></p><b>|</b>");
+ Selection().SetSelection(selection, SetSelectionOptions());
+ EXPECT_TRUE(GetDocument().GetFrame()->GetEditor().CanCopy());
+}
+
TEST_F(EditorTest, copyGeneratedPassword) {
// Checks that if the password field has the value generated by Chrome
// (HTMLInputElement::shouldRevealPassword will be true), copying the field
@@ -82,4 +92,34 @@ TEST_F(EditorTest, DontCopyHiddenSelections) {
EXPECT_TRUE(copied.IsEmpty()) << copied << " was copied.";
}
+TEST_F(EditorTest, ReplaceSelection) {
+ const char* body_content = "<input id=text value='HELLO'>";
+ SetBodyContent(body_content);
+
+ HTMLInputElement& text_control =
+ ToHTMLInputElement(*GetDocument().getElementById("text"));
+ text_control.select();
+ text_control.SetSelectionRange(2, 2);
+
+ Editor& editor = GetDocument().GetFrame()->GetEditor();
+ editor.ReplaceSelection("NEW");
+
+ EXPECT_EQ("HENEWLLO", text_control.value());
+}
+
+// http://crbug.com/873037
+TEST_F(EditorTest, UndoWithInvalidSelection) {
+ const SelectionInDOMTree selection = SetSelectionTextToBody(
+ "<div contenteditable><div></div><b>^abc|</b></div>");
+ Selection().SetSelection(selection, SetSelectionOptions());
+ Text& abc = ToText(*selection.Base().ComputeContainerNode());
+ // Push Text node "abc" into undo stack
+ GetDocument().execCommand("italic", false, "", ASSERT_NO_EXCEPTION);
+ // Change Text node "abc" in undo stack
+ abc.setData("");
+ GetDocument().GetFrame()->GetEditor().Undo();
+ EXPECT_EQ("<div contenteditable><div></div><b>|</b></div>",
+ GetSelectionTextFromBody());
+}
+
} // namespace blink
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
new file mode 100644
index 00000000000..13c44b7be15
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/editing/element_inner_text.cc
@@ -0,0 +1,691 @@
+// 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/dom/element.h"
+
+#include <algorithm>
+
+#include "base/auto_reset.h"
+#include "third_party/blink/renderer/core/dom/node_computed_style.h"
+#include "third_party/blink/renderer/core/dom/node_traversal.h"
+#include "third_party/blink/renderer/core/dom/text.h"
+#include "third_party/blink/renderer/core/editing/editing_utilities.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_br_element.h"
+#include "third_party/blink/renderer/core/html/html_paragraph_element.h"
+#include "third_party/blink/renderer/core/layout/layout_table_cell.h"
+#include "third_party/blink/renderer/core/layout/layout_table_row.h"
+#include "third_party/blink/renderer/core/layout/layout_table_section.h"
+#include "third_party/blink/renderer/core/layout/layout_text_fragment.h"
+#include "third_party/blink/renderer/core/layout/line/inline_text_box.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/paint/ng/ng_paint_fragment_traversal.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/vector.h"
+
+namespace blink {
+
+namespace {
+
+// The implementation of Element#innerText algorithm[1].
+// [1]
+// https://html.spec.whatwg.org/multipage/dom.html#the-innertext-idl-attribute
+class ElementInnerTextCollector final {
+ public:
+ ElementInnerTextCollector() = default;
+
+ String RunOn(const Element& element);
+
+ private:
+ // Result characters of innerText collection steps.
+ class Result final {
+ public:
+ Result() = default;
+
+ void EmitBeginBlock();
+ void EmitChar16(UChar code_point);
+ void EmitCollapsibleSpace();
+ void EmitEndBlock();
+ void EmitNewline();
+ void EmitRequiredLineBreak(int count);
+ void EmitTab();
+ void EmitText(const StringView& text);
+ String Finish();
+
+ bool HasCollapsibleSpace() const { return has_collapsible_space_; }
+
+ private:
+ void FlushCollapsibleSpace();
+ void FlushRequiredLineBreak();
+
+ StringBuilder builder_;
+ int required_line_break_count_ = 0;
+ bool at_start_of_block_ = false;
+ bool has_collapsible_space_ = false;
+
+ DISALLOW_COPY_AND_ASSIGN(Result);
+ };
+
+ // Minimal CSS text box representation for collecting character.
+ struct TextBox {
+ StringView text;
+ // An offset in |LayoutText::GetText()| or |NGInlineItemsData.text_content|.
+ unsigned start = 0;
+
+ TextBox(StringView passed_text, unsigned passed_start)
+ : text(passed_text), start(passed_start) {
+ DCHECK_GT(text.length(), 0u);
+ }
+ };
+
+ static bool EndsWithWhiteSpace(const InlineTextBox& text_box);
+ static bool EndsWithWhiteSpace(const LayoutText& layout_text);
+ static bool EndsWithWhiteSpace(const NGPhysicalTextFragment& fragment);
+ static bool HasDisplayContentsStyle(const Node& node);
+ static bool IsAfterWhiteSpace(const InlineTextBox& text_box);
+ static bool IsAfterWhiteSpace(const LayoutText& layout_text);
+ static bool IsAfterWhiteSpace(const NGPhysicalTextFragment& fragment);
+ static bool IsBeingRendered(const Node& node);
+ static bool IsCollapsibleSpace(UChar code_point);
+ // 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 LayoutTableRow& table_row);
+ static bool StartsWithWhiteSpace(const LayoutText& layout_text);
+
+ void ProcessChildren(const Node& node);
+ void ProcessChildrenWithRequiredLineBreaks(const Node& node,
+ int required_line_break_count);
+ void ProcessLayoutText(const LayoutText& layout_text);
+ void ProcessLayoutTextEmpty(const LayoutText& layout_text);
+ void ProcessLayoutTextForNG(const NGPaintFragment::FragmentRange& fragments);
+ void ProcessNode(const Node& node);
+ void ProcessOptionElement(const HTMLOptionElement& element);
+ void ProcessSelectElement(const HTMLSelectElement& element);
+ void ProcessText(StringView text, EWhiteSpace white_space);
+ void ProcessTextBoxes(const LayoutText& layout_text,
+ const Vector<TextBox>& text_boxes);
+ void ProcessTextNode(const Text& node);
+
+ // Result character buffer.
+ Result result_;
+
+ DISALLOW_COPY_AND_ASSIGN(ElementInnerTextCollector);
+};
+
+String ElementInnerTextCollector::RunOn(const Element& element) {
+ DCHECK(!element.InActiveDocument() || !NeedsLayoutTreeUpdate(element));
+
+ // 1. If this element is not being rendered, or if the user agent is a non-CSS
+ // user agent, then return the same value as the textContent IDL attribute on
+ // this element.
+ // Note: To pass WPT test, case we don't use |textContent| for
+ // "display:content". See [1] for discussion about "display:contents" and
+ // "being rendered".
+ // [1] https://github.com/whatwg/html/issues/1837
+ if (!IsBeingRendered(element) && !HasDisplayContentsStyle(element)) {
+ const bool convert_brs_to_newlines = false;
+ return element.textContent(convert_brs_to_newlines);
+ }
+
+ // 2. Let results be the list resulting in running the inner text collection
+ // steps with this element. Each item in results will either be a JavaScript
+ // string or a positive integer (a required line break count).
+ ProcessNode(element);
+ return result_.Finish();
+}
+
+// static
+bool ElementInnerTextCollector::EndsWithWhiteSpace(
+ const InlineTextBox& text_box) {
+ const unsigned length = text_box.Len();
+ if (length == 0)
+ return false;
+ const String text = text_box.GetLineLayoutItem().GetText();
+ return IsCollapsibleSpace(text[text_box.Start() + length - 1]);
+}
+
+// static
+bool ElementInnerTextCollector::EndsWithWhiteSpace(
+ const LayoutText& layout_text) {
+ const unsigned length = layout_text.TextLength();
+ return length > 0 && layout_text.ContainsOnlyWhitespace(length - 1, 1);
+}
+
+// static
+bool ElementInnerTextCollector::EndsWithWhiteSpace(
+ const NGPhysicalTextFragment& fragment) {
+ return IsCollapsibleSpace(fragment.Text()[fragment.Length() - 1]);
+}
+
+// static
+bool ElementInnerTextCollector::HasDisplayContentsStyle(const Node& node) {
+ return node.IsElementNode() && ToElement(node).HasDisplayContentsStyle();
+}
+
+// An element is *being rendered* if it has any associated CSS layout boxes,
+// SVG layout boxes, or some equivalent in other styling languages.
+// Note: Just being off-screen does not mean the element is not being rendered.
+// The presence of the "hidden" attribute normally means the element is not
+// being rendered, though this might be overridden by the style sheets.
+// From https://html.spec.whatwg.org/multipage/rendering.html#being-rendered
+// static
+bool ElementInnerTextCollector::IsBeingRendered(const Node& node) {
+ return node.GetLayoutObject();
+}
+
+// static
+bool ElementInnerTextCollector::IsAfterWhiteSpace(
+ const InlineTextBox& text_box) {
+ const unsigned start = text_box.Start();
+ if (start == 0)
+ return false;
+ const String text = text_box.GetLineLayoutItem().GetText();
+ return IsCollapsibleSpace(text[start - 1]);
+}
+
+// static
+bool ElementInnerTextCollector::IsAfterWhiteSpace(
+ const LayoutText& layout_text) {
+ if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
+ const auto fragments = NGPaintFragment::InlineFragmentsFor(&layout_text);
+ if (!fragments.IsEmpty() &&
+ fragments.IsInLayoutNGInlineFormattingContext()) {
+ NGPaintFragmentTraversalContext previous =
+ NGPaintFragmentTraversal::PreviousInlineLeafOfIgnoringLineBreak(
+ NGPaintFragmentTraversalContext::Create(&fragments.front()));
+ if (previous.IsNull())
+ return false;
+ const NGPhysicalFragment& previous_fragment =
+ previous.GetFragment()->PhysicalFragment();
+ if (!previous_fragment.IsText())
+ return false;
+ return EndsWithWhiteSpace(ToNGPhysicalTextFragment(previous_fragment));
+ }
+ }
+ if (InlineTextBox* text_box = layout_text.FirstTextBox()) {
+ const InlineBox* previous = text_box->PrevLeafChild();
+ if (!previous || !previous->IsInlineTextBox())
+ return false;
+ return EndsWithWhiteSpace(ToInlineTextBox(*previous));
+ }
+ const LayoutObject* previous_leaf = PreviousLeafOf(layout_text);
+ if (!previous_leaf || !previous_leaf->IsText())
+ return false;
+ const LayoutText& previous_text = ToLayoutText(*previous_leaf);
+ const unsigned length = previous_text.TextLength();
+ if (length == 0)
+ return false;
+ return previous_text.ContainsOnlyWhitespace(length - 1, 1);
+}
+
+bool ElementInnerTextCollector::IsAfterWhiteSpace(
+ const NGPhysicalTextFragment& text_box) {
+ const unsigned start = text_box.StartOffset();
+ if (start == 0)
+ return false;
+ const String text = text_box.TextContent();
+ return IsCollapsibleSpace(text[start - 1]);
+}
+
+// See https://drafts.csswg.org/css-text-3/#white-space-phase-2
+bool ElementInnerTextCollector::IsCollapsibleSpace(UChar code_point) {
+ return code_point == kSpaceCharacter || code_point == kNewlineCharacter ||
+ code_point == kTabulationCharacter ||
+ code_point == kCarriageReturnCharacter;
+}
+
+// static
+bool ElementInnerTextCollector::IsDisplayBlockLevel(const Node& node) {
+ const LayoutObject* const layout_object = node.GetLayoutObject();
+ if (!layout_object || !layout_object->IsLayoutBlock())
+ return false;
+ if (layout_object->IsAtomicInlineLevel())
+ return false;
+ if (layout_object->IsRubyText()) {
+ // RT isn't consider as block-level.
+ // e.g. <ruby>abc<rt>def</rt>.innerText == "abcdef"
+ return false;
+ }
+ // Note: CAPTION is associated to |LayoutNGTableCaption| in LayoutNG or
+ // |LayoutBlockFlow| in legacy layout.
+ return true;
+}
+
+// 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 LayoutTableRow& table_row) {
+ const LayoutTable* const table = table_row.Table();
+ if (!table)
+ return false;
+ if (table_row.NextRow())
+ return true;
+ // For TABLE contains TBODY, TFOOTER, THEAD.
+ const LayoutTableSection* const table_section = table_row.Section();
+ if (!table_section)
+ return false;
+ // See |LayoutTable::SectionAbove()| and |SectionBelow()| for traversing
+ // |LayoutTableSection|.
+ for (LayoutObject* runner = table_section->NextSibling(); runner;
+ runner = runner->NextSibling()) {
+ if (!runner->IsTableSection())
+ continue;
+ if (ToLayoutTableSection(*runner).NumRows() > 0)
+ return true;
+ }
+ // No table row after |node|.
+ return false;
+}
+
+// static
+bool ElementInnerTextCollector::StartsWithWhiteSpace(
+ const LayoutText& layout_text) {
+ const unsigned length = layout_text.TextLength();
+ return length > 0 && layout_text.ContainsOnlyWhitespace(0, 1);
+}
+
+void ElementInnerTextCollector::ProcessChildren(const Node& container) {
+ for (const Node& node : NodeTraversal::ChildrenOf(container))
+ ProcessNode(node);
+}
+
+void ElementInnerTextCollector::ProcessChildrenWithRequiredLineBreaks(
+ const Node& node,
+ int required_line_break_count) {
+ DCHECK_GE(required_line_break_count, 0);
+ DCHECK_LE(required_line_break_count, 2);
+ result_.EmitBeginBlock();
+ result_.EmitRequiredLineBreak(required_line_break_count);
+ ProcessChildren(node);
+ result_.EmitRequiredLineBreak(required_line_break_count);
+ result_.EmitEndBlock();
+}
+
+void ElementInnerTextCollector::ProcessLayoutText(
+ const LayoutText& layout_text) {
+ if (layout_text.TextLength() == 0)
+ return;
+ if (layout_text.Style()->Visibility() != EVisibility::kVisible) {
+ // TODO(editing-dev): Once we make ::first-letter don't apply "visibility",
+ // we should get rid of this if-statement. http://crbug.com/866744
+ return;
+ }
+ if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
+ const auto fragments = NGPaintFragment::InlineFragmentsFor(&layout_text);
+ if (!fragments.IsEmpty() &&
+ fragments.IsInLayoutNGInlineFormattingContext()) {
+ ProcessLayoutTextForNG(fragments);
+ return;
+ }
+ }
+
+ if (!layout_text.FirstTextBox()) {
+ if (!layout_text.ContainsOnlyWhitespace(0, layout_text.TextLength()))
+ return;
+ if (IsAfterWhiteSpace(layout_text))
+ return;
+ // <div style="width:0">abc<span> <span>def</span></div> reaches here for
+ // a space between SPAN.
+ result_.EmitCollapsibleSpace();
+ return;
+ }
+
+ // TODO(editing-dev): We should handle "text-transform" in "::first-line".
+ // In legacy layout, |InlineTextBox| holds original text and text box
+ // paint does text transform.
+ const String text = layout_text.GetText();
+ const bool collapse_white_space = layout_text.Style()->CollapseWhiteSpace();
+ bool may_have_leading_space = collapse_white_space &&
+ StartsWithWhiteSpace(layout_text) &&
+ !IsAfterWhiteSpace(layout_text);
+ Vector<TextBox> text_boxes;
+ for (InlineTextBox* text_box : layout_text.TextBoxes()) {
+ const unsigned start =
+ may_have_leading_space && IsAfterWhiteSpace(*text_box)
+ ? text_box->Start() - 1
+ : text_box->Start();
+ const unsigned end = text_box->Start() + text_box->Len();
+ may_have_leading_space =
+ collapse_white_space && !IsCollapsibleSpace(text[end - 1]);
+ text_boxes.emplace_back(StringView(text, start, end - start), start);
+ }
+ ProcessTextBoxes(layout_text, text_boxes);
+ if (!collapse_white_space || !EndsWithWhiteSpace(layout_text))
+ return;
+ result_.EmitCollapsibleSpace();
+}
+
+void ElementInnerTextCollector::ProcessLayoutTextForNG(
+ const NGPaintFragment::FragmentRange& paint_fragments) {
+ DCHECK(!paint_fragments.IsEmpty());
+ const LayoutText& layout_text =
+ ToLayoutText(*paint_fragments.front().GetLayoutObject());
+ const bool collapse_white_space = layout_text.Style()->CollapseWhiteSpace();
+ bool may_have_leading_space = collapse_white_space &&
+ StartsWithWhiteSpace(layout_text) &&
+ !IsAfterWhiteSpace(layout_text);
+ // TODO(editing-dev): We should include overflow text to result of CSS
+ // "text-overflow". See http://crbug.com/873957
+ Vector<TextBox> text_boxes;
+ const StringImpl* last_text_content = nullptr;
+ for (const NGPaintFragment* paint_fragment : paint_fragments) {
+ const NGPhysicalTextFragment& text_fragment =
+ ToNGPhysicalTextFragment(paint_fragment->PhysicalFragment());
+ if (text_fragment.IsGeneratedText())
+ continue;
+ // Symbol marker should be appeared in pseudo-element only.
+ DCHECK_NE(text_fragment.TextType(), NGPhysicalTextFragment::kSymbolMarker);
+ if (last_text_content != text_fragment.TextContent().Impl()) {
+ if (!text_boxes.IsEmpty()) {
+ ProcessTextBoxes(layout_text, text_boxes);
+ text_boxes.clear();
+ }
+ last_text_content = text_fragment.TextContent().Impl();
+ }
+ const unsigned start =
+ may_have_leading_space && IsAfterWhiteSpace(text_fragment)
+ ? text_fragment.StartOffset() - 1
+ : text_fragment.StartOffset();
+ const unsigned end = text_fragment.EndOffset();
+ may_have_leading_space =
+ collapse_white_space &&
+ !IsCollapsibleSpace(text_fragment.TextContent()[end - 1]);
+ text_boxes.emplace_back(
+ StringView(text_fragment.TextContent(), start, end - start), start);
+ }
+ if (!text_boxes.IsEmpty())
+ ProcessTextBoxes(layout_text, text_boxes);
+ if (!collapse_white_space || !EndsWithWhiteSpace(layout_text))
+ return;
+ result_.EmitCollapsibleSpace();
+}
+
+// The "inner text collection steps".
+void ElementInnerTextCollector::ProcessNode(const Node& node) {
+ // 1. Let items be the result of running the inner text collection steps with
+ // each child node of node in tree order, and then concatenating the results
+ // to a single list.
+
+ // 2. If node's computed value of 'visibility' is not 'visible', then return
+ // items.
+ const ComputedStyle* style = node.GetComputedStyle();
+ if (style && style->Visibility() != EVisibility::kVisible)
+ return ProcessChildren(node);
+
+ // 3. If node is not being rendered, then return items. For the purpose of
+ // this step, the following elements must act as described if the computed
+ // value of the 'display' property is not 'none':
+ // Note: items can be non-empty due to 'display:contents'.
+ if (!IsBeingRendered(node)) {
+ // "display:contents" also reaches here since it doesn't have a CSS box.
+ return ProcessChildren(node);
+ }
+ // * select elements have an associated non-replaced inline CSS box whose
+ // child boxes include only those of optgroup and option element child
+ // nodes;
+ // * optgroup elements have an associated non-replaced block-level CSS box
+ // whose child boxes include only those of option element child nodes; and
+ // * option element have an associated non-replaced block-level CSS box whose
+ // child boxes are as normal for non-replaced block-level CSS boxes.
+ if (IsHTMLSelectElement(node))
+ return ProcessSelectElement(ToHTMLSelectElement(node));
+ if (IsHTMLOptionElement(node)) {
+ // Since child nodes of OPTION are not rendered, we use dedicated function.
+ // e.g. <div>ab<option>12</div>cd</div>innerText == "ab\n12\ncd"
+ // Note: "label" attribute doesn't affect value of innerText.
+ return ProcessOptionElement(ToHTMLOptionElement(node));
+ }
+
+ // 4. If node is a Text node, then for each CSS text box produced by node.
+ if (node.IsTextNode())
+ return ProcessTextNode(ToText(node));
+
+ // 5. If node is a br element, then append a string containing a single U+000A
+ // LINE FEED (LF) character to items.
+ if (IsHTMLBRElement(node)) {
+ ProcessChildren(node);
+ result_.EmitNewline();
+ return;
+ }
+
+ // 6. If node's computed value of 'display' is 'table-cell', and node's CSS
+ // box is not the last 'table-cell' box of its enclosing 'table-row' box, then
+ // append a string containing a single U+0009 CHARACTER TABULATION (tab)
+ // character to items.
+ const LayoutObject& layout_object = *node.GetLayoutObject();
+ if (style->Display() == EDisplay::kTableCell) {
+ ProcessChildrenWithRequiredLineBreaks(node, 0);
+ result_.EmitEndBlock();
+ if (layout_object.IsTableCell() &&
+ ToLayoutTableCell(layout_object).NextCell())
+ result_.EmitTab();
+ return;
+ }
+
+ // 7. If node's computed value of 'display' is 'table-row', and node's CSS box
+ // is not the last 'table-row' box of the nearest ancestor 'table' box, then
+ // append a string containing a single U+000A LINE FEED (LF) character to
+ // items.
+ if (style->Display() == EDisplay::kTableRow) {
+ ProcessChildrenWithRequiredLineBreaks(node, 0);
+ if (layout_object.IsTableRow() &&
+ ShouldEmitNewlineForTableRow(ToLayoutTableRow(layout_object)))
+ result_.EmitNewline();
+ return;
+ }
+
+ // 8. If node is a p element, then append 2 (a required line break count) at
+ // the beginning and end of items.
+ if (IsHTMLParagraphElement(node)) {
+ // Note: <p style="display:contents>foo</p> doesn't generate layout object
+ // for P.
+ ProcessChildrenWithRequiredLineBreaks(node, 2);
+ return;
+ }
+
+ // 9. If node's used value of 'display' is block-level or 'table-caption',
+ // then append 1 (a required line break count) at the beginning and end of
+ // items.
+ if (IsDisplayBlockLevel(node))
+ return ProcessChildrenWithRequiredLineBreaks(node, 1);
+
+ if (layout_object.IsLayoutBlock())
+ return ProcessChildrenWithRequiredLineBreaks(node, 0);
+ ProcessChildren(node);
+}
+
+void ElementInnerTextCollector::ProcessOptionElement(
+ const HTMLOptionElement& option_element) {
+ result_.EmitRequiredLineBreak(1);
+ result_.EmitText(option_element.text());
+ result_.EmitRequiredLineBreak(1);
+}
+
+void ElementInnerTextCollector::ProcessSelectElement(
+ const HTMLSelectElement& select_element) {
+ for (const Node& child : NodeTraversal::ChildrenOf(select_element)) {
+ if (IsHTMLOptionElement(child)) {
+ ProcessOptionElement(ToHTMLOptionElement(child));
+ continue;
+ }
+ if (!IsHTMLOptGroupElement(child))
+ continue;
+ // Note: We should emit newline for OPTGROUP even if it has no OPTION.
+ // e.g. <div>a<select><optgroup></select>b</div>.innerText == "a\nb"
+ result_.EmitRequiredLineBreak(1);
+ for (const Node& maybe_option : NodeTraversal::ChildrenOf(child)) {
+ if (IsHTMLOptionElement(maybe_option))
+ ProcessOptionElement(ToHTMLOptionElement(maybe_option));
+ }
+ result_.EmitRequiredLineBreak(1);
+ }
+}
+
+void ElementInnerTextCollector::ProcessTextBoxes(
+ const LayoutText& layout_text,
+ const Vector<TextBox>& passed_text_boxes) {
+ DCHECK(!passed_text_boxes.IsEmpty());
+ Vector<TextBox> text_boxes = passed_text_boxes;
+ // TODO(editing-dev): We may want to check |ContainsReversedText()| in
+ // |LayoutText|. See http://crbug.com/873949
+ std::sort(text_boxes.begin(), text_boxes.end(),
+ [](const TextBox& text_box1, const TextBox& text_box2) {
+ return text_box1.start < text_box2.start;
+ });
+ const EWhiteSpace white_space = layout_text.Style()->WhiteSpace();
+ for (const TextBox& text_box : text_boxes)
+ ProcessText(text_box.text, white_space);
+}
+
+void ElementInnerTextCollector::ProcessText(StringView text,
+ EWhiteSpace white_space) {
+ if (!ComputedStyle::CollapseWhiteSpace(white_space))
+ return result_.EmitText(text);
+ for (unsigned index = 0; index < text.length(); ++index) {
+ if (white_space == EWhiteSpace::kPreLine &&
+ text[index] == kNewlineCharacter) {
+ result_.EmitNewline();
+ continue;
+ }
+ if (IsCollapsibleSpace(text[index])) {
+ result_.EmitCollapsibleSpace();
+ continue;
+ }
+ result_.EmitChar16(text[index]);
+ }
+}
+
+void ElementInnerTextCollector::ProcessTextNode(const Text& node) {
+ if (!node.GetLayoutObject())
+ return;
+ const LayoutText& layout_text = *node.GetLayoutObject();
+ if (LayoutText* first_letter_part = layout_text.GetFirstLetterPart())
+ ProcessLayoutText(*first_letter_part);
+ ProcessLayoutText(layout_text);
+}
+
+// ----
+
+void ElementInnerTextCollector::Result::EmitBeginBlock() {
+ if (has_collapsible_space_)
+ return;
+ at_start_of_block_ = true;
+}
+
+void ElementInnerTextCollector::Result::EmitChar16(UChar code_point) {
+ if (required_line_break_count_ > 0)
+ FlushRequiredLineBreak();
+ else
+ FlushCollapsibleSpace();
+ DCHECK_EQ(required_line_break_count_, 0);
+ DCHECK(!has_collapsible_space_);
+ builder_.Append(code_point);
+ at_start_of_block_ = false;
+}
+
+void ElementInnerTextCollector::Result::EmitCollapsibleSpace() {
+ if (at_start_of_block_)
+ return;
+ FlushRequiredLineBreak();
+ has_collapsible_space_ = true;
+}
+
+void ElementInnerTextCollector::Result::EmitEndBlock() {
+ // Discard tailing collapsible spaces from last child of the block.
+ has_collapsible_space_ = false;
+}
+
+void ElementInnerTextCollector::Result::EmitNewline() {
+ FlushRequiredLineBreak();
+ has_collapsible_space_ = false;
+ builder_.Append(kNewlineCharacter);
+}
+
+void ElementInnerTextCollector::Result::EmitRequiredLineBreak(int count) {
+ DCHECK_GE(count, 0);
+ DCHECK_LE(count, 2);
+ if (count == 0)
+ return;
+ // 4. Remove any runs of consecutive required line break count items at the
+ // start or end of results.
+ if (builder_.IsEmpty()) {
+ DCHECK_EQ(required_line_break_count_, 0);
+ return;
+ }
+ // 5. Replace each remaining run of consecutive required line break count
+ // items with a string consisting of as many U+000A LINE FEED (LF) characters
+ // as the maximum of the values in the required line break count items.
+ required_line_break_count_ = std::max(required_line_break_count_, count);
+ at_start_of_block_ = true;
+}
+
+void ElementInnerTextCollector::Result::EmitTab() {
+ if (required_line_break_count_ > 0)
+ FlushRequiredLineBreak();
+ has_collapsible_space_ = false;
+ at_start_of_block_ = false;
+ builder_.Append(kTabulationCharacter);
+}
+
+void ElementInnerTextCollector::Result::EmitText(const StringView& text) {
+ if (text.IsEmpty())
+ return;
+ at_start_of_block_ = false;
+ if (required_line_break_count_ > 0)
+ FlushRequiredLineBreak();
+ else
+ FlushCollapsibleSpace();
+ DCHECK_EQ(required_line_break_count_, 0);
+ DCHECK(!has_collapsible_space_);
+ builder_.Append(text);
+}
+
+String ElementInnerTextCollector::Result::Finish() {
+ if (required_line_break_count_ == 0)
+ FlushCollapsibleSpace();
+ return builder_.ToString();
+}
+
+void ElementInnerTextCollector::Result::FlushCollapsibleSpace() {
+ if (!has_collapsible_space_)
+ return;
+ has_collapsible_space_ = false;
+ builder_.Append(kSpaceCharacter);
+}
+
+void ElementInnerTextCollector::Result::FlushRequiredLineBreak() {
+ DCHECK_GE(required_line_break_count_, 0);
+ DCHECK_LE(required_line_break_count_, 2);
+ builder_.Append("\n\n", required_line_break_count_);
+ required_line_break_count_ = 0;
+ has_collapsible_space_ = false;
+}
+
+} // anonymous namespace
+
+String Element::innerText() {
+ // We need to update layout, since |ElementInnerTextCollector()| uses line
+ // boxes in the layout tree.
+ GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(this);
+ return ElementInnerTextCollector().RunOn(*this);
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..9a29659c447
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/editing/element_inner_text_test.cc
@@ -0,0 +1,40 @@
+// 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/dom/element.h"
+
+#include "third_party/blink/renderer/core/editing/testing/editing_test_base.h"
+
+namespace blink {
+
+class ElementInnerTest : public EditingTestBase {};
+
+// http://crbug.com/877498
+TEST_F(ElementInnerTest, ListItemWithLeadingWhiteSpace) {
+ SetBodyContent("<li id=target> abc</li>");
+ Element& target = *GetDocument().getElementById("target");
+ EXPECT_EQ("abc", target.innerText());
+}
+
+// http://crbug.com/877470
+TEST_F(ElementInnerTest, SVGElementAsTableCell) {
+ SetBodyContent(
+ "<div id=target>abc"
+ "<svg><rect style='display:table-cell'></rect></svg>"
+ "</div>");
+ Element& target = *GetDocument().getElementById("target");
+ EXPECT_EQ("abc", target.innerText());
+}
+
+// http://crbug.com/878725
+TEST_F(ElementInnerTest, SVGElementAsTableRow) {
+ SetBodyContent(
+ "<div id=target>abc"
+ "<svg><rect style='display:table-row'></rect></svg>"
+ "</div>");
+ Element& target = *GetDocument().getElementById("target");
+ EXPECT_EQ("abc", target.innerText());
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/editing/finder/find_options.h b/chromium/third_party/blink/renderer/core/editing/finder/find_options.h
index 06c986371da..60582843d84 100644
--- a/chromium/third_party/blink/renderer/core/editing/finder/find_options.h
+++ b/chromium/third_party/blink/renderer/core/editing/finder/find_options.h
@@ -30,18 +30,13 @@ namespace blink {
enum FindOptionFlag {
kCaseInsensitive = 1 << 0,
- kAtWordStarts = 1 << 1,
- // When combined with AtWordStarts, accepts a match in the middle of a word if
- // the match begins with an uppercase letter followed by a lowercase or
- // non-letter. Accepts several other intra-word matches.
- kTreatMedialCapitalAsWordStart = 1 << 2,
- kBackwards = 1 << 3,
- kWrapAround = 1 << 4,
- kStartInSelection = 1 << 5,
- kWholeWord = 1 << 6, // WholeWord should imply AtWordStarts
+ kBackwards = 1 << 1,
+ kWrapAround = 1 << 2,
+ kStartInSelection = 1 << 3,
+ kWholeWord = 1 << 4,
// TODO(yosin) Once find UI works on flat tree and it doesn't use
// |rangeOfString()|, we should get rid of |FindAPICall| enum member.
- kFindAPICall = 1 << 7, // Used for Window.find or execCommand('find')
+ kFindAPICall = 1 << 5, // Used for Window.find or execCommand('find')
};
typedef unsigned FindOptions;
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 3e1ccba1566..3c0dcd3510c 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
@@ -38,7 +38,9 @@
#include "third_party/blink/public/web/web_local_frame_client.h"
#include "third_party/blink/public/web/web_view_client.h"
#include "third_party/blink/renderer/core/accessibility/ax_object_cache_base.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/dom/shadow_root.h"
#include "third_party/blink/renderer/core/editing/editor.h"
#include "third_party/blink/renderer/core/editing/ephemeral_range.h"
@@ -51,6 +53,7 @@
#include "third_party/blink/renderer/core/editing/selection_template.h"
#include "third_party/blink/renderer/core/editing/visible_selection.h"
#include "third_party/blink/renderer/core/exported/web_view_impl.h"
+#include "third_party/blink/renderer/core/frame/find_in_page.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"
@@ -58,11 +61,16 @@
#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/page/page.h"
+#include "third_party/blink/renderer/platform/histogram.h"
#include "third_party/blink/renderer/platform/timer.h"
#include "third_party/blink/renderer/platform/wtf/time.h"
namespace blink {
+namespace {
+constexpr TimeDelta kForcedInvocationDeadline = TimeDelta::FromSeconds(10);
+}
+
TextFinder::FindMatch::FindMatch(Range* range, int ordinal)
: range_(range), ordinal_(ordinal) {}
@@ -70,44 +78,53 @@ void TextFinder::FindMatch::Trace(blink::Visitor* visitor) {
visitor->Trace(range_);
}
-class TextFinder::DeferredScopeStringMatches
- : public GarbageCollectedFinalized<TextFinder::DeferredScopeStringMatches> {
+class TextFinder::IdleScopeStringMatchesCallback
+ : public ScriptedIdleTaskController::IdleTask {
public:
- static DeferredScopeStringMatches* Create(TextFinder* text_finder,
- int identifier,
- const WebString& search_text,
- const WebFindOptions& options) {
- return new DeferredScopeStringMatches(text_finder, identifier, search_text,
- options);
+ static IdleScopeStringMatchesCallback* Create(TextFinder* text_finder,
+ int identifier,
+ const WebString& search_text,
+ const WebFindOptions& options) {
+ return new IdleScopeStringMatchesCallback(text_finder, identifier,
+ search_text, options);
}
- void Trace(blink::Visitor* visitor) { visitor->Trace(text_finder_); }
+ void Dispose() {
+ DCHECK_GT(callback_handle_, 0);
+ if (!text_finder_->GetFrame())
+ return;
+ Document* document = text_finder_->GetFrame()->GetDocument();
+ if (!document)
+ return;
+ document->CancelIdleCallback(callback_handle_);
+ }
- void Dispose() { timer_.Stop(); }
+ void Trace(blink::Visitor* visitor) override {
+ visitor->Trace(text_finder_);
+ ScriptedIdleTaskController::IdleTask::Trace(visitor);
+ }
private:
- DeferredScopeStringMatches(TextFinder* text_finder,
- int identifier,
- const WebString& search_text,
- const WebFindOptions& options)
- : timer_(text_finder->OwnerFrame().GetFrame()->GetTaskRunner(
- TaskType::kInternalDefault),
- this,
- &DeferredScopeStringMatches::DoTimeout),
- text_finder_(text_finder),
+ IdleScopeStringMatchesCallback(TextFinder* text_finder,
+ int identifier,
+ const WebString& search_text,
+ const WebFindOptions& options)
+ : text_finder_(text_finder),
identifier_(identifier),
search_text_(search_text),
options_(options) {
- timer_.StartOneShot(TimeDelta(), FROM_HERE);
+ callback_handle_ =
+ text_finder->GetFrame()->GetDocument()->RequestIdleCallback(
+ this, IdleRequestOptions());
}
- void DoTimeout(TimerBase*) {
- text_finder_->ResumeScopingStringMatches(identifier_, search_text_,
- options_);
+ void invoke(IdleDeadline* deadline) override {
+ text_finder_->ResumeScopingStringMatches(deadline, identifier_,
+ search_text_, options_);
}
- TaskRunnerTimer<DeferredScopeStringMatches> timer_;
Member<TextFinder> text_finder_;
+ int callback_handle_ = 0;
const int identifier_;
const WebString search_text_;
const WebFindOptions options_;
@@ -136,11 +153,17 @@ bool TextFinder::Find(int identifier,
const WebFindOptions& options,
bool wrap_within_frame,
bool* active_now) {
- if (!options.find_next)
+ if (!options.find_next) {
+ // This find-in-page is redone due to the frame finishing loading.
+ // If we can, just reuse the old active match;
+ if (options.force && active_match_) {
+ should_locate_active_rect_ = true;
+ return true;
+ }
UnmarkAllTextMatches();
- else
+ } else {
SetMarkerActive(active_match_.Get(), false);
-
+ }
if (active_match_ &&
&active_match_->OwnerDocument() != OwnerFrame().GetFrame()->GetDocument())
active_match_ = nullptr;
@@ -164,9 +187,6 @@ bool TextFinder::Find(int identifier,
(options.forward ? 0 : kBackwards) |
(options.match_case ? 0 : kCaseInsensitive) |
(wrap_within_frame ? kWrapAround : 0) |
- (options.word_start ? kAtWordStarts : 0) |
- (options.medial_capital_as_word_start ? kTreatMedialCapitalAsWordStart
- : 0) |
(options.find_next ? 0 : kStartInSelection);
active_match_ = Editor::FindRangeOfString(
*OwnerFrame().GetFrame()->GetDocument(), search_text,
@@ -216,7 +236,7 @@ bool TextFinder::Find(int identifier,
// Find-next due to DOM alteration (that couldn't be set as active), so
// we set the flag to ask the scoping effort to find the active rect for
// us and report it back to the UI.
- locating_active_rect_ = true;
+ should_locate_active_rect_ = true;
} else {
if (!was_active_frame) {
if (options.forward)
@@ -343,7 +363,7 @@ void TextFinder::StopFindingAndClearSelection() {
// Remove all markers for matches found and turn off the highlighting.
OwnerFrame().GetFrame()->GetDocument()->Markers().RemoveMarkersOfTypes(
- DocumentMarker::kTextMatch);
+ DocumentMarker::MarkerTypes::TextMatch());
OwnerFrame().GetFrame()->GetEditor().SetMarkedTextMatchesAreHighlighted(
false);
ClearFindMatchesCache();
@@ -409,7 +429,8 @@ void TextFinder::StartScopingStringMatches(int identifier,
ScopeStringMatchesSoon(identifier, search_text, options);
}
-void TextFinder::ScopeStringMatches(int identifier,
+void TextFinder::ScopeStringMatches(IdleDeadline* deadline,
+ int identifier,
const WebString& search_text,
const WebFindOptions& options) {
if (!ShouldScopeMatches(search_text, options)) {
@@ -417,6 +438,9 @@ void TextFinder::ScopeStringMatches(int identifier,
return;
}
+ const TimeDelta time_available =
+ TimeDelta::FromMillisecondsD(deadline->timeRemaining());
+ const TimeTicks start_time = CurrentTimeTicks();
PositionInFlatTree search_start = PositionInFlatTree::FirstPositionInNode(
*OwnerFrame().GetFrame()->GetDocument());
PositionInFlatTree search_end = PositionInFlatTree::LastPositionInNode(
@@ -437,14 +461,8 @@ void TextFinder::ScopeStringMatches(int identifier,
// needs to be audited. see http://crbug.com/590369 for more details.
search_start.GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
- // This timeout controls how long we scope before releasing control. This
- // value does not prevent us from running for longer than this, but it is
- // periodically checked to see if we have exceeded our allocated time.
- const double kMaxScopingDuration = 0.1; // seconds
-
int match_count = 0;
bool full_range_searched = false;
- double start_time = CurrentTime();
PositionInFlatTree next_scoping_start;
do {
// Find next occurrence of the search string.
@@ -467,9 +485,10 @@ void TextFinder::ScopeStringMatches(int identifier,
// resultRange will be collapsed if the matched text spans over multiple
// TreeScopes. FIXME: Show such matches to users.
search_start = result.EndPosition();
- continue;
+ if (deadline->timeRemaining() > 0)
+ continue;
+ break;
}
-
++match_count;
// Catch a special case where Find found something but doesn't know what
@@ -477,7 +496,7 @@ void TextFinder::ScopeStringMatches(int identifier,
// as the active rect.
IntRect result_bounds = result_range->BoundingBox();
IntRect active_selection_rect;
- if (locating_active_rect_) {
+ if (should_locate_active_rect_) {
active_selection_rect =
active_match_.Get() ? active_match_->BoundingBox() : result_bounds;
}
@@ -487,14 +506,14 @@ void TextFinder::ScopeStringMatches(int identifier,
// find this rect during scoping it means we have found the active
// tickmark.
bool found_active_match = false;
- if (locating_active_rect_ && (active_selection_rect == result_bounds)) {
+ if (should_locate_active_rect_ && active_selection_rect == result_bounds) {
// We have found the active tickmark frame.
current_active_match_frame_ = true;
found_active_match = true;
// We also know which tickmark is active now.
active_match_index_ = total_match_count_ + match_count - 1;
// To stop looking for the active tickmark, we set this flag.
- locating_active_rect_ = false;
+ should_locate_active_rect_ = false;
// Notify browser of new location for the selected rectangle.
ReportFindInPageSelection(
@@ -517,7 +536,11 @@ void TextFinder::ScopeStringMatches(int identifier,
search_start = result.EndPosition();
next_scoping_start = search_start;
- } while (CurrentTime() - start_time < kMaxScopingDuration);
+ } while (deadline->timeRemaining() > 0);
+
+ const TimeDelta time_spent = CurrentTimeTicks() - start_time;
+ UMA_HISTOGRAM_TIMES("WebCore.FindInPage.ScopingTime",
+ time_spent - time_available);
if (next_scoping_start.IsNotNull()) {
resume_scoping_from_range_ =
@@ -577,9 +600,9 @@ void TextFinder::FinishCurrentScopingEffort(int identifier) {
}
void TextFinder::CancelPendingScopingEffort() {
- if (deferred_scoping_work_) {
- deferred_scoping_work_->Dispose();
- deferred_scoping_work_.Clear();
+ if (idle_scoping_callback_) {
+ idle_scoping_callback_->Dispose();
+ idle_scoping_callback_.Clear();
}
active_match_index_ = -1;
@@ -600,20 +623,17 @@ void TextFinder::IncreaseMatchCount(int identifier, int count) {
total_match_count_ += count;
// Update the UI with the latest findings.
- if (OwnerFrame().Client()) {
- OwnerFrame().Client()->ReportFindInPageMatchCount(
- identifier, total_match_count_, !frame_scoping_ || !total_match_count_);
- }
+ OwnerFrame().GetFindInPage()->ReportFindInPageMatchCount(
+ identifier, total_match_count_, !frame_scoping_ || !total_match_count_);
}
void TextFinder::ReportFindInPageSelection(const WebRect& selection_rect,
int active_match_ordinal,
int identifier) {
// Update the UI with the latest selection rect.
- if (OwnerFrame().Client()) {
- OwnerFrame().Client()->ReportFindInPageSelection(
- identifier, active_match_ordinal, selection_rect);
- }
+ OwnerFrame().GetFindInPage()->ReportFindInPageSelection(
+ identifier, active_match_ordinal, selection_rect,
+ false /* final_update */);
// Update accessibility too, so if the user commits to this query
// we can move accessibility focus to this result.
ReportFindInPageResultToAccessibility(identifier);
@@ -806,7 +826,7 @@ TextFinder::TextFinder(WebLocalFrameImpl& owner_frame)
find_request_identifier_(-1),
next_invalidate_after_(0),
find_match_markers_version_(0),
- locating_active_rect_(false),
+ should_locate_active_rect_(false),
scoping_in_progress_(false),
last_find_request_completed_with_no_matches_(false),
find_match_rects_are_valid_(false) {}
@@ -828,7 +848,7 @@ void TextFinder::UnmarkAllTextMatches() {
if (frame && frame->GetPage() &&
frame->GetEditor().MarkedTextMatchesAreHighlighted()) {
frame->GetDocument()->Markers().RemoveMarkersOfTypes(
- DocumentMarker::kTextMatch);
+ DocumentMarker::MarkerTypes::TextMatch());
}
}
@@ -868,17 +888,28 @@ bool TextFinder::ShouldScopeMatches(const String& search_text,
void TextFinder::ScopeStringMatchesSoon(int identifier,
const WebString& search_text,
const WebFindOptions& options) {
- DCHECK_EQ(deferred_scoping_work_, nullptr);
- deferred_scoping_work_ = DeferredScopeStringMatches::Create(
- this, identifier, search_text, options);
+ DCHECK_EQ(idle_scoping_callback_, nullptr);
+ // If it's for testing, run the scoping immediately.
+ // TODO(rakina): Change to use general solution when it's available.
+ // https://crbug.com/875203
+ if (options.run_synchronously_for_testing) {
+ ScopeStringMatches(
+ IdleDeadline::Create(CurrentTimeTicks() + kForcedInvocationDeadline,
+ IdleDeadline::CallbackType::kCalledWhenIdle),
+ identifier, search_text, options);
+ } else {
+ idle_scoping_callback_ = IdleScopeStringMatchesCallback::Create(
+ this, identifier, search_text, options);
+ }
}
-void TextFinder::ResumeScopingStringMatches(int identifier,
+void TextFinder::ResumeScopingStringMatches(IdleDeadline* deadline,
+ int identifier,
const WebString& search_text,
const WebFindOptions& options) {
- deferred_scoping_work_.Clear();
+ idle_scoping_callback_.Clear();
- ScopeStringMatches(identifier, search_text, options);
+ ScopeStringMatches(deadline, identifier, search_text, options);
}
void TextFinder::InvalidateIfNecessary() {
@@ -912,7 +943,7 @@ void TextFinder::Trace(blink::Visitor* visitor) {
visitor->Trace(owner_frame_);
visitor->Trace(active_match_);
visitor->Trace(resume_scoping_from_range_);
- visitor->Trace(deferred_scoping_work_);
+ visitor->Trace(idle_scoping_callback_);
visitor->Trace(find_matches_cache_);
}
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 1ae14d99cf9..9bea1754b33 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
@@ -41,6 +41,7 @@
namespace blink {
+class IdleDeadline;
class LocalFrame;
class Range;
class WebLocalFrameImpl;
@@ -127,8 +128,8 @@ class CORE_EXPORT TextFinder final
void Trace(blink::Visitor*);
private:
- class DeferredScopeStringMatches;
- friend class DeferredScopeStringMatches;
+ class IdleScopeStringMatchesCallback;
+ friend class IdleScopeStringMatchesCallback;
explicit TextFinder(WebLocalFrameImpl& owner_frame);
@@ -185,7 +186,8 @@ class CORE_EXPORT TextFinder final
// multiple frames to be searched at the same time and provides a way to
// cancel at any time (see cancelPendingScopingEffort). The parameter
// searchText specifies what to look for.
- void ScopeStringMatches(int identifier,
+ void ScopeStringMatches(IdleDeadline* deadline,
+ int identifier,
const WebString& search_text,
const WebFindOptions&);
@@ -194,8 +196,9 @@ class CORE_EXPORT TextFinder final
const WebString& search_text,
const WebFindOptions&);
- // Called by a DeferredScopeStringMatches instance.
- void ResumeScopingStringMatches(int identifier,
+ // Called by an IdleScopeStringMatchesCallback instance.
+ void ResumeScopingStringMatches(IdleDeadline* deadline,
+ int identifier,
const WebString& search_text,
const WebFindOptions&);
@@ -260,7 +263,7 @@ class CORE_EXPORT TextFinder final
int next_invalidate_after_;
// Pending call to scopeStringMatches.
- Member<DeferredScopeStringMatches> deferred_scoping_work_;
+ Member<IdleScopeStringMatchesCallback> idle_scoping_callback_;
// Version number incremented whenever this frame's find-in-page match
// markers change.
@@ -276,7 +279,7 @@ class CORE_EXPORT TextFinder final
// This flag is used by the scoping effort to determine if we need to figure
// out which rectangle is the active match. Once we find the active
// rectangle we clear this flag.
- bool locating_active_rect_;
+ bool should_locate_active_rect_;
// Keeps track of whether there is an scoping effort ongoing in the frame.
bool scoping_in_progress_;
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 289b62c4ba0..a5dcce03959 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
@@ -80,7 +80,7 @@ TEST_F(TextFinderTest, FindTextSimple) {
int identifier = 0;
WebString search_text(String("FindMe"));
- WebFindOptions find_options; // Default.
+ WebFindOptions find_options; // Default + add testing flag.
bool wrap_within_frame = true;
ASSERT_TRUE(GetTextFinder().Find(identifier, search_text, find_options,
@@ -153,7 +153,7 @@ TEST_F(TextFinderTest, FindTextAutosizing) {
int identifier = 0;
WebString search_text(String("FindMe"));
- WebFindOptions find_options; // Default.
+ WebFindOptions find_options; // Default + add testing flag.
bool wrap_within_frame = true;
// Set viewport scale to 20 in order to simulate zoom-in
@@ -193,7 +193,7 @@ TEST_F(TextFinderTest, FindTextNotFound) {
int identifier = 0;
WebString search_text(String("Boo"));
- WebFindOptions find_options; // Default.
+ WebFindOptions find_options; // Default + add testing flag.
bool wrap_within_frame = true;
EXPECT_FALSE(GetTextFinder().Find(identifier, search_text, find_options,
@@ -214,7 +214,7 @@ TEST_F(TextFinderTest, FindTextInShadowDOM) {
int identifier = 0;
WebString search_text(String("foo"));
- WebFindOptions find_options; // Default.
+ WebFindOptions find_options; // Default + add testing flag.
bool wrap_within_frame = true;
// TextIterator currently returns the matches in the flat treeorder, so
@@ -310,13 +310,12 @@ TEST_F(TextFinderTest, ScopeTextMatchesSimple) {
int identifier = 0;
WebString search_text(String("FindMe"));
- WebFindOptions find_options; // Default.
+ WebFindOptions find_options; // Default + add testing flag.
+ find_options.run_synchronously_for_testing = true;
GetTextFinder().ResetMatchCount();
GetTextFinder().StartScopingStringMatches(identifier, search_text,
find_options);
- while (GetTextFinder().ScopingInProgress())
- RunPendingTasks();
EXPECT_EQ(2, GetTextFinder().TotalMatchCount());
WebVector<WebFloatRect> match_rects = GetTextFinder().FindMatchRects();
@@ -344,15 +343,14 @@ TEST_F(TextFinderTest, ScopeTextMatchesRepeated) {
int identifier = 0;
WebString search_text1(String("XFindMe"));
WebString search_text2(String("FindMe"));
- WebFindOptions find_options; // Default.
+ WebFindOptions find_options; // Default + add testing flag.
+ find_options.run_synchronously_for_testing = true;
GetTextFinder().ResetMatchCount();
GetTextFinder().StartScopingStringMatches(identifier, search_text1,
find_options);
GetTextFinder().StartScopingStringMatches(identifier, search_text2,
find_options);
- while (GetTextFinder().ScopingInProgress())
- RunPendingTasks();
// Only searchText2 should be highlighted.
EXPECT_EQ(2, GetTextFinder().TotalMatchCount());
@@ -375,13 +373,12 @@ TEST_F(TextFinderTest, ScopeTextMatchesWithShadowDOM) {
int identifier = 0;
WebString search_text(String("fOO"));
- WebFindOptions find_options; // Default.
+ WebFindOptions find_options; // Default + add testing flag.
+ find_options.run_synchronously_for_testing = true;
GetTextFinder().ResetMatchCount();
GetTextFinder().StartScopingStringMatches(identifier, search_text,
find_options);
- while (GetTextFinder().ScopingInProgress())
- RunPendingTasks();
// TextIterator currently returns the matches in the flat tree order,
// so in this case the matches will be returned in the order of
@@ -405,13 +402,12 @@ TEST_F(TextFinderTest, ScopeRepeatPatternTextMatches) {
int identifier = 0;
WebString search_text(String("ab ab"));
- WebFindOptions find_options; // Default.
+ WebFindOptions find_options; // Default + add testing flag.
+ find_options.run_synchronously_for_testing = true;
GetTextFinder().ResetMatchCount();
GetTextFinder().StartScopingStringMatches(identifier, search_text,
find_options);
- while (GetTextFinder().ScopingInProgress())
- RunPendingTasks();
EXPECT_EQ(2, GetTextFinder().TotalMatchCount());
WebVector<WebFloatRect> match_rects = GetTextFinder().FindMatchRects();
@@ -428,13 +424,12 @@ TEST_F(TextFinderTest, OverlappingMatches) {
int identifier = 0;
WebString search_text(String("aba"));
- WebFindOptions find_options; // Default.
+ WebFindOptions find_options; // Default + add testing flag.
+ find_options.run_synchronously_for_testing = true;
GetTextFinder().ResetMatchCount();
GetTextFinder().StartScopingStringMatches(identifier, search_text,
find_options);
- while (GetTextFinder().ScopingInProgress())
- RunPendingTasks();
// We shouldn't find overlapped matches.
EXPECT_EQ(1, GetTextFinder().TotalMatchCount());
@@ -451,13 +446,12 @@ TEST_F(TextFinderTest, SequentialMatches) {
int identifier = 0;
WebString search_text(String("ab"));
- WebFindOptions find_options; // Default.
+ WebFindOptions find_options; // Default + add testing flag.
+ find_options.run_synchronously_for_testing = true;
GetTextFinder().ResetMatchCount();
GetTextFinder().StartScopingStringMatches(identifier, search_text,
find_options);
- while (GetTextFinder().ScopingInProgress())
- RunPendingTasks();
EXPECT_EQ(3, GetTextFinder().TotalMatchCount());
WebVector<WebFloatRect> match_rects = GetTextFinder().FindMatchRects();
@@ -473,15 +467,14 @@ TEST_F(TextFinderTest, FindTextJavaScriptUpdatesDOM) {
int identifier = 0;
WebString search_text(String("FindMe"));
- WebFindOptions find_options; // Default.
+ WebFindOptions find_options; // Default + add testing flag.
+ find_options.run_synchronously_for_testing = true;
bool wrap_within_frame = true;
bool active_now;
GetTextFinder().ResetMatchCount();
GetTextFinder().StartScopingStringMatches(identifier, search_text,
find_options);
- while (GetTextFinder().ScopingInProgress())
- RunPendingTasks();
find_options.find_next = true;
ASSERT_TRUE(GetTextFinder().Find(identifier, search_text, find_options,
@@ -511,8 +504,7 @@ TEST_F(TextFinderTest, FindTextJavaScriptUpdatesDOM) {
GetTextFinder().CancelPendingScopingEffort();
GetTextFinder().StartScopingStringMatches(identifier, search_text,
find_options);
- while (GetTextFinder().ScopingInProgress())
- RunPendingTasks();
+
EXPECT_EQ(2, GetTextFinder().TotalMatchCount());
WebVector<WebFloatRect> match_rects = GetTextFinder().FindMatchRects();
@@ -531,15 +523,14 @@ TEST_F(TextFinderTest, FindTextJavaScriptUpdatesDOMAfterNoMatches) {
int identifier = 0;
WebString search_text(String("FindMe"));
- WebFindOptions find_options; // Default.
+ WebFindOptions find_options; // Default + add testing flag.
+ find_options.run_synchronously_for_testing = true;
bool wrap_within_frame = true;
bool active_now = false;
GetTextFinder().ResetMatchCount();
GetTextFinder().StartScopingStringMatches(identifier, search_text,
find_options);
- while (GetTextFinder().ScopingInProgress())
- RunPendingTasks();
find_options.find_next = true;
ASSERT_FALSE(GetTextFinder().Find(identifier, search_text, find_options,
@@ -566,8 +557,7 @@ TEST_F(TextFinderTest, FindTextJavaScriptUpdatesDOMAfterNoMatches) {
GetTextFinder().CancelPendingScopingEffort();
GetTextFinder().StartScopingStringMatches(identifier, search_text,
find_options);
- while (GetTextFinder().ScopingInProgress())
- RunPendingTasks();
+
EXPECT_EQ(1, GetTextFinder().TotalMatchCount());
WebVector<WebFloatRect> match_rects = GetTextFinder().FindMatchRects();
@@ -615,7 +605,8 @@ TEST_F(TextFinderFakeTimerTest, ScopeWithTimeouts) {
GetDocument().UpdateStyleAndLayout();
int identifier = 0;
- WebFindOptions find_options; // Default.
+ WebFindOptions find_options; // Default + add testing flag.
+ find_options.run_synchronously_for_testing = true;
GetTextFinder().ResetMatchCount();
@@ -623,8 +614,6 @@ TEST_F(TextFinderFakeTimerTest, ScopeWithTimeouts) {
// of the TimeProxyPlatform timer is greater than timeout threshold.
GetTextFinder().StartScopingStringMatches(identifier, search_pattern,
find_options);
- while (GetTextFinder().ScopingInProgress())
- RunPendingTasks();
EXPECT_EQ(4, GetTextFinder().TotalMatchCount());
}
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 e2971565e29..ed727836c71 100644
--- a/chromium/third_party/blink/renderer/core/editing/frame_selection.cc
+++ b/chromium/third_party/blink/renderer/core/editing/frame_selection.cc
@@ -39,6 +39,7 @@
#include "third_party/blink/renderer/core/dom/text.h"
#include "third_party/blink/renderer/core/editing/caret_display_item_client.h"
#include "third_party/blink/renderer/core/editing/commands/typing_command.h"
+#include "third_party/blink/renderer/core/editing/editing_behavior.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"
@@ -294,7 +295,7 @@ void FrameSelection::DidSetSelectionDeprecated(
// The task source should be kDOMManipulation, but the spec doesn't say
// anything about this.
frame_->DomWindow()->EnqueueDocumentEvent(
- Event::Create(EventTypeNames::selectionchange),
+ *Event::Create(EventTypeNames::selectionchange),
TaskType::kMiscPlatformAPI);
}
@@ -333,7 +334,7 @@ static DispatchEventResult DispatchSelectStart(
return DispatchEventResult::kNotCanceled;
return select_start_target->DispatchEvent(
- Event::CreateCancelableBubble(EventTypeNames::selectstart));
+ *Event::CreateCancelableBubble(EventTypeNames::selectstart));
}
// The return value of |FrameSelection::modify()| is different based on
@@ -727,7 +728,7 @@ void FrameSelection::SelectAll(SetSelectionBy set_selection_by) {
if (select_start_target) {
const Document& expected_document = GetDocument();
- if (select_start_target->DispatchEvent(Event::CreateCancelableBubble(
+ if (select_start_target->DispatchEvent(*Event::CreateCancelableBubble(
EventTypeNames::selectstart)) != DispatchEventResult::kNotCanceled)
return;
// The frame may be detached due to selectstart event.
@@ -1228,17 +1229,6 @@ void FrameSelection::ClearDocumentCachedRange() {
selection_editor_->ClearDocumentCachedRange();
}
-base::Optional<unsigned> FrameSelection::LayoutSelectionStart() const {
- return layout_selection_->SelectionStart();
-}
-base::Optional<unsigned> FrameSelection::LayoutSelectionEnd() const {
- return layout_selection_->SelectionEnd();
-}
-
-void FrameSelection::ClearLayoutSelection() {
- layout_selection_->ClearSelection();
-}
-
LayoutSelectionStatus FrameSelection::ComputeLayoutSelectionStatus(
const NGPaintFragment& text_fragment) const {
return layout_selection_->ComputeSelectionStatus(text_fragment);
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 7b1ecd427d9..7e9257f0819 100644
--- a/chromium/third_party/blink/renderer/core/editing/frame_selection.h
+++ b/chromium/third_party/blink/renderer/core/editing/frame_selection.h
@@ -45,6 +45,7 @@ namespace blink {
class DisplayItemClient;
class Element;
class LayoutBlock;
+class LayoutText;
class LocalFrame;
class FrameCaret;
class GranularityStrategy;
@@ -77,6 +78,7 @@ enum class SelectSoftLineBreak { kNotSelected, kSelected };
struct LayoutSelectionStatus {
STACK_ALLOCATED();
+ public:
LayoutSelectionStatus(unsigned passed_start,
unsigned passed_end,
SelectSoftLineBreak passed_line_break)
@@ -93,6 +95,29 @@ struct LayoutSelectionStatus {
SelectSoftLineBreak line_break;
};
+enum class SelectionIncludeEnd { kInclude, kNotInclude };
+
+struct LayoutTextSelectionStatus {
+ STACK_ALLOCATED();
+
+ public:
+ LayoutTextSelectionStatus(unsigned passed_start,
+ unsigned passed_end,
+ SelectionIncludeEnd passed_include_end)
+ : start(passed_start), end(passed_end), include_end(passed_include_end) {
+ DCHECK_LE(start, end);
+ }
+ bool operator==(const LayoutTextSelectionStatus& other) const {
+ return start == other.start && end == other.end &&
+ include_end == other.include_end;
+ }
+ bool IsEmpty() const { return start == 0 && end == 0; }
+
+ unsigned start;
+ unsigned end;
+ SelectionIncludeEnd include_end;
+};
+
class CORE_EXPORT FrameSelection final
: public GarbageCollectedFinalized<FrameSelection>,
public SynchronousMutationObserver {
@@ -246,9 +271,8 @@ class CORE_EXPORT FrameSelection final
FrameCaret& FrameCaretForTesting() const { return *frame_caret_; }
- base::Optional<unsigned> LayoutSelectionStart() const;
- base::Optional<unsigned> LayoutSelectionEnd() const;
- void ClearLayoutSelection();
+ LayoutTextSelectionStatus ComputeLayoutSelectionStatus(
+ const LayoutText& text) const;
LayoutSelectionStatus ComputeLayoutSelectionStatus(
const NGPaintFragment&) const;
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 928567b6975..77eab39f4d9 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
@@ -51,8 +51,8 @@ class FrameSelectionTest : public EditingTestBase {
}
Text* AppendTextNode(const String& data);
- int LayoutCount() const {
- return GetDummyPageHolder().GetFrameView().LayoutCount();
+ unsigned LayoutCount() const {
+ return GetDummyPageHolder().GetFrameView().LayoutCountForTesting();
}
PositionWithAffinity CaretPosition() const {
@@ -133,7 +133,7 @@ TEST_F(FrameSelectionTest, PaintCaretShouldNotLayout) {
EXPECT_TRUE(ToLayoutBlock(GetDocument().body()->GetLayoutObject())
->ShouldPaintCursorCaret());
- int start_count = LayoutCount();
+ unsigned start_count = LayoutCount();
{
// To force layout in next updateLayout calling, widen view.
LocalFrameView& frame_view = GetDummyPageHolder().GetFrameView();
diff --git a/chromium/third_party/blink/renderer/core/editing/granularity_strategy.cc b/chromium/third_party/blink/renderer/core/editing/granularity_strategy.cc
index c6e06db17c5..0acec8634c1 100644
--- a/chromium/third_party/blink/renderer/core/editing/granularity_strategy.cc
+++ b/chromium/third_party/blink/renderer/core/editing/granularity_strategy.cc
@@ -11,6 +11,7 @@
#include "third_party/blink/renderer/core/editing/visible_position.h"
#include "third_party/blink/renderer/core/editing/visible_selection.h"
#include "third_party/blink/renderer/core/editing/visible_units.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
namespace blink {
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 c1f8fd068d1..8f33fe2c5c0 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
@@ -41,11 +41,7 @@ class GranularityStrategyTest : public PageTestBase {
protected:
void SetUp() override;
- void SetSelectionAndEndTyping(const VisibleSelection&);
Text* AppendTextNode(const String& data);
- int LayoutCount() const {
- return GetDummyPageHolder().GetFrameView().LayoutCount();
- }
void SetInnerHTML(const char*);
// Parses the text node, appending the info to m_letterPos and m_wordMiddles.
void ParseText(Text*);
@@ -88,11 +84,6 @@ void GranularityStrategyTest::SetUp() {
GetFrame().GetSettings()->SetSelectionStrategy(SelectionStrategy::kDirection);
}
-void GranularityStrategyTest::SetSelectionAndEndTyping(
- const VisibleSelection& new_selection) {
- Selection().SetSelectionAndEndTyping(new_selection.AsSelection());
-}
-
Text* GranularityStrategyTest::AppendTextNode(const String& data) {
Text* text = GetDocument().createTextNode(data);
GetDocument().body()->AppendChild(text);
@@ -262,8 +253,9 @@ void GranularityStrategyTest::SetupTextSpan(String str1,
else
p2 = Position(text3, sel_end - str1.length() - str2.length());
- Selection().SetSelectionAndEndTyping(
- SelectionInDOMTree::Builder().SetBaseAndExtent(p1, p2).Build());
+ Selection().SetSelection(
+ SelectionInDOMTree::Builder().SetBaseAndExtent(p1, p2).Build(),
+ SetSelectionOptions());
}
void GranularityStrategyTest::SetupVerticalAlign(String str1,
@@ -489,10 +481,11 @@ TEST_F(GranularityStrategyTest, Character) {
// "Foo B^a|>r Baz," (^ means base, | means extent, , < means start, and >
// means end).
- Selection().SetSelectionAndEndTyping(
+ Selection().SetSelection(
SelectionInDOMTree::Builder()
.SetBaseAndExtent(Position(text, 5), Position(text, 6))
- .Build());
+ .Build(),
+ SetSelectionOptions());
EXPECT_EQ_SELECTED_TEXT("a");
// "Foo B^ar B|>az,"
Selection().MoveRangeSelectionExtent(
@@ -510,10 +503,11 @@ TEST_F(GranularityStrategyTest, DirectionRotate) {
Text* text = SetupRotate("Foo Bar Baz,");
// "Foo B^a|>r Baz," (^ means base, | means extent, , < means start, and >
// means end).
- Selection().SetSelectionAndEndTyping(
+ Selection().SetSelection(
SelectionInDOMTree::Builder()
.SetBaseAndExtent(Position(text, 5), Position(text, 6))
- .Build());
+ .Build(),
+ SetSelectionOptions());
EXPECT_EQ_SELECTED_TEXT("a");
IntPoint p = letter_pos_[9];
// Need to move by one pixel, otherwise this point is not evaluated
@@ -533,10 +527,11 @@ TEST_F(GranularityStrategyTest, DirectionExpandTranslateZ) {
Text* text = SetupTranslateZ("abcdef ghij kl mnopqr stuvwi inm mnii,");
// "abcdef ghij kl mno^p|>qr stuvwi inm mnii," (^ means base, | means extent,
// < means start, and > means end).
- Selection().SetSelectionAndEndTyping(
+ Selection().SetSelection(
SelectionInDOMTree::Builder()
.SetBaseAndExtent(Position(text, 18), Position(text, 19))
- .Build());
+ .Build(),
+ SetSelectionOptions());
EXPECT_EQ_SELECTED_TEXT("p");
TestDirectionExpand();
}
@@ -545,10 +540,11 @@ TEST_F(GranularityStrategyTest, DirectionExpandTransform) {
Text* text = SetupTransform("abcdef ghij kl mnopqr stuvwi inm mnii,");
// "abcdef ghij kl mno^p|>qr stuvwi inm mnii," (^ means base, | means extent,
// < means start, and > means end).
- Selection().SetSelectionAndEndTyping(
+ Selection().SetSelection(
SelectionInDOMTree::Builder()
.SetBaseAndExtent(Position(text, 18), Position(text, 19))
- .Build());
+ .Build(),
+ SetSelectionOptions());
EXPECT_EQ_SELECTED_TEXT("p");
TestDirectionExpand();
}
@@ -569,20 +565,22 @@ TEST_F(GranularityStrategyTest, DirectionExpandFontSizes) {
TEST_F(GranularityStrategyTest, DirectionShrinkTranslateZ) {
Text* text = SetupTranslateZ("abcdef ghij kl mnopqr iiinmni, abc");
- Selection().SetSelectionAndEndTyping(
+ Selection().SetSelection(
SelectionInDOMTree::Builder()
.SetBaseAndExtent(Position(text, 18), Position(text, 21))
- .Build());
+ .Build(),
+ SetSelectionOptions());
EXPECT_EQ_SELECTED_TEXT("pqr");
TestDirectionShrink();
}
TEST_F(GranularityStrategyTest, DirectionShrinkTransform) {
Text* text = SetupTransform("abcdef ghij kl mnopqr iiinmni, abc");
- Selection().SetSelectionAndEndTyping(
+ Selection().SetSelection(
SelectionInDOMTree::Builder()
.SetBaseAndExtent(Position(text, 18), Position(text, 21))
- .Build());
+ .Build(),
+ SetSelectionOptions());
EXPECT_EQ_SELECTED_TEXT("pqr");
TestDirectionShrink();
}
@@ -601,20 +599,22 @@ TEST_F(GranularityStrategyTest, DirectionShrinkFontSizes) {
TEST_F(GranularityStrategyTest, DirectionSwitchSideTranslateZ) {
Text* text = SetupTranslateZ("abcd efgh ijkl mnopqr iiinmni, abc");
- Selection().SetSelectionAndEndTyping(
+ Selection().SetSelection(
SelectionInDOMTree::Builder()
.SetBaseAndExtent(Position(text, 18), Position(text, 21))
- .Build());
+ .Build(),
+ SetSelectionOptions());
EXPECT_EQ_SELECTED_TEXT("pqr");
TestDirectionSwitchSide();
}
TEST_F(GranularityStrategyTest, DirectionSwitchSideTransform) {
Text* text = SetupTransform("abcd efgh ijkl mnopqr iiinmni, abc");
- Selection().SetSelectionAndEndTyping(
+ Selection().SetSelection(
SelectionInDOMTree::Builder()
.SetBaseAndExtent(Position(text, 18), Position(text, 21))
- .Build());
+ .Build(),
+ SetSelectionOptions());
EXPECT_EQ_SELECTED_TEXT("pqr");
TestDirectionSwitchSide();
}
@@ -646,10 +646,11 @@ TEST_F(GranularityStrategyTest, DirectionSwitchSideWordGranularityThenShrink) {
// "abcd efgh ijkl mno^pqr|> iiin, abc" (^ means base, | means extent, < means
// start, and > means end).
- Selection().SetSelectionAndEndTyping(
+ Selection().SetSelection(
SelectionInDOMTree::Builder()
.SetBaseAndExtent(Position(text, 18), Position(text, 21))
- .Build());
+ .Build(),
+ SetSelectionOptions());
EXPECT_EQ_SELECTED_TEXT("pqr");
// Move to the middle of word #4 selecting it - this will set the offset to
// be half the width of "iiin".
@@ -684,10 +685,11 @@ TEST_F(GranularityStrategyTest, DirectionSwitchStartOnBoundary) {
// "ab cd efghijkl ^mnopqr |>stuvwi inm," (^ means base and | means extent,
// > means end).
- Selection().SetSelectionAndEndTyping(
+ Selection().SetSelection(
SelectionInDOMTree::Builder()
.SetBaseAndExtent(Position(text, 15), Position(text, 22))
- .Build());
+ .Build(),
+ SetSelectionOptions());
EXPECT_EQ_SELECTED_TEXT("mnopqr ");
Selection().MoveRangeSelectionExtent(word_middles_[4]);
EXPECT_EQ_SELECTED_TEXT("mnopqr iiin");
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 12251e0d5fc..0926bb93a7e 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
@@ -13,7 +13,7 @@ ImeTextSpan::ImeTextSpan(Type type,
unsigned start_offset,
unsigned end_offset,
const Color& underline_color,
- ui::mojom::ImeTextSpanThickness thickness,
+ ws::mojom::ImeTextSpanThickness thickness,
const Color& background_color,
const Color& suggestion_highlight_color,
const Vector<String>& suggestions)
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 ea3c5047627..23bc5969889 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
@@ -26,7 +26,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_IME_IME_TEXT_SPAN_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_IME_IME_TEXT_SPAN_H_
-#include "services/ui/public/interfaces/ime/ime.mojom-shared.h"
+#include "services/ws/public/mojom/ime/ime.mojom-shared.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/graphics/color.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
@@ -47,7 +47,7 @@ class CORE_EXPORT ImeTextSpan {
unsigned start_offset,
unsigned end_offset,
const Color& underline_color,
- ui::mojom::ImeTextSpanThickness,
+ ws::mojom::ImeTextSpanThickness,
const Color& background_color,
const Color& suggestion_highlight_color = Color::kTransparent,
const Vector<String>& suggestions = Vector<String>());
@@ -58,7 +58,7 @@ class CORE_EXPORT ImeTextSpan {
unsigned StartOffset() const { return start_offset_; }
unsigned EndOffset() const { return end_offset_; }
const Color& UnderlineColor() const { return underline_color_; }
- ui::mojom::ImeTextSpanThickness Thickness() const { return thickness_; }
+ ws::mojom::ImeTextSpanThickness Thickness() const { return thickness_; }
const Color& BackgroundColor() const { return background_color_; }
const Color& SuggestionHighlightColor() const {
return suggestion_highlight_color_;
@@ -70,7 +70,7 @@ class CORE_EXPORT ImeTextSpan {
unsigned start_offset_;
unsigned end_offset_;
Color underline_color_;
- ui::mojom::ImeTextSpanThickness thickness_;
+ ws::mojom::ImeTextSpanThickness thickness_;
Color background_color_;
Color suggestion_highlight_color_;
Vector<String> suggestions_;
diff --git a/chromium/third_party/blink/renderer/core/editing/ime/ime_text_span_test.cc b/chromium/third_party/blink/renderer/core/editing/ime/ime_text_span_test.cc
index 6118240220a..d8e1764ade3 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
@@ -12,7 +12,7 @@ namespace {
ImeTextSpan CreateImeTextSpan(unsigned start_offset, unsigned end_offset) {
return ImeTextSpan(ImeTextSpan::Type::kComposition, start_offset, end_offset,
Color::kTransparent,
- ui::mojom::ImeTextSpanThickness::kNone,
+ ws::mojom::ImeTextSpanThickness::kNone,
Color::kTransparent);
}
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 484f9b7237b..b28cb1f6c82 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
@@ -28,6 +28,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/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"
@@ -46,6 +47,7 @@
#include "third_party/blink/renderer/core/editing/state_machines/backward_code_point_state_machine.h"
#include "third_party/blink/renderer/core/editing/state_machines/forward_code_point_state_machine.h"
#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/html/forms/html_input_element.h"
#include "third_party/blink/renderer/core/html/forms/html_text_area_element.h"
@@ -68,7 +70,7 @@ void DispatchCompositionUpdateEvent(LocalFrame& frame, const String& text) {
CompositionEvent* event = CompositionEvent::Create(
EventTypeNames::compositionupdate, frame.DomWindow(), text);
- target->DispatchEvent(event);
+ target->DispatchEvent(*event);
}
void DispatchCompositionEndEvent(LocalFrame& frame, const String& text) {
@@ -83,7 +85,7 @@ void DispatchCompositionEndEvent(LocalFrame& frame, const String& text) {
CompositionEvent* event = CompositionEvent::Create(
EventTypeNames::compositionend, frame.DomWindow(), text);
- EventDispatcher::DispatchScopedEvent(*target, event);
+ EventDispatcher::DispatchScopedEvent(*target, *event);
}
bool NeedsIncrementalInsertion(const LocalFrame& frame,
@@ -110,7 +112,7 @@ void DispatchBeforeInputFromComposition(EventTarget* target,
InputEvent* before_input_event = InputEvent::CreateBeforeInput(
input_type, data, InputEvent::kNotCancelable,
InputEvent::EventIsComposing::kIsComposing, nullptr);
- target->DispatchEvent(before_input_event);
+ target->DispatchEvent(*before_input_event);
}
// Used to insert/replace text during composition update and confirm
@@ -396,7 +398,8 @@ void InputMethodController::Clear() {
composition_range_->setStart(&GetDocument(), 0);
composition_range_->collapse(true);
}
- GetDocument().Markers().RemoveMarkersOfTypes(DocumentMarker::kComposition);
+ GetDocument().Markers().RemoveMarkersOfTypes(
+ DocumentMarker::MarkerTypes::Composition());
}
void InputMethodController::ContextDestroyed(Document*) {
@@ -734,7 +737,7 @@ bool InputMethodController::DispatchCompositionStartEvent(const String& text) {
CompositionEvent* event = CompositionEvent::Create(
EventTypeNames::compositionstart, GetFrame().DomWindow(), text);
- target->DispatchEvent(event);
+ target->DispatchEvent(*event);
return IsAvailable();
}
@@ -905,7 +908,7 @@ void InputMethodController::SetComposition(
if (ime_text_spans.IsEmpty()) {
GetDocument().Markers().AddCompositionMarker(
CompositionEphemeralRange(), Color::kTransparent,
- ui::mojom::ImeTextSpanThickness::kThin,
+ ws::mojom::ImeTextSpanThickness::kThin,
LayoutTheme::GetTheme().PlatformDefaultCompositionBackgroundColor());
return;
}
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 700b09a46ad..34fefa1e1e5 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
@@ -23,7 +23,7 @@
#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"
-using ui::mojom::ImeTextSpanThickness;
+using ws::mojom::ImeTextSpanThickness;
namespace blink {
@@ -1029,7 +1029,7 @@ TEST_F(InputMethodControllerTest,
"sample");
Controller().SetEditableSelectionOffsets(PlainTextRange(17, 17));
- EXPECT_STREQ("hello\nworld\n0123456789", div->innerText().Utf8().data());
+ EXPECT_STREQ("hello\nworld\n\n0123456789", div->innerText().Utf8().data());
EXPECT_EQ(17u, Controller().GetSelectionOffsets().Start());
EXPECT_EQ(17u, Controller().GetSelectionOffsets().End());
@@ -1039,79 +1039,79 @@ TEST_F(InputMethodControllerTest,
ImeTextSpanThickness::kThin, 0));
// The caret exceeds left boundary.
- // "*hello\nworld\n01234AB56789", where * stands for caret.
+ // "*hello\nworld\n\n01234AB56789", where * stands for caret.
Controller().SetComposition("AB", ime_text_spans, -100, -100);
- EXPECT_STREQ("hello\nworld\n01234AB56789", div->innerText().Utf8().data());
+ EXPECT_STREQ("hello\nworld\n\n01234AB56789", div->innerText().Utf8().data());
EXPECT_EQ(0u, Controller().GetSelectionOffsets().Start());
EXPECT_EQ(0u, Controller().GetSelectionOffsets().End());
// The caret is on left boundary.
- // "*hello\nworld\n01234AB56789".
+ // "*hello\nworld\n\n01234AB56789".
Controller().SetComposition("AB", ime_text_spans, -17, -17);
- EXPECT_STREQ("hello\nworld\n01234AB56789", div->innerText().Utf8().data());
+ EXPECT_STREQ("hello\nworld\n\n01234AB56789", div->innerText().Utf8().data());
EXPECT_EQ(0u, Controller().GetSelectionOffsets().Start());
EXPECT_EQ(0u, Controller().GetSelectionOffsets().End());
// The caret is in the 1st node.
- // "he*llo\nworld\n01234AB56789".
+ // "he*llo\nworld\n\n01234AB56789".
Controller().SetComposition("AB", ime_text_spans, -15, -15);
- EXPECT_STREQ("hello\nworld\n01234AB56789", div->innerText().Utf8().data());
+ EXPECT_STREQ("hello\nworld\n\n01234AB56789", div->innerText().Utf8().data());
EXPECT_EQ(2u, Controller().GetSelectionOffsets().Start());
EXPECT_EQ(2u, Controller().GetSelectionOffsets().End());
// The caret is on right boundary of the 1st node.
- // "hello*\nworld\n01234AB56789".
+ // "hello*\nworld\n\n01234AB56789".
Controller().SetComposition("AB", ime_text_spans, -12, -12);
- EXPECT_STREQ("hello\nworld\n01234AB56789", div->innerText().Utf8().data());
+ EXPECT_STREQ("hello\nworld\n\n01234AB56789", div->innerText().Utf8().data());
EXPECT_EQ(5u, Controller().GetSelectionOffsets().Start());
EXPECT_EQ(5u, Controller().GetSelectionOffsets().End());
// The caret is on right boundary of the 2nd node.
- // "hello\n*world\n01234AB56789".
+ // "hello\n*world\n\n01234AB56789".
Controller().SetComposition("AB", ime_text_spans, -11, -11);
- EXPECT_STREQ("hello\nworld\n01234AB56789", div->innerText().Utf8().data());
+ EXPECT_STREQ("hello\nworld\n\n01234AB56789", div->innerText().Utf8().data());
EXPECT_EQ(6u, Controller().GetSelectionOffsets().Start());
EXPECT_EQ(6u, Controller().GetSelectionOffsets().End());
// The caret is on right boundary of the 3rd node.
// "hello\nworld*\n01234AB56789".
Controller().SetComposition("AB", ime_text_spans, -6, -6);
- EXPECT_STREQ("hello\nworld\n01234AB56789", div->innerText().Utf8().data());
+ EXPECT_STREQ("hello\nworld\n\n01234AB56789", div->innerText().Utf8().data());
EXPECT_EQ(11u, Controller().GetSelectionOffsets().Start());
EXPECT_EQ(11u, Controller().GetSelectionOffsets().End());
// The caret is on right boundary of the 4th node.
// "hello\nworld\n*01234AB56789".
Controller().SetComposition("AB", ime_text_spans, -5, -5);
- EXPECT_STREQ("hello\nworld\n01234AB56789", div->innerText().Utf8().data());
+ EXPECT_STREQ("hello\nworld\n\n01234AB56789", div->innerText().Utf8().data());
EXPECT_EQ(12u, Controller().GetSelectionOffsets().Start());
EXPECT_EQ(12u, Controller().GetSelectionOffsets().End());
// The caret is before the composing text.
- // "hello\nworld\n01234*AB56789".
+ // "hello\nworld\n\n01234*AB56789".
Controller().SetComposition("AB", ime_text_spans, 0, 0);
- EXPECT_STREQ("hello\nworld\n01234AB56789", div->innerText().Utf8().data());
+ EXPECT_STREQ("hello\nworld\n\n01234AB56789", div->innerText().Utf8().data());
EXPECT_EQ(17u, Controller().GetSelectionOffsets().Start());
EXPECT_EQ(17u, Controller().GetSelectionOffsets().End());
// The caret is after the composing text.
- // "hello\nworld\n01234AB*56789".
+ // "hello\nworld\n\n01234AB*56789".
Controller().SetComposition("AB", ime_text_spans, 2, 2);
- EXPECT_STREQ("hello\nworld\n01234AB56789", div->innerText().Utf8().data());
+ EXPECT_STREQ("hello\nworld\n\n01234AB56789", div->innerText().Utf8().data());
EXPECT_EQ(19u, Controller().GetSelectionOffsets().Start());
EXPECT_EQ(19u, Controller().GetSelectionOffsets().End());
// The caret is on right boundary.
- // "hello\nworld\n01234AB56789*".
+ // "hello\nworld\n\n01234AB56789*".
Controller().SetComposition("AB", ime_text_spans, 7, 7);
- EXPECT_STREQ("hello\nworld\n01234AB56789", div->innerText().Utf8().data());
+ EXPECT_STREQ("hello\nworld\n\n01234AB56789", div->innerText().Utf8().data());
EXPECT_EQ(24u, Controller().GetSelectionOffsets().Start());
EXPECT_EQ(24u, Controller().GetSelectionOffsets().End());
// The caret exceeds right boundary.
- // "hello\nworld\n01234AB56789*".
+ // "hello\nworld\n\n01234AB56789*".
Controller().SetComposition("AB", ime_text_spans, 100, 100);
- EXPECT_STREQ("hello\nworld\n01234AB56789", div->innerText().Utf8().data());
+ EXPECT_STREQ("hello\nworld\n\n01234AB56789", div->innerText().Utf8().data());
EXPECT_EQ(24u, Controller().GetSelectionOffsets().Start());
EXPECT_EQ(24u, Controller().GetSelectionOffsets().End());
}
@@ -1477,14 +1477,16 @@ TEST_F(InputMethodControllerTest, ImeTextSpanAppearsCorrectlyAfterNewline) {
PlainTextRange(2).CreateRange(*div).StartPosition();
const Position& second_line_position =
PlainTextRange(8).CreateRange(*div).StartPosition();
- ASSERT_EQ(0u, GetDocument()
- .Markers()
- .MarkersFor(first_line_position.ComputeContainerNode())
- .size());
- ASSERT_EQ(1u, GetDocument()
- .Markers()
- .MarkersFor(second_line_position.ComputeContainerNode())
- .size());
+ ASSERT_EQ(0u,
+ GetDocument()
+ .Markers()
+ .MarkersFor(ToText(*first_line_position.ComputeContainerNode()))
+ .size());
+ ASSERT_EQ(
+ 1u, GetDocument()
+ .Markers()
+ .MarkersFor(ToText(*second_line_position.ComputeContainerNode()))
+ .size());
// Verify marker has correct start/end offsets (measured from the beginning
// of the node, which is the beginning of the line)
@@ -1624,7 +1626,9 @@ TEST_F(InputMethodControllerTest,
// Check that the marker is still attached to "text" and doesn't include
// either space around it
- EXPECT_EQ(1u, GetDocument().Markers().MarkersFor(div->firstChild()).size());
+ EXPECT_EQ(
+ 1u,
+ GetDocument().Markers().MarkersFor(ToText(*div->firstChild())).size());
EXPECT_STREQ("text",
GetMarkedText(GetDocument().Markers(), div->firstChild(), 0)
.Utf8()
@@ -2406,17 +2410,19 @@ TEST_F(InputMethodControllerTest, CompositionUnderlineSpansMultipleNodes) {
Controller().SetComposition("test", ime_text_spans, 0, 4);
Node* b = div->firstChild();
- Node* text1 = b->firstChild();
- Node* text2 = b->nextSibling();
+ Text* text1 = ToText(b->firstChild());
+ Text* text2 = ToText(b->nextSibling());
const DocumentMarkerVector& text1_markers =
- GetDocument().Markers().MarkersFor(text1, DocumentMarker::kComposition);
+ GetDocument().Markers().MarkersFor(
+ *text1, DocumentMarker::MarkerTypes::Composition());
EXPECT_EQ(1u, text1_markers.size());
EXPECT_EQ(0u, text1_markers[0]->StartOffset());
EXPECT_EQ(1u, text1_markers[0]->EndOffset());
const DocumentMarkerVector& text2_markers =
- GetDocument().Markers().MarkersFor(text2, DocumentMarker::kComposition);
+ GetDocument().Markers().MarkersFor(
+ *text2, DocumentMarker::MarkerTypes::Composition());
EXPECT_EQ(1u, text2_markers.size());
EXPECT_EQ(0u, text2_markers[0]->StartOffset());
EXPECT_EQ(3u, text2_markers[0]->EndOffset());
diff --git a/chromium/third_party/blink/renderer/core/editing/inline_box_position.cc b/chromium/third_party/blink/renderer/core/editing/inline_box_position.cc
index 18852bacfc0..ec1407bad56 100644
--- a/chromium/third_party/blink/renderer/core/editing/inline_box_position.cc
+++ b/chromium/third_party/blink/renderer/core/editing/inline_box_position.cc
@@ -45,6 +45,8 @@ namespace blink {
namespace {
+const int kBlockFlowAdjustmentMaxRecursionDepth = 1024;
+
bool IsNonTextLeafChild(LayoutObject* object) {
if (object->SlowFirstChild())
return false;
@@ -187,11 +189,19 @@ InlineBoxPosition ComputeInlineBoxPositionForAtomicInline(
template <typename Strategy>
PositionWithAffinityTemplate<Strategy> ComputeInlineAdjustedPositionAlgorithm(
- const PositionWithAffinityTemplate<Strategy>&);
+ const PositionWithAffinityTemplate<Strategy>&,
+ int recursion_depth);
template <typename Strategy>
PositionWithAffinityTemplate<Strategy> AdjustBlockFlowPositionToInline(
- const PositionTemplate<Strategy>& position) {
+ const PositionTemplate<Strategy>& position,
+ int recursion_depth) {
+ if (recursion_depth >= kBlockFlowAdjustmentMaxRecursionDepth) {
+ // TODO(editing-dev): This function enters infinite recursion in some cases.
+ // Find the root cause and fix it. See https://crbug.com/857266
+ return PositionWithAffinityTemplate<Strategy>();
+ }
+
// Try a visually equivalent position with possibly opposite editability. This
// helps in case |position| is in an editable block but surrounded by
// non-editable positions. It acts to negate the logic at the beginning of
@@ -201,7 +211,8 @@ PositionWithAffinityTemplate<Strategy> AdjustBlockFlowPositionToInline(
if (downstream_equivalent != position) {
return ComputeInlineAdjustedPositionAlgorithm(
PositionWithAffinityTemplate<Strategy>(downstream_equivalent,
- TextAffinity::kUpstream));
+ TextAffinity::kUpstream),
+ recursion_depth + 1);
}
const PositionTemplate<Strategy>& upstream_equivalent =
UpstreamIgnoringEditingBoundaries(position);
@@ -211,12 +222,14 @@ PositionWithAffinityTemplate<Strategy> AdjustBlockFlowPositionToInline(
return ComputeInlineAdjustedPositionAlgorithm(
PositionWithAffinityTemplate<Strategy>(upstream_equivalent,
- TextAffinity::kUpstream));
+ TextAffinity::kUpstream),
+ recursion_depth + 1);
}
template <typename Strategy>
PositionWithAffinityTemplate<Strategy> ComputeInlineAdjustedPositionAlgorithm(
- const PositionWithAffinityTemplate<Strategy>& position) {
+ const PositionWithAffinityTemplate<Strategy>& position,
+ int recursion_depth) {
// TODO(yoichio): We don't assume |position| is canonicalized no longer and
// there are few cases failing to compute. Fix it: crbug.com/812535.
DCHECK(!position.AnchorNode()->IsShadowRoot()) << position;
@@ -233,7 +246,8 @@ PositionWithAffinityTemplate<Strategy> ComputeInlineAdjustedPositionAlgorithm(
if (layout_object.IsLayoutBlockFlow() &&
CanHaveChildrenForEditing(position.AnchorNode()) &&
HasRenderedNonAnonymousDescendantsWithHeight(&layout_object)) {
- return AdjustBlockFlowPositionToInline(position.GetPosition());
+ return AdjustBlockFlowPositionToInline(position.GetPosition(),
+ recursion_depth);
}
// TODO(crbug.com/567964): Change the second operand to DCHECK once fixed.
@@ -350,19 +364,19 @@ InlineBoxPosition ComputeInlineBoxPosition(const VisiblePosition& position) {
PositionWithAffinity ComputeInlineAdjustedPosition(
const PositionWithAffinity& position) {
- return ComputeInlineAdjustedPositionAlgorithm(position);
+ return ComputeInlineAdjustedPositionAlgorithm(position, 0);
}
PositionInFlatTreeWithAffinity ComputeInlineAdjustedPosition(
const PositionInFlatTreeWithAffinity& position) {
- return ComputeInlineAdjustedPositionAlgorithm(position);
+ return ComputeInlineAdjustedPositionAlgorithm(position, 0);
}
PositionWithAffinity ComputeInlineAdjustedPosition(
const VisiblePosition& position) {
DCHECK(position.IsValid()) << position;
return ComputeInlineAdjustedPositionAlgorithm(
- position.ToPositionWithAffinity());
+ position.ToPositionWithAffinity(), 0);
}
InlineBoxPosition ComputeInlineBoxPositionForInlineAdjustedPosition(
diff --git a/chromium/third_party/blink/renderer/core/editing/inline_box_position.h b/chromium/third_party/blink/renderer/core/editing/inline_box_position.h
index bc473b241bd..a95fd02f0f3 100644
--- a/chromium/third_party/blink/renderer/core/editing/inline_box_position.h
+++ b/chromium/third_party/blink/renderer/core/editing/inline_box_position.h
@@ -43,8 +43,9 @@ enum class UnicodeBidi : unsigned;
struct InlineBoxPosition {
STACK_ALLOCATED();
- const InlineBox* const inline_box;
- const int offset_in_box;
+ public:
+ const InlineBox* inline_box;
+ int offset_in_box;
InlineBoxPosition() : inline_box(nullptr), offset_in_box(0) {}
diff --git a/chromium/third_party/blink/renderer/core/editing/iterators/search_buffer.cc b/chromium/third_party/blink/renderer/core/editing/iterators/search_buffer.cc
index 8a66dd124ee..c1bca6a3346 100644
--- a/chromium/third_party/blink/renderer/core/editing/iterators/search_buffer.cc
+++ b/chromium/third_party/blink/renderer/core/editing/iterators/search_buffer.cc
@@ -56,7 +56,7 @@ inline SearchBuffer::SearchBuffer(const String& target, FindOptions options)
prefix_length_(0),
number_of_characters_just_appended_(0),
at_break_(true),
- needs_more_context_(options & kAtWordStarts),
+ needs_more_context_(options & kWholeWord),
target_requires_kana_workaround_(ContainsKanaLetters(target)) {
DCHECK(!target.IsEmpty()) << target;
target.AppendTo(target_);
@@ -72,14 +72,14 @@ inline SearchBuffer::SearchBuffer(const String& target, FindOptions options)
std::max(target_length * 8, kMinimumSearchBufferSize));
overlap_ = buffer_.capacity() / 4;
- if ((options_ & kAtWordStarts) && target_length) {
+ if ((options_ & kWholeWord) && target_length) {
const UChar32 target_first_character =
GetCodePointAt(target_.data(), 0, target_length);
// Characters in the separator category never really occur at the beginning
// of a word, so if the target begins with such a character, we just ignore
// the AtWordStart option.
if (IsSeparator(target_first_character)) {
- options_ &= ~kAtWordStarts;
+ options_ &= ~kWholeWord;
needs_more_context_ = false;
}
}
@@ -176,7 +176,7 @@ inline bool SearchBuffer::IsBadMatch(const UChar* match,
}
inline bool SearchBuffer::IsWordStartMatch(size_t start, size_t length) const {
- DCHECK(options_ & kAtWordStarts);
+ DCHECK(options_ & kWholeWord);
if (!start)
return true;
@@ -185,41 +185,6 @@ inline bool SearchBuffer::IsWordStartMatch(size_t start, size_t length) const {
int offset = start;
UChar32 first_character = GetCodePointAt(buffer_.data(), offset, size);
- if (options_ & kTreatMedialCapitalAsWordStart) {
- UChar32 previous_character;
- U16_PREV(buffer_.data(), 0, offset, previous_character);
-
- if (IsSeparator(first_character)) {
- // The start of a separator run is a word start (".org" in "webkit.org").
- if (!IsSeparator(previous_character))
- return true;
- } else if (IsASCIIUpper(first_character)) {
- // The start of an uppercase run is a word start ("Kit" in "WebKit").
- if (!IsASCIIUpper(previous_character))
- return true;
- // The last character of an uppercase run followed by a non-separator,
- // non-digit is a word start ("Request" in "XMLHTTPRequest").
- offset = start;
- U16_FWD_1(buffer_.data(), offset, size);
- UChar32 next_character = 0;
- if (offset < size)
- next_character = GetCodePointAt(buffer_.data(), offset, size);
- if (!IsASCIIUpper(next_character) && !IsASCIIDigit(next_character) &&
- !IsSeparator(next_character))
- return true;
- } else if (IsASCIIDigit(first_character)) {
- // The start of a digit run is a word start ("2" in "WebKit2").
- if (!IsASCIIDigit(previous_character))
- return true;
- } else if (IsSeparator(previous_character) ||
- IsASCIIDigit(previous_character)) {
- // The start of a non-separator, non-uppercase, non-digit run is a word
- // start, except after an uppercase. ("org" in "webkit.org", but not "ore"
- // in "WebCore").
- return true;
- }
- }
-
// Chinese and Japanese lack word boundary marks, and there is no clear
// agreement on what constitutes a word, so treat the position before any CJK
// character as a word start.
@@ -264,7 +229,7 @@ nextMatch:
// possibly including a combining character that's not yet in the buffer.
if (!at_break_ && match.start >= size - overlap_) {
size_t overlap = overlap_;
- if (options_ & kAtWordStarts) {
+ if (options_ & kWholeWord) {
// Ensure that there is sufficient context before matchStart the next time
// around for determining if it is at a word boundary.
int word_boundary_context_start = match.start;
@@ -285,7 +250,7 @@ nextMatch:
// If this match is "bad", move on to the next match.
if (IsBadMatch(buffer_.data() + match.start, match.length) ||
- ((options_ & kAtWordStarts) &&
+ ((options_ & kWholeWord) &&
!IsWordStartMatch(match.start, match.length))) {
goto nextMatch;
}
diff --git a/chromium/third_party/blink/renderer/core/editing/iterators/search_buffer.h b/chromium/third_party/blink/renderer/core/editing/iterators/search_buffer.h
index dbe606fc24f..f7754d32f02 100644
--- a/chromium/third_party/blink/renderer/core/editing/iterators/search_buffer.h
+++ b/chromium/third_party/blink/renderer/core/editing/iterators/search_buffer.h
@@ -45,9 +45,7 @@ class TextSearcherICU;
// Keeps enough of the previous text to be able to search in the future, but no
// more. Non-breaking spaces are always equal to normal spaces. Case folding is
// also done if the CaseInsensitive option is specified. Matches are further
-// filtered if the AtWordStarts option is specified, although some matches
-// inside a word are permitted if TreatMedialCapitalAsWordStart is specified as
-// well.
+// filtered if it should be starting at a word start (WholeWord is set).
class SearchBuffer {
STACK_ALLOCATED();
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 14bafd61ba2..59eb8dfe742 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
@@ -46,6 +46,7 @@ class CORE_EXPORT TextIteratorBehavior final {
bool ExcludeAutofilledValue() const {
return values_.bits.exclude_autofilled_value;
}
+ // TODO(editing-dev): We should remove unused flag |ForInnerText()|.
bool ForInnerText() const { return values_.bits.for_inner_text; }
bool ForSelectionToString() const {
return values_.bits.for_selection_to_string;
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 2286b3e9869..3dfaec9d2c3 100644
--- a/chromium/third_party/blink/renderer/core/editing/layout_selection.cc
+++ b/chromium/third_party/blink/renderer/core/editing/layout_selection.cc
@@ -22,6 +22,7 @@
#include "third_party/blink/renderer/core/editing/layout_selection.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/editing/ephemeral_range.h"
#include "third_party/blink/renderer/core/editing/frame_selection.h"
@@ -40,70 +41,10 @@
namespace blink {
-SelectionPaintRange::SelectionPaintRange(LayoutObject* start_layout_object,
- base::Optional<unsigned> start_offset,
- LayoutObject* end_layout_object,
- base::Optional<unsigned> end_offset)
- : start_layout_object_(start_layout_object),
- start_offset_(start_offset),
- end_layout_object_(end_layout_object),
- end_offset_(end_offset) {}
-
-bool SelectionPaintRange::operator==(const SelectionPaintRange& other) const {
- return start_layout_object_ == other.start_layout_object_ &&
- start_offset_ == other.start_offset_ &&
- end_layout_object_ == other.end_layout_object_ &&
- end_offset_ == other.end_offset_;
-}
-
-LayoutObject* SelectionPaintRange::StartLayoutObject() const {
- DCHECK(!IsNull());
- return start_layout_object_;
-}
-
-base::Optional<unsigned> SelectionPaintRange::StartOffset() const {
- DCHECK(!IsNull());
- return start_offset_;
-}
-
-LayoutObject* SelectionPaintRange::EndLayoutObject() const {
- DCHECK(!IsNull());
- return end_layout_object_;
-}
-
-base::Optional<unsigned> SelectionPaintRange::EndOffset() const {
- DCHECK(!IsNull());
- return end_offset_;
-}
-
-SelectionPaintRange::Iterator::Iterator(const SelectionPaintRange* range) {
- if (!range || range->IsNull()) {
- current_ = nullptr;
- return;
- }
- current_ = range->StartLayoutObject();
- stop_ = range->EndLayoutObject()->NextInPreOrder();
-}
-
-LayoutObject* SelectionPaintRange::Iterator::operator*() const {
- DCHECK(current_);
- return current_;
-}
-
-SelectionPaintRange::Iterator& SelectionPaintRange::Iterator::operator++() {
- DCHECK(current_);
- current_ = current_->NextInPreOrder();
- if (current_ && current_ != stop_)
- return *this;
-
- current_ = nullptr;
- return *this;
-}
-
LayoutSelection::LayoutSelection(FrameSelection& frame_selection)
: frame_selection_(&frame_selection),
has_pending_selection_(false),
- paint_range_(SelectionPaintRange()) {}
+ has_selection_(false) {}
enum class SelectionMode {
kNone,
@@ -166,89 +107,69 @@ static EphemeralRangeInFlatTree CalcSelectionInFlatTree(
// LayoutObjects each has SelectionState of kStart, kEnd, kStartAndEnd, or
// kInside.
using SelectedLayoutObjects = HashSet<LayoutObject*>;
+
+// The current selection to be painted is represented as 2 pairs of
+// (LayoutObject, offset).
+struct SelectionPaintRange {
+ STACK_ALLOCATED();
+
+ public:
+ bool IsNull() const { return !start_layout_object; }
+ LayoutObject* start_layout_object = nullptr;
+ base::Optional<unsigned> start_offset = base::nullopt;
+ LayoutObject* end_layout_object = nullptr;
+ base::Optional<unsigned> end_offset = base::nullopt;
+};
+
// OldSelectedLayoutObjects is current selected LayoutObjects with
// current SelectionState which is kStart, kEnd, kStartAndEnd or kInside.
-using OldSelectedLayoutObjects = HashMap<LayoutObject*, SelectionState>;
+struct OldSelectedLayoutObjects {
+ STACK_ALLOCATED();
-#ifndef NDEBUG
-void PrintSelectedLayoutObjects(
- const SelectedLayoutObjects& new_selected_objects) {
- std::stringstream stream;
- stream << std::endl;
- for (LayoutObject* layout_object : new_selected_objects) {
- PrintLayoutObjectForSelection(stream, layout_object);
- stream << std::endl;
+ public:
+ OldSelectedLayoutObjects() = default;
+ OldSelectedLayoutObjects(OldSelectedLayoutObjects&& other) {
+ paint_range = other.paint_range;
+ selected_map = std::move(other.selected_map);
}
- LOG(INFO) << stream.str();
-}
-void PrintOldSelectedLayoutObjects(
- const OldSelectedLayoutObjects& old_selected_objects) {
- std::stringstream stream;
- stream << std::endl;
- for (const auto& key_pair : old_selected_objects) {
- LayoutObject* layout_object = key_pair.key;
- SelectionState old_state = key_pair.value;
- PrintLayoutObjectForSelection(stream, layout_object);
- stream << " old: " << old_state << std::endl;
- }
- LOG(INFO) << stream.str();
-}
+ SelectionPaintRange paint_range;
+ HashMap<LayoutObject*, SelectionState> selected_map;
-void PrintSelectionPaintRange(const SelectionPaintRange& paint_range) {
- std::stringstream stream;
- stream << std::endl << "layout_objects:" << std::endl;
- for (LayoutObject* layout_object : paint_range) {
- PrintLayoutObjectForSelection(stream, layout_object);
- stream << std::endl;
- }
- LOG(INFO) << stream.str();
-}
+ private:
+ DISALLOW_COPY_AND_ASSIGN(OldSelectedLayoutObjects);
+};
-void PrintSelectionStateInLayoutView(const FrameSelection& selection) {
- std::stringstream stream;
- stream << std::endl << "layout_objects:" << std::endl;
- LayoutView* layout_view = selection.GetDocument().GetLayoutView();
- for (LayoutObject* layout_object = layout_view; layout_object;
- layout_object = layout_object->NextInPreOrder()) {
- PrintLayoutObjectForSelection(stream, layout_object);
- stream << std::endl;
- }
- LOG(INFO) << stream.str();
-}
-#endif
+std::ostream& operator<<(std::ostream&, const OldSelectedLayoutObjects&);
-// This class represents a selection range in layout tree and each LayoutObject
-// is SelectionState-marked.
-class NewPaintRangeAndSelectedLayoutObjects {
+// This struct represents a selection range in layout tree and each
+// LayoutObject is SelectionState-marked.
+struct NewPaintRangeAndSelectedLayoutObjects {
STACK_ALLOCATED();
public:
NewPaintRangeAndSelectedLayoutObjects() = default;
- NewPaintRangeAndSelectedLayoutObjects(SelectionPaintRange paint_range,
- SelectedLayoutObjects selected_objects)
- : paint_range_(paint_range),
- selected_objects_(std::move(selected_objects)) {}
+ NewPaintRangeAndSelectedLayoutObjects(
+ SelectionPaintRange passed_paint_range,
+ SelectedLayoutObjects passed_selected_objects)
+ : paint_range(passed_paint_range),
+ selected_objects(std::move(passed_selected_objects)) {}
NewPaintRangeAndSelectedLayoutObjects(
NewPaintRangeAndSelectedLayoutObjects&& other) {
- paint_range_ = other.paint_range_;
- selected_objects_ = std::move(other.selected_objects_);
+ paint_range = other.paint_range;
+ selected_objects = std::move(other.selected_objects);
}
- SelectionPaintRange PaintRange() const { return paint_range_; }
-
- const SelectedLayoutObjects& LayoutObjects() const {
- return selected_objects_;
- }
-
- private:
- SelectionPaintRange paint_range_;
- SelectedLayoutObjects selected_objects_;
+ SelectionPaintRange paint_range;
+ SelectedLayoutObjects selected_objects;
private:
DISALLOW_COPY_AND_ASSIGN(NewPaintRangeAndSelectedLayoutObjects);
};
+std::ostream& operator<<(std::ostream&,
+ const NewPaintRangeAndSelectedLayoutObjects&);
+
static void SetShouldInvalidateIfNeeded(LayoutObject* layout_object) {
if (layout_object->ShouldInvalidateSelection())
return;
@@ -274,6 +195,14 @@ static void SetShouldInvalidateIfNeeded(LayoutObject* layout_object) {
}
}
+static const Node* GetNodeOf(LayoutObject* layout_object) {
+ if (LayoutTextFragment* first_letter =
+ ToLayoutTextFragmentOrNull(layout_object)) {
+ return first_letter->AssociatedTextNode();
+ }
+ return layout_object->GetNode();
+}
+
static void SetSelectionStateIfNeeded(LayoutObject* layout_object,
SelectionState state) {
DCHECK_NE(state, SelectionState::kContain) << layout_object;
@@ -282,14 +211,17 @@ static void SetSelectionStateIfNeeded(LayoutObject* layout_object,
return;
layout_object->SetSelectionState(state);
- // Set containing block SelectionState kContain for CSS ::selection style.
- // See LayoutObject::InvalidatePaintForSelection().
- for (LayoutObject* containing_block = layout_object->ContainingBlock();
- containing_block;
- containing_block = containing_block->ContainingBlock()) {
- if (containing_block->GetSelectionState() == SelectionState::kContain)
+ const Node* node = GetNodeOf(layout_object);
+ DCHECK(node);
+ // Set ancestors SelectionState kContain for CSS ::selection style.
+ // See LayoutObject::InvalidateSelectedChildrenOnStyleChange().
+ for (Node& ancestor : FlatTreeTraversal::AncestorsOf(*node)) {
+ LayoutObject* ancestor_layout = ancestor.GetLayoutObject();
+ if (!ancestor_layout)
+ continue;
+ if (ancestor_layout->GetSelectionState() == SelectionState::kContain)
return;
- containing_block->LayoutObject::SetSelectionState(SelectionState::kContain);
+ ancestor_layout->LayoutObject::SetSelectionState(SelectionState::kContain);
}
}
@@ -297,13 +229,12 @@ static void SetSelectionStateIfNeeded(LayoutObject* layout_object,
// comparing them in |new_range| and |old_range|.
static void SetShouldInvalidateSelection(
const NewPaintRangeAndSelectedLayoutObjects& new_range,
- const SelectionPaintRange& old_range,
const OldSelectedLayoutObjects& old_selected_objects) {
// We invalidate each LayoutObject in new SelectionPaintRange which
// has SelectionState of kStart, kEnd, kStartAndEnd, or kInside
// and is not in old SelectionPaintRange.
- for (LayoutObject* layout_object : new_range.LayoutObjects()) {
- if (old_selected_objects.Contains(layout_object))
+ for (LayoutObject* layout_object : new_range.selected_objects) {
+ if (old_selected_objects.selected_map.Contains(layout_object))
continue;
const SelectionState new_state = layout_object->GetSelectionState();
DCHECK_NE(new_state, SelectionState::kContain) << layout_object;
@@ -314,7 +245,7 @@ static void SetShouldInvalidateSelection(
// each of:
// 1. LayoutObject was painted and would not be painted.
// 2. LayoutObject was not painted and would be painted.
- for (const auto& key_value : old_selected_objects) {
+ for (const auto& key_value : old_selected_objects.selected_map) {
LayoutObject* const layout_object = key_value.key;
const SelectionState old_state = key_value.value;
const SelectionState new_state = layout_object->GetSelectionState();
@@ -329,76 +260,127 @@ static void SetShouldInvalidateSelection(
}
// Invalidate Selection start/end is moving on a same node.
- const SelectionPaintRange& new_paint_range = new_range.PaintRange();
- if (new_paint_range.IsNull() || old_range.IsNull())
+ const SelectionPaintRange& new_paint_range = new_range.paint_range;
+ const SelectionPaintRange& old_paint_range = old_selected_objects.paint_range;
+ if (new_paint_range.IsNull())
return;
- if (new_paint_range.StartLayoutObject()->IsText() &&
- new_paint_range.StartLayoutObject() == old_range.StartLayoutObject() &&
- new_paint_range.StartOffset() != old_range.StartOffset())
- SetShouldInvalidateIfNeeded(new_paint_range.StartLayoutObject());
- if (new_paint_range.EndLayoutObject()->IsText() &&
- new_paint_range.EndLayoutObject() == old_range.EndLayoutObject() &&
- new_paint_range.EndOffset() != old_range.EndOffset())
- SetShouldInvalidateIfNeeded(new_paint_range.EndLayoutObject());
+ if (new_paint_range.start_layout_object->IsText() &&
+ new_paint_range.start_layout_object ==
+ old_paint_range.start_layout_object &&
+ new_paint_range.start_offset != old_paint_range.start_offset)
+ SetShouldInvalidateIfNeeded(new_paint_range.start_layout_object);
+ if (new_paint_range.end_layout_object->IsText() &&
+ new_paint_range.end_layout_object == old_paint_range.end_layout_object &&
+ new_paint_range.end_offset != old_paint_range.end_offset)
+ SetShouldInvalidateIfNeeded(new_paint_range.end_layout_object);
}
-base::Optional<unsigned> LayoutSelection::SelectionStart() const {
- DCHECK(!HasPendingSelection());
- if (paint_range_.IsNull())
- return base::nullopt;
- return paint_range_.StartOffset();
+static LayoutTextFragment* FirstLetterPartFor(
+ const LayoutObject* layout_object) {
+ if (!layout_object->IsText())
+ return nullptr;
+ if (const LayoutText* layout_text = ToLayoutTextOrNull(layout_object))
+ return ToLayoutTextFragmentOrNull(layout_text->GetFirstLetterPart());
+ return nullptr;
}
-base::Optional<unsigned> LayoutSelection::SelectionEnd() const {
- DCHECK(!HasPendingSelection());
- if (paint_range_.IsNull())
- return base::nullopt;
- return paint_range_.EndOffset();
+static bool IsDisplayContentElement(const Node& node) {
+ if (!node.IsElementNode())
+ return false;
+ const ComputedStyle* const style = node.GetComputedStyle();
+ return style && style->Display() == EDisplay::kContents;
}
-static OldSelectedLayoutObjects ResetOldSelectedLayoutObjects(
- const SelectionPaintRange& old_range) {
- OldSelectedLayoutObjects old_selected_objects;
- HashSet<LayoutObject*> containing_block_set;
- for (LayoutObject* layout_object : old_range) {
- const SelectionState old_state = layout_object->GetSelectionState();
- if (old_state == SelectionState::kNone)
- continue;
- if (old_state != SelectionState::kContain)
- old_selected_objects.insert(layout_object, old_state);
- layout_object->SetSelectionState(SelectionState::kNone);
-
- // Reset containing block SelectionState for CSS ::selection style.
- // See LayoutObject::InvalidatePaintForSelection().
- for (LayoutObject* containing_block = layout_object->ContainingBlock();
- containing_block;
- containing_block = containing_block->ContainingBlock()) {
- if (containing_block_set.Contains(containing_block))
- break;
- containing_block->SetSelectionState(SelectionState::kNone);
- containing_block_set.insert(containing_block);
+template <typename Visitor>
+static void VisitSelectedInclusiveDescendantsOfInternal(const Node& node,
+ Visitor* visitor) {
+ // Display:content element appears in a flat tree even it doesn't have
+ // a LayoutObject but we need to visit its children.
+ if (!IsDisplayContentElement(node)) {
+ LayoutObject* layout_object = node.GetLayoutObject();
+ if (!layout_object)
+ return;
+ if (LayoutTextFragment* first_letter = FirstLetterPartFor(layout_object)) {
+ if (first_letter->GetSelectionState() != SelectionState::kNone)
+ visitor->Visit(first_letter);
}
+ if (layout_object->GetSelectionState() == SelectionState::kNone)
+ return;
+ visitor->Visit(layout_object);
}
- return old_selected_objects;
+
+ for (Node& child : FlatTreeTraversal::ChildrenOf(node))
+ VisitSelectedInclusiveDescendantsOfInternal(child, visitor);
}
-void LayoutSelection::ClearSelection() {
- // For querying Layer::compositingState()
- // This is correct, since destroying layout objects needs to cause eager paint
- // invalidations.
- DisableCompositingQueryAsserts disabler;
+static inline bool IsFlatTreeClean(const Node& node) {
+ return !node.GetDocument().IsSlotAssignmentOrLegacyDistributionDirty();
+}
- // Just return if the selection is already empty.
- if (paint_range_.IsNull())
- return;
+template <typename Visitor>
+static void VisitSelectedInclusiveDescendantsOf(const Node& node,
+ Visitor* visitor) {
+ DCHECK(IsFlatTreeClean(node));
+ return VisitSelectedInclusiveDescendantsOfInternal(node, visitor);
+}
- const OldSelectedLayoutObjects& old_selected_objects =
- ResetOldSelectedLayoutObjects(paint_range_);
- for (LayoutObject* const layout_object : old_selected_objects.Keys())
- SetShouldInvalidateIfNeeded(layout_object);
+static OldSelectedLayoutObjects ResetOldSelectedLayoutObjects(
+ const Node& root,
+ base::Optional<unsigned> old_start_offset,
+ base::Optional<unsigned> old_end_offset) {
+ class OldSelectedVisitor {
+ STACK_ALLOCATED();
+
+ public:
+ OldSelectedVisitor(base::Optional<unsigned> passed_old_start_offset,
+ base::Optional<unsigned> passed_old_end_offset)
+ : old_start_offset(passed_old_start_offset),
+ old_end_offset(passed_old_end_offset) {}
+
+ void Visit(LayoutObject* layout_object) {
+ const SelectionState old_state = layout_object->GetSelectionState();
+ DCHECK_NE(old_state, SelectionState::kNone) << layout_object;
+ layout_object->SetSelectionState(SelectionState::kNone);
+ if (old_state == SelectionState::kContain)
+ return;
+ old_selected_objects.selected_map.insert(layout_object, old_state);
+ if (old_state == SelectionState::kInside)
+ return;
+ switch (old_state) {
+ case SelectionState::kStart: {
+ DCHECK(!old_selected_objects.paint_range.start_layout_object);
+ old_selected_objects.paint_range.start_layout_object = layout_object;
+ old_selected_objects.paint_range.start_offset = old_start_offset;
+ break;
+ }
+ case SelectionState::kEnd: {
+ DCHECK(!old_selected_objects.paint_range.end_layout_object);
+ old_selected_objects.paint_range.end_layout_object = layout_object;
+ old_selected_objects.paint_range.end_offset = old_end_offset;
+ break;
+ }
+ case SelectionState::kStartAndEnd: {
+ DCHECK(!old_selected_objects.paint_range.start_layout_object);
+ DCHECK(!old_selected_objects.paint_range.end_layout_object);
+ old_selected_objects.paint_range.start_layout_object = layout_object;
+ old_selected_objects.paint_range.start_offset = old_start_offset;
+ old_selected_objects.paint_range.end_layout_object = layout_object;
+ old_selected_objects.paint_range.end_offset = old_end_offset;
+ break;
+ }
+ default: {
+ NOTREACHED();
+ break;
+ }
+ }
+ }
- // Reset selection.
- paint_range_ = SelectionPaintRange();
+ OldSelectedLayoutObjects old_selected_objects;
+ const base::Optional<unsigned> old_start_offset;
+ const base::Optional<unsigned> old_end_offset;
+ } visitor(old_start_offset, old_end_offset);
+ VisitSelectedInclusiveDescendantsOf(root, &visitor);
+ return std::move(visitor.old_selected_objects);
}
static base::Optional<unsigned> ComputeStartOffset(
@@ -425,15 +407,6 @@ static base::Optional<unsigned> ComputeEndOffset(
return ToText(layout_node)->length();
}
-static LayoutTextFragment* FirstLetterPartFor(LayoutObject* layout_object) {
- if (!layout_object->IsText())
- return nullptr;
- if (!ToLayoutText(layout_object)->IsTextFragment())
- return nullptr;
- return ToLayoutTextFragment(const_cast<LayoutObject*>(
- AssociatedLayoutObjectOf(*layout_object->GetNode(), 0)));
-}
-
static void MarkSelected(SelectedLayoutObjects* selected_objects,
LayoutObject* layout_object,
SelectionState state) {
@@ -512,6 +485,8 @@ static NewPaintRangeAndSelectedLayoutObjects MarkStartAndEndInOneNode(
// LayoutObjectAndOffset represents start or end of SelectionPaintRange.
struct LayoutObjectAndOffset {
STACK_ALLOCATED();
+
+ public:
LayoutObject* layout_object;
base::Optional<unsigned> offset;
@@ -676,23 +651,23 @@ static NewPaintRangeAndSelectedLayoutObjects ComputeNewPaintRange(
base::Optional<unsigned> start_node_offset,
LayoutObject* end_layout_object,
base::Optional<unsigned> end_node_offset) {
- if (new_range.PaintRange().IsNull())
+ if (new_range.paint_range.IsNull())
return {};
- LayoutObject* const start = new_range.PaintRange().StartLayoutObject();
+ LayoutObject* const start = new_range.paint_range.start_layout_object;
// If LayoutObject is not in NG, use legacy offset.
const base::Optional<unsigned> start_offset =
start->EnclosingNGBlockFlow()
? GetTextContentOffsetStart(start_layout_object, start_node_offset)
- : new_range.PaintRange().StartOffset();
+ : new_range.paint_range.start_offset;
- LayoutObject* const end = new_range.PaintRange().EndLayoutObject();
+ LayoutObject* const end = new_range.paint_range.end_layout_object;
const base::Optional<unsigned> end_offset =
end->EnclosingNGBlockFlow()
? GetTextContentOffsetEnd(end_layout_object, end_node_offset)
- : new_range.PaintRange().EndOffset();
+ : new_range.paint_range.end_offset;
return {{start, start_offset, end, end_offset},
- std::move(new_range.LayoutObjects())};
+ std::move(new_range.selected_objects)};
}
// ClampOffset modifies |offset| fixed in a range of |text_fragment| start/end
@@ -741,6 +716,49 @@ static bool IsBeforeSoftLineBreak(const NGPaintFragment& fragment) {
return physical_line_box.BaseDirection() == shape_result->Direction();
}
+static bool IsTextNodeAssociated(const LayoutText& text) {
+ if (const LayoutTextFragment* fragment = ToLayoutTextFragmentOrNull(text))
+ return fragment->AssociatedTextNode();
+ if (Node* node = text.GetNode())
+ return ToTextOrNull(node);
+ return false;
+}
+
+LayoutTextSelectionStatus LayoutSelection::ComputeSelectionStatus(
+ const LayoutText& text) const {
+ DCHECK(!HasPendingSelection());
+ const SelectionState selection_state = text.GetSelectionState();
+ if (selection_state == SelectionState::kNone)
+ return {0, 0, SelectionIncludeEnd::kNotInclude};
+ if (!IsTextNodeAssociated(text)) {
+ // TODO(yoichio): This is really weird legacy behavior. Remove this.
+ if (text.IsBR() && selection_state == SelectionState::kEnd)
+ return {0, 0, SelectionIncludeEnd::kNotInclude};
+ return {0, text.TextLength(), SelectionIncludeEnd::kInclude};
+ }
+
+ switch (selection_state) {
+ case SelectionState::kInside:
+ return {0, text.TextLength(), SelectionIncludeEnd::kInclude};
+ case SelectionState::kStart:
+ return {start_offset_.value(), text.TextLength(),
+ SelectionIncludeEnd::kInclude};
+ case SelectionState::kEnd:
+ return {0, end_offset_.value(), SelectionIncludeEnd::kNotInclude};
+ case SelectionState::kStartAndEnd:
+ return {start_offset_.value(), end_offset_.value(),
+ SelectionIncludeEnd::kNotInclude};
+ default:
+ NOTREACHED();
+ return {0, 0, SelectionIncludeEnd::kNotInclude};
+ }
+}
+
+LayoutTextSelectionStatus FrameSelection::ComputeLayoutSelectionStatus(
+ const LayoutText& text) const {
+ return layout_selection_->ComputeSelectionStatus(text);
+}
+
// FrameSelection holds selection offsets in layout block flow at
// LayoutSelection::Commit() if selection starts/ends within Text that
// each LayoutObject::SelectionState indicates.
@@ -755,8 +773,7 @@ LayoutSelectionStatus LayoutSelection::ComputeSelectionStatus(
return {0, 0, SelectSoftLineBreak::kNotSelected};
switch (text_fragment.GetLayoutObject()->GetSelectionState()) {
case SelectionState::kStart: {
- DCHECK(SelectionStart().has_value());
- const unsigned start_in_block = SelectionStart().value_or(0);
+ const unsigned start_in_block = start_offset_.value();
const bool is_continuous = start_in_block <= text_fragment.EndOffset();
return {ClampOffset(start_in_block, text_fragment),
text_fragment.EndOffset(),
@@ -765,9 +782,7 @@ LayoutSelectionStatus LayoutSelection::ComputeSelectionStatus(
: SelectSoftLineBreak::kNotSelected};
}
case SelectionState::kEnd: {
- DCHECK(SelectionEnd().has_value());
- const unsigned end_in_block =
- SelectionEnd().value_or(text_fragment.EndOffset());
+ const unsigned end_in_block = end_offset_.value();
const unsigned end_in_fragment = ClampOffset(end_in_block, text_fragment);
const bool is_continuous = text_fragment.EndOffset() < end_in_block;
return {text_fragment.StartOffset(), end_in_fragment,
@@ -776,11 +791,8 @@ LayoutSelectionStatus LayoutSelection::ComputeSelectionStatus(
: SelectSoftLineBreak::kNotSelected};
}
case SelectionState::kStartAndEnd: {
- DCHECK(SelectionStart().has_value());
- DCHECK(SelectionEnd().has_value());
- const unsigned start_in_block = SelectionStart().value_or(0);
- const unsigned end_in_block =
- SelectionEnd().value_or(text_fragment.EndOffset());
+ const unsigned start_in_block = start_offset_.value();
+ const unsigned end_in_block = end_offset_.value();
const unsigned end_in_fragment = ClampOffset(end_in_block, text_fragment);
const bool is_continuous = start_in_block <= text_fragment.EndOffset() &&
text_fragment.EndOffset() < end_in_block;
@@ -868,6 +880,34 @@ void LayoutSelection::SetHasPendingSelection() {
has_pending_selection_ = true;
}
+void AssertNewRangeSanity(
+ const NewPaintRangeAndSelectedLayoutObjects& new_range) {
+#if DCHECK_IS_ON()
+ const SelectionPaintRange& paint_range = new_range.paint_range;
+ if (paint_range.start_layout_object) {
+ DCHECK(paint_range.end_layout_object) << new_range;
+ DCHECK(paint_range.start_layout_object->GetSelectionState() ==
+ SelectionState::kStart ||
+ paint_range.start_layout_object->GetSelectionState() ==
+ SelectionState::kStartAndEnd)
+ << new_range;
+ DCHECK(paint_range.end_layout_object->GetSelectionState() ==
+ SelectionState::kEnd ||
+ paint_range.end_layout_object->GetSelectionState() ==
+ SelectionState::kStartAndEnd);
+ DCHECK(new_range.selected_objects.Contains(paint_range.start_layout_object))
+ << new_range;
+ DCHECK(new_range.selected_objects.Contains(paint_range.end_layout_object))
+ << new_range;
+ return;
+ }
+ DCHECK(!paint_range.end_layout_object) << new_range;
+ DCHECK(!paint_range.start_offset.has_value()) << new_range;
+ DCHECK(!paint_range.end_offset.has_value()) << new_range;
+ DCHECK(new_range.selected_objects.IsEmpty()) << new_range;
+#endif
+}
+
void LayoutSelection::Commit() {
if (!HasPendingSelection())
return;
@@ -880,56 +920,24 @@ void LayoutSelection::Commit() {
frame_selection_->GetDocument().Lifecycle());
const OldSelectedLayoutObjects& old_selected_objects =
- ResetOldSelectedLayoutObjects(paint_range_);
+ ResetOldSelectedLayoutObjects(frame_selection_->GetDocument(),
+ start_offset_, end_offset_);
const NewPaintRangeAndSelectedLayoutObjects& new_range =
CalcSelectionRangeAndSetSelectionState(*frame_selection_);
+ AssertNewRangeSanity(new_range);
DCHECK(frame_selection_->GetDocument().GetLayoutView()->GetFrameView());
- SetShouldInvalidateSelection(new_range, paint_range_, old_selected_objects);
+ SetShouldInvalidateSelection(new_range, old_selected_objects);
- paint_range_ = new_range.PaintRange();
- if (paint_range_.IsNull())
- return;
- // TODO(yoichio): Remove this if state.
- // This SelectionState reassignment is ad-hoc patch for
- // prohibiting use-after-free(crbug.com/752715).
- // LayoutText::setSelectionState(state) propergates |state| to ancestor
- // LayoutObjects, which can accidentally change start/end LayoutObject state
- // then LayoutObject::IsSelectionBorder() returns false although we should
- // clear selection at LayoutObject::WillBeRemoved().
- // We should make LayoutObject::setSelectionState() trivial and remove
- // such propagation or at least do it in LayoutSelection.
- if ((paint_range_.StartLayoutObject()->GetSelectionState() !=
- SelectionState::kStart &&
- paint_range_.StartLayoutObject()->GetSelectionState() !=
- SelectionState::kStartAndEnd) ||
- (paint_range_.EndLayoutObject()->GetSelectionState() !=
- SelectionState::kEnd &&
- paint_range_.EndLayoutObject()->GetSelectionState() !=
- SelectionState::kStartAndEnd)) {
- if (paint_range_.StartLayoutObject() == paint_range_.EndLayoutObject()) {
- paint_range_.StartLayoutObject()->SetSelectionState(
- SelectionState::kStartAndEnd);
- } else {
- paint_range_.StartLayoutObject()->SetSelectionState(
- SelectionState::kStart);
- paint_range_.EndLayoutObject()->SetSelectionState(SelectionState::kEnd);
- }
- }
- // TODO(yoichio): If start == end, they should be kStartAndEnd.
- // If not, start.SelectionState == kStart and vice versa.
- DCHECK(paint_range_.StartLayoutObject()->GetSelectionState() ==
- SelectionState::kStart ||
- paint_range_.StartLayoutObject()->GetSelectionState() ==
- SelectionState::kStartAndEnd);
- DCHECK(paint_range_.EndLayoutObject()->GetSelectionState() ==
- SelectionState::kEnd ||
- paint_range_.EndLayoutObject()->GetSelectionState() ==
- SelectionState::kStartAndEnd);
+ start_offset_ = new_range.paint_range.start_offset;
+ end_offset_ = new_range.paint_range.end_offset;
+ has_selection_ = !new_range.paint_range.IsNull();
}
void LayoutSelection::OnDocumentShutdown() {
has_pending_selection_ = false;
- paint_range_ = SelectionPaintRange();
+ has_selection_ = false;
+ start_offset_ = base::nullopt;
+ end_offset_ = base::nullopt;
}
static LayoutRect SelectionRectForLayoutObject(const LayoutObject* object) {
@@ -944,31 +952,43 @@ static LayoutRect SelectionRectForLayoutObject(const LayoutObject* object) {
IntRect LayoutSelection::AbsoluteSelectionBounds() {
Commit();
- if (paint_range_.IsNull())
+ if (!has_selection_)
return IntRect();
// Create a single bounding box rect that encloses the whole selection.
- LayoutRect selected_rect;
- for (LayoutObject* layout_object : paint_range_) {
- const SelectionState state = layout_object->GetSelectionState();
- if (state == SelectionState::kContain || state == SelectionState::kNone)
- continue;
- selected_rect.Unite(SelectionRectForLayoutObject(layout_object));
- }
-
- return PixelSnappedIntRect(selected_rect);
+ class SelectionBoundsVisitor {
+ STACK_ALLOCATED();
+
+ public:
+ void Visit(LayoutObject* layout_object) {
+ if (layout_object->GetSelectionState() == SelectionState::kContain)
+ return;
+ selected_rect.Unite(SelectionRectForLayoutObject(layout_object));
+ }
+ LayoutRect selected_rect;
+ } visitor;
+ VisitSelectedInclusiveDescendantsOf(frame_selection_->GetDocument(),
+ &visitor);
+ return PixelSnappedIntRect(visitor.selected_rect);
}
void LayoutSelection::InvalidatePaintForSelection() {
- if (paint_range_.IsNull())
+ if (!has_selection_)
return;
- for (LayoutObject* runner : paint_range_) {
- if (runner->GetSelectionState() == SelectionState::kNone)
- continue;
+ class InvalidatingVisitor {
+ STACK_ALLOCATED();
- runner->SetShouldInvalidateSelection();
- }
+ public:
+ void Visit(LayoutObject* layout_object) {
+ if (layout_object->GetSelectionState() == SelectionState::kContain)
+ return;
+ layout_object->SetShouldInvalidateSelection();
+ }
+ LayoutRect selected_rect;
+ } visitor;
+ VisitSelectedInclusiveDescendantsOf(frame_selection_->GetDocument(),
+ &visitor);
}
void LayoutSelection::Trace(blink::Visitor* visitor) {
@@ -997,12 +1017,104 @@ void PrintLayoutObjectForSelection(std::ostream& ostream,
<< (layout_object->ShouldInvalidateSelection() ? ", ShouldInvalidate"
: ", NotInvalidate");
}
-#ifndef NDEBUG
+
+#if DCHECK_IS_ON()
void ShowLayoutObjectForSelection(LayoutObject* layout_object) {
std::stringstream stream;
PrintLayoutObjectForSelection(stream, layout_object);
LOG(INFO) << '\n' << stream.str();
}
+
+std::ostream& operator<<(std::ostream& ostream,
+ const base::Optional<unsigned>& offset) {
+ if (offset.has_value())
+ ostream << offset.value();
+ else
+ ostream << "<nullopt>";
+ return ostream;
+}
+
+std::ostream& operator<<(std::ostream& ostream,
+ const SelectionPaintRange& range) {
+ ostream << range.start_layout_object << ": " << range.start_offset << ", "
+ << range.end_layout_object << ": " << range.end_offset;
+ return ostream;
+}
+
+std::ostream& operator<<(std::ostream& ostream,
+ const HashMap<LayoutObject*, SelectionState>& map) {
+ ostream << "[";
+ const char* comma = "";
+ for (const auto& key_value : map) {
+ LayoutObject* const layout_object = key_value.key;
+ const SelectionState old_state = key_value.value;
+ ostream << comma << layout_object << "." << old_state;
+ comma = ", ";
+ }
+ ostream << "]";
+ return ostream;
+}
+
+std::ostream& operator<<(std::ostream& ostream,
+ const OldSelectedLayoutObjects& objects) {
+ ostream << objects.paint_range << ". " << objects.selected_map;
+ return ostream;
+}
+
+std::ostream& operator<<(std::ostream& ostream,
+ const SelectedLayoutObjects& selected_objects) {
+ ostream << "[";
+ const char* comma = "";
+ for (LayoutObject* layout_object : selected_objects) {
+ ostream << comma << layout_object;
+ comma = ", ";
+ }
+ ostream << "]";
+ return ostream;
+}
+
+std::ostream& operator<<(
+ std::ostream& ostream,
+ const NewPaintRangeAndSelectedLayoutObjects& new_range) {
+ ostream << new_range.paint_range << ". " << new_range.selected_objects;
+ return ostream;
+}
+
+void PrintSelectedLayoutObjects(
+ const SelectedLayoutObjects& new_selected_objects) {
+ std::stringstream stream;
+ stream << std::endl;
+ for (LayoutObject* layout_object : new_selected_objects) {
+ PrintLayoutObjectForSelection(stream, layout_object);
+ stream << std::endl;
+ }
+ LOG(INFO) << stream.str();
+}
+
+void PrintOldSelectedLayoutObjects(
+ const OldSelectedLayoutObjects& old_selected_objects) {
+ std::stringstream stream;
+ stream << std::endl;
+ for (const auto& key_pair : old_selected_objects.selected_map) {
+ LayoutObject* layout_object = key_pair.key;
+ SelectionState old_state = key_pair.value;
+ PrintLayoutObjectForSelection(stream, layout_object);
+ stream << " old: " << old_state << std::endl;
+ }
+ LOG(INFO) << stream.str();
+}
+
+void PrintSelectionStateInLayoutView(const FrameSelection& selection) {
+ std::stringstream stream;
+ stream << std::endl << "layout_objects:" << std::endl;
+ LayoutView* layout_view = selection.GetDocument().GetLayoutView();
+ for (LayoutObject* layout_object = layout_view; layout_object;
+ layout_object = layout_object->NextInPreOrder()) {
+ PrintLayoutObjectForSelection(stream, layout_object);
+ stream << std::endl;
+ }
+ LOG(INFO) << stream.str();
+}
#endif
} // namespace blink
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 42daa45ca07..997524e50dd 100644
--- a/chromium/third_party/blink/renderer/core/editing/layout_selection.h
+++ b/chromium/third_party/blink/renderer/core/editing/layout_selection.h
@@ -31,63 +31,11 @@ namespace blink {
class IntRect;
class LayoutObject;
+class LayoutText;
class NGPaintFragment;
class FrameSelection;
struct LayoutSelectionStatus;
-// This class represents a selection range in layout tree for painting and
-// paint invalidation.
-// The current selection to be painted is represented as 2 pairs of
-// (LayoutObject, offset).
-// 2 LayoutObjects are only valid for |Text| node without 'transform' or
-// 'first-letter'.
-// TODO(editing-dev): Clarify the meaning of "offset".
-// editing/ passes them as offsets in the DOM tree but layout uses them as
-// offset in the layout tree. This doesn't work in the cases of
-// CSS first-letter or character transform. See crbug.com/17528.
-class SelectionPaintRange {
- DISALLOW_NEW();
-
- public:
- class Iterator
- : public std::iterator<std::input_iterator_tag, LayoutObject*> {
- public:
- explicit Iterator(const SelectionPaintRange*);
- Iterator(const Iterator&) = default;
- bool operator==(const Iterator& other) const {
- return current_ == other.current_;
- }
- bool operator!=(const Iterator& other) const { return !operator==(other); }
- Iterator& operator++();
- LayoutObject* operator*() const;
-
- private:
- LayoutObject* current_;
- const LayoutObject* stop_;
- };
- Iterator begin() const { return Iterator(this); };
- Iterator end() const { return Iterator(nullptr); };
-
- SelectionPaintRange() = default;
- SelectionPaintRange(LayoutObject* start_layout_object,
- base::Optional<unsigned> start_offset,
- LayoutObject* end_layout_object,
- base::Optional<unsigned> end_offset);
-
- bool operator==(const SelectionPaintRange& other) const;
-
- LayoutObject* StartLayoutObject() const;
- base::Optional<unsigned> StartOffset() const;
- LayoutObject* EndLayoutObject() const;
- base::Optional<unsigned> EndOffset() const;
-
- bool IsNull() const { return !start_layout_object_; }
-
- private:
- LayoutObject* start_layout_object_ = nullptr;
- base::Optional<unsigned> start_offset_ = base::nullopt;
- LayoutObject* end_layout_object_ = nullptr;
- base::Optional<unsigned> end_offset_ = base::nullopt;
-};
+struct LayoutTextSelectionStatus;
class LayoutSelection final : public GarbageCollected<LayoutSelection> {
public:
@@ -102,9 +50,7 @@ class LayoutSelection final : public GarbageCollected<LayoutSelection> {
IntRect AbsoluteSelectionBounds();
void InvalidatePaintForSelection();
- void ClearSelection();
- base::Optional<unsigned> SelectionStart() const;
- base::Optional<unsigned> SelectionEnd() const;
+ LayoutTextSelectionStatus ComputeSelectionStatus(const LayoutText&) const;
LayoutSelectionStatus ComputeSelectionStatus(const NGPaintFragment&) const;
void OnDocumentShutdown();
@@ -116,8 +62,19 @@ class LayoutSelection final : public GarbageCollected<LayoutSelection> {
Member<FrameSelection> frame_selection_;
bool has_pending_selection_ : 1;
-
- SelectionPaintRange paint_range_;
+ // Each offset represents text offsets on selection edge if it is text.
+ // For example, suppose we select "f^oo<br><img>|",
+ // |start_offset_| is 1 and |end_offset_| is nullopt.
+ // Each of them is only valid for a |Text| node without 'transform' or
+ // 'first-letter'.
+ // TODO(editing-dev): Clarify the meaning of "offset".
+ // editing/ passes them as offsets in the DOM tree but layout uses them as
+ // offset in the layout tree. This doesn't work in the cases of
+ // character transform. See crbug.com/17528.
+ base::Optional<unsigned> start_offset_;
+ base::Optional<unsigned> end_offset_;
+ // This is true if at least one LayoutObject has a valid SelectionState.
+ bool has_selection_;
};
void CORE_EXPORT PrintLayoutObjectForSelection(std::ostream&, LayoutObject*);
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 abb63da7d1f..afac01b2dea 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
@@ -21,167 +21,92 @@
namespace blink {
-static const LayoutTextFragment* ToFirstLetterOrNull(
- const LayoutObject& layout_object) {
- if (const LayoutTextFragment* fragment =
- ToLayoutTextFragmentOrNull(layout_object)) {
- if (fragment->IsRemainingTextLayoutObject())
- return nullptr;
- return fragment;
- }
- return nullptr;
-}
-
-static const Node* FindNextNodeOnDOMIncludingShadow(const Node& node) {
- if (const ShadowRoot* shadow_root = node.GetShadowRoot())
- return shadow_root;
- if (const Node* first_child = node.firstChild())
- return first_child;
- if (const Node* next_sibling = node.nextSibling())
- return next_sibling;
- for (const Node* parent = node.parentNode(); parent;) {
- if (parent->IsShadowRoot()) {
- Node* host = parent->ParentOrShadowHostNode();
- DCHECK_EQ(host->GetShadowRoot(), parent);
- if (const Node* first_child = host->firstChild())
- return first_child;
- parent = host;
- continue;
- }
- if (const Node* next_sibling = parent->nextSibling())
- return next_sibling;
- parent = parent->parentNode();
- }
- return nullptr;
-}
-
static LayoutTextFragment* FirstLetterPartFor(
const LayoutObject* layout_object) {
if (!layout_object->IsText())
return nullptr;
- if (!ToLayoutText(layout_object)->IsTextFragment())
- return nullptr;
- return ToLayoutTextFragment(const_cast<LayoutObject*>(
- AssociatedLayoutObjectOf(*layout_object->GetNode(), 0)));
-}
-
-static LayoutObject* NextLayoutObjectOnDOMTreeIncludeShadow(
- const LayoutObject& layout_object) {
- // If |layout_object| is a first letter part, return remaining part.
- if (const LayoutTextFragment* fragment = ToFirstLetterOrNull(layout_object)) {
- return fragment->AssociatedTextNode()->GetLayoutObject();
- }
- // Otherwise, find the first layouted object of following nodes.
- const Node* node = layout_object.GetNode();
- DCHECK(node);
- for (const Node* next = FindNextNodeOnDOMIncludingShadow(*node); next;
- next = FindNextNodeOnDOMIncludingShadow(*next)) {
- LayoutObject* layout_object = next->GetLayoutObject();
- if (!layout_object)
- continue;
- if (LayoutObject* first_letter = FirstLetterPartFor(layout_object))
- return first_letter;
- return layout_object;
- }
+ if (const LayoutText* layout_text = ToLayoutTextOrNull(layout_object))
+ return ToLayoutTextFragmentOrNull(layout_text->GetFirstLetterPart());
return nullptr;
}
class LayoutSelectionTest : public EditingTestBase {
protected:
- LayoutObject* Current() const { return current_; }
- void Reset() {
- results.clear();
- stream = std::stringstream();
- current_ = GetDocument().body()->GetLayoutObject();
+ static void PrintText(std::ostream& ostream, const Text& text) {
+ ostream << "'" << text.data().Utf8().data() << "'";
}
- void Next() {
- DCHECK(current_);
- current_ = NextLayoutObjectOnDOMTreeIncludeShadow(*current_);
- }
- void TestNext(bool result) {
- results.push_back(result);
- if (!result) {
- stream << "case " << results.size() - 1 << " failed.\n";
- }
- if (!current_) {
- stream << "cases are more than layout objects.\n";
+ static void PrintLayoutTextInfo(const FrameSelection& selection,
+ std::ostream& ostream,
+ const LayoutText& layout_text) {
+ if (layout_text.IsLayoutNGObject()) {
+ // TODO(yoichio): Print NG LayoutSelectionStatus.
return;
}
- Next();
+ const LayoutTextSelectionStatus& status =
+ selection.ComputeLayoutSelectionStatus(layout_text);
+ ostream << "(" << status.start << "," << status.end << ")";
}
- bool CheckResult() {
- if (current_)
- stream << "cases are fewer than layout objects.";
+ static void PrintLayoutObjectInfo(const FrameSelection& selection,
+ std::ostream& ostream,
+ LayoutObject* layout_object) {
+ const SelectionState& status = layout_object->GetSelectionState();
+ ostream << ", " << status;
+ if (status != SelectionState::kNone && layout_object->IsText())
+ PrintLayoutTextInfo(selection, ostream, ToLayoutText(*layout_object));
- std::string errors = stream.str();
- if (errors.size()) {
- std::stringstream layout_tree;
- PrintLayoutTree(layout_tree);
- LOG(ERROR) << "\n" << errors << layout_tree.str();
- }
- return !errors.size();
- }
-
- WTF::Vector<bool> results;
- std::stringstream stream;
-
- void PrintLayoutTree(std::stringstream& stream) {
- for (LayoutObject* runner = GetDocument().body()->GetLayoutObject(); runner;
- runner = NextLayoutObjectOnDOMTreeIncludeShadow(*runner)) {
- stream << '\n';
- PrintLayoutObjectForSelection(stream, runner);
- }
- }
-
- void PrintText(std::ostream& ostream, const Text& text) {
- ostream << "'" << text.data().Utf8().data() << "'";
+ ostream << (layout_object->ShouldInvalidateSelection()
+ ? ", ShouldInvalidate "
+ : ", NotInvalidate ");
}
-
- void PrintSelectionInfo(std::ostream& ostream, LayoutObject* layout_object) {
+ static void PrintSelectionInfo(const FrameSelection& selection,
+ std::ostream& ostream,
+ const Node& node,
+ size_t depth) {
+ if (const Text* text = ToTextOrNull(node))
+ PrintText(ostream, *text);
+ else if (const Element* element = ToElementOrNull(node))
+ ostream << element->tagName().Utf8().data();
+ else
+ ostream << node;
+
+ LayoutObject* layout_object = node.GetLayoutObject();
if (!layout_object) {
- ostream << "<null>";
+ ostream << ", <null LayoutObject> ";
return;
}
- if (const LayoutTextFragment* fragment =
- ToLayoutTextFragmentOrNull(*layout_object)) {
- // TODO(yoichio): Treat LayoutQuote which may generate LayoutTextFragment
- // that's neither first-letter nor remaining text.
- if (fragment->IsRemainingTextLayoutObject())
- ostream << "remaining part of ";
- else
- ostream << "first-letter of ";
- PrintText(ostream, *fragment->AssociatedTextNode());
- } else {
- if (Text* text = ToTextOrNull(layout_object->GetNode()))
- PrintText(ostream, *text);
- else
- ostream << layout_object->GetNode();
+ PrintLayoutObjectInfo(selection, ostream, layout_object);
+ if (LayoutTextFragment* first_letter = FirstLetterPartFor(layout_object)) {
+ ostream << std::endl
+ << RepeatString(" ", depth + 1).Utf8().data() << ":first-letter";
+ PrintLayoutObjectInfo(selection, ostream, first_letter);
}
- ostream << ", " << layout_object->GetSelectionState()
- << (layout_object->ShouldInvalidateSelection()
- ? ", ShouldInvalidate "
- : ", NotInvalidate ");
}
- void PrintDOMTreeInternal(std::ostream& ostream,
- const Node& node,
- size_t depth) {
+ static void PrintDOMTreeInternal(const FrameSelection& selection,
+ std::ostream& ostream,
+ const Node& node,
+ size_t depth) {
ostream << RepeatString(" ", depth).Utf8().data();
- PrintSelectionInfo(ostream, node.GetLayoutObject());
+ if (IsHTMLStyleElement(node)) {
+ ostream << "<style> ";
+ return;
+ }
+ PrintSelectionInfo(selection, ostream, node, depth);
if (ShadowRoot* shadow_root = node.GetShadowRoot()) {
ostream << std::endl << RepeatString(" ", depth + 1).Utf8().data();
- ostream << "#shadow-root";
+ ostream << "#shadow-root ";
for (Node* child = shadow_root->firstChild(); child;
child = child->nextSibling()) {
- PrintDOMTreeInternal(ostream, *child, depth + 2);
+ ostream << std::endl;
+ PrintDOMTreeInternal(selection, ostream, *child, depth + 2);
}
}
for (Node* child = node.firstChild(); child; child = child->nextSibling()) {
ostream << std::endl;
- PrintDOMTreeInternal(ostream, *child, depth + 1);
+ PrintDOMTreeInternal(selection, ostream, *child, depth + 1);
}
}
@@ -189,139 +114,18 @@ class LayoutSelectionTest : public EditingTestBase {
void PrintDOMTreeForDebug() {
std::stringstream stream;
stream << "\nPrintDOMTreeForDebug";
- PrintDOMTreeInternal(stream, *GetDocument().body(), 0u);
+ PrintDOMTreeInternal(Selection(), stream, *GetDocument().body(), 0u);
LOG(INFO) << stream.str();
}
#endif
std::string DumpSelectionInfo() {
std::stringstream stream;
- PrintDOMTreeInternal(stream, *GetDocument().body(), 0u);
+ PrintDOMTreeInternal(Selection(), stream, *GetDocument().body(), 0u);
return stream.str();
}
-
- private:
- LayoutObject* current_ = nullptr;
};
-// You can test SeletionStatus of all LayoutObjects in the body with following
-// macros. See TraverseLayoutObject example below.
-#define TEST_RESET() Reset();
-#define TEST_NEXT(predicate, state, invalidate) \
- TestNext(TestLayoutObject(Current(), predicate, SelectionState::state, \
- InvalidateOption::invalidate));
-#define TEST_CHECK() EXPECT_TRUE(CheckResult())
-
-std::ostream& operator<<(std::ostream& ostream, LayoutObject* layout_object) {
- PrintLayoutObjectForSelection(ostream, layout_object);
- return ostream;
-}
-
-enum class InvalidateOption { ShouldInvalidate, NotInvalidate };
-
-static bool TestLayoutObjectState(LayoutObject* object,
- SelectionState state,
- InvalidateOption invalidate) {
- if (!object)
- return false;
- if (object->GetSelectionState() != state)
- return false;
- if (object->ShouldInvalidateSelection() !=
- (invalidate == InvalidateOption::ShouldInvalidate))
- return false;
- return true;
-}
-
-using IsTypeOf =
- base::RepeatingCallback<bool(const LayoutObject& layout_object)>;
-using IsTypeOfSimple = bool(const LayoutObject& layout_object);
-#define USING_LAYOUTOBJECT_FUNC(member_func) \
- static bool member_func(const LayoutObject& layout_object) { \
- return layout_object.member_func(); \
- }
-
-USING_LAYOUTOBJECT_FUNC(IsLayoutBlock);
-USING_LAYOUTOBJECT_FUNC(IsLayoutBlockFlow);
-USING_LAYOUTOBJECT_FUNC(IsLayoutNGBlockFlow);
-USING_LAYOUTOBJECT_FUNC(IsLayoutInline);
-USING_LAYOUTOBJECT_FUNC(IsBR);
-USING_LAYOUTOBJECT_FUNC(IsListItem);
-USING_LAYOUTOBJECT_FUNC(IsLayoutImage);
-USING_LAYOUTOBJECT_FUNC(IsLayoutButton);
-USING_LAYOUTOBJECT_FUNC(IsRuby);
-USING_LAYOUTOBJECT_FUNC(IsRubyText);
-USING_LAYOUTOBJECT_FUNC(IsSVGRoot);
-USING_LAYOUTOBJECT_FUNC(IsSVGText);
-USING_LAYOUTOBJECT_FUNC(IsLayoutEmbeddedContent);
-
-static IsTypeOf IsLayoutTextFragmentOf(const String& text) {
- return WTF::BindRepeating(
- [](const String& text, const LayoutObject& object) {
- if (!object.IsText())
- return false;
- if (text != ToLayoutText(object).GetText())
- return false;
- return ToLayoutText(object).IsTextFragment();
- },
- text);
-}
-
-static IsTypeOf IsLayoutOf(const String& text) {
- return WTF::BindRepeating(
- [](const String& text, const LayoutObject& object) {
- return ToElement(object.GetNode())->tagName() == text;
- },
- text);
-}
-
-static bool IsSVGTSpan(const LayoutObject& layout_object) {
- return layout_object.GetName() == String("LayoutSVGTSpan");
-}
-
-static bool IsLegacyBlockFlow(const LayoutObject& layout_object) {
- return layout_object.IsLayoutBlockFlow() && !layout_object.IsLayoutNGMixin();
-}
-
-static bool TestLayoutObject(LayoutObject* object,
- IsTypeOfSimple& predicate,
- SelectionState state,
- InvalidateOption invalidate) {
- if (!TestLayoutObjectState(object, state, invalidate))
- return false;
-
- if (!predicate(*object))
- return false;
- return true;
-}
-static bool TestLayoutObject(LayoutObject* object,
- const IsTypeOf& predicate,
- SelectionState state,
- InvalidateOption invalidate) {
- if (!TestLayoutObjectState(object, state, invalidate))
- return false;
-
- if (!predicate.Run(*object))
- return false;
- return true;
-}
-static bool TestLayoutObject(LayoutObject* object,
- const String& text,
- SelectionState state,
- InvalidateOption invalidate) {
- return TestLayoutObject(
- object,
- WTF::BindRepeating(
- [](const String& text, const LayoutObject& object) {
- if (!object.IsText())
- return false;
- if (text != ToLayoutText(object).GetText())
- return false;
- return true;
- },
- text),
- state, invalidate);
-}
-
TEST_F(LayoutSelectionTest, TraverseLayoutObject) {
SetBodyContent("foo<br>bar");
Selection().SetSelectionAndEndTyping(
@@ -331,9 +135,9 @@ TEST_F(LayoutSelectionTest, TraverseLayoutObject) {
Selection().CommitAppearanceIfNeeded();
EXPECT_EQ(
"BODY, Contain, NotInvalidate \n"
- " 'foo', Start, ShouldInvalidate \n"
- " BR, Inside, ShouldInvalidate \n"
- " 'bar', End, ShouldInvalidate ",
+ " 'foo', Start(0,3), ShouldInvalidate \n"
+ " BR, Inside(0,1), ShouldInvalidate \n"
+ " 'bar', End(0,3), ShouldInvalidate ",
DumpSelectionInfo());
}
@@ -347,14 +151,14 @@ TEST_F(LayoutSelectionTest, TraverseLayoutObjectTruncateVisibilityHidden) {
.SelectAllChildren(*GetDocument().body())
.Build());
Selection().CommitAppearanceIfNeeded();
- TEST_RESET();
- TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate);
- TEST_NEXT(IsLayoutInline, kNone, NotInvalidate);
- TEST_NEXT("before", kNone, NotInvalidate);
- TEST_NEXT("foo", kStartAndEnd, ShouldInvalidate);
- TEST_NEXT(IsLayoutInline, kNone, NotInvalidate);
- TEST_NEXT("after", kNone, NotInvalidate);
- TEST_CHECK();
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " SPAN, None, NotInvalidate \n"
+ " 'before', None, NotInvalidate \n"
+ " 'foo', StartAndEnd(0,3), ShouldInvalidate \n"
+ " SPAN, None, NotInvalidate \n"
+ " 'after', None, NotInvalidate ",
+ DumpSelectionInfo());
}
TEST_F(LayoutSelectionTest, TraverseLayoutObjectBRs) {
@@ -364,16 +168,14 @@ TEST_F(LayoutSelectionTest, TraverseLayoutObjectBRs) {
.SelectAllChildren(*GetDocument().body())
.Build());
Selection().CommitAppearanceIfNeeded();
- TEST_RESET();
- TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate);
- TEST_NEXT(IsBR, kStart, ShouldInvalidate);
- TEST_NEXT(IsBR, kInside, ShouldInvalidate);
- TEST_NEXT("foo", kInside, ShouldInvalidate);
- TEST_NEXT(IsBR, kInside, ShouldInvalidate);
- TEST_NEXT(IsBR, kEnd, ShouldInvalidate);
- TEST_CHECK();
- EXPECT_FALSE(Selection().LayoutSelectionStart().has_value());
- EXPECT_FALSE(Selection().LayoutSelectionEnd().has_value());
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " BR, Start(0,1), ShouldInvalidate \n"
+ " BR, Inside(0,1), ShouldInvalidate \n"
+ " 'foo', Inside(0,3), ShouldInvalidate \n"
+ " BR, Inside(0,1), ShouldInvalidate \n"
+ " BR, End(0,0), ShouldInvalidate ",
+ DumpSelectionInfo());
}
TEST_F(LayoutSelectionTest, TraverseLayoutObjectListStyleImage) {
@@ -387,14 +189,15 @@ TEST_F(LayoutSelectionTest, TraverseLayoutObjectListStyleImage) {
.SelectAllChildren(*GetDocument().body())
.Build());
Selection().CommitAppearanceIfNeeded();
- TEST_RESET();
- TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate);
- TEST_NEXT(IsLayoutBlockFlow, kContain, NotInvalidate);
- TEST_NEXT(IsListItem, kContain, NotInvalidate);
- TEST_NEXT("foo", kStart, ShouldInvalidate);
- TEST_NEXT(IsListItem, kContain, NotInvalidate);
- TEST_NEXT("bar", kEnd, ShouldInvalidate);
- TEST_CHECK();
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " <style> \n"
+ " UL, Contain, NotInvalidate \n"
+ " LI, Contain, NotInvalidate \n"
+ " 'foo', Start(0,3), ShouldInvalidate \n"
+ " LI, Contain, NotInvalidate \n"
+ " 'bar', End(0,3), ShouldInvalidate ",
+ DumpSelectionInfo());
}
TEST_F(LayoutSelectionTest, TraverseLayoutObjectCrossingShadowBoundary) {
@@ -408,16 +211,19 @@ TEST_F(LayoutSelectionTest, TraverseLayoutObjectCrossingShadowBoundary) {
"<span slot=s1><!--|-->bar1</span><span slot=s2>bar2</span>"
"</div>"));
Selection().CommitAppearanceIfNeeded();
- TEST_RESET();
- TEST_NEXT(IsLayoutOf("BODY"), kContain, NotInvalidate);
- TEST_NEXT("foo", kStart, ShouldInvalidate);
- TEST_NEXT(IsLayoutOf("DIV"), kContain, NotInvalidate);
- TEST_NEXT("Foo", kInside, ShouldInvalidate);
- TEST_NEXT(IsLayoutOf("SPAN"), kNone, NotInvalidate);
- TEST_NEXT("bar1", kNone, NotInvalidate);
- TEST_NEXT(IsLayoutOf("SPAN"), kNone, NotInvalidate);
- TEST_NEXT("bar2", kEnd, ShouldInvalidate);
- TEST_CHECK();
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " 'foo', Start(0,3), ShouldInvalidate \n"
+ " DIV, Contain, NotInvalidate \n"
+ " #shadow-root \n"
+ " 'Foo', Inside(0,3), ShouldInvalidate \n"
+ " SLOT, <null LayoutObject> \n"
+ " SLOT, <null LayoutObject> \n"
+ " SPAN, None, NotInvalidate \n"
+ " 'bar1', None, NotInvalidate \n"
+ " SPAN, Contain, NotInvalidate \n"
+ " 'bar2', End(0,4), ShouldInvalidate ",
+ DumpSelectionInfo());
}
// crbug.com/752715
@@ -432,16 +238,16 @@ TEST_F(LayoutSelectionTest,
Position(span->firstChild(), 3))
.Build());
Selection().CommitAppearanceIfNeeded();
- TEST_RESET();
- TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate);
- TEST_NEXT(IsLayoutBlockFlow, kNone, NotInvalidate);
- TEST_NEXT("div1", kNone, NotInvalidate);
- TEST_NEXT(IsLayoutBlockFlow, kContain, NotInvalidate);
- TEST_NEXT("foo", kNone, NotInvalidate);
- TEST_NEXT(IsLayoutInline, kNone, NotInvalidate);
- TEST_NEXT("bar", kStartAndEnd, ShouldInvalidate);
- TEST_NEXT("baz", kNone, NotInvalidate);
- TEST_CHECK();
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " DIV, None, NotInvalidate \n"
+ " 'div1', None, NotInvalidate \n"
+ " DIV, Contain, NotInvalidate \n"
+ " 'foo', None, NotInvalidate \n"
+ " SPAN, Contain, NotInvalidate \n"
+ " 'bar', StartAndEnd(0,3), ShouldInvalidate \n"
+ " 'baz', None, NotInvalidate ",
+ DumpSelectionInfo());
Node* d1 = GetDocument().QuerySelector("#d1");
Node* d2 = GetDocument().QuerySelector("#d2");
@@ -451,16 +257,16 @@ TEST_F(LayoutSelectionTest,
.Build());
// This commit should not crash.
Selection().CommitAppearanceIfNeeded();
- TEST_RESET();
- TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate);
- TEST_NEXT(IsLayoutBlockFlow, kContain, NotInvalidate);
- TEST_NEXT("div1", kStartAndEnd, ShouldInvalidate);
- TEST_NEXT(IsLayoutBlockFlow, kNone, NotInvalidate);
- TEST_NEXT("foo", kNone, NotInvalidate);
- TEST_NEXT(IsLayoutInline, kNone, NotInvalidate);
- TEST_NEXT("bar", kNone, ShouldInvalidate);
- TEST_NEXT("baz", kNone, NotInvalidate);
- TEST_CHECK();
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " DIV, Contain, NotInvalidate \n"
+ " 'div1', StartAndEnd(0,4), ShouldInvalidate \n"
+ " DIV, None, NotInvalidate \n"
+ " 'foo', None, NotInvalidate \n"
+ " SPAN, None, NotInvalidate \n"
+ " 'bar', None, ShouldInvalidate \n"
+ " 'baz', None, NotInvalidate ",
+ DumpSelectionInfo());
}
TEST_F(LayoutSelectionTest, TraverseLayoutObjectLineWrap) {
@@ -470,12 +276,10 @@ TEST_F(LayoutSelectionTest, TraverseLayoutObjectLineWrap) {
.SelectAllChildren(*GetDocument().body())
.Build());
Selection().CommitAppearanceIfNeeded();
- TEST_RESET();
- TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate);
- TEST_NEXT("bar\n", kStartAndEnd, ShouldInvalidate);
- TEST_CHECK();
- EXPECT_EQ(0u, Selection().LayoutSelectionStart());
- EXPECT_EQ(4u, Selection().LayoutSelectionEnd());
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " 'bar\n', StartAndEnd(0,4), ShouldInvalidate ",
+ DumpSelectionInfo());
}
TEST_F(LayoutSelectionTest, FirstLetter) {
@@ -487,12 +291,27 @@ TEST_F(LayoutSelectionTest, FirstLetter) {
.SelectAllChildren(*GetDocument().body())
.Build());
Selection().CommitAppearanceIfNeeded();
- TEST_RESET();
- TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate);
- TEST_NEXT(IsLayoutInline, kNone, NotInvalidate);
- TEST_NEXT(IsLayoutTextFragmentOf("f"), kStart, ShouldInvalidate);
- TEST_NEXT(IsLayoutTextFragmentOf("oo"), kEnd, ShouldInvalidate);
- TEST_CHECK();
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " <style> \n"
+ " SPAN, Contain, NotInvalidate \n"
+ " 'foo', End(0,2), ShouldInvalidate \n"
+ " :first-letter, Start(0,1), ShouldInvalidate ",
+ DumpSelectionInfo());
+}
+
+TEST_F(LayoutSelectionTest, FirstLetterMultiple) {
+ Selection().SetSelectionAndEndTyping(
+ SetSelectionTextToBody("<style>::first-letter { color: red; }</style>"
+ "<span> [^f]o|o</span>"));
+ Selection().CommitAppearanceIfNeeded();
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " <style> \n"
+ " SPAN, Contain, NotInvalidate \n"
+ " ' [f]oo', End(0,1), ShouldInvalidate \n"
+ " :first-letter, Start(2,4), ShouldInvalidate ",
+ DumpSelectionInfo());
}
TEST_F(LayoutSelectionTest, FirstLetterClearSeletion) {
@@ -500,24 +319,25 @@ TEST_F(LayoutSelectionTest, FirstLetterClearSeletion) {
Selection().SetSelectionAndEndTyping(
SetSelectionTextToBody("fo^o<div>bar</div>b|az"));
Selection().CommitAppearanceIfNeeded();
- TEST_RESET();
- TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate);
- TEST_NEXT("foo", kStart, ShouldInvalidate);
- TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate);
- TEST_NEXT(IsLayoutTextFragmentOf("b"), kInside, ShouldInvalidate);
- TEST_NEXT(IsLayoutTextFragmentOf("ar"), kInside, ShouldInvalidate);
- TEST_NEXT("baz", kEnd, ShouldInvalidate);
- TEST_CHECK();
-
- Selection().ClearLayoutSelection();
- TEST_RESET();
- TEST_NEXT(IsLayoutBlock, kNone, NotInvalidate);
- TEST_NEXT("foo", kNone, ShouldInvalidate);
- TEST_NEXT(IsLayoutBlock, kNone, NotInvalidate);
- TEST_NEXT(IsLayoutTextFragmentOf("b"), kNone, ShouldInvalidate);
- TEST_NEXT(IsLayoutTextFragmentOf("ar"), kNone, ShouldInvalidate);
- TEST_NEXT("baz", kNone, ShouldInvalidate);
- TEST_CHECK();
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " 'foo', Start(2,3), ShouldInvalidate \n"
+ " DIV, Contain, NotInvalidate \n"
+ " 'bar', Inside(0,2), ShouldInvalidate \n"
+ " :first-letter, Inside(0,1), ShouldInvalidate \n"
+ " 'baz', End(0,1), ShouldInvalidate ",
+ DumpSelectionInfo());
+
+ Selection().Clear();
+ Selection().CommitAppearanceIfNeeded();
+ EXPECT_EQ(
+ "BODY, None, NotInvalidate \n"
+ " 'foo', None, ShouldInvalidate \n"
+ " DIV, None, NotInvalidate \n"
+ " 'bar', None, ShouldInvalidate \n"
+ " :first-letter, None, ShouldInvalidate \n"
+ " 'baz', None, ShouldInvalidate ",
+ DumpSelectionInfo());
}
TEST_F(LayoutSelectionTest, FirstLetterUpdateSeletion) {
@@ -536,31 +356,29 @@ TEST_F(LayoutSelectionTest, FirstLetterUpdateSeletion) {
.SetBaseAndExtent({foo, 2}, {baz, 1})
.Build());
Selection().CommitAppearanceIfNeeded();
- TEST_RESET();
- TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate);
- TEST_NEXT("foo", kStart, ShouldInvalidate);
- TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate);
- TEST_NEXT(IsLayoutTextFragmentOf("b"), kInside, ShouldInvalidate);
- TEST_NEXT(IsLayoutTextFragmentOf("ar"), kInside, ShouldInvalidate);
- TEST_NEXT("baz", kEnd, ShouldInvalidate);
- TEST_CHECK();
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " <style> \n"
+ " 'foo', Start(2,3), ShouldInvalidate \n"
+ " DIV, Contain, NotInvalidate \n"
+ " 'bar', Inside(0,2), ShouldInvalidate \n"
+ " :first-letter, Inside(0,1), ShouldInvalidate \n"
+ " 'baz', End(0,1), ShouldInvalidate ",
+ DumpSelectionInfo());
// <div>foo</div><div>bar</div>ba^z|
Selection().SetSelectionAndEndTyping(SelectionInDOMTree::Builder()
.SetBaseAndExtent({baz, 2}, {baz, 3})
.Build());
Selection().CommitAppearanceIfNeeded();
- TEST_RESET();
- TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate);
- TEST_NEXT("foo", kNone, ShouldInvalidate);
- // TODO(yoichio): Invalidating next LayoutBlock is flaky but it doesn't
- // matter in wild because we don't paint selection gap. I will update
- // invalidating propagation so this flakiness should be fixed as:
- // TEST_NEXT(IsLayoutBlock, kNone, NotInvalidate);
- Next();
- TEST_NEXT(IsLayoutTextFragmentOf("b"), kNone, ShouldInvalidate);
- TEST_NEXT(IsLayoutTextFragmentOf("ar"), kNone, ShouldInvalidate);
- TEST_NEXT("baz", kStartAndEnd, ShouldInvalidate);
- TEST_CHECK();
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " <style> \n"
+ " 'foo', None, ShouldInvalidate \n"
+ " DIV, None, NotInvalidate \n"
+ " 'bar', None, ShouldInvalidate \n"
+ " :first-letter, None, ShouldInvalidate \n"
+ " 'baz', StartAndEnd(2,3), ShouldInvalidate ",
+ DumpSelectionInfo());
}
TEST_F(LayoutSelectionTest, CommitAppearanceIfNeededNotCrash) {
@@ -578,12 +396,10 @@ TEST_F(LayoutSelectionTest, SelectImage) {
SetSelectionTextToBody("^<img style=\"width:100px; height:100px\"/>|");
Selection().SetSelectionAndEndTyping(selection);
Selection().CommitAppearanceIfNeeded();
- TEST_RESET();
- TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate);
- TEST_NEXT(IsLayoutImage, kStartAndEnd, ShouldInvalidate);
- TEST_CHECK();
- EXPECT_FALSE(Selection().LayoutSelectionStart().has_value());
- EXPECT_FALSE(Selection().LayoutSelectionEnd().has_value());
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " IMG, StartAndEnd, ShouldInvalidate ",
+ DumpSelectionInfo());
}
TEST_F(LayoutSelectionTest, MoveOnSameNode_Start) {
@@ -591,23 +407,21 @@ TEST_F(LayoutSelectionTest, MoveOnSameNode_Start) {
SetSelectionTextToBody("f^oo<span>b|ar</span>");
Selection().SetSelectionAndEndTyping(selection);
Selection().CommitAppearanceIfNeeded();
- TEST_RESET();
- TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate);
- TEST_NEXT("foo", kStart, ShouldInvalidate);
- TEST_NEXT(IsLayoutInline, kNone, NotInvalidate);
- TEST_NEXT("bar", kEnd, ShouldInvalidate);
- TEST_CHECK();
- EXPECT_EQ(1u, Selection().LayoutSelectionStart());
- EXPECT_EQ(1u, Selection().LayoutSelectionEnd());
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " 'foo', Start(1,3), ShouldInvalidate \n"
+ " SPAN, Contain, NotInvalidate \n"
+ " 'bar', End(0,1), ShouldInvalidate ",
+ DumpSelectionInfo());
// Paint virtually and clear ShouldInvalidate flag.
UpdateAllLifecyclePhases();
- TEST_RESET();
- TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate);
- TEST_NEXT("foo", kStart, NotInvalidate);
- TEST_NEXT(IsLayoutInline, kNone, NotInvalidate);
- TEST_NEXT("bar", kEnd, NotInvalidate);
- TEST_CHECK();
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " 'foo', Start(1,3), NotInvalidate \n"
+ " SPAN, Contain, NotInvalidate \n"
+ " 'bar', End(0,1), NotInvalidate ",
+ DumpSelectionInfo());
// "fo^o<span>b|ar</span>"
Selection().SetSelectionAndEndTyping(
@@ -617,14 +431,12 @@ TEST_F(LayoutSelectionTest, MoveOnSameNode_Start) {
.Build());
Selection().CommitAppearanceIfNeeded();
// Only "foo" should be invalidated.
- TEST_RESET();
- TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate);
- TEST_NEXT("foo", kStart, ShouldInvalidate);
- TEST_NEXT(IsLayoutInline, kNone, NotInvalidate);
- TEST_NEXT("bar", kEnd, NotInvalidate);
- TEST_CHECK();
- EXPECT_EQ(2u, Selection().LayoutSelectionStart());
- EXPECT_EQ(1u, Selection().LayoutSelectionEnd());
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " 'foo', Start(2,3), ShouldInvalidate \n"
+ " SPAN, Contain, NotInvalidate \n"
+ " 'bar', End(0,1), NotInvalidate ",
+ DumpSelectionInfo());
}
TEST_F(LayoutSelectionTest, MoveOnSameNode_End) {
@@ -632,23 +444,21 @@ TEST_F(LayoutSelectionTest, MoveOnSameNode_End) {
SetSelectionTextToBody("f^oo<span>b|ar</span>");
Selection().SetSelectionAndEndTyping(selection);
Selection().CommitAppearanceIfNeeded();
- TEST_RESET();
- TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate);
- TEST_NEXT("foo", kStart, ShouldInvalidate);
- TEST_NEXT(IsLayoutInline, kNone, NotInvalidate);
- TEST_NEXT("bar", kEnd, ShouldInvalidate);
- TEST_CHECK();
- EXPECT_EQ(1u, Selection().LayoutSelectionStart());
- EXPECT_EQ(1u, Selection().LayoutSelectionEnd());
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " 'foo', Start(1,3), ShouldInvalidate \n"
+ " SPAN, Contain, NotInvalidate \n"
+ " 'bar', End(0,1), ShouldInvalidate ",
+ DumpSelectionInfo());
// Paint virtually and clear ShouldInvalidate flag.
UpdateAllLifecyclePhases();
- TEST_RESET();
- TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate);
- TEST_NEXT("foo", kStart, NotInvalidate);
- TEST_NEXT(IsLayoutInline, kNone, NotInvalidate);
- TEST_NEXT("bar", kEnd, NotInvalidate);
- TEST_CHECK();
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " 'foo', Start(1,3), NotInvalidate \n"
+ " SPAN, Contain, NotInvalidate \n"
+ " 'bar', End(0,1), NotInvalidate ",
+ DumpSelectionInfo());
// "fo^o<span>ba|r</span>"
Selection().SetSelectionAndEndTyping(
@@ -658,33 +468,29 @@ TEST_F(LayoutSelectionTest, MoveOnSameNode_End) {
.Build());
Selection().CommitAppearanceIfNeeded();
// Only "bar" should be invalidated.
- TEST_RESET();
- TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate);
- TEST_NEXT("foo", kStart, NotInvalidate);
- TEST_NEXT(IsLayoutInline, kNone, NotInvalidate);
- TEST_NEXT("bar", kEnd, ShouldInvalidate);
- TEST_CHECK();
- EXPECT_EQ(1u, Selection().LayoutSelectionStart());
- EXPECT_EQ(2u, Selection().LayoutSelectionEnd());
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " 'foo', Start(1,3), NotInvalidate \n"
+ " SPAN, Contain, NotInvalidate \n"
+ " 'bar', End(0,2), ShouldInvalidate ",
+ DumpSelectionInfo());
}
TEST_F(LayoutSelectionTest, MoveOnSameNode_StartAndEnd) {
const SelectionInDOMTree& selection = SetSelectionTextToBody("f^oob|ar");
Selection().SetSelectionAndEndTyping(selection);
Selection().CommitAppearanceIfNeeded();
- TEST_RESET();
- TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate);
- TEST_NEXT("foobar", kStartAndEnd, ShouldInvalidate);
- TEST_CHECK();
- EXPECT_EQ(1u, Selection().LayoutSelectionStart());
- EXPECT_EQ(4u, Selection().LayoutSelectionEnd());
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " 'foobar', StartAndEnd(1,4), ShouldInvalidate ",
+ DumpSelectionInfo());
// Paint virtually and clear ShouldInvalidate flag.
UpdateAllLifecyclePhases();
- TEST_RESET();
- TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate);
- TEST_NEXT("foobar", kStartAndEnd, NotInvalidate);
- TEST_CHECK();
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " 'foobar', StartAndEnd(1,4), NotInvalidate ",
+ DumpSelectionInfo());
// "f^ooba|r"
Selection().SetSelectionAndEndTyping(
@@ -694,31 +500,27 @@ TEST_F(LayoutSelectionTest, MoveOnSameNode_StartAndEnd) {
.Build());
Selection().CommitAppearanceIfNeeded();
// "foobar" should be invalidated.
- TEST_RESET();
- TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate);
- TEST_NEXT("foobar", kStartAndEnd, ShouldInvalidate);
- TEST_CHECK();
- EXPECT_EQ(1u, Selection().LayoutSelectionStart());
- EXPECT_EQ(5u, Selection().LayoutSelectionEnd());
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " 'foobar', StartAndEnd(1,5), ShouldInvalidate ",
+ DumpSelectionInfo());
}
TEST_F(LayoutSelectionTest, MoveOnSameNode_StartAndEnd_Collapse) {
const SelectionInDOMTree& selection = SetSelectionTextToBody("f^oob|ar");
Selection().SetSelectionAndEndTyping(selection);
Selection().CommitAppearanceIfNeeded();
- TEST_RESET();
- TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate);
- TEST_NEXT("foobar", kStartAndEnd, ShouldInvalidate);
- TEST_CHECK();
- EXPECT_EQ(1u, Selection().LayoutSelectionStart());
- EXPECT_EQ(4u, Selection().LayoutSelectionEnd());
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " 'foobar', StartAndEnd(1,4), ShouldInvalidate ",
+ DumpSelectionInfo());
// Paint virtually and clear ShouldInvalidate flag.
UpdateAllLifecyclePhases();
- TEST_RESET();
- TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate);
- TEST_NEXT("foobar", kStartAndEnd, NotInvalidate);
- TEST_CHECK();
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " 'foobar', StartAndEnd(1,4), NotInvalidate ",
+ DumpSelectionInfo());
// "foo^|bar"
Selection().SetSelectionAndEndTyping(
@@ -727,12 +529,10 @@ TEST_F(LayoutSelectionTest, MoveOnSameNode_StartAndEnd_Collapse) {
.Build());
Selection().CommitAppearanceIfNeeded();
// "foobar" should be invalidated.
- TEST_RESET();
- TEST_NEXT(IsLayoutBlock, kNone, NotInvalidate);
- TEST_NEXT("foobar", kNone, ShouldInvalidate);
- TEST_CHECK();
- EXPECT_FALSE(Selection().LayoutSelectionStart().has_value());
- EXPECT_FALSE(Selection().LayoutSelectionEnd().has_value());
+ EXPECT_EQ(
+ "BODY, None, NotInvalidate \n"
+ " 'foobar', None, ShouldInvalidate ",
+ DumpSelectionInfo());
}
TEST_F(LayoutSelectionTest, ContentEditableButton) {
@@ -742,40 +542,38 @@ TEST_F(LayoutSelectionTest, ContentEditableButton) {
.SelectAllChildren(*GetDocument().body())
.Build());
Selection().CommitAppearanceIfNeeded();
- TEST_RESET();
- TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate);
- TEST_NEXT(IsLayoutButton, kContain, NotInvalidate);
- TEST_NEXT("foo", kStartAndEnd, ShouldInvalidate);
- TEST_CHECK();
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " INPUT, Contain, NotInvalidate \n"
+ " #shadow-root \n"
+ " 'foo', StartAndEnd(0,3), ShouldInvalidate ",
+ DumpSelectionInfo());
}
TEST_F(LayoutSelectionTest, ClearSelection) {
Selection().SetSelectionAndEndTyping(
SetSelectionTextToBody("<div>f^o|o</div>"));
Selection().CommitAppearanceIfNeeded();
- TEST_RESET();
- TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate);
- TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate);
- TEST_NEXT("foo", kStartAndEnd, ShouldInvalidate);
- TEST_CHECK();
- EXPECT_EQ(1u, Selection().LayoutSelectionStart());
- EXPECT_EQ(2u, Selection().LayoutSelectionEnd());
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " DIV, Contain, NotInvalidate \n"
+ " 'foo', StartAndEnd(1,2), ShouldInvalidate ",
+ DumpSelectionInfo());
UpdateAllLifecyclePhases();
- TEST_RESET();
- TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate);
- TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate);
- TEST_NEXT("foo", kStartAndEnd, NotInvalidate);
- TEST_CHECK();
-
- Selection().ClearLayoutSelection();
- TEST_RESET();
- TEST_NEXT(IsLayoutBlock, kNone, NotInvalidate);
- TEST_NEXT(IsLayoutBlock, kNone, NotInvalidate);
- TEST_NEXT("foo", kNone, ShouldInvalidate);
- TEST_CHECK();
- EXPECT_FALSE(Selection().LayoutSelectionStart().has_value());
- EXPECT_FALSE(Selection().LayoutSelectionEnd().has_value());
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " DIV, Contain, NotInvalidate \n"
+ " 'foo', StartAndEnd(1,2), NotInvalidate ",
+ DumpSelectionInfo());
+
+ Selection().Clear();
+ Selection().CommitAppearanceIfNeeded();
+ EXPECT_EQ(
+ "BODY, None, NotInvalidate \n"
+ " DIV, None, NotInvalidate \n"
+ " 'foo', None, ShouldInvalidate ",
+ DumpSelectionInfo());
}
TEST_F(LayoutSelectionTest, SVG) {
@@ -783,23 +581,21 @@ TEST_F(LayoutSelectionTest, SVG) {
SetSelectionTextToBody("<svg><text x=10 y=10>fo^o|bar</text></svg>");
Selection().SetSelectionAndEndTyping(selection);
Selection().CommitAppearanceIfNeeded();
- TEST_RESET();
- TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate);
- TEST_NEXT(IsSVGRoot, kNone, NotInvalidate);
// LayoutSVGText should be invalidate though it is kContain.
- TEST_NEXT(IsSVGText, kContain, ShouldInvalidate);
- TEST_NEXT("foobar", kStartAndEnd, ShouldInvalidate);
- TEST_CHECK();
- EXPECT_EQ(2u, Selection().LayoutSelectionStart());
- EXPECT_EQ(3u, Selection().LayoutSelectionEnd());
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " svg, Contain, NotInvalidate \n"
+ " text, Contain, ShouldInvalidate \n"
+ " 'foobar', StartAndEnd(2,3), ShouldInvalidate ",
+ DumpSelectionInfo());
UpdateAllLifecyclePhases();
- TEST_RESET();
- TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate);
- TEST_NEXT(IsSVGRoot, kNone, NotInvalidate);
- TEST_NEXT(IsSVGText, kContain, NotInvalidate);
- TEST_NEXT("foobar", kStartAndEnd, NotInvalidate);
- TEST_CHECK();
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " svg, Contain, NotInvalidate \n"
+ " text, Contain, NotInvalidate \n"
+ " 'foobar', StartAndEnd(2,3), NotInvalidate ",
+ DumpSelectionInfo());
Selection().SetSelectionAndEndTyping(
SelectionInDOMTree::Builder()
@@ -807,14 +603,12 @@ TEST_F(LayoutSelectionTest, SVG) {
{selection.Extent().AnchorNode(), 4})
.Build());
Selection().CommitAppearanceIfNeeded();
- TEST_RESET();
- TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate);
- TEST_NEXT(IsSVGRoot, kNone, NotInvalidate);
- TEST_NEXT(IsSVGText, kContain, ShouldInvalidate);
- TEST_NEXT("foobar", kStartAndEnd, ShouldInvalidate);
- TEST_CHECK();
- EXPECT_EQ(2u, Selection().LayoutSelectionStart());
- EXPECT_EQ(4u, Selection().LayoutSelectionEnd());
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " svg, Contain, NotInvalidate \n"
+ " text, Contain, ShouldInvalidate \n"
+ " 'foobar', StartAndEnd(2,4), ShouldInvalidate ",
+ DumpSelectionInfo());
}
// crbug.com/781705
@@ -822,26 +616,24 @@ TEST_F(LayoutSelectionTest, SVGAncestor) {
const SelectionInDOMTree& selection = SetSelectionTextToBody(
"<svg><text x=10 y=10><tspan>fo^o|bar</tspan></text></svg>");
Selection().SetSelectionAndEndTyping(selection);
- Selection().CommitAppearanceIfNeeded();
- TEST_RESET();
- TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate);
- TEST_NEXT(IsSVGRoot, kNone, NotInvalidate);
// LayoutSVGText should be invalidated.
- TEST_NEXT(IsSVGText, kContain, ShouldInvalidate);
- TEST_NEXT(IsSVGTSpan, kNone, NotInvalidate);
- TEST_NEXT("foobar", kStartAndEnd, ShouldInvalidate);
- TEST_CHECK();
- EXPECT_EQ(2u, Selection().LayoutSelectionStart());
- EXPECT_EQ(3u, Selection().LayoutSelectionEnd());
+ Selection().CommitAppearanceIfNeeded();
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " svg, Contain, NotInvalidate \n"
+ " text, Contain, ShouldInvalidate \n"
+ " tspan, Contain, NotInvalidate \n"
+ " 'foobar', StartAndEnd(2,3), ShouldInvalidate ",
+ DumpSelectionInfo());
UpdateAllLifecyclePhases();
- TEST_RESET();
- TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate);
- TEST_NEXT(IsSVGRoot, kNone, NotInvalidate);
- TEST_NEXT(IsSVGText, kContain, NotInvalidate);
- TEST_NEXT(IsSVGTSpan, kNone, NotInvalidate);
- TEST_NEXT("foobar", kStartAndEnd, NotInvalidate);
- TEST_CHECK();
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " svg, Contain, NotInvalidate \n"
+ " text, Contain, NotInvalidate \n"
+ " tspan, Contain, NotInvalidate \n"
+ " 'foobar', StartAndEnd(2,3), NotInvalidate ",
+ DumpSelectionInfo());
Selection().SetSelectionAndEndTyping(
SelectionInDOMTree::Builder()
@@ -849,25 +641,25 @@ TEST_F(LayoutSelectionTest, SVGAncestor) {
{selection.Extent().AnchorNode(), 4})
.Build());
Selection().CommitAppearanceIfNeeded();
- TEST_RESET();
- TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate);
- TEST_NEXT(IsSVGRoot, kNone, NotInvalidate);
- TEST_NEXT(IsSVGText, kContain, ShouldInvalidate);
- TEST_NEXT(IsSVGTSpan, kNone, NotInvalidate);
- TEST_NEXT("foobar", kStartAndEnd, ShouldInvalidate);
- TEST_CHECK();
- EXPECT_EQ(2u, Selection().LayoutSelectionStart());
- EXPECT_EQ(4u, Selection().LayoutSelectionEnd());
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " svg, Contain, NotInvalidate \n"
+ " text, Contain, ShouldInvalidate \n"
+ " tspan, Contain, NotInvalidate \n"
+ " 'foobar', StartAndEnd(2,4), ShouldInvalidate ",
+ DumpSelectionInfo());
}
TEST_F(LayoutSelectionTest, Embed) {
Selection().SetSelectionAndEndTyping(
SetSelectionTextToBody("^<embed type=foobar></embed>|"));
Selection().CommitAppearanceIfNeeded();
- TEST_RESET();
- TEST_NEXT(IsLayoutBlock, kContain, NotInvalidate);
- TEST_NEXT(IsLayoutEmbeddedContent, kStartAndEnd, ShouldInvalidate);
- TEST_CHECK();
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " EMBED, StartAndEnd, ShouldInvalidate \n"
+ " #shadow-root \n"
+ " SLOT, <null LayoutObject> ",
+ DumpSelectionInfo());
}
// http:/crbug.com/843144
@@ -875,34 +667,209 @@ TEST_F(LayoutSelectionTest, Ruby) {
Selection().SetSelectionAndEndTyping(
SetSelectionTextToBody("^<ruby>foo<rt>bar</rt></ruby>|"));
Selection().CommitAppearanceIfNeeded();
- TEST_RESET();
- TEST_NEXT(IsLayoutOf("BODY"), kContain, NotInvalidate);
- TEST_NEXT(IsRuby, kNone, NotInvalidate);
- TEST_NEXT("foo", kStart, ShouldInvalidate);
- TEST_NEXT(IsRubyText, kContain, NotInvalidate);
- TEST_NEXT("bar", kEnd, ShouldInvalidate);
- TEST_CHECK();
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " RUBY, Contain, NotInvalidate \n"
+ " 'foo', Start(0,3), ShouldInvalidate \n"
+ " RT, Contain, NotInvalidate \n"
+ " 'bar', End(0,3), ShouldInvalidate ",
+ DumpSelectionInfo());
+
+ UpdateAllLifecyclePhases();
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " RUBY, Contain, NotInvalidate \n"
+ " 'foo', Start(0,3), NotInvalidate \n"
+ " RT, Contain, NotInvalidate \n"
+ " 'bar', End(0,3), NotInvalidate ",
+ DumpSelectionInfo());
+
+ Selection().Clear();
+ Selection().CommitAppearanceIfNeeded();
+ EXPECT_EQ(
+ "BODY, None, NotInvalidate \n"
+ " RUBY, None, NotInvalidate \n"
+ " 'foo', None, ShouldInvalidate \n"
+ " RT, None, NotInvalidate \n"
+ " 'bar', None, ShouldInvalidate ",
+ DumpSelectionInfo());
+}
+
+TEST_F(LayoutSelectionTest, ClearByRemoveNode) {
+ Selection().SetSelectionAndEndTyping(
+ SetSelectionTextToBody("^foo<span>bar</span>baz|"));
+ Selection().CommitAppearanceIfNeeded();
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " 'foo', Start(0,3), ShouldInvalidate \n"
+ " SPAN, Contain, NotInvalidate \n"
+ " 'bar', Inside(0,3), ShouldInvalidate \n"
+ " 'baz', End(0,3), ShouldInvalidate ",
+ DumpSelectionInfo());
+
+ Node* baz = GetDocument().body()->lastChild();
+ baz->remove();
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " 'foo', Start(0,3), ShouldInvalidate \n"
+ " SPAN, Contain, NotInvalidate \n"
+ " 'bar', Inside(0,3), ShouldInvalidate ",
+ DumpSelectionInfo());
+
+ UpdateAllLifecyclePhases();
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " 'foo', Start(0,3), NotInvalidate \n"
+ " SPAN, Contain, NotInvalidate \n"
+ " 'bar', End(0,3), NotInvalidate ",
+ DumpSelectionInfo());
+}
+
+TEST_F(LayoutSelectionTest, ClearByRemoveLayoutObject) {
+ Selection().SetSelectionAndEndTyping(
+ SetSelectionTextToBody("^foo<span>bar</span><span>baz</span>|"));
+ Selection().CommitAppearanceIfNeeded();
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " 'foo', Start(0,3), ShouldInvalidate \n"
+ " SPAN, Contain, NotInvalidate \n"
+ " 'bar', Inside(0,3), ShouldInvalidate \n"
+ " SPAN, Contain, NotInvalidate \n"
+ " 'baz', End(0,3), ShouldInvalidate ",
+ DumpSelectionInfo());
+
+ Element* span_baz = ToElement(GetDocument().body()->lastChild());
+ span_baz->SetInlineStyleProperty(CSSPropertyDisplay, CSSValueNone);
+ GetDocument().UpdateStyleAndLayoutTreeIgnorePendingStylesheets();
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " 'foo', Start(0,3), ShouldInvalidate \n"
+ " SPAN, Contain, NotInvalidate \n"
+ " 'bar', Inside(0,3), ShouldInvalidate \n"
+ " SPAN, <null LayoutObject> \n"
+ " 'baz', <null LayoutObject> ",
+ DumpSelectionInfo());
+ UpdateAllLifecyclePhases();
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " 'foo', Start(0,3), NotInvalidate \n"
+ " SPAN, Contain, NotInvalidate \n"
+ " 'bar', End(0,3), NotInvalidate \n"
+ " SPAN, <null LayoutObject> \n"
+ " 'baz', <null LayoutObject> ",
+ DumpSelectionInfo());
+}
+
+TEST_F(LayoutSelectionTest, ClearBySlotChange) {
+ Selection().SetSelectionAndEndTyping(
+ SetSelectionTextToBody("<div>"
+ "<template data-mode=open>"
+ "^Foo<slot name=s1></slot>|"
+ "</template>"
+ "baz<span slot=s1>bar</span>"
+ "</div>"));
+ Selection().CommitAppearanceIfNeeded();
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " DIV, Contain, NotInvalidate \n"
+ " #shadow-root \n"
+ " 'Foo', Start(0,3), ShouldInvalidate \n"
+ " SLOT, <null LayoutObject> \n"
+ " 'baz', <null LayoutObject> \n"
+ " SPAN, Contain, NotInvalidate \n"
+ " 'bar', End(0,3), ShouldInvalidate ",
+ DumpSelectionInfo());
+ Element* slot =
+ GetDocument().body()->firstChild()->GetShadowRoot()->QuerySelector(
+ "slot");
+ slot->setAttribute("name", "s2");
+ GetDocument().UpdateStyleAndLayoutTreeIgnorePendingStylesheets();
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " DIV, Contain, NotInvalidate \n"
+ " #shadow-root \n"
+ " 'Foo', Start(0,3), ShouldInvalidate \n"
+ " SLOT, <null LayoutObject> \n"
+ " 'baz', <null LayoutObject> \n"
+ " SPAN, <null LayoutObject> \n"
+ " 'bar', <null LayoutObject> ",
+ DumpSelectionInfo());
UpdateAllLifecyclePhases();
- TEST_RESET();
- TEST_NEXT(IsLayoutOf("BODY"), kContain, NotInvalidate);
- TEST_NEXT(IsRuby, kNone, NotInvalidate);
- TEST_NEXT("foo", kStart, NotInvalidate);
- TEST_NEXT(IsRubyText, kContain, NotInvalidate);
- TEST_NEXT("bar", kEnd, NotInvalidate);
- TEST_CHECK();
-
- Selection().ClearLayoutSelection();
- TEST_RESET();
- TEST_NEXT(IsLayoutOf("BODY"), kNone, NotInvalidate);
- TEST_NEXT(IsRuby, kNone, NotInvalidate);
- TEST_NEXT("foo", kNone, ShouldInvalidate);
- // TODO(yoichio): These 2 should be kNone.
- // TEST_NEXT(IsRubyText, kNone, NotInvalidate);
- // TEST_NEXT("bar", kNone, ShouldInvalidate);
- TEST_NEXT(IsRubyText, kContain, NotInvalidate);
- TEST_NEXT("bar", kEnd, NotInvalidate);
- TEST_CHECK();
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " DIV, Contain, NotInvalidate \n"
+ " #shadow-root \n"
+ " 'Foo', StartAndEnd(0,3), NotInvalidate \n"
+ " SLOT, <null LayoutObject> \n"
+ " 'baz', <null LayoutObject> \n"
+ " SPAN, <null LayoutObject> \n"
+ " 'bar', <null LayoutObject> ",
+ DumpSelectionInfo());
+}
+
+TEST_F(LayoutSelectionTest, MoveNode) {
+ Selection().SetSelectionAndEndTyping(SetSelectionTextToBody(
+ "<div id='div1'></div><div id='div2'>^foo<b>ba|r</b></div>"));
+ Selection().CommitAppearanceIfNeeded();
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " DIV, None, NotInvalidate \n"
+ " DIV, Contain, NotInvalidate \n"
+ " 'foo', Start(0,3), ShouldInvalidate \n"
+ " B, Contain, NotInvalidate \n"
+ " 'bar', End(0,2), ShouldInvalidate ",
+ DumpSelectionInfo());
+ Node* div1 = GetDocument().QuerySelector("#div1");
+ Node* div2 = GetDocument().QuerySelector("#div2");
+ div1->appendChild(div2);
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " DIV, None, NotInvalidate \n"
+ " DIV, <null LayoutObject> \n"
+ " 'foo', <null LayoutObject> \n"
+ " B, <null LayoutObject> \n"
+ " 'bar', <null LayoutObject> ",
+ DumpSelectionInfo());
+
+ UpdateAllLifecyclePhases();
+ EXPECT_EQ(
+ "BODY, None, NotInvalidate \n"
+ " DIV, None, NotInvalidate \n"
+ " DIV, None, NotInvalidate \n"
+ " 'foo', None, NotInvalidate \n"
+ " B, None, NotInvalidate \n"
+ " 'bar', None, NotInvalidate ",
+ DumpSelectionInfo());
+}
+
+// http://crbug.com/870734
+TEST_F(LayoutSelectionTest, InvalidateSlot) {
+ Selection().SetSelectionAndEndTyping(
+ SetSelectionTextToBody("^<div>"
+ "<template data-mode=open>"
+ "<slot></slot>"
+ "</template>"
+ "foo"
+ "</div>|"));
+ UpdateAllLifecyclePhases();
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " DIV, Contain, NotInvalidate \n"
+ " #shadow-root \n"
+ " SLOT, <null LayoutObject> \n"
+ " 'foo', StartAndEnd(0,3), NotInvalidate ",
+ DumpSelectionInfo());
+
+ Selection().Clear();
+ Selection().CommitAppearanceIfNeeded();
+ EXPECT_EQ(
+ "BODY, None, NotInvalidate \n"
+ " DIV, None, NotInvalidate \n"
+ " #shadow-root \n"
+ " SLOT, <null LayoutObject> \n"
+ " 'foo', None, ShouldInvalidate ",
+ DumpSelectionInfo());
}
static const NGPaintFragment* FindNGPaintFragmentInternal(
@@ -983,57 +950,34 @@ std::ostream& operator<<(std::ostream& ostream,
TEST_F(NGLayoutSelectionTest, SelectOnOneText) {
SetSelectionAndUpdateLayoutSelection("foo<span>b^a|r</span>");
- TEST_RESET();
- TEST_NEXT(IsLayoutNGBlockFlow, kContain, NotInvalidate);
- TEST_NEXT("foo", kNone, NotInvalidate);
- TEST_NEXT(IsLayoutInline, kNone, NotInvalidate);
- TEST_NEXT("bar", kStartAndEnd, ShouldInvalidate);
- TEST_CHECK();
-
- LayoutObject* const foo =
- GetDocument().body()->firstChild()->GetLayoutObject();
- EXPECT_EQ(LayoutSelectionStatus(0u, 0u, SelectSoftLineBreak::kNotSelected),
- Selection().ComputeLayoutSelectionStatus(GetNGPaintFragment(foo)));
- LayoutObject* const bar = GetDocument()
- .body()
- ->firstChild()
- ->nextSibling()
- ->firstChild()
- ->GetLayoutObject();
- EXPECT_EQ(LayoutSelectionStatus(4u, 5u, SelectSoftLineBreak::kNotSelected),
- Selection().ComputeLayoutSelectionStatus(GetNGPaintFragment(bar)));
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " 'foo', None, NotInvalidate \n"
+ " SPAN, Contain, NotInvalidate \n"
+ " 'bar', StartAndEnd, ShouldInvalidate ",
+ DumpSelectionInfo());
}
TEST_F(NGLayoutSelectionTest, FirstLetterInAnotherBlockFlow) {
SetSelectionAndUpdateLayoutSelection(
"<style>:first-letter { float: right}</style>^fo|o");
- TEST_RESET();
- TEST_NEXT(IsLayoutNGBlockFlow, kContain, NotInvalidate);
- TEST_NEXT(IsLayoutTextFragmentOf("f"), kStart, ShouldInvalidate);
- TEST_NEXT(IsLayoutTextFragmentOf("oo"), kEnd, ShouldInvalidate);
- TEST_CHECK();
- Node* const foo = GetDocument().body()->firstChild()->nextSibling();
- const LayoutTextFragment* const foo_f =
- ToLayoutTextFragment(AssociatedLayoutObjectOf(*foo, 0));
- EXPECT_EQ(
- LayoutSelectionStatus(0u, 1u, SelectSoftLineBreak::kSelected),
- Selection().ComputeLayoutSelectionStatus(GetNGPaintFragment(foo_f)));
- const LayoutTextFragment* const foo_oo =
- ToLayoutTextFragment(AssociatedLayoutObjectOf(*foo, 1));
EXPECT_EQ(
- LayoutSelectionStatus(1u, 2u, SelectSoftLineBreak::kNotSelected),
- Selection().ComputeLayoutSelectionStatus(GetNGPaintFragment(foo_oo)));
+ "BODY, Contain, NotInvalidate \n"
+ " <style> \n"
+ " 'foo', End(0,2), ShouldInvalidate \n"
+ " :first-letter, Start(0,1), ShouldInvalidate ",
+ DumpSelectionInfo());
}
TEST_F(NGLayoutSelectionTest, TwoNGBlockFlows) {
SetSelectionAndUpdateLayoutSelection("<div>f^oo</div><div>ba|r</div>");
- TEST_RESET();
- TEST_NEXT(IsLayoutNGBlockFlow, kContain, NotInvalidate);
- TEST_NEXT(IsLayoutNGBlockFlow, kContain, NotInvalidate);
- TEST_NEXT("foo", kStart, ShouldInvalidate);
- TEST_NEXT(IsLayoutNGBlockFlow, kContain, NotInvalidate);
- TEST_NEXT("bar", kEnd, ShouldInvalidate);
- TEST_CHECK();
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " DIV, Contain, NotInvalidate \n"
+ " 'foo', Start, ShouldInvalidate \n"
+ " DIV, Contain, NotInvalidate \n"
+ " 'bar', End, ShouldInvalidate ",
+ DumpSelectionInfo());
LayoutObject* const foo =
GetDocument().body()->firstChild()->firstChild()->GetLayoutObject();
EXPECT_EQ(LayoutSelectionStatus(1u, 3u, SelectSoftLineBreak::kSelected),
@@ -1054,15 +998,13 @@ TEST_F(NGLayoutSelectionTest, MixedBlockFlowsAsSibling) {
SetSelectionAndUpdateLayoutSelection(
"<div>f^oo</div>"
"<div contenteditable>ba|r</div>");
- TEST_RESET();
- TEST_NEXT(IsLayoutBlockFlow, kContain, NotInvalidate);
- TEST_NEXT(IsLayoutBlockFlow, kContain, NotInvalidate);
- TEST_NEXT("foo", kStart, ShouldInvalidate);
- TEST_NEXT(IsLayoutBlockFlow, kContain, NotInvalidate);
- TEST_NEXT("bar", kEnd, ShouldInvalidate);
- TEST_CHECK();
- EXPECT_EQ(1u, Selection().LayoutSelectionStart().value());
- EXPECT_EQ(2u, Selection().LayoutSelectionEnd().value());
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " DIV, Contain, NotInvalidate \n"
+ " 'foo', Start(1,3), ShouldInvalidate \n"
+ " DIV, Contain, NotInvalidate \n"
+ " 'bar', End(0,2), ShouldInvalidate ",
+ DumpSelectionInfo());
}
// TODO(editing-dev): Once LayoutNG supports editing, we should change this
@@ -1072,14 +1014,13 @@ TEST_F(NGLayoutSelectionTest, MixedBlockFlowsAnscestor) {
SetSelectionAndUpdateLayoutSelection(
"<div contenteditable>f^oo"
"<div contenteditable=false>ba|r</div></div>");
- TEST_RESET();
- TEST_NEXT(IsLayoutBlockFlow, kContain, NotInvalidate);
- TEST_NEXT(IsLegacyBlockFlow, kContain, NotInvalidate);
- TEST_NEXT("foo", kStart, ShouldInvalidate);
- TEST_NEXT(IsLegacyBlockFlow, kContain, NotInvalidate);
- TEST_NEXT("bar", kEnd, ShouldInvalidate);
- TEST_CHECK();
- EXPECT_EQ(1u, Selection().LayoutSelectionStart().value());
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " DIV, Contain, NotInvalidate \n"
+ " 'foo', Start(1,3), ShouldInvalidate \n"
+ " DIV, Contain, NotInvalidate \n"
+ " 'bar', End(0,2), ShouldInvalidate ",
+ DumpSelectionInfo());
}
// TODO(editing-dev): Once LayoutNG supports editing, we should change this
@@ -1088,15 +1029,13 @@ TEST_F(NGLayoutSelectionTest, MixedBlockFlowsDecendant) {
SetSelectionAndUpdateLayoutSelection(
"<div contenteditable=false>f^oo"
"<div contenteditable>ba|r</div></div>");
- TEST_RESET();
- TEST_NEXT(IsLayoutBlockFlow, kContain, NotInvalidate);
- TEST_NEXT(IsLayoutBlockFlow, kContain, NotInvalidate);
- TEST_NEXT("foo", kStart, ShouldInvalidate);
- TEST_NEXT(IsLegacyBlockFlow, kContain, NotInvalidate);
- TEST_NEXT("bar", kEnd, ShouldInvalidate);
- TEST_CHECK();
- EXPECT_EQ(1u, Selection().LayoutSelectionStart().value());
- EXPECT_EQ(2u, Selection().LayoutSelectionEnd().value());
+ EXPECT_EQ(
+ "BODY, Contain, NotInvalidate \n"
+ " DIV, Contain, NotInvalidate \n"
+ " 'foo', Start(1,3), ShouldInvalidate \n"
+ " DIV, Contain, NotInvalidate \n"
+ " 'bar', End(0,2), ShouldInvalidate ",
+ DumpSelectionInfo());
}
TEST_F(NGLayoutSelectionTest, LineBreakBasic) {
diff --git a/chromium/third_party/blink/renderer/core/editing/local_caret_rect.cc b/chromium/third_party/blink/renderer/core/editing/local_caret_rect.cc
index 9165003e1eb..fb4046bc08b 100644
--- a/chromium/third_party/blink/renderer/core/editing/local_caret_rect.cc
+++ b/chromium/third_party/blink/renderer/core/editing/local_caret_rect.cc
@@ -69,8 +69,9 @@ LocalCaretRect LocalCaretRectOfPositionTemplate(
// DCHECK hit, we should pass primary direction to the latter function.
// TODO(crbug.com/793098): Fix it so that we don't need to bother about
// primary direction.
- DCHECK_EQ(PrimaryDirectionOf(*position.AnchorNode()),
- PrimaryDirectionOf(*adjusted.AnchorNode()));
+ DCHECK_EQ(
+ PrimaryDirectionOf(*position.GetPosition().ComputeContainerNode()),
+ PrimaryDirectionOf(*adjusted.GetPosition().ComputeContainerNode()));
const InlineBoxPosition& box_position =
ComputeInlineBoxPositionForInlineAdjustedPosition(adjusted);
@@ -122,8 +123,8 @@ LocalCaretRect LocalSelectionRectOfPositionTemplate(
// DCHECK hit, we should pass primary direction to the latter function.
// TODO(crbug.com/793098): Fix it so that we don't need to bother about
// primary direction.
- DCHECK_EQ(PrimaryDirectionOf(*position.AnchorNode()),
- PrimaryDirectionOf(*adjusted.AnchorNode()));
+ DCHECK_EQ(PrimaryDirectionOf(*position.GetPosition().ComputeContainerNode()),
+ PrimaryDirectionOf(*adjusted.GetPosition().ComputeContainerNode()));
const InlineBoxPosition& box_position =
ComputeInlineBoxPositionForInlineAdjustedPosition(adjusted);
diff --git a/chromium/third_party/blink/renderer/core/editing/local_caret_rect.h b/chromium/third_party/blink/renderer/core/editing/local_caret_rect.h
index 9e6de0ba55f..3a9c15a82b8 100644
--- a/chromium/third_party/blink/renderer/core/editing/local_caret_rect.h
+++ b/chromium/third_party/blink/renderer/core/editing/local_caret_rect.h
@@ -17,6 +17,7 @@ class LayoutObject;
struct LocalCaretRect {
STACK_ALLOCATED();
+ public:
const LayoutObject* layout_object = nullptr;
LayoutRect rect;
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 a63b0f3efcd..16486a2826f 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
@@ -953,4 +953,15 @@ TEST_P(ParameterizedLocalCaretRectTest, BidiTextWithImage) {
PositionWithAffinity(Position::AfterNode(image))));
}
+// https://crbug.com/876044
+TEST_P(ParameterizedLocalCaretRectTest, RtlMeterNoCrash) {
+ SetBodyContent("foo<meter dir=rtl></meter>");
+ const Position position = Position::LastPositionInNode(*GetDocument().body());
+ // Shouldn't crash inside
+ const LocalCaretRect local_caret_rect =
+ LocalCaretRectOfPosition(PositionWithAffinity(position));
+ EXPECT_EQ(GetDocument().QuerySelector("meter")->GetLayoutObject(),
+ local_caret_rect.layout_object);
+}
+
} // namespace blink
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..0c410be12ec 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
@@ -10,7 +10,7 @@ ActiveSuggestionMarker::ActiveSuggestionMarker(
unsigned start_offset,
unsigned end_offset,
Color underline_color,
- ui::mojom::ImeTextSpanThickness thickness,
+ ws::mojom::ImeTextSpanThickness thickness,
Color background_color)
: StyleableMarker(start_offset,
end_offset,
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 4c559c26792..1f14b3a7383 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
@@ -17,7 +17,7 @@ class CORE_EXPORT ActiveSuggestionMarker final : public StyleableMarker {
ActiveSuggestionMarker(unsigned start_offset,
unsigned end_offset,
Color underline_color,
- ui::mojom::ImeTextSpanThickness,
+ ws::mojom::ImeTextSpanThickness,
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 9f484b0d46e..5ea2177bf85 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,7 @@ class ActiveSuggestionMarkerListImplTest : public EditingTestBase {
DocumentMarker* CreateMarker(unsigned start_offset, unsigned end_offset) {
return new ActiveSuggestionMarker(
start_offset, end_offset, Color::kTransparent,
- ui::mojom::ImeTextSpanThickness::kThin, Color::kBlack);
+ ws::mojom::ImeTextSpanThickness::kThin, 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 946b9cac652..c73d81df78c 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
@@ -6,7 +6,7 @@
#include "testing/gtest/include/gtest/gtest.h"
-using ui::mojom::ImeTextSpanThickness;
+using ws::mojom::ImeTextSpanThickness;
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..b0c2616450d 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
@@ -9,7 +9,7 @@ namespace blink {
CompositionMarker::CompositionMarker(unsigned start_offset,
unsigned end_offset,
Color underline_color,
- ui::mojom::ImeTextSpanThickness thickness,
+ ws::mojom::ImeTextSpanThickness thickness,
Color background_color)
: StyleableMarker(start_offset,
end_offset,
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 ba5af65c07e..3db02634f2e 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
@@ -19,7 +19,7 @@ class CORE_EXPORT CompositionMarker final : public StyleableMarker {
CompositionMarker(unsigned start_offset,
unsigned end_offset,
Color underline_color,
- ui::mojom::ImeTextSpanThickness,
+ ws::mojom::ImeTextSpanThickness,
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 48ea3899453..c979e285703 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
@@ -17,7 +17,7 @@ class CompositionMarkerListImplTest : public EditingTestBase {
DocumentMarker* CreateMarker(unsigned start_offset, unsigned end_offset) {
return new CompositionMarker(start_offset, end_offset, Color::kTransparent,
- ui::mojom::ImeTextSpanThickness::kThin,
+ ws::mojom::ImeTextSpanThickness::kThin,
Color::kBlack);
}
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 028e2658518..c088ffc2dbd 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
@@ -6,7 +6,7 @@
#include "testing/gtest/include/gtest/gtest.h"
-using ui::mojom::ImeTextSpanThickness;
+using ws::mojom::ImeTextSpanThickness;
namespace blink {
diff --git a/chromium/third_party/blink/renderer/core/editing/markers/document_marker.h b/chromium/third_party/blink/renderer/core/editing/markers/document_marker.h
index 8c2f9716baa..245f7779742 100644
--- a/chromium/third_party/blink/renderer/core/editing/markers/document_marker.h
+++ b/chromium/third_party/blink/renderer/core/editing/markers/document_marker.h
@@ -99,9 +99,27 @@ class CORE_EXPORT DocumentMarker
class MarkerTypes {
public:
- // The constructor is intentionally implicit to allow conversion from the
- // bit-wise sum of above types
- MarkerTypes(unsigned mask) : mask_(mask) {}
+ explicit MarkerTypes(unsigned mask = 0) : mask_(mask) {}
+
+ static MarkerTypes All() {
+ return MarkerTypes((1 << kMarkerTypeIndexesCount) - 1);
+ }
+
+ static MarkerTypes AllBut(const MarkerTypes& types) {
+ return MarkerTypes(All().mask_ & ~types.mask_);
+ }
+
+ static MarkerTypes ActiveSuggestion() {
+ return MarkerTypes(kActiveSuggestion);
+ }
+ static MarkerTypes Composition() { return MarkerTypes(kComposition); }
+ static MarkerTypes Grammar() { return MarkerTypes(kGrammar); }
+ static MarkerTypes Misspelling() {
+ return MarkerTypes(kSpelling | kGrammar);
+ }
+ static MarkerTypes Spelling() { return MarkerTypes(kSpelling); }
+ static MarkerTypes TextMatch() { return MarkerTypes(kTextMatch); }
+ static MarkerTypes Suggestion() { return MarkerTypes(kSuggestion); }
bool Contains(MarkerType type) const { return mask_ & type; }
bool Intersects(const MarkerTypes& types) const {
@@ -111,8 +129,9 @@ class CORE_EXPORT DocumentMarker
return mask_ == other.mask_;
}
- void Add(const MarkerTypes& types) { mask_ |= types.mask_; }
- void Remove(const MarkerTypes& types) { mask_ &= ~types.mask_; }
+ MarkerTypes Add(const MarkerTypes& types) const {
+ return MarkerTypes(mask_ | types.mask_);
+ }
MarkerTypesIterator begin() const { return MarkerTypesIterator(mask_); }
MarkerTypesIterator end() const { return MarkerTypesIterator(0); }
@@ -121,16 +140,6 @@ class CORE_EXPORT DocumentMarker
unsigned mask_;
};
- class AllMarkers : public MarkerTypes {
- public:
- AllMarkers() : MarkerTypes((1 << kMarkerTypeIndexesCount) - 1) {}
- };
-
- class MisspellingMarkers : public MarkerTypes {
- public:
- MisspellingMarkers() : MarkerTypes(kSpelling | kGrammar) {}
- };
-
virtual ~DocumentMarker();
virtual MarkerType GetType() const = 0;
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 dc0257d76b7..f749a9be258 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
@@ -128,33 +128,24 @@ Member<DocumentMarkerList>& DocumentMarkerController::ListForType(
return (*marker_lists)[marker_list_index];
}
-inline bool DocumentMarkerController::PossiblyHasMarkers(
- DocumentMarker::MarkerTypes types) {
- if (markers_.IsEmpty()) {
- // It's possible for markers_ to become empty through garbage collection if
- // all its Nodes are GC'ed since we only hold weak references, in which case
- // possibly_existing_marker_types_ isn't reset to 0 as it is in the other
- // codepaths that remove from markers_. Therefore, we check for this case
- // here.
-
- // Alternatively, we could handle this case at the time the Node is GC'ed,
- // but that operation is more performance-sensitive than anywhere
- // PossiblyHasMarkers() is used.
- possibly_existing_marker_types_ = 0;
- SetContext(nullptr);
- return false;
- }
+bool DocumentMarkerController::PossiblyHasMarkers(
+ DocumentMarker::MarkerType type) const {
+ return PossiblyHasMarkers(DocumentMarker::MarkerTypes(type));
+}
+inline bool DocumentMarkerController::PossiblyHasMarkers(
+ DocumentMarker::MarkerTypes types) const {
+ DCHECK(!markers_.IsEmpty() ||
+ possibly_existing_marker_types_ == DocumentMarker::MarkerTypes(0));
return possibly_existing_marker_types_.Intersects(types);
}
DocumentMarkerController::DocumentMarkerController(Document& document)
- : possibly_existing_marker_types_(0), document_(&document) {
-}
+ : document_(&document) {}
void DocumentMarkerController::Clear() {
markers_.clear();
- possibly_existing_marker_types_ = 0;
+ possibly_existing_marker_types_ = DocumentMarker::MarkerTypes();
SetContext(nullptr);
}
@@ -186,7 +177,7 @@ void DocumentMarkerController::AddTextMatchMarker(
void DocumentMarkerController::AddCompositionMarker(
const EphemeralRange& range,
Color underline_color,
- ui::mojom::ImeTextSpanThickness thickness,
+ ws::mojom::ImeTextSpanThickness thickness,
Color background_color) {
DCHECK(!document_->NeedsLayoutTreeUpdate());
AddMarkerInternal(range, [underline_color, thickness, background_color](
@@ -199,7 +190,7 @@ void DocumentMarkerController::AddCompositionMarker(
void DocumentMarkerController::AddActiveSuggestionMarker(
const EphemeralRange& range,
Color underline_color,
- ui::mojom::ImeTextSpanThickness thickness,
+ ws::mojom::ImeTextSpanThickness thickness,
Color background_color) {
DCHECK(!document_->NeedsLayoutTreeUpdate());
AddMarkerInternal(range, [underline_color, thickness, background_color](
@@ -280,7 +271,9 @@ void DocumentMarkerController::AddMarkerInternal(
void DocumentMarkerController::AddMarkerToNode(const Node& node,
DocumentMarker* new_marker) {
- possibly_existing_marker_types_.Add(new_marker->GetType());
+ DCHECK_GE(ToText(node).length(), new_marker->EndOffset());
+ possibly_existing_marker_types_ = possibly_existing_marker_types_.Add(
+ DocumentMarker::MarkerTypes(new_marker->GetType()));
SetContext(document_);
Member<MarkerLists>& markers =
@@ -302,28 +295,28 @@ void DocumentMarkerController::AddMarkerToNode(const Node& node,
// Moves markers from src_node to dst_node. Markers are moved if their start
// offset is less than length. Markers that run past that point are truncated.
-void DocumentMarkerController::MoveMarkers(const Node* src_node,
+void DocumentMarkerController::MoveMarkers(const Text& src_node,
int length,
- const Node* dst_node) {
+ const Text& dst_node) {
if (length <= 0)
return;
- if (!PossiblyHasMarkers(DocumentMarker::AllMarkers()))
+ if (!PossiblyHasMarkers(DocumentMarker::MarkerTypes::All()))
return;
DCHECK(!markers_.IsEmpty());
- MarkerLists* src_markers = markers_.at(src_node);
+ MarkerLists* const src_markers = markers_.at(&src_node);
if (!src_markers)
return;
- if (!markers_.Contains(dst_node)) {
- markers_.insert(dst_node,
+ if (!markers_.Contains(&dst_node)) {
+ markers_.insert(&dst_node,
new MarkerLists(DocumentMarker::kMarkerTypeIndexesCount));
}
- MarkerLists* dst_markers = markers_.at(dst_node);
+ MarkerLists* const dst_markers = markers_.at(&dst_node);
bool doc_dirty = false;
- for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) {
+ for (DocumentMarker::MarkerType type : DocumentMarker::MarkerTypes::All()) {
DocumentMarkerList* const src_list = ListForType(src_markers, type);
if (!src_list)
continue;
@@ -339,7 +332,7 @@ void DocumentMarkerController::MoveMarkers(const Node* src_node,
if (!doc_dirty)
return;
- InvalidatePaintForNode(*dst_node);
+ InvalidatePaintForNode(dst_node);
}
void DocumentMarkerController::RemoveMarkersInternal(
@@ -360,7 +353,7 @@ void DocumentMarkerController::RemoveMarkersInternal(
bool doc_dirty = false;
size_t empty_lists_count = 0;
- for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) {
+ for (DocumentMarker::MarkerType type : DocumentMarker::MarkerTypes::All()) {
DocumentMarkerList* const list = ListForType(markers, type);
if (!list || list->IsEmpty()) {
if (list && list->IsEmpty())
@@ -383,7 +376,7 @@ void DocumentMarkerController::RemoveMarkersInternal(
if (empty_lists_count == DocumentMarker::kMarkerTypeIndexesCount) {
markers_.erase(&node);
if (markers_.IsEmpty()) {
- possibly_existing_marker_types_ = 0;
+ possibly_existing_marker_types_ = DocumentMarker::MarkerTypes();
SetContext(nullptr);
}
}
@@ -479,13 +472,13 @@ DocumentMarkerController::MarkersIntersectingRange(
}
DocumentMarkerVector DocumentMarkerController::MarkersFor(
- const Node* node,
- DocumentMarker::MarkerTypes marker_types) {
+ const Text& text,
+ DocumentMarker::MarkerTypes marker_types) const {
DocumentMarkerVector result;
if (!PossiblyHasMarkers(marker_types))
return result;
- MarkerLists* markers = markers_.at(node);
+ MarkerLists* markers = markers_.at(&text);
if (!markers)
return result;
@@ -505,11 +498,11 @@ DocumentMarkerVector DocumentMarkerController::MarkersFor(
return result;
}
-DocumentMarkerVector DocumentMarkerController::Markers() {
+DocumentMarkerVector DocumentMarkerController::Markers() const {
DocumentMarkerVector result;
- for (MarkerMap::iterator i = markers_.begin(); i != markers_.end(); ++i) {
- MarkerLists* markers = i->value.Get();
- for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) {
+ for (const auto& node_markers : markers_) {
+ MarkerLists* markers = node_markers.value;
+ for (DocumentMarker::MarkerType type : DocumentMarker::MarkerTypes::All()) {
DocumentMarkerList* const list = ListForType(markers, type);
if (!list)
continue;
@@ -525,24 +518,25 @@ DocumentMarkerVector DocumentMarkerController::Markers() {
}
DocumentMarkerVector DocumentMarkerController::ComputeMarkersToPaint(
- const Node& node) {
+ const Text& text) const {
// We don't render composition or spelling markers that overlap suggestion
// markers.
// Note: DocumentMarkerController::MarkersFor() returns markers sorted by
// start offset.
const DocumentMarkerVector& suggestion_markers =
- MarkersFor(&node, DocumentMarker::kSuggestion);
+ MarkersFor(text, DocumentMarker::MarkerTypes::Suggestion());
if (suggestion_markers.IsEmpty()) {
// If there are no suggestion markers, we can return early as a minor
// performance optimization.
- DocumentMarker::MarkerTypes remaining_types = DocumentMarker::AllMarkers();
- remaining_types.Remove(DocumentMarker::kSuggestion);
- return MarkersFor(&node, remaining_types);
+ return MarkersFor(
+ text, DocumentMarker::MarkerTypes::AllBut(
+ DocumentMarker::MarkerTypes(DocumentMarker::kSuggestion)));
}
const DocumentMarkerVector& markers_overridden_by_suggestion_markers =
- MarkersFor(&node,
- DocumentMarker::kComposition | DocumentMarker::kSpelling);
+ MarkersFor(text,
+ DocumentMarker::MarkerTypes(DocumentMarker::kComposition |
+ DocumentMarker::kSpelling));
Vector<unsigned> suggestion_starts;
Vector<unsigned> suggestion_ends;
@@ -590,12 +584,10 @@ DocumentMarkerVector DocumentMarkerController::ComputeMarkersToPaint(
markers_to_paint.AppendVector(suggestion_markers);
- DocumentMarker::MarkerTypes remaining_types = DocumentMarker::AllMarkers();
- remaining_types.Remove(DocumentMarker::kComposition |
- DocumentMarker::kSpelling |
- DocumentMarker::kSuggestion);
-
- markers_to_paint.AppendVector(MarkersFor(&node, remaining_types));
+ markers_to_paint.AppendVector(MarkersFor(
+ text, DocumentMarker::MarkerTypes::AllBut(DocumentMarker::MarkerTypes(
+ DocumentMarker::kComposition | DocumentMarker::kSpelling |
+ DocumentMarker::kSuggestion))));
return markers_to_paint;
}
@@ -658,7 +650,17 @@ void DocumentMarkerController::InvalidateRectsForAllTextMatchMarkers() {
}
}
+void DocumentMarkerController::DidProcessMarkerMap(Visitor* visitor) {
+ if (markers_.IsEmpty())
+ Clear();
+}
+
void DocumentMarkerController::Trace(blink::Visitor* visitor) {
+ // Note: To make |DidProcessMarkerMap()| called after weak members callback
+ // of |markers_|, we should register it before tracing |markers_|.
+ visitor->template RegisterWeakMembers<
+ DocumentMarkerController, &DocumentMarkerController::DidProcessMarkerMap>(
+ this);
visitor->Trace(markers_);
visitor->Trace(document_);
SynchronousMutationObserver::Trace(visitor);
@@ -684,7 +686,7 @@ void DocumentMarkerController::RemoveSpellingMarkersUnderWords(
continue;
MarkerLists* markers = node_markers.value;
for (DocumentMarker::MarkerType type :
- DocumentMarker::MisspellingMarkers()) {
+ DocumentMarker::MarkerTypes::Misspelling()) {
DocumentMarkerList* const list = ListForType(markers, type);
if (!list)
continue;
@@ -721,8 +723,7 @@ void DocumentMarkerController::RemoveMarkersOfTypes(
RemoveMarkersFromList(iterator, marker_types);
}
- possibly_existing_marker_types_.Remove(marker_types);
- if (PossiblyHasMarkers(DocumentMarker::AllMarkers()))
+ if (PossiblyHasMarkers(DocumentMarker::MarkerTypes::AllBut(marker_types)))
return;
SetContext(nullptr);
}
@@ -734,13 +735,13 @@ void DocumentMarkerController::RemoveMarkersFromList(
bool node_can_be_removed;
size_t empty_lists_count = 0;
- if (marker_types == DocumentMarker::AllMarkers()) {
+ if (marker_types == DocumentMarker::MarkerTypes::All()) {
needs_repainting = true;
node_can_be_removed = true;
} else {
MarkerLists* markers = iterator->value.Get();
- for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) {
+ for (DocumentMarker::MarkerType type : DocumentMarker::MarkerTypes::All()) {
DocumentMarkerList* const list = ListForType(markers, type);
if (!list || list->IsEmpty()) {
if (list && list->IsEmpty())
@@ -769,7 +770,7 @@ void DocumentMarkerController::RemoveMarkersFromList(
if (node_can_be_removed) {
markers_.erase(iterator);
if (markers_.IsEmpty()) {
- possibly_existing_marker_types_ = 0;
+ possibly_existing_marker_types_ = DocumentMarker::MarkerTypes();
SetContext(nullptr);
}
}
@@ -788,7 +789,7 @@ void DocumentMarkerController::RepaintMarkers(
// inner loop: process each marker in the current node
MarkerLists* markers = i->value.Get();
- for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) {
+ for (DocumentMarker::MarkerType type : DocumentMarker::MarkerTypes::All()) {
DocumentMarkerList* const list = ListForType(markers, type);
if (!list || list->IsEmpty() || !marker_types.Contains(type))
continue;
@@ -858,7 +859,7 @@ void DocumentMarkerController::ShowMarkers() const {
const Node* node = node_iterator->key;
builder.Append(String::Format("%p", node));
MarkerLists* markers = markers_.at(node);
- for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) {
+ for (DocumentMarker::MarkerType type : DocumentMarker::MarkerTypes::All()) {
DocumentMarkerList* const list = ListForType(markers, type);
if (!list)
continue;
@@ -891,7 +892,7 @@ void DocumentMarkerController::DidUpdateCharacterData(CharacterData* node,
unsigned offset,
unsigned old_length,
unsigned new_length) {
- if (!PossiblyHasMarkers(DocumentMarker::AllMarkers()))
+ if (!PossiblyHasMarkers(DocumentMarker::MarkerTypes::All()))
return;
DCHECK(!markers_.IsEmpty());
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 7f358621152..5d709d635ea 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
@@ -64,27 +64,27 @@ class CORE_EXPORT DocumentMarkerController final
void AddTextMatchMarker(const EphemeralRange&, TextMatchMarker::MatchStatus);
void AddCompositionMarker(const EphemeralRange&,
Color underline_color,
- ui::mojom::ImeTextSpanThickness,
+ ws::mojom::ImeTextSpanThickness,
Color background_color);
void AddActiveSuggestionMarker(const EphemeralRange&,
Color underline_color,
- ui::mojom::ImeTextSpanThickness,
+ ws::mojom::ImeTextSpanThickness,
Color background_color);
void AddSuggestionMarker(const EphemeralRange&,
const SuggestionMarkerProperties&);
- void MoveMarkers(const Node* src_node, int length, const Node* dst_node);
+ void MoveMarkers(const Text& src_node, int length, const Text& dst_node);
void PrepareForDestruction();
void RemoveMarkersInRange(const EphemeralRange&, DocumentMarker::MarkerTypes);
void RemoveMarkersOfTypes(DocumentMarker::MarkerTypes);
void RemoveMarkersForNode(
const Node*,
- DocumentMarker::MarkerTypes = DocumentMarker::AllMarkers());
+ DocumentMarker::MarkerTypes = DocumentMarker::MarkerTypes::All());
void RemoveSpellingMarkersUnderWords(const Vector<String>& words);
void RemoveSuggestionMarkerByTag(const Node*, int32_t marker_tag);
void RepaintMarkers(
- DocumentMarker::MarkerTypes = DocumentMarker::AllMarkers());
+ DocumentMarker::MarkerTypes = DocumentMarker::MarkerTypes::All());
// Returns true if markers within a range are found.
bool SetTextMatchMarkersActive(const EphemeralRange&, bool);
// Returns true if markers within a range defined by a node, |startOffset| and
@@ -117,11 +117,10 @@ class CORE_EXPORT DocumentMarkerController final
MarkersIntersectingRange(const EphemeralRangeInFlatTree&,
DocumentMarker::MarkerTypes);
DocumentMarkerVector MarkersFor(
- const Node*,
- DocumentMarker::MarkerTypes = DocumentMarker::AllMarkers());
- DocumentMarkerVector Markers();
- // TODO(yoichio): Make const by making PossiblyHasMarkers const.
- DocumentMarkerVector ComputeMarkersToPaint(const Node&);
+ const Text&,
+ DocumentMarker::MarkerTypes = DocumentMarker::MarkerTypes::All()) const;
+ DocumentMarkerVector Markers() const;
+ DocumentMarkerVector ComputeMarkersToPaint(const Text&) const;
Vector<IntRect> LayoutRectsForTextMatchMarkers();
void InvalidateRectsForAllTextMatchMarkers();
@@ -152,7 +151,8 @@ class CORE_EXPORT DocumentMarkerController final
using MarkerMap = HeapHashMap<WeakMember<const Node>, Member<MarkerLists>>;
static Member<DocumentMarkerList>& ListForType(MarkerLists*,
DocumentMarker::MarkerType);
- bool PossiblyHasMarkers(DocumentMarker::MarkerTypes);
+ bool PossiblyHasMarkers(DocumentMarker::MarkerTypes) const;
+ bool PossiblyHasMarkers(DocumentMarker::MarkerType) const;
void RemoveMarkersFromList(MarkerMap::iterator, DocumentMarker::MarkerTypes);
void RemoveMarkers(TextIterator&, DocumentMarker::MarkerTypes);
void RemoveMarkersInternal(const Node&,
@@ -160,6 +160,9 @@ class CORE_EXPORT DocumentMarkerController final
int length,
DocumentMarker::MarkerTypes);
+ // Called after weak processing of |markers_| is done.
+ void DidProcessMarkerMap(Visitor* visitor);
+
MarkerMap markers_;
// Provide a quick way to determine whether a particular marker type is absent
// without going through the map.
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 1fb2fcf60c8..3d71f4ece8f 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
@@ -189,10 +189,8 @@ TEST_F(DocumentMarkerControllerTest, NodeWillBeRemovedBySetInnerHTML) {
EXPECT_EQ(0u, MarkerController().Markers().size());
}
-// TODO(crbug.com/862900): Fix DocumentMarkerController::DidUpdateCharacterData
-// and enable this test.
-TEST_F(DocumentMarkerControllerTest,
- DISABLED_SynchronousMutationNotificationAfterGC) {
+// For http://crbug.com/862900
+TEST_F(DocumentMarkerControllerTest, SynchronousMutationNotificationAfterGC) {
SetBodyContent("<b><i>foo</i></b>");
Persistent<Text> sibling_text = CreateTextNode("bar");
{
@@ -234,10 +232,10 @@ 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);
+ ws::mojom::ImeTextSpanThickness::kThin, Color::kBlack);
MarkerController().AddCompositionMarker(
EphemeralRange(Position(text, 1), Position(text, 3)), Color::kTransparent,
- ui::mojom::ImeTextSpanThickness::kThick, Color::kBlack);
+ ws::mojom::ImeTextSpanThickness::kThick, Color::kBlack);
EXPECT_EQ(2u, MarkerController().Markers().size());
}
@@ -273,8 +271,8 @@ TEST_F(DocumentMarkerControllerTest, RemoveStartOfMarker) {
// Remove markers that overlap "a"
marker_range = EphemeralRange(Position(text, 0), Position(text, 1));
- GetDocument().Markers().RemoveMarkersInRange(marker_range,
- DocumentMarker::AllMarkers());
+ GetDocument().Markers().RemoveMarkersInRange(
+ marker_range, DocumentMarker::MarkerTypes::All());
EXPECT_EQ(0u, MarkerController().Markers().size());
}
@@ -292,8 +290,8 @@ TEST_F(DocumentMarkerControllerTest, RemoveMiddleOfMarker) {
// Remove markers that overlap "b"
marker_range = EphemeralRange(Position(text, 1), Position(text, 2));
- GetDocument().Markers().RemoveMarkersInRange(marker_range,
- DocumentMarker::AllMarkers());
+ GetDocument().Markers().RemoveMarkersInRange(
+ marker_range, DocumentMarker::MarkerTypes::All());
EXPECT_EQ(0u, MarkerController().Markers().size());
}
@@ -311,8 +309,8 @@ TEST_F(DocumentMarkerControllerTest, RemoveEndOfMarker) {
// Remove markers that overlap "c"
marker_range = EphemeralRange(Position(text, 2), Position(text, 3));
- GetDocument().Markers().RemoveMarkersInRange(marker_range,
- DocumentMarker::AllMarkers());
+ GetDocument().Markers().RemoveMarkersInRange(
+ marker_range, DocumentMarker::MarkerTypes::All());
EXPECT_EQ(0u, MarkerController().Markers().size());
}
@@ -385,7 +383,7 @@ TEST_F(DocumentMarkerControllerTest, FirstMarkerIntersectingOffsetRange) {
// Query for a spellcheck marker intersecting "3456"
const DocumentMarker* const result =
MarkerController().FirstMarkerIntersectingOffsetRange(
- *text, 2, 6, DocumentMarker::MisspellingMarkers());
+ *text, 2, 6, DocumentMarker::MarkerTypes::Misspelling());
EXPECT_EQ(DocumentMarker::kSpelling, result->GetType());
EXPECT_EQ(0u, result->StartOffset());
@@ -406,7 +404,7 @@ TEST_F(DocumentMarkerControllerTest,
// Query for a spellcheck marker containing the position between "1" and "2"
const DocumentMarker* const result =
MarkerController().FirstMarkerIntersectingOffsetRange(
- *text, 1, 1, DocumentMarker::MisspellingMarkers());
+ *text, 1, 1, DocumentMarker::MarkerTypes::Misspelling());
EXPECT_EQ(DocumentMarker::kSpelling, result->GetType());
EXPECT_EQ(0u, result->StartOffset());
@@ -435,7 +433,7 @@ TEST_F(DocumentMarkerControllerTest, MarkersIntersectingRange) {
MarkerController().MarkersIntersectingRange(
EphemeralRangeInFlatTree(PositionInFlatTree(text, 2),
PositionInFlatTree(text, 6)),
- DocumentMarker::MisspellingMarkers());
+ DocumentMarker::MarkerTypes::Misspelling());
EXPECT_EQ(1u, results.size());
EXPECT_EQ(DocumentMarker::kSpelling, results[0].second->GetType());
@@ -457,7 +455,7 @@ TEST_F(DocumentMarkerControllerTest, MarkersIntersectingCollapsedRange) {
MarkerController().MarkersIntersectingRange(
EphemeralRangeInFlatTree(PositionInFlatTree(text, 1),
PositionInFlatTree(text, 1)),
- DocumentMarker::MisspellingMarkers());
+ DocumentMarker::MarkerTypes::Misspelling());
EXPECT_EQ(1u, results.size());
EXPECT_EQ(DocumentMarker::kSpelling, results[0].second->GetType());
@@ -496,7 +494,7 @@ TEST_F(DocumentMarkerControllerTest, MarkersIntersectingRangeWithShadowDOM) {
MarkerController().MarkersIntersectingRange(
EphemeralRangeInFlatTree(PositionInFlatTree(not_shadow_text, 9),
PositionInFlatTree(shadow1_text, 1)),
- DocumentMarker::kTextMatch);
+ DocumentMarker::MarkerTypes::TextMatch());
EXPECT_EQ(1u, results.size());
}
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..15826e6e1a0 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
@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/core/editing/markers/styleable_marker.h"
-using ui::mojom::ImeTextSpanThickness;
+using ws::mojom::ImeTextSpanThickness;
namespace blink {
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 d7d188106a1..00746605fcc 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
@@ -5,7 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_MARKERS_STYLEABLE_MARKER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_MARKERS_STYLEABLE_MARKER_H_
-#include "services/ui/public/interfaces/ime/ime.mojom-shared.h"
+#include "services/ws/public/mojom/ime/ime.mojom-shared.h"
#include "third_party/blink/renderer/core/editing/markers/document_marker.h"
namespace blink {
@@ -17,7 +17,7 @@ class CORE_EXPORT StyleableMarker : public DocumentMarker {
StyleableMarker(unsigned start_offset,
unsigned end_offset,
Color underline_color,
- ui::mojom::ImeTextSpanThickness,
+ ws::mojom::ImeTextSpanThickness,
Color background_color);
// StyleableMarker-specific
@@ -31,7 +31,7 @@ class CORE_EXPORT StyleableMarker : public DocumentMarker {
private:
const Color underline_color_;
const Color background_color_;
- const ui::mojom::ImeTextSpanThickness thickness_;
+ const ws::mojom::ImeTextSpanThickness thickness_;
DISALLOW_COPY_AND_ASSIGN(StyleableMarker);
};
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 435e6fdad54..b83a3d8f790 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
@@ -55,7 +55,7 @@ SuggestionMarkerProperties::Builder::SetBackgroundColor(
SuggestionMarkerProperties::Builder&
SuggestionMarkerProperties::Builder::SetThickness(
- ui::mojom::ImeTextSpanThickness thickness) {
+ ws::mojom::ImeTextSpanThickness thickness) {
data_.thickness_ = thickness;
return *this;
}
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 acad4f9e49d..474a9b4c001 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
@@ -9,7 +9,7 @@
#include "third_party/blink/renderer/core/editing/markers/styleable_marker.h"
#include "third_party/blink/renderer/core/editing/markers/suggestion_marker.h"
-using ui::mojom::ImeTextSpanThickness;
+using ws::mojom::ImeTextSpanThickness;
namespace blink {
diff --git a/chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker_test.cc b/chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker_test.cc
index fcec1421a83..da117c89f30 100644
--- a/chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker_test.cc
@@ -32,7 +32,7 @@ TEST_F(SuggestionMarkerTest, ConstructorAndGetters) {
.SetSuggestions(suggestions)
.SetHighlightColor(Color::kTransparent)
.SetUnderlineColor(Color::kDarkGray)
- .SetThickness(ui::mojom::ImeTextSpanThickness::kThin)
+ .SetThickness(ws::mojom::ImeTextSpanThickness::kThin)
.SetBackgroundColor(Color::kGray)
.Build());
EXPECT_EQ(suggestions, marker->Suggestions());
@@ -47,7 +47,7 @@ TEST_F(SuggestionMarkerTest, ConstructorAndGetters) {
SuggestionMarkerProperties::Builder()
.SetType(SuggestionMarker::SuggestionType::kMisspelling)
.SetHighlightColor(Color::kBlack)
- .SetThickness(ui::mojom::ImeTextSpanThickness::kThick)
+ .SetThickness(ws::mojom::ImeTextSpanThickness::kThick)
.Build());
EXPECT_TRUE(marker2->HasThicknessThick());
EXPECT_TRUE(marker2->IsMisspelling());
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 11e667a0c21..ff002cfba28 100644
--- a/chromium/third_party/blink/renderer/core/editing/selection_controller.cc
+++ b/chromium/third_party/blink/renderer/core/editing/selection_controller.cc
@@ -33,6 +33,7 @@
#include "third_party/blink/public/platform/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/editing/editing_behavior.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/editing/editor.h"
@@ -46,6 +47,7 @@
#include "third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller.h"
#include "third_party/blink/renderer/core/editing/visible_position.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"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/html_names.h"
@@ -80,7 +82,7 @@ DispatchEventResult DispatchSelectStart(Node* node) {
return DispatchEventResult::kNotCanceled;
return node->DispatchEvent(
- Event::CreateCancelableBubble(EventTypeNames::selectstart));
+ *Event::CreateCancelableBubble(EventTypeNames::selectstart));
}
SelectionInFlatTree ExpandSelectionToRespectUserSelectAll(
@@ -135,7 +137,8 @@ DocumentMarker* SpellCheckMarkerAtPosition(
const unsigned offset = position.ComputeOffsetInContainerNode();
return document_marker_controller.FirstMarkerIntersectingOffsetRange(
- *ToText(node), offset, offset, DocumentMarker::MisspellingMarkers());
+ *ToText(node), offset, offset,
+ DocumentMarker::MarkerTypes::Misspelling());
}
} // namespace
@@ -991,6 +994,7 @@ void SelectionController::HandleMouseDraggedEvent(
if (!Selection().IsAvailable())
return;
if (selection_state_ != SelectionState::kExtendedSelection) {
+ frame_->LocalFrameRoot().Client()->SetMouseCapture(true);
HitTestRequest request(HitTestRequest::kReadOnly | HitTestRequest::kActive);
HitTestLocation location(mouse_down_pos);
HitTestResult result(request, location);
@@ -1064,6 +1068,9 @@ bool SelectionController::HandleMouseReleaseEvent(
handled = true;
}
+ if (frame_->LocalFrameRoot().Client())
+ frame_->LocalFrameRoot().Client()->SetMouseCapture(false);
+
Selection().NotifyTextControlOfSelectionChange(SetSelectionBy::kUser);
Selection().SelectFrameElementInParentIfFullySelected();
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 4a8c93b7117..83922c86a50 100644
--- a/chromium/third_party/blink/renderer/core/editing/selection_editor.cc
+++ b/chromium/third_party/blink/renderer/core/editing/selection_editor.cc
@@ -27,6 +27,7 @@
#include "third_party/blink/renderer/core/dom/node_with_index.h"
#include "third_party/blink/renderer/core/dom/text.h"
+#include "third_party/blink/renderer/core/editing/editing_behavior.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/selection_adjuster.h"
@@ -162,6 +163,14 @@ void SelectionEditor::ContextDestroyed(Document*) {
static Position ComputePositionForChildrenRemoval(const Position& position,
ContainerNode& container) {
Node* node = position.ComputeContainerNode();
+#if DCHECK_IS_ON()
+ DCHECK(node) << position;
+#else
+ // TODO(https://crbug.com/882592): Once we know the root cause, we should
+ // get rid of following if-statement.
+ if (!node)
+ return position;
+#endif
if (container.ContainsIncludingHostElements(*node))
return Position::FirstPositionInNode(container);
return position;
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 b011187607a..3632932b41e 100644
--- a/chromium/third_party/blink/renderer/core/editing/selection_modifier.cc
+++ b/chromium/third_party/blink/renderer/core/editing/selection_modifier.cc
@@ -26,6 +26,7 @@
#include "third_party/blink/renderer/core/editing/selection_modifier.h"
+#include "third_party/blink/renderer/core/editing/editing_behavior.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"
@@ -38,7 +39,11 @@
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/layout/layout_block.h"
#include "third_party/blink/renderer/core/layout/line/inline_text_box.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_caret_position.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h"
#include "third_party/blink/renderer/core/page/spatial_navigation.h"
+#include "third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h"
namespace blink {
@@ -136,23 +141,43 @@ TextDirection SelectionModifier::DirectionOfEnclosingBlock() const {
: TextDirection::kLtr;
}
-static TextDirection DirectionOf(const VisibleSelection& visible_selection) {
- const InlineBox* start_box = nullptr;
- const InlineBox* end_box = nullptr;
- // Cache the VisiblePositions because visibleStart() and visibleEnd()
- // can cause layout, which has the potential to invalidate lineboxes.
- const VisiblePosition& start_position = visible_selection.VisibleStart();
- const VisiblePosition& end_position = visible_selection.VisibleEnd();
- if (start_position.IsNotNull())
- start_box = ComputeInlineBoxPosition(start_position).inline_box;
- if (end_position.IsNotNull())
- end_box = ComputeInlineBoxPosition(end_position).inline_box;
- if (start_box && end_box && start_box->Direction() == end_box->Direction())
- return start_box->Direction();
+namespace {
+
+base::Optional<TextDirection> DirectionAt(const VisiblePosition& position) {
+ if (position.IsNull())
+ return base::nullopt;
+ const PositionWithAffinity adjusted = ComputeInlineAdjustedPosition(position);
+ if (adjusted.IsNull())
+ return base::nullopt;
+
+ if (NGInlineFormattingContextOf(adjusted.GetPosition())) {
+ if (const NGPaintFragment* fragment =
+ ComputeNGCaretPosition(adjusted).fragment)
+ return fragment->PhysicalFragment().ResolvedDirection();
+ return base::nullopt;
+ }
+
+ if (const InlineBox* box =
+ ComputeInlineBoxPositionForInlineAdjustedPosition(adjusted)
+ .inline_box)
+ return box->Direction();
+ return base::nullopt;
+}
+
+TextDirection DirectionOf(const VisibleSelection& visible_selection) {
+ base::Optional<TextDirection> maybe_start_direction =
+ DirectionAt(visible_selection.VisibleStart());
+ base::Optional<TextDirection> maybe_end_direction =
+ DirectionAt(visible_selection.VisibleEnd());
+ if (maybe_start_direction.has_value() && maybe_end_direction.has_value() &&
+ maybe_start_direction.value() == maybe_end_direction.value())
+ return maybe_start_direction.value();
return DirectionOfEnclosingBlockOf(visible_selection.Extent());
}
+} // namespace
+
TextDirection SelectionModifier::DirectionOfSelection() const {
return DirectionOf(selection_);
}
diff --git a/chromium/third_party/blink/renderer/core/editing/selection_modifier_character.cc b/chromium/third_party/blink/renderer/core/editing/selection_modifier_character.cc
index 782a1a4de87..194724bcbe6 100644
--- a/chromium/third_party/blink/renderer/core/editing/selection_modifier_character.cc
+++ b/chromium/third_party/blink/renderer/core/editing/selection_modifier_character.cc
@@ -49,22 +49,65 @@ template <typename Strategy>
struct TraversalLeft {
STATIC_ONLY(TraversalLeft);
- static InlineBox* BackwardLeafChildOf(const InlineBox& box) {
- return box.NextLeafChild();
+ static int CaretBackwardOffsetOf(const InlineBox& box) {
+ return box.CaretRightmostOffset();
}
- static int CaretEndOffsetOf(const InlineBox& box) {
- return box.CaretRightmostOffset();
+ static int CaretForwardOffsetOf(const InlineBox& box) {
+ return box.CaretLeftmostOffset();
+ }
+
+ static const InlineBox* ForwardLeafChildOf(const InlineBox& box) {
+ return box.PrevLeafChild();
+ }
+
+ static const InlineBox* ForwardLeafChildIgnoringLineBreakOf(
+ const InlineBox& box) {
+ return box.PrevLeafChildIgnoringLineBreak();
}
- static int CaretMinOffsetOf(TextDirection direction, const InlineBox& box) {
+ static int ForwardGraphemeBoundaryOf(TextDirection direction,
+ const Node& node,
+ int offset) {
if (direction == TextDirection::kLtr)
- return box.CaretMinOffset();
- return box.CaretMaxOffset();
+ return PreviousGraphemeBoundaryOf(node, offset);
+ return NextGraphemeBoundaryOf(node, offset);
}
- static int CaretStartOffsetOf(const InlineBox& box) {
- return box.CaretLeftmostOffset();
+ static bool IsOvershot(int offset, const InlineBox& box) {
+ if (box.IsLeftToRightDirection())
+ return offset < box.CaretMinOffset();
+ return offset > box.CaretMaxOffset();
+ }
+
+ static PositionTemplate<Strategy> ForwardVisuallyDistinctCandidateOf(
+ TextDirection direction,
+ const PositionTemplate<Strategy>& position) {
+ if (direction == TextDirection::kLtr)
+ return PreviousVisuallyDistinctCandidate(position);
+ return NextVisuallyDistinctCandidate(position);
+ }
+
+ static VisiblePositionTemplate<Strategy> HonorEditingBoundary(
+ TextDirection direction,
+ const VisiblePositionTemplate<Strategy>& visible_position,
+ const PositionTemplate<Strategy>& anchor) {
+ if (direction == TextDirection::kLtr) {
+ return AdjustBackwardPositionToAvoidCrossingEditingBoundaries(
+ visible_position, anchor);
+ }
+ return AdjustForwardPositionToAvoidCrossingEditingBoundaries(
+ visible_position, anchor);
+ }
+
+ // TODO(xiaochengh): The functions below are used only by bidi adjustment.
+ // Merge them into inline_box_traversal.cc.
+
+ static int CaretForwardOffsetInLineDirection(TextDirection line_direction,
+ const InlineBox& box) {
+ if (line_direction == TextDirection::kLtr)
+ return box.CaretMinOffset();
+ return box.CaretMaxOffset();
}
static const InlineBox* FindBackwardBidiRun(const InlineBox& box,
@@ -90,18 +133,6 @@ struct TraversalLeft {
return InlineBoxTraversal::FindLeftBoundaryOfEntireBidiRun(box, bidi_level);
}
- static int ForwardGraphemeBoundaryOf(TextDirection direction,
- const Node& node,
- int offset) {
- if (direction == TextDirection::kLtr)
- return PreviousGraphemeBoundaryOf(node, offset);
- return NextGraphemeBoundaryOf(node, offset);
- }
-
- static const InlineBox* ForwardLeafChildOf(const InlineBox& box) {
- return box.PrevLeafChild();
- }
-
static const InlineBox* ForwardNonPseudoLeafChildOf(const InlineBox& box) {
for (const InlineBox* runner = ForwardLeafChildOf(box); runner;
runner = ForwardLeafChildOf(*runner)) {
@@ -111,17 +142,56 @@ struct TraversalLeft {
return nullptr;
}
+ static const InlineBox* LogicalForwardMostInLine(TextDirection line_direction,
+ const InlineBox& box) {
+ if (line_direction == TextDirection::kLtr)
+ return box.Root().GetLogicalStartNonPseudoBox();
+ return box.Root().GetLogicalEndNonPseudoBox();
+ }
+};
+
+// The traversal strategy for |RightPositionOf()|.
+template <typename Strategy>
+struct TraversalRight {
+ STATIC_ONLY(TraversalRight);
+
+ static int CaretBackwardOffsetOf(const InlineBox& box) {
+ return box.CaretLeftmostOffset();
+ }
+
+ static int CaretForwardOffsetOf(const InlineBox& box) {
+ return box.CaretRightmostOffset();
+ }
+
+ static const InlineBox* ForwardLeafChildOf(const InlineBox& box) {
+ return box.NextLeafChild();
+ }
+
static const InlineBox* ForwardLeafChildIgnoringLineBreakOf(
const InlineBox& box) {
- return box.PrevLeafChildIgnoringLineBreak();
+ return box.NextLeafChildIgnoringLineBreak();
+ }
+
+ static int ForwardGraphemeBoundaryOf(TextDirection direction,
+ const Node& node,
+ int offset) {
+ if (direction == TextDirection::kLtr)
+ return NextGraphemeBoundaryOf(node, offset);
+ return PreviousGraphemeBoundaryOf(node, offset);
+ }
+
+ static bool IsOvershot(int offset, const InlineBox& box) {
+ if (box.IsLeftToRightDirection())
+ return offset > box.CaretMaxOffset();
+ return offset < box.CaretMinOffset();
}
static PositionTemplate<Strategy> ForwardVisuallyDistinctCandidateOf(
TextDirection direction,
const PositionTemplate<Strategy>& position) {
if (direction == TextDirection::kLtr)
- return PreviousVisuallyDistinctCandidate(position);
- return NextVisuallyDistinctCandidate(position);
+ return NextVisuallyDistinctCandidate(position);
+ return PreviousVisuallyDistinctCandidate(position);
}
static VisiblePositionTemplate<Strategy> HonorEditingBoundary(
@@ -129,50 +199,23 @@ struct TraversalLeft {
const VisiblePositionTemplate<Strategy>& visible_position,
const PositionTemplate<Strategy>& anchor) {
if (direction == TextDirection::kLtr) {
- return AdjustBackwardPositionToAvoidCrossingEditingBoundaries(
+ return AdjustForwardPositionToAvoidCrossingEditingBoundaries(
visible_position, anchor);
}
- return AdjustForwardPositionToAvoidCrossingEditingBoundaries(
+ return AdjustBackwardPositionToAvoidCrossingEditingBoundaries(
visible_position, anchor);
}
- static const InlineBox* LogicalStartBoxOf(TextDirection direction,
- const InlineBox& box) {
- if (direction == TextDirection::kLtr)
- return box.Root().GetLogicalStartNonPseudoBox();
- return box.Root().GetLogicalEndNonPseudoBox();
- }
-
- static bool IsOvershot(int offset, const InlineBox& box) {
- if (box.IsLeftToRightDirection())
- return offset < box.CaretMinOffset();
- return offset > box.CaretMaxOffset();
- }
-};
+ // TODO(xiaochengh): The functions below are used only by bidi adjustment.
+ // Merge them into inline_box_traversal.cc.
-// The traversal strategy for |RightPositionOf()|.
-template <typename Strategy>
-struct TraversalRight {
- STATIC_ONLY(TraversalRight);
-
- static const InlineBox* BackwardLeafChildOf(const InlineBox& box) {
- return box.PrevLeafChild();
- }
-
- static int CaretEndOffsetOf(const InlineBox& box) {
- return box.CaretLeftmostOffset();
- }
-
- static int CaretMinOffsetOf(TextDirection direction, const InlineBox& box) {
- if (direction == TextDirection::kLtr)
+ static int CaretForwardOffsetInLineDirection(TextDirection line_direction,
+ const InlineBox& box) {
+ if (line_direction == TextDirection::kLtr)
return box.CaretMaxOffset();
return box.CaretMinOffset();
}
- static int CaretStartOffsetOf(const InlineBox& box) {
- return box.CaretRightmostOffset();
- }
-
static const InlineBox* FindBackwardBidiRun(const InlineBox& box,
unsigned bidi_level) {
return InlineBoxTraversal::FindLeftBidiRun(box, bidi_level);
@@ -196,18 +239,6 @@ struct TraversalRight {
bidi_level);
}
- static int ForwardGraphemeBoundaryOf(TextDirection direction,
- const Node& node,
- int offset) {
- if (direction == TextDirection::kLtr)
- return NextGraphemeBoundaryOf(node, offset);
- return PreviousGraphemeBoundaryOf(node, offset);
- }
-
- static const InlineBox* ForwardLeafChildOf(const InlineBox& box) {
- return box.NextLeafChild();
- }
-
static const InlineBox* ForwardNonPseudoLeafChildOf(const InlineBox& box) {
for (const InlineBox* runner = ForwardLeafChildOf(box); runner;
runner = ForwardLeafChildOf(*runner)) {
@@ -217,54 +248,25 @@ struct TraversalRight {
return nullptr;
}
- static const InlineBox* ForwardLeafChildIgnoringLineBreakOf(
- const InlineBox& box) {
- return box.NextLeafChildIgnoringLineBreak();
- }
-
- static PositionTemplate<Strategy> ForwardVisuallyDistinctCandidateOf(
- TextDirection direction,
- const PositionTemplate<Strategy>& position) {
- if (direction == TextDirection::kLtr)
- return NextVisuallyDistinctCandidate(position);
- return PreviousVisuallyDistinctCandidate(position);
- }
-
- static VisiblePositionTemplate<Strategy> HonorEditingBoundary(
- TextDirection direction,
- const VisiblePositionTemplate<Strategy>& visible_position,
- const PositionTemplate<Strategy>& anchor) {
- if (direction == TextDirection::kLtr) {
- return AdjustForwardPositionToAvoidCrossingEditingBoundaries(
- visible_position, anchor);
- }
- return AdjustBackwardPositionToAvoidCrossingEditingBoundaries(
- visible_position, anchor);
- }
-
- static const InlineBox* LogicalStartBoxOf(TextDirection direction,
- const InlineBox& box) {
- if (direction == TextDirection::kLtr)
+ static const InlineBox* LogicalForwardMostInLine(TextDirection line_direction,
+ const InlineBox& box) {
+ if (line_direction == TextDirection::kLtr)
return box.Root().GetLogicalEndNonPseudoBox();
return box.Root().GetLogicalStartNonPseudoBox();
}
-
- static bool IsOvershot(int offset, const InlineBox& box) {
- if (box.IsLeftToRightDirection())
- return offset > box.CaretMaxOffset();
- return offset < box.CaretMinOffset();
- }
};
template <typename Traversal>
-bool IsAfterAtomicInlineOrLineBreak(const InlineBox& box, int offset) {
- if (offset != Traversal::CaretEndOffsetOf(box))
+bool IsBeforeAtomicInlineOrLineBreak(const InlineBox& box, int offset) {
+ if (offset != Traversal::CaretBackwardOffsetOf(box))
return false;
if (box.IsInlineTextBox() && ToInlineTextBox(box).IsLineBreak())
return true;
return box.GetLineLayoutItem().IsAtomicInlineLevel();
}
+// TODO(xiaochengh): The function is for bidi adjustment.
+// Merge it into inline_box_traversal.cc.
template <typename Traversal>
const InlineBox* LeadingBoxOfEntireSecondaryRun(const InlineBox* box) {
const InlineBox* runner = box;
@@ -287,19 +289,22 @@ const InlineBox* LeadingBoxOfEntireSecondaryRun(const InlineBox* box) {
}
}
+// TODO(xiaochengh): The function is for bidi adjustment.
+// Merge it into inline_box_traversal.cc.
// TODO(xiaochengh): Stop passing return value by non-const reference parameters
template <typename Traversal>
bool FindForwardBoxInPossiblyBidiContext(const InlineBox*& box,
int& offset,
- TextDirection primary_direction) {
+ TextDirection line_direction) {
const unsigned char level = box->BidiLevel();
- if (box->Direction() == primary_direction) {
+ if (box->Direction() == line_direction) {
const InlineBox* const forward_box = Traversal::ForwardLeafChildOf(*box);
if (!forward_box) {
- if (const InlineBox* logical_start =
- Traversal::LogicalStartBoxOf(primary_direction, *box)) {
- box = logical_start;
- offset = Traversal::CaretMinOffsetOf(primary_direction, *box);
+ if (const InlineBox* logical_forward_most =
+ Traversal::LogicalForwardMostInLine(line_direction, *box)) {
+ box = logical_forward_most;
+ offset =
+ Traversal::CaretForwardOffsetInLineDirection(line_direction, *box);
}
return true;
}
@@ -313,15 +318,15 @@ bool FindForwardBoxInPossiblyBidiContext(const InlineBox*& box,
return true;
box = forward_box;
- offset = Traversal::CaretEndOffsetOf(*box);
- return box->Direction() == primary_direction;
+ offset = Traversal::CaretBackwardOffsetOf(*box);
+ return box->Direction() == line_direction;
}
const InlineBox* const forward_non_pseudo_box =
Traversal::ForwardNonPseudoLeafChildOf(*box);
if (forward_non_pseudo_box) {
box = forward_non_pseudo_box;
- offset = Traversal::CaretEndOffsetOf(*box);
+ offset = Traversal::CaretBackwardOffsetOf(*box);
if (box->BidiLevel() > level) {
const InlineBox* const forward_bidi_run =
Traversal::FindForwardBidiRun(*forward_non_pseudo_box, level);
@@ -333,7 +338,7 @@ bool FindForwardBoxInPossiblyBidiContext(const InlineBox*& box,
// Trailing edge of a secondary run. Set to the leading edge of
// the entire run.
box = LeadingBoxOfEntireSecondaryRun<Traversal>(box);
- offset = Traversal::CaretMinOffsetOf(primary_direction, *box);
+ offset = Traversal::CaretForwardOffsetInLineDirection(line_direction, *box);
return true;
}
@@ -341,63 +346,84 @@ template <typename Strategy, typename Traversal>
static PositionTemplate<Strategy> TraverseInternalAlgorithm(
const VisiblePositionTemplate<Strategy>& visible_position) {
DCHECK(visible_position.IsValid()) << visible_position;
- const PositionTemplate<Strategy> deep_position =
- visible_position.DeepEquivalent();
- PositionTemplate<Strategy> p = deep_position;
-
- if (p.IsNull())
+ if (visible_position.IsNull())
return PositionTemplate<Strategy>();
+ const PositionTemplate<Strategy> deep_position =
+ visible_position.DeepEquivalent();
const PositionTemplate<Strategy> downstream_start =
- MostForwardCaretPosition(p);
- const TextDirection primary_direction = PrimaryDirectionOf(*p.AnchorNode());
+ MostForwardCaretPosition(deep_position);
+ const TextDirection line_direction =
+ PrimaryDirectionOf(*deep_position.AnchorNode());
const TextAffinity affinity = visible_position.Affinity();
- while (true) {
- InlineBoxPosition box_position = ComputeInlineBoxPosition(
- PositionWithAffinityTemplate<Strategy>(p, affinity));
- const InlineBox* box = box_position.inline_box;
- int offset = box_position.offset_in_box;
+ // Conceptually, starting from the given caret position, traverse each leaf
+ // inline box and each caret position in the box (skipping CSS generated
+ // content) until we have:
+ // - crossed a grapheme boundary, or
+ // - reached the line boundary, or
+ // - reached an atomic inline.
+ // TODO(xiaochengh): Refactor the code to make it closer to the above.
+ // TODO(xiaochengh): Simplify loop termination conditions. Find and fix any
+ // possibility of infinite iterations.
+ for (InlineBoxPosition box_position =
+ ComputeInlineBoxPosition(visible_position.ToPositionWithAffinity());
+ ;) {
+ const InlineBox* const box = box_position.inline_box;
+ const int offset = box_position.offset_in_box;
if (!box) {
- return Traversal::ForwardVisuallyDistinctCandidateOf(primary_direction,
+ return Traversal::ForwardVisuallyDistinctCandidateOf(line_direction,
deep_position);
}
- while (true) {
- if (IsAfterAtomicInlineOrLineBreak<Traversal>(*box, offset)) {
+ const InlineBox* next_box = nullptr;
+ int next_offset = 0;
+ bool can_create_position = false;
+
+ // TODO(xiaochengh): The loop below iterates for exactly once. Merge it into
+ // the outer loop and clean up the code.
+ do {
+ if (IsBeforeAtomicInlineOrLineBreak<Traversal>(*box, offset)) {
return Traversal::ForwardVisuallyDistinctCandidateOf(box->Direction(),
deep_position);
}
const LineLayoutItem line_layout_item = box->GetLineLayoutItem();
+ // Skip generated content.
if (!line_layout_item.GetNode()) {
- box = Traversal::ForwardLeafChildOf(*box);
- if (!box) {
- return Traversal::ForwardVisuallyDistinctCandidateOf(
- primary_direction, deep_position);
+ next_box = Traversal::ForwardLeafChildOf(*box);
+ if (!next_box) {
+ return Traversal::ForwardVisuallyDistinctCandidateOf(line_direction,
+ deep_position);
}
- offset = Traversal::CaretEndOffsetOf(*box);
+ next_offset = Traversal::CaretBackwardOffsetOf(*next_box);
continue;
}
- offset = Traversal::ForwardGraphemeBoundaryOf(
- box->Direction(), *line_layout_item.GetNode(), offset);
+ const int forward_grapheme_boundary =
+ Traversal::ForwardGraphemeBoundaryOf(
+ box->Direction(), *line_layout_item.GetNode(), offset);
const int caret_min_offset = box->CaretMinOffset();
const int caret_max_offset = box->CaretMaxOffset();
- if (offset > caret_min_offset && offset < caret_max_offset)
+ if (forward_grapheme_boundary > caret_min_offset &&
+ forward_grapheme_boundary < caret_max_offset) {
+ next_box = box;
+ next_offset = forward_grapheme_boundary;
+ can_create_position = true;
break;
+ }
- if (Traversal::IsOvershot(offset, *box)) {
+ if (Traversal::IsOvershot(forward_grapheme_boundary, *box)) {
// Overshot forwardly.
const InlineBox* const forward_box =
Traversal::ForwardLeafChildIgnoringLineBreakOf(*box);
if (!forward_box) {
const PositionTemplate<Strategy>& forward_position =
Traversal::ForwardVisuallyDistinctCandidateOf(
- primary_direction, visible_position.DeepEquivalent());
+ line_direction, visible_position.DeepEquivalent());
if (forward_position.IsNull())
return PositionTemplate<Strategy>();
@@ -413,27 +439,41 @@ static PositionTemplate<Strategy> TraverseInternalAlgorithm(
// Reposition at the other logical position corresponding to our
// edge's visual position and go for another round.
- box = forward_box;
- offset = Traversal::CaretEndOffsetOf(*forward_box);
+ next_box = forward_box;
+ next_offset = Traversal::CaretBackwardOffsetOf(*forward_box);
continue;
}
- DCHECK_EQ(offset, Traversal::CaretStartOffsetOf(*box));
- const bool should_break = FindForwardBoxInPossiblyBidiContext<Traversal>(
- box, offset, primary_direction);
- if (should_break)
- break;
+ DCHECK_EQ(forward_grapheme_boundary,
+ Traversal::CaretForwardOffsetOf(*box));
+ next_box = box;
+ next_offset = forward_grapheme_boundary;
+ // We may be at a bidi boundary, in which case the visual caret position
+ // doesn't match its DOM position, and certain adjustment is needed.
+ can_create_position = FindForwardBoxInPossiblyBidiContext<Traversal>(
+ next_box, next_offset, line_direction);
+ } while (false);
+
+ if (!can_create_position) {
+ box_position = InlineBoxPosition(next_box, next_offset);
+ continue;
}
- p = PositionTemplate<Strategy>::EditingPositionOf(
- box->GetLineLayoutItem().GetNode(), offset);
+ // TODO(xiaochengh): Eliminate single-char variable name.
+ const PositionTemplate<Strategy> p =
+ PositionTemplate<Strategy>::EditingPositionOf(
+ next_box->GetLineLayoutItem().GetNode(), next_offset);
if ((IsVisuallyEquivalentCandidate(p) &&
MostForwardCaretPosition(p) != downstream_start) ||
p.AtStartOfTree() || p.AtEndOfTree())
return p;
+ // TODO(xiaochengh): This detour to |p| seems unnecessary. Investigate if we
+ // can simply use |InlineBoxPosition(next_box, next_offset)|.
DCHECK_NE(p, deep_position);
+ box_position = ComputeInlineBoxPosition(
+ PositionWithAffinityTemplate<Strategy>(p, affinity));
}
}
diff --git a/chromium/third_party/blink/renderer/core/editing/spellcheck/cold_mode_spell_check_requester.h b/chromium/third_party/blink/renderer/core/editing/spellcheck/cold_mode_spell_check_requester.h
index 051d047b775..12fe2e355e3 100644
--- a/chromium/third_party/blink/renderer/core/editing/spellcheck/cold_mode_spell_check_requester.h
+++ b/chromium/third_party/blink/renderer/core/editing/spellcheck/cold_mode_spell_check_requester.h
@@ -16,10 +16,10 @@ class LocalFrame;
class IdleDeadline;
class SpellCheckRequester;
-// This class is only supposed to be used by IdleSpellCheckCallback in cold mode
-// invocation. Not to be confused with SpellCheckRequester.
-// The class iteratively checks the editing host currently focused when the
-// document is idle.
+// This class is only supposed to be used by IdleSpellCheckController in cold
+// mode invocation. Not to be confused with SpellCheckRequester. The class
+// iteratively checks the editing host currently focused when the document is
+// idle.
class ColdModeSpellCheckRequester
: public GarbageCollected<ColdModeSpellCheckRequester> {
public:
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 b9731680d1a..037cbee5320 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
@@ -17,6 +17,7 @@
#include "third_party/blink/renderer/core/editing/spellcheck/spell_check_requester.h"
#include "third_party/blink/renderer/core/editing/spellcheck/spell_checker.h"
#include "third_party/blink/renderer/core/editing/visible_position.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
namespace blink {
@@ -116,7 +117,7 @@ void HotModeSpellCheckRequester::CheckSpellingAt(const Position& position) {
CurrentWordIfTypingInPartialWord(*root_editable);
if (current_word.IsNotNull()) {
root_editable->GetDocument().Markers().RemoveMarkersInRange(
- current_word, DocumentMarker::MisspellingMarkers());
+ current_word, DocumentMarker::MarkerTypes::Misspelling());
return;
}
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 9a6e8f62112..059987d772b 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
@@ -13,8 +13,8 @@ namespace blink {
class Element;
class SpellCheckRequester;
-// This class is only supposed to be used by IdleSpellCheckCallback in hot mode
-// invocation. Not to be confused with SpellCheckRequester.
+// This class is only supposed to be used by IdleSpellCheckController in hot
+// mode invocation. Not to be confused with SpellCheckRequester.
class HotModeSpellCheckRequester {
STACK_ALLOCATED();
diff --git a/chromium/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_callback.cc b/chromium/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller.cc
index d76ebfa4daa..21c25f5b4ba 100644
--- a/chromium/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_callback.cc
+++ b/chromium/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller.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/editing/spellcheck/idle_spell_check_callback.h"
+#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"
@@ -39,20 +39,42 @@ constexpr TimeDelta kForcedInvocationDeadline = TimeDelta::FromSeconds(10);
} // namespace
-IdleSpellCheckCallback::~IdleSpellCheckCallback() = default;
+class IdleSpellCheckController::IdleCallback final
+ : public ScriptedIdleTaskController::IdleTask {
+ public:
+ static IdleCallback* Create(IdleSpellCheckController* controller) {
+ return new IdleCallback(controller);
+ }
+
+ void Trace(blink::Visitor* visitor) final {
+ visitor->Trace(controller_);
+ ScriptedIdleTaskController::IdleTask::Trace(visitor);
+ }
+
+ private:
+ explicit IdleCallback(IdleSpellCheckController* controller)
+ : controller_(controller) {}
+
+ void invoke(IdleDeadline* deadline) final { controller_->Invoke(deadline); }
-void IdleSpellCheckCallback::Trace(blink::Visitor* visitor) {
+ const Member<IdleSpellCheckController> controller_;
+
+ DISALLOW_COPY_AND_ASSIGN(IdleCallback);
+};
+
+IdleSpellCheckController::~IdleSpellCheckController() = default;
+
+void IdleSpellCheckController::Trace(blink::Visitor* visitor) {
visitor->Trace(frame_);
visitor->Trace(cold_mode_requester_);
DocumentShutdownObserver::Trace(visitor);
- ScriptedIdleTaskController::IdleTask::Trace(visitor);
}
-IdleSpellCheckCallback* IdleSpellCheckCallback::Create(LocalFrame& frame) {
- return new IdleSpellCheckCallback(frame);
+IdleSpellCheckController* IdleSpellCheckController::Create(LocalFrame& frame) {
+ return new IdleSpellCheckController(frame);
}
-IdleSpellCheckCallback::IdleSpellCheckCallback(LocalFrame& frame)
+IdleSpellCheckController::IdleSpellCheckController(LocalFrame& frame)
: state_(State::kInactive),
idle_callback_handle_(kInvalidHandle),
frame_(frame),
@@ -60,27 +82,31 @@ IdleSpellCheckCallback::IdleSpellCheckCallback(LocalFrame& frame)
cold_mode_requester_(ColdModeSpellCheckRequester::Create(frame)),
cold_mode_timer_(frame.GetTaskRunner(TaskType::kInternalDefault),
this,
- &IdleSpellCheckCallback::ColdModeTimerFired) {}
+ &IdleSpellCheckController::ColdModeTimerFired) {}
-SpellCheckRequester& IdleSpellCheckCallback::GetSpellCheckRequester() const {
+SpellCheckRequester& IdleSpellCheckController::GetSpellCheckRequester() const {
return GetFrame().GetSpellChecker().GetSpellCheckRequester();
}
-bool IdleSpellCheckCallback::IsSpellCheckingEnabled() const {
+bool IdleSpellCheckController::IsSpellCheckingEnabled() const {
return GetFrame().GetSpellChecker().IsSpellCheckingEnabled();
}
-void IdleSpellCheckCallback::Deactivate() {
+void IdleSpellCheckController::DisposeIdleCallback() {
+ if (idle_callback_handle_ != kInvalidHandle && IsAvailable())
+ GetDocument().CancelIdleCallback(idle_callback_handle_);
+ idle_callback_handle_ = kInvalidHandle;
+}
+
+void IdleSpellCheckController::Deactivate() {
state_ = State::kInactive;
if (cold_mode_timer_.IsActive())
cold_mode_timer_.Stop();
cold_mode_requester_->ClearProgress();
- if (idle_callback_handle_ != kInvalidHandle && IsAvailable())
- GetDocument().CancelIdleCallback(idle_callback_handle_);
- idle_callback_handle_ = kInvalidHandle;
+ DisposeIdleCallback();
}
-void IdleSpellCheckCallback::SetNeedsInvocation() {
+void IdleSpellCheckController::SetNeedsInvocation() {
if (!IsSpellCheckingEnabled() || !IsAvailable()) {
Deactivate();
return;
@@ -96,18 +122,17 @@ void IdleSpellCheckCallback::SetNeedsInvocation() {
cold_mode_timer_.Stop();
}
- if (state_ == State::kColdModeRequested) {
- GetDocument().CancelIdleCallback(idle_callback_handle_);
- idle_callback_handle_ = kInvalidHandle;
- }
+ if (state_ == State::kColdModeRequested)
+ DisposeIdleCallback();
IdleRequestOptions options;
options.setTimeout(kHotModeRequestTimeoutMS);
- idle_callback_handle_ = GetDocument().RequestIdleCallback(this, options);
+ idle_callback_handle_ =
+ GetDocument().RequestIdleCallback(IdleCallback::Create(this), options);
state_ = State::kHotModeRequested;
}
-void IdleSpellCheckCallback::SetNeedsColdModeInvocation() {
+void IdleSpellCheckController::SetNeedsColdModeInvocation() {
if (!RuntimeEnabledFeatures::IdleTimeColdModeSpellCheckingEnabled() ||
!IsSpellCheckingEnabled()) {
Deactivate();
@@ -126,7 +151,7 @@ void IdleSpellCheckCallback::SetNeedsColdModeInvocation() {
state_ = State::kColdModeTimerStarted;
}
-void IdleSpellCheckCallback::ColdModeTimerFired(TimerBase*) {
+void IdleSpellCheckController::ColdModeTimerFired(TimerBase*) {
DCHECK(RuntimeEnabledFeatures::IdleTimeColdModeSpellCheckingEnabled());
DCHECK_EQ(State::kColdModeTimerStarted, state_);
@@ -135,13 +160,13 @@ void IdleSpellCheckCallback::ColdModeTimerFired(TimerBase*) {
return;
}
- idle_callback_handle_ =
- GetDocument().RequestIdleCallback(this, IdleRequestOptions());
+ idle_callback_handle_ = GetDocument().RequestIdleCallback(
+ IdleCallback::Create(this), IdleRequestOptions());
state_ = State::kColdModeRequested;
}
-void IdleSpellCheckCallback::HotModeInvocation(IdleDeadline* deadline) {
- TRACE_EVENT0("blink", "IdleSpellCheckCallback::hotModeInvocation");
+void IdleSpellCheckController::HotModeInvocation(IdleDeadline* deadline) {
+ TRACE_EVENT0("blink", "IdleSpellCheckController::hotModeInvocation");
// TODO(xiaochengh): Figure out if this has any performance impact.
GetDocument().UpdateStyleAndLayout();
@@ -169,7 +194,7 @@ void IdleSpellCheckCallback::HotModeInvocation(IdleDeadline* deadline) {
}
}
-void IdleSpellCheckCallback::invoke(IdleDeadline* deadline) {
+void IdleSpellCheckController::Invoke(IdleDeadline* deadline) {
DCHECK_NE(idle_callback_handle_, kInvalidHandle);
idle_callback_handle_ = kInvalidHandle;
@@ -195,15 +220,15 @@ void IdleSpellCheckCallback::invoke(IdleDeadline* deadline) {
}
}
-void IdleSpellCheckCallback::DocumentAttached(Document* document) {
+void IdleSpellCheckController::DocumentAttached(Document* document) {
SetContext(document);
}
-void IdleSpellCheckCallback::ContextDestroyed(Document*) {
+void IdleSpellCheckController::ContextDestroyed(Document*) {
Deactivate();
}
-void IdleSpellCheckCallback::ForceInvocationForTesting() {
+void IdleSpellCheckController::ForceInvocationForTesting() {
if (!IsSpellCheckingEnabled())
return;
@@ -216,12 +241,12 @@ void IdleSpellCheckCallback::ForceInvocationForTesting() {
cold_mode_timer_.Stop();
state_ = State::kColdModeRequested;
idle_callback_handle_ = kDummyHandleForForcedInvocation;
- invoke(deadline);
+ Invoke(deadline);
break;
case State::kHotModeRequested:
case State::kColdModeRequested:
GetDocument().CancelIdleCallback(idle_callback_handle_);
- invoke(deadline);
+ Invoke(deadline);
break;
case State::kInactive:
case State::kInHotModeInvocation:
@@ -230,13 +255,13 @@ void IdleSpellCheckCallback::ForceInvocationForTesting() {
}
}
-void IdleSpellCheckCallback::SkipColdModeTimerForTesting() {
+void IdleSpellCheckController::SkipColdModeTimerForTesting() {
DCHECK(cold_mode_timer_.IsActive());
cold_mode_timer_.Stop();
ColdModeTimerFired(&cold_mode_timer_);
}
-void IdleSpellCheckCallback::SetNeedsMoreColdModeInvocationForTesting() {
+void IdleSpellCheckController::SetNeedsMoreColdModeInvocationForTesting() {
cold_mode_requester_->SetNeedsMoreInvocationForTesting();
}
diff --git a/chromium/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_callback.h b/chromium/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller.h
index 31237edd418..72e6fcc39e1 100644
--- a/chromium/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_callback.h
+++ b/chromium/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller.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_EDITING_SPELLCHECK_IDLE_SPELL_CHECK_CALLBACK_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_SPELLCHECK_IDLE_SPELL_CHECK_CALLBACK_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_SPELLCHECK_IDLE_SPELL_CHECK_CONTROLLER_H_
+#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"
@@ -17,28 +17,28 @@ class ColdModeSpellCheckRequester;
class LocalFrame;
class SpellCheckRequester;
-#define FOR_EACH_IDLE_SPELL_CHECK_CALLBACK_STATE(V) \
- V(Inactive) \
- V(HotModeRequested) \
- V(InHotModeInvocation) \
- V(ColdModeTimerStarted) \
- V(ColdModeRequested) \
+#define FOR_EACH_IDLE_SPELL_CHECK_CONTROLLER_STATE(V) \
+ V(Inactive) \
+ V(HotModeRequested) \
+ V(InHotModeInvocation) \
+ V(ColdModeTimerStarted) \
+ V(ColdModeRequested) \
V(InColdModeInvocation)
// Main class for the implementation of idle time spell checker.
-class CORE_EXPORT IdleSpellCheckCallback final
- : public ScriptedIdleTaskController::IdleTask,
+class CORE_EXPORT IdleSpellCheckController final
+ : public GarbageCollectedFinalized<IdleSpellCheckController>,
public DocumentShutdownObserver {
- DISALLOW_COPY_AND_ASSIGN(IdleSpellCheckCallback);
- USING_GARBAGE_COLLECTED_MIXIN(IdleSpellCheckCallback);
+ DISALLOW_COPY_AND_ASSIGN(IdleSpellCheckController);
+ USING_GARBAGE_COLLECTED_MIXIN(IdleSpellCheckController);
public:
- static IdleSpellCheckCallback* Create(LocalFrame&);
- ~IdleSpellCheckCallback() override;
+ static IdleSpellCheckController* Create(LocalFrame&);
+ ~IdleSpellCheckController();
enum class State {
#define V(state) k##state,
- FOR_EACH_IDLE_SPELL_CHECK_CALLBACK_STATE(V)
+ FOR_EACH_IDLE_SPELL_CHECK_CONTROLLER_STATE(V)
#undef V
};
@@ -64,8 +64,9 @@ class CORE_EXPORT IdleSpellCheckCallback final
void Trace(blink::Visitor*) override;
private:
- explicit IdleSpellCheckCallback(LocalFrame&);
- void invoke(IdleDeadline*) override;
+ class IdleCallback;
+
+ explicit IdleSpellCheckController(LocalFrame&);
LocalFrame& GetFrame() const { return *frame_; }
@@ -81,6 +82,9 @@ class CORE_EXPORT IdleSpellCheckCallback final
// Returns whether spell checking is globally enabled.
bool IsSpellCheckingEnabled() const;
+ // Called at idle time as entrance function.
+ void Invoke(IdleDeadline*);
+
// Functions for hot mode.
void HotModeInvocation(IdleDeadline*);
@@ -95,16 +99,18 @@ class CORE_EXPORT IdleSpellCheckCallback final
// Implements |DocumentShutdownObserver|.
void ContextDestroyed(Document*) final;
+ void DisposeIdleCallback();
+
State state_;
int idle_callback_handle_;
const Member<LocalFrame> frame_;
uint64_t last_processed_undo_step_sequence_;
const Member<ColdModeSpellCheckRequester> cold_mode_requester_;
- TaskRunnerTimer<IdleSpellCheckCallback> cold_mode_timer_;
+ TaskRunnerTimer<IdleSpellCheckController> cold_mode_timer_;
- friend class IdleSpellCheckCallbackTest;
+ friend class IdleSpellCheckControllerTest;
};
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_SPELLCHECK_IDLE_SPELL_CHECK_CALLBACK_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_SPELLCHECK_IDLE_SPELL_CHECK_CONTROLLER_H_
diff --git a/chromium/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_callback_test.cc b/chromium/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller_test.cc
index 74179ea4f8a..91dbdb2e3d7 100644
--- a/chromium/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_callback_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller_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/editing/spellcheck/idle_spell_check_callback.h"
+#include "third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/editing/spellcheck/spell_check_test_base.h"
@@ -14,12 +14,12 @@
namespace blink {
-using State = IdleSpellCheckCallback::State;
+using State = IdleSpellCheckController::State;
-class IdleSpellCheckCallbackTest : public SpellCheckTestBase {
+class IdleSpellCheckControllerTest : public SpellCheckTestBase {
protected:
- IdleSpellCheckCallback& IdleChecker() {
- return GetSpellChecker().GetIdleSpellCheckCallback();
+ IdleSpellCheckController& IdleChecker() {
+ return GetSpellChecker().GetIdleSpellCheckController();
}
void SetUp() override {
@@ -55,28 +55,28 @@ class IdleSpellCheckCallbackTest : public SpellCheckTestBase {
// Test cases for lifecycle state transitions.
-TEST_F(IdleSpellCheckCallbackTest, InitializationWithColdMode) {
+TEST_F(IdleSpellCheckControllerTest, InitializationWithColdMode) {
if (!RuntimeEnabledFeatures::IdleTimeColdModeSpellCheckingEnabled())
return;
EXPECT_EQ(State::kColdModeTimerStarted, IdleChecker().GetState());
}
-TEST_F(IdleSpellCheckCallbackTest, InitializationWithoutColdMode) {
+TEST_F(IdleSpellCheckControllerTest, InitializationWithoutColdMode) {
if (RuntimeEnabledFeatures::IdleTimeColdModeSpellCheckingEnabled())
return;
EXPECT_EQ(State::kInactive, IdleChecker().GetState());
}
-TEST_F(IdleSpellCheckCallbackTest, RequestWhenInactive) {
+TEST_F(IdleSpellCheckControllerTest, RequestWhenInactive) {
TransitTo(State::kInactive);
IdleChecker().SetNeedsInvocation();
EXPECT_EQ(State::kHotModeRequested, IdleChecker().GetState());
EXPECT_NE(-1, IdleChecker().IdleCallbackHandle());
}
-TEST_F(IdleSpellCheckCallbackTest, RequestWhenHotModeRequested) {
+TEST_F(IdleSpellCheckControllerTest, RequestWhenHotModeRequested) {
TransitTo(State::kHotModeRequested);
int handle = IdleChecker().IdleCallbackHandle();
IdleChecker().SetNeedsInvocation();
@@ -85,7 +85,7 @@ TEST_F(IdleSpellCheckCallbackTest, RequestWhenHotModeRequested) {
EXPECT_NE(-1, IdleChecker().IdleCallbackHandle());
}
-TEST_F(IdleSpellCheckCallbackTest, RequestWhenColdModeTimerStarted) {
+TEST_F(IdleSpellCheckControllerTest, RequestWhenColdModeTimerStarted) {
if (!RuntimeEnabledFeatures::IdleTimeColdModeSpellCheckingEnabled())
return;
@@ -95,7 +95,7 @@ TEST_F(IdleSpellCheckCallbackTest, RequestWhenColdModeTimerStarted) {
EXPECT_NE(-1, IdleChecker().IdleCallbackHandle());
}
-TEST_F(IdleSpellCheckCallbackTest, RequestWhenColdModeRequested) {
+TEST_F(IdleSpellCheckControllerTest, RequestWhenColdModeRequested) {
if (!RuntimeEnabledFeatures::IdleTimeColdModeSpellCheckingEnabled())
return;
@@ -107,7 +107,7 @@ TEST_F(IdleSpellCheckCallbackTest, RequestWhenColdModeRequested) {
EXPECT_NE(-1, IdleChecker().IdleCallbackHandle());
}
-TEST_F(IdleSpellCheckCallbackTest, HotModeTransitToInactive) {
+TEST_F(IdleSpellCheckControllerTest, HotModeTransitToInactive) {
if (RuntimeEnabledFeatures::IdleTimeColdModeSpellCheckingEnabled())
return;
@@ -116,7 +116,7 @@ TEST_F(IdleSpellCheckCallbackTest, HotModeTransitToInactive) {
EXPECT_EQ(State::kInactive, IdleChecker().GetState());
}
-TEST_F(IdleSpellCheckCallbackTest, HotModeTransitToColdMode) {
+TEST_F(IdleSpellCheckControllerTest, HotModeTransitToColdMode) {
if (!RuntimeEnabledFeatures::IdleTimeColdModeSpellCheckingEnabled())
return;
@@ -125,7 +125,7 @@ TEST_F(IdleSpellCheckCallbackTest, HotModeTransitToColdMode) {
EXPECT_EQ(State::kColdModeTimerStarted, IdleChecker().GetState());
}
-TEST_F(IdleSpellCheckCallbackTest, ColdModeTimerStartedToRequested) {
+TEST_F(IdleSpellCheckControllerTest, ColdModeTimerStartedToRequested) {
if (!RuntimeEnabledFeatures::IdleTimeColdModeSpellCheckingEnabled())
return;
@@ -135,7 +135,7 @@ TEST_F(IdleSpellCheckCallbackTest, ColdModeTimerStartedToRequested) {
EXPECT_NE(-1, IdleChecker().IdleCallbackHandle());
}
-TEST_F(IdleSpellCheckCallbackTest, ColdModeStayAtColdMode) {
+TEST_F(IdleSpellCheckControllerTest, ColdModeStayAtColdMode) {
if (!RuntimeEnabledFeatures::IdleTimeColdModeSpellCheckingEnabled())
return;
@@ -145,7 +145,7 @@ TEST_F(IdleSpellCheckCallbackTest, ColdModeStayAtColdMode) {
EXPECT_EQ(State::kColdModeTimerStarted, IdleChecker().GetState());
}
-TEST_F(IdleSpellCheckCallbackTest, ColdModeToInactive) {
+TEST_F(IdleSpellCheckControllerTest, ColdModeToInactive) {
if (!RuntimeEnabledFeatures::IdleTimeColdModeSpellCheckingEnabled())
return;
@@ -154,19 +154,19 @@ TEST_F(IdleSpellCheckCallbackTest, ColdModeToInactive) {
EXPECT_EQ(State::kInactive, IdleChecker().GetState());
}
-TEST_F(IdleSpellCheckCallbackTest, DetachWhenInactive) {
+TEST_F(IdleSpellCheckControllerTest, DetachWhenInactive) {
TransitTo(State::kInactive);
GetDocument().Shutdown();
EXPECT_EQ(State::kInactive, IdleChecker().GetState());
}
-TEST_F(IdleSpellCheckCallbackTest, DetachWhenHotModeRequested) {
+TEST_F(IdleSpellCheckControllerTest, DetachWhenHotModeRequested) {
TransitTo(State::kHotModeRequested);
GetDocument().Shutdown();
EXPECT_EQ(State::kInactive, IdleChecker().GetState());
}
-TEST_F(IdleSpellCheckCallbackTest, DetachWhenColdModeTimerStarted) {
+TEST_F(IdleSpellCheckControllerTest, DetachWhenColdModeTimerStarted) {
if (!RuntimeEnabledFeatures::IdleTimeColdModeSpellCheckingEnabled())
return;
@@ -175,7 +175,7 @@ TEST_F(IdleSpellCheckCallbackTest, DetachWhenColdModeTimerStarted) {
EXPECT_EQ(State::kInactive, IdleChecker().GetState());
}
-TEST_F(IdleSpellCheckCallbackTest, DetachWhenColdModeRequested) {
+TEST_F(IdleSpellCheckControllerTest, DetachWhenColdModeRequested) {
if (!RuntimeEnabledFeatures::IdleTimeColdModeSpellCheckingEnabled())
return;
@@ -184,8 +184,8 @@ TEST_F(IdleSpellCheckCallbackTest, DetachWhenColdModeRequested) {
EXPECT_EQ(State::kInactive, IdleChecker().GetState());
}
-// crbug.com/863784
-TEST_F(IdleSpellCheckCallbackTest, ColdModeRangeCrossesShadow) {
+// https://crbug.com/863784
+TEST_F(IdleSpellCheckControllerTest, ColdModeRangeCrossesShadow) {
ScopedIdleTimeColdModeSpellCheckingForTest cold_mode_scope(true);
SetBodyContent(
"<div contenteditable style=\"width:800px\">"
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 ddead93876c..84b674e7837 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
@@ -43,7 +43,7 @@
#include "third_party/blink/renderer/core/editing/markers/document_marker_controller.h"
#include "third_party/blink/renderer/core/editing/markers/spell_check_marker.h"
#include "third_party/blink/renderer/core/editing/selection_template.h"
-#include "third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_callback.h"
+#include "third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller.h"
#include "third_party/blink/renderer/core/editing/spellcheck/spell_check_requester.h"
#include "third_party/blink/renderer/core/editing/spellcheck/text_checking_paragraph.h"
#include "third_party/blink/renderer/core/editing/visible_position.h"
@@ -107,7 +107,7 @@ WebTextCheckClient* SpellChecker::GetTextCheckerClient() const {
SpellChecker::SpellChecker(LocalFrame& frame)
: frame_(&frame),
spell_check_requester_(SpellCheckRequester::Create(frame)),
- idle_spell_check_callback_(IdleSpellCheckCallback::Create(frame)) {}
+ idle_spell_check_controller_(IdleSpellCheckController::Create(frame)) {}
bool SpellChecker::IsSpellCheckingEnabled() const {
if (WebTextCheckClient* client = GetTextCheckerClient())
@@ -120,7 +120,7 @@ void SpellChecker::IgnoreSpelling() {
.Selection()
.ComputeVisibleSelectionInDOMTree()
.ToNormalizedEphemeralRange(),
- DocumentMarker::kSpelling);
+ DocumentMarker::MarkerTypes::Spelling());
}
void SpellChecker::AdvanceToNextMisspelling(bool start_before_selection) {
@@ -322,7 +322,7 @@ void SpellChecker::MarkAndReplaceFor(
}
// Clear the stale markers.
- RemoveMarkers(checking_range, DocumentMarker::MisspellingMarkers());
+ RemoveMarkers(checking_range, DocumentMarker::MarkerTypes::Misspelling());
if (!results.size())
return;
@@ -415,12 +415,10 @@ void SpellChecker::RemoveSpellingAndGrammarMarkers(const HTMLElement& element,
// needs to be audited. See http://crbug.com/590369 for more details.
GetFrame().GetDocument()->UpdateStyleAndLayoutTreeForNode(&element);
- DocumentMarker::MarkerTypes marker_types(DocumentMarker::kSpelling);
- marker_types.Add(DocumentMarker::kGrammar);
for (Node& node : NodeTraversal::InclusiveDescendantsOf(element)) {
if (elements_type == ElementsType::kAll || !HasEditableStyle(node)) {
- GetFrame().GetDocument()->Markers().RemoveMarkersForNode(&node,
- marker_types);
+ GetFrame().GetDocument()->Markers().RemoveMarkersForNode(
+ &node, DocumentMarker::MarkerTypes::Misspelling());
}
}
}
@@ -456,7 +454,7 @@ SpellChecker::GetSpellCheckMarkerUnderSelection() const {
DocumentMarker* const marker =
GetFrame().GetDocument()->Markers().FirstMarkerIntersectingOffsetRange(
ToText(*selection_start_container), selection_start_offset,
- selection_end_offset, DocumentMarker::MisspellingMarkers());
+ selection_end_offset, DocumentMarker::MarkerTypes::Misspelling());
if (!marker)
return {};
@@ -538,16 +536,16 @@ void SpellChecker::ReplaceMisspelledRange(const String& text) {
}
void SpellChecker::RespondToChangedSelection() {
- idle_spell_check_callback_->SetNeedsInvocation();
+ idle_spell_check_controller_->SetNeedsInvocation();
}
void SpellChecker::RespondToChangedContents() {
- idle_spell_check_callback_->SetNeedsInvocation();
+ idle_spell_check_controller_->SetNeedsInvocation();
}
void SpellChecker::RemoveSpellingMarkers() {
GetFrame().GetDocument()->Markers().RemoveMarkersOfTypes(
- DocumentMarker::MisspellingMarkers());
+ DocumentMarker::MarkerTypes::Misspelling());
}
void SpellChecker::RemoveSpellingMarkersUnderWords(
@@ -588,13 +586,13 @@ bool SpellChecker::SelectionStartHasMarkerFor(
.ComputeVisibleSelectionInDOMTree()
.Start()
.AnchorNode());
- if (!node)
+ if (!node || !node->IsTextNode())
return false;
unsigned start_offset = static_cast<unsigned>(from);
unsigned end_offset = static_cast<unsigned>(from + length);
DocumentMarkerVector markers =
- GetFrame().GetDocument()->Markers().MarkersFor(node);
+ GetFrame().GetDocument()->Markers().MarkersFor(ToText(*node));
for (size_t i = 0; i < markers.size(); ++i) {
DocumentMarker* marker = markers[i];
if (marker->StartOffset() <= start_offset &&
@@ -620,18 +618,18 @@ void SpellChecker::CancelCheck() {
}
void SpellChecker::DocumentAttached(Document* document) {
- idle_spell_check_callback_->DocumentAttached(document);
+ idle_spell_check_controller_->DocumentAttached(document);
}
void SpellChecker::Trace(blink::Visitor* visitor) {
visitor->Trace(frame_);
visitor->Trace(spell_check_requester_);
- visitor->Trace(idle_spell_check_callback_);
+ visitor->Trace(idle_spell_check_controller_);
}
void SpellChecker::PrepareForLeakDetection() {
spell_check_requester_->PrepareForLeakDetection();
- idle_spell_check_callback_->Deactivate();
+ idle_spell_check_controller_->Deactivate();
}
Vector<TextCheckingResult> SpellChecker::FindMisspellings(const String& text) {
diff --git a/chromium/third_party/blink/renderer/core/editing/spellcheck/spell_checker.h b/chromium/third_party/blink/renderer/core/editing/spellcheck/spell_checker.h
index ac10024ee57..d312e93e2be 100644
--- a/chromium/third_party/blink/renderer/core/editing/spellcheck/spell_checker.h
+++ b/chromium/third_party/blink/renderer/core/editing/spellcheck/spell_checker.h
@@ -37,7 +37,7 @@ namespace blink {
class Document;
class Element;
-class IdleSpellCheckCallback;
+class IdleSpellCheckController;
class LocalFrame;
class HTMLElement;
class SpellCheckMarker;
@@ -85,8 +85,8 @@ class CORE_EXPORT SpellChecker final : public GarbageCollected<SpellChecker> {
SpellCheckRequester& GetSpellCheckRequester() const {
return *spell_check_requester_;
}
- IdleSpellCheckCallback& GetIdleSpellCheckCallback() const {
- return *idle_spell_check_callback_;
+ IdleSpellCheckController& GetIdleSpellCheckController() const {
+ return *idle_spell_check_controller_;
}
// The leak detector will report leaks should queued requests be posted
@@ -116,7 +116,7 @@ class CORE_EXPORT SpellChecker final : public GarbageCollected<SpellChecker> {
Member<LocalFrame> frame_;
const Member<SpellCheckRequester> spell_check_requester_;
- const Member<IdleSpellCheckCallback> idle_spell_check_callback_;
+ const Member<IdleSpellCheckController> idle_spell_check_controller_;
DISALLOW_COPY_AND_ASSIGN(SpellChecker);
};
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 ae13fc64b71..34899454590 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
@@ -21,7 +21,9 @@ namespace blink {
class SpellCheckerTest : public SpellCheckTestBase {
protected:
- int LayoutCount() const { return Page().GetFrameView().LayoutCount(); }
+ unsigned LayoutCount() const {
+ return Page().GetFrameView().LayoutCountForTesting();
+ }
DummyPageHolder& Page() const { return GetDummyPageHolder(); }
void ForceLayout();
@@ -91,7 +93,7 @@ TEST_F(SpellCheckerTest, SpellCheckDoesNotCauseUpdateLayout) {
EXPECT_TRUE(GetSpellChecker().IsSpellCheckingEnabled());
ForceLayout();
- int start_count = LayoutCount();
+ unsigned start_count = LayoutCount();
GetSpellChecker().RespondToChangedSelection();
EXPECT_EQ(start_count, LayoutCount());
}
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 e66b7394c4c..f12657dda8e 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
@@ -102,6 +102,7 @@ EphemeralRangeInFlatTree ComputeRangeSurroundingCaret(
struct SuggestionInfosWithNodeAndHighlightColor {
STACK_ALLOCATED();
+ public:
Persistent<Node> text_node;
Color highlight_color;
Vector<TextSuggestionInfo> suggestion_infos;
@@ -224,8 +225,10 @@ void TextSuggestionController::HandlePotentialSuggestionTap(
const std::pair<const Node*, const DocumentMarker*>& node_and_marker =
FirstMarkerIntersectingRange(
- range_to_check, DocumentMarker::kSpelling | DocumentMarker::kGrammar |
- DocumentMarker::kSuggestion);
+ range_to_check,
+ DocumentMarker::MarkerTypes(DocumentMarker::kSpelling |
+ DocumentMarker::kGrammar |
+ DocumentMarker::kSuggestion));
if (!node_and_marker.first)
return;
@@ -255,7 +258,7 @@ void TextSuggestionController::ReplaceActiveSuggestionRange(
const HeapVector<std::pair<Member<Node>, Member<DocumentMarker>>>&
node_marker_pairs =
GetFrame().GetDocument()->Markers().MarkersIntersectingRange(
- range_to_check, DocumentMarker::kActiveSuggestion);
+ range_to_check, DocumentMarker::MarkerTypes::ActiveSuggestion());
if (node_marker_pairs.IsEmpty())
return;
@@ -291,7 +294,7 @@ void TextSuggestionController::ApplyTextSuggestion(int32_t marker_tag,
const HeapVector<std::pair<Member<Node>, Member<DocumentMarker>>>&
node_marker_pairs =
GetFrame().GetDocument()->Markers().MarkersIntersectingRange(
- range_to_check, DocumentMarker::kSuggestion);
+ range_to_check, DocumentMarker::MarkerTypes::Suggestion());
const Node* marker_text_node = nullptr;
SuggestionMarker* marker = nullptr;
@@ -356,7 +359,7 @@ void TextSuggestionController::OnSuggestionMenuClosed() {
return;
GetDocument().Markers().RemoveMarkersOfTypes(
- DocumentMarker::kActiveSuggestion);
+ DocumentMarker::MarkerTypes::ActiveSuggestion());
GetFrame().Selection().SetCaretVisible(true);
is_suggestion_menu_open_ = false;
}
@@ -381,7 +384,7 @@ void TextSuggestionController::SuggestionMenuTimeoutCallback(
const HeapVector<std::pair<Member<Node>, Member<DocumentMarker>>>&
node_suggestion_marker_pairs =
GetFrame().GetDocument()->Markers().MarkersIntersectingRange(
- range_to_check, DocumentMarker::kSuggestion);
+ range_to_check, DocumentMarker::MarkerTypes::Suggestion());
if (!node_suggestion_marker_pairs.IsEmpty()) {
ShowSuggestionMenu(node_suggestion_marker_pairs, max_number_of_suggestions);
return;
@@ -391,7 +394,7 @@ void TextSuggestionController::SuggestionMenuTimeoutCallback(
const HeapVector<std::pair<Member<Node>, Member<DocumentMarker>>>
node_spelling_marker_pairs =
GetFrame().GetDocument()->Markers().MarkersIntersectingRange(
- range_to_check, DocumentMarker::MisspellingMarkers());
+ range_to_check, DocumentMarker::MarkerTypes::Misspelling());
if (!node_spelling_marker_pairs.IsEmpty())
ShowSpellCheckMenu(node_spelling_marker_pairs.front());
@@ -416,7 +419,7 @@ void TextSuggestionController::ShowSpellCheckMenu(
GetFrame().Selection().SetCaretVisible(false);
GetDocument().Markers().AddActiveSuggestionMarker(
active_suggestion_range, SK_ColorTRANSPARENT,
- ui::mojom::ImeTextSpanThickness::kNone,
+ ws::mojom::ImeTextSpanThickness::kNone,
LayoutTheme::GetTheme().PlatformActiveSpellingMarkerHighlightColor());
Vector<String> suggestions;
@@ -478,7 +481,7 @@ void TextSuggestionController::ShowSuggestionMenu(
Position(text_node, span_union_end));
GetDocument().Markers().AddActiveSuggestionMarker(
- marker_range, SK_ColorTRANSPARENT, ui::mojom::ImeTextSpanThickness::kThin,
+ marker_range, SK_ColorTRANSPARENT, ws::mojom::ImeTextSpanThickness::kThin,
suggestion_infos_with_node_and_highlight_color.highlight_color);
is_suggestion_menu_open_ = true;
@@ -580,7 +583,8 @@ TextSuggestionController::FirstMarkerTouchingSelection(
void TextSuggestionController::AttemptToDeleteActiveSuggestionRange() {
const std::pair<const Node*, const DocumentMarker*>& node_and_marker =
- FirstMarkerTouchingSelection(DocumentMarker::kActiveSuggestion);
+ FirstMarkerTouchingSelection(
+ DocumentMarker::MarkerTypes::ActiveSuggestion());
if (!node_and_marker.first)
return;
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 f7906a27bbe..eab4b202994 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
@@ -13,7 +13,7 @@
#include "third_party/blink/renderer/core/editing/testing/editing_test_base.h"
#include "third_party/blink/renderer/core/editing/visible_selection.h"
-using ui::mojom::ImeTextSpanThickness;
+using ws::mojom::ImeTextSpanThickness;
namespace blink {
@@ -57,7 +57,7 @@ TEST_F(TextSuggestionControllerTest, ApplyTextSuggestion) {
"word1 word2 word3 word4"
"</div>");
Element* div = GetDocument().QuerySelector("div");
- Node* text = div->firstChild();
+ Text* text = ToText(div->firstChild());
// Add marker on "word1". This marker should *not* be cleared by the
// replace operation.
@@ -120,7 +120,7 @@ TEST_F(TextSuggestionControllerTest, ApplyTextSuggestion) {
// This returns the markers sorted by start offset; we need them sorted by
// start *and* end offset, since we have multiple markers starting at 0.
- DocumentMarkerVector markers = GetDocument().Markers().MarkersFor(text);
+ DocumentMarkerVector markers = GetDocument().Markers().MarkersFor(*text);
std::sort(markers.begin(), markers.end(),
[](const DocumentMarker* marker1, const DocumentMarker* marker2) {
if (marker1->StartOffset() != marker2->StartOffset())
@@ -169,7 +169,7 @@ TEST_F(TextSuggestionControllerTest,
"mispelled"
"</div>");
Element* div = GetDocument().QuerySelector("div");
- Node* text = div->firstChild();
+ Text* text = ToText(div->firstChild());
// Add marker on "mispelled". This marker should be cleared by the replace
// operation.
@@ -183,7 +183,7 @@ TEST_F(TextSuggestionControllerTest,
// Check the tag for the marker that was just added (the current tag value is
// not reset between test cases).
int32_t marker_tag =
- ToSuggestionMarker(GetDocument().Markers().MarkersFor(text)[0])->Tag();
+ ToSuggestionMarker(GetDocument().Markers().MarkersFor(*text)[0])->Tag();
// Select immediately before "mispelled".
GetDocument().GetFrame()->Selection().SetSelectionAndEndTyping(
@@ -195,7 +195,7 @@ TEST_F(TextSuggestionControllerTest,
GetDocument().GetFrame()->GetTextSuggestionController().ApplyTextSuggestion(
marker_tag, 0);
- EXPECT_EQ(0u, GetDocument().Markers().MarkersFor(text).size());
+ EXPECT_EQ(0u, GetDocument().Markers().MarkersFor(*text).size());
EXPECT_EQ("misspelled", text->textContent());
}
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 0e95a9a6bc9..6e7b50fd2bb 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
@@ -142,7 +142,7 @@ NSAttributedString* AttributedSubstringFromRange(const EphemeralRange& range,
WebPoint GetBaselinePoint(LocalFrameView* frame_view,
const EphemeralRange& range,
NSAttributedString* string) {
- IntRect string_rect = frame_view->FrameToViewport(ComputeTextRect(range));
+ IntRect string_rect = frame_view->FrameToViewport(FirstRectForRange(range));
IntPoint string_point = string_rect.MinXMaxYCorner();
// Adjust for the font's descender. AppKit wants the baseline point.
diff --git a/chromium/third_party/blink/renderer/core/events/BUILD.gn b/chromium/third_party/blink/renderer/core/events/BUILD.gn
index b1a771baa0a..a88f31af4cd 100644
--- a/chromium/third_party/blink/renderer/core/events/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/events/BUILD.gn
@@ -60,6 +60,7 @@ blink_core_sources("events") {
"progress_event.h",
"promise_rejection_event.cc",
"promise_rejection_event.h",
+ "registered_event_listener.cc",
"registered_event_listener.h",
"resource_progress_event.cc",
"resource_progress_event.h",
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 caaf3a21c89..ff1f40aaac3 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,8 @@
#include "third_party/blink/renderer/core/events/animation_event.h"
+#include "third_party/blink/renderer/core/event_names.h"
+
namespace blink {
AnimationEvent::AnimationEvent() : elapsed_time_(0.0) {}
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 bcfcc250c60..538e58dc3bd 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,6 +4,8 @@
#include "third_party/blink/renderer/core/events/animation_playback_event.h"
+#include "third_party/blink/renderer/core/event_names.h"
+
namespace blink {
AnimationPlaybackEvent::AnimationPlaybackEvent(const AtomicString& type,
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 0c78953ec88..4c64c2a489e 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
@@ -4,6 +4,8 @@
#include "third_party/blink/renderer/core/events/application_cache_error_event.h"
+#include "third_party/blink/renderer/core/event_type_names.h"
+
namespace blink {
static const String& ErrorReasonToString(
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 0acf1645bff..c293a8ed2e4 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
@@ -7,6 +7,7 @@
#include "third_party/blink/public/platform/web_application_cache_host_client.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
+#include "third_party/blink/renderer/core/event_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"
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 460379eff57..c08be5d5a57 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
@@ -25,6 +25,9 @@
#include "third_party/blink/renderer/core/events/before_text_inserted_event.h"
+#include "third_party/blink/renderer/core/event_names.h"
+#include "third_party/blink/renderer/core/event_type_names.h"
+
namespace blink {
BeforeTextInsertedEvent::BeforeTextInsertedEvent(const String& text)
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 76c99f83baa..f82a6a78bef 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
@@ -26,6 +26,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_BEFORE_UNLOAD_EVENT_H_
#include "third_party/blink/renderer/core/dom/events/event.h"
+#include "third_party/blink/renderer/core/event_names.h"
namespace blink {
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 0b5579c76f4..6d592f631d2 100644
--- a/chromium/third_party/blink/renderer/core/events/drag_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/drag_event.cc
@@ -7,6 +7,7 @@
#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"
+#include "third_party/blink/renderer/core/dom/events/event_path.h"
namespace blink {
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 52507abfb98..46fce0c0f05 100644
--- a/chromium/third_party/blink/renderer/core/events/error_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/error_event.cc
@@ -82,6 +82,10 @@ const AtomicString& ErrorEvent::InterfaceName() const {
return EventNames::ErrorEvent;
}
+bool ErrorEvent::CanBeDispatchedInWorld(const DOMWrapperWorld& world) const {
+ return !world_ || world_ == &world;
+}
+
ScriptValue ErrorEvent::error(ScriptState* script_state) const {
// Don't return |m_error| when we are in the different worlds to avoid
// leaking a V8 value.
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 a18243e50b6..e6a8d727ddf 100644
--- a/chromium/third_party/blink/renderer/core/events/error_event.h
+++ b/chromium/third_party/blink/renderer/core/events/error_event.h
@@ -88,6 +88,7 @@ class ErrorEvent final : public Event {
SourceLocation* Location() const { return location_.get(); }
const AtomicString& InterfaceName() const override;
+ bool CanBeDispatchedInWorld(const DOMWrapperWorld&) const override;
DOMWrapperWorld* World() const { return world_.get(); }
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 959a71466f7..fd4111499ae 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
@@ -24,7 +24,9 @@
"accessibleincrement",
"accessiblescrollintoview",
"activate",
+ "activateinvisible",
"active",
+ "activechange",
"addsourcebuffer",
"addstream",
"addtrack",
@@ -40,8 +42,8 @@
"availablechange",
"backgroundfetchabort",
"backgroundfetchclick",
- "backgroundfetched",
"backgroundfetchfail",
+ "backgroundfetchsuccess",
"beforecopy",
"beforecut",
"beforeinput",
@@ -124,6 +126,7 @@
"fullscreenerror",
"gamepadconnected",
"gamepaddisconnected",
+ "gatheringstatechange",
"gattserverdisconnected",
"geofenceenter",
"geofenceleave",
@@ -205,6 +208,7 @@
"pointermove",
"pointerout",
"pointerover",
+ "pointerrawmove",
"pointerup",
"popstate",
"progress",
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 536b99d0dde..68cb3aea7e0 100644
--- a/chromium/third_party/blink/renderer/core/events/focus_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/focus_event.cc
@@ -27,6 +27,7 @@
#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"
namespace blink {
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 7f8822bd06d..16e99ca01a6 100644
--- a/chromium/third_party/blink/renderer/core/events/keyboard_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/keyboard_event.cc
@@ -26,6 +26,8 @@
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_input_event.h"
#include "third_party/blink/renderer/core/editing/ime/input_method_controller.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/input/input_device_capabilities.h"
#include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
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 c098abda392..1d32bb8d3df 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/core/frame/user_activation.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/v8_private_property.h"
@@ -78,6 +79,8 @@ MessageEvent::MessageEvent(const AtomicString& type,
source_ = initializer.source();
if (initializer.hasPorts())
ports_ = new MessagePortArray(initializer.ports());
+ if (initializer.hasUserActivation())
+ user_activation_ = initializer.userActivation();
DCHECK(IsValidSource(source_.Get()));
}
@@ -98,7 +101,8 @@ MessageEvent::MessageEvent(scoped_refptr<SerializedScriptValue> data,
const String& origin,
const String& last_event_id,
EventTarget* source,
- MessagePortArray* ports)
+ MessagePortArray* ports,
+ UserActivation* user_activation)
: Event(EventTypeNames::message, Bubbles::kNo, Cancelable::kNo),
data_type_(kDataTypeSerializedScriptValue),
data_as_serialized_script_value_(
@@ -106,7 +110,8 @@ MessageEvent::MessageEvent(scoped_refptr<SerializedScriptValue> data,
origin_(origin),
last_event_id_(last_event_id),
source_(source),
- ports_(ports) {
+ ports_(ports),
+ user_activation_(user_activation) {
DCHECK(IsValidSource(source_.Get()));
}
@@ -114,7 +119,8 @@ MessageEvent::MessageEvent(scoped_refptr<SerializedScriptValue> data,
const String& origin,
const String& last_event_id,
EventTarget* source,
- Vector<MessagePortChannel> channels)
+ Vector<MessagePortChannel> channels,
+ UserActivation* user_activation)
: Event(EventTypeNames::message, Bubbles::kNo, Cancelable::kNo),
data_type_(kDataTypeSerializedScriptValue),
data_as_serialized_script_value_(
@@ -122,7 +128,16 @@ MessageEvent::MessageEvent(scoped_refptr<SerializedScriptValue> data,
origin_(origin),
last_event_id_(last_event_id),
source_(source),
- channels_(std::move(channels)) {
+ channels_(std::move(channels)),
+ user_activation_(user_activation) {
+ DCHECK(IsValidSource(source_.Get()));
+}
+
+MessageEvent::MessageEvent(const String& origin, EventTarget* source)
+ : Event(EventTypeNames::messageerror, Bubbles::kNo, Cancelable::kNo),
+ data_type_(kDataTypeNull),
+ origin_(origin),
+ source_(source) {
DCHECK(IsValidSource(source_.Get()));
}
@@ -186,7 +201,8 @@ void MessageEvent::initMessageEvent(const AtomicString& type,
const String& origin,
const String& last_event_id,
EventTarget* source,
- MessagePortArray* ports) {
+ MessagePortArray* ports,
+ UserActivation* user_activation) {
if (IsBeingDispatched())
return;
@@ -200,6 +216,7 @@ void MessageEvent::initMessageEvent(const AtomicString& type,
source_ = source;
ports_ = ports;
is_ports_dirty_ = true;
+ user_activation_ = user_activation;
}
void MessageEvent::initMessageEvent(const AtomicString& type,
@@ -248,6 +265,7 @@ void MessageEvent::Trace(blink::Visitor* visitor) {
visitor->Trace(data_as_array_buffer_);
visitor->Trace(source_);
visitor->Trace(ports_);
+ visitor->Trace(user_activation_);
Event::Trace(visitor);
}
@@ -261,6 +279,7 @@ v8::Local<v8::Object> MessageEvent::AssociateWithWrapper(
// how much memory is used via the wrapper. To keep the wrapper alive, it's
// set to the wrapper of the MessageEvent as a private value.
switch (GetDataType()) {
+ case MessageEvent::kDataTypeNull:
case MessageEvent::kDataTypeScriptValue:
case MessageEvent::kDataTypeSerializedScriptValue:
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 8020a910fb3..12fbe776d60 100644
--- a/chromium/third_party/blink/renderer/core/events/message_event.h
+++ b/chromium/third_party/blink/renderer/core/events/message_event.h
@@ -43,6 +43,8 @@
namespace blink {
+class UserActivation;
+
class CORE_EXPORT MessageEvent final : public Event {
DEFINE_WRAPPERTYPEINFO();
@@ -60,15 +62,26 @@ class CORE_EXPORT MessageEvent final : public Event {
const String& last_event_id = String(),
EventTarget* source = nullptr) {
return new MessageEvent(std::move(data), origin, last_event_id, source,
- ports);
+ ports, nullptr);
+ }
+ static MessageEvent* Create(MessagePortArray* ports,
+ scoped_refptr<SerializedScriptValue> data,
+ UserActivation* user_activation) {
+ return new MessageEvent(std::move(data), String(), String(), nullptr, ports,
+ user_activation);
}
static MessageEvent* Create(Vector<MessagePortChannel> channels,
scoped_refptr<SerializedScriptValue> data,
const String& origin = String(),
const String& last_event_id = String(),
- EventTarget* source = nullptr) {
+ EventTarget* source = nullptr,
+ UserActivation* user_activation = nullptr) {
return new MessageEvent(std::move(data), origin, last_event_id, source,
- std::move(channels));
+ std::move(channels), user_activation);
+ }
+ static MessageEvent* CreateError(const String& origin = String(),
+ EventTarget* source = nullptr) {
+ return new MessageEvent(origin, source);
}
static MessageEvent* Create(const String& data,
const String& origin = String()) {
@@ -101,7 +114,8 @@ class CORE_EXPORT MessageEvent final : public Event {
const String& origin,
const String& last_event_id,
EventTarget* source,
- MessagePortArray*);
+ MessagePortArray*,
+ UserActivation* user_activation);
void initMessageEvent(const AtomicString& type,
bool bubbles,
bool cancelable,
@@ -116,12 +130,14 @@ class CORE_EXPORT MessageEvent final : public Event {
EventTarget* source() const { return source_.Get(); }
MessagePortArray ports();
bool isPortsDirty() const { return is_ports_dirty_; }
+ UserActivation* userActivation() const { return user_activation_; }
Vector<MessagePortChannel> ReleaseChannels() { return std::move(channels_); }
const AtomicString& InterfaceName() const override;
enum DataType {
+ kDataTypeNull, // For "messageerror" events.
kDataTypeScriptValue,
kDataTypeSerializedScriptValue,
kDataTypeString,
@@ -191,12 +207,17 @@ class CORE_EXPORT MessageEvent final : public Event {
const String& origin,
const String& last_event_id,
EventTarget* source,
- MessagePortArray*);
+ MessagePortArray*,
+ UserActivation* user_activation);
MessageEvent(scoped_refptr<SerializedScriptValue> data,
const String& origin,
const String& last_event_id,
EventTarget* source,
- Vector<MessagePortChannel>);
+ Vector<MessagePortChannel>,
+ UserActivation* user_activation);
+
+ // Creates a "messageerror" event.
+ MessageEvent(const String& origin, EventTarget* source);
MessageEvent(const String& data, const String& origin);
MessageEvent(Blob* data, const String& origin);
@@ -217,6 +238,7 @@ class CORE_EXPORT MessageEvent final : public Event {
Member<MessagePortArray> ports_;
bool is_ports_dirty_ = true;
Vector<MessagePortChannel> channels_;
+ Member<UserActivation> user_activation_;
};
} // namespace blink
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 c84bba5e4e1..317eda18574 100644
--- a/chromium/third_party/blink/renderer/core/events/message_event.idl
+++ b/chromium/third_party/blink/renderer/core/events/message_event.idl
@@ -38,6 +38,7 @@
// TODO(bashi): |source| should be (WindowProxy or MessagePort)?
readonly attribute EventTarget? source;
[CachedAttribute=isPortsDirty] readonly attribute FrozenArray<MessagePort> ports;
+ [RuntimeEnabled=UserActivationAPI] readonly attribute UserActivation? userActivation;
// TODO(foolip): none of the arguments should have [Default=Undefined] (they
// have other default values in the spec) and |sourceArg|'s type is wrong.
diff --git a/chromium/third_party/blink/renderer/core/events/message_event_init.idl b/chromium/third_party/blink/renderer/core/events/message_event_init.idl
index bab4872accb..d874b15b1ee 100644
--- a/chromium/third_party/blink/renderer/core/events/message_event_init.idl
+++ b/chromium/third_party/blink/renderer/core/events/message_event_init.idl
@@ -11,4 +11,5 @@ dictionary MessageEventInit : EventInit {
// TODO(bashi): |source| should be (WindowProxy or MessagePort)?
EventTarget? source;
sequence<MessagePort> ports = [];
+ [RuntimeEnabled=UserActivationAPI] UserActivation? userActivation = null;
};
diff --git a/chromium/third_party/blink/renderer/core/events/mouse_event.cc b/chromium/third_party/blink/renderer/core/events/mouse_event.cc
index a4ab1280f78..9317e211320 100644
--- a/chromium/third_party/blink/renderer/core/events/mouse_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/mouse_event.cc
@@ -25,6 +25,7 @@
#include "third_party/blink/public/platform/web_pointer_properties.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_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
@@ -173,7 +174,6 @@ MouseEvent* MouseEvent::Create(const AtomicString& event_type,
MouseEvent::MouseEvent()
: position_type_(PositionType::kPosition),
- has_cached_relative_position_(false),
button_(0),
buttons_(0),
related_target_(nullptr),
@@ -427,17 +427,17 @@ DispatchEventResult MouseEvent::DispatchEvent(EventDispatcher& dispatcher) {
// event. This is not part of the DOM specs, but is used for compatibility
// with the ondblclick="" attribute. This is treated as a separate event in
// other DOM-compliant browsers like Firefox, and so we do the same.
- MouseEvent* double_click_event = MouseEvent::Create();
- double_click_event->InitMouseEventInternal(
+ MouseEvent& double_click_event = *MouseEvent::Create();
+ double_click_event.InitMouseEventInternal(
EventTypeNames::dblclick, bubbles(), cancelable(), view(), detail(),
screenX(), screenY(), clientX(), clientY(), GetModifiers(), button(),
related_target, sourceCapabilities(), buttons());
- double_click_event->SetComposed(composed());
+ double_click_event.SetComposed(composed());
// Inherit the trusted status from the original event.
- double_click_event->SetTrusted(isTrusted());
+ double_click_event.SetTrusted(isTrusted());
if (DefaultHandled())
- double_click_event->SetDefaultHandled();
+ double_click_event.SetDefaultHandled();
DispatchEventResult double_click_dispatch_result =
EventDispatcher::DispatchEvent(dispatcher.GetNode(), double_click_event);
if (double_click_dispatch_result != DispatchEventResult::kNotCanceled)
@@ -508,9 +508,9 @@ void MouseEvent::ComputeRelativePosition() {
if (LocalFrameView* view = n->GetLayoutObject()->View()->GetFrameView())
layer_location_ = view->DocumentToFrame(scaled_page_location);
- // FIXME: This logic is a wrong implementation of convertToLayerCoords.
+ // FIXME: Does this differ from PaintLayer::ConvertToLayerCoords?
for (PaintLayer* layer = n->GetLayoutObject()->EnclosingLayer(); layer;
- layer = layer->Parent()) {
+ layer = layer->ContainingLayer()) {
layer_location_ -= DoubleSize(layer->Location().X().ToDouble(),
layer->Location().Y().ToDouble());
}
@@ -527,6 +527,7 @@ int MouseEvent::layerX() {
// TODO(mustaq): Remove the PointerEvent specific code when mouse has
// fractional coordinates. See crbug.com/655786.
+
return IsPointerEvent() ? layer_location_.X()
: static_cast<int>(layer_location_.X());
}
@@ -537,24 +538,29 @@ int MouseEvent::layerY() {
// TODO(mustaq): Remove the PointerEvent specific code when mouse has
// fractional coordinates. See crbug.com/655786.
+
return IsPointerEvent() ? layer_location_.Y()
: static_cast<int>(layer_location_.Y());
}
-int MouseEvent::offsetX() {
+double MouseEvent::offsetX() {
if (!HasPosition())
return 0;
if (!has_cached_relative_position_)
ComputeRelativePosition();
- return std::round(offset_location_.X());
+ return (RuntimeEnabledFeatures::FractionalMouseEventEnabled())
+ ? offset_location_.X()
+ : std::round(offset_location_.X());
}
-int MouseEvent::offsetY() {
+double MouseEvent::offsetY() {
if (!HasPosition())
return 0;
if (!has_cached_relative_position_)
ComputeRelativePosition();
- return std::round(offset_location_.Y());
+ return (RuntimeEnabledFeatures::FractionalMouseEventEnabled())
+ ? offset_location_.Y()
+ : 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 2609d5657ee..01753e47145 100644
--- a/chromium/third_party/blink/renderer/core/events/mouse_event.h
+++ b/chromium/third_party/blink/renderer/core/events/mouse_event.h
@@ -26,8 +26,11 @@
#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/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"
namespace blink {
class DataTransfer;
@@ -159,8 +162,8 @@ class CORE_EXPORT MouseEvent : public UIEventWithKeyState {
int layerX();
int layerY();
- int offsetX();
- int offsetY();
+ virtual double offsetX();
+ virtual double offsetY();
virtual double pageX() const {
return (RuntimeEnabledFeatures::FractionalMouseEventEnabled())
@@ -206,11 +209,16 @@ class CORE_EXPORT MouseEvent : public UIEventWithKeyState {
void ReceivedTarget() override;
- // TODO(eirage): Move these coordinates back to private when MouseEvent
- // fractional flag is removed.
+ // 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:
void InitMouseEventInternal(const AtomicString& type,
@@ -231,15 +239,12 @@ class CORE_EXPORT MouseEvent : public UIEventWithKeyState {
void InitCoordinates(const double client_x, const double client_y);
void ComputePageLocation();
- void ComputeRelativePosition();
DoublePoint movement_delta_;
DoublePoint layer_location_; // zoomed CSS pixels
- DoublePoint offset_location_; // zoomed CSS pixels
DoublePoint absolute_location_; // (un-zoomed) FrameView content space
PositionType position_type_;
- bool has_cached_relative_position_;
short button_;
unsigned short buttons_;
Member<EventTarget> related_target_;
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 79fbfc264e4..aa691287186 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,8 @@
#include "third_party/blink/renderer/core/events/page_transition_event.h"
+#include "third_party/blink/renderer/core/event_names.h"
+
namespace blink {
PageTransitionEvent::PageTransitionEvent() : persisted_(false) {}
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 171f5115ace..116c06af9ef 100644
--- a/chromium/third_party/blink/renderer/core/events/pointer_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/pointer_event.cc
@@ -6,6 +6,7 @@
#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"
namespace blink {
@@ -99,6 +100,28 @@ double PointerEvent::pageY() const {
: page_location_.Y();
}
+double PointerEvent::offsetX() {
+ if (!HasPosition())
+ return 0;
+ if (!has_cached_relative_position_)
+ ComputeRelativePosition();
+ return (!RuntimeEnabledFeatures::FractionalMouseTypePointerEventEnabled() &&
+ pointer_type_ == "mouse")
+ ? std::round(offset_location_.X())
+ : offset_location_.X();
+}
+
+double PointerEvent::offsetY() {
+ if (!HasPosition())
+ return 0;
+ if (!has_cached_relative_position_)
+ ComputeRelativePosition();
+ return (!RuntimeEnabledFeatures::FractionalMouseTypePointerEventEnabled() &&
+ pointer_type_ == "mouse")
+ ? std::round(offset_location_.Y())
+ : offset_location_.Y();
+}
+
void PointerEvent::ReceivedTarget() {
coalesced_events_targets_dirty_ = true;
MouseEvent::ReceivedTarget();
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 1e3ea058482..cdc4d8d8751 100644
--- a/chromium/third_party/blink/renderer/core/events/pointer_event.h
+++ b/chromium/third_party/blink/renderer/core/events/pointer_event.h
@@ -48,6 +48,9 @@ class CORE_EXPORT PointerEvent final : public MouseEvent {
double pageX() const override;
double pageY() const override;
+ double offsetX() override;
+ double offsetY() override;
+
void ReceivedTarget() override;
// Always return null for fromElement and toElement because these fields
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 f3e68551981..77839b72ca2 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,7 @@
#include "third_party/blink/renderer/core/events/pointer_event_factory.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/platform/geometry/float_size.h"
@@ -62,6 +63,8 @@ const AtomicString& PointerEventNameForEventType(WebInputEvent::Type type) {
return EventTypeNames::pointerup;
case WebInputEvent::kPointerMove:
return EventTypeNames::pointermove;
+ case WebInputEvent::kPointerRawMove:
+ return EventTypeNames::pointerrawmove;
case WebInputEvent::kPointerCancel:
return EventTypeNames::pointercancel;
default:
@@ -170,6 +173,7 @@ void PointerEventFactory::SetEventSpecificFields(
pointer_event_init.setCancelable(type != EventTypeNames::pointerenter &&
type != EventTypeNames::pointerleave &&
type != EventTypeNames::pointercancel &&
+ type != EventTypeNames::pointerrawmove &&
type != EventTypeNames::gotpointercapture &&
type != EventTypeNames::lostpointercapture);
@@ -185,6 +189,7 @@ PointerEvent* PointerEventFactory::Create(
DCHECK(event_type == WebInputEvent::kPointerDown ||
event_type == WebInputEvent::kPointerUp ||
event_type == WebInputEvent::kPointerMove ||
+ event_type == WebInputEvent::kPointerRawMove ||
event_type == WebInputEvent::kPointerCancel);
PointerEventInit pointer_event_init;
@@ -223,7 +228,8 @@ PointerEvent* PointerEventFactory::Create(
SetEventSpecificFields(pointer_event_init, type);
- if (type == EventTypeNames::pointermove) {
+ if (type == EventTypeNames::pointermove ||
+ type == EventTypeNames::pointerrawmove) {
HeapVector<Member<PointerEvent>> coalesced_pointer_events;
for (const auto& coalesced_event : coalesced_events) {
DCHECK_EQ(web_pointer_event.id, coalesced_event.id);
@@ -307,6 +313,21 @@ PointerEvent* PointerEventFactory::CreatePointerEventFrom(
pointer_event->PlatformTimeStamp());
}
+PointerEvent* PointerEventFactory::CreatePointerRawMoveEvent(
+ PointerEvent* pointer_event) {
+ // This function is for creating pointerrawmove event from a pointerdown/up
+ // event that caused by chorded buttons and hence its type is changed to
+ // pointermove.
+ DCHECK(pointer_event->type() == EventTypeNames::pointermove &&
+ (pointer_event->buttons() &
+ ~ButtonToButtonsBitfield(static_cast<WebPointerProperties::Button>(
+ pointer_event->button()))) != 0 &&
+ pointer_event->button() != 0);
+
+ return CreatePointerEventFrom(pointer_event, EventTypeNames::pointerrawmove,
+ pointer_event->relatedTarget());
+}
+
PointerEvent* PointerEventFactory::CreatePointerCaptureEvent(
PointerEvent* pointer_event,
const AtomicString& type) {
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 c84481caf3d..b2826fa992f 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
@@ -38,10 +38,13 @@ class CORE_EXPORT PointerEventFactory {
const int pointer_id,
TimeTicks platfrom_time_stamp);
- // For creating capture events (i.e got/lostpointercapture)
+ // For creating raw move events in chorded button case.
+ PointerEvent* CreatePointerRawMoveEvent(PointerEvent*);
+
+ // For creating capture events (i.e got/lostpointercapture).
PointerEvent* CreatePointerCaptureEvent(PointerEvent*, const AtomicString&);
- // For creating boundary events (i.e pointerout/leave/over/enter)
+ // For creating boundary events (i.e pointerout/leave/over/enter).
PointerEvent* CreatePointerBoundaryEvent(PointerEvent*,
const AtomicString&,
EventTarget*);
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 ceb416a9e57..60806ea27ef 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
@@ -27,6 +27,8 @@
#include "third_party/blink/renderer/core/events/pop_state_event.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
+#include "third_party/blink/renderer/core/event_names.h"
+#include "third_party/blink/renderer/core/event_type_names.h"
#include "third_party/blink/renderer/core/frame/history.h"
namespace blink {
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 9e0b9b044e5..ea992bc9416 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,8 @@
#include "third_party/blink/renderer/core/events/progress_event.h"
+#include "third_party/blink/renderer/core/event_names.h"
+
namespace blink {
ProgressEvent::ProgressEvent()
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 885728339a5..90fed2e1c2b 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/core/event_names.h"
#include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/core/events/registered_event_listener.cc b/chromium/third_party/blink/renderer/core/events/registered_event_listener.cc
new file mode 100644
index 00000000000..996205306dd
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/events/registered_event_listener.cc
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2001 Tobias Anton (anton@stud.fbi.fh-darmstadt.de)
+ * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 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.
+ *
+ */
+
+#include "third_party/blink/renderer/core/events/registered_event_listener.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"
+
+namespace blink {
+
+RegisteredEventListener::RegisteredEventListener()
+ : use_capture_(false),
+ passive_(false),
+ once_(false),
+ blocked_event_warning_emitted_(false),
+ passive_forced_for_document_target_(false),
+ passive_specified_(false) {}
+
+RegisteredEventListener::RegisteredEventListener(
+ EventListener* listener,
+ const AddEventListenerOptionsResolved& options)
+ : callback_(listener),
+ use_capture_(options.capture()),
+ passive_(options.passive()),
+ once_(options.once()),
+ blocked_event_warning_emitted_(false),
+ passive_forced_for_document_target_(
+ options.PassiveForcedForDocumentTarget()),
+ passive_specified_(options.PassiveSpecified()) {}
+
+RegisteredEventListener& RegisteredEventListener::operator=(
+ const RegisteredEventListener& that) = default;
+
+void RegisteredEventListener::Trace(Visitor* visitor) {
+ visitor->Trace(callback_);
+}
+
+AddEventListenerOptionsResolved RegisteredEventListener::Options() const {
+ AddEventListenerOptionsResolved result;
+ result.setCapture(use_capture_);
+ result.setPassive(passive_);
+ result.SetPassiveForcedForDocumentTarget(passive_forced_for_document_target_);
+ result.setOnce(once_);
+ result.SetPassiveSpecified(passive_specified_);
+ return result;
+}
+
+void RegisteredEventListener::SetCallback(EventListener* listener) {
+ callback_ = listener;
+}
+
+bool RegisteredEventListener::Matches(
+ const EventListener* listener,
+ const EventListenerOptions& options) const {
+ // Equality is soley based on the listener and useCapture flags.
+ DCHECK(callback_);
+ DCHECK(listener);
+ return *callback_ == *listener &&
+ static_cast<bool>(use_capture_) == options.capture();
+}
+
+bool RegisteredEventListener::operator==(
+ const RegisteredEventListener& other) const {
+ // Equality is soley based on the listener and useCapture flags.
+ DCHECK(callback_);
+ DCHECK(other.callback_);
+ return *callback_ == *other.callback_ && use_capture_ == other.use_capture_;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/events/registered_event_listener.h b/chromium/third_party/blink/renderer/core/events/registered_event_listener.h
index c2b0157bd17..7e9c4c84c2f 100644
--- a/chromium/third_party/blink/renderer/core/events/registered_event_listener.h
+++ b/chromium/third_party/blink/renderer/core/events/registered_event_listener.h
@@ -26,53 +26,34 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_REGISTERED_EVENT_LISTENER_H_
#include "base/memory/scoped_refptr.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/platform/bindings/trace_wrapper_member.h"
namespace blink {
+class AddEventListenerOptionsResolved;
+class EventListener;
+class EventListenerOptions;
+
+// RegisteredEventListener represents 'event listener' defined in the DOM
+// standard. https://dom.spec.whatwg.org/#concept-event-listener
class RegisteredEventListener final {
DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
public:
- RegisteredEventListener()
- : use_capture_(false),
- passive_(false),
- once_(false),
- blocked_event_warning_emitted_(false),
- passive_forced_for_document_target_(false),
- passive_specified_(false) {}
-
+ RegisteredEventListener();
RegisteredEventListener(EventListener* listener,
- const AddEventListenerOptionsResolved& options)
- : callback_(listener),
- use_capture_(options.capture()),
- passive_(options.passive()),
- once_(options.once()),
- blocked_event_warning_emitted_(false),
- passive_forced_for_document_target_(
- options.PassiveForcedForDocumentTarget()),
- passive_specified_(options.PassiveSpecified()) {}
-
- void Trace(blink::Visitor* visitor) { visitor->Trace(callback_); }
-
- AddEventListenerOptionsResolved Options() const {
- AddEventListenerOptionsResolved result;
- result.setCapture(use_capture_);
- result.setPassive(passive_);
- result.SetPassiveForcedForDocumentTarget(
- passive_forced_for_document_target_);
- result.setOnce(once_);
- result.SetPassiveSpecified(passive_specified_);
- return result;
- }
+ const AddEventListenerOptionsResolved& options);
+ RegisteredEventListener& operator=(const RegisteredEventListener& that);
+
+ void Trace(Visitor* visitor);
+
+ AddEventListenerOptionsResolved Options() const;
const EventListener* Callback() const { return callback_; }
EventListener* Callback() { return callback_; }
- void SetCallback(EventListener* listener) { callback_ = listener; }
+ void SetCallback(EventListener* listener);
bool Passive() const { return passive_; }
@@ -95,20 +76,9 @@ class RegisteredEventListener final {
}
bool Matches(const EventListener* listener,
- const EventListenerOptions& options) const {
- // Equality is soley based on the listener and useCapture flags.
- DCHECK(callback_);
- DCHECK(listener);
- return *callback_ == *listener &&
- static_cast<bool>(use_capture_) == options.capture();
- }
+ const EventListenerOptions& options) const;
- bool operator==(const RegisteredEventListener& other) const {
- // Equality is soley based on the listener and useCapture flags.
- DCHECK(callback_);
- DCHECK(other.callback_);
- return *callback_ == *other.callback_ && use_capture_ == other.use_capture_;
- }
+ bool operator==(const RegisteredEventListener& other) const;
private:
TraceWrapperMember<EventListener> callback_;
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 21725edfba8..09130862539 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
@@ -26,6 +26,8 @@
#include "third_party/blink/renderer/core/events/resource_progress_event.h"
+#include "third_party/blink/renderer/core/event_names.h"
+
namespace blink {
ResourceProgressEvent::ResourceProgressEvent(const AtomicString& type,
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 92313893bcc..6b9f32d62ce 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
@@ -27,6 +27,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_SECURITY_POLICY_VIOLATION_EVENT_H_
#include "third_party/blink/renderer/core/dom/events/event.h"
+#include "third_party/blink/renderer/core/event_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"
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 4cc304c7fa5..f9a44143ef2 100644
--- a/chromium/third_party/blink/renderer/core/events/touch_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/touch_event.cc
@@ -28,6 +28,7 @@
#include "third_party/blink/public/platform/web_coalesced_input_event.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/frame_console.h"
#include "third_party/blink/renderer/core/frame/intervention.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
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 c7e9b86989f..652db736442 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
@@ -8,6 +8,7 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.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/use_counter.h"
#include "third_party/blink/renderer/core/loader/empty_clients.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
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 47dd89d9ffe..a8fedb14598 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,8 @@
#include "third_party/blink/renderer/core/events/transition_event.h"
+#include "third_party/blink/renderer/core/event_names.h"
+
namespace blink {
TransitionEvent::TransitionEvent() : elapsed_time_(0) {}
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 798939f7696..e8dd2c98d58 100644
--- a/chromium/third_party/blink/renderer/core/events/ui_event.h
+++ b/chromium/third_party/blink/renderer/core/events/ui_event.h
@@ -95,6 +95,8 @@ class CORE_EXPORT UIEvent : public Event {
Member<InputDeviceCapabilities> source_capabilities_;
};
+DEFINE_EVENT_TYPE_CASTS(UIEvent);
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_UI_EVENT_H_
diff --git a/chromium/third_party/blink/renderer/core/events/visual_viewport_resize_event.cc b/chromium/third_party/blink/renderer/core/events/visual_viewport_resize_event.cc
index 6e9208726af..38aa8e7bb37 100644
--- a/chromium/third_party/blink/renderer/core/events/visual_viewport_resize_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/visual_viewport_resize_event.cc
@@ -4,6 +4,8 @@
#include "third_party/blink/renderer/core/events/visual_viewport_resize_event.h"
+#include "third_party/blink/renderer/core/dom/events/event_target.h"
+#include "third_party/blink/renderer/core/event_type_names.h"
#include "third_party/blink/renderer/core/frame/use_counter.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/core/events/visual_viewport_scroll_event.cc b/chromium/third_party/blink/renderer/core/events/visual_viewport_scroll_event.cc
index 51832e86e70..0eeac6890a6 100644
--- a/chromium/third_party/blink/renderer/core/events/visual_viewport_scroll_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/visual_viewport_scroll_event.cc
@@ -4,6 +4,8 @@
#include "third_party/blink/renderer/core/events/visual_viewport_scroll_event.h"
+#include "third_party/blink/renderer/core/dom/events/event_target.h"
+#include "third_party/blink/renderer/core/event_type_names.h"
#include "third_party/blink/renderer/core/frame/use_counter.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/core/events/wheel_event.cc b/chromium/third_party/blink/renderer/core/events/wheel_event.cc
index b1f9fcaebef..c8c64c6ebc0 100644
--- a/chromium/third_party/blink/renderer/core/events/wheel_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/wheel_event.cc
@@ -24,6 +24,9 @@
#include "third_party/blink/renderer/core/events/wheel_event.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/frame/local_dom_window.h"
+#include "third_party/blink/renderer/core/frame/use_counter.h"
namespace blink {
@@ -115,6 +118,23 @@ bool WheelEvent::IsWheelEvent() const {
return true;
}
+void WheelEvent::preventDefault() {
+ MouseEvent::preventDefault();
+
+ if (!currentTarget() || !currentTarget()->IsTopLevelNode())
+ return;
+
+ PassiveMode passive_mode = HandlingPassive();
+ if (passive_mode == PassiveMode::kPassiveForcedDocumentLevel ||
+ passive_mode == PassiveMode::kNotPassiveDefault) {
+ if (ExecutionContext* context = currentTarget()->GetExecutionContext()) {
+ UseCounter::Count(
+ context,
+ WebFeature::kDocumentLevelPassiveDefaultEventListenerPreventedWheel);
+ }
+ }
+}
+
DispatchEventResult WheelEvent::DispatchEvent(EventDispatcher& dispatcher) {
return dispatcher.Dispatch();
}
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 5b5ae33de9b..2a7b4416ff6 100644
--- a/chromium/third_party/blink/renderer/core/events/wheel_event.h
+++ b/chromium/third_party/blink/renderer/core/events/wheel_event.h
@@ -70,6 +70,8 @@ class CORE_EXPORT WheelEvent final : public MouseEvent {
bool IsMouseEvent() const override;
bool IsWheelEvent() const override;
+ void preventDefault() override;
+
const WebMouseWheelEvent& NativeEvent() const { return native_event_; }
// WheelEvent doesn't modify the event path, but its parent MouseEvent does.
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 34fda803b0c..b5eec8aeb32 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
@@ -152,7 +152,7 @@ bool ExecutionContext::DispatchErrorEventInternal(
DCHECK(!in_dispatch_error_event_);
in_dispatch_error_event_ = true;
- target->DispatchEvent(error_event);
+ target->DispatchEvent(*error_event);
in_dispatch_error_event_ = false;
return error_event->defaultPrevented();
}
@@ -259,4 +259,14 @@ void ExecutionContext::Trace(blink::Visitor* visitor) {
Supplementable<ExecutionContext>::Trace(visitor);
}
+bool ExecutionContext::IsSameAgentCluster(
+ const base::UnguessableToken& other_id) const {
+ base::UnguessableToken this_id = GetAgentClusterID();
+ // If the AgentClusterID is empty then it should never be the same (e.g.
+ // currently for worklets).
+ if (this_id.is_empty() || other_id.is_empty())
+ return false;
+ return this_id == other_id;
+}
+
} // 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 8c0d54536d0..97d4c1ec41c 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
@@ -32,11 +32,13 @@
#include "base/location.h"
#include "base/macros.h"
+#include "base/unguessable_token.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/context_lifecycle_notifier.h"
#include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/loader/fetch/access_control_status.h"
+#include "third_party/blink/renderer/platform/loader/fetch/https_state.h"
#include "third_party/blink/renderer/platform/supplementable.h"
#include "third_party/blink/renderer/platform/weborigin/referrer_policy.h"
#include "v8/include/v8.h"
@@ -143,6 +145,8 @@ class CORE_EXPORT ExecutionContext : public ContextLifecycleNotifier,
virtual LocalDOMWindow* ExecutingWindow() const { return nullptr; }
virtual String UserAgent() const = 0;
+ virtual HttpsState GetHttpsState() const = 0;
+
// Gets the DOMTimerCoordinator which maintains the "active timer
// list" of tasks created by setTimeout and setInterval. The
// DOMTimerCoordinator is owned by the ExecutionContext and should
@@ -153,6 +157,11 @@ class CORE_EXPORT ExecutionContext : public ContextLifecycleNotifier,
virtual SecurityContext& GetSecurityContext() = 0;
+ // https://tc39.github.io/ecma262/#sec-agent-clusters
+ virtual const base::UnguessableToken& GetAgentClusterID() const = 0;
+
+ bool IsSameAgentCluster(const base::UnguessableToken&) const;
+
virtual bool CanExecuteScripts(ReasonForCallingCanExecuteScripts) {
return false;
}
diff --git a/chromium/third_party/blink/renderer/core/exported/BUILD.gn b/chromium/third_party/blink/renderer/core/exported/BUILD.gn
index 2e6006a9738..6b0519caa53 100644
--- a/chromium/third_party/blink/renderer/core/exported/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/exported/BUILD.gn
@@ -28,8 +28,6 @@ blink_core_sources("exported") {
"web_dom_message_event.cc",
"web_element.cc",
"web_element_collection.cc",
- "web_file_chooser_completion_impl.cc",
- "web_file_chooser_completion_impl.h",
"web_form_control_element.cc",
"web_form_element.cc",
"web_form_element_observer_impl.cc",
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 4cea1fbf477..0fb56249274 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
@@ -53,6 +53,7 @@
#include "third_party/blink/public/web/web_dom_event.h"
#include "third_party/blink/public/web/web_form_element.h"
#include "third_party/blink/public/web/web_local_frame_client.h"
+#include "third_party/blink/public/web/web_navigation_params.h"
#include "third_party/blink/public/web/web_node.h"
#include "third_party/blink/public/web/web_plugin.h"
#include "third_party/blink/public/web/web_plugin_params.h"
@@ -157,6 +158,29 @@ void ResetWheelAndTouchEventHandlerProperties(LocalFrame& frame) {
cc::EventListenerProperties::kNone);
}
+void SetupDocumentLoader(
+ DocumentLoader* document_loader,
+ std::unique_ptr<WebNavigationParams> navigation_params) {
+ if (!navigation_params) {
+ document_loader->GetTiming().SetNavigationStart(CurrentTimeTicks());
+ return;
+ }
+
+ const WebNavigationTimings& navigation_timings =
+ navigation_params->navigation_timings;
+ document_loader->UpdateNavigationTimings(
+ navigation_timings.navigation_start, navigation_timings.redirect_start,
+ navigation_timings.redirect_end, navigation_timings.fetch_start,
+ navigation_timings.input_start);
+
+ document_loader->SetSourceLocation(navigation_params->source_location);
+ if (navigation_params->is_user_activated)
+ document_loader->SetUserActivated();
+
+ document_loader->SetServiceWorkerNetworkProvider(
+ std::move(navigation_params->service_worker_network_provider));
+}
+
} // namespace
LocalFrameClientImpl::LocalFrameClientImpl(WebLocalFrameImpl* frame)
@@ -501,7 +525,8 @@ NavigationPolicy LocalFrameClientImpl::DecidePolicyForNavigation(
HTMLFormElement* form,
ContentSecurityPolicyDisposition
should_check_main_world_content_security_policy,
- mojom::blink::BlobURLTokenPtr blob_url_token) {
+ mojom::blink::BlobURLTokenPtr blob_url_token,
+ base::TimeTicks input_start_time) {
if (!web_frame_->Client())
return kNavigationPolicyIgnore;
@@ -513,8 +538,8 @@ NavigationPolicy LocalFrameClientImpl::DecidePolicyForNavigation(
wrapped_resource_request);
navigation_info.navigation_type = type;
navigation_info.default_policy = static_cast<WebNavigationPolicy>(policy);
- navigation_info.extra_data =
- web_document_loader ? web_document_loader->GetExtraData() : nullptr;
+ // TODO(dgozman): remove this after some Canary coverage.
+ CHECK(!web_document_loader || !web_document_loader->GetExtraData());
navigation_info.replaces_current_history_item = replaces_current_history_item;
navigation_info.is_client_redirect = is_client_redirect;
navigation_info.triggering_event_info = triggering_event_info;
@@ -524,6 +549,7 @@ NavigationPolicy LocalFrameClientImpl::DecidePolicyForNavigation(
? kWebContentSecurityPolicyDispositionCheck
: kWebContentSecurityPolicyDispositionDoNotCheck;
navigation_info.blob_url_token = blob_url_token.PassInterface().PassHandle();
+ navigation_info.input_start = input_start_time;
// Can be null.
LocalFrame* local_parent_frame = GetLocalParentFrame(web_frame_);
@@ -741,16 +767,14 @@ DocumentLoader* LocalFrameClientImpl::CreateDocumentLoader(
const SubstituteData& data,
ClientRedirectPolicy client_redirect_policy,
const base::UnguessableToken& devtools_navigation_token,
- std::unique_ptr<WebDocumentLoader::ExtraData> extra_data,
- const WebNavigationTimings& navigation_timings) {
+ std::unique_ptr<WebNavigationParams> navigation_params,
+ std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) {
DCHECK(frame);
WebDocumentLoaderImpl* document_loader = WebDocumentLoaderImpl::Create(
frame, request, data, client_redirect_policy, devtools_navigation_token);
+ SetupDocumentLoader(document_loader, std::move(navigation_params));
document_loader->SetExtraData(std::move(extra_data));
- document_loader->UpdateNavigationTimings(
- navigation_timings.navigation_start, navigation_timings.redirect_start,
- navigation_timings.redirect_end, navigation_timings.fetch_start);
if (web_frame_->Client())
web_frame_->Client()->DidCreateDocumentLoader(document_loader);
return document_loader;
@@ -1114,6 +1138,14 @@ void LocalFrameClientImpl::FrameRectsChanged(const IntRect& frame_rect) {
web_frame_->Client()->FrameRectsChanged(frame_rect);
}
+bool LocalFrameClientImpl::IsPluginHandledExternally(
+ HTMLPlugInElement& plugin_element,
+ const KURL& resource_url,
+ const String& suggesed_mime_type) {
+ return web_frame_->Client()->IsPluginHandledExternally(
+ &plugin_element, resource_url, suggesed_mime_type);
+}
+
std::unique_ptr<WebWorkerFetchContext>
LocalFrameClientImpl::CreateWorkerFetchContext() {
DCHECK(web_frame_->Client());
@@ -1130,6 +1162,10 @@ void LocalFrameClientImpl::SetMouseCapture(bool capture) {
web_frame_->Client()->SetMouseCapture(capture);
}
+bool LocalFrameClientImpl::UsePrintingLayout() const {
+ return web_frame_->UsePrintingLayout();
+}
+
STATIC_ASSERT_ENUM(DownloadCrossOriginRedirects::kFollow,
WebLocalFrameClient::CrossOriginRedirects::kFollow);
STATIC_ASSERT_ENUM(DownloadCrossOriginRedirects::kNavigate,
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 14a451e9e11..92e532c3286 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
@@ -122,7 +122,8 @@ class LocalFrameClientImpl final : public LocalFrameClient {
WebTriggeringEventInfo,
HTMLFormElement*,
ContentSecurityPolicyDisposition should_bypass_main_world_csp,
- mojom::blink::BlobURLTokenPtr) override;
+ mojom::blink::BlobURLTokenPtr,
+ base::TimeTicks input_start_time) override;
void DispatchWillSendSubmitEvent(HTMLFormElement*) override;
void DispatchWillSubmitForm(HTMLFormElement*) override;
void DidStartLoading(LoadStartType) override;
@@ -161,8 +162,8 @@ class LocalFrameClientImpl final : public LocalFrameClient {
const SubstituteData&,
ClientRedirectPolicy,
const base::UnguessableToken& devtools_navigation_token,
- std::unique_ptr<WebDocumentLoader::ExtraData> extra_data,
- const WebNavigationTimings& navigation_timings) override;
+ std::unique_ptr<WebNavigationParams> navigation_params,
+ std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) override;
WTF::String UserAgent() override;
WTF::String DoNotTrackValue() override;
void TransitionToCommittedForNewPage() override;
@@ -277,12 +278,18 @@ class LocalFrameClientImpl final : public LocalFrameClient {
void FrameRectsChanged(const IntRect&) override;
+ bool IsPluginHandledExternally(HTMLPlugInElement&,
+ const KURL&,
+ const String&) override;
+
std::unique_ptr<WebWorkerFetchContext> CreateWorkerFetchContext() override;
std::unique_ptr<WebContentSettingsClient> CreateWorkerContentSettingsClient()
override;
void SetMouseCapture(bool capture) override;
+ bool UsePrintingLayout() const override;
+
private:
explicit LocalFrameClientImpl(WebLocalFrameImpl*);
diff --git a/chromium/third_party/blink/renderer/core/exported/shared_worker_repository_client_impl.cc b/chromium/third_party/blink/renderer/core/exported/shared_worker_repository_client_impl.cc
index c72e0d15c99..476ecac87f1 100644
--- a/chromium/third_party/blink/renderer/core/exported/shared_worker_repository_client_impl.cc
+++ b/chromium/third_party/blink/renderer/core/exported/shared_worker_repository_client_impl.cc
@@ -87,7 +87,7 @@ class SharedWorkerConnectListener final
}
void ScriptLoadFailed() override {
- worker_->DispatchEvent(Event::CreateCancelable(EventTypeNames::error));
+ worker_->DispatchEvent(*Event::CreateCancelable(EventTypeNames::error));
worker_->SetIsBeingConnected(false);
}
diff --git a/chromium/third_party/blink/renderer/core/exported/web_associated_url_loader_impl.cc b/chromium/third_party/blink/renderer/core/exported/web_associated_url_loader_impl.cc
index c74a5977af6..4ba08d21eff 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_associated_url_loader_impl.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_associated_url_loader_impl.cc
@@ -48,9 +48,8 @@
#include "third_party/blink/public/web/web_associated_url_loader_client.h"
#include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/dom/document.h"
-#include "third_party/blink/renderer/core/loader/document_threadable_loader.h"
-#include "third_party/blink/renderer/core/loader/document_threadable_loader_client.h"
-#include "third_party/blink/renderer/core/loader/threadable_loading_context.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"
#include "third_party/blink/renderer/platform/exported/wrapped_resource_response.h"
#include "third_party/blink/renderer/platform/loader/cors/cors.h"
@@ -96,7 +95,7 @@ void HTTPRequestHeaderValidator::VisitHeader(const WebString& name,
// It forwards its ThreadableLoaderClient notifications to a
// WebAssociatedURLLoaderClient.
class WebAssociatedURLLoaderImpl::ClientAdapter final
- : public DocumentThreadableLoaderClient {
+ : public ThreadableLoaderClient {
public:
static std::unique_ptr<ClientAdapter> Create(
WebAssociatedURLLoaderImpl*,
@@ -119,7 +118,7 @@ class WebAssociatedURLLoaderImpl::ClientAdapter final
void DidFail(const ResourceError&) override;
void DidFailRedirectCheck() override;
- // DocumentThreadableLoaderClient
+ // ThreadableLoaderClient
bool WillFollowRedirect(
const KURL& /*new_url*/,
const ResourceResponse& /*redirect_response*/) override;
@@ -133,7 +132,7 @@ class WebAssociatedURLLoaderImpl::ClientAdapter final
// WebAssociatedURLLoader::loadAsynchronously() completes.
void EnableErrorNotifications();
- // Stops loading and releases the DocumentThreadableLoader as early as
+ // Stops loading and releases the ThreadableLoader as early as
// possible.
WebAssociatedURLLoaderClient* ReleaseClient() {
WebAssociatedURLLoaderClient* client = client_;
@@ -410,10 +409,19 @@ void WebAssociatedURLLoaderImpl::LoadAsynchronously(
request.GetFetchCredentialsMode(), std::move(task_runner));
if (allow_load) {
- ThreadableLoaderOptions options;
ResourceLoaderOptions resource_loader_options;
resource_loader_options.data_buffering_policy = kDoNotBufferData;
+ if (options_.grant_universal_access) {
+ const auto mode = new_request.GetFetchRequestMode();
+ DCHECK(mode == network::mojom::FetchRequestMode::kNoCORS ||
+ mode == network::mojom::FetchRequestMode::kNavigate);
+ scoped_refptr<SecurityOrigin> origin =
+ SecurityOrigin::CreateUniqueOpaque();
+ origin->GrantUniversalAccess();
+ resource_loader_options.security_origin = std::move(origin);
+ }
+
const ResourceRequest& webcore_request = new_request.ToResourceRequest();
WebURLRequest::RequestContext context = webcore_request.GetRequestContext();
if (context == WebURLRequest::kRequestContextUnspecified) {
@@ -432,9 +440,8 @@ void WebAssociatedURLLoaderImpl::LoadAsynchronously(
Document* document = ToDocument(observer_->LifecycleContext());
DCHECK(document);
- loader_ = DocumentThreadableLoader::Create(
- *ThreadableLoadingContext::Create(*document), client_adapter_.get(),
- options, resource_loader_options);
+ loader_ = new ThreadableLoader(*document, client_adapter_.get(),
+ resource_loader_options);
loader_->Start(webcore_request);
}
@@ -508,7 +515,7 @@ void WebAssociatedURLLoaderImpl::DisposeObserver() {
// without cancelling the loader means that it's possible there're some
// non-Blink non-on-heap objects still facing on-heap Blink objects. E.g.
// there could be a WebURLLoader instance behind the
- // DocumentThreadableLoader instance. So, for safety, we chose to just
+ // ThreadableLoader instance. So, for safety, we chose to just
// crash here.
CHECK(ThreadState::Current());
diff --git a/chromium/third_party/blink/renderer/core/exported/web_associated_url_loader_impl.h b/chromium/third_party/blink/renderer/core/exported/web_associated_url_loader_impl.h
index 74d27ddb4bc..cfe041c06a2 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_associated_url_loader_impl.h
+++ b/chromium/third_party/blink/renderer/core/exported/web_associated_url_loader_impl.h
@@ -17,7 +17,7 @@
namespace blink {
-class DocumentThreadableLoader;
+class ThreadableLoader;
class WebAssociatedURLLoaderClient;
class Document;
@@ -57,10 +57,10 @@ class CORE_EXPORT WebAssociatedURLLoaderImpl final
WebAssociatedURLLoaderClient* client_;
WebAssociatedURLLoaderOptions options_;
- // An adapter which converts the DocumentThreadableLoaderClient method
+ // An adapter which converts the hreadableLoaderClient method
// calls into the WebURLLoaderClient method calls.
std::unique_ptr<ClientAdapter> client_adapter_;
- Persistent<DocumentThreadableLoader> loader_;
+ Persistent<ThreadableLoader> loader_;
// A ContextLifecycleObserver for cancelling |m_loader| when the Document
// is detached.
diff --git a/chromium/third_party/blink/renderer/core/exported/web_associated_url_loader_impl_test.cc b/chromium/third_party/blink/renderer/core/exported/web_associated_url_loader_impl_test.cc
index d58fe497799..8162e3064b5 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_associated_url_loader_impl_test.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_associated_url_loader_impl_test.cc
@@ -520,7 +520,7 @@ TEST_F(WebAssociatedURLLoaderTest,
ServeRequests();
// We should get a notification about access control check failure.
- EXPECT_FALSE(will_follow_redirect_);
+ EXPECT_TRUE(will_follow_redirect_);
EXPECT_FALSE(did_receive_response_);
EXPECT_FALSE(did_receive_data_);
EXPECT_TRUE(did_fail_);
@@ -568,8 +568,7 @@ TEST_F(WebAssociatedURLLoaderTest,
EXPECT_TRUE(expected_loader_);
expected_loader_->LoadAsynchronously(request, this);
ServeRequests();
- // We should not receive a notification for the redirect.
- EXPECT_FALSE(will_follow_redirect_);
+ EXPECT_TRUE(will_follow_redirect_);
EXPECT_TRUE(did_receive_response_);
EXPECT_TRUE(did_receive_data_);
EXPECT_TRUE(did_finish_loading_);
@@ -686,5 +685,60 @@ TEST_F(WebAssociatedURLLoaderTest, CrossOriginHeaderAllowResponseHeaders) {
EXPECT_FALSE(actual_response_.HttpHeaderField(header_name_string).IsEmpty());
}
+TEST_F(WebAssociatedURLLoaderTest, AccessCheckForLocalURL) {
+ KURL url = ToKURL("file://test.pdf");
+
+ WebURLRequest request(url);
+ request.SetRequestContext(WebURLRequest::kRequestContextPlugin);
+ request.SetFetchRequestMode(network::mojom::FetchRequestMode::kNoCORS);
+ request.SetFetchCredentialsMode(network::mojom::FetchCredentialsMode::kOmit);
+
+ expected_response_ = WebURLResponse();
+ expected_response_.SetMIMEType("text/plain");
+ expected_response_.SetHTTPStatusCode(200);
+ Platform::Current()->GetURLLoaderMockFactory()->RegisterURL(
+ url, expected_response_, frame_file_path_);
+
+ WebAssociatedURLLoaderOptions options;
+ expected_loader_ = CreateAssociatedURLLoader(options);
+ EXPECT_TRUE(expected_loader_);
+ expected_loader_->LoadAsynchronously(request, this);
+ ServeRequests();
+
+ // The request failes due to a security check.
+ EXPECT_FALSE(did_receive_response_);
+ EXPECT_FALSE(did_receive_data_);
+ EXPECT_FALSE(did_finish_loading_);
+ EXPECT_TRUE(did_fail_);
+}
+
+TEST_F(WebAssociatedURLLoaderTest, BypassAccessCheckForLocalURL) {
+ KURL url = ToKURL("file://test.pdf");
+
+ WebURLRequest request(url);
+ request.SetRequestContext(WebURLRequest::kRequestContextPlugin);
+ request.SetFetchRequestMode(network::mojom::FetchRequestMode::kNoCORS);
+ request.SetFetchCredentialsMode(network::mojom::FetchCredentialsMode::kOmit);
+
+ expected_response_ = WebURLResponse();
+ expected_response_.SetMIMEType("text/plain");
+ expected_response_.SetHTTPStatusCode(200);
+ Platform::Current()->GetURLLoaderMockFactory()->RegisterURL(
+ url, expected_response_, frame_file_path_);
+
+ WebAssociatedURLLoaderOptions options;
+ options.grant_universal_access = true;
+ expected_loader_ = CreateAssociatedURLLoader(options);
+ EXPECT_TRUE(expected_loader_);
+ expected_loader_->LoadAsynchronously(request, this);
+ ServeRequests();
+
+ // The security check is bypassed due to |grant_universal_access|.
+ EXPECT_TRUE(did_receive_response_);
+ EXPECT_TRUE(did_receive_data_);
+ EXPECT_TRUE(did_finish_loading_);
+ EXPECT_FALSE(did_fail_);
+}
+
#undef MAYBE_UntrustedCheckHeaders
} // 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 976bae9c792..7a7f6e0d88e 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
@@ -76,7 +76,7 @@
#include "third_party/blink/renderer/core/inspector/inspector_resource_content_loader.h"
#include "third_party/blink/renderer/core/inspector/inspector_session.h"
#include "third_party/blink/renderer/core/inspector/inspector_task_runner.h"
-#include "third_party/blink/renderer/core/inspector/inspector_tracing_agent.h"
+#include "third_party/blink/renderer/core/inspector/inspector_testing_agent.h"
#include "third_party/blink/renderer/core/inspector/inspector_worker_agent.h"
#include "third_party/blink/renderer/core/inspector/main_thread_debugger.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
@@ -207,7 +207,7 @@ class WebDevToolsAgentImpl::Session : public GarbageCollectedFinalized<Session>,
mojom::blink::DevToolsSessionHostAssociatedPtrInfo host_ptr_info,
mojom::blink::DevToolsSessionAssociatedRequest main_request,
mojom::blink::DevToolsSessionRequest io_request,
- const String& reattach_state);
+ mojom::blink::DevToolsSessionStatePtr reattach_session_state);
~Session() override;
virtual void Trace(blink::Visitor*);
@@ -216,7 +216,6 @@ class WebDevToolsAgentImpl::Session : public GarbageCollectedFinalized<Session>,
InspectorSession* inspector_session() { return inspector_session_.Get(); }
InspectorNetworkAgent* network_agent() { return network_agent_.Get(); }
InspectorPageAgent* page_agent() { return page_agent_.Get(); }
- InspectorTracingAgent* tracing_agent() { return tracing_agent_.Get(); }
InspectorOverlayAgent* overlay_agent() { return overlay_agent_.Get(); }
private:
@@ -228,18 +227,21 @@ class WebDevToolsAgentImpl::Session : public GarbageCollectedFinalized<Session>,
const String& message) override;
// InspectorSession::Client implementation.
- void SendProtocolResponse(int session_id,
- int call_id,
- const String& response,
- const String& state) override;
- void SendProtocolNotification(int session_id,
- const String& message,
- const String& state) override;
+ void SendProtocolResponse(
+ int session_id,
+ int call_id,
+ const String& response,
+ mojom::blink::DevToolsSessionStatePtr updates) override;
+ void SendProtocolNotification(
+ int session_id,
+ const String& message,
+ mojom::blink::DevToolsSessionStatePtr updates) override;
void DispatchProtocolCommandInternal(int call_id,
const String& method,
const String& message);
- void InitializeInspectorSession(const String& reattach_state);
+ void InitializeInspectorSession(
+ mojom::blink::DevToolsSessionStatePtr reattach_session_state);
Member<WebDevToolsAgentImpl> agent_;
Member<WebLocalFrameImpl> frame_;
@@ -249,7 +251,6 @@ class WebDevToolsAgentImpl::Session : public GarbageCollectedFinalized<Session>,
Member<InspectorSession> inspector_session_;
Member<InspectorNetworkAgent> network_agent_;
Member<InspectorPageAgent> page_agent_;
- Member<InspectorTracingAgent> tracing_agent_;
Member<InspectorOverlayAgent> overlay_agent_;
bool detached_ = false;
@@ -310,7 +311,7 @@ WebDevToolsAgentImpl::Session::Session(
mojom::blink::DevToolsSessionHostAssociatedPtrInfo host_ptr_info,
mojom::blink::DevToolsSessionAssociatedRequest request,
mojom::blink::DevToolsSessionRequest io_request,
- const String& reattach_state)
+ mojom::blink::DevToolsSessionStatePtr reattach_session_state)
: agent_(agent),
frame_(agent->web_local_frame_impl_),
binding_(this, std::move(request)) {
@@ -323,7 +324,7 @@ WebDevToolsAgentImpl::Session::Session(
host_ptr_.set_connection_error_handler(WTF::Bind(
&WebDevToolsAgentImpl::Session::Detach, WrapWeakPersistent(this)));
- InitializeInspectorSession(reattach_state);
+ InitializeInspectorSession(std::move(reattach_session_state));
}
WebDevToolsAgentImpl::Session::~Session() {
@@ -336,7 +337,6 @@ void WebDevToolsAgentImpl::Session::Trace(blink::Visitor* visitor) {
visitor->Trace(inspector_session_);
visitor->Trace(network_agent_);
visitor->Trace(page_agent_);
- visitor->Trace(tracing_agent_);
visitor->Trace(overlay_agent_);
}
@@ -351,10 +351,11 @@ void WebDevToolsAgentImpl::Session::Detach() {
inspector_session_->Dispose();
}
-void WebDevToolsAgentImpl::Session::SendProtocolResponse(int session_id,
- int call_id,
- const String& response,
- const String& state) {
+void WebDevToolsAgentImpl::Session::SendProtocolResponse(
+ int session_id,
+ int call_id,
+ const String& response,
+ mojom::blink::DevToolsSessionStatePtr updates) {
if (detached_)
return;
@@ -362,14 +363,14 @@ void WebDevToolsAgentImpl::Session::SendProtocolResponse(int session_id,
// protocol response in any of them.
if (LayoutTestSupport::IsRunningLayoutTest())
agent_->FlushProtocolNotifications();
- host_ptr_->DispatchProtocolResponse(response, call_id, state);
+ host_ptr_->DispatchProtocolResponse(response, call_id, std::move(updates));
}
void WebDevToolsAgentImpl::Session::SendProtocolNotification(
int session_id,
const String& message,
- const String& state) {
- host_ptr_->DispatchProtocolNotification(message, state);
+ mojom::blink::DevToolsSessionStatePtr updates) {
+ host_ptr_->DispatchProtocolNotification(message, std::move(updates));
}
void WebDevToolsAgentImpl::Session::DispatchProtocolCommand(
@@ -388,21 +389,23 @@ void WebDevToolsAgentImpl::Session::DispatchProtocolCommand(
// detach, so we have to check a flag here.
if (detached_)
return;
- inspector_session_->DispatchProtocolMessage(method, message);
+ inspector_session_->DispatchProtocolMessage(call_id, method, message);
}
void WebDevToolsAgentImpl::Session::InitializeInspectorSession(
- const String& reattach_state) {
+ mojom::blink::DevToolsSessionStatePtr reattach_session_state) {
ClientMessageLoopAdapter::EnsureMainThreadDebuggerCreated();
MainThreadDebugger* main_thread_debugger = MainThreadDebugger::Instance();
v8::Isolate* isolate = V8PerIsolateData::MainThreadIsolate();
InspectedFrames* inspected_frames = agent_->inspected_frames_.Get();
+ bool should_reattach = !reattach_session_state.is_null();
+
inspector_session_ = new InspectorSession(
this, agent_->probe_sink_.Get(), 0,
main_thread_debugger->GetV8Inspector(),
main_thread_debugger->ContextGroupId(inspected_frames->Root()),
- reattach_state);
+ std::move(reattach_session_state));
InspectorDOMAgent* dom_agent = new InspectorDOMAgent(
isolate, inspected_frames, inspector_session_->V8Session());
@@ -443,9 +446,6 @@ void WebDevToolsAgentImpl::Session::InitializeInspectorSession(
inspector_session_->Append(
new InspectorWorkerAgent(inspected_frames, nullptr));
- tracing_agent_ = new InspectorTracingAgent(inspected_frames);
- inspector_session_->Append(tracing_agent_);
-
page_agent_ = InspectorPageAgent::Create(
inspected_frames, agent_, agent_->resource_content_loader_.Get(),
inspector_session_->V8Session());
@@ -471,12 +471,14 @@ void WebDevToolsAgentImpl::Session::InitializeInspectorSession(
// we have to store the frame which will become the main frame later.
inspector_session_->Append(new InspectorEmulationAgent(frame_.Get()));
+ inspector_session_->Append(new InspectorTestingAgent(inspected_frames));
+
// Call session init callbacks registered from higher layers
CoreInitializer::GetInstance().InitInspectorAgentSession(
inspector_session_, agent_->include_view_agents_, dom_agent,
inspected_frames, frame_->ViewImpl()->GetPage());
- if (!reattach_state.IsNull()) {
+ if (should_reattach) {
inspector_session_->Restore();
if (agent_->worker_client_)
agent_->worker_client_->ResumeStartup();
@@ -551,12 +553,12 @@ void WebDevToolsAgentImpl::AttachDevToolsSession(
mojom::blink::DevToolsSessionHostAssociatedPtrInfo host,
mojom::blink::DevToolsSessionAssociatedRequest session_request,
mojom::blink::DevToolsSessionRequest io_session_request,
- const String& reattach_state) {
+ mojom::blink::DevToolsSessionStatePtr reattach_session_state) {
if (!sessions_.size())
Platform::Current()->CurrentThread()->AddTaskObserver(this);
- Session* session =
- new Session(this, std::move(host), std::move(session_request),
- std::move(io_session_request), reattach_state);
+ Session* session = new Session(
+ this, std::move(host), std::move(session_request),
+ std::move(io_session_request), std::move(reattach_session_state));
sessions_.insert(session);
if (node_to_inspect_) {
session->overlay_agent()->Inspect(node_to_inspect_);
@@ -655,14 +657,9 @@ String WebDevToolsAgentImpl::EvaluateInOverlayForTesting(const String& script) {
return result;
}
-void WebDevToolsAgentImpl::PaintOverlay() {
- for (auto& session : sessions_)
- session->overlay_agent()->PaintOverlay();
-}
-
-void WebDevToolsAgentImpl::LayoutOverlay() {
+void WebDevToolsAgentImpl::UpdateOverlays() {
for (auto& session : sessions_)
- session->overlay_agent()->LayoutOverlay();
+ session->overlay_agent()->UpdateAllOverlayLifecyclePhases();
}
void WebDevToolsAgentImpl::DispatchBufferedTouchEvents() {
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 9b49622f7d3..61d383f0b77 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
@@ -74,8 +74,7 @@ class CORE_EXPORT WebDevToolsAgentImpl final
void WillBeDestroyed();
void FlushProtocolNotifications();
- void PaintOverlay();
- void LayoutOverlay();
+ void UpdateOverlays();
bool HandleInputEvent(const WebInputEvent&);
void DispatchBufferedTouchEvents();
void BindRequest(mojom::blink::DevToolsAgentAssociatedRequest);
@@ -100,7 +99,7 @@ class CORE_EXPORT WebDevToolsAgentImpl final
mojom::blink::DevToolsSessionHostAssociatedPtrInfo,
mojom::blink::DevToolsSessionAssociatedRequest main_session,
mojom::blink::DevToolsSessionRequest io_session,
- const String& reattach_state) override;
+ mojom::blink::DevToolsSessionStatePtr reattach_session_state) override;
void InspectElement(const WebPoint& point_in_local_root) override;
// InspectorPageAgent::Client implementation.
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 963fa6d2d44..addbe642180 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_document.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_document.cc
@@ -47,6 +47,8 @@
#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/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/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"
@@ -156,9 +158,17 @@ WebString WebDocument::Title() const {
}
WebString WebDocument::ContentAsTextForTesting() const {
- if (Element* document_element = ConstUnwrap<Document>()->documentElement())
- return WebString(document_element->innerText());
- return WebString();
+ Element* document_element = ConstUnwrap<Document>()->documentElement();
+ if (!document_element)
+ return WebString();
+ // TODO(editing-dev): We should use |Element::innerText()|.
+ const_cast<Document*>(ConstUnwrap<Document>())
+ ->UpdateStyleAndLayoutIgnorePendingStylesheetsForNode(document_element);
+ if (!document_element->GetLayoutObject())
+ return document_element->textContent(true);
+ return WebString(
+ PlainText(EphemeralRange::RangeOfContents(*document_element),
+ TextIteratorBehavior::Builder().SetForInnerText(true).Build()));
}
WebElementCollection WebDocument::All() {
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 ddb7c6c8894..e6cc9b8b7f0 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
@@ -150,20 +150,8 @@ WebDocumentLoaderImpl::GetServiceWorkerNetworkProvider() {
return DocumentLoader::GetServiceWorkerNetworkProvider();
}
-void WebDocumentLoaderImpl::SetSourceLocation(
- const WebSourceLocation& source_location) {
- std::unique_ptr<SourceLocation> location =
- SourceLocation::Create(source_location.url, source_location.line_number,
- source_location.column_number, nullptr);
- DocumentLoader::SetSourceLocation(std::move(location));
-}
-
void WebDocumentLoaderImpl::ResetSourceLocation() {
- DocumentLoader::SetSourceLocation(nullptr);
-}
-
-void WebDocumentLoaderImpl::SetUserActivated() {
- DocumentLoader::SetUserActivated();
+ DocumentLoader::ResetSourceLocation();
}
void WebDocumentLoaderImpl::BlockParser() {
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 e222cbeb96d..fef873f6749 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
@@ -77,9 +77,7 @@ class CORE_EXPORT WebDocumentLoaderImpl final : public DocumentLoader,
void SetServiceWorkerNetworkProvider(
std::unique_ptr<WebServiceWorkerNetworkProvider>) override;
WebServiceWorkerNetworkProvider* GetServiceWorkerNetworkProvider() override;
- void SetSourceLocation(const WebSourceLocation&) override;
void ResetSourceLocation() override;
- void SetUserActivated() override;
void BlockParser() override;
void ResumeParser() override;
bool IsArchive() const override;
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 db718d4593b..97b23b480cd 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
@@ -38,6 +38,7 @@
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/events/message_event.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
+#include "third_party/blink/renderer/core/frame/user_activation.h"
#include "third_party/blink/renderer/core/messaging/blink_transferable_message.h"
#include "third_party/blink/renderer/core/messaging/message_port.h"
@@ -60,9 +61,9 @@ WebDOMMessageEvent::WebDOMMessageEvent(
}
// TODO(esprehn): Chromium always passes empty string for lastEventId, is that
// right?
- Unwrap<MessageEvent>()->initMessageEvent("message", false, false,
- message_data, origin,
- "" /*lastEventId*/, window, ports);
+ Unwrap<MessageEvent>()->initMessageEvent(
+ "message", false, false, message_data, origin, "" /*lastEventId*/, window,
+ ports, nullptr /*user_activation*/);
}
WebDOMMessageEvent::WebDOMMessageEvent(TransferableMessage message,
@@ -79,11 +80,19 @@ WebDOMMessageEvent::WebDOMMessageEvent(TransferableMessage message,
Document* core_document = target_document;
ports = MessagePort::EntanglePorts(*core_document, std::move(msg.ports));
}
+
+ UserActivation* user_activation = nullptr;
+ if (msg.user_activation) {
+ user_activation =
+ new UserActivation(msg.user_activation->has_been_active,
+ msg.user_activation->was_active);
+ }
+
// TODO(esprehn): Chromium always passes empty string for lastEventId, is that
// right?
- Unwrap<MessageEvent>()->initMessageEvent("message", false, false,
- std::move(msg.message), origin,
- "" /*lastEventId*/, window, ports);
+ Unwrap<MessageEvent>()->initMessageEvent(
+ "message", false, false, std::move(msg.message), origin,
+ "" /*lastEventId*/, window, ports, user_activation);
}
WebString WebDOMMessageEvent::Origin() const {
@@ -94,7 +103,13 @@ TransferableMessage WebDOMMessageEvent::AsMessage() {
BlinkTransferableMessage msg;
msg.message = Unwrap<MessageEvent>()->DataAsSerializedScriptValue();
msg.ports = Unwrap<MessageEvent>()->ReleaseChannels();
- return ToTransferableMessage(std::move(msg));
+ UserActivation* user_activation = Unwrap<MessageEvent>()->userActivation();
+ TransferableMessage transferable_msg = ToTransferableMessage(std::move(msg));
+ if (user_activation) {
+ transferable_msg.user_activation = mojom::UserActivationSnapshot::New(
+ user_activation->hasBeenActive(), user_activation->isActive());
+ }
+ return transferable_msg;
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/exported/web_drag_data_test.cc b/chromium/third_party/blink/renderer/core/exported/web_drag_data_test.cc
index 7aa8936378b..2ea006b233b 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_drag_data_test.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_drag_data_test.cc
@@ -7,6 +7,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/web_vector.h"
#include "third_party/blink/renderer/core/clipboard/data_object.h"
+#include "third_party/blink/renderer/platform/file_metadata.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/core/exported/web_file_chooser_completion_impl.cc b/chromium/third_party/blink/renderer/core/exported/web_file_chooser_completion_impl.cc
deleted file mode 100644
index ab69ba2edd0..00000000000
--- a/chromium/third_party/blink/renderer/core/exported/web_file_chooser_completion_impl.cc
+++ /dev/null
@@ -1,76 +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/core/exported/web_file_chooser_completion_impl.h"
-
-#include "third_party/blink/renderer/platform/file_metadata.h"
-#include "third_party/blink/renderer/platform/wtf/date_math.h"
-
-namespace blink {
-
-WebFileChooserCompletionImpl::WebFileChooserCompletionImpl(
- scoped_refptr<FileChooser> chooser)
- : file_chooser_(std::move(chooser)) {}
-
-WebFileChooserCompletionImpl::~WebFileChooserCompletionImpl() = default;
-
-void WebFileChooserCompletionImpl::DidChooseFile(
- const WebVector<WebString>& file_names) {
- Vector<FileChooserFileInfo> file_info;
- for (size_t i = 0; i < file_names.size(); ++i)
- file_info.push_back(FileChooserFileInfo(file_names[i]));
- file_chooser_->ChooseFiles(file_info);
- // This object is no longer needed.
- delete this;
-}
-
-void WebFileChooserCompletionImpl::DidChooseFile(
- const WebVector<SelectedFileInfo>& files) {
- Vector<FileChooserFileInfo> file_info;
- for (size_t i = 0; i < files.size(); ++i) {
- if (files[i].file_system_url.IsEmpty()) {
- file_info.push_back(
- FileChooserFileInfo(files[i].path, files[i].display_name));
- } else {
- FileMetadata metadata;
- metadata.modification_time = files[i].modification_time * kMsPerSecond;
- metadata.length = files[i].length;
- metadata.type = files[i].is_directory ? FileMetadata::kTypeDirectory
- : FileMetadata::kTypeFile;
- file_info.push_back(
- FileChooserFileInfo(files[i].file_system_url, metadata));
- }
- }
- file_chooser_->ChooseFiles(file_info);
- // This object is no longer needed.
- delete this;
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/exported/web_file_chooser_completion_impl.h b/chromium/third_party/blink/renderer/core/exported/web_file_chooser_completion_impl.h
deleted file mode 100644
index 51e7baacd3a..00000000000
--- a/chromium/third_party/blink/renderer/core/exported/web_file_chooser_completion_impl.h
+++ /dev/null
@@ -1,57 +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_CORE_EXPORTED_WEB_FILE_CHOOSER_COMPLETION_IMPL_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_EXPORTED_WEB_FILE_CHOOSER_COMPLETION_IMPL_H_
-
-#include "base/memory/scoped_refptr.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_file_chooser_completion.h"
-#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/html/forms/file_chooser.h"
-
-namespace blink {
-
-class CORE_EXPORT WebFileChooserCompletionImpl final
- : public WebFileChooserCompletion {
- public:
- explicit WebFileChooserCompletionImpl(scoped_refptr<FileChooser>);
- ~WebFileChooserCompletionImpl() override;
- void DidChooseFile(const WebVector<WebString>& file_names) override;
- void DidChooseFile(const WebVector<SelectedFileInfo>& files) override;
-
- private:
- scoped_refptr<FileChooser> file_chooser_;
-};
-
-} // namespace blink
-
-#endif
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 192e2915af4..3ddef9c5c59 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
@@ -79,6 +79,8 @@ bool WebFormControlElement::IsAutofilled() const {
bool WebFormControlElement::UserHasEditedTheField() const {
if (auto* input = ToHTMLInputElementOrNull(*private_))
return input->UserHasEditedTheField();
+ if (auto* select_element = ToHTMLSelectElementOrNull(*private_))
+ return select_element->UserHasEditedTheField();
return true;
}
@@ -133,10 +135,10 @@ void WebFormControlElement::SetAutofillValue(const WebString& value) {
nullptr);
}
Unwrap<Element>()->DispatchScopedEvent(
- Event::CreateBubble(EventTypeNames::keydown));
+ *Event::CreateBubble(EventTypeNames::keydown));
Unwrap<TextControlElement>()->SetAutofillValue(value);
Unwrap<Element>()->DispatchScopedEvent(
- Event::CreateBubble(EventTypeNames::keyup));
+ *Event::CreateBubble(EventTypeNames::keyup));
if (!Focused()) {
Unwrap<Element>()->DispatchBlurEvent(nullptr, kWebFocusTypeForward,
nullptr);
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 e9e57f61987..08bc3a23c7f 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
@@ -45,6 +45,7 @@
#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/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"
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 7a664c13f71..4178562d3a0 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
@@ -40,6 +40,7 @@
#include "build/build_config.h"
#include "cc/layers/picture_layer.h"
#include "cc/trees/layer_tree_host.h"
+#include "mojo/public/cpp/bindings/binding.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/page/launching_process_state.h"
@@ -98,7 +99,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/spellcheck/idle_spell_check_callback.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"
#include "third_party/blink/renderer/core/exported/web_remote_frame_impl.h"
@@ -107,6 +108,7 @@
#include "third_party/blink/renderer/core/frame/event_handler_registry.h"
#include "third_party/blink/renderer/core/frame/find_in_page.h"
#include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/remote_frame.h"
@@ -127,11 +129,7 @@
#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/loader/document_loader.h"
-#include "third_party/blink/renderer/core/loader/document_threadable_loader.h"
-#include "third_party/blink/renderer/core/loader/document_threadable_loader_client.h"
#include "third_party/blink/renderer/core/loader/frame_load_request.h"
-#include "third_party/blink/renderer/core/loader/threadable_loader.h"
-#include "third_party/blink/renderer/core/loader/threadable_loading_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/core/page/scoped_page_pauser.h"
@@ -139,6 +137,8 @@
#include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.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/scrollbar.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_test_suite.h"
#include "third_party/blink/renderer/core/testing/null_execution_context.h"
#include "third_party/blink/renderer/core/testing/sim/sim_request.h"
#include "third_party/blink/renderer/core/testing/sim/sim_test.h"
@@ -155,8 +155,6 @@
#include "third_party/blink/renderer/platform/loader/fetch/resource_error.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/scroll/scrollbar.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_test_suite.h"
#include "third_party/blink/renderer/platform/testing/histogram_tester.h"
#include "third_party/blink/renderer/platform/testing/paint_test_configurations.h"
#include "third_party/blink/renderer/platform/testing/scoped_fake_plugin_registry.h"
@@ -332,7 +330,7 @@ class WebFrameTest : public testing::Test {
int node_count = 0;
for (Node& node : range.Nodes()) {
const DocumentMarkerVector& markers_in_node =
- document->Markers().MarkersFor(&node, marker_types);
+ document->Markers().MarkersFor(ToText(node), marker_types);
node_count += std::count_if(
markers_in_node.begin(), markers_in_node.end(),
[start_offset, end_offset, &node, &start_container,
@@ -2581,8 +2579,8 @@ TEST_F(WebFrameTest, setPageScaleFactorDoesNotLayout) {
&client, nullptr, ConfigureAndroid);
web_view_helper.Resize(WebSize(viewport_width, viewport_height));
- int prev_layout_count =
- web_view_helper.LocalMainFrame()->GetFrameView()->LayoutCount();
+ unsigned prev_layout_count =
+ web_view_helper.LocalMainFrame()->GetFrameView()->LayoutCountForTesting();
web_view_helper.GetWebView()->SetPageScaleFactor(3);
EXPECT_FALSE(web_view_helper.GetWebView()
->MainFrameImpl()
@@ -2591,7 +2589,7 @@ TEST_F(WebFrameTest, setPageScaleFactorDoesNotLayout) {
EXPECT_EQ(prev_layout_count, web_view_helper.GetWebView()
->MainFrameImpl()
->GetFrameView()
- ->LayoutCount());
+ ->LayoutCountForTesting());
}
TEST_F(WebFrameTest, setPageScaleFactorWithOverlayScrollbarsDoesNotLayout) {
@@ -2607,8 +2605,8 @@ TEST_F(WebFrameTest, setPageScaleFactorWithOverlayScrollbarsDoesNotLayout) {
&client, nullptr, ConfigureAndroid);
web_view_helper.Resize(WebSize(viewport_width, viewport_height));
- int prev_layout_count =
- web_view_helper.LocalMainFrame()->GetFrameView()->LayoutCount();
+ unsigned prev_layout_count =
+ web_view_helper.LocalMainFrame()->GetFrameView()->LayoutCountForTesting();
web_view_helper.GetWebView()->SetPageScaleFactor(30);
EXPECT_FALSE(web_view_helper.GetWebView()
->MainFrameImpl()
@@ -2617,7 +2615,7 @@ TEST_F(WebFrameTest, setPageScaleFactorWithOverlayScrollbarsDoesNotLayout) {
EXPECT_EQ(prev_layout_count, web_view_helper.GetWebView()
->MainFrameImpl()
->GetFrameView()
- ->LayoutCount());
+ ->LayoutCountForTesting());
}
TEST_F(WebFrameTest, pageScaleFactorWrittenToHistoryItem) {
@@ -3437,13 +3435,6 @@ void SimulatePageScale(WebViewImpl* web_view_impl, float& scale) {
scale = web_view_impl->PageScaleFactor();
}
-void SimulateMultiTargetZoom(WebViewImpl* web_view_impl,
- const WebRect& rect,
- float& scale) {
- if (web_view_impl->ZoomToMultipleTargetsRect(rect))
- SimulatePageScale(web_view_impl, scale);
-}
-
void SimulateDoubleTap(WebViewImpl* web_view_impl,
WebPoint& point,
float& scale) {
@@ -4005,46 +3996,6 @@ TEST_F(WebFrameTest, BlockBoundTest) {
EXPECT_EQ(rect_right_bottom, block_bound);
}
-TEST_F(WebFrameTest, DivMultipleTargetZoomMultipleDivsTest) {
- RegisterMockedHttpURLLoad("get_multiple_divs_for_auto_zoom_test.html");
-
- const float kDeviceScaleFactor = 2.0f;
- int viewport_width = 640 / kDeviceScaleFactor;
- int viewport_height = 1280 / kDeviceScaleFactor;
- float double_tap_zoom_already_legible_ratio = 1.2f;
- FrameTestHelpers::WebViewHelper web_view_helper;
- web_view_helper.InitializeAndLoad(
- base_url_ + "get_multiple_divs_for_auto_zoom_test.html");
- web_view_helper.Resize(WebSize(viewport_width, viewport_height));
- web_view_helper.GetWebView()->SetDefaultPageScaleLimits(0.5f, 4);
- web_view_helper.GetWebView()->SetDeviceScaleFactor(kDeviceScaleFactor);
- web_view_helper.GetWebView()->SetPageScaleFactor(0.5f);
- web_view_helper.GetWebView()->SetMaximumLegibleScale(1.f);
- web_view_helper.GetWebView()->UpdateAllLifecyclePhases();
-
- web_view_helper.GetWebView()->EnableFakePageScaleAnimationForTesting(true);
-
- WebRect viewport_rect(0, 0, viewport_width, viewport_height);
- WebRect top_div(200, 100, 200, 150);
- WebRect bottom_div(200, 300, 200, 150);
- float scale;
- SetScaleAndScrollAndLayout(
- web_view_helper.GetWebView(), WebPoint(0, 0),
- (web_view_helper.GetWebView()->MinimumPageScaleFactor()) *
- (1 + double_tap_zoom_already_legible_ratio) / 2);
-
- SimulateMultiTargetZoom(web_view_helper.GetWebView(), top_div, scale);
- EXPECT_FLOAT_EQ(1, scale);
- SimulateMultiTargetZoom(web_view_helper.GetWebView(), bottom_div, scale);
- EXPECT_FLOAT_EQ(1, scale);
- SimulateMultiTargetZoom(web_view_helper.GetWebView(), viewport_rect, scale);
- EXPECT_FLOAT_EQ(1, scale);
- web_view_helper.GetWebView()->SetPageScaleFactor(
- web_view_helper.GetWebView()->MinimumPageScaleFactor());
- SimulateMultiTargetZoom(web_view_helper.GetWebView(), top_div, scale);
- EXPECT_FLOAT_EQ(1, scale);
-}
-
TEST_F(WebFrameTest, DontZoomInOnFocusedInTouchAction) {
RegisterMockedHttpURLLoad("textbox_in_touch_action.html");
@@ -4495,7 +4446,7 @@ class TestReloadDoesntRedirectWebFrameClient
// FrameTestHelpers::TestWebFrameClient:
WebNavigationPolicy DecidePolicyForNavigation(
const NavigationPolicyInfo& info) override {
- EXPECT_FALSE(info.extra_data);
+ EXPECT_FALSE(info.is_client_redirect);
return kWebNavigationPolicyCurrentTab;
}
};
@@ -4549,7 +4500,8 @@ TEST_F(WebFrameTest, ReloadPreservesState) {
// Reload the page and end up at the same url. State should not be propagated.
web_view_helper.GetWebView()->MainFrameImpl()->StartReload(
WebFrameLoadType::kReload);
- FrameTestHelpers::PumpPendingRequestsForFrameToLoad();
+ FrameTestHelpers::PumpPendingRequestsForFrameToLoad(
+ web_view_helper.LocalMainFrame());
EXPECT_EQ(0, web_view_helper.LocalMainFrame()->GetScrollOffset().width);
EXPECT_EQ(0, web_view_helper.LocalMainFrame()->GetScrollOffset().height);
EXPECT_EQ(1.0f, web_view_helper.GetWebView()->PageScaleFactor());
@@ -4602,7 +4554,8 @@ TEST_F(WebFrameTest, IframeRedirect) {
web_view_helper.InitializeAndLoad(base_url_ + "iframe_redirect.html");
// Pump pending requests one more time. The test page loads script that
// navigates.
- FrameTestHelpers::PumpPendingRequestsForFrameToLoad();
+ FrameTestHelpers::PumpPendingRequestsForFrameToLoad(
+ web_view_helper.LocalMainFrame());
WebFrame* iframe = web_view_helper.LocalMainFrame()->FindFrameByName(
WebString::FromUTF8("ifr"));
@@ -5082,23 +5035,38 @@ TEST_F(WebFrameTest, ExecuteScriptDuringDidCreateScriptContext) {
FrameTestHelpers::ReloadFrame(web_view_helper.GetWebView()->MainFrameImpl());
}
-class FindUpdateWebFrameClient : public FrameTestHelpers::TestWebFrameClient {
+class TestFindInPageClient : public mojom::blink::FindInPageClient {
public:
- FindUpdateWebFrameClient()
- : find_results_are_ready_(false), count_(-1), active_index_(-1) {}
- ~FindUpdateWebFrameClient() override = default;
+ TestFindInPageClient()
+ : find_results_are_ready_(false),
+ count_(-1),
+ active_index_(-1),
+ binding_(this) {}
- // FrameTestHelpers::TestWebFrameClient:
- void ReportFindInPageMatchCount(int, int count, bool final_update) override {
- count_ = count;
- if (final_update)
- find_results_are_ready_ = true;
+ ~TestFindInPageClient() override = default;
+
+ void SetFrame(WebLocalFrameImpl* frame) {
+ mojom::blink::FindInPageClientPtr client;
+ binding_.Bind(MakeRequest(&client));
+ frame->GetFindInPage()->SetClient(std::move(client));
}
- void ReportFindInPageSelection(int,
- int active_match_ordinal,
- const WebRect&) override {
+ void SetNumberOfMatches(
+ int request_id,
+ unsigned int current_number_of_matches,
+ mojom::blink::FindMatchUpdateType final_update) final {
+ count_ = current_number_of_matches;
+ find_results_are_ready_ =
+ (final_update == mojom::blink::FindMatchUpdateType::kFinalUpdate);
+ }
+
+ void SetActiveMatch(int request_id,
+ const WebRect& active_match_rect,
+ int active_match_ordinal,
+ mojom::blink::FindMatchUpdateType final_update) final {
active_index_ = active_match_ordinal;
+ find_results_are_ready_ =
+ (final_update == mojom::blink::FindMatchUpdateType::kFinalUpdate);
}
bool FindResultsAreReady() const { return find_results_are_ready_; }
@@ -5109,15 +5077,16 @@ class FindUpdateWebFrameClient : public FrameTestHelpers::TestWebFrameClient {
bool find_results_are_ready_;
int count_;
int active_index_;
+ mojo::Binding<mojom::blink::FindInPageClient> binding_;
};
TEST_F(WebFrameTest, FindInPageMatchRects) {
RegisterMockedHttpURLLoad("find_in_page_frame.html");
- FindUpdateWebFrameClient client;
+ FrameTestHelpers::TestWebFrameClient frame_client;
FrameTestHelpers::WebViewHelper web_view_helper;
web_view_helper.InitializeAndLoad(base_url_ + "find_in_page_frame.html",
- &client);
+ &frame_client);
web_view_helper.Resize(WebSize(640, 480));
web_view_helper.GetWebView()->SetMaximumLegibleScale(1.f);
web_view_helper.GetWebView()->UpdateAllLifecyclePhases();
@@ -5131,8 +5100,11 @@ TEST_F(WebFrameTest, FindInPageMatchRects) {
const int kNumResults = 17;
WebFindOptions options;
+ options.run_synchronously_for_testing = true;
WebString search_text = WebString::FromUTF8(kFindString);
WebLocalFrameImpl* main_frame = web_view_helper.LocalMainFrame();
+ TestFindInPageClient find_in_page_client;
+ find_in_page_client.SetFrame(main_frame);
EXPECT_TRUE(main_frame->Find(kFindIdentifier, search_text, options, false));
main_frame->EnsureTextFinder().ResetMatchCount();
@@ -5142,9 +5114,8 @@ TEST_F(WebFrameTest, FindInPageMatchRects) {
frame->EnsureTextFinder().StartScopingStringMatches(kFindIdentifier,
search_text, options);
}
-
RunPendingTasks();
- EXPECT_TRUE(client.FindResultsAreReady());
+ EXPECT_TRUE(find_in_page_client.FindResultsAreReady());
WebVector<WebFloatRect> web_match_rects =
main_frame->EnsureTextFinder().FindMatchRects();
@@ -5188,10 +5159,10 @@ TEST_F(WebFrameTest, FindInPageMatchRects) {
TEST_F(WebFrameTest, FindInPageActiveIndex) {
RegisterMockedHttpURLLoad("find_match_count.html");
- FindUpdateWebFrameClient client;
+ FrameTestHelpers::TestWebFrameClient frame_client;
FrameTestHelpers::WebViewHelper web_view_helper;
web_view_helper.InitializeAndLoad(base_url_ + "find_match_count.html",
- &client);
+ &frame_client);
web_view_helper.GetWebView()->Resize(WebSize(640, 480));
RunPendingTasks();
@@ -5200,8 +5171,12 @@ TEST_F(WebFrameTest, FindInPageActiveIndex) {
const int kActiveIndex = 1;
WebFindOptions options;
+ options.run_synchronously_for_testing = true;
WebString search_text = WebString::FromUTF8(kFindString);
WebLocalFrameImpl* main_frame = web_view_helper.LocalMainFrame();
+ TestFindInPageClient find_in_page_client;
+ find_in_page_client.SetFrame(main_frame);
+
EXPECT_TRUE(main_frame->Find(kFindIdentifier, search_text, options, false));
main_frame->EnsureTextFinder().ResetMatchCount();
@@ -5210,8 +5185,8 @@ TEST_F(WebFrameTest, FindInPageActiveIndex) {
frame->EnsureTextFinder().StartScopingStringMatches(kFindIdentifier,
search_text, options);
}
-
RunPendingTasks();
+
EXPECT_TRUE(main_frame->Find(kFindIdentifier, search_text, options, false));
main_frame->StopFindingForTesting(
mojom::StopFindAction::kStopFindActionClearSelection);
@@ -5223,8 +5198,8 @@ TEST_F(WebFrameTest, FindInPageActiveIndex) {
}
RunPendingTasks();
- EXPECT_TRUE(client.FindResultsAreReady());
- EXPECT_EQ(kActiveIndex, client.ActiveIndex());
+ EXPECT_TRUE(find_in_page_client.FindResultsAreReady());
+ EXPECT_EQ(kActiveIndex, find_in_page_client.ActiveIndex());
const char* kFindStringNew = "e";
WebString search_text_new = WebString::FromUTF8(kFindStringNew);
@@ -5240,17 +5215,18 @@ TEST_F(WebFrameTest, FindInPageActiveIndex) {
}
RunPendingTasks();
- EXPECT_TRUE(client.FindResultsAreReady());
- EXPECT_EQ(kActiveIndex, client.ActiveIndex());
+ EXPECT_TRUE(find_in_page_client.FindResultsAreReady());
+ EXPECT_EQ(kActiveIndex, find_in_page_client.ActiveIndex());
}
TEST_F(WebFrameTest, FindOnDetachedFrame) {
RegisterMockedHttpURLLoad("find_in_page.html");
RegisterMockedHttpURLLoad("find_in_page_frame.html");
- FindUpdateWebFrameClient client;
+ FrameTestHelpers::TestWebFrameClient frame_client;
FrameTestHelpers::WebViewHelper web_view_helper;
- web_view_helper.InitializeAndLoad(base_url_ + "find_in_page.html", &client);
+ web_view_helper.InitializeAndLoad(base_url_ + "find_in_page.html",
+ &frame_client);
web_view_helper.Resize(WebSize(640, 480));
RunPendingTasks();
@@ -5258,8 +5234,12 @@ TEST_F(WebFrameTest, FindOnDetachedFrame) {
const int kFindIdentifier = 12345;
WebFindOptions options;
+ options.run_synchronously_for_testing = true;
WebString search_text = WebString::FromUTF8(kFindString);
WebLocalFrameImpl* main_frame = web_view_helper.LocalMainFrame();
+ TestFindInPageClient main_find_in_page_client;
+ main_find_in_page_client.SetFrame(main_frame);
+
WebLocalFrameImpl* second_frame =
ToWebLocalFrameImpl(main_frame->TraverseNext());
@@ -5271,7 +5251,7 @@ TEST_F(WebFrameTest, FindOnDetachedFrame) {
second_frame->Find(kFindIdentifier, search_text, options, false));
RunPendingTasks();
- EXPECT_FALSE(client.FindResultsAreReady());
+ EXPECT_FALSE(main_find_in_page_client.FindResultsAreReady());
main_frame->EnsureTextFinder().ResetMatchCount();
@@ -5282,16 +5262,17 @@ TEST_F(WebFrameTest, FindOnDetachedFrame) {
}
RunPendingTasks();
- EXPECT_TRUE(client.FindResultsAreReady());
+ EXPECT_TRUE(main_find_in_page_client.FindResultsAreReady());
}
TEST_F(WebFrameTest, FindDetachFrameBeforeScopeStrings) {
RegisterMockedHttpURLLoad("find_in_page.html");
RegisterMockedHttpURLLoad("find_in_page_frame.html");
- FindUpdateWebFrameClient client;
+ FrameTestHelpers::TestWebFrameClient frame_client;
FrameTestHelpers::WebViewHelper web_view_helper;
- web_view_helper.InitializeAndLoad(base_url_ + "find_in_page.html", &client);
+ web_view_helper.InitializeAndLoad(base_url_ + "find_in_page.html",
+ &frame_client);
web_view_helper.Resize(WebSize(640, 480));
RunPendingTasks();
@@ -5299,16 +5280,18 @@ TEST_F(WebFrameTest, FindDetachFrameBeforeScopeStrings) {
const int kFindIdentifier = 12345;
WebFindOptions options;
+ options.run_synchronously_for_testing = true;
WebString search_text = WebString::FromUTF8(kFindString);
WebLocalFrameImpl* main_frame = web_view_helper.LocalMainFrame();
+ TestFindInPageClient find_in_page_client;
+ find_in_page_client.SetFrame(main_frame);
- for (WebFrame* frame = main_frame; frame; frame = frame->TraverseNext()) {
- EXPECT_TRUE(frame->ToWebLocalFrame()->Find(kFindIdentifier, search_text,
- options, false));
+ for (WebLocalFrameImpl* frame = main_frame; frame;
+ frame = static_cast<WebLocalFrameImpl*>(frame->TraverseNext())) {
+ EXPECT_TRUE(frame->Find(kFindIdentifier, search_text, options, false));
}
-
RunPendingTasks();
- EXPECT_FALSE(client.FindResultsAreReady());
+ EXPECT_FALSE(find_in_page_client.FindResultsAreReady());
// Detach the frame between finding and scoping.
RemoveElementById(main_frame, "frame");
@@ -5322,16 +5305,17 @@ TEST_F(WebFrameTest, FindDetachFrameBeforeScopeStrings) {
}
RunPendingTasks();
- EXPECT_TRUE(client.FindResultsAreReady());
+ EXPECT_TRUE(find_in_page_client.FindResultsAreReady());
}
TEST_F(WebFrameTest, FindDetachFrameWhileScopingStrings) {
RegisterMockedHttpURLLoad("find_in_page.html");
RegisterMockedHttpURLLoad("find_in_page_frame.html");
- FindUpdateWebFrameClient client;
+ FrameTestHelpers::TestWebFrameClient frame_client;
FrameTestHelpers::WebViewHelper web_view_helper;
- web_view_helper.InitializeAndLoad(base_url_ + "find_in_page.html", &client);
+ web_view_helper.InitializeAndLoad(base_url_ + "find_in_page.html",
+ &frame_client);
web_view_helper.Resize(WebSize(640, 480));
RunPendingTasks();
@@ -5339,16 +5323,18 @@ TEST_F(WebFrameTest, FindDetachFrameWhileScopingStrings) {
const int kFindIdentifier = 12345;
WebFindOptions options;
+ options.run_synchronously_for_testing = true;
WebString search_text = WebString::FromUTF8(kFindString);
WebLocalFrameImpl* main_frame = web_view_helper.LocalMainFrame();
+ TestFindInPageClient find_in_page_client;
+ find_in_page_client.SetFrame(main_frame);
- for (WebFrame* frame = main_frame; frame; frame = frame->TraverseNext()) {
- EXPECT_TRUE(frame->ToWebLocalFrame()->Find(kFindIdentifier, search_text,
- options, false));
+ for (WebLocalFrameImpl* frame = main_frame; frame;
+ frame = static_cast<WebLocalFrameImpl*>(frame->TraverseNext())) {
+ EXPECT_TRUE(frame->Find(kFindIdentifier, search_text, options, false));
}
-
RunPendingTasks();
- EXPECT_FALSE(client.FindResultsAreReady());
+ EXPECT_FALSE(find_in_page_client.FindResultsAreReady());
main_frame->EnsureTextFinder().ResetMatchCount();
@@ -5362,17 +5348,22 @@ TEST_F(WebFrameTest, FindDetachFrameWhileScopingStrings) {
// before it actually scopes.
RemoveElementById(main_frame, "frame");
+ for (WebLocalFrameImpl* frame = main_frame; frame;
+ frame = static_cast<WebLocalFrameImpl*>(frame->TraverseNext())) {
+ frame->EnsureTextFinder().StartScopingStringMatches(kFindIdentifier,
+ search_text, options);
+ }
RunPendingTasks();
- EXPECT_TRUE(client.FindResultsAreReady());
+ EXPECT_TRUE(find_in_page_client.FindResultsAreReady());
}
TEST_F(WebFrameTest, ResetMatchCount) {
RegisterMockedHttpURLLoad("find_in_generated_frame.html");
- FindUpdateWebFrameClient client;
+ FrameTestHelpers::TestWebFrameClient frame_client;
FrameTestHelpers::WebViewHelper web_view_helper;
web_view_helper.InitializeAndLoad(base_url_ + "find_in_generated_frame.html",
- &client);
+ &frame_client);
web_view_helper.Resize(WebSize(640, 480));
RunPendingTasks();
@@ -5380,8 +5371,11 @@ TEST_F(WebFrameTest, ResetMatchCount) {
const int kFindIdentifier = 12345;
WebFindOptions options;
+ options.run_synchronously_for_testing = true;
WebString search_text = WebString::FromUTF8(kFindString);
WebLocalFrameImpl* main_frame = web_view_helper.LocalMainFrame();
+ TestFindInPageClient find_in_page_client;
+ find_in_page_client.SetFrame(main_frame);
// Check that child frame exists.
EXPECT_TRUE(!!main_frame->TraverseNext());
@@ -5392,7 +5386,7 @@ TEST_F(WebFrameTest, ResetMatchCount) {
}
RunPendingTasks();
- EXPECT_FALSE(client.FindResultsAreReady());
+ EXPECT_FALSE(find_in_page_client.FindResultsAreReady());
main_frame->EnsureTextFinder().ResetMatchCount();
}
@@ -5400,9 +5394,9 @@ TEST_F(WebFrameTest, ResetMatchCount) {
TEST_F(WebFrameTest, SetTickmarks) {
RegisterMockedHttpURLLoad("find.html");
- FindUpdateWebFrameClient client;
+ FrameTestHelpers::TestWebFrameClient frame_client;
FrameTestHelpers::WebViewHelper web_view_helper;
- web_view_helper.InitializeAndLoad(base_url_ + "find.html", &client);
+ web_view_helper.InitializeAndLoad(base_url_ + "find.html", &frame_client);
web_view_helper.Resize(WebSize(640, 480));
RunPendingTasks();
@@ -5410,8 +5404,11 @@ TEST_F(WebFrameTest, SetTickmarks) {
const int kFindIdentifier = 12345;
WebFindOptions options;
+ options.run_synchronously_for_testing = true;
WebString search_text = WebString::FromUTF8(kFindString);
WebLocalFrameImpl* main_frame = web_view_helper.LocalMainFrame();
+ TestFindInPageClient find_in_page_client;
+ find_in_page_client.SetFrame(main_frame);
EXPECT_TRUE(main_frame->Find(kFindIdentifier, search_text, options, false));
main_frame->EnsureTextFinder().ResetMatchCount();
@@ -5419,7 +5416,7 @@ TEST_F(WebFrameTest, SetTickmarks) {
kFindIdentifier, search_text, options);
RunPendingTasks();
- EXPECT_TRUE(client.FindResultsAreReady());
+ EXPECT_TRUE(find_in_page_client.FindResultsAreReady());
// Get the tickmarks for the original find request.
LocalFrameView* frame_view = web_view_helper.LocalMainFrame()->GetFrameView();
@@ -5453,24 +5450,28 @@ TEST_F(WebFrameTest, SetTickmarks) {
TEST_F(WebFrameTest, FindInPageJavaScriptUpdatesDOM) {
RegisterMockedHttpURLLoad("find.html");
- FindUpdateWebFrameClient client;
+ FrameTestHelpers::TestWebFrameClient frame_client;
FrameTestHelpers::WebViewHelper web_view_helper;
- web_view_helper.InitializeAndLoad(base_url_ + "find.html", &client);
+ web_view_helper.InitializeAndLoad(base_url_ + "find.html", &frame_client);
web_view_helper.Resize(WebSize(640, 480));
RunPendingTasks();
WebLocalFrameImpl* frame = web_view_helper.LocalMainFrame();
+ TestFindInPageClient find_in_page_client;
+ find_in_page_client.SetFrame(frame);
+
const int kFindIdentifier = 12345;
static const char* kFindString = "foo";
WebString search_text = WebString::FromUTF8(kFindString);
WebFindOptions options;
+ options.run_synchronously_for_testing = true;
bool active_now;
frame->EnsureTextFinder().ResetMatchCount();
frame->EnsureTextFinder().StartScopingStringMatches(kFindIdentifier,
search_text, options);
RunPendingTasks();
- EXPECT_TRUE(client.FindResultsAreReady());
+ EXPECT_TRUE(find_in_page_client.FindResultsAreReady());
// Find in a <div> element.
options.find_next = true;
@@ -5529,9 +5530,9 @@ TEST_F(WebFrameTest, FindInPageJavaScriptUpdatesDOMProperOrdinal) {
"bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo "
"bar foo bar foo abc bar <div id='new_text'></div>";
- FindUpdateWebFrameClient client;
+ FrameTestHelpers::TestWebFrameClient frame_client;
FrameTestHelpers::WebViewHelper web_view_helper;
- web_view_helper.Initialize(&client);
+ web_view_helper.Initialize(&frame_client);
WebLocalFrameImpl* frame = web_view_helper.LocalMainFrame();
FrameTestHelpers::LoadHTMLString(frame, html,
@@ -5540,30 +5541,31 @@ TEST_F(WebFrameTest, FindInPageJavaScriptUpdatesDOMProperOrdinal) {
web_view_helper.GetWebView()->SetFocus(true);
RunPendingTasks();
+ TestFindInPageClient find_in_page_client;
+ find_in_page_client.SetFrame(frame);
const int kFindIdentifier = 12345;
- WebFindOptions options;
+ mojom::blink::FindOptionsPtr options(mojom::blink::FindOptions::New());
+ options->run_synchronously_for_testing = true;
+ options->find_next = false;
+ options->forward = true;
// The first search that will start the scoping process.
- frame->RequestFind(kFindIdentifier, search_pattern, options);
- EXPECT_FALSE(client.FindResultsAreReady());
- EXPECT_EQ(1, client.Count());
- EXPECT_TRUE(frame->EnsureTextFinder().ScopingInProgress());
-
- // The scoping won't find all the entries on the first run due to the fake
- // timer.
- while (frame->EnsureTextFinder().ScopingInProgress())
- RunPendingTasks();
-
- EXPECT_EQ(2, client.Count());
- EXPECT_EQ(1, client.ActiveIndex());
+ frame->GetFindInPage()->Find(kFindIdentifier, search_pattern,
+ options.Clone());
+ EXPECT_FALSE(find_in_page_client.FindResultsAreReady());
+ RunPendingTasks();
- options.find_next = true;
+ EXPECT_EQ(2, find_in_page_client.Count());
+ EXPECT_EQ(1, find_in_page_client.ActiveIndex());
+ options->find_next = true;
// The second search will jump to the next match without any scoping.
- frame->RequestFind(kFindIdentifier, search_pattern, options);
-
- EXPECT_EQ(2, client.Count());
- EXPECT_EQ(2, client.ActiveIndex());
+ frame->GetFindInPage()->Find(kFindIdentifier, search_pattern,
+ options.Clone());
+ // Run pending tasks to make sure IncreaseMatchCount calls passes.
+ RunPendingTasks();
+ EXPECT_EQ(2, find_in_page_client.Count());
+ EXPECT_EQ(2, find_in_page_client.ActiveIndex());
EXPECT_FALSE(frame->EnsureTextFinder().ScopingInProgress());
// Insert new text, which contains occurence of |searchText|.
@@ -5572,15 +5574,12 @@ TEST_F(WebFrameTest, FindInPageJavaScriptUpdatesDOMProperOrdinal) {
"textDiv.innerHTML = 'foo abc';"));
// The third search will find a new match and initiate a new scoping.
- frame->RequestFind(kFindIdentifier, search_pattern, options);
-
- EXPECT_TRUE(frame->EnsureTextFinder().ScopingInProgress());
-
- while (frame->EnsureTextFinder().ScopingInProgress())
- RunPendingTasks();
+ frame->GetFindInPage()->Find(kFindIdentifier, search_pattern,
+ options.Clone());
+ RunPendingTasks();
- EXPECT_EQ(3, client.Count());
- EXPECT_EQ(3, client.ActiveIndex());
+ EXPECT_EQ(3, find_in_page_client.Count());
+ EXPECT_EQ(3, find_in_page_client.ActiveIndex());
}
TEST_F(WebFrameTest, FindInPageStopFindActionKeepSelectionInAnotherDocument) {
@@ -5607,6 +5606,61 @@ TEST_F(WebFrameTest, FindInPageStopFindActionKeepSelectionInAnotherDocument) {
// Pass if not crash. See http://crbug.com/719880 for details.
}
+TEST_F(WebFrameTest, FindInPageForcedRedoOfFindInPage) {
+ const WebString search_pattern = WebString::FromUTF8("bar");
+ const char* html = "foo bar foo foo bar";
+ FrameTestHelpers::TestWebFrameClient frame_client;
+ FrameTestHelpers::WebViewHelper web_view_helper;
+ web_view_helper.Initialize(&frame_client);
+
+ WebLocalFrameImpl* frame = web_view_helper.LocalMainFrame();
+ FrameTestHelpers::LoadHTMLString(frame, html,
+ URLTestHelpers::ToKURL(base_url_));
+ web_view_helper.Resize(WebSize(640, 480));
+ web_view_helper.GetWebView()->SetFocus(true);
+ RunPendingTasks();
+
+ TestFindInPageClient find_in_page_client;
+ find_in_page_client.SetFrame(frame);
+ const int kFindIdentifier = 12345;
+
+ auto options = mojom::blink::FindOptions::New();
+ options->run_synchronously_for_testing = true;
+ options->find_next = false;
+ options->forward = true;
+ // First run.
+ frame->GetFindInPage()->Find(kFindIdentifier, search_pattern,
+ options->Clone());
+ RunPendingTasks();
+ EXPECT_EQ(2, find_in_page_client.Count());
+ EXPECT_EQ(1, find_in_page_client.ActiveIndex());
+
+ options->force = true;
+ frame->GetFindInPage()->Find(kFindIdentifier, search_pattern,
+ options->Clone());
+ RunPendingTasks();
+ EXPECT_EQ(2, find_in_page_client.Count());
+ EXPECT_EQ(1, find_in_page_client.ActiveIndex());
+
+ options->find_next = true;
+ options->force = false;
+
+ frame->GetFindInPage()->Find(kFindIdentifier, search_pattern,
+ options->Clone());
+ RunPendingTasks();
+ EXPECT_EQ(2, find_in_page_client.Count());
+ EXPECT_EQ(2, find_in_page_client.ActiveIndex());
+
+ options->find_next = false;
+ options->force = true;
+
+ frame->GetFindInPage()->Find(kFindIdentifier, search_pattern,
+ options->Clone());
+ RunPendingTasks();
+ EXPECT_EQ(2, find_in_page_client.Count());
+ EXPECT_EQ(2, find_in_page_client.ActiveIndex());
+}
+
static WebPoint TopLeft(const WebRect& rect) {
return WebPoint(rect.x, rect.y);
}
@@ -6533,317 +6587,6 @@ TEST_F(CompositedSelectionBoundsTest, InputScrolled) {
#endif
#endif
-class DisambiguationPopupTestWebViewClient
- : public FrameTestHelpers::TestWebViewClient {
- public:
- DisambiguationPopupTestWebViewClient() = default;
- ~DisambiguationPopupTestWebViewClient() override = default;
-
- // FrameTestHelpers::TestWebViewClient:
- bool DidTapMultipleTargets(const WebSize&,
- const WebRect&,
- const WebVector<WebRect>& target_rects) override {
- EXPECT_GE(target_rects.size(), 2u);
- triggered_ = true;
- return true;
- }
-
- bool Triggered() const { return triggered_; }
- void ResetTriggered() { triggered_ = false; }
- bool triggered_;
-};
-
-static WebCoalescedInputEvent FatTap(int x, int y, int diameter) {
- WebGestureEvent event(WebInputEvent::kGestureTap, WebInputEvent::kNoModifiers,
- WebInputEvent::GetStaticTimeStampForTests(),
- kWebGestureDeviceTouchscreen);
- event.SetPositionInWidget(WebFloatPoint(x, y));
- event.data.tap.width = diameter;
- event.data.tap.height = diameter;
- return WebCoalescedInputEvent(event);
-}
-
-TEST_F(WebFrameTest, DisambiguationPopup) {
- const std::string html_file = "disambiguation_popup.html";
- RegisterMockedHttpURLLoad(html_file);
-
- DisambiguationPopupTestWebViewClient client;
- const int kTapDiameter = 100;
-
- // Make sure we initialize to minimum scale, even if the window size
- // only becomes available after the load begins.
- FrameTestHelpers::WebViewHelper web_view_helper;
- web_view_helper.InitializeAndLoad(base_url_ + html_file, nullptr, &client);
- web_view_helper.Resize(WebSize(1000, 1000));
-
- client.ResetTriggered();
- web_view_helper.GetWebView()->HandleInputEvent(FatTap(0, 0, kTapDiameter));
- EXPECT_FALSE(client.Triggered());
-
- client.ResetTriggered();
- web_view_helper.GetWebView()->HandleInputEvent(
- FatTap(200, 115, kTapDiameter));
- EXPECT_FALSE(client.Triggered());
-
- for (int i = 0; i <= 46; i++) {
- client.ResetTriggered();
- web_view_helper.GetWebView()->HandleInputEvent(
- FatTap(120, 230 + i * 5, kTapDiameter));
-
- int j = i % 10;
- if (j >= 7 && j <= 9)
- EXPECT_TRUE(client.Triggered());
- else
- EXPECT_FALSE(client.Triggered());
- }
-
- for (int i = 0; i <= 46; i++) {
- client.ResetTriggered();
- web_view_helper.GetWebView()->HandleInputEvent(
- FatTap(10 + i * 5, 590, kTapDiameter));
-
- int j = i % 10;
- if (j >= 7 && j <= 9)
- EXPECT_TRUE(client.Triggered());
- else
- EXPECT_FALSE(client.Triggered());
- }
-
- // The same taps shouldn't trigger didTapMultipleTargets() after disabling the
- // notification for multi-target-tap.
- web_view_helper.GetWebView()
- ->GetSettings()
- ->SetMultiTargetTapNotificationEnabled(false);
-
- for (int i = 0; i <= 46; i++) {
- client.ResetTriggered();
- web_view_helper.GetWebView()->HandleInputEvent(
- FatTap(10 + i * 5, 590, kTapDiameter));
- EXPECT_FALSE(client.Triggered());
- }
-}
-
-TEST_F(WebFrameTest, DisambiguationPopupNoContainer) {
- RegisterMockedHttpURLLoad("disambiguation_popup_no_container.html");
-
- DisambiguationPopupTestWebViewClient client;
- const int kTapDiameter = 100;
-
- // Make sure we initialize to minimum scale, even if the window size
- // only becomes available after the load begins.
- FrameTestHelpers::WebViewHelper web_view_helper;
- web_view_helper.InitializeAndLoad(
- base_url_ + "disambiguation_popup_no_container.html", nullptr, &client);
- web_view_helper.Resize(WebSize(1000, 1000));
-
- client.ResetTriggered();
- web_view_helper.GetWebView()->HandleInputEvent(FatTap(50, 50, kTapDiameter));
- EXPECT_FALSE(client.Triggered());
-}
-
-TEST_F(WebFrameTest, DisambiguationPopupMobileSite) {
- const std::string html_file = "disambiguation_popup_mobile_site.html";
- RegisterMockedHttpURLLoad(html_file);
-
- DisambiguationPopupTestWebViewClient client;
- const int kTapDiameter = 100;
-
- // Make sure we initialize to minimum scale, even if the window size
- // only becomes available after the load begins.
- FrameTestHelpers::WebViewHelper web_view_helper;
- web_view_helper.InitializeAndLoad(base_url_ + html_file, nullptr, &client,
- nullptr, ConfigureAndroid);
- web_view_helper.Resize(WebSize(1000, 1000));
-
- client.ResetTriggered();
- web_view_helper.GetWebView()->HandleInputEvent(FatTap(0, 0, kTapDiameter));
- EXPECT_FALSE(client.Triggered());
-
- client.ResetTriggered();
- web_view_helper.GetWebView()->HandleInputEvent(
- FatTap(200, 115, kTapDiameter));
- EXPECT_FALSE(client.Triggered());
-
- for (int i = 0; i <= 46; i++) {
- client.ResetTriggered();
- web_view_helper.GetWebView()->HandleInputEvent(
- FatTap(120, 230 + i * 5, kTapDiameter));
- EXPECT_FALSE(client.Triggered());
- }
-
- for (int i = 0; i <= 46; i++) {
- client.ResetTriggered();
- web_view_helper.GetWebView()->HandleInputEvent(
- FatTap(10 + i * 5, 590, kTapDiameter));
- EXPECT_FALSE(client.Triggered());
- }
-}
-
-TEST_F(WebFrameTest, DisambiguationPopupViewportSite) {
- const std::string html_file = "disambiguation_popup_viewport_site.html";
- RegisterMockedHttpURLLoad(html_file);
-
- DisambiguationPopupTestWebViewClient client;
- const int kTapDiameter = 100;
-
- // Make sure we initialize to minimum scale, even if the window size
- // only becomes available after the load begins.
- FrameTestHelpers::WebViewHelper web_view_helper;
- web_view_helper.InitializeAndLoad(base_url_ + html_file, nullptr, &client,
- nullptr, ConfigureAndroid);
- web_view_helper.Resize(WebSize(1000, 1000));
-
- client.ResetTriggered();
- web_view_helper.GetWebView()->HandleInputEvent(FatTap(0, 0, kTapDiameter));
- EXPECT_FALSE(client.Triggered());
-
- client.ResetTriggered();
- web_view_helper.GetWebView()->HandleInputEvent(
- FatTap(200, 115, kTapDiameter));
- EXPECT_FALSE(client.Triggered());
-
- for (int i = 0; i <= 46; i++) {
- client.ResetTriggered();
- web_view_helper.GetWebView()->HandleInputEvent(
- FatTap(120, 230 + i * 5, kTapDiameter));
- EXPECT_FALSE(client.Triggered());
- }
-
- for (int i = 0; i <= 46; i++) {
- client.ResetTriggered();
- web_view_helper.GetWebView()->HandleInputEvent(
- FatTap(10 + i * 5, 590, kTapDiameter));
- EXPECT_FALSE(client.Triggered());
- }
-}
-
-TEST_F(WebFrameTest, DisambiguationPopupVisualViewport) {
- const std::string html_file = "disambiguation_popup_200_by_800.html";
- RegisterMockedHttpURLLoad(html_file);
-
- DisambiguationPopupTestWebViewClient client;
- const int kTapDiameter = 100;
-
- FrameTestHelpers::WebViewHelper web_view_helper;
- web_view_helper.InitializeAndLoad(base_url_ + html_file, nullptr, &client,
- nullptr, ConfigureAndroid);
-
- WebViewImpl* web_view_impl = web_view_helper.GetWebView();
- ASSERT_TRUE(web_view_impl);
- LocalFrame* frame = web_view_impl->MainFrameImpl()->GetFrame();
- ASSERT_TRUE(frame);
-
- web_view_helper.Resize(WebSize(100, 200));
-
- // Scroll main frame to the bottom of the document
- web_view_impl->MainFrameImpl()->SetScrollOffset(WebSize(0, 400));
- EXPECT_EQ(ScrollOffset(0, 400),
- frame->View()->LayoutViewport()->GetScrollOffset());
-
- web_view_impl->SetPageScaleFactor(2.0);
-
- // Scroll visual viewport to the top of the main frame.
- VisualViewport& visual_viewport = frame->GetPage()->GetVisualViewport();
- visual_viewport.SetLocation(FloatPoint(0, 0));
- EXPECT_EQ(ScrollOffset(0, 0), visual_viewport.GetScrollOffset());
-
- // Tap at the top: there is nothing there.
- client.ResetTriggered();
- web_view_helper.GetWebView()->HandleInputEvent(FatTap(10, 60, kTapDiameter));
- EXPECT_FALSE(client.Triggered());
-
- // Scroll visual viewport to the bottom of the main frame.
- visual_viewport.SetLocation(FloatPoint(0, 200));
- EXPECT_EQ(ScrollOffset(0, 200), visual_viewport.GetScrollOffset());
-
- // Now the tap with the same coordinates should hit two elements.
- client.ResetTriggered();
- web_view_helper.GetWebView()->HandleInputEvent(FatTap(10, 60, kTapDiameter));
- EXPECT_TRUE(client.Triggered());
-
- // The same tap shouldn't trigger didTapMultipleTargets() after disabling the
- // notification for multi-target-tap.
- web_view_helper.GetWebView()
- ->GetSettings()
- ->SetMultiTargetTapNotificationEnabled(false);
- client.ResetTriggered();
- web_view_helper.GetWebView()->HandleInputEvent(FatTap(10, 60, kTapDiameter));
- EXPECT_FALSE(client.Triggered());
-}
-
-TEST_F(WebFrameTest, DisambiguationPopupBlacklist) {
- const unsigned kViewportWidth = 500;
- const unsigned kViewportHeight = 1000;
- const unsigned kDivHeight = 100;
- const std::string html_file = "disambiguation_popup_blacklist.html";
- RegisterMockedHttpURLLoad(html_file);
-
- DisambiguationPopupTestWebViewClient client;
- const int kTapDiameter = 100;
-
- // Make sure we initialize to minimum scale, even if the window size
- // only becomes available after the load begins.
- FrameTestHelpers::WebViewHelper web_view_helper;
- web_view_helper.InitializeAndLoad(base_url_ + html_file, nullptr, &client);
- web_view_helper.Resize(WebSize(kViewportWidth, kViewportHeight));
-
- // Click somewhere where the popup shouldn't appear.
- client.ResetTriggered();
- web_view_helper.GetWebView()->HandleInputEvent(
- FatTap(kViewportWidth / 2, 0, kTapDiameter));
- EXPECT_FALSE(client.Triggered());
-
- // Click directly in between two container divs with click handlers, with
- // children that don't handle clicks.
- client.ResetTriggered();
- web_view_helper.GetWebView()->HandleInputEvent(
- FatTap(kViewportWidth / 2, kDivHeight, kTapDiameter));
- EXPECT_TRUE(client.Triggered());
-
- // The third div container should be blacklisted if you click on the link it
- // contains.
- client.ResetTriggered();
- web_view_helper.GetWebView()->HandleInputEvent(
- FatTap(kViewportWidth / 2, kDivHeight * 3.25, kTapDiameter));
- EXPECT_FALSE(client.Triggered());
-}
-
-TEST_F(WebFrameTest, DisambiguationPopupPageScale) {
- RegisterMockedHttpURLLoad("disambiguation_popup_page_scale.html");
-
- DisambiguationPopupTestWebViewClient client;
- const int kTapDiameter = 50;
-
- // Make sure we initialize to minimum scale, even if the window size
- // only becomes available after the load begins.
- FrameTestHelpers::WebViewHelper web_view_helper;
- web_view_helper.InitializeAndLoad(
- base_url_ + "disambiguation_popup_page_scale.html", nullptr, &client);
- web_view_helper.Resize(WebSize(1000, 1000));
-
- client.ResetTriggered();
- web_view_helper.GetWebView()->HandleInputEvent(FatTap(80, 80, kTapDiameter));
- EXPECT_TRUE(client.Triggered());
-
- client.ResetTriggered();
- web_view_helper.GetWebView()->HandleInputEvent(
- FatTap(230, 190, kTapDiameter));
- EXPECT_TRUE(client.Triggered());
-
- web_view_helper.GetWebView()->SetPageScaleFactor(3.0f);
- web_view_helper.GetWebView()->UpdateAllLifecyclePhases();
-
- client.ResetTriggered();
- web_view_helper.GetWebView()->HandleInputEvent(
- FatTap(240, 240, kTapDiameter));
- EXPECT_TRUE(client.Triggered());
-
- client.ResetTriggered();
- web_view_helper.GetWebView()->HandleInputEvent(
- FatTap(690, 570, kTapDiameter));
- EXPECT_FALSE(client.Triggered());
-}
-
class TestSubstituteDataWebFrameClient
: public FrameTestHelpers::TestWebFrameClient {
public:
@@ -6997,7 +6740,7 @@ TEST_F(WebFrameTest, ReplaceMisspelledRange) {
document->GetFrame()
->GetSpellChecker()
- .GetIdleSpellCheckCallback()
+ .GetIdleSpellCheckController()
.ForceInvocationForTesting();
const int kAllTextBeginOffset = 0;
@@ -7012,7 +6755,7 @@ TEST_F(WebFrameTest, ReplaceMisspelledRange) {
EXPECT_EQ(1, textcheck.NumberOfTimesChecked());
EXPECT_EQ(1, NumMarkersInRange(document, selection_range,
- DocumentMarker::kSpelling));
+ DocumentMarker::MarkerTypes::Spelling()));
frame->ReplaceMisspelledRange("welcome");
EXPECT_EQ("_welcome_.", WebFrameContentDumper::DumpWebViewAsText(
@@ -7043,7 +6786,7 @@ TEST_F(WebFrameTest, RemoveSpellingMarkers) {
document->GetFrame()
->GetSpellChecker()
- .GetIdleSpellCheckCallback()
+ .GetIdleSpellCheckController()
.ForceInvocationForTesting();
frame->RemoveSpellingMarkers();
@@ -7059,7 +6802,7 @@ TEST_F(WebFrameTest, RemoveSpellingMarkers) {
.ToNormalizedEphemeralRange();
EXPECT_EQ(0, NumMarkersInRange(document, selection_range,
- DocumentMarker::kSpelling));
+ DocumentMarker::MarkerTypes::Spelling()));
}
static void GetSpellingMarkerOffsets(WebVector<unsigned>* offsets,
@@ -7093,7 +6836,7 @@ TEST_F(WebFrameTest, RemoveSpellingMarkersUnderWords) {
EXPECT_FALSE(exception_state.HadException());
frame->GetSpellChecker()
- .GetIdleSpellCheckCallback()
+ .GetIdleSpellCheckController()
.ForceInvocationForTesting();
WebVector<unsigned> offsets1;
@@ -7175,7 +6918,7 @@ TEST_F(WebFrameTest, SlowSpellcheckMarkerPosition) {
document->GetFrame()
->GetSpellChecker()
- .GetIdleSpellCheckCallback()
+ .GetIdleSpellCheckController()
.ForceInvocationForTesting();
textcheck.Kick();
@@ -7206,7 +6949,7 @@ TEST_F(WebFrameTest, SpellcheckResultErasesMarkers) {
document->GetFrame()
->GetSpellChecker()
- .GetIdleSpellCheckCallback()
+ .GetIdleSpellCheckController()
.ForceInvocationForTesting();
document->UpdateStyleAndLayout();
@@ -7243,7 +6986,7 @@ TEST_F(WebFrameTest, SpellcheckResultsSavedInDocument) {
document->GetFrame()
->GetSpellChecker()
- .GetIdleSpellCheckCallback()
+ .GetIdleSpellCheckController()
.ForceInvocationForTesting();
textcheck.Kick();
@@ -7258,7 +7001,7 @@ TEST_F(WebFrameTest, SpellcheckResultsSavedInDocument) {
document->GetFrame()
->GetSpellChecker()
- .GetIdleSpellCheckCallback()
+ .GetIdleSpellCheckController()
.ForceInvocationForTesting();
textcheck.KickGrammar();
@@ -7638,7 +7381,8 @@ TEST_F(WebFrameTest, ModifiedClickNewWindow) {
->Loader()
.StartNavigation(frame_request, WebFrameLoadType::kStandard,
NavigationPolicyFromEvent(event));
- FrameTestHelpers::PumpPendingRequestsForFrameToLoad();
+ FrameTestHelpers::PumpPendingRequestsForFrameToLoad(
+ web_view_helper.LocalMainFrame());
// decidePolicyForNavigation should be called for the ctrl+click.
EXPECT_EQ(1, web_frame_client.DecidePolicyCallCount());
@@ -7694,7 +7438,8 @@ TEST_F(WebFrameTest, BackDuringChildFrameReload) {
history_item->GenerateResourceRequest(mojom::FetchCacheMode::kDefault);
main_frame->CommitNavigation(
WrappedResourceRequest(request), WebFrameLoadType::kBackForward, item,
- false, base::UnguessableToken::Create(), nullptr, WebNavigationTimings());
+ false, base::UnguessableToken::Create(), nullptr /* navigation_params */,
+ nullptr /* extra_data */);
FrameTestHelpers::ReloadFrame(child_frame);
EXPECT_EQ(item.UrlString(), main_frame->GetDocument().Url().GetString());
@@ -7713,7 +7458,8 @@ TEST_F(WebFrameTest, ReloadPost) {
"javascript:document.forms[0].submit()");
// Pump requests one more time after the javascript URL has executed to
// trigger the actual POST load request.
- FrameTestHelpers::PumpPendingRequestsForFrameToLoad();
+ FrameTestHelpers::PumpPendingRequestsForFrameToLoad(
+ web_view_helper.LocalMainFrame());
EXPECT_EQ(WebString::FromUTF8("POST"),
frame->GetDocumentLoader()->GetRequest().HttpMethod());
@@ -7868,7 +7614,8 @@ TEST_F(WebFrameTest, NavigateToSame) {
ToLocalFrame(web_view_helper.GetWebView()->GetPage()->MainFrame())
->Loader()
.StartNavigation(frame_request);
- FrameTestHelpers::PumpPendingRequestsForFrameToLoad();
+ FrameTestHelpers::PumpPendingRequestsForFrameToLoad(
+ web_view_helper.LocalMainFrame());
EXPECT_TRUE(client.FrameLoadTypeReloadSeen());
}
@@ -8226,7 +7973,8 @@ TEST_F(WebFrameTest, CurrentHistoryItem) {
// Before commit, there is no history item.
EXPECT_FALSE(main_frame_loader.GetDocumentLoader()->GetHistoryItem());
- FrameTestHelpers::PumpPendingRequestsForFrameToLoad();
+ FrameTestHelpers::PumpPendingRequestsForFrameToLoad(
+ web_view_helper.LocalMainFrame());
// After commit, there is.
HistoryItem* item = main_frame_loader.GetDocumentLoader()->GetHistoryItem();
@@ -10065,60 +9813,6 @@ TEST_F(WebFrameTest, FrameWidgetTest) {
helper.Reset();
}
-class MockDocumentThreadableLoaderClient
- : public DocumentThreadableLoaderClient {
- public:
- MockDocumentThreadableLoaderClient() : failed_(false) {}
- ~MockDocumentThreadableLoaderClient() override = default;
-
- // DocumentThreadableLoaderClient:
- void DidFail(const ResourceError&) override { failed_ = true; }
-
- void Reset() { failed_ = false; }
- bool Failed() { return failed_; }
-
- bool failed_;
-};
-
-// FIXME: This would be better as a unittest on DocumentThreadableLoader but it
-// requires spin-up of a frame. It may be possible to remove that requirement
-// and convert it to a unittest.
-TEST_F(WebFrameTest, LoaderOriginAccess) {
- FrameTestHelpers::WebViewHelper web_view_helper;
- web_view_helper.InitializeAndLoad("about:blank");
-
- SchemeRegistry::RegisterURLSchemeAsDisplayIsolated("chrome");
-
- // Cross-origin request.
- KURL resource_url("chrome://test.pdf");
- ResourceRequest request(resource_url);
- request.SetRequestContext(WebURLRequest::kRequestContextObject);
- request.SetFetchCredentialsMode(network::mojom::FetchCredentialsMode::kOmit);
- RegisterMockedChromeURLLoad("test.pdf");
-
- LocalFrame* frame(
- ToLocalFrame(web_view_helper.GetWebView()->GetPage()->MainFrame()));
-
- MockDocumentThreadableLoaderClient client;
- ThreadableLoaderOptions options;
-
- // First try to load the request with regular access. Should fail.
- request.SetFetchRequestMode(network::mojom::FetchRequestMode::kCORS);
- ResourceLoaderOptions resource_loader_options;
- DocumentThreadableLoader::LoadResourceSynchronously(
- *ThreadableLoadingContext::Create(*frame->GetDocument()), request, client,
- options, resource_loader_options);
- EXPECT_TRUE(client.Failed());
-
- client.Reset();
- // Try to load the request with cross origin access. Should succeed.
- request.SetFetchRequestMode(network::mojom::FetchRequestMode::kNoCORS);
- DocumentThreadableLoader::LoadResourceSynchronously(
- *ThreadableLoadingContext::Create(*frame->GetDocument()), request, client,
- options, resource_loader_options);
- EXPECT_FALSE(client.Failed());
-}
-
TEST_F(WebFrameTest, DetachRemoteFrame) {
FrameTestHelpers::WebViewHelper helper;
helper.InitializeRemote();
@@ -11689,6 +11383,7 @@ TEST_F(WebFrameSimTest, TickmarksDocumentRelative) {
frame_view->GetScrollableArea()->SetScrollOffset(ScrollOffset(3000, 1000),
kProgrammaticScroll);
WebFindOptions options;
+ options.run_synchronously_for_testing = true;
WebString search_text = WebString::FromUTF8("test");
const int kFindIdentifier = 12345;
EXPECT_TRUE(frame->Find(kFindIdentifier, search_text, options, false));
@@ -11697,8 +11392,6 @@ TEST_F(WebFrameSimTest, TickmarksDocumentRelative) {
frame->EnsureTextFinder().StartScopingStringMatches(kFindIdentifier,
search_text, options);
- RunPendingTasks();
-
// Get the tickmarks for the original find request.
Vector<IntRect> original_tickmarks;
frame_view->LayoutViewport()->GetTickmarks(original_tickmarks);
@@ -11752,6 +11445,7 @@ TEST_F(WebFrameSimTest, FindInPageSelectNextMatch) {
frame_view->GetScrollableArea()->SetScrollOffset(ScrollOffset(3000, 1000),
kProgrammaticScroll);
WebFindOptions options;
+ options.run_synchronously_for_testing = true;
WebString search_text = WebString::FromUTF8("test");
const int kFindIdentifier = 12345;
EXPECT_TRUE(frame->Find(kFindIdentifier, search_text, options, false));
@@ -11760,8 +11454,6 @@ TEST_F(WebFrameSimTest, FindInPageSelectNextMatch) {
frame->EnsureTextFinder().StartScopingStringMatches(kFindIdentifier,
search_text, options);
- RunPendingTasks();
-
WebVector<WebFloatRect> web_match_rects =
frame->EnsureTextFinder().FindMatchRects();
ASSERT_EQ(2ul, web_match_rects.size());
@@ -12768,16 +12460,18 @@ TEST_F(WebFrameTest, NavigatorPluginsClearedWhenPluginsDisabled) {
ScopedFakePluginRegistry fake_plugins;
FrameTestHelpers::WebViewHelper web_view_helper;
web_view_helper.Initialize();
- v8::HandleScope scope(v8::Isolate::GetCurrent());
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ v8::Local<v8::Context> context = isolate->GetCurrentContext();
+ v8::HandleScope scope(isolate);
v8::Local<v8::Value> result =
web_view_helper.LocalMainFrame()->ExecuteScriptAndReturnValue(
WebScriptSource("navigator.plugins.length"));
- EXPECT_NE(0, result->Int32Value());
+ EXPECT_NE(0, result->Int32Value(context).ToChecked());
web_view_helper.GetWebView()->GetPage()->GetSettings().SetPluginsEnabled(
false);
result = web_view_helper.LocalMainFrame()->ExecuteScriptAndReturnValue(
WebScriptSource("navigator.plugins.length"));
- EXPECT_EQ(0, result->Int32Value());
+ EXPECT_EQ(0, result->Int32Value(context).ToChecked());
}
TEST_F(WebFrameTest, RecordSameDocumentNavigationToHistogram) {
@@ -12878,6 +12572,8 @@ TEST_F(WebFrameTest, DidScrollCallbackAfterScrollableAreaChanges) {
cc_scroll_layer->SetScrollOffsetFromImplSide(gfx::ScrollOffset(0, 3));
}
+// Tests the integration between blink and cc with slimming paint where a layer
+// list is sent to cc.
class SlimmingPaintWebFrameTest : public PaintTestConfigurations,
public WebFrameTest {
public:
@@ -12907,6 +12603,13 @@ class SlimmingPaintWebFrameTest : public PaintTestConfigurations,
->content_layers.size();
}
+ cc::Layer* ContentLayerAt(size_t index) {
+ return paint_artifact_compositor()
+ ->GetExtraDataForTesting()
+ ->content_layers[index]
+ .get();
+ }
+
size_t ScrollHitTestLayerCount() {
return paint_artifact_compositor()
->GetExtraDataForTesting()
@@ -12927,11 +12630,9 @@ class SlimmingPaintWebFrameTest : public PaintTestConfigurations,
std::unique_ptr<FrameTestHelpers::WebViewHelper> web_view_helper_;
};
-INSTANTIATE_SPV2_TEST_CASE_P(SlimmingPaintWebFrameTest);
+INSTANTIATE_LAYER_LIST_TEST_CASE_P(SlimmingPaintWebFrameTest);
TEST_P(SlimmingPaintWebFrameTest, DidScrollCallbackAfterScrollableAreaChanges) {
- DCHECK(RuntimeEnabledFeatures::SlimmingPaintV2Enabled());
-
InitializeWithHTML(*WebView()->MainFrameImpl()->GetFrame(),
"<style>"
" #scrollable {"
@@ -12955,13 +12656,23 @@ TEST_P(SlimmingPaintWebFrameTest, DidScrollCallbackAfterScrollableAreaChanges) {
ToLayoutBox(scrollable->GetLayoutObject())->GetScrollableArea();
EXPECT_NE(nullptr, scrollable_area);
- EXPECT_EQ(ContentLayerCount(), 2u);
- EXPECT_EQ(ScrollHitTestLayerCount(), 1u);
+ auto initial_content_layer_count = ContentLayerCount();
+ auto initial_scroll_hit_test_layer_count = ScrollHitTestLayerCount();
+
+ cc::Layer* overflow_scroll_layer = nullptr;
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ overflow_scroll_layer = ScrollHitTestLayerAt(ScrollHitTestLayerCount() - 1);
+ } else {
+ overflow_scroll_layer = ContentLayerAt(ContentLayerCount() - 2);
+ }
+ EXPECT_TRUE(overflow_scroll_layer->scrollable());
+ EXPECT_EQ(overflow_scroll_layer->scroll_container_bounds(),
+ gfx::Size(100, 100));
// Ensure a synthetic impl-side scroll offset propagates to the scrollable
// area using the DidScroll callback.
EXPECT_EQ(ScrollOffset(), scrollable_area->GetScrollOffset());
- ScrollHitTestLayerAt(0)->SetScrollOffsetFromImplSide(gfx::ScrollOffset(0, 1));
+ overflow_scroll_layer->SetScrollOffsetFromImplSide(gfx::ScrollOffset(0, 1));
WebView()->UpdateAllLifecyclePhases();
EXPECT_EQ(ScrollOffset(0, 1), scrollable_area->GetScrollOffset());
@@ -12978,17 +12689,18 @@ TEST_P(SlimmingPaintWebFrameTest, DidScrollCallbackAfterScrollableAreaChanges) {
// The web scroll layer has not been deleted yet and we should be able to
// apply impl-side offsets without crashing.
- EXPECT_EQ(ScrollHitTestLayerCount(), 1u);
- ScrollHitTestLayerAt(0)->SetScrollOffsetFromImplSide(gfx::ScrollOffset(0, 3));
+ EXPECT_EQ(ContentLayerCount(), initial_content_layer_count);
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ EXPECT_EQ(ScrollHitTestLayerCount(), initial_scroll_hit_test_layer_count);
+ overflow_scroll_layer->SetScrollOffsetFromImplSide(gfx::ScrollOffset(0, 3));
WebView()->UpdateAllLifecyclePhases();
- EXPECT_EQ(ContentLayerCount(), 1u);
- EXPECT_EQ(ScrollHitTestLayerCount(), 0u);
+ EXPECT_LT(ContentLayerCount(), initial_content_layer_count);
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ EXPECT_LT(ScrollHitTestLayerCount(), initial_scroll_hit_test_layer_count);
}
TEST_P(SlimmingPaintWebFrameTest, FrameViewScroll) {
- DCHECK(RuntimeEnabledFeatures::SlimmingPaintV2Enabled());
-
InitializeWithHTML(*WebView()->MainFrameImpl()->GetFrame(),
"<style>"
" #forceScroll {"
@@ -13003,12 +12715,25 @@ TEST_P(SlimmingPaintWebFrameTest, FrameViewScroll) {
auto* scrollable_area = GetLocalFrameView()->LayoutViewport();
EXPECT_NE(nullptr, scrollable_area);
- EXPECT_EQ(ScrollHitTestLayerCount(), 1u);
+ cc::Layer* scroll_layer = nullptr;
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ EXPECT_EQ(ScrollHitTestLayerCount(), 1u);
+ scroll_layer = ScrollHitTestLayerAt(0);
+ } else {
+ // Find the last scroll layer.
+ for (size_t index = ContentLayerCount() - 1; index >= 0; index--) {
+ if (ContentLayerAt(index)->scrollable()) {
+ scroll_layer = ContentLayerAt(index);
+ break;
+ }
+ }
+ }
+ EXPECT_TRUE(scroll_layer->scrollable());
// Ensure a synthetic impl-side scroll offset propagates to the scrollable
// area using the DidScroll callback.
EXPECT_EQ(ScrollOffset(), scrollable_area->GetScrollOffset());
- ScrollHitTestLayerAt(0)->SetScrollOffsetFromImplSide(gfx::ScrollOffset(0, 1));
+ scroll_layer->SetScrollOffsetFromImplSide(gfx::ScrollOffset(0, 1));
WebView()->UpdateAllLifecyclePhases();
EXPECT_EQ(ScrollOffset(0, 1), scrollable_area->GetScrollOffset());
}
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 c13ddd736a1..20ebff56a21 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
@@ -32,6 +32,7 @@
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/dom/node.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/platform/weborigin/kurl.h"
namespace blink {
@@ -77,6 +78,16 @@ WebPoint WebHitTestResult::LocalPoint() const {
return RoundedIntPoint(private_->Result().LocalPoint());
}
+WebPoint WebHitTestResult::LocalPointWithoutContentBoxOffset() const {
+ IntPoint local_point = RoundedIntPoint(private_->Result().LocalPoint());
+ LayoutObject* object = private_->Result().GetLayoutObject();
+ if (object->IsBox()) {
+ LayoutBox* box = ToLayoutBox(object);
+ local_point.Move(-RoundedIntSize(box->PhysicalContentBoxOffset()));
+ }
+ return local_point;
+}
+
WebElement WebHitTestResult::UrlElement() const {
return WebElement(private_->Result().URLElement());
}
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 b6a4b95e83e..a60244e4495 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
@@ -44,6 +44,7 @@
#include "third_party/blink/renderer/core/events/web_input_event_conversion.h"
#include "third_party/blink/renderer/core/exported/web_settings_impl.h"
#include "third_party/blink/renderer/core/exported/web_view_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/local_frame_client.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
@@ -295,9 +296,6 @@ bool WebPagePopupImpl::InitializePage() {
page_->GetSettings().SetMinimumFontSize(main_settings.GetMinimumFontSize());
page_->GetSettings().SetMinimumLogicalFontSize(
main_settings.GetMinimumLogicalFontSize());
- // FIXME: Should we support enabling a11y while a popup is shown?
- page_->GetSettings().SetAccessibilityEnabled(
- main_settings.GetAccessibilityEnabled());
page_->GetSettings().SetScrollAnimatorEnabled(
main_settings.GetScrollAnimatorEnabled());
page_->GetSettings().SetAvailablePointerTypes(
@@ -338,7 +336,7 @@ void WebPagePopupImpl::PostMessageToPopup(const String& message) {
return;
ScriptForbiddenScope::AllowUserAgentScript allow_script;
if (LocalDOMWindow* window = ToLocalFrame(page_->MainFrame())->DomWindow())
- window->DispatchEvent(MessageEvent::Create(message));
+ window->DispatchEvent(*MessageEvent::Create(message));
}
void WebPagePopupImpl::DestroyPage() {
@@ -355,7 +353,10 @@ AXObject* WebPagePopupImpl::RootAXObject() {
Document* document = ToLocalFrame(page_->MainFrame())->GetDocument();
if (!document)
return nullptr;
- AXObjectCache* cache = document->GetOrCreateAXObjectCache();
+ AXObjectCache* cache = document->ExistingAXObjectCache();
+ // There should never be a circumstance when RootAXObject() is triggered
+ // and the AXObjectCache doesn't already exist. It's called when trying
+ // to attach the accessibility tree of the pop-up to the host page.
DCHECK(cache);
return ToAXObjectCacheBase(cache)->GetOrCreate(document->GetLayoutView());
}
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 be907d1f091..4b59070c543 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());
}
+double WebPerformance::InputForNavigationStart() const {
+ return MillisecondsToSeconds(private_->timing()->inputStart());
+}
+
double WebPerformance::UnloadEventEnd() const {
return MillisecondsToSeconds(private_->timing()->unloadEventEnd());
}
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 57e1b53a801..0444ed416f6 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
@@ -92,6 +92,8 @@
#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/paint/paint_layer.h"
+#include "third_party/blink/renderer/core/scroll/scroll_animator_base.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
#include "third_party/blink/renderer/platform/exported/wrapped_resource_response.h"
#include "third_party/blink/renderer/platform/geometry/layout_rect.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
@@ -101,8 +103,6 @@
#include "third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.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/scroll/scroll_animator_base.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
namespace blink {
@@ -246,28 +246,28 @@ void WebPluginContainerImpl::Hide() {
web_plugin_->UpdateVisibility(false);
}
-void WebPluginContainerImpl::HandleEvent(Event* event) {
+void WebPluginContainerImpl::HandleEvent(Event& event) {
// The events we pass are defined at:
// 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())
+ if (event.IsMouseEvent())
HandleMouseEvent(ToMouseEvent(event));
- else if (event->IsWheelEvent())
+ else if (event.IsWheelEvent())
HandleWheelEvent(ToWheelEvent(event));
- else if (event->IsKeyboardEvent())
+ else if (event.IsKeyboardEvent())
HandleKeyboardEvent(ToKeyboardEvent(event));
- else if (event->IsTouchEvent())
+ else if (event.IsTouchEvent())
HandleTouchEvent(ToTouchEvent(event));
- else if (event->IsGestureEvent())
+ else if (event.IsGestureEvent())
HandleGestureEvent(ToGestureEvent(event));
- else if (event->IsDragEvent() && web_plugin_->CanProcessDrag())
+ else if (event.IsDragEvent() && web_plugin_->CanProcessDrag())
HandleDragEvent(ToDragEvent(event));
// FIXME: it would be cleaner if EmbeddedContentView::HandleEvent returned
// true/false and HTMLPluginElement called SetDefaultHandled or
// DefaultEventHandler.
- if (!event->DefaultHandled())
+ if (!event.DefaultHandled())
element_->Node::DefaultEventHandler(event);
}
@@ -310,8 +310,30 @@ void WebPluginContainerImpl::SetPlugin(WebPlugin* plugin) {
void WebPluginContainerImpl::UsePluginAsFindHandler() {
WebLocalFrameImpl* frame =
WebLocalFrameImpl::FromFrame(element_->GetDocument().GetFrame());
- if (frame)
- frame->GetFindInPage()->SetPluginFindHandler(this);
+ if (!frame)
+ return;
+ frame->GetFindInPage()->SetPluginFindHandler(this);
+}
+
+void WebPluginContainerImpl::ReportFindInPageMatchCount(int identifier,
+ int total,
+ bool final_update) {
+ WebLocalFrameImpl* frame =
+ WebLocalFrameImpl::FromFrame(element_->GetDocument().GetFrame());
+ if (!frame)
+ return;
+ frame->GetFindInPage()->ReportFindInPageMatchCount(identifier, total,
+ final_update);
+}
+
+void WebPluginContainerImpl::ReportFindInPageSelection(int identifier,
+ int index) {
+ WebLocalFrameImpl* frame =
+ WebLocalFrameImpl::FromFrame(element_->GetDocument().GetFrame());
+ if (!frame)
+ return;
+ frame->GetFindInPage()->ReportFindInPageSelection(
+ identifier, index, blink::WebRect(), false /* final_update */);
}
float WebPluginContainerImpl::DeviceScaleFactor() {
@@ -453,14 +475,14 @@ void WebPluginContainerImpl::DispatchProgressEvent(const WebString& type,
event = ResourceProgressEvent::Create(type, length_computable, loaded,
total, url);
}
- element_->DispatchEvent(event);
+ element_->DispatchEvent(*event);
}
void WebPluginContainerImpl::EnqueueMessageEvent(
const WebDOMMessageEvent& event) {
if (!element_->GetExecutionContext())
return;
- element_->EnqueueEvent(event, TaskType::kInternalDefault);
+ element_->EnqueueEvent(*event, TaskType::kInternalDefault);
}
void WebPluginContainerImpl::Invalidate() {
@@ -786,7 +808,7 @@ void WebPluginContainerImpl::Trace(blink::Visitor* visitor) {
ContextClient::Trace(visitor);
}
-void WebPluginContainerImpl::HandleMouseEvent(MouseEvent* event) {
+void WebPluginContainerImpl::HandleMouseEvent(MouseEvent& event) {
// We cache the parent LocalFrameView here as the plugin widget could be
// deleted in the call to HandleEvent. See http://b/issue?id=1362948
LocalFrameView& parent = ParentFrameView();
@@ -794,18 +816,18 @@ void WebPluginContainerImpl::HandleMouseEvent(MouseEvent* event) {
// TODO(dtapuska): Move WebMouseEventBuilder into the anonymous namespace
// in this class.
WebMouseEventBuilder transformed_event(&parent, element_->GetLayoutObject(),
- *event);
+ event);
if (transformed_event.GetType() == WebInputEvent::kUndefined)
return;
- if (event->type() == EventTypeNames::mousedown)
+ if (event.type() == EventTypeNames::mousedown)
FocusPlugin();
WebCursorInfo cursor_info;
if (web_plugin_ && web_plugin_->HandleInputEvent(
WebCoalescedInputEvent(transformed_event),
cursor_info) != WebInputEventResult::kNotHandled)
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
// A windowless plugin can change the cursor in response to a mouse move
// event. We need to reflect the changed cursor in the frame view as the
@@ -817,61 +839,61 @@ void WebPluginContainerImpl::HandleMouseEvent(MouseEvent* event) {
cursor_info, &parent.GetFrame().LocalFrameRoot());
}
-void WebPluginContainerImpl::HandleDragEvent(MouseEvent* event) {
- DCHECK(event->IsDragEvent());
+void WebPluginContainerImpl::HandleDragEvent(MouseEvent& event) {
+ DCHECK(event.IsDragEvent());
WebDragStatus drag_status = kWebDragStatusUnknown;
- if (event->type() == EventTypeNames::dragenter)
+ if (event.type() == EventTypeNames::dragenter)
drag_status = kWebDragStatusEnter;
- else if (event->type() == EventTypeNames::dragleave)
+ else if (event.type() == EventTypeNames::dragleave)
drag_status = kWebDragStatusLeave;
- else if (event->type() == EventTypeNames::dragover)
+ else if (event.type() == EventTypeNames::dragover)
drag_status = kWebDragStatusOver;
- else if (event->type() == EventTypeNames::drop)
+ else if (event.type() == EventTypeNames::drop)
drag_status = kWebDragStatusDrop;
if (drag_status == kWebDragStatusUnknown)
return;
- DataTransfer* data_transfer = event->getDataTransfer();
+ DataTransfer* data_transfer = event.getDataTransfer();
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());
+ WebFloatPoint drag_screen_location(event.screenX(), event.screenY());
IntPoint location(FrameRect().Location());
- WebFloatPoint drag_location(event->AbsoluteLocation().X() - location.X(),
- event->AbsoluteLocation().Y() - location.Y());
+ WebFloatPoint drag_location(event.AbsoluteLocation().X() - location.X(),
+ event.AbsoluteLocation().Y() - location.Y());
web_plugin_->HandleDragStatusUpdate(drag_status, drag_data,
drag_operation_mask, drag_location,
drag_screen_location);
}
-void WebPluginContainerImpl::HandleWheelEvent(WheelEvent* event) {
- WebFloatPoint absolute_location = event->NativeEvent().PositionInRootFrame();
+void WebPluginContainerImpl::HandleWheelEvent(WheelEvent& event) {
+ WebFloatPoint absolute_location = event.NativeEvent().PositionInRootFrame();
// Translate the root frame position to content coordinates.
absolute_location = ParentFrameView().ConvertFromRootFrame(absolute_location);
FloatPoint local_point = element_->GetLayoutObject()->AbsoluteToLocal(
absolute_location, kUseTransforms);
- WebMouseWheelEvent translated_event = event->NativeEvent().FlattenTransform();
+ WebMouseWheelEvent translated_event = event.NativeEvent().FlattenTransform();
translated_event.SetPositionInWidget(local_point.X(), local_point.Y());
WebCursorInfo cursor_info;
if (web_plugin_->HandleInputEvent(WebCoalescedInputEvent(translated_event),
cursor_info) !=
WebInputEventResult::kNotHandled)
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
}
-void WebPluginContainerImpl::HandleKeyboardEvent(KeyboardEvent* event) {
- WebKeyboardEventBuilder web_event(*event);
+void WebPluginContainerImpl::HandleKeyboardEvent(KeyboardEvent& event) {
+ WebKeyboardEventBuilder web_event(event);
if (web_event.GetType() == WebInputEvent::kUndefined)
return;
if (HandleCutCopyPasteKeyboardEvent(web_event)) {
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
return;
}
@@ -885,7 +907,7 @@ void WebPluginContainerImpl::HandleKeyboardEvent(KeyboardEvent* event) {
if (web_plugin_->HandleInputEvent(WebCoalescedInputEvent(web_event),
cursor_info) !=
WebInputEventResult::kNotHandled) {
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
}
}
@@ -967,25 +989,25 @@ WebCoalescedInputEvent WebPluginContainerImpl::TransformCoalescedTouchEvent(
return transformed_event;
}
-void WebPluginContainerImpl::HandleTouchEvent(TouchEvent* event) {
+void WebPluginContainerImpl::HandleTouchEvent(TouchEvent& event) {
switch (touch_event_request_type_) {
case kTouchEventRequestTypeNone:
return;
case kTouchEventRequestTypeRaw:
case kTouchEventRequestTypeRawLowLatency: {
- if (!event->NativeEvent())
+ if (!event.NativeEvent())
return;
- if (event->type() == EventTypeNames::touchstart)
+ if (event.type() == EventTypeNames::touchstart)
FocusPlugin();
WebCoalescedInputEvent transformed_event =
- TransformCoalescedTouchEvent(*event->NativeEvent());
+ TransformCoalescedTouchEvent(*event.NativeEvent());
WebCursorInfo cursor_info;
if (web_plugin_->HandleInputEvent(transformed_event, cursor_info) !=
WebInputEventResult::kNotHandled)
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
// FIXME: Can a plugin change the cursor from a touch-event callback?
return;
}
@@ -995,17 +1017,17 @@ void WebPluginContainerImpl::HandleTouchEvent(TouchEvent* event) {
}
}
-void WebPluginContainerImpl::HandleGestureEvent(GestureEvent* event) {
- if (event->NativeEvent().GetType() == WebInputEvent::kUndefined)
+void WebPluginContainerImpl::HandleGestureEvent(GestureEvent& event) {
+ if (event.NativeEvent().GetType() == WebInputEvent::kUndefined)
return;
- if (event->NativeEvent().GetType() == WebInputEvent::kGestureTapDown)
+ if (event.NativeEvent().GetType() == WebInputEvent::kGestureTapDown)
FocusPlugin();
// Take a copy of the event and translate it into the coordinate
// system of the plugin.
- WebGestureEvent translated_event = event->NativeEvent();
+ WebGestureEvent translated_event = event.NativeEvent();
WebFloatPoint absolute_root_frame_location =
- event->NativeEvent().PositionInRootFrame();
+ event.NativeEvent().PositionInRootFrame();
FloatPoint local_point = element_->GetLayoutObject()->AbsoluteToLocal(
absolute_root_frame_location, kUseTransforms);
translated_event.FlattenTransform();
@@ -1015,16 +1037,16 @@ void WebPluginContainerImpl::HandleGestureEvent(GestureEvent* event) {
if (web_plugin_->HandleInputEvent(WebCoalescedInputEvent(translated_event),
cursor_info) !=
WebInputEventResult::kNotHandled) {
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
return;
}
// FIXME: Can a plugin change the cursor from a touch-event callback?
}
-void WebPluginContainerImpl::SynthesizeMouseEventIfPossible(TouchEvent* event) {
+void WebPluginContainerImpl::SynthesizeMouseEventIfPossible(TouchEvent& event) {
WebMouseEventBuilder web_event(&ParentFrameView(),
- element_->GetLayoutObject(), *event);
+ element_->GetLayoutObject(), event);
if (web_event.GetType() == WebInputEvent::kUndefined)
return;
@@ -1032,7 +1054,7 @@ void WebPluginContainerImpl::SynthesizeMouseEventIfPossible(TouchEvent* event) {
if (web_plugin_->HandleInputEvent(WebCoalescedInputEvent(web_event),
cursor_info) !=
WebInputEventResult::kNotHandled)
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
}
void WebPluginContainerImpl::FocusPlugin() {
@@ -1064,7 +1086,7 @@ void WebPluginContainerImpl::ComputeClipRectsForPlugin(
// the containing view space, and rounded off. See
// LayoutEmbeddedContent::UpdateGeometry. To remove the lossy effect of
// rounding off, use contentBoxRect directly.
- LayoutRect unclipped_absolute_rect(box->ContentBoxRect());
+ LayoutRect unclipped_absolute_rect(box->PhysicalContentBoxRect());
box->MapToVisualRectInAncestorSpace(root_view, unclipped_absolute_rect);
unclipped_absolute_rect =
box->View()->GetFrameView()->DocumentToFrame(unclipped_absolute_rect);
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 d6a40e48c2e..a03415edb35 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
@@ -114,7 +114,7 @@ class CORE_EXPORT WebPluginContainerImpl final
void UpdateAllLifecyclePhases();
void InvalidateRect(const IntRect&);
void SetFocused(bool, WebFocusType);
- void HandleEvent(Event*);
+ void HandleEvent(Event&);
bool IsErrorplaceholder();
void EventListenersRemoved();
void InvalidatePaint() {}
@@ -148,6 +148,10 @@ class CORE_EXPORT WebPluginContainerImpl final
void SetPlugin(WebPlugin*) override;
void UsePluginAsFindHandler() override;
+ void ReportFindInPageMatchCount(int identifier,
+ int total,
+ bool final_update) override;
+ void ReportFindInPageSelection(int identifier, int index) override;
float DeviceScaleFactor() override;
float PageScaleFactor() override;
@@ -217,15 +221,15 @@ class CORE_EXPORT WebPluginContainerImpl final
WebCoalescedInputEvent TransformCoalescedTouchEvent(
const WebCoalescedInputEvent&);
- void HandleMouseEvent(MouseEvent*);
- void HandleDragEvent(MouseEvent*);
- void HandleWheelEvent(WheelEvent*);
- void HandleKeyboardEvent(KeyboardEvent*);
+ void HandleMouseEvent(MouseEvent&);
+ void HandleDragEvent(MouseEvent&);
+ void HandleWheelEvent(WheelEvent&);
+ void HandleKeyboardEvent(KeyboardEvent&);
bool HandleCutCopyPasteKeyboardEvent(const WebKeyboardEvent&);
- void HandleTouchEvent(TouchEvent*);
- void HandleGestureEvent(GestureEvent*);
+ void HandleTouchEvent(TouchEvent&);
+ void HandleGestureEvent(GestureEvent&);
- void SynthesizeMouseEventIfPossible(TouchEvent*);
+ void SynthesizeMouseEventIfPossible(TouchEvent&);
void FocusPlugin();
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 3a289592911..a9a5cb0e3f2 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
@@ -267,7 +267,7 @@ void CreateAndHandleKeyboardEvent(WebElement* plugin_container_one_element,
web_keyboard_event.windows_key_code = key_code;
KeyboardEvent* key_event = KeyboardEvent::Create(web_keyboard_event, nullptr);
ToWebPluginContainerImpl(plugin_container_one_element->PluginContainer())
- ->HandleEvent(key_event);
+ ->HandleEvent(*key_event);
}
void ExecuteContextMenuCommand(WebViewImpl* web_view,
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 b2add6c5df8..d1876f47a2e 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
@@ -19,6 +19,7 @@
#include "third_party/blink/renderer/core/execution_context/security_context.h"
#include "third_party/blink/renderer/core/exported/web_view_impl.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/remote_frame_client_impl.h"
#include "third_party/blink/renderer/core/frame/remote_frame_owner.h"
diff --git a/chromium/third_party/blink/renderer/core/exported/web_security_policy.cc b/chromium/third_party/blink/renderer/core/exported/web_security_policy.cc
index b49ba1e5a5d..4ee1bb58c79 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_security_policy.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_security_policy.cc
@@ -65,60 +65,36 @@ void WebSecurityPolicy::RegisterURLSchemeAsFirstPartyWhenTopLevel(
SchemeRegistry::RegisterURLSchemeAsFirstPartyWhenTopLevel(scheme);
}
-void WebSecurityPolicy::AddOriginAccessWhitelistEntry(
+void WebSecurityPolicy::AddOriginAccessAllowListEntry(
const WebURL& source_origin,
const WebString& destination_protocol,
const WebString& destination_host,
bool allow_destination_subdomains) {
- SecurityPolicy::AddOriginAccessWhitelistEntry(
+ SecurityPolicy::AddOriginAccessAllowListEntry(
*SecurityOrigin::Create(source_origin), destination_protocol,
destination_host, allow_destination_subdomains);
}
-void WebSecurityPolicy::RemoveOriginAccessWhitelistEntry(
- const WebURL& source_origin,
- const WebString& destination_protocol,
- const WebString& destination_host,
- bool allow_destination_subdomains) {
- SecurityPolicy::RemoveOriginAccessWhitelistEntry(
- *SecurityOrigin::Create(source_origin), destination_protocol,
- destination_host, allow_destination_subdomains);
-}
-
-void WebSecurityPolicy::RemoveAllOriginAccessWhitelistEntriesForOrigin(
+void WebSecurityPolicy::ClearOriginAccessAllowListForOrigin(
const WebURL& source_origin) {
- SecurityPolicy::RemoveAllOriginAccessWhitelistEntriesForOrigin(
+ SecurityPolicy::ClearOriginAccessAllowListForOrigin(
*SecurityOrigin::Create(source_origin));
}
-void WebSecurityPolicy::ResetOriginAccessWhitelists() {
- SecurityPolicy::ResetOriginAccessWhitelists();
-}
-
-void WebSecurityPolicy::AddOriginAccessBlacklistEntry(
- const WebURL& source_origin,
- const WebString& destination_protocol,
- const WebString& destination_host,
- bool allow_destination_subdomains) {
- SecurityPolicy::AddOriginAccessBlacklistEntry(
- *SecurityOrigin::Create(source_origin), destination_protocol,
- destination_host, allow_destination_subdomains);
+void WebSecurityPolicy::ClearOriginAccessAllowList() {
+ SecurityPolicy::ClearOriginAccessAllowList();
}
-void WebSecurityPolicy::RemoveOriginAccessBlacklistEntry(
+void WebSecurityPolicy::AddOriginAccessBlockListEntry(
const WebURL& source_origin,
const WebString& destination_protocol,
const WebString& destination_host,
bool allow_destination_subdomains) {
- SecurityPolicy::RemoveOriginAccessBlacklistEntry(
+ SecurityPolicy::AddOriginAccessBlockListEntry(
*SecurityOrigin::Create(source_origin), destination_protocol,
destination_host, allow_destination_subdomains);
}
-void WebSecurityPolicy::ResetOriginAccessBlacklists() {
- SecurityPolicy::ResetOriginAccessBlacklists();
-}
-
void WebSecurityPolicy::AddOriginTrustworthyWhiteList(const WebString& origin) {
SecurityPolicy::AddOriginTrustworthyWhiteList(origin);
}
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 4760b2c18b4..95ddf7175e2 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
@@ -47,7 +47,6 @@ WebSettingsImpl::WebSettingsImpl(Settings* settings,
render_v_sync_notification_enabled_(false),
auto_zoom_focused_node_to_legible_scale_(false),
support_deprecated_target_density_dpi_(false),
- shrinks_viewport_content_to_fit_(false),
viewport_meta_layout_size_quirk_(false),
viewport_meta_non_user_scalable_quirk_(false),
clobber_user_agent_initial_scale_quirk_(false) {
@@ -71,8 +70,8 @@ void WebSettingsImpl::SetFixedFontFamily(const WebString& font,
settings_->NotifyGenericFontFamilyChange();
}
-void WebSettingsImpl::SetFMPNetworkQuietTimeout(double timeout) {
- settings_->SetFMPNetworkQuietTimeout(timeout);
+void WebSettingsImpl::SetNetworkQuietTimeout(double timeout) {
+ settings_->SetNetworkQuietTimeout(timeout);
}
void WebSettingsImpl::SetForceMainWorldInitialization(bool enabled) {
@@ -160,10 +159,6 @@ void WebSettingsImpl::SetAccessibilityFontScaleFactor(float font_scale_factor) {
settings_->SetAccessibilityFontScaleFactor(font_scale_factor);
}
-void WebSettingsImpl::SetAccessibilityEnabled(bool enabled) {
- settings_->SetAccessibilityEnabled(enabled);
-}
-
void WebSettingsImpl::SetAccessibilityPasswordValuesEnabled(bool enabled) {
settings_->SetAccessibilityPasswordValuesEnabled(enabled);
}
@@ -305,7 +300,7 @@ void WebSettingsImpl::SetDOMPasteAllowed(bool enabled) {
void WebSettingsImpl::SetShrinksViewportContentToFit(
bool shrink_viewport_content) {
- shrinks_viewport_content_to_fit_ = shrink_viewport_content;
+ settings_->SetShrinksViewportContentToFit(shrink_viewport_content);
}
void WebSettingsImpl::SetSpatialNavigationEnabled(bool enabled) {
@@ -593,14 +588,6 @@ void WebSettingsImpl::SetEnableTouchAdjustment(bool enabled) {
settings_->SetTouchAdjustmentEnabled(enabled);
}
-bool WebSettingsImpl::MultiTargetTapNotificationEnabled() {
- return settings_->GetMultiTargetTapNotificationEnabled();
-}
-
-void WebSettingsImpl::SetMultiTargetTapNotificationEnabled(bool enabled) {
- settings_->SetMultiTargetTapNotificationEnabled(enabled);
-}
-
bool WebSettingsImpl::ViewportEnabled() const {
return settings_->GetViewportEnabled();
}
@@ -618,7 +605,7 @@ bool WebSettingsImpl::MockGestureTapHighlightsEnabled() const {
}
bool WebSettingsImpl::ShrinksViewportContentToFit() const {
- return shrinks_viewport_content_to_fit_;
+ return settings_->GetShrinksViewportContentToFit();
}
void WebSettingsImpl::SetShouldRespectImageOrientation(bool enabled) {
@@ -758,4 +745,41 @@ void WebSettingsImpl::SetLazyFrameLoadingDistanceThresholdPx4G(
settings_->SetLazyFrameLoadingDistanceThresholdPx4G(distance_px);
}
+void WebSettingsImpl::SetLazyImageLoadingDistanceThresholdPxUnknown(
+ int distance_px) {
+ settings_->SetLazyImageLoadingDistanceThresholdPxUnknown(distance_px);
+}
+
+void WebSettingsImpl::SetLazyImageLoadingDistanceThresholdPxOffline(
+ int distance_px) {
+ settings_->SetLazyImageLoadingDistanceThresholdPxOffline(distance_px);
+}
+
+void WebSettingsImpl::SetLazyImageLoadingDistanceThresholdPxSlow2G(
+ int distance_px) {
+ settings_->SetLazyImageLoadingDistanceThresholdPxSlow2G(distance_px);
+}
+
+void WebSettingsImpl::SetLazyImageLoadingDistanceThresholdPx2G(
+ int distance_px) {
+ settings_->SetLazyImageLoadingDistanceThresholdPx2G(distance_px);
+}
+
+void WebSettingsImpl::SetLazyImageLoadingDistanceThresholdPx3G(
+ int distance_px) {
+ settings_->SetLazyImageLoadingDistanceThresholdPx3G(distance_px);
+}
+
+void WebSettingsImpl::SetLazyImageLoadingDistanceThresholdPx4G(
+ int distance_px) {
+ settings_->SetLazyImageLoadingDistanceThresholdPx4G(distance_px);
+}
+
+STATIC_ASSERT_ENUM(WebSettings::kImageAnimationPolicyAllowed,
+ kImageAnimationPolicyAllowed);
+STATIC_ASSERT_ENUM(WebSettings::kImageAnimationPolicyAnimateOnce,
+ kImageAnimationPolicyAnimateOnce);
+STATIC_ASSERT_ENUM(WebSettings::kImageAnimationPolicyNoAnimation,
+ kImageAnimationPolicyNoAnimation);
+
} // namespace blink
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 8dc554aa52b..36c9adb1993 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
@@ -54,7 +54,6 @@ class CORE_EXPORT WebSettingsImpl final : public WebSettings {
void SetAcceleratedCompositingEnabled(bool) override;
void SetAutoplayPolicy(AutoplayPolicy) override;
void SetPreferCompositingToLCDTextEnabled(bool) override;
- void SetAccessibilityEnabled(bool) override;
void SetAccessibilityPasswordValuesEnabled(bool) override;
void SetAllowFileAccessFromFileURLs(bool) override;
void SetAllowCustomScrollbarInMainFrame(bool) override;
@@ -85,15 +84,13 @@ class CORE_EXPORT WebSettingsImpl final : public WebSettings {
void SetEditingBehavior(EditingBehavior) override;
void SetEnableScrollAnimator(bool) override;
void SetEnableTouchAdjustment(bool) override;
- bool MultiTargetTapNotificationEnabled() override;
- void SetMultiTargetTapNotificationEnabled(bool) override;
void SetWebGL1Enabled(bool) override;
void SetWebGL2Enabled(bool) override;
void SetFantasyFontFamily(const WebString&,
UScriptCode = USCRIPT_COMMON) override;
void SetFixedFontFamily(const WebString&,
UScriptCode = USCRIPT_COMMON) override;
- void SetFMPNetworkQuietTimeout(double timeout) override;
+ void SetNetworkQuietTimeout(double timeout) override;
void SetForceMainWorldInitialization(bool) override;
void SetForcePreloadNoneForMediaElements(bool) override;
void SetForceZeroLayoutHeight(bool) override;
@@ -207,12 +204,21 @@ class CORE_EXPORT WebSettingsImpl final : public WebSettings {
void SetDoNotUpdateSelectionOnMutatingSelectionRange(bool) override;
void SetMediaDownloadInProductHelpEnabled(bool) override;
void SetLowPriorityIframesThreshold(WebEffectiveConnectionType) override;
+
+ // TODO(rajendrant): Remove these lazyload distance threshold settings for
+ // frames and images, once the values are finalized from the experiment.
void SetLazyFrameLoadingDistanceThresholdPxUnknown(int) override;
void SetLazyFrameLoadingDistanceThresholdPxOffline(int) override;
void SetLazyFrameLoadingDistanceThresholdPxSlow2G(int) override;
void SetLazyFrameLoadingDistanceThresholdPx2G(int) override;
void SetLazyFrameLoadingDistanceThresholdPx3G(int) override;
void SetLazyFrameLoadingDistanceThresholdPx4G(int) override;
+ void SetLazyImageLoadingDistanceThresholdPxUnknown(int) override;
+ void SetLazyImageLoadingDistanceThresholdPxOffline(int) override;
+ void SetLazyImageLoadingDistanceThresholdPxSlow2G(int) override;
+ void SetLazyImageLoadingDistanceThresholdPx2G(int) override;
+ void SetLazyImageLoadingDistanceThresholdPx3G(int) override;
+ void SetLazyImageLoadingDistanceThresholdPx4G(int) override;
bool ShowFPSCounter() const { return show_fps_counter_; }
bool ShowPaintRects() const { return show_paint_rects_; }
@@ -250,7 +256,6 @@ class CORE_EXPORT WebSettingsImpl final : public WebSettings {
bool auto_zoom_focused_node_to_legible_scale_;
bool per_tile_painting_enabled_;
bool support_deprecated_target_density_dpi_;
- bool shrinks_viewport_content_to_fit_;
// This quirk is to maintain compatibility with Android apps built on
// the Android SDK prior to and including version 18. Presumably, this
// can be removed any time after 2015. See http://crbug.com/277369.
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 7ed15f2edac..f62c5445922 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
@@ -49,7 +49,6 @@
#include "third_party/blink/renderer/core/inspector/console_message.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/threadable_loading_context.h"
#include "third_party/blink/renderer/core/loader/worker_fetch_context.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/core/script/script.h"
@@ -129,13 +128,13 @@ void WebSharedWorkerImpl::OnShadowPageInitialized() {
network::mojom::FetchRequestMode::kSameOrigin;
network::mojom::FetchCredentialsMode fetch_credentials_mode =
network::mojom::FetchCredentialsMode::kSameOrigin;
- if ((static_cast<KURL>(url_)).ProtocolIsData()) {
+ if ((static_cast<KURL>(script_request_url_)).ProtocolIsData()) {
fetch_request_mode = network::mojom::FetchRequestMode::kNoCORS;
fetch_credentials_mode = network::mojom::FetchCredentialsMode::kInclude;
}
- main_script_loader_->LoadAsynchronously(
- *shadow_page_->GetDocument(), url_,
+ main_script_loader_->LoadTopLevelScriptAsynchronously(
+ *shadow_page_->GetDocument(), script_request_url_,
WebURLRequest::kRequestContextSharedWorker, fetch_request_mode,
fetch_credentials_mode, creation_address_space_,
Bind(&WebSharedWorkerImpl::DidReceiveScriptLoaderResponse,
@@ -152,7 +151,7 @@ void WebSharedWorkerImpl::ResumeStartup() {
is_paused_on_start_ = false;
if (is_paused_on_start) {
// We'll continue in OnShadowPageInitialized().
- shadow_page_->Initialize(url_);
+ shadow_page_->Initialize(script_request_url_);
}
}
@@ -205,11 +204,11 @@ void WebSharedWorkerImpl::ConnectTaskOnWorkerThread(
MessagePort* port = MessagePort::Create(*worker_global_scope);
port->Entangle(std::move(channel));
SECURITY_DCHECK(worker_global_scope->IsSharedWorkerGlobalScope());
- worker_global_scope->DispatchEvent(CreateConnectEvent(port));
+ worker_global_scope->DispatchEvent(*CreateConnectEvent(port));
}
void WebSharedWorkerImpl::StartWorkerContext(
- const WebURL& url,
+ const WebURL& script_request_url,
const WebString& name,
const WebString& content_security_policy,
WebContentSecurityPolicyType policy_type,
@@ -220,7 +219,7 @@ void WebSharedWorkerImpl::StartWorkerContext(
mojo::ScopedMessagePipeHandle content_settings_handle,
mojo::ScopedMessagePipeHandle interface_provider) {
DCHECK(IsMainThread());
- url_ = url;
+ script_request_url_ = script_request_url;
name_ = name;
creation_address_space_ = creation_address_space;
// Chrome doesn't use interface versioning.
@@ -245,7 +244,7 @@ void WebSharedWorkerImpl::StartWorkerContext(
}
// We'll continue in OnShadowPageInitialized().
- shadow_page_->Initialize(url_);
+ shadow_page_->Initialize(script_request_url_);
}
void WebSharedWorkerImpl::DidReceiveScriptLoaderResponse() {
@@ -320,7 +319,7 @@ void WebSharedWorkerImpl::ContinueOnScriptLoaderFinished() {
std::move(web_worker_fetch_context));
ContentSecurityPolicy* content_security_policy =
- main_script_loader_->ReleaseContentSecurityPolicy();
+ main_script_loader_->GetContentSecurityPolicy();
ReferrerPolicy referrer_policy = kReferrerPolicyDefault;
if (!main_script_loader_->GetReferrerPolicy().IsNull()) {
SecurityPolicy::ReferrerPolicyFromHeaderValue(
@@ -334,13 +333,19 @@ void WebSharedWorkerImpl::ContinueOnScriptLoaderFinished() {
// (https://crbug.com/824646)
ScriptType script_type = ScriptType::kClassic;
+ const KURL script_response_url = main_script_loader_->ResponseURL();
+ DCHECK(static_cast<KURL>(script_request_url_) == script_response_url ||
+ SecurityOrigin::AreSameSchemeHostPort(script_request_url_,
+ script_response_url));
+
auto global_scope_creation_params =
std::make_unique<GlobalScopeCreationParams>(
- url_, script_type, document->UserAgent(),
+ script_response_url, script_type, document->UserAgent(),
content_security_policy ? content_security_policy->Headers()
: Vector<CSPHeaderAndType>(),
referrer_policy, starter_origin, starter_secure_context,
- worker_clients, main_script_loader_->ResponseAddressSpace(),
+ document->GetHttpsState(), worker_clients,
+ main_script_loader_->ResponseAddressSpace(),
main_script_loader_->OriginTrialTokens(), devtools_worker_token_,
std::move(worker_settings), kV8CacheOptionsDefault,
nullptr /* worklet_module_response_map */,
@@ -349,8 +354,8 @@ void WebSharedWorkerImpl::ContinueOnScriptLoaderFinished() {
reporting_proxy_ = new SharedWorkerReportingProxy(
this, parent_execution_context_task_runners_);
- worker_thread_ = std::make_unique<SharedWorkerThread>(
- name_, ThreadableLoadingContext::Create(*document), *reporting_proxy_);
+ worker_thread_ =
+ std::make_unique<SharedWorkerThread>(name_, *reporting_proxy_);
probe::scriptImported(document, main_script_loader_->Identifier(),
main_script_loader_->SourceText());
main_script_loader_ = nullptr;
@@ -364,9 +369,9 @@ void WebSharedWorkerImpl::ContinueOnScriptLoaderFinished() {
worker_inspector_proxy_->ShouldPauseOnWorkerStart(document),
parent_execution_context_task_runners_);
worker_inspector_proxy_->WorkerThreadCreated(document, GetWorkerThread(),
- url_);
+ script_response_url);
// TODO(nhiroki): Support module workers (https://crbug.com/680046).
- GetWorkerThread()->EvaluateClassicScript(url_, source_code,
+ GetWorkerThread()->EvaluateClassicScript(script_response_url, source_code,
nullptr /* cached_meta_data */,
v8_inspector::V8StackTraceId());
client_->WorkerScriptLoaded();
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 c7ba68eade9..cee87b6d28c 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
@@ -146,7 +146,7 @@ class CORE_EXPORT WebSharedWorkerImpl final : public WebSharedWorker,
// Kept around only while main script loading is ongoing.
scoped_refptr<WorkerClassicScriptLoader> main_script_loader_;
- WebURL url_;
+ WebURL script_request_url_;
WebString name_;
mojom::IPAddressSpace creation_address_space_;
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 2acc5921abe..1dfa732a6a7 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
@@ -95,6 +95,7 @@
#include "third_party/blink/renderer/core/frame/event_handler_registry.h"
#include "third_party/blink/renderer/core/frame/fullscreen_controller.h"
#include "third_party/blink/renderer/core/frame/link_highlights.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"
@@ -132,28 +133,22 @@
#include "third_party/blink/renderer/core/page/focus_controller.h"
#include "third_party/blink/renderer/core/page/frame_tree.h"
#include "third_party/blink/renderer/core/page/page.h"
-#include "third_party/blink/renderer/core/page/page_overlay.h"
#include "third_party/blink/renderer/core/page/page_popup_client.h"
#include "third_party/blink/renderer/core/page/pointer_lock_controller.h"
#include "third_party/blink/renderer/core/page/scrolling/top_document_root_scroller_controller.h"
-#include "third_party/blink/renderer/core/page/touch_disambiguation.h"
-#include "third_party/blink/renderer/core/page/validation_message_client_impl.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/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/animation/compositor_animation_host.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/geometry/float_rect.h"
#include "third_party/blink/renderer/platform/graphics/compositor_mutator_client.h"
#include "third_party/blink/renderer/platform/graphics/compositor_mutator_impl.h"
#include "third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h"
-#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
#include "third_party/blink/renderer/platform/graphics/image.h"
-#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
#include "third_party/blink/renderer/platform/histogram.h"
#include "third_party/blink/renderer/platform/image-decoders/image_decoder.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
@@ -163,7 +158,6 @@
#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/scheduler/public/thread_scheduler.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h"
#include "third_party/blink/renderer/platform/weborigin/scheme_registry.h"
#include "third_party/blink/renderer/platform/wtf/time.h"
@@ -186,7 +180,6 @@ static const float doubleTapZoomContentMinimumMargin = 2;
static const double doubleTapZoomAnimationDurationInSeconds = 0.25;
static const float doubleTapZoomAlreadyLegibleRatio = 1.2f;
-static const double multipleTargetsZoomAnimationDurationInSeconds = 0.25;
static const double findInPageAnimationDurationInSeconds = 0;
// Constants for viewport anchoring on resize.
@@ -261,26 +254,6 @@ class EmptyEventListener final : public EventListener {
void handleEvent(ExecutionContext* execution_context, Event*) override {}
};
-class ColorOverlay final : public PageOverlay::Delegate {
- public:
- explicit ColorOverlay(SkColor color) : color_(color) {}
-
- private:
- void PaintPageOverlay(const PageOverlay& page_overlay,
- GraphicsContext& graphics_context,
- const IntSize& size) const override {
- if (DrawingRecorder::UseCachedDrawingIfPossible(
- graphics_context, page_overlay, DisplayItem::kPageOverlay))
- return;
- FloatRect rect(0, 0, size.Width(), size.Height());
- DrawingRecorder recorder(graphics_context, page_overlay,
- DisplayItem::kPageOverlay);
- graphics_context.FillRect(rect, color_);
- }
-
- SkColor color_;
-};
-
} // namespace
// WebView ----------------------------------------------------------------
@@ -368,7 +341,6 @@ WebViewImpl::WebViewImpl(WebViewClient* client,
page_ =
Page::CreateOrdinary(page_clients, opener ? opener->GetPage() : nullptr);
CoreInitializer::GetInstance().ProvideModulesToPage(*page_, client_);
- page_->SetValidationMessageClient(ValidationMessageClientImpl::Create(*this));
SetVisibilityState(visibility_state, true);
InitializeLayerTreeView();
@@ -385,10 +357,6 @@ WebViewImpl::~WebViewImpl() {
DCHECK(!page_);
}
-ValidationMessageClient* WebViewImpl::GetValidationMessageClient() const {
- return page_ ? &page_->GetValidationMessageClient() : nullptr;
-}
-
WebDevToolsAgentImpl* WebViewImpl::MainFrameDevToolsAgentImpl() {
WebLocalFrameImpl* main_frame = MainFrameImpl();
return main_frame ? main_frame->DevToolsAgentImpl() : nullptr;
@@ -609,54 +577,6 @@ WebInputEventResult WebViewImpl::HandleGestureEvent(
switch (event.GetType()) {
case WebInputEvent::kGestureTap: {
- // Don't trigger a disambiguation popup on sites designed for mobile
- // devices. Instead, assume that the page has been designed with big
- // enough buttons and links. Don't trigger a disambiguation popup when
- // screencasting, since it's implemented outside of compositor pipeline
- // and is not being screencasted itself. This leads to bad user
- // experience.
- WebDevToolsAgentImpl* dev_tools = MainFrameDevToolsAgentImpl();
- VisualViewport& visual_viewport = GetPage()->GetVisualViewport();
- bool screencast_enabled = dev_tools && dev_tools->ScreencastEnabled();
- if (event.data.tap.width > 0 &&
- !visual_viewport.ShouldDisableDesktopWorkarounds() &&
- !screencast_enabled) {
- IntRect bounding_box(visual_viewport.ViewportToRootFrame(
- IntRect(event.PositionInWidget().x - event.data.tap.width / 2,
- event.PositionInWidget().y - event.data.tap.height / 2,
- event.data.tap.width, event.data.tap.height)));
-
- // TODO(bokan): We shouldn't pass details of the VisualViewport offset
- // to render_view_impl. crbug.com/459591
- WebSize visual_viewport_offset =
- FlooredIntSize(visual_viewport.GetScrollOffset());
-
- if (web_settings_->MultiTargetTapNotificationEnabled()) {
- Vector<IntRect> good_targets;
- HeapVector<Member<Node>> highlight_nodes;
- FindGoodTouchTargets(bounding_box, MainFrameImpl()->GetFrame(),
- good_targets, highlight_nodes);
- // FIXME: replace touch adjustment code when numberOfGoodTargets == 1?
- // Single candidate case is currently handled by:
- // https://bugs.webkit.org/show_bug.cgi?id=85101
- if (good_targets.size() >= 2 && client_ &&
- client_->DidTapMultipleTargets(visual_viewport_offset,
- bounding_box, good_targets)) {
- // Stash the position of the node that would've been used absent
- // disambiguation, for UMA purposes.
- last_tap_disambiguation_best_candidate_position_ =
- RoundedIntPoint(targeted_event.GetHitTestLocation().Point()) -
- RoundedIntSize(targeted_event.GetHitTestResult().LocalPoint());
-
- EnableTapHighlights(highlight_nodes);
- GetPage()->GetLinkHighlights().StartHighlightAnimationIfNeeded();
- event_result = WebInputEventResult::kHandledSystem;
- event_cancelled = true;
- break;
- }
- }
- }
-
{
ContextMenuAllowedScope scope;
event_result =
@@ -729,58 +649,6 @@ WebInputEventResult WebViewImpl::HandleGestureEvent(
return event_result;
}
-namespace {
-// This enum is used to back a histogram, and should therefore be treated as
-// append-only.
-enum TapDisambiguationResult {
- kUmaTapDisambiguationOther = 0,
- kUmaTapDisambiguationBackButton = 1,
- kUmaTapDisambiguationTappedOutside = 2,
- kUmaTapDisambiguationTappedInsideDeprecated = 3,
- kUmaTapDisambiguationTappedInsideSameNode = 4,
- kUmaTapDisambiguationTappedInsideDifferentNode = 5,
- kUmaTapDisambiguationCount = 6,
-};
-
-void RecordTapDisambiguation(TapDisambiguationResult result) {
- UMA_HISTOGRAM_ENUMERATION("Touchscreen.TapDisambiguation", result,
- kUmaTapDisambiguationCount);
-}
-
-} // namespace
-
-void WebViewImpl::ResolveTapDisambiguation(base::TimeTicks timestamp,
- WebPoint tap_viewport_offset,
- bool is_long_press) {
- WebGestureEvent event(is_long_press ? WebInputEvent::kGestureLongPress
- : WebInputEvent::kGestureTap,
- WebInputEvent::kNoModifiers, timestamp,
- blink::kWebGestureDeviceTouchscreen);
-
- event.SetPositionInWidget(FloatPoint(tap_viewport_offset));
-
- {
- // Compute UMA stat about whether the node selected by disambiguation UI was
- // different from the one preferred by the regular hit-testing + adjustment
- // logic.
- WebGestureEvent scaled_event =
- TransformWebGestureEvent(MainFrameImpl()->GetFrameView(), event);
- GestureEventWithHitTestResults targeted_event =
- page_->DeprecatedLocalMainFrame()->GetEventHandler().TargetGestureEvent(
- scaled_event);
- WebPoint node_position =
- RoundedIntPoint(targeted_event.GetHitTestLocation().Point()) -
- RoundedIntSize(targeted_event.GetHitTestResult().LocalPoint());
- TapDisambiguationResult result =
- (node_position == last_tap_disambiguation_best_candidate_position_)
- ? kUmaTapDisambiguationTappedInsideSameNode
- : kUmaTapDisambiguationTappedInsideDifferentNode;
- RecordTapDisambiguation(result);
- }
-
- HandleGestureEvent(event);
-}
-
bool WebViewImpl::StartPageScaleAnimation(const IntPoint& target_position,
bool use_anchor,
float new_scale,
@@ -1320,26 +1188,6 @@ void WebViewImpl::ZoomToFindInPageRect(const WebRect& rect_in_root_frame) {
findInPageAnimationDurationInSeconds);
}
-bool WebViewImpl::ZoomToMultipleTargetsRect(const WebRect& rect_in_root_frame) {
- // TODO(lukasza): https://crbug.com/734209: Add OOPIF support.
- if (!MainFrameImpl())
- return false;
-
- float scale;
- WebPoint scroll;
-
- ComputeScaleAndScrollForBlockRect(
- WebPoint(rect_in_root_frame.x, rect_in_root_frame.y), rect_in_root_frame,
- nonUserInitiatedPointPadding, MinimumPageScaleFactor(), scale, scroll);
-
- if (scale <= PageScaleFactor())
- return false;
-
- StartPageScaleAnimation(scroll, false, scale,
- multipleTargetsZoomAnimationDurationInSeconds);
- return true;
-}
-
#if !defined(OS_MACOSX)
// Mac has no way to open a context menu based on a keyboard event.
WebInputEventResult WebViewImpl::SendContextMenuEvent() {
@@ -1712,8 +1560,6 @@ void WebViewImpl::BeginFrame(base::TimeTicks last_frame_time) {
DocumentLifecycle::AllowThrottlingScope throttling_scope(
MainFrameImpl()->GetFrame()->GetDocument()->Lifecycle());
PageWidgetDelegate::Animate(*page_, last_frame_time);
- if (auto* client = GetValidationMessageClient())
- client->LayoutOverlay();
}
void WebViewImpl::UpdateLifecycle(LifecycleUpdate requested_update) {
@@ -1726,23 +1572,14 @@ void WebViewImpl::UpdateLifecycle(LifecycleUpdate requested_update) {
PageWidgetDelegate::UpdateLifecycle(*page_, *MainFrameImpl()->GetFrame(),
requested_update);
+ if (requested_update == LifecycleUpdate::kLayout)
+ return;
+
UpdateLayerTreeBackgroundColor();
if (requested_update == LifecycleUpdate::kPrePaint)
return;
- if (auto* client = GetValidationMessageClient())
- client->PaintOverlay();
- if (WebDevToolsAgentImpl* devtools = MainFrameDevToolsAgentImpl())
- devtools->PaintOverlay();
- if (page_color_overlay_)
- page_color_overlay_->GetGraphicsLayer()->Paint(nullptr);
-
- // TODO(chrishtr): link highlights don't currently paint themselves, it's
- // still driven by cc. Fix this.
- // TODO(pdr): Move this to LocalFrameView::UpdateLifecyclePhasesInternal.
- GetPage()->GetLinkHighlights().UpdateGeometry();
-
if (LocalFrameView* view = MainFrameImpl()->GetFrameView()) {
LocalFrame* frame = MainFrameImpl()->GetFrame();
WebWidgetClient* client =
@@ -1918,6 +1755,11 @@ WebInputEventResult WebViewImpl::HandleInputEvent(
}
}
+ // Skip the pointerrawmove for mouse capture case.
+ if (mouse_capture_node_ &&
+ input_event.GetType() == WebInputEvent::kPointerRawMove)
+ return WebInputEventResult::kHandledSystem;
+
if (mouse_capture_node_ &&
WebInputEvent::IsMouseEventType(input_event.GetType())) {
TRACE_EVENT1("input", "captured mouse event", "type",
@@ -2587,7 +2429,7 @@ void WebViewImpl::DisableAutoResizeMode() {
}
void WebViewImpl::SetDefaultPageScaleLimits(float min_scale, float max_scale) {
- return GetPage()->SetDefaultPageScaleLimits(min_scale, max_scale);
+ GetPage()->SetDefaultPageScaleLimits(min_scale, max_scale);
}
void WebViewImpl::SetInitialPageScaleOverride(
@@ -2634,13 +2476,11 @@ PageScaleConstraintsSet& WebViewImpl::GetPageScaleConstraintsSet() const {
return GetPage()->GetPageScaleConstraintsSet();
}
-void WebViewImpl::RefreshPageScaleFactorAfterLayout() {
+void WebViewImpl::RefreshPageScaleFactor() {
if (!MainFrame() || !GetPage() || !GetPage()->MainFrame() ||
!GetPage()->MainFrame()->IsLocalFrame() ||
!GetPage()->DeprecatedLocalMainFrame()->View())
return;
- LocalFrameView* view = GetPage()->DeprecatedLocalMainFrame()->View();
-
UpdatePageDefinedViewportConstraints(MainFrameImpl()
->GetFrame()
->GetDocument()
@@ -2648,16 +2488,6 @@ void WebViewImpl::RefreshPageScaleFactorAfterLayout() {
.GetViewportDescription());
GetPageScaleConstraintsSet().ComputeFinalConstraints();
- int vertical_scrollbar_width = 0;
- if (view->LayoutViewport()->VerticalScrollbar() &&
- !view->LayoutViewport()->VerticalScrollbar()->IsOverlayScrollbar()) {
- vertical_scrollbar_width =
- view->LayoutViewport()->VerticalScrollbar()->Width();
- }
- GetPageScaleConstraintsSet().AdjustFinalConstraintsToContentsSize(
- ContentsSize(), vertical_scrollbar_width,
- GetSettings()->ShrinksViewportContentToFit());
-
float new_page_scale_factor = PageScaleFactor();
if (GetPageScaleConstraintsSet().NeedsReset() &&
GetPageScaleConstraintsSet().FinalConstraints().initial_scale != -1) {
@@ -2790,13 +2620,6 @@ IntSize WebViewImpl::ContentsSize() const {
}
WebSize WebViewImpl::ContentsPreferredMinimumSize() {
- if (MainFrameImpl()) {
- MainFrameImpl()
- ->GetFrame()
- ->View()
- ->UpdateLifecycleToCompositingCleanPlusScrolling();
- }
-
Document* document = page_->MainFrame()->IsLocalFrame()
? page_->DeprecatedLocalMainFrame()->GetDocument()
: nullptr;
@@ -2804,6 +2627,10 @@ WebSize WebViewImpl::ContentsPreferredMinimumSize() {
!document->documentElement()->GetLayoutBox())
return WebSize();
+ // The preferred size requires an up-to-date layout tree.
+ DCHECK(!document->NeedsLayoutTreeUpdate() &&
+ !document->View()->NeedsLayout());
+
// Needed for computing MinPreferredWidth.
FontCachePurgePreventer fontCachePurgePreventer;
int width_scaled = document->GetLayoutView()
@@ -3121,12 +2948,6 @@ void WebViewImpl::DidCommitLoad(bool is_new_navigation,
// Give the visual viewport's scroll layer its initial size.
GetPage()->GetVisualViewport().MainFrameDidChangeSize();
-
- // Make sure link highlight from previous page is cleared.
- // TODO(pdr): Move this to Page::DidCommitLoad.
- GetPage()->GetLinkHighlights().ResetForPageNavigation();
- if (!MainFrameImpl())
- return;
}
void WebViewImpl::ResizeAfterLayout() {
@@ -3150,25 +2971,35 @@ void WebViewImpl::ResizeAfterLayout() {
}
if (GetPageScaleConstraintsSet().ConstraintsDirty())
- RefreshPageScaleFactorAfterLayout();
+ RefreshPageScaleFactor();
resize_viewport_anchor_->ResizeFrameView(MainFrameSize());
}
-void WebViewImpl::LayoutUpdated() {
+void WebViewImpl::MainFrameLayoutUpdated() {
DCHECK(MainFrameImpl());
if (!client_)
return;
- UpdatePageOverlays();
-
- fullscreen_controller_->DidUpdateLayout();
- client_->DidUpdateLayout();
+ fullscreen_controller_->DidUpdateMainFrameLayout();
+ client_->DidUpdateMainFrameLayout();
}
void WebViewImpl::DidChangeContentsSize() {
- GetPageScaleConstraintsSet().DidChangeContentsSize(ContentsSize(),
- PageScaleFactor());
+ if (!GetPage()->MainFrame()->IsLocalFrame())
+ return;
+
+ LocalFrameView* view = ToLocalFrame(GetPage()->MainFrame())->View();
+
+ int vertical_scrollbar_width = 0;
+ if (view && view->LayoutViewport()) {
+ Scrollbar* vertical_scrollbar = view->LayoutViewport()->VerticalScrollbar();
+ if (vertical_scrollbar && !vertical_scrollbar->IsOverlayScrollbar())
+ vertical_scrollbar_width = vertical_scrollbar->Width();
+ }
+
+ GetPageScaleConstraintsSet().DidChangeContentsSize(
+ ContentsSize(), vertical_scrollbar_width, PageScaleFactor());
}
void WebViewImpl::PageScaleFactorChanged() {
@@ -3199,21 +3030,7 @@ void WebViewImpl::SetZoomFactorOverride(float zoom_factor) {
}
void WebViewImpl::SetPageOverlayColor(SkColor color) {
- if (page_color_overlay_)
- page_color_overlay_.reset();
-
- if (color == Color::kTransparent)
- return;
-
- page_color_overlay_ = PageOverlay::Create(
- MainFrameImpl(), std::make_unique<ColorOverlay>(color));
-
- // Run compositing update before calling updatePageOverlays.
- MainFrameImpl()
- ->GetFrameView()
- ->UpdateLifecycleToCompositingCleanPlusScrolling();
-
- UpdatePageOverlays();
+ page_->SetPageOverlayColor(color);
}
WebPageImportanceSignals* WebViewImpl::PageImportanceSignals() {
@@ -3312,8 +3129,8 @@ void WebViewImpl::RegisterViewportLayersWithCompositor() {
VisualViewport& visual_viewport = GetPage()->GetVisualViewport();
WebLayerTreeView::ViewportLayers viewport_layers;
- viewport_layers.overscroll_elasticity =
- visual_viewport.OverscrollElasticityLayer()->CcLayer();
+ viewport_layers.overscroll_elasticity_element_id =
+ visual_viewport.GetCompositorOverscrollElasticityElementId();
viewport_layers.page_scale = visual_viewport.PageScaleLayer()->CcLayer();
viewport_layers.inner_viewport_container =
visual_viewport.ContainerLayer()->CcLayer();
@@ -3557,15 +3374,6 @@ base::WeakPtr<CompositorMutatorImpl> WebViewImpl::EnsureCompositorMutator(
return mutator_;
}
-void WebViewImpl::UpdatePageOverlays() {
- if (page_color_overlay_)
- page_color_overlay_->Update();
- if (auto* client = GetValidationMessageClient())
- client->LayoutOverlay();
- if (WebDevToolsAgentImpl* devtools = MainFrameDevToolsAgentImpl())
- devtools->LayoutOverlay();
-}
-
float WebViewImpl::DeviceScaleFactor() const {
// TODO(oshima): Investigate if this should return the ScreenInfo's scale
// factor rather than page's scale factor, which can be 1 in use-zoom-for-dsf
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 9055bbe708a..ca44078fa4c 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
@@ -77,11 +77,9 @@ class CompositorAnimationHost;
class DevToolsEmulator;
class Frame;
class FullscreenController;
-class PageOverlay;
class PageScaleConstraintsSet;
class PaintLayerCompositor;
class UserGestureToken;
-class ValidationMessageClient;
class WebDevToolsAgentImpl;
class WebElement;
class WebInputMethodController;
@@ -187,8 +185,9 @@ class CORE_EXPORT WebViewImpl final : public WebView,
double maximum_zoom_level) override;
float TextZoomFactor() override;
float SetTextZoomFactor(float) override;
- bool ZoomToMultipleTargetsRect(const WebRect&) override;
float PageScaleFactor() const override;
+ float MinimumPageScaleFactor() const override;
+ float MaximumPageScaleFactor() const override;
void SetDefaultPageScaleLimits(float min_scale, float max_scale) override;
void SetInitialPageScaleOverride(float) override;
void SetMaximumLegibleScale(float) override;
@@ -239,8 +238,6 @@ class CORE_EXPORT WebViewImpl final : public WebView,
float DefaultMinimumPageScaleFactor() const;
float DefaultMaximumPageScaleFactor() const;
- float MinimumPageScaleFactor() const;
- float MaximumPageScaleFactor() const;
float ClampPageScaleFactorToLimits(float) const;
void ResetScaleStateImmediately();
@@ -277,8 +274,6 @@ class CORE_EXPORT WebViewImpl final : public WebView,
// the page is shutting down, but will be valid at all other times.
Page* GetPage() const { return page_.Get(); }
- // Returns a ValidationMessageClient associated to the Page. This is nullable.
- ValidationMessageClient* GetValidationMessageClient() const;
WebDevToolsAgentImpl* MainFrameDevToolsAgentImpl();
DevToolsEmulator* GetDevToolsEmulator() const {
@@ -316,10 +311,10 @@ class CORE_EXPORT WebViewImpl final : public WebView,
// Indicates two things:
// 1) This view may have a new layout now.
- // 2) Calling updateAllLifecyclePhases() is a no-op.
+ // 2) Layout is up-to-date.
// After calling WebWidget::updateAllLifecyclePhases(), expect to get this
// notification unless the view did not need a layout.
- void LayoutUpdated();
+ void MainFrameLayoutUpdated();
void ResizeAfterLayout();
void DidChangeContentsSize();
@@ -368,10 +363,6 @@ class CORE_EXPORT WebViewImpl final : public WebView,
void EnableTapHighlights(HeapVector<Member<Node>>&);
void AnimateDoubleTapZoom(const IntPoint&);
- void ResolveTapDisambiguation(base::TimeTicks timestamp,
- WebPoint tap_viewport_offset,
- bool is_long_press) override;
-
void EnableFakePageScaleAnimationForTesting(bool);
bool FakeDoubleTapAnimationPendingForTesting() const {
return double_tap_zoom_pending_;
@@ -469,7 +460,7 @@ class CORE_EXPORT WebViewImpl final : public WebView,
void PropagateZoomFactorToLocalFrameRoots(Frame*, float);
float MaximumLegiblePageScale() const;
- void RefreshPageScaleFactorAfterLayout();
+ void RefreshPageScaleFactor();
IntSize ContentsSize() const;
void UpdateICBAndResizeViewport();
@@ -531,7 +522,6 @@ class CORE_EXPORT WebViewImpl final : public WebView,
void DisablePopupMouseWheelEventListener();
void CancelPagePopup();
- void UpdatePageOverlays();
float DeviceScaleFactor() const;
@@ -631,7 +621,6 @@ class CORE_EXPORT WebViewImpl final : public WebView,
scoped_refptr<WebPagePopupImpl> last_hidden_page_popup_;
Persistent<DevToolsEmulator> dev_tools_emulator_;
- std::unique_ptr<PageOverlay> page_color_overlay_;
// Whether the user can press tab to focus links.
bool tabs_to_links_;
@@ -650,8 +639,6 @@ class CORE_EXPORT WebViewImpl final : public WebView,
std::unique_ptr<FullscreenController> fullscreen_controller_;
- WebPoint last_tap_disambiguation_best_candidate_position_;
-
SkColor base_background_color_;
bool base_background_color_override_enabled_;
SkColor base_background_color_override_;
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 c92036ebe57..dcafda0916f 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
@@ -87,6 +87,7 @@
#include "third_party/blink/renderer/core/exported/web_view_impl.h"
#include "third_party/blink/renderer/core/frame/event_handler_registry.h"
#include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/settings.h"
@@ -1024,6 +1025,32 @@ TEST_F(WebViewTest, FinishComposingTextDoesNotAssert) {
WebInputMethodController::kKeepSelection);
}
+// Regression test for https://crbug.com/873999
+TEST_F(WebViewTest, LongPressOutsideInputShouldNotSelectPlaceholderText) {
+ RegisterMockedHttpURLLoad("input_placeholder.html");
+ WebViewImpl* web_view =
+ web_view_helper_.InitializeAndLoad(base_url_ + "input_placeholder.html");
+ web_view->SetInitialFocus(false);
+ web_view->Resize(WebSize(500, 300));
+ web_view->UpdateAllLifecyclePhases();
+ RunPendingTasks();
+
+ WebString input_id = WebString::FromUTF8("input");
+
+ // Focus in input.
+ EXPECT_TRUE(TapElementById(WebInputEvent::kGestureTap, input_id));
+
+ // Long press below input.
+ WebGestureEvent event(WebInputEvent::kGestureLongPress,
+ WebInputEvent::kNoModifiers,
+ WebInputEvent::GetStaticTimeStampForTests(),
+ kWebGestureDeviceTouchscreen);
+ event.SetPositionInWidget(WebFloatPoint(100, 150));
+ EXPECT_EQ(WebInputEventResult::kHandledSystem,
+ web_view->HandleInputEvent(WebCoalescedInputEvent(event)));
+ EXPECT_TRUE(web_view->MainFrameImpl()->SelectionAsText().IsEmpty());
+}
+
TEST_F(WebViewTest, FinishComposingTextCursorPositionChange) {
RegisterMockedHttpURLLoad("input_field_populated.html");
WebViewImpl* web_view = web_view_helper_.InitializeAndLoad(
@@ -1523,7 +1550,7 @@ TEST_F(WebViewTest, SetCompositionFromExistingText) {
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);
+ ws::mojom::ImeTextSpanThickness::kThin, 0);
WebLocalFrameImpl* frame = web_view->MainFrameImpl();
WebInputMethodController* active_input_method_controller =
frame->GetInputMethodController();
@@ -1550,7 +1577,7 @@ TEST_F(WebViewTest, SetCompositionFromExistingTextInTextArea) {
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);
+ ws::mojom::ImeTextSpanThickness::kThin, 0);
WebLocalFrameImpl* frame = web_view->MainFrameImpl();
WebInputMethodController* active_input_method_controller =
frame->FrameWidget()->GetActiveWebInputMethodController();
@@ -1594,7 +1621,7 @@ TEST_F(WebViewTest, SetCompositionFromExistingTextInRichText) {
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);
+ ws::mojom::ImeTextSpanThickness::kThin, 0);
WebLocalFrameImpl* frame = web_view->MainFrameImpl();
frame->SetEditableSelectionOffsets(1, 1);
WebDocument document = web_view->MainFrameImpl()->GetDocument();
@@ -2484,7 +2511,8 @@ static void DragAndDropURL(WebViewImpl* web_view, const std::string& url) {
widget->DragTargetDragEnter(drag_data, client_point, screen_point,
kWebDragOperationCopy, 0);
widget->DragTargetDrop(drag_data, client_point, screen_point, 0);
- FrameTestHelpers::PumpPendingRequestsForFrameToLoad();
+ FrameTestHelpers::PumpPendingRequestsForFrameToLoad(
+ web_view->MainFrameImpl());
}
TEST_F(WebViewTest, DragDropURL) {
@@ -4131,25 +4159,6 @@ TEST_F(WebViewTest, PreferredSize) {
EXPECT_EQ(2, size.height);
}
-TEST_F(WebViewTest, PreferredSizeDirtyLayout) {
- std::string url = base_url_ + "specify_size.html?100px:100px";
- URLTestHelpers::RegisterMockedURLLoad(
- ToKURL(url), test::CoreTestDataPath("specify_size.html"));
- WebViewImpl* web_view = web_view_helper_.InitializeAndLoad(url);
- WebElement document_element =
- web_view->MainFrameImpl()->GetDocument().DocumentElement();
-
- WebSize size = web_view->ContentsPreferredMinimumSize();
- EXPECT_EQ(100, size.width);
- EXPECT_EQ(100, size.height);
-
- document_element.SetAttribute("style", "display: none");
-
- size = web_view->ContentsPreferredMinimumSize();
- EXPECT_EQ(0, size.width);
- EXPECT_EQ(0, size.height);
-}
-
TEST_F(WebViewTest, PreferredSizeWithGrid) {
WebViewImpl* web_view = web_view_helper_.Initialize();
WebURL base_url = URLTestHelpers::ToKURL("http://example.com/");
@@ -4467,6 +4476,24 @@ TEST_F(WebViewTest, WebSubstringUtil) {
ASSERT_TRUE(!!result);
}
+TEST_F(WebViewTest, WebSubstringUtilBaselinePoint) {
+ RegisterMockedHttpURLLoad("content_editable_multiline.html");
+ WebViewImpl* web_view = web_view_helper_.InitializeAndLoad(
+ base_url_ + "content_editable_multiline.html");
+ web_view->GetSettings()->SetDefaultFontSize(12);
+ web_view->Resize(WebSize(400, 400));
+ WebLocalFrameImpl* frame = web_view->MainFrameImpl();
+
+ WebPoint old_point;
+ WebSubstringUtil::AttributedSubstringInRange(frame, 3, 1, &old_point);
+
+ WebPoint 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);
+}
+
TEST_F(WebViewTest, WebSubstringUtilPinchZoom) {
RegisterMockedHttpURLLoad("content_editable_populated.html");
WebViewImpl* web_view = web_view_helper_.InitializeAndLoad(
diff --git a/chromium/third_party/blink/renderer/core/exported/worker_shadow_page.cc b/chromium/third_party/blink/renderer/core/exported/worker_shadow_page.cc
index bee5e5d485d..ed222991f24 100644
--- a/chromium/third_party/blink/renderer/core/exported/worker_shadow_page.cc
+++ b/chromium/third_party/blink/renderer/core/exported/worker_shadow_page.cc
@@ -9,7 +9,6 @@
#include "third_party/blink/public/platform/web_referrer_policy.h"
#include "third_party/blink/public/web/web_settings.h"
#include "third_party/blink/renderer/core/exported/web_view_impl.h"
-#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/loader/frame_load_request.h"
#include "third_party/blink/renderer/platform/loader/fetch/substitute_data.h"
@@ -75,16 +74,6 @@ void WorkerShadowPage::Initialize(const KURL& script_url) {
nullptr, ResourceRequest(script_url), SubstituteData(buffer)));
}
-void WorkerShadowPage::SetContentSecurityPolicyAndReferrerPolicy(
- ContentSecurityPolicy* content_security_policy,
- String referrer_policy) {
- DCHECK(IsMainThread());
- content_security_policy->SetOverrideURLForSelf(GetDocument()->Url());
- GetDocument()->InitContentSecurityPolicy(content_security_policy);
- if (!referrer_policy.IsNull())
- GetDocument()->ParseAndSetReferrerPolicy(referrer_policy);
-}
-
void WorkerShadowPage::DidFinishDocumentLoad() {
DCHECK(IsMainThread());
AdvanceState(State::kInitialized);
@@ -113,11 +102,6 @@ base::UnguessableToken WorkerShadowPage::GetDevToolsFrameToken() {
return client_->GetDevToolsWorkerToken();
}
-std::unique_ptr<WebSocketHandshakeThrottle>
-WorkerShadowPage::CreateWebSocketHandshakeThrottle() {
- return Platform::Current()->CreateWebSocketHandshakeThrottle();
-}
-
void WorkerShadowPage::WillSendRequest(WebURLRequest& request) {
if (preferences_.enable_do_not_track) {
request.SetHTTPHeaderField(WebString::FromUTF8(kDoNotTrackHeader), "1");
diff --git a/chromium/third_party/blink/renderer/core/exported/worker_shadow_page.h b/chromium/third_party/blink/renderer/core/exported/worker_shadow_page.h
index cf252214cef..43cf850c57a 100644
--- a/chromium/third_party/blink/renderer/core/exported/worker_shadow_page.h
+++ b/chromium/third_party/blink/renderer/core/exported/worker_shadow_page.h
@@ -19,7 +19,6 @@ class SharedURLLoaderFactory;
namespace blink {
-class ContentSecurityPolicy;
class WebApplicationCacheHost;
class WebApplicationCacheHostClient;
class WebSettings;
@@ -29,7 +28,7 @@ class WebSettings;
// Loading components are strongly associated with frames, but out-of-process
// workers (i.e., SharedWorker and ServiceWorker) don't have frames. To enable
// loading on such workers, this class provides a virtual frame (a.k.a, shadow
-// page) to them.
+// page) to them. Note that this class is now only used for main script loading.
//
// WorkerShadowPage lives on the main thread.
//
@@ -66,9 +65,6 @@ class CORE_EXPORT WorkerShadowPage : public WebLocalFrameClient {
// complete.
void Initialize(const KURL& script_url);
- void SetContentSecurityPolicyAndReferrerPolicy(ContentSecurityPolicy*,
- String referrer_policy);
-
// WebLocalFrameClient overrides.
std::unique_ptr<WebApplicationCacheHost> CreateApplicationCacheHost(
WebApplicationCacheHostClient*) override;
@@ -82,11 +78,6 @@ class CORE_EXPORT WorkerShadowPage : public WebLocalFrameClient {
base::UnguessableToken GetDevToolsFrameToken() override;
void WillSendRequest(WebURLRequest&) override;
- // TODO(nhiroki): Remove this once the off-main-thread WebSocket is enabled by
- // default (https://crbug.com/825740).
- std::unique_ptr<WebSocketHandshakeThrottle> CreateWebSocketHandshakeThrottle()
- override;
-
Document* GetDocument() { return main_frame_->GetFrame()->GetDocument(); }
WebSettings* GetSettings() { return web_view_->GetSettings(); }
WebDocumentLoader* DocumentLoader() {
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 063ffe6342f..d96f3aaee3c 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
@@ -373,6 +373,20 @@ bool BodyStreamBuffer::IsStreamDisturbedForDCheck() {
}
void BodyStreamBuffer::CloseAndLockAndDisturb(ExceptionState& exception_state) {
+ // Speculative fix for https://crbug.com/882599. Stop the stream from being
+ // garbage collected while this function is executing.
+ // TODO(ricea): Remove this when a better solution is found or if it doesn't
+ // work.
+ v8::Local<v8::Value> stream_handle =
+ stream_.NewLocal(script_state_->GetIsolate());
+ if (stream_handle.IsEmpty()) {
+ stream_broken_ = true;
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "Body stream has suffered a fatal error and cannot be disturbed");
+ return;
+ }
+
base::Optional<bool> is_readable = IsStreamReadable(exception_state);
if (exception_state.HadException())
return;
diff --git a/chromium/third_party/blink/renderer/core/fetch/data_consumer_handle_test_util.cc b/chromium/third_party/blink/renderer/core/fetch/data_consumer_handle_test_util.cc
index 45fc96cdc24..808341e5920 100644
--- a/chromium/third_party/blink/renderer/core/fetch/data_consumer_handle_test_util.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/data_consumer_handle_test_util.cc
@@ -61,7 +61,8 @@ void DataConsumerHandleTestUtil::Thread::Initialize() {
DCHECK(thread_->IsCurrentThread());
if (initialization_policy_ >= kScriptExecution) {
isolate_holder_ = std::make_unique<gin::IsolateHolder>(
- scheduler::GetSingleThreadTaskRunnerForTesting());
+ scheduler::GetSingleThreadTaskRunnerForTesting(),
+ gin::IsolateHolder::IsolateType::kTest);
GetIsolate()->Enter();
}
thread_->InitializeOnThread();
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 00c4d01d2f6..c4cd7528f0c 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
@@ -11,6 +11,7 @@
#include "third_party/blink/renderer/core/fileapi/file.h"
#include "third_party/blink/renderer/core/html/forms/form_data.h"
#include "third_party/blink/renderer/core/html/parser/text_resource_decoder.h"
+#include "third_party/blink/renderer/platform/file_metadata.h"
#include "third_party/blink/renderer/platform/loader/fetch/text_resource_decoder_options.h"
#include "third_party/blink/renderer/platform/network/http_names.h"
#include "third_party/blink/renderer/platform/network/parsed_content_disposition.h"
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 442e88fc9e0..620bbccd596 100644
--- a/chromium/third_party/blink/renderer/core/fetch/fetch_manager.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/fetch_manager.cc
@@ -33,6 +33,7 @@
#include "third_party/blink/renderer/core/probe/core_probes.h"
#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/bindings/script_forbidden_scope.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/exported/wrapped_resource_response.h"
@@ -65,6 +66,44 @@ namespace blink {
namespace {
+class EmptyDataHandle final : public WebDataConsumerHandle {
+ private:
+ class EmptyDataReader final : public WebDataConsumerHandle::Reader {
+ public:
+ explicit EmptyDataReader(
+ WebDataConsumerHandle::Client* client,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner)
+ : factory_(this) {
+ task_runner->PostTask(
+ FROM_HERE, WTF::Bind(&EmptyDataReader::Notify, factory_.GetWeakPtr(),
+ WTF::Unretained(client)));
+ }
+
+ private:
+ Result BeginRead(const void** buffer,
+ WebDataConsumerHandle::Flags,
+ size_t* available) override {
+ *available = 0;
+ *buffer = nullptr;
+ return kDone;
+ }
+ Result EndRead(size_t) override {
+ return WebDataConsumerHandle::kUnexpectedError;
+ }
+ void Notify(WebDataConsumerHandle::Client* client) {
+ client->DidGetReadable();
+ }
+ base::WeakPtrFactory<EmptyDataReader> factory_;
+ };
+
+ std::unique_ptr<Reader> ObtainReader(
+ Client* client,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner) override {
+ return std::make_unique<EmptyDataReader>(client, std::move(task_runner));
+ }
+ const char* DebugName() const override { return "EmptyDataHandle"; }
+};
+
bool HasNonEmptyLocationHeader(const FetchHeaderList* headers) {
String value;
if (!headers->Get(HTTPNames::Location, value))
@@ -179,7 +218,7 @@ class FetchManager::Loader final
~Loader() override;
virtual void Trace(blink::Visitor*);
- void DidReceiveRedirectTo(const KURL&) override;
+ bool WillFollowRedirect(const KURL&, const ResourceResponse&) override;
void DidReceiveResponse(unsigned long,
const ResourceResponse&,
std::unique_ptr<WebDataConsumerHandle>) override;
@@ -376,8 +415,36 @@ void FetchManager::Loader::Trace(blink::Visitor* visitor) {
visitor->Trace(execution_context_);
}
-void FetchManager::Loader::DidReceiveRedirectTo(const KURL& url) {
+bool FetchManager::Loader::WillFollowRedirect(
+ const KURL& url,
+ const ResourceResponse& response) {
+ const auto redirect_mode = fetch_request_data_->Redirect();
+ if (redirect_mode == network::mojom::FetchRedirectMode::kError) {
+ DidFailRedirectCheck();
+ Dispose();
+ return false;
+ }
+
+ if (redirect_mode == network::mojom::FetchRedirectMode::kManual) {
+ const unsigned long unused = 0;
+ // There is no need to read the body of redirect response because there is
+ // no way to read the body of opaque-redirect filtered response's internal
+ // response.
+ // TODO(horo): If we support any API which expose the internal body, we
+ // will have to read the body. And also HTTPCache changes will be needed
+ // because it doesn't store the body of redirect responses.
+ DidReceiveResponse(unused, response, std::make_unique<EmptyDataHandle>());
+
+ if (threadable_loader_)
+ NotifyFinished();
+
+ Dispose();
+ return false;
+ }
+
+ DCHECK_EQ(redirect_mode, network::mojom::FetchRedirectMode::kFollow);
url_list_.push_back(url);
+ return true;
}
void FetchManager::Loader::DidReceiveResponse(
@@ -440,7 +507,7 @@ void FetchManager::Loader::DidReceiveResponse(
}
}
if (response.WasFetchedViaServiceWorker()) {
- switch (response.ResponseTypeViaServiceWorker()) {
+ switch (response.GetType()) {
case FetchResponseType::kBasic:
case FetchResponseType::kDefault:
tainting = FetchRequestData::kBasicTainting;
@@ -477,7 +544,13 @@ void FetchManager::Loader::DidReceiveResponse(
new BodyStreamBuffer(script_state, sri_consumer, signal_));
}
response_data->SetStatus(response.HttpStatusCode());
- response_data->SetStatusMessage(response.HttpStatusText());
+ if (response.Url().ProtocolIsAbout() || response.Url().ProtocolIsData() ||
+ response.Url().ProtocolIs("blob")) {
+ response_data->SetStatusMessage("OK");
+ } else {
+ response_data->SetStatusMessage(response.HttpStatusText());
+ }
+
for (auto& it : response.HttpHeaderFields())
response_data->HeaderList()->Append(it.key, it.value);
if (response.UrlListViaServiceWorker().IsEmpty()) {
@@ -744,8 +817,7 @@ void FetchManager::Loader::PerformNetworkError(const String& message) {
}
void FetchManager::Loader::PerformHTTPFetch(ExceptionState& exception_state) {
- // CORS preflight fetch procedure is implemented inside
- // DocumentThreadableLoader.
+ // CORS preflight fetch procedure is implemented inside ThreadableLoader.
// "1. Let |HTTPRequest| be a copy of |request|, except that |HTTPRequest|'s
// body is a tee of |request|'s body."
@@ -792,6 +864,7 @@ void FetchManager::Loader::PerformHTTPFetch(ExceptionState& exception_state) {
request.SetCacheMode(fetch_request_data_->CacheMode());
request.SetFetchRedirectMode(fetch_request_data_->Redirect());
request.SetFetchImportanceMode(fetch_request_data_->Importance());
+ request.SetPriority(fetch_request_data_->Priority());
request.SetUseStreamOnResponse(true);
request.SetExternalRequestStateFromRequestorAddressSpace(
execution_context_->GetSecurityContext().AddressSpace());
@@ -807,12 +880,13 @@ void FetchManager::Loader::PerformHTTPFetch(ExceptionState& exception_state) {
? execution_context_->GetReferrerPolicy()
: fetch_request_data_->GetReferrerPolicy();
const String referrer_string =
- fetch_request_data_->ReferrerString() ==
- FetchRequestData::ClientReferrerString()
+ fetch_request_data_->ReferrerString() == Referrer::ClientReferrerString()
? execution_context_->OutgoingReferrer()
: fetch_request_data_->ReferrerString();
// Note that generateReferrer generates |no-referrer| from |no-referrer|
// referrer string (i.e. String()).
+ // TODO(domfarolino): Can we use ResourceRequest's SetReferrerString() and
+ // SetReferrerPolicy() instead of calling SetHTTPReferrer()?
request.SetHTTPReferrer(SecurityPolicy::GenerateReferrer(
referrer_policy, fetch_request_data_->Url(), referrer_string));
request.SetSkipServiceWorker(is_isolated_world_);
@@ -836,7 +910,7 @@ void FetchManager::Loader::PerformHTTPFetch(ExceptionState& exception_state) {
// |HTTPRequest|'s origin, serialized and utf-8 encoded, to |HTTPRequest|'s
// header list."
// We set Origin header in updateRequestForAccessControl() called from
- // DocumentThreadableLoader::makeCrossOriginAccessRequest
+ // ThreadableLoader::makeCrossOriginAccessRequest
// "5. Let |credentials flag| be set if either |HTTPRequest|'s credentials
// mode is |include|, or |HTTPRequest|'s credentials mode is |same-origin|
@@ -854,12 +928,9 @@ void FetchManager::Loader::PerformHTTPFetch(ExceptionState& exception_state) {
std::move(factory_clone));
}
- ThreadableLoaderOptions threadable_loader_options;
-
probe::willStartFetch(execution_context_, this);
- threadable_loader_ = ThreadableLoader::Create(*execution_context_, this,
- threadable_loader_options,
- resource_loader_options);
+ threadable_loader_ = new ThreadableLoader(*execution_context_, this,
+ resource_loader_options);
threadable_loader_->Start(request);
}
@@ -877,6 +948,7 @@ void FetchManager::Loader::PerformDataFetch() {
request.SetFetchCredentialsMode(network::mojom::FetchCredentialsMode::kOmit);
request.SetFetchRedirectMode(FetchRedirectMode::kError);
request.SetFetchImportanceMode(fetch_request_data_->Importance());
+ request.SetPriority(fetch_request_data_->Priority());
// We intentionally skip 'setExternalRequestStateFromRequestorAddressSpace',
// as 'data:' can never be external.
@@ -884,12 +956,9 @@ void FetchManager::Loader::PerformDataFetch() {
resource_loader_options.data_buffering_policy = kDoNotBufferData;
resource_loader_options.security_origin = fetch_request_data_->Origin().get();
- ThreadableLoaderOptions threadable_loader_options;
-
probe::willStartFetch(execution_context_, this);
- threadable_loader_ = ThreadableLoader::Create(*execution_context_, this,
- threadable_loader_options,
- resource_loader_options);
+ threadable_loader_ = new ThreadableLoader(*execution_context_, this,
+ resource_loader_options);
threadable_loader_->Start(request);
}
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 de775ac28cc..b70756e382f 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
@@ -48,15 +48,17 @@ FetchRequestData* FetchRequestData::Create(
nullptr /* AbortSignal */));
}
request->SetContext(web_request.GetRequestContext());
- request->SetReferrer(
- Referrer(web_request.ReferrerUrl().GetString(),
- static_cast<ReferrerPolicy>(web_request.GetReferrerPolicy())));
+ request->SetReferrerString(web_request.ReferrerUrl().GetString());
+ request->SetReferrerPolicy(
+ static_cast<ReferrerPolicy>(web_request.GetReferrerPolicy()));
request->SetMode(web_request.Mode());
request->SetCredentials(web_request.CredentialsMode());
request->SetCacheMode(web_request.CacheMode());
request->SetRedirect(web_request.RedirectMode());
request->SetMIMEType(request->header_list_->ExtractMIMEType());
request->SetIntegrity(web_request.Integrity());
+ request->SetPriority(
+ static_cast<ResourceLoadPriority>(web_request.Priority()));
request->SetKeepalive(web_request.Keepalive());
request->SetIsHistoryNavigation(web_request.IsHistoryNavigation());
return request;
@@ -70,7 +72,8 @@ FetchRequestData* FetchRequestData::CloneExceptBody() {
request->origin_ = origin_;
request->same_origin_data_url_flag_ = same_origin_data_url_flag_;
request->context_ = context_;
- request->referrer_ = referrer_;
+ request->referrer_string_ = referrer_string_;
+ request->referrer_policy_ = referrer_policy_;
request->mode_ = mode_;
request->credentials_ = credentials_;
request->cache_mode_ = cache_mode_;
@@ -78,6 +81,7 @@ FetchRequestData* FetchRequestData::CloneExceptBody() {
request->response_tainting_ = response_tainting_;
request->mime_type_ = mime_type_;
request->integrity_ = integrity_;
+ request->priority_ = priority_;
request->importance_ = importance_;
request->keepalive_ = keepalive_;
request->is_history_navigation_ = is_history_navigation_;
@@ -124,13 +128,15 @@ FetchRequestData::FetchRequestData()
header_list_(FetchHeaderList::Create()),
context_(WebURLRequest::kRequestContextUnspecified),
same_origin_data_url_flag_(false),
- referrer_(Referrer(ClientReferrerString(), kReferrerPolicyDefault)),
+ referrer_string_(Referrer::ClientReferrerString()),
+ referrer_policy_(kReferrerPolicyDefault),
mode_(network::mojom::FetchRequestMode::kNoCORS),
credentials_(network::mojom::FetchCredentialsMode::kOmit),
cache_mode_(mojom::FetchCacheMode::kDefault),
redirect_(network::mojom::FetchRedirectMode::kFollow),
importance_(mojom::FetchImportanceMode::kImportanceAuto),
response_tainting_(kBasicTainting),
+ priority_(ResourceLoadPriority::kUnresolved),
keepalive_(false) {}
void FetchRequestData::Trace(blink::Visitor* visitor) {
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 9db2e759c0c..2177b72edf6 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
@@ -14,6 +14,7 @@
#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"
+#include "third_party/blink/renderer/platform/loader/fetch/resource_load_priority.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/referrer_policy.h"
@@ -55,12 +56,10 @@ class FetchRequestData final
void SetSameOriginDataURLFlag(bool flag) {
same_origin_data_url_flag_ = flag;
}
- const Referrer& GetReferrer() const { return referrer_; }
- void SetReferrer(const Referrer& r) { referrer_ = r; }
- const AtomicString& ReferrerString() const { return referrer_.referrer; }
- void SetReferrerString(const AtomicString& s) { referrer_.referrer = s; }
- ReferrerPolicy GetReferrerPolicy() const { return referrer_.referrer_policy; }
- void SetReferrerPolicy(ReferrerPolicy p) { referrer_.referrer_policy = p; }
+ const AtomicString& ReferrerString() const { return referrer_string_; }
+ void SetReferrerString(const AtomicString& s) { referrer_string_ = s; }
+ ReferrerPolicy GetReferrerPolicy() const { return referrer_policy_; }
+ void SetReferrerPolicy(ReferrerPolicy p) { referrer_policy_ = p; }
void SetMode(network::mojom::FetchRequestMode mode) { mode_ = mode; }
network::mojom::FetchRequestMode Mode() const { return mode_; }
void SetCredentials(network::mojom::FetchCredentialsMode credentials) {
@@ -94,6 +93,8 @@ class FetchRequestData final
void SetMIMEType(const String& type) { mime_type_ = type; }
String Integrity() const { return integrity_; }
void SetIntegrity(const String& integrity) { integrity_ = integrity; }
+ ResourceLoadPriority Priority() const { return priority_; }
+ void SetPriority(ResourceLoadPriority priority) { priority_ = priority; }
bool Keepalive() const { return keepalive_; }
void SetKeepalive(bool b) { keepalive_ = b; }
bool IsHistoryNavigation() const { return is_history_navigation_; }
@@ -106,12 +107,6 @@ class FetchRequestData final
url_loader_factory_ = std::move(factory);
}
- // We use these strings instead of "no-referrer" and "client" in the spec.
- static AtomicString NoReferrerString() { return AtomicString(); }
- static AtomicString ClientReferrerString() {
- return AtomicString("about:client");
- }
-
void Trace(blink::Visitor*);
private:
@@ -127,10 +122,8 @@ class FetchRequestData final
scoped_refptr<const SecurityOrigin> origin_;
// FIXME: Support m_forceOriginHeaderFlag;
bool same_origin_data_url_flag_;
- // |m_referrer| consists of referrer string and referrer policy.
- // We use |noReferrerString()| and |clientReferrerString()| as
- // "no-referrer" and "client" strings in the spec.
- Referrer referrer_;
+ AtomicString referrer_string_;
+ ReferrerPolicy referrer_policy_;
// FIXME: Support m_authenticationFlag;
// FIXME: Support m_synchronousFlag;
network::mojom::FetchRequestMode mode_;
@@ -147,6 +140,7 @@ class FetchRequestData final
TraceWrapperMember<BodyStreamBuffer> buffer_;
String mime_type_;
String integrity_;
+ ResourceLoadPriority priority_;
bool keepalive_;
bool is_history_navigation_ = false;
// A specific factory that should be used for this request instead of whatever
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 53ef2e15dd6..add6602b065 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
@@ -41,15 +41,16 @@ Vector<String> HeaderSetToVector(const WebHTTPHeaderSet& headers) {
FetchResponseData* FetchResponseData::Create() {
// "Unless stated otherwise, a response's url is null, status is 200, status
- // message is `OK`, header list is an empty header list, and body is null."
- return new FetchResponseData(Type::kDefault, 200, "OK");
+ // message is the empty byte sequence, header list is an empty header list,
+ // and body is null."
+ return new FetchResponseData(Type::kDefault, 200, g_empty_atom);
}
FetchResponseData* FetchResponseData::CreateNetworkErrorResponse() {
// "A network error is a response whose status is always 0, status message
// is always the empty byte sequence, header list is aways an empty list,
// and body is always null."
- return new FetchResponseData(Type::kError, 0, "");
+ return new FetchResponseData(Type::kError, 0, g_empty_atom);
}
FetchResponseData* FetchResponseData::CreateWithBuffer(
@@ -114,7 +115,8 @@ FetchResponseData* FetchResponseData::CreateOpaqueFilteredResponse() const {
// cache state is 'none'."
//
// https://fetch.spec.whatwg.org/#concept-filtered-response-opaque
- FetchResponseData* response = new FetchResponseData(Type::kOpaque, 0, "");
+ FetchResponseData* response =
+ new FetchResponseData(Type::kOpaque, 0, g_empty_atom);
response->internal_response_ = const_cast<FetchResponseData*>(this);
return response;
}
@@ -128,7 +130,7 @@ FetchResponseData* FetchResponseData::CreateOpaqueRedirectFilteredResponse()
//
// https://fetch.spec.whatwg.org/#concept-filtered-response-opaque-redirect
FetchResponseData* response =
- new FetchResponseData(Type::kOpaqueRedirect, 0, "");
+ new FetchResponseData(Type::kOpaqueRedirect, 0, g_empty_atom);
response->SetURLList(url_list_);
response->internal_response_ = const_cast<FetchResponseData*>(this);
return response;
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 5810fcd80a3..b32bb7976ae 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
@@ -10,8 +10,8 @@
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "services/network/public/mojom/fetch_api.mojom-blink.h"
+#include "third_party/blink/public/mojom/fetch/fetch_api_response.mojom-blink.h"
#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom-blink.h"
-#include "third_party/blink/public/platform/modules/fetch/fetch_api_response.mojom-blink.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_request.h"
#include "third_party/blink/public/platform/web_cors.h"
#include "third_party/blink/renderer/core/core_export.h"
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 48bb0a57e4d..2f69f7cf7dd 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
@@ -11,6 +11,7 @@
#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/blob/blob_data.h"
+#include "third_party/blink/renderer/platform/file_metadata.h"
#include "third_party/blink/renderer/platform/network/encoded_form_data.h"
#include "third_party/blink/renderer/platform/network/form_data_encoder.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
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 a62d026e974..2d21c80e665 100644
--- a/chromium/third_party/blink/renderer/core/fetch/global_fetch.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/global_fetch.cc
@@ -59,9 +59,12 @@ class GlobalFetchImpl final
return ScriptPromise();
probe::willSendXMLHttpOrFetchNetworkRequest(execution_context, r->url());
- auto promise = fetch_manager_->Fetch(
- script_state, r->PassRequestData(script_state, exception_state),
- r->signal(), exception_state);
+ FetchRequestData* request_data =
+ r->PassRequestData(script_state, exception_state);
+ if (exception_state.HadException())
+ return ScriptPromise();
+ auto promise = fetch_manager_->Fetch(script_state, request_data,
+ r->signal(), exception_state);
if (exception_state.HadException())
return ScriptPromise();
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 a9768f6569b..43d2a3204df 100644
--- a/chromium/third_party/blink/renderer/core/fetch/multipart_parser.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/multipart_parser.cc
@@ -263,7 +263,9 @@ void MultipartParser::ParseDataAndDelimiter(const char** bytes_pointer,
} else {
// Search for a partial delimiter in the end of the bytes.
const size_t size = static_cast<size_t>(bytes_end - *bytes_pointer);
- for (delimiter_begin = bytes_end - std::min(delimiter_.size() - 1u, size);
+ for (delimiter_begin =
+ bytes_end -
+ std::min(static_cast<size_t>(delimiter_.size() - 1u), size);
delimiter_begin < bytes_end; ++delimiter_begin) {
if (matcher_.Match(delimiter_begin, bytes_end))
break;
diff --git a/chromium/third_party/blink/renderer/core/fetch/request.cc b/chromium/third_party/blink/renderer/core/fetch/request.cc
index 00d5b6a8867..b928837b3a9 100644
--- a/chromium/third_party/blink/renderer/core/fetch/request.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/request.cc
@@ -61,13 +61,15 @@ FetchRequestData* CreateCopyOfFetchRequestDataForFetch(
}
// FIXME: Set ForceOriginHeaderFlag.
request->SetSameOriginDataURLFlag(true);
- request->SetReferrer(original->GetReferrer());
+ request->SetReferrerString(original->ReferrerString());
+ request->SetReferrerPolicy(original->GetReferrerPolicy());
request->SetMode(original->Mode());
request->SetCredentials(original->Credentials());
request->SetCacheMode(original->CacheMode());
request->SetRedirect(original->Redirect());
request->SetIntegrity(original->Integrity());
request->SetImportance(original->Importance());
+ request->SetPriority(original->Priority());
request->SetKeepalive(original->Keepalive());
request->SetIsHistoryNavigation(original->IsHistoryNavigation());
if (original->URLLoaderFactory()) {
@@ -272,7 +274,7 @@ Request* Request::CreateRequestWithRequestOrString(
request->SetIsHistoryNavigation(false);
// "Set |request|’s referrer to "client"."
- request->SetReferrerString(FetchRequestData::ClientReferrerString());
+ request->SetReferrerString(AtomicString(Referrer::ClientReferrerString()));
// "Set |request|’s referrer policy to the empty string."
request->SetReferrerPolicy(kReferrerPolicyDefault);
@@ -313,7 +315,8 @@ Request* Request::CreateRequestWithRequestOrString(
//
// parsedReferrer’s origin is not same origin with origin"
//
- request->SetReferrerString(FetchRequestData::ClientReferrerString());
+ request->SetReferrerString(
+ AtomicString(Referrer::ClientReferrerString()));
} else {
// "Set |request|'s referrer to |parsedReferrer|."
request->SetReferrerString(AtomicString(parsed_referrer.GetString()));
@@ -719,9 +722,8 @@ String Request::referrer() const {
// "The referrer attribute's getter must return the empty string if
// request's referrer is no referrer, "about:client" if request's referrer
// is client and request's referrer, serialized, otherwise."
- DCHECK_EQ(FetchRequestData::NoReferrerString(), AtomicString());
- DCHECK_EQ(FetchRequestData::ClientReferrerString(),
- AtomicString("about:client"));
+ DCHECK_EQ(Referrer::NoReferrer(), String());
+ DCHECK_EQ(Referrer::ClientReferrerString(), "about:client");
return request_->ReferrerString();
}
diff --git a/chromium/third_party/blink/renderer/core/fetch/request.idl b/chromium/third_party/blink/renderer/core/fetch/request.idl
index 19218756447..0e5f9c14e1c 100644
--- a/chromium/third_party/blink/renderer/core/fetch/request.idl
+++ b/chromium/third_party/blink/renderer/core/fetch/request.idl
@@ -50,7 +50,7 @@ enum ReferrerPolicy {
readonly attribute boolean keepalive;
readonly attribute AbortSignal signal;
- [RuntimeEnabled=RequestIsHistoryNavigation] readonly attribute boolean isHistoryNavigation;
+ [MeasureAs=RequestIsHistoryNavigation] readonly attribute boolean isHistoryNavigation;
[RaisesException, CallWith=ScriptState, DoNotTestNewObject, NewObject] Request clone();
};
diff --git a/chromium/third_party/blink/renderer/core/fetch/response.h b/chromium/third_party/blink/renderer/core/fetch/response.h
index 33463f83bed..10caa9a5728 100644
--- a/chromium/third_party/blink/renderer/core/fetch/response.h
+++ b/chromium/third_party/blink/renderer/core/fetch/response.h
@@ -5,7 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FETCH_RESPONSE_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_FETCH_RESPONSE_H_
-#include "third_party/blink/public/platform/modules/fetch/fetch_api_response.mojom-blink.h"
+#include "third_party/blink/public/mojom/fetch/fetch_api_response.mojom-blink.h"
#include "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/core/core_export.h"
diff --git a/chromium/third_party/blink/renderer/core/fileapi/file_error.cc b/chromium/third_party/blink/renderer/core/fileapi/file_error.cc
index 990ab274b2d..bad63bf4072 100644
--- a/chromium/third_party/blink/renderer/core/fileapi/file_error.cc
+++ b/chromium/third_party/blink/renderer/core/fileapi/file_error.cc
@@ -143,6 +143,88 @@ const char* ErrorCodeToMessage(ErrorCode code) {
}
}
+DOMExceptionCode FileErrorToExceptionCode(base::File::Error code) {
+ switch (code) {
+ case base::File::FILE_OK:
+ return DOMExceptionCode::kNoError;
+ case base::File::FILE_ERROR_FAILED:
+ return DOMExceptionCode::kInvalidStateError;
+ case base::File::FILE_ERROR_EXISTS:
+ return DOMExceptionCode::kPathExistsError;
+ case base::File::FILE_ERROR_NOT_EMPTY:
+ case base::File::FILE_ERROR_INVALID_OPERATION:
+ return DOMExceptionCode::kInvalidModificationError;
+ case base::File::FILE_ERROR_TOO_MANY_OPENED:
+ case base::File::FILE_ERROR_NO_MEMORY:
+ return DOMExceptionCode::kUnknownError;
+ case base::File::FILE_ERROR_NOT_FOUND:
+ return DOMExceptionCode::kNotFoundError;
+ case base::File::FILE_ERROR_IN_USE:
+ case base::File::FILE_ERROR_ACCESS_DENIED:
+ return DOMExceptionCode::kNoModificationAllowedError;
+ case base::File::FILE_ERROR_NO_SPACE:
+ return DOMExceptionCode::kQuotaExceededError;
+ case base::File::FILE_ERROR_NOT_A_DIRECTORY:
+ case base::File::FILE_ERROR_NOT_A_FILE:
+ return DOMExceptionCode::kTypeMismatchError;
+ case base::File::FILE_ERROR_ABORT:
+ return DOMExceptionCode::kAbortError;
+ case base::File::FILE_ERROR_SECURITY:
+ return DOMExceptionCode::kSecurityError;
+ case base::File::FILE_ERROR_INVALID_URL:
+ return DOMExceptionCode::kEncodingError;
+ case base::File::FILE_ERROR_IO:
+ return DOMExceptionCode::kNotReadableError;
+ case base::File::FILE_ERROR_MAX:
+ NOTREACHED();
+ return DOMExceptionCode::kUnknownError;
+ }
+ NOTREACHED();
+ return DOMExceptionCode::kUnknownError;
+}
+
+const char* FileErrorToMessage(base::File::Error code) {
+ // Note that some of these do not set message. If message is null then the
+ // default message is used.
+ switch (code) {
+ case base::File::FILE_ERROR_NOT_FOUND:
+ return kNotFoundErrorMessage;
+ case base::File::FILE_ERROR_ACCESS_DENIED:
+ return kNoModificationAllowedErrorMessage;
+ case base::File::FILE_ERROR_FAILED:
+ return kInvalidStateErrorMessage;
+ case base::File::FILE_ERROR_ABORT:
+ return kAbortErrorMessage;
+ case base::File::FILE_ERROR_SECURITY:
+ return kSecurityErrorMessage;
+ case base::File::FILE_ERROR_NO_SPACE:
+ return kQuotaExceededErrorMessage;
+ case base::File::FILE_ERROR_INVALID_URL:
+ return kEncodingErrorMessage;
+ case base::File::FILE_ERROR_IO:
+ return kNotReadableErrorMessage;
+ case base::File::FILE_ERROR_EXISTS:
+ return kPathExistsErrorMessage;
+ case base::File::FILE_ERROR_NOT_A_DIRECTORY:
+ case base::File::FILE_ERROR_NOT_A_FILE:
+ return kTypeMismatchErrorMessage;
+ case base::File::FILE_OK:
+ case base::File::FILE_ERROR_INVALID_OPERATION:
+ case base::File::FILE_ERROR_NOT_EMPTY:
+ case base::File::FILE_ERROR_NO_MEMORY:
+ case base::File::FILE_ERROR_TOO_MANY_OPENED:
+ case base::File::FILE_ERROR_IN_USE:
+ // TODO(mek): More specific error messages for at least some of these
+ // errors.
+ return nullptr;
+ case base::File::FILE_ERROR_MAX:
+ NOTREACHED();
+ return nullptr;
+ }
+ NOTREACHED();
+ return nullptr;
+}
+
} // namespace
void ThrowDOMException(ExceptionState& exception_state,
@@ -171,6 +253,12 @@ DOMException* CreateDOMException(ErrorCode code) {
ErrorCodeToMessage(code));
}
+DOMException* CreateDOMException(base::File::Error code) {
+ DCHECK_NE(code, base::File::FILE_OK);
+ return DOMException::Create(FileErrorToExceptionCode(code),
+ FileErrorToMessage(code));
+}
+
STATIC_ASSERT_ENUM(kWebFileErrorNotFound, kNotFoundErr);
STATIC_ASSERT_ENUM(kWebFileErrorSecurity, kSecurityErr);
STATIC_ASSERT_ENUM(kWebFileErrorAbort, kAbortErr);
diff --git a/chromium/third_party/blink/renderer/core/fileapi/file_error.h b/chromium/third_party/blink/renderer/core/fileapi/file_error.h
index 4b5408c1479..36aad689b84 100644
--- a/chromium/third_party/blink/renderer/core/fileapi/file_error.h
+++ b/chromium/third_party/blink/renderer/core/fileapi/file_error.h
@@ -31,6 +31,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FILEAPI_FILE_ERROR_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_FILEAPI_FILE_ERROR_H_
+#include "base/files/file.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -73,6 +74,7 @@ CORE_EXPORT void ThrowDOMException(ExceptionState&,
ErrorCode,
String message = String());
CORE_EXPORT DOMException* CreateDOMException(ErrorCode);
+CORE_EXPORT DOMException* CreateDOMException(base::File::Error);
} // namespace FileError
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 ef6ffcadab4..44ac7305177 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
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/fileapi/file_list.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/platform/file_metadata.h"
namespace blink {
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 d2e87ac7ddf..a875dcfde10 100644
--- a/chromium/third_party/blink/renderer/core/fileapi/file_reader.cc
+++ b/chromium/third_party/blink/renderer/core/fileapi/file_reader.cc
@@ -459,16 +459,16 @@ void FileReader::DidFail(FileError::ErrorCode error_code) {
void FileReader::FireEvent(const AtomicString& type) {
probe::AsyncTask async_task(GetExecutionContext(), this, "event");
if (!loader_) {
- DispatchEvent(ProgressEvent::Create(type, false, 0, 0));
+ DispatchEvent(*ProgressEvent::Create(type, false, 0, 0));
return;
}
if (loader_->TotalBytes()) {
- DispatchEvent(ProgressEvent::Create(type, true, loader_->BytesLoaded(),
- *loader_->TotalBytes()));
+ DispatchEvent(*ProgressEvent::Create(type, true, loader_->BytesLoaded(),
+ *loader_->TotalBytes()));
} else {
DispatchEvent(
- ProgressEvent::Create(type, false, loader_->BytesLoaded(), 0));
+ *ProgressEvent::Create(type, false, loader_->BytesLoaded(), 0));
}
}
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 88fa2d46436..6bf6e8d9e9e 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
@@ -365,7 +365,14 @@ void FileReaderLoader::OnDataPipeReadable(MojoResult result) {
FailureType::kMojoPipeUnexpectedReadError);
return;
}
+
+ auto weak_this = weak_factory_.GetWeakPtr();
OnReceivedData(static_cast<const char*>(buffer), num_bytes);
+ // OnReceivedData calls out to our client, which could delete |this|, so
+ // bail out if that happened.
+ if (!weak_this)
+ return;
+
consumer_handle_->EndReadData(num_bytes);
if (BytesLoaded() >= total_bytes_) {
received_all_data_ = true;
diff --git a/chromium/third_party/blink/renderer/core/frame/BUILD.gn b/chromium/third_party/blink/renderer/core/frame/BUILD.gn
index faf80c781f1..5268927624e 100644
--- a/chromium/third_party/blink/renderer/core/frame/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/frame/BUILD.gn
@@ -51,6 +51,7 @@ blink_core_sources("frame") {
"event_handler_registry.cc",
"event_handler_registry.h",
"external.h",
+ "feature_policy_violation_report_body.h",
"find_in_page.cc",
"find_in_page.h",
"frame.cc",
@@ -158,6 +159,7 @@ blink_core_sources("frame") {
"settings_delegate.h",
"smart_clip.cc",
"smart_clip.h",
+ "test_report_body.h",
"use_counter.cc",
"use_counter.h",
"user_activation.cc",
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 7b142845ba1..8a3b46e59a2 100644
--- a/chromium/third_party/blink/renderer/core/frame/ad_tracker.cc
+++ b/chromium/third_party/blink/renderer/core/frame/ad_tracker.cc
@@ -76,7 +76,7 @@ void AdTracker::Will(const probe::CallFunction& probe) {
probe.function->GetScriptOrigin().ResourceName();
String script_url;
if (!resource_name.IsEmpty())
- script_url = ToCoreString(resource_name->ToString());
+ script_url = ToCoreString(resource_name->ToString(ToIsolate(local_root_)));
WillExecuteScript(probe.context, script_url);
}
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 68ca2035ba3..710613e32e9 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
@@ -34,6 +34,11 @@ class TestAdTracker : public AdTracker {
AdTracker::Trace(visitor);
}
+ bool RequestWithUrlTaggedAsAd(const String& url) const {
+ DCHECK(is_ad_.Contains(url));
+ return is_ad_.at(url);
+ }
+
protected:
String ScriptAtTopOfStack(ExecutionContext* execution_context) override {
if (script_at_top_.IsEmpty())
@@ -63,9 +68,12 @@ class TestAdTracker : public AdTracker {
AdTracker::WillSendRequest(execution_context, identifier, document_loader,
resource_request, redirect_response,
fetch_initiator_info, resource_type);
+ is_ad_.insert(resource_request.Url().GetString(),
+ resource_request.IsAdResource());
}
private:
+ HashMap<String, bool> is_ad_;
String script_at_top_;
Member<ExecutionContext> execution_context_;
String ad_suffix_;
@@ -179,11 +187,12 @@ class AdTrackerSimTest : public SimTest {
Persistent<TestAdTracker> ad_tracker_;
};
-// Resources loaded by ad script are tagged as ads.
-TEST_F(AdTrackerSimTest, ResourceLoadedWhileExecutingAdScript) {
- SimRequest ad_resource("https://example.com/ad_script.js", "text/javascript");
- SimRequest vanilla_script("https://example.com/vanilla_script.js",
- "text/javascript");
+// Script loaded by ad script is tagged as ad.
+TEST_F(AdTrackerSimTest, ScriptLoadedWhileExecutingAdScript) {
+ const char kAdUrl[] = "https://example.com/ad_script.js";
+ const char kVanillaUrl[] = "https://example.com/vanilla_script.js";
+ SimRequest ad_resource(kAdUrl, "text/javascript");
+ SimRequest vanilla_script(kVanillaUrl, "text/javascript");
ad_tracker_->SetAdSuffix("ad_script.js");
@@ -196,10 +205,57 @@ TEST_F(AdTrackerSimTest, ResourceLoadedWhileExecutingAdScript) {
)SCRIPT");
vanilla_script.Complete("");
- EXPECT_TRUE(IsKnownAdScript(&GetDocument(),
- String("https://example.com/ad_script.js")));
- EXPECT_TRUE(IsKnownAdScript(&GetDocument(),
- String("https://example.com/vanilla_script.js")));
+ EXPECT_TRUE(IsKnownAdScript(&GetDocument(), kAdUrl));
+ EXPECT_TRUE(IsKnownAdScript(&GetDocument(), kVanillaUrl));
+ EXPECT_TRUE(ad_tracker_->RequestWithUrlTaggedAsAd(kAdUrl));
+ EXPECT_TRUE(ad_tracker_->RequestWithUrlTaggedAsAd(kVanillaUrl));
+}
+
+// Image loaded by ad script is tagged as ad.
+TEST_F(AdTrackerSimTest, ImageLoadedWhileExecutingAdScript) {
+ const char kAdUrl[] = "https://example.com/ad_script.js";
+ const char kVanillaUrl[] = "https://example.com/vanilla_image.jpg";
+ SimRequest ad_resource(kAdUrl, "text/javascript");
+ SimRequest vanilla_image(kVanillaUrl, "image/jpeg");
+
+ 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 = "vanilla_image.jpg";
+ document.body.appendChild(image);
+ )SCRIPT");
+ vanilla_image.Complete("");
+
+ EXPECT_TRUE(IsKnownAdScript(&GetDocument(), kAdUrl));
+ EXPECT_TRUE(ad_tracker_->RequestWithUrlTaggedAsAd(kAdUrl));
+ // TODO(crbug.com/848916): Should be true.
+ EXPECT_FALSE(ad_tracker_->RequestWithUrlTaggedAsAd(kVanillaUrl));
+}
+
+// Frame loaded by ad script is tagged as ad.
+TEST_F(AdTrackerSimTest, FrameLoadedWhileExecutingAdScript) {
+ const char kAdUrl[] = "https://example.com/ad_script.js";
+ const char kVanillaUrl[] = "https://example.com/vanilla_page.html";
+ SimRequest ad_resource(kAdUrl, "text/javascript");
+ SimRequest vanilla_page(kVanillaUrl, "text/html");
+
+ ad_tracker_->SetAdSuffix("ad_script.js");
+
+ main_resource_->Complete("<body></body><script src=ad_script.js></script>");
+
+ ad_resource.Complete(R"SCRIPT(
+ iframe = document.createElement("iframe");
+ iframe.src = "vanilla_page.html";
+ document.body.appendChild(iframe);
+ )SCRIPT");
+ vanilla_page.Complete("");
+
+ EXPECT_TRUE(IsKnownAdScript(&GetDocument(), kAdUrl));
+ EXPECT_TRUE(ad_tracker_->RequestWithUrlTaggedAsAd(kAdUrl));
+ EXPECT_TRUE(ad_tracker_->RequestWithUrlTaggedAsAd(kVanillaUrl));
}
// A script tagged as an ad in one frame shouldn't cause it to be considered
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 2401b6f7711..67af69ff0b5 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
@@ -1420,9 +1420,9 @@ void ContentSecurityPolicy::DispatchViolationEvents(
if (execution_context_->IsWorkletGlobalScope())
return;
- SecurityPolicyViolationEvent* event = SecurityPolicyViolationEvent::Create(
+ SecurityPolicyViolationEvent& event = *SecurityPolicyViolationEvent::Create(
EventTypeNames::securitypolicyviolation, violation_data);
- DCHECK(event->bubbles());
+ DCHECK(event.bubbles());
if (execution_context_->IsDocument()) {
Document* document = ToDocument(execution_context_);
@@ -1895,4 +1895,13 @@ ContentSecurityPolicy::ExposeForNavigationalChecks() const {
return list;
}
+bool ContentSecurityPolicy::HasPolicyFromSource(
+ ContentSecurityPolicyHeaderSource source) const {
+ for (const auto& policy : policies_) {
+ if (policy->HeaderSource() == source)
+ return true;
+ }
+ return false;
+}
+
} // namespace blink
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 d97eb519aab..783a241e7da 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
@@ -461,6 +461,8 @@ class CORE_EXPORT ContentSecurityPolicy
// there is no execution context to enforce the sandbox flags.
SandboxFlags GetSandboxMask() const { return sandbox_mask_; }
+ bool HasPolicyFromSource(ContentSecurityPolicyHeaderSource) const;
+
private:
FRIEND_TEST_ALL_PREFIXES(ContentSecurityPolicyTest, NonceInline);
FRIEND_TEST_ALL_PREFIXES(ContentSecurityPolicyTest, NonceSinglePolicy);
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 ad5c35ac936..f5e347fe099 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,13 +29,24 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
String header = String::FromUTF8(data, size);
unsigned hash = header.IsNull() ? 0 : header.Impl()->GetHash();
+ // Use the 'hash' value to pick header_type and header_source input.
+ // 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;
+ if (hash & 0x02) {
+ header_source = (hash & 0x04)
+ ? kContentSecurityPolicyHeaderSourceMeta
+ : kContentSecurityPolicyHeaderSourceOriginPolicy;
+ }
+
// Construct and initialize a policy from the string.
ContentSecurityPolicy* csp = ContentSecurityPolicy::Create();
- csp->DidReceiveHeader(header,
- hash & 0x01 ? kContentSecurityPolicyHeaderTypeEnforce
- : kContentSecurityPolicyHeaderTypeReport,
- hash & 0x02 ? kContentSecurityPolicyHeaderSourceHTTP
- : kContentSecurityPolicyHeaderSourceMeta);
+ csp->DidReceiveHeader(header, header_type, header_source);
g_page_holder->GetDocument().InitContentSecurityPolicy(csp);
// Force a garbage collection.
diff --git a/chromium/third_party/blink/renderer/core/frame/deprecation.cc b/chromium/third_party/blink/renderer/core/frame/deprecation.cc
index fbe82e389d1..0731a09bdc1 100644
--- a/chromium/third_party/blink/renderer/core/frame/deprecation.cc
+++ b/chromium/third_party/blink/renderer/core/frame/deprecation.cc
@@ -53,6 +53,8 @@ enum Milestone {
kM69,
kM70,
kM71,
+ kM72,
+ kM73,
};
// Returns estimated milestone dates as human-readable strings.
@@ -87,6 +89,10 @@ const char* MilestoneString(Milestone milestone) {
return "M70, around October 2018";
case kM71:
return "M71, around December 2018";
+ case kM72:
+ return "M72, around January 2019";
+ case kM73:
+ return "M73, around March 2019";
}
NOTREACHED();
@@ -97,7 +103,8 @@ const char* MilestoneString(Milestone milestone) {
double MilestoneDate(Milestone milestone) {
// These are the Estimated Stable Dates:
// https://www.chromium.org/developers/calendar
-
+ // All are at 04:00:00 GMT.
+ // TODO(yoichio): We should have something like "Time(March, 6, 2018)".
switch (milestone) {
case kUnknown:
return 0;
@@ -125,6 +132,10 @@ double MilestoneDate(Milestone milestone) {
return 1539662400000; // October 16, 2018.
case kM71:
return 1543899600000; // December 4, 2018.
+ case kM72:
+ return 1548734400000; // January 29, 2019.
+ case kM73:
+ return 1552363200000; // March 12, 2019.
}
NOTREACHED();
@@ -341,15 +352,11 @@ DeprecationInfo GetDeprecationInfo(WebFeature feature) {
case WebFeature::kApplicationCacheManifestSelectInsecureOrigin:
case WebFeature::kApplicationCacheAPIInsecureOrigin:
- return {
- "ApplicationCacheAPIInsecureOrigin", kM69,
- String::Format(
- "Application Cache is deprecated in non-secure contexts, and "
- "will be restricted to secure contexts in %s. Please consider "
- "migrating your application to HTTPS, and eventually shifting "
- "over to Service Workers. See https://goo.gl/rStTGz for more "
- "details.",
- MilestoneString(kM69))};
+ return {"ApplicationCacheAPIInsecureOrigin", kM70,
+ "Application Cache is restricted to secure contexts. Please "
+ "consider migrating your application to HTTPS, and eventually "
+ "shifting over to Service Workers. See https://goo.gl/rStTGz for "
+ "more details."};
case WebFeature::kNotificationInsecureOrigin:
case WebFeature::kNotificationAPIInsecureOriginIframe:
@@ -449,12 +456,22 @@ DeprecationInfo GetDeprecationInfo(WebFeature feature) {
WillBeRemoved("The step timing function with step position 'middle'",
kM62, "5189363944128512")};
- case WebFeature::kHTMLImportsHasStyleSheets:
- return {"HTMLImportsHasStyleSheets", kUnknown,
- "Styling master document from stylesheets defined in "
- "HTML Imports is deprecated. "
- "Please refer to "
- "https://goo.gl/EGXzpw for possible migration paths."};
+ case WebFeature::kHTMLImports:
+ return {"DeprecatedHTMLImports", kM73,
+ ReplacedWillBeRemoved("HTML Imports", "ES modules", kM73,
+ "5144752345317376")};
+
+ case WebFeature::kElementCreateShadowRoot:
+ return {"ElementCreateShadowRoot", kM73,
+ ReplacedWillBeRemoved("Element.createShadowRoot",
+ "Element.attachShadow", kM73,
+ "4507242028072960")};
+
+ case WebFeature::kDocumentRegisterElement:
+ return {"DocumentRegisterElement", kM73,
+ ReplacedWillBeRemoved("document.registerElement",
+ "window.customElements.define", kM73,
+ "4642138092470272")};
case WebFeature::
kEncryptedMediaDisallowedByFeaturePolicyInCrossOriginIframe:
@@ -544,29 +561,24 @@ DeprecationInfo GetDeprecationInfo(WebFeature feature) {
"self.origin (window.origin)", kM70,
"5701042356355072")};
- case WebFeature::kHTMLFrameSetElementAnonymousNamedGetter:
- return {"HTMLFrameSetElementAnonymousNamedGetter", kM70,
- WillBeRemoved("Anonymous named getter of HTMLFrameSetElement",
- kM70, "5235521668251648")};
-
case WebFeature::kMediaElementSourceOnOfflineContext:
- return {"MediaElementAudioSourceNode", kM70,
+ return {"MediaElementAudioSourceNode", kM71,
WillBeRemoved("Creating a MediaElementAudioSourceNode on an "
"OfflineAudioContext",
- kM70, "5258622686724096")};
+ kM71, "5258622686724096")};
case WebFeature::kMediaStreamDestinationOnOfflineContext:
- return {"MediaStreamAudioDestinationNode", kM70,
+ return {"MediaStreamAudioDestinationNode", kM71,
WillBeRemoved("Creating a MediaStreamAudioDestinationNode on an "
"OfflineAudioContext",
- kM70, "5258622686724096")};
+ kM71, "5258622686724096")};
case WebFeature::kMediaStreamSourceOnOfflineContext:
return {
- "MediaStreamAudioSourceNode", kM70,
+ "MediaStreamAudioSourceNode", kM71,
WillBeRemoved(
"Creating a MediaStreamAudioSourceNode on an OfflineAudioContext",
- kM70, "5258622686724096")};
+ kM71, "5258622686724096")};
case WebFeature::kRTCDataChannelInitMaxRetransmitTime:
return {"RTCDataChannelInitMaxRetransmitTime", kM70,
@@ -583,6 +595,22 @@ DeprecationInfo GetDeprecationInfo(WebFeature feature) {
"https://www.chromestatus.com/feature/"
"6708326821789696 for more details.",
MilestoneString(kM70))};
+ case WebFeature::kTextToSpeech_SpeakDisallowedByAutoplay:
+ return {"TextToSpeech_DisallowedByAutoplay", kM71,
+ WillBeRemoved("speechSynthesis.speak() without user activation",
+ kM71, "5687444770914304")};
+
+ case WebFeature::kPPAPIWebSocket:
+ // TODO(ricea): Update once we have an expected release date for M74.
+ return {"PPAPIWebSocket", kUnknown,
+ "The Native Client Pepper WebSocket API is deprecated and will "
+ "be disabled in M74, mid-2019"};
+
+ case WebFeature::kServiceWorkerImportScriptNotInstalled:
+ return {"ServiceWorkerImportScriptNotInstalled", kM71,
+ WillBeRemoved("importScripts() of new scripts after service "
+ "worker installation",
+ kM71, "5748516353736704")};
// Features that aren't deprecated don't have a deprecation message.
default:
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 b8aeb9c22df..e8049050ae0 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
@@ -30,7 +30,7 @@ void DeviceSingleWindowEventController::DispatchDeviceEvent(Event* event) {
GetDocument().IsContextDestroyed())
return;
- GetDocument().domWindow()->DispatchEvent(event);
+ GetDocument().domWindow()->DispatchEvent(*event);
if (needs_checking_null_events_) {
if (IsNullEvent(event))
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 21c4cd01f89..3c1da181b37 100644
--- a/chromium/third_party/blink/renderer/core/frame/dom_window.cc
+++ b/chromium/third_party/blink/renderer/core/frame/dom_window.cc
@@ -6,6 +6,7 @@
#include <memory>
+#include "third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.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"
@@ -19,6 +20,7 @@
#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/use_counter.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"
@@ -116,12 +118,13 @@ void DOMWindow::postMessage(LocalDOMWindow* incumbent_window,
ExceptionState& exception_state) {
WindowPostMessageOptions options;
options.setTargetOrigin(target_origin);
- postMessage(incumbent_window, message, transfer, options, exception_state);
+ if (!transfer.IsEmpty())
+ options.setTransfer(transfer);
+ postMessage(incumbent_window, message, options, exception_state);
}
void DOMWindow::postMessage(LocalDOMWindow* incumbent_window,
const ScriptValue& message,
- Vector<ScriptValue>& transfer,
const WindowPostMessageOptions& options,
ExceptionState& exception_state) {
UseCounter::Count(incumbent_window->GetFrame(),
@@ -133,24 +136,14 @@ void DOMWindow::postMessage(LocalDOMWindow* incumbent_window,
v8::Isolate* isolate = window_proxy_manager_->GetIsolate();
Transferables transferables;
- if (!transfer.IsEmpty()) {
- if (!SerializedScriptValue::ExtractTransferables(
- isolate, transfer, transferables, exception_state)) {
- return;
- }
- }
-
- SerializedScriptValue::SerializeOptions serialize_options;
- serialize_options.transferables = &transferables;
scoped_refptr<SerializedScriptValue> serialized_message =
- SerializedScriptValue::Serialize(isolate, message.V8Value(),
- serialize_options, exception_state);
+ PostMessageHelper::SerializeMessageByMove(isolate, message, options,
+ transferables, exception_state);
if (exception_state.HadException())
return;
-
- serialized_message->UnregisterMemoryAllocatedWithCurrentScriptContext();
+ DCHECK(serialized_message);
DoPostMessage(std::move(serialized_message), transferables.message_ports,
- options.targetOrigin(), incumbent_window, exception_state);
+ options, incumbent_window, exception_state);
}
DOMWindow* DOMWindow::AnonymousIndexedGetter(uint32_t index) const {
@@ -405,13 +398,14 @@ void DOMWindow::PostMessageForTesting(
const String& target_origin,
LocalDOMWindow* source,
ExceptionState& exception_state) {
- DoPostMessage(std::move(message), ports, target_origin, source,
- exception_state);
+ WindowPostMessageOptions options;
+ options.setTargetOrigin(target_origin);
+ DoPostMessage(std::move(message), ports, options, source, exception_state);
}
void DOMWindow::DoPostMessage(scoped_refptr<SerializedScriptValue> message,
const MessagePortArray& ports,
- const String& target_origin,
+ const WindowPostMessageOptions& options,
LocalDOMWindow* source,
ExceptionState& exception_state) {
if (!IsCurrentlyDisplayedInFrame())
@@ -419,6 +413,8 @@ void DOMWindow::DoPostMessage(scoped_refptr<SerializedScriptValue> message,
Document* source_document = source->document();
+ const String& target_origin = options.targetOrigin();
+
// Compute the target origin. We need to do this synchronously in order
// to generate the SyntaxError exception correctly.
scoped_refptr<const SecurityOrigin> target;
@@ -483,9 +479,13 @@ void DOMWindow::DoPostMessage(scoped_refptr<SerializedScriptValue> message,
source->GetFrame(),
WebFeature::kPostMessageOutgoingWouldBeBlockedByConnectSrc);
}
+ UserActivation* user_activation = nullptr;
+ if (options.includeUserActivation())
+ user_activation = UserActivation::CreateSnapshot(source);
- MessageEvent* event = MessageEvent::Create(
- std::move(channels), std::move(message), source_origin, String(), source);
+ MessageEvent* event =
+ MessageEvent::Create(std::move(channels), std::move(message),
+ source_origin, String(), source, user_activation);
SchedulePostMessage(event, std::move(target), source_document);
}
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 31905b58793..58a3f12a0ce 100644
--- a/chromium/third_party/blink/renderer/core/frame/dom_window.h
+++ b/chromium/third_party/blink/renderer/core/frame/dom_window.h
@@ -95,7 +95,6 @@ class CORE_EXPORT DOMWindow : public EventTargetWithInlineData,
void postMessage(LocalDOMWindow* incumbent_window,
const ScriptValue& message,
- Vector<ScriptValue>& transfer,
const WindowPostMessageOptions& options,
ExceptionState&);
@@ -137,7 +136,7 @@ class CORE_EXPORT DOMWindow : public EventTargetWithInlineData,
private:
void DoPostMessage(scoped_refptr<SerializedScriptValue> message,
const MessagePortArray&,
- const String& target_origin,
+ const WindowPostMessageOptions& options,
LocalDOMWindow* source,
ExceptionState&);
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 fb49073f4cc..77fb4065891 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
@@ -69,6 +69,11 @@ bool EventHandlerRegistry::EventTypeToClass(
event_type == EventTypeNames::touchmove) {
*result = options.passive() ? kTouchStartOrMoveEventPassive
: kTouchStartOrMoveEventBlocking;
+ } else if (event_type == EventTypeNames::pointerrawmove) {
+ // This will be used to avoid waking up the main thread to
+ // process pointerrawmove events and hit-test them when
+ // there is no listener on the page.
+ *result = kPointerRawMoveEvent;
} else if (EventUtil::IsPointerEventType(event_type)) {
// The pointer events never block scrolling and the compositor
// only needs to know about the touch listeners.
@@ -271,6 +276,12 @@ void EventHandlerRegistry::NotifyHasHandlersChanged(
HasEventHandlers(kTouchStartOrMoveEventPassive) ||
HasEventHandlers(kPointerEvent)));
break;
+ case kPointerRawMoveEvent:
+ GetPage()->GetChromeClient().SetEventListenerProperties(
+ frame, cc::EventListenerClass::kPointerRawMove,
+ GetEventListenerProperties(false,
+ HasEventHandlers(kPointerRawMoveEvent)));
+ break;
case kTouchEndOrCancelEventBlocking:
case kTouchEndOrCancelEventPassive:
GetPage()->GetChromeClient().SetEventListenerProperties(
@@ -292,8 +303,14 @@ void EventHandlerRegistry::NotifyHasHandlersChanged(
if (handler_class == kTouchStartOrMoveEventBlocking ||
handler_class == kTouchStartOrMoveEventBlockingLowLatency) {
if (auto* node = target->ToNode()) {
- if (auto* layout_object = node->GetLayoutObject())
+ if (auto* layout_object = node->GetLayoutObject()) {
layout_object->MarkEffectiveWhitelistedTouchActionChanged();
+ auto* continuation = layout_object->VirtualContinuation();
+ while (continuation) {
+ continuation->MarkEffectiveWhitelistedTouchActionChanged();
+ continuation = continuation->VirtualContinuation();
+ }
+ }
} else if (auto* dom_window = target->ToLocalDOMWindow()) {
// This event handler is on a window. Ensure the layout view is
// invalidated because the layout view tracks the window's blocking
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 da98d722d5a..d841a519fc9 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
@@ -41,7 +41,8 @@ class CORE_EXPORT EventHandlerRegistry final
kTouchStartOrMoveEventPassive,
kTouchEndOrCancelEventBlocking,
kTouchEndOrCancelEventPassive,
- kPointerEvent,
+ kPointerEvent, // This includes all pointerevents excluding pointerrawmove.
+ kPointerRawMoveEvent,
#if DCHECK_IS_ON()
// Additional event categories for verifying handler tracking logic.
kEventsForTesting,
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
new file mode 100644
index 00000000000..b0a54f2e167
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/frame/feature_policy_violation_report_body.h
@@ -0,0 +1,32 @@
+// 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_FRAME_FEATURE_POLICY_VIOLATION_REPORT_BODY_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_FEATURE_POLICY_VIOLATION_REPORT_BODY_H_
+
+#include "third_party/blink/renderer/bindings/core/v8/source_location.h"
+#include "third_party/blink/renderer/core/frame/message_report_body.h"
+
+namespace blink {
+
+class CORE_EXPORT FeaturePolicyViolationReportBody : public MessageReportBody {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ FeaturePolicyViolationReportBody(const String& feature,
+ const String& message,
+ std::unique_ptr<SourceLocation> location)
+ : MessageReportBody(message, std::move(location)), feature_(feature) {}
+
+ String feature() const { return feature_; }
+
+ ~FeaturePolicyViolationReportBody() override = default;
+
+ private:
+ const String feature_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_FEATURE_POLICY_VIOLATION_REPORT_BODY_H_
diff --git a/chromium/third_party/blink/renderer/core/frame/feature_policy_violation_report_body.idl b/chromium/third_party/blink/renderer/core/frame/feature_policy_violation_report_body.idl
new file mode 100644
index 00000000000..16cd1a019ca
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/frame/feature_policy_violation_report_body.idl
@@ -0,0 +1,16 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://github.com/WICG/reporting/blob/master/EXPLAINER.md#reportingobserver---observing-reports-from-javascript
+
+[
+ NoInterfaceObject,
+ RuntimeEnabled=ReportingObserver
+] interface FeaturePolicyViolationReportBody : ReportBody {
+ readonly attribute DOMString feature;
+ readonly attribute DOMString message;
+ readonly attribute DOMString? sourceFile;
+ readonly attribute unsigned long? lineNumber;
+ readonly attribute unsigned long? columnNumber;
+};
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 c1a4a34c3a7..5866de60510 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
@@ -35,18 +35,18 @@
#include "third_party/blink/public/web/web_local_frame_client.h"
#include "third_party/blink/public/web/web_plugin.h"
#include "third_party/blink/public/web/web_plugin_document.h"
+#include "third_party/blink/public/web/web_widget_client.h"
#include "third_party/blink/renderer/core/editing/finder/text_finder.h"
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.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"
namespace blink {
FindInPage::FindInPage(WebLocalFrameImpl& frame,
InterfaceRegistry* interface_registry)
- : ContextLifecycleObserver(
- frame.GetFrame() ? frame.GetFrame()->GetDocument() : nullptr),
- frame_(&frame),
- binding_(this) {
+ : frame_(&frame), binding_(this) {
// TODO(rakina): Use InterfaceRegistry of |frame| directly rather than passing
// both of them.
if (!interface_registry)
@@ -57,19 +57,31 @@ FindInPage::FindInPage(WebLocalFrameImpl& frame,
WTF::BindRepeating(&FindInPage::BindToRequest, WrapWeakPersistent(this)));
}
-void WebLocalFrameImpl::RequestFind(int identifier,
- const WebString& search_text,
- const WebFindOptions& options) {
- find_in_page_->RequestFind(identifier, search_text, options);
-}
+void FindInPage::Find(int request_id,
+ const String& search_text,
+ mojom::blink::FindOptionsPtr options) {
+ DCHECK(!search_text.IsEmpty());
+ blink::WebPlugin* plugin = GetWebPluginForFind();
+ // Check if the plugin still exists in the document.
+ if (plugin) {
+ if (options->find_next) {
+ // Just navigate back/forward.
+ plugin->SelectFindResult(options->forward, request_id);
+ LocalFrame* core_frame = frame_->GetFrame();
+ core_frame->GetPage()->GetFocusController().SetFocusedFrame(core_frame);
+ } else if (!plugin->StartFind(search_text, options->match_case,
+ request_id)) {
+ // Send "no results"
+ ReportFindInPageMatchCount(request_id, 0 /* count */,
+ true /* final_update */);
+ }
+ return;
+ }
-void FindInPage::RequestFind(int identifier,
- const WebString& search_text,
- const WebFindOptions& options) {
// Send "no results" if this frame has no visible content.
- if (!frame_->HasVisibleContent() && !options.force) {
- frame_->Client()->ReportFindInPageMatchCount(identifier, 0 /* count */,
- true /* finalUpdate */);
+ if (!frame_->HasVisibleContent() && !options->force) {
+ ReportFindInPageMatchCount(request_id, 0 /* count */,
+ true /* final_update */);
return;
}
@@ -77,18 +89,26 @@ void FindInPage::RequestFind(int identifier,
bool result = false;
bool active_now = false;
+ WebFindOptions web_options;
+ web_options.forward = options->forward;
+ web_options.match_case = options->match_case;
+ web_options.find_next = options->find_next;
+ web_options.force = options->force;
+ web_options.run_synchronously_for_testing =
+ options->run_synchronously_for_testing;
+
// Search for an active match only if this frame is focused or if this is a
// find next request.
- if (frame_->IsFocused() || options.find_next) {
- result = frame_->Find(identifier, search_text, options,
- false /* wrapWithinFrame */, &active_now);
+ if (frame_->IsFocused() || options->find_next) {
+ result = FindInternal(request_id, search_text, web_options,
+ false /* wrap_within_frame */, &active_now);
}
- if (result && !options.find_next) {
+ if (result && !options->find_next) {
// Indicate that at least one match has been found. 1 here means
// possibly more matches could be coming.
- frame_->Client()->ReportFindInPageMatchCount(identifier, 1 /* count */,
- false /* finalUpdate */);
+ ReportFindInPageMatchCount(request_id, 1 /* count */,
+ false /* final_update */);
}
// There are three cases in which scoping is needed:
@@ -109,17 +129,17 @@ void FindInPage::RequestFind(int identifier,
//
// If none of these cases are true, then we just report the current match
// count without scoping.
- if (/* (1) */ options.find_next && /* (2) */ current_selection.IsNull() &&
+ if (/* (1) */ options->find_next && /* (2) */ current_selection.IsNull() &&
/* (3) */ !(result && !active_now)) {
// Force report of the actual count.
- EnsureTextFinder().IncreaseMatchCount(identifier, 0);
+ EnsureTextFinder().IncreaseMatchCount(request_id, 0);
return;
}
// Start a new scoping request. If the scoping function determines that it
// needs to scope, it will defer until later.
- EnsureTextFinder().StartScopingStringMatches(identifier, search_text,
- options);
+ EnsureTextFinder().StartScopingStringMatches(request_id, search_text,
+ web_options);
}
bool WebLocalFrameImpl::Find(int identifier,
@@ -127,15 +147,15 @@ bool WebLocalFrameImpl::Find(int identifier,
const WebFindOptions& options,
bool wrap_within_frame,
bool* active_now) {
- return find_in_page_->Find(identifier, search_text, options,
- wrap_within_frame, active_now);
+ return find_in_page_->FindInternal(identifier, search_text, options,
+ wrap_within_frame, active_now);
}
-bool FindInPage::Find(int identifier,
- const WebString& search_text,
- const WebFindOptions& options,
- bool wrap_within_frame,
- bool* active_now) {
+bool FindInPage::FindInternal(int identifier,
+ const WebString& search_text,
+ const WebFindOptions& options,
+ bool wrap_within_frame,
+ bool* active_now) {
if (!frame_->GetFrame())
return false;
@@ -197,9 +217,8 @@ WebFloatRect FindInPage::ActiveFindMatchRect() {
return WebFloatRect();
}
-void FindInPage::ActivateNearestFindResult(
- const WebFloatPoint& point,
- ActivateNearestFindResultCallback callback) {
+void FindInPage::ActivateNearestFindResult(int request_id,
+ const WebFloatPoint& point) {
WebRect active_match_rect;
const int ordinal =
EnsureTextFinder().SelectNearestFindMatch(point, &active_match_rect);
@@ -207,17 +226,15 @@ void FindInPage::ActivateNearestFindResult(
// Something went wrong, so send a no-op reply (force the frame to report
// the current match count) in case the host is waiting for a response due
// to rate-limiting.
- int number_of_matches = EnsureTextFinder().TotalMatchCount();
- std::move(callback).Run(WebRect(), number_of_matches,
- -1 /* active_match_ordinal */,
- !EnsureTextFinder().FrameScoping() ||
- !number_of_matches /* final_reply */);
+ EnsureTextFinder().IncreaseMatchCount(request_id, 0);
return;
}
- // Call callback with current active match's rect and its ordinal,
- // and don't update total number of matches.
- std::move(callback).Run(active_match_rect, -1 /* number_of_matches */,
- ordinal, true /* final_reply*/);
+ ReportFindInPageSelection(request_id, ordinal, active_match_rect,
+ true /* final_update */);
+}
+
+void FindInPage::SetClient(mojom::blink::FindInPageClientPtr client) {
+ client_ = std::move(client);
}
void FindInPage::GetNearestFindResult(const WebFloatPoint& point,
@@ -282,10 +299,6 @@ WebPluginContainer* FindInPage::PluginFindHandler() const {
return plugin_find_handler_;
}
-WebPlugin* WebLocalFrameImpl::GetWebPluginForFind() {
- return find_in_page_->GetWebPluginForFind();
-}
-
WebPlugin* FindInPage::GetWebPluginForFind() {
if (frame_->GetDocument().IsPluginDocument())
return frame_->GetDocument().To<WebPluginDocument>().Plugin();
@@ -303,8 +316,29 @@ void FindInPage::Dispose() {
binding_.Close();
}
-void FindInPage::ContextDestroyed(ExecutionContext* context) {
- binding_.Close();
+void FindInPage::ReportFindInPageMatchCount(int request_id,
+ int count,
+ bool final_update) {
+ // In tests, |client_| might not be set.
+ if (!client_)
+ return;
+ client_->SetNumberOfMatches(
+ request_id, count,
+ final_update ? mojom::blink::FindMatchUpdateType::kFinalUpdate
+ : mojom::blink::FindMatchUpdateType::kMoreUpdatesComing);
+}
+
+void FindInPage::ReportFindInPageSelection(int request_id,
+ int active_match_ordinal,
+ const blink::WebRect& selection_rect,
+ bool final_update) {
+ // In tests, |client_| might not be set.
+ if (!client_)
+ return;
+ client_->SetActiveMatch(
+ request_id, selection_rect, active_match_ordinal,
+ final_update ? mojom::blink::FindMatchUpdateType::kFinalUpdate
+ : mojom::blink::FindMatchUpdateType::kMoreUpdatesComing);
}
} // namespace blink
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 cd5c66b285c..921687cbaa6 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
@@ -25,9 +25,7 @@ struct WebFloatRect;
class CORE_EXPORT FindInPage final
: public GarbageCollectedFinalized<FindInPage>,
- public ContextLifecycleObserver,
public mojom::blink::FindInPage {
- USING_PRE_FINALIZER(FindInPage, Dispose);
public:
static FindInPage* Create(WebLocalFrameImpl& frame,
@@ -35,15 +33,11 @@ class CORE_EXPORT FindInPage final
return new FindInPage(frame, interface_registry);
}
- void RequestFind(int identifier,
- const WebString& search_text,
- const WebFindOptions&);
-
- bool Find(int identifier,
- const WebString& search_text,
- const WebFindOptions&,
- bool wrap_within_frame,
- bool* active_now = nullptr);
+ bool FindInternal(int identifier,
+ const WebString& search_text,
+ const WebFindOptions&,
+ bool wrap_within_frame,
+ bool* active_now = nullptr);
void SetTickmarks(const WebVector<WebRect>&);
@@ -54,10 +48,21 @@ class CORE_EXPORT FindInPage final
// coordinates.
WebFloatRect 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,
+ bool final_update);
+
// mojom::blink::FindInPage overrides
+ void Find(int request_id,
+ const String& search_text,
+ mojom::blink::FindOptionsPtr) final;
- void ActivateNearestFindResult(const WebFloatPoint&,
- ActivateNearestFindResultCallback) final;
+ void SetClient(mojom::blink::FindInPageClientPtr) final;
+
+ void ActivateNearestFindResult(int request_id, const WebFloatPoint&) final;
// Stops the current find-in-page, following the given |action|
void StopFinding(mojom::StopFindAction action) final;
@@ -90,12 +95,9 @@ class CORE_EXPORT FindInPage final
void Dispose();
- void ContextDestroyed(ExecutionContext*) override;
-
- void Trace(blink::Visitor* visitor) override {
+ void Trace(blink::Visitor* visitor) {
visitor->Trace(text_finder_);
visitor->Trace(frame_);
- ContextLifecycleObserver::Trace(visitor);
}
private:
@@ -108,6 +110,8 @@ class CORE_EXPORT FindInPage final
const Member<WebLocalFrameImpl> frame_;
+ mojom::blink::FindInPageClientPtr client_;
+
mojo::AssociatedBinding<mojom::blink::FindInPage> binding_;
DISALLOW_COPY_AND_ASSIGN(FindInPage);
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 7f1ed1c33c4..b1c01f09f4e 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
@@ -81,13 +81,12 @@ TEST_F(FindInPageTest, FindMatchRectsReturnsCorrectRects) {
int identifier = 0;
WebString search_text(String("aA"));
- WebFindOptions find_options; // Default.
+ WebFindOptions find_options; // Default + add testing flag.
+ find_options.run_synchronously_for_testing = true;
GetTextFinder().ResetMatchCount();
GetTextFinder().StartScopingStringMatches(identifier, search_text,
find_options);
- while (GetTextFinder().ScopingInProgress())
- RunPendingTasks();
int rects_version = GetTextFinder().FindMatchMarkersVersion();
FindInPageCallbackReceiver callback_receiver;
diff --git a/chromium/third_party/blink/renderer/core/frame/frame.cc b/chromium/third_party/blink/renderer/core/frame/frame.cc
index 660c3ac07b3..2e50c68a659 100644
--- a/chromium/third_party/blink/renderer/core/frame/frame.cc
+++ b/chromium/third_party/blink/renderer/core/frame/frame.cc
@@ -248,14 +248,18 @@ bool Frame::ConsumeTransientUserActivation(
: UserGestureIndicator::ConsumeUserGesture();
}
-bool Frame::IsFeatureEnabled(mojom::FeaturePolicyFeature feature) const {
+bool Frame::IsFeatureEnabled(mojom::FeaturePolicyFeature feature,
+ ReportOptions report_on_failure) const {
FeaturePolicy* feature_policy = GetSecurityContext()->GetFeaturePolicy();
// The policy should always be initialized before checking it to ensure we
// properly inherit the parent policy.
DCHECK(feature_policy);
- // Otherwise, check policy.
- return feature_policy->IsFeatureEnabled(feature);
+ if (feature_policy->IsFeatureEnabled(feature))
+ return true;
+ if (report_on_failure == ReportOptions::kReportOnFailure)
+ ReportFeaturePolicyViolation(feature);
+ return false;
}
void Frame::SetOwner(FrameOwner* owner) {
diff --git a/chromium/third_party/blink/renderer/core/frame/frame.h b/chromium/third_party/blink/renderer/core/frame/frame.h
index 9dd4cf19433..1e11f071d45 100644
--- a/chromium/third_party/blink/renderer/core/frame/frame.h
+++ b/chromium/third_party/blink/renderer/core/frame/frame.h
@@ -39,7 +39,6 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/user_gesture_indicator.h"
#include "third_party/blink/renderer/core/frame/frame_lifecycle.h"
-#include "third_party/blink/renderer/core/frame/frame_types.h"
#include "third_party/blink/renderer/core/frame/frame_view.h"
#include "third_party/blink/renderer/core/loader/frame_loader_types.h"
#include "third_party/blink/renderer/core/page/frame_tree.h"
@@ -72,6 +71,10 @@ enum class FrameDetachType { kRemove, kSwap };
// Status of user gesture.
enum class UserGestureStatus { kActive, kNone };
+// Whether to report policy violations when checking whether a feature is
+// enabled.
+enum class ReportOptions { kReportOnFailure, kDoNotReport };
+
// 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.
@@ -102,7 +105,6 @@ class CORE_EXPORT Frame : public GarbageCollectedFinalized<Frame> {
UserGestureStatus) = 0;
// Synchronously begins a navigation.
virtual void Navigate(const FrameLoadRequest&) = 0;
- virtual void Reload(WebFrameLoadType, ClientRedirectPolicy) = 0;
// The base Detach() method must be the last line of overrides of Detach().
virtual void Detach(FrameDetachType);
@@ -225,9 +227,15 @@ class CORE_EXPORT Frame : public GarbageCollectedFinalized<Frame> {
return lifecycle_.GetState() == FrameLifecycle::kAttached;
}
- // Tests whether the feature-policy controlled feature is enabled by policy in
- // the given frame.
- bool IsFeatureEnabled(mojom::FeaturePolicyFeature) const;
+ // 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.
+ bool IsFeatureEnabled(
+ mojom::FeaturePolicyFeature,
+ ReportOptions report_on_failure = ReportOptions::kDoNotReport) const;
+ virtual void ReportFeaturePolicyViolation(mojom::FeaturePolicyFeature) const {
+ }
// 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
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 25b337f1269..cf9cee1cc34 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
@@ -44,7 +44,7 @@
#include "third_party/blink/public/platform/web_url_request.h"
#include "third_party/blink/public/platform/web_url_response.h"
#include "third_party/blink/public/web/web_frame_widget.h"
-#include "third_party/blink/public/web/web_navigation_timings.h"
+#include "third_party/blink/public/web/web_navigation_params.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_view_client.h"
@@ -78,13 +78,13 @@ namespace {
// progress, it exits the run loop.
// 7. At this point, all parsing, resource loads, and layout should be finished.
-void RunServeAsyncRequestsTask() {
+void RunServeAsyncRequestsTask(scoped_refptr<base::TaskRunner> task_runner) {
// TODO(kinuko,toyoshim): Create a mock factory and use it instead of
// getting the platform's one. (crbug.com/751425)
Platform::Current()->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
if (TestWebFrameClient::IsLoading()) {
- Platform::Current()->CurrentThread()->GetTaskRunner()->PostTask(
- FROM_HERE, WTF::Bind(&RunServeAsyncRequestsTask));
+ task_runner->PostTask(FROM_HERE,
+ WTF::Bind(&RunServeAsyncRequestsTask, task_runner));
} else {
test::ExitRunLoop();
}
@@ -101,11 +101,13 @@ std::unique_ptr<T> CreateDefaultClientIfNeeded(T*& client) {
return owned_client;
}
-WebNavigationTimings BuildDummyWebNavigationTimings() {
- WebNavigationTimings web_navigation_timings;
- web_navigation_timings.navigation_start = base::TimeTicks::Now();
- web_navigation_timings.fetch_start = base::TimeTicks::Now();
- return web_navigation_timings;
+std::unique_ptr<WebNavigationParams> BuildDummyNavigationParams() {
+ std::unique_ptr<WebNavigationParams> navigation_params =
+ std::make_unique<WebNavigationParams>();
+ navigation_params->navigation_timings.navigation_start =
+ base::TimeTicks::Now();
+ navigation_params->navigation_timings.fetch_start = base::TimeTicks::Now();
+ return navigation_params;
}
} // namespace
@@ -118,16 +120,16 @@ void LoadFrame(WebLocalFrame* frame, const std::string& url) {
frame->CommitNavigation(
WebURLRequest(web_url), blink::WebFrameLoadType::kStandard,
blink::WebHistoryItem(), false, base::UnguessableToken::Create(),
- nullptr, BuildDummyWebNavigationTimings());
+ BuildDummyNavigationParams(), nullptr /* extra_data */);
}
- PumpPendingRequestsForFrameToLoad();
+ PumpPendingRequestsForFrameToLoad(frame);
}
void LoadHTMLString(WebLocalFrame* frame,
const std::string& html,
const WebURL& base_url) {
frame->LoadHTMLString(WebData(html.data(), html.size()), base_url);
- PumpPendingRequestsForFrameToLoad();
+ PumpPendingRequestsForFrameToLoad(frame);
}
void LoadHistoryItem(WebLocalFrame* frame,
@@ -136,25 +138,27 @@ void LoadHistoryItem(WebLocalFrame* frame,
HistoryItem* history_item = item;
frame->CommitNavigation(
WrappedResourceRequest(history_item->GenerateResourceRequest(cache_mode)),
- WebFrameLoadType::kBackForward, item,
- /*is_client_redirect=*/false, base::UnguessableToken::Create(), nullptr,
- BuildDummyWebNavigationTimings());
- PumpPendingRequestsForFrameToLoad();
+ WebFrameLoadType::kBackForward, item, false /* is_client_redirect */,
+ base::UnguessableToken::Create(), BuildDummyNavigationParams(),
+ nullptr /* extra_data */);
+ PumpPendingRequestsForFrameToLoad(frame);
}
void ReloadFrame(WebLocalFrame* frame) {
frame->StartReload(WebFrameLoadType::kReload);
- PumpPendingRequestsForFrameToLoad();
+ PumpPendingRequestsForFrameToLoad(frame);
}
void ReloadFrameBypassingCache(WebLocalFrame* frame) {
frame->StartReload(WebFrameLoadType::kReloadBypassingCache);
- PumpPendingRequestsForFrameToLoad();
+ PumpPendingRequestsForFrameToLoad(frame);
}
-void PumpPendingRequestsForFrameToLoad() {
- Platform::Current()->CurrentThread()->GetTaskRunner()->PostTask(
- FROM_HERE, WTF::Bind(&RunServeAsyncRequestsTask));
+void PumpPendingRequestsForFrameToLoad(WebLocalFrame* frame) {
+ scoped_refptr<base::TaskRunner> task_runner =
+ frame->GetTaskRunner(blink::TaskType::kInternalTest);
+ task_runner->PostTask(FROM_HERE,
+ WTF::Bind(&RunServeAsyncRequestsTask, task_runner));
test::EnterRunLoop();
}
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 644cec99b7b..ceabae359f7 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
@@ -55,9 +55,9 @@
#include "third_party/blink/public/web/web_view_client.h"
#include "third_party/blink/renderer/core/exported/web_view_impl.h"
#include "third_party/blink/renderer/core/frame/settings.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
#include "third_party/blink/renderer/core/testing/use_mock_scrollbar_settings.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h"
#define EXPECT_FLOAT_POINT_EQ(expected, actual) \
do { \
@@ -111,7 +111,7 @@ void ReloadFrameBypassingCache(WebLocalFrame*);
// Pumps pending resource requests while waiting for a frame to load. Consider
// using one of the above helper methods whenever possible.
-void PumpPendingRequestsForFrameToLoad();
+void PumpPendingRequestsForFrameToLoad(WebLocalFrame*);
WebMouseEvent CreateMouseEvent(WebInputEvent::Type,
WebMouseEvent::Button,
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 cac4c748fcf..fbb4717268b 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
@@ -90,7 +90,10 @@ void FrameViewAutoSizeInfo::AutoSizeIfNeeded() {
kHorizontalScrollbar));
// Don't bother checking for a vertical scrollbar because the width is at
// already greater the maximum.
- } else if (new_size.Height() > max_auto_size_.Height()) {
+ } 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.
+ !layout_viewport->HasVerticalScrollbar()) {
new_size.Expand(
layout_viewport->HypotheticalScrollbarThickness(kVerticalScrollbar),
0);
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 cbd15aa4a83..a64cf520db0 100644
--- a/chromium/third_party/blink/renderer/core/frame/fullscreen_controller.cc
+++ b/chromium/third_party/blink/renderer/core/frame/fullscreen_controller.cc
@@ -75,12 +75,18 @@ void FullscreenController::DidEnterFullscreen() {
UpdatePageScaleConstraints(false);
web_view_base_->SetPageScaleFactor(1.0f);
- if (web_view_base_->MainFrame()->IsWebLocalFrame())
- web_view_base_->MainFrame()->ToWebLocalFrame()->SetScrollOffset(WebSize());
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);
+ }
+ }
+
// Notify all local frames that we have entered fullscreen.
for (Frame* frame = web_view_base_->GetPage()->MainFrame(); frame;
frame = frame->Tree().TraverseNext()) {
@@ -89,6 +95,7 @@ void FullscreenController::DidEnterFullscreen() {
if (Document* document = ToLocalFrame(frame)->GetDocument())
Fullscreen::DidEnterFullscreen(*document);
}
+ pending_frames_.clear();
// TODO(foolip): If the top level browsing context (main frame) ends up with
// no fullscreen element, exit fullscreen again to recover.
@@ -152,6 +159,7 @@ void FullscreenController::EnterFullscreen(LocalFrame& frame,
// restore a previous set. This can happen if we exit and quickly reenter
// fullscreen without performing a layout.
if (state_ == State::kInitial) {
+ // TODO(dtapuska): Remove these fields https://crbug.com/878773
initial_page_scale_factor_ = web_view_base_->PageScaleFactor();
initial_scroll_offset_ =
web_view_base_->MainFrame()->IsWebLocalFrame()
@@ -164,6 +172,8 @@ void FullscreenController::EnterFullscreen(LocalFrame& frame,
web_view_base_->BackgroundColorOverride();
}
+ pending_frames_.insert(&frame);
+
// If already entering fullscreen, just wait.
if (state_ == State::kEnteringFullscreen)
return;
@@ -173,7 +183,7 @@ void FullscreenController::EnterFullscreen(LocalFrame& frame,
blink::WebFullscreenOptions blink_options;
// Only clone options if the feature is enabled.
if (RuntimeEnabledFeatures::FullscreenOptionsEnabled())
- blink_options.prefers_navigation_bar = options.prefersNavigationBar();
+ blink_options.prefers_navigation_bar = options.navigationUI() != "hide";
GetWebFrameClient(frame).EnterFullscreen(blink_options);
state_ = State::kEnteringFullscreen;
@@ -250,7 +260,7 @@ void FullscreenController::UpdateSize() {
UpdatePageScaleConstraints(false);
}
-void FullscreenController::DidUpdateLayout() {
+void FullscreenController::DidUpdateMainFrameLayout() {
if (state_ != State::kNeedsScrollAndScaleRestore)
return;
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 b7627a13ef6..986b7eff53b 100644
--- a/chromium/third_party/blink/renderer/core/frame/fullscreen_controller.h
+++ b/chromium/third_party/blink/renderer/core/frame/fullscreen_controller.h
@@ -34,15 +34,16 @@
#include <memory>
#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/platform/geometry/float_point.h"
#include "third_party/blink/renderer/platform/geometry/int_size.h"
#include "third_party/blink/renderer/platform/graphics/color.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
namespace blink {
class Element;
class FullscreenOptions;
-class LocalFrame;
class WebViewImpl;
// FullscreenController is a per-WebView class that manages the transition into
@@ -71,7 +72,7 @@ class CORE_EXPORT FullscreenController {
void UpdateSize();
- void DidUpdateLayout();
+ void DidUpdateMainFrameLayout();
protected:
explicit FullscreenController(WebViewImpl*);
@@ -104,6 +105,10 @@ class CORE_EXPORT FullscreenController {
FloatPoint initial_visual_viewport_offset_;
bool initial_background_color_override_enabled_ = false;
RGBA32 initial_background_color_override_ = Color::kTransparent;
+
+ using PendingFullscreenSet =
+ PersistentHeapLinkedHashSet<WeakMember<LocalFrame>>;
+ PendingFullscreenSet pending_frames_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/link_highlights.cc b/chromium/third_party/blink/renderer/core/frame/link_highlights.cc
index 34f1ffce410..1f4cc6178fc 100644
--- a/chromium/third_party/blink/renderer/core/frame/link_highlights.cc
+++ b/chromium/third_party/blink/renderer/core/frame/link_highlights.cc
@@ -30,9 +30,13 @@ void LinkHighlights::Trace(blink::Visitor* visitor) {
}
void LinkHighlights::RemoveAllHighlights() {
- if (timeline_) {
- for (auto& highlight : link_highlights_)
+ for (auto& highlight : link_highlights_) {
+ if (timeline_)
timeline_->AnimationDestroyed(*highlight);
+ if (auto* node = highlight->GetNode()) {
+ if (auto* layout_object = node->GetLayoutObject())
+ layout_object->SetNeedsPaintPropertyUpdate();
+ }
}
link_highlights_.clear();
}
@@ -54,7 +58,7 @@ void LinkHighlights::SetTapHighlights(
continue;
Color highlight_color =
- node->GetLayoutObject()->Style()->TapHighlightColor();
+ node->GetLayoutObject()->StyleRef().TapHighlightColor();
// Safari documentation for -webkit-tap-highlight-color says if the
// specified color has 0 alpha, then tap highlighting is disabled.
// http://developer.apple.com/library/safari/#documentation/appleapplications/reference/safaricssref/articles/standardcssproperties.html
@@ -64,6 +68,7 @@ void LinkHighlights::SetTapHighlights(
link_highlights_.push_back(LinkHighlightImpl::Create(node));
if (timeline_)
timeline_->AnimationAttached(*link_highlights_.back());
+ node->GetLayoutObject()->SetNeedsPaintPropertyUpdate();
}
}
@@ -105,4 +110,25 @@ void LinkHighlights::WillCloseLayerTreeView(WebLayerTreeView& layer_tree_view) {
animation_host_ = nullptr;
}
+bool LinkHighlights::NeedsHighlightEffectInternal(
+ const LayoutObject& object) const {
+ for (auto& highlight : link_highlights_) {
+ if (auto* node = highlight->GetNode()) {
+ if (node->GetLayoutObject() == &object)
+ return true;
+ }
+ }
+ return false;
+}
+
+CompositorElementId LinkHighlights::element_id(const LayoutObject& object) {
+ for (auto& highlight : link_highlights_) {
+ if (auto* node = highlight->GetNode()) {
+ if (node->GetLayoutObject() == &object)
+ return highlight->element_id();
+ }
+ }
+ return CompositorElementId();
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/link_highlights.h b/chromium/third_party/blink/renderer/core/frame/link_highlights.h
index 2eb1e31bc48..940eb547673 100644
--- a/chromium/third_party/blink/renderer/core/frame/link_highlights.h
+++ b/chromium/third_party/blink/renderer/core/frame/link_highlights.h
@@ -8,6 +8,7 @@
#include <memory>
#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/graphics/compositor_element_id.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
namespace blink {
@@ -18,6 +19,7 @@ class CompositorAnimationHost;
class CompositorAnimationTimeline;
class WebLayerTreeView;
class LocalFrame;
+class LayoutObject;
class CORE_EXPORT LinkHighlights final
: public GarbageCollectedFinalized<LinkHighlights> {
@@ -31,6 +33,7 @@ class CORE_EXPORT LinkHighlights final
void SetTapHighlights(HeapVector<Member<Node>>&);
+ // Updates geometry on all highlights. See: LinkHighlightImpl::UpdateGeometry.
void UpdateGeometry();
void StartHighlightAnimationIfNeeded();
@@ -38,11 +41,22 @@ class CORE_EXPORT LinkHighlights final
void LayerTreeViewInitialized(WebLayerTreeView&);
void WillCloseLayerTreeView(WebLayerTreeView&);
+ bool IsEmpty() const { return link_highlights_.IsEmpty(); }
+
+ bool NeedsHighlightEffect(const LayoutObject& object) const {
+ if (link_highlights_.IsEmpty())
+ return false;
+ return NeedsHighlightEffectInternal(object);
+ }
+
+ CompositorElementId element_id(const LayoutObject& object);
+
private:
FRIEND_TEST_ALL_PREFIXES(LinkHighlightImplTest, verifyWebViewImplIntegration);
FRIEND_TEST_ALL_PREFIXES(LinkHighlightImplTest, resetDuringNodeRemoval);
FRIEND_TEST_ALL_PREFIXES(LinkHighlightImplTest, resetLayerTreeView);
FRIEND_TEST_ALL_PREFIXES(LinkHighlightImplTest, multipleHighlights);
+ FRIEND_TEST_ALL_PREFIXES(LinkHighlightImplTest, HighlightLayerEffectNode);
explicit LinkHighlights(Page&);
@@ -55,6 +69,8 @@ class CORE_EXPORT LinkHighlights final
return *page_;
}
+ bool NeedsHighlightEffectInternal(const LayoutObject& object) const;
+
Member<Page> page_;
Vector<std::unique_ptr<LinkHighlightImpl>> link_highlights_;
std::unique_ptr<CompositorAnimationHost> animation_host_;
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 4b1dd4d6f67..0811826c4d2 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
@@ -39,6 +39,7 @@
#include "third_party/blink/renderer/bindings/core/v8/source_location.h"
#include "third_party/blink/renderer/bindings/core/v8/usv_string_or_trusted_url.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/aom/computed_accessible_node.h"
#include "third_party/blink/renderer/core/css/css_computed_style_declaration.h"
#include "third_party/blink/renderer/core/css/css_rule_list.h"
@@ -96,13 +97,14 @@
#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/script/modulator.h"
+#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/core/trustedtypes/trusted_type_policy_factory.h"
#include "third_party/blink/renderer/core/trustedtypes/trusted_url.h"
#include "third_party/blink/renderer/platform/bindings/exception_messages.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
#include "third_party/blink/renderer/platform/scroll/scroll_types.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
namespace blink {
@@ -278,7 +280,13 @@ void LocalDOMWindow::AcceptLanguagesChanged() {
if (navigator_)
navigator_->SetLanguagesChanged();
- DispatchEvent(Event::Create(EventTypeNames::languagechange));
+ DispatchEvent(*Event::Create(EventTypeNames::languagechange));
+}
+
+TrustedTypePolicyFactory* LocalDOMWindow::trustedTypes() const {
+ if (!trusted_types_)
+ trusted_types_ = TrustedTypePolicyFactory::Create(GetFrame());
+ return trusted_types_.Get();
}
Document* LocalDOMWindow::CreateDocument(const String& mime_type,
@@ -331,11 +339,11 @@ Document* LocalDOMWindow::InstallNewDocument(const String& mime_type,
return document_;
}
-void LocalDOMWindow::EnqueueWindowEvent(Event* event, TaskType task_type) {
+void LocalDOMWindow::EnqueueWindowEvent(Event& event, TaskType task_type) {
EnqueueEvent(event, task_type);
}
-void LocalDOMWindow::EnqueueDocumentEvent(Event* event, TaskType task_type) {
+void LocalDOMWindow::EnqueueDocumentEvent(Event& event, TaskType task_type) {
if (document_)
document_->EnqueueEvent(event, task_type);
}
@@ -372,19 +380,19 @@ void LocalDOMWindow::EnqueuePageshowEvent(PageshowEventPersistence persisted) {
// The task source should be kDOMManipulation, but the spec doesn't say
// anything about this.
EnqueueWindowEvent(
- PageTransitionEvent::Create(EventTypeNames::pageshow, persisted),
+ *PageTransitionEvent::Create(EventTypeNames::pageshow, persisted),
TaskType::kMiscPlatformAPI);
return;
}
DispatchEvent(
- PageTransitionEvent::Create(EventTypeNames::pageshow, persisted),
+ *PageTransitionEvent::Create(EventTypeNames::pageshow, persisted),
document_.Get());
}
void LocalDOMWindow::EnqueueHashchangeEvent(const String& old_url,
const String& new_url) {
// https://html.spec.whatwg.org/#history-traversal
- EnqueueWindowEvent(HashChangeEvent::Create(old_url, new_url),
+ EnqueueWindowEvent(*HashChangeEvent::Create(old_url, new_url),
TaskType::kDOMManipulation);
}
@@ -392,7 +400,7 @@ void LocalDOMWindow::EnqueuePopstateEvent(
scoped_refptr<SerializedScriptValue> state_object) {
// FIXME: https://bugs.webkit.org/show_bug.cgi?id=36202 Popstate event needs
// to fire asynchronously
- DispatchEvent(PopStateEvent::Create(std::move(state_object), history()));
+ DispatchEvent(*PopStateEvent::Create(std::move(state_object), history()));
}
void LocalDOMWindow::StatePopped(
@@ -469,6 +477,7 @@ void LocalDOMWindow::Reset() {
media_ = nullptr;
custom_elements_ = nullptr;
application_cache_ = nullptr;
+ trusted_types_ = nullptr;
}
void LocalDOMWindow::SendOrientationChangeEvent() {
@@ -490,7 +499,7 @@ void LocalDOMWindow::SendOrientationChangeEvent() {
for (LocalFrame* frame : frames) {
frame->DomWindow()->DispatchEvent(
- Event::Create(EventTypeNames::orientationchange));
+ *Event::Create(EventTypeNames::orientationchange));
}
}
@@ -659,7 +668,7 @@ void LocalDOMWindow::DispatchMessageEventWithOriginCheck(
GetFrame(), WebFeature::kPostMessageIncomingWouldBeBlockedByConnectSrc);
}
- DispatchEvent(event);
+ DispatchEvent(*event);
}
DOMSelection* LocalDOMWindow::getSelection() {
@@ -883,7 +892,7 @@ bool LocalDOMWindow::find(const String& string,
// FIXME (13016): Support searchInFrames and showDialog
FindOptions options =
(backwards ? kBackwards : 0) | (case_sensitive ? 0 : kCaseInsensitive) |
- (wrap ? kWrapAround : 0) | (whole_word ? kWholeWord | kAtWordStarts : 0);
+ (wrap ? kWrapAround : 0) | (whole_word ? kWholeWord : 0);
return Editor::FindString(*GetFrame(), string, options);
}
@@ -1081,8 +1090,6 @@ ScriptPromise LocalDOMWindow::getComputedAccessibleNode(
ScriptState* script_state,
Element* element) {
DCHECK(element);
- // TODO(meredithl): Create finer grain method for enabling accessibility.
- element->GetDocument().GetPage()->GetSettings().SetAccessibilityEnabled(true);
ComputedAccessibleNodePromiseResolver* resolver =
ComputedAccessibleNodePromiseResolver::Create(script_state, *element);
ScriptPromise promise = resolver->Promise();
@@ -1439,7 +1446,7 @@ void LocalDOMWindow::WarnUnusedPreloads(TimerBase* base) {
}
void LocalDOMWindow::DispatchLoadEvent() {
- Event* load_event(Event::Create(EventTypeNames::load));
+ Event& load_event = *Event::Create(EventTypeNames::load);
DocumentLoader* document_loader =
GetFrame() ? GetFrame()->Loader().GetDocumentLoader() : nullptr;
if (document_loader &&
@@ -1479,19 +1486,19 @@ void LocalDOMWindow::DispatchLoadEvent() {
probe::loadEventFired(GetFrame());
}
-DispatchEventResult LocalDOMWindow::DispatchEvent(Event* event,
+DispatchEventResult LocalDOMWindow::DispatchEvent(Event& event,
EventTarget* target) {
#if DCHECK_IS_ON()
DCHECK(!EventDispatchForbiddenScope::IsEventDispatchForbidden());
#endif
- event->SetTrusted(true);
- event->SetTarget(target ? target : this);
- event->SetCurrentTarget(this);
- event->SetEventPhase(Event::kAtTarget);
+ event.SetTrusted(true);
+ event.SetTarget(target ? target : this);
+ event.SetCurrentTarget(this);
+ event.SetEventPhase(Event::kAtTarget);
TRACE_EVENT1("devtools.timeline", "EventDispatch", "data",
- InspectorEventDispatchEvent::Data(*event));
+ InspectorEventDispatchEvent::Data(event));
return FireEventListeners(event);
}
@@ -1550,21 +1557,12 @@ DOMWindow* LocalDOMWindow::open(ExecutionContext* executionContext,
const AtomicString& target,
const String& features,
ExceptionState& exception_state) {
- DCHECK(stringOrUrl.IsUSVString() ||
- RuntimeEnabledFeatures::TrustedDOMTypesEnabled());
-
- if (!stringOrUrl.IsTrustedURL() && document_->RequireTrustedTypes()) {
- exception_state.ThrowTypeError(
- "This document requires `TrustedURL` assignment.");
- return nullptr;
+ String url = TrustedURL::GetString(stringOrUrl, document_, exception_state);
+ if (!exception_state.HadException()) {
+ return openFromString(executionContext, current_window, entered_window, url,
+ target, features, exception_state);
}
-
- String url = stringOrUrl.IsUSVString()
- ? stringOrUrl.GetAsUSVString()
- : stringOrUrl.GetAsTrustedURL()->toString();
-
- return openFromString(executionContext, current_window, entered_window, url,
- target, features, exception_state);
+ return nullptr;
}
DOMWindow* LocalDOMWindow::openFromString(ExecutionContext* executionContext,
@@ -1609,21 +1607,12 @@ DOMWindow* LocalDOMWindow::open(const USVStringOrTrustedURL& stringOrUrl,
LocalDOMWindow* calling_window,
LocalDOMWindow* entered_window,
ExceptionState& exception_state) {
- DCHECK(stringOrUrl.IsUSVString() ||
- RuntimeEnabledFeatures::TrustedDOMTypesEnabled());
-
- if (!stringOrUrl.IsTrustedURL() && document_->RequireTrustedTypes()) {
- exception_state.ThrowTypeError(
- "This document requires `TrustedURL` assignment.");
- return nullptr;
+ String url = TrustedURL::GetString(stringOrUrl, document_, exception_state);
+ if (!exception_state.HadException()) {
+ return openFromString(url, frame_name, window_features_string,
+ calling_window, entered_window, exception_state);
}
-
- String url = stringOrUrl.IsUSVString()
- ? stringOrUrl.GetAsUSVString()
- : stringOrUrl.GetAsTrustedURL()->toString();
-
- return openFromString(url, frame_name, window_features_string, calling_window,
- entered_window, exception_state);
+ return nullptr;
}
DOMWindow* LocalDOMWindow::openFromString(const String& url_string,
@@ -1704,6 +1693,7 @@ void LocalDOMWindow::Trace(blink::Visitor* visitor) {
visitor->Trace(post_message_timers_);
visitor->Trace(visualViewport_);
visitor->Trace(event_listener_observers_);
+ visitor->Trace(trusted_types_);
DOMWindow::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 f64aaa45cde..66664c4626c 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
@@ -31,9 +31,9 @@
#include "third_party/blink/renderer/core/dom/events/event_target.h"
#include "third_party/blink/renderer/core/frame/dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
+#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
#include "third_party/blink/renderer/platform/bindings/trace_wrapper_member.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/scroll/scrollable_area.h"
#include "third_party/blink/renderer/platform/supplementable.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
@@ -69,6 +69,7 @@ class SecurityOrigin;
class SerializedScriptValue;
class SourceLocation;
class StyleMedia;
+class TrustedTypePolicyFactory;
class USVStringOrTrustedURL;
class V8FrameRequestCallback;
class V8IdleRequestCallback;
@@ -311,7 +312,7 @@ class CORE_EXPORT LocalDOMWindow final : public DOMWindow,
void RemoveAllEventListeners() override;
using EventTarget::DispatchEvent;
- DispatchEventResult DispatchEvent(Event*, EventTarget*);
+ DispatchEventResult DispatchEvent(Event&, EventTarget*);
void FinishedLoading();
@@ -319,8 +320,8 @@ class CORE_EXPORT LocalDOMWindow final : public DOMWindow,
// recurse on its child frames.
void SendOrientationChangeEvent();
- void EnqueueWindowEvent(Event*, TaskType);
- void EnqueueDocumentEvent(Event*, TaskType);
+ void EnqueueWindowEvent(Event&, TaskType);
+ void EnqueueDocumentEvent(Event&, TaskType);
void EnqueuePageshowEvent(PageshowEventPersistence);
void EnqueueHashchangeEvent(const String& old_url, const String& new_url);
void EnqueuePopstateEvent(scoped_refptr<SerializedScriptValue>);
@@ -330,6 +331,8 @@ class CORE_EXPORT LocalDOMWindow final : public DOMWindow,
void AcceptLanguagesChanged();
+ TrustedTypePolicyFactory* trustedTypes() const;
+
protected:
// EventTarget overrides.
void AddedEventListener(const AtomicString& event_type,
@@ -407,6 +410,8 @@ class CORE_EXPORT LocalDOMWindow final : public DOMWindow,
HeapHashSet<Member<PostMessageTimer>> post_message_timers_;
HeapHashSet<WeakMember<EventListenerObserver>> event_listener_observers_;
+
+ mutable Member<TrustedTypePolicyFactory> trusted_types_;
};
DEFINE_TYPE_CASTS(LocalDOMWindow,
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 52810bba03b..a7ddc156c2b 100644
--- a/chromium/third_party/blink/renderer/core/frame/local_frame.cc
+++ b/chromium/third_party/blink/renderer/core/frame/local_frame.cc
@@ -33,12 +33,14 @@
#include <memory>
#include "services/network/public/cpp/features.h"
+#include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/blink/public/platform/interface_provider.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/web_url_request.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/CoreProbeSink.h"
#include "third_party/blink/renderer/core/aom/computed_accessible_node.h"
#include "third_party/blink/renderer/core/core_initializer.h"
@@ -48,6 +50,7 @@
#include "third_party/blink/renderer/core/dom/document_parser.h"
#include "third_party/blink/renderer/core/dom/document_type.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
+#include "third_party/blink/renderer/core/dom/ignore_opens_during_unload_count_incrementer.h"
#include "third_party/blink/renderer/core/editing/editing_utilities.h"
#include "third_party/blink/renderer/core/editing/editor.h"
#include "third_party/blink/renderer/core/editing/frame_selection.h"
@@ -59,11 +62,14 @@
#include "third_party/blink/renderer/core/frame/ad_tracker.h"
#include "third_party/blink/renderer/core/frame/content_settings_client.h"
#include "third_party/blink/renderer/core/frame/event_handler_registry.h"
+#include "third_party/blink/renderer/core/frame/feature_policy_violation_report_body.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_client.h"
#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/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/html/html_frame_element_base.h"
#include "third_party/blink/renderer/core/html/html_plugin_element.h"
@@ -88,6 +94,7 @@
#include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h"
#include "third_party/blink/renderer/core/paint/object_painter.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
+#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/graphics/graphics_layer.h"
@@ -97,9 +104,9 @@
#include "third_party/blink/renderer/platform/instrumentation/resource_coordinator/blink_resource_coordinator_base.h"
#include "third_party/blink/renderer/platform/instrumentation/resource_coordinator/frame_resource_coordinator.h"
#include "third_party/blink/renderer/platform/json/json_values.h"
-#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_request.h"
+#include "third_party/blink/renderer/platform/network/network_utils.h"
#include "third_party/blink/renderer/platform/plugins/plugin_data.h"
#include "third_party/blink/renderer/platform/plugins/plugin_script_forbidden_scope.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
@@ -144,54 +151,6 @@ bool ShouldUseClientLoFiForRequest(
return true;
}
-class EmptyFrameScheduler final : public FrameScheduler {
- public:
- EmptyFrameScheduler() { DCHECK(IsMainThread()); }
-
- scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner(
- TaskType type) override {
- return Platform::Current()->MainThread()->GetTaskRunner();
- }
-
- std::unique_ptr<scheduler::WebResourceLoadingTaskRunnerHandle>
- CreateResourceLoadingTaskRunnerHandle() override {
- return scheduler::WebResourceLoadingTaskRunnerHandle::CreateUnprioritized(
- GetTaskRunner(TaskType::kNetworkingWithURLLoaderAnnotation));
- }
-
- void SetFrameVisible(bool) override {}
- bool IsFrameVisible() const override { return false; }
- bool IsPageVisible() const override { return false; }
- void SetPaused(bool) override {}
- void SetCrossOrigin(bool) override {}
- bool IsCrossOrigin() const override { return false; }
- void SetIsAdFrame() override {}
- bool IsAdFrame() const override { return false; }
- void TraceUrlChange(const String& override) override {}
- FrameScheduler::FrameType GetFrameType() const override {
- return FrameScheduler::FrameType::kSubframe;
- }
- PageScheduler* GetPageScheduler() const override { return nullptr; }
- WebScopedVirtualTimePauser CreateWebScopedVirtualTimePauser(
- const String&,
- WebScopedVirtualTimePauser::VirtualTaskDuration) override {
- return WebScopedVirtualTimePauser();
- }
- void DidStartProvisionalLoad(bool is_main_frame) override {}
- void DidCommitProvisionalLoad(bool is_web_history_inert_commit,
- bool is_reload,
- bool is_main_frame) override {}
- void OnFirstMeaningfulPaint() override {}
- std::unique_ptr<ActiveConnectionHandle> OnActiveConnectionCreated() override {
- return nullptr;
- }
- bool IsExemptFromBudgetBasedThrottling() const override { return false; }
- std::unique_ptr<blink::mojom::blink::PauseSubresourceLoadingHandle>
- GetPauseSubresourceLoadingHandle() override {
- return nullptr;
- }
-};
-
} // namespace
template class CORE_TEMPLATE_EXPORT Supplement<LocalFrame>;
@@ -300,6 +259,7 @@ void LocalFrame::Trace(blink::Visitor* visitor) {
visitor->Trace(input_method_controller_);
visitor->Trace(text_suggestion_controller_);
visitor->Trace(computed_node_mapping_);
+ visitor->Trace(smooth_scroll_sequencer_);
Frame::Trace(visitor);
Supplementable<LocalFrame>::Trace(visitor);
}
@@ -323,23 +283,6 @@ void LocalFrame::Navigate(const FrameLoadRequest& request) {
loader_.StartNavigation(request);
}
-void LocalFrame::Reload(WebFrameLoadType load_type,
- ClientRedirectPolicy client_redirect_policy) {
- DCHECK(IsReloadLoadType(load_type));
- if (client_redirect_policy == ClientRedirectPolicy::kNotClientRedirect) {
- if (!loader_.GetDocumentLoader()->GetHistoryItem())
- return;
- FrameLoadRequest request = FrameLoadRequest(
- nullptr,
- loader_.ResourceRequestForReload(load_type, client_redirect_policy));
- request.SetClientRedirect(client_redirect_policy);
- loader_.StartNavigation(request, load_type);
- } else {
- DCHECK_EQ(WebFrameLoadType::kReload, load_type);
- navigation_scheduler_->ScheduleReload();
- }
-}
-
void LocalFrame::Detach(FrameDetachType type) {
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// BEGIN RE-ENTRANCY SAFE BLOCK
@@ -367,6 +310,11 @@ void LocalFrame::Detach(FrameDetachType type) {
// child frame during or after detaching children results in an attached
// frame on a detached DOM tree, which is bad.
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
+ // both when unloading itself and when unloading its descendants.
+ IgnoreOpensDuringUnloadCountIncrementer ignore_opens_during_unload(
+ GetDocument());
loader_.DispatchUnloadEvent();
DetachChildren();
@@ -506,6 +454,23 @@ Frame* LocalFrame::FindFrameForNavigation(const AtomicString& name,
return frame;
}
+void LocalFrame::Reload(WebFrameLoadType load_type,
+ ClientRedirectPolicy client_redirect_policy) {
+ DCHECK(IsReloadLoadType(load_type));
+ if (client_redirect_policy == ClientRedirectPolicy::kNotClientRedirect) {
+ if (!loader_.GetDocumentLoader()->GetHistoryItem())
+ return;
+ FrameLoadRequest request = FrameLoadRequest(
+ nullptr,
+ loader_.ResourceRequestForReload(load_type, client_redirect_policy));
+ request.SetClientRedirect(client_redirect_policy);
+ loader_.StartNavigation(request, load_type);
+ } else {
+ DCHECK_EQ(WebFrameLoadType::kReload, load_type);
+ navigation_scheduler_->ScheduleReload();
+ }
+}
+
LocalWindowProxy* LocalFrame::WindowProxy(DOMWrapperWorld& world) {
return ToLocalWindowProxy(Frame::GetWindowProxy(world));
}
@@ -559,7 +524,7 @@ void LocalFrame::DidResume() {
DCHECK(RuntimeEnabledFeatures::PageLifecycleEnabled());
if (GetDocument()) {
const TimeTicks resume_event_start = CurrentTimeTicks();
- GetDocument()->DispatchEvent(Event::Create(EventTypeNames::resume));
+ GetDocument()->DispatchEvent(*Event::Create(EventTypeNames::resume));
const TimeTicks resume_event_end = CurrentTimeTicks();
DEFINE_STATIC_LOCAL(
CustomCountHistogram, resume_histogram,
@@ -638,22 +603,14 @@ scoped_refptr<InspectorTaskRunner> LocalFrame::GetInspectorTaskRunner() {
void LocalFrame::StartPrinting(const FloatSize& page_size,
const FloatSize& original_page_size,
float maximum_shrink_ratio) {
- SetPrinting(/*printing=*/true, /*use_printing_layout=*/true, page_size,
- original_page_size, maximum_shrink_ratio);
-}
-
-void LocalFrame::StartPrintingWithoutPrintingLayout() {
- SetPrinting(/*printing=*/true, /*use_printing_layout=*/false, FloatSize(),
- FloatSize(), 0);
+ SetPrinting(true, page_size, original_page_size, maximum_shrink_ratio);
}
void LocalFrame::EndPrinting() {
- SetPrinting(/*printing=*/false, /*use_printing_layout=*/false, FloatSize(),
- FloatSize(), 0);
+ SetPrinting(false, FloatSize(), FloatSize(), 0);
}
void LocalFrame::SetPrinting(bool printing,
- bool use_printing_layout,
const FloatSize& page_size,
const FloatSize& original_page_size,
float maximum_shrink_ratio) {
@@ -669,7 +626,7 @@ void LocalFrame::SetPrinting(bool printing,
if (TextAutosizer* text_autosizer = GetDocument()->GetTextAutosizer())
text_autosizer->UpdatePageInfo();
- if (use_printing_layout && ShouldUsePrintingLayout()) {
+ if (ShouldUsePrintingLayout()) {
View()->ForceLayoutForPagination(page_size, original_page_size,
maximum_shrink_ratio);
} else {
@@ -687,7 +644,7 @@ void LocalFrame::SetPrinting(bool printing,
child = child->Tree().NextSibling()) {
if (child->IsLocalFrame()) {
if (printing)
- ToLocalFrame(child)->StartPrintingWithoutPrintingLayout();
+ ToLocalFrame(child)->StartPrinting();
else
ToLocalFrame(child)->EndPrinting();
}
@@ -700,19 +657,22 @@ void LocalFrame::SetPrinting(bool printing,
}
bool LocalFrame::ShouldUsePrintingLayout() const {
+ if (!GetDocument()->Printing())
+ return false;
+
// Only the top frame being printed should be fitted to page size.
// Subframes should be constrained by parents only.
- // This function considers the following three kinds of frames as top frames:
+ // This function considers the following two kinds of frames as top frames:
// -- frame with no parent;
- // -- frame's parent is remote frame;
// -- frame's parent is not in printing mode.
- // Among them, if a frame's parent is a remote frame, but in printing mode,
- // this frame should not use printing layout either. But in that case, this
- // frame is a local top frame, the printing must start from
- // StartPrintingWithoutPrintingLayout() so this function won't been called.
- return GetDocument()->Printing() &&
- (!Tree().Parent() || !Tree().Parent()->IsLocalFrame() ||
- !ToLocalFrame(Tree().Parent())->GetDocument()->Printing());
+ // For the second type, it is a bit complicated when its parent is a remote
+ // frame. In such case, we can not check its document or other internal
+ // status. However, if the parent is in printing mode, this frame's printing
+ // must have started with |use_printing_layout| as false in print context.
+ return !Tree().Parent() ||
+ (Tree().Parent()->IsLocalFrame() &&
+ !ToLocalFrame(Tree().Parent())->GetDocument()->Printing()) ||
+ (!Tree().Parent()->IsLocalFrame() && Client()->UsePrintingLayout());
}
FloatSize LocalFrame::ResizePageRectsKeepingRatio(
@@ -890,18 +850,6 @@ String LocalFrame::GetLayerTreeAsTextForTesting(unsigned flags) const {
static_cast<LayerTreeFlags>(flags));
}
}
-
- if (flags & kLayerTreeIncludesPaintInvalidations) {
- std::unique_ptr<JSONArray> object_paint_invalidations =
- view_->TrackedObjectPaintInvalidationsAsJSON();
- if (object_paint_invalidations && object_paint_invalidations->size()) {
- if (!layers)
- layers = JSONObject::Create();
- layers->SetArray("objectPaintInvalidations",
- std::move(object_paint_invalidations));
- }
- }
-
return layers ? layers->ToPrettyJSONString() : String();
}
@@ -914,13 +862,11 @@ inline LocalFrame::LocalFrame(LocalFrameClient* client,
FrameOwner* owner,
InterfaceRegistry* interface_registry)
: Frame(client, page, owner, LocalWindowProxyManager::Create(*this)),
- frame_scheduler_(page.GetPageScheduler()
- ? page.GetPageScheduler()->CreateFrameScheduler(
- client->GetFrameBlameContext(),
- IsMainFrame()
- ? FrameScheduler::FrameType::kMainFrame
- : FrameScheduler::FrameType::kSubframe)
- : std::make_unique<EmptyFrameScheduler>()),
+ frame_scheduler_(page.GetPageScheduler()->CreateFrameScheduler(
+ this,
+ client->GetFrameBlameContext(),
+ IsMainFrame() ? FrameScheduler::FrameType::kMainFrame
+ : FrameScheduler::FrameType::kSubframe)),
loader_(this),
navigation_scheduler_(NavigationScheduler::Create(this)),
script_controller_(ScriptController::Create(
@@ -1035,6 +981,17 @@ bool LocalFrame::CanNavigate(const Frame& target_frame,
SecurityOrigin::Create(destination_url).get())) {
return true;
}
+
+ String target_domain = NetworkUtils::GetDomainAndRegistry(
+ target_frame.GetSecurityContext()->GetSecurityOrigin()->Domain(),
+ NetworkUtils::kIncludePrivateRegistries);
+ String destination_domain = NetworkUtils::GetDomainAndRegistry(
+ destination_url.Host(), NetworkUtils::kIncludePrivateRegistries);
+ if (!target_domain.IsEmpty() && !destination_domain.IsEmpty() &&
+ target_domain == destination_domain) {
+ return true;
+ }
+
// Frame-busting used to be generally allowed in most situations, but may
// now blocked if the document initiating the navigation has never received
// a user gesture and the navigation isn't same-origin with the target.
@@ -1315,20 +1272,17 @@ void ScopedFrameBlamer::LeaveContext() {
context->Leave();
}
-void LocalFrame::MaybeAllowImagePlaceholder(FetchParameters& params) const {
- if (GetSettings() && GetSettings()->GetFetchImagePlaceholders()) {
- params.SetAllowImagePlaceholder();
- return;
- }
+bool LocalFrame::IsClientLoFiAllowed(const ResourceRequest& request) const {
+ return Client() && ShouldUseClientLoFiForRequest(
+ request, Client()->GetPreviewsStateForFrame());
+}
- if (Client() &&
- ShouldUseClientLoFiForRequest(params.GetResourceRequest(),
- Client()->GetPreviewsStateForFrame())) {
- params.MutableResourceRequest().SetPreviewsState(
- params.GetResourceRequest().GetPreviewsState() |
- WebURLRequest::kClientLoFiOn);
- params.SetAllowImagePlaceholder();
- }
+bool LocalFrame::IsLazyLoadingImageAllowed() const {
+ if (!RuntimeEnabledFeatures::LazyImageLoadingEnabled())
+ return false;
+ if (Owner() && !Owner()->ShouldLazyLoadChildren())
+ return false;
+ return true;
}
WebURLLoaderFactory* LocalFrame::GetURLLoaderFactory() {
@@ -1353,9 +1307,12 @@ WebPluginContainerImpl* LocalFrame::GetWebPluginContainer(Node* node) const {
}
void LocalFrame::SetViewportIntersectionFromParent(
- const IntRect& viewport_intersection) {
- if (remote_viewport_intersection_ != viewport_intersection) {
+ const IntRect& viewport_intersection,
+ bool occluded_or_obscured) {
+ if (remote_viewport_intersection_ != viewport_intersection ||
+ occluded_or_obscured_by_ancestor_ != occluded_or_obscured) {
remote_viewport_intersection_ = viewport_intersection;
+ occluded_or_obscured_by_ancestor_ = occluded_or_obscured;
if (View()) {
View()->SetNeedsIntersectionObservation(LocalFrameView::kRequired);
View()->ScheduleAnimation();
@@ -1374,7 +1331,9 @@ void LocalFrame::ForceSynchronousDocumentInstall(
GetDocument()->Shutdown();
DomWindow()->InstallNewDocument(
- mime_type, DocumentInit::Create().WithFrame(this), false);
+ mime_type,
+ DocumentInit::Create().WithDocumentLoader(loader_.GetDocumentLoader()),
+ false);
loader_.StateMachine()->AdvanceTo(
FrameLoaderStateMachine::kCommittedFirstRealLoad);
@@ -1448,7 +1407,61 @@ void LocalFrame::BindPreviewsResourceLoadingHintsRequest(
DCHECK(!previews_resource_loading_hints_receiver_);
previews_resource_loading_hints_receiver_ =
std::make_unique<PreviewsResourceLoadingHintsReceiverImpl>(
- std::move(request));
+ std::move(request), GetDocument());
+}
+
+SmoothScrollSequencer& LocalFrame::GetSmoothScrollSequencer() {
+ if (!IsLocalRoot())
+ return LocalFrameRoot().GetSmoothScrollSequencer();
+ if (!smooth_scroll_sequencer_)
+ smooth_scroll_sequencer_ = new SmoothScrollSequencer();
+ return *smooth_scroll_sequencer_;
+}
+
+ukm::UkmRecorder* LocalFrame::GetUkmRecorder() {
+ Document* document = GetDocument();
+ if (!document)
+ return nullptr;
+ return document->UkmRecorder();
+}
+
+int64_t LocalFrame::GetUkmSourceId() {
+ Document* document = GetDocument();
+ if (!document)
+ return ukm::kInvalidSourceId;
+ return document->UkmSourceID();
+}
+
+const mojom::blink::ReportingServiceProxyPtr& LocalFrame::GetReportingService()
+ const {
+ if (!reporting_service_) {
+ Platform::Current()->GetConnector()->BindInterface(
+ Platform::Current()->GetBrowserServiceName(), &reporting_service_);
+ }
+ return reporting_service_;
+}
+
+void LocalFrame::ReportFeaturePolicyViolation(
+ mojom::FeaturePolicyFeature feature) const {
+ if (!RuntimeEnabledFeatures::FeaturePolicyReportingEnabled())
+ return;
+ const String& feature_name = GetNameForFeature(feature);
+ FeaturePolicyViolationReportBody* body = new FeaturePolicyViolationReportBody(
+ feature_name, "Feature policy violation", SourceLocation::Capture());
+ Report* report =
+ new Report("feature-policy", GetDocument()->Url().GetString(), body);
+ ReportingContext::From(GetDocument())->QueueReport(report);
+
+ bool is_null;
+ int line_number = body->lineNumber(is_null);
+ line_number = is_null ? 0 : line_number;
+ int column_number = body->columnNumber(is_null);
+ column_number = is_null ? 0 : column_number;
+
+ // Send the feature policy violation report to the Reporting API.
+ GetReportingService()->QueueFeaturePolicyViolationReport(
+ GetDocument()->Url(), feature_name, "Feature policy violation",
+ body->sourceFile(), line_number, column_number);
}
} // 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 79dec449f7e..f14e8bf372a 100644
--- a/chromium/third_party/blink/renderer/core/frame/local_frame.h
+++ b/chromium/third_party/blink/renderer/core/frame/local_frame.h
@@ -35,6 +35,7 @@
#include "mojo/public/cpp/bindings/strong_binding_set.h"
#include "third_party/blink/public/mojom/loader/pause_subresource_loading_handle.mojom-blink.h"
#include "third_party/blink/public/mojom/loader/previews_resource_loading_hints.mojom-blink.h"
+#include "third_party/blink/public/platform/reporting.mojom-blink.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/core/accessibility/axid.h"
#include "third_party/blink/renderer/core/core_export.h"
@@ -42,6 +43,7 @@
#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/loader/frame_loader.h"
#include "third_party/blink/renderer/platform/graphics/touch_action.h"
@@ -71,7 +73,6 @@ class Editor;
class Element;
class EventHandler;
class EventHandlerRegistry;
-class FetchParameters;
class FloatSize;
class FrameConsole;
class FrameResourceCoordinator;
@@ -93,8 +94,10 @@ class Node;
class NodeTraversal;
class PerformanceMonitor;
class PluginData;
+class ResourceRequest;
class ScriptController;
class SharedBuffer;
+class SmoothScrollSequencer;
class SpellChecker;
class TextSuggestionController;
class WebComputedAXTree;
@@ -104,6 +107,7 @@ class WebURLLoaderFactory;
extern template class CORE_EXTERN_TEMPLATE_EXPORT Supplement<LocalFrame>;
class CORE_EXPORT LocalFrame final : public Frame,
+ public FrameScheduler::Delegate,
public Supplementable<LocalFrame> {
USING_GARBAGE_COLLECTED_MIXIN(LocalFrame);
@@ -125,7 +129,6 @@ class CORE_EXPORT LocalFrame final : public Frame,
bool replace_current_item,
UserGestureStatus) override;
void Navigate(const FrameLoadRequest&) override;
- void Reload(WebFrameLoadType, ClientRedirectPolicy) override;
void Detach(FrameDetachType) override;
bool ShouldClose() override;
SecurityContext* GetSecurityContext() const override;
@@ -150,6 +153,7 @@ class CORE_EXPORT LocalFrame final : public Frame,
Frame* FindFrameForNavigation(const AtomicString& name,
LocalFrame& active_frame,
const KURL& destination_url);
+ void Reload(WebFrameLoadType, ClientRedirectPolicy);
// Note: these two functions are not virtual but intentionally shadow the
// corresponding method in the Frame base class to return the
@@ -203,13 +207,11 @@ class CORE_EXPORT LocalFrame final : public Frame,
// Begin printing with the given page size information.
// The frame content will fit to the page size with specified shrink ratio.
- void StartPrinting(const FloatSize& page_size,
- const FloatSize& original_page_size,
- float maximum_shrink_ratio);
-
- // Begin printing without changing the the frame's layout. This is used for
- // child frames because they don't need to fit to a page size.
- void StartPrintingWithoutPrintingLayout();
+ // If this frame doesn't need to fit into a page size, default values are
+ // used.
+ void StartPrinting(const FloatSize& page_size = FloatSize(),
+ const FloatSize& original_page_size = FloatSize(),
+ float maximum_shrink_ratio = 0);
void EndPrinting();
bool ShouldUsePrintingLayout() const;
@@ -286,10 +288,11 @@ class CORE_EXPORT LocalFrame final : public Frame,
AdTracker* GetAdTracker() { return ad_tracker_; }
void SetAdTrackerForTesting(AdTracker* ad_tracker);
- // Convenience function to allow loading image placeholders for the request if
- // either the flag in Settings() for using image placeholders is set, or if
- // the embedder decides that Client Lo-Fi should be used for this request.
- void MaybeAllowImagePlaceholder(FetchParameters&) const;
+ // Returns true if Client Lo-Fi should be used for this request.
+ bool IsClientLoFiAllowed(const ResourceRequest&) const;
+
+ // Returns true if lazyloading the image is possible.
+ bool IsLazyLoadingImageAllowed() const;
// The returned value is a off-heap raw-ptr and should not be stored.
WebURLLoaderFactory* GetURLLoaderFactory();
@@ -305,10 +308,13 @@ class CORE_EXPORT LocalFrame final : public Frame,
WebPluginContainerImpl* GetWebPluginContainer(Node* = nullptr) const;
// Called on a view for a LocalFrame with a RemoteFrame parent. This makes
- // viewport intersection available that accounts for remote ancestor frames
- // and their respective scroll positions, clips, etc.
- void SetViewportIntersectionFromParent(const IntRect&);
+ // viewport intersection and occlusion/obscuration available that accounts for
+ // remote ancestor frames and their respective scroll positions, clips, etc.
+ void SetViewportIntersectionFromParent(const IntRect&, bool);
IntRect RemoteViewportIntersection() { return remote_viewport_intersection_; }
+ bool MayBeOccludedOrObscuredByRemoteAncestor() const {
+ return occluded_or_obscured_by_ancestor_;
+ }
// Replaces the initial empty document with a Document suitable for
// |mime_type| and populated with the contents of |data|. Only intended for
@@ -319,8 +325,8 @@ class CORE_EXPORT LocalFrame final : public Frame,
bool should_send_resource_timing_info_to_parent() const {
return should_send_resource_timing_info_to_parent_;
}
- void DidSendResourceTimingInfoToParent() {
- should_send_resource_timing_info_to_parent_ = false;
+ void SetShouldSendResourceTimingInfoToParent(bool value) {
+ should_send_resource_timing_info_to_parent_ = value;
}
// TODO(https://crbug.com/578349): provisional frames are a hack that should
@@ -364,6 +370,10 @@ class CORE_EXPORT LocalFrame final : public Frame,
void BindPreviewsResourceLoadingHintsRequest(
blink::mojom::blink::PreviewsResourceLoadingHintsReceiverRequest request);
+ SmoothScrollSequencer& GetSmoothScrollSequencer();
+
+ void ReportFeaturePolicyViolation(mojom::FeaturePolicyFeature) const override;
+
private:
friend class FrameNavigationDisabler;
@@ -386,14 +396,18 @@ class CORE_EXPORT LocalFrame final : public Frame,
// Internal implementation for starting or ending printing.
// |printing| is true when printing starts, false when printing ends.
// |page_size|, |original_page_size|, and |maximum_shrink_ratio| are only
- // meaningful when starting to print with printing layout -- both |printing|
- // and |use_printing_layout| are true.
+ // meaningful when we should use printing layout for this frame.
void SetPrinting(bool printing,
- bool use_printing_layout,
const FloatSize& page_size,
const FloatSize& original_page_size,
float maximum_shrink_ratio);
+ // FrameScheduler::Delegate overrides:
+ ukm::UkmRecorder* GetUkmRecorder() override;
+ ukm::SourceId GetUkmSourceId() override;
+
+ const mojom::blink::ReportingServiceProxyPtr& GetReportingService() const;
+
std::unique_ptr<FrameScheduler> frame_scheduler_;
// Holds all PauseSubresourceLoadingHandles allowing either |this| to delete
@@ -443,10 +457,17 @@ class CORE_EXPORT LocalFrame final : public Frame,
Member<AdTracker> ad_tracker_;
Member<IdlenessDetector> idleness_detector_;
Member<InspectorTraceEvents> inspector_trace_events_;
+ // SmoothScrollSequencer is only populated for local roots; all local frames
+ // use the instance owned by their local root.
+ Member<SmoothScrollSequencer> smooth_scroll_sequencer_;
InterfaceRegistry* const interface_registry_;
+ // This is declared mutable so that the service endpoint can be cached by
+ // const methods.
+ mutable mojom::blink::ReportingServiceProxyPtr reporting_service_;
IntRect remote_viewport_intersection_;
+ bool occluded_or_obscured_by_ancestor_ = false;
std::unique_ptr<FrameResourceCoordinator> frame_resource_coordinator_;
// Used to keep track of which ComputedAccessibleNodes have already been
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 7360a10773e..983cd3c06cf 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
@@ -45,7 +45,7 @@
#include "third_party/blink/public/platform/web_worker_fetch_context.h"
#include "third_party/blink/public/web/web_global_object_reuse_policy.h"
#include "third_party/blink/public/web/web_history_commit_type.h"
-#include "third_party/blink/public/web/web_navigation_timings.h"
+#include "third_party/blink/public/web/web_navigation_params.h"
#include "third_party/blink/public/web/web_triggering_event_info.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/document.h"
@@ -158,7 +158,8 @@ class CORE_EXPORT LocalFrameClient : public FrameClient {
HTMLFormElement*,
ContentSecurityPolicyDisposition
should_check_main_world_content_security_policy,
- mojom::blink::BlobURLTokenPtr) = 0;
+ mojom::blink::BlobURLTokenPtr,
+ base::TimeTicks input_start_time) = 0;
virtual void DispatchWillSendSubmitEvent(HTMLFormElement*) = 0;
virtual void DispatchWillSubmitForm(HTMLFormElement*) = 0;
@@ -237,8 +238,8 @@ class CORE_EXPORT LocalFrameClient : public FrameClient {
const SubstituteData&,
ClientRedirectPolicy,
const base::UnguessableToken& devtools_navigation_token,
- std::unique_ptr<WebDocumentLoader::ExtraData> extra_data,
- const WebNavigationTimings& navigation_timings) = 0;
+ std::unique_ptr<WebNavigationParams> navigation_params,
+ std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) = 0;
virtual String UserAgent() = 0;
@@ -418,6 +419,15 @@ class CORE_EXPORT LocalFrameClient : public FrameClient {
virtual void FrameRectsChanged(const IntRect&) {}
+ // 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.
+ virtual bool IsPluginHandledExternally(HTMLPlugInElement&,
+ const KURL&,
+ const String&) {
+ return false;
+ };
+
// Returns a new WebWorkerFetchContext for a dedicated worker or worklet.
virtual std::unique_ptr<WebWorkerFetchContext> CreateWorkerFetchContext() {
return nullptr;
@@ -429,6 +439,10 @@ class CORE_EXPORT LocalFrameClient : public FrameClient {
}
virtual void SetMouseCapture(bool) {}
+
+ // Returns whether we are associated with a print context who suggests to use
+ // printing layout.
+ virtual bool UsePrintingLayout() const { return false; }
};
} // namespace blink
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 fa87b7a3228..9d8d5a64256 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
@@ -12,6 +12,16 @@
namespace blink {
+namespace {
+
+void MaybeAllowImagePlaceholder(DummyPageHolder* page_holder,
+ FetchParameters& params) {
+ if (page_holder->GetFrame().IsClientLoFiAllowed(params.GetResourceRequest()))
+ params.SetClientLoFiPlaceholder();
+}
+
+} // namespace
+
class TestLocalFrameClient : public EmptyLocalFrameClient {
public:
explicit TestLocalFrameClient(
@@ -32,24 +42,22 @@ TEST(LocalFrameTest, MaybeAllowPlaceholderImageUsesSpecifiedRequestValue) {
request1.SetURL(KURL("http://insecure.com"));
request1.SetPreviewsState(WebURLRequest::kClientLoFiOn);
FetchParameters params1(request1);
- DummyPageHolder::Create(IntSize(800, 600), nullptr,
- new TestLocalFrameClient(WebURLRequest::kPreviewsOff))
- ->GetFrame()
- .MaybeAllowImagePlaceholder(params1);
+ auto page_holder = DummyPageHolder::Create(
+ IntSize(800, 600), nullptr,
+ new TestLocalFrameClient(WebURLRequest::kPreviewsOff));
+ MaybeAllowImagePlaceholder(page_holder.get(), params1);
EXPECT_EQ(FetchParameters::kAllowPlaceholder,
- params1.GetPlaceholderImageRequestType());
+ params1.GetImageRequestOptimization());
ResourceRequest request2;
request2.SetURL(KURL("https://secure.com"));
request2.SetPreviewsState(WebURLRequest::kPreviewsOff);
FetchParameters params2(request2);
- DummyPageHolder::Create(
+ auto page_holder2 = DummyPageHolder::Create(
IntSize(800, 600), nullptr,
- new TestLocalFrameClient(WebURLRequest::kClientLoFiOn))
- ->GetFrame()
- .MaybeAllowImagePlaceholder(params2);
- EXPECT_EQ(FetchParameters::kDisallowPlaceholder,
- params2.GetPlaceholderImageRequestType());
+ new TestLocalFrameClient(WebURLRequest::kClientLoFiOn));
+ MaybeAllowImagePlaceholder(page_holder2.get(), params2);
+ EXPECT_EQ(FetchParameters::kNone, params2.GetImageRequestOptimization());
}
TEST(LocalFrameTest, MaybeAllowPlaceholderImageUsesFramePreviewsState) {
@@ -60,9 +68,9 @@ TEST(LocalFrameTest, MaybeAllowPlaceholderImageUsesFramePreviewsState) {
std::unique_ptr<DummyPageHolder> page_holder = DummyPageHolder::Create(
IntSize(800, 600), nullptr,
new TestLocalFrameClient(WebURLRequest::kClientLoFiOn));
- page_holder->GetFrame().MaybeAllowImagePlaceholder(params1);
+ MaybeAllowImagePlaceholder(page_holder.get(), params1);
EXPECT_EQ(FetchParameters::kAllowPlaceholder,
- params1.GetPlaceholderImageRequestType());
+ params1.GetImageRequestOptimization());
EXPECT_TRUE(page_holder->GetFrame().IsUsingDataSavingPreview());
ResourceRequest request2;
@@ -72,9 +80,8 @@ TEST(LocalFrameTest, MaybeAllowPlaceholderImageUsesFramePreviewsState) {
std::unique_ptr<DummyPageHolder> page_holder2 = DummyPageHolder::Create(
IntSize(800, 600), nullptr,
new TestLocalFrameClient(WebURLRequest::kServerLitePageOn));
- page_holder2->GetFrame().MaybeAllowImagePlaceholder(params2);
- EXPECT_EQ(FetchParameters::kDisallowPlaceholder,
- params2.GetPlaceholderImageRequestType());
+ MaybeAllowImagePlaceholder(page_holder2.get(), params2);
+ EXPECT_EQ(FetchParameters::kNone, params2.GetImageRequestOptimization());
EXPECT_FALSE(page_holder2->GetFrame().IsUsingDataSavingPreview());
}
@@ -84,27 +91,24 @@ TEST(LocalFrameTest,
request1.SetURL(KURL("https://secure.com"));
request1.SetPreviewsState(WebURLRequest::kPreviewsUnspecified);
FetchParameters params1(request1);
- DummyPageHolder::Create(
+ auto page_holder = DummyPageHolder::Create(
IntSize(800, 600), nullptr,
new TestLocalFrameClient(WebURLRequest::kServerLoFiOn |
- WebURLRequest::kClientLoFiOn))
- ->GetFrame()
- .MaybeAllowImagePlaceholder(params1);
+ WebURLRequest::kClientLoFiOn));
+ MaybeAllowImagePlaceholder(page_holder.get(), params1);
EXPECT_EQ(FetchParameters::kAllowPlaceholder,
- params1.GetPlaceholderImageRequestType());
+ params1.GetImageRequestOptimization());
ResourceRequest request2;
request2.SetURL(KURL("http://insecure.com"));
request2.SetPreviewsState(WebURLRequest::kPreviewsUnspecified);
FetchParameters params2(request2);
- DummyPageHolder::Create(
+ auto page_holder2 = DummyPageHolder::Create(
IntSize(800, 600), nullptr,
new TestLocalFrameClient(WebURLRequest::kServerLoFiOn |
- WebURLRequest::kClientLoFiOn))
- ->GetFrame()
- .MaybeAllowImagePlaceholder(params2);
- EXPECT_EQ(FetchParameters::kDisallowPlaceholder,
- params2.GetPlaceholderImageRequestType());
+ WebURLRequest::kClientLoFiOn));
+ MaybeAllowImagePlaceholder(page_holder2.get(), params2);
+ EXPECT_EQ(FetchParameters::kNone, params2.GetImageRequestOptimization());
}
TEST(LocalFrameTest, IsUsingDataSavingPreview) {
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 1a661a7f0bd..39ccc46f037 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
@@ -42,15 +42,16 @@
#include "third_party/blink/renderer/core/css/style_change_reason.h"
#include "third_party/blink/renderer/core/dom/element_visibility_observer.h"
#include "third_party/blink/renderer/core/dom/static_node_list.h"
+#include "third_party/blink/renderer/core/editing/compute_layer_selection.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/editing/markers/document_marker_controller.h"
-#include "third_party/blink/renderer/core/editing/rendered_position.h"
#include "third_party/blink/renderer/core/events/error_event.h"
#include "third_party/blink/renderer/core/exported/web_plugin_container_impl.h"
#include "third_party/blink/renderer/core/frame/browser_controls.h"
#include "third_party/blink/renderer/core/frame/event_handler_registry.h"
#include "third_party/blink/renderer/core/frame/frame_view_auto_size_info.h"
+#include "third_party/blink/renderer/core/frame/link_highlights.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/location.h"
@@ -61,6 +62,7 @@
#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"
#include "third_party/blink/renderer/core/fullscreen/fullscreen.h"
#include "third_party/blink/renderer/core/html/forms/text_control_element.h"
#include "third_party/blink/renderer/core/html/html_frame_element.h"
@@ -95,9 +97,9 @@
#include "third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_context.h"
#include "third_party/blink/renderer/core/page/scrolling/snap_coordinator.h"
#include "third_party/blink/renderer/core/page/scrolling/top_document_root_scroller_controller.h"
+#include "third_party/blink/renderer/core/page/validation_message_client.h"
#include "third_party/blink/renderer/core/paint/block_paint_invalidator.h"
#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h"
-#include "third_party/blink/renderer/core/paint/compositing/composited_selection.h"
#include "third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.h"
#include "third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_as_text.h"
#include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h"
@@ -108,6 +110,8 @@
#include "third_party/blink/renderer/core/paint/pre_paint_tree_walk.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/core/resize_observer/resize_observer_controller.h"
+#include "third_party/blink/renderer/core/scroll/scroll_animator_base.h"
+#include "third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/core/svg/svg_svg_element.h"
#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
@@ -119,6 +123,7 @@
#include "third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.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/link_highlight.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/paint_controller.h"
@@ -126,14 +131,11 @@
#include "third_party/blink/renderer/platform/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/json/json_values.h"
#include "third_party/blink/renderer/platform/language.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.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/scroll/scroll_alignment.h"
-#include "third_party/blink/renderer/platform/scroll/scroll_animator_base.h"
-#include "third_party/blink/renderer/platform/scroll/smooth_scroll_sequencer.h"
#include "third_party/blink/renderer/platform/transforms/transform_state.h"
#include "third_party/blink/renderer/platform/ukm_time_aggregator.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
@@ -168,6 +170,7 @@ constexpr size_t kCssFragmentIdentifierPrefixLength =
// EnsureUkmTimeAggregator().
enum class UkmMetricNames {
kCompositing,
+ kCompositingCommit,
kIntersectionObservation,
kPaint,
kPrePaint,
@@ -233,7 +236,6 @@ LocalFrameView::LocalFrameView(LocalFrame& frame, IntRect frame_rect)
DocumentLifecycle::kUninitialized),
past_layout_lifecycle_update_(false),
suppress_adjust_view_size_(false),
- allows_layout_invalidation_after_layout_clean_(true),
intersection_observation_state_(kNotNeeded),
needs_forced_compositing_update_(false),
needs_focus_on_fragment_(false),
@@ -285,13 +287,12 @@ void LocalFrameView::Reset() {
// 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.
- if (RuntimeEnabledFeatures::
- RenderingPipelineThrottlingLoadingIframesEnabled())
- lifecycle_updates_throttled_ = !GetFrame().IsMainFrame();
+ lifecycle_updates_throttled_ = !GetFrame().IsMainFrame();
has_pending_layout_ = false;
layout_scheduling_enabled_ = true;
in_synchronous_post_layout_ = false;
- layout_count_ = 0;
+ layout_count_for_testing_ = 0;
+ lifecycle_update_count_for_testing_ = 0;
nested_layout_count_ = 0;
post_layout_tasks_timer_.Stop();
update_plugins_timer_.Stop();
@@ -481,7 +482,7 @@ void LocalFrameView::SetFrameRect(const IntRect& unclamped_frame_rect) {
FrameRectsChanged();
if (auto* layout_view = GetLayoutView())
- layout_view->SetMayNeedPaintInvalidation();
+ layout_view->SetShouldCheckForPaintInvalidation();
if (width_changed || height_changed) {
ViewportSizeChanged(width_changed, height_changed);
@@ -759,7 +760,7 @@ void LocalFrameView::PerformLayout(bool in_subtree_layout) {
// LayoutView for paint invalidation. This simplifies our code as we
// just always do a full tree walk.
if (LayoutObject* container = root->Container())
- container->SetMayNeedPaintInvalidation();
+ container->SetShouldCheckForPaintInvalidation();
}
layout_subtree_root_list_.Clear();
} else {
@@ -889,7 +890,7 @@ void LocalFrameView::UpdateLayout() {
if (first_layout_) {
first_layout_ = false;
last_viewport_size_ = GetLayoutSize();
- last_zoom_factor_ = GetLayoutView()->Style()->Zoom();
+ last_zoom_factor_ = GetLayoutView()->StyleRef().Zoom();
ScrollbarMode h_mode;
ScrollbarMode v_mode;
@@ -960,10 +961,9 @@ void LocalFrameView::UpdateLayout() {
this, TracedLayoutObject::Create(*GetLayoutView(), true));
GetLayoutView()->Compositor()->DidLayout();
+ layout_count_for_testing_++;
- layout_count_++;
-
- if (AXObjectCache* cache = document->GetOrCreateAXObjectCache()) {
+ if (AXObjectCache* cache = document->ExistingAXObjectCache()) {
const KURL& url = document->Url();
if (url.IsValid() && !url.IsAboutBlankURL())
cache->HandleLayoutComplete(document);
@@ -990,8 +990,7 @@ void LocalFrameView::UpdateLayout() {
GetLayoutView()->AssertSubtreeIsLaidOut();
#endif
- if (frame_->IsMainFrame() &&
- RuntimeEnabledFeatures::VisualViewportAPIEnabled()) {
+ if (frame_->IsMainFrame()) {
// Scrollbars changing state can cause a visual viewport size change.
DoubleSize new_viewport_size(visual_viewport.VisibleWidthCSSPx(),
visual_viewport.VisibleHeightCSSPx());
@@ -1267,7 +1266,7 @@ void LocalFrameView::ViewportSizeChanged(bool width_changed,
if (GetLayoutView() && frame_->IsMainFrame() &&
frame_->GetPage()->GetBrowserControls().TotalHeight()) {
- if (GetLayoutView()->Style()->HasFixedBackgroundImage()) {
+ if (GetLayoutView()->StyleRef().HasFixedBackgroundImage()) {
// We've already issued a full invalidation above.
GetLayoutView()->SetShouldDoFullPaintInvalidationOnResizeIfNeeded(
width_changed, height_changed);
@@ -1383,8 +1382,8 @@ bool LocalFrameView::InvalidateViewportConstrainedObjects() {
for (auto* const viewport_constrained_object :
*viewport_constrained_objects_) {
LayoutObject* layout_object = viewport_constrained_object;
- DCHECK(layout_object->Style()->HasViewportConstrainedPosition() ||
- layout_object->Style()->HasStickyConstrainedPosition());
+ DCHECK(layout_object->StyleRef().HasViewportConstrainedPosition() ||
+ layout_object->StyleRef().HasStickyConstrainedPosition());
DCHECK(layout_object->HasLayer());
PaintLayer* layer = ToLayoutBoxModelObject(layout_object)->Layer();
@@ -1394,7 +1393,7 @@ bool LocalFrameView::InvalidateViewportConstrainedObjects() {
// If the layer has no visible content, then we shouldn't invalidate; but
// if we're not compositing-inputs-clean, then we can't query
// layer->SubtreeIsInvisible() here.
- layout_object->SetMayNeedPaintInvalidationSubtree();
+ layout_object->SetSubtreeShouldCheckForPaintInvalidation();
if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled() &&
!layer->NeedsRepaint()) {
// Paint properties of the layer relative to its containing graphics
@@ -1465,10 +1464,6 @@ void LocalFrameView::ProcessUrlFragment(const KURL& url,
UseCounter::Count(&GetFrame(),
WebFeature::kScrollToFragmentSucceedWithIsomorphic);
break;
- case DecodeURLResult::kMixed:
- UseCounter::Count(&GetFrame(),
- WebFeature::kScrollToFragmentSucceedWithMixed);
- break;
}
} else {
switch (decode_result) {
@@ -1484,10 +1479,6 @@ void LocalFrameView::ProcessUrlFragment(const KURL& url,
UseCounter::Count(&GetFrame(),
WebFeature::kScrollToFragmentFailWithIsomorphic);
break;
- case DecodeURLResult::kMixed:
- UseCounter::Count(&GetFrame(),
- WebFeature::kScrollToFragmentFailWithMixed);
- break;
}
}
} else {
@@ -1532,6 +1523,9 @@ bool LocalFrameView::ProcessUrlFragmentHelper(const String& name,
!(name.IsEmpty() || DeprecatedEqualIgnoringCase(name, "top")))
return false;
+ if (anchor_node)
+ anchor_node->DispatchActivateInvisibleEventIfNeeded();
+
if (behavior == kUrlFragmentDontScroll)
return true;
@@ -1598,11 +1592,11 @@ void LocalFrameView::SetLayoutSizeFixedToFrameSize(bool is_fixed) {
SetLayoutSizeInternal(Size());
}
-static CompositedSelection ComputeCompositedSelection(LocalFrame& frame) {
+static cc::LayerSelection ComputeLayerSelection(LocalFrame& frame) {
if (!frame.View() || frame.View()->ShouldThrottleRendering())
return {};
- return ComputeCompositedSelection(frame.Selection());
+ return ComputeLayerSelection(frame.Selection());
}
void LocalFrameView::UpdateCompositedSelectionIfNeeded() {
@@ -1622,10 +1616,9 @@ void LocalFrameView::UpdateCompositedSelectionIfNeeded() {
: nullptr;
if (local_frame) {
- const CompositedSelection& selection =
- ComputeCompositedSelection(*local_frame);
- if (selection.type != kNoSelection) {
- page->GetChromeClient().UpdateCompositedSelection(local_frame, selection);
+ const cc::LayerSelection& selection = ComputeLayerSelection(*local_frame);
+ if (selection != cc::LayerSelection()) {
+ page->GetChromeClient().UpdateLayerSelection(local_frame, selection);
return;
}
}
@@ -1640,7 +1633,7 @@ void LocalFrameView::UpdateCompositedSelectionIfNeeded() {
local_frame = &frame_->LocalFrameRoot();
}
DCHECK(local_frame);
- page->GetChromeClient().ClearCompositedSelection(local_frame);
+ page->GetChromeClient().ClearLayerSelection(local_frame);
}
void LocalFrameView::SetNeedsCompositingUpdate(
@@ -1651,7 +1644,7 @@ void LocalFrameView::SetNeedsCompositingUpdate(
}
}
-PlatformChromeClient* LocalFrameView::GetChromeClient() const {
+ChromeClient* LocalFrameView::GetChromeClient() const {
Page* page = GetFrame().GetPage();
if (!page)
return nullptr;
@@ -1718,9 +1711,11 @@ static bool PrepareOrthogonalWritingModeRootForLayout(LayoutObject& root) {
ToLayoutBox(root).IsGridItem() || root.IsTablePart())
return false;
- // Do not lay out objects managed by LayoutNG.
- if (RuntimeEnabledFeatures::LayoutNGEnabled() &&
- (root.IsLayoutBlock() && IsLayoutNGContainingBlock(ToLayoutBlock(&root))))
+ // Do not pre-layout objects that are fully managed by LayoutNG; it is not
+ // necessary and may lead to double layouts. We do need to pre-layout
+ // objects whose containing block is a legacy object so that it can
+ // properly compute its intrinsic size.
+ if (RuntimeEnabledFeatures::LayoutNGEnabled() && IsManagedByLayoutNG(root))
return false;
RemoveFloatingObjectsForSubtreeRoot(root);
@@ -1742,6 +1737,7 @@ void LocalFrameView::ScheduleOrthogonalWritingModeRootsForLayout() {
}
bool LocalFrameView::CheckLayoutInvalidationIsAllowed() const {
+#if DCHECK_IS_ON()
if (allows_layout_invalidation_after_layout_clean_)
return true;
@@ -1750,6 +1746,7 @@ bool LocalFrameView::CheckLayoutInvalidationIsAllowed() const {
CHECK_FOR_DIRTY_LAYOUT(Lifecycle().GetState() <
DocumentLifecycle::kLayoutClean);
+#endif
return true;
}
@@ -1897,6 +1894,9 @@ void LocalFrameView::ScrollAndFocusFragmentAnchor() {
if (!anchor_node)
return;
+ if (!frame_->GetDocument()->IsRenderingReady())
+ return;
+
if (anchor_node->GetLayoutObject()) {
LayoutRect rect;
if (anchor_node != frame_->GetDocument()) {
@@ -2089,8 +2089,7 @@ void LocalFrameView::SendResizeEventIfNeeded() {
last_viewport_size_ = GetLayoutSize();
last_zoom_factor_ = layout_view->StyleRef().Zoom();
- if (RuntimeEnabledFeatures::VisualViewportAPIEnabled())
- frame_->GetDocument()->EnqueueVisualViewportResizeEvent();
+ frame_->GetDocument()->EnqueueVisualViewportResizeEvent();
frame_->GetDocument()->EnqueueResizeEvent();
@@ -2216,7 +2215,7 @@ void LocalFrameView::UpdateGeometriesIfNeeded() {
}
void LocalFrameView::UpdateAllLifecyclePhases() {
- GetFrame().LocalFrameRoot().View()->UpdateLifecyclePhasesInternal(
+ GetFrame().LocalFrameRoot().View()->UpdateLifecyclePhases(
DocumentLifecycle::kPaintClean);
}
@@ -2225,7 +2224,7 @@ bool LocalFrameView::UpdateLifecycleToCompositingCleanPlusScrolling() {
if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
return UpdateAllLifecyclePhasesExceptPaint();
} else {
- return GetFrame().LocalFrameRoot().View()->UpdateLifecyclePhasesInternal(
+ return GetFrame().LocalFrameRoot().View()->UpdateLifecyclePhases(
DocumentLifecycle::kCompositingClean);
}
}
@@ -2234,18 +2233,18 @@ bool LocalFrameView::UpdateLifecycleToCompositingInputsClean() {
// When SPv2 is enabled, the standard compositing lifecycle steps do not
// exist; compositing is done after paint instead.
DCHECK(!RuntimeEnabledFeatures::SlimmingPaintV2Enabled());
- return GetFrame().LocalFrameRoot().View()->UpdateLifecyclePhasesInternal(
+ return GetFrame().LocalFrameRoot().View()->UpdateLifecyclePhases(
DocumentLifecycle::kCompositingInputsClean);
}
bool LocalFrameView::UpdateAllLifecyclePhasesExceptPaint() {
- return GetFrame().LocalFrameRoot().View()->UpdateLifecyclePhasesInternal(
+ return GetFrame().LocalFrameRoot().View()->UpdateLifecyclePhases(
DocumentLifecycle::kPrePaintClean);
}
void LocalFrameView::UpdateLifecyclePhasesForPrinting() {
auto* local_frame_view_root = GetFrame().LocalFrameRoot().View();
- local_frame_view_root->UpdateLifecyclePhasesInternal(
+ local_frame_view_root->UpdateLifecyclePhases(
DocumentLifecycle::kPrePaintClean);
auto* detached_frame_view = this;
@@ -2259,14 +2258,13 @@ void LocalFrameView::UpdateLifecyclePhasesForPrinting() {
// We are printing a detached frame or a descendant of a detached frame which
// was not reached in some phases during during |local_frame_view_root->
- // UpdateLifecyclePhasesInternalnormal()|. We need the subtree to be ready for
+ // UpdateLifecyclePhasesnormal()|. We need the subtree to be ready for
// painting.
- detached_frame_view->UpdateLifecyclePhasesInternal(
- DocumentLifecycle::kPrePaintClean);
+ detached_frame_view->UpdateLifecyclePhases(DocumentLifecycle::kPrePaintClean);
}
bool LocalFrameView::UpdateLifecycleToLayoutClean() {
- return GetFrame().LocalFrameRoot().View()->UpdateLifecyclePhasesInternal(
+ return GetFrame().LocalFrameRoot().View()->UpdateLifecyclePhases(
DocumentLifecycle::kLayoutClean);
}
@@ -2348,13 +2346,19 @@ void LocalFrameView::ClearPrintContext() {
// TODO(leviw): We don't assert lifecycle information from documents in child
// WebPluginContainerImpls.
-bool LocalFrameView::UpdateLifecyclePhasesInternal(
+bool LocalFrameView::UpdateLifecyclePhases(
DocumentLifecycle::LifecycleState target_state) {
- if (frame_->GetDocument() &&
- frame_->GetDocument()->Lifecycle().LifecyclePostponed())
+ // 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() &&
+ frame_->GetDocument()->Lifecycle().LifecyclePostponed())) {
return false;
- if (current_update_lifecycle_phases_target_state_ !=
- DocumentLifecycle::kUninitialized) {
+ }
+
+ // Prevent reentrance.
+ // TODO(vmpstr): Should we just have a DCHECK instead here?
+ if (UNLIKELY(current_update_lifecycle_phases_target_state_ !=
+ DocumentLifecycle::kUninitialized)) {
NOTREACHED()
<< "LocalFrameView::updateLifecyclePhasesInternal() reentrance";
return false;
@@ -2371,23 +2375,107 @@ bool LocalFrameView::UpdateLifecyclePhasesInternal(
target_state == DocumentLifecycle::kCompositingClean ||
target_state == DocumentLifecycle::kPrePaintClean ||
target_state == DocumentLifecycle::kPaintClean);
+ lifecycle_update_count_for_testing_++;
+ // If the document is not active then it is either not yet initialized, or it
+ // is stopping. In either case, we can't reach one of the supported target
+ // states.
if (!frame_->GetDocument()->IsActive())
- return Lifecycle().GetState() == target_state;
+ return false;
+ // This is used to guard against reentrance. It is also used in conjunction
+ // with the current lifecycle state to determine which phases are yet to run
+ // in this cycle.
base::AutoReset<DocumentLifecycle::LifecycleState> target_state_scope(
&current_update_lifecycle_phases_target_state_, target_state);
-
+ // This is used to check if we're within a lifecycle update but have passed
+ // the layout update phase. Note there is a bit of a subtlety here: it's not
+ // sufficient for us to check the current lifecycle state, since it can be
+ // past kLayoutClean but the function to run style and layout phase has not
+ // actually been run yet. Since this bool affects throttling, and throttling,
+ // in turn, determines whether style and layout function will run, we need a
+ // separate bool.
+ base::AutoReset<bool> past_layout_lifecycle_resetter(
+ &past_layout_lifecycle_update_, false);
+
+ // If we're throttling, then we don't need to update lifecycle phases, only
+ // the throttling status.
if (ShouldThrottleRendering()) {
UpdateThrottlingStatusForSubtree();
return Lifecycle().GetState() == target_state;
}
+ // 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();
+ // Run the lifecycle updates.
+ UpdateLifecyclePhasesInternal(target_state);
+
+ // Update intersection observations if needed.
+ if (intersection_observation_state_ != kNotNeeded &&
+ target_state == DocumentLifecycle::kPaintClean) {
+ TRACE_EVENT0("blink,benchmark",
+ "LocalFrameView::UpdateViewportIntersectionsForSubtree");
+ SCOPED_UMA_AND_UKM_TIMER("Blink.IntersectionObservation.UpdateTime",
+ UkmMetricNames::kIntersectionObservation);
+ UpdateViewportIntersectionsForSubtree();
+ }
+
+ UpdateThrottlingStatusForSubtree();
+
+ return Lifecycle().GetState() == target_state;
+}
+
+void LocalFrameView::UpdateLifecyclePhasesInternal(
+ DocumentLifecycle::LifecycleState target_state) {
+ bool run_more_lifecycle_phases =
+ RunStyleAndLayoutLifecyclePhases(target_state);
+ DCHECK(Lifecycle().GetState() >= DocumentLifecycle::kLayoutClean);
+ if (!run_more_lifecycle_phases)
+ return;
+
+ if (!GetLayoutView())
+ return;
+
+#if DCHECK_IS_ON()
+ DisallowLayoutInvalidationScope disallow_layout_invalidation(this);
+#endif
+
+ {
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"),
+ "SetLayerTreeId", TRACE_EVENT_SCOPE_THREAD, "data",
+ InspectorSetLayerTreeId::Data(frame_.Get()));
+ TRACE_EVENT1("devtools.timeline", "UpdateLayerTree", "data",
+ InspectorUpdateLayerTreeEvent::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 for slimming paint v2.
+ run_more_lifecycle_phases = RunPrePaintLifecyclePhase(target_state);
+ DCHECK(ShouldThrottleRendering() ||
+ Lifecycle().GetState() >= DocumentLifecycle::kPrePaintClean);
+ if (!run_more_lifecycle_phases)
+ return;
+ }
+
+ DCHECK_EQ(target_state, DocumentLifecycle::kPaintClean);
+ RunPaintLifecyclePhase();
+ DCHECK(ShouldThrottleRendering() ||
+ (frame_->GetDocument()->Printing() &&
+ !RuntimeEnabledFeatures::PrintBrowserEnabled()) ||
+ Lifecycle().GetState() == DocumentLifecycle::kPaintClean);
+}
+
+bool LocalFrameView::RunStyleAndLayoutLifecyclePhases(
+ DocumentLifecycle::LifecycleState target_state) {
UpdateStyleAndLayoutIfNeededRecursive();
DCHECK(Lifecycle().GetState() >= DocumentLifecycle::kLayoutClean);
@@ -2408,140 +2496,144 @@ bool LocalFrameView::UpdateLifecyclePhasesInternal(
});
}
- if (target_state == DocumentLifecycle::kLayoutClean) {
- UpdateThrottlingStatusForSubtree();
- return Lifecycle().GetState() == target_state;
- }
+ if (target_state == DocumentLifecycle::kLayoutClean)
+ return false;
- base::AutoReset<bool> past_layout_lifecycle_update(
- &past_layout_lifecycle_update_, true);
+ // This will be reset by AutoReset in the calling function
+ // (UpdateLifecyclePhases()).
+ past_layout_lifecycle_update_ = true;
- // OOPIF local frame roots that are throttled can return now that layout
- // is clean and intersection observations can be calculated.
- if (ShouldThrottleRendering()) {
- if (target_state == DocumentLifecycle::kPaintClean)
- UpdateViewportIntersectionsForSubtree();
- UpdateThrottlingStatusForSubtree();
- return Lifecycle().GetState() == target_state;
- }
+ // After layout and the |past_layout_lifecycle_update_| update, the value of
+ // ShouldThrottleRendering() can change. OOPIF local frame roots that are
+ // throttled can return now that layout is clean. This situation happens if
+ // the throttling was disabled due to required intersection observation, which
+ // can now be run.
+ if (ShouldThrottleRendering())
+ return false;
+ // Now we can run post layout steps in preparation for further phases.
ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) {
frame_view.PerformScrollAnchoringAdjustments();
});
+ frame_->GetPage()->GetValidationMessageClient().LayoutOverlay();
+ frame_->GetPage()->UpdatePageColorOverlay();
+
if (target_state == DocumentLifecycle::kPaintClean) {
ForAllNonThrottledLocalFrameViews(
[](LocalFrameView& frame_view) { frame_view.NotifyResizeObservers(); });
NotifyFrameRectsChangedIfNeededRecursive();
}
+ return true;
+}
- if (auto* layout_view = GetLayoutView()) {
- allows_layout_invalidation_after_layout_clean_ = false;
- ForAllChildLocalFrameViews([](LocalFrameView& frame_view) {
- if (!frame_view.ShouldThrottleRendering())
- frame_view.CheckDoesNotNeedLayout();
- frame_view.allows_layout_invalidation_after_layout_clean_ = false;
+bool LocalFrameView::RunCompositingLifecyclePhase(
+ DocumentLifecycle::LifecycleState target_state) {
+ auto* layout_view = GetLayoutView();
+ DCHECK(layout_view);
+
+ if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ SCOPED_UMA_AND_UKM_TIMER("Blink.Compositing.UpdateTime",
+ UkmMetricNames::kCompositing);
+ layout_view->Compositor()->UpdateIfNeededRecursive(target_state);
+ } else {
+ ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) {
+ frame_view.GetLayoutView()->Layer()->UpdateDescendantDependentFlags();
+ frame_view.GetLayoutView()->CommitPendingSelection();
});
+ }
- {
- TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"),
- "SetLayerTreeId", TRACE_EVENT_SCOPE_THREAD, "data",
- InspectorSetLayerTreeId::Data(frame_.Get()));
- TRACE_EVENT1("devtools.timeline", "UpdateLayerTree", "data",
- InspectorUpdateLayerTreeEvent::Data(frame_.Get()));
-
- if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
- SCOPED_UMA_AND_UKM_TIMER("Blink.Compositing.UpdateTime",
- UkmMetricNames::kCompositing);
- layout_view->Compositor()->UpdateIfNeededRecursive(target_state);
- } else {
- ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) {
- frame_view.GetLayoutView()->Layer()->UpdateDescendantDependentFlags();
- frame_view.GetLayoutView()->CommitPendingSelection();
- });
- }
+ // We may be in kCompositingInputsClean clean, which does not need to notify
+ // the global root scroller controller.
+ if (target_state >= DocumentLifecycle::kCompositingClean) {
+ frame_->GetPage()->GlobalRootScrollerController().DidUpdateCompositing(
+ *this);
+ }
- if (target_state >= DocumentLifecycle::kCompositingClean) {
- frame_->GetPage()->GlobalRootScrollerController().DidUpdateCompositing(
- *this);
- }
+ // We need to run more phases only if the target is beyond kCompositingClean.
+ if (target_state > DocumentLifecycle::kCompositingClean) {
+ // TODO(vmpstr): Why is composited selection only updated if we're moving
+ // past kCompositingClean?
+ UpdateCompositedSelectionIfNeeded();
+ return true;
+ }
+ return false;
+}
- if (target_state >= DocumentLifecycle::kPrePaintClean) {
- UpdateCompositedSelectionIfNeeded();
+bool LocalFrameView::RunPrePaintLifecyclePhase(
+ DocumentLifecycle::LifecycleState target_state) {
+ TRACE_EVENT0("blink,benchmark", "LocalFrameView::prePaint");
- // TODO(pdr): prePaint should be under the "Paint" devtools timeline
- // step for slimming paint v2.
- PrePaint();
- }
+ ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) {
+ frame_view.Lifecycle().AdvanceTo(DocumentLifecycle::kInPrePaint);
+ if (frame_view.CanThrottleRendering()) {
+ // This frame can be throttled but not throttled, meaning we are not in an
+ // AllowThrottlingScope. Now this frame may contain dirty paint flags, and
+ // we need to propagate the flags into the ancestor chain so that
+ // PrePaintTreeWalk can reach this frame.
+ frame_view.SetNeedsPaintPropertyUpdate();
+ if (auto* owner = frame_view.GetFrame().OwnerLayoutObject())
+ owner->SetShouldCheckForPaintInvalidation();
}
+ });
- if (target_state == DocumentLifecycle::kPaintClean) {
- // While printing a document, the paint walk is done by the printing
- // component into a special canvas. There is no point doing a normal paint
- // step (or animations update for BlinkGenPropertyTrees/SPv2) 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 print_mode_enabled = frame_->GetDocument()->Printing() &&
- !RuntimeEnabledFeatures::PrintBrowserEnabled();
- if (!print_mode_enabled)
- PaintTree();
-
- if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
- if (layout_view->Compositor()->InCompositingMode()) {
- GetScrollingCoordinator()->UpdateAfterPaint(this);
- }
- }
+ {
+ SCOPED_UMA_AND_UKM_TIMER("Blink.PrePaint.UpdateTime",
+ UkmMetricNames::kPrePaint);
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled() ||
- RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
- if (!print_mode_enabled) {
- base::Optional<CompositorElementIdSet> composited_element_ids =
- CompositorElementIdSet();
- PushPaintArtifactToCompositor(composited_element_ids.value());
- // TODO(wkorman): Add call to UpdateCompositorScrollAnimations here.
- DocumentAnimations::UpdateAnimations(GetLayoutView()->GetDocument(),
- DocumentLifecycle::kPaintClean,
- composited_element_ids);
-
- // Notify the controller that the artifact has been pushed and some
- // lifecycle state can be freed (such as raster invalidations).
- paint_controller_->FinishCycle();
- // PaintController for BlinkGenPropertyTrees is transient.
- if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled())
- paint_controller_ = nullptr;
- }
- }
+ PrePaintTreeWalk().WalkTree(*this);
+ }
- if (intersection_observation_state_ != kNotNeeded) {
- TRACE_EVENT0("blink,benchmark",
- "LocalFrameView::UpdateViewportIntersectionsForSubtree");
- SCOPED_UMA_AND_UKM_TIMER("Blink.IntersectionObservation.UpdateTime",
- UkmMetricNames::kIntersectionObservation);
- UpdateViewportIntersectionsForSubtree();
- }
+ ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) {
+ frame_view.Lifecycle().AdvanceTo(DocumentLifecycle::kPrePaintClean);
+ });
- DCHECK(!frame_->Selection().NeedsLayoutSelectionUpdate());
- DCHECK(ShouldThrottleRendering() ||
- (frame_->GetDocument()->Printing() &&
- Lifecycle().GetState() == DocumentLifecycle::kPrePaintClean) ||
- Lifecycle().GetState() == DocumentLifecycle::kPaintClean);
+ return target_state > DocumentLifecycle::kPrePaintClean;
+}
+
+void LocalFrameView::RunPaintLifecyclePhase() {
+ // While printing a document, the paint walk is done by the printing
+ // component into a special canvas. There is no point doing a normal paint
+ // step (or animations update for BlinkGenPropertyTrees/SPv2) 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 print_mode_enabled = frame_->GetDocument()->Printing() &&
+ !RuntimeEnabledFeatures::PrintBrowserEnabled();
+ if (!print_mode_enabled)
+ PaintTree();
+
+ if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (GetLayoutView()->Compositor()->InCompositingMode()) {
+ GetScrollingCoordinator()->UpdateAfterPaint(this);
}
-
- allows_layout_invalidation_after_layout_clean_ = true;
- ForAllChildLocalFrameViews([](LocalFrameView& frame_view) {
- if (!frame_view.ShouldThrottleRendering())
- frame_view.CheckDoesNotNeedLayout();
- frame_view.allows_layout_invalidation_after_layout_clean_ = true;
- });
}
- UpdateThrottlingStatusForSubtree();
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled() ||
+ RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
+ if (!print_mode_enabled) {
+ base::Optional<CompositorElementIdSet> composited_element_ids =
+ CompositorElementIdSet();
+ PushPaintArtifactToCompositor(composited_element_ids.value());
+ // TODO(wkorman): Add call to UpdateCompositorScrollAnimations here.
+ ForAllNonThrottledLocalFrameViews(
+ [&composited_element_ids](LocalFrameView& frame_view) {
+ DocumentAnimations::UpdateAnimations(
+ frame_view.GetLayoutView()->GetDocument(),
+ DocumentLifecycle::kPaintClean, composited_element_ids);
+ });
- return Lifecycle().GetState() == target_state;
+ // Notify the controller that the artifact has been pushed and some
+ // lifecycle state can be freed (such as raster invalidations).
+ paint_controller_->FinishCycle();
+ // PaintController for BlinkGenPropertyTrees is transient.
+ if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled())
+ paint_controller_ = nullptr;
+ }
+ }
}
void LocalFrameView::EnqueueScrollAnchoringAdjustment(
@@ -2569,33 +2661,6 @@ void LocalFrameView::PerformScrollAnchoringAdjustments() {
}
}
-void LocalFrameView::PrePaint() {
- TRACE_EVENT0("blink,benchmark", "LocalFrameView::prePaint");
-
- ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) {
- frame_view.Lifecycle().AdvanceTo(DocumentLifecycle::kInPrePaint);
- if (frame_view.CanThrottleRendering()) {
- // This frame can be throttled but not throttled, meaning we are not in an
- // AllowThrottlingScope. Now this frame may contain dirty paint flags, and
- // we need to propagate the flags into the ancestor chain so that
- // PrePaintTreeWalk can reach this frame.
- frame_view.SetNeedsPaintPropertyUpdate();
- if (auto* owner = frame_view.GetFrame().OwnerLayoutObject())
- owner->SetMayNeedPaintInvalidation();
- }
- });
-
- {
- SCOPED_UMA_AND_UKM_TIMER("Blink.PrePaint.UpdateTime",
- UkmMetricNames::kPrePaint);
- PrePaintTreeWalk().WalkTree(*this);
- }
-
- ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) {
- frame_view.Lifecycle().AdvanceTo(DocumentLifecycle::kPrePaintClean);
- });
-}
-
static void CollectViewportLayersForLayerList(GraphicsContext& context,
VisualViewport& visual_viewport) {
DCHECK(RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled());
@@ -2653,7 +2718,11 @@ static void CollectDrawableLayersForLayerListRecursively(
if (!layer || layer->Client().ShouldThrottleRendering())
return;
- if (layer->DrawsContent()) {
+ // We need to collect all layers that draw content, as well as some layers
+ // that don't for the purposes of hit testing. For example, an empty div
+ // will not draw content but needs to create a layer to ensure scroll events
+ // do not pass through it.
+ if (layer->DrawsContent() || layer->GetHitTestableWithoutDrawsContent()) {
ScopedPaintChunkProperties scope(context.GetPaintController(),
layer->GetPropertyTreeState(), *layer,
DisplayItem::kForeignLayerWrapper);
@@ -2685,21 +2754,41 @@ static void CollectDrawableLayersForLayerListRecursively(
CollectDrawableLayersForLayerListRecursively(context, layer->MaskLayer());
}
+static void CollectLinkHighlightLayersForLayerListRecursively(
+ GraphicsContext& context,
+ const GraphicsLayer* layer) {
+ DCHECK(RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled());
+
+ if (!layer || layer->Client().ShouldThrottleRendering())
+ return;
+
+ for (auto* highlight : layer->GetLinkHighlights()) {
+ DCHECK(highlight->effect())
+ << "Highlight effect node should have been created in PrePaint.";
+ auto* highlight_layer = highlight->Layer();
+ auto property_tree_state = layer->GetPropertyTreeState();
+ property_tree_state.SetEffect(highlight->effect());
+ ScopedPaintChunkProperties scope(context.GetPaintController(),
+ property_tree_state, *highlight,
+ DisplayItem::kForeignLayerLinkHighlight);
+ auto position = highlight_layer->position();
+ auto size = highlight_layer->bounds();
+ RecordForeignLayer(context, *highlight,
+ DisplayItem::kForeignLayerLinkHighlight, highlight_layer,
+ layer->GetOffsetFromTransformNode() +
+ FloatSize(position.x(), position.y()),
+ IntSize(size.width(), size.height()));
+ }
+
+ for (const auto* child : layer->Children())
+ CollectLinkHighlightLayersForLayerListRecursively(context, child);
+}
+
static void PaintGraphicsLayerRecursively(GraphicsLayer* layer) {
layer->PaintRecursively();
#if DCHECK_IS_ON()
- if (VLOG_IS_ON(2)) {
- DEFINE_STATIC_LOCAL(String, s_previous_tree, ());
- LayerTreeFlags flags = VLOG_IS_ON(3) ? 0xffffffff : kOutputAsLayerTree;
- String new_tree = GraphicsLayerTreeAsTextForTesting(layer, flags);
- if (new_tree != s_previous_tree) {
- VLOG(2) << "After GraphicsLayer::PaintRecursively()\n"
- << "GraphicsLayer tree:\n"
- << new_tree.Utf8().data();
- s_previous_tree = new_tree;
- }
- }
+ VerboseLogGraphicsLayerTree(layer);
#endif
}
@@ -2707,8 +2796,7 @@ void LocalFrameView::PaintTree() {
TRACE_EVENT0("blink,benchmark", "LocalFrameView::paintTree");
SCOPED_UMA_AND_UKM_TIMER("Blink.Paint.UpdateTime", UkmMetricNames::kPaint);
- DCHECK(GetFrame() == GetPage()->MainFrame() ||
- (!GetFrame().Tree().Parent()->IsLocalFrame()));
+ DCHECK(GetFrame().IsLocalRoot());
auto* layout_view = GetLayoutView();
DCHECK(layout_view);
@@ -2768,6 +2856,28 @@ void LocalFrameView::PaintTree() {
}
}
+ // TODO(chrishtr): Link highlights don't currently paint themselves,
+ // it's still driven by cc. Fix this.
+ // This uses an invalidation approach based on graphics layer raster
+ // invalidation so it must be after paint. This adds/removes link highlight
+ // layers so it must be before |CollectDrawableLayersForLayerListRecursively|.
+ frame_->GetPage()->GetLinkHighlights().UpdateGeometry();
+
+ frame_->GetPage()->GetValidationMessageClient().PaintOverlay();
+ frame_->GetPage()->PaintPageColorOverlay();
+
+ ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) {
+ frame_view.Lifecycle().AdvanceTo(DocumentLifecycle::kPaintClean);
+ if (auto* layout_view = frame_view.GetLayoutView())
+ layout_view->Layer()->ClearNeedsRepaintRecursively();
+ });
+
+ // Devtools overlays query the inspected page's paint data so this update
+ // needs to be after the lifecycle advance to kPaintClean. Because devtools
+ // overlays can add layers, this needs to be before layers are collected.
+ if (auto* web_local_frame_impl = WebLocalFrameImpl::FromFrame(frame_))
+ web_local_frame_impl->UpdateDevToolsOverlays();
+
if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
// BlinkGenPropertyTrees just needs a transient PaintController to
// collect the foreign layers which doesn't need caching. It also
@@ -2790,16 +2900,13 @@ void LocalFrameView::PaintTree() {
// With BlinkGenPropertyTrees, |PaintRootGraphicsLayer| is the ancestor of
// all drawable layers (see: PaintLayerCompositor::PaintRootGraphicsLayer)
// so we do not need to collect scrollbars separately.
- CollectDrawableLayersForLayerListRecursively(
- context, layout_view->Compositor()->PaintRootGraphicsLayer());
+ auto* root = layout_view->Compositor()->PaintRootGraphicsLayer();
+ CollectDrawableLayersForLayerListRecursively(context, root);
+ // Link highlights paint after all other layers.
+ if (!frame_->GetPage()->GetLinkHighlights().IsEmpty())
+ CollectLinkHighlightLayersForLayerListRecursively(context, root);
paint_controller_->CommitNewDisplayItems();
}
-
- ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) {
- frame_view.Lifecycle().AdvanceTo(DocumentLifecycle::kPaintClean);
- if (auto* layout_view = frame_view.GetLayoutView())
- layout_view->Layer()->ClearNeedsRepaintRecursively();
- });
}
void LocalFrameView::PushPaintArtifactToCompositor(
@@ -2827,8 +2934,8 @@ void LocalFrameView::PushPaintArtifactToCompositor(
paint_artifact_compositor_->RootLayer(), &GetFrame());
}
- SCOPED_UMA_AND_UKM_TIMER("Blink.Compositing.UpdateTime",
- UkmMetricNames::kCompositing);
+ SCOPED_UMA_AND_UKM_TIMER("Blink.CompositingCommit.UpdateTime",
+ UkmMetricNames::kCompositingCommit);
paint_artifact_compositor_->Update(
paint_controller_->GetPaintArtifactShared(), composited_element_ids,
@@ -2964,12 +3071,12 @@ void LocalFrameView::ForceLayoutForPagination(
// Dumping externalRepresentation(m_frame->layoutObject()).ascii() is a good
// trick to see the state of things before and after the layout
if (LayoutView* layout_view = this->GetLayoutView()) {
- float page_logical_width = layout_view->Style()->IsHorizontalWritingMode()
+ float page_logical_width = layout_view->StyleRef().IsHorizontalWritingMode()
? page_size.Width()
: page_size.Height();
- float page_logical_height = layout_view->Style()->IsHorizontalWritingMode()
- ? page_size.Height()
- : page_size.Width();
+ float page_logical_height =
+ layout_view->StyleRef().IsHorizontalWritingMode() ? page_size.Height()
+ : page_size.Width();
LayoutUnit floored_page_logical_width =
static_cast<LayoutUnit>(page_logical_width);
@@ -2987,7 +3094,7 @@ void LocalFrameView::ForceLayoutForPagination(
// FIXME: We are assuming a shrink-to-fit printing implementation. A
// cropping implementation should not do this!
bool horizontal_writing_mode =
- layout_view->Style()->IsHorizontalWritingMode();
+ layout_view->StyleRef().IsHorizontalWritingMode();
const LayoutRect& document_rect = LayoutRect(layout_view->DocumentRect());
LayoutUnit doc_logical_width = horizontal_writing_mode
? document_rect.Width()
@@ -3027,7 +3134,7 @@ void LocalFrameView::ForceLayoutForPagination(
? updated_document_rect.MaxX()
: updated_document_rect.MaxY();
LayoutUnit clipped_logical_left;
- if (!layout_view->Style()->IsLeftToRightDirection()) {
+ if (!layout_view->StyleRef().IsLeftToRightDirection()) {
clipped_logical_left =
LayoutUnit(doc_logical_right - page_logical_width);
}
@@ -3316,32 +3423,6 @@ void LocalFrameView::TrackObjectPaintInvalidation(
tracked_object_paint_invalidations_->push_back(invalidation);
}
-std::unique_ptr<JSONArray>
-LocalFrameView::TrackedObjectPaintInvalidationsAsJSON() const {
- if (!tracked_object_paint_invalidations_)
- return nullptr;
-
- std::unique_ptr<JSONArray> result = JSONArray::Create();
- for (Frame* frame = &frame_->Tree().Top(); frame;
- frame = frame->Tree().TraverseNext()) {
- if (!frame->IsLocalFrame())
- continue;
- if (auto* layout_view = ToLocalFrame(frame)->ContentLayoutObject()) {
- if (!layout_view->GetFrameView()->tracked_object_paint_invalidations_)
- continue;
- for (const auto& item :
- *layout_view->GetFrameView()->tracked_object_paint_invalidations_) {
- std::unique_ptr<JSONObject> item_json = JSONObject::Create();
- item_json->SetString("object", item.name);
- item_json->SetString("reason",
- PaintInvalidationReasonToString(item.reason));
- result->PushObject(std::move(item_json));
- }
- }
- }
- return result;
-}
-
void LocalFrameView::AddResizerArea(LayoutBox& resizer_box) {
if (!resizer_areas_)
resizer_areas_ = std::make_unique<ResizerAreaSet>();
@@ -3358,7 +3439,7 @@ void LocalFrameView::RemoveResizerArea(LayoutBox& resizer_box) {
}
void LocalFrameView::ScheduleAnimation() {
- if (auto* client = ToChromeClient(GetChromeClient()))
+ if (auto* client = GetChromeClient())
client->ScheduleAnimation(this);
}
@@ -3642,7 +3723,7 @@ IntPoint LocalFrameView::FrameToViewport(const IntPoint& point_in_frame) const {
}
IntRect LocalFrameView::FrameToScreen(const IntRect& rect) const {
- if (auto* client = ToChromeClient(GetChromeClient()))
+ if (auto* client = GetChromeClient())
return client->ViewportToScreen(FrameToViewport(rect), this);
return IntRect();
}
@@ -4132,7 +4213,7 @@ void LocalFrameView::BeginLifecycleUpdates() {
return;
lifecycle_updates_throttled_ = false;
if (auto* owner = GetFrame().OwnerLayoutObject())
- owner->SetMayNeedPaintInvalidation();
+ owner->SetShouldCheckForPaintInvalidation();
LayoutView* layout_view = GetLayoutView();
bool layout_view_is_empty = layout_view && !layout_view->FirstChild();
@@ -4174,8 +4255,8 @@ bool LocalFrameView::HasVisibleSlowRepaintViewportConstrainedObjects() const {
return false;
for (const LayoutObject* layout_object : *ViewportConstrainedObjects()) {
DCHECK(layout_object->IsBoxModelObject() && layout_object->HasLayer());
- DCHECK(layout_object->Style()->GetPosition() == EPosition::kFixed ||
- layout_object->Style()->GetPosition() == EPosition::kSticky);
+ DCHECK(layout_object->StyleRef().GetPosition() == EPosition::kFixed ||
+ layout_object->StyleRef().GetPosition() == EPosition::kSticky);
if (ToLayoutBoxModelObject(layout_object)->IsSlowRepaintConstrainedObject())
return true;
}
@@ -4245,7 +4326,7 @@ MainThreadScrollingReasons LocalFrameView::MainThreadScrollingReasonsPerFrame()
// smooth-scroll animations. For this reason, we use HasOverflow instead of
// ScrollsOverflow (which is false for overflow: hidden).
if (LayoutViewport()->HasOverflow() &&
- GetLayoutView()->Style()->VisibleToHitTesting() &&
+ GetLayoutView()->StyleRef().VisibleToHitTesting() &&
HasVisibleSlowRepaintViewportConstrainedObjects()) {
reasons |=
MainThreadScrollingReason::kHasNonLayerViewportConstrainedObjects;
@@ -4347,8 +4428,8 @@ UkmTimeAggregator& LocalFrameView::EnsureUkmTimeAggregator() {
frame_->GetDocument()->UkmRecorder(),
// Note that changing the order or values of the following vector
// requires changing the UkmMetricNames enum.
- {"Compositing", "IntersectionObservation", "Paint", "PrePaint",
- "StyleAndLayout"},
+ {"Compositing", "CompositingCommit", "IntersectionObservation", "Paint",
+ "PrePaint", "StyleAndLayout"},
TimeDelta::FromSeconds(30)));
}
return *ukm_time_aggregator_;
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 9e546708d7c..b8103714e46 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
@@ -41,8 +41,8 @@
#include "third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h"
#include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h"
#include "third_party/blink/renderer/core/paint/layout_object_counter.h"
+#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
#include "third_party/blink/renderer/platform/graphics/graphics_layer_client.h"
-#include "third_party/blink/renderer/platform/scroll/scrollable_area.h"
namespace blink {
@@ -56,7 +56,6 @@ class Frame;
class FloatSize;
class FrameViewAutoSizeInfo;
class IntRect;
-class JSONArray;
class JSONObject;
class LayoutEmbeddedContent;
class LocalFrame;
@@ -152,7 +151,11 @@ class CORE_EXPORT LocalFrameView final
bool HasOrthogonalWritingModeRoots() const;
void LayoutOrthogonalWritingModeRoots();
void ScheduleOrthogonalWritingModeRootsForLayout();
- int LayoutCount() const { return layout_count_; }
+
+ unsigned LayoutCountForTesting() const { return layout_count_for_testing_; }
+ unsigned LifecycleUpdateCountForTesting() const {
+ return lifecycle_update_count_for_testing_;
+ }
void CountObjectsNeedingLayout(unsigned& needs_layout_objects,
unsigned& total_objects,
@@ -386,7 +389,13 @@ class CORE_EXPORT LocalFrameView final
}
void TrackObjectPaintInvalidation(const DisplayItemClient&,
PaintInvalidationReason);
- std::unique_ptr<JSONArray> TrackedObjectPaintInvalidationsAsJSON() const;
+ struct ObjectPaintInvalidation {
+ String name;
+ PaintInvalidationReason reason;
+ };
+ Vector<ObjectPaintInvalidation>* TrackedObjectPaintInvalidations() const {
+ return tracked_object_paint_invalidations_.get();
+ }
using ScrollableAreaSet = HeapHashSet<Member<PaintLayerScrollableArea>>;
void AddScrollableArea(PaintLayerScrollableArea*);
@@ -420,7 +429,7 @@ class CORE_EXPORT LocalFrameView final
// The window that hosts the LocalFrameView. The LocalFrameView will
// communicate scrolls and repaints to the host window in the window's
// coordinate space.
- PlatformChromeClient* GetChromeClient() const;
+ ChromeClient* GetChromeClient() const;
// Functions for child manipulation and inspection.
bool IsSelfVisible() const {
@@ -618,7 +627,8 @@ class CORE_EXPORT LocalFrameView final
const WebScrollIntoViewParams&);
PaintArtifactCompositor* GetPaintArtifactCompositorForTesting() {
- DCHECK(RuntimeEnabledFeatures::SlimmingPaintV2Enabled());
+ DCHECK(RuntimeEnabledFeatures::SlimmingPaintV2Enabled() ||
+ RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled());
return paint_artifact_compositor_.get();
}
@@ -654,6 +664,34 @@ class CORE_EXPORT LocalFrameView final
void NotifyFrameRectsChangedIfNeeded();
private:
+#if DCHECK_IS_ON()
+ class DisallowLayoutInvalidationScope {
+ public:
+ DisallowLayoutInvalidationScope(LocalFrameView* view)
+ : local_frame_view_(view) {
+ local_frame_view_->allows_layout_invalidation_after_layout_clean_ = false;
+ local_frame_view_->ForAllChildLocalFrameViews(
+ [](LocalFrameView& frame_view) {
+ if (!frame_view.ShouldThrottleRendering())
+ frame_view.CheckDoesNotNeedLayout();
+ frame_view.allows_layout_invalidation_after_layout_clean_ = false;
+ });
+ }
+ ~DisallowLayoutInvalidationScope() {
+ local_frame_view_->allows_layout_invalidation_after_layout_clean_ = true;
+ local_frame_view_->ForAllChildLocalFrameViews(
+ [](LocalFrameView& frame_view) {
+ if (!frame_view.ShouldThrottleRendering())
+ frame_view.CheckDoesNotNeedLayout();
+ frame_view.allows_layout_invalidation_after_layout_clean_ = true;
+ });
+ }
+
+ private:
+ UntracedMember<LocalFrameView> local_frame_view_;
+ };
+#endif
+
explicit LocalFrameView(LocalFrame&, IntRect);
void PaintInternal(GraphicsContext&,
@@ -668,10 +706,24 @@ class CORE_EXPORT LocalFrameView final
void SetupPrintContext();
void ClearPrintContext();
- // Returns whethre the lifecycle was succesfully updated to the
+ // Returns whether the lifecycle was succesfully updated to the
// target state.
- bool UpdateLifecyclePhasesInternal(
+ bool UpdateLifecyclePhases(DocumentLifecycle::LifecycleState target_state);
+ // The internal version that does the work after the proper context and checks
+ // have passed in the above function call.
+ void UpdateLifecyclePhasesInternal(
+ DocumentLifecycle::LifecycleState target_state);
+ // Four lifecycle phases helper functions corresponding to StyleAndLayout,
+ // Compositing, PrePaint, and Paint phases. If the return value is true, it
+ // means further lifecycle phases need to be run. This is used to abort
+ // earlier if we don't need to run future lifecycle phases.
+ bool RunStyleAndLayoutLifecyclePhases(
DocumentLifecycle::LifecycleState target_state);
+ bool RunCompositingLifecyclePhase(
+ DocumentLifecycle::LifecycleState target_state);
+ bool RunPrePaintLifecyclePhase(
+ DocumentLifecycle::LifecycleState target_state);
+ void RunPaintLifecyclePhase();
void NotifyFrameRectsChangedIfNeededRecursive();
void UpdateStyleAndLayoutIfNeededRecursive();
@@ -786,7 +838,8 @@ class CORE_EXPORT LocalFrameView final
bool layout_scheduling_enabled_;
bool in_synchronous_post_layout_;
- int layout_count_;
+ unsigned layout_count_for_testing_;
+ unsigned lifecycle_update_count_for_testing_;
unsigned nested_layout_count_;
TaskRunnerTimer<LocalFrameView> post_layout_tasks_timer_;
TaskRunnerTimer<LocalFrameView> update_plugins_timer_;
@@ -866,8 +919,11 @@ class CORE_EXPORT LocalFrameView final
AnchoringAdjustmentQueue anchoring_adjustment_queue_;
bool suppress_adjust_view_size_;
- bool allows_layout_invalidation_after_layout_clean_;
-
+#if DCHECK_IS_ON()
+ // In DCHECK on builds, this is set to false when we're running lifecycle
+ // phases past layout to ensure that phases after layout don't dirty layout.
+ bool allows_layout_invalidation_after_layout_clean_ = true;
+#endif
IntersectionObservationState intersection_observation_state_;
bool needs_forced_compositing_update_;
@@ -881,10 +937,6 @@ class CORE_EXPORT LocalFrameView final
mutable std::unique_ptr<ScrollingCoordinatorContext> scrolling_context_;
// For testing.
- struct ObjectPaintInvalidation {
- String name;
- PaintInvalidationReason reason;
- };
std::unique_ptr<Vector<ObjectPaintInvalidation>>
tracked_object_paint_invalidations_;
@@ -932,6 +984,20 @@ inline void LocalFrameView::IncrementVisuallyNonEmptyPixelCount(
SetIsVisuallyNonEmpty();
}
+inline bool operator==(const LocalFrameView::ObjectPaintInvalidation& a,
+ const LocalFrameView::ObjectPaintInvalidation& b) {
+ return a.name == b.name && a.reason == b.reason;
+}
+inline bool operator!=(const LocalFrameView::ObjectPaintInvalidation& a,
+ const LocalFrameView::ObjectPaintInvalidation& b) {
+ return !(a == b);
+}
+inline std::ostream& operator<<(
+ std::ostream& os,
+ const LocalFrameView::ObjectPaintInvalidation& info) {
+ return os << info.name << " reason=" << info.reason;
+}
+
DEFINE_TYPE_CASTS(LocalFrameView,
EmbeddedContentView,
embedded_content_view,
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 5bda833fcbc..24d0f3390e7 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/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"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
@@ -18,7 +19,9 @@
#include "third_party/blink/renderer/platform/geometry/int_size.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_artifact.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
+using blink::test::RunPendingTasks;
using testing::_;
using testing::AnyNumber;
@@ -265,5 +268,64 @@ TEST_F(LocalFrameViewSimTest, CSSFragmentIdentifierEmptySelector) {
EXPECT_EQ(nullptr, GetDocument().CssTarget());
}
+// Ensure the fragment navigation "scroll into view and focus" behavior doesn't
+// activate synchronously while rendering is blocked waiting on a stylesheet.
+// See https://crbug.com/851338.
+TEST_F(LocalFrameViewSimTest, FragmentNavChangesFocusWhileRenderingBlocked) {
+ SimRequest main_resource("https://example.com/test.html", "text/html");
+ SimRequest css_resource("https://example.com/sheet.css", "text/css");
+ LoadURL("https://example.com/test.html");
+
+ main_resource.Complete(R"HTML(
+ <!DOCTYPE html>
+ <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>
+ <input id="bottom">Bottom of the page</a>
+ )HTML");
+
+ ScrollableArea* viewport = GetDocument().View()->LayoutViewport();
+ ASSERT_EQ(ScrollOffset(), viewport->GetScrollOffset());
+
+ // We're still waiting on the stylesheet to load so the load event shouldn't
+ // yet dispatch and rendering is deferred.
+ ASSERT_FALSE(GetDocument().IsRenderingReady());
+ EXPECT_FALSE(GetDocument().IsLoadCompleted());
+
+ // Click on the anchor element. This will cause a synchronous same-document
+ // navigation.
+ HTMLAnchorElement* anchor =
+ ToHTMLAnchorElement(GetDocument().getElementById("anchorlink"));
+ anchor->click();
+
+ // Even though the navigation is synchronous, the active element shouldn't be
+ // changed.
+ EXPECT_EQ(GetDocument().body(), GetDocument().ActiveElement())
+ << "Active element changed while rendering is blocked";
+ EXPECT_EQ(ScrollOffset(), viewport->GetScrollOffset())
+ << "Scroll offset changed while rendering is blocked";
+
+ // Force a layout.
+ anchor->style()->setProperty(&GetDocument(), "display", "block", String(),
+ ASSERT_NO_EXCEPTION);
+ GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+
+ EXPECT_EQ(GetDocument().body(), GetDocument().ActiveElement())
+ << "Active element changed due to layout while rendering is blocked";
+ EXPECT_EQ(ScrollOffset(), viewport->GetScrollOffset())
+ << "Scroll offset changed due to layout while rendering is blocked";
+
+ // Complete the CSS stylesheet load so the document can finish loading. The
+ // fragment should be activated at that point.
+ css_resource.Complete("");
+ RunPendingTasks();
+ ASSERT_TRUE(GetDocument().IsLoadCompleted());
+ EXPECT_EQ(GetDocument().getElementById("bottom"),
+ GetDocument().ActiveElement())
+ << "Active element wasn't changed after load completed.";
+ EXPECT_NE(ScrollOffset(), viewport->GetScrollOffset())
+ << "Scroll offset wasn't changed after load completed.";
+}
+
} // namespace
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/location.cc b/chromium/third_party/blink/renderer/core/frame/location.cc
index 588a7d65dbf..08b34cd8278 100644
--- a/chromium/third_party/blink/renderer/core/frame/location.cc
+++ b/chromium/third_party/blink/renderer/core/frame/location.cc
@@ -121,20 +121,11 @@ void Location::setHref(LocalDOMWindow* current_window,
LocalDOMWindow* entered_window,
const USVStringOrTrustedURL& stringOrUrl,
ExceptionState& exception_state) {
- DCHECK(stringOrUrl.IsUSVString() ||
- RuntimeEnabledFeatures::TrustedDOMTypesEnabled());
-
- if (stringOrUrl.IsUSVString() &&
- current_window->document()->RequireTrustedTypes()) {
- exception_state.ThrowTypeError(
- "This document requires `TrustedURL` assignment.");
- return;
+ String url = TrustedURL::GetString(stringOrUrl, current_window->document(),
+ exception_state);
+ if (!exception_state.HadException()) {
+ SetLocation(url, current_window, entered_window, &exception_state);
}
-
- String url = stringOrUrl.IsUSVString()
- ? stringOrUrl.GetAsUSVString()
- : stringOrUrl.GetAsTrustedURL()->toString();
- SetLocation(url, current_window, entered_window, &exception_state);
}
void Location::setProtocol(LocalDOMWindow* current_window,
@@ -233,45 +224,23 @@ void Location::assign(LocalDOMWindow* current_window,
return;
}
- DCHECK(stringOrUrl.IsUSVString() ||
- RuntimeEnabledFeatures::TrustedDOMTypesEnabled());
- DCHECK(!stringOrUrl.IsNull());
-
- if (stringOrUrl.IsUSVString() &&
- current_window->document()->RequireTrustedTypes()) {
- exception_state.ThrowTypeError(
- "This document requires `TrustedURL` assignment.");
- return;
+ String url = TrustedURL::GetString(stringOrUrl, current_window->document(),
+ exception_state);
+ if (!exception_state.HadException()) {
+ SetLocation(url, current_window, entered_window, &exception_state);
}
-
- String url = stringOrUrl.IsUSVString()
- ? stringOrUrl.GetAsUSVString()
- : stringOrUrl.GetAsTrustedURL()->toString();
-
- SetLocation(url, current_window, entered_window, &exception_state);
}
void Location::replace(LocalDOMWindow* current_window,
LocalDOMWindow* entered_window,
const USVStringOrTrustedURL& stringOrUrl,
ExceptionState& exception_state) {
- DCHECK(stringOrUrl.IsUSVString() ||
- RuntimeEnabledFeatures::TrustedDOMTypesEnabled());
- DCHECK(!stringOrUrl.IsNull());
-
- if (stringOrUrl.IsUSVString() &&
- current_window->document()->RequireTrustedTypes()) {
- exception_state.ThrowTypeError(
- "This document requires `TrustedURL` assignment.");
- return;
+ String url = TrustedURL::GetString(stringOrUrl, current_window->document(),
+ exception_state);
+ if (!exception_state.HadException()) {
+ SetLocation(url, current_window, entered_window, &exception_state,
+ SetLocationPolicy::kReplaceThisFrame);
}
-
- String url = stringOrUrl.IsUSVString()
- ? stringOrUrl.GetAsUSVString()
- : stringOrUrl.GetAsTrustedURL()->toString();
-
- SetLocation(url, current_window, entered_window, &exception_state,
- SetLocationPolicy::kReplaceThisFrame);
}
void Location::reload(LocalDOMWindow* current_window) {
@@ -279,8 +248,12 @@ void Location::reload(LocalDOMWindow* current_window) {
return;
if (GetDocument()->Url().ProtocolIsJavaScript())
return;
- dom_window_->GetFrame()->Reload(WebFrameLoadType::kReload,
- ClientRedirectPolicy::kClientRedirect);
+ // reload() is not cross-origin accessible, so |dom_window_| will always be
+ // local.
+ ToLocalDOMWindow(dom_window_)
+ ->GetFrame()
+ ->Reload(WebFrameLoadType::kReload,
+ ClientRedirectPolicy::kClientRedirect);
}
void Location::SetLocation(const String& url,
diff --git a/chromium/third_party/blink/renderer/core/frame/location.idl b/chromium/third_party/blink/renderer/core/frame/location.idl
index 575131be33d..59d42cedfe6 100644
--- a/chromium/third_party/blink/renderer/core/frame/location.idl
+++ b/chromium/third_party/blink/renderer/core/frame/location.idl
@@ -30,7 +30,7 @@
[
CheckSecurity=Receiver,
- Unforgeable
+ Exposed=Window
] interface Location {
// |assign| is *NOT* cross-origin accessible in the spec, but it needs
// the Incumbent realm when navigating the page. See the below link.
@@ -41,7 +41,7 @@
// |assign| itself is not cross-origin accessible.
// TODO(yukishiino): Remove [CrossOrigin] once we support the Incumbent
// realm correctly.
- [CallWith=(CurrentWindow,EnteredWindow), CrossOrigin, RaisesException] void assign(URLString url);
+ [CallWith=(CurrentWindow,EnteredWindow), CrossOrigin, RaisesException, Unforgeable] void assign(URLString url);
// |replace|, and *writing* |href| do not require a security check, as they
// *change* the page, and thus these do not change any property of an
@@ -49,26 +49,26 @@
// However, *reading* |href|, or accessing any component, is a security
// problem, since that allows tracking navigation.
// https://html.spec.whatwg.org/multipage/browsers.html#crossoriginproperties-(-o-)
- [CallWith=(CurrentWindow,EnteredWindow), CrossOrigin, RaisesException] void replace(URLString url);
- [CallWith=CurrentWindow] void reload();
+ [CallWith=(CurrentWindow,EnteredWindow), CrossOrigin, RaisesException, Unforgeable] void replace(URLString url);
+ [CallWith=CurrentWindow, Unforgeable] void reload();
// TODO(foolip): |ancestorOrigins| should have [Unforgeable, SameObject].
- readonly attribute DOMStringList ancestorOrigins;
+ [Unforgeable] readonly attribute DOMStringList ancestorOrigins;
- [Affects=Nothing, SetterCallWith=(CurrentWindow,EnteredWindow), CrossOrigin=Setter, RaisesException=Setter] attribute URLString href;
+ [Affects=Nothing, SetterCallWith=(CurrentWindow,EnteredWindow), CrossOrigin=Setter, RaisesException=Setter, Unforgeable] attribute URLString href;
// TODO(yukishiino): Use [Unforgeable] stringifier instead of toString.
- DOMString toString();
- [MeasureAs=LocationOrigin] readonly attribute USVString origin;
+ [Unforgeable] DOMString toString();
+ [MeasureAs=LocationOrigin, Unforgeable] readonly attribute USVString origin;
- [SetterCallWith=(CurrentWindow,EnteredWindow), RaisesException=Setter] attribute USVString protocol;
- [SetterCallWith=(CurrentWindow,EnteredWindow), RaisesException=Setter] attribute USVString host;
- [SetterCallWith=(CurrentWindow,EnteredWindow), RaisesException=Setter] attribute USVString hostname;
- [SetterCallWith=(CurrentWindow,EnteredWindow), RaisesException=Setter] attribute USVString port;
- [SetterCallWith=(CurrentWindow,EnteredWindow), RaisesException=Setter] attribute USVString pathname;
- [SetterCallWith=(CurrentWindow,EnteredWindow), RaisesException=Setter] attribute USVString search;
- [SetterCallWith=(CurrentWindow,EnteredWindow), RaisesException=Setter] attribute USVString hash;
+ [SetterCallWith=(CurrentWindow,EnteredWindow), RaisesException=Setter, Unforgeable] attribute USVString protocol;
+ [SetterCallWith=(CurrentWindow,EnteredWindow), RaisesException=Setter, Unforgeable] attribute USVString host;
+ [SetterCallWith=(CurrentWindow,EnteredWindow), RaisesException=Setter, Unforgeable] attribute USVString hostname;
+ [SetterCallWith=(CurrentWindow,EnteredWindow), RaisesException=Setter, Unforgeable] attribute USVString port;
+ [SetterCallWith=(CurrentWindow,EnteredWindow), RaisesException=Setter, Unforgeable] attribute USVString pathname;
+ [SetterCallWith=(CurrentWindow,EnteredWindow), RaisesException=Setter, Unforgeable] attribute USVString search;
+ [SetterCallWith=(CurrentWindow,EnteredWindow), RaisesException=Setter, Unforgeable] attribute USVString hash;
// 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] any valueOf();
+ [NotEnumerable, CallWith=ThisValue, Unforgeable] any valueOf();
};
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 7601d88283c..cba070e9822 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
@@ -39,6 +39,7 @@
#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/frame/frame_test_helpers.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/location.h"
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
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 8d23e6cbf86..2c7b3a5e528 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
@@ -36,7 +36,7 @@ void NavigatorUserActivation::Trace(blink::Visitor* visitor) {
}
NavigatorUserActivation::NavigatorUserActivation(Navigator& navigator) {
- user_activation_ = new UserActivation(navigator.DomWindow());
+ user_activation_ = UserActivation::CreateLive(navigator.DomWindow());
}
} // namespace blink
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 1780b5ac8b3..d483fca0a80 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
@@ -31,18 +31,26 @@
#include "third_party/blink/renderer/core/frame/page_scale_constraints_set.h"
#include <algorithm>
+#include "third_party/blink/renderer/core/frame/settings.h"
+#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/platform/length.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
namespace blink {
-PageScaleConstraintsSet::PageScaleConstraintsSet()
+PageScaleConstraintsSet::PageScaleConstraintsSet(Page* page)
: default_constraints_(-1, 1, 1),
final_constraints_(ComputeConstraintsStack()),
+ page_(page),
last_contents_width_(0),
+ last_vertical_scrollbar_width_(0),
needs_reset_(false),
constraints_dirty_(false) {}
+void PageScaleConstraintsSet::Trace(blink::Visitor* visitor) {
+ visitor->Trace(page_);
+}
+
void PageScaleConstraintsSet::SetDefaultConstraints(
const PageScaleConstraints& default_constraints) {
default_constraints_ = default_constraints;
@@ -90,17 +98,16 @@ PageScaleConstraints PageScaleConstraintsSet::ComputeConstraintsStack() const {
void PageScaleConstraintsSet::ComputeFinalConstraints() {
final_constraints_ = ComputeConstraintsStack();
-
+ AdjustFinalConstraintsToContentsSize();
constraints_dirty_ = false;
}
-void PageScaleConstraintsSet::AdjustFinalConstraintsToContentsSize(
- IntSize contents_size,
- int non_overlay_scrollbar_width,
- bool shrinks_viewport_content_to_fit) {
- if (shrinks_viewport_content_to_fit)
+void PageScaleConstraintsSet::AdjustFinalConstraintsToContentsSize() {
+ if (page_->GetSettings().GetShrinksViewportContentToFit()) {
final_constraints_.FitToContentsWidth(
- contents_size.Width(), icb_size_.Width() - non_overlay_scrollbar_width);
+ last_contents_width_,
+ icb_size_.Width() - last_vertical_scrollbar_width_);
+ }
final_constraints_.ResolveAutoInitialScale();
}
@@ -111,8 +118,10 @@ void PageScaleConstraintsSet::SetNeedsReset(bool needs_reset) {
constraints_dirty_ = true;
}
-void PageScaleConstraintsSet::DidChangeContentsSize(IntSize contents_size,
- float page_scale_factor) {
+void PageScaleConstraintsSet::DidChangeContentsSize(
+ IntSize contents_size,
+ int vertical_scrollbar_width,
+ float page_scale_factor) {
// If a large fixed-width element expanded the size of the document late in
// loading and our initial scale is not set (or set to be less than the last
// minimum scale), reset the page scale factor to the new initial scale.
@@ -123,6 +132,7 @@ void PageScaleConstraintsSet::DidChangeContentsSize(IntSize contents_size,
SetNeedsReset(true);
constraints_dirty_ = true;
+ last_vertical_scrollbar_width_ = vertical_scrollbar_width;
last_contents_width_ = contents_size.Width();
}
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 18a97c96b27..57c85d2b657 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
@@ -38,21 +38,25 @@
#include "third_party/blink/renderer/core/frame/page_scale_constraints.h"
#include "third_party/blink/renderer/core/page/viewport_description.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/length.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
namespace blink {
+class Page;
+
// This class harmonizes the viewport (particularly page scale) constraints from
// the meta viewport tag and other sources.
-class CORE_EXPORT PageScaleConstraintsSet {
- USING_FAST_MALLOC(PageScaleConstraintsSet);
-
+class CORE_EXPORT PageScaleConstraintsSet
+ : public GarbageCollected<PageScaleConstraintsSet> {
public:
- static std::unique_ptr<PageScaleConstraintsSet> Create() {
- return base::WrapUnique(new PageScaleConstraintsSet);
+ static PageScaleConstraintsSet* Create(Page* page) {
+ return new PageScaleConstraintsSet(page);
}
+ void Trace(blink::Visitor*);
+
void SetDefaultConstraints(const PageScaleConstraints&);
const PageScaleConstraints& DefaultConstraints() const;
@@ -91,12 +95,9 @@ class CORE_EXPORT PageScaleConstraintsSet {
return final_constraints_;
}
void ComputeFinalConstraints();
- void AdjustFinalConstraintsToContentsSize(
- IntSize contents_size,
- int non_overlay_scrollbar_width,
- bool shrinks_viewport_content_to_fit);
-
- void DidChangeContentsSize(IntSize contents_size, float page_scale_factor);
+ void DidChangeContentsSize(IntSize contents_size,
+ int vertical_scrollbar_width,
+ float page_scale_factor);
// This should be set to true on each page load to note that the page scale
// factor needs to be reset to its initial value.
@@ -112,17 +113,22 @@ class CORE_EXPORT PageScaleConstraintsSet {
IntSize InitialViewportSize() const { return icb_size_; }
private:
- PageScaleConstraintsSet();
+ PageScaleConstraintsSet(Page* page);
PageScaleConstraints ComputeConstraintsStack() const;
+ void AdjustFinalConstraintsToContentsSize();
+
PageScaleConstraints default_constraints_;
PageScaleConstraints page_defined_constraints_;
PageScaleConstraints user_agent_constraints_;
PageScaleConstraints fullscreen_constraints_;
PageScaleConstraints final_constraints_;
+ Member<Page> page_;
+
int last_contents_width_;
+ int last_vertical_scrollbar_width_;
IntSize icb_size_;
bool needs_reset_;
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 62e763460ee..481b0db8515 100644
--- a/chromium/third_party/blink/renderer/core/frame/performance_monitor.cc
+++ b/chromium/third_party/blink/renderer/core/frame/performance_monitor.cc
@@ -208,7 +208,7 @@ void PerformanceMonitor::Did(const probe::ExecuteScript& probe) {
if (probe.Duration() <= kLongTaskSubTaskThreshold)
return;
std::unique_ptr<SubTaskAttribution> sub_task_attribution =
- SubTaskAttribution::Create(String("script-run"),
+ SubTaskAttribution::Create(AtomicString("script-run"),
probe.context->Url().GetString(),
probe.CaptureStartTime(), probe.Duration());
sub_task_attributions_.push_back(std::move(sub_task_attribution));
@@ -266,7 +266,7 @@ void PerformanceMonitor::Did(const probe::V8Compile& probe) {
std::unique_ptr<SubTaskAttribution> sub_task_attribution =
SubTaskAttribution::Create(
- String("script-compile"),
+ AtomicString("script-compile"),
String::Format("%s(%d, %d)", probe.file_name.Utf8().data(),
probe.line, probe.column),
v8_compile_start_time_, v8_compile_duration);
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 92dfb88ac49..cc2da5ddb10 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
@@ -13,6 +13,7 @@ namespace blink {
class HTMLVideoElement;
class ScriptPromiseResolver;
+struct PictureInPictureControlInfo;
// PictureInPictureController allows to know if Picture-in-Picture is allowed
// for a video element in Blink outside of modules/ module. It
@@ -41,6 +42,7 @@ class CORE_EXPORT PictureInPictureController
kDisabledBySystem,
kDisabledByFeaturePolicy,
kDisabledByAttribute,
+ kMediaStreamsNotSupportedYet,
};
// Enter Picture-in-Picture for a video element and resolve promise if any.
@@ -64,6 +66,11 @@ class CORE_EXPORT PictureInPictureController
virtual void OnPictureInPictureControlClicked(
const WebString& control_id) = 0;
+ // Assign custom controls to be added to the Picture-in-Picture window.
+ virtual void SetPictureInPictureCustomControls(
+ HTMLVideoElement*,
+ const std::vector<PictureInPictureControlInfo>&) = 0;
+
// Returns whether the given element is currently in Picture-in-Picture.
virtual bool IsPictureInPictureElement(const Element*) const = 0;
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 2e0021740a8..81daa624014 100644
--- a/chromium/third_party/blink/renderer/core/frame/remote_frame.cc
+++ b/chromium/third_party/blink/renderer/core/frame/remote_frame.cc
@@ -84,11 +84,6 @@ void RemoteFrame::Navigate(const FrameLoadRequest& passed_request) {
frame_request.GetBlobURLToken());
}
-void RemoteFrame::Reload(WebFrameLoadType frame_load_type,
- ClientRedirectPolicy client_redirect_policy) {
- Client()->Reload(frame_load_type, client_redirect_policy);
-}
-
void RemoteFrame::Detach(FrameDetachType type) {
lifecycle_.AdvanceTo(FrameLifecycle::kDetaching);
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 76238a41200..b6160560b72 100644
--- a/chromium/third_party/blink/renderer/core/frame/remote_frame.h
+++ b/chromium/third_party/blink/renderer/core/frame/remote_frame.h
@@ -34,7 +34,6 @@ class CORE_EXPORT RemoteFrame final : public Frame {
bool replace_current_item,
UserGestureStatus) override;
void Navigate(const FrameLoadRequest& passed_request) override;
- void Reload(WebFrameLoadType, ClientRedirectPolicy) override;
void Detach(FrameDetachType) override;
RemoteSecurityContext* GetSecurityContext() const override;
bool PrepareForCommit() override;
diff --git a/chromium/third_party/blink/renderer/core/frame/remote_frame_client.h b/chromium/third_party/blink/renderer/core/frame/remote_frame_client.h
index f578bbfdd7d..faf6c60739f 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
@@ -31,7 +31,6 @@ class RemoteFrameClient : public FrameClient {
virtual void Navigate(const ResourceRequest&,
bool should_replace_current_entry,
mojom::blink::BlobURLTokenPtr) = 0;
- virtual void Reload(WebFrameLoadType, ClientRedirectPolicy) = 0;
unsigned BackForwardLength() override = 0;
// Notifies the remote frame to check whether it is done loading, after one
@@ -52,7 +51,8 @@ class RemoteFrameClient : public FrameClient {
const IntRect& screen_space_rect) = 0;
virtual void UpdateRemoteViewportIntersection(
- const IntRect& viewport_intersection) = 0;
+ const IntRect& viewport_intersection,
+ bool occluded_or_obscured) = 0;
virtual void AdvanceFocus(WebFocusType, LocalFrame* source) = 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 25d988f493e..b60c1a4d3d9 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
@@ -119,15 +119,6 @@ void RemoteFrameClientImpl::Navigate(
}
}
-void RemoteFrameClientImpl::Reload(
- WebFrameLoadType load_type,
- ClientRedirectPolicy client_redirect_policy) {
- DCHECK(IsReloadLoadType(load_type));
- if (web_frame_->Client()) {
- web_frame_->Client()->Reload(load_type, client_redirect_policy);
- }
-}
-
unsigned RemoteFrameClientImpl::BackForwardLength() {
// TODO(creis,japhet): This method should return the real value for the
// session history length. For now, return static value for the initial
@@ -160,8 +151,10 @@ void RemoteFrameClientImpl::FrameRectsChanged(
}
void RemoteFrameClientImpl::UpdateRemoteViewportIntersection(
- const IntRect& viewport_intersection) {
- web_frame_->Client()->UpdateRemoteViewportIntersection(viewport_intersection);
+ const IntRect& viewport_intersection,
+ bool occluded_or_obscured) {
+ web_frame_->Client()->UpdateRemoteViewportIntersection(viewport_intersection,
+ occluded_or_obscured);
}
void RemoteFrameClientImpl::AdvanceFocus(WebFocusType type,
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 0e9871705b3..fa9ad8cb017 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
@@ -36,7 +36,6 @@ class RemoteFrameClientImpl final : public RemoteFrameClient {
void Navigate(const ResourceRequest&,
bool should_replace_current_entry,
mojom::blink::BlobURLTokenPtr) override;
- void Reload(WebFrameLoadType, ClientRedirectPolicy) override;
unsigned BackForwardLength() override;
void CheckCompleted() override;
void ForwardPostMessage(MessageEvent*,
@@ -45,7 +44,7 @@ class RemoteFrameClientImpl final : public RemoteFrameClient {
bool has_user_gesture) const override;
void FrameRectsChanged(const IntRect& local_frame_rect,
const IntRect& screen_space_rect) override;
- void UpdateRemoteViewportIntersection(const IntRect&) override;
+ void UpdateRemoteViewportIntersection(const IntRect&, bool) override;
void AdvanceFocus(WebFocusType, LocalFrame*) override;
void VisibilityChanged(bool visible) override;
void SetIsInert(bool) override;
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 47f1be02f65..3551d79e1df 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
@@ -64,7 +64,8 @@ RemoteFrameView* RemoteFrameView::Create(RemoteFrame* remote_frame) {
}
void RemoteFrameView::UpdateViewportIntersectionsForSubtree() {
- if (!remote_frame_->OwnerLayoutObject())
+ LayoutEmbeddedContent* owner = remote_frame_->OwnerLayoutObject();
+ if (!owner)
return;
LocalFrameView* local_root_view =
@@ -72,41 +73,69 @@ void RemoteFrameView::UpdateViewportIntersectionsForSubtree() {
if (!local_root_view)
return;
- // Start with rect in remote frame's coordinate space. Then
- // mapToVisualRectInAncestorSpace will move it to the local root's coordinate
- // space and account for any clip from containing elements such as a
- // scrollable div. Passing nullptr as an argument to
- // mapToVisualRectInAncestorSpace causes it to be clipped to the viewport,
- // even if there are RemoteFrame ancestors in the frame tree.
- LayoutRect rect(0, 0, frame_rect_.Width(), frame_rect_.Height());
- rect.Move(remote_frame_->OwnerLayoutObject()->ContentBoxOffset());
IntRect viewport_intersection;
- if (remote_frame_->OwnerLayoutObject()->MapToVisualRectInAncestorSpace(
- nullptr, rect, kUseGeometryMapper)) {
- IntRect root_visible_rect(IntPoint(), local_root_view->Size());
- IntRect intersected_rect = EnclosingIntRect(rect);
- intersected_rect.Intersect(root_visible_rect);
-
- // Translate the intersection rect from the root frame's coordinate space
- // to the remote frame's coordinate space.
- FloatRect viewport_intersection_float =
- remote_frame_->OwnerLayoutObject()
- ->AncestorToLocalQuad(local_root_view->GetLayoutView(),
- FloatQuad(intersected_rect),
- kTraverseDocumentBoundaries | kUseTransforms)
- .BoundingBox();
- viewport_intersection_float.Move(
- -remote_frame_->OwnerLayoutObject()->ContentBoxOffset());
- viewport_intersection = EnclosingIntRect(viewport_intersection_float);
+ bool occluded_or_obscured = false;
+ DocumentLifecycle::LifecycleState parent_state =
+ owner->GetDocument().Lifecycle().GetState();
+
+ // If the parent LocalFrameView is throttled and out-of-date, then we can't
+ // get any useful information.
+ if (parent_state >= DocumentLifecycle::kLayoutClean) {
+ // Start with rect in remote frame's coordinate space. Then
+ // mapToVisualRectInAncestorSpace will move it to the local root's
+ // coordinate space and account for any clip from containing elements such
+ // as a scrollable div. Passing nullptr as an argument to
+ // mapToVisualRectInAncestorSpace causes it to be clipped to the viewport,
+ // even if there are RemoteFrame ancestors in the frame tree.
+ LayoutRect rect(0, 0, frame_rect_.Width(), frame_rect_.Height());
+ rect.Move(owner->PhysicalContentBoxOffset());
+ if (owner->MapToVisualRectInAncestorSpace(nullptr, rect,
+ kUseGeometryMapper)) {
+ IntRect root_visible_rect(IntPoint(), local_root_view->Size());
+ IntRect intersected_rect = EnclosingIntRect(rect);
+ intersected_rect.Intersect(root_visible_rect);
+
+ // Translate the intersection rect from the root frame's coordinate space
+ // to the remote frame's coordinate space.
+ FloatRect viewport_intersection_float =
+ remote_frame_->OwnerLayoutObject()
+ ->AncestorToLocalQuad(
+ local_root_view->GetLayoutView(), FloatQuad(intersected_rect),
+ kTraverseDocumentBoundaries | kUseTransforms)
+ .BoundingBox();
+ viewport_intersection_float.Move(
+ -remote_frame_->OwnerLayoutObject()->PhysicalContentBoxOffset());
+ viewport_intersection = EnclosingIntRect(viewport_intersection_float);
+ }
+ }
+
+ if (parent_state >= DocumentLifecycle::kPrePaintClean &&
+ RuntimeEnabledFeatures::IntersectionObserverV2Enabled()) {
+ // TODO(layout-dev): As an optimization, we should only check for
+ // occlusion and effects if the remote frame needs it, i.e., if it has at
+ // least one active IntersectionObserver with trackVisibility:true.
+ if (owner->GetDocument()
+ .GetFrame()
+ ->LocalFrameRoot()
+ .MayBeOccludedOrObscuredByRemoteAncestor() ||
+ owner->HasDistortingVisualEffects()) {
+ occluded_or_obscured = true;
+ } else {
+ HitTestResult result(owner->HitTestForOcclusion());
+ occluded_or_obscured =
+ result.InnerNode() && result.InnerNode() != owner->GetNode();
+ }
}
- if (viewport_intersection == last_viewport_intersection_)
+ if (viewport_intersection == last_viewport_intersection_ &&
+ occluded_or_obscured == last_occluded_or_obscured_) {
return;
+ }
- // TODO(szager): Propagate occlusion information.
last_viewport_intersection_ = viewport_intersection;
+ last_occluded_or_obscured_ = occluded_or_obscured;
remote_frame_->Client()->UpdateRemoteViewportIntersection(
- viewport_intersection);
+ viewport_intersection, occluded_or_obscured);
}
IntRect RemoteFrameView::GetCompositingRect() {
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 25b94e7eaf5..a9732e5b85e 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
@@ -88,6 +88,7 @@ class RemoteFrameView final : public GarbageCollectedFinalized<RemoteFrameView>,
Member<RemoteFrame> remote_frame_;
bool is_attached_;
IntRect last_viewport_intersection_;
+ bool last_occluded_or_obscured_ = false;
IntRect frame_rect_;
bool self_visible_;
bool parent_visible_;
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 b8c6458145d..aac718d505e 100644
--- a/chromium/third_party/blink/renderer/core/frame/reporting_context.cc
+++ b/chromium/third_party/blink/renderer/core/frame/reporting_context.cc
@@ -9,6 +9,7 @@
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/report.h"
#include "third_party/blink/renderer/core/frame/reporting_observer.h"
+#include "third_party/blink/renderer/core/frame/use_counter.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
namespace blink {
@@ -31,10 +32,11 @@ ReportingContext* ReportingContext::From(ExecutionContext* context) {
}
void ReportingContext::QueueReport(Report* report) {
+ CountReport(report);
report_buffer_.insert(report);
// Only the most recent 100 reports will remain buffered.
- // https://wicg.github.io/reporting/#notify-observers
+ // https://w3c.github.io/reporting/#notify-observers
if (report_buffer_.size() > 100)
report_buffer_.RemoveFirst();
@@ -42,7 +44,26 @@ void ReportingContext::QueueReport(Report* report) {
observer->QueueReport(report);
}
+void ReportingContext::CountReport(Report* report) {
+ const String& type = report->type();
+ WebFeature feature;
+
+ if (type == "deprecation") {
+ feature = WebFeature::kDeprecationReport;
+ } else if (type == "feature-policy") {
+ feature = WebFeature::kFeaturePolicyReport;
+ } else if (type == "intervention") {
+ feature = WebFeature::kInterventionReport;
+ } else {
+ return;
+ }
+
+ UseCounter::Count(execution_context_, feature);
+}
+
void ReportingContext::RegisterObserver(ReportingObserver* observer) {
+ UseCounter::Count(execution_context_, WebFeature::kReportingObserver);
+
observers_.insert(observer);
if (!observer->Buffered())
return;
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 f75fbdef812..c60b9d776d6 100644
--- a/chromium/third_party/blink/renderer/core/frame/reporting_context.h
+++ b/chromium/third_party/blink/renderer/core/frame/reporting_context.h
@@ -33,6 +33,9 @@ class CORE_EXPORT ReportingContext final
// Queues a report in all registered observers.
void QueueReport(Report*);
+ // Counts the use of a report type via UseCounter.
+ void CountReport(Report*);
+
void RegisterObserver(ReportingObserver*);
void UnregisterObserver(ReportingObserver*);
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 3dc134c59cc..7292b061d18 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
@@ -9,12 +9,12 @@
#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"
+#include "third_party/blink/renderer/core/scroll/scroll_animator_base.h"
+#include "third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.h"
#include "third_party/blink/renderer/platform/geometry/double_rect.h"
#include "third_party/blink/renderer/platform/geometry/float_rect.h"
#include "third_party/blink/renderer/platform/geometry/layout_rect.h"
#include "third_party/blink/renderer/platform/scroll/scroll_alignment.h"
-#include "third_party/blink/renderer/platform/scroll/scroll_animator_base.h"
-#include "third_party/blink/renderer/platform/scroll/smooth_scroll_sequencer.h"
namespace blink {
namespace {
@@ -297,9 +297,9 @@ LayoutRect RootFrameViewport::ScrollIntoView(
if (params.is_for_scroll_sequence) {
DCHECK(params.GetScrollType() == kProgrammaticScroll ||
params.GetScrollType() == kUserScroll);
- ScrollBehavior behavior =
- DetermineScrollBehavior(params.GetScrollBehavior(),
- GetLayoutBox()->Style()->GetScrollBehavior());
+ ScrollBehavior behavior = DetermineScrollBehavior(
+ params.GetScrollBehavior(),
+ GetLayoutBox()->StyleRef().GetScrollBehavior());
GetSmoothScrollSequencer()->QueueAnimation(this, new_scroll_offset,
behavior);
} else {
@@ -532,7 +532,7 @@ CompositorElementId RootFrameViewport::GetScrollbarElementId(
: LayoutViewport().GetScrollbarElementId(orientation);
}
-PlatformChromeClient* RootFrameViewport::GetChromeClient() const {
+ChromeClient* RootFrameViewport::GetChromeClient() const {
return LayoutViewport().GetChromeClient();
}
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 6dd97704a05..d9c8fe851c0 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
@@ -7,7 +7,7 @@
#include "base/single_thread_task_runner.h"
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/platform/scroll/scrollable_area.h"
+#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
namespace blink {
@@ -106,7 +106,7 @@ class CORE_EXPORT RootFrameViewport final
CompositorElementId GetScrollbarElementId(
ScrollbarOrientation orientation) override;
bool ScrollAnimatorEnabled() const override;
- PlatformChromeClient* GetChromeClient() const override;
+ ChromeClient* GetChromeClient() const override;
SmoothScrollSequencer* GetSmoothScrollSequencer() const override;
void ServiceScrollAnimations(double) override;
void UpdateCompositorScrollAnimations() override;
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 03c375761a1..f37a736e664 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
@@ -10,13 +10,13 @@
#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/public/platform/web_thread.h"
+#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme_mock.h"
#include "third_party/blink/renderer/platform/geometry/double_rect.h"
#include "third_party/blink/renderer/platform/geometry/layout_rect.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
#include "third_party/blink/renderer/platform/scroll/scroll_alignment.h"
#include "third_party/blink/renderer/platform/scroll/scroll_types.h"
-#include "third_party/blink/renderer/platform/scroll/scrollable_area.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme_mock.h"
namespace {
blink::ScrollbarThemeMock scrollbar_theme_;
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 85925c61167..c87d81d4eb5 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,7 +104,7 @@ RotationViewportAnchor::RotationViewportAnchor(
: root_frame_view_(&root_frame_view),
visual_viewport_(&visual_viewport),
anchor_in_inner_view_coords_(anchor_in_inner_view_coords),
- page_scale_constraints_set_(page_scale_constraints_set) {
+ page_scale_constraints_set_(&page_scale_constraints_set) {
SetAnchor();
}
@@ -119,7 +119,7 @@ void RotationViewportAnchor::SetAnchor() {
old_page_scale_factor_ = visual_viewport_->Scale();
old_minimum_page_scale_factor_ =
- page_scale_constraints_set_.FinalConstraints().minimum_scale;
+ page_scale_constraints_set_->FinalConstraints().minimum_scale;
// Save the absolute location in case we won't find the anchor node, we'll
// fall back to that.
@@ -178,9 +178,9 @@ void RotationViewportAnchor::SetAnchor() {
void RotationViewportAnchor::RestoreToAnchor() {
float new_page_scale_factor =
old_page_scale_factor_ / old_minimum_page_scale_factor_ *
- page_scale_constraints_set_.FinalConstraints().minimum_scale;
+ page_scale_constraints_set_->FinalConstraints().minimum_scale;
new_page_scale_factor =
- page_scale_constraints_set_.FinalConstraints().ClampToConstraints(
+ page_scale_constraints_set_->FinalConstraints().ClampToConstraints(
new_page_scale_factor);
FloatSize visual_viewport_size(visual_viewport_->Size());
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 a45b6a73d6f..6ee1c7683ca 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
@@ -70,7 +70,7 @@ class CORE_EXPORT RotationViewportAnchor {
FloatSize anchor_in_inner_view_coords_;
FloatSize anchor_in_node_coords_;
- PageScaleConstraintsSet& page_scale_constraints_set_;
+ Member<PageScaleConstraintsSet> page_scale_constraints_set_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/settings.cc b/chromium/third_party/blink/renderer/core/frame/settings.cc
index 46800b198d2..18f629d7b51 100644
--- a/chromium/third_party/blink/renderer/core/frame/settings.cc
+++ b/chromium/third_party/blink/renderer/core/frame/settings.cc
@@ -30,7 +30,7 @@
#include "base/memory/ptr_util.h"
#include "build/build_config.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
namespace blink {
@@ -88,7 +88,7 @@ void Settings::SetTextAutosizingEnabled(bool text_autosizing_enabled) {
Invalidate(SettingsDelegate::kTextAutosizingChange);
}
-// FIXME: Move to Settings.in once make_settings can understand IntSize.
+// TODO: Move to Settings.json5 once make_settings can understand IntSize.
void Settings::SetTextAutosizingWindowSizeOverride(
const IntSize& text_autosizing_window_size_override) {
if (text_autosizing_window_size_override_ ==
diff --git a/chromium/third_party/blink/renderer/core/frame/settings.json5 b/chromium/third_party/blink/renderer/core/frame/settings.json5
index 24f03d2a651..db9341b931a 100644
--- a/chromium/third_party/blink/renderer/core/frame/settings.json5
+++ b/chromium/third_party/blink/renderer/core/frame/settings.json5
@@ -555,6 +555,14 @@
invalidate: "ViewportDescription",
},
+ // When true, Blink will use the content width and viewport size to set the
+ // minimum scale factor such that the user can't zoom out into the area
+ // beyond the content.
+ {
+ name: "shrinksViewportContentToFit",
+ initial: false,
+ },
+
{
name: "dnsPrefetchingEnabled",
initial: false,
@@ -575,11 +583,11 @@
initial: false,
},
- // Set the timeout seconds of NetworkQuietTimers in FirstMeaningfulPainterDetector.
+ // Set the timeout seconds of the network-quiet timers in IdlenessDetector.
// Used by embedders who want to change the timeout time in order to run web contents
// on various embedded devices and changeable network bandwidths in different regions.
{
- name: "FMPNetworkQuietTimeout",
+ name: "NetworkQuietTimeout",
initial: "0.5",
type: "double",
},
@@ -656,13 +664,6 @@
type: "HoverType",
},
- // Whether accessibility support is enabled at all.
- {
- name: "accessibilityEnabled",
- initial: false,
- invalidate: "AccessibilityState",
- },
-
// If true, the value in password fields is exposed to assistive technologies.
{
name: "accessibilityPasswordValuesEnabled",
@@ -856,17 +857,6 @@
type: "PassiveListenerDefault",
},
- // Whether the CSSPreloadScanner is used for externally CSS preloads. NoPreload
- // indicates that the scanner will be used, but no preloads issued.
- {
- name: "cssExternalScannerNoPreload",
- initial: false,
- },
- {
- name: "cssExternalScannerPreload",
- initial: false,
- },
-
// Some platforms have media subsystems which are too buggy to allow preloading
// of content by default. See http://crbug.com/612909 for details.
{
@@ -893,12 +883,6 @@
initial: false,
},
- // Whether or not to issue range requests for images and show placeholders.
- {
- name: "fetchImagePlaceholders",
- initial: false,
- },
-
// Whether the frame is a presentation receiver and should expose
// `navigator.presentation.receiver`.
{
@@ -1000,5 +984,39 @@
initial: 800,
type: "int",
},
+
+ //
+ // Lazy image loading distance-from-viewport thresholds for different effective connection types.
+ //
+ {
+ name: "lazyImageLoadingDistanceThresholdPxUnknown",
+ initial: 800,
+ type: "int",
+ },
+ {
+ name: "lazyImageLoadingDistanceThresholdPxOffline",
+ initial: 800,
+ type: "int",
+ },
+ {
+ name: "lazyImageLoadingDistanceThresholdPxSlow2G",
+ initial: 800,
+ type: "int",
+ },
+ {
+ name: "lazyImageLoadingDistanceThresholdPx2G",
+ initial: 800,
+ type: "int",
+ },
+ {
+ name: "lazyImageLoadingDistanceThresholdPx3G",
+ initial: 800,
+ type: "int",
+ },
+ {
+ name: "lazyImageLoadingDistanceThresholdPx4G",
+ initial: 800,
+ type: "int",
+ },
],
}
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 b0887aaf9be..60a0b40369c 100644
--- a/chromium/third_party/blink/renderer/core/frame/smart_clip.cc
+++ b/chromium/third_party/blink/renderer/core/frame/smart_clip.cc
@@ -173,7 +173,7 @@ Node* SmartClip::FindBestOverlappingNode(Node* root_node,
if (layout_object && !node_rect.IsEmpty()) {
if (layout_object->IsText() || layout_object->IsLayoutImage() ||
node->IsFrameOwnerElement() ||
- (layout_object->Style()->HasBackgroundImage() &&
+ (layout_object->StyleRef().HasBackgroundImage() &&
!ShouldSkipBackgroundImage(node))) {
if (resized_crop_rect.Intersects(node_rect)) {
min_node = MinNodeContainsNodes(min_node, node);
@@ -203,8 +203,8 @@ bool SmartClip::ShouldSkipBackgroundImage(Node* node) {
// or a width. On the other hand, if we've got a legit background image,
// it's very likely the height or the width will be set to auto.
LayoutObject* layout_object = node->GetLayoutObject();
- if (layout_object && (layout_object->Style()->LogicalHeight().IsAuto() ||
- layout_object->Style()->LogicalWidth().IsAuto()))
+ if (layout_object && (layout_object->StyleRef().LogicalHeight().IsAuto() ||
+ layout_object->StyleRef().LogicalWidth().IsAuto()))
return true;
return false;
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
new file mode 100644
index 00000000000..4ce924049b8
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/frame/test_report_body.h
@@ -0,0 +1,28 @@
+// 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_FRAME_TEST_REPORT_BODY_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_TEST_REPORT_BODY_H_
+
+#include "third_party/blink/renderer/core/frame/report_body.h"
+
+namespace blink {
+
+class TestReportBody : public ReportBody {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ TestReportBody(const String& message) : message_(message) {}
+
+ ~TestReportBody() override = default;
+
+ String message() const { return message_; }
+
+ private:
+ const String message_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_TEST_REPORT_BODY_H_
diff --git a/chromium/third_party/blink/renderer/core/frame/test_report_body.idl b/chromium/third_party/blink/renderer/core/frame/test_report_body.idl
new file mode 100644
index 00000000000..49a458f5fc3
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/frame/test_report_body.idl
@@ -0,0 +1,12 @@
+// 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://w3c.github.io/reporting/#test-report
+
+[
+ NoInterfaceObject,
+ RuntimeEnabled=TestReporting
+] interface TestReportBody : ReportBody {
+ readonly attribute DOMString message;
+};
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 0f07a645ebc..8aaaacc2a6d 100644
--- a/chromium/third_party/blink/renderer/core/frame/user_activation.cc
+++ b/chromium/third_party/blink/renderer/core/frame/user_activation.cc
@@ -8,6 +8,19 @@
namespace blink {
+UserActivation* UserActivation::CreateSnapshot(LocalDOMWindow* window) {
+ LocalFrame* frame = window->GetFrame();
+ return new UserActivation(frame ? frame->HasBeenActivated() : false,
+ Frame::HasTransientUserActivation(frame));
+}
+
+UserActivation* UserActivation::CreateLive(LocalDOMWindow* window) {
+ return new UserActivation(window);
+}
+
+UserActivation::UserActivation(bool has_been_active, bool is_active)
+ : has_been_active_(has_been_active), is_active_(is_active) {}
+
UserActivation::UserActivation(LocalDOMWindow* window) : window_(window) {}
UserActivation::~UserActivation() = default;
@@ -20,14 +33,14 @@ void UserActivation::Trace(blink::Visitor* visitor) {
bool UserActivation::hasBeenActive() const {
LocalFrame* frame = window_ ? window_->GetFrame() : nullptr;
if (!frame)
- return false;
+ return has_been_active_;
return frame->HasBeenActivated();
}
bool UserActivation::isActive() const {
LocalFrame* frame = window_ ? window_->GetFrame() : nullptr;
if (!frame)
- return false;
+ return is_active_;
return Frame::HasTransientUserActivation(frame);
}
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 9658ea291f2..b6da9d40649 100644
--- a/chromium/third_party/blink/renderer/core/frame/user_activation.h
+++ b/chromium/third_party/blink/renderer/core/frame/user_activation.h
@@ -15,8 +15,14 @@ class UserActivation final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
- explicit UserActivation(LocalDOMWindow* window);
+ // Creates an instance that is a snapshot of the current state of this
+ // LocalDOMWindow.
+ static UserActivation* CreateSnapshot(LocalDOMWindow* window);
+
+ // Creates an instance that represents the live state of this LocalDOMWindow.
+ static UserActivation* CreateLive(LocalDOMWindow* window);
+ UserActivation(bool has_been_active, bool is_active);
~UserActivation() override;
void Trace(blink::Visitor*) override;
@@ -25,7 +31,11 @@ class UserActivation final : public ScriptWrappable {
bool isActive() const;
private:
+ explicit UserActivation(LocalDOMWindow* window);
+
Member<LocalDOMWindow> window_;
+ bool has_been_active_ = false;
+ bool is_active_ = false;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/viewport_data.h b/chromium/third_party/blink/renderer/core/frame/viewport_data.h
index e3f539089ea..58569a9f851 100644
--- a/chromium/third_party/blink/renderer/core/frame/viewport_data.h
+++ b/chromium/third_party/blink/renderer/core/frame/viewport_data.h
@@ -31,6 +31,9 @@ class ViewportData : public GarbageCollectedFinalized<ViewportData> {
// When true this will force a kCover viewport fit value which will result in
// the document expanding into the display cutout area.
CORE_EXPORT void SetExpandIntoDisplayCutout(bool expand);
+ CORE_EXPORT bool GetExpandIntoDisplayCutout() const {
+ return force_expand_display_cutout_;
+ }
mojom::ViewportFit GetCurrentViewportFitForTests() const {
return viewport_fit_;
}
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 512a32095b1..a8d88cdf749 100644
--- a/chromium/third_party/blink/renderer/core/frame/visual_viewport.cc
+++ b/chromium/third_party/blink/renderer/core/frame/visual_viewport.cc
@@ -49,15 +49,19 @@
#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/core/paint/paint_layer_scrollable_area.h"
+#include "third_party/blink/renderer/core/paint/paint_property_tree_builder.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
+#include "third_party/blink/renderer/core/scroll/scroll_animator_base.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme_overlay.h"
#include "third_party/blink/renderer/platform/geometry/double_rect.h"
#include "third_party/blink/renderer/platform/geometry/float_size.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/effect_paint_property_node.h"
+#include "third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h"
#include "third_party/blink/renderer/platform/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
-#include "third_party/blink/renderer/platform/scroll/scroll_animator_base.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay.h"
namespace blink {
@@ -67,10 +71,22 @@ VisualViewport::VisualViewport(Page& owner)
browser_controls_adjustment_(0),
max_page_scale_(-1),
track_pinch_zoom_stats_for_page_(false),
- unique_id_(NewUniqueObjectId()) {
+ needs_paint_property_update_(true) {
+ UniqueObjectId unique_id = NewUniqueObjectId();
+ element_id_ = CompositorElementIdFromUniqueObjectId(
+ unique_id, CompositorElementIdNamespace::kPrimary);
+ scroll_element_id_ = CompositorElementIdFromUniqueObjectId(
+ unique_id, CompositorElementIdNamespace::kScroll);
+ overscroll_elasticity_element_id_ = CompositorElementIdFromUniqueObjectId(
+ unique_id, CompositorElementIdNamespace::kOverscrollElasticity);
Reset();
}
+TransformPaintPropertyNode*
+VisualViewport::GetOverscrollElasticityTransformNode() const {
+ return overscroll_elasticity_transform_node_.get();
+}
+
TransformPaintPropertyNode* VisualViewport::GetPageScaleNode() const {
return scale_transform_node_.get();
}
@@ -83,21 +99,45 @@ ScrollPaintPropertyNode* VisualViewport::GetScrollNode() const {
return scroll_node_.get();
}
-void VisualViewport::UpdatePaintPropertyNodes(
- scoped_refptr<const TransformPaintPropertyNode> transform_parent,
- scoped_refptr<const ScrollPaintPropertyNode> scroll_parent) {
+void VisualViewport::UpdatePaintPropertyNodesIfNeeded(
+ PaintPropertyTreeBuilderFragmentContext& context) {
+ if (!needs_paint_property_update_)
+ return;
+
+ needs_paint_property_update_ = false;
+
+ auto* transform_parent = context.current.transform;
+ auto* scroll_parent = context.current.scroll;
+ auto* clip_parent = context.current.clip;
+ auto* effect_parent = context.current_effect;
+
DCHECK(transform_parent);
DCHECK(scroll_parent);
+ DCHECK(clip_parent);
+ DCHECK(effect_parent);
if (inner_viewport_container_layer_) {
inner_viewport_container_layer_->SetLayerState(
- PropertyTreeState(&TransformPaintPropertyNode::Root(),
- &ClipPaintPropertyNode::Root(),
- &EffectPaintPropertyNode::Root()),
+ PropertyTreeState(transform_parent, clip_parent, effect_parent),
IntPoint());
}
{
+ TransformPaintPropertyNode::State state;
+ state.compositor_element_id = GetCompositorOverscrollElasticityElementId();
+ // TODO(crbug.com/877794) Should create overscroll elasticity transform node
+ // based on settings.
+ if (!overscroll_elasticity_transform_node_) {
+ overscroll_elasticity_transform_node_ =
+ TransformPaintPropertyNode::Create(*transform_parent,
+ std::move(state));
+ } else {
+ overscroll_elasticity_transform_node_->Update(*transform_parent,
+ std::move(state));
+ }
+ }
+
+ {
TransformationMatrix scale_transform;
scale_transform.Scale(Scale());
TransformPaintPropertyNode::State state{scale_transform, FloatPoint3D()};
@@ -105,24 +145,25 @@ void VisualViewport::UpdatePaintPropertyNodes(
if (!scale_transform_node_) {
scale_transform_node_ = TransformPaintPropertyNode::Create(
- *transform_parent, std::move(state));
+ *overscroll_elasticity_transform_node_.get(), std::move(state));
} else {
- scale_transform_node_->Update(*transform_parent, std::move(state));
+ scale_transform_node_->Update(
+ *overscroll_elasticity_transform_node_.get(), std::move(state));
}
}
if (page_scale_layer_) {
page_scale_layer_->SetLayerState(
- PropertyTreeState(scale_transform_node_.get(),
- &ClipPaintPropertyNode::Root(),
- &EffectPaintPropertyNode::Root()),
+ PropertyTreeState(scale_transform_node_.get(), clip_parent,
+ effect_parent),
IntPoint());
}
{
ScrollPaintPropertyNode::State state;
state.container_rect = IntRect(IntPoint(), ExcludeScrollbars(size_));
- state.contents_rect = IntRect(IntPoint(), ContentsSize());
+ state.contents_rect =
+ IntRect(IntPoint(), ExcludeScrollbars(ContentsSize()));
state.user_scrollable_horizontal =
UserInputScrollable(kHorizontalScrollbar);
@@ -158,11 +199,53 @@ void VisualViewport::UpdatePaintPropertyNodes(
if (inner_viewport_scroll_layer_) {
inner_viewport_scroll_layer_->SetLayerState(
- PropertyTreeState(translation_transform_node_.get(),
- &ClipPaintPropertyNode::Root(),
- &EffectPaintPropertyNode::Root()),
+ PropertyTreeState(translation_transform_node_.get(), clip_parent,
+ effect_parent),
IntPoint());
}
+
+ if (overlay_scrollbar_horizontal_) {
+ EffectPaintPropertyNode::State state;
+ state.local_transform_space = transform_parent;
+ state.direct_compositing_reasons =
+ CompositingReason::kActiveOpacityAnimation;
+ state.compositor_element_id =
+ GetScrollbarElementId(ScrollbarOrientation::kHorizontalScrollbar);
+ if (!horizontal_scrollbar_effect_node_) {
+ horizontal_scrollbar_effect_node_ =
+ EffectPaintPropertyNode::Create(*effect_parent, std::move(state));
+ } else {
+ horizontal_scrollbar_effect_node_->Update(*effect_parent,
+ std::move(state));
+ }
+
+ overlay_scrollbar_horizontal_->SetLayerState(
+ PropertyTreeState(transform_parent, context.current.clip,
+ horizontal_scrollbar_effect_node_.get()),
+ IntPoint(overlay_scrollbar_horizontal_->GetPosition().X(),
+ overlay_scrollbar_horizontal_->GetPosition().Y()));
+ }
+
+ if (overlay_scrollbar_vertical_) {
+ EffectPaintPropertyNode::State state;
+ state.local_transform_space = transform_parent;
+ state.direct_compositing_reasons =
+ CompositingReason::kActiveOpacityAnimation;
+ state.compositor_element_id =
+ GetScrollbarElementId(ScrollbarOrientation::kVerticalScrollbar);
+ if (!vertical_scrollbar_effect_node_) {
+ vertical_scrollbar_effect_node_ =
+ EffectPaintPropertyNode::Create(*effect_parent, std::move(state));
+ } else {
+ vertical_scrollbar_effect_node_->Update(*effect_parent, std::move(state));
+ }
+
+ overlay_scrollbar_vertical_->SetLayerState(
+ PropertyTreeState(transform_parent, context.current.clip,
+ vertical_scrollbar_effect_node_.get()),
+ IntPoint(overlay_scrollbar_vertical_->GetPosition().X(),
+ overlay_scrollbar_vertical_->GetPosition().Y()));
+ }
}
VisualViewport::~VisualViewport() {
@@ -174,6 +257,10 @@ void VisualViewport::Trace(blink::Visitor* visitor) {
ScrollableArea::Trace(visitor);
}
+void VisualViewport::SetNeedsPaintPropertiesUpdate() {
+ needs_paint_property_update_ = true;
+}
+
void VisualViewport::UpdateStyleAndLayoutIgnorePendingStylesheets() const {
if (!MainFrame())
return;
@@ -183,17 +270,11 @@ void VisualViewport::UpdateStyleAndLayoutIgnorePendingStylesheets() const {
}
void VisualViewport::EnqueueScrollEvent() {
- if (!RuntimeEnabledFeatures::VisualViewportAPIEnabled())
- return;
-
if (Document* document = MainFrame()->GetDocument())
document->EnqueueVisualViewportScrollEvent();
}
void VisualViewport::EnqueueResizeEvent() {
- if (!RuntimeEnabledFeatures::VisualViewportAPIEnabled())
- return;
-
if (Document* document = MainFrame()->GetDocument())
document->EnqueueVisualViewportResizeEvent();
}
@@ -206,6 +287,7 @@ void VisualViewport::SetSize(const IntSize& size) {
"height", size.Height());
bool width_did_change = size.Width() != size_.Width();
size_ = size;
+ needs_paint_property_update_ = true;
if (inner_viewport_container_layer_) {
inner_viewport_container_layer_->SetSize(size_);
@@ -213,7 +295,11 @@ void VisualViewport::SetSize(const IntSize& size) {
static_cast<gfx::Size>(size_));
// Need to re-compute sizes for the overlay scrollbars.
- InitializeScrollbars();
+ if (overlay_scrollbar_horizontal_) {
+ DCHECK(overlay_scrollbar_vertical_);
+ SetupScrollbar(kHorizontalScrollbar);
+ SetupScrollbar(kVerticalScrollbar);
+ }
}
if (!MainFrame())
@@ -245,6 +331,7 @@ void VisualViewport::MainFrameDidChangeSize() {
if (inner_viewport_scroll_layer_)
inner_viewport_scroll_layer_->SetSize(ContentsSize());
+ needs_paint_property_update_ = true;
ClampToBoundaries();
}
@@ -409,6 +496,8 @@ bool VisualViewport::DidSetScaleOrLocation(float scale,
ClampToBoundaries();
+ needs_paint_property_update_ = true;
+
return true;
}
@@ -450,14 +539,20 @@ void VisualViewport::CreateLayerTree() {
!overscroll_elasticity_layer_ && !page_scale_layer_ &&
!inner_viewport_container_layer_);
+ needs_paint_property_update_ = true;
+
// FIXME: The root transform layer should only be created on demand.
root_transform_layer_ = GraphicsLayer::Create(*this);
inner_viewport_container_layer_ = GraphicsLayer::Create(*this);
- overscroll_elasticity_layer_ = GraphicsLayer::Create(*this);
+ // TODO(crbug.com/836884) Should remove overscroll_elasticity_layer_ after
+ // BGPT landed.
+ if (!RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
+ overscroll_elasticity_layer_ = GraphicsLayer::Create(*this);
+ overscroll_elasticity_layer_->SetElementId(
+ GetCompositorOverscrollElasticityElementId());
+ }
page_scale_layer_ = GraphicsLayer::Create(*this);
inner_viewport_scroll_layer_ = GraphicsLayer::Create(*this);
- overlay_scrollbar_horizontal_ = GraphicsLayer::Create(*this);
- overlay_scrollbar_vertical_ = GraphicsLayer::Create(*this);
ScrollingCoordinator* coordinator = GetPage().GetScrollingCoordinator();
DCHECK(coordinator);
@@ -478,9 +573,17 @@ void VisualViewport::CreateLayerTree() {
page_scale_layer_->SetElementId(GetCompositorElementId());
root_transform_layer_->AddChild(inner_viewport_container_layer_.get());
- inner_viewport_container_layer_->AddChild(overscroll_elasticity_layer_.get());
- overscroll_elasticity_layer_->AddChild(page_scale_layer_.get());
- page_scale_layer_->AddChild(inner_viewport_scroll_layer_.get());
+ // TODO(crbug.com/836884) Should remove overscroll_elasticity_layer_ after
+ // BGPT landed.
+ if (!RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
+ inner_viewport_container_layer_->AddChild(
+ overscroll_elasticity_layer_.get());
+ overscroll_elasticity_layer_->AddChild(page_scale_layer_.get());
+ page_scale_layer_->AddChild(inner_viewport_scroll_layer_.get());
+ } else {
+ inner_viewport_container_layer_->AddChild(page_scale_layer_.get());
+ page_scale_layer_->AddChild(inner_viewport_scroll_layer_.get());
+ }
// Ensure this class is set as the scroll layer's ScrollableArea.
coordinator->ScrollableAreaScrollLayerDidChange(this);
@@ -511,34 +614,19 @@ void VisualViewport::InitializeScrollbars() {
if (!inner_viewport_container_layer_)
return;
+ needs_paint_property_update_ = true;
+
if (VisualViewportSuppliesScrollbars() &&
!GetPage().GetSettings().GetHideScrollbars()) {
- if (!overlay_scrollbar_horizontal_->Parent()) {
- inner_viewport_container_layer_->AddChild(
- overlay_scrollbar_horizontal_.get());
- if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
- // TODO(pdr): The viewport overlay scrollbars do not have the correct
- // paint properties. See: https://crbug.com/836910
- overlay_scrollbar_horizontal_->SetLayerState(
- PropertyTreeState(PropertyTreeState::Root()), IntPoint());
- }
- }
- if (!overlay_scrollbar_vertical_->Parent()) {
- inner_viewport_container_layer_->AddChild(
- overlay_scrollbar_vertical_.get());
- if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
- // TODO(pdr): The viewport overlay scrollbars do not have the correct
- // paint properties. See: https://crbug.com/836910
- overlay_scrollbar_vertical_->SetLayerState(
- PropertyTreeState(PropertyTreeState::Root()), IntPoint());
- }
- }
-
+ DCHECK(!overlay_scrollbar_horizontal_);
+ DCHECK(!overlay_scrollbar_vertical_);
+ overlay_scrollbar_horizontal_ = GraphicsLayer::Create(*this);
+ overlay_scrollbar_vertical_ = GraphicsLayer::Create(*this);
SetupScrollbar(kHorizontalScrollbar);
SetupScrollbar(kVerticalScrollbar);
} else {
- overlay_scrollbar_horizontal_->RemoveFromParent();
- overlay_scrollbar_vertical_->RemoveFromParent();
+ overlay_scrollbar_horizontal_ = nullptr;
+ overlay_scrollbar_vertical_ = nullptr;
}
// Ensure existing LocalFrameView scrollbars are removed if the visual
@@ -557,7 +645,11 @@ void VisualViewport::SetupScrollbar(ScrollbarOrientation orientation) {
std::unique_ptr<ScrollingCoordinator::ScrollbarLayerGroup>&
scrollbar_layer_group = is_horizontal ? scrollbar_layer_group_horizontal_
: scrollbar_layer_group_vertical_;
-
+ if (!scrollbar_graphics_layer->Parent()) {
+ inner_viewport_container_layer_->AddChild(scrollbar_graphics_layer);
+ scrollbar_graphics_layer->SetLayerState(
+ PropertyTreeState(PropertyTreeState::Root()), IntPoint());
+ }
ScrollbarThemeOverlay& theme = ScrollbarThemeOverlay::MobileTheme();
int thumb_thickness = clampTo<int>(
std::floor(GetPage().GetChromeClient().WindowToViewportScalar(
@@ -608,6 +700,8 @@ void VisualViewport::SetupScrollbar(ScrollbarOrientation orientation) {
scrollbar_graphics_layer->SetPosition(FloatPoint(x_position, y_position));
scrollbar_graphics_layer->SetSize(IntSize(width, height));
scrollbar_graphics_layer->SetContentsRect(IntRect(0, 0, width, height));
+
+ needs_paint_property_update_ = true;
}
bool VisualViewport::VisualViewportSuppliesScrollbars() const {
@@ -615,20 +709,23 @@ bool VisualViewport::VisualViewportSuppliesScrollbars() const {
}
CompositorElementId VisualViewport::GetCompositorElementId() const {
- return CompositorElementIdFromUniqueObjectId(
- unique_id_, CompositorElementIdNamespace::kPrimary);
+ return element_id_;
}
CompositorElementId VisualViewport::GetCompositorScrollElementId() const {
- return CompositorElementIdFromUniqueObjectId(
- unique_id_, CompositorElementIdNamespace::kScroll);
+ return scroll_element_id_;
+}
+
+CompositorElementId VisualViewport::GetCompositorOverscrollElasticityElementId()
+ const {
+ return overscroll_elasticity_element_id_;
}
bool VisualViewport::ScrollAnimatorEnabled() const {
return GetPage().GetSettings().GetScrollAnimatorEnabled();
}
-PlatformChromeClient* VisualViewport::GetChromeClient() const {
+ChromeClient* VisualViewport::GetChromeClient() const {
return &GetPage().GetChromeClient();
}
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 6f10824b473..071c04b952a 100644
--- a/chromium/third_party/blink/renderer/core/frame/visual_viewport.h
+++ b/chromium/third_party/blink/renderer/core/frame/visual_viewport.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Google 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
@@ -38,24 +38,27 @@
#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/page/scrolling/scrolling_coordinator.h"
+#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
#include "third_party/blink/renderer/platform/geometry/float_rect.h"
#include "third_party/blink/renderer/platform/geometry/float_size.h"
#include "third_party/blink/renderer/platform/geometry/int_size.h"
#include "third_party/blink/renderer/platform/graphics/compositor_element_id.h"
#include "third_party/blink/renderer/platform/graphics/graphics_layer_client.h"
#include "third_party/blink/renderer/platform/scroll/scroll_types.h"
-#include "third_party/blink/renderer/platform/scroll/scrollable_area.h"
namespace blink {
+class EffectPaintPropertyNode;
class GraphicsContext;
class GraphicsLayer;
class IntRect;
class IntSize;
class LocalFrame;
class Page;
+class RootFrameViewport;
class ScrollPaintPropertyNode;
class TransformPaintPropertyNode;
+struct PaintPropertyTreeBuilderFragmentContext;
// Represents the visual viewport the user is currently seeing the page through.
// This class corresponds to the InnerViewport on the compositor. It is a
@@ -182,7 +185,7 @@ class CORE_EXPORT VisualViewport final
IntPoint RootFrameToViewport(const IntPoint&) const;
// ScrollableArea implementation
- PlatformChromeClient* GetChromeClient() const override;
+ ChromeClient* GetChromeClient() const override;
bool ShouldUseIntegerScrollOffset() const override;
void SetScrollOffset(const ScrollOffset&,
ScrollType,
@@ -252,6 +255,7 @@ class CORE_EXPORT VisualViewport final
ScrollbarTheme& GetPageScrollbarTheme() const override;
bool VisualViewportSuppliesScrollbars() const override;
+ TransformPaintPropertyNode* GetOverscrollElasticityTransformNode() const;
TransformPaintPropertyNode* GetPageScaleNode() const;
TransformPaintPropertyNode* GetScrollTranslationNode() const;
ScrollPaintPropertyNode* GetScrollNode() const;
@@ -260,9 +264,12 @@ class CORE_EXPORT VisualViewport final
// translation property nodes. Also set the layer states (inner viewport
// container, page scale layer, inner viewport scroll layer) to reference
// these nodes.
- void UpdatePaintPropertyNodes(
- scoped_refptr<const TransformPaintPropertyNode> transform_parent,
- scoped_refptr<const ScrollPaintPropertyNode> scroll_parent);
+ void UpdatePaintPropertyNodesIfNeeded(
+ PaintPropertyTreeBuilderFragmentContext& context);
+
+ CompositorElementId GetCompositorOverscrollElasticityElementId() const;
+
+ void SetNeedsPaintPropertiesUpdate();
private:
explicit VisualViewport(Page&);
@@ -328,9 +335,13 @@ class CORE_EXPORT VisualViewport final
std::unique_ptr<GraphicsLayer> overlay_scrollbar_horizontal_;
std::unique_ptr<GraphicsLayer> overlay_scrollbar_vertical_;
+ scoped_refptr<TransformPaintPropertyNode>
+ overscroll_elasticity_transform_node_;
scoped_refptr<TransformPaintPropertyNode> scale_transform_node_;
scoped_refptr<TransformPaintPropertyNode> translation_transform_node_;
scoped_refptr<ScrollPaintPropertyNode> scroll_node_;
+ scoped_refptr<EffectPaintPropertyNode> horizontal_scrollbar_effect_node_;
+ scoped_refptr<EffectPaintPropertyNode> vertical_scrollbar_effect_node_;
// Offset of the visual viewport from the main frame's origin, in CSS pixels.
ScrollOffset offset_;
@@ -355,7 +366,11 @@ class CORE_EXPORT VisualViewport final
// only to report statistics about pinch-zoom usage.
float max_page_scale_;
bool track_pinch_zoom_stats_for_page_;
- UniqueObjectId unique_id_;
+ CompositorElementId element_id_;
+ CompositorElementId scroll_element_id_;
+ CompositorElementId overscroll_elasticity_element_id_;
+
+ bool needs_paint_property_update_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/visual_viewport.idl b/chromium/third_party/blink/renderer/core/frame/visual_viewport.idl
index be7e37de0c3..00317b9f566 100644
--- a/chromium/third_party/blink/renderer/core/frame/visual_viewport.idl
+++ b/chromium/third_party/blink/renderer/core/frame/visual_viewport.idl
@@ -27,7 +27,6 @@
// WICG proposal: https://github.com/WICG/ViewportAPI
[
- RuntimeEnabled=VisualViewportAPI,
ImplementedAs=DOMVisualViewport
] interface VisualViewport : EventTarget {
[Measure] readonly attribute double offsetLeft;
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 24acefd9154..ca840617dcd 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
@@ -15,6 +15,7 @@
#include "third_party/blink/public/platform/web_input_event.h"
#include "third_party/blink/public/platform/web_layer_tree_view.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"
#include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/public/web/web_local_frame_client.h"
@@ -24,6 +25,7 @@
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/frame/browser_controls.h"
#include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/web_frame_widget_base.h"
@@ -40,6 +42,7 @@
#include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.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/scrollbar_theme_overlay.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/double_point.h"
@@ -402,6 +405,11 @@ TEST_P(VisualViewportTest, TestWebViewResizedBeforeAttachment) {
VisualViewport& visual_viewport = GetFrame()->GetPage()->GetVisualViewport();
EXPECT_FLOAT_SIZE_EQ(FloatSize(320, 240),
visual_viewport.ContainerLayer()->Size());
+
+ if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
+ EXPECT_EQ(IntSize(320, 240),
+ visual_viewport.GetScrollNode()->ContainerRect().Size());
+ }
}
// Make sure that the visibleRect method acurately reflects the scale and scroll
@@ -737,9 +745,14 @@ TEST_P(VisualViewportTest, TestAttachingNewFrameSetsInnerScrollLayerSize) {
// Navigate again, this time the LocalFrameView should be smaller.
RegisterMockedHttpURLLoad("viewport-device-width.html");
NavigateTo(base_url_ + "viewport-device-width.html");
+ WebView()->UpdateAllLifecyclePhases();
- // Ensure the scroll layer matches the frame view's size.
+ // Ensure the scroll contents size matches the frame view's size.
EXPECT_EQ(IntSize(320, 240), visual_viewport.ScrollLayer()->Size());
+ if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
+ EXPECT_EQ(IntSize(320, 240),
+ visual_viewport.GetScrollNode()->ContentsRect().Size());
+ }
// Ensure the location and scale were reset.
EXPECT_EQ(FloatSize(), visual_viewport.GetScrollOffset());
@@ -1493,8 +1506,8 @@ TEST_P(VisualViewportTest,
NavigateTo("about:blank");
VisualViewport& visual_viewport = GetFrame()->GetPage()->GetVisualViewport();
- EXPECT_FALSE(visual_viewport.LayerForHorizontalScrollbar()->Parent());
- EXPECT_FALSE(visual_viewport.LayerForVerticalScrollbar()->Parent());
+ EXPECT_FALSE(visual_viewport.LayerForHorizontalScrollbar());
+ EXPECT_FALSE(visual_viewport.LayerForVerticalScrollbar());
}
// Tests that scrollbar layers are attached to the inner viewport container
@@ -1506,6 +1519,8 @@ TEST_P(VisualViewportTest,
NavigateTo("about:blank");
VisualViewport& visual_viewport = GetFrame()->GetPage()->GetVisualViewport();
+ EXPECT_TRUE(visual_viewport.LayerForHorizontalScrollbar());
+ EXPECT_TRUE(visual_viewport.LayerForVerticalScrollbar());
EXPECT_TRUE(visual_viewport.LayerForHorizontalScrollbar()->Parent());
EXPECT_TRUE(visual_viewport.LayerForVerticalScrollbar()->Parent());
}
@@ -1533,6 +1548,15 @@ TEST_P(VisualViewportTest, TestChangingContentSizeAffectsScrollBounds) {
frame_view.LayoutViewport()->LayerForScrolling()->CcLayer();
EXPECT_EQ(gfx::Size(1500, 2400), scroll_layer->bounds());
+
+ if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
+ EXPECT_EQ(IntSize(1500, 2400), frame_view.GetLayoutView()
+ ->FirstFragment()
+ .PaintProperties()
+ ->Scroll()
+ ->ContentsRect()
+ .Size());
+ }
}
// Tests that resizing the visual viepwort keeps its bounds within the outer
@@ -1763,13 +1787,8 @@ TEST_P(VisualViewportTest, SlowScrollAfterImplScroll) {
EXPECT_EQ(FloatSize(350, 260), visual_viewport.GetScrollOffset());
}
-static void accessibilitySettings(WebSettings* settings) {
- VisualViewportTest::ConfigureSettings(settings);
- settings->SetAccessibilityEnabled(true);
-}
-
TEST_P(VisualViewportTest, AccessibilityHitTestWhileZoomedIn) {
- InitializeWithDesktopSettings(accessibilitySettings);
+ InitializeWithDesktopSettings();
RegisterMockedHttpURLLoad("hit-test.html");
NavigateTo(base_url_ + "hit-test.html");
@@ -1780,6 +1799,8 @@ TEST_P(VisualViewportTest, AccessibilityHitTestWhileZoomedIn) {
WebDocument web_doc = WebView()->MainFrameImpl()->GetDocument();
LocalFrameView& frame_view = *WebView()->MainFrameImpl()->GetFrameView();
+ WebAXContext ax_context(web_doc);
+
WebView()->SetPageScaleFactor(2);
WebView()->SetVisualViewportOffset(WebFloatPoint(200, 230));
frame_view.LayoutViewport()->SetScrollOffset(ScrollOffset(400, 1100),
@@ -1956,7 +1977,7 @@ TEST_P(VisualViewportTest, RotationAnchoringWithRootScroller) {
}
// Make sure a composited background-attachment:fixed background gets resized
-// when using inert (non-layout affecting) browser controls.
+// by browser controls.
TEST_P(VisualViewportTest, ResizeCompositedAndFixedBackground) {
if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
return;
@@ -2032,7 +2053,7 @@ static void configureAndroidNonCompositing(WebSettings* settings) {
}
// Make sure a non-composited background-attachment:fixed background gets
-// resized when using inert (non-layout affecting) browser controls.
+// resized by browser controls.
TEST_P(VisualViewportTest, ResizeNonCompositedAndFixedBackground) {
if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
return;
@@ -2232,6 +2253,67 @@ TEST_P(VisualViewportTest, InvalidateLayoutViewWhenDocumentSmallerThanView) {
document->View()->SetTracksPaintInvalidations(false);
}
+// Ensure we create transform node for overscroll elasticity properly.
+TEST_P(VisualViewportTest, EnsureOverscrollElasticityTransformNode) {
+ if (!RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled())
+ return;
+
+ InitializeWithAndroidSettings();
+ WebView()->Resize(IntSize(400, 400));
+ NavigateTo("about:blank");
+ WebView()->UpdateAllLifecyclePhases();
+
+ VisualViewport& visual_viewport = GetFrame()->GetPage()->GetVisualViewport();
+ auto* node = visual_viewport.GetOverscrollElasticityTransformNode();
+ CompositorElementId element_id =
+ visual_viewport.GetCompositorOverscrollElasticityElementId();
+ EXPECT_TRUE(node);
+ EXPECT_EQ(element_id, node->GetCompositorElementId());
+}
+
+// Ensure we create effect node for scrollbar properly.
+TEST_P(VisualViewportTest, EnsureEffectNodeForScrollbars) {
+ if (!RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled())
+ return;
+
+ InitializeWithAndroidSettings();
+ WebView()->Resize(IntSize(400, 400));
+ NavigateTo("about:blank");
+ WebView()->UpdateAllLifecyclePhases();
+
+ VisualViewport& visual_viewport = GetFrame()->GetPage()->GetVisualViewport();
+ auto* vertical_scrollbar = visual_viewport.LayerForVerticalScrollbar();
+ auto* horizontal_scrollbar = visual_viewport.LayerForHorizontalScrollbar();
+ ASSERT_TRUE(vertical_scrollbar);
+ ASSERT_TRUE(horizontal_scrollbar);
+
+ auto& vertical_scrollbar_state = vertical_scrollbar->GetPropertyTreeState();
+ auto& horizontal_scrollbar_state =
+ horizontal_scrollbar->GetPropertyTreeState();
+
+ ScrollbarThemeOverlay& theme = ScrollbarThemeOverlay::MobileTheme();
+ int scrollbar_thickness = clampTo<int>(std::floor(
+ GetFrame()->GetPage()->GetChromeClient().WindowToViewportScalar(
+ theme.ScrollbarThickness(kRegularScrollbar))));
+
+ EXPECT_TRUE(vertical_scrollbar_state.Effect());
+ EXPECT_EQ(vertical_scrollbar_state.Effect()->GetCompositorElementId(),
+ visual_viewport.GetScrollbarElementId(
+ ScrollbarOrientation::kVerticalScrollbar));
+ EXPECT_EQ(vertical_scrollbar->GetOffsetFromTransformNode(),
+ IntPoint(400 - scrollbar_thickness, 0));
+
+ EXPECT_TRUE(horizontal_scrollbar_state.Effect());
+ EXPECT_EQ(horizontal_scrollbar_state.Effect()->GetCompositorElementId(),
+ visual_viewport.GetScrollbarElementId(
+ ScrollbarOrientation::kHorizontalScrollbar));
+ EXPECT_EQ(horizontal_scrollbar->GetOffsetFromTransformNode(),
+ IntPoint(0, 400 - scrollbar_thickness));
+
+ EXPECT_EQ(vertical_scrollbar_state.Effect()->Parent(),
+ horizontal_scrollbar_state.Effect()->Parent());
+}
+
// Make sure we don't crash when the visual viewport's height is 0. This can
// happen transiently in autoresize mode and cause a crash. This test passes if
// it doesn't crash.
@@ -2298,6 +2380,13 @@ TEST_F(VisualViewportSimTest, ScrollingContentsSmallerThanContainer) {
EXPECT_EQ(gfx::Size(320, 480),
visual_viewport.ScrollLayer()->CcLayer()->bounds());
+ if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
+ EXPECT_EQ(IntSize(400, 600),
+ visual_viewport.GetScrollNode()->ContainerRect().Size());
+ EXPECT_EQ(IntSize(320, 480),
+ visual_viewport.GetScrollNode()->ContentsRect().Size());
+ }
+
WebView().ApplyViewportDeltas(WebFloatSize(1, 1), WebFloatSize(),
WebFloatSize(), 2, 1);
EXPECT_EQ(IntSize(400, 600), visual_viewport.ContainerLayer()->Size());
@@ -2306,6 +2395,13 @@ TEST_F(VisualViewportSimTest, ScrollingContentsSmallerThanContainer) {
EXPECT_EQ(IntSize(320, 480), visual_viewport.ScrollLayer()->Size());
EXPECT_EQ(gfx::Size(320, 480),
visual_viewport.ScrollLayer()->CcLayer()->bounds());
+
+ if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
+ EXPECT_EQ(IntSize(400, 600),
+ visual_viewport.GetScrollNode()->ContainerRect().Size());
+ EXPECT_EQ(IntSize(320, 480),
+ visual_viewport.GetScrollNode()->ContentsRect().Size());
+ }
}
} // namespace
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 d2026b66ee0..c27342aa11e 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
@@ -293,12 +293,6 @@ void WebFrameWidgetImpl::UpdateLifecycle(LifecycleUpdate requested_update) {
if (!LocalRootImpl())
return;
- bool pre_paint_only = requested_update == LifecycleUpdate::kPrePaint;
-
- WebDevToolsAgentImpl* devtools = LocalRootImpl()->DevToolsAgentImpl();
- if (devtools && !pre_paint_only)
- devtools->PaintOverlay();
-
DocumentLifecycle::AllowThrottlingScope throttling_scope(
LocalRootImpl()->GetFrame()->GetDocument()->Lifecycle());
PageWidgetDelegate::UpdateLifecycle(*GetPage(), *LocalRootImpl()->GetFrame(),
@@ -696,14 +690,15 @@ void WebFrameWidgetImpl::WillCloseLayerTreeView() {
}
void WebFrameWidgetImpl::SetRemoteViewportIntersection(
- const WebRect& viewport_intersection) {
+ const WebRect& viewport_intersection,
+ bool occluded_or_obscured) {
// Remote viewports are only applicable to local frames with remote ancestors.
DCHECK(LocalRootImpl()->Parent() &&
LocalRootImpl()->Parent()->IsWebRemoteFrame() &&
LocalRootImpl()->GetFrame());
LocalRootImpl()->GetFrame()->SetViewportIntersectionFromParent(
- viewport_intersection);
+ viewport_intersection, occluded_or_obscured);
}
void WebFrameWidgetImpl::SetIsInert(bool inert) {
@@ -877,7 +872,16 @@ WebInputEventResult WebFrameWidgetImpl::HandleGestureEvent(
View()->SetLastHiddenPagePopup(nullptr);
break;
case WebInputEvent::kGestureShowPress:
+ break;
case WebInputEvent::kGestureDoubleTap:
+ // Until https://crbug.com/734209 is resolved and OOPIFs learn how to
+ // handle AnimateDoubleTap, we shouldn't pass this event to the event
+ // handler as it will just result in (at best) hitting NOTREACHED() in
+ // debug builds.
+ LOG(INFO) << "DoubleTap zoom animations not yet implemented for OOPIF.";
+ event_result = WebInputEventResult::kHandledSystem;
+ Client()->DidHandleGestureEvent(event, event_cancelled);
+ return event_result;
break;
case WebInputEvent::kGestureTwoFingerTap:
case WebInputEvent::kGestureLongPress:
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 aed5ed2ed2a..7edc6ca1f98 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
@@ -109,7 +109,7 @@ class WebFrameWidgetImpl final : public WebFrameWidgetBase,
bool SelectionBounds(WebRect& anchor, WebRect& focus) const override;
bool IsAcceleratedCompositingActive() const override;
void WillCloseLayerTreeView() override;
- void SetRemoteViewportIntersection(const WebRect&) override;
+ void SetRemoteViewportIntersection(const WebRect&, bool) override;
void SetIsInert(bool) override;
void SetInheritedEffectiveTouchAction(TouchAction) override;
void UpdateRenderThrottlingStatus(bool is_throttled,
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 082b055a570..fbadba8e0f2 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
@@ -119,6 +119,7 @@
#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_media_player_action.h"
+#include "third_party/blink/public/web/web_navigation_params.h"
#include "third_party/blink/public/web/web_node.h"
#include "third_party/blink/public/web/web_performance.h"
#include "third_party/blink/public/web/web_plugin.h"
@@ -139,6 +140,7 @@
#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"
@@ -220,6 +222,7 @@
#include "third_party/blink/renderer/core/page/print_context.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
+#include "third_party/blink/renderer/core/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/bindings/dom_wrapper_world.h"
@@ -242,7 +245,6 @@
#include "third_party/blink/renderer/platform/loader/fetch/substitute_data.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
#include "third_party/blink/renderer/platform/scroll/scroll_types.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.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"
@@ -593,6 +595,10 @@ bool WebLocalFrameImpl::IsFocused() const {
ViewImpl()->GetPage()->GetFocusController().FocusedFrame());
}
+bool WebLocalFrameImpl::UsePrintingLayout() const {
+ return print_context_ ? print_context_->use_printing_layout() : false;
+}
+
WebSize WebLocalFrameImpl::GetScrollOffset() const {
if (ScrollableArea* scrollable_area = LayoutViewport())
return scrollable_area->ScrollOffsetInt();
@@ -662,6 +668,11 @@ 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();
}
@@ -938,7 +949,7 @@ void WebLocalFrameImpl::LoadHTMLString(const WebData& data,
CommitDataNavigation(data, WebString::FromUTF8("text/html"),
WebString::FromUTF8("UTF-8"), base_url, unreachable_url,
replace, WebFrameLoadType::kStandard, WebHistoryItem(),
- false, nullptr, WebNavigationTimings());
+ false, nullptr, nullptr);
}
void WebLocalFrameImpl::StopLoading() {
@@ -1200,13 +1211,9 @@ bool WebLocalFrameImpl::HasSelection() const {
return plugin_container->Plugin()->HasSelection();
// frame()->selection()->isNone() never returns true.
- return GetFrame()
- ->Selection()
- .ComputeVisibleSelectionInDOMTreeDeprecated()
- .Start() != GetFrame()
- ->Selection()
- .ComputeVisibleSelectionInDOMTreeDeprecated()
- .End();
+ const auto& selection =
+ GetFrame()->Selection().ComputeVisibleSelectionInDOMTreeDeprecated();
+ return selection.Start() != selection.End();
}
WebRange WebLocalFrameImpl::SelectionRange() const {
@@ -1490,7 +1497,7 @@ void WebLocalFrameImpl::DispatchPrintEventRecursively(
}
if (!frame->Tree().IsDescendantOf(frame_))
continue;
- ToLocalFrame(frame)->DomWindow()->DispatchEvent(Event::Create(event_type));
+ ToLocalFrame(frame)->DomWindow()->DispatchEvent(*Event::Create(event_type));
}
}
@@ -1856,6 +1863,11 @@ void WebLocalFrameImpl::DidChangeContentsSize(const IntSize& size) {
GetTextFinder()->IncreaseMarkerVersion();
}
+void WebLocalFrameImpl::UpdateDevToolsOverlays() {
+ if (dev_tools_agent_)
+ dev_tools_agent_->UpdateOverlays();
+}
+
void WebLocalFrameImpl::CreateFrameView() {
TRACE_EVENT0("blink", "WebLocalFrameImpl::createFrameView");
@@ -2026,8 +2038,8 @@ void WebLocalFrameImpl::CommitNavigation(
const WebHistoryItem& item,
bool is_client_redirect,
const base::UnguessableToken& devtools_navigation_token,
- std::unique_ptr<WebDocumentLoader::ExtraData> extra_data,
- const WebNavigationTimings& navigation_timings) {
+ std::unique_ptr<WebNavigationParams> navigation_params,
+ std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) {
DCHECK(GetFrame());
DCHECK(!request.IsNull());
DCHECK(!request.Url().ProtocolIs("javascript"));
@@ -2042,9 +2054,9 @@ void WebLocalFrameImpl::CommitNavigation(
if (is_client_redirect)
frame_request.SetClientRedirect(ClientRedirectPolicy::kClientRedirect);
HistoryItem* history_item = item;
- GetFrame()->Loader().CommitNavigation(frame_request, web_frame_load_type,
- history_item, std::move(extra_data),
- navigation_timings);
+ GetFrame()->Loader().CommitNavigation(
+ frame_request, web_frame_load_type, history_item,
+ std::move(navigation_params), std::move(extra_data));
}
blink::mojom::CommitResult WebLocalFrameImpl::CommitSameDocumentNavigation(
@@ -2111,37 +2123,62 @@ void WebLocalFrameImpl::CommitDataNavigation(
WebFrameLoadType web_frame_load_type,
const WebHistoryItem& item,
bool is_client_redirect,
- std::unique_ptr<WebDocumentLoader::ExtraData> navigation_data,
- const WebNavigationTimings& navigation_timings) {
+ std::unique_ptr<WebNavigationParams> navigation_params,
+ std::unique_ptr<WebDocumentLoader::ExtraData> navigation_data) {
DCHECK(GetFrame());
- // If we are loading substitute data to replace an existing load, then
- // inherit all of the properties of that original request. This way,
- // reload will re-attempt the original request. It is essential that
- // we only do this when there is an unreachableURL since a non-empty
- // unreachableURL informs FrameLoader::reload to load unreachableURL
- // instead of the currently loaded URL.
+ // TODO(dgozman): this whole logic of rewriting the params is odd,
+ // and should be moved to the callsites instead.
ResourceRequest request;
HistoryItem* history_item = item;
DocumentLoader* provisional_document_loader =
GetFrame()->Loader().GetProvisionalDocumentLoader();
+ // If we are loading substitute data to replace an existing load, then
+ // inherit all of the properties of that original request. This way,
+ // reload will re-attempt the original request. It is essential that
+ // we only do this when there is an |unreachable_url| since a non-empty
+ // |unreachable_url| informs FrameLoader::CommitNavigation to load
+ // |unreachable_url| instead of the currently loaded URL.
if (replace && !unreachable_url.IsEmpty() && provisional_document_loader) {
request = provisional_document_loader->OriginalRequest();
+
// When replacing a failed back/forward provisional navigation with an error
// page, retain the HistoryItem for the failed provisional navigation
// and reuse it for the error page navigation.
- if (provisional_document_loader->LoadType() ==
- WebFrameLoadType::kBackForward &&
+ WebFrameLoadType previous_load_type =
+ provisional_document_loader->LoadType();
+ if (previous_load_type == WebFrameLoadType::kBackForward &&
provisional_document_loader->GetHistoryItem()) {
history_item = provisional_document_loader->GetHistoryItem();
web_frame_load_type = WebFrameLoadType::kBackForward;
+ } else if (previous_load_type == WebFrameLoadType::kReload ||
+ previous_load_type == WebFrameLoadType::kReloadBypassingCache) {
+ web_frame_load_type = previous_load_type;
}
}
request.SetURL(base_url);
- request.SetCheckForBrowserSideNavigation(false);
+ CommitDataNavigationWithRequest(
+ WrappedResourceRequest(request), data, mime_type, text_encoding,
+ unreachable_url, replace, web_frame_load_type, history_item,
+ is_client_redirect, std::move(navigation_params),
+ std::move(navigation_data));
+}
+
+void WebLocalFrameImpl::CommitDataNavigationWithRequest(
+ const WebURLRequest& request,
+ const WebData& data,
+ const WebString& mime_type,
+ const WebString& text_encoding,
+ const WebURL& unreachable_url,
+ bool replace,
+ WebFrameLoadType web_frame_load_type,
+ const WebHistoryItem& history_item,
+ bool is_client_redirect,
+ std::unique_ptr<WebNavigationParams> navigation_params,
+ std::unique_ptr<WebDocumentLoader::ExtraData> navigation_data) {
FrameLoadRequest frame_request(
- nullptr, request,
+ nullptr, request.ToResourceRequest(),
SubstituteData(data, mime_type, text_encoding, unreachable_url));
DCHECK(frame_request.GetSubstituteData().IsValid());
frame_request.SetReplacesCurrentItem(replace);
@@ -2150,7 +2187,7 @@ void WebLocalFrameImpl::CommitDataNavigation(
GetFrame()->Loader().CommitNavigation(
frame_request, web_frame_load_type, history_item,
- std::move(navigation_data), navigation_timings);
+ std::move(navigation_params), std::move(navigation_data));
}
WebLocalFrame::FallbackContentResult
@@ -2223,7 +2260,7 @@ void WebLocalFrameImpl::SetCommittedFirstRealLoad() {
DCHECK(GetFrame());
GetFrame()->Loader().StateMachine()->AdvanceTo(
FrameLoaderStateMachine::kCommittedMultipleRealLoads);
- GetFrame()->DidSendResourceTimingInfoToParent();
+ GetFrame()->SetShouldSendResourceTimingInfoToParent(false);
}
void WebLocalFrameImpl::NotifyUserActivation() {
@@ -2312,6 +2349,8 @@ WebNode WebLocalFrameImpl::ContextMenuNode() const {
void WebLocalFrameImpl::WillBeDetached() {
if (dev_tools_agent_)
dev_tools_agent_->WillBeDestroyed();
+ if (find_in_page_)
+ find_in_page_->Dispose();
}
void WebLocalFrameImpl::WillDetachParent() {
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 feb4b14bc8e..9b07d3bc3e5 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
@@ -31,6 +31,9 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_WEB_LOCAL_FRAME_IMPL_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_WEB_LOCAL_FRAME_IMPL_H_
+#include <memory>
+#include <set>
+
#include "base/single_thread_task_runner.h"
#include "third_party/blink/public/platform/web_file_system_type.h"
#include "third_party/blink/public/web/devtools_agent.mojom-blink.h"
@@ -46,8 +49,6 @@
#include "third_party/blink/renderer/platform/wtf/compiler.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-#include <memory>
-
namespace blink {
class ChromePrintContext;
@@ -264,8 +265,8 @@ class CORE_EXPORT WebLocalFrameImpl final
const WebHistoryItem&,
bool is_client_redirect,
const base::UnguessableToken& devtools_navigation_token,
- std::unique_ptr<WebDocumentLoader::ExtraData> extra_data,
- const WebNavigationTimings& navigation_timings) override;
+ std::unique_ptr<WebNavigationParams> navigation_params,
+ std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) override;
blink::mojom::CommitResult CommitSameDocumentNavigation(
const WebURL&,
WebFrameLoadType,
@@ -282,8 +283,20 @@ class CORE_EXPORT WebLocalFrameImpl final
WebFrameLoadType,
const WebHistoryItem&,
bool is_client_redirect,
- std::unique_ptr<WebDocumentLoader::ExtraData> navigation_data,
- const WebNavigationTimings& navigation_timings) override;
+ std::unique_ptr<WebNavigationParams> navigation_params,
+ std::unique_ptr<WebDocumentLoader::ExtraData> navigation_data) override;
+ void CommitDataNavigationWithRequest(
+ const WebURLRequest&,
+ const WebData&,
+ const WebString& mime_type,
+ const WebString& text_encoding,
+ const WebURL& unreachable_url,
+ bool replace,
+ WebFrameLoadType,
+ const WebHistoryItem&,
+ bool is_client_redirect,
+ std::unique_ptr<WebNavigationParams> navigation_params,
+ std::unique_ptr<WebDocumentLoader::ExtraData> navigation_data) override;
FallbackContentResult MaybeRenderFallbackContent(
const WebURLError&) const override;
void ReportContentSecurityPolicyViolation(
@@ -305,18 +318,13 @@ class CORE_EXPORT WebLocalFrameImpl final
void DidCallAddSearchProvider() override;
void DidCallIsSearchProviderInstalled() override;
void ReplaceSelection(const WebString&) override;
- void RequestFind(int identifier,
- const WebString& search_text,
- const WebFindOptions&) override;
bool Find(int identifier,
const WebString& search_text,
const WebFindOptions&,
bool wrap_within_frame,
bool* active_now = nullptr) override;
void StopFindingForTesting(mojom::StopFindAction) override;
-
void SetTickmarks(const WebVector<WebRect>&) override;
- WebPlugin* GetWebPluginForFind() override;
WebNode ContextMenuNode() const override;
WebFrameWidget* FrameWidget() const override;
void CopyImageAt(const WebPoint&) override;
@@ -363,6 +371,8 @@ class CORE_EXPORT WebLocalFrameImpl final
void DidChangeContentsSize(const IntSize&);
+ void UpdateDevToolsOverlays();
+
void CreateFrameView();
static WebLocalFrameImpl* FromFrame(LocalFrame*);
@@ -404,7 +414,7 @@ class CORE_EXPORT WebLocalFrameImpl final
ContentSettingsClient& GetContentSettingsClient() {
return content_settings_client_;
- };
+ }
SharedWorkerRepositoryClientImpl* SharedWorkerRepositoryClient() const {
return shared_worker_repository_client_.get();
@@ -439,6 +449,9 @@ class CORE_EXPORT WebLocalFrameImpl final
// Returns true if the frame is focused.
bool IsFocused() const;
+ // Returns true if our print context suggests using printing layout.
+ bool UsePrintingLayout() const;
+
virtual void Trace(blink::Visitor*);
private:
@@ -533,4 +546,4 @@ DEFINE_TYPE_CASTS(WebLocalFrameImpl,
} // namespace blink
-#endif
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_WEB_LOCAL_FRAME_IMPL_H_
diff --git a/chromium/third_party/blink/renderer/core/frame/window.idl b/chromium/third_party/blink/renderer/core/frame/window.idl
index 2b97ed831cd..09827d3c41a 100644
--- a/chromium/third_party/blink/renderer/core/frame/window.idl
+++ b/chromium/third_party/blink/renderer/core/frame/window.idl
@@ -102,7 +102,7 @@
[CrossOrigin, CallWith=CurrentWindow, RaisesException] void postMessage(any message, USVString targetOrigin, optional sequence<object> transfer = []);
- [CrossOrigin, CallWith=CurrentWindow, RaisesException, RuntimeEnabled=WindowPostMessageOptions] void postMessage(any message, optional sequence<object> transfer = [], optional WindowPostMessageOptions options);
+ [CrossOrigin, CallWith=CurrentWindow, RaisesException, RuntimeEnabled=PostMessageOptions] void postMessage(any message, optional WindowPostMessageOptions options);
// Custom elements
// https://w3c.github.io/webcomponents/spec/custom/#custom-elements-api
@@ -148,7 +148,7 @@
// Visual Viewport API
// https://github.com/WICG/ViewportAPI
- [RuntimeEnabled=VisualViewportAPI, Replaceable, SameObject] readonly attribute VisualViewport visualViewport;
+ [Replaceable, SameObject] readonly attribute VisualViewport visualViewport;
// client
[Affects=Nothing, Replaceable] readonly attribute long screenX;
@@ -217,6 +217,10 @@
readonly attribute boolean isSecureContext;
attribute DOMMatrixConstructor WebKitCSSMatrix;
+
+ //TrustedTypes API
+ //http://github.com/wicg/trusted-types
+ [RuntimeEnabled=TrustedDOMTypes] readonly attribute TrustedTypePolicyFactory TrustedTypes;
};
Window implements GlobalEventHandlers;
diff --git a/chromium/third_party/blink/renderer/core/frame/window_post_message_options.idl b/chromium/third_party/blink/renderer/core/frame/window_post_message_options.idl
index da0e1961654..41c8764e0b1 100644
--- a/chromium/third_party/blink/renderer/core/frame/window_post_message_options.idl
+++ b/chromium/third_party/blink/renderer/core/frame/window_post_message_options.idl
@@ -4,6 +4,6 @@
// https://github.com/dtapuska/useractivation
-dictionary WindowPostMessageOptions {
+dictionary WindowPostMessageOptions : PostMessageOptions {
USVString targetOrigin = "/";
};
diff --git a/chromium/third_party/blink/renderer/core/frame/window_timers.idl b/chromium/third_party/blink/renderer/core/frame/window_timers.idl
index 9f8fc078334..1641a395baa 100644
--- a/chromium/third_party/blink/renderer/core/frame/window_timers.idl
+++ b/chromium/third_party/blink/renderer/core/frame/window_timers.idl
@@ -25,7 +25,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-// https://html.spec.whatwg.org/#timers
+// https://html.spec.whatwg.org/C/webappapis.html#windoworworkerglobalscope-mixin
+// https://html.spec.whatwg.org/C/timers-and-user-prompts.html#timers
[
ImplementedAs=DOMWindowTimers,
@@ -33,13 +34,13 @@
NoInterfaceObject, // Always used on target of 'implements'
Exposed=(Window,Worker)
] interface WindowTimers {
- // FIXME: would be clearer as a union type, like:
- // typedef (Function or DOMString) Handler
- // Needs spec update and better union support: http://crbug.com/240176
- [CallWith=ScriptState, RuntimeCallStatsCounter=WindowSetTimeout] long setTimeout(Function handler, optional long timeout = 0, any... arguments);
+ // TODO(yukishiino): Use TimerHandler (or Function at least) to implement
+ // setTimeout and setInterval.
+ // https://html.spec.whatwg.org/C/webappapis.html#windoworworkerglobalscope-mixin
+ [CallWith=ScriptState, RuntimeCallStatsCounter=WindowSetTimeout] long setTimeout(CallbackFunctionTreatedAsScriptValue handler, optional long timeout = 0, any... arguments);
[CallWith=ScriptState] long setTimeout(DOMString 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] long setInterval(CallbackFunctionTreatedAsScriptValue handler, optional long timeout = 0, any... arguments);
[CallWith=ScriptState] long setInterval(DOMString handler, optional long timeout = 0, any... arguments);
void clearInterval(optional long handle = 0);
};
diff --git a/chromium/third_party/blink/renderer/core/fullscreen/BUILD.gn b/chromium/third_party/blink/renderer/core/fullscreen/BUILD.gn
index 2e0549f01d2..213571c5546 100644
--- a/chromium/third_party/blink/renderer/core/fullscreen/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/fullscreen/BUILD.gn
@@ -12,5 +12,7 @@ blink_core_sources("fullscreen") {
"element_fullscreen.h",
"fullscreen.cc",
"fullscreen.h",
+ "scoped_allow_fullscreen.cc",
+ "scoped_allow_fullscreen.h",
]
}
diff --git a/chromium/third_party/blink/renderer/core/fullscreen/fullscreen.cc b/chromium/third_party/blink/renderer/core/fullscreen/fullscreen.cc
index 1cc5721b2ff..7d8d65b11f5 100644
--- a/chromium/third_party/blink/renderer/core/fullscreen/fullscreen.cc
+++ b/chromium/third_party/blink/renderer/core/fullscreen/fullscreen.cc
@@ -43,16 +43,18 @@
#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/use_counter.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_iframe_element.h"
#include "third_party/blink/renderer/core/html_element_type_helpers.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/core/svg/svg_svg_element.h"
#include "third_party/blink/renderer/platform/bindings/microtask.h"
#include "third_party/blink/renderer/platform/feature_policy/feature_policy.h"
-#include "third_party/blink/renderer/platform/scoped_orientation_change_indicator.h"
namespace blink {
@@ -110,6 +112,11 @@ void FullscreenElementChanged(Document& document,
// https://crbug.com/668758
frame->GetEventHandler().ScheduleHoverStateUpdate();
frame->GetChromeClient().FullscreenElementChanged(old_element, new_element);
+
+ // Update paint properties on the visual viewport since
+ // user-input-scrollable bits will change based on fullscreen state.
+ if (Page* page = frame->GetPage())
+ page->GetVisualViewport().SetNeedsPaintPropertiesUpdate();
}
}
@@ -142,10 +149,15 @@ void GoFullscreen(Element& element, Fullscreen::RequestType request_type) {
Document& document = element.GetDocument();
Element* old_element = Fullscreen::FullscreenElementFrom(document);
+ // If |element| is already in top layer remove it so it will
+ // be appended to the end.
+ if (element.IsInTopLayer())
+ document.RemoveFromTopLayer(&element);
+ else
+ DCHECK(!HasFullscreenFlag(element));
+
// To fullscreen an |element| within a |document|, set the |element|'s
// fullscreen flag and add it to |document|'s top layer.
- DCHECK(!HasFullscreenFlag(element));
- DCHECK(!element.IsInTopLayer());
SetFullscreenFlag(element, request_type);
document.AddToTopLayer(&element);
@@ -192,7 +204,8 @@ void Unfullscreen(Document& document) {
}
// https://html.spec.whatwg.org/multipage/embedded-content.html#allowed-to-use
-bool AllowedToUseFullscreen(const Frame* frame) {
+bool AllowedToUseFullscreen(const Frame* frame,
+ ReportOptions report_on_failure) {
// To determine whether a Document object |document| is allowed to use the
// feature indicated by attribute name |allowattribute|, run these steps:
@@ -202,7 +215,8 @@ bool AllowedToUseFullscreen(const Frame* frame) {
// 2. If Feature Policy is enabled, return the policy for "fullscreen"
// feature.
- return frame->IsFeatureEnabled(mojom::FeaturePolicyFeature::kFullscreen);
+ return frame->IsFeatureEnabled(mojom::FeaturePolicyFeature::kFullscreen,
+ report_on_failure);
}
bool AllowedToRequestFullscreen(Document& document) {
@@ -214,7 +228,8 @@ bool AllowedToRequestFullscreen(Document& document) {
return true;
// The algorithm is triggered by a user generated orientation change.
- if (ScopedOrientationChangeIndicator::ProcessingOrientationChange()) {
+ if (ScopedAllowFullscreen::FullscreenAllowedReason() ==
+ ScopedAllowFullscreen::kOrientationChange) {
UseCounter::Count(document,
WebFeature::kFullscreenAllowedByOrientationChange);
return true;
@@ -242,7 +257,8 @@ bool FullscreenIsSupported(const Document& document) {
}
// https://fullscreen.spec.whatwg.org/#fullscreen-element-ready-check
-bool FullscreenElementReady(const Element& element) {
+bool FullscreenElementReady(const Element& element,
+ ReportOptions report_on_failure) {
// A fullscreen element ready check for an element |element| returns true if
// all of the following are true, and false otherwise:
@@ -252,31 +268,10 @@ bool FullscreenElementReady(const Element& element) {
// |element|'s node document is allowed to use the feature indicated by
// attribute name allowfullscreen.
- if (!AllowedToUseFullscreen(element.GetDocument().GetFrame()))
- return false;
-
- // |element|'s node document's fullscreen element stack is either empty or its
- // top element is an inclusive ancestor of |element|.
- if (const Element* top_element =
- Fullscreen::FullscreenElementFrom(element.GetDocument())) {
- if (!top_element->contains(&element))
- return false;
- }
-
- // |element| has no ancestor element whose local name is iframe and namespace
- // is the HTML namespace.
- if (Traversal<HTMLIFrameElement>::FirstAncestor(element))
+ if (!AllowedToUseFullscreen(element.GetDocument().GetFrame(),
+ report_on_failure))
return false;
- // |element|'s node document's browsing context either has a browsing context
- // container and the fullscreen element ready check returns true for
- // |element|'s node document's browsing context's browsing context container,
- // or it has no browsing context container.
- if (const Element* owner = element.GetDocument().LocalOwner()) {
- if (!FullscreenElementReady(*owner))
- return false;
- }
-
return true;
}
@@ -292,7 +287,7 @@ bool RequestFullscreenConditionsMet(Element& pending, Document& document) {
return false;
// The fullscreen element ready check for |pending| returns false.
- if (!FullscreenElementReady(pending))
+ if (!FullscreenElementReady(pending, ReportOptions::kReportOnFailure))
return false;
// Fullscreen is supported.
@@ -440,7 +435,7 @@ void FireEvent(const AtomicString& type, Element* element, Document* document) {
// set to true, at |target|.
Event* event = Event::CreateBubble(type);
event->SetComposed(true);
- target->DispatchEvent(event);
+ target->DispatchEvent(*event);
}
const AtomicString& AdjustEventType(const AtomicString& type,
@@ -668,7 +663,8 @@ void Fullscreen::ContinueRequestFullscreen(Document& document,
// 9. If any of the following conditions are false, then set |error| to true:
// * |pending|'s node document is |pendingDoc|.
// * The fullscreen element ready check for |pending| returns true.
- if (pending.GetDocument() != document || !FullscreenElementReady(pending))
+ if (pending.GetDocument() != document ||
+ !FullscreenElementReady(pending, ReportOptions::kDoNotReport))
error = true;
// 10. If |error| is true:
@@ -959,7 +955,8 @@ bool Fullscreen::FullscreenEnabled(Document& document) {
// The fullscreenEnabled attribute's getter must return true if the context
// object is allowed to use the feature indicated by attribute name
// allowfullscreen and fullscreen is supported, and false otherwise.
- return AllowedToUseFullscreen(document.GetFrame()) &&
+ return AllowedToUseFullscreen(document.GetFrame(),
+ ReportOptions::kDoNotReport) &&
FullscreenIsSupported(document);
}
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 e7f13d20b5b..a33dc291a31 100644
--- a/chromium/third_party/blink/renderer/core/fullscreen/fullscreen_options.idl
+++ b/chromium/third_party/blink/renderer/core/fullscreen/fullscreen_options.idl
@@ -4,6 +4,12 @@
// https://github.com/dtapuska/fullscreen
+enum FullscreenNavigationUI {
+ "auto",
+ "show",
+ "hide"
+};
+
dictionary FullscreenOptions {
- [RuntimeEnabled=FullscreenOptions] boolean prefersNavigationBar = false;
+ [RuntimeEnabled=FullscreenOptions] FullscreenNavigationUI navigationUI = "auto";
};
diff --git a/chromium/third_party/blink/renderer/core/fullscreen/scoped_allow_fullscreen.cc b/chromium/third_party/blink/renderer/core/fullscreen/scoped_allow_fullscreen.cc
new file mode 100644
index 00000000000..d16945fbb20
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/fullscreen/scoped_allow_fullscreen.cc
@@ -0,0 +1,32 @@
+// 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/fullscreen/scoped_allow_fullscreen.h"
+
+#include "third_party/blink/renderer/platform/wtf/assertions.h"
+#include "third_party/blink/renderer/platform/wtf/wtf.h"
+
+namespace blink {
+
+base::Optional<ScopedAllowFullscreen::Reason> ScopedAllowFullscreen::reason_;
+
+ScopedAllowFullscreen::ScopedAllowFullscreen(Reason reason) {
+ DCHECK(IsMainThread());
+ previous_reason_ = reason_;
+ reason_ = reason;
+}
+
+ScopedAllowFullscreen::~ScopedAllowFullscreen() {
+ DCHECK(IsMainThread());
+ reason_ = previous_reason_;
+}
+
+// static
+base::Optional<ScopedAllowFullscreen::Reason>
+ScopedAllowFullscreen::FullscreenAllowedReason() {
+ DCHECK(IsMainThread());
+ return reason_;
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..950b3841cef
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/fullscreen/scoped_allow_fullscreen.h
@@ -0,0 +1,34 @@
+// 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_FULLSCREEN_SCOPED_ALLOW_FULLSCREEN_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_FULLSCREEN_SCOPED_ALLOW_FULLSCREEN_H_
+
+#include "base/macros.h"
+#include "base/optional.h"
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/wtf/allocator.h"
+
+namespace blink {
+
+class CORE_EXPORT ScopedAllowFullscreen {
+ STACK_ALLOCATED();
+
+ public:
+ enum Reason { kOrientationChange };
+
+ static base::Optional<Reason> FullscreenAllowedReason();
+ explicit ScopedAllowFullscreen(Reason);
+ ~ScopedAllowFullscreen();
+
+ private:
+ static base::Optional<Reason> reason_;
+ base::Optional<Reason> previous_reason_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedAllowFullscreen);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FULLSCREEN_SCOPED_ALLOW_FULLSCREEN_H_
diff --git a/chromium/third_party/blink/renderer/core/fullscreen/scoped_allow_fullscreen_test.cc b/chromium/third_party/blink/renderer/core/fullscreen/scoped_allow_fullscreen_test.cc
new file mode 100644
index 00000000000..dbecd86c528
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/fullscreen/scoped_allow_fullscreen_test.cc
@@ -0,0 +1,48 @@
+// 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/fullscreen/scoped_allow_fullscreen.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace blink {
+
+TEST(ScopedAllowFullscreenTest, InitialState) {
+ EXPECT_FALSE(ScopedAllowFullscreen::FullscreenAllowedReason().has_value());
+}
+
+TEST(ScopedAllowFullscreenTest, ConstructOneScope) {
+ ScopedAllowFullscreen scope(ScopedAllowFullscreen::kOrientationChange);
+
+ EXPECT_EQ(ScopedAllowFullscreen::kOrientationChange,
+ ScopedAllowFullscreen::FullscreenAllowedReason().value());
+}
+
+TEST(ScopedAllowFullscreenTest, MultipleScopesInTheSameScope) {
+ ScopedAllowFullscreen scope1(ScopedAllowFullscreen::kOrientationChange);
+
+ EXPECT_EQ(ScopedAllowFullscreen::kOrientationChange,
+ ScopedAllowFullscreen::FullscreenAllowedReason().value());
+
+ ScopedAllowFullscreen scope2(ScopedAllowFullscreen::kOrientationChange);
+
+ EXPECT_EQ(ScopedAllowFullscreen::kOrientationChange,
+ ScopedAllowFullscreen::FullscreenAllowedReason().value());
+}
+
+TEST(ScopedAllowFullscreenTest, DestructResetsState) {
+ { ScopedAllowFullscreen scope(ScopedAllowFullscreen::kOrientationChange); }
+
+ EXPECT_FALSE(ScopedAllowFullscreen::FullscreenAllowedReason().has_value());
+}
+
+TEST(ScopedAllowFullscreenTest, DestructResetsStateToPrevious) {
+ ScopedAllowFullscreen scope(ScopedAllowFullscreen::kOrientationChange);
+ { ScopedAllowFullscreen scope(ScopedAllowFullscreen::kOrientationChange); }
+
+ EXPECT_EQ(ScopedAllowFullscreen::kOrientationChange,
+ ScopedAllowFullscreen::FullscreenAllowedReason().value());
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/BUILD.gn b/chromium/third_party/blink/renderer/core/html/BUILD.gn
index fe667fbfe8b..422cf6086f5 100644
--- a/chromium/third_party/blink/renderer/core/html/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/html/BUILD.gn
@@ -457,6 +457,8 @@ blink_core_sources("html") {
"imports/link_import.h",
"lazy_load_frame_observer.cc",
"lazy_load_frame_observer.h",
+ "lazy_load_image_observer.cc",
+ "lazy_load_image_observer.h",
"link_manifest.cc",
"link_manifest.h",
"link_rel_attribute.cc",
@@ -496,6 +498,8 @@ blink_core_sources("html") {
"media/picture_in_picture_interstitial.h",
"plugin_document.cc",
"plugin_document.h",
+ "portal/html_portal_element.cc",
+ "portal/html_portal_element.h",
"rel_list.cc",
"rel_list.h",
"shadow/details_marker_control.cc",
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 6e4540bb56e..b980a75b90e 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
@@ -5,7 +5,9 @@
#include "third_party/blink/renderer/core/html/anchor_element_metrics.h"
#include "base/metrics/histogram_macros.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/mojom/loader/navigation_predictor.mojom-blink.h"
+#include "third_party/blink/renderer/core/dom/element_traversal.h"
#include "third_party/blink/renderer/core/dom/flat_tree_traversal.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/html/anchor_element_metrics_sender.h"
@@ -17,14 +19,10 @@
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
#include "third_party/blink/renderer/platform/histogram.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
-// If RecordAnchorMetricsClicked feature is enabled, then metrics of anchor
-// elements clicked by the user will be extracted and recorded.
-const base::Feature kRecordAnchorMetricsClicked{
- "RecordAnchorMetricsClicked", base::FEATURE_DISABLED_BY_DEFAULT};
-
namespace {
// Helper function that returns the root document the anchor element is in.
@@ -137,6 +135,10 @@ IntRect AbsoluteElementBoundingBoxRect(const LayoutObject* layout_object) {
} // anonymous namespace
+// Webpage with more than |kMaxAnchorElementMetricsSize| anchor element metrics
+// to report will be ignored, so it should be large enough to cover most pages.
+const int AnchorElementMetrics::kMaxAnchorElementMetricsSize = 40;
+
// static
base::Optional<AnchorElementMetrics> AnchorElementMetrics::Create(
const HTMLAnchorElement* anchor_element) {
@@ -180,6 +182,8 @@ base::Optional<AnchorElementMetrics> AnchorElementMetrics::Create(
->GetScrollableArea()
->ContentsSize()
.Height();
+ float ratio_root_height = root_height / base_height;
+
int root_scrolled =
root_frame_view->LayoutViewport()->ScrollOffsetInt().Height();
float ratio_distance_root_bottom =
@@ -197,66 +201,123 @@ base::Optional<AnchorElementMetrics> AnchorElementMetrics::Create(
return AnchorElementMetrics(
anchor_element, ratio_area, ratio_visible_area,
ratio_distance_top_to_visible_top, ratio_distance_center_to_visible_top,
- ratio_distance_root_top, ratio_distance_root_bottom,
+ ratio_distance_root_top, ratio_distance_root_bottom, ratio_root_height,
IsInIFrame(*anchor_element), ContainsImage(*anchor_element),
IsSameHost(*anchor_element), IsUrlIncrementedByOne(*anchor_element));
}
// static
base::Optional<AnchorElementMetrics>
-AnchorElementMetrics::MaybeExtractMetricsClicked(
+AnchorElementMetrics::MaybeReportClickedMetricsOnClick(
const HTMLAnchorElement* anchor_element) {
- if (!base::FeatureList::IsEnabled(kRecordAnchorMetricsClicked) ||
- !anchor_element->Href().ProtocolIsInHTTPFamily())
+ if (!base::FeatureList::IsEnabled(features::kRecordAnchorMetricsClicked) ||
+ !anchor_element->Href().ProtocolIsInHTTPFamily() ||
+ !anchor_element->GetDocument().BaseURL().ProtocolIsInHTTPFamily()) {
return base::nullopt;
+ }
auto anchor_metrics = Create(anchor_element);
if (anchor_metrics.has_value()) {
- anchor_metrics.value().RecordMetrics();
- anchor_metrics.value().SendMetricsToBrowser();
+ anchor_metrics.value().RecordMetricsOnClick();
+
+ // Send metrics of the anchor element to the browser process.
+ AnchorElementMetricsSender::From(*GetRootDocument(*anchor_element))
+ ->SendClickedAnchorMetricsToBrowser(
+ anchor_metrics.value().CreateMetricsPtr());
}
return anchor_metrics;
}
-void AnchorElementMetrics::SendMetricsToBrowser() const {
- DCHECK(anchor_element_->GetDocument().GetFrame());
+// static
+void AnchorElementMetrics::MaybeReportViewportMetricsOnLoad(
+ Document& document) {
+ DCHECK(document.GetFrame());
+ if (!base::FeatureList::IsEnabled(features::kRecordAnchorMetricsVisible) ||
+ document.ParentDocument() || !document.View() ||
+ !document.BaseURL().ProtocolIsInHTTPFamily()) {
+ return;
+ }
+
+ Vector<mojom::blink::AnchorElementMetricsPtr> anchor_elements_metrics;
+ AnchorElementMetricsSender* sender =
+ AnchorElementMetricsSender::From(document);
+ for (const auto& member_element : sender->GetAnchorElements()) {
+ const HTMLAnchorElement& anchor_element = *member_element;
+
+ // We ignore anchor elements that are not in the visual viewport.
+ if (!anchor_element.Href().ProtocolIsInHTTPFamily() ||
+ anchor_element.VisibleBoundsInVisualViewport().IsEmpty()) {
+ continue;
+ }
+
+ base::Optional<AnchorElementMetrics> anchor_metric =
+ Create(&anchor_element);
+ if (!anchor_metric.has_value())
+ continue;
+
+ anchor_elements_metrics.push_back(anchor_metric.value().CreateMetricsPtr());
+ if (anchor_elements_metrics.size() > kMaxAnchorElementMetricsSize)
+ return;
+ }
+
+ if (anchor_elements_metrics.IsEmpty())
+ return;
+
+ sender->SendAnchorMetricsVectorToBrowser(std::move(anchor_elements_metrics));
+}
+
+mojom::blink::AnchorElementMetricsPtr AnchorElementMetrics::CreateMetricsPtr()
+ const {
auto metrics = mojom::blink::AnchorElementMetrics::New();
metrics->ratio_area = ratio_area_;
- metrics->ratio_distance_root_top = ratio_distance_root_top_;
+ metrics->ratio_visible_area = ratio_visible_area_;
+ metrics->ratio_distance_top_to_visible_top =
+ ratio_distance_top_to_visible_top_;
metrics->ratio_distance_center_to_visible_top =
ratio_distance_center_to_visible_top_;
+ metrics->ratio_distance_root_top = ratio_distance_root_top_;
+ metrics->ratio_distance_root_bottom = ratio_distance_root_bottom_;
+ metrics->is_in_iframe = is_in_iframe_;
+ metrics->contains_image = contains_image_;
+ metrics->is_same_host = is_same_host_;
+ metrics->is_url_incremented_by_one = is_url_incremented_by_one_;
+
+ metrics->source_url = GetRootDocument(*anchor_element_)->Url();
metrics->target_url = anchor_element_->Href();
- Document* root_document =
- anchor_element_->GetDocument().GetFrame()->LocalFrameRoot().GetDocument();
- AnchorElementMetricsSender::From(*root_document)
- ->SendClickedAnchorMetricsToBrowser(std::move(metrics));
+ return metrics;
}
-void AnchorElementMetrics::RecordMetrics() const {
+void AnchorElementMetrics::RecordMetricsOnClick() const {
UMA_HISTOGRAM_PERCENTAGE("AnchorElementMetrics.Clicked.RatioArea",
- int(ratio_area_ * 100));
+ static_cast<int>(ratio_area_ * 100));
UMA_HISTOGRAM_PERCENTAGE("AnchorElementMetrics.Clicked.RatioVisibleArea",
- int(ratio_visible_area_ * 100));
+ static_cast<int>(ratio_visible_area_ * 100));
UMA_HISTOGRAM_PERCENTAGE(
"AnchorElementMetrics.Clicked.RatioDistanceTopToVisibleTop",
- int(std::min(ratio_distance_top_to_visible_top_, 1.0f) * 100));
+ static_cast<int>(std::min(ratio_distance_top_to_visible_top_, 1.0f) *
+ 100));
UMA_HISTOGRAM_PERCENTAGE(
"AnchorElementMetrics.Clicked.RatioDistanceCenterToVisibleTop",
- int(std::min(ratio_distance_center_to_visible_top_, 1.0f) * 100));
+ static_cast<int>(std::min(ratio_distance_center_to_visible_top_, 1.0f) *
+ 100));
UMA_HISTOGRAM_COUNTS_10000(
"AnchorElementMetrics.Clicked.RatioDistanceRootTop",
- int(std::min(ratio_distance_root_top_, 100.0f) * 100));
+ static_cast<int>(std::min(ratio_distance_root_top_, 100.0f) * 100));
UMA_HISTOGRAM_COUNTS_10000(
"AnchorElementMetrics.Clicked.RatioDistanceRootBottom",
- int(std::min(ratio_distance_root_bottom_, 100.0f) * 100));
+ static_cast<int>(std::min(ratio_distance_root_bottom_, 100.0f) * 100));
+
+ UMA_HISTOGRAM_COUNTS_10000(
+ "AnchorElementMetrics.Clicked.RatioRootHeight",
+ static_cast<int>(std::min(ratio_root_height_, 100.0f) * 100));
UMA_HISTOGRAM_BOOLEAN("AnchorElementMetrics.Clicked.IsInIFrame",
is_in_iframe_);
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 a65889a8b3c..5efa25b71cd 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
@@ -5,32 +5,32 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_ANCHOR_ELEMENT_METRICS_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_ANCHOR_ELEMENT_METRICS_H_
-#include "base/feature_list.h"
#include "base/optional.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/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
namespace blink {
-CORE_EXPORT extern const base::Feature kRecordAnchorMetricsClicked;
-
+class Document;
class HTMLAnchorElement;
+// This class is used to hold metrics of an html anchor element. Metrics are
+// extracted via static methods. Metrics can be recorded and converted to mojom
+// message used to send to the browser process.
class CORE_EXPORT AnchorElementMetrics {
STACK_ALLOCATED();
public:
// Creates AnchorElementMetrics from anchor element if possible. Then records
// the metrics, and sends them to the browser process.
- static base::Optional<AnchorElementMetrics> MaybeExtractMetricsClicked(
+ static base::Optional<AnchorElementMetrics> MaybeReportClickedMetricsOnClick(
const HTMLAnchorElement*);
- // Upload anchor element features.
- void RecordMetrics() const;
-
- // Send anchor element features to browser process.
- void SendMetricsToBrowser() const;
+ // Gets anchor elements from |document|, extracts features of valid anchor
+ // elements and sends to the browser process.
+ static void MaybeReportViewportMetricsOnLoad(Document& document);
// Getters of anchor element features.
float GetRatioArea() const { return ratio_area_; }
@@ -51,9 +51,20 @@ class CORE_EXPORT AnchorElementMetrics {
bool GetIsUrlIncrementedByOne() const { return is_url_incremented_by_one_; }
private:
+ // The maximum number of anchor element metrics allowed to report to the
+ // browser on page load.
+ static const int kMaxAnchorElementMetricsSize;
+
// Extract features of the anchor element.
static base::Optional<AnchorElementMetrics> Create(const HTMLAnchorElement*);
+ // Returns the mojom struct used to send metrics to the browser process.
+ mojom::blink::AnchorElementMetricsPtr CreateMetricsPtr() const;
+
+ // Record metrics of |anchor_element_|. Function is called when the anchor
+ // element is clicked by the user.
+ void RecordMetricsOnClick() const;
+
// The anchor element that this class is associated with.
Member<const HTMLAnchorElement> anchor_element_;
@@ -77,6 +88,9 @@ class CORE_EXPORT AnchorElementMetrics {
// height.
const float ratio_distance_root_bottom_;
+ // The hight of the root document, divided by the viewport height.
+ const float ratio_root_height_;
+
// Whether the anchor element is within an iframe.
const bool is_in_iframe_;
@@ -97,6 +111,7 @@ class CORE_EXPORT AnchorElementMetrics {
float ratio_distance_center_to_visible_top,
float ratio_distance_root_top,
float ratio_distance_root_bottom,
+ float ratio_root_height,
bool is_in_iframe,
bool contains_image,
bool is_same_host,
@@ -109,6 +124,7 @@ class CORE_EXPORT AnchorElementMetrics {
ratio_distance_center_to_visible_top),
ratio_distance_root_top_(ratio_distance_root_top),
ratio_distance_root_bottom_(ratio_distance_root_bottom),
+ ratio_root_height_(ratio_root_height),
is_in_iframe_(is_in_iframe),
contains_image_(contains_image),
is_same_host_(is_same_host),
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 437c346c9f7..c6c2002df32 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
@@ -5,8 +5,10 @@
#include "third_party/blink/renderer/core/html/anchor_element_metrics_sender.h"
#include "services/service_manager/public/cpp/interface_provider.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.h"
+#include "third_party/blink/renderer/core/html/html_anchor_element.h"
namespace blink {
@@ -16,10 +18,10 @@ const char AnchorElementMetricsSender::kSupplementName[] =
AnchorElementMetricsSender::~AnchorElementMetricsSender() = default;
+// static
AnchorElementMetricsSender* AnchorElementMetricsSender::From(
Document& document) {
- // Only root document owns the AnchorElementMetricsSender.
- DCHECK(!document.ParentDocument());
+ DCHECK(HasAnchorElementMetricsSender(document));
AnchorElementMetricsSender* sender =
Supplement<Document>::From<AnchorElementMetricsSender>(document);
@@ -30,21 +32,68 @@ AnchorElementMetricsSender* AnchorElementMetricsSender::From(
return sender;
}
+// static
+bool AnchorElementMetricsSender::HasAnchorElementMetricsSender(
+ Document& document) {
+ bool is_feature_enabled =
+ base::FeatureList::IsEnabled(features::kRecordAnchorMetricsClicked) ||
+ base::FeatureList::IsEnabled(features::kRecordAnchorMetricsVisible);
+ const KURL& url = document.BaseURL();
+ return is_feature_enabled && !document.ParentDocument() && url.IsValid() &&
+ url.ProtocolIsInHTTPFamily();
+}
+
void AnchorElementMetricsSender::SendClickedAnchorMetricsToBrowser(
- mojom::blink::AnchorElementMetricsPtr metric) const {
- metrics_host_->UpdateAnchorElementMetrics(std::move(metric));
+ mojom::blink::AnchorElementMetricsPtr metric) {
+ if (!AssociateInterface())
+ return;
+
+ metrics_host_->ReportAnchorElementMetricsOnClick(std::move(metric));
+}
+
+void AnchorElementMetricsSender::SendAnchorMetricsVectorToBrowser(
+ Vector<mojom::blink::AnchorElementMetricsPtr> metrics) {
+ if (!AssociateInterface())
+ return;
+
+ metrics_host_->ReportAnchorElementMetricsOnLoad(std::move(metrics));
+ has_onload_report_sent_ = true;
+ anchor_elements_.clear();
+}
+
+void AnchorElementMetricsSender::AddAnchorElement(HTMLAnchorElement& element) {
+ if (has_onload_report_sent_)
+ return;
+ anchor_elements_.push_back(element);
+}
+
+const HeapVector<Member<HTMLAnchorElement>>&
+AnchorElementMetricsSender::GetAnchorElements() const {
+ return anchor_elements_;
}
void AnchorElementMetricsSender::Trace(blink::Visitor* visitor) {
+ visitor->Trace(anchor_elements_);
Supplement<Document>::Trace(visitor);
}
+bool AnchorElementMetricsSender::AssociateInterface() {
+ if (metrics_host_)
+ return true;
+
+ Document* document = GetSupplementable();
+ // Unable to associate since no frame is attached.
+ if (!document->GetFrame())
+ return false;
+
+ document->GetFrame()->GetInterfaceProvider().GetInterface(
+ mojo::MakeRequest(&metrics_host_));
+ return true;
+}
+
AnchorElementMetricsSender::AnchorElementMetricsSender(Document& document)
: Supplement<Document>(document) {
DCHECK(!document.ParentDocument());
-
- document.GetFrame()->LocalFrameRoot().GetInterfaceProvider().GetInterface(
- mojo::MakeRequest(&metrics_host_));
}
} // namespace blink
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 d51bac362d8..fd756677afc 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
@@ -9,10 +9,12 @@
#include "third_party/blink/public/mojom/loader/navigation_predictor.mojom-blink.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/supplementable.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
class Document;
+class HTMLAnchorElement;
// AnchorElementMetricsSender is responsible to send anchor element metrics to
// the browser process for a given document.
@@ -30,18 +32,43 @@ class AnchorElementMetricsSender final
// |Document|. Constructs new one if it does not exist.
static AnchorElementMetricsSender* From(Document&);
- // Send metrics of anchor element clicked by the user to the browser.
+ // Returns true if |document| should have associated
+ // AnchorElementMetricsSender.
+ static bool HasAnchorElementMetricsSender(Document& document);
+
+ // Sends metrics of anchor element clicked by the user to the browser.
void SendClickedAnchorMetricsToBrowser(
- mojom::blink::AnchorElementMetricsPtr metric) const;
+ mojom::blink::AnchorElementMetricsPtr metric);
+
+ // Sends metrics of visible anchor elements to the browser.
+ void SendAnchorMetricsVectorToBrowser(
+ Vector<mojom::blink::AnchorElementMetricsPtr> metrics);
+
+ // Adds an anchor element to |anchor_elements_|.
+ void AddAnchorElement(HTMLAnchorElement& element);
+
+ // Returns the stored |anchor_elements_|.
+ const HeapVector<Member<HTMLAnchorElement>>& GetAnchorElements() const;
void Trace(blink::Visitor*) override;
private:
explicit AnchorElementMetricsSender(Document&);
+ // Associates |metrics_host_| with the IPC interface if not already, so it can
+ // be used to send messages. Returns true if associated, false otherwise.
+ bool AssociateInterface();
+
// Browser host to which the anchor element metrics are sent.
mojom::blink::AnchorElementMetricsHostPtr metrics_host_;
+ // Collection of anchor elements in the document.
+ HeapVector<Member<HTMLAnchorElement>> anchor_elements_;
+
+ // If |has_onload_report_sent_| is true, |anchor_elements_| will not accept
+ // new anchor elements.
+ bool has_onload_report_sent_ = false;
+
DISALLOW_COPY_AND_ASSIGN(AnchorElementMetricsSender);
};
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 98bc49e1186..a9baf18fb6f 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
@@ -7,6 +7,7 @@
#include "base/optional.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/html/html_anchor_element.h"
#include "third_party/blink/renderer/core/html/html_iframe_element.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
@@ -31,7 +32,8 @@ class AnchorElementMetricsTest : public SimTest {
ToHTMLAnchorElement(GetDocument().getElementById("anchor"));
anchor_element->SetHref(AtomicString(target));
- return AnchorElementMetrics::MaybeExtractMetricsClicked(anchor_element)
+ return AnchorElementMetrics::MaybeReportClickedMetricsOnClick(
+ anchor_element)
.value()
.GetIsUrlIncrementedByOne();
}
@@ -42,7 +44,7 @@ class AnchorElementMetricsTest : public SimTest {
void SetUp() override {
SimTest::SetUp();
WebView().Resize(WebSize(kViewportWidth, kViewportHeight));
- feature_list_.InitAndEnableFeature(kRecordAnchorMetricsClicked);
+ feature_list_.InitAndEnableFeature(features::kRecordAnchorMetricsClicked);
}
base::test::ScopedFeatureList feature_list_;
@@ -83,16 +85,59 @@ TEST_F(AnchorElementMetricsTest, FinchControl) {
// With feature kRecordAnchorMetricsClicked disabled, we should not see any
// count in histograms.
base::test::ScopedFeatureList disabled_feature_list;
- disabled_feature_list.InitAndDisableFeature(kRecordAnchorMetricsClicked);
- AnchorElementMetrics::MaybeExtractMetricsClicked(anchor_element);
+ disabled_feature_list.InitAndDisableFeature(
+ features::kRecordAnchorMetricsClicked);
+ AnchorElementMetrics::MaybeReportClickedMetricsOnClick(anchor_element);
histogram_tester.ExpectTotalCount("AnchorElementMetrics.Clicked.RatioArea",
0);
// If we enable feature kRecordAnchorMetricsClicked, we should see count is 1
// in histograms.
base::test::ScopedFeatureList enabled_feature_list;
- enabled_feature_list.InitAndEnableFeature(kRecordAnchorMetricsClicked);
- AnchorElementMetrics::MaybeExtractMetricsClicked(anchor_element);
+ enabled_feature_list.InitAndEnableFeature(
+ features::kRecordAnchorMetricsClicked);
+ AnchorElementMetrics::MaybeReportClickedMetricsOnClick(anchor_element);
+ histogram_tester.ExpectTotalCount("AnchorElementMetrics.Clicked.RatioArea",
+ 1);
+}
+
+// Test that non-HTTP URLs are not reported.
+TEST_F(AnchorElementMetricsTest, NonHTTPOnClick) {
+ HistogramTester histogram_tester;
+
+ // Tests that an HTTPS page with a data anchor is not reported when the anchor
+ // is clicked.
+ SimRequest http_resource("https://example.com/", "text/html");
+ LoadURL("https://example.com/");
+ http_resource.Complete("<a id='anchor' href='data://google.com/'>google</a>");
+ HTMLAnchorElement* anchor_element =
+ ToHTMLAnchorElement(GetDocument().getElementById("anchor"));
+
+ AnchorElementMetrics::MaybeReportClickedMetricsOnClick(anchor_element);
+ histogram_tester.ExpectTotalCount("AnchorElementMetrics.Clicked.RatioArea",
+ 0);
+
+ // Tests that a data page with an HTTPS anchor is not reported when the anchor
+ // is clicked.
+ SimRequest data_resource("data://example.com/", "text/html");
+ LoadURL("data://example.com/");
+ data_resource.Complete(
+ "<a id='anchor' href='https://google.com/'>google</a>");
+ anchor_element = ToHTMLAnchorElement(GetDocument().getElementById("anchor"));
+
+ AnchorElementMetrics::MaybeReportClickedMetricsOnClick(anchor_element);
+ histogram_tester.ExpectTotalCount("AnchorElementMetrics.Clicked.RatioArea",
+ 0);
+
+ // Tests that an HTTPS page with an HTTPS anchor is reported when the anchor
+ // is clicked.
+ SimRequest http_resource_2("https://example.com/", "text/html");
+ LoadURL("https://example.com/");
+ http_resource_2.Complete(
+ "<a id='anchor' href='https://google.com/'>google</a>");
+ anchor_element = ToHTMLAnchorElement(GetDocument().getElementById("anchor"));
+
+ AnchorElementMetrics::MaybeReportClickedMetricsOnClick(anchor_element);
histogram_tester.ExpectTotalCount("AnchorElementMetrics.Clicked.RatioArea",
1);
}
@@ -118,7 +163,8 @@ TEST_F(AnchorElementMetricsTest, AnchorFeatureImageLink) {
HTMLAnchorElement* anchor_element = ToHTMLAnchorElement(anchor);
auto feature =
- AnchorElementMetrics::MaybeExtractMetricsClicked(anchor_element).value();
+ AnchorElementMetrics::MaybeReportClickedMetricsOnClick(anchor_element)
+ .value();
EXPECT_FLOAT_EQ(0.25, feature.GetRatioArea());
EXPECT_FLOAT_EQ(0.25, feature.GetRatioVisibleArea());
EXPECT_FLOAT_EQ(0.5, feature.GetRatioDistanceTopToVisibleTop());
@@ -152,7 +198,8 @@ TEST_F(AnchorElementMetricsTest, AnchorFeatureExtract) {
HTMLAnchorElement* anchor_element = ToHTMLAnchorElement(anchor);
auto feature =
- AnchorElementMetrics::MaybeExtractMetricsClicked(anchor_element).value();
+ AnchorElementMetrics::MaybeReportClickedMetricsOnClick(anchor_element)
+ .value();
EXPECT_GT(feature.GetRatioArea(), 0);
EXPECT_FLOAT_EQ(feature.GetRatioDistanceRootTop(), 2);
EXPECT_FLOAT_EQ(feature.GetRatioDistanceTopToVisibleTop(), 2);
@@ -175,7 +222,8 @@ TEST_F(AnchorElementMetricsTest, AnchorFeatureExtract) {
ScrollOffset(0, kViewportHeight * 1.5), kProgrammaticScroll);
auto feature2 =
- AnchorElementMetrics::MaybeExtractMetricsClicked(anchor_element).value();
+ AnchorElementMetrics::MaybeReportClickedMetricsOnClick(anchor_element)
+ .value();
EXPECT_LT(0, feature2.GetRatioVisibleArea());
EXPECT_FLOAT_EQ(0.5, feature2.GetRatioDistanceTopToVisibleTop());
EXPECT_LT(0.5, feature2.GetRatioDistanceCenterToVisibleTop());
@@ -223,7 +271,8 @@ TEST_F(AnchorElementMetricsTest, AnchorFeatureInIframe) {
HTMLAnchorElement* anchor_element = ToHTMLAnchorElement(anchor);
auto feature =
- AnchorElementMetrics::MaybeExtractMetricsClicked(anchor_element).value();
+ AnchorElementMetrics::MaybeReportClickedMetricsOnClick(anchor_element)
+ .value();
EXPECT_LT(0, feature.GetRatioArea());
EXPECT_FLOAT_EQ(0, feature.GetRatioVisibleArea());
EXPECT_FLOAT_EQ(2.5, feature.GetRatioDistanceTopToVisibleTop());
@@ -239,7 +288,8 @@ TEST_F(AnchorElementMetricsTest, AnchorFeatureInIframe) {
ScrollOffset(0, kViewportHeight * 1.8), kProgrammaticScroll);
auto feature2 =
- AnchorElementMetrics::MaybeExtractMetricsClicked(anchor_element).value();
+ AnchorElementMetrics::MaybeReportClickedMetricsOnClick(anchor_element)
+ .value();
EXPECT_LT(0, feature2.GetRatioVisibleArea());
EXPECT_FLOAT_EQ(0.7, feature2.GetRatioDistanceTopToVisibleTop());
EXPECT_FLOAT_EQ(2.5, feature2.GetRatioDistanceRootTop());
@@ -249,7 +299,8 @@ TEST_F(AnchorElementMetricsTest, AnchorFeatureInIframe) {
ScrollOffset(0, kViewportHeight * 0.2), kProgrammaticScroll);
auto feature3 =
- AnchorElementMetrics::MaybeExtractMetricsClicked(anchor_element).value();
+ AnchorElementMetrics::MaybeReportClickedMetricsOnClick(anchor_element)
+ .value();
EXPECT_LT(0, feature3.GetRatioVisibleArea());
EXPECT_FLOAT_EQ(0.5, feature3.GetRatioDistanceTopToVisibleTop());
EXPECT_FLOAT_EQ(2.5, feature3.GetRatioDistanceRootTop());
diff --git a/chromium/third_party/blink/renderer/core/html/canvas/baselines.idl b/chromium/third_party/blink/renderer/core/html/canvas/baselines.idl
new file mode 100644
index 00000000000..e7854c96743
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/html/canvas/baselines.idl
@@ -0,0 +1,9 @@
+// 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.
+
+dictionary Baselines {
+ double alphabetic;
+ double hanging;
+ double ideographic;
+};
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 f0dc7b1ac34..d67b997fa83 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
@@ -30,8 +30,11 @@ namespace blink {
namespace {
-// a small slack period between deadline and current time for safety
-constexpr TimeDelta kSlackBeforeDeadline = TimeDelta::FromMilliseconds(1);
+// small slack period between deadline and current time for safety
+constexpr TimeDelta kCreateBlobSlackBeforeDeadline =
+ TimeDelta::FromMilliseconds(1);
+constexpr TimeDelta kEncodeRowSlackBeforeDeadline =
+ TimeDelta::FromMicroseconds(100);
/* The value is based on user statistics on Nov 2017. */
#if (defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_WIN))
@@ -53,35 +56,19 @@ const double kIdleTaskCompleteTimeoutDelayMs = 5700.0;
const double kIdleTaskCompleteTimeoutDelayMs = 9000.0;
#endif
-bool IsDeadlineNearOrPassed(TimeTicks deadline) {
- return CurrentTimeTicks() >= deadline - kSlackBeforeDeadline;
+bool IsCreateBlobDeadlineNearOrPassed(TimeTicks deadline) {
+ return CurrentTimeTicks() >= deadline - kCreateBlobSlackBeforeDeadline;
}
-String ConvertMimeTypeEnumToString(ImageEncoder::MimeType mime_type_enum) {
- switch (mime_type_enum) {
- case ImageEncoder::kMimeTypePng:
- return "image/png";
- case ImageEncoder::kMimeTypeJpeg:
- return "image/jpeg";
- case ImageEncoder::kMimeTypeWebp:
- return "image/webp";
- default:
- return "image/unknown";
- }
-}
-
-ImageEncoder::MimeType ConvertMimeTypeStringToEnum(const String& mime_type) {
- ImageEncoder::MimeType mime_type_enum;
- if (mime_type == "image/png") {
- mime_type_enum = ImageEncoder::kMimeTypePng;
- } else if (mime_type == "image/jpeg") {
- mime_type_enum = ImageEncoder::kMimeTypeJpeg;
- } else if (mime_type == "image/webp") {
- mime_type_enum = ImageEncoder::kMimeTypeWebp;
- } else {
- mime_type_enum = ImageEncoder::kNumberOfMimeTypeSupported;
- }
- return mime_type_enum;
+bool IsEncodeRowDeadlineNearOrPassed(TimeTicks deadline, size_t image_width) {
+ // Rough estimate of the row encoding time in micro seconds. We will consider
+ // a slack time later to not pass the idle task deadline.
+ int row_encode_time_us = 1000 * (kIdleTaskCompleteTimeoutDelayMs / 4000.0) *
+ (image_width / 4000.0);
+ TimeDelta row_encode_time_delta =
+ TimeDelta::FromMicroseconds(row_encode_time_us);
+ return CurrentTimeTicks() >=
+ deadline - row_encode_time_delta - kEncodeRowSlackBeforeDeadline;
}
void RecordIdleTaskStatusHistogram(
@@ -103,44 +90,44 @@ enum ElapsedTimeHistogramType {
};
void RecordElapsedTimeHistogram(ElapsedTimeHistogramType type,
- ImageEncoder::MimeType mime_type,
+ ImageEncodingMimeType mime_type,
TimeDelta elapsed_time) {
if (type == kInitiateEncodingDelay) {
- if (mime_type == ImageEncoder::kMimeTypePng) {
+ if (mime_type == kMimeTypePng) {
DEFINE_THREAD_SAFE_STATIC_LOCAL(
CustomCountHistogram, to_blob_png_initiate_encoding_counter,
("Blink.Canvas.ToBlob.InitiateEncodingDelay.PNG", 0, 10000000, 50));
to_blob_png_initiate_encoding_counter.CountMicroseconds(elapsed_time);
- } else if (mime_type == ImageEncoder::kMimeTypeJpeg) {
+ } else if (mime_type == kMimeTypeJpeg) {
DEFINE_THREAD_SAFE_STATIC_LOCAL(
CustomCountHistogram, to_blob_jpeg_initiate_encoding_counter,
("Blink.Canvas.ToBlob.InitiateEncodingDelay.JPEG", 0, 10000000, 50));
to_blob_jpeg_initiate_encoding_counter.CountMicroseconds(elapsed_time);
}
} else if (type == kCompleteEncodingDelay) {
- if (mime_type == ImageEncoder::kMimeTypePng) {
+ if (mime_type == kMimeTypePng) {
DEFINE_THREAD_SAFE_STATIC_LOCAL(
CustomCountHistogram, to_blob_png_idle_encode_counter,
("Blink.Canvas.ToBlob.CompleteEncodingDelay.PNG", 0, 10000000, 50));
to_blob_png_idle_encode_counter.CountMicroseconds(elapsed_time);
- } else if (mime_type == ImageEncoder::kMimeTypeJpeg) {
+ } else if (mime_type == kMimeTypeJpeg) {
DEFINE_THREAD_SAFE_STATIC_LOCAL(
CustomCountHistogram, to_blob_jpeg_idle_encode_counter,
("Blink.Canvas.ToBlob.CompleteEncodingDelay.JPEG", 0, 10000000, 50));
to_blob_jpeg_idle_encode_counter.CountMicroseconds(elapsed_time);
}
} else if (type == kToBlobDuration) {
- if (mime_type == ImageEncoder::kMimeTypePng) {
+ if (mime_type == kMimeTypePng) {
DEFINE_THREAD_SAFE_STATIC_LOCAL(
CustomCountHistogram, to_blob_png_counter,
("Blink.Canvas.ToBlobDuration.PNG", 0, 10000000, 50));
to_blob_png_counter.CountMicroseconds(elapsed_time);
- } else if (mime_type == ImageEncoder::kMimeTypeJpeg) {
+ } else if (mime_type == kMimeTypeJpeg) {
DEFINE_THREAD_SAFE_STATIC_LOCAL(
CustomCountHistogram, to_blob_jpeg_counter,
("Blink.Canvas.ToBlobDuration.JPEG", 0, 10000000, 50));
to_blob_jpeg_counter.CountMicroseconds(elapsed_time);
- } else if (mime_type == ImageEncoder::kMimeTypeWebp) {
+ } else if (mime_type == kMimeTypeWebp) {
DEFINE_THREAD_SAFE_STATIC_LOCAL(
CustomCountHistogram, to_blob_webp_counter,
("Blink.Canvas.ToBlobDuration.WEBP", 0, 10000000, 50));
@@ -153,13 +140,13 @@ void RecordElapsedTimeHistogram(ElapsedTimeHistogramType type,
CanvasAsyncBlobCreator* CanvasAsyncBlobCreator::Create(
scoped_refptr<StaticBitmapImage> image,
- const String& mime_type,
+ const ImageEncodingMimeType mime_type,
V8BlobCallback* callback,
ToBlobFunctionType function_type,
TimeTicks start_time,
ExecutionContext* context) {
ImageEncodeOptions options;
- options.setType(mime_type);
+ options.setType(ImageEncodingMimeTypeName(mime_type));
return new CanvasAsyncBlobCreator(image, options, function_type, callback,
start_time, context, nullptr);
}
@@ -184,6 +171,7 @@ CanvasAsyncBlobCreator::CanvasAsyncBlobCreator(
ExecutionContext* context,
ScriptPromiseResolver* resolver)
: fail_encoder_initialization_for_test_(false),
+ enforce_idle_encoding_for_test_(false),
image_(image),
context_(context),
encode_options_(options),
@@ -194,10 +182,9 @@ CanvasAsyncBlobCreator::CanvasAsyncBlobCreator(
script_promise_resolver_(resolver) {
DCHECK(image);
- String mime_type_string = ImageEncoderUtils::ToEncodingMimeType(
+ mime_type_ = ImageEncoderUtils::ToEncodingMimeType(
encode_options_.type(),
ImageEncoderUtils::kEncodeReasonConvertToBlobPromise);
- mime_type_ = ConvertMimeTypeStringToEnum(mime_type_string);
// We use pixmap to access the image pixels. Make the image unaccelerated if
// necessary.
@@ -258,7 +245,7 @@ CanvasAsyncBlobCreator::CanvasAsyncBlobCreator(
// 16 bpc PNG, we need to ensure the color type of the pixmap is
// kRGBA_F16_SkColorType to kick in 16 bit encoding in SkPngEncoder. Since
// SkPixmap only holds a pointer to data, we need a helper data member here.
- if (mime_type_ == ImageEncoder::kMimeTypePng &&
+ if (mime_type_ == kMimeTypePng &&
encode_options_.pixelFormat() == kRGBA16ImagePixelFormatName &&
src_data_.colorType() == kN32_SkColorType) {
size_t data_length = src_data_.width() * src_data_.height() *
@@ -318,9 +305,9 @@ void CanvasAsyncBlobCreator::Dispose() {
}
ImageEncodeOptions CanvasAsyncBlobCreator::GetImageEncodeOptionsForMimeType(
- ImageEncoder::MimeType mime_type) {
+ ImageEncodingMimeType mime_type) {
ImageEncodeOptions encode_options;
- encode_options.setType(ConvertMimeTypeEnumToString(mime_type));
+ encode_options.setType(ImageEncodingMimeTypeName(mime_type));
return encode_options;
}
@@ -328,7 +315,7 @@ bool CanvasAsyncBlobCreator::EncodeImage(const double& quality) {
std::unique_ptr<ImageDataBuffer> buffer = ImageDataBuffer::Create(src_data_);
if (!buffer)
return false;
- return buffer->EncodeImage("image/webp", quality, &encoded_image_);
+ return buffer->EncodeImage(mime_type_, quality, &encoded_image_);
}
void CanvasAsyncBlobCreator::ScheduleAsyncBlobCreation(const double& quality) {
@@ -339,7 +326,17 @@ void CanvasAsyncBlobCreator::ScheduleAsyncBlobCreation(const double& quality) {
WrapPersistent(this)));
return;
}
- if (mime_type_ == ImageEncoder::kMimeTypeWebp) {
+ // Webp encoder does not support progressive encoding. We also don't use idle
+ // encoding for layout tests, since the idle task start and completition
+ // deadlines (6.7s or 13s) bypass the layout 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.
+ bool use_idle_encoding =
+ (mime_type_ != kMimeTypeWebp) &&
+ (enforce_idle_encoding_for_test_ ||
+ !RuntimeEnabledFeatures::NoIdleEncodingForLayoutTestsEnabled());
+
+ if (!use_idle_encoding) {
if (!IsMainThread()) {
DCHECK(function_type_ == kHTMLCanvasConvertToBlobPromise ||
function_type_ == kOffscreenCanvasConvertToBlobPromise);
@@ -416,7 +413,7 @@ void CanvasAsyncBlobCreator::IdleEncodeRows(TimeTicks deadline) {
}
for (int y = num_rows_completed_; y < src_data_.height(); ++y) {
- if (IsDeadlineNearOrPassed(deadline)) {
+ if (IsEncodeRowDeadlineNearOrPassed(deadline, src_data_.width())) {
num_rows_completed_ = y;
Platform::Current()->CurrentThread()->Scheduler()->PostIdleTask(
FROM_HERE, WTF::Bind(&CanvasAsyncBlobCreator::IdleEncodeRows,
@@ -436,7 +433,7 @@ void CanvasAsyncBlobCreator::IdleEncodeRows(TimeTicks deadline) {
TimeDelta elapsed_time =
WTF::CurrentTimeTicks() - schedule_idle_task_start_time_;
RecordElapsedTimeHistogram(kCompleteEncodingDelay, mime_type_, elapsed_time);
- if (IsDeadlineNearOrPassed(deadline)) {
+ if (IsCreateBlobDeadlineNearOrPassed(deadline)) {
context_->GetTaskRunner(TaskType::kCanvasBlobSerialization)
->PostTask(FROM_HERE,
WTF::Bind(&CanvasAsyncBlobCreator::CreateBlobAndReturnResult,
@@ -477,7 +474,7 @@ void CanvasAsyncBlobCreator::CreateBlobAndReturnResult() {
WTF::CurrentTimeTicks() - start_time_);
Blob* result_blob = Blob::Create(encoded_image_.data(), encoded_image_.size(),
- ConvertMimeTypeEnumToString(mime_type_));
+ ImageEncodingMimeTypeName(mime_type_));
if (function_type_ == kHTMLCanvasToBlobCallback) {
context_->GetTaskRunner(TaskType::kCanvasBlobSerialization)
->PostTask(FROM_HERE,
@@ -514,8 +511,6 @@ void CanvasAsyncBlobCreator::CreateNullAndReturnResult() {
void CanvasAsyncBlobCreator::EncodeImageOnEncoderThread(double quality) {
DCHECK(!IsMainThread());
- DCHECK(mime_type_ == ImageEncoder::kMimeTypeWebp);
-
if (!EncodeImage(quality)) {
PostCrossThreadTask(
*parent_frame_task_runner_, FROM_HERE,
@@ -534,7 +529,7 @@ bool CanvasAsyncBlobCreator::InitializeEncoder(double quality) {
// This is solely used for unit tests.
if (fail_encoder_initialization_for_test_)
return false;
- if (mime_type_ == ImageEncoder::kMimeTypeJpeg) {
+ if (mime_type_ == kMimeTypeJpeg) {
SkJpegEncoder::Options options;
options.fQuality = ImageEncoder::ComputeJpegQuality(quality);
options.fAlphaOption = SkJpegEncoder::AlphaOption::kBlendOnBlack;
@@ -548,7 +543,7 @@ bool CanvasAsyncBlobCreator::InitializeEncoder(double quality) {
// formats.
// TODO(zakerinasab): Progressive encoding on webp image formats
// (crbug.com/571399)
- DCHECK_EQ(ImageEncoder::kMimeTypePng, mime_type_);
+ DCHECK_EQ(kMimeTypePng, mime_type_);
SkPngEncoder::Options options;
options.fFilterFlags = SkPngEncoder::FilterFlag::kSub;
options.fZLibLevel = 3;
@@ -573,8 +568,7 @@ void CanvasAsyncBlobCreator::IdleTaskStartTimeoutEvent(double quality) {
idle_task_status_ = kIdleTaskSwitchedToImmediateTask;
SignalTaskSwitchInStartTimeoutEventForTesting();
- DCHECK(mime_type_ == ImageEncoder::kMimeTypePng ||
- mime_type_ == ImageEncoder::kMimeTypeJpeg);
+ DCHECK(mime_type_ == kMimeTypePng || mime_type_ == kMimeTypeJpeg);
if (InitializeEncoder(quality)) {
context_->GetTaskRunner(TaskType::kCanvasBlobSerialization)
->PostTask(
@@ -600,8 +594,7 @@ void CanvasAsyncBlobCreator::IdleTaskCompleteTimeoutEvent() {
idle_task_status_ = kIdleTaskSwitchedToImmediateTask;
SignalTaskSwitchInCompleteTimeoutEventForTesting();
- DCHECK(mime_type_ == ImageEncoder::kMimeTypePng ||
- mime_type_ == ImageEncoder::kMimeTypeJpeg);
+ DCHECK(mime_type_ == kMimeTypePng || mime_type_ == kMimeTypeJpeg);
context_->GetTaskRunner(TaskType::kCanvasBlobSerialization)
->PostTask(
FROM_HERE,
@@ -645,7 +638,7 @@ bool CanvasAsyncBlobCreator::EncodeImageForConvertToBlobTest() {
std::unique_ptr<ImageDataBuffer> buffer = ImageDataBuffer::Create(src_data_);
if (!buffer)
return false;
- return buffer->EncodeImage(encode_options_.type(), encode_options_.quality(),
+ return buffer->EncodeImage(mime_type_, encode_options_.quality(),
&encoded_image_);
}
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 3b2875d712f..d6fccdbe188 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
@@ -15,6 +15,7 @@
#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"
#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/image-encoders/image_encoder.h"
@@ -56,7 +57,7 @@ class CORE_EXPORT CanvasAsyncBlobCreator
};
static CanvasAsyncBlobCreator* Create(scoped_refptr<StaticBitmapImage>,
- const String& mime_type,
+ const ImageEncodingMimeType mime_type,
V8BlobCallback*,
ToBlobFunctionType function_type,
TimeTicks start_time,
@@ -94,7 +95,7 @@ class CORE_EXPORT CanvasAsyncBlobCreator
ExecutionContext*,
ScriptPromiseResolver*);
static ImageEncodeOptions GetImageEncodeOptionsForMimeType(
- ImageEncoder::MimeType);
+ ImageEncodingMimeType);
// Methods are virtual for unit testing
virtual void ScheduleInitiateEncoding(double quality);
virtual void IdleEncodeRows(TimeTicks deadline);
@@ -110,6 +111,7 @@ class CORE_EXPORT CanvasAsyncBlobCreator
protected:
IdleTaskStatus idle_task_status_;
bool fail_encoder_initialization_for_test_;
+ bool enforce_idle_encoding_for_test_;
private:
friend class CanvasAsyncBlobCreatorTest;
@@ -123,7 +125,7 @@ class CORE_EXPORT CanvasAsyncBlobCreator
Member<ExecutionContext> context_;
SkPixmap src_data_;
- ImageEncoder::MimeType mime_type_;
+ ImageEncodingMimeType mime_type_;
const ImageEncodeOptions encode_options_;
ToBlobFunctionType function_type_;
sk_sp<SkData> png_16bit_data_helper_;
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 e3b52699d79..52892e814b8 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
@@ -22,7 +22,7 @@ typedef CanvasAsyncBlobCreator::IdleTaskStatus IdleTaskStatus;
class MockCanvasAsyncBlobCreator : public CanvasAsyncBlobCreator {
public:
MockCanvasAsyncBlobCreator(scoped_refptr<StaticBitmapImage> image,
- ImageEncoder::MimeType mime_type,
+ ImageEncodingMimeType mime_type,
Document* document,
bool fail_encoder_initialization = false)
: CanvasAsyncBlobCreator(
@@ -35,6 +35,7 @@ class MockCanvasAsyncBlobCreator : public CanvasAsyncBlobCreator {
nullptr) {
if (fail_encoder_initialization)
fail_encoder_initialization_for_test_ = true;
+ enforce_idle_encoding_for_test_ = true;
}
CanvasAsyncBlobCreator::IdleTaskStatus GetIdleTaskStatus() {
@@ -73,9 +74,7 @@ class MockCanvasAsyncBlobCreatorWithoutStart
public:
MockCanvasAsyncBlobCreatorWithoutStart(scoped_refptr<StaticBitmapImage> image,
Document* document)
- : MockCanvasAsyncBlobCreator(image,
- ImageEncoder::kMimeTypePng,
- document) {}
+ : MockCanvasAsyncBlobCreator(image, kMimeTypePng, document) {}
protected:
void ScheduleInitiateEncoding(double) override {
@@ -94,7 +93,7 @@ class MockCanvasAsyncBlobCreatorWithoutComplete
Document* document,
bool fail_encoder_initialization = false)
: MockCanvasAsyncBlobCreator(image,
- ImageEncoder::kMimeTypePng,
+ kMimeTypePng,
document,
fail_encoder_initialization) {}
@@ -177,7 +176,7 @@ TEST_F(CanvasAsyncBlobCreatorTest,
EXPECT_CALL(*(AsyncBlobCreator()),
SignalTaskSwitchInStartTimeoutEventForTesting());
- AsyncBlobCreator()->ScheduleAsyncBlobCreation(true);
+ AsyncBlobCreator()->ScheduleAsyncBlobCreation(1.0);
test::EnterRunLoop();
testing::Mock::VerifyAndClearExpectations(AsyncBlobCreator());
@@ -195,7 +194,7 @@ TEST_F(CanvasAsyncBlobCreatorTest,
EXPECT_CALL(*(AsyncBlobCreator()),
SignalTaskSwitchInCompleteTimeoutEventForTesting());
- AsyncBlobCreator()->ScheduleAsyncBlobCreation(true);
+ AsyncBlobCreator()->ScheduleAsyncBlobCreation(1.0);
test::EnterRunLoop();
testing::Mock::VerifyAndClearExpectations(AsyncBlobCreator());
@@ -209,7 +208,7 @@ TEST_F(CanvasAsyncBlobCreatorTest, IdleTaskFailedWhenStartTimeoutEventHappens) {
// the idle task status.
PrepareMockCanvasAsyncBlobCreatorFail();
- AsyncBlobCreator()->ScheduleAsyncBlobCreation(true);
+ AsyncBlobCreator()->ScheduleAsyncBlobCreation(1.0);
test::EnterRunLoop();
EXPECT_EQ(IdleTaskStatus::kIdleTaskFailed,
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 4e74a0202bb..6c893781a14 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
@@ -91,6 +91,12 @@ class CORE_EXPORT CanvasRenderingContext : public ScriptWrappable,
virtual ContextType GetContextType() const = 0;
virtual bool IsComposited() const = 0;
virtual bool IsAccelerated() const = 0;
+ virtual bool IsOriginTopLeft() const {
+ // Canvas contexts have the origin of coordinates on the top left corner.
+ // Accelerated resources (e.g. GPU textures) have their origin of
+ // coordinates in the uppper left corner.
+ return !IsAccelerated();
+ }
virtual bool ShouldAntialias() const { return false; }
virtual void SetIsHidden(bool) = 0;
virtual bool isContextLost() const { return true; }
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 76934b8437e..68451d9e07d 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
@@ -7,6 +7,7 @@
#include "third_party/blink/public/platform/platform.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"
#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/static_bitmap_image.h"
@@ -60,6 +61,12 @@ bool CanvasRenderingContextHost::Is2d() const {
CanvasResourceProvider*
CanvasRenderingContextHost::GetOrCreateCanvasResourceProvider(
AccelerationHint hint) {
+ return GetOrCreateCanvasResourceProviderImpl(hint);
+}
+
+CanvasResourceProvider*
+CanvasRenderingContextHost::GetOrCreateCanvasResourceProviderImpl(
+ AccelerationHint hint) {
if (!ResourceProvider() && !did_fail_to_create_resource_provider_) {
if (IsValidImageSize(Size())) {
base::WeakPtr<CanvasResourceDispatcher> dispatcher =
@@ -67,37 +74,45 @@ CanvasRenderingContextHost::GetOrCreateCanvasResourceProvider(
? GetOrCreateResourceDispatcher()->GetWeakPtr()
: nullptr;
if (Is3d()) {
+ const CanvasResourceProvider::ResourceUsage usage =
+ SharedGpuContext::IsGpuCompositingEnabled()
+ ? CanvasResourceProvider::kAcceleratedCompositedResourceUsage
+ : CanvasResourceProvider::kSoftwareCompositedResourceUsage;
+
CanvasResourceProvider::PresentationMode presentation_mode =
RuntimeEnabledFeatures::WebGLImageChromiumEnabled()
? CanvasResourceProvider::kAllowImageChromiumPresentationMode
: CanvasResourceProvider::kDefaultPresentationMode;
+ const bool is_origin_top_left =
+ !SharedGpuContext::IsGpuCompositingEnabled();
+
ReplaceResourceProvider(CanvasResourceProvider::Create(
- Size(),
- SharedGpuContext::IsGpuCompositingEnabled()
- ? CanvasResourceProvider::kAcceleratedCompositedResourceUsage
- : CanvasResourceProvider::kSoftwareCompositedResourceUsage,
- SharedGpuContext::ContextProviderWrapper(),
- 0, // msaa_sample_count
- ColorParams(), presentation_mode, std::move(dispatcher)));
+ Size(), usage, SharedGpuContext::ContextProviderWrapper(),
+ 0 /* msaa_sample_count */, ColorParams(), presentation_mode,
+ std::move(dispatcher), is_origin_top_left));
} else {
- bool want_acceleration =
+ DCHECK(Is2d());
+ const bool want_acceleration =
hint == kPreferAcceleration && ShouldAccelerate2dContext();
- CanvasResourceProvider::ResourceUsage usage =
+ const CanvasResourceProvider::ResourceUsage usage =
want_acceleration
? CanvasResourceProvider::kAcceleratedCompositedResourceUsage
: CanvasResourceProvider::kSoftwareCompositedResourceUsage;
- CanvasResourceProvider::PresentationMode presentation_mode =
+ const CanvasResourceProvider::PresentationMode presentation_mode =
RuntimeEnabledFeatures::Canvas2dImageChromiumEnabled()
? CanvasResourceProvider::kAllowImageChromiumPresentationMode
: CanvasResourceProvider::kDefaultPresentationMode;
+ const bool is_origin_top_left =
+ !want_acceleration || LowLatencyEnabled();
+
ReplaceResourceProvider(CanvasResourceProvider::Create(
Size(), usage, SharedGpuContext::ContextProviderWrapper(),
GetMSAASampleCountFor2dContext(), ColorParams(), presentation_mode,
- std::move(dispatcher)));
+ std::move(dispatcher), is_origin_top_left));
if (ResourceProvider()) {
// Always save an initial frame, to support resetting the top level
@@ -108,9 +123,8 @@ CanvasRenderingContextHost::GetOrCreateCanvasResourceProvider(
}
}
}
- if (!ResourceProvider()) {
+ if (!ResourceProvider())
did_fail_to_create_resource_provider_ = true;
- }
}
return ResourceProvider();
}
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 e54af262dec..cc614483968 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
@@ -9,6 +9,7 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/events/event_dispatcher.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
+#include "third_party/blink/renderer/core/html/canvas/canvas_image_source.h"
#include "third_party/blink/renderer/core/html/canvas/image_encode_options.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
@@ -28,6 +29,7 @@ class KURL;
class StaticBitmapImage;
class CORE_EXPORT CanvasRenderingContextHost : public CanvasResourceHost,
+ public CanvasImageSource,
public GarbageCollectedMixin {
public:
CanvasRenderingContextHost();
@@ -64,8 +66,6 @@ class CORE_EXPORT CanvasRenderingContextHost : public CanvasResourceHost,
virtual bool ShouldAccelerate2dContext() const = 0;
virtual unsigned GetMSAASampleCountFor2dContext() const = 0;
- // TODO(fserb): remove this.
- virtual bool IsOffscreenCanvas() const { return false; }
virtual bool IsNeutered() const { return false; }
virtual void Commit(scoped_refptr<CanvasResource> canvas_resource,
@@ -73,10 +73,16 @@ class CORE_EXPORT CanvasRenderingContextHost : public CanvasResourceHost,
bool IsPaintable() const;
+ // Required by template functions in WebGLRenderingContextBase
+ int width() const { return Size().Width(); }
+ int height() const { return Size().Height(); }
+
// Partial CanvasResourceHost implementation
void RestoreCanvasMatrixClipStack(cc::PaintCanvas*) const final;
- CanvasResourceProvider* GetOrCreateCanvasResourceProvider(
+ CanvasResourceProvider* GetOrCreateCanvasResourceProviderImpl(
AccelerationHint hint) final;
+ CanvasResourceProvider* GetOrCreateCanvasResourceProvider(
+ AccelerationHint hint) override;
bool Is3d() const;
bool Is2d() const;
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 8596b77e5f7..3912c3b63c0 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
@@ -144,9 +144,8 @@ intptr_t HTMLCanvasElement::global_gpu_memory_usage_ = 0;
unsigned HTMLCanvasElement::global_accelerated_context_count_ = 0;
HTMLCanvasElement::~HTMLCanvasElement() {
- if (surface_layer_bridge_ && surface_layer_bridge_->GetCcLayer()) {
+ if (surface_layer_bridge_ && surface_layer_bridge_->GetCcLayer())
GraphicsLayer::UnregisterContentsLayer(surface_layer_bridge_->GetCcLayer());
- }
v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(
-externally_allocated_memory_);
}
@@ -188,7 +187,7 @@ LayoutObject* HTMLCanvasElement::CreateLayoutObject(
}
Node::InsertionNotificationRequest HTMLCanvasElement::InsertedInto(
- ContainerNode* node) {
+ ContainerNode& node) {
SetIsInCanvasSubtree(true);
return HTMLElement::InsertedInto(node);
}
@@ -257,8 +256,9 @@ CanvasRenderingContext* HTMLCanvasElement::GetCanvasRenderingContext(
// Unknown type.
if (context_type == CanvasRenderingContext::kContextTypeCount ||
(context_type == CanvasRenderingContext::kContextXRPresent &&
- !OriginTrials::WebXREnabled(&GetDocument())))
+ !OriginTrials::WebXREnabled(&GetDocument()))) {
return nullptr;
+ }
// Log the aliased context type used.
if (!context_) {
@@ -296,9 +296,8 @@ CanvasRenderingContext* HTMLCanvasElement::GetCanvasRenderingContext(
probe::didCreateCanvasContext(&GetDocument());
- if (Is3d()) {
+ if (Is3d())
UpdateMemoryUsage();
- }
LayoutObject* layout_object = GetLayoutObject();
if (layout_object && Is2d() && !context_->CreationAttributes().alpha) {
@@ -336,40 +335,33 @@ bool HTMLCanvasElement::IsAccelerated() const {
bool HTMLCanvasElement::IsWebGL1Enabled() const {
Document& document = GetDocument();
LocalFrame* frame = document.GetFrame();
- if (frame) {
- Settings* settings = frame->GetSettings();
- if (settings && settings->GetWebGL1Enabled())
- return true;
- }
- return false;
+ if (!frame)
+ return false;
+ Settings* settings = frame->GetSettings();
+ return settings && settings->GetWebGL1Enabled();
}
bool HTMLCanvasElement::IsWebGL2Enabled() const {
Document& document = GetDocument();
LocalFrame* frame = document.GetFrame();
- if (frame) {
- Settings* settings = frame->GetSettings();
- if (settings && settings->GetWebGL2Enabled())
- return true;
- }
- return false;
+ if (!frame)
+ return false;
+ Settings* settings = frame->GetSettings();
+ return settings && settings->GetWebGL2Enabled();
}
bool HTMLCanvasElement::IsWebGLBlocked() const {
Document& document = GetDocument();
LocalFrame* frame = document.GetFrame();
- if (frame && frame->Client()->ShouldBlockWebGL())
- return true;
- return false;
+ return frame && frame->Client()->ShouldBlockWebGL();
}
void HTMLCanvasElement::DidDraw(const FloatRect& rect) {
if (rect.IsEmpty())
return;
canvas_is_clear_ = false;
- ClearCopiedImage();
if (GetLayoutObject() && !LowLatencyEnabled())
- GetLayoutObject()->SetMayNeedPaintInvalidation();
+ GetLayoutObject()->SetShouldCheckForPaintInvalidation();
if (Is2d() && context_->ShouldAntialias() && GetPage() &&
GetPage()->DeviceScaleFactorDeprecated() > 1.0f) {
FloatRect inflated_rect = rect;
@@ -415,19 +407,28 @@ void HTMLCanvasElement::FinalizeFrame() {
if (!LowLatencyEnabled())
canvas2d_bridge_->FinalizeFrame();
+ }
- if (LowLatencyEnabled() && !dirty_rect_.IsEmpty() &&
- GetOrCreateCanvasResourceProvider(kPreferAcceleration)) {
+ if (LowLatencyEnabled() && !dirty_rect_.IsEmpty()) {
+ if (GetOrCreateCanvasResourceProvider(kPreferAcceleration)) {
+ ResourceProvider()->TryEnableSingleBuffering();
+ if (canvas2d_bridge_)
+ canvas2d_bridge_->FlushRecording();
// Push a frame
base::TimeTicks start_time = WTF::CurrentTimeTicks();
- scoped_refptr<StaticBitmapImage> image =
- canvas2d_bridge_->NewImageSnapshot(kPreferAcceleration);
- FloatRect src_rect(0, 0, Size().Width(), Size().Height());
+ if (Is3d())
+ context_->PaintRenderingResultsToCanvas(kBackBuffer);
+ scoped_refptr<CanvasResource> canvas_resource =
+ ResourceProvider()->ProduceFrame();
+ const FloatRect src_rect(0, 0, Size().Width(), Size().Height());
dirty_rect_.Intersect(src_rect);
- IntRect int_dirty = EnclosingIntRect(dirty_rect_);
- SkIRect damage_rect = SkIRect::MakeXYWH(
+ const IntRect int_dirty = EnclosingIntRect(dirty_rect_);
+ const SkIRect damage_rect = SkIRect::MakeXYWH(
int_dirty.X(), int_dirty.Y(), int_dirty.Width(), int_dirty.Height());
- frame_dispatcher_->DispatchFrameSync(image, start_time, damage_rect);
+ const bool needs_vertical_flip = !RenderingContext()->IsOriginTopLeft();
+ frame_dispatcher_->DispatchFrameSync(std::move(canvas_resource),
+ start_time, damage_rect,
+ needs_vertical_flip);
(void)start_time;
(void)damage_rect;
dirty_rect_ = FloatRect();
@@ -451,15 +452,13 @@ void HTMLCanvasElement::DisableAcceleration(
unaccelerated_bridge_used_for_testing) {
// Create and configure an unaccelerated Canvas2DLayerBridge.
std::unique_ptr<Canvas2DLayerBridge> bridge;
- if (unaccelerated_bridge_used_for_testing) {
+ if (unaccelerated_bridge_used_for_testing)
bridge = std::move(unaccelerated_bridge_used_for_testing);
- } else {
+ else
bridge = CreateUnaccelerated2dBuffer();
- }
- if (bridge && canvas2d_bridge_) {
+ if (bridge && canvas2d_bridge_)
ReplaceExisting2dLayerBridge(std::move(bridge));
- }
// We must force a paint invalidation on the canvas even if it's
// content did not change because it layer was destroyed.
@@ -484,7 +483,7 @@ void HTMLCanvasElement::DoDeferredPaintInvalidation() {
FloatRect invalidation_rect;
if (layout_box) {
- FloatRect content_rect(layout_box->ContentBoxRect());
+ FloatRect content_rect(layout_box->PhysicalContentBoxRect());
FloatRect mapped_dirty_rect =
MapRect(dirty_rect_, src_rect, content_rect);
if (context_->IsComposited()) {
@@ -500,14 +499,12 @@ void HTMLCanvasElement::DoDeferredPaintInvalidation() {
if (dirty_rect_.IsEmpty())
return;
- if (canvas2d_bridge_) {
+ if (canvas2d_bridge_)
canvas2d_bridge_->DoPaintInvalidation(invalidation_rect);
- }
}
- if (context_ && HasImageBitmapContext() && context_->CcLayer()) {
+ if (context_ && HasImageBitmapContext() && context_->CcLayer())
context_->CcLayer()->SetNeedsDisplay();
- }
NotifyListenersCanvasChanged();
did_notify_listeners_for_current_frame_ = true;
@@ -522,7 +519,7 @@ 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->ContentBoxRect());
+ FloatRect content_rect(layout_box->PhysicalContentBoxRect());
if (content_rect.Width() > src_rect.Width() ||
content_rect.Height() > src_rect.Height()) {
dirty_rect_.Inflate(0.5);
@@ -552,14 +549,16 @@ void HTMLCanvasElement::Reset() {
unsigned w = 0;
AtomicString value = getAttribute(widthAttr);
if (value.IsEmpty() || !ParseHTMLNonNegativeInteger(value, w) ||
- w > 0x7fffffffu)
+ w > 0x7fffffffu) {
w = kDefaultCanvasWidth;
+ }
unsigned h = 0;
value = getAttribute(heightAttr);
if (value.IsEmpty() || !ParseHTMLNonNegativeInteger(value, h) ||
- h > 0x7fffffffu)
+ h > 0x7fffffffu) {
h = kDefaultCanvasHeight;
+ }
if (Is2d()) {
context_->Reset();
@@ -620,9 +619,8 @@ void HTMLCanvasElement::NotifyListenersCanvasChanged() {
bool listener_needs_new_frame_capture = false;
for (const CanvasDrawListener* listener : listeners_) {
- if (listener->NeedsNewFrame()) {
+ if (listener->NeedsNewFrame())
listener_needs_new_frame_capture = true;
- }
}
if (listener_needs_new_frame_capture) {
@@ -634,9 +632,8 @@ void HTMLCanvasElement::NotifyListenersCanvasChanged() {
sk_sp<SkImage> image =
source_image->PaintImageForCurrentFrame().GetSkImage();
for (CanvasDrawListener* listener : listeners_) {
- if (listener->NeedsNewFrame()) {
+ if (listener->NeedsNewFrame())
listener->SendNewFrame(image, source_image->ContextProviderWrapper());
- }
}
}
}
@@ -691,11 +688,10 @@ void HTMLCanvasElement::Paint(GraphicsContext& context, const LayoutRect& r) {
if (!context_ && !PlaceholderFrame())
return;
- if (Is3d()) {
+ if (Is3d())
context_->SetFilterQuality(FilterQuality());
- } else if (canvas2d_bridge_) {
+ else if (canvas2d_bridge_)
canvas2d_bridge_->UpdateFilterQuality();
- }
if (HasResourceProvider() && !canvas_is_clear_)
PaintTiming::From(GetDocument()).MarkFirstContentfulPaint();
@@ -752,20 +748,18 @@ void HTMLCanvasElement::SetSurfaceSize(const IntSize& size) {
size_ = size;
did_fail_to_create_resource_provider_ = false;
DiscardResourceProvider();
- ClearCopiedImage();
- if (Is2d() && context_->isContextLost()) {
+ if (Is2d() && context_->isContextLost())
context_->DidSetSurfaceSize();
- }
if (frame_dispatcher_)
frame_dispatcher_->Reshape(size_);
}
const AtomicString HTMLCanvasElement::ImageSourceURL() const {
- return AtomicString(
- ToDataURLInternal(ImageEncoderUtils::kDefaultMimeType, 0, kFrontBuffer));
+ return AtomicString(ToDataURLInternal(
+ ImageEncoderUtils::kDefaultRequestedMimeType, 0, kFrontBuffer));
}
-scoped_refptr<StaticBitmapImage> HTMLCanvasElement::ToStaticBitmapImage(
+scoped_refptr<StaticBitmapImage> HTMLCanvasElement::Snapshot(
SourceDrawingBuffer source_buffer,
AccelerationHint hint) const {
if (size_.IsEmpty())
@@ -814,21 +808,22 @@ String HTMLCanvasElement::ToDataURLInternal(
if (!IsPaintable())
return String("data:,");
- String encoding_mime_type = ImageEncoderUtils::ToEncodingMimeType(
- mime_type, ImageEncoderUtils::kEncodeReasonToDataURL);
+ ImageEncodingMimeType encoding_mime_type =
+ ImageEncoderUtils::ToEncodingMimeType(
+ mime_type, ImageEncoderUtils::kEncodeReasonToDataURL);
base::Optional<ScopedUsHistogramTimer> timer;
- if (encoding_mime_type == "image/png") {
+ if (encoding_mime_type == kMimeTypePng) {
DEFINE_THREAD_SAFE_STATIC_LOCAL(
CustomCountHistogram, scoped_us_counter_png,
("Blink.Canvas.ToDataURL.PNG", 0, 10000000, 50));
timer.emplace(scoped_us_counter_png);
- } else if (encoding_mime_type == "image/jpeg") {
+ } else if (encoding_mime_type == kMimeTypeJpeg) {
DEFINE_THREAD_SAFE_STATIC_LOCAL(
CustomCountHistogram, scoped_us_counter_jpeg,
("Blink.Canvas.ToDataURL.JPEG", 0, 10000000, 50));
timer.emplace(scoped_us_counter_jpeg);
- } else if (encoding_mime_type == "image/webp") {
+ } else if (encoding_mime_type == kMimeTypeWebp) {
DEFINE_THREAD_SAFE_STATIC_LOCAL(
CustomCountHistogram, scoped_us_counter_webp,
("Blink.Canvas.ToDataURL.WEBP", 0, 10000000, 50));
@@ -839,7 +834,7 @@ String HTMLCanvasElement::ToDataURLInternal(
}
scoped_refptr<StaticBitmapImage> image_bitmap =
- ToStaticBitmapImage(source_buffer, kPreferNoAcceleration);
+ Snapshot(source_buffer, kPreferNoAcceleration);
if (image_bitmap) {
std::unique_ptr<ImageDataBuffer> data_buffer =
ImageDataBuffer::Create(image_bitmap);
@@ -860,9 +855,8 @@ String HTMLCanvasElement::toDataURL(const String& mime_type,
double quality = kUndefinedQualityValue;
if (!quality_argument.IsEmpty()) {
v8::Local<v8::Value> v8_value = quality_argument.V8Value();
- if (v8_value->IsNumber()) {
+ if (v8_value->IsNumber())
quality = v8_value.As<v8::Number>()->Value();
- }
}
return ToDataURLInternal(mime_type, quality, kBackBuffer);
}
@@ -893,17 +887,17 @@ void HTMLCanvasElement::toBlob(V8BlobCallback* callback,
double quality = kUndefinedQualityValue;
if (!quality_argument.IsEmpty()) {
v8::Local<v8::Value> v8_value = quality_argument.V8Value();
- if (v8_value->IsNumber()) {
+ if (v8_value->IsNumber())
quality = v8_value.As<v8::Number>()->Value();
- }
}
- String encoding_mime_type = ImageEncoderUtils::ToEncodingMimeType(
- mime_type, ImageEncoderUtils::kEncodeReasonToBlobCallback);
+ ImageEncodingMimeType encoding_mime_type =
+ ImageEncoderUtils::ToEncodingMimeType(
+ mime_type, ImageEncoderUtils::kEncodeReasonToBlobCallback);
CanvasAsyncBlobCreator* async_creator = nullptr;
scoped_refptr<StaticBitmapImage> image_bitmap =
- ToStaticBitmapImage(kBackBuffer, kPreferNoAcceleration);
+ Snapshot(kBackBuffer, kPreferNoAcceleration);
if (image_bitmap) {
async_creator = CanvasAsyncBlobCreator::Create(
image_bitmap, encoding_mime_type, callback,
@@ -922,7 +916,6 @@ void HTMLCanvasElement::toBlob(V8BlobCallback* callback,
V8BlobCallback>::InvokeAndReportException,
WrapPersistent(ToV8PersistentCallbackFunction(callback)),
nullptr, nullptr));
- return;
}
}
@@ -936,8 +929,9 @@ void HTMLCanvasElement::RemoveListener(CanvasDrawListener* listener) {
bool HTMLCanvasElement::OriginClean() const {
if (GetDocument().GetSettings() &&
- GetDocument().GetSettings()->GetDisableReadingFromCanvas())
+ GetDocument().GetSettings()->GetDisableReadingFromCanvas()) {
return false;
+ }
if (PlaceholderFrame())
return PlaceholderFrame()->OriginClean();
return origin_clean_;
@@ -963,10 +957,6 @@ bool HTMLCanvasElement::ShouldAccelerate(AccelerationCriteria criteria) const {
if (context_ && !Is2d())
return false;
- // TODO(crbug.com/789232): Make low latency mode work with GPU acceleration
- if (LowLatencyEnabled())
- return false;
-
// 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.
@@ -983,8 +973,9 @@ bool HTMLCanvasElement::ShouldAccelerate(AccelerationCriteria criteria) const {
if (criteria != kIgnoreResourceLimitCriteria) {
Settings* settings = GetDocument().GetSettings();
if (!settings ||
- canvas_pixel_count < settings->GetMinimumAccelerated2dCanvasSize())
+ canvas_pixel_count < settings->GetMinimumAccelerated2dCanvasSize()) {
return false;
+ }
// When GPU allocated memory runs low (due to having created too many
// accelerated canvases), the compositor starves and browser becomes laggy.
@@ -1014,12 +1005,9 @@ bool HTMLCanvasElement::ShouldAccelerate(AccelerationCriteria criteria) const {
}
unsigned HTMLCanvasElement::GetMSAASampleCountFor2dContext() const {
- unsigned msaa_sample_count = 0;
- if (GetDocument().GetSettings()) {
- msaa_sample_count =
- GetDocument().GetSettings()->GetAccelerated2dCanvasMSAASampleCount();
- }
- return msaa_sample_count;
+ if (!GetDocument().GetSettings())
+ return 0;
+ return GetDocument().GetSettings()->GetAccelerated2dCanvasMSAASampleCount();
}
std::unique_ptr<Canvas2DLayerBridge>
@@ -1067,19 +1055,16 @@ void HTMLCanvasElement::SetCanvas2DLayerBridgeInternal(
if (external_canvas2d_bridge->IsValid())
canvas2d_bridge_ = std::move(external_canvas2d_bridge);
} else {
- if (ShouldAccelerate(kNormalAccelerationCriteria)) {
+ if (ShouldAccelerate(kNormalAccelerationCriteria))
canvas2d_bridge_ = CreateAccelerated2dBuffer();
- }
- if (!canvas2d_bridge_) {
+ if (!canvas2d_bridge_)
canvas2d_bridge_ = CreateUnaccelerated2dBuffer();
- }
}
- if (canvas2d_bridge_) {
+ if (canvas2d_bridge_)
canvas2d_bridge_->SetCanvasResourceHost(this);
- } else {
+ else
return;
- }
did_fail_to_create_resource_provider_ = false;
UpdateMemoryUsage();
@@ -1089,8 +1074,9 @@ void HTMLCanvasElement::SetCanvas2DLayerBridgeInternal(
// consistency, we don't want to apply AA in accelerated canvases but not in
// unaccelerated canvases.
if (!GetMSAASampleCountFor2dContext() && GetDocument().GetSettings() &&
- !GetDocument().GetSettings()->GetAntialiased2dCanvasEnabled())
+ !GetDocument().GetSettings()->GetAntialiased2dCanvasEnabled()) {
context_->SetShouldAntialias(false);
+ }
if (context_)
SetNeedsCompositingUpdate();
@@ -1118,9 +1104,8 @@ Canvas2DLayerBridge* HTMLCanvasElement::GetOrCreateCanvas2DLayerBridge() {
DCHECK(Is2d());
if (!canvas2d_bridge_ && !did_fail_to_create_resource_provider_) {
SetCanvas2DLayerBridgeInternal(nullptr);
- if (did_fail_to_create_resource_provider_ && !Size().IsEmpty()) {
+ if (did_fail_to_create_resource_provider_ && !Size().IsEmpty())
context_->LoseContext(CanvasRenderingContext::kSyntheticLostContext);
- }
}
return canvas2d_bridge_.get();
}
@@ -1134,58 +1119,12 @@ void HTMLCanvasElement::SetCanvas2DLayerBridgeForTesting(
SetCanvas2DLayerBridgeInternal(std::move(bridge));
}
-scoped_refptr<Image> HTMLCanvasElement::CopiedImage(
- SourceDrawingBuffer source_buffer,
- AccelerationHint hint) {
- if (SurfaceLayerBridge()) {
- return PlaceholderFrame()->Bitmap();
- }
-
- if (!IsPaintable())
- return nullptr;
-
- if (!context_)
- return CreateTransparentImage(Size());
-
- if (HasImageBitmapContext()) {
- scoped_refptr<Image> image = context_->GetImage(hint);
- // TODO(fserb): return image?
- if (image)
- return context_->GetImage(hint);
- // Special case: transferFromImageBitmap is not yet called.
- sk_sp<SkSurface> surface =
- SkSurface::MakeRasterN32Premul(width(), height());
- return StaticBitmapImage::Create(surface->makeImageSnapshot());
- }
-
- bool need_to_update = !copied_image_;
- // The concept of SourceDrawingBuffer is valid on only WebGL.
- if (context_->Is3d())
- need_to_update |= context_->PaintRenderingResultsToCanvas(source_buffer);
- if (need_to_update) {
- if (Is2d() && GetOrCreateCanvas2DLayerBridge()) {
- copied_image_ = canvas2d_bridge_->NewImageSnapshot(hint);
- } else if (Is3d() && GetOrCreateCanvasResourceProvider(hint)) {
- copied_image_ = ResourceProvider()->Snapshot();
- }
- UpdateMemoryUsage();
- }
- return copied_image_;
-}
-
void HTMLCanvasElement::DiscardResourceProvider() {
canvas2d_bridge_.reset();
CanvasResourceHost::DiscardResourceProvider();
dirty_rect_ = FloatRect();
}
-void HTMLCanvasElement::ClearCopiedImage() {
- if (copied_image_) {
- copied_image_ = nullptr;
- UpdateMemoryUsage();
- }
-}
-
void HTMLCanvasElement::PageVisibilityChanged() {
bool hidden = !GetPage()->IsPageVisible();
SetSuspendOffscreenCanvasAnimation(hidden);
@@ -1194,12 +1133,8 @@ void HTMLCanvasElement::PageVisibilityChanged() {
return;
context_->SetIsHidden(hidden);
- if (hidden) {
- ClearCopiedImage();
- if (Is3d()) {
- DiscardResourceProvider();
- }
- }
+ if (hidden && Is3d())
+ DiscardResourceProvider();
}
void HTMLCanvasElement::ContextDestroyed(ExecutionContext*) {
@@ -1275,11 +1210,10 @@ scoped_refptr<Image> HTMLCanvasElement::GetSourceImageForCanvas(
// use paintRenderingResultsToCanvas instead of getImage in order to keep a
// cached copy of the backing in the canvas's resource provider.
RenderingContext()->PaintRenderingResultsToCanvas(kBackBuffer);
- if (ResourceProvider()) {
+ if (ResourceProvider())
image = ResourceProvider()->Snapshot();
- } else {
+ else
image = CreateTransparentImage(Size());
- }
} else {
if (CanvasHeuristicParameters::kDisableAccelerationToAvoidReadbacks &&
!RuntimeEnabledFeatures::Canvas2dFixedRenderingModeEnabled() &&
@@ -1288,16 +1222,14 @@ scoped_refptr<Image> HTMLCanvasElement::GetSourceImageForCanvas(
DisableAcceleration();
}
image = RenderingContext()->GetImage(hint);
- if (!image) {
+ if (!image)
image = CreateTransparentImage(Size());
- }
}
- if (image) {
+ if (image)
*status = kNormalSourceImageStatus;
- } else {
+ else
*status = kInvalidSourceImageStatus;
- }
return image;
}
@@ -1372,8 +1304,9 @@ bool HTMLCanvasElement::IsSupportedInteractiveCanvasFallback(
if (auto* input_element = ToHTMLInputElementOrNull(element)) {
if (input_element->type() == InputTypeNames::checkbox ||
input_element->type() == InputTypeNames::radio ||
- input_element->IsTextButton())
+ input_element->IsTextButton()) {
return true;
+ }
}
// A select element with a "multiple" attribute or with a display size greater
@@ -1471,20 +1404,16 @@ void HTMLCanvasElement::UpdateMemoryUsage() {
}
}
- if (copied_image_)
- non_gpu_buffer_count++;
-
if (Is3d()) {
if (ResourceProvider()) {
non_gpu_buffer_count++;
- if (ResourceProvider()->IsAccelerated()) {
+ if (ResourceProvider()->IsAccelerated())
gpu_buffer_count += 2;
- }
}
non_gpu_buffer_count += context_->ExternallyAllocatedBufferCountPerPixel();
}
- int bytes_per_pixel = ColorParams().BytesPerPixel();
+ const int bytes_per_pixel = ColorParams().BytesPerPixel();
// Re-computation of gpu memory usage is only carried out when there is a
// a change from acceleration to non-accleration or vice versa.
@@ -1546,6 +1475,14 @@ void HTMLCanvasElement::ReplaceExisting2dLayerBridge(
UpdateMemoryUsage();
}
+CanvasResourceProvider* HTMLCanvasElement::GetOrCreateCanvasResourceProvider(
+ AccelerationHint hint) {
+ if (Is2d())
+ return GetOrCreateCanvas2DLayerBridge()->GetOrCreateResourceProvider(hint);
+
+ return CanvasRenderingContextHost::GetOrCreateCanvasResourceProvider(hint);
+}
+
bool HTMLCanvasElement::HasImageBitmapContext() const {
if (!context_)
return false;
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 1b4daa38b71..064d390f591 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
@@ -37,7 +37,6 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/dom/document.h"
-#include "third_party/blink/renderer/core/html/canvas/canvas_image_source.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"
@@ -91,7 +90,6 @@ class CORE_EXPORT HTMLCanvasElement final
: public HTMLElement,
public ContextLifecycleObserver,
public PageVisibilityObserver,
- public CanvasImageSource,
public CanvasRenderingContextHost,
public WebSurfaceLayerBridgeObserver,
public ImageBitmapSource,
@@ -156,9 +154,6 @@ class CORE_EXPORT HTMLCanvasElement final
return context_.Get();
}
- scoped_refptr<Image> CopiedImage(SourceDrawingBuffer, AccelerationHint);
- void ClearCopiedImage();
-
bool OriginClean() const override;
void SetOriginTainted() override { origin_clean_ = false; }
@@ -177,7 +172,7 @@ class CORE_EXPORT HTMLCanvasElement final
const AtomicString ImageSourceURL() const override;
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
bool IsDirty() { return !dirty_rect_.IsEmpty(); }
@@ -218,6 +213,9 @@ class CORE_EXPORT HTMLCanvasElement final
bool ShouldAccelerate2dContext() const override;
unsigned GetMSAASampleCountFor2dContext() const override;
SkFilterQuality FilterQuality() const override;
+ bool LowLatencyEnabled() const override { return !!frame_dispatcher_; }
+ CanvasResourceProvider* GetOrCreateCanvasResourceProvider(
+ AccelerationHint hint) override;
void DisableAcceleration(std::unique_ptr<Canvas2DLayerBridge>
unaccelerated_bridge_used_for_testing = nullptr);
@@ -271,7 +269,7 @@ class CORE_EXPORT HTMLCanvasElement final
}
DispatchEventResult HostDispatchEvent(Event* event) override {
- return DispatchEvent(event);
+ return DispatchEvent(*event);
}
bool IsWebGL1Enabled() const override;
@@ -297,7 +295,8 @@ class CORE_EXPORT HTMLCanvasElement final
needs_unbuffered_input_ = value;
}
- bool LowLatencyEnabled() const { return !!frame_dispatcher_; }
+ scoped_refptr<StaticBitmapImage> Snapshot(SourceDrawingBuffer,
+ AccelerationHint) const;
protected:
void DidMoveToNewDocument(Document& old_document) override;
@@ -331,9 +330,6 @@ class CORE_EXPORT HTMLCanvasElement final
bool PaintsIntoCanvasBuffer() const;
- scoped_refptr<StaticBitmapImage> ToStaticBitmapImage(SourceDrawingBuffer,
- AccelerationHint) const;
-
String ToDataURLInternal(const String& mime_type,
const double& quality,
SourceDrawingBuffer) const;
@@ -368,10 +364,6 @@ class CORE_EXPORT HTMLCanvasElement final
std::unique_ptr<Canvas2DLayerBridge> canvas2d_bridge_;
void ReplaceExisting2dLayerBridge(std::unique_ptr<Canvas2DLayerBridge>);
- // FIXME: This is temporary for platforms that have to copy the image buffer
- // to render (and for CSSCanvasValue).
- mutable scoped_refptr<Image> copied_image_;
-
// Used for OffscreenCanvas that controls this HTML canvas element
// and for low latency mode.
std::unique_ptr<::blink::SurfaceLayerBridge> surface_layer_bridge_;
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 864bfe664f0..4cb4bb59cf3 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,6 +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/platform/fonts/character_range.h"
namespace blink {
@@ -65,24 +66,22 @@ void TextMetrics::Update(const Font& font,
FloatRect bbox = font.BoundingBox(text_run);
const FontMetrics& font_metrics = font_data->GetFontMetrics();
- Vector<CharacterRange> ranges = font.IndividualCharacterRanges(text_run);
- advances_.resize(ranges.size());
- for (unsigned i = 0; i < ranges.size(); i++) {
- advances_[i] = ranges[i].start;
- }
+ advances_ = font.IndividualCharacterAdvances(text_run);
// x direction
width_ = bbox.Width();
+ FloatRect glyph_bounds;
+ double real_width = font.Width(text_run, nullptr, &glyph_bounds);
float dx = 0.0f;
if (align == kCenterTextAlign)
- dx = -width_ / 2.0f;
+ dx = real_width / 2.0f;
else if (align == kRightTextAlign ||
(align == kStartTextAlign && direction == TextDirection::kRtl) ||
(align == kEndTextAlign && direction != TextDirection::kRtl))
- dx = -width_;
- actual_bounding_box_left_ = -bbox.X() - dx;
- actual_bounding_box_right_ = bbox.MaxX() + dx;
+ dx = real_width;
+ actual_bounding_box_left_ = -glyph_bounds.X() + dx;
+ actual_bounding_box_right_ = glyph_bounds.MaxX() - dx;
// y direction
const float ascent = font_metrics.FloatAscent();
@@ -101,9 +100,10 @@ void TextMetrics::Update(const Font& font,
em_height_descent_ = baseline_y;
// TODO(fserb): hanging/ideographic baselines are broken.
- hanging_baseline_ = ascent * kHangingAsPercentOfAscent / 100.0f - baseline_y;
- ideographic_baseline_ = -descent - baseline_y;
- alphabetic_baseline_ = -baseline_y;
+ baselines_.setAlphabetic(-baseline_y);
+ baselines_.setHanging(ascent * kHangingAsPercentOfAscent / 100.0f -
+ baseline_y);
+ baselines_.setIdeographic(-descent - baseline_y);
}
} // 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 51fc4e38880..be43231d62d 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
@@ -27,6 +27,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CANVAS_TEXT_METRICS_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"
@@ -62,9 +63,8 @@ class CORE_EXPORT TextMetrics final : public ScriptWrappable {
}
double emHeightAscent() const { return em_height_ascent_; }
double emHeightDescent() const { return em_height_descent_; }
- double hangingBaseline() const { return hanging_baseline_; }
- double alphabeticBaseline() const { return alphabetic_baseline_; }
- double ideographicBaseline() const { return ideographic_baseline_; }
+ void getBaselines(Baselines& baselines) const { baselines = baselines_; }
+ Baselines getBaselines() const { return baselines_; }
static float GetFontBaseline(const TextBaseline&, const FontMetrics&);
@@ -89,9 +89,7 @@ class CORE_EXPORT TextMetrics final : public ScriptWrappable {
double actual_bounding_box_descent_ = 0.0;
double em_height_ascent_ = 0.0;
double em_height_descent_ = 0.0;
- double hanging_baseline_ = 0.0;
- double alphabetic_baseline_ = 0.0;
- double ideographic_baseline_ = 0.0;
+ Baselines baselines_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/canvas/text_metrics.idl b/chromium/third_party/blink/renderer/core/html/canvas/text_metrics.idl
index bcaa5e2c1d7..79446ef391f 100644
--- a/chromium/third_party/blink/renderer/core/html/canvas/text_metrics.idl
+++ b/chromium/third_party/blink/renderer/core/html/canvas/text_metrics.idl
@@ -40,7 +40,5 @@ interface TextMetrics {
[RuntimeEnabled=ExtendedTextMetrics] readonly attribute double actualBoundingBoxDescent;
[RuntimeEnabled=ExtendedTextMetrics] readonly attribute double emHeightAscent;
[RuntimeEnabled=ExtendedTextMetrics] readonly attribute double emHeightDescent;
- [RuntimeEnabled=ExtendedTextMetrics] readonly attribute double hangingBaseline;
- [RuntimeEnabled=ExtendedTextMetrics] readonly attribute double alphabeticBaseline;
- [RuntimeEnabled=ExtendedTextMetrics] readonly attribute double ideographicBaseline;
+ [RuntimeEnabled=ExtendedTextMetrics] Baselines getBaselines();
};
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 e9c6d13a02f..51426df6728 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
@@ -3,7 +3,9 @@
// found in the LICENSE file.
interface CustomElementRegistry {
- [CallWith=ScriptState, CEReactions, CustomElementCallbacks, RaisesException, MeasureAs=CustomElementRegistryDefine] void define(DOMString name, Function constructor, optional ElementDefinitionOptions options);
+ // TODO(yukishiino): |constructor| should be of callback function type
+ // (should be: callback T = any ()).
+ [CallWith=ScriptState, CEReactions, CustomElementCallbacks, RaisesException, MeasureAs=CustomElementRegistryDefine] void define(DOMString name, CallbackFunctionTreatedAsScriptValue 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 b36542033cc..bd294a4e00c 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
@@ -435,9 +435,11 @@ TEST_F(CustomElementRegistryTest, lookupCustomElementDefinition) {
TEST_F(CustomElementRegistryTest, defineCustomElementWithStyle) {
RuntimeEnabledFeatures::SetConstructableStylesheetsEnabled(true);
+ V8TestingScope scope;
NonThrowableExceptionState should_not_throw;
ElementDefinitionOptions options;
- CSSStyleSheet* sheet = CSSStyleSheet::Create(GetDocument(), should_not_throw);
+ CSSStyleSheet* sheet = GetDocument().createEmptyCSSStyleSheet(
+ scope.GetScriptState(), CSSStyleSheetInit(), should_not_throw);
options.setStyle(sheet);
TestCustomElementDefinitionBuilder builder(sheet);
CustomElementDefinition* definition_a =
diff --git a/chromium/third_party/blink/renderer/core/html/focus_options.idl b/chromium/third_party/blink/renderer/core/html/focus_options.idl
index 8a9ef0fc95b..e9ee3806efe 100644
--- a/chromium/third_party/blink/renderer/core/html/focus_options.idl
+++ b/chromium/third_party/blink/renderer/core/html/focus_options.idl
@@ -1,3 +1,3 @@
dictionary FocusOptions {
- [RuntimeEnabled=FocusOptions]boolean preventScroll = false;
+ boolean preventScroll = false;
};
diff --git a/chromium/third_party/blink/renderer/core/html/forms/base_checkable_input_type.cc b/chromium/third_party/blink/renderer/core/html/forms/base_checkable_input_type.cc
index c8137f0297f..fefc9d7011e 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/base_checkable_input_type.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/base_checkable_input_type.cc
@@ -65,9 +65,8 @@ void BaseCheckableInputType::AppendToFormData(FormData& form_data) const {
form_data.AppendFromElement(GetElement().GetName(), GetElement().value());
}
-void BaseCheckableInputType::HandleKeydownEvent(KeyboardEvent* event) {
- const String& key = event->key();
- if (key == " ") {
+void BaseCheckableInputType::HandleKeydownEvent(KeyboardEvent& event) {
+ if (event.key() == " ") {
GetElement().SetActive(true);
// No setDefaultHandled(), because IE dispatches a keypress in this case
// and the caller will only dispatch a keypress if we don't call
@@ -75,10 +74,10 @@ void BaseCheckableInputType::HandleKeydownEvent(KeyboardEvent* event) {
}
}
-void BaseCheckableInputType::HandleKeypressEvent(KeyboardEvent* event) {
- if (event->charCode() == ' ') {
+void BaseCheckableInputType::HandleKeypressEvent(KeyboardEvent& event) {
+ if (event.charCode() == ' ') {
// Prevent scrolling down the page.
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
}
}
diff --git a/chromium/third_party/blink/renderer/core/html/forms/base_checkable_input_type.h b/chromium/third_party/blink/renderer/core/html/forms/base_checkable_input_type.h
index 95d84ae6052..e7129cca958 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/base_checkable_input_type.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/base_checkable_input_type.h
@@ -49,7 +49,7 @@ class BaseCheckableInputType : public InputType, public InputTypeView {
: InputType(element),
InputTypeView(element),
is_in_click_handler_(false) {}
- void HandleKeydownEvent(KeyboardEvent*) override;
+ void HandleKeydownEvent(KeyboardEvent&) override;
bool NeedsShadowSubtree() const override { return false; }
bool is_in_click_handler_;
@@ -59,7 +59,7 @@ class BaseCheckableInputType : public InputType, public InputTypeView {
FormControlState SaveFormControlState() const final;
void RestoreFormControlState(const FormControlState&) final;
void AppendToFormData(FormData&) const final;
- void HandleKeypressEvent(KeyboardEvent*) final;
+ void HandleKeypressEvent(KeyboardEvent&) final;
bool CanSetStringValue() const final;
void AccessKeyAction(bool send_mouse_events) final;
bool MatchesDefaultPseudoClass() override;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/checkbox_input_type.cc b/chromium/third_party/blink/renderer/core/html/forms/checkbox_input_type.cc
index db7b034b596..3ef8609c637 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/checkbox_input_type.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/checkbox_input_type.cc
@@ -55,9 +55,8 @@ String CheckboxInputType::ValueMissingText() const {
WebLocalizedString::kValidationValueMissingForCheckbox);
}
-void CheckboxInputType::HandleKeyupEvent(KeyboardEvent* event) {
- const String& key = event->key();
- if (key != " ")
+void CheckboxInputType::HandleKeyupEvent(KeyboardEvent& event) {
+ if (event.key() != " ")
return;
DispatchSimulatedClickIfActive(event);
}
@@ -80,9 +79,9 @@ ClickHandlingState* CheckboxInputType::WillDispatchClick() {
return state;
}
-void CheckboxInputType::DidDispatchClick(Event* event,
+void CheckboxInputType::DidDispatchClick(Event& event,
const ClickHandlingState& state) {
- if (event->defaultPrevented() || event->DefaultHandled()) {
+ if (event.defaultPrevented() || event.DefaultHandled()) {
GetElement().setIndeterminate(state.indeterminate);
GetElement().setChecked(state.checked);
} else {
@@ -90,7 +89,7 @@ void CheckboxInputType::DidDispatchClick(Event* event,
}
is_in_click_handler_ = false;
// The work we did in willDispatchClick was default handling.
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
}
bool CheckboxInputType::ShouldAppearIndeterminate() const {
diff --git a/chromium/third_party/blink/renderer/core/html/forms/checkbox_input_type.h b/chromium/third_party/blink/renderer/core/html/forms/checkbox_input_type.h
index ae088c656ef..425616ce905 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/checkbox_input_type.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/checkbox_input_type.h
@@ -45,9 +45,9 @@ class CheckboxInputType final : public BaseCheckableInputType {
const AtomicString& FormControlType() const override;
bool ValueMissing(const String&) const override;
String ValueMissingText() const override;
- void HandleKeyupEvent(KeyboardEvent*) override;
+ void HandleKeyupEvent(KeyboardEvent&) override;
ClickHandlingState* WillDispatchClick() override;
- void DidDispatchClick(Event*, const ClickHandlingState&) override;
+ void DidDispatchClick(Event&, const ClickHandlingState&) override;
bool ShouldAppearIndeterminate() const override;
};
diff --git a/chromium/third_party/blink/renderer/core/html/forms/chooser_only_temporal_input_type_view.cc b/chromium/third_party/blink/renderer/core/html/forms/chooser_only_temporal_input_type_view.cc
index e530f808439..3328396a2c4 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/chooser_only_temporal_input_type_view.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/chooser_only_temporal_input_type_view.cc
@@ -58,7 +58,7 @@ void ChooserOnlyTemporalInputTypeView::Trace(blink::Visitor* visitor) {
DateTimeChooserClient::Trace(visitor);
}
-void ChooserOnlyTemporalInputTypeView::HandleDOMActivateEvent(Event* event) {
+void ChooserOnlyTemporalInputTypeView::HandleDOMActivateEvent(Event& event) {
Document& document = GetElement().GetDocument();
if (GetElement().IsDisabledOrReadOnly() || !GetElement().GetLayoutObject() ||
!Frame::HasTransientUserActivation(document.GetFrame()) ||
@@ -74,7 +74,7 @@ void ChooserOnlyTemporalInputTypeView::HandleDOMActivateEvent(Event* event) {
return;
UseCounter::Count(
document,
- (event->UnderlyingEvent() && event->UnderlyingEvent()->isTrusted())
+ (event.UnderlyingEvent() && event.UnderlyingEvent()->isTrusted())
? WebFeature::kTemporalInputTypeChooserByTrustedClick
: WebFeature::kTemporalInputTypeChooserByUntrustedClick);
date_time_chooser_ =
diff --git a/chromium/third_party/blink/renderer/core/html/forms/chooser_only_temporal_input_type_view.h b/chromium/third_party/blink/renderer/core/html/forms/chooser_only_temporal_input_type_view.h
index a69e2d873eb..9388831482d 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/chooser_only_temporal_input_type_view.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/chooser_only_temporal_input_type_view.h
@@ -56,7 +56,7 @@ class ChooserOnlyTemporalInputTypeView final
void ClosePopupView() override;
void ValueAttributeChanged() override;
void DidSetValue(const String&, bool value_changed) override;
- void HandleDOMActivateEvent(Event*) override;
+ void HandleDOMActivateEvent(Event&) override;
void UpdateView() override;
// DateTimeChooserClient functions:
diff --git a/chromium/third_party/blink/renderer/core/html/forms/clear_button_element.cc b/chromium/third_party/blink/renderer/core/html/forms/clear_button_element.cc
index 7e92b7e68e5..6321006801d 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/clear_button_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/clear_button_element.cc
@@ -54,28 +54,28 @@ void ClearButtonElement::DetachLayoutTree(const AttachContext& context) {
HTMLDivElement::DetachLayoutTree(context);
}
-void ClearButtonElement::DefaultEventHandler(Event* event) {
+void ClearButtonElement::DefaultEventHandler(Event& event) {
if (!clear_button_owner_) {
- if (!event->DefaultHandled())
+ if (!event.DefaultHandled())
HTMLDivElement::DefaultEventHandler(event);
return;
}
if (!clear_button_owner_->ShouldClearButtonRespondToMouseEvents()) {
- if (!event->DefaultHandled())
+ if (!event.DefaultHandled())
HTMLDivElement::DefaultEventHandler(event);
return;
}
- if (event->type() == EventTypeNames::click) {
+ if (event.type() == EventTypeNames::click) {
if (GetLayoutObject() && GetLayoutObject()->VisibleToHitTesting()) {
clear_button_owner_->FocusAndSelectClearButtonOwner();
clear_button_owner_->ClearValue();
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
}
}
- if (!event->DefaultHandled())
+ if (!event.DefaultHandled())
HTMLDivElement::DefaultEventHandler(event);
}
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 4698422d545..6666122bd6b 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
@@ -50,7 +50,7 @@ class ClearButtonElement final : public HTMLDivElement {
ClearButtonElement(Document&, ClearButtonOwner&);
void DetachLayoutTree(const AttachContext& = AttachContext()) override;
bool IsMouseFocusable() const override { return false; }
- void DefaultEventHandler(Event*) override;
+ void DefaultEventHandler(Event&) override;
bool IsClearButtonElement() const override;
Member<ClearButtonOwner> clear_button_owner_;
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 4bd8a95e142..744cb149c9d 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
@@ -30,6 +30,7 @@
#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"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
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 153c9b67d82..ad33b11ea9c 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
@@ -145,7 +145,7 @@ void ColorInputType::DidSetValue(const String&, bool value_changed) {
chooser_->SetSelectedColor(ValueAsColor());
}
-void ColorInputType::HandleDOMActivateEvent(Event* event) {
+void ColorInputType::HandleDOMActivateEvent(Event& event) {
if (GetElement().IsDisabledFormControl())
return;
@@ -157,14 +157,14 @@ void ColorInputType::HandleDOMActivateEvent(Event* event) {
if (chrome_client && !chooser_) {
UseCounter::Count(
document,
- (event->UnderlyingEvent() && event->UnderlyingEvent()->isTrusted())
+ (event.UnderlyingEvent() && event.UnderlyingEvent()->isTrusted())
? WebFeature::kColorInputTypeChooserByTrustedClick
: WebFeature::kColorInputTypeChooserByUntrustedClick);
chooser_ = chrome_client->OpenColorChooser(document.GetFrame(), this,
ValueAsColor());
}
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
}
void ColorInputType::ClosePopupView() {
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 d6356adc4d2..904ada1b097 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
@@ -71,7 +71,7 @@ class ColorInputType final : public InputType,
String SanitizeValue(const String&) const override;
void CreateShadowSubtree() override;
void DidSetValue(const String&, bool value_changed) override;
- void HandleDOMActivateEvent(Event*) override;
+ void HandleDOMActivateEvent(Event&) override;
void ClosePopupView() override;
bool ShouldRespectListAttribute() override;
bool TypeMismatchFor(const String&) const 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 700e6c78a0d..6499045e477 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
@@ -747,8 +747,8 @@ void DateTimeEditElement::GetLayout(const LayoutParameters& layout_parameters,
break;
}
}
- if (DateTimeFieldElement* field =
- FieldAt(std::min(focused_field_index, fields_.size() - 1)))
+ if (DateTimeFieldElement* field = FieldAt(std::min(
+ focused_field_index, static_cast<size_t>(fields_.size()) - 1)))
field->focus();
}
@@ -785,12 +785,12 @@ void DateTimeEditElement::ResetFields() {
fields_.Shrink(0);
}
-void DateTimeEditElement::DefaultEventHandler(Event* event) {
+void DateTimeEditElement::DefaultEventHandler(Event& event) {
// In case of control owner forward event to control, e.g. DOM
// dispatchEvent method.
if (DateTimeFieldElement* field = FocusedField()) {
field->DefaultEventHandler(event);
- if (event->DefaultHandled())
+ if (event.DefaultHandled())
return;
}
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 68bea3cff35..c3e22542129 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
@@ -66,6 +66,8 @@ class DateTimeEditElement final : public HTMLDivElement,
struct LayoutParameters {
STACK_ALLOCATED();
+
+ public:
String date_time_format;
String fallback_date_time_format;
Locale& locale;
@@ -88,7 +90,7 @@ class DateTimeEditElement final : public HTMLDivElement,
void AddField(DateTimeFieldElement*);
bool AnyEditableFieldsHaveValues() const;
void BlurByOwner();
- void DefaultEventHandler(Event*) override;
+ void DefaultEventHandler(Event&) override;
void DisabledStateChanged();
Element* FieldsWrapperElement() const;
void FocusIfNoFocus();
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 2e46e6058ef..ac6bc06d4eb 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,12 +55,12 @@ float DateTimeFieldElement::ComputeTextWidth(const ComputedStyle& style,
return style.GetFont().Width(ConstructTextRun(style.GetFont(), text, style));
}
-void DateTimeFieldElement::DefaultEventHandler(Event* event) {
- if (event->IsKeyboardEvent()) {
- KeyboardEvent* keyboard_event = ToKeyboardEvent(event);
+void DateTimeFieldElement::DefaultEventHandler(Event& event) {
+ if (event.IsKeyboardEvent()) {
+ auto& keyboard_event = ToKeyboardEvent(event);
if (!IsDisabled() && !IsFieldOwnerDisabled() && !IsFieldOwnerReadOnly()) {
HandleKeyboardEvent(keyboard_event);
- if (keyboard_event->DefaultHandled()) {
+ if (keyboard_event.DefaultHandled()) {
if (field_owner_)
field_owner_->FieldDidChangeValueByKeyboard();
return;
@@ -69,7 +69,7 @@ void DateTimeFieldElement::DefaultEventHandler(Event* event) {
DefaultKeyboardEventHandler(keyboard_event);
if (field_owner_)
field_owner_->FieldDidChangeValueByKeyboard();
- if (keyboard_event->DefaultHandled())
+ if (keyboard_event.DefaultHandled())
return;
}
@@ -77,14 +77,14 @@ void DateTimeFieldElement::DefaultEventHandler(Event* event) {
}
void DateTimeFieldElement::DefaultKeyboardEventHandler(
- KeyboardEvent* keyboard_event) {
- if (keyboard_event->type() != EventTypeNames::keydown)
+ KeyboardEvent& keyboard_event) {
+ if (keyboard_event.type() != EventTypeNames::keydown)
return;
if (IsDisabled() || IsFieldOwnerDisabled())
return;
- const String& key = keyboard_event->key();
+ const String& key = keyboard_event.key();
if (key == "ArrowLeft") {
if (!field_owner_)
@@ -92,7 +92,7 @@ void DateTimeFieldElement::DefaultKeyboardEventHandler(
// FIXME: We'd like to use FocusController::advanceFocus(FocusDirectionLeft,
// ...) but it doesn't work for shadow nodes. webkit.org/b/104650
if (!LocaleForOwner().IsRTL() && field_owner_->FocusOnPreviousField(*this))
- keyboard_event->SetDefaultHandled();
+ keyboard_event.SetDefaultHandled();
return;
}
@@ -103,7 +103,7 @@ void DateTimeFieldElement::DefaultKeyboardEventHandler(
// FocusController::advanceFocus(FocusDirectionRight, ...)
// but it doesn't work for shadow nodes. webkit.org/b/104650
if (!LocaleForOwner().IsRTL() && field_owner_->FocusOnNextField(*this))
- keyboard_event->SetDefaultHandled();
+ keyboard_event.SetDefaultHandled();
return;
}
@@ -111,21 +111,21 @@ void DateTimeFieldElement::DefaultKeyboardEventHandler(
return;
if (key == "ArrowDown") {
- if (keyboard_event->getModifierState("Alt"))
+ if (keyboard_event.getModifierState("Alt"))
return;
- keyboard_event->SetDefaultHandled();
+ keyboard_event.SetDefaultHandled();
StepDown();
return;
}
if (key == "ArrowUp") {
- keyboard_event->SetDefaultHandled();
+ keyboard_event.SetDefaultHandled();
StepUp();
return;
}
if (key == "Backspace" || key == "Delete") {
- keyboard_event->SetDefaultHandled();
+ keyboard_event.SetDefaultHandled();
SetEmptyValue(kDispatchEvent);
return;
}
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 f6cd41ebef9..6a6cb1e77b1 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
@@ -60,7 +60,7 @@ class DateTimeFieldElement : public HTMLSpanElement {
virtual void FieldDidChangeValueByKeyboard() = 0;
};
- void DefaultEventHandler(Event*) override;
+ void DefaultEventHandler(Event&) override;
virtual bool HasValue() const = 0;
bool IsDisabled() const;
virtual float MaximumWidth(const ComputedStyle&);
@@ -83,7 +83,7 @@ class DateTimeFieldElement : public HTMLSpanElement {
protected:
DateTimeFieldElement(Document&, FieldOwner&);
void FocusOnNextField();
- virtual void HandleKeyboardEvent(KeyboardEvent*) = 0;
+ virtual void HandleKeyboardEvent(KeyboardEvent&) = 0;
void Initialize(const AtomicString& pseudo,
const String& ax_help_text,
int ax_minimum,
@@ -98,7 +98,7 @@ class DateTimeFieldElement : public HTMLSpanElement {
void SetFocused(bool, WebFocusType) override;
private:
- void DefaultKeyboardEventHandler(KeyboardEvent*);
+ void DefaultKeyboardEventHandler(KeyboardEvent&);
bool IsDateTimeFieldElement() const final;
bool IsFieldOwnerDisabled() const;
bool IsFieldOwnerReadOnly() const;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/date_time_field_elements.h b/chromium/third_party/blink/renderer/core/html/forms/date_time_field_elements.h
index 758f9a71d56..f2ff719f1d1 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/date_time_field_elements.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/date_time_field_elements.h
@@ -290,6 +290,8 @@ class DateTimeYearFieldElement final : public DateTimeNumericFieldElement {
public:
struct Parameters {
STACK_ALLOCATED();
+
+ public:
int minimum_year;
int maximum_year;
bool min_is_specified;
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 21e1612c224..38ff8175c37 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
@@ -113,12 +113,12 @@ String DateTimeNumericFieldElement::FormatValue(int value) const {
}
void DateTimeNumericFieldElement::HandleKeyboardEvent(
- KeyboardEvent* keyboard_event) {
+ KeyboardEvent& keyboard_event) {
DCHECK(!IsDisabled());
- if (keyboard_event->type() != EventTypeNames::keypress)
+ if (keyboard_event.type() != EventTypeNames::keypress)
return;
- UChar char_code = static_cast<UChar>(keyboard_event->charCode());
+ UChar char_code = static_cast<UChar>(keyboard_event.charCode());
String number =
LocaleForOwner().ConvertFromLocalizedNumber(String(&char_code, 1));
const int digit = number[0] - '0';
@@ -147,7 +147,7 @@ void DateTimeNumericFieldElement::HandleKeyboardEvent(
new_value * 10 > range_.maximum)
FocusOnNextField();
- keyboard_event->SetDefaultHandled();
+ keyboard_event.SetDefaultHandled();
}
bool DateTimeNumericFieldElement::HasValue() const {
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 ffd9fcaa9f3..a661fce1ffc 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
@@ -87,7 +87,7 @@ class DateTimeNumericFieldElement : public DateTimeFieldElement {
private:
// DateTimeFieldElement functions.
- void HandleKeyboardEvent(KeyboardEvent*) final;
+ void HandleKeyboardEvent(KeyboardEvent&) final;
float MaximumWidth(const ComputedStyle&) override;
void StepDown() final;
void StepUp() final;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/date_time_symbolic_field_element.cc b/chromium/third_party/blink/renderer/core/html/forms/date_time_symbolic_field_element.cc
index 25a3c572c28..4c6ba85412b 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/date_time_symbolic_field_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/date_time_symbolic_field_element.cc
@@ -74,15 +74,15 @@ float DateTimeSymbolicFieldElement::MaximumWidth(const ComputedStyle& style) {
}
void DateTimeSymbolicFieldElement::HandleKeyboardEvent(
- KeyboardEvent* keyboard_event) {
- if (keyboard_event->type() != EventTypeNames::keypress)
+ KeyboardEvent& keyboard_event) {
+ if (keyboard_event.type() != EventTypeNames::keypress)
return;
- const UChar char_code = WTF::Unicode::ToLower(keyboard_event->charCode());
+ const UChar char_code = WTF::Unicode::ToLower(keyboard_event.charCode());
if (char_code < ' ')
return;
- keyboard_event->SetDefaultHandled();
+ keyboard_event.SetDefaultHandled();
int index = type_ahead_.HandleEvent(
keyboard_event, TypeAhead::kMatchPrefix | TypeAhead::kCycleFirstChar |
diff --git a/chromium/third_party/blink/renderer/core/html/forms/date_time_symbolic_field_element.h b/chromium/third_party/blink/renderer/core/html/forms/date_time_symbolic_field_element.h
index 59cf9e95218..c2e18f02005 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/date_time_symbolic_field_element.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/date_time_symbolic_field_element.h
@@ -58,7 +58,7 @@ class DateTimeSymbolicFieldElement : public DateTimeFieldElement,
}
// DateTimeFieldElement functions.
- void HandleKeyboardEvent(KeyboardEvent*) final;
+ void HandleKeyboardEvent(KeyboardEvent&) final;
float MaximumWidth(const ComputedStyle&) override;
String Placeholder() const override;
void StepDown() final;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/file_chooser.cc b/chromium/third_party/blink/renderer/core/html/forms/file_chooser.cc
index bfab0af72fb..223eb7496ad 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/file_chooser.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/file_chooser.cc
@@ -28,6 +28,11 @@
#include "third_party/blink/renderer/core/html/forms/file_chooser.h"
+#include "third_party/blink/public/web/web_local_frame_client.h"
+#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
+#include "third_party/blink/renderer/core/page/chrome_client_impl.h"
+#include "third_party/blink/renderer/platform/wtf/date_math.h"
+
namespace blink {
FileChooserClient::~FileChooserClient() = default;
@@ -58,6 +63,49 @@ scoped_refptr<FileChooser> FileChooser::Create(
FileChooser::~FileChooser() = default;
+bool FileChooser::OpenFileChooser(ChromeClientImpl& chrome_client_impl) {
+ LocalFrame* frame = FrameOrNull();
+ if (!frame)
+ return false;
+ chrome_client_impl_ = chrome_client_impl;
+
+ WebLocalFrameClient* client =
+ frame ? WebLocalFrameImpl::FromFrame(frame)->Client() : nullptr;
+ if (!client || !client->RunFileChooser(params_, this))
+ return false;
+
+ // Should be released on file choosing.
+ AddRef();
+ chrome_client_impl.RegisterPopupOpeningObserver(client_);
+ return true;
+}
+
+void FileChooser::DidChooseFile(const WebVector<WebString>& file_names) {
+ Vector<FileChooserFileInfo> file_info;
+ for (size_t i = 0; i < file_names.size(); ++i)
+ file_info.push_back(FileChooserFileInfo(file_names[i]));
+ ChooseFiles(file_info);
+}
+
+void FileChooser::DidChooseFile(const WebVector<SelectedFileInfo>& files) {
+ Vector<FileChooserFileInfo> file_info;
+ for (size_t i = 0; i < files.size(); ++i) {
+ if (files[i].file_system_url.IsEmpty()) {
+ file_info.push_back(
+ FileChooserFileInfo(files[i].path, files[i].display_name));
+ } else {
+ FileMetadata metadata;
+ metadata.modification_time = files[i].modification_time * kMsPerSecond;
+ metadata.length = files[i].length;
+ metadata.type = files[i].is_directory ? FileMetadata::kTypeDirectory
+ : FileMetadata::kTypeFile;
+ file_info.push_back(
+ FileChooserFileInfo(files[i].file_system_url, metadata));
+ }
+ }
+ ChooseFiles(file_info);
+}
+
void FileChooser::ChooseFiles(const Vector<FileChooserFileInfo>& files) {
// FIXME: This is inelegant. We should not be looking at params_ here.
if (params_.selected_files.size() == files.size()) {
@@ -68,12 +116,24 @@ void FileChooser::ChooseFiles(const Vector<FileChooserFileInfo>& files) {
break;
}
}
- if (!was_changed)
+ if (!was_changed) {
+ DidCloseChooser();
return;
+ }
}
if (client_)
client_->FilesChosen(files);
+ DidCloseChooser();
+}
+
+void FileChooser::DidCloseChooser() {
+ if (chrome_client_impl_) {
+ chrome_client_impl_->DidCompleteFileChooser(*this);
+ if (client_)
+ chrome_client_impl_->UnregisterPopupOpeningObserver(client_);
+ }
+ Release();
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/forms/file_chooser.h b/chromium/third_party/blink/renderer/core/html/forms/file_chooser.h
index 879fcd9176e..f4c300be99c 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/file_chooser.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/file_chooser.h
@@ -30,7 +30,9 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_FILE_CHOOSER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_FILE_CHOOSER_H_
+#include "third_party/blink/public/web/web_file_chooser_completion.h"
#include "third_party/blink/public/web/web_file_chooser_params.h"
+#include "third_party/blink/renderer/core/page/popup_opening_observer.h"
#include "third_party/blink/renderer/platform/file_metadata.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
@@ -41,7 +43,9 @@
namespace blink {
+class ChromeClientImpl;
class FileChooser;
+class LocalFrame;
struct FileChooserFileInfo {
DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
@@ -60,10 +64,11 @@ struct FileChooserFileInfo {
const FileMetadata metadata;
};
-class FileChooserClient : public GarbageCollectedMixin {
+class CORE_EXPORT FileChooserClient : public PopupOpeningObserver {
public:
virtual void FilesChosen(const Vector<FileChooserFileInfo>&) = 0;
- virtual ~FileChooserClient();
+ virtual LocalFrame* FrameOrNull() const = 0;
+ ~FileChooserClient() override;
protected:
FileChooser* NewFileChooser(const WebFileChooserParams&);
@@ -76,25 +81,39 @@ class FileChooserClient : public GarbageCollectedMixin {
scoped_refptr<FileChooser> chooser_;
};
-class FileChooser : public RefCounted<FileChooser> {
+class FileChooser : public RefCounted<FileChooser>,
+ public WebFileChooserCompletion {
public:
- static scoped_refptr<FileChooser> Create(FileChooserClient*,
- const WebFileChooserParams&);
- ~FileChooser();
-
+ CORE_EXPORT static scoped_refptr<FileChooser> Create(
+ FileChooserClient*,
+ const WebFileChooserParams&);
+ ~FileChooser() override;
+
+ LocalFrame* FrameOrNull() const {
+ return client_ ? client_->FrameOrNull() : nullptr;
+ }
void DisconnectClient() { client_ = nullptr; }
- // FIXME: We should probably just pass file paths that could be virtual paths
- // with proper display names rather than passing structs.
- void ChooseFiles(const Vector<FileChooserFileInfo>& files);
-
const WebFileChooserParams& Params() const { return params_; }
+ bool OpenFileChooser(ChromeClientImpl& chrome_client_impl);
+
private:
FileChooser(FileChooserClient*, const WebFileChooserParams&);
+ void DidCloseChooser();
+
+ // WebFileChooserCompletion implementation:
+ void DidChooseFile(const WebVector<WebString>& file_names) override;
+ void DidChooseFile(const WebVector<SelectedFileInfo>& files) override;
+
+ // FIXME: We should probably just pass file paths that could be virtual paths
+ // with proper display names rather than passing structs.
+ void ChooseFiles(const Vector<FileChooserFileInfo>& files);
+
WeakPersistent<FileChooserClient> client_;
WebFileChooserParams params_;
+ Persistent<ChromeClientImpl> chrome_client_impl_;
};
} // namespace blink
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 eb2f4437747..3c4362f6ea6 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
@@ -144,7 +144,7 @@ String FileInputType::ValueMissingText() const {
: WebLocalizedString::kValidationValueMissingForFile);
}
-void FileInputType::HandleDOMActivateEvent(Event* event) {
+void FileInputType::HandleDOMActivateEvent(Event& event) {
if (GetElement().IsDisabledFormControl())
return;
@@ -171,9 +171,8 @@ void FileInputType::HandleDOMActivateEvent(Event* event) {
: WebFeature::kInputTypeFileInsecureOriginOpenChooser);
chrome_client->OpenFileChooser(document.GetFrame(), NewFileChooser(params));
- chrome_client->RegisterPopupOpeningObserver(this);
}
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
}
LayoutObject* FileInputType::CreateLayoutObject(const ComputedStyle&) const {
@@ -349,11 +348,12 @@ void FileInputType::SetFiles(FileList* files) {
void FileInputType::FilesChosen(const Vector<FileChooserFileInfo>& files) {
SetFiles(CreateFileList(files,
GetElement().FastHasAttribute(webkitdirectoryAttr)));
- if (HasConnectedFileChooser()) {
+ if (HasConnectedFileChooser())
DisconnectFileChooser();
- if (auto* chrome_client = GetChromeClient())
- chrome_client->UnregisterPopupOpeningObserver(this);
- }
+}
+
+LocalFrame* FileInputType::FrameOrNull() const {
+ return GetElement().GetDocument().GetFrame();
}
void FileInputType::SetFilesFromDirectory(const String& path) {
@@ -434,26 +434,25 @@ void FileInputType::CopyNonAttributeProperties(const HTMLInputElement& source) {
file_list_->Append(source_list->item(i)->Clone());
}
-void FileInputType::HandleKeypressEvent(KeyboardEvent* event) {
+void FileInputType::HandleKeypressEvent(KeyboardEvent& event) {
if (GetElement().FastHasAttribute(webkitdirectoryAttr)) {
// Override to invoke the action on Enter key up (not press) to avoid
// repeats committing the file chooser.
- const String& key = event->key();
- if (key == "Enter") {
- event->SetDefaultHandled();
+ if (event.key() == "Enter") {
+ event.SetDefaultHandled();
return;
}
}
KeyboardClickableInputTypeView::HandleKeypressEvent(event);
}
-void FileInputType::HandleKeyupEvent(KeyboardEvent* event) {
+void FileInputType::HandleKeyupEvent(KeyboardEvent& event) {
if (GetElement().FastHasAttribute(webkitdirectoryAttr)) {
// Override to invoke the action on Enter key up (not press) to avoid
// repeats committing the file chooser.
- if (event->key() == "Enter") {
- GetElement().DispatchSimulatedClick(event);
- event->SetDefaultHandled();
+ if (event.key() == "Enter") {
+ GetElement().DispatchSimulatedClick(&event);
+ event.SetDefaultHandled();
return;
}
}
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 4227f174f05..f8453951ae8 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
@@ -47,8 +47,7 @@ class FileList;
class CORE_EXPORT FileInputType final : public InputType,
public KeyboardClickableInputTypeView,
- private FileChooserClient,
- private PopupOpeningObserver {
+ private FileChooserClient {
USING_GARBAGE_COLLECTED_MIXIN(FileInputType);
public:
@@ -73,7 +72,7 @@ class CORE_EXPORT FileInputType final : public InputType,
void AppendToFormData(FormData&) const override;
bool ValueMissing(const String&) const override;
String ValueMissingText() const override;
- void HandleDOMActivateEvent(Event*) override;
+ void HandleDOMActivateEvent(Event&) override;
LayoutObject* CreateLayoutObject(const ComputedStyle&) const override;
bool CanSetStringValue() const override;
FileList* Files() override;
@@ -94,11 +93,12 @@ class CORE_EXPORT FileInputType final : public InputType,
void CopyNonAttributeProperties(const HTMLInputElement&) override;
// KeyboardClickableInputTypeView overrides.
- void HandleKeypressEvent(KeyboardEvent*) override;
- void HandleKeyupEvent(KeyboardEvent*) override;
+ void HandleKeypressEvent(KeyboardEvent&) override;
+ void HandleKeyupEvent(KeyboardEvent&) override;
// FileChooserClient implementation.
void FilesChosen(const Vector<FileChooserFileInfo>&) override;
+ LocalFrame* FrameOrNull() const override;
// PopupOpeningObserver implementation.
void WillOpenPopup() override;
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 f962ee437d6..08bfc1d1e5a 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
@@ -10,11 +10,33 @@
#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/html_names.h"
+#include "third_party/blink/renderer/core/loader/empty_clients.h"
#include "third_party/blink/renderer/core/page/drag_data.h"
+#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
#include "third_party/blink/renderer/platform/wtf/date_math.h"
namespace blink {
+namespace {
+
+class WebKitDirectoryChromeClient : public EmptyChromeClient {
+ public:
+ void EnumerateChosenDirectory(FileChooser* chooser) override {
+ chooser->AddRef(); // Do same as ChromeClientImpl
+ static_cast<WebFileChooserCompletion*>(chooser)->DidChooseFile(
+ WebVector<WebString>());
+ }
+
+ void RegisterPopupOpeningObserver(PopupOpeningObserver*) override {
+ NOTREACHED() << "RegisterPopupOpeningObserver should not be called.";
+ }
+ void UnregisterPopupOpeningObserver(PopupOpeningObserver*) override {
+ NOTREACHED() << "UnregisterPopupOpeningObserver should not be called.";
+ }
+};
+
+} // namespace
+
TEST(FileInputTypeTest, createFileList) {
Vector<FileChooserFileInfo> files;
@@ -108,4 +130,24 @@ TEST(FileInputTypeTest, setFilesFromPaths) {
file_input->Files()->item(1)->GetPath());
}
+TEST(FileInputTypeTest, DropTouchesNoPopupOpeningObserver) {
+ Page::PageClients page_clients;
+ FillWithEmptyClients(page_clients);
+ auto* chrome_client = new WebKitDirectoryChromeClient;
+ page_clients.chrome_client = chrome_client;
+ auto page_holder = DummyPageHolder::Create(IntSize(), &page_clients);
+ Document& doc = page_holder->GetDocument();
+
+ doc.body()->SetInnerHTMLFromString("<input type=file webkitdirectory>");
+ auto& input = *ToHTMLInputElement(doc.body()->firstChild());
+
+ DragData drag_data(DataObject::Create(), FloatPoint(), FloatPoint(),
+ kDragOperationCopy);
+ drag_data.PlatformData()->Add(File::Create("/foo/bar"));
+ input.ReceiveDroppedFiles(&drag_data);
+
+ // The test passes if WebKitDirectoryChromeClient::
+ // UnregisterPopupOpeningObserver() was not called.
+}
+
} // namespace blink
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 13ad529582c..d7f49d9291f 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
@@ -104,43 +104,42 @@ void HTMLButtonElement::ParseAttribute(
}
}
-void HTMLButtonElement::DefaultEventHandler(Event* event) {
- if (event->type() == EventTypeNames::DOMActivate &&
- !IsDisabledFormControl()) {
+void HTMLButtonElement::DefaultEventHandler(Event& event) {
+ if (event.type() == EventTypeNames::DOMActivate && !IsDisabledFormControl()) {
if (Form() && type_ == SUBMIT) {
Form()->PrepareForSubmission(event, this);
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
}
if (Form() && type_ == RESET) {
Form()->reset();
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
}
}
- if (event->IsKeyboardEvent()) {
- if (event->type() == EventTypeNames::keydown &&
- ToKeyboardEvent(event)->key() == " ") {
+ if (event.IsKeyboardEvent()) {
+ if (event.type() == EventTypeNames::keydown &&
+ ToKeyboardEvent(event).key() == " ") {
SetActive(true);
// No setDefaultHandled() - IE dispatches a keypress in this case.
return;
}
- if (event->type() == EventTypeNames::keypress) {
- switch (ToKeyboardEvent(event)->charCode()) {
+ if (event.type() == EventTypeNames::keypress) {
+ switch (ToKeyboardEvent(event).charCode()) {
case '\r':
- DispatchSimulatedClick(event);
- event->SetDefaultHandled();
+ DispatchSimulatedClick(&event);
+ event.SetDefaultHandled();
return;
case ' ':
// Prevent scrolling down the page.
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
return;
}
}
- if (event->type() == EventTypeNames::keyup &&
- ToKeyboardEvent(event)->key() == " ") {
+ if (event.type() == EventTypeNames::keyup &&
+ ToKeyboardEvent(event).key() == " ") {
if (IsActive())
- DispatchSimulatedClick(event);
- event->SetDefaultHandled();
+ DispatchSimulatedClick(&event);
+ event.SetDefaultHandled();
return;
}
}
@@ -211,7 +210,7 @@ bool HTMLButtonElement::MatchesDefaultPseudoClass() const {
}
Node::InsertionNotificationRequest HTMLButtonElement::InsertedInto(
- ContainerNode* insertion_point) {
+ ContainerNode& insertion_point) {
InsertionNotificationRequest request =
HTMLFormControlElement::InsertedInto(insertion_point);
LogAddElementIfIsolatedWorldAndInDocument("button", typeAttr, formmethodAttr,
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 23da1dfd32d..240049aeaba 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
@@ -52,10 +52,10 @@ class HTMLButtonElement final : public HTMLFormControlElement {
// HTMLFormControlElement always creates one, but buttons don't need it.
bool AlwaysCreateUserAgentShadowRoot() const override { return false; }
- Node::InsertionNotificationRequest InsertedInto(ContainerNode*) override;
+ Node::InsertionNotificationRequest InsertedInto(ContainerNode&) override;
void ParseAttribute(const AttributeModificationParams&) override;
bool IsPresentationAttribute(const QualifiedName&) const override;
- void DefaultEventHandler(Event*) override;
+ void DefaultEventHandler(Event&) override;
bool HasActivationBehavior() const override;
void AppendToFormData(FormData&) override;
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 f0fd9883c82..ff5255a74c2 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
@@ -296,7 +296,7 @@ void HTMLFormControlElement::DidMoveToNewDocument(Document& old_document) {
}
Node::InsertionNotificationRequest HTMLFormControlElement::InsertedInto(
- ContainerNode* insertion_point) {
+ ContainerNode& insertion_point) {
ancestor_disabled_state_ = kAncestorDisabledStateUnknown;
// Force traversal to find ancestor
may_have_field_set_ancestor_ = true;
@@ -304,17 +304,17 @@ Node::InsertionNotificationRequest HTMLFormControlElement::InsertedInto(
SetNeedsWillValidateCheck();
HTMLElement::InsertedInto(insertion_point);
ListedElement::InsertedInto(insertion_point);
- FieldSetAncestorsSetNeedsValidityCheck(insertion_point);
+ FieldSetAncestorsSetNeedsValidityCheck(&insertion_point);
// Trigger for elements outside of forms.
- if (!formOwner() && insertion_point->isConnected())
+ if (!formOwner() && insertion_point.isConnected())
GetDocument().DidAssociateFormControl(this);
return kInsertionDone;
}
-void HTMLFormControlElement::RemovedFrom(ContainerNode* insertion_point) {
- FieldSetAncestorsSetNeedsValidityCheck(insertion_point);
+void HTMLFormControlElement::RemovedFrom(ContainerNode& insertion_point) {
+ FieldSetAncestorsSetNeedsValidityCheck(&insertion_point);
HideVisibleValidationMessage();
has_validation_message_ = false;
ancestor_disabled_state_ = kAncestorDisabledStateUnknown;
@@ -361,7 +361,7 @@ void HTMLFormControlElement::FieldSetAncestorsSetNeedsValidityCheck(
}
void HTMLFormControlElement::DispatchChangeEvent() {
- DispatchScopedEvent(Event::CreateBubble(EventTypeNames::change));
+ DispatchScopedEvent(*Event::CreateBubble(EventTypeNames::change));
}
HTMLFormElement* HTMLFormControlElement::formOwner() const {
@@ -544,7 +544,7 @@ bool HTMLFormControlElement::checkValidity(
return false;
Document* original_document = &GetDocument();
DispatchEventResult dispatch_result =
- DispatchEvent(Event::CreateCancelable(EventTypeNames::invalid));
+ DispatchEvent(*Event::CreateCancelable(EventTypeNames::invalid));
if (dispatch_result == DispatchEventResult::kNotCanceled &&
unhandled_invalid_controls && isConnected() &&
original_document == GetDocument())
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 a04b6f74193..7245757ade4 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
@@ -164,8 +164,8 @@ class CORE_EXPORT HTMLFormControlElement : public LabelableElement,
virtual void RequiredAttributeChanged();
virtual void DisabledAttributeChanged();
void AttachLayoutTree(AttachContext&) override;
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
- void RemovedFrom(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
+ void RemovedFrom(ContainerNode&) override;
void WillChangeForm() override;
void DidChangeForm() override;
void DidMoveToNewDocument(Document& old_document) override;
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 b34b281fd00..d85fbda8d19 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
@@ -118,7 +118,7 @@ TEST_F(HTMLFormControlElementTest, UpdateValidationMessageSkippedIfPrinting) {
SetHtmlInnerHTML("<body><input required id=input></body>");
ValidationMessageClient* validation_message_client =
new MockFormValidationMessageClient();
- GetPage().SetValidationMessageClient(validation_message_client);
+ GetPage().SetValidationMessageClientForTesting(validation_message_client);
Page::OrdinaryPages().insert(&GetPage());
HTMLInputElement* input = ToHTMLInputElement(GetElementById("input"));
@@ -137,7 +137,8 @@ TEST_F(HTMLFormControlElementTest, DoNotUpdateLayoutDuringDOMMutation) {
ToHTMLFormControlElement(GetDocument().QuerySelector("select"));
auto* const optgroup = GetDocument().CreateRawElement(HTMLNames::optgroupTag);
auto* validation_client = new MockFormValidationMessageClient();
- GetDocument().GetPage()->SetValidationMessageClient(validation_client);
+ GetDocument().GetPage()->SetValidationMessageClientForTesting(
+ validation_client);
select->setCustomValidity("foobar");
select->reportValidity();
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 430f7bc185b..0cae0aab952 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
@@ -40,16 +40,16 @@ HTMLFormControlElementWithState::HTMLFormControlElementWithState(
HTMLFormControlElementWithState::~HTMLFormControlElementWithState() = default;
Node::InsertionNotificationRequest
-HTMLFormControlElementWithState::InsertedInto(ContainerNode* insertion_point) {
- if (insertion_point->isConnected() && !ContainingShadowRoot())
+HTMLFormControlElementWithState::InsertedInto(ContainerNode& insertion_point) {
+ if (insertion_point.isConnected() && !ContainingShadowRoot())
GetDocument().GetFormController().RegisterStatefulFormControl(*this);
return HTMLFormControlElement::InsertedInto(insertion_point);
}
void HTMLFormControlElementWithState::RemovedFrom(
- ContainerNode* insertion_point) {
- if (insertion_point->isConnected() && !ContainingShadowRoot() &&
- !insertion_point->ContainingShadowRoot())
+ ContainerNode& insertion_point) {
+ if (insertion_point.isConnected() && !ContainingShadowRoot() &&
+ !insertion_point.ContainingShadowRoot())
GetDocument().GetFormController().UnregisterStatefulFormControl(*this);
HTMLFormControlElement::RemovedFrom(insertion_point);
}
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 fab6339d451..c9933846098 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
@@ -55,13 +55,17 @@ class CORE_EXPORT HTMLFormControlElementWithState
void NotifyFormStateChanged();
void Trace(Visitor*) override;
+ bool UserHasEditedTheField() const { return user_has_edited_the_field_; }
+ // This is only used in tests, to fake the user's action
+ void SetUserHasEditedTheFieldForTest() { user_has_edited_the_field_ = true; }
protected:
+ bool user_has_edited_the_field_ = false;
HTMLFormControlElementWithState(const QualifiedName& tag_name, Document&);
void FinishParsingChildren() override;
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
- void RemovedFrom(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
+ void RemovedFrom(ContainerNode&) override;
bool IsFormControlElementWithState() const final;
private:
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 7fd27d29aae..13167057f5b 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
@@ -105,10 +105,10 @@ bool HTMLFormElement::IsValidElement() {
}
Node::InsertionNotificationRequest HTMLFormElement::InsertedInto(
- ContainerNode* insertion_point) {
+ ContainerNode& insertion_point) {
HTMLElement::InsertedInto(insertion_point);
LogAddElementIfIsolatedWorldAndInDocument("form", methodAttr, actionAttr);
- if (insertion_point->isConnected())
+ if (insertion_point.isConnected())
GetDocument().DidAssociateFormControl(this);
return kInsertionDone;
}
@@ -119,7 +119,7 @@ void NotifyFormRemovedFromTree(const T& elements, Node& root) {
element->FormRemovedFromTree(root);
}
-void HTMLFormElement::RemovedFrom(ContainerNode* insertion_point) {
+void HTMLFormElement::RemovedFrom(ContainerNode& insertion_point) {
// We don't need to take care of form association by 'form' content
// attribute becuse IdTargetObserver handles it.
if (has_elements_associated_by_parser_) {
@@ -130,7 +130,7 @@ void HTMLFormElement::RemovedFrom(ContainerNode* insertion_point) {
} else {
ListedElement::List elements;
CollectListedElements(
- NodeTraversal::HighestAncestorOrSelf(*insertion_point), elements);
+ NodeTraversal::HighestAncestorOrSelf(insertion_point), elements);
NotifyFormRemovedFromTree(elements, root);
CollectListedElements(root, elements);
NotifyFormRemovedFromTree(elements, root);
@@ -142,7 +142,7 @@ void HTMLFormElement::RemovedFrom(ContainerNode* insertion_point) {
} else {
HeapVector<Member<HTMLImageElement>> images;
CollectImageElements(
- NodeTraversal::HighestAncestorOrSelf(*insertion_point), images);
+ NodeTraversal::HighestAncestorOrSelf(insertion_point), images);
NotifyFormRemovedFromTree(images, root);
CollectImageElements(root, images);
NotifyFormRemovedFromTree(images, root);
@@ -177,7 +177,7 @@ HTMLElement* HTMLFormElement::item(unsigned index) {
return elements()->item(index);
}
-void HTMLFormElement::SubmitImplicitly(Event* event,
+void HTMLFormElement::SubmitImplicitly(Event& event,
bool from_implicit_submission_trigger) {
int submission_trigger_count = 0;
bool seen_default_button = false;
@@ -189,7 +189,7 @@ void HTMLFormElement::SubmitImplicitly(Event* event,
if (from_implicit_submission_trigger)
seen_default_button = true;
if (control->IsSuccessfulSubmitButton()) {
- control->DispatchSimulatedClick(event);
+ control->DispatchSimulatedClick(&event);
return;
}
if (from_implicit_submission_trigger) {
@@ -249,7 +249,7 @@ bool HTMLFormElement::ValidateInteractively() {
}
void HTMLFormElement::PrepareForSubmission(
- Event* event,
+ Event& event,
HTMLFormControlElement* submit_button) {
LocalFrame* frame = GetDocument().GetFrame();
if (!frame || is_submitting_ || in_user_js_submit_event_)
@@ -289,14 +289,13 @@ void HTMLFormElement::PrepareForSubmission(
"the end of the file. Please add an explicit end tag "
"('</" +
tag_name + ">')"));
- DispatchEvent(Event::Create(EventTypeNames::error));
+ DispatchEvent(*Event::Create(EventTypeNames::error));
return;
}
}
}
bool skip_validation = !GetDocument().GetPage() || NoValidate();
- DCHECK(event);
if (submit_button && submit_button->FormNoValidate())
skip_validation = true;
@@ -311,12 +310,12 @@ void HTMLFormElement::PrepareForSubmission(
true);
frame->Client()->DispatchWillSendSubmitEvent(this);
should_submit =
- DispatchEvent(Event::CreateCancelableBubble(EventTypeNames::submit)) ==
+ DispatchEvent(*Event::CreateCancelableBubble(EventTypeNames::submit)) ==
DispatchEventResult::kNotCanceled;
}
if (should_submit) {
planned_navigation_ = nullptr;
- Submit(event, submit_button);
+ Submit(&event, submit_button);
}
if (!planned_navigation_)
return;
@@ -409,7 +408,7 @@ void HTMLFormElement::ConstructFormDataSet(
// TODO(tkent): We might move the event dispatching later than the
// ListedElements iteration.
if (RuntimeEnabledFeatures::FormDataEventEnabled())
- DispatchEvent(FormDataEvent::Create(form_data));
+ DispatchEvent(*FormDataEvent::Create(form_data));
if (submit_button)
submit_button->SetActivatedSubmit(true);
@@ -502,7 +501,7 @@ void HTMLFormElement::reset() {
is_in_reset_function_ = true;
- if (DispatchEvent(Event::CreateCancelableBubble(EventTypeNames::reset)) !=
+ if (DispatchEvent(*Event::CreateCancelableBubble(EventTypeNames::reset)) !=
DispatchEventResult::kNotCanceled) {
is_in_reset_function_ = false;
return;
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 3b79057bd29..9dcf98152b4 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,11 +71,11 @@ class CORE_EXPORT HTMLFormElement final : public HTMLElement {
void Disassociate(HTMLImageElement&);
void DidAssociateByParser();
- void PrepareForSubmission(Event*, HTMLFormControlElement* submit_button);
+ void PrepareForSubmission(Event&, HTMLFormControlElement* submit_button);
void submitFromJavaScript();
void reset();
- void SubmitImplicitly(Event*, bool from_implicit_submission_trigger);
+ void SubmitImplicitly(Event&, bool from_implicit_submission_trigger);
String GetName() const;
@@ -115,8 +115,8 @@ class CORE_EXPORT HTMLFormElement final : public HTMLElement {
private:
explicit HTMLFormElement(Document&);
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
- void RemovedFrom(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
+ void RemovedFrom(ContainerNode&) override;
void FinishParsingChildren() override;
void HandleLocalEvents(Event&) override;
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 da1847ae422..d335302cd47 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
@@ -1230,23 +1230,23 @@ void HTMLInputElement::SetValueFromRenderer(const String& value) {
}
EventDispatchHandlingState* HTMLInputElement::PreDispatchEventHandler(
- Event* event) {
- if (event->type() == EventTypeNames::textInput &&
+ Event& event) {
+ if (event.type() == EventTypeNames::textInput &&
input_type_view_->ShouldSubmitImplicitly(event)) {
- event->stopPropagation();
+ event.stopPropagation();
return nullptr;
}
- if (event->type() != EventTypeNames::click)
+ if (event.type() != EventTypeNames::click)
return nullptr;
- if (!event->IsMouseEvent() ||
- ToMouseEvent(event)->button() !=
+ if (!event.IsMouseEvent() ||
+ ToMouseEvent(event).button() !=
static_cast<short>(WebPointerProperties::Button::kLeft))
return nullptr;
return input_type_view_->WillDispatchClick();
}
void HTMLInputElement::PostDispatchEventHandler(
- Event* event,
+ Event& event,
EventDispatchHandlingState* state) {
if (!state)
return;
@@ -1254,18 +1254,18 @@ void HTMLInputElement::PostDispatchEventHandler(
*static_cast<ClickHandlingState*>(state));
}
-void HTMLInputElement::DefaultEventHandler(Event* evt) {
- if (evt->IsMouseEvent() && evt->type() == EventTypeNames::click &&
- ToMouseEvent(evt)->button() ==
+void HTMLInputElement::DefaultEventHandler(Event& evt) {
+ if (evt.IsMouseEvent() && evt.type() == EventTypeNames::click &&
+ ToMouseEvent(evt).button() ==
static_cast<short>(WebPointerProperties::Button::kLeft)) {
input_type_view_->HandleClickEvent(ToMouseEvent(evt));
- if (evt->DefaultHandled())
+ if (evt.DefaultHandled())
return;
}
- if (evt->IsKeyboardEvent() && evt->type() == EventTypeNames::keydown) {
+ if (evt.IsKeyboardEvent() && evt.type() == EventTypeNames::keydown) {
input_type_view_->HandleKeydownEvent(ToKeyboardEvent(evt));
- if (evt->DefaultHandled())
+ if (evt.DefaultHandled())
return;
}
@@ -1273,11 +1273,11 @@ void HTMLInputElement::DefaultEventHandler(Event* evt) {
// all events in text fields. Makes editing keyboard handling take precedence
// over the keydown and keypress handling in this function.
bool call_base_class_early =
- IsTextField() && (evt->type() == EventTypeNames::keydown ||
- evt->type() == EventTypeNames::keypress);
+ IsTextField() && (evt.type() == EventTypeNames::keydown ||
+ evt.type() == EventTypeNames::keypress);
if (call_base_class_early) {
TextControlElement::DefaultEventHandler(evt);
- if (evt->DefaultHandled())
+ if (evt.DefaultHandled())
return;
}
@@ -1287,23 +1287,23 @@ void HTMLInputElement::DefaultEventHandler(Event* evt) {
// the element, or presses enter while it is the active element. JavaScript
// code wishing to activate the element must dispatch a DOMActivate event - a
// click event will not do the job.
- if (evt->type() == EventTypeNames::DOMActivate) {
+ if (evt.type() == EventTypeNames::DOMActivate) {
input_type_view_->HandleDOMActivateEvent(evt);
- if (evt->DefaultHandled())
+ if (evt.DefaultHandled())
return;
}
// 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() == EventTypeNames::keypress) {
+ if (evt.IsKeyboardEvent() && evt.type() == EventTypeNames::keypress) {
input_type_view_->HandleKeypressEvent(ToKeyboardEvent(evt));
- if (evt->DefaultHandled())
+ if (evt.DefaultHandled())
return;
}
- if (evt->IsKeyboardEvent() && evt->type() == EventTypeNames::keyup) {
+ if (evt.IsKeyboardEvent() && evt.type() == EventTypeNames::keyup) {
input_type_view_->HandleKeyupEvent(ToKeyboardEvent(evt));
- if (evt->DefaultHandled())
+ if (evt.DefaultHandled())
return;
}
@@ -1327,24 +1327,24 @@ void HTMLInputElement::DefaultEventHandler(Event* evt) {
form_for_submission->SubmitImplicitly(evt,
CanTriggerImplicitSubmission());
}
- evt->SetDefaultHandled();
+ evt.SetDefaultHandled();
return;
}
- if (evt->IsBeforeTextInsertedEvent()) {
+ if (evt.IsBeforeTextInsertedEvent()) {
input_type_view_->HandleBeforeTextInsertedEvent(
- static_cast<BeforeTextInsertedEvent*>(evt));
+ static_cast<BeforeTextInsertedEvent&>(evt));
}
- if (evt->IsMouseEvent() && evt->type() == EventTypeNames::mousedown) {
+ if (evt.IsMouseEvent() && evt.type() == EventTypeNames::mousedown) {
input_type_view_->HandleMouseDownEvent(ToMouseEvent(evt));
- if (evt->DefaultHandled())
+ if (evt.DefaultHandled())
return;
}
input_type_view_->ForwardEvent(evt);
- if (!call_base_class_early && !evt->DefaultHandled())
+ if (!call_base_class_early && !evt.DefaultHandled())
TextControlElement::DefaultEventHandler(evt);
}
@@ -1540,18 +1540,18 @@ void HTMLInputElement::DidChangeForm() {
}
Node::InsertionNotificationRequest HTMLInputElement::InsertedInto(
- ContainerNode* insertion_point) {
+ ContainerNode& insertion_point) {
TextControlElement::InsertedInto(insertion_point);
- if (insertion_point->isConnected() && !Form())
+ if (insertion_point.isConnected() && !Form())
AddToRadioButtonGroup();
ResetListAttributeTargetObserver();
LogAddElementIfIsolatedWorldAndInDocument("input", typeAttr, formactionAttr);
return kInsertionShouldCallDidNotifySubtreeInsertions;
}
-void HTMLInputElement::RemovedFrom(ContainerNode* insertion_point) {
+void HTMLInputElement::RemovedFrom(ContainerNode& insertion_point) {
input_type_view_->ClosePopupView();
- if (insertion_point->isConnected() && !Form())
+ if (insertion_point.isConnected() && !Form())
RemoveFromRadioButtonGroup();
TextControlElement::RemovedFrom(insertion_point);
DCHECK(!isConnected());
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 d87939dcde0..69c79368486 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
@@ -306,7 +306,7 @@ class CORE_EXPORT HTMLInputElement
protected:
HTMLInputElement(Document&, const CreateElementFlags);
- void DefaultEventHandler(Event*) override;
+ void DefaultEventHandler(Event&) override;
void CreateShadowSubtree();
private:
@@ -314,8 +314,8 @@ class CORE_EXPORT HTMLInputElement
void WillChangeForm() final;
void DidChangeForm() final;
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
- void RemovedFrom(ContainerNode*) final;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
+ void RemovedFrom(ContainerNode&) final;
void DidMoveToNewDocument(Document& old_document) final;
bool HasActivationBehavior() const override;
@@ -361,8 +361,8 @@ class CORE_EXPORT HTMLInputElement
void ResetImpl() final;
bool SupportsAutofocus() const final;
- EventDispatchHandlingState* PreDispatchEventHandler(Event*) final;
- void PostDispatchEventHandler(Event*, EventDispatchHandlingState*) final;
+ EventDispatchHandlingState* PreDispatchEventHandler(Event&) final;
+ void PostDispatchEventHandler(Event&, EventDispatchHandlingState*) final;
bool IsURLAttribute(const Attribute&) const final;
bool HasLegalLinkAttribute(const QualifiedName&) const final;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_input_element_test.cc b/chromium/third_party/blink/renderer/core/html/forms/html_input_element_test.cc
index 83cdd180392..ba604cffda7 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
@@ -160,7 +160,7 @@ TEST_F(HTMLInputElementTest, RadioKeyDownDCHECKFailure) {
radio2.setAttribute(HTMLNames::styleAttr, "position:fixed");
KeyboardEventInit init;
init.setKey("ArrowRight");
- radio1.DefaultEventHandler(new KeyboardEvent("keydown", init));
+ radio1.DefaultEventHandler(*new KeyboardEvent("keydown", init));
EXPECT_EQ(GetDocument().ActiveElement(), &radio2);
}
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 ea36f0bd3c8..8dcffb2b7e5 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
@@ -137,18 +137,18 @@ bool HTMLLabelElement::IsInInteractiveContent(Node* node) const {
return false;
}
-void HTMLLabelElement::DefaultEventHandler(Event* evt) {
- if (evt->type() == EventTypeNames::click && !processing_click_) {
+void HTMLLabelElement::DefaultEventHandler(Event& evt) {
+ if (evt.type() == EventTypeNames::click && !processing_click_) {
HTMLElement* element = control();
// If we can't find a control or if the control received the click
// event, then there's no need for us to do anything.
if (!element ||
- (evt->target() && element->IsShadowIncludingInclusiveAncestorOf(
- evt->target()->ToNode())))
+ (evt.target() &&
+ element->IsShadowIncludingInclusiveAncestorOf(evt.target()->ToNode())))
return;
- if (evt->target() && IsInInteractiveContent(evt->target()->ToNode()))
+ if (evt.target() && IsInInteractiveContent(evt.target()->ToNode()))
return;
// Behaviour of label element is as follows:
@@ -167,7 +167,7 @@ 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()) {
+ if (evt.IsMouseEvent() && ToMouseEvent(evt).HasPosition()) {
if (LocalFrame* frame = GetDocument().GetFrame()) {
// Check if there is a selection and click is not on the
// selection.
@@ -178,7 +178,7 @@ void HTMLLabelElement::DefaultEventHandler(Event* evt) {
!frame->GetEventHandler()
.GetSelectionController()
.MouseDownWasSingleClickInSelection() &&
- evt->target()->ToNode()->CanStartSelection())
+ evt.target()->ToNode()->CanStartSelection())
is_label_text_selected = true;
// If selection is there and is single click i.e. text is
// selected by dragging over label text, then return.
@@ -186,7 +186,7 @@ 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 && ToMouseEvent(evt).ClickCount() == 1)
return;
}
}
@@ -206,11 +206,11 @@ void HTMLLabelElement::DefaultEventHandler(Event* evt) {
}
// Click the corresponding control.
- element->DispatchSimulatedClick(evt);
+ element->DispatchSimulatedClick(&evt);
processing_click_ = false;
- evt->SetDefaultHandled();
+ evt.SetDefaultHandled();
}
HTMLElement::DefaultEventHandler(evt);
diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_label_element.h b/chromium/third_party/blink/renderer/core/html/forms/html_label_element.h
index 9bfb702444a..884851e4d53 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/html_label_element.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/html_label_element.h
@@ -53,7 +53,7 @@ class CORE_EXPORT HTMLLabelElement final : public HTMLElement {
void SetHovered(bool = true) override;
// Overridden to either click() or focus() the corresponding control.
- void DefaultEventHandler(Event*) override;
+ void DefaultEventHandler(Event&) override;
bool HasActivationBehavior() const override;
void focus(const FocusParams&) override;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_legend_element.cc b/chromium/third_party/blink/renderer/core/html/forms/html_legend_element.cc
index 4317588c878..2efbd56c96a 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/html_legend_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/html_legend_element.cc
@@ -26,6 +26,7 @@
#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/use_counter.h"
#include "third_party/blink/renderer/core/html/forms/html_field_set_element.h"
#include "third_party/blink/renderer/core/html/forms/html_form_control_element.h"
#include "third_party/blink/renderer/core/html_names.h"
@@ -48,7 +49,13 @@ HTMLFormControlElement* HTMLLegendElement::AssociatedControl() {
// Find first form element inside the fieldset that is not a legend element.
// FIXME: Should we consider tabindex?
- return Traversal<HTMLFormControlElement>::Next(*fieldset, fieldset);
+ if (auto* control =
+ Traversal<HTMLFormControlElement>::Next(*fieldset, fieldset)) {
+ UseCounter::Count(GetDocument(),
+ WebFeature::kLegendDelegateFocusOrAccessKey);
+ return control;
+ }
+ return nullptr;
}
void HTMLLegendElement::focus(const FocusParams& params) {
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 37bebed4f77..873fe5617ad 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
@@ -88,17 +88,17 @@ bool HTMLOptGroupElement::MatchesEnabledPseudoClass() const {
}
Node::InsertionNotificationRequest HTMLOptGroupElement::InsertedInto(
- ContainerNode* insertion_point) {
+ ContainerNode& insertion_point) {
HTMLElement::InsertedInto(insertion_point);
if (HTMLSelectElement* select = OwnerSelectElement()) {
- if (insertion_point == select)
+ if (&insertion_point == select)
select->OptGroupInsertedOrRemoved(*this);
}
return kInsertionDone;
}
-void HTMLOptGroupElement::RemovedFrom(ContainerNode* insertion_point) {
- if (auto* select = ToHTMLSelectElementOrNull(*insertion_point)) {
+void HTMLOptGroupElement::RemovedFrom(ContainerNode& insertion_point) {
+ if (auto* select = ToHTMLSelectElementOrNull(insertion_point)) {
if (!parentNode())
select->OptGroupInsertedOrRemoved(*this);
}
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 52cb07a2a04..759d835e1bc 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
@@ -57,8 +57,8 @@ class CORE_EXPORT HTMLOptGroupElement final : public HTMLElement {
void AccessKeyAction(bool send_mouse_events) override;
void DidAddUserAgentShadowRoot(ShadowRoot&) override;
bool MatchesEnabledPseudoClass() const override;
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
- void RemovedFrom(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
+ void RemovedFrom(ContainerNode&) override;
void UpdateGroupLabel();
};
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 09cc2e27ee8..7b5479e672e 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
@@ -329,22 +329,22 @@ String HTMLOptionElement::DefaultToolTip() const {
}
Node::InsertionNotificationRequest HTMLOptionElement::InsertedInto(
- ContainerNode* insertion_point) {
+ ContainerNode& insertion_point) {
HTMLElement::InsertedInto(insertion_point);
if (HTMLSelectElement* select = OwnerSelectElement()) {
- if (insertion_point == select || (IsHTMLOptGroupElement(*insertion_point) &&
- insertion_point->parentNode() == select))
+ if (&insertion_point == select || (IsHTMLOptGroupElement(insertion_point) &&
+ insertion_point.parentNode() == select))
select->OptionInserted(*this, is_selected_);
}
return kInsertionDone;
}
-void HTMLOptionElement::RemovedFrom(ContainerNode* insertion_point) {
- if (auto* select = ToHTMLSelectElementOrNull(*insertion_point)) {
+void HTMLOptionElement::RemovedFrom(ContainerNode& insertion_point) {
+ if (auto* select = ToHTMLSelectElementOrNull(insertion_point)) {
if (!parentNode() || IsHTMLOptGroupElement(*parentNode()))
select->OptionRemoved(*this);
- } else if (IsHTMLOptGroupElement(*insertion_point)) {
- if (auto* select = ToHTMLSelectElementOrNull(insertion_point->parentNode()))
+ } else if (IsHTMLOptGroupElement(insertion_point)) {
+ if (auto* select = ToHTMLSelectElementOrNull(insertion_point.parentNode()))
select->OptionRemoved(*this);
}
HTMLElement::RemovedFrom(insertion_point);
@@ -392,11 +392,4 @@ bool HTMLOptionElement::IsDisplayNone() const {
return !style || style->Display() == EDisplay::kNone;
}
-String HTMLOptionElement::innerText() {
- // A workaround for crbug.com/424578. We add ShadowRoot to an OPTION, but
- // innerText behavior for Shadow DOM is unclear. We just return the same
- // string before adding ShadowRoot.
- return textContent();
-}
-
} // namespace blink
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 22a344809c6..854489f5b46 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
@@ -98,11 +98,10 @@ 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;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
+ void RemovedFrom(ContainerNode&) override;
void AccessKeyAction(bool) override;
void ChildrenChanged(const ChildrenChange&) override;
- String innerText() override;
void DidAddUserAgentShadowRoot(ShadowRoot&) override;
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 0f81481f811..659073195e0 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
@@ -46,6 +46,7 @@
#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/html/forms/form_controller.h"
@@ -1141,7 +1142,8 @@ size_t HTMLSelectElement::SearchOptionsForValue(const String& value,
size_t list_index_start,
size_t list_index_end) const {
const ListItems& items = GetListItems();
- size_t loop_end_index = std::min(items.size(), list_index_end);
+ size_t loop_end_index =
+ std::min(static_cast<size_t>(items.size()), list_index_end);
for (size_t i = list_index_start; i < loop_end_index; ++i) {
if (!IsHTMLOptionElement(items[i]))
continue;
@@ -1244,7 +1246,7 @@ void HTMLSelectElement::ResetImpl() {
SetNeedsValidityCheck();
}
-void HTMLSelectElement::HandlePopupOpenKeyboardEvent(Event* event) {
+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
@@ -1258,13 +1260,13 @@ void HTMLSelectElement::HandlePopupOpenKeyboardEvent(Event* event) {
// from the menu.
SaveLastSelection();
ShowPopup();
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
return;
}
bool HTMLSelectElement::ShouldOpenPopupForKeyDownEvent(
- KeyboardEvent* key_event) {
- const String& key = key_event->key();
+ const KeyboardEvent& key_event) {
+ const String& key = key_event.key();
LayoutTheme& layout_theme = LayoutTheme::GetTheme();
if (IsSpatialNavigationEnabled(GetDocument().GetFrame()))
@@ -1273,26 +1275,27 @@ bool HTMLSelectElement::ShouldOpenPopupForKeyDownEvent(
return ((layout_theme.PopsMenuByArrowKeys() &&
(key == "ArrowDown" || key == "ArrowUp")) ||
(layout_theme.PopsMenuByAltDownUpOrF4Key() &&
- (key == "ArrowDown" || key == "ArrowUp") && key_event->altKey()) ||
+ (key == "ArrowDown" || key == "ArrowUp") && key_event.altKey()) ||
(layout_theme.PopsMenuByAltDownUpOrF4Key() &&
- (!key_event->altKey() && !key_event->ctrlKey() && key == "F4")));
+ (!key_event.altKey() && !key_event.ctrlKey() && key == "F4")));
}
-bool HTMLSelectElement::ShouldOpenPopupForKeyPressEvent(KeyboardEvent* event) {
+bool HTMLSelectElement::ShouldOpenPopupForKeyPressEvent(
+ const KeyboardEvent& event) {
LayoutTheme& layout_theme = LayoutTheme::GetTheme();
- int key_code = event->keyCode();
+ int key_code = event.keyCode();
- return ((layout_theme.PopsMenuBySpaceKey() && event->keyCode() == ' ' &&
+ return ((layout_theme.PopsMenuBySpaceKey() && key_code == ' ' &&
!type_ahead_.HasActiveSession(event)) ||
(layout_theme.PopsMenuByReturnKey() && key_code == '\r'));
}
-void HTMLSelectElement::MenuListDefaultEventHandler(Event* event) {
- if (event->type() == EventTypeNames::keydown) {
- if (!GetLayoutObject() || !event->IsKeyboardEvent())
+void HTMLSelectElement::MenuListDefaultEventHandler(Event& event) {
+ if (event.type() == EventTypeNames::keydown) {
+ if (!GetLayoutObject() || !event.IsKeyboardEvent())
return;
- KeyboardEvent* key_event = ToKeyboardEvent(event);
+ auto& key_event = ToKeyboardEvent(event);
if (ShouldOpenPopupForKeyDownEvent(key_event)) {
HandlePopupOpenKeyboardEvent(event);
return;
@@ -1315,10 +1318,10 @@ void HTMLSelectElement::MenuListDefaultEventHandler(Event* event) {
int ignore_modifiers = WebInputEvent::kShiftKey |
WebInputEvent::kControlKey | WebInputEvent::kAltKey |
WebInputEvent::kMetaKey;
- if (key_event->GetModifiers() & ignore_modifiers)
+ if (key_event.GetModifiers() & ignore_modifiers)
return;
- const String& key = key_event->key();
+ const String& key = key_event.key();
bool handled = true;
const ListItems& list_items = GetListItems();
HTMLOptionElement* option = SelectedOption();
@@ -1345,24 +1348,24 @@ void HTMLSelectElement::MenuListDefaultEventHandler(Event* event) {
}
if (handled)
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
}
- if (event->type() == EventTypeNames::keypress) {
- if (!GetLayoutObject() || !event->IsKeyboardEvent())
+ if (event.type() == EventTypeNames::keypress) {
+ if (!GetLayoutObject() || !event.IsKeyboardEvent())
return;
- int key_code = ToKeyboardEvent(event)->keyCode();
+ 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();
+ event.SetDefaultHandled();
return;
}
- KeyboardEvent* key_event = ToKeyboardEvent(event);
+ auto& key_event = ToKeyboardEvent(event);
if (ShouldOpenPopupForKeyPressEvent(key_event)) {
HandlePopupOpenKeyboardEvent(event);
return;
@@ -1372,18 +1375,18 @@ void HTMLSelectElement::MenuListDefaultEventHandler(Event* event) {
if (Form())
Form()->SubmitImplicitly(event, false);
DispatchInputAndChangeEventForMenuList();
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
}
}
- if (event->type() == EventTypeNames::mousedown && event->IsMouseEvent() &&
- ToMouseEvent(event)->button() ==
+ if (event.type() == EventTypeNames::mousedown && event.IsMouseEvent() &&
+ ToMouseEvent(event).button() ==
static_cast<short>(WebPointerProperties::Button::kLeft)) {
InputDeviceCapabilities* source_capabilities =
GetDocument()
.domWindow()
->GetInputDeviceCapabilities()
- ->FiresTouchEvents(ToMouseEvent(event)->FromTouch());
+ ->FiresTouchEvents(ToMouseEvent(event).FromTouch());
focus(FocusParams(SelectionBehaviorOnFocus::kRestore, kWebFocusTypeNone,
source_capabilities));
if (GetLayoutObject() && GetLayoutObject()->IsMenuList() &&
@@ -1402,7 +1405,7 @@ void HTMLSelectElement::MenuListDefaultEventHandler(Event* event) {
ShowPopup();
}
}
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
}
}
@@ -1485,8 +1488,8 @@ void HTMLSelectElement::HandleMouseRelease() {
ListBoxOnChange();
}
-void HTMLSelectElement::ListBoxDefaultEventHandler(Event* event) {
- if (event->type() == EventTypeNames::gesturetap && event->IsGestureEvent()) {
+void HTMLSelectElement::ListBoxDefaultEventHandler(Event& event) {
+ if (event.type() == EventTypeNames::gesturetap && 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.
@@ -1494,18 +1497,18 @@ void HTMLSelectElement::ListBoxDefaultEventHandler(Event* event) {
return;
// Convert to coords relative to the list box if needed.
- GestureEvent& gesture_event = ToGestureEvent(*event);
+ auto& gesture_event = ToGestureEvent(event);
if (HTMLOptionElement* option = EventTargetOption(gesture_event)) {
if (!IsDisabledFormControl()) {
UpdateSelectedState(option, true, gesture_event.shiftKey());
ListBoxOnChange();
}
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
}
- } else if (event->type() == EventTypeNames::mousedown &&
- event->IsMouseEvent() &&
- ToMouseEvent(event)->button() ==
+ } else if (event.type() == EventTypeNames::mousedown &&
+ event.IsMouseEvent() &&
+ ToMouseEvent(event).button() ==
static_cast<short>(WebPointerProperties::Button::kLeft)) {
focus();
// Calling focus() may cause us to lose our layoutObject, in which case
@@ -1515,29 +1518,29 @@ void HTMLSelectElement::ListBoxDefaultEventHandler(Event* event) {
return;
// Convert to coords relative to the list box if needed.
- MouseEvent* mouse_event = ToMouseEvent(event);
- if (HTMLOptionElement* option = EventTargetOption(*mouse_event)) {
+ 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());
+ UpdateSelectedState(option, mouse_event.metaKey(),
+ mouse_event.shiftKey());
#else
- UpdateSelectedState(option, mouse_event->ctrlKey(),
- mouse_event->shiftKey());
+ UpdateSelectedState(option, mouse_event.ctrlKey(),
+ mouse_event.shiftKey());
#endif
}
if (LocalFrame* frame = GetDocument().GetFrame())
frame->GetEventHandler().SetMouseDownMayStartAutoscroll();
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
}
- } else if (event->type() == EventTypeNames::mousemove &&
- event->IsMouseEvent()) {
- MouseEvent* mouse_event = ToMouseEvent(event);
- if (mouse_event->button() !=
+ } else if (event.type() == EventTypeNames::mousemove &&
+ event.IsMouseEvent()) {
+ auto& mouse_event = ToMouseEvent(event);
+ if (mouse_event.button() !=
static_cast<short>(WebPointerProperties::Button::kLeft) ||
- !mouse_event->ButtonDown())
+ !mouse_event.ButtonDown())
return;
if (LayoutObject* object = GetLayoutObject())
@@ -1551,7 +1554,7 @@ void HTMLSelectElement::ListBoxDefaultEventHandler(Event* event) {
if (last_on_change_selection_.IsEmpty())
return;
- if (HTMLOptionElement* option = EventTargetOption(*mouse_event)) {
+ if (HTMLOptionElement* option = EventTargetOption(mouse_event)) {
if (!IsDisabledFormControl()) {
if (is_multiple_) {
// Only extend selection if there is something selected.
@@ -1568,9 +1571,8 @@ void HTMLSelectElement::ListBoxDefaultEventHandler(Event* event) {
}
}
- } else if (event->type() == EventTypeNames::mouseup &&
- event->IsMouseEvent() &&
- ToMouseEvent(event)->button() ==
+ } else if (event.type() == EventTypeNames::mouseup && event.IsMouseEvent() &&
+ ToMouseEvent(event).button() ==
static_cast<short>(WebPointerProperties::Button::kLeft) &&
GetLayoutObject()) {
if (GetDocument().GetPage() &&
@@ -1582,10 +1584,10 @@ void HTMLSelectElement::ListBoxDefaultEventHandler(Event* event) {
else
HandleMouseRelease();
- } else if (event->type() == EventTypeNames::keydown) {
- if (!event->IsKeyboardEvent())
+ } else if (event.type() == EventTypeNames::keydown) {
+ if (!event.IsKeyboardEvent())
return;
- const String& key = ToKeyboardEvent(event)->key();
+ const String& key = ToKeyboardEvent(event).key();
bool handled = false;
HTMLOptionElement* end_option = nullptr;
@@ -1653,7 +1655,7 @@ void HTMLSelectElement::ListBoxDefaultEventHandler(Event* event) {
SetActiveSelectionEnd(end_option);
bool select_new_item =
- !is_multiple_ || ToKeyboardEvent(event)->shiftKey() ||
+ !is_multiple_ || ToKeyboardEvent(event).shiftKey() ||
!IsSpatialNavigationEnabled(GetDocument().GetFrame());
if (select_new_item)
active_selection_state_ = true;
@@ -1661,7 +1663,7 @@ void HTMLSelectElement::ListBoxDefaultEventHandler(Event* event) {
// other options, then set the anchor index equal to the end index.
bool deselect_others =
!is_multiple_ ||
- (!ToKeyboardEvent(event)->shiftKey() && select_new_item);
+ (!ToKeyboardEvent(event).shiftKey() && select_new_item);
if (!active_selection_anchor_ || deselect_others) {
if (deselect_others)
DeselectItemsWithoutValidation();
@@ -1676,18 +1678,18 @@ void HTMLSelectElement::ListBoxDefaultEventHandler(Event* event) {
ScrollToSelection();
}
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
}
- } else if (event->type() == EventTypeNames::keypress) {
- if (!event->IsKeyboardEvent())
+ } else if (event.type() == EventTypeNames::keypress) {
+ if (!event.IsKeyboardEvent())
return;
- int key_code = ToKeyboardEvent(event)->keyCode();
+ int key_code = ToKeyboardEvent(event).keyCode();
if (key_code == '\r') {
if (Form())
Form()->SubmitImplicitly(event, false);
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
} else if (is_multiple_ && key_code == ' ' &&
IsSpatialNavigationEnabled(GetDocument().GetFrame())) {
// Use space to toggle selection change.
@@ -1695,15 +1697,20 @@ void HTMLSelectElement::ListBoxDefaultEventHandler(Event* event) {
UpdateSelectedState(active_selection_end_.Get(), true /*multi*/,
false /*shift*/);
ListBoxOnChange();
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
}
}
}
-void HTMLSelectElement::DefaultEventHandler(Event* event) {
+void HTMLSelectElement::DefaultEventHandler(Event& event) {
if (!GetLayoutObject())
return;
+ if (event.type() == EventTypeNames::click ||
+ event.type() == EventTypeNames::change) {
+ user_has_edited_the_field_ = true;
+ }
+
if (IsDisabledFormControl()) {
HTMLFormControlElementWithState::DefaultEventHandler(event);
return;
@@ -1713,16 +1720,16 @@ void HTMLSelectElement::DefaultEventHandler(Event* event) {
MenuListDefaultEventHandler(event);
else
ListBoxDefaultEventHandler(event);
- if (event->DefaultHandled())
+ if (event.DefaultHandled())
return;
- if (event->type() == EventTypeNames::keypress && event->IsKeyboardEvent()) {
- KeyboardEvent* keyboard_event = ToKeyboardEvent(event);
- if (!keyboard_event->ctrlKey() && !keyboard_event->altKey() &&
- !keyboard_event->metaKey() &&
- WTF::Unicode::IsPrintableChar(keyboard_event->charCode())) {
+ if (event.type() == EventTypeNames::keypress && 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);
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
return;
}
}
@@ -1756,7 +1763,7 @@ String HTMLSelectElement::OptionAtIndex(int index) const {
return String();
}
-void HTMLSelectElement::TypeAheadFind(KeyboardEvent* event) {
+void HTMLSelectElement::TypeAheadFind(const KeyboardEvent& event) {
int index = type_ahead_.HandleEvent(
event, TypeAhead::kMatchPrefix | TypeAhead::kCycleFirstChar);
if (index < 0)
@@ -2078,4 +2085,12 @@ void HTMLSelectElement::DidMutateSubtree() {
popup_->UpdateFromElement(PopupMenu::kByDOMChange);
}
+void HTMLSelectElement::CloneNonAttributePropertiesFrom(
+ const Element& source,
+ CloneChildrenFlag flag) {
+ const auto& source_element = static_cast<const HTMLSelectElement&>(source);
+ user_has_edited_the_field_ = source_element.user_has_edited_the_field_;
+ HTMLFormControlElement::CloneNonAttributePropertiesFrom(source, flag);
+}
+
} // 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 1474997846d..21954b8fb20 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
@@ -173,6 +173,8 @@ class CORE_EXPORT HTMLSelectElement final
bool HasNonInBodyInsertionMode() const override { return true; }
void Trace(blink::Visitor*) override;
+ void CloneNonAttributePropertiesFrom(const Element&,
+ CloneChildrenFlag) override;
protected:
explicit HTMLSelectElement(Document&);
@@ -209,7 +211,7 @@ class CORE_EXPORT HTMLSelectElement final
void AppendToFormData(FormData&) override;
void DidAddUserAgentShadowRoot(ShadowRoot&) override;
- void DefaultEventHandler(Event*) override;
+ void DefaultEventHandler(Event&) override;
void DispatchInputAndChangeEventForMenuList();
@@ -217,7 +219,7 @@ class CORE_EXPORT HTMLSelectElement final
void RecalcListItems() const;
enum ResetReason { kResetReasonSelectedOptionRemoved, kResetReasonOthers };
void ResetToDefaultSelection(ResetReason = kResetReasonOthers);
- void TypeAheadFind(KeyboardEvent*);
+ void TypeAheadFind(const KeyboardEvent&);
void SaveLastSelection();
void SaveListboxActiveSelection();
// Returns the first selected OPTION, or nullptr.
@@ -242,11 +244,11 @@ class CORE_EXPORT HTMLSelectElement final
void ParseMultipleAttribute(const AtomicString&);
HTMLOptionElement* LastSelectedOption() const;
void UpdateSelectedState(HTMLOptionElement*, bool multi, bool shift);
- void MenuListDefaultEventHandler(Event*);
- void HandlePopupOpenKeyboardEvent(Event*);
- bool ShouldOpenPopupForKeyDownEvent(KeyboardEvent*);
- bool ShouldOpenPopupForKeyPressEvent(KeyboardEvent*);
- void ListBoxDefaultEventHandler(Event*);
+ void MenuListDefaultEventHandler(Event&);
+ void HandlePopupOpenKeyboardEvent(Event&);
+ bool ShouldOpenPopupForKeyDownEvent(const KeyboardEvent&);
+ bool ShouldOpenPopupForKeyPressEvent(const KeyboardEvent&);
+ void ListBoxDefaultEventHandler(Event&);
void SetOptionsChangedOnLayoutObject();
size_t SearchOptionsForValue(const String&,
size_t list_index_start,
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 9dff47c1d26..47172cdbd9d 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
@@ -262,13 +262,15 @@ void HTMLTextAreaElement::UpdateFocusAppearanceWithOptions(
}
}
-void HTMLTextAreaElement::DefaultEventHandler(Event* event) {
- if (GetLayoutObject() && (event->IsMouseEvent() || event->IsDragEvent() ||
- event->HasInterface(EventNames::WheelEvent) ||
- event->type() == EventTypeNames::blur))
+void HTMLTextAreaElement::DefaultEventHandler(Event& event) {
+ if (GetLayoutObject() && (event.IsMouseEvent() || event.IsDragEvent() ||
+ event.HasInterface(EventNames::WheelEvent) ||
+ event.type() == EventTypeNames::blur)) {
ForwardEvent(event);
- else if (GetLayoutObject() && event->IsBeforeTextInsertedEvent())
- HandleBeforeTextInsertedEvent(static_cast<BeforeTextInsertedEvent*>(event));
+ } else if (GetLayoutObject() && event.IsBeforeTextInsertedEvent()) {
+ HandleBeforeTextInsertedEvent(
+ static_cast<BeforeTextInsertedEvent*>(&event));
+ }
TextControlElement::DefaultEventHandler(event);
}
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 20fc30c33d0..90d2379e4c9 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
@@ -95,7 +95,7 @@ class CORE_EXPORT HTMLTextAreaElement final : public TextControlElement {
}
bool IsRequiredFormControl() const override { return IsRequired(); }
- void DefaultEventHandler(Event*) override;
+ void DefaultEventHandler(Event&) override;
void SubtreeHasChanged() 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 b5fe2fd1de2..7a92a205fbc 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
@@ -86,22 +86,22 @@ bool ImageInputType::SupportsValidation() const {
return false;
}
-static IntPoint ExtractClickLocation(Event* event) {
- if (!event->UnderlyingEvent() || !event->UnderlyingEvent()->IsMouseEvent())
+static IntPoint ExtractClickLocation(const Event& event) {
+ if (!event.UnderlyingEvent() || !event.UnderlyingEvent()->IsMouseEvent())
return IntPoint();
- MouseEvent* mouse_event = ToMouseEvent(event->UnderlyingEvent());
- if (!mouse_event->HasPosition())
+ auto& mouse_event = *ToMouseEvent(event.UnderlyingEvent());
+ 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) {
+void ImageInputType::HandleDOMActivateEvent(Event& event) {
if (GetElement().IsDisabledFormControl() || !GetElement().Form())
return;
click_location_ = ExtractClickLocation(event);
GetElement().Form()->PrepareForSubmission(
event, &GetElement()); // Event handlers can run.
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
}
LayoutObject* ImageInputType::CreateLayoutObject(
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 ea47c1acb06..b7df5596ff6 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
@@ -52,7 +52,7 @@ class ImageInputType final : public BaseButtonInputType {
String ResultForDialogSubmit() const override;
bool SupportsValidation() const override;
LayoutObject* CreateLayoutObject(const ComputedStyle&) const override;
- void HandleDOMActivateEvent(Event*) override;
+ void HandleDOMActivateEvent(Event&) override;
void AltAttributeChanged() override;
void SrcAttributeChanged() override;
void ValueAttributeChanged() override;
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 273cf3f5172..04d1ece53f4 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
@@ -49,26 +49,26 @@ bool InputTypeView::SizeShouldIncludeDecoration(int,
return false;
}
-void InputTypeView::HandleClickEvent(MouseEvent*) {}
+void InputTypeView::HandleClickEvent(MouseEvent&) {}
-void InputTypeView::HandleMouseDownEvent(MouseEvent*) {}
+void InputTypeView::HandleMouseDownEvent(MouseEvent&) {}
-void InputTypeView::HandleKeydownEvent(KeyboardEvent*) {}
+void InputTypeView::HandleKeydownEvent(KeyboardEvent&) {}
-void InputTypeView::HandleKeypressEvent(KeyboardEvent*) {}
+void InputTypeView::HandleKeypressEvent(KeyboardEvent&) {}
-void InputTypeView::HandleKeyupEvent(KeyboardEvent*) {}
+void InputTypeView::HandleKeyupEvent(KeyboardEvent&) {}
-void InputTypeView::HandleBeforeTextInsertedEvent(BeforeTextInsertedEvent*) {}
+void InputTypeView::HandleBeforeTextInsertedEvent(BeforeTextInsertedEvent&) {}
-void InputTypeView::HandleDOMActivateEvent(Event*) {}
+void InputTypeView::HandleDOMActivateEvent(Event&) {}
-void InputTypeView::ForwardEvent(Event*) {}
+void InputTypeView::ForwardEvent(Event&) {}
-void InputTypeView::DispatchSimulatedClickIfActive(KeyboardEvent* event) const {
+void InputTypeView::DispatchSimulatedClickIfActive(KeyboardEvent& event) const {
if (GetElement().IsActive())
- GetElement().DispatchSimulatedClick(event);
- event->SetDefaultHandled();
+ GetElement().DispatchSimulatedClick(&event);
+ event.SetDefaultHandled();
}
void InputTypeView::AccessKeyAction(bool) {
@@ -76,10 +76,9 @@ void InputTypeView::AccessKeyAction(bool) {
kWebFocusTypeNone, nullptr));
}
-bool InputTypeView::ShouldSubmitImplicitly(Event* event) {
- return event->IsKeyboardEvent() &&
- event->type() == EventTypeNames::keypress &&
- ToKeyboardEvent(event)->charCode() == '\r';
+bool InputTypeView::ShouldSubmitImplicitly(const Event& event) {
+ return event.IsKeyboardEvent() && event.type() == EventTypeNames::keypress &&
+ ToKeyboardEvent(event).charCode() == '\r';
}
HTMLFormElement* InputTypeView::FormForSubmission() const {
@@ -139,7 +138,7 @@ ClickHandlingState* InputTypeView::WillDispatchClick() {
return nullptr;
}
-void InputTypeView::DidDispatchClick(Event*, const ClickHandlingState&) {}
+void InputTypeView::DidDispatchClick(Event&, const ClickHandlingState&) {}
void InputTypeView::UpdateView() {}
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 f741beb93ed..4fa98908002 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
@@ -78,24 +78,24 @@ class CORE_EXPORT InputTypeView : public GarbageCollectedMixin {
// Event handling functions
- virtual void HandleClickEvent(MouseEvent*);
- virtual void HandleMouseDownEvent(MouseEvent*);
+ virtual void HandleClickEvent(MouseEvent&);
+ virtual void HandleMouseDownEvent(MouseEvent&);
virtual ClickHandlingState* WillDispatchClick();
- virtual void DidDispatchClick(Event*, const ClickHandlingState&);
- virtual void HandleKeydownEvent(KeyboardEvent*);
- virtual void HandleKeypressEvent(KeyboardEvent*);
- virtual void HandleKeyupEvent(KeyboardEvent*);
- virtual void HandleBeforeTextInsertedEvent(BeforeTextInsertedEvent*);
- virtual void ForwardEvent(Event*);
- virtual bool ShouldSubmitImplicitly(Event*);
+ virtual void DidDispatchClick(Event&, const ClickHandlingState&);
+ virtual void HandleKeydownEvent(KeyboardEvent&);
+ virtual void HandleKeypressEvent(KeyboardEvent&);
+ virtual void HandleKeyupEvent(KeyboardEvent&);
+ virtual void HandleBeforeTextInsertedEvent(BeforeTextInsertedEvent&);
+ virtual void ForwardEvent(Event&);
+ virtual bool ShouldSubmitImplicitly(const Event&);
virtual HTMLFormElement* FormForSubmission() const;
virtual bool HasCustomFocusLogic() const;
virtual void HandleFocusInEvent(Element* old_focused_element, WebFocusType);
virtual void HandleBlurEvent();
- virtual void HandleDOMActivateEvent(Event*);
+ virtual void HandleDOMActivateEvent(Event&);
virtual void AccessKeyAction(bool send_mouse_events);
virtual void Blur();
- void DispatchSimulatedClickIfActive(KeyboardEvent*) const;
+ void DispatchSimulatedClickIfActive(KeyboardEvent&) const;
virtual void SubtreeHasChanged();
virtual LayoutObject* CreateLayoutObject(const ComputedStyle&) const;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/keyboard_clickable_input_type_view.cc b/chromium/third_party/blink/renderer/core/html/forms/keyboard_clickable_input_type_view.cc
index 848859cea96..31ddcf49a14 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/keyboard_clickable_input_type_view.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/keyboard_clickable_input_type_view.cc
@@ -38,9 +38,8 @@ namespace blink {
using namespace HTMLNames;
-void KeyboardClickableInputTypeView::HandleKeydownEvent(KeyboardEvent* event) {
- const String& key = event->key();
- if (key == " ") {
+void KeyboardClickableInputTypeView::HandleKeydownEvent(KeyboardEvent& event) {
+ if (event.key() == " ") {
GetElement().SetActive(true);
// No setDefaultHandled(), because IE dispatches a keypress in this case
// and the caller will only dispatch a keypress if we don't call
@@ -48,22 +47,21 @@ void KeyboardClickableInputTypeView::HandleKeydownEvent(KeyboardEvent* event) {
}
}
-void KeyboardClickableInputTypeView::HandleKeypressEvent(KeyboardEvent* event) {
- const String& key = event->key();
+void KeyboardClickableInputTypeView::HandleKeypressEvent(KeyboardEvent& event) {
+ const String& key = event.key();
if (key == "Enter") {
- GetElement().DispatchSimulatedClick(event);
- event->SetDefaultHandled();
+ GetElement().DispatchSimulatedClick(&event);
+ event.SetDefaultHandled();
return;
}
if (key == " ") {
// Prevent scrolling down the page.
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
}
}
-void KeyboardClickableInputTypeView::HandleKeyupEvent(KeyboardEvent* event) {
- const String& key = event->key();
- if (key != " ")
+void KeyboardClickableInputTypeView::HandleKeyupEvent(KeyboardEvent& event) {
+ if (event.key() != " ")
return;
// Simulate mouse click for spacebar for button types.
DispatchSimulatedClickIfActive(event);
diff --git a/chromium/third_party/blink/renderer/core/html/forms/keyboard_clickable_input_type_view.h b/chromium/third_party/blink/renderer/core/html/forms/keyboard_clickable_input_type_view.h
index 1dc03b1e7ac..4fd91a6a78f 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/keyboard_clickable_input_type_view.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/keyboard_clickable_input_type_view.h
@@ -43,9 +43,9 @@ class CORE_EXPORT KeyboardClickableInputTypeView : public InputTypeView {
: InputTypeView(element) {}
protected:
- void HandleKeydownEvent(KeyboardEvent*) override;
- void HandleKeypressEvent(KeyboardEvent*) override;
- void HandleKeyupEvent(KeyboardEvent*) override;
+ void HandleKeydownEvent(KeyboardEvent&) override;
+ void HandleKeypressEvent(KeyboardEvent&) override;
+ void HandleKeyupEvent(KeyboardEvent&) override;
void AccessKeyAction(bool send_mouse_events) override;
};
diff --git a/chromium/third_party/blink/renderer/core/html/forms/listed_element.cc b/chromium/third_party/blink/renderer/core/html/forms/listed_element.cc
index dee6e10f57b..ff7a94f7862 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
@@ -74,13 +74,13 @@ void ListedElement::DidMoveToNewDocument(Document& old_document) {
SetFormAttributeTargetObserver(nullptr);
}
-void ListedElement::InsertedInto(ContainerNode* insertion_point) {
+void ListedElement::InsertedInto(ContainerNode& insertion_point) {
if (!form_was_set_by_parser_ || !form_ ||
- NodeTraversal::HighestAncestorOrSelf(*insertion_point) !=
+ NodeTraversal::HighestAncestorOrSelf(insertion_point) !=
NodeTraversal::HighestAncestorOrSelf(*form_.Get()))
ResetFormOwner();
- if (!insertion_point->isConnected())
+ if (!insertion_point.isConnected())
return;
HTMLElement* element = ToHTMLElement(this);
@@ -88,9 +88,9 @@ void ListedElement::InsertedInto(ContainerNode* insertion_point) {
ResetFormAttributeTargetObserver();
}
-void ListedElement::RemovedFrom(ContainerNode* insertion_point) {
+void ListedElement::RemovedFrom(ContainerNode& insertion_point) {
HTMLElement* element = ToHTMLElement(this);
- if (insertion_point->isConnected() && element->FastHasAttribute(formAttr)) {
+ if (insertion_point.isConnected() && element->FastHasAttribute(formAttr)) {
SetFormAttributeTargetObserver(nullptr);
ResetFormOwner();
return;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/listed_element.h b/chromium/third_party/blink/renderer/core/html/forms/listed_element.h
index 891cb564d2c..d7ba4cdfeaa 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/listed_element.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/listed_element.h
@@ -97,8 +97,8 @@ class CORE_EXPORT ListedElement : public GarbageCollectedMixin {
protected:
ListedElement();
- void InsertedInto(ContainerNode*);
- void RemovedFrom(ContainerNode*);
+ void InsertedInto(ContainerNode&);
+ void RemovedFrom(ContainerNode&);
void DidMoveToNewDocument(Document& old_document);
// FIXME: Remove usage of setForm. resetFormOwner should be enough, and
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 2263a99f65d..fa68adc9faf 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
@@ -401,8 +401,8 @@ void MultipleFieldsTemporalInputTypeView::DestroyShadowSubtree() {
is_destroying_shadow_subtree_ = false;
}
-void MultipleFieldsTemporalInputTypeView::HandleClickEvent(MouseEvent* event) {
- if (!event->isTrusted()) {
+void MultipleFieldsTemporalInputTypeView::HandleClickEvent(MouseEvent& event) {
+ if (!event.isTrusted()) {
UseCounter::Count(GetElement().GetDocument(),
WebFeature::kTemporalInputTypeIgnoreUntrustedClick);
}
@@ -426,10 +426,10 @@ void MultipleFieldsTemporalInputTypeView::HandleFocusInEvent(
}
}
-void MultipleFieldsTemporalInputTypeView::ForwardEvent(Event* event) {
+void MultipleFieldsTemporalInputTypeView::ForwardEvent(Event& event) {
if (SpinButtonElement* element = GetSpinButtonElement()) {
element->ForwardEvent(event);
- if (event->DefaultHandled())
+ if (event.DefaultHandled())
return;
}
@@ -449,16 +449,16 @@ void MultipleFieldsTemporalInputTypeView::RequiredAttributeChanged() {
}
void MultipleFieldsTemporalInputTypeView::HandleKeydownEvent(
- KeyboardEvent* event) {
+ KeyboardEvent& event) {
if (!GetElement().IsFocused())
return;
if (picker_indicator_is_visible_ &&
- ((event->key() == "ArrowDown" && event->getModifierState("Alt")) ||
+ ((event.key() == "ArrowDown" && event.getModifierState("Alt")) ||
(LayoutTheme::GetTheme().ShouldOpenPickerWithF4Key() &&
- event->key() == "F4"))) {
+ event.key() == "F4"))) {
if (PickerIndicatorElement* element = GetPickerIndicatorElement())
element->OpenPopup();
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
} else {
ForwardEvent(event);
}
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 b60ffbe75fc..19ba2dd93bf 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
@@ -101,10 +101,10 @@ class MultipleFieldsTemporalInputTypeView final
void CreateShadowSubtree() final;
void DestroyShadowSubtree() final;
void DisabledAttributeChanged() final;
- void ForwardEvent(Event*) final;
- void HandleClickEvent(MouseEvent*) final;
+ void ForwardEvent(Event&) final;
+ void HandleClickEvent(MouseEvent&) final;
void HandleFocusInEvent(Element* old_focused_element, WebFocusType) final;
- void HandleKeydownEvent(KeyboardEvent*) final;
+ void HandleKeydownEvent(KeyboardEvent&) final;
bool HasBadInput() const override;
bool HasCustomFocusLogic() const final;
void MinOrMaxAttributeChanged() 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 67232ce9a40..d3a9680a2ae 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
@@ -188,17 +188,17 @@ bool NumberInputType::IsSteppable() const {
return true;
}
-void NumberInputType::HandleKeydownEvent(KeyboardEvent* event) {
+void NumberInputType::HandleKeydownEvent(KeyboardEvent& event) {
EventQueueScope scope;
HandleKeydownEventForSpinButton(event);
- if (!event->DefaultHandled())
+ if (!event.DefaultHandled())
TextFieldInputType::HandleKeydownEvent(event);
}
void NumberInputType::HandleBeforeTextInsertedEvent(
- BeforeTextInsertedEvent* event) {
- event->SetText(GetLocale().StripInvalidNumberCharacters(event->GetText(),
- "0123456789.Ee-+"));
+ BeforeTextInsertedEvent& event) {
+ event.SetText(GetLocale().StripInvalidNumberCharacters(event.GetText(),
+ "0123456789.Ee-+"));
}
Decimal NumberInputType::ParseToNumber(const String& src,
diff --git a/chromium/third_party/blink/renderer/core/html/forms/number_input_type.h b/chromium/third_party/blink/renderer/core/html/forms/number_input_type.h
index 302539b63a0..d0f9d9b8f82 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/number_input_type.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/number_input_type.h
@@ -62,8 +62,8 @@ class NumberInputType final : public TextFieldInputType {
int& preferred_size) const override;
bool IsSteppable() const override;
StepRange CreateStepRange(AnyStepHandling) const override;
- void HandleKeydownEvent(KeyboardEvent*) override;
- void HandleBeforeTextInsertedEvent(BeforeTextInsertedEvent*) override;
+ void HandleKeydownEvent(KeyboardEvent&) override;
+ void HandleBeforeTextInsertedEvent(BeforeTextInsertedEvent&) override;
Decimal ParseToNumber(const String&, const Decimal&) const override;
String Serialize(const Decimal&) const override;
String LocalizeValue(const String&) const override;
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 643ec24d789..4ba22bb2f91 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
@@ -68,26 +68,26 @@ LayoutObject* PickerIndicatorElement::CreateLayoutObject(const ComputedStyle&) {
return new LayoutDetailsMarker(this);
}
-void PickerIndicatorElement::DefaultEventHandler(Event* event) {
+void PickerIndicatorElement::DefaultEventHandler(Event& event) {
if (!GetLayoutObject())
return;
if (!picker_indicator_owner_ ||
picker_indicator_owner_->IsPickerIndicatorOwnerDisabledOrReadOnly())
return;
- if (event->type() == EventTypeNames::click) {
+ if (event.type() == EventTypeNames::click) {
OpenPopup();
- event->SetDefaultHandled();
- } else if (event->type() == EventTypeNames::keypress &&
- event->IsKeyboardEvent()) {
- int char_code = ToKeyboardEvent(event)->charCode();
+ event.SetDefaultHandled();
+ } else if (event.type() == EventTypeNames::keypress &&
+ event.IsKeyboardEvent()) {
+ int char_code = ToKeyboardEvent(event).charCode();
if (char_code == ' ' || char_code == '\r') {
OpenPopup();
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
}
}
- if (!event->DefaultHandled())
+ if (!event.DefaultHandled())
HTMLDivElement::DefaultEventHandler(event);
}
@@ -153,14 +153,13 @@ bool PickerIndicatorElement::IsPickerIndicatorElement() const {
}
Node::InsertionNotificationRequest PickerIndicatorElement::InsertedInto(
- ContainerNode* insertion_point) {
+ ContainerNode& insertion_point) {
HTMLDivElement::InsertedInto(insertion_point);
return kInsertionShouldCallDidNotifySubtreeInsertions;
}
void PickerIndicatorElement::DidNotifySubtreeInsertionsToDocument() {
- if (!GetDocument().GetSettings() ||
- !GetDocument().GetSettings()->GetAccessibilityEnabled())
+ if (!GetDocument().ExistingAXObjectCache())
return;
// Don't make this focusable if we are in layout tests in order to avoid to
// break existing tests.
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 c0c6fe30e6f..9f675b22456 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
@@ -76,10 +76,10 @@ class PickerIndicatorElement final : public HTMLDivElement,
private:
PickerIndicatorElement(Document&, PickerIndicatorOwner&);
LayoutObject* CreateLayoutObject(const ComputedStyle&) override;
- void DefaultEventHandler(Event*) override;
+ void DefaultEventHandler(Event&) override;
void DetachLayoutTree(const AttachContext& = AttachContext()) override;
bool IsPickerIndicatorElement() const override;
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
void DidNotifySubtreeInsertionsToDocument() override;
HTMLInputElement* HostInput();
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 0ca386d492d..b5059052536 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
@@ -65,8 +65,8 @@ String RadioInputType::ValueMissingText() const {
WebLocalizedString::kValidationValueMissingForRadio);
}
-void RadioInputType::HandleClickEvent(MouseEvent* event) {
- event->SetDefaultHandled();
+void RadioInputType::HandleClickEvent(MouseEvent& event) {
+ event.SetDefaultHandled();
}
HTMLInputElement* RadioInputType::FindNextFocusableRadioButtonInGroup(
@@ -82,19 +82,19 @@ HTMLInputElement* RadioInputType::FindNextFocusableRadioButtonInGroup(
return nullptr;
}
-void RadioInputType::HandleKeydownEvent(KeyboardEvent* event) {
+void RadioInputType::HandleKeydownEvent(KeyboardEvent& event) {
// TODO(tkent): We should return more earlier.
if (!GetElement().GetLayoutObject())
return;
BaseCheckableInputType::HandleKeydownEvent(event);
- if (event->DefaultHandled())
+ if (event.DefaultHandled())
return;
- const String& key = event->key();
+ const String& key = event.key();
if (key != "ArrowUp" && key != "ArrowDown" && key != "ArrowLeft" &&
key != "ArrowRight")
return;
- if (event->ctrlKey() || event->metaKey() || event->altKey())
+ if (event.ctrlKey() || event.metaKey() || event.altKey())
return;
// Left and up mean "previous radio button".
@@ -132,15 +132,14 @@ void RadioInputType::HandleKeydownEvent(KeyboardEvent* event) {
document.SetFocusedElement(input_element,
FocusParams(SelectionBehaviorOnFocus::kRestore,
kWebFocusTypeNone, nullptr));
- input_element->DispatchSimulatedClick(event, kSendNoEvents);
- event->SetDefaultHandled();
+ input_element->DispatchSimulatedClick(&event, kSendNoEvents);
+ event.SetDefaultHandled();
return;
}
}
-void RadioInputType::HandleKeyupEvent(KeyboardEvent* event) {
- const String& key = event->key();
- if (key != " ")
+void RadioInputType::HandleKeyupEvent(KeyboardEvent& event) {
+ if (event.key() != " ")
return;
// If an unselected radio is tabbed into (because the entire group has nothing
// checked, or because of some explicit .focus() call), then allow space to
@@ -199,9 +198,9 @@ ClickHandlingState* RadioInputType::WillDispatchClick() {
return state;
}
-void RadioInputType::DidDispatchClick(Event* event,
+void RadioInputType::DidDispatchClick(Event& event,
const ClickHandlingState& state) {
- if (event->defaultPrevented() || event->DefaultHandled()) {
+ if (event.defaultPrevented() || event.DefaultHandled()) {
// Restore the original selected radio button if possible.
// Make sure it is still a radio button and only do the restoration if it
// still belongs to our group.
@@ -217,7 +216,7 @@ void RadioInputType::DidDispatchClick(Event* event,
}
is_in_click_handler_ = false;
// The work we did in willDispatchClick was default handling.
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
}
bool RadioInputType::ShouldAppearIndeterminate() const {
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 7c1740d85da..9b9a70a51d1 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
@@ -47,13 +47,13 @@ class RadioInputType final : public BaseCheckableInputType {
const AtomicString& FormControlType() const override;
bool ValueMissing(const String&) const override;
String ValueMissingText() const override;
- void HandleClickEvent(MouseEvent*) override;
- void HandleKeydownEvent(KeyboardEvent*) override;
- void HandleKeyupEvent(KeyboardEvent*) override;
+ void HandleClickEvent(MouseEvent&) override;
+ void HandleKeydownEvent(KeyboardEvent&) override;
+ void HandleKeyupEvent(KeyboardEvent&) override;
bool IsKeyboardFocusable() const override;
bool ShouldSendChangeEventAfterCheckedChanged() override;
ClickHandlingState* WillDispatchClick() override;
- void DidDispatchClick(Event*, const ClickHandlingState&) override;
+ void DidDispatchClick(Event&, const ClickHandlingState&) override;
bool ShouldAppearIndeterminate() const override;
HTMLInputElement* FindNextFocusableRadioButtonInGroup(HTMLInputElement*,
diff --git a/chromium/third_party/blink/renderer/core/html/forms/range_input_type.cc b/chromium/third_party/blink/renderer/core/html/forms/range_input_type.cc
index c709be1ef9e..146e9cc75f5 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
@@ -154,12 +154,12 @@ bool RangeInputType::IsSteppable() const {
return true;
}
-void RangeInputType::HandleMouseDownEvent(MouseEvent* event) {
+void RangeInputType::HandleMouseDownEvent(MouseEvent& event) {
if (GetElement().IsDisabledFormControl())
return;
- Node* target_node = event->target()->ToNode();
- if (event->button() !=
+ Node* target_node = event.target()->ToNode();
+ if (event.button() !=
static_cast<short>(WebPointerProperties::Button::kLeft) ||
!target_node)
return;
@@ -170,14 +170,14 @@ void RangeInputType::HandleMouseDownEvent(MouseEvent* event) {
SliderThumbElement* thumb = GetSliderThumbElement();
if (target_node == thumb)
return;
- thumb->DragFrom(LayoutPoint(event->AbsoluteLocation()));
+ thumb->DragFrom(LayoutPoint(event.AbsoluteLocation()));
}
-void RangeInputType::HandleKeydownEvent(KeyboardEvent* event) {
+void RangeInputType::HandleKeydownEvent(KeyboardEvent& event) {
if (GetElement().IsDisabledFormControl())
return;
- const String& key = event->key();
+ const String& key = event.key();
const Decimal current = ParseToNumberOrNaN(GetElement().value());
DCHECK(current.IsFinite());
@@ -236,7 +236,7 @@ void RangeInputType::HandleKeydownEvent(KeyboardEvent* event) {
cache->HandleValueChanged(&GetElement());
}
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
}
void RangeInputType::CreateShadowSubtree() {
@@ -340,10 +340,8 @@ inline Element* RangeInputType::SliderTrackElement() const {
void RangeInputType::ListAttributeTargetChanged() {
tick_mark_values_dirty_ = true;
- if (GetElement().GetLayoutObject())
- GetElement()
- .GetLayoutObject()
- ->SetShouldDoFullPaintInvalidationIncludingNonCompositingDescendants();
+ if (auto* object = GetElement().GetLayoutObject())
+ object->SetSubtreeShouldDoFullPaintInvalidation();
Element* slider_track_element = SliderTrackElement();
if (slider_track_element->GetLayoutObject())
slider_track_element->GetLayoutObject()->SetNeedsLayout(
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 23c39a870fb..bbdb85edb19 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
@@ -61,8 +61,8 @@ class RangeInputType final : public InputType, public InputTypeView {
bool SupportsRequired() const override;
StepRange CreateStepRange(AnyStepHandling) const override;
bool IsSteppable() const override;
- void HandleMouseDownEvent(MouseEvent*) override;
- void HandleKeydownEvent(KeyboardEvent*) override;
+ void HandleMouseDownEvent(MouseEvent&) override;
+ void HandleKeydownEvent(KeyboardEvent&) override;
LayoutObject* CreateLayoutObject(const ComputedStyle&) const override;
void CreateShadowSubtree() override;
Decimal ParseToNumber(const String&, const Decimal&) const override;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/reset_input_type.cc b/chromium/third_party/blink/renderer/core/html/forms/reset_input_type.cc
index b1093eb2d12..98ddebfb25d 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/reset_input_type.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/reset_input_type.cc
@@ -51,11 +51,11 @@ bool ResetInputType::SupportsValidation() const {
return false;
}
-void ResetInputType::HandleDOMActivateEvent(Event* event) {
+void ResetInputType::HandleDOMActivateEvent(Event& event) {
if (GetElement().IsDisabledFormControl() || !GetElement().Form())
return;
GetElement().Form()->reset();
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
}
String ResetInputType::DefaultLabel() const {
diff --git a/chromium/third_party/blink/renderer/core/html/forms/reset_input_type.h b/chromium/third_party/blink/renderer/core/html/forms/reset_input_type.h
index e2c58bc3f47..b239a154c21 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/reset_input_type.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/reset_input_type.h
@@ -43,7 +43,7 @@ class ResetInputType final : public BaseButtonInputType {
ResetInputType(HTMLInputElement& element) : BaseButtonInputType(element) {}
const AtomicString& FormControlType() const override;
bool SupportsValidation() const override;
- void HandleDOMActivateEvent(Event*) override;
+ void HandleDOMActivateEvent(Event&) override;
String DefaultLabel() const override;
bool IsTextButton() const override;
};
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 76c81677b59..82c28f67be9 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
@@ -85,17 +85,16 @@ void SearchInputType::CreateShadowSubtree() {
view_port->nextSibling());
}
-void SearchInputType::HandleKeydownEvent(KeyboardEvent* event) {
+void SearchInputType::HandleKeydownEvent(KeyboardEvent& event) {
if (GetElement().IsDisabledOrReadOnly()) {
TextFieldInputType::HandleKeydownEvent(event);
return;
}
- const String& key = event->key();
- if (key == "Escape") {
+ if (event.key() == "Escape") {
GetElement().SetValueForUser("");
GetElement().OnSearch();
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
return;
}
TextFieldInputType::HandleKeydownEvent(event);
@@ -124,7 +123,7 @@ void SearchInputType::StartSearchEventTimer() {
void SearchInputType::DispatchSearchEvent() {
search_event_timer_.Stop();
- GetElement().DispatchEvent(Event::CreateBubble(EventTypeNames::search));
+ GetElement().DispatchEvent(*Event::CreateBubble(EventTypeNames::search));
}
void SearchInputType::SearchEventTimerFired(TimerBase*) {
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 45b6abc3505..7724359c187 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
@@ -47,7 +47,7 @@ class SearchInputType final : public BaseTextInputType {
const AtomicString& FormControlType() const override;
bool NeedsContainer() const override;
void CreateShadowSubtree() override;
- void HandleKeydownEvent(KeyboardEvent*) override;
+ void HandleKeydownEvent(KeyboardEvent&) override;
void DidSetValueByUserEdit() override;
bool SupportsInputModeAttribute() const override;
void UpdateView() override;
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 4e1399fa545..bcaf25d38d8 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
@@ -211,14 +211,14 @@ void SliderThumbElement::StopDragging() {
HostInput()->DispatchFormControlChangeEvent();
}
-void SliderThumbElement::DefaultEventHandler(Event* event) {
- if (event->IsPointerEvent() &&
- event->type() == EventTypeNames::lostpointercapture) {
+void SliderThumbElement::DefaultEventHandler(Event& event) {
+ if (event.IsPointerEvent() &&
+ event.type() == EventTypeNames::lostpointercapture) {
StopDragging();
return;
}
- if (!event->IsMouseEvent()) {
+ if (!event.IsMouseEvent()) {
HTMLDivElement::DefaultEventHandler(event);
return;
}
@@ -233,10 +233,10 @@ void SliderThumbElement::DefaultEventHandler(Event* event) {
return;
}
- MouseEvent* mouse_event = ToMouseEvent(event);
- bool is_left_button = mouse_event->button() ==
+ auto& mouse_event = ToMouseEvent(event);
+ bool is_left_button = mouse_event.button() ==
static_cast<short>(WebPointerProperties::Button::kLeft);
- const AtomicString& event_type = event->type();
+ const AtomicString& event_type = event.type();
// We intentionally do not call event->setDefaultHandled() here because
// MediaControlTimelineElement::defaultEventHandler() wants to handle these
@@ -251,7 +251,7 @@ void SliderThumbElement::DefaultEventHandler(Event* event) {
}
if (event_type == EventTypeNames::mousemove) {
if (in_drag_mode_)
- SetPositionFromPoint(LayoutPoint(mouse_event->AbsoluteLocation()));
+ SetPositionFromPoint(LayoutPoint(mouse_event.AbsoluteLocation()));
return;
}
@@ -358,9 +358,9 @@ LayoutObject* SliderContainerElement::CreateLayoutObject(const ComputedStyle&) {
return new LayoutSliderContainer(this);
}
-void SliderContainerElement::DefaultEventHandler(Event* event) {
- if (event->IsTouchEvent()) {
- HandleTouchEvent(ToTouchEvent(event));
+void SliderContainerElement::DefaultEventHandler(Event& event) {
+ if (event.IsTouchEvent()) {
+ HandleTouchEvent(ToTouchEvent(&event));
return;
}
}
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 dab6251d227..cda495321bb 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
@@ -48,7 +48,7 @@ class SliderThumbElement final : public HTMLDivElement {
void SetPositionFromValue();
void DragFrom(const LayoutPoint&);
- void DefaultEventHandler(Event*) override;
+ void DefaultEventHandler(Event&) override;
bool WillRespondToMouseMoveEvents() override;
bool WillRespondToMouseClickEvents() override;
void DetachLayoutTree(const AttachContext& = AttachContext()) override;
@@ -90,7 +90,7 @@ class SliderContainerElement final : public HTMLDivElement {
DECLARE_NODE_FACTORY(SliderContainerElement);
HTMLInputElement* HostInput() const;
- void DefaultEventHandler(Event*) override;
+ void DefaultEventHandler(Event&) override;
void HandleTouchEvent(TouchEvent*);
void UpdateTouchEventHandlerRegistry();
void DidMoveToNewDocument(Document&) override;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/spin_button_element.cc b/chromium/third_party/blink/renderer/core/html/forms/spin_button_element.cc
index 1800cd0a703..9aa7296953d 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
@@ -37,7 +37,7 @@
#include "third_party/blink/renderer/core/layout/layout_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/platform/scroll/scrollbar_theme.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
namespace blink {
@@ -69,31 +69,31 @@ void SpinButtonElement::DetachLayoutTree(const AttachContext& context) {
HTMLDivElement::DetachLayoutTree(context);
}
-void SpinButtonElement::DefaultEventHandler(Event* event) {
- if (!event->IsMouseEvent()) {
- if (!event->DefaultHandled())
+void SpinButtonElement::DefaultEventHandler(Event& event) {
+ if (!event.IsMouseEvent()) {
+ if (!event.DefaultHandled())
HTMLDivElement::DefaultEventHandler(event);
return;
}
LayoutBox* box = GetLayoutBox();
if (!box) {
- if (!event->DefaultHandled())
+ if (!event.DefaultHandled())
HTMLDivElement::DefaultEventHandler(event);
return;
}
if (!ShouldRespondToMouseEvents()) {
- if (!event->DefaultHandled())
+ if (!event.DefaultHandled())
HTMLDivElement::DefaultEventHandler(event);
return;
}
- MouseEvent* mouse_event = ToMouseEvent(event);
+ auto& mouse_event = ToMouseEvent(event);
IntPoint local = RoundedIntPoint(box->AbsoluteToLocal(
- FloatPoint(mouse_event->AbsoluteLocation()), kUseTransforms));
- if (mouse_event->type() == EventTypeNames::mousedown &&
- mouse_event->button() ==
+ FloatPoint(mouse_event.AbsoluteLocation()), kUseTransforms));
+ if (mouse_event.type() == EventTypeNames::mousedown &&
+ mouse_event.button() ==
static_cast<short>(WebPointerProperties::Button::kLeft)) {
if (box->PixelSnappedBorderBoxRect().Contains(local)) {
if (spin_button_owner_)
@@ -109,13 +109,13 @@ void SpinButtonElement::DefaultEventHandler(Event* event) {
DoStepAction(up_down_state_ == kUp ? 1 : -1);
}
}
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
}
- } else if (mouse_event->type() == EventTypeNames::mouseup &&
- mouse_event->button() ==
+ } else if (mouse_event.type() == EventTypeNames::mouseup &&
+ mouse_event.button() ==
static_cast<short>(WebPointerProperties::Button::kLeft)) {
ReleaseCapture();
- } else if (event->type() == EventTypeNames::mousemove) {
+ } else if (event.type() == EventTypeNames::mousemove) {
if (box->PixelSnappedBorderBoxRect().Contains(local)) {
if (!capturing_) {
if (LocalFrame* frame = GetDocument().GetFrame()) {
@@ -135,7 +135,7 @@ void SpinButtonElement::DefaultEventHandler(Event* event) {
}
}
- if (!event->DefaultHandled())
+ if (!event.DefaultHandled())
HTMLDivElement::DefaultEventHandler(event);
}
@@ -144,11 +144,11 @@ void SpinButtonElement::WillOpenPopup() {
up_down_state_ = kIndeterminate;
}
-void SpinButtonElement::ForwardEvent(Event* event) {
+void SpinButtonElement::ForwardEvent(Event& event) {
if (!GetLayoutBox())
return;
- if (!event->HasInterface(EventNames::WheelEvent))
+ if (!event.HasInterface(EventNames::WheelEvent))
return;
if (!spin_button_owner_)
@@ -157,8 +157,8 @@ void SpinButtonElement::ForwardEvent(Event* event) {
if (!spin_button_owner_->ShouldSpinButtonRespondToWheelEvents())
return;
- DoStepAction(ToWheelEvent(event)->wheelDeltaY());
- event->SetDefaultHandled();
+ DoStepAction(ToWheelEvent(event).wheelDeltaY());
+ event.SetDefaultHandled();
}
bool SpinButtonElement::WillRespondToMouseMoveEvents() {
diff --git a/chromium/third_party/blink/renderer/core/html/forms/spin_button_element.h b/chromium/third_party/blink/renderer/core/html/forms/spin_button_element.h
index 3f0f6190721..0244fb96b86 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/spin_button_element.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/spin_button_element.h
@@ -72,7 +72,7 @@ class CORE_EXPORT SpinButtonElement final : public HTMLDivElement,
bool WillRespondToMouseMoveEvents() override;
bool WillRespondToMouseClickEvents() override;
- void ForwardEvent(Event*);
+ void ForwardEvent(Event&);
void Trace(blink::Visitor*) override;
@@ -86,7 +86,7 @@ class CORE_EXPORT SpinButtonElement final : public HTMLDivElement,
}
bool MatchesReadOnlyPseudoClass() const override;
bool MatchesReadWritePseudoClass() const override;
- void DefaultEventHandler(Event*) override;
+ void DefaultEventHandler(Event&) override;
void WillOpenPopup() override;
void DoStepAction(int);
void StartRepeatingTimer();
diff --git a/chromium/third_party/blink/renderer/core/html/forms/submit_input_type.cc b/chromium/third_party/blink/renderer/core/html/forms/submit_input_type.cc
index 1391ae8173b..b722264fdd1 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/submit_input_type.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/submit_input_type.cc
@@ -61,12 +61,12 @@ bool SubmitInputType::SupportsRequired() const {
return false;
}
-void SubmitInputType::HandleDOMActivateEvent(Event* event) {
+void SubmitInputType::HandleDOMActivateEvent(Event& event) {
if (GetElement().IsDisabledFormControl() || !GetElement().Form())
return;
GetElement().Form()->PrepareForSubmission(
event, &GetElement()); // Event handlers can run.
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
}
bool SubmitInputType::CanBeSuccessfulSubmitButton() {
diff --git a/chromium/third_party/blink/renderer/core/html/forms/submit_input_type.h b/chromium/third_party/blink/renderer/core/html/forms/submit_input_type.h
index 22d94696d35..80cd8afd535 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/submit_input_type.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/submit_input_type.h
@@ -44,7 +44,7 @@ class SubmitInputType final : public BaseButtonInputType {
const AtomicString& FormControlType() const override;
void AppendToFormData(FormData&) const override;
bool SupportsRequired() const override;
- void HandleDOMActivateEvent(Event*) override;
+ void HandleDOMActivateEvent(Event&) override;
bool CanBeSuccessfulSubmitButton() override;
String DefaultLabel() const override;
bool IsTextButton() const override;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/text_control_element.cc b/chromium/third_party/blink/renderer/core/html/forms/text_control_element.cc
index 950f28468c2..d5de47f1ebc 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
@@ -31,6 +31,7 @@
#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/editing/editing_behavior.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/frame_selection.h"
@@ -67,7 +68,6 @@ TextControlElement::TextControlElement(const QualifiedName& tag_name,
Document& doc)
: HTMLFormControlElementWithState(tag_name, doc),
last_change_was_user_edit_(false),
- user_has_edited_the_field_(false),
cached_selection_start_(0),
cached_selection_end_(0) {
cached_selection_direction_ =
@@ -103,8 +103,8 @@ void TextControlElement::DispatchBlurEvent(
source_capabilities);
}
-void TextControlElement::DefaultEventHandler(Event* event) {
- if (event->type() == EventTypeNames::webkitEditableContentChanged &&
+void TextControlElement::DefaultEventHandler(Event& event) {
+ if (event.type() == EventTypeNames::webkitEditableContentChanged &&
GetLayoutObject() && GetLayoutObject()->IsTextControl()) {
last_change_was_user_edit_ = !GetDocument().IsRunningExecCommand();
user_has_edited_the_field_ |= last_change_was_user_edit_;
@@ -127,9 +127,9 @@ void TextControlElement::DefaultEventHandler(Event* event) {
HTMLFormControlElementWithState::DefaultEventHandler(event);
}
-void TextControlElement::ForwardEvent(Event* event) {
- if (event->type() == EventTypeNames::blur ||
- event->type() == EventTypeNames::focus)
+void TextControlElement::ForwardEvent(Event& event) {
+ if (event.type() == EventTypeNames::blur ||
+ event.type() == EventTypeNames::focus)
return;
InnerEditorElement()->DefaultEventHandler(event);
}
@@ -732,7 +732,7 @@ void TextControlElement::SelectionChanged(bool user_triggered) {
frame->Selection().GetSelectionInDOMTree();
if (selection.Type() != kRangeSelection)
return;
- DispatchEvent(Event::CreateBubble(EventTypeNames::select));
+ DispatchEvent(*Event::CreateBubble(EventTypeNames::select));
}
void TextControlElement::ScheduleSelectEvent() {
@@ -752,12 +752,6 @@ void TextControlElement::ParseAttribute(
}
}
-bool TextControlElement::UserHasEditedTheField() const {
- if (!IsTextControl())
- return false;
- return user_has_edited_the_field_;
-}
-
bool TextControlElement::LastChangeWasUserEdit() const {
if (!IsTextControl())
return false;
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 e479e520253..d0e68214474 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
@@ -62,7 +62,7 @@ class CORE_EXPORT TextControlElement : public HTMLFormControlElementWithState {
~TextControlElement() override;
- void ForwardEvent(Event*);
+ void ForwardEvent(Event&);
void SetFocused(bool, WebFocusType) override;
@@ -134,10 +134,8 @@ class CORE_EXPORT TextControlElement : public HTMLFormControlElementWithState {
void DropInnerEditorElement() { inner_editor_ = nullptr; }
void SelectionChanged(bool user_triggered);
- bool UserHasEditedTheField() const;
bool LastChangeWasUserEdit() const;
- // This is only used in tests, to fake the user's action
- void SetUserHasEditedTheFieldForTest() { user_has_edited_the_field_ = true; }
+
virtual void SetInnerEditorValue(const String&);
String InnerEditorValue() const;
Node* CreatePlaceholderBreakElement() const;
@@ -165,7 +163,7 @@ class CORE_EXPORT TextControlElement : public HTMLFormControlElementWithState {
void RestoreCachedSelection();
- void DefaultEventHandler(Event*) override;
+ void DefaultEventHandler(Event&) override;
virtual void SubtreeHasChanged() = 0;
void SetLastChangeWasNotUserEdit() { last_change_was_user_edit_ = false; }
@@ -221,7 +219,6 @@ class CORE_EXPORT TextControlElement : public HTMLFormControlElementWithState {
// zero-length String is a valid data.
String value_before_first_user_edit_;
bool last_change_was_user_edit_;
- bool user_has_edited_the_field_;
unsigned cached_selection_start_;
unsigned cached_selection_end_;
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 cf430c80937..6f528005d96 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
@@ -73,10 +73,10 @@ TEST_F(TextControlElementTest, SetSelectionRangeDoesNotCauseLayout) {
// Force layout if document().updateStyleAndLayoutIgnorePendingStylesheets()
// is called.
GetDocument().body()->AppendChild(GetDocument().createTextNode("foo"));
- const int start_layout_count = Page().GetFrameView().LayoutCount();
+ unsigned start_layout_count = Page().GetFrameView().LayoutCountForTesting();
EXPECT_TRUE(GetDocument().NeedsLayoutTreeUpdate());
Input().SetSelectionRange(2, 2);
- EXPECT_EQ(start_layout_count, Page().GetFrameView().LayoutCount());
+ EXPECT_EQ(start_layout_count, Page().GetFrameView().LayoutCountForTesting());
}
TEST_F(TextControlElementTest, IndexForPosition) {
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 5c59d0917ed..0bbcdc92060 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
@@ -106,13 +106,13 @@ TextControlInnerEditorElement* TextControlInnerEditorElement::Create(
return new TextControlInnerEditorElement(document);
}
-void TextControlInnerEditorElement::DefaultEventHandler(Event* event) {
+void TextControlInnerEditorElement::DefaultEventHandler(Event& event) {
// FIXME: In the future, we should add a way to have default event listeners.
// Then we would add one to the text field's inner div, and we wouldn't need
// this subclass.
// Or possibly we could just use a normal event listener.
- if (event->IsBeforeTextInsertedEvent() ||
- event->type() == EventTypeNames::webkitEditableContentChanged) {
+ if (event.IsBeforeTextInsertedEvent() ||
+ event.type() == EventTypeNames::webkitEditableContentChanged) {
Element* shadow_ancestor = OwnerShadowHost();
// A TextControlInnerTextElement can have no host if its been detached,
// but kept alive by an EditCommand. In this case, an undo/redo can
@@ -122,7 +122,7 @@ void TextControlInnerEditorElement::DefaultEventHandler(Event* event) {
if (shadow_ancestor)
shadow_ancestor->DefaultEventHandler(event);
}
- if (!event->DefaultHandled())
+ if (!event.DefaultHandled())
HTMLDivElement::DefaultEventHandler(event);
}
@@ -239,25 +239,25 @@ void SearchFieldCancelButtonElement::DetachLayoutTree(
HTMLDivElement::DetachLayoutTree(context);
}
-void SearchFieldCancelButtonElement::DefaultEventHandler(Event* event) {
+void SearchFieldCancelButtonElement::DefaultEventHandler(Event& event) {
// If the element is visible, on mouseup, clear the value, and set selection
HTMLInputElement* input(ToHTMLInputElement(OwnerShadowHost()));
if (!input || input->IsDisabledOrReadOnly()) {
- if (!event->DefaultHandled())
+ if (!event.DefaultHandled())
HTMLDivElement::DefaultEventHandler(event);
return;
}
- if (event->type() == EventTypeNames::click && event->IsMouseEvent() &&
- ToMouseEvent(event)->button() ==
+ if (event.type() == EventTypeNames::click && event.IsMouseEvent() &&
+ ToMouseEvent(event).button() ==
static_cast<short>(WebPointerProperties::Button::kLeft)) {
input->SetValueForUser("");
input->SetAutofillState(WebAutofillState::kNotFilled);
input->OnSearch();
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
}
- if (!event->DefaultHandled())
+ if (!event.DefaultHandled())
HTMLDivElement::DefaultEventHandler(event);
}
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 283af2b971d..8ae0bcf469e 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
@@ -57,7 +57,7 @@ class TextControlInnerEditorElement final : public HTMLDivElement {
public:
static TextControlInnerEditorElement* Create(Document&);
- void DefaultEventHandler(Event*) override;
+ void DefaultEventHandler(Event&) override;
void SetVisibility(bool is_visible);
scoped_refptr<ComputedStyle> CreateInnerEditorStyle() const;
@@ -74,7 +74,7 @@ class SearchFieldCancelButtonElement final : public HTMLDivElement {
public:
static SearchFieldCancelButtonElement* Create(Document&);
- void DefaultEventHandler(Event*) override;
+ void DefaultEventHandler(Event&) override;
bool WillRespondToMouseClickEvents() override;
private:
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 430db9f5a54..5e2265d7b00 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
@@ -70,24 +70,24 @@ class DataListIndicatorElement final : public HTMLDivElement {
return new LayoutDetailsMarker(this);
}
- EventDispatchHandlingState* PreDispatchEventHandler(Event* event) override {
+ EventDispatchHandlingState* PreDispatchEventHandler(Event& event) override {
// Chromium opens autofill popup in a mousedown event listener
// associated to the document. We don't want to open it in this case
// because we opens a datalist chooser later.
// FIXME: We should dispatch mousedown events even in such case.
- if (event->type() == EventTypeNames::mousedown)
- event->stopPropagation();
+ if (event.type() == EventTypeNames::mousedown)
+ event.stopPropagation();
return nullptr;
}
- void DefaultEventHandler(Event* event) override {
+ void DefaultEventHandler(Event& event) override {
DCHECK(GetDocument().IsActive());
- if (event->type() != EventTypeNames::click)
+ if (event.type() != EventTypeNames::click)
return;
HTMLInputElement* host = HostInput();
if (host && !host->IsDisabledOrReadOnly()) {
GetDocument().GetPage()->GetChromeClient().OpenTextDataListChooser(*host);
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
}
}
@@ -193,45 +193,45 @@ void TextFieldInputType::SetValue(const String& sanitized_value,
}
}
-void TextFieldInputType::HandleKeydownEvent(KeyboardEvent* event) {
+void TextFieldInputType::HandleKeydownEvent(KeyboardEvent& event) {
if (!GetElement().IsFocused())
return;
if (ChromeClient* chrome_client = GetChromeClient()) {
- chrome_client->HandleKeyboardEventOnTextField(GetElement(), *event);
+ chrome_client->HandleKeyboardEventOnTextField(GetElement(), event);
return;
}
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
}
-void TextFieldInputType::HandleKeydownEventForSpinButton(KeyboardEvent* event) {
+void TextFieldInputType::HandleKeydownEventForSpinButton(KeyboardEvent& event) {
if (GetElement().IsDisabledOrReadOnly())
return;
- const String& key = event->key();
+ const String& key = event.key();
if (key == "ArrowUp")
SpinButtonStepUp();
- else if (key == "ArrowDown" && !event->altKey())
+ else if (key == "ArrowDown" && !event.altKey())
SpinButtonStepDown();
else
return;
GetElement().DispatchFormControlChangeEvent();
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
}
-void TextFieldInputType::ForwardEvent(Event* event) {
+void TextFieldInputType::ForwardEvent(Event& event) {
if (SpinButtonElement* spin_button = GetSpinButtonElement()) {
spin_button->ForwardEvent(event);
- if (event->DefaultHandled())
+ if (event.DefaultHandled())
return;
}
if (GetElement().GetLayoutObject() &&
- (event->IsMouseEvent() || event->IsDragEvent() ||
- event->HasInterface(EventNames::WheelEvent) ||
- event->type() == EventTypeNames::blur ||
- event->type() == EventTypeNames::focus)) {
+ (event.IsMouseEvent() || event.IsDragEvent() ||
+ event.HasInterface(EventNames::WheelEvent) ||
+ event.type() == EventTypeNames::blur ||
+ event.type() == EventTypeNames::focus)) {
LayoutTextControlSingleLine* layout_text_control =
ToLayoutTextControlSingleLine(GetElement().GetLayoutObject());
- if (event->type() == EventTypeNames::blur) {
+ if (event.type() == EventTypeNames::blur) {
if (LayoutBox* inner_editor_layout_object =
GetElement().InnerEditorElement()->GetLayoutBox()) {
// FIXME: This class has no need to know about PaintLayer!
@@ -245,7 +245,7 @@ void TextFieldInputType::ForwardEvent(Event* event) {
}
layout_text_control->CapsLockStateMayHaveChanged();
- } else if (event->type() == EventTypeNames::focus) {
+ } else if (event.type() == EventTypeNames::focus) {
layout_text_control->CapsLockStateMayHaveChanged();
}
@@ -260,10 +260,10 @@ void TextFieldInputType::HandleBlurEvent() {
spin_button->ReleaseCapture();
}
-bool TextFieldInputType::ShouldSubmitImplicitly(Event* event) {
- return (event->type() == EventTypeNames::textInput &&
- event->HasInterface(EventNames::TextEvent) &&
- ToTextEvent(event)->data() == "\n") ||
+bool TextFieldInputType::ShouldSubmitImplicitly(const Event& event) {
+ return (event.type() == EventTypeNames::textInput &&
+ event.HasInterface(EventNames::TextEvent) &&
+ ToTextEvent(event).data() == "\n") ||
InputTypeView::ShouldSubmitImplicitly(event);
}
@@ -407,7 +407,7 @@ String TextFieldInputType::SanitizeValue(const String& proposed_value) const {
}
void TextFieldInputType::HandleBeforeTextInsertedEvent(
- BeforeTextInsertedEvent* event) {
+ BeforeTextInsertedEvent& event) {
// Make sure that the text to be inserted will not violate the maxLength.
// We use HTMLInputElement::innerEditorValue() instead of
@@ -447,7 +447,7 @@ void TextFieldInputType::HandleBeforeTextInsertedEvent(
// Truncate the inserted text to avoid violating the maxLength and other
// constraints.
- String event_text = event->GetText();
+ String event_text = event.GetText();
unsigned text_length = event_text.length();
while (text_length > 0 && IsASCIILineBreak(event_text[text_length - 1]))
text_length--;
@@ -456,7 +456,7 @@ void TextFieldInputType::HandleBeforeTextInsertedEvent(
event_text.Replace('\r', ' ');
event_text.Replace('\n', ' ');
- event->SetText(LimitLength(event_text, appendable_length));
+ event.SetText(LimitLength(event_text, appendable_length));
}
bool TextFieldInputType::ShouldRespectListAttribute() {
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 9fd8ca56c72..77ced4ace78 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
@@ -52,7 +52,7 @@ class TextFieldInputType : public InputType,
TextFieldInputType(HTMLInputElement&);
~TextFieldInputType() override;
bool CanSetSuggestedValue() override;
- void HandleKeydownEvent(KeyboardEvent*) override;
+ void HandleKeydownEvent(KeyboardEvent&) override;
void CreateShadowSubtree() override;
void DestroyShadowSubtree() override;
@@ -73,7 +73,7 @@ class TextFieldInputType : public InputType,
virtual String ConvertFromVisibleValue(const String&) const;
virtual void DidSetValueByUserEdit();
- void HandleKeydownEventForSpinButton(KeyboardEvent*);
+ void HandleKeydownEventForSpinButton(KeyboardEvent&);
bool ShouldHaveSpinButton() const;
Element* ContainerElement() const;
@@ -83,9 +83,9 @@ class TextFieldInputType : public InputType,
bool MayTriggerVirtualKeyboard() const final;
bool IsTextField() const final;
bool ValueMissing(const String&) const override;
- void HandleBeforeTextInsertedEvent(BeforeTextInsertedEvent*) override;
- void ForwardEvent(Event*) final;
- bool ShouldSubmitImplicitly(Event*) final;
+ void HandleBeforeTextInsertedEvent(BeforeTextInsertedEvent&) override;
+ void ForwardEvent(Event&) final;
+ bool ShouldSubmitImplicitly(const Event&) final;
bool ShouldRespectListAttribute() override;
void ListAttributeTargetChanged() override;
void UpdatePlaceholderText() final;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/type_ahead.cc b/chromium/third_party/blink/renderer/core/html/forms/type_ahead.cc
index fcfcb60b40c..1327ff78854 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/type_ahead.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/type_ahead.cc
@@ -51,12 +51,13 @@ static String StripLeadingWhiteSpace(const String& string) {
return string.Substring(i, length - i);
}
-int TypeAhead::HandleEvent(KeyboardEvent* event, MatchModeFlags match_mode) {
+int TypeAhead::HandleEvent(const KeyboardEvent& event,
+ MatchModeFlags match_mode) {
if (last_type_time_) {
- if (event->PlatformTimeStamp() < *last_type_time_)
+ if (event.PlatformTimeStamp() < *last_type_time_)
return -1;
- if (event->PlatformTimeStamp() - *last_type_time_ > kTypeAheadTimeout)
+ if (event.PlatformTimeStamp() - *last_type_time_ > kTypeAheadTimeout)
buffer_.Clear();
} else {
// If |last_type_time_| is null, there should be no type ahead session in
@@ -64,9 +65,9 @@ int TypeAhead::HandleEvent(KeyboardEvent* event, MatchModeFlags match_mode) {
// empty.
DCHECK(buffer_.IsEmpty());
}
- last_type_time_ = event->PlatformTimeStamp();
+ last_type_time_ = event.PlatformTimeStamp();
- UChar c = event->charCode();
+ UChar c = event.charCode();
buffer_.Append(c);
int option_count = data_source_->OptionCount();
@@ -119,10 +120,10 @@ int TypeAhead::HandleEvent(KeyboardEvent* event, MatchModeFlags match_mode) {
return -1;
}
-bool TypeAhead::HasActiveSession(KeyboardEvent* event) {
+bool TypeAhead::HasActiveSession(const KeyboardEvent& event) {
if (!last_type_time_)
return false;
- TimeDelta delta = event->PlatformTimeStamp() - *last_type_time_;
+ TimeDelta delta = event.PlatformTimeStamp() - *last_type_time_;
return delta <= kTypeAheadTimeout;
}
diff --git a/chromium/third_party/blink/renderer/core/html/forms/type_ahead.h b/chromium/third_party/blink/renderer/core/html/forms/type_ahead.h
index 25c91411fba..033d37ea432 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/type_ahead.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/type_ahead.h
@@ -60,8 +60,8 @@ class CORE_EXPORT TypeAhead {
using MatchModeFlags = unsigned;
// Returns the index for the matching option.
- int HandleEvent(KeyboardEvent*, MatchModeFlags);
- bool HasActiveSession(KeyboardEvent*);
+ int HandleEvent(const KeyboardEvent&, MatchModeFlags);
+ bool HasActiveSession(const KeyboardEvent&);
void ResetSession();
private:
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 f7c74b52229..5077a9152e2 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
@@ -51,7 +51,7 @@ TEST_F(TypeAheadTest, HasActiveSessionAtStart) {
WebInputEvent::kChar, 0,
base::TimeTicks() + base::TimeDelta::FromMilliseconds(500));
web_event.text[0] = ' ';
- KeyboardEvent* event = KeyboardEvent::Create(web_event, nullptr);
+ auto& event = *KeyboardEvent::Create(web_event, nullptr);
EXPECT_FALSE(type_ahead_.HasActiveSession(event));
}
@@ -62,7 +62,7 @@ TEST_F(TypeAheadTest, HasActiveSessionAfterHandleEvent) {
WebInputEvent::kChar, 0,
base::TimeTicks() + base::TimeDelta::FromMilliseconds(500));
web_event.text[0] = ' ';
- KeyboardEvent* event = KeyboardEvent::Create(web_event, nullptr);
+ auto& event = *KeyboardEvent::Create(web_event, nullptr);
type_ahead_.HandleEvent(
event, TypeAhead::kMatchPrefix | TypeAhead::kCycleFirstChar);
@@ -76,7 +76,7 @@ TEST_F(TypeAheadTest, HasActiveSessionAfterHandleEvent) {
WebInputEvent::kChar, 0,
base::TimeTicks() + base::TimeDelta::FromMilliseconds(1500));
web_event.text[0] = ' ';
- KeyboardEvent* event = KeyboardEvent::Create(web_event, nullptr);
+ auto& event = *KeyboardEvent::Create(web_event, nullptr);
EXPECT_TRUE(type_ahead_.HasActiveSession(event));
}
@@ -86,7 +86,7 @@ TEST_F(TypeAheadTest, HasActiveSessionAfterHandleEvent) {
WebInputEvent::kChar, 0,
base::TimeTicks() + base::TimeDelta::FromMilliseconds(1501));
web_event.text[0] = ' ';
- KeyboardEvent* event = KeyboardEvent::Create(web_event, nullptr);
+ auto& event = *KeyboardEvent::Create(web_event, nullptr);
EXPECT_FALSE(type_ahead_.HasActiveSession(event));
}
}
@@ -96,7 +96,7 @@ TEST_F(TypeAheadTest, HasActiveSessionAfterResetSession) {
WebInputEvent::kChar, 0,
base::TimeTicks() + base::TimeDelta::FromMilliseconds(500));
web_event.text[0] = ' ';
- KeyboardEvent* event = KeyboardEvent::Create(web_event, nullptr);
+ auto& event = *KeyboardEvent::Create(web_event, nullptr);
type_ahead_.HandleEvent(event,
TypeAhead::kMatchPrefix | TypeAhead::kCycleFirstChar);
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 4862942b40a..055c6aa2980 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
@@ -33,6 +33,7 @@
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/frame/use_counter.h"
#include "third_party/blink/renderer/core/html/anchor_element_metrics.h"
+#include "third_party/blink/renderer/core/html/anchor_element_metrics_sender.h"
#include "third_party/blink/renderer/core/html/html_image_element.h"
#include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h"
#include "third_party/blink/renderer/core/layout/layout_box.h"
@@ -45,6 +46,9 @@
#include "third_party/blink/renderer/platform/network/network_hints.h"
#include "third_party/blink/renderer/platform/weborigin/security_policy.h"
+#include "third_party/blink/renderer/bindings/core/v8/usv_string_or_trusted_url.h"
+#include "third_party/blink/renderer/core/trustedtypes/trusted_url.h"
+
namespace blink {
using namespace HTMLNames;
@@ -122,7 +126,7 @@ static void AppendServerMapMousePosition(StringBuilder& url, Event* event) {
// The origin (0,0) is at the upper left of the content area, inside the
// padding and border.
- map_point -= ToLayoutBox(layout_object)->ContentBoxOffset();
+ map_point -= ToLayoutBox(layout_object)->PhysicalContentBoxOffset();
// CSS zoom is not reflected in the map coordinates.
float scale_factor = 1 / layout_object->Style()->EffectiveZoom();
@@ -139,11 +143,11 @@ static void AppendServerMapMousePosition(StringBuilder& url, Event* event) {
url.AppendNumber(clamped_point.Y());
}
-void HTMLAnchorElement::DefaultEventHandler(Event* event) {
+void HTMLAnchorElement::DefaultEventHandler(Event& event) {
if (IsLink()) {
if (IsFocused() && IsEnterKeyKeydownEvent(event) && IsLiveLink()) {
- event->SetDefaultHandled();
- DispatchSimulatedClick(event);
+ event.SetDefaultHandled();
+ DispatchSimulatedClick(&event);
return;
}
@@ -248,6 +252,11 @@ void HTMLAnchorElement::SetHref(const AtomicString& value) {
setAttribute(hrefAttr, value);
}
+void HTMLAnchorElement::setHref(const USVStringOrTrustedURL& stringOrTrustedURL,
+ ExceptionState& exception_state) {
+ setAttribute(hrefAttr, stringOrTrustedURL, exception_state);
+}
+
KURL HTMLAnchorElement::Url() const {
return Href();
}
@@ -307,8 +316,7 @@ void HTMLAnchorElement::SendPings(const KURL& destination_url) const {
ping_value.Contains('<')) {
Deprecation::CountDeprecation(
GetDocument(), WebFeature::kCanRequestURLHTTPContainingNewline);
- if (RuntimeEnabledFeatures::RestrictCanRequestURLCharacterSetEnabled())
- return;
+ return;
}
UseCounter::Count(GetDocument(), WebFeature::kHTMLAnchorElementPingAttribute);
@@ -321,8 +329,8 @@ void HTMLAnchorElement::SendPings(const KURL& destination_url) const {
}
}
-void HTMLAnchorElement::HandleClick(Event* event) {
- event->SetDefaultHandled();
+void HTMLAnchorElement::HandleClick(Event& event) {
+ event.SetDefaultHandled();
LocalFrame* frame = GetDocument().GetFrame();
if (!frame)
@@ -333,11 +341,11 @@ void HTMLAnchorElement::HandleClick(Event* event) {
WebFeature::kAnchorClickDispatchForNonConnectedNode);
}
- AnchorElementMetrics::MaybeExtractMetricsClicked(this);
+ AnchorElementMetrics::MaybeReportClickedMetricsOnClick(this);
StringBuilder url;
url.Append(StripLeadingAndTrailingHTMLSpaces(FastGetAttribute(hrefAttr)));
- AppendServerMapMousePosition(url, event);
+ AppendServerMapMousePosition(url, &event);
KURL completed_url = GetDocument().CompleteURL(url.ToString());
// Schedule the ping before the frame load. Prerender in Chrome may kill the
@@ -354,8 +362,7 @@ void HTMLAnchorElement::HandleClick(Event* event) {
!HasRel(kRelationNoReferrer)) {
UseCounter::Count(GetDocument(),
WebFeature::kHTMLAnchorElementReferrerPolicyAttribute);
- request.SetHTTPReferrer(SecurityPolicy::GenerateReferrer(
- policy, completed_url, GetDocument().OutgoingReferrer()));
+ request.SetReferrerPolicy(policy);
}
if (hasAttribute(downloadAttr)) {
@@ -370,7 +377,7 @@ void HTMLAnchorElement::HandleClick(Event* event) {
}
// Ignore the download attribute if we either can't read the content, or
// the event is an alt-click or similar.
- if (NavigationPolicyFromEvent(event) != kNavigationPolicyDownload &&
+ if (NavigationPolicyFromEvent(&event) != kNavigationPolicyDownload &&
GetDocument().GetSecurityOrigin()->CanReadContent(completed_url)) {
request.SetSuggestedFilename(
static_cast<String>(FastGetAttribute(downloadAttr)));
@@ -390,29 +397,31 @@ void HTMLAnchorElement::HandleClick(Event* event) {
}
if (HasRel(kRelationNoOpener))
frame_request.SetShouldSetOpener(kNeverSetOpener);
+ frame_request.SetHrefTranslate(FastGetAttribute(hreftranslateAttr));
frame_request.SetTriggeringEventInfo(
- event->isTrusted() ? WebTriggeringEventInfo::kFromTrustedEvent
- : WebTriggeringEventInfo::kFromUntrustedEvent);
+ event.isTrusted() ? WebTriggeringEventInfo::kFromTrustedEvent
+ : WebTriggeringEventInfo::kFromUntrustedEvent);
+ frame_request.SetInputStartTime(event.PlatformTimeStamp());
// TODO(japhet): Link clicks can be emulated via JS without a user gesture.
// Why doesn't this go through NavigationScheduler?
frame->Loader().StartNavigation(frame_request, WebFrameLoadType::kStandard,
- NavigationPolicyFromEvent(event));
+ NavigationPolicyFromEvent(&event));
}
-bool IsEnterKeyKeydownEvent(Event* event) {
- return event->type() == EventTypeNames::keydown && event->IsKeyboardEvent() &&
- ToKeyboardEvent(event)->key() == "Enter" &&
- !ToKeyboardEvent(event)->repeat();
+bool IsEnterKeyKeydownEvent(Event& event) {
+ return event.type() == EventTypeNames::keydown && event.IsKeyboardEvent() &&
+ ToKeyboardEvent(event).key() == "Enter" &&
+ !ToKeyboardEvent(event).repeat();
}
-bool IsLinkClick(Event* event) {
- if ((event->type() != EventTypeNames::click &&
- event->type() != EventTypeNames::auxclick) ||
- !event->IsMouseEvent()) {
+bool IsLinkClick(Event& event) {
+ if ((event.type() != EventTypeNames::click &&
+ event.type() != EventTypeNames::auxclick) ||
+ !event.IsMouseEvent()) {
return false;
}
- MouseEvent* mouse_event = ToMouseEvent(event);
- short button = mouse_event->button();
+ auto& mouse_event = ToMouseEvent(event);
+ short button = mouse_event.button();
return (button == static_cast<short>(WebPointerProperties::Button::kLeft) ||
button == static_cast<short>(WebPointerProperties::Button::kMiddle));
}
@@ -426,10 +435,15 @@ bool HTMLAnchorElement::IsInteractiveContent() const {
}
Node::InsertionNotificationRequest HTMLAnchorElement::InsertedInto(
- ContainerNode* insertion_point) {
+ ContainerNode& insertion_point) {
InsertionNotificationRequest request =
HTMLElement::InsertedInto(insertion_point);
LogAddElementIfIsolatedWorldAndInDocument("a", hrefAttr);
+
+ Document& top_document = GetDocument().TopDocument();
+ if (AnchorElementMetricsSender::HasAnchorElementMetricsSender(top_document))
+ AnchorElementMetricsSender::From(top_document)->AddAnchorElement(*this);
+
return request;
}
diff --git a/chromium/third_party/blink/renderer/core/html/html_anchor_element.h b/chromium/third_party/blink/renderer/core/html/html_anchor_element.h
index 46fa061558f..1a1ef58df4e 100644
--- a/chromium/third_party/blink/renderer/core/html/html_anchor_element.h
+++ b/chromium/third_party/blink/renderer/core/html/html_anchor_element.h
@@ -58,6 +58,9 @@ enum {
kRelationNoOpener = 0x00040000,
};
+class ExceptionState;
+class USVStringOrTrustedURL;
+
class CORE_EXPORT HTMLAnchorElement : public HTMLElement, public DOMURLUtils {
DEFINE_WRAPPERTYPEINFO();
@@ -68,6 +71,7 @@ class CORE_EXPORT HTMLAnchorElement : public HTMLElement, public DOMURLUtils {
KURL Href() const;
void SetHref(const AtomicString&);
+ void setHref(const USVStringOrTrustedURL&, ExceptionState&);
const AtomicString& GetName() const;
@@ -106,7 +110,7 @@ class CORE_EXPORT HTMLAnchorElement : public HTMLElement, public DOMURLUtils {
bool ShouldHaveFocusAppearance() const final;
bool IsMouseFocusable() const override;
bool IsKeyboardFocusable() const override;
- void DefaultEventHandler(Event*) final;
+ void DefaultEventHandler(Event&) final;
bool HasActivationBehavior() const override;
void SetActive(bool = true) final;
void AccessKeyAction(bool send_mouse_events) final;
@@ -116,8 +120,8 @@ class CORE_EXPORT HTMLAnchorElement : public HTMLElement, public DOMURLUtils {
int tabIndex() const final;
bool draggable() const final;
bool IsInteractiveContent() const final;
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
- void HandleClick(Event*);
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
+ void HandleClick(Event&);
unsigned link_relations_ : 31;
mutable LinkHash cached_visited_link_hash_;
@@ -133,8 +137,8 @@ inline LinkHash HTMLAnchorElement::VisitedLinkHash() const {
// Functions shared with the other anchor elements (i.e., SVG).
-bool IsEnterKeyKeydownEvent(Event*);
-bool IsLinkClick(Event*);
+bool IsEnterKeyKeydownEvent(Event&);
+bool IsLinkClick(Event&);
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/html_anchor_element.idl b/chromium/third_party/blink/renderer/core/html/html_anchor_element.idl
index a1c70d7e97c..b988d1be33c 100644
--- a/chromium/third_party/blink/renderer/core/html/html_anchor_element.idl
+++ b/chromium/third_party/blink/renderer/core/html/html_anchor_element.idl
@@ -27,6 +27,7 @@ interface HTMLAnchorElement : HTMLElement {
[CEReactions, Reflect] attribute DOMString rel;
[SameObject, PutForwards=value] readonly attribute DOMTokenList relList;
[CEReactions, Reflect] attribute DOMString hreflang;
+ [RuntimeEnabled=HrefTranslate, CEReactions, Reflect] attribute DOMString hrefTranslate;
[CEReactions, Reflect] attribute DOMString type;
[CEReactions, Reflect, ReflectOnly=("","no-referrer","origin","no-referrer-when-downgrade","origin-when-cross-origin","unsafe-url"), ReflectMissing="", ReflectInvalid=""] attribute DOMString referrerPolicy;
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 7e379723313..92811c0ef7d 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
@@ -92,6 +92,7 @@
"high",
"href",
"hreflang",
+ "hreftranslate",
"hspace",
"http-equiv",
"id",
@@ -101,13 +102,16 @@
"inert",
"inputmode",
"integrity",
+ "intrinsicsize",
"is",
"ismap",
"keytype",
"kind",
+ "invisible",
"label",
"lang",
"language",
+ "lazyload",
"leftmargin",
"link",
"list",
@@ -137,6 +141,7 @@
"nowrap",
"object",
"onabort",
+ "onactivateinvisible",
"onafterprint",
"onanimationstart",
"onanimationiteration",
@@ -213,6 +218,7 @@
"onpointermove",
"onpointerout",
"onpointerover",
+ "onpointerrawmove",
"onpointerup",
"onpopstate",
"onprogress",
diff --git a/chromium/third_party/blink/renderer/core/html/html_base_element.cc b/chromium/third_party/blink/renderer/core/html/html_base_element.cc
index ffc67f05147..e36e2d35881 100644
--- a/chromium/third_party/blink/renderer/core/html/html_base_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_base_element.cc
@@ -48,16 +48,16 @@ void HTMLBaseElement::ParseAttribute(
}
Node::InsertionNotificationRequest HTMLBaseElement::InsertedInto(
- ContainerNode* insertion_point) {
+ ContainerNode& insertion_point) {
HTMLElement::InsertedInto(insertion_point);
- if (insertion_point->isConnected())
+ if (insertion_point.isConnected())
GetDocument().ProcessBaseElement();
return kInsertionDone;
}
-void HTMLBaseElement::RemovedFrom(ContainerNode* insertion_point) {
+void HTMLBaseElement::RemovedFrom(ContainerNode& insertion_point) {
HTMLElement::RemovedFrom(insertion_point);
- if (insertion_point->isConnected())
+ if (insertion_point.isConnected())
GetDocument().ProcessBaseElement();
}
@@ -96,21 +96,7 @@ KURL HTMLBaseElement::href() const {
void HTMLBaseElement::setHref(const USVStringOrTrustedURL& stringOrUrl,
ExceptionState& exception_state) {
- DCHECK(stringOrUrl.IsUSVString() ||
- RuntimeEnabledFeatures::TrustedDOMTypesEnabled());
- DCHECK(!stringOrUrl.IsNull());
-
- if (stringOrUrl.IsUSVString() && GetDocument().RequireTrustedTypes()) {
- exception_state.ThrowTypeError(
- "This document requires `TrustedURL` assignment.");
- return;
- }
-
- AtomicString value(stringOrUrl.IsUSVString()
- ? stringOrUrl.GetAsUSVString()
- : stringOrUrl.GetAsTrustedURL()->toString());
-
- setAttribute(hrefAttr, value);
+ setAttribute(hrefAttr, stringOrUrl, exception_state);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/html_base_element.h b/chromium/third_party/blink/renderer/core/html/html_base_element.h
index e05135dbeed..132fb47e946 100644
--- a/chromium/third_party/blink/renderer/core/html/html_base_element.h
+++ b/chromium/third_party/blink/renderer/core/html/html_base_element.h
@@ -45,8 +45,8 @@ class HTMLBaseElement final : public HTMLElement {
bool IsURLAttribute(const Attribute&) const override;
void ParseAttribute(const AttributeModificationParams&) override;
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
- void RemovedFrom(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
+ void RemovedFrom(ContainerNode&) override;
};
} // namespace blink
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 9ba00c43265..4d4c3b99b3e 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
@@ -235,7 +235,7 @@ void HTMLBodyElement::ParseAttribute(
}
Node::InsertionNotificationRequest HTMLBodyElement::InsertedInto(
- ContainerNode* insertion_point) {
+ ContainerNode& insertion_point) {
HTMLElement::InsertedInto(insertion_point);
return kInsertionShouldCallDidNotifySubtreeInsertions;
}
diff --git a/chromium/third_party/blink/renderer/core/html/html_body_element.h b/chromium/third_party/blink/renderer/core/html/html_body_element.h
index 98305e10ee9..16bc931578a 100644
--- a/chromium/third_party/blink/renderer/core/html/html_body_element.h
+++ b/chromium/third_party/blink/renderer/core/html/html_body_element.h
@@ -57,7 +57,7 @@ class CORE_EXPORT HTMLBodyElement final : public HTMLElement {
const AtomicString&,
MutableCSSPropertyValueSet*) override;
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
void DidNotifySubtreeInsertionsToDocument() override;
bool IsURLAttribute(const Attribute&) const override;
diff --git a/chromium/third_party/blink/renderer/core/html/html_details_element.cc b/chromium/third_party/blink/renderer/core/html/html_details_element.cc
index 5f229ac5dc1..3873d06703e 100644
--- a/chromium/third_party/blink/renderer/core/html/html_details_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_details_element.cc
@@ -67,7 +67,7 @@ bool HTMLDetailsElement::IsFirstSummary(const Node& node) {
}
void HTMLDetailsElement::DispatchPendingEvent() {
- DispatchEvent(Event::Create(EventTypeNames::toggle));
+ DispatchEvent(*Event::Create(EventTypeNames::toggle));
}
LayoutObject* HTMLDetailsElement::CreateLayoutObject(
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 a4edfeaa209..e3143d836a3 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
@@ -28,6 +28,7 @@
#include "third_party/blink/renderer/core/accessibility/ax_object_cache.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/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/use_counter.h"
#include "third_party/blink/renderer/core/fullscreen/fullscreen.h"
@@ -180,7 +181,7 @@ void HTMLDialogElement::showModal(ExceptionState& exception_state) {
SetFocusForDialog(this);
}
-void HTMLDialogElement::RemovedFrom(ContainerNode* insertion_point) {
+void HTMLDialogElement::RemovedFrom(ContainerNode& insertion_point) {
HTMLElement::RemovedFrom(insertion_point);
SetNotCentered();
InertSubtreesChanged(GetDocument());
@@ -207,10 +208,10 @@ bool HTMLDialogElement::IsPresentationAttribute(
return HTMLElement::IsPresentationAttribute(name);
}
-void HTMLDialogElement::DefaultEventHandler(Event* event) {
- if (event->type() == EventTypeNames::cancel) {
+void HTMLDialogElement::DefaultEventHandler(Event& event) {
+ if (event.type() == EventTypeNames::cancel) {
close();
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
return;
}
HTMLElement::DefaultEventHandler(event);
diff --git a/chromium/third_party/blink/renderer/core/html/html_dialog_element.h b/chromium/third_party/blink/renderer/core/html/html_dialog_element.h
index 9b5691b6aa8..1562436ff75 100644
--- a/chromium/third_party/blink/renderer/core/html/html_dialog_element.h
+++ b/chromium/third_party/blink/renderer/core/html/html_dialog_element.h
@@ -43,7 +43,7 @@ class HTMLDialogElement final : public HTMLElement {
void close(const String& return_value = String());
void show();
void showModal(ExceptionState&);
- void RemovedFrom(ContainerNode*) override;
+ void RemovedFrom(ContainerNode&) override;
// NotCentered means do not center the dialog. Centered means the dialog has
// been centered and centeredPosition() is set. NeedsCentering means attempt
@@ -66,7 +66,7 @@ class HTMLDialogElement final : public HTMLElement {
explicit HTMLDialogElement(Document&);
bool IsPresentationAttribute(const QualifiedName&) const override;
- void DefaultEventHandler(Event*) override;
+ void DefaultEventHandler(Event&) override;
void ForceLayoutForCentering();
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 2b4aea46f74..ea779b097c7 100644
--- a/chromium/third_party/blink/renderer/core/html/html_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_element.cc
@@ -45,6 +45,7 @@
#include "third_party/blink/renderer/core/editing/spellcheck/spell_checker.h"
#include "third_party/blink/renderer/core/events/keyboard_event.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/settings.h"
#include "third_party/blink/renderer/core/frame/use_counter.h"
#include "third_party/blink/renderer/core/html/forms/html_form_element.h"
@@ -334,6 +335,8 @@ AttributeTriggers* HTMLElement::TriggersForAttributeName(
&HTMLElement::OnXMLLangAttrChanged},
{onabortAttr, kNoWebFeature, EventTypeNames::abort, nullptr},
+ {onactivateinvisibleAttr, kNoWebFeature,
+ EventTypeNames::activateinvisible, nullptr},
{onanimationendAttr, kNoWebFeature, EventTypeNames::animationend,
nullptr},
{onanimationiterationAttr, kNoWebFeature,
@@ -409,6 +412,8 @@ AttributeTriggers* HTMLElement::TriggersForAttributeName(
{onpointermoveAttr, kNoWebFeature, EventTypeNames::pointermove, nullptr},
{onpointeroutAttr, kNoWebFeature, EventTypeNames::pointerout, nullptr},
{onpointeroverAttr, kNoWebFeature, EventTypeNames::pointerover, nullptr},
+ {onpointerrawmoveAttr, kNoWebFeature, EventTypeNames::pointerrawmove,
+ nullptr},
{onpointerupAttr, kNoWebFeature, EventTypeNames::pointerup, nullptr},
{onprogressAttr, kNoWebFeature, EventTypeNames::progress, nullptr},
{onratechangeAttr, kNoWebFeature, EventTypeNames::ratechange, nullptr},
@@ -1058,7 +1063,7 @@ void HTMLElement::AdjustDirectionalityIfNeededAfterChildrenChanged(
}
Node::InsertionNotificationRequest HTMLElement::InsertedInto(
- ContainerNode* insertion_point) {
+ ContainerNode& insertion_point) {
// Process the superclass first to ensure that `InActiveDocument()` is
// updated.
Element::InsertedInto(insertion_point);
@@ -1207,10 +1212,10 @@ bool HTMLElement::IsInteractiveContent() const {
return false;
}
-void HTMLElement::DefaultEventHandler(Event* event) {
- if (event->type() == EventTypeNames::keypress && event->IsKeyboardEvent()) {
+void HTMLElement::DefaultEventHandler(Event& event) {
+ if (event.type() == EventTypeNames::keypress && event.IsKeyboardEvent()) {
HandleKeypressEvent(ToKeyboardEvent(event));
- if (event->DefaultHandled())
+ if (event.DefaultHandled())
return;
}
@@ -1236,7 +1241,7 @@ bool HTMLElement::MatchesReadWritePseudoClass() const {
return parentElement() && HasEditableStyle(*parentElement());
}
-void HTMLElement::HandleKeypressEvent(KeyboardEvent* event) {
+void HTMLElement::HandleKeypressEvent(KeyboardEvent& event) {
if (!IsSpatialNavigationEnabled(GetDocument().GetFrame()) || !SupportsFocus())
return;
GetDocument().UpdateStyleAndLayoutTree();
@@ -1246,10 +1251,10 @@ void HTMLElement::HandleKeypressEvent(KeyboardEvent* event) {
// action.
if (IsTextControl() || HasEditableStyle(*this))
return;
- int char_code = event->charCode();
+ int char_code = event.charCode();
if (char_code == '\r' || char_code == ' ') {
- DispatchSimulatedClick(event);
- event->SetDefaultHandled();
+ DispatchSimulatedClick(&event);
+ event.SetDefaultHandled();
}
}
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 241c4c8f1ce..418bf8c54b9 100644
--- a/chromium/third_party/blink/renderer/core/html/html_element.h
+++ b/chromium/third_party/blink/renderer/core/html/html_element.h
@@ -102,7 +102,7 @@ class CORE_EXPORT HTMLElement : public Element {
virtual bool IsLabelable() const { return false; }
// http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#interactive-content
virtual bool IsInteractiveContent() const;
- void DefaultEventHandler(Event*) override;
+ void DefaultEventHandler(Event&) override;
static const AtomicString& EventNameForAttributeName(
const QualifiedName& attr_name);
@@ -154,7 +154,7 @@ class CORE_EXPORT HTMLElement : public Element {
void ChildrenChanged(const ChildrenChange&) override;
void CalculateAndAdjustDirectionality();
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
private:
String DebugNodeName() const final;
@@ -178,7 +178,7 @@ class CORE_EXPORT HTMLElement : public Element {
TranslateAttributeMode GetTranslateAttributeMode() const;
- void HandleKeypressEvent(KeyboardEvent*);
+ void HandleKeypressEvent(KeyboardEvent&);
static AttributeTriggers* TriggersForAttributeName(
const QualifiedName& attr_name);
diff --git a/chromium/third_party/blink/renderer/core/html/html_element_test.cc b/chromium/third_party/blink/renderer/core/html/html_element_test.cc
new file mode 100644
index 00000000000..f0c8d331cb0
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/html/html_element_test.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/core/html/html_element.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/core/testing/page_test_base.h"
+
+namespace blink {
+
+class HTMLElementTest : public PageTestBase {};
+
+TEST_F(HTMLElementTest, AdjustDirectionalityInFlatTree) {
+ SetBodyContent("<bdi><summary><i id=target></i></summary></bdi>");
+ UpdateAllLifecyclePhases();
+ GetDocument().getElementById("target")->remove();
+ // Pass if not crashed.
+}
+
+} // namespace blink
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 e770805c114..3d9304a7b19 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
@@ -187,7 +187,7 @@ void HTMLFrameElementBase::SetNameAndOpenURL() {
}
Node::InsertionNotificationRequest HTMLFrameElementBase::InsertedInto(
- ContainerNode* insertion_point) {
+ ContainerNode& insertion_point) {
HTMLFrameOwnerElement::InsertedInto(insertion_point);
// We should never have a content frame at the point where we got inserted
// into a tree.
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 5eae80dd946..cfe6e814a74 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
@@ -47,7 +47,7 @@ class CORE_EXPORT HTMLFrameElementBase : public HTMLFrameOwnerElement {
void ParseAttribute(const AttributeModificationParams&) override;
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
void DidNotifySubtreeInsertionsToDocument() final;
void AttachLayoutTree(AttachContext&) override;
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 645cbeef2cb..2d8afad79b1 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
@@ -25,11 +25,13 @@
#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/exported/web_plugin_container_impl.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_client.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/remote_frame_view.h"
#include "third_party/blink/renderer/core/html/lazy_load_frame_observer.h"
+#include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/core/layout/layout_embedded_content.h"
#include "third_party/blink/renderer/core/loader/document_loader.h"
#include "third_party/blink/renderer/core/loader/frame_load_request.h"
@@ -252,7 +254,7 @@ void HTMLFrameOwnerElement::DispatchLoad() {
if (lazy_load_frame_observer_)
lazy_load_frame_observer_->RecordMetricsOnLoadFinished();
- DispatchScopedEvent(Event::Create(EventTypeNames::load));
+ DispatchScopedEvent(*Event::Create(EventTypeNames::load));
}
const ParsedFeaturePolicy& HTMLFrameOwnerElement::ContainerPolicy() const {
@@ -337,6 +339,16 @@ bool HTMLFrameOwnerElement::LoadOrRedirectSubframe(
const KURL& url,
const AtomicString& frame_name,
bool replace_current_item) {
+ // Update the |should_lazy_load_children_| value according to the "lazyload"
+ // attribute immediately, so that it still gets respected even if the "src"
+ // attribute gets parsed in ParseAttribute() before the "lazyload" attribute
+ // does.
+ if (should_lazy_load_children_ &&
+ EqualIgnoringASCIICase(FastGetAttribute(HTMLNames::lazyloadAttr),
+ "off")) {
+ should_lazy_load_children_ = false;
+ }
+
UpdateContainerPolicy();
if (ContentFrame()) {
@@ -361,10 +373,7 @@ bool HTMLFrameOwnerElement::LoadOrRedirectSubframe(
ResourceRequest request(url);
ReferrerPolicy policy = ReferrerPolicyAttribute();
- if (policy != kReferrerPolicyDefault) {
- request.SetHTTPReferrer(SecurityPolicy::GenerateReferrer(
- policy, url, GetDocument().OutgoingReferrer()));
- }
+ request.SetReferrerPolicy(policy);
WebFrameLoadType child_load_type = WebFrameLoadType::kReplaceCurrentItem;
if (!GetDocument().LoadEventFinished() &&
@@ -383,25 +392,27 @@ bool HTMLFrameOwnerElement::LoadOrRedirectSubframe(
if ((RuntimeEnabledFeatures::LazyFrameLoadingEnabled() ||
RuntimeEnabledFeatures::LazyFrameVisibleLoadTimeMetricsEnabled()) &&
- should_lazy_load_children_ &&
+ !lazy_load_frame_observer_ &&
// Only http:// or https:// URLs are eligible for lazy loading, excluding
// URLs like invalid or empty URLs, "about:blank", local file URLs, etc.
// that it doesn't make sense to lazily load.
url.ProtocolIsInHTTPFamily() &&
- // Disallow lazy loading if javascript in the embedding document would be
- // able to access the contents of the frame, since in those cases
- // deferring the frame could break the page. Note that this check does not
- // take any possible redirects of |url| into account.
- !GetDocument().GetSecurityOrigin()->CanAccess(
- SecurityOrigin::Create(url).get())) {
- // Don't lazy load subresources inside a lazily loaded frame. This will make
- // it possible for subresources in hidden frames to load that will
- // never be visible, as well as make it so that deferred frames that have
- // multiple layers of iframes inside them can load faster once they're near
- // the viewport or visible.
+ (EqualIgnoringASCIICase(FastGetAttribute(HTMLNames::lazyloadAttr),
+ "on") ||
+ (should_lazy_load_children_ &&
+ // Disallow lazy loading by default if javascript in the embedding
+ // document would be able to access the contents of the frame, since in
+ // those cases deferring the frame could break the page. Note that this
+ // check does not take any possible redirects of |url| into account.
+ !GetDocument().GetSecurityOrigin()->CanAccess(
+ SecurityOrigin::Create(url).get())))) {
+ // By default, avoid deferring subresources inside a lazily loaded frame.
+ // This will make it possible for subresources in hidden frames to load that
+ // will never be visible, as well as make it so that deferred frames that
+ // have multiple layers of iframes inside them can load faster once they're
+ // near the viewport or visible.
should_lazy_load_children_ = false;
- DCHECK(!lazy_load_frame_observer_);
lazy_load_frame_observer_ = new LazyLoadFrameObserver(*this);
if (RuntimeEnabledFeatures::LazyFrameVisibleLoadTimeMetricsEnabled())
@@ -430,6 +441,21 @@ bool HTMLFrameOwnerElement::ShouldLazyLoadChildren() const {
return should_lazy_load_children_;
}
+void HTMLFrameOwnerElement::ParseAttribute(
+ const AttributeModificationParams& params) {
+ if (params.name == HTMLNames::lazyloadAttr) {
+ if (EqualIgnoringASCIICase(params.new_value, "off")) {
+ should_lazy_load_children_ = false;
+ if (lazy_load_frame_observer_ &&
+ lazy_load_frame_observer_->IsLazyLoadPending()) {
+ lazy_load_frame_observer_->LoadImmediately();
+ }
+ }
+ } else {
+ HTMLElement::ParseAttribute(params);
+ }
+}
+
void HTMLFrameOwnerElement::Trace(blink::Visitor* visitor) {
visitor->Trace(content_frame_);
visitor->Trace(embedded_content_view_);
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 5e62e5ad01d..f8fe9ffeebf 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
@@ -118,6 +118,8 @@ class CORE_EXPORT HTMLFrameOwnerElement : public HTMLElement,
void CancelPendingLazyLoad();
+ void ParseAttribute(const AttributeModificationParams&) override;
+
void Trace(blink::Visitor*) override;
protected:
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 b1a5c9ee85c..e6eed01a33b 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
@@ -29,7 +29,6 @@
#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/events/mouse_event.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_client.h"
#include "third_party/blink/renderer/core/frame/use_counter.h"
@@ -263,11 +262,11 @@ void HTMLFrameSetElement::AttachLayoutTree(AttachContext& context) {
HTMLElement::AttachLayoutTree(context);
}
-void HTMLFrameSetElement::DefaultEventHandler(Event* evt) {
- if (evt->IsMouseEvent() && !noresize_ && GetLayoutObject() &&
+void HTMLFrameSetElement::DefaultEventHandler(Event& evt) {
+ if (evt.IsMouseEvent() && !noresize_ && GetLayoutObject() &&
GetLayoutObject()->IsFrameSet()) {
if (ToLayoutFrameSet(GetLayoutObject())->UserResize(ToMouseEvent(evt))) {
- evt->SetDefaultHandled();
+ evt.SetDefaultHandled();
return;
}
}
@@ -275,8 +274,8 @@ void HTMLFrameSetElement::DefaultEventHandler(Event* evt) {
}
Node::InsertionNotificationRequest HTMLFrameSetElement::InsertedInto(
- ContainerNode* insertion_point) {
- if (insertion_point->isConnected() && GetDocument().GetFrame()) {
+ ContainerNode& insertion_point) {
+ if (insertion_point.isConnected() && GetDocument().GetFrame()) {
// A document using <frameset> likely won't literally have a body, but as
// far as the client is concerned, the frameset is effectively the body.
GetDocument().WillInsertBody();
@@ -292,23 +291,4 @@ void HTMLFrameSetElement::WillRecalcStyle(StyleRecalcChange) {
}
}
-LocalDOMWindow* HTMLFrameSetElement::AnonymousNamedGetter(
- const AtomicString& name) {
- Element* frame_element = Children()->namedItem(name);
- if (!IsHTMLFrameElement(frame_element))
- return nullptr;
- Document* document = ToHTMLFrameElement(frame_element)->contentDocument();
- if (!document || !document->GetFrame())
- return nullptr;
-
- LocalDOMWindow* window = document->domWindow();
- if (window) {
- UseCounter::Count(
- *document, WebFeature::kHTMLFrameSetElementNonNullAnonymousNamedGetter);
- }
- Deprecation::CountDeprecation(
- *document, WebFeature::kHTMLFrameSetElementAnonymousNamedGetter);
- return window;
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/html_frame_set_element.h b/chromium/third_party/blink/renderer/core/html/html_frame_set_element.h
index 98e44dea87c..19614936be3 100644
--- a/chromium/third_party/blink/renderer/core/html/html_frame_set_element.h
+++ b/chromium/third_party/blink/renderer/core/html/html_frame_set_element.h
@@ -51,8 +51,6 @@ class HTMLFrameSetElement final : public HTMLElement {
bool HasNonInBodyInsertionMode() const override { return true; }
- LocalDOMWindow* AnonymousNamedGetter(const AtomicString&);
-
DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(blur);
DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(error);
DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(focus);
@@ -75,9 +73,9 @@ class HTMLFrameSetElement final : public HTMLElement {
bool LayoutObjectIsNeeded(const ComputedStyle&) const override;
LayoutObject* CreateLayoutObject(const ComputedStyle&) override;
- void DefaultEventHandler(Event*) override;
+ void DefaultEventHandler(Event&) override;
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
void WillRecalcStyle(StyleRecalcChange) override;
Vector<HTMLDimension> row_lengths_;
diff --git a/chromium/third_party/blink/renderer/core/html/html_frame_set_element.idl b/chromium/third_party/blink/renderer/core/html/html_frame_set_element.idl
index 372df5434ba..c3418963b09 100644
--- a/chromium/third_party/blink/renderer/core/html/html_frame_set_element.idl
+++ b/chromium/third_party/blink/renderer/core/html/html_frame_set_element.idl
@@ -39,7 +39,6 @@
attribute EventHandler onscroll;
// Non-standard APIs
- [NotEnumerable] getter Window (DOMString name);
[RuntimeEnabled=OrientationEvent] attribute EventHandler onorientationchange;
};
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 594570fcffd..a1835bff94b 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
@@ -119,22 +119,22 @@ HTMLSelectElement* HTMLHRElement::OwnerSelectElement() const {
}
Node::InsertionNotificationRequest HTMLHRElement::InsertedInto(
- ContainerNode* insertion_point) {
+ ContainerNode& insertion_point) {
HTMLElement::InsertedInto(insertion_point);
if (HTMLSelectElement* select = OwnerSelectElement()) {
- if (insertion_point == select || (IsHTMLOptGroupElement(*insertion_point) &&
- insertion_point->parentNode() == select))
+ if (&insertion_point == select || (IsHTMLOptGroupElement(insertion_point) &&
+ insertion_point.parentNode() == select))
select->HrInsertedOrRemoved(*this);
}
return kInsertionDone;
}
-void HTMLHRElement::RemovedFrom(ContainerNode* insertion_point) {
- if (auto* select = ToHTMLSelectElementOrNull(*insertion_point)) {
+void HTMLHRElement::RemovedFrom(ContainerNode& insertion_point) {
+ if (auto* select = ToHTMLSelectElementOrNull(insertion_point)) {
if (!parentNode() || IsHTMLOptGroupElement(*parentNode()))
select->HrInsertedOrRemoved(*this);
- } else if (IsHTMLOptGroupElement(*insertion_point)) {
- Node* parent = insertion_point->parentNode();
+ } else if (IsHTMLOptGroupElement(insertion_point)) {
+ Node* parent = insertion_point.parentNode();
if (auto* select = ToHTMLSelectElementOrNull(parent))
select->HrInsertedOrRemoved(*this);
}
diff --git a/chromium/third_party/blink/renderer/core/html/html_hr_element.h b/chromium/third_party/blink/renderer/core/html/html_hr_element.h
index a595db984e1..09087f53858 100644
--- a/chromium/third_party/blink/renderer/core/html/html_hr_element.h
+++ b/chromium/third_party/blink/renderer/core/html/html_hr_element.h
@@ -46,8 +46,8 @@ class HTMLHRElement final : public HTMLElement {
const QualifiedName&,
const AtomicString&,
MutableCSSPropertyValueSet*) override;
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
- void RemovedFrom(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
+ void RemovedFrom(ContainerNode&) override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/html_hyperlink_element_utils.idl b/chromium/third_party/blink/renderer/core/html/html_hyperlink_element_utils.idl
index c2e628caf4d..bf2021fbe4b 100644
--- a/chromium/third_party/blink/renderer/core/html/html_hyperlink_element_utils.idl
+++ b/chromium/third_party/blink/renderer/core/html/html_hyperlink_element_utils.idl
@@ -8,7 +8,7 @@
NoInterfaceObject // Always used on target of 'implements'
] interface HTMLHyperlinkElementUtils {
- [CEReactions, RaisesException=Setter, CallWith=ScriptState] stringifier attribute URLString href;
+ [CEReactions, RaisesException=Setter] stringifier attribute URLString href;
readonly attribute USVString origin;
[CEReactions] attribute USVString protocol;
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 fae0cdf64c2..7dcd351c2b7 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
@@ -173,8 +173,7 @@ void HTMLIFrameElement::ParseAttribute(
FrameOwnerPropertiesChanged();
UpdateContainerPolicy();
}
- } else if (RuntimeEnabledFeatures::EmbedderCSPEnforcementEnabled() &&
- name == cspAttr) {
+ } else if (name == cspAttr) {
if (!ContentSecurityPolicy::IsValidCSPAttr(
value.GetString(), GetDocument().RequiredCSP().GetString())) {
required_csp_ = g_null_atom;
@@ -274,11 +273,11 @@ LayoutObject* HTMLIFrameElement::CreateLayoutObject(const ComputedStyle&) {
}
Node::InsertionNotificationRequest HTMLIFrameElement::InsertedInto(
- ContainerNode* insertion_point) {
+ ContainerNode& insertion_point) {
InsertionNotificationRequest result =
HTMLFrameElementBase::InsertedInto(insertion_point);
- if (insertion_point->IsInDocumentTree() && GetDocument().IsHTMLDocument()) {
+ if (insertion_point.IsInDocumentTree() && GetDocument().IsHTMLDocument()) {
ToHTMLDocument(GetDocument()).AddNamedItem(name_);
if (!ContentSecurityPolicy::IsValidCSPAttr(
@@ -298,9 +297,9 @@ Node::InsertionNotificationRequest HTMLIFrameElement::InsertedInto(
return result;
}
-void HTMLIFrameElement::RemovedFrom(ContainerNode* insertion_point) {
+void HTMLIFrameElement::RemovedFrom(ContainerNode& insertion_point) {
HTMLFrameElementBase::RemovedFrom(insertion_point);
- if (insertion_point->IsInDocumentTree() && GetDocument().IsHTMLDocument())
+ if (insertion_point.IsInDocumentTree() && GetDocument().IsHTMLDocument())
ToHTMLDocument(GetDocument()).RemoveNamedItem(name_);
}
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 4b898d38257..eabe69962d2 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
@@ -62,8 +62,8 @@ class CORE_EXPORT HTMLIFrameElement final
const AtomicString&,
MutableCSSPropertyValueSet*) override;
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
- void RemovedFrom(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
+ void RemovedFrom(ContainerNode&) override;
bool LayoutObjectIsNeeded(const ComputedStyle&) const override;
LayoutObject* CreateLayoutObject(const ComputedStyle&) override;
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 c0d5a9c012c..c45e0f752d8 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
@@ -39,7 +39,7 @@ interface HTMLIFrameElement : HTMLElement {
[CheckSecurity=ReturnValue, RaisesException] Document? getSVGDocument();
[CEReactions, Reflect, ReflectOnly=("","no-referrer","origin","no-referrer-when-downgrade","origin-when-cross-origin","unsafe-url"), ReflectMissing="", ReflectInvalid=""] attribute DOMString referrerPolicy;
// https://w3c.github.io/webappsec-csp/embedded/#dom-htmliframeelement-csp
- [RuntimeEnabled=EmbedderCSPEnforcement, CEReactions, Reflect] attribute DOMString csp;
+ [CEReactions, Reflect] attribute DOMString csp;
// Feature Policy
// https://wicg.github.io/feature-policy/
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 8c29fcd4001..9ad16293c39 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
@@ -61,6 +61,7 @@
#include "third_party/blink/renderer/core/trustedtypes/trusted_url.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/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/weborigin/security_policy.h"
namespace blink {
@@ -100,6 +101,7 @@ HTMLImageElement::HTMLImageElement(Document& document, bool created_by_parser)
element_created_by_parser_(created_by_parser),
is_fallback_image_(false),
should_invert_color_(false),
+ sizes_set_width_(false),
referrer_policy_(kReferrerPolicyDefault) {
SetHasCustomStyleCallbacks();
}
@@ -222,6 +224,7 @@ void HTMLImageElement::ResetFormOwner() {
void HTMLImageElement::SetBestFitURLAndDPRFromImageCandidate(
const ImageCandidate& candidate) {
+ sizes_set_width_ = false;
best_fit_image_url_ = candidate.Url();
float candidate_density = candidate.Density();
float old_image_device_pixel_ratio = image_device_pixel_ratio_;
@@ -231,6 +234,7 @@ void HTMLImageElement::SetBestFitURLAndDPRFromImageCandidate(
bool intrinsic_sizing_viewport_dependant = false;
if (candidate.GetResourceWidth() > 0) {
intrinsic_sizing_viewport_dependant = true;
+ sizes_set_width_ = true;
UseCounter::Count(GetDocument(), WebFeature::kSrcsetWDescriptor);
} else if (!candidate.SrcOrigin()) {
UseCounter::Count(GetDocument(), WebFeature::kSrcsetXDescriptor);
@@ -276,10 +280,13 @@ void HTMLImageElement::ParseAttribute(
UseCounter::Count(GetDocument(),
WebFeature::kHTMLImageElementReferrerPolicyAttribute);
}
- } else if (name == decodingAttr &&
- RuntimeEnabledFeatures::ImageDecodingAttributeEnabled()) {
+ } else if (name == decodingAttr) {
UseCounter::Count(GetDocument(), WebFeature::kImageDecodingAttribute);
decoding_mode_ = ParseImageDecodingMode(params.new_value);
+ } else if (name == intrinsicsizeAttr &&
+ RuntimeEnabledFeatures::
+ ExperimentalProductivityFeaturesEnabled()) {
+ ParseIntrinsicSizeAttribute(params.new_value);
} else {
HTMLElement::ParseAttribute(params);
}
@@ -390,9 +397,9 @@ void HTMLImageElement::AttachLayoutTree(AttachContext& context) {
}
Node::InsertionNotificationRequest HTMLImageElement::InsertedInto(
- ContainerNode* insertion_point) {
+ ContainerNode& insertion_point) {
if (!form_was_set_by_parser_ ||
- NodeTraversal::HighestAncestorOrSelf(*insertion_point) !=
+ NodeTraversal::HighestAncestorOrSelf(insertion_point) !=
NodeTraversal::HighestAncestorOrSelf(*form_.Get()))
ResetFormOwner();
if (listener_)
@@ -412,15 +419,17 @@ Node::InsertionNotificationRequest HTMLImageElement::InsertedInto(
// If we have been inserted from a layoutObject-less document,
// our loader may have not fetched the image, so do it now.
- if ((insertion_point->isConnected() && !GetImageLoader().GetContent()) ||
- image_was_modified)
+ if ((insertion_point.isConnected() && !GetImageLoader().GetContent() &&
+ !GetImageLoader().HasPendingActivity()) ||
+ image_was_modified) {
GetImageLoader().UpdateFromElement(ImageLoader::kUpdateNormal,
referrer_policy_);
+ }
return HTMLElement::InsertedInto(insertion_point);
}
-void HTMLImageElement::RemovedFrom(ContainerNode* insertion_point) {
+void HTMLImageElement::RemovedFrom(ContainerNode& insertion_point) {
if (!form_ || NodeTraversal::HighestAncestorOrSelf(*form_.Get()) !=
NodeTraversal::HighestAncestorOrSelf(*this))
ResetFormOwner();
@@ -476,9 +485,13 @@ unsigned HTMLImageElement::height() {
}
LayoutSize HTMLImageElement::DensityCorrectedIntrinsicDimensions() const {
+ IntSize overridden_intrinsic_size = GetOverriddenIntrinsicSize();
+ if (!overridden_intrinsic_size.IsEmpty())
+ return LayoutSize(overridden_intrinsic_size);
ImageResourceContent* image_resource = GetImageLoader().GetContent();
if (!image_resource || !image_resource->HasImage())
return LayoutSize();
+
float pixel_density = image_device_pixel_ratio_;
if (image_resource->HasDevicePixelRatioHeaderValue() &&
image_resource->DevicePixelRatioHeaderValue() > 0)
@@ -486,6 +499,7 @@ LayoutSize HTMLImageElement::DensityCorrectedIntrinsicDimensions() const {
RespectImageOrientationEnum respect_image_orientation =
LayoutObject::ShouldRespectImageOrientation(GetLayoutObject());
+
LayoutSize natural_size(
image_resource->IntrinsicSize(respect_image_orientation));
natural_size.Scale(pixel_density);
@@ -503,14 +517,14 @@ unsigned HTMLImageElement::naturalHeight() const {
unsigned HTMLImageElement::LayoutBoxWidth() const {
LayoutBox* box = GetLayoutBox();
return box ? AdjustForAbsoluteZoom::AdjustInt(
- box->ContentBoxRect().PixelSnappedWidth(), box)
+ box->PhysicalContentBoxRect().PixelSnappedWidth(), box)
: 0;
}
unsigned HTMLImageElement::LayoutBoxHeight() const {
LayoutBox* box = GetLayoutBox();
return box ? AdjustForAbsoluteZoom::AdjustInt(
- box->ContentBoxRect().PixelSnappedHeight(), box)
+ box->PhysicalContentBoxRect().PixelSnappedHeight(), box)
: 0;
}
@@ -557,6 +571,43 @@ void HTMLImageElement::setHeight(unsigned value) {
SetUnsignedIntegralAttribute(heightAttr, value);
}
+IntSize HTMLImageElement::GetOverriddenIntrinsicSize() const {
+ if (sizes_set_width_ && !overridden_intrinsic_size_.IsEmpty()) {
+ float width = GetResourceWidth().width;
+ return IntSize(
+ RoundToInt(LayoutUnit(width)),
+ RoundToInt(LayoutUnit(
+ width * overridden_intrinsic_size_.Height() /
+ static_cast<float>(overridden_intrinsic_size_.Width()))));
+ }
+ return overridden_intrinsic_size_;
+}
+
+void HTMLImageElement::ParseIntrinsicSizeAttribute(const String& value) {
+ unsigned new_width = 0, new_height = 0;
+ Vector<String> size;
+ value.Split('x', size);
+ if (!value.IsEmpty() &&
+ (size.size() != 2 ||
+ !ParseHTMLNonNegativeInteger(size.at(0), new_width) ||
+ !ParseHTMLNonNegativeInteger(size.at(1), new_height))) {
+ GetDocument().AddConsoleMessage(
+ ConsoleMessage::Create(kOtherMessageSource, kWarningMessageLevel,
+ "Unable to parse intrinsicSize: expected "
+ "[unsigned] x [unsigned], got " +
+ value));
+ new_width = 0;
+ new_height = 0;
+ }
+
+ IntSize new_size(new_width, new_height);
+ if (overridden_intrinsic_size_ != new_size) {
+ overridden_intrinsic_size_ = new_size;
+ if (GetLayoutObject() && GetLayoutObject()->IsLayoutImage())
+ ToLayoutImage(GetLayoutObject())->IntrinsicSizeChanged();
+ }
+}
+
KURL HTMLImageElement::Src() const {
return GetDocument().CompleteURL(getAttribute(srcAttr));
}
@@ -656,10 +707,10 @@ FloatSize HTMLImageElement::DefaultDestinationSize(
return FloatSize(size);
}
-static bool SourceSizeValue(Element& element,
+static bool SourceSizeValue(const Element* element,
Document& current_document,
float& source_size) {
- String sizes = element.FastGetAttribute(sizesAttr);
+ String sizes = element->FastGetAttribute(sizesAttr);
bool exists = !sizes.IsNull();
if (exists)
UseCounter::Count(current_document, WebFeature::kSizes);
@@ -669,13 +720,11 @@ static bool SourceSizeValue(Element& element,
return exists;
}
-FetchParameters::ResourceWidth HTMLImageElement::GetResourceWidth() {
+FetchParameters::ResourceWidth HTMLImageElement::GetResourceWidth() const {
FetchParameters::ResourceWidth resource_width;
Element* element = source_.Get();
- if (!element)
- element = this;
- resource_width.is_set =
- SourceSizeValue(*element, GetDocument(), resource_width.width);
+ resource_width.is_set = SourceSizeValue(element ? element : this,
+ GetDocument(), resource_width.width);
return resource_width;
}
@@ -683,7 +732,7 @@ float HTMLImageElement::SourceSize(Element& element) {
float value;
// We don't care here if the sizes attribute exists, so we ignore the return
// value. If it doesn't exist, we just return the default.
- SourceSizeValue(element, GetDocument(), value);
+ SourceSizeValue(&element, GetDocument(), value);
return value;
}
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 14a6964d1ea..4a8ab5c0e88 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
@@ -24,6 +24,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_HTML_IMAGE_ELEMENT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_HTML_IMAGE_ELEMENT_H_
+#include <memory>
+
#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"
@@ -31,6 +33,8 @@
#include "third_party/blink/renderer/core/html/forms/form_associated.h"
#include "third_party/blink/renderer/core/html/html_element.h"
#include "third_party/blink/renderer/core/html/html_image_loader.h"
+#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/heap/heap_allocator.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h"
@@ -87,6 +91,9 @@ class CORE_EXPORT HTMLImageElement final
ImageResource* CachedImageResourceForImageDocument() const {
return GetImageLoader().ImageResourceForImageDocument();
}
+ void LoadDeferredImage() {
+ GetImageLoader().LoadDeferredImage(referrer_policy_);
+ }
void SetImageForTest(ImageResourceContent* content) {
GetImageLoader().SetImageForTest(content);
}
@@ -101,6 +108,8 @@ class CORE_EXPORT HTMLImageElement final
void setWidth(unsigned);
+ IntSize GetOverriddenIntrinsicSize() const;
+
int x() const;
int y() const;
@@ -131,7 +140,7 @@ class CORE_EXPORT HTMLImageElement final
void SetIsFallbackImage() { is_fallback_image_ = true; }
- FetchParameters::ResourceWidth GetResourceWidth();
+ FetchParameters::ResourceWidth GetResourceWidth() const;
float SourceSize(Element&);
void ForceReload() const;
@@ -139,6 +148,17 @@ class CORE_EXPORT HTMLImageElement final
FormAssociated* ToFormAssociatedOrNull() override { return this; };
void AssociateWith(HTMLFormElement*) override;
+ bool ElementCreatedByParser() const { return element_created_by_parser_; }
+
+ LazyLoadImageObserver::VisibleLoadTimeMetrics&
+ EnsureVisibleLoadTimeMetrics() {
+ if (!visible_load_time_metrics_) {
+ visible_load_time_metrics_ =
+ std::make_unique<LazyLoadImageObserver::VisibleLoadTimeMetrics>();
+ }
+ return *visible_load_time_metrics_;
+ }
+
protected:
// Controls how an image element appears in the layout. See:
// https://html.spec.whatwg.org/multipage/embedded-content.html#image-request
@@ -185,8 +205,8 @@ class CORE_EXPORT HTMLImageElement final
bool draggable() const override;
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
- void RemovedFrom(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
+ void RemovedFrom(ContainerNode&) override;
NamedItemType GetNamedItemType() const override {
return NamedItemType::kNameOrIdWithName;
}
@@ -201,6 +221,8 @@ class CORE_EXPORT HTMLImageElement final
void NotifyViewportChanged();
void CreateMediaQueryListIfDoesNotExist();
+ void ParseIntrinsicSizeAttribute(const String& value);
+
Member<HTMLImageLoader> image_loader_;
Member<ViewportChangeListener> listener_;
Member<HTMLFormElement> form_;
@@ -212,8 +234,14 @@ class CORE_EXPORT HTMLImageElement final
unsigned element_created_by_parser_ : 1;
unsigned is_fallback_image_ : 1;
bool should_invert_color_;
+ bool sizes_set_width_;
ReferrerPolicy referrer_policy_;
+
+ IntSize overridden_intrinsic_size_;
+
+ std::unique_ptr<LazyLoadImageObserver::VisibleLoadTimeMetrics>
+ visible_load_time_metrics_;
};
} // 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 c3e798091f8..b752807f648 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
@@ -40,8 +40,10 @@
readonly attribute boolean complete;
readonly attribute DOMString currentSrc;
[CEReactions, Reflect, ReflectOnly=("","no-referrer","origin","no-referrer-when-downgrade","origin-when-cross-origin","unsafe-url"), ReflectMissing="", ReflectInvalid=""] attribute DOMString referrerPolicy;
- [RuntimeEnabled=ImageDecodingAttribute, CEReactions, Reflect, ReflectOnly=("async", "sync", "auto"), ReflectMissing="auto", ReflectInvalid="auto"] attribute DOMString decoding;
+ [CEReactions, Reflect, ReflectOnly=("async", "sync", "auto"), ReflectMissing="auto", ReflectInvalid="auto"] attribute DOMString decoding;
[CEReactions, RuntimeEnabled=PriorityHints, Reflect, ReflectOnly=("low", "auto", "high"), ReflectMissing="auto", ReflectInvalid="auto"] attribute DOMString importance;
+ // https://github.com/ojanvafai/intrinsicsize-attribute/blob/master/README.md
+ [RuntimeEnabled=ExperimentalProductivityFeatures, CEReactions, Reflect] attribute DOMString intrinsicSize;
// obsolete members
// https://html.spec.whatwg.org/#HTMLImageElement-partial
@@ -59,5 +61,5 @@
[MeasureAs=HTMLImageElementX] readonly attribute long x;
[MeasureAs=HTMLImageElementY] readonly attribute long y;
- [RuntimeEnabled=JSImageDecode, CallWith=ScriptState, RaisesException] Promise decode();
+ [CallWith=ScriptState, RaisesException] Promise decode();
};
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 45bcc55d547..037b0f90ef3 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
@@ -52,7 +52,7 @@ void HTMLImageLoader::DispatchLoadEvent() {
// An <object> considers a 404 to be an error and should fire onerror.
error_occurred = (GetContent()->GetResponse().HttpStatusCode() >= 400);
}
- GetElement()->DispatchEvent(Event::Create(
+ GetElement()->DispatchEvent(*Event::Create(
error_occurred ? EventTypeNames::error : EventTypeNames::load));
}
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 113961948b9..16be42aa1c1 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
@@ -33,6 +33,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/dom/events/event.h"
+#include "third_party/blink/renderer/core/frame/deprecation.h"
#include "third_party/blink/renderer/core/frame/local_frame_client.h"
#include "third_party/blink/renderer/core/frame/use_counter.h"
#include "third_party/blink/renderer/core/html/cross_origin_attribute.h"
@@ -70,6 +71,9 @@ void HTMLLinkElement::ParseAttribute(
const AtomicString& value = params.new_value;
if (name == relAttr) {
rel_attribute_ = LinkRelAttribute(value);
+ if (rel_attribute_.IsImport()) {
+ Deprecation::CountDeprecation(GetDocument(), WebFeature::kHTMLImports);
+ }
rel_list_->DidUpdateAttributeValue(params.old_value, value);
Process();
} else if (name == hrefAttr) {
@@ -110,6 +114,8 @@ void HTMLLinkElement::ParseAttribute(
importance_ = value;
} else if (name == disabledAttr) {
UseCounter::Count(GetDocument(), WebFeature::kHTMLLinkElementDisabled);
+ if (params.reason == AttributeModificationReason::kByParser)
+ UseCounter::Count(GetDocument(), WebFeature::kHTMLLinkElementDisabledByParser);
if (LinkStyle* link = GetLinkStyle())
link->SetDisabledState(!value.IsNull());
} else {
@@ -201,10 +207,10 @@ void HTMLLinkElement::Process() {
}
Node::InsertionNotificationRequest HTMLLinkElement::InsertedInto(
- ContainerNode* insertion_point) {
+ ContainerNode& insertion_point) {
HTMLElement::InsertedInto(insertion_point);
LogAddElementIfIsolatedWorldAndInDocument("link", relAttr, hrefAttr);
- if (!insertion_point->isConnected())
+ if (!insertion_point.isConnected())
return kInsertionDone;
DCHECK(isConnected());
if (!ShouldLoadLink() && IsInShadowTree()) {
@@ -224,12 +230,12 @@ Node::InsertionNotificationRequest HTMLLinkElement::InsertedInto(
return kInsertionDone;
}
-void HTMLLinkElement::RemovedFrom(ContainerNode* insertion_point) {
+void HTMLLinkElement::RemovedFrom(ContainerNode& insertion_point) {
// Store the result of isConnected() here before Node::removedFrom(..) clears
// the flags.
bool was_connected = isConnected();
HTMLElement::RemovedFrom(insertion_point);
- if (!insertion_point->isConnected())
+ if (!insertion_point.isConnected())
return;
link_loader_->Abort();
@@ -238,8 +244,8 @@ void HTMLLinkElement::RemovedFrom(ContainerNode* insertion_point) {
DCHECK(!GetLinkStyle() || !GetLinkStyle()->HasSheet());
return;
}
- GetDocument().GetStyleEngine().RemoveStyleSheetCandidateNode(
- *this, *insertion_point);
+ GetDocument().GetStyleEngine().RemoveStyleSheetCandidateNode(*this,
+ insertion_point);
if (link_)
link_->OwnerRemoved();
}
@@ -259,27 +265,28 @@ bool HTMLLinkElement::StyleSheetIsLoading() const {
}
void HTMLLinkElement::LinkLoaded() {
- DispatchEvent(Event::Create(EventTypeNames::load));
+ DispatchEvent(*Event::Create(EventTypeNames::load));
}
void HTMLLinkElement::LinkLoadingErrored() {
- DispatchEvent(Event::Create(EventTypeNames::error));
+ DispatchEvent(*Event::Create(EventTypeNames::error));
}
void HTMLLinkElement::DidStartLinkPrerender() {
- DispatchEvent(Event::Create(EventTypeNames::webkitprerenderstart));
+ DispatchEvent(*Event::Create(EventTypeNames::webkitprerenderstart));
}
void HTMLLinkElement::DidStopLinkPrerender() {
- DispatchEvent(Event::Create(EventTypeNames::webkitprerenderstop));
+ DispatchEvent(*Event::Create(EventTypeNames::webkitprerenderstop));
}
void HTMLLinkElement::DidSendLoadForLinkPrerender() {
- DispatchEvent(Event::Create(EventTypeNames::webkitprerenderload));
+ DispatchEvent(*Event::Create(EventTypeNames::webkitprerenderload));
}
void HTMLLinkElement::DidSendDOMContentLoadedForLinkPrerender() {
- DispatchEvent(Event::Create(EventTypeNames::webkitprerenderdomcontentloaded));
+ DispatchEvent(
+ *Event::Create(EventTypeNames::webkitprerenderdomcontentloaded));
}
scoped_refptr<base::SingleThreadTaskRunner>
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 56774e1a1a8..4efebf4bd67 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
@@ -133,8 +133,8 @@ class CORE_EXPORT HTMLLinkElement final : public HTMLElement,
// From Node and subclassses
void ParseAttribute(const AttributeModificationParams&) override;
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
- void RemovedFrom(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
+ void RemovedFrom(ContainerNode&) override;
bool IsURLAttribute(const Attribute&) const override;
bool HasLegalLinkAttribute(const QualifiedName&) const override;
const QualifiedName& SubResourceAttributeName() const override;
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 62a9a980a93..d7eb12070cf 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
@@ -87,13 +87,13 @@ void HTMLMapElement::ParseAttribute(const AttributeModificationParams& params) {
return;
}
if (isConnected())
- GetTreeScope().RemoveImageMap(this);
+ GetTreeScope().RemoveImageMap(*this);
String map_name = params.new_value;
if (map_name[0] == '#')
map_name = map_name.Substring(1);
name_ = AtomicString(map_name);
if (isConnected())
- GetTreeScope().AddImageMap(this);
+ GetTreeScope().AddImageMap(*this);
return;
}
@@ -106,15 +106,15 @@ HTMLCollection* HTMLMapElement::areas() {
}
Node::InsertionNotificationRequest HTMLMapElement::InsertedInto(
- ContainerNode* insertion_point) {
- if (insertion_point->isConnected())
- GetTreeScope().AddImageMap(this);
+ ContainerNode& insertion_point) {
+ if (insertion_point.isConnected())
+ GetTreeScope().AddImageMap(*this);
return HTMLElement::InsertedInto(insertion_point);
}
-void HTMLMapElement::RemovedFrom(ContainerNode* insertion_point) {
- if (insertion_point->isConnected())
- GetTreeScope().RemoveImageMap(this);
+void HTMLMapElement::RemovedFrom(ContainerNode& insertion_point) {
+ if (insertion_point.isConnected())
+ GetTreeScope().RemoveImageMap(*this);
HTMLElement::RemovedFrom(insertion_point);
}
diff --git a/chromium/third_party/blink/renderer/core/html/html_map_element.h b/chromium/third_party/blink/renderer/core/html/html_map_element.h
index bf40b8fad60..c5bce072aa8 100644
--- a/chromium/third_party/blink/renderer/core/html/html_map_element.h
+++ b/chromium/third_party/blink/renderer/core/html/html_map_element.h
@@ -50,8 +50,8 @@ class CORE_EXPORT HTMLMapElement final : public HTMLElement {
void ParseAttribute(const AttributeModificationParams&) override;
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
- void RemovedFrom(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
+ void RemovedFrom(ContainerNode&) override;
AtomicString name_;
};
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 85588ab0613..c13307136df 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
@@ -37,6 +37,7 @@
#include "third_party/blink/renderer/core/css/css_style_declaration.h"
#include "third_party/blink/renderer/core/css_property_names.h"
#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/dom/events/event_listener.h"
#include "third_party/blink/renderer/core/dom/frame_request_callback_collection.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
@@ -127,7 +128,7 @@ class HTMLMarqueeElement::AnimationFinished final : public EventListener {
};
Node::InsertionNotificationRequest HTMLMarqueeElement::InsertedInto(
- ContainerNode* insertion_point) {
+ ContainerNode& insertion_point) {
HTMLElement::InsertedInto(insertion_point);
if (isConnected())
@@ -136,9 +137,9 @@ Node::InsertionNotificationRequest HTMLMarqueeElement::InsertedInto(
return kInsertionDone;
}
-void HTMLMarqueeElement::RemovedFrom(ContainerNode* insertion_point) {
+void HTMLMarqueeElement::RemovedFrom(ContainerNode& insertion_point) {
HTMLElement::RemovedFrom(insertion_point);
- if (insertion_point->isConnected()) {
+ if (insertion_point.isConnected()) {
stop();
}
}
@@ -255,21 +256,24 @@ StringKeyframeEffectModel* HTMLMarqueeElement::CreateEffectModel(
SecureContextMode secure_context_mode =
mover_->GetDocument().GetSecureContextMode();
- scoped_refptr<StringKeyframe> keyframe1 = StringKeyframe::Create();
+ StringKeyframeVector keyframes;
+ StringKeyframe* keyframe1 = StringKeyframe::Create();
set_result = keyframe1->SetCSSPropertyValue(
CSSPropertyTransform, parameters.transform_begin, secure_context_mode,
style_sheet_contents);
DCHECK(set_result.did_parse);
+ keyframes.push_back(keyframe1);
- scoped_refptr<StringKeyframe> keyframe2 = StringKeyframe::Create();
+ StringKeyframe* keyframe2 = StringKeyframe::Create();
set_result = keyframe2->SetCSSPropertyValue(
CSSPropertyTransform, parameters.transform_end, secure_context_mode,
style_sheet_contents);
DCHECK(set_result.did_parse);
+ keyframes.push_back(keyframe2);
- return StringKeyframeEffectModel::Create(
- {std::move(keyframe1), std::move(keyframe2)},
- EffectModel::kCompositeReplace, LinearTimingFunction::Shared());
+ return StringKeyframeEffectModel::Create(keyframes,
+ EffectModel::kCompositeReplace,
+ LinearTimingFunction::Shared());
}
void HTMLMarqueeElement::ContinueAnimation() {
@@ -291,7 +295,7 @@ void HTMLMarqueeElement::ContinueAnimation() {
double duration = 0;
if (scroll_amount)
duration = parameters.distance * scroll_delay / scroll_amount;
- if (!duration)
+ if (duration <= 0)
return;
StringKeyframeEffectModel* effect_model = CreateEffectModel(parameters);
diff --git a/chromium/third_party/blink/renderer/core/html/html_marquee_element.h b/chromium/third_party/blink/renderer/core/html/html_marquee_element.h
index a366b09b336..a2b0d56eb07 100644
--- a/chromium/third_party/blink/renderer/core/html/html_marquee_element.h
+++ b/chromium/third_party/blink/renderer/core/html/html_marquee_element.h
@@ -37,8 +37,8 @@ class HTMLMarqueeElement final : public HTMLElement {
static HTMLMarqueeElement* Create(Document&);
- InsertionNotificationRequest InsertedInto(ContainerNode*) final;
- void RemovedFrom(ContainerNode*) final;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) final;
+ void RemovedFrom(ContainerNode&) final;
bool IsHorizontal() const;
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 dbd315181f1..36c0bff088b 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
@@ -486,7 +486,7 @@ void HTMLMetaElement::ParseAttribute(
}
Node::InsertionNotificationRequest HTMLMetaElement::InsertedInto(
- ContainerNode* insertion_point) {
+ ContainerNode& insertion_point) {
HTMLElement::InsertedInto(insertion_point);
return kInsertionShouldCallDidNotifySubtreeInsertions;
}
diff --git a/chromium/third_party/blink/renderer/core/html/html_meta_element.h b/chromium/third_party/blink/renderer/core/html/html_meta_element.h
index 207409164e8..0f7ecb567a8 100644
--- a/chromium/third_party/blink/renderer/core/html/html_meta_element.h
+++ b/chromium/third_party/blink/renderer/core/html/html_meta_element.h
@@ -74,7 +74,7 @@ class CORE_EXPORT HTMLMetaElement final : public HTMLElement {
bool viewport_meta_zero_values_quirk);
void ParseAttribute(const AttributeModificationParams&) override;
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
void DidNotifySubtreeInsertionsToDocument() override;
static float ParsePositiveNumber(Document*,
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 8537c83e021..4ac6bf8bdb4 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
@@ -289,13 +289,13 @@ void HTMLObjectElement::UpdatePluginInternal() {
}
Node::InsertionNotificationRequest HTMLObjectElement::InsertedInto(
- ContainerNode* insertion_point) {
+ ContainerNode& insertion_point) {
HTMLPlugInElement::InsertedInto(insertion_point);
ListedElement::InsertedInto(insertion_point);
return kInsertionDone;
}
-void HTMLObjectElement::RemovedFrom(ContainerNode* insertion_point) {
+void HTMLObjectElement::RemovedFrom(ContainerNode& insertion_point) {
HTMLPlugInElement::RemovedFrom(insertion_point);
ListedElement::RemovedFrom(insertion_point);
}
diff --git a/chromium/third_party/blink/renderer/core/html/html_object_element.h b/chromium/third_party/blink/renderer/core/html/html_object_element.h
index 7e33237e2b3..2d142b38708 100644
--- a/chromium/third_party/blink/renderer/core/html/html_object_element.h
+++ b/chromium/third_party/blink/renderer/core/html/html_object_element.h
@@ -91,8 +91,8 @@ class CORE_EXPORT HTMLObjectElement final : public HTMLPlugInElement,
const AtomicString&,
MutableCSSPropertyValueSet*) override;
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
- void RemovedFrom(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
+ void RemovedFrom(ContainerNode&) override;
void DidMoveToNewDocument(Document& old_document) override;
diff --git a/chromium/third_party/blink/renderer/core/html/html_picture_element.cc b/chromium/third_party/blink/renderer/core/html/html_picture_element.cc
index 9172a770c93..acabeb3c412 100644
--- a/chromium/third_party/blink/renderer/core/html/html_picture_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_picture_element.cc
@@ -50,7 +50,7 @@ void HTMLPictureElement::AddListenerToSourceChildren() {
}
Node::InsertionNotificationRequest HTMLPictureElement::InsertedInto(
- ContainerNode* insertion_point) {
+ ContainerNode& insertion_point) {
UseCounter::Count(GetDocument(), WebFeature::kPicture);
return HTMLElement::InsertedInto(insertion_point);
}
diff --git a/chromium/third_party/blink/renderer/core/html/html_picture_element.h b/chromium/third_party/blink/renderer/core/html/html_picture_element.h
index 27d6d850437..0127628cb29 100644
--- a/chromium/third_party/blink/renderer/core/html/html_picture_element.h
+++ b/chromium/third_party/blink/renderer/core/html/html_picture_element.h
@@ -23,7 +23,7 @@ class HTMLPictureElement final : public HTMLElement {
explicit HTMLPictureElement(Document&);
private:
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
};
} // namespace blink
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 d849d6968de..63481433984 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
@@ -69,6 +69,16 @@ enum PluginRequestObjectResult {
kPluginRequestObjectResultMax
};
+String GetMIMETypeFromURL(const KURL& url) {
+ String filename = url.LastPathComponent();
+ int extension_pos = filename.ReverseFind('.');
+ if (extension_pos >= 0) {
+ String extension = filename.Substring(extension_pos + 1);
+ return MIMETypeRegistry::GetWellKnownMIMETypeForExtension(extension);
+ }
+ return String();
+}
+
} // anonymous namespace
const Vector<String>& PluginParameters::Names() const {
@@ -148,6 +158,12 @@ void HTMLPlugInElement::SetFocused(bool focused, WebFocusType focus_type) {
bool HTMLPlugInElement::RequestObjectInternal(
const PluginParameters& plugin_params) {
+ if (handled_externally_) {
+ // TODO(ekaramad): Fix this once we know what to do with frames inside
+ // plugins (https://crbug.com/776510).
+ return true;
+ }
+
if (url_.IsEmpty() && service_type_.IsEmpty())
return false;
@@ -159,9 +175,20 @@ bool HTMLPlugInElement::RequestObjectInternal(
if (!AllowedToLoadObject(completed_url, service_type_))
return false;
+ handled_externally_ =
+ GetDocument().GetFrame()->Client()->IsPluginHandledExternally(
+ *this, completed_url,
+ service_type_.IsEmpty() ? GetMIMETypeFromURL(completed_url)
+ : service_type_);
+ if (handled_externally_) {
+ // This is a temporary placeholder and the logic around
+ // |handled_externally_| might change as MimeHandlerView is moving towards
+ // depending on OOPIFs instead of WebPlugin (https://crbug.com/659750).
+ completed_url = BlankURL();
+ }
ObjectContentType object_type = GetObjectContentType();
if (object_type == ObjectContentType::kFrame ||
- object_type == ObjectContentType::kImage) {
+ object_type == ObjectContentType::kImage || handled_externally_) {
// If the plugin element already contains a subframe,
// loadOrRedirectSubframe will re-use it. Otherwise, it will create a
// new frame and set it as the LayoutEmbeddedContent's EmbeddedContentView,
@@ -252,7 +279,7 @@ void HTMLPlugInElement::UpdatePlugin() {
}
}
-void HTMLPlugInElement::RemovedFrom(ContainerNode* insertion_point) {
+void HTMLPlugInElement::RemovedFrom(ContainerNode& insertion_point) {
// If we've persisted the plugin and we're removed from the tree then
// make sure we cleanup the persistance pointer.
if (persisted_plugin_) {
@@ -409,7 +436,7 @@ void HTMLPlugInElement::CollectStyleForPresentationAttribute(
}
}
-void HTMLPlugInElement::DefaultEventHandler(Event* event) {
+void HTMLPlugInElement::DefaultEventHandler(Event& event) {
// Firefox seems to use a fake event listener to dispatch events to plugin
// (tested with mouse events only). This is observable via different order
// of events - in Firefox, event listeners specified in HTML attributes
@@ -431,7 +458,7 @@ void HTMLPlugInElement::DefaultEventHandler(Event* event) {
if (!plugin)
return;
plugin->HandleEvent(event);
- if (event->DefaultHandled())
+ if (event.DefaultHandled())
return;
HTMLFrameOwnerElement::DefaultEventHandler(event);
}
@@ -489,13 +516,7 @@ HTMLPlugInElement::ObjectContentType HTMLPlugInElement::GetObjectContentType()
KURL url = GetDocument().CompleteURL(url_);
if (mime_type.IsEmpty()) {
// Try to guess the MIME type based off the extension.
- String filename = url.LastPathComponent();
- int extension_pos = filename.ReverseFind('.');
- if (extension_pos >= 0) {
- String extension = filename.Substring(extension_pos + 1);
- mime_type = MIMETypeRegistry::GetWellKnownMIMETypeForExtension(extension);
- }
-
+ mime_type = GetMIMETypeFromURL(url);
if (mime_type.IsEmpty())
return ObjectContentType::kFrame;
}
@@ -521,7 +542,7 @@ HTMLPlugInElement::ObjectContentType HTMLPlugInElement::GetObjectContentType()
bool HTMLPlugInElement::IsImageType() const {
if (GetDocument().GetFrame())
return GetObjectContentType() == ObjectContentType::kImage;
- return Image::SupportsType(service_type_);
+ return MIMETypeRegistry::IsSupportedImageResourceMIMEType(service_type_);
}
LayoutEmbeddedObject* HTMLPlugInElement::GetLayoutEmbeddedObject() const {
@@ -615,11 +636,12 @@ bool HTMLPlugInElement::LoadPlugin(const KURL& url,
}
void HTMLPlugInElement::DispatchErrorEvent() {
- if (GetDocument().IsPluginDocument() && GetDocument().LocalOwner())
+ if (GetDocument().IsPluginDocument() && GetDocument().LocalOwner()) {
GetDocument().LocalOwner()->DispatchEvent(
- Event::Create(EventTypeNames::error));
- else
- DispatchEvent(Event::Create(EventTypeNames::error));
+ *Event::Create(EventTypeNames::error));
+ } else {
+ DispatchEvent(*Event::Create(EventTypeNames::error));
+ }
}
bool HTMLPlugInElement::AllowedToLoadObject(const KURL& url,
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 62e6624c9c2..5120fac04c2 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
@@ -110,7 +110,7 @@ class CORE_EXPORT HTMLPlugInElement
PreferPlugInsForImagesOption);
// Node functions:
- void RemovedFrom(ContainerNode* insertion_point) override;
+ void RemovedFrom(ContainerNode& insertion_point) override;
void DidMoveToNewDocument(Document& old_document) override;
void AttachLayoutTree(AttachContext&) override;
@@ -160,7 +160,7 @@ class CORE_EXPORT HTMLPlugInElement
bool CanContainRangeEndPoint() const override { return false; }
bool CanStartSelection() const override;
bool WillRespondToMouseClickEvents() final;
- void DefaultEventHandler(Event*) final;
+ void DefaultEventHandler(Event&) final;
void DetachLayoutTree(const AttachContext& = AttachContext()) final;
void FinishParsingChildren() final;
@@ -224,6 +224,8 @@ class CORE_EXPORT HTMLPlugInElement
// off embedded_content_view_ here while the plugin is persisting but not
// being displayed.
Member<WebPluginContainerImpl> persisted_plugin_;
+
+ bool handled_externally_ = false;
};
inline bool IsHTMLPlugInElement(const HTMLElement& element) {
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 339453b3df8..86b3cefd4bf 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
@@ -88,9 +88,9 @@ void HTMLScriptElement::ParseAttribute(
}
Node::InsertionNotificationRequest HTMLScriptElement::InsertedInto(
- ContainerNode* insertion_point) {
+ ContainerNode& insertion_point) {
ScriptType script_type = ScriptType::kClassic;
- if (insertion_point->isConnected() && HasSourceAttribute() &&
+ if (insertion_point.isConnected() && HasSourceAttribute() &&
!ScriptLoader::IsValidScriptTypeAndLanguage(
TypeAttributeValue(), LanguageAttributeValue(),
ScriptLoader::kDisallowLegacyTypeInTypeAttribute, script_type)) {
@@ -160,6 +160,10 @@ String HTMLScriptElement::IntegrityAttributeValue() const {
return getAttribute(integrityAttr);
}
+String HTMLScriptElement::ReferrerPolicyAttributeValue() const {
+ return getAttribute(referrerpolicyAttr);
+}
+
String HTMLScriptElement::TextFromChildren() {
return Element::TextFromChildren();
}
@@ -204,11 +208,11 @@ Document& HTMLScriptElement::GetDocument() const {
}
void HTMLScriptElement::DispatchLoadEvent() {
- DispatchEvent(Event::Create(EventTypeNames::load));
+ DispatchEvent(*Event::Create(EventTypeNames::load));
}
void HTMLScriptElement::DispatchErrorEvent() {
- DispatchEvent(Event::Create(EventTypeNames::error));
+ DispatchEvent(*Event::Create(EventTypeNames::error));
}
void HTMLScriptElement::SetScriptElementForBinding(
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 b30157a1278..c2ad9c0aeae 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
@@ -60,7 +60,7 @@ class CORE_EXPORT HTMLScriptElement final : public HTMLElement,
HTMLScriptElement(Document&, const CreateElementFlags);
void ParseAttribute(const AttributeModificationParams&) override;
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
void DidNotifySubtreeInsertionsToDocument() override;
void ChildrenChanged(const ChildrenChange&) override;
void DidMoveToNewDocument(Document& old_document) override;
@@ -79,6 +79,7 @@ class CORE_EXPORT HTMLScriptElement final : public HTMLElement,
String EventAttributeValue() const override;
String CrossOriginAttributeValue() const override;
String IntegrityAttributeValue() const override;
+ String ReferrerPolicyAttributeValue() const override;
String TextFromChildren() override;
bool AsyncAttributeValue() const override;
bool DeferAttributeValue() const override;
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 36c8def3b60..7c0464c3719 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
@@ -28,6 +28,7 @@ interface HTMLScriptElement : HTMLElement {
[CEReactions, Reflect] attribute boolean defer;
[CEReactions, Reflect, ReflectOnly=("anonymous","use-credentials"), ReflectEmpty="anonymous", ReflectInvalid="anonymous"] attribute DOMString? crossOrigin;
[CEReactions] attribute DOMString 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;
// obsolete members
// https://html.spec.whatwg.org/#HTMLScriptElement-partial
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 aae0b3cd9d5..7006760ee15 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
@@ -189,6 +189,47 @@ const HeapVector<Member<Element>> HTMLSlotElement::AssignedElementsForBinding(
return elements;
}
+bool HTMLSlotElement::IsAssignedNodeSameWithBefore(
+ HeapVector<Member<Node>>& new_assigned_nodes,
+ HeapHashSet<Member<Node>>& old_assigned_nodes) {
+ if (new_assigned_nodes.size() != old_assigned_nodes.size())
+ return false;
+ for (auto node : old_assigned_nodes) {
+ if (!new_assigned_nodes.Contains(*node))
+ return false;
+ }
+ return true;
+}
+
+void HTMLSlotElement::assign(HeapVector<Member<Node>> nodes) {
+ if (ContainingShadowRoot()) {
+ SlotChangeType slot_change_type =
+ IsAssignedNodeSameWithBefore(nodes, assigned_nodes_candidates_)
+ ? SlotChangeType::kSuppressSlotChangeEvent
+ : SlotChangeType::kSignalSlotChangeEvent;
+ DidSlotChange(slot_change_type);
+ }
+ assigned_nodes_candidates_.clear();
+ for (Member<Node> child : nodes) {
+ assigned_nodes_candidates_.insert(child);
+ }
+ if (ContainingShadowRoot()) {
+ ContainingShadowRoot()->GetSlotAssignment().CallSlotChangeIfNeeded(*this);
+ // TODO(crbug.com/869308): Don't call SetNeedsAssignmentRecalc if we can
+ // detect all possible slotchange surely
+ ContainingShadowRoot()->GetSlotAssignment().SetNeedsAssignmentRecalc();
+ }
+}
+
+bool HTMLSlotElement::ContainsInAssignedNodesCandidates(
+ Node& host_child) const {
+ return assigned_nodes_candidates_.Contains(&host_child);
+}
+
+void HTMLSlotElement::SignalSlotChange() {
+ DidSlotChange(SlotChangeType::kSignalSlotChangeEvent);
+}
+
const HeapVector<Member<Node>>& HTMLSlotElement::GetDistributedNodes() {
DCHECK(!RuntimeEnabledFeatures::IncrementalShadowDOMEnabled());
DCHECK(!NeedsDistributionRecalc());
@@ -231,7 +272,6 @@ void HTMLSlotElement::AppendDistributedNodesFrom(const HTMLSlotElement& other) {
for (const auto& node : other.distributed_nodes_)
distributed_indices_.Set(node.Get(), index++);
}
-
void HTMLSlotElement::ClearAssignedNodes() {
DCHECK(RuntimeEnabledFeatures::IncrementalShadowDOMEnabled());
assigned_nodes_.clear();
@@ -278,7 +318,7 @@ void HTMLSlotElement::DispatchSlotChangeEvent() {
DCHECK(!IsInUserAgentShadowRoot());
Event* event = Event::CreateBubble(EventTypeNames::slotchange);
event->SetTarget(this);
- DispatchScopedEvent(event);
+ DispatchScopedEvent(*event);
}
Node* HTMLSlotElement::AssignedNodeNextTo(const Node& node) const {
@@ -357,17 +397,12 @@ void HTMLSlotElement::AttachLayoutTree(AttachContext& context) {
// of IncementalShadowDOM.
const HeapVector<Member<Node>>&
HTMLSlotElement::ChildrenInFlatTreeIfAssignmentIsSupported() {
- if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
- return AssignedNodes();
- DCHECK(!NeedsDistributionRecalc());
- return distributed_nodes_;
+ return AssignedNodes();
}
void HTMLSlotElement::DetachLayoutTree(const AttachContext& context) {
if (SupportsAssignment()) {
- const HeapVector<Member<Node>>& flat_tree_children =
- RuntimeEnabledFeatures::SlotInFlatTreeEnabled() ? assigned_nodes_
- : distributed_nodes_;
+ const HeapVector<Member<Node>>& flat_tree_children = assigned_nodes_;
for (auto& node : flat_tree_children)
node->LazyReattachIfAttached();
}
@@ -404,17 +439,17 @@ void HTMLSlotElement::AttributeChanged(
}
Node::InsertionNotificationRequest HTMLSlotElement::InsertedInto(
- ContainerNode* insertion_point) {
+ ContainerNode& insertion_point) {
HTMLElement::InsertedInto(insertion_point);
if (SupportsAssignment()) {
ShadowRoot* root = ContainingShadowRoot();
DCHECK(root);
DCHECK(root->IsV1());
- if (root == insertion_point->ContainingShadowRoot()) {
+ if (root == insertion_point.ContainingShadowRoot()) {
// This slot is inserted into the same tree of |insertion_point|
root->DidAddSlot(*this);
} else if (RuntimeEnabledFeatures::IncrementalShadowDOMEnabled() &&
- insertion_point->isConnected() &&
+ insertion_point.isConnected() &&
root->NeedsSlotAssignmentRecalc()) {
// Even when a slot and its containing shadow root is removed together
// and inserted together again, the slot's cached assigned nodes can be
@@ -429,7 +464,7 @@ Node::InsertionNotificationRequest HTMLSlotElement::InsertedInto(
return kInsertionDone;
}
-void HTMLSlotElement::RemovedFrom(ContainerNode* insertion_point) {
+void HTMLSlotElement::RemovedFrom(ContainerNode& insertion_point) {
// `removedFrom` is called after the node is removed from the tree.
// That means:
// 1. If this slot is still in a tree scope, it means the slot has been in a
@@ -472,11 +507,11 @@ void HTMLSlotElement::RemovedFrom(ContainerNode* insertion_point) {
} else {
ClearDistribution();
}
- } else if (insertion_point->IsInV1ShadowTree()) {
+ } else if (insertion_point.IsInV1ShadowTree()) {
// This slot was in a shadow tree and got disconnected from the shadow tree.
// In the above example, (this slot == s1), (insertion point == d)
// and (insertion_point->ContainingShadowRoot == sr1).
- insertion_point->ContainingShadowRoot()->GetSlotAssignment().DidRemoveSlot(
+ insertion_point.ContainingShadowRoot()->GetSlotAssignment().DidRemoveSlot(
*this);
if (RuntimeEnabledFeatures::IncrementalShadowDOMEnabled()) {
ClearAssignedNodesAndFlatTreeChildren();
@@ -490,28 +525,13 @@ void HTMLSlotElement::RemovedFrom(ContainerNode* insertion_point) {
HTMLElement::RemovedFrom(insertion_point);
}
-void HTMLSlotElement::WillRecalcStyle(StyleRecalcChange change) {
- if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
- return;
- if (change < kIndependentInherit &&
- GetStyleChangeType() < kSubtreeStyleChange) {
- return;
- }
- for (auto& node : distributed_nodes_) {
- node->SetNeedsStyleRecalc(
- kLocalStyleChange,
- StyleChangeReasonForTracing::Create(
- StyleChangeReason::kPropagateInheritChangeToDistributedNodes));
- }
-}
void HTMLSlotElement::DidRecalcStyle(StyleRecalcChange change) {
- if (!RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
- return;
if (change < kIndependentInherit)
return;
for (auto& node : assigned_nodes_) {
if (change == kReattach && node->IsElementNode()) {
+ DCHECK(node->ShouldCallRecalcStyle(kReattach));
ToElement(node)->RecalcStyle(kReattach);
continue;
}
@@ -713,6 +733,7 @@ void HTMLSlotElement::Trace(blink::Visitor* visitor) {
visitor->Trace(distributed_nodes_);
visitor->Trace(old_distributed_nodes_);
visitor->Trace(distributed_indices_);
+ visitor->Trace(assigned_nodes_candidates_);
HTMLElement::Trace(visitor);
}
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 e9a7f683a4b..f3540f7bdda 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
@@ -53,6 +53,13 @@ class CORE_EXPORT HTMLSlotElement final : public HTMLElement {
const HeapVector<Member<Element>> AssignedElementsForBinding(
const AssignedNodesOptions&);
+ bool IsAssignedNodeSameWithBefore(
+ HeapVector<Member<Node>>& new_assigned_nodes,
+ HeapHashSet<Member<Node>>& old_assigned_nodes);
+ void assign(HeapVector<Member<Node>> nodes);
+ bool ContainsInAssignedNodesCandidates(Node&) const;
+ void SignalSlotChange();
+
const HeapVector<Member<Node>> FlattenedAssignedNodes();
Node* FirstAssignedNode() const {
@@ -134,9 +141,8 @@ class CORE_EXPORT HTMLSlotElement final : public HTMLElement {
private:
HTMLSlotElement(Document&);
- InsertionNotificationRequest InsertedInto(ContainerNode*) final;
- void RemovedFrom(ContainerNode*) final;
- void WillRecalcStyle(StyleRecalcChange) final;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) final;
+ void RemovedFrom(ContainerNode&) final;
void DidRecalcStyle(StyleRecalcChange) final;
void EnqueueSlotChangeEvent();
@@ -162,6 +168,8 @@ class CORE_EXPORT HTMLSlotElement final : public HTMLElement {
HeapVector<Member<Node>> assigned_nodes_;
bool slotchange_event_enqueued_ = false;
+ HeapHashSet<Member<Node>> assigned_nodes_candidates_;
+
// For IncrementalShadowDOM
HeapVector<Member<Node>> flat_tree_children_;
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 64a2ea54095..b490cd4252e 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
@@ -30,4 +30,5 @@ interface HTMLSlotElement : HTMLElement {
[CEReactions, Reflect] attribute DOMString name;
[ImplementedAs=AssignedNodesForBinding] sequence<Node> assignedNodes(optional AssignedNodesOptions options);
[ImplementedAs=AssignedElementsForBinding] sequence<Elements> assignedElements(optional AssignedNodesOptions options);
+ [RuntimeEnabled=ManualSlotting] void assign(sequence<Node> nodes);
};
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 ff13fd9afea..f46ad2de65c 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
@@ -89,7 +89,7 @@ void HTMLSourceElement::DidMoveToNewDocument(Document& old_document) {
}
Node::InsertionNotificationRequest HTMLSourceElement::InsertedInto(
- ContainerNode* insertion_point) {
+ ContainerNode& insertion_point) {
HTMLElement::InsertedInto(insertion_point);
Element* parent = parentElement();
if (auto* media = ToHTMLMediaElementOrNull(parent))
@@ -99,10 +99,10 @@ Node::InsertionNotificationRequest HTMLSourceElement::InsertedInto(
return kInsertionDone;
}
-void HTMLSourceElement::RemovedFrom(ContainerNode* removal_root) {
+void HTMLSourceElement::RemovedFrom(ContainerNode& removal_root) {
Element* parent = parentElement();
- if (!parent && removal_root->IsElementNode())
- parent = ToElement(removal_root);
+ if (!parent && removal_root.IsElementNode())
+ parent = ToElement(&removal_root);
if (auto* media = ToHTMLMediaElementOrNull(parent))
media->SourceWasRemoved(this);
if (auto* picture = ToHTMLPictureElementOrNull(parent)) {
@@ -155,7 +155,7 @@ void HTMLSourceElement::CancelPendingErrorEvent() {
void HTMLSourceElement::DispatchPendingEvent() {
DVLOG(SOURCE_LOG_LEVEL) << "dispatchPendingEvent - " << (void*)this;
- DispatchEvent(Event::CreateCancelable(EventTypeNames::error));
+ DispatchEvent(*Event::CreateCancelable(EventTypeNames::error));
}
bool HTMLSourceElement::MediaQueryMatches() const {
diff --git a/chromium/third_party/blink/renderer/core/html/html_source_element.h b/chromium/third_party/blink/renderer/core/html/html_source_element.h
index 5d6fe8c704d..e60012d84e9 100644
--- a/chromium/third_party/blink/renderer/core/html/html_source_element.h
+++ b/chromium/third_party/blink/renderer/core/html/html_source_element.h
@@ -66,8 +66,8 @@ class HTMLSourceElement final : public HTMLElement {
void DidMoveToNewDocument(Document& old_document) override;
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
- void RemovedFrom(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
+ void RemovedFrom(ContainerNode&) override;
bool IsURLAttribute(const Attribute&) const override;
void ParseAttribute(const AttributeModificationParams&) override;
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 9822de60262..2e216d1783a 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
@@ -75,7 +75,7 @@ void HTMLStyleElement::FinishParsingChildren() {
}
Node::InsertionNotificationRequest HTMLStyleElement::InsertedInto(
- ContainerNode* insertion_point) {
+ ContainerNode& insertion_point) {
HTMLElement::InsertedInto(insertion_point);
if (isConnected()) {
if (StyleElement::ProcessStyleSheet(GetDocument(), *this) ==
@@ -87,9 +87,9 @@ Node::InsertionNotificationRequest HTMLStyleElement::InsertedInto(
return kInsertionDone;
}
-void HTMLStyleElement::RemovedFrom(ContainerNode* insertion_point) {
+void HTMLStyleElement::RemovedFrom(ContainerNode& insertion_point) {
HTMLElement::RemovedFrom(insertion_point);
- StyleElement::RemovedFrom(*this, insertion_point);
+ StyleElement::RemovedFrom(*this, &insertion_point);
}
void HTMLStyleElement::ChildrenChanged(const ChildrenChange& change) {
@@ -113,9 +113,9 @@ void HTMLStyleElement::DispatchPendingEvent(
if (loaded_sheet_) {
if (GetDocument().HasListenerType(
Document::kLoadListenerAtCapturePhaseOrAtStyleElement))
- DispatchEvent(Event::Create(EventTypeNames::load));
+ DispatchEvent(*Event::Create(EventTypeNames::load));
} else {
- DispatchEvent(Event::Create(EventTypeNames::error));
+ DispatchEvent(*Event::Create(EventTypeNames::error));
}
// Checks Document's load event synchronously here for performance.
// This is safe because dispatchPendingEvent() is called asynchronously.
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 c8b672683f3..151ba08bebf 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
@@ -55,8 +55,8 @@ class CORE_EXPORT HTMLStyleElement final : public HTMLElement,
// overload from HTMLElement
void ParseAttribute(const AttributeModificationParams&) override;
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
- void RemovedFrom(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
+ void RemovedFrom(ContainerNode&) override;
void ChildrenChanged(const ChildrenChange&) override;
void FinishParsingChildren() override;
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 0a7063bb35f..751682d9b77 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
@@ -101,40 +101,40 @@ bool HTMLSummaryElement::SupportsFocus() const {
return IsMainSummary() || HTMLElement::SupportsFocus();
}
-void HTMLSummaryElement::DefaultEventHandler(Event* event) {
+void HTMLSummaryElement::DefaultEventHandler(Event& event) {
if (IsMainSummary()) {
- if (event->type() == EventTypeNames::DOMActivate &&
- !IsClickableControl(event->target()->ToNode())) {
+ if (event.type() == EventTypeNames::DOMActivate &&
+ !IsClickableControl(event.target()->ToNode())) {
if (HTMLDetailsElement* details = DetailsElement())
details->ToggleOpen();
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
return;
}
- if (event->IsKeyboardEvent()) {
- if (event->type() == EventTypeNames::keydown &&
- ToKeyboardEvent(event)->key() == " ") {
+ if (event.IsKeyboardEvent()) {
+ if (event.type() == EventTypeNames::keydown &&
+ ToKeyboardEvent(event).key() == " ") {
SetActive(true);
// No setDefaultHandled() - IE dispatches a keypress in this case.
return;
}
- if (event->type() == EventTypeNames::keypress) {
- switch (ToKeyboardEvent(event)->charCode()) {
+ if (event.type() == EventTypeNames::keypress) {
+ switch (ToKeyboardEvent(event).charCode()) {
case '\r':
- DispatchSimulatedClick(event);
- event->SetDefaultHandled();
+ DispatchSimulatedClick(&event);
+ event.SetDefaultHandled();
return;
case ' ':
// Prevent scrolling down the page.
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
return;
}
}
- if (event->type() == EventTypeNames::keyup &&
- ToKeyboardEvent(event)->key() == " ") {
+ if (event.type() == EventTypeNames::keyup &&
+ ToKeyboardEvent(event).key() == " ") {
if (IsActive())
- DispatchSimulatedClick(event);
- event->SetDefaultHandled();
+ DispatchSimulatedClick(&event);
+ event.SetDefaultHandled();
return;
}
}
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 081f9b0909f..4641a8d1222 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
@@ -39,7 +39,7 @@ class HTMLSummaryElement final : public HTMLElement {
explicit HTMLSummaryElement(Document&);
LayoutObject* CreateLayoutObject(const ComputedStyle&) override;
- void DefaultEventHandler(Event*) override;
+ void DefaultEventHandler(Event&) override;
bool HasActivationBehavior() const override;
void DidAddUserAgentShadowRoot(ShadowRoot&) override;
HTMLDetailsElement* DetailsElement() 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 8dadbe241bb..c94a0b9d510 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
@@ -358,6 +358,11 @@
name: "plaintext",
interfaceName: "HTMLElement",
},
+ {
+ name: "portal",
+ interfaceName: "HTMLPortalElement",
+ interfaceHeaderDir: "third_party/blink/renderer/core/html/portal",
+ },
"pre",
{
name: "progress",
diff --git a/chromium/third_party/blink/renderer/core/html/html_title_element.cc b/chromium/third_party/blink/renderer/core/html/html_title_element.cc
index e2bfb87b6f1..7118b49f116 100644
--- a/chromium/third_party/blink/renderer/core/html/html_title_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_title_element.cc
@@ -41,16 +41,16 @@ inline HTMLTitleElement::HTMLTitleElement(Document& document)
DEFINE_NODE_FACTORY(HTMLTitleElement)
Node::InsertionNotificationRequest HTMLTitleElement::InsertedInto(
- ContainerNode* insertion_point) {
+ ContainerNode& insertion_point) {
HTMLElement::InsertedInto(insertion_point);
if (IsInDocumentTree())
GetDocument().SetTitleElement(this);
return kInsertionDone;
}
-void HTMLTitleElement::RemovedFrom(ContainerNode* insertion_point) {
+void HTMLTitleElement::RemovedFrom(ContainerNode& insertion_point) {
HTMLElement::RemovedFrom(insertion_point);
- if (insertion_point->IsInDocumentTree())
+ if (insertion_point.IsInDocumentTree())
GetDocument().RemoveTitle(this);
}
diff --git a/chromium/third_party/blink/renderer/core/html/html_title_element.h b/chromium/third_party/blink/renderer/core/html/html_title_element.h
index 7bd56a89cc2..9089c14b325 100644
--- a/chromium/third_party/blink/renderer/core/html/html_title_element.h
+++ b/chromium/third_party/blink/renderer/core/html/html_title_element.h
@@ -38,8 +38,8 @@ class HTMLTitleElement final : public HTMLElement {
private:
explicit HTMLTitleElement(Document&);
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
- void RemovedFrom(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
+ void RemovedFrom(ContainerNode&) override;
void ChildrenChanged(const ChildrenChange&) override;
bool ignore_title_updates_when_children_change_;
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 746d734590f..2bde271b936 100644
--- a/chromium/third_party/blink/renderer/core/html/image_document.cc
+++ b/chromium/third_party/blink/renderer/core/html/image_document.cc
@@ -49,10 +49,10 @@
#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/resource/image_resource.h"
+#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
-#include "third_party/blink/renderer/platform/platform_chrome_client.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
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 97a78a6a961..4a293f76f32 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
@@ -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/dom/document_parser.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/frame/visual_viewport.h"
#include "third_party/blink/renderer/core/geometry/dom_rect.h"
@@ -105,7 +106,8 @@ void ImageDocumentTest::CreateDocumentWithoutLoadingImage(int view_width,
LocalFrame& frame = dummy_page_holder_->GetFrame();
frame.GetDocument()->Shutdown();
- DocumentInit init = DocumentInit::Create().WithFrame(&frame);
+ DocumentInit init = DocumentInit::Create().WithDocumentLoader(
+ frame.Loader().GetDocumentLoader());
frame.DomWindow()->InstallNewDocument("image/jpeg", init, false);
}
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 8320510afaa..6cb6d5635ab 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
@@ -33,8 +33,6 @@
#include "third_party/blink/renderer/core/css/style_engine.h"
#include "third_party/blink/renderer/core/css/style_sheet_list.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/use_counter.h"
#include "third_party/blink/renderer/core/html/custom/v0_custom_element.h"
#include "third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_import_step.h"
#include "third_party/blink/renderer/core/html/custom/v0_custom_element_sync_microtask_queue.h"
@@ -81,10 +79,6 @@ void HTMLImportChild::DidFinish() {
void HTMLImportChild::DidFinishLoading() {
StateWillChange();
- if (GetDocument() && GetDocument()->GetStyleEngine().HasStyleSheets()) {
- Deprecation::CountDeprecation(Root()->GetDocument(),
- WebFeature::kHTMLImportsHasStyleSheets);
- }
V0CustomElement::DidFinishLoadingImport(*(Root()->GetDocument()));
}
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 b609bfc96fd..76282a097ea 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
@@ -41,14 +41,19 @@
namespace blink {
HTMLImportsController::HTMLImportsController(Document& master)
- : root_(HTMLImportTreeRoot::Create(&master)) {
- UseCounter::Count(master, WebFeature::kHTMLImports);
-}
+ : root_(HTMLImportTreeRoot::Create(&master)) {}
void HTMLImportsController::Dispose() {
- for (const auto& loader : loaders_)
- loader->Dispose();
- loaders_.clear();
+ // TODO(tkent): We copy loaders_ before iteration to avoid crashes.
+ // This copy should be unnecessary. loaders_ is not modified during
+ // the iteration. Also, null-check for |loader| should be
+ // unnecessary. crbug.com/843151.
+ LoaderList list;
+ list.swap(loaders_);
+ for (const auto& loader : list) {
+ if (loader)
+ loader->Dispose();
+ }
if (root_) {
root_->Dispose();
diff --git a/chromium/third_party/blink/renderer/core/html/imports/link_import.cc b/chromium/third_party/blink/renderer/core/html/imports/link_import.cc
index ac02520f1b8..9f7cfcb5f89 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
@@ -80,10 +80,7 @@ void LinkImport::Process() {
ResourceRequest resource_request(GetDocument().CompleteURL(url));
ReferrerPolicy referrer_policy = owner_->GetReferrerPolicy();
- if (referrer_policy != kReferrerPolicyDefault) {
- resource_request.SetHTTPReferrer(SecurityPolicy::GenerateReferrer(
- referrer_policy, url, GetDocument().OutgoingReferrer()));
- }
+ resource_request.SetReferrerPolicy(referrer_policy);
ResourceLoaderOptions options;
options.initiator_info.name = owner_->localName();
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 4c4f9b2a756..4da61acd407 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
@@ -9,6 +9,7 @@
#include "base/metrics/histogram_macros.h"
#include "third_party/blink/public/platform/web_effective_connection_type.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/frame/frame.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_client.h"
@@ -19,6 +20,7 @@
#include "third_party/blink/renderer/core/intersection_observer/intersection_observer_entry.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/style/computed_style.h"
#include "third_party/blink/renderer/platform/heap/visitor.h"
#include "third_party/blink/renderer/platform/length.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_request.h"
@@ -36,7 +38,8 @@ namespace {
// could break their functionality, so these heuristics are used to recognize
// likely hidden frames and immediately load them so that they can function
// properly.
-bool IsFrameProbablyHidden(const DOMRectReadOnly& bounding_client_rect) {
+bool IsFrameProbablyHidden(const DOMRectReadOnly& bounding_client_rect,
+ const Element& element) {
// Tiny frames that are 4x4 or smaller are likely not intended to be seen by
// the user. Note that this condition includes frames marked as
// "display:none", since those frames would have dimensions of 0x0.
@@ -48,6 +51,17 @@ bool IsFrameProbablyHidden(const DOMRectReadOnly& bounding_client_rect) {
if (bounding_client_rect.right() < 0.0 || bounding_client_rect.bottom() < 0.0)
return true;
+ const ComputedStyle* style = element.GetComputedStyle();
+ if (style) {
+ switch (style->Visibility()) {
+ case EVisibility::kHidden:
+ case EVisibility::kCollapse:
+ return true;
+ case EVisibility::kVisible:
+ break;
+ }
+ }
+
return false;
}
@@ -77,13 +91,28 @@ int GetLazyFrameLoadingViewportDistanceThresholdPx(const Document& document) {
} // namespace
+struct LazyLoadFrameObserver::LazyLoadRequestInfo {
+ LazyLoadRequestInfo(const ResourceRequest& resource_request,
+ WebFrameLoadType frame_load_type)
+ : resource_request(resource_request), frame_load_type(frame_load_type) {}
+
+ const ResourceRequest resource_request;
+ const WebFrameLoadType frame_load_type;
+};
+
LazyLoadFrameObserver::LazyLoadFrameObserver(HTMLFrameOwnerElement& element)
: element_(&element) {}
+LazyLoadFrameObserver::~LazyLoadFrameObserver() = default;
+
void LazyLoadFrameObserver::DeferLoadUntilNearViewport(
const ResourceRequest& resource_request,
WebFrameLoadType frame_load_type) {
DCHECK(!lazy_load_intersection_observer_);
+ DCHECK(!lazy_load_request_info_);
+ lazy_load_request_info_ =
+ std::make_unique<LazyLoadRequestInfo>(resource_request, frame_load_type);
+
was_recorded_as_deferred_ = false;
lazy_load_intersection_observer_ = IntersectionObserver::Create(
@@ -92,13 +121,14 @@ void LazyLoadFrameObserver::DeferLoadUntilNearViewport(
kFixed)},
{std::numeric_limits<float>::min()}, &element_->GetDocument(),
WTF::BindRepeating(&LazyLoadFrameObserver::LoadIfHiddenOrNearViewport,
- WrapWeakPersistent(this), resource_request,
- frame_load_type));
+ WrapWeakPersistent(this)));
lazy_load_intersection_observer_->observe(element_);
}
void LazyLoadFrameObserver::CancelPendingLazyLoad() {
+ lazy_load_request_info_.reset();
+
if (!lazy_load_intersection_observer_)
return;
lazy_load_intersection_observer_->disconnect();
@@ -106,8 +136,6 @@ void LazyLoadFrameObserver::CancelPendingLazyLoad() {
}
void LazyLoadFrameObserver::LoadIfHiddenOrNearViewport(
- const ResourceRequest& resource_request,
- WebFrameLoadType frame_load_type,
const HeapVector<Member<IntersectionObserverEntry>>& entries) {
DCHECK(!entries.IsEmpty());
DCHECK_EQ(element_, entries.back()->target());
@@ -115,13 +143,21 @@ void LazyLoadFrameObserver::LoadIfHiddenOrNearViewport(
if (entries.back()->isIntersecting()) {
RecordInitialDeferralAction(
FrameInitialDeferralAction::kLoadedNearOrInViewport);
- } else if (IsFrameProbablyHidden(*entries.back()->boundingClientRect())) {
+ } else if (IsFrameProbablyHidden(*entries.back()->boundingClientRect(),
+ *element_)) {
RecordInitialDeferralAction(FrameInitialDeferralAction::kLoadedHidden);
} else {
RecordInitialDeferralAction(FrameInitialDeferralAction::kDeferred);
return;
}
+ LoadImmediately();
+}
+
+void LazyLoadFrameObserver::LoadImmediately() {
+ DCHECK(IsLazyLoadPending());
+ DCHECK(lazy_load_request_info_);
+
if (was_recorded_as_deferred_) {
DCHECK(element_->GetDocument().GetFrame());
DCHECK(element_->GetDocument().GetFrame()->Client());
@@ -134,18 +170,23 @@ void LazyLoadFrameObserver::LoadIfHiddenOrNearViewport(
->GetEffectiveConnectionType());
}
+ std::unique_ptr<LazyLoadRequestInfo> scoped_request_info =
+ std::move(lazy_load_request_info_);
+
// The content frame of the element should not have changed, since any
// pending lazy load should have been already been cancelled in
// DisconnectContentFrame() if the content frame changes.
DCHECK(element_->ContentFrame());
- // Note that calling FrameLoader::Load() causes the
- // |lazy_load_intersection_observer| to be disconnected.
+ // Note that calling FrameLoader::StartNavigation() causes the
+ // |lazy_load_intersection_observer_| to be disconnected.
ToLocalFrame(element_->ContentFrame())
->Loader()
- .StartNavigation(
- FrameLoadRequest(&element_->GetDocument(), resource_request),
- frame_load_type);
+ .StartNavigation(FrameLoadRequest(&element_->GetDocument(),
+ scoped_request_info->resource_request),
+ scoped_request_info->frame_load_type);
+
+ DCHECK(!IsLazyLoadPending());
}
void LazyLoadFrameObserver::StartTrackingVisibilityMetrics() {
@@ -166,7 +207,7 @@ void LazyLoadFrameObserver::RecordMetricsOnVisibilityChanged(
DCHECK(!entries.IsEmpty());
DCHECK_EQ(element_, entries.back()->target());
- if (IsFrameProbablyHidden(*entries.back()->boundingClientRect())) {
+ if (IsFrameProbablyHidden(*entries.back()->boundingClientRect(), *element_)) {
visibility_metrics_observer_->disconnect();
visibility_metrics_observer_.Clear();
return;
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 248e38f1cfe..5864e31a98c 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
@@ -5,6 +5,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_LAZY_LOAD_FRAME_OBSERVER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_LAZY_LOAD_FRAME_OBSERVER_H_
+#include <memory>
+
#include "third_party/blink/public/web/web_frame_load_type.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
@@ -19,7 +21,8 @@ class HTMLFrameOwnerElement;
class ResourceRequest;
class Visitor;
-class LazyLoadFrameObserver : public GarbageCollected<LazyLoadFrameObserver> {
+class LazyLoadFrameObserver
+ : public GarbageCollectedFinalized<LazyLoadFrameObserver> {
public:
// This enum is logged to histograms, so values should not be reordered or
// reused, and it must match the corresponding enum
@@ -40,6 +43,7 @@ class LazyLoadFrameObserver : public GarbageCollected<LazyLoadFrameObserver> {
};
explicit LazyLoadFrameObserver(HTMLFrameOwnerElement&);
+ ~LazyLoadFrameObserver();
void DeferLoadUntilNearViewport(const ResourceRequest&, WebFrameLoadType);
bool IsLazyLoadPending() const { return lazy_load_intersection_observer_; }
@@ -48,12 +52,14 @@ class LazyLoadFrameObserver : public GarbageCollected<LazyLoadFrameObserver> {
void StartTrackingVisibilityMetrics();
void RecordMetricsOnLoadFinished();
+ void LoadImmediately();
+
void Trace(blink::Visitor*);
private:
+ struct LazyLoadRequestInfo;
+
void LoadIfHiddenOrNearViewport(
- const ResourceRequest&,
- WebFrameLoadType,
const HeapVector<Member<IntersectionObserverEntry>>&);
void RecordMetricsOnVisibilityChanged(
@@ -68,6 +74,10 @@ class LazyLoadFrameObserver : public GarbageCollected<LazyLoadFrameObserver> {
// the viewport.
Member<IntersectionObserver> lazy_load_intersection_observer_;
+ // Keeps track of the resource request and other info needed to load in the
+ // deferred frame. This is only non-null if there's a lazy load pending.
+ std::unique_ptr<LazyLoadRequestInfo> lazy_load_request_info_;
+
// Used to record visibility-related metrics related to lazy load. This is an
// IntersectionObserver instead of just an ElementVisibilityObserver so that
// hidden frames can be detected in order to avoid recording metrics for them.
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 f987c930f60..566013294d4 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
@@ -8,10 +8,13 @@
#include <memory>
#include <tuple>
+#include "base/optional.h"
#include "third_party/blink/public/platform/web_effective_connection_type.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/settings.h"
+#include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
#include "third_party/blink/renderer/core/testing/sim/sim_compositor.h"
#include "third_party/blink/renderer/core/testing/sim/sim_request.h"
@@ -391,6 +394,8 @@ TEST_P(LazyLoadFramesTest, HiddenAndTinyFrames) {
SimRequest display_none_frame_resource(
"https://crossorigin.com/display_none.html", "text/html");
+ SimRequest visibility_hidden_frame_resource(
+ "https://crossorigin.com/visibility_hidden.html", "text/html");
SimRequest tiny_frame_resource("https://crossorigin.com/tiny.html",
"text/html");
SimRequest tiny_width_frame_resource(
@@ -419,6 +424,9 @@ TEST_P(LazyLoadFramesTest, HiddenAndTinyFrames) {
<iframe src='https://crossorigin.com/display_none.html'
style='display: none;'
onload='console.log("display none element onload");'></iframe>
+ <iframe src='https://crossorigin.com/visibility_hidden.html'
+ style='visibility:hidden;width:100px;height:100px;'
+ onload='console.log("visibility hidden element onload");'></iframe>
<iframe src='https://crossorigin.com/tiny.html'
style='width: 4px; height: 4px;'
onload='console.log("tiny element onload");'></iframe>
@@ -442,6 +450,7 @@ TEST_P(LazyLoadFramesTest, HiddenAndTinyFrames) {
test::RunPendingTasks();
display_none_frame_resource.Complete("");
+ visibility_hidden_frame_resource.Complete("");
tiny_frame_resource.Complete("");
tiny_width_frame_resource.Complete("");
tiny_height_frame_resource.Complete("");
@@ -453,6 +462,7 @@ TEST_P(LazyLoadFramesTest, HiddenAndTinyFrames) {
EXPECT_TRUE(ConsoleMessages().Contains("main body onload"));
EXPECT_TRUE(ConsoleMessages().Contains("display none element onload"));
+ EXPECT_TRUE(ConsoleMessages().Contains("visibility hidden element onload"));
EXPECT_TRUE(ConsoleMessages().Contains("tiny element onload"));
EXPECT_TRUE(ConsoleMessages().Contains("tiny width element onload"));
EXPECT_TRUE(ConsoleMessages().Contains("tiny height element onload"));
@@ -475,7 +485,7 @@ TEST_P(LazyLoadFramesTest, HiddenAndTinyFrames) {
"Blink.VisibleBeforeLoaded.LazyLoadEligibleFrames.BelowTheFold", 0);
ExpectInitialDeferralActionHistogramSamplesIfApplicable(
- LazyLoadFrameObserver::FrameInitialDeferralAction::kLoadedHidden, 6);
+ LazyLoadFrameObserver::FrameInitialDeferralAction::kLoadedHidden, 7);
histogram_tester()->ExpectTotalCount(
"Blink.LazyLoad.CrossOriginFrames.LoadStartedAfterBeingDeferred", 0);
histogram_tester()->ExpectTotalCount(
@@ -719,6 +729,353 @@ TEST_P(LazyLoadFramesTest, JavascriptStringFrameUrl) {
"Blink.LazyLoad.CrossOriginFrames.VisibleAfterBeingDeferred", 0);
}
+TEST_P(LazyLoadFramesTest, CrossOriginFrameFarFromViewportWithLazyLoadAttrOff) {
+ SimRequest main_resource("https://example.com/", "text/html");
+ SimRequest child_frame_resource("https://crossorigin.com/subframe.html",
+ "text/html");
+
+ LoadURL("https://example.com/");
+
+ main_resource.Complete(String::Format(
+ R"HTML(
+ <body onload='console.log("main body onload");'>
+ <div style='height: %dpx;'></div>
+ <iframe src='https://crossorigin.com/subframe.html'
+ style='width: 200px; height: 200px;' lazyload='off'
+ onload='console.log("child frame element onload");'></iframe>
+ </body>)HTML",
+ kViewportHeight + GetLoadingDistanceThreshold() + 100));
+
+ Compositor().BeginFrame();
+ test::RunPendingTasks();
+
+ child_frame_resource.Complete("");
+
+ Compositor().BeginFrame();
+ test::RunPendingTasks();
+
+ EXPECT_TRUE(ConsoleMessages().Contains("main body onload"));
+ EXPECT_TRUE(ConsoleMessages().Contains("child frame element onload"));
+
+ ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 0);
+ histogram_tester()->ExpectTotalCount(
+ "Blink.VisibleBeforeLoaded.LazyLoadEligibleFrames.BelowTheFold", 0);
+
+ for (const auto& pair : kInitialDeferralActionHistogramNames)
+ histogram_tester()->ExpectTotalCount(pair.second, 0);
+ histogram_tester()->ExpectTotalCount(
+ "Blink.LazyLoad.CrossOriginFrames.LoadStartedAfterBeingDeferred", 0);
+ histogram_tester()->ExpectTotalCount(
+ "Blink.LazyLoad.CrossOriginFrames.VisibleAfterBeingDeferred", 0);
+}
+
+TEST_P(LazyLoadFramesTest,
+ LoadSameOriginFrameFarFromViewportWithLazyLoadAttributeOn) {
+ SimRequest main_resource("https://example.com/", "text/html");
+ base::Optional<SimRequest> child_frame_resource;
+
+ if (!RuntimeEnabledFeatures::LazyFrameLoadingEnabled()) {
+ // This SimRequest needs to be created now if the frame won't actually be
+ // lazily loaded. Otherwise, it'll be defined later to ensure that the
+ // subframe resource isn't requested until the page is scrolled down.
+ child_frame_resource.emplace("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");'>
+ <div style='height: %dpx;'></div>
+ <iframe src='https://example.com/subframe.html'
+ style='width: 400px; height: 400px;' lazyload='on'
+ onload='console.log("child frame element onload");'></iframe>
+ </body>)HTML",
+ kViewportHeight + GetLoadingDistanceThreshold() + 100));
+
+ Compositor().BeginFrame();
+ test::RunPendingTasks();
+
+ // If the child frame is being lazy loaded, then the body's load event
+ // should have already fired.
+ EXPECT_EQ(RuntimeEnabledFeatures::LazyFrameLoadingEnabled(),
+ ConsoleMessages().Contains("main body onload"));
+ EXPECT_FALSE(ConsoleMessages().Contains("child frame element onload"));
+
+ ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 0);
+
+ ExpectInitialDeferralActionHistogramSamplesIfApplicable(
+ LazyLoadFrameObserver::FrameInitialDeferralAction::kDeferred, 1);
+ histogram_tester()->ExpectTotalCount(
+ "Blink.LazyLoad.CrossOriginFrames.LoadStartedAfterBeingDeferred", 0);
+ histogram_tester()->ExpectTotalCount(
+ "Blink.LazyLoad.CrossOriginFrames.VisibleAfterBeingDeferred", 0);
+
+ if (!child_frame_resource) {
+ child_frame_resource.emplace("https://example.com/subframe.html",
+ "text/html");
+ }
+
+ if (RuntimeEnabledFeatures::LazyFrameLoadingEnabled()) {
+ // 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);
+
+ Compositor().BeginFrame();
+ test::RunPendingTasks();
+ }
+
+ EXPECT_FALSE(ConsoleMessages().Contains("child frame element onload"));
+ ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 0);
+
+ ExpectInitialDeferralActionHistogramSamplesIfApplicable(
+ LazyLoadFrameObserver::FrameInitialDeferralAction::kDeferred, 1);
+ ExpectLoadStartedAfterDeferredSamplesIfApplicable(1);
+ histogram_tester()->ExpectTotalCount(
+ "Blink.LazyLoad.CrossOriginFrames.VisibleAfterBeingDeferred", 0);
+
+ child_frame_resource->Complete("");
+
+ Compositor().BeginFrame();
+ test::RunPendingTasks();
+
+ EXPECT_TRUE(ConsoleMessages().Contains("main body onload"));
+ EXPECT_TRUE(ConsoleMessages().Contains("child frame element onload"));
+ ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 0);
+
+ // Scroll down so that the child frame is visible.
+ GetDocument().View()->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, GetLoadingDistanceThreshold() + 150),
+ kProgrammaticScroll);
+
+ Compositor().BeginFrame();
+ test::RunPendingTasks();
+
+ EXPECT_TRUE(ConsoleMessages().Contains("main body onload"));
+ EXPECT_TRUE(ConsoleMessages().Contains("child frame element onload"));
+ ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 1);
+
+ histogram_tester()->ExpectTotalCount(
+ "Blink.VisibleBeforeLoaded.LazyLoadEligibleFrames.BelowTheFold", 0);
+
+ ExpectInitialDeferralActionHistogramSamplesIfApplicable(
+ LazyLoadFrameObserver::FrameInitialDeferralAction::kDeferred, 1);
+ ExpectLoadStartedAfterDeferredSamplesIfApplicable(1);
+ ExpectVisibleAfterDeferredSamplesIfApplicable(1);
+}
+
+TEST_P(LazyLoadFramesTest,
+ LoadCrossOriginFrameFarFromViewportThenSetLazyLoadAttributeOff) {
+ SimRequest main_resource("https://example.com/", "text/html");
+ base::Optional<SimRequest> child_frame_resource;
+
+ if (!RuntimeEnabledFeatures::LazyFrameLoadingEnabled()) {
+ // This SimRequest needs to be created now if the frame won't actually be
+ // lazily loaded. Otherwise, it'll be defined later to ensure that the
+ // subframe resource isn't requested until the page is scrolled down.
+ child_frame_resource.emplace("https://crossorigin.com/subframe.html",
+ "text/html");
+ }
+
+ LoadURL("https://example.com/");
+
+ main_resource.Complete(String::Format(
+ R"HTML(
+ <body onload='console.log("main body onload");'>
+ <div style='height: %dpx;'></div>
+ <iframe id='child_frame' src='https://crossorigin.com/subframe.html'
+ style='width: 400px; height: 400px;'
+ onload='console.log("child frame element onload");'></iframe>
+ </body>)HTML",
+ kViewportHeight + GetLoadingDistanceThreshold() + 100));
+
+ Compositor().BeginFrame();
+ test::RunPendingTasks();
+
+ // If the child frame is being lazy loaded, then the body's load event
+ // should have already fired.
+ EXPECT_EQ(RuntimeEnabledFeatures::LazyFrameLoadingEnabled(),
+ ConsoleMessages().Contains("main body onload"));
+ EXPECT_FALSE(ConsoleMessages().Contains("child frame element onload"));
+
+ if (!child_frame_resource) {
+ child_frame_resource.emplace("https://crossorigin.com/subframe.html",
+ "text/html");
+ }
+
+ Element* child_frame_element = GetDocument().getElementById("child_frame");
+ ASSERT_TRUE(child_frame_element);
+ child_frame_element->setAttribute(HTMLNames::lazyloadAttr, "off");
+
+ ExpectInitialDeferralActionHistogramSamplesIfApplicable(
+ LazyLoadFrameObserver::FrameInitialDeferralAction::kDeferred, 1);
+ ExpectLoadStartedAfterDeferredSamplesIfApplicable(1);
+ histogram_tester()->ExpectTotalCount(
+ "Blink.LazyLoad.CrossOriginFrames.VisibleAfterBeingDeferred", 0);
+
+ child_frame_resource->Complete("");
+
+ Compositor().BeginFrame();
+ test::RunPendingTasks();
+
+ EXPECT_TRUE(ConsoleMessages().Contains("main body onload"));
+ EXPECT_TRUE(ConsoleMessages().Contains("child frame element onload"));
+
+ ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 0);
+
+ histogram_tester()->ExpectTotalCount(
+ "Blink.VisibleBeforeLoaded.LazyLoadEligibleFrames.BelowTheFold", 0);
+
+ ExpectInitialDeferralActionHistogramSamplesIfApplicable(
+ LazyLoadFrameObserver::FrameInitialDeferralAction::kDeferred, 1);
+ ExpectLoadStartedAfterDeferredSamplesIfApplicable(1);
+ histogram_tester()->ExpectTotalCount(
+ "Blink.LazyLoad.CrossOriginFrames.VisibleAfterBeingDeferred", 0);
+}
+
+TEST_P(LazyLoadFramesTest,
+ NestedFrameWithLazyLoadAttributeOnInFrameWithNoLazyLoadAttribute) {
+ std::unique_ptr<SimRequest> child_frame_resource =
+ LoadPageWithCrossOriginFrameFarFromViewport();
+
+ if (RuntimeEnabledFeatures::LazyFrameLoadingEnabled()) {
+ // 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);
+
+ Compositor().BeginFrame();
+ test::RunPendingTasks();
+ }
+
+ // There's another nested cross origin iframe inside the first child frame,
+ // even further down such that it's not near the viewport. If LazyLoad is
+ // enabled, it should be deferred even though it's nested inside a frame that
+ // was previously deferred, because it has the attribute lazyload=on.
+ base::Optional<SimRequest> nested_frame_resource;
+ if (!RuntimeEnabledFeatures::LazyFrameLoadingEnabled())
+ nested_frame_resource.emplace("https://test.com/", "text/html");
+
+ child_frame_resource->Complete(
+ String::Format("<div style='height: %dpx;'></div>"
+ "<iframe src='https://test.com/' lazyload='on'"
+ " style='width: 200px; height: 200px;'>"
+ "</iframe>",
+ kViewportHeight + GetLoadingDistanceThreshold() + 100));
+
+ Compositor().BeginFrame();
+ test::RunPendingTasks();
+
+ if (!RuntimeEnabledFeatures::LazyFrameLoadingEnabled()) {
+ nested_frame_resource->Complete("");
+
+ Compositor().BeginFrame();
+ test::RunPendingTasks();
+ }
+
+ EXPECT_TRUE(ConsoleMessages().Contains("main body onload"));
+ EXPECT_TRUE(ConsoleMessages().Contains("child frame element onload"));
+}
+
+TEST_P(LazyLoadFramesTest,
+ NestedFrameWithLazyLoadAttributeOnInFrameWithLazyLoadAttributeOff) {
+ SimRequest main_resource("https://example.com/", "text/html");
+ SimRequest child_frame_resource("https://crossorigin.com/subframe.html",
+ "text/html");
+
+ LoadURL("https://example.com/");
+
+ main_resource.Complete(String::Format(
+ R"HTML(
+ <body onload='console.log("main body onload");'>
+ <div style='height: %dpx;'></div>
+ <iframe src='https://crossorigin.com/subframe.html'
+ style='width: 200px; height: 200px;' lazyload='off'
+ onload='console.log("child frame element onload");'></iframe>
+ </body>)HTML",
+ kViewportHeight + GetLoadingDistanceThreshold() + 100));
+
+ Compositor().BeginFrame();
+ test::RunPendingTasks();
+
+ // There's another nested cross origin iframe inside the first child frame,
+ // even further down such that it's not near the viewport. If LazyLoad is
+ // enabled, it should be deferred because it has the attribute lazyload=on,
+ // even though it's nested inside a frame that has the attribute lazyload=off.
+ base::Optional<SimRequest> nested_frame_resource;
+ if (!RuntimeEnabledFeatures::LazyFrameLoadingEnabled())
+ nested_frame_resource.emplace("https://test.com/", "text/html");
+
+ child_frame_resource.Complete(
+ String::Format("<div style='height: %dpx;'></div>"
+ "<iframe src='https://test.com/' lazyload='on'"
+ " style='width: 200px; height: 200px;'>"
+ "</iframe>",
+ kViewportHeight + GetLoadingDistanceThreshold() + 100));
+
+ Compositor().BeginFrame();
+ test::RunPendingTasks();
+
+ if (!RuntimeEnabledFeatures::LazyFrameLoadingEnabled()) {
+ nested_frame_resource->Complete("");
+
+ Compositor().BeginFrame();
+ test::RunPendingTasks();
+ }
+
+ EXPECT_TRUE(ConsoleMessages().Contains("main body onload"));
+ EXPECT_TRUE(ConsoleMessages().Contains("child frame element onload"));
+}
+
+TEST_P(LazyLoadFramesTest,
+ NestedFrameWithLazyLoadAttributeOffInFrameWithLazyLoadAttributeOff) {
+ SimRequest main_resource("https://example.com/", "text/html");
+ SimRequest child_frame_resource("https://crossorigin.com/subframe.html",
+ "text/html");
+
+ LoadURL("https://example.com/");
+
+ main_resource.Complete(String::Format(
+ R"HTML(
+ <body onload='console.log("main body onload");'>
+ <div style='height: %dpx;'></div>
+ <iframe src='https://crossorigin.com/subframe.html'
+ style='width: 200px; height: 200px;' lazyload='off'
+ onload='console.log("child frame element onload");'></iframe>
+ </body>)HTML",
+ kViewportHeight + GetLoadingDistanceThreshold() + 100));
+
+ Compositor().BeginFrame();
+ test::RunPendingTasks();
+
+ // There's another nested cross origin iframe inside the first child frame,
+ // even further down such that it's not near the viewport. Since it has the
+ // attribute lazyload=off, it shouldn't be deferred. Note that this also
+ // matches the default behavior that would happen if the lazyload attribute
+ // was omitted on the nested iframe entirely.
+ SimRequest nested_frame_resource("https://test.com/", "text/html");
+
+ child_frame_resource.Complete(
+ String::Format("<div style='height: %dpx;'></div>"
+ "<iframe src='https://test.com/' lazyload='off'"
+ " style='width: 200px; height: 200px;'>"
+ "</iframe>",
+ kViewportHeight + GetLoadingDistanceThreshold() + 100));
+
+ Compositor().BeginFrame();
+ test::RunPendingTasks();
+
+ nested_frame_resource.Complete("");
+
+ Compositor().BeginFrame();
+ test::RunPendingTasks();
+
+ EXPECT_TRUE(ConsoleMessages().Contains("main body onload"));
+ EXPECT_TRUE(ConsoleMessages().Contains("child frame element onload"));
+}
+
INSTANTIATE_TEST_CASE_P(
LazyFrameLoading,
LazyLoadFramesTest,
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
new file mode 100644
index 00000000000..7681186dd9d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/html/lazy_load_image_observer.cc
@@ -0,0 +1,258 @@
+// 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/html/lazy_load_image_observer.h"
+
+#include <limits>
+
+#include "base/metrics/histogram_macros.h"
+#include "build/build_config.h"
+#include "third_party/blink/public/platform/web_effective_connection_type.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_computed_style.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/html_image_element.h"
+#include "third_party/blink/renderer/core/html_element_type_helpers.h"
+#include "third_party/blink/renderer/core/inspector/console_message.h"
+#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"
+
+namespace blink {
+
+namespace {
+
+int GetLazyImageLoadingViewportDistanceThresholdPx(const Document& document) {
+ const Settings* settings = document.GetSettings();
+ if (!settings)
+ return 0;
+
+ DCHECK(document.GetFrame() && document.GetFrame()->Client());
+ switch (document.GetFrame()->Client()->GetEffectiveConnectionType()) {
+ case WebEffectiveConnectionType::kTypeUnknown:
+ return settings->GetLazyImageLoadingDistanceThresholdPxUnknown();
+ case WebEffectiveConnectionType::kTypeOffline:
+ return settings->GetLazyImageLoadingDistanceThresholdPxOffline();
+ case WebEffectiveConnectionType::kTypeSlow2G:
+ return settings->GetLazyImageLoadingDistanceThresholdPxSlow2G();
+ case WebEffectiveConnectionType::kType2G:
+ return settings->GetLazyImageLoadingDistanceThresholdPx2G();
+ case WebEffectiveConnectionType::kType3G:
+ return settings->GetLazyImageLoadingDistanceThresholdPx3G();
+ case WebEffectiveConnectionType::kType4G:
+ return settings->GetLazyImageLoadingDistanceThresholdPx4G();
+ }
+ NOTREACHED();
+ return 0;
+}
+
+Document* GetRootDocumentOrNull(Element* element) {
+ if (LocalFrame* frame = element->GetDocument().GetFrame())
+ return frame->LocalFrameRoot().GetDocument();
+ return nullptr;
+}
+
+} // namespace
+
+void LazyLoadImageObserver::StartMonitoring(Element* element) {
+ if (Document* document = GetRootDocumentOrNull(element)) {
+ document->EnsureLazyLoadImageObserver().StartMonitoringNearViewport(
+ document, element);
+ }
+}
+
+void LazyLoadImageObserver::StopMonitoring(Element* element) {
+ if (Document* document = GetRootDocumentOrNull(element)) {
+ document->EnsureLazyLoadImageObserver()
+ .lazy_load_intersection_observer_->unobserve(element);
+ }
+}
+
+void LazyLoadImageObserver::StartTrackingVisibilityMetrics(
+ HTMLImageElement* image_element) {
+ if (!RuntimeEnabledFeatures::LazyImageVisibleLoadTimeMetricsEnabled())
+ return;
+ if (Document* document = GetRootDocumentOrNull(image_element)) {
+ document->EnsureLazyLoadImageObserver().StartMonitoringVisibility(
+ document, image_element);
+ }
+}
+
+void LazyLoadImageObserver::RecordMetricsOnLoadFinished(
+ HTMLImageElement* image_element) {
+ if (!RuntimeEnabledFeatures::LazyImageVisibleLoadTimeMetricsEnabled())
+ return;
+ if (Document* document = GetRootDocumentOrNull(image_element)) {
+ document->EnsureLazyLoadImageObserver().OnLoadFinished(image_element);
+ }
+}
+
+LazyLoadImageObserver::LazyLoadImageObserver() = default;
+
+void LazyLoadImageObserver::StartMonitoringNearViewport(Document* root_document,
+ Element* element) {
+ DCHECK(RuntimeEnabledFeatures::LazyImageLoadingEnabled());
+
+ if (!lazy_load_intersection_observer_) {
+ root_document->AddConsoleMessage(ConsoleMessage::Create(
+ kInterventionMessageSource, kInfoMessageLevel,
+ "Images loaded lazily and replaced with placeholders. Load events are "
+ "deferred. See https://crbug.com/846170"));
+ lazy_load_intersection_observer_ = IntersectionObserver::Create(
+ {Length(GetLazyImageLoadingViewportDistanceThresholdPx(*root_document),
+ kFixed)},
+ {std::numeric_limits<float>::min()}, root_document,
+ WTF::BindRepeating(&LazyLoadImageObserver::LoadIfNearViewport,
+ WrapWeakPersistent(this)));
+ }
+ lazy_load_intersection_observer_->observe(element);
+}
+
+void LazyLoadImageObserver::LoadIfNearViewport(
+ const HeapVector<Member<IntersectionObserverEntry>>& entries) {
+ DCHECK(!entries.IsEmpty());
+
+ for (auto entry : entries) {
+ if (!entry->isIntersecting())
+ continue;
+ Element* element = entry->target();
+ if (auto* image_element = ToHTMLImageElementOrNull(element))
+ image_element->LoadDeferredImage();
+
+ // Load the background image if the element has one deferred.
+ if (const ComputedStyle* style = element->GetComputedStyle())
+ style->LoadDeferredImages(element->GetDocument());
+
+ lazy_load_intersection_observer_->unobserve(element);
+ }
+}
+
+void LazyLoadImageObserver::StartMonitoringVisibility(
+ Document* root_document,
+ HTMLImageElement* image_element) {
+ DCHECK(RuntimeEnabledFeatures::LazyImageVisibleLoadTimeMetricsEnabled());
+
+ VisibleLoadTimeMetrics& visible_load_time_metrics =
+ image_element->EnsureVisibleLoadTimeMetrics();
+ if (visible_load_time_metrics.has_initial_intersection_been_set) {
+ // The element has already been monitored.
+ return;
+ }
+ if (!visibility_metrics_observer_) {
+ visibility_metrics_observer_ = IntersectionObserver::Create(
+ {}, {std::numeric_limits<float>::min()}, root_document,
+ WTF::BindRepeating(&LazyLoadImageObserver::OnVisibilityChanged,
+ WrapWeakPersistent(this)));
+ }
+ visibility_metrics_observer_->observe(image_element);
+}
+
+void LazyLoadImageObserver::OnLoadFinished(HTMLImageElement* image_element) {
+ DCHECK(RuntimeEnabledFeatures::LazyImageVisibleLoadTimeMetricsEnabled());
+
+ VisibleLoadTimeMetrics& visible_load_time_metrics =
+ image_element->EnsureVisibleLoadTimeMetrics();
+ if (visible_load_time_metrics.has_visibility_metrics_been_recorded)
+ return;
+
+ visible_load_time_metrics.has_visibility_metrics_been_recorded = true;
+ visibility_metrics_observer_->unobserve(image_element);
+
+ TimeDelta visible_load_delay;
+ if (!visible_load_time_metrics.time_when_first_visible.is_null()) {
+ visible_load_delay =
+ CurrentTimeTicks() - visible_load_time_metrics.time_when_first_visible;
+ }
+
+ switch (image_element->GetDocument()
+ .GetFrame()
+ ->Client()
+ ->GetEffectiveConnectionType()) {
+ case WebEffectiveConnectionType::kTypeSlow2G:
+ if (visible_load_time_metrics.is_initially_intersecting) {
+ UMA_HISTOGRAM_MEDIUM_TIMES(
+ "Blink.VisibleLoadTime.LazyLoadImages.AboveTheFold.Slow2G",
+ visible_load_delay);
+ } else {
+ UMA_HISTOGRAM_MEDIUM_TIMES(
+ "Blink.VisibleLoadTime.LazyLoadImages.BelowTheFold.Slow2G",
+ visible_load_delay);
+ }
+ break;
+
+ case WebEffectiveConnectionType::kType2G:
+ if (visible_load_time_metrics.is_initially_intersecting) {
+ UMA_HISTOGRAM_MEDIUM_TIMES(
+ "Blink.VisibleLoadTime.LazyLoadImages.AboveTheFold.2G",
+ visible_load_delay);
+ } else {
+ UMA_HISTOGRAM_MEDIUM_TIMES(
+ "Blink.VisibleLoadTime.LazyLoadImages.BelowTheFold.2G",
+ visible_load_delay);
+ }
+ break;
+
+ case WebEffectiveConnectionType::kType3G:
+ if (visible_load_time_metrics.is_initially_intersecting) {
+ UMA_HISTOGRAM_MEDIUM_TIMES(
+ "Blink.VisibleLoadTime.LazyLoadImages.AboveTheFold.3G",
+ visible_load_delay);
+ } else {
+ UMA_HISTOGRAM_MEDIUM_TIMES(
+ "Blink.VisibleLoadTime.LazyLoadImages.BelowTheFold.3G",
+ visible_load_delay);
+ }
+ break;
+
+ case WebEffectiveConnectionType::kType4G:
+ if (visible_load_time_metrics.is_initially_intersecting) {
+ UMA_HISTOGRAM_MEDIUM_TIMES(
+ "Blink.VisibleLoadTime.LazyLoadImages.AboveTheFold.4G",
+ visible_load_delay);
+ } else {
+ UMA_HISTOGRAM_MEDIUM_TIMES(
+ "Blink.VisibleLoadTime.LazyLoadImages.BelowTheFold.4G",
+ visible_load_delay);
+ }
+ break;
+
+ case WebEffectiveConnectionType::kTypeUnknown:
+ case WebEffectiveConnectionType::kTypeOffline:
+ // No VisibleLoadTime histograms are recorded for these effective
+ // connection types.
+ break;
+ }
+}
+
+void LazyLoadImageObserver::OnVisibilityChanged(
+ const HeapVector<Member<IntersectionObserverEntry>>& entries) {
+ DCHECK(!entries.IsEmpty());
+
+ for (auto entry : entries) {
+ if (auto* image_element = ToHTMLImageElementOrNull(entry->target())) {
+ VisibleLoadTimeMetrics& visible_load_time_metrics =
+ image_element->EnsureVisibleLoadTimeMetrics();
+ if (!visible_load_time_metrics.has_initial_intersection_been_set) {
+ visible_load_time_metrics.is_initially_intersecting =
+ entry->isIntersecting();
+ visible_load_time_metrics.has_initial_intersection_been_set = true;
+ }
+ if (entry->isIntersecting()) {
+ DCHECK(visible_load_time_metrics.time_when_first_visible.is_null());
+ visible_load_time_metrics.time_when_first_visible = CurrentTimeTicks();
+ visibility_metrics_observer_->unobserve(image_element);
+ }
+ }
+ }
+}
+
+void LazyLoadImageObserver::Trace(Visitor* visitor) {
+ visitor->Trace(lazy_load_intersection_observer_);
+ visitor->Trace(visibility_metrics_observer_);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/lazy_load_image_observer.h b/chromium/third_party/blink/renderer/core/html/lazy_load_image_observer.h
new file mode 100644
index 00000000000..5a84e8eab4a
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/html/lazy_load_image_observer.h
@@ -0,0 +1,65 @@
+// 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_HTML_LAZY_LOAD_IMAGE_OBSERVER_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_LAZY_LOAD_IMAGE_OBSERVER_H_
+
+#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
+#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
+#include "third_party/blink/renderer/platform/heap/member.h"
+
+namespace blink {
+
+class Document;
+class Element;
+class HTMLImageElement;
+class IntersectionObserver;
+class IntersectionObserverEntry;
+class Visitor;
+
+class LazyLoadImageObserver final
+ : public GarbageCollected<LazyLoadImageObserver> {
+ public:
+ struct VisibleLoadTimeMetrics {
+ // Keeps track of whether the image was initially intersecting the viewport.
+ bool is_initially_intersecting = false;
+ bool has_initial_intersection_been_set = false;
+
+ bool has_visibility_metrics_been_recorded = false;
+
+ // Set when the image first becomes visible (i.e. appears in the viewport).
+ TimeTicks time_when_first_visible;
+ };
+
+ LazyLoadImageObserver();
+
+ static void StartMonitoring(Element*);
+ static void StopMonitoring(Element*);
+
+ static void StartTrackingVisibilityMetrics(HTMLImageElement*);
+ static void RecordMetricsOnLoadFinished(HTMLImageElement*);
+
+ void Trace(Visitor*);
+
+ private:
+ void StartMonitoringNearViewport(Document*, Element*);
+ void LoadIfNearViewport(const HeapVector<Member<IntersectionObserverEntry>>&);
+
+ void StartMonitoringVisibility(Document*, HTMLImageElement*);
+ void OnLoadFinished(HTMLImageElement*);
+
+ void OnVisibilityChanged(
+ const HeapVector<Member<IntersectionObserverEntry>>&);
+
+ // The intersection observer responsible for loading the image once it's near
+ // the viewport.
+ Member<IntersectionObserver> lazy_load_intersection_observer_;
+
+ // The intersection observer used to track when the image becomes visible.
+ Member<IntersectionObserver> visibility_metrics_observer_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_LAZY_LOAD_IMAGE_OBSERVER_H_
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 299c837f1fd..2de33545c84 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
@@ -89,6 +89,8 @@ class CORE_EXPORT ListItemOrdinal {
static Node* EnclosingList(const Node*);
struct NodeAndOrdinal {
STACK_ALLOCATED();
+
+ public:
Persistent<const Node> node;
ListItemOrdinal* ordinal = nullptr;
operator bool() const { return node; }
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 70d13239678..d8902478e8e 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
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/html/media/autoplay_policy.h"
+#include "build/build_config.h"
#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h"
#include "third_party/blink/public/platform/autoplay.mojom-blink.h"
#include "third_party/blink/public/platform/web_media_player.h"
@@ -85,6 +86,12 @@ AutoplayPolicy::Type AutoplayPolicy::GetAutoplayPolicyForDocument(
if (IsDocumentWhitelisted(document))
return Type::kNoUserGestureRequired;
+ if (DocumentHasUserExceptionFlag(document))
+ return Type::kNoUserGestureRequired;
+
+ if (document.GetSettings()->GetPresentationReceiver())
+ return Type::kNoUserGestureRequired;
+
return document.GetSettings()->GetAutoplayPolicy();
}
@@ -109,8 +116,7 @@ bool AutoplayPolicy::IsDocumentAllowedToPlay(const Document& document) {
return true;
}
- if (!RuntimeEnabledFeatures::FeaturePolicyAutoplayFeatureEnabled() ||
- !frame->IsFeatureEnabled(mojom::FeaturePolicyFeature::kAutoplay)) {
+ if (!frame->IsFeatureEnabled(mojom::FeaturePolicyFeature::kAutoplay)) {
return false;
}
}
@@ -134,6 +140,21 @@ bool AutoplayPolicy::DocumentHasForceAllowFlag(const Document& document) {
mojom::blink::kAutoplayFlagForceAllow;
}
+// static
+bool AutoplayPolicy::DocumentHasUserExceptionFlag(const Document& document) {
+ if (!document.GetPage())
+ return false;
+ return document.GetPage()->AutoplayFlags() &
+ mojom::blink::kAutoplayFlagUserException;
+}
+
+// static
+bool AutoplayPolicy::DocumentShouldAutoplayMutedVideos(
+ const Document& document) {
+ return GetAutoplayPolicyForDocument(document) !=
+ AutoplayPolicy::Type::kNoUserGestureRequired;
+}
+
AutoplayPolicy::AutoplayPolicy(HTMLMediaElement* element)
: locked_pending_user_gesture_(false),
locked_pending_user_gesture_if_cross_origin_experiment_enabled_(true),
@@ -169,7 +190,7 @@ void AutoplayPolicy::DidMoveToNewDocument(Document& old_document) {
bool AutoplayPolicy::IsEligibleForAutoplayMuted() const {
return element_->IsHTMLVideoElement() && element_->muted() &&
- RuntimeEnabledFeatures::AutoplayMutedVideosEnabled();
+ DocumentShouldAutoplayMutedVideos(element_->GetDocument());
}
void AutoplayPolicy::StartAutoplayMutedWhenVisible() {
@@ -288,7 +309,7 @@ bool AutoplayPolicy::IsOrWillBeAutoplayingMuted() const {
bool AutoplayPolicy::IsOrWillBeAutoplayingMutedInternal(bool muted) const {
if (!element_->IsHTMLVideoElement() ||
- !RuntimeEnabledFeatures::AutoplayMutedVideosEnabled()) {
+ !DocumentShouldAutoplayMutedVideos(element_->GetDocument())) {
return false;
}
@@ -349,7 +370,7 @@ bool AutoplayPolicy::IsGestureNeededForPlaybackIfPendingUserGestureIsLocked()
// - Preload was not disabled (low end devices);
// - Autoplay is enabled in settings;
if (element_->IsHTMLVideoElement() && element_->muted() &&
- RuntimeEnabledFeatures::AutoplayMutedVideosEnabled() &&
+ DocumentShouldAutoplayMutedVideos(element_->GetDocument()) &&
!(element_->GetDocument().GetSettings() &&
GetNetworkStateNotifier().SaveDataEnabled() &&
!element_->GetDocument()
diff --git a/chromium/third_party/blink/renderer/core/html/media/autoplay_policy.h b/chromium/third_party/blink/renderer/core/html/media/autoplay_policy.h
index c3ece86de70..c8c1ab9c869 100644
--- a/chromium/third_party/blink/renderer/core/html/media/autoplay_policy.h
+++ b/chromium/third_party/blink/renderer/core/html/media/autoplay_policy.h
@@ -49,6 +49,12 @@ class AutoplayPolicy final : public GarbageCollected<AutoplayPolicy> {
// Returns true if the given |document| should force allow autoplay.
static bool DocumentHasForceAllowFlag(const Document&);
+ // Returns true if the given |document| has the user exception flag.
+ static bool DocumentHasUserExceptionFlag(const Document&);
+
+ // Returns true if the given |document| should autoplay muted videos.
+ static bool DocumentShouldAutoplayMutedVideos(const Document&);
+
explicit AutoplayPolicy(HTMLMediaElement*);
void VideoWillBeDrawnToCanvas() const;
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 5ba7fbdda2c..c3e033ed21d 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
@@ -168,7 +168,8 @@ void AutoplayUmaHelper::OnAutoplayInitiated(AutoplaySource source) {
// Record if it will be blocked by Data Saver or Autoplay setting.
if (element_->IsHTMLVideoElement() && element_->muted() &&
- RuntimeEnabledFeatures::AutoplayMutedVideosEnabled()) {
+ AutoplayPolicy::DocumentShouldAutoplayMutedVideos(
+ element_->GetDocument())) {
bool data_saver_enabled_for_autoplay =
GetNetworkStateNotifier().SaveDataEnabled() &&
element_->GetDocument().GetSettings() &&
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 a7cec27411c..e534225c831 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
@@ -83,7 +83,6 @@
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/layout/intersection_geometry.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/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"
@@ -94,7 +93,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/histogram.h"
-#include "third_party/blink/renderer/platform/layout_test_support.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_descriptor.h"
#include "third_party/blink/renderer/platform/network/mime/content_type.h"
#include "third_party/blink/renderer/platform/network/mime/mime_type_from_url.h"
@@ -504,7 +502,6 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tag_name,
tracks_are_ready_(true),
processing_preference_change_(false),
playing_remotely_(false),
- in_overlay_fullscreen_video_(false),
mostly_filling_viewport_(false),
was_always_muted_(true),
audio_tracks_(AudioTrackList::Create(*this)),
@@ -690,12 +687,12 @@ LayoutObject* HTMLMediaElement::CreateLayoutObject(const ComputedStyle&) {
}
Node::InsertionNotificationRequest HTMLMediaElement::InsertedInto(
- ContainerNode* insertion_point) {
+ ContainerNode& insertion_point) {
BLINK_MEDIA_LOG << "insertedInto(" << (void*)this << ", " << insertion_point
<< ")";
HTMLElement::InsertedInto(insertion_point);
- if (insertion_point->isConnected()) {
+ if (insertion_point.isConnected()) {
UseCounter::Count(GetDocument(), WebFeature::kHTMLMediaElementInDocument);
if ((!getAttribute(srcAttr).IsEmpty() || src_object_) &&
network_state_ == kNetworkEmpty) {
@@ -711,12 +708,12 @@ void HTMLMediaElement::DidNotifySubtreeInsertionsToDocument() {
UpdateControlsVisibility();
}
-void HTMLMediaElement::RemovedFrom(ContainerNode* insertion_point) {
+void HTMLMediaElement::RemovedFrom(ContainerNode& insertion_point) {
BLINK_MEDIA_LOG << "removedFrom(" << (void*)this << ", " << insertion_point
<< ")";
HTMLElement::RemovedFrom(insertion_point);
- if (insertion_point->InActiveDocument()) {
+ if (insertion_point.InActiveDocument()) {
UpdateControlsVisibility();
if (network_state_ > kNetworkEmpty)
PauseInternal();
@@ -762,7 +759,7 @@ void HTMLMediaElement::ScheduleEvent(Event* event) {
BLINK_MEDIA_LOG << "ScheduleEvent(" << (void*)this << ")"
<< " - scheduling '" << event->type() << "'";
#endif
- async_event_queue_->EnqueueEvent(FROM_HERE, event);
+ async_event_queue_->EnqueueEvent(FROM_HERE, *event);
}
void HTMLMediaElement::LoadTimerFired(TimerBase*) {
@@ -2651,21 +2648,6 @@ void HTMLMediaElement::setMuted(bool muted) {
autoplay_policy_->StopAutoplayMutedWhenVisible();
}
-void HTMLMediaElement::enterPictureInPicture(
- WebMediaPlayer::PipWindowOpenedCallback callback) {
- if (DisplayType() == WebMediaPlayer::DisplayType::kFullscreen)
- Fullscreen::ExitFullscreen(GetDocument());
-
- if (GetWebMediaPlayer())
- GetWebMediaPlayer()->EnterPictureInPicture(std::move(callback));
-}
-
-void HTMLMediaElement::exitPictureInPicture(
- WebMediaPlayer::PipWindowClosedCallback callback) {
- if (GetWebMediaPlayer())
- GetWebMediaPlayer()->ExitPictureInPicture(std::move(callback));
-}
-
double HTMLMediaElement::EffectiveMediaVolume() const {
if (muted_)
return 0;
@@ -3642,42 +3624,6 @@ bool HTMLMediaElement::IsFullscreen() const {
return Fullscreen::IsFullscreenElement(*this);
}
-void HTMLMediaElement::DidEnterFullscreen() {
- UpdateControlsVisibility();
-
- if (DisplayType() == WebMediaPlayer::DisplayType::kPictureInPicture)
- exitPictureInPicture(base::DoNothing());
-
- if (web_media_player_) {
- // FIXME: There is no embedder-side handling in layout test mode.
- if (!LayoutTestSupport::IsRunningLayoutTest())
- web_media_player_->EnteredFullscreen();
- web_media_player_->OnDisplayTypeChanged(DisplayType());
- }
-
- // 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);
- }
-}
-
-void HTMLMediaElement::DidExitFullscreen() {
- UpdateControlsVisibility();
-
- if (GetWebMediaPlayer()) {
- GetWebMediaPlayer()->ExitedFullscreen();
- GetWebMediaPlayer()->OnDisplayTypeChanged(DisplayType());
- }
-
- if (in_overlay_fullscreen_video_) {
- GetDocument().GetLayoutView()->Compositor()->SetNeedsCompositingUpdate(
- kCompositingUpdateRebuildTree);
- }
- in_overlay_fullscreen_video_ = false;
-}
-
cc::Layer* HTMLMediaElement::CcLayer() const {
return cc_layer_;
}
@@ -4279,7 +4225,8 @@ void HTMLMediaElement::RequestPause() {
bool HTMLMediaElement::MediaShouldBeOpaque() const {
return !IsMediaDataCORSSameOrigin(GetDocument().GetSecurityOrigin()) &&
- ready_state_ < kHaveMetadata && !FastGetAttribute(srcAttr).IsEmpty();
+ ready_state_ < kHaveMetadata && !FastGetAttribute(srcAttr).IsEmpty() &&
+ EffectivePreloadType() != WebMediaPlayer::kPreloadNone;
}
void HTMLMediaElement::CheckViewportIntersectionTimerFired(TimerBase*) {
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 c9b109245ca..a69c53b3f8e 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
@@ -217,8 +217,6 @@ class CORE_EXPORT HTMLMediaElement
bool muted() const;
void setMuted(bool);
virtual bool SupportsPictureInPicture() const { return false; }
- void enterPictureInPicture(WebMediaPlayer::PipWindowOpenedCallback callback);
- void exitPictureInPicture(WebMediaPlayer::PipWindowClosedCallback callback);
void TogglePlayState();
@@ -272,8 +270,6 @@ class CORE_EXPORT HTMLMediaElement
}
bool IsFullscreen() const;
- void DidEnterFullscreen();
- void DidExitFullscreen();
virtual bool UsesOverlayFullscreenVideo() const { return false; }
bool HasClosedCaptions() const;
@@ -348,8 +344,8 @@ class CORE_EXPORT HTMLMediaElement
void CloneNonAttributePropertiesFrom(const Element&,
CloneChildrenFlag) override;
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
- void RemovedFrom(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
+ void RemovedFrom(ContainerNode&) override;
// Return true if media is cross origin from the current document
// and has not passed a cors check, meaning that we should return
@@ -656,8 +652,6 @@ class CORE_EXPORT HTMLMediaElement
bool tracks_are_ready_ : 1;
bool processing_preference_change_ : 1;
bool playing_remotely_ : 1;
- // Whether this element is in overlay fullscreen mode.
- bool in_overlay_fullscreen_video_ : 1;
bool mostly_filling_viewport_ : 1;
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 9ec32c49d96..57473bc604e 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
@@ -27,6 +27,7 @@
#include <memory>
#include "cc/paint/paint_canvas.h"
+#include "third_party/blink/public/platform/web_fullscreen_video_status.h"
#include "third_party/blink/renderer/core/css_property_names.h"
#include "third_party/blink/renderer/core/dom/attribute.h"
#include "third_party/blink/renderer/core/dom/document.h"
@@ -46,12 +47,15 @@
#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/layout_image.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/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/histogram.h"
+#include "third_party/blink/renderer/platform/layout_test_support.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
namespace blink {
@@ -72,7 +76,8 @@ enum VideoPersistenceControlsType {
inline HTMLVideoElement::HTMLVideoElement(Document& document)
: HTMLMediaElement(videoTag, document),
remoting_interstitial_(nullptr),
- picture_in_picture_interstitial_(nullptr) {
+ picture_in_picture_interstitial_(nullptr),
+ in_overlay_fullscreen_video_(false) {
if (document.GetSettings()) {
default_poster_url_ =
AtomicString(document.GetSettings()->GetDefaultVideoPosterURL());
@@ -105,14 +110,14 @@ bool HTMLVideoElement::HasPendingActivity() const {
}
Node::InsertionNotificationRequest HTMLVideoElement::InsertedInto(
- ContainerNode* insertion_point) {
- if (insertion_point->isConnected() && custom_controls_fullscreen_detector_)
+ ContainerNode& insertion_point) {
+ if (insertion_point.isConnected() && custom_controls_fullscreen_detector_)
custom_controls_fullscreen_detector_->Attach();
return HTMLMediaElement::InsertedInto(insertion_point);
}
-void HTMLVideoElement::RemovedFrom(ContainerNode* insertion_point) {
+void HTMLVideoElement::RemovedFrom(ContainerNode& insertion_point) {
HTMLMediaElement::RemovedFrom(insertion_point);
if (custom_controls_fullscreen_detector_)
@@ -203,18 +208,26 @@ void HTMLVideoElement::ParseAttribute(
remoting_interstitial_->OnPosterImageChanged();
if (picture_in_picture_interstitial_)
picture_in_picture_interstitial_->OnPosterImageChanged();
+ } else if (params.name == intrinsicsizeAttr &&
+ RuntimeEnabledFeatures::
+ ExperimentalProductivityFeaturesEnabled()) {
+ ParseIntrinsicSizeAttribute(params.new_value);
} else {
HTMLMediaElement::ParseAttribute(params);
}
}
unsigned HTMLVideoElement::videoWidth() const {
+ if (overridden_intrinsic_size_.Width() > 0)
+ return overridden_intrinsic_size_.Width();
if (!GetWebMediaPlayer())
return 0;
return GetWebMediaPlayer()->NaturalSize().width;
}
unsigned HTMLVideoElement::videoHeight() const {
+ if (overridden_intrinsic_size_.Height() > 0)
+ return overridden_intrinsic_size_.Height();
if (!GetWebMediaPlayer())
return 0;
return GetWebMediaPlayer()->NaturalSize().height;
@@ -225,6 +238,35 @@ IntSize HTMLVideoElement::videoVisibleSize() const {
: IntSize();
}
+IntSize HTMLVideoElement::GetOverriddenIntrinsicSize() const {
+ return overridden_intrinsic_size_;
+}
+
+void HTMLVideoElement::ParseIntrinsicSizeAttribute(const String& value) {
+ unsigned new_width = 0, new_height = 0;
+ Vector<String> size;
+ value.Split('x', size);
+ if (!value.IsEmpty() &&
+ (size.size() != 2 ||
+ !ParseHTMLNonNegativeInteger(size.at(0), new_width) ||
+ !ParseHTMLNonNegativeInteger(size.at(1), new_height))) {
+ GetDocument().AddConsoleMessage(
+ ConsoleMessage::Create(kOtherMessageSource, kWarningMessageLevel,
+ "Unable to parse intrinsicSize: expected "
+ "[unsigned] x [unsigned], got " +
+ value));
+ new_width = 0;
+ new_height = 0;
+ }
+
+ IntSize new_size(new_width, new_height);
+ if (overridden_intrinsic_size_ != new_size) {
+ overridden_intrinsic_size_ = new_size;
+ if (GetLayoutObject() && GetLayoutObject()->IsVideo())
+ ToLayoutVideo(GetLayoutObject())->IntrinsicSizeChanged();
+ }
+}
+
bool HTMLVideoElement::IsURLAttribute(const Attribute& attribute) const {
return attribute.GetName() == posterAttr ||
HTMLMediaElement::IsURLAttribute(attribute);
@@ -365,6 +407,26 @@ bool HTMLVideoElement::CopyVideoTextureToPlatformTexture(
premultiply_alpha, flip_y, already_uploaded_id, out_metadata);
}
+bool HTMLVideoElement::CopyVideoYUVDataToPlatformTexture(
+ gpu::gles2::GLES2Interface* gl,
+ GLenum target,
+ GLuint texture,
+ GLenum internal_format,
+ GLenum format,
+ GLenum type,
+ GLint level,
+ bool premultiply_alpha,
+ bool flip_y,
+ int already_uploaded_id,
+ WebMediaPlayer::VideoFrameUploadMetadata* out_metadata) {
+ if (!GetWebMediaPlayer())
+ return false;
+
+ return GetWebMediaPlayer()->CopyVideoYUVDataToPlatformTexture(
+ gl, target, texture, internal_format, format, type, level,
+ premultiply_alpha, flip_y, already_uploaded_id, out_metadata);
+}
+
bool HTMLVideoElement::TexImageImpl(
WebMediaPlayer::TexImageFunctionID function_id,
GLenum target,
@@ -423,6 +485,42 @@ bool HTMLVideoElement::UsesOverlayFullscreenVideo() const {
GetWebMediaPlayer()->SupportsOverlayFullscreenVideo();
}
+void HTMLVideoElement::DidEnterFullscreen() {
+ UpdateControlsVisibility();
+
+ if (DisplayType() == WebMediaPlayer::DisplayType::kPictureInPicture)
+ exitPictureInPicture(base::DoNothing());
+
+ if (GetWebMediaPlayer()) {
+ // FIXME: There is no embedder-side handling in layout test mode.
+ if (!LayoutTestSupport::IsRunningLayoutTest())
+ GetWebMediaPlayer()->EnteredFullscreen();
+ GetWebMediaPlayer()->OnDisplayTypeChanged(DisplayType());
+ }
+
+ // 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);
+ }
+}
+
+void HTMLVideoElement::DidExitFullscreen() {
+ UpdateControlsVisibility();
+
+ if (GetWebMediaPlayer()) {
+ GetWebMediaPlayer()->ExitedFullscreen();
+ GetWebMediaPlayer()->OnDisplayTypeChanged(DisplayType());
+ }
+
+ if (in_overlay_fullscreen_video_) {
+ GetDocument().GetLayoutView()->Compositor()->SetNeedsCompositingUpdate(
+ kCompositingUpdateRebuildTree);
+ }
+ in_overlay_fullscreen_video_ = false;
+}
+
void HTMLVideoElement::DidMoveToNewDocument(Document& old_document) {
if (image_loader_)
image_loader_->ElementDidMoveToNewDocument();
@@ -549,6 +647,30 @@ bool HTMLVideoElement::SupportsPictureInPicture() const {
PictureInPictureController::Status::kEnabled;
}
+void HTMLVideoElement::enterPictureInPicture(
+ WebMediaPlayer::PipWindowOpenedCallback callback) {
+ if (DisplayType() == WebMediaPlayer::DisplayType::kFullscreen)
+ Fullscreen::ExitFullscreen(GetDocument());
+
+ if (GetWebMediaPlayer())
+ GetWebMediaPlayer()->EnterPictureInPicture(std::move(callback));
+}
+
+void HTMLVideoElement::exitPictureInPicture(
+ WebMediaPlayer::PipWindowClosedCallback callback) {
+ if (GetWebMediaPlayer())
+ GetWebMediaPlayer()->ExitPictureInPicture(std::move(callback));
+}
+
+void HTMLVideoElement::SendCustomControlsToPipWindow() {
+ // TODO(sawtelle): Allow setting controls multiple times for a video, even
+ // when not active, https://crbug.com/869133
+ if (!GetWebMediaPlayer() || !HasPictureInPictureCustomControls())
+ return;
+ GetWebMediaPlayer()->SetPictureInPictureCustomControls(
+ GetPictureInPictureCustomControls());
+}
+
void HTMLVideoElement::PictureInPictureStopped() {
PictureInPictureController::From(GetDocument())
.OnExitedPictureInPicture(nullptr);
@@ -566,6 +688,10 @@ WebMediaPlayer::DisplayType HTMLVideoElement::DisplayType() const {
.IsPictureInPictureElement(this)) {
return WebMediaPlayer::DisplayType::kPictureInPicture;
}
+
+ if (is_effectively_fullscreen_)
+ return WebMediaPlayer::DisplayType::kFullscreen;
+
return HTMLMediaElement::DisplayType();
}
@@ -595,6 +721,31 @@ void HTMLVideoElement::OnExitedPictureInPicture() {
GetWebMediaPlayer()->OnDisplayTypeChanged(DisplayType());
}
+void HTMLVideoElement::SetPictureInPictureCustomControls(
+ const std::vector<PictureInPictureControlInfo>& pip_custom_controls) {
+ pip_custom_controls_ = pip_custom_controls;
+}
+
+const std::vector<PictureInPictureControlInfo>&
+HTMLVideoElement::GetPictureInPictureCustomControls() const {
+ return pip_custom_controls_;
+}
+
+bool HTMLVideoElement::HasPictureInPictureCustomControls() const {
+ return !pip_custom_controls_.empty();
+}
+
+void HTMLVideoElement::SetIsEffectivelyFullscreen(
+ blink::WebFullscreenVideoStatus status) {
+ is_effectively_fullscreen_ =
+ status != blink::WebFullscreenVideoStatus::kNotEffectivelyFullscreen;
+
+ if (GetWebMediaPlayer()) {
+ GetWebMediaPlayer()->SetIsEffectivelyFullscreen(status);
+ GetWebMediaPlayer()->OnDisplayTypeChanged(DisplayType());
+ }
+}
+
void HTMLVideoElement::AddedEventListener(
const AtomicString& event_type,
RegisteredEventListener& registered_listener) {
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 9eabe309d6c..128c855071c 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
@@ -26,6 +26,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_HTML_VIDEO_ELEMENT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_HTML_VIDEO_ELEMENT_H_
+#include "third_party/blink/public/common/picture_in_picture/picture_in_picture_control_info.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/html_image_loader.h"
@@ -57,20 +58,24 @@ class CORE_EXPORT HTMLVideoElement final : public HTMLMediaElement,
bool HasPendingActivity() const final;
// Node override.
- Node::InsertionNotificationRequest InsertedInto(ContainerNode*) override;
- void RemovedFrom(ContainerNode*) override;
+ Node::InsertionNotificationRequest InsertedInto(ContainerNode&) override;
+ void RemovedFrom(ContainerNode&) override;
unsigned videoWidth() const;
unsigned videoHeight() const;
IntSize videoVisibleSize() const;
+ IntSize GetOverriddenIntrinsicSize() const;
+
// Fullscreen
void webkitEnterFullscreen();
void webkitExitFullscreen();
bool webkitSupportsFullscreen();
bool webkitDisplayingFullscreen();
bool UsesOverlayFullscreenVideo() const override;
+ void DidEnterFullscreen();
+ void DidExitFullscreen();
// Statistics
unsigned webkitDecodedFrameCount() const;
@@ -82,9 +87,9 @@ class CORE_EXPORT HTMLVideoElement final : public HTMLMediaElement,
const IntRect&,
const cc::PaintFlags*,
int already_uploaded_id = -1,
- WebMediaPlayer::VideoFrameUploadMetadata* = nullptr) const;
+ WebMediaPlayer::VideoFrameUploadMetadata* out_metadata = nullptr) const;
- // Used by WebGL to do GPU-GPU textures copy if possible.
+ // Used by WebGL to do GPU-GPU texture copy if possible.
bool CopyVideoTextureToPlatformTexture(
gpu::gles2::GLES2Interface*,
GLenum target,
@@ -95,8 +100,22 @@ class CORE_EXPORT HTMLVideoElement final : public HTMLMediaElement,
GLint level,
bool premultiply_alpha,
bool flip_y,
- int already_uploaded_id = -1,
- WebMediaPlayer::VideoFrameUploadMetadata* out_metadata = nullptr);
+ int already_uploaded_id,
+ WebMediaPlayer::VideoFrameUploadMetadata* out_metadata);
+
+ // Used by WebGL to do YUV-RGB, CPU-GPU texture copy if possible.
+ bool CopyVideoYUVDataToPlatformTexture(
+ gpu::gles2::GLES2Interface*,
+ GLenum target,
+ GLuint texture,
+ GLenum internal_format,
+ GLenum format,
+ GLenum type,
+ GLint level,
+ bool premultiply_alpha,
+ bool flip_y,
+ int already_uploaded_id,
+ WebMediaPlayer::VideoFrameUploadMetadata* out_metadata);
// Used by WebGL to do CPU-GPU texture upload if possible.
bool TexImageImpl(WebMediaPlayer::TexImageFunctionID,
@@ -148,6 +167,9 @@ class CORE_EXPORT HTMLVideoElement final : public HTMLMediaElement,
void MediaRemotingStarted(const WebString& remote_device_friendly_name) final;
bool SupportsPictureInPicture() const final;
+ void enterPictureInPicture(WebMediaPlayer::PipWindowOpenedCallback callback);
+ void exitPictureInPicture(WebMediaPlayer::PipWindowClosedCallback callback);
+ void SendCustomControlsToPipWindow();
void PictureInPictureStopped() final;
void PictureInPictureControlClicked(const WebString& control_id) final;
void MediaRemotingStopped(WebLocalizedString::Name error_msg) final;
@@ -159,6 +181,14 @@ class CORE_EXPORT HTMLVideoElement final : public HTMLMediaElement,
void OnEnteredPictureInPicture();
void OnExitedPictureInPicture();
+ void SetPictureInPictureCustomControls(
+ const std::vector<PictureInPictureControlInfo>& pip_custom_controls);
+ const std::vector<PictureInPictureControlInfo>&
+ GetPictureInPictureCustomControls() const;
+ bool HasPictureInPictureCustomControls() const;
+
+ void SetIsEffectivelyFullscreen(blink::WebFullscreenVideoStatus);
+
protected:
// EventTarget overrides.
void AddedEventListener(const AtomicString& event_type,
@@ -190,6 +220,8 @@ class CORE_EXPORT HTMLVideoElement final : public HTMLMediaElement,
void DidMoveToNewDocument(Document& old_document) override;
void SetDisplayMode(DisplayMode) override;
+ void ParseIntrinsicSizeAttribute(const String& value);
+
Member<HTMLImageLoader> image_loader_;
Member<MediaCustomControlsFullscreenDetector>
custom_controls_fullscreen_detector_;
@@ -207,6 +239,20 @@ class CORE_EXPORT HTMLVideoElement final : public HTMLMediaElement,
// 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;
+
+ // Whether this element is in overlay fullscreen mode.
+ bool in_overlay_fullscreen_video_;
+
+ // Holds the most recently set custom controls. These will be persistent
+ // across active/inactive windows until new controls are passed in.
+ std::vector<PictureInPictureControlInfo> pip_custom_controls_;
+
+ // 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;
+
+ IntSize overridden_intrinsic_size_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/media/html_video_element.idl b/chromium/third_party/blink/renderer/core/html/media/html_video_element.idl
index c3824d30a36..1dc61839315 100644
--- a/chromium/third_party/blink/renderer/core/html/media/html_video_element.idl
+++ b/chromium/third_party/blink/renderer/core/html/media/html_video_element.idl
@@ -35,6 +35,9 @@
readonly attribute unsigned long videoHeight;
[CEReactions, Reflect, URL, Measure] attribute DOMString poster;
+ // github.com/ojanvafai/intrinsicsize-attribute/blob/master/README.md
+ [RuntimeEnabled=ExperimentalProductivityFeatures, CEReactions, Reflect] attribute DOMString intrinsicSize;
+
// Non-standard APIs
[RuntimeEnabled=PrefixedVideoFullscreen, DeprecateAs=PrefixedVideoSupportsFullscreen] readonly attribute boolean webkitSupportsFullscreen;
[RuntimeEnabled=PrefixedVideoFullscreen, DeprecateAs=PrefixedVideoDisplayingFullscreen] readonly attribute boolean webkitDisplayingFullscreen;
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 534f6027f2f..78a1a88e979 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
@@ -7,6 +7,9 @@
#include "cc/layers/layer.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/picture_in_picture/picture_in_picture_control_info.h"
+#include "third_party/blink/public/platform/web_fullscreen_video_status.h"
+#include "third_party/blink/public/platform/web_media_player.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
#include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/core/loader/empty_clients.h"
@@ -16,10 +19,16 @@
namespace blink {
+class HTMLVideoElementMockMediaPlayer : public EmptyWebMediaPlayer {
+ public:
+ MOCK_METHOD1(SetIsEffectivelyFullscreen, void(WebFullscreenVideoStatus));
+ MOCK_METHOD1(OnDisplayTypeChanged, void(WebMediaPlayer::DisplayType));
+};
+
class HTMLVideoElementFrameClient : public EmptyLocalFrameClient {
public:
- HTMLVideoElementFrameClient()
- : player_(std::make_unique<EmptyWebMediaPlayer>()) {}
+ HTMLVideoElementFrameClient(std::unique_ptr<WebMediaPlayer> player)
+ : player_(std::move(player)) {}
std::unique_ptr<WebMediaPlayer> CreateWebMediaPlayer(
HTMLMediaElement&,
@@ -37,7 +46,13 @@ class HTMLVideoElementFrameClient : public EmptyLocalFrameClient {
class HTMLVideoElementTest : public PageTestBase {
public:
void SetUp() override {
- SetupPageWithClients(nullptr, new HTMLVideoElementFrameClient(), nullptr);
+ auto mock_media_player =
+ std::make_unique<HTMLVideoElementMockMediaPlayer>();
+ media_player_ = mock_media_player.get();
+
+ SetupPageWithClients(
+ nullptr, new HTMLVideoElementFrameClient(std::move(mock_media_player)),
+ nullptr);
video_ = HTMLVideoElement::Create(GetDocument());
GetDocument().body()->appendChild(video_);
}
@@ -46,8 +61,15 @@ class HTMLVideoElementTest : public PageTestBase {
HTMLVideoElement* video() { return video_.Get(); }
+ HTMLVideoElementMockMediaPlayer* MockWebMediaPlayer() {
+ return media_player_;
+ }
+
private:
Persistent<HTMLVideoElement> video_;
+
+ // Owned by HTMLVideoElementFrameClient.
+ HTMLVideoElementMockMediaPlayer* media_player_;
};
TEST_F(HTMLVideoElementTest, PictureInPictureInterstitialAndTextContainer) {
@@ -91,4 +113,43 @@ TEST_F(HTMLVideoElementTest, PictureInPictureInterstitial_Reattach) {
GetDocument().body()->removeChild(video());
}
+TEST_F(HTMLVideoElementTest, setPictureInPictureControls) {
+ EXPECT_FALSE(video()->HasPictureInPictureCustomControls());
+
+ std::vector<PictureInPictureControlInfo> test_controls;
+ test_controls.push_back(PictureInPictureControlInfo());
+ video()->SetPictureInPictureCustomControls(test_controls);
+
+ EXPECT_TRUE(video()->HasPictureInPictureCustomControls());
+}
+
+TEST_F(HTMLVideoElementTest, EffectivelyFullscreen_DisplayType) {
+ EXPECT_EQ(WebMediaPlayer::DisplayType::kInline, video()->DisplayType());
+
+ // Vector of data to use for tests. First value is to be set when calling
+ // SetIsEffectivelyFullscreen(). The second one is the expected DisplayType.
+ // This is testing all possible values of WebFullscreenVideoStatus and then
+ // sets the value back to a value that should put the DisplayType back to
+ // inline.
+ std::vector<std::pair<WebFullscreenVideoStatus, WebMediaPlayer::DisplayType>>
+ tests = {
+ {WebFullscreenVideoStatus::kNotEffectivelyFullscreen,
+ WebMediaPlayer::DisplayType::kInline},
+ {WebFullscreenVideoStatus::kFullscreenAndPictureInPictureEnabled,
+ WebMediaPlayer::DisplayType::kFullscreen},
+ {WebFullscreenVideoStatus::kFullscreenAndPictureInPictureDisabled,
+ WebMediaPlayer::DisplayType::kFullscreen},
+ {WebFullscreenVideoStatus::kNotEffectivelyFullscreen,
+ WebMediaPlayer::DisplayType::kInline},
+ };
+
+ for (const auto& test : tests) {
+ EXPECT_CALL(*MockWebMediaPlayer(), SetIsEffectivelyFullscreen(test.first));
+ EXPECT_CALL(*MockWebMediaPlayer(), OnDisplayTypeChanged(test.second));
+ video()->SetIsEffectivelyFullscreen(test.first);
+
+ EXPECT_EQ(test.second, video()->DisplayType());
+ }
+}
+
} // namespace blink
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 6ece9151c10..c4dedb2c6ad 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
@@ -14,6 +14,8 @@
namespace blink {
+using blink::WebFullscreenVideoStatus;
+
namespace {
constexpr TimeDelta kCheckFullscreenInterval = TimeDelta::FromSeconds(1);
@@ -57,10 +59,8 @@ void MediaCustomControlsFullscreenDetector::Detach() {
EventTypeNames::fullscreenchange, this, true);
check_viewport_intersection_timer_.Stop();
- if (VideoElement().GetWebMediaPlayer()) {
- VideoElement().GetWebMediaPlayer()->SetIsEffectivelyFullscreen(
- blink::WebFullscreenVideoStatus::kNotEffectivelyFullscreen);
- }
+ VideoElement().SetIsEffectivelyFullscreen(
+ WebFullscreenVideoStatus::kNotEffectivelyFullscreen);
}
bool MediaCustomControlsFullscreenDetector::ComputeIsDominantVideoForTests(
@@ -113,11 +113,8 @@ void MediaCustomControlsFullscreenDetector::handleEvent(
if (!VideoElement().isConnected() || !IsVideoOrParentFullscreen()) {
check_viewport_intersection_timer_.Stop();
- if (VideoElement().GetWebMediaPlayer()) {
- VideoElement().GetWebMediaPlayer()->SetIsEffectivelyFullscreen(
- blink::WebFullscreenVideoStatus::kNotEffectivelyFullscreen);
- }
-
+ VideoElement().SetIsEffectivelyFullscreen(
+ WebFullscreenVideoStatus::kNotEffectivelyFullscreen);
return;
}
@@ -126,10 +123,6 @@ void MediaCustomControlsFullscreenDetector::handleEvent(
}
void MediaCustomControlsFullscreenDetector::ContextDestroyed() {
- // This method is called by HTMLVideoElement when it observes context destroy.
- // The reason is that when HTMLMediaElement observes context destroy, it will
- // destroy webMediaPlayer() thus the final
- // setIsEffectivelyFullscreen(kNotEffectivelyFullscreen) is not called.
Detach();
}
@@ -144,12 +137,9 @@ void MediaCustomControlsFullscreenDetector::
geometry.TargetIntRect(), geometry.RootIntRect(),
geometry.IntersectionIntRect());
- if (!VideoElement().GetWebMediaPlayer())
- return;
-
if (!is_dominant) {
- VideoElement().GetWebMediaPlayer()->SetIsEffectivelyFullscreen(
- blink::WebFullscreenVideoStatus::kNotEffectivelyFullscreen);
+ VideoElement().SetIsEffectivelyFullscreen(
+ WebFullscreenVideoStatus::kNotEffectivelyFullscreen);
return;
}
@@ -158,12 +148,11 @@ void MediaCustomControlsFullscreenDetector::
!RuntimeEnabledFeatures::PictureInPictureEnabled() &&
!VideoElement().FastHasAttribute(HTMLNames::disablepictureinpictureAttr);
if (picture_in_picture_allowed) {
- VideoElement().GetWebMediaPlayer()->SetIsEffectivelyFullscreen(
- blink::WebFullscreenVideoStatus::kFullscreenAndPictureInPictureEnabled);
+ VideoElement().SetIsEffectivelyFullscreen(
+ WebFullscreenVideoStatus::kFullscreenAndPictureInPictureEnabled);
} else {
- VideoElement().GetWebMediaPlayer()->SetIsEffectivelyFullscreen(
- blink::WebFullscreenVideoStatus::
- kFullscreenAndPictureInPictureDisabled);
+ VideoElement().SetIsEffectivelyFullscreen(
+ WebFullscreenVideoStatus::kFullscreenAndPictureInPictureDisabled);
}
}
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 c8c4d7492d8..b75878c500f 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
@@ -47,7 +47,7 @@ class CORE_EXPORT MediaCustomControlsFullscreenDetector final
const IntRect& root_rect,
const IntRect& intersection_rect);
- // `m_videoElement` owns |this|.
+ // `video_element_` owns |this|.
Member<HTMLVideoElement> video_element_;
TaskRunnerTimer<MediaCustomControlsFullscreenDetector>
check_viewport_intersection_timer_;
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 184bbfd83e2..5263a790ecb 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
@@ -137,23 +137,23 @@ DocumentParser* MediaDocument::CreateParser() {
return MediaDocumentParser::Create(this);
}
-void MediaDocument::DefaultEventHandler(Event* event) {
- Node* target_node = event->target()->ToNode();
+void MediaDocument::DefaultEventHandler(Event& event) {
+ Node* target_node = event.target()->ToNode();
if (!target_node)
return;
- if (event->type() == EventTypeNames::keydown && event->IsKeyboardEvent()) {
+ if (event.type() == EventTypeNames::keydown && event.IsKeyboardEvent()) {
HTMLVideoElement* video =
Traversal<HTMLVideoElement>::FirstWithin(*target_node);
if (!video)
return;
- KeyboardEvent* keyboard_event = ToKeyboardEvent(event);
- if (keyboard_event->key() == " " ||
- keyboard_event->keyCode() == VKEY_MEDIA_PLAY_PAUSE) {
+ auto& keyboard_event = ToKeyboardEvent(event);
+ if (keyboard_event.key() == " " ||
+ keyboard_event.keyCode() == VKEY_MEDIA_PLAY_PAUSE) {
// space or media key (play/pause)
video->TogglePlayState();
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
}
}
}
diff --git a/chromium/third_party/blink/renderer/core/html/media/media_document.h b/chromium/third_party/blink/renderer/core/html/media/media_document.h
index 7ed8b75f41e..c877e115d38 100644
--- a/chromium/third_party/blink/renderer/core/html/media/media_document.h
+++ b/chromium/third_party/blink/renderer/core/html/media/media_document.h
@@ -41,7 +41,7 @@ class MediaDocument final : public HTMLDocument {
DocumentParser* CreateParser() override;
- void DefaultEventHandler(Event*) override;
+ void DefaultEventHandler(Event&) override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/media/picture_in_picture_interstitial.cc b/chromium/third_party/blink/renderer/core/html/media/picture_in_picture_interstitial.cc
index 5f760986991..e0adc27811f 100644
--- a/chromium/third_party/blink/renderer/core/html/media/picture_in_picture_interstitial.cc
+++ b/chromium/third_party/blink/renderer/core/html/media/picture_in_picture_interstitial.cc
@@ -117,7 +117,7 @@ void PictureInPictureInterstitial::Hide() {
}
Node::InsertionNotificationRequest PictureInPictureInterstitial::InsertedInto(
- ContainerNode* root) {
+ ContainerNode& root) {
if (GetVideoElement().isConnected() && !resize_observer_) {
resize_observer_ =
ResizeObserver::Create(GetVideoElement().GetDocument(),
@@ -128,7 +128,7 @@ Node::InsertionNotificationRequest PictureInPictureInterstitial::InsertedInto(
return HTMLDivElement::InsertedInto(root);
}
-void PictureInPictureInterstitial::RemovedFrom(ContainerNode*) {
+void PictureInPictureInterstitial::RemovedFrom(ContainerNode&) {
DCHECK(!GetVideoElement().isConnected());
if (resize_observer_) {
diff --git a/chromium/third_party/blink/renderer/core/html/media/picture_in_picture_interstitial.h b/chromium/third_party/blink/renderer/core/html/media/picture_in_picture_interstitial.h
index 991b29da40b..5cddd5d722d 100644
--- a/chromium/third_party/blink/renderer/core/html/media/picture_in_picture_interstitial.h
+++ b/chromium/third_party/blink/renderer/core/html/media/picture_in_picture_interstitial.h
@@ -36,8 +36,8 @@ class PictureInPictureInterstitial final : public HTMLDivElement {
HTMLVideoElement& GetVideoElement() const { return *video_element_; }
// Node override.
- Node::InsertionNotificationRequest InsertedInto(ContainerNode*) override;
- void RemovedFrom(ContainerNode*) override;
+ Node::InsertionNotificationRequest InsertedInto(ContainerNode&) override;
+ void RemovedFrom(ContainerNode&) override;
// Element:
void Trace(blink::Visitor*) override;
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 cbe3e41b259..95cc220f037 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
@@ -28,17 +28,11 @@
#include "third_party/blink/renderer/core/html/parser/css_preload_scanner.h"
#include <memory>
-#include "third_party/blink/renderer/core/dom/document.h"
-#include "third_party/blink/renderer/core/frame/settings.h"
+
#include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h"
-#include "third_party/blink/renderer/core/html/parser/html_resource_preloader.h"
-#include "third_party/blink/renderer/core/loader/document_loader.h"
-#include "third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.h"
-#include "third_party/blink/renderer/platform/histogram.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/text/segmented_string.h"
-#include "third_party/blink/renderer/platform/weborigin/security_policy.h"
namespace blink {
@@ -256,108 +250,4 @@ void CSSPreloadScanner::EmitRule(const SegmentedString& source) {
rule_value_.Clear();
}
-CSSPreloaderResourceClient::CSSPreloaderResourceClient(
- HTMLResourcePreloader* preloader)
- : policy_(preloader->GetDocument()
- ->GetSettings()
- ->GetCSSExternalScannerPreload()
- ? kScanAndPreload
- : kScanOnly),
- preloader_(preloader) {}
-
-CSSPreloaderResourceClient::~CSSPreloaderResourceClient() = default;
-
-void CSSPreloaderResourceClient::NotifyFinished(Resource*) {
- MaybeClearResource();
-}
-
-// Only attach for one appendData call, as that's where most imports will likely
-// be (according to spec).
-void CSSPreloaderResourceClient::DataReceived(Resource* resource,
- const char*,
- size_t) {
- if (received_first_data_)
- return;
- received_first_data_ = true;
- if (preloader_)
- ScanCSS(ToCSSStyleSheetResource(resource));
- MaybeClearResource();
-}
-
-void CSSPreloaderResourceClient::ScanCSS(
- const CSSStyleSheetResource* resource) {
- DCHECK(preloader_);
-
- // Early abort if there is no document loader. Do this early to ensure that
- // scan histograms and preload histograms do not count different quantities.
- if (!preloader_->GetDocument()->Loader())
- return;
-
- // Passing an empty SegmentedString here results in PreloadRequest with no
- // file/line information.
- // TODO(csharrison): If this becomes an issue the CSSPreloadScanner may be
- // augmented to take care of this case without performing an additional
- // copy.
- TimeTicks start_time = CurrentTimeTicks();
- const String& chunk = resource->SheetText(nullptr);
- if (chunk.IsNull())
- return;
- CSSPreloadScanner css_preload_scanner;
-
- ReferrerPolicy referrer_policy = kReferrerPolicyDefault;
- String referrer_policy_header =
- resource->GetResponse().HttpHeaderField(HTTPNames::Referrer_Policy);
- if (!referrer_policy_header.IsNull()) {
- SecurityPolicy::ReferrerPolicyFromHeaderValue(
- referrer_policy_header, kDoNotSupportReferrerPolicyLegacyKeywords,
- &referrer_policy);
- }
- css_preload_scanner.SetReferrerPolicy(referrer_policy);
- PreloadRequestStream preloads;
- css_preload_scanner.Scan(chunk, SegmentedString(), preloads,
- resource->GetResponse().Url());
- UMA_HISTOGRAM_CUSTOM_TIMES(
- "PreloadScanner.ExternalCSS.ScanTime", CurrentTimeTicks() - start_time,
- TimeDelta::FromMilliseconds(1), TimeDelta::FromSeconds(1000), 50);
- FetchPreloads(preloads);
-}
-
-void CSSPreloaderResourceClient::FetchPreloads(PreloadRequestStream& preloads) {
- if (preloads.size()) {
- preloader_->GetDocument()->Loader()->DidObserveLoadingBehavior(
- WebLoadingBehaviorFlag::kWebLoadingBehaviorCSSPreloadFound);
- }
-
- if (policy_ == kScanAndPreload) {
- int current_preload_count = preloader_->CountPreloads();
- preloader_->TakeAndPreload(preloads);
- DEFINE_STATIC_LOCAL(
- CustomCountHistogram, css_import_histogram,
- ("PreloadScanner.ExternalCSS.PreloadCount", 1, 100, 50));
- css_import_histogram.Count(preloader_->CountPreloads() -
- current_preload_count);
- }
-}
-
-void CSSPreloaderResourceClient::MaybeClearResource() {
- // Do not remove the client for unused, speculative markup preloads. This will
- // trigger cancellation of the request and potential removal from memory
- // cache. Link preloads are an exception because they support dynamic removal
- // cancelling the request (and have their own passive resource client).
- // Note: Speculative preloads which remain unused for their lifetime will
- // never have this client removed. This should be fine because we only hold
- // weak references to the resource.
- if (GetResource() && GetResource()->IsUnusedPreload() &&
- !GetResource()->IsLinkPreload()) {
- return;
- }
-
- ClearResource();
-}
-
-void CSSPreloaderResourceClient::Trace(blink::Visitor* visitor) {
- visitor->Trace(preloader_);
- ResourceClient::Trace(visitor);
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/parser/css_preload_scanner.h b/chromium/third_party/blink/renderer/core/html/parser/css_preload_scanner.h
index fc3bc615fda..43fb7394c0e 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/css_preload_scanner.h
+++ b/chromium/third_party/blink/renderer/core/html/parser/css_preload_scanner.h
@@ -30,15 +30,11 @@
#include "base/macros.h"
#include "third_party/blink/renderer/core/html/parser/html_token.h"
#include "third_party/blink/renderer/core/html/parser/preload_request.h"
-#include "third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/loader/fetch/resource_client.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
namespace blink {
class SegmentedString;
-class HTMLResourcePreloader;
class CSSPreloadScanner {
DISALLOW_NEW();
@@ -97,42 +93,6 @@ class CSSPreloadScanner {
DISALLOW_COPY_AND_ASSIGN(CSSPreloadScanner);
};
-// Each CSSPreloaderResourceClient keeps track of a single CSS resource, and
-// drives a CSSPreloadScanner as raw data arrives for it. This lets us preload
-// @import tags before parsing.
-class CORE_EXPORT CSSPreloaderResourceClient
- : public GarbageCollectedFinalized<CSSPreloaderResourceClient>,
- public ResourceClient {
- USING_GARBAGE_COLLECTED_MIXIN(CSSPreloaderResourceClient);
-
- public:
- CSSPreloaderResourceClient(HTMLResourcePreloader*);
- ~CSSPreloaderResourceClient() override;
- void NotifyFinished(Resource*) override;
- void DataReceived(Resource*, const char*, size_t) override;
- String DebugName() const override { return "CSSPreloaderResourceClient"; }
-
- void Trace(blink::Visitor*) override;
-
- protected:
- // Protected for tests, which don't want to initialize a fully featured
- // DocumentLoader.
- virtual void FetchPreloads(PreloadRequestStream& preloads);
-
- private:
- void ScanCSS(const CSSStyleSheetResource*);
- void MaybeClearResource();
-
- enum PreloadPolicy {
- kScanOnly,
- kScanAndPreload,
- };
-
- const PreloadPolicy policy_;
- WeakMember<HTMLResourcePreloader> preloader_;
- bool received_first_data_ = false;
-};
-
} // namespace blink
#endif
diff --git a/chromium/third_party/blink/renderer/core/html/parser/css_preload_scanner_test.cc b/chromium/third_party/blink/renderer/core/html/parser/css_preload_scanner_test.cc
deleted file mode 100644
index 8d745234bc0..00000000000
--- a/chromium/third_party/blink/renderer/core/html/parser/css_preload_scanner_test.cc
+++ /dev/null
@@ -1,231 +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/html/parser/css_preload_scanner.h"
-
-#include <memory>
-
-#include "base/macros.h"
-#include "testing/gtest/include/gtest/gtest.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"
-#include "third_party/blink/renderer/core/frame/settings.h"
-#include "third_party/blink/renderer/core/html/parser/html_resource_preloader.h"
-#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
-#include "third_party/blink/renderer/platform/exported/wrapped_resource_response.h"
-#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/loader/fetch/fetch_context.h"
-#include "third_party/blink/renderer/platform/loader/fetch/resource.h"
-#include "third_party/blink/renderer/platform/loader/fetch/resource_error.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/weborigin/kurl.h"
-#include "third_party/blink/renderer/platform/wtf/text/text_encoding.h"
-
-namespace blink {
-
-namespace {
-
-class CSSMockHTMLResourcePreloader : public HTMLResourcePreloader {
-
- public:
- explicit CSSMockHTMLResourcePreloader(Document& document,
- const char* expected_referrer = nullptr)
- : HTMLResourcePreloader(document),
- expected_referrer_(expected_referrer) {}
-
- void Preload(std::unique_ptr<PreloadRequest> preload_request,
- const NetworkHintsInterface&) override {
- if (expected_referrer_) {
- Resource* resource = preload_request->Start(GetDocument(), nullptr);
- EXPECT_EQ(expected_referrer_,
- resource->GetResourceRequest().HttpReferrer());
- }
- }
-
- const char* expected_referrer_;
-
- DISALLOW_COPY_AND_ASSIGN(CSSMockHTMLResourcePreloader);
-};
-
-class PreloadRecordingCSSPreloaderResourceClient final
- : public CSSPreloaderResourceClient {
- public:
- PreloadRecordingCSSPreloaderResourceClient(HTMLResourcePreloader* preloader)
- : CSSPreloaderResourceClient(preloader) {}
-
- void FetchPreloads(PreloadRequestStream& preloads) override {
- for (const auto& it : preloads) {
- preload_urls_.push_back(it->ResourceURL());
- preload_referrer_policies_.push_back(it->GetReferrerPolicy());
- }
- CSSPreloaderResourceClient::FetchPreloads(preloads);
- }
-
- Vector<String> preload_urls_;
- Vector<ReferrerPolicy> preload_referrer_policies_;
-};
-
-class CSSPreloadScannerTest : public testing::Test {};
-
-} // namespace
-
-TEST_F(CSSPreloadScannerTest, ScanFromResourceClient) {
- std::unique_ptr<DummyPageHolder> dummy_page_holder =
- DummyPageHolder::Create(IntSize(500, 500));
- dummy_page_holder->GetDocument()
- .GetSettings()
- ->SetCSSExternalScannerNoPreload(true);
-
- CSSMockHTMLResourcePreloader* preloader =
- new CSSMockHTMLResourcePreloader(dummy_page_holder->GetDocument());
-
- KURL url("http://127.0.0.1/foo.css");
- Platform::Current()->GetURLLoaderMockFactory()->RegisterURL(
- url, WrappedResourceResponse(ResourceResponse()), "");
- FetchParameters params{ResourceRequest(url)};
- PreloadRecordingCSSPreloaderResourceClient* resource_client =
- new PreloadRecordingCSSPreloaderResourceClient(preloader);
- Resource* resource = CSSStyleSheetResource::Fetch(
- params, dummy_page_holder->GetDocument().Fetcher(), resource_client);
- const char* data = "@import url('http://127.0.0.1/preload.css');";
- resource->AppendData(data, strlen(data));
-
- EXPECT_EQ(1u, resource_client->preload_urls_.size());
- EXPECT_EQ("http://127.0.0.1/preload.css",
- resource_client->preload_urls_.front());
- Platform::Current()->GetURLLoaderMockFactory()->UnregisterURL(url);
-}
-
-// Regression test for crbug.com/608310 where the client is destroyed but was
-// not removed from the resource's client list.
-TEST_F(CSSPreloadScannerTest, DestroyClientBeforeDataSent) {
- std::unique_ptr<DummyPageHolder> dummy_page_holder =
- DummyPageHolder::Create(IntSize(500, 500));
- dummy_page_holder->GetDocument()
- .GetSettings()
- ->SetCSSExternalScannerNoPreload(true);
-
- Persistent<CSSMockHTMLResourcePreloader> preloader =
- new CSSMockHTMLResourcePreloader(dummy_page_holder->GetDocument());
-
- KURL url("http://127.0.0.1/foo.css");
- Platform::Current()->GetURLLoaderMockFactory()->RegisterURL(
- url, WrappedResourceResponse(ResourceResponse()), "");
- FetchParameters params{ResourceRequest(url)};
- PreloadRecordingCSSPreloaderResourceClient* resource_client =
- new PreloadRecordingCSSPreloaderResourceClient(preloader);
- Resource* resource = CSSStyleSheetResource::Fetch(
- params, dummy_page_holder->GetDocument().Fetcher(), resource_client);
-
- // Destroys the resourceClient.
- ThreadState::Current()->CollectAllGarbage();
-
- const char* data = "@import url('http://127.0.0.1/preload.css');";
- // Should not crash.
- resource->AppendData(data, strlen(data));
- Platform::Current()->GetURLLoaderMockFactory()->UnregisterURL(url);
-}
-
-// Regression test for crbug.com/646869 where the client's data is cleared
-// before DataReceived() is called.
-TEST_F(CSSPreloadScannerTest, DontReadFromClearedData) {
- std::unique_ptr<DummyPageHolder> dummy_page_holder =
- DummyPageHolder::Create(IntSize(500, 500));
- dummy_page_holder->GetDocument()
- .GetSettings()
- ->SetCSSExternalScannerNoPreload(true);
-
- CSSMockHTMLResourcePreloader* preloader =
- new CSSMockHTMLResourcePreloader(dummy_page_holder->GetDocument());
-
- KURL url("data:text/css,@import url('http://127.0.0.1/preload.css');");
- FetchParameters params{ResourceRequest(url)};
- Resource* resource = CSSStyleSheetResource::Fetch(
- params, dummy_page_holder->GetDocument().Fetcher(), nullptr);
- ASSERT_FALSE(resource->ResourceBuffer());
-
- // Should not crash.
- PreloadRecordingCSSPreloaderResourceClient* resource_client =
- new PreloadRecordingCSSPreloaderResourceClient(preloader);
- Resource* resource2 = CSSStyleSheetResource::Fetch(
- params, dummy_page_holder->GetDocument().Fetcher(), resource_client);
- ASSERT_EQ(resource, resource2);
- EXPECT_EQ(0u, resource_client->preload_urls_.size());
-}
-
-// Regression test for crbug.com/645331, where a resource client gets callbacks
-// after the document is shutdown and we have no frame.
-TEST_F(CSSPreloadScannerTest, DoNotExpectValidDocument) {
- std::unique_ptr<DummyPageHolder> dummy_page_holder =
- DummyPageHolder::Create(IntSize(500, 500));
- dummy_page_holder->GetDocument()
- .GetSettings()
- ->SetCSSExternalScannerNoPreload(true);
-
- CSSMockHTMLResourcePreloader* preloader =
- new CSSMockHTMLResourcePreloader(dummy_page_holder->GetDocument());
-
- KURL url("http://127.0.0.1/foo.css");
- Platform::Current()->GetURLLoaderMockFactory()->RegisterURL(
- url, WrappedResourceResponse(ResourceResponse()), "");
- FetchParameters params{ResourceRequest(url)};
- PreloadRecordingCSSPreloaderResourceClient* resource_client =
- new PreloadRecordingCSSPreloaderResourceClient(preloader);
- Resource* resource = CSSStyleSheetResource::Fetch(
- params, dummy_page_holder->GetDocument().Fetcher(), resource_client);
-
- dummy_page_holder->GetDocument().Shutdown();
-
- const char* data = "@import url('http://127.0.0.1/preload.css');";
- resource->AppendData(data, strlen(data));
-
- // Do not expect to gather any preloads, as the document loader is invalid,
- // which means we can't notify WebLoadingBehaviorData of the preloads.
- EXPECT_EQ(0u, resource_client->preload_urls_.size());
- Platform::Current()->GetURLLoaderMockFactory()->UnregisterURL(url);
-}
-
-TEST_F(CSSPreloadScannerTest, ReferrerPolicyHeader) {
- std::unique_ptr<DummyPageHolder> dummy_page_holder =
- DummyPageHolder::Create(IntSize(500, 500));
- dummy_page_holder->GetDocument().GetSettings()->SetCSSExternalScannerPreload(
- true);
-
- CSSMockHTMLResourcePreloader* preloader = new CSSMockHTMLResourcePreloader(
- dummy_page_holder->GetDocument(), "http://127.0.0.1/foo.css");
-
- KURL url("http://127.0.0.1/foo.css");
- FetchParameters params{ResourceRequest(url)};
- Platform::Current()->GetURLLoaderMockFactory()->RegisterURL(
- url, WrappedResourceResponse(ResourceResponse()), "");
-
- ResourceResponse response(url);
- response.SetHTTPStatusCode(200);
- response.SetHTTPHeaderField("referrer-policy", "unsafe-url");
-
- PreloadRecordingCSSPreloaderResourceClient* resource_client =
- new PreloadRecordingCSSPreloaderResourceClient(preloader);
- Resource* resource = CSSStyleSheetResource::Fetch(
- params, dummy_page_holder->GetDocument().Fetcher(), resource_client);
- resource->SetResponse(response);
-
- KURL preload_url("http://127.0.0.1/preload.css");
- Platform::Current()->GetURLLoaderMockFactory()->RegisterURL(
- preload_url, WrappedResourceResponse(ResourceResponse()), "");
-
- const char* data = "@import url('http://127.0.0.1/preload.css');";
- resource->AppendData(data, strlen(data));
-
- EXPECT_EQ(1u, resource_client->preload_urls_.size());
- EXPECT_EQ("http://127.0.0.1/preload.css",
- resource_client->preload_urls_.front());
- EXPECT_EQ(kReferrerPolicyAlways,
- resource_client->preload_referrer_policies_.front());
- Platform::Current()->GetURLLoaderMockFactory()->UnregisterURL(url);
- Platform::Current()->GetURLLoaderMockFactory()->UnregisterURL(preload_url);
-}
-
-} // namespace blink
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 80157426c22..0a09f4c4333 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
@@ -316,7 +316,7 @@ static const size_t kCharsetLength = sizeof("charset") - 1;
// https://html.spec.whatwg.org/multipage/infrastructure.html#extracting-character-encodings-from-meta-elements
String ExtractCharset(const String& value) {
- size_t pos = 0;
+ wtf_size_t pos = 0;
unsigned length = value.length();
while (pos < length) {
@@ -372,25 +372,25 @@ enum class MetaAttribute {
WTF::TextEncoding EncodingFromMetaAttributes(
const HTMLAttributeList& attributes) {
bool got_pragma = false;
+ bool has_charset = false;
MetaAttribute mode = MetaAttribute::kNone;
String charset;
for (const auto& html_attribute : attributes) {
const String& attribute_name = html_attribute.first;
- const String& attribute_value = AtomicString(html_attribute.second);
+ const AtomicString& attribute_value = AtomicString(html_attribute.second);
if (ThreadSafeMatch(attribute_name, http_equivAttr)) {
if (DeprecatedEqualIgnoringCase(attribute_value, "content-type"))
got_pragma = true;
- } else if (charset.IsEmpty()) {
- if (ThreadSafeMatch(attribute_name, charsetAttr)) {
- charset = attribute_value;
- mode = MetaAttribute::kCharset;
- } else if (ThreadSafeMatch(attribute_name, contentAttr)) {
- charset = ExtractCharset(attribute_value);
- if (charset.length())
- mode = MetaAttribute::kPragma;
- }
+ } else if (ThreadSafeMatch(attribute_name, charsetAttr)) {
+ has_charset = true;
+ charset = attribute_value;
+ mode = MetaAttribute::kCharset;
+ } else if (!has_charset && ThreadSafeMatch(attribute_name, contentAttr)) {
+ charset = ExtractCharset(attribute_value);
+ if (charset.length())
+ mode = MetaAttribute::kPragma;
}
}
@@ -440,7 +440,7 @@ inline StringImpl* FindStringIfStatic(const CharType* characters,
return it->value;
}
-String AttemptStaticStringCreation(const LChar* characters, size_t size) {
+String AttemptStaticStringCreation(const LChar* characters, wtf_size_t size) {
String string(FindStringIfStatic(characters, size));
if (string.Impl())
return string;
@@ -448,7 +448,7 @@ String AttemptStaticStringCreation(const LChar* characters, size_t size) {
}
String AttemptStaticStringCreation(const UChar* characters,
- size_t size,
+ wtf_size_t size,
CharacterWidth width) {
String string(FindStringIfStatic(characters, size));
if (string.Impl())
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_parser_idioms.h b/chromium/third_party/blink/renderer/core/html/parser/html_parser_idioms.h
index 81dd1b81a07..ac928bb675f 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/html_parser_idioms.h
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_parser_idioms.h
@@ -121,11 +121,11 @@ bool ThreadSafeMatch(const String&, const QualifiedName&);
enum CharacterWidth { kLikely8Bit, kForce8Bit, kForce16Bit };
-String AttemptStaticStringCreation(const LChar*, size_t);
+String AttemptStaticStringCreation(const LChar*, wtf_size_t);
-String AttemptStaticStringCreation(const UChar*, size_t, CharacterWidth);
+String AttemptStaticStringCreation(const UChar*, wtf_size_t, CharacterWidth);
-template <size_t inlineCapacity>
+template <wtf_size_t inlineCapacity>
inline static String AttemptStaticStringCreation(
const Vector<UChar, inlineCapacity>& vector,
CharacterWidth width) {
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 6f69497460a..d2fdce1f266 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
@@ -25,6 +25,8 @@
#include "third_party/blink/renderer/core/html/parser/html_parser_scheduler.h"
+#include "base/feature_list.h"
+#include "base/metrics/field_trial_params.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_thread.h"
#include "third_party/blink/renderer/core/dom/document.h"
@@ -35,6 +37,10 @@
namespace blink {
+const base::Feature kHTMLParsingYieldTime {
+ "HTMLParsingYieldTime", base::FEATURE_DISABLED_BY_DEFAULT
+};
+
PumpSession::PumpSession(unsigned& nesting_level)
: NestingLevelIncrementer(nesting_level) {}
@@ -55,12 +61,18 @@ void SpeculationsPumpSession::AddedElementTokens(size_t count) {
processed_element_tokens_ += count;
}
+const double kDefaultParserTimeLimit = 0.5;
+
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) {}
+ is_paused_with_active_timer_(false),
+ parser_time_limit_(
+ base::GetFieldTrialParamByFeatureAsDouble(kHTMLParsingYieldTime,
+ "limit",
+ kDefaultParserTimeLimit)) {}
HTMLParserScheduler::~HTMLParserScheduler() = default;
@@ -111,8 +123,7 @@ inline bool HTMLParserScheduler::ShouldYield(
->ShouldYieldForHighPriorityWork())
return true;
- const double kParserTimeLimit = 0.5;
- if (session.ElapsedTime() > kParserTimeLimit)
+ if (session.ElapsedTime() > parser_time_limit_)
return true;
// Yield if a lot of DOM work has been done in this session and a script tag
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 73b5506500d..12f950acb75 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
@@ -105,6 +105,7 @@ class HTMLParserScheduler final
TaskHandle cancellable_continue_parse_task_handle_;
bool is_paused_with_active_timer_;
+ const double parser_time_limit_;
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 3feabddb03a..3bc30470a70 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
@@ -308,6 +308,11 @@ class TokenPreloadScanner::StartTagScanner {
language_attribute_value_ = attribute_value;
} else if (Match(attribute_name, nomoduleAttr)) {
nomodule_attribute_value_ = true;
+ } else if (!referrer_policy_set_ &&
+ Match(attribute_name, referrerpolicyAttr) &&
+ !attribute_value.IsNull()) {
+ SetReferrerPolicy(attribute_value,
+ kDoNotSupportReferrerPolicyLegacyKeywords);
}
}
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 e3b72a13d59..02f099d5785 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
@@ -130,7 +130,7 @@ class HTMLMockHTMLResourcePreloader : public ResourcePreloader {
Document* document,
const char* expected_referrer) {
PreloadRequestVerification(type, url, base_url, width, referrer_policy);
- Resource* resource = preload_request_->Start(document, nullptr);
+ Resource* resource = preload_request_->Start(document);
ASSERT_TRUE(resource);
EXPECT_EQ(expected_referrer, resource->GetResourceRequest().HttpReferrer());
}
@@ -150,7 +150,7 @@ class HTMLMockHTMLResourcePreloader : public ResourcePreloader {
network::mojom::FetchRequestMode request_mode,
network::mojom::FetchCredentialsMode credentials_mode) {
ASSERT_TRUE(preload_request_.get());
- Resource* resource = preload_request_->Start(document, nullptr);
+ Resource* resource = preload_request_->Start(document);
ASSERT_TRUE(resource);
EXPECT_EQ(request_mode,
resource->GetResourceRequest().GetFetchRequestMode());
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_resource_preloader.cc b/chromium/third_party/blink/renderer/core/html/parser/html_resource_preloader.cc
index a2d1538ac03..d89dfaab23e 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/html_resource_preloader.cc
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_resource_preloader.cc
@@ -30,7 +30,6 @@
#include "third_party/blink/renderer/core/frame/deprecation.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/loader/document_loader.h"
-#include "third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
@@ -45,7 +44,6 @@ HTMLResourcePreloader* HTMLResourcePreloader::Create(Document& document) {
void HTMLResourcePreloader::Trace(blink::Visitor* visitor) {
visitor->Trace(document_);
- visitor->Trace(css_preloaders_);
}
int HTMLResourcePreloader::CountPreloads() {
@@ -76,19 +74,7 @@ void HTMLResourcePreloader::Preload(
if (!document_->Loader())
return;
- CSSPreloaderResourceClient* client = nullptr;
- // Don't scan a Resource more than once, to avoid a self-referencing
- // stlyesheet causing infinite recursion.
- if (!css_preloaders_.Contains(preload->ResourceURL()) &&
- preload->ResourceType() == Resource::kCSSStyleSheet) {
- Settings* settings = document_->GetSettings();
- if (settings && (settings->GetCSSExternalScannerNoPreload() ||
- settings->GetCSSExternalScannerPreload())) {
- client = new CSSPreloaderResourceClient(this);
- css_preloaders_.insert(preload->ResourceURL(), client);
- }
- }
- preload->Start(document_, client);
+ preload->Start(document_);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_resource_preloader.h b/chromium/third_party/blink/renderer/core/html/parser/html_resource_preloader.h
index cdc70967a1c..4eb9de5a91d 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/html_resource_preloader.h
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_resource_preloader.h
@@ -29,7 +29,6 @@
#include <memory>
#include "base/macros.h"
-#include "third_party/blink/renderer/core/html/parser/css_preload_scanner.h"
#include "third_party/blink/renderer/core/html/parser/preload_request.h"
#include "third_party/blink/renderer/core/html/parser/resource_preloader.h"
#include "third_party/blink/renderer/core/loader/network_hints_interface.h"
@@ -59,7 +58,6 @@ class CORE_EXPORT HTMLResourcePreloader
private:
Member<Document> document_;
- HeapHashMap<String, Member<CSSPreloaderResourceClient>> css_preloaders_;
DISALLOW_COPY_AND_ASSIGN(HTMLResourcePreloader);
};
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 37d3d704128..e008d75a778 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
@@ -24,8 +24,7 @@ KURL PreloadRequest::CompleteURL(Document* document) {
return document->CompleteURL(resource_url_);
}
-Resource* PreloadRequest::Start(Document* document,
- CSSPreloaderResourceClient* client) {
+Resource* PreloadRequest::Start(Document* document) {
DCHECK(IsMainThread());
FetchInitiatorInfo initiator_info;
@@ -37,11 +36,10 @@ Resource* PreloadRequest::Start(Document* document,
DCHECK(!url.ProtocolIsData());
ResourceRequest resource_request(url);
- resource_request.SetHTTPReferrer(SecurityPolicy::GenerateReferrer(
- referrer_policy_, url,
- referrer_source_ == kBaseUrlIsReferrer
- ? base_url_.StrippedForUseAsReferrer()
- : document->OutgoingReferrer()));
+ resource_request.SetReferrerPolicy(referrer_policy_);
+ if (referrer_source_ == kBaseUrlIsReferrer)
+ resource_request.SetReferrerString(base_url_.StrippedForUseAsReferrer());
+
resource_request.SetRequestContext(ResourceFetcher::DetermineRequestContext(
resource_type_, is_image_set_, false));
@@ -102,7 +100,7 @@ Resource* PreloadRequest::Start(Document* document,
// the async request to the blocked script here.
}
- return document->Loader()->StartPreload(resource_type_, params, client);
+ return document->Loader()->StartPreload(resource_type_, params);
}
} // 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 04d1ac5f95c..89f944b03a6 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
@@ -23,7 +23,6 @@
namespace blink {
-class CSSPreloaderResourceClient;
class Document;
class CORE_EXPORT PreloadRequest {
@@ -68,7 +67,7 @@ class CORE_EXPORT PreloadRequest {
referrer_policy, referrer_source, is_image_set));
}
- Resource* Start(Document*, CSSPreloaderResourceClient*);
+ Resource* Start(Document*);
void SetDefer(FetchParameters::DeferOption defer) { defer_ = defer; }
void SetCharset(const String& charset) { charset_ = charset; }
diff --git a/chromium/third_party/blink/renderer/core/html/parser/xss_auditor.cc b/chromium/third_party/blink/renderer/core/html/parser/xss_auditor.cc
index edb8d5c33e7..15c5e9263c3 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/xss_auditor.cc
+++ b/chromium/third_party/blink/renderer/core/html/parser/xss_auditor.cc
@@ -151,7 +151,7 @@ static bool StartsClosingScriptTagAt(const String& string, size_t start) {
// If other files need this, we should move this to
// core/html/parser/HTMLParserIdioms.h
-template <size_t inlineCapacity>
+template <wtf_size_t inlineCapacity>
bool ThreadSafeMatch(const Vector<UChar, inlineCapacity>& vector,
const QualifiedName& qname) {
return EqualIgnoringNullity(vector, qname.LocalName().Impl());
diff --git a/chromium/third_party/blink/renderer/core/html/parser/xss_auditor.h b/chromium/third_party/blink/renderer/core/html/parser/xss_auditor.h
index c15a1dcf200..3cdaa407429 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/xss_auditor.h
+++ b/chromium/third_party/blink/renderer/core/html/parser/xss_auditor.h
@@ -45,6 +45,8 @@ class XSSAuditorDelegate;
struct FilterTokenRequest {
STACK_ALLOCATED();
+
+ public:
FilterTokenRequest(HTMLToken& token,
HTMLSourceTracker& source_tracker,
bool should_allow_cdata)
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 0a9ae8d42af..9c5746dd5ba 100644
--- a/chromium/third_party/blink/renderer/core/html/plugin_document.cc
+++ b/chromium/third_party/blink/renderer/core/html/plugin_document.cc
@@ -26,6 +26,7 @@
#include "third_party/blink/renderer/core/css/css_color_value.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
+#include "third_party/blink/renderer/core/dom/events/event_listener.h"
#include "third_party/blink/renderer/core/dom/raw_data_document_parser.h"
#include "third_party/blink/renderer/core/events/before_unload_event.h"
#include "third_party/blink/renderer/core/exported/web_plugin_container_impl.h"
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
new file mode 100644
index 00000000000..58d40cd193b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/html/portal/html_portal_element.cc
@@ -0,0 +1,80 @@
+// 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/html/portal/html_portal_element.h"
+
+#include "services/service_manager/public/cpp/interface_provider.h"
+#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
+#include "third_party/blink/renderer/core/html/html_unknown_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/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+
+namespace blink {
+
+HTMLPortalElement::HTMLPortalElement(Document& document)
+ : HTMLFrameOwnerElement(HTMLNames::portalTag, document) {}
+
+HTMLPortalElement::~HTMLPortalElement() {}
+
+HTMLElement* HTMLPortalElement::Create(Document& document) {
+ if (RuntimeEnabledFeatures::PortalsEnabled())
+ return new HTMLPortalElement(document);
+ return HTMLUnknownElement::Create(HTMLNames::portalTag, document);
+}
+
+void HTMLPortalElement::Navigate() {
+ KURL url = GetNonEmptyURLAttribute(HTMLNames::srcAttr);
+ if (!url.IsEmpty() && portal_ptr_) {
+ portal_ptr_->Navigate(url);
+ }
+}
+
+HTMLPortalElement::InsertionNotificationRequest HTMLPortalElement::InsertedInto(
+ ContainerNode& node) {
+ auto result = HTMLFrameOwnerElement::InsertedInto(node);
+
+ Document& document = GetDocument();
+
+ if (node.IsInDocumentTree() && document.IsHTMLDocument()) {
+ document.GetFrame()->GetInterfaceProvider().GetInterface(
+ mojo::MakeRequest(&portal_ptr_));
+ portal_ptr_->Init(WTF::Bind(
+ [](HTMLPortalElement* portal,
+ const base::UnguessableToken& portal_token) {
+ portal->portal_token_ = portal_token;
+ },
+ WrapPersistent(this)));
+ Navigate();
+ }
+
+ return result;
+}
+
+void HTMLPortalElement::RemovedFrom(ContainerNode& node) {
+ HTMLFrameOwnerElement::RemovedFrom(node);
+
+ Document& document = GetDocument();
+
+ if (node.IsInDocumentTree() && document.IsHTMLDocument()) {
+ portal_ptr_.reset();
+ }
+}
+
+bool HTMLPortalElement::IsURLAttribute(const Attribute& attribute) const {
+ return attribute.GetName() == HTMLNames::srcAttr ||
+ HTMLFrameOwnerElement::IsURLAttribute(attribute);
+}
+
+void HTMLPortalElement::ParseAttribute(
+ const AttributeModificationParams& params) {
+ HTMLFrameOwnerElement::ParseAttribute(params);
+
+ if (params.name == HTMLNames::srcAttr)
+ Navigate();
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..85a58889aab
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/html/portal/html_portal_element.h
@@ -0,0 +1,61 @@
+// 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_HTML_PORTAL_HTML_PORTAL_ELEMENT_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_PORTAL_HTML_PORTAL_ELEMENT_H_
+
+#include "base/unguessable_token.h"
+#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/node.h"
+#include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
+
+namespace blink {
+
+class Document;
+
+// The HTMLPortalElement implements the <portal> HTML element. The portal
+// element can be used to embed another top-level browsing context, which can be
+// activated using script. The portal element is still under development and not
+// part of the HTML standard. It can be enabled by passing
+// --enable-features=Portals. See
+// https://github.com/KenjiBaheux/portals/blob/master/explainer.md for more
+// details.
+class CORE_EXPORT HTMLPortalElement : public HTMLFrameOwnerElement {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ static HTMLElement* Create(Document&);
+
+ ~HTMLPortalElement() override;
+
+ private:
+ explicit HTMLPortalElement(Document&);
+
+ // Navigates the portal to |url_|.
+ void Navigate();
+
+ // Node overrides
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
+ void RemovedFrom(ContainerNode&) override;
+
+ // Element overrides
+ bool IsURLAttribute(const Attribute&) const override;
+ void ParseAttribute(const AttributeModificationParams&) override;
+
+ // HTMLFrameOwnerElement overrides
+ ParsedFeaturePolicy ConstructContainerPolicy(Vector<String>*) const override {
+ return ParsedFeaturePolicy();
+ }
+
+ // Uniquely identifies the portal, this token is used by the browser process
+ // to reference this portal when communicating with the renderer.
+ base::UnguessableToken portal_token_;
+
+ mojom::blink::PortalPtr portal_ptr_;
+};
+
+} // 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
new file mode 100644
index 00000000000..01d321197ef
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/html/portal/html_portal_element.idl
@@ -0,0 +1,10 @@
+// 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/KenjiBaheux/portals/blob/master/explainer.md
+
+[HTMLConstructor, RuntimeEnabled=Portals]
+interface HTMLPortalElement : HTMLElement {
+ [CEReactions, Reflect, URL, RaisesException=Setter] attribute URLString src;
+};
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 323b423a0e4..8c926360eaf 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
@@ -61,7 +61,7 @@ DEFINE_NODE_FACTORY(HTMLTrackElement)
HTMLTrackElement::~HTMLTrackElement() = default;
Node::InsertionNotificationRequest HTMLTrackElement::InsertedInto(
- ContainerNode* insertion_point) {
+ ContainerNode& insertion_point) {
DVLOG(TRACK_LOG_LEVEL) << "insertedInto";
// Since we've moved to a new parent, we may now be able to load.
@@ -69,14 +69,14 @@ Node::InsertionNotificationRequest HTMLTrackElement::InsertedInto(
HTMLElement::InsertedInto(insertion_point);
HTMLMediaElement* parent = MediaElement();
- if (insertion_point == parent)
+ if (&insertion_point == parent)
parent->DidAddTrackElement(this);
return kInsertionDone;
}
-void HTMLTrackElement::RemovedFrom(ContainerNode* insertion_point) {
- if (!parentNode() && IsHTMLMediaElement(*insertion_point))
- ToHTMLMediaElement(insertion_point)->DidRemoveTrackElement(this);
+void HTMLTrackElement::RemovedFrom(ContainerNode& insertion_point) {
+ if (!parentNode() && IsHTMLMediaElement(insertion_point))
+ ToHTMLMediaElement(insertion_point).DidRemoveTrackElement(this);
HTMLElement::RemovedFrom(insertion_point);
}
@@ -259,7 +259,7 @@ void HTMLTrackElement::DidCompleteLoad(LoadStatus status) {
// simple event named error at the track element.
if (status == kFailure) {
SetReadyState(kError);
- DispatchEvent(Event::Create(EventTypeNames::error));
+ DispatchEvent(*Event::Create(EventTypeNames::error));
return;
}
@@ -269,7 +269,7 @@ void HTMLTrackElement::DidCompleteLoad(LoadStatus status) {
// readiness state to loaded, and fire a simple event named load at the track
// element.
SetReadyState(kLoaded);
- DispatchEvent(Event::Create(EventTypeNames::load));
+ DispatchEvent(*Event::Create(EventTypeNames::load));
}
void HTMLTrackElement::NewCuesAvailable(TextTrackLoader* loader) {
diff --git a/chromium/third_party/blink/renderer/core/html/track/html_track_element.h b/chromium/third_party/blink/renderer/core/html/track/html_track_element.h
index f33b45388c8..bce64ced060 100644
--- a/chromium/third_party/blink/renderer/core/html/track/html_track_element.h
+++ b/chromium/third_party/blink/renderer/core/html/track/html_track_element.h
@@ -61,9 +61,9 @@ class HTMLTrackElement final : public HTMLElement,
void ParseAttribute(const AttributeModificationParams&) override;
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
- void RemovedFrom(ContainerNode*) override;
+ void RemovedFrom(ContainerNode&) override;
bool IsURLAttribute(const Attribute&) const override;
// TextTrackLoaderClient
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 2b39733f1f4..bec2694660a 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
@@ -29,6 +29,7 @@
#include "third_party/blink/renderer/core/html/track/text_track_container.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/html/media/html_video_element.h"
#include "third_party/blink/renderer/core/html/track/cue_timeline.h"
#include "third_party/blink/renderer/core/html/track/text_track.h"
@@ -112,6 +113,8 @@ void TextTrackContainer::UpdateDefaultFontSize(
LayoutUnit smallest_dimension =
std::min(video_size.Height(), video_size.Width());
float font_size = smallest_dimension * 0.05f;
+ if (media_layout_object->GetFrame())
+ font_size /= media_layout_object->GetFrame()->PageZoomFactor();
// Avoid excessive FP precision issue.
// C11 5.2.4.2.2:9 requires assignment and cast to remove extra precision, but
diff --git a/chromium/third_party/blink/renderer/core/html/track/text_track_cue.cc b/chromium/third_party/blink/renderer/core/html/track/text_track_cue.cc
index dd087a5a5a9..2c037af48f5 100644
--- a/chromium/third_party/blink/renderer/core/html/track/text_track_cue.cc
+++ b/chromium/third_party/blink/renderer/core/html/track/text_track_cue.cc
@@ -120,7 +120,7 @@ unsigned TextTrackCue::CueIndex() {
return cue_index_;
}
-DispatchEventResult TextTrackCue::DispatchEventInternal(Event* event) {
+DispatchEventResult TextTrackCue::DispatchEventInternal(Event& event) {
// When a TextTrack's mode is disabled: no cues are active, no events fired.
if (!track() || track()->mode() == TextTrack::DisabledKeyword())
return DispatchEventResult::kCanceledBeforeDispatch;
diff --git a/chromium/third_party/blink/renderer/core/html/track/text_track_cue.h b/chromium/third_party/blink/renderer/core/html/track/text_track_cue.h
index ab7eac0c101..51d3734993d 100644
--- a/chromium/third_party/blink/renderer/core/html/track/text_track_cue.h
+++ b/chromium/third_party/blink/renderer/core/html/track/text_track_cue.h
@@ -109,7 +109,7 @@ class TextTrackCue : public EventTargetWithInlineData {
void CueWillChange();
virtual void CueDidChange(
CueMutationAffectsOrder = kCueMutationDoesNotAffectOrder);
- DispatchEventResult DispatchEventInternal(Event*) override;
+ DispatchEventResult DispatchEventInternal(Event&) override;
private:
AtomicString id_;
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 1e347714595..a9c5149b524 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
@@ -245,7 +245,7 @@ ExecutionContext* TextTrackList::GetExecutionContext() const {
void TextTrackList::ScheduleTrackEvent(const AtomicString& event_name,
TextTrack* track) {
- EnqueueEvent(TrackEvent::Create(event_name, track),
+ EnqueueEvent(*TrackEvent::Create(event_name, track),
TaskType::kMediaElementEvent);
}
@@ -267,7 +267,7 @@ void TextTrackList::ScheduleChangeEvent() {
// ...
// Fire a simple event named change at the media element's textTracks
// attribute's TextTrackList object.
- EnqueueEvent(Event::Create(EventTypeNames::change),
+ EnqueueEvent(*Event::Create(EventTypeNames::change),
TaskType::kMediaElementEvent);
}
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 098bff15260..59271258e49 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
@@ -47,6 +47,8 @@ using VTTRegionMap = HeapHashMap<String, Member<VTTRegion>>;
struct VTTDisplayParameters {
STACK_ALLOCATED();
+
+ public:
VTTDisplayParameters();
FloatPoint position;
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 0aa57d0afb6..41e6233754c 100644
--- a/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc
+++ b/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc
@@ -18,6 +18,7 @@
#include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h"
#include "third_party/blink/renderer/platform/image-decoders/image_decoder.h"
#include "third_party/blink/renderer/platform/scheduler/public/background_scheduler.h"
+#include "third_party/blink/renderer/platform/wtf/saturated_arithmetic.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkColorSpaceXformCanvas.h"
#include "third_party/skia/include/core/SkImageInfo.h"
@@ -43,10 +44,19 @@ namespace {
// The following two functions are helpers used in cropImage
static inline IntRect NormalizeRect(const IntRect& rect) {
- return IntRect(std::min(rect.X(), rect.MaxX()),
- std::min(rect.Y(), rect.MaxY()),
- std::max(rect.Width(), -rect.Width()),
- std::max(rect.Height(), -rect.Height()));
+ int x = rect.X();
+ int y = rect.Y();
+ int width = rect.Width();
+ int height = rect.Height();
+ if (width < 0) {
+ x = ClampAdd(x, width);
+ width = -width;
+ }
+ if (height < 0) {
+ y = ClampAdd(y, height);
+ height = -height;
+ }
+ return IntRect(x, y, width, height);
}
ImageBitmap::ParsedOptions ParseOptions(const ImageBitmapOptions& options,
@@ -613,7 +623,8 @@ ImageBitmap::ImageBitmap(HTMLVideoElement* video,
0, // msaa_sample_count
CanvasColorParams(), // TODO: set color space here to avoid clamping
CanvasResourceProvider::kDefaultPresentationMode,
- nullptr); // canvas_resource_dispatcher
+ nullptr, // canvas_resource_dispatcher
+ IsAccelerated()); // is_origin_top_left
if (!resource_provider)
return;
diff --git a/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap_options.idl b/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap_options.idl
index 8dec004d448..9fcdca02f1c 100644
--- a/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap_options.idl
+++ b/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap_options.idl
@@ -7,12 +7,12 @@
enum ImageOrientation { "none", "flipY" };
enum PremultiplyAlpha { "none", "premultiply", "default" };
enum ColorSpaceConversion { "none", "default", "srgb", "linear-rgb", "rec2020", "p3" };
-[RuntimeEnabled=ExtendedImageBitmapOptions] enum ResizeQuality { "pixelated", "low", "medium", "high" };
+enum ResizeQuality { "pixelated", "low", "medium", "high" };
dictionary ImageBitmapOptions {
ImageOrientation imageOrientation = "none";
PremultiplyAlpha premultiplyAlpha = "default";
ColorSpaceConversion colorSpaceConversion = "default";
- [RuntimeEnabled=ExtendedImageBitmapOptions, EnforceRange] unsigned long resizeWidth;
- [RuntimeEnabled=ExtendedImageBitmapOptions, EnforceRange] unsigned long resizeHeight;
- [RuntimeEnabled=ExtendedImageBitmapOptions] ResizeQuality resizeQuality = "low";
+ [EnforceRange] unsigned long resizeWidth;
+ [EnforceRange] unsigned long resizeHeight;
+ ResizeQuality resizeQuality = "low";
};
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 5387f4ab222..c25c6f98f98 100644
--- a/chromium/third_party/blink/renderer/core/input/event_handler.cc
+++ b/chromium/third_party/blink/renderer/core/input/event_handler.cc
@@ -87,6 +87,8 @@
#include "third_party/blink/renderer/core/page/touch_adjustment.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_animator_base.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar.h"
#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"
@@ -96,8 +98,6 @@
#include "third_party/blink/renderer/platform/histogram.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/scroll/scroll_animator_base.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar.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/std_lib_extras.h"
@@ -287,12 +287,12 @@ HitTestResult EventHandler::HitTestResultAtLocation(
HitTestLocation adjusted_location(
(LayoutRect(main_content_point, location.BoundingBox().Size())));
return main_frame.GetEventHandler().HitTestResultAtLocation(
- adjusted_location, hit_type, stop_node);
+ adjusted_location, hit_type, stop_node, no_lifecycle_update);
} else {
HitTestLocation adjusted_location(main_view->ConvertFromRootFrame(
frame_view->ConvertToRootFrame(location.Point())));
return main_frame.GetEventHandler().HitTestResultAtLocation(
- adjusted_location, hit_type, stop_node);
+ adjusted_location, hit_type, stop_node, no_lifecycle_update);
}
}
}
@@ -437,7 +437,7 @@ EventHandler::OptionalCursor EventHandler::SelectCursor(
if (scroll_manager_->MiddleClickAutoscrollInProgress())
return kNoCursorChange;
- if (result.GetScrollbar())
+ if (result.GetScrollbar() && !result.GetScrollbar()->IsCustomScrollbar())
return PointerCursor();
Node* node = result.InnerPossiblyPseudoNode();
@@ -964,11 +964,11 @@ WebInputEventResult EventHandler::HandleMouseMoveOrLeaveEvent(
event_result = DispatchMousePointerEvent(
WebInputEvent::kPointerMove, mev.InnerNode(), mev.CanvasRegionId(),
mev.Event(), coalesced_events);
+ // TODO(crbug.com/346473): Since there is no default action for the mousemove
+ // event we should consider doing drag&drop even when js cancels the
+ // mouse move event.
// https://w3c.github.io/uievents/#event-type-mousemove
- // Since there is no default action for the mousemove event issue a
- // mouse dragged event irrespective of whether the event is cancelled.
- if (event_result != WebInputEventResult::kNotHandled &&
- event_result != WebInputEventResult::kHandledApplication)
+ if (event_result != WebInputEventResult::kNotHandled)
return event_result;
return mouse_event_manager_->HandleMouseDraggedEvent(mev);
@@ -1766,10 +1766,9 @@ GestureEventWithHitTestResults EventHandler::HitTestResultForGestureEvent(
LocalFrame* hit_frame = hit_test_result.InnerNodeFrame();
if (!hit_frame)
hit_frame = frame_;
- location = HitTestLocation(hit_frame->View()->ConvertFromRootFrame(
- LayoutPoint(adjusted_event.PositionInRootFrame())));
- hit_test_result = EventHandlingUtil::HitTestResultInFrame(
- hit_frame, location,
+ location = HitTestLocation(adjusted_event.PositionInRootFrame());
+ hit_test_result = root_frame.GetEventHandler().HitTestResultAtLocation(
+ location,
(hit_type | HitTestRequest::kReadOnly) & ~HitTestRequest::kListBased);
}
// If we did a rect-based hit test it must be resolved to the best single node
@@ -1925,9 +1924,8 @@ WebInputEventResult EventHandler::ShowNonLocatedContextMenu(
IntPoint location_in_viewport =
visual_viewport.RootFrameToViewport(location_in_root_frame);
IntPoint global_position =
- ToChromeClient(view->GetChromeClient())
- ->ViewportToScreen(IntRect(location_in_viewport, IntSize()),
- frame_->View())
+ view->GetChromeClient()->ViewportToScreen(
+ IntRect(location_in_viewport, IntSize()), frame_->View())
.Location();
Node* target_node =
@@ -2110,7 +2108,7 @@ bool EventHandler::HandleTextInputEvent(const String& text,
TextEvent* event = TextEvent::Create(frame_->DomWindow(), text, input_type);
event->SetUnderlyingEvent(underlying_event);
- target->DispatchEvent(event);
+ target->DispatchEvent(*event);
return event->DefaultHandled() || event->defaultPrevented();
}
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 399af96b68e..c8947ab4b56 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
@@ -8,6 +8,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/range.h"
+#include "third_party/blink/renderer/core/editing/editing_behavior.h"
#include "third_party/blink/renderer/core/editing/editor.h"
#include "third_party/blink/renderer/core/editing/ephemeral_range.h"
#include "third_party/blink/renderer/core/editing/frame_selection.h"
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 0ee5fc42034..9c9612c58ee 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
@@ -11,7 +11,7 @@
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
-#include "third_party/blink/renderer/platform/scroll/scrollable_area.h"
+#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
namespace blink {
namespace EventHandlingUtil {
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 dbe687c2fe8..6f7d66c407e 100644
--- a/chromium/third_party/blink/renderer/core/input/gesture_manager.cc
+++ b/chromium/third_party/blink/renderer/core/input/gesture_manager.cc
@@ -10,6 +10,7 @@
#include "third_party/blink/renderer/core/dom/user_gesture_indicator.h"
#include "third_party/blink/renderer/core/editing/selection_controller.h"
#include "third_party/blink/renderer/core/events/gesture_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/settings.h"
@@ -20,7 +21,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/paint/paint_layer_scrollable_area.h"
-#include "third_party/blink/renderer/platform/scroll/scroll_animator_base.h"
+#include "third_party/blink/renderer/core/scroll/scroll_animator_base.h"
#if BUILDFLAG(ENABLE_UNHANDLED_TAP)
#include "services/service_manager/public/cpp/interface_provider.h"
@@ -103,7 +104,7 @@ WebInputEventResult GestureManager::HandleGestureEventInFrame(
event_target->GetDocument().domWindow(), gesture_event);
if (gesture_dom_event) {
DispatchEventResult gesture_dom_event_result =
- event_target->DispatchEvent(gesture_dom_event);
+ event_target->DispatchEvent(*gesture_dom_event);
if (gesture_dom_event_result != DispatchEventResult::kNotCanceled) {
DCHECK(gesture_dom_event_result !=
DispatchEventResult::kCanceledByEventHandler);
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 c38c46486fd..4d9cb5a389d 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
@@ -13,6 +13,7 @@
#include "third_party/blink/renderer/core/dom/user_gesture_indicator.h"
#include "third_party/blink/renderer/core/editing/editor.h"
#include "third_party/blink/renderer/core/events/keyboard_event.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/html/html_dialog_element.h"
#include "third_party/blink/renderer/core/input/event_handler.h"
@@ -221,7 +222,7 @@ WebInputEventResult KeyboardEventManager::KeyEvent(
initial_key_event, frame_->GetDocument()->domWindow());
return EventHandlingUtil::ToWebInputEventResult(
- node->DispatchEvent(dom_event));
+ node->DispatchEvent(*dom_event));
}
WebKeyboardEvent key_down_event = initial_key_event;
@@ -233,7 +234,7 @@ WebInputEventResult KeyboardEventManager::KeyEvent(
keydown->SetDefaultPrevented(true);
keydown->SetTarget(node);
- DispatchEventResult dispatch_result = node->DispatchEvent(keydown);
+ DispatchEventResult dispatch_result = node->DispatchEvent(*keydown);
if (dispatch_result != DispatchEventResult::kNotCanceled)
return EventHandlingUtil::ToWebInputEventResult(dispatch_result);
// If frame changed as a result of keydown dispatch, then return early to
@@ -273,7 +274,7 @@ WebInputEventResult KeyboardEventManager::KeyEvent(
key_press_event, frame_->GetDocument()->domWindow());
keypress->SetTarget(node);
return EventHandlingUtil::ToWebInputEventResult(
- node->DispatchEvent(keypress));
+ node->DispatchEvent(*keypress));
}
void KeyboardEventManager::CapsLockStateMayHaveChanged() {
@@ -410,7 +411,7 @@ void KeyboardEventManager::DefaultTabEventHandler(KeyboardEvent* event) {
void KeyboardEventManager::DefaultEscapeEventHandler(KeyboardEvent* event) {
if (HTMLDialogElement* dialog = frame_->GetDocument()->ActiveModalDialog())
- dialog->DispatchEvent(Event::CreateCancelable(EventTypeNames::cancel));
+ dialog->DispatchEvent(*Event::CreateCancelable(EventTypeNames::cancel));
}
static OverrideCapsLockState g_override_caps_lock_state;
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 79e0df06a96..cecfa6320c7 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
@@ -19,6 +19,7 @@
#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/events/web_input_event_conversion.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/settings.h"
@@ -256,7 +257,7 @@ WebInputEventResult MouseEventManager::DispatchMouseEvent(
: MouseEvent::kRealOrIndistinguishable,
mouse_event.menu_source_type);
- DispatchEventResult dispatch_result = target->DispatchEvent(event);
+ DispatchEventResult dispatch_result = target->DispatchEvent(*event);
return EventHandlingUtil::ToWebInputEventResult(dispatch_result);
}
return WebInputEventResult::kNotHandled;
@@ -1052,7 +1053,7 @@ WebInputEventResult MouseEventManager::DispatchDragEvent(
: MouseEvent::kRealOrIndistinguishable);
return EventHandlingUtil::ToWebInputEventResult(
- drag_target->DispatchEvent(me));
+ drag_target->DispatchEvent(*me));
}
void MouseEventManager::ClearDragDataTransfer() {
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 9c88c1d580c..3b3c9688a43 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
@@ -8,6 +8,7 @@
#include "third_party/blink/public/platform/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"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/input/event_handler.h"
#include "third_party/blink/renderer/core/input/event_handling_util.h"
@@ -58,8 +59,8 @@ WebInputEventResult MouseWheelEventManager::HandleWheelEvent(
bool has_phase_info = event.phase != WebMouseWheelEvent::kPhaseNone ||
event.momentum_phase != WebMouseWheelEvent::kPhaseNone;
if (!has_phase_info) {
- // Synthetic wheel events generated from GesturePinchUpdate don't have
- // phase info. Send these events to the target under the cursor.
+ // Wheel events generated from plugin and tests may not have phase info.
+ // Send these events to the target under the cursor.
wheel_target_ = FindTargetNode(event, doc, view);
} else if (event.phase == WebMouseWheelEvent::kPhaseBegan || !wheel_target_) {
// Find and save the wheel_target_, this target will be used for the rest
@@ -83,7 +84,7 @@ WebInputEventResult MouseWheelEventManager::HandleWheelEvent(
bool should_enforce_vertical_scroll =
wheel_target_->GetDocument().IsVerticalScrollEnforced();
DispatchEventResult dom_event_result =
- wheel_target_->DispatchEvent(dom_event);
+ wheel_target_->DispatchEvent(*dom_event);
if (dom_event_result != DispatchEventResult::kNotCanceled) {
// Reset the target if the dom event is cancelled to make sure that new
// targeting happens for the next wheel 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 1a981850154..b2af030b97d 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
@@ -7,6 +7,7 @@
#include "base/auto_reset.h"
#include "third_party/blink/public/platform/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"
#include "third_party/blink/renderer/core/dom/user_gesture_indicator.h"
#include "third_party/blink/renderer/core/events/mouse_event.h"
@@ -22,6 +23,7 @@
#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/core/page/pointer_lock_controller.h"
namespace blink {
@@ -31,7 +33,8 @@ size_t ToPointerTypeIndex(WebPointerProperties::PointerType t) {
return static_cast<size_t>(t);
}
bool HasPointerEventListener(const EventHandlerRegistry& registry) {
- return registry.HasEventHandlers(EventHandlerRegistry::kPointerEvent);
+ return registry.HasEventHandlers(EventHandlerRegistry::kPointerEvent) ||
+ registry.HasEventHandlers(EventHandlerRegistry::kPointerRawMoveEvent);
}
const AtomicString& MouseEventNameForPointerEventInputType(
@@ -49,6 +52,14 @@ const AtomicString& MouseEventNameForPointerEventInputType(
}
}
+Element* GetPointerLockedElement(LocalFrame* frame) {
+ if (Page* p = frame->GetPage()) {
+ if (!p->GetPointerLockController().LockPending())
+ return p->GetPointerLockController().GetElement();
+ }
+ return nullptr;
+}
+
} // namespace
PointerEventManager::PointerEventManager(LocalFrame& frame,
@@ -146,22 +157,8 @@ WebInputEventResult PointerEventManager::DispatchPointerEvent(
if (!target)
return WebInputEventResult::kNotHandled;
- // Set whether node under pointer has received pointerover or not.
const int pointer_id = pointer_event->pointerId();
-
const AtomicString& event_type = pointer_event->type();
- if ((event_type == EventTypeNames::pointerout ||
- event_type == EventTypeNames::pointerover) &&
- node_under_pointer_.Contains(pointer_id)) {
- EventTarget* target_under_pointer =
- node_under_pointer_.at(pointer_id).target;
- if (target_under_pointer == target) {
- node_under_pointer_.Set(
- pointer_id,
- EventTargetAttributes(target_under_pointer,
- event_type == EventTypeNames::pointerover));
- }
- }
if (!frame_ || !HasPointerEventListener(frame_->GetEventHandlerRegistry()))
return WebInputEventResult::kNotHandled;
@@ -181,7 +178,7 @@ WebInputEventResult PointerEventManager::DispatchPointerEvent(
DCHECK(!dispatching_pointer_id_);
base::AutoReset<int> dispatch_holder(&dispatching_pointer_id_, pointer_id);
- DispatchEventResult dispatch_result = target->DispatchEvent(pointer_event);
+ DispatchEventResult dispatch_result = target->DispatchEvent(*pointer_event);
return EventHandlingUtil::ToWebInputEventResult(dispatch_result);
}
return WebInputEventResult::kNotHandled;
@@ -240,12 +237,12 @@ void PointerEventManager::SetNodeUnderPointer(PointerEvent* pointer_event,
} else if (target !=
node_under_pointer_.at(pointer_event->pointerId()).target) {
node_under_pointer_.Set(pointer_event->pointerId(),
- EventTargetAttributes(target, false));
+ EventTargetAttributes(target));
}
SendBoundaryEvents(node.target, target, pointer_event);
} else if (target) {
node_under_pointer_.insert(pointer_event->pointerId(),
- EventTargetAttributes(target, false));
+ EventTargetAttributes(target));
SendBoundaryEvents(nullptr, target, pointer_event);
}
}
@@ -488,6 +485,44 @@ WebInputEventResult PointerEventManager::FlushEvents() {
WebInputEventResult PointerEventManager::HandlePointerEvent(
const WebPointerEvent& event,
const Vector<WebPointerEvent>& coalesced_events) {
+ if (event.GetType() == WebInputEvent::Type::kPointerRawMove) {
+ if (!RuntimeEnabledFeatures::PointerRawMoveEnabled() ||
+ !frame_->GetEventHandlerRegistry().HasEventHandlers(
+ EventHandlerRegistry::kPointerRawMoveEvent))
+ return WebInputEventResult::kHandledSystem;
+
+ // If the page has pointer lock active and the event was from
+ // mouse use the locked target as the target.
+ // TODO(nzolghadr): Consideration for locked element might fit
+ // better in ComputerPointerEventTarget but at this point it is
+ // not quite possible as we haven't merged the locked event
+ // dispatch with this path.
+ Node* target;
+ Element* pointer_locked_element = GetPointerLockedElement(frame_);
+ if (pointer_locked_element &&
+ event.pointer_type == WebPointerProperties::PointerType::kMouse) {
+ // The locked element could be in another frame. So we need to delegate
+ // sending the event to that frame.
+ LocalFrame* target_frame =
+ pointer_locked_element->GetDocument().GetFrame();
+ if (!target_frame)
+ return WebInputEventResult::kHandledSystem;
+ if (target_frame != frame_) {
+ target_frame->GetEventHandler().HandlePointerEvent(event,
+ coalesced_events);
+ return WebInputEventResult::kHandledSystem;
+ }
+ target = pointer_locked_element;
+ } else {
+ target = ComputePointerEventTarget(event).target_node;
+ }
+
+ PointerEvent* pointer_event = pointer_event_factory_.Create(
+ event, coalesced_events, frame_->GetDocument()->domWindow());
+ DispatchPointerEvent(target, pointer_event);
+ return WebInputEventResult::kHandledSystem;
+ }
+
if (event.GetType() == WebInputEvent::Type::kPointerCausedUaAction) {
HandlePointerInterruption(event);
return WebInputEventResult::kHandledSystem;
@@ -579,6 +614,18 @@ WebInputEventResult PointerEventManager::SendMousePointerEvent(
EventTarget* effective_target = GetEffectiveTargetForPointerEvent(
pointer_event_target, pointer_event->pointerId());
+ if ((event_type == WebInputEvent::kPointerDown ||
+ event_type == WebInputEvent::kPointerUp) &&
+ pointer_event->type() == EventTypeNames::pointermove &&
+ RuntimeEnabledFeatures::PointerRawMoveEnabled() &&
+ frame_->GetEventHandlerRegistry().HasEventHandlers(
+ EventHandlerRegistry::kPointerRawMoveEvent)) {
+ // This is a chorded button move event. We need to also send a
+ // pointerrawmove for it.
+ DispatchPointerEvent(
+ effective_target,
+ pointer_event_factory_.CreatePointerRawMoveEvent(pointer_event));
+ }
WebInputEventResult result =
DispatchPointerEvent(effective_target, pointer_event);
diff --git a/chromium/third_party/blink/renderer/core/input/pointer_event_manager.h b/chromium/third_party/blink/renderer/core/input/pointer_event_manager.h
index 7bf0088b4a5..a079904bc95 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
@@ -109,10 +109,9 @@ class CORE_EXPORT PointerEventManager
public:
void Trace(blink::Visitor* visitor) { visitor->Trace(target); }
Member<EventTarget> target;
- bool has_recieved_over_event;
- EventTargetAttributes() : target(nullptr), has_recieved_over_event(false) {}
- EventTargetAttributes(EventTarget* target, bool has_recieved_over_event)
- : target(target), has_recieved_over_event(has_recieved_over_event) {}
+ EventTargetAttributes() : target(nullptr) {}
+ EventTargetAttributes(EventTarget* target)
+ : target(target) {}
};
class PointerEventBoundaryEventDispatcher : public BoundaryEventDispatcher {
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 f2ffe18d24b..cb8ae7bdd86 100644
--- a/chromium/third_party/blink/renderer/core/input/scroll_manager.cc
+++ b/chromium/third_party/blink/renderer/core/input/scroll_manager.cc
@@ -9,6 +9,7 @@
#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/frame/browser_controls.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
#include "third_party/blink/renderer/core/input/event_handler.h"
@@ -26,9 +27,9 @@
#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/paint/paint_layer_scrollable_area.h"
+#include "third_party/blink/renderer/core/scroll/scroll_customization.h"
#include "third_party/blink/renderer/platform/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
-#include "third_party/blink/renderer/platform/scroll/scroll_customization.h"
namespace blink {
namespace {
@@ -57,6 +58,15 @@ SnapFlingController::GestureScrollUpdateInfo GetGestureScrollUpdateInfo(
.event_time = event.TimeStamp()};
}
+ScrollableArea* ScrollableAreaForSnapping(LayoutBox* layout_box) {
+ if (!layout_box)
+ return nullptr;
+
+ return layout_box->IsLayoutView()
+ ? layout_box->GetFrameView()->GetScrollableArea()
+ : layout_box->GetScrollableArea();
+}
+
} // namespace
ScrollManager::ScrollManager(LocalFrame& frame) : frame_(frame) {
@@ -120,7 +130,12 @@ AutoscrollController* ScrollManager::GetAutoscrollController() const {
static bool CanPropagate(const ScrollState& scroll_state,
const Element& element) {
- if (!element.GetLayoutBox()->GetScrollableArea())
+ ScrollableArea* scrollable_area = element.GetLayoutBox()->GetScrollableArea();
+ if (!scrollable_area)
+ return true;
+
+ if (!scrollable_area->UserInputScrollable(kHorizontalScrollbar) &&
+ !scrollable_area->UserInputScrollable(kVerticalScrollbar))
return true;
return (scroll_state.deltaXHint() == 0 ||
@@ -608,20 +623,14 @@ WebInputEventResult ScrollManager::HandleGestureScrollEnd(
}
LayoutBox* ScrollManager::LayoutBoxForSnapping() const {
+ if (!previous_gesture_scrolled_element_)
+ return nullptr;
Element* document_element = frame_->GetDocument()->documentElement();
return previous_gesture_scrolled_element_ == document_element
? frame_->GetDocument()->GetLayoutView()
: previous_gesture_scrolled_element_->GetLayoutBox();
}
-ScrollableArea* ScrollManager::ScrollableAreaForSnapping() const {
- Element* document_element = frame_->GetDocument()->documentElement();
- return previous_gesture_scrolled_element_ == document_element
- ? frame_->View()->GetScrollableArea()
- : previous_gesture_scrolled_element_->GetLayoutBox()
- ->GetScrollableArea();
-}
-
void ScrollManager::SnapAtGestureScrollEnd() {
if (!previous_gesture_scrolled_element_ ||
(!did_scroll_x_for_scroll_gesture_ && !did_scroll_y_for_scroll_gesture_))
@@ -654,7 +663,11 @@ bool ScrollManager::GetSnapFlingInfo(const gfx::Vector2dF& natural_displacement,
gfx::Vector2dF ScrollManager::ScrollByForSnapFling(
const gfx::Vector2dF& delta) {
- DCHECK(previous_gesture_scrolled_element_);
+ ScrollableArea* scrollable_area =
+ ScrollableAreaForSnapping(LayoutBoxForSnapping());
+ if (!scrollable_area)
+ return gfx::Vector2dF();
+
std::unique_ptr<ScrollStateData> scroll_state_data =
std::make_unique<ScrollStateData>();
@@ -672,13 +685,16 @@ gfx::Vector2dF ScrollManager::ScrollByForSnapFling(
previous_gesture_scrolled_element_);
CustomizedScroll(*scroll_state);
-
- ScrollableArea* scrollable_area = ScrollableAreaForSnapping();
FloatPoint end_position = scrollable_area->ScrollPosition();
return gfx::Vector2dF(end_position.X(), end_position.Y());
}
void ScrollManager::ScrollEndForSnapFling() {
+ if (current_scroll_chain_.empty()) {
+ NotifyScrollPhaseEndForCustomizedScroll();
+ ClearGestureScrollState();
+ return;
+ }
std::unique_ptr<ScrollStateData> scroll_state_data =
std::make_unique<ScrollStateData>();
scroll_state_data->is_ending = true;
@@ -800,7 +816,7 @@ WebInputEventResult ScrollManager::HandleGestureScrollEvent(
event_target->GetDocument().domWindow(), gesture_event);
if (gesture_dom_event) {
DispatchEventResult gesture_dom_event_result =
- event_target->DispatchEvent(gesture_dom_event);
+ event_target->DispatchEvent(*gesture_dom_event);
if (gesture_dom_event_result != DispatchEventResult::kNotCanceled) {
DCHECK(gesture_dom_event_result !=
DispatchEventResult::kCanceledByEventHandler);
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 72f0136a007..6053e47590a 100644
--- a/chromium/third_party/blink/renderer/core/input/scroll_manager.h
+++ b/chromium/third_party/blink/renderer/core/input/scroll_manager.h
@@ -27,7 +27,6 @@ class LocalFrame;
class PaintLayer;
class PaintLayerScrollableArea;
class Page;
-class ScrollableArea;
class Scrollbar;
class ScrollState;
class WebGestureEvent;
@@ -140,7 +139,6 @@ class CORE_EXPORT ScrollManager
void NotifyScrollPhaseEndForCustomizedScroll();
LayoutBox* LayoutBoxForSnapping() const;
- ScrollableArea* ScrollableAreaForSnapping() const;
// NOTE: If adding a new field to this class please ensure that it is
// cleared in |ScrollManager::clear()|.
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 e0b7f9c0d4f..ab29a7e495f 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
@@ -4,6 +4,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/local_dom_window.h"
#include "third_party/blink/renderer/core/input/event_handler.h"
#include "third_party/blink/renderer/core/input/scroll_manager.h"
#include "third_party/blink/renderer/core/layout/layout_box.h"
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 adc2e8d8a92..7448ec43283 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
@@ -12,6 +12,7 @@
#include "third_party/blink/renderer/core/events/touch_event.h"
#include "third_party/blink/renderer/core/frame/deprecation.h"
#include "third_party/blink/renderer/core/frame/event_handler_registry.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h"
#include "third_party/blink/renderer/core/input/event_handling_util.h"
@@ -478,7 +479,7 @@ TouchEventManager::DispatchTouchEventFromAccumulatdTouchPoints() {
current_touch_action_);
DispatchEventResult dom_dispatch_result =
- touch_event_target->DispatchEvent(touch_event);
+ touch_event_target->DispatchEvent(*touch_event);
event_result = EventHandlingUtil::MergeEventResult(
event_result,
diff --git a/chromium/third_party/blink/renderer/core/inspector/BUILD.gn b/chromium/third_party/blink/renderer/core/inspector/BUILD.gn
index f7e3da603ef..0c995cd84b1 100644
--- a/chromium/third_party/blink/renderer/core/inspector/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/inspector/BUILD.gn
@@ -77,14 +77,16 @@ blink_core_sources("inspector") {
"inspector_resource_content_loader.h",
"inspector_session.cc",
"inspector_session.h",
+ "inspector_session_state.cc",
+ "inspector_session_state.h",
"inspector_style_sheet.cc",
"inspector_style_sheet.h",
"inspector_task_runner.cc",
"inspector_task_runner.h",
+ "inspector_testing_agent.cc",
+ "inspector_testing_agent.h",
"inspector_trace_events.cc",
"inspector_trace_events.h",
- "inspector_tracing_agent.cc",
- "inspector_tracing_agent.h",
"inspector_worker_agent.cc",
"inspector_worker_agent.h",
"main_thread_debugger.cc",
@@ -175,8 +177,8 @@ inspector_protocol_generate("protocol_sources") {
"inspector/protocol/Security.h",
"inspector/protocol/Target.cpp",
"inspector/protocol/Target.h",
- "inspector/protocol/Tracing.cpp",
- "inspector/protocol/Tracing.h",
+ "inspector/protocol/Testing.cpp",
+ "inspector/protocol/Testing.h",
]
deps = [
diff --git a/chromium/third_party/blink/renderer/core/inspector/DEPS b/chromium/third_party/blink/renderer/core/inspector/DEPS
index 5676a4a419d..97ba2c0be13 100644
--- a/chromium/third_party/blink/renderer/core/inspector/DEPS
+++ b/chromium/third_party/blink/renderer/core/inspector/DEPS
@@ -1,5 +1,7 @@
include_rules = [
"+base/time/time_override.h",
+ "+base/sampling_heap_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",
diff --git a/chromium/third_party/blink/renderer/core/inspector/browser_protocol.pdl b/chromium/third_party/blink/renderer/core/inspector/browser_protocol.pdl
index b374349b8a4..7daf2e80eaf 100644
--- a/chromium/third_party/blink/renderer/core/inspector/browser_protocol.pdl
+++ b/chromium/third_party/blink/renderer/core/inspector/browser_protocol.pdl
@@ -480,6 +480,39 @@ domain Browser
# The window state. Default to normal.
optional WindowState windowState
+ experimental type PermissionType extends string
+ enum
+ accessibilityEvents
+ audioCapture
+ backgroundSync
+ clipboardRead
+ clipboardWrite
+ durableStorage
+ flash
+ geolocation
+ midi
+ midiSysex
+ notifications
+ paymentHandler
+ protectedMediaIdentifier
+ sensors
+ videoCapture
+
+ # Grant specific permissions to the given origin and reject all others.
+ experimental command grantPermissions
+ parameters
+ string origin
+ array of PermissionType permissions
+ # BrowserContext to override permissions. When omitted, default browser context is used.
+ optional Target.BrowserContextID browserContextId
+
+ # Reset all permission management for all origins.
+ experimental command resetPermissions
+ parameters
+ # BrowserContext to reset permissions. When omitted, default browser context is used.
+ optional Target.BrowserContextID browserContextId
+
+
# Close browser gracefully.
command close
@@ -2076,6 +2109,8 @@ experimental domain DOMSnapshot
# that are painted together will have the same index. Only provided if includePaintOrder in
# getSnapshot was true.
optional integer paintOrder
+ # Set to true to indicate the element begins a new stacking context.
+ optional boolean isStackingContext
# A subset of the full ComputedStyle as defined by the request whitelist.
type ComputedStyle extends object
@@ -2185,6 +2220,8 @@ experimental domain DOMSnapshot
array of Rectangle bounds
# Contents of the LayoutText, if any.
array of StringIndex text
+ # Stacking context information.
+ RareBooleanData stackingContexts
# Details of post layout rendered text positions. The exact layout should not be regarded as
# stable and may change between versions.
@@ -2909,6 +2946,13 @@ domain Input
# 0).
optional integer location
+ # This method emulates inserting text that doesn't come from a key press,
+ # for example an emoji keyboard or an IME.
+ experimental command insertText
+ parameters
+ # The text to insert.
+ string text
+
# Dispatches a mouse event to the page.
command dispatchMouseEvent
parameters
@@ -3407,6 +3451,20 @@ experimental domain Memory
type SamplingProfile extends object
properties
array of SamplingProfileNode samples
+ array of Module modules
+
+ # Executable module information
+ type Module extends object
+ properties
+ # Name of the module.
+ string name
+ # UUID of the module.
+ string uuid
+ # Base address where the module is loaded into memory. Encoded as a decimal
+ # or hexadecimal (0x prefixed) string.
+ string baseAddress
+ # Size of the module in bytes.
+ number size
# Network domain allows tracking network activities of the page. It exposes information about http,
# file, data and other requests and responses, their headers, bodies, timing, etc.
@@ -5218,6 +5276,14 @@ domain Page
# Clears seeded compilation cache.
experimental command clearCompilationCache
+ # Generates a report for testing.
+ experimental command generateTestReport
+ parameters
+ # Message to be displayed in the report.
+ string message
+ # Specifies the endpoint group to deliver the report to.
+ optional string group
+
event domContentEventFired
parameters
Network.MonotonicTime timestamp
@@ -5925,6 +5991,8 @@ domain Target
# Whether to pause new targets when attaching to them. Use `Runtime.runIfWaitingForDebugger`
# to run paused targets.
boolean waitForDebuggerOnStart
+ # Enables "flat" access to the session via specifying sessionId attribute in the commands.
+ experimental optional boolean flatten
# Controls whether to discover available targets and notify via
# `targetCreated/targetInfoChanged/targetDestroyed` events.
@@ -6117,3 +6185,16 @@ experimental domain Tracing
optional IO.StreamHandle stream
# Compression format of returned stream.
optional StreamCompression streamCompression
+
+# Testing domain is a dumping ground for the capabilities requires for browser or app testing that do not fit other
+# domains.
+experimental domain Testing
+ depends on Page
+
+ # Generates a report for testing.
+ command generateTestReport
+ parameters
+ # Message to be displayed in the report.
+ string message
+ # Specifies the endpoint group to deliver the report to.
+ optional string group
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 e31a9f246e7..ccd906e4959 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
@@ -158,7 +158,7 @@ float DevToolsHost::zoomFactor() {
float zoom_factor = frontend_frame_->PageZoomFactor();
// Cancel the device scale factor applied to the zoom factor in
// use-zoom-for-dsf mode.
- const PlatformChromeClient* client =
+ const ChromeClient* client =
frontend_frame_->View()->GetChromeClient();
float window_to_viewport_ratio = client->WindowToViewportScalar(1.0f);
return zoom_factor / window_to_viewport_ratio;
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 cdd317fd95c..daea2992340 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
@@ -33,11 +33,6 @@
#include "third_party/blink/renderer/platform/animation/timing_function.h"
#include "third_party/blink/renderer/platform/wtf/text/base64.h"
-namespace AnimationAgentState {
-static const char animationAgentEnabled[] = "animationAgentEnabled";
-static const char animationAgentPlaybackRate[] = "animationAgentPlaybackRate";
-} // namespace AnimationAgentState
-
namespace blink {
using protocol::Response;
@@ -49,30 +44,26 @@ InspectorAnimationAgent::InspectorAnimationAgent(
: inspected_frames_(inspected_frames),
css_agent_(css_agent),
v8_session_(v8_session),
- is_cloning_(false) {}
+ is_cloning_(false),
+ enabled_(&agent_state_, /*default_value=*/false),
+ playback_rate_(&agent_state_, /*default_value=*/1.0) {}
void InspectorAnimationAgent::Restore() {
- if (state_->booleanProperty(AnimationAgentState::animationAgentEnabled,
- false)) {
- enable();
- double playback_rate = 1;
- state_->getDouble(AnimationAgentState::animationAgentPlaybackRate,
- &playback_rate);
- setPlaybackRate(playback_rate);
- }
+ if (enabled_.Get())
+ setPlaybackRate(playback_rate_.Get());
}
Response InspectorAnimationAgent::enable() {
- state_->setBoolean(AnimationAgentState::animationAgentEnabled, true);
+ enabled_.Set(true);
instrumenting_agents_->addInspectorAnimationAgent(this);
return Response::OK();
}
Response InspectorAnimationAgent::disable() {
- setPlaybackRate(1);
+ setPlaybackRate(1.0);
for (const auto& clone : id_to_animation_clone_.Values())
clone->cancel();
- state_->setBoolean(AnimationAgentState::animationAgentEnabled, false);
+ enabled_.Clear();
instrumenting_agents_->removeInspectorAnimationAgent(this);
id_to_animation_.clear();
id_to_animation_type_.clear();
@@ -88,10 +79,7 @@ void InspectorAnimationAgent::DidCommitLoadForLocalFrame(LocalFrame* frame) {
id_to_animation_clone_.clear();
cleared_animations_.clear();
}
- double playback_rate = 1;
- state_->getDouble(AnimationAgentState::animationAgentPlaybackRate,
- &playback_rate);
- setPlaybackRate(playback_rate);
+ setPlaybackRate(playback_rate_.Get());
}
static std::unique_ptr<protocol::Animation::AnimationEffect>
@@ -155,7 +143,7 @@ BuildObjectForAnimationKeyframes(const KeyframeEffect* effect) {
keyframes = protocol::Array<protocol::Animation::KeyframeStyle>::create();
for (size_t i = 0; i < model->GetFrames().size(); i++) {
- const Keyframe* keyframe = model->GetFrames().at(i).get();
+ const Keyframe* keyframe = model->GetFrames().at(i);
// Ignore CSS Transitions
if (!keyframe->IsStringKeyframe())
continue;
@@ -234,8 +222,7 @@ Response InspectorAnimationAgent::getPlaybackRate(double* playback_rate) {
Response InspectorAnimationAgent::setPlaybackRate(double playback_rate) {
for (LocalFrame* frame : *inspected_frames_)
frame->GetDocument()->Timeline().SetPlaybackRate(playback_rate);
- state_->setDouble(AnimationAgentState::animationAgentPlaybackRate,
- playback_rate);
+ playback_rate_.Set(playback_rate);
return Response::OK();
}
@@ -299,7 +286,7 @@ blink::Animation* InspectorAnimationAgent::AnimationClone(
KeyframeVector old_keyframes = old_string_keyframe_model->GetFrames();
StringKeyframeVector new_keyframes;
for (auto& old_keyframe : old_keyframes)
- new_keyframes.push_back(ToStringKeyframe(old_keyframe.get()));
+ new_keyframes.push_back(ToStringKeyframe(old_keyframe));
new_model = StringKeyframeEffectModel::Create(new_keyframes);
} else if (old_model->IsTransitionKeyframeEffectModel()) {
TransitionKeyframeEffectModel* old_transition_keyframe_model =
@@ -307,7 +294,7 @@ blink::Animation* InspectorAnimationAgent::AnimationClone(
KeyframeVector old_keyframes = old_transition_keyframe_model->GetFrames();
TransitionKeyframeVector new_keyframes;
for (auto& old_keyframe : old_keyframes)
- new_keyframes.push_back(ToTransitionKeyframe(old_keyframe.get()));
+ new_keyframes.push_back(ToTransitionKeyframe(old_keyframe));
new_model = TransitionKeyframeEffectModel::Create(new_keyframes);
}
@@ -386,7 +373,7 @@ Response InspectorAnimationAgent::setTiming(const String& animation_id,
DCHECK(frames.size() == 3);
KeyframeVector new_frames;
for (int i = 0; i < 3; i++)
- new_frames.push_back(ToTransitionKeyframe(frames[i]->Clone().get()));
+ new_frames.push_back(ToTransitionKeyframe(frames[i]->Clone()));
// Update delay, represented by the distance between the first two
// keyframes.
new_frames[1]->SetOffset(delay / (delay + duration));
@@ -525,8 +512,7 @@ void InspectorAnimationAgent::AnimationPlayStateChanged(
void InspectorAnimationAgent::DidClearDocumentOfWindowObject(
LocalFrame* frame) {
- if (!state_->booleanProperty(AnimationAgentState::animationAgentEnabled,
- false))
+ if (!enabled_.Get())
return;
DCHECK(frame->GetDocument());
frame->GetDocument()->Timeline().SetPlaybackRate(
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 0d3a2d2043c..623a2462e0d 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
@@ -90,6 +90,8 @@ class CORE_EXPORT InspectorAnimationAgent final
HashMap<String, String> id_to_animation_type_;
bool is_cloning_;
HashSet<String> cleared_animations_;
+ InspectorAgentState::Boolean enabled_;
+ InspectorAgentState::Double playback_rate_;
DISALLOW_COPY_AND_ASSIGN(InspectorAnimationAgent);
};
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 519a1499abc..d0c272a758d 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
@@ -35,36 +35,32 @@
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
namespace blink {
-
using protocol::Response;
-namespace ApplicationCacheAgentState {
-static const char kApplicationCacheAgentEnabled[] =
- "applicationCacheAgentEnabled";
-}
-
InspectorApplicationCacheAgent::InspectorApplicationCacheAgent(
InspectedFrames* inspected_frames)
- : inspected_frames_(inspected_frames) {}
+ : inspected_frames_(inspected_frames),
+ enabled_(&agent_state_, /*default_value=*/false) {}
+
+void InspectorApplicationCacheAgent::InnerEnable() {
+ enabled_.Set(true);
+ instrumenting_agents_->addInspectorApplicationCacheAgent(this);
+ GetFrontend()->networkStateUpdated(GetNetworkStateNotifier().OnLine());
+}
void InspectorApplicationCacheAgent::Restore() {
- if (state_->booleanProperty(
- ApplicationCacheAgentState::kApplicationCacheAgentEnabled, false)) {
- enable();
- }
+ if (enabled_.Get())
+ InnerEnable();
}
Response InspectorApplicationCacheAgent::enable() {
- state_->setBoolean(ApplicationCacheAgentState::kApplicationCacheAgentEnabled,
- true);
- instrumenting_agents_->addInspectorApplicationCacheAgent(this);
- GetFrontend()->networkStateUpdated(GetNetworkStateNotifier().OnLine());
+ if (!enabled_.Get())
+ InnerEnable();
return Response::OK();
}
Response InspectorApplicationCacheAgent::disable() {
- state_->setBoolean(ApplicationCacheAgentState::kApplicationCacheAgentEnabled,
- false);
+ enabled_.Clear();
instrumenting_agents_->removeInspectorApplicationCacheAgent(this);
return Response::OK();
}
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 8aa426bd62c..8853a40b9c2 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
@@ -68,6 +68,9 @@ class CORE_EXPORT InspectorApplicationCacheAgent final
std::unique_ptr<protocol::ApplicationCache::ApplicationCache>*) override;
private:
+ // Unconditionally enables the agent, even if |enabled_.Get()==true|.
+ // For idempotence, call enable().
+ void InnerEnable();
explicit InspectorApplicationCacheAgent(InspectedFrames*);
std::unique_ptr<protocol::ApplicationCache::ApplicationCache>
@@ -85,6 +88,7 @@ class CORE_EXPORT InspectorApplicationCacheAgent final
DocumentLoader*&);
Member<InspectedFrames> inspected_frames_;
+ InspectorAgentState::Boolean enabled_;
DISALLOW_COPY_AND_ASSIGN(InspectorApplicationCacheAgent);
};
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 b413b5869a0..c2e74eccdd9 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
@@ -53,8 +53,11 @@ bool EncodeAsImage(char* body,
if (!image_to_encode)
return false;
- String mime_type = "image/";
- mime_type.append(encoding);
+ String mime_type_name = "image/";
+ mime_type_name.append(encoding);
+ ImageEncodingMimeType mime_type;
+ bool valid_mime_type = ParseImageEncodingMimeType(mime_type_name, mime_type);
+ DCHECK(valid_mime_type);
return image_to_encode->EncodeImage(mime_type, quality, output);
}
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 5b36ce15894..2f7c4291ade 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
@@ -33,6 +33,7 @@
#include "third_party/blink/renderer/core/CoreProbeSink.h"
#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/inspector/inspector_session_state.h"
#include "third_party/blink/renderer/core/inspector/protocol/Protocol.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
@@ -55,7 +56,7 @@ class CORE_EXPORT InspectorAgent
virtual void Init(CoreProbeSink*,
protocol::UberDispatcher*,
- protocol::DictionaryValue*) = 0;
+ InspectorSessionState*) = 0;
virtual void Dispose() = 0;
};
@@ -67,19 +68,13 @@ class InspectorBaseAgent : public InspectorAgent,
void Init(CoreProbeSink* instrumenting_agents,
protocol::UberDispatcher* dispatcher,
- protocol::DictionaryValue* state) override {
+ InspectorSessionState* session_state) override {
instrumenting_agents_ = instrumenting_agents;
frontend_.reset(
new typename DomainMetainfo::FrontendClass(dispatcher->channel()));
DomainMetainfo::DispatcherClass::wire(dispatcher, this);
- state_ = state->getObject(DomainMetainfo::domainName);
- if (!state_) {
- std::unique_ptr<protocol::DictionaryValue> new_state =
- protocol::DictionaryValue::create();
- state_ = new_state.get();
- state->setObject(DomainMetainfo::domainName, std::move(new_state));
- }
+ agent_state_.InitFrom(session_state);
}
protocol::Response disable() override { return protocol::Response::OK(); }
@@ -87,7 +82,6 @@ class InspectorBaseAgent : public InspectorAgent,
void Dispose() override {
disable();
frontend_.reset();
- state_ = nullptr;
instrumenting_agents_ = nullptr;
}
@@ -97,13 +91,13 @@ class InspectorBaseAgent : public InspectorAgent,
}
protected:
- InspectorBaseAgent() = default;
+ InspectorBaseAgent() : agent_state_(DomainMetainfo::domainName) {}
typename DomainMetainfo::FrontendClass* GetFrontend() const {
return frontend_.get();
}
Member<CoreProbeSink> instrumenting_agents_;
- protocol::DictionaryValue* state_;
+ InspectorAgentState agent_state_;
private:
std::unique_ptr<typename DomainMetainfo::FrontendClass> frontend_;
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 b06102238b5..8944fc46dca 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
@@ -324,11 +324,6 @@ void CollectPlatformFontsFromRunFontDataList(
} // namespace
-namespace CSSAgentState {
-static const char kCssAgentEnabled[] = "cssAgentEnabled";
-static const char kRuleRecordingEnabled[] = "ruleRecordingEnabled";
-} // namespace CSSAgentState
-
typedef blink::protocol::CSS::Backend::EnableCallback EnableCallback;
enum ForcePseudoClassFlags {
@@ -679,14 +674,17 @@ InspectorCSSAgent::InspectorCSSAgent(
resource_content_loader_(resource_content_loader),
resource_container_(resource_container),
resource_content_loader_client_id_(
- resource_content_loader->CreateClientId()) {}
+ resource_content_loader->CreateClientId()),
+ enable_requested_(&agent_state_, /*default_value=*/false),
+ enable_completed_(false),
+ coverage_enabled_(&agent_state_, /*default_value=*/false) {}
InspectorCSSAgent::~InspectorCSSAgent() = default;
void InspectorCSSAgent::Restore() {
- if (state_->booleanProperty(CSSAgentState::kCssAgentEnabled, false))
- WasEnabled();
- if (state_->booleanProperty(CSSAgentState::kRuleRecordingEnabled, false))
+ if (enable_requested_.Get())
+ CompleteEnabled();
+ if (coverage_enabled_.Get())
SetCoverageEnabled(true);
}
@@ -719,7 +717,7 @@ void InspectorCSSAgent::enable(std::unique_ptr<EnableCallback> prp_callback) {
Response::Error("DOM agent needs to be enabled first."));
return;
}
- state_->setBoolean(CSSAgentState::kCssAgentEnabled, true);
+ enable_requested_.Set(true);
resource_content_loader_->EnsureResourcesContentLoaded(
resource_content_loader_client_id_,
WTF::Bind(&InspectorCSSAgent::ResourceContentLoaded, WrapPersistent(this),
@@ -728,32 +726,28 @@ void InspectorCSSAgent::enable(std::unique_ptr<EnableCallback> prp_callback) {
void InspectorCSSAgent::ResourceContentLoaded(
std::unique_ptr<EnableCallback> callback) {
- WasEnabled();
+ if (enable_requested_.Get()) // Could be disabled while fetching resources.
+ CompleteEnabled();
callback->sendSuccess();
}
-void InspectorCSSAgent::WasEnabled() {
- if (!state_->booleanProperty(CSSAgentState::kCssAgentEnabled, false)) {
- // We were disabled while fetching resources.
- return;
- }
-
+void InspectorCSSAgent::CompleteEnabled() {
instrumenting_agents_->addInspectorCSSAgent(this);
dom_agent_->SetDOMListener(this);
HeapVector<Member<Document>> documents = dom_agent_->Documents();
for (Document* document : documents)
UpdateActiveStyleSheets(document);
- was_enabled_ = true;
+ enable_completed_ = true;
}
Response InspectorCSSAgent::disable() {
Reset();
dom_agent_->SetDOMListener(nullptr);
instrumenting_agents_->removeInspectorCSSAgent(this);
- state_->setBoolean(CSSAgentState::kCssAgentEnabled, false);
- was_enabled_ = false;
+ enable_completed_ = false;
+ enable_requested_.Set(false);
resource_content_loader_->Cancel(resource_content_loader_client_id_);
- state_->setBoolean(CSSAgentState::kRuleRecordingEnabled, false);
+ coverage_enabled_.Set(false);
SetCoverageEnabled(false);
return Response::OK();
}
@@ -1929,8 +1923,8 @@ InspectorStyleSheet* InspectorCSSAgent::ViaInspectorStyleSheet(
}
Response InspectorCSSAgent::AssertEnabled() {
- return was_enabled_ ? Response::OK()
- : Response::Error("CSS agent was not enabled");
+ return enable_completed_ ? Response::OK()
+ : Response::Error("CSS agent was not enabled");
}
Response InspectorCSSAgent::AssertInspectorStyleSheetForId(
@@ -2320,7 +2314,7 @@ Response InspectorCSSAgent::getBackgroundColors(
if (content_bounds.Size().IsEmpty() && element_layout->IsBox()) {
// Return content box instead - may have indirect text children.
LayoutBox* layout_box = ToLayoutBox(element_layout);
- content_bounds = layout_box->ContentBoxRect();
+ content_bounds = layout_box->PhysicalContentBoxRect();
content_bounds = LayoutRect(
element_layout->LocalToAbsoluteQuad(FloatRect(content_bounds))
.BoundingBox());
@@ -2408,7 +2402,7 @@ void InspectorCSSAgent::WillChangeStyleElement(Element* element) {
}
Response InspectorCSSAgent::startRuleUsageTracking() {
- state_->setBoolean(CSSAgentState::kRuleRecordingEnabled, true);
+ coverage_enabled_.Set(true);
SetCoverageEnabled(true);
for (Document* document : dom_agent_->Documents()) {
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 77f282f682f..a1ad18b7f96 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
@@ -254,7 +254,7 @@ class CORE_EXPORT InspectorCSSAgent final
typedef HashMap<int, unsigned> NodeIdToForcedPseudoState;
void ResourceContentLoaded(std::unique_ptr<EnableCallback>);
- void WasEnabled();
+ void CompleteEnabled();
void ResetNonPersistentData();
InspectorStyleSheetForInlineStyle* AsInspectorStyleSheet(Element* element);
@@ -334,7 +334,9 @@ class CORE_EXPORT InspectorCSSAgent final
Member<CSSStyleSheet> inspector_user_agent_style_sheet_;
int resource_content_loader_client_id_;
- bool was_enabled_ = false;
+ InspectorAgentState::Boolean enable_requested_;
+ bool enable_completed_;
+ InspectorAgentState::Boolean coverage_enabled_;
friend class InspectorResourceContentLoaderCallback;
friend class StyleSheetBinder;
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 6e6dc1c4910..f2555191419 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
@@ -90,10 +90,6 @@ using namespace HTMLNames;
using protocol::Maybe;
using protocol::Response;
-namespace DOMAgentState {
-static const char kDomAgentEnabled[] = "domAgentEnabled";
-};
-
namespace {
const size_t kMaxTextSize = 10000;
@@ -242,14 +238,14 @@ InspectorDOMAgent::InspectorDOMAgent(
dom_listener_(nullptr),
document_node_to_id_map_(new NodeToIdMap()),
last_node_id_(1),
- suppress_attribute_modified_event_(false) {}
+ suppress_attribute_modified_event_(false),
+ enabled_(&agent_state_, /*default_value=*/false) {}
InspectorDOMAgent::~InspectorDOMAgent() = default;
void InspectorDOMAgent::Restore() {
- if (!Enabled())
- return;
- InnerEnable();
+ if (enabled_.Get())
+ EnableAndReset();
}
HeapVector<Member<Document>> InspectorDOMAgent::Documents() {
@@ -274,7 +270,7 @@ void InspectorDOMAgent::SetDocument(Document* doc) {
DiscardFrontendBindings();
document_ = doc;
- if (!Enabled())
+ if (!enabled_.Get())
return;
// Immediately communicate 0 document or document that has finished loading.
@@ -282,6 +278,10 @@ void InspectorDOMAgent::SetDocument(Document* doc) {
GetFrontend()->documentUpdated();
}
+bool InspectorDOMAgent::Enabled() const {
+ return enabled_.Get();
+}
+
void InspectorDOMAgent::ReleaseDanglingNodes() {
dangling_node_to_id_maps_.clear();
}
@@ -448,8 +448,8 @@ Response InspectorDOMAgent::AssertEditableElement(int node_id,
return Response::OK();
}
-void InspectorDOMAgent::InnerEnable() {
- state_->setBoolean(DOMAgentState::kDomAgentEnabled, true);
+void InspectorDOMAgent::EnableAndReset() {
+ enabled_.Set(true);
history_ = new InspectorHistory();
dom_editor_ = new DOMEditor(history_.Get());
document_ = inspected_frames_->Root()->GetDocument();
@@ -457,19 +457,15 @@ void InspectorDOMAgent::InnerEnable() {
}
Response InspectorDOMAgent::enable() {
- if (!Enabled())
- InnerEnable();
+ if (!enabled_.Get())
+ EnableAndReset();
return Response::OK();
}
-bool InspectorDOMAgent::Enabled() const {
- return state_->booleanProperty(DOMAgentState::kDomAgentEnabled, false);
-}
-
Response InspectorDOMAgent::disable() {
- if (!Enabled())
+ if (!enabled_.Get())
return Response::Error("DOM agent hasn't been enabled");
- state_->setBoolean(DOMAgentState::kDomAgentEnabled, false);
+ enabled_.Clear();
instrumenting_agents_->removeInspectorDOMAgent(this);
history_.Clear();
dom_editor_.Clear();
@@ -482,8 +478,7 @@ Response InspectorDOMAgent::getDocument(
Maybe<bool> pierce,
std::unique_ptr<protocol::DOM::Node>* root) {
// Backward compatibility. Mark agent as enabled when it requests document.
- if (!Enabled())
- InnerEnable();
+ enable();
if (!document_)
return Response::Error("Document is not available");
@@ -504,7 +499,7 @@ Response InspectorDOMAgent::getFlattenedDocument(
Maybe<int> depth,
Maybe<bool> pierce,
std::unique_ptr<protocol::Array<protocol::DOM::Node>>* nodes) {
- if (!Enabled())
+ if (!enabled_.Get())
return Response::Error("DOM agent hasn't been enabled");
if (!document_)
@@ -964,7 +959,7 @@ Response InspectorDOMAgent::performSearch(
Maybe<bool> optional_include_user_agent_shadow_dom,
String* search_id,
int* result_count) {
- if (!Enabled())
+ if (!enabled_.Get())
return Response::Error("DOM agent is not enabled");
// FIXME: Few things are missing here:
@@ -1224,7 +1219,7 @@ Response InspectorDOMAgent::moveTo(int node_id,
}
Response InspectorDOMAgent::undo() {
- if (!Enabled())
+ if (!enabled_.Get())
return Response::Error("DOM agent is not enabled");
DummyExceptionStateForTesting exception_state;
history_->Undo(exception_state);
@@ -1232,7 +1227,7 @@ Response InspectorDOMAgent::undo() {
}
Response InspectorDOMAgent::redo() {
- if (!Enabled())
+ if (!enabled_.Get())
return Response::Error("DOM agent is not enabled");
DummyExceptionStateForTesting exception_state;
history_->Redo(exception_state);
@@ -1317,14 +1312,16 @@ Response InspectorDOMAgent::getNodeForLocation(
int y,
Maybe<bool> optional_include_user_agent_shadow_dom,
int* node_id) {
- if (!Enabled())
+ if (!enabled_.Get())
return Response::Error("DOM agent is not enabled");
bool include_user_agent_shadow_dom =
optional_include_user_agent_shadow_dom.fromMaybe(false);
Response response = PushDocumentUponHandlelessOperation();
if (!response.isSuccess())
return response;
- LayoutPoint document_point(x, y);
+
+ LayoutPoint document_point(x * inspected_frames_->Root()->PageZoomFactor(),
+ y * inspected_frames_->Root()->PageZoomFactor());
HitTestRequest request(HitTestRequest::kMove | HitTestRequest::kReadOnly |
HitTestRequest::kAllowChildFrameContent);
HitTestLocation location(document_->View()->DocumentToFrame(document_point));
@@ -1812,7 +1809,7 @@ void InspectorDOMAgent::DOMContentLoadedEventFired(LocalFrame* frame) {
// Re-push document once it is loaded.
DiscardFrontendBindings();
- if (Enabled())
+ if (enabled_.Get())
GetFrontend()->documentUpdated();
}
@@ -2145,7 +2142,7 @@ Node* InspectorDOMAgent::NodeForPath(const String& path) {
Response InspectorDOMAgent::pushNodeByPathToFrontend(const String& path,
int* node_id) {
- if (!Enabled())
+ if (!enabled_.Get())
return Response::Error("DOM agent is not enabled");
if (Node* node = NodeForPath(path))
*node_id = PushNodePathToFrontend(node);
@@ -2157,7 +2154,7 @@ Response InspectorDOMAgent::pushNodeByPathToFrontend(const String& path,
Response InspectorDOMAgent::pushNodesByBackendIdsToFrontend(
std::unique_ptr<protocol::Array<int>> backend_node_ids,
std::unique_ptr<protocol::Array<int>>* result) {
- if (!Enabled())
+ if (!enabled_.Get())
return Response::Error("DOM agent is not enabled");
*result = protocol::Array<int>::create();
for (size_t index = 0; index < backend_node_ids->length(); ++index) {
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 cf7a5d12641..7399d07c18e 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
@@ -279,7 +279,9 @@ class CORE_EXPORT InspectorDOMAgent final
private:
void SetDocument(Document*);
- void InnerEnable();
+ // Unconditionally enables the agent, even if |enabled_.Get()==true|.
+ // For idempotence, call enable().
+ void EnableAndReset();
// Node-related methods.
typedef HeapHashMap<Member<Node>, int> NodeToIdMap;
@@ -347,6 +349,7 @@ class CORE_EXPORT InspectorDOMAgent final
Member<InspectorHistory> history_;
Member<DOMEditor> dom_editor_;
bool suppress_attribute_modified_event_;
+ InspectorAgentState::Boolean enabled_;
DISALLOW_COPY_AND_ASSIGN(InspectorDOMAgent);
};
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 3a20c3da3c1..211bc57ec12 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
@@ -59,13 +59,6 @@ static const char instrumentationEventCategoryType[] = "instrumentation:";
const uint32_t inheritableDOMBreakpointTypesMask = (1 << SubtreeModified);
const int domBreakpointDerivedTypeShift = 16;
-} // namespace
-
-namespace blink {
-
-using protocol::Maybe;
-using protocol::Response;
-
static const char kWebglErrorFiredEventName[] = "webglErrorFired";
static const char kWebglWarningFiredEventName[] = "webglWarningFired";
static const char kWebglErrorNameProperty[] = "webglErrorName";
@@ -75,14 +68,22 @@ static const char kAudioContextCreatedEventName[] = "audioContextCreated";
static const char kAudioContextClosedEventName[] = "audioContextClosed";
static const char kAudioContextResumedEventName[] = "audioContextResumed";
static const char kAudioContextSuspendedEventName[] = "audioContextSuspended";
+} // namespace
-namespace DOMDebuggerAgentState {
-static const char kEventListenerBreakpoints[] = "eventListenerBreakpoints";
-static const char kEventTargetAny[] = "*";
-static const char kPauseOnAllXHRs[] = "pauseOnAllXHRs";
-static const char kXhrBreakpoints[] = "xhrBreakpoints";
-static const char kEnabled[] = "enabled";
-} // namespace DOMDebuggerAgentState
+namespace blink {
+using protocol::Maybe;
+using protocol::Response;
+namespace {
+// Returns the key that we use to identify the brekpoint in
+// event_listener_breakpoints_. |target_name| may be "", in which case
+// we'll match any target.
+WTF::String EventListenerBreakpointKey(const WTF::String& event_name,
+ const WTF::String& target_name) {
+ if (target_name.IsEmpty() || target_name == "*")
+ return event_name + "$$" + "*";
+ return event_name + "$$" + target_name.LowerASCII();
+}
+} // namespace
// static
void InspectorDOMDebuggerAgent::CollectEventListeners(
@@ -109,10 +110,11 @@ void InspectorDOMDebuggerAgent::CollectEventListeners(
EventListener* event_listener = listeners->at(k).Callback();
if (event_listener->GetType() != EventListener::kJSEventListenerType)
continue;
- V8AbstractEventListener* v8_listener =
- static_cast<V8AbstractEventListener*>(event_listener);
- v8::Local<v8::Context> context =
- ToV8Context(execution_context, v8_listener->World());
+ // TODO(yukiy): Use a child class of blink::EventListener that is for v8
+ // event listeners here if it is implemented in redesigning
+ // EventListener/EventHandler: https://crbug.com/872138 .
+ v8::Local<v8::Context> context = ToV8Context(
+ execution_context, *(event_listener->GetWorldForInspector()));
// Optionally hide listeners from other contexts.
if (!report_for_all_contexts && context != isolate->GetCurrentContext())
continue;
@@ -120,7 +122,7 @@ void InspectorDOMDebuggerAgent::CollectEventListeners(
// compiled, potentially unsuccessfully. In that case, the function
// returns the empty handle without an exception.
v8::Local<v8::Object> handler =
- v8_listener->GetListenerObject(execution_context);
+ event_listener->GetListenerObjectForInspector(execution_context);
if (handler.IsEmpty())
continue;
bool use_capture = listeners->at(k).Capture();
@@ -196,7 +198,13 @@ InspectorDOMDebuggerAgent::InspectorDOMDebuggerAgent(
v8::Isolate* isolate,
InspectorDOMAgent* dom_agent,
v8_inspector::V8InspectorSession* v8_session)
- : isolate_(isolate), dom_agent_(dom_agent), v8_session_(v8_session) {}
+ : isolate_(isolate),
+ dom_agent_(dom_agent),
+ v8_session_(v8_session),
+ enabled_(&agent_state_, /*default_value=*/false),
+ pause_on_all_xhrs_(&agent_state_, /*default_value=*/false),
+ xhr_breakpoints_(&agent_state_, /*default_value=*/false),
+ event_listener_breakpoints_(&agent_state_, /*default_value*/ false) {}
InspectorDOMDebuggerAgent::~InspectorDOMDebuggerAgent() = default;
@@ -209,14 +217,12 @@ void InspectorDOMDebuggerAgent::Trace(blink::Visitor* visitor) {
Response InspectorDOMDebuggerAgent::disable() {
SetEnabled(false);
dom_breakpoints_.clear();
- state_->remove(DOMDebuggerAgentState::kEventListenerBreakpoints);
- state_->remove(DOMDebuggerAgentState::kXhrBreakpoints);
- state_->remove(DOMDebuggerAgentState::kPauseOnAllXHRs);
+ agent_state_.ClearAllFields();
return Response::OK();
}
void InspectorDOMDebuggerAgent::Restore() {
- if (state_->booleanProperty(DOMDebuggerAgentState::kEnabled, false))
+ if (enabled_.Get())
instrumenting_agents_->addInspectorDOMDebuggerAgent(this);
}
@@ -233,59 +239,12 @@ Response InspectorDOMDebuggerAgent::setInstrumentationBreakpoint(
String());
}
-static protocol::DictionaryValue* EnsurePropertyObject(
- protocol::DictionaryValue* object,
- const String& property_name) {
- protocol::Value* value = object->get(property_name);
- if (value)
- return protocol::DictionaryValue::cast(value);
-
- std::unique_ptr<protocol::DictionaryValue> new_result =
- protocol::DictionaryValue::create();
- protocol::DictionaryValue* result = new_result.get();
- object->setObject(property_name, std::move(new_result));
- return result;
-}
-
-protocol::DictionaryValue*
-InspectorDOMDebuggerAgent::EventListenerBreakpoints() {
- protocol::DictionaryValue* breakpoints =
- state_->getObject(DOMDebuggerAgentState::kEventListenerBreakpoints);
- if (!breakpoints) {
- std::unique_ptr<protocol::DictionaryValue> new_breakpoints =
- protocol::DictionaryValue::create();
- breakpoints = new_breakpoints.get();
- state_->setObject(DOMDebuggerAgentState::kEventListenerBreakpoints,
- std::move(new_breakpoints));
- }
- return breakpoints;
-}
-
-protocol::DictionaryValue* InspectorDOMDebuggerAgent::XhrBreakpoints() {
- protocol::DictionaryValue* breakpoints =
- state_->getObject(DOMDebuggerAgentState::kXhrBreakpoints);
- if (!breakpoints) {
- std::unique_ptr<protocol::DictionaryValue> new_breakpoints =
- protocol::DictionaryValue::create();
- breakpoints = new_breakpoints.get();
- state_->setObject(DOMDebuggerAgentState::kXhrBreakpoints,
- std::move(new_breakpoints));
- }
- return breakpoints;
-}
-
Response InspectorDOMDebuggerAgent::SetBreakpoint(const String& event_name,
const String& target_name) {
if (event_name.IsEmpty())
return Response::Error("Event name is empty");
- protocol::DictionaryValue* breakpoints_by_target =
- EnsurePropertyObject(EventListenerBreakpoints(), event_name);
- if (target_name.IsEmpty()) {
- breakpoints_by_target->setBoolean(DOMDebuggerAgentState::kEventTargetAny,
- true);
- } else {
- breakpoints_by_target->setBoolean(target_name.DeprecatedLower(), true);
- }
+ event_listener_breakpoints_.Set(
+ EventListenerBreakpointKey(event_name, target_name), true);
DidAddBreakpoint();
return Response::OK();
}
@@ -308,12 +267,8 @@ Response InspectorDOMDebuggerAgent::RemoveBreakpoint(
const String& target_name) {
if (event_name.IsEmpty())
return Response::Error("Event name is empty");
- protocol::DictionaryValue* breakpoints_by_target =
- EnsurePropertyObject(EventListenerBreakpoints(), event_name);
- if (target_name.IsEmpty())
- breakpoints_by_target->remove(DOMDebuggerAgentState::kEventTargetAny);
- else
- breakpoints_by_target->remove(target_name.DeprecatedLower());
+ event_listener_breakpoints_.Clear(
+ EventListenerBreakpointKey(event_name, target_name));
DidRemoveBreakpoint();
return Response::OK();
}
@@ -653,17 +608,13 @@ InspectorDOMDebuggerAgent::PreparePauseOnNativeEventData(
String full_event_name = (target_name ? listenerEventCategoryType
: instrumentationEventCategoryType) +
event_name;
- protocol::DictionaryValue* breakpoints = EventListenerBreakpoints();
- protocol::Value* value = breakpoints->get(full_event_name);
- if (!value)
- return nullptr;
- bool match = false;
- protocol::DictionaryValue* breakpoints_by_target =
- protocol::DictionaryValue::cast(value);
- breakpoints_by_target->getBoolean(DOMDebuggerAgentState::kEventTargetAny,
- &match);
- if (!match && target_name)
- breakpoints_by_target->getBoolean(target_name->DeprecatedLower(), &match);
+
+ bool match = event_listener_breakpoints_.Get(
+ EventListenerBreakpointKey(full_event_name, "*"));
+ if (!match && target_name) {
+ match = event_listener_breakpoints_.Get(
+ EventListenerBreakpointKey(full_event_name, *target_name));
+ }
if (!match)
return nullptr;
@@ -743,38 +694,36 @@ void InspectorDOMDebuggerAgent::BreakableLocation(const char* name) {
Response InspectorDOMDebuggerAgent::setXHRBreakpoint(const String& url) {
if (url.IsEmpty())
- state_->setBoolean(DOMDebuggerAgentState::kPauseOnAllXHRs, true);
+ pause_on_all_xhrs_.Set(true);
else
- XhrBreakpoints()->setBoolean(url, true);
+ xhr_breakpoints_.Set(url, true);
DidAddBreakpoint();
return Response::OK();
}
Response InspectorDOMDebuggerAgent::removeXHRBreakpoint(const String& url) {
if (url.IsEmpty())
- state_->setBoolean(DOMDebuggerAgentState::kPauseOnAllXHRs, false);
+ pause_on_all_xhrs_.Set(false);
else
- XhrBreakpoints()->remove(url);
+ xhr_breakpoints_.Clear(url);
DidRemoveBreakpoint();
return Response::OK();
}
-void InspectorDOMDebuggerAgent::WillSendXMLHttpOrFetchNetworkRequest(
- const String& url) {
- String breakpoint_url;
- if (state_->booleanProperty(DOMDebuggerAgentState::kPauseOnAllXHRs, false))
- breakpoint_url = "";
- else {
- protocol::DictionaryValue* breakpoints = XhrBreakpoints();
- for (size_t i = 0; i < breakpoints->size(); ++i) {
- auto breakpoint = breakpoints->at(i);
- if (url.Contains(breakpoint.first)) {
- breakpoint_url = breakpoint.first;
- break;
- }
- }
+// Returns the breakpoint url if a match is found, or WTF::String().
+String InspectorDOMDebuggerAgent::MatchXHRBreakpoints(const String& url) const {
+ if (pause_on_all_xhrs_.Get())
+ return "";
+ for (const WTF::String& breakpoint : xhr_breakpoints_.Keys()) {
+ if (url.Contains(breakpoint))
+ return breakpoint;
}
+ return WTF::String();
+}
+void InspectorDOMDebuggerAgent::WillSendXMLHttpOrFetchNetworkRequest(
+ const String& url) {
+ String breakpoint_url = MatchXHRBreakpoints(url);
if (breakpoint_url.IsNull())
return;
@@ -796,7 +745,7 @@ void InspectorDOMDebuggerAgent::DidCreateCanvasContext() {
}
void InspectorDOMDebuggerAgent::DidAddBreakpoint() {
- if (state_->booleanProperty(DOMDebuggerAgentState::kEnabled, false))
+ if (enabled_.Get())
return;
SetEnabled(true);
}
@@ -804,23 +753,21 @@ void InspectorDOMDebuggerAgent::DidAddBreakpoint() {
void InspectorDOMDebuggerAgent::DidRemoveBreakpoint() {
if (!dom_breakpoints_.IsEmpty())
return;
- if (EventListenerBreakpoints()->size())
+ if (!event_listener_breakpoints_.IsEmpty())
return;
- if (XhrBreakpoints()->size())
+ if (!xhr_breakpoints_.IsEmpty())
return;
- if (state_->booleanProperty(DOMDebuggerAgentState::kPauseOnAllXHRs, false))
+ if (pause_on_all_xhrs_.Get())
return;
SetEnabled(false);
}
void InspectorDOMDebuggerAgent::SetEnabled(bool enabled) {
- if (enabled) {
+ enabled_.Set(enabled);
+ if (enabled)
instrumenting_agents_->addInspectorDOMDebuggerAgent(this);
- state_->setBoolean(DOMDebuggerAgentState::kEnabled, true);
- } else {
- state_->remove(DOMDebuggerAgentState::kEnabled);
+ else
instrumenting_agents_->removeInspectorDOMDebuggerAgent(this);
- }
}
void InspectorDOMDebuggerAgent::DidCommitLoadForLocalFrame(LocalFrame*) {
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 f9856e29375..a1c53b88100 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
@@ -133,6 +133,8 @@ class CORE_EXPORT InspectorDOMDebuggerAgent final
const v8_inspector::StringView& object_group_id);
private:
+ String MatchXHRBreakpoints(const String& url) const;
+
static void EventListenersInfoForTarget(v8::Isolate*,
v8::Local<v8::Value>,
int depth,
@@ -148,10 +150,6 @@ class CORE_EXPORT InspectorDOMDebuggerAgent final
std::unique_ptr<protocol::DictionaryValue> PreparePauseOnNativeEventData(
const String& event_name,
const String* target_name);
-
- protocol::DictionaryValue* EventListenerBreakpoints();
- protocol::DictionaryValue* XhrBreakpoints();
-
void BreakProgramOnDOMEvent(Node* target,
int breakpoint_type,
bool insertion);
@@ -175,6 +173,10 @@ class CORE_EXPORT InspectorDOMDebuggerAgent final
Member<InspectorDOMAgent> dom_agent_;
v8_inspector::V8InspectorSession* v8_session_;
HeapHashMap<Member<Node>, uint32_t> dom_breakpoints_;
+ InspectorAgentState::Boolean enabled_;
+ InspectorAgentState::Boolean pause_on_all_xhrs_;
+ InspectorAgentState::BooleanMap xhr_breakpoints_;
+ InspectorAgentState::BooleanMap event_listener_breakpoints_;
DISALLOW_COPY_AND_ASSIGN(InspectorDOMDebuggerAgent);
};
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 0da6c561fc6..e79866fd4fc 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
@@ -43,14 +43,9 @@
#include "v8/include/v8-inspector.h"
namespace blink {
-
using protocol::Maybe;
using protocol::Response;
-namespace DOMSnapshotAgentState {
-static const char kDomSnapshotAgentEnabled[] = "DOMSnapshotAgentEnabled";
-};
-
namespace {
std::unique_ptr<protocol::DOM::Rect> BuildRectForFloatRect(
@@ -148,15 +143,11 @@ InspectorDOMSnapshotAgent::InspectorDOMSnapshotAgent(
InspectedFrames* inspected_frames,
InspectorDOMDebuggerAgent* dom_debugger_agent)
: inspected_frames_(inspected_frames),
- dom_debugger_agent_(dom_debugger_agent) {}
+ dom_debugger_agent_(dom_debugger_agent),
+ enabled_(&agent_state_, /*default_value=*/false) {}
InspectorDOMSnapshotAgent::~InspectorDOMSnapshotAgent() = default;
-bool InspectorDOMSnapshotAgent::Enabled() const {
- return state_->booleanProperty(
- DOMSnapshotAgentState::kDomSnapshotAgentEnabled, false);
-}
-
void InspectorDOMSnapshotAgent::GetOriginUrl(String* origin_url_ptr,
const Node* node) {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
@@ -197,28 +188,27 @@ void InspectorDOMSnapshotAgent::DidInsertDOMNode(Node* node) {
origin_url_map_->insert(DOMNodeIds::IdForNode(node), origin_url);
}
-void InspectorDOMSnapshotAgent::InnerEnable() {
- state_->setBoolean(DOMSnapshotAgentState::kDomSnapshotAgentEnabled, true);
+void InspectorDOMSnapshotAgent::EnableAndReset() {
+ enabled_.Set(true);
origin_url_map_ = std::make_unique<OriginUrlMap>();
instrumenting_agents_->addInspectorDOMSnapshotAgent(this);
}
void InspectorDOMSnapshotAgent::Restore() {
- if (!Enabled())
- return;
- InnerEnable();
+ if (enabled_.Get())
+ EnableAndReset();
}
Response InspectorDOMSnapshotAgent::enable() {
- if (!Enabled())
- InnerEnable();
+ if (!enabled_.Get())
+ EnableAndReset();
return Response::OK();
}
Response InspectorDOMSnapshotAgent::disable() {
- if (!Enabled())
+ if (!enabled_.Get())
return Response::Error("DOM snapshot agent hasn't been enabled.");
- state_->setBoolean(DOMSnapshotAgentState::kDomSnapshotAgentEnabled, false);
+ enabled_.Clear();
origin_url_map_.reset();
instrumenting_agents_->removeInspectorDOMSnapshotAgent(this);
return Response::OK();
@@ -431,7 +421,8 @@ int InspectorDOMSnapshotAgent::VisitNode(Node* node,
if (InspectorDOMAgent::GetPseudoElementType(element->GetPseudoId(),
&pseudo_type)) {
value->setPseudoType(pseudo_type);
- VisitPseudoLayoutChildren(node, node->GetLayoutObject(), index);
+ if (node->GetLayoutObject())
+ VisitPseudoLayoutChildren(node, index);
}
} else {
value->setPseudoElementIndexes(
@@ -549,6 +540,7 @@ void InspectorDOMSnapshotAgent::VisitDocument2(Document* document) {
.setBounds(protocol::Array<protocol::Array<double>>::create())
.setText(protocol::Array<int>::create())
.setStyles(protocol::Array<protocol::Array<int>>::create())
+ .setStackingContexts(BooleanData())
.build())
.setTextBoxes(
protocol::DOMSnapshot::TextBoxSnapshot::create()
@@ -639,7 +631,8 @@ int InspectorDOMSnapshotAgent::VisitNode2(Node* node, int parent_index) {
if (InspectorDOMAgent::GetPseudoElementType(element->GetPseudoId(),
&pseudo_type)) {
SetRare(nodes->getPseudoType(nullptr), index, pseudo_type);
- VisitPseudoLayoutChildren2(node, node->GetLayoutObject(), index);
+ if (node->GetLayoutObject())
+ VisitPseudoLayoutChildren2(node, index);
}
} else {
VisitPseudoElements2(element, index);
@@ -726,23 +719,21 @@ void InspectorDOMSnapshotAgent::VisitContainerChildren2(Node* container,
}
}
-void InspectorDOMSnapshotAgent::VisitPseudoLayoutChildren(
- Node* pseudo_node,
- LayoutObject* layout_object,
- int index) {
- for (LayoutObject* child = layout_object->SlowFirstChild(); child;
- child = child->NextSibling()) {
- VisitLayoutTreeNode(child, pseudo_node, index);
+void InspectorDOMSnapshotAgent::VisitPseudoLayoutChildren(Node* pseudo_node,
+ int index) {
+ for (LayoutObject* child = pseudo_node->GetLayoutObject()->SlowFirstChild();
+ child; child = child->NextSibling()) {
+ if (child->IsAnonymous())
+ VisitLayoutTreeNode(child, pseudo_node, index);
}
}
-void InspectorDOMSnapshotAgent::VisitPseudoLayoutChildren2(
- Node* pseudo_node,
- LayoutObject* layout_object,
- int index) {
- for (LayoutObject* child = layout_object->SlowFirstChild(); child;
- child = child->NextSibling()) {
- BuildLayoutTreeNode(child, pseudo_node, index);
+void InspectorDOMSnapshotAgent::VisitPseudoLayoutChildren2(Node* pseudo_node,
+ int index) {
+ for (LayoutObject* child = pseudo_node->GetLayoutObject()->SlowFirstChild();
+ child; child = child->NextSibling()) {
+ if (child->IsAnonymous())
+ BuildLayoutTreeNode(child, pseudo_node, index);
}
}
@@ -759,11 +750,9 @@ InspectorDOMSnapshotAgent::VisitPseudoElements(
}
auto pseudo_elements = protocol::Array<int>::create();
- PseudoId pseudo_types[] = {kPseudoIdFirstLetter, kPseudoIdBefore,
- kPseudoIdAfter};
- for (PseudoId pseudo_id : pseudo_types) {
- if (parent->GetPseudoElement(pseudo_id)) {
- Node* pseudo_node = parent->GetPseudoElement(pseudo_id);
+ for (PseudoId pseudo_id :
+ {kPseudoIdFirstLetter, kPseudoIdBefore, kPseudoIdAfter}) {
+ if (Node* pseudo_node = parent->GetPseudoElement(pseudo_id)) {
pseudo_elements->addItem(VisitNode(pseudo_node, include_event_listeners,
include_user_agent_shadow_tree));
}
@@ -773,18 +762,10 @@ InspectorDOMSnapshotAgent::VisitPseudoElements(
void InspectorDOMSnapshotAgent::VisitPseudoElements2(Element* parent,
int parent_index) {
- if (!parent->GetPseudoElement(kPseudoIdFirstLetter) &&
- !parent->GetPseudoElement(kPseudoIdBefore) &&
- !parent->GetPseudoElement(kPseudoIdAfter)) {
- return;
- }
- PseudoId pseudo_types[] = {kPseudoIdFirstLetter, kPseudoIdBefore,
- kPseudoIdAfter};
- for (PseudoId i : pseudo_types) {
- if (parent->GetPseudoElement(i)) {
- Node* pseudo_node = parent->GetPseudoElement(i);
+ for (PseudoId pseudo_id :
+ {kPseudoIdFirstLetter, kPseudoIdBefore, kPseudoIdAfter}) {
+ if (Node* pseudo_node = parent->GetPseudoElement(pseudo_id))
VisitNode2(pseudo_node, parent_index);
- }
}
}
@@ -833,6 +814,9 @@ int InspectorDOMSnapshotAgent::VisitLayoutTreeNode(LayoutObject* layout_object,
if (style_index != -1)
layout_tree_node->setStyleIndex(style_index);
+ if (layout_object->Style() && layout_object->Style()->IsStacked())
+ layout_tree_node->setIsStackingContext(true);
+
if (paint_order_map_) {
PaintLayer* paint_layer = layout_object->EnclosingLayer();
@@ -846,19 +830,19 @@ int InspectorDOMSnapshotAgent::VisitLayoutTreeNode(LayoutObject* layout_object,
if (layout_object->IsText()) {
LayoutText* layout_text = ToLayoutText(layout_object);
layout_tree_node->setLayoutText(layout_text->GetText());
- if (layout_text->HasTextBoxes()) {
+ Vector<LayoutText::TextBoxInfo> text_boxes = layout_text->GetTextBoxInfo();
+ if (!text_boxes.IsEmpty()) {
std::unique_ptr<protocol::Array<protocol::DOMSnapshot::InlineTextBox>>
inline_text_nodes =
protocol::Array<protocol::DOMSnapshot::InlineTextBox>::create();
- for (const InlineTextBox* text_box : layout_text->TextBoxes()) {
- FloatRect local_coords_text_box_rect(text_box->FrameRect());
+ for (const LayoutText::TextBoxInfo& text_box : text_boxes) {
FloatRect absolute_coords_text_box_rect =
- layout_object->LocalToAbsoluteQuad(local_coords_text_box_rect)
+ layout_object->LocalToAbsoluteQuad(FloatRect(text_box.local_rect))
.BoundingBox();
inline_text_nodes->addItem(
protocol::DOMSnapshot::InlineTextBox::create()
- .setStartCharacterIndex(text_box->Start())
- .setNumCharacters(text_box->Len())
+ .setStartCharacterIndex(text_box.dom_start_offset)
+ .setNumCharacters(text_box.dom_length)
.setBoundingBox(
BuildRectForFloatRect(absolute_coords_text_box_rect))
.build());
@@ -886,6 +870,9 @@ int InspectorDOMSnapshotAgent::BuildLayoutTreeNode(LayoutObject* layout_object,
layout_tree_snapshot->getBounds()->addItem(BuildRectForFloatRect2(
FloatRect(layout_object->AbsoluteBoundingBoxRect())));
+ if (layout_object->Style() && layout_object->Style()->IsStacked())
+ SetRare(layout_tree_snapshot->getStackingContexts(), layout_index);
+
String text = layout_object->IsText() ? ToLayoutText(layout_object)->GetText()
: String();
layout_tree_snapshot->getText()->addItem(AddString(text));
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 b65e206b4a4..603dad2210f 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
@@ -55,15 +55,15 @@ class CORE_EXPORT InspectorDOMSnapshotAgent final
documents,
std::unique_ptr<protocol::Array<String>>* strings) override;
- bool Enabled() const;
-
// InspectorInstrumentation API.
void CharacterDataModified(CharacterData*);
void DidInsertDOMNode(Node*);
private:
InspectorDOMSnapshotAgent(InspectedFrames*, InspectorDOMDebuggerAgent*);
- void InnerEnable();
+ // Unconditionally enables the agent, even if |enabled_.Get()==true|.
+ // For idempotence, call enable().
+ void EnableAndReset();
int VisitNode(Node*,
bool include_event_listeners,
@@ -95,12 +95,8 @@ class CORE_EXPORT InspectorDOMSnapshotAgent final
void VisitContainerChildren2(Node* container, int parent_index);
// Collect LayoutTreeNodes owned by a pseudo element.
- void VisitPseudoLayoutChildren(Node* pseudo_node,
- LayoutObject* layout_object,
- int index);
- void VisitPseudoLayoutChildren2(Node* pseudo_node,
- LayoutObject* layout_object,
- int index);
+ void VisitPseudoLayoutChildren(Node* pseudo_node, int index);
+ void VisitPseudoLayoutChildren2(Node* pseudo_node, int index);
std::unique_ptr<protocol::Array<int>> VisitPseudoElements(
Element* parent,
@@ -169,7 +165,7 @@ class CORE_EXPORT InspectorDOMSnapshotAgent final
DocumentOrderMap document_order_map_;
Member<InspectedFrames> inspected_frames_;
Member<InspectorDOMDebuggerAgent> dom_debugger_agent_;
-
+ InspectorAgentState::Boolean enabled_;
DISALLOW_COPY_AND_ASSIGN(InspectorDOMSnapshotAgent);
};
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 6f2867e6f16..4843946ecc8 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
@@ -23,36 +23,32 @@
#include "third_party/blink/renderer/platform/wtf/time.h"
namespace blink {
-
using protocol::Maybe;
using protocol::Response;
-namespace EmulationAgentState {
-static const char kScriptExecutionDisabled[] = "scriptExecutionDisabled";
-static const char kScrollbarsHidden[] = "scrollbarsHidden";
-static const char kDocumentCookieDisabled[] = "documentCookieDisabled";
-static const char kTouchEventEmulationEnabled[] = "touchEventEmulationEnabled";
-static const char kMaxTouchPoints[] = "maxTouchPoints";
-static const char kEmulatedMedia[] = "emulatedMedia";
-static const char kDefaultBackgroundColorOverrideRGBA[] =
- "defaultBackgroundColorOverrideRGBA";
-static const char kNavigatorPlatform[] = "navigatorPlatform";
-static const char kVirtualTimeBudget[] = "virtualTimeBudget";
-static const char kVirtualTimeBudgetInitalOffset[] =
- "virtualTimeBudgetInitalOffset";
-static const char kInitialVirtualTime[] = "initialVirtualTime";
-static const char kVirtualTimeOffset[] = "virtualTimeOffset";
-static const char kVirtualTimePolicy[] = "virtualTimePolicy";
-static const char kVirtualTimeTaskStarvationCount[] =
- "virtualTimeTaskStarvationCount";
-static const char kWaitForNavigation[] = "waitForNavigation";
-static const char kUserAgentOverride[] = "userAgentOverride";
-static const char kAcceptLanguageOverride[] = "acceptLanguage";
-} // namespace EmulationAgentState
-
InspectorEmulationAgent::InspectorEmulationAgent(
WebLocalFrameImpl* web_local_frame_impl)
- : web_local_frame_(web_local_frame_impl) {}
+ : web_local_frame_(web_local_frame_impl),
+ default_background_color_override_rgba_(&agent_state_,
+ /*default_value=*/WTF::String()),
+ script_execution_disabled_(&agent_state_, /*default_value=*/false),
+ scrollbars_hidden_(&agent_state_, /*default_value=*/false),
+ document_cookie_disabled_(&agent_state_, /*default_value=*/false),
+ touch_event_emulation_enabled_(&agent_state_, /*default_value=*/false),
+ max_touch_points_(&agent_state_, /*default_value=*/1),
+ emulated_media_(&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()),
+ 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),
+ virtual_time_offset_(&agent_state_, /*default_value=*/0.0),
+ virtual_time_policy_(&agent_state_, /*default_value=*/WTF::String()),
+ virtual_time_task_starvation_count_(&agent_state_, /*default_value=*/0),
+ wait_for_navigation_(&agent_state_, /*default_value=*/false) {}
InspectorEmulationAgent::~InspectorEmulationAgent() = default;
@@ -61,101 +57,69 @@ WebViewImpl* InspectorEmulationAgent::GetWebViewImpl() {
}
void InspectorEmulationAgent::Restore() {
- String user_agent;
- state_->getString(EmulationAgentState::kUserAgentOverride, &user_agent);
- String accept_language;
- state_->getString(EmulationAgentState::kAcceptLanguageOverride,
- &accept_language);
- String navigator_platform;
- state_->getString(EmulationAgentState::kNavigatorPlatform,
- &navigator_platform);
- setUserAgentOverride(user_agent, accept_language, navigator_platform);
+ setUserAgentOverride(user_agent_override_.Get(),
+ accept_language_override_.Get(),
+ navigator_platform_override_.Get());
if (!web_local_frame_)
return;
// Following code only runs for pages.
- if (state_->booleanProperty(EmulationAgentState::kScriptExecutionDisabled,
- false)) {
+ if (script_execution_disabled_.Get())
GetWebViewImpl()->GetDevToolsEmulator()->SetScriptExecutionDisabled(true);
- }
- if (state_->booleanProperty(EmulationAgentState::kScrollbarsHidden, false))
+ if (scrollbars_hidden_.Get())
GetWebViewImpl()->GetDevToolsEmulator()->SetScrollbarsHidden(true);
- if (state_->booleanProperty(EmulationAgentState::kDocumentCookieDisabled,
- false)) {
+ if (document_cookie_disabled_.Get())
GetWebViewImpl()->GetDevToolsEmulator()->SetDocumentCookieDisabled(true);
- }
- setTouchEmulationEnabled(
- state_->booleanProperty(EmulationAgentState::kTouchEventEmulationEnabled,
- false),
- state_->integerProperty(EmulationAgentState::kMaxTouchPoints, 1));
- String emulated_media;
- state_->getString(EmulationAgentState::kEmulatedMedia, &emulated_media);
- setEmulatedMedia(emulated_media);
- auto* rgba_value =
- state_->get(EmulationAgentState::kDefaultBackgroundColorOverrideRGBA);
- if (rgba_value) {
- blink::protocol::ErrorSupport errors;
- auto rgba = protocol::DOM::RGBA::fromValue(rgba_value, &errors);
- if (!errors.hasErrors()) {
- setDefaultBackgroundColorOverride(
- Maybe<protocol::DOM::RGBA>(std::move(rgba)));
+ setTouchEmulationEnabled(touch_event_emulation_enabled_.Get(),
+ max_touch_points_.Get());
+ setEmulatedMedia(emulated_media_.Get());
+ if (!default_background_color_override_rgba_.Get().IsNull()) {
+ std::unique_ptr<protocol::Value> parsed = protocol::StringUtil::parseJSON(
+ default_background_color_override_rgba_.Get());
+ if (parsed) {
+ blink::protocol::ErrorSupport errors;
+ auto rgba = protocol::DOM::RGBA::fromValue(parsed.get(), &errors);
+ if (!errors.hasErrors()) {
+ setDefaultBackgroundColorOverride(
+ Maybe<protocol::DOM::RGBA>(std::move(rgba)));
+ }
}
}
- String virtual_time_policy;
- if (state_->getString(EmulationAgentState::kVirtualTimePolicy,
- &virtual_time_policy)) {
- // Tell the scheduler about the saved virtual time progress to ensure that
- // virtual time monotonically advances despite the cross origin navigation.
- // This should be done regardless of the virtual time mode.
- double offset = 0;
- state_->getDouble(EmulationAgentState::kVirtualTimeOffset, &offset);
- web_local_frame_->View()->Scheduler()->SetInitialVirtualTimeOffset(
- base::TimeDelta::FromMillisecondsD(offset));
-
- // Set initial time baselines for all modes.
- double initial_virtual_time = 0;
- bool has_initial_time = state_->getDouble(
- EmulationAgentState::kInitialVirtualTime, &initial_virtual_time);
- Maybe<double> initial_time = has_initial_time
- ? Maybe<double>()
- : Maybe<double>(initial_virtual_time);
-
- // Preserve wait for navigation in all modes.
- bool wait_for_navigation = false;
- state_->getBoolean(EmulationAgentState::kWaitForNavigation,
- &wait_for_navigation);
-
- // Reinstate the stored policy.
- double virtual_time_ticks_base_ms;
-
- // For Pause, do not pass budget or starvation count.
- if (virtual_time_policy ==
- protocol::Emulation::VirtualTimePolicyEnum::Pause) {
- setVirtualTimePolicy(protocol::Emulation::VirtualTimePolicyEnum::Pause,
- Maybe<double>(), Maybe<int>(), wait_for_navigation,
- std::move(initial_time),
- &virtual_time_ticks_base_ms);
- return;
- }
-
- // Calculate remaining budget for the advancing modes.
- double budget = 0;
- state_->getDouble(EmulationAgentState::kVirtualTimeBudget, &budget);
- double inital_offset = 0;
- state_->getDouble(EmulationAgentState::kVirtualTimeBudgetInitalOffset,
- &inital_offset);
- double budget_remaining = budget + inital_offset - offset;
- DCHECK_GE(budget_remaining, 0);
-
- int starvation_count = 0;
- state_->getInteger(EmulationAgentState::kVirtualTimeTaskStarvationCount,
- &starvation_count);
-
- setVirtualTimePolicy(virtual_time_policy, budget_remaining,
- starvation_count, wait_for_navigation,
- std::move(initial_time), &virtual_time_ticks_base_ms);
+ if (virtual_time_policy_.Get().IsNull())
+ return;
+ // Tell the scheduler about the saved virtual time progress to ensure that
+ // virtual time monotonically advances despite the cross origin navigation.
+ // This should be done regardless of the virtual time mode.
+ web_local_frame_->View()->Scheduler()->SetInitialVirtualTimeOffset(
+ base::TimeDelta::FromMillisecondsD(virtual_time_offset_.Get()));
+
+ // Preserve wait for navigation in all modes.
+ bool wait_for_navigation = wait_for_navigation_.Get();
+
+ // Reinstate the stored policy.
+ double virtual_time_ticks_base_ms;
+
+ // For Pause, do not pass budget or starvation count.
+ if (virtual_time_policy_.Get() ==
+ protocol::Emulation::VirtualTimePolicyEnum::Pause) {
+ setVirtualTimePolicy(protocol::Emulation::VirtualTimePolicyEnum::Pause,
+ Maybe<double>(), Maybe<int>(), wait_for_navigation,
+ initial_virtual_time_.Get(),
+ &virtual_time_ticks_base_ms);
+ return;
}
+
+ // Calculate remaining budget for the advancing modes.
+ double budget_remaining = virtual_time_budget_.Get() +
+ virtual_time_budget_initial_offset_.Get() -
+ virtual_time_offset_.Get();
+ DCHECK_GE(budget_remaining, 0);
+
+ setVirtualTimePolicy(virtual_time_policy_.Get(), budget_remaining,
+ virtual_time_task_starvation_count_.Get(),
+ wait_for_navigation, initial_virtual_time_.Get(),
+ &virtual_time_ticks_base_ms);
}
Response InspectorEmulationAgent::disable() {
@@ -198,11 +162,9 @@ Response InspectorEmulationAgent::setScriptExecutionDisabled(bool value) {
Response response = AssertPage();
if (!response.isSuccess())
return response;
- if (state_->booleanProperty(EmulationAgentState::kScriptExecutionDisabled,
- false) == value) {
+ if (script_execution_disabled_.Get() == value)
return response;
- }
- state_->setBoolean(EmulationAgentState::kScriptExecutionDisabled, value);
+ script_execution_disabled_.Set(value);
GetWebViewImpl()->GetDevToolsEmulator()->SetScriptExecutionDisabled(value);
return response;
}
@@ -211,11 +173,9 @@ Response InspectorEmulationAgent::setScrollbarsHidden(bool hidden) {
Response response = AssertPage();
if (!response.isSuccess())
return response;
- if (state_->booleanProperty(EmulationAgentState::kScrollbarsHidden, false) ==
- hidden) {
+ if (scrollbars_hidden_.Get() == hidden)
return response;
- }
- state_->setBoolean(EmulationAgentState::kScrollbarsHidden, hidden);
+ scrollbars_hidden_.Set(hidden);
GetWebViewImpl()->GetDevToolsEmulator()->SetScrollbarsHidden(hidden);
return response;
}
@@ -224,11 +184,9 @@ Response InspectorEmulationAgent::setDocumentCookieDisabled(bool disabled) {
Response response = AssertPage();
if (!response.isSuccess())
return response;
- if (state_->booleanProperty(EmulationAgentState::kDocumentCookieDisabled,
- false) == disabled) {
+ if (document_cookie_disabled_.Get() == disabled)
return response;
- }
- state_->setBoolean(EmulationAgentState::kDocumentCookieDisabled, disabled);
+ document_cookie_disabled_.Set(disabled);
GetWebViewImpl()->GetDevToolsEmulator()->SetDocumentCookieDisabled(disabled);
return response;
}
@@ -245,8 +203,8 @@ Response InspectorEmulationAgent::setTouchEmulationEnabled(
"Touch points must be between 1 and " +
String::Number(WebTouchEvent::kTouchesLengthCap));
}
- state_->setBoolean(EmulationAgentState::kTouchEventEmulationEnabled, enabled);
- state_->setInteger(EmulationAgentState::kMaxTouchPoints, max_points);
+ touch_event_emulation_enabled_.Set(enabled);
+ max_touch_points_.Set(max_points);
GetWebViewImpl()->GetDevToolsEmulator()->SetTouchEventEmulationEnabled(
enabled, max_points);
return response;
@@ -256,7 +214,7 @@ Response InspectorEmulationAgent::setEmulatedMedia(const String& media) {
Response response = AssertPage();
if (!response.isSuccess())
return response;
- state_->setString(EmulationAgentState::kEmulatedMedia, media);
+ emulated_media_.Set(media);
GetWebViewImpl()->GetPage()->GetSettings().SetMediaTypeOverride(media);
return response;
}
@@ -279,7 +237,7 @@ Response InspectorEmulationAgent::setVirtualTimePolicy(
Response response = AssertPage();
if (!response.isSuccess())
return response;
- state_->setString(EmulationAgentState::kVirtualTimePolicy, policy);
+ virtual_time_policy_.Set(policy);
PendingVirtualTimePolicy new_policy;
new_policy.policy = PageScheduler::VirtualTimePolicy::kPause;
@@ -306,24 +264,21 @@ Response InspectorEmulationAgent::setVirtualTimePolicy(
if (virtual_time_budget_ms.isJust()) {
new_policy.virtual_time_budget_ms = virtual_time_budget_ms.fromJust();
- state_->setDouble(EmulationAgentState::kVirtualTimeBudget,
- *new_policy.virtual_time_budget_ms);
+ virtual_time_budget_.Set(*new_policy.virtual_time_budget_ms);
// Record the current virtual time offset so Restore can compute how much
// budget is left.
- state_->setDouble(
- EmulationAgentState::kVirtualTimeBudgetInitalOffset,
- state_->doubleProperty(EmulationAgentState::kVirtualTimeOffset, 0.0));
+ virtual_time_budget_initial_offset_.Set(virtual_time_offset_.Get());
} else {
- state_->remove(EmulationAgentState::kVirtualTimeBudget);
+ virtual_time_budget_.Clear();
}
if (max_virtual_time_task_starvation_count.isJust()) {
new_policy.max_virtual_time_task_starvation_count =
max_virtual_time_task_starvation_count.fromJust();
- state_->setDouble(EmulationAgentState::kVirtualTimeTaskStarvationCount,
- *new_policy.max_virtual_time_task_starvation_count);
+ virtual_time_task_starvation_count_.Set(
+ *new_policy.max_virtual_time_task_starvation_count);
} else {
- state_->remove(EmulationAgentState::kVirtualTimeTaskStarvationCount);
+ virtual_time_task_starvation_count_.Clear();
}
InnerEnable();
@@ -334,14 +289,13 @@ Response InspectorEmulationAgent::setVirtualTimePolicy(
// This needs to happen before we apply virtual time.
if (initial_virtual_time.isJust()) {
- state_->setDouble(EmulationAgentState::kInitialVirtualTime,
- initial_virtual_time.fromJust());
+ initial_virtual_time_.Set(initial_virtual_time.fromJust());
web_local_frame_->View()->Scheduler()->SetInitialVirtualTime(
base::Time::FromDoubleT(initial_virtual_time.fromJust()));
}
if (wait_for_navigation.fromMaybe(false)) {
- state_->setBoolean(EmulationAgentState::kWaitForNavigation, true);
+ wait_for_navigation_.Set(true);
pending_virtual_time_policy_ = std::move(new_policy);
} else {
ApplyVirtualTimePolicy(new_policy);
@@ -382,7 +336,7 @@ void InspectorEmulationAgent::ApplyVirtualTimePolicy(
void InspectorEmulationAgent::FrameStartedLoading(LocalFrame*) {
if (pending_virtual_time_policy_) {
- state_->setBoolean(EmulationAgentState::kWaitForNavigation, false);
+ wait_for_navigation_.Set(false);
ApplyVirtualTimePolicy(*pending_virtual_time_policy_);
pending_virtual_time_policy_ = base::nullopt;
}
@@ -396,15 +350,12 @@ void InspectorEmulationAgent::WillSendRequest(
const ResourceResponse& redirect_response,
const FetchInitiatorInfo& initiator_info,
Resource::Type resource_type) {
- String accept_lang_override;
- state_->getString(EmulationAgentState::kAcceptLanguageOverride,
- &accept_lang_override);
- if (!accept_lang_override.IsEmpty() &&
+ if (!accept_language_override_.Get().IsEmpty() &&
request.HttpHeaderField("Accept-Language").IsEmpty()) {
request.SetHTTPHeaderField(
"Accept-Language",
- AtomicString(
- NetworkUtils::GenerateAcceptLanguageHeader(accept_lang_override)));
+ AtomicString(NetworkUtils::GenerateAcceptLanguageHeader(
+ accept_language_override_.Get())));
}
}
@@ -413,7 +364,7 @@ Response InspectorEmulationAgent::setNavigatorOverrides(
Response response = AssertPage();
if (!response.isSuccess())
return response;
- state_->setString(EmulationAgentState::kNavigatorPlatform, platform);
+ navigator_platform_override_.Set(platform);
GetWebViewImpl()->GetPage()->GetSettings().SetNavigatorPlatformOverride(
platform);
return response;
@@ -424,22 +375,19 @@ void InspectorEmulationAgent::VirtualTimeBudgetExpired() {
DCHECK(web_local_frame_);
web_local_frame_->View()->Scheduler()->SetVirtualTimePolicy(
PageScheduler::VirtualTimePolicy::kPause);
- state_->setString(EmulationAgentState::kVirtualTimePolicy,
- protocol::Emulation::VirtualTimePolicyEnum::Pause);
+ virtual_time_policy_.Set(protocol::Emulation::VirtualTimePolicyEnum::Pause);
GetFrontend()->virtualTimeBudgetExpired();
}
void InspectorEmulationAgent::OnVirtualTimeAdvanced(
WTF::TimeDelta virtual_time_offset) {
- state_->setDouble(EmulationAgentState::kVirtualTimeOffset,
- virtual_time_offset.InMillisecondsF());
+ virtual_time_offset_.Set(virtual_time_offset.InMillisecondsF());
GetFrontend()->virtualTimeAdvanced(virtual_time_offset.InMillisecondsF());
}
void InspectorEmulationAgent::OnVirtualTimePaused(
WTF::TimeDelta virtual_time_offset) {
- state_->setDouble(EmulationAgentState::kVirtualTimeOffset,
- virtual_time_offset.InMillisecondsF());
+ virtual_time_offset_.Set(virtual_time_offset.InMillisecondsF());
GetFrontend()->virtualTimePaused(virtual_time_offset.InMillisecondsF());
}
@@ -451,13 +399,13 @@ Response InspectorEmulationAgent::setDefaultBackgroundColorOverride(
if (!color.isJust()) {
// Clear the override and state.
GetWebViewImpl()->ClearBaseBackgroundColorOverride();
- state_->remove(EmulationAgentState::kDefaultBackgroundColorOverrideRGBA);
+ default_background_color_override_rgba_.Clear();
return Response::OK();
}
blink::protocol::DOM::RGBA* rgba = color.fromJust();
- state_->setValue(EmulationAgentState::kDefaultBackgroundColorOverrideRGBA,
- rgba->toValue());
+ default_background_color_override_rgba_.Set(
+ rgba->toValue()->serialize());
// Clamping of values is done by Color() constructor.
int alpha = lroundf(255.0f * rgba->getA(1.0f));
GetWebViewImpl()->SetBaseBackgroundColorOverride(
@@ -497,32 +445,24 @@ Response InspectorEmulationAgent::setUserAgentOverride(
protocol::Maybe<String> platform) {
if (!user_agent.IsEmpty() || accept_language.isJust() || platform.isJust())
InnerEnable();
- state_->setString(EmulationAgentState::kUserAgentOverride, user_agent);
- state_->setString(EmulationAgentState::kAcceptLanguageOverride,
- accept_language.fromMaybe(String()));
- state_->setString(EmulationAgentState::kNavigatorPlatform,
- platform.fromMaybe(String()));
+ user_agent_override_.Set(user_agent);
+ accept_language_override_.Set(accept_language.fromMaybe(String()));
+ navigator_platform_override_.Set(platform.fromMaybe(String()));
if (web_local_frame_) {
GetWebViewImpl()->GetPage()->GetSettings().SetNavigatorPlatformOverride(
- platform.fromMaybe(String()));
+ navigator_platform_override_.Get());
}
return Response::OK();
}
void InspectorEmulationAgent::ApplyAcceptLanguageOverride(String* accept_lang) {
- String accept_lang_override;
- state_->getString(EmulationAgentState::kAcceptLanguageOverride,
- &accept_lang_override);
- if (!accept_lang_override.IsEmpty())
- *accept_lang = accept_lang_override;
+ if (!accept_language_override_.Get().IsEmpty())
+ *accept_lang = accept_language_override_.Get();
}
void InspectorEmulationAgent::ApplyUserAgentOverride(String* user_agent) {
- String user_agent_override;
- state_->getString(EmulationAgentState::kUserAgentOverride,
- &user_agent_override);
- if (!user_agent_override.IsEmpty())
- *user_agent = user_agent_override;
+ if (!user_agent_override_.Get().IsEmpty())
+ *user_agent = user_agent_override_.Get();
}
void InspectorEmulationAgent::InnerEnable() {
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 1688b5747d4..256d89afcec 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
@@ -122,6 +122,23 @@ class CORE_EXPORT InspectorEmulationAgent final
base::Optional<PendingVirtualTimePolicy> pending_virtual_time_policy_;
bool enabled_ = false;
+ InspectorAgentState::String default_background_color_override_rgba_;
+ InspectorAgentState::Boolean script_execution_disabled_;
+ InspectorAgentState::Boolean scrollbars_hidden_;
+ InspectorAgentState::Boolean document_cookie_disabled_;
+ InspectorAgentState::Boolean touch_event_emulation_enabled_;
+ InspectorAgentState::Integer max_touch_points_;
+ InspectorAgentState::String emulated_media_;
+ InspectorAgentState::String navigator_platform_override_;
+ InspectorAgentState::String user_agent_override_;
+ InspectorAgentState::String accept_language_override_;
+ InspectorAgentState::Double virtual_time_budget_;
+ InspectorAgentState::Double virtual_time_budget_initial_offset_;
+ InspectorAgentState::Double initial_virtual_time_;
+ InspectorAgentState::Double virtual_time_offset_;
+ InspectorAgentState::String virtual_time_policy_;
+ InspectorAgentState::Integer virtual_time_task_starvation_count_;
+ InspectorAgentState::Boolean wait_for_navigation_;
DISALLOW_COPY_AND_ASSIGN(InspectorEmulationAgent);
};
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 71a3169d516..1c2c5319778 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_highlight.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_highlight.cc
@@ -15,10 +15,11 @@
#include "third_party/blink/renderer/core/layout/layout_inline.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/layout/shapes/shape_outside_info.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/style/computed_style_constants.h"
#include "third_party/blink/renderer/platform/graphics/path.h"
-#include "third_party/blink/renderer/platform/platform_chrome_client.h"
+#include "third_party/blink/renderer/platform/layout_test_support.h"
namespace blink {
@@ -418,11 +419,17 @@ void InspectorHighlight::AppendNodeHighlight(
if (!layout_object)
return;
+ // Just for testing, invert the content color for nodes rendered by LayoutNG.
+ // TODO(layout-dev): Stop munging the color before NG ships. crbug.com/869866
+ Color content_color = layout_object->IsLayoutNGObject() &&
+ !LayoutTestSupport::IsRunningLayoutTest()
+ ? Color(highlight_config.content.Rgb() ^ 0x00ffffff)
+ : highlight_config.content;
+
Vector<FloatQuad> svg_quads;
if (BuildSVGQuads(node, svg_quads)) {
for (size_t i = 0; i < svg_quads.size(); ++i) {
- AppendQuad(svg_quads[i], highlight_config.content,
- highlight_config.content_outline);
+ AppendQuad(svg_quads[i], content_color, highlight_config.content_outline);
}
return;
}
@@ -430,8 +437,8 @@ void InspectorHighlight::AppendNodeHighlight(
FloatQuad content, padding, border, margin;
if (!BuildNodeQuads(node, &content, &padding, &border, &margin))
return;
- AppendQuad(content, highlight_config.content,
- highlight_config.content_outline, "content");
+ AppendQuad(content, content_color, highlight_config.content_outline,
+ "content");
AppendQuad(padding, highlight_config.padding, Color::kTransparent, "padding");
AppendQuad(border, highlight_config.border, Color::kTransparent, "border");
AppendQuad(margin, highlight_config.margin, Color::kTransparent, "margin");
@@ -616,11 +623,11 @@ bool InspectorHighlight::BuildNodeQuads(Node* node,
const int vertical_scrollbar_width = layout_box->VerticalScrollbarWidth();
const int horizontal_scrollbar_height =
layout_box->HorizontalScrollbarHeight();
- content_box = layout_box->ContentBoxRect();
+ content_box = layout_box->PhysicalContentBoxRect();
content_box.SetWidth(content_box.Width() + vertical_scrollbar_width);
content_box.SetHeight(content_box.Height() + horizontal_scrollbar_height);
- padding_box = layout_box->PaddingBoxRect();
+ padding_box = layout_box->PhysicalPaddingBoxRect();
padding_box.SetWidth(padding_box.Width() + vertical_scrollbar_width);
padding_box.SetHeight(padding_box.Height() + horizontal_scrollbar_height);
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 b9df4c5d20a..a0f3790ef37 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
@@ -14,14 +14,8 @@
#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
namespace blink {
-
using protocol::Response;
-namespace LogAgentState {
-static const char kLogEnabled[] = "logEnabled";
-static const char kLogViolations[] = "logViolations";
-} // namespace LogAgentState
-
namespace {
String MessageSourceValue(MessageSource source) {
@@ -80,10 +74,11 @@ InspectorLogAgent::InspectorLogAgent(
ConsoleMessageStorage* storage,
PerformanceMonitor* performance_monitor,
v8_inspector::V8InspectorSession* v8_session)
- : enabled_(false),
- storage_(storage),
+ : storage_(storage),
performance_monitor_(performance_monitor),
- v8_session_(v8_session) {}
+ v8_session_(v8_session),
+ enabled_(&agent_state_, /*default_value=*/false),
+ violation_thresholds_(&agent_state_, -1.0) {}
InspectorLogAgent::~InspectorLogAgent() = default;
@@ -95,19 +90,23 @@ void InspectorLogAgent::Trace(blink::Visitor* visitor) {
}
void InspectorLogAgent::Restore() {
- if (!state_->booleanProperty(LogAgentState::kLogEnabled, false))
+ if (!enabled_.Get())
+ return;
+ InnerEnable();
+ if (violation_thresholds_.IsEmpty())
return;
- enable();
- protocol::Value* config = state_->get(LogAgentState::kLogViolations);
- if (config) {
- protocol::ErrorSupport errors;
- startViolationsReport(
- protocol::Array<ViolationSetting>::fromValue(config, &errors));
+ auto settings = protocol::Array<ViolationSetting>::create();
+ for (const WTF::String& key : violation_thresholds_.Keys()) {
+ settings->addItem(ViolationSetting::create()
+ .setName(key)
+ .setThreshold(violation_thresholds_.Get(key))
+ .build());
}
+ startViolationsReport(std::move(settings));
}
void InspectorLogAgent::ConsoleMessageAdded(ConsoleMessage* message) {
- DCHECK(enabled_);
+ DCHECK(enabled_.Get());
std::unique_ptr<protocol::Log::LogEntry> entry =
protocol::Log::LogEntry::create()
@@ -163,13 +162,8 @@ void InspectorLogAgent::ConsoleMessageAdded(ConsoleMessage* message) {
GetFrontend()->flush();
}
-Response InspectorLogAgent::enable() {
- if (enabled_)
- return Response::OK();
+void InspectorLogAgent::InnerEnable() {
instrumenting_agents_->addInspectorLogAgent(this);
- state_->setBoolean(LogAgentState::kLogEnabled, true);
- enabled_ = true;
-
if (storage_->ExpiredCount()) {
std::unique_ptr<protocol::Log::LogEntry> expired =
protocol::Log::LogEntry::create()
@@ -184,15 +178,21 @@ Response InspectorLogAgent::enable() {
}
for (size_t i = 0; i < storage_->size(); ++i)
ConsoleMessageAdded(storage_->at(i));
+}
+
+Response InspectorLogAgent::enable() {
+ if (enabled_.Get())
+ return Response::OK();
+ enabled_.Set(true);
+ InnerEnable();
return Response::OK();
}
Response InspectorLogAgent::disable() {
- if (!enabled_)
+ if (!enabled_.Get())
return Response::OK();
- state_->setBoolean(LogAgentState::kLogEnabled, false);
+ enabled_.Clear();
stopViolationsReport();
- enabled_ = false;
instrumenting_agents_->removeInspectorLogAgent(this);
return Response::OK();
}
@@ -222,27 +222,27 @@ static PerformanceMonitor::Violation ParseViolation(const String& name) {
Response InspectorLogAgent::startViolationsReport(
std::unique_ptr<protocol::Array<ViolationSetting>> settings) {
- if (!enabled_)
+ if (!enabled_.Get())
return Response::Error("Log is not enabled");
- state_->setValue(LogAgentState::kLogViolations, settings->toValue());
if (!performance_monitor_)
return Response::Error("Violations are not supported for this target");
performance_monitor_->UnsubscribeAll(this);
+ violation_thresholds_.Clear();
for (size_t i = 0; i < settings->length(); ++i) {
- PerformanceMonitor::Violation violation =
- ParseViolation(settings->get(i)->getName());
+ const WTF::String& name = settings->get(i)->getName();
+ double threshold = settings->get(i)->getThreshold();
+ PerformanceMonitor::Violation violation = ParseViolation(name);
if (violation == PerformanceMonitor::kAfterLast)
continue;
performance_monitor_->Subscribe(
- violation,
- base::TimeDelta::FromMillisecondsD(settings->get(i)->getThreshold()),
- this);
+ violation, base::TimeDelta::FromMillisecondsD(threshold), this);
+ violation_thresholds_.Set(name, threshold);
}
return Response::OK();
}
Response InspectorLogAgent::stopViolationsReport() {
- state_->remove(LogAgentState::kLogViolations);
+ violation_thresholds_.Clear();
if (!performance_monitor_)
return Response::Error("Violations are not supported for this target");
performance_monitor_->UnsubscribeAll(this);
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 5ff38f0ca4b..8b46b3181e3 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
@@ -53,11 +53,13 @@ class CORE_EXPORT InspectorLogAgent
const String& text,
base::TimeDelta time,
SourceLocation*) override;
+ void InnerEnable();
- bool enabled_;
Member<ConsoleMessageStorage> storage_;
Member<PerformanceMonitor> performance_monitor_;
v8_inspector::V8InspectorSession* v8_session_;
+ InspectorAgentState::Boolean enabled_;
+ InspectorAgentState::DoubleMap violation_thresholds_;
DISALLOW_COPY_AND_ASSIGN(InspectorLogAgent);
};
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 752723d0ad3..2ca70ca367f 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,6 +33,7 @@
#include <cstdio>
#include "base/debug/stack_trace.h"
+#include "base/sampling_heap_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,17 +42,13 @@
namespace blink {
-const unsigned kDefaultNativeMemorySamplingInterval = 128 * 1024;
-
-namespace MemoryAgentState {
-static const char samplingProfileInterval[] =
- "memoryAgentSamplingProfileInterval";
-} // namespace MemoryAgentState
+constexpr int kDefaultNativeMemorySamplingInterval = 128 * 1024;
using protocol::Response;
InspectorMemoryAgent::InspectorMemoryAgent(InspectedFrames* inspected_frames)
- : frames_(inspected_frames) {}
+ : frames_(inspected_frames),
+ sampling_profile_interval_(&agent_state_, /*default_value=*/0) {}
InspectorMemoryAgent::~InspectorMemoryAgent() = default;
@@ -72,11 +69,8 @@ void InspectorMemoryAgent::Trace(blink::Visitor* visitor) {
}
void InspectorMemoryAgent::Restore() {
- int sampling_interval = 0;
- state_->getInteger(MemoryAgentState::samplingProfileInterval,
- &sampling_interval);
// The action below won't start sampling if the sampling_interval is zero.
- startSampling(protocol::Maybe<int>(sampling_interval),
+ startSampling(protocol::Maybe<int>(sampling_profile_interval_.Get()),
protocol::Maybe<bool>());
}
@@ -87,22 +81,19 @@ Response InspectorMemoryAgent::startSampling(
in_sampling_interval.fromMaybe(kDefaultNativeMemorySamplingInterval);
if (interval <= 0)
return Response::Error("Invalid sampling rate.");
- base::SamplingHeapProfiler::GetInstance()->SetSamplingInterval(interval);
- state_->setInteger(MemoryAgentState::samplingProfileInterval, interval);
+ base::SamplingHeapProfiler::Get()->SetSamplingInterval(interval);
+ sampling_profile_interval_.Set(interval);
if (in_suppressRandomness.fromMaybe(false))
- base::SamplingHeapProfiler::GetInstance()->SuppressRandomnessForTest(true);
- profile_id_ = base::SamplingHeapProfiler::GetInstance()->Start();
+ base::PoissonAllocationSampler::Get()->SuppressRandomnessForTest(true);
+ profile_id_ = base::SamplingHeapProfiler::Get()->Start();
return Response::OK();
}
Response InspectorMemoryAgent::stopSampling() {
- int sampling_interval = 0;
- state_->getInteger(MemoryAgentState::samplingProfileInterval,
- &sampling_interval);
- if (!sampling_interval)
+ if (sampling_profile_interval_.Get() == 0)
return Response::Error("Sampling profiler is not started.");
- base::SamplingHeapProfiler::GetInstance()->Stop();
- state_->setInteger(MemoryAgentState::samplingProfileInterval, 0);
+ base::SamplingHeapProfiler::Get()->Stop();
+ sampling_profile_interval_.Clear();
return Response::OK();
}
@@ -120,15 +111,20 @@ Response InspectorMemoryAgent::getSamplingProfile(
std::unique_ptr<protocol::Memory::SamplingProfile>
InspectorMemoryAgent::GetSamplingProfileById(uint32_t id) {
+ base::ModuleCache module_cache;
std::unique_ptr<protocol::Array<protocol::Memory::SamplingProfileNode>>
samples =
protocol::Array<protocol::Memory::SamplingProfileNode>::create();
std::vector<base::SamplingHeapProfiler::Sample> raw_samples =
- base::SamplingHeapProfiler::GetInstance()->GetSamples(id);
+ base::SamplingHeapProfiler::Get()->GetSamples(id);
for (auto& it : raw_samples) {
std::unique_ptr<protocol::Array<protocol::String>> stack =
protocol::Array<protocol::String>::create();
+ for (const void* frame : it.stack) {
+ uintptr_t address = reinterpret_cast<uintptr_t>(frame);
+ module_cache.GetModuleForAddress(address); // Populates module_cache.
+ }
std::vector<std::string> source_stack = Symbolize(it.stack);
for (auto& it2 : source_stack)
stack->addItem(it2.c_str());
@@ -155,8 +151,21 @@ InspectorMemoryAgent::GetSamplingProfileById(uint32_t id) {
.build());
}
+ std::unique_ptr<protocol::Array<protocol::Memory::Module>> modules =
+ protocol::Array<protocol::Memory::Module>::create();
+ for (const auto* module : module_cache.GetModules()) {
+ modules->addItem(
+ protocol::Memory::Module::create()
+ .setName(module->filename.value().c_str())
+ .setUuid(module->id.c_str())
+ .setBaseAddress(String::Format("0x%" PRIxPTR, module->base_address))
+ .setSize(static_cast<double>(module->size))
+ .build());
+ }
+
return protocol::Memory::SamplingProfile::create()
.setSamples(std::move(samples))
+ .setModules(std::move(modules))
.build();
}
@@ -185,21 +194,19 @@ std::vector<std::string> InspectorMemoryAgent::Symbolize(
line.substr(space_pos == std::string::npos ? 0 : space_pos + 1);
symbols_cache_.insert(addresses_to_symbolize[i], name);
}
+#endif
std::vector<std::string> result;
- for (void* address : addresses)
- result.push_back(symbols_cache_.at(address));
-
- return result;
-#else
- std::vector<std::string> result;
for (void* address : addresses) {
char buffer[20];
- std::snprintf(buffer, sizeof(buffer), "%p", address);
- result.push_back(buffer);
+ std::snprintf(buffer, sizeof(buffer), "0x%" PRIxPTR,
+ reinterpret_cast<uintptr_t>(address));
+ if (symbols_cache_.Contains(address))
+ result.push_back(std::string(buffer) + " " + symbols_cache_.at(address));
+ else
+ result.push_back(buffer);
}
return result;
-#endif
}
} // namespace blink
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 0c6706701d3..e89c94d0016 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
@@ -76,6 +76,7 @@ class CORE_EXPORT InspectorMemoryAgent final
uint32_t profile_id_ = 0;
HashMap<void*, std::string> symbols_cache_;
+ InspectorAgentState::Integer sampling_profile_interval_;
DISALLOW_COPY_AND_ASSIGN(InspectorMemoryAgent);
};
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 15aa529a806..3bda497d2da 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
@@ -90,29 +90,14 @@ using GetResponseBodyCallback =
protocol::Network::Backend::GetResponseBodyCallback;
using protocol::Response;
-namespace NetworkAgentState {
-static const char kNetworkAgentEnabled[] = "networkAgentEnabled";
-static const char kExtraRequestHeaders[] = "extraRequestHeaders";
-static const char kCacheDisabled[] = "cacheDisabled";
-static const char kBypassServiceWorker[] = "bypassServiceWorker";
-static const char kBlockedURLs[] = "blockedURLs";
-static const char kTotalBufferSize[] = "totalBufferSize";
-static const char kResourceBufferSize[] = "resourceBufferSize";
-static const char kMaxPostDataSize[] = "maxPostBodySize";
-} // namespace NetworkAgentState
-
namespace {
#if defined(OS_ANDROID)
-// 10MB
-static size_t g_maximum_total_buffer_size = 10 * 1000 * 1000;
-// 5MB
-static size_t g_maximum_resource_buffer_size = 5 * 1000 * 1000;
+constexpr int kDefaultTotalBufferSize = 10 * 1000 * 1000; // 10 MB
+constexpr int kDefaultResourceBufferSize = 5 * 1000 * 1000; // 5 MB
#else
-// 100MB
-static size_t g_maximum_total_buffer_size = 100 * 1000 * 1000;
-// 10MB
-static size_t g_maximum_resource_buffer_size = 10 * 1000 * 1000;
+constexpr int kDefaultTotalBufferSize = 100 * 1000 * 1000; // 100 MB
+constexpr int kDefaultResourceBufferSize = 10 * 1000 * 1000; // 10 MB
#endif
// Pattern may contain stars ('*') which match to any (possibly empty) string.
@@ -427,13 +412,8 @@ String GetReferrerPolicy(ReferrerPolicy policy) {
} // namespace
void InspectorNetworkAgent::Restore() {
- if (state_->booleanProperty(NetworkAgentState::kNetworkAgentEnabled, false)) {
- Enable(state_->integerProperty(NetworkAgentState::kTotalBufferSize,
- g_maximum_total_buffer_size),
- state_->integerProperty(NetworkAgentState::kResourceBufferSize,
- g_maximum_resource_buffer_size),
- state_->integerProperty(NetworkAgentState::kMaxPostDataSize, 0));
- }
+ if (enabled_.Get())
+ Enable();
}
static std::unique_ptr<protocol::Network::ResourceTiming> BuildObjectForTiming(
@@ -692,25 +672,21 @@ void InspectorNetworkAgent::Trace(blink::Visitor* visitor) {
}
void InspectorNetworkAgent::ShouldBlockRequest(const KURL& url, bool* result) {
- protocol::DictionaryValue* blocked_urls =
- state_->getObject(NetworkAgentState::kBlockedURLs);
- if (!blocked_urls)
+ if (blocked_urls_.IsEmpty())
return;
String url_string = url.GetString();
- for (size_t i = 0; i < blocked_urls->size(); ++i) {
- auto entry = blocked_urls->at(i);
- if (Matches(url_string, entry.first)) {
+ for (const String& blocked : blocked_urls_.Keys()) {
+ if (Matches(url_string, blocked)) {
*result = true;
return;
}
}
- return;
}
void InspectorNetworkAgent::ShouldBypassServiceWorker(bool* result) {
- *result =
- state_->booleanProperty(NetworkAgentState::kBypassServiceWorker, false);
+ if (bypass_service_worker_.Get())
+ *result = true;
}
void InspectorNetworkAgent::DidBlockRequest(
@@ -793,7 +769,7 @@ void InspectorNetworkAgent::WillSendRequestInternal(
initiator_info);
std::unique_ptr<protocol::Network::Request> request_info(
- BuildObjectForResourceRequest(request, max_post_data_size_));
+ BuildObjectForResourceRequest(request, max_post_data_size_.Get()));
// |loader| is null while inspecting worker.
// TODO(horo): Refactor MixedContentChecker and set mixed content type even if
@@ -848,17 +824,16 @@ void InspectorNetworkAgent::WillSendRequest(
loader->GetSubstituteData().IsValid())
return;
- protocol::DictionaryValue* headers =
- state_->getObject(NetworkAgentState::kExtraRequestHeaders);
- if (headers) {
- for (size_t i = 0; i < headers->size(); ++i) {
- auto header = headers->at(i);
- AtomicString header_name = AtomicString(header.first);
- String value;
- if (!header.second->asString(&value))
- continue;
+ if (!extra_request_headers_.IsEmpty()) {
+ for (const WTF::String& key : extra_request_headers_.Keys()) {
+ const WTF::String& value = extra_request_headers_.Get(key);
+ 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.
if (header_name.LowerASCII() == HTTPNames::Referer.LowerASCII())
request.SetHTTPReferrer(Referrer(value, kReferrerPolicyAlways));
else
@@ -870,7 +845,7 @@ void InspectorNetworkAgent::WillSendRequest(
request.SetDevToolsToken(devtools_token_);
- if (state_->booleanProperty(NetworkAgentState::kCacheDisabled, false)) {
+ if (cache_disabled_.Get()) {
if (LoadsFromCacheOnly(request) &&
request.GetRequestContext() != WebURLRequest::kRequestContextInternal) {
request.SetCacheMode(mojom::FetchCacheMode::kUnspecifiedForceCacheMiss);
@@ -879,7 +854,7 @@ void InspectorNetworkAgent::WillSendRequest(
}
request.SetShouldResetAppCache(true);
}
- if (state_->booleanProperty(NetworkAgentState::kBypassServiceWorker, false))
+ if (bypass_service_worker_.Get())
request.SetSkipServiceWorker(true);
InspectorPageAgent::ResourceType type =
@@ -1328,40 +1303,41 @@ void InspectorNetworkAgent::DidReceiveWebSocketFrameError(
Response InspectorNetworkAgent::enable(Maybe<int> total_buffer_size,
Maybe<int> resource_buffer_size,
Maybe<int> max_post_data_size) {
- Enable(total_buffer_size.fromMaybe(g_maximum_total_buffer_size),
- resource_buffer_size.fromMaybe(g_maximum_resource_buffer_size),
- max_post_data_size.fromMaybe(0));
+ total_buffer_size_.Set(total_buffer_size.fromMaybe(kDefaultTotalBufferSize));
+ resource_buffer_size_.Set(
+ resource_buffer_size.fromMaybe(kDefaultResourceBufferSize));
+ max_post_data_size_.Set(max_post_data_size.fromMaybe(0));
+ Enable();
return Response::OK();
}
-void InspectorNetworkAgent::Enable(int total_buffer_size,
- int resource_buffer_size,
- int max_post_data_size) {
+void InspectorNetworkAgent::Enable() {
if (!GetFrontend())
return;
- resources_data_->SetResourcesDataSizeLimits(total_buffer_size,
- resource_buffer_size);
- state_->setBoolean(NetworkAgentState::kNetworkAgentEnabled, true);
- state_->setInteger(NetworkAgentState::kTotalBufferSize, total_buffer_size);
- state_->setInteger(NetworkAgentState::kResourceBufferSize,
- resource_buffer_size);
- state_->setInteger(NetworkAgentState::kMaxPostDataSize, max_post_data_size);
- max_post_data_size_ = max_post_data_size;
+ enabled_.Set(true);
+ resources_data_->SetResourcesDataSizeLimits(total_buffer_size_.Get(),
+ resource_buffer_size_.Get());
instrumenting_agents_->addInspectorNetworkAgent(this);
}
Response InspectorNetworkAgent::disable() {
DCHECK(!pending_request_);
- state_->setBoolean(NetworkAgentState::kNetworkAgentEnabled, false);
instrumenting_agents_->removeInspectorNetworkAgent(this);
+ agent_state_.ClearAllFields();
resources_data_->Clear();
return Response::OK();
}
Response InspectorNetworkAgent::setExtraHTTPHeaders(
std::unique_ptr<protocol::Network::Headers> headers) {
- state_->setObject(NetworkAgentState::kExtraRequestHeaders,
- headers->toValue());
+ extra_request_headers_.Clear();
+ std::unique_ptr<protocol::DictionaryValue> in = headers->toValue();
+ for (size_t i = 0; i < in->size(); ++i) {
+ const auto& entry = in->at(i);
+ String value;
+ if (entry.second && entry.second->asString(&value))
+ extra_request_headers_.Set(entry.first, value);
+ }
return Response::OK();
}
@@ -1413,11 +1389,9 @@ void InspectorNetworkAgent::getResponseBody(
Response InspectorNetworkAgent::setBlockedURLs(
std::unique_ptr<protocol::Array<String>> urls) {
- std::unique_ptr<protocol::DictionaryValue> new_list =
- protocol::DictionaryValue::create();
+ blocked_urls_.Clear();
for (size_t i = 0; i < urls->length(); i++)
- new_list->setBoolean(urls->get(i), true);
- state_->setObject(NetworkAgentState::kBlockedURLs, std::move(new_list));
+ blocked_urls_.Set(urls->get(i), true);
return Response::OK();
}
@@ -1495,14 +1469,14 @@ Response InspectorNetworkAgent::setCacheDisabled(bool cache_disabled) {
// TODO(ananta)
// We should extract network cache state into a global entity which can be
// queried from FrameLoader and other places.
- state_->setBoolean(NetworkAgentState::kCacheDisabled, cache_disabled);
+ cache_disabled_.Set(cache_disabled);
if (cache_disabled && IsMainThread())
GetMemoryCache()->EvictResources();
return Response::OK();
}
Response InspectorNetworkAgent::setBypassServiceWorker(bool bypass) {
- state_->setBoolean(NetworkAgentState::kBypassServiceWorker, bypass);
+ bypass_service_worker_.Set(bypass);
return Response::OK();
}
@@ -1537,7 +1511,7 @@ void InspectorNetworkAgent::DidCommitLoad(LocalFrame* frame,
if (loader->GetFrame() != inspected_frames_->Root())
return;
- if (state_->booleanProperty(NetworkAgentState::kCacheDisabled, false))
+ if (cache_disabled_.Get())
GetMemoryCache()->EvictResources();
resources_data_->Clear(IdentifiersFactory::LoaderId(loader));
@@ -1667,7 +1641,7 @@ bool InspectorNetworkAgent::FetchResourceContent(Document* document,
}
String InspectorNetworkAgent::NavigationInitiatorInfo(LocalFrame* frame) {
- if (!state_->booleanProperty(NetworkAgentState::kNetworkAgentEnabled, false))
+ if (!enabled_.Get())
return String();
FrameNavigationInitiatorMap::iterator it =
frame_navigation_initiator_map_.find(IdentifiersFactory::FrameId(frame));
@@ -1688,9 +1662,8 @@ InspectorNetworkAgent::InspectorNetworkAgent(
: inspected_frames_(inspected_frames),
worker_global_scope_(worker_global_scope),
v8_session_(v8_session),
- resources_data_(
- NetworkResourcesData::Create(g_maximum_total_buffer_size,
- g_maximum_resource_buffer_size)),
+ resources_data_(NetworkResourcesData::Create(kDefaultTotalBufferSize,
+ kDefaultResourceBufferSize)),
devtools_token_(worker_global_scope_
? worker_global_scope_->GetParentDevToolsToken()
: inspected_frames->Root()->GetDevToolsFrameToken()),
@@ -1702,13 +1675,22 @@ InspectorNetworkAgent::InspectorNetworkAgent(
TaskType::kInternalLoading),
this,
&InspectorNetworkAgent::RemoveFinishedReplayXHRFired),
- max_post_data_size_(0) {
+ enabled_(&agent_state_, /*default_value=*/false),
+ cache_disabled_(&agent_state_, /*default_value=*/false),
+ bypass_service_worker_(&agent_state_, /*default_value=*/false),
+ blocked_urls_(&agent_state_, /*default_value=*/false),
+ extra_request_headers_(&agent_state_, /*default_value=*/WTF::String()),
+ total_buffer_size_(&agent_state_,
+ /*default_value=*/kDefaultTotalBufferSize),
+ resource_buffer_size_(&agent_state_,
+ /*default_value=*/kDefaultResourceBufferSize),
+ max_post_data_size_(&agent_state_, /*default_value=*/0) {
DCHECK((IsMainThread() && !worker_global_scope_) ||
(!IsMainThread() && worker_global_scope_));
}
void InspectorNetworkAgent::ShouldForceCORSPreflight(bool* result) {
- if (state_->booleanProperty(NetworkAgentState::kCacheDisabled, false))
+ if (cache_disabled_.Get())
*result = true;
}
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 ccee3be2318..8a9127d4efa 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
@@ -234,9 +234,7 @@ class CORE_EXPORT InspectorNetworkAgent final
String NavigationInitiatorInfo(LocalFrame*);
private:
- void Enable(int total_buffer_size,
- int resource_buffer_size,
- int max_post_data_size);
+ void Enable();
void WillSendRequestInternal(ExecutionContext*,
unsigned long identifier,
DocumentLoader*,
@@ -286,7 +284,14 @@ class CORE_EXPORT InspectorNetworkAgent final
HeapHashSet<Member<XMLHttpRequest>> replay_xhrs_;
HeapHashSet<Member<XMLHttpRequest>> replay_xhrs_to_be_deleted_;
TaskRunnerTimer<InspectorNetworkAgent> remove_finished_replay_xhr_timer_;
- int max_post_data_size_;
+ InspectorAgentState::Boolean enabled_;
+ InspectorAgentState::Boolean cache_disabled_;
+ InspectorAgentState::Boolean bypass_service_worker_;
+ InspectorAgentState::BooleanMap blocked_urls_;
+ InspectorAgentState::StringMap extra_request_headers_;
+ InspectorAgentState::Integer total_buffer_size_;
+ InspectorAgentState::Integer resource_buffer_size_;
+ InspectorAgentState::Integer max_post_data_size_;
};
} // namespace blink
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 13cbc84b416..f3291721bf4 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
@@ -76,18 +76,6 @@ using protocol::Maybe;
using protocol::Response;
namespace {
-
-namespace OverlayAgentState {
-static const char kEnabled[] = "enabled";
-static const char kShowDebugBorders[] = "showDebugBorders";
-static const char kShowFPSCounter[] = "showFPSCounter";
-static const char kShowPaintRects[] = "showPaintRects";
-static const char kShowScrollBottleneckRects[] = "showScrollBottleneckRects";
-static const char kShowSizeOnResize[] = "showSizeOnResize";
-static const char kSuspended[] = "suspended";
-static const char kPausedInDebuggerMessage[] = "pausedInDebuggerMessage";
-} // namespace OverlayAgentState
-
Node* HoveredNodeForPoint(LocalFrame* frame,
const IntPoint& point_in_root_frame,
bool ignore_pointer_events_none) {
@@ -220,15 +208,12 @@ InspectorOverlayAgent::InspectorOverlayAgent(
InspectorDOMAgent* dom_agent)
: frame_impl_(frame_impl),
inspected_frames_(inspected_frames),
- enabled_(false),
- draw_view_size_(false),
resize_timer_active_(false),
omit_tooltip_(false),
timer_(
frame_impl->GetFrame()->GetTaskRunner(TaskType::kInternalInspector),
this,
&InspectorOverlayAgent::OnTimer),
- suspended_(false),
disposed_(false),
in_layout_(false),
needs_update_(false),
@@ -236,7 +221,15 @@ InspectorOverlayAgent::InspectorOverlayAgent(
dom_agent_(dom_agent),
swallow_next_mouse_up_(false),
inspect_mode_(kNotSearching),
- backend_node_id_to_inspect_(0) {}
+ backend_node_id_to_inspect_(0),
+ enabled_(&agent_state_, /*default_value=*/false),
+ suspended_(&agent_state_, /*default_value=*/false),
+ show_debug_borders_(&agent_state_, /*default_value=*/false),
+ show_fps_counter_(&agent_state_, /*default_value=*/false),
+ show_paint_rects_(&agent_state_, /*default_value=*/false),
+ show_scroll_bottleneck_rects_(&agent_state_, /*default_value=*/false),
+ show_size_on_resize_(&agent_state_, /*default_value=*/false),
+ paused_in_debugger_message_(&agent_state_, /*default_value=*/String()) {}
InspectorOverlayAgent::~InspectorOverlayAgent() {
DCHECK(!overlay_page_);
@@ -256,22 +249,14 @@ void InspectorOverlayAgent::Trace(blink::Visitor* visitor) {
}
void InspectorOverlayAgent::Restore() {
- if (state_->booleanProperty(OverlayAgentState::kEnabled, false))
- enabled_ = true;
- setShowDebugBorders(
- state_->booleanProperty(OverlayAgentState::kShowDebugBorders, false));
- setShowFPSCounter(
- state_->booleanProperty(OverlayAgentState::kShowFPSCounter, false));
- setShowPaintRects(
- state_->booleanProperty(OverlayAgentState::kShowPaintRects, false));
- setShowScrollBottleneckRects(state_->booleanProperty(
- OverlayAgentState::kShowScrollBottleneckRects, false));
- setShowViewportSizeOnResize(
- state_->booleanProperty(OverlayAgentState::kShowSizeOnResize, false));
- String message;
- if (state_->getString(OverlayAgentState::kPausedInDebuggerMessage, &message))
- setPausedInDebuggerMessage(message);
- setSuspended(state_->booleanProperty(OverlayAgentState::kSuspended, false));
+ setShowDebugBorders(show_debug_borders_.Get());
+ setShowFPSCounter(show_fps_counter_.Get());
+ setShowPaintRects(show_paint_rects_.Get());
+ setShowScrollBottleneckRects(show_scroll_bottleneck_rects_.Get());
+ setShowViewportSizeOnResize(show_size_on_resize_.Get());
+ if (paused_in_debugger_message_.Get().IsNull())
+ setPausedInDebuggerMessage(paused_in_debugger_message_.Get());
+ setSuspended(suspended_.Get());
}
void InspectorOverlayAgent::Dispose() {
@@ -283,8 +268,7 @@ void InspectorOverlayAgent::Dispose() {
Response InspectorOverlayAgent::enable() {
if (!dom_agent_->Enabled())
return Response::Error("DOM should be enabled first");
- state_->setBoolean(OverlayAgentState::kEnabled, true);
- enabled_ = true;
+ enabled_.Set(true);
if (backend_node_id_to_inspect_)
GetFrontend()->inspectNodeRequested(backend_node_id_to_inspect_);
backend_node_id_to_inspect_ = 0;
@@ -292,8 +276,7 @@ Response InspectorOverlayAgent::enable() {
}
Response InspectorOverlayAgent::disable() {
- state_->setBoolean(OverlayAgentState::kEnabled, false);
- enabled_ = false;
+ enabled_.Clear();
setShowDebugBorders(false);
setShowFPSCounter(false);
setShowPaintRects(false);
@@ -307,7 +290,7 @@ Response InspectorOverlayAgent::disable() {
}
Response InspectorOverlayAgent::setShowDebugBorders(bool show) {
- state_->setBoolean(OverlayAgentState::kShowDebugBorders, show);
+ show_debug_borders_.Set(show);
if (show) {
Response response = CompositingEnabled();
if (!response.isSuccess())
@@ -318,7 +301,7 @@ Response InspectorOverlayAgent::setShowDebugBorders(bool show) {
}
Response InspectorOverlayAgent::setShowFPSCounter(bool show) {
- state_->setBoolean(OverlayAgentState::kShowFPSCounter, show);
+ show_fps_counter_.Set(show);
if (show) {
Response response = CompositingEnabled();
if (!response.isSuccess())
@@ -329,7 +312,7 @@ Response InspectorOverlayAgent::setShowFPSCounter(bool show) {
}
Response InspectorOverlayAgent::setShowPaintRects(bool show) {
- state_->setBoolean(OverlayAgentState::kShowPaintRects, show);
+ show_paint_rects_.Set(show);
if (show) {
Response response = CompositingEnabled();
if (!response.isSuccess())
@@ -342,7 +325,7 @@ Response InspectorOverlayAgent::setShowPaintRects(bool show) {
}
Response InspectorOverlayAgent::setShowScrollBottleneckRects(bool show) {
- state_->setBoolean(OverlayAgentState::kShowScrollBottleneckRects, show);
+ show_scroll_bottleneck_rects_.Set(show);
if (show) {
Response response = CompositingEnabled();
if (!response.isSuccess())
@@ -353,25 +336,21 @@ Response InspectorOverlayAgent::setShowScrollBottleneckRects(bool show) {
}
Response InspectorOverlayAgent::setShowViewportSizeOnResize(bool show) {
- state_->setBoolean(OverlayAgentState::kShowSizeOnResize, show);
- draw_view_size_ = show;
+ show_size_on_resize_.Set(show);
return Response::OK();
}
Response InspectorOverlayAgent::setPausedInDebuggerMessage(
Maybe<String> message) {
- String just_message = message.fromMaybe(String());
- state_->setString(OverlayAgentState::kPausedInDebuggerMessage, just_message);
- paused_in_debugger_message_ = just_message;
+ paused_in_debugger_message_.Set(message.fromMaybe(String()));
ScheduleUpdate();
return Response::OK();
}
Response InspectorOverlayAgent::setSuspended(bool suspended) {
- state_->setBoolean(OverlayAgentState::kSuspended, suspended);
- if (suspended && !suspended_)
+ if (suspended && !suspended_.Get())
ClearInternal();
- suspended_ = suspended;
+ suspended_.Set(suspended);
return Response::OK();
}
@@ -491,40 +470,34 @@ void InspectorOverlayAgent::Invalidate() {
if (!page_overlay_) {
page_overlay_ = PageOverlay::Create(
- frame_impl_, std::make_unique<InspectorPageOverlayDelegate>(*this));
+ frame_impl_->GetFrame(),
+ std::make_unique<InspectorPageOverlayDelegate>(*this));
}
page_overlay_->Update();
}
-void InspectorOverlayAgent::PaintOverlay() {
- UpdateAllLifecyclePhases();
- // TODO(chrishtr): integrate paint into the overlay's lifecycle.
- if (page_overlay_ && page_overlay_->GetGraphicsLayer())
- page_overlay_->GetGraphicsLayer()->Paint(nullptr);
-}
-
-void InspectorOverlayAgent::LayoutOverlay() {
+void InspectorOverlayAgent::UpdateAllOverlayLifecyclePhases() {
if (page_overlay_)
page_overlay_->Update();
+
+ if (!IsEmpty()) {
+ base::AutoReset<bool> scoped(&in_layout_, true);
+ if (needs_update_) {
+ needs_update_ = false;
+ RebuildOverlayPage();
+ }
+ OverlayMainFrame()->View()->UpdateAllLifecyclePhases();
+ }
+
+ if (page_overlay_ && page_overlay_->GetGraphicsLayer())
+ page_overlay_->GetGraphicsLayer()->Paint(nullptr);
}
bool InspectorOverlayAgent::IsInspectorLayer(GraphicsLayer* layer) {
return page_overlay_ && page_overlay_->GetGraphicsLayer() == layer;
}
-void InspectorOverlayAgent::UpdateAllLifecyclePhases() {
- if (IsEmpty())
- return;
-
- base::AutoReset<bool> scoped(&in_layout_, true);
- if (needs_update_) {
- needs_update_ = false;
- RebuildOverlayPage();
- }
- OverlayMainFrame()->View()->UpdateAllLifecyclePhases();
-}
-
void InspectorOverlayAgent::DispatchBufferedTouchEvents() {
if (IsEmpty())
return;
@@ -640,12 +613,12 @@ void InspectorOverlayAgent::InnerHighlightQuad(
bool InspectorOverlayAgent::IsEmpty() {
if (disposed_)
return true;
- if (suspended_)
+ if (suspended_.Get())
return true;
- bool has_visible_elements = highlight_node_ || event_target_node_ ||
- highlight_quad_ ||
- (resize_timer_active_ && draw_view_size_) ||
- !paused_in_debugger_message_.IsNull();
+ bool has_visible_elements =
+ highlight_node_ || event_target_node_ || highlight_quad_ ||
+ (resize_timer_active_ && show_size_on_resize_.Get()) ||
+ !paused_in_debugger_message_.Get().IsNull();
return !has_visible_elements && inspect_mode_ == kNotSearching;
}
@@ -742,14 +715,15 @@ void InspectorOverlayAgent::DrawQuadHighlight() {
}
void InspectorOverlayAgent::DrawPausedInDebuggerMessage() {
- if (inspect_mode_ == kNotSearching && !paused_in_debugger_message_.IsNull()) {
+ if (inspect_mode_ == kNotSearching &&
+ !paused_in_debugger_message_.Get().IsNull()) {
EvaluateInOverlay("drawPausedInDebuggerMessage",
- paused_in_debugger_message_);
+ paused_in_debugger_message_.Get());
}
}
void InspectorOverlayAgent::DrawViewSize() {
- if (resize_timer_active_ && draw_view_size_)
+ if (resize_timer_active_ && show_size_on_resize_.Get())
EvaluateInOverlay("drawViewSize", "");
}
@@ -945,7 +919,7 @@ void InspectorOverlayAgent::ClearInternal() {
overlay_host_.Clear();
}
resize_timer_active_ = false;
- paused_in_debugger_message_ = String();
+ paused_in_debugger_message_.Clear();
inspect_mode_ = kNotSearching;
screenshot_mode_ = false;
timer_.Stop();
@@ -964,7 +938,7 @@ void InspectorOverlayAgent::OverlaySteppedOver() {
}
void InspectorOverlayAgent::PageLayoutInvalidated(bool resized) {
- if (resized && draw_view_size_) {
+ if (resized && show_size_on_resize_.Get()) {
resize_timer_active_ = true;
timer_.StartOneShot(TimeDelta::FromSeconds(1), FROM_HERE);
}
@@ -1145,7 +1119,7 @@ void InspectorOverlayAgent::Inspect(Node* inspected_node) {
return;
int backend_node_id = DOMNodeIds::IdForNode(node);
- if (!enabled_) {
+ if (!enabled_.Get()) {
backend_node_id_to_inspect_ = backend_node_id;
return;
}
@@ -1154,7 +1128,7 @@ void InspectorOverlayAgent::Inspect(Node* inspected_node) {
}
void InspectorOverlayAgent::NodeHighlightRequested(Node* node) {
- if (!enabled_)
+ if (!enabled_.Get())
return;
while (node && !node->IsElementNode() && !node->IsDocumentNode() &&
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 ec0ad5f0b1c..c2354e321a4 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
@@ -122,8 +122,10 @@ class CORE_EXPORT InspectorOverlayAgent final
bool HandleInputEvent(const WebInputEvent&);
void PageLayoutInvalidated(bool resized);
String EvaluateInOverlayForTest(const String&);
- void PaintOverlay();
- void LayoutOverlay();
+
+ // Update the complete lifecycle (e.g., layout, paint) for the overlay.
+ void UpdateAllOverlayLifecyclePhases();
+
bool IsInspectorLayer(GraphicsLayer*);
private:
@@ -160,7 +162,6 @@ class CORE_EXPORT InspectorOverlayAgent final
void Invalidate();
void ScheduleUpdate();
void ClearInternal();
- void UpdateAllLifecyclePhases();
bool HandleMouseDown(const WebMouseEvent&);
bool HandleMouseUp(const WebMouseEvent&);
@@ -190,8 +191,6 @@ class CORE_EXPORT InspectorOverlayAgent final
Member<WebLocalFrameImpl> frame_impl_;
Member<InspectedFrames> inspected_frames_;
- bool enabled_;
- String paused_in_debugger_message_;
Member<Node> highlight_node_;
Member<Node> event_target_node_;
InspectorHighlightConfig node_highlight_config_;
@@ -201,11 +200,9 @@ class CORE_EXPORT InspectorOverlayAgent final
Member<InspectorOverlayHost> overlay_host_;
Color quad_content_color_;
Color quad_content_outline_color_;
- bool draw_view_size_;
bool resize_timer_active_;
bool omit_tooltip_;
TaskRunnerTimer<InspectorOverlayAgent> timer_;
- bool suspended_;
bool disposed_;
bool in_layout_;
bool needs_update_;
@@ -220,6 +217,14 @@ class CORE_EXPORT InspectorOverlayAgent final
bool screenshot_mode_ = false;
IntPoint screenshot_anchor_;
IntPoint screenshot_position_;
+ InspectorAgentState::Boolean enabled_;
+ InspectorAgentState::Boolean suspended_;
+ InspectorAgentState::Boolean show_debug_borders_;
+ InspectorAgentState::Boolean show_fps_counter_;
+ InspectorAgentState::Boolean show_paint_rects_;
+ InspectorAgentState::Boolean show_scroll_bottleneck_rects_;
+ InspectorAgentState::Boolean show_size_on_resize_;
+ InspectorAgentState::String paused_in_debugger_message_;
DISALLOW_COPY_AND_ASSIGN(InspectorOverlayAgent);
};
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 665eadcb132..76e8e22c33d 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
@@ -43,7 +43,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/local_frame_view.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/html/html_frame_owner_element.h"
#include "third_party/blink/renderer/core/html/imports/html_import_loader.h"
@@ -83,25 +86,6 @@ namespace blink {
using protocol::Response;
-namespace PageAgentState {
-static const char kPageAgentEnabled[] = "pageAgentEnabled";
-static const char kPageAgentScriptsToEvaluateOnLoad[] =
- "pageAgentScriptsToEvaluateOnLoad";
-static const char kScreencastEnabled[] = "screencastEnabled";
-static const char kLifecycleEventsEnabled[] = "lifecycleEventsEnabled";
-static const char kBypassCSPEnabled[] = "bypassCSPEnabled";
-static const char kStandardFontFamily[] = "standardFontFamily";
-static const char kFixedFontFamily[] = "fixedFontFamily";
-static const char kSerifFontFamily[] = "serifFontFamily";
-static const char kSansSerifFontFamily[] = "sansSerifFontFamily";
-static const char kCursiveFontFamily[] = "cursiveFontFamily";
-static const char kFantasyFontFamily[] = "fantasyFontFamily";
-static const char kPictographFontFamily[] = "pictographFontFamily";
-static const char kStandardFontSize[] = "standardFontSize";
-static const char kFixedFontSize[] = "fixedFontSize";
-static const char kProduceCompilationCache[] = "generateCompilationCache";
-} // namespace PageAgentState
-
namespace {
String ScheduledNavigationReasonToProtocol(ScheduledNavigation::Reason reason) {
@@ -463,82 +447,89 @@ InspectorPageAgent::InspectorPageAgent(
: inspected_frames_(inspected_frames),
v8_session_(v8_session),
client_(client),
- last_script_identifier_(0),
- enabled_(false),
reloading_(false),
inspector_resource_content_loader_(resource_content_loader),
resource_content_loader_client_id_(
- resource_content_loader->CreateClientId()) {}
+ resource_content_loader->CreateClientId()),
+ enabled_(&agent_state_, /*default_value=*/false),
+ screencast_enabled_(&agent_state_, /*default_value=*/false),
+ lifecycle_events_enabled_(&agent_state_, /*default_value=*/false),
+ bypass_csp_enabled_(&agent_state_, /*default_value=*/false),
+ scripts_to_evaluate_on_load_(&agent_state_,
+ /*default_value=*/WTF::String()),
+ standard_font_family_(&agent_state_, /*default_value=*/WTF::String()),
+ fixed_font_family_(&agent_state_, /*default_value=*/WTF::String()),
+ serif_font_family_(&agent_state_, /*default_value=*/WTF::String()),
+ sans_serif_font_family_(&agent_state_, /*default_value=*/WTF::String()),
+ cursive_font_family_(&agent_state_, /*default_value=*/WTF::String()),
+ fantasy_font_family_(&agent_state_, /*default_value=*/WTF::String()),
+ pictograph_font_family_(&agent_state_, /*default_value=*/WTF::String()),
+ standard_font_size_(&agent_state_, /*default_value=*/0),
+ fixed_font_size_(&agent_state_, /*default_value=*/0),
+ produce_compilation_cache_(&agent_state_, /*default_value=*/false) {}
void InspectorPageAgent::Restore() {
- if (state_->booleanProperty(PageAgentState::kPageAgentEnabled, false))
+ if (enabled_.Get())
enable();
- if (state_->booleanProperty(PageAgentState::kBypassCSPEnabled, false))
+ if (bypass_csp_enabled_.Get())
setBypassCSP(true);
-
// Re-apply generic fonts overrides.
- String font;
bool notifyGenericFontFamilyChange = false;
LocalFrame* frame = inspected_frames_->Root();
auto* settings = frame->GetSettings();
if (settings) {
auto& family_settings = settings->GetGenericFontFamilySettings();
- if (state_->getString(PageAgentState::kStandardFontFamily, &font)) {
- family_settings.UpdateStandard(AtomicString(font));
+ if (!standard_font_family_.Get().IsNull()) {
+ family_settings.UpdateStandard(AtomicString(standard_font_family_.Get()));
notifyGenericFontFamilyChange = true;
}
- if (state_->getString(PageAgentState::kFixedFontFamily, &font)) {
- family_settings.UpdateFixed(AtomicString(font));
+ if (!fixed_font_family_.Get().IsNull()) {
+ family_settings.UpdateFixed(AtomicString(fixed_font_family_.Get()));
notifyGenericFontFamilyChange = true;
}
- if (state_->getString(PageAgentState::kSerifFontFamily, &font)) {
- family_settings.UpdateSerif(AtomicString(font));
+ if (!serif_font_family_.Get().IsNull()) {
+ family_settings.UpdateSerif(AtomicString(serif_font_family_.Get()));
notifyGenericFontFamilyChange = true;
}
- if (state_->getString(PageAgentState::kSansSerifFontFamily, &font)) {
- family_settings.UpdateSansSerif(AtomicString(font));
+ if (!sans_serif_font_family_.Get().IsNull()) {
+ family_settings.UpdateSansSerif(
+ AtomicString(sans_serif_font_family_.Get()));
notifyGenericFontFamilyChange = true;
}
- if (state_->getString(PageAgentState::kCursiveFontFamily, &font)) {
- family_settings.UpdateCursive(AtomicString(font));
+ if (!cursive_font_family_.Get().IsNull()) {
+ family_settings.UpdateCursive(AtomicString(cursive_font_family_.Get()));
notifyGenericFontFamilyChange = true;
}
- if (state_->getString(PageAgentState::kFantasyFontFamily, &font)) {
- family_settings.UpdateFantasy(AtomicString(font));
+ if (!fantasy_font_family_.Get().IsNull()) {
+ family_settings.UpdateFantasy(AtomicString(fantasy_font_family_.Get()));
notifyGenericFontFamilyChange = true;
}
- if (state_->getString(PageAgentState::kPictographFontFamily, &font)) {
- family_settings.UpdatePictograph(AtomicString(font));
+ if (!pictograph_font_family_.Get().IsNull()) {
+ family_settings.UpdatePictograph(
+ AtomicString(pictograph_font_family_.Get()));
notifyGenericFontFamilyChange = true;
}
- if (notifyGenericFontFamilyChange) {
+ if (notifyGenericFontFamilyChange)
settings->NotifyGenericFontFamilyChange();
- }
}
// Re-apply default font size overrides.
- int font_size;
if (settings) {
- if (state_->getInteger(PageAgentState::kStandardFontSize, &font_size)) {
- settings->SetDefaultFontSize(font_size);
- }
- if (state_->getInteger(PageAgentState::kFixedFontSize, &font_size)) {
- settings->SetDefaultFixedFontSize(font_size);
- }
+ if (standard_font_size_.Get() != 0)
+ settings->SetDefaultFontSize(standard_font_size_.Get());
+ if (fixed_font_size_.Get() != 0)
+ settings->SetDefaultFixedFontSize(fixed_font_size_.Get());
}
}
Response InspectorPageAgent::enable() {
- enabled_ = true;
- state_->setBoolean(PageAgentState::kPageAgentEnabled, true);
+ enabled_.Set(true);
instrumenting_agents_->addInspectorPageAgent(this);
return Response::OK();
}
Response InspectorPageAgent::disable() {
- enabled_ = false;
- state_->setBoolean(PageAgentState::kPageAgentEnabled, false);
- state_->remove(PageAgentState::kPageAgentScriptsToEvaluateOnLoad);
+ agent_state_.ClearAllFields();
script_to_evaluate_on_load_once_ = String();
pending_script_to_evaluate_on_load_once_ = String();
instrumenting_agents_->removeInspectorPageAgent(this);
@@ -553,32 +544,25 @@ Response InspectorPageAgent::disable() {
Response InspectorPageAgent::addScriptToEvaluateOnLoad(const String& source,
String* identifier) {
- protocol::DictionaryValue* scripts =
- state_->getObject(PageAgentState::kPageAgentScriptsToEvaluateOnLoad);
- if (!scripts) {
- std::unique_ptr<protocol::DictionaryValue> new_scripts =
- protocol::DictionaryValue::create();
- scripts = new_scripts.get();
- state_->setObject(PageAgentState::kPageAgentScriptsToEvaluateOnLoad,
- std::move(new_scripts));
+ std::vector<WTF::String> keys = scripts_to_evaluate_on_load_.Keys();
+ auto result = std::max_element(
+ keys.begin(), keys.end(), [](const WTF::String& a, const WTF::String& b) {
+ return Decimal::FromString(a) < Decimal::FromString(b);
+ });
+ if (result == keys.end()) {
+ scripts_to_evaluate_on_load_.Set(String::Number(1), source);
+ } else {
+ scripts_to_evaluate_on_load_.Set(
+ String::Number(Decimal::FromString(*result).ToDouble() + 1), source);
}
- // Assure we don't override existing ids -- m_lastScriptIdentifier could get
- // out of sync WRT actual scripts once we restored the scripts from the cookie
- // during navigation.
- do {
- *identifier = String::Number(++last_script_identifier_);
- } while (scripts->get(*identifier));
- scripts->setString(*identifier, source);
return Response::OK();
}
Response InspectorPageAgent::removeScriptToEvaluateOnLoad(
const String& identifier) {
- protocol::DictionaryValue* scripts =
- state_->getObject(PageAgentState::kPageAgentScriptsToEvaluateOnLoad);
- if (!scripts || !scripts->get(identifier))
+ if (scripts_to_evaluate_on_load_.Get(identifier).IsNull())
return Response::Error("Script not found");
- scripts->remove(identifier);
+ scripts_to_evaluate_on_load_.Clear(identifier);
return Response::OK();
}
@@ -594,7 +578,7 @@ Response InspectorPageAgent::removeScriptToEvaluateOnNewDocument(
}
Response InspectorPageAgent::setLifecycleEventsEnabled(bool enabled) {
- state_->setBoolean(PageAgentState::kLifecycleEventsEnabled, enabled);
+ lifecycle_events_enabled_.Set(enabled);
if (!enabled)
return Response::OK();
@@ -651,11 +635,6 @@ Response InspectorPageAgent::reload(
optional_script_to_evaluate_on_load.fromMaybe("");
v8_session_->setSkipAllPauses(true);
reloading_ = true;
- inspected_frames_->Root()->Reload(
- optional_bypass_cache.fromMaybe(false)
- ? WebFrameLoadType::kReloadBypassingCache
- : WebFrameLoadType::kReload,
- ClientRedirectPolicy::kNotClientRedirect);
return Response::OK();
}
@@ -756,7 +735,7 @@ void InspectorPageAgent::getResourceContent(
const String& frame_id,
const String& url,
std::unique_ptr<GetResourceContentCallback> callback) {
- if (!enabled_) {
+ if (!enabled_.Get()) {
callback->sendFailure(Response::Error("Agent is not enabled."));
return;
}
@@ -807,7 +786,7 @@ void InspectorPageAgent::searchInResource(
Maybe<bool> optional_case_sensitive,
Maybe<bool> optional_is_regex,
std::unique_ptr<SearchInResourceCallback> callback) {
- if (!enabled_) {
+ if (!enabled_.Get()) {
callback->sendFailure(Response::Error("Agent is not enabled."));
return;
}
@@ -823,7 +802,7 @@ void InspectorPageAgent::searchInResource(
Response InspectorPageAgent::setBypassCSP(bool enabled) {
LocalFrame* frame = inspected_frames_->Root();
frame->GetSettings()->SetBypassCSP(enabled);
- state_->setBoolean(PageAgentState::kBypassCSPEnabled, enabled);
+ bypass_csp_enabled_.Set(enabled);
return Response::OK();
}
@@ -852,16 +831,15 @@ void InspectorPageAgent::DidNavigateWithinDocument(LocalFrame* frame) {
void InspectorPageAgent::DidClearDocumentOfWindowObject(LocalFrame* frame) {
if (!GetFrontend())
return;
-
- protocol::DictionaryValue* scripts =
- state_->getObject(PageAgentState::kPageAgentScriptsToEvaluateOnLoad);
- if (scripts) {
- for (size_t i = 0; i < scripts->size(); ++i) {
- auto script = scripts->at(i);
- String script_text;
- if (script.second->asString(&script_text))
- frame->GetScriptController().ExecuteScriptInMainWorld(script_text);
- }
+ std::vector<WTF::String> keys = scripts_to_evaluate_on_load_.Keys();
+ std::sort(keys.begin(), keys.end(),
+ [](const WTF::String& a, const WTF::String& b) {
+ return Decimal::FromString(a) < Decimal::FromString(b);
+ });
+
+ for (const WTF::String& key : keys) {
+ const WTF::String& script = scripts_to_evaluate_on_load_.Get(key);
+ frame->GetScriptController().ExecuteScriptInMainWorld(script);
}
if (!script_to_evaluate_on_load_once_.IsEmpty()) {
frame->GetScriptController().ExecuteScriptInMainWorld(
@@ -913,8 +891,7 @@ void InspectorPageAgent::FrameDetachedFromParent(LocalFrame* frame) {
}
bool InspectorPageAgent::ScreencastEnabled() {
- return enabled_ &&
- state_->booleanProperty(PageAgentState::kScreencastEnabled, false);
+ return enabled_.Get() && screencast_enabled_.Get();
}
void InspectorPageAgent::FrameStartedLoading(LocalFrame* frame) {
@@ -964,8 +941,7 @@ void InspectorPageAgent::LifecycleEvent(LocalFrame* frame,
DocumentLoader* loader,
const char* name,
double timestamp) {
- if (!loader ||
- !state_->booleanProperty(PageAgentState::kLifecycleEventsEnabled, false))
+ if (!loader || !lifecycle_events_enabled_.Get())
return;
GetFrontend()->lifecycleEvent(IdentifiersFactory::FrameId(frame),
IdentifiersFactory::LoaderId(loader), name,
@@ -993,7 +969,7 @@ void InspectorPageAgent::Did(const probe::RecalculateStyle&) {
}
void InspectorPageAgent::PageLayoutInvalidated(bool resized) {
- if (enabled_ && client_)
+ if (enabled_.Get() && client_)
client_->PageLayoutInvalidated(resized);
}
@@ -1118,12 +1094,12 @@ Response InspectorPageAgent::startScreencast(Maybe<String> format,
Maybe<int> max_width,
Maybe<int> max_height,
Maybe<int> every_nth_frame) {
- state_->setBoolean(PageAgentState::kScreencastEnabled, true);
+ screencast_enabled_.Set(true);
return Response::OK();
}
Response InspectorPageAgent::stopScreencast() {
- state_->setBoolean(PageAgentState::kScreencastEnabled, false);
+ screencast_enabled_.Set(false);
return Response::OK();
}
@@ -1214,46 +1190,34 @@ Response InspectorPageAgent::setFontFamilies(
if (settings) {
auto& family_settings = settings->GetGenericFontFamilySettings();
if (font_families->hasStandard()) {
- state_->setString(PageAgentState::kStandardFontFamily,
- font_families->getStandard(String()));
- family_settings.UpdateStandard(
- AtomicString(font_families->getStandard(String())));
+ standard_font_family_.Set(font_families->getStandard(String()));
+ family_settings.UpdateStandard(AtomicString(standard_font_family_.Get()));
}
if (font_families->hasFixed()) {
- state_->setString(PageAgentState::kFixedFontFamily,
- font_families->getFixed(String()));
- family_settings.UpdateFixed(
- AtomicString(font_families->getFixed(String())));
+ fixed_font_family_.Set(font_families->getFixed(String()));
+ family_settings.UpdateFixed(AtomicString(fixed_font_family_.Get()));
}
if (font_families->hasSerif()) {
- state_->setString(PageAgentState::kSerifFontFamily,
- font_families->getSerif(String()));
- family_settings.UpdateSerif(
- AtomicString(font_families->getSerif(String())));
+ serif_font_family_.Set(font_families->getSerif(String()));
+ family_settings.UpdateSerif(AtomicString(serif_font_family_.Get()));
}
if (font_families->hasSansSerif()) {
- state_->setString(PageAgentState::kSansSerifFontFamily,
- font_families->getSansSerif(String()));
+ sans_serif_font_family_.Set(font_families->getSansSerif(String()));
family_settings.UpdateSansSerif(
- AtomicString(font_families->getSansSerif(String())));
+ AtomicString(sans_serif_font_family_.Get()));
}
if (font_families->hasCursive()) {
- state_->setString(PageAgentState::kCursiveFontFamily,
- font_families->getCursive(String()));
- family_settings.UpdateCursive(
- AtomicString(font_families->getCursive(String())));
+ cursive_font_family_.Set(font_families->getCursive(String()));
+ family_settings.UpdateCursive(AtomicString(cursive_font_family_.Get()));
}
if (font_families->hasFantasy()) {
- state_->setString(PageAgentState::kFantasyFontFamily,
- font_families->getFantasy(String()));
- family_settings.UpdateFantasy(
- AtomicString(font_families->getFantasy(String())));
+ fantasy_font_family_.Set(font_families->getFantasy(String()));
+ family_settings.UpdateFantasy(AtomicString(fantasy_font_family_.Get()));
}
if (font_families->hasPictograph()) {
- state_->setString(PageAgentState::kPictographFontFamily,
- font_families->getPictograph(String()));
+ pictograph_font_family_.Set(font_families->getPictograph(String()));
family_settings.UpdatePictograph(
- AtomicString(font_families->getPictograph(String())));
+ AtomicString(pictograph_font_family_.Get()));
}
settings->NotifyGenericFontFamilyChange();
}
@@ -1267,14 +1231,12 @@ Response InspectorPageAgent::setFontSizes(
auto* settings = frame->GetSettings();
if (settings) {
if (font_sizes->hasStandard()) {
- state_->setInteger(PageAgentState::kStandardFontSize,
- font_sizes->getStandard(0));
- settings->SetDefaultFontSize(font_sizes->getStandard(0));
+ standard_font_size_.Set(font_sizes->getStandard(0));
+ settings->SetDefaultFontSize(standard_font_size_.Get());
}
if (font_sizes->hasFixed()) {
- state_->setInteger(PageAgentState::kFixedFontSize,
- font_sizes->getFixed(0));
- settings->SetDefaultFixedFontSize(font_sizes->getFixed(0));
+ fixed_font_size_.Set(font_sizes->getFixed(0));
+ settings->SetDefaultFixedFontSize(fixed_font_size_.Get());
}
}
@@ -1299,7 +1261,7 @@ void InspectorPageAgent::ConsumeCompilationCache(
void InspectorPageAgent::ProduceCompilationCache(const ScriptSourceCode& source,
v8::Local<v8::Script> script) {
- if (!state_->booleanProperty(PageAgentState::kProduceCompilationCache, false))
+ if (!produce_compilation_cache_.Get())
return;
KURL url = source.Url();
if (source.Streamer())
@@ -1308,6 +1270,10 @@ void InspectorPageAgent::ProduceCompilationCache(const ScriptSourceCode& source,
return;
if (url.IsEmpty())
return;
+ String url_string = url.GetString();
+ auto it = compilation_cache_.find(url_string);
+ if (it != compilation_cache_.end())
+ return;
static const int kMinimalCodeLength = 1024;
if (source.Source().length() < kMinimalCodeLength)
return;
@@ -1316,12 +1282,12 @@ void InspectorPageAgent::ProduceCompilationCache(const ScriptSourceCode& source,
if (cached_data) {
String base64data = Base64Encode(
reinterpret_cast<const char*>(cached_data->data), cached_data->length);
- GetFrontend()->compilationCacheProduced(url, base64data);
+ GetFrontend()->compilationCacheProduced(url_string, base64data);
}
}
Response InspectorPageAgent::setProduceCompilationCache(bool enabled) {
- state_->setBoolean(PageAgentState::kProduceCompilationCache, enabled);
+ produce_compilation_cache_.Set(enabled);
return Response::OK();
}
@@ -1339,6 +1305,20 @@ Response InspectorPageAgent::clearCompilationCache() {
return Response::OK();
}
+protocol::Response InspectorPageAgent::generateTestReport(const String& message,
+ Maybe<String> group) {
+ Document* document = inspected_frames_->Root()->GetDocument();
+
+ // Construct the test report.
+ TestReportBody* body = new TestReportBody(message);
+ Report* report = new Report("test", document->Url().GetString(), body);
+
+ // Send the test report to any ReportingObservers.
+ ReportingContext::From(document)->QueueReport(report);
+
+ return Response::OK();
+}
+
void InspectorPageAgent::Trace(blink::Visitor* visitor) {
visitor->Trace(inspected_frames_);
visitor->Trace(inspector_resource_content_loader_);
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 c5a48a9f1e1..997a23bc320 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
@@ -56,6 +56,7 @@ class InspectedFrames;
class InspectorResourceContentLoader;
class LocalFrame;
class ScheduledNavigation;
+class ScriptSourceCode;
class SharedBuffer;
using blink::protocol::Maybe;
@@ -157,6 +158,8 @@ class CORE_EXPORT InspectorPageAgent final
std::unique_ptr<protocol::Page::FontFamilies>) override;
protocol::Response setFontSizes(
std::unique_ptr<protocol::Page::FontSizes>) override;
+ protocol::Response generateTestReport(const String& message,
+ Maybe<String> group) override;
protocol::Response setProduceCompilationCache(bool enabled) override;
protocol::Response addCompilationCache(const String& url,
@@ -236,13 +239,26 @@ class CORE_EXPORT InspectorPageAgent final
HashMap<String, Vector<char>> compilation_cache_;
v8_inspector::V8InspectorSession* v8_session_;
Client* client_;
- long last_script_identifier_;
String pending_script_to_evaluate_on_load_once_;
String script_to_evaluate_on_load_once_;
- bool enabled_;
bool reloading_;
Member<InspectorResourceContentLoader> inspector_resource_content_loader_;
int resource_content_loader_client_id_;
+ InspectorAgentState::Boolean enabled_;
+ InspectorAgentState::Boolean screencast_enabled_;
+ InspectorAgentState::Boolean lifecycle_events_enabled_;
+ InspectorAgentState::Boolean bypass_csp_enabled_;
+ InspectorAgentState::StringMap scripts_to_evaluate_on_load_;
+ InspectorAgentState::String standard_font_family_;
+ InspectorAgentState::String fixed_font_family_;
+ InspectorAgentState::String serif_font_family_;
+ InspectorAgentState::String sans_serif_font_family_;
+ InspectorAgentState::String cursive_font_family_;
+ InspectorAgentState::String fantasy_font_family_;
+ InspectorAgentState::String pictograph_font_family_;
+ InspectorAgentState::Integer standard_font_size_;
+ InspectorAgentState::Integer fixed_font_size_;
+ InspectorAgentState::Boolean produce_compilation_cache_;
DISALLOW_COPY_AND_ASSIGN(InspectorPageAgent);
};
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 85c4644d147..e97a0b78164 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
@@ -22,9 +22,6 @@ namespace blink {
using protocol::Response;
namespace {
-
-static const char kPerformanceAgentEnabled[] = "PerformanceAgentEnabled";
-
constexpr bool isPlural(const char* str, int len) {
return len > 1 && str[len - 2] == 's';
}
@@ -40,34 +37,37 @@ static constexpr const char* kInstanceCounterNames[] = {
InspectorPerformanceAgent::InspectorPerformanceAgent(
InspectedFrames* inspected_frames)
- : inspected_frames_(inspected_frames) {}
+ : inspected_frames_(inspected_frames),
+ enabled_(&agent_state_, /*default_value=*/false) {}
InspectorPerformanceAgent::~InspectorPerformanceAgent() = default;
void InspectorPerformanceAgent::Restore() {
- if (state_->booleanProperty(kPerformanceAgentEnabled, false))
- enable();
+ if (enabled_.Get())
+ InnerEnable();
}
-protocol::Response InspectorPerformanceAgent::enable() {
- if (enabled_)
- return Response::OK();
- enabled_ = true;
- state_->setBoolean(kPerformanceAgentEnabled, true);
+void InspectorPerformanceAgent::InnerEnable() {
instrumenting_agents_->addInspectorPerformanceAgent(this);
Platform::Current()->CurrentThread()->AddTaskTimeObserver(this);
layout_start_ticks_ = TimeTicks();
recalc_style_start_ticks_ = TimeTicks();
task_start_ticks_ = TimeTicks();
script_start_ticks_ = TimeTicks();
+}
+
+protocol::Response InspectorPerformanceAgent::enable() {
+ if (enabled_.Get())
+ return Response::OK();
+ enabled_.Set(true);
+ InnerEnable();
return Response::OK();
}
protocol::Response InspectorPerformanceAgent::disable() {
- if (!enabled_)
+ if (!enabled_.Get())
return Response::OK();
- enabled_ = false;
- state_->setBoolean(kPerformanceAgentEnabled, false);
+ enabled_.Clear();
instrumenting_agents_->removeInspectorPerformanceAgent(this);
Platform::Current()->CurrentThread()->RemoveTaskTimeObserver(this);
return Response::OK();
@@ -87,7 +87,7 @@ void AppendMetric(protocol::Array<protocol::Performance::Metric>* container,
Response InspectorPerformanceAgent::getMetrics(
std::unique_ptr<protocol::Array<protocol::Performance::Metric>>*
out_result) {
- if (!enabled_) {
+ if (!enabled_.Get()) {
*out_result = protocol::Array<protocol::Performance::Metric>::create();
return Response::OK();
}
@@ -148,7 +148,7 @@ Response InspectorPerformanceAgent::getMetrics(
}
void InspectorPerformanceAgent::ConsoleTimeStamp(const String& title) {
- if (!enabled_)
+ if (!enabled_.Get())
return;
std::unique_ptr<protocol::Array<protocol::Performance::Metric>> metrics;
getMetrics(&metrics);
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 3e0d3f87acb..c62b7bba0a9 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
@@ -65,9 +65,9 @@ class CORE_EXPORT InspectorPerformanceAgent final
explicit InspectorPerformanceAgent(InspectedFrames*);
void ScriptStarts();
void ScriptEnds();
+ void InnerEnable();
Member<InspectedFrames> inspected_frames_;
- bool enabled_ = false;
TimeDelta layout_duration_;
TimeTicks layout_start_ticks_;
TimeDelta recalc_style_duration_;
@@ -80,7 +80,7 @@ class CORE_EXPORT InspectorPerformanceAgent final
unsigned long long recalc_style_count_ = 0;
int script_call_depth_ = 0;
int layout_depth_ = 0;
-
+ InspectorAgentState::Boolean enabled_;
DISALLOW_COPY_AND_ASSIGN(InspectorPerformanceAgent);
};
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 6c1a9dd42a0..dd2d0b200ab 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
@@ -72,11 +72,6 @@
"include": ["getDOMCounters", "startSampling", "stopSampling", "getSamplingProfile", "getAllTimeSamplingProfile"]
},
{
- "domain": "Tracing",
- "include": ["start", "end"],
- "async": ["start", "end"]
- },
- {
"domain": "Page",
"exclude": ["getNavigationHistory", "navigateToHistoryEntry", "captureScreenshot", "screencastFrameAck", "handleJavaScriptDialog", "setColorPickerEnabled",
"getAppManifest", "requestAppBanner", "setControlNavigations", "processNavigation", "printToPDF", "bringToFront", "setDownloadBehavior", "navigate", "crash", "close", "setWebLifecycleState"],
@@ -104,6 +99,9 @@
"domain": "Target",
"include": ["setAutoAttach", "sendMessageToTarget"],
"include_events": ["attachedToTarget", "detachedFromTarget", "receivedMessageFromTarget"]
+ },
+ {
+ "domain": "Testing"
}
]
},
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_session.cc b/chromium/third_party/blink/renderer/core/inspector/inspector_session.cc
index f8d7b79d0db..be55a4b43b3 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_session.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_session.cc
@@ -8,6 +8,7 @@
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/use_counter.h"
#include "third_party/blink/renderer/core/inspector/inspector_base_agent.h"
+#include "third_party/blink/renderer/core/inspector/inspector_session_state.h"
#include "third_party/blink/renderer/core/inspector/protocol/Protocol.h"
#include "third_party/blink/renderer/core/inspector/v8_inspector_string.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
@@ -18,32 +19,30 @@ namespace {
const char kV8StateKey[] = "v8";
}
-InspectorSession::InspectorSession(Client* client,
- CoreProbeSink* instrumenting_agents,
- int session_id,
- v8_inspector::V8Inspector* inspector,
- int context_group_id,
- const String& reattach_state)
+InspectorSession::InspectorSession(
+ Client* client,
+ CoreProbeSink* instrumenting_agents,
+ int session_id,
+ v8_inspector::V8Inspector* inspector,
+ int context_group_id,
+ mojom::blink::DevToolsSessionStatePtr reattach_session_state)
: client_(client),
v8_session_(nullptr),
session_id_(session_id),
disposed_(false),
instrumenting_agents_(instrumenting_agents),
- inspector_backend_dispatcher_(new protocol::UberDispatcher(this)) {
- String v8_state;
- if (!reattach_state.IsNull()) {
- std::unique_ptr<protocol::Value> state =
- protocol::StringUtil::parseJSON(reattach_state);
- if (state)
- state_ = protocol::DictionaryValue::cast(std::move(state));
- if (!state_)
- state_ = protocol::DictionaryValue::create();
- state_->getString(kV8StateKey, &v8_state);
- } else {
- state_ = protocol::DictionaryValue::create();
- }
- v8_session_ = inspector->connect(context_group_id, this,
- ToV8InspectorStringView(v8_state));
+ inspector_backend_dispatcher_(new protocol::UberDispatcher(this)),
+ session_state_(std::move(reattach_session_state)),
+ v8_session_state_(kV8StateKey),
+ v8_session_state_json_(&v8_session_state_, /*default_value=*/String()) {
+ v8_session_state_.InitFrom(&session_state_);
+
+ // inspector->connect may result in calls to |this| against the
+ // V8Inspector::Channel interface for receiving responses / notifications,
+ // while v8_session_ is still nullptr.
+ v8_session_ =
+ inspector->connect(context_group_id, /*channel*/ this,
+ ToV8InspectorStringView(v8_session_state_json_.Get()));
}
InspectorSession::~InspectorSession() {
@@ -53,7 +52,7 @@ InspectorSession::~InspectorSession() {
void InspectorSession::Append(InspectorAgent* agent) {
agents_.push_back(agent);
agent->Init(instrumenting_agents_.Get(), inspector_backend_dispatcher_.get(),
- state_.get());
+ &session_state_);
}
void InspectorSession::Restore() {
@@ -72,7 +71,8 @@ void InspectorSession::Dispose() {
v8_session_.reset();
}
-void InspectorSession::DispatchProtocolMessage(const String& method,
+void InspectorSession::DispatchProtocolMessage(int call_id,
+ const String& method,
const String& message) {
DCHECK(!disposed_);
if (v8_inspector::V8InspectorSession::canDispatchMethod(
@@ -80,22 +80,26 @@ void InspectorSession::DispatchProtocolMessage(const String& method,
v8_session_->dispatchProtocolMessage(ToV8InspectorStringView(message));
} else {
inspector_backend_dispatcher_->dispatch(
- protocol::StringUtil::parseJSON(message));
+ call_id, method, protocol::StringUtil::parseJSON(message), message);
}
}
void InspectorSession::DispatchProtocolMessage(const String& message) {
DCHECK(!disposed_);
+ int call_id;
String method;
- std::unique_ptr<protocol::DictionaryValue> parsedMessage;
- if (!inspector_backend_dispatcher_->getCommandName(message, &method,
- &parsedMessage))
+ std::unique_ptr<protocol::Value> parsed_message =
+ protocol::StringUtil::parseJSON(message);
+ if (!inspector_backend_dispatcher_->parseCommand(parsed_message.get(),
+ &call_id, &method)) {
return;
+ }
if (v8_inspector::V8InspectorSession::canDispatchMethod(
ToV8InspectorStringView(method))) {
v8_session_->dispatchProtocolMessage(ToV8InspectorStringView(message));
} else {
- inspector_backend_dispatcher_->dispatch(std::move(parsedMessage));
+ inspector_backend_dispatcher_->dispatch(call_id, method,
+ std::move(parsed_message), message);
}
}
@@ -110,6 +114,13 @@ void InspectorSession::sendProtocolResponse(
SendProtocolResponse(call_id, message->serialize());
}
+void InspectorSession::fallThrough(int call_id,
+ const String& method,
+ const String& message) {
+ // There's no other layer to handle the command.
+ NOTREACHED();
+}
+
void InspectorSession::sendResponse(
int call_id,
std::unique_ptr<v8_inspector::StringBuffer> message) {
@@ -124,19 +135,10 @@ void InspectorSession::SendProtocolResponse(int call_id,
if (disposed_)
return;
flushProtocolNotifications();
- client_->SendProtocolResponse(session_id_, call_id, message,
- GetStateToSend());
-}
-
-String InspectorSession::GetStateToSend() {
if (v8_session_)
- state_->setString(kV8StateKey, ToCoreString(v8_session_->stateJSON()));
- String state_to_send = state_->serialize();
- if (state_to_send == last_sent_state_)
- state_to_send = String();
- else
- last_sent_state_ = state_to_send;
- return state_to_send;
+ v8_session_state_json_.Set(ToCoreString(v8_session_->stateJSON()));
+ client_->SendProtocolResponse(session_id_, call_id, message,
+ session_state_.TakeUpdates());
}
class InspectorSession::Notification {
@@ -200,12 +202,12 @@ void InspectorSession::flushProtocolNotifications() {
agents_[i]->FlushPendingProtocolNotifications();
if (!notification_queue_.size())
return;
- String state_to_send = GetStateToSend();
+ if (v8_session_)
+ v8_session_state_json_.Set(ToCoreString(v8_session_->stateJSON()));
for (size_t i = 0; i < notification_queue_.size(); ++i) {
- client_->SendProtocolNotification(
- session_id_, notification_queue_[i]->Serialize(), state_to_send);
- // Only send state once in this series of serialized updates.
- state_to_send = String();
+ client_->SendProtocolNotification(session_id_,
+ notification_queue_[i]->Serialize(),
+ session_state_.TakeUpdates());
}
notification_queue_.clear();
}
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_session.h b/chromium/third_party/blink/renderer/core/inspector/inspector_session.h
index 9822485cd05..1f913f21536 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_session.h
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_session.h
@@ -6,7 +6,9 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_INSPECTOR_INSPECTOR_SESSION_H_
#include "base/macros.h"
+#include "third_party/blink/public/web/devtools_agent.mojom-blink.h"
#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/inspector/inspector_session_state.h"
#include "third_party/blink/renderer/core/inspector/protocol/Forward.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
@@ -27,22 +29,25 @@ class CORE_EXPORT InspectorSession
public:
class Client {
public:
- virtual void SendProtocolResponse(int session_id,
- int call_id,
- const String& response,
- const String& state) = 0;
- virtual void SendProtocolNotification(int session_id,
- const String& message,
- const String& state) = 0;
+ virtual void SendProtocolResponse(
+ int session_id,
+ int call_id,
+ const String& response,
+ mojom::blink::DevToolsSessionStatePtr updates) = 0;
+ virtual void SendProtocolNotification(
+ int session_id,
+ const String& message,
+ mojom::blink::DevToolsSessionStatePtr updates) = 0;
virtual ~Client() = default;
};
- InspectorSession(Client*,
- CoreProbeSink*,
- int session_id,
- v8_inspector::V8Inspector*,
- int context_group_id,
- const String& reattach_state);
+ InspectorSession(
+ Client*,
+ CoreProbeSink*,
+ int session_id,
+ v8_inspector::V8Inspector*,
+ int context_group_id,
+ mojom::blink::DevToolsSessionStatePtr reattach_session_state);
~InspectorSession() override;
// TODO(dgozman): remove session id once WokrerInspectorController
// does not use it anymore.
@@ -53,7 +58,9 @@ class CORE_EXPORT InspectorSession
void Restore();
void Dispose();
void DidCommitLoadForLocalFrame(LocalFrame*);
- void DispatchProtocolMessage(const String& method, const String& message);
+ void DispatchProtocolMessage(int call_id,
+ const String& method,
+ const String& message);
void DispatchProtocolMessage(const String& message);
void flushProtocolNotifications() override;
@@ -75,8 +82,9 @@ class CORE_EXPORT InspectorSession
std::unique_ptr<v8_inspector::StringBuffer> message) override;
void SendProtocolResponse(int call_id, const String& message);
-
- String GetStateToSend();
+ void fallThrough(int call_id,
+ const String& method,
+ const String& message) override;
Client* client_;
std::unique_ptr<v8_inspector::V8InspectorSession> v8_session_;
@@ -84,11 +92,12 @@ class CORE_EXPORT InspectorSession
bool disposed_;
Member<CoreProbeSink> instrumenting_agents_;
std::unique_ptr<protocol::UberDispatcher> inspector_backend_dispatcher_;
- std::unique_ptr<protocol::DictionaryValue> state_;
+ InspectorSessionState session_state_;
HeapVector<Member<InspectorAgent>> agents_;
class Notification;
Vector<std::unique_ptr<Notification>> notification_queue_;
- String last_sent_state_;
+ InspectorAgentState v8_session_state_;
+ InspectorAgentState::String v8_session_state_json_;
DISALLOW_COPY_AND_ASSIGN(InspectorSession);
};
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_session_state.cc b/chromium/third_party/blink/renderer/core/inspector/inspector_session_state.cc
new file mode 100644
index 00000000000..6f7888933ff
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_session_state.cc
@@ -0,0 +1,114 @@
+// 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/inspector/inspector_session_state.h"
+
+#include "third_party/blink/renderer/core/inspector/protocol/Protocol.h"
+
+namespace blink {
+
+//
+// InspectorSessionState
+//
+InspectorSessionState::InspectorSessionState(
+ mojom::blink::DevToolsSessionStatePtr reattach)
+ : reattach_state_(std::move(reattach)),
+ updates_(mojom::blink::DevToolsSessionState::New()) {}
+
+const mojom::blink::DevToolsSessionState* InspectorSessionState::ReattachState()
+ const {
+ return reattach_state_.get();
+}
+
+void InspectorSessionState::EnqueueUpdate(const WTF::String& key,
+ const WTF::String& value) {
+ updates_->entries.Set(key, value);
+}
+
+mojom::blink::DevToolsSessionStatePtr InspectorSessionState::TakeUpdates() {
+ auto updates = std::move(updates_);
+ updates_ = mojom::blink::DevToolsSessionState::New();
+ return updates;
+}
+
+//
+// Encoding / Decoding routines.
+//
+/*static*/
+void InspectorAgentState::EncodeToJSON(bool v, WTF::String* out) {
+ std::unique_ptr<protocol::FundamentalValue> value =
+ blink::protocol::FundamentalValue::create(v);
+ *out = value->serialize();
+}
+
+/*static*/
+bool InspectorAgentState::DecodeFromJSON(const WTF::String& in, bool* v) {
+ std::unique_ptr<protocol::Value> parsed = protocol::StringUtil::parseJSON(in);
+ return parsed->asBoolean(v);
+}
+
+/*static*/
+void InspectorAgentState::EncodeToJSON(int32_t v, WTF::String* out) {
+ std::unique_ptr<protocol::FundamentalValue> value =
+ blink::protocol::FundamentalValue::create(v);
+ *out = value->serialize();
+}
+
+/*static*/
+bool InspectorAgentState::DecodeFromJSON(const WTF::String& in, int32_t* v) {
+ std::unique_ptr<protocol::Value> parsed = protocol::StringUtil::parseJSON(in);
+ return parsed->asInteger(v);
+}
+
+/*static*/
+void InspectorAgentState::EncodeToJSON(double v, WTF::String* out) {
+ std::unique_ptr<protocol::FundamentalValue> value =
+ blink::protocol::FundamentalValue::create(v);
+ *out = value->serialize();
+}
+
+/*static*/
+bool InspectorAgentState::DecodeFromJSON(const WTF::String& in, double* v) {
+ std::unique_ptr<protocol::Value> parsed = protocol::StringUtil::parseJSON(in);
+ return parsed->asDouble(v);
+}
+
+/*static*/
+void InspectorAgentState::EncodeToJSON(const WTF::String& v, WTF::String* out) {
+ std::unique_ptr<protocol::StringValue> value =
+ protocol::StringValue::create(v);
+ *out = value->serialize();
+}
+
+/*static*/
+bool InspectorAgentState::DecodeFromJSON(const WTF::String& in,
+ WTF::String* v) {
+ std::unique_ptr<protocol::Value> parsed = protocol::StringUtil::parseJSON(in);
+ return parsed->asString(v);
+}
+
+//
+// InspectorAgentState
+//
+InspectorAgentState::InspectorAgentState(const WTF::String& domain_name)
+ : domain_name_(domain_name) {}
+
+WTF::String InspectorAgentState::RegisterField(Field* field) {
+ WTF::String prefix_key =
+ domain_name_ + "." + WTF::String::Number(fields_.size()) + "/";
+ fields_.push_back(field);
+ return prefix_key;
+}
+
+void InspectorAgentState::InitFrom(InspectorSessionState* session_state) {
+ for (Field* f : fields_)
+ f->InitFrom(session_state);
+}
+
+void InspectorAgentState::ClearAllFields() {
+ for (Field* f : fields_)
+ f->Clear();
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_session_state.h b/chromium/third_party/blink/renderer/core/inspector/inspector_session_state.h
new file mode 100644
index 00000000000..3c5c8c65349
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_session_state.h
@@ -0,0 +1,277 @@
+// 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_INSPECTOR_INSPECTOR_SESSION_STATE_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_INSPECTOR_INSPECTOR_SESSION_STATE_H_
+
+#include <memory>
+#include <type_traits>
+#include <vector>
+#include "third_party/blink/public/web/devtools_agent.mojom-blink.h"
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+class InspectorAgentState;
+// An abstraction for the inspector session state in the renderer.
+// Makes the |reattach_state| sent from the browser available to the
+// InspectorAgentState::Field instances, and queues the updates
+// that are made to these fields.
+class CORE_EXPORT InspectorSessionState {
+ public:
+ InspectorSessionState(mojom::blink::DevToolsSessionStatePtr reattach_state);
+
+ // Make |reattach_state| available to InspectorAgentState::Field instances.
+ const mojom::blink::DevToolsSessionState* ReattachState() const;
+
+ // Registers a field update in the stored session state and in the updates
+ // that are sent back to the browser.
+ // A null string for |value| indicates a deletion.
+ // TODO(johannes): Lower cost of repeated updates.
+ void EnqueueUpdate(const WTF::String& key, const WTF::String& value);
+
+ // Yields and consumes the field updates that have thus far accumulated.
+ // These updates are sent back to DevToolsSession on the browser side.
+ mojom::blink::DevToolsSessionStatePtr TakeUpdates();
+
+ private:
+ const mojom::blink::DevToolsSessionStatePtr reattach_state_;
+ mojom::blink::DevToolsSessionStatePtr updates_;
+};
+
+// InspectorAgentState connects the fields of inspector agents
+// with the renderer-side InspectorSessionState.
+class CORE_EXPORT InspectorAgentState {
+ private:
+ // Trivial Helpers for converting between the value types used for the agent
+ // state fields and JSON strings used for the wire protocol. The point of
+ // these is to be able to call overloaded methods from the template
+ // implementations below; they just delegate to protocol::Value parsing
+ // and serialization.
+ static void EncodeToJSON(bool v, WTF::String* out);
+ static bool DecodeFromJSON(const WTF::String& in, bool* v);
+ static void EncodeToJSON(int32_t v, WTF::String* out);
+ static bool DecodeFromJSON(const WTF::String& in, int32_t* v);
+ static void EncodeToJSON(double v, WTF::String* out);
+ static bool DecodeFromJSON(const WTF::String& in, double* v);
+ static void EncodeToJSON(const WTF::String& v, WTF::String* out);
+ static bool DecodeFromJSON(const WTF::String& in, WTF::String* v);
+
+ public:
+ // A field is connected to the |agent_state|, which initializes the field
+ // via ::InitFrom / ::Decode when the agent is (re)attached.
+ class Field {
+ public:
+ Field(InspectorAgentState* agent_state)
+ : prefix_key_(agent_state->RegisterField(this)) {}
+ virtual ~Field() = default;
+
+ void InitFrom(InspectorSessionState* session_state) {
+ session_state_ = session_state;
+ Decode();
+ }
+
+ // Clears the field to its default or to the empty map if it's a map field.
+ virtual void Clear() = 0;
+
+ protected:
+ virtual void Decode() = 0;
+
+ // The field instance is allowed to use/allocate any entry in
+ // the session state starting with this prefix. SimpleField instances
+ // just use prefix_key_ directly, MapField instances append a suffix.
+ const WTF::String prefix_key_;
+ InspectorSessionState* session_state_;
+ };
+
+ // A simple field with a default value, providing Get, Set, and Clear
+ // operations. E.g. an instantiation with WTF::String yields:
+ // - const WTF::String& Get();
+ // - Set(const WTF::String&);
+ // - void Clear();
+ template <class ValueType>
+ class SimpleField : public Field {
+ // Means in practice: const WTF::String& for WTF::String, otherwise same
+ // as ValueType.
+ using ConstRefType =
+ typename std::conditional<std::is_fundamental<ValueType>::value,
+ ValueType,
+ const ValueType&>::type;
+
+ public:
+ // Constructs a new field registered with |agent_state| which
+ // will use |default_value| when not set.
+ SimpleField(InspectorAgentState* agent_state, ConstRefType default_value)
+ : Field(agent_state),
+ default_value_(default_value),
+ value_(default_value) {}
+
+ // Returns the value of the field, or the default if not set.
+ ConstRefType Get() const { return value_; }
+
+ // Sets the field to the value, or clears if |value| is the default.
+ void Set(ConstRefType value) {
+ if (value == value_)
+ return;
+ if (value == default_value_) {
+ Clear();
+ return;
+ }
+ value_ = value;
+ WTF::String encoded_value;
+ EncodeToJSON(value, &encoded_value);
+ session_state_->EnqueueUpdate(prefix_key_, encoded_value);
+ }
+
+ // Clears the field to its default.
+ void Clear() override {
+ if (default_value_ == value_)
+ return;
+ value_ = default_value_;
+ session_state_->EnqueueUpdate(prefix_key_, WTF::String());
+ }
+
+ private:
+ // Decodes the key from the encoded session state. This is used
+ // during initialization when an agent is reattached.
+ void Decode() override {
+ const mojom::blink::DevToolsSessionState* reattach_state =
+ session_state_->ReattachState();
+ if (!reattach_state)
+ return;
+ auto it = reattach_state->entries.find(prefix_key_);
+ if (it != reattach_state->entries.end())
+ DecodeFromJSON(it->value, &value_);
+ }
+
+ const ValueType default_value_;
+ ValueType value_;
+ };
+
+ // A map field provides a map from WTF::String to its value type,
+ // and Keys, Get, Set, Clear operations.
+ template <class ValueType>
+ class MapField : public Field {
+ // Means in practice: const WTF::String& for WTF::String, otherwise same
+ // as ValueType.
+ using ConstRefType =
+ typename std::conditional<std::is_fundamental<ValueType>::value,
+ ValueType,
+ const ValueType&>::type;
+
+ public:
+ // Constructs a new field registered with |agent_state| which
+ // will use |default_value| for keys that are not set.
+ MapField(InspectorAgentState* agent_state, ConstRefType default_value)
+ : Field(agent_state), default_value_(default_value) {}
+
+ // Enumerates the keys for which values are stored in this field.
+ // The order of the keys is undefined.
+ std::vector<WTF::String> Keys() const {
+ // TODO(johannes): It'd be nice to avoid copying; unfortunately
+ // it didn't seem easy to return map_.Keys().
+ std::vector<WTF::String> keys;
+ for (const WTF::String& s : map_.Keys())
+ keys.push_back(s);
+ return keys;
+ }
+
+ // O(1) shortcut for Keys().empty().
+ bool IsEmpty() const { return map_.IsEmpty(); }
+
+ // Returns the value for a given |key|, or the default value if
+ // the key wasn't set.
+ ConstRefType Get(const WTF::String& key) const {
+ auto it = map_.find(key);
+ return it == map_.end() ? default_value_ : it->value;
+ }
+
+ // Sets the |value| for |key| as provided, except if |value| is the
+ // default value in which case |key| is cleared.
+ void Set(const WTF::String& key, ConstRefType value) {
+ if (value == default_value_) {
+ Clear(key);
+ return;
+ }
+ auto it = map_.find(key);
+ if (it != map_.end() && it->value == value)
+ return;
+ map_.Set(key, value);
+ WTF::String encoded_value;
+ EncodeToJSON(value, &encoded_value);
+ session_state_->EnqueueUpdate(prefix_key_ + key, encoded_value);
+ }
+
+ // Clears the entry for |key|.
+ void Clear(const WTF::String& key) {
+ auto it = map_.find(key);
+ if (it == map_.end())
+ return;
+ map_.erase(it);
+ session_state_->EnqueueUpdate(prefix_key_ + key, WTF::String());
+ }
+
+ // Clears the entire field.
+ void Clear() override {
+ // TODO(johannes): Handle this in a single update.
+ for (const WTF::String& key : map_.Keys())
+ session_state_->EnqueueUpdate(prefix_key_ + key, WTF::String());
+ map_.clear();
+ }
+
+ private:
+ // Decodes the key from the encoded session state. This is used
+ // during initialization when an agent is reattached.
+ void Decode() override {
+ const mojom::blink::DevToolsSessionState* reattach_state =
+ session_state_->ReattachState();
+ if (!reattach_state)
+ return;
+ // TODO(johannes): Avoid scanning all keys, let session_state_ provide
+ // the keys that match a prefix.
+ for (const auto& entry : reattach_state->entries) {
+ if (!entry.key.StartsWith(prefix_key_))
+ continue;
+ WTF::String suffix_key = entry.key.Substring(prefix_key_.length());
+ ValueType v;
+ if (DecodeFromJSON(entry.value, &v))
+ map_.Set(suffix_key, v);
+ }
+ }
+
+ const ValueType default_value_;
+ WTF::HashMap<WTF::String, ValueType> map_;
+ };
+
+ using Boolean = SimpleField<bool>;
+ using Integer = SimpleField<int32_t>;
+ using Double = SimpleField<double>;
+ using String = SimpleField<WTF::String>;
+ using BooleanMap = MapField<bool>;
+ using IntegerMap = MapField<int32_t>;
+ using DoubleMap = MapField<double>;
+ using StringMap = MapField<WTF::String>;
+
+ InspectorAgentState(const WTF::String& domain_name);
+
+ // Registers |field| and returns the prefix key for it.
+ // The prefix key is domain_name + "." + index in fields_ + "/",
+ // e.g. "network.0/".
+ WTF::String RegisterField(Field* field);
+
+ // Init must be called *after* all fields are registered with the
+ // InspectorAgentState. Usually, the fact that fields are registered in
+ // the constructors / initializers of agents takes care of it.
+ void InitFrom(InspectorSessionState* session_state);
+
+ // Clears all fields registered with this InspectorAgentState instance.
+ void ClearAllFields();
+
+ private:
+ const WTF::String domain_name_;
+ std::vector<Field*> fields_;
+};
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_INSPECTOR_SESSION_STATE_H_
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_session_state_test.cc b/chromium/third_party/blink/renderer/core/inspector/inspector_session_state_test.cc
new file mode 100644
index 00000000000..73dc4ea72b2
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_session_state_test.cc
@@ -0,0 +1,259 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/inspector/inspector_session_state.h"
+
+#include "build/build_config.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace blink {
+using mojom::blink::DevToolsSessionState;
+using mojom::blink::DevToolsSessionStatePtr;
+using std::unique_ptr;
+using testing::UnorderedElementsAre;
+
+// This session object is normally on the browser side; see
+// content/browser/devtools/devtools_session.{h,cc}, but here's a minimal
+// reimplementation to allow testing without sending data through a Mojo pipe.
+class DevToolsSession {
+ public:
+ void ApplyUpdates(DevToolsSessionStatePtr updates) {
+ if (!updates)
+ return;
+ if (!session_state_cookie_)
+ session_state_cookie_ = DevToolsSessionState::New();
+ for (auto& entry : updates->entries) {
+ if (!entry.value.IsNull())
+ session_state_cookie_->entries.Set(entry.key, std::move(entry.value));
+ else
+ session_state_cookie_->entries.erase(entry.key);
+ }
+ }
+
+ DevToolsSessionStatePtr CloneCookie() const {
+ return session_state_cookie_.Clone();
+ }
+
+ DevToolsSessionStatePtr session_state_cookie_;
+};
+
+// The InspectorAgentState abstraction is used to group the
+// fields of an agent together, and to connect it to the
+// InspectorSessionState instance, from which fields
+// may receive their initial state (if we reattach)
+// and to which fields send their updates.
+// In this test, we use a simple struct rather than
+// an agent class (like InspectorPageAgent) with a few fields.
+struct AgentWithSimpleFields {
+ AgentWithSimpleFields()
+ : agent_state_("simple_agent"),
+ enabled_(&agent_state_, /*default_value=*/false),
+ field1_(&agent_state_, /*default_value=*/0.0),
+ multiplier_(&agent_state_, /*default_value=*/1.0),
+ counter_(&agent_state_, /*default_value=*/1),
+ message_(&agent_state_, /*default_value=*/WTF::String()) {}
+
+ InspectorAgentState agent_state_;
+ InspectorAgentState::Boolean enabled_;
+ InspectorAgentState::Double field1_;
+ InspectorAgentState::Double multiplier_;
+ InspectorAgentState::Integer counter_;
+ InspectorAgentState::String message_;
+};
+
+TEST(InspectorSessionStateTest, SimpleFields) {
+ // The browser session (DevToolsSession) remains live while renderer
+ // sessions (InspectorSession - here we just exercise
+ // InspectorSessionState) may come and go.
+ DevToolsSession dev_tools_session;
+
+ { // Renderer session.
+ InspectorSessionState session_state(dev_tools_session.CloneCookie());
+ AgentWithSimpleFields simple_agent;
+ simple_agent.agent_state_.InitFrom(&session_state);
+
+ simple_agent.enabled_.Set(true);
+ simple_agent.field1_.Set(11.0);
+ simple_agent.multiplier_.Set(42.0);
+ simple_agent.counter_.Set(311);
+
+ EXPECT_EQ(true, simple_agent.enabled_.Get());
+ EXPECT_EQ(11.0, simple_agent.field1_.Get());
+ EXPECT_EQ(42.0, simple_agent.multiplier_.Get());
+ EXPECT_EQ(311, simple_agent.counter_.Get());
+
+ // Now send the updates back to the browser session.
+ dev_tools_session.ApplyUpdates(session_state.TakeUpdates());
+ }
+
+ { // Restore renderer session, verify, then make additional updates.
+ InspectorSessionState session_state(dev_tools_session.CloneCookie());
+ AgentWithSimpleFields simple_agent;
+ simple_agent.agent_state_.InitFrom(&session_state);
+
+ EXPECT_EQ(true, simple_agent.enabled_.Get());
+ EXPECT_EQ(11.0, simple_agent.field1_.Get());
+ EXPECT_EQ(42.0, simple_agent.multiplier_.Get());
+ EXPECT_EQ(311, simple_agent.counter_.Get());
+
+ simple_agent.enabled_.Set(false);
+ simple_agent.multiplier_.Clear();
+ simple_agent.field1_.Set(-1.0);
+ simple_agent.counter_.Set(312);
+
+ // Now send the updates back to the browser session.
+ dev_tools_session.ApplyUpdates(session_state.TakeUpdates());
+ }
+
+ { // Restore renderer session, verify, then clear everything.
+ InspectorSessionState session_state(dev_tools_session.CloneCookie());
+ AgentWithSimpleFields simple_agent;
+ simple_agent.agent_state_.InitFrom(&session_state);
+
+ EXPECT_EQ(false, simple_agent.enabled_.Get());
+ EXPECT_EQ(-1.0, simple_agent.field1_.Get());
+ EXPECT_EQ(1.0, simple_agent.multiplier_.Get());
+ EXPECT_EQ(312, simple_agent.counter_.Get());
+
+ simple_agent.enabled_.Clear();
+ simple_agent.multiplier_.Set(1.0); // default value => clears.
+ simple_agent.field1_.Clear();
+ simple_agent.counter_.Clear();
+ }
+}
+
+// This agent test struct exercises maps from strings to strings
+// and strings to doubles.
+struct AgentWithMapFields {
+ AgentWithMapFields()
+ : agent_state_("map_agents"),
+ strings_(&agent_state_, /*default_value=*/WTF::String()),
+ doubles_(&agent_state_, /*default_value=*/0.0) {}
+
+ InspectorAgentState agent_state_;
+ InspectorAgentState::StringMap strings_;
+ InspectorAgentState::DoubleMap doubles_;
+};
+
+TEST(InspectorSessionStateTest, MapFields) {
+ DevToolsSession dev_tools_session; // Browser session.
+
+ { // Renderer session.
+ InspectorSessionState session_state(dev_tools_session.CloneCookie());
+ AgentWithMapFields maps_agent;
+ maps_agent.agent_state_.InitFrom(&session_state);
+
+ EXPECT_TRUE(maps_agent.strings_.IsEmpty());
+
+ maps_agent.strings_.Set("key1", "Hello, world.");
+ maps_agent.strings_.Set("key2", WTF::String::FromUTF8("I ❤ Unicode."));
+
+ EXPECT_FALSE(maps_agent.strings_.IsEmpty());
+
+ EXPECT_THAT(maps_agent.strings_.Keys(),
+ UnorderedElementsAre("key1", "key2"));
+ EXPECT_EQ("Hello, world.", maps_agent.strings_.Get("key1"));
+ EXPECT_EQ(WTF::String::FromUTF8("I ❤ Unicode."),
+ maps_agent.strings_.Get("key2"));
+ EXPECT_TRUE(maps_agent.strings_.Get("key3").IsNull());
+
+ // Now send the updates back to the browser session.
+ dev_tools_session.ApplyUpdates(session_state.TakeUpdates());
+ }
+
+ { // Restore renderer session, verify, then make additional updates.
+ InspectorSessionState session_state(dev_tools_session.CloneCookie());
+ AgentWithMapFields maps_agent;
+ maps_agent.agent_state_.InitFrom(&session_state);
+
+ EXPECT_THAT(maps_agent.strings_.Keys(),
+ UnorderedElementsAre("key1", "key2"));
+ EXPECT_EQ("Hello, world.", maps_agent.strings_.Get("key1"));
+ EXPECT_EQ(WTF::String::FromUTF8("I ❤ Unicode."),
+ maps_agent.strings_.Get("key2"));
+ EXPECT_TRUE(maps_agent.strings_.Get("key3").IsNull());
+
+ maps_agent.strings_.Clear("key1");
+ maps_agent.strings_.Set("key2", "updated message for key 2");
+ maps_agent.strings_.Set("key3", "new message for key 3");
+
+ // Now send the updates back to the browser session.
+ dev_tools_session.ApplyUpdates(session_state.TakeUpdates());
+ }
+
+ { // Restore renderer session and verify.
+ InspectorSessionState session_state(dev_tools_session.CloneCookie());
+ AgentWithMapFields maps_agent;
+ maps_agent.agent_state_.InitFrom(&session_state);
+
+ EXPECT_THAT(maps_agent.strings_.Keys(),
+ UnorderedElementsAre("key2", "key3"));
+ EXPECT_TRUE(maps_agent.strings_.Get("key1").IsNull());
+ EXPECT_EQ("updated message for key 2", maps_agent.strings_.Get("key2"));
+ EXPECT_EQ("new message for key 3", maps_agent.strings_.Get("key3"));
+
+ maps_agent.strings_.Clear();
+
+ dev_tools_session.ApplyUpdates(session_state.TakeUpdates());
+ }
+
+ // The cookie should be empty since everything is cleared.
+ DevToolsSessionStatePtr cookie = dev_tools_session.CloneCookie();
+ EXPECT_TRUE(cookie->entries.IsEmpty());
+}
+
+TEST(InspectorSessionStateTest, MultipleAgents) {
+ DevToolsSession dev_tools_session; // Browser session.
+
+ { // Renderer session.
+ InspectorSessionState session_state(dev_tools_session.CloneCookie());
+ AgentWithSimpleFields simple_agent;
+ simple_agent.agent_state_.InitFrom(&session_state);
+ AgentWithMapFields maps_agent;
+ maps_agent.agent_state_.InitFrom(&session_state);
+
+ simple_agent.message_.Set("Hello, world.");
+ maps_agent.doubles_.Set("Pi", 3.1415);
+ dev_tools_session.ApplyUpdates(session_state.TakeUpdates());
+ }
+
+ // Show that the keys for the field values are prefixed with the domain name
+ // passed to AgentState so that the stored values won't collide.
+ DevToolsSessionStatePtr cookie = dev_tools_session.CloneCookie();
+ std::vector<WTF::String> keys;
+ for (const WTF::String& k : cookie->entries.Keys())
+ keys.push_back(k);
+
+ EXPECT_THAT(keys, UnorderedElementsAre("map_agents.1/Pi", "simple_agent.4/"));
+
+ { // Renderer session, maps_agent clears its fields, and show that it will
+ // clear the agent's fields, but no other fields.
+ InspectorSessionState session_state(dev_tools_session.CloneCookie());
+ AgentWithSimpleFields simple_agent;
+ simple_agent.agent_state_.InitFrom(&session_state);
+ AgentWithMapFields maps_agent;
+ maps_agent.agent_state_.InitFrom(&session_state);
+ maps_agent.strings_.Set("foo", "bar");
+ maps_agent.agent_state_.ClearAllFields();
+
+ EXPECT_TRUE(maps_agent.doubles_.IsEmpty());
+ EXPECT_TRUE(maps_agent.strings_.IsEmpty());
+ EXPECT_FALSE(simple_agent.message_.Get().IsEmpty()); // other agent.
+
+ dev_tools_session.ApplyUpdates(session_state.TakeUpdates());
+ }
+
+ { // Renderer session, this time the simple agent clears its fields and
+ // as a result the session has no more entries (both agents are cleared).
+ InspectorSessionState session_state(dev_tools_session.CloneCookie());
+ AgentWithSimpleFields simple_agent;
+ simple_agent.agent_state_.InitFrom(&session_state);
+ simple_agent.agent_state_.ClearAllFields();
+
+ dev_tools_session.ApplyUpdates(session_state.TakeUpdates());
+ }
+ EXPECT_TRUE(dev_tools_session.CloneCookie()->entries.IsEmpty());
+}
+} // namespace blink
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 b76d7d34ccd..aeb1d5074a0 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
@@ -85,18 +85,15 @@ bool InspectorTaskRunner::IsRunningTask() {
InspectorTaskRunner::Task InspectorTaskRunner::TakeNextTask(
InspectorTaskRunner::WaitMode wait_mode) {
MutexLocker lock(mutex_);
- bool timed_out = false;
- static double infinite_time = std::numeric_limits<double>::max();
- double absolute_time = wait_mode == kWaitForTask ? infinite_time : 0.0;
- while (!disposed_ && !timed_out && queue_.IsEmpty())
- timed_out = !condition_.TimedWait(mutex_, absolute_time);
- DCHECK(!timed_out || absolute_time != infinite_time);
+ if (wait_mode == kWaitForTask) {
+ while (!disposed_ && queue_.IsEmpty())
+ condition_.Wait(mutex_);
+ }
- if (disposed_ || timed_out)
+ if (disposed_ || queue_.IsEmpty())
return Task();
- SECURITY_DCHECK(!queue_.IsEmpty());
return queue_.TakeFirst();
}
@@ -116,10 +113,11 @@ void InspectorTaskRunner::PerformSingleTask(Task task) {
}
void InspectorTaskRunner::PerformSingleTaskDontWait() {
- DCHECK(isolate_task_runner_->BelongsToCurrentThread());
Task task = TakeNextTask(kDontWaitForTask);
- if (task)
+ if (task) {
+ DCHECK(isolate_task_runner_->BelongsToCurrentThread());
PerformSingleTask(std::move(task));
+ }
}
void InspectorTaskRunner::V8InterruptCallback(v8::Isolate*, void* data) {
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_testing_agent.cc b/chromium/third_party/blink/renderer/core/inspector/inspector_testing_agent.cc
new file mode 100644
index 00000000000..a8ffbd609c2
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_testing_agent.cc
@@ -0,0 +1,27 @@
+// 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/inspector/inspector_testing_agent.h"
+
+#include "third_party/blink/renderer/core/inspector/inspected_frames.h"
+
+namespace blink {
+
+InspectorTestingAgent::InspectorTestingAgent(InspectedFrames* inspected_frames)
+ : inspected_frames_(inspected_frames) {}
+
+InspectorTestingAgent::~InspectorTestingAgent() = default;
+
+void InspectorTestingAgent::Trace(blink::Visitor* visitor) {
+ visitor->Trace(inspected_frames_);
+ InspectorBaseAgent::Trace(visitor);
+}
+
+protocol::Response InspectorTestingAgent::generateTestReport(
+ const String& message,
+ protocol::Maybe<String> group) {
+ return protocol::Response::OK();
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_testing_agent.h b/chromium/third_party/blink/renderer/core/inspector/inspector_testing_agent.h
new file mode 100644
index 00000000000..daa1f562b94
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_testing_agent.h
@@ -0,0 +1,34 @@
+// 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_INSPECTOR_INSPECTOR_TESTING_AGENT_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_INSPECTOR_INSPECTOR_TESTING_AGENT_H_
+
+#include "base/macros.h"
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/inspector/inspector_base_agent.h"
+#include "third_party/blink/renderer/core/inspector/protocol/Testing.h"
+
+namespace blink {
+
+class InspectedFrames;
+
+class CORE_EXPORT InspectorTestingAgent final
+ : public InspectorBaseAgent<protocol::Testing::Metainfo> {
+ public:
+ InspectorTestingAgent(InspectedFrames*);
+ ~InspectorTestingAgent() override;
+ void Trace(blink::Visitor*) override;
+
+ protocol::Response generateTestReport(const String& message,
+ protocol::Maybe<String> group) override;
+
+ private:
+ Member<InspectedFrames> inspected_frames_;
+ DISALLOW_COPY_AND_ASSIGN(InspectorTestingAgent);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_INSPECTOR_INSPECTOR_TESTING_AGENT_H_
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 e22bd9a857f..e547e3fe6b9 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
@@ -358,6 +358,43 @@ const char* CompileOptionsString(v8::ScriptCompiler::CompileOptions options) {
return "";
}
+const char* NotStreamedReasonString(ScriptStreamer::NotStreamingReason reason) {
+ switch (reason) {
+ case ScriptStreamer::kNotHTTP:
+ return "not http/https protocol";
+ case ScriptStreamer::kReload:
+ return "reload event";
+ case ScriptStreamer::kContextNotValid:
+ return "script context not valid";
+ case ScriptStreamer::kEncodingNotSupported:
+ return "encoding not supported";
+ case ScriptStreamer::kThreadBusy:
+ return "script streamer thread busy";
+ case ScriptStreamer::kV8CannotStream:
+ return "V8 cannot stream script";
+ case ScriptStreamer::kScriptTooSmall:
+ return "script too small";
+ case ScriptStreamer::kNoResourceBuffer:
+ return "resource no longer alive";
+ case ScriptStreamer::kHasCodeCache:
+ return "script has code-cache available";
+ case ScriptStreamer::kStreamerNotReadyOnGetSource:
+ return "streamer not ready";
+ case ScriptStreamer::kInlineScript:
+ return "inline script";
+ case ScriptStreamer::kDidntTryToStartStreaming:
+ return "start streaming not called";
+ case ScriptStreamer::kErrorOccurred:
+ return "an error occurred";
+ case ScriptStreamer::kAlreadyLoaded:
+ case ScriptStreamer::kCount:
+ case ScriptStreamer::kInvalid:
+ NOTREACHED();
+ }
+ NOTREACHED();
+ return "";
+}
+
} // namespace
namespace InspectorScheduleStyleInvalidationTrackingEvent {
@@ -1105,7 +1142,8 @@ std::unique_ptr<TracedValue> InspectorCompileScriptEvent::Data(
const String& url,
const TextPosition& text_position,
const V8CacheResult& cache_result,
- bool streamed) {
+ bool streamed,
+ ScriptStreamer::NotStreamingReason not_streaming_reason) {
std::unique_ptr<TracedValue> value = FillLocation(url, text_position);
if (cache_result.produce_result) {
@@ -1125,6 +1163,10 @@ std::unique_ptr<TracedValue> InspectorCompileScriptEvent::Data(
value->SetBoolean("cacheRejected", cache_result.consume_result->rejected);
}
value->SetBoolean("streamed", streamed);
+ if (!streamed) {
+ value->SetString("notStreamedReason",
+ NotStreamedReasonString(not_streaming_reason));
+ }
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 cd8112d1558..6812d634dda 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
@@ -9,6 +9,7 @@
#include "base/macros.h"
#include "base/optional.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_streamer.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/css/css_selector.h"
#include "third_party/blink/renderer/core/loader/frame_loader_types.h"
@@ -425,7 +426,8 @@ struct V8CacheResult {
std::unique_ptr<TracedValue> Data(const String& url,
const WTF::TextPosition&,
const V8CacheResult&,
- bool streamed);
+ bool streamed,
+ ScriptStreamer::NotStreamingReason);
} // namespace InspectorCompileScriptEvent
namespace InspectorFunctionCallEvent {
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_tracing_agent.cc b/chromium/third_party/blink/renderer/core/inspector/inspector_tracing_agent.cc
deleted file mode 100644
index befcba062bf..00000000000
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_tracing_agent.cc
+++ /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.
-
-#include "third_party/blink/renderer/core/inspector/inspector_tracing_agent.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/inspector/inspected_frames.h"
-#include "third_party/blink/renderer/core/inspector/inspector_trace_events.h"
-#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
-
-namespace blink {
-
-using protocol::Maybe;
-using protocol::Response;
-
-namespace TracingAgentState {
-const char kSessionId[] = "sessionId";
-}
-
-namespace {
-const char kDevtoolsMetadataEventCategory[] =
- TRACE_DISABLED_BY_DEFAULT("devtools.timeline");
-}
-
-InspectorTracingAgent::InspectorTracingAgent(InspectedFrames* inspected_frames)
- : inspected_frames_(inspected_frames) {}
-
-InspectorTracingAgent::~InspectorTracingAgent() {}
-
-void InspectorTracingAgent::Trace(blink::Visitor* visitor) {
- visitor->Trace(inspected_frames_);
- InspectorBaseAgent::Trace(visitor);
-}
-
-void InspectorTracingAgent::Restore() {
- state_->getString(TracingAgentState::kSessionId, &session_id_);
- if (IsStarted())
- EmitMetadataEvents();
-}
-
-void InspectorTracingAgent::start(Maybe<String> categories,
- Maybe<String> options,
- Maybe<double> buffer_usage_reporting_interval,
- Maybe<String> transfer_mode,
- Maybe<String> transfer_compression,
- Maybe<protocol::Tracing::TraceConfig> config,
- std::unique_ptr<StartCallback> callback) {
- DCHECK(!IsStarted());
- if (config.isJust()) {
- callback->sendFailure(Response::Error(
- "Using trace config on renderer targets is not supported yet."));
- return;
- }
-
- session_id_ = IdentifiersFactory::CreateIdentifier();
- state_->setString(TracingAgentState::kSessionId, session_id_);
-
- // Tracing is already started by DevTools TracingHandler::Start for the
- // renderer target in the browser process. It will eventually start tracing
- // in the renderer process via IPC. But we still need a redundant enable here
- // for EmitMetadataEvents, at which point we are not sure if tracing
- // is already started in the renderer process.
- TraceEvent::EnableTracing(categories.fromMaybe(String()));
-
- EmitMetadataEvents();
- callback->sendSuccess();
-}
-
-void InspectorTracingAgent::end(std::unique_ptr<EndCallback> callback) {
- TraceEvent::DisableTracing();
- InnerDisable();
- callback->sendSuccess();
-}
-
-bool InspectorTracingAgent::IsStarted() const {
- return !session_id_.IsEmpty();
-}
-
-void InspectorTracingAgent::EmitMetadataEvents() {
- TRACE_EVENT_INSTANT1(kDevtoolsMetadataEventCategory, "TracingStartedInPage",
- TRACE_EVENT_SCOPE_THREAD, "data",
- InspectorTracingStartedInFrame::Data(
- session_id_, inspected_frames_->Root()));
-}
-
-Response InspectorTracingAgent::disable() {
- InnerDisable();
- return Response::OK();
-}
-
-void InspectorTracingAgent::InnerDisable() {
- state_->remove(TracingAgentState::kSessionId);
- session_id_ = String();
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_tracing_agent.h b/chromium/third_party/blink/renderer/core/inspector/inspector_tracing_agent.h
deleted file mode 100644
index db27f8766ab..00000000000
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_tracing_agent.h
+++ /dev/null
@@ -1,55 +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_INSPECTOR_INSPECTOR_TRACING_AGENT_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_INSPECTOR_INSPECTOR_TRACING_AGENT_H_
-
-#include "base/macros.h"
-#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/inspector/inspector_base_agent.h"
-#include "third_party/blink/renderer/core/inspector/protocol/Tracing.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-
-namespace blink {
-
-class InspectedFrames;
-
-class CORE_EXPORT InspectorTracingAgent final
- : public InspectorBaseAgent<protocol::Tracing::Metainfo> {
- public:
- explicit InspectorTracingAgent(InspectedFrames*);
- ~InspectorTracingAgent() override;
-
- void Trace(blink::Visitor*) override;
-
- // Base agent methods.
- void Restore() override;
- protocol::Response disable() override;
-
- // Protocol method implementations.
- void start(protocol::Maybe<String> categories,
- protocol::Maybe<String> options,
- protocol::Maybe<double> buffer_usage_reporting_interval,
- protocol::Maybe<String> transfer_mode,
- protocol::Maybe<String> transfer_compression,
- protocol::Maybe<protocol::Tracing::TraceConfig>,
- std::unique_ptr<StartCallback>) override;
- void end(std::unique_ptr<EndCallback>) override;
-
- private:
- void EmitMetadataEvents();
- void InnerDisable();
- bool IsStarted() const;
-
- String session_id_;
- Member<InspectedFrames> inspected_frames_;
-
- DISALLOW_COPY_AND_ASSIGN(InspectorTracingAgent);
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_INSPECTOR_INSPECTOR_TRACING_AGENT_H_
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_worker_agent.cc b/chromium/third_party/blink/renderer/core/inspector/inspector_worker_agent.cc
index e393fd7f79d..1bc6721bd0c 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_worker_agent.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_worker_agent.cc
@@ -44,52 +44,46 @@ namespace blink {
using protocol::Maybe;
using protocol::Response;
-namespace WorkerAgentState {
-static const char kAutoAttach[] = "autoAttach";
-static const char kWaitForDebuggerOnStart[] = "waitForDebuggerOnStart";
-static const char kAttachedSessionIds[] = "attachedSessionIds";
-}; // namespace WorkerAgentState
-
int InspectorWorkerAgent::s_last_connection_ = 0;
InspectorWorkerAgent::InspectorWorkerAgent(
InspectedFrames* inspected_frames,
WorkerGlobalScope* worker_global_scope)
: inspected_frames_(inspected_frames),
- worker_global_scope_(worker_global_scope) {}
+ worker_global_scope_(worker_global_scope),
+ auto_attach_(&agent_state_, /*default_value=*/ false),
+ wait_for_debugger_on_start_(&agent_state_, /*default_value=*/ false),
+ attached_session_ids_(&agent_state_, /*default_value*/ false) {}
InspectorWorkerAgent::~InspectorWorkerAgent() = default;
void InspectorWorkerAgent::Restore() {
- if (!AutoAttachEnabled())
+ if (!auto_attach_.Get())
return;
instrumenting_agents_->addInspectorWorkerAgent(this);
- protocol::DictionaryValue* attached = AttachedSessionIds();
- for (size_t i = 0; i < attached->size(); ++i)
- GetFrontend()->detachedFromTarget(attached->at(i).first);
- state_->remove(WorkerAgentState::kAttachedSessionIds);
+ for (const WTF::String& session_id : attached_session_ids_.Keys())
+ GetFrontend()->detachedFromTarget(session_id);
+ attached_session_ids_.Clear();
ConnectToAllProxies();
}
Response InspectorWorkerAgent::disable() {
- if (AutoAttachEnabled()) {
+ if (auto_attach_.Get()) {
DisconnectFromAllProxies(false);
instrumenting_agents_->removeInspectorWorkerAgent(this);
}
- state_->setBoolean(WorkerAgentState::kAutoAttach, false);
- state_->setBoolean(WorkerAgentState::kWaitForDebuggerOnStart, false);
- state_->remove(WorkerAgentState::kAttachedSessionIds);
+ agent_state_.ClearAllFields();
return Response::OK();
}
Response InspectorWorkerAgent::setAutoAttach(bool auto_attach,
- bool wait_for_debugger_on_start) {
- state_->setBoolean(WorkerAgentState::kWaitForDebuggerOnStart,
- wait_for_debugger_on_start);
+ bool wait_for_debugger_on_start,
+ Maybe<bool> flatten) {
+ wait_for_debugger_on_start_.Set(wait_for_debugger_on_start);
- if (auto_attach == AutoAttachEnabled())
+ if (auto_attach == auto_attach_.Get())
return Response::OK();
- state_->setBoolean(WorkerAgentState::kAutoAttach, auto_attach);
+ auto_attach_.Set(auto_attach);
if (auto_attach) {
instrumenting_agents_->addInspectorWorkerAgent(this);
ConnectToAllProxies();
@@ -100,10 +94,6 @@ Response InspectorWorkerAgent::setAutoAttach(bool auto_attach,
return Response::OK();
}
-bool InspectorWorkerAgent::AutoAttachEnabled() {
- return state_->booleanProperty(WorkerAgentState::kAutoAttach, false);
-}
-
Response InspectorWorkerAgent::sendMessageToTarget(const String& message,
Maybe<String> session_id,
Maybe<String> target_id) {
@@ -134,26 +124,25 @@ Response InspectorWorkerAgent::sendMessageToTarget(const String& message,
}
void InspectorWorkerAgent::ShouldWaitForDebuggerOnWorkerStart(bool* result) {
- if (AutoAttachEnabled() &&
- state_->booleanProperty(WorkerAgentState::kWaitForDebuggerOnStart, false))
+ if (auto_attach_.Get() && wait_for_debugger_on_start_.Get())
*result = true;
}
void InspectorWorkerAgent::DidStartWorker(WorkerInspectorProxy* proxy,
bool waiting_for_debugger) {
- DCHECK(GetFrontend() && AutoAttachEnabled());
+ DCHECK(GetFrontend() && auto_attach_.Get());
ConnectToProxy(proxy, waiting_for_debugger);
}
void InspectorWorkerAgent::WorkerTerminated(WorkerInspectorProxy* proxy) {
- DCHECK(GetFrontend() && AutoAttachEnabled());
+ DCHECK(GetFrontend() && auto_attach_.Get());
Vector<String> session_ids;
for (auto& it : session_id_to_connection_) {
if (connected_proxies_.at(it.value) == proxy)
session_ids.push_back(it.key);
}
for (const String& session_id : session_ids) {
- AttachedSessionIds()->remove(session_id);
+ attached_session_ids_.Clear(session_id);
GetFrontend()->detachedFromTarget(session_id, proxy->InspectorId());
int connection = session_id_to_connection_.at(session_id);
proxy->DisconnectFromInspector(connection, this);
@@ -186,7 +175,7 @@ void InspectorWorkerAgent::DisconnectFromAllProxies(bool report_to_frontend) {
for (auto& it : session_id_to_connection_) {
WorkerInspectorProxy* proxy = connected_proxies_.at(it.value);
if (report_to_frontend) {
- AttachedSessionIds()->remove(it.key);
+ attached_session_ids_.Clear(it.key);
GetFrontend()->detachedFromTarget(it.key, proxy->InspectorId());
}
proxy->DisconnectFromInspector(it.value, this);
@@ -197,7 +186,7 @@ void InspectorWorkerAgent::DisconnectFromAllProxies(bool report_to_frontend) {
}
void InspectorWorkerAgent::DidCommitLoadForLocalFrame(LocalFrame* frame) {
- if (!AutoAttachEnabled() || frame != inspected_frames_->Root())
+ if (!auto_attach_.Get() || frame != inspected_frames_->Root())
return;
// During navigation workers from old page may die after a while.
@@ -206,19 +195,6 @@ void InspectorWorkerAgent::DidCommitLoadForLocalFrame(LocalFrame* frame) {
DisconnectFromAllProxies(true);
}
-protocol::DictionaryValue* InspectorWorkerAgent::AttachedSessionIds() {
- protocol::DictionaryValue* ids =
- state_->getObject(WorkerAgentState::kAttachedSessionIds);
- if (!ids) {
- std::unique_ptr<protocol::DictionaryValue> new_ids =
- protocol::DictionaryValue::create();
- ids = new_ids.get();
- state_->setObject(WorkerAgentState::kAttachedSessionIds,
- std::move(new_ids));
- }
- return ids;
-}
-
void InspectorWorkerAgent::ConnectToProxy(WorkerInspectorProxy* proxy,
bool waiting_for_debugger) {
int connection = ++s_last_connection_;
@@ -230,7 +206,7 @@ void InspectorWorkerAgent::ConnectToProxy(WorkerInspectorProxy* proxy,
proxy->ConnectToInspector(connection, this);
DCHECK(GetFrontend());
- AttachedSessionIds()->setBoolean(session_id, true);
+ attached_session_ids_.Set(session_id, true);
GetFrontend()->attachedToTarget(session_id,
protocol::Target::TargetInfo::create()
.setTargetId(proxy->InspectorId())
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_worker_agent.h b/chromium/third_party/blink/renderer/core/inspector/inspector_worker_agent.h
index 7970afdc281..6f2a733f327 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_worker_agent.h
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_worker_agent.h
@@ -63,18 +63,17 @@ class CORE_EXPORT InspectorWorkerAgent final
// Called from Dispatcher
protocol::Response setAutoAttach(bool auto_attach,
- bool wait_for_debugger_on_start) override;
+ bool wait_for_debugger_on_start,
+ protocol::Maybe<bool> flatten) override;
protocol::Response sendMessageToTarget(
const String& message,
protocol::Maybe<String> session_id,
protocol::Maybe<String> target_id) override;
private:
- bool AutoAttachEnabled();
void ConnectToAllProxies();
void DisconnectFromAllProxies(bool report_to_frontend);
void ConnectToProxy(WorkerInspectorProxy*, bool waiting_for_debugger);
- protocol::DictionaryValue* AttachedSessionIds();
// WorkerInspectorProxy::PageInspector implementation.
void DispatchMessageFromWorker(WorkerInspectorProxy*,
@@ -88,6 +87,9 @@ class CORE_EXPORT InspectorWorkerAgent final
HeapHashMap<int, Member<WorkerInspectorProxy>> connected_proxies_;
HashMap<int, String> connection_to_session_id_;
HashMap<String, int> session_id_to_connection_;
+ InspectorAgentState::Boolean auto_attach_;
+ InspectorAgentState::Boolean wait_for_debugger_on_start_;
+ InspectorAgentState::BooleanMap attached_session_ids_;
static int s_last_connection_;
DISALLOW_COPY_AND_ASSIGN(InspectorWorkerAgent);
};
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 826eca01553..4c21915aa2f 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
@@ -140,6 +140,12 @@ void MainThreadDebugger::ContextCreated(ScriptState* script_state,
StringBuilder aux_data_builder;
aux_data_builder.Append("{\"isDefault\":");
aux_data_builder.Append(world.IsMainWorld() ? "true" : "false");
+ if (world.IsMainWorld())
+ aux_data_builder.Append(",\"type\":\"default\"");
+ else if (world.IsIsolatedWorld())
+ aux_data_builder.Append(",\"type\":\"isolated\"");
+ else if (world.IsWorkerWorld())
+ aux_data_builder.Append(",\"type\":\"worker\"");
aux_data_builder.Append(",\"frameId\":\"");
aux_data_builder.Append(IdentifiersFactory::FrameId(frame));
aux_data_builder.Append("\"}");
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 20bab9dc449..a8256bca696 100644
--- a/chromium/third_party/blink/renderer/core/inspector/thread_debugger.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/thread_debugger.cc
@@ -12,15 +12,16 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_dom_exception.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_dom_token_list.h"
#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_helper.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_event_listener_info.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_event_listener_or_event_handler.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"
#include "third_party/blink/renderer/bindings/core/v8/v8_node_list.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_script_runner.h"
#include "third_party/blink/renderer/core/dom/user_gesture_indicator.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/inspector/inspector_dom_debugger_agent.h"
#include "third_party/blink/renderer/core/inspector/inspector_trace_events.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 1918108e9fc..6197024ef86 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
@@ -74,7 +74,7 @@ void WorkerInspectorController::ConnectFrontend(int session_id) {
InspectorSession* session = new InspectorSession(
this, probe_sink_.Get(), session_id, debugger_->GetV8Inspector(),
- debugger_->ContextGroupId(thread_), String());
+ debugger_->ContextGroupId(thread_), nullptr);
session->Append(new InspectorLogAgent(thread_->GetConsoleMessageStorage(),
nullptr, session->V8Session()));
if (thread_->GlobalScope()->IsWorkerGlobalScope()) {
@@ -125,10 +125,11 @@ void WorkerInspectorController::FlushProtocolNotifications() {
it.value->flushProtocolNotifications();
}
-void WorkerInspectorController::SendProtocolResponse(int session_id,
- int call_id,
- const String& response,
- const String& state) {
+void WorkerInspectorController::SendProtocolResponse(
+ int session_id,
+ int call_id,
+ const String& response,
+ mojom::blink::DevToolsSessionStatePtr updates) {
// Make tests more predictable by flushing all sessions before sending
// protocol response in any of them.
if (LayoutTestSupport::IsRunningLayoutTest())
@@ -138,9 +139,10 @@ void WorkerInspectorController::SendProtocolResponse(int session_id,
response);
}
-void WorkerInspectorController::SendProtocolNotification(int session_id,
- const String& message,
- const String& state) {
+void WorkerInspectorController::SendProtocolNotification(
+ int session_id,
+ const String& message,
+ mojom::blink::DevToolsSessionStatePtr updates) {
thread_->GetWorkerReportingProxy().PostMessageToPageInspector(session_id,
message);
}
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 4b6509d7bfc..51f4e176187 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
@@ -67,13 +67,15 @@ class WorkerInspectorController final
WorkerInspectorController(WorkerThread*, WorkerThreadDebugger*);
// InspectorSession::Client implementation.
- void SendProtocolResponse(int session_id,
- int call_id,
- const String& response,
- const String& state) override;
- void SendProtocolNotification(int session_id,
- const String& message,
- const String& state) override;
+ void SendProtocolResponse(
+ int session_id,
+ int call_id,
+ const String& response,
+ mojom::blink::DevToolsSessionStatePtr updates) override;
+ void SendProtocolNotification(
+ int session_id,
+ const String& message,
+ mojom::blink::DevToolsSessionStatePtr updates) override;
// WebThread::TaskObserver implementation.
void WillProcessTask() override;
diff --git a/chromium/third_party/blink/renderer/core/inspector/worker_thread_debugger.cc b/chromium/third_party/blink/renderer/core/inspector/worker_thread_debugger.cc
index 57f03bbf3b3..7a03ef6ff2c 100644
--- a/chromium/third_party/blink/renderer/core/inspector/worker_thread_debugger.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/worker_thread_debugger.cc
@@ -101,12 +101,13 @@ void WorkerThreadDebugger::WorkerThreadDestroyed(WorkerThread* worker_thread) {
}
void WorkerThreadDebugger::ContextCreated(WorkerThread* worker_thread,
+ const KURL& url_for_debugger,
v8::Local<v8::Context> context) {
int worker_context_group_id = ContextGroupId(worker_thread);
DCHECK(worker_threads_.Contains(worker_context_group_id));
v8_inspector::V8ContextInfo context_info(context, worker_context_group_id,
v8_inspector::StringView());
- String origin = worker_thread->GlobalScope()->Url().GetString();
+ String origin = url_for_debugger;
context_info.origin = ToV8InspectorStringView(origin);
GetV8Inspector()->contextCreated(context_info);
}
diff --git a/chromium/third_party/blink/renderer/core/inspector/worker_thread_debugger.h b/chromium/third_party/blink/renderer/core/inspector/worker_thread_debugger.h
index ca4ffef8754..eeb8c8f9267 100644
--- a/chromium/third_party/blink/renderer/core/inspector/worker_thread_debugger.h
+++ b/chromium/third_party/blink/renderer/core/inspector/worker_thread_debugger.h
@@ -52,7 +52,9 @@ class CORE_EXPORT WorkerThreadDebugger final : public ThreadDebugger {
int ContextGroupId(WorkerThread*);
void WorkerThreadCreated(WorkerThread*);
void WorkerThreadDestroyed(WorkerThread*);
- void ContextCreated(WorkerThread*, v8::Local<v8::Context>);
+ void ContextCreated(WorkerThread*,
+ const KURL& url_for_debugger,
+ v8::Local<v8::Context>);
void ContextWillBeDestroyed(WorkerThread*, v8::Local<v8::Context>);
void ExceptionThrown(WorkerThread*, ErrorEvent*);
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 8b355a9f0b1..310a6cf7d0b 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
@@ -16,16 +16,20 @@ namespace blink {
namespace {
bool IsOccluded(const Element& element, const IntersectionGeometry& geometry) {
- HitTestResult hits(
- element.GetLayoutObject()->HitTestForOcclusion(geometry.TargetRect()));
- const HitTestResult::NodeSet& hit_nodes = hits.ListBasedTestResult();
- for (const auto& node : hit_nodes) {
- if (!node->contains(&element) &&
- node->GetLayoutObject()->HasNonZeroEffectiveOpacity()) {
- return true;
- }
+ DCHECK(RuntimeEnabledFeatures::IntersectionObserverV2Enabled());
+ if (element.GetDocument()
+ .GetFrame()
+ ->LocalFrameRoot()
+ .MayBeOccludedOrObscuredByRemoteAncestor()) {
+ return true;
}
- return false;
+ // TODO(layout-dev): This should hit-test the intersection rect, not the
+ // target rect; it's not helpful to know that the portion of the target that
+ // is clipped is also occluded. To do that, the intersection rect must be
+ // mapped down to the local space of the target element.
+ HitTestResult result(
+ element.GetLayoutObject()->HitTestForOcclusion(geometry.TargetRect()));
+ return result.InnerNode() && result.InnerNode() != &element;
}
} // namespace
@@ -87,7 +91,8 @@ void IntersectionObservation::ComputeIntersectionObservations(
Observer()->FirstThresholdGreaterThan(new_visible_ratio);
if (RuntimeEnabledFeatures::IntersectionObserverV2Enabled() &&
Observer()->trackVisibility()) {
- is_visible = !Target()->GetLayoutObject()->HasDistortingVisualEffects() &&
+ is_visible = new_threshold_index > 0 &&
+ !Target()->GetLayoutObject()->HasDistortingVisualEffects() &&
!IsOccluded(*Target(), geometry);
}
} else {
@@ -106,7 +111,7 @@ void IntersectionObservation::ComputeIntersectionObservations(
IntersectionObserverEntry* new_entry = new IntersectionObserverEntry(
timestamp, new_visible_ratio, FloatRect(geometry.TargetRect()),
root_bounds_pointer, FloatRect(geometry.IntersectionRect()),
- geometry.DoesIntersect(), is_visible, Target());
+ new_threshold_index > 0, is_visible, Target());
Observer()->EnqueueIntersectionObserverEntry(*new_entry);
SetLastThresholdIndex(new_threshold_index);
SetWasVisible(is_visible);
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 2fba8dca939..7b251e67fec 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
@@ -115,10 +115,11 @@ void ParseThresholds(const DoubleOrDoubleSequence& threshold_parameter,
Vector<float>& thresholds,
ExceptionState& exception_state) {
if (threshold_parameter.IsDouble()) {
- thresholds.push_back(static_cast<float>(threshold_parameter.GetAsDouble()));
+ thresholds.push_back(
+ MakeClampedNum<float>(threshold_parameter.GetAsDouble()));
} else {
for (auto threshold_value : threshold_parameter.GetAsDoubleSequence())
- thresholds.push_back(static_cast<float>(threshold_value));
+ thresholds.push_back(MakeClampedNum<float>(threshold_value));
}
for (auto threshold_value : thresholds) {
@@ -135,6 +136,15 @@ void ParseThresholds(const DoubleOrDoubleSequence& threshold_parameter,
} // anonymous namespace
+// Minimum time, in milliseconds, between observations. See:
+// http://szager-chromium.github.io/IntersectionObserver/#dom-intersectionobserver-trackvisibility
+const DOMHighResTimeStamp IntersectionObserver::s_v2_throttle_delay_ = 100;
+static bool v2_throttle_delay_enabled = true;
+
+void IntersectionObserver::SetV2ThrottleDelayEnabledForTesting(bool enabled) {
+ v2_throttle_delay_enabled = enabled;
+}
+
IntersectionObserver* IntersectionObserver::Create(
const IntersectionObserverInit& observer_init,
IntersectionObserverDelegate& delegate,
@@ -196,6 +206,7 @@ IntersectionObserver::IntersectionObserver(
right_margin_(kFixed),
bottom_margin_(kFixed),
left_margin_(kFixed),
+ last_run_time_(-s_v2_throttle_delay_),
root_is_implicit_(root ? 0 : 1),
track_visibility_(track_visibility ? 1 : 0) {
switch (root_margin.size()) {
@@ -311,8 +322,13 @@ void IntersectionObserver::ComputeIntersectionObservations() {
return;
DOMHighResTimeStamp timestamp =
DOMWindowPerformance::performance(*delegate_dom_window)->now();
+ if (track_visibility_ && v2_throttle_delay_enabled &&
+ timestamp - last_run_time_ < s_v2_throttle_delay_) {
+ return;
+ }
+ last_run_time_ = timestamp;
for (auto& observation : observations_)
- observation->ComputeIntersectionObservations(timestamp);
+ observation->ComputeIntersectionObservations(last_run_time_);
}
void IntersectionObserver::disconnect(ExceptionState& exception_state) {
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 e9b5f859229..543e7e4d05b 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
@@ -97,6 +97,10 @@ class CORE_EXPORT IntersectionObserver final
void Trace(blink::Visitor*) override;
+ // Enable/disable throttling of visibility checking, so we don't have to add
+ // 100ms sleep() calls to tests.
+ static void SetV2ThrottleDelayEnabledForTesting(bool);
+
private:
explicit IntersectionObserver(IntersectionObserverDelegate&,
Element*,
@@ -109,6 +113,10 @@ class CORE_EXPORT IntersectionObserver final
// deleted; true otherwise.
bool RootIsValid() const;
+ // If trackVisibility is true, don't compute observations more frequently
+ // than this many milliseconds.
+ static const DOMHighResTimeStamp s_v2_throttle_delay_;
+
const TraceWrapperMember<IntersectionObserverDelegate> delegate_;
WeakMember<Element> root_;
HeapLinkedHashSet<WeakMember<IntersectionObservation>> observations_;
@@ -118,6 +126,7 @@ class CORE_EXPORT IntersectionObserver final
Length right_margin_;
Length bottom_margin_;
Length left_margin_;
+ DOMHighResTimeStamp last_run_time_;
unsigned root_is_implicit_ : 1;
unsigned track_visibility_ : 1;
};
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 c867a3d46d0..3152c635649 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
@@ -66,7 +66,13 @@ class IntersectionObserverV2Test : public IntersectionObserverTest,
public ScopedIntersectionObserverV2ForTest {
public:
IntersectionObserverV2Test()
- : IntersectionObserverTest(), ScopedIntersectionObserverV2ForTest(true) {}
+ : IntersectionObserverTest(), ScopedIntersectionObserverV2ForTest(true) {
+ IntersectionObserver::SetV2ThrottleDelayEnabledForTesting(false);
+ }
+
+ ~IntersectionObserverV2Test() override {
+ IntersectionObserver::SetV2ThrottleDelayEnabledForTesting(true);
+ }
};
TEST_F(IntersectionObserverTest, ObserveSchedulesFrame) {
@@ -354,6 +360,16 @@ TEST_F(IntersectionObserverV2Test, BasicOcclusion) {
EXPECT_EQ(observer_delegate->EntryCount(), 2);
EXPECT_TRUE(observer_delegate->LastEntry()->isIntersecting());
EXPECT_FALSE(observer_delegate->LastEntry()->isVisible());
+
+ // Zero-opacity objects should not count as occluding.
+ occluder->SetInlineStyleProperty(CSSPropertyOpacity, "0");
+ Compositor().BeginFrame();
+ test::RunPendingTasks();
+ ASSERT_FALSE(Compositor().NeedsBeginFrame());
+ EXPECT_EQ(observer_delegate->CallCount(), 3);
+ EXPECT_EQ(observer_delegate->EntryCount(), 3);
+ EXPECT_TRUE(observer_delegate->LastEntry()->isIntersecting());
+ EXPECT_TRUE(observer_delegate->LastEntry()->isVisible());
}
TEST_F(IntersectionObserverV2Test, BasicOpacity) {
diff --git a/chromium/third_party/blink/renderer/core/invisible_dom/BUILD.gn b/chromium/third_party/blink/renderer/core/invisible_dom/BUILD.gn
new file mode 100644
index 00000000000..683b133e552
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/invisible_dom/BUILD.gn
@@ -0,0 +1,13 @@
+# 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.
+
+import("//third_party/blink/renderer/core/core.gni")
+
+blink_core_sources("invisible_dom") {
+ sources = [
+ "activate_invisible_event.cc",
+ "activate_invisible_event.h",
+ "activate_invisible_event.idl",
+ ]
+}
diff --git a/chromium/third_party/blink/renderer/core/invisible_dom/OWNERS b/chromium/third_party/blink/renderer/core/invisible_dom/OWNERS
new file mode 100644
index 00000000000..3d44e4e4af2
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/invisible_dom/OWNERS
@@ -0,0 +1,4 @@
+rakina@chromium.org
+
+# TEAM: dom-dev@chromium.org
+# COMPONENT: Blink>DOM
diff --git a/chromium/third_party/blink/renderer/core/invisible_dom/activate_invisible_event.cc b/chromium/third_party/blink/renderer/core/invisible_dom/activate_invisible_event.cc
new file mode 100644
index 00000000000..3257145ef6d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/invisible_dom/activate_invisible_event.cc
@@ -0,0 +1,33 @@
+// 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/invisible_dom/activate_invisible_event.h"
+
+#include "third_party/blink/renderer/core/dom/element.h"
+#include "third_party/blink/renderer/core/dom/events/event_dispatcher.h"
+#include "third_party/blink/renderer/core/event_names.h"
+
+namespace blink {
+
+const AtomicString& ActivateInvisibleEvent::InterfaceName() const {
+ return EventNames::ActivateInvisibleEvent;
+}
+
+bool ActivateInvisibleEvent::IsActivateInvisibleEvent() const {
+ return true;
+}
+
+ActivateInvisibleEvent::ActivateInvisibleEvent(Element* activated_element)
+ : Event(EventTypeNames::activateinvisible,
+ Bubbles::kYes,
+ Cancelable::kYes,
+ ComposedMode::kScoped),
+ activated_element_(activated_element) {}
+
+void ActivateInvisibleEvent::Trace(Visitor* visitor) {
+ visitor->Trace(activated_element_);
+ Event::Trace(visitor);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/invisible_dom/activate_invisible_event.h b/chromium/third_party/blink/renderer/core/invisible_dom/activate_invisible_event.h
new file mode 100644
index 00000000000..050e2663f1b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/invisible_dom/activate_invisible_event.h
@@ -0,0 +1,43 @@
+// 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_INVISIBLE_DOM_ACTIVATE_INVISIBLE_EVENT_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_INVISIBLE_DOM_ACTIVATE_INVISIBLE_EVENT_H_
+
+#include "third_party/blink/renderer/core/dom/events/event.h"
+
+namespace blink {
+
+class Element;
+
+class ActivateInvisibleEvent : public Event {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ static ActivateInvisibleEvent* Create(Element* activated_element) {
+ return new ActivateInvisibleEvent(activated_element);
+ }
+
+ Element* activatedElement() const { return activated_element_.Get(); }
+
+ void SetActivatedElement(Element* activated_element) {
+ activated_element_ = activated_element;
+ }
+
+ const AtomicString& InterfaceName() const override;
+ bool IsActivateInvisibleEvent() const override;
+
+ void Trace(Visitor*) override;
+
+ private:
+ explicit ActivateInvisibleEvent(Element* activated_element);
+
+ Member<Element> activated_element_;
+};
+
+DEFINE_EVENT_TYPE_CASTS(ActivateInvisibleEvent);
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_INVISIBLE_DOM_ACTIVATE_INVISIBLE_EVENT_H_
diff --git a/chromium/third_party/blink/renderer/core/invisible_dom/activate_invisible_event.idl b/chromium/third_party/blink/renderer/core/invisible_dom/activate_invisible_event.idl
new file mode 100644
index 00000000000..4ee6aaba60e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/invisible_dom/activate_invisible_event.idl
@@ -0,0 +1,11 @@
+// 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.
+
+// Explainer at https://goo.gl/mJUNB5
+
+[
+ RuntimeEnabled=InvisibleDOM
+] interface ActivateInvisibleEvent : Event {
+ readonly attribute Element? activatedElement;
+};
diff --git a/chromium/third_party/blink/renderer/core/layout/BUILD.gn b/chromium/third_party/blink/renderer/core/layout/BUILD.gn
index 1cbe8b01257..b5ab541b751 100644
--- a/chromium/third_party/blink/renderer/core/layout/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/layout/BUILD.gn
@@ -438,6 +438,7 @@ blink_core_sources("layout") {
"ng/ng_layout_utils.h",
"ng/ng_length_utils.cc",
"ng/ng_length_utils.h",
+ "ng/ng_link.h",
"ng/ng_out_of_flow_layout_part.cc",
"ng/ng_out_of_flow_layout_part.h",
"ng/ng_out_of_flow_positioned_descendant.h",
@@ -461,6 +462,7 @@ blink_core_sources("layout") {
"ng/ng_text_decoration_offset.h",
"ng/ng_unpositioned_float.cc",
"ng/ng_unpositioned_float.h",
+ "ng/ng_unpositioned_float_vector.h",
"order_iterator.cc",
"order_iterator.h",
"overflow_model.h",
diff --git a/chromium/third_party/blink/renderer/core/layout/api/line_layout_inline.h b/chromium/third_party/blink/renderer/core/layout/api/line_layout_inline.h
index b61921ec6f9..885fd9ba19b 100644
--- a/chromium/third_party/blink/renderer/core/layout/api/line_layout_inline.h
+++ b/chromium/third_party/blink/renderer/core/layout/api/line_layout_inline.h
@@ -63,7 +63,7 @@ class LineLayoutInline : public LineLayoutBoxModel {
return ToInline()->LastLineBoxIncludingCulling();
}
- LineBoxList* LineBoxes() { return ToInline()->LineBoxes(); }
+ LineBoxList* LineBoxes() { return ToInline()->MutableLineBoxes(); }
bool HitTestCulledInline(HitTestResult& result,
const HitTestLocation& location_in_container,
diff --git a/chromium/third_party/blink/renderer/core/layout/api/line_layout_item.h b/chromium/third_party/blink/renderer/core/layout/api/line_layout_item.h
index fcc3467d2c1..d4d92293b34 100644
--- a/chromium/third_party/blink/renderer/core/layout/api/line_layout_item.h
+++ b/chromium/third_party/blink/renderer/core/layout/api/line_layout_item.h
@@ -121,7 +121,7 @@ class LineLayoutItem {
if (IsSVGInlineText())
return false;
- return Style()->PreserveNewline();
+ return StyleRef().PreserveNewline();
}
unsigned length() const { return layout_object_->length(); }
diff --git a/chromium/third_party/blink/renderer/core/layout/api/line_layout_text.h b/chromium/third_party/blink/renderer/core/layout/api/line_layout_text.h
index d6a6ab3edea..5154d693423 100644
--- a/chromium/third_party/blink/renderer/core/layout/api/line_layout_text.h
+++ b/chromium/third_party/blink/renderer/core/layout/api/line_layout_text.h
@@ -5,6 +5,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_API_LINE_LAYOUT_TEXT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_API_LINE_LAYOUT_TEXT_H_
+#include "third_party/blink/renderer/core/editing/frame_selection.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/layout/api/line_layout_item.h"
#include "third_party/blink/renderer/core/layout/layout_text.h"
#include "third_party/blink/renderer/platform/layout_unit.h"
@@ -121,6 +123,11 @@ class LineLayoutText : public LineLayoutItem {
UChar PreviousCharacter() const { return ToText()->PreviousCharacter(); }
+ struct LayoutTextSelectionStatus SelectionStatus() const {
+ return ToText()->GetFrame()->Selection().ComputeLayoutSelectionStatus(
+ *ToText());
+ }
+
private:
LayoutText* ToText() { return ToLayoutText(GetLayoutObject()); }
const LayoutText* ToText() const { return ToLayoutText(GetLayoutObject()); }
diff --git a/chromium/third_party/blink/renderer/core/layout/api/selection_state.h b/chromium/third_party/blink/renderer/core/layout/api/selection_state.h
index 922c5147599..fea6336f816 100644
--- a/chromium/third_party/blink/renderer/core/layout/api/selection_state.h
+++ b/chromium/third_party/blink/renderer/core/layout/api/selection_state.h
@@ -10,25 +10,32 @@
namespace blink {
+// Each LayoutObject has a SelectionState and it represents how the
+// LayoutObject is selected. This enum is used to paint/invalidate selection
+// highlight for the LayoutObject.
enum class SelectionState {
- // LayoutObject is not selected.
+ // The LayoutObject is not selected.
kNone,
- // LayoutObject is the start of a selection run and doesn't have children.
+ // kStart, kInside, kEnd and kStartAndEnd represent the LayoutObject
+ // is somehow selected to paint and either LayoutText or LayoutReplaced.
+ // The start of a selection.
kStart,
- // LayoutObject is fully encompassed by a selection run and
- // doesn't have children.
+ // Inside a selection.
kInside,
- // LayoutObject is the end of a selection run and doesn't have children.
+ // The end of a selection.
kEnd,
- // LayoutObject contains an entire selection run and doesn't have children.
+ // The LayoutObject contains an entire selection.
kStartAndEnd,
- // LayoutObject has at least one LayoutObject child which SelectionState is
- // kStart, kInside, kEnd or kStartAndEnd.
- // This property is used to invalidate LayoutObject for ::selection style
- // change. See LayoutObject::InvalidatePaintForSelection().
+ // The LayoutObject has at least one LayoutObject child which SelectionState
+ // is not KNone.
+ // This property is used to invalidate LayoutObject.
kContain
};
+inline bool IsSelected(const SelectionState state) {
+ return state != SelectionState::kNone && state != SelectionState::kContain;
+}
+
CORE_EXPORT std::ostream& operator<<(std::ostream&, const SelectionState);
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/bidi_run_for_line.cc b/chromium/third_party/blink/renderer/core/layout/bidi_run_for_line.cc
index 59a9901a6dd..d304a55087f 100644
--- a/chromium/third_party/blink/renderer/core/layout/bidi_run_for_line.cc
+++ b/chromium/third_party/blink/renderer/core/layout/bidi_run_for_line.cc
@@ -83,8 +83,8 @@ TextDirection DeterminePlaintextDirectionality(LineLayoutItem root,
InlineIterator iter(LineLayoutItem(root), first_layout_object,
first_layout_object == current ? pos : 0);
InlineBidiResolver observer;
- observer.SetStatus(BidiStatus(root.Style()->Direction(),
- IsOverride(root.Style()->GetUnicodeBidi())));
+ observer.SetStatus(BidiStatus(root.StyleRef().Direction(),
+ IsOverride(root.StyleRef().GetUnicodeBidi())));
observer.SetPositionIgnoringNestedIsolates(iter);
return observer.DetermineParagraphDirectionality();
}
@@ -138,7 +138,7 @@ void ConstructBidiRunsForLine(InlineBidiResolver& top_resolver,
isolated_resolver.GetMidpointState();
isolated_line_midpoint_state =
top_resolver.MidpointStateForIsolatedRun(isolated_run.run_to_replace);
- UnicodeBidi unicode_bidi = isolated_inline.Style()->GetUnicodeBidi();
+ UnicodeBidi unicode_bidi = isolated_inline.StyleRef().GetUnicodeBidi();
TextDirection direction;
if (unicode_bidi == UnicodeBidi::kPlaintext) {
direction = DeterminePlaintextDirectionality(
@@ -146,7 +146,7 @@ void ConstructBidiRunsForLine(InlineBidiResolver& top_resolver,
} else {
DCHECK(unicode_bidi == UnicodeBidi::kIsolate ||
unicode_bidi == UnicodeBidi::kIsolateOverride);
- direction = isolated_inline.Style()->Direction();
+ direction = isolated_inline.StyleRef().Direction();
}
isolated_resolver.SetStatus(BidiStatus::CreateForIsolate(
direction, IsOverride(unicode_bidi), isolated_run.level));
diff --git a/chromium/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope.cc b/chromium/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope.cc
index 8397c2195ef..b5dde5c35ad 100644
--- a/chromium/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope.cc
+++ b/chromium/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope.cc
@@ -31,10 +31,11 @@ LayoutWorkletGlobalScope* LayoutWorkletGlobalScope::Create(
reporting_proxy, pending_layout_registry);
String context_name("LayoutWorklet #");
context_name.append(String::Number(global_scope_number));
- global_scope->ScriptController()->InitializeContextIfNeeded(context_name);
+ global_scope->ScriptController()->InitializeContextIfNeeded(context_name,
+ NullURL());
MainThreadDebugger::Instance()->ContextCreated(
global_scope->ScriptController()->GetScriptState(),
- global_scope->GetFrame(), global_scope->GetSecurityOrigin());
+ global_scope->GetFrame(), global_scope->DocumentSecurityOrigin());
return global_scope;
}
diff --git a/chromium/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope.idl b/chromium/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope.idl
index 3bdcf12288b..0ed4c1efbce 100644
--- a/chromium/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope.idl
+++ b/chromium/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope.idl
@@ -9,5 +9,7 @@
Global=(Worklet,LayoutWorklet),
RuntimeEnabled=CSSLayoutAPI
] interface LayoutWorkletGlobalScope : WorkletGlobalScope {
- [RaisesException] void registerLayout(DOMString name, Function layoutCtor);
+ // TODO(yukishiino): |layoutCtor| should be of callback function type
+ // (should be: callback T = any ()).
+ [RaisesException] void registerLayout(DOMString name, CallbackFunctionTreatedAsScriptValue layoutCtor);
};
diff --git a/chromium/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope_proxy.cc b/chromium/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope_proxy.cc
index 078e62405f9..13dcac64411 100644
--- a/chromium/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope_proxy.cc
+++ b/chromium/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope_proxy.cc
@@ -45,8 +45,8 @@ LayoutWorkletGlobalScopeProxy::LayoutWorkletGlobalScopeProxy(
document->Url(), ScriptType::kModule, document->UserAgent(),
document->GetContentSecurityPolicy()->Headers(),
document->GetReferrerPolicy(), document->GetSecurityOrigin(),
- document->IsSecureContext(), worker_clients, document->AddressSpace(),
- OriginTrialContext::GetTokens(document).get(),
+ document->IsSecureContext(), document->GetHttpsState(), worker_clients,
+ document->AddressSpace(), OriginTrialContext::GetTokens(document).get(),
base::UnguessableToken::Create(), nullptr /* worker_settings */,
kV8CacheOptionsDefault, module_responses_map);
global_scope_ = LayoutWorkletGlobalScope::Create(
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 50501fdc7cd..f070bde3cad 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
@@ -111,11 +111,11 @@ LayoutUnit FlexItem::AvailableAlignmentSpace(
bool FlexItem::HasAutoMarginsInCrossAxis() const {
if (algorithm->IsHorizontalFlow()) {
- return box->Style()->MarginTop().IsAuto() ||
- box->Style()->MarginBottom().IsAuto();
+ return box->StyleRef().MarginTop().IsAuto() ||
+ box->StyleRef().MarginBottom().IsAuto();
}
- return box->Style()->MarginLeft().IsAuto() ||
- box->Style()->MarginRight().IsAuto();
+ return box->StyleRef().MarginLeft().IsAuto() ||
+ box->StyleRef().MarginRight().IsAuto();
}
ItemPosition FlexItem::Alignment() const {
@@ -127,14 +127,14 @@ void FlexItem::UpdateAutoMarginsInMainAxis(LayoutUnit auto_margin_offset) {
DCHECK_GE(auto_margin_offset, LayoutUnit());
if (algorithm->IsHorizontalFlow()) {
- if (box->Style()->MarginLeft().IsAuto())
+ if (box->StyleRef().MarginLeft().IsAuto())
box->SetMarginLeft(auto_margin_offset);
- if (box->Style()->MarginRight().IsAuto())
+ if (box->StyleRef().MarginRight().IsAuto())
box->SetMarginRight(auto_margin_offset);
} else {
- if (box->Style()->MarginTop().IsAuto())
+ if (box->StyleRef().MarginTop().IsAuto())
box->SetMarginTop(auto_margin_offset);
- if (box->Style()->MarginBottom().IsAuto())
+ if (box->StyleRef().MarginBottom().IsAuto())
box->SetMarginBottom(auto_margin_offset);
}
}
@@ -145,10 +145,10 @@ void FlexLine::FreezeViolations(Vector<FlexItem*>& violations) {
LayoutBox* child = violations[i]->box;
LayoutUnit child_size = violations[i]->flexed_content_size;
remaining_free_space -= child_size - violations[i]->flex_base_content_size;
- total_flex_grow -= child->Style()->FlexGrow();
- total_flex_shrink -= child->Style()->FlexShrink();
+ total_flex_grow -= child->StyleRef().FlexGrow();
+ total_flex_shrink -= child->StyleRef().FlexShrink();
total_weighted_flex_shrink -=
- child->Style()->FlexShrink() * violations[i]->flex_base_content_size;
+ child->StyleRef().FlexShrink() * violations[i]->flex_base_content_size;
// totalWeightedFlexShrink can be negative when we exceed the precision of
// a double when we initially calcuate totalWeightedFlexShrink. We then
// subtract each child's weighted flex shrink with full precision, now
@@ -173,8 +173,8 @@ void FlexLine::FreezeInflexibleItems() {
DCHECK(!flex_item.box->IsOutOfFlowPositioned());
DCHECK(!flex_item.frozen) << i;
float flex_factor = (flex_sign == kPositiveFlexibility)
- ? child->Style()->FlexGrow()
- : child->Style()->FlexShrink();
+ ? child->StyleRef().FlexGrow()
+ : child->StyleRef().FlexShrink();
if (flex_factor == 0 ||
(flex_sign == kPositiveFlexibility &&
flex_item.flex_base_content_size >
@@ -218,12 +218,12 @@ 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->Style()->FlexGrow() / total_flex_grow;
+ remaining_free_space * child->StyleRef().FlexGrow() / total_flex_grow;
} else if (remaining_free_space < 0 && total_weighted_flex_shrink > 0 &&
flex_sign == kNegativeFlexibility &&
std::isfinite(total_weighted_flex_shrink) &&
- child->Style()->FlexShrink()) {
- extra_space = remaining_free_space * child->Style()->FlexShrink() *
+ child->StyleRef().FlexShrink()) {
+ extra_space = remaining_free_space * child->StyleRef().FlexShrink() *
flex_item.flex_base_content_size /
total_weighted_flex_shrink;
}
@@ -262,14 +262,14 @@ LayoutUnit FlexLine::ApplyMainAxisAutoMarginAdjustment() {
LayoutBox* child = line_items[i].box;
DCHECK(!child->IsOutOfFlowPositioned());
if (is_horizontal) {
- if (child->Style()->MarginLeft().IsAuto())
+ if (child->StyleRef().MarginLeft().IsAuto())
++number_of_auto_margins;
- if (child->Style()->MarginRight().IsAuto())
+ if (child->StyleRef().MarginRight().IsAuto())
++number_of_auto_margins;
} else {
- if (child->Style()->MarginTop().IsAuto())
+ if (child->StyleRef().MarginTop().IsAuto())
++number_of_auto_margins;
- if (child->Style()->MarginBottom().IsAuto())
+ if (child->StyleRef().MarginBottom().IsAuto())
++number_of_auto_margins;
}
}
@@ -302,7 +302,7 @@ void FlexLine::ComputeLineItemsPosition(LayoutUnit main_axis_offset,
available_free_space, justify_content, line_items.size());
LayoutUnit max_descent; // Used when align-items: baseline.
LayoutUnit max_child_cross_axis_extent;
- bool should_flip_main_axis = !algorithm->Style()->IsColumnFlexDirection() &&
+ bool should_flip_main_axis = !algorithm->StyleRef().IsColumnFlexDirection() &&
!algorithm->IsLeftToRightFlow();
for (size_t i = 0; i < line_items.size(); ++i) {
FlexItem& flex_item = line_items[i];
@@ -392,10 +392,10 @@ FlexLine* FlexLayoutAlgorithm::ComputeNextFlexLine(
line_items.push_back(flex_item);
line_has_in_flow_item = true;
sum_flex_base_size += flex_item.FlexBaseMarginBoxSize();
- total_flex_grow += flex_item.box->Style()->FlexGrow();
- total_flex_shrink += flex_item.box->Style()->FlexShrink();
- total_weighted_flex_shrink +=
- flex_item.box->Style()->FlexShrink() * flex_item.flex_base_content_size;
+ total_flex_grow += flex_item.box->StyleRef().FlexGrow();
+ total_flex_shrink += flex_item.box->StyleRef().FlexShrink();
+ total_weighted_flex_shrink += flex_item.box->StyleRef().FlexShrink() *
+ flex_item.flex_base_content_size;
sum_hypothetical_main_size += flex_item.HypotheticalMainAxisMarginBoxSize();
}
DCHECK(line_items.size() > 0 || next_item_index_ == all_items_.size());
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 05635caaa22..ea5bf0f2ca9 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
@@ -62,9 +62,8 @@ enum class TransformedWritingMode {
class FlexItem {
public:
+ // flex_base_content_size includes scrollbar width but not border or padding.
FlexItem(LayoutBox*,
- // flex_base_content_size includes scrollbar width but not border or
- // padding.
LayoutUnit flex_base_content_size,
MinMaxSize min_max_sizes,
LayoutUnit main_axis_border_and_padding,
@@ -243,11 +242,13 @@ class FlexLayoutAlgorithm {
Vector<FlexItem>& all_items);
const ComputedStyle* Style() const { return style_; }
+ const ComputedStyle& StyleRef() const { return *style_; }
Vector<FlexLine>& FlexLines() { return flex_lines_; }
// Computes the next flex line, stores it in FlexLines(), and returns a
// pointer to it. Returns nullptr if there are no more lines.
+ // container_logical_width is the border box width.
FlexLine* ComputeNextFlexLine(LayoutUnit container_logical_width);
bool IsHorizontalFlow() const;
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 9e585042752..befe3ddc81b 100644
--- a/chromium/third_party/blink/renderer/core/layout/floating_objects.cc
+++ b/chromium/third_party/blink/renderer/core/layout/floating_objects.cc
@@ -59,7 +59,7 @@ FloatingObject::FloatingObject(LayoutBox* layout_object)
is_in_placed_tree_(false)
#endif
{
- EFloat type = layout_object->Style()->Floating();
+ EFloat type = layout_object->StyleRef().Floating();
DCHECK_NE(type, EFloat::kNone);
if (type == EFloat::kLeft)
type_ = kFloatLeft;
diff --git a/chromium/third_party/blink/renderer/core/layout/fragmentainer_iterator.cc b/chromium/third_party/blink/renderer/core/layout/fragmentainer_iterator.cc
index e76d8e745b2..a376aeedf38 100644
--- a/chromium/third_party/blink/renderer/core/layout/fragmentainer_iterator.cc
+++ b/chromium/third_party/blink/renderer/core/layout/fragmentainer_iterator.cc
@@ -79,11 +79,10 @@ LayoutUnit FragmentainerIterator::FragmentainerLogicalTopInFlowThread() const {
current_fragmentainer_index_ * group.ColumnLogicalHeight();
}
-LayoutRect FragmentainerIterator::ClipRectInFlowThread(
- MultiColumnFragmentainerGroup::ClipRectAxesSelector axes_selector) const {
+LayoutRect FragmentainerIterator::ClipRectInFlowThread() const {
DCHECK(!AtEnd());
LayoutRect clip_rect = CurrentGroup().FlowThreadPortionOverflowRectAt(
- current_fragmentainer_index_, axes_selector);
+ current_fragmentainer_index_);
flow_thread_.FlipForWritingMode(clip_rect);
return clip_rect;
}
diff --git a/chromium/third_party/blink/renderer/core/layout/fragmentainer_iterator.h b/chromium/third_party/blink/renderer/core/layout/fragmentainer_iterator.h
index c9b5747f387..f82bce53fdf 100644
--- a/chromium/third_party/blink/renderer/core/layout/fragmentainer_iterator.h
+++ b/chromium/third_party/blink/renderer/core/layout/fragmentainer_iterator.h
@@ -43,9 +43,7 @@ class FragmentainerIterator {
// Return the physical clip rectangle of the current fragmentainer, relative
// to the flow thread.
- LayoutRect ClipRectInFlowThread(
- MultiColumnFragmentainerGroup::ClipRectAxesSelector =
- MultiColumnFragmentainerGroup::kBothAxes) const;
+ LayoutRect ClipRectInFlowThread() const;
private:
const LayoutFlowThread& flow_thread_;
diff --git a/chromium/third_party/blink/renderer/core/layout/grid.cc b/chromium/third_party/blink/renderer/core/layout/grid.cc
index 219dd6fa054..2ece4fae04b 100644
--- a/chromium/third_party/blink/renderer/core/layout/grid.cc
+++ b/chromium/third_party/blink/renderer/core/layout/grid.cc
@@ -12,55 +12,20 @@
namespace blink {
-std::unique_ptr<Grid> Grid::Create(const LayoutGrid* layout_grid) {
- return base::WrapUnique(new VectorGrid(layout_grid));
-}
-
-Grid::Grid(const LayoutGrid* grid) : order_iterator_(grid) {}
+namespace {
-VectorGrid::VectorGrid(const LayoutGrid* grid) : Grid(grid) {}
+static inline GridTrackSizingDirection OrthogonalDirection(
+ GridTrackSizingDirection direction) {
+ return direction == kForRows ? kForColumns : kForRows;
+};
-size_t VectorGrid::NumTracks(GridTrackSizingDirection direction) const {
- if (direction == kForRows)
- return matrix_.size();
- return matrix_.size() ? matrix_[0].size() : 0;
-}
+} // namespace
-void VectorGrid::EnsureGridSize(size_t maximum_row_size,
- size_t maximum_column_size) {
- const size_t old_row_size = NumTracks(kForRows);
- if (maximum_row_size > old_row_size) {
- matrix_.Grow(maximum_row_size);
- for (size_t row = old_row_size; row < NumTracks(kForRows); ++row)
- matrix_[row].Grow(NumTracks(kForColumns));
- }
-
- if (maximum_column_size > NumTracks(kForColumns)) {
- for (size_t row = 0; row < NumTracks(kForRows); ++row)
- matrix_[row].Grow(maximum_column_size);
- }
-}
-
-void VectorGrid::insert(LayoutBox& child, const GridArea& area) {
- DCHECK(area.rows.IsTranslatedDefinite());
- DCHECK(area.columns.IsTranslatedDefinite());
- EnsureGridSize(area.rows.EndLine(), area.columns.EndLine());
-
- for (const auto& row : area.rows) {
- for (const auto& column : area.columns)
- matrix_[row][column].push_back(&child);
- }
-
- SetGridItemArea(child, area);
+std::unique_ptr<Grid> Grid::Create(const LayoutGrid* layout_grid) {
+ return base::WrapUnique(new ListGrid(layout_grid));
}
-std::unique_ptr<Grid::GridIterator> VectorGrid::CreateIterator(
- GridTrackSizingDirection direction,
- size_t fixed_track_index,
- size_t varying_track_index) const {
- return base::WrapUnique(new VectorGridIterator(
- *this, direction, fixed_track_index, varying_track_index));
-}
+Grid::Grid(const LayoutGrid* grid) : order_iterator_(grid) {}
void Grid::SetSmallestTracksStart(int row_start, int column_start) {
smallest_row_start_ = row_start;
@@ -171,90 +136,341 @@ Grid::GridIterator::GridIterator(GridTrackSizingDirection direction,
: varying_track_index),
child_index_(0) {}
-VectorGridIterator::VectorGridIterator(const VectorGrid& grid,
- GridTrackSizingDirection direction,
- size_t fixed_track_index,
- size_t varying_track_index)
- : GridIterator(direction, fixed_track_index, varying_track_index),
- matrix_(grid.matrix_) {
- DCHECK(!matrix_.IsEmpty());
- DCHECK(!matrix_[0].IsEmpty());
- DCHECK_LT(row_index_, matrix_.size());
- DCHECK_LT(column_index_, matrix_[0].size());
-}
-
-LayoutBox* VectorGridIterator::NextGridItem() {
- DCHECK(!matrix_.IsEmpty());
- DCHECK(!matrix_[0].IsEmpty());
-
- size_t& varying_track_index =
- (direction_ == kForColumns) ? row_index_ : column_index_;
- const size_t end_of_varying_track_index =
- (direction_ == kForColumns) ? matrix_.size() : matrix_[0].size();
- for (; varying_track_index < end_of_varying_track_index;
- ++varying_track_index) {
- const GridCell& children = matrix_[row_index_][column_index_];
- if (child_index_ < children.size())
- return children[child_index_++];
-
- child_index_ = 0;
+ListGrid::GridCell* ListGrid::GridTrack::Find(size_t index) const {
+ auto orthogonal_axis = OrthogonalDirection(direction_);
+ for (auto* cell = cells_.Head(); cell;
+ cell = cell->NextInDirection(direction_)) {
+ size_t cell_index = cell->Index(orthogonal_axis);
+ if (cell_index == index)
+ return cell;
+ if (cell_index > index)
+ return nullptr;
}
return nullptr;
}
-bool VectorGridIterator::CheckEmptyCells(size_t row_span,
- size_t column_span) const {
- DCHECK(!matrix_.IsEmpty());
- DCHECK(!matrix_[0].IsEmpty());
+static int ComparePositions(size_t first, size_t second) {
+ return first < second ? -1 : (first != second);
+}
- // Ignore cells outside current grid as we will grow it later if needed.
- size_t max_rows = std::min(row_index_ + row_span, matrix_.size());
- size_t max_columns = std::min(column_index_ + column_span, matrix_[0].size());
+DoublyLinkedList<ListGrid::GridCell>::AddResult ListGrid::GridTrack::Insert(
+ GridCell* cell) {
+ cell->SetTraversalMode(direction_);
+ return cells_.Insert(
+ cell, [direction = direction_](ListGrid::GridCell * first,
+ ListGrid::GridCell * second) {
+ // This is ugly but we need to do this in order the
+ // DoublyLinkedList::Insert() algorithm to work at that code
+ // only uses next_ and prev_.
+ first->SetTraversalMode(direction);
+ second->SetTraversalMode(direction);
+ auto ortho_direction = OrthogonalDirection(direction);
+ return ComparePositions(first->Index(ortho_direction),
+ second->Index(ortho_direction));
+ });
+}
- // This adds a O(N^2) behavior that shouldn't be a big deal as we expect
- // spanning areas to be small.
- for (size_t row = row_index_; row < max_rows; ++row) {
- for (size_t column = column_index_; column < max_columns; ++column) {
- const GridCell& children = matrix_[row][column];
- if (!children.IsEmpty())
- return false;
+DoublyLinkedList<ListGrid::GridCell>::AddResult ListGrid::GridTrack::Insert(
+ LayoutBox& item,
+ const GridSpan& span) {
+ auto CompareCells = [direction = direction_](ListGrid::GridCell * first,
+ ListGrid::GridCell * second) {
+ first->SetTraversalMode(direction);
+ second->SetTraversalMode(direction);
+ auto ortho_direction = OrthogonalDirection(direction);
+ return ComparePositions(first->Index(ortho_direction),
+ second->Index(ortho_direction));
+ };
+
+ size_t col_index = direction_ == kForColumns ? Index() : span.StartLine();
+ size_t row_index = direction_ == kForColumns ? span.StartLine() : Index();
+
+ auto result = cells_.Insert(
+ base::WrapUnique(new GridCell(row_index, col_index)), CompareCells);
+ auto* cell = result.node;
+ for (auto index : span) {
+ cell->AppendItem(item);
+
+ if (index == span.EndLine() - 1)
+ break;
+
+ cell->SetTraversalMode(direction_);
+ auto ortho_direction = OrthogonalDirection(direction_);
+ if (!cell->Next() ||
+ (cell->Next()->Index(ortho_direction) != (index + 1))) {
+ size_t next_col_index = direction_ == kForColumns ? Index() : index + 1;
+ size_t next_row_index = direction_ == kForColumns ? index + 1 : Index();
+ auto next_cell =
+ base::WrapUnique(new GridCell(next_row_index, next_col_index));
+ auto result = InsertAfter(next_cell.get(), cell);
+ if (result.is_new_entry)
+ next_cell.release();
}
+ cell = cell->Next();
}
+ return result;
+}
- return true;
+DoublyLinkedList<ListGrid::GridCell>::AddResult
+ListGrid::GridTrack::InsertAfter(GridCell* cell, GridCell* insertion_point) {
+ insertion_point->SetTraversalMode(direction_);
+ cell->SetTraversalMode(direction_);
+ if (auto* next = insertion_point->Next()) {
+ if (next == cell)
+ return {cell, false};
+ // We need to set the traversal mode for the next cell as we're
+ // going to insert in between and we need to properly update next_
+ // and prev_ pointers.
+ next->SetTraversalMode(direction_);
+ }
+ return cells_.InsertAfter(cell, insertion_point);
}
-std::unique_ptr<GridArea> VectorGridIterator::NextEmptyGridArea(
+ListGrid::GridTrack::~GridTrack() {
+ // We destroy cells just when disposing columns as we don't want to
+ // double free them.
+ // TODO(svillar): we need to eventually get rid of this different
+ // destructors depending on the axis.
+ if (direction_ == kForRows) {
+ cells_.Clear();
+ return;
+ }
+
+ while (!cells_.IsEmpty()) {
+ cells_.Head()->SetTraversalMode(kForColumns);
+ if (cells_.Head()->Next())
+ cells_.Head()->Next()->SetTraversalMode(kForColumns);
+ delete cells_.RemoveHead();
+ }
+}
+
+const GridItemList& ListGrid::Cell(size_t row_index,
+ size_t column_index) const {
+ DEFINE_STATIC_LOCAL(const GridItemList, empty_vector, ());
+ for (auto* row = rows_.Head(); row; row = row->Next()) {
+ if (row->Index() == row_index) {
+ auto* cell = row->Find(column_index);
+ return cell ? cell->Items() : empty_vector;
+ }
+ if (row->Index() > row_index)
+ return empty_vector;
+ }
+ return empty_vector;
+}
+
+ListGrid::GridTrack* ListGrid::InsertTracks(
+ DoublyLinkedList<GridTrack>& tracks,
+ const GridSpan& span,
+ GridTrackSizingDirection direction) {
+ auto CompareTracks = [](ListGrid::GridTrack* first,
+ ListGrid::GridTrack* second) {
+ return ComparePositions(first->Index(), second->Index());
+ };
+
+ size_t start_line = span.StartLine();
+ size_t end_line = span.EndLine();
+
+ DoublyLinkedList<ListGrid::GridTrack>::AddResult result = tracks.Insert(
+ base::WrapUnique(new GridTrack(start_line, direction)), CompareTracks);
+ auto* track = result.node;
+ DCHECK(track);
+
+ auto* iter = track;
+ for (size_t track_index = start_line + 1; iter && track_index < end_line;
+ ++track_index) {
+ if (!iter->Next() || track_index < iter->Next()->Index()) {
+ tracks.InsertAfter(
+ base::WrapUnique(new GridTrack(track_index, direction)), iter);
+ }
+ iter = iter->Next();
+ }
+
+ return track;
+}
+
+void ListGrid::Insert(LayoutBox& item, const GridArea& area) {
+ DCHECK(area.rows.IsTranslatedDefinite() &&
+ area.columns.IsTranslatedDefinite());
+ EnsureGridSize(area.rows.EndLine(), area.columns.EndLine());
+
+ GridTrack* first_row = InsertTracks(rows_, area.rows, kForRows);
+ DCHECK(first_row);
+ GridTrack* first_column = InsertTracks(columns_, area.columns, kForColumns);
+ DCHECK(first_column);
+
+ GridCell* above_cell = nullptr;
+ GridTrack* row = first_row;
+ for (auto row_index : area.rows) {
+ auto result = row->Insert(item, area.columns);
+ // We need to call Insert() for the first row of cells to get the
+ // column pointers right. For the following rows we can use
+ // InsertAfter() as it's cheaper (it doesn't traverse the
+ // list). We need to keep track of the cell in the row above
+ // (above_cell) in order to properly update the column next_ &
+ // prev_ pointers.
+ auto* cell_iter = result.node;
+ auto* col_iter = first_column;
+ while (col_iter && col_iter->Index() < area.columns.EndLine()) {
+ if (row_index == area.rows.StartLine()) {
+ col_iter->Insert(cell_iter);
+ } else {
+ col_iter->InsertAfter(cell_iter, above_cell);
+ above_cell = above_cell->NextInDirection(kForRows);
+ }
+ cell_iter = cell_iter->NextInDirection(kForRows);
+ col_iter = col_iter->Next();
+ }
+ above_cell = result.node;
+ row = row->Next();
+ }
+
+ SetGridItemArea(item, area);
+}
+
+void ListGrid::EnsureGridSize(size_t maximum_row_size,
+ size_t maximum_column_size) {
+ num_rows_ = std::max(num_rows_, maximum_row_size);
+ num_columns_ = std::max(num_columns_, maximum_column_size);
+}
+
+void ListGrid::ClearGridDataStructure() {
+ num_rows_ = num_columns_ = 0;
+ while (!rows_.IsEmpty())
+ delete rows_.RemoveHead();
+ DCHECK(rows_.IsEmpty());
+ while (!columns_.IsEmpty())
+ delete columns_.RemoveHead();
+ DCHECK(columns_.IsEmpty());
+}
+
+ListGrid::~ListGrid() {
+ ClearGridDataStructure();
+}
+
+void ListGrid::GridCell::SetTraversalMode(GridTrackSizingDirection direction) {
+ if (direction == direction_)
+ return;
+ direction_ = direction;
+ std::swap(next_, next_ortho_);
+ std::swap(prev_, prev_ortho_);
+}
+
+ListGrid::GridCell* ListGrid::GridCell::NextInDirection(
+ GridTrackSizingDirection direction) const {
+ return direction_ == direction ? next_ : next_ortho_;
+}
+
+std::unique_ptr<Grid::GridIterator> ListGrid::CreateIterator(
+ GridTrackSizingDirection direction,
+ size_t fixed_track_index,
+ size_t varying_track_index) const {
+ return base::WrapUnique(new ListGridIterator(
+ *this, direction, fixed_track_index, varying_track_index));
+}
+
+ListGridIterator::ListGridIterator(const ListGrid& grid,
+ GridTrackSizingDirection direction,
+ size_t fixed_track_index,
+ size_t varying_track_index)
+ : GridIterator(direction, fixed_track_index, varying_track_index),
+ grid_(grid) {}
+
+LayoutBox* ListGridIterator::NextGridItem() {
+ DCHECK(grid_.NumTracks(kForRows));
+ DCHECK(grid_.NumTracks(kForColumns));
+
+ bool is_row_axis = direction_ == kForColumns;
+ if (!cell_node_) {
+ auto* track = is_row_axis ? grid_.columns_.Head() : grid_.rows_.Head();
+ DCHECK(track);
+ const size_t fixed_index = is_row_axis ? column_index_ : row_index_;
+ while (track && track->Index() != fixed_index)
+ track = track->Next();
+
+ if (!track)
+ return nullptr;
+
+ child_index_ = 0;
+ cell_node_ = track->Cells().Head();
+ DCHECK(cell_node_);
+ DCHECK(!cell_node_->Items().IsEmpty());
+ return cell_node_->Items()[child_index_++];
+ }
+
+ if (child_index_ < cell_node_->Items().size())
+ return cell_node_->Items()[child_index_++];
+
+ child_index_ = 0;
+ cell_node_ = cell_node_->NextInDirection(direction_);
+ if (!cell_node_)
+ return nullptr;
+
+ DCHECK(!cell_node_->Items().IsEmpty());
+ return cell_node_->Items()[child_index_++];
+}
+
+std::unique_ptr<GridArea> ListGridIterator::NextEmptyGridArea(
size_t fixed_track_span,
size_t varying_track_span) {
- DCHECK(!matrix_.IsEmpty());
- DCHECK(!matrix_[0].IsEmpty());
- DCHECK_GE(fixed_track_span, 1u);
- DCHECK_GE(varying_track_span, 1u);
-
- size_t row_span =
- (direction_ == kForColumns) ? varying_track_span : fixed_track_span;
- size_t column_span =
- (direction_ == kForColumns) ? fixed_track_span : varying_track_span;
-
- size_t& varying_track_index =
- (direction_ == kForColumns) ? row_index_ : column_index_;
- const size_t end_of_varying_track_index =
- (direction_ == kForColumns) ? matrix_.size() : matrix_[0].size();
- for (; varying_track_index < end_of_varying_track_index;
- ++varying_track_index) {
- if (CheckEmptyCells(row_span, column_span)) {
- std::unique_ptr<GridArea> result = std::make_unique<GridArea>(
- GridSpan::TranslatedDefiniteGridSpan(row_index_,
- row_index_ + row_span),
- GridSpan::TranslatedDefiniteGridSpan(column_index_,
- column_index_ + column_span));
- // Advance the iterator to avoid an infinite loop where we would return
- // the same grid area over and over.
- ++varying_track_index;
- return result;
+ auto FindCellOrClosest = [](ListGrid::GridCell* cell_node,
+ GridTrackSizingDirection direction,
+ size_t index) {
+ auto ortho_direction = OrthogonalDirection(direction);
+ while (cell_node && cell_node->Index(direction) < index)
+ cell_node = cell_node->NextInDirection(ortho_direction);
+
+ return cell_node;
+ };
+
+ auto CreateUniqueGridArea = [this, fixed_track_span, varying_track_span]() {
+ bool is_row_axis = direction_ == kForColumns;
+ size_t row_span = is_row_axis ? varying_track_span : fixed_track_span;
+ size_t column_span = is_row_axis ? fixed_track_span : varying_track_span;
+ return std::make_unique<GridArea>(
+ GridSpan::TranslatedDefiniteGridSpan(row_index_, row_index_ + row_span),
+ GridSpan::TranslatedDefiniteGridSpan(column_index_,
+ column_index_ + column_span));
+ };
+
+ auto CellIsInsideSpan = [](ListGrid::GridCell* cell_node,
+ GridTrackSizingDirection direction, size_t start,
+ size_t end) {
+ DCHECK(cell_node);
+ size_t cell_index = cell_node->Index(direction);
+ return cell_index >= start && cell_index <= end;
+ };
+
+ auto orthogonal_axis = OrthogonalDirection(direction_);
+ auto& tracks = grid_.Tracks(orthogonal_axis);
+
+ bool is_row_axis = direction_ == kForColumns;
+ auto& varying_index = is_row_axis ? row_index_ : column_index_;
+ const size_t fixed_index = is_row_axis ? column_index_ : row_index_;
+ const size_t end_fixed_span = fixed_index + fixed_track_span - 1;
+ size_t last_varying_index = grid_.NumTracks(orthogonal_axis);
+ auto* track_node = tracks.Head();
+ while (track_node && track_node->Index() < varying_index)
+ track_node = track_node->Next();
+
+ do {
+ if (!track_node) {
+ if (last_varying_index - varying_index >= varying_track_span)
+ return CreateUniqueGridArea();
+ return nullptr;
}
- }
+ if (track_node->Index() - varying_index >= varying_track_span)
+ return CreateUniqueGridArea();
+
+ auto* cell_node =
+ FindCellOrClosest(track_node->Cells().Head(), direction_, fixed_index);
+ if (cell_node &&
+ CellIsInsideSpan(cell_node, direction_, fixed_index, end_fixed_span))
+ varying_index = track_node->Index() + 1;
+ else if (track_node->Index() - varying_index >= varying_track_span)
+ return CreateUniqueGridArea();
+ track_node = track_node->Next();
+ } while (true); // track_node will eventually be nullptr
+
return nullptr;
}
diff --git a/chromium/third_party/blink/renderer/core/layout/grid.h b/chromium/third_party/blink/renderer/core/layout/grid.h
index 28b061d6cf9..db8a3038d8b 100644
--- a/chromium/third_party/blink/renderer/core/layout/grid.h
+++ b/chromium/third_party/blink/renderer/core/layout/grid.h
@@ -6,30 +6,30 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_GRID_H_
#include "base/macros.h"
+#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/layout/order_iterator.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/platform/wtf/assertions.h"
+#include "third_party/blink/renderer/platform/wtf/doubly_linked_list.h"
#include "third_party/blink/renderer/platform/wtf/linked_hash_set.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
// TODO(svillar): Perhaps we should use references here.
-typedef Vector<LayoutBox*, 1> GridCell;
-typedef Vector<Vector<GridCell>> GridAsMatrix;
+typedef Vector<LayoutBox*, 1> GridItemList;
typedef LinkedHashSet<size_t> OrderedTrackIndexSet;
class LayoutGrid;
class GridIterator;
-// The Grid class represent a generic storage for grid items. It's currently
-// implemented as a matrix (vector of vectors) but it can be eventually replaced
-// by a more memory efficient representation. This class is used by the
-// LayoutGrid object to place the grid items on a grid like structure, so that
-// they could be accessed by rows/columns instead of just traversing the DOM or
-// Layout trees.
-class Grid {
+// The Grid class represent a generic storage for grid items. This
+// class is used by the LayoutGrid object to place the grid items on a
+// grid like structure, so that they could be accessed by rows/columns
+// instead of just traversing the DOM or Layout trees. The other user
+// of this class is the GridTrackSizingAlgorithm class.
+class CORE_EXPORT Grid {
public:
static std::unique_ptr<Grid> Create(const LayoutGrid*);
@@ -37,9 +37,9 @@ class Grid {
virtual void EnsureGridSize(size_t maximum_row_size,
size_t maximum_column_size) = 0;
- virtual void insert(LayoutBox&, const GridArea&) = 0;
+ virtual void Insert(LayoutBox&, const GridArea&) = 0;
- virtual const GridCell& Cell(size_t row, size_t column) const = 0;
+ virtual const GridItemList& Cell(size_t row, size_t column) const = 0;
virtual ~Grid(){};
@@ -64,7 +64,6 @@ class Grid {
void SetAutoRepeatEmptyColumns(std::unique_ptr<OrderedTrackIndexSet>);
void SetAutoRepeatEmptyRows(std::unique_ptr<OrderedTrackIndexSet>);
- size_t AutoRepeatEmptyTracksCount(GridTrackSizingDirection) const;
bool HasAutoRepeatEmptyTracks(GridTrackSizingDirection) const;
bool IsEmptyAutoRepeatTrack(GridTrackSizingDirection, size_t) const;
@@ -135,39 +134,150 @@ class Grid {
std::unique_ptr<OrderedTrackIndexSet> auto_repeat_empty_rows_{nullptr};
};
-class VectorGrid final : public Grid {
+// This is a Grid specialization which uses doubly linked lists (DLL)
+// for the grid data structure. Each axis will be represented by a DLL
+// of GridTrack's. The grid will only have list nodes for those tracks
+// which actually contain at least one item. Those DLL are ordered by
+// the track index.
+class CORE_EXPORT ListGrid final : public Grid {
public:
- explicit VectorGrid(const LayoutGrid*);
+ explicit ListGrid(const LayoutGrid* grid) : Grid(grid) {}
- size_t NumTracks(GridTrackSizingDirection) const override;
- const GridCell& Cell(size_t row, size_t column) const override {
- return matrix_[row][column];
+ size_t NumTracks(GridTrackSizingDirection direction) const override {
+ return direction == kForRows ? num_rows_ : num_columns_;
}
- void insert(LayoutBox&, const GridArea&) override;
+ const GridItemList& Cell(size_t row, size_t column) const override;
+ void Insert(LayoutBox&, const GridArea&) override;
+ void EnsureGridSize(size_t maximum_row_size,
+ size_t maximum_column_size) override;
+
+ ~ListGrid() final;
+
+ // This is the class representing a cell in the grid. GridCell's are
+ // only created for those cells which do have items inside. Each
+ // GridCell will be part of two different DLL, one representing the
+ // column and another one representing the row.
+ class GridCell final : public DoublyLinkedListNode<GridCell> {
+ USING_FAST_MALLOC(GridCell);
+ friend class WTF::DoublyLinkedListNode<GridCell>;
+
+ public:
+ GridCell(size_t row, size_t column) : row_(row), column_(column) {}
+
+ size_t Index(GridTrackSizingDirection direction) const {
+ return direction == kForRows ? row_ : column_;
+ }
+
+ void AppendItem(LayoutBox& item) { items_.push_back(&item); }
+
+ const GridItemList& Items() const { return items_; }
+
+ // DoublyLinkedListNode classes must provide a next_ and prev_
+ // pointers to the DoublyLinkedList class so that it could perform
+ // the list operations. In the case of GridCells we need them to
+ // be shared by two lists the row and the column. This means that
+ // we need to maintain 4 separate pointers. In order to accomodate
+ // this in the DoublyLinkedList model, we must set the proper
+ // traversal mode (navigation by rows or columns) before any
+ // operation with a GridCell involving the use of the next_/prev_
+ // pointers.
+ // TODO(svillar): we could probably use DoublyLinkedLists just for
+ // one axis, this will remove the need for this and some other
+ // clumsy things like different behaviours in ~GridTrack() for
+ // each axis.
+ void SetTraversalMode(GridTrackSizingDirection);
+ GridTrackSizingDirection TraversalMode() const { return direction_; }
+
+ // Use this ONLY for traversals. If your code performs any
+ // modification in the list of cells while traversing then this
+ // might not work as expected and you should use
+ // SetTraversalMode()+Next() instead.
+ GridCell* NextInDirection(GridTrackSizingDirection) const;
+
+ private:
+ GridCell* prev_{nullptr};
+ GridCell* next_{nullptr};
+ GridCell* prev_ortho_{nullptr};
+ GridCell* next_ortho_{nullptr};
+
+ GridTrackSizingDirection direction_{kForColumns};
+ GridItemList items_;
+ size_t row_;
+ size_t column_;
+ };
+
+ // This class represents a track (column or row) of the grid. Each
+ // GridTrack will be part of a DLL stored in the ListGrid class,
+ // either rows_ or columns_. GridTrack's are never empty, i.e., they
+ // are only created whenever an item spans through them. Each
+ // GridTrack keeps a sorted list of the cells containing grid items
+ // in that particular track. The list of cells is ordered by the
+ // index of the cell in the orthogonal direction, i.e., the list of
+ // cells in a GridTrack representing a column will be sorted by
+ // their row index.
+ class CORE_EXPORT GridTrack final : public DoublyLinkedListNode<GridTrack> {
+ USING_FAST_MALLOC(GridTrack);
+ friend class WTF::DoublyLinkedListNode<GridTrack>;
+
+ public:
+ GridTrack(size_t index, GridTrackSizingDirection direction)
+ : index_(index), direction_(direction) {}
+
+ size_t Index() const { return index_; }
+ DoublyLinkedList<GridCell>::AddResult Insert(GridCell*);
+ DoublyLinkedList<GridCell>::AddResult InsertAfter(
+ GridCell* cell,
+ GridCell* insertion_point);
+ DoublyLinkedList<GridCell>::AddResult Insert(LayoutBox&, const GridSpan&);
+ GridCell* Find(size_t cell_index) const;
+
+ const DoublyLinkedList<GridCell>& Cells() const { return cells_; }
+
+ ~GridTrack();
+
+ private:
+ DoublyLinkedList<GridCell> cells_;
+ size_t index_;
+ GridTrackSizingDirection direction_;
+
+ GridTrack* prev_;
+ GridTrack* next_;
+ };
private:
- friend class VectorGridIterator;
+ friend class ListGridIterator;
- void EnsureGridSize(size_t maximum_row_size,
- size_t maximum_column_size) override;
+ // Returns a pointer to the first track.
+ GridTrack* InsertTracks(DoublyLinkedList<GridTrack>&,
+ const GridSpan&,
+ GridTrackSizingDirection);
+
+ void ClearGridDataStructure() override;
+ void ConsolidateGridDataStructure() override {}
- void ClearGridDataStructure() override { matrix_.resize(0); };
- void ConsolidateGridDataStructure() override { matrix_.ShrinkToFit(); }
+ const DoublyLinkedList<GridTrack>& Tracks(
+ GridTrackSizingDirection direction) const {
+ return direction == kForRows ? rows_ : columns_;
+ }
std::unique_ptr<GridIterator> CreateIterator(
GridTrackSizingDirection,
size_t fixed_track_index,
size_t varying_track_index = 0) const override;
- GridAsMatrix matrix_;
+ size_t num_rows_{0};
+ size_t num_columns_{0};
+
+ DoublyLinkedList<GridTrack> columns_;
+ DoublyLinkedList<GridTrack> rows_;
};
-class VectorGridIterator final : public Grid::GridIterator {
+class ListGridIterator final : public Grid::GridIterator {
public:
- VectorGridIterator(const VectorGrid&,
- GridTrackSizingDirection,
- size_t fixed_track_span,
- size_t varying_track_span = 0);
+ ListGridIterator(const ListGrid& grid,
+ GridTrackSizingDirection,
+ size_t fixed_track_index,
+ size_t varying_track_index = 0);
LayoutBox* NextGridItem() override;
std::unique_ptr<GridArea> NextEmptyGridArea(
@@ -175,10 +285,9 @@ class VectorGridIterator final : public Grid::GridIterator {
size_t varying_track_span) override;
private:
- bool CheckEmptyCells(size_t row_span, size_t column_span) const;
-
- const GridAsMatrix& matrix_;
- DISALLOW_COPY_AND_ASSIGN(VectorGridIterator);
+ const ListGrid& grid_;
+ ListGrid::GridCell* cell_node_{nullptr};
+ DISALLOW_COPY_AND_ASSIGN(ListGridIterator);
};
} // 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
new file mode 100644
index 00000000000..65bdebf1006
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/grid_test.cc
@@ -0,0 +1,335 @@
+// 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/grid.h"
+#include "third_party/blink/renderer/core/layout/layout_grid.h"
+
+#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
+
+namespace blink {
+
+namespace {
+
+class GridTest : public RenderingTest {
+ protected:
+ LayoutGrid* GetGridByElementId(const char* id) {
+ return ToLayoutGrid(GetLayoutObjectByElementId(id));
+ }
+};
+
+TEST_F(GridTest, EmptyGrid) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ .grid { display: grid; }
+ </style>
+ <div id=target class=grid>
+ </div>
+ )HTML");
+ auto* layout_grid = GetGridByElementId("target");
+ auto* grid = layout_grid->InternalGrid();
+ ASSERT_NE(grid, nullptr);
+
+ EXPECT_EQ(0u, grid->NumTracks(kForRows));
+ EXPECT_EQ(0u, grid->NumTracks(kForColumns));
+
+ EXPECT_FALSE(grid->HasGridItems());
+
+ EXPECT_EQ(0, grid->SmallestTrackStart(kForRows));
+ EXPECT_EQ(0, grid->SmallestTrackStart(kForColumns));
+
+ EXPECT_EQ(0u, grid->AutoRepeatTracks(kForRows));
+ EXPECT_EQ(0u, grid->AutoRepeatTracks(kForColumns));
+ EXPECT_FALSE(grid->HasAutoRepeatEmptyTracks(kForRows));
+ EXPECT_FALSE(grid->HasAutoRepeatEmptyTracks(kForColumns));
+}
+
+TEST_F(GridTest, SingleChild) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ .grid { display: grid; }
+ </style>
+ <div id=target class=grid>
+ <div id=child></div>
+ </div>
+ )HTML");
+ auto* layout_grid = GetGridByElementId("target");
+ auto* grid = layout_grid->InternalGrid();
+ ASSERT_NE(grid, nullptr);
+ auto* child = ToLayoutBox(GetLayoutObjectByElementId("child"));
+ ASSERT_NE(child, nullptr);
+
+ EXPECT_EQ(1u, grid->NumTracks(kForRows));
+ EXPECT_EQ(1u, grid->NumTracks(kForColumns));
+
+ EXPECT_TRUE(grid->HasGridItems());
+
+ EXPECT_EQ(0, grid->SmallestTrackStart(kForRows));
+ EXPECT_EQ(0, grid->SmallestTrackStart(kForColumns));
+
+ auto area = grid->GridItemArea(*child);
+ EXPECT_EQ(0u, area.columns.StartLine());
+ EXPECT_EQ(1u, area.columns.EndLine());
+ EXPECT_EQ(0u, area.rows.StartLine());
+ EXPECT_EQ(1u, area.rows.EndLine());
+}
+
+TEST_F(GridTest, OverlappingChildren) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ .grid { display: grid; grid-template: repeat(3, 20px) / repeat(3, 20px); }
+ #child1 { grid-row: 1 / 3; grid-column: 1 / 3 }
+ #child2 { grid-row: 1 / 3; grid-column: 2 / 4 }
+ #child3 { grid-row: 2 / 4; grid-column: 1 / 3 }
+ #child4 { grid-row: 2 / 4; grid-column: 2 / 4 }
+ </style>
+ <div id=target class=grid>
+ <div id=child1></div>
+ <div id=child2></div>
+ <div id=child3></div>
+ <div id=child4></div>
+ </div>
+ )HTML");
+ auto* layout_grid = GetGridByElementId("target");
+ auto* grid = layout_grid->InternalGrid();
+ ASSERT_NE(grid, nullptr);
+
+ size_t num_rows = grid->NumTracks(kForRows);
+ size_t num_cols = grid->NumTracks(kForColumns);
+ EXPECT_EQ(3u, num_rows);
+ EXPECT_EQ(3u, num_cols);
+
+ EXPECT_TRUE(grid->HasGridItems());
+
+ size_t index = 0;
+ Vector<size_t> expected_items_per_cell = {1, 2, 1, 2, 4, 2, 1, 2, 1};
+ for (size_t row = 0; row < num_rows; ++row) {
+ for (size_t col = 0; col < num_cols; ++col)
+ EXPECT_EQ(expected_items_per_cell[index++], grid->Cell(row, col).size());
+ }
+}
+
+TEST_F(GridTest, PartiallyOverlappingChildren) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ .grid { display: grid; grid-template: repeat(1, 20px) / repeat(3, 20px); }
+ #child1 { grid-row: 1; grid-column: 1; }
+ #child2 { grid-row: 1; grid-column: 3; }
+ #child3 { grid-row: 1; grid-column: 1 / 3 }
+ </style>
+ <div id=target class=grid>
+ <div id=child1></div>
+ <div id=child2></div>
+ <div id=child3></div>
+ </div>
+ )HTML");
+ auto* layout_grid = GetGridByElementId("target");
+ auto* grid = layout_grid->InternalGrid();
+ ASSERT_NE(grid, nullptr);
+
+ size_t num_rows = grid->NumTracks(kForRows);
+ size_t num_cols = grid->NumTracks(kForColumns);
+ EXPECT_EQ(1u, num_rows);
+ EXPECT_EQ(3u, num_cols);
+
+ EXPECT_TRUE(grid->HasGridItems());
+
+ size_t index = 0;
+ Vector<size_t> expected_items_per_cell = {2, 1, 1};
+ for (size_t col = 0; col < num_cols; ++col)
+ EXPECT_EQ(expected_items_per_cell[index++], grid->Cell(0, col).size());
+}
+
+TEST_F(GridTest, IntrinsicGrid) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ .grid { display: grid; grid-template-rows: repeat(2, 10px); }
+ #child1 { grid-row: -1 / -5; }
+ #child2 { grid-row: 3 / span 4; }
+ </style>
+ <div id=target class=grid>
+ <div id=child1></div>
+ <div id=child2></div>
+ </div>
+ )HTML");
+ auto* layout_grid = GetGridByElementId("target");
+ auto* grid = layout_grid->InternalGrid();
+ ASSERT_NE(grid, nullptr);
+ auto* child1 = ToLayoutBox(GetLayoutObjectByElementId("child1"));
+ ASSERT_NE(child1, nullptr);
+ auto* child2 = ToLayoutBox(GetLayoutObjectByElementId("child2"));
+ ASSERT_NE(child2, nullptr);
+
+ EXPECT_EQ(8u, grid->NumTracks(kForRows));
+ EXPECT_EQ(1u, grid->NumTracks(kForColumns));
+
+ EXPECT_TRUE(grid->HasGridItems());
+
+ EXPECT_EQ(-2, grid->SmallestTrackStart(kForRows));
+ EXPECT_EQ(0, grid->SmallestTrackStart(kForColumns));
+
+ auto area = grid->GridItemArea(*child1);
+ EXPECT_EQ(0u, area.columns.StartLine());
+ EXPECT_EQ(1u, area.columns.EndLine());
+ EXPECT_EQ(0u, area.rows.StartLine());
+ EXPECT_EQ(4u, area.rows.EndLine());
+
+ area = grid->GridItemArea(*child2);
+ EXPECT_EQ(0u, area.columns.StartLine());
+ EXPECT_EQ(1u, area.columns.EndLine());
+ EXPECT_EQ(4u, area.rows.StartLine());
+ EXPECT_EQ(8u, area.rows.EndLine());
+}
+
+TEST_F(GridTest, AutoFit) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ .grid { display: grid; width: 100px; grid-template-columns: repeat(auto-fit, 10px); }
+ #child { grid-column: 2 / 6; }
+ #child2 { grid-column: 9; }
+ </style>
+ <div id=target class=grid>
+ <div id=child></div>
+ <div id=child2></div>
+ </div>
+ )HTML");
+ auto* layout_grid = GetGridByElementId("target");
+ auto* grid = layout_grid->InternalGrid();
+ ASSERT_NE(grid, nullptr);
+
+ EXPECT_EQ(1u, grid->NumTracks(kForRows));
+ EXPECT_EQ(10u, grid->NumTracks(kForColumns));
+
+ EXPECT_TRUE(grid->HasGridItems());
+
+ EXPECT_EQ(0u, grid->AutoRepeatTracks(kForRows));
+ EXPECT_EQ(10u, grid->AutoRepeatTracks(kForColumns));
+ EXPECT_FALSE(grid->HasAutoRepeatEmptyTracks(kForRows));
+ EXPECT_TRUE(grid->HasAutoRepeatEmptyTracks(kForColumns));
+
+ auto* empty_tracks = grid->AutoRepeatEmptyTracks(kForColumns);
+ ASSERT_NE(empty_tracks, nullptr);
+ ASSERT_EQ(empty_tracks->size(), 5u);
+ Vector<size_t> expected_empty_tracks = {0, 5, 6, 7, 9};
+ size_t index = 0;
+ for (auto track : *empty_tracks) {
+ EXPECT_EQ(expected_empty_tracks[index++], track);
+ EXPECT_TRUE(grid->IsEmptyAutoRepeatTrack(kForColumns, track));
+ }
+}
+
+TEST_F(GridTest, AutoFill) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ .grid { display: grid; width: 100px; grid-template-columns: repeat(auto-fill, 10px); }
+ #child { grid-column: 2 / 6; }
+ #child2 { grid-column: 9; }
+ </style>
+ <div id=target class=grid>
+ <div id=child></div>
+ <div id=child2></div>
+ </div>
+ )HTML");
+ auto* layout_grid = GetGridByElementId("target");
+ auto* grid = layout_grid->InternalGrid();
+ ASSERT_NE(grid, nullptr);
+
+ EXPECT_EQ(1u, grid->NumTracks(kForRows));
+ EXPECT_EQ(10u, grid->NumTracks(kForColumns));
+
+ EXPECT_TRUE(grid->HasGridItems());
+
+ EXPECT_EQ(0u, grid->AutoRepeatTracks(kForRows));
+ EXPECT_EQ(10u, grid->AutoRepeatTracks(kForColumns));
+ EXPECT_FALSE(grid->HasAutoRepeatEmptyTracks(kForRows));
+ EXPECT_FALSE(grid->HasAutoRepeatEmptyTracks(kForColumns));
+}
+
+TEST_F(GridTest, AutoPositionedItems) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ .grid { display: grid; grid-template-rows: repeat(3, 10px); grid-auto-flow: column }
+ .vertical { writing-mode: vertical-rl}
+ </style>
+ <div id=target class=grid>
+ <div></div>
+ <div class=vertical></div>
+ <div></div>
+ <div></div>
+ </div>
+ )HTML");
+ auto* layout_grid = GetGridByElementId("target");
+ auto* grid = layout_grid->InternalGrid();
+ ASSERT_NE(grid, nullptr);
+
+ EXPECT_EQ(3u, grid->NumTracks(kForRows));
+ EXPECT_EQ(2u, grid->NumTracks(kForColumns));
+
+ EXPECT_TRUE(grid->HasGridItems());
+ EXPECT_FALSE(grid->NeedsItemsPlacement());
+}
+
+TEST_F(GridTest, ExplicitlyPositionedChild) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ .grid { display: grid; }
+ #child { grid-row: 1; grid-column: 2 / span 3; }
+ </style>
+ <div id=target class=grid>
+ <div id=child></div>
+ </div>
+ )HTML");
+ auto* layout_grid = GetGridByElementId("target");
+ auto* grid = layout_grid->InternalGrid();
+ ASSERT_NE(grid, nullptr);
+ auto* child = ToLayoutBox(GetLayoutObjectByElementId("child"));
+ ASSERT_NE(child, nullptr);
+
+ EXPECT_EQ(1u, grid->NumTracks(kForRows));
+ EXPECT_EQ(4u, grid->NumTracks(kForColumns));
+
+ EXPECT_TRUE(grid->HasGridItems());
+
+ EXPECT_EQ(0, grid->SmallestTrackStart(kForRows));
+ EXPECT_EQ(0, grid->SmallestTrackStart(kForColumns));
+
+ auto area = grid->GridItemArea(*child);
+ EXPECT_EQ(1u, area.columns.StartLine());
+ EXPECT_EQ(4u, area.columns.EndLine());
+ EXPECT_EQ(0u, area.rows.StartLine());
+ EXPECT_EQ(1u, area.rows.EndLine());
+
+ for (auto row : area.rows) {
+ for (auto column : area.columns) {
+ auto& cell = grid->Cell(row, column);
+ EXPECT_EQ(1u, cell.size());
+ }
+ }
+}
+
+TEST_F(GridTest, CellInsert) {
+ auto track = base::WrapUnique(new ListGrid::GridTrack(0, kForColumns));
+ auto* cell = new ListGrid::GridCell(0, 0);
+
+ auto result = track->Insert(cell);
+ EXPECT_TRUE(result.is_new_entry);
+ EXPECT_EQ(cell, result.node);
+
+ auto* cell2 = new ListGrid::GridCell(1, 0);
+ result = track->Insert(cell2);
+ EXPECT_TRUE(result.is_new_entry);
+ EXPECT_EQ(cell2, result.node);
+
+ result = track->InsertAfter(cell2, cell);
+ EXPECT_FALSE(result.is_new_entry);
+ EXPECT_EQ(cell2, result.node);
+
+ auto* cell3 = new ListGrid::GridCell(2, 0);
+ result = track->InsertAfter(cell3, cell2);
+ EXPECT_TRUE(result.is_new_entry);
+ EXPECT_EQ(cell3, result.node);
+}
+
+} // anonymous namespace
+
+} // 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 b92100e3b67..cbc3c20d5b0 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
@@ -227,10 +227,12 @@ LayoutUnit GridTrackSizingAlgorithm::GridAreaBreadthForChild(
const Vector<GridTrack>& all_tracks = Tracks(direction);
const GridSpan& span = grid_.GridItemSpan(child, direction);
LayoutUnit grid_area_breadth;
- for (const auto& track_position : span) {
+ for (const auto& track_position : span)
grid_area_breadth += all_tracks[track_position].BaseSize();
- if (add_content_alignment_offset)
- grid_area_breadth += layout_grid_->GridItemOffset(direction);
+
+ if (add_content_alignment_offset) {
+ grid_area_breadth +=
+ (span.IntegerSpan() - 1) * layout_grid_->GridItemOffset(direction);
}
grid_area_breadth +=
@@ -249,6 +251,12 @@ bool GridTrackSizingAlgorithm::IsIntrinsicSizedGridArea(const LayoutBox& child,
GridTrackSize track_size = RawGridTrackSize(direction, track_position);
// We consider fr units as 'auto' for the min sizing function.
// TODO(jfernandez): https://github.com/w3c/csswg-drafts/issues/2611
+ //
+ // The use of AvailableSize function may imply different results
+ // for the same item when assuming indefinite or definite size
+ // constraints depending on the phase we evaluate the item's
+ // baseline participation.
+ // TODO(jfernandez): https://github.com/w3c/csswg-drafts/issues/3046
if (track_size.IsContentSized() || track_size.IsFitContent() ||
track_size.MinTrackBreadth().IsFlex() ||
(track_size.MaxTrackBreadth().IsFlex() && !AvailableSpace(direction)))
@@ -786,15 +794,7 @@ GridTrackSize GridTrackSizingAlgorithm::RawGridTrackSize(
bool GridTrackSizingAlgorithm::IsRelativeGridLengthAsAuto(
const GridLength& length,
GridTrackSizingDirection direction) const {
- if (!length.HasPercentage())
- return false;
- // TODO(svillar): we should remove the second check later. We need it
- // because during the second iteration of the algorithm we set definite
- // sizes in the grid container so percents would not resolve properly (it
- // would think that the height is definite when it is not).
- return !AvailableSpace(direction) ||
- (direction == kForRows &&
- !layout_grid_->CachedHasDefiniteLogicalHeight());
+ return length.HasPercentage() && !AvailableSpace(direction);
}
bool GridTrackSizingAlgorithm::IsRelativeSizedTrackAsAuto(
@@ -887,8 +887,11 @@ void GridTrackSizingAlgorithm::InitializeTrackSizes() {
DCHECK(content_sized_tracks_index_.IsEmpty());
DCHECK(flexible_sized_tracks_index_.IsEmpty());
DCHECK(auto_sized_tracks_for_stretch_index_.IsEmpty());
+ DCHECK(!has_percent_sized_rows_indefinite_height_);
Vector<GridTrack>& track_list = Tracks(direction_);
bool has_definite_free_space = !!AvailableSpace();
+ bool indefinite_height =
+ direction_ == kForRows && !layout_grid_->CachedHasDefiniteLogicalHeight();
size_t num_tracks = track_list.size();
for (size_t i = 0; i < num_tracks; ++i) {
GridTrackSize track_size = GetGridTrackSize(direction_, i);
@@ -911,6 +914,13 @@ void GridTrackSizingAlgorithm::InitializeTrackSizes() {
flexible_sized_tracks_index_.push_back(i);
if (track_size.HasAutoMaxTrackBreadth() && !track_size.IsFitContent())
auto_sized_tracks_for_stretch_index_.push_back(i);
+
+ if (!has_percent_sized_rows_indefinite_height_ && indefinite_height) {
+ GridTrackSize raw_track_size = RawGridTrackSize(direction_, i);
+ if (raw_track_size.MinTrackBreadth().HasPercentage() ||
+ raw_track_size.MaxTrackBreadth().HasPercentage())
+ has_percent_sized_rows_indefinite_height_ = true;
+ }
}
}
@@ -1566,6 +1576,7 @@ void GridTrackSizingAlgorithm::Setup(
content_sized_tracks_index_.Shrink(0);
flexible_sized_tracks_index_.Shrink(0);
auto_sized_tracks_for_stretch_index_.Shrink(0);
+ has_percent_sized_rows_indefinite_height_ = false;
if (available_space) {
LayoutUnit gutters_size = layout_grid_->GuttersSize(
@@ -1582,8 +1593,6 @@ void GridTrackSizingAlgorithm::Setup(
}
void GridTrackSizingAlgorithm::ComputeBaselineAlignmentContext() {
- if (sizing_state_ > kRowSizingFirstIteration)
- return;
GridAxis axis = GridAxisForDirection(direction_);
baseline_alignment_.Clear(axis);
baseline_alignment_.SetBlockFlow(layout_grid_->StyleRef().GetWritingMode());
@@ -1641,6 +1650,7 @@ void GridTrackSizingAlgorithm::Reset() {
content_sized_tracks_index_.Shrink(0);
flexible_sized_tracks_index_.Shrink(0);
auto_sized_tracks_for_stretch_index_.Shrink(0);
+ has_percent_sized_rows_indefinite_height_ = false;
SetAvailableSpace(kForRows, base::nullopt);
SetAvailableSpace(kForColumns, base::nullopt);
}
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 5127dd2cec0..36ae436b67d 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
@@ -117,6 +117,12 @@ class GridTrackSizingAlgorithm final {
bool TracksAreWiderThanMinTrackBreadth() const;
#endif
+ LayoutUnit ComputeTrackBasedSize() const;
+
+ bool HasAnyPercentSizedRowsIndefiniteHeight() const {
+ return has_percent_sized_rows_indefinite_height_;
+ }
+
private:
base::Optional<LayoutUnit> AvailableSpace() const;
bool IsRelativeGridLengthAsAuto(const GridLength&,
@@ -127,7 +133,6 @@ class GridTrackSizingAlgorithm final {
size_t translated_index) const;
GridTrackSize RawGridTrackSize(GridTrackSizingDirection,
size_t translated_index) const;
- LayoutUnit ComputeTrackBasedSize() const;
// Helper methods for step 1. initializeTrackSizes().
LayoutUnit InitialBaseSize(const GridTrackSize&) const;
@@ -195,6 +200,7 @@ class GridTrackSizingAlgorithm final {
// Data.
bool WasSetup() const { return !!strategy_; }
bool needs_setup_{true};
+ bool has_percent_sized_rows_indefinite_height_{false};
base::Optional<LayoutUnit> available_space_columns_;
base::Optional<LayoutUnit> available_space_rows_;
diff --git a/chromium/third_party/blink/renderer/core/layout/hit_test_request.h b/chromium/third_party/blink/renderer/core/layout/hit_test_request.h
index e7626ce8bb2..0c3e6e9cd77 100644
--- a/chromium/third_party/blink/renderer/core/layout/hit_test_request.h
+++ b/chromium/third_party/blink/renderer/core/layout/hit_test_request.h
@@ -52,6 +52,7 @@ class HitTestRequest {
// testing after a hit has been found.
kPenetratingList = 1 << 12,
kAvoidCache = 1 << 13,
+ kIgnoreZeroOpacityObjects = 1 << 14,
};
typedef unsigned HitTestRequestType;
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 c45642f7473..b9b95b5527d 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
@@ -39,9 +39,9 @@
#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_image.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"
-#include "third_party/blink/renderer/platform/scroll/scrollbar.h"
namespace blink {
@@ -238,7 +238,7 @@ String HitTestResult::Title(TextDirection& dir) const {
String title = ToElement(title_node)->title();
if (!title.IsNull()) {
if (LayoutObject* layout_object = title_node->GetLayoutObject())
- dir = layout_object->Style()->Direction();
+ dir = layout_object->StyleRef().Direction();
return title;
}
}
diff --git a/chromium/third_party/blink/renderer/core/layout/intersection_geometry.cc b/chromium/third_party/blink/renderer/core/layout/intersection_geometry.cc
index 2efb1a9cfef..33844bd0a67 100644
--- a/chromium/third_party/blink/renderer/core/layout/intersection_geometry.cc
+++ b/chromium/third_party/blink/renderer/core/layout/intersection_geometry.cc
@@ -9,6 +9,7 @@
#include "third_party/blink/renderer/core/frame/settings.h"
#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_inline.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"
@@ -104,9 +105,11 @@ void IntersectionGeometry::InitializeGeometry() {
}
void IntersectionGeometry::InitializeTargetRect() {
- if (target_->IsBoxModelObject()) {
+ if (target_->IsBox()) {
target_rect_ =
LayoutRect(ToLayoutBoxModelObject(target_)->BorderBoundingBox());
+ } else if (target_->IsLayoutInline()) {
+ target_rect_ = ToLayoutInline(target_)->LinesBoundingBox();
} else {
target_rect_ = ToLayoutText(target_)->LinesBoundingBox();
}
@@ -124,7 +127,7 @@ void IntersectionGeometry::InitializeRootRect() {
// we can zoom out to fit the entire element width.
root_rect_ = ToLayoutView(root_)->OverflowClipRect(LayoutPoint());
} else if (root_->IsBox() && root_->HasOverflowClip()) {
- root_rect_ = LayoutRect(ToLayoutBox(root_)->ContentBoxRect());
+ root_rect_ = LayoutRect(ToLayoutBox(root_)->PhysicalContentBoxRect());
} else {
root_rect_ = LayoutRect(ToLayoutBoxModelObject(root_)->BorderBoundingBox());
}
diff --git a/chromium/third_party/blink/renderer/core/layout/jank_tracker.cc b/chromium/third_party/blink/renderer/core/layout/jank_tracker.cc
index 24c209e7954..3d5b32575d3 100644
--- a/chromium/third_party/blink/renderer/core/layout/jank_tracker.cc
+++ b/chromium/third_party/blink/renderer/core/layout/jank_tracker.cc
@@ -15,8 +15,9 @@
namespace blink {
-static constexpr TimeDelta kTimerDelay = TimeDelta::FromSeconds(3);
+static constexpr TimeDelta kTimerDelay = TimeDelta::FromMilliseconds(500);
static const float kRegionGranularitySteps = 60.0;
+static const float kMovementThreshold = 3.0; // CSS pixels.
static FloatPoint LogicalStart(const FloatRect& rect,
const LayoutObject& object) {
@@ -41,13 +42,44 @@ static float RegionGranularityScale(const IntRect& viewport) {
std::min(viewport.Height(), viewport.Width());
}
+static 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 LayoutRect& rect,
+ float granularity_scale) {
+ return rect.Width().ToFloat() * granularity_scale < 0.5 ||
+ rect.Height().ToFloat() * granularity_scale < 0.5;
+}
+
+#ifdef TRACE_JANK_REGIONS
+static void RegionToTracedValue(const Region& region,
+ double granularity_scale,
+ TracedValue& value) {
+ value.BeginArray("region_rects");
+ for (const IntRect& rect : region.Rects()) {
+ value.BeginArray();
+ value.PushInteger(clampTo<int>(roundf(rect.X() / granularity_scale)));
+ value.PushInteger(clampTo<int>(roundf(rect.Y() / granularity_scale)));
+ value.PushInteger(clampTo<int>(roundf(rect.Width() / granularity_scale)));
+ value.PushInteger(clampTo<int>(roundf(rect.Height() / granularity_scale)));
+ value.EndArray();
+ }
+ value.EndArray();
+}
+#endif // TRACE_JANK_REGIONS
+
JankTracker::JankTracker(LocalFrameView* frame_view)
: frame_view_(frame_view),
score_(0.0),
timer_(frame_view->GetFrame().GetTaskRunner(TaskType::kInternalDefault),
this,
&JankTracker::TimerFired),
- has_fired_(false),
max_distance_(0.0) {}
void JankTracker::NotifyObjectPrePaint(const LayoutObject& object,
@@ -60,8 +92,16 @@ void JankTracker::NotifyObjectPrePaint(const LayoutObject& object,
if (old_visual_rect.IsEmpty() || new_visual_rect.IsEmpty())
return;
- if (LogicalStart(FloatRect(old_visual_rect), object) ==
- LogicalStart(FloatRect(new_visual_rect), object))
+ if (EqualWithinMovementThreshold(
+ LogicalStart(FloatRect(old_visual_rect), object),
+ LogicalStart(FloatRect(new_visual_rect), object), object))
+ return;
+
+ IntRect viewport = frame_view_->GetScrollableArea()->VisibleContentRect();
+ float scale = RegionGranularityScale(viewport);
+
+ if (SmallerThanRegionGranularity(old_visual_rect, scale) &&
+ SmallerThanRegionGranularity(new_visual_rect, scale))
return;
const auto* local_transform = painting_layer.GetLayoutObject()
@@ -87,7 +127,6 @@ void JankTracker::NotifyObjectPrePaint(const LayoutObject& object,
// a better idea of how to aggregate multiple scores for a page.
// See review thread of http://crrev.com/c/1046155 for more details.
- IntRect viewport = frame_view_->GetScrollableArea()->VisibleContentRect();
if (!old_visual_rect_abs.Intersects(viewport) &&
!new_visual_rect_abs.Intersects(viewport))
return;
@@ -106,7 +145,6 @@ void JankTracker::NotifyObjectPrePaint(const LayoutObject& object,
IntRect visible_new_visual_rect = RoundedIntRect(new_visual_rect_abs);
visible_new_visual_rect.Intersect(viewport);
- float scale = RegionGranularityScale(viewport);
visible_old_visual_rect.Scale(scale);
visible_new_visual_rect.Scale(scale);
@@ -115,17 +153,12 @@ void JankTracker::NotifyObjectPrePaint(const LayoutObject& object,
}
void JankTracker::NotifyPrePaintFinished() {
- if (!IsActive())
- return;
-
- if (region_.IsEmpty()) {
- if (!timer_.IsActive())
- timer_.StartOneShot(kTimerDelay, FROM_HERE);
+ if (!IsActive() || region_.IsEmpty())
return;
- }
IntRect viewport = frame_view_->GetScrollableArea()->VisibleContentRect();
- viewport.Scale(RegionGranularityScale(viewport));
+ double granularity_scale = RegionGranularityScale(viewport);
+ viewport.Scale(granularity_scale);
double viewport_area = double(viewport.Width()) * double(viewport.Height());
double jank_fraction = region_.Area() / viewport_area;
@@ -134,10 +167,27 @@ void JankTracker::NotifyPrePaintFinished() {
DVLOG(1) << "viewport " << (jank_fraction * 100)
<< "% janked, raising score to " << score_;
- TRACE_EVENT_INSTANT1("loading", "FrameLayoutJank", TRACE_EVENT_SCOPE_THREAD,
- "viewportFraction", jank_fraction);
+ TRACE_EVENT_INSTANT2("loading", "FrameLayoutJank", TRACE_EVENT_SCOPE_THREAD,
+ "data",
+ PerFrameTraceData(jank_fraction, granularity_scale),
+ "frame", ToTraceValue(&frame_view_->GetFrame()));
region_ = Region();
+}
+
+void JankTracker::NotifyInput(const WebInputEvent& event) {
+ bool event_is_meaningful =
+ event.GetType() == WebInputEvent::kMouseDown ||
+ event.GetType() == WebInputEvent::kKeyDown ||
+ event.GetType() == WebInputEvent::kRawKeyDown ||
+ // We need to explicitly include tap, as if there are no listeners, we
+ // won't receive the pointer events.
+ event.GetType() == WebInputEvent::kGestureTap ||
+ // Ignore kPointerDown, since it might be a scroll.
+ event.GetType() == WebInputEvent::kPointerUp;
+
+ if (!event_is_meaningful)
+ return;
// This cancels any previously scheduled task from the same timer.
timer_.StartOneShot(kTimerDelay, FROM_HERE);
@@ -149,33 +199,29 @@ bool JankTracker::IsActive() {
if (frame_view_->GetFrame().GetChromeClient().IsSVGImageChromeClient())
return false;
- if (has_fired_)
+ if (timer_.IsActive())
return false;
+
return true;
}
-std::unique_ptr<TracedValue> JankTracker::TraceData() const {
+std::unique_ptr<TracedValue> JankTracker::PerFrameTraceData(
+ double jank_fraction,
+ double granularity_scale) const {
std::unique_ptr<TracedValue> value = TracedValue::Create();
- value->SetDouble("score", score_);
- value->SetDouble("maxDistance", max_distance_);
+ value->SetDouble("jank_fraction", jank_fraction);
+ value->SetDouble("cumulative_score", score_);
+ value->SetDouble("max_distance", max_distance_);
+
+#ifdef TRACE_JANK_REGIONS
+ // Jank regions can be included in trace event by defining TRACE_JANK_REGIONS
+ // at the top of this file. This is useful for debugging and visualizing, but
+ // might impact performance negatively.
+ RegionToTracedValue(region_, granularity_scale, *value);
+#endif
+
+ value->SetBoolean("is_main_frame", frame_view_->GetFrame().IsMainFrame());
return value;
}
-void JankTracker::TimerFired(TimerBase* timer) {
- has_fired_ = true;
-
- // TODO(skobes): Aggregate jank scores from iframes.
- if (!frame_view_->GetFrame().IsMainFrame())
- return;
-
- DVLOG(1) << "final jank score for "
- << frame_view_->GetFrame().DomWindow()->location()->toString()
- << " is " << score_ << " with max move distance of "
- << max_distance_;
-
- TRACE_EVENT_INSTANT2("loading", "TotalLayoutJank", TRACE_EVENT_SCOPE_THREAD,
- "data", TraceData(), "frame",
- ToTraceValue(&frame_view_->GetFrame()));
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/jank_tracker.h b/chromium/third_party/blink/renderer/core/layout/jank_tracker.h
index 171bc0ca121..602b5feabb1 100644
--- a/chromium/third_party/blink/renderer/core/layout/jank_tracker.h
+++ b/chromium/third_party/blink/renderer/core/layout/jank_tracker.h
@@ -17,6 +17,7 @@ class LayoutRect;
class LocalFrameView;
class PaintLayer;
class TracedValue;
+class WebInputEvent;
// Tracks "jank" from layout objects changing their visual location between
// animation frames.
@@ -30,14 +31,17 @@ class CORE_EXPORT JankTracker {
const LayoutRect& old_visual_rect,
const PaintLayer& painting_layer);
void NotifyPrePaintFinished();
+ void NotifyInput(const WebInputEvent&);
bool IsActive();
double Score() const { return score_; }
float MaxDistance() const { return max_distance_; }
void Dispose() { timer_.Stop(); }
private:
- void TimerFired(TimerBase*);
- std::unique_ptr<TracedValue> TraceData() const;
+ void TimerFired(TimerBase*) {}
+ std::unique_ptr<TracedValue> PerFrameTraceData(
+ double jank_fraction,
+ double granularity_scale) const;
// This owns us.
UntracedMember<LocalFrameView> frame_view_;
@@ -48,9 +52,8 @@ class CORE_EXPORT JankTracker {
// The per-frame jank region.
Region region_;
- // Timer that fires the first time we've had no layout jank for a few seconds.
+ // Tracks the short period after an input event during which we ignore jank.
TaskRunnerTimer<JankTracker> timer_;
- bool has_fired_;
// The maximum distance any layout object has moved in any frame.
float max_distance_;
diff --git a/chromium/third_party/blink/renderer/core/layout/jank_tracker_test.cc b/chromium/third_party/blink/renderer/core/layout/jank_tracker_test.cc
index dcc0fcd4f3f..a93a32dabf4 100644
--- a/chromium/third_party/blink/renderer/core/layout/jank_tracker_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/jank_tracker_test.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/layout/jank_tracker.h"
+#include "third_party/blink/public/platform/web_mouse_event.h"
#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
namespace blink {
@@ -12,6 +13,13 @@ class JankTrackerTest : public RenderingTest {
protected:
LocalFrameView& GetFrameView() { return *GetFrame().View(); }
JankTracker& GetJankTracker() { return GetFrameView().GetJankTracker(); }
+
+ void SimulateInput() {
+ GetJankTracker().NotifyInput(WebMouseEvent(
+ WebInputEvent::kMouseDown, WebFloatPoint(), WebFloatPoint(),
+ WebPointerProperties::Button::kLeft, 0,
+ WebInputEvent::Modifiers::kLeftButtonDown, CurrentTimeTicks()));
+ }
};
TEST_F(JankTrackerTest, SimpleBlockMovement) {
@@ -79,4 +87,45 @@ TEST_F(JankTrackerTest, RtlDistance) {
EXPECT_FLOAT_EQ(20.0, GetJankTracker().MaxDistance());
}
+TEST_F(JankTrackerTest, SmallMovementIgnored) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #j { position: relative; width: 300px; height: 100px; }
+ </style>
+ <div id='j'></div>
+ )HTML");
+ GetDocument().getElementById("j")->setAttribute(HTMLNames::styleAttr,
+ AtomicString("top: 2px"));
+ GetFrameView().UpdateAllLifecyclePhases();
+ EXPECT_EQ(0.0, GetJankTracker().Score());
+}
+
+TEST_F(JankTrackerTest, SmallMovementIgnoredWithZoom) {
+ GetDocument().GetFrame()->SetPageZoomFactor(2);
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #j { position: relative; width: 300px; height: 100px; }
+ </style>
+ <div id='j'></div>
+ )HTML");
+ GetDocument().getElementById("j")->setAttribute(HTMLNames::styleAttr,
+ AtomicString("top: 2px"));
+ GetFrameView().UpdateAllLifecyclePhases();
+ EXPECT_EQ(0.0, GetJankTracker().Score());
+}
+
+TEST_F(JankTrackerTest, IgnoreAfterInput) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #j { position: relative; width: 300px; height: 100px; }
+ </style>
+ <div id='j'></div>
+ )HTML");
+ GetDocument().getElementById("j")->setAttribute(HTMLNames::styleAttr,
+ AtomicString("top: 60px"));
+ SimulateInput();
+ GetFrameView().UpdateAllLifecyclePhases();
+ EXPECT_EQ(0.0, GetJankTracker().Score());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_analyzer.cc b/chromium/third_party/blink/renderer/core/layout/layout_analyzer.cc
index e5b6ef708dc..92ae9e1b00a 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_analyzer.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_analyzer.cc
@@ -68,7 +68,7 @@ void LayoutAnalyzer::Push(const LayoutObject& o) {
Increment(kLayoutObjectsThatAreTableCells);
if (o.IsFloating())
Increment(kLayoutObjectsThatAreFloating);
- if (o.Style()->SpecifiesColumns())
+ if (o.StyleRef().SpecifiesColumns())
Increment(kLayoutObjectsThatSpecifyColumns);
if (o.HasLayer())
Increment(kLayoutObjectsThatHaveALayer);
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 3ea1d5cb077..19bec29707e 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_block.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_block.cc
@@ -55,6 +55,7 @@
#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/layout/line/inline_text_box.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_constraint_space.h"
#include "third_party/blink/renderer/core/layout/text_autosizer.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/page/scrolling/root_scroller_controller.h"
@@ -71,6 +72,7 @@ namespace blink {
struct SameSizeAsLayoutBlock : public LayoutBox {
LayoutObjectChildList children;
+ scoped_refptr<const NGConstraintSpace> cached_constraint_space_;
uint32_t bitfields;
};
@@ -107,7 +109,8 @@ LayoutBlock::LayoutBlock(ContainerNode* node)
descendants_with_floats_marked_for_layout_(false),
has_positioned_objects_(false),
has_percent_height_descendants_(false),
- pagination_state_changed_(false) {
+ pagination_state_changed_(false),
+ is_legacy_initiated_out_of_flow_layout_(false) {
// LayoutBlockFlow calls setChildrenInline(true).
// By default, subclasses do not have inline children.
}
@@ -161,13 +164,13 @@ void LayoutBlock::StyleWillChange(StyleDifference diff,
if (old_style && Parent()) {
bool old_style_contains_fixed_position =
old_style->CanContainFixedPositionObjects(IsDocumentElement()) ||
- ShouldApplyPaintContainment();
+ ShouldApplyPaintContainment() || ShouldApplyLayoutContainment();
bool old_style_contains_absolute_position =
old_style_contains_fixed_position ||
old_style->CanContainAbsolutePositionObjects();
bool new_style_contains_fixed_position =
new_style.CanContainFixedPositionObjects(IsDocumentElement()) ||
- ShouldApplyPaintContainment();
+ ShouldApplyPaintContainment() || ShouldApplyLayoutContainment();
bool new_style_contains_absolute_position =
new_style_contains_fixed_position ||
new_style.CanContainAbsolutePositionObjects();
@@ -264,7 +267,7 @@ void LayoutBlock::StyleDidChange(StyleDifference diff,
SetCanContainFixedPositionObjects(
IsLayoutView() || IsSVGForeignObject() || IsTextControl() ||
new_style.CanContainFixedPositionObjects(IsDocumentElement()) ||
- ShouldApplyPaintContainment());
+ ShouldApplyPaintContainment() || ShouldApplyLayoutContainment());
// It's possible for our border/padding to change, but for the overall logical
// width or height of the block to end up being the same. We keep track of
@@ -287,10 +290,12 @@ void LayoutBlock::UpdateFromStyle() {
if (should_clip_overflow != HasOverflowClip()) {
if (!should_clip_overflow)
GetScrollableArea()->InvalidateAllStickyConstraints();
- SetMayNeedPaintInvalidationSubtree();
+ SetSubtreeShouldCheckForPaintInvalidation();
// The overflow clip paint property depends on whether overflow clip is
// present so we need to update paint properties if this changes.
SetNeedsPaintPropertyUpdate();
+ if (Layer())
+ Layer()->SetNeedsCompositingInputsUpdate();
}
SetHasOverflowClip(should_clip_overflow);
}
@@ -444,8 +449,8 @@ void LayoutBlock::UpdateLayout() {
if (HasControlClip() && overflow_)
ClearLayoutOverflow();
- InvalidateBackgroundObscurationStatus();
height_available_to_children_changed_ = false;
+ cached_constraint_space_ = nullptr;
}
bool LayoutBlock::WidthAvailableToChildrenHasChanged() {
@@ -462,7 +467,7 @@ bool LayoutBlock::WidthAvailableToChildrenHasChanged() {
// if we have percentage padding, which is rather non-obvious. That method
// returns true in other cases as well.
width_available_to_children_has_changed |=
- Style()->BoxSizing() == EBoxSizing::kBorderBox &&
+ StyleRef().BoxSizing() == EBoxSizing::kBorderBox &&
NeedsPreferredWidthsRecalculation() &&
View()->GetLayoutState()->ContainingBlockLogicalWidthChanged();
@@ -551,14 +556,14 @@ void LayoutBlock::AddOverflowFromPositionedObjects() {
for (auto* positioned_object : *positioned_descendants) {
// Fixed positioned elements don't contribute to layout overflow, since they
// don't scroll with the content.
- if (positioned_object->Style()->GetPosition() != EPosition::kFixed)
+ if (positioned_object->StyleRef().GetPosition() != EPosition::kFixed)
AddOverflowFromChild(*positioned_object,
ToLayoutSize(positioned_object->Location()));
}
}
void LayoutBlock::AddVisualOverflowFromTheme() {
- if (!Style()->HasAppearance())
+ if (!StyleRef().HasAppearance())
return;
IntRect inflated_rect = PixelSnappedBorderBoxRect();
@@ -570,10 +575,10 @@ void LayoutBlock::AddVisualOverflowFromTheme() {
static inline bool ChangeInAvailableLogicalHeightAffectsChild(
LayoutBlock* parent,
LayoutBox& child) {
- if (parent->Style()->BoxSizing() != EBoxSizing::kBorderBox)
+ if (parent->StyleRef().BoxSizing() != EBoxSizing::kBorderBox)
return false;
- return parent->Style()->IsHorizontalWritingMode() &&
- !child.Style()->IsHorizontalWritingMode();
+ return parent->StyleRef().IsHorizontalWritingMode() &&
+ !child.StyleRef().IsHorizontalWritingMode();
}
void LayoutBlock::UpdateBlockChildDirtyBitsBeforeLayout(bool relayout_children,
@@ -695,19 +700,19 @@ bool LayoutBlock::SimplifiedLayout() {
void LayoutBlock::MarkFixedPositionObjectForLayoutIfNeeded(
LayoutObject* child,
SubtreeLayoutScope& layout_scope) {
- if (child->Style()->GetPosition() != EPosition::kFixed)
+ if (child->StyleRef().GetPosition() != EPosition::kFixed)
return;
bool has_static_block_position =
- child->Style()->HasStaticBlockPosition(IsHorizontalWritingMode());
+ child->StyleRef().HasStaticBlockPosition(IsHorizontalWritingMode());
bool has_static_inline_position =
- child->Style()->HasStaticInlinePosition(IsHorizontalWritingMode());
+ child->StyleRef().HasStaticInlinePosition(IsHorizontalWritingMode());
if (!has_static_block_position && !has_static_inline_position)
return;
LayoutObject* o = child->Parent();
while (!o->IsLayoutView() &&
- o->Style()->GetPosition() != EPosition::kAbsolute)
+ o->StyleRef().GetPosition() != EPosition::kAbsolute)
o = o->Parent();
// The LayoutView is absolute-positioned, but does not move.
if (o->IsLayoutView())
@@ -789,7 +794,7 @@ void LayoutBlock::LayoutPositionedObjects(bool relayout_children,
void LayoutBlock::LayoutPositionedObject(LayoutBox* positioned_object,
bool relayout_children,
PositionedLayoutBehavior info) {
- positioned_object->SetMayNeedPaintInvalidation();
+ positioned_object->SetShouldCheckForPaintInvalidation();
SubtreeLayoutScope layout_scope(*positioned_object);
// If positionedObject is fixed-positioned and moves with an absolute-
@@ -801,11 +806,20 @@ void LayoutBlock::LayoutPositionedObject(LayoutBox* positioned_object,
return;
}
- if (!positioned_object->NormalChildNeedsLayout() &&
- (relayout_children || height_available_to_children_changed_ ||
- (!IsLayoutNGBlockFlow() &&
- NeedsLayoutDueToStaticPosition(positioned_object))))
- layout_scope.SetChildNeedsLayout(positioned_object);
+ if (!positioned_object->NormalChildNeedsLayout()) {
+ bool update_child_needs_layout =
+ relayout_children || height_available_to_children_changed_;
+ if (!update_child_needs_layout) {
+ if (!positioned_object->IsLayoutNGObject() ||
+ ToLayoutBlock(positioned_object)
+ ->IsLegacyInitiatedOutOfFlowLayout()) {
+ update_child_needs_layout |=
+ NeedsLayoutDueToStaticPosition(positioned_object);
+ }
+ }
+ if (update_child_needs_layout)
+ layout_scope.SetChildNeedsLayout(positioned_object);
+ }
LayoutUnit logical_top_estimate;
bool is_paginated = View()->GetLayoutState()->IsPaginated();
@@ -949,9 +963,9 @@ void LayoutBlock::RemovePositionedObject(LayoutBox* o) {
parent->MarkContainerNeedsCollectInlines();
}
-PaintInvalidationReason LayoutBlock::InvalidatePaint(
+void LayoutBlock::InvalidatePaint(
const PaintInvalidatorContext& context) const {
- return BlockPaintInvalidator(*this).InvalidatePaint(context);
+ BlockPaintInvalidator(*this).InvalidatePaint(context);
}
void LayoutBlock::ClearPreviousVisualRects() {
@@ -1075,9 +1089,9 @@ void LayoutBlock::DirtyForLayoutFromPercentageHeightDescendants(
LayoutUnit LayoutBlock::TextIndentOffset() const {
LayoutUnit cw;
- if (Style()->TextIndent().IsPercentOrCalc())
+ if (StyleRef().TextIndent().IsPercentOrCalc())
cw = ContainingBlock()->AvailableLogicalWidth();
- return MinimumValueForLength(Style()->TextIndent(), cw);
+ return MinimumValueForLength(StyleRef().TextIndent(), cw);
}
bool LayoutBlock::IsPointInOverflowControl(
@@ -1241,7 +1255,7 @@ PositionWithAffinity LayoutBlock::PositionForPointIfOutsideAtomicInlineLevel(
static inline bool IsChildHitTestCandidate(LayoutBox* box) {
return box->Size().Height() &&
- box->Style()->Visibility() == EVisibility::kVisible &&
+ box->StyleRef().Visibility() == EVisibility::kVisible &&
!box->IsOutOfFlowPositioned() && !box->IsLayoutFlowThread();
}
@@ -1269,7 +1283,7 @@ PositionWithAffinity LayoutBlock::PositionForPoint(
while (last_candidate_box && !IsChildHitTestCandidate(last_candidate_box))
last_candidate_box = last_candidate_box->PreviousSiblingBox();
- bool blocks_are_flipped = Style()->IsFlippedBlocksWritingMode();
+ bool blocks_are_flipped = StyleRef().IsFlippedBlocksWritingMode();
if (last_candidate_box) {
if (point_in_logical_contents.Y() >
LogicalTopForChild(*last_candidate_box) ||
@@ -1493,7 +1507,7 @@ void LayoutBlock::ComputeBlockPreferredLogicalWidths(
// will attempt to overlap the float if the negative margin is smaller
// than the float width.
bool ltr = containing_block
- ? containing_block->Style()->IsLeftToRightDirection()
+ ? containing_block->StyleRef().IsLeftToRightDirection()
: style_to_use.IsLeftToRightDirection();
LayoutUnit margin_logical_left = ltr ? margin_start : margin_end;
LayoutUnit margin_logical_right = ltr ? margin_end : margin_start;
@@ -1620,8 +1634,8 @@ LayoutUnit LayoutBlock::BaselinePosition(
// the theme is turned off, checkboxes/radios will still have decent
// baselines.
// FIXME: Need to patch form controls to deal with vertical lines.
- if (Style()->HasAppearance() &&
- !LayoutTheme::GetTheme().IsControlContainer(Style()->Appearance())) {
+ if (StyleRef().HasAppearance() &&
+ !LayoutTheme::GetTheme().IsControlContainer(StyleRef().Appearance())) {
return Size().Height() + MarginTop() +
LayoutTheme::GetTheme().BaselinePositionAdjustment(StyleRef());
}
@@ -1715,7 +1729,7 @@ bool LayoutBlock::UseLogicalBottomMarginEdgeForInlineBlockBaseline() const {
// We likewise avoid using the last line box in the case of size containment,
// where the block's contents shouldn't be considered when laying out its
// ancestors or siblings.
- return (!Style()->IsOverflowVisible() &&
+ return (!StyleRef().IsOverflowVisible() &&
!ShouldIgnoreOverflowPropertyForInlineBlockBaseline()) ||
ShouldApplySizeContainment();
}
@@ -1764,7 +1778,8 @@ const LayoutBlock* LayoutBlock::EnclosingFirstLineStyleBlock() const {
const LayoutBlock* first_line_block = this;
bool has_pseudo = false;
while (true) {
- has_pseudo = first_line_block->Style()->HasPseudoStyle(kPseudoIdFirstLine);
+ has_pseudo =
+ first_line_block->StyleRef().HasPseudoStyle(kPseudoIdFirstLine);
if (has_pseudo)
break;
LayoutObject* parent_block = first_line_block->Parent();
@@ -1852,7 +1867,7 @@ void LayoutBlock::AddOutlineRects(
LayoutBox* LayoutBlock::CreateAnonymousBoxWithSameTypeAs(
const LayoutObject* parent) const {
- return CreateAnonymousWithParentAndDisplay(parent, Style()->Display());
+ return CreateAnonymousWithParentAndDisplay(parent, StyleRef().Display());
}
void LayoutBlock::PaginatedContentWasLaidOut(
@@ -1903,15 +1918,17 @@ LayoutUnit LayoutBlock::CollapsedMarginAfterForChild(
bool LayoutBlock::HasMarginBeforeQuirk(const LayoutBox* child) const {
// If the child has the same directionality as we do, then we can just return
// its margin quirk.
- if (!child->IsWritingModeRoot())
+ if (!child->IsWritingModeRoot()) {
return child->IsLayoutBlock() ? ToLayoutBlock(child)->HasMarginBeforeQuirk()
- : child->Style()->HasMarginBeforeQuirk();
+ : child->StyleRef().HasMarginBeforeQuirk();
+ }
// The child has a different directionality. If the child is parallel, then
// it's just flipped relative to us. We can use the opposite edge.
- if (child->IsHorizontalWritingMode() == IsHorizontalWritingMode())
+ if (child->IsHorizontalWritingMode() == IsHorizontalWritingMode()) {
return child->IsLayoutBlock() ? ToLayoutBlock(child)->HasMarginAfterQuirk()
- : child->Style()->HasMarginAfterQuirk();
+ : child->StyleRef().HasMarginAfterQuirk();
+ }
// The child is perpendicular to us and box sides are never quirky in
// html.css, and we don't really care about whether or not authors specified
@@ -1922,15 +1939,17 @@ bool LayoutBlock::HasMarginBeforeQuirk(const LayoutBox* child) const {
bool LayoutBlock::HasMarginAfterQuirk(const LayoutBox* child) const {
// If the child has the same directionality as we do, then we can just return
// its margin quirk.
- if (!child->IsWritingModeRoot())
+ if (!child->IsWritingModeRoot()) {
return child->IsLayoutBlock() ? ToLayoutBlock(child)->HasMarginAfterQuirk()
- : child->Style()->HasMarginAfterQuirk();
+ : child->StyleRef().HasMarginAfterQuirk();
+ }
// The child has a different directionality. If the child is parallel, then
// it's just flipped relative to us. We can use the opposite edge.
- if (child->IsHorizontalWritingMode() == IsHorizontalWritingMode())
+ if (child->IsHorizontalWritingMode() == IsHorizontalWritingMode()) {
return child->IsLayoutBlock() ? ToLayoutBlock(child)->HasMarginBeforeQuirk()
- : child->Style()->HasMarginBeforeQuirk();
+ : child->StyleRef().HasMarginBeforeQuirk();
+ }
// The child is perpendicular to us and box sides are never quirky in
// html.css, and we don't really care about whether or not authors specified
@@ -1970,6 +1989,14 @@ LayoutBlock* LayoutBlock::CreateAnonymousWithParentAndDisplay(
return layout_block;
}
+const NGConstraintSpace* LayoutBlock::CachedConstraintSpace() const {
+ return cached_constraint_space_.get();
+}
+
+void LayoutBlock::SetCachedConstraintSpace(const NGConstraintSpace& space) {
+ cached_constraint_space_ = &space;
+}
+
bool LayoutBlock::RecalcNormalFlowChildOverflowIfNeeded(
LayoutObject* layout_object) {
if (layout_object->IsOutOfFlowPositioned())
@@ -2172,7 +2199,7 @@ bool LayoutBlock::HasDefiniteLogicalHeight() const {
}
bool LayoutBlock::NeedsPreferredWidthsRecalculation() const {
- return (HasRelativeLogicalHeight() && Style()->LogicalWidth().IsAuto()) ||
+ return (HasRelativeLogicalHeight() && StyleRef().LogicalWidth().IsAuto()) ||
LayoutBox::NeedsPreferredWidthsRecalculation();
}
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 d3b523f344d..d7640e1c3e4 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_block.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_block.h
@@ -33,6 +33,7 @@ namespace blink {
struct PaintInfo;
class LineLayoutBox;
+class NGConstraintSpace;
class WordMeasurement;
typedef WTF::ListHashSet<LayoutBox*, 16> TrackedLayoutBoxListHashSet;
@@ -290,12 +291,12 @@ class CORE_EXPORT LayoutBlock : public LayoutBox {
return LogicalLeftOffsetForContent() + AvailableLogicalWidth();
}
LayoutUnit StartOffsetForContent() const {
- return Style()->IsLeftToRightDirection()
+ return StyleRef().IsLeftToRightDirection()
? LogicalLeftOffsetForContent()
: LogicalWidth() - LogicalRightOffsetForContent();
}
LayoutUnit EndOffsetForContent() const {
- return !Style()->IsLeftToRightDirection()
+ return !StyleRef().IsLeftToRightDirection()
? LogicalLeftOffsetForContent()
: LogicalWidth() - LogicalRightOffsetForContent();
}
@@ -307,6 +308,9 @@ class CORE_EXPORT LayoutBlock : public LayoutBox {
LayoutUnit AvailableLogicalHeightForPercentageComputation() const;
bool HasDefiniteLogicalHeight() const;
+ const NGConstraintSpace* CachedConstraintSpace() const;
+ void SetCachedConstraintSpace(const NGConstraintSpace& space);
+
protected:
bool RecalcNormalFlowChildOverflowIfNeeded(LayoutObject*);
bool RecalcPositionedDescendantsOverflowAfterStyleChange();
@@ -357,6 +361,16 @@ class CORE_EXPORT LayoutBlock : public LayoutBox {
void MarkFixedPositionObjectForLayoutIfNeeded(LayoutObject* child,
SubtreeLayoutScope&);
+ public:
+ bool IsLegacyInitiatedOutOfFlowLayout() const {
+ return is_legacy_initiated_out_of_flow_layout_;
+ }
+
+ void SetIsLegacyInitiatedOutOfFlowLayout(bool b) {
+ is_legacy_initiated_out_of_flow_layout_ = b;
+ }
+
+ protected:
LayoutUnit MarginIntrinsicLogicalWidthForChild(const LayoutBox& child) const;
LayoutUnit BeforeMarginInLineDirection(LineDirectionMode) const;
@@ -481,8 +495,7 @@ class CORE_EXPORT LayoutBlock : public LayoutBox {
}
protected:
- PaintInvalidationReason InvalidatePaint(
- const PaintInvalidatorContext&) const override;
+ void InvalidatePaint(const PaintInvalidatorContext&) const override;
void ClearPreviousVisualRects() override;
@@ -519,6 +532,7 @@ class CORE_EXPORT LayoutBlock : public LayoutBox {
virtual bool UpdateLogicalWidthAndColumnWidth();
LayoutObjectChildList children_;
+ scoped_refptr<const NGConstraintSpace> cached_constraint_space_;
unsigned
has_margin_before_quirk_ : 1; // Note these quirk values can't be put
@@ -544,6 +558,10 @@ class CORE_EXPORT LayoutBlock : public LayoutBox {
// to, for all we know.
unsigned pagination_state_changed_ : 1;
+ // LayoutNG-only: This flag is true if an NG out of flow layout was
+ // initiated by Legacy positioning code.
+ unsigned is_legacy_initiated_out_of_flow_layout_ : 1;
+
// FIXME: This is temporary as we move code that accesses block flow
// member variables out of LayoutBlock and into LayoutBlockFlow.
friend class LayoutBlockFlow;
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 0fcd90c4837..b40b0ec1c7e 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
@@ -34,6 +34,7 @@
#include <memory>
#include <utility>
+#include "third_party/blink/renderer/core/editing/editing_behavior.h"
#include "third_party/blink/renderer/core/editing/editor.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
@@ -273,7 +274,13 @@ LayoutBlockFlow::LayoutBlockFlow(ContainerNode* node) : LayoutBlock(node) {
SetChildrenInline(true);
}
+#if DCHECK_IS_ON()
+LayoutBlockFlow::~LayoutBlockFlow() {
+ line_boxes_.AssertIsEmpty();
+}
+#else
LayoutBlockFlow::~LayoutBlockFlow() = default;
+#endif
LayoutBlockFlow* LayoutBlockFlow::CreateAnonymous(
Document* document,
@@ -377,19 +384,19 @@ bool LayoutBlockFlow::CheckIfIsSelfCollapsingBlock() const {
"-webkit-input-placeholder"));
if (LogicalHeight() > LayoutUnit() || BorderAndPaddingLogicalHeight() ||
- Style()->LogicalMinHeight().IsPositive() ||
- Style()->MarginBeforeCollapse() == EMarginCollapse::kSeparate ||
- Style()->MarginAfterCollapse() == EMarginCollapse::kSeparate)
+ StyleRef().LogicalMinHeight().IsPositive() ||
+ StyleRef().MarginBeforeCollapse() == EMarginCollapse::kSeparate ||
+ StyleRef().MarginAfterCollapse() == EMarginCollapse::kSeparate)
return false;
- Length logical_height_length = Style()->LogicalHeight();
+ Length logical_height_length = StyleRef().LogicalHeight();
bool has_auto_height = logical_height_length.IsAuto();
if (logical_height_length.IsPercentOrCalc() &&
!GetDocument().InQuirksMode()) {
has_auto_height = true;
for (LayoutBlock* cb = ContainingBlock(); !cb->IsLayoutView();
cb = cb->ContainingBlock()) {
- if (cb->Style()->LogicalHeight().IsFixed() || cb->IsTableCell())
+ if (cb->StyleRef().LogicalHeight().IsFixed() || cb->IsTableCell())
has_auto_height = false;
}
}
@@ -561,8 +568,8 @@ void LayoutBlockFlow::ResetLayout() {
// have no margins, so we don't fill in the values for table cells.
if (!IsTableCell()) {
InitMaxMarginValues();
- SetHasMarginBeforeQuirk(Style()->HasMarginBeforeQuirk());
- SetHasMarginAfterQuirk(Style()->HasMarginAfterQuirk());
+ SetHasMarginBeforeQuirk(StyleRef().HasMarginBeforeQuirk());
+ SetHasMarginAfterQuirk(StyleRef().HasMarginAfterQuirk());
}
if (View()->GetLayoutState()->IsPaginated()) {
@@ -682,14 +689,14 @@ void LayoutBlockFlow::DetermineLogicalLeftPositionForChild(LayoutBox& child) {
// If the child is being centred then the margin calculated to do that has
// factored in any offset required to avoid floats, so use it if necessary.
if (StyleRef().GetTextAlign() == ETextAlign::kWebkitCenter ||
- child.Style()->MarginStartUsing(StyleRef()).IsAuto())
+ child.StyleRef().MarginStartUsing(StyleRef()).IsAuto())
new_position =
std::max(new_position, position_to_avoid_floats + child_margin_start);
else if (position_to_avoid_floats > initial_start_position)
new_position = std::max(new_position, position_to_avoid_floats);
}
- SetLogicalLeftForChild(child, Style()->IsLeftToRightDirection()
+ SetLogicalLeftForChild(child, StyleRef().IsLeftToRightDirection()
? new_position
: total_available_logical_width -
new_position -
@@ -1140,7 +1147,7 @@ static bool ShouldSetStrutOnBlock(const LayoutBlockFlow& block,
if (total_logical_height > page_logical_height)
return false;
} else {
- if (line_index > block.Style()->Orphans())
+ if (line_index > block.StyleRef().Orphans())
return false;
// Not enough orphans here. Push the entire block to the next column / page
@@ -1521,7 +1528,7 @@ void LayoutBlockFlow::LayoutBlockChildren(bool relayout_children,
CHECK(!next_sibling || next_sibling->IsBox());
next = ToLayoutBox(next_sibling);
- child->SetMayNeedPaintInvalidation();
+ child->SetShouldCheckForPaintInvalidation();
if (child_to_exclude == child)
continue; // Skip this child, since it will be positioned by the
@@ -2040,7 +2047,7 @@ LayoutUnit LayoutBlockFlow::ClearFloatsIfNeeded(LayoutBox& child,
// In case the child discarded the before margin of the block we need to
// reset the mustDiscardMarginBefore flag to the initial value.
- SetMustDiscardMarginBefore(Style()->MarginBeforeCollapse() ==
+ SetMustDiscardMarginBefore(StyleRef().MarginBeforeCollapse() ==
EMarginCollapse::kDiscard);
}
@@ -2089,13 +2096,13 @@ void LayoutBlockFlow::MarginBeforeEstimateForChild(
// FIXME: Use writing mode independent accessor for marginBeforeCollapse.
if ((GetDocument().InQuirksMode() && HasMarginBeforeQuirk(&child) &&
(IsTableCell() || IsBody())) ||
- child.Style()->MarginBeforeCollapse() == EMarginCollapse::kSeparate)
+ child.StyleRef().MarginBeforeCollapse() == EMarginCollapse::kSeparate)
return;
// The margins are discarded by a child that specified
// -webkit-margin-collapse: discard.
// FIXME: Use writing mode independent accessor for marginBeforeCollapse.
- if (child.Style()->MarginBeforeCollapse() == EMarginCollapse::kDiscard) {
+ if (child.StyleRef().MarginBeforeCollapse() == EMarginCollapse::kDiscard) {
positive_margin_before = LayoutUnit();
negative_margin_before = LayoutUnit();
discard_margin_before = true;
@@ -2140,9 +2147,9 @@ void LayoutBlockFlow::MarginBeforeEstimateForChild(
if (grandchild_box->IsLayoutBlock()) {
LayoutBlock* grandchild_block = ToLayoutBlock(grandchild_box);
grandchild_block->SetHasMarginBeforeQuirk(
- grandchild_box->Style()->HasMarginBeforeQuirk());
+ grandchild_box->StyleRef().HasMarginBeforeQuirk());
grandchild_block->SetHasMarginAfterQuirk(
- grandchild_box->Style()->HasMarginAfterQuirk());
+ grandchild_box->StyleRef().HasMarginAfterQuirk());
}
}
@@ -2150,7 +2157,7 @@ void LayoutBlockFlow::MarginBeforeEstimateForChild(
// require clearance to move past any floats. If that's the case we want to be
// sure we estimate the correct position including margins after any floats
// rather than use 'clearance' later which could give us the wrong position.
- if (grandchild_box->Style()->Clear() != EClear::kNone &&
+ if (grandchild_box->StyleRef().Clear() != EClear::kNone &&
child_block_flow->MarginBeforeForChild(*grandchild_box) == 0)
return;
@@ -2310,7 +2317,7 @@ void LayoutBlockFlow::HandleAfterSideOfBlock(LayoutBox* last_child,
}
void LayoutBlockFlow::SetMustDiscardMarginBefore(bool value) {
- if (Style()->MarginBeforeCollapse() == EMarginCollapse::kDiscard) {
+ if (StyleRef().MarginBeforeCollapse() == EMarginCollapse::kDiscard) {
DCHECK(value);
return;
}
@@ -2325,7 +2332,7 @@ void LayoutBlockFlow::SetMustDiscardMarginBefore(bool value) {
}
void LayoutBlockFlow::SetMustDiscardMarginAfter(bool value) {
- if (Style()->MarginAfterCollapse() == EMarginCollapse::kDiscard) {
+ if (StyleRef().MarginAfterCollapse() == EMarginCollapse::kDiscard) {
DCHECK(value);
return;
}
@@ -2340,12 +2347,12 @@ void LayoutBlockFlow::SetMustDiscardMarginAfter(bool value) {
}
bool LayoutBlockFlow::MustDiscardMarginBefore() const {
- return Style()->MarginBeforeCollapse() == EMarginCollapse::kDiscard ||
+ return StyleRef().MarginBeforeCollapse() == EMarginCollapse::kDiscard ||
(rare_data_ && rare_data_->discard_margin_before_);
}
bool LayoutBlockFlow::MustDiscardMarginAfter() const {
- return Style()->MarginAfterCollapse() == EMarginCollapse::kDiscard ||
+ return StyleRef().MarginAfterCollapse() == EMarginCollapse::kDiscard ||
(rare_data_ && rare_data_->discard_margin_after_);
}
@@ -2355,13 +2362,13 @@ bool LayoutBlockFlow::MustDiscardMarginBeforeForChild(
if (!child.IsWritingModeRoot()) {
return child.IsLayoutBlockFlow()
? ToLayoutBlockFlow(&child)->MustDiscardMarginBefore()
- : (child.Style()->MarginBeforeCollapse() ==
+ : (child.StyleRef().MarginBeforeCollapse() ==
EMarginCollapse::kDiscard);
}
if (child.IsHorizontalWritingMode() == IsHorizontalWritingMode()) {
return child.IsLayoutBlockFlow()
? ToLayoutBlockFlow(&child)->MustDiscardMarginAfter()
- : (child.Style()->MarginAfterCollapse() ==
+ : (child.StyleRef().MarginAfterCollapse() ==
EMarginCollapse::kDiscard);
}
@@ -2378,13 +2385,13 @@ bool LayoutBlockFlow::MustDiscardMarginAfterForChild(
if (!child.IsWritingModeRoot()) {
return child.IsLayoutBlockFlow()
? ToLayoutBlockFlow(&child)->MustDiscardMarginAfter()
- : (child.Style()->MarginAfterCollapse() ==
+ : (child.StyleRef().MarginAfterCollapse() ==
EMarginCollapse::kDiscard);
}
if (child.IsHorizontalWritingMode() == IsHorizontalWritingMode()) {
return child.IsLayoutBlockFlow()
? ToLayoutBlockFlow(&child)->MustDiscardMarginBefore()
- : (child.Style()->MarginBeforeCollapse() ==
+ : (child.StyleRef().MarginBeforeCollapse() ==
EMarginCollapse::kDiscard);
}
@@ -2521,10 +2528,6 @@ scoped_refptr<NGLayoutResult> LayoutBlockFlow::CachedLayoutResult(
return nullptr;
}
-const NGConstraintSpace* LayoutBlockFlow::CachedConstraintSpace() const {
- return nullptr;
-}
-
scoped_refptr<NGLayoutResult> LayoutBlockFlow::CachedLayoutResultForTesting() {
return nullptr;
}
@@ -2533,8 +2536,14 @@ void LayoutBlockFlow::SetCachedLayoutResult(const NGConstraintSpace&,
NGBreakToken*,
scoped_refptr<NGLayoutResult>) {}
-void LayoutBlockFlow::SetPaintFragment(
- scoped_refptr<const NGPhysicalFragment>) {}
+void LayoutBlockFlow::SetPaintFragment(const NGBreakToken*,
+ scoped_refptr<const NGPhysicalFragment>,
+ NGPhysicalOffset) {}
+
+void LayoutBlockFlow::UpdatePaintFragmentFromCachedLayoutResult(
+ const NGBreakToken*,
+ scoped_refptr<const NGPhysicalFragment>,
+ NGPhysicalOffset) {}
void LayoutBlockFlow::ComputeOverflow(LayoutUnit old_client_after_edge,
bool recompute_floats) {
@@ -2675,7 +2684,7 @@ LayoutUnit LayoutBlockFlow::FirstLineBoxBaseline() const {
if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
if (const NGPaintFragment* paint_fragment = PaintFragment()) {
NGBoxFragment box_fragment(
- StyleRef().GetWritingMode(),
+ StyleRef().GetWritingMode(), StyleRef().Direction(),
ToNGPhysicalBoxFragment(paint_fragment->PhysicalFragment()));
NGLineHeightMetrics metrics =
box_fragment.BaselineMetricsWithoutSynthesize(
@@ -2708,7 +2717,7 @@ LayoutUnit LayoutBlockFlow::InlineBlockBaseline(
return LayoutUnit(-1);
// InlineFlowBox::placeBoxesInBlockDirection will flip lines in
// case of verticalLR mode, so we can assume verticalRL for now.
- if (Style()->IsFlippedLinesWritingMode()) {
+ if (StyleRef().IsFlippedLinesWritingMode()) {
return LogicalHeight() - LastLineBox()->LogicalBottom() +
font_data->GetFontMetrics().Ascent(LastRootBox()->BaselineType());
}
@@ -2846,7 +2855,7 @@ LayoutUnit LayoutBlockFlow::GetClearDelta(LayoutBox* child,
// At least one float is present. We need to perform the clearance
// computation.
- EClear clear = child->Style()->Clear();
+ EClear clear = child->StyleRef().Clear();
LayoutUnit logical_bottom = LowestFloatLogicalBottom(clear);
// We also clear floats if we are too big to sit on the same line as a float
@@ -2926,13 +2935,6 @@ void LayoutBlockFlow::WillBeDestroyed() {
// TODO(mstensho): figure out if we need this. We have no test coverage for
// it. It looks like all line boxes have been removed at this point.
if (FirstLineBox()) {
- // We can't wait for LayoutBox::destroy to clear the selection,
- // because by then we will have nuked the line boxes.
- // FIXME: The FrameSelection should be responsible for this when it
- // is notified of DOM mutations.
- if (IsSelectionBorder())
- View()->ClearSelection();
-
// If we are an anonymous block, then our line boxes might have children
// that will outlast this block. In the non-anonymous block case those
// children will be destroyed by the time we return from this function.
@@ -3027,7 +3029,7 @@ void LayoutBlockFlow::StyleDidChange(StyleDifference diff,
CreateOrDestroyMultiColumnFlowThreadIfNeeded(old_style);
if (old_style) {
if (LayoutMultiColumnFlowThread* flow_thread = MultiColumnFlowThread()) {
- if (!Style()->ColumnRuleEquivalent(*old_style)) {
+ if (!StyleRef().ColumnRuleEquivalent(*old_style)) {
// Column rules are painted by anonymous column set children of the
// multicol container. We need to notify them.
flow_thread->ColumnRuleStyleDidChange();
@@ -3049,7 +3051,7 @@ void LayoutBlockFlow::UpdateStaticInlinePositionForChild(
LayoutBox& child,
LayoutUnit logical_top,
IndentTextOrNot indent_text) {
- if (child.Style()->IsOriginalDisplayInlineType())
+ if (child.StyleRef().IsOriginalDisplayInlineType())
SetStaticInlinePositionForChild(
child, StartAlignedOffsetForLine(logical_top, indent_text));
else
@@ -3616,7 +3618,7 @@ void LayoutBlockFlow::RemoveFloatingObjects() {
LayoutPoint LayoutBlockFlow::FlipFloatForWritingModeForChild(
const FloatingObject& child,
const LayoutPoint& point) const {
- if (!Style()->IsFlippedBlocksWritingMode())
+ if (!StyleRef().IsFlippedBlocksWritingMode())
return point;
// This is similar to LayoutBox::flipForWritingModeForChild. We have to
@@ -3656,7 +3658,7 @@ LayoutUnit LayoutBlockFlow::AdjustLogicalLeftOffsetForLine(
IndentTextOrNot apply_text_indent) const {
LayoutUnit left = offset_from_floats;
- if (apply_text_indent == kIndentText && Style()->IsLeftToRightDirection())
+ if (apply_text_indent == kIndentText && StyleRef().IsLeftToRightDirection())
left += TextIndentOffset();
return left;
@@ -3667,7 +3669,7 @@ LayoutUnit LayoutBlockFlow::AdjustLogicalRightOffsetForLine(
IndentTextOrNot apply_text_indent) const {
LayoutUnit right = offset_from_floats;
- if (apply_text_indent == kIndentText && !Style()->IsLeftToRightDirection())
+ if (apply_text_indent == kIndentText && !StyleRef().IsLeftToRightDirection())
right -= TextIndentOffset();
return right;
@@ -3688,7 +3690,7 @@ LayoutPoint LayoutBlockFlow::ComputeLogicalLocationForFloat(
LayoutUnit float_logical_left;
- if (child_box->Style()->Floating() == EFloat::kLeft) {
+ if (child_box->StyleRef().Floating() == EFloat::kLeft) {
LayoutUnit height_remaining_left = LayoutUnit(1);
LayoutUnit height_remaining_right = LayoutUnit(1);
float_logical_left = LogicalLeftOffsetForPositioningFloat(
@@ -3871,11 +3873,11 @@ LayoutUnit LayoutBlockFlow::PositionAndLayoutFloat(
LayoutBox& child = *floating_object.GetLayoutObject();
// FIXME Investigate if this can be removed. crbug.com/370006
- child.SetMayNeedPaintInvalidation();
+ child.SetShouldCheckForPaintInvalidation();
logical_top_margin_edge =
std::max(logical_top_margin_edge,
- LowestFloatLogicalBottom(child.Style()->Clear()));
+ LowestFloatLogicalBottom(child.StyleRef().Clear()));
bool is_paginated = View()->GetLayoutState()->IsPaginated();
if (is_paginated && !ChildrenInline()) {
@@ -3976,7 +3978,7 @@ LayoutUnit LayoutBlockFlow::PositionAndLayoutFloat(
}
LayoutUnit child_logical_left_margin =
- Style()->IsLeftToRightDirection() ? margin_start : margin_end;
+ StyleRef().IsLeftToRightDirection() ? margin_start : margin_end;
SetLogicalLeftForChild(
child, float_logical_location.X() + child_logical_left_margin);
SetLogicalLeftForFloat(floating_object, float_logical_location.X());
@@ -4308,9 +4310,11 @@ void LayoutBlockFlow::UpdateAncestorShouldPaintFloatingObject(
bool float_box_is_self_painting_layer =
float_box.HasLayer() && float_box.Layer()->IsSelfPaintingLayer();
bool found_painting_ancestor = false;
- for (LayoutObject* ancestor = float_box.Parent();
- ancestor && ancestor->IsLayoutBlockFlow();
- ancestor = ancestor->Parent()) {
+ for (LayoutObject* ancestor = float_box.ContainingBlock(); ancestor;
+ ancestor = ancestor->ContainingBlock()) {
+ if (!ancestor->IsLayoutBlockFlow())
+ continue;
+
LayoutBlockFlow* ancestor_block = ToLayoutBlockFlow(ancestor);
FloatingObjects* ancestor_floating_objects =
ancestor_block->floating_objects_.get();
@@ -4426,10 +4430,10 @@ bool LayoutBlockFlow::CreatesNewFormattingContext() const {
if (IsInline() || IsFloatingOrOutOfFlowPositioned() || HasOverflowClip() ||
IsFlexItemIncludingDeprecated() || IsTableCell() || IsTableCaption() ||
IsFieldset() || IsCustomItem() || IsDocumentElement() || IsGridItem() ||
- IsWritingModeRoot() || Style()->Display() == EDisplay::kFlowRoot ||
+ IsWritingModeRoot() || StyleRef().Display() == EDisplay::kFlowRoot ||
ShouldApplyPaintContainment() || ShouldApplyLayoutContainment() ||
- Style()->SpecifiesColumns() ||
- Style()->GetColumnSpan() == EColumnSpan::kAll) {
+ StyleRef().SpecifiesColumns() ||
+ StyleRef().GetColumnSpan() == EColumnSpan::kAll) {
// The specs require this object to establish a new formatting context.
return true;
}
@@ -4670,8 +4674,8 @@ PositionWithAffinity LayoutBlockFlow::PositionForPoint(
if (!FirstRootBox())
return CreatePositionWithAffinity(0);
- bool lines_are_flipped = Style()->IsFlippedLinesWritingMode();
- bool blocks_are_flipped = Style()->IsFlippedBlocksWritingMode();
+ bool lines_are_flipped = StyleRef().IsFlippedLinesWritingMode();
+ bool blocks_are_flipped = StyleRef().IsFlippedBlocksWritingMode();
// look for the closest line box in the root box which is at the passed-in y
// coordinate
@@ -4752,14 +4756,20 @@ PositionWithAffinity LayoutBlockFlow::PositionForPoint(
}
}
+ if (closest_box->GetLineLayoutItem().IsAtomicInlineLevel()) {
+ // We want to pass the original point other than a corrected one.
+ LayoutPoint point(point_in_logical_contents);
+ if (!IsHorizontalWritingMode())
+ point = point.TransposedPoint();
+ return PositionForPointRespectingEditingBoundaries(
+ LineLayoutBox(closest_box->GetLineLayoutItem()), point);
+ }
+
// pass the box a top position that is inside it
LayoutPoint point(point_in_logical_contents.X(),
closest_box->Root().BlockDirectionPointInLine());
if (!IsHorizontalWritingMode())
point = point.TransposedPoint();
- if (closest_box->GetLineLayoutItem().IsAtomicInlineLevel())
- return PositionForPointRespectingEditingBoundaries(
- LineLayoutBox(closest_box->GetLineLayoutItem()), point);
return closest_box->GetLineLayoutItem().PositionForPoint(point);
}
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 8003efb0b11..93e35d45af4 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
@@ -66,6 +66,7 @@ class NGPaintFragment;
class NGPhysicalFragment;
struct NGInlineNodeData;
+struct NGPhysicalOffset;
enum IndentTextOrNot { kDoNotIndentText, kIndentText };
@@ -143,7 +144,7 @@ class CORE_EXPORT LayoutBlockFlow : public LayoutBlock {
LayoutUnit position,
IndentTextOrNot indent_text,
LayoutUnit logical_height = LayoutUnit()) const {
- return Style()->IsLeftToRightDirection()
+ return StyleRef().IsLeftToRightDirection()
? LogicalLeftOffsetForLine(position, indent_text, logical_height)
: LogicalWidth() - LogicalRightOffsetForLine(
position, indent_text, logical_height);
@@ -171,7 +172,7 @@ class CORE_EXPORT LayoutBlockFlow : public LayoutBlock {
LayoutUnit StartOffsetForAvoidingFloats(
LayoutUnit position,
LayoutUnit logical_height = LayoutUnit()) const {
- return Style()->IsLeftToRightDirection()
+ return StyleRef().IsLeftToRightDirection()
? LogicalLeftOffsetForAvoidingFloats(position, logical_height)
: LogicalWidth() - LogicalRightOffsetForAvoidingFloats(
position, logical_height);
@@ -179,7 +180,7 @@ class CORE_EXPORT LayoutBlockFlow : public LayoutBlock {
LayoutUnit EndOffsetForAvoidingFloats(
LayoutUnit position,
LayoutUnit logical_height = LayoutUnit()) const {
- return !Style()->IsLeftToRightDirection()
+ return !StyleRef().IsLeftToRightDirection()
? LogicalLeftOffsetForAvoidingFloats(position, logical_height)
: LogicalWidth() - LogicalRightOffsetForAvoidingFloats(
position, logical_height);
@@ -305,7 +306,7 @@ class CORE_EXPORT LayoutBlockFlow : public LayoutBlock {
static bool ShouldSkipCreatingRunsForObject(LineLayoutItem obj) {
return obj.IsFloating() || (obj.IsOutOfFlowPositioned() &&
- !obj.Style()->IsOriginalDisplayInlineType() &&
+ !obj.StyleRef().IsOriginalDisplayInlineType() &&
!obj.Container().IsLayoutInline());
}
@@ -454,14 +455,18 @@ class CORE_EXPORT LayoutBlockFlow : public LayoutBlock {
virtual scoped_refptr<NGLayoutResult> CachedLayoutResult(
const NGConstraintSpace&,
NGBreakToken*) const;
- virtual const NGConstraintSpace* CachedConstraintSpace() const;
virtual scoped_refptr<NGLayoutResult> CachedLayoutResultForTesting();
virtual void SetCachedLayoutResult(const NGConstraintSpace&,
NGBreakToken*,
scoped_refptr<NGLayoutResult>);
virtual void WillCollectInlines() {}
- virtual void SetPaintFragment(scoped_refptr<const NGPhysicalFragment>);
- virtual void ClearPaintFragment() {}
+ virtual void SetPaintFragment(const NGBreakToken*,
+ scoped_refptr<const NGPhysicalFragment>,
+ NGPhysicalOffset);
+ virtual void UpdatePaintFragmentFromCachedLayoutResult(
+ const NGBreakToken*,
+ scoped_refptr<const NGPhysicalFragment>,
+ NGPhysicalOffset);
virtual const NGPhysicalBoxFragment* CurrentFragment() const {
return nullptr;
}
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 cdb3d46b9c7..4697ac56be7 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
@@ -101,7 +101,7 @@ class ExpansionOpportunities {
CHECK_LE(opportunities_in_run, total_opportunities_);
// Don't justify for white-space: pre.
- if (r->line_layout_item_.Style()->WhiteSpace() != EWhiteSpace::kPre) {
+ if (r->line_layout_item_.StyleRef().WhiteSpace() != EWhiteSpace::kPre) {
InlineTextBox* text_box = ToInlineTextBox(r->box_);
CHECK(total_opportunities_);
int expansion = ((available_logical_width - total_logical_width) *
@@ -150,7 +150,7 @@ static inline InlineTextBox* CreateInlineBoxForText(BidiRun& run,
if (text.IsBR())
text_box->SetIsText(is_only_run || text.GetDocument().InNoQuirksMode());
text_box->SetDirOverride(
- run.DirOverride(text.Style()->RtlOrdering() == EOrder::kVisual));
+ run.DirOverride(text.StyleRef().RtlOrdering() == EOrder::kVisual));
if (run.has_hyphen_)
text_box->SetHasHyphen(true);
return text_box;
@@ -286,16 +286,17 @@ RootInlineBox* LayoutBlockFlow::ConstructLine(BidiRunList<BidiRun>& bidi_runs,
const LineInfo& line_info) {
DCHECK(bidi_runs.FirstRun());
- bool root_has_selected_children = false;
InlineFlowBox* parent_box = nullptr;
int run_count = bidi_runs.RunCount() - line_info.RunsFromLeadingWhitespace();
for (BidiRun* r = bidi_runs.FirstRun(); r; r = r->Next()) {
// Create a box for our object.
bool is_only_run = (run_count == 1);
- if (run_count == 2 && !r->line_layout_item_.IsListMarker())
- is_only_run = (!Style()->IsLeftToRightDirection() ? bidi_runs.LastRun()
- : bidi_runs.FirstRun())
- ->line_layout_item_.IsListMarker();
+ if (run_count == 2 && !r->line_layout_item_.IsListMarker()) {
+ is_only_run =
+ (!StyleRef().IsLeftToRightDirection() ? bidi_runs.LastRun()
+ : bidi_runs.FirstRun())
+ ->line_layout_item_.IsListMarker();
+ }
if (line_info.IsEmpty())
continue;
@@ -312,10 +313,6 @@ RootInlineBox* LayoutBlockFlow::ConstructLine(BidiRunList<BidiRun>& bidi_runs,
if (!box)
continue;
- if (!root_has_selected_children &&
- box->GetLineLayoutItem().GetSelectionState() != SelectionState::kNone)
- root_has_selected_children = true;
-
// If we have no parent box yet, or if the run is not simply a sibling,
// then we need to construct inline boxes as necessary to properly enclose
// the run's inline box. Segments can only be siblings at the root level, as
@@ -366,7 +363,7 @@ RootInlineBox* LayoutBlockFlow::ConstructLine(BidiRunList<BidiRun>& bidi_runs,
ETextAlign LayoutBlockFlow::TextAlignmentForLine(
bool ends_with_soft_break) const {
- return Style()->GetTextAlign(!ends_with_soft_break);
+ return StyleRef().GetTextAlign(!ends_with_soft_break);
}
static bool TextAlignmentNeedsTrailingSpace(ETextAlign text_align,
@@ -487,10 +484,10 @@ void LayoutBlockFlow::SetMarginsForRubyRun(BidiRun* run,
}
layout_ruby_run->GetOverhang(
line_info.IsFirstLine(),
- layout_ruby_run->Style()->IsLeftToRightDirection() ? previous_object
- : next_object,
- layout_ruby_run->Style()->IsLeftToRightDirection() ? next_object
- : previous_object,
+ layout_ruby_run->StyleRef().IsLeftToRightDirection() ? previous_object
+ : next_object,
+ layout_ruby_run->StyleRef().IsLeftToRightDirection() ? next_object
+ : previous_object,
start_overhang, end_overhang);
SetMarginStartForChild(*layout_ruby_run, LayoutUnit(-start_overhang));
SetMarginEndForChild(*layout_ruby_run, LayoutUnit(-end_overhang));
@@ -587,7 +584,7 @@ static inline void SetLogicalWidthForTextRun(
run->Direction(), line_info.IsFirstLine());
if (i > 0 && word_length == 1 &&
layout_text.CharacterAt(word_measurement.start_offset) == ' ')
- measured_width += layout_text.Style()->WordSpacing();
+ measured_width += layout_text.StyleRef().WordSpacing();
} else {
FloatRect word_glyph_bounds = word_measurement.glyph_bounds;
word_glyph_bounds.Move(measured_width, 0);
@@ -663,11 +660,11 @@ void LayoutBlockFlow::UpdateLogicalWidthForAlignment(
unsigned expansion_opportunity_count) {
TextDirection direction;
if (root_inline_box &&
- root_inline_box->GetLineLayoutItem().Style()->GetUnicodeBidi() ==
+ root_inline_box->GetLineLayoutItem().StyleRef().GetUnicodeBidi() ==
UnicodeBidi::kPlaintext)
direction = root_inline_box->Direction();
else
- direction = Style()->Direction();
+ direction = StyleRef().Direction();
// Armed with the total width of the line (without justification),
// we now examine our text-align property in order to determine where to
@@ -677,19 +674,19 @@ void LayoutBlockFlow::UpdateLogicalWidthForAlignment(
case ETextAlign::kLeft:
case ETextAlign::kWebkitLeft:
UpdateLogicalWidthForLeftAlignedBlock(
- Style()->IsLeftToRightDirection(), trailing_space_run, logical_left,
+ StyleRef().IsLeftToRightDirection(), trailing_space_run, logical_left,
total_logical_width, available_logical_width);
break;
case ETextAlign::kRight:
case ETextAlign::kWebkitRight:
UpdateLogicalWidthForRightAlignedBlock(
- Style()->IsLeftToRightDirection(), trailing_space_run, logical_left,
+ StyleRef().IsLeftToRightDirection(), trailing_space_run, logical_left,
total_logical_width, available_logical_width);
break;
case ETextAlign::kCenter:
case ETextAlign::kWebkitCenter:
UpdateLogicalWidthForCenterAlignedBlock(
- Style()->IsLeftToRightDirection(), trailing_space_run, logical_left,
+ StyleRef().IsLeftToRightDirection(), trailing_space_run, logical_left,
total_logical_width, available_logical_width);
break;
case ETextAlign::kJustify:
@@ -704,24 +701,26 @@ void LayoutBlockFlow::UpdateLogicalWidthForAlignment(
}
FALLTHROUGH;
case ETextAlign::kStart:
- if (direction == TextDirection::kLtr)
+ if (direction == TextDirection::kLtr) {
UpdateLogicalWidthForLeftAlignedBlock(
- Style()->IsLeftToRightDirection(), trailing_space_run, logical_left,
- total_logical_width, available_logical_width);
- else
+ StyleRef().IsLeftToRightDirection(), trailing_space_run,
+ logical_left, total_logical_width, available_logical_width);
+ } else {
UpdateLogicalWidthForRightAlignedBlock(
- Style()->IsLeftToRightDirection(), trailing_space_run, logical_left,
- total_logical_width, available_logical_width);
+ StyleRef().IsLeftToRightDirection(), trailing_space_run,
+ logical_left, total_logical_width, available_logical_width);
+ }
break;
case ETextAlign::kEnd:
- if (direction == TextDirection::kLtr)
+ if (direction == TextDirection::kLtr) {
UpdateLogicalWidthForRightAlignedBlock(
- Style()->IsLeftToRightDirection(), trailing_space_run, logical_left,
- total_logical_width, available_logical_width);
- else
+ StyleRef().IsLeftToRightDirection(), trailing_space_run,
+ logical_left, total_logical_width, available_logical_width);
+ } else {
UpdateLogicalWidthForLeftAlignedBlock(
- Style()->IsLeftToRightDirection(), trailing_space_run, logical_left,
- total_logical_width, available_logical_width);
+ StyleRef().IsLeftToRightDirection(), trailing_space_run,
+ logical_left, total_logical_width, available_logical_width);
+ }
break;
}
if (ShouldPlaceBlockDirectionScrollbarOnLogicalLeft())
@@ -808,7 +807,7 @@ BidiRun* LayoutBlockFlow::ComputeInlineDirectionPositionsForSegment(
ExpansionOpportunities expansions;
LayoutObject* previous_object = nullptr;
ETextAlign text_align = line_info.GetTextAlign();
- TextJustify text_justify = Style()->GetTextJustify();
+ TextJustify text_justify = StyleRef().GetTextJustify();
BidiRun* r = first_run;
size_t word_measurements_index = 0;
@@ -1260,7 +1259,7 @@ void LayoutBlockFlow::LayoutRunsAndFloatsInRange(
if (!pagination_strut_from_deleted_line) {
for (const auto& positioned_object : line_breaker.PositionedObjects()) {
- if (positioned_object.Style()->IsOriginalDisplayInlineType()) {
+ if (positioned_object.StyleRef().IsOriginalDisplayInlineType()) {
// Auto-positioned "inline" out-of-flow objects have already been
// positioned, but if we're paginated, or just ceased to be so, we
// need to update their position now, since the line they "belong" to
@@ -1300,7 +1299,7 @@ void LayoutBlockFlow::LayoutRunsAndFloatsInRange(
// widows then we need to ignore the possibility of having a new widows
// situation. Otherwise, we risk leaving empty containers which is against the
// block fragmentation principles.
- if (paginated && Style()->Widows() > 1 && !DidBreakAtLineToAvoidWidow()) {
+ if (paginated && StyleRef().Widows() > 1 && !DidBreakAtLineToAvoidWidow()) {
// Check the line boxes to make sure we didn't create unacceptable widows.
// However, we'll prioritize orphans - so nothing we do here should create
// a new orphan.
@@ -1322,11 +1321,11 @@ void LayoutBlockFlow::LayoutRunsAndFloatsInRange(
line_box == first_line_in_block)
return;
- if (num_lines_hanging < Style()->Widows()) {
+ if (num_lines_hanging < StyleRef().Widows()) {
// We have detected a widow. Now we need to work out how many
// lines there are on the previous page, and how many we need
// to steal.
- int num_lines_needed = Style()->Widows() - num_lines_hanging;
+ int num_lines_needed = StyleRef().Widows() - num_lines_hanging;
RootInlineBox* current_first_line_of_new_page = line_box;
// Count the number of lines in the previous page.
@@ -1344,7 +1343,7 @@ void LayoutBlockFlow::LayoutRunsAndFloatsInRange(
// about orphans, but given the specification says the initial orphan
// value is non-zero, this is ok. The author is always free to set orphans
// explicitly as well.
- int orphans = Style()->Orphans();
+ int orphans = StyleRef().Orphans();
int num_lines_available = num_lines_in_previous_page - orphans;
if (num_lines_available <= 0)
return;
@@ -1536,10 +1535,10 @@ static inline void StripTrailingSpace(LayoutUnit& inline_max,
}
// FIXME: This ignores first-line.
- const Font& font = text->Style()->GetFont();
+ const Font& font = text->StyleRef().GetFont();
TextRun run =
ConstructTextRun(font, &trailing_whitespace_char, 1, text->StyleRef(),
- text->Style()->Direction());
+ text->StyleRef().Direction());
float space_width = font.Width(run);
inline_max -= LayoutUnit::FromFloatCeil(
space_width + font.GetFontDescription().WordSpacing());
@@ -1628,8 +1627,8 @@ void LayoutBlockFlow::ComputeInlinePreferredLogicalWidths(
bool should_break_line_after_text = false;
while (LayoutObject* child = child_iterator.Next()) {
auto_wrap = child->IsAtomicInlineLevel()
- ? child->Parent()->Style()->AutoWrap()
- : child->Style()->AutoWrap();
+ ? child->Parent()->StyleRef().AutoWrap()
+ : child->StyleRef().AutoWrap();
if (!child->IsBR()) {
// Step One: determine whether or not we need to go ahead and
@@ -1920,7 +1919,7 @@ bool LayoutBlockFlow::ShouldTruncateOverflowingText() const {
object_to_check = parent;
}
return object_to_check->HasOverflowClip() &&
- object_to_check->Style()->TextOverflow() != ETextOverflow::kClip;
+ object_to_check->StyleRef().TextOverflow() != ETextOverflow::kClip;
}
DISABLE_CFI_PERF
@@ -1960,7 +1959,7 @@ void LayoutBlockFlow::LayoutInlineChildren(bool relayout_children,
if (o->IsAtomicInlineLevel() || o->IsFloating() ||
o->IsOutOfFlowPositioned()) {
LayoutBox* box = ToLayoutBox(o);
- box->SetMayNeedPaintInvalidation();
+ box->SetShouldCheckForPaintInvalidation();
UpdateBlockChildDirtyBitsBeforeLayout(relayout_children, *box);
@@ -2002,7 +2001,7 @@ void LayoutBlockFlow::LayoutInlineChildren(bool relayout_children,
if (LastRootBox()) {
LayoutUnit lowest_allowed_position =
std::max(LastRootBox()->LineBottom(), LogicalHeight() + PaddingAfter());
- if (!Style()->IsFlippedLinesWritingMode())
+ if (!StyleRef().IsFlippedLinesWritingMode())
last_line_annotations_adjustment =
LastRootBox()
->ComputeUnderAnnotationAdjustment(lowest_allowed_position)
@@ -2149,11 +2148,11 @@ RootInlineBox* LayoutBlockFlow::DetermineStartPosition(
resolver.SetPosition(iter, NumberOfIsolateAncestors(iter));
resolver.SetStatus(last->LineBreakBidiStatus());
} else {
- TextDirection direction = Style()->Direction();
- if (Style()->GetUnicodeBidi() == UnicodeBidi::kPlaintext)
+ TextDirection direction = StyleRef().Direction();
+ if (StyleRef().GetUnicodeBidi() == UnicodeBidi::kPlaintext)
direction = DeterminePlaintextDirectionality(LineLayoutItem(this));
resolver.SetStatus(
- BidiStatus(direction, IsOverride(Style()->GetUnicodeBidi())));
+ BidiStatus(direction, IsOverride(StyleRef().GetUnicodeBidi())));
InlineIterator iter = InlineIterator(
LineLayoutBlockFlow(this),
BidiFirstSkippingEmptyInlines(LineLayoutBlockFlow(this),
@@ -2170,11 +2169,11 @@ bool LayoutBlockFlow::LineBoxHasBRWithClearance(RootInlineBox* curr) {
// difficulty.
if (!curr->EndsWithBreak())
return false;
- InlineBox* last_box = Style()->IsLeftToRightDirection()
+ InlineBox* last_box = StyleRef().IsLeftToRightDirection()
? curr->LastLeafChild()
: curr->FirstLeafChild();
return last_box && last_box->GetLineLayoutItem().IsBR() &&
- last_box->GetLineLayoutItem().Style()->Clear() != EClear::kNone;
+ last_box->GetLineLayoutItem().StyleRef().Clear() != EClear::kNone;
}
void LayoutBlockFlow::DetermineEndPosition(LineLayoutState& layout_state,
@@ -2321,7 +2320,7 @@ void LayoutBlockFlow::AddOverflowFromInlineChildren() {
// FIXME: Need to find another way to do this, since scrollbars could show
// when we don't want them to.
if (HasOverflowClip() && !end_padding && GetNode() &&
- IsRootEditableElement(*GetNode()) && Style()->IsLeftToRightDirection())
+ IsRootEditableElement(*GetNode()) && StyleRef().IsLeftToRightDirection())
end_padding = LayoutUnit(1);
for (RootInlineBox* curr = FirstRootBox(); curr; curr = curr->NextRootBox()) {
AddLayoutOverflow(curr->PaddedLayoutOverflowRect(end_padding));
@@ -2356,7 +2355,7 @@ void LayoutBlockFlow::AddOverflowFromInlineChildren() {
}
void LayoutBlockFlow::DeleteEllipsisLineBoxes() {
- ETextAlign text_align = Style()->GetTextAlign();
+ ETextAlign text_align = StyleRef().GetTextAlign();
IndentTextOrNot indent_text = kIndentText;
for (RootInlineBox* curr = FirstRootBox(); curr; curr = curr->NextRootBox()) {
if (curr->HasEllipsisBox()) {
@@ -2382,7 +2381,7 @@ void LayoutBlockFlow::DeleteEllipsisLineBoxes() {
}
void LayoutBlockFlow::ClearTruncationOnAtomicInlines(RootInlineBox* root) {
- bool ltr = Style()->IsLeftToRightDirection();
+ bool ltr = StyleRef().IsLeftToRightDirection();
InlineBox* first_child = ltr ? root->LastChild() : root->FirstChild();
for (InlineBox* box = first_child; box;
box = ltr ? box->PrevOnLine() : box->NextOnLine()) {
@@ -2399,7 +2398,7 @@ void LayoutBlockFlow::ClearTruncationOnAtomicInlines(RootInlineBox* root) {
void LayoutBlockFlow::CheckLinesForTextOverflow() {
// Determine the width of the ellipsis using the current font.
- const Font& font = Style()->GetFont();
+ const Font& font = StyleRef().GetFont();
const size_t kFullStopStringLength = 3;
const UChar kFullStopString[] = {kFullstopCharacter, kFullstopCharacter,
@@ -2452,8 +2451,8 @@ void LayoutBlockFlow::CheckLinesForTextOverflow() {
// For RTL, we use the left edge of the padding box and check the left edge of
// the line box to see if it is less Include the scrollbar for overflow
// blocks, which means we want to use "contentWidth()".
- bool ltr = Style()->IsLeftToRightDirection();
- ETextAlign text_align = Style()->GetTextAlign();
+ bool ltr = StyleRef().IsLeftToRightDirection();
+ ETextAlign text_align = StyleRef().GetTextAlign();
IndentTextOrNot indent_text = kIndentText;
for (RootInlineBox* curr = FirstRootBox(); curr; curr = curr->NextRootBox()) {
LayoutUnit block_right_edge =
@@ -2508,7 +2507,7 @@ void LayoutBlockFlow::TryPlacingEllipsisOnAtomicInlines(
const AtomicString& selected_ellipsis_str,
InlineBox* box_truncation_starts_at) {
bool found_box = box_truncation_starts_at ? true : false;
- bool ltr = Style()->IsLeftToRightDirection();
+ bool ltr = StyleRef().IsLeftToRightDirection();
LayoutUnit logical_left_offset = block_left_edge;
// Each atomic inline block (e.g. a <span>) inside a blockflow is managed by
@@ -2608,17 +2607,17 @@ void LayoutBlockFlow::MarkLinesDirtyInBlockRange(LayoutUnit logical_top,
LayoutUnit LayoutBlockFlow::StartAlignedOffsetForLine(
LayoutUnit position,
IndentTextOrNot indent_text) {
- ETextAlign text_align = Style()->GetTextAlign();
+ ETextAlign text_align = StyleRef().GetTextAlign();
bool apply_indent_text;
switch (text_align) { // FIXME: Handle TAEND here
case ETextAlign::kLeft:
case ETextAlign::kWebkitLeft:
- apply_indent_text = Style()->IsLeftToRightDirection();
+ apply_indent_text = StyleRef().IsLeftToRightDirection();
break;
case ETextAlign::kRight:
case ETextAlign::kWebkitRight:
- apply_indent_text = !Style()->IsLeftToRightDirection();
+ apply_indent_text = !StyleRef().IsLeftToRightDirection();
break;
case ETextAlign::kStart:
apply_indent_text = true;
@@ -2642,7 +2641,7 @@ LayoutUnit LayoutBlockFlow::StartAlignedOffsetForLine(
total_logical_width, available_logical_width,
0);
- if (!Style()->IsLeftToRightDirection())
+ if (!StyleRef().IsLeftToRightDirection())
return LogicalWidth() - logical_left;
return logical_left;
}
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 9435e5ffc88..5511e3e4bb1 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_box.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_box.cc
@@ -32,6 +32,7 @@
#include "third_party/blink/public/platform/web_scroll_into_view_params.h"
#include "third_party/blink/renderer/core/dom/document.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"
#include "third_party/blink/renderer/core/frame/local_frame_client.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
@@ -63,10 +64,8 @@
#include "third_party/blink/renderer/core/layout/shapes/shape_outside_info.h"
#include "third_party/blink/renderer/core/page/autoscroll_controller.h"
#include "third_party/blink/renderer/core/page/page.h"
-#include "third_party/blink/renderer/core/page/scrolling/root_scroller_util.h"
#include "third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h"
#include "third_party/blink/renderer/core/page/scrolling/snap_coordinator.h"
-#include "third_party/blink/renderer/core/paint/adjust_paint_offset_scope.h"
#include "third_party/blink/renderer/core/paint/background_image_geometry.h"
#include "third_party/blink/renderer/core/paint/box_paint_invalidator.h"
#include "third_party/blink/renderer/core/paint/box_painter.h"
@@ -112,15 +111,22 @@ LayoutBox::LayoutBox(ContainerNode* node)
SetIsBox();
}
+LayoutBox::~LayoutBox() {
+#if DCHECK_IS_ON()
+ if (IsInLayoutNGInlineFormattingContext())
+ DCHECK(!first_paint_fragment_);
+#endif
+}
+
PaintLayerType LayoutBox::LayerTypeRequired() const {
// hasAutoZIndex only returns true if the element is positioned or a flex-item
// since position:static elements that are not flex-items get their z-index
// coerced to auto.
if (IsPositioned() || CreatesGroup() || HasTransformRelatedProperty() ||
- HasHiddenBackface() || HasReflection() || Style()->SpecifiesColumns() ||
- Style()->IsStackingContext() ||
- Style()->ShouldCompositeForCurrentAnimations() ||
- RootScrollerUtil::IsEffective(*this))
+ HasHiddenBackface() || HasReflection() || StyleRef().SpecifiesColumns() ||
+ StyleRef().IsStackingContext() ||
+ StyleRef().ShouldCompositeForCurrentAnimations() ||
+ IsEffectiveRootScroller())
return kNormalPaintLayer;
if (HasOverflowClip())
@@ -337,8 +343,16 @@ void LayoutBox::StyleDidChange(StyleDifference diff,
// overflowClipRect(), and border radii, so we update properties on
// border size or radii change.
if (!old_style->BorderSizeEquals(new_style) ||
- !old_style->RadiiEqual(new_style))
+ !old_style->RadiiEqual(new_style)) {
SetNeedsPaintPropertyUpdate();
+ if (Layer())
+ Layer()->SetNeedsCompositingInputsUpdate();
+ }
+ }
+
+ if (old_style->OverscrollBehaviorX() != new_style.OverscrollBehaviorX() ||
+ old_style->OverscrollBehaviorY() != new_style.OverscrollBehaviorY()) {
+ SetNeedsPaintPropertyUpdate();
}
}
@@ -427,17 +441,17 @@ void LayoutBox::UpdateGridPositionAfterStyleChange(
if (!old_style || !Parent() || !Parent()->IsLayoutGrid())
return;
- if (old_style->GridColumnStart() == Style()->GridColumnStart() &&
- old_style->GridColumnEnd() == Style()->GridColumnEnd() &&
- old_style->GridRowStart() == Style()->GridRowStart() &&
- old_style->GridRowEnd() == Style()->GridRowEnd() &&
- old_style->Order() == Style()->Order() &&
- old_style->HasOutOfFlowPosition() == Style()->HasOutOfFlowPosition())
+ if (old_style->GridColumnStart() == StyleRef().GridColumnStart() &&
+ old_style->GridColumnEnd() == StyleRef().GridColumnEnd() &&
+ old_style->GridRowStart() == StyleRef().GridRowStart() &&
+ old_style->GridRowEnd() == StyleRef().GridRowEnd() &&
+ old_style->Order() == StyleRef().Order() &&
+ old_style->HasOutOfFlowPosition() == StyleRef().HasOutOfFlowPosition())
return;
// Positioned items don't participate on the layout of the grid,
// so we don't need to mark the grid as dirty if they change positions.
- if (old_style->HasOutOfFlowPosition() && Style()->HasOutOfFlowPosition())
+ if (old_style->HasOutOfFlowPosition() && StyleRef().HasOutOfFlowPosition())
return;
// It should be possible to not dirty the grid in some cases (like moving an
@@ -508,7 +522,7 @@ void LayoutBox::UpdateLayout() {
DCHECK(!child->NeedsLayout());
child = child->NextSibling();
}
- InvalidateBackgroundObscurationStatus();
+ UpdateAfterLayout();
ClearNeedsLayout();
}
@@ -558,7 +572,7 @@ LayoutUnit LayoutBox::ScrollWidth() const {
return GetScrollableArea()->ScrollWidth();
// For objects with visible overflow, this matches IE.
// FIXME: Need to work right with writing modes.
- if (Style()->IsLeftToRightDirection())
+ if (StyleRef().IsLeftToRightDirection())
return std::max(ClientWidth(), LayoutOverflowRect().MaxX() - BorderLeft());
return ClientWidth() -
std::min(LayoutUnit(), LayoutOverflowRect().X() - BorderLeft());
@@ -703,7 +717,7 @@ LayoutRect LayoutBox::ScrollRectToVisibleRecursive(
// If we are fixed-position and stick to the viewport, it is useless to
// scroll the parent.
- if (Style()->GetPosition() == EPosition::kFixed && Container() == View())
+ if (StyleRef().GetPosition() == EPosition::kFixed && Container() == View())
return absolute_rect_for_parent;
if (parent_box) {
@@ -749,6 +763,8 @@ FloatRect LayoutBox::LocalBoundingBoxRectForAccessibility() const {
}
void LayoutBox::UpdateAfterLayout() {
+ InvalidateBackgroundObscurationStatus();
+
// Transform-origin depends on box size, so we need to update the layer
// transform after layout.
if (HasLayer()) {
@@ -761,7 +777,7 @@ LayoutUnit LayoutBox::LogicalHeightWithVisibleOverflow() const {
if (!overflow_ || HasOverflowClip())
return LogicalHeight();
LayoutRect overflow = LayoutOverflowRect();
- if (Style()->IsHorizontalWritingMode())
+ if (StyleRef().IsHorizontalWritingMode())
return overflow.MaxY();
return overflow.MaxX();
}
@@ -854,28 +870,29 @@ void LayoutBox::SetLocationAndUpdateOverflowControlsIfNeeded(
IntRect LayoutBox::AbsoluteContentBox() const {
// This is wrong with transforms and flipped writing modes.
- IntRect rect = PixelSnappedIntRect(ContentBoxRect());
+ IntRect rect = PixelSnappedIntRect(PhysicalContentBoxRect());
FloatPoint abs_pos = LocalToAbsolute();
rect.Move(abs_pos.X(), abs_pos.Y());
return rect;
}
IntSize LayoutBox::AbsoluteContentBoxOffset() const {
- IntPoint offset = RoundedIntPoint(ContentBoxOffset());
+ IntPoint offset = RoundedIntPoint(PhysicalContentBoxOffset());
FloatPoint abs_pos = LocalToAbsolute();
offset.Move(abs_pos.X(), abs_pos.Y());
return ToIntSize(offset);
}
FloatQuad LayoutBox::AbsoluteContentQuad(MapCoordinatesFlags flags) const {
- LayoutRect rect = ContentBoxRect();
+ LayoutRect rect = PhysicalContentBoxRect();
return LocalToAbsoluteQuad(FloatRect(rect), flags);
}
-LayoutRect LayoutBox::BackgroundRect(BackgroundRectType rect_type) const {
+LayoutRect LayoutBox::PhysicalBackgroundRect(
+ BackgroundRectType rect_type) const {
EFillBox background_box = EFillBox::kText;
// Find the largest background rect of the given opaqueness.
- if (const FillLayer* current = &(Style()->BackgroundLayers())) {
+ if (const FillLayer* current = &(StyleRef().BackgroundLayers())) {
do {
const FillLayer* cur = current;
current = current->Next();
@@ -930,10 +947,10 @@ LayoutRect LayoutBox::BackgroundRect(BackgroundRectType rect_type) const {
return BorderBoxRect();
break;
case EFillBox::kPadding:
- return PaddingBoxRect();
+ return PhysicalPaddingBoxRect();
break;
case EFillBox::kContent:
- return ContentBoxRect();
+ return PhysicalContentBoxRect();
break;
default:
break;
@@ -952,7 +969,7 @@ bool LayoutBox::CanResize() const {
// hasOverflowClip(). However, they do "implicitly" clip their contents, so
// we want to allow resizing them also.
return (HasOverflowClip() || IsLayoutIFrame()) &&
- Style()->Resize() != EResize::kNone;
+ StyleRef().Resize() != EResize::kNone;
}
void LayoutBox::AddLayerHitTestRects(
@@ -975,14 +992,14 @@ void LayoutBox::ComputeSelfHitTestRects(Vector<LayoutRect>& rects,
}
int LayoutBox::VerticalScrollbarWidth() const {
- if (!HasOverflowClip() || Style()->OverflowY() == EOverflow::kOverlay)
+ if (!HasOverflowClip() || StyleRef().OverflowY() == EOverflow::kOverlay)
return 0;
return GetScrollableArea()->VerticalScrollbarWidth();
}
int LayoutBox::HorizontalScrollbarHeight() const {
- if (!HasOverflowClip() || Style()->OverflowX() == EOverflow::kOverlay)
+ if (!HasOverflowClip() || StyleRef().OverflowX() == EOverflow::kOverlay)
return 0;
return GetScrollableArea()->HorizontalScrollbarHeight();
@@ -1141,8 +1158,8 @@ void LayoutBox::ScrollByRecursively(const ScrollOffset& delta) {
}
bool LayoutBox::NeedsPreferredWidthsRecalculation() const {
- return Style()->PaddingStart().IsPercentOrCalc() ||
- Style()->PaddingEnd().IsPercentOrCalc();
+ return StyleRef().PaddingStart().IsPercentOrCalc() ||
+ StyleRef().PaddingEnd().IsPercentOrCalc();
}
IntSize LayoutBox::OriginAdjustmentForScrollbars() const {
@@ -1185,7 +1202,7 @@ bool LayoutBox::MapVisualRectToContainer(
const LayoutObject* ancestor,
VisualRectFlags visual_rect_flags,
TransformState& transform_state) const {
- bool container_preserve_3d = container_object->Style()->Preserves3D();
+ bool container_preserve_3d = container_object->StyleRef().Preserves3D();
TransformState::TransformAccumulation accumulation =
container_preserve_3d ? TransformState::kAccumulateTransform
@@ -1244,7 +1261,7 @@ bool LayoutBox::MapVisualRectToContainer(
// d) Perspective applied by container.
if (container_object && container_object->HasLayer() &&
- container_object->Style()->HasPerspective()) {
+ container_object->StyleRef().HasPerspective()) {
// Perspective on the container affects us, so we have to factor it in here.
DCHECK(container_object->HasLayer());
FloatPoint perspective_origin =
@@ -1252,7 +1269,7 @@ bool LayoutBox::MapVisualRectToContainer(
TransformationMatrix perspective_matrix;
perspective_matrix.ApplyPerspective(
- container_object->Style()->Perspective());
+ container_object->StyleRef().Perspective());
perspective_matrix.ApplyTransformOrigin(perspective_origin.X(),
perspective_origin.Y(), 0);
@@ -1474,7 +1491,7 @@ LayoutUnit LayoutBox::AdjustBorderBoxLogicalWidthForBoxSizing(
float width) const {
LayoutUnit borders_plus_padding = CollapsedBorderAndCSSPaddingLogicalWidth();
LayoutUnit result(width);
- if (Style()->BoxSizing() == EBoxSizing::kContentBox)
+ if (StyleRef().BoxSizing() == EBoxSizing::kContentBox)
return result + borders_plus_padding;
return std::max(result, borders_plus_padding);
}
@@ -1483,7 +1500,7 @@ LayoutUnit LayoutBox::AdjustBorderBoxLogicalHeightForBoxSizing(
float height) const {
LayoutUnit borders_plus_padding = CollapsedBorderAndCSSPaddingLogicalHeight();
LayoutUnit result(height);
- if (Style()->BoxSizing() == EBoxSizing::kContentBox)
+ if (StyleRef().BoxSizing() == EBoxSizing::kContentBox)
return result + borders_plus_padding;
return std::max(result, borders_plus_padding);
}
@@ -1491,7 +1508,7 @@ LayoutUnit LayoutBox::AdjustBorderBoxLogicalHeightForBoxSizing(
LayoutUnit LayoutBox::AdjustContentBoxLogicalWidthForBoxSizing(
float width) const {
LayoutUnit result(width);
- if (Style()->BoxSizing() == EBoxSizing::kBorderBox)
+ if (StyleRef().BoxSizing() == EBoxSizing::kBorderBox)
result -= CollapsedBorderAndCSSPaddingLogicalWidth();
return std::max(LayoutUnit(), result);
}
@@ -1499,7 +1516,7 @@ LayoutUnit LayoutBox::AdjustContentBoxLogicalWidthForBoxSizing(
LayoutUnit LayoutBox::AdjustContentBoxLogicalHeightForBoxSizing(
float height) const {
LayoutUnit result(height);
- if (Style()->BoxSizing() == EBoxSizing::kBorderBox)
+ if (StyleRef().BoxSizing() == EBoxSizing::kBorderBox)
result -= CollapsedBorderAndCSSPaddingLogicalHeight();
return std::max(LayoutUnit(), result);
}
@@ -1512,7 +1529,7 @@ bool LayoutBox::HitTestAllPhases(HitTestResult& result,
// Check if we need to do anything at all.
// If we have clipping, then we can't have any spillout.
// TODO(pdr): Why is this optimization not valid for the effective root?
- if (!RootScrollerUtil::IsEffective(*this)) {
+ if (!IsEffectiveRootScroller()) {
LayoutRect overflow_box =
(HasOverflowClip() || ShouldApplyPaintContainment())
? BorderBoxRect()
@@ -1549,10 +1566,10 @@ bool LayoutBox::NodeAtPoint(HitTestResult& result,
adjusted_location, kExcludeOverlayScrollbarSizeForHitTesting))) {
skip_children = true;
}
- if (!skip_children && Style()->HasBorderRadius()) {
+ if (!skip_children && StyleRef().HasBorderRadius()) {
LayoutRect bounds_rect(adjusted_location, Size());
skip_children = !location_in_container.Intersects(
- Style()->GetRoundedInnerBorderFor(bounds_rect));
+ StyleRef().GetRoundedInnerBorderFor(bounds_rect));
}
}
@@ -1561,7 +1578,7 @@ bool LayoutBox::NodeAtPoint(HitTestResult& result,
return true;
}
- if (Style()->HasBorderRadius() &&
+ if (StyleRef().HasBorderRadius() &&
HitTestClippedOutByBorder(location_in_container, adjusted_location))
return false;
@@ -1605,7 +1622,7 @@ bool LayoutBox::HitTestClippedOutByBorder(
LayoutRect border_rect = BorderBoxRect();
border_rect.MoveBy(border_box_location);
return !location_in_container.Intersects(
- Style()->GetRoundedBorderFor(border_rect));
+ StyleRef().GetRoundedBorderFor(border_rect));
}
void LayoutBox::Paint(const PaintInfo& paint_info) const {
@@ -1633,8 +1650,8 @@ bool LayoutBox::GetBackgroundPaintedExtent(LayoutRect& painted_extent) const {
return true;
}
- if (!Style()->BackgroundLayers().GetImage() ||
- Style()->BackgroundLayers().Next()) {
+ if (!StyleRef().BackgroundLayers().GetImage() ||
+ StyleRef().BackgroundLayers().Next()) {
painted_extent = background_rect;
return true;
}
@@ -1644,7 +1661,7 @@ bool LayoutBox::GetBackgroundPaintedExtent(LayoutRect& painted_extent) const {
// and outside of the paint phase. Potentially returning different results at
// different phases. crbug.com/732934
geometry.Calculate(nullptr, PaintPhase::kBlockBackground,
- kGlobalPaintNormalPhase, Style()->BackgroundLayers(),
+ kGlobalPaintNormalPhase, StyleRef().BackgroundLayers(),
background_rect);
if (geometry.HasNonLocalGeometry())
return false;
@@ -1661,18 +1678,19 @@ bool LayoutBox::BackgroundIsKnownToBeOpaqueInRect(
// We cannot be sure if theme paints the background opaque.
// In this case it is safe to not assume opaqueness.
// FIXME: May be ask theme if it paints opaque.
- if (Style()->HasAppearance())
+ if (StyleRef().HasAppearance())
return false;
// FIXME: Check the opaqueness of background images.
// FIXME: Use rounded rect if border radius is present.
- if (Style()->HasBorderRadius())
+ if (StyleRef().HasBorderRadius())
return false;
if (HasClipPath())
return false;
- if (Style()->HasBlendMode())
+ if (StyleRef().HasBlendMode())
return false;
- return BackgroundRect(kBackgroundKnownOpaqueRect).Contains(local_rect);
+ return PhysicalBackgroundRect(kBackgroundKnownOpaqueRect)
+ .Contains(local_rect);
}
static bool IsCandidateForOpaquenessTest(const LayoutBox& child_box) {
@@ -1752,7 +1770,7 @@ bool LayoutBox::ComputeBackgroundIsKnownToBeObscured() const {
if (IsLayoutView())
return false;
// FIXME: box-shadow is painted while background painting.
- if (Style()->BoxShadow())
+ if (StyleRef().BoxShadow())
return false;
LayoutRect background_rect;
if (!GetBackgroundPaintedExtent(background_rect))
@@ -1778,8 +1796,8 @@ void LayoutBox::ImageChanged(WrappedImagePtr image,
SetNeedsPaintPropertyUpdate();
}
- // TODO(chrishtr): support PaintInvalidationReason::kDelayedFull for animated
- // border images.
+ // TODO(chrishtr): support delayed paint invalidation for animated border
+ // images.
if ((StyleRef().BorderImage().GetImage() &&
StyleRef().BorderImage().GetImage()->Data() == image) ||
(StyleRef().MaskBoxImage().GetImage() &&
@@ -1819,7 +1837,7 @@ void LayoutBox::ImageChanged(WrappedImagePtr image,
}
}
- ShapeValue* shape_outside_value = Style()->ShapeOutside();
+ ShapeValue* shape_outside_value = StyleRef().ShapeOutside();
if (!GetFrameView()->IsInPerformLayout() && IsFloating() &&
shape_outside_value && shape_outside_value->GetImage() &&
shape_outside_value->GetImage()->Data() == image) {
@@ -1861,14 +1879,14 @@ void LayoutBox::LocationChanged() {
// The location may change because of layout of other objects. Should check
// this object for paint invalidation.
if (!NeedsLayout())
- SetMayNeedPaintInvalidation();
+ SetShouldCheckForPaintInvalidation();
}
void LayoutBox::SizeChanged() {
// The size may change because of layout of other objects. Should check this
// object for paint invalidation.
if (!NeedsLayout())
- SetMayNeedPaintInvalidation();
+ SetShouldCheckForPaintInvalidation();
if (GetNode() && GetNode()->IsElementNode()) {
Element& element = ToElement(*GetNode());
@@ -1892,25 +1910,23 @@ void LayoutBox::EnsureIsReadyForPaintInvalidation() {
if (MayNeedPaintInvalidationAnimatedBackgroundImage() &&
!BackgroundIsKnownToBeObscured()) {
SetShouldDoFullPaintInvalidationWithoutGeometryChange(
- PaintInvalidationReason::kDelayedFull);
+ PaintInvalidationReason::kBackground);
+ SetShouldDelayFullPaintInvalidation();
}
- if (FullPaintInvalidationReason() != PaintInvalidationReason::kDelayedFull ||
- !IntersectsVisibleViewport())
+ if (!ShouldDelayFullPaintInvalidation() || !IntersectsVisibleViewport())
return;
- // Do regular full paint invalidation if the object with
- // PaintInvalidationReason::kDelayedFull is onscreen.
- // Conservatively assume the delayed paint invalidation was caused by
- // background image change.
+ // Do regular full paint invalidation if the object with delayed paint
+ // invalidation is onscreen. Conservatively assume the delayed paint
+ // invalidation was caused by background image change.
SetBackgroundChangedSinceLastPaintInvalidation();
SetShouldDoFullPaintInvalidationWithoutGeometryChange(
- PaintInvalidationReason::kFull);
+ FullPaintInvalidationReason());
}
-PaintInvalidationReason LayoutBox::InvalidatePaint(
- const PaintInvalidatorContext& context) const {
- return BoxPaintInvalidator(*this, context).InvalidatePaint();
+void LayoutBox::InvalidatePaint(const PaintInvalidatorContext& context) const {
+ BoxPaintInvalidator(*this, context).InvalidatePaint();
}
LayoutRect LayoutBox::OverflowClipRect(
@@ -1918,7 +1934,7 @@ LayoutRect LayoutBox::OverflowClipRect(
OverlayScrollbarClipBehavior overlay_scrollbar_clip_behavior) const {
LayoutRect clip_rect;
- if (RootScrollerUtil::IsEffective(*this)) {
+ if (IsEffectiveRootScroller()) {
// If this box is the effective root scroller, use the viewport clipping
// rect since it will account for the URL bar correctly which the border
// box does not. We can do this because the effective root scroller is
@@ -1965,26 +1981,28 @@ LayoutRect LayoutBox::ClipRect(const LayoutPoint& location) const {
LayoutRect clip_rect =
LayoutRect(border_box_rect.Location() + location, border_box_rect.Size());
- if (!Style()->ClipLeft().IsAuto()) {
- LayoutUnit c = ValueForLength(Style()->ClipLeft(), border_box_rect.Width());
+ if (!StyleRef().ClipLeft().IsAuto()) {
+ LayoutUnit c =
+ ValueForLength(StyleRef().ClipLeft(), border_box_rect.Width());
clip_rect.Move(c, LayoutUnit());
clip_rect.Contract(c, LayoutUnit());
}
- if (!Style()->ClipRight().IsAuto())
+ if (!StyleRef().ClipRight().IsAuto())
clip_rect.Contract(
- Size().Width() - ValueForLength(Style()->ClipRight(), Size().Width()),
+ Size().Width() - ValueForLength(StyleRef().ClipRight(), Size().Width()),
LayoutUnit());
- if (!Style()->ClipTop().IsAuto()) {
- LayoutUnit c = ValueForLength(Style()->ClipTop(), border_box_rect.Height());
+ if (!StyleRef().ClipTop().IsAuto()) {
+ LayoutUnit c =
+ ValueForLength(StyleRef().ClipTop(), border_box_rect.Height());
clip_rect.Move(LayoutUnit(), c);
clip_rect.Contract(LayoutUnit(), c);
}
- if (!Style()->ClipBottom().IsAuto()) {
+ if (!StyleRef().ClipBottom().IsAuto()) {
clip_rect.Contract(LayoutUnit(),
- Size().Height() - ValueForLength(Style()->ClipBottom(),
+ Size().Height() - ValueForLength(StyleRef().ClipBottom(),
Size().Height()));
}
@@ -2122,7 +2140,7 @@ LayoutUnit LayoutBox::PerpendicularContainingBlockLogicalHeight() const {
void LayoutBox::MapLocalToAncestor(const LayoutBoxModelObject* ancestor,
TransformState& transform_state,
MapCoordinatesFlags mode) const {
- bool is_fixed_pos = Style()->GetPosition() == EPosition::kFixed;
+ bool is_fixed_pos = StyleRef().GetPosition() == EPosition::kFixed;
// If this box has a transform or contains paint, it acts as a fixed position
// container for fixed descendants, and may itself also be fixed position. So
@@ -2141,7 +2159,7 @@ void LayoutBox::MapAncestorToLocal(const LayoutBoxModelObject* ancestor,
if (this == ancestor)
return;
- bool is_fixed_pos = Style()->GetPosition() == EPosition::kFixed;
+ bool is_fixed_pos = StyleRef().GetPosition() == EPosition::kFixed;
// If this box has a transform or contains paint, it acts as a fixed position
// container for fixed descendants, and may itself also be fixed position. So
@@ -2169,7 +2187,7 @@ LayoutSize LayoutBox::OffsetFromContainerInternal(
offset += OffsetFromScrollableContainer(o, ignore_scroll_offset);
if (IsOutOfFlowPositioned() && o->IsLayoutInline() &&
- o->CanContainOutOfFlowPositionedElement(Style()->GetPosition())) {
+ o->CanContainOutOfFlowPositionedElement(StyleRef().GetPosition())) {
offset += ToLayoutInline(o)->OffsetForInFlowPositionedInline(*this);
}
@@ -2181,7 +2199,9 @@ InlineBox* LayoutBox::CreateInlineBox() {
}
void LayoutBox::DirtyLineBoxes(bool full_layout) {
- if (inline_box_wrapper_) {
+ if (IsInLayoutNGInlineFormattingContext()) {
+ SetFirstInlineFragment(nullptr);
+ } else if (inline_box_wrapper_) {
if (full_layout) {
inline_box_wrapper_->Destroy();
inline_box_wrapper_ = nullptr;
@@ -2191,10 +2211,24 @@ void LayoutBox::DirtyLineBoxes(bool full_layout) {
}
}
+void LayoutBox::SetFirstInlineFragment(NGPaintFragment* fragment) {
+ CHECK(IsInLayoutNGInlineFormattingContext()) << *this;
+ NGPaintFragment::ResetInlineFragmentsFor(this);
+ first_paint_fragment_ = fragment;
+}
+
+void LayoutBox::InLayoutNGInlineFormattingContextWillChange(bool new_value) {
+ DeleteLineBoxWrapper();
+
+ // Because |first_paint_fragment_| and |inline_box_wrapper_| are union, when
+ // one is deleted, the other should be initialized to nullptr.
+ DCHECK(new_value ? !first_paint_fragment_ : !inline_box_wrapper_);
+}
+
void LayoutBox::PositionLineBox(InlineBox* box) {
if (IsOutOfFlowPositioned()) {
// Cache the x position only if we were an INLINE type originally.
- bool originally_inline = Style()->IsOriginalDisplayInlineType();
+ bool originally_inline = StyleRef().IsOriginalDisplayInlineType();
if (originally_inline) {
// The value is cached in the xPos of the box. We only need this value if
// our object was inline originally, since otherwise it would have ended
@@ -2226,7 +2260,7 @@ void LayoutBox::MoveWithEdgeOfInlineContainerIfNecessary(bool is_horizontal) {
DCHECK(IsOutOfFlowPositioned());
DCHECK(Container()->IsLayoutInline());
DCHECK(Container()->CanContainOutOfFlowPositionedElement(
- Style()->GetPosition()));
+ StyleRef().GetPosition()));
// If this object is inside a relative positioned inline and its inline
// position is an explicit offset from the edge of its container then it will
// need to move if its inline container has changed width. We do not track if
@@ -2234,12 +2268,14 @@ void LayoutBox::MoveWithEdgeOfInlineContainerIfNecessary(bool is_horizontal) {
// inside it, so it probably has - mark our object for layout so that it can
// move to the new offset created by the new width.
if (!NormalChildNeedsLayout() &&
- !Style()->HasStaticInlinePosition(is_horizontal))
+ !StyleRef().HasStaticInlinePosition(is_horizontal))
SetChildNeedsLayout(kMarkOnlyThis);
}
void LayoutBox::DeleteLineBoxWrapper() {
- if (inline_box_wrapper_) {
+ if (IsInLayoutNGInlineFormattingContext()) {
+ SetFirstInlineFragment(nullptr);
+ } else if (inline_box_wrapper_) {
if (!DocumentBeingDestroyed())
inline_box_wrapper_->Remove();
inline_box_wrapper_->Destroy();
@@ -2336,7 +2372,7 @@ bool LayoutBox::IsBreakInsideControllable(EBreakInside break_value) const {
}
EBreakBetween LayoutBox::BreakAfter() const {
- EBreakBetween break_value = Style()->BreakAfter();
+ EBreakBetween break_value = StyleRef().BreakAfter();
if (break_value == EBreakBetween::kAuto ||
IsBreakBetweenControllable(break_value))
return break_value;
@@ -2344,7 +2380,7 @@ EBreakBetween LayoutBox::BreakAfter() const {
}
EBreakBetween LayoutBox::BreakBefore() const {
- EBreakBetween break_value = Style()->BreakBefore();
+ EBreakBetween break_value = StyleRef().BreakBefore();
if (break_value == EBreakBetween::kAuto ||
IsBreakBetweenControllable(break_value))
return break_value;
@@ -2352,7 +2388,7 @@ EBreakBetween LayoutBox::BreakBefore() const {
}
EBreakInside LayoutBox::BreakInside() const {
- EBreakInside break_value = Style()->BreakInside();
+ EBreakInside break_value = StyleRef().BreakInside();
if (break_value == EBreakInside::kAuto ||
IsBreakInsideControllable(break_value))
return break_value;
@@ -2423,7 +2459,7 @@ void LayoutBox::InflateVisualRectForFilterUnderContainer(
// Convert rect into coordinate space of parent to apply parent's
// reflection and filter.
LayoutSize parent_offset =
- parent->OffsetFromAncestorContainer(&container);
+ parent->OffsetFromAncestor(&container);
transform_state.Move(-parent_offset);
ToLayoutBox(parent)->InflateVisualRectForFilter(transform_state);
transform_state.Move(parent_offset);
@@ -2504,7 +2540,7 @@ bool LayoutBox::MapToVisualRectInAncestorSpaceInternal(
return false;
if (skip_info.AncestorSkipped()) {
- bool preserve3D = container->Style()->Preserves3D();
+ bool preserve3D = container->StyleRef().Preserves3D();
TransformState::TransformAccumulation accumulation =
preserve3D ? TransformState::kAccumulateTransform
: TransformState::kFlattenTransform;
@@ -2512,7 +2548,7 @@ bool LayoutBox::MapToVisualRectInAncestorSpaceInternal(
// If the ancestor is below the container, then we need to map the rect into
// ancestor's coordinates.
LayoutSize container_offset =
- ancestor->OffsetFromAncestorContainer(container);
+ ancestor->OffsetFromAncestor(container);
transform_state.Move(-container_offset, accumulation);
return true;
}
@@ -2597,7 +2633,7 @@ static float GetMaxWidthListMarker(const LayoutBox* layout_object) {
Node* parent_node = layout_object->GeneratingNode();
DCHECK(parent_node);
DCHECK(IsHTMLOListElement(parent_node) || IsHTMLUListElement(parent_node));
- DCHECK_NE(layout_object->Style()->TextAutosizingMultiplier(), 1);
+ DCHECK_NE(layout_object->StyleRef().TextAutosizingMultiplier(), 1);
#endif
float max_width = 0;
for (LayoutObject* child = layout_object->SlowFirstChild(); child;
@@ -2648,8 +2684,9 @@ void LayoutBox::ComputeLogicalWidth(
// https://bugs.webkit.org/show_bug.cgi?id=46418
bool in_vertical_box =
Parent()->IsDeprecatedFlexibleBox() &&
- (Parent()->Style()->BoxOrient() == EBoxOrient::kVertical);
- bool stretching = (Parent()->Style()->BoxAlign() == EBoxAlignment::kStretch);
+ (Parent()->StyleRef().BoxOrient() == EBoxOrient::kVertical);
+ bool stretching =
+ (Parent()->StyleRef().BoxAlign() == EBoxAlignment::kStretch);
// TODO (lajava): Stretching is the only reason why we don't want the box to
// be treated as a replaced element, so we could perhaps refactor all this
// logic, not only for flex and grid since alignment is intended to be applied
@@ -2707,7 +2744,7 @@ void LayoutBox::ComputeLogicalWidth(
ComputeMarginsForDirection(
kInlineDirection, cb, container_logical_width, computed_values.extent_,
computed_values.margins_.start_, computed_values.margins_.end_,
- Style()->MarginStart(), Style()->MarginEnd());
+ StyleRef().MarginStart(), StyleRef().MarginEnd());
if (!has_perpendicular_containing_block && container_logical_width &&
container_logical_width !=
@@ -2717,8 +2754,8 @@ void LayoutBox::ComputeLogicalWidth(
!cb->IsLayoutGrid()) {
LayoutUnit new_margin_total =
container_logical_width - computed_values.extent_;
- bool has_inverted_direction = cb->Style()->IsLeftToRightDirection() !=
- Style()->IsLeftToRightDirection();
+ bool has_inverted_direction = cb->StyleRef().IsLeftToRightDirection() !=
+ StyleRef().IsLeftToRightDirection();
if (has_inverted_direction) {
computed_values.margins_.start_ =
new_margin_total - computed_values.margins_.end_;
@@ -2738,8 +2775,8 @@ void LayoutBox::ComputeLogicalWidth(
const float adjusted_margin =
(1 - 1.0 / style_to_use.TextAutosizingMultiplier()) *
GetMaxWidthListMarker(this);
- bool has_inverted_direction = cb->Style()->IsLeftToRightDirection() !=
- Style()->IsLeftToRightDirection();
+ bool has_inverted_direction = cb->StyleRef().IsLeftToRightDirection() !=
+ StyleRef().IsLeftToRightDirection();
if (has_inverted_direction)
computed_values.margins_.end_ += adjusted_margin;
else
@@ -2766,9 +2803,9 @@ LayoutUnit LayoutBox::FillAvailableMeasure(LayoutUnit available_logical_width,
LayoutUnit available_size_for_resolving_margin =
isOrthogonalElement ? ContainingBlockLogicalWidthForContent()
: available_logical_width;
- margin_start = MinimumValueForLength(Style()->MarginStart(),
+ margin_start = MinimumValueForLength(StyleRef().MarginStart(),
available_size_for_resolving_margin);
- margin_end = MinimumValueForLength(Style()->MarginEnd(),
+ margin_end = MinimumValueForLength(StyleRef().MarginEnd(),
available_size_for_resolving_margin);
LayoutUnit available = available_logical_width - margin_start - margin_end;
available = std::max(available, LayoutUnit());
@@ -2874,15 +2911,15 @@ bool LayoutBox::ColumnFlexItemHasStretchAlignment() const {
bool LayoutBox::IsStretchingColumnFlexItem() const {
LayoutObject* parent = Parent();
if (parent->IsDeprecatedFlexibleBox() &&
- parent->Style()->BoxOrient() == EBoxOrient::kVertical &&
- parent->Style()->BoxAlign() == EBoxAlignment::kStretch)
+ parent->StyleRef().BoxOrient() == EBoxOrient::kVertical &&
+ parent->StyleRef().BoxAlign() == EBoxAlignment::kStretch)
return true;
// We don't stretch multiline flexboxes because they need to apply line
// spacing (align-content) first.
if (parent->IsFlexibleBox() &&
- parent->Style()->FlexWrap() == EFlexWrap::kNowrap &&
- parent->Style()->IsColumnFlexDirection() &&
+ parent->StyleRef().FlexWrap() == EFlexWrap::kNowrap &&
+ parent->StyleRef().IsColumnFlexDirection() &&
ColumnFlexItemHasStretchAlignment())
return true;
return false;
@@ -2930,8 +2967,8 @@ bool LayoutBox::SizesLogicalWidthToFitContent(
if (Parent()->IsFlexibleBox()) {
// For multiline columns, we need to apply align-content first, so we can't
// stretch now.
- if (!Parent()->Style()->IsColumnFlexDirection() ||
- Parent()->Style()->FlexWrap() != EFlexWrap::kNowrap)
+ if (!Parent()->StyleRef().IsColumnFlexDirection() ||
+ Parent()->StyleRef().FlexWrap() != EFlexWrap::kNowrap)
return true;
if (!ColumnFlexItemHasStretchAlignment())
return true;
@@ -2943,8 +2980,8 @@ bool LayoutBox::SizesLogicalWidthToFitContent(
// FIXME: Think about writing-mode here.
// https://bugs.webkit.org/show_bug.cgi?id=46473
if (Parent()->IsDeprecatedFlexibleBox() &&
- (Parent()->Style()->BoxOrient() == EBoxOrient::kHorizontal ||
- Parent()->Style()->BoxAlign() != EBoxAlignment::kStretch))
+ (Parent()->StyleRef().BoxOrient() == EBoxOrient::kHorizontal ||
+ Parent()->StyleRef().BoxAlign() != EBoxAlignment::kStretch))
return true;
// Button, input, select, textarea, and legend treat width value of 'auto' as
@@ -3025,7 +3062,7 @@ void LayoutBox::ComputeMarginsForDirection(MarginDirection flow_direction,
// width of the containing block, then any 'auto' values for 'margin-left' or
// 'margin-right' are, for the following rules, treated as zero.
LayoutUnit margin_box_width =
- child_width + (!Style()->Width().IsAuto()
+ child_width + (!StyleRef().Width().IsAuto()
? margin_start_width + margin_end_width
: LayoutUnit());
@@ -3101,8 +3138,8 @@ void LayoutBox::UpdateLogicalHeight() {
static inline Length HeightForDocumentElement(const Document& document) {
return document.documentElement()
->GetLayoutObject()
- ->Style()
- ->LogicalHeight();
+ ->StyleRef()
+ .LogicalHeight();
}
void LayoutBox::ComputeLogicalHeight(
@@ -3151,8 +3188,8 @@ void LayoutBox::ComputeLogicalHeight(
ComputeMarginsForDirection(
flow_direction, cb, ContainingBlockLogicalWidthForContent(),
computed_values.extent_, computed_values.margins_.before_,
- computed_values.margins_.after_, Style()->MarginBefore(),
- Style()->MarginAfter());
+ computed_values.margins_.after_, StyleRef().MarginBefore(),
+ StyleRef().MarginAfter());
return;
}
@@ -3160,8 +3197,9 @@ void LayoutBox::ComputeLogicalHeight(
// https://bugs.webkit.org/show_bug.cgi?id=46418
bool in_horizontal_box =
Parent()->IsDeprecatedFlexibleBox() &&
- Parent()->Style()->BoxOrient() == EBoxOrient::kHorizontal;
- bool stretching = Parent()->Style()->BoxAlign() == EBoxAlignment::kStretch;
+ 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;
@@ -3175,7 +3213,7 @@ void LayoutBox::ComputeLogicalHeight(
ComputeReplacedLogicalHeight() + BorderAndPaddingLogicalHeight(),
kFixed);
} else {
- h = Style()->LogicalHeight();
+ h = StyleRef().LogicalHeight();
check_min_max_height = true;
}
@@ -3193,7 +3231,7 @@ void LayoutBox::ComputeLogicalHeight(
LayoutUnit height_result;
if (check_min_max_height) {
height_result = ComputeLogicalHeightUsing(
- kMainOrPreferredSize, Style()->LogicalHeight(),
+ kMainOrPreferredSize, StyleRef().LogicalHeight(),
computed_values.extent_ - BorderAndPaddingLogicalHeight());
if (height_result == -1)
height_result = computed_values.extent_;
@@ -3209,8 +3247,8 @@ void LayoutBox::ComputeLogicalHeight(
ComputeMarginsForDirection(
flow_direction, cb, ContainingBlockLogicalWidthForContent(),
computed_values.extent_, computed_values.margins_.before_,
- computed_values.margins_.after_, Style()->MarginBefore(),
- Style()->MarginAfter());
+ computed_values.margins_.after_, StyleRef().MarginBefore(),
+ StyleRef().MarginAfter());
}
// WinIE quirk: The <html> block always fills the entire canvas in quirks
@@ -3339,7 +3377,7 @@ LayoutUnit LayoutBox::ComputeContentAndScrollbarLogicalHeightUsing(
bool LayoutBox::StretchesToViewportInQuirksMode() const {
if (!IsDocumentElement() && !IsBody())
return false;
- return Style()->LogicalHeight().IsAuto() &&
+ return StyleRef().LogicalHeight().IsAuto() &&
!IsFloatingOrOutOfFlowPositioned() && !IsInline() &&
!FlowThreadContainingBlock();
}
@@ -3369,7 +3407,7 @@ bool LayoutBox::SkipContainingBlockForPercentHeightCalculation(
return GetDocument().InQuirksMode() && !containing_block->IsTableCell() &&
!containing_block->IsOutOfFlowPositioned() &&
!containing_block->IsLayoutGrid() &&
- containing_block->Style()->LogicalHeight().IsAuto();
+ containing_block->StyleRef().LogicalHeight().IsAuto();
}
LayoutUnit LayoutBox::ComputePercentageLogicalHeight(
@@ -3411,11 +3449,11 @@ LayoutUnit LayoutBox::ComputePercentageLogicalHeight(
// height if they have overflow set to visible or hidden or if
// they are replaced elements, and a 0px height if they have not.
LayoutTableCell* cell = ToLayoutTableCell(cb);
- if (Style()->OverflowY() != EOverflow::kVisible &&
- Style()->OverflowY() != EOverflow::kHidden &&
+ if (StyleRef().OverflowY() != EOverflow::kVisible &&
+ StyleRef().OverflowY() != EOverflow::kHidden &&
!ShouldBeConsideredAsReplaced() &&
- (!cell->Style()->LogicalHeight().IsAuto() ||
- !cell->Table()->Style()->LogicalHeight().IsAuto()))
+ (!cell->StyleRef().LogicalHeight().IsAuto() ||
+ !cell->Table()->StyleRef().LogicalHeight().IsAuto()))
return LayoutUnit();
return LayoutUnit(-1);
}
@@ -3446,7 +3484,7 @@ LayoutUnit LayoutBox::ComputePercentageLogicalHeight(
IsTable() ||
(cb->IsTableCell() && !skipped_auto_height_containing_block &&
cb->HasOverrideLogicalHeight() &&
- Style()->BoxSizing() == EBoxSizing::kContentBox);
+ StyleRef().BoxSizing() == EBoxSizing::kContentBox);
if (subtract_border_and_padding) {
result -= BorderAndPaddingLogicalHeight();
return std::max(LayoutUnit(), result);
@@ -3458,7 +3496,7 @@ LayoutUnit LayoutBox::ComputeReplacedLogicalWidth(
ShouldComputePreferred should_compute_preferred) const {
return ComputeReplacedLogicalWidthRespectingMinMaxWidth(
ComputeReplacedLogicalWidthUsing(kMainOrPreferredSize,
- Style()->LogicalWidth()),
+ StyleRef().LogicalWidth()),
should_compute_preferred);
}
@@ -3467,17 +3505,17 @@ LayoutUnit LayoutBox::ComputeReplacedLogicalWidthRespectingMinMaxWidth(
ShouldComputePreferred should_compute_preferred) const {
LayoutUnit min_logical_width =
(should_compute_preferred == kComputePreferred &&
- Style()->LogicalMinWidth().IsPercentOrCalc())
+ StyleRef().LogicalMinWidth().IsPercentOrCalc())
? logical_width
: ComputeReplacedLogicalWidthUsing(kMinSize,
- Style()->LogicalMinWidth());
+ StyleRef().LogicalMinWidth());
LayoutUnit max_logical_width =
(should_compute_preferred == kComputePreferred &&
- Style()->LogicalMaxWidth().IsPercentOrCalc()) ||
- Style()->LogicalMaxWidth().IsMaxSizeNone()
+ StyleRef().LogicalMaxWidth().IsPercentOrCalc()) ||
+ StyleRef().LogicalMaxWidth().IsMaxSizeNone()
? logical_width
: ComputeReplacedLogicalWidthUsing(kMaxSize,
- Style()->LogicalMaxWidth());
+ StyleRef().LogicalMaxWidth());
return std::max(min_logical_width,
std::min(logical_width, max_logical_width));
}
@@ -3517,7 +3555,7 @@ LayoutUnit LayoutBox::ComputeReplacedLogicalWidthUsing(
: PerpendicularContainingBlockLogicalHeight();
}
Length container_logical_width =
- ContainingBlock()->Style()->LogicalWidth();
+ ContainingBlock()->StyleRef().LogicalWidth();
// 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())
@@ -3546,13 +3584,13 @@ LayoutUnit LayoutBox::ComputeReplacedLogicalWidthUsing(
LayoutUnit LayoutBox::ComputeReplacedLogicalHeight(LayoutUnit) const {
return ComputeReplacedLogicalHeightRespectingMinMaxHeight(
ComputeReplacedLogicalHeightUsing(kMainOrPreferredSize,
- Style()->LogicalHeight()));
+ StyleRef().LogicalHeight()));
}
bool LayoutBox::LogicalHeightComputesAsNone(SizeType size_type) const {
DCHECK(size_type == kMinSize || size_type == kMaxSize);
- Length logical_height = size_type == kMinSize ? Style()->LogicalMinHeight()
- : Style()->LogicalMaxHeight();
+ Length logical_height = size_type == kMinSize ? StyleRef().LogicalMinHeight()
+ : StyleRef().LogicalMaxHeight();
Length initial_logical_height =
size_type == kMinSize ? ComputedStyleInitialValues::InitialMinHeight()
: ComputedStyleInitialValues::InitialMaxHeight();
@@ -3572,13 +3610,15 @@ LayoutUnit LayoutBox::ComputeReplacedLogicalHeightRespectingMinMaxHeight(
// the percentage value is treated as '0' (for 'min-height') or 'none' (for
// 'max-height').
LayoutUnit min_logical_height;
- if (!LogicalHeightComputesAsNone(kMinSize))
+ if (!LogicalHeightComputesAsNone(kMinSize)) {
min_logical_height = ComputeReplacedLogicalHeightUsing(
- kMinSize, Style()->LogicalMinHeight());
+ kMinSize, StyleRef().LogicalMinHeight());
+ }
LayoutUnit max_logical_height = logical_height;
- if (!LogicalHeightComputesAsNone(kMaxSize))
+ if (!LogicalHeightComputesAsNone(kMaxSize)) {
max_logical_height = ComputeReplacedLogicalHeightUsing(
- kMaxSize, Style()->LogicalMaxHeight());
+ kMaxSize, StyleRef().LogicalMaxHeight());
+ }
return std::max(min_logical_height,
std::min(logical_height, max_logical_height));
}
@@ -3621,8 +3661,9 @@ LayoutUnit LayoutBox::ComputeReplacedLogicalHeightUsing(
}
}
- if (cb->IsOutOfFlowPositioned() && cb->Style()->Height().IsAuto() &&
- !(cb->Style()->Top().IsAuto() || cb->Style()->Bottom().IsAuto())) {
+ if (cb->IsOutOfFlowPositioned() && cb->StyleRef().Height().IsAuto() &&
+ !(cb->StyleRef().Top().IsAuto() ||
+ cb->StyleRef().Bottom().IsAuto())) {
SECURITY_DCHECK(cb->IsLayoutBlock());
LayoutBlock* block = ToLayoutBlock(cb);
LogicalExtentComputedValues computed_values;
@@ -3653,8 +3694,8 @@ LayoutUnit LayoutBox::ComputeReplacedLogicalHeightUsing(
// image are perpendicular writing-modes, this isn't right.
// https://bugs.webkit.org/show_bug.cgi?id=46997
while (cb && !cb->IsLayoutView() &&
- (cb->Style()->LogicalHeight().IsAuto() ||
- cb->Style()->LogicalHeight().IsPercentOrCalc())) {
+ (cb->StyleRef().LogicalHeight().IsAuto() ||
+ cb->StyleRef().LogicalHeight().IsPercentOrCalc())) {
if (cb->IsTableCell()) {
// Don't let table cells squeeze percent-height replaced elements
// <http://bugs.webkit.org/show_bug.cgi?id=15359>
@@ -3695,7 +3736,7 @@ LayoutUnit LayoutBox::AvailableLogicalHeight(
// This code gets executed 740 times in the test case.
// https://chromium-review.googlesource.com/c/chromium/src/+/1103289
LayoutUnit height =
- AvailableLogicalHeightUsing(Style()->LogicalHeight(), height_type);
+ AvailableLogicalHeightUsing(StyleRef().LogicalHeight(), height_type);
if (UNLIKELY(height == -1))
return height;
return ConstrainContentBoxLogicalHeightByMinMax(height, LayoutUnit(-1));
@@ -3704,7 +3745,7 @@ LayoutUnit LayoutBox::AvailableLogicalHeight(
// in the content height.
// FIXME: Should we pass intrinsicContentLogicalHeight() instead of -1 here?
return ConstrainContentBoxLogicalHeightByMinMax(
- AvailableLogicalHeightUsing(Style()->LogicalHeight(), height_type),
+ AvailableLogicalHeightUsing(StyleRef().LogicalHeight(), height_type),
LayoutUnit(-1));
}
@@ -3758,8 +3799,8 @@ LayoutUnit LayoutBox::AvailableLogicalHeightUsing(
// writing-mode.
// https://bugs.webkit.org/show_bug.cgi?id=46500
if (IsLayoutBlock() && IsOutOfFlowPositioned() &&
- Style()->Height().IsAuto() &&
- !(Style()->Top().IsAuto() || Style()->Bottom().IsAuto())) {
+ StyleRef().Height().IsAuto() &&
+ !(StyleRef().Top().IsAuto() || StyleRef().Bottom().IsAuto())) {
LayoutBlock* block = const_cast<LayoutBlock*>(ToLayoutBlock(this));
LogicalExtentComputedValues computed_values;
block->ComputeLogicalHeight(block->LogicalHeight(), LayoutUnit(),
@@ -3808,7 +3849,7 @@ LayoutUnit LayoutBox::ContainingBlockLogicalWidthForPositioned(
return ContainingBlockLogicalHeightForPositioned(containing_block, false);
// Use viewport as container for top-level fixed-position elements.
- if (Style()->GetPosition() == EPosition::kFixed &&
+ if (StyleRef().GetPosition() == EPosition::kFixed &&
containing_block->IsLayoutView() && !GetDocument().Printing()) {
const LayoutView* view = ToLayoutView(containing_block);
if (LocalFrameView* frame_view = view->GetFrameView()) {
@@ -3838,7 +3879,7 @@ LayoutUnit LayoutBox::ContainingBlockLogicalWidthForPositioned(
DCHECK(containing_block->IsLayoutInline());
DCHECK(containing_block->CanContainOutOfFlowPositionedElement(
- Style()->GetPosition()));
+ StyleRef().GetPosition()));
const LayoutInline* flow = ToLayoutInline(containing_block);
InlineFlowBox* first = flow->FirstLineBox();
@@ -3850,7 +3891,7 @@ LayoutUnit LayoutBox::ContainingBlockLogicalWidthForPositioned(
LayoutUnit from_left;
LayoutUnit from_right;
- if (containing_block->Style()->IsLeftToRightDirection()) {
+ if (containing_block->StyleRef().IsLeftToRightDirection()) {
from_left = first->LogicalLeft() + first->BorderLogicalLeft();
from_right =
last->LogicalLeft() + last->LogicalWidth() - last->BorderLogicalRight();
@@ -3871,7 +3912,7 @@ LayoutUnit LayoutBox::ContainingBlockLogicalHeightForPositioned(
return ContainingBlockLogicalWidthForPositioned(containing_block, false);
// Use viewport as container for top-level fixed-position elements.
- if (Style()->GetPosition() == EPosition::kFixed &&
+ if (StyleRef().GetPosition() == EPosition::kFixed &&
containing_block->IsLayoutView() && !GetDocument().Printing()) {
const LayoutView* view = ToLayoutView(containing_block);
if (LocalFrameView* frame_view = view->GetFrameView()) {
@@ -3893,7 +3934,7 @@ LayoutUnit LayoutBox::ContainingBlockLogicalHeightForPositioned(
DCHECK(containing_block->IsLayoutInline());
DCHECK(containing_block->CanContainOutOfFlowPositionedElement(
- Style()->GetPosition()));
+ StyleRef().GetPosition()));
const LayoutInline* flow = ToLayoutInline(containing_block);
InlineFlowBox* first = flow->FirstLineBox();
@@ -3942,7 +3983,7 @@ void LayoutBox::ComputeInlineStaticDistance(
return;
LayoutObject* parent = child->Parent();
- TextDirection parent_direction = parent->Style()->Direction();
+ TextDirection parent_direction = parent->StyleRef().Direction();
// This method is using EnclosingBox() which is wrong for absolutely
// positioned grid items, as they rely on the grid area. So for grid items if
@@ -3977,13 +4018,13 @@ void LayoutBox::ComputeInlineStaticDistance(
*ToLayoutBox(curr), static_position, static_block_position);
} else if (curr->IsInline()) {
if (curr->IsInFlowPositioned()) {
- if (!curr->Style()->LogicalLeft().IsAuto())
+ if (!curr->StyleRef().LogicalLeft().IsAuto())
static_position +=
- ValueForLength(curr->Style()->LogicalLeft(),
+ ValueForLength(curr->StyleRef().LogicalLeft(),
curr->ContainingBlock()->AvailableWidth());
else
static_position -=
- ValueForLength(curr->Style()->LogicalRight(),
+ ValueForLength(curr->StyleRef().LogicalRight(),
curr->ContainingBlock()->AvailableWidth());
}
}
@@ -4015,13 +4056,13 @@ void LayoutBox::ComputeInlineStaticDistance(
}
} else if (curr->IsInline()) {
if (curr->IsInFlowPositioned()) {
- if (!curr->Style()->LogicalLeft().IsAuto())
+ if (!curr->StyleRef().LogicalLeft().IsAuto())
static_position -=
- ValueForLength(curr->Style()->LogicalLeft(),
+ ValueForLength(curr->StyleRef().LogicalLeft(),
curr->ContainingBlock()->AvailableWidth());
else
static_position +=
- ValueForLength(curr->Style()->LogicalRight(),
+ ValueForLength(curr->StyleRef().LogicalRight(),
curr->ContainingBlock()->AvailableWidth());
}
}
@@ -4061,17 +4102,17 @@ void LayoutBox::ComputePositionedLogicalWidth(
// Use the container block's direction except when calculating the static
// distance. This conforms with the reference results for
// abspos-replaced-width-margin-000.htm of the CSS 2.1 test suite.
- TextDirection container_direction = container_block->Style()->Direction();
+ TextDirection container_direction = container_block->StyleRef().Direction();
bool is_horizontal = IsHorizontalWritingMode();
const LayoutUnit borders_plus_padding = BorderAndPaddingLogicalWidth();
const Length margin_logical_left =
- is_horizontal ? Style()->MarginLeft() : Style()->MarginTop();
+ is_horizontal ? StyleRef().MarginLeft() : StyleRef().MarginTop();
const Length margin_logical_right =
- is_horizontal ? Style()->MarginRight() : Style()->MarginBottom();
+ is_horizontal ? StyleRef().MarginRight() : StyleRef().MarginBottom();
- Length logical_left_length = Style()->LogicalLeft();
- Length logical_right_length = Style()->LogicalRight();
+ Length logical_left_length = StyleRef().LogicalLeft();
+ Length logical_right_length = StyleRef().LogicalRight();
// ---------------------------------------------------------------------------
// For the purposes of this section and the next, the term "static position"
// (of an element) refers, roughly, to the position an element would have had
@@ -4102,17 +4143,17 @@ void LayoutBox::ComputePositionedLogicalWidth(
// Calculate constraint equation values for 'width' case.
ComputePositionedLogicalWidthUsing(
- kMainOrPreferredSize, Style()->LogicalWidth(), container_block,
+ kMainOrPreferredSize, StyleRef().LogicalWidth(), container_block,
container_direction, container_logical_width, borders_plus_padding,
logical_left_length, logical_right_length, margin_logical_left,
margin_logical_right, computed_values);
// Calculate constraint equation values for 'max-width' case.
- if (!Style()->LogicalMaxWidth().IsMaxSizeNone()) {
+ if (!StyleRef().LogicalMaxWidth().IsMaxSizeNone()) {
LogicalExtentComputedValues max_values;
ComputePositionedLogicalWidthUsing(
- kMaxSize, Style()->LogicalMaxWidth(), container_block,
+ kMaxSize, StyleRef().LogicalMaxWidth(), container_block,
container_direction, container_logical_width, borders_plus_padding,
logical_left_length, logical_right_length, margin_logical_left,
margin_logical_right, max_values);
@@ -4126,12 +4167,12 @@ void LayoutBox::ComputePositionedLogicalWidth(
}
// Calculate constraint equation values for 'min-width' case.
- if (!Style()->LogicalMinWidth().IsZero() ||
- Style()->LogicalMinWidth().IsIntrinsic()) {
+ if (!StyleRef().LogicalMinWidth().IsZero() ||
+ StyleRef().LogicalMinWidth().IsIntrinsic()) {
LogicalExtentComputedValues min_values;
ComputePositionedLogicalWidthUsing(
- kMinSize, Style()->LogicalMinWidth(), container_block,
+ kMinSize, StyleRef().LogicalMinWidth(), container_block,
container_direction, container_logical_width, borders_plus_padding,
logical_left_length, logical_right_length, margin_logical_left,
margin_logical_right, min_values);
@@ -4159,7 +4200,7 @@ void LayoutBox::ComputeLogicalLeftPositionedOffset(
// if the containing block is both a flipped mode and perpendicular to us.
if (container_block->IsHorizontalWritingMode() !=
child->IsHorizontalWritingMode() &&
- container_block->Style()->IsFlippedBlocksWritingMode()) {
+ container_block->StyleRef().IsFlippedBlocksWritingMode()) {
logical_left_pos =
container_logical_width - logical_width_value - logical_left_pos;
logical_left_pos +=
@@ -4228,12 +4269,12 @@ void LayoutBox::ComputePositionedLogicalWidthUsing(
bool logical_width_is_auto = logical_width.IsAuto();
bool logical_left_is_auto = logical_left.IsAuto();
bool logical_right_is_auto = logical_right.IsAuto();
- LayoutUnit& margin_logical_left_value = Style()->IsLeftToRightDirection()
+ LayoutUnit& margin_logical_left_value = StyleRef().IsLeftToRightDirection()
? computed_values.margins_.start_
: computed_values.margins_.end_;
LayoutUnit& margin_logical_right_value =
- Style()->IsLeftToRightDirection() ? computed_values.margins_.end_
- : computed_values.margins_.start_;
+ StyleRef().IsLeftToRightDirection() ? computed_values.margins_.end_
+ : computed_values.margins_.start_;
if (!logical_left_is_auto && !logical_width_is_auto &&
!logical_right_is_auto) {
// -------------------------------------------------------------------------
@@ -4394,7 +4435,7 @@ void LayoutBox::ComputePositionedLogicalWidthUsing(
// logical left position of the first line box when really it should use the
// last line box. When this is fixed elsewhere, this block should be removed.
if (container_block->IsLayoutInline() &&
- !container_block->Style()->IsLeftToRightDirection()) {
+ !container_block->StyleRef().IsLeftToRightDirection()) {
const LayoutInline* flow = ToLayoutInline(container_block);
InlineFlowBox* first_line = flow->FirstLineBox();
InlineFlowBox* last_line = flow->LastLineBox();
@@ -4408,6 +4449,7 @@ void LayoutBox::ComputePositionedLogicalWidthUsing(
}
if (container_block->IsBox() &&
+ container_block->IsHorizontalWritingMode() == IsHorizontalWritingMode() &&
ToLayoutBox(container_block)->ScrollsOverflowY() &&
ToLayoutBox(container_block)
->ShouldPlaceBlockDirectionScrollbarOnLogicalLeft()) {
@@ -4563,11 +4605,11 @@ void LayoutBox::ComputeLogicalTopPositionedOffset(
// containing block's coordinate space. If the containing block is flipped
// along this axis, then we need to flip the coordinate. This can only happen
// if the containing block is both a flipped mode and perpendicular to us.
- if ((child->Style()->IsFlippedBlocksWritingMode() &&
+ if ((child->StyleRef().IsFlippedBlocksWritingMode() &&
child->IsHorizontalWritingMode() !=
container_block->IsHorizontalWritingMode()) ||
- (child->Style()->IsFlippedBlocksWritingMode() !=
- container_block->Style()->IsFlippedBlocksWritingMode() &&
+ (child->StyleRef().IsFlippedBlocksWritingMode() !=
+ container_block->StyleRef().IsFlippedBlocksWritingMode() &&
child->IsHorizontalWritingMode() ==
container_block->IsHorizontalWritingMode()))
logical_top_pos =
@@ -4575,7 +4617,7 @@ void LayoutBox::ComputeLogicalTopPositionedOffset(
// Our offset is from the logical bottom edge in a flipped environment, e.g.,
// right for vertical-rl.
- if (container_block->Style()->IsFlippedBlocksWritingMode() &&
+ if (container_block->StyleRef().IsFlippedBlocksWritingMode() &&
child->IsHorizontalWritingMode() ==
container_block->IsHorizontalWritingMode()) {
if (child->IsHorizontalWritingMode())
@@ -4764,6 +4806,15 @@ void LayoutBox::ComputePositionedLogicalHeightUsing(
}
computed_values.extent_ = logical_height_value;
+ if (container_block->IsBox() &&
+ container_block->IsHorizontalWritingMode() != IsHorizontalWritingMode() &&
+ ToLayoutBox(container_block)->ScrollsOverflowY() &&
+ ToLayoutBox(container_block)
+ ->ShouldPlaceBlockDirectionScrollbarOnLogicalLeft()) {
+ logical_top_value = logical_top_value +
+ ToLayoutBox(container_block)->VerticalScrollbarWidth();
+ }
+
// Use computed values to calculate the vertical position.
computed_values.position_ =
logical_top_value + computed_values.margins_.before_;
@@ -4785,7 +4836,7 @@ LayoutRect LayoutBox::LocalCaretRect(
LayoutUnit caret_width = GetFrameView()->CaretWidth();
LayoutRect rect(Location(), LayoutSize(caret_width, Size().Height()));
bool ltr =
- box ? box->IsLeftToRightDirection() : Style()->IsLeftToRightDirection();
+ box ? box->IsLeftToRightDirection() : StyleRef().IsLeftToRightDirection();
if ((!caret_offset) ^ ltr)
rect.Move(LayoutSize(Size().Width() - caret_width, LayoutUnit()));
@@ -4806,7 +4857,7 @@ LayoutRect LayoutBox::LocalCaretRect(
// giant tall-as-window insertion point
//
// FIXME: ignoring :first-line, missing good reason to take care of
- const SimpleFontData* font_data = Style()->GetFont().PrimaryFont();
+ const SimpleFontData* font_data = StyleRef().GetFont().PrimaryFont();
LayoutUnit font_height =
LayoutUnit(font_data ? font_data->GetFontMetrics().Height() : 0);
if (font_height > rect.Height() || (!IsAtomicInlineLevel() && !IsTable()))
@@ -4868,7 +4919,7 @@ PositionWithAffinity LayoutBox::PositionForPoint(
layout_object = layout_object->NextSibling()) {
if ((!layout_object->SlowFirstChild() && !layout_object->IsInline() &&
!layout_object->IsLayoutBlockFlow()) ||
- layout_object->Style()->Visibility() != EVisibility::kVisible)
+ layout_object->StyleRef().Visibility() != EVisibility::kVisible)
continue;
if (!layout_object->IsBox())
@@ -4943,7 +4994,7 @@ bool LayoutBox::ShrinkToAvoidFloats() const {
return false;
// Only auto width objects can possibly shrink to avoid floats.
- if (!Style()->Width().IsAuto())
+ if (!StyleRef().Width().IsAuto())
return false;
// If the containing block is LayoutNG, we will not let legacy layout deal
@@ -5085,7 +5136,7 @@ bool LayoutBox::IsRenderedLegend() const {
}
void LayoutBox::AddVisualEffectOverflow() {
- if (!Style()->HasVisualOverflowingEffect())
+ if (!StyleRef().HasVisualOverflowingEffect())
return;
// Add in the final overflow with shadows, outsets and outline combined.
@@ -5160,11 +5211,11 @@ void LayoutBox::AddOverflowFromChild(const LayoutBox& child,
}
bool LayoutBox::HasTopOverflow() const {
- return !Style()->IsLeftToRightDirection() && !IsHorizontalWritingMode();
+ return !StyleRef().IsLeftToRightDirection() && !IsHorizontalWritingMode();
}
bool LayoutBox::HasLeftOverflow() const {
- return !Style()->IsLeftToRightDirection() && IsHorizontalWritingMode();
+ return !StyleRef().IsLeftToRightDirection() && IsHorizontalWritingMode();
}
DISABLE_CFI_PERF
@@ -5285,14 +5336,14 @@ bool LayoutBox::HasUnsplittableScrollingOverflow() const {
// under these conditions, but it should work out to be good enough for common
// cases. Paginating overflow with scrollbars present is not the end of the
// world and is what we used to do in the old model anyway.
- return !Style()->LogicalHeight().IsIntrinsicOrAuto() ||
- (!Style()->LogicalMaxHeight().IsIntrinsicOrAuto() &&
- !Style()->LogicalMaxHeight().IsMaxSizeNone() &&
- (!Style()->LogicalMaxHeight().IsPercentOrCalc() ||
+ return !StyleRef().LogicalHeight().IsIntrinsicOrAuto() ||
+ (!StyleRef().LogicalMaxHeight().IsIntrinsicOrAuto() &&
+ !StyleRef().LogicalMaxHeight().IsMaxSizeNone() &&
+ (!StyleRef().LogicalMaxHeight().IsPercentOrCalc() ||
PercentageLogicalHeightIsResolvable())) ||
- (!Style()->LogicalMinHeight().IsIntrinsicOrAuto() &&
- Style()->LogicalMinHeight().IsPositive() &&
- (!Style()->LogicalMinHeight().IsPercentOrCalc() ||
+ (!StyleRef().LogicalMinHeight().IsIntrinsicOrAuto() &&
+ StyleRef().LogicalMinHeight().IsPositive() &&
+ (!StyleRef().LogicalMinHeight().IsPercentOrCalc() ||
PercentageLogicalHeightIsResolvable()));
}
@@ -5301,7 +5352,8 @@ LayoutBox::PaginationBreakability LayoutBox::GetPaginationBreakability() const {
// actually look for replaced elements.
if (IsAtomicInlineLevel() || HasUnsplittableScrollingOverflow() ||
(Parent() && IsWritingModeRoot()) ||
- (IsOutOfFlowPositioned() && Style()->GetPosition() == EPosition::kFixed))
+ (IsOutOfFlowPositioned() &&
+ StyleRef().GetPosition() == EPosition::kFixed))
return kForbidBreaks;
EBreakInside break_value = BreakInside();
@@ -5493,7 +5545,7 @@ LayoutUnit LayoutBox::OffsetTop(const Element* parent) const {
LayoutPoint LayoutBox::FlipForWritingModeForChild(
const LayoutBox* child,
const LayoutPoint& point) const {
- if (!Style()->IsFlippedBlocksWritingMode())
+ if (!StyleRef().IsFlippedBlocksWritingMode())
return point;
// The child is going to add in its x(), so we have to make sure it ends up in
@@ -5531,15 +5583,15 @@ LayoutPoint LayoutBox::PhysicalLocation(
}
bool LayoutBox::HasRelativeLogicalWidth() const {
- return Style()->LogicalWidth().IsPercentOrCalc() ||
- Style()->LogicalMinWidth().IsPercentOrCalc() ||
- Style()->LogicalMaxWidth().IsPercentOrCalc();
+ return StyleRef().LogicalWidth().IsPercentOrCalc() ||
+ StyleRef().LogicalMinWidth().IsPercentOrCalc() ||
+ StyleRef().LogicalMaxWidth().IsPercentOrCalc();
}
bool LayoutBox::HasRelativeLogicalHeight() const {
- return Style()->LogicalHeight().IsPercentOrCalc() ||
- Style()->LogicalMinHeight().IsPercentOrCalc() ||
- Style()->LogicalMaxHeight().IsPercentOrCalc();
+ return StyleRef().LogicalHeight().IsPercentOrCalc() ||
+ StyleRef().LogicalMinHeight().IsPercentOrCalc() ||
+ StyleRef().LogicalMaxHeight().IsPercentOrCalc();
}
static void MarkBoxForRelayoutAfterSplit(LayoutBox* box) {
@@ -5759,18 +5811,18 @@ bool LayoutBox::MustInvalidateFillLayersPaintOnWidthChange(
bool LayoutBox::MustInvalidateBackgroundOrBorderPaintOnWidthChange() const {
if (HasMask() &&
- MustInvalidateFillLayersPaintOnWidthChange(Style()->MaskLayers()))
+ MustInvalidateFillLayersPaintOnWidthChange(StyleRef().MaskLayers()))
return true;
// If we don't have a background/border/mask, then nothing to do.
if (!HasBoxDecorationBackground())
return false;
- if (MustInvalidateFillLayersPaintOnWidthChange(Style()->BackgroundLayers()))
+ if (MustInvalidateFillLayersPaintOnWidthChange(StyleRef().BackgroundLayers()))
return true;
// Our fill layers are ok. Let's check border.
- if (Style()->CanRenderBorderImage())
+ if (StyleRef().CanRenderBorderImage())
return true;
return false;
@@ -5778,18 +5830,19 @@ bool LayoutBox::MustInvalidateBackgroundOrBorderPaintOnWidthChange() const {
bool LayoutBox::MustInvalidateBackgroundOrBorderPaintOnHeightChange() const {
if (HasMask() &&
- MustInvalidateFillLayersPaintOnHeightChange(Style()->MaskLayers()))
+ MustInvalidateFillLayersPaintOnHeightChange(StyleRef().MaskLayers()))
return true;
// If we don't have a background/border/mask, then nothing to do.
if (!HasBoxDecorationBackground())
return false;
- if (MustInvalidateFillLayersPaintOnHeightChange(Style()->BackgroundLayers()))
+ if (MustInvalidateFillLayersPaintOnHeightChange(
+ StyleRef().BackgroundLayers()))
return true;
// Our fill layers are ok. Let's check border.
- if (Style()->CanRenderBorderImage())
+ if (StyleRef().CanRenderBorderImage())
return true;
return false;
@@ -6038,10 +6091,11 @@ bool LayoutBox::ComputeShouldClipOverflow() const {
}
void LayoutBox::MutableForPainting::
- SavePreviousContentBoxSizeAndLayoutOverflowRect() {
+ SavePreviousContentBoxRectAndLayoutOverflowRect() {
auto& rare_data = GetLayoutBox().EnsureRareData();
- rare_data.has_previous_content_box_size_and_layout_overflow_rect_ = true;
- rare_data.previous_content_box_size_ = GetLayoutBox().ContentSize();
+ rare_data.has_previous_content_box_rect_and_layout_overflow_rect_ = true;
+ rare_data.previous_physical_content_box_rect_ =
+ GetLayoutBox().PhysicalContentBoxRect();
rare_data.previous_physical_layout_overflow_rect_ =
GetLayoutBox().PhysicalLayoutOverflowRect();
}
@@ -6066,7 +6120,7 @@ TextDirection LayoutBox::ResolvedDirection() const {
if (InlineBoxWrapper())
return InlineBoxWrapper()->Direction();
}
- return Style()->Direction();
+ return StyleRef().Direction();
}
} // 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 f780aa5975a..944172fdafe 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_box.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_box.h
@@ -70,7 +70,7 @@ struct LayoutBoxRareData {
override_logical_height_(-1),
has_override_containing_block_content_logical_width_(false),
has_override_containing_block_content_logical_height_(false),
- has_previous_content_box_size_and_layout_overflow_rect_(false),
+ has_previous_content_box_rect_and_layout_overflow_rect_(false),
percent_height_container_(nullptr),
snap_container_(nullptr),
snap_areas_(nullptr) {}
@@ -84,7 +84,7 @@ struct LayoutBoxRareData {
bool has_override_containing_block_content_logical_width_ : 1;
bool has_override_containing_block_content_logical_height_ : 1;
- bool has_previous_content_box_size_and_layout_overflow_rect_ : 1;
+ bool has_previous_content_box_rect_and_layout_overflow_rect_ : 1;
LayoutUnit override_containing_block_content_logical_width_;
LayoutUnit override_containing_block_content_logical_height_;
@@ -109,8 +109,8 @@ struct LayoutBoxRareData {
// Used by BoxPaintInvalidator. Stores the previous content box size and
// layout overflow rect after the last paint invalidation. They are valid if
- // m_hasPreviousContentBoxSizeAndLayoutOverflowRect is true.
- LayoutSize previous_content_box_size_;
+ // has_previous_content_box_rect_and_layout_overflow_rect_ is true.
+ LayoutRect previous_physical_content_box_rect_;
LayoutRect previous_physical_layout_overflow_rect_;
// Used by LocalFrameView::ScrollIntoView. When the scroll is sequenced
@@ -262,22 +262,22 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
}
LayoutUnit LogicalLeft() const {
- return Style()->IsHorizontalWritingMode() ? frame_rect_.X()
- : frame_rect_.Y();
+ return StyleRef().IsHorizontalWritingMode() ? frame_rect_.X()
+ : frame_rect_.Y();
}
LayoutUnit LogicalRight() const { return LogicalLeft() + LogicalWidth(); }
LayoutUnit LogicalTop() const {
- return Style()->IsHorizontalWritingMode() ? frame_rect_.Y()
- : frame_rect_.X();
+ return StyleRef().IsHorizontalWritingMode() ? frame_rect_.Y()
+ : frame_rect_.X();
}
LayoutUnit LogicalBottom() const { return LogicalTop() + LogicalHeight(); }
LayoutUnit LogicalWidth() const {
- return Style()->IsHorizontalWritingMode() ? frame_rect_.Width()
- : frame_rect_.Height();
+ return StyleRef().IsHorizontalWritingMode() ? frame_rect_.Width()
+ : frame_rect_.Height();
}
LayoutUnit LogicalHeight() const {
- return Style()->IsHorizontalWritingMode() ? frame_rect_.Height()
- : frame_rect_.Width();
+ return StyleRef().IsHorizontalWritingMode() ? frame_rect_.Height()
+ : frame_rect_.Width();
}
// Logical height of the object, including content overflowing the
@@ -295,12 +295,12 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
LayoutUnit intrinsic_content_height) const;
int PixelSnappedLogicalHeight() const {
- return Style()->IsHorizontalWritingMode() ? PixelSnappedHeight()
- : PixelSnappedWidth();
+ return StyleRef().IsHorizontalWritingMode() ? PixelSnappedHeight()
+ : PixelSnappedWidth();
}
int PixelSnappedLogicalWidth() const {
- return Style()->IsHorizontalWritingMode() ? PixelSnappedWidth()
- : PixelSnappedHeight();
+ return StyleRef().IsHorizontalWritingMode() ? PixelSnappedWidth()
+ : PixelSnappedHeight();
}
LayoutUnit MinimumLogicalHeightForEmptyLine() const {
@@ -312,31 +312,31 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
}
void SetLogicalLeft(LayoutUnit left) {
- if (Style()->IsHorizontalWritingMode())
+ if (StyleRef().IsHorizontalWritingMode())
SetX(left);
else
SetY(left);
}
void SetLogicalTop(LayoutUnit top) {
- if (Style()->IsHorizontalWritingMode())
+ if (StyleRef().IsHorizontalWritingMode())
SetY(top);
else
SetX(top);
}
void SetLogicalLocation(const LayoutPoint& location) {
- if (Style()->IsHorizontalWritingMode())
+ if (StyleRef().IsHorizontalWritingMode())
SetLocation(location);
else
SetLocation(location.TransposedPoint());
}
void SetLogicalWidth(LayoutUnit size) {
- if (Style()->IsHorizontalWritingMode())
+ if (StyleRef().IsHorizontalWritingMode())
SetWidth(size);
else
SetHeight(size);
}
void SetLogicalHeight(LayoutUnit size) {
- if (Style()->IsHorizontalWritingMode())
+ if (StyleRef().IsHorizontalWritingMode())
SetHeight(size);
else
SetWidth(size);
@@ -390,9 +390,15 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
}
// Note that those functions have their origin at this box's CSS border box.
- // As such their location doesn't account for 'top'/'left'.
+ // As such their location doesn't account for 'top'/'left'. About its
+ // coordinate space, it can be treated as in either physical coordinates
+ // or "physical coordinates in flipped block-flow direction", and
+ // FlipForWritingMode() will do nothing on it.
LayoutRect BorderBoxRect() const { return LayoutRect(LayoutPoint(), Size()); }
- DISABLE_CFI_PERF LayoutRect PaddingBoxRect() const {
+
+ // TODO(crbug.com/877518): Some callers of this method may actually want
+ // "physical coordinates in flipped block-flow direction".
+ DISABLE_CFI_PERF LayoutRect PhysicalPaddingBoxRect() const {
return LayoutRect(ClientLeft(), ClientTop(), ClientWidth(), ClientHeight());
}
@@ -408,11 +414,17 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
// The content area of the box (excludes padding - and intrinsic padding for
// table cells, etc... - and border).
- DISABLE_CFI_PERF LayoutRect ContentBoxRect() const {
+ // TODO(crbug.com/877518): Some callers of this method may actually want
+ // "physical coordinates in flipped block-flow direction".
+ // TODO(wangxianzhu): Also exclude scrollbars which are between the inner
+ // border box and the padding box.
+ DISABLE_CFI_PERF LayoutRect PhysicalContentBoxRect() const {
return LayoutRect(BorderLeft() + PaddingLeft(), BorderTop() + PaddingTop(),
ContentWidth(), ContentHeight());
}
- LayoutSize ContentBoxOffset() const {
+ // TODO(crbug.com/877518): Some callers of this method may actually want
+ // "physical coordinates in flipped block-flow direction".
+ LayoutSize PhysicalContentBoxOffset() const {
return LayoutSize(BorderLeft() + PaddingLeft(), BorderTop() + PaddingTop());
}
// The content box in absolute coords. Ignores transforms.
@@ -422,8 +434,11 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
// The content box converted to absolute coords (taking transforms into
// account).
FloatQuad AbsoluteContentQuad(MapCoordinatesFlags = 0) const;
+
// The enclosing rectangle of the background with given opacity requirement.
- LayoutRect BackgroundRect(BackgroundRectType) const;
+ // TODO(crbug.com/877518): Some callers of this method may actually want
+ // "physical coordinates in flipped block-flow direction".
+ LayoutRect PhysicalBackgroundRect(BackgroundRectType) const;
// This returns the content area of the box (excluding padding and border).
// The only difference with contentBoxRect is that computedCSSContentBoxRect
@@ -457,12 +472,8 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
bool CanResize() const;
- // Visual and layout overflow are in the coordinate space of the box. This
- // means that they aren't purely physical directions. For horizontal-tb and
- // vertical-lr they will match physical directions, but for vertical-rl, the
- // left/right are flipped when compared to their physical counterparts.
- // For example minX is on the left in vertical-lr, but it is on the right in
- // vertical-rl.
+ // Like most of the other box geometries, visual and layout overflow are also
+ // in the "physical coordinates in flipped block-flow direction" of the box.
LayoutRect NoOverflowRect() const;
LayoutRect LayoutOverflowRect() const {
return overflow_ ? overflow_->LayoutOverflowRect() : NoOverflowRect();
@@ -479,22 +490,27 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
return LayoutSize(LayoutOverflowRect().MaxX(), LayoutOverflowRect().MaxY());
}
LayoutUnit LogicalLeftLayoutOverflow() const {
- return Style()->IsHorizontalWritingMode() ? LayoutOverflowRect().X()
- : LayoutOverflowRect().Y();
+ return StyleRef().IsHorizontalWritingMode() ? LayoutOverflowRect().X()
+ : LayoutOverflowRect().Y();
}
LayoutUnit LogicalRightLayoutOverflow() const {
- return Style()->IsHorizontalWritingMode() ? LayoutOverflowRect().MaxX()
- : LayoutOverflowRect().MaxY();
+ return StyleRef().IsHorizontalWritingMode() ? LayoutOverflowRect().MaxX()
+ : LayoutOverflowRect().MaxY();
}
LayoutRect VisualOverflowRect() const override;
+ LayoutRect PhysicalVisualOverflowRect() const {
+ LayoutRect overflow_rect = VisualOverflowRect();
+ FlipForWritingMode(overflow_rect);
+ return overflow_rect;
+ }
LayoutUnit LogicalLeftVisualOverflow() const {
- return Style()->IsHorizontalWritingMode() ? VisualOverflowRect().X()
- : VisualOverflowRect().Y();
+ return StyleRef().IsHorizontalWritingMode() ? VisualOverflowRect().X()
+ : VisualOverflowRect().Y();
}
LayoutUnit LogicalRightVisualOverflow() const {
- return Style()->IsHorizontalWritingMode() ? VisualOverflowRect().MaxX()
- : VisualOverflowRect().MaxY();
+ return StyleRef().IsHorizontalWritingMode() ? VisualOverflowRect().MaxX()
+ : VisualOverflowRect().MaxY();
}
LayoutRect SelfVisualOverflowRect() const {
@@ -551,12 +567,12 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
return LayoutSize(ContentWidth(), ContentHeight());
}
LayoutUnit ContentLogicalWidth() const {
- return Style()->IsHorizontalWritingMode() ? ContentWidth()
- : ContentHeight();
+ return StyleRef().IsHorizontalWritingMode() ? ContentWidth()
+ : ContentHeight();
}
LayoutUnit ContentLogicalHeight() const {
- return Style()->IsHorizontalWritingMode() ? ContentHeight()
- : ContentWidth();
+ return StyleRef().IsHorizontalWritingMode() ? ContentHeight()
+ : ContentWidth();
}
// IE extensions. Used to calculate offsetWidth/Height. Overridden by inlines
@@ -581,10 +597,12 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
LayoutUnit ClientWidth() const;
LayoutUnit ClientHeight() const;
DISABLE_CFI_PERF LayoutUnit ClientLogicalWidth() const {
- return Style()->IsHorizontalWritingMode() ? ClientWidth() : ClientHeight();
+ return StyleRef().IsHorizontalWritingMode() ? ClientWidth()
+ : ClientHeight();
}
DISABLE_CFI_PERF LayoutUnit ClientLogicalHeight() const {
- return Style()->IsHorizontalWritingMode() ? ClientHeight() : ClientWidth();
+ return StyleRef().IsHorizontalWritingMode() ? ClientHeight()
+ : ClientWidth();
}
DISABLE_CFI_PERF LayoutUnit ClientLogicalBottom() const {
return BorderBefore() + ClientLogicalHeight();
@@ -734,6 +752,8 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
// block-flow and inline-direction axis.
struct LogicalExtentComputedValues {
STACK_ALLOCATED();
+
+ public:
LogicalExtentComputedValues() = default;
// This is the dimension in the measured direction
@@ -811,10 +831,16 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
// contains us. Enables the atomic inline LayoutObject to quickly determine
// what line it is contained on and to easily iterate over structures on the
// line.
- InlineBox* InlineBoxWrapper() const { return inline_box_wrapper_; }
+ //
+ // InlineBoxWrapper() and FirstInlineFragment() are mutually exclusive,
+ // depends on IsInLayoutNGInlineFormattingContext().
+ InlineBox* InlineBoxWrapper() const;
void SetInlineBoxWrapper(InlineBox*);
void DeleteLineBoxWrapper();
+ NGPaintFragment* FirstInlineFragment() const final;
+ void SetFirstInlineFragment(NGPaintFragment*) final;
+
void SetSpannerPlaceholder(LayoutMultiColumnSpannerPlaceholder&);
void ClearSpannerPlaceholder();
LayoutMultiColumnSpannerPlaceholder* SpannerPlaceholder() const final {
@@ -901,12 +927,12 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
virtual LayoutSize IntrinsicSize() const { return LayoutSize(); }
LayoutUnit IntrinsicLogicalWidth() const {
- return Style()->IsHorizontalWritingMode() ? IntrinsicSize().Width()
- : IntrinsicSize().Height();
+ return StyleRef().IsHorizontalWritingMode() ? IntrinsicSize().Width()
+ : IntrinsicSize().Height();
}
LayoutUnit IntrinsicLogicalHeight() const {
- return Style()->IsHorizontalWritingMode() ? IntrinsicSize().Height()
- : IntrinsicSize().Width();
+ return StyleRef().IsHorizontalWritingMode() ? IntrinsicSize().Height()
+ : IntrinsicSize().Width();
}
virtual LayoutUnit IntrinsicContentLogicalHeight() const {
return intrinsic_content_logical_height_;
@@ -967,12 +993,12 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
// physical width and available physical height. Relative positioning is one
// of those cases, since left/top offsets are physical.
LayoutUnit AvailableWidth() const {
- return Style()->IsHorizontalWritingMode()
+ return StyleRef().IsHorizontalWritingMode()
? AvailableLogicalWidth()
: AvailableLogicalHeight(kIncludeMarginBorderPadding);
}
LayoutUnit AvailableHeight() const {
- return Style()->IsHorizontalWritingMode()
+ return StyleRef().IsHorizontalWritingMode()
? AvailableLogicalHeight(kIncludeMarginBorderPadding)
: AvailableLogicalWidth();
}
@@ -980,12 +1006,12 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
int VerticalScrollbarWidth() const;
int HorizontalScrollbarHeight() const;
int ScrollbarLogicalWidth() const {
- return Style()->IsHorizontalWritingMode() ? VerticalScrollbarWidth()
- : HorizontalScrollbarHeight();
+ return StyleRef().IsHorizontalWritingMode() ? VerticalScrollbarWidth()
+ : HorizontalScrollbarHeight();
}
int ScrollbarLogicalHeight() const {
- return Style()->IsHorizontalWritingMode() ? HorizontalScrollbarHeight()
- : VerticalScrollbarWidth();
+ return StyleRef().IsHorizontalWritingMode() ? HorizontalScrollbarHeight()
+ : VerticalScrollbarWidth();
}
// Return the width of the vertical scrollbar, unless it's larger than the
@@ -1006,16 +1032,16 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
virtual void DispatchFakeMouseMoveEventSoon(EventHandler&);
DISABLE_CFI_PERF bool HasAutoVerticalScrollbar() const {
- return HasOverflowClip() && Style()->HasAutoVerticalScroll();
+ return HasOverflowClip() && StyleRef().HasAutoVerticalScroll();
}
DISABLE_CFI_PERF bool HasAutoHorizontalScrollbar() const {
- return HasOverflowClip() && Style()->HasAutoHorizontalScroll();
+ return HasOverflowClip() && StyleRef().HasAutoHorizontalScroll();
}
DISABLE_CFI_PERF bool ScrollsOverflow() const {
- return HasOverflowClip() && Style()->ScrollsOverflow();
+ return HasOverflowClip() && StyleRef().ScrollsOverflow();
}
virtual bool ShouldPlaceBlockDirectionScrollbarOnLogicalLeft() const {
- return Style()->ShouldPlaceBlockDirectionScrollbarOnLogicalLeft();
+ return StyleRef().ShouldPlaceBlockDirectionScrollbarOnLogicalLeft();
}
bool HasScrollableOverflowX() const {
@@ -1027,10 +1053,10 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
PixelSnappedScrollHeight() != PixelSnappedClientHeight();
}
virtual bool ScrollsOverflowX() const {
- return HasOverflowClip() && Style()->ScrollsOverflowX();
+ return HasOverflowClip() && StyleRef().ScrollsOverflowX();
}
virtual bool ScrollsOverflowY() const {
- return HasOverflowClip() && Style()->ScrollsOverflowY();
+ return HasOverflowClip() && StyleRef().ScrollsOverflowY();
}
// Elements such as the <input> field override this to specify that they are
@@ -1103,7 +1129,7 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
bool IsWritingModeRoot() const {
return !Parent() ||
- Parent()->Style()->GetWritingMode() != Style()->GetWritingMode();
+ Parent()->StyleRef().GetWritingMode() != StyleRef().GetWritingMode();
}
bool IsOrthogonalWritingModeRoot() const {
return Parent() &&
@@ -1302,7 +1328,7 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
}
bool HasSameDirectionAs(const LayoutBox* object) const {
- return Style()->Direction() == object->Style()->Direction();
+ return StyleRef().Direction() == object->StyleRef().Direction();
}
ShapeOutsideInfo* GetShapeOutsideInfo() const;
@@ -1372,12 +1398,12 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
void SavePreviousSize() {
GetLayoutBox().previous_size_ = GetLayoutBox().Size();
}
- void SavePreviousContentBoxSizeAndLayoutOverflowRect();
- void ClearPreviousContentBoxSizeAndLayoutOverflowRect() {
+ void SavePreviousContentBoxRectAndLayoutOverflowRect();
+ void ClearPreviousContentBoxRectAndLayoutOverflowRect() {
if (!GetLayoutBox().rare_data_)
return;
GetLayoutBox()
- .rare_data_->has_previous_content_box_size_and_layout_overflow_rect_ =
+ .rare_data_->has_previous_content_box_rect_and_layout_overflow_rect_ =
false;
}
@@ -1395,17 +1421,17 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
}
LayoutSize PreviousSize() const { return previous_size_; }
- LayoutSize PreviousContentBoxSize() const {
+ LayoutRect PreviousPhysicalContentBoxRect() const {
return rare_data_ &&
rare_data_
- ->has_previous_content_box_size_and_layout_overflow_rect_
- ? rare_data_->previous_content_box_size_
- : PreviousSize();
+ ->has_previous_content_box_rect_and_layout_overflow_rect_
+ ? rare_data_->previous_physical_content_box_rect_
+ : LayoutRect(LayoutPoint(), PreviousSize());
}
LayoutRect PreviousPhysicalLayoutOverflowRect() const {
return rare_data_ &&
rare_data_
- ->has_previous_content_box_size_and_layout_overflow_rect_
+ ->has_previous_content_box_rect_and_layout_overflow_rect_
? rare_data_->previous_physical_layout_overflow_rect_
: LayoutRect(LayoutPoint(), PreviousSize());
}
@@ -1435,7 +1461,25 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
ClearPreferredLogicalWidthsDirty();
}
+ // 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.
+ //
+ // 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;
+
protected:
+ ~LayoutBox() override;
+
virtual bool ComputeShouldClipOverflow() const;
virtual LayoutRect ControlClipRect(const LayoutPoint&) const {
return LayoutRect();
@@ -1451,6 +1495,8 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
void UpdateFromStyle() override;
+ void InLayoutNGInlineFormattingContextWillChange(bool) final;
+
virtual ItemPosition SelfAlignmentNormalBehavior(
const LayoutBox* child = nullptr) const {
DCHECK(!child);
@@ -1504,8 +1550,7 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
void ComputeSelfHitTestRects(Vector<LayoutRect>&,
const LayoutPoint& layer_offset) const override;
- PaintInvalidationReason InvalidatePaint(
- const PaintInvalidatorContext&) const override;
+ void InvalidatePaint(const PaintInvalidatorContext&) const override;
bool ColumnFlexItemHasStretchAlignment() const;
bool IsStretchingColumnFlexItem() const;
@@ -1606,20 +1651,6 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
LayoutUnit& margin_start,
LayoutUnit& margin_end) const;
- // 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.
- virtual void ComputeIntrinsicLogicalWidths(
- LayoutUnit& min_logical_width,
- LayoutUnit& max_logical_width) const;
-
LayoutBoxRareData& EnsureRareData() {
if (!rare_data_)
rare_data_ = std::make_unique<LayoutBoxRareData>();
@@ -1699,8 +1730,15 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
&LayoutBox::SetMarginBottom, &LayoutBox::SetMarginLeft);
}
- // The inline box containing this LayoutBox, for atomic inline elements.
- InlineBox* inline_box_wrapper_;
+ union {
+ // The inline box containing this LayoutBox, for atomic inline elements.
+ // Valid only when !IsInLayoutNGInlineFormattingContext().
+ InlineBox* inline_box_wrapper_;
+ // The first fragment of the inline box containing this LayoutBox, for
+ // atomic inline elements. Valid only when
+ // IsInLayoutNGInlineFormattingContext().
+ scoped_refptr<NGPaintFragment> first_paint_fragment_;
+ };
std::unique_ptr<LayoutBoxRareData> rare_data_;
};
@@ -1761,7 +1799,13 @@ inline LayoutBox* LayoutBox::NextSiblingMultiColumnBox() const {
return NextSiblingBox();
}
+inline InlineBox* LayoutBox::InlineBoxWrapper() const {
+ return IsInLayoutNGInlineFormattingContext() ? nullptr : inline_box_wrapper_;
+}
+
inline void LayoutBox::SetInlineBoxWrapper(InlineBox* box_wrapper) {
+ CHECK(!IsInLayoutNGInlineFormattingContext());
+
if (box_wrapper) {
DCHECK(!inline_box_wrapper_);
// m_inlineBoxWrapper should already be nullptr. Deleting it is a safeguard
@@ -1776,6 +1820,11 @@ inline void LayoutBox::SetInlineBoxWrapper(InlineBox* box_wrapper) {
inline_box_wrapper_ = box_wrapper;
}
+inline NGPaintFragment* LayoutBox::FirstInlineFragment() const {
+ return IsInLayoutNGInlineFormattingContext() ? first_paint_fragment_.get()
+ : nullptr;
+}
+
inline bool LayoutBox::IsForcedFragmentainerBreakValue(
EBreakBetween break_value) {
return break_value == EBreakBetween::kColumn ||
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 778ffee5aaf..3ad5ae0f5d1 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
@@ -49,15 +49,15 @@ namespace {
inline bool IsOutOfFlowPositionedWithImplicitHeight(
const LayoutBoxModelObject* child) {
return child->IsOutOfFlowPositioned() &&
- !child->Style()->LogicalTop().IsAuto() &&
- !child->Style()->LogicalBottom().IsAuto();
+ !child->StyleRef().LogicalTop().IsAuto() &&
+ !child->StyleRef().LogicalBottom().IsAuto();
}
// Inclusive of |from|, exclusive of |to|.
PaintLayer* FindFirstStickyBetween(LayoutObject* from, LayoutObject* to) {
LayoutObject* maybe_sticky_ancestor = from;
while (maybe_sticky_ancestor && maybe_sticky_ancestor != to) {
- if (maybe_sticky_ancestor->Style()->HasStickyConstrainedPosition()) {
+ if (maybe_sticky_ancestor->StyleRef().HasStickyConstrainedPosition()) {
return ToLayoutBoxModelObject(maybe_sticky_ancestor)->Layer();
}
@@ -118,7 +118,7 @@ BackgroundPaintLocation LayoutBoxModelObject::GetBackgroundPaintLocation(
// TODO(flackr): Remove this when box shadows are still painted correctly when
// painting into the composited scrolling contents layer.
// https://crbug.com/646464
- if (Style()->BoxShadow()) {
+ if (StyleRef().BoxShadow()) {
if (reasons)
*reasons |= MainThreadScrollingReason::kHasBoxShadowFromNonRootLayer;
return kBackgroundPaintInGraphicsLayer;
@@ -127,7 +127,7 @@ BackgroundPaintLocation LayoutBoxModelObject::GetBackgroundPaintLocation(
// Assume optimistically that the background can be painted in the scrolling
// contents until we find otherwise.
BackgroundPaintLocation paint_location = kBackgroundPaintInScrollingContents;
- const FillLayer* layer = &(Style()->BackgroundLayers());
+ const FillLayer* layer = &(StyleRef().BackgroundLayers());
for (; layer; layer = layer->Next()) {
if (layer->Attachment() == EFillAttachment::kLocal)
continue;
@@ -143,20 +143,20 @@ BackgroundPaintLocation LayoutBoxModelObject::GetBackgroundPaintLocation(
// there is no border and we don't have custom scrollbars.
if (clip == EFillBox::kBorder) {
if (!has_custom_scrollbars &&
- (Style()->BorderTopWidth() == 0 ||
+ (StyleRef().BorderTopWidth() == 0 ||
!ResolveColor(GetCSSPropertyBorderTopColor()).HasAlpha()) &&
- (Style()->BorderLeftWidth() == 0 ||
+ (StyleRef().BorderLeftWidth() == 0 ||
!ResolveColor(GetCSSPropertyBorderLeftColor()).HasAlpha()) &&
- (Style()->BorderRightWidth() == 0 ||
+ (StyleRef().BorderRightWidth() == 0 ||
!ResolveColor(GetCSSPropertyBorderRightColor()).HasAlpha()) &&
- (Style()->BorderBottomWidth() == 0 ||
+ (StyleRef().BorderBottomWidth() == 0 ||
!ResolveColor(GetCSSPropertyBorderBottomColor()).HasAlpha())) {
continue;
}
// If we have an opaque background color only, we can safely paint it
// into both the scrolling contents layer and the graphics layer to
// preserve LCD text.
- if (layer == (&Style()->BackgroundLayers()) &&
+ if (layer == (&StyleRef().BackgroundLayers()) &&
ResolveColor(GetCSSPropertyBackgroundColor()).Alpha() < 255)
return kBackgroundPaintInGraphicsLayer;
paint_location |= kBackgroundPaintInGraphicsLayer;
@@ -164,9 +164,10 @@ BackgroundPaintLocation LayoutBoxModelObject::GetBackgroundPaintLocation(
}
// A content fill box can be treated as a padding fill box if there is no
// padding.
- if (clip == EFillBox::kContent && Style()->PaddingTop().IsZero() &&
- Style()->PaddingLeft().IsZero() && Style()->PaddingRight().IsZero() &&
- Style()->PaddingBottom().IsZero()) {
+ if (clip == EFillBox::kContent && StyleRef().PaddingTop().IsZero() &&
+ StyleRef().PaddingLeft().IsZero() &&
+ StyleRef().PaddingRight().IsZero() &&
+ StyleRef().PaddingBottom().IsZero()) {
continue;
}
}
@@ -190,8 +191,8 @@ void LayoutBoxModelObject::WillBeDestroyed() {
// 0 during destruction.
if (LocalFrame* frame = GetFrame()) {
if (LocalFrameView* frame_view = frame->View()) {
- if (Style()->HasViewportConstrainedPosition() ||
- Style()->HasStickyConstrainedPosition())
+ if (StyleRef().HasViewportConstrainedPosition() ||
+ StyleRef().HasStickyConstrainedPosition())
frame_view->RemoveViewportConstrainedObject(*this);
}
}
@@ -218,8 +219,8 @@ void LayoutBoxModelObject::StyleWillChange(StyleDifference diff,
// invalidate the current compositing container chain which may have painted
// cached subsequences containing this object or descendant objects.
if (Style() &&
- (Style()->IsStacked() != new_style.IsStacked() ||
- Style()->IsStackingContext() != new_style.IsStackingContext()) &&
+ (StyleRef().IsStacked() != new_style.IsStacked() ||
+ StyleRef().IsStackingContext() != new_style.IsStackingContext()) &&
// ObjectPaintInvalidator requires this.
IsRooted()) {
if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
@@ -317,6 +318,8 @@ void LayoutBoxModelObject::StyleDidChange(StyleDifference diff,
} else if (had_transform_related_property != HasTransformRelatedProperty()) {
// This affects whether to create transform node.
SetNeedsPaintPropertyUpdate();
+ if (Layer())
+ Layer()->SetNeedsCompositingInputsUpdate();
}
if (Layer()) {
@@ -356,7 +359,7 @@ void LayoutBoxModelObject::StyleDidChange(StyleDifference diff,
old_style && ToLayoutBoxModelObject(body_layout)
->BackgroundStolenForBeingBody(old_style);
if (new_stole_body_background != old_stole_body_background &&
- body_layout->Style() && body_layout->Style()->HasBackground()) {
+ body_layout->Style() && body_layout->StyleRef().HasBackground()) {
body_layout->SetShouldDoFullPaintInvalidation();
}
}
@@ -364,10 +367,10 @@ void LayoutBoxModelObject::StyleDidChange(StyleDifference diff,
if (LocalFrameView* frame_view = View()->GetFrameView()) {
bool new_style_is_viewport_constained =
- Style()->GetPosition() == EPosition::kFixed;
+ StyleRef().GetPosition() == EPosition::kFixed;
bool old_style_is_viewport_constrained =
old_style && old_style->GetPosition() == EPosition::kFixed;
- bool new_style_is_sticky = Style()->HasStickyConstrainedPosition();
+ bool new_style_is_sticky = StyleRef().HasStickyConstrainedPosition();
bool old_style_is_sticky =
old_style && old_style->HasStickyConstrainedPosition();
@@ -672,7 +675,7 @@ bool LayoutBoxModelObject::HasAutoHeightOrContainingBlockWithAutoHeight()
// TODO(rego): Check if we can somehow reuse LayoutBlock::
// availableLogicalHeightForPercentageComputation() (see crbug.com/635655).
const LayoutBox* this_box = IsBox() ? ToLayoutBox(this) : nullptr;
- Length logical_height_length = Style()->LogicalHeight();
+ Length logical_height_length = StyleRef().LogicalHeight();
LayoutBlock* cb =
ContainingBlockForAutoHeightDetection(logical_height_length);
if (logical_height_length.IsPercentOrCalc() && cb && IsBox())
@@ -713,11 +716,14 @@ LayoutSize LayoutBoxModelObject::RelativePositionOffset() const {
// https://drafts.csswg.org/css-position-3/#rel-pos
base::Optional<LayoutUnit> left;
base::Optional<LayoutUnit> right;
- if (!Style()->Left().IsAuto())
- left = ValueForLength(Style()->Left(), containing_block->AvailableWidth());
- if (!Style()->Right().IsAuto())
+ if (!StyleRef().Left().IsAuto()) {
+ left =
+ ValueForLength(StyleRef().Left(), containing_block->AvailableWidth());
+ }
+ if (!StyleRef().Right().IsAuto()) {
right =
- ValueForLength(Style()->Right(), containing_block->AvailableWidth());
+ ValueForLength(StyleRef().Right(), containing_block->AvailableWidth());
+ }
if (!left && !right) {
left = LayoutUnit();
right = LayoutUnit();
@@ -726,8 +732,8 @@ LayoutSize LayoutBoxModelObject::RelativePositionOffset() const {
left = -right.value();
if (!right)
right = -left.value();
- bool is_ltr = containing_block->Style()->IsLeftToRightDirection();
- WritingMode writing_mode = containing_block->Style()->GetWritingMode();
+ bool is_ltr = containing_block->StyleRef().IsLeftToRightDirection();
+ WritingMode writing_mode = containing_block->StyleRef().GetWritingMode();
switch (writing_mode) {
case WritingMode::kHorizontalTb:
if (is_ltr)
@@ -755,18 +761,18 @@ LayoutSize LayoutBoxModelObject::RelativePositionOffset() const {
base::Optional<LayoutUnit> top;
base::Optional<LayoutUnit> bottom;
- if (!Style()->Top().IsAuto() &&
+ if (!StyleRef().Top().IsAuto() &&
(!containing_block->HasAutoHeightOrContainingBlockWithAutoHeight() ||
- !Style()->Top().IsPercentOrCalc() ||
+ !StyleRef().Top().IsPercentOrCalc() ||
containing_block->StretchesToViewport())) {
- top = ValueForLength(Style()->Top(), containing_block->AvailableHeight());
+ top = ValueForLength(StyleRef().Top(), containing_block->AvailableHeight());
}
- if (!Style()->Bottom().IsAuto() &&
+ if (!StyleRef().Bottom().IsAuto() &&
(!containing_block->HasAutoHeightOrContainingBlockWithAutoHeight() ||
- !Style()->Bottom().IsPercentOrCalc() ||
+ !StyleRef().Bottom().IsPercentOrCalc() ||
containing_block->StretchesToViewport())) {
- bottom =
- ValueForLength(Style()->Bottom(), containing_block->AvailableHeight());
+ bottom = ValueForLength(StyleRef().Bottom(),
+ containing_block->AvailableHeight());
}
if (!top && !bottom) {
top = LayoutUnit();
@@ -800,6 +806,8 @@ LayoutSize LayoutBoxModelObject::RelativePositionOffset() const {
}
void LayoutBoxModelObject::UpdateStickyPositionConstraints() const {
+ DCHECK(StyleRef().HasStickyConstrainedPosition());
+
const FloatSize constraining_size = ComputeStickyConstrainingRect().Size();
StickyPositionScrollingConstraints constraints;
@@ -844,7 +852,7 @@ void LayoutBoxModelObject::UpdateStickyPositionConstraints() const {
FloatSize scroll_container_border_offset =
FloatSize(scroll_ancestor.BorderLeft(), scroll_ancestor.BorderTop());
if (containing_block != &scroll_ancestor) {
- FloatQuad local_quad(FloatRect(containing_block->PaddingBoxRect()));
+ FloatQuad local_quad(FloatRect(containing_block->PhysicalPaddingBoxRect()));
scroll_container_relative_padding_box_rect =
containing_block
->LocalToAncestorQuadWithoutTransforms(local_quad, &scroll_ancestor,
@@ -863,21 +871,21 @@ void LayoutBoxModelObject::UpdateStickyPositionConstraints() const {
// It is an open issue whether the margin should collapse.
// See https://www.w3.org/TR/css-position-3/#sticky-pos
scroll_container_relative_containing_block_rect.ContractEdges(
- MinimumValueForLength(containing_block->Style()->PaddingTop(),
+ MinimumValueForLength(containing_block->StyleRef().PaddingTop(),
max_container_width) +
- MinimumValueForLength(Style()->MarginTop(), max_width),
- MinimumValueForLength(containing_block->Style()->PaddingRight(),
+ MinimumValueForLength(StyleRef().MarginTop(), max_width),
+ MinimumValueForLength(containing_block->StyleRef().PaddingRight(),
max_container_width) +
- MinimumValueForLength(Style()->MarginRight(), max_width),
- MinimumValueForLength(containing_block->Style()->PaddingBottom(),
+ MinimumValueForLength(StyleRef().MarginRight(), max_width),
+ MinimumValueForLength(containing_block->StyleRef().PaddingBottom(),
max_container_width) +
- MinimumValueForLength(Style()->MarginBottom(), max_width),
- MinimumValueForLength(containing_block->Style()->PaddingLeft(),
+ MinimumValueForLength(StyleRef().MarginBottom(), max_width),
+ MinimumValueForLength(containing_block->StyleRef().PaddingLeft(),
max_container_width) +
- MinimumValueForLength(Style()->MarginLeft(), max_width));
+ MinimumValueForLength(StyleRef().MarginLeft(), max_width));
- constraints.SetScrollContainerRelativeContainingBlockRect(
- FloatRect(scroll_container_relative_containing_block_rect));
+ constraints.scroll_container_relative_containing_block_rect =
+ FloatRect(scroll_container_relative_containing_block_rect);
FloatRect sticky_box_rect =
IsLayoutInline() ? FloatRect(ToLayoutInline(this)->LinesBoundingBox())
@@ -896,10 +904,10 @@ void LayoutBoxModelObject::UpdateStickyPositionConstraints() const {
FloatSize container_border_offset(containing_block->BorderLeft(),
containing_block->BorderTop());
sticky_location -= container_border_offset;
- constraints.SetScrollContainerRelativeStickyBoxRect(
+ constraints.scroll_container_relative_sticky_box_rect =
FloatRect(scroll_container_relative_padding_box_rect.Location() +
ToFloatSize(sticky_location),
- flipped_sticky_box_rect.Size()));
+ flipped_sticky_box_rect.Size());
// To correctly compute the offsets, the constraints need to know about any
// nested position:sticky elements between themselves and their
@@ -907,46 +915,44 @@ void LayoutBoxModelObject::UpdateStickyPositionConstraints() const {
//
// The respective search ranges are [container, containingBlock) and
// [containingBlock, scrollAncestor).
- constraints.SetNearestStickyLayerShiftingStickyBox(
- FindFirstStickyBetween(location_container, containing_block));
+ constraints.nearest_sticky_layer_shifting_sticky_box =
+ FindFirstStickyBetween(location_container, containing_block);
// We cannot use |scrollAncestor| here as it disregards the root
// ancestorOverflowLayer(), which we should include.
- constraints.SetNearestStickyLayerShiftingContainingBlock(
+ constraints.nearest_sticky_layer_shifting_containing_block =
FindFirstStickyBetween(
containing_block,
- &Layer()->AncestorOverflowLayer()->GetLayoutObject()));
+ &Layer()->AncestorOverflowLayer()->GetLayoutObject());
// We skip the right or top sticky offset if there is not enough space to
// honor both the left/right or top/bottom offsets.
LayoutUnit horizontal_offsets =
- MinimumValueForLength(Style()->Right(),
+ MinimumValueForLength(StyleRef().Right(),
LayoutUnit(constraining_size.Width())) +
- MinimumValueForLength(Style()->Left(),
+ MinimumValueForLength(StyleRef().Left(),
LayoutUnit(constraining_size.Width()));
bool skip_right = false;
bool skip_left = false;
- if (!Style()->Left().IsAuto() && !Style()->Right().IsAuto()) {
+ if (!StyleRef().Left().IsAuto() && !StyleRef().Right().IsAuto()) {
if (horizontal_offsets >
scroll_container_relative_containing_block_rect.Width() ||
horizontal_offsets + sticky_box_rect.Width() >
constraining_size.Width()) {
- skip_right = Style()->IsLeftToRightDirection();
+ skip_right = StyleRef().IsLeftToRightDirection();
skip_left = !skip_right;
}
}
- if (!Style()->Left().IsAuto() && !skip_left) {
- constraints.SetLeftOffset(MinimumValueForLength(
- Style()->Left(), LayoutUnit(constraining_size.Width())));
- constraints.AddAnchorEdge(
- StickyPositionScrollingConstraints::kAnchorEdgeLeft);
+ if (!StyleRef().Left().IsAuto() && !skip_left) {
+ constraints.left_offset = MinimumValueForLength(
+ StyleRef().Left(), LayoutUnit(constraining_size.Width()));
+ constraints.is_anchored_left = true;
}
- if (!Style()->Right().IsAuto() && !skip_right) {
- constraints.SetRightOffset(MinimumValueForLength(
- Style()->Right(), LayoutUnit(constraining_size.Width())));
- constraints.AddAnchorEdge(
- StickyPositionScrollingConstraints::kAnchorEdgeRight);
+ if (!StyleRef().Right().IsAuto() && !skip_right) {
+ constraints.right_offset = MinimumValueForLength(
+ StyleRef().Right(), LayoutUnit(constraining_size.Width()));
+ constraints.is_anchored_right = true;
}
bool skip_bottom = false;
@@ -954,11 +960,11 @@ void LayoutBoxModelObject::UpdateStickyPositionConstraints() const {
// mode when related sections are fixed in spec.
// See http://lists.w3.org/Archives/Public/www-style/2014May/0286.html
LayoutUnit vertical_offsets =
- MinimumValueForLength(Style()->Top(),
+ MinimumValueForLength(StyleRef().Top(),
LayoutUnit(constraining_size.Height())) +
- MinimumValueForLength(Style()->Bottom(),
+ MinimumValueForLength(StyleRef().Bottom(),
LayoutUnit(constraining_size.Height()));
- if (!Style()->Top().IsAuto() && !Style()->Bottom().IsAuto()) {
+ if (!StyleRef().Top().IsAuto() && !StyleRef().Bottom().IsAuto()) {
if (vertical_offsets >
scroll_container_relative_containing_block_rect.Height() ||
vertical_offsets + sticky_box_rect.Height() >
@@ -967,29 +973,25 @@ void LayoutBoxModelObject::UpdateStickyPositionConstraints() const {
}
}
- if (!Style()->Top().IsAuto()) {
- constraints.SetTopOffset(MinimumValueForLength(
- Style()->Top(), LayoutUnit(constraining_size.Height())));
- constraints.AddAnchorEdge(
- StickyPositionScrollingConstraints::kAnchorEdgeTop);
+ if (!StyleRef().Top().IsAuto()) {
+ constraints.top_offset = MinimumValueForLength(
+ StyleRef().Top(), LayoutUnit(constraining_size.Height()));
+ constraints.is_anchored_top = true;
}
- if (!Style()->Bottom().IsAuto() && !skip_bottom) {
- constraints.SetBottomOffset(MinimumValueForLength(
- Style()->Bottom(), LayoutUnit(constraining_size.Height())));
- constraints.AddAnchorEdge(
- StickyPositionScrollingConstraints::kAnchorEdgeBottom);
+ if (!StyleRef().Bottom().IsAuto() && !skip_bottom) {
+ constraints.bottom_offset = MinimumValueForLength(
+ StyleRef().Bottom(), LayoutUnit(constraining_size.Height()));
+ constraints.is_anchored_bottom = true;
}
- // At least one edge should be anchored if we are calculating constraints.
- DCHECK(constraints.GetAnchorEdges());
PaintLayerScrollableArea* scrollable_area =
Layer()->AncestorOverflowLayer()->GetScrollableArea();
scrollable_area->GetStickyConstraintsMap().Set(Layer(), constraints);
}
bool LayoutBoxModelObject::IsSlowRepaintConstrainedObject() const {
- if (!HasLayer() || (Style()->GetPosition() != EPosition::kFixed &&
- Style()->GetPosition() != EPosition::kSticky)) {
+ if (!HasLayer() || (StyleRef().GetPosition() != EPosition::kFixed &&
+ StyleRef().GetPosition() != EPosition::kSticky)) {
return false;
}
@@ -1015,18 +1017,12 @@ bool LayoutBoxModelObject::IsSlowRepaintConstrainedObject() const {
}
FloatRect LayoutBoxModelObject::ComputeStickyConstrainingRect() const {
- if (Layer()->AncestorOverflowLayer()->IsRootLayer()) {
- return FloatRect(
- View()->GetFrameView()->LayoutViewport()->VisibleContentRect());
- }
-
LayoutBox* enclosing_clipping_box =
Layer()->AncestorOverflowLayer()->GetLayoutBox();
DCHECK(enclosing_clipping_box);
FloatRect constraining_rect;
- constraining_rect = FloatRect(
- enclosing_clipping_box->OverflowClipRect(LayoutPoint(DoublePoint(
- enclosing_clipping_box->GetScrollableArea()->ScrollPosition()))));
+ constraining_rect =
+ FloatRect(enclosing_clipping_box->OverflowClipRect(LayoutPoint()));
constraining_rect.Move(-enclosing_clipping_box->BorderLeft() +
enclosing_clipping_box->PaddingLeft(),
-enclosing_clipping_box->BorderTop() +
@@ -1056,6 +1052,8 @@ LayoutSize LayoutBoxModelObject::StickyPositionOffset() const {
// The sticky offset is physical, so we can just return the delta computed in
// absolute coords (though it may be wrong with transforms).
FloatRect constraining_rect = ComputeStickyConstrainingRect();
+ constraining_rect.MoveBy(
+ ancestor_overflow_layer->GetScrollableArea()->ScrollPosition());
return LayoutSize(
constraints->ComputeStickyOffset(constraining_rect, constraints_map));
}
@@ -1107,7 +1105,7 @@ LayoutPoint LayoutBoxModelObject::AdjustedPositionRelativeTo(
if (IsBox() && IsOutOfFlowPositioned() &&
inline_parent->CanContainOutOfFlowPositionedElement(
- Style()->GetPosition())) {
+ StyleRef().GetPosition())) {
// Offset for out of flow positioned elements with inline containers is
// a special case in the CSS spec
reference_point +=
@@ -1260,7 +1258,7 @@ LayoutRect LayoutBoxModelObject::LocalCaretRectForEmptyElement(
}
x = std::min(x, (max_x - caret_width).ClampNegativeToZero());
- const Font& font = Style()->GetFont();
+ const Font& font = StyleRef().GetFont();
const SimpleFontData* font_data = font.PrimaryFont();
LayoutUnit height;
// crbug.com/595692 This check should not be needed but sometimes
@@ -1290,7 +1288,8 @@ const LayoutObject* LayoutBoxModelObject::PushMappingToContainer(
return nullptr;
bool is_inline = IsLayoutInline();
- bool is_fixed_pos = !is_inline && Style()->GetPosition() == EPosition::kFixed;
+ bool is_fixed_pos =
+ !is_inline && StyleRef().GetPosition() == EPosition::kFixed;
bool contains_fixed_position = CanContainFixedPositionObjects();
TransformationMatrix adjustment_for_skipped_ancestor;
@@ -1300,7 +1299,7 @@ const LayoutObject* LayoutBoxModelObject::PushMappingToContainer(
// because transforms create containers, so it should be safe to just
// subtract the delta between the container and ancestor_to_stop_at.
LayoutSize ancestor_offset =
- ancestor_to_stop_at->OffsetFromAncestorContainer(container);
+ ancestor_to_stop_at->OffsetFromAncestor(container);
adjustment_for_skipped_ancestor.Translate(
-ancestor_offset.Width().ToFloat(),
-ancestor_offset.Height().ToFloat());
@@ -1313,10 +1312,12 @@ const LayoutObject* LayoutBoxModelObject::PushMappingToContainer(
offset_depends_on_point = true;
} else {
offset_depends_on_point =
- container->Style()->IsFlippedBlocksWritingMode() && container->IsBox();
+ container->StyleRef().IsFlippedBlocksWritingMode() &&
+ container->IsBox();
}
- bool preserve3d = container->Style()->Preserves3D() || Style()->Preserves3D();
+ bool preserve3d =
+ container->StyleRef().Preserves3D() || StyleRef().Preserves3D();
GeometryInfoFlags flags = 0;
if (preserve3d)
flags |= kAccumulatingTransform;
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 87a4b950344..775d0434e21 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
@@ -119,8 +119,9 @@ enum LineDirectionMode { kHorizontalLine, kVerticalLine };
// extra details.
//
// - physical coordinates with flipped block-flow direction: those are physical
-// coordinates but we flipped the block direction. See
-// LayoutBox::noOverflowRect.
+// coordinates but we flipped the block direction. Almost all geometries
+// in box layout use this coordinate space, except those having explicit
+// "Logical" or "Physical" prefix in their names.
//
// For more, see Source/core/layout/README.md ### Coordinate Spaces.
class CORE_EXPORT LayoutBoxModelObject : public LayoutObject {
@@ -133,7 +134,7 @@ class CORE_EXPORT LayoutBoxModelObject : public LayoutObject {
LayoutSize RelativePositionOffset() const;
LayoutSize RelativePositionLogicalOffset() const {
- return Style()->IsHorizontalWritingMode()
+ return StyleRef().IsHorizontalWritingMode()
? RelativePositionOffset()
: RelativePositionOffset().TransposedSize();
}
@@ -191,34 +192,34 @@ class CORE_EXPORT LayoutBoxModelObject : public LayoutObject {
// These return the CSS computed padding values.
LayoutUnit ComputedCSSPaddingTop() const {
- return ComputedCSSPadding(Style()->PaddingTop());
+ return ComputedCSSPadding(StyleRef().PaddingTop());
}
LayoutUnit ComputedCSSPaddingBottom() const {
- return ComputedCSSPadding(Style()->PaddingBottom());
+ return ComputedCSSPadding(StyleRef().PaddingBottom());
}
LayoutUnit ComputedCSSPaddingLeft() const {
- return ComputedCSSPadding(Style()->PaddingLeft());
+ return ComputedCSSPadding(StyleRef().PaddingLeft());
}
LayoutUnit ComputedCSSPaddingRight() const {
- return ComputedCSSPadding(Style()->PaddingRight());
+ return ComputedCSSPadding(StyleRef().PaddingRight());
}
LayoutUnit ComputedCSSPaddingBefore() const {
- return ComputedCSSPadding(Style()->PaddingBefore());
+ return ComputedCSSPadding(StyleRef().PaddingBefore());
}
LayoutUnit ComputedCSSPaddingAfter() const {
- return ComputedCSSPadding(Style()->PaddingAfter());
+ return ComputedCSSPadding(StyleRef().PaddingAfter());
}
LayoutUnit ComputedCSSPaddingStart() const {
- return ComputedCSSPadding(Style()->PaddingStart());
+ return ComputedCSSPadding(StyleRef().PaddingStart());
}
LayoutUnit ComputedCSSPaddingEnd() const {
- return ComputedCSSPadding(Style()->PaddingEnd());
+ return ComputedCSSPadding(StyleRef().PaddingEnd());
}
LayoutUnit ComputedCSSPaddingOver() const {
- return ComputedCSSPadding(Style()->PaddingOver());
+ return ComputedCSSPadding(StyleRef().PaddingOver());
}
LayoutUnit ComputedCSSPaddingUnder() const {
- return ComputedCSSPadding(Style()->PaddingUnder());
+ return ComputedCSSPadding(StyleRef().PaddingUnder());
}
// These functions are used during layout.
@@ -242,16 +243,16 @@ class CORE_EXPORT LayoutBoxModelObject : public LayoutObject {
LayoutUnit PaddingUnder() const { return PhysicalPaddingToLogical().Under(); }
virtual LayoutUnit BorderTop() const {
- return LayoutUnit(Style()->BorderTopWidth());
+ return LayoutUnit(StyleRef().BorderTopWidth());
}
virtual LayoutUnit BorderBottom() const {
- return LayoutUnit(Style()->BorderBottomWidth());
+ return LayoutUnit(StyleRef().BorderBottomWidth());
}
virtual LayoutUnit BorderLeft() const {
- return LayoutUnit(Style()->BorderLeftWidth());
+ return LayoutUnit(StyleRef().BorderLeftWidth());
}
virtual LayoutUnit BorderRight() const {
- return LayoutUnit(Style()->BorderRightWidth());
+ return LayoutUnit(StyleRef().BorderRightWidth());
}
LayoutUnit BorderBefore() const { return PhysicalBorderToLogical().Before(); }
@@ -281,7 +282,7 @@ class CORE_EXPORT LayoutBoxModelObject : public LayoutObject {
}
bool HasBorderOrPadding() const {
- return Style()->HasBorder() || Style()->HasPadding();
+ return StyleRef().HasBorder() || StyleRef().HasPadding();
}
LayoutUnit BorderAndPaddingStart() const {
@@ -315,17 +316,17 @@ class CORE_EXPORT LayoutBoxModelObject : public LayoutObject {
return BorderStart() + BorderEnd() + PaddingStart() + PaddingEnd();
}
DISABLE_CFI_PERF LayoutUnit BorderAndPaddingLogicalLeft() const {
- return Style()->IsHorizontalWritingMode() ? BorderLeft() + PaddingLeft()
- : BorderTop() + PaddingTop();
+ return StyleRef().IsHorizontalWritingMode() ? BorderLeft() + PaddingLeft()
+ : BorderTop() + PaddingTop();
}
LayoutUnit BorderLogicalLeft() const {
- return LayoutUnit(Style()->IsHorizontalWritingMode() ? BorderLeft()
- : BorderTop());
+ return LayoutUnit(StyleRef().IsHorizontalWritingMode() ? BorderLeft()
+ : BorderTop());
}
LayoutUnit BorderLogicalRight() const {
- return LayoutUnit(Style()->IsHorizontalWritingMode() ? BorderRight()
- : BorderBottom());
+ return LayoutUnit(StyleRef().IsHorizontalWritingMode() ? BorderRight()
+ : BorderBottom());
}
LayoutUnit PaddingLogicalWidth() const {
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 51ff438c497..1054c045c7b 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
@@ -21,16 +21,6 @@ class LayoutBoxModelObjectTest : public RenderingTest {
PaintLayer* GetPaintLayerByElementId(const char* id) {
return ToLayoutBoxModelObject(GetLayoutObjectByElementId(id))->Layer();
}
-
- const FloatRect& GetScrollContainerRelativeContainingBlockRect(
- const StickyPositionScrollingConstraints& constraints) const {
- return constraints.ScrollContainerRelativeContainingBlockRect();
- }
-
- const FloatRect& GetScrollContainerRelativeStickyBoxRect(
- const StickyPositionScrollingConstraints& constraints) const {
- return constraints.ScrollContainerRelativeStickyBoxRect();
- }
};
// Verifies that the sticky constraints are correctly computed.
@@ -59,19 +49,19 @@ TEST_F(LayoutBoxModelObjectTest, StickyPositionConstraints) {
const StickyPositionScrollingConstraints& constraints =
scrollable_area->GetStickyConstraintsMap().at(sticky->Layer());
- ASSERT_EQ(0.f, constraints.TopOffset());
+ ASSERT_EQ(0.f, constraints.top_offset);
// The coordinates of the constraint rects should all be with respect to the
// unscrolled scroller.
ASSERT_EQ(IntRect(15, 115, 170, 370),
EnclosingIntRect(
- GetScrollContainerRelativeContainingBlockRect(constraints)));
+ constraints.scroll_container_relative_containing_block_rect));
ASSERT_EQ(
IntRect(15, 115, 100, 100),
- EnclosingIntRect(GetScrollContainerRelativeStickyBoxRect(constraints)));
+ EnclosingIntRect(constraints.scroll_container_relative_sticky_box_rect));
// The sticky constraining rect also doesn't include the border offset.
- ASSERT_EQ(IntRect(0, 50, 400, 100),
+ ASSERT_EQ(IntRect(0, 0, 400, 100),
EnclosingIntRect(sticky->ComputeStickyConstrainingRect()));
}
@@ -102,19 +92,19 @@ TEST_F(LayoutBoxModelObjectTest, StickyPositionVerticalRLConstraints) {
const StickyPositionScrollingConstraints& constraints =
scrollable_area->GetStickyConstraintsMap().at(sticky->Layer());
- ASSERT_EQ(0.f, constraints.TopOffset());
+ ASSERT_EQ(0.f, constraints.top_offset);
// The coordinates of the constraint rects should all be with respect to the
// unscrolled scroller.
ASSERT_EQ(IntRect(215, 115, 170, 370),
EnclosingIntRect(
- GetScrollContainerRelativeContainingBlockRect(constraints)));
+ constraints.scroll_container_relative_containing_block_rect));
ASSERT_EQ(
IntRect(285, 115, 100, 100),
- EnclosingIntRect(GetScrollContainerRelativeStickyBoxRect(constraints)));
+ EnclosingIntRect(constraints.scroll_container_relative_sticky_box_rect));
// The sticky constraining rect also doesn't include the border offset.
- ASSERT_EQ(IntRect(0, 50, 400, 100),
+ ASSERT_EQ(IntRect(0, 0, 400, 100),
EnclosingIntRect(sticky->ComputeStickyConstrainingRect()));
}
@@ -155,17 +145,17 @@ TEST_F(LayoutBoxModelObjectTest, StickyPositionInlineConstraints) {
const StickyPositionScrollingConstraints& constraints =
scrollable_area->GetStickyConstraintsMap().at(sticky->Layer());
- EXPECT_EQ(10.f, constraints.TopOffset());
+ EXPECT_EQ(10.f, constraints.top_offset);
// The coordinates of the constraint rects should all be with respect to the
// unscrolled scroller.
EXPECT_EQ(IntRect(0, 100, 200, 400),
EnclosingIntRect(
- GetScrollContainerRelativeContainingBlockRect(constraints)));
+ constraints.scroll_container_relative_containing_block_rect));
EXPECT_EQ(
IntRect(0, 100, 10, 10),
- EnclosingIntRect(GetScrollContainerRelativeStickyBoxRect(constraints)));
- EXPECT_EQ(IntRect(0, 50, 100, 100),
+ EnclosingIntRect(constraints.scroll_container_relative_sticky_box_rect));
+ EXPECT_EQ(IntRect(0, 0, 100, 100),
EnclosingIntRect(sticky->ComputeStickyConstrainingRect()));
}
@@ -214,17 +204,17 @@ TEST_F(LayoutBoxModelObjectTest, StickyPositionVerticalRLInlineConstraints) {
const StickyPositionScrollingConstraints& constraints =
scrollable_area->GetStickyConstraintsMap().at(sticky->Layer());
- EXPECT_EQ(10.f, constraints.TopOffset());
+ EXPECT_EQ(10.f, constraints.top_offset);
// The coordinates of the constraint rects should all be with respect to the
// unscrolled scroller.
EXPECT_EQ(IntRect(2000, 100, 200, 400),
EnclosingIntRect(
- GetScrollContainerRelativeContainingBlockRect(constraints)));
+ constraints.scroll_container_relative_containing_block_rect));
EXPECT_EQ(
IntRect(2190, 100, 10, 10),
- EnclosingIntRect(GetScrollContainerRelativeStickyBoxRect(constraints)));
- EXPECT_EQ(IntRect(2100, 50, 100, 100),
+ EnclosingIntRect(constraints.scroll_container_relative_sticky_box_rect));
+ EXPECT_EQ(IntRect(0, 0, 100, 100),
EnclosingIntRect(sticky->ComputeStickyConstrainingRect()));
}
@@ -255,16 +245,16 @@ TEST_F(LayoutBoxModelObjectTest, StickyPositionTransforms) {
const StickyPositionScrollingConstraints& constraints =
scrollable_area->GetStickyConstraintsMap().at(sticky->Layer());
- ASSERT_EQ(0.f, constraints.TopOffset());
+ ASSERT_EQ(0.f, constraints.top_offset);
// The coordinates of the constraint rects should all be with respect to the
// unscrolled scroller.
ASSERT_EQ(IntRect(15, 115, 170, 370),
EnclosingIntRect(
- GetScrollContainerRelativeContainingBlockRect(constraints)));
+ constraints.scroll_container_relative_containing_block_rect));
ASSERT_EQ(
IntRect(15, 115, 100, 100),
- EnclosingIntRect(GetScrollContainerRelativeStickyBoxRect(constraints)));
+ EnclosingIntRect(constraints.scroll_container_relative_sticky_box_rect));
}
// Verifies that the sticky constraints are correctly computed.
@@ -293,14 +283,14 @@ TEST_F(LayoutBoxModelObjectTest, StickyPositionPercentageStyles) {
const StickyPositionScrollingConstraints& constraints =
scrollable_area->GetStickyConstraintsMap().at(sticky->Layer());
- ASSERT_EQ(0.f, constraints.TopOffset());
+ ASSERT_EQ(0.f, constraints.top_offset);
ASSERT_EQ(IntRect(25, 145, 200, 330),
EnclosingIntRect(
- GetScrollContainerRelativeContainingBlockRect(constraints)));
+ constraints.scroll_container_relative_containing_block_rect));
ASSERT_EQ(
IntRect(25, 145, 100, 100),
- EnclosingIntRect(GetScrollContainerRelativeStickyBoxRect(constraints)));
+ EnclosingIntRect(constraints.scroll_container_relative_sticky_box_rect));
}
// Verifies that the sticky constraints are correct when the sticky position
@@ -330,10 +320,10 @@ TEST_F(LayoutBoxModelObjectTest, StickyPositionContainerIsScroller) {
scrollable_area->GetStickyConstraintsMap().at(sticky->Layer());
ASSERT_EQ(IntRect(0, 0, 400, 1100),
EnclosingIntRect(
- GetScrollContainerRelativeContainingBlockRect(constraints)));
+ constraints.scroll_container_relative_containing_block_rect));
ASSERT_EQ(
IntRect(0, 0, 100, 100),
- EnclosingIntRect(GetScrollContainerRelativeStickyBoxRect(constraints)));
+ EnclosingIntRect(constraints.scroll_container_relative_sticky_box_rect));
}
// Verifies that the sticky constraints are correct when the sticky position
@@ -366,10 +356,10 @@ TEST_F(LayoutBoxModelObjectTest, StickyPositionAnonymousContainer) {
scrollable_area->GetStickyConstraintsMap().at(sticky->Layer());
ASSERT_EQ(IntRect(15, 115, 170, 370),
EnclosingIntRect(
- GetScrollContainerRelativeContainingBlockRect(constraints)));
+ constraints.scroll_container_relative_containing_block_rect));
ASSERT_EQ(
IntRect(15, 165, 100, 100),
- EnclosingIntRect(GetScrollContainerRelativeStickyBoxRect(constraints)));
+ EnclosingIntRect(constraints.scroll_container_relative_sticky_box_rect));
}
TEST_F(LayoutBoxModelObjectTest, StickyPositionTableContainers) {
@@ -395,10 +385,10 @@ TEST_F(LayoutBoxModelObjectTest, StickyPositionTableContainers) {
scrollable_area->GetStickyConstraintsMap().at(sticky->Layer());
EXPECT_EQ(IntRect(0, 0, 50, 100),
EnclosingIntRect(
- GetScrollContainerRelativeContainingBlockRect(constraints)));
+ constraints.scroll_container_relative_containing_block_rect));
EXPECT_EQ(
IntRect(0, 50, 50, 50),
- EnclosingIntRect(GetScrollContainerRelativeStickyBoxRect(constraints)));
+ EnclosingIntRect(constraints.scroll_container_relative_sticky_box_rect));
}
// Tests that when a non-layer changes size it invalidates the constraints for
@@ -429,11 +419,10 @@ TEST_F(LayoutBoxModelObjectTest, StickyPositionConstraintInvalidation) {
ToLayoutBoxModelObject(GetLayoutObjectByElementId("target"));
EXPECT_TRUE(
scrollable_area->GetStickyConstraintsMap().Contains(sticky->Layer()));
- EXPECT_EQ(25.f,
- GetScrollContainerRelativeStickyBoxRect(
- scrollable_area->GetStickyConstraintsMap().at(sticky->Layer()))
- .Location()
- .X());
+ EXPECT_EQ(25.f, scrollable_area->GetStickyConstraintsMap()
+ .at(sticky->Layer())
+ .scroll_container_relative_sticky_box_rect.Location()
+ .X());
ToHTMLElement(target->GetNode())->classList().Add("hide");
GetDocument().View()->UpdateLifecycleToLayoutClean();
// Layout should invalidate the sticky constraints of the sticky element and
@@ -444,11 +433,10 @@ TEST_F(LayoutBoxModelObjectTest, StickyPositionConstraintInvalidation) {
// After updating compositing inputs we should have the updated position.
GetDocument().View()->UpdateAllLifecyclePhases();
- EXPECT_EQ(50.f,
- GetScrollContainerRelativeStickyBoxRect(
- scrollable_area->GetStickyConstraintsMap().at(sticky->Layer()))
- .Location()
- .X());
+ EXPECT_EQ(50.f, scrollable_area->GetStickyConstraintsMap()
+ .at(sticky->Layer())
+ .scroll_container_relative_sticky_box_rect.Location()
+ .X());
}
// Verifies that the correct sticky-box shifting ancestor is found when
@@ -499,18 +487,18 @@ TEST_F(LayoutBoxModelObjectTest,
// The outer block element trivially has no sticky-box shifting ancestor.
EXPECT_FALSE(constraints_map.at(sticky_outer_div)
- .NearestStickyLayerShiftingStickyBox());
+ .nearest_sticky_layer_shifting_sticky_box);
// Neither does the outer inline element, as its parent element is also its
// containing block.
EXPECT_FALSE(constraints_map.at(sticky_outer_inline)
- .NearestStickyLayerShiftingStickyBox());
+ .nearest_sticky_layer_shifting_sticky_box);
// However the inner inline element does have a sticky-box shifting ancestor,
// as its containing block is the ancestor block element, above its ancestor
// sticky element.
EXPECT_EQ(sticky_outer_inline, constraints_map.at(sticky_inner_inline)
- .NearestStickyLayerShiftingStickyBox());
+ .nearest_sticky_layer_shifting_sticky_box);
}
// Verifies that the correct containing-block shifting ancestor is found when
@@ -556,15 +544,15 @@ TEST_F(LayoutBoxModelObjectTest,
// The outer <div> should not detect the scroller as its containing-block
// shifting ancestor.
EXPECT_FALSE(constraints_map.at(sticky_parent)
- .NearestStickyLayerShiftingContainingBlock());
+ .nearest_sticky_layer_shifting_containing_block);
// Both inner children should detect the parent <div> as their
// containing-block shifting ancestor. They skip past unanchored sticky
// because it will never have a non-zero offset.
EXPECT_EQ(sticky_parent, constraints_map.at(sticky_child)
- .NearestStickyLayerShiftingContainingBlock());
+ .nearest_sticky_layer_shifting_containing_block);
EXPECT_EQ(sticky_parent, constraints_map.at(sticky_nested_child)
- .NearestStickyLayerShiftingContainingBlock());
+ .nearest_sticky_layer_shifting_containing_block);
}
// Verifies that the correct containing-block shifting ancestor is found when
@@ -596,7 +584,7 @@ TEST_F(LayoutBoxModelObjectTest,
// The grandchild sticky should detect the parent as its containing-block
// shifting ancestor.
EXPECT_EQ(sticky_parent, constraints_map.at(sticky_grandchild)
- .NearestStickyLayerShiftingContainingBlock());
+ .nearest_sticky_layer_shifting_containing_block);
}
// Verifies that the correct containing-block shifting ancestor is found when
@@ -629,7 +617,7 @@ TEST_F(LayoutBoxModelObjectTest,
// The table cell should detect the outer <div> as its containing-block
// shifting ancestor.
EXPECT_EQ(sticky_outer, constraints_map.at(sticky_th)
- .NearestStickyLayerShiftingContainingBlock());
+ .nearest_sticky_layer_shifting_containing_block);
}
// Verifies that the calculated position:sticky offsets are correct when we have
@@ -1051,9 +1039,9 @@ TEST_F(LayoutBoxModelObjectTest, StickyPositionNestedFixedPos) {
// The inner sticky should not detect the outer one as any sort of ancestor.
EXPECT_FALSE(constraints_map.at(inner_sticky->Layer())
- .NearestStickyLayerShiftingStickyBox());
+ .nearest_sticky_layer_shifting_sticky_box);
EXPECT_FALSE(constraints_map.at(inner_sticky->Layer())
- .NearestStickyLayerShiftingContainingBlock());
+ .nearest_sticky_layer_shifting_containing_block);
// Scroll the page down.
scrollable_area->ScrollToAbsolutePosition(
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 30156c6b95e..c131f801bb0 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
@@ -132,46 +132,48 @@ TEST_F(LayoutBoxTest, BackgroundRect) {
// translucent image extends to the borders.
LayoutBox* layout_box = ToLayoutBox(GetLayoutObjectByElementId("target1"));
EXPECT_EQ(LayoutRect(20, 20, 100, 100),
- layout_box->BackgroundRect(kBackgroundKnownOpaqueRect));
+ layout_box->PhysicalBackgroundRect(kBackgroundKnownOpaqueRect));
EXPECT_EQ(LayoutRect(0, 0, 140, 140),
- layout_box->BackgroundRect(kBackgroundClipRect));
+ layout_box->PhysicalBackgroundRect(kBackgroundClipRect));
// #target2's background color is opaque but only fills the padding-box
// because it has local attachment. This eclipses the content-box image.
layout_box = ToLayoutBox(GetLayoutObjectByElementId("target2"));
EXPECT_EQ(LayoutRect(10, 10, 120, 120),
- layout_box->BackgroundRect(kBackgroundKnownOpaqueRect));
+ layout_box->PhysicalBackgroundRect(kBackgroundKnownOpaqueRect));
EXPECT_EQ(LayoutRect(10, 10, 120, 120),
- layout_box->BackgroundRect(kBackgroundClipRect));
+ layout_box->PhysicalBackgroundRect(kBackgroundClipRect));
// #target3's background color is not opaque so we only have a clip rect.
layout_box = ToLayoutBox(GetLayoutObjectByElementId("target3"));
- EXPECT_TRUE(layout_box->BackgroundRect(kBackgroundKnownOpaqueRect).IsEmpty());
+ EXPECT_TRUE(
+ layout_box->PhysicalBackgroundRect(kBackgroundKnownOpaqueRect).IsEmpty());
EXPECT_EQ(LayoutRect(0, 0, 140, 140),
- layout_box->BackgroundRect(kBackgroundClipRect));
+ layout_box->PhysicalBackgroundRect(kBackgroundClipRect));
// #target4's background color has a blend mode so it isn't opaque.
layout_box = ToLayoutBox(GetLayoutObjectByElementId("target4"));
- EXPECT_TRUE(layout_box->BackgroundRect(kBackgroundKnownOpaqueRect).IsEmpty());
+ EXPECT_TRUE(
+ layout_box->PhysicalBackgroundRect(kBackgroundKnownOpaqueRect).IsEmpty());
EXPECT_EQ(LayoutRect(0, 0, 140, 140),
- layout_box->BackgroundRect(kBackgroundClipRect));
+ layout_box->PhysicalBackgroundRect(kBackgroundClipRect));
// #target5's solid background only covers the content-box but it has a "none"
// background covering the border box.
layout_box = ToLayoutBox(GetLayoutObjectByElementId("target5"));
EXPECT_EQ(LayoutRect(20, 20, 100, 100),
- layout_box->BackgroundRect(kBackgroundKnownOpaqueRect));
+ layout_box->PhysicalBackgroundRect(kBackgroundKnownOpaqueRect));
EXPECT_EQ(LayoutRect(0, 0, 140, 140),
- layout_box->BackgroundRect(kBackgroundClipRect));
+ layout_box->PhysicalBackgroundRect(kBackgroundClipRect));
// Because it can scroll due to local attachment, the opaque local background
// in #target6 is treated as padding box for the clip rect, but remains the
// content box for the known opaque rect.
layout_box = ToLayoutBox(GetLayoutObjectByElementId("target6"));
EXPECT_EQ(LayoutRect(20, 20, 100, 100),
- layout_box->BackgroundRect(kBackgroundKnownOpaqueRect));
+ layout_box->PhysicalBackgroundRect(kBackgroundKnownOpaqueRect));
EXPECT_EQ(LayoutRect(10, 10, 120, 120),
- layout_box->BackgroundRect(kBackgroundClipRect));
+ layout_box->PhysicalBackgroundRect(kBackgroundClipRect));
}
TEST_F(LayoutBoxTest, LocationContainer) {
@@ -453,7 +455,7 @@ class AnimatedImage : public StubImage {
bool MaybeAnimated() override { return true; }
};
-TEST_F(LayoutBoxTest, DeferredInvalidation) {
+TEST_F(LayoutBoxTest, DelayedInvalidation) {
SetBodyInnerHTML("<img id='image' style='width: 100px; height: 100px;'/>");
auto* obj = ToLayoutBox(GetLayoutObjectByElementId("image"));
ASSERT_TRUE(obj);
@@ -465,19 +467,24 @@ TEST_F(LayoutBoxTest, DeferredInvalidation) {
ToLayoutImage(obj)->ImageResource()->SetImageResource(image);
ASSERT_TRUE(ToLayoutImage(obj)->CachedImage()->GetImage()->MaybeAnimated());
- // CanDeferInvalidation::kYes results in a deferred invalidation.
obj->ClearPaintInvalidationFlags();
+ EXPECT_FALSE(obj->ShouldDoFullPaintInvalidation());
EXPECT_EQ(obj->FullPaintInvalidationReason(), PaintInvalidationReason::kNone);
+ EXPECT_FALSE(obj->ShouldDelayFullPaintInvalidation());
+
+ // CanDeferInvalidation::kYes results in a deferred invalidation.
obj->ImageChanged(image, ImageResourceObserver::CanDeferInvalidation::kYes);
+ EXPECT_FALSE(obj->ShouldDoFullPaintInvalidation());
EXPECT_EQ(obj->FullPaintInvalidationReason(),
- PaintInvalidationReason::kDelayedFull);
+ PaintInvalidationReason::kImage);
+ EXPECT_TRUE(obj->ShouldDelayFullPaintInvalidation());
// CanDeferInvalidation::kNo results in a immediate invalidation.
- obj->ClearPaintInvalidationFlags();
- EXPECT_EQ(obj->FullPaintInvalidationReason(), PaintInvalidationReason::kNone);
obj->ImageChanged(image, ImageResourceObserver::CanDeferInvalidation::kNo);
+ EXPECT_TRUE(obj->ShouldDoFullPaintInvalidation());
EXPECT_EQ(obj->FullPaintInvalidationReason(),
PaintInvalidationReason::kImage);
+ EXPECT_FALSE(obj->ShouldDelayFullPaintInvalidation());
}
TEST_F(LayoutBoxTest, MarkerContainerLayoutOverflowRect) {
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 054433df359..b5c23c5fc24 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_button.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_button.cc
@@ -34,7 +34,7 @@ void LayoutButton::AddChild(LayoutObject* new_child,
if (!inner_) {
// Create an anonymous block.
DCHECK(!FirstChild());
- inner_ = CreateAnonymousBlock(Style()->Display());
+ inner_ = CreateAnonymousBlock(StyleRef().Display());
LayoutFlexibleBox::AddChild(inner_);
}
@@ -66,13 +66,13 @@ void LayoutButton::UpdateAnonymousChildStyle(const LayoutObject* child,
// when the content overflows, treat it the same as align-items: flex-start.
child_style.SetMarginTop(Length());
child_style.SetMarginBottom(Length());
- child_style.SetFlexDirection(Style()->FlexDirection());
- child_style.SetJustifyContent(Style()->JustifyContent());
- child_style.SetFlexWrap(Style()->FlexWrap());
+ child_style.SetFlexDirection(StyleRef().FlexDirection());
+ child_style.SetJustifyContent(StyleRef().JustifyContent());
+ child_style.SetFlexWrap(StyleRef().FlexWrap());
// TODO (lajava): An anonymous box must not be used to resolve children's auto
// values.
- child_style.SetAlignItems(Style()->AlignItems());
- child_style.SetAlignContent(Style()->AlignContent());
+ child_style.SetAlignItems(StyleRef().AlignItems());
+ child_style.SetAlignContent(StyleRef().AlignContent());
}
LayoutRect LayoutButton::ControlClipRect(
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 81eab5fb614..afab92ce999 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_counter.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_counter.cc
@@ -484,7 +484,7 @@ scoped_refptr<StringImpl> LayoutCounter::OriginalText() const {
!before_after_container->IsPseudoElement())
return nullptr; // LayoutCounters are restricted to before and after
// pseudo elements
- PseudoId container_style = before_after_container->Style()->StyleType();
+ PseudoId container_style = before_after_container->StyleRef().StyleType();
if ((container_style == kPseudoIdBefore) ||
(container_style == kPseudoIdAfter))
break;
@@ -602,7 +602,7 @@ void LayoutCounter::LayoutObjectSubtreeWillBeDetached(
static void UpdateCounters(LayoutObject& layout_object) {
DCHECK(layout_object.Style());
const CounterDirectiveMap* directive_map =
- layout_object.Style()->GetCounterDirectives();
+ layout_object.StyleRef().GetCounterDirectives();
if (!directive_map)
return;
CounterDirectiveMap::const_iterator end = directive_map->end();
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 1d8a9b6e426..228b90affdf 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
@@ -42,18 +42,18 @@ class FlexBoxIterator {
public:
FlexBoxIterator(LayoutDeprecatedFlexibleBox* parent)
: box_(parent), largest_ordinal_(1) {
- if (box_->Style()->BoxOrient() == EBoxOrient::kHorizontal &&
- !box_->Style()->IsLeftToRightDirection())
- forward_ = box_->Style()->BoxDirection() != EBoxDirection::kNormal;
+ if (box_->StyleRef().BoxOrient() == EBoxOrient::kHorizontal &&
+ !box_->StyleRef().IsLeftToRightDirection())
+ forward_ = box_->StyleRef().BoxDirection() != EBoxDirection::kNormal;
else
- forward_ = box_->Style()->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.
LayoutBox* child = box_->FirstChildBox();
while (child) {
- if (child->Style()->BoxOrdinalGroup() > largest_ordinal_)
- largest_ordinal_ = child->Style()->BoxOrdinalGroup();
+ if (child->StyleRef().BoxOrdinalGroup() > largest_ordinal_)
+ largest_ordinal_ = child->StyleRef().BoxOrdinalGroup();
child = child->NextSiblingBox();
}
}
@@ -105,10 +105,10 @@ class FlexBoxIterator {
}
if (current_child_ && NotFirstOrdinalValue())
- ordinal_values_.insert(current_child_->Style()->BoxOrdinalGroup());
- } while (!current_child_ ||
- (!current_child_->IsAnonymous() &&
- current_child_->Style()->BoxOrdinalGroup() != current_ordinal_));
+ ordinal_values_.insert(current_child_->StyleRef().BoxOrdinalGroup());
+ } while (!current_child_ || (!current_child_->IsAnonymous() &&
+ current_child_->StyleRef().BoxOrdinalGroup() !=
+ current_ordinal_));
// This peice of code just exists for detecting if this iterator actually
// does something other than returning the default order.
@@ -129,7 +129,7 @@ class FlexBoxIterator {
bool NotFirstOrdinalValue() {
unsigned first_ordinal_value = forward_ ? 1 : largest_ordinal_;
return current_ordinal_ == first_ordinal_value &&
- current_child_->Style()->BoxOrdinalGroup() != first_ordinal_value;
+ current_child_->StyleRef().BoxOrdinalGroup() != first_ordinal_value;
}
LayoutDeprecatedFlexibleBox* box_;
@@ -148,14 +148,14 @@ class FlexBoxIterator {
// (crawling into blocks).
static bool ShouldCheckLines(LayoutBlockFlow* block_flow) {
return !block_flow->IsFloatingOrOutOfFlowPositioned() &&
- block_flow->Style()->Height().IsAuto();
+ block_flow->StyleRef().Height().IsAuto();
}
static int GetHeightForLineCount(const LayoutBlockFlow* block_flow,
int line_count,
bool include_bottom,
int& count) {
- if (block_flow->Style()->Visibility() != EVisibility::kVisible)
+ if (block_flow->StyleRef().Visibility() != EVisibility::kVisible)
return -1;
if (block_flow->ChildrenInline()) {
for (RootInlineBox* box = block_flow->FirstRootBox(); box;
@@ -197,7 +197,7 @@ static int GetHeightForLineCount(const LayoutBlockFlow* block_flow,
static RootInlineBox* LineAtIndex(const LayoutBlockFlow* block_flow, int i) {
DCHECK_GE(i, 0);
- if (block_flow->Style()->Visibility() != EVisibility::kVisible)
+ if (block_flow->StyleRef().Visibility() != EVisibility::kVisible)
return nullptr;
if (block_flow->ChildrenInline()) {
@@ -225,7 +225,7 @@ static RootInlineBox* LineAtIndex(const LayoutBlockFlow* block_flow, int i) {
static int LineCount(const LayoutBlockFlow* block_flow,
const RootInlineBox* stop_root_inline_box = nullptr,
bool* found = nullptr) {
- if (block_flow->Style()->Visibility() != EVisibility::kVisible)
+ if (block_flow->StyleRef().Visibility() != EVisibility::kVisible)
return 0;
int count = 0;
if (block_flow->ChildrenInline()) {
@@ -260,7 +260,7 @@ static int LineCount(const LayoutBlockFlow* block_flow,
}
static void ClearTruncation(LayoutBlockFlow* block_flow) {
- if (block_flow->Style()->Visibility() != EVisibility::kVisible)
+ if (block_flow->StyleRef().Visibility() != EVisibility::kVisible)
return;
if (block_flow->ChildrenInline() && block_flow->HasMarkupTruncation()) {
block_flow->SetHasMarkupTruncation(false);
@@ -303,8 +303,8 @@ static LayoutUnit MarginWidthForChild(LayoutBox* child) {
// A margin basically has three types: fixed, percentage, and auto (variable).
// Auto and percentage margins simply become 0 when computing min/max width.
// Fixed margins can be added in as is.
- Length margin_left = child->Style()->MarginLeft();
- Length margin_right = child->Style()->MarginRight();
+ Length margin_left = child->StyleRef().MarginLeft();
+ Length margin_right = child->StyleRef().MarginRight();
LayoutUnit margin;
if (margin_left.IsFixed())
margin += margin_left.Value();
@@ -316,7 +316,7 @@ static LayoutUnit MarginWidthForChild(LayoutBox* child) {
static bool ChildDoesNotAffectWidthOrFlexing(LayoutObject* child) {
// Positioned children and collapsed children don't affect the min/max width.
return child->IsOutOfFlowPositioned() ||
- child->Style()->Visibility() == EVisibility::kCollapse;
+ child->StyleRef().Visibility() == EVisibility::kCollapse;
}
static LayoutUnit WidthForChild(LayoutBox* child) {
@@ -393,14 +393,14 @@ void LayoutDeprecatedFlexibleBox::UpdateBlockLayout(bool relayout_children) {
UseCounter::Count(GetDocument(), WebFeature::kWebkitBoxLayout);
- if (Style()->BoxAlign() != ComputedStyleInitialValues::InitialBoxAlign())
+ if (StyleRef().BoxAlign() != ComputedStyleInitialValues::InitialBoxAlign())
UseCounter::Count(GetDocument(), WebFeature::kWebkitBoxAlignNotInitial);
- if (Style()->BoxDirection() !=
+ if (StyleRef().BoxDirection() !=
ComputedStyleInitialValues::InitialBoxDirection())
UseCounter::Count(GetDocument(), WebFeature::kWebkitBoxDirectionNotInitial);
- if (Style()->BoxPack() != ComputedStyleInitialValues::InitialBoxPack())
+ if (StyleRef().BoxPack() != ComputedStyleInitialValues::InitialBoxPack())
UseCounter::Count(GetDocument(), WebFeature::kWebkitBoxPackNotInitial);
if (!FirstChildBox()) {
@@ -433,8 +433,8 @@ void LayoutDeprecatedFlexibleBox::UpdateBlockLayout(bool relayout_children) {
if (previous_size != Size() ||
(Parent()->IsDeprecatedFlexibleBox() &&
- Parent()->Style()->BoxOrient() == EBoxOrient::kHorizontal &&
- Parent()->Style()->BoxAlign() == EBoxAlignment::kStretch))
+ Parent()->StyleRef().BoxOrient() == EBoxOrient::kHorizontal &&
+ Parent()->StyleRef().BoxAlign() == EBoxAlignment::kStretch))
relayout_children = true;
SetHeight(LayoutUnit());
@@ -471,11 +471,11 @@ static void GatherFlexChildrenInfo(FlexBoxIterator& iterator,
bool relayout_children,
bool& have_flex) {
for (LayoutBox* child = iterator.First(); child; child = iterator.Next()) {
- if (child->Style()->BoxFlex() !=
+ if (child->StyleRef().BoxFlex() !=
ComputedStyleInitialValues::InitialBoxFlex())
UseCounter::Count(document, WebFeature::kWebkitBoxChildFlexNotInitial);
- if (child->Style()->BoxOrdinalGroup() !=
+ if (child->StyleRef().BoxOrdinalGroup() !=
ComputedStyleInitialValues::InitialBoxOrdinalGroup()) {
UseCounter::Count(document,
WebFeature::kWebkitBoxChildOrdinalGroupNotInitial);
@@ -483,7 +483,7 @@ static void GatherFlexChildrenInfo(FlexBoxIterator& iterator,
// Check to see if this child flexes.
if (!ChildDoesNotAffectWidthOrFlexing(child) &&
- child->Style()->BoxFlex() > 0.0f) {
+ child->StyleRef().BoxFlex() > 0.0f) {
// We always have to lay out flexible objects again, since the flex
// distribution
// may have changed, and we need to reallocate space.
@@ -534,8 +534,8 @@ void LayoutDeprecatedFlexibleBox::LayoutHorizontalBox(bool relayout_children) {
// this file.
// We probably want to check if the element is replaced.
if (relayout_children || (child->IsAtomicInlineLevel() &&
- (child->Style()->Width().IsPercentOrCalc() ||
- child->Style()->Height().IsPercentOrCalc())))
+ (child->StyleRef().Width().IsPercentOrCalc() ||
+ child->StyleRef().Height().IsPercentOrCalc())))
layout_scope.SetChildNeedsLayout(child);
// Compute the child's vertical margins.
@@ -548,7 +548,7 @@ void LayoutDeprecatedFlexibleBox::LayoutHorizontalBox(bool relayout_children) {
child->LayoutIfNeeded();
// Update our height and overflow height.
- if (Style()->BoxAlign() == EBoxAlignment::kBaseline) {
+ if (StyleRef().BoxAlign() == EBoxAlignment::kBaseline) {
LayoutUnit ascent(child->FirstLineBoxBaseline());
if (ascent == -1)
ascent = child->Size().Height() + child->MarginBottom();
@@ -573,12 +573,14 @@ void LayoutDeprecatedFlexibleBox::LayoutHorizontalBox(bool relayout_children) {
UpdateFragmentationInfoForChild(*child);
}
- if (!iterator.First() && HasLineIfEmpty())
- SetHeight(Size().Height() + LineHeight(true,
- Style()->IsHorizontalWritingMode()
- ? kHorizontalLine
- : kVerticalLine,
- kPositionOfInteriorLineBoxes));
+ if (!iterator.First() && HasLineIfEmpty()) {
+ SetHeight(Size().Height() +
+ LineHeight(true,
+ StyleRef().IsHorizontalWritingMode()
+ ? kHorizontalLine
+ : kVerticalLine,
+ kPositionOfInteriorLineBoxes));
+ }
SetHeight(Size().Height() + to_add);
@@ -590,7 +592,7 @@ void LayoutDeprecatedFlexibleBox::LayoutHorizontalBox(bool relayout_children) {
height_specified = true;
// Now that our height is actually known, we can place our boxes.
- stretching_children_ = (Style()->BoxAlign() == EBoxAlignment::kStretch);
+ stretching_children_ = (StyleRef().BoxAlign() == EBoxAlignment::kStretch);
for (LayoutBox* child = iterator.First(); child; child = iterator.Next()) {
if (child->IsOutOfFlowPositioned()) {
child->ContainingBlock()->InsertPositionedObject(child);
@@ -598,14 +600,14 @@ void LayoutDeprecatedFlexibleBox::LayoutHorizontalBox(bool relayout_children) {
child_layer->SetStaticInlinePosition(x_pos);
if (child_layer->StaticBlockPosition() != y_pos) {
child_layer->SetStaticBlockPosition(y_pos);
- if (child->Style()->HasStaticBlockPosition(
- Style()->IsHorizontalWritingMode()))
+ if (child->StyleRef().HasStaticBlockPosition(
+ StyleRef().IsHorizontalWritingMode()))
child->SetChildNeedsLayout(kMarkOnlyThis);
}
continue;
}
- if (child->Style()->Visibility() == EVisibility::kCollapse) {
+ if (child->StyleRef().Visibility() == EVisibility::kCollapse) {
// visibility: collapsed children do not participate in our positioning.
// But we need to lay them down.
child->LayoutIfNeeded();
@@ -635,7 +637,7 @@ void LayoutDeprecatedFlexibleBox::LayoutHorizontalBox(bool relayout_children) {
// We can place the child now, using our value of box-align.
x_pos += child->MarginLeft();
LayoutUnit child_y = y_pos;
- switch (Style()->BoxAlign()) {
+ switch (StyleRef().BoxAlign()) {
case EBoxAlignment::kCenter:
child_y += child->MarginTop() +
((ContentHeight() -
@@ -691,7 +693,7 @@ void LayoutDeprecatedFlexibleBox::LayoutHorizontalBox(bool relayout_children) {
for (LayoutBox* child = iterator.First(); child;
child = iterator.Next()) {
if (AllowedChildFlex(child, expanding))
- total_flex += child->Style()->BoxFlex();
+ total_flex += child->StyleRef().BoxFlex();
}
LayoutUnit space_available_this_pass = remaining_space;
for (LayoutBox* child = iterator.First(); child;
@@ -702,7 +704,7 @@ void LayoutDeprecatedFlexibleBox::LayoutHorizontalBox(bool relayout_children) {
(allowed_flex == LayoutUnit::Max())
? allowed_flex
: LayoutUnit(allowed_flex *
- (total_flex / child->Style()->BoxFlex()));
+ (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);
@@ -717,13 +719,13 @@ void LayoutDeprecatedFlexibleBox::LayoutHorizontalBox(bool relayout_children) {
for (LayoutBox* child = iterator.First();
child && space_available_this_pass && total_flex;
child = iterator.Next()) {
- if (child->Style()->Visibility() == EVisibility::kCollapse)
+ if (child->StyleRef().Visibility() == EVisibility::kCollapse)
continue;
if (AllowedChildFlex(child, expanding)) {
LayoutUnit space_add =
LayoutUnit(space_available_this_pass *
- (child->Style()->BoxFlex() / total_flex));
+ (child->StyleRef().BoxFlex() / total_flex));
if (space_add) {
child->SetOverrideLogicalWidth(WidthForChild(child) + space_add);
flexing_children = true;
@@ -733,7 +735,7 @@ void LayoutDeprecatedFlexibleBox::LayoutHorizontalBox(bool relayout_children) {
space_available_this_pass -= space_add;
remaining_space -= space_add;
- total_flex -= child->Style()->BoxFlex();
+ total_flex -= child->StyleRef().BoxFlex();
}
}
if (remaining_space == remaining_space_at_beginning) {
@@ -758,13 +760,13 @@ void LayoutDeprecatedFlexibleBox::LayoutHorizontalBox(bool relayout_children) {
}
} while (have_flex);
- if (remaining_space > 0 && ((Style()->IsLeftToRightDirection() &&
- Style()->BoxPack() != EBoxPack::kStart) ||
- (!Style()->IsLeftToRightDirection() &&
- Style()->BoxPack() != EBoxPack::kEnd))) {
+ if (remaining_space > 0 && ((StyleRef().IsLeftToRightDirection() &&
+ StyleRef().BoxPack() != EBoxPack::kStart) ||
+ (!StyleRef().IsLeftToRightDirection() &&
+ StyleRef().BoxPack() != EBoxPack::kEnd))) {
// Children must be repositioned.
LayoutUnit offset;
- if (Style()->BoxPack() == EBoxPack::kJustify) {
+ if (StyleRef().BoxPack() == EBoxPack::kJustify) {
// Determine the total number of children.
int total_children = 0;
for (LayoutBox* child = iterator.First(); child;
@@ -798,7 +800,7 @@ void LayoutDeprecatedFlexibleBox::LayoutHorizontalBox(bool relayout_children) {
}
}
} else {
- if (Style()->BoxPack() == EBoxPack::kCenter)
+ if (StyleRef().BoxPack() == EBoxPack::kCenter)
offset += remaining_space / 2;
else // END for LTR, START for RTL
offset += remaining_space;
@@ -836,7 +838,7 @@ void LayoutDeprecatedFlexibleBox::LayoutVerticalBox(bool relayout_children) {
// We confine the line clamp ugliness to vertical flexible boxes (thus keeping
// it out of
// mainstream block layout); this is not really part of the XUL box model.
- if (Style()->HasLineClamp())
+ if (StyleRef().HasLineClamp())
ApplyLineClamp(iterator, relayout_children);
PaintLayerScrollableArea::DelayScrollOffsetClampScope delay_clamp_scope;
@@ -856,21 +858,22 @@ void LayoutDeprecatedFlexibleBox::LayoutVerticalBox(bool relayout_children) {
child_layer->SetStaticInlinePosition(BorderStart() + PaddingStart());
if (child_layer->StaticBlockPosition() != Size().Height()) {
child_layer->SetStaticBlockPosition(Size().Height());
- if (child->Style()->HasStaticBlockPosition(
- Style()->IsHorizontalWritingMode()))
+ if (child->StyleRef().HasStaticBlockPosition(
+ StyleRef().IsHorizontalWritingMode()))
child->SetChildNeedsLayout(kMarkOnlyThis);
}
continue;
}
SubtreeLayoutScope layout_scope(*child);
- if (!Style()->HasLineClamp() &&
- (relayout_children || (child->IsAtomicInlineLevel() &&
- (child->Style()->Width().IsPercentOrCalc() ||
- child->Style()->Height().IsPercentOrCalc()))))
+ if (!StyleRef().HasLineClamp() &&
+ (relayout_children ||
+ (child->IsAtomicInlineLevel() &&
+ (child->StyleRef().Width().IsPercentOrCalc() ||
+ child->StyleRef().Height().IsPercentOrCalc()))))
layout_scope.SetChildNeedsLayout(child);
- if (child->Style()->Visibility() == EVisibility::kCollapse) {
+ if (child->StyleRef().Visibility() == EVisibility::kCollapse) {
// visibility: collapsed children do not participate in our positioning.
// But we need to lay them down.
child->LayoutIfNeeded();
@@ -891,7 +894,7 @@ void LayoutDeprecatedFlexibleBox::LayoutVerticalBox(bool relayout_children) {
// We can place the child now, using our value of box-align.
LayoutUnit child_x = BorderLeft() + PaddingLeft();
- switch (Style()->BoxAlign()) {
+ switch (StyleRef().BoxAlign()) {
case EBoxAlignment::kCenter:
case EBoxAlignment::kBaseline: // Baseline just maps to center for
// vertical boxes
@@ -902,7 +905,7 @@ void LayoutDeprecatedFlexibleBox::LayoutVerticalBox(bool relayout_children) {
.ClampNegativeToZero();
break;
case EBoxAlignment::kEnd:
- if (!Style()->IsLeftToRightDirection()) {
+ if (!StyleRef().IsLeftToRightDirection()) {
child_x += child->MarginLeft();
} else {
child_x +=
@@ -910,7 +913,7 @@ void LayoutDeprecatedFlexibleBox::LayoutVerticalBox(bool relayout_children) {
}
break;
default: // BSTART/BSTRETCH
- if (Style()->IsLeftToRightDirection()) {
+ if (StyleRef().IsLeftToRightDirection()) {
child_x += child->MarginLeft();
} else {
child_x +=
@@ -930,12 +933,14 @@ void LayoutDeprecatedFlexibleBox::LayoutVerticalBox(bool relayout_children) {
y_pos = Size().Height();
- if (!iterator.First() && HasLineIfEmpty())
- SetHeight(Size().Height() + LineHeight(true,
- Style()->IsHorizontalWritingMode()
- ? kHorizontalLine
- : kVerticalLine,
- kPositionOfInteriorLineBoxes));
+ if (!iterator.First() && HasLineIfEmpty()) {
+ SetHeight(Size().Height() +
+ LineHeight(true,
+ StyleRef().IsHorizontalWritingMode()
+ ? kHorizontalLine
+ : kVerticalLine,
+ kPositionOfInteriorLineBoxes));
+ }
SetHeight(Size().Height() + to_add);
@@ -977,7 +982,7 @@ void LayoutDeprecatedFlexibleBox::LayoutVerticalBox(bool relayout_children) {
for (LayoutBox* child = iterator.First(); child;
child = iterator.Next()) {
if (AllowedChildFlex(child, expanding))
- total_flex += child->Style()->BoxFlex();
+ total_flex += child->StyleRef().BoxFlex();
}
LayoutUnit space_available_this_pass = remaining_space;
for (LayoutBox* child = iterator.First(); child;
@@ -989,7 +994,7 @@ void LayoutDeprecatedFlexibleBox::LayoutVerticalBox(bool relayout_children) {
? allowed_flex
: static_cast<LayoutUnit>(
allowed_flex *
- (total_flex / child->Style()->BoxFlex()));
+ (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);
@@ -1007,7 +1012,7 @@ void LayoutDeprecatedFlexibleBox::LayoutVerticalBox(bool relayout_children) {
if (AllowedChildFlex(child, expanding)) {
LayoutUnit space_add = static_cast<LayoutUnit>(
space_available_this_pass *
- (child->Style()->BoxFlex() / total_flex));
+ (child->StyleRef().BoxFlex() / total_flex));
if (space_add) {
child->SetOverrideLogicalHeight(HeightForChild(child) +
space_add);
@@ -1018,7 +1023,7 @@ void LayoutDeprecatedFlexibleBox::LayoutVerticalBox(bool relayout_children) {
space_available_this_pass -= space_add;
remaining_space -= space_add;
- total_flex -= child->Style()->BoxFlex();
+ total_flex -= child->StyleRef().BoxFlex();
}
}
if (remaining_space == remaining_space_at_beginning) {
@@ -1044,10 +1049,10 @@ void LayoutDeprecatedFlexibleBox::LayoutVerticalBox(bool relayout_children) {
}
} while (have_flex);
- if (Style()->BoxPack() != EBoxPack::kStart && remaining_space > 0) {
+ if (StyleRef().BoxPack() != EBoxPack::kStart && remaining_space > 0) {
// Children must be repositioned.
LayoutUnit offset;
- if (Style()->BoxPack() == EBoxPack::kJustify) {
+ if (StyleRef().BoxPack() == EBoxPack::kJustify) {
// Determine the total number of children.
int total_children = 0;
for (LayoutBox* child = iterator.First(); child;
@@ -1081,7 +1086,7 @@ void LayoutDeprecatedFlexibleBox::LayoutVerticalBox(bool relayout_children) {
}
}
} else {
- if (Style()->BoxPack() == EBoxPack::kCenter)
+ if (StyleRef().BoxPack() == EBoxPack::kCenter)
offset += remaining_space / 2;
else // END
offset += remaining_space;
@@ -1131,9 +1136,9 @@ void LayoutDeprecatedFlexibleBox::ApplyLineClamp(FlexBoxIterator& iterator,
child->ClearOverrideSize();
if (relayout_children ||
(child->IsAtomicInlineLevel() &&
- (child->Style()->Width().IsPercentOrCalc() ||
- child->Style()->Height().IsPercentOrCalc())) ||
- (child->Style()->Height().IsAuto() && child->IsLayoutBlock())) {
+ (child->StyleRef().Width().IsPercentOrCalc() ||
+ child->StyleRef().Height().IsPercentOrCalc())) ||
+ (child->StyleRef().Height().IsAuto() && child->IsLayoutBlock())) {
child->SetChildNeedsLayout(kMarkOnlyThis);
// Dirty all the positioned objects.
@@ -1143,7 +1148,7 @@ void LayoutDeprecatedFlexibleBox::ApplyLineClamp(FlexBoxIterator& iterator,
}
}
child->LayoutIfNeeded();
- if (child->Style()->Height().IsAuto() && child->IsLayoutBlockFlow())
+ if (child->StyleRef().Height().IsAuto() && child->IsLayoutBlockFlow())
max_line_count =
std::max(max_line_count, LineCount(ToLayoutBlockFlow(child)));
}
@@ -1151,7 +1156,7 @@ void LayoutDeprecatedFlexibleBox::ApplyLineClamp(FlexBoxIterator& iterator,
// Get the number of lines and then alter all block flow children with auto
// height to use the
// specified height. We always try to leave room for at least one line.
- int num_visible_lines = Style()->LineClamp();
+ int num_visible_lines = StyleRef().LineClamp();
DCHECK_GT(num_visible_lines, 0);
if (num_visible_lines >= max_line_count)
@@ -1159,7 +1164,7 @@ void LayoutDeprecatedFlexibleBox::ApplyLineClamp(FlexBoxIterator& iterator,
for (LayoutBox* child = iterator.First(); child; child = iterator.Next()) {
if (ChildDoesNotAffectWidthOrFlexing(child) ||
- !child->Style()->Height().IsAuto() || !child->IsLayoutBlockFlow())
+ !child->StyleRef().Height().IsAuto() || !child->IsLayoutBlockFlow())
continue;
LayoutBlockFlow* block_child = ToLayoutBlockFlow(child);
@@ -1177,7 +1182,7 @@ void LayoutDeprecatedFlexibleBox::ApplyLineClamp(FlexBoxIterator& iterator,
child->ForceChildLayout();
// FIXME: For now don't support RTL.
- if (Style()->Direction() != TextDirection::kLtr)
+ if (StyleRef().Direction() != TextDirection::kLtr)
continue;
// Get the last line
@@ -1195,7 +1200,7 @@ void LayoutDeprecatedFlexibleBox::ApplyLineClamp(FlexBoxIterator& iterator,
const Font& font = Style(num_visible_lines == 1)->GetFont();
float total_width =
font.Width(ConstructTextRun(font, &kHorizontalEllipsisCharacter, 1,
- StyleRef(), Style()->Direction()));
+ StyleRef(), StyleRef().Direction()));
// See if this width can be accommodated on the last visible line
LineLayoutBlockFlow dest_block = last_visible_line->Block();
@@ -1203,10 +1208,10 @@ void LayoutDeprecatedFlexibleBox::ApplyLineClamp(FlexBoxIterator& iterator,
// FIXME: Directions of src/destBlock could be different from our direction
// and from one another.
- if (!src_block.Style()->IsLeftToRightDirection())
+ if (!src_block.StyleRef().IsLeftToRightDirection())
continue;
- bool left_to_right = dest_block.Style()->IsLeftToRightDirection();
+ bool left_to_right = dest_block.StyleRef().IsLeftToRightDirection();
if (!left_to_right)
continue;
@@ -1243,9 +1248,9 @@ void LayoutDeprecatedFlexibleBox::ClearLineClamp() {
child->ClearOverrideSize();
if ((child->IsAtomicInlineLevel() &&
- (child->Style()->Width().IsPercentOrCalc() ||
- child->Style()->Height().IsPercentOrCalc())) ||
- (child->Style()->Height().IsAuto() && child->IsLayoutBlock())) {
+ (child->StyleRef().Width().IsPercentOrCalc() ||
+ child->StyleRef().Height().IsPercentOrCalc())) ||
+ (child->StyleRef().Height().IsAuto() && child->IsLayoutBlock())) {
child->SetChildNeedsLayout();
if (child->IsLayoutBlockFlow()) {
@@ -1260,7 +1265,7 @@ void LayoutDeprecatedFlexibleBox::PlaceChild(LayoutBox* child,
const LayoutPoint& location) {
// FIXME Investigate if this can be removed based on other flags.
// crbug.com/370010
- child->SetMayNeedPaintInvalidation();
+ child->SetShouldCheckForPaintInvalidation();
// Place the child.
child->SetLocation(location);
@@ -1269,7 +1274,7 @@ void LayoutDeprecatedFlexibleBox::PlaceChild(LayoutBox* child,
LayoutUnit LayoutDeprecatedFlexibleBox::AllowedChildFlex(LayoutBox* child,
bool expanding) {
if (ChildDoesNotAffectWidthOrFlexing(child) ||
- child->Style()->BoxFlex() == 0.0f)
+ child->StyleRef().BoxFlex() == 0.0f)
return LayoutUnit();
if (expanding) {
@@ -1277,8 +1282,8 @@ LayoutUnit LayoutDeprecatedFlexibleBox::AllowedChildFlex(LayoutBox* child,
// FIXME: For now just handle fixed values.
LayoutUnit max_width = LayoutUnit::Max();
LayoutUnit width = ContentWidthForChild(child);
- if (child->Style()->MaxWidth().IsFixed())
- max_width = LayoutUnit(child->Style()->MaxWidth().Value());
+ 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();
@@ -1286,8 +1291,8 @@ LayoutUnit LayoutDeprecatedFlexibleBox::AllowedChildFlex(LayoutBox* child,
// FIXME: For now just handle fixed values.
LayoutUnit max_height = LayoutUnit::Max();
LayoutUnit height = ContentHeightForChild(child);
- if (child->Style()->MaxHeight().IsFixed())
- max_height = LayoutUnit(child->Style()->MaxHeight().Value());
+ if (child->StyleRef().MaxHeight().IsFixed())
+ max_height = LayoutUnit(child->StyleRef().MaxHeight().Value());
if (max_height == LayoutUnit::Max())
return max_height;
return (max_height - height).ClampNegativeToZero();
@@ -1297,7 +1302,7 @@ LayoutUnit LayoutDeprecatedFlexibleBox::AllowedChildFlex(LayoutBox* child,
if (IsHorizontal()) {
LayoutUnit min_width = child->MinPreferredLogicalWidth();
LayoutUnit width = ContentWidthForChild(child);
- const Length& min_width_length = child->Style()->MinWidth();
+ 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())
@@ -1306,7 +1311,7 @@ LayoutUnit LayoutDeprecatedFlexibleBox::AllowedChildFlex(LayoutBox* child,
LayoutUnit allowed_shrinkage = (min_width - width).ClampPositiveToZero();
return allowed_shrinkage;
}
- const Length& min_height_length = child->Style()->MinHeight();
+ const Length& min_height_length = child->StyleRef().MinHeight();
if (min_height_length.IsFixed() || min_height_length.IsAuto()) {
LayoutUnit min_height(min_height_length.Value());
LayoutUnit height = ContentHeightForChild(child);
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 5b52ab81b37..f70000471da 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
@@ -56,10 +56,10 @@ class LayoutDeprecatedFlexibleBox final : public LayoutBlock {
LayoutUnit AllowedChildFlex(LayoutBox* child, bool expanding);
bool IsVertical() const {
- return Style()->BoxOrient() == EBoxOrient::kVertical;
+ return StyleRef().BoxOrient() == EBoxOrient::kVertical;
}
bool IsHorizontal() const {
- return Style()->BoxOrient() == EBoxOrient::kHorizontal;
+ return StyleRef().BoxOrient() == EBoxOrient::kHorizontal;
}
void ApplyLineClamp(FlexBoxIterator&, bool relayout_children);
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_details_marker.cc b/chromium/third_party/blink/renderer/core/layout/layout_details_marker.cc
index b5fdf263ff0..16f354effd5 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_details_marker.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_details_marker.cc
@@ -33,17 +33,17 @@ LayoutDetailsMarker::LayoutDetailsMarker(Element* element)
: LayoutBlockFlow(element) {}
LayoutDetailsMarker::Orientation LayoutDetailsMarker::GetOrientation() const {
- switch (Style()->GetWritingMode()) {
+ switch (StyleRef().GetWritingMode()) {
case WritingMode::kHorizontalTb:
- if (Style()->IsLeftToRightDirection())
+ if (StyleRef().IsLeftToRightDirection())
return IsOpen() ? kDown : kRight;
return IsOpen() ? kDown : kLeft;
case WritingMode::kVerticalRl:
- if (Style()->IsLeftToRightDirection())
+ if (StyleRef().IsLeftToRightDirection())
return IsOpen() ? kLeft : kDown;
return IsOpen() ? kLeft : kUp;
case WritingMode::kVerticalLr:
- if (Style()->IsLeftToRightDirection())
+ if (StyleRef().IsLeftToRightDirection())
return IsOpen() ? kRight : kDown;
return IsOpen() ? kRight : kUp;
// TODO(layout-dev): Sideways-lr and sideways-rl are not yet supported.
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 b5991e0691c..ccef8ac73df 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
@@ -35,7 +35,6 @@
#include "third_party/blink/renderer/core/layout/hit_test_result.h"
#include "third_party/blink/renderer/core/layout/layout_analyzer.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
-#include "third_party/blink/renderer/core/page/scrolling/root_scroller_util.h"
#include "third_party/blink/renderer/core/paint/embedded_content_painter.h"
namespace blink {
@@ -160,7 +159,7 @@ bool LayoutEmbeddedContent::NodeAtPointOverEmbeddedContentView(
if ((inside || location_in_container.IsRectBasedTest()) && !had_result &&
result.InnerNode() == GetNode()) {
result.SetIsOverEmbeddedContentView(
- ContentBoxRect().Contains(result.LocalPoint()));
+ PhysicalContentBoxRect().Contains(result.LocalPoint()));
}
return inside;
}
@@ -171,8 +170,9 @@ bool LayoutEmbeddedContent::NodeAtPoint(
const LayoutPoint& accumulated_offset,
HitTestAction action) {
FrameView* frame_view = ChildFrameView();
- if (!frame_view || !frame_view->IsLocalFrameView() ||
- !result.GetHitTestRequest().AllowsChildFrameContent()) {
+ bool skip_contents = (result.GetHitTestRequest().GetStopNode() == this ||
+ !result.GetHitTestRequest().AllowsChildFrameContent());
+ if (!frame_view || !frame_view->IsLocalFrameView() || skip_contents) {
return NodeAtPointOverEmbeddedContentView(result, location_in_container,
accumulated_offset, action);
}
@@ -199,8 +199,10 @@ bool LayoutEmbeddedContent::NodeAtPoint(
LayoutPoint(BorderLeft() + PaddingLeft(), BorderTop() + PaddingTop());
HitTestLocation new_hit_test_location(
location_in_container, -adjusted_location - content_offset);
- HitTestRequest new_hit_test_request(result.GetHitTestRequest().GetType() |
- HitTestRequest::kChildFrameHitTest);
+ HitTestRequest new_hit_test_request(
+ result.GetHitTestRequest().GetType() |
+ HitTestRequest::kChildFrameHitTest,
+ result.GetHitTestRequest().GetStopNode());
HitTestResult child_frame_result(new_hit_test_request,
new_hit_test_location);
@@ -257,7 +259,7 @@ void LayoutEmbeddedContent::StyleDidChange(StyleDifference diff,
if (!embedded_content_view)
return;
- if (Style()->Visibility() != EVisibility::kVisible) {
+ if (StyleRef().Visibility() != EVisibility::kVisible) {
embedded_content_view->Hide();
} else {
embedded_content_view->Show();
@@ -271,14 +273,17 @@ void LayoutEmbeddedContent::UpdateLayout() {
ClearNeedsLayout();
}
-void LayoutEmbeddedContent::Paint(const PaintInfo& paint_info) const {
- EmbeddedContentPainter(*this).Paint(paint_info);
-}
-
-void LayoutEmbeddedContent::PaintContents(
+void LayoutEmbeddedContent::PaintReplaced(
const PaintInfo& paint_info,
const LayoutPoint& paint_offset) const {
- EmbeddedContentPainter(*this).PaintContents(paint_info, paint_offset);
+ EmbeddedContentPainter(*this).PaintReplaced(paint_info, paint_offset);
+}
+
+void LayoutEmbeddedContent::InvalidatePaint(
+ const PaintInvalidatorContext& context) const {
+ LayoutReplaced::InvalidatePaint(context);
+ if (auto* plugin = Plugin())
+ plugin->InvalidatePaint();
}
CursorDirective LayoutEmbeddedContent::GetCursor(const LayoutPoint& point,
@@ -292,19 +297,16 @@ CursorDirective LayoutEmbeddedContent::GetCursor(const LayoutPoint& point,
}
LayoutRect LayoutEmbeddedContent::ReplacedContentRect() const {
+ LayoutRect content_rect = PhysicalContentBoxRect();
+ // IFrames set as the root scroller should get their size from their parent.
+ if (ChildFrameView() && View() && IsEffectiveRootScroller())
+ content_rect = LayoutRect(LayoutPoint(), View()->ViewRect().Size());
+
// We don't propagate sub-pixel into sub-frame layout, in other words, the
// rect is snapped at the document boundary, and sub-pixel movement could
// cause the sub-frame to layout due to the 1px snap difference. In order to
// avoid that, the size of sub-frame is rounded in advance.
- LayoutRect size_rounded_rect = ContentBoxRect();
-
- // IFrames set as the root scroller should get their size from their parent.
- if (ChildFrameView() && View() && RootScrollerUtil::IsEffective(*this))
- size_rounded_rect = LayoutRect(LayoutPoint(), View()->ViewRect().Size());
-
- size_rounded_rect.SetSize(
- LayoutSize(RoundedIntSize(size_rounded_rect.Size())));
- return size_rounded_rect;
+ return PreSnappedRectForPersistentSizing(content_rect);
}
void LayoutEmbeddedContent::UpdateOnEmbeddedContentViewChange() {
@@ -318,7 +320,7 @@ void LayoutEmbeddedContent::UpdateOnEmbeddedContentViewChange() {
if (!NeedsLayout())
UpdateGeometry(*embedded_content_view);
- if (Style()->Visibility() != EVisibility::kVisible) {
+ if (StyleRef().Visibility() != EVisibility::kVisible) {
embedded_content_view->Hide();
} else {
embedded_content_view->Show();
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 03a429008ef..8f598652a42 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
@@ -63,8 +63,6 @@ class CORE_EXPORT LayoutEmbeddedContent : public LayoutReplaced {
void UpdateGeometry(EmbeddedContentView&);
bool IsLayoutEmbeddedContent() const final { return true; }
- virtual void PaintContents(const PaintInfo&,
- const LayoutPoint& paint_offset) const;
bool IsThrottledFrameView() const;
@@ -73,7 +71,9 @@ class CORE_EXPORT LayoutEmbeddedContent : public LayoutReplaced {
void StyleDidChange(StyleDifference, const ComputedStyle* old_style) final;
void UpdateLayout() override;
- void Paint(const PaintInfo&) const override;
+ void PaintReplaced(const PaintInfo&,
+ const LayoutPoint& paint_offset) const override;
+ void InvalidatePaint(const PaintInvalidatorContext&) const final;
CursorDirective GetCursor(const LayoutPoint&, Cursor&) const final;
bool CanBeSelectionLeafInternal() const final { return true; }
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_embedded_object.cc b/chromium/third_party/blink/renderer/core/layout/layout_embedded_object.cc
index 696c65e019f..58387dc7a89 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_embedded_object.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_embedded_object.cc
@@ -34,7 +34,6 @@
#include "third_party/blink/renderer/core/layout/layout_analyzer.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/embedded_object_paint_invalidator.h"
#include "third_party/blink/renderer/core/paint/embedded_object_painter.h"
#include "third_party/blink/renderer/platform/text/platform_locale.h"
@@ -83,36 +82,12 @@ bool LayoutEmbeddedObject::ShowsUnavailablePluginIndicator() const {
return plugin_availability_ != kPluginAvailable;
}
-void LayoutEmbeddedObject::PaintContents(
- const PaintInfo& paint_info,
- const LayoutPoint& paint_offset) const {
- Element* element = ToElement(GetNode());
- if (!IsHTMLPlugInElement(element))
- return;
-
- LayoutEmbeddedContent::PaintContents(paint_info, paint_offset);
-}
-
-void LayoutEmbeddedObject::Paint(const PaintInfo& paint_info) const {
- if (ShowsUnavailablePluginIndicator()) {
- LayoutReplaced::Paint(paint_info);
- return;
- }
-
- LayoutEmbeddedContent::Paint(paint_info);
-}
-
void LayoutEmbeddedObject::PaintReplaced(
const PaintInfo& paint_info,
const LayoutPoint& paint_offset) const {
EmbeddedObjectPainter(*this).PaintReplaced(paint_info, paint_offset);
}
-PaintInvalidationReason LayoutEmbeddedObject::InvalidatePaint(
- const PaintInvalidatorContext& context) const {
- return EmbeddedObjectPaintInvalidator(*this, context).InvalidatePaint();
-}
-
void LayoutEmbeddedObject::UpdateLayout() {
DCHECK(NeedsLayout());
LayoutAnalyzer::Scope analyzer(*this);
@@ -143,7 +118,7 @@ void LayoutEmbeddedObject::ComputeIntrinsicSizingInfo(
if (frame_view && frame_view->GetIntrinsicSizingInfo(intrinsic_sizing_info)) {
// Handle zoom & vertical writing modes here, as the embedded document
// doesn't know about them.
- intrinsic_sizing_info.size.Scale(Style()->EffectiveZoom());
+ intrinsic_sizing_info.size.Scale(StyleRef().EffectiveZoom());
if (!IsHorizontalWritingMode())
intrinsic_sizing_info.Transpose();
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_embedded_object.h b/chromium/third_party/blink/renderer/core/layout/layout_embedded_object.h
index 88d4ea15a1a..42cd2a20509 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_embedded_object.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_embedded_object.h
@@ -50,13 +50,8 @@ class LayoutEmbeddedObject final : public LayoutEmbeddedContent {
}
private:
- void PaintContents(const PaintInfo&,
- const LayoutPoint& paint_offset) const final;
void PaintReplaced(const PaintInfo&,
const LayoutPoint& paint_offset) const final;
- void Paint(const PaintInfo&) const final;
- PaintInvalidationReason InvalidatePaint(
- const PaintInvalidatorContext&) const final;
void UpdateLayout() final;
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 b872b41039f..2d661fb9b0a 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_fieldset.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_fieldset.cc
@@ -39,8 +39,8 @@ void LayoutFieldset::ComputePreferredLogicalWidths() {
if (LayoutBox* legend = FindInFlowLegend()) {
int legend_min_width = legend->MinPreferredLogicalWidth().ToInt();
- Length legend_margin_left = legend->Style()->MarginLeft();
- Length legend_margin_right = legend->Style()->MarginRight();
+ Length legend_margin_left = legend->StyleRef().MarginLeft();
+ Length legend_margin_right = legend->StyleRef().MarginRight();
if (legend_margin_left.IsFixed())
legend_min_width += legend_margin_left.Value();
@@ -66,8 +66,8 @@ LayoutObject* LayoutFieldset::LayoutSpecialExcludedChild(bool relayout_children,
legend->LayoutIfNeeded();
LayoutUnit logical_left;
- if (Style()->IsLeftToRightDirection()) {
- switch (legend->Style()->GetTextAlign()) {
+ if (StyleRef().IsLeftToRightDirection()) {
+ switch (legend->StyleRef().GetTextAlign()) {
case ETextAlign::kCenter:
logical_left = (LogicalWidth() - LogicalWidthForChild(*legend)) / 2;
break;
@@ -81,7 +81,7 @@ LayoutObject* LayoutFieldset::LayoutSpecialExcludedChild(bool relayout_children,
break;
}
} else {
- switch (legend->Style()->GetTextAlign()) {
+ switch (legend->StyleRef().GetTextAlign()) {
case ETextAlign::kLeft:
logical_left = BorderStart() + PaddingStart();
break;
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 3624f931377..c0bc37891ee 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
@@ -38,6 +38,7 @@ namespace blink {
using namespace HTMLNames;
const int kDefaultWidthNumChars = 34;
+const int kButtonShadowHeight = 2;
LayoutFileUploadControl::LayoutFileUploadControl(HTMLInputElement* input)
: LayoutBlockFlow(input),
@@ -70,7 +71,7 @@ int LayoutFileUploadControl::MaxFilenameWidth() const {
(UploadButton() && UploadButton()->GetLayoutBox())
? UploadButton()->GetLayoutBox()->PixelSnappedWidth()
: 0;
- return std::max(0, ContentBoxRect().PixelSnappedWidth() -
+ return std::max(0, PhysicalContentBoxRect().PixelSnappedWidth() -
upload_button_width - kAfterButtonSpacing);
}
@@ -87,7 +88,7 @@ void LayoutFileUploadControl::ComputeIntrinsicLogicalWidths(
// characters (using "0" as the nominal character).
const UChar kCharacter = '0';
const String character_as_string = String(&kCharacter, 1);
- const Font& font = Style()->GetFont();
+ const Font& font = StyleRef().GetFont();
float min_default_label_width =
kDefaultWidthNumChars *
font.Width(ConstructTextRun(font, character_as_string, StyleRef(),
@@ -105,7 +106,7 @@ void LayoutFileUploadControl::ComputeIntrinsicLogicalWidths(
max_logical_width =
LayoutUnit(ceilf(std::max(min_default_label_width, default_label_width)));
- if (!Style()->Width().IsPercentOrCalc())
+ if (!StyleRef().Width().IsPercentOrCalc())
min_logical_width = max_logical_width;
}
@@ -177,8 +178,24 @@ String LayoutFileUploadControl::FileTextValue() const {
HTMLInputElement* input = ToHTMLInputElement(GetNode());
DCHECK(input->files());
return LayoutTheme::GetTheme().FileListNameForWidth(
- input->GetLocale(), input->files(), Style()->GetFont(),
+ input->GetLocale(), input->files(), StyleRef().GetFont(),
MaxFilenameWidth());
}
+LayoutRect LayoutFileUploadControl::ControlClipRect(
+ const LayoutPoint& additional_offset) const {
+ LayoutRect rect(additional_offset, Size());
+ rect.Expand(BorderInsets());
+ rect.Expand(LayoutUnit(), LayoutUnit(kButtonShadowHeight));
+ return rect;
+}
+
+// Override to allow effective ControlClipRect to be bigger than the padding
+// box because of kButtonShadowHeight.
+LayoutRect LayoutFileUploadControl::OverflowClipRect(
+ const LayoutPoint& 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 4c4d2cdccf4..3e840946ea2 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
@@ -49,6 +49,11 @@ class CORE_EXPORT LayoutFileUploadControl final : public LayoutBlockFlow {
HTMLInputElement* UploadButton() const;
int UploadButtonWidth();
+ bool HasControlClip() const override { return true; }
+ LayoutRect ControlClipRect(const LayoutPoint&) const override;
+ LayoutRect OverflowClipRect(const LayoutPoint&,
+ OverlayScrollbarClipBehavior) const override;
+
static const int kAfterButtonSpacing = 4;
const char* GetName() const override { return "LayoutFileUploadControl"; }
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 054c5a5a12d..74deded7a2c 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
@@ -246,9 +246,9 @@ IntSize LayoutFlexibleBox::OriginAdjustmentForScrollbars() const {
if (!adjustment_width && !adjustment_height)
return size;
- EFlexDirection flex_direction = Style()->FlexDirection();
- TextDirection text_direction = Style()->Direction();
- WritingMode writing_mode = Style()->GetWritingMode();
+ EFlexDirection flex_direction = StyleRef().FlexDirection();
+ TextDirection text_direction = StyleRef().Direction();
+ WritingMode writing_mode = StyleRef().GetWritingMode();
if (flex_direction == EFlexDirection::kRow) {
if (text_direction == TextDirection::kRtl) {
@@ -294,18 +294,18 @@ IntSize LayoutFlexibleBox::ScrolledContentOffset() const {
}
bool LayoutFlexibleBox::HasTopOverflow() const {
- EFlexDirection flex_direction = Style()->FlexDirection();
+ EFlexDirection flex_direction = StyleRef().FlexDirection();
if (IsHorizontalWritingMode())
return flex_direction == EFlexDirection::kColumnReverse;
- return flex_direction == (Style()->IsLeftToRightDirection()
+ return flex_direction == (StyleRef().IsLeftToRightDirection()
? EFlexDirection::kRowReverse
: EFlexDirection::kRow);
}
bool LayoutFlexibleBox::HasLeftOverflow() const {
- EFlexDirection flex_direction = Style()->FlexDirection();
+ EFlexDirection flex_direction = StyleRef().FlexDirection();
if (IsHorizontalWritingMode()) {
- return flex_direction == (Style()->IsLeftToRightDirection()
+ return flex_direction == (StyleRef().IsLeftToRightDirection()
? EFlexDirection::kRowReverse
: EFlexDirection::kRow);
}
@@ -438,7 +438,7 @@ void LayoutFlexibleBox::RepositionLogicalHeightDependentFlexItems(
AlignChildren(line_contexts);
- if (Style()->FlexWrap() == EFlexWrap::kWrapReverse)
+ if (StyleRef().FlexWrap() == EFlexWrap::kWrapReverse)
FlipForWrapReverse(line_contexts, cross_axis_start_edge);
// direction:rtl + flex-direction:column means the cross-axis direction is
@@ -468,7 +468,7 @@ bool LayoutFlexibleBox::HasOrthogonalFlow(const LayoutBox& child) const {
}
bool LayoutFlexibleBox::IsColumnFlow() const {
- return Style()->IsColumnFlexDirection();
+ return StyleRef().IsColumnFlexDirection();
}
bool LayoutFlexibleBox::IsHorizontalFlow() const {
@@ -479,22 +479,23 @@ bool LayoutFlexibleBox::IsHorizontalFlow() const {
bool LayoutFlexibleBox::IsLeftToRightFlow() const {
if (IsColumnFlow()) {
- return blink::IsHorizontalWritingMode(Style()->GetWritingMode()) ||
- IsFlippedLinesWritingMode(Style()->GetWritingMode());
+ return blink::IsHorizontalWritingMode(StyleRef().GetWritingMode()) ||
+ IsFlippedLinesWritingMode(StyleRef().GetWritingMode());
}
- return Style()->IsLeftToRightDirection() ^
- (Style()->FlexDirection() == EFlexDirection::kRowReverse);
+ return StyleRef().IsLeftToRightDirection() ^
+ (StyleRef().FlexDirection() == EFlexDirection::kRowReverse);
}
bool LayoutFlexibleBox::IsMultiline() const {
- return Style()->FlexWrap() != EFlexWrap::kNowrap;
+ return StyleRef().FlexWrap() != EFlexWrap::kNowrap;
}
Length LayoutFlexibleBox::FlexBasisForChild(const LayoutBox& child) const {
- Length flex_length = child.Style()->FlexBasis();
- if (flex_length.IsAuto())
- flex_length =
- IsHorizontalFlow() ? child.Style()->Width() : child.Style()->Height();
+ Length flex_length = child.StyleRef().FlexBasis();
+ if (flex_length.IsAuto()) {
+ flex_length = IsHorizontalFlow() ? child.StyleRef().Width()
+ : child.StyleRef().Height();
+ }
return flex_length;
}
@@ -826,28 +827,31 @@ void LayoutFlexibleBox::ClearCachedMainSizeForChild(const LayoutBox& child) {
intrinsic_size_along_main_axis_.erase(&child);
}
-bool LayoutFlexibleBox::ShouldForceLayoutForNGChild(
- const LayoutBlockFlow& child) const {
+bool LayoutFlexibleBox::CanAvoidLayoutForNGChild(
+ const LayoutBox& child_box) const {
+ if (!child_box.IsLayoutNGMixin())
+ return false;
+ const LayoutBlockFlow& child(ToLayoutBlockFlow(child_box));
// If the last layout was done with a different override size,
// or different definite-ness, we need to force-relayout so
// that percentage sizes are resolved correctly.
const NGConstraintSpace* old_space = child.CachedConstraintSpace();
if (!old_space)
- return true;
+ return false;
if (old_space->IsFixedSizeInline() != child.HasOverrideLogicalWidth())
- return true;
+ return false;
if (old_space->IsFixedSizeBlock() != child.HasOverrideLogicalHeight())
- return true;
+ return false;
if (old_space->FixedSizeBlockIsDefinite() !=
UseOverrideLogicalHeightForPerentageResolution(child))
- return true;
+ return false;
if (child.HasOverrideLogicalWidth() &&
old_space->AvailableSize().inline_size != child.OverrideLogicalWidth())
- return true;
+ return false;
if (child.HasOverrideLogicalHeight() &&
old_space->AvailableSize().block_size != child.OverrideLogicalHeight())
- return true;
- return false;
+ return false;
+ return true;
}
DISABLE_CFI_PERF
@@ -942,7 +946,7 @@ void LayoutFlexibleBox::LayoutFlexItems(bool relayout_children,
LayoutUnit main_axis_offset =
FlowAwareBorderStart() + FlowAwarePaddingStart();
- if (Style()->FlexDirection() == EFlexDirection::kRowReverse &&
+ if (StyleRef().FlexDirection() == EFlexDirection::kRowReverse &&
ShouldPlaceBlockDirectionScrollbarOnLogicalLeft()) {
main_axis_offset += IsHorizontalFlow() ? VerticalScrollbarWidth()
: HorizontalScrollbarHeight();
@@ -971,11 +975,12 @@ void LayoutFlexibleBox::LayoutFlexItems(bool relayout_children,
bool LayoutFlexibleBox::HasAutoMarginsInCrossAxis(
const LayoutBox& child) const {
- if (IsHorizontalFlow())
- return child.Style()->MarginTop().IsAuto() ||
- child.Style()->MarginBottom().IsAuto();
- return child.Style()->MarginLeft().IsAuto() ||
- child.Style()->MarginRight().IsAuto();
+ if (IsHorizontalFlow()) {
+ return child.StyleRef().MarginTop().IsAuto() ||
+ child.StyleRef().MarginBottom().IsAuto();
+ }
+ return child.StyleRef().MarginLeft().IsAuto() ||
+ child.StyleRef().MarginRight().IsAuto();
}
bool LayoutFlexibleBox::UpdateAutoMarginsInCrossAxis(
@@ -985,10 +990,10 @@ bool LayoutFlexibleBox::UpdateAutoMarginsInCrossAxis(
DCHECK_GE(available_alignment_space, LayoutUnit());
bool is_horizontal = IsHorizontalFlow();
- Length top_or_left =
- is_horizontal ? child.Style()->MarginTop() : child.Style()->MarginLeft();
- Length bottom_or_right = is_horizontal ? child.Style()->MarginBottom()
- : child.Style()->MarginRight();
+ Length top_or_left = is_horizontal ? child.StyleRef().MarginTop()
+ : child.StyleRef().MarginLeft();
+ Length bottom_or_right = is_horizontal ? child.StyleRef().MarginBottom()
+ : child.StyleRef().MarginRight();
if (top_or_left.IsAuto() && bottom_or_right.IsAuto()) {
AdjustAlignmentForChild(child, available_alignment_space / 2);
if (is_horizontal) {
@@ -1001,13 +1006,13 @@ bool LayoutFlexibleBox::UpdateAutoMarginsInCrossAxis(
return true;
}
bool should_adjust_top_or_left = true;
- if (IsColumnFlow() && !child.Style()->IsLeftToRightDirection()) {
+ if (IsColumnFlow() && !child.StyleRef().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 (!IsColumnFlow() && child.Style()->IsFlippedBlocksWritingMode()) {
+ if (!IsColumnFlow() && child.StyleRef().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.
@@ -1061,13 +1066,14 @@ void LayoutFlexibleBox::PrepareOrderIteratorAndMargins() {
// start/end margins.
if (IsHorizontalFlow()) {
child->SetMarginLeft(
- ComputeChildMarginValue(child->Style()->MarginLeft()));
+ ComputeChildMarginValue(child->StyleRef().MarginLeft()));
child->SetMarginRight(
- ComputeChildMarginValue(child->Style()->MarginRight()));
+ ComputeChildMarginValue(child->StyleRef().MarginRight()));
} else {
- child->SetMarginTop(ComputeChildMarginValue(child->Style()->MarginTop()));
+ child->SetMarginTop(
+ ComputeChildMarginValue(child->StyleRef().MarginTop()));
child->SetMarginBottom(
- ComputeChildMarginValue(child->Style()->MarginBottom()));
+ ComputeChildMarginValue(child->StyleRef().MarginBottom()));
}
}
}
@@ -1077,8 +1083,8 @@ MinMaxSize LayoutFlexibleBox::ComputeMinAndMaxSizesForChild(
const LayoutBox& child) const {
MinMaxSize sizes{LayoutUnit(), LayoutUnit::Max()};
- Length max = IsHorizontalFlow() ? child.Style()->MaxWidth()
- : child.Style()->MaxHeight();
+ Length max = IsHorizontalFlow() ? child.StyleRef().MaxWidth()
+ : child.StyleRef().MaxHeight();
if (max.IsSpecifiedOrIntrinsic()) {
sizes.max_size = ComputeMainAxisExtentForChild(child, kMaxSize, max);
if (sizes.max_size == -1)
@@ -1086,8 +1092,8 @@ MinMaxSize LayoutFlexibleBox::ComputeMinAndMaxSizesForChild(
DCHECK_GE(sizes.max_size, LayoutUnit());
}
- Length min = IsHorizontalFlow() ? child.Style()->MinWidth()
- : child.Style()->MinHeight();
+ Length min = IsHorizontalFlow() ? child.StyleRef().MinWidth()
+ : child.StyleRef().MinHeight();
if (min.IsSpecifiedOrIntrinsic()) {
sizes.min_size = ComputeMainAxisExtentForChild(child, kMinSize, min);
// computeMainAxisExtentForChild can return -1 when the child has a
@@ -1197,10 +1203,10 @@ bool LayoutFlexibleBox::UseOverrideLogicalHeightForPerentageResolution(
LayoutUnit LayoutFlexibleBox::AdjustChildSizeForAspectRatioCrossAxisMinAndMax(
const LayoutBox& child,
LayoutUnit child_size) const {
- Length cross_min = IsHorizontalFlow() ? child.Style()->MinHeight()
- : child.Style()->MinWidth();
- Length cross_max = IsHorizontalFlow() ? child.Style()->MaxHeight()
- : child.Style()->MaxWidth();
+ Length cross_min = IsHorizontalFlow() ? child.StyleRef().MinHeight()
+ : child.StyleRef().MinWidth();
+ Length cross_max = IsHorizontalFlow() ? child.StyleRef().MaxHeight()
+ : child.StyleRef().MaxWidth();
if (CrossAxisLengthIsDefinite(child, cross_max)) {
LayoutUnit max_value =
@@ -1297,16 +1303,12 @@ static LayoutUnit AlignmentOffset(LayoutUnit available_free_space,
return LayoutUnit();
}
-void LayoutFlexibleBox::SetOverrideMainAxisContentSizeForChild(
- LayoutBox& child,
- LayoutUnit child_preferred_size) {
+void LayoutFlexibleBox::SetOverrideMainAxisContentSizeForChild(FlexItem& item) {
// child_preferred_size includes scrollbar width.
- if (HasOrthogonalFlow(child)) {
- child.SetOverrideLogicalHeight(child_preferred_size +
- child.BorderAndPaddingLogicalHeight());
+ if (HasOrthogonalFlow(*item.box)) {
+ item.box->SetOverrideLogicalHeight(item.FlexedBorderBoxSize());
} else {
- child.SetOverrideLogicalWidth(child_preferred_size +
- child.BorderAndPaddingLogicalWidth());
+ item.box->SetOverrideLogicalWidth(item.FlexedBorderBoxSize());
}
}
@@ -1380,8 +1382,8 @@ void LayoutFlexibleBox::PrepareChildForPositionedLayout(LayoutBox& child) {
FlowAwareBorderStart() + FlowAwarePaddingStart();
if (child_layer->StaticInlinePosition() != static_inline_position) {
child_layer->SetStaticInlinePosition(static_inline_position);
- if (child.Style()->HasStaticInlinePosition(
- Style()->IsHorizontalWritingMode()))
+ if (child.StyleRef().HasStaticInlinePosition(
+ StyleRef().IsHorizontalWritingMode()))
child.SetChildNeedsLayout(kMarkOnlyThis);
}
@@ -1389,8 +1391,8 @@ void LayoutFlexibleBox::PrepareChildForPositionedLayout(LayoutBox& child) {
FlowAwareBorderBefore() + FlowAwarePaddingBefore();
if (child_layer->StaticBlockPosition() != static_block_position) {
child_layer->SetStaticBlockPosition(static_block_position);
- if (child.Style()->HasStaticBlockPosition(
- Style()->IsHorizontalWritingMode()))
+ if (child.StyleRef().HasStaticBlockPosition(
+ StyleRef().IsHorizontalWritingMode()))
child.SetChildNeedsLayout(kMarkOnlyThis);
}
}
@@ -1400,14 +1402,14 @@ void LayoutFlexibleBox::ResetAutoMarginsAndLogicalTopInCrossAxis(
if (HasAutoMarginsInCrossAxis(child)) {
child.UpdateLogicalHeight();
if (IsHorizontalFlow()) {
- if (child.Style()->MarginTop().IsAuto())
+ if (child.StyleRef().MarginTop().IsAuto())
child.SetMarginTop(LayoutUnit());
- if (child.Style()->MarginBottom().IsAuto())
+ if (child.StyleRef().MarginBottom().IsAuto())
child.SetMarginBottom(LayoutUnit());
} else {
- if (child.Style()->MarginLeft().IsAuto())
+ if (child.StyleRef().MarginLeft().IsAuto())
child.SetMarginLeft(LayoutUnit());
- if (child.Style()->MarginRight().IsAuto())
+ if (child.StyleRef().MarginRight().IsAuto())
child.SetMarginRight(LayoutUnit());
}
}
@@ -1437,10 +1439,10 @@ bool LayoutFlexibleBox::ChildHasIntrinsicMainAxisSize(
bool result = false;
if (IsHorizontalFlow() != child.StyleRef().IsHorizontalWritingMode()) {
Length child_flex_basis = FlexBasisForChild(child);
- Length child_min_size = IsHorizontalFlow() ? child.Style()->MinWidth()
- : child.Style()->MinHeight();
- Length child_max_size = IsHorizontalFlow() ? child.Style()->MaxWidth()
- : child.Style()->MaxHeight();
+ Length child_min_size = IsHorizontalFlow() ? child.StyleRef().MinWidth()
+ : child.StyleRef().MinHeight();
+ Length child_max_size = IsHorizontalFlow() ? child.StyleRef().MaxWidth()
+ : child.StyleRef().MaxHeight();
if (child_flex_basis.IsIntrinsic() || child_min_size.IsIntrinsicOrAuto() ||
child_max_size.IsIntrinsic())
result = true;
@@ -1472,10 +1474,9 @@ void LayoutFlexibleBox::LayoutLineItems(FlexLine* current_line,
DCHECK(!flex_item.box->IsOutOfFlowPositioned());
- child->SetMayNeedPaintInvalidation();
+ child->SetShouldCheckForPaintInvalidation();
- SetOverrideMainAxisContentSizeForChild(*child,
- flex_item.flexed_content_size);
+ SetOverrideMainAxisContentSizeForChild(flex_item);
// The flexed content size and the override size include the scrollbar
// width, so we need to compare to the size including the scrollbar.
if (flex_item.flexed_content_size !=
@@ -1492,10 +1493,9 @@ void LayoutFlexibleBox::LayoutLineItems(FlexLine* current_line,
relayout_children && !relaid_out_children_.Contains(child);
// TODO(dgrogan): Broaden the NG part of this check once NG types other
// than Mixin derivatives are cached.
- if ((child->IsLayoutNGMixin() &&
- ShouldForceLayoutForNGChild(ToLayoutBlockFlow(*child))) ||
- (child->IsLayoutBlock() &&
- ToLayoutBlock(*child).HasPercentHeightDescendants())) {
+ if (child->IsLayoutBlock() &&
+ ToLayoutBlock(*child).HasPercentHeightDescendants() &&
+ !CanAvoidLayoutForNGChild(*child)) {
// Have to force another relayout even though the child is sized
// correctly, because its descendants are not sized correctly yet. Our
// previous layout of the child was done without an override height set.
@@ -1544,7 +1544,7 @@ void LayoutFlexibleBox::ApplyLineItemsPosition(FlexLine* current_line) {
CrossAxisScrollbarExtent()));
}
- if (Style()->FlexDirection() == EFlexDirection::kColumnReverse) {
+ if (StyleRef().FlexDirection() == EFlexDirection::kColumnReverse) {
// We have to do an extra pass for column-reverse to reposition the flex
// items since the start depends on the height of the flexbox, which we
// only know after we've positioned all the flex items.
@@ -1690,7 +1690,7 @@ void LayoutFlexibleBox::AlignChildren(Vector<FlexLine>& line_contexts) {
min_margin_after_baselines.push_back(min_margin_after_baseline);
}
- if (Style()->FlexWrap() != EFlexWrap::kWrapReverse)
+ if (StyleRef().FlexWrap() != EFlexWrap::kWrapReverse)
return;
// wrap-reverse flips the cross axis start and end. For baseline alignment,
@@ -1716,7 +1716,7 @@ void LayoutFlexibleBox::ApplyStretchAlignmentToChild(
LayoutUnit line_cross_axis_extent) {
LayoutBox& child = *flex_item.box;
if (!flex_item.HasOrthogonalFlow() &&
- child.Style()->LogicalHeight().IsAuto()) {
+ child.StyleRef().LogicalHeight().IsAuto()) {
LayoutUnit stretched_logical_height =
std::max(child.BorderAndPaddingLogicalHeight(),
line_cross_axis_extent - flex_item.CrossAxisMarginExtent());
@@ -1728,10 +1728,9 @@ void LayoutFlexibleBox::ApplyStretchAlignmentToChild(
// FIXME: Can avoid laying out here in some cases. See
// https://webkit.org/b/87905.
bool child_needs_relayout = desired_logical_height != child.LogicalHeight();
- if ((child.IsLayoutNGMixin() &&
- ShouldForceLayoutForNGChild(ToLayoutBlockFlow(child))) ||
- (child.IsLayoutBlock() &&
- ToLayoutBlock(child).HasPercentHeightDescendants())) {
+ if (child.IsLayoutBlock() &&
+ ToLayoutBlock(child).HasPercentHeightDescendants() &&
+ !CanAvoidLayoutForNGChild(child)) {
// Have to force another relayout even though the child is sized
// correctly, because its descendants are not sized correctly yet. Our
// previous layout of the child was done without an override height set.
@@ -1754,7 +1753,7 @@ void LayoutFlexibleBox::ApplyStretchAlignmentToChild(
child_intrinsic_content_logical_height);
}
} else if (flex_item.HasOrthogonalFlow() &&
- child.Style()->LogicalWidth().IsAuto()) {
+ child.StyleRef().LogicalWidth().IsAuto()) {
LayoutUnit child_width =
(line_cross_axis_extent - flex_item.CrossAxisMarginExtent())
.ClampNegativeToZero();
@@ -1771,7 +1770,7 @@ void LayoutFlexibleBox::ApplyStretchAlignmentToChild(
void LayoutFlexibleBox::FlipForRightToLeftColumn(
const Vector<FlexLine>& line_contexts) {
- if (Style()->IsLeftToRightDirection() || !IsColumnFlow())
+ if (StyleRef().IsLeftToRightDirection() || !IsColumnFlow())
return;
LayoutUnit cross_extent = CrossAxisExtent();
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 bd15dbdec74..43a2d3bc59b 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
@@ -157,7 +157,7 @@ class CORE_EXPORT LayoutFlexibleBox : public LayoutBlock {
EOverflow MainAxisOverflowForChild(const LayoutBox& child) const;
EOverflow CrossAxisOverflowForChild(const LayoutBox& child) const;
void CacheChildMainSize(const LayoutBox& child);
- bool ShouldForceLayoutForNGChild(const LayoutBlockFlow& child) const;
+ bool CanAvoidLayoutForNGChild(const LayoutBox& child) const;
void LayoutFlexItems(bool relayout_children, SubtreeLayoutScope&);
LayoutUnit AutoMarginOffsetInMainAxis(const Vector<FlexItem>&,
@@ -181,8 +181,7 @@ class CORE_EXPORT LayoutFlexibleBox : public LayoutBlock {
LayoutUnit& remaining_free_space);
void ResetAutoMarginsAndLogicalTopInCrossAxis(LayoutBox& child);
- void SetOverrideMainAxisContentSizeForChild(LayoutBox& child,
- LayoutUnit child_preferred_size);
+ void SetOverrideMainAxisContentSizeForChild(FlexItem&);
void PrepareChildForPositionedLayout(LayoutBox& child);
void LayoutLineItems(FlexLine*, bool relayout_children, SubtreeLayoutScope&);
void ApplyLineItemsPosition(FlexLine*);
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_flow_thread.cc b/chromium/third_party/blink/renderer/core/layout/layout_flow_thread.cc
index ae0e0281e0b..28c03e02ed4 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_flow_thread.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_flow_thread.cc
@@ -149,8 +149,7 @@ void LayoutFlowThread::AbsoluteQuadsForDescendant(const LayoutBox& descendant,
LayoutRect fragment = bounding_rect_in_flow_thread;
// We use inclusiveIntersect() because intersect() would reset the
// coordinates for zero-height objects.
- LayoutRect clip_rect = iterator.ClipRectInFlowThread(
- MultiColumnFragmentainerGroup::kBlockDirectionAxis);
+ LayoutRect clip_rect = iterator.ClipRectInFlowThread();
fragment.InclusiveIntersect(clip_rect);
fragment.MoveBy(-offset_from_flow_thread);
quads.push_back(descendant.LocalToAbsoluteQuad(FloatRect(fragment), mode));
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_frame.cc b/chromium/third_party/blink/renderer/core/layout/layout_frame.cc
index 73500ad12d7..5f31c15938d 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_frame.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_frame.cc
@@ -44,7 +44,7 @@ FrameEdgeInfo LayoutFrame::EdgeInfo() const {
void LayoutFrame::ImageChanged(WrappedImagePtr image,
CanDeferInvalidation,
const IntRect*) {
- if (const CursorList* cursors = Style()->Cursors()) {
+ if (const CursorList* cursors = StyleRef().Cursors()) {
for (const CursorData& cursor : *cursors) {
if (cursor.GetImage() && cursor.GetImage()->CachedImage() == image) {
if (LocalFrame* frame = GetFrame()) {
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 a0d5dac003b..70ab4ee452f 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
@@ -96,7 +96,7 @@ void LayoutFrameSet::LayOutAxis(GridAxis& axis,
int count_fixed = 0;
int count_percent = 0;
- float effective_zoom = Style()->EffectiveZoom();
+ float effective_zoom = StyleRef().EffectiveZoom();
// First we need to investigate how many columns of each type we have and
// how much space these columns are going to require.
@@ -470,15 +470,15 @@ void LayoutFrameSet::ContinueResizing(GridAxis& axis, int position) {
LayoutInvalidationReason::kSizeChanged);
}
-bool LayoutFrameSet::UserResize(MouseEvent* evt) {
+bool LayoutFrameSet::UserResize(const MouseEvent& evt) {
if (!is_resizing_) {
if (NeedsLayout())
return false;
- if (evt->type() == EventTypeNames::mousedown &&
- evt->button() ==
+ if (evt.type() == EventTypeNames::mousedown &&
+ evt.button() ==
static_cast<short>(WebPointerProperties::Button::kLeft)) {
FloatPoint local_pos =
- AbsoluteToLocal(FloatPoint(evt->AbsoluteLocation()), kUseTransforms);
+ AbsoluteToLocal(FloatPoint(evt.AbsoluteLocation()), kUseTransforms);
StartResizing(cols_, local_pos.X());
StartResizing(rows_, local_pos.Y());
if (cols_.split_being_resized_ != kNoSplit ||
@@ -488,16 +488,16 @@ bool LayoutFrameSet::UserResize(MouseEvent* evt) {
}
}
} else {
- if (evt->type() == EventTypeNames::mousemove ||
- (evt->type() == EventTypeNames::mouseup &&
- evt->button() ==
+ if (evt.type() == EventTypeNames::mousemove ||
+ (evt.type() == EventTypeNames::mouseup &&
+ evt.button() ==
static_cast<short>(WebPointerProperties::Button::kLeft))) {
FloatPoint local_pos =
- AbsoluteToLocal(FloatPoint(evt->AbsoluteLocation()), kUseTransforms);
+ AbsoluteToLocal(FloatPoint(evt.AbsoluteLocation()), kUseTransforms);
ContinueResizing(cols_, local_pos.X());
ContinueResizing(rows_, local_pos.Y());
- if (evt->type() == EventTypeNames::mouseup &&
- evt->button() ==
+ if (evt.type() == EventTypeNames::mouseup &&
+ evt.button() ==
static_cast<short>(WebPointerProperties::Button::kLeft)) {
SetIsResizing(false);
return true;
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 8de95dd343c..6e4df71d46c 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
@@ -41,6 +41,8 @@ enum FrameEdge {
struct FrameEdgeInfo {
STACK_ALLOCATED();
+
+ public:
FrameEdgeInfo(bool prevent_resize = false, bool allow_border = true)
: prevent_resize_(4), allow_border_(4) {
prevent_resize_.Fill(prevent_resize);
@@ -85,7 +87,7 @@ class LayoutFrameSet final : public LayoutBox {
FrameEdgeInfo EdgeInfo() const;
- bool UserResize(MouseEvent*);
+ bool UserResize(const MouseEvent&);
bool CanResizeRow(const IntPoint&) const;
bool CanResizeColumn(const IntPoint&) const;
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 c9948bff78c..73c4c9b6996 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
@@ -269,8 +269,8 @@ void LayoutGeometryMap::PushMappingsToAncestor(
base::AutoReset<size_t> position_change(&insertion_position_,
mapping_.size());
bool accumulating_transform =
- layout_object.Style()->Preserves3D() ||
- ancestor_layer->GetLayoutObject().Style()->Preserves3D();
+ layout_object.StyleRef().Preserves3D() ||
+ ancestor_layer->GetLayoutObject().StyleRef().Preserves3D();
Push(&layout_object, ToLayoutSize(layer_offset),
accumulating_transform ? kAccumulatingTransform : 0);
return;
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_geometry_map_step.h b/chromium/third_party/blink/renderer/core/layout/layout_geometry_map_step.h
index 280b3f5e7b0..e56ea11ee09 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_geometry_map_step.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_geometry_map_step.h
@@ -53,7 +53,6 @@ struct LayoutGeometryMapStep {
: layout_object_(o.layout_object_),
offset_(o.offset_),
offset_for_fixed_position_(o.offset_for_fixed_position_),
- offset_for_sticky_position_(o.offset_for_sticky_position_),
flags_(o.flags_) {
DCHECK(!o.transform_);
}
@@ -64,11 +63,7 @@ struct LayoutGeometryMapStep {
LayoutSize offset_;
std::unique_ptr<TransformationMatrix>
transform_; // Includes offset if non-null.
- // If m_offsetForFixedPosition could only apply to the fixed position steps,
- // we may be able to merge with m_offsetForStickyPosition and simplify
- // mapping.
LayoutSize offset_for_fixed_position_;
- LayoutSize offset_for_sticky_position_;
GeometryInfoFlags flags_;
};
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 425ee90f87e..cfa392065c4 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
@@ -467,7 +467,6 @@ TEST_F(LayoutGeometryMapTest, ColumnTest) {
LayoutGeometryMap rgm;
rgm.PushMappingsToAncestor(GetLayoutBox(web_view, "A"), nullptr);
- FloatPoint point;
FloatRect rect(0.0f, 0.0f, 5.0f, 3.0f);
EXPECT_EQ(FloatQuad(FloatRect(8.0f, 8.0f, 5.0f, 3.0f)),
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 7048f7638ef..351edfd1ff9 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_grid.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_grid.cc
@@ -36,6 +36,7 @@
#include "third_party/blink/renderer/core/layout/text_autosizer.h"
#include "third_party/blink/renderer/core/paint/grid_painter.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/style/computed_style.h"
#include "third_party/blink/renderer/core/style/grid_area.h"
#include "third_party/blink/renderer/platform/length_functions.h"
@@ -198,34 +199,6 @@ bool LayoutGrid::NamedGridLinesDefinitionDidChange(
old_style.NamedGridColumnLines() != StyleRef().NamedGridColumnLines();
}
-// This method optimizes the gutters computation by skiping the available size
-// call if gaps are fixed size (it's only needed for percentages).
-base::Optional<LayoutUnit> LayoutGrid::AvailableSpaceForGutters(
- GridTrackSizingDirection direction) const {
- bool is_row_axis = direction == kForColumns;
-
- const GapLength& gap =
- is_row_axis ? StyleRef().ColumnGap() : StyleRef().RowGap();
- if (!gap.IsNormal() && !gap.GetLength().IsPercentOrCalc())
- return base::nullopt;
-
- return is_row_axis ? AvailableLogicalWidth()
- : AvailableLogicalHeightForPercentageComputation();
-}
-
-LayoutUnit LayoutGrid::ComputeTrackBasedLogicalHeight() const {
- LayoutUnit logical_height;
-
- const Vector<GridTrack>& all_rows = track_sizing_algorithm_.Tracks(kForRows);
- for (const auto& row : all_rows)
- logical_height += row.BaseSize();
-
- logical_height += GuttersSize(*grid_, kForRows, 0, all_rows.size(),
- AvailableSpaceForGutters(kForRows));
-
- return logical_height;
-}
-
void LayoutGrid::ComputeTrackSizesForDefiniteSize(
GridTrackSizingDirection direction,
LayoutUnit available_space) {
@@ -249,7 +222,8 @@ void LayoutGrid::RepeatTracksSizingIfNeeded(
// all the cases with orthogonal flows require this extra cycle; we need a
// more specific condition to detect whether child's min-content contribution
// has changed or not.
- if (!has_any_orthogonal_item_)
+ if (!has_any_orthogonal_item_ &&
+ !track_sizing_algorithm_.HasAnyPercentSizedRowsIndefiniteHeight())
return;
// TODO (lajava): Whenever the min-content contribution of a grid item changes
@@ -262,7 +236,13 @@ void LayoutGrid::RepeatTracksSizingIfNeeded(
// Hence we need to repeat computeUsedBreadthOfGridTracks for both, columns
// and rows, to determine the final values.
ComputeTrackSizesForDefiniteSize(kForColumns, available_space_for_columns);
+ ComputeContentPositionAndDistributionOffset(
+ kForColumns, track_sizing_algorithm_.FreeSpace(kForColumns).value(),
+ NonCollapsedTracks(kForColumns));
ComputeTrackSizesForDefiniteSize(kForRows, available_space_for_rows);
+ ComputeContentPositionAndDistributionOffset(
+ kForRows, track_sizing_algorithm_.FreeSpace(kForRows).value(),
+ NonCollapsedTracks(kForRows));
}
void LayoutGrid::UpdateBlockLayout(bool relayout_children) {
@@ -277,6 +257,8 @@ void LayoutGrid::UpdateBlockLayout(bool relayout_children) {
SubtreeLayoutScope layout_scope(*this);
+ PaintLayerScrollableArea::DelayScrollOffsetClampScope delay_clamp_scope;
+
{
// LayoutState needs this deliberate scope to pop before updating scroll
// information (which may trigger relayout).
@@ -330,9 +312,9 @@ void LayoutGrid::UpdateBlockLayout(bool relayout_children) {
min_content_height_,
max_content_height_);
}
- LayoutUnit track_based_logical_height = ComputeTrackBasedLogicalHeight() +
- BorderAndPaddingLogicalHeight() +
- ScrollbarLogicalHeight();
+ LayoutUnit track_based_logical_height =
+ track_sizing_algorithm_.ComputeTrackBasedSize() +
+ BorderAndPaddingLogicalHeight() + ScrollbarLogicalHeight();
SetLogicalHeight(track_based_logical_height);
LayoutUnit old_client_after_edge = ClientLogicalBottom();
@@ -398,10 +380,10 @@ LayoutUnit LayoutGrid::GridGap(GridTrackSizingDirection direction) const {
if (gap.IsNormal())
return LayoutUnit();
- if (gap.GetLength().IsPercentOrCalc())
- available_size = is_row_axis
- ? AvailableLogicalWidth()
- : AvailableLogicalHeightForPercentageComputation();
+ if (gap.GetLength().IsPercentOrCalc()) {
+ available_size =
+ is_row_axis ? AvailableLogicalWidth() : ContentLogicalHeight();
+ }
// TODO(rego): Maybe we could cache the computed percentage as a performance
// improvement.
@@ -807,7 +789,7 @@ void LayoutGrid::PlaceItemsOnGrid(
specified_major_axis_auto_grid_items.push_back(child);
continue;
}
- grid.insert(*child, area);
+ grid.Insert(*child, area);
}
#if DCHECK_IS_ON()
@@ -978,7 +960,7 @@ void LayoutGrid::PlaceSpecifiedMajorAxisItemsOnGrid(
Grid& grid,
const Vector<LayoutBox*>& auto_grid_items) const {
bool is_for_columns = AutoPlacementMajorAxisDirection() == kForColumns;
- bool is_grid_auto_flow_dense = Style()->IsGridAutoFlowAlgorithmDense();
+ bool is_grid_auto_flow_dense = StyleRef().IsGridAutoFlowAlgorithmDense();
// Mapping between the major axis tracks (rows or columns) and the last
// auto-placed item's position inserted on that track. This is needed to
@@ -1013,7 +995,7 @@ void LayoutGrid::PlaceSpecifiedMajorAxisItemsOnGrid(
major_axis_positions);
}
- grid.insert(*auto_grid_item, *empty_grid_area);
+ grid.Insert(*auto_grid_item, *empty_grid_area);
if (!is_grid_auto_flow_dense)
minor_axis_cursors.Set(major_axis_initial_position,
@@ -1027,7 +1009,7 @@ void LayoutGrid::PlaceAutoMajorAxisItemsOnGrid(
Grid& grid,
const Vector<LayoutBox*>& auto_grid_items) const {
std::pair<size_t, size_t> auto_placement_cursor = std::make_pair(0, 0);
- bool is_grid_auto_flow_dense = Style()->IsGridAutoFlowAlgorithmDense();
+ bool is_grid_auto_flow_dense = StyleRef().IsGridAutoFlowAlgorithmDense();
for (auto* const auto_grid_item : auto_grid_items) {
PlaceAutoMajorAxisItemOnGrid(grid, *auto_grid_item, auto_placement_cursor);
@@ -1126,18 +1108,18 @@ void LayoutGrid::PlaceAutoMajorAxisItemOnGrid(
GridSpan::TranslatedDefiniteGridSpan(0, minor_axis_span_size));
}
- grid.insert(grid_item, *empty_grid_area);
+ grid.Insert(grid_item, *empty_grid_area);
// Move auto-placement cursor to the new position.
auto_placement_cursor.first = empty_grid_area->rows.StartLine();
auto_placement_cursor.second = empty_grid_area->columns.StartLine();
}
GridTrackSizingDirection LayoutGrid::AutoPlacementMajorAxisDirection() const {
- return Style()->IsGridAutoFlowDirectionColumn() ? kForColumns : kForRows;
+ return StyleRef().IsGridAutoFlowDirectionColumn() ? kForColumns : kForRows;
}
GridTrackSizingDirection LayoutGrid::AutoPlacementMinorAxisDirection() const {
- return Style()->IsGridAutoFlowDirectionColumn() ? kForRows : kForColumns;
+ return StyleRef().IsGridAutoFlowDirectionColumn() ? kForRows : kForColumns;
}
void LayoutGrid::DirtyGrid() {
@@ -1993,11 +1975,11 @@ LayoutUnit LayoutGrid::GridAreaBreadthForOutOfFlowChild(
int end_line = span.UntranslatedEndLine() + smallest_start;
int last_line = NumTracks(direction, *grid_);
GridPosition start_position = direction == kForColumns
- ? child.Style()->GridColumnStart()
- : child.Style()->GridRowStart();
+ ? child.StyleRef().GridColumnStart()
+ : child.StyleRef().GridRowStart();
GridPosition end_position = direction == kForColumns
- ? child.Style()->GridColumnEnd()
- : child.Style()->GridRowEnd();
+ ? child.StyleRef().GridColumnEnd()
+ : child.StyleRef().GridRowEnd();
bool start_is_auto =
GridPositionIsAutoForOutOfFlow(start_position, direction) ||
@@ -2026,12 +2008,14 @@ LayoutUnit LayoutGrid::GridAreaBreadthForOutOfFlowChild(
end = positions[end_line];
// These vectors store line positions including gaps, but we shouldn't
// consider them for the edges of the grid.
- base::Optional<LayoutUnit> available_size_for_gutters =
- AvailableSpaceForGutters(direction);
if (end_line > 0 && end_line < last_line) {
DCHECK(!grid_->NeedsItemsPlacement());
- end -= GuttersSize(*grid_, direction, end_line - 1, 2,
- available_size_for_gutters);
+ // TODO(rego): It would be more efficient to call GridGap(direction) and
+ // pass that value to GuttersSize(), so we could avoid the call to
+ // available size if the gutter doesn't use percentages.
+ end -= GuttersSize(
+ *grid_, direction, end_line - 1, 2,
+ is_row_axis ? AvailableLogicalWidth() : ContentLogicalHeight());
end -= is_row_axis ? offset_between_columns_.distribution_offset
: offset_between_rows_.distribution_offset;
}
@@ -2056,7 +2040,7 @@ LayoutUnit LayoutGrid::LogicalOffsetForChild(const LayoutBox& child,
LayoutUnit child_margin =
is_flowaware_row_axis ? child.MarginLineLeft() : child.MarginBefore();
LayoutUnit offset = child_position - grid_border - child_margin;
- if (!is_row_axis || Style()->IsLeftToRightDirection())
+ if (!is_row_axis || StyleRef().IsLeftToRightDirection())
return offset;
LayoutUnit child_breadth =
@@ -2313,7 +2297,7 @@ LayoutPoint LayoutGrid::FindChildLogicalPosition(const LayoutBox& child) const {
// We stored column_position_'s data ignoring the direction, hence we might
// need now to translate positions from RTL to LTR, as it's more convenient
// for painting.
- if (!Style()->IsLeftToRightDirection()) {
+ if (!StyleRef().IsLeftToRightDirection()) {
row_axis_offset =
(child.IsOutOfFlowPositioned()
? TranslateOutOfFlowRTLCoordinate(child, row_axis_offset)
@@ -2337,7 +2321,7 @@ LayoutPoint LayoutGrid::GridAreaLogicalPosition(const GridArea& area) const {
// See comment in findChildLogicalPosition() about why we need sometimes to
// translate from RTL to LTR the rowAxisOffset coordinate.
- return LayoutPoint(Style()->IsLeftToRightDirection()
+ return LayoutPoint(StyleRef().IsLeftToRightDirection()
? row_axis_offset
: TranslateRTLCoordinate(row_axis_offset),
column_axis_offset);
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_grid.h b/chromium/third_party/blink/renderer/core/layout/layout_grid.h
index 6fb09c71acd..151695765d3 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_grid.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_grid.h
@@ -76,7 +76,9 @@ class LayoutGrid final : public LayoutBlock {
return row_positions_;
}
- const GridCell& GetGridCell(int row, int column) const {
+ // TODO(svillar): rename this method as this does not return a
+ // GridCell but its contents.
+ const GridItemList& GetGridCell(int row, int column) const {
SECURITY_DCHECK(!grid_->NeedsItemsPlacement());
return grid_->Cell(row, column);
}
@@ -122,6 +124,9 @@ class LayoutGrid final : public LayoutBlock {
StyleContentAlignmentData ContentAlignment(GridTrackSizingDirection) const;
+ // Exposed for testing *ONLY*.
+ Grid* InternalGrid() const { return grid_.get(); }
+
protected:
ItemPosition SelfAlignmentNormalBehavior(
const LayoutBox* child = nullptr) const override {
@@ -156,9 +161,6 @@ class LayoutGrid final : public LayoutBlock {
const ComputedStyle& new_style) const;
void StyleDidChange(StyleDifference, const ComputedStyle*) override;
- base::Optional<LayoutUnit> AvailableSpaceForGutters(
- GridTrackSizingDirection) const;
-
bool ExplicitGridDidResize(const ComputedStyle&) const;
bool NamedGridLinesDefinitionDidChange(const ComputedStyle&) const;
@@ -197,7 +199,6 @@ class LayoutGrid final : public LayoutBlock {
GridTrackSizingDirection,
LayoutUnit& min_intrinsic_size,
LayoutUnit& max_intrinsic_size) const;
- LayoutUnit ComputeTrackBasedLogicalHeight() const;
void ComputeTrackSizesForDefiniteSize(GridTrackSizingDirection,
LayoutUnit free_space);
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 6de2e94ed6d..c3276c21c64 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
@@ -30,7 +30,6 @@
#include "third_party/blink/renderer/core/html/canvas/html_canvas_element.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/html_canvas_paint_invalidator.h"
#include "third_party/blink/renderer/core/paint/html_canvas_painter.h"
namespace blink {
@@ -53,8 +52,8 @@ void LayoutHTMLCanvas::PaintReplaced(const PaintInfo& paint_info,
void LayoutHTMLCanvas::CanvasSizeChanged() {
IntSize canvas_size = ToHTMLCanvasElement(GetNode())->Size();
- LayoutSize zoomed_size(canvas_size.Width() * Style()->EffectiveZoom(),
- canvas_size.Height() * Style()->EffectiveZoom());
+ LayoutSize zoomed_size(canvas_size.Width() * StyleRef().EffectiveZoom(),
+ canvas_size.Height() * StyleRef().EffectiveZoom());
if (zoomed_size == IntrinsicSize())
return;
@@ -83,9 +82,13 @@ void LayoutHTMLCanvas::CanvasSizeChanged() {
SetNeedsLayout(LayoutInvalidationReason::kSizeChanged);
}
-PaintInvalidationReason LayoutHTMLCanvas::InvalidatePaint(
+void LayoutHTMLCanvas::InvalidatePaint(
const PaintInvalidatorContext& context) const {
- return HTMLCanvasPaintInvalidator(*this, context).InvalidatePaint();
+ auto* element = ToHTMLCanvasElement(GetNode());
+ if (element->IsDirty())
+ element->DoDeferredPaintInvalidation();
+
+ LayoutReplaced::InvalidatePaint(context);
}
CompositingReasons LayoutHTMLCanvas::AdditionalCompositingReasons() const {
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 5058233b7c0..c3e989ede9d 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
@@ -41,8 +41,7 @@ class LayoutHTMLCanvas final : public LayoutReplaced {
}
PaintLayerType LayerTypeRequired() const override;
- PaintInvalidationReason InvalidatePaint(
- const PaintInvalidatorContext&) const final;
+ void InvalidatePaint(const PaintInvalidatorContext&) const final;
void CanvasSizeChanged();
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_iframe.cc b/chromium/third_party/blink/renderer/core/layout/layout_iframe.cc
index b0c1de439bb..b13a56e2828 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_iframe.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_iframe.cc
@@ -41,7 +41,7 @@ bool LayoutIFrame::IsInlineBlockOrInlineTable() const {
}
PaintLayerType LayoutIFrame::LayerTypeRequired() const {
- if (Style()->Resize() != EResize::kNone)
+ if (StyleRef().Resize() != EResize::kNone)
return kNormalPaintLayer;
return LayoutEmbeddedContent::LayerTypeRequired();
}
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 46c2078a03b..c76ccc2b7bd 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_image.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_image.cc
@@ -80,17 +80,17 @@ bool CheckForMaxDownscalingImagePolicy(const LocalFrame& frame,
return false;
// Invert the image if the image's size is more than 2 times bigger than the
// size it is being laid-out by.
- LayoutUnit layout_width = layout_image->ContentBoxRect().Width();
- LayoutUnit layout_height = layout_image->ContentBoxRect().Height();
+ LayoutUnit layout_width = layout_image->ContentWidth();
+ LayoutUnit layout_height = layout_image->ContentHeight();
auto image_width = element->naturalWidth();
auto image_height = element->naturalHeight();
if (layout_width > 0 && layout_height > 0 && image_width > 0 &&
image_height > 0) {
double device_pixel_ratio = frame.DevicePixelRatio();
- if (LayoutUnit(image_width / kmax_downscaling_ratio * device_pixel_ratio) >
- layout_width ||
- LayoutUnit(image_height / kmax_downscaling_ratio * device_pixel_ratio) >
- layout_height)
+ if (LayoutUnit(image_width / (kmax_downscaling_ratio *
+ device_pixel_ratio)) > layout_width ||
+ LayoutUnit(image_height / (kmax_downscaling_ratio *
+ device_pixel_ratio)) > layout_height)
return true;
}
return false;
@@ -129,7 +129,7 @@ void LayoutImage::StyleDidChange(StyleDifference diff,
bool old_orientation =
old_style ? old_style->RespectImageOrientation()
: ComputedStyleInitialValues::InitialRespectImageOrientation();
- if (Style() && Style()->RespectImageOrientation() != old_orientation)
+ if (Style() && StyleRef().RespectImageOrientation() != old_orientation)
IntrinsicSizeChanged();
}
@@ -182,10 +182,13 @@ void LayoutImage::ImageChanged(WrappedImagePtr new_image,
if (!did_increment_visually_non_empty_pixel_count_) {
// At a zoom level of 1 the image is guaranteed to have an integer size.
View()->GetFrameView()->IncrementVisuallyNonEmptyPixelCount(
- FlooredIntSize(image_resource_->ImageSize(1.0f)));
+ FlooredIntSize(ImageSizeOverriddenByIntrinsicSize(1.0f)));
did_increment_visually_non_empty_pixel_count_ = true;
}
+ // The replaced content transform depends on the intrinsic size (see:
+ // FragmentPaintPropertyTreeBuilder::UpdateReplacedContentTransform).
+ SetNeedsPaintPropertyUpdate();
InvalidatePaintAndMarkForLayoutIfNeeded(defer);
}
@@ -198,8 +201,9 @@ void LayoutImage::UpdateIntrinsicSizeIfNeeded(const LayoutSize& new_size) {
void LayoutImage::InvalidatePaintAndMarkForLayoutIfNeeded(
CanDeferInvalidation defer) {
LayoutSize old_intrinsic_size = IntrinsicSize();
- LayoutSize new_intrinsic_size =
- RoundedLayoutSize(image_resource_->ImageSize(Style()->EffectiveZoom()));
+
+ LayoutSize new_intrinsic_size = RoundedLayoutSize(
+ ImageSizeOverriddenByIntrinsicSize(StyleRef().EffectiveZoom()));
UpdateIntrinsicSizeIfNeeded(new_intrinsic_size);
// In the case of generated image content using :before/:after/content, we
@@ -215,17 +219,17 @@ void LayoutImage::InvalidatePaintAndMarkForLayoutIfNeeded(
// If the actual area occupied by the image has changed and it is not
// constrained by style then a layout is required.
- bool image_size_is_constrained = Style()->LogicalWidth().IsSpecified() &&
- Style()->LogicalHeight().IsSpecified();
+ bool image_size_is_constrained = StyleRef().LogicalWidth().IsSpecified() &&
+ StyleRef().LogicalHeight().IsSpecified();
// 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
// shrink-to-fit is needed, always force a layout.
bool containing_block_needs_to_recompute_preferred_size =
- Style()->LogicalWidth().IsPercentOrCalc() ||
- Style()->LogicalMaxWidth().IsPercentOrCalc() ||
- Style()->LogicalMinWidth().IsPercentOrCalc();
+ StyleRef().LogicalWidth().IsPercentOrCalc() ||
+ StyleRef().LogicalMaxWidth().IsPercentOrCalc() ||
+ StyleRef().LogicalMinWidth().IsPercentOrCalc();
if (image_source_has_changed_size &&
(!image_size_is_constrained ||
@@ -236,10 +240,11 @@ void LayoutImage::InvalidatePaintAndMarkForLayoutIfNeeded(
}
SetShouldDoFullPaintInvalidationWithoutGeometryChange(
- defer == CanDeferInvalidation::kYes && ImageResource() &&
- ImageResource()->MaybeAnimated()
- ? PaintInvalidationReason::kDelayedFull
- : PaintInvalidationReason::kImage);
+ PaintInvalidationReason::kImage);
+
+ if (defer == CanDeferInvalidation::kYes && ImageResource() &&
+ ImageResource()->MaybeAnimated())
+ SetShouldDelayFullPaintInvalidation();
// Tell any potential compositing layers that the image needs updating.
ContentChanged(kImageChanged);
@@ -301,25 +306,25 @@ bool LayoutImage::ForegroundIsKnownToBeOpaqueInRect(
ImageResourceContent* image_content = image_resource_->CachedImage();
if (!image_content || !image_content->IsLoaded())
return false;
- if (!ContentBoxRect().Contains(local_rect))
+ if (!PhysicalContentBoxRect().Contains(local_rect))
return false;
- EFillBox background_clip = Style()->BackgroundClip();
+ EFillBox background_clip = StyleRef().BackgroundClip();
// Background paints under borders.
- if (background_clip == EFillBox::kBorder && Style()->HasBorder() &&
- !Style()->BorderObscuresBackground())
+ if (background_clip == EFillBox::kBorder && StyleRef().HasBorder() &&
+ !StyleRef().BorderObscuresBackground())
return false;
// Background shows in padding area.
if ((background_clip == EFillBox::kBorder ||
background_clip == EFillBox::kPadding) &&
- Style()->HasPadding())
+ StyleRef().HasPadding())
return false;
// Object-position may leave parts of the content box empty, regardless of the
// value of object-fit.
- if (Style()->ObjectPosition() !=
+ if (StyleRef().ObjectPosition() !=
ComputedStyleInitialValues::InitialObjectPosition())
return false;
// Object-fit may leave parts of the content box empty.
- EObjectFit object_fit = Style()->GetObjectFit();
+ EObjectFit object_fit = StyleRef().GetObjectFit();
if (object_fit != EObjectFit::kFill && object_fit != EObjectFit::kCover)
return false;
// Check for image with alpha.
@@ -364,36 +369,78 @@ bool LayoutImage::NodeAtPoint(HitTestResult& result,
return inside;
}
-void LayoutImage::ComputeIntrinsicSizingInfo(
+IntSize LayoutImage::GetOverriddenIntrinsicSize() const {
+ if (auto* image_element = ToHTMLImageElementOrNull(GetNode())) {
+ if (RuntimeEnabledFeatures::ExperimentalProductivityFeaturesEnabled())
+ return image_element->GetOverriddenIntrinsicSize();
+ }
+ return IntSize();
+}
+
+FloatSize LayoutImage::ImageSizeOverriddenByIntrinsicSize(
+ float multiplier) const {
+ FloatSize overridden_intrinsic_size = FloatSize(GetOverriddenIntrinsicSize());
+ if (overridden_intrinsic_size.IsEmpty())
+ return image_resource_->ImageSize(multiplier);
+
+ if (multiplier != 1) {
+ overridden_intrinsic_size.Scale(multiplier);
+ if (overridden_intrinsic_size.Width() < 1.0f)
+ overridden_intrinsic_size.SetWidth(1.0f);
+ if (overridden_intrinsic_size.Height() < 1.0f)
+ overridden_intrinsic_size.SetHeight(1.0f);
+ }
+
+ return overridden_intrinsic_size;
+}
+
+bool LayoutImage::OverrideIntrinsicSizingInfo(
IntrinsicSizingInfo& intrinsic_sizing_info) const {
- if (SVGImage* svg_image = EmbeddedSVGImage()) {
- svg_image->GetIntrinsicSizingInfo(intrinsic_sizing_info);
+ IntSize overridden_intrinsic_size = GetOverriddenIntrinsicSize();
+ if (overridden_intrinsic_size.IsEmpty())
+ return false;
- // Handle zoom & vertical writing modes here, as the embedded SVG document
- // doesn't know about them.
- intrinsic_sizing_info.size.Scale(Style()->EffectiveZoom());
- if (Style()->GetObjectFit() != EObjectFit::kScaleDown)
- intrinsic_sizing_info.size.Scale(ImageDevicePixelRatio());
+ intrinsic_sizing_info.size = FloatSize(overridden_intrinsic_size);
+ intrinsic_sizing_info.aspect_ratio = intrinsic_sizing_info.size;
+ if (!IsHorizontalWritingMode())
+ intrinsic_sizing_info.Transpose();
- if (!IsHorizontalWritingMode())
- intrinsic_sizing_info.Transpose();
- return;
- }
+ return true;
+}
+
+void LayoutImage::ComputeIntrinsicSizingInfo(
+ IntrinsicSizingInfo& intrinsic_sizing_info) const {
+ if (!OverrideIntrinsicSizingInfo(intrinsic_sizing_info)) {
+ if (SVGImage* svg_image = EmbeddedSVGImage()) {
+ svg_image->GetIntrinsicSizingInfo(intrinsic_sizing_info);
+
+ // Handle zoom & vertical writing modes here, as the embedded SVG document
+ // doesn't know about them.
+ intrinsic_sizing_info.size.Scale(StyleRef().EffectiveZoom());
+ if (StyleRef().GetObjectFit() != EObjectFit::kScaleDown)
+ intrinsic_sizing_info.size.Scale(ImageDevicePixelRatio());
+
+ if (!IsHorizontalWritingMode())
+ intrinsic_sizing_info.Transpose();
+ return;
+ }
- LayoutReplaced::ComputeIntrinsicSizingInfo(intrinsic_sizing_info);
-
- // Our intrinsicSize is empty if we're laying out generated images with
- // relative width/height. Figure out the right intrinsic size to use.
- if (intrinsic_sizing_info.size.IsEmpty() &&
- image_resource_->ImageHasRelativeSize() && !IsLayoutNGListMarkerImage()) {
- LayoutObject* containing_block =
- IsOutOfFlowPositioned() ? Container() : ContainingBlock();
- if (containing_block->IsBox()) {
- LayoutBox* box = ToLayoutBox(containing_block);
- intrinsic_sizing_info.size.SetWidth(
- box->AvailableLogicalWidth().ToFloat());
- intrinsic_sizing_info.size.SetHeight(
- box->AvailableLogicalHeight(kIncludeMarginBorderPadding).ToFloat());
+ LayoutReplaced::ComputeIntrinsicSizingInfo(intrinsic_sizing_info);
+
+ // Our intrinsicSize is empty if we're laying out generated images with
+ // relative width/height. Figure out the right intrinsic size to use.
+ if (intrinsic_sizing_info.size.IsEmpty() &&
+ image_resource_->ImageHasRelativeSize() &&
+ !IsLayoutNGListMarkerImage()) {
+ LayoutObject* containing_block =
+ IsOutOfFlowPositioned() ? Container() : ContainingBlock();
+ if (containing_block->IsBox()) {
+ LayoutBox* box = ToLayoutBox(containing_block);
+ intrinsic_sizing_info.size.SetWidth(
+ box->AvailableLogicalWidth().ToFloat());
+ intrinsic_sizing_info.size.SetHeight(
+ box->AvailableLogicalHeight(kIncludeMarginBorderPadding).ToFloat());
+ }
}
}
// Don't compute an intrinsic ratio to preserve historical WebKit behavior if
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 e8742bea3a3..f02e9ba8ee2 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_image.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_image.h
@@ -78,6 +78,9 @@ class CORE_EXPORT LayoutImage : public LayoutReplaced {
float ImageDevicePixelRatio() const { return image_device_pixel_ratio_; }
void IntrinsicSizeChanged() override {
+ // The replaced content transform depends on the intrinsic size (see:
+ // FragmentPaintPropertyTreeBuilder::UpdateReplacedContentTransform).
+ SetNeedsPaintPropertyUpdate();
if (image_resource_)
ImageChanged(image_resource_->ImagePtr(), CanDeferInvalidation::kNo);
}
@@ -137,6 +140,11 @@ class CORE_EXPORT LayoutImage : public LayoutReplaced {
void InvalidatePaintAndMarkForLayoutIfNeeded(CanDeferInvalidation);
void UpdateIntrinsicSizeIfNeeded(const LayoutSize&);
+ // Override intrinsic sizing info by HTMLImageElement "intrinsicsize"
+ // attribute if enabled and exists.
+ bool OverrideIntrinsicSizingInfo(IntrinsicSizingInfo&) 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_inline.cc b/chromium/third_party/blink/renderer/core/layout/layout_inline.cc
index e287ac7b2a5..5b7fca21fe0 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_inline.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_inline.cc
@@ -70,10 +70,20 @@ struct SameSizeAsLayoutInline : public LayoutBoxModelObject {
static_assert(sizeof(LayoutInline) == sizeof(SameSizeAsLayoutInline),
"LayoutInline should stay small");
-LayoutInline::LayoutInline(Element* element) : LayoutBoxModelObject(element) {
+LayoutInline::LayoutInline(Element* element)
+ : LayoutBoxModelObject(element), line_boxes_() {
SetChildrenInline(true);
}
+LayoutInline::~LayoutInline() {
+#if DCHECK_IS_ON()
+ if (IsInLayoutNGInlineFormattingContext())
+ DCHECK(!first_paint_fragment_);
+ else
+ line_boxes_.AssertIsEmpty();
+#endif
+}
+
LayoutInline* LayoutInline::CreateAnonymous(Document* document) {
LayoutInline* layout_inline = new LayoutInline(nullptr);
layout_inline->SetDocumentForAnonymous(document);
@@ -105,13 +115,6 @@ void LayoutInline::WillBeDestroyed() {
if (!DocumentBeingDestroyed()) {
if (FirstLineBox()) {
- // We can't wait for LayoutBoxModelObject::destroy to clear the selection,
- // because by then we will have nuked the line boxes.
- // FIXME: The FrameSelection should be responsible for this when it
- // is notified of DOM mutations.
- if (IsSelectionBorder())
- View()->ClearSelection();
-
// If line boxes are contained inside a root, that means we're an inline.
// In that case, we need to remove all the line boxes so that the parent
// lines aren't pointing to deleted children. If the first line box does
@@ -126,11 +129,32 @@ void LayoutInline::WillBeDestroyed() {
}
}
- line_boxes_.DeleteLineBoxes();
+ DeleteLineBoxes();
LayoutBoxModelObject::WillBeDestroyed();
}
+void LayoutInline::DeleteLineBoxes() {
+ if (IsInLayoutNGInlineFormattingContext())
+ SetFirstInlineFragment(nullptr);
+ else
+ MutableLineBoxes()->DeleteLineBoxes();
+}
+
+void LayoutInline::SetFirstInlineFragment(NGPaintFragment* fragment) {
+ CHECK(IsInLayoutNGInlineFormattingContext());
+ NGPaintFragment::ResetInlineFragmentsFor(this);
+ first_paint_fragment_ = fragment;
+}
+
+void LayoutInline::InLayoutNGInlineFormattingContextWillChange(bool new_value) {
+ DeleteLineBoxes();
+
+ // Because |first_paint_fragment_| and |line_boxes_| are union, when one is
+ // deleted, the other should be initialized to nullptr.
+ DCHECK(new_value ? !first_paint_fragment_ : !line_boxes_.First());
+}
+
LayoutInline* LayoutInline::InlineElementContinuation() const {
LayoutBoxModelObject* continuation = Continuation();
if (!continuation || continuation->IsInline())
@@ -269,8 +293,8 @@ void LayoutInline::UpdateAlwaysCreateLineBoxes(bool full_layout) {
(parent_layout_inline && parent_layout_inline->AlwaysCreateLineBoxes()) ||
(parent_layout_inline &&
parent_style.VerticalAlign() != EVerticalAlign::kBaseline) ||
- Style()->VerticalAlign() != EVerticalAlign::kBaseline ||
- Style()->GetTextEmphasisMark() != TextEmphasisMark::kNone ||
+ StyleRef().VerticalAlign() != EVerticalAlign::kBaseline ||
+ StyleRef().GetTextEmphasisMark() != TextEmphasisMark::kNone ||
(check_fonts &&
(!StyleRef().HasIdenticalAscentDescentAndLineGap(parent_style) ||
parent_style.LineHeight() != StyleRef().LineHeight()));
@@ -400,7 +424,7 @@ void LayoutInline::AddChildIgnoringContinuation(LayoutObject* new_child,
// collect the x/y offsets from inline parents later.
if (LayoutObject* positioned_ancestor =
InFlowPositionedInlineAncestor(this))
- new_style->SetPosition(positioned_ancestor->Style()->GetPosition());
+ new_style->SetPosition(positioned_ancestor->StyleRef().GetPosition());
LayoutBlockFlow* new_box =
LayoutBlockFlow::CreateAnonymous(&GetDocument(), std::move(new_style));
@@ -689,7 +713,7 @@ void LayoutInline::GenerateCulledLineBoxRects(
if (!CulledInlineFirstLineBox())
return;
- bool is_horizontal = Style()->IsHorizontalWritingMode();
+ bool is_horizontal = StyleRef().IsHorizontalWritingMode();
LayoutUnit logical_top, logical_height;
for (LayoutObject* curr = FirstChild(); curr; curr = curr->NextSibling()) {
@@ -869,19 +893,19 @@ static LayoutUnit ComputeMargin(const LayoutInline* layout_object,
}
LayoutUnit LayoutInline::MarginLeft() const {
- return ComputeMargin(this, Style()->MarginLeft());
+ return ComputeMargin(this, StyleRef().MarginLeft());
}
LayoutUnit LayoutInline::MarginRight() const {
- return ComputeMargin(this, Style()->MarginRight());
+ return ComputeMargin(this, StyleRef().MarginRight());
}
LayoutUnit LayoutInline::MarginTop() const {
- return ComputeMargin(this, Style()->MarginTop());
+ return ComputeMargin(this, StyleRef().MarginTop());
}
LayoutUnit LayoutInline::MarginBottom() const {
- return ComputeMargin(this, Style()->MarginBottom());
+ return ComputeMargin(this, StyleRef().MarginBottom());
}
bool LayoutInline::NodeAtPoint(HitTestResult& result,
@@ -908,9 +932,9 @@ bool LayoutInline::NodeAtPoint(HitTestResult& result,
return false;
}
- return line_boxes_.HitTest(LineLayoutBoxModel(this), result,
- location_in_container, accumulated_offset,
- hit_test_action);
+ return LineBoxes()->HitTest(LineLayoutBoxModel(this), result,
+ location_in_container, accumulated_offset,
+ hit_test_action);
}
namespace {
@@ -1034,12 +1058,12 @@ class LinesBoundingBoxGeneratorContext {
LayoutRect LayoutInline::LinesBoundingBox() const {
if (const NGPhysicalBoxFragment* box_fragment =
EnclosingBlockFlowFragmentOf(*this)) {
- LayoutRect result;
+ NGPhysicalOffsetRect bounding_box;
auto children =
NGInlineFragmentTraversal::SelfFragmentsOf(*box_fragment, this);
for (const auto& child : children)
- result.Unite(child.RectInContainerBox().ToLayoutRect());
- return result;
+ bounding_box.UniteIfNonZero(child.RectInContainerBox());
+ return bounding_box.ToLayoutRect();
}
if (!AlwaysCreateLineBoxes()) {
@@ -1071,7 +1095,7 @@ LayoutRect LayoutInline::LinesBoundingBox() const {
logical_right_side = curr->LogicalRight();
}
- bool is_horizontal = Style()->IsHorizontalWritingMode();
+ bool is_horizontal = StyleRef().IsHorizontalWritingMode();
LayoutUnit x = is_horizontal ? logical_left_side : FirstLineBox()->X();
LayoutUnit y = is_horizontal ? FirstLineBox()->Y() : logical_left_side;
@@ -1138,7 +1162,7 @@ LayoutRect LayoutInline::CulledInlineVisualOverflowBoundingBox() const {
LinesBoundingBoxGeneratorContext context(float_result);
GenerateCulledLineBoxRects(context, this);
LayoutRect result(EnclosingLayoutRect(float_result));
- bool is_horizontal = Style()->IsHorizontalWritingMode();
+ bool is_horizontal = StyleRef().IsHorizontalWritingMode();
for (LayoutObject* curr = FirstChild(); curr; curr = curr->NextSibling()) {
if (curr->IsFloatingOrOutOfFlowPositioned())
continue;
@@ -1184,7 +1208,10 @@ LayoutRect LayoutInline::LinesVisualOverflowBoundingBox() const {
child_rect.offset += child.offset_to_container_box;
result.Unite(child_rect);
}
- return result.ToLayoutRect();
+ LayoutRect rect = result.ToLayoutRect();
+ if (HasFlippedBlocksWritingMode())
+ ContainingBlock()->FlipForWritingMode(rect);
+ return rect;
}
if (!AlwaysCreateLineBoxes())
@@ -1215,7 +1242,7 @@ LayoutRect LayoutInline::LinesVisualOverflowBoundingBox() const {
LayoutRect rect(logical_left_side, logical_top, logical_width,
logical_height);
- if (!Style()->IsHorizontalWritingMode())
+ if (!StyleRef().IsHorizontalWritingMode())
rect = rect.TransposedRect();
return rect;
}
@@ -1274,7 +1301,7 @@ LayoutRect LayoutInline::LocalVisualRectIgnoringVisibility() const {
LayoutRect LayoutInline::VisualOverflowRect() const {
LayoutRect overflow_rect = LinesVisualOverflowBoundingBox();
- LayoutUnit outline_outset(Style()->OutlineOutsetExtent());
+ LayoutUnit outline_outset(StyleRef().OutlineOutsetExtent());
if (outline_outset) {
Vector<LayoutRect> rects;
if (GetDocument().InNoQuirksMode()) {
@@ -1312,13 +1339,13 @@ bool LayoutInline::MapToVisualRectInAncestorSpaceInternal(
if (!container)
return true;
- bool preserve3d = container->Style()->Preserves3D();
+ bool preserve3d = container->StyleRef().Preserves3D();
TransformState::TransformAccumulation accumulation =
preserve3d ? TransformState::kAccumulateTransform
: TransformState::kFlattenTransform;
- if (Style()->HasInFlowPosition() && Layer()) {
+ if (StyleRef().HasInFlowPosition() && Layer()) {
// Apply the in-flow position offset when invalidating a rectangle. The
// layer is translated, but the layout box isn't, so we need to do this to
// get the right dirty rect. Since this is called from LayoutObject::
@@ -1362,7 +1389,7 @@ LayoutSize LayoutInline::OffsetFromContainerInternal(
PaintLayerType LayoutInline::LayerTypeRequired() const {
return IsInFlowPositioned() || CreatesGroup() ||
- Style()->ShouldCompositeForCurrentAnimations() ||
+ StyleRef().ShouldCompositeForCurrentAnimations() ||
ShouldApplyPaintContainment()
? kNormalPaintLayer
: kNoPaintLayer;
@@ -1404,7 +1431,7 @@ void LayoutInline::UpdateHitTestResult(HitTestResult& result,
void LayoutInline::DirtyLineBoxes(bool full_layout) {
if (full_layout) {
- line_boxes_.DeleteLineBoxes();
+ DeleteLineBoxes();
return;
}
@@ -1431,7 +1458,7 @@ void LayoutInline::DirtyLineBoxes(bool full_layout) {
}
}
} else {
- line_boxes_.DirtyLineBoxes();
+ MutableLineBoxes()->DirtyLineBoxes();
}
}
@@ -1442,20 +1469,18 @@ InlineFlowBox* LayoutInline::CreateInlineFlowBox() {
InlineFlowBox* LayoutInline::CreateAndAppendInlineFlowBox() {
SetAlwaysCreateLineBoxes();
InlineFlowBox* flow_box = CreateInlineFlowBox();
- line_boxes_.AppendLineBox(flow_box);
+ MutableLineBoxes()->AppendLineBox(flow_box);
return flow_box;
}
void LayoutInline::DirtyLinesFromChangedChild(
LayoutObject* child,
MarkingBehavior marking_behavior) {
- // During layout tree construction, we can't detect whether this node is
- // in LayoutNG or not.
- if (Parent() && EnclosingNGBlockFlow()) {
+ if (IsInLayoutNGInlineFormattingContext()) {
SetAncestorLineBoxDirty();
return;
}
- line_boxes_.DirtyLinesFromChangedChild(
+ MutableLineBoxes()->DirtyLinesFromChangedChild(
LineLayoutItem(this), LineLayoutItem(child),
marking_behavior == kMarkContainerChain);
}
@@ -1470,7 +1495,7 @@ LayoutUnit LayoutInline::LineHeight(
return LayoutUnit(s->ComputedLineHeight());
}
- return LayoutUnit(Style()->ComputedLineHeight());
+ return LayoutUnit(StyleRef().ComputedLineHeight());
}
LayoutUnit LayoutInline::BaselinePosition(
@@ -1516,23 +1541,17 @@ LayoutSize LayoutInline::OffsetForInFlowPositionedInline(
// Per http://www.w3.org/TR/CSS2/visudet.html#abs-non-replaced-width an
// absolute positioned box with a static position should locate itself as
- // though it is a normal flow box in relation to its containing block. If this
- // relative-positioned inline has a negative offset we need to compensate for
- // it so that we align the positioned object with the edge of its containing
- // block.
- if (child.Style()->HasStaticInlinePosition(
- Style()->IsHorizontalWritingMode()))
- logical_offset.SetWidth(
- std::max(LayoutUnit(), -OffsetForInFlowPosition().Width()));
- else
+ // though it is a normal flow box in relation to its containing block.
+ if (!child.StyleRef().HasStaticInlinePosition(
+ StyleRef().IsHorizontalWritingMode()))
logical_offset.SetWidth(inline_position);
- if (!child.Style()->HasStaticBlockPosition(
- Style()->IsHorizontalWritingMode()))
+ if (!child.StyleRef().HasStaticBlockPosition(
+ StyleRef().IsHorizontalWritingMode()))
logical_offset.SetHeight(block_position);
- return Style()->IsHorizontalWritingMode() ? logical_offset
- : logical_offset.TransposedSize();
+ return StyleRef().IsHorizontalWritingMode() ? logical_offset
+ : logical_offset.TransposedSize();
}
void LayoutInline::ImageChanged(WrappedImagePtr,
@@ -1592,18 +1611,24 @@ void LayoutInline::AddOutlineRectsForContinuations(
const LayoutPoint& additional_offset,
IncludeBlockVisualOverflowOrNot include_block_overflows) const {
if (LayoutBoxModelObject* continuation = Continuation()) {
+ if (continuation->NeedsLayout()) {
+ // TODO(mstensho): Prevent this from happening. Before we can get the
+ // outlines of an object, we obviously need to have laid it out. We may
+ // currently end up in a situation where the continuation's layout isn't
+ // up-to-date here. This happens when calculating the overflow rectangle
+ // while laying out one of the earlier anonymous blocks that form the
+ // continuation chain. The outlines from the continuations should probably
+ // not be part of the overflow rectangle of that anonymous block at
+ // all. Yet, here we are. Bail.
+ return;
+ }
+ LayoutPoint offset = additional_offset;
if (continuation->IsInline())
- continuation->AddOutlineRects(
- rects,
- additional_offset + (continuation->ContainingBlock()->Location() -
- ContainingBlock()->Location()),
- include_block_overflows);
+ offset += continuation->ContainingBlock()->Location();
else
- continuation->AddOutlineRects(
- rects,
- additional_offset + (ToLayoutBox(continuation)->Location() -
- ContainingBlock()->Location()),
- include_block_overflows);
+ offset += ToLayoutBox(continuation)->Location();
+ offset -= ContainingBlock()->Location();
+ continuation->AddOutlineRects(rects, offset, include_block_overflows);
}
}
@@ -1622,15 +1647,15 @@ void LayoutInline::ComputeSelfHitTestRects(
void LayoutInline::AddAnnotatedRegions(Vector<AnnotatedRegionValue>& regions) {
// Convert the style regions to absolute coordinates.
- if (Style()->Visibility() != EVisibility::kVisible)
+ if (StyleRef().Visibility() != EVisibility::kVisible)
return;
- if (Style()->DraggableRegionMode() == EDraggableRegionMode::kNone)
+ if (StyleRef().DraggableRegionMode() == EDraggableRegionMode::kNone)
return;
AnnotatedRegionValue region;
region.draggable =
- Style()->DraggableRegionMode() == EDraggableRegionMode::kDrag;
+ StyleRef().DraggableRegionMode() == EDraggableRegionMode::kDrag;
region.bounds = LayoutRect(LinesBoundingBox());
LayoutObject* container = ContainingBlock();
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 c9ebb0bdcf4..026a6943695 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_inline.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_inline.h
@@ -116,6 +116,8 @@ class CORE_EXPORT LayoutInline : public LayoutBoxModelObject {
public:
explicit LayoutInline(Element*);
+ ~LayoutInline() override;
+
static LayoutInline* CreateAnonymous(Document*);
LayoutObject* FirstChild() const {
@@ -158,11 +160,16 @@ class CORE_EXPORT LayoutInline : public LayoutBoxModelObject {
void DirtyLineBoxes(bool full_layout);
- LineBoxList* LineBoxes() { return &line_boxes_; }
- const LineBoxList* LineBoxes() const { return &line_boxes_; }
+ // LineBoxes() and FirstInlineFragment() are mutually exclusive,
+ // depends on IsInLayoutNGInlineFormattingContext().
+ const LineBoxList* LineBoxes() const {
+ return IsInLayoutNGInlineFormattingContext() ? &LineBoxList::Empty()
+ : &line_boxes_;
+ }
+ LineBoxList* MutableLineBoxes();
- InlineFlowBox* FirstLineBox() const { return line_boxes_.First(); }
- InlineFlowBox* LastLineBox() const { return line_boxes_.Last(); }
+ InlineFlowBox* FirstLineBox() const { return LineBoxes()->First(); }
+ InlineFlowBox* LastLineBox() const { return LineBoxes()->Last(); }
InlineBox* FirstLineBoxIncludingCulling() const {
return AlwaysCreateLineBoxes() ? FirstLineBox()
: CulledInlineFirstLineBox();
@@ -171,6 +178,9 @@ class CORE_EXPORT LayoutInline : public LayoutBoxModelObject {
return AlwaysCreateLineBoxes() ? LastLineBox() : CulledInlineLastLineBox();
}
+ NGPaintFragment* FirstInlineFragment() const final;
+ void SetFirstInlineFragment(NGPaintFragment*) final;
+
LayoutBoxModelObject* VirtualContinuation() const final {
return Continuation();
}
@@ -229,6 +239,10 @@ class CORE_EXPORT LayoutInline : public LayoutBoxModelObject {
protected:
void WillBeDestroyed() override;
+ void InLayoutNGInlineFormattingContextWillChange(bool) final;
+
+ void DeleteLineBoxes();
+
void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
void ComputeSelfHitTestRects(Vector<LayoutRect>& rects,
@@ -353,11 +367,28 @@ class CORE_EXPORT LayoutInline : public LayoutBoxModelObject {
LayoutBoxModelObject* ContinuationBefore(LayoutObject* before_child);
LayoutObjectChildList children_;
- // All of the line boxes created for this inline flow. For example,
- // <i>Hello<br>world.</i> will have two <i> line boxes.
- LineBoxList line_boxes_;
+
+ union {
+ // All of the line boxes created for this inline flow. For example,
+ // <i>Hello<br>world.</i> will have two <i> line boxes.
+ // Valid only when !IsInLayoutNGInlineFormattingContext().
+ LineBoxList line_boxes_;
+ // The first fragment of inline boxes associated with this object.
+ // Valid only when IsInLayoutNGInlineFormattingContext().
+ scoped_refptr<NGPaintFragment> first_paint_fragment_;
+ };
};
+inline LineBoxList* LayoutInline::MutableLineBoxes() {
+ CHECK(!IsInLayoutNGInlineFormattingContext());
+ return &line_boxes_;
+}
+
+inline NGPaintFragment* LayoutInline::FirstInlineFragment() const {
+ return IsInLayoutNGInlineFormattingContext() ? first_paint_fragment_.get()
+ : nullptr;
+}
+
DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutInline, IsLayoutInline());
} // namespace blink
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
index 2e51a69f048..7e9a28f344a 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_list_box.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_list_box.cc
@@ -70,7 +70,7 @@ unsigned LayoutListBox::size() const {
}
LayoutUnit LayoutListBox::DefaultItemHeight() const {
- const SimpleFontData* font_data = Style()->GetFont().PrimaryFont();
+ const SimpleFontData* font_data = StyleRef().GetFont().PrimaryFont();
if (!font_data)
return LayoutUnit();
return LayoutUnit(font_data->GetFontMetrics().Height() +
@@ -127,7 +127,7 @@ void LayoutListBox::ComputeIntrinsicLogicalWidths(
LayoutUnit& max_logical_width) const {
LayoutBlockFlow::ComputeIntrinsicLogicalWidths(min_logical_width,
max_logical_width);
- if (Style()->Width().IsPercentOrCalc())
+ if (StyleRef().Width().IsPercentOrCalc())
min_logical_width = LayoutUnit();
}
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 4c9de99ea96..1a1b1939108 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
@@ -51,8 +51,8 @@ void LayoutListItem::StyleDidChange(StyleDifference diff,
const ComputedStyle* old_style) {
LayoutBlockFlow::StyleDidChange(diff, old_style);
- StyleImage* current_image = Style()->ListStyleImage();
- if (Style()->ListStyleType() != EListStyleType::kNone ||
+ StyleImage* current_image = StyleRef().ListStyleImage();
+ if (StyleRef().ListStyleType() != EListStyleType::kNone ||
(current_image && !current_image->ErrorOccurred())) {
if (!marker_)
marker_ = LayoutListMarker::CreateAnonymous(this);
@@ -80,8 +80,8 @@ void LayoutListItem::WillBeDestroyed() {
LayoutBlockFlow::WillBeDestroyed();
- if (Style() && Style()->ListStyleImage())
- Style()->ListStyleImage()->RemoveClient(this);
+ if (Style() && StyleRef().ListStyleImage())
+ StyleRef().ListStyleImage()->RemoveClient(this);
}
void LayoutListItem::InsertedIntoTree() {
@@ -397,7 +397,7 @@ void LayoutListItem::PositionListMarker() {
// TODO(jchaffraix): Propagating the overflow to the line boxes seems
// pretty wrong (https://crbug.com/554160).
// FIXME: Need to account for relative positioning in the layout overflow.
- if (Style()->IsLeftToRightDirection()) {
+ if (StyleRef().IsLeftToRightDirection()) {
LayoutUnit marker_line_offset =
std::min(marker_->LineOffset(),
LogicalLeftOffsetForLine(marker_->LogicalTop(),
@@ -482,7 +482,7 @@ void LayoutListItem::PositionListMarker() {
LayoutPoint(marker_logical_left + line_offset,
block_offset + marker_inline_box->LogicalTop()),
marker_->Size());
- if (!Style()->IsHorizontalWritingMode())
+ if (!StyleRef().IsHorizontalWritingMode())
marker_rect = marker_rect.TransposedRect();
LayoutBox* o = marker_;
bool propagate_visual_overflow = true;
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 5e34e8e29be..e52e55838ec 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
@@ -64,7 +64,7 @@ LayoutListMarker* LayoutListMarker::CreateAnonymous(LayoutListItem* item) {
LayoutSize LayoutListMarker::ImageBulletSize() const {
DCHECK(IsImage());
- const SimpleFontData* font_data = Style()->GetFont().PrimaryFont();
+ const SimpleFontData* font_data = StyleRef().GetFont().PrimaryFont();
DCHECK(font_data);
if (!font_data)
return LayoutSize();
@@ -76,15 +76,15 @@ LayoutSize LayoutListMarker::ImageBulletSize() const {
LayoutUnit bullet_width =
font_data->GetFontMetrics().Ascent() / LayoutUnit(2);
return RoundedLayoutSize(
- image_->ImageSize(GetDocument(), Style()->EffectiveZoom(),
+ image_->ImageSize(GetDocument(), StyleRef().EffectiveZoom(),
LayoutSize(bullet_width, bullet_width)));
}
void LayoutListMarker::StyleWillChange(StyleDifference diff,
const ComputedStyle& new_style) {
if (Style() &&
- (new_style.ListStylePosition() != Style()->ListStylePosition() ||
- new_style.ListStyleType() != Style()->ListStyleType()))
+ (new_style.ListStylePosition() != StyleRef().ListStylePosition() ||
+ new_style.ListStyleType() != StyleRef().ListStyleType()))
SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
LayoutInvalidationReason::kStyleChange);
@@ -95,10 +95,10 @@ void LayoutListMarker::StyleDidChange(StyleDifference diff,
const ComputedStyle* old_style) {
LayoutBox::StyleDidChange(diff, old_style);
- if (image_ != Style()->ListStyleImage()) {
+ if (image_ != StyleRef().ListStyleImage()) {
if (image_)
image_->RemoveClient(this);
- image_ = Style()->ListStyleImage();
+ image_ = StyleRef().ListStyleImage();
if (image_)
image_->AddClient(this);
}
@@ -126,7 +126,7 @@ void LayoutListMarker::UpdateLayout() {
for (LayoutBox* o = ParentBox(); o && o != ListItem(); o = o->ParentBox()) {
block_offset += o->LogicalTop();
}
- if (ListItem()->Style()->IsLeftToRightDirection()) {
+ if (ListItem()->StyleRef().IsLeftToRightDirection()) {
line_offset_ = ListItem()->LogicalLeftOffsetForLine(
block_offset, kDoNotIndentText, LayoutUnit());
} else {
@@ -139,7 +139,7 @@ void LayoutListMarker::UpdateLayout() {
SetWidth(image_size.Width());
SetHeight(image_size.Height());
} else {
- const SimpleFontData* font_data = Style()->GetFont().PrimaryFont();
+ const SimpleFontData* font_data = StyleRef().GetFont().PrimaryFont();
DCHECK(font_data);
SetLogicalWidth(MinPreferredLogicalWidth());
SetLogicalHeight(
@@ -149,8 +149,8 @@ void LayoutListMarker::UpdateLayout() {
SetMarginStart(LayoutUnit());
SetMarginEnd(LayoutUnit());
- Length start_margin = Style()->MarginStart();
- Length end_margin = Style()->MarginEnd();
+ Length start_margin = StyleRef().MarginStart();
+ Length end_margin = StyleRef().MarginEnd();
if (start_margin.IsFixed())
SetMarginStart(LayoutUnit(start_margin.Value()));
if (end_margin.IsFixed())
@@ -194,11 +194,11 @@ void LayoutListMarker::UpdateContent() {
case ListStyleCategory::kNone:
break;
case ListStyleCategory::kSymbol:
- text_ = ListMarkerText::GetText(Style()->ListStyleType(),
+ text_ = ListMarkerText::GetText(StyleRef().ListStyleType(),
0); // value is ignored for these types
break;
case ListStyleCategory::kLanguage:
- text_ = ListMarkerText::GetText(Style()->ListStyleType(),
+ text_ = ListMarkerText::GetText(StyleRef().ListStyleType(),
list_item_->Value());
break;
}
@@ -206,7 +206,7 @@ void LayoutListMarker::UpdateContent() {
String LayoutListMarker::TextAlternative() const {
UChar suffix =
- ListMarkerText::Suffix(Style()->ListStyleType(), list_item_->Value());
+ ListMarkerText::Suffix(StyleRef().ListStyleType(), list_item_->Value());
// Return suffix after the marker text, even in RTL, reflecting speech order.
return text_ + suffix + ' ';
}
@@ -214,15 +214,15 @@ String LayoutListMarker::TextAlternative() const {
LayoutUnit LayoutListMarker::GetWidthOfTextWithSuffix() const {
if (text_.IsEmpty())
return LayoutUnit();
- const Font& font = Style()->GetFont();
+ const Font& font = StyleRef().GetFont();
LayoutUnit item_width = LayoutUnit(font.Width(TextRun(text_)));
// TODO(wkorman): Look into constructing a text run for both text and suffix
// and painting them together.
UChar suffix[2] = {
- ListMarkerText::Suffix(Style()->ListStyleType(), list_item_->Value()),
+ ListMarkerText::Suffix(StyleRef().ListStyleType(), list_item_->Value()),
' '};
TextRun run =
- ConstructTextRun(font, suffix, 2, StyleRef(), Style()->Direction());
+ ConstructTextRun(font, suffix, 2, StyleRef(), StyleRef().Direction());
LayoutUnit suffix_space_width = LayoutUnit(font.Width(run));
return item_width + suffix_space_width;
}
@@ -234,8 +234,8 @@ void LayoutListMarker::ComputePreferredLogicalWidths() {
if (IsImage()) {
LayoutSize image_size(ImageBulletSize());
min_preferred_logical_width_ = max_preferred_logical_width_ =
- Style()->IsHorizontalWritingMode() ? image_size.Width()
- : image_size.Height();
+ StyleRef().IsHorizontalWritingMode() ? image_size.Width()
+ : image_size.Height();
ClearPreferredLogicalWidthsDirty();
UpdateMargins();
return;
@@ -296,8 +296,6 @@ void LayoutListMarker::UpdateMargins() {
std::pair<LayoutUnit, LayoutUnit> LayoutListMarker::InlineMarginsForInside(
const ComputedStyle& style,
bool is_image) {
- LayoutUnit margin_start;
- LayoutUnit margin_end;
if (is_image)
return {LayoutUnit(), LayoutUnit(kCMarkerPaddingPx)};
switch (GetListStyleCategory(style.ListStyleType())) {
@@ -462,7 +460,7 @@ LayoutListMarker::ListStyleCategory LayoutListMarker::GetListStyleCategory(
bool LayoutListMarker::IsInside() const {
return list_item_->Ordinal().NotInList() ||
- Style()->ListStylePosition() == EListStylePosition::kInside;
+ StyleRef().ListStylePosition() == EListStylePosition::kInside;
}
LayoutRect LayoutListMarker::GetRelativeMarkerRect() const {
@@ -476,7 +474,7 @@ LayoutRect LayoutListMarker::GetRelativeMarkerRect() const {
case ListStyleCategory::kSymbol:
return RelativeSymbolMarkerRect(StyleRef(), Size().Width());
case ListStyleCategory::kLanguage: {
- const SimpleFontData* font_data = Style()->GetFont().PrimaryFont();
+ const SimpleFontData* font_data = StyleRef().GetFont().PrimaryFont();
DCHECK(font_data);
if (!font_data)
return relative_rect;
@@ -487,7 +485,7 @@ LayoutRect LayoutListMarker::GetRelativeMarkerRect() const {
}
}
- if (!Style()->IsHorizontalWritingMode()) {
+ if (!StyleRef().IsHorizontalWritingMode()) {
relative_rect = relative_rect.TransposedRect();
relative_rect.SetX(Size().Width() - relative_rect.X() -
relative_rect.Width());
@@ -526,8 +524,8 @@ void LayoutListMarker::ListItemStyleDidChange() {
if (Style()) {
// Reuse the current margins. Otherwise resetting the margins to initial
// values would trigger unnecessary layout.
- new_style->SetMarginStart(Style()->MarginStart());
- new_style->SetMarginEnd(Style()->MarginRight());
+ new_style->SetMarginStart(StyleRef().MarginStart());
+ new_style->SetMarginEnd(StyleRef().MarginRight());
}
SetStyle(std::move(new_style));
}
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 bd60a3f2faf..5157116554f 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_media.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_media.cc
@@ -45,11 +45,11 @@ HTMLMediaElement* LayoutMedia::MediaElement() const {
}
void LayoutMedia::UpdateLayout() {
- LayoutSize old_size = ContentBoxRect().Size();
+ LayoutSize old_size(ContentWidth(), ContentHeight());
LayoutImage::UpdateLayout();
- LayoutRect new_rect = ContentBoxRect();
+ LayoutRect new_rect(PhysicalContentBoxRect());
LayoutState state(*this);
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
index 5a05b42ab92..b94bd3119a9 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_menu_list.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_menu_list.cc
@@ -35,6 +35,7 @@
#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 {
@@ -77,6 +78,8 @@ void LayoutMenuList::UpdateInnerStyle() {
inner_block_->SetStyleInternal(std::move(inner_style));
// LayoutMenuList::ControlClipRect() depends on inner_block_->ContentsSize().
SetNeedsPaintPropertyUpdate();
+ if (Layer())
+ Layer()->SetNeedsCompositingInputsUpdate();
}
void LayoutMenuList::CreateInnerBlock() {
@@ -91,16 +94,18 @@ void LayoutMenuList::CreateInnerBlock() {
inner_block_ =
LayoutBlockFlow::CreateAnonymous(&GetDocument(), CreateInnerStyle());
- button_text_ = LayoutText::CreateEmptyAnonymous(GetDocument());
+ button_text_ =
+ LayoutText::CreateEmptyAnonymous(GetDocument(), MutableStyle());
// 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.
- button_text_->SetStyle(MutableStyle());
inner_block_->AddChild(button_text_);
LayoutFlexibleBox::AddChild(inner_block_);
// LayoutMenuList::ControlClipRect() depends on inner_block_->ContentsSize().
SetNeedsPaintPropertyUpdate();
+ if (Layer())
+ Layer()->SetNeedsCompositingInputsUpdate();
}
bool LayoutMenuList::HasOptionStyleChanged(
@@ -120,7 +125,7 @@ void LayoutMenuList::AdjustInnerStyle(ComputedStyle& inner_style) const {
// 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 (Style()->AlignItemsPosition() == ItemPosition::kCenter) {
+ if (StyleRef().AlignItemsPosition() == ItemPosition::kCenter) {
inner_style.SetMarginTop(Length());
inner_style.SetMarginBottom(Length());
inner_style.SetAlignSelfPosition(ItemPosition::kFlexStart);
@@ -168,6 +173,8 @@ void LayoutMenuList::AddChild(LayoutObject* new_child,
// LayoutMenuList::ControlClipRect() depends on inner_block_->ContentsSize().
SetNeedsPaintPropertyUpdate();
+ if (Layer())
+ Layer()->SetNeedsCompositingInputsUpdate();
}
void LayoutMenuList::RemoveChild(LayoutObject* old_child) {
@@ -192,7 +199,7 @@ void LayoutMenuList::StyleDidChange(StyleDifference diff,
}
void LayoutMenuList::UpdateInnerBlockHeight() {
- const SimpleFontData* font_data = Style()->GetFont().PrimaryFont();
+ const SimpleFontData* font_data = StyleRef().GetFont().PrimaryFont();
DCHECK(font_data);
inner_block_height_ = (font_data ? font_data->GetFontMetrics().Height() : 0) +
inner_block_->BorderAndPaddingHeight();
@@ -208,9 +215,9 @@ void LayoutMenuList::UpdateOptionsWidth() const {
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(Style()->GetFont(), text, *Style());
+ TextRun text_run = ConstructTextRun(StyleRef().GetFont(), text, *Style());
max_option_width =
- std::max(max_option_width, Style()->GetFont().Width(text_run));
+ std::max(max_option_width, StyleRef().GetFont().Width(text_run));
}
options_width_ = static_cast<int>(ceilf(max_option_width));
}
@@ -275,6 +282,8 @@ void LayoutMenuList::SetText(const String& s) {
}
// LayoutMenuList::ControlClipRect() depends on inner_block_->ContentsSize().
SetNeedsPaintPropertyUpdate();
+ if (Layer())
+ Layer()->SetNeedsCompositingInputsUpdate();
}
String LayoutMenuList::GetText() const {
@@ -287,7 +296,7 @@ LayoutRect LayoutMenuList::ControlClipRect(
// 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.
- LayoutRect outer_box = ContentBoxRect();
+ LayoutRect outer_box = PhysicalContentBoxRect();
outer_box.MoveBy(additional_offset);
LayoutRect inner_box(
@@ -307,7 +316,7 @@ void LayoutMenuList::ComputeIntrinsicLogicalWidths(
std::max(options_width_,
LayoutTheme::GetTheme().MinimumMenuListSize(StyleRef())) +
inner_block_->PaddingLeft() + inner_block_->PaddingRight();
- if (!Style()->Width().IsPercentOrCalc())
+ if (!StyleRef().Width().IsPercentOrCalc())
min_logical_width = max_logical_width;
else
min_logical_width = LayoutUnit();
@@ -317,7 +326,7 @@ void LayoutMenuList::ComputeLogicalHeight(
LayoutUnit logical_height,
LayoutUnit logical_top,
LogicalExtentComputedValues& computed_values) const {
- if (Style()->HasAppearance())
+ if (StyleRef().HasAppearance())
logical_height = inner_block_height_ + BorderAndPaddingHeight();
LayoutBox::ComputeLogicalHeight(logical_height, logical_top, computed_values);
}
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 4f96b5b4d2d..5fc48cc8d8a 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
@@ -330,7 +330,7 @@ LayoutUnit LayoutMultiColumnFlowThread::MaxColumnLogicalHeight() const {
return column_height_available_;
}
const LayoutBlockFlow* multicol_block = MultiColumnBlockFlow();
- Length logical_max_height = multicol_block->Style()->LogicalMaxHeight();
+ Length logical_max_height = multicol_block->StyleRef().LogicalMaxHeight();
if (!logical_max_height.IsMaxSizeNone()) {
LayoutUnit resolved_logical_max_height =
multicol_block->ComputeContentLogicalHeight(
@@ -889,7 +889,7 @@ bool LayoutMultiColumnFlowThread::DescendantIsValidColumnSpanner(
// The spec says that column-span only applies to in-flow block-level
// elements.
- if (descendant->Style()->GetColumnSpan() != EColumnSpan::kAll ||
+ if (descendant->StyleRef().GetColumnSpan() != EColumnSpan::kAll ||
!descendant->IsBox() || descendant->IsInline() ||
descendant->IsFloatingOrOutOfFlowPositioned())
return false;
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 66b6ce7896b..5d3fcefbc4c 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
@@ -346,7 +346,7 @@ bool LayoutMultiColumnSet::HeightIsAuto() const {
// 'balance' - in accordance with the spec).
// Pretending that column-fill is auto also matches the old multicol
// implementation, which has no support for this property.
- if (MultiColumnBlockFlow()->Style()->GetColumnFill() ==
+ if (MultiColumnBlockFlow()->StyleRef().GetColumnFill() ==
EColumnFill::kBalance)
return true;
if (LayoutBox* next = NextSiblingBox()) {
@@ -492,12 +492,12 @@ PositionWithAffinity LayoutMultiColumnSet::PositionForPoint(
LayoutUnit LayoutMultiColumnSet::ColumnGap() const {
LayoutBlockFlow* parent_block = MultiColumnBlockFlow();
- if (parent_block->Style()->ColumnGap().IsNormal()) {
+ if (parent_block->StyleRef().ColumnGap().IsNormal()) {
// "1em" is recommended as the normal gap setting. Matches <p> margins.
return LayoutUnit(
- parent_block->Style()->GetFontDescription().ComputedPixelSize());
+ parent_block->StyleRef().GetFontDescription().ComputedPixelSize());
}
- return ValueForLength(parent_block->Style()->ColumnGap().GetLength(),
+ return ValueForLength(parent_block->StyleRef().ColumnGap().GetLength(),
AvailableLogicalWidth());
}
@@ -591,7 +591,7 @@ bool LayoutMultiColumnSet::ComputeColumnRuleBounds(
if (col_count <= 1)
return false;
- bool left_to_right = Style()->IsLeftToRightDirection();
+ bool left_to_right = StyleRef().IsLeftToRightDirection();
LayoutUnit curr_logical_left_offset =
left_to_right ? LayoutUnit() : ContentLogicalWidth();
LayoutUnit rule_add = BorderAndPaddingLogicalLeft();
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 087c84fcb6d..97f9fff388a 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
@@ -46,7 +46,7 @@ void LayoutMultiColumnSpannerPlaceholder::
if (FlowThread()->RemoveSpannerPlaceholderIfNoLongerValid(
object_in_flow_thread)) {
// No longer a valid spanner, due to style changes. |this| is now dead.
- if (object_in_flow_thread->Style()->HasOutOfFlowPosition() &&
+ if (object_in_flow_thread->StyleRef().HasOutOfFlowPosition() &&
!old_style->HasOutOfFlowPosition()) {
// We went from being a spanner to being out-of-flow positioned. When an
// object becomes out-of-flow positioned, we need to lay out its parent,
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 1742a37f570..4f03d574ef5 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_object.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_object.cc
@@ -92,6 +92,7 @@
#include "third_party/blink/renderer/core/paint/object_paint_invalidator.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/smooth_scroll_sequencer.h"
#include "third_party/blink/renderer/core/style/content_data.h"
#include "third_party/blink/renderer/core/style/cursor_data.h"
#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
@@ -101,7 +102,6 @@
#include "third_party/blink/renderer/platform/instance_counters.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/traced_value.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
-#include "third_party/blink/renderer/platform/scroll/smooth_scroll_sequencer.h"
#include "third_party/blink/renderer/platform/transforms/transform_state.h"
#include "third_party/blink/renderer/platform/wtf/allocator/partitions.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
@@ -136,8 +136,8 @@ LayoutBlock* FindContainingBlock(LayoutObject* container,
// LayoutObject::Container() method can actually be used to obtain the inline
// directly.
if (container && container->IsInline() && !container->IsAtomicInlineLevel()) {
- DCHECK(container->Style()->HasInFlowPosition() ||
- container->Style()->HasFilter());
+ DCHECK(container->StyleRef().HasInFlowPosition() ||
+ container->StyleRef().HasFilter());
container = container->ContainingBlock(skip_info);
}
@@ -170,7 +170,9 @@ LayoutObject::SetLayoutNeededForbiddenScope::~SetLayoutNeededForbiddenScope() {
#endif
struct SameSizeAsLayoutObject : DisplayItemClient {
- ~SameSizeAsLayoutObject() override = default; // Allocate vtable pointer.
+ // Normally this field uses the gap between DisplayItemClient and
+ // LayoutObject's other fields.
+ uint8_t paint_invalidation_reason_;
void* pointers[5];
Member<void*> members[1];
#if DCHECK_IS_ON()
@@ -276,7 +278,8 @@ LayoutObject* LayoutObject::CreateObject(Element* element,
}
LayoutObject::LayoutObject(Node* node)
- : style_(nullptr),
+ : full_paint_invalidation_reason_(PaintInvalidationReason::kNone),
+ style_(nullptr),
node_(node),
parent_(nullptr),
previous_(nullptr),
@@ -378,7 +381,7 @@ void LayoutObject::AddChild(LayoutObject* new_child,
}
if (new_child->IsText() &&
- new_child->Style()->TextTransform() == ETextTransform::kCapitalize)
+ new_child->StyleRef().TextTransform() == ETextTransform::kCapitalize)
ToLayoutText(new_child)->TransformText();
}
@@ -698,13 +701,13 @@ LayoutRect LayoutObject::ScrollRectToVisible(
if (!enclosing_box)
return rect;
- GetDocument().GetPage()->GetSmoothScrollSequencer()->AbortAnimations();
+ GetDocument().GetFrame()->GetSmoothScrollSequencer().AbortAnimations();
WebScrollIntoViewParams new_params(params);
new_params.is_for_scroll_sequence |=
params.GetScrollType() == kProgrammaticScroll;
LayoutRect new_location =
enclosing_box->ScrollRectToVisibleRecursive(rect, new_params);
- GetDocument().GetPage()->GetSmoothScrollSequencer()->RunQueuedAnimations();
+ GetDocument().GetFrame()->GetSmoothScrollSequencer().RunQueuedAnimations();
return new_location;
}
@@ -887,7 +890,7 @@ void LayoutObject::MarkContainerChainForLayout(bool schedule_relayout,
LayoutObject* container = object->Container();
if (!container && !object->IsLayoutView())
return;
- if (!last->IsTextOrSVGChild() && last->Style()->HasOutOfFlowPosition()) {
+ if (!last->IsTextOrSVGChild() && last->StyleRef().HasOutOfFlowPosition()) {
object = last->ContainingBlock();
if (object->PosChildNeedsLayout())
return;
@@ -939,7 +942,7 @@ void LayoutObject::SetPreferredLogicalWidthsDirty(
MarkingBehavior mark_parents) {
bitfields_.SetPreferredLogicalWidthsDirty(true);
if (mark_parents == kMarkContainerChain &&
- (IsText() || !Style()->HasOutOfFlowPosition()))
+ (IsText() || !StyleRef().HasOutOfFlowPosition()))
InvalidateContainerPreferredLogicalWidths();
}
@@ -978,7 +981,7 @@ inline void LayoutObject::InvalidateContainerPreferredLogicalWidths() {
o->bitfields_.SetPreferredLogicalWidthsDirty(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->Style()->HasOutOfFlowPosition())
+ if (o->StyleRef().HasOutOfFlowPosition())
break;
o = container;
}
@@ -987,7 +990,7 @@ inline void LayoutObject::InvalidateContainerPreferredLogicalWidths() {
LayoutObject* LayoutObject::ContainerForAbsolutePosition(
AncestorSkipInfo* skip_info) const {
return FindAncestorByPredicate(this, skip_info, [](LayoutObject* candidate) {
- if (!candidate->CanContainAbsolutePositionObjects() &&
+ if (!candidate->StyleRef().CanContainAbsolutePositionObjects() &&
candidate->ShouldApplyLayoutContainment()) {
UseCounter::Count(candidate->GetDocument(),
WebFeature::kCSSContainLayoutPositionedDescendants);
@@ -1000,7 +1003,8 @@ LayoutObject* LayoutObject::ContainerForFixedPosition(
AncestorSkipInfo* skip_info) const {
DCHECK(!IsText());
return FindAncestorByPredicate(this, skip_info, [](LayoutObject* candidate) {
- if (!candidate->CanContainFixedPositionObjects() &&
+ if (!candidate->StyleRef().CanContainFixedPositionObjects(
+ candidate->IsDocumentElement()) &&
candidate->ShouldApplyLayoutContainment()) {
UseCounter::Count(candidate->GetDocument(),
WebFeature::kCSSContainLayoutPositionedDescendants);
@@ -1054,9 +1058,10 @@ LayoutBlock* LayoutObject::ContainingBlock(AncestorSkipInfo* skip_info) const {
return ToLayoutBlock(object);
}
-FloatRect LayoutObject::AbsoluteBoundingBoxFloatRect() const {
+FloatRect LayoutObject::AbsoluteBoundingBoxFloatRect(
+ MapCoordinatesFlags flags) const {
Vector<FloatQuad> quads;
- AbsoluteQuads(quads);
+ AbsoluteQuads(quads, flags);
size_t n = quads.size();
if (n == 0)
@@ -1532,7 +1537,7 @@ void LayoutObject::InvalidatePaintRectangle(const LayoutRect& dirty_rect) {
// Not using the WithoutGeometryChange version because we need to map the
// partial invalidated rect to visual rect in backing or the containing
// transform node.
- SetMayNeedPaintInvalidation();
+ SetShouldCheckForPaintInvalidation();
}
LayoutRect LayoutObject::AbsoluteSelectionRect() const {
@@ -1547,9 +1552,9 @@ LayoutRect LayoutObject::AbsoluteSelectionRect() const {
}
DISABLE_CFI_PERF
-PaintInvalidationReason LayoutObject::InvalidatePaint(
+void LayoutObject::InvalidatePaint(
const PaintInvalidatorContext& context) const {
- return ObjectPaintInvalidatorWithContext(*this, context).InvalidatePaint();
+ ObjectPaintInvalidatorWithContext(*this, context).InvalidatePaint();
}
void LayoutObject::AdjustVisualRectForCompositedScrolling(
@@ -1677,7 +1682,7 @@ bool LayoutObject::MapToVisualRectInAncestorSpaceInternal(
transform_state.SetQuad(FloatQuad(FloatRect(rect)));
}
- bool preserve3d = parent->Style()->Preserves3D() && !parent->IsText();
+ bool preserve3d = parent->StyleRef().Preserves3D() && !parent->IsText();
TransformState::TransformAccumulation accumulation =
preserve3d ? TransformState::kAccumulateTransform
@@ -1699,9 +1704,9 @@ HitTestResult LayoutObject::HitTestForOcclusion(
LocalFrame* frame = GetDocument().GetFrame();
DCHECK(!frame->View()->NeedsLayout());
HitTestRequest::HitTestRequestType hit_type =
- HitTestRequest::kListBased | HitTestRequest::kPenetratingList |
HitTestRequest::kIgnorePointerEventsNone | HitTestRequest::kReadOnly |
- HitTestRequest::kIgnoreClipping;
+ HitTestRequest::kIgnoreClipping |
+ HitTestRequest::kIgnoreZeroOpacityObjects;
HitTestLocation location(hit_rect);
return frame->GetEventHandler().HitTestResultAtLocation(location, hit_type,
this, true);
@@ -1802,8 +1807,8 @@ void LayoutObject::DumpLayoutTreeAndMark(StringBuilder& string_builder,
#endif // NDEBUG
bool LayoutObject::IsSelectable() const {
- return !IsInert() && !(Style()->UserSelect() == EUserSelect::kNone &&
- Style()->UserModify() == EUserModify::kReadOnly);
+ return !IsInert() && !(StyleRef().UserSelect() == EUserSelect::kNone &&
+ StyleRef().UserModify() == EUserModify::kReadOnly);
}
// Called when an object that was floating or positioned becomes a normal flow
@@ -1813,7 +1818,7 @@ static inline void HandleDynamicFloatPositionChange(LayoutObject* object) {
// We have gone from not affecting the inline status of the parent flow to
// suddenly having an impact. See if there is a mismatch between the parent
// flow's childrenInline() state and our state.
- object->SetInline(object->Style()->IsDisplayInlineType());
+ object->SetInline(object->StyleRef().IsDisplayInlineType());
if (object->IsInline() != object->Parent()->ChildrenInline()) {
if (!object->IsInline()) {
ToLayoutBoxModelObject(object->Parent())->ChildBecameNonInline(object);
@@ -1847,15 +1852,15 @@ StyleDifference LayoutObject::AdjustStyleDifference(
// needed if we have style or text affected by these properties.
if (diff.TextDecorationOrColorChanged() &&
!diff.NeedsFullPaintInvalidation()) {
- if (Style()->HasBorderColorReferencingCurrentColor() ||
- Style()->HasOutlineWithCurrentColor() ||
- Style()->HasBackgroundRelatedColorReferencingCurrentColor() ||
+ 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()) ||
- (IsSVG() && Style()->SvgStyle().IsFillColorCurrentColor()) ||
- (IsSVG() && Style()->SvgStyle().IsStrokeColorCurrentColor()) ||
+ (IsSVG() && StyleRef().SvgStyle().IsFillColorCurrentColor()) ||
+ (IsSVG() && StyleRef().SvgStyle().IsStrokeColorCurrentColor()) ||
IsListMarker())
diff.SetNeedsPaintInvalidationObject();
}
@@ -1949,7 +1954,7 @@ void LayoutObject::MarkContainerChainForOverflowRecalcIfNeeded() {
void LayoutObject::SetNeedsOverflowRecalcAfterStyleChange() {
bool needed_recalc = NeedsOverflowRecalcAfterStyleChange();
SetSelfNeedsOverflowRecalcAfterStyleChange();
- SetMayNeedPaintInvalidation();
+ SetShouldCheckForPaintInvalidation();
if (!needed_recalc)
MarkContainerChainForOverflowRecalcIfNeeded();
}
@@ -2054,7 +2059,7 @@ void LayoutObject::SetStyle(scoped_refptr<ComputedStyle> style) {
if (diff.NeedsPaintInvalidationSubtree() ||
updated_diff.NeedsPaintInvalidationSubtree()) {
- SetShouldDoFullPaintInvalidationIncludingNonCompositingDescendants();
+ SetSubtreeShouldDoFullPaintInvalidation();
} else if (diff.NeedsPaintInvalidationObject() ||
updated_diff.NeedsPaintInvalidationObject()) {
// TODO(wangxianzhu): For now LayoutSVGRoot::localVisualRect() depends on
@@ -2071,16 +2076,17 @@ void LayoutObject::SetStyle(scoped_refptr<ComputedStyle> style) {
InvalidateClipPathCache();
if (diff.NeedsVisualRectUpdate())
- SetMayNeedPaintInvalidation();
+ SetShouldCheckForPaintInvalidation();
// Text nodes share style with their parents but the paint properties don't
// apply to them, hence the !isText() check. If property nodes are added or
// removed as a result of these style changes, PaintPropertyTreeBuilder will
// call SetNeedsRepaint to cause re-generation of PaintChunks.
- if (!IsText() && (diff.TransformChanged() || diff.OpacityChanged() ||
- diff.ZIndexChanged() || diff.FilterChanged() ||
- diff.BackdropFilterChanged() || diff.CssClipChanged() ||
- diff.BlendModeChanged())) {
+ if (!IsText() && !HasLayer() &&
+ (diff.TransformChanged() || diff.OpacityChanged() ||
+ diff.ZIndexChanged() || diff.FilterChanged() ||
+ diff.BackdropFilterChanged() || diff.CssClipChanged() ||
+ diff.BlendModeChanged() || diff.MaskChanged())) {
SetNeedsPaintPropertyUpdate();
}
}
@@ -2314,7 +2320,7 @@ void LayoutObject::PropagateStyleToAnonymousChildren() {
// properties.
for (LayoutObject* child = SlowFirstChild(); child;
child = child->NextSibling()) {
- if (!child->IsAnonymous() || child->Style()->StyleType() != kPseudoIdNone)
+ if (!child->IsAnonymous() || child->StyleRef().StyleType() != kPseudoIdNone)
continue;
if (child->AnonymousHasStylePropagationOverride())
@@ -2322,17 +2328,17 @@ void LayoutObject::PropagateStyleToAnonymousChildren() {
scoped_refptr<ComputedStyle> new_style =
ComputedStyle::CreateAnonymousStyleWithDisplay(
- StyleRef(), child->Style()->Display());
+ StyleRef(), child->StyleRef().Display());
// Preserve the position style of anonymous block continuations as they can
// have relative position when they contain block descendants of relative
// positioned inlines.
if (child->IsInFlowPositioned() && child->IsLayoutBlockFlow() &&
ToLayoutBlockFlow(child)->IsAnonymousBlockContinuation())
- new_style->SetPosition(child->Style()->GetPosition());
+ new_style->SetPosition(child->StyleRef().GetPosition());
if (child->IsLayoutNGListMarker())
- new_style->SetWhiteSpace(child->Style()->WhiteSpace());
+ new_style->SetWhiteSpace(child->StyleRef().WhiteSpace());
UpdateAnonymousChildStyle(child, *new_style);
@@ -2469,7 +2475,7 @@ void LayoutObject::MapLocalToAncestor(const LayoutBoxModelObject* ancestor,
if (IsBox()) {
mode &= ~kApplyContainerFlip;
} else if (container->IsBox()) {
- if (container->Style()->IsFlippedBlocksWritingMode()) {
+ if (container->StyleRef().IsFlippedBlocksWritingMode()) {
IntPoint center_point = RoundedIntPoint(transform_state.MappedPoint());
transform_state.Move(ToLayoutBox(container)->FlipForWritingMode(
LayoutPoint(center_point)) -
@@ -2500,8 +2506,8 @@ void LayoutObject::MapLocalToAncestor(const LayoutBoxModelObject* ancestor,
// them.
bool preserve3d =
mode & kUseTransforms &&
- ((container->Style()->Preserves3D() && !container->IsText()) ||
- (Style()->Preserves3D() && !IsText()));
+ ((container->StyleRef().Preserves3D() && !container->IsText()) ||
+ (StyleRef().Preserves3D() && !IsText()));
if (mode & kUseTransforms && ShouldUseTransformFromContainer(container)) {
TransformationMatrix t;
GetTransformFromContainer(container, container_offset, t);
@@ -2519,13 +2525,13 @@ void LayoutObject::MapLocalToAncestor(const LayoutBoxModelObject* ancestor,
// create containers, so it should be safe to just subtract the delta
// between the ancestor and |o|.
LayoutSize container_offset =
- ancestor->OffsetFromAncestorContainer(container);
+ ancestor->OffsetFromAncestor(container);
transform_state.Move(-container_offset.Width(), -container_offset.Height(),
preserve3d ? TransformState::kAccumulateTransform
: TransformState::kFlattenTransform);
// If the ancestor is fixed, then the rect is already in its coordinates so
// doesn't need viewport-adjusting.
- if (ancestor->Style()->GetPosition() != EPosition::kFixed &&
+ if (ancestor->StyleRef().GetPosition() != EPosition::kFixed &&
container->IsLayoutView() &&
StyleRef().GetPosition() == EPosition::kFixed) {
LayoutSize adjustment = ToLayoutView(container)->OffsetForFixedPosition();
@@ -2560,7 +2566,7 @@ void LayoutObject::MapAncestorToLocal(const LayoutBoxModelObject* ancestor,
if (IsBox()) {
mode &= ~kApplyContainerFlip;
} else if (container->IsBox()) {
- apply_container_flip = container->Style()->IsFlippedBlocksWritingMode();
+ apply_container_flip = container->StyleRef().IsFlippedBlocksWritingMode();
mode &= ~kApplyContainerFlip;
}
}
@@ -2571,7 +2577,7 @@ void LayoutObject::MapAncestorToLocal(const LayoutBoxModelObject* ancestor,
LayoutSize container_offset = OffsetFromContainer(container);
bool preserve3d =
mode & kUseTransforms &&
- (container->Style()->Preserves3D() || Style()->Preserves3D());
+ (container->StyleRef().Preserves3D() || StyleRef().Preserves3D());
if (mode & kUseTransforms && ShouldUseTransformFromContainer(container)) {
TransformationMatrix t;
GetTransformFromContainer(container, container_offset, t);
@@ -2601,11 +2607,11 @@ void LayoutObject::MapAncestorToLocal(const LayoutBoxModelObject* ancestor,
}
if (skip_info.AncestorSkipped()) {
- container_offset = ancestor->OffsetFromAncestorContainer(container);
+ container_offset = ancestor->OffsetFromAncestor(container);
transform_state.Move(-container_offset.Width(), -container_offset.Height());
// If the ancestor is fixed, then the rect is already in its coordinates so
// doesn't need viewport-adjusting.
- if (ancestor->Style()->GetPosition() != EPosition::kFixed &&
+ if (ancestor->StyleRef().GetPosition() != EPosition::kFixed &&
container->IsLayoutView() &&
StyleRef().GetPosition() == EPosition::kFixed) {
LayoutSize adjustment = ToLayoutView(container)->OffsetForFixedPosition();
@@ -2620,7 +2626,7 @@ bool LayoutObject::ShouldUseTransformFromContainer(
// or perspective. We just care about transform, so check the layer's
// transform directly.
return (HasLayer() && ToLayoutBoxModelObject(this)->Layer()->Transform()) ||
- (container_object && container_object->Style()->HasPerspective());
+ (container_object && container_object->StyleRef().HasPerspective());
}
void LayoutObject::GetTransformFromContainer(
@@ -2637,7 +2643,7 @@ void LayoutObject::GetTransformFromContainer(
offset_in_container.Height().ToFloat());
if (container_object && container_object->HasLayer() &&
- container_object->Style()->HasPerspective()) {
+ container_object->StyleRef().HasPerspective()) {
// Perspective on the container affects us, so we have to factor it in here.
DCHECK(container_object->HasLayer());
FloatPoint perspective_origin =
@@ -2645,7 +2651,7 @@ void LayoutObject::GetTransformFromContainer(
TransformationMatrix perspective_matrix;
perspective_matrix.ApplyPerspective(
- container_object->Style()->Perspective());
+ container_object->StyleRef().Perspective());
perspective_matrix.ApplyTransformOrigin(perspective_origin.X(),
perspective_origin.Y(), 0);
@@ -2756,7 +2762,7 @@ LayoutSize LayoutObject::OffsetFromScrollableContainer(
box->OriginAdjustmentForScrollbars());
}
-LayoutSize LayoutObject::OffsetFromAncestorContainer(
+LayoutSize LayoutObject::OffsetFromAncestor(
const LayoutObject* ancestor_container) const {
if (ancestor_container == this)
return LayoutSize();
@@ -2764,10 +2770,12 @@ LayoutSize LayoutObject::OffsetFromAncestorContainer(
LayoutSize offset;
LayoutPoint reference_point;
const LayoutObject* curr_container = this;
+ AncestorSkipInfo skip_info(ancestor_container);
do {
- const LayoutObject* next_container = curr_container->Container();
+ const LayoutObject* next_container = curr_container->Container(&skip_info);
+
// This means we reached the top without finding container.
- DCHECK(next_container);
+ CHECK(next_container);
if (!next_container)
break;
DCHECK(!curr_container->HasTransformRelatedProperty());
@@ -2776,7 +2784,12 @@ LayoutSize LayoutObject::OffsetFromAncestorContainer(
offset += current_offset;
reference_point.Move(current_offset);
curr_container = next_container;
- } while (curr_container != ancestor_container);
+ } while (curr_container != ancestor_container &&
+ !skip_info.AncestorSkipped());
+ if (skip_info.AncestorSkipped()) {
+ DCHECK(curr_container);
+ offset -= ancestor_container->OffsetFromAncestor(curr_container);
+ }
return offset;
}
@@ -2805,7 +2818,7 @@ void LayoutObject::ComputeLayerHitTestRects(
if (container) {
current_layer = container->EnclosingLayer();
if (current_layer->GetLayoutObject() != container) {
- layer_offset.Move(container->OffsetFromAncestorContainer(
+ layer_offset.Move(container->OffsetFromAncestor(
&current_layer->GetLayoutObject()));
// If the layer itself is scrolled, we have to undo the subtraction of
// its scroll offset since we want the offset relative to the scrolling
@@ -2858,7 +2871,7 @@ void LayoutObject::AddLayerHitTestRects(
iter_value = &iter->value;
}
TouchAction whitelisted_touch_action =
- Style()->GetEffectiveTouchAction() & supported_fast_actions;
+ StyleRef().GetEffectiveTouchAction() & supported_fast_actions;
for (size_t i = 0; i < own_rects.size(); i++) {
// If we have a different touch action than the container the rect needs to
// be reported even if it is contained.
@@ -2933,7 +2946,7 @@ RespectImageOrientationEnum LayoutObject::ShouldRespectImageOrientation(
return kRespectImageOrientation;
if (layout_object->Style() &&
- layout_object->Style()->RespectImageOrientation() ==
+ layout_object->StyleRef().RespectImageOrientation() ==
kRespectImageOrientation)
return kRespectImageOrientation;
@@ -2981,12 +2994,6 @@ inline LayoutObject* LayoutObject::ParentCrossingFrames() const {
return Parent();
}
-bool LayoutObject::IsSelectionBorder() const {
- SelectionState st = GetSelectionState();
- return st == SelectionState::kStart || st == SelectionState::kEnd ||
- st == SelectionState::kStartAndEnd;
-}
-
inline void LayoutObject::ClearLayoutRootIfNeeded() const {
if (LocalFrameView* view = GetFrameView()) {
if (!DocumentBeingDestroyed())
@@ -3098,8 +3105,8 @@ void LayoutObject::InsertedIntoTree() {
// If |this| is visible but this object was not, tell the layer it has some
// visible content that needs to be drawn and layer visibility optimization
// can't be used
- if (Parent()->Style()->Visibility() != EVisibility::kVisible &&
- Style()->Visibility() == EVisibility::kVisible && !HasLayer()) {
+ if (Parent()->StyleRef().Visibility() != EVisibility::kVisible &&
+ StyleRef().Visibility() == EVisibility::kVisible && !HasLayer()) {
if (!layer)
layer = Parent()->EnclosingLayer();
if (layer)
@@ -3149,8 +3156,8 @@ void LayoutObject::WillBeRemovedFromTree() {
// If we remove a visible child from an invisible parent, we don't know the
// layer visibility any more.
PaintLayer* layer = nullptr;
- if (Parent()->Style()->Visibility() != EVisibility::kVisible &&
- Style()->Visibility() == EVisibility::kVisible && !HasLayer()) {
+ if (Parent()->StyleRef().Visibility() != EVisibility::kVisible &&
+ StyleRef().Visibility() == EVisibility::kVisible && !HasLayer()) {
layer = Parent()->EnclosingLayer();
if (layer)
layer->DirtyVisibleContentStatus();
@@ -3519,10 +3526,10 @@ scoped_refptr<ComputedStyle> LayoutObject::GetUncachedPseudoStyle(
void LayoutObject::AddAnnotatedRegions(Vector<AnnotatedRegionValue>& regions) {
// Convert the style regions to absolute coordinates.
- if (Style()->Visibility() != EVisibility::kVisible || !IsBox())
+ if (StyleRef().Visibility() != EVisibility::kVisible || !IsBox())
return;
- if (Style()->DraggableRegionMode() == EDraggableRegionMode::kNone)
+ if (StyleRef().DraggableRegionMode() == EDraggableRegionMode::kNone)
return;
LayoutBox* box = ToLayoutBox(this);
@@ -3531,7 +3538,7 @@ void LayoutObject::AddAnnotatedRegions(Vector<AnnotatedRegionValue>& regions) {
AnnotatedRegionValue region;
region.draggable =
- Style()->DraggableRegionMode() == EDraggableRegionMode::kDrag;
+ StyleRef().DraggableRegionMode() == EDraggableRegionMode::kDrag;
region.bounds = LayoutRect(abs_bounds);
regions.push_back(region);
}
@@ -3539,7 +3546,7 @@ void LayoutObject::AddAnnotatedRegions(Vector<AnnotatedRegionValue>& regions) {
bool LayoutObject::WillRenderImage() {
// Without visibility we won't render (and therefore don't care about
// animation).
- if (Style()->Visibility() != EVisibility::kVisible)
+ if (StyleRef().Visibility() != EVisibility::kVisible)
return false;
// We will not render a new image when PausableObjects is paused
@@ -3602,7 +3609,7 @@ Element* LayoutObject::OffsetParent(const Element* base) const {
if (IsFixedPositioned())
return nullptr;
- float effective_zoom = Style()->EffectiveZoom();
+ float effective_zoom = StyleRef().EffectiveZoom();
Node* node = nullptr;
for (LayoutObject* ancestor = Parent(); ancestor;
ancestor = ancestor->Parent()) {
@@ -3637,7 +3644,7 @@ Element* LayoutObject::OffsetParent(const Element* base) const {
break;
// Webkit specific extension where offsetParent stops at zoom level changes.
- if (effective_zoom != ancestor->Style()->EffectiveZoom())
+ if (effective_zoom != ancestor->StyleRef().EffectiveZoom())
break;
}
@@ -3776,30 +3783,15 @@ bool LayoutObject::IsRelayoutBoundaryForInspector() const {
return ObjectIsRelayoutBoundary(this);
}
-static PaintInvalidationReason DocumentLifecycleBasedPaintInvalidationReason(
- const DocumentLifecycle& document_lifecycle) {
- switch (document_lifecycle.GetState()) {
- case DocumentLifecycle::kInStyleRecalc:
- return PaintInvalidationReason::kStyle;
- case DocumentLifecycle::kInPreLayout:
- case DocumentLifecycle::kInPerformLayout:
- case DocumentLifecycle::kAfterPerformLayout:
- return PaintInvalidationReason::kGeometry;
- case DocumentLifecycle::kInCompositingUpdate:
- return PaintInvalidationReason::kCompositing;
- default:
- return PaintInvalidationReason::kFull;
- }
-}
-
inline void LayoutObject::MarkAncestorsForPaintInvalidation() {
for (LayoutObject* parent = ParentCrossingFrames();
parent && !parent->ShouldCheckForPaintInvalidation();
parent = parent->ParentCrossingFrames())
- parent->bitfields_.SetMayNeedPaintInvalidation(true);
+ parent->bitfields_.SetShouldCheckForPaintInvalidation(true);
}
inline void LayoutObject::SetNeedsPaintOffsetAndVisualRectUpdate() {
+ DCHECK(ShouldCheckForPaintInvalidation());
for (auto* object = this;
object && !object->NeedsPaintOffsetAndVisualRectUpdate();
object = object->ParentCrossingFrames()) {
@@ -3811,66 +3803,93 @@ void LayoutObject::SetShouldInvalidateSelection() {
if (!CanUpdateSelectionOnRootLineBoxes())
return;
bitfields_.SetShouldInvalidateSelection(true);
- SetMayNeedPaintInvalidation();
- GetFrameView()->ScheduleVisualUpdateForPaintInvalidationIfNeeded();
+ SetShouldCheckForPaintInvalidation();
}
void LayoutObject::SetShouldDoFullPaintInvalidation(
PaintInvalidationReason reason) {
- SetNeedsPaintOffsetAndVisualRectUpdate();
SetShouldDoFullPaintInvalidationWithoutGeometryChange(reason);
+ SetNeedsPaintOffsetAndVisualRectUpdate();
+}
+
+static PaintInvalidationReason DocumentLifecycleBasedPaintInvalidationReason(
+ const DocumentLifecycle& document_lifecycle) {
+ switch (document_lifecycle.GetState()) {
+ case DocumentLifecycle::kInStyleRecalc:
+ return PaintInvalidationReason::kStyle;
+ case DocumentLifecycle::kInPreLayout:
+ case DocumentLifecycle::kInPerformLayout:
+ case DocumentLifecycle::kAfterPerformLayout:
+ return PaintInvalidationReason::kGeometry;
+ case DocumentLifecycle::kInCompositingUpdate:
+ return PaintInvalidationReason::kCompositing;
+ default:
+ return PaintInvalidationReason::kFull;
+ }
}
void LayoutObject::SetShouldDoFullPaintInvalidationWithoutGeometryChange(
PaintInvalidationReason reason) {
// Only full invalidation reasons are allowed.
DCHECK(IsFullPaintInvalidationReason(reason));
+ // This is before the early return to ensure visual update is always scheduled
+ // in case that this is called not during a document lifecycle update.
+ GetFrameView()->ScheduleVisualUpdateForPaintInvalidationIfNeeded();
- bool is_upgrading_delayed_full_to_full =
- bitfields_.FullPaintInvalidationReason() ==
- PaintInvalidationReason::kDelayedFull &&
- reason != PaintInvalidationReason::kDelayedFull;
-
- if (bitfields_.FullPaintInvalidationReason() ==
- PaintInvalidationReason::kNone ||
- is_upgrading_delayed_full_to_full) {
- if (reason == PaintInvalidationReason::kFull) {
- reason = DocumentLifecycleBasedPaintInvalidationReason(
- GetDocument().Lifecycle());
- }
- bitfields_.SetFullPaintInvalidationReason(reason);
- if (!is_upgrading_delayed_full_to_full)
- MarkAncestorsForPaintInvalidation();
+ if (ShouldDoFullPaintInvalidation())
+ return;
+ SetShouldCheckForPaintInvalidationWithoutGeometryChange();
+ if (reason == PaintInvalidationReason::kFull) {
+ reason = DocumentLifecycleBasedPaintInvalidationReason(
+ GetDocument().Lifecycle());
}
-
- GetFrameView()->ScheduleVisualUpdateForPaintInvalidationIfNeeded();
+ full_paint_invalidation_reason_ = reason;
+ bitfields_.SetShouldDelayFullPaintInvalidation(false);
}
-void LayoutObject::SetMayNeedPaintInvalidation() {
+void LayoutObject::SetShouldCheckForPaintInvalidation() {
+ SetShouldCheckForPaintInvalidationWithoutGeometryChange();
SetNeedsPaintOffsetAndVisualRectUpdate();
- SetMayNeedPaintInvalidationWithoutGeometryChange();
}
-void LayoutObject::SetMayNeedPaintInvalidationWithoutGeometryChange() {
- if (MayNeedPaintInvalidation())
+void LayoutObject::SetShouldCheckForPaintInvalidationWithoutGeometryChange() {
+ if (ShouldCheckForPaintInvalidation())
return;
- bitfields_.SetMayNeedPaintInvalidation(true);
- MarkAncestorsForPaintInvalidation();
GetFrameView()->ScheduleVisualUpdateForPaintInvalidationIfNeeded();
+ bitfields_.SetShouldCheckForPaintInvalidation(true);
+ MarkAncestorsForPaintInvalidation();
}
-void LayoutObject::SetMayNeedPaintInvalidationSubtree() {
- if (MayNeedPaintInvalidationSubtree())
+void LayoutObject::SetSubtreeShouldCheckForPaintInvalidation() {
+ if (SubtreeShouldCheckForPaintInvalidation()) {
+ DCHECK(ShouldCheckForPaintInvalidation());
return;
- bitfields_.SetMayNeedPaintInvalidationSubtree(true);
- SetMayNeedPaintInvalidation();
+ }
+ SetShouldCheckForPaintInvalidation();
+ bitfields_.SetSubtreeShouldCheckForPaintInvalidation(true);
}
void LayoutObject::SetMayNeedPaintInvalidationAnimatedBackgroundImage() {
if (MayNeedPaintInvalidationAnimatedBackgroundImage())
return;
bitfields_.SetMayNeedPaintInvalidationAnimatedBackgroundImage(true);
- SetMayNeedPaintInvalidationWithoutGeometryChange();
+ SetShouldCheckForPaintInvalidationWithoutGeometryChange();
+}
+
+void LayoutObject::SetShouldDelayFullPaintInvalidation() {
+ // Should have already set a full paint invalidation reason.
+ DCHECK(IsFullPaintInvalidationReason(full_paint_invalidation_reason_));
+
+ bitfields_.SetShouldDelayFullPaintInvalidation(true);
+ if (!ShouldCheckForPaintInvalidation()) {
+ // This will also schedule a visual update.
+ SetShouldCheckForPaintInvalidationWithoutGeometryChange();
+ } else {
+ // Schedule visual update for the next document cycle in which we will
+ // check if the delayed invalidation should be promoted to a real
+ // invalidation.
+ GetFrameView()->ScheduleVisualUpdateForPaintInvalidationIfNeeded();
+ }
}
void LayoutObject::ClearPaintInvalidationFlags() {
@@ -3880,25 +3899,37 @@ void LayoutObject::ClearPaintInvalidationFlags() {
DCHECK(!ShouldCheckForPaintInvalidation() || PaintInvalidationStateIsDirty());
#endif
fragment_.SetPartialInvalidationLocalRect(LayoutRect());
- ClearShouldDoFullPaintInvalidation();
- bitfields_.SetMayNeedPaintInvalidation(false);
- bitfields_.SetMayNeedPaintInvalidationSubtree(false);
+ if (!ShouldDelayFullPaintInvalidation())
+ full_paint_invalidation_reason_ = PaintInvalidationReason::kNone;
+ bitfields_.SetShouldCheckForPaintInvalidation(false);
+ bitfields_.SetSubtreeShouldCheckForPaintInvalidation(false);
+ bitfields_.SetSubtreeShouldDoFullPaintInvalidation(false);
bitfields_.SetMayNeedPaintInvalidationAnimatedBackgroundImage(false);
bitfields_.SetNeedsPaintOffsetAndVisualRectUpdate(false);
bitfields_.SetShouldInvalidateSelection(false);
bitfields_.SetBackgroundChangedSinceLastPaintInvalidation(false);
}
+#if DCHECK_IS_ON()
+bool LayoutObject::PaintInvalidationStateIsDirty() const {
+ return BackgroundChangedSinceLastPaintInvalidation() ||
+ ShouldCheckForPaintInvalidation() || ShouldInvalidateSelection() ||
+ NeedsPaintOffsetAndVisualRectUpdate() ||
+ ShouldDoFullPaintInvalidation() ||
+ SubtreeShouldDoFullPaintInvalidation() ||
+ MayNeedPaintInvalidationAnimatedBackgroundImage() ||
+ !fragment_.PartialInvalidationLocalRect().IsEmpty();
+}
+#endif
+
bool LayoutObject::IsAllowedToModifyLayoutTreeStructure(Document& document) {
return document.Lifecycle().StateAllowsLayoutTreeMutations();
}
-void LayoutObject::
- SetShouldDoFullPaintInvalidationIncludingNonCompositingDescendants() {
- // Clear first because PaintInvalidationSubtree overrides other full paint
- // invalidation reasons.
- ClearShouldDoFullPaintInvalidation();
- SetShouldDoFullPaintInvalidation(PaintInvalidationReason::kSubtree);
+void LayoutObject::SetSubtreeShouldDoFullPaintInvalidation(
+ PaintInvalidationReason reason) {
+ SetShouldDoFullPaintInvalidation(reason);
+ bitfields_.SetSubtreeShouldDoFullPaintInvalidation(true);
}
void LayoutObject::SetIsBackgroundAttachmentFixedObject(
@@ -3967,7 +3998,7 @@ void LayoutObject::MarkEffectiveWhitelistedTouchActionChanged() {
void LayoutObject::InvalidateIfControlStateChanged(ControlState control_state) {
if (LayoutTheme::GetTheme().ControlStateChanged(GetNode(), StyleRef(),
control_state)) {
- SetShouldDoFullPaintInvalidationIncludingNonCompositingDescendants();
+ SetSubtreeShouldDoFullPaintInvalidation();
}
}
@@ -4026,7 +4057,7 @@ const LayoutObject* AssociatedLayoutObjectOf(const Node& node,
}
bool LayoutObject::CanBeSelectionLeaf() const {
- if (SlowFirstChild() || Style()->Visibility() != EVisibility::kVisible)
+ if (SlowFirstChild() || StyleRef().Visibility() != EVisibility::kVisible)
return false;
return CanBeSelectionLeafInternal();
}
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 8c7bd54890c..658b8a4e598 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_object.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_object.h
@@ -72,8 +72,8 @@ class LayoutGeometryMap;
class LayoutMultiColumnSpannerPlaceholder;
class LayoutView;
class LocalFrameView;
+class NGPaintFragment;
class NGPhysicalBoxFragment;
-class ObjectPaintProperties;
class PaintLayer;
class PseudoStyleRequest;
@@ -235,13 +235,17 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
// DisplayItemClient methods.
+ protected:
+ void EnsureIdForTesting() { fragment_.EnsureIdForTesting(); };
+
// Do not call VisualRect directly outside of the DisplayItemClient
// interface, use a per-fragment one on FragmentData instead.
private:
- // Hide DisplayItemClient methods whose names are too generic for
- // LayoutObject. Use LayoutObject methods instead, or explicitly cast.
+ // Hide DisplayItemClient's methods whose names are too generic for
+ // LayoutObjects. Should use LayoutObject's methods instead.
using DisplayItemClient::Invalidate;
using DisplayItemClient::IsValid;
+ using DisplayItemClient::GetPaintInvalidationReason;
LayoutRect VisualRect() const final;
@@ -620,6 +624,7 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
virtual bool IsLayoutFlowThread() const { return false; }
virtual bool IsLayoutInline() const { return false; }
virtual bool IsLayoutEmbeddedContent() const { return false; }
+ virtual bool IsLayoutNGObject() const { return false; }
bool IsDocumentElement() const {
return GetDocument().documentElement() == node_;
@@ -726,9 +731,16 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
virtual void SetNeedsTransformUpdate() {}
virtual void SetNeedsBoundariesUpdate();
+ // Per the spec, mix-blend-mode applies to all non-SVG elements, and SVG
+ // elements that are container elements, graphics elements or graphics
+ // referencing elements.
+ // https://www.w3.org/TR/compositing-1/#propdef-mix-blend-mode
bool IsBlendingAllowed() const {
- return !IsSVG() || (IsSVGContainer() && !IsSVGHiddenContainer()) ||
- IsSVGShape() || IsSVGImage() || IsSVGText();
+ return !IsSVG() || IsSVGShape() || IsSVGImage() || IsSVGText() ||
+ IsSVGInline() || IsSVGRoot() || IsSVGForeignObject() ||
+ // TODO(pdr): According to the current spec, blending should apply to
+ // hidden containers (e.g. pattern).
+ (IsSVGContainer() && !IsSVGHiddenContainer());
}
virtual bool HasNonIsolatedBlendingDescendants() const {
// This is only implemented for layout objects that containt SVG flow.
@@ -835,6 +847,9 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
bool IsText() const { return bitfields_.IsText(); }
bool IsBox() const { return bitfields_.IsBox(); }
bool IsInline() const { return bitfields_.IsInline(); } // inline object
+ bool IsInLayoutNGInlineFormattingContext() const {
+ return bitfields_.IsInLayoutNGInlineFormattingContext();
+ }
bool IsAtomicInlineLevel() const { return bitfields_.IsAtomicInlineLevel(); }
bool IsHorizontalWritingMode() const {
return bitfields_.HorizontalWritingMode();
@@ -891,10 +906,8 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
return bitfields_.ChildNeedsOverflowRecalcAfterStyleChange();
}
- bool IsSelectionBorder() const;
-
// CSS clip only applies when position is absolute or fixed. Prefer this check
- // over !Style()->HasAutoClip().
+ // over !StyleRef().HasAutoClip().
bool HasClip() const {
return IsOutOfFlowPositioned() && !StyleRef().HasAutoClip();
}
@@ -923,6 +936,16 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
bool HasShapeOutside() const { return StyleRef().ShapeOutside(); }
+ // Return true if the given object is the effective root scroller in its
+ // Document. See |effective root scroller| in page/scrolling/README.md.
+ // Note: a root scroller always establishes a PaintLayer.
+ // This bit is updated in
+ // RootScrollerController::RecomputeEffectiveRootScroller in the LayoutClean
+ // document lifecycle phase.
+ bool IsEffectiveRootScroller() const {
+ return bitfields_.IsEffectiveRootScroller();
+ }
+
// The pseudo element style can be cached or uncached. Use the cached method
// if the pseudo element doesn't respect any pseudo classes (and therefore
// has no concept of changing state).
@@ -1107,6 +1130,10 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
void SetFloating(bool is_floating) { bitfields_.SetFloating(is_floating); }
void SetInline(bool is_inline) { bitfields_.SetIsInline(is_inline); }
+ void SetIsInLayoutNGInlineFormattingContext(bool);
+ virtual NGPaintFragment* FirstInlineFragment() const { return nullptr; }
+ virtual void SetFirstInlineFragment(NGPaintFragment*) {}
+
void SetHasBoxDecorationBackground(bool);
enum BackgroundObscurationState {
@@ -1141,6 +1168,9 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
void SetCanContainFixedPositionObjects(bool can_contain_fixed_position) {
bitfields_.SetCanContainFixedPositionObjects(can_contain_fixed_position);
}
+ void SetIsEffectiveRootScroller(bool is_effective_root_scroller) {
+ bitfields_.SetIsEffectiveRootScroller(is_effective_root_scroller);
+ }
virtual void Paint(const PaintInfo&) const;
@@ -1360,13 +1390,13 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
// and multicol).
LayoutSize OffsetFromContainer(const LayoutObject*,
bool ignore_scroll_offset = false) const;
- // Return the offset from an object up the container() chain. Asserts that
- // none of the intermediate objects have transforms.
- LayoutSize OffsetFromAncestorContainer(const LayoutObject*) const;
+ // Return the offset from an object from the ancestor. The ancestor need
+ // not be on the containing block chain of |this|.
+ LayoutSize OffsetFromAncestor(const LayoutObject*) const;
virtual void AbsoluteRects(Vector<IntRect>&, const LayoutPoint&) const {}
- FloatRect AbsoluteBoundingBoxFloatRect() const;
+ FloatRect AbsoluteBoundingBoxFloatRect(MapCoordinatesFlags = 0) const;
// This returns an IntRect enclosing this object. If this object has an
// integral size and the position has fractional values, the resultant
// IntRect can be larger than the integral size.
@@ -1460,17 +1490,15 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
// a small region of a canvas changes.
void InvalidatePaintRectangle(const LayoutRect&);
- void SetShouldDoFullPaintInvalidationIncludingNonCompositingDescendants();
-
// Returns the rect that should have paint invalidated whenever this object
// changes. The rect is in the view's coordinate space. This method deals with
// outlines and overflow.
virtual LayoutRect AbsoluteVisualRect() const;
- // Returns the rect that should have paint invalidated whenever this object
+ // Returns the rect that should have raster invalidated whenever this object
// changes. The rect is in the object's local coordinate space. This is for
// non-SVG objects and LayoutSVGRoot only. SVG objects (except LayoutSVGRoot)
- // should use visualRectInLocalSVGCoordinates() and map with SVG transforms
+ // should use VisualRectInLocalSVGCoordinates() and map with SVG transforms
// instead.
LayoutRect LocalVisualRect() const {
if (StyleRef().Visibility() != EVisibility::kVisible &&
@@ -1728,32 +1756,34 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
virtual void ClearPreviousVisualRects();
PaintInvalidationReason FullPaintInvalidationReason() const {
- return bitfields_.FullPaintInvalidationReason();
+ return full_paint_invalidation_reason_;
}
bool ShouldDoFullPaintInvalidation() const {
- return bitfields_.FullPaintInvalidationReason() !=
- PaintInvalidationReason::kNone;
+ if (!ShouldDelayFullPaintInvalidation() &&
+ full_paint_invalidation_reason_ != PaintInvalidationReason::kNone) {
+ DCHECK(IsFullPaintInvalidationReason(full_paint_invalidation_reason_));
+ DCHECK(ShouldCheckForPaintInvalidation());
+ return true;
+ }
+ return false;
}
void SetShouldDoFullPaintInvalidation(
PaintInvalidationReason = PaintInvalidationReason::kFull);
void SetShouldDoFullPaintInvalidationWithoutGeometryChange(
PaintInvalidationReason = PaintInvalidationReason::kFull);
- void ClearShouldDoFullPaintInvalidation() {
- bitfields_.SetFullPaintInvalidationReason(PaintInvalidationReason::kNone);
- }
void ClearPaintInvalidationFlags();
- bool MayNeedPaintInvalidation() const {
- return bitfields_.MayNeedPaintInvalidation();
+ bool ShouldCheckForPaintInvalidation() const {
+ return bitfields_.ShouldCheckForPaintInvalidation();
}
- void SetMayNeedPaintInvalidation();
- void SetMayNeedPaintInvalidationWithoutGeometryChange();
+ void SetShouldCheckForPaintInvalidation();
+ void SetShouldCheckForPaintInvalidationWithoutGeometryChange();
- bool MayNeedPaintInvalidationSubtree() const {
- return bitfields_.MayNeedPaintInvalidationSubtree();
+ bool SubtreeShouldCheckForPaintInvalidation() const {
+ return bitfields_.SubtreeShouldCheckForPaintInvalidation();
}
- void SetMayNeedPaintInvalidationSubtree();
+ void SetSubtreeShouldCheckForPaintInvalidation();
bool NeedsPaintOffsetAndVisualRectUpdate() const {
return bitfields_.NeedsPaintOffsetAndVisualRectUpdate();
@@ -1764,20 +1794,33 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
}
void SetMayNeedPaintInvalidationAnimatedBackgroundImage();
+ void SetSubtreeShouldDoFullPaintInvalidation(
+ PaintInvalidationReason reason = PaintInvalidationReason::kSubtree);
+ bool SubtreeShouldDoFullPaintInvalidation() const {
+ DCHECK(!bitfields_.SubtreeShouldDoFullPaintInvalidation() ||
+ ShouldDoFullPaintInvalidation());
+ return bitfields_.SubtreeShouldDoFullPaintInvalidation();
+ }
+
+ // If true, it means that invalidation and repainting of the object can be
+ // delayed until a future frame. This can be the case for an object whose
+ // content is not visible to the user.
+ bool ShouldDelayFullPaintInvalidation() const {
+ return bitfields_.ShouldDelayFullPaintInvalidation();
+ }
+ void SetShouldDelayFullPaintInvalidation();
+
bool ShouldInvalidateSelection() const {
return bitfields_.ShouldInvalidateSelection();
}
void SetShouldInvalidateSelection();
- bool ShouldCheckForPaintInvalidation() const {
- return MayNeedPaintInvalidation() || ShouldDoFullPaintInvalidation();
- }
-
virtual LayoutRect ViewRect() const;
- // New version to replace the above old version.
- virtual PaintInvalidationReason InvalidatePaint(
- const PaintInvalidatorContext&) const;
+ // Called by PaintInvalidator during PrePaint. Checks paint invalidation flags
+ // and other changes that will cause different painting, and invalidate
+ // display item clients for painting if needed.
+ virtual void InvalidatePaint(const PaintInvalidatorContext&) const;
// When this object is invalidated for paint, this method is called to
// invalidate any DisplayItemClients owned by this object, including the
@@ -1860,8 +1903,8 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
layout_object_.bitfields_
.SetDescendantEffectiveWhitelistedTouchActionChanged(false);
}
- void SetMayNeedPaintInvalidation() {
- layout_object_.SetMayNeedPaintInvalidation();
+ void SetShouldCheckForPaintInvalidation() {
+ layout_object_.SetShouldCheckForPaintInvalidation();
}
void SetShouldDoFullPaintInvalidation(PaintInvalidationReason reason) {
layout_object_.SetShouldDoFullPaintInvalidation(reason);
@@ -1874,6 +1917,9 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
void SetBackgroundChangedSinceLastPaintInvalidation() {
layout_object_.SetBackgroundChangedSinceLastPaintInvalidation();
}
+ void SetShouldDelayFullPaintInvalidation() {
+ layout_object_.SetShouldDelayFullPaintInvalidation();
+ }
void EnsureIsReadyForPaintInvalidation() {
layout_object_.EnsureIsReadyForPaintInvalidation();
}
@@ -2133,6 +2179,8 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
// changes at all).
virtual bool AnonymousHasStylePropagationOverride() { return false; }
+ virtual void InLayoutNGInlineFormattingContextWillChange(bool) {}
+
// A fast path for MapToVisualRectInAncestorSpace for when GeometryMapper
// can be used. |intersects| is set to whether the input rect intersected
// (see documentation of return value of MapToVisualRectInAncestorSpace).
@@ -2191,12 +2239,7 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
const LayoutPoint& layer_offset) const {}
#if DCHECK_IS_ON()
- virtual bool PaintInvalidationStateIsDirty() const {
- return BackgroundChangedSinceLastPaintInvalidation() ||
- ShouldCheckForPaintInvalidation() || ShouldInvalidateSelection() ||
- NeedsPaintOffsetAndVisualRectUpdate() ||
- !fragment_.PartialInvalidationLocalRect().IsEmpty();
- }
+ virtual bool PaintInvalidationStateIsDirty() const;
#endif
// Called before paint invalidation.
@@ -2311,6 +2354,14 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
void ApplyPseudoStyleChanges(const ComputedStyle& old_style);
void ApplyFirstLineChanges(const ComputedStyle& old_style);
+ // This is set by Set[Subtree]ShouldDoFullPaintInvalidation, and cleared
+ // during PrePaint in this object's InvalidatePaint(). It's different from
+ // DisplayItemClient::GetPaintInvalidationReason() which is set during
+ // PrePaint and cleared in PaintController::FinishCycle().
+ // It's defined as the first field so that it can use the memory gap between
+ // DisplayItemClient and LayoutObject's other fields.
+ PaintInvalidationReason full_paint_invalidation_reason_;
+
scoped_refptr<ComputedStyle> style_;
// Oilpan: This untraced pointer to the owning Node is considered safe.
@@ -2370,16 +2421,19 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
child_needs_overflow_recalc_after_style_change_(false),
preferred_logical_widths_dirty_(false),
needs_collect_inlines_(false),
- may_need_paint_invalidation_(false),
- may_need_paint_invalidation_subtree_(false),
+ should_check_for_paint_invalidation_(true),
+ subtree_should_check_for_paint_invalidation_(false),
+ should_delay_full_paint_invalidation_(false),
+ subtree_should_do_full_paint_invalidation_(false),
may_need_paint_invalidation_animated_background_image_(false),
- needs_paint_offset_and_visual_rect_update_(false),
+ needs_paint_offset_and_visual_rect_update_(true),
should_invalidate_selection_(false),
floating_(false),
is_anonymous_(!node),
is_text_(false),
is_box_(false),
is_inline_(true),
+ is_in_layout_ng_inline_formatting_context_(false),
is_atomic_inline_level_(false),
horizontal_writing_mode_(true),
has_layer_(false),
@@ -2413,11 +2467,10 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
inside_blocking_touch_event_handler_(false),
effective_whitelisted_touch_action_changed_(true),
descendant_effective_whitelisted_touch_action_changed_(false),
+ is_effective_root_scroller_(false),
positioned_state_(kIsStaticallyPositioned),
selection_state_(static_cast<unsigned>(SelectionState::kNone)),
- background_obscuration_state_(kBackgroundObscurationStatusInvalid),
- full_paint_invalidation_reason_(
- static_cast<unsigned>(PaintInvalidationReason::kNone)) {}
+ background_obscuration_state_(kBackgroundObscurationStatusInvalid) {}
// Self needs layout means that this layout object is marked for a full
// layout. This is the default layout but it is expensive as it recomputes
@@ -2481,10 +2534,14 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
// Also maybe set to inline boxes to optimize the propagation.
ADD_BOOLEAN_BITFIELD(needs_collect_inlines_, NeedsCollectInlines);
- ADD_BOOLEAN_BITFIELD(may_need_paint_invalidation_,
- MayNeedPaintInvalidation);
- ADD_BOOLEAN_BITFIELD(may_need_paint_invalidation_subtree_,
- MayNeedPaintInvalidationSubtree);
+ ADD_BOOLEAN_BITFIELD(should_check_for_paint_invalidation_,
+ ShouldCheckForPaintInvalidation);
+ ADD_BOOLEAN_BITFIELD(subtree_should_check_for_paint_invalidation_,
+ SubtreeShouldCheckForPaintInvalidation);
+ ADD_BOOLEAN_BITFIELD(should_delay_full_paint_invalidation_,
+ ShouldDelayFullPaintInvalidation);
+ ADD_BOOLEAN_BITFIELD(subtree_should_do_full_paint_invalidation_,
+ SubtreeShouldDoFullPaintInvalidation);
ADD_BOOLEAN_BITFIELD(may_need_paint_invalidation_animated_background_image_,
MayNeedPaintInvalidationAnimatedBackgroundImage);
ADD_BOOLEAN_BITFIELD(needs_paint_offset_and_visual_rect_update_,
@@ -2506,6 +2563,12 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
// siblings (think of paragraphs).
ADD_BOOLEAN_BITFIELD(is_inline_, IsInline);
+ // This boolean is set when this LayoutObject is in LayoutNG inline
+ // formatting context. Note, this LayoutObject itself may be laid out by
+ // legacy.
+ ADD_BOOLEAN_BITFIELD(is_in_layout_ng_inline_formatting_context_,
+ IsInLayoutNGInlineFormattingContext);
+
// This boolean is set if the element is an atomic inline-level box.
//
// In CSS, atomic inline-level boxes are laid out on a line but they
@@ -2637,10 +2700,7 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
ADD_BOOLEAN_BITFIELD(descendant_effective_whitelisted_touch_action_changed_,
DescendantEffectiveWhitelistedTouchActionChanged);
- protected:
- // Use protected to avoid warning about unused variable.
- // Increment this to 63 if a new bit is added.
- // unsigned unused_bits_ : 0;
+ ADD_BOOLEAN_BITFIELD(is_effective_root_scroller_, IsEffectiveRootScroller);
private:
// This is the cached 'position' value of this object
@@ -2649,12 +2709,7 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
unsigned selection_state_ : 3; // SelectionState
// Mutable for getter which lazily update this field.
mutable unsigned
- background_obscuration_state_ : 2; // BackgroundObscurationState
-
- unsigned full_paint_invalidation_reason_ : 5; // PaintInvalidationReason
- static_assert(static_cast<unsigned>(PaintInvalidationReason::kMax) <
- (1u << 5),
- "PaintInvalidationReason should fit in the bit field");
+ background_obscuration_state_ : 2; // BackgroundObscurationState
public:
bool IsOutOfFlowPositioned() const {
@@ -2716,14 +2771,6 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
BackgroundObscurationState s) const {
background_obscuration_state_ = s;
}
-
- PaintInvalidationReason FullPaintInvalidationReason() const {
- return static_cast<PaintInvalidationReason>(
- full_paint_invalidation_reason_);
- }
- void SetFullPaintInvalidationReason(PaintInvalidationReason reason) {
- full_paint_invalidation_reason_ = static_cast<unsigned>(reason);
- }
};
#undef ADD_BOOLEAN_BITFIELD
@@ -2825,7 +2872,7 @@ inline void LayoutObject::SetNeedsLayoutAndFullPaintInvalidation(
inline void LayoutObject::ClearNeedsLayout() {
// Set flags for later stages/cycles.
SetEverHadLayout();
- SetMayNeedPaintInvalidation();
+ SetShouldCheckForPaintInvalidation();
// Clear needsLayout flags.
SetSelfNeedsLayout(false);
@@ -2867,6 +2914,14 @@ inline void LayoutObject::SetNeedsPositionedMovementLayout() {
MarkContainerChainForLayout();
}
+inline void LayoutObject::SetIsInLayoutNGInlineFormattingContext(
+ bool new_value) {
+ if (IsInLayoutNGInlineFormattingContext() == new_value)
+ return;
+ InLayoutNGInlineFormattingContextWillChange(new_value);
+ bitfields_.SetIsInLayoutNGInlineFormattingContext(new_value);
+}
+
inline void LayoutObject::SetHasBoxDecorationBackground(bool b) {
if (b == bitfields_.HasBoxDecorationBackground())
return;
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 985e6b03452..a4e4d874b22 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
@@ -101,13 +101,6 @@ LayoutObject* LayoutObjectChildList::RemoveChildNode(
ToLayoutBox(old_child)->DeleteLineBoxWrapper();
if (!owner->DocumentBeingDestroyed()) {
- // If oldChild is the start or end of the selection, then clear the
- // selection to avoid problems of invalid pointers.
- // FIXME: The FrameSelection should be responsible for this when it
- // is notified of DOM mutations.
- if (old_child->IsSelectionBorder() && owner->View())
- owner->View()->ClearSelection();
-
owner->NotifyOfSubtreeChange();
if (notify_layout_object) {
@@ -231,7 +224,7 @@ void LayoutObjectChildList::InsertChildNode(LayoutObject* owner,
if (!owner->DocumentBeingDestroyed())
owner->NotifyOfSubtreeChange();
- if (AXObjectCache* cache = owner->GetDocument().GetOrCreateAXObjectCache())
+ if (AXObjectCache* cache = owner->GetDocument().ExistingAXObjectCache())
cache->ChildrenChanged(owner);
}
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 e72b057182c..a40375c5f57 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
@@ -264,6 +264,22 @@ TEST_F(LayoutObjectTest, FloatUnderBlock) {
EXPECT_EQ(container, floating->ContainingBlock());
}
+TEST_F(LayoutObjectTest, InlineFloatMismatch) {
+ SetBodyInnerHTML(R"HTML(
+ <span id=span style='position: relative; left: 40px; width: 100px; height: 100px'>
+ <div id=float_obj style='float: left; margin-left: 10px;'>
+ </div>
+ </span>
+ )HTML");
+
+ LayoutObject* float_obj =
+ ToLayoutBoxModelObject(GetLayoutObjectByElementId("float_obj"));
+ LayoutObject* span =
+ ToLayoutBoxModelObject(GetLayoutObjectByElementId("span"));
+ // 10px for margin, -40px because float is to the left of the span.
+ EXPECT_EQ(LayoutSize(-30, 0), float_obj->OffsetFromAncestor(span));
+}
+
TEST_F(LayoutObjectTest, FloatUnderInline) {
SetBodyInnerHTML(R"HTML(
<div id='layered-div' style='position: absolute'>
@@ -303,10 +319,10 @@ TEST_F(LayoutObjectTest, MutableForPaintingClearPaintFlags) {
object->SetShouldDoFullPaintInvalidation();
EXPECT_TRUE(object->ShouldDoFullPaintInvalidation());
EXPECT_TRUE(object->NeedsPaintOffsetAndVisualRectUpdate());
- object->SetMayNeedPaintInvalidation();
- EXPECT_TRUE(object->MayNeedPaintInvalidation());
- object->SetMayNeedPaintInvalidationSubtree();
- EXPECT_TRUE(object->MayNeedPaintInvalidationSubtree());
+ object->SetShouldCheckForPaintInvalidation();
+ EXPECT_TRUE(object->ShouldCheckForPaintInvalidation());
+ object->SetSubtreeShouldCheckForPaintInvalidation();
+ EXPECT_TRUE(object->SubtreeShouldCheckForPaintInvalidation());
object->SetMayNeedPaintInvalidationAnimatedBackgroundImage();
EXPECT_TRUE(object->MayNeedPaintInvalidationAnimatedBackgroundImage());
object->SetShouldInvalidateSelection();
@@ -323,8 +339,8 @@ TEST_F(LayoutObjectTest, MutableForPaintingClearPaintFlags) {
object->GetMutableForPainting().ClearPaintFlags();
EXPECT_FALSE(object->ShouldDoFullPaintInvalidation());
- EXPECT_FALSE(object->MayNeedPaintInvalidation());
- EXPECT_FALSE(object->MayNeedPaintInvalidationSubtree());
+ EXPECT_FALSE(object->ShouldCheckForPaintInvalidation());
+ EXPECT_FALSE(object->SubtreeShouldCheckForPaintInvalidation());
EXPECT_FALSE(object->MayNeedPaintInvalidationAnimatedBackgroundImage());
EXPECT_FALSE(object->ShouldInvalidateSelection());
EXPECT_FALSE(object->BackgroundChangedSinceLastPaintInvalidation());
@@ -353,55 +369,55 @@ TEST_F(LayoutObjectTest, NeedsPaintOffsetAndVisualRectUpdate) {
object->SetShouldDoFullPaintInvalidation();
EXPECT_TRUE(object->ShouldDoFullPaintInvalidation());
EXPECT_TRUE(object->NeedsPaintOffsetAndVisualRectUpdate());
- EXPECT_TRUE(parent->MayNeedPaintInvalidation());
+ EXPECT_TRUE(parent->ShouldCheckForPaintInvalidation());
EXPECT_TRUE(parent->NeedsPaintOffsetAndVisualRectUpdate());
object->ClearPaintInvalidationFlags();
EXPECT_FALSE(object->ShouldDoFullPaintInvalidation());
EXPECT_FALSE(object->NeedsPaintOffsetAndVisualRectUpdate());
parent->ClearPaintInvalidationFlags();
- EXPECT_FALSE(parent->MayNeedPaintInvalidation());
+ EXPECT_FALSE(parent->ShouldCheckForPaintInvalidation());
EXPECT_FALSE(parent->NeedsPaintOffsetAndVisualRectUpdate());
- object->SetMayNeedPaintInvalidation();
- EXPECT_TRUE(object->MayNeedPaintInvalidation());
+ object->SetShouldCheckForPaintInvalidation();
+ EXPECT_TRUE(object->ShouldCheckForPaintInvalidation());
EXPECT_TRUE(object->NeedsPaintOffsetAndVisualRectUpdate());
- EXPECT_TRUE(parent->MayNeedPaintInvalidation());
+ EXPECT_TRUE(parent->ShouldCheckForPaintInvalidation());
EXPECT_TRUE(parent->NeedsPaintOffsetAndVisualRectUpdate());
object->ClearPaintInvalidationFlags();
- EXPECT_FALSE(object->MayNeedPaintInvalidation());
+ EXPECT_FALSE(object->ShouldCheckForPaintInvalidation());
EXPECT_FALSE(object->NeedsPaintOffsetAndVisualRectUpdate());
parent->ClearPaintInvalidationFlags();
- EXPECT_FALSE(parent->MayNeedPaintInvalidation());
+ EXPECT_FALSE(parent->ShouldCheckForPaintInvalidation());
EXPECT_FALSE(parent->NeedsPaintOffsetAndVisualRectUpdate());
object->SetShouldDoFullPaintInvalidationWithoutGeometryChange();
EXPECT_TRUE(object->ShouldDoFullPaintInvalidation());
EXPECT_FALSE(object->NeedsPaintOffsetAndVisualRectUpdate());
- EXPECT_TRUE(parent->MayNeedPaintInvalidation());
+ EXPECT_TRUE(parent->ShouldCheckForPaintInvalidation());
EXPECT_FALSE(parent->NeedsPaintOffsetAndVisualRectUpdate());
- object->SetMayNeedPaintInvalidation();
+ object->SetShouldCheckForPaintInvalidation();
EXPECT_TRUE(object->NeedsPaintOffsetAndVisualRectUpdate());
EXPECT_TRUE(parent->NeedsPaintOffsetAndVisualRectUpdate());
object->ClearPaintInvalidationFlags();
- EXPECT_FALSE(object->MayNeedPaintInvalidation());
+ EXPECT_FALSE(object->ShouldCheckForPaintInvalidation());
EXPECT_FALSE(object->NeedsPaintOffsetAndVisualRectUpdate());
parent->ClearPaintInvalidationFlags();
- EXPECT_FALSE(parent->MayNeedPaintInvalidation());
+ EXPECT_FALSE(parent->ShouldCheckForPaintInvalidation());
EXPECT_FALSE(parent->NeedsPaintOffsetAndVisualRectUpdate());
- object->SetMayNeedPaintInvalidationWithoutGeometryChange();
- EXPECT_TRUE(object->MayNeedPaintInvalidation());
+ object->SetShouldCheckForPaintInvalidationWithoutGeometryChange();
+ EXPECT_TRUE(object->ShouldCheckForPaintInvalidation());
EXPECT_FALSE(object->NeedsPaintOffsetAndVisualRectUpdate());
- EXPECT_TRUE(parent->MayNeedPaintInvalidation());
+ EXPECT_TRUE(parent->ShouldCheckForPaintInvalidation());
EXPECT_FALSE(parent->NeedsPaintOffsetAndVisualRectUpdate());
- object->SetMayNeedPaintInvalidation();
+ object->SetShouldCheckForPaintInvalidation();
EXPECT_TRUE(object->NeedsPaintOffsetAndVisualRectUpdate());
EXPECT_TRUE(parent->NeedsPaintOffsetAndVisualRectUpdate());
object->ClearPaintInvalidationFlags();
- EXPECT_FALSE(object->MayNeedPaintInvalidation());
+ EXPECT_FALSE(object->ShouldCheckForPaintInvalidation());
EXPECT_FALSE(object->NeedsPaintOffsetAndVisualRectUpdate());
parent->ClearPaintInvalidationFlags();
- EXPECT_FALSE(parent->MayNeedPaintInvalidation());
+ EXPECT_FALSE(parent->ShouldCheckForPaintInvalidation());
EXPECT_FALSE(parent->NeedsPaintOffsetAndVisualRectUpdate());
}
@@ -831,4 +847,34 @@ TEST_F(LayoutObjectSimTest, TouchActionUpdatesSubframeEventHandler) {
EXPECT_FALSE(DocumentHasTouchActionRegion(registry));
}
+TEST_F(LayoutObjectSimTest, HitTestForOcclusionInIframe) {
+ SimRequest main_resource("https://example.com/test.html", "text/html");
+ SimRequest frame_resource("https://example.com/frame.html", "text/html");
+
+ LoadURL("https://example.com/test.html");
+ main_resource.Complete(R"HTML(
+ <iframe style='width:300px;height:150px;' src=frame.html></iframe>
+ <div id='occluder' style='will-change:transform;width:100px;height:100px;'>
+ </div>
+ )HTML");
+ frame_resource.Complete(R"HTML(
+ <div id='target'>target</div>
+ )HTML");
+
+ GetDocument().View()->UpdateAllLifecyclePhases();
+ Element* iframe_element = GetDocument().QuerySelector("iframe");
+ HTMLFrameOwnerElement* frame_owner_element =
+ ToHTMLFrameOwnerElement(iframe_element);
+ Document* iframe_doc = frame_owner_element->contentDocument();
+ Element* target = iframe_doc->getElementById("target");
+ HitTestResult result = target->GetLayoutObject()->HitTestForOcclusion();
+ EXPECT_TRUE(result.InnerNode() == target);
+
+ Element* occluder = GetDocument().getElementById("occluder");
+ occluder->SetInlineStyleProperty(CSSPropertyMarginTop, "-150px");
+ GetDocument().View()->UpdateAllLifecyclePhases();
+ result = target->GetLayoutObject()->HitTestForOcclusion();
+ EXPECT_TRUE(result.InnerNode() == occluder);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_paged_flow_thread.cc b/chromium/third_party/blink/renderer/core/layout/layout_paged_flow_thread.cc
index b60ba59848e..ab2d39dee42 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_paged_flow_thread.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_paged_flow_thread.cc
@@ -26,7 +26,7 @@ int LayoutPagedFlowThread::PageCount() {
bool LayoutPagedFlowThread::NeedsNewWidth() const {
return ProgressionIsInline() !=
- PagedBlockFlow()->Style()->HasInlinePaginationAxis();
+ PagedBlockFlow()->StyleRef().HasInlinePaginationAxis();
}
void LayoutPagedFlowThread::UpdateLogicalWidth() {
@@ -39,7 +39,8 @@ void LayoutPagedFlowThread::UpdateLogicalWidth() {
void LayoutPagedFlowThread::UpdateLayout() {
// There should either be zero or one of those for paged layout.
DCHECK_EQ(FirstMultiColumnBox(), LastMultiColumnBox());
- SetProgressionIsInline(PagedBlockFlow()->Style()->HasInlinePaginationAxis());
+ SetProgressionIsInline(
+ PagedBlockFlow()->StyleRef().HasInlinePaginationAxis());
LayoutMultiColumnFlowThread::UpdateLayout();
LayoutMultiColumnSet* column_set = FirstMultiColumnSet();
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_progress.cc b/chromium/third_party/blink/renderer/core/layout/layout_progress.cc
index 83fe6ed2204..ebc3235f0fc 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_progress.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_progress.cc
@@ -91,7 +91,7 @@ void LayoutProgress::UpdateAnimationState() {
animation_repeat_interval_ =
LayoutTheme::GetTheme().AnimationRepeatIntervalForProgressBar();
- bool animating = !IsDeterminate() && Style()->HasAppearance() &&
+ bool animating = !IsDeterminate() && StyleRef().HasAppearance() &&
animation_duration_ > TimeDelta();
if (animating == animating_)
return;
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_quote.cc b/chromium/third_party/blink/renderer/core/layout/layout_quote.cc
index 335af89a053..473122e721e 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_quote.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_quote.cc
@@ -302,10 +302,10 @@ String LayoutQuote::ComputeText() const {
}
const QuotesData* LayoutQuote::GetQuotesData() const {
- if (const QuotesData* custom_quotes = Style()->Quotes())
+ if (const QuotesData* custom_quotes = StyleRef().Quotes())
return custom_quotes;
- if (const QuotesData* quotes = QuotesDataForLanguage(Style()->Locale()))
+ if (const QuotesData* quotes = QuotesDataForLanguage(StyleRef().Locale()))
return quotes;
return BasicQuotesData();
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 f61b89843f8..6e368e90a20 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_replaced.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_replaced.cc
@@ -75,13 +75,16 @@ void LayoutReplaced::StyleDidChange(StyleDifference diff,
// Replaced elements can have border-radius clips without clipping overflow;
// the overflow clipping case is already covered in LayoutBox::StyleDidChange
- if (old_style && !old_style->RadiiEqual(StyleRef()))
+ if (old_style && !old_style->RadiiEqual(StyleRef())) {
SetNeedsPaintPropertyUpdate();
+ if (Layer())
+ Layer()->SetNeedsCompositingInputsUpdate();
+ }
bool had_style = !!old_style;
float old_zoom = had_style ? old_style->EffectiveZoom()
: ComputedStyleInitialValues::InitialZoom();
- if (Style() && Style()->EffectiveZoom() != old_zoom)
+ if (Style() && StyleRef().EffectiveZoom() != old_zoom)
IntrinsicSizeChanged();
}
@@ -99,7 +102,6 @@ void LayoutReplaced::UpdateLayout() {
overflow_.reset();
AddVisualEffectOverflow();
UpdateAfterLayout();
- InvalidateBackgroundObscurationStatus();
ClearNeedsLayout();
@@ -108,9 +110,10 @@ void LayoutReplaced::UpdateLayout() {
}
void LayoutReplaced::IntrinsicSizeChanged() {
- int scaled_width = static_cast<int>(kDefaultWidth * Style()->EffectiveZoom());
+ int scaled_width =
+ static_cast<int>(kDefaultWidth * StyleRef().EffectiveZoom());
int scaled_height =
- static_cast<int>(kDefaultHeight * Style()->EffectiveZoom());
+ static_cast<int>(kDefaultHeight * StyleRef().EffectiveZoom());
intrinsic_size_ = LayoutSize(scaled_width, scaled_height);
SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
LayoutInvalidationReason::kSizeChanged);
@@ -121,16 +124,16 @@ void LayoutReplaced::Paint(const PaintInfo& paint_info) const {
}
bool LayoutReplaced::HasReplacedLogicalHeight() const {
- if (Style()->LogicalHeight().IsAuto())
+ if (StyleRef().LogicalHeight().IsAuto())
return false;
- if (Style()->LogicalHeight().IsSpecified()) {
+ if (StyleRef().LogicalHeight().IsSpecified()) {
if (HasAutoHeightOrContainingBlockWithAutoHeight())
return false;
return true;
}
- if (Style()->LogicalHeight().IsIntrinsic())
+ if (StyleRef().LogicalHeight().IsIntrinsic())
return true;
return false;
@@ -140,7 +143,7 @@ bool LayoutReplaced::NeedsPreferredWidthsRecalculation() const {
// If the height is a percentage and the width is auto, then the
// containingBlocks's height changing can cause this node to change it's
// preferred width because it maintains aspect ratio.
- return HasRelativeLogicalHeight() && Style()->LogicalWidth().IsAuto();
+ return HasRelativeLogicalHeight() && StyleRef().LogicalWidth().IsAuto();
}
static inline bool LayoutObjectHasAspectRatio(
@@ -178,7 +181,8 @@ FloatSize LayoutReplaced::ConstrainIntrinsicSizeToMinMax(
FloatSize constrained_size = intrinsic_sizing_info.size;
if (!intrinsic_sizing_info.aspect_ratio.IsEmpty() &&
!intrinsic_sizing_info.size.IsEmpty() &&
- Style()->LogicalWidth().IsAuto() && Style()->LogicalHeight().IsAuto()) {
+ StyleRef().LogicalWidth().IsAuto() &&
+ StyleRef().LogicalHeight().IsAuto()) {
// We can't multiply or divide by 'intrinsicSizingInfo.aspectRatio' here, it
// breaks tests, like images/zoomed-img-size.html, which
// can only be fixed once subpixel precision is available for things like
@@ -213,22 +217,22 @@ void LayoutReplaced::ComputePositionedLogicalWidth(
// To match WinIE, in quirks mode use the parent's 'direction' property
// instead of the the container block's.
- TextDirection container_direction = container_block->Style()->Direction();
+ TextDirection container_direction = container_block->StyleRef().Direction();
// Variables to solve.
bool is_horizontal = IsHorizontalWritingMode();
- Length logical_left = Style()->LogicalLeft();
- Length logical_right = Style()->LogicalRight();
+ Length logical_left = StyleRef().LogicalLeft();
+ Length logical_right = StyleRef().LogicalRight();
Length margin_logical_left =
- is_horizontal ? Style()->MarginLeft() : Style()->MarginTop();
+ is_horizontal ? StyleRef().MarginLeft() : StyleRef().MarginTop();
Length margin_logical_right =
- is_horizontal ? Style()->MarginRight() : Style()->MarginBottom();
- LayoutUnit& margin_logical_left_alias = Style()->IsLeftToRightDirection()
+ is_horizontal ? StyleRef().MarginRight() : StyleRef().MarginBottom();
+ LayoutUnit& margin_logical_left_alias = StyleRef().IsLeftToRightDirection()
? computed_values.margins_.start_
: computed_values.margins_.end_;
LayoutUnit& margin_logical_right_alias =
- Style()->IsLeftToRightDirection() ? computed_values.margins_.end_
- : computed_values.margins_.start_;
+ StyleRef().IsLeftToRightDirection() ? computed_values.margins_.end_
+ : computed_values.margins_.start_;
// ---------------------------------------------------------------------------
// 1. The used value of 'width' is determined as for inline replaced
@@ -392,7 +396,7 @@ void LayoutReplaced::ComputePositionedLogicalWidth(
// should use the last line box. When this is fixed elsewhere, this block
// should be removed.
if (container_block->IsLayoutInline() &&
- !container_block->Style()->IsLeftToRightDirection()) {
+ !container_block->StyleRef().IsLeftToRightDirection()) {
const LayoutInline* flow = ToLayoutInline(container_block);
InlineFlowBox* first_line = flow->FirstLineBox();
InlineFlowBox* last_line = flow->LastLineBox();
@@ -431,13 +435,13 @@ void LayoutReplaced::ComputePositionedLogicalHeight(
ContainingBlockLogicalWidthForPositioned(container_block, false);
// Variables to solve.
- Length margin_before = Style()->MarginBefore();
- Length margin_after = Style()->MarginAfter();
+ Length margin_before = StyleRef().MarginBefore();
+ Length margin_after = StyleRef().MarginAfter();
LayoutUnit& margin_before_alias = computed_values.margins_.before_;
LayoutUnit& margin_after_alias = computed_values.margins_.after_;
- Length logical_top = Style()->LogicalTop();
- Length logical_bottom = Style()->LogicalBottom();
+ Length logical_top = StyleRef().LogicalTop();
+ Length logical_bottom = StyleRef().LogicalBottom();
// ---------------------------------------------------------------------------
// 1. The used value of 'height' is determined as for inline replaced
@@ -572,11 +576,11 @@ void LayoutReplaced::ComputePositionedLogicalHeight(
LayoutRect LayoutReplaced::ComputeObjectFit(
const LayoutSize* overridden_intrinsic_size) const {
- LayoutRect content_rect = ContentBoxRect();
- EObjectFit object_fit = Style()->GetObjectFit();
+ LayoutRect content_rect = PhysicalContentBoxRect();
+ EObjectFit object_fit = StyleRef().GetObjectFit();
if (object_fit == EObjectFit::kFill &&
- Style()->ObjectPosition() ==
+ StyleRef().ObjectPosition() ==
ComputedStyleInitialValues::InitialObjectPosition()) {
return content_rect;
}
@@ -622,10 +626,11 @@ LayoutRect LayoutReplaced::ComputeObjectFit(
NOTREACHED();
}
- LayoutUnit x_offset = MinimumValueForLength(
- Style()->ObjectPosition().X(), content_rect.Width() - final_rect.Width());
+ LayoutUnit x_offset =
+ MinimumValueForLength(StyleRef().ObjectPosition().X(),
+ content_rect.Width() - final_rect.Width());
LayoutUnit y_offset =
- MinimumValueForLength(Style()->ObjectPosition().Y(),
+ MinimumValueForLength(StyleRef().ObjectPosition().Y(),
content_rect.Height() - final_rect.Height());
final_rect.Move(x_offset, y_offset);
@@ -636,6 +641,11 @@ LayoutRect LayoutReplaced::ReplacedContentRect() const {
return ComputeObjectFit();
}
+LayoutRect LayoutReplaced::PreSnappedRectForPersistentSizing(LayoutRect rect) {
+ rect.SetSize(LayoutSize(RoundedIntSize(rect.Size())));
+ return rect;
+}
+
void LayoutReplaced::ComputeIntrinsicSizingInfo(
IntrinsicSizingInfo& intrinsic_sizing_info) const {
if (ShouldApplySizeContainment()) {
@@ -677,9 +687,9 @@ LayoutUnit LayoutReplaced::ComputeConstrainedLogicalWidth(
// This solves above equation for 'width' (== logicalWidth).
LayoutUnit margin_start =
- MinimumValueForLength(Style()->MarginStart(), logical_width);
+ MinimumValueForLength(StyleRef().MarginStart(), logical_width);
LayoutUnit margin_end =
- MinimumValueForLength(Style()->MarginEnd(), logical_width);
+ MinimumValueForLength(StyleRef().MarginEnd(), logical_width);
logical_width = (logical_width - (margin_start + margin_end +
(Size().Width() - ClientWidth())))
.ClampNegativeToZero();
@@ -689,11 +699,11 @@ LayoutUnit LayoutReplaced::ComputeConstrainedLogicalWidth(
LayoutUnit LayoutReplaced::ComputeReplacedLogicalWidth(
ShouldComputePreferred should_compute_preferred) const {
- if (Style()->LogicalWidth().IsSpecified() ||
- Style()->LogicalWidth().IsIntrinsic())
+ if (StyleRef().LogicalWidth().IsSpecified() ||
+ StyleRef().LogicalWidth().IsIntrinsic())
return ComputeReplacedLogicalWidthRespectingMinMaxWidth(
ComputeReplacedLogicalWidthUsing(kMainOrPreferredSize,
- Style()->LogicalWidth()),
+ StyleRef().LogicalWidth()),
should_compute_preferred);
// 10.3.2 Inline, replaced elements:
@@ -704,8 +714,8 @@ LayoutUnit LayoutReplaced::ComputeReplacedLogicalWidth(
FloatSize constrained_size =
ConstrainIntrinsicSizeToMinMax(intrinsic_sizing_info);
- if (Style()->LogicalWidth().IsAuto()) {
- bool computed_height_is_auto = Style()->LogicalHeight().IsAuto();
+ if (StyleRef().LogicalWidth().IsAuto()) {
+ bool computed_height_is_auto = StyleRef().LogicalHeight().IsAuto();
// If 'height' and 'width' both have computed values of 'auto' and the
// element also has an intrinsic width, then that intrinsic width is the
@@ -776,10 +786,11 @@ LayoutUnit LayoutReplaced::ComputeReplacedLogicalHeight(
LayoutUnit estimated_used_width) const {
// 10.5 Content height: the 'height' property:
// http://www.w3.org/TR/CSS21/visudet.html#propdef-height
- if (HasReplacedLogicalHeight())
+ if (HasReplacedLogicalHeight()) {
return ComputeReplacedLogicalHeightRespectingMinMaxHeight(
ComputeReplacedLogicalHeightUsing(kMainOrPreferredSize,
- Style()->LogicalHeight()));
+ StyleRef().LogicalHeight()));
+ }
// 10.6.2 Inline, replaced elements:
// http://www.w3.org/TR/CSS21/visudet.html#inline-replaced-height
@@ -789,7 +800,7 @@ LayoutUnit LayoutReplaced::ComputeReplacedLogicalHeight(
FloatSize constrained_size =
ConstrainIntrinsicSizeToMinMax(intrinsic_sizing_info);
- bool width_is_auto = Style()->LogicalWidth().IsAuto();
+ bool width_is_auto = StyleRef().LogicalWidth().IsAuto();
// If 'height' and 'width' both have computed values of 'auto' and the element
// also has an intrinsic height, then that intrinsic height is the used value
@@ -835,7 +846,7 @@ void LayoutReplaced::ComputePreferredLogicalWidths() {
// 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 = Style()->LogicalWidth();
+ const Length& logical_width = StyleRef().LogicalWidth();
if (logical_width.IsPercentOrCalc() || logical_width.IsFillAvailable() ||
logical_width.IsFitContent())
ComputeIntrinsicLogicalWidths(min_preferred_logical_width_,
@@ -987,10 +998,10 @@ LayoutRect LayoutReplaced::LocalSelectionRect() const {
RootInlineBox& root = InlineBoxWrapper()->Root();
LayoutUnit new_logical_top =
- root.Block().Style()->IsFlippedBlocksWritingMode()
+ root.Block().StyleRef().IsFlippedBlocksWritingMode()
? InlineBoxWrapper()->LogicalBottom() - root.SelectionBottom()
: root.SelectionTop() - InlineBoxWrapper()->LogicalTop();
- if (root.Block().Style()->IsHorizontalWritingMode())
+ if (root.Block().StyleRef().IsHorizontalWritingMode())
return LayoutRect(LayoutUnit(), new_logical_top, Size().Width(),
root.SelectionHeight());
return LayoutRect(new_logical_top, LayoutUnit(), root.SelectionHeight(),
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 6d403787109..62be25f377f 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_replaced.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_replaced.h
@@ -63,6 +63,12 @@ class CORE_EXPORT LayoutReplaced : public LayoutBox {
// This function returns the local rect of the replaced content.
virtual LayoutRect ReplacedContentRect() const;
+ // This is used by a few special elements, e.g. <video>, <iframe> to ensure
+ // a persistent sizing under different subpixel offset, because these
+ // elements have a high cost to resize. The drawback is that we may overflow
+ // or underflow the final content box by 1px.
+ static LayoutRect PreSnappedRectForPersistentSizing(LayoutRect);
+
bool NeedsPreferredWidthsRecalculation() const override;
// These values are specified to be 300 and 150 pixels in the CSS 2.1 spec.
@@ -75,7 +81,7 @@ class CORE_EXPORT LayoutReplaced : public LayoutBox {
LayoutRect LocalSelectionRect() const final;
bool HasObjectFit() const {
- return Style()->GetObjectFit() !=
+ return StyleRef().GetObjectFit() !=
ComputedStyleInitialValues::InitialObjectFit();
}
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_ruby_run.cc b/chromium/third_party/blink/renderer/core/layout/layout_ruby_run.cc
index 141eee16323..699e128ec54 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_ruby_run.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_ruby_run.cc
@@ -237,8 +237,8 @@ void LayoutRubyRun::UpdateLayout() {
last_line_ruby_text_bottom = root_box->LogicalBottomLayoutOverflow();
}
- if (Style()->IsFlippedLinesWritingMode() ==
- (Style()->GetRubyPosition() == RubyPosition::kAfter)) {
+ if (StyleRef().IsFlippedLinesWritingMode() ==
+ (StyleRef().GetRubyPosition() == RubyPosition::kAfter)) {
LayoutUnit first_line_top;
if (LayoutRubyBase* rb = RubyBase()) {
RootInlineBox* root_box = rb->FirstRootBox();
@@ -295,10 +295,10 @@ void LayoutRubyRun::GetOverhang(bool first_line,
(logical_width - root_inline_box->LogicalRight()).ToInt());
}
- start_overhang = Style()->IsLeftToRightDirection() ? logical_left_overhang
- : logical_right_overhang;
- end_overhang = Style()->IsLeftToRightDirection() ? logical_right_overhang
- : logical_left_overhang;
+ start_overhang = StyleRef().IsLeftToRightDirection() ? logical_left_overhang
+ : logical_right_overhang;
+ end_overhang = StyleRef().IsLeftToRightDirection() ? logical_right_overhang
+ : logical_left_overhang;
if (!start_layout_object || !start_layout_object->IsText() ||
start_layout_object->Style(first_line)->FontSize() >
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 7c63b998a28..5990208b8f8 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
@@ -44,7 +44,7 @@ bool LayoutRubyText::IsChildAllowed(LayoutObject* child,
ETextAlign LayoutRubyText::TextAlignmentForLine(
bool ends_with_soft_break) const {
- ETextAlign text_align = Style()->GetTextAlign();
+ ETextAlign text_align = StyleRef().GetTextAlign();
// FIXME: This check is bogus since user can set the initial value.
if (text_align != ComputedStyleInitialValues::InitialTextAlign())
return LayoutBlockFlow::TextAlignmentForLine(ends_with_soft_break);
@@ -58,7 +58,7 @@ void LayoutRubyText::AdjustInlineDirectionLineBounds(
unsigned expansion_opportunity_count,
LayoutUnit& logical_left,
LayoutUnit& logical_width) const {
- ETextAlign text_align = Style()->GetTextAlign();
+ ETextAlign text_align = StyleRef().GetTextAlign();
// FIXME: This check is bogus since user can set the initial value.
if (text_align != ComputedStyleInitialValues::InitialTextAlign())
return LayoutBlockFlow::AdjustInlineDirectionLineBounds(
@@ -73,7 +73,7 @@ void LayoutRubyText::AdjustInlineDirectionLineBounds(
LayoutUnit inset = (logical_width - max_preferred_logical_width) /
(expansion_opportunity_count + 1);
if (expansion_opportunity_count)
- inset = std::min(LayoutUnit(2 * Style()->FontSize()), inset);
+ inset = std::min(LayoutUnit(2 * StyleRef().FontSize()), inset);
logical_left += inset / 2;
logical_width -= inset;
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_scrollbar.h b/chromium/third_party/blink/renderer/core/layout/layout_scrollbar.h
index 9e0463e6849..135055581dd 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_scrollbar.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_scrollbar.h
@@ -26,9 +26,9 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_SCROLLBAR_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_SCROLLBAR_H_
+#include "third_party/blink/renderer/core/scroll/scrollbar.h"
#include "third_party/blink/renderer/core/style/computed_style_constants.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_scrollbar_part.cc b/chromium/third_party/blink/renderer/core/layout/layout_scrollbar_part.cc
index a11e72a8884..7900a41b0b5 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_scrollbar_part.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_scrollbar_part.cc
@@ -165,18 +165,18 @@ void LayoutScrollbarPart::UpdateScrollbarWidth() {
// up to date, especially since we are called at style change.
// FIXME: Querying the style's border information doesn't work on table cells
// with collapsing borders.
- int visible_size = box->Size().Width() - box->Style()->BorderLeftWidth() -
- box->Style()->BorderRightWidth();
+ int visible_size = box->Size().Width() - box->StyleRef().BorderLeftWidth() -
+ box->StyleRef().BorderRightWidth();
SetWidth(LayoutUnit(ComputeScrollbarWidth(visible_size, Style())));
// Buttons and track pieces can all have margins along the axis of the
// scrollbar. Values are rounded because scrollbar parts need to be rendered
// at device pixel boundaries.
SetMarginLeft(LayoutUnit(
- MinimumValueForLength(Style()->MarginLeft(), LayoutUnit(visible_size))
+ MinimumValueForLength(StyleRef().MarginLeft(), LayoutUnit(visible_size))
.Round()));
SetMarginRight(LayoutUnit(
- MinimumValueForLength(Style()->MarginRight(), LayoutUnit(visible_size))
+ MinimumValueForLength(StyleRef().MarginRight(), LayoutUnit(visible_size))
.Round()));
}
@@ -188,18 +188,18 @@ void LayoutScrollbarPart::UpdateScrollbarHeight() {
// up to date, especially since we are called at style change.
// FIXME: Querying the style's border information doesn't work on table cells
// with collapsing borders.
- int visible_size = box->Size().Height() - box->Style()->BorderTopWidth() -
- box->Style()->BorderBottomWidth();
+ int visible_size = box->Size().Height() - box->StyleRef().BorderTopWidth() -
+ box->StyleRef().BorderBottomWidth();
SetHeight(LayoutUnit(ComputeScrollbarHeight(visible_size, Style())));
// Buttons and track pieces can all have margins along the axis of the
// scrollbar. Values are rounded because scrollbar parts need to be rendered
// at device pixel boundaries.
SetMarginTop(LayoutUnit(
- MinimumValueForLength(Style()->MarginTop(), LayoutUnit(visible_size))
+ MinimumValueForLength(StyleRef().MarginTop(), LayoutUnit(visible_size))
.Round()));
SetMarginBottom(LayoutUnit(
- MinimumValueForLength(Style()->MarginBottom(), LayoutUnit(visible_size))
+ MinimumValueForLength(StyleRef().MarginBottom(), LayoutUnit(visible_size))
.Round()));
}
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_scrollbar_theme.cc b/chromium/third_party/blink/renderer/core/layout/layout_scrollbar_theme.cc
index c358de3b4a6..477c563b4d1 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_scrollbar_theme.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_scrollbar_theme.cc
@@ -27,9 +27,9 @@
#include "third_party/blink/renderer/core/layout/layout_scrollbar.h"
#include "third_party/blink/renderer/core/paint/scrollbar_painter.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_scrollbar_theme.h b/chromium/third_party/blink/renderer/core/layout/layout_scrollbar_theme.h
index fe60d6d1e0e..f158bb40eab 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_scrollbar_theme.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_scrollbar_theme.h
@@ -26,7 +26,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_SCROLLBAR_THEME_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_SCROLLBAR_THEME_H_
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
namespace blink {
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 a442b80ea2f..7918e4b2a2a 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_slider.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_slider.cc
@@ -52,8 +52,8 @@ void LayoutSlider::ComputeIntrinsicLogicalWidths(
LayoutUnit& min_logical_width,
LayoutUnit& max_logical_width) const {
max_logical_width =
- LayoutUnit(kDefaultTrackLength * Style()->EffectiveZoom());
- if (!Style()->Width().IsPercentOrCalc())
+ LayoutUnit(kDefaultTrackLength * StyleRef().EffectiveZoom());
+ if (!StyleRef().Width().IsPercentOrCalc())
min_logical_width = max_logical_width;
}
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 111cbabae2a..4a8785ddf0a 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
@@ -76,7 +76,7 @@ void LayoutSliderContainer::ComputeLogicalHeight(
int tick_length = LayoutTheme::GetTheme().SliderTickSize().Height();
track_height = LayoutUnit(2 * (offset_from_center + tick_length));
}
- float zoom_factor = Style()->EffectiveZoom();
+ float zoom_factor = StyleRef().EffectiveZoom();
if (zoom_factor != 1.0)
track_height *= zoom_factor;
@@ -133,7 +133,7 @@ void LayoutSliderContainer::UpdateLayout() {
if (is_vertical) {
thumb_location.SetY(thumb_location.Y() + track->ContentHeight() -
thumb->Size().Height() - offset);
- } else if (Style()->IsLeftToRightDirection()) {
+ } else if (StyleRef().IsLeftToRightDirection()) {
thumb_location.SetX(thumb_location.X() + offset);
} else {
thumb_location.SetX(thumb_location.X() - offset);
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 1dc29c6de9f..c352cdcf161 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_state.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_state.cc
@@ -85,7 +85,7 @@ LayoutState::LayoutState(LayoutBox& layout_object,
if (!layout_object.IsOutOfFlowPositioned())
return;
if (LayoutObject* container = layout_object.Container()) {
- if (container->Style()->HasInFlowPosition() &&
+ if (container->StyleRef().HasInFlowPosition() &&
container->IsLayoutInline()) {
pagination_offset_ +=
ToLayoutInline(container)->OffsetForInFlowPositionedInline(
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 d1231377016..f2497d62bcf 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_table.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_table.cc
@@ -90,20 +90,21 @@ void LayoutTable::StyleDidChange(StyleDifference diff,
old_style ? old_style->IsFixedTableLayout() : false;
// In the collapsed border model, there is no cell spacing.
- h_spacing_ = ShouldCollapseBorders() ? 0 : Style()->HorizontalBorderSpacing();
- v_spacing_ = ShouldCollapseBorders() ? 0 : Style()->VerticalBorderSpacing();
+ h_spacing_ =
+ ShouldCollapseBorders() ? 0 : StyleRef().HorizontalBorderSpacing();
+ v_spacing_ = ShouldCollapseBorders() ? 0 : StyleRef().VerticalBorderSpacing();
DCHECK_GE(h_spacing_, 0);
DCHECK_GE(v_spacing_, 0);
if (!table_layout_ ||
- Style()->IsFixedTableLayout() != old_fixed_table_layout) {
+ StyleRef().IsFixedTableLayout() != old_fixed_table_layout) {
if (table_layout_)
table_layout_->WillChangeTableLayout();
// According to the CSS2 spec, you only use fixed table layout if an
// explicit width is specified on the table. Auto width implies auto table
// layout.
- if (Style()->IsFixedTableLayout())
+ if (StyleRef().IsFixedTableLayout())
table_layout_ = std::make_unique<TableLayoutAlgorithmFixed>(this);
else
table_layout_ = std::make_unique<TableLayoutAlgorithmAuto>(this);
@@ -138,7 +139,7 @@ static inline void ResetSectionPointerIfNotBefore(LayoutTableSection*& ptr,
static inline bool NeedsTableSection(LayoutObject* object) {
// Return true if 'object' can't exist in an anonymous table without being
// wrapped in a table section box.
- EDisplay display = object->Style()->Display();
+ EDisplay display = object->StyleRef().Display();
return display != EDisplay::kTableCaption &&
display != EDisplay::kTableColumnGroup &&
display != EDisplay::kTableColumn;
@@ -153,7 +154,7 @@ void LayoutTable::AddChild(LayoutObject* child, LayoutObject* before_child) {
has_col_elements_ = true;
wrap_in_anonymous_section = false;
} else if (child->IsTableSection()) {
- switch (child->Style()->Display()) {
+ switch (child->StyleRef().Display()) {
case EDisplay::kTableHeaderGroup:
ResetSectionPointerIfNotBefore(head_, before_child);
if (!head_) {
@@ -266,7 +267,7 @@ void LayoutTable::RemoveColumn(const LayoutTableCol*) {
}
bool LayoutTable::IsLogicalWidthAuto() const {
- Length style_logical_width = Style()->LogicalWidth();
+ Length style_logical_width = StyleRef().LogicalWidth();
return (!style_logical_width.IsSpecified() ||
!style_logical_width.IsPositive()) &&
!style_logical_width.IsIntrinsic();
@@ -302,24 +303,24 @@ void LayoutTable::UpdateLogicalWidth() {
LayoutUnit available_logical_width = ContainingBlockLogicalWidthForContent();
bool has_perpendicular_containing_block =
- cb->Style()->IsHorizontalWritingMode() !=
- Style()->IsHorizontalWritingMode();
+ cb->StyleRef().IsHorizontalWritingMode() !=
+ StyleRef().IsHorizontalWritingMode();
LayoutUnit container_width_in_inline_direction =
has_perpendicular_containing_block
? PerpendicularContainingBlockLogicalHeight()
: available_logical_width;
- Length style_logical_width = Style()->LogicalWidth();
+ Length style_logical_width = StyleRef().LogicalWidth();
if (!IsLogicalWidthAuto()) {
SetLogicalWidth(ConvertStyleLogicalWidthToComputedWidth(
style_logical_width, container_width_in_inline_direction));
} else {
// Subtract out any fixed margins from our available width for auto width
// tables.
- LayoutUnit margin_start =
- MinimumValueForLength(Style()->MarginStart(), available_logical_width);
+ LayoutUnit margin_start = MinimumValueForLength(StyleRef().MarginStart(),
+ available_logical_width);
LayoutUnit margin_end =
- MinimumValueForLength(Style()->MarginEnd(), available_logical_width);
+ MinimumValueForLength(StyleRef().MarginEnd(), available_logical_width);
LayoutUnit margin_total = margin_start + margin_end;
// Subtract out our margins to get the available content width.
@@ -346,7 +347,7 @@ void LayoutTable::UpdateLogicalWidth() {
}
// Ensure we aren't bigger than our max-width style.
- Length style_max_logical_width = Style()->LogicalMaxWidth();
+ Length style_max_logical_width = StyleRef().LogicalMaxWidth();
if ((style_max_logical_width.IsSpecified() &&
!style_max_logical_width.IsNegative()) ||
style_max_logical_width.IsIntrinsic()) {
@@ -364,7 +365,7 @@ void LayoutTable::UpdateLogicalWidth() {
LayoutUnit(std::max(LogicalWidth(), MinPreferredLogicalWidth()).Floor()));
// Ensure we aren't smaller than our min-width style.
- Length style_min_logical_width = Style()->LogicalMinWidth();
+ Length style_min_logical_width = StyleRef().LogicalMinWidth();
if ((style_min_logical_width.IsSpecified() &&
!style_min_logical_width.IsNegative()) ||
style_min_logical_width.IsIntrinsic()) {
@@ -379,8 +380,8 @@ void LayoutTable::UpdateLogicalWidth() {
ComputedMarginValues margin_values;
ComputeMarginsForDirection(kInlineDirection, cb, available_logical_width,
LogicalWidth(), margin_values.start_,
- margin_values.end_, Style()->MarginStart(),
- Style()->MarginEnd());
+ margin_values.end_, StyleRef().MarginStart(),
+ StyleRef().MarginEnd());
SetMarginStart(margin_values.start_);
SetMarginEnd(margin_values.end_);
@@ -408,7 +409,7 @@ LayoutUnit LayoutTable::ConvertStyleLogicalWidthToComputedWidth(
bool is_css_table = !IsHTMLTableElement(GetNode());
if (is_css_table && style_logical_width.IsSpecified() &&
style_logical_width.IsPositive() &&
- Style()->BoxSizing() == EBoxSizing::kContentBox) {
+ StyleRef().BoxSizing() == EBoxSizing::kContentBox) {
borders = BorderStart() + BorderEnd() +
(ShouldCollapseBorders() ? LayoutUnit()
: PaddingStart() + PaddingEnd());
@@ -434,7 +435,7 @@ LayoutUnit LayoutTable::ConvertStyleLogicalHeightToComputedHeight(
// FIXME: We cannot apply box-sizing: content-box on <table> which other
// browsers allow.
if (IsHTMLTableElement(GetNode()) ||
- Style()->BoxSizing() == EBoxSizing::kBorderBox) {
+ StyleRef().BoxSizing() == EBoxSizing::kBorderBox) {
borders = border_and_padding;
}
computed_logical_height =
@@ -476,7 +477,7 @@ void LayoutTable::LayoutCaption(LayoutTableCaption& caption,
UpdateFragmentationInfoForChild(caption);
if (!SelfNeedsLayout())
- caption.SetMayNeedPaintInvalidation();
+ caption.SetShouldCheckForPaintInvalidation();
SetLogicalHeight(LogicalHeight() + caption.LogicalHeight() +
CollapsedMarginBeforeForChild(caption) +
@@ -508,7 +509,7 @@ void LayoutTable::LayoutSection(
LayoutUnit LayoutTable::LogicalHeightFromStyle() const {
LayoutUnit computed_logical_height;
- Length logical_height_length = Style()->LogicalHeight();
+ Length logical_height_length = StyleRef().LogicalHeight();
if (logical_height_length.IsIntrinsic() ||
(logical_height_length.IsSpecified() &&
logical_height_length.IsPositive())) {
@@ -516,7 +517,7 @@ LayoutUnit LayoutTable::LogicalHeightFromStyle() const {
ConvertStyleLogicalHeightToComputedHeight(logical_height_length);
}
- Length logical_max_height_length = Style()->LogicalMaxHeight();
+ Length logical_max_height_length = StyleRef().LogicalMaxHeight();
if (logical_max_height_length.IsIntrinsic() ||
(logical_max_height_length.IsSpecified() &&
!logical_max_height_length.IsNegative())) {
@@ -526,7 +527,7 @@ LayoutUnit LayoutTable::LogicalHeightFromStyle() const {
std::min(computed_logical_height, computed_max_logical_height);
}
- Length logical_min_height_length = Style()->LogicalMinHeight();
+ Length logical_min_height_length = StyleRef().LogicalMinHeight();
if (logical_min_height_length.IsIntrinsic() ||
(logical_min_height_length.IsSpecified() &&
!logical_min_height_length.IsNegative())) {
@@ -630,7 +631,7 @@ void LayoutTable::UpdateLayout() {
// Lay out top captions.
// FIXME: Collapse caption margin.
for (unsigned i = 0; i < captions_.size(); i++) {
- if (captions_[i]->Style()->CaptionSide() == ECaptionSide::kBottom)
+ if (captions_[i]->StyleRef().CaptionSide() == ECaptionSide::kBottom)
continue;
LayoutCaption(*captions_[i], layouter);
}
@@ -652,10 +653,10 @@ void LayoutTable::UpdateLayout() {
SetLogicalHeight(table_box_logical_top + border_and_padding_before);
LayoutUnit section_logical_left = LayoutUnit(
- Style()->IsLeftToRightDirection() ? BorderStart() : BorderEnd());
+ StyleRef().IsLeftToRightDirection() ? BorderStart() : BorderEnd());
if (!collapsing) {
section_logical_left +=
- Style()->IsLeftToRightDirection() ? PaddingStart() : PaddingEnd();
+ StyleRef().IsLeftToRightDirection() ? PaddingStart() : PaddingEnd();
}
LayoutUnit current_available_logical_height =
AvailableLogicalHeight(kIncludeMarginBorderPadding);
@@ -797,7 +798,7 @@ void LayoutTable::UpdateLayout() {
// Lay out bottom captions.
for (unsigned i = 0; i < captions_.size(); i++) {
- if (captions_[i]->Style()->CaptionSide() != ECaptionSide::kBottom)
+ if (captions_[i]->StyleRef().CaptionSide() != ECaptionSide::kBottom)
continue;
LayoutCaption(*captions_[i], layouter);
}
@@ -869,16 +870,16 @@ bool LayoutTable::IsAbsoluteColumnCollapsed(
ColAndColGroup colElement = ColElementAtAbsoluteColumn(absolute_column_index);
LayoutTableCol* col = colElement.col;
LayoutTableCol* colgroup = colElement.colgroup;
- return (col && col->Style()->Visibility() == EVisibility::kCollapse) ||
+ return (col && col->StyleRef().Visibility() == EVisibility::kCollapse) ||
(colgroup &&
- colgroup->Style()->Visibility() == EVisibility::kCollapse);
+ colgroup->StyleRef().Visibility() == EVisibility::kCollapse);
}
void LayoutTable::InvalidateCollapsedBorders() {
collapsed_borders_valid_ = false;
needs_invalidate_collapsed_borders_for_all_cells_ = true;
collapsed_outer_borders_valid_ = false;
- SetMayNeedPaintInvalidation();
+ SetShouldCheckForPaintInvalidation();
}
void LayoutTable::InvalidateCollapsedBordersForAllCellsIfNeeded() {
@@ -946,9 +947,9 @@ void LayoutTable::SubtractCaptionRect(LayoutRect& rect) const {
captions_[i]->MarginBefore() +
captions_[i]->MarginAfter();
bool caption_is_before =
- (captions_[i]->Style()->CaptionSide() != ECaptionSide::kBottom) ^
- Style()->IsFlippedBlocksWritingMode();
- if (Style()->IsHorizontalWritingMode()) {
+ (captions_[i]->StyleRef().CaptionSide() != ECaptionSide::kBottom) ^
+ StyleRef().IsFlippedBlocksWritingMode();
+ if (StyleRef().IsHorizontalWritingMode()) {
rect.SetHeight(rect.Height() - caption_logical_height);
if (caption_is_before)
rect.Move(LayoutUnit(), caption_logical_height);
@@ -1204,7 +1205,7 @@ void LayoutTable::RecalcSections() const {
LayoutObject* next_sibling;
for (LayoutObject* child = FirstChild(); child; child = next_sibling) {
next_sibling = child->NextSibling();
- switch (child->Style()->Display()) {
+ switch (child->StyleRef().Display()) {
case EDisplay::kTableColumn:
case EDisplay::kTableColumnGroup:
has_col_elements_ = true;
@@ -1512,7 +1513,7 @@ LayoutRect LayoutTable::OverflowClipRect(
// mapping them to top/bottom, we might have to hack this code first
// (depending on what order we do these bug fixes in).
if (!captions_.IsEmpty()) {
- if (Style()->IsHorizontalWritingMode()) {
+ if (StyleRef().IsHorizontalWritingMode()) {
rect.SetHeight(Size().Height());
rect.SetY(location.Y());
} else {
@@ -1638,9 +1639,9 @@ void LayoutTable::EnsureIsReadyForPaintInvalidation() {
}
}
-PaintInvalidationReason LayoutTable::InvalidatePaint(
+void LayoutTable::InvalidatePaint(
const PaintInvalidatorContext& context) const {
- return TablePaintInvalidator(*this, context).InvalidatePaint();
+ TablePaintInvalidator(*this, context).InvalidatePaint();
}
LayoutUnit LayoutTable::PaddingTop() const {
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 6b9835b310b..045eff0404d 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_table.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_table.h
@@ -145,7 +145,7 @@ class CORE_EXPORT LayoutTable final : public LayoutBlock {
int VBorderSpacing() const { return v_spacing_; }
bool ShouldCollapseBorders() const {
- return Style()->BorderCollapse() == EBorderCollapse::kCollapse;
+ return StyleRef().BorderCollapse() == EBorderCollapse::kCollapse;
}
LayoutUnit BorderLeft() const override;
@@ -428,8 +428,7 @@ class CORE_EXPORT LayoutTable final : public LayoutBlock {
void SimplifiedNormalFlowLayout() override;
bool RecalcOverflowAfterStyleChange() override;
void EnsureIsReadyForPaintInvalidation() override;
- PaintInvalidationReason InvalidatePaint(
- const PaintInvalidatorContext&) const override;
+ void InvalidatePaint(const PaintInvalidatorContext&) const override;
bool PaintedOutputOfObjectHasNoEffectRegardlessOfSize() const override;
private:
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_table_box_component.cc b/chromium/third_party/blink/renderer/core/layout/layout_table_box_component.cc
index 03a3cc2cd04..b08070687ed 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_table_box_component.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_table_box_component.cc
@@ -61,8 +61,8 @@ void LayoutTableBoxComponent::StyleDidChange(StyleDifference diff,
const ComputedStyle* old_style) {
LayoutBox::StyleDidChange(diff, old_style);
SetCanContainFixedPositionObjects(
- Style()->CanContainFixedPositionObjects(false) ||
- ShouldApplyPaintContainment());
+ StyleRef().CanContainFixedPositionObjects(false) ||
+ ShouldApplyPaintContainment() || ShouldApplyLayoutContainment());
}
} // namespace blink
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 e08a856cf69..9c7f0761fdf 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
@@ -150,7 +150,7 @@ Length LayoutTableCell::LogicalWidthFromColumns(
unsigned col_span_count = ColSpan();
int col_width_sum = 0;
for (unsigned i = 1; i <= col_span_count; i++) {
- Length col_width = table_col->Style()->LogicalWidth();
+ Length col_width = table_col->StyleRef().LogicalWidth();
// Percentage value should be returned only for colSpan == 1.
// Otherwise we return original width for the cell.
@@ -198,7 +198,7 @@ void LayoutTableCell::ComputePreferredLogicalWidths() {
if (logical_height > -1)
SetOverrideLogicalHeight(logical_height);
- if (GetNode() && Style()->AutoWrap()) {
+ if (GetNode() && StyleRef().AutoWrap()) {
// See if nowrap was set.
Length w = StyleOrColLogicalWidth();
const AtomicString& nowrap = ToElement(GetNode())->getAttribute(nowrapAttr);
@@ -316,8 +316,8 @@ LayoutUnit LayoutTableCell::PaddingTop() const {
ComputedCSSPaddingTop() + LogicalIntrinsicPaddingToPhysical().Top();
// TODO(crbug.com/377847): The ToInt call should be removed when Table is
// sub-pixel aware.
- return Style()->IsHorizontalWritingMode() ? LayoutUnit(result.ToInt())
- : result;
+ return StyleRef().IsHorizontalWritingMode() ? LayoutUnit(result.ToInt())
+ : result;
}
LayoutUnit LayoutTableCell::PaddingBottom() const {
@@ -325,8 +325,8 @@ LayoutUnit LayoutTableCell::PaddingBottom() const {
ComputedCSSPaddingBottom() + LogicalIntrinsicPaddingToPhysical().Bottom();
// TODO(crbug.com/377847): The ToInt call should be removed when Table is
// sub-pixel aware.
- return Style()->IsHorizontalWritingMode() ? LayoutUnit(result.ToInt())
- : result;
+ return StyleRef().IsHorizontalWritingMode() ? LayoutUnit(result.ToInt())
+ : result;
}
LayoutUnit LayoutTableCell::PaddingLeft() const {
@@ -334,8 +334,8 @@ LayoutUnit LayoutTableCell::PaddingLeft() const {
ComputedCSSPaddingLeft() + LogicalIntrinsicPaddingToPhysical().Left();
// TODO(crbug.com/377847): The ToInt call should be removed when Table is
// sub-pixel aware.
- return Style()->IsHorizontalWritingMode() ? result
- : LayoutUnit(result.ToInt());
+ return StyleRef().IsHorizontalWritingMode() ? result
+ : LayoutUnit(result.ToInt());
}
LayoutUnit LayoutTableCell::PaddingRight() const {
@@ -343,8 +343,8 @@ LayoutUnit LayoutTableCell::PaddingRight() const {
ComputedCSSPaddingRight() + LogicalIntrinsicPaddingToPhysical().Right();
// TODO(crbug.com/377847): The ToInt call should be removed when Table is
// sub-pixel aware.
- return Style()->IsHorizontalWritingMode() ? result
- : LayoutUnit(result.ToInt());
+ return StyleRef().IsHorizontalWritingMode() ? result
+ : LayoutUnit(result.ToInt());
}
void LayoutTableCell::SetOverrideLogicalHeightFromRowHeight(
@@ -452,7 +452,7 @@ LayoutUnit LayoutTableCell::CellBaselinePosition() const {
void LayoutTableCell::StyleDidChange(StyleDifference diff,
const ComputedStyle* old_style) {
- DCHECK_EQ(Style()->Display(), EDisplay::kTableCell);
+ DCHECK_EQ(StyleRef().Display(), EDisplay::kTableCell);
LayoutBlockFlow::StyleDidChange(diff, old_style);
SetHasBoxDecorationBackground(true);
@@ -460,14 +460,14 @@ void LayoutTableCell::StyleDidChange(StyleDifference diff,
if (!old_style)
return;
- if (Parent() && Section() && Style()->Height() != old_style->Height())
+ if (Parent() && Section() && StyleRef().Height() != old_style->Height())
Section()->RowLogicalHeightChanged(Row());
// Our intrinsic padding pushes us down to align with the baseline of other
// cells on the row. If our vertical-align has changed then so will the
// padding needed to align with other cells - clear it so we can recalculate
// it from scratch.
- if (Style()->VerticalAlign() != old_style->VerticalAlign())
+ if (StyleRef().VerticalAlign() != old_style->VerticalAlign())
ClearIntrinsicPadding();
if (!Parent())
@@ -797,14 +797,14 @@ CollapsedBorderValue LayoutTableCell::ComputeCollapsedBeforeBorder() const {
const CSSProperty& after_color_property =
ResolveBorderProperty(GetCSSPropertyBorderBlockEndColor());
CollapsedBorderValue result = CollapsedBorderValue(
- Style()->BorderBeforeStyle(), Style()->BorderBeforeWidth(),
+ StyleRef().BorderBeforeStyle(), StyleRef().BorderBeforeWidth(),
ResolveColor(before_color_property), kBorderPrecedenceCell);
if (cell_above) {
// (2) A before cell's after border.
result = ChooseBorder(
- CollapsedBorderValue(cell_above->Style()->BorderAfterStyle(),
- cell_above->Style()->BorderAfterWidth(),
+ CollapsedBorderValue(cell_above->StyleRef().BorderAfterStyle(),
+ cell_above->StyleRef().BorderAfterWidth(),
cell_above->ResolveColor(after_color_property),
kBorderPrecedenceCell),
result);
@@ -815,8 +815,8 @@ CollapsedBorderValue LayoutTableCell::ComputeCollapsedBeforeBorder() const {
// (3) Our row's before border.
result = ChooseBorder(
result,
- CollapsedBorderValue(Parent()->Style()->BorderBeforeStyle(),
- Parent()->Style()->BorderBeforeWidth(),
+ CollapsedBorderValue(Parent()->StyleRef().BorderBeforeStyle(),
+ Parent()->StyleRef().BorderBeforeWidth(),
Parent()->ResolveColor(before_color_property),
kBorderPrecedenceRow));
if (!result.Exists())
@@ -832,8 +832,8 @@ CollapsedBorderValue LayoutTableCell::ComputeCollapsedBeforeBorder() const {
if (prev_row) {
result = ChooseBorder(
- CollapsedBorderValue(prev_row->Style()->BorderAfterStyle(),
- prev_row->Style()->BorderAfterWidth(),
+ CollapsedBorderValue(prev_row->StyleRef().BorderAfterStyle(),
+ prev_row->StyleRef().BorderAfterWidth(),
prev_row->ResolveColor(after_color_property),
kBorderPrecedenceRow),
result);
@@ -848,8 +848,8 @@ CollapsedBorderValue LayoutTableCell::ComputeCollapsedBeforeBorder() const {
// (5) Our row group's before border.
result = ChooseBorder(
result,
- CollapsedBorderValue(curr_section->Style()->BorderBeforeStyle(),
- curr_section->Style()->BorderBeforeWidth(),
+ CollapsedBorderValue(curr_section->StyleRef().BorderBeforeStyle(),
+ curr_section->StyleRef().BorderBeforeWidth(),
curr_section->ResolveColor(before_color_property),
kBorderPrecedenceRowGroup));
if (!result.Exists())
@@ -859,8 +859,8 @@ CollapsedBorderValue LayoutTableCell::ComputeCollapsedBeforeBorder() const {
curr_section = table->SectionAbove(curr_section, kSkipEmptySections);
if (curr_section) {
result = ChooseBorder(
- CollapsedBorderValue(curr_section->Style()->BorderAfterStyle(),
- curr_section->Style()->BorderAfterWidth(),
+ CollapsedBorderValue(curr_section->StyleRef().BorderAfterStyle(),
+ curr_section->StyleRef().BorderAfterWidth(),
curr_section->ResolveColor(after_color_property),
kBorderPrecedenceRowGroup),
result);
@@ -877,8 +877,8 @@ CollapsedBorderValue LayoutTableCell::ComputeCollapsedBeforeBorder() const {
if (col_elt) {
result = ChooseBorder(
result,
- CollapsedBorderValue(col_elt->Style()->BorderBeforeStyle(),
- col_elt->Style()->BorderBeforeWidth(),
+ CollapsedBorderValue(col_elt->StyleRef().BorderBeforeStyle(),
+ col_elt->StyleRef().BorderBeforeWidth(),
col_elt->ResolveColor(before_color_property),
kBorderPrecedenceColumn));
if (!result.Exists())
@@ -888,8 +888,8 @@ CollapsedBorderValue LayoutTableCell::ComputeCollapsedBeforeBorder() const {
result = ChooseBorder(
result,
CollapsedBorderValue(
- enclosing_column_group->Style()->BorderBeforeStyle(),
- enclosing_column_group->Style()->BorderBeforeWidth(),
+ enclosing_column_group->StyleRef().BorderBeforeStyle(),
+ enclosing_column_group->StyleRef().BorderBeforeWidth(),
enclosing_column_group->ResolveColor(before_color_property),
kBorderPrecedenceColumnGroup));
if (!result.Exists())
@@ -899,8 +899,8 @@ CollapsedBorderValue LayoutTableCell::ComputeCollapsedBeforeBorder() const {
// (9) The table's before border.
result = ChooseBorder(
- result, CollapsedBorderValue(table->Style()->BorderBeforeStyle(),
- table->Style()->BorderBeforeWidth(),
+ result, CollapsedBorderValue(table->StyleRef().BorderBeforeStyle(),
+ table->StyleRef().BorderBeforeWidth(),
table->ResolveColor(before_color_property),
kBorderPrecedenceTable));
if (!result.Exists())
@@ -928,15 +928,15 @@ CollapsedBorderValue LayoutTableCell::ComputeCollapsedAfterBorder() const {
const CSSProperty& after_color_property =
ResolveBorderProperty(GetCSSPropertyBorderBlockEndColor());
CollapsedBorderValue result = CollapsedBorderValue(
- Style()->BorderAfterStyle(), Style()->BorderAfterWidth(),
+ StyleRef().BorderAfterStyle(), StyleRef().BorderAfterWidth(),
ResolveColor(after_color_property), kBorderPrecedenceCell);
if (cell_below) {
// (2) An after cell's before border.
result = ChooseBorder(
result,
- CollapsedBorderValue(cell_below->Style()->BorderBeforeStyle(),
- cell_below->Style()->BorderBeforeWidth(),
+ CollapsedBorderValue(cell_below->StyleRef().BorderBeforeStyle(),
+ cell_below->StyleRef().BorderBeforeWidth(),
cell_below->ResolveColor(before_color_property),
kBorderPrecedenceCell));
if (!result.Exists())
@@ -945,8 +945,8 @@ CollapsedBorderValue LayoutTableCell::ComputeCollapsedAfterBorder() const {
// (3) Our row's after border. (FIXME: Deal with rowspan!)
result = ChooseBorder(
- result, CollapsedBorderValue(Parent()->Style()->BorderAfterStyle(),
- Parent()->Style()->BorderAfterWidth(),
+ result, CollapsedBorderValue(Parent()->StyleRef().BorderAfterStyle(),
+ Parent()->StyleRef().BorderAfterWidth(),
Parent()->ResolveColor(after_color_property),
kBorderPrecedenceRow));
if (!result.Exists())
@@ -956,8 +956,8 @@ CollapsedBorderValue LayoutTableCell::ComputeCollapsedAfterBorder() const {
if (cell_below) {
result = ChooseBorder(
result, CollapsedBorderValue(
- cell_below->Parent()->Style()->BorderBeforeStyle(),
- cell_below->Parent()->Style()->BorderBeforeWidth(),
+ cell_below->Parent()->StyleRef().BorderBeforeStyle(),
+ cell_below->Parent()->StyleRef().BorderBeforeWidth(),
cell_below->Parent()->ResolveColor(before_color_property),
kBorderPrecedenceRow));
if (!result.Exists())
@@ -970,8 +970,8 @@ CollapsedBorderValue LayoutTableCell::ComputeCollapsedAfterBorder() const {
// (5) Our row group's after border.
result = ChooseBorder(
result,
- CollapsedBorderValue(curr_section->Style()->BorderAfterStyle(),
- curr_section->Style()->BorderAfterWidth(),
+ CollapsedBorderValue(curr_section->StyleRef().BorderAfterStyle(),
+ curr_section->StyleRef().BorderAfterWidth(),
curr_section->ResolveColor(after_color_property),
kBorderPrecedenceRowGroup));
if (!result.Exists())
@@ -982,8 +982,8 @@ CollapsedBorderValue LayoutTableCell::ComputeCollapsedAfterBorder() const {
if (curr_section) {
result = ChooseBorder(
result, CollapsedBorderValue(
- curr_section->Style()->BorderBeforeStyle(),
- curr_section->Style()->BorderBeforeWidth(),
+ curr_section->StyleRef().BorderBeforeStyle(),
+ curr_section->StyleRef().BorderBeforeWidth(),
curr_section->ResolveColor(before_color_property),
kBorderPrecedenceRowGroup));
if (!result.Exists())
@@ -999,8 +999,8 @@ CollapsedBorderValue LayoutTableCell::ComputeCollapsedAfterBorder() const {
if (col_elt) {
result = ChooseBorder(
result,
- CollapsedBorderValue(col_elt->Style()->BorderAfterStyle(),
- col_elt->Style()->BorderAfterWidth(),
+ CollapsedBorderValue(col_elt->StyleRef().BorderAfterStyle(),
+ col_elt->StyleRef().BorderAfterWidth(),
col_elt->ResolveColor(after_color_property),
kBorderPrecedenceColumn));
if (!result.Exists())
@@ -1010,8 +1010,8 @@ CollapsedBorderValue LayoutTableCell::ComputeCollapsedAfterBorder() const {
result = ChooseBorder(
result,
CollapsedBorderValue(
- enclosing_column_group->Style()->BorderAfterStyle(),
- enclosing_column_group->Style()->BorderAfterWidth(),
+ enclosing_column_group->StyleRef().BorderAfterStyle(),
+ enclosing_column_group->StyleRef().BorderAfterWidth(),
enclosing_column_group->ResolveColor(after_color_property),
kBorderPrecedenceColumnGroup));
if (!result.Exists())
@@ -1021,8 +1021,8 @@ CollapsedBorderValue LayoutTableCell::ComputeCollapsedAfterBorder() const {
// (9) The table's after border.
result = ChooseBorder(
- result, CollapsedBorderValue(table->Style()->BorderAfterStyle(),
- table->Style()->BorderAfterWidth(),
+ result, CollapsedBorderValue(table->StyleRef().BorderAfterStyle(),
+ table->StyleRef().BorderAfterWidth(),
table->ResolveColor(after_color_property),
kBorderPrecedenceTable));
if (!result.Exists())
@@ -1142,7 +1142,7 @@ void LayoutTableCell::ScrollbarsChanged(bool horizontal_scrollbar_changed,
// Shrink our intrinsic padding as much as possible to accommodate the
// scrollbar.
- if (Style()->VerticalAlign() == EVerticalAlign::kMiddle) {
+ if (StyleRef().VerticalAlign() == EVerticalAlign::kMiddle) {
LayoutUnit total_height = LogicalHeight();
LayoutUnit height_without_intrinsic_padding =
total_height - IntrinsicPaddingBefore() - IntrinsicPaddingAfter();
@@ -1215,9 +1215,9 @@ bool LayoutTableCell::HasLineIfEmpty() const {
return LayoutBlock::HasLineIfEmpty();
}
-PaintInvalidationReason LayoutTableCell::InvalidatePaint(
+void LayoutTableCell::InvalidatePaint(
const PaintInvalidatorContext& context) const {
- return TableCellPaintInvalidator(*this, context).InvalidatePaint();
+ TableCellPaintInvalidator(*this, context).InvalidatePaint();
}
} // namespace blink
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 859bb4f7c4c..44dedd17ffa 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
@@ -144,7 +144,7 @@ class CORE_EXPORT LayoutTableCell : public LayoutBlockFlow {
}
Length StyleOrColLogicalWidth() const {
- Length style_width = Style()->LogicalWidth();
+ Length style_width = StyleRef().LogicalWidth();
if (!style_width.IsAuto())
return style_width;
if (LayoutTableCol* first_column =
@@ -156,7 +156,7 @@ class CORE_EXPORT LayoutTableCell : public LayoutBlockFlow {
}
int LogicalHeightFromStyle() const {
- Length height = Style()->LogicalHeight();
+ Length height = StyleRef().LogicalHeight();
int style_logical_height =
height.IsIntrinsicOrAuto()
? 0
@@ -166,7 +166,7 @@ class CORE_EXPORT LayoutTableCell : public LayoutBlockFlow {
// add in the border and padding.
// Call computedCSSPadding* directly to avoid including implicitPadding.
if (!GetDocument().InQuirksMode() &&
- Style()->BoxSizing() != EBoxSizing::kBorderBox) {
+ StyleRef().BoxSizing() != EBoxSizing::kBorderBox) {
style_logical_height +=
(ComputedCSSPaddingBefore() + ComputedCSSPaddingAfter()).Floor() +
(BorderBefore() + BorderAfter()).Floor();
@@ -199,7 +199,7 @@ class CORE_EXPORT LayoutTableCell : public LayoutBlockFlow {
LayoutUnit CellBaselinePosition() const;
bool IsBaselineAligned() const {
- EVerticalAlign va = Style()->VerticalAlign();
+ EVerticalAlign va = StyleRef().VerticalAlign();
return va == EVerticalAlign::kBaseline ||
va == EVerticalAlign::kTextBottom ||
va == EVerticalAlign::kTextTop || va == EVerticalAlign::kSuper ||
@@ -356,8 +356,7 @@ class CORE_EXPORT LayoutTableCell : public LayoutBlockFlow {
const LayoutRect& container_rect,
TouchAction container_whitelisted_touch_action) const override;
- PaintInvalidationReason InvalidatePaint(
- const PaintInvalidatorContext&) const override;
+ void InvalidatePaint(const PaintInvalidatorContext&) const override;
LayoutSize OffsetFromContainerInternal(
const LayoutObject*,
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 d24abbb60c7..f70ca598132 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
@@ -43,8 +43,8 @@ LayoutTableCol::LayoutTableCol(Element* element)
void LayoutTableCol::StyleDidChange(StyleDifference diff,
const ComputedStyle* old_style) {
- DCHECK(Style()->Display() == EDisplay::kTableColumn ||
- Style()->Display() == EDisplay::kTableColumnGroup);
+ DCHECK(StyleRef().Display() == EDisplay::kTableColumn ||
+ StyleRef().Display() == EDisplay::kTableColumnGroup);
LayoutTableBoxComponent::StyleDidChange(diff, old_style);
@@ -58,7 +58,7 @@ void LayoutTableCol::StyleDidChange(StyleDifference diff,
LayoutTableBoxComponent::InvalidateCollapsedBordersOnStyleChange(
*this, *table, diff, *old_style);
- if ((old_style->LogicalWidth() != Style()->LogicalWidth()) ||
+ if ((old_style->LogicalWidth() != StyleRef().LogicalWidth()) ||
LayoutTableBoxComponent::DoCellsHaveDirtyWidth(*this, *table, diff,
*old_style)) {
// TODO(dgrogan): Optimization opportunities:
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 2496e1b4f6f..56634d3d044 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
@@ -68,10 +68,10 @@ class LayoutTableCol final : public LayoutTableBoxComponent {
bool IsTableColumnGroupWithColumnChildren() { return FirstChild(); }
bool IsTableColumn() const {
- return Style()->Display() == EDisplay::kTableColumn;
+ return StyleRef().Display() == EDisplay::kTableColumn;
}
bool IsTableColumnGroup() const {
- return Style()->Display() == EDisplay::kTableColumnGroup;
+ return StyleRef().Display() == EDisplay::kTableColumnGroup;
}
LayoutTableCol* EnclosingColumnGroup() const;
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 a8f12d0d977..3d6f9125d25 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
@@ -53,7 +53,7 @@ void LayoutTableRow::WillBeRemovedFromTree() {
void LayoutTableRow::StyleDidChange(StyleDifference diff,
const ComputedStyle* old_style) {
- DCHECK_EQ(Style()->Display(), EDisplay::kTableRow);
+ DCHECK_EQ(StyleRef().Display(), EDisplay::kTableRow);
LayoutTableBoxComponent::StyleDidChange(diff, old_style);
PropagateStyleToAnonymousChildren();
@@ -61,7 +61,7 @@ void LayoutTableRow::StyleDidChange(StyleDifference diff,
if (!old_style)
return;
- if (Section() && Style()->LogicalHeight() != old_style->LogicalHeight())
+ if (Section() && StyleRef().LogicalHeight() != old_style->LogicalHeight())
Section()->RowLogicalHeightChanged(this);
if (!Parent())
@@ -100,7 +100,7 @@ void LayoutTableRow::StyleDidChange(StyleDifference diff,
// When a row gets collapsed or uncollapsed, it's necessary to check all the
// rows to find any cell that may span the current row.
if ((old_style->Visibility() == EVisibility::kCollapse) !=
- (Style()->Visibility() == EVisibility::kCollapse)) {
+ (StyleRef().Visibility() == EVisibility::kCollapse)) {
for (LayoutTableRow* row = Section()->FirstRow(); row;
row = row->NextRow()) {
for (LayoutTableCell* cell = row->FirstCell(); cell;
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 649d16a7862..f70334f48de 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
@@ -138,7 +138,7 @@ class CORE_EXPORT LayoutTableRow final : public LayoutTableBoxComponent {
PaintLayerType LayerTypeRequired() const override {
if (HasTransformRelatedProperty() || HasHiddenBackface() ||
- CreatesGroup() || Style()->ShouldCompositeForCurrentAnimations() ||
+ CreatesGroup() || StyleRef().ShouldCompositeForCurrentAnimations() ||
IsStickyPositioned())
return kNormalPaintLayer;
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 94b85608727..ca17a55de69 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
@@ -106,9 +106,9 @@ LayoutTableSection::~LayoutTableSection() = default;
void LayoutTableSection::StyleDidChange(StyleDifference diff,
const ComputedStyle* old_style) {
- DCHECK(Style()->Display() == EDisplay::kTableFooterGroup ||
- Style()->Display() == EDisplay::kTableRowGroup ||
- Style()->Display() == EDisplay::kTableHeaderGroup);
+ DCHECK(StyleRef().Display() == EDisplay::kTableFooterGroup ||
+ StyleRef().Display() == EDisplay::kTableRowGroup ||
+ StyleRef().Display() == EDisplay::kTableHeaderGroup);
LayoutTableBoxComponent::StyleDidChange(diff, old_style);
PropagateStyleToAnonymousChildren();
@@ -773,10 +773,9 @@ void LayoutTableSection::DistributeRowSpanHeightToRows(
}
bool LayoutTableSection::RowHasVisibilityCollapse(unsigned row) const {
- return (RuntimeEnabledFeatures::VisibilityCollapseRowEnabled() &&
- ((grid_[row].row &&
- grid_[row].row->Style()->Visibility() == EVisibility::kCollapse) ||
- Style()->Visibility() == EVisibility::kCollapse));
+ return ((grid_[row].row &&
+ grid_[row].row->StyleRef().Visibility() == EVisibility::kCollapse) ||
+ StyleRef().Visibility() == EVisibility::kCollapse);
}
// Find out the baseline of the cell
@@ -1143,7 +1142,7 @@ int LayoutTableSection::DistributeExtraLogicalHeightToRows(
}
bool CellHasExplicitlySpecifiedHeight(const LayoutTableCell& cell) {
- if (cell.Style()->LogicalHeight().IsFixed())
+ if (cell.StyleRef().LogicalHeight().IsFixed())
return true;
LayoutBlock* cb = cell.ContainingBlock();
if (cb->AvailableLogicalHeightForPercentageComputation() == -1)
@@ -1155,8 +1154,8 @@ static bool ShouldFlexCellChild(const LayoutTableCell& cell,
LayoutObject* cell_descendant) {
if (!CellHasExplicitlySpecifiedHeight(cell))
return false;
- if (cell_descendant->Style()->OverflowY() == EOverflow::kVisible ||
- cell_descendant->Style()->OverflowY() == EOverflow::kHidden)
+ if (cell_descendant->StyleRef().OverflowY() == EOverflow::kVisible ||
+ cell_descendant->StyleRef().OverflowY() == EOverflow::kHidden)
return true;
return cell_descendant->IsBox() &&
ToLayoutBox(cell_descendant)->ShouldBeConsideredAsReplaced();
@@ -1245,7 +1244,7 @@ void LayoutTableSection::LayoutRows() {
LayoutUnit(r_height)))
cell_vertical_align = EVerticalAlign::kTop;
else
- cell_vertical_align = cell->Style()->VerticalAlign();
+ cell_vertical_align = cell->StyleRef().VerticalAlign();
// Calculate total collapsed height affecting one cell.
int collapsed_height = 0;
@@ -1272,7 +1271,7 @@ void LayoutTableSection::LayoutRows() {
// need a layout. In this case, we know we're going to issue paint
// invalidations ourselves (and the child) anyway.
if (!Table()->SelfNeedsLayout())
- cell->SetMayNeedPaintInvalidation();
+ cell->SetShouldCheckForPaintInvalidation();
}
}
if (row)
@@ -1904,12 +1903,13 @@ void LayoutTableSection::RelayoutCellIfFlexed(LayoutTableCell& cell,
// as we discover new bugs. :)
bool cell_children_flex = false;
bool flex_all_children = CellHasExplicitlySpecifiedHeight(cell) ||
- (!Table()->Style()->LogicalHeight().IsAuto() &&
+ (!Table()->StyleRef().LogicalHeight().IsAuto() &&
row_height != cell.LogicalHeight());
for (LayoutObject* child = cell.FirstChild(); child;
child = child->NextSibling()) {
- if (!child->IsText() && child->Style()->LogicalHeight().IsPercentOrCalc() &&
+ if (!child->IsText() &&
+ child->StyleRef().LogicalHeight().IsPercentOrCalc() &&
(flex_all_children || ShouldFlexCellChild(cell, child)) &&
(!child->IsTable() || ToLayoutTable(child)->HasSections())) {
cell_children_flex = true;
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 d2226f3991c..ff1d80f7a5b 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
@@ -65,14 +65,14 @@ TEST_F(LayoutTableTest, OverflowWithCollapsedBorders) {
// The table's border box rect covers all collapsed borders of the first
// row, and bottom collapsed borders of the last row.
- LayoutRect expected_border_box_rect = table->ContentBoxRect();
+ LayoutRect expected_border_box_rect = table->PhysicalContentBoxRect();
expected_border_box_rect.ExpandEdges(LayoutUnit(2), LayoutUnit(5),
LayoutUnit(0), LayoutUnit(1));
EXPECT_EQ(expected_border_box_rect, table->BorderBoxRect());
// The table's self visual overflow rect covers all collapsed borders, but
// not visual overflows (outlines) from descendants.
- LayoutRect expected_self_visual_overflow = table->ContentBoxRect();
+ LayoutRect expected_self_visual_overflow = table->PhysicalContentBoxRect();
expected_self_visual_overflow.ExpandEdges(LayoutUnit(2), LayoutUnit(10),
LayoutUnit(0), LayoutUnit(10));
EXPECT_EQ(expected_self_visual_overflow, table->SelfVisualOverflowRect());
@@ -81,7 +81,7 @@ TEST_F(LayoutTableTest, OverflowWithCollapsedBorders) {
// The table's visual overflow covers self visual overflow and content visual
// overflows.
- LayoutRect expected_visual_overflow = table->ContentBoxRect();
+ LayoutRect expected_visual_overflow = table->PhysicalContentBoxRect();
expected_visual_overflow.ExpandEdges(LayoutUnit(6), LayoutUnit(10),
LayoutUnit(8), LayoutUnit(10));
EXPECT_EQ(expected_visual_overflow, table->VisualOverflowRect());
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 bb8a4d4515e..25e07cd1168 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_text.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_text.cc
@@ -50,6 +50,7 @@
#include "third_party/blink/renderer/core/layout/line/glyph_overflow.h"
#include "third_party/blink/renderer/core/layout/line/inline_text_box.h"
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_logical_rect.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/layout_ng_text.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_abstract_inline_text_box.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_node.h"
@@ -131,7 +132,8 @@ LayoutText::LayoutText(Node* node, scoped_refptr<StringImpl> str)
max_width_(-1),
first_line_min_width_(0),
last_line_line_min_width_(0),
- text_(std::move(str)) {
+ text_(std::move(str)),
+ text_boxes_() {
DCHECK(text_);
DCHECK(!node || !node->IsDocumentNode());
@@ -141,9 +143,24 @@ LayoutText::LayoutText(Node* node, scoped_refptr<StringImpl> str)
GetFrameView()->IncrementVisuallyNonEmptyCharacterCount(text_.length());
}
-LayoutText* LayoutText::CreateEmptyAnonymous(Document& doc) {
- LayoutText* text = new LayoutText(nullptr, StringImpl::empty_);
+LayoutText::~LayoutText() {
+#if DCHECK_IS_ON()
+ if (IsInLayoutNGInlineFormattingContext())
+ DCHECK(!first_paint_fragment_);
+ else
+ text_boxes_.AssertIsEmpty();
+#endif
+}
+
+LayoutText* LayoutText::CreateEmptyAnonymous(
+ Document& doc,
+ scoped_refptr<ComputedStyle> style) {
+ LayoutText* text =
+ RuntimeEnabledFeatures::LayoutNGEnabled() && !style->ForceLegacyLayout()
+ ? new LayoutNGText(nullptr, StringImpl::empty_)
+ : new LayoutText(nullptr, StringImpl::empty_);
text->SetDocumentForAnonymous(&doc);
+ text->SetStyle(std::move(style));
return text;
}
@@ -216,19 +233,67 @@ void LayoutText::WillBeDestroyed() {
}
void LayoutText::ExtractTextBox(InlineTextBox* box) {
- text_boxes_.ExtractLineBox(box);
+ MutableTextBoxes().ExtractLineBox(box);
}
void LayoutText::AttachTextBox(InlineTextBox* box) {
- text_boxes_.AttachLineBox(box);
+ MutableTextBoxes().AttachLineBox(box);
}
void LayoutText::RemoveTextBox(InlineTextBox* box) {
- text_boxes_.RemoveLineBox(box);
+ MutableTextBoxes().RemoveLineBox(box);
}
void LayoutText::DeleteTextBoxes() {
- text_boxes_.DeleteLineBoxes();
+ if (IsInLayoutNGInlineFormattingContext())
+ SetFirstInlineFragment(nullptr);
+ else
+ MutableTextBoxes().DeleteLineBoxes();
+}
+
+void LayoutText::SetFirstInlineFragment(NGPaintFragment* first_fragment) {
+ CHECK(IsInLayoutNGInlineFormattingContext());
+ // TODO(layout-dev): Because We should call |WillDestroy()| once for
+ // associated fragments, when you reuse fragments, you should construct
+ // NGAbstractInlineTextBox for them.
+ for (NGPaintFragment* fragment : NGPaintFragment::InlineFragmentsFor(this))
+ NGAbstractInlineTextBox::WillDestroy(fragment);
+ NGPaintFragment::ResetInlineFragmentsFor(this);
+ first_paint_fragment_ = first_fragment;
+}
+
+void LayoutText::InLayoutNGInlineFormattingContextWillChange(bool new_value) {
+ DeleteTextBoxes();
+
+ // 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());
+}
+
+Vector<LayoutText::TextBoxInfo> LayoutText::GetTextBoxInfo() const {
+ Vector<TextBoxInfo> results;
+ if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
+ auto fragments = NGPaintFragment::InlineFragmentsFor(this);
+ if (fragments.IsInLayoutNGInlineFormattingContext()) {
+ for (const NGPaintFragment* fragment : fragments) {
+ const NGPhysicalTextFragment& text_fragment =
+ ToNGPhysicalTextFragment(fragment->PhysicalFragment());
+ results.push_back(TextBoxInfo{
+ {fragment->InlineOffsetToContainerBox().ToLayoutPoint(),
+ text_fragment.Size().ToLayoutSize()},
+ // TODO(kojii): Compute DOM offset, not text content offset.
+ text_fragment.StartOffset(),
+ text_fragment.Length()});
+ }
+ return results;
+ }
+ }
+
+ for (const InlineTextBox* text_box : TextBoxes()) {
+ results.push_back(
+ TextBoxInfo{text_box->FrameRect(), text_box->Start(), text_box->Len()});
+ }
+ return results;
}
base::Optional<FloatPoint> LayoutText::GetUpperLeftCorner() const {
@@ -356,7 +421,6 @@ static IntRect EllipsisRectForBox(InlineTextBox* box,
if (truncation == kCNoTruncation)
return IntRect();
- IntRect rect;
if (EllipsisBox* ellipsis = box->Root().GetEllipsisBox()) {
int ellipsis_start_position = std::max<int>(start_pos - box->Start(), 0);
int ellipsis_end_position =
@@ -380,7 +444,7 @@ void LayoutText::AccumlateQuads(Vector<FloatQuad>& quads,
const LayoutRect& passed_boundaries) const {
FloatRect boundaries(passed_boundaries);
if (!ellipsis_rect.IsEmpty()) {
- if (Style()->IsHorizontalWritingMode())
+ if (StyleRef().IsHorizontalWritingMode())
boundaries.SetWidth(ellipsis_rect.MaxX() - boundaries.X());
else
boundaries.SetHeight(ellipsis_rect.MaxY() - boundaries.Y());
@@ -480,6 +544,18 @@ void LayoutText::AbsoluteQuadsForRange(Vector<FloatQuad>& quads,
if (!MapDOMOffsetToTextContentOffset(*mapping, &start, &end))
return;
+ // We don't want to add collapsed (i.e., start == end) quads from text
+ // fragments that intersect [start, end] only at the boundary, unless they
+ // are the only quads found. For example, when we have
+ // - text fragments: ABC DEF GHI
+ // - text offsets: 012 345 678
+ // and input range [3, 6], since fragment "DEF" gives non-collapsed quad,
+ // we no longer add quads from "ABC" and "GHI" since they are collapsed.
+ // TODO(layout-dev): This heuristic doesn't cover all cases, as we return
+ // 2 collapsed quads (instead of 1) for range [3, 3] in the above example.
+ bool found_non_collapsed_quad = false;
+ Vector<FloatQuad, 1> collapsed_quads_candidates;
+
// Find fragments that have text for the specified range.
DCHECK_LE(start, end);
auto fragments = NGPaintFragment::InlineFragmentsFor(this);
@@ -489,12 +565,22 @@ void LayoutText::AbsoluteQuadsForRange(Vector<FloatQuad>& quads,
if (start > text_fragment.EndOffset() ||
end < text_fragment.StartOffset())
continue;
+ const unsigned clamped_start =
+ std::max(start, text_fragment.StartOffset());
+ const unsigned clamped_end = std::min(end, text_fragment.EndOffset());
NGPhysicalOffsetRect rect =
- text_fragment.LocalRect(std::max(start, text_fragment.StartOffset()),
- std::min(end, text_fragment.EndOffset()));
+ text_fragment.LocalRect(clamped_start, clamped_end);
rect.offset += fragment->InlineOffsetToContainerBox();
- quads.push_back(LocalToAbsoluteQuad(rect.ToFloatRect()));
+ const FloatQuad quad = LocalToAbsoluteQuad(rect.ToFloatRect());
+ if (clamped_start < clamped_end) {
+ quads.push_back(quad);
+ found_non_collapsed_quad = true;
+ } else {
+ collapsed_quads_candidates.push_back(quad);
+ }
}
+ if (!found_non_collapsed_quad)
+ quads.AppendVector(collapsed_quads_candidates);
return;
}
@@ -661,7 +747,7 @@ PositionWithAffinity LayoutText::PositionForPoint(
FirstTextBox()->IsHorizontal() ? point.X() : point.Y();
LayoutUnit point_block_direction =
FirstTextBox()->IsHorizontal() ? point.Y() : point.X();
- bool blocks_are_flipped = Style()->IsFlippedBlocksWritingMode();
+ bool blocks_are_flipped = StyleRef().IsFlippedBlocksWritingMode();
InlineTextBox* last_box = nullptr;
for (InlineTextBox* box : TextBoxes()) {
@@ -791,7 +877,7 @@ LayoutRect LayoutText::LocalCaretRect(
// for unicode-bidi: plaintext, use inlineBoxBidiLevel() to test the correct
// direction for the cursor.
- if (right_aligned && Style()->GetUnicodeBidi() == UnicodeBidi::kPlaintext) {
+ if (right_aligned && StyleRef().GetUnicodeBidi() == UnicodeBidi::kPlaintext) {
if (inline_box->BidiLevel() % 2 != 1)
right_aligned = false;
}
@@ -805,7 +891,7 @@ LayoutRect LayoutText::LocalCaretRect(
}
return LayoutRect(
- Style()->IsHorizontalWritingMode()
+ StyleRef().IsHorizontalWritingMode()
? IntRect(left.ToInt(), top, caret_width.ToInt(), height)
: IntRect(top, left.ToInt(), height, caret_width.ToInt()));
}
@@ -820,7 +906,7 @@ ALWAYS_INLINE float LayoutText::WidthFromFont(
HashSet<const SimpleFontData*>* fallback_fonts,
FloatRect* glyph_bounds_accumulation,
float expansion) const {
- if (Style()->HasTextCombine() && IsCombineText()) {
+ if (StyleRef().HasTextCombine() && IsCombineText()) {
const LayoutTextCombine* combine_text = ToLayoutTextCombine(this);
if (combine_text->IsCombined())
return combine_text->CombinedTextWidth(f);
@@ -830,7 +916,7 @@ ALWAYS_INLINE float LayoutText::WidthFromFont(
ConstructTextRun(f, this, start, len, StyleRef(), text_direction);
run.SetCharactersLength(TextLength() - start);
DCHECK_GE(run.CharactersLength(), run.length());
- run.SetTabSize(!Style()->CollapseWhiteSpace(), Style()->GetTabSize());
+ run.SetTabSize(!StyleRef().CollapseWhiteSpace(), StyleRef().GetTabSize());
run.SetXPos(lead_width + text_width_so_far);
run.SetExpansion(expansion);
@@ -864,7 +950,7 @@ void LayoutText::TrimmedPrefWidths(LayoutUnit lead_width_layout_unit,
// below.
float lead_width = lead_width_layout_unit.ToFloat();
- bool collapse_white_space = Style()->CollapseWhiteSpace();
+ bool collapse_white_space = StyleRef().CollapseWhiteSpace();
if (!collapse_white_space)
strip_front_spaces = false;
@@ -900,9 +986,9 @@ void LayoutText::TrimmedPrefWidths(LayoutUnit lead_width_layout_unit,
DCHECK(text_);
StringImpl& text = *text_.Impl();
if (text[0] == kSpaceCharacter ||
- (text[0] == kNewlineCharacter && !Style()->PreserveNewline()) ||
+ (text[0] == kNewlineCharacter && !StyleRef().PreserveNewline()) ||
text[0] == kTabulationCharacter) {
- const Font& font = Style()->GetFont(); // FIXME: This ignores first-line.
+ const Font& font = StyleRef().GetFont(); // FIXME: This ignores first-line.
if (strip_front_spaces) {
const UChar kSpaceChar = kSpaceCharacter;
TextRun run =
@@ -916,12 +1002,12 @@ void LayoutText::TrimmedPrefWidths(LayoutUnit lead_width_layout_unit,
strip_front_spaces = collapse_white_space && has_end_white_space_;
- if (!Style()->AutoWrap() || float_min_width > float_max_width)
+ if (!StyleRef().AutoWrap() || float_min_width > float_max_width)
float_min_width = float_max_width;
// Compute our max widths by scanning the string for newlines.
if (has_break) {
- const Font& f = Style()->GetFont(); // FIXME: This ignores first-line.
+ const Font& f = StyleRef().GetFont(); // FIXME: This ignores first-line.
bool first_line = true;
first_line_max_width = LayoutUnit(float_max_width);
last_line_max_width = LayoutUnit(float_max_width);
@@ -1346,7 +1432,7 @@ void LayoutText::ComputePreferredLogicalWidths(
} else {
// Nowrap can never be broken, so don't bother setting the breakable
// character boolean. Pre can only be broken if we encounter a newline.
- if (Style()->AutoWrap() || is_newline)
+ if (StyleRef().AutoWrap() || is_newline)
has_breakable_char_ = true;
if (curr_min_width > min_width_)
@@ -1370,7 +1456,8 @@ void LayoutText::ComputePreferredLogicalWidths(
ConstructTextRun(f, this, i, 1, style_to_use, text_direction);
run.SetCharactersLength(len - i);
DCHECK_GE(run.CharactersLength(), run.length());
- run.SetTabSize(!Style()->CollapseWhiteSpace(), Style()->GetTabSize());
+ run.SetTabSize(!StyleRef().CollapseWhiteSpace(),
+ StyleRef().GetTabSize());
run.SetXPos(lead_width + curr_max_width);
curr_max_width += f.Width(run);
@@ -1414,13 +1501,13 @@ bool LayoutText::IsAllCollapsibleWhitespace() const {
unsigned length = TextLength();
if (Is8Bit()) {
for (unsigned i = 0; i < length; ++i) {
- if (!Style()->IsCollapsibleWhiteSpace(Characters8()[i]))
+ if (!StyleRef().IsCollapsibleWhiteSpace(Characters8()[i]))
return false;
}
return true;
}
for (unsigned i = 0; i < length; ++i) {
- if (!Style()->IsCollapsibleWhiteSpace(Characters16()[i]))
+ if (!StyleRef().IsCollapsibleWhiteSpace(Characters16()[i]))
return false;
}
return true;
@@ -1469,6 +1556,23 @@ float LayoutText::FirstRunY() const {
return FirstTextBox() ? FirstTextBox()->Y().ToFloat() : 0;
}
+bool LayoutText::CanOptimizeSetText() const {
+ // If we have only one line of text and "contain: layout size" we can avoid
+ // doing a layout and only paint in the SetText() operation.
+ return Parent()->IsLayoutBlockFlow() &&
+ (Parent()->ShouldApplyLayoutContainment() &&
+ Parent()->ShouldApplySizeContainment()) &&
+ FirstTextBox() &&
+ (FirstTextBox() == LastTextBox() &&
+ // If "line-height" is "normal" we might need to recompute the
+ // baseline which is not straight forward.
+ !StyleRef().LineHeight().IsNegative() &&
+ // We would need to recompute the position if "direction" is "rtl" or
+ // "text-align" is not the default one.
+ StyleRef().IsLeftToRightDirection() &&
+ (StyleRef().GetTextAlign(true) == ETextAlign::kStart));
+}
+
void LayoutText::SetTextWithOffset(scoped_refptr<StringImpl> text,
unsigned offset,
unsigned len,
@@ -1476,6 +1580,31 @@ void LayoutText::SetTextWithOffset(scoped_refptr<StringImpl> text,
if (!force && Equal(text_.Impl(), text.get()))
return;
+ if (CanOptimizeSetText() &&
+ // Check that we are replacing the whole text.
+ offset == 0 && len == TextLength()) {
+ const ComputedStyle* style_to_use =
+ FirstTextBox()->GetLineLayoutItem().Style(
+ FirstTextBox()->IsFirstLineStyle());
+ TextRun text_run = TextRun(String(text));
+ text_run.SetTabSize(!style_to_use->CollapseWhiteSpace(),
+ style_to_use->GetTabSize());
+ FloatRect glyph_bounds;
+ float text_width =
+ style_to_use->GetFont().Width(text_run, nullptr, &glyph_bounds);
+ // TODO(rego): We could avoid measuring text width in some specific
+ // situations (e.g. if "white-space" property is "pre" and "overflow-wrap"
+ // is "normal").
+ if (text_width <= ContainingBlock()->ContentLogicalWidth()) {
+ FirstTextBox()->ManuallySetStartLenAndLogicalWidth(
+ offset, text->length(), LayoutUnit(text_width));
+ SetText(std::move(text), force, true);
+ lines_dirty_ = false;
+ valid_ng_items_ = false;
+ return;
+ }
+ }
+
unsigned old_len = TextLength();
unsigned new_len = text->length();
int delta = new_len - old_len;
@@ -1655,7 +1784,9 @@ void LayoutText::SecureText(UChar mask) {
}
}
-void LayoutText::SetText(scoped_refptr<StringImpl> text, bool force) {
+void LayoutText::SetText(scoped_refptr<StringImpl> text,
+ bool force,
+ bool avoid_layout_and_only_paint) {
DCHECK(text);
if (!force && Equal(text_.Impl(), text.get()))
@@ -1667,8 +1798,12 @@ void LayoutText::SetText(scoped_refptr<StringImpl> text, bool force) {
// To avoid that, we call setNeedsLayoutAndPrefWidthsRecalc() only if this
// LayoutText has parent.
if (Parent()) {
- SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
- LayoutInvalidationReason::kTextChanged);
+ if (avoid_layout_and_only_paint) {
+ SetShouldDoFullPaintInvalidation();
+ } else {
+ SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
+ LayoutInvalidationReason::kTextChanged);
+ }
}
known_to_have_no_overflow_and_no_fallback_fonts_ = false;
@@ -1705,7 +1840,7 @@ InlineTextBox* LayoutText::CreateTextBox(int start, unsigned short length) {
InlineTextBox* LayoutText::CreateInlineTextBox(int start,
unsigned short length) {
InlineTextBox* text_box = CreateTextBox(start, length);
- text_boxes_.AppendLineBox(text_box);
+ MutableTextBoxes().AppendLineBox(text_box);
return text_box;
}
@@ -1716,7 +1851,7 @@ void LayoutText::PositionLineBox(InlineBox* box) {
if (!s->Len()) {
// We want the box to be destroyed.
s->Remove(kDontMarkLineBoxes);
- text_boxes_.RemoveLineBox(s);
+ MutableTextBoxes().RemoveLineBox(s);
s->Destroy();
return;
}
@@ -1760,8 +1895,8 @@ float LayoutText::Width(unsigned from,
return 0;
float w;
- if (&f == &Style()->GetFont()) {
- if (!Style()->PreserveNewline() && !from && len == TextLength()) {
+ if (&f == &StyleRef().GetFont()) {
+ if (!StyleRef().PreserveNewline() && !from && len == TextLength()) {
if (fallback_fonts) {
DCHECK(glyph_bounds);
if (PreferredLogicalWidthsDirty() ||
@@ -1787,7 +1922,7 @@ float LayoutText::Width(unsigned from,
run.SetCharactersLength(TextLength() - from);
DCHECK_GE(run.CharactersLength(), run.length());
- run.SetTabSize(!Style()->CollapseWhiteSpace(), Style()->GetTabSize());
+ run.SetTabSize(!StyleRef().CollapseWhiteSpace(), StyleRef().GetTabSize());
run.SetXPos(x_pos.ToFloat());
w = f.Width(run, fallback_fonts, glyph_bounds);
}
@@ -1802,7 +1937,7 @@ LayoutRect LayoutText::LinesBoundingBox() const {
auto children =
NGInlineFragmentTraversal::SelfFragmentsOf(*box_fragment, this);
for (const auto& child : children)
- bounding_box.Unite(child.RectInContainerBox());
+ bounding_box.UniteIfNonZero(child.RectInContainerBox());
return bounding_box.ToLayoutRect();
}
@@ -1821,7 +1956,7 @@ LayoutRect LayoutText::LinesBoundingBox() const {
logical_right_side = curr->LogicalRight().ToFloat();
}
- bool is_horizontal = Style()->IsHorizontalWritingMode();
+ bool is_horizontal = StyleRef().IsHorizontalWritingMode();
float x = is_horizontal ? logical_left_side : FirstTextBox()->X().ToFloat();
float y = is_horizontal ? FirstTextBox()->Y().ToFloat() : logical_left_side;
@@ -1875,7 +2010,7 @@ LayoutRect LayoutText::VisualOverflowRect() const {
LayoutRect rect(logical_left_side, logical_top, logical_width,
logical_height);
- if (!Style()->IsHorizontalWritingMode())
+ if (!StyleRef().IsHorizontalWritingMode())
rect = rect.TransposedRect();
return rect;
}
@@ -1916,29 +2051,10 @@ LayoutRect LayoutText::LocalSelectionRect() const {
return rect;
}
- // Now calculate startPos and endPos for painting selection.
- // We include a selection while endPos > 0
- unsigned start_pos, end_pos;
- if (GetSelectionState() == SelectionState::kInside) {
- // We are fully selected.
- start_pos = 0;
- end_pos = TextLength();
- } else {
- if (GetSelectionState() == SelectionState::kStart) {
- // TODO(yoichio): value_or is used to prevent use uininitialized value
- // on release. It should be value() after LayoutSelection brushup.
- start_pos = frame_selection.LayoutSelectionStart().value_or(0);
- end_pos = TextLength();
- } else if (GetSelectionState() == SelectionState::kEnd) {
- start_pos = 0;
- end_pos = frame_selection.LayoutSelectionEnd().value_or(0);
- } else {
- DCHECK(GetSelectionState() == SelectionState::kStartAndEnd);
- start_pos = frame_selection.LayoutSelectionStart().value_or(0);
- end_pos = frame_selection.LayoutSelectionEnd().value_or(0);
- }
- }
-
+ const LayoutTextSelectionStatus& selection_status =
+ frame_selection.ComputeLayoutSelectionStatus(*this);
+ const unsigned start_pos = selection_status.start;
+ const unsigned end_pos = selection_status.end;
DCHECK_LE(start_pos, end_pos);
LayoutRect rect;
for (InlineTextBox* box : TextBoxes()) {
@@ -2268,7 +2384,6 @@ LayoutRect LayoutText::DebugRect() const {
FloatPoint first_run_offset;
if (const NGPhysicalBoxFragment* box_fragment =
EnclosingBlockFlowFragment()) {
- NGPhysicalOffsetRect bounding_box;
const auto fragments =
NGInlineFragmentTraversal::SelfFragmentsOf(*box_fragment, this);
if (fragments.size()) {
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 c5773395249..2abf772bad6 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_text.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_text.h
@@ -77,7 +77,10 @@ class CORE_EXPORT LayoutText : public LayoutObject {
// doesn't re-transform the string.
LayoutText(Node*, scoped_refptr<StringImpl>);
- static LayoutText* CreateEmptyAnonymous(Document&);
+ ~LayoutText() override;
+
+ static LayoutText* CreateEmptyAnonymous(Document&,
+ scoped_refptr<ComputedStyle>);
const char* GetName() const override { return "LayoutText"; }
@@ -90,6 +93,9 @@ class CORE_EXPORT LayoutText : public LayoutObject {
void AttachTextBox(InlineTextBox*);
void RemoveTextBox(InlineTextBox*);
+ NGPaintFragment* FirstInlineFragment() const final;
+ void SetFirstInlineFragment(NGPaintFragment*) final;
+
const String& GetText() const { return text_; }
virtual unsigned TextStartOffset() const { return 0; }
String PlainText() const;
@@ -184,7 +190,9 @@ class CORE_EXPORT LayoutText : public LayoutObject {
float FirstRunX() const;
float FirstRunY() const;
- virtual void SetText(scoped_refptr<StringImpl>, bool force = false);
+ virtual void SetText(scoped_refptr<StringImpl>,
+ bool force = false,
+ bool avoid_layout_and_only_paint = false);
void SetTextWithOffset(scoped_refptr<StringImpl>,
unsigned offset,
unsigned len,
@@ -202,13 +210,18 @@ class CORE_EXPORT LayoutText : public LayoutObject {
int caret_offset,
LayoutUnit* extra_width_to_end_of_line = nullptr) const override;
- const InlineTextBoxList& TextBoxes() const { return text_boxes_; }
+ // TextBoxes() and FirstInlineFragment() are mutually exclusive,
+ // depends on IsInLayoutNGInlineFormattingContext().
+ const InlineTextBoxList& TextBoxes() const {
+ return IsInLayoutNGInlineFormattingContext() ? InlineTextBoxList::Empty()
+ : text_boxes_;
+ }
// Returns first |InlineTextBox| produces for associated |Node|.
// Note: When |this| is remaining part of ::first-letter, this function
// returns first-letter part of |InlineTextBox| instead of remaining part.
- InlineTextBox* FirstTextBox() const { return text_boxes_.First(); }
- InlineTextBox* LastTextBox() const { return text_boxes_.Last(); }
+ InlineTextBox* FirstTextBox() const { return TextBoxes().First(); }
+ InlineTextBox* LastTextBox() const { return TextBoxes().Last(); }
// Returns upper left corner point in local physical coordinates with flipped
// block-flow direction if this object has rendered text.
@@ -222,6 +235,14 @@ class CORE_EXPORT LayoutText : public LayoutObject {
// All callers should call HasTextBoxes instead, and take NG into account.
bool HasLegacyTextBoxes() const { return FirstTextBox(); }
+ // Compute the rect and offset of text boxes for this LayoutText.
+ struct TextBoxInfo {
+ LayoutRect local_rect;
+ unsigned dom_start_offset;
+ unsigned dom_length;
+ };
+ Vector<TextBoxInfo> GetTextBoxInfo() const;
+
// Returns the Position in DOM that corresponds to the given offset in the
// |text_| string.
// TODO(layout-dev): Fix it when text-transform changes text length.
@@ -255,7 +276,7 @@ class CORE_EXPORT LayoutText : public LayoutObject {
bool ContainsReversedText() const { return contains_reversed_text_; }
bool IsSecure() const {
- return Style()->TextSecurity() != ETextSecurity::kNone;
+ return StyleRef().TextSecurity() != ETextSecurity::kNone;
}
void MomentarilyRevealLastTypedCharacter(
unsigned last_typed_character_offset);
@@ -299,6 +320,8 @@ class CORE_EXPORT LayoutText : public LayoutObject {
void StyleWillChange(StyleDifference, const ComputedStyle&) final {}
void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
+ void InLayoutNGInlineFormattingContextWillChange(bool) final;
+
void AddLayerHitTestRects(
LayerHitTestRects&,
const PaintLayer* current_layer,
@@ -316,6 +339,8 @@ class CORE_EXPORT LayoutText : public LayoutObject {
bool CanBeSelectionLeafInternal() const final { return true; }
private:
+ InlineTextBoxList& MutableTextBoxes();
+
void AccumlateQuads(Vector<FloatQuad>&,
const IntRect& ellipsis_rect,
LocalOrAbsoluteOption,
@@ -362,6 +387,8 @@ class CORE_EXPORT LayoutText : public LayoutObject {
LayoutRect LocalVisualRectIgnoringVisibility() const final;
+ bool CanOptimizeSetText() const;
+
// We put the bitfield first to minimize padding on 64-bit.
protected:
// Whether or not we can be broken into multiple lines.
@@ -398,11 +425,27 @@ class CORE_EXPORT LayoutText : public LayoutObject {
String text_;
- // The line boxes associated with this object.
- // Read the LINE BOXES OWNERSHIP section in the class header comment.
- InlineTextBoxList text_boxes_;
+ union {
+ // The line boxes associated with this object.
+ // Read the LINE BOXES OWNERSHIP section in the class header comment.
+ // Valid only when !IsInLayoutNGInlineFormattingContext().
+ InlineTextBoxList text_boxes_;
+ // The first fragment of text boxes associated with this object.
+ // Valid only when IsInLayoutNGInlineFormattingContext().
+ scoped_refptr<NGPaintFragment> first_paint_fragment_;
+ };
};
+inline InlineTextBoxList& LayoutText::MutableTextBoxes() {
+ CHECK(!IsInLayoutNGInlineFormattingContext());
+ return text_boxes_;
+}
+
+inline NGPaintFragment* LayoutText::FirstInlineFragment() const {
+ return IsInLayoutNGInlineFormattingContext() ? first_paint_fragment_.get()
+ : nullptr;
+}
+
inline UChar LayoutText::UncheckedCharacterAt(unsigned i) const {
SECURITY_DCHECK(i < TextLength());
return Is8Bit() ? Characters8()[i] : Characters16()[i];
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 dde546fa0ee..4056a1f163d 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
@@ -149,7 +149,7 @@ void LayoutTextCombine::TransformToInlineCoordinates(GraphicsContext& context,
void LayoutTextCombine::UpdateIsCombined() {
// CSS3 spec says text-combine works only in vertical writing mode.
- is_combined_ = !Style()->IsHorizontalWritingMode()
+ is_combined_ = !StyleRef().IsHorizontalWritingMode()
// Nothing to combine.
&& !HasEmptyText();
}
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_text_combine.h b/chromium/third_party/blink/renderer/core/layout/layout_text_combine.h
index 9ad8dc9fa11..d356152a9da 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_text_combine.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_text_combine.h
@@ -39,7 +39,7 @@ class LayoutTextCombine final : public LayoutText {
float CombinedTextWidth(const Font& font) const {
return font.GetFontDescription().ComputedSize();
}
- const Font& OriginalFont() const { return Parent()->Style()->GetFont(); }
+ const Font& OriginalFont() const { return Parent()->StyleRef().GetFont(); }
void TransformToInlineCoordinates(GraphicsContext&,
const LayoutRect& box_rect,
bool clip = false) const;
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 5799f09fddd..42e01965496 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
@@ -26,7 +26,7 @@
#include "third_party/blink/renderer/core/html/forms/text_control_element.h"
#include "third_party/blink/renderer/core/layout/hit_test_result.h"
#include "third_party/blink/renderer/core/page/page.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
namespace blink {
@@ -108,9 +108,9 @@ void LayoutTextControl::ComputeLogicalHeight(
// We are able to have a horizontal scrollbar if the overflow style is
// scroll, or if its auto and there's no word wrap.
- if (Style()->OverflowInlineDirection() == EOverflow::kScroll ||
- (Style()->OverflowInlineDirection() == EOverflow::kAuto &&
- inner_editor->GetLayoutObject()->Style()->OverflowWrap() ==
+ if (StyleRef().OverflowInlineDirection() == EOverflow::kScroll ||
+ (StyleRef().OverflowInlineDirection() == EOverflow::kAuto &&
+ inner_editor->GetLayoutObject()->StyleRef().OverflowWrap() ==
EOverflowWrap::kNormal))
logical_height += ScrollbarThickness();
@@ -214,7 +214,7 @@ bool LayoutTextControl::HasValidAvgCharWidth(const SimpleFontData* font_data,
}
float LayoutTextControl::GetAvgCharWidth(const AtomicString& family) const {
- const Font& font = Style()->GetFont();
+ const Font& font = StyleRef().GetFont();
const SimpleFontData* primary_font = font.PrimaryFont();
if (primary_font && HasValidAvgCharWidth(primary_font, family))
@@ -231,7 +231,7 @@ float LayoutTextControl::ScaleEmToUnits(int x) const {
// This matches the unitsPerEm value for MS Shell Dlg and Courier New from the
// "head" font table.
float units_per_em = 2048.0f;
- return roundf(Style()->GetFont().GetFontDescription().ComputedSize() * x /
+ return roundf(StyleRef().GetFont().GetFontDescription().ComputedSize() * x /
units_per_em);
}
@@ -240,7 +240,7 @@ void LayoutTextControl::ComputeIntrinsicLogicalWidths(
LayoutUnit& max_logical_width) const {
// Use average character width. Matches IE.
AtomicString family =
- Style()->GetFont().GetFontDescription().Family().Family();
+ StyleRef().GetFont().GetFontDescription().Family().Family();
max_logical_width = PreferredContentLogicalWidth(
const_cast<LayoutTextControl*>(this)->GetAvgCharWidth(family));
if (InnerEditorElement()) {
@@ -249,7 +249,7 @@ void LayoutTextControl::ComputeIntrinsicLogicalWidths(
max_logical_width += inner_editor_layout_box->PaddingStart() +
inner_editor_layout_box->PaddingEnd();
}
- if (!Style()->LogicalWidth().IsPercentOrCalc())
+ if (!StyleRef().LogicalWidth().IsPercentOrCalc())
min_logical_width = max_logical_width;
}
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 f01b6cd9f56..4774cfda147 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
@@ -195,7 +195,7 @@ bool LayoutTextControlSingleLine::HasControlClip() const {
LayoutRect LayoutTextControlSingleLine::ControlClipRect(
const LayoutPoint& additional_offset) const {
- LayoutRect clip_rect = PaddingBoxRect();
+ LayoutRect clip_rect = PhysicalPaddingBoxRect();
clip_rect.MoveBy(additional_offset);
return clip_rect;
}
@@ -223,7 +223,7 @@ LayoutUnit LayoutTextControlSingleLine::PreferredContentLogicalWidth(
LayoutUnit result = LayoutUnit::FromFloatCeil(char_width * factor);
float max_char_width = 0.f;
- const Font& font = Style()->GetFont();
+ const Font& font = StyleRef().GetFont();
AtomicString family = font.GetFontDescription().Family().Family();
// Match the default system font to the width of MS Shell Dlg, the default
// font for textareas in Firefox, Safari Win and IE for some encodings (in
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_text_fragment.cc b/chromium/third_party/blink/renderer/core/layout/layout_text_fragment.cc
index 1e34a60f88c..5e37b07d5da 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_text_fragment.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_text_fragment.cc
@@ -92,8 +92,10 @@ scoped_refptr<StringImpl> LayoutTextFragment::OriginalText() const {
return result->Substring(Start(), FragmentLength());
}
-void LayoutTextFragment::SetText(scoped_refptr<StringImpl> text, bool force) {
- LayoutText::SetText(std::move(text), force);
+void LayoutTextFragment::SetText(scoped_refptr<StringImpl> text,
+ bool force,
+ bool avoid_layout_and_only_paint) {
+ LayoutText::SetText(std::move(text), force, avoid_layout_and_only_paint);
start_ = 0;
fragment_length_ = TextLength();
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_text_fragment.h b/chromium/third_party/blink/renderer/core/layout/layout_text_fragment.h
index 42bcacb1f1f..56272e472ea 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_text_fragment.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_text_fragment.h
@@ -70,7 +70,9 @@ class CORE_EXPORT LayoutTextFragment final : public LayoutText {
scoped_refptr<StringImpl> OriginalText() const override;
- void SetText(scoped_refptr<StringImpl>, bool force = false) override;
+ void SetText(scoped_refptr<StringImpl>,
+ bool force = false,
+ bool avoid_layout_and_only_paint = false) override;
void SetTextFragment(scoped_refptr<StringImpl>,
unsigned start,
unsigned length);
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 5511b99eb41..bcc7bebc531 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
@@ -650,7 +650,7 @@ TEST_P(ParameterizedLayoutTextTest, LocalSelectionRectLineBreakPre) {
LayoutRect(30, 0, 10, 10),
GetSelectionRectFor("<div style='white-space:pre;'>foo^\n|\nbar</div>"));
EXPECT_EQ(
- LayoutNGEnabled() ? LayoutRect(0, 10, 10, 10) : LayoutRect(0, 0, 50, 20),
+ LayoutRect(0, 10, 10, 10),
GetSelectionRectFor("<div style='white-space:pre;'>foo\n^\n|bar</div>"));
}
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 4bd730e8b3a..8416290da02 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_theme.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_theme.cc
@@ -21,6 +21,11 @@
#include "third_party/blink/renderer/core/layout/layout_theme.h"
+#include <string>
+
+#include "base/feature_list.h"
+#include "base/metrics/field_trial_params.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_rect.h"
#include "third_party/blink/public/web/blink.h"
@@ -51,6 +56,7 @@
#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/color.h"
#include "third_party/blink/renderer/platform/graphics/touch_action.h"
#include "third_party/blink/renderer/platform/layout_test_support.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
@@ -63,6 +69,36 @@
namespace blink {
+namespace {
+
+void GetAutofillPreviewColorsFromFieldTrial(std::string* color,
+ std::string* background_color) {
+ constexpr char kAutofillDefaultBackgroundColor[] = "#FAFFBD";
+ constexpr char kAutofillDefaultColor[] = "#000000";
+
+ if (base::FeatureList::IsEnabled(features::kAutofillPreviewStyleExperiment)) {
+ std::string bg_color_param = base::GetFieldTrialParamValueByFeature(
+ features::kAutofillPreviewStyleExperiment,
+ features::kAutofillPreviewStyleExperimentBgColorParameterName);
+ std::string color_param = base::GetFieldTrialParamValueByFeature(
+ features::kAutofillPreviewStyleExperiment,
+ features::kAutofillPreviewStyleExperimentColorParameterName);
+ if (Color().SetFromString(bg_color_param.c_str()) &&
+ Color().SetFromString(color_param.c_str())) {
+ *background_color = bg_color_param;
+ *color = color_param;
+ return;
+ }
+ }
+
+ // Fallback to the default colors if the experiment is not enabled or if a
+ // color param is invalid.
+ *background_color = std::string(kAutofillDefaultBackgroundColor);
+ *color = std::string(kAutofillDefaultColor);
+}
+
+} // namespace
+
// Wrapper function defined in WebKit.h
void SetMockThemeEnabledForTest(bool value) {
LayoutTestSupport::SetMockThemeEnabledForTest(value);
@@ -264,7 +300,16 @@ void LayoutTheme::AdjustStyle(ComputedStyle& style, Element* e) {
}
String LayoutTheme::ExtraDefaultStyleSheet() {
- return g_empty_string;
+ std::string color, background_color;
+ GetAutofillPreviewColorsFromFieldTrial(&color, &background_color);
+ constexpr char const format[] =
+ "input:-webkit-autofill, textarea:-webkit-autofill, "
+ "select:-webkit-autofill {"
+ " background-color: %s !important;"
+ " background-image:none !important;"
+ " color: %s !important;"
+ "}";
+ return String::Format(format, background_color.c_str(), color.c_str());
}
String LayoutTheme::ExtraQuirksStyleSheet() {
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 363ef2d9a7d..61e2790d404 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_theme.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_theme.h
@@ -45,7 +45,7 @@ class HTMLInputElement;
class LengthSize;
class Locale;
class Node;
-class PlatformChromeClient;
+class ChromeClient;
class Theme;
class ThemePainter;
@@ -190,7 +190,7 @@ class CORE_EXPORT LayoutTheme : public RefCounted<LayoutTheme> {
virtual int PopupInternalPaddingStart(const ComputedStyle&) const {
return 0;
}
- virtual int PopupInternalPaddingEnd(const PlatformChromeClient*,
+ virtual int PopupInternalPaddingEnd(const ChromeClient*,
const ComputedStyle&) const {
return 0;
}
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 1c2a0a8b5d5..18bd95dfb4c 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
@@ -28,11 +28,11 @@
#include "third_party/blink/public/platform/web_theme_engine.h"
#include "third_party/blink/renderer/core/css_value_keywords.h"
#include "third_party/blink/renderer/core/layout/layout_theme_font_provider.h"
+#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
#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/layout_test_support.h"
-#include "third_party/blink/renderer/platform/platform_chrome_client.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
namespace blink {
@@ -317,7 +317,7 @@ int LayoutThemeDefault::PopupInternalPaddingStart(
}
int LayoutThemeDefault::PopupInternalPaddingEnd(
- const PlatformChromeClient* client,
+ const ChromeClient* client,
const ComputedStyle& style) const {
if (style.Appearance() == kNoControlPart)
return 0;
@@ -344,7 +344,7 @@ int LayoutThemeDefault::MenuListArrowWidthInDIP() const {
}
float LayoutThemeDefault::ClampedMenuListArrowPaddingSize(
- const PlatformChromeClient* client,
+ const ChromeClient* client,
const ComputedStyle& style) const {
if (cached_menu_list_arrow_padding_size_ > 0 &&
style.EffectiveZoom() == cached_menu_list_arrow_zoom_level_)
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 994d74e81f6..fcbd0533a13 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
@@ -112,7 +112,7 @@ class CORE_EXPORT LayoutThemeDefault : public LayoutTheme {
// These methods define the padding for the MenuList's inner block.
int PopupInternalPaddingStart(const ComputedStyle&) const override;
- int PopupInternalPaddingEnd(const PlatformChromeClient*,
+ int PopupInternalPaddingEnd(const ChromeClient*,
const ComputedStyle&) const override;
int PopupInternalPaddingTop(const ComputedStyle&) const override;
int PopupInternalPaddingBottom(const ComputedStyle&) const override;
@@ -121,7 +121,7 @@ class CORE_EXPORT LayoutThemeDefault : public LayoutTheme {
// thickness, which is 3px or 4px, and we use the value from the default Aura
// theme.
int MenuListArrowWidthInDIP() const;
- float ClampedMenuListArrowPaddingSize(const PlatformChromeClient*,
+ float ClampedMenuListArrowPaddingSize(const ChromeClient*,
const ComputedStyle&) const;
static void SetSelectionColors(unsigned active_background_color,
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 6ec0a66a931..15b4973104a 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
@@ -77,7 +77,7 @@ class LayoutThemeMac final : public LayoutTheme {
int SliderTickOffsetFromTrackCenter() const override;
int PopupInternalPaddingStart(const ComputedStyle&) const override;
- int PopupInternalPaddingEnd(const PlatformChromeClient*,
+ int PopupInternalPaddingEnd(const ChromeClient*,
const ComputedStyle&) const override;
int PopupInternalPaddingTop(const ComputedStyle&) const override;
int PopupInternalPaddingBottom(const ComputedStyle&) const override;
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 00c31f0fcf5..3c60c8a5e53 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
@@ -761,7 +761,7 @@ int LayoutThemeMac::PopupInternalPaddingStart(
return 0;
}
-int LayoutThemeMac::PopupInternalPaddingEnd(const PlatformChromeClient*,
+int LayoutThemeMac::PopupInternalPaddingEnd(const ChromeClient*,
const ComputedStyle& style) const {
if (style.Appearance() == kMenulistPart)
return PopupButtonPadding(
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 f589fe02384..71941d1a546 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
@@ -156,8 +156,8 @@ void LayoutTreeAsText::WriteLayoutObject(WTF::TextStream& ts,
if (behavior & kLayoutAsTextShowAddresses)
ts << " " << static_cast<const void*>(&o);
- if (o.Style() && o.Style()->ZIndex())
- ts << " zI: " << o.Style()->ZIndex();
+ if (o.Style() && o.StyleRef().ZIndex())
+ ts << " zI: " << o.StyleRef().ZIndex();
if (o.GetNode()) {
String tag_name = GetTagName(o.GetNode());
@@ -201,10 +201,10 @@ void LayoutTreeAsText::WriteLayoutObject(WTF::TextStream& ts,
text_stroke_color != color && text_stroke_color.Rgb())
ts << " [textStrokeColor=" << text_stroke_color << "]";
- if (o.Parent()->Style()->TextStrokeWidth() !=
- o.Style()->TextStrokeWidth() &&
- o.Style()->TextStrokeWidth() > 0)
- ts << " [textStrokeWidth=" << o.Style()->TextStrokeWidth() << "]";
+ if (o.Parent()->StyleRef().TextStrokeWidth() !=
+ o.StyleRef().TextStrokeWidth() &&
+ o.StyleRef().TextStrokeWidth() > 0)
+ ts << " [textStrokeWidth=" << o.StyleRef().TextStrokeWidth() << "]";
}
if (!o.IsBoxModelObject())
@@ -215,44 +215,44 @@ void LayoutTreeAsText::WriteLayoutObject(WTF::TextStream& ts,
box.BorderLeft()) {
ts << " [border:";
- BorderValue prev_border = o.Style()->BorderTop();
+ BorderValue prev_border = o.StyleRef().BorderTop();
if (!box.BorderTop()) {
ts << " none";
} else {
ts << " (" << box.BorderTop() << "px ";
- PrintBorderStyle(ts, o.Style()->BorderTopStyle());
+ PrintBorderStyle(ts, o.StyleRef().BorderTopStyle());
ts << o.ResolveColor(GetCSSPropertyBorderTopColor()) << ")";
}
- if (!o.Style()->BorderRightEquals(prev_border)) {
- prev_border = o.Style()->BorderRight();
+ if (!o.StyleRef().BorderRightEquals(prev_border)) {
+ prev_border = o.StyleRef().BorderRight();
if (!box.BorderRight()) {
ts << " none";
} else {
ts << " (" << box.BorderRight() << "px ";
- PrintBorderStyle(ts, o.Style()->BorderRightStyle());
+ PrintBorderStyle(ts, o.StyleRef().BorderRightStyle());
ts << o.ResolveColor(GetCSSPropertyBorderRightColor()) << ")";
}
}
- if (!o.Style()->BorderBottomEquals(prev_border)) {
- prev_border = box.Style()->BorderBottom();
+ if (!o.StyleRef().BorderBottomEquals(prev_border)) {
+ prev_border = box.StyleRef().BorderBottom();
if (!box.BorderBottom()) {
ts << " none";
} else {
ts << " (" << box.BorderBottom() << "px ";
- PrintBorderStyle(ts, o.Style()->BorderBottomStyle());
+ PrintBorderStyle(ts, o.StyleRef().BorderBottomStyle());
ts << o.ResolveColor(GetCSSPropertyBorderBottomColor()) << ")";
}
}
- if (!o.Style()->BorderLeftEquals(prev_border)) {
- prev_border = o.Style()->BorderLeft();
+ if (!o.StyleRef().BorderLeftEquals(prev_border)) {
+ prev_border = o.StyleRef().BorderLeft();
if (!box.BorderLeft()) {
ts << " none";
} else {
ts << " (" << box.BorderLeft() << "px ";
- PrintBorderStyle(ts, o.Style()->BorderLeftStyle());
+ PrintBorderStyle(ts, o.StyleRef().BorderLeftStyle());
ts << o.ResolveColor(GetCSSPropertyBorderLeftColor()) << ")";
}
}
@@ -443,9 +443,10 @@ static void WriteTextRun(WTF::TextStream& ts,
ts << ": "
<< QuoteAndEscapeNonPrintables(
String(o.GetText()).Substring(run.Start(), run.Len()));
- if (run.HasHyphen())
+ if (run.HasHyphen()) {
ts << " + hyphen string "
- << QuoteAndEscapeNonPrintables(o.Style()->HyphenString());
+ << QuoteAndEscapeNonPrintables(o.StyleRef().HyphenString());
+ }
ts << "\n";
}
@@ -609,7 +610,7 @@ static void Write(WTF::TextStream& ts,
WriteIndent(ts, indent);
- if (layer.GetLayoutObject().Style()->Visibility() == EVisibility::kHidden)
+ if (layer.GetLayoutObject().StyleRef().Visibility() == EVisibility::kHidden)
ts << "hidden ";
ts << "layer ";
@@ -653,11 +654,11 @@ static void Write(WTF::TextStream& ts,
else if (paint_phase == kLayerPaintPhaseForeground)
ts << " layerType: foreground only";
- if (layer.GetLayoutObject().Style()->HasBlendMode()) {
+ if (layer.GetLayoutObject().StyleRef().HasBlendMode()) {
ts << " blendMode: "
<< CompositeOperatorName(
kCompositeSourceOver,
- layer.GetLayoutObject().Style()->GetBlendMode());
+ layer.GetLayoutObject().StyleRef().GetBlendMode());
}
if (behavior & kLayoutAsTextShowCompositedLayers) {
@@ -703,9 +704,12 @@ void LayoutTreeAsText::WriteLayers(WTF::TextStream& ts,
LayoutRect layer_bounds;
ClipRect damage_rect, clip_rect_to_apply;
layer->Clipper(PaintLayer::kUseGeometryMapper)
- .CalculateRects(ClipRectsContext(root_layer, kUncachedClipRects),
- &layer->GetLayoutObject().FirstFragment(), &paint_rect,
- layer_bounds, damage_rect, clip_rect_to_apply);
+ .CalculateRects(
+ ClipRectsContext(root_layer,
+ &root_layer->GetLayoutObject().FirstFragment(),
+ kUncachedClipRects),
+ &layer->GetLayoutObject().FirstFragment(), &paint_rect, layer_bounds,
+ damage_rect, clip_rect_to_apply);
LayoutPoint offset_from_root;
layer->ConvertToLayerCoords(root_layer, offset_from_root);
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 dbb9797d76a..3c3cb42d43c 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_video.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_video.cc
@@ -52,7 +52,7 @@ void LayoutVideo::IntrinsicSizeChanged() {
void LayoutVideo::UpdateIntrinsicSize() {
LayoutSize size = CalculateIntrinsicSize();
- size.Scale(Style()->EffectiveZoom());
+ size.Scale(StyleRef().EffectiveZoom());
// Never set the element size to zero when in a media document.
if (size.IsEmpty() && GetNode()->ownerDocument() &&
@@ -70,6 +70,11 @@ void LayoutVideo::UpdateIntrinsicSize() {
LayoutSize LayoutVideo::CalculateIntrinsicSize() {
HTMLVideoElement* video = VideoElement();
+ DCHECK(video);
+
+ if (RuntimeEnabledFeatures::ExperimentalProductivityFeaturesEnabled() &&
+ !video->GetOverriddenIntrinsicSize().IsEmpty())
+ return LayoutSize(video->GetOverriddenIntrinsicSize());
// Spec text from 4.8.6
//
@@ -171,10 +176,7 @@ LayoutRect LayoutVideo::ReplacedContentRect() const {
if (ShouldDisplayVideo()) {
// Video codecs may need to restart from an I-frame when the output is
// resized. Round size in advance to avoid 1px snap difference.
- // TODO(trchen): The way of rounding is different from LayoutEmbeddedContent
- // just to match existing behavior. This is probably a bug and We should
- // unify it with LayoutEmbeddedContent.
- return LayoutRect(PixelSnappedIntRect(ComputeObjectFit()));
+ return PreSnappedRectForPersistentSizing(ComputeObjectFit());
}
// If we are displaying the poster image no pre-rounding is needed, but the
// size of the image should be used for fitting instead.
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 163058f6eef..41b297b4e36 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_video.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_video.h
@@ -48,10 +48,11 @@ class LayoutVideo final : public LayoutMedia {
const char* GetName() const override { return "LayoutVideo"; }
+ void IntrinsicSizeChanged() override;
+
private:
void UpdateFromElement() override;
- void IntrinsicSizeChanged() override;
LayoutSize CalculateIntrinsicSize();
void UpdateIntrinsicSize();
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 c71691161e5..73ed54a073a 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_view.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_view.cc
@@ -137,8 +137,6 @@ bool LayoutView::HitTestNoLifecycleUpdate(const HitTestLocation& location,
TRACE_EVENT_BEGIN0("blink,devtools.timeline", "HitTest");
hit_test_count_++;
- DCHECK(!location.IsRectBasedTest() || result.GetHitTestRequest().ListBased());
-
uint64_t dom_tree_version = GetDocument().DomTreeVersion();
HitTestResult cache_result = result;
bool hit_layer = false;
@@ -253,15 +251,31 @@ void LayoutView::SetShouldDoFullPaintInvalidationOnResizeIfNeeded(
// should fully invalidate on viewport resize if the background image is not
// composited and needs full paint invalidation on background positioning area
// resize.
- if (Style()->HasFixedBackgroundImage()) {
+ if (StyleRef().HasFixedBackgroundImage()) {
if ((width_changed && MustInvalidateFillLayersPaintOnWidthChange(
- Style()->BackgroundLayers())) ||
+ StyleRef().BackgroundLayers())) ||
(height_changed && MustInvalidateFillLayersPaintOnHeightChange(
- Style()->BackgroundLayers())))
+ StyleRef().BackgroundLayers())))
SetShouldDoFullPaintInvalidation(PaintInvalidationReason::kBackground);
}
}
+bool LayoutView::ShouldPlaceBlockDirectionScrollbarOnLogicalLeft() const {
+ LocalFrame& frame = GetFrameView()->GetFrame();
+ // See crbug.com/249860
+ if (frame.IsMainFrame())
+ return false;
+ // <body> inherits 'direction' from <html>, so checking style on the body is
+ // sufficient.
+ if (Element* body = GetDocument().body()) {
+ if (LayoutObject* body_layout_object = body->GetLayoutObject()) {
+ return body_layout_object->StyleRef()
+ .ShouldPlaceBlockDirectionScrollbarOnLogicalLeft();
+ }
+ }
+ return false;
+}
+
void LayoutView::UpdateBlockLayout(bool relayout_children) {
SubtreeLayoutScope layout_scope(*this);
@@ -280,9 +294,9 @@ void LayoutView::UpdateBlockLayout(bool relayout_children) {
continue;
if ((child->IsBox() && ToLayoutBox(child)->HasRelativeLogicalHeight()) ||
- child->Style()->LogicalHeight().IsPercentOrCalc() ||
- child->Style()->LogicalMinHeight().IsPercentOrCalc() ||
- child->Style()->LogicalMaxHeight().IsPercentOrCalc())
+ child->StyleRef().LogicalHeight().IsPercentOrCalc() ||
+ child->StyleRef().LogicalMinHeight().IsPercentOrCalc() ||
+ child->StyleRef().LogicalMaxHeight().IsPercentOrCalc())
layout_scope.SetChildNeedsLayout(child);
}
@@ -374,7 +388,8 @@ void LayoutView::MapLocalToAncestor(const LayoutBoxModelObject* ancestor,
if (mode & kTraverseDocumentBoundaries) {
auto* parent_doc_layout_object = GetFrame()->OwnerLayoutObject();
if (parent_doc_layout_object) {
- transform_state.Move(parent_doc_layout_object->ContentBoxOffset());
+ transform_state.Move(
+ parent_doc_layout_object->PhysicalContentBoxOffset());
parent_doc_layout_object->MapLocalToAncestor(ancestor, transform_state,
mode);
} else {
@@ -391,7 +406,7 @@ const LayoutObject* LayoutView::PushMappingToContainer(
if (geometry_map.GetMapCoordinatesFlags() & kTraverseDocumentBoundaries) {
if (auto* parent_doc_layout_object = GetFrame()->OwnerLayoutObject()) {
- offset += parent_doc_layout_object->ContentBoxOffset();
+ offset += parent_doc_layout_object->PhysicalContentBoxOffset();
container = parent_doc_layout_object;
}
}
@@ -423,7 +438,8 @@ void LayoutView::MapAncestorToLocal(const LayoutBoxModelObject* ancestor,
parent_doc_layout_object->MapAncestorToLocal(ancestor, transform_state,
mode & ~kIsFixed);
- transform_state.Move(parent_doc_layout_object->ContentBoxOffset());
+ transform_state.Move(
+ parent_doc_layout_object->PhysicalContentBoxOffset());
}
} else {
DCHECK(this == ancestor || !ancestor);
@@ -463,13 +479,13 @@ static void SetShouldDoFullPaintInvalidationForViewAndAllDescendantsInternal(
void LayoutView::SetShouldDoFullPaintInvalidationForViewAndAllDescendants() {
if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
- SetShouldDoFullPaintInvalidationIncludingNonCompositingDescendants();
+ SetSubtreeShouldDoFullPaintInvalidation();
else
SetShouldDoFullPaintInvalidationForViewAndAllDescendantsInternal(this);
}
void LayoutView::InvalidatePaintForViewAndCompositedLayers() {
- SetShouldDoFullPaintInvalidationIncludingNonCompositingDescendants();
+ SetSubtreeShouldDoFullPaintInvalidation();
// The only way we know how to hit these ASSERTS below this point is via the
// Chromium OS login screen.
@@ -552,7 +568,7 @@ bool LayoutView::MapToVisualRectInAncestorSpaceInternal(
rect = LayoutRect(EnclosingIntRect(rect));
// Adjust for frame border.
- rect.Move(obj->ContentBoxOffset());
+ rect.Move(obj->PhysicalContentBoxOffset());
transform_state.SetQuad(FloatQuad(FloatRect(rect)));
return obj->MapToVisualRectInAncestorSpaceInternal(
@@ -580,10 +596,6 @@ void LayoutView::AbsoluteQuads(Vector<FloatQuad>& quads,
FloatRect(FloatPoint(), FloatSize(Layer()->Size())), mode));
}
-void LayoutView::ClearSelection() {
- frame_view_->GetFrame().Selection().ClearLayoutSelection();
-}
-
void LayoutView::CommitPendingSelection() {
TRACE_EVENT0("blink", "LayoutView::commitPendingSelection");
DCHECK(!NeedsLayout());
@@ -751,14 +763,14 @@ IntSize LayoutView::GetLayoutSize(
int LayoutView::ViewLogicalWidth(
IncludeScrollbarsInRect scrollbar_inclusion) const {
- return Style()->IsHorizontalWritingMode() ? ViewWidth(scrollbar_inclusion)
- : ViewHeight(scrollbar_inclusion);
+ return StyleRef().IsHorizontalWritingMode() ? ViewWidth(scrollbar_inclusion)
+ : ViewHeight(scrollbar_inclusion);
}
int LayoutView::ViewLogicalHeight(
IncludeScrollbarsInRect scrollbar_inclusion) const {
- return Style()->IsHorizontalWritingMode() ? ViewHeight(scrollbar_inclusion)
- : ViewWidth(scrollbar_inclusion);
+ return StyleRef().IsHorizontalWritingMode() ? ViewHeight(scrollbar_inclusion)
+ : ViewWidth(scrollbar_inclusion);
}
LayoutUnit LayoutView::ViewLogicalHeightForPercentages() const {
@@ -876,7 +888,7 @@ bool LayoutView::RecalcOverflowAfterStyleChange() {
if (NeedsLayout())
return result;
if (GetFrameView()->VisualViewportSuppliesScrollbars())
- SetMayNeedPaintInvalidation();
+ SetShouldCheckForPaintInvalidation();
GetFrameView()->AdjustViewSize();
SetNeedsPaintPropertyUpdate();
}
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 fed51c0988f..f29f4b3747e 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_view.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_view.h
@@ -28,9 +28,9 @@
#include "third_party/blink/renderer/core/layout/hit_test_result.h"
#include "third_party/blink/renderer/core/layout/layout_block_flow.h"
#include "third_party/blink/renderer/core/layout/layout_state.h"
+#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/pod_free_list_arena.h"
-#include "third_party/blink/renderer/platform/scroll/scrollable_area.h"
namespace blink {
@@ -146,7 +146,6 @@ class CORE_EXPORT LayoutView final : public LayoutBlockFlow {
const PaintInfo&,
const LayoutPoint& paint_offset) const override;
- void ClearSelection();
void CommitPendingSelection();
void AbsoluteRects(Vector<IntRect>&,
@@ -241,13 +240,7 @@ class CORE_EXPORT LayoutView final : public LayoutBlockFlow {
void SetShouldDoFullPaintInvalidationOnResizeIfNeeded(bool width_changed,
bool height_changed);
- // The document scrollbar is always on the right, even in RTL. This is to
- // prevent it from moving around on navigations.
- // TODO(skobes): This is not quite the ideal behavior, see
- // http://crbug.com/250514 and http://crbug.com/249860.
- bool ShouldPlaceBlockDirectionScrollbarOnLogicalLeft() const override {
- return false;
- }
+ bool ShouldPlaceBlockDirectionScrollbarOnLogicalLeft() const override;
LayoutRect DebugRect() const override;
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 5f78b14e948..df1edc2851a 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
@@ -84,7 +84,7 @@ LayoutUnit SnapToLinesLayouter::ComputeInitialPositionAdjustment(
// 7. Round line to an integer by adding 0.5 and then flooring it.
LayoutUnit line_position(floorf(cue_box_.SnapToLinesPosition() + 0.5f));
- WritingMode writing_mode = cue_box_.Style()->GetWritingMode();
+ WritingMode writing_mode = cue_box_.StyleRef().GetWritingMode();
// 8. Vertical Growing Left: Add one to line then negate it.
if (IsFlippedBlocksWritingMode(writing_mode))
line_position = -(line_position + 1);
@@ -119,7 +119,7 @@ LayoutUnit SnapToLinesLayouter::ComputeInitialPositionAdjustment(
// incorrect results.
IntRect ContentBoxRelativeToAncestor(const LayoutBox& box,
const LayoutBoxModelObject& ancestor) {
- FloatRect cue_content_box(box.ContentBoxRect());
+ FloatRect cue_content_box(box.PhysicalContentBoxRect());
// We pass UseTransforms here primarily because we use a transform for
// non-snap-to-lines positioning (see VTTCue.cpp.)
FloatQuad mapped_content_quad =
@@ -132,7 +132,7 @@ IntRect ContentBoxRelativeToAncestor(const LayoutBox& box,
// timeline is mostly padding.
IntRect PaddingBoxRelativeToAncestor(const LayoutBox& box,
const LayoutBoxModelObject& ancestor) {
- FloatRect cue_content_box(box.PaddingBoxRect());
+ FloatRect cue_content_box(box.PhysicalPaddingBoxRect());
// We pass UseTransforms here primarily because we use a transform for
// non-snap-to-lines positioning (see VTTCue.cpp.)
FloatQuad mapped_content_quad =
@@ -195,7 +195,7 @@ void SnapToLinesLayouter::UpdateLayout() {
// into which cues will not be placed.
// 2. Horizontal: Let full dimension be the height of video's rendering area
// Vertical: Let full dimension be the width of video's rendering area.
- WritingMode writing_mode = cue_box_.Style()->GetWritingMode();
+ WritingMode writing_mode = cue_box_.StyleRef().GetWritingMode();
LayoutBlock* parent_block = cue_box_.ContainingBlock();
LayoutUnit full_dimension = blink::IsHorizontalWritingMode(writing_mode)
? parent_block->Size().Height()
@@ -236,7 +236,7 @@ void SnapToLinesLayouter::UpdateLayout() {
// rendering area except for a width of margin at the left of the rendering
// area and a width of margin at the right of the rendering area.
IntRect title_area =
- EnclosingIntRect(cue_box_.ContainingBlock()->ContentBoxRect());
+ EnclosingIntRect(cue_box_.ContainingBlock()->PhysicalContentBoxRect());
if (blink::IsHorizontalWritingMode(writing_mode)) {
title_area.Move(0, margin.ToInt());
title_area.Contract(0, (2 * margin).ToInt());
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 26865edd839..2d8baac93aa 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
@@ -138,7 +138,7 @@ AbstractInlineTextBox::Direction LegacyAbstractInlineTextBox::GetDirection()
if (!inline_text_box_ || !GetLineLayoutItem())
return kLeftToRight;
- if (GetLineLayoutItem().Style()->IsHorizontalWritingMode()) {
+ if (GetLineLayoutItem().StyleRef().IsHorizontalWritingMode()) {
return (inline_text_box_->Direction() == TextDirection::kRtl
? kRightToLeft
: kLeftToRight);
diff --git a/chromium/third_party/blink/renderer/core/layout/line/breaking_context_inline_headers.h b/chromium/third_party/blink/renderer/core/layout/line/breaking_context_inline_headers.h
index 9a3994b07c8..34644633314 100644
--- a/chromium/third_party/blink/renderer/core/layout/line/breaking_context_inline_headers.h
+++ b/chromium/third_party/blink/renderer/core/layout/line/breaking_context_inline_headers.h
@@ -254,8 +254,8 @@ inline bool RequiresLineBoxForContent(LineLayoutInline flow,
if (flow.GetDocument().InNoQuirksMode() &&
(flow.Style(line_info.IsFirstLine())->LineHeight() !=
parent.Style(line_info.IsFirstLine())->LineHeight() ||
- flow.Style()->VerticalAlign() != parent.Style()->VerticalAlign() ||
- !parent.Style()->HasIdenticalAscentDescentAndLineGap(flow.StyleRef())))
+ flow.StyleRef().VerticalAlign() != parent.StyleRef().VerticalAlign() ||
+ !parent.StyleRef().HasIdenticalAscentDescentAndLineGap(flow.StyleRef())))
return true;
return false;
}
@@ -356,12 +356,13 @@ inline void BreakingContext::InitializeForCurrentObject() {
current_.GetLineLayoutItem().Parent()))
include_end_width_ = true;
- curr_ws_ = current_.GetLineLayoutItem().IsLayoutInline()
- ? current_style_->WhiteSpace()
- : current_.GetLineLayoutItem().Parent().Style()->WhiteSpace();
+ curr_ws_ =
+ current_.GetLineLayoutItem().IsLayoutInline()
+ ? current_style_->WhiteSpace()
+ : current_.GetLineLayoutItem().Parent().StyleRef().WhiteSpace();
last_ws_ = last_object_.IsLayoutInline()
- ? last_object_.Style()->WhiteSpace()
- : last_object_.Parent().Style()->WhiteSpace();
+ ? last_object_.StyleRef().WhiteSpace()
+ : last_object_.Parent().StyleRef().WhiteSpace();
bool is_svg_text = current_.GetLineLayoutItem().IsSVGInlineText();
auto_wrap_ = !is_svg_text && ComputedStyle::AutoWrap(curr_ws_);
@@ -481,7 +482,7 @@ inline void BreakingContext::HandleOutOfFlowPositioned(
// If our original display wasn't an inline type, then we can
// go ahead and determine our static inline position now.
LineLayoutBox box(current_.GetLineLayoutItem());
- bool is_inline_type = box.Style()->IsOriginalDisplayInlineType();
+ bool is_inline_type = box.StyleRef().IsOriginalDisplayInlineType();
if (!is_inline_type) {
block_.SetStaticInlinePositionForChild(box, block_.StartOffsetForContent());
} else {
@@ -573,7 +574,7 @@ inline bool ShouldSkipWhitespaceAfterStartObject(
LineLayoutText(next).TextLength() > 0) {
LineLayoutText next_text(next);
UChar next_char = next_text.CharacterAt(0);
- if (next_text.Style()->IsCollapsibleWhiteSpace(next_char)) {
+ if (next_text.StyleRef().IsCollapsibleWhiteSpace(next_char)) {
line_midpoint_state.StartIgnoringSpaces(InlineIterator(nullptr, o, 0));
return true;
}
@@ -718,12 +719,14 @@ ALWAYS_INLINE float TextWidth(
bool collapse_white_space,
HashSet<const SimpleFontData*>* fallback_fonts = nullptr,
FloatRect* glyph_bounds = nullptr) {
- if ((!from && len == text.TextLength()) || text.Style()->HasTextCombine())
+ if ((!from && len == text.TextLength()) || text.StyleRef().HasTextCombine()) {
return text.Width(from, len, font, LayoutUnit(x_pos),
- text.Style()->Direction(), fallback_fonts, glyph_bounds);
+ text.StyleRef().Direction(), fallback_fonts,
+ glyph_bounds);
+ }
TextRun run = ConstructTextRun(font, text, from, len, text.StyleRef());
- run.SetTabSize(!collapse_white_space, text.Style()->GetTabSize());
+ run.SetTabSize(!collapse_white_space, text.StyleRef().GetTabSize());
run.SetXPos(x_pos);
return font.Width(run, fallback_fonts, glyph_bounds);
}
@@ -1506,7 +1509,7 @@ inline void BreakingContext::CommitAndUpdateLineBreakIfNeeded() {
check_for_break = true;
} else if (next_object_ && current_.GetLineLayoutItem().IsText() &&
next_object_.IsText() && !next_object_.IsBR() &&
- (auto_wrap_ || next_object_.Style()->AutoWrap())) {
+ (auto_wrap_ || next_object_.StyleRef().AutoWrap())) {
if (auto_wrap_ && current_character_is_space_) {
check_for_break = true;
} else {
diff --git a/chromium/third_party/blink/renderer/core/layout/line/ellipsis_box.h b/chromium/third_party/blink/renderer/core/layout/line/ellipsis_box.h
index 9115b252011..d971a1a1296 100644
--- a/chromium/third_party/blink/renderer/core/layout/line/ellipsis_box.h
+++ b/chromium/third_party/blink/renderer/core/layout/line/ellipsis_box.h
@@ -49,8 +49,7 @@ class EllipsisBox final : public InlineBox {
nullptr,
parent),
height_(height),
- str_(ellipsis_str),
- selection_state_(SelectionState::kNone) {
+ str_(ellipsis_str) {
SetHasVirtualLogicalHeight();
}
@@ -63,11 +62,9 @@ class EllipsisBox final : public InlineBox {
const LayoutPoint& accumulated_offset,
LayoutUnit line_top,
LayoutUnit line_bottom) override;
- void SetSelectionState(SelectionState s) { selection_state_ = s; }
IntRect SelectionRect() const;
LayoutUnit VirtualLogicalHeight() const override { return height_; }
- SelectionState GetSelectionState() const override { return selection_state_; }
const AtomicString& EllipsisStr() const { return str_; }
const char* BoxName() const override;
@@ -75,7 +72,6 @@ class EllipsisBox final : public InlineBox {
private:
LayoutUnit height_;
AtomicString str_;
- SelectionState selection_state_;
};
} // 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 91a6f9381fd..abf45f20026 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
@@ -21,6 +21,7 @@
#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/api/selection_state.h"
#include "third_party/blink/renderer/core/layout/hit_test_location.h"
#include "third_party/blink/renderer/core/layout/layout_block_flow.h"
#include "third_party/blink/renderer/core/layout/line/inline_flow_box.h"
@@ -303,8 +304,8 @@ InlineBox* InlineBox::PrevLeafChildIgnoringLineBreak() const {
return (leaf && leaf->IsLineBreak()) ? nullptr : leaf;
}
-SelectionState InlineBox::GetSelectionState() const {
- return GetLineLayoutItem().GetSelectionState();
+bool InlineBox::IsSelected() const {
+ return GetLineLayoutItem().GetSelectionState() != SelectionState::kNone;
}
bool InlineBox::CanAccommodateEllipsis(bool ltr,
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 68b713b258a..853def8ebd1 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
@@ -26,7 +26,6 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/layout/api/line_layout_box_model.h"
#include "third_party/blink/renderer/core/layout/api/line_layout_item.h"
-#include "third_party/blink/renderer/core/layout/api/selection_state.h"
#include "third_party/blink/renderer/platform/fonts/font_vertical_position_type.h"
#include "third_party/blink/renderer/platform/graphics/paint/display_item_client.h"
#include "third_party/blink/renderer/platform/text/text_direction.h"
@@ -308,7 +307,7 @@ class CORE_EXPORT InlineBox : public DisplayItemClient {
virtual void DirtyLineBoxes();
- virtual SelectionState GetSelectionState() const;
+ virtual bool IsSelected() const;
virtual bool CanAccommodateEllipsis(bool ltr,
LayoutUnit block_edge,
diff --git a/chromium/third_party/blink/renderer/core/layout/line/inline_flow_box.cc b/chromium/third_party/blink/renderer/core/layout/line/inline_flow_box.cc
index 3f9a3fa0370..ddb0ad2a4d2 100644
--- a/chromium/third_party/blink/renderer/core/layout/line/inline_flow_box.cc
+++ b/chromium/third_party/blink/renderer/core/layout/line/inline_flow_box.cc
@@ -355,14 +355,14 @@ void InlineFlowBox::DetermineSpacingForFlowBoxes(
// The root inline box never has borders/margins/padding.
if (Parent()) {
- bool ltr = GetLineLayoutItem().Style()->IsLeftToRightDirection();
+ bool ltr = GetLineLayoutItem().StyleRef().IsLeftToRightDirection();
// Check to see if all initial lines are unconstructed. If so, then
// we know the inline began on this line (unless we are a continuation).
LineBoxList* line_box_list = LineBoxes();
if (!line_box_list->First()->IsConstructed() &&
!GetLineLayoutItem().IsInlineElementContinuation()) {
- if (GetLineLayoutItem().Style()->BoxDecorationBreak() ==
+ if (GetLineLayoutItem().StyleRef().BoxDecorationBreak() ==
EBoxDecorationBreak::kClone)
include_left_edge = include_right_edge = true;
else if (ltr && line_box_list->First() == this)
@@ -391,7 +391,7 @@ void InlineFlowBox::DetermineSpacingForFlowBoxes(
// next line.
// (4) The decoration break is set to clone therefore there will be
// borders on every sides.
- if (GetLineLayoutItem().Style()->BoxDecorationBreak() ==
+ if (GetLineLayoutItem().StyleRef().BoxDecorationBreak() ==
EBoxDecorationBreak::kClone) {
include_left_edge = include_right_edge = true;
} else if (ltr) {
@@ -485,8 +485,8 @@ void InlineFlowBox::PlaceBoxRangeInInlineDirection(
if (curr->GetLineLayoutItem().IsOutOfFlowPositioned()) {
if (curr->GetLineLayoutItem()
.Parent()
- .Style()
- ->IsLeftToRightDirection()) {
+ .StyleRef()
+ .IsLeftToRightDirection()) {
curr->SetLogicalLeft(logical_left);
} else {
// Our offset that we cache needs to be from the edge of the right
@@ -825,8 +825,8 @@ void InlineFlowBox::PlaceBoxesInBlockDirection(
// being part of the overall lineTop/lineBottom.
// Really this is a workaround hack for the fact that ruby should have
// been done as line layout and not done using inline-block.
- if (GetLineLayoutItem().Style()->IsFlippedLinesWritingMode() ==
- (curr->GetLineLayoutItem().Style()->GetRubyPosition() ==
+ if (GetLineLayoutItem().StyleRef().IsFlippedLinesWritingMode() ==
+ (curr->GetLineLayoutItem().StyleRef().GetRubyPosition() ==
RubyPosition::kAfter))
has_annotations_before = true;
else
@@ -845,7 +845,7 @@ void InlineFlowBox::PlaceBoxesInBlockDirection(
(ruby_base.FirstRootBox() ? ruby_base.FirstRootBox()->LineTop()
: LayoutUnit());
new_logical_top +=
- !GetLineLayoutItem().Style()->IsFlippedLinesWritingMode()
+ !GetLineLayoutItem().StyleRef().IsFlippedLinesWritingMode()
? top_ruby_base_leading
: bottom_ruby_base_leading;
box_height -= (top_ruby_base_leading + bottom_ruby_base_leading);
@@ -912,7 +912,7 @@ void InlineFlowBox::PlaceBoxesInBlockDirection(
std::max(line_bottom, line_bottom_including_margins);
}
- if (GetLineLayoutItem().Style()->IsFlippedLinesWritingMode())
+ if (GetLineLayoutItem().StyleRef().IsFlippedLinesWritingMode())
FlipLinesInBlockDirection(line_top_including_margins,
line_bottom_including_margins);
}
@@ -1138,7 +1138,7 @@ static void ComputeGlyphOverflow(
float measured_width = layout_text.Width(
text->Start(), text->Len(), LayoutUnit(), text->Direction(), false,
&fallback_fonts, &glyph_bounds);
- const Font& font = layout_text.Style()->GetFont();
+ const Font& font = layout_text.StyleRef().GetFont();
glyph_overflow.SetFromBounds(glyph_bounds, font, measured_width);
if (!fallback_fonts.IsEmpty()) {
GlyphOverflowAndFallbackFontsMap::ValueType* it =
@@ -1353,11 +1353,12 @@ bool InlineFlowBox::NodeAtPoint(HitTestResult& result,
overflow_rect.Location()))
return false;
- if (GetLineLayoutItem().Style()->HasBorderRadius()) {
+ if (GetLineLayoutItem().StyleRef().HasBorderRadius()) {
LayoutRect border_rect = LogicalFrameRect();
border_rect.MoveBy(accumulated_offset);
- FloatRoundedRect border = GetLineLayoutItem().Style()->GetRoundedBorderFor(
- border_rect, IncludeLogicalLeftEdge(), IncludeLogicalRightEdge());
+ FloatRoundedRect border =
+ GetLineLayoutItem().StyleRef().GetRoundedBorderFor(
+ border_rect, IncludeLogicalLeftEdge(), IncludeLogicalRightEdge());
if (!location_in_container.Intersects(border))
return false;
}
@@ -1402,7 +1403,8 @@ bool InlineFlowBox::BoxShadowCanBeAppliedToBackground(
// would be clipped out, so it has to be drawn separately).
StyleImage* image = last_background_layer.GetImage();
bool has_fill_image = image && image->CanRender();
- return (!has_fill_image && !GetLineLayoutItem().Style()->HasBorderRadius()) ||
+ return (!has_fill_image &&
+ !GetLineLayoutItem().StyleRef().HasBorderRadius()) ||
(!PrevForSameLayoutObject() && !NextForSameLayoutObject()) ||
!Parent();
}
@@ -1423,10 +1425,6 @@ InlineBox* InlineFlowBox::LastLeafChild() const {
return leaf;
}
-SelectionState InlineFlowBox::GetSelectionState() const {
- return SelectionState::kNone;
-}
-
bool InlineFlowBox::CanAccommodateEllipsis(bool ltr,
LayoutUnit block_edge,
LayoutUnit ellipsis_width) const {
@@ -1507,14 +1505,14 @@ LayoutUnit InlineFlowBox::ComputeOverAnnotationAdjustment(
if (curr->GetLineLayoutItem().IsAtomicInlineLevel() &&
curr->GetLineLayoutItem().IsRubyRun() &&
- curr->GetLineLayoutItem().Style()->GetRubyPosition() ==
+ curr->GetLineLayoutItem().StyleRef().GetRubyPosition() ==
RubyPosition::kBefore) {
LineLayoutRubyRun ruby_run = LineLayoutRubyRun(curr->GetLineLayoutItem());
LineLayoutRubyText ruby_text = ruby_run.RubyText();
if (!ruby_text)
continue;
- if (!ruby_run.Style()->IsFlippedLinesWritingMode()) {
+ if (!ruby_run.StyleRef().IsFlippedLinesWritingMode()) {
LayoutUnit top_of_first_ruby_text_line =
ruby_text.LogicalTop() + (ruby_text.FirstRootBox()
? ruby_text.FirstRootBox()->LineTop()
@@ -1578,14 +1576,14 @@ LayoutUnit InlineFlowBox::ComputeUnderAnnotationAdjustment(
if (curr->GetLineLayoutItem().IsAtomicInlineLevel() &&
curr->GetLineLayoutItem().IsRubyRun() &&
- curr->GetLineLayoutItem().Style()->GetRubyPosition() ==
+ curr->GetLineLayoutItem().StyleRef().GetRubyPosition() ==
RubyPosition::kAfter) {
LineLayoutRubyRun ruby_run = LineLayoutRubyRun(curr->GetLineLayoutItem());
LineLayoutRubyText ruby_text = ruby_run.RubyText();
if (!ruby_text)
continue;
- if (ruby_run.Style()->IsFlippedLinesWritingMode()) {
+ if (ruby_run.StyleRef().IsFlippedLinesWritingMode()) {
LayoutUnit top_of_first_ruby_text_line =
ruby_text.LogicalTop() + (ruby_text.FirstRootBox()
? ruby_text.FirstRootBox()->LineTop()
@@ -1649,7 +1647,7 @@ void InlineFlowBox::CollectLeafBoxesInLogicalOrder(
leaf_boxes_in_logical_order.push_back(leaf);
}
- if (GetLineLayoutItem().Style()->RtlOrdering() == EOrder::kVisual)
+ if (GetLineLayoutItem().StyleRef().RtlOrdering() == EOrder::kVisual)
return;
// Reverse of reordering of the line (L2 according to Bidi spec):
diff --git a/chromium/third_party/blink/renderer/core/layout/line/inline_flow_box.h b/chromium/third_party/blink/renderer/core/layout/line/inline_flow_box.h
index 410e182a030..d04be47e4c1 100644
--- a/chromium/third_party/blink/renderer/core/layout/line/inline_flow_box.h
+++ b/chromium/third_party/blink/renderer/core/layout/line/inline_flow_box.h
@@ -22,7 +22,6 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LINE_INLINE_FLOW_BOX_H_
#include <memory>
-#include "third_party/blink/renderer/core/layout/api/selection_state.h"
#include "third_party/blink/renderer/core/layout/line/inline_box.h"
#include "third_party/blink/renderer/core/layout/overflow_model.h"
#include "third_party/blink/renderer/core/style/shadow_data.h"
@@ -74,7 +73,7 @@ class InlineFlowBox : public InlineBox {
// bullet list items. Even when the list bullet is an image, the line is
// still considered to be immune from the quirk.
has_text_children_ =
- line_layout_item.Style()->Display() == EDisplay::kListItem;
+ line_layout_item.StyleRef().Display() == EDisplay::kListItem;
has_text_descendants_ = has_text_children_;
}
@@ -261,7 +260,7 @@ class InlineFlowBox : public InlineBox {
void RemoveChild(InlineBox* child, MarkLineBoxes);
- SelectionState GetSelectionState() const override;
+ bool IsSelected() const override { return false; }
bool CanAccommodateEllipsis(bool ltr,
LayoutUnit block_edge,
diff --git a/chromium/third_party/blink/renderer/core/layout/line/inline_iterator.h b/chromium/third_party/blink/renderer/core/layout/line/inline_iterator.h
index f475497f5ad..52ecfc00b9f 100644
--- a/chromium/third_party/blink/renderer/core/layout/line/inline_iterator.h
+++ b/chromium/third_party/blink/renderer/core/layout/line/inline_iterator.h
@@ -197,7 +197,7 @@ static inline void NotifyObserverWillExitObject(Observer* observer,
if (!observer || !object || !object.IsLayoutInline())
return;
- UnicodeBidi unicode_bidi = object.Style()->GetUnicodeBidi();
+ UnicodeBidi unicode_bidi = object.StyleRef().GetUnicodeBidi();
if (unicode_bidi == UnicodeBidi::kNormal)
return; // Nothing to do for unicode-bidi: normal
if (TreatAsIsolated(object.StyleRef())) {
@@ -517,7 +517,7 @@ ALWAYS_INLINE WTF::Unicode::CharDirection InlineIterator::Direction() const {
return WTF::Unicode::Direction(c);
if (line_layout_item_ && line_layout_item_.IsListMarker())
- return line_layout_item_.Style()->IsLeftToRightDirection()
+ return line_layout_item_.StyleRef().IsLeftToRightDirection()
? WTF::Unicode::kLeftToRight
: WTF::Unicode::kRightToLeft;
@@ -549,7 +549,7 @@ static inline bool IsCollapsibleSpace(UChar character,
character == kSoftHyphenCharacter)
return true;
if (character == '\n')
- return !layout_text.Style()->PreserveNewline();
+ return !layout_text.StyleRef().PreserveNewline();
return false;
}
diff --git a/chromium/third_party/blink/renderer/core/layout/line/inline_text_box.cc b/chromium/third_party/blink/renderer/core/layout/line/inline_text_box.cc
index 80dca35b5f4..bd3cc1dc3ce 100644
--- a/chromium/third_party/blink/renderer/core/layout/line/inline_text_box.cc
+++ b/chromium/third_party/blink/renderer/core/layout/line/inline_text_box.cc
@@ -30,6 +30,7 @@
#include "third_party/blink/renderer/core/layout/api/line_layout_br.h"
#include "third_party/blink/renderer/core/layout/api/line_layout_ruby_run.h"
#include "third_party/blink/renderer/core/layout/api/line_layout_ruby_text.h"
+#include "third_party/blink/renderer/core/layout/api/selection_state.h"
#include "third_party/blink/renderer/core/layout/hit_test_result.h"
#include "third_party/blink/renderer/core/layout/line/abstract_inline_text_box.h"
#include "third_party/blink/renderer/core/layout/line/ellipsis_box.h"
@@ -160,86 +161,37 @@ LayoutUnit InlineTextBox::VerticalPosition(
return LogicalTop() + OffsetTo(position_type, baseline_type);
}
-bool InlineTextBox::IsSelected(int start_pos, int end_pos) const {
- int s_pos = std::max(start_pos - start_, 0);
- // The position after a hard line break is considered to be past its end.
- // See the corresponding code in InlineTextBox::getSelectionState.
- int e_pos = std::min(end_pos - start_, int(len_) + (IsLineBreak() ? 0 : 1));
- return (s_pos < e_pos);
-}
-
-SelectionState InlineTextBox::GetSelectionState() const {
- SelectionState state = GetLineLayoutItem().GetSelectionState();
- if (state == SelectionState::kStart || state == SelectionState::kEnd ||
- state == SelectionState::kStartAndEnd) {
- // The position after a hard line break is considered to be past its end.
- // See the corresponding code in InlineTextBox::isSelected.
- int last_selectable = Start() + Len() - (IsLineBreak() ? 1 : 0);
-
- // FIXME: Remove -webkit-line-break: LineBreakAfterWhiteSpace.
- int end_of_line_adjustment_for_css_line_break =
- GetLineLayoutItem().Style()->GetLineBreak() ==
- LineBreak::kAfterWhiteSpace
- ? -1
- : 0;
- const FrameSelection& selection =
- GetLineLayoutItem().GetDocument().GetFrame()->Selection();
- // TODO(yoichio): |value_or()| is used to prevent use uininitialized
- // value on release build. It should be value() because calling
- // LayoutSelectionStart() if SelectionState is neigher kStart nor
- // kStartAndEnd is invalid operation.
- bool start =
- (state != SelectionState::kEnd &&
- static_cast<int>(selection.LayoutSelectionStart().value_or(0)) >=
- start_ &&
- static_cast<int>(selection.LayoutSelectionStart().value_or(0)) <=
- start_ + len_ + end_of_line_adjustment_for_css_line_break);
- bool end = (state != SelectionState::kStart &&
- static_cast<int>(selection.LayoutSelectionEnd().value_or(0)) >
- start_ &&
- static_cast<int>(selection.LayoutSelectionEnd().value_or(0)) <=
- last_selectable);
- if (start && end)
- state = SelectionState::kStartAndEnd;
- else if (start)
- state = SelectionState::kStart;
- else if (end)
- state = SelectionState::kEnd;
- else if ((state == SelectionState::kEnd ||
- static_cast<int>(selection.LayoutSelectionStart().value_or(0)) <
- start_) &&
- (state == SelectionState::kStart ||
- static_cast<int>(selection.LayoutSelectionEnd().value_or(0)) >
- last_selectable))
- state = SelectionState::kInside;
- else if (state == SelectionState::kStartAndEnd)
- state = SelectionState::kNone;
- }
-
- // If there are ellipsis following, make sure their selection is updated.
- if (EllipsisBox* ellipsis = Root().GetEllipsisBox()) {
- if (state != SelectionState::kNone) {
- int start, end;
- SelectionStartEnd(start, end);
- // The ellipsis should be considered to be selected if the end of the
- // selection is past the beginning of the truncation and the beginning of
- // the selection is before or at the beginning of the truncation.
- ellipsis->SetSelectionState(end >= truncation_ && start <= truncation_
- ? SelectionState::kInside
- : SelectionState::kNone);
- } else {
- ellipsis->SetSelectionState(SelectionState::kNone);
- }
- }
+// Compute if selection includes end of the InlineTextBox.
+bool InlineTextBox::IsBoxEndIncludedInSelection() const {
+ const LayoutTextSelectionStatus& status =
+ GetLineLayoutItem().SelectionStatus();
+ if (status.IsEmpty())
+ return false;
+ if (status.start == status.end)
+ return false;
+ const unsigned box_end = IsLineBreak() ? Start() : Start() + Len();
+ if (status.start > box_end || status.end < box_end)
+ return false;
+ if (status.end > box_end)
+ return true;
+ // status.end == box_end
+ return status.include_end == SelectionIncludeEnd::kInclude;
+}
- return state;
+bool InlineTextBox::IsSelected() const {
+ const LayoutTextSelectionStatus& status =
+ GetLineLayoutItem().SelectionStatus();
+ if (status.IsEmpty())
+ return false;
+ if (Start() < status.end && status.start < Start() + Len())
+ return true;
+ return IsBoxEndIncludedInSelection();
}
bool InlineTextBox::HasWrappedSelectionNewline() const {
DCHECK(!GetLineLayoutItem().NeedsLayout());
- SelectionState state = GetSelectionState();
- if (state != SelectionState::kStart && state != SelectionState::kInside)
+ if (!IsBoxEndIncludedInSelection())
return false;
// Checking last leaf child can be slow, so we make sure to do this
@@ -261,13 +213,12 @@ bool InlineTextBox::HasWrappedSelectionNewline() const {
if (NextForSameLayoutObject())
return true;
auto root_block = Root().Block();
- if (root_block.IsInline() &&
- root_block.GetSelectionState() != SelectionState::kEnd &&
- root_block.GetSelectionState() != SelectionState::kStartAndEnd &&
- root_block.InlineBoxWrapper() &&
- ((is_ltr && root_block.InlineBoxWrapper()->NextOnLine()) ||
- (!is_ltr && root_block.InlineBoxWrapper()->PrevOnLine()))) {
- return false;
+ if (root_block.IsInline() && root_block.InlineBoxWrapper()) {
+ const InlineBox* next_root =
+ is_ltr ? root_block.InlineBoxWrapper()->NextOnLine()
+ : root_block.InlineBoxWrapper()->PrevOnLine();
+ if (next_root)
+ return false;
}
return true;
@@ -474,7 +425,7 @@ LayoutUnit InlineTextBox::PlaceEllipsisBox(bool flow_is_ltr,
bool InlineTextBox::IsLineBreak() const {
return GetLineLayoutItem().IsBR() ||
- (GetLineLayoutItem().Style()->PreserveNewline() && Len() == 1 &&
+ (GetLineLayoutItem().StyleRef().PreserveNewline() && Len() == 1 &&
GetLineLayoutItem().GetText().length() > Start() &&
(*GetLineLayoutItem().GetText().Impl())[Start()] == '\n');
}
@@ -545,34 +496,10 @@ void InlineTextBox::Paint(const PaintInfo& paint_info,
}
void InlineTextBox::SelectionStartEnd(int& s_pos, int& e_pos) const {
- int start_pos, end_pos;
- if (GetLineLayoutItem().GetSelectionState() == SelectionState::kInside) {
- start_pos = 0;
- end_pos = GetLineLayoutItem().TextLength();
- } else {
- const FrameSelection& selection =
- GetLineLayoutItem().GetDocument().GetFrame()->Selection();
- // TODO(yoichio): |value_or()| is used to prevent use uininitialized
- // value on release build. It should be |value()| because calling
- // LayoutSelectionStart() if SelectionState is neigher kStart nor
- // kStartAndEnd is invalid operation.
- if (GetLineLayoutItem().GetSelectionState() == SelectionState::kStart) {
- start_pos = selection.LayoutSelectionStart().value_or(0);
- end_pos = GetLineLayoutItem().TextLength();
- } else if (GetLineLayoutItem().GetSelectionState() ==
- SelectionState::kEnd) {
- start_pos = 0;
- end_pos = selection.LayoutSelectionEnd().value_or(0);
- } else {
- DCHECK(GetLineLayoutItem().GetSelectionState() ==
- SelectionState::kStartAndEnd);
- start_pos = selection.LayoutSelectionStart().value_or(0);
- end_pos = selection.LayoutSelectionEnd().value_or(0);
- }
- }
-
- s_pos = std::max(start_pos - start_, 0);
- e_pos = std::min(end_pos - start_, (int)len_);
+ const LayoutTextSelectionStatus& status =
+ GetLineLayoutItem().SelectionStatus();
+ s_pos = std::max(static_cast<int>(status.start) - start_, 0);
+ e_pos = std::min(static_cast<int>(status.end) - start_, (int)len_);
}
void InlineTextBox::PaintDocumentMarker(GraphicsContext& pt,
@@ -794,4 +721,22 @@ void InlineTextBox::DumpBox(StringBuilder& string_inlinetextbox) const {
#endif
+void InlineTextBox::ManuallySetStartLenAndLogicalWidth(
+ unsigned start,
+ unsigned len,
+ LayoutUnit logical_width) {
+ DCHECK(!IsDirty());
+ DCHECK_EQ(Root().FirstChild(), this);
+ DCHECK_EQ(Root().FirstChild(), Root().LastChild());
+ DCHECK(Root().FirstChild()->IsText());
+
+ start_ = start;
+ len_ = len;
+
+ SetLogicalWidth(logical_width);
+
+ if (!KnownToHaveNoOverflow() && g_text_boxes_with_overflow)
+ g_text_boxes_with_overflow->erase(this);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/line/inline_text_box.h b/chromium/third_party/blink/renderer/core/layout/line/inline_text_box.h
index fb346171800..3ad1e81c035 100644
--- a/chromium/third_party/blink/renderer/core/layout/line/inline_text_box.h
+++ b/chromium/third_party/blink/renderer/core/layout/line/inline_text_box.h
@@ -60,6 +60,9 @@ class CORE_EXPORT InlineTextBox : public InlineBox {
InlineTextBox* NextForSameLayoutObject() const { return next_text_box_; }
void SetNextForSameLayoutObject(InlineTextBox* n) { next_text_box_ = n; }
void SetPreviousForSameLayoutObject(InlineTextBox* p) { prev_text_box_ = p; }
+ void ManuallySetStartLenAndLogicalWidth(unsigned start,
+ unsigned len,
+ LayoutUnit logical_width);
// FIXME: These accessors should DCHECK(!isDirty()). See
// https://bugs.webkit.org/show_bug.cgi?id=97264
@@ -130,7 +133,6 @@ class CORE_EXPORT InlineTextBox : public InlineBox {
int start_pos,
int end_pos,
bool include_newline_space_width = true) const;
- bool IsSelected(int start_pos, int end_pos) const;
void SelectionStartEnd(int& s_pos, int& e_pos) const;
virtual void PaintDocumentMarker(GraphicsContext&,
@@ -169,11 +171,12 @@ class CORE_EXPORT InlineTextBox : public InlineBox {
void AttachLine() final;
public:
- SelectionState GetSelectionState() const final;
+ bool IsSelected() const final;
bool HasWrappedSelectionNewline() const;
float NewlineSpaceWidth() const;
private:
+ bool IsBoxEndIncludedInSelection() const;
void SetTruncation(unsigned);
void ClearTruncation() final;
diff --git a/chromium/third_party/blink/renderer/core/layout/line/layout_text_info.h b/chromium/third_party/blink/renderer/core/layout/line/layout_text_info.h
index cd3d0b5912d..80979ce2b5e 100644
--- a/chromium/third_party/blink/renderer/core/layout/line/layout_text_info.h
+++ b/chromium/third_party/blink/renderer/core/layout/line/layout_text_info.h
@@ -33,6 +33,8 @@ class Font;
struct LayoutTextInfo {
STACK_ALLOCATED();
+
+ public:
LayoutTextInfo() : text_(nullptr), font_(nullptr) {}
LineLayoutText text_;
diff --git a/chromium/third_party/blink/renderer/core/layout/line/line_box_list.cc b/chromium/third_party/blink/renderer/core/layout/line/line_box_list.cc
index c780319ef62..2b943ba9617 100644
--- a/chromium/third_party/blink/renderer/core/layout/line/line_box_list.cc
+++ b/chromium/third_party/blink/renderer/core/layout/line/line_box_list.cc
@@ -39,14 +39,27 @@
#include "third_party/blink/renderer/core/paint/paint_info.h"
namespace blink {
+
#if DCHECK_IS_ON()
template <typename InlineBoxType>
-InlineBoxList<InlineBoxType>::~InlineBoxList() {
+void InlineBoxList<InlineBoxType>::AssertIsEmpty() {
DCHECK(!first_);
DCHECK(!last_);
}
#endif
+const LineBoxList& LineBoxList::Empty() {
+ // Need to use "static" because DISALLOW_NEW.
+ static LineBoxList empty;
+ return empty;
+}
+
+const InlineTextBoxList& InlineTextBoxList::Empty() {
+ // Need to use "static" because DISALLOW_NEW.
+ static InlineTextBoxList empty;
+ return empty;
+}
+
template <typename InlineBoxType>
void InlineBoxList<InlineBoxType>::AppendLineBox(InlineBoxType* box) {
if (!first_) {
@@ -143,7 +156,7 @@ bool LineBoxList::RangeIntersectsRect(LineLayoutBoxModel layout_object,
LayoutUnit physical_extent = AbsoluteValue(physical_end - physical_start);
physical_start = std::min(physical_start, physical_end);
- if (layout_object.Style()->IsHorizontalWritingMode()) {
+ if (layout_object.StyleRef().IsHorizontalWritingMode()) {
physical_start += offset.Y();
return cull_rect.IntersectsVerticalRange(physical_start,
physical_start + physical_extent);
diff --git a/chromium/third_party/blink/renderer/core/layout/line/line_box_list.h b/chromium/third_party/blink/renderer/core/layout/line/line_box_list.h
index 9bb03d9ce19..969f137b3a7 100644
--- a/chromium/third_party/blink/renderer/core/layout/line/line_box_list.h
+++ b/chromium/third_party/blink/renderer/core/layout/line/line_box_list.h
@@ -54,7 +54,9 @@ class InlineBoxList {
InlineBoxList() : first_(nullptr), last_(nullptr) {}
#if DCHECK_IS_ON()
- ~InlineBoxList();
+ // Owners should check this on destructor. This class does not implement
+ // destructor to be part of a union.
+ void AssertIsEmpty();
#endif
InlineBoxType* First() const { return first_; }
@@ -139,8 +141,10 @@ class InlineBoxList {
extern template class CORE_EXTERN_TEMPLATE_EXPORT InlineBoxList<InlineFlowBox>;
extern template class CORE_EXTERN_TEMPLATE_EXPORT InlineBoxList<InlineTextBox>;
-class LineBoxList : public InlineBoxList<InlineFlowBox> {
+class CORE_EXPORT LineBoxList : public InlineBoxList<InlineFlowBox> {
public:
+ static const LineBoxList& Empty();
+
void DeleteLineBoxTree();
void DirtyLineBoxes();
@@ -169,7 +173,10 @@ class LineBoxList : public InlineBoxList<InlineFlowBox> {
const LayoutPoint&) const;
};
-class InlineTextBoxList : public InlineBoxList<InlineTextBox> {};
+class CORE_EXPORT InlineTextBoxList : public InlineBoxList<InlineTextBox> {
+ public:
+ static const InlineTextBoxList& Empty();
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/line/line_breaker.cc b/chromium/third_party/blink/renderer/core/layout/line/line_breaker.cc
index c0362d86c75..4d6464b537a 100644
--- a/chromium/third_party/blink/renderer/core/layout/line/line_breaker.cc
+++ b/chromium/third_party/blink/renderer/core/layout/line/line_breaker.cc
@@ -38,7 +38,7 @@ void LineBreaker::SkipLeadingWhitespace(InlineBidiResolver& resolver,
if (line_layout_item.IsOutOfFlowPositioned()) {
SetStaticPositions(block_, LineLayoutBox(line_layout_item),
width.IndentText());
- if (line_layout_item.Style()->IsOriginalDisplayInlineType()) {
+ if (line_layout_item.StyleRef().IsOriginalDisplayInlineType()) {
resolver.Runs().AddRun(
CreateRun(0, 1, LineLayoutItem(line_layout_item), resolver));
line_info.IncrementRunsFromLeadingWhitespace();
diff --git a/chromium/third_party/blink/renderer/core/layout/line/line_width.cc b/chromium/third_party/blink/renderer/core/layout/line/line_width.cc
index b1047e8934c..0be9101c2a0 100644
--- a/chromium/third_party/blink/renderer/core/layout/line/line_width.cc
+++ b/chromium/third_party/blink/renderer/core/layout/line/line_width.cc
@@ -87,7 +87,8 @@ void LineWidth::ShrinkAvailableWidthForNewFloatIfNeeded(
new_left = left_;
}
}
- if (IndentText() == kIndentText && block_.Style()->IsLeftToRightDirection())
+ if (IndentText() == kIndentText &&
+ block_.StyleRef().IsLeftToRightDirection())
new_left += FloorToInt(block_.TextIndentOffset());
left_ = std::max(left_, new_left);
} else {
@@ -102,7 +103,7 @@ void LineWidth::ShrinkAvailableWidthForNewFloatIfNeeded(
}
}
if (IndentText() == kIndentText &&
- !block_.Style()->IsLeftToRightDirection())
+ !block_.StyleRef().IsLeftToRightDirection())
new_right -= FloorToInt(block_.TextIndentOffset());
right_ = std::min(right_, new_right);
}
diff --git a/chromium/third_party/blink/renderer/core/layout/line/root_inline_box.cc b/chromium/third_party/blink/renderer/core/layout/line/root_inline_box.cc
index 04f3b7eb9aa..0167a842a2f 100644
--- a/chromium/third_party/blink/renderer/core/layout/line/root_inline_box.cc
+++ b/chromium/third_party/blink/renderer/core/layout/line/root_inline_box.cc
@@ -307,7 +307,7 @@ LayoutUnit RootInlineBox::AlignBoxesInBlockDirection(
LayoutUnit RootInlineBox::BeforeAnnotationsAdjustment() const {
LayoutUnit result;
- if (!GetLineLayoutItem().Style()->IsFlippedLinesWritingMode()) {
+ if (!GetLineLayoutItem().StyleRef().IsFlippedLinesWritingMode()) {
// Annotations under the previous line may push us down.
if (PrevRootBox() && PrevRootBox()->HasAnnotationsAfter())
result = PrevRootBox()->ComputeUnderAnnotationAdjustment(LineTop());
@@ -342,37 +342,18 @@ LayoutUnit RootInlineBox::BeforeAnnotationsAdjustment() const {
return result;
}
-SelectionState RootInlineBox::GetSelectionState() const {
+bool RootInlineBox::IsSelected() const {
// Walk over all of the selected boxes.
- SelectionState state = SelectionState::kNone;
for (InlineBox* box = FirstLeafChild(); box; box = box->NextLeafChild()) {
- SelectionState box_state = box->GetSelectionState();
- if ((box_state == SelectionState::kStart &&
- state == SelectionState::kEnd) ||
- (box_state == SelectionState::kEnd &&
- state == SelectionState::kStart)) {
- state = SelectionState::kStartAndEnd;
- } else if (state == SelectionState::kNone ||
- ((box_state == SelectionState::kStart ||
- box_state == SelectionState::kEnd) &&
- (state == SelectionState::kNone ||
- state == SelectionState::kInside))) {
- state = box_state;
- } else if (box_state == SelectionState::kNone &&
- state == SelectionState::kStart) {
- // We are past the end of the selection.
- state = SelectionState::kStartAndEnd;
- }
- if (state == SelectionState::kStartAndEnd)
- break;
+ if (box->IsSelected())
+ return true;
}
-
- return state;
+ return false;
}
InlineBox* RootInlineBox::FirstSelectedBox() const {
for (InlineBox* box = FirstLeafChild(); box; box = box->NextLeafChild()) {
- if (box->GetSelectionState() != SelectionState::kNone)
+ if (box->IsSelected())
return box;
}
@@ -381,7 +362,7 @@ InlineBox* RootInlineBox::FirstSelectedBox() const {
InlineBox* RootInlineBox::LastSelectedBox() const {
for (InlineBox* box = LastLeafChild(); box; box = box->PrevLeafChild()) {
- if (box->GetSelectionState() != SelectionState::kNone)
+ if (box->IsSelected())
return box;
}
@@ -391,11 +372,11 @@ InlineBox* RootInlineBox::LastSelectedBox() const {
LayoutUnit RootInlineBox::SelectionTop() const {
LayoutUnit selection_top = line_top_;
if (has_annotations_before_)
- selection_top -= !GetLineLayoutItem().Style()->IsFlippedLinesWritingMode()
+ selection_top -= !GetLineLayoutItem().StyleRef().IsFlippedLinesWritingMode()
? ComputeOverAnnotationAdjustment(line_top_)
: ComputeUnderAnnotationAdjustment(line_top_);
- if (GetLineLayoutItem().Style()->IsFlippedLinesWritingMode() ||
+ if (GetLineLayoutItem().StyleRef().IsFlippedLinesWritingMode() ||
!PrevRootBox())
return selection_top;
@@ -409,11 +390,11 @@ LayoutUnit RootInlineBox::SelectionBottom() const {
if (has_annotations_after_)
selection_bottom +=
- !GetLineLayoutItem().Style()->IsFlippedLinesWritingMode()
+ !GetLineLayoutItem().StyleRef().IsFlippedLinesWritingMode()
? ComputeUnderAnnotationAdjustment(line_bottom_)
: ComputeOverAnnotationAdjustment(line_bottom_);
- if (!GetLineLayoutItem().Style()->IsFlippedLinesWritingMode() ||
+ if (!GetLineLayoutItem().StyleRef().IsFlippedLinesWritingMode() ||
!NextRootBox())
return selection_bottom;
@@ -421,7 +402,7 @@ LayoutUnit RootInlineBox::SelectionBottom() const {
}
LayoutUnit RootInlineBox::BlockDirectionPointInLine() const {
- return !Block().Style()->IsFlippedBlocksWritingMode()
+ return !Block().StyleRef().IsFlippedBlocksWritingMode()
? std::max(LineTop(), SelectionTop())
: std::min(LineBottom(), SelectionBottom());
}
@@ -689,15 +670,15 @@ LayoutUnit RootInlineBox::VerticalPositionForBox(
}
LayoutUnit vertical_position;
- EVerticalAlign vertical_align = box_model.Style()->VerticalAlign();
+ EVerticalAlign vertical_align = box_model.StyleRef().VerticalAlign();
if (vertical_align == EVerticalAlign::kTop ||
vertical_align == EVerticalAlign::kBottom)
return LayoutUnit();
LineLayoutItem parent = box_model.Parent();
if (parent.IsLayoutInline() &&
- parent.Style()->VerticalAlign() != EVerticalAlign::kTop &&
- parent.Style()->VerticalAlign() != EVerticalAlign::kBottom)
+ parent.StyleRef().VerticalAlign() != EVerticalAlign::kTop &&
+ parent.StyleRef().VerticalAlign() != EVerticalAlign::kBottom)
vertical_position = box->Parent()->LogicalTop();
if (vertical_align != EVerticalAlign::kBaseline) {
@@ -745,12 +726,12 @@ LayoutUnit RootInlineBox::VerticalPositionForBox(
LayoutUnit line_height;
// Per http://www.w3.org/TR/CSS21/visudet.html#propdef-vertical-align:
// 'Percentages: refer to the 'line-height' of the element itself'.
- if (box_model.Style()->GetVerticalAlignLength().IsPercentOrCalc())
- line_height = LayoutUnit(box_model.Style()->ComputedLineHeight());
+ if (box_model.StyleRef().GetVerticalAlignLength().IsPercentOrCalc())
+ line_height = LayoutUnit(box_model.StyleRef().ComputedLineHeight());
else
line_height = box_model.LineHeight(first_line, line_direction);
vertical_position -= ValueForLength(
- box_model.Style()->GetVerticalAlignLength(), line_height);
+ box_model.StyleRef().GetVerticalAlignLength(), line_height);
}
}
diff --git a/chromium/third_party/blink/renderer/core/layout/line/root_inline_box.h b/chromium/third_party/blink/renderer/core/layout/line/root_inline_box.h
index 522cb2f5523..3f2ee123a5a 100644
--- a/chromium/third_party/blink/renderer/core/layout/line/root_inline_box.h
+++ b/chromium/third_party/blink/renderer/core/layout/line/root_inline_box.h
@@ -24,7 +24,6 @@
#include <memory>
#include "third_party/blink/renderer/core/layout/api/line_layout_item.h"
-#include "third_party/blink/renderer/core/layout/api/selection_state.h"
#include "third_party/blink/renderer/core/layout/line/inline_flow_box.h"
#include "third_party/blink/renderer/platform/text/bidi_context.h"
@@ -145,7 +144,7 @@ class RootInlineBox : public InlineFlowBox {
LayoutUnit line_top,
LayoutUnit line_bottom) override;
- SelectionState GetSelectionState() const final;
+ bool IsSelected() const final;
InlineBox* FirstSelectedBox() const;
InlineBox* LastSelectedBox() const;
diff --git a/chromium/third_party/blink/renderer/core/layout/multi_column_fragmentainer_group.cc b/chromium/third_party/blink/renderer/core/layout/multi_column_fragmentainer_group.cc
index 869820da343..70fbce40992 100644
--- a/chromium/third_party/blink/renderer/core/layout/multi_column_fragmentainer_group.cc
+++ b/chromium/third_party/blink/renderer/core/layout/multi_column_fragmentainer_group.cc
@@ -243,7 +243,7 @@ LayoutPoint MultiColumnFragmentainerGroup::VisualPointToFlowThreadPoint(
local_point.MoveBy(-column_rect.Location());
if (!column_set_.IsHorizontalWritingMode()) {
if (snap == kSnapToColumn) {
- LayoutUnit column_start = column_set_.Style()->IsLeftToRightDirection()
+ LayoutUnit column_start = column_set_.StyleRef().IsLeftToRightDirection()
? LayoutUnit()
: column_rect.Height();
if (local_point.X() < 0)
@@ -255,7 +255,7 @@ LayoutPoint MultiColumnFragmentainerGroup::VisualPointToFlowThreadPoint(
local_point.Y());
}
if (snap == kSnapToColumn) {
- LayoutUnit column_start = column_set_.Style()->IsLeftToRightDirection()
+ LayoutUnit column_start = column_set_.StyleRef().IsLeftToRightDirection()
? LayoutUnit()
: column_rect.Width();
if (local_point.Y() < 0)
@@ -425,7 +425,7 @@ LayoutRect MultiColumnFragmentainerGroup::ColumnRectAt(
LayoutUnit column_gap = column_set_.ColumnGap();
if (column_set_.MultiColumnFlowThread()->ProgressionIsInline()) {
- if (column_set_.Style()->IsLeftToRightDirection())
+ if (column_set_.StyleRef().IsLeftToRightDirection())
column_logical_left += column_index * (column_logical_width + column_gap);
else
column_logical_left += column_set_.ContentLogicalWidth() -
@@ -460,12 +460,9 @@ LayoutRect MultiColumnFragmentainerGroup::FlowThreadPortionRectAt(
static const int kMulticolMaxClipPixels = 1000000;
LayoutRect MultiColumnFragmentainerGroup::FlowThreadPortionOverflowRectAt(
- unsigned column_index,
- ClipRectAxesSelector axes_selector) const {
+ unsigned column_index) const {
// This function determines the portion of the flow thread that paints for the
- // column. Along the inline axis, columns are unclipped at outside edges
- // (i.e., the first and last column in the set), and they clip to half the
- // column gap along interior edges.
+ // column.
//
// In the block direction, we will not clip overflow out of the top of the
// first column, or out of the bottom of the last column. This applies only to
@@ -476,11 +473,6 @@ LayoutRect MultiColumnFragmentainerGroup::FlowThreadPortionOverflowRectAt(
// contents from a previous column in the overflow area of a following column.
bool is_first_column_in_row = !column_index;
bool is_last_column_in_row = column_index == ActualColumnCount() - 1;
- bool is_ltr = column_set_.Style()->IsLeftToRightDirection();
- bool is_leftmost_column =
- is_ltr ? is_first_column_in_row : is_last_column_in_row;
- bool is_rightmost_column =
- is_ltr ? is_last_column_in_row : is_first_column_in_row;
LayoutRect portion_rect = FlowThreadPortionRectAt(column_index);
bool is_first_column_in_multicol_container =
@@ -498,33 +490,16 @@ LayoutRect MultiColumnFragmentainerGroup::FlowThreadPortionOverflowRectAt(
LayoutRect overflow_rect(
IntRect(-kMulticolMaxClipPixels, -kMulticolMaxClipPixels,
2 * kMulticolMaxClipPixels, 2 * kMulticolMaxClipPixels));
- LayoutUnit column_gap = column_set_.ColumnGap();
if (column_set_.IsHorizontalWritingMode()) {
if (!is_first_column_in_multicol_container)
overflow_rect.ShiftYEdgeTo(portion_rect.Y());
if (!is_last_column_in_multicol_container)
overflow_rect.ShiftMaxYEdgeTo(portion_rect.MaxY());
- if (axes_selector == kBothAxes) {
- if (!is_leftmost_column)
- overflow_rect.ShiftXEdgeTo(portion_rect.X() - column_gap / 2);
- if (!is_rightmost_column) {
- overflow_rect.ShiftMaxXEdgeTo(portion_rect.MaxX() + column_gap -
- column_gap / 2);
- }
- }
} else {
if (!is_first_column_in_multicol_container)
overflow_rect.ShiftXEdgeTo(portion_rect.X());
if (!is_last_column_in_multicol_container)
overflow_rect.ShiftMaxXEdgeTo(portion_rect.MaxX());
- if (axes_selector == kBothAxes) {
- if (!is_leftmost_column)
- overflow_rect.ShiftYEdgeTo(portion_rect.Y() - column_gap / 2);
- if (!is_rightmost_column) {
- overflow_rect.ShiftMaxYEdgeTo(portion_rect.MaxY() + column_gap -
- column_gap / 2);
- }
- }
}
return overflow_rect;
}
@@ -572,7 +547,7 @@ unsigned MultiColumnFragmentainerGroup::ColumnIndexAtVisualPoint(
is_horizontal_writing_mode == is_column_progression_inline
? visual_point.X()
: visual_point.Y();
- if (!column_set_.Style()->IsLeftToRightDirection() &&
+ if (!column_set_.StyleRef().IsLeftToRightDirection() &&
is_column_progression_inline)
offset_in_column_progression_direction =
column_set_.LogicalWidth() - offset_in_column_progression_direction;
@@ -618,7 +593,7 @@ void MultiColumnFragmentainerGroup::ColumnIntervalForVisualRect(
bool is_column_progression_inline =
column_set_.MultiColumnFlowThread()->ProgressionIsInline();
bool is_flipped_column_progression =
- !column_set_.Style()->IsLeftToRightDirection() &&
+ !column_set_.StyleRef().IsLeftToRightDirection() &&
is_column_progression_inline;
if (column_set_.IsHorizontalWritingMode() == is_column_progression_inline) {
if (is_flipped_column_progression) {
diff --git a/chromium/third_party/blink/renderer/core/layout/multi_column_fragmentainer_group.h b/chromium/third_party/blink/renderer/core/layout/multi_column_fragmentainer_group.h
index 13aedea607f..2008b234259 100644
--- a/chromium/third_party/blink/renderer/core/layout/multi_column_fragmentainer_group.h
+++ b/chromium/third_party/blink/renderer/core/layout/multi_column_fragmentainer_group.h
@@ -126,22 +126,7 @@ class CORE_EXPORT MultiColumnFragmentainerGroup {
LayoutRect FlowThreadPortionRectAt(unsigned column_index) const;
- enum ClipRectAxesSelector {
- // Only limit the clip rectangle in the block direction. Leave inline
- // position and length at infinity. Certain operations require this. Those
- // operations would typically ideally want no clipping at all, but in our
- // implementation we have to clip in the block direction, in order to slice
- // the flow thread properly into columns.
- kBlockDirectionAxis,
-
- // Limit the clip rectangle along both axes. This is what to use for
- // painting and hit testing.
- kBothAxes
- };
-
- LayoutRect FlowThreadPortionOverflowRectAt(
- unsigned column_index,
- ClipRectAxesSelector = kBothAxes) const;
+ LayoutRect FlowThreadPortionOverflowRectAt(unsigned column_index) const;
// Get the first and the last column intersecting the specified block range.
// Note that |logicalBottomInFlowThread| is an exclusive endpoint.
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.cc b/chromium/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.cc
index 2ce9008b4b1..de141ded5ab 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.cc
@@ -165,11 +165,13 @@ NGLayoutOpportunity CreateLayoutOpportunity(
NGExclusionSpace::NGExclusionSpace()
: exclusions_(RefVector<scoped_refptr<const NGExclusion>>::Create()),
num_exclusions_(0),
+ both_clear_offset_(LayoutUnit::Min()),
derived_geometry_(nullptr) {}
NGExclusionSpace::NGExclusionSpace(const NGExclusionSpace& other)
: exclusions_(other.exclusions_),
num_exclusions_(other.num_exclusions_),
+ both_clear_offset_(other.both_clear_offset_),
derived_geometry_(std::move(other.derived_geometry_)) {
// This copy-constructor does fun things. It moves the derived_geometry_ to
// the newly created exclusion space where it'll more-likely be used.
@@ -203,6 +205,9 @@ void NGExclusionSpace::Add(scoped_refptr<const NGExclusion> exclusion) {
if (derived_geometry_)
derived_geometry_->Add(exclusion);
+ both_clear_offset_ =
+ std::max(both_clear_offset_, exclusion->rect.BlockEndOffset());
+
exclusions_->push_back(std::move(exclusion));
num_exclusions_++;
}
@@ -580,6 +585,8 @@ const NGExclusionSpace::DerivedGeometry& NGExclusionSpace::GetDerivedGeometry()
}
bool NGExclusionSpace::operator==(const NGExclusionSpace& other) const {
+ if (num_exclusions_ == 0 && other.num_exclusions_ == 0)
+ return true;
return num_exclusions_ == other.num_exclusions_ &&
exclusions_ == other.exclusions_;
}
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.h b/chromium/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.h
index 1907888de13..b45d208968a 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.h
@@ -23,6 +23,8 @@ namespace blink {
// The space is mutated simply by adding exclusions, and various information
// can be queried based on the exclusions.
class CORE_EXPORT NGExclusionSpace {
+ USING_FAST_MALLOC(NGExclusionSpace);
+
public:
NGExclusionSpace();
NGExclusionSpace(const NGExclusionSpace&);
@@ -38,6 +40,15 @@ class CORE_EXPORT NGExclusionSpace {
const NGBfcOffset& offset,
const LayoutUnit available_inline_size,
const NGLogicalSize& minimum_size) const {
+ // If the area clears all floats, we can just return the layout opportunity
+ // which matches the available space.
+ if (offset.block_offset >= both_clear_offset_) {
+ NGBfcOffset end_offset(
+ offset.line_offset + available_inline_size.ClampNegativeToZero(),
+ LayoutUnit::Max());
+ return NGLayoutOpportunity(NGBfcRect(offset, end_offset), nullptr);
+ }
+
return GetDerivedGeometry().FindLayoutOpportunity(
offset, available_inline_size, minimum_size);
}
@@ -45,12 +56,25 @@ class CORE_EXPORT NGExclusionSpace {
Vector<NGLayoutOpportunity> AllLayoutOpportunities(
const NGBfcOffset& offset,
const LayoutUnit available_inline_size) const {
+ // If the area clears all floats, we can just return a single layout
+ // opportunity which matches the available space.
+ if (offset.block_offset >= both_clear_offset_) {
+ NGBfcOffset end_offset(
+ offset.line_offset + available_inline_size.ClampNegativeToZero(),
+ LayoutUnit::Max());
+ return Vector<NGLayoutOpportunity>(
+ {NGLayoutOpportunity(NGBfcRect(offset, end_offset), nullptr)});
+ }
+
return GetDerivedGeometry().AllLayoutOpportunities(offset,
available_inline_size);
}
// Returns the clearance offset based on the provided {@code clear_type}.
LayoutUnit ClearanceOffset(EClear clear_type) const {
+ if (clear_type == EClear::kNone)
+ return LayoutUnit::Min();
+
return GetDerivedGeometry().ClearanceOffset(clear_type);
}
@@ -59,6 +83,8 @@ class CORE_EXPORT NGExclusionSpace {
return GetDerivedGeometry().LastFloatBlockStart();
}
+ bool IsEmpty() const { return !num_exclusions_; }
+
bool operator==(const NGExclusionSpace& other) const;
bool operator!=(const NGExclusionSpace& other) const {
return !(*this == other);
@@ -142,6 +168,7 @@ class CORE_EXPORT NGExclusionSpace {
// space has, which may differ to the number of exclusions in the Vector.
scoped_refptr<RefVector<scoped_refptr<const NGExclusion>>> exclusions_;
size_t num_exclusions_;
+ LayoutUnit both_clear_offset_;
// The derived geometry struct, is the data-structure which handles all of the
// queries on the exclusion space. It can always be rebuilt from exclusions_
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/exclusions/ng_line_layout_opportunity.h b/chromium/third_party/blink/renderer/core/layout/ng/exclusions/ng_line_layout_opportunity.h
index ee9f8b10141..cf853395678 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/exclusions/ng_line_layout_opportunity.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/exclusions/ng_line_layout_opportunity.h
@@ -16,6 +16,7 @@ namespace blink {
struct CORE_EXPORT NGLineLayoutOpportunity {
STACK_ALLOCATED();
+ public:
NGLineLayoutOpportunity() {}
NGLineLayoutOpportunity(LayoutUnit inline_size)
: line_right_offset(inline_size), float_line_right_offset(inline_size) {}
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/geometry/ng_box_strut.cc b/chromium/third_party/blink/renderer/core/layout/ng/geometry/ng_box_strut.cc
index 88fdc42ff13..f9b117deaaa 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/geometry/ng_box_strut.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/geometry/ng_box_strut.cc
@@ -18,6 +18,10 @@ bool NGBoxStrut::operator==(const NGBoxStrut& other) const {
std::tie(inline_start, inline_end, block_start, block_end);
}
+bool NGBoxStrut::operator!=(const NGBoxStrut& other) const {
+ return !(*this == other);
+}
+
NGPhysicalBoxStrut NGBoxStrut::ConvertToPhysical(
WritingMode writing_mode,
TextDirection direction) const {
@@ -45,8 +49,6 @@ NGPhysicalBoxStrut NGBoxStrut::ConvertToPhysical(
}
}
-// Converts physical dimensions to logical ones per
-// https://drafts.csswg.org/css-writing-modes-3/#logical-to-physical
NGBoxStrut NGPhysicalBoxStrut::ConvertToLogical(WritingMode writing_mode,
TextDirection direction) const {
NGBoxStrut strut;
@@ -70,6 +72,13 @@ NGBoxStrut NGPhysicalBoxStrut::ConvertToLogical(WritingMode writing_mode,
return strut;
}
+NGLineBoxStrut NGPhysicalBoxStrut::ConvertToLineLogical(
+ WritingMode writing_mode,
+ TextDirection direction) const {
+ return NGLineBoxStrut(ConvertToLogical(writing_mode, direction),
+ IsFlippedLinesWritingMode(writing_mode));
+}
+
String NGBoxStrut::ToString() const {
return String::Format("Inline: (%d %d) Block: (%d %d)", inline_start.ToInt(),
inline_end.ToInt(), block_start.ToInt(),
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 dc01037d61b..1f15434c6fd 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
@@ -77,6 +77,7 @@ struct CORE_EXPORT NGBoxStrut {
}
bool operator==(const NGBoxStrut& other) const;
+ bool operator!=(const NGBoxStrut& other) const;
String ToString() const;
@@ -108,6 +109,7 @@ struct CORE_EXPORT NGLineBoxStrut {
NGLineBoxStrut(const NGBoxStrut&, bool is_flipped_lines);
LayoutUnit InlineSum() const { return inline_start + inline_end; }
+ LayoutUnit BlockSum() const { return line_over + line_under; }
LayoutUnit inline_start;
LayoutUnit inline_end;
@@ -128,7 +130,14 @@ struct CORE_EXPORT NGPhysicalBoxStrut {
LayoutUnit left)
: top(top), right(right), bottom(bottom), left(left) {}
+ // Converts physical dimensions to logical ones per
+ // https://drafts.csswg.org/css-writing-modes-3/#logical-to-physical
NGBoxStrut ConvertToLogical(WritingMode, TextDirection) const;
+
+ // Converts physical dimensions to line-relative logical ones per
+ // https://drafts.csswg.org/css-writing-modes-3/#line-directions
+ NGLineBoxStrut ConvertToLineLogical(WritingMode, TextDirection) const;
+
NGPixelSnappedPhysicalBoxStrut SnapToDevicePixels() const;
LayoutUnit HorizontalSum() const { return left + right; }
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/geometry/ng_physical_offset_rect.cc b/chromium/third_party/blink/renderer/core/layout/ng/geometry/ng_physical_offset_rect.cc
index 37dc6f0a2da..1c7546adee7 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/geometry/ng_physical_offset_rect.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/geometry/ng_physical_offset_rect.cc
@@ -28,6 +28,21 @@ void NGPhysicalOffsetRect::Unite(const NGPhysicalOffsetRect& other) {
return;
}
+ UniteEvenIfEmpty(other);
+}
+
+void NGPhysicalOffsetRect::UniteIfNonZero(const NGPhysicalOffsetRect& other) {
+ if (other.size.IsZero())
+ return;
+ if (size.IsZero()) {
+ *this = other;
+ return;
+ }
+
+ UniteEvenIfEmpty(other);
+}
+
+void NGPhysicalOffsetRect::UniteEvenIfEmpty(const NGPhysicalOffsetRect& other) {
LayoutUnit left = std::min(offset.left, other.offset.left);
LayoutUnit top = std::min(offset.top, other.offset.top);
LayoutUnit right = std::max(Right(), other.Right());
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/geometry/ng_physical_offset_rect.h b/chromium/third_party/blink/renderer/core/layout/ng/geometry/ng_physical_offset_rect.h
index 723c8961491..b894db5c435 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/geometry/ng_physical_offset_rect.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/geometry/ng_physical_offset_rect.h
@@ -37,6 +37,8 @@ struct CORE_EXPORT NGPhysicalOffsetRect {
NGPhysicalOffsetRect operator+(const NGPhysicalOffset&) const;
void Unite(const NGPhysicalOffsetRect&);
+ void UniteIfNonZero(const NGPhysicalOffsetRect&);
+ void UniteEvenIfEmpty(const NGPhysicalOffsetRect&);
void Expand(const NGPhysicalBoxStrut&);
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/geometry/ng_physical_size.h b/chromium/third_party/blink/renderer/core/layout/ng/geometry/ng_physical_size.h
index def21e35109..4ae9473aecc 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/geometry/ng_physical_size.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/geometry/ng_physical_size.h
@@ -31,6 +31,9 @@ struct CORE_EXPORT NGPhysicalSize {
bool IsEmpty() const {
return width == LayoutUnit() || height == LayoutUnit();
}
+ bool IsZero() const {
+ return width == LayoutUnit() && height == LayoutUnit();
+ }
// Conversions from/to existing code. New code prefers type safety for
// logical/physical distinctions.
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/layout_ng_text.h b/chromium/third_party/blink/renderer/core/layout/ng/inline/layout_ng_text.h
index 8ea80821037..5a456f2d8cf 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/layout_ng_text.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/layout_ng_text.h
@@ -26,6 +26,7 @@ class CORE_EXPORT LayoutNGText : public LayoutText {
bool IsOfType(LayoutObjectType type) const override {
return type == kLayoutObjectNGText || LayoutText::IsOfType(type);
}
+ bool IsLayoutNGObject() const override { return true; }
bool HasValidLayout() const { return valid_ng_items_; }
const Vector<NGInlineItem*>& InlineItems() const {
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 97202bc6428..6fb04b01720 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
@@ -119,10 +119,9 @@ NGInlineBoxState* NGInlineLayoutStateStack::OnBeginPlaceItems(
box.metrics = box.text_metrics = NGLineHeightMetrics();
if (box.needs_box_fragment) {
// Existing box states are wrapped before they were closed, and hence
- // they do not have start edges.
- box.has_start_edge = false;
- box.margin_inline_start = LayoutUnit();
- box.margin_border_padding_inline_start = LayoutUnit();
+ // they do not have start edges, unless 'box-decoration-break: clone'.
+ box.has_start_edge =
+ box.style->BoxDecorationBreak() == EBoxDecorationBreak::kClone;
}
DCHECK(box.pending_descendants.IsEmpty());
}
@@ -155,18 +154,11 @@ NGInlineBoxState* NGInlineLayoutStateStack::OnOpenTag(
// Compute box properties regardless of needs_box_fragment since close tag may
// also set needs_box_fragment.
- box->padding = item_result.padding;
box->has_start_edge = item_result.has_edge;
- if (box->has_start_edge) {
- box->margin_inline_start = item_result.margins.inline_start;
- // The open tag item has the start margin+border+padding in |inline_size|.
- box->margin_border_padding_inline_start = item_result.inline_size;
- } else {
- DCHECK_EQ(item_result.margins.inline_start, LayoutUnit());
- DCHECK_EQ(item_result.inline_size, LayoutUnit());
- }
- box->border_padding_line_over = item_result.borders_paddings_line_over;
- box->border_padding_line_under = item_result.borders_paddings_line_under;
+ 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;
}
@@ -183,7 +175,10 @@ NGInlineBoxState* NGInlineLayoutStateStack::OnOpenTag(
NGInlineBoxState* NGInlineLayoutStateStack::OnCloseTag(
NGLineBoxFragmentBuilder::ChildList* line_box,
NGInlineBoxState* box,
- FontBaseline baseline_type) {
+ FontBaseline baseline_type,
+ bool has_end_edge) {
+ DCHECK_EQ(box, &stack_.back());
+ box->has_end_edge = has_end_edge;
EndBoxState(box, line_box, baseline_type);
// TODO(kojii): When the algorithm restarts from a break token, the stack may
// underflow. We need either synthesize a missing box state, or push all
@@ -197,6 +192,9 @@ void NGInlineLayoutStateStack::OnEndPlaceItems(
FontBaseline baseline_type) {
for (auto it = stack_.rbegin(); it != stack_.rend(); ++it) {
NGInlineBoxState* box = &(*it);
+ if (!box->has_end_edge && box->needs_box_fragment &&
+ box->style->BoxDecorationBreak() == EBoxDecorationBreak::kClone)
+ box->has_end_edge = true;
EndBoxState(box, line_box, baseline_type);
}
}
@@ -225,27 +223,19 @@ void NGInlineLayoutStateStack::EndBoxState(
// Create box fragments for parent if the current box has properties (e.g.,
// margin) that make it tricky to compute the parent's rects.
if (box->ParentNeedsBoxFragment(parent_box))
- parent_box.SetNeedsBoxFragment();
+ parent_box.SetNeedsBoxFragment(nullptr);
}
-void NGInlineBoxState::SetNeedsBoxFragment() {
+void NGInlineBoxState::SetNeedsBoxFragment(
+ const LayoutObject* inline_container) {
+ // Note: inline_container can also be incorrectly passed as null.
+ // when being set for parent_box. This is ok, because inline_container
+ // is already set correctly inside inline_layout_algorithm.
DCHECK(item);
needs_box_fragment = true;
-}
-
-void NGInlineBoxState::SetLineRightForBoxFragment(
- const NGInlineItem& item,
- const NGInlineItemResult& item_result) {
- DCHECK(needs_box_fragment);
- has_end_edge = item_result.has_edge;
- if (has_end_edge) {
- margin_inline_end = item_result.margins.inline_end;
- // The close tag item has the end margin+border+padding in |inline_size|.
- margin_border_padding_inline_end = item_result.inline_size;
- } else {
- DCHECK_EQ(item_result.margins.inline_end, LayoutUnit());
- DCHECK_EQ(item_result.inline_size, LayoutUnit());
- }
+ // Assign inline_container only if it has not been set.
+ if (!this->inline_container)
+ this->inline_container = inline_container;
}
bool NGInlineBoxState::ParentNeedsBoxFragment(
@@ -254,7 +244,8 @@ bool NGInlineBoxState::ParentNeedsBoxFragment(
return false;
// Below are the known cases where parent rect may not equal the union of
// its child rects.
- if (margin_inline_start || margin_inline_end)
+ if ((has_start_edge && margin_inline_start) ||
+ (has_end_edge && margin_inline_end))
return true;
// Inline box height is determined by font metrics, which can be different
// from the height of its child atomic inline.
@@ -284,11 +275,12 @@ void NGInlineLayoutStateStack::AddBoxFragmentPlaceholder(
// Extend the block direction of the box by borders and paddings. Inline
// direction is already included into positions in NGLineBreaker.
- NGLogicalOffset offset(LayoutUnit(),
- -metrics.ascent - box->border_padding_line_over);
- NGLogicalSize size(LayoutUnit(), metrics.LineHeight() +
- box->border_padding_line_over +
- box->border_padding_line_under);
+ NGLogicalOffset offset(
+ LayoutUnit(),
+ -metrics.ascent - (box->borders.line_over + box->padding.line_over));
+ NGLogicalSize size(
+ LayoutUnit(),
+ metrics.LineHeight() + box->borders.BlockSum() + box->padding.BlockSum());
unsigned fragment_end = line_box->size();
DCHECK(box->item);
@@ -296,17 +288,20 @@ void NGInlineLayoutStateStack::AddBoxFragmentPlaceholder(
BoxData{box->fragment_start, fragment_end, box->item, size});
BoxData& box_data = box_data_list_.back();
box_data.padding = box->padding;
+ box_data.inline_container = box->inline_container;
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_border_padding_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_border_padding_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);
@@ -538,7 +533,7 @@ NGInlineLayoutStateStack::BoxData::CreateBoxFragment(
// NGInlineLayoutAlgorithm can handle them later.
DCHECK(!child.HasInFlowFragment());
}
- box.MoveOutOfFlowDescendantCandidatesToDescendants();
+ box.MoveOutOfFlowDescendantCandidatesToDescendants(inline_container);
return box.ToInlineBoxFragment();
}
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 bfd5b61b6e5..a155e88ea79 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
@@ -15,6 +15,7 @@
namespace blink {
+class LayoutObject;
class NGInlineItem;
struct NGInlineItemResult;
class ShapeResult;
@@ -36,6 +37,7 @@ struct NGInlineBoxState {
unsigned fragment_start = 0;
const NGInlineItem* item = nullptr;
const ComputedStyle* style = nullptr;
+ const LayoutObject* inline_container = nullptr;
// The united metrics for the current box. This includes all objects in this
// box, including descendants, and adjusted by placement properties such as
@@ -57,14 +59,10 @@ struct NGInlineBoxState {
// is set.
bool has_start_edge = false;
bool has_end_edge = false;
- NGLineBoxStrut padding;
- // |CreateBoxFragment()| needs margin, border+padding, and the sum of them.
LayoutUnit margin_inline_start;
LayoutUnit margin_inline_end;
- LayoutUnit margin_border_padding_inline_start;
- LayoutUnit margin_border_padding_inline_end;
- LayoutUnit border_padding_line_over;
- LayoutUnit border_padding_line_under;
+ NGLineBoxStrut borders;
+ NGLineBoxStrut padding;
Vector<NGPendingPositions> pending_descendants;
bool include_used_fonts = false;
@@ -87,9 +85,7 @@ struct NGInlineBoxState {
void AccumulateUsedFonts(const ShapeResult*, FontBaseline);
// Create a box fragment for this box.
- void SetNeedsBoxFragment();
- void SetLineRightForBoxFragment(const NGInlineItem&,
- const NGInlineItemResult&);
+ void SetNeedsBoxFragment(const LayoutObject* inline_container);
// In certain circumstances, the parent's rects is not a simple union of its
// children fragments' rects, e.g., when children have margin. In such cases,
@@ -126,7 +122,8 @@ class CORE_EXPORT NGInlineLayoutStateStack {
// Pop a box state stack.
NGInlineBoxState* OnCloseTag(NGLineBoxFragmentBuilder::ChildList*,
NGInlineBoxState*,
- FontBaseline);
+ FontBaseline,
+ bool has_end_edge = true);
// Compute all the pending positioning at the end of a line.
void OnEndPlaceItems(NGLineBoxFragmentBuilder::ChildList*, FontBaseline);
@@ -183,6 +180,7 @@ class CORE_EXPORT NGInlineLayoutStateStack {
const NGInlineItem* item;
NGLogicalSize size;
+ const LayoutObject* inline_container = nullptr;
bool has_line_left_edge = false;
bool has_line_right_edge = false;
NGLineBoxStrut padding;
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 6ce8dc88622..12b91e93799 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
@@ -7,6 +7,7 @@
#include "third_party/blink/renderer/core/layout/layout_inline.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
+#include "third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h"
namespace blink {
@@ -61,7 +62,7 @@ class NGPhysicalFragmentCollectorBase {
// Traverse descendants unless the fragment is laid out separately from the
// inline layout algorithm.
- if (&fragment != root_fragment_ && fragment.IsBlockLayoutRoot())
+ if (&fragment != root_fragment_ && fragment.IsBlockFormattingContextRoot())
return;
DCHECK(fragment.IsContainer());
@@ -72,7 +73,7 @@ class NGPhysicalFragmentCollectorBase {
for (const auto& child :
ToNGPhysicalContainerFragment(fragment).Children()) {
base::AutoReset<NGPhysicalOffset> offset_resetter(
- &current_offset_to_root_, current_offset_to_root_ + child->Offset());
+ &current_offset_to_root_, current_offset_to_root_ + child.Offset());
base::AutoReset<const NGPhysicalFragment*> fragment_resetter(
&current_fragment_, child.get());
Visit();
@@ -181,30 +182,6 @@ class LayoutInlineCollector final : public NGPhysicalFragmentCollectorBase {
DISALLOW_COPY_AND_ASSIGN(LayoutInlineCollector);
};
-// The visitor emitting all fragments generated from the given LayoutObject.
-class LayoutObjectCollector final : public NGPhysicalFragmentCollectorBase {
- STACK_ALLOCATED();
-
- public:
- explicit LayoutObjectCollector(const LayoutObject* layout_object)
- : target_(layout_object) {}
-
- Vector<Result> CollectFrom(const NGPhysicalFragment& fragment) final {
- return CollectExclusivelyFrom(fragment);
- }
-
- private:
- void Visit() final {
- if (GetFragment().GetLayoutObject() == target_)
- Emit();
- VisitChildren();
- }
-
- const LayoutObject* target_;
-
- DISALLOW_COPY_AND_ASSIGN(LayoutObjectCollector);
-};
-
// The visitor emitting ancestors of the given fragment in bottom-up order.
class AncestorCollector : public NGPhysicalFragmentCollectorBase {
STACK_ALLOCATED();
@@ -271,11 +248,21 @@ class InclusiveAncestorCollector : public NGPhysicalFragmentCollectorBase {
Vector<Result> NGInlineFragmentTraversal::SelfFragmentsOf(
const NGPhysicalContainerFragment& container,
const LayoutObject* layout_object) {
- if (layout_object->IsLayoutInline()) {
- return LayoutInlineCollector(ToLayoutInline(*layout_object))
- .CollectFrom(container);
+ if (const LayoutInline* layout_inline = ToLayoutInlineOrNull(layout_object)) {
+ // TODO(crbug.com/874361): Stop partial culling of inline boxes, so that we
+ // can simply check existence of paint fragments below.
+ if (!layout_inline->HasSelfPaintingLayer()) {
+ return LayoutInlineCollector(ToLayoutInline(*layout_object))
+ .CollectFrom(container);
+ }
+ }
+ Vector<Result> result;
+ for (const NGPaintFragment* fragment :
+ NGPaintFragment::InlineFragmentsFor(layout_object)) {
+ result.push_back(Result{&fragment->PhysicalFragment(),
+ fragment->InlineOffsetToContainerBox()});
}
- return LayoutObjectCollector(layout_object).CollectFrom(container);
+ return result;
}
// static
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_fragment_traversal.h b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_fragment_traversal.h
index ef8bfd61034..5c063598618 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_fragment_traversal.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_fragment_traversal.h
@@ -44,6 +44,14 @@ class CORE_EXPORT NGInlineFragmentTraversal {
// Returns list of inline fragments produced from the specified LayoutObject.
// The search is restricted in the subtree of |container|.
+ // Note: When |target| is a LayoutInline, some/all of its own box fragments
+ // may be absent from the fragment tree, in which case the nearest box/text
+ // descendant fragments are returned.
+ // Note 2: Most callers should use the enclosing block flow fragment of
+ // |target| as |container|. The only exception is
+ // LayoutInline::HitTestCulledInline().
+ // TODO(xiaochengh): As |container| is redundant in most cases, split this
+ // function into two variants that takes/omits |container|.
static Vector<NGPhysicalFragmentWithOffset> SelfFragmentsOf(
const NGPhysicalContainerFragment& container,
const LayoutObject* target);
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 4ae097be73a..5a2e860c8a2 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
@@ -56,8 +56,7 @@ NGInlineItem::NGInlineItem(NGInlineItemType type,
unsigned start,
unsigned end,
const ComputedStyle* style,
- LayoutObject* layout_object,
- bool end_may_collapse)
+ LayoutObject* layout_object)
: start_offset_(start),
end_offset_(end),
style_(style),
@@ -72,7 +71,7 @@ NGInlineItem::NGInlineItem(NGInlineItemType type,
should_create_box_fragment_(false),
style_variant_(static_cast<unsigned>(NGStyleVariant::kStandard)),
end_collapse_type_(kNotCollapsible),
- end_may_collapse_(end_may_collapse),
+ is_end_collapsible_newline_(false),
is_symbol_marker_(false) {
DCHECK_GE(end, start);
ComputeBoxProperties();
@@ -97,7 +96,7 @@ NGInlineItem::NGInlineItem(const NGInlineItem& other,
should_create_box_fragment_(other.should_create_box_fragment_),
style_variant_(other.style_variant_),
end_collapse_type_(other.end_collapse_type_),
- end_may_collapse_(other.end_may_collapse_),
+ is_end_collapsible_newline_(other.is_end_collapsible_newline_),
is_symbol_marker_(other.is_symbol_marker_) {
DCHECK_GE(end, start);
}
@@ -126,6 +125,8 @@ void NGInlineItem::ComputeBoxProperties() {
style_->CanContainFixedPositionObjects(false) ||
ToLayoutBoxModelObject(layout_object_)
->ShouldApplyPaintContainment() ||
+ ToLayoutBoxModelObject(layout_object_)
+ ->ShouldApplyLayoutContainment() ||
CanBeHitTestTargetPseudoNodeStyle(*style_);
}
return;
@@ -327,4 +328,15 @@ bool NGInlineItem::HasEndEdge() const {
!ToLayoutInline(GetLayoutObject())->Continuation();
}
+void NGInlineItem::SetEndCollapseType(NGCollapseType type) {
+ DCHECK(Type() == NGInlineItem::kText || type == kOpaqueToCollapsing ||
+ (Type() == NGInlineItem::kControl && type == kCollapsible));
+ end_collapse_type_ = type;
+}
+
+void NGInlineItem::SetEndCollapseType(NGCollapseType type, bool is_newline) {
+ SetEndCollapseType(type);
+ is_end_collapsible_newline_ = is_newline;
+}
+
} // 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 2e2a046614a..523079722cd 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
@@ -51,12 +51,12 @@ class CORE_EXPORT NGInlineItem {
enum NGCollapseType {
// No collapsible spaces.
kNotCollapsible,
- // A collapsible space run that does not contain segment breaks.
- kCollapsibleSpace,
- // A collapsible space run that contains segment breaks.
- kCollapsibleNewline,
// This item is opaque to whitespace collapsing.
- kOpaqueToCollapsing
+ kOpaqueToCollapsing,
+ // This item ends with collapsible spaces.
+ kCollapsible,
+ // Collapsible spaces at the end of this item were collapsed.
+ kCollapsed,
};
// The constructor and destructor can't be implicit or inlined, because they
@@ -65,8 +65,7 @@ class CORE_EXPORT NGInlineItem {
unsigned start,
unsigned end,
const ComputedStyle* style = nullptr,
- LayoutObject* layout_object = nullptr,
- bool end_may_collapse = false);
+ LayoutObject* layout_object = nullptr);
~NGInlineItem();
// Copy constructor adjusting start/end and shape results.
@@ -123,12 +122,12 @@ class CORE_EXPORT NGInlineItem {
NGCollapseType EndCollapseType() const {
return static_cast<NGCollapseType>(end_collapse_type_);
}
- void SetEndCollapseType(NGCollapseType type) { end_collapse_type_ = type; }
+ void SetEndCollapseType(NGCollapseType type);
- // Whether the item may be affected by whitespace collapsing. Unlike the
- // EndCollapseType() method this returns true even if a trailing space has
- // been removed.
- bool EndMayCollapse() const { return end_may_collapse_; }
+ // Whether the end collapsible space run contains a newline.
+ // Valid only when kCollapsible or kCollapsed.
+ bool IsEndCollapsibleNewline() const { return is_end_collapsible_newline_; }
+ void SetEndCollapseType(NGCollapseType type, bool is_newline);
static void Split(Vector<NGInlineItem>&, unsigned index, unsigned offset);
@@ -189,7 +188,7 @@ class CORE_EXPORT NGInlineItem {
unsigned should_create_box_fragment_ : 1;
unsigned style_variant_ : 2;
unsigned end_collapse_type_ : 2; // NGCollapseType
- unsigned end_may_collapse_ : 1;
+ unsigned is_end_collapsible_newline_ : 1;
unsigned is_symbol_marker_ : 1;
friend class NGInlineNode;
};
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 50ee0dee064..d81c185d04e 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
@@ -80,16 +80,8 @@ LayoutUnit NGLineInfo::ComputeWidth() const {
return inline_size;
}
-void NGLineInfo::SetLineBfcOffset(NGBfcOffset line_bfc_offset,
- LayoutUnit available_width,
- LayoutUnit width) {
- line_bfc_offset_ = line_bfc_offset;
- available_width_ = available_width;
- width_ = width;
-}
-
void NGLineInfo::SetLineEndFragment(
- scoped_refptr<NGPhysicalTextFragment> fragment) {
+ scoped_refptr<const NGPhysicalTextFragment> fragment) {
line_end_fragment_ = std::move(fragment);
}
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 70ecc25ca16..1f4d8982ebd 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
@@ -50,14 +50,12 @@ struct CORE_EXPORT NGInlineItemResult {
// NGLayoutResult for atomic inline items.
scoped_refptr<NGLayoutResult> layout_result;
- // Margins and padding for atomic inline items and open/close tags.
+ // Margins, borders, and padding for open tags.
+ // Margins are set for atomic inlines too.
NGLineBoxStrut margins;
+ NGLineBoxStrut borders;
NGLineBoxStrut padding;
- // Borders/padding for open tags.
- LayoutUnit borders_paddings_line_over;
- LayoutUnit borders_paddings_line_under;
-
// Has start/end edge for open/close tags.
bool has_edge = false;
@@ -163,13 +161,17 @@ class CORE_EXPORT NGLineInfo {
LayoutUnit TextIndent() const { return text_indent_; }
- NGBfcOffset LineBfcOffset() const { return line_bfc_offset_; }
+ NGBfcOffset BfcOffset() const { return bfc_offset_; }
LayoutUnit AvailableWidth() const { return available_width_; }
- LayoutUnit Width() const { return width_; }
+ LayoutUnit Width() const { return width_.ClampNegativeToZero(); }
+ LayoutUnit WidthForAlignment() const { return width_; }
LayoutUnit ComputeWidth() const;
- void SetLineBfcOffset(NGBfcOffset line_bfc_offset,
- LayoutUnit available_width,
- LayoutUnit width);
+
+ void SetBfcOffset(const NGBfcOffset& bfc_offset) { bfc_offset_ = bfc_offset; }
+ void SetWidth(LayoutUnit available_width, LayoutUnit width) {
+ available_width_ = available_width;
+ width_ = width;
+ }
// Start text offset of this line.
unsigned StartOffset() const { return start_offset_; }
@@ -182,18 +184,19 @@ class CORE_EXPORT NGLineInfo {
}
// Fragment to append to the line end. Used by 'text-overflow: ellipsis'.
- scoped_refptr<NGPhysicalTextFragment>& LineEndFragment() {
+ scoped_refptr<const NGPhysicalTextFragment>& LineEndFragment() {
return line_end_fragment_;
}
- void SetLineEndFragment(scoped_refptr<NGPhysicalTextFragment>);
+ void SetLineEndFragment(scoped_refptr<const NGPhysicalTextFragment>);
private:
const NGInlineItemsData* items_data_ = nullptr;
const ComputedStyle* line_style_ = nullptr;
NGInlineItemResults results_;
- scoped_refptr<NGPhysicalTextFragment> line_end_fragment_;
+ scoped_refptr<const NGPhysicalTextFragment> line_end_fragment_;
+
+ NGBfcOffset bfc_offset_;
- NGBfcOffset line_bfc_offset_;
LayoutUnit available_width_;
LayoutUnit width_;
LayoutUnit text_indent_;
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 ae1cb609e0a..ddca6f5e37d 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
@@ -6,6 +6,7 @@
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/layout/layout_text.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/layout_ng_text.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_builder.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
@@ -20,29 +21,9 @@ NGInlineItemsBuilderTemplate<
template <typename OffsetMappingBuilder>
String NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::ToString() {
- // Segment Break Transformation Rules[1] defines to keep trailing new lines in
- // Phase I, but to remove after line break, in Phase II[2]. Although the spec
- // defines so, trailing collapsible spaces at the end of an inline formatting
- // context will be removed in Phase II and that removing here makes no
- // differences.
- //
- // However, doing so reduces the opportunities to re-use NGInlineItem a lot in
- // appending scenario, which is quite common. In order to re-use NGInlineItem
- // as much as posssible, trailing spaces are removed in Phase II, exactly as
- // defined in the spec.
- //
- // [1] https://drafts.csswg.org/css-text-3/#line-break-transform
- // [2] https://drafts.csswg.org/css-text-3/#white-space-phase-2
- return text_.ToString();
-}
-
-template <>
-String NGInlineItemsBuilderTemplate<NGOffsetMappingBuilder>::ToString() {
- // While trailing collapsible space is kept as above, NGOffsetMappingBuilder
- // assumes NGLineBreaker does not remove it. For now, remove only for
- // NGOffsetMappingBuilder.
- // TODO(kojii): Consider NGOffsetMappingBuilder to support NGLineBreaker to
- // remove trailing spaces.
+ // Segment Break Transformation Rules[1] defines to keep trailing new lines,
+ // but it will be removed in Phase II[2]. We prefer not to add trailing new
+ // lines and collapsible spaces in Phase I.
RemoveTrailingCollapsibleSpaceIfExists();
return text_.ToString();
@@ -132,10 +113,8 @@ void AppendItem(Vector<NGInlineItem>* items,
unsigned start,
unsigned end,
const ComputedStyle* style = nullptr,
- LayoutObject* layout_object = nullptr,
- bool end_may_collapse = false) {
- items->push_back(
- NGInlineItem(type, start, end, style, layout_object, end_may_collapse));
+ LayoutObject* layout_object = nullptr) {
+ items->push_back(NGInlineItem(type, start, end, style, layout_object));
}
inline bool ShouldIgnore(UChar c) {
@@ -193,26 +172,68 @@ NGInlineItem* LastItemToCollapseWith(Vector<NGInlineItem>* items) {
return nullptr;
}
-inline bool MayCollapseWithLast(const NGInlineItem* item) {
- return item && item->EndMayCollapse();
-}
-
} // anonymous namespace
template <typename OffsetMappingBuilder>
bool NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::Append(
const String& original_string,
- LayoutObject* layout_object,
+ LayoutNGText* layout_text,
const Vector<NGInlineItem*>& items) {
// Don't reuse existing items if they might be affected by whitespace
// collapsing.
// TODO(layout-dev): This could likely be optimized further.
// TODO(layout-dev): Handle cases where the old items are not consecutive.
- if (MayCollapseWithLast(LastItemToCollapseWith(items_)) ||
- IsCollapsibleSpace(original_string[items[0]->StartOffset()]))
- return false;
+ const ComputedStyle& new_style = layout_text->StyleRef();
+ bool collapse_spaces = new_style.CollapseWhiteSpace();
+ if (NGInlineItem* last_item = LastItemToCollapseWith(items_)) {
+ const NGInlineItem& old_item0 = *items[0];
+ if (collapse_spaces) {
+ DCHECK_GT(old_item0.Length(), 0u);
+ switch (last_item->EndCollapseType()) {
+ case NGInlineItem::kCollapsible:
+ // If the original string starts with a collapsible space, it may be
+ // collapsed.
+ if (original_string[old_item0.StartOffset()] == kSpaceCharacter)
+ return false;
+ break;
+ case NGInlineItem::kNotCollapsible: {
+ // If the start of the original string was collapsed, it may be
+ // restored.
+ const String& source_text = layout_text->GetText();
+ if (source_text.length() && IsCollapsibleSpace(source_text[0]) &&
+ original_string[old_item0.StartOffset()] != kSpaceCharacter)
+ return false;
+ break;
+ }
+ case NGInlineItem::kCollapsed:
+ RestoreTrailingCollapsibleSpace(last_item);
+ return false;
+ case NGInlineItem::kOpaqueToCollapsing:
+ NOTREACHED();
+ break;
+ }
+ }
+
+ // On nowrap -> wrap boundary, a break opporunity may be inserted.
+ DCHECK(last_item->Style());
+ if (!last_item->Style()->AutoWrap() && new_style.AutoWrap())
+ return false;
+
+ } else if (collapse_spaces) {
+ // If the original string starts with a collapsible space, it may be
+ // collapsed because it is now a leading collapsible space.
+ const NGInlineItem& old_item0 = *items[0];
+ DCHECK_GT(old_item0.Length(), 0u);
+ if (original_string[old_item0.StartOffset()] == kSpaceCharacter)
+ return false;
+ }
for (const NGInlineItem* item : items) {
+ // Collapsed space item at the start will not be restored, and that not
+ // needed to add.
+ if (!text_.length() && !item->Length() && collapse_spaces)
+ continue;
+
unsigned start = text_.length();
text_.Append(original_string, item->StartOffset(), item->Length());
@@ -227,16 +248,28 @@ bool NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::Append(
// If the position has shifted the item and the shape result needs to be
// adjusted to reflect the new start and end offsets.
unsigned end = start + item->Length();
- DCHECK(item->TextShapeResult());
- NGInlineItem adjusted_item(
- *item, start, end, item->TextShapeResult()->CopyAdjustedOffset(start));
+ scoped_refptr<ShapeResult> adjusted_shape_result;
+ if (item->TextShapeResult()) {
+ DCHECK_EQ(item->Type(), NGInlineItem::kText);
+ adjusted_shape_result =
+ item->TextShapeResult()->CopyAdjustedOffset(start);
+ DCHECK(adjusted_shape_result);
+ } else {
+ // The following should be true, but some unit tests fail.
+ // DCHECK_EQ(item->Type(), NGInlineItem::kControl);
+ }
+ NGInlineItem adjusted_item(*item, start, end,
+ std::move(adjusted_shape_result));
- DCHECK(adjusted_item.TextShapeResult());
+#if DCHECK_IS_ON()
DCHECK_EQ(start, adjusted_item.StartOffset());
- DCHECK_EQ(start, adjusted_item.TextShapeResult()->StartIndexForResult());
DCHECK_EQ(end, adjusted_item.EndOffset());
- DCHECK_EQ(end, adjusted_item.TextShapeResult()->EndIndexForResult());
+ if (adjusted_item.TextShapeResult()) {
+ DCHECK_EQ(start, adjusted_item.TextShapeResult()->StartIndexForResult());
+ DCHECK_EQ(end, adjusted_item.TextShapeResult()->EndIndexForResult());
+ }
DCHECK_EQ(item->IsEmptyItem(), adjusted_item.IsEmptyItem());
+#endif
items_->push_back(adjusted_item);
is_empty_inline_ &= adjusted_item.IsEmptyItem();
@@ -247,7 +280,7 @@ bool NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::Append(
template <>
bool NGInlineItemsBuilderTemplate<NGOffsetMappingBuilder>::Append(
const String&,
- LayoutObject*,
+ LayoutNGText*,
const Vector<NGInlineItem*>&) {
NOTREACHED();
return false;
@@ -268,6 +301,8 @@ void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::Append(
EWhiteSpace whitespace = style->WhiteSpace();
bool is_svg_text = layout_object && layout_object->IsSVGInlineText();
+ RestoreTrailingCollapsibleSpaceIfRemoved();
+
if (!ComputedStyle::CollapseWhiteSpace(whitespace))
AppendPreserveWhitespace(string, style, layout_object);
else if (ComputedStyle::PreserveNewline(whitespace) && !is_svg_text)
@@ -299,9 +334,10 @@ void NGInlineItemsBuilderTemplate<
NGInlineItem::NGCollapseType end_collapse = NGInlineItem::kNotCollapsible;
unsigned i = 0;
UChar c = string[i];
+ bool space_run_has_newline = false;
if (IsCollapsibleSpace(c)) {
// Find the end of the collapsible space run.
- bool space_run_has_newline = MoveToEndOfCollapsibleSpaces(string, &i, &c);
+ space_run_has_newline = MoveToEndOfCollapsibleSpaces(string, &i, &c);
// LayoutBR does not set preserve_newline, but should be preserved.
if (UNLIKELY(space_run_has_newline && string.length() == 1 &&
@@ -320,15 +356,13 @@ void NGInlineItemsBuilderTemplate<
} else {
// The last item ends with a collapsible space this run should collapse
// to. Collapse the entire space run in this item.
- DCHECK(item->EndCollapseType() == NGInlineItem::kCollapsibleSpace ||
- item->EndCollapseType() == NGInlineItem::kCollapsibleNewline);
+ DCHECK(item->EndCollapseType() == NGInlineItem::kCollapsible);
insert_space = false;
// If the space run either in this item or in the last item contains a
// newline, apply segment break rules. This may result in removal of
// the space in the last item.
- if ((space_run_has_newline ||
- item->EndCollapseType() == NGInlineItem::kCollapsibleNewline) &&
+ if ((space_run_has_newline || item->IsEndCollapsibleNewline()) &&
item->Type() == NGInlineItem::kText &&
ShouldRemoveNewline(text_, item->EndOffset() - 1, item->Style(),
StringView(string, i), style)) {
@@ -380,15 +414,15 @@ void NGInlineItemsBuilderTemplate<
// If this space run is at the end of this item, keep whether the
// collapsible space run has a newline or not in the item.
if (i == string.length()) {
- end_collapse = space_run_has_newline ? NGInlineItem::kCollapsibleNewline
- : NGInlineItem::kCollapsibleSpace;
+ end_collapse = NGInlineItem::kCollapsible;
}
} else {
// If the last item ended with a collapsible space run with segment breaks,
// apply segment break rules. This may result in removal of the space in the
// last item.
if (NGInlineItem* item = LastItemToCollapseWith(items_)) {
- if (item->EndCollapseType() == NGInlineItem::kCollapsibleNewline &&
+ if (item->EndCollapseType() == NGInlineItem::kCollapsible &&
+ item->IsEndCollapsibleNewline() &&
ShouldRemoveNewline(text_, item->EndOffset() - 1, item->Style(),
string, style)) {
RemoveTrailingCollapsibleSpace(item);
@@ -413,14 +447,16 @@ void NGInlineItemsBuilderTemplate<
text_.Append(string, start_of_non_space, i - start_of_non_space);
mapping_builder_.AppendIdentityMapping(i - start_of_non_space);
- if (i == string.length())
+ if (i == string.length()) {
+ DCHECK_EQ(end_collapse, NGInlineItem::kNotCollapsible);
break;
+ }
// Process a collapsible space run. First, find the end of the run.
DCHECK_EQ(c, string[i]);
DCHECK(IsCollapsibleSpace(c));
unsigned start_of_spaces = i;
- bool space_run_has_newline = MoveToEndOfCollapsibleSpaces(string, &i, &c);
+ space_run_has_newline = MoveToEndOfCollapsibleSpaces(string, &i, &c);
// Because leading spaces are handled before this loop, no need to check
// cross-item collapsing.
@@ -445,8 +481,7 @@ void NGInlineItemsBuilderTemplate<
// If this space run is at the end of this item, keep whether the
// collapsible space run has a newline or not in the item.
if (i == string.length()) {
- end_collapse = space_run_has_newline ? NGInlineItem::kCollapsibleNewline
- : NGInlineItem::kCollapsibleSpace;
+ end_collapse = NGInlineItem::kCollapsible;
break;
}
}
@@ -454,9 +489,9 @@ void NGInlineItemsBuilderTemplate<
if (text_.length() > start_offset) {
AppendItem(items_, NGInlineItem::kText, start_offset, text_.length(), style,
- layout_object, end_collapse != NGInlineItem::kNotCollapsible);
+ layout_object);
NGInlineItem& item = items_->back();
- item.SetEndCollapseType(end_collapse);
+ item.SetEndCollapseType(end_collapse, space_run_has_newline);
is_empty_inline_ &= item.IsEmptyItem();
}
}
@@ -534,7 +569,7 @@ void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::AppendForcedBreak(
// are leading spaces and that they should be collapsed.
// Pretend that this item ends with a collapsible space, so that following
// collapsible spaces can be collapsed.
- items_->back().SetEndCollapseType(NGInlineItem::kCollapsibleSpace);
+ items_->back().SetEndCollapseType(NGInlineItem::kCollapsible, false);
// Then re-add bidi controls to restore the bidi context.
if (!bidi_context_.IsEmpty()) {
@@ -585,6 +620,7 @@ void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::AppendAtomicInline(
LayoutObject* layout_object) {
typename OffsetMappingBuilder::SourceNodeScope scope(&mapping_builder_,
layout_object);
+ RestoreTrailingCollapsibleSpaceIfRemoved();
Append(NGInlineItem::kAtomicInline, kObjectReplacementCharacter, style,
layout_object);
}
@@ -623,7 +659,7 @@ template <typename OffsetMappingBuilder>
void NGInlineItemsBuilderTemplate<
OffsetMappingBuilder>::RemoveTrailingCollapsibleSpaceIfExists() {
if (NGInlineItem* item = LastItemToCollapseWith(items_)) {
- if (item->EndCollapseType() != NGInlineItem::kNotCollapsible)
+ if (item->EndCollapseType() == NGInlineItem::kCollapsible)
RemoveTrailingCollapsibleSpace(item);
}
}
@@ -633,9 +669,8 @@ template <typename OffsetMappingBuilder>
void NGInlineItemsBuilderTemplate<
OffsetMappingBuilder>::RemoveTrailingCollapsibleSpace(NGInlineItem* item) {
DCHECK(item);
+ DCHECK_EQ(item->EndCollapseType(), NGInlineItem::kCollapsible);
DCHECK_GT(item->Length(), 0u);
- DCHECK(item->EndCollapseType() == NGInlineItem::kCollapsibleSpace ||
- item->EndCollapseType() == NGInlineItem::kCollapsibleNewline);
// A forced break pretends that it's a collapsible space, see
// |AppendForcedBreak()|. It should not be removed.
@@ -643,10 +678,11 @@ void NGInlineItemsBuilderTemplate<
return;
DCHECK_EQ(item->Type(), NGInlineItem::kText);
+ DCHECK_GT(item->EndOffset(), item->StartOffset());
unsigned space_offset = item->EndOffset() - 1;
DCHECK_EQ(text_[space_offset], kSpaceCharacter);
text_.erase(space_offset);
- mapping_builder_.CollapseTrailingSpace(text_.length() - space_offset);
+ mapping_builder_.CollapseTrailingSpace(space_offset);
// Remove the item if the item has only one space that we're removing.
if (item->Length() == 1) {
@@ -659,7 +695,7 @@ void NGInlineItemsBuilderTemplate<
item = &(*items_)[index];
} else {
item->SetEndOffset(item->EndOffset() - 1);
- item->SetEndCollapseType(NGInlineItem::kNotCollapsible);
+ item->SetEndCollapseType(NGInlineItem::kCollapsed);
item++;
}
@@ -670,6 +706,42 @@ void NGInlineItemsBuilderTemplate<
}
}
+// Restore removed collapsible space at the end of items.
+template <typename OffsetMappingBuilder>
+void NGInlineItemsBuilderTemplate<
+ OffsetMappingBuilder>::RestoreTrailingCollapsibleSpaceIfRemoved() {
+ if (NGInlineItem* last_item = LastItemToCollapseWith(items_)) {
+ if (last_item->EndCollapseType() == NGInlineItem::kCollapsed)
+ RestoreTrailingCollapsibleSpace(last_item);
+ }
+}
+
+// Restore removed collapsible space at the end of the specified item.
+template <typename OffsetMappingBuilder>
+void NGInlineItemsBuilderTemplate<
+ OffsetMappingBuilder>::RestoreTrailingCollapsibleSpace(NGInlineItem* item) {
+ DCHECK(item);
+ DCHECK(item->EndCollapseType() == NGInlineItem::kCollapsed);
+
+ // TODO(kojii): Implement StringBuilder::insert().
+ if (text_.length() == item->EndOffset()) {
+ text_.Append(' ');
+ } else {
+ String current = text_.ToString();
+ text_.Clear();
+ text_.Append(StringView(current, 0, item->EndOffset()));
+ text_.Append(' ');
+ text_.Append(StringView(current, item->EndOffset()));
+ }
+
+ item->SetEndOffset(item->EndOffset() + 1);
+ item->SetEndCollapseType(NGInlineItem::kCollapsible);
+
+ for (item++; item != items_->end(); item++) {
+ item->SetOffset(item->StartOffset() + 1, item->EndOffset() + 1);
+ }
+}
+
template <typename OffsetMappingBuilder>
void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::EnterBidiContext(
LayoutObject* node,
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 e944f9ac38f..0d5b52ad314 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
@@ -17,6 +17,7 @@
namespace blink {
class ComputedStyle;
+class LayoutNGText;
class LayoutObject;
class LayoutText;
@@ -57,7 +58,7 @@ class NGInlineItemsBuilderTemplate {
// Returns whether the existing items could be reused.
// NOTE: The state of the builder remains unchanged if the append operation
// fails (i.e. if it returns false).
- bool Append(const String&, LayoutObject*, const Vector<NGInlineItem*>&);
+ bool Append(const String&, LayoutNGText*, const Vector<NGInlineItem*>&);
// Append a string.
// When appending, spaces are collapsed according to CSS Text, The white space
@@ -153,17 +154,16 @@ class NGInlineItemsBuilderTemplate {
void RemoveTrailingCollapsibleSpaceIfExists();
void RemoveTrailingCollapsibleSpace(NGInlineItem*);
+ void RestoreTrailingCollapsibleSpaceIfRemoved();
+ void RestoreTrailingCollapsibleSpace(NGInlineItem*);
+
void Exit(LayoutObject*);
};
template <>
-CORE_EXPORT String
-NGInlineItemsBuilderTemplate<NGOffsetMappingBuilder>::ToString();
-
-template <>
CORE_EXPORT bool NGInlineItemsBuilderTemplate<NGOffsetMappingBuilder>::Append(
const String&,
- LayoutObject*,
+ LayoutNGText*,
const Vector<NGInlineItem*>&);
extern template class CORE_EXTERN_TEMPLATE_EXPORT
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 1d75a511be4..1e3400b9086 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
@@ -6,9 +6,9 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/core/layout/layout_inline.h"
-#include "third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_builder.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/layout_ng_text.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_layout_test.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
-#include "third_party/blink/renderer/core/testing/page_test_base.h"
namespace blink {
@@ -19,32 +19,10 @@ namespace {
EXPECT_EQ(start, (item).StartOffset()); \
EXPECT_EQ(end, (item).EndOffset());
-static String GetCollapsed(const NGOffsetMappingBuilder& builder) {
- Vector<unsigned> mapping = builder.DumpOffsetMappingForTesting();
-
- Vector<unsigned> collapsed_indexes;
- for (unsigned i = 0; i + 1 < mapping.size(); ++i) {
- if (mapping[i] == mapping[i + 1])
- collapsed_indexes.push_back(i);
- }
-
- StringBuilder result;
- result.Append('{');
- bool first = true;
- for (unsigned index : collapsed_indexes) {
- if (!first)
- result.Append(", ");
- result.AppendNumber(index);
- first = false;
- }
- result.Append('}');
- return result.ToString();
-}
-
-class NGInlineItemsBuilderTest : public PageTestBase {
+class NGInlineItemsBuilderTest : public NGLayoutTest {
protected:
void SetUp() override {
- PageTestBase::SetUp();
+ NGLayoutTest::SetUp();
style_ = ComputedStyle::Create();
}
@@ -69,17 +47,16 @@ class NGInlineItemsBuilderTest : public PageTestBase {
const String& TestAppend(Vector<Input> inputs) {
items_.clear();
Vector<LayoutText*> anonymous_objects;
- NGInlineItemsBuilderForOffsetMapping builder(&items_);
+ NGInlineItemsBuilder builder(&items_);
for (Input& input : inputs) {
if (!input.layout_text) {
- input.layout_text = LayoutText::CreateEmptyAnonymous(GetDocument());
+ input.layout_text = LayoutText::CreateEmptyAnonymous(
+ GetDocument(), GetStyle(input.whitespace));
anonymous_objects.push_back(input.layout_text);
}
- builder.Append(input.text, GetStyle(input.whitespace).get(),
- input.layout_text);
+ builder.Append(input.text, input.layout_text->Style(), input.layout_text);
}
text_ = builder.ToString();
- collapsed_ = GetCollapsed(builder.GetOffsetMappingBuilder());
ValidateItems();
CheckReuseItemsProducesSameResult(inputs);
for (LayoutObject* anonymous_object : anonymous_objects)
@@ -126,178 +103,122 @@ class NGInlineItemsBuilderTest : public PageTestBase {
}
// Try to re-use previous items, or Append if it was not re-usable.
- bool reused = !previous_items.IsEmpty() &&
- reuse_builder.Append(text_, nullptr, previous_items);
+ bool reused =
+ !previous_items.IsEmpty() &&
+ reuse_builder.Append(text_, ToLayoutNGText(input.layout_text),
+ previous_items);
if (!reused)
- reuse_builder.Append(input.text, style_.get());
+ reuse_builder.Append(input.text, input.layout_text->Style());
}
- // Currently, NGInlineItemsBuilder does not strip trailing spaces while
- // NGInlineItemsBuilderForOffsetMapping does. See
- // NGInlineItemsBuilderTemplate<NGOffsetMappingBuilder>::ToString().
String reuse_text = reuse_builder.ToString();
- if (!reuse_text.IsEmpty() && reuse_text != text_ &&
- reuse_text[reuse_text.length() - 1] == kSpaceCharacter)
- reuse_text = reuse_text.Substring(0, reuse_text.length() - 1);
EXPECT_EQ(text_, reuse_text);
}
Vector<NGInlineItem> items_;
String text_;
- String collapsed_;
scoped_refptr<ComputedStyle> style_;
};
-#define TestWhitespaceValue(expected_text, expected_collapsed, input, \
- whitespace) \
- SetWhiteSpace(whitespace); \
- EXPECT_EQ(expected_text, TestAppend(input)) << "white-space: " #whitespace; \
- EXPECT_EQ(expected_collapsed, collapsed_);
+#define TestWhitespaceValue(expected_text, input, whitespace) \
+ SetWhiteSpace(whitespace); \
+ EXPECT_EQ(expected_text, TestAppend(input)) << "white-space: " #whitespace;
TEST_F(NGInlineItemsBuilderTest, CollapseSpaces) {
String input("text text text text");
String collapsed("text text text text");
- String collapsed_indexes("{10, 16, 17}");
- TestWhitespaceValue(collapsed, collapsed_indexes, input,
- EWhiteSpace::kNormal);
- TestWhitespaceValue(collapsed, collapsed_indexes, input,
- EWhiteSpace::kNowrap);
- TestWhitespaceValue(collapsed, collapsed_indexes, input,
- EWhiteSpace::kWebkitNowrap);
- TestWhitespaceValue(collapsed, collapsed_indexes, input,
- EWhiteSpace::kPreLine);
- TestWhitespaceValue(input, "{}", input, EWhiteSpace::kPre);
- TestWhitespaceValue(input, "{}", input, EWhiteSpace::kPreWrap);
+ TestWhitespaceValue(collapsed, input, EWhiteSpace::kNormal);
+ TestWhitespaceValue(collapsed, input, EWhiteSpace::kNowrap);
+ TestWhitespaceValue(collapsed, input, EWhiteSpace::kWebkitNowrap);
+ TestWhitespaceValue(collapsed, input, EWhiteSpace::kPreLine);
+ TestWhitespaceValue(input, input, EWhiteSpace::kPre);
+ TestWhitespaceValue(input, input, EWhiteSpace::kPreWrap);
}
TEST_F(NGInlineItemsBuilderTest, CollapseTabs) {
String input("text text text text");
String collapsed("text text text text");
- String collapsed_indexes("{10, 16, 17}");
- TestWhitespaceValue(collapsed, collapsed_indexes, input,
- EWhiteSpace::kNormal);
- TestWhitespaceValue(collapsed, collapsed_indexes, input,
- EWhiteSpace::kNowrap);
- TestWhitespaceValue(collapsed, collapsed_indexes, input,
- EWhiteSpace::kWebkitNowrap);
- TestWhitespaceValue(collapsed, collapsed_indexes, input,
- EWhiteSpace::kPreLine);
- TestWhitespaceValue(input, "{}", input, EWhiteSpace::kPre);
- TestWhitespaceValue(input, "{}", input, EWhiteSpace::kPreWrap);
+ TestWhitespaceValue(collapsed, input, EWhiteSpace::kNormal);
+ TestWhitespaceValue(collapsed, input, EWhiteSpace::kNowrap);
+ TestWhitespaceValue(collapsed, input, EWhiteSpace::kWebkitNowrap);
+ TestWhitespaceValue(collapsed, input, EWhiteSpace::kPreLine);
+ TestWhitespaceValue(input, input, EWhiteSpace::kPre);
+ TestWhitespaceValue(input, input, EWhiteSpace::kPreWrap);
}
TEST_F(NGInlineItemsBuilderTest, CollapseNewLines) {
String input("text\ntext \n text\n\ntext");
String collapsed("text text text text");
- String collapsed_indexes("{10, 11, 17}");
- TestWhitespaceValue(collapsed, collapsed_indexes, input,
- EWhiteSpace::kNormal);
- TestWhitespaceValue(collapsed, collapsed_indexes, input,
- EWhiteSpace::kNowrap);
- TestWhitespaceValue("text\ntext\ntext\n\ntext", "{9, 11}", input,
- EWhiteSpace::kPreLine);
- TestWhitespaceValue(input, "{}", input, EWhiteSpace::kPre);
- TestWhitespaceValue(input, "{}", input, EWhiteSpace::kPreWrap);
+ TestWhitespaceValue(collapsed, input, EWhiteSpace::kNormal);
+ TestWhitespaceValue(collapsed, input, EWhiteSpace::kNowrap);
+ TestWhitespaceValue("text\ntext\ntext\n\ntext", input, EWhiteSpace::kPreLine);
+ TestWhitespaceValue(input, input, EWhiteSpace::kPre);
+ TestWhitespaceValue(input, input, EWhiteSpace::kPreWrap);
}
TEST_F(NGInlineItemsBuilderTest, CollapseNewlinesAsSpaces) {
EXPECT_EQ("text text", TestAppend("text\ntext"));
- EXPECT_EQ("{}", collapsed_);
EXPECT_EQ("text text", TestAppend("text\n\ntext"));
- EXPECT_EQ("{5}", collapsed_);
EXPECT_EQ("text text", TestAppend("text \n\n text"));
- EXPECT_EQ("{5, 6, 7}", collapsed_);
EXPECT_EQ("text text", TestAppend("text \n \n text"));
- EXPECT_EQ("{5, 6, 7, 8}", collapsed_);
}
TEST_F(NGInlineItemsBuilderTest, CollapseAcrossElements) {
EXPECT_EQ("text text", TestAppend("text ", " text"))
<< "Spaces are collapsed even when across elements.";
- EXPECT_EQ("{5}", collapsed_);
}
TEST_F(NGInlineItemsBuilderTest, CollapseLeadingSpaces) {
EXPECT_EQ("text", TestAppend(" text"));
- EXPECT_EQ("{0, 1}", collapsed_);
EXPECT_EQ("text", TestAppend(" ", "text"));
- EXPECT_EQ("{0}", collapsed_);
EXPECT_EQ("text", TestAppend(" ", " text"));
- EXPECT_EQ("{0, 1}", collapsed_);
}
TEST_F(NGInlineItemsBuilderTest, CollapseTrailingSpaces) {
EXPECT_EQ("text", TestAppend("text "));
- EXPECT_EQ("{4, 5}", collapsed_);
EXPECT_EQ("text", TestAppend("text", " "));
- EXPECT_EQ("{4}", collapsed_);
EXPECT_EQ("text", TestAppend("text ", " "));
- EXPECT_EQ("{4, 5}", collapsed_);
}
TEST_F(NGInlineItemsBuilderTest, CollapseAllSpaces) {
EXPECT_EQ("", TestAppend(" "));
- EXPECT_EQ("{0, 1}", collapsed_);
EXPECT_EQ("", TestAppend(" ", " "));
- EXPECT_EQ("{0, 1, 2, 3}", collapsed_);
EXPECT_EQ("", TestAppend(" ", "\n"));
- EXPECT_EQ("{0, 1, 2}", collapsed_);
EXPECT_EQ("", TestAppend("\n", " "));
- EXPECT_EQ("{0, 1, 2}", collapsed_);
}
TEST_F(NGInlineItemsBuilderTest, CollapseLeadingNewlines) {
EXPECT_EQ("text", TestAppend("\ntext"));
- EXPECT_EQ("{0}", collapsed_);
EXPECT_EQ("text", TestAppend("\n\ntext"));
- EXPECT_EQ("{0, 1}", collapsed_);
EXPECT_EQ("text", TestAppend("\n", "text"));
- EXPECT_EQ("{0}", collapsed_);
EXPECT_EQ("text", TestAppend("\n\n", "text"));
- EXPECT_EQ("{0, 1}", collapsed_);
EXPECT_EQ("text", TestAppend(" \n", "text"));
- EXPECT_EQ("{0, 1}", collapsed_);
EXPECT_EQ("text", TestAppend("\n", " text"));
- EXPECT_EQ("{0, 1}", collapsed_);
EXPECT_EQ("text", TestAppend("\n\n", " text"));
- EXPECT_EQ("{0, 1, 2}", collapsed_);
EXPECT_EQ("text", TestAppend(" \n", " text"));
- EXPECT_EQ("{0, 1, 2}", collapsed_);
EXPECT_EQ("text", TestAppend("\n", "\ntext"));
- EXPECT_EQ("{0, 1}", collapsed_);
EXPECT_EQ("text", TestAppend("\n\n", "\ntext"));
- EXPECT_EQ("{0, 1, 2}", collapsed_);
EXPECT_EQ("text", TestAppend(" \n", "\ntext"));
- EXPECT_EQ("{0, 1, 2}", collapsed_);
}
TEST_F(NGInlineItemsBuilderTest, CollapseTrailingNewlines) {
EXPECT_EQ("text", TestAppend("text\n"));
- EXPECT_EQ("{4}", collapsed_);
EXPECT_EQ("text", TestAppend("text", "\n"));
- EXPECT_EQ("{4}", collapsed_);
EXPECT_EQ("text", TestAppend("text\n", "\n"));
- EXPECT_EQ("{4, 5}", collapsed_);
EXPECT_EQ("text", TestAppend("text\n", " "));
- EXPECT_EQ("{4, 5}", collapsed_);
EXPECT_EQ("text", TestAppend("text ", "\n"));
- EXPECT_EQ("{4, 5}", collapsed_);
}
TEST_F(NGInlineItemsBuilderTest, CollapseNewlineAcrossElements) {
EXPECT_EQ("text text", TestAppend("text ", "\ntext"));
- EXPECT_EQ("{5}", collapsed_);
EXPECT_EQ("text text", TestAppend("text ", "\n text"));
- EXPECT_EQ("{5, 6}", collapsed_);
EXPECT_EQ("text text", TestAppend("text", " ", "\ntext"));
- EXPECT_EQ("{5}", collapsed_);
}
TEST_F(NGInlineItemsBuilderTest, CollapseBeforeAndAfterNewline) {
SetWhiteSpace(EWhiteSpace::kPreLine);
EXPECT_EQ("text\ntext", TestAppend("text \n text"))
<< "Spaces before and after newline are removed.";
- EXPECT_EQ("{4, 5, 7, 8}", collapsed_);
}
TEST_F(NGInlineItemsBuilderTest,
@@ -306,67 +227,51 @@ TEST_F(NGInlineItemsBuilderTest,
TestAppend({"text ", EWhiteSpace::kPreWrap}, {" text"}))
<< "The whitespace in constructions like '<span style=\"white-space: "
"pre-wrap\">text <span><span> text</span>' does not collapse.";
- EXPECT_EQ("{}", collapsed_);
}
TEST_F(NGInlineItemsBuilderTest, CollapseZeroWidthSpaces) {
EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text\u200B\ntext"))
<< "Newline is removed if the character before is ZWS.";
- EXPECT_EQ("{5}", collapsed_);
EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text\n\u200Btext"))
<< "Newline is removed if the character after is ZWS.";
- EXPECT_EQ("{4}", collapsed_);
EXPECT_EQ(String(u"text\u200B\u200Btext"),
TestAppend(u"text\u200B\n\u200Btext"))
<< "Newline is removed if the character before/after is ZWS.";
- EXPECT_EQ("{5}", collapsed_);
EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text\n", u"\u200Btext"))
<< "Newline is removed if the character after across elements is ZWS.";
- EXPECT_EQ("{4}", collapsed_);
EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text\u200B", u"\ntext"))
<< "Newline is removed if the character before is ZWS even across "
"elements.";
- EXPECT_EQ("{5}", collapsed_);
EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text \n", u"\u200Btext"))
<< "Collapsible space before newline does not affect the result.";
- EXPECT_EQ("{4, 5}", collapsed_);
-
EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text\u200B\n", u" text"))
<< "Collapsible space after newline is removed even when the "
"newline was removed.";
- EXPECT_EQ("{5, 6}", collapsed_);
-
EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text\u200B ", u"\ntext"))
<< "A white space sequence containing a segment break before or after "
"a zero width space is collapsed to a zero width space.";
- EXPECT_EQ("{5, 6}", collapsed_);
}
TEST_F(NGInlineItemsBuilderTest, CollapseEastAsianWidth) {
EXPECT_EQ(String(u"\u4E00\u4E00"), TestAppend(u"\u4E00\n\u4E00"))
<< "Newline is removed when both sides are Wide.";
- EXPECT_EQ("{1}", collapsed_);
EXPECT_EQ(String(u"\u4E00 A"), TestAppend(u"\u4E00\nA"))
<< "Newline is not removed when after is Narrow.";
- EXPECT_EQ("{}", collapsed_);
EXPECT_EQ(String(u"A \u4E00"), TestAppend(u"A\n\u4E00"))
<< "Newline is not removed when before is Narrow.";
- EXPECT_EQ("{}", collapsed_);
EXPECT_EQ(String(u"\u4E00\u4E00"), TestAppend(u"\u4E00\n", u"\u4E00"))
<< "Newline at the end of elements is removed when both sides are Wide.";
- EXPECT_EQ("{1}", collapsed_);
EXPECT_EQ(String(u"\u4E00\u4E00"), TestAppend(u"\u4E00", u"\n\u4E00"))
<< "Newline at the beginning of elements is removed "
"when both sides are Wide.";
- EXPECT_EQ("{1}", collapsed_);
}
TEST_F(NGInlineItemsBuilderTest, OpaqueToSpaceCollapsing) {
- NGInlineItemsBuilderForOffsetMapping builder(&items_);
+ NGInlineItemsBuilder builder(&items_);
builder.Append("Hello ", style_.get());
builder.AppendOpaque(NGInlineItem::kBidiControl,
kFirstStrongIsolateCharacter);
@@ -375,20 +280,18 @@ TEST_F(NGInlineItemsBuilderTest, OpaqueToSpaceCollapsing) {
kFirstStrongIsolateCharacter);
builder.Append(" World", style_.get());
EXPECT_EQ(String(u"Hello \u2068\u2068World"), builder.ToString());
- EXPECT_EQ("{7, 9}", GetCollapsed(builder.GetOffsetMappingBuilder()));
}
TEST_F(NGInlineItemsBuilderTest, CollapseAroundReplacedElement) {
- NGInlineItemsBuilderForOffsetMapping builder(&items_);
+ NGInlineItemsBuilder builder(&items_);
builder.Append("Hello ", style_.get());
builder.AppendAtomicInline();
builder.Append(" World", style_.get());
EXPECT_EQ(String(u"Hello \uFFFC World"), builder.ToString());
- EXPECT_EQ("{}", GetCollapsed(builder.GetOffsetMappingBuilder()));
}
TEST_F(NGInlineItemsBuilderTest, CollapseNewlineAfterObject) {
- NGInlineItemsBuilderForOffsetMapping builder(&items_);
+ NGInlineItemsBuilder builder(&items_);
builder.AppendAtomicInline();
builder.Append("\n", style_.get());
builder.AppendAtomicInline();
@@ -397,19 +300,16 @@ TEST_F(NGInlineItemsBuilderTest, CollapseNewlineAfterObject) {
EXPECT_EQ(nullptr, items_[0].Style());
EXPECT_EQ(style_.get(), items_[1].Style());
EXPECT_EQ(nullptr, items_[2].Style());
- EXPECT_EQ("{}", GetCollapsed(builder.GetOffsetMappingBuilder()));
}
TEST_F(NGInlineItemsBuilderTest, AppendEmptyString) {
EXPECT_EQ("", TestAppend(""));
- EXPECT_EQ("{}", collapsed_);
EXPECT_EQ(0u, items_.size());
}
TEST_F(NGInlineItemsBuilderTest, NewLines) {
SetWhiteSpace(EWhiteSpace::kPre);
EXPECT_EQ("apple\norange\ngrape\n", TestAppend("apple\norange\ngrape\n"));
- EXPECT_EQ("{}", collapsed_);
EXPECT_EQ(6u, items_.size());
EXPECT_EQ(NGInlineItem::kText, items_[0].Type());
EXPECT_EQ(NGInlineItem::kControl, items_[1].Type());
@@ -432,7 +332,6 @@ TEST_F(NGInlineItemsBuilderTest, IgnorablePre) {
"orange"
"\n"
"grape"));
- EXPECT_EQ("{}", collapsed_);
EXPECT_EQ(5u, items_.size());
EXPECT_ITEM_OFFSET(items_[0], NGInlineItem::kText, 0u, 5u);
EXPECT_ITEM_OFFSET(items_[1], NGInlineItem::kControl, 5u, 6u);
@@ -443,13 +342,12 @@ TEST_F(NGInlineItemsBuilderTest, IgnorablePre) {
TEST_F(NGInlineItemsBuilderTest, Empty) {
Vector<NGInlineItem> items;
- NGInlineItemsBuilderForOffsetMapping builder(&items);
+ NGInlineItemsBuilder builder(&items);
scoped_refptr<ComputedStyle> block_style(ComputedStyle::Create());
builder.EnterBlock(block_style.get());
builder.ExitBlock();
EXPECT_EQ("", builder.ToString());
- EXPECT_EQ("{}", GetCollapsed(builder.GetOffsetMappingBuilder()));
}
class CollapsibleSpaceTest : public NGInlineItemsBuilderTest,
@@ -472,7 +370,7 @@ TEST_P(CollapsibleSpaceTest, CollapsedSpaceAfterNoWrap) {
TEST_F(NGInlineItemsBuilderTest, BidiBlockOverride) {
Vector<NGInlineItem> items;
- NGInlineItemsBuilderForOffsetMapping builder(&items);
+ NGInlineItemsBuilder builder(&items);
scoped_refptr<ComputedStyle> block_style(ComputedStyle::Create());
block_style->SetUnicodeBidi(UnicodeBidi::kBidiOverride);
block_style->SetDirection(TextDirection::kRtl);
@@ -486,7 +384,6 @@ TEST_F(NGInlineItemsBuilderTest, BidiBlockOverride) {
u"Hello"
u"\u202C"),
builder.ToString());
- EXPECT_EQ("{}", GetCollapsed(builder.GetOffsetMappingBuilder()));
}
static std::unique_ptr<LayoutInline> CreateLayoutInline(
@@ -500,7 +397,7 @@ static std::unique_ptr<LayoutInline> CreateLayoutInline(
TEST_F(NGInlineItemsBuilderTest, BidiIsolate) {
Vector<NGInlineItem> items;
- NGInlineItemsBuilderForOffsetMapping builder(&items);
+ NGInlineItemsBuilder builder(&items);
builder.Append("Hello ", style_.get());
std::unique_ptr<LayoutInline> isolate_rtl(
CreateLayoutInline([](ComputedStyle* style) {
@@ -520,12 +417,11 @@ TEST_F(NGInlineItemsBuilderTest, BidiIsolate) {
u"\u2069"
u" World"),
builder.ToString());
- EXPECT_EQ("{}", GetCollapsed(builder.GetOffsetMappingBuilder()));
}
TEST_F(NGInlineItemsBuilderTest, BidiIsolateOverride) {
Vector<NGInlineItem> items;
- NGInlineItemsBuilderForOffsetMapping builder(&items);
+ NGInlineItemsBuilder builder(&items);
builder.Append("Hello ", style_.get());
std::unique_ptr<LayoutInline> isolate_override_rtl(
CreateLayoutInline([](ComputedStyle* style) {
@@ -545,7 +441,6 @@ TEST_F(NGInlineItemsBuilderTest, BidiIsolateOverride) {
u"\u202C\u2069"
u" World"),
builder.ToString());
- EXPECT_EQ("{}", GetCollapsed(builder.GetOffsetMappingBuilder()));
}
} // namespace
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 303800dd4db..7734a5e7f69 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc
@@ -19,6 +19,7 @@
#include "third_party/blink/renderer/core/layout/ng/inline/ng_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/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"
@@ -36,6 +37,8 @@ namespace {
// Represents a data struct that are needed for 'text-align' and justifications.
struct NGLineAlign {
STACK_ALLOCATED();
+
+ public:
NGLineAlign(const NGLineInfo&);
NGLineAlign() = delete;
@@ -48,7 +51,10 @@ struct NGLineAlign {
};
NGLineAlign::NGLineAlign(const NGLineInfo& line_info) {
- space = line_info.AvailableWidth() - line_info.Width();
+ // NGLineInfo::WidthForAlignment may return a negative value, as text-indent
+ // can accept negative values. We need to use this un-clamped value for
+ // alginment, instead of just NGLineInfo::Width.
+ space = line_info.AvailableWidth() - line_info.WidthForAlignment();
// Compute the end text offset of this line for the alignment purpose.
// Trailing spaces are not part of the alignment space even when they are
@@ -114,8 +120,10 @@ NGInlineBoxState* NGInlineLayoutAlgorithm::HandleOpenTag(
// https://drafts.csswg.org/css2/visudet.html#line-height
if (!quirks_mode_ || !item.IsEmptyItem())
box->ComputeTextMetrics(*item.Style(), baseline_type_);
- if (item.ShouldCreateBoxFragment())
- box->SetNeedsBoxFragment();
+ if (item.ShouldCreateBoxFragment()) {
+ box->SetNeedsBoxFragment(
+ box_states_->ContainingLayoutObjectForAbsolutePositionObjects());
+ }
return box;
}
@@ -229,14 +237,14 @@ void NGInlineLayoutAlgorithm::CreateLine(NGLineInfo* line_info,
} else if (item.Type() == NGInlineItem::kOpenTag) {
box = HandleOpenTag(item, item_result);
} else if (item.Type() == NGInlineItem::kCloseTag) {
- if (!box->needs_box_fragment && item_result.inline_size)
- box->SetNeedsBoxFragment();
- if (box->needs_box_fragment) {
- box->SetLineRightForBoxFragment(item, item_result);
- if (quirks_mode_)
- box->EnsureTextMetrics(*item.Style(), baseline_type_);
+ if (!box->needs_box_fragment && item_result.inline_size) {
+ box->SetNeedsBoxFragment(
+ box_states_->ContainingLayoutObjectForAbsolutePositionObjects());
}
- box = box_states_->OnCloseTag(&line_box_, box, baseline_type_);
+ if (quirks_mode_ && box->needs_box_fragment)
+ box->EnsureTextMetrics(*item.Style(), baseline_type_);
+ box = box_states_->OnCloseTag(&line_box_, box, baseline_type_,
+ item.HasEndEdge());
} else if (item.Type() == NGInlineItem::kAtomicInline) {
box = PlaceAtomicInline(item, &item_result, *line_info);
} else if (item.Type() == NGInlineItem::kListMarker) {
@@ -258,11 +266,6 @@ void NGInlineLayoutAlgorithm::CreateLine(NGLineInfo* line_info,
IsLtr(line_info->BaseDirection()) ? 0 : 1, box);
}
- // We can return early if we don't have any children (and don't need to
- // create a line-box for a list marker, etc).
- if (line_box_.IsEmpty() && line_info->IsEmptyLine())
- return;
-
box_states_->OnEndPlaceItems(&line_box_, baseline_type_);
// TODO(kojii): For LTR, we can optimize ComputeInlinePositions() to compute
@@ -282,6 +285,10 @@ void NGInlineLayoutAlgorithm::CreateLine(NGLineInfo* line_info,
.TruncateLine(inline_size, &line_box_);
}
+ // Negative margins can make the position negative, but the inline size is
+ // always positive or 0.
+ inline_size = inline_size.ClampNegativeToZero();
+
// Create box fragmetns if needed. After this point forward, |line_box_| is a
// tree structure.
if (box_states_->HasBoxFragments())
@@ -290,9 +297,20 @@ void NGInlineLayoutAlgorithm::CreateLine(NGLineInfo* line_info,
const NGLineHeightMetrics& line_box_metrics =
box_states_->LineBoxState().metrics;
+ // Other 'text-align' values than 'justify' move line boxes as a whole, but
+ // indivisual items do not change their relative position to the line box.
+ LayoutUnit bfc_line_offset = line_info->BfcOffset().line_offset;
+ if (text_align != ETextAlign::kJustify)
+ bfc_line_offset += OffsetForTextAlign(*line_info, text_align);
+
+ if (IsLtr(line_info->BaseDirection()))
+ bfc_line_offset += line_info->TextIndent();
+
+ container_builder_.SetBfcLineOffset(bfc_line_offset);
+
// Handle out-of-flow positioned objects. They need inline offsets for their
// static positions.
- PlaceOutOfFlowObjects(*line_info, line_box_metrics);
+ PlaceOutOfFlowObjects(*line_info, line_box_metrics, inline_size);
// Even if we have something in-flow, it may just be empty items that
// shouldn't trigger creation of a line. Exit now if that's the case.
@@ -301,32 +319,18 @@ void NGInlineLayoutAlgorithm::CreateLine(NGLineInfo* line_info,
DCHECK(!line_box_metrics.IsEmpty());
- NGBfcOffset line_bfc_offset(line_info->LineBfcOffset());
-
// Up until this point, children are placed so that the dominant baseline is
// at 0. Move them to the final baseline position, and set the logical top of
// the line box to the line top.
line_box_.MoveInBlockDirection(line_box_metrics.ascent);
- // Negative margins can make the position negative, but the inline size is
- // always positive or 0.
- inline_size = inline_size.ClampNegativeToZero();
-
- // Other 'text-align' values than 'justify' move line boxes as a whole, but
- // indivisual items do not change their relative position to the line box.
- if (text_align != ETextAlign::kJustify)
- line_bfc_offset.line_offset += OffsetForTextAlign(*line_info, text_align);
-
- if (IsLtr(line_info->BaseDirection()))
- line_bfc_offset.line_offset += line_info->TextIndent();
-
if (line_info->UseFirstLineStyle())
container_builder_.SetStyleVariant(NGStyleVariant::kFirstLine);
container_builder_.AddChildren(line_box_);
container_builder_.SetInlineSize(inline_size);
container_builder_.SetBaseDirection(line_info->BaseDirection());
container_builder_.SetMetrics(line_box_metrics);
- container_builder_.SetBfcOffset(line_bfc_offset);
+ container_builder_.SetBfcBlockOffset(line_info->BfcOffset().block_offset);
}
void NGInlineLayoutAlgorithm::PlaceControlItem(const NGInlineItem& item,
@@ -373,7 +377,7 @@ void NGInlineLayoutAlgorithm::PlaceControlItem(const NGInlineItem& item,
// Place a generated content that does not exist in DOM nor in LayoutObject
// tree.
void NGInlineLayoutAlgorithm::PlaceGeneratedContent(
- scoped_refptr<NGPhysicalFragment> fragment,
+ scoped_refptr<const NGPhysicalFragment> fragment,
UBiDiLevel bidi_level,
NGInlineBoxState* box) {
LayoutUnit inline_size = IsHorizontalWritingMode() ? fragment->Size().width
@@ -425,7 +429,7 @@ void NGInlineLayoutAlgorithm::PlaceLayoutResult(NGInlineItemResult* item_result,
const NGInlineItem& item = *item_result->item;
DCHECK(item.Style());
NGBoxFragment fragment(
- ConstraintSpace().GetWritingMode(),
+ ConstraintSpace().GetWritingMode(), ConstraintSpace().Direction(),
ToNGPhysicalBoxFragment(*item_result->layout_result->PhysicalFragment()));
NGLineHeightMetrics metrics = fragment.BaselineMetrics(
{NGBaselineAlgorithmType::kAtomicInline, baseline_type_},
@@ -443,7 +447,10 @@ void NGInlineLayoutAlgorithm::PlaceLayoutResult(NGInlineItemResult* item_result,
// @return whether |line_box_| has any in-flow fragments.
void NGInlineLayoutAlgorithm::PlaceOutOfFlowObjects(
const NGLineInfo& line_info,
- const NGLineHeightMetrics& line_box_metrics) {
+ const NGLineHeightMetrics& line_box_metrics,
+ LayoutUnit inline_size) {
+ TextDirection line_direction = line_info.BaseDirection();
+
for (NGLineBoxFragmentBuilder::Child& child : line_box_) {
if (LayoutObject* box = child.out_of_flow_positioned_box) {
// The static position is at the line-top. Ignore the block_offset.
@@ -452,24 +459,37 @@ void NGInlineLayoutAlgorithm::PlaceOutOfFlowObjects(
// If a block-level box appears in the middle of a line, move the static
// position to where the next block will be placed.
if (!box->StyleRef().IsOriginalDisplayInlineType()) {
- LayoutUnit line_offset;
- if (!line_info.IsEmptyLine()) {
- line_offset = line_info.LineBfcOffset().line_offset -
- ConstraintSpace().BfcOffset().line_offset;
+ LayoutUnit inline_offset = container_builder_.BfcLineOffset() -
+ ConstraintSpace().BfcOffset().line_offset;
+
+ // Flip the inline_offset if we are in RTL.
+ if (IsRtl(line_direction)) {
+ LayoutUnit container_inline_size =
+ ConstraintSpace().AvailableSize().inline_size;
+ inline_offset = container_inline_size - inline_offset + inline_size;
}
- line_offset += line_info.TextIndent();
+
+ inline_offset += line_info.TextIndent();
// We need to subtract the line offset, in order to ignore
// floats and text-indent.
- static_offset.inline_offset = -line_offset;
+ static_offset.inline_offset = -inline_offset;
if (child.offset.inline_offset && !line_box_metrics.IsEmpty())
static_offset.block_offset = line_box_metrics.LineHeight();
+ } else {
+ // Our child offset is line-relative, but the static offset is
+ // flow-relative, using the direction we give to
+ // |AddInlineOutOfFlowChildCandidate|.
+ if (IsRtl(line_direction)) {
+ static_offset.inline_offset =
+ inline_size - static_offset.inline_offset;
+ }
}
container_builder_.AddInlineOutOfFlowChildCandidate(
- NGBlockNode(ToLayoutBox(box)), static_offset,
- line_info.BaseDirection(), child.out_of_flow_containing_box);
+ NGBlockNode(ToLayoutBox(box)), static_offset, line_direction,
+ child.out_of_flow_containing_box);
child.out_of_flow_positioned_box = child.out_of_flow_containing_box =
nullptr;
@@ -605,7 +625,7 @@ scoped_refptr<NGLayoutResult> NGInlineLayoutAlgorithm::Layout() {
// We're just going to collapse through this one, so whatever went in on one
// side will go out on the other side. The position of the adjoining floats
- // will be affected by any subsequent block, until the BFC offset is
+ // will be affected by any subsequent block, until the BFC block offset is
// resolved.
container_builder_.AddAdjoiningFloatTypes(
ConstraintSpace().AdjoiningFloatTypes());
@@ -616,17 +636,21 @@ scoped_refptr<NGLayoutResult> NGInlineLayoutAlgorithm::Layout() {
// path than to create a fast code path for the stability.
} else {
DCHECK(ConstraintSpace().MarginStrut().IsEmpty());
- container_builder_.SetBfcOffset(ConstraintSpace().BfcOffset());
- // The BFC offset was determined before entering this algorithm. This means
- // that there should be no adjoining floats.
+ // We need to pre-emptively set the BFC block offset in order for leading
+ // floats to be positioned correctly.
+ container_builder_.SetBfcBlockOffset(
+ ConstraintSpace().BfcOffset().block_offset);
+
+ // The BFC block offset was determined before entering this algorithm. This
+ // means that there should be no adjoining floats.
DCHECK(!ConstraintSpace().AdjoiningFloatTypes());
}
// In order to get the correct list of layout opportunities, we need to
// position any "leading" items (floats) within the exclusion space first.
unsigned handled_item_index =
- PositionLeadingItems(initial_exclusion_space.get());
+ PositionLeadingFloats(initial_exclusion_space.get());
// 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.
@@ -779,16 +803,15 @@ scoped_refptr<NGLayoutResult> NGInlineLayoutAlgorithm::Layout() {
container_builder_.SetExclusionSpace(
exclusion_space ? std::move(exclusion_space)
: std::move(initial_exclusion_space));
- container_builder_.MoveOutOfFlowDescendantCandidatesToDescendants();
+ container_builder_.MoveOutOfFlowDescendantCandidatesToDescendants(nullptr);
return container_builder_.ToLineBoxFragment();
}
// This positions any "leading" floats within the given exclusion space.
// If we are also an empty inline, it will add any out-of-flow descendants.
-unsigned NGInlineLayoutAlgorithm::PositionLeadingItems(
+unsigned NGInlineLayoutAlgorithm::PositionLeadingFloats(
NGExclusionSpace* exclusion_space) {
const Vector<NGInlineItem>& items = Node().ItemsData(false).items;
- LayoutUnit bfc_line_offset = ConstraintSpace().BfcOffset().line_offset;
unsigned index = BreakToken() ? BreakToken()->ItemIndex() : 0;
for (; index < items.size(); ++index) {
@@ -796,16 +819,10 @@ unsigned NGInlineLayoutAlgorithm::PositionLeadingItems(
if (item.Type() == NGInlineItem::kFloating) {
NGBlockNode node(ToLayoutBox(item.GetLayoutObject()));
- NGBoxStrut margins =
- ComputeMarginsForContainer(ConstraintSpace(), node.Style());
-
- scoped_refptr<NGUnpositionedFloat> unpositioned_float =
- NGUnpositionedFloat::Create(
- ConstraintSpace().AvailableSize(),
- ConstraintSpace().PercentageResolutionSize(), bfc_line_offset,
- bfc_line_offset, margins, node, /* break_token */ nullptr);
- AddUnpositionedFloat(&unpositioned_floats_, &container_builder_,
- std::move(unpositioned_float));
+
+ AddUnpositionedFloat(
+ &unpositioned_floats_, &container_builder_,
+ NGUnpositionedFloat(node, /* break_token */ nullptr));
}
// Abort if we've found something that makes this a non-empty inline.
@@ -815,7 +832,8 @@ unsigned NGInlineLayoutAlgorithm::PositionLeadingItems(
}
}
- if (ConstraintSpace().FloatsBfcOffset() || container_builder_.BfcOffset())
+ if (container_builder_.BfcBlockOffset() ||
+ ConstraintSpace().FloatsBfcBlockOffset())
PositionPendingFloats(/* content_size */ LayoutUnit(), exclusion_space);
return index;
@@ -824,24 +842,28 @@ unsigned NGInlineLayoutAlgorithm::PositionLeadingItems(
void NGInlineLayoutAlgorithm::PositionPendingFloats(
LayoutUnit content_size,
NGExclusionSpace* exclusion_space) {
- DCHECK(container_builder_.BfcOffset() || ConstraintSpace().FloatsBfcOffset())
- << "The parent BFC offset should be known here";
+ DCHECK(container_builder_.BfcBlockOffset() ||
+ ConstraintSpace().FloatsBfcBlockOffset())
+ << "The floats BFC block offset should be known here";
if (BreakToken() && BreakToken()->IgnoreFloats()) {
unpositioned_floats_.clear();
return;
}
- NGBfcOffset bfc_offset = container_builder_.BfcOffset()
- ? container_builder_.BfcOffset().value()
- : ConstraintSpace().FloatsBfcOffset().value();
+ LayoutUnit bfc_block_offset =
+ container_builder_.BfcBlockOffset()
+ ? container_builder_.BfcBlockOffset().value()
+ : ConstraintSpace().FloatsBfcBlockOffset().value();
- LayoutUnit origin_block_offset = bfc_offset.block_offset + content_size;
- LayoutUnit from_block_offset = bfc_offset.block_offset;
+ NGBfcOffset origin_bfc_offset = {ConstraintSpace().BfcOffset().line_offset,
+ bfc_block_offset + content_size};
const Vector<NGPositionedFloat> positioned_floats =
- PositionFloats(origin_block_offset, from_block_offset,
- unpositioned_floats_, ConstraintSpace(), exclusion_space);
+ PositionFloats(ConstraintSpace().AvailableSize(),
+ ConstraintSpace().PercentageResolutionSize(),
+ origin_bfc_offset, bfc_block_offset, unpositioned_floats_,
+ ConstraintSpace(), exclusion_space);
positioned_floats_.AppendVector(positioned_floats);
unpositioned_floats_.clear();
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 4fcf7b1026a..4522aee3f1e 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
@@ -11,6 +11,8 @@
#include "third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h"
#include "third_party/blink/renderer/core/layout/ng/ng_fragment_builder.h"
#include "third_party/blink/renderer/core/layout/ng/ng_layout_algorithm.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_unpositioned_float.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_unpositioned_float_vector.h"
#include "third_party/blink/renderer/platform/fonts/font_baseline.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -47,7 +49,8 @@ class CORE_EXPORT NGInlineLayoutAlgorithm final
scoped_refptr<NGLayoutResult> Layout() override;
private:
- unsigned PositionLeadingItems(NGExclusionSpace*);
+ unsigned PositionLeadingFloats(NGExclusionSpace*);
+
void PositionPendingFloats(LayoutUnit content_size, NGExclusionSpace*);
bool IsHorizontalWritingMode() const { return is_horizontal_writing_mode_; }
@@ -63,7 +66,7 @@ class CORE_EXPORT NGInlineLayoutAlgorithm final
const NGLineInfo&,
NGInlineItemResult*,
NGInlineBoxState*);
- void PlaceGeneratedContent(scoped_refptr<NGPhysicalFragment>,
+ void PlaceGeneratedContent(scoped_refptr<const NGPhysicalFragment>,
UBiDiLevel,
NGInlineBoxState*);
NGInlineBoxState* PlaceAtomicInline(const NGInlineItem&,
@@ -72,7 +75,9 @@ class CORE_EXPORT NGInlineLayoutAlgorithm final
void PlaceLayoutResult(NGInlineItemResult*,
NGInlineBoxState*,
LayoutUnit inline_offset = LayoutUnit());
- void PlaceOutOfFlowObjects(const NGLineInfo&, const NGLineHeightMetrics&);
+ void PlaceOutOfFlowObjects(const NGLineInfo&,
+ const NGLineHeightMetrics&,
+ LayoutUnit inline_size);
void PlaceListMarker(const NGInlineItem&,
NGInlineItemResult*,
const NGLineInfo&);
@@ -93,7 +98,7 @@ class CORE_EXPORT NGInlineLayoutAlgorithm final
unsigned quirks_mode_ : 1;
Vector<NGPositionedFloat> positioned_floats_;
- Vector<scoped_refptr<NGUnpositionedFloat>> unpositioned_floats_;
+ NGUnpositionedFloatVector unpositioned_floats_;
};
} // namespace blink
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 6476e38750a..3488b31d0bb 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
@@ -86,12 +86,12 @@ TEST_F(NGInlineLayoutAlgorithmTest, GenerateHyphen) {
GetBoxFragmentByElementId("container");
EXPECT_EQ(2u, block->Children().size());
const NGPhysicalLineBoxFragment& line1 =
- ToNGPhysicalLineBoxFragment(*block->Children()[0]);
+ ToNGPhysicalLineBoxFragment(*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 = ToNGPhysicalTextFragment(*line1.Children()[1]);
+ const auto& hyphen = ToNGPhysicalTextFragment(*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());
@@ -116,12 +116,12 @@ TEST_F(NGInlineLayoutAlgorithmTest, GenerateEllipsis) {
GetBoxFragmentByElementId("container");
EXPECT_EQ(1u, block->Children().size());
const NGPhysicalLineBoxFragment& line1 =
- ToNGPhysicalLineBoxFragment(*block->Children()[0]);
+ ToNGPhysicalLineBoxFragment(*block->Children()[0].get());
// The ellipsis is in its own NGPhysicalTextFragment.
EXPECT_EQ(2u, line1.Children().size());
EXPECT_EQ(NGPhysicalFragment::kFragmentText, line1.Children()[1]->Type());
- const auto& ellipsis = ToNGPhysicalTextFragment(*line1.Children()[1]);
+ const auto& ellipsis = ToNGPhysicalTextFragment(*line1.Children()[1].get());
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());
@@ -153,7 +153,7 @@ TEST_F(NGInlineLayoutAlgorithmTest, BoxForEndMargin) {
ASSERT_TRUE(block_box);
EXPECT_EQ(2u, block_box->Children().size());
const NGPhysicalLineBoxFragment& line_box1 =
- ToNGPhysicalLineBoxFragment(*block_box->Children()[0]);
+ ToNGPhysicalLineBoxFragment(*block_box->Children()[0].get());
EXPECT_EQ(2u, line_box1.Children().size());
// The <span> generates a box fragment for the 2nd line because it has a
@@ -188,13 +188,13 @@ TEST_F(NGInlineLayoutAlgorithmTest, ContainerBorderPadding) {
auto* block_box =
ToNGPhysicalBoxFragment(layout_result->PhysicalFragment().get());
- EXPECT_TRUE(layout_result->BfcOffset().has_value());
- EXPECT_EQ(0, layout_result->BfcOffset().value().line_offset);
- EXPECT_EQ(0, layout_result->BfcOffset().value().block_offset);
+ EXPECT_TRUE(layout_result->BfcBlockOffset().has_value());
+ EXPECT_EQ(0, layout_result->BfcBlockOffset().value());
+ EXPECT_EQ(0, layout_result->BfcLineOffset());
- auto* line = ToNGPhysicalLineBoxFragment(block_box->Children()[0].get());
- EXPECT_EQ(5, line->Offset().left);
- EXPECT_EQ(10, line->Offset().top);
+ NGPhysicalOffset line_offset = block_box->Children()[0].Offset();
+ EXPECT_EQ(5, line_offset.left);
+ EXPECT_EQ(10, line_offset.top);
}
// The test leaks memory. crbug.com/721932
@@ -222,8 +222,8 @@ TEST_F(NGInlineLayoutAlgorithmTest, MAYBE_VerticalAlignBottomReplaced) {
auto* line =
ToNGPhysicalLineBoxFragment(layout_result->PhysicalFragment().get());
EXPECT_EQ(LayoutUnit(96), line->Size().height);
- auto* img = line->Children()[0].get();
- EXPECT_EQ(LayoutUnit(0), img->Offset().top);
+ NGPhysicalOffset img_offset = line->Children()[0].Offset();
+ EXPECT_EQ(LayoutUnit(0), img_offset.top);
}
// Verifies that text can flow correctly around floats that were positioned
@@ -259,36 +259,32 @@ TEST_F(NGInlineLayoutAlgorithmTest, TextFloatsAroundFloatsBefore) {
)HTML");
// ** Run LayoutNG algorithm **
scoped_refptr<NGConstraintSpace> space;
- scoped_refptr<NGPhysicalBoxFragment> html_fragment;
+ scoped_refptr<const NGPhysicalBoxFragment> html_fragment;
std::tie(html_fragment, space) = RunBlockLayoutAlgorithmForElement(
GetDocument().getElementsByTagName("html")->item(0));
auto* body_fragment =
ToNGPhysicalBoxFragment(html_fragment->Children()[0].get());
auto* container_fragment =
ToNGPhysicalBoxFragment(body_fragment->Children()[0].get());
- Vector<NGPhysicalLineBoxFragment*> line_boxes;
+ Vector<NGPhysicalOffset> line_offsets;
for (const auto& child : container_fragment->Children()) {
if (!child->IsLineBox())
continue;
- line_boxes.push_back(ToNGPhysicalLineBoxFragment(child.get()));
+ line_offsets.push_back(child.Offset());
}
// Line break points may vary by minor differences in fonts.
// The test is valid as long as we have 3 or more lines and their positions
// are correct.
- EXPECT_GE(line_boxes.size(), 3UL);
+ EXPECT_GE(line_offsets.size(), 3UL);
- auto* line_box1 = line_boxes[0];
// 40 = #left-float1' width 30 + #left-float2 10
- EXPECT_EQ(LayoutUnit(40), line_box1->Offset().left);
+ EXPECT_EQ(LayoutUnit(40), line_offsets[0].left);
- auto* line_box2 = line_boxes[1];
// 40 = #left-float1' width 30
- EXPECT_EQ(LayoutUnit(30), line_box2->Offset().left);
-
- auto* line_box3 = line_boxes[2];
- EXPECT_EQ(LayoutUnit(), line_box3->Offset().left);
+ EXPECT_EQ(LayoutUnit(30), line_offsets[1].left);
+ EXPECT_EQ(LayoutUnit(), line_offsets[2].left);
}
// Verifies that text correctly flows around the inline float that fits on
@@ -322,11 +318,10 @@ TEST_F(NGInlineLayoutAlgorithmTest, TextFloatsAroundInlineFloatThatFitsOnLine) {
// float plus two lines.
EXPECT_EQ(3u, block_box->Children().size());
- const NGPhysicalLineBoxFragment& first_line =
- ToNGPhysicalLineBoxFragment(*block_box->Children()[1]);
+ NGPhysicalOffset first_line_offset = block_box->Children()[1].Offset();
// 30 == narrow-float's width.
- EXPECT_EQ(LayoutUnit(30), first_line.Offset().left);
+ EXPECT_EQ(LayoutUnit(30), first_line_offset.left);
Element* span = GetDocument().getElementById("text");
// 38 == narrow-float's width + body's margin.
@@ -448,7 +443,7 @@ TEST_F(NGInlineLayoutAlgorithmTest, InkOverflow) {
)HTML");
Element* element = GetElementById("container");
scoped_refptr<NGConstraintSpace> space;
- scoped_refptr<NGPhysicalBoxFragment> box_fragment;
+ scoped_refptr<const NGPhysicalBoxFragment> box_fragment;
std::tie(box_fragment, space) = RunBlockLayoutAlgorithmForElement(element);
EXPECT_EQ(LayoutUnit(10), box_fragment->Size().height);
@@ -476,12 +471,12 @@ TEST_F(NGInlineLayoutAlgorithmTest,
)HTML");
Element* element = GetElementById("container");
scoped_refptr<NGConstraintSpace> space;
- scoped_refptr<NGPhysicalBoxFragment> box_fragment;
+ scoped_refptr<const NGPhysicalBoxFragment> box_fragment;
std::tie(box_fragment, space) = RunBlockLayoutAlgorithmForElement(element);
// The StateStack in the break token of the first line should be inside of the
// #rel span.
- NGPhysicalLineBoxFragment* line1 =
+ const NGPhysicalLineBoxFragment* line1 =
ToNGPhysicalLineBoxFragment(box_fragment->Children()[0].get());
NGInlineBreakToken* break_token = ToNGInlineBreakToken(line1->BreakToken());
const NGInlineLayoutStateStack& state_stack = break_token->StateStack();
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 9cecafec27e..8a6882744e2 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
@@ -22,10 +22,12 @@
#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"
#include "third_party/blink/renderer/core/layout/ng/ng_length_utils.h"
#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/style/computed_style.h"
#include "third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.h"
@@ -37,21 +39,45 @@ namespace blink {
namespace {
-// Templated helper function for CollectInlinesInternal().
-template <typename OffsetMappingBuilder>
-void ClearNeedsLayoutIfUpdatingLayout(LayoutObject* node) {
- node->ClearNeedsLayout();
- node->ClearNeedsCollectInlines();
+// Estimate the number of NGInlineItem to minimize the vector expansions.
+unsigned EstimateInlineItemsCount(const LayoutBlockFlow& block) {
+ unsigned count = 0;
+ for (LayoutObject* child = block.FirstChild(); child;
+ child = child->NextSibling()) {
+ ++count;
+ }
+ return count * 4;
+}
+
+// Estimate the number of units and ranges in NGOffsetMapping to minimize vector
+// and hash map expansions.
+unsigned EstimateOffsetMappingItemsCount(const LayoutBlockFlow& block) {
+ // Cancels out the factor 4 in EstimateInlineItemsCount() to get the number of
+ // LayoutObjects.
+ // TODO(layout-dev): Unify the two functions and make them less hacky.
+ return EstimateInlineItemsCount(block) / 4;
+}
+
+// Ensure this LayoutObject IsInLayoutNGInlineFormattingContext and does not
+// have associated NGPaintFragment.
+void ClearInlineFragment(LayoutObject* object) {
+ object->SetIsInLayoutNGInlineFormattingContext(true);
+ object->SetFirstInlineFragment(nullptr);
+}
+
+void ClearNeedsLayout(LayoutObject* object) {
+ object->ClearNeedsLayout();
+ object->ClearNeedsCollectInlines();
+
+ ClearInlineFragment(object);
+
// Reset previous items if they cannot be reused to prevent stale items
// for subsequent layouts. Items that can be reused have already been
// added to the builder.
- if (node->IsLayoutNGText())
- ToLayoutNGText(node)->ClearInlineItems();
+ if (object->IsLayoutNGText())
+ ToLayoutNGText(object)->ClearInlineItems();
}
-template <>
-void ClearNeedsLayoutIfUpdatingLayout<NGOffsetMappingBuilder>(LayoutObject*) {}
-
// The function is templated to indicate the purpose of collected inlines:
// - With EmptyOffsetMappingBuilder: updating layout;
// - With NGOffsetMappingBuilder: building offset mapping on clean layout.
@@ -66,7 +92,8 @@ template <typename OffsetMappingBuilder>
void CollectInlinesInternal(
LayoutBlockFlow* block,
NGInlineItemsBuilderTemplate<OffsetMappingBuilder>* builder,
- String* previous_text) {
+ String* previous_text,
+ bool update_layout) {
builder->EnterBlock(block->Style());
LayoutObject* node = GetLayoutObjectForFirstChildNode(block);
@@ -98,7 +125,8 @@ void CollectInlinesInternal(
if (symbol == layout_text)
builder->SetIsSymbolMarker(true);
- ClearNeedsLayoutIfUpdatingLayout<OffsetMappingBuilder>(layout_text);
+ if (update_layout)
+ ClearNeedsLayout(layout_text);
} else if (node->IsFloating()) {
// Add floats and positioned objects in the same way as atomic inlines.
@@ -108,7 +136,8 @@ void CollectInlinesInternal(
kObjectReplacementCharacter, nullptr, node);
} else if (node->IsOutOfFlowPositioned()) {
- builder->AppendOpaque(NGInlineItem::kOutOfFlowPositioned, nullptr, node);
+ builder->AppendOpaque(NGInlineItem::kOutOfFlowPositioned,
+ kObjectReplacementCharacter, nullptr, node);
} else if (node->IsAtomicInlineLevel()) {
if (node->IsLayoutNGListMarker()) {
@@ -121,6 +150,9 @@ void CollectInlinesInternal(
// signal the presence of a non-text object to the unicode bidi
// algorithm.
builder->AppendAtomicInline(node->Style(), node);
+
+ if (update_layout)
+ ClearInlineFragment(node);
}
} else {
@@ -135,13 +167,13 @@ void CollectInlinesInternal(
if (LayoutObject* child = node->SlowFirstChild()) {
node = child;
continue;
-
- } else {
- // An empty inline node.
- ClearNeedsLayoutIfUpdatingLayout<OffsetMappingBuilder>(node);
}
+ // An empty inline node.
builder->ExitInline(node);
+
+ if (update_layout)
+ ClearNeedsLayout(node);
}
// Find the next sibling, or parent, until we reach |block|.
@@ -158,7 +190,9 @@ void CollectInlinesInternal(
}
DCHECK(node->IsInline());
builder->ExitInline(node);
- ClearNeedsLayoutIfUpdatingLayout<OffsetMappingBuilder>(node);
+
+ if (update_layout)
+ ClearNeedsLayout(node);
}
}
builder->ExitBlock();
@@ -279,19 +313,20 @@ const NGOffsetMapping* NGInlineNode::ComputeOffsetMappingIfNeeded() {
// already there in NGInlineNodeData. For efficiency, we should make
// |builder| not construct items and text content.
Vector<NGInlineItem> items;
+ items.ReserveCapacity(EstimateInlineItemsCount(*GetLayoutBlockFlow()));
NGInlineItemsBuilderForOffsetMapping builder(&items);
- CollectInlinesInternal(GetLayoutBlockFlow(), &builder, nullptr);
+ builder.GetOffsetMappingBuilder().ReserveCapacity(
+ EstimateOffsetMappingItemsCount(*GetLayoutBlockFlow()));
+ const bool update_layout = false;
+ CollectInlinesInternal(GetLayoutBlockFlow(), &builder, nullptr,
+ update_layout);
String text = builder.ToString();
-
- // The trailing space of the text for offset mapping may be removed. If not,
- // share the string instance.
- if (text == data->text_content)
- text = data->text_content;
+ DCHECK_EQ(data->text_content, text);
// TODO(xiaochengh): This doesn't compute offset mapping correctly when
// text-transform CSS property changes text length.
NGOffsetMappingBuilder& mapping_builder = builder.GetOffsetMappingBuilder();
- mapping_builder.SetDestinationString(text);
+ mapping_builder.SetDestinationString(data->text_content);
data->offset_mapping =
std::make_unique<NGOffsetMapping>(mapping_builder.Build());
}
@@ -312,8 +347,10 @@ void NGInlineNode::CollectInlines(NGInlineNodeData* data,
String* previous_text =
previous_data ? &previous_data->text_content : nullptr;
+ data->items.ReserveCapacity(EstimateInlineItemsCount(*block));
NGInlineItemsBuilder builder(&data->items);
- CollectInlinesInternal(block, &builder, previous_text);
+ const bool update_layout = true;
+ CollectInlinesInternal(block, &builder, previous_text, update_layout);
data->text_content = builder.ToString();
// Set |is_bidi_enabled_| for all UTF-16 strings for now, because at this
@@ -477,8 +514,7 @@ void NGInlineNode::ShapeText(const String& text_content,
break;
end_offset = item.EndOffset();
} else if (item.Type() == NGInlineItem::kOpenTag ||
- item.Type() == NGInlineItem::kCloseTag ||
- item.Type() == NGInlineItem::kOutOfFlowPositioned) {
+ item.Type() == NGInlineItem::kCloseTag) {
// These items are opaque to shaping.
// Opaque items cannot have text, such as Object Replacement Characters,
// since such characters can affect shaping.
@@ -639,33 +675,72 @@ void NGInlineNode::AssociateItemsWithInlines(NGInlineNodeData* data) {
}
}
+// Clear associated fragments for all LayoutObjects. They are associated when
+// NGPaintFragment is constructed.
+void NGInlineNode::ClearAssociatedFragments(NGInlineBreakToken* break_token) {
+ if (!IsPrepareLayoutFinished())
+ return;
+
+ LayoutObject* last_object = nullptr;
+ const Vector<NGInlineItem>& items = Data().items;
+ for (unsigned i = break_token ? break_token->ItemIndex() : 0;
+ i < items.size(); i++) {
+ const NGInlineItem& item = items[i];
+ if (item.Type() == NGInlineItem::kFloating ||
+ item.Type() == NGInlineItem::kOutOfFlowPositioned ||
+ item.Type() == NGInlineItem::kListMarker)
+ continue;
+ LayoutObject* object = item.GetLayoutObject();
+ if (!object || object == last_object)
+ continue;
+ object->SetFirstInlineFragment(nullptr);
+ last_object = object;
+ }
+}
+
scoped_refptr<NGLayoutResult> NGInlineNode::Layout(
const NGConstraintSpace& constraint_space,
NGBreakToken* break_token) {
+ bool needs_clear_fragments = IsPrepareLayoutFinished();
PrepareLayoutIfNeeded();
+ NGInlineBreakToken* inline_break_token = ToNGInlineBreakToken(break_token);
+ if (needs_clear_fragments && !constraint_space.IsIntermediateLayout()) {
+ ClearAssociatedFragments(inline_break_token);
+ }
+
NGInlineLayoutAlgorithm algorithm(*this, constraint_space,
- ToNGInlineBreakToken(break_token));
+ inline_break_token);
return algorithm.Layout();
}
-static LayoutUnit ComputeContentSize(NGInlineNode node,
- const MinMaxSizeInput& input,
- NGLineBreakerMode mode) {
+static LayoutUnit ComputeContentSize(
+ NGInlineNode node,
+ WritingMode container_writing_mode,
+ const MinMaxSizeInput& input,
+ NGLineBreakerMode mode,
+ const NGConstraintSpace* constraint_space) {
const ComputedStyle& style = node.Style();
WritingMode writing_mode = style.GetWritingMode();
LayoutUnit available_inline_size =
mode == NGLineBreakerMode::kMaxContent ? LayoutUnit::Max() : LayoutUnit();
+ NGPhysicalSize icb_size = constraint_space
+ ? constraint_space->InitialContainingBlockSize()
+ : node.InitialContainingBlockSize();
+ DCHECK(!constraint_space || constraint_space->InitialContainingBlockSize() ==
+ node.InitialContainingBlockSize())
+ << constraint_space->InitialContainingBlockSize() << " vs "
+ << node.InitialContainingBlockSize();
scoped_refptr<NGConstraintSpace> space =
- NGConstraintSpaceBuilder(writing_mode, node.InitialContainingBlockSize())
+ NGConstraintSpaceBuilder(writing_mode, icb_size)
.SetTextDirection(style.Direction())
.SetAvailableSize({available_inline_size, NGSizeIndefinite})
.SetIsIntermediateLayout(true)
.ToConstraintSpace(writing_mode);
Vector<NGPositionedFloat> positioned_floats;
- Vector<scoped_refptr<NGUnpositionedFloat>> unpositioned_floats;
+ NGUnpositionedFloatVector unpositioned_floats;
scoped_refptr<NGInlineBreakToken> break_token;
NGExclusionSpace empty_exclusion_space;
@@ -705,12 +780,24 @@ static LayoutUnit ComputeContentSize(NGInlineNode node,
previous_floats_inline_size = LayoutUnit();
for (const auto& unpositioned_float : unpositioned_floats) {
- NGBlockNode float_node = unpositioned_float->node;
+ NGBlockNode float_node = unpositioned_float.node;
const ComputedStyle& float_style = float_node.Style();
MinMaxSizeInput zero_input; // Floats don't intrude into floats.
+ // We'll need extrinsic sizing data when computing min/max for orthogonal
+ // flow roots.
+ scoped_refptr<NGConstraintSpace> extrinsic_constraint_space;
+ const NGConstraintSpace* optional_constraint_space = nullptr;
+ if (!IsParallelWritingMode(container_writing_mode,
+ float_node.Style().GetWritingMode())) {
+ DCHECK(constraint_space);
+ extrinsic_constraint_space = CreateExtrinsicConstraintSpaceForChild(
+ *constraint_space, input.extrinsic_block_size, float_node);
+ optional_constraint_space = extrinsic_constraint_space.get();
+ }
+
MinMaxSize child_sizes = ComputeMinAndMaxContentContribution(
- writing_mode, float_node, zero_input);
+ writing_mode, float_node, zero_input, optional_constraint_space);
LayoutUnit child_inline_margins =
ComputeMinMaxMargins(style, float_node).InlineSum();
@@ -746,7 +833,10 @@ static LayoutUnit ComputeContentSize(NGInlineNode node,
return result;
}
-MinMaxSize NGInlineNode::ComputeMinMaxSize(const MinMaxSizeInput& input) {
+MinMaxSize NGInlineNode::ComputeMinMaxSize(
+ WritingMode container_writing_mode,
+ const MinMaxSizeInput& input,
+ const NGConstraintSpace* constraint_space) {
PrepareLayoutIfNeeded();
// Run line breaking with 0 and indefinite available width.
@@ -759,14 +849,16 @@ MinMaxSize NGInlineNode::ComputeMinMaxSize(const MinMaxSizeInput& input) {
// break opportunity.
MinMaxSize sizes;
sizes.min_size =
- ComputeContentSize(*this, input, NGLineBreakerMode::kMinContent);
+ ComputeContentSize(*this, container_writing_mode, input,
+ NGLineBreakerMode::kMinContent, constraint_space);
// Compute the sum of inline sizes of all inline boxes with no line breaks.
// TODO(kojii): NGConstraintSpaceBuilder does not allow NGSizeIndefinite
// inline available size. We can allow it, or make this more efficient
// without using NGLineBreaker.
sizes.max_size =
- ComputeContentSize(*this, input, NGLineBreakerMode::kMaxContent);
+ ComputeContentSize(*this, container_writing_mode, input,
+ NGLineBreakerMode::kMaxContent, constraint_space);
// Negative text-indent can make min > max. Ensure min is the minimum size.
sizes.min_size = std::min(sizes.min_size, sizes.max_size);
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 73d49d80621..9ea381d9e41 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
@@ -14,6 +14,7 @@
namespace blink {
class NGConstraintSpace;
+class NGInlineBreakToken;
class NGInlineItem;
class NGLayoutResult;
class NGOffsetMapping;
@@ -43,7 +44,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(const MinMaxSizeInput&);
+ MinMaxSize ComputeMinMaxSize(WritingMode container_writing_mode,
+ const MinMaxSizeInput&,
+ const NGConstraintSpace* = nullptr);
// Instruct to re-compute |PrepareLayout| on the next layout.
void InvalidatePrepareLayoutForTest();
@@ -91,6 +94,8 @@ class CORE_EXPORT NGInlineNode : public NGLayoutInputNode {
void ShapeTextForFirstLineIfNeeded(NGInlineNodeData*);
void AssociateItemsWithInlines(NGInlineNodeData*);
+ void ClearAssociatedFragments(NGInlineBreakToken*);
+
NGInlineNodeData* MutableData();
const NGInlineNodeData& Data() const;
const NGInlineNodeData& EnsureData();
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 c06d5dcefb0..0922cea9ca0 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
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/core/dom/text.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"
@@ -116,6 +117,12 @@ class NGInlineNodeTest : public NGLayoutTest {
}
}
+ const String& GetText() const {
+ NGInlineNodeData* data = layout_block_flow_->GetNGInlineNodeData();
+ CHECK(data);
+ return data->text_content;
+ }
+
Vector<NGInlineItem>& Items() {
NGInlineNodeData* data = layout_block_flow_->GetNGInlineNodeData();
CHECK(data);
@@ -399,7 +406,8 @@ TEST_F(NGInlineNodeTest, MinMaxSize) {
LoadAhem();
SetupHtml("t", "<div id=t style='font:10px Ahem'>AB CDEF</div>");
NGInlineNodeForTest node = CreateInlineNode();
- MinMaxSize sizes = node.ComputeMinMaxSize(MinMaxSizeInput());
+ MinMaxSize sizes =
+ node.ComputeMinMaxSize(WritingMode::kHorizontalTb, MinMaxSizeInput());
EXPECT_EQ(40, sizes.min_size);
EXPECT_EQ(70, sizes.max_size);
}
@@ -408,7 +416,8 @@ TEST_F(NGInlineNodeTest, MinMaxSizeElementBoundary) {
LoadAhem();
SetupHtml("t", "<div id=t style='font:10px Ahem'>A B<span>C D</span></div>");
NGInlineNodeForTest node = CreateInlineNode();
- MinMaxSize sizes = node.ComputeMinMaxSize(MinMaxSizeInput());
+ MinMaxSize sizes =
+ node.ComputeMinMaxSize(WritingMode::kHorizontalTb, MinMaxSizeInput());
// |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);
@@ -427,7 +436,8 @@ TEST_F(NGInlineNodeTest, MinMaxSizeFloats) {
)HTML");
NGInlineNodeForTest node = CreateInlineNode();
- MinMaxSize sizes = node.ComputeMinMaxSize(MinMaxSizeInput());
+ MinMaxSize sizes =
+ node.ComputeMinMaxSize(WritingMode::kHorizontalTb, MinMaxSizeInput());
EXPECT_EQ(50, sizes.min_size);
EXPECT_EQ(130, sizes.max_size);
@@ -446,7 +456,8 @@ TEST_F(NGInlineNodeTest, MinMaxSizeFloatsClearance) {
)HTML");
NGInlineNodeForTest node = CreateInlineNode();
- MinMaxSize sizes = node.ComputeMinMaxSize(MinMaxSizeInput());
+ MinMaxSize sizes =
+ node.ComputeMinMaxSize(WritingMode::kHorizontalTb, MinMaxSizeInput());
EXPECT_EQ(50, sizes.min_size);
EXPECT_EQ(160, sizes.max_size);
@@ -615,4 +626,19 @@ TEST_F(NGInlineNodeTest, InvalidateRemoveFloat) {
EXPECT_TRUE(layout_block_flow_->NeedsCollectInlines());
}
+TEST_F(NGInlineNodeTest, SpaceRestoredByInsertingWord) {
+ SetupHtml("t", "<div id=t>before <span id=x></span> after</div>");
+ EXPECT_FALSE(layout_block_flow_->NeedsCollectInlines());
+ EXPECT_EQ(String("before after"), GetText());
+
+ Element* span = GetElementById("x");
+ ASSERT_TRUE(span);
+ Text* text = Text::Create(GetDocument(), "mid");
+ span->appendChild(text);
+ // EXPECT_TRUE(layout_block_flow_->NeedsCollectInlines());
+
+ ForceLayout();
+ EXPECT_EQ(String("before mid after"), GetText());
+}
+
} // namespace blink
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 5e01951043f..9956afc3f3c 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
@@ -133,14 +133,15 @@ scoped_refptr<NGLayoutResult> NGLineBoxFragmentBuilder::ToLineBoxFragment() {
NGPhysicalSize physical_size = Size().ConvertToPhysical(line_writing_mode);
NGPhysicalOffsetRect contents_ink_overflow({}, physical_size);
- for (size_t i = 0; i < children_.size(); ++i) {
- NGPhysicalFragment* child = children_[i].get();
- child->SetOffset(offsets_[i].ConvertToPhysical(
- line_writing_mode, Direction(), physical_size, child->Size()));
- child->PropagateContentsInkOverflow(&contents_ink_overflow);
+ DCHECK_EQ(children_.size(), offsets_.size());
+ for (size_t i = 0; i < children_.size(); i++) {
+ auto& child = children_[i];
+ child.offset_ = offsets_[i].ConvertToPhysical(
+ line_writing_mode, Direction(), physical_size, child->Size());
+ child->PropagateContentsInkOverflow(&contents_ink_overflow, child.Offset());
}
- scoped_refptr<NGPhysicalLineBoxFragment> fragment =
+ scoped_refptr<const NGPhysicalLineBoxFragment> fragment =
base::AdoptRef(new NGPhysicalLineBoxFragment(
Style(), style_variant_, physical_size, children_,
contents_ink_overflow, metrics_, base_direction_,
@@ -149,8 +150,8 @@ scoped_refptr<NGLayoutResult> NGLineBoxFragmentBuilder::ToLineBoxFragment() {
return base::AdoptRef(new NGLayoutResult(
std::move(fragment), oof_positioned_descendants_, positioned_floats_,
- unpositioned_list_marker_, std::move(exclusion_space_), bfc_offset_,
- end_margin_strut_,
+ unpositioned_list_marker_, std::move(exclusion_space_), bfc_line_offset_,
+ bfc_block_offset_, end_margin_strut_,
/* intrinsic_block_size */ LayoutUnit(),
/* minimal_space_shortage */ LayoutUnit::Max(), EBreakBetween::kAuto,
EBreakBetween::kAuto, /* has_forced_break */ false, is_pushed_by_floats_,
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 be0369eaaf2..30cfe7d2ce3 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
@@ -51,7 +51,7 @@ class CORE_EXPORT NGLineBoxFragmentBuilder final
DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
scoped_refptr<NGLayoutResult> layout_result;
- scoped_refptr<NGPhysicalFragment> fragment;
+ scoped_refptr<const NGPhysicalFragment> fragment;
LayoutObject* out_of_flow_positioned_box = nullptr;
LayoutObject* out_of_flow_containing_box = nullptr;
NGLogicalOffset offset;
@@ -77,7 +77,7 @@ class CORE_EXPORT NGLineBoxFragmentBuilder final
inline_size(inline_size),
bidi_level(bidi_level) {}
// Create an in-flow |NGPhysicalFragment|.
- Child(scoped_refptr<NGPhysicalFragment> fragment,
+ Child(scoped_refptr<const NGPhysicalFragment> fragment,
NGLogicalOffset offset,
LayoutUnit inline_size,
UBiDiLevel bidi_level)
@@ -85,7 +85,7 @@ class CORE_EXPORT NGLineBoxFragmentBuilder final
offset(offset),
inline_size(inline_size),
bidi_level(bidi_level) {}
- Child(scoped_refptr<NGPhysicalFragment> fragment,
+ Child(scoped_refptr<const NGPhysicalFragment> fragment,
LayoutUnit block_offset,
LayoutUnit inline_size,
UBiDiLevel bidi_level)
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 31fa4092c6d..57d9a805457 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
@@ -9,6 +9,7 @@
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_text_fragment_builder.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_block_break_token.h"
#include "third_party/blink/renderer/core/layout/ng/ng_constraint_space.h"
#include "third_party/blink/renderer/core/layout/ng/ng_floats_utils.h"
#include "third_party/blink/renderer/core/layout/ng/ng_fragment.h"
@@ -40,17 +41,16 @@ inline bool ShouldCreateLineBox(const NGInlineItemResults& item_results) {
} // namespace
-NGLineBreaker::NGLineBreaker(
- NGInlineNode node,
- NGLineBreakerMode mode,
- const NGConstraintSpace& space,
- Vector<NGPositionedFloat>* positioned_floats,
- Vector<scoped_refptr<NGUnpositionedFloat>>* unpositioned_floats,
- NGContainerFragmentBuilder* container_builder,
- NGExclusionSpace* exclusion_space,
- unsigned handled_float_index,
- const NGLineLayoutOpportunity& line_opportunity,
- const NGInlineBreakToken* break_token)
+NGLineBreaker::NGLineBreaker(NGInlineNode node,
+ NGLineBreakerMode mode,
+ const NGConstraintSpace& space,
+ Vector<NGPositionedFloat>* positioned_floats,
+ NGUnpositionedFloatVector* unpositioned_floats,
+ NGContainerFragmentBuilder* container_builder,
+ NGExclusionSpace* exclusion_space,
+ unsigned handled_float_index,
+ const NGLineLayoutOpportunity& line_opportunity,
+ const NGInlineBreakToken* break_token)
: line_opportunity_(line_opportunity),
node_(node),
is_first_formatted_line_((!break_token || (!break_token->ItemIndex() &&
@@ -80,6 +80,7 @@ NGLineBreaker::NGLineBreaker(
current_style_ = break_token->Style();
item_index_ = break_token->ItemIndex();
offset_ = break_token->TextOffset();
+ break_iterator_.SetStartOffset(offset_);
previous_line_had_forced_break_ = break_token->IsForcedBreak();
items_data_.AssertOffset(item_index_, offset_);
ignore_floats_ = break_token->IgnoreFloats();
@@ -93,10 +94,8 @@ NGLineBreaker::~NGLineBreaker() = default;
inline NGInlineItemResult* NGLineBreaker::AddItem(const NGInlineItem& item,
unsigned end_offset) {
DCHECK_LE(end_offset, item.EndOffset());
- item_results_->push_back(
- NGInlineItemResult(&item, item_index_, offset_, end_offset,
- ShouldCreateLineBox(*item_results_)));
- return &item_results_->back();
+ return &item_results_->emplace_back(&item, item_index_, offset_, end_offset,
+ ShouldCreateLineBox(*item_results_));
}
inline NGInlineItemResult* NGLineBreaker::AddItem(const NGInlineItem& item) {
@@ -104,7 +103,7 @@ inline NGInlineItemResult* NGLineBreaker::AddItem(const NGInlineItem& item) {
}
void NGLineBreaker::SetLineEndFragment(
- scoped_refptr<NGPhysicalTextFragment> fragment) {
+ scoped_refptr<const NGPhysicalTextFragment> fragment) {
bool is_horizontal =
IsHorizontalWritingMode(constraint_space_.GetWritingMode());
if (line_info_->LineEndFragment()) {
@@ -187,13 +186,16 @@ void NGLineBreaker::NextLine(NGLineInfo* line_info) {
//
// TODO(kojii): There are cases where we need to PlaceItems() without creating
// line boxes. These cases need to be reviewed.
- if (ShouldCreateLineBox(*item_results_) ||
+ bool should_create_line_box =
+ ShouldCreateLineBox(*item_results_) ||
(has_list_marker_ && line_info_->IsLastLine()) ||
- mode_ != NGLineBreakerMode::kContent)
- ComputeLineLocation();
- else
+ mode_ != NGLineBreakerMode::kContent;
+
+ if (!should_create_line_box)
line_info_->SetIsEmptyLine();
+ ComputeLineLocation();
+
line_info_ = nullptr;
item_results_ = nullptr;
}
@@ -258,7 +260,6 @@ void NGLineBreaker::BreakLine() {
} else if (item.Type() == NGInlineItem::kOpenTag) {
HandleOpenTag(item);
} else if (item.Type() == NGInlineItem::kOutOfFlowPositioned) {
- DCHECK_EQ(item.Length(), 0u);
AddItem(item);
MoveToNextOf(item);
} else if (item.Length()) {
@@ -289,15 +290,14 @@ void NGLineBreaker::UpdatePosition() {
}
void NGLineBreaker::ComputeLineLocation() const {
- LayoutUnit bfc_line_offset = line_opportunity_.line_left_offset;
+ // Negative margins can make the position negative, but the inline size is
+ // always positive or 0.
LayoutUnit available_width = AvailableWidth();
DCHECK_EQ(position_, line_info_->ComputeWidth());
- // Negative margins can make the position negative, but the inline size is
- // always positive or 0.
- line_info_->SetLineBfcOffset(
- {bfc_line_offset, line_opportunity_.bfc_block_offset}, available_width,
- position_.ClampNegativeToZero());
+ line_info_->SetWidth(available_width, position_);
+ line_info_->SetBfcOffset(
+ {line_opportunity_.line_left_offset, line_opportunity_.bfc_block_offset});
}
void NGLineBreaker::HandleText(const NGInlineItem& item) {
@@ -406,7 +406,7 @@ void NGLineBreaker::BreakText(NGInlineItemResult* item_result,
// Use kStartShouldBeSafe if at the beginning of a line.
unsigned options = ShapingLineBreaker::kDefaultOptions;
- if (offset_ != line_info_->StartOffset())
+ if (item_result->start_offset != line_info_->StartOffset())
options |= ShapingLineBreaker::kDontReshapeStart;
// Use kNoResultIfOverflow if 'break-word' and we're trying to break normally
@@ -780,14 +780,12 @@ void NGLineBreaker::HandleAtomicInline(const NGInlineItem& item) {
: sizes.max_size;
}
+ // For the inline layout purpose, only inline-margins are needed, computed for
+ // the line's writing-mode.
DCHECK(item.Style());
const ComputedStyle& style = *item.Style();
- bool is_flipped_lines = style.IsFlippedLinesWritingMode();
item_result->margins =
- NGLineBoxStrut(ComputeMarginsForVisualContainer(constraint_space_, style),
- is_flipped_lines);
- item_result->padding = NGLineBoxStrut(
- ComputePadding(constraint_space_, style), is_flipped_lines);
+ ComputeLineMarginsForVisualContainer(constraint_space_, style);
item_result->inline_size += item_result->margins.InlineSum();
if (state_ == LineBreakState::kLeading)
@@ -800,8 +798,8 @@ void NGLineBreaker::HandleAtomicInline(const NGInlineItem& item) {
// Performs layout and positions a float.
//
// If there is a known available_width (e.g. something has resolved the
-// container BFC offset) it will attempt to position the float on the current
-// line.
+// container BFC block offset) it will attempt to position the float on the
+// current line.
// Additionally updates the available_width for the line as the float has
// (probably) consumed space.
//
@@ -830,24 +828,22 @@ void NGLineBreaker::HandleFloat(const NGInlineItem& item) {
NGBlockNode node(ToLayoutBox(item.GetLayoutObject()));
const ComputedStyle& float_style = node.Style();
- NGBoxStrut margins =
- ComputeMarginsForContainer(constraint_space_, float_style);
// TODO(ikilpatrick): Add support for float break tokens inside an inline
// layout context.
- scoped_refptr<NGUnpositionedFloat> unpositioned_float =
- NGUnpositionedFloat::Create(constraint_space_.AvailableSize(),
- constraint_space_.PercentageResolutionSize(),
- constraint_space_.BfcOffset().line_offset,
- constraint_space_.BfcOffset().line_offset,
- margins, node,
- /* break_token */ nullptr);
+ NGUnpositionedFloat unpositioned_float(node, /* break_token */ nullptr);
+
+ // If we are currently computing our min/max-content size simply append
+ // to the unpositioned floats list and abort.
+ if (mode_ != NGLineBreakerMode::kContent) {
+ AddUnpositionedFloat(unpositioned_floats_, container_builder_,
+ std::move(unpositioned_float));
+ return;
+ }
LayoutUnit inline_margin_size =
- (ComputeInlineSizeForUnpositionedFloat(constraint_space_,
- unpositioned_float.get()) +
- margins.InlineSum())
- .ClampNegativeToZero();
+ ComputeMarginBoxInlineSizeForUnpositionedFloat(constraint_space_,
+ &unpositioned_float);
LayoutUnit bfc_block_offset = line_opportunity_.bfc_block_offset;
@@ -870,15 +866,10 @@ void NGLineBreaker::HandleFloat(const NGInlineItem& item) {
// also is strictly within the non-shape area).
// - It will be moved down due to block-start edge alignment.
// - It will be moved down due to clearance.
- // - We are currently computing our min/max-content size. (We use the
- // unpositioned_floats to manually adjust the min/max-content size after
- // the line breaker has run).
bool float_after_line =
!can_fit_float ||
exclusion_space_->LastFloatBlockStart() > bfc_block_offset ||
- exclusion_space_->ClearanceOffset(float_style.Clear()) >
- bfc_block_offset ||
- mode_ != NGLineBreakerMode::kContent;
+ exclusion_space_->ClearanceOffset(float_style.Clear()) > bfc_block_offset;
// Check if we already have a pending float. That's because a float cannot be
// higher than any block or floated box generated before.
@@ -887,13 +878,13 @@ void NGLineBreaker::HandleFloat(const NGInlineItem& item) {
std::move(unpositioned_float));
} else {
NGPositionedFloat positioned_float = PositionFloat(
- bfc_block_offset, constraint_space_.BfcOffset().block_offset,
- unpositioned_float.get(), constraint_space_, exclusion_space_);
+ constraint_space_.AvailableSize(),
+ constraint_space_.PercentageResolutionSize(),
+ {constraint_space_.BfcOffset().line_offset, bfc_block_offset},
+ constraint_space_.BfcOffset().block_offset, &unpositioned_float,
+ constraint_space_, exclusion_space_);
positioned_floats_->push_back(positioned_float);
- DCHECK_EQ(positioned_float.bfc_offset.block_offset,
- bfc_block_offset + margins.block_start);
-
NGLayoutOpportunity opportunity = exclusion_space_->FindLayoutOpportunity(
{constraint_space_.BfcOffset().line_offset, bfc_block_offset},
constraint_space_.AvailableSize().inline_size, NGLogicalSize());
@@ -918,20 +909,12 @@ bool NGLineBreaker::ComputeOpenTagResult(
if (item.ShouldCreateBoxFragment() &&
(style.HasBorder() || style.HasPadding() ||
(style.HasMargin() && item_result->has_edge))) {
- bool is_flipped_lines = style.IsFlippedLinesWritingMode();
- NGLineBoxStrut borders = NGLineBoxStrut(
- ComputeBorders(constraint_space, style), is_flipped_lines);
- item_result->padding = NGLineBoxStrut(
- ComputePadding(constraint_space, style), is_flipped_lines);
- item_result->borders_paddings_line_over =
- borders.line_over + item_result->padding.line_over;
- item_result->borders_paddings_line_under =
- borders.line_under + item_result->padding.line_under;
+ item_result->borders = ComputeLineBorders(constraint_space, style);
+ item_result->padding = ComputeLinePadding(constraint_space, style);
if (item_result->has_edge) {
- item_result->margins = NGLineBoxStrut(
- ComputeMarginsForSelf(constraint_space, style), is_flipped_lines);
+ item_result->margins = ComputeLineMarginsForSelf(constraint_space, style);
item_result->inline_size = item_result->margins.inline_start +
- borders.inline_start +
+ item_result->borders.inline_start +
item_result->padding.inline_start;
return true;
}
@@ -968,18 +951,16 @@ void NGLineBreaker::HandleCloseTag(const NGInlineItem& item) {
if (item_result->has_edge) {
DCHECK(item.Style());
const ComputedStyle& style = *item.Style();
- bool is_flipped_lines = style.IsFlippedLinesWritingMode();
- item_result->margins = NGLineBoxStrut(
- ComputeMarginsForSelf(constraint_space_, style), is_flipped_lines);
+ NGBoxStrut margins = ComputeMarginsForSelf(constraint_space_, style);
NGBoxStrut borders = ComputeBorders(constraint_space_, style);
NGBoxStrut paddings = ComputePadding(constraint_space_, style);
- item_result->inline_size = item_result->margins.inline_end +
- borders.inline_end + paddings.inline_end;
+ item_result->inline_size =
+ margins.inline_end + borders.inline_end + paddings.inline_end;
position_ += item_result->inline_size;
if (!item_result->should_create_line_box &&
(item_result->inline_size ||
- (item_result->margins.inline_end && !in_line_height_quirks_mode_)))
+ (margins.inline_end && !in_line_height_quirks_mode_)))
item_result->should_create_line_box = true;
}
DCHECK(item.GetLayoutObject() && item.GetLayoutObject()->Parent());
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 5f52e8c952e..238da9ba29a 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
@@ -23,7 +23,6 @@ class NGInlineBreakToken;
class NGInlineItem;
class NGInlineLayoutStateStack;
struct NGPositionedFloat;
-struct NGUnpositionedFloat;
// The line breaker needs to know which mode its in to properly handle floats.
enum class NGLineBreakerMode { kContent, kMinContent, kMaxContent };
@@ -40,7 +39,7 @@ class CORE_EXPORT NGLineBreaker {
NGLineBreakerMode,
const NGConstraintSpace&,
Vector<NGPositionedFloat>*,
- Vector<scoped_refptr<NGUnpositionedFloat>>*,
+ NGUnpositionedFloatVector*,
NGContainerFragmentBuilder* container_builder,
NGExclusionSpace*,
unsigned handled_float_index,
@@ -69,7 +68,7 @@ class CORE_EXPORT NGLineBreaker {
NGInlineItemResult* AddItem(const NGInlineItem&, unsigned end_offset);
NGInlineItemResult* AddItem(const NGInlineItem&);
- void SetLineEndFragment(scoped_refptr<NGPhysicalTextFragment>);
+ void SetLineEndFragment(scoped_refptr<const NGPhysicalTextFragment>);
void ComputeCanBreakAfter(NGInlineItemResult*) const;
void BreakLine();
@@ -199,7 +198,7 @@ class CORE_EXPORT NGLineBreaker {
NGLineBreakerMode mode_;
const NGConstraintSpace& constraint_space_;
Vector<NGPositionedFloat>* positioned_floats_;
- Vector<scoped_refptr<NGUnpositionedFloat>>* unpositioned_floats_;
+ NGUnpositionedFloatVector* unpositioned_floats_;
NGContainerFragmentBuilder* container_builder_; /* May be nullptr */
NGExclusionSpace* exclusion_space_;
scoped_refptr<const ComputedStyle> current_style_;
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 1a6baf2a451..208595bc496 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
@@ -41,7 +41,7 @@ class NGLineBreakerTest : public NGBaseLayoutAlgorithmTest {
.ToConstraintSpace(WritingMode::kHorizontalTb);
Vector<NGPositionedFloat> positioned_floats;
- Vector<scoped_refptr<NGUnpositionedFloat>> unpositioned_floats;
+ NGUnpositionedFloatVector unpositioned_floats;
scoped_refptr<NGInlineBreakToken> break_token;
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 919cb689b26..49df71cfc51 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
@@ -112,6 +112,16 @@ LayoutUnit NGLineTruncator::TruncateLine(
return std::max(ellipsis_inline_offset + ellipsis_width, line_width);
}
+// Hide this child from being painted.
+void NGLineTruncator::HideChild(NGLineBoxFragmentBuilder::Child* child) {
+ DCHECK(child->HasInFlowFragment());
+ // TODO(kojii): Not producing fragments is the most clean and efficient way to
+ // hide them, but we may want to revisit how to do this to reduce special
+ // casing in other code.
+ child->layout_result = nullptr;
+ child->fragment = nullptr;
+}
+
// Return the offset to place the ellipsis.
//
// This function may truncate or move the child so that the ellipsis can fit.
@@ -131,16 +141,24 @@ base::Optional<LayoutUnit> NGLineTruncator::EllipsisOffset(
? child->offset.inline_offset
: line_width - (child->offset.inline_offset + child->inline_size);
LayoutUnit space_for_child = available_width_ - child_inline_offset;
- if (space_for_child <= 0)
+ if (space_for_child <= 0) {
+ // This child is outside of the content box, but we still need to hide it.
+ // When the box has paddings, this child outside of the content box maybe
+ // still inside of the clipping box.
+ if (!is_first_child)
+ HideChild(child);
return base::nullopt;
+ }
+ // At least part of this child is in the box.
// If not all of this child can fit, try to truncate.
space_for_child -= ellipsis_width;
if (space_for_child < child->inline_size &&
!TruncateChild(space_for_child, is_first_child, child)) {
- // This child maybe partially visible. When it can't be truncated, move it
- // out so that none of this child should be visible.
- child->offset.inline_offset = line_width;
+ // This child is partially in the box, but it should not be visible because
+ // earlier sibling will be truncated and ellipsized.
+ if (!is_first_child)
+ HideChild(child);
return base::nullopt;
}
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 adfcd22ad9c..83bfbd120b1 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
@@ -39,6 +39,7 @@ class CORE_EXPORT NGLineTruncator final {
bool TruncateChild(LayoutUnit space_for_this_child,
bool is_first_child,
NGLineBoxFragmentBuilder::Child* child);
+ void HideChild(NGLineBoxFragmentBuilder::Child* child);
NGInlineNode& node_;
scoped_refptr<const ComputedStyle> line_style_;
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 46e7077f983..78e257b7111 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
@@ -8,6 +8,7 @@
#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/position.h"
+#include "third_party/blink/renderer/core/layout/layout_text_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h"
#include "third_party/blink/renderer/core/layout/ng/ng_block_node.h"
#include "third_party/blink/renderer/platform/text/character.h"
@@ -86,6 +87,28 @@ NGOffsetMappingUnit::NGOffsetMappingUnit(NGOffsetMappingUnitType type,
NGOffsetMappingUnit::~NGOffsetMappingUnit() = default;
+bool NGOffsetMappingUnit::Concatenate(const NGOffsetMappingUnit& other) {
+ if (owner_ != other.owner_)
+ return false;
+ if (type_ != other.type_ || type_ == NGOffsetMappingUnitType::kExpanded)
+ return false;
+ if (dom_end_ != other.dom_start_)
+ return false;
+ if (text_content_end_ != other.text_content_start_)
+ return false;
+ // Don't merge first letter and remaining text
+ if (const LayoutTextFragment* text_fragment =
+ ToLayoutTextFragmentOrNull(owner_->GetLayoutObject())) {
+ // TODO(layout-dev): Fix offset calculation for text-transform
+ if (text_fragment->IsRemainingTextLayoutObject() &&
+ other.dom_start_ == text_fragment->TextStartOffset())
+ return false;
+ }
+ dom_end_ = other.dom_end_;
+ text_content_end_ = other.text_content_end_;
+ return true;
+}
+
unsigned NGOffsetMappingUnit::ConvertDOMOffsetToTextContent(
unsigned offset) const {
DCHECK_GE(offset, dom_start_);
@@ -181,7 +204,7 @@ NGOffsetMapping::NGOffsetMapping(NGOffsetMapping&& other)
NGOffsetMapping::NGOffsetMapping(UnitVector&& units,
RangeMap&& ranges,
String text)
- : units_(units), ranges_(ranges), text_(text) {}
+ : units_(std::move(units)), ranges_(std::move(ranges)), text_(text) {}
NGOffsetMapping::~NGOffsetMapping() = default;
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 efb2769eb30..e38f1250bf2 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
@@ -55,19 +55,25 @@ class CORE_EXPORT NGOffsetMappingUnit {
unsigned TextContentStart() const { return text_content_start_; }
unsigned TextContentEnd() const { return text_content_end_; }
+ // If the passed unit can be concatenated to |this| to create a bigger unit,
+ // replaces |this| by the result and returns true; Returns false otherwise.
+ bool Concatenate(const NGOffsetMappingUnit&);
+
unsigned ConvertDOMOffsetToTextContent(unsigned) const;
unsigned ConvertTextContentToFirstDOMOffset(unsigned) const;
unsigned ConvertTextContentToLastDOMOffset(unsigned) const;
private:
- const NGOffsetMappingUnitType type_ = NGOffsetMappingUnitType::kIdentity;
+ NGOffsetMappingUnitType type_ = NGOffsetMappingUnitType::kIdentity;
+
+ Persistent<const Node> owner_;
+ unsigned dom_start_;
+ unsigned dom_end_;
+ unsigned text_content_start_;
+ unsigned text_content_end_;
- const Persistent<const Node> owner_;
- const unsigned dom_start_;
- const unsigned dom_end_;
- const unsigned text_content_start_;
- const unsigned text_content_end_;
+ friend class NGOffsetMappingBuilder;
};
class NGMappingUnitRange {
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_builder.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_builder.cc
index 9e277be260a..f80da9ada70 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_builder.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_builder.cc
@@ -12,70 +12,40 @@ namespace blink {
namespace {
-// Returns the type of a unit-length simple offset mapping.
-NGOffsetMappingUnitType GetUnitLengthMappingType(unsigned value) {
- if (value == 0u)
- return NGOffsetMappingUnitType::kCollapsed;
- if (value == 1u)
- return NGOffsetMappingUnitType::kIdentity;
- return NGOffsetMappingUnitType::kExpanded;
-}
-
-// Returns the associated node of a possibly null LayoutObject.
+// Returns the associated non-pseudo node from |layout_object|, handling
+// first-letter text fragments.
const Node* GetAssociatedNode(const LayoutObject* layout_object) {
if (!layout_object)
return nullptr;
- if (!layout_object->IsText() ||
- !ToLayoutText(layout_object)->IsTextFragment())
- return layout_object->NonPseudoNode();
- const LayoutTextFragment* fragment = ToLayoutTextFragment(layout_object);
- return fragment->AssociatedTextNode();
-}
-
-// Finds the offset mapping unit starting from index |start|.
-std::pair<NGOffsetMappingUnitType, unsigned> GetMappingUnitTypeAndEnd(
- const Vector<unsigned>& mapping,
- const Vector<const LayoutObject*>& annotation,
- unsigned start) {
- DCHECK_LT(start + 1, mapping.size());
- NGOffsetMappingUnitType type =
- GetUnitLengthMappingType(mapping[start + 1] - mapping[start]);
- if (type == NGOffsetMappingUnitType::kExpanded)
- return std::make_pair(type, start + 1);
-
- unsigned end = start + 1;
- for (; end + 1 < mapping.size(); ++end) {
- if (annotation[end] != annotation[start])
- break;
- NGOffsetMappingUnitType next_type =
- GetUnitLengthMappingType(mapping[end + 1] - mapping[end]);
- if (next_type != type)
- break;
- }
- return std::make_pair(type, end);
+ if (const auto* text_fragment = ToLayoutTextFragmentOrNull(layout_object))
+ return text_fragment->AssociatedTextNode();
+ return layout_object->GetNode();
}
-// If |layout_object| is the remaining text of a text node, returns the start
-// offset; In all other cases, returns 0.
-unsigned GetRemainingTextOffset(const LayoutObject* layout_object) {
- if (!layout_object || !layout_object->IsText())
- return 0;
- return ToLayoutText(layout_object)->TextStartOffset();
+// Returns 0 unless |layout_object| is the remaining text of a node styled with
+// ::first-letter, in which case it returns the start offset of the remaining
+// text.
+unsigned GetAssociatedStartOffset(const LayoutObject* layout_object) {
+ if (const auto* text_fragment = ToLayoutTextFragmentOrNull(layout_object))
+ return text_fragment->Start();
+ return 0;
}
} // namespace
-NGOffsetMappingBuilder::NGOffsetMappingBuilder() {
- mapping_.push_back(0);
-}
+NGOffsetMappingBuilder::NGOffsetMappingBuilder() = default;
NGOffsetMappingBuilder::SourceNodeScope::SourceNodeScope(
NGOffsetMappingBuilder* builder,
const LayoutObject* node)
- : auto_reset_(&builder->current_source_node_, node) {
+ : builder_(builder),
+ layout_object_auto_reset_(&builder->current_node_,
+ GetAssociatedNode(node)),
+ appended_length_auto_reset_(&builder->current_offset_,
+ GetAssociatedStartOffset(node)) {
+ builder_->has_open_unit_ = false;
#if DCHECK_IS_ON()
- builder_ = builder;
- if (!node)
+ if (!builder_->current_node_)
return;
// We allow at most one scope with non-null node at any time.
DCHECK(!builder->has_nonnull_node_scope_);
@@ -84,187 +54,183 @@ NGOffsetMappingBuilder::SourceNodeScope::SourceNodeScope(
}
NGOffsetMappingBuilder::SourceNodeScope::~SourceNodeScope() {
+ builder_->has_open_unit_ = false;
#if DCHECK_IS_ON()
- if (builder_->current_source_node_)
+ if (builder_->current_node_)
builder_->has_nonnull_node_scope_ = false;
#endif
}
+void NGOffsetMappingBuilder::ReserveCapacity(unsigned capacity) {
+ unit_ranges_.ReserveCapacityForSize(capacity);
+ mapping_units_.ReserveCapacity(capacity * 1.5);
+}
+
void NGOffsetMappingBuilder::AppendIdentityMapping(unsigned length) {
DCHECK_GT(length, 0u);
- DCHECK(!mapping_.IsEmpty());
- for (unsigned i = 0; i < length; ++i) {
- unsigned next = mapping_.back() + 1;
- mapping_.push_back(next);
+ const unsigned dom_start = current_offset_;
+ const unsigned dom_end = dom_start + length;
+ const unsigned text_content_start = destination_length_;
+ const unsigned text_content_end = text_content_start + length;
+ current_offset_ += length;
+ destination_length_ += length;
+
+ if (!current_node_)
+ return;
+
+ if (has_open_unit_ &&
+ mapping_units_.back().GetType() == NGOffsetMappingUnitType::kIdentity) {
+ DCHECK_EQ(mapping_units_.back().GetOwner(), current_node_);
+ DCHECK_EQ(mapping_units_.back().DOMEnd(), dom_start);
+ mapping_units_.back().dom_end_ += length;
+ mapping_units_.back().text_content_end_ += length;
+ return;
}
- annotation_.resize(annotation_.size() + length);
- std::fill(annotation_.end() - length, annotation_.end(),
- current_source_node_);
+
+ mapping_units_.emplace_back(NGOffsetMappingUnitType::kIdentity,
+ *current_node_, dom_start, dom_end,
+ text_content_start, text_content_end);
+ has_open_unit_ = true;
}
void NGOffsetMappingBuilder::AppendCollapsedMapping(unsigned length) {
DCHECK_GT(length, 0u);
- DCHECK(!mapping_.IsEmpty());
- const unsigned back = mapping_.back();
- for (unsigned i = 0; i < length; ++i)
- mapping_.push_back(back);
- annotation_.resize(annotation_.size() + length);
- std::fill(annotation_.end() - length, annotation_.end(),
- current_source_node_);
-}
+ const unsigned dom_start = current_offset_;
+ const unsigned dom_end = dom_start + length;
+ const unsigned text_content_start = destination_length_;
+ const unsigned text_content_end = text_content_start;
+ current_offset_ += length;
+
+ if (!current_node_)
+ return;
-void NGOffsetMappingBuilder::CollapseTrailingSpace(unsigned skip_length) {
- DCHECK(!mapping_.IsEmpty());
-
- // Find the |skipped_count + 1|-st last uncollapsed character. By collapsing
- // it, all mapping values beyond this position are decremented by 1.
- unsigned skipped_count = 0;
- for (unsigned i = mapping_.size() - 1; skipped_count <= skip_length; --i) {
- DCHECK_GT(i, 0u);
- if (mapping_[i] != mapping_[i - 1])
- ++skipped_count;
- --mapping_[i];
+ if (has_open_unit_ &&
+ mapping_units_.back().GetType() == NGOffsetMappingUnitType::kCollapsed) {
+ DCHECK_EQ(mapping_units_.back().GetOwner(), current_node_);
+ DCHECK_EQ(mapping_units_.back().DOMEnd(), dom_start);
+ mapping_units_.back().dom_end_ += length;
+ return;
}
+
+ mapping_units_.emplace_back(NGOffsetMappingUnitType::kCollapsed,
+ *current_node_, dom_start, dom_end,
+ text_content_start, text_content_end);
+ has_open_unit_ = true;
}
-void NGOffsetMappingBuilder::Concatenate(const NGOffsetMappingBuilder& other) {
- DCHECK(!mapping_.IsEmpty());
- DCHECK(!other.mapping_.IsEmpty());
- const unsigned shift_amount = mapping_.back();
- for (unsigned i = 1; i < other.mapping_.size(); ++i)
- mapping_.push_back(other.mapping_[i] + shift_amount);
- annotation_.AppendVector(other.annotation_);
+void NGOffsetMappingBuilder::CollapseTrailingSpace(unsigned space_offset) {
+ DCHECK_LT(space_offset, destination_length_);
+ --destination_length_;
+
+ NGOffsetMappingUnit* container_unit = nullptr;
+ for (unsigned i = mapping_units_.size(); i;) {
+ NGOffsetMappingUnit& unit = mapping_units_[--i];
+ if (unit.TextContentStart() > space_offset) {
+ --unit.text_content_start_;
+ --unit.text_content_end_;
+ continue;
+ }
+ container_unit = &unit;
+ break;
+ }
+
+ if (!container_unit || container_unit->TextContentEnd() <= space_offset)
+ return;
+
+ // container_unit->TextContentStart()
+ // <= space_offset <
+ // container_unit->TextContentEnd()
+ DCHECK_EQ(NGOffsetMappingUnitType::kIdentity, container_unit->GetType());
+ const Node& node = container_unit->GetOwner();
+ unsigned dom_offset = container_unit->DOMStart();
+ unsigned text_content_offset = container_unit->TextContentStart();
+ unsigned offset_to_collapse = space_offset - text_content_offset;
+
+ Vector<NGOffsetMappingUnit, 3> new_units;
+ if (offset_to_collapse) {
+ new_units.emplace_back(NGOffsetMappingUnitType::kIdentity, node, dom_offset,
+ dom_offset + offset_to_collapse, text_content_offset,
+ text_content_offset + offset_to_collapse);
+ dom_offset += offset_to_collapse;
+ text_content_offset += offset_to_collapse;
+ }
+ new_units.emplace_back(NGOffsetMappingUnitType::kCollapsed, node, dom_offset,
+ dom_offset + 1, text_content_offset,
+ text_content_offset);
+ ++dom_offset;
+ if (dom_offset < container_unit->DOMEnd()) {
+ new_units.emplace_back(NGOffsetMappingUnitType::kIdentity, node, dom_offset,
+ container_unit->DOMEnd(), text_content_offset,
+ container_unit->TextContentEnd() - 1);
+ }
+
+ // TODO(xiaochengh): Optimize if this becomes performance bottleneck.
+ unsigned position = std::distance(mapping_units_.begin(), container_unit);
+ mapping_units_.EraseAt(position);
+ mapping_units_.InsertVector(position, new_units);
+ ShiftRanges(position, new_units.size() - 1);
+ unsigned new_unit_end = position + new_units.size();
+ while (new_unit_end && new_unit_end < mapping_units_.size() &&
+ mapping_units_[new_unit_end - 1].Concatenate(
+ mapping_units_[new_unit_end])) {
+ mapping_units_.EraseAt(new_unit_end);
+ ShiftRanges(new_unit_end, -1);
+ }
+ while (position && position < mapping_units_.size() &&
+ mapping_units_[position - 1].Concatenate(mapping_units_[position])) {
+ mapping_units_.EraseAt(position);
+ ShiftRanges(position, -1);
+ }
}
-void NGOffsetMappingBuilder::Composite(const NGOffsetMappingBuilder& other) {
- DCHECK(!mapping_.IsEmpty());
- DCHECK_EQ(mapping_.back() + 1, other.mapping_.size());
- for (unsigned i = 0; i < mapping_.size(); ++i)
- mapping_[i] = other.mapping_[mapping_[i]];
+void NGOffsetMappingBuilder::ShiftRanges(unsigned position, int delta) {
+ for (auto& range : unit_ranges_) {
+ auto& pair = range.value;
+ if (pair.first > position)
+ pair.first += delta;
+ if (pair.second > position)
+ pair.second += delta;
+ }
}
void NGOffsetMappingBuilder::SetDestinationString(String string) {
- DCHECK_EQ(mapping_.back(), string.length());
+ DCHECK_EQ(destination_length_, string.length());
destination_string_ = string;
}
NGOffsetMapping NGOffsetMappingBuilder::Build() {
- NGOffsetMapping::UnitVector units;
- NGOffsetMapping::RangeMap ranges;
-
- // Information of current owner node
- const Node* nonnull_owner = nullptr;
- unsigned processed_length = 0;
- unsigned unit_range_start = 0;
- unsigned remaining_text_offset = 0;
-
- // Information of non-atomic inlines that we are currently in
- using NodeAndStart = std::pair<const Node*, unsigned>;
- Vector<NodeAndStart> current_inlines;
-
- // Sentinels
- annotation_.push_back(nullptr);
- boundaries_.push_back(InlineBoundary({nullptr, mapping_.size() - 1, false}));
-
- const InlineBoundary* boundary_it = boundaries_.begin();
- unsigned unit_start = 0;
- while (unit_start + 1 < mapping_.size() ||
- std::next(boundary_it) != boundaries_.end()) {
- // Handle boundaries of non-atomic inline nodes
- if (std::next(boundary_it) != boundaries_.end() &&
- boundary_it->offset <= unit_start) {
- const InlineBoundary& boundary = *boundary_it++;
- const Node* node = GetAssociatedNode(boundary.node);
- // Skip generated content
- if (!node)
- continue;
-
- // Enter non-atomic inline
- if (boundary.is_enter) {
- current_inlines.push_back(NodeAndStart({node, units.size()}));
- continue;
- }
-
- // Exit non-atomic inline
- DCHECK(current_inlines.size());
- DCHECK_EQ(node, current_inlines.back().first);
- const unsigned node_unit_range_start = current_inlines.back().second;
- if (units.size() > node_unit_range_start) {
- ranges.insert(node,
- std::make_pair(node_unit_range_start, units.size()));
- }
- current_inlines.pop_back();
- continue;
- }
-
- // Create mapping units and/or unit ranges, if any
- DCHECK_LT(unit_start, annotation_.size());
- const Node* node = GetAssociatedNode(annotation_[unit_start]);
- const auto type_and_end =
- GetMappingUnitTypeAndEnd(mapping_, annotation_, unit_start);
- unsigned unit_end = type_and_end.second;
- // Create unit only for non-generated content.
- if (node) {
- if (node != nonnull_owner) {
- nonnull_owner = node;
- processed_length = 0;
- }
-
- if (!unit_start ||
- node != GetAssociatedNode(annotation_[unit_start - 1])) {
- unit_range_start = units.size();
- // We get a non-zero |remaining_text_offset| only when |current_node| is
- // a text node that has blockified ::first-letter style, and we are at
- // the remaining text of |current_node|.
- remaining_text_offset = GetRemainingTextOffset(annotation_[unit_start]);
- }
-
- NGOffsetMappingUnitType type = type_and_end.first;
- unsigned dom_start = processed_length + remaining_text_offset;
- unsigned dom_end = unit_end - unit_start + dom_start;
- unsigned text_content_start = mapping_[unit_start];
- unsigned text_content_end = mapping_[unit_end];
- units.emplace_back(type, *node, dom_start, dom_end, text_content_start,
- text_content_end);
-
- processed_length += dom_end - dom_start;
-
- if (GetAssociatedNode(annotation_[unit_end]) != node) {
- auto iter = ranges.find(node);
- if (iter != ranges.end()) {
- // We are here if characters of |node| were appended inconsecutively,
- // separated by generated characters. An example is BiDi-overridden
- // text node with 'white-space: pre' style, where generated BiDi-
- // control characters are inserted around '\n' characters.
- DCHECK_EQ(iter->value.second, unit_range_start);
- iter->value.second = units.size();
- } else {
- ranges.insert(node, std::make_pair(unit_range_start, units.size()));
- }
- }
- }
- unit_start = unit_end;
+ // All mapping units are already built. Scan them to build mapping ranges.
+ for (unsigned range_start = 0; range_start < mapping_units_.size();) {
+ const Node* node = &mapping_units_[range_start].GetOwner();
+ // Units of the same node should be consecutive in the mapping function,
+ // If not, the layout structure should be already broken.
+ DCHECK(!unit_ranges_.Contains(node)) << node;
+ unsigned range_end = range_start + 1;
+ while (range_end < mapping_units_.size() &&
+ mapping_units_[range_end].GetOwner() == node)
+ ++range_end;
+ unit_ranges_.insert(node, std::make_pair(range_start, range_end));
+ range_start = range_end;
}
- return NGOffsetMapping(std::move(units), std::move(ranges),
+ return NGOffsetMapping(std::move(mapping_units_), std::move(unit_ranges_),
destination_string_);
}
-void NGOffsetMappingBuilder::EnterInline(const LayoutObject& node) {
- boundaries_.push_back(InlineBoundary({&node, mapping_.size() - 1, true}));
-}
-
-void NGOffsetMappingBuilder::ExitInline(const LayoutObject& node) {
- boundaries_.push_back(InlineBoundary({&node, mapping_.size() - 1, false}));
-}
-
-Vector<unsigned> NGOffsetMappingBuilder::DumpOffsetMappingForTesting() const {
- return mapping_;
+void NGOffsetMappingBuilder::EnterInline(const LayoutObject& layout_object) {
+ if (!layout_object.NonPseudoNode())
+ return;
+ open_inlines_.push_back(mapping_units_.size());
}
-Vector<const LayoutObject*> NGOffsetMappingBuilder::DumpAnnotationForTesting()
- const {
- return annotation_;
+void NGOffsetMappingBuilder::ExitInline(const LayoutObject& layout_object) {
+ if (!layout_object.NonPseudoNode())
+ return;
+ DCHECK(open_inlines_.size());
+ unit_ranges_.insert(
+ layout_object.GetNode(),
+ std::make_pair(open_inlines_.back(), mapping_units_.size()));
+ open_inlines_.pop_back();
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_builder.h b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_builder.h
index 716d3ac760e..c24971a7498 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_builder.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_builder.h
@@ -7,6 +7,7 @@
#include "base/auto_reset.h"
#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -14,7 +15,6 @@
namespace blink {
class LayoutObject;
-class NGOffsetMapping;
// This is the helper class for constructing the DOM-to-TextContent offset
// mapping. It holds an offset mapping, and provides APIs to modify the mapping
@@ -25,22 +25,6 @@ class CORE_EXPORT NGOffsetMappingBuilder {
STACK_ALLOCATED();
public:
- NGOffsetMappingBuilder();
-
- // Append an identity offset mapping of the specified length with null
- // annotation to the builder.
- void AppendIdentityMapping(unsigned length);
-
- // Append a collapsed offset mapping from the specified length with null
- // annotation to the builder.
- void AppendCollapsedMapping(unsigned length);
-
- // TODO(xiaochengh): Add the following API when we start to fix offset mapping
- // for text-transform.
- // Append an expanded offset mapping to the specified length with null
- // annotation to the builder.
- // void AppendExpandedMapping(unsigned length);
-
// A scope-like object that, mappings appended inside the scope are marked as
// from the given source node. When multiple scopes nest, only the inner-most
// scope is effective. Note that at most one of the nested scopes may have a
@@ -80,30 +64,47 @@ class CORE_EXPORT NGOffsetMappingBuilder {
~SourceNodeScope();
private:
- base::AutoReset<const LayoutObject*> auto_reset_;
-
-#if DCHECK_IS_ON()
- NGOffsetMappingBuilder* builder_ = nullptr;
-#endif
+ NGOffsetMappingBuilder* const builder_ = nullptr;
+ base::AutoReset<Persistent<const Node>> layout_object_auto_reset_;
+ base::AutoReset<unsigned> appended_length_auto_reset_;
DISALLOW_COPY_AND_ASSIGN(SourceNodeScope);
};
+ NGOffsetMappingBuilder();
+
+ void ReserveCapacity(unsigned capacity);
+
+ // Append an identity offset mapping of the specified length with null
+ // annotation to the builder.
+ void AppendIdentityMapping(unsigned length);
+
+ // Append a collapsed offset mapping from the specified length with null
+ // annotation to the builder.
+ void AppendCollapsedMapping(unsigned length);
+
+ // TODO(xiaochengh): Add the following API when we start to fix offset mapping
+ // for text-transform.
+ // Append an expanded offset mapping to the specified length with null
+ // annotation to the builder.
+ // void AppendExpandedMapping(unsigned length);
+
// This function should only be called by NGInlineItemsBuilder during
// whitespace collapsing, and in the case that the target string of the
// currently held mapping:
- // (i) has at least |skip_length + 1| characters,
- // (ii) has the last |skip_length| characters being non-text extra
- // characters, and
- // (iii) has the |skip_length + 1|-st last character being a space.
+ // (i) has at least |space_offset + 1| characters,
+ // (ii) character at |space_offset| in destination string is a collapsible
+ // whitespace,
// This function changes the space into collapsed.
- void CollapseTrailingSpace(unsigned index);
+ void CollapseTrailingSpace(unsigned space_offset);
// Concatenate the offset mapping held by another builder to this builder.
- void Concatenate(const NGOffsetMappingBuilder&);
+ // TODO(xiaochengh): Implement when adding support for 'text-transform'
+ // void Concatenate(const NGOffsetMappingBuilder&);
// Composite the offset mapping held by another builder to this builder.
- void Composite(const NGOffsetMappingBuilder&);
+ // TODO(xiaochengh): Implement when adding support for 'text-transform'
+ // void Composite(const NGOffsetMappingBuilder&);
// Set the destination string of the offset mapping.
void SetDestinationString(String);
@@ -120,35 +121,32 @@ class CORE_EXPORT NGOffsetMappingBuilder {
// This method can only be called once, as it can invalidate the stored data.
NGOffsetMapping Build();
- // Exposed for testing only.
- Vector<unsigned> DumpOffsetMappingForTesting() const;
- Vector<const LayoutObject*> DumpAnnotationForTesting() const;
-
private:
- // A mock implementation of the offset mapping builder that stores the mapping
- // value of every offset in the plain way. This is simple but inefficient, and
- // will be replaced by a real efficient implementation.
- Vector<unsigned> mapping_;
+ // Helper function for CollapseTrailingSpace() to maintain unit ranges.
+ void ShiftRanges(unsigned position, int delta);
- const LayoutObject* current_source_node_ = nullptr;
+ Persistent<const Node> current_node_ = nullptr;
+ unsigned current_offset_ = 0;
+ bool has_open_unit_ = false;
#if DCHECK_IS_ON()
bool has_nonnull_node_scope_ = false;
#endif
- // A mock implementation that stores the annotation value of all offsets in
- // the plain way. It will be replaced by a real implementation for efficiency.
- Vector<const LayoutObject*> annotation_;
+ // Length of the current destination string.
+ unsigned destination_length_ = 0;
+
+ // Mapping units of the current mapping function.
+ Vector<NGOffsetMappingUnit> mapping_units_;
+
+ // Unit ranges of the current mapping function.
+ NGOffsetMapping::RangeMap unit_ranges_;
+
+ // Unit range starts of currently entered inline elements.
+ Vector<unsigned> open_inlines_;
// The destination string of the offset mapping.
String destination_string_;
- struct InlineBoundary {
- const LayoutObject* node;
- size_t offset;
- bool is_enter;
- };
- Vector<InlineBoundary> boundaries_;
-
friend class SourceNodeScope;
DISALLOW_COPY_AND_ASSIGN(NGOffsetMappingBuilder);
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 1036a000106..50b791d9a08 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
@@ -39,6 +39,74 @@ class NGOffsetMappingTest : public NGLayoutTest {
return *map;
}
+ String GetCollapsedIndexes() const {
+ const NGOffsetMapping& mapping = GetOffsetMapping();
+ const EphemeralRange block_range =
+ EphemeralRange::RangeOfContents(*layout_block_flow_->GetNode());
+
+ StringBuilder result;
+ for (const Node& node : block_range.Nodes()) {
+ if (!node.IsTextNode())
+ continue;
+
+ Vector<unsigned> collapsed_indexes;
+ for (const auto& unit : mapping.GetMappingUnitsForDOMRange(
+ EphemeralRange::RangeOfContents(node))) {
+ if (unit.GetType() != NGOffsetMappingUnitType::kCollapsed)
+ continue;
+ for (unsigned i = unit.DOMStart(); i < unit.DOMEnd(); ++i)
+ collapsed_indexes.push_back(i);
+ }
+
+ result.Append('{');
+ bool first = true;
+ for (unsigned index : collapsed_indexes) {
+ if (!first)
+ result.Append(", ");
+ result.AppendNumber(index);
+ first = false;
+ }
+ result.Append('}');
+ }
+ return result.ToString();
+ }
+
+ String TestCollapsingWithCSSWhiteSpace(String text, String whitespace) {
+ StringBuilder html;
+ html.Append("<div id=t style=\"white-space:");
+ html.Append(whitespace);
+ html.Append("\">");
+ html.Append(text);
+ html.Append("</div>");
+ SetupHtml("t", html.ToString());
+ return GetCollapsedIndexes();
+ }
+
+ String TestCollapsing(Vector<String> text) {
+ StringBuilder html;
+ html.Append("<div id=t>");
+ for (unsigned i = 0; i < text.size(); ++i) {
+ if (i)
+ html.Append("<!---->");
+ html.Append(text[i]);
+ }
+ html.Append("</div>");
+ SetupHtml("t", html.ToString());
+ return GetCollapsedIndexes();
+ }
+
+ String TestCollapsing(String text) {
+ return TestCollapsing(Vector<String>({text}));
+ }
+
+ String TestCollapsing(String text, String text2) {
+ return TestCollapsing(Vector<String>({text, text2}));
+ }
+
+ String TestCollapsing(String text, String text2, String text3) {
+ return TestCollapsing(Vector<String>({text, text2, text3}));
+ }
+
bool IsOffsetMappingStored() const {
return layout_block_flow_->GetNGInlineNodeData()->offset_mapping.get();
}
@@ -88,15 +156,165 @@ class NGOffsetMappingTest : public NGLayoutTest {
FontCachePurgePreventer purge_preventer_;
};
-// TODO(layout-dev): Remove this unused parameterization.
-class ParameterizedNGOffsetMappingTest
- : public testing::WithParamInterface<bool>,
- public NGOffsetMappingTest {
- public:
- ParameterizedNGOffsetMappingTest() {}
-};
+TEST_F(NGOffsetMappingTest, CollapseSpaces) {
+ String input("text text text text");
+ EXPECT_EQ("{10, 16, 17}", TestCollapsingWithCSSWhiteSpace(input, "normal"));
+ EXPECT_EQ("{10, 16, 17}", TestCollapsingWithCSSWhiteSpace(input, "nowrap"));
+ EXPECT_EQ("{10, 16, 17}",
+ TestCollapsingWithCSSWhiteSpace(input, "-webkit-nowrap"));
+ EXPECT_EQ("{10, 16, 17}", TestCollapsingWithCSSWhiteSpace(input, "pre-line"));
+ EXPECT_EQ("{}", TestCollapsingWithCSSWhiteSpace(input, "pre"));
+ EXPECT_EQ("{}", TestCollapsingWithCSSWhiteSpace(input, "pre-wrap"));
+}
+
+TEST_F(NGOffsetMappingTest, CollapseTabs) {
+ String input("text text \ttext \t\ttext");
+ EXPECT_EQ("{10, 16, 17}", TestCollapsingWithCSSWhiteSpace(input, "normal"));
+ EXPECT_EQ("{10, 16, 17}", TestCollapsingWithCSSWhiteSpace(input, "nowrap"));
+ EXPECT_EQ("{10, 16, 17}",
+ TestCollapsingWithCSSWhiteSpace(input, "-webkit-nowrap"));
+ EXPECT_EQ("{10, 16, 17}", TestCollapsingWithCSSWhiteSpace(input, "pre-line"));
+ EXPECT_EQ("{}", TestCollapsingWithCSSWhiteSpace(input, "pre"));
+ EXPECT_EQ("{}", TestCollapsingWithCSSWhiteSpace(input, "pre-wrap"));
+}
+
+TEST_F(NGOffsetMappingTest, CollapseNewLines) {
+ String input("text\ntext \n text\n\ntext");
+ EXPECT_EQ("{10, 11, 17}", TestCollapsingWithCSSWhiteSpace(input, "normal"));
+ EXPECT_EQ("{10, 11, 17}", TestCollapsingWithCSSWhiteSpace(input, "nowrap"));
+ EXPECT_EQ("{10, 11, 17}",
+ TestCollapsingWithCSSWhiteSpace(input, "-webkit-nowrap"));
+ EXPECT_EQ("{9, 11}", TestCollapsingWithCSSWhiteSpace(input, "pre-line"));
+ EXPECT_EQ("{}", TestCollapsingWithCSSWhiteSpace(input, "pre"));
+ EXPECT_EQ("{}", TestCollapsingWithCSSWhiteSpace(input, "pre-wrap"));
+}
+
+TEST_F(NGOffsetMappingTest, CollapseNewlinesAsSpaces) {
+ EXPECT_EQ("{}", TestCollapsing("text\ntext"));
+ EXPECT_EQ("{5}", TestCollapsing("text\n\ntext"));
+ EXPECT_EQ("{5, 6, 7}", TestCollapsing("text \n\n text"));
+ EXPECT_EQ("{5, 6, 7, 8}", TestCollapsing("text \n \n text"));
+}
+
+TEST_F(NGOffsetMappingTest, CollapseAcrossElements) {
+ EXPECT_EQ("{}{0}", TestCollapsing("text ", " text"))
+ << "Spaces are collapsed even when across elements.";
+}
+
+TEST_F(NGOffsetMappingTest, CollapseLeadingSpaces) {
+ EXPECT_EQ("{0, 1}", TestCollapsing(" text"));
+ // TODO(xiaochengh): Currently, LayoutText of trailing whitespace nodes are
+ // omitted, so we can't verify the following cases. Get around it and make the
+ // following tests work. EXPECT_EQ("{0}{}", TestCollapsing(" ", "text"));
+ // EXPECT_EQ("{0}{0}", TestCollapsing(" ", " text"));
+}
+
+TEST_F(NGOffsetMappingTest, CollapseTrailingSpaces) {
+ EXPECT_EQ("{4, 5}", TestCollapsing("text "));
+ EXPECT_EQ("{}{0}", TestCollapsing("text", " "));
+ // TODO(xiaochengh): Get around whitespace LayoutText omission, and make the
+ // following test cases work.
+ // EXPECT_EQ("{4}{0}", TestCollapsing("text ", " "));
+}
+
+// TODO(xiaochengh): Get around whitespace LayoutText omission, and make the
+// following test cases work.
+TEST_F(NGOffsetMappingTest, DISABLED_CollapseAllSpaces) {
+ EXPECT_EQ("{0, 1}", TestCollapsing(" "));
+ EXPECT_EQ("{0, 1}{0, 1}", TestCollapsing(" ", " "));
+ EXPECT_EQ("{0, 1}{0}", TestCollapsing(" ", "\n"));
+ EXPECT_EQ("{0}{0, 1}", TestCollapsing("\n", " "));
+}
+
+TEST_F(NGOffsetMappingTest, CollapseLeadingNewlines) {
+ EXPECT_EQ("{0}", TestCollapsing("\ntext"));
+ EXPECT_EQ("{0, 1}", TestCollapsing("\n\ntext"));
+ // TODO(xiaochengh): Get around whitespace LayoutText omission, and make the
+ // following test cases work.
+ // EXPECT_EQ("{0}{}", TestCollapsing("\n", "text"));
+ // EXPECT_EQ("{0, 1}{}", TestCollapsing("\n\n", "text"));
+ // EXPECT_EQ("{0, 1}{}", TestCollapsing(" \n", "text"));
+ // EXPECT_EQ("{0}{0}", TestCollapsing("\n", " text"));
+ // EXPECT_EQ("{0, 1}{0}", TestCollapsing("\n\n", " text"));
+ // EXPECT_EQ("{0, 1}{0}", TestCollapsing(" \n", " text"));
+ // EXPECT_EQ("{0}{0}", TestCollapsing("\n", "\ntext"));
+ // EXPECT_EQ("{0, 1}{0}", TestCollapsing("\n\n", "\ntext"));
+ // EXPECT_EQ("{0, 1}{0}", TestCollapsing(" \n", "\ntext"));
+}
+
+TEST_F(NGOffsetMappingTest, CollapseTrailingNewlines) {
+ EXPECT_EQ("{4}", TestCollapsing("text\n"));
+ EXPECT_EQ("{}{0}", TestCollapsing("text", "\n"));
+ // TODO(xiaochengh): Get around whitespace LayoutText omission, and make the
+ // following test cases work.
+ // EXPECT_EQ("{4}{0}", TestCollapsing("text\n", "\n"));
+ // EXPECT_EQ("{4}{0}", TestCollapsing("text\n", " "));
+ // EXPECT_EQ("{4}{0}", TestCollapsing("text ", "\n"));
+}
-INSTANTIATE_TEST_CASE_P(All, ParameterizedNGOffsetMappingTest, testing::Bool());
+TEST_F(NGOffsetMappingTest, CollapseNewlineAcrossElements) {
+ EXPECT_EQ("{}{0}", TestCollapsing("text ", "\ntext"));
+ EXPECT_EQ("{}{0, 1}", TestCollapsing("text ", "\n text"));
+ EXPECT_EQ("{}{}{0}", TestCollapsing("text", " ", "\ntext"));
+}
+
+TEST_F(NGOffsetMappingTest, CollapseBeforeAndAfterNewline) {
+ EXPECT_EQ("{4, 5, 7, 8}",
+ TestCollapsingWithCSSWhiteSpace("text \n text", "pre-line"))
+ << "Spaces before and after newline are removed.";
+}
+
+TEST_F(NGOffsetMappingTest,
+ CollapsibleSpaceAfterNonCollapsibleSpaceAcrossElements) {
+ SetupHtml("t",
+ "<div id=t>"
+ "<span style=\"white-space:pre-wrap\">text </span>"
+ " text"
+ "</div>");
+ EXPECT_EQ("{}{}", GetCollapsedIndexes())
+ << "The whitespace in constructions like '<span style=\"white-space: "
+ "pre-wrap\">text <span><span> text</span>' does not collapse.";
+}
+
+TEST_F(NGOffsetMappingTest, CollapseZeroWidthSpaces) {
+ EXPECT_EQ("{5}", TestCollapsing(u"text\u200B\ntext"))
+ << "Newline is removed if the character before is ZWS.";
+ EXPECT_EQ("{4}", TestCollapsing(u"text\n\u200Btext"))
+ << "Newline is removed if the character after is ZWS.";
+ EXPECT_EQ("{5}", TestCollapsing(u"text\u200B\n\u200Btext"))
+ << "Newline is removed if the character before/after is ZWS.";
+
+ EXPECT_EQ("{4}{}", TestCollapsing(u"text\n", u"\u200Btext"))
+ << "Newline is removed if the character after across elements is ZWS.";
+ EXPECT_EQ("{}{0}", TestCollapsing(u"text\u200B", u"\ntext"))
+ << "Newline is removed if the character before is ZWS even across "
+ "elements.";
+
+ EXPECT_EQ("{4, 5}{}", TestCollapsing(u"text \n", u"\u200Btext"))
+ << "Collapsible space before newline does not affect the result.";
+ EXPECT_EQ("{5}{0}", TestCollapsing(u"text\u200B\n", u" text"))
+ << "Collapsible space after newline is removed even when the "
+ "newline was removed.";
+ EXPECT_EQ("{5}{0}", TestCollapsing(u"text\u200B ", u"\ntext"))
+ << "A white space sequence containing a segment break before or after "
+ "a zero width space is collapsed to a zero width space.";
+}
+
+TEST_F(NGOffsetMappingTest, CollapseEastAsianWidth) {
+ EXPECT_EQ("{1}", TestCollapsing(u"\u4E00\n\u4E00"))
+ << "Newline is removed when both sides are Wide.";
+
+ EXPECT_EQ("{}", TestCollapsing(u"\u4E00\nA"))
+ << "Newline is not removed when after is Narrow.";
+ EXPECT_EQ("{}", TestCollapsing(u"A\n\u4E00"))
+ << "Newline is not removed when before is Narrow.";
+
+ EXPECT_EQ("{1}{}", TestCollapsing(u"\u4E00\n", u"\u4E00"))
+ << "Newline at the end of elements is removed when both sides are Wide.";
+ EXPECT_EQ("{}{0}", TestCollapsing(u"\u4E00", u"\n\u4E00"))
+ << "Newline at the beginning of elements is removed "
+ "when both sides are Wide.";
+}
#define TEST_UNIT(unit, type, owner, dom_start, dom_end, text_content_start, \
text_content_end) \
@@ -112,14 +330,14 @@ INSTANTIATE_TEST_CASE_P(All, ParameterizedNGOffsetMappingTest, testing::Bool());
EXPECT_EQ(start, ranges.at(owner).first); \
EXPECT_EQ(end, ranges.at(owner).second)
-TEST_P(ParameterizedNGOffsetMappingTest, StoredResult) {
+TEST_F(NGOffsetMappingTest, StoredResult) {
SetupHtml("t", "<div id=t>foo</div>");
EXPECT_FALSE(IsOffsetMappingStored());
GetOffsetMapping();
EXPECT_TRUE(IsOffsetMappingStored());
}
-TEST_P(ParameterizedNGOffsetMappingTest, NGInlineFormattingContextOf) {
+TEST_F(NGOffsetMappingTest, NGInlineFormattingContextOf) {
SetBodyInnerHTML(
"<div id=container>"
" foo"
@@ -156,7 +374,7 @@ TEST_P(ParameterizedNGOffsetMappingTest, NGInlineFormattingContextOf) {
NGInlineFormattingContextOf(Position(blah, 0)));
}
-TEST_P(ParameterizedNGOffsetMappingTest, OneTextNode) {
+TEST_F(NGOffsetMappingTest, OneTextNode) {
SetupHtml("t", "<div id=t>foo</div>");
const Node* foo_node = layout_object_->GetNode();
const NGOffsetMapping& result = GetOffsetMapping();
@@ -219,7 +437,7 @@ TEST_P(ParameterizedNGOffsetMappingTest, OneTextNode) {
EXPECT_TRUE(IsAfterNonCollapsedContent(Position(foo_node, 3)));
}
-TEST_P(ParameterizedNGOffsetMappingTest, TwoTextNodes) {
+TEST_F(NGOffsetMappingTest, TwoTextNodes) {
SetupHtml("t", "<div id=t>foo<span id=s>bar</span></div>");
const LayoutText* foo = ToLayoutText(layout_object_);
const LayoutText* bar = GetLayoutTextUnder("s");
@@ -287,7 +505,7 @@ TEST_P(ParameterizedNGOffsetMappingTest, TwoTextNodes) {
EXPECT_TRUE(IsAfterNonCollapsedContent(Position(bar_node, 3)));
}
-TEST_P(ParameterizedNGOffsetMappingTest, BRBetweenTextNodes) {
+TEST_F(NGOffsetMappingTest, BRBetweenTextNodes) {
SetupHtml("t", u"<div id=t>foo<br>bar</div>");
const LayoutText* foo = ToLayoutText(layout_object_);
const LayoutText* br = ToLayoutText(foo->NextSibling());
@@ -342,7 +560,7 @@ TEST_P(ParameterizedNGOffsetMappingTest, BRBetweenTextNodes) {
EXPECT_EQ(Position(bar_node, 0), GetLastPosition(4));
}
-TEST_P(ParameterizedNGOffsetMappingTest, OneTextNodeWithCollapsedSpace) {
+TEST_F(NGOffsetMappingTest, OneTextNodeWithCollapsedSpace) {
SetupHtml("t", "<div id=t>foo bar</div>");
const Node* node = layout_object_->GetNode();
const NGOffsetMapping& result = GetOffsetMapping();
@@ -415,7 +633,7 @@ TEST_P(ParameterizedNGOffsetMappingTest, OneTextNodeWithCollapsedSpace) {
EXPECT_TRUE(IsAfterNonCollapsedContent(Position(node, 8)));
}
-TEST_P(ParameterizedNGOffsetMappingTest, FullyCollapsedWhiteSpaceNode) {
+TEST_F(NGOffsetMappingTest, FullyCollapsedWhiteSpaceNode) {
SetupHtml("t",
"<div id=t>"
"<span id=s1>foo </span>"
@@ -481,7 +699,7 @@ TEST_P(ParameterizedNGOffsetMappingTest, FullyCollapsedWhiteSpaceNode) {
StartOfNextNonCollapsedContent(Position(space_node, 0u)).IsNull());
}
-TEST_P(ParameterizedNGOffsetMappingTest, ReplacedElement) {
+TEST_F(NGOffsetMappingTest, ReplacedElement) {
SetupHtml("t", "<div id=t>foo <img> bar</div>");
const LayoutText* foo = ToLayoutText(layout_object_);
const LayoutObject* img = foo->NextSibling();
@@ -538,7 +756,7 @@ TEST_P(ParameterizedNGOffsetMappingTest, ReplacedElement) {
EXPECT_EQ(Position(bar_node, 0), GetLastPosition(5));
}
-TEST_P(ParameterizedNGOffsetMappingTest, FirstLetter) {
+TEST_F(NGOffsetMappingTest, FirstLetter) {
SetupHtml("t",
"<style>div:first-letter{color:red}</style>"
"<div id=t>foo</div>");
@@ -568,7 +786,7 @@ TEST_P(ParameterizedNGOffsetMappingTest, FirstLetter) {
EXPECT_EQ(Position(foo_node, 1), GetLastPosition(1));
}
-TEST_P(ParameterizedNGOffsetMappingTest, FirstLetterWithLeadingSpace) {
+TEST_F(NGOffsetMappingTest, FirstLetterWithLeadingSpace) {
SetupHtml("t",
"<style>div:first-letter{color:red}</style>"
"<div id=t> foo</div>");
@@ -604,7 +822,7 @@ TEST_P(ParameterizedNGOffsetMappingTest, FirstLetterWithLeadingSpace) {
EXPECT_EQ(Position(foo_node, 2), GetLastPosition(0));
}
-TEST_P(ParameterizedNGOffsetMappingTest, FirstLetterWithoutRemainingText) {
+TEST_F(NGOffsetMappingTest, FirstLetterWithoutRemainingText) {
SetupHtml("t",
"<style>div:first-letter{color:red}</style>"
"<div id=t> f</div>");
@@ -635,7 +853,7 @@ TEST_P(ParameterizedNGOffsetMappingTest, FirstLetterWithoutRemainingText) {
EXPECT_EQ(Position(text_node, 2), GetLastPosition(0));
}
-TEST_P(ParameterizedNGOffsetMappingTest, FirstLetterInDifferentBlock) {
+TEST_F(NGOffsetMappingTest, FirstLetterInDifferentBlock) {
SetupHtml("t",
"<style>:first-letter{float:right}</style><div id=t>foo</div>");
Element* div = GetDocument().getElementById("t");
@@ -699,7 +917,7 @@ TEST_P(ParameterizedNGOffsetMappingTest, FirstLetterInDifferentBlock) {
EXPECT_EQ(Position(text_node, 1), remaining_text_result.GetLastPosition(1));
}
-TEST_P(ParameterizedNGOffsetMappingTest, WhiteSpaceTextNodeWithoutLayoutText) {
+TEST_F(NGOffsetMappingTest, WhiteSpaceTextNodeWithoutLayoutText) {
SetupHtml("t", "<div id=t> <span>foo</span></div>");
Element* div = GetDocument().getElementById("t");
const Node* text_node = div->firstChild();
@@ -708,8 +926,7 @@ TEST_P(ParameterizedNGOffsetMappingTest, WhiteSpaceTextNodeWithoutLayoutText) {
EXPECT_TRUE(StartOfNextNonCollapsedContent(Position(text_node, 0u)).IsNull());
}
-TEST_P(ParameterizedNGOffsetMappingTest,
- OneContainerWithLeadingAndTrailingSpaces) {
+TEST_F(NGOffsetMappingTest, OneContainerWithLeadingAndTrailingSpaces) {
SetupHtml("t", "<div id=t><span id=s> foo </span></div>");
const Node* span = GetElementById("s");
const Node* text = span->firstChild();
@@ -733,7 +950,7 @@ TEST_P(ParameterizedNGOffsetMappingTest,
EXPECT_EQ(3u, *GetTextContentOffset(Position::AfterNode(*span)));
}
-TEST_P(ParameterizedNGOffsetMappingTest, ContainerWithGeneratedContent) {
+TEST_F(NGOffsetMappingTest, ContainerWithGeneratedContent) {
SetupHtml("t",
"<style>#s::before{content:'bar'} #s::after{content:'baz'}</style>"
"<div id=t><span id=s>foo</span></div>");
@@ -755,7 +972,7 @@ TEST_P(ParameterizedNGOffsetMappingTest, ContainerWithGeneratedContent) {
EXPECT_EQ(6u, *GetTextContentOffset(Position::AfterNode(*span)));
}
-TEST_P(ParameterizedNGOffsetMappingTest, Table) {
+TEST_F(NGOffsetMappingTest, Table) {
SetupHtml("t", "<table><tr><td id=t> foo </td></tr></table>");
const Node* foo_node = layout_object_->GetNode();
@@ -775,7 +992,7 @@ TEST_P(ParameterizedNGOffsetMappingTest, Table) {
TEST_RANGE(result.GetRanges(), foo_node, 0u, 3u);
}
-TEST_P(ParameterizedNGOffsetMappingTest, GetMappingForInlineBlock) {
+TEST_F(NGOffsetMappingTest, GetMappingForInlineBlock) {
SetupHtml("t",
"<div id=t>foo"
"<span style='display: inline-block' id=span> bar </span>"
@@ -803,7 +1020,7 @@ TEST_P(ParameterizedNGOffsetMappingTest, GetMappingForInlineBlock) {
EXPECT_NE(span_mapping, span_after_mapping);
}
-TEST_P(ParameterizedNGOffsetMappingTest, NoWrapSpaceAndCollapsibleSpace) {
+TEST_F(NGOffsetMappingTest, NoWrapSpaceAndCollapsibleSpace) {
SetupHtml("t",
"<div id=t>"
"<span style='white-space: nowrap' id=span>foo </span>"
@@ -828,7 +1045,7 @@ TEST_P(ParameterizedNGOffsetMappingTest, NoWrapSpaceAndCollapsibleSpace) {
4u, 5u, 8u);
}
-TEST_P(ParameterizedNGOffsetMappingTest, BiDiAroundForcedBreakInPreLine) {
+TEST_F(NGOffsetMappingTest, BiDiAroundForcedBreakInPreLine) {
SetupHtml("t",
"<div id=t style='white-space: pre-line'>"
"<bdo dir=rtl id=bdo>foo\nbar</bdo></div>");
@@ -852,7 +1069,7 @@ TEST_P(ParameterizedNGOffsetMappingTest, BiDiAroundForcedBreakInPreLine) {
TEST_RANGE(mapping.GetRanges(), text, 0u, 3u);
}
-TEST_P(ParameterizedNGOffsetMappingTest, BiDiAroundForcedBreakInPreWrap) {
+TEST_F(NGOffsetMappingTest, BiDiAroundForcedBreakInPreWrap) {
SetupHtml("t",
"<div id=t style='white-space: pre-wrap'>"
"<bdo dir=rtl id=bdo>foo\nbar</bdo></div>");
@@ -876,7 +1093,7 @@ TEST_P(ParameterizedNGOffsetMappingTest, BiDiAroundForcedBreakInPreWrap) {
TEST_RANGE(mapping.GetRanges(), text, 0u, 3u);
}
-TEST_P(ParameterizedNGOffsetMappingTest, BiDiAroundForcedBreakInPre) {
+TEST_F(NGOffsetMappingTest, BiDiAroundForcedBreakInPre) {
SetupHtml("t",
"<div id=t style='white-space: pre'>"
"<bdo dir=rtl id=bdo>foo\nbar</bdo></div>");
@@ -900,7 +1117,7 @@ TEST_P(ParameterizedNGOffsetMappingTest, BiDiAroundForcedBreakInPre) {
TEST_RANGE(mapping.GetRanges(), text, 0u, 3u);
}
-TEST_P(ParameterizedNGOffsetMappingTest, SoftHyphen) {
+TEST_F(NGOffsetMappingTest, SoftHyphen) {
LoadAhem();
SetupHtml(
"t",
@@ -916,7 +1133,7 @@ TEST_P(ParameterizedNGOffsetMappingTest, SoftHyphen) {
TEST_RANGE(mapping.GetRanges(), text, 0u, 1u);
}
-TEST_P(ParameterizedNGOffsetMappingTest, TextOverflowEllipsis) {
+TEST_F(NGOffsetMappingTest, TextOverflowEllipsis) {
LoadAhem();
SetupHtml("t",
"<div id=t style='font: 10px/10px Ahem; width: 30px; overflow: "
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 3187df368dd..e4b997558af 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
@@ -14,7 +14,7 @@ NGPhysicalLineBoxFragment::NGPhysicalLineBoxFragment(
const ComputedStyle& style,
NGStyleVariant style_variant,
NGPhysicalSize size,
- Vector<scoped_refptr<NGPhysicalFragment>>& children,
+ Vector<NGLink>& children,
const NGPhysicalOffsetRect& contents_ink_overflow,
const NGLineHeightMetrics& metrics,
TextDirection base_direction,
@@ -52,7 +52,7 @@ NGPhysicalOffsetRect NGPhysicalLineBoxFragment::ScrollableOverflow(
NGPhysicalOffsetRect overflow({}, Size());
for (const auto& child : Children()) {
NGPhysicalOffsetRect child_scroll_overflow = child->ScrollableOverflow();
- child_scroll_overflow.offset += child->Offset();
+ child_scroll_overflow.offset += child.Offset();
// If child has the same style as parent, parent will compute relative
// offset.
if (&child->Style() != container_style) {
@@ -72,7 +72,7 @@ const NGPhysicalFragment* NGPhysicalLineBoxFragment::FirstLogicalLeaf() const {
// should compute and store it during layout.
const TextDirection direction = Style().Direction();
const NGPhysicalFragment* runner = this;
- while (runner->IsContainer() && !runner->IsBlockLayoutRoot()) {
+ while (runner->IsContainer() && !runner->IsBlockFormattingContextRoot()) {
const NGPhysicalContainerFragment* runner_as_container =
ToNGPhysicalContainerFragment(runner);
if (runner_as_container->Children().IsEmpty())
@@ -92,7 +92,7 @@ const NGPhysicalFragment* NGPhysicalLineBoxFragment::LastLogicalLeaf() const {
// should compute and store it during layout.
const TextDirection direction = Style().Direction();
const NGPhysicalFragment* runner = this;
- while (runner->IsContainer() && !runner->IsBlockLayoutRoot()) {
+ while (runner->IsContainer() && !runner->IsBlockFormattingContextRoot()) {
const NGPhysicalContainerFragment* runner_as_container =
ToNGPhysicalContainerFragment(runner);
if (runner_as_container->Children().IsEmpty())
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 7ca454dcb6b..a8730288743 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
@@ -19,7 +19,7 @@ class CORE_EXPORT NGPhysicalLineBoxFragment final
NGPhysicalLineBoxFragment(const ComputedStyle&,
NGStyleVariant style_variant,
NGPhysicalSize size,
- Vector<scoped_refptr<NGPhysicalFragment>>& children,
+ Vector<NGLink>& children,
const NGPhysicalOffsetRect& contents_ink_overflow,
const NGLineHeightMetrics&,
TextDirection base_direction,
@@ -56,13 +56,6 @@ class CORE_EXPORT NGPhysicalLineBoxFragment final
// Whether the content soft-wraps to the next line.
bool HasSoftWrapToNextLine() const;
- scoped_refptr<NGPhysicalFragment> CloneWithoutOffset() const {
- Vector<scoped_refptr<NGPhysicalFragment>> children_copy(children_);
- return base::AdoptRef(new NGPhysicalLineBoxFragment(
- Style(), StyleVariant(), size_, children_copy, contents_ink_overflow_,
- metrics_, BaseDirection(), break_token_));
- }
-
private:
NGLineHeightMetrics metrics_;
};
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 7c705969eb7..22ada853289 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
@@ -7,12 +7,55 @@
#include "third_party/blink/renderer/core/dom/node.h"
#include "third_party/blink/renderer/core/layout/layout_text_fragment.h"
#include "third_party/blink/renderer/core/layout/line/line_orientation_utils.h"
+#include "third_party/blink/renderer/core/layout/ng/geometry/ng_logical_size.h"
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_physical_offset_rect.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
namespace blink {
+namespace {
+
+inline bool IsPhysicalTextFragmentAnonymousText(
+ const LayoutObject* layout_object) {
+ if (!layout_object)
+ return false;
+ if (layout_object->IsText() && ToLayoutText(layout_object)->IsTextFragment())
+ return !ToLayoutTextFragment(layout_object)->AssociatedTextNode();
+ const Node* node = layout_object->GetNode();
+ return !node || node->IsPseudoElement();
+}
+
+} // anonymous namespace
+
+NGPhysicalTextFragment::NGPhysicalTextFragment(
+ LayoutObject* layout_object,
+ const ComputedStyle& style,
+ NGStyleVariant style_variant,
+ NGTextType text_type,
+ const String& text,
+ unsigned start_offset,
+ unsigned end_offset,
+ NGPhysicalSize size,
+ NGLineOrientation line_orientation,
+ NGTextEndEffect end_effect,
+ scoped_refptr<const ShapeResult> shape_result)
+ : NGPhysicalFragment(layout_object,
+ style,
+ style_variant,
+ size,
+ kFragmentText,
+ text_type),
+ text_(text),
+ start_offset_(start_offset),
+ end_offset_(end_offset),
+ shape_result_(shape_result),
+ line_orientation_(static_cast<unsigned>(line_orientation)),
+ end_effect_(static_cast<unsigned>(end_effect)),
+ is_anonymous_text_(IsPhysicalTextFragmentAnonymousText(layout_object)) {
+ DCHECK(shape_result_ || IsFlowControl()) << ToString();
+}
+
// Convert logical cooridnate to local physical coordinate.
NGPhysicalOffsetRect NGPhysicalTextFragment::ConvertToLocal(
const LayoutRect& logical_rect) const {
@@ -41,7 +84,8 @@ LayoutUnit NGPhysicalTextFragment::InlinePositionForOffset(
offset -= start_offset_;
if (shape_result_) {
- return round(shape_result_->PositionForOffset(offset, adjust_mid_cluster));
+ return round(shape_result_->CaretPositionForOffset(offset, Text(),
+ adjust_mid_cluster));
}
// This fragment is a flow control because otherwise ShapeResult exists.
@@ -149,7 +193,7 @@ NGPhysicalOffsetRect NGPhysicalTextFragment::SelfInkOverflow() const {
return local_ink_overflow;
}
-scoped_refptr<NGPhysicalFragment> NGPhysicalTextFragment::TrimText(
+scoped_refptr<const NGPhysicalFragment> NGPhysicalTextFragment::TrimText(
unsigned new_start_offset,
unsigned new_end_offset) const {
DCHECK(shape_result_);
@@ -167,35 +211,33 @@ scoped_refptr<NGPhysicalFragment> NGPhysicalTextFragment::TrimText(
LineOrientation(), EndEffect(), std::move(new_shape_result)));
}
-scoped_refptr<NGPhysicalFragment> NGPhysicalTextFragment::CloneWithoutOffset()
- const {
- return base::AdoptRef(new NGPhysicalTextFragment(
- layout_object_, Style(), static_cast<NGStyleVariant>(style_variant_),
- TextType(), text_, start_offset_, end_offset_, size_, LineOrientation(),
- EndEffect(), shape_result_));
-}
-
-bool NGPhysicalTextFragment::IsAnonymousText() const {
- // TODO(xiaochengh): Introduce and set a flag for anonymous text.
- const LayoutObject* layout_object = GetLayoutObject();
- if (layout_object && layout_object->IsText() &&
- ToLayoutText(layout_object)->IsTextFragment())
- return !ToLayoutTextFragment(layout_object)->AssociatedTextNode();
- const Node* node = GetNode();
- return !node || node->IsPseudoElement();
-}
-
unsigned NGPhysicalTextFragment::TextOffsetForPoint(
const NGPhysicalOffset& point) const {
- if (IsLineBreak())
- return StartOffset();
- DCHECK(TextShapeResult());
+ const ComputedStyle& style = Style();
const LayoutUnit& point_in_line_direction =
- Style().IsHorizontalWritingMode() ? point.left : point.top;
- return TextShapeResult()->OffsetForPosition(point_in_line_direction.ToFloat(),
- IncludePartialGlyphs,
- BreakGlyphs) +
- StartOffset();
+ style.IsHorizontalWritingMode() ? point.left : point.top;
+ if (const ShapeResult* shape_result = TextShapeResult()) {
+ return shape_result->CaretOffsetForHitTest(
+ point_in_line_direction.ToFloat(), Text(), BreakGlyphs) +
+ StartOffset();
+ }
+
+ // Flow control fragments such as forced line break, tabulation, soft-wrap
+ // opportunities, etc. do not have ShapeResult.
+ DCHECK(IsFlowControl());
+
+ // Zero-inline-size objects such as newline always return the start offset.
+ NGLogicalSize size = Size().ConvertToLogical(style.GetWritingMode());
+ if (!size.inline_size)
+ return StartOffset();
+
+ // Sized objects such as tabulation returns the next offset if the given point
+ // is on the right half.
+ LayoutUnit inline_offset = IsLtr(ResolvedDirection())
+ ? point_in_line_direction
+ : size.inline_size - point_in_line_direction;
+ DCHECK_EQ(1u, Length());
+ return inline_offset <= size.inline_size / 2 ? StartOffset() : EndOffset();
}
UBiDiLevel NGPhysicalTextFragment::BidiLevel() const {
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 19758ce7666..fa31c5788ce 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
@@ -67,21 +67,7 @@ class CORE_EXPORT NGPhysicalTextFragment final : public NGPhysicalFragment {
NGPhysicalSize size,
NGLineOrientation line_orientation,
NGTextEndEffect end_effect,
- scoped_refptr<const ShapeResult> shape_result)
- : NGPhysicalFragment(layout_object,
- style,
- style_variant,
- size,
- kFragmentText,
- text_type),
- text_(text),
- start_offset_(start_offset),
- end_offset_(end_offset),
- shape_result_(shape_result),
- line_orientation_(static_cast<unsigned>(line_orientation)),
- end_effect_(static_cast<unsigned>(end_effect)) {
- DCHECK(shape_result_ || IsFlowControl()) << ToString();
- }
+ scoped_refptr<const ShapeResult> shape_result);
NGTextType TextType() const { return static_cast<NGTextType>(sub_type_); }
// True if this is a generated text.
@@ -96,6 +82,7 @@ class CORE_EXPORT NGPhysicalTextFragment final : public NGPhysicalFragment {
unsigned Length() const { return end_offset_ - start_offset_; }
StringView Text() const { return StringView(text_, start_offset_, Length()); }
+ const String& TextContent() const { return text_; }
// ShapeResult may be nullptr if |IsFlowControl()|.
const ShapeResult* TextShapeResult() const { return shape_result_.get(); }
@@ -131,10 +118,10 @@ class CORE_EXPORT NGPhysicalTextFragment final : public NGPhysicalFragment {
// Create a new fragment that has part of the text of this fragment.
// All other properties are the same as this fragment.
- scoped_refptr<NGPhysicalFragment> TrimText(unsigned start_offset,
- unsigned end_offset) const;
+ scoped_refptr<const NGPhysicalFragment> TrimText(unsigned start_offset,
+ unsigned end_offset) const;
- scoped_refptr<NGPhysicalFragment> CloneWithoutOffset() const;
+ scoped_refptr<const NGPhysicalFragment> CloneWithoutOffset() const;
NGTextFragmentPaintInfo PaintInfo() const {
return NGTextFragmentPaintInfo{text_, StartOffset(), EndOffset(),
@@ -143,7 +130,7 @@ class CORE_EXPORT NGPhysicalTextFragment final : public NGPhysicalFragment {
// Returns true if the text is generated (from, e.g., list marker,
// pseudo-element, ...) instead of from a DOM text node.
- bool IsAnonymousText() const;
+ bool IsAnonymousText() const { return is_anonymous_text_; }
// Returns the text offset in the fragment placed closest to the given point.
unsigned TextOffsetForPoint(const NGPhysicalOffset&) const;
@@ -170,13 +157,14 @@ class CORE_EXPORT NGPhysicalTextFragment final : public NGPhysicalFragment {
const String text_;
// Start and end offset of the parent block text.
- unsigned start_offset_;
- unsigned end_offset_;
+ const unsigned start_offset_;
+ const unsigned end_offset_;
- scoped_refptr<const ShapeResult> shape_result_;
+ const scoped_refptr<const ShapeResult> shape_result_;
- unsigned line_orientation_ : 2; // NGLineOrientation
- unsigned end_effect_ : 1; // NGTextEndEffect
+ const unsigned line_orientation_ : 2; // NGLineOrientation
+ const unsigned end_effect_ : 1; // NGTextEndEffect
+ const unsigned is_anonymous_text_ : 1;
};
DEFINE_TYPE_CASTS(NGPhysicalTextFragment,
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 8962d687d27..4419bfca2e6 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
@@ -245,4 +245,48 @@ TEST_F(NGPhysicalTextFragmentTest, QuotationMarksAreAnonymousText) {
EXPECT_TRUE(closed_quote.IsAnonymousText());
}
+TEST_F(NGPhysicalTextFragmentTest, TextOffsetForPointForTabulation) {
+ LoadAhem();
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #container {
+ white-space: pre;
+ font-family: Ahem;
+ font-size: 10px;
+ tab-size: 8;
+ }
+ </style>
+ <div id="container">&#09;</div>
+ )HTML");
+ auto text_fragments = CollectTextFragmentsInContainer("container");
+ ASSERT_EQ(1u, text_fragments.size());
+ const NGPhysicalTextFragment& text = *text_fragments[0];
+ EXPECT_EQ(0u, text.TextOffsetForPoint({LayoutUnit(), LayoutUnit()}));
+ EXPECT_EQ(0u, text.TextOffsetForPoint({LayoutUnit(39), LayoutUnit()}));
+ EXPECT_EQ(1u, text.TextOffsetForPoint({LayoutUnit(41), LayoutUnit()}));
+ EXPECT_EQ(1u, text.TextOffsetForPoint({LayoutUnit(80), LayoutUnit()}));
+}
+
+TEST_F(NGPhysicalTextFragmentTest, TextOffsetForPointForTabulationRtl) {
+ LoadAhem();
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #container {
+ white-space: pre;
+ font-family: Ahem;
+ font-size: 10px;
+ tab-size: 8;
+ }
+ </style>
+ <div id="container" dir="rtl">&#09;</div>
+ )HTML");
+ auto text_fragments = CollectTextFragmentsInContainer("container");
+ ASSERT_EQ(1u, text_fragments.size());
+ const NGPhysicalTextFragment& text = *text_fragments[0];
+ EXPECT_EQ(1u, text.TextOffsetForPoint({LayoutUnit(), LayoutUnit()}));
+ EXPECT_EQ(1u, text.TextOffsetForPoint({LayoutUnit(39), LayoutUnit()}));
+ EXPECT_EQ(0u, text.TextOffsetForPoint({LayoutUnit(41), LayoutUnit()}));
+ EXPECT_EQ(0u, text.TextOffsetForPoint({LayoutUnit(80), LayoutUnit()}));
+}
+
} // namespace blink
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 c1cbefd220e..64a42f1a618 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
@@ -81,8 +81,9 @@ void NGTextFragmentBuilder::SetText(
end_effect_ = NGTextEndEffect::kNone;
}
-scoped_refptr<NGPhysicalTextFragment> NGTextFragmentBuilder::ToTextFragment() {
- scoped_refptr<NGPhysicalTextFragment> fragment =
+scoped_refptr<const NGPhysicalTextFragment>
+NGTextFragmentBuilder::ToTextFragment() {
+ scoped_refptr<const NGPhysicalTextFragment> fragment =
base::AdoptRef(new NGPhysicalTextFragment(
layout_object_, Style(), style_variant_, text_type_, text_,
start_offset_, end_offset_, size_.ConvertToPhysical(GetWritingMode()),
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 df788efc4cb..2621674b787 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
@@ -38,7 +38,7 @@ class CORE_EXPORT NGTextFragmentBuilder final : public NGBaseFragmentBuilder {
scoped_refptr<const ShapeResult>);
// Creates the fragment. Can only be called once.
- scoped_refptr<NGPhysicalTextFragment> ToTextFragment();
+ scoped_refptr<const NGPhysicalTextFragment> ToTextFragment();
private:
NGInlineNode inline_node_;
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow.cc b/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow.cc
index 6100ce6b12f..7319e68c7e7 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow.cc
@@ -37,19 +37,11 @@ void LayoutNGBlockFlow::ComputeIntrinsicLogicalWidths(
max_logical_width);
return;
}
- MinMaxSize sizes =
- node.ComputeMinMaxSize(StyleRef().GetWritingMode(), MinMaxSizeInput());
- // ComputeMinMaxSize returns a border-box size. This function needs to return
- // content-box plus scrollbar.
- // We can't just call BorderAndPaddingLogicalWidth() here because that
- // handles percentages differently from NG intrinsic sizing.
- scoped_refptr<NGConstraintSpace> space =
- NGConstraintSpaceBuilder(node.Style().GetWritingMode(),
- node.InitialContainingBlockSize())
- .ToConstraintSpace(node.Style().GetWritingMode());
- sizes -=
- (ComputeBorders(*space, StyleRef()) + ComputePadding(*space, StyleRef()))
- .InlineSum();
+ MinMaxSizeInput input;
+ // This function returns content-box plus scrollbar.
+ input.size_type = NGMinMaxSizeType::kContentBoxSize;
+ MinMaxSize sizes = node.ComputeMinMaxSize(StyleRef().GetWritingMode(), input);
+ sizes += LayoutUnit(ScrollbarLogicalWidth());
min_logical_width = sizes.min_size;
max_logical_width = sizes.max_size;
}
@@ -77,7 +69,7 @@ void LayoutNGBlockFlow::UpdateBlockLayout(bool relayout_children) {
result->OutOfFlowPositionedDescendants())
descendant.node.UseOldOutOfFlowPositioning();
- NGPhysicalBoxFragment* fragment =
+ const NGPhysicalBoxFragment* fragment =
ToNGPhysicalBoxFragment(result->PhysicalFragment().get());
// This object has already been positioned in legacy layout by our containing
@@ -102,7 +94,7 @@ void LayoutNGBlockFlow::UpdateBlockLayout(bool relayout_children) {
constraint_space->GetWritingMode(), constraint_space->Direction(),
containing_block_size, fragment->Size());
}
- fragment->SetOffset(physical_offset);
+ result->SetOffset(physical_offset);
}
void LayoutNGBlockFlow::UpdateOutOfFlowBlockLayout() {
@@ -149,6 +141,8 @@ void LayoutNGBlockFlow::UpdateOutOfFlowBlockLayout() {
container_builder.SetInlineSize(container_border_box_logical_width);
container_builder.SetBlockSize(container_border_box_logical_height);
+ container_builder.SetBorders(
+ ComputeBorders(*constraint_space, *container_style));
container_builder.SetPadding(
ComputePadding(*constraint_space, *container_style));
@@ -231,18 +225,14 @@ void LayoutNGBlockFlow::UpdateOutOfFlowBlockLayout() {
NGBlockNode(this), static_position,
css_container->IsBox() ? nullptr : css_container);
- NGBoxStrut scrollbar_sizes;
- if (css_container->IsBox())
- scrollbar_sizes =
- NGBlockNode(ToLayoutBox(css_container)).GetScrollbarSizes();
// We really only want to lay out ourselves here, so we pass |this| to
// Run(). Otherwise, NGOutOfFlowLayoutPart may also lay out other objects
// it discovers that are part of the same containing block, but those
// should get laid out by the actual containing block.
- NGOutOfFlowLayoutPart(&container_builder,
- css_container->CanContainAbsolutePositionObjects(),
- css_container->CanContainFixedPositionObjects(),
- scrollbar_sizes, *constraint_space, *container_style)
+ NGOutOfFlowLayoutPart(
+ &container_builder, css_container->CanContainAbsolutePositionObjects(),
+ css_container->CanContainFixedPositionObjects(), borders_and_scrollbars,
+ *constraint_space, *container_style)
.Run(/* only_layout */ this);
scoped_refptr<NGLayoutResult> result = container_builder.ToBoxFragment();
// These are the unpositioned OOF descendants of the current OOF block.
@@ -250,19 +240,19 @@ void LayoutNGBlockFlow::UpdateOutOfFlowBlockLayout() {
result->OutOfFlowPositionedDescendants())
descendant.node.UseOldOutOfFlowPositioning();
- scoped_refptr<NGPhysicalBoxFragment> fragment =
+ scoped_refptr<const NGPhysicalBoxFragment> fragment =
ToNGPhysicalBoxFragment(result->PhysicalFragment().get());
DCHECK_GT(fragment->Children().size(), 0u);
// Copy sizes of all child fragments to Legacy.
// There could be multiple fragments, when this node has descendants whose
// container is this node's container.
// Example: fixed descendant of fixed element.
- for (scoped_refptr<NGPhysicalFragment> child_fragment :
- fragment->Children()) {
+ for (auto& child : fragment->Children()) {
+ const NGPhysicalFragment* child_fragment = child.get();
DCHECK(child_fragment->GetLayoutObject()->IsBox());
LayoutBox* child_legacy_box =
ToLayoutBox(child_fragment->GetLayoutObject());
- NGPhysicalOffset child_offset = child_fragment->Offset();
+ NGPhysicalOffset child_offset = child.Offset();
if (container_style->IsFlippedBlocksWritingMode()) {
child_legacy_box->SetX(container_border_box_logical_height -
child_offset.left - child_fragment->Size().width);
@@ -271,8 +261,8 @@ void LayoutNGBlockFlow::UpdateOutOfFlowBlockLayout() {
}
child_legacy_box->SetY(child_offset.top);
}
- scoped_refptr<NGPhysicalFragment> child_fragment = fragment->Children()[0];
DCHECK_EQ(fragment->Children()[0]->GetLayoutObject(), this);
+ SetIsLegacyInitiatedOutOfFlowLayout(true);
}
} // namespace blink
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 0d78f32b213..88f8f934006 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
@@ -32,7 +32,7 @@ void LayoutNGFlexibleBox::UpdateBlockLayout(bool relayout_children) {
result->OutOfFlowPositionedDescendants())
descendant.node.UseOldOutOfFlowPositioning();
- NGPhysicalBoxFragment* fragment =
+ const NGPhysicalBoxFragment* fragment =
ToNGPhysicalBoxFragment(result->PhysicalFragment().get());
// Pasted from layout_ng_block_flow. TODO(dgrogan): Factor a utility method.
@@ -46,7 +46,7 @@ void LayoutNGFlexibleBox::UpdateBlockLayout(bool relayout_children) {
constraint_space->GetWritingMode(), constraint_space->Direction(),
containing_block_size, fragment->Size());
}
- fragment->SetOffset(physical_offset);
+ result->SetOffset(physical_offset);
}
} // 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 6ff73e9c01f..45f1acd810d 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
@@ -18,6 +18,7 @@ class CORE_EXPORT LayoutNGFlexibleBox : public LayoutBlock {
void UpdateBlockLayout(bool relayout_children) override;
bool IsFlexibleBox() const final { return true; }
+ bool IsLayoutNGObject() const override { return true; }
const char* GetName() const override { return "LayoutNGFlexibleBox"; }
protected:
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 6351676134d..1c306008c41 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
@@ -20,8 +20,6 @@
#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_relative_utils.h"
-#include "third_party/blink/renderer/core/page/scrolling/root_scroller_util.h"
-#include "third_party/blink/renderer/core/paint/adjust_paint_offset_scope.h"
#include "third_party/blink/renderer/core/paint/ng/ng_block_flow_painter.h"
#include "third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h"
@@ -136,7 +134,7 @@ void LayoutNGMixin<Base>::AddScrollingOverflowFromChildren() {
} else {
continue;
}
- child_scrollable_overflow.offset += child->Offset();
+ child_scrollable_overflow.offset += child.Offset();
children_overflow.Unite(child_scrollable_overflow);
}
}
@@ -216,13 +214,15 @@ scoped_refptr<NGLayoutResult> LayoutNGMixin<Base>::CachedLayoutResult(
NGBreakToken* break_token) const {
if (!RuntimeEnabledFeatures::LayoutNGFragmentCachingEnabled())
return nullptr;
- if (!cached_result_ || break_token || Base::NeedsLayout())
+ if (!cached_result_ || !Base::cached_constraint_space_ || break_token ||
+ Base::NeedsLayout())
return nullptr;
- if (constraint_space != *cached_constraint_space_)
+ if (constraint_space != *Base::cached_constraint_space_)
return nullptr;
// The checks above should be enough to bail if layout is incomplete, but
// let's verify:
- DCHECK(IsBlockLayoutComplete(*cached_constraint_space_, *cached_result_));
+ DCHECK(
+ IsBlockLayoutComplete(*Base::cached_constraint_space_, *cached_result_));
// If we used to contain abspos items, we can't reuse the fragment, because
// we can't be sure that the list of items hasn't changed (as we bubble them
// up during layout). In the case of newly-added abspos items to this
@@ -235,11 +235,6 @@ scoped_refptr<NGLayoutResult> LayoutNGMixin<Base>::CachedLayoutResult(
}
template <typename Base>
-const NGConstraintSpace* LayoutNGMixin<Base>::CachedConstraintSpace() const {
- return cached_constraint_space_.get();
-}
-
-template <typename Base>
void LayoutNGMixin<Base>::SetCachedLayoutResult(
const NGConstraintSpace& constraint_space,
NGBreakToken* break_token,
@@ -251,7 +246,7 @@ void LayoutNGMixin<Base>::SetCachedLayoutResult(
if (constraint_space.IsIntermediateLayout())
return;
- cached_constraint_space_ = &constraint_space;
+ Base::cached_constraint_space_ = &constraint_space;
cached_result_ = layout_result;
}
@@ -263,17 +258,76 @@ LayoutNGMixin<Base>::CachedLayoutResultForTesting() {
template <typename Base>
void LayoutNGMixin<Base>::SetPaintFragment(
- scoped_refptr<const NGPhysicalFragment> fragment) {
- paint_fragment_ = NGPaintFragment::Create(std::move(fragment));
+ NGPaintFragment* last_paint_fragment,
+ scoped_refptr<NGPaintFragment> paint_fragment) {
+ if (paint_fragment) {
+ // When paint fragment is replaced, the subtree needs paint invalidation to
+ // re-compute paint properties in NGPaintFragment.
+ Base::SetSubtreeShouldDoFullPaintInvalidation();
+ }
- // When paint fragment is replaced, the subtree needs paint invalidation to
- // re-compute paint properties in NGPaintFragment.
- Base::SetShouldDoFullPaintInvalidation(PaintInvalidationReason::kSubtree);
+ if (last_paint_fragment) {
+ last_paint_fragment->SetNext(std::move(paint_fragment));
+ } else {
+ paint_fragment_ = std::move(paint_fragment);
+ }
}
template <typename Base>
-void LayoutNGMixin<Base>::ClearPaintFragment() {
- paint_fragment_ = nullptr;
+void LayoutNGMixin<Base>::SetPaintFragment(
+ const NGBreakToken* break_token,
+ scoped_refptr<const NGPhysicalFragment> fragment,
+ NGPhysicalOffset offset) {
+ // TODO(kojii): There are cases where the first call has break_token.
+ // Investigate why and handle appropriately.
+ // DCHECK(!break_token || paint_fragment_);
+ NGPaintFragment* last_paint_fragment = nullptr;
+ if (break_token && paint_fragment_) {
+ last_paint_fragment = paint_fragment_->Last(*break_token);
+ // TODO(kojii): Sometimes an unknown break_token is given. Need to
+ // investigate why, and handle appropriately. For now, just keep it to avoid
+ // crashes and use-after-free.
+ if (!last_paint_fragment)
+ last_paint_fragment = paint_fragment_->Last();
+ DCHECK(last_paint_fragment);
+ }
+ SetPaintFragment(
+ last_paint_fragment,
+ fragment ? NGPaintFragment::Create(fragment, offset) : nullptr);
+}
+
+template <typename Base>
+void LayoutNGMixin<Base>::UpdatePaintFragmentFromCachedLayoutResult(
+ const NGBreakToken* break_token,
+ scoped_refptr<const NGPhysicalFragment> fragment,
+ NGPhysicalOffset fragment_offset) {
+ DCHECK(fragment);
+ // TODO(kojii): There are cases where the first call has break_token.
+ // Investigate why and handle appropriately.
+ // DCHECK(!break_token || paint_fragment_);
+ NGPaintFragment* paint_fragment = nullptr;
+ NGPaintFragment* last_paint_fragment = nullptr;
+ if (!break_token) {
+ paint_fragment = paint_fragment_.get();
+ } else if (paint_fragment_) {
+ last_paint_fragment = paint_fragment_->Last(*break_token);
+ // TODO(kojii): Sometimes an unknown break_token is given. Need to
+ // investigate why, and handle appropriately. For now, just keep it to avoid
+ // crashes and use-after-free.
+ if (!last_paint_fragment)
+ last_paint_fragment = paint_fragment_->Last();
+ DCHECK(last_paint_fragment);
+ paint_fragment = last_paint_fragment->Next();
+ }
+
+ if (!paint_fragment) {
+ SetPaintFragment(
+ last_paint_fragment,
+ NGPaintFragment::Create(std::move(fragment), fragment_offset));
+ return;
+ }
+
+ paint_fragment->UpdatePhysicalFragmentFromCachedLayoutResult(fragment);
}
template <typename Base>
@@ -314,7 +368,7 @@ bool LayoutNGMixin<Base>::NodeAtPoint(
// LayoutBox in the paint layer, regardless of writing mode or whether the box
// was placed by NG or legacy.
const LayoutPoint physical_offset = accumulated_offset + Base::Location();
- if (!RootScrollerUtil::IsEffective(*this)) {
+ if (!this->IsEffectiveRootScroller()) {
// Check if we need to do anything at all.
// If we have clipping, then we can't have any spillout.
LayoutRect overflow_box = Base::HasOverflowClip()
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 4ffae304592..abc162b4d5e 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
@@ -20,6 +20,7 @@ class NGPaintFragment;
class NGPhysicalFragment;
struct NGBaseline;
struct NGInlineNodeData;
+struct NGPhysicalOffset;
// This mixin holds code shared between LayoutNG subclasses of
// LayoutBlockFlow.
@@ -30,6 +31,8 @@ class LayoutNGMixin : public Base {
explicit LayoutNGMixin(Element* element);
~LayoutNGMixin() override;
+ bool IsLayoutNGObject() const override { return true; }
+
NGInlineNodeData* TakeNGInlineNodeData() override;
NGInlineNodeData* GetNGInlineNodeData() const override;
void ResetNGInlineNodeData() override;
@@ -57,7 +60,6 @@ class LayoutNGMixin : public Base {
scoped_refptr<NGLayoutResult> CachedLayoutResult(
const NGConstraintSpace&,
NGBreakToken*) const override;
- const NGConstraintSpace* CachedConstraintSpace() const override;
void SetCachedLayoutResult(const NGConstraintSpace&,
NGBreakToken*,
@@ -68,8 +70,13 @@ class LayoutNGMixin : public Base {
NGPaintFragment* PaintFragment() const override {
return paint_fragment_.get();
}
- void SetPaintFragment(scoped_refptr<const NGPhysicalFragment>) override;
- void ClearPaintFragment() override;
+ void SetPaintFragment(const NGBreakToken*,
+ scoped_refptr<const NGPhysicalFragment>,
+ NGPhysicalOffset) final;
+ void UpdatePaintFragmentFromCachedLayoutResult(
+ const NGBreakToken*,
+ scoped_refptr<const NGPhysicalFragment>,
+ NGPhysicalOffset) final;
protected:
bool IsOfType(LayoutObject::LayoutObjectType) const override;
@@ -78,6 +85,8 @@ class LayoutNGMixin : public Base {
private:
void AddScrollingOverflowFromChildren();
+ void SetPaintFragment(NGPaintFragment* last_paint_fragment,
+ scoped_refptr<NGPaintFragment>);
protected:
void AddOutlineRects(
@@ -92,8 +101,7 @@ class LayoutNGMixin : public Base {
std::unique_ptr<NGInlineNodeData> ng_inline_node_data_;
scoped_refptr<NGLayoutResult> cached_result_;
- scoped_refptr<const NGConstraintSpace> cached_constraint_space_;
- std::unique_ptr<NGPaintFragment> paint_fragment_;
+ scoped_refptr<NGPaintFragment> paint_fragment_;
friend class NGBaseLayoutAlgorithmTest;
};
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 e9e3423485d..b8cb4e14c60 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
@@ -32,7 +32,7 @@ void LayoutNGTableCell::UpdateBlockLayout(bool relayout_children) {
result->OutOfFlowPositionedDescendants())
descendant.node.UseOldOutOfFlowPositioning();
- NGPhysicalBoxFragment* fragment =
+ const NGPhysicalBoxFragment* fragment =
ToNGPhysicalBoxFragment(result->PhysicalFragment().get());
const LayoutBox* section = LocationContainer();
@@ -46,7 +46,7 @@ void LayoutNGTableCell::UpdateBlockLayout(bool relayout_children) {
constraint_space->GetWritingMode(), constraint_space->Direction(),
section_size, fragment->Size());
}
- fragment->SetOffset(physical_offset);
+ result->SetOffset(physical_offset);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.cc b/chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.cc
index ae9625d9aa3..677d24963df 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
@@ -293,8 +293,8 @@ void LayoutNGListItem::UpdateMarkerContentIfNeeded() {
}
}
if (!child) {
- text = LayoutText::CreateEmptyAnonymous(GetDocument());
- text->SetStyle(marker_->MutableStyle());
+ text = LayoutText::CreateEmptyAnonymous(GetDocument(),
+ marker_->MutableStyle());
marker_->AddChild(text);
is_marker_text_updated_ = false;
}
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 a060bb11312..cb5c14d88f2 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
@@ -26,6 +26,7 @@ class CORE_EXPORT LayoutNGListItem final : public LayoutNGBlockFlow {
return StyleRef().ListStyleImage() &&
!StyleRef().ListStyleImage()->ErrorOccurred();
}
+ bool IsLayoutNGObject() const override { return true; }
void UpdateMarkerTextIfNeeded() {
if (marker_ && !is_marker_text_updated_ && !IsMarkerImage())
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_list_marker.h
index 469de1bebe9..c85d0a8e89d 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_list_marker.h
@@ -33,6 +33,8 @@ class CORE_EXPORT LayoutNGListMarker final
bool IsContentImage() const;
+ bool IsLayoutNGObject() const override { return true; }
+
LayoutObject* SymbolMarkerLayoutText() const;
// Marker text with suffix, e.g. "1. ", for use in accessibility.
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 8d38ae23317..44af6cbbb50 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
@@ -17,6 +17,8 @@ class CORE_EXPORT LayoutNGListMarkerImage final : public LayoutImage {
explicit LayoutNGListMarkerImage(Element*);
static LayoutNGListMarkerImage* CreateAnonymous(Document*);
+ bool IsLayoutNGObject() const override { return true; }
+
private:
bool IsOfType(LayoutObjectType) const override;
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 876df626a78..92a8543b03c 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
@@ -75,7 +75,7 @@ bool NGUnpositionedListMarker::AddToBox(
content_metrics = line_box.Metrics();
} else {
- NGBoxFragment content_fragment(space.GetWritingMode(),
+ NGBoxFragment content_fragment(space.GetWritingMode(), space.Direction(),
ToNGPhysicalBoxFragment(content));
content_metrics = content_fragment.BaselineMetricsWithoutSynthesize(
{NGBaselineAlgorithmType::kFirstLine, baseline_type});
@@ -95,7 +95,7 @@ bool NGUnpositionedListMarker::AddToBox(
ToNGPhysicalBoxFragment(*marker_layout_result->PhysicalFragment());
// Compute the inline offset of the marker.
- NGBoxFragment marker_fragment(space.GetWritingMode(),
+ NGBoxFragment marker_fragment(space.GetWritingMode(), space.Direction(),
marker_physical_fragment);
NGLogicalOffset marker_offset(
InlineOffset(marker_fragment.Size().inline_size),
@@ -156,10 +156,10 @@ LayoutUnit NGUnpositionedListMarker::ComputeIntrudedFloatOffset(
// Because opportunity.rect is in the content area of LI, so origin_offset
// should plus border_scrollbar_padding.inline_start, and available_size
// should minus border_scrollbar_padding.
- NGBfcOffset bfc_offset = container_builder->BfcOffset().value();
NGBfcOffset origin_offset = {
- bfc_offset.line_offset + border_scrollbar_padding.inline_start,
- bfc_offset.block_offset + marker_block_offset};
+ container_builder->BfcLineOffset() +
+ border_scrollbar_padding.inline_start,
+ container_builder->BfcBlockOffset().value() + marker_block_offset};
LayoutUnit available_size = container_builder->InlineSize() -
border_scrollbar_padding.inline_start -
border_scrollbar_padding.inline_end;
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 95365fa5ad5..49fbfe4f653 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
@@ -28,7 +28,7 @@ void NGBaseLayoutAlgorithmTest::AdvanceToLayoutPhase() {
GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kInPerformLayout);
}
-std::pair<scoped_refptr<NGPhysicalBoxFragment>,
+std::pair<scoped_refptr<const NGPhysicalBoxFragment>,
scoped_refptr<NGConstraintSpace>>
NGBaseLayoutAlgorithmTest::RunBlockLayoutAlgorithmForElement(Element* element) {
LayoutBlockFlow* block_flow = ToLayoutBlockFlow(element->GetLayoutObject());
@@ -58,7 +58,8 @@ const NGPhysicalBoxFragment* NGBaseLayoutAlgorithmTest::CurrentFragmentFor(
return block_flow->CurrentFragment();
}
-const NGPhysicalBoxFragment* FragmentChildIterator::NextChild() {
+const NGPhysicalBoxFragment* FragmentChildIterator::NextChild(
+ NGPhysicalOffset* fragment_offset) {
if (!parent_)
return nullptr;
if (index_ >= parent_->Children().size())
@@ -69,7 +70,10 @@ const NGPhysicalBoxFragment* FragmentChildIterator::NextChild() {
if (index_ >= parent_->Children().size())
return nullptr;
}
- return ToNGPhysicalBoxFragment(parent_->Children()[index_++].get());
+ auto& child = parent_->Children()[index_++];
+ if (fragment_offset)
+ *fragment_offset = child.Offset();
+ return ToNGPhysicalBoxFragment(child.get());
}
scoped_refptr<NGConstraintSpace> ConstructBlockLayoutTestConstraintSpace(
@@ -86,7 +90,7 @@ scoped_refptr<NGConstraintSpace> ConstructBlockLayoutTestConstraintSpace(
return NGConstraintSpaceBuilder(
writing_mode,
- /* icb_size */ size.ConvertToPhysical(writing_mode))
+ /* icb_size */ NGPhysicalSize(LayoutUnit(800), LayoutUnit(600)))
.SetAvailableSize(size)
.SetPercentageResolutionSize(size)
.SetTextDirection(direction)
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 9ee54bdbde8..e6811a1f344 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
@@ -32,7 +32,7 @@ class NGBaseLayoutAlgorithmTest
// RunBlockLayoutAlgorithmForElement.
void AdvanceToLayoutPhase();
- std::pair<scoped_refptr<NGPhysicalBoxFragment>,
+ std::pair<scoped_refptr<const NGPhysicalBoxFragment>,
scoped_refptr<NGConstraintSpace>>
RunBlockLayoutAlgorithmForElement(Element* element);
@@ -55,7 +55,8 @@ class FragmentChildIterator {
index_ = 0;
}
- const NGPhysicalBoxFragment* NextChild();
+ const NGPhysicalBoxFragment* NextChild(
+ NGPhysicalOffset* fragment_offset = nullptr);
private:
const NGPhysicalBoxFragment* parent_;
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_block_child_iterator.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_block_child_iterator.h
index 16d9404aa63..0b2bfd26002 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_block_child_iterator.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_block_child_iterator.h
@@ -47,6 +47,7 @@ class CORE_EXPORT NGBlockChildIterator {
struct NGBlockChildIterator::Entry {
STACK_ALLOCATED();
+ public:
Entry(NGLayoutInputNode node, NGBreakToken* token)
: node(node), token(token) {}
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 bd3d4fcdab5..0fe36c73788 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
@@ -12,7 +12,6 @@
#include "third_party/blink/renderer/core/layout/layout_object.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/list/layout_ng_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_child_iterator.h"
#include "third_party/blink/renderer/core/layout/ng/ng_constraint_space.h"
@@ -36,7 +35,7 @@ namespace {
// Return true if a child is to be cleared past adjoining floats. These are
// floats that would otherwise (if 'clear' were 'none') be pulled down by the
-// BFC offset of the child. If the child is to clear floats, though, we
+// BFC block offset of the child. If the child is to clear floats, though, we
// obviously need separate the child from the floats and move it past them,
// since that's what clearance is all about. This means that if we have any such
// floats to clear, we know for sure that we get clearance, even before layout.
@@ -85,7 +84,7 @@ bool IsEmptyBlock(const NGLayoutInputNode child,
if (child.CreatesNewFormattingContext())
return false;
- if (layout_result.BfcOffset())
+ if (layout_result.BfcBlockOffset())
return false;
#if DCHECK_IS_ON()
@@ -100,59 +99,35 @@ bool IsEmptyBlock(const NGLayoutInputNode child,
return true;
}
-NGLogicalOffset LogicalFromBfcOffsets(const NGFragment& fragment,
- const NGBfcOffset& child_bfc_offset,
- const NGBfcOffset& parent_bfc_offset,
- LayoutUnit parent_inline_size,
- TextDirection direction) {
+LayoutUnit LogicalFromBfcLineOffset(const NGFragment& fragment,
+ LayoutUnit child_bfc_line_offset,
+ LayoutUnit parent_bfc_line_offset,
+ LayoutUnit parent_inline_size,
+ TextDirection direction) {
// We need to respect the current text direction to calculate the logical
// offset correctly.
LayoutUnit relative_line_offset =
- child_bfc_offset.line_offset - parent_bfc_offset.line_offset;
+ child_bfc_line_offset - parent_bfc_line_offset;
LayoutUnit inline_offset =
direction == TextDirection::kLtr
? relative_line_offset
: parent_inline_size - relative_line_offset - fragment.InlineSize();
- return {inline_offset,
- child_bfc_offset.block_offset - parent_bfc_offset.block_offset};
+ return inline_offset;
}
-// Create a child constraint space with only extrinsic block sizing data. This
-// will and can not be used for final layout, but is needed in an intermediate
-// measure pass that calculates the min/max size contribution from a child that
-// establishes an orthogonal flow root.
-//
-// Note that it's the child's *block* size that will be propagated as min/max
-// inline size to the container. Therefore it's crucial to provide the child
-// with an available inline size (which can be derived from the block size of
-// the container if definite). We'll provide any extrinsic available block size
-// that we have. This includes fixed and resolvable percentage sizes, for
-// instance, while auto will not resolve. If no extrinsic size can be
-// determined, we will resort to using a fallback later on, such as the initial
-// containing block size. Spec:
-// https://www.w3.org/TR/css-writing-modes-3/#orthogonal-auto
-scoped_refptr<NGConstraintSpace> CreateExtrinsicConstraintSpace(
- const NGConstraintSpace& container_space,
- NGBlockNode container,
- NGBlockNode child) {
- LayoutUnit extrinsic_block_size = ComputeBlockSizeForFragment(
- container_space, container.Style(), NGSizeIndefinite);
- if (extrinsic_block_size != NGSizeIndefinite) {
- extrinsic_block_size -=
- CalculateBorderScrollbarPadding(container_space, container).BlockSum();
- extrinsic_block_size = std::max(extrinsic_block_size, LayoutUnit());
- }
- NGLogicalSize extrinsic_size(NGSizeIndefinite, extrinsic_block_size);
-
- return NGConstraintSpaceBuilder(container_space)
- .SetAvailableSize(extrinsic_size)
- .SetPercentageResolutionSize(extrinsic_size)
- .SetIsIntermediateLayout(true)
- .SetIsNewFormattingContext(child.CreatesNewFormattingContext())
- .SetFloatsBfcOffset(NGBfcOffset())
- .ToConstraintSpace(child.Style().GetWritingMode());
+NGLogicalOffset LogicalFromBfcOffsets(const NGFragment& fragment,
+ const NGBfcOffset& child_bfc_offset,
+ const NGBfcOffset& parent_bfc_offset,
+ LayoutUnit parent_inline_size,
+ TextDirection direction) {
+ LayoutUnit inline_offset = LogicalFromBfcLineOffset(
+ fragment, child_bfc_offset.line_offset, parent_bfc_offset.line_offset,
+ parent_inline_size, direction);
+
+ return {inline_offset,
+ child_bfc_offset.block_offset - parent_bfc_offset.block_offset};
}
// Stop margin collapsing on one side of a block when
@@ -189,6 +164,10 @@ NGBlockLayoutAlgorithm::NGBlockLayoutAlgorithm(NGBlockNode node,
// header.
NGBlockLayoutAlgorithm::~NGBlockLayoutAlgorithm() = default;
+void NGBlockLayoutAlgorithm::SetBoxType(NGPhysicalFragment::NGBoxType type) {
+ container_builder_.SetBoxType(type);
+}
+
base::Optional<MinMaxSize> NGBlockLayoutAlgorithm::ComputeMinMaxSize(
const MinMaxSizeInput& input) const {
MinMaxSize sizes;
@@ -201,6 +180,16 @@ base::Optional<MinMaxSize> NGBlockLayoutAlgorithm::ComputeMinMaxSize(
LayoutUnit float_left_inline_size = input.float_left_inline_size;
LayoutUnit float_right_inline_size = input.float_right_inline_size;
+ NGBoxStrut border_padding = ComputeBorders(ConstraintSpace(), Node()) +
+ ComputePadding(ConstraintSpace(), Node());
+ LayoutUnit extrinsic_block_size = ComputeBlockSizeForFragment(
+ ConstraintSpace(), Style(), NGSizeIndefinite, border_padding);
+ if (extrinsic_block_size != NGSizeIndefinite) {
+ extrinsic_block_size -=
+ (border_padding + Node().GetScrollbarSizes()).BlockSum();
+ extrinsic_block_size = extrinsic_block_size.ClampNegativeToZero();
+ }
+
for (NGLayoutInputNode child = Node().FirstChild(); child;
child = child.NextSibling()) {
if (child.IsOutOfFlowPositioned() || child.IsColumnSpanAll())
@@ -230,8 +219,10 @@ base::Optional<MinMaxSize> NGBlockLayoutAlgorithm::ComputeMinMaxSize(
}
MinMaxSizeInput child_input;
- if (child.IsInline() || child.IsAnonymousBlock())
- child_input = {float_left_inline_size, float_right_inline_size};
+ if (child.IsInline() || child.IsAnonymousBlock()) {
+ child_input = {float_left_inline_size, float_right_inline_size,
+ extrinsic_block_size};
+ }
MinMaxSize child_sizes;
if (child.IsInline()) {
@@ -240,18 +231,22 @@ base::Optional<MinMaxSize> NGBlockLayoutAlgorithm::ComputeMinMaxSize(
// all inline nodes following |child| and their descendants, and produces
// an anonymous box that contains all line boxes.
// |NextSibling| returns the next block sibling, or nullptr, skipping all
- // following inline siblings and descendants.
- child_sizes =
- child.ComputeMinMaxSize(Style().GetWritingMode(), child_input);
+ // following inline siblings and descendants. We'll pass our constraint
+ // space here, so that floated orthogonal flow roots can calculate an
+ // extrinsic constraint space.
+ child_sizes = child.ComputeMinMaxSize(Style().GetWritingMode(),
+ child_input, &constraint_space_);
} else {
// We'll need extrinsic sizing data when computing min/max for orthogonal
- // flow roots.
+ // flow roots. If the child is a block node, we can check that right away,
+ // but if it's inline, there's no way of telling; there may be floated
+ // children that establish an orthogonal flow root.
scoped_refptr<NGConstraintSpace> extrinsic_constraint_space;
const NGConstraintSpace* optional_constraint_space = nullptr;
if (!IsParallelWritingMode(Style().GetWritingMode(),
child.Style().GetWritingMode())) {
- extrinsic_constraint_space = CreateExtrinsicConstraintSpace(
- ConstraintSpace(), Node(), ToNGBlockNode(child));
+ extrinsic_constraint_space = CreateExtrinsicConstraintSpaceForChild(
+ ConstraintSpace(), extrinsic_block_size, child);
optional_constraint_space = extrinsic_constraint_space.get();
}
child_sizes = ComputeMinAndMaxContentContribution(
@@ -327,43 +322,46 @@ base::Optional<MinMaxSize> NGBlockLayoutAlgorithm::ComputeMinMaxSize(
DCHECK_GE(sizes.min_size, LayoutUnit());
DCHECK_LE(sizes.min_size, sizes.max_size) << Node().ToString();
- sizes +=
- CalculateBorderScrollbarPadding(ConstraintSpace(), node_).InlineSum();
+ if (input.size_type == NGMinMaxSizeType::kBorderBoxSize)
+ sizes += border_padding.InlineSum() + node_.GetScrollbarSizes().InlineSum();
return sizes;
}
NGLogicalOffset NGBlockLayoutAlgorithm::CalculateLogicalOffset(
- NGLayoutInputNode child,
const NGFragment& fragment,
- const NGBoxStrut& child_margins,
- const base::Optional<NGBfcOffset>& known_fragment_offset) {
- if (known_fragment_offset) {
+ LayoutUnit child_bfc_line_offset,
+ const base::Optional<LayoutUnit>& child_bfc_block_offset) {
+ LayoutUnit inline_size = container_builder_.Size().inline_size;
+ TextDirection direction = ConstraintSpace().Direction();
+
+ if (child_bfc_block_offset) {
return LogicalFromBfcOffsets(
- fragment, known_fragment_offset.value(), ContainerBfcOffset(),
- container_builder_.Size().inline_size, ConstraintSpace().Direction());
+ fragment, {child_bfc_line_offset, child_bfc_block_offset.value()},
+ ContainerBfcOffset(), inline_size, direction);
}
- LayoutUnit inline_offset =
- border_scrollbar_padding_.inline_start + child_margins.inline_start;
-
- if (child.IsInline()) {
- inline_offset +=
- InlineOffsetForTextAlign(Style(), child_available_size_.inline_size);
- }
+ LayoutUnit inline_offset = LogicalFromBfcLineOffset(
+ fragment, child_bfc_line_offset, container_builder_.BfcLineOffset(),
+ inline_size, direction);
// If we've reached here, both the child and the current layout don't have a
- // BFC offset yet. Children in this situation are always placed at a logical
- // block offset of 0.
- DCHECK(!container_builder_.BfcOffset());
+ // BFC block offset yet. Children in this situation are always placed at a
+ // logical block offset of 0.
+ DCHECK(!container_builder_.BfcBlockOffset());
return {inline_offset, LayoutUnit()};
}
scoped_refptr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() {
- border_scrollbar_padding_ =
- CalculateBorderScrollbarPadding(ConstraintSpace(), Node());
+ NGBoxStrut borders = ComputeBorders(ConstraintSpace(), Node());
+ NGBoxStrut padding = ComputePadding(ConstraintSpace(), Node());
+ border_padding_ = borders + padding;
+ NGBoxStrut scrollbars = Node().GetScrollbarSizes();
+ border_scrollbar_padding_ = ConstraintSpace().IsAnonymous()
+ ? NGBoxStrut()
+ : border_padding_ + scrollbars;
NGLogicalSize border_box_size = CalculateBorderBoxSize(
- ConstraintSpace(), Node(), CalculateDefaultBlockSize());
+ ConstraintSpace(), Node(), CalculateDefaultBlockSize(), border_padding_);
// Our calculated block-axis size may be indefinite at this point.
// If so, just leave the size as NGSizeIndefinite instead of subtracting
@@ -384,16 +382,18 @@ scoped_refptr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() {
child_percentage_size_.block_size = NGSizeIndefinite;
container_builder_.SetInlineSize(border_box_size.inline_size);
+ container_builder_.SetBfcLineOffset(
+ ConstraintSpace().BfcOffset().line_offset);
if (NGFloatTypes float_types = ConstraintSpace().AdjoiningFloatTypes()) {
DCHECK(!ConstraintSpace().IsNewFormattingContext());
- DCHECK(!container_builder_.BfcOffset());
+ DCHECK(!container_builder_.BfcBlockOffset());
// If there were preceding adjoining floats, they will be affected when the
- // BFC offset gets resolved or updated. We then need to roll back and
- // re-layout those floats with the new BFC offset, once the BFC offset is
- // updated.
- abort_when_bfc_offset_updated_ = true;
+ // BFC block offset gets resolved or updated. We then need to roll back and
+ // re-layout those floats with the new BFC block offset, once the BFC block
+ // offset is updated.
+ abort_when_bfc_block_offset_updated_ = true;
container_builder_.AddAdjoiningFloatTypes(float_types);
}
@@ -416,28 +416,28 @@ scoped_refptr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() {
// must be dealt with at the first fragment.
// D: We're forced to stop margin collapsing by a CSS property
//
- // In all those cases we can and must resolve the BFC offset now.
+ // 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) {
bool discard_subsequent_margins =
previous_inflow_position.margin_strut.discard_margins &&
!border_scrollbar_padding_.block_start;
- if (!ResolveBfcOffset(&previous_inflow_position)) {
- // There should be no preceding content that depends on the BFC offset of
- // a new formatting context block, and likewise when resuming from a break
- // token.
+ if (!ResolveBfcBlockOffset(&previous_inflow_position)) {
+ // There should be no preceding content that depends on the BFC block
+ // offset of a new formatting context block, and likewise when resuming
+ // from a break token.
DCHECK(!ConstraintSpace().IsNewFormattingContext());
DCHECK(!is_resuming_);
- return container_builder_.Abort(NGLayoutResult::kBfcOffsetResolved);
+ return container_builder_.Abort(NGLayoutResult::kBfcBlockOffsetResolved);
}
// Move to the content edge. This is where the first child should be placed.
previous_inflow_position.logical_block_offset = content_edge;
- // If we resolved the BFC offset now, the margin strut has been reset. If
- // margins are to be discarded, and this box would otherwise have adjoining
- // margins between its own margin and those subsequent content, we need to
- // make sure subsequent content discard theirs.
+ // If we resolved the BFC block offset now, the margin strut has been
+ // reset. If margins are to be discarded, and this box would otherwise have
+ // adjoining margins between its own margin and those subsequent content,
+ // we need to make sure subsequent content discard theirs.
if (discard_subsequent_margins)
previous_inflow_position.margin_strut.discard_margins = true;
}
@@ -448,15 +448,15 @@ scoped_refptr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() {
// establish a new formatting context), that may not be the case,
// though. There may e.g. be clearance involved, or inline-start margins.
if (ConstraintSpace().IsNewFormattingContext())
- DCHECK_EQ(container_builder_.BfcOffset().value(), NGBfcOffset());
+ DCHECK_EQ(container_builder_.BfcBlockOffset().value(), LayoutUnit());
// If this is a new formatting context, or if we're resuming from a break
// token, no margin strut must be lingering around at this point.
if (ConstraintSpace().IsNewFormattingContext() || is_resuming_)
DCHECK(ConstraintSpace().MarginStrut().IsEmpty());
- if (!container_builder_.BfcOffset()) {
+ if (!container_builder_.BfcBlockOffset()) {
// New formatting contexts, and where we have an empty block affected by
- // clearance should already have their BFC offset resolved.
+ // clearance should already have their BFC block offset resolved.
DCHECK(!previous_inflow_position.empty_block_affected_by_clearance);
DCHECK(!ConstraintSpace().IsNewFormattingContext());
}
@@ -495,9 +495,7 @@ scoped_refptr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() {
} else if (child.IsFloating()) {
HandleFloat(previous_inflow_position, ToNGBlockNode(child),
ToNGBlockBreakToken(child_break_token));
- } else if (child.IsListMarker() &&
- !ToLayoutNGListMarker(child.GetLayoutBox())
- ->NeedsOccupyWholeLine()) {
+ } else if (child.IsListMarker() && !child.ListMarkerOccupiesWholeLine()) {
container_builder_.SetUnpositionedListMarker(
NGUnpositionedListMarker(ToNGBlockNode(child)));
} else {
@@ -518,8 +516,9 @@ scoped_refptr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() {
&previous_inline_break_token);
if (!success) {
- // We need to abort the layout, as our BFC offset was resolved.
- return container_builder_.Abort(NGLayoutResult::kBfcOffsetResolved);
+ // We need to abort the layout, as our BFC block offset was resolved.
+ return container_builder_.Abort(
+ NGLayoutResult::kBfcBlockOffsetResolved);
}
if (container_builder_.DidBreak() &&
IsFragmentainerOutOfSpace(
@@ -561,16 +560,19 @@ scoped_refptr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() {
LayoutUnit margin_strut_sum = node_.IsQuirkyContainer()
? end_margin_strut.QuirkyContainerSum()
: end_margin_strut.Sum();
- if (!container_builder_.BfcOffset()) {
+ if (!container_builder_.BfcBlockOffset()) {
// If we have collapsed through the block start and all children (if any),
- // now is the time to determine the BFC offset, because finally we have
- // found something solid to hang on to (like clearance or a bottom border,
- // for instance). If we're a new formatting context, though, we shouldn't
- // be here, because then the offset should already have been determined.
+ // now is the time to determine the BFC block offset, because finally we
+ // have found something solid to hang on to (like clearance or a bottom
+ // border, for instance). If we're a new formatting context, though, we
+ // shouldn't be here, because then the offset should already have been
+ // determined.
DCHECK(!ConstraintSpace().IsNewFormattingContext());
- if (!ResolveBfcOffset(&previous_inflow_position))
- return container_builder_.Abort(NGLayoutResult::kBfcOffsetResolved);
- DCHECK(container_builder_.BfcOffset());
+ if (!ResolveBfcBlockOffset(&previous_inflow_position)) {
+ return container_builder_.Abort(
+ NGLayoutResult::kBfcBlockOffsetResolved);
+ }
+ DCHECK(container_builder_.BfcBlockOffset());
} else {
// The trailing margin strut will be part of our intrinsic block size, but
// only if there is something that separates the end margin strut from the
@@ -605,21 +607,21 @@ scoped_refptr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() {
// Recompute the block-axis size now that we know our content size.
border_box_size.block_size = ComputeBlockSizeForFragment(
- ConstraintSpace(), Style(), intrinsic_block_size_);
+ ConstraintSpace(), Style(), intrinsic_block_size_, border_padding_);
container_builder_.SetBlockSize(border_box_size.block_size);
- // If our BFC offset is still unknown, there's one last thing to take into
- // consideration: Non-empty blocks always know their position in space. If we
- // have a break token, it means that we know the blocks' position even if
- // they're empty; it will be at the very start of the fragmentainer.
- if (!container_builder_.BfcOffset() &&
+ // If our BFC block offset is still unknown, there's one last thing to take
+ // into consideration: Non-empty blocks always know their position in space.
+ // If we have a break token, it means that we know the blocks' position even
+ // if they're empty; it will be at the very start of the fragmentainer.
+ if (!container_builder_.BfcBlockOffset() &&
(border_box_size.block_size || BreakToken())) {
- if (!ResolveBfcOffset(&previous_inflow_position))
- return container_builder_.Abort(NGLayoutResult::kBfcOffsetResolved);
- DCHECK(container_builder_.BfcOffset());
+ if (!ResolveBfcBlockOffset(&previous_inflow_position))
+ return container_builder_.Abort(NGLayoutResult::kBfcBlockOffsetResolved);
+ DCHECK(container_builder_.BfcBlockOffset());
}
- if (container_builder_.BfcOffset()) {
+ if (container_builder_.BfcBlockOffset()) {
// Do not collapse margins between the last in-flow child and bottom margin
// of its parent if the parent has height != auto.
if (!Style().LogicalHeight().IsAuto()) {
@@ -636,12 +638,13 @@ scoped_refptr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() {
container_builder_.SetEndMarginStrut(end_margin_strut);
container_builder_.SetIntrinsicBlockSize(intrinsic_block_size_);
- container_builder_.SetPadding(ComputePadding(ConstraintSpace(), Style()));
+ container_builder_.SetPadding(padding);
+ container_builder_.SetBorders(borders);
- // We only finalize for fragmentation if the fragment has a BFC offset. This
- // may occur with a zero block size fragment. We need to know the BFC offset
- // to determine where the fragmentation line is relative to us.
- if (container_builder_.BfcOffset() &&
+ // We only finalize for fragmentation if the fragment has a BFC block offset.
+ // This may occur with a zero block size fragment. We need to know the BFC
+ // block offset to determine where the fragmentation line is relative to us.
+ if (container_builder_.BfcBlockOffset() &&
ConstraintSpace().HasBlockFragmentation())
FinalizeForFragmentation();
@@ -649,7 +652,7 @@ scoped_refptr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() {
// layout.
if (unpositioned_floats_.IsEmpty()) {
NGOutOfFlowLayoutPart(&container_builder_, Node().IsAbsoluteContainer(),
- Node().IsFixedContainer(), Node().GetScrollbarSizes(),
+ Node().IsFixedContainer(), borders + scrollbars,
ConstraintSpace(), Style())
.Run();
}
@@ -657,17 +660,20 @@ scoped_refptr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() {
#if DCHECK_IS_ON()
// If we have any unpositioned floats at this stage, our parent will pick up
// this by examining adjoining float types returned, so that we get relayout
- // with a forced BFC offset once it's known.
+ // with a forced BFC block offset once it's known.
if (!unpositioned_floats_.IsEmpty()) {
- DCHECK(!container_builder_.BfcOffset());
+ DCHECK(!container_builder_.BfcBlockOffset());
DCHECK(container_builder_.AdjoiningFloatTypes());
}
#endif
PropagateBaselinesFromChildren();
- DCHECK(exclusion_space_);
- container_builder_.SetExclusionSpace(std::move(exclusion_space_));
+ // An exclusion space is confined to nodes within the same formatting context.
+ if (!ConstraintSpace().IsNewFormattingContext()) {
+ DCHECK(exclusion_space_);
+ container_builder_.SetExclusionSpace(std::move(exclusion_space_));
+ }
if (ConstraintSpace().UseFirstLineStyle())
container_builder_.SetStyleVariant(NGStyleVariant::kFirstLine);
@@ -694,7 +700,7 @@ void NGBlockLayoutAlgorithm::HandleOutOfFlowPositioned(
// We only include the margin strut in the OOF static-position if we know we
// aren't going to be a zero-block-size fragment.
- if (container_builder_.BfcOffset())
+ if (container_builder_.BfcBlockOffset())
offset.block_offset += previous_inflow_position.margin_strut.Sum();
container_builder_.AddOutOfFlowChildCandidate(child, offset);
@@ -704,35 +710,24 @@ void NGBlockLayoutAlgorithm::HandleFloat(
const NGPreviousInflowPosition& previous_inflow_position,
NGBlockNode child,
NGBlockBreakToken* child_break_token) {
- // Calculate margins in the BFC's writing mode.
- NGBoxStrut margins = CalculateMargins(child, child_break_token);
-
- LayoutUnit origin_inline_offset =
- ConstraintSpace().BfcOffset().line_offset +
- border_scrollbar_padding_.LineLeft(ConstraintSpace().Direction());
-
- scoped_refptr<NGUnpositionedFloat> unpositioned_float =
- NGUnpositionedFloat::Create(child_available_size_, child_percentage_size_,
- origin_inline_offset,
- ConstraintSpace().BfcOffset().line_offset,
- margins, child, child_break_token);
AddUnpositionedFloat(&unpositioned_floats_, &container_builder_,
- unpositioned_float);
+ NGUnpositionedFloat(child, child_break_token));
// If there is a break token for a float we must be resuming layout, we must
// always know our position in the BFC.
DCHECK(!child_break_token || child_break_token->IsBreakBefore() ||
- container_builder_.BfcOffset());
+ container_builder_.BfcBlockOffset());
// No need to postpone the positioning if we know the correct offset.
- if (container_builder_.BfcOffset() || ConstraintSpace().FloatsBfcOffset()) {
+ if (container_builder_.BfcBlockOffset() ||
+ ConstraintSpace().FloatsBfcBlockOffset()) {
// Adjust origin point to the margins of the last child.
// Example: <div style="margin-bottom: 20px"><float></div>
// <div style="margin-bottom: 30px"></div>
LayoutUnit origin_block_offset =
- container_builder_.BfcOffset()
+ container_builder_.BfcBlockOffset()
? NextBorderEdge(previous_inflow_position)
- : ConstraintSpace().FloatsBfcOffset().value().block_offset;
+ : ConstraintSpace().FloatsBfcBlockOffset().value();
PositionPendingFloats(origin_block_offset);
}
}
@@ -756,15 +751,20 @@ bool NGBlockLayoutAlgorithm::HandleNewFormattingContext(
ComputeChildData(*previous_inflow_position, child, child_break_token,
has_clearance_past_adjoining_floats);
- // If the child has a block-start margin, and the BFC offset is still
+ LayoutUnit child_origin_line_offset =
+ ConstraintSpace().BfcOffset().line_offset +
+ border_scrollbar_padding_.LineLeft(direction) +
+ child_data.margins.LineLeft(direction).ClampNegativeToZero();
+
+ // If the child has a block-start margin, and the BFC block offset is still
// unresolved, and we have preceding adjoining floats, things get complicated
// here. Depending on whether the child fits beside the floats, the margin may
// or may not be adjoining with the current margin strut. This affects the
// position of the preceding adjoining floats. We may have to resolve the BFC
- // offset once with the child's margin tentatively adjoining, then realize
- // that the child isn't going to fit beside the floats at the current
- // position, and therefore re-resolve the BFC offset with the child's margin
- // non-adjoining. This is akin to clearance.
+ // block offset once with the child's margin tentatively adjoining, then
+ // realize that the child isn't going to fit beside the floats at the current
+ // position, and therefore re-resolve the BFC block offset with the child's
+ // margin non-adjoining. This is akin to clearance.
NGMarginStrut adjoining_margin_strut(previous_inflow_position->margin_strut);
adjoining_margin_strut.Append(child_data.margins.block_start,
child_style.HasMarginBeforeQuirk());
@@ -780,32 +780,32 @@ bool NGBlockLayoutAlgorithm::HandleNewFormattingContext(
bool child_margin_got_separated = false;
bool had_pending_floats = false;
- if (!container_builder_.BfcOffset()) {
+ if (!container_builder_.BfcBlockOffset()) {
had_pending_floats = !unpositioned_floats_.IsEmpty();
- if (ConstraintSpace().FloatsBfcOffset()) {
+ if (ConstraintSpace().FloatsBfcBlockOffset()) {
// This is not the first time we're here. We already have a suggested BFC
- // offset.
+ // block offset.
bfc_offset_already_resolved = true;
- NGBfcOffset bfc_offset = *ConstraintSpace().FloatsBfcOffset();
- child_bfc_offset_estimate = bfc_offset.block_offset;
- // We require that the BFC offset be the one we'd get with either margins
- // adjoining or margins separated. Anything else is a bug.
- DCHECK(bfc_offset.block_offset == adjoining_bfc_offset_estimate ||
- bfc_offset.block_offset == non_adjoining_bfc_offset_estimate);
+ child_bfc_offset_estimate = *ConstraintSpace().FloatsBfcBlockOffset();
+ // We require that the BFC block offset be the one we'd get with either
+ // margins adjoining or margins separated. Anything else is a bug.
+ DCHECK(child_bfc_offset_estimate == adjoining_bfc_offset_estimate ||
+ child_bfc_offset_estimate == non_adjoining_bfc_offset_estimate);
// Figure out if the child margin has already got separated from the
// margin strut or not.
child_margin_got_separated =
- bfc_offset.block_offset != adjoining_bfc_offset_estimate;
+ child_bfc_offset_estimate != adjoining_bfc_offset_estimate;
} else if (has_clearance_past_adjoining_floats) {
child_bfc_offset_estimate = NextBorderEdge(*previous_inflow_position);
child_margin_got_separated = true;
}
- // The BFC offset of this container gets resolved because of this child.
+ // The BFC block offset of this container gets resolved because of this
+ // child.
child_determined_bfc_offset = true;
- if (!ResolveBfcOffset(previous_inflow_position,
- child_bfc_offset_estimate)) {
+ if (!ResolveBfcBlockOffset(previous_inflow_position,
+ child_bfc_offset_estimate)) {
// If we need to abort here, it means that we had preceding unpositioned
// floats. This is only expected if we're here for the first time.
DCHECK(!bfc_offset_already_resolved);
@@ -832,9 +832,9 @@ bool NGBlockLayoutAlgorithm::HandleNewFormattingContext(
child_determined_bfc_offset;
NGLayoutOpportunity opportunity;
scoped_refptr<NGLayoutResult> layout_result;
- std::tie(layout_result, opportunity) =
- LayoutNewFormattingContext(child, child_break_token, child_data,
- child_bfc_offset_estimate, abort_if_cleared);
+ std::tie(layout_result, opportunity) = LayoutNewFormattingContext(
+ child, child_break_token, child_data,
+ {child_origin_line_offset, child_bfc_offset_estimate}, abort_if_cleared);
if (!layout_result) {
DCHECK(abort_if_cleared);
@@ -845,16 +845,16 @@ bool NGBlockLayoutAlgorithm::HandleNewFormattingContext(
// if we can do it right away from here, or if we have to roll back and
// reposition floats first.
if (child_determined_bfc_offset) {
- // The BFC offset was calculated when we got to this child, with the
- // child's margin adjoining. Since that turned out to be wrong, re-resolve
- // the BFC offset without the child's margin.
- LayoutUnit old_offset = container_builder_.BfcOffset()->block_offset;
- container_builder_.ResetBfcOffset();
- ResolveBfcOffset(previous_inflow_position,
- non_adjoining_bfc_offset_estimate);
+ // The BFC block offset was calculated when we got to this child, with
+ // the child's margin adjoining. Since that turned out to be wrong,
+ // re-resolve the BFC block offset without the child's margin.
+ LayoutUnit old_offset = container_builder_.BfcBlockOffset().value();
+ container_builder_.ResetBfcBlockOffset();
+ ResolveBfcBlockOffset(previous_inflow_position,
+ non_adjoining_bfc_offset_estimate);
if ((bfc_offset_already_resolved || had_pending_floats) &&
- old_offset != container_builder_.BfcOffset()->block_offset) {
- // The first BFC offset resolution turned out to be wrong, and we
+ old_offset != container_builder_.BfcBlockOffset().value()) {
+ // The first BFC block offset resolution turned out to be wrong, and we
// positioned preceding adjacent floats based on that. Now we have to
// roll back and position them at the correct offset. The only expected
// incorrect estimate is with the child's margin adjoining. Any other
@@ -872,7 +872,8 @@ bool NGBlockLayoutAlgorithm::HandleNewFormattingContext(
// We can re-layout the child right away. This re-layout *must* produce a
// fragment and opportunity which fits within the exclusion space.
std::tie(layout_result, opportunity) = LayoutNewFormattingContext(
- child, child_break_token, child_data, child_bfc_offset_estimate,
+ child, child_break_token, child_data,
+ {child_origin_line_offset, child_bfc_offset_estimate},
/* abort_if_cleared */ false);
}
DCHECK(layout_result->PhysicalFragment());
@@ -883,10 +884,10 @@ bool NGBlockLayoutAlgorithm::HandleNewFormattingContext(
// pretend that computed margins are 0 here, as they have already been
// excluded from the layout opportunity rectangle.
NGBoxStrut auto_margins;
- if (child.IsListMarker() &&
- ToLayoutNGListMarker(child.GetLayoutBox())->NeedsOccupyWholeLine()) {
- // Deal with marker's margin. It happens only when marker
- // NeedsOccupyWholeLine().
+ if (child.IsListMarker()) {
+ // Deal with marker's margin. It happens only when marker needs to occupy
+ // the whole line.
+ DCHECK(child.ListMarkerOccupiesWholeLine());
auto_margins.inline_start = NGUnpositionedListMarker(ToNGBlockNode(child))
.InlineOffset(fragment.InlineSize());
auto_margins.inline_end = opportunity.rect.InlineSize() -
@@ -896,8 +897,26 @@ bool NGBlockLayoutAlgorithm::HandleNewFormattingContext(
fragment.InlineSize(), &auto_margins);
}
- NGBfcOffset child_bfc_offset(opportunity.rect.start_offset.line_offset +
- auto_margins.LineLeft(direction),
+ LayoutUnit child_bfc_line_offset = opportunity.rect.start_offset.line_offset +
+ auto_margins.LineLeft(direction);
+
+ // When there are negative margins present, a new formatting context can move
+ // outside its layout opportunity. This occurs when the *line-left* edge
+ // hasn't been shifted by floats.
+ //
+ // NOTE: Firefox and EdgeHTML both match this behaviour of only considering
+ // the line-left edge. WebKit also considers this line-right edge, but this
+ // is slightly more complicated to implement, and probably not needed for web
+ // compatibility.
+ bool can_move_outside_opportunity =
+ opportunity.rect.start_offset.line_offset == child_origin_line_offset;
+
+ if (can_move_outside_opportunity) {
+ child_bfc_line_offset +=
+ child_data.margins.LineLeft(direction).ClampPositiveToZero();
+ }
+
+ NGBfcOffset child_bfc_offset(child_bfc_line_offset,
opportunity.rect.start_offset.block_offset);
NGLogicalOffset logical_offset = LogicalFromBfcOffsets(
@@ -930,8 +949,8 @@ bool NGBlockLayoutAlgorithm::HandleNewFormattingContext(
ToNGBlockNode(child).StoreMargins(ConstraintSpace(), child_data.margins);
*previous_inflow_position = ComputeInflowPosition(
- *previous_inflow_position, child, child_data, child_bfc_offset,
- logical_offset, *layout_result, fragment,
+ *previous_inflow_position, child, child_data,
+ child_bfc_offset.block_offset, logical_offset, *layout_result, fragment,
/* empty_block_affected_by_clearance */ false);
*previous_inline_break_token = nullptr;
@@ -943,23 +962,13 @@ NGBlockLayoutAlgorithm::LayoutNewFormattingContext(
NGLayoutInputNode child,
NGBreakToken* child_break_token,
const NGInflowChildData& child_data,
- LayoutUnit child_origin_block_offset,
+ NGBfcOffset origin_offset,
bool abort_if_cleared) {
- const TextDirection direction = ConstraintSpace().Direction();
- const WritingMode writing_mode = ConstraintSpace().GetWritingMode();
-
- LayoutUnit child_bfc_line_offset =
- ConstraintSpace().BfcOffset().line_offset +
- border_scrollbar_padding_.LineLeft(direction) +
- child_data.margins.LineLeft(direction);
-
// The origin offset is where we should start looking for layout
// opportunities. It needs to be adjusted by the child's clearance.
- NGBfcOffset origin_offset = {child_bfc_line_offset,
- child_origin_block_offset};
AdjustToClearance(exclusion_space_->ClearanceOffset(child.Style().Clear()),
&origin_offset);
- DCHECK(container_builder_.BfcOffset());
+ DCHECK(container_builder_.BfcBlockOffset());
// Before we lay out, figure out how much inline space we have available at
// the start block offset estimate (the child is not allowed to overlap with
@@ -972,49 +981,77 @@ NGBlockLayoutAlgorithm::LayoutNewFormattingContext(
// floats.
LayoutUnit inline_margin = child_data.margins.InlineSum();
LayoutUnit inline_size =
- (child_available_size_.inline_size - inline_margin).ClampNegativeToZero();
- NGLayoutOpportunity opportunity = exclusion_space_->FindLayoutOpportunity(
- origin_offset, inline_size, NGLogicalSize());
+ (child_available_size_.inline_size - inline_margin.ClampNegativeToZero())
+ .ClampNegativeToZero();
- scoped_refptr<NGLayoutResult> layout_result;
+ Vector<NGLayoutOpportunity> opportunities =
+ exclusion_space_->AllLayoutOpportunities(origin_offset, inline_size);
+
+ // We should always have at least one opportunity.
+ DCHECK_GT(opportunities.size(), 0u);
// Now we lay out. This will give us a child fragment and thus its size, which
- // means that we can find out where it's actually going to fit. If it doesn't
+ // means that we can find out if it's actually going to fit. If it doesn't
// fit where it was laid out, and is pushed downwards, we'll lay out over
- // again, since a new BFC offset could result in a new fragment size,
+ // 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.
- do {
+ 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
- // child_origin_block_offset, reposition any floats affected by that, and
+ // origin_offset.block_offset, reposition any floats affected by that, and
// try again.
- layout_result = nullptr;
- break;
+ return std::make_pair(nullptr, opportunity);
}
- origin_offset.block_offset = opportunity.rect.BlockStartOffset();
+ // When the inline dimensions of layout opportunity match the available
+ // space, a new formatting context can expand outside of the opportunity if
+ // negative margins are present.
+ bool can_expand_outside_opportunity =
+ (opportunity.rect.start_offset.line_offset ==
+ origin_offset.line_offset &&
+ opportunity.rect.InlineSize() == inline_size);
+
+ LayoutUnit inline_negative_margin =
+ can_expand_outside_opportunity ? inline_margin.ClampPositiveToZero()
+ : LayoutUnit();
+
// The available inline size in the child constraint space needs to include
// inline margins, since layout algorithms (both legacy and NG) will resolve
// auto inline size by subtracting the inline margins from available inline
// size. We have calculated a layout opportunity without margins in mind,
// since they overlap with adjacent floats. Now we need to add them.
NGLogicalSize child_available_size = {
- (opportunity.rect.InlineSize() + inline_margin).ClampNegativeToZero(),
+ (opportunity.rect.InlineSize() - inline_negative_margin + inline_margin)
+ .ClampNegativeToZero(),
child_available_size_.block_size};
auto child_space =
CreateConstraintSpaceForChild(child, child_data, child_available_size);
- layout_result = child.Layout(*child_space, child_break_token);
+
+ // All formatting context roots (like this child) should start with an empty
+ // exclusion space.
+ DCHECK(child_space->ExclusionSpace().IsEmpty());
+
+ scoped_refptr<NGLayoutResult> layout_result =
+ child.Layout(*child_space, child_break_token);
+
+ // Since this child establishes a new formatting context, no exclusion space
+ // should be returned.
+ DCHECK(!layout_result->ExclusionSpace());
+
DCHECK(layout_result->PhysicalFragment());
+ NGFragment fragment(ConstraintSpace().GetWritingMode(),
+ *layout_result->PhysicalFragment());
- // Now find a layout opportunity where the fragment is actually going to
- // fit.
- NGFragment fragment(writing_mode, *layout_result->PhysicalFragment());
- opportunity = exclusion_space_->FindLayoutOpportunity(
- origin_offset, inline_size, fragment.Size());
- } while (origin_offset.block_offset < opportunity.rect.BlockStartOffset());
+ // Now we can check if the fragment will fit in this layout opportunity.
+ if ((opportunity.rect.InlineSize() >= fragment.InlineSize() ||
+ opportunity.rect.InlineSize() == inline_size) &&
+ opportunity.rect.BlockSize() >= fragment.BlockSize())
+ return std::make_pair(std::move(layout_result), opportunity);
+ }
- return std::make_pair(std::move(layout_result), opportunity);
+ NOTREACHED();
+ return std::make_pair(nullptr, NGLayoutOpportunity());
}
bool NGBlockLayoutAlgorithm::HandleInflow(
@@ -1029,26 +1066,18 @@ bool NGBlockLayoutAlgorithm::HandleInflow(
bool is_non_empty_inline =
child.IsInline() && !ToNGInlineNode(child).IsEmptyInline();
-
- // We update marker text in WillCollectInlines(). If ListItem isn't
- // ChildrenInline(), we should WillCollectInlines() manually.
- if (Node().IsListItem() && !child.IsInline()) {
- LayoutBlockFlow* block = ToLayoutBlockFlow(Node().GetLayoutBox());
- block->WillCollectInlines();
- }
-
bool has_clearance_past_adjoining_floats =
child.IsBlock() &&
HasClearancePastAdjoiningFloats(container_builder_.AdjoiningFloatTypes(),
child.Style());
// If we can separate the previous margin strut from what is to follow, do
- // that. Then we're able to resolve *our* BFC offset and position any pending
- // floats. There are two situations where this is necessary:
+ // that. Then we're able to resolve *our* BFC block offset and position any
+ // pending floats. There are two situations where this is necessary:
// 1. If the child is to be cleared by adjoining floats.
// 2. If the child is a non-empty inline.
if (has_clearance_past_adjoining_floats || is_non_empty_inline) {
- if (!ResolveBfcOffset(previous_inflow_position))
+ if (!ResolveBfcBlockOffset(previous_inflow_position))
return false;
}
@@ -1061,53 +1090,44 @@ bool NGBlockLayoutAlgorithm::HandleInflow(
scoped_refptr<NGLayoutResult> layout_result =
child.Layout(*child_space, child_break_token);
- base::Optional<NGBfcOffset> child_bfc_offset = layout_result->BfcOffset();
+ base::Optional<LayoutUnit> child_bfc_block_offset =
+ layout_result->BfcBlockOffset();
// TODO(layout-dev): A more optimal version of this is to set
// relayout_child_when_bfc_resolved only if the child tree itself _added_ any
// floats that it failed to position. Currently, we risk relaying out the
// parent block for no reason, because we're not able to make this
// distinction.
bool relayout_child_when_bfc_resolved =
- layout_result->AdjoiningFloatTypes() && !child_bfc_offset &&
- !child_space->FloatsBfcOffset();
+ layout_result->AdjoiningFloatTypes() && !child_bfc_block_offset &&
+ !child_space->FloatsBfcBlockOffset();
bool is_empty_block = IsEmptyBlock(child, *layout_result);
- // A child may have aborted its layout if it resolved its BFC offset. If
- // we don't have a BFC offset yet, we need to propagate the abortion up
- // to our parent.
- if (layout_result->Status() == NGLayoutResult::kBfcOffsetResolved &&
- !container_builder_.BfcOffset()) {
- // There's no need to do anything apart from resolving the BFC offset here,
- // so make sure that it aborts before trying to position floats or anything
- // like that, which would just be waste of time. This is simply propagating
- // an abort up to a node which is able to restart the layout (a node that
- // has resolved its BFC offset).
- abort_when_bfc_offset_updated_ = true;
- ResolveBfcOffset(previous_inflow_position, child_bfc_offset->block_offset);
+ // A child may have aborted its layout if it resolved its BFC block offset.
+ // If we don't have a BFC block offset yet, we need to propagate the abortion
+ // up to our parent.
+ if (layout_result->Status() == NGLayoutResult::kBfcBlockOffsetResolved &&
+ !container_builder_.BfcBlockOffset()) {
+ // There's no need to do anything apart from resolving the BFC block offset
+ // here, so make sure that it aborts before trying to position floats or
+ // anything like that, which would just be waste of time. This is simply
+ // propagating an abort up to a node which is able to restart the layout (a
+ // node that has resolved its BFC block offset).
+ DCHECK(child_bfc_block_offset);
+ abort_when_bfc_block_offset_updated_ = true;
+ ResolveBfcBlockOffset(previous_inflow_position,
+ child_bfc_block_offset.value());
return false;
}
- // We only want to copy from a layout that was successful. If the status was
- // kBfcOffsetResolved we may have unpositioned floats which we will position
- // in the current exclusion space once *our* BFC is resolved.
- //
- // The exclusion space is then updated when the child undergoes relayout
- // below.
- if (layout_result->Status() == NGLayoutResult::kSuccess) {
- DCHECK(layout_result->ExclusionSpace());
- exclusion_space_ =
- std::make_unique<NGExclusionSpace>(*layout_result->ExclusionSpace());
- }
-
// We have special behaviour for an empty block which gets pushed down due to
// clearance, see comment inside ComputeInflowPosition.
bool empty_block_affected_by_clearance = false;
// We try and position the child within the block formatting context. This
- // may cause our BFC offset to be resolved, in which case we should abort our
- // layout if needed.
+ // may cause our BFC block offset to be resolved, in which case we should
+ // abort our layout if needed.
bool has_clearance = layout_result->IsPushedByFloats();
- if (!child_bfc_offset) {
+ if (!child_bfc_block_offset) {
if (!has_clearance && child_space->HasClearanceOffset() &&
child.Style().Clear() != EClear::kNone) {
// This is an empty block child that we collapsed through, so we have to
@@ -1123,31 +1143,32 @@ bool NGBlockLayoutAlgorithm::HandleInflow(
}
if (has_clearance) {
// The child has clearance. Clearance inhibits margin collapsing and acts as
- // spacing before the block-start margin of the child. Our BFC offset is
- // therefore resolvable, and if it hasn't already been resolved, we'll do it
- // now to separate the child's collapsed margin from this container.
- if (!ResolveBfcOffset(previous_inflow_position))
+ // spacing before the block-start margin of the child. Our BFC block offset
+ // is therefore resolvable, and if it hasn't already been resolved, we'll
+ // do it now to separate the child's collapsed margin from this container.
+ if (!ResolveBfcBlockOffset(previous_inflow_position))
return false;
}
- if (!child_bfc_offset) {
+ if (!child_bfc_block_offset) {
DCHECK(is_empty_block);
- // Layout wasn't able to determine the BFC offset of the child. This has to
- // mean that the child is empty (block-size-wise).
- if (container_builder_.BfcOffset()) {
- // Since we know our own BFC offset, though, we can calculate that of the
- // child as well.
- child_bfc_offset = PositionEmptyChildWithParentBfc(
+ // Layout wasn't able to determine the BFC block offset of the child. This
+ // has to mean that the child is empty (block-size-wise).
+ if (container_builder_.BfcBlockOffset()) {
+ // Since we know our own BFC block offset, though, we can calculate that
+ // of the child as well.
+ child_bfc_block_offset = PositionEmptyChildWithParentBfc(
child, *child_space, child_data, *layout_result);
}
} else if (!has_clearance) {
// We shouldn't have any pending floats here, since an in-flow child found
- // its BFC offset.
+ // its BFC block offset.
DCHECK(unpositioned_floats_.IsEmpty());
- // The child's BFC offset is known, and since there's no clearance, this
- // container will get the same offset, unless it has already been resolved.
- if (!ResolveBfcOffset(previous_inflow_position,
- child_bfc_offset->block_offset))
+ // The child's BFC block offset is known, and since there's no clearance,
+ // this container will get the same offset, unless it has already been
+ // resolved.
+ if (!ResolveBfcBlockOffset(previous_inflow_position,
+ child_bfc_block_offset.value()))
return false;
}
@@ -1181,63 +1202,65 @@ bool NGBlockLayoutAlgorithm::HandleInflow(
}
}
- // We need to layout a child if we know its BFC offset and:
- // - It aborted its layout as it resolved its BFC offset.
+ // We need to layout a child if we know its BFC block offset and:
+ // - It aborted its layout as it resolved its BFC block offset.
// - It has some unpositioned floats.
// - It was affected by clearance.
- if ((layout_result->Status() == NGLayoutResult::kBfcOffsetResolved ||
+ if ((layout_result->Status() == NGLayoutResult::kBfcBlockOffsetResolved ||
relayout_child_when_bfc_resolved ||
empty_block_affected_by_clearance_needs_relayout) &&
- child_bfc_offset) {
+ child_bfc_block_offset) {
scoped_refptr<NGConstraintSpace> new_child_space =
CreateConstraintSpaceForChild(child, child_data, child_available_size_,
- child_bfc_offset);
+ child_bfc_block_offset);
layout_result = child.Layout(*new_child_space, child_break_token);
- if (layout_result->Status() == NGLayoutResult::kBfcOffsetResolved) {
- // Even a second layout pass may abort, if the BFC offset initially
+ if (layout_result->Status() == NGLayoutResult::kBfcBlockOffsetResolved) {
+ // Even a second layout pass may abort, if the BFC block offset initially
// calculated turned out to be wrong. This happens when we discover that
// an in-flow block-level descendant that establishes a new formatting
// context doesn't fit beside the floats at its initial position. Allow
// one more pass.
- child_bfc_offset = layout_result->BfcOffset();
- DCHECK(child_bfc_offset);
+ child_bfc_block_offset = layout_result->BfcBlockOffset();
+ DCHECK(child_bfc_block_offset);
new_child_space = CreateConstraintSpaceForChild(
- child, child_data, child_available_size_, child_bfc_offset);
+ child, child_data, child_available_size_, child_bfc_block_offset);
layout_result = child.Layout(*new_child_space, child_break_token);
}
DCHECK_EQ(layout_result->Status(), NGLayoutResult::kSuccess);
-
- DCHECK(layout_result->ExclusionSpace());
- exclusion_space_ =
- std::make_unique<NGExclusionSpace>(*layout_result->ExclusionSpace());
relayout_child_when_bfc_resolved = false;
}
- // If we don't know our BFC offset yet, and the child stumbled into something
- // that needs it (unable to position floats when the BFC offset is unknown),
- // we need abort layout once we manage to resolve it, and relayout. Note that
- // this check is performed after the optional second layout pass above, since
- // we may have been able to resolve our BFC offset (e.g. due to clearance) and
- // position any descendant floats in the second pass. In particular, when it
- // comes to clearance of empty blocks, if we just applied it and resolved the
- // BFC offset to separate the margins before and after clearance, we cannot
- // abort and re-layout this block, or clearance would be lost.
+ // It is now safe to update our version of the exclusion space.
+ DCHECK(layout_result->ExclusionSpace());
+ exclusion_space_ =
+ std::make_unique<NGExclusionSpace>(*layout_result->ExclusionSpace());
+
+ // If we don't know our BFC block offset yet, and the child stumbled into
+ // something that needs it (unable to position floats when the BFC block
+ // offset is unknown), we need abort layout once we manage to resolve it, and
+ // relayout. Note that this check is performed after the optional second
+ // layout pass above, since we may have been able to resolve our BFC block
+ // offset (e.g. due to clearance) and position any descendant floats in the
+ // second pass. In particular, when it comes to clearance of empty blocks, if
+ // we just applied it and resolved the BFC block offset to separate the
+ // margins before and after clearance, we cannot abort and re-layout this
+ // block, or clearance would be lost.
//
// If we are a new formatting context, the child will get re-laid out once it
// has been positioned.
- if (!container_builder_.BfcOffset()) {
- abort_when_bfc_offset_updated_ |= relayout_child_when_bfc_resolved;
- // If our BFC offset is unknown, and the child got pushed down by floats,
- // so will we.
+ if (!container_builder_.BfcBlockOffset()) {
+ abort_when_bfc_block_offset_updated_ |= relayout_child_when_bfc_resolved;
+ // If our BFC block offset is unknown, and the child got pushed down by
+ // floats, so will we.
if (layout_result->IsPushedByFloats())
container_builder_.SetIsPushedByFloats();
}
// A line-box may have a list of floats which we add as children.
- if (child.IsInline() &&
- (container_builder_.BfcOffset() || ConstraintSpace().FloatsBfcOffset())) {
+ if (child.IsInline() && (container_builder_.BfcBlockOffset() ||
+ ConstraintSpace().FloatsBfcBlockOffset())) {
AddPositionedFloats(layout_result->PositionedFloats());
}
@@ -1247,7 +1270,7 @@ bool NGBlockLayoutAlgorithm::HandleInflow(
NGFragment fragment(ConstraintSpace().GetWritingMode(), physical_fragment);
NGLogicalOffset logical_offset = CalculateLogicalOffset(
- child, fragment, child_data.margins, child_bfc_offset);
+ fragment, layout_result->BfcLineOffset(), child_bfc_block_offset);
if (ConstraintSpace().HasBlockFragmentation()) {
if (BreakBeforeChild(child, *layout_result, previous_inflow_position,
@@ -1261,7 +1284,7 @@ bool NGBlockLayoutAlgorithm::HandleInflow(
PositionOrPropagateListMarker(*layout_result, &logical_offset);
- if (is_empty_block && !container_builder_.BfcOffset()) {
+ if (is_empty_block && !container_builder_.BfcBlockOffset()) {
container_builder_.AddAdjoiningFloatTypes(
layout_result->AdjoiningFloatTypes());
}
@@ -1273,10 +1296,10 @@ bool NGBlockLayoutAlgorithm::HandleInflow(
if (child.IsBlock())
ToNGBlockNode(child).StoreMargins(ConstraintSpace(), child_data.margins);
- *previous_inflow_position =
- ComputeInflowPosition(*previous_inflow_position, child, child_data,
- child_bfc_offset, logical_offset, *layout_result,
- fragment, empty_block_affected_by_clearance);
+ *previous_inflow_position = ComputeInflowPosition(
+ *previous_inflow_position, child, child_data, child_bfc_block_offset,
+ logical_offset, *layout_result, fragment,
+ empty_block_affected_by_clearance);
*previous_inline_break_token =
child.IsInline() ? layout_result->PhysicalFragment()->BreakToken()
@@ -1327,7 +1350,7 @@ NGPreviousInflowPosition NGBlockLayoutAlgorithm::ComputeInflowPosition(
const NGPreviousInflowPosition& previous_inflow_position,
const NGLayoutInputNode child,
const NGInflowChildData& child_data,
- const base::Optional<NGBfcOffset>& child_bfc_offset,
+ const base::Optional<LayoutUnit>& child_bfc_block_offset,
const NGLogicalOffset& logical_offset,
const NGLayoutResult& layout_result,
const NGFragment& fragment,
@@ -1343,8 +1366,9 @@ NGPreviousInflowPosition NGBlockLayoutAlgorithm::ComputeInflowPosition(
if (empty_block_affected_by_clearance) {
// If there's clearance, we must have applied that by now and thus
- // resolved our BFC offset.
- DCHECK(container_builder_.BfcOffset());
+ // resolved our BFC block offset.
+ DCHECK(container_builder_.BfcBlockOffset());
+ DCHECK(child_bfc_block_offset.has_value());
// If an empty block was affected by clearance (that is it got pushed
// down past a float), we need to do something slightly bizarre.
@@ -1384,12 +1408,12 @@ NGPreviousInflowPosition NGBlockLayoutAlgorithm::ComputeInflowPosition(
logical_block_offset += margin_before_clearance;
// Calculate and apply actual clearance.
- LayoutUnit clearance = child_bfc_offset.value().block_offset -
+ LayoutUnit clearance = child_bfc_block_offset.value() -
layout_result.EndMarginStrut().Sum() -
NextBorderEdge(previous_inflow_position);
logical_block_offset += clearance;
}
- if (!container_builder_.BfcOffset())
+ if (!container_builder_.BfcBlockOffset())
DCHECK_EQ(logical_block_offset, LayoutUnit());
} else {
logical_block_offset = logical_offset.block_offset + fragment.BlockSize();
@@ -1430,7 +1454,7 @@ NGPreviousInflowPosition NGBlockLayoutAlgorithm::ComputeInflowPosition(
empty_or_sibling_empty_affected_by_clearance};
}
-NGBfcOffset NGBlockLayoutAlgorithm::PositionEmptyChildWithParentBfc(
+LayoutUnit NGBlockLayoutAlgorithm::PositionEmptyChildWithParentBfc(
const NGLayoutInputNode& child,
const NGConstraintSpace& child_space,
const NGInflowChildData& child_data,
@@ -1439,35 +1463,26 @@ NGBfcOffset NGBlockLayoutAlgorithm::PositionEmptyChildWithParentBfc(
// The child must be an in-flow zero-block-size fragment, use its end margin
// strut for positioning.
- NGBfcOffset child_bfc_offset = {
- ConstraintSpace().BfcOffset().line_offset +
- border_scrollbar_padding_.LineLeft(ConstraintSpace().Direction()) +
- child_data.margins.LineLeft(ConstraintSpace().Direction()),
+ LayoutUnit child_bfc_block_offset =
child_data.bfc_offset_estimate.block_offset +
- layout_result.EndMarginStrut().Sum()};
-
- if (child.IsInline()) {
- child_bfc_offset.line_offset +=
- LineOffsetForTextAlign(Style().GetTextAlign(), Style().Direction(),
- child_available_size_.inline_size, LayoutUnit());
- }
+ layout_result.EndMarginStrut().Sum();
- ApplyClearance(child_space, &child_bfc_offset.block_offset);
+ ApplyClearance(child_space, &child_bfc_block_offset);
- return child_bfc_offset;
+ return child_bfc_block_offset;
}
LayoutUnit NGBlockLayoutAlgorithm::FragmentainerSpaceAvailable() const {
- DCHECK(container_builder_.BfcOffset().has_value());
+ DCHECK(container_builder_.BfcBlockOffset());
return ConstraintSpace().FragmentainerSpaceAtBfcStart() -
- container_builder_.BfcOffset()->block_offset;
+ container_builder_.BfcBlockOffset().value();
}
bool NGBlockLayoutAlgorithm::IsFragmentainerOutOfSpace(
LayoutUnit block_offset) const {
if (!ConstraintSpace().HasBlockFragmentation())
return false;
- if (!container_builder_.BfcOffset().has_value())
+ if (!container_builder_.BfcBlockOffset().has_value())
return false;
return block_offset >= FragmentainerSpaceAvailable();
}
@@ -1485,7 +1500,8 @@ void NGBlockLayoutAlgorithm::FinalizeForFragmentation() {
LayoutUnit used_block_size =
BreakToken() ? BreakToken()->UsedBlockSize() : LayoutUnit();
LayoutUnit block_size = ComputeBlockSizeForFragment(
- ConstraintSpace(), Style(), used_block_size + intrinsic_block_size_);
+ ConstraintSpace(), Style(), used_block_size + intrinsic_block_size_,
+ border_padding_);
block_size -= used_block_size;
DCHECK_GE(block_size, LayoutUnit())
@@ -1687,7 +1703,7 @@ NGBlockLayoutAlgorithm::BreakType NGBlockLayoutAlgorithm::BreakTypeBeforeChild(
const NGLayoutResult& layout_result,
LayoutUnit block_offset,
bool is_pushed_by_floats) const {
- if (!container_builder_.BfcOffset().has_value())
+ if (!container_builder_.BfcBlockOffset().has_value())
return NoBreak;
const NGPhysicalFragment& physical_fragment =
@@ -1778,7 +1794,10 @@ NGBoxStrut NGBlockLayoutAlgorithm::CalculateMargins(
// to resolve auto margins before layout, to be able to position child floats
// correctly.
if (!child.CreatesNewFormattingContext()) {
- LayoutUnit child_inline_size = ComputeInlineSizeForFragment(*space, child);
+ NGBoxStrut child_border_padding =
+ ComputeBorders(*space, child) + ComputePadding(*space, child);
+ LayoutUnit child_inline_size =
+ ComputeInlineSizeForFragment(*space, child, child_border_padding);
ResolveInlineMargins(child_style, Style(),
space->AvailableSize().inline_size, child_inline_size,
@@ -1792,7 +1811,7 @@ NGBlockLayoutAlgorithm::CreateConstraintSpaceForChild(
const NGLayoutInputNode child,
const NGInflowChildData& child_data,
const NGLogicalSize child_available_size,
- const base::Optional<NGBfcOffset> floats_bfc_offset) {
+ const base::Optional<LayoutUnit> floats_bfc_block_offset) {
NGConstraintSpaceBuilder space_builder(ConstraintSpace());
NGLogicalSize available_size(child_available_size);
@@ -1817,20 +1836,14 @@ NGBlockLayoutAlgorithm::CreateConstraintSpaceForChild(
.SetBfcOffset(child_data.bfc_offset_estimate)
.SetMarginStrut(child_data.margin_strut);
- if (!is_new_fc) {
- space_builder.SetExclusionSpace(*exclusion_space_);
- space_builder.SetAdjoiningFloatTypes(
- container_builder_.AdjoiningFloatTypes());
- }
-
- if (!container_builder_.BfcOffset() && ConstraintSpace().FloatsBfcOffset()) {
- space_builder.SetFloatsBfcOffset(
- NGBfcOffset{child_data.bfc_offset_estimate.line_offset,
- ConstraintSpace().FloatsBfcOffset()->block_offset});
+ if (!container_builder_.BfcBlockOffset() &&
+ ConstraintSpace().FloatsBfcBlockOffset()) {
+ space_builder.SetFloatsBfcBlockOffset(
+ ConstraintSpace().FloatsBfcBlockOffset().value());
}
- if (floats_bfc_offset)
- space_builder.SetFloatsBfcOffset(floats_bfc_offset);
+ if (floats_bfc_block_offset)
+ space_builder.SetFloatsBfcBlockOffset(floats_bfc_block_offset);
WritingMode writing_mode;
LayoutUnit clearance_offset = constraint_space_.IsNewFormattingContext()
@@ -1855,7 +1868,13 @@ NGBlockLayoutAlgorithm::CreateConstraintSpaceForChild(
}
space_builder.SetClearanceOffset(clearance_offset);
if (child_data.force_clearance)
- space_builder.SetShouldForceClearance();
+ space_builder.SetShouldForceClearance(true);
+
+ if (!is_new_fc) {
+ space_builder.SetExclusionSpace(*exclusion_space_);
+ space_builder.SetAdjoiningFloatTypes(
+ container_builder_.AdjoiningFloatTypes());
+ }
LayoutUnit space_available;
if (ConstraintSpace().HasBlockFragmentation()) {
@@ -1928,8 +1947,7 @@ bool NGBlockLayoutAlgorithm::AddBaseline(const NGBaselineRequest& request,
return true;
}
- LayoutObject* layout_object = child->GetLayoutObject();
- if (layout_object->IsFloatingOrOutOfFlowPositioned())
+ if (child->IsFloatingOrOutOfFlowPositioned())
return false;
if (child->IsBox()) {
@@ -1975,72 +1993,77 @@ void NGBlockLayoutAlgorithm::PropagateBaselinesFromChildren() {
}
}
-bool NGBlockLayoutAlgorithm::ResolveBfcOffset(
+bool NGBlockLayoutAlgorithm::ResolveBfcBlockOffset(
NGPreviousInflowPosition* previous_inflow_position,
LayoutUnit bfc_block_offset) {
- if (container_builder_.BfcOffset()) {
+ if (container_builder_.BfcBlockOffset()) {
DCHECK(unpositioned_floats_.IsEmpty());
return true;
}
- NGBfcOffset bfc_offset(ConstraintSpace().BfcOffset().line_offset,
- bfc_block_offset);
- if (ApplyClearance(ConstraintSpace(), &bfc_offset.block_offset))
+ if (ApplyClearance(ConstraintSpace(), &bfc_block_offset))
container_builder_.SetIsPushedByFloats();
- container_builder_.SetBfcOffset(bfc_offset);
+
+ container_builder_.SetBfcBlockOffset(bfc_block_offset);
container_builder_.ResetAdjoiningFloatTypes();
- if (NeedsAbortOnBfcOffsetChange())
+ if (NeedsAbortOnBfcBlockOffsetChange())
return false;
- // If our BFC offset was updated, we may have been affected by clearance
- // ourselves. We need to adjust the origin point to accomodate this.
- bfc_block_offset = bfc_offset.block_offset;
-
+ // If our BFC block offset was updated, we may have been affected by
+ // clearance ourselves. We need to adjust the origin point to accomodate
+ // this.
PositionPendingFloats(bfc_block_offset);
// Reset the previous inflow position. Clear the margin strut and set the
// offset to our block-start border edge.
//
- // We'll now end up at the block-start border edge. If the BFC offset was
- // resolved due to a block-start border or padding, that must be added by the
- // caller, for subsequent layout to continue at the right position. Whether we
- // need to add border+padding or not isn't something we should determine here,
- // so it must be dealt with as part of initializing the layout algorithm.
+ // We'll now end up at the block-start border edge. If the BFC block offset
+ // was resolved due to a block-start border or padding, that must be added by
+ // the caller, for subsequent layout to continue at the right position.
+ // Whether we need to add border+padding or not isn't something we should
+ // determine here, so it must be dealt with as part of initializing the
+ // layout algorithm.
previous_inflow_position->logical_block_offset = LayoutUnit();
previous_inflow_position->margin_strut = NGMarginStrut();
return true;
}
-bool NGBlockLayoutAlgorithm::NeedsAbortOnBfcOffsetChange() const {
- DCHECK(container_builder_.BfcOffset());
- if (!abort_when_bfc_offset_updated_)
+bool NGBlockLayoutAlgorithm::NeedsAbortOnBfcBlockOffsetChange() const {
+ DCHECK(container_builder_.BfcBlockOffset());
+ if (!abort_when_bfc_block_offset_updated_)
return false;
- // If no previous BFC offset was set, we need to abort.
- if (!ConstraintSpace().FloatsBfcOffset())
+ // If no previous BFC block offset was set, we need to abort.
+ if (!ConstraintSpace().FloatsBfcBlockOffset())
return true;
- // If the previous BFC offset matches the new one, we can continue. Otherwise,
- // we need to abort.
+ // If the previous BFC block offset matches the new one, we can continue.
+ // Otherwise, we need to abort.
LayoutUnit old_bfc_block_offset =
- ConstraintSpace().FloatsBfcOffset()->block_offset;
- return container_builder_.BfcOffset()->block_offset != old_bfc_block_offset;
+ ConstraintSpace().FloatsBfcBlockOffset().value();
+ return container_builder_.BfcBlockOffset().value() != old_bfc_block_offset;
}
void NGBlockLayoutAlgorithm::PositionPendingFloats(
LayoutUnit origin_block_offset) {
- DCHECK(container_builder_.BfcOffset() || ConstraintSpace().FloatsBfcOffset())
- << "The parent BFC offset should be known here";
+ DCHECK(container_builder_.BfcBlockOffset() ||
+ ConstraintSpace().FloatsBfcBlockOffset())
+ << "The parent BFC block offset should be known here";
- NGBfcOffset bfc_offset = container_builder_.BfcOffset()
- ? container_builder_.BfcOffset().value()
- : ConstraintSpace().FloatsBfcOffset().value();
+ NGBfcOffset origin_bfc_offset = {
+ ConstraintSpace().BfcOffset().line_offset +
+ border_scrollbar_padding_.LineLeft(ConstraintSpace().Direction()),
+ origin_block_offset};
- LayoutUnit from_block_offset = bfc_offset.block_offset;
+ LayoutUnit bfc_block_offset =
+ container_builder_.BfcBlockOffset()
+ ? container_builder_.BfcBlockOffset().value()
+ : ConstraintSpace().FloatsBfcBlockOffset().value();
- const auto positioned_floats = PositionFloats(
- origin_block_offset, from_block_offset, unpositioned_floats_,
- ConstraintSpace(), exclusion_space_.get());
+ const auto positioned_floats =
+ PositionFloats(child_available_size_, child_percentage_size_,
+ origin_bfc_offset, bfc_block_offset, unpositioned_floats_,
+ ConstraintSpace(), exclusion_space_.get());
AddPositionedFloats(positioned_floats);
@@ -2049,12 +2072,17 @@ void NGBlockLayoutAlgorithm::PositionPendingFloats(
void NGBlockLayoutAlgorithm::AddPositionedFloats(
const Vector<NGPositionedFloat>& positioned_floats) {
- DCHECK(container_builder_.BfcOffset() || ConstraintSpace().FloatsBfcOffset())
- << "The parent BFC offset should be known here";
+ DCHECK(container_builder_.BfcBlockOffset() ||
+ ConstraintSpace().FloatsBfcBlockOffset())
+ << "The parent BFC block offset should be known here";
+
+ LayoutUnit bfc_block_offset =
+ container_builder_.BfcBlockOffset()
+ ? container_builder_.BfcBlockOffset().value()
+ : ConstraintSpace().FloatsBfcBlockOffset().value();
- NGBfcOffset bfc_offset = container_builder_.BfcOffset()
- ? container_builder_.BfcOffset().value()
- : ConstraintSpace().FloatsBfcOffset().value();
+ LayoutUnit bfc_line_offset = ConstraintSpace().BfcOffset().line_offset;
+ NGBfcOffset bfc_offset = {bfc_line_offset, bfc_block_offset};
// TODO(ikilpatrick): Add DCHECK that any positioned floats are children.
for (const auto& positioned_float : positioned_floats) {
@@ -2100,10 +2128,10 @@ LayoutUnit NGBlockLayoutAlgorithm::CalculateMinimumBlockSize(
LayoutUnit body_block_end_margin =
ComputeMarginsForSelf(ConstraintSpace(), Style()).block_end;
LayoutUnit margin_sum;
- if (container_builder_.BfcOffset()) {
+ if (container_builder_.BfcBlockOffset()) {
NGMarginStrut body_strut = end_margin_strut;
body_strut.Append(body_block_end_margin, /* is_quirky */ false);
- margin_sum = container_builder_.BfcOffset().value().block_offset -
+ margin_sum = container_builder_.BfcBlockOffset().value() -
ConstraintSpace().BfcOffset().block_offset +
body_strut.Sum();
} else {
@@ -2165,10 +2193,10 @@ void NGBlockLayoutAlgorithm::PositionListMarkerWithoutLineBoxes() {
// https://github.com/w3c/csswg-drafts/issues/2418
//
// TODO(kojii): Since this makes this block non-empty, it's probably better to
- // resolve BFC offset if not done yet, but that involves additional complexity
- // without knowing how much this is needed. For now, include the marker into
- // the block size only if BFC was resolved.
- if (container_builder_.BfcOffset()) {
+ // resolve BFC block offset if not done yet, but that involves additional
+ // complexity without knowing how much this is needed. For now, include the
+ // marker into the block size only if BFC was resolved.
+ if (container_builder_.BfcBlockOffset()) {
intrinsic_block_size_ = std::max(marker_block_size, intrinsic_block_size_);
container_builder_.SetIntrinsicBlockSize(intrinsic_block_size_);
container_builder_.SetBlockSize(
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 6e979c6e022..dab8d19c237 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
@@ -12,6 +12,8 @@
#include "third_party/blink/renderer/core/layout/ng/ng_block_node.h"
#include "third_party/blink/renderer/core/layout/ng/ng_fragment_builder.h"
#include "third_party/blink/renderer/core/layout/ng/ng_layout_algorithm.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_unpositioned_float.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_unpositioned_float_vector.h"
namespace blink {
@@ -55,22 +57,25 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
~NGBlockLayoutAlgorithm() override;
+ void SetBoxType(NGPhysicalFragment::NGBoxType type);
+
base::Optional<MinMaxSize> ComputeMinMaxSize(
const MinMaxSizeInput&) const override;
scoped_refptr<NGLayoutResult> Layout() override;
private:
- // Return the BFC offset of this block.
+ // Return the BFC block offset of this block.
LayoutUnit BfcBlockOffset() const {
- // If we have resolved our BFC offset, use that.
- if (container_builder_.BfcOffset())
- return container_builder_.BfcOffset()->block_offset;
- // Otherwise fall back to the BFC offset assigned by the parent algorithm.
+ // If we have resolved our BFC block offset, use that.
+ if (container_builder_.BfcBlockOffset())
+ return *container_builder_.BfcBlockOffset();
+ // Otherwise fall back to the BFC block offset assigned by the parent
+ // algorithm.
return ConstraintSpace().BfcOffset().block_offset;
}
- // Return the BFC offset of the next block-start border edge (for some child)
- // we'd get if we commit pending margins.
+ // Return the BFC block offset of the next block-start border edge (for some
+ // child) we'd get if we commit pending margins.
LayoutUnit NextBorderEdge(
const NGPreviousInflowPosition& previous_inflow_position) const {
return BfcBlockOffset() + previous_inflow_position.logical_block_offset +
@@ -85,32 +90,32 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
const NGLayoutInputNode child,
const NGInflowChildData& child_data,
const NGLogicalSize child_available_size,
- const base::Optional<NGBfcOffset> floats_bfc_offset = base::nullopt);
+ const base::Optional<LayoutUnit> floats_bfc_block_offset = base::nullopt);
- // @return Estimated BFC offset for the "to be layout" child.
+ // @return Estimated BFC block offset for the "to be layout" child.
NGInflowChildData ComputeChildData(const NGPreviousInflowPosition&,
NGLayoutInputNode,
const NGBreakToken* child_break_token,
bool force_clearance);
NGPreviousInflowPosition ComputeInflowPosition(
- const NGPreviousInflowPosition& previous_inflow_position,
+ const NGPreviousInflowPosition&,
const NGLayoutInputNode child,
- const NGInflowChildData& child_data,
- const base::Optional<NGBfcOffset>& child_bfc_offset,
- const NGLogicalOffset& logical_offset,
- const NGLayoutResult& layout_result,
- const NGFragment& fragment,
+ const NGInflowChildData&,
+ const base::Optional<LayoutUnit>& child_bfc_block_offset,
+ const NGLogicalOffset&,
+ const NGLayoutResult&,
+ const NGFragment&,
bool empty_block_affected_by_clearance);
- // Position an empty child using the parent BFC offset.
+ // Position an empty child using the parent BFC block offset.
// The fragment doesn't know its offset, but we can still calculate its BFC
// position because the parent fragment's BFC is known.
// Example:
// BFC Offset is known here because of the padding.
// <div style="padding: 1px">
// <div id="empty-div" style="margin: 1px"></div>
- NGBfcOffset PositionEmptyChildWithParentBfc(
+ LayoutUnit PositionEmptyChildWithParentBfc(
const NGLayoutInputNode& child,
const NGConstraintSpace& child_space,
const NGInflowChildData& child_data,
@@ -137,7 +142,7 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
// below #float ignoring its vertical margin.
//
// Returns false if we need to abort layout, because a previously unknown BFC
- // offset has now been resolved.
+ // block offset has now been resolved.
bool HandleNewFormattingContext(
NGLayoutInputNode child,
NGBreakToken* child_break_token,
@@ -150,12 +155,12 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
LayoutNewFormattingContext(NGLayoutInputNode child,
NGBreakToken* child_break_token,
const NGInflowChildData&,
- LayoutUnit child_origin_block_offset,
+ NGBfcOffset origin_offset,
bool abort_if_cleared);
// Handle an in-flow child.
// Returns false if we need to abort layout, because a previously unknown BFC
- // offset has now been resolved. (Same as HandleNewFormattingContext).
+ // block offset has now been resolved. (Same as HandleNewFormattingContext).
bool HandleInflow(NGLayoutInputNode child,
NGBreakToken* child_break_token,
NGPreviousInflowPosition*,
@@ -207,29 +212,32 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
const NGPhysicalLineBoxFragment&,
LayoutUnit line_box_block_offset) const;
- // If still unresolved, resolve the fragment's BFC offset.
+ // If still unresolved, resolve the fragment's BFC block offset.
//
// This includes applying clearance, so the bfc_block_offset passed won't be
- // the final BFC offset, if it wasn't large enough to get past all relevant
- // floats. The updated BFC offset can be read out with ContainerBfcOffset().
+ // the final BFC block offset, if it wasn't large enough to get past all
+ // relevant floats. The updated BFC block offset can be read out with
+ // ContainerBfcBlockOffset().
//
- // In addition to resolving our BFC offset, this will also position pending
- // floats, and update our in-flow layout state. Returns false if resolving the
- // BFC offset resulted in needing to abort layout. It will always return true
- // otherwise. If the BFC offset was already resolved, this method does nothing
- // (and returns true).
- bool ResolveBfcOffset(NGPreviousInflowPosition*, LayoutUnit bfc_block_offset);
-
- // A very common way to resolve the BFC offset is to simply commit the pending
- // margin, so here's a convenience overload for that.
- bool ResolveBfcOffset(NGPreviousInflowPosition* previous_inflow_position) {
- return ResolveBfcOffset(previous_inflow_position,
- NextBorderEdge(*previous_inflow_position));
+ // In addition to resolving our BFC block offset, this will also position
+ // pending floats, and update our in-flow layout state. Returns false if
+ // resolving the BFC block offset resulted in needing to abort layout. It
+ // will always return true otherwise. If the BFC block offset was already
+ // resolved, this method does nothing (and returns true).
+ bool ResolveBfcBlockOffset(NGPreviousInflowPosition*,
+ LayoutUnit bfc_block_offset);
+
+ // A very common way to resolve the BFC block offset is to simply commit the
+ // pending margin, so here's a convenience overload for that.
+ bool ResolveBfcBlockOffset(
+ NGPreviousInflowPosition* previous_inflow_position) {
+ return ResolveBfcBlockOffset(previous_inflow_position,
+ NextBorderEdge(*previous_inflow_position));
}
- // Return true if the BFC offset has changed and this means that we need to
- // abort layout.
- bool NeedsAbortOnBfcOffsetChange() const;
+ // Return true if the BFC block offset has changed and this means that we
+ // need to abort layout.
+ bool NeedsAbortOnBfcBlockOffsetChange() const;
// Positions pending floats starting from {@origin_block_offset}.
void PositionPendingFloats(LayoutUnit origin_block_offset);
@@ -248,10 +256,9 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
// {@code known_fragment_offset} if the fragment knows it's offset
// @return Fragment's offset relative to the fragment's parent.
NGLogicalOffset CalculateLogicalOffset(
- NGLayoutInputNode child,
- const NGFragment&,
- const NGBoxStrut& child_margins,
- const base::Optional<NGBfcOffset>& known_fragment_offset);
+ const NGFragment& fragment,
+ LayoutUnit child_bfc_line_offset,
+ const base::Optional<LayoutUnit>& child_bfc_block_offset);
// Computes default content size for HTML and BODY elements in quirks mode.
// Returns NGSizeIndefinite in all other cases.
@@ -264,6 +271,7 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
NGLogicalSize child_available_size_;
NGLogicalSize child_percentage_size_;
+ NGBoxStrut border_padding_;
NGBoxStrut border_scrollbar_padding_;
LayoutUnit intrinsic_block_size_;
@@ -281,18 +289,18 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
// Set if we're resuming layout of a node that has already produced fragments.
bool is_resuming_;
- // Set when we're to abort if the BFC offset gets resolved or updated.
- // Sometimes we walk past elements (i.e. floats) that depend on the BFC offset
- // being known (in order to position and lay themselves out properly). When
- // this happens, and we finally manage to resolve (or update) the BFC offset
- // at some subsequent element, we need to check if this flag is set, and abort
- // layout if it is.
- bool abort_when_bfc_offset_updated_ = false;
+ // Set when we're to abort if the BFC block offset gets resolved or updated.
+ // Sometimes we walk past elements (i.e. floats) that depend on the BFC block
+ // offset being known (in order to position and lay themselves out properly).
+ // When this happens, and we finally manage to resolve (or update) the BFC
+ // block offset at some subsequent element, we need to check if this flag is
+ // set, and abort layout if it is.
+ bool abort_when_bfc_block_offset_updated_ = false;
bool has_processed_first_child_ = false;
std::unique_ptr<NGExclusionSpace> exclusion_space_;
- Vector<scoped_refptr<NGUnpositionedFloat>> unpositioned_floats_;
+ NGUnpositionedFloatVector unpositioned_floats_;
};
} // namespace blink
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 4103730530c..b796cc0b8e0 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();
}
- scoped_refptr<NGPhysicalBoxFragment> RunBlockLayoutAlgorithm(
+ scoped_refptr<const NGPhysicalBoxFragment> RunBlockLayoutAlgorithm(
const NGConstraintSpace& space,
NGBlockNode node) {
scoped_refptr<NGLayoutResult> result =
@@ -87,7 +87,8 @@ TEST_F(NGBlockLayoutAlgorithmTest, FixedSize) {
NGBlockNode box(ToLayoutBox(GetLayoutObjectByElementId("box")));
- scoped_refptr<NGPhysicalFragment> frag = RunBlockLayoutAlgorithm(*space, box);
+ scoped_refptr<const NGPhysicalFragment> frag =
+ RunBlockLayoutAlgorithm(*space, box);
EXPECT_EQ(NGPhysicalSize(LayoutUnit(30), LayoutUnit(40)), frag->Size());
}
@@ -157,7 +158,7 @@ TEST_F(NGBlockLayoutAlgorithmTest, LayoutBlockChildren) {
WritingMode::kHorizontalTb, TextDirection::kLtr,
NGLogicalSize(LayoutUnit(100), NGSizeIndefinite));
- scoped_refptr<NGPhysicalBoxFragment> frag =
+ scoped_refptr<const NGPhysicalBoxFragment> frag =
RunBlockLayoutAlgorithm(*space, container);
EXPECT_EQ(LayoutUnit(kWidth), frag->Size().width);
@@ -165,13 +166,13 @@ TEST_F(NGBlockLayoutAlgorithmTest, LayoutBlockChildren) {
EXPECT_EQ(NGPhysicalFragment::kFragmentBox, frag->Type());
ASSERT_EQ(frag->Children().size(), 2UL);
- const NGPhysicalFragment* first_child_fragment = frag->Children()[0].get();
- EXPECT_EQ(kHeight1, first_child_fragment->Size().height);
- EXPECT_EQ(0, first_child_fragment->Offset().top);
+ const NGLink& first_child = frag->Children()[0];
+ EXPECT_EQ(kHeight1, first_child->Size().height);
+ EXPECT_EQ(0, first_child.Offset().top);
- const NGPhysicalFragment* second_child_fragment = frag->Children()[1].get();
- EXPECT_EQ(kHeight2, second_child_fragment->Size().height);
- EXPECT_EQ(kHeight1 + kMarginTop, second_child_fragment->Offset().top);
+ const NGLink& second_child = frag->Children()[1];
+ EXPECT_EQ(kHeight2, second_child->Size().height);
+ EXPECT_EQ(kHeight1 + kMarginTop, second_child.Offset().top);
}
// Verifies that a child is laid out correctly if it's writing mode is different
@@ -201,16 +202,16 @@ TEST_F(NGBlockLayoutAlgorithmTest, LayoutBlockChildrenWithWritingMode) {
ConstructBlockLayoutTestConstraintSpace(
WritingMode::kHorizontalTb, TextDirection::kLtr,
NGLogicalSize(LayoutUnit(500), LayoutUnit(500)));
- scoped_refptr<NGPhysicalBoxFragment> frag =
+ scoped_refptr<const NGPhysicalBoxFragment> frag =
RunBlockLayoutAlgorithm(*space, container);
- const NGPhysicalFragment* child = frag->Children()[0].get();
- // DIV2
- child = static_cast<const NGPhysicalBoxFragment*>(child)->Children()[0].get();
+ const NGLink& child = frag->Children()[0];
+ const NGLink& child2 =
+ static_cast<const NGPhysicalBoxFragment*>(child.get())->Children()[0];
- EXPECT_EQ(kHeight, child->Size().height);
- EXPECT_EQ(0, child->Offset().top);
- EXPECT_EQ(kMarginLeft, child->Offset().left);
+ EXPECT_EQ(kHeight, child2->Size().height);
+ EXPECT_EQ(0, child2.Offset().top);
+ EXPECT_EQ(kMarginLeft, child2.Offset().left);
}
// Verifies that floats are positioned at the top of the first child that can
@@ -254,27 +255,32 @@ TEST_F(NGBlockLayoutAlgorithmTest, CollapsingMarginsCase1WithFloats) {
// ** Run LayoutNG algorithm **
scoped_refptr<NGConstraintSpace> space;
- scoped_refptr<NGPhysicalBoxFragment> fragment;
+ scoped_refptr<const NGPhysicalBoxFragment> fragment;
std::tie(fragment, space) = RunBlockLayoutAlgorithmForElement(
GetDocument().getElementsByTagName("html")->item(0));
ASSERT_EQ(fragment->Children().size(), 1UL);
+ NGPhysicalOffset body_offset = fragment->Children()[0].Offset();
auto* body_fragment = ToNGPhysicalBoxFragment(fragment->Children()[0].get());
// 20 = max(first child's margin top, containers's margin top)
int body_top_offset = 20;
- EXPECT_THAT(LayoutUnit(body_top_offset), body_fragment->Offset().top);
+ EXPECT_THAT(LayoutUnit(body_top_offset), body_offset.top);
// 8 = body's margin
int body_left_offset = 8;
- EXPECT_THAT(LayoutUnit(body_left_offset), body_fragment->Offset().left);
+ EXPECT_THAT(LayoutUnit(body_left_offset), body_offset.left);
ASSERT_EQ(1UL, body_fragment->Children().size());
+
auto* container_fragment =
ToNGPhysicalBoxFragment(body_fragment->Children()[0].get());
+ NGPhysicalOffset container_offset = body_fragment->Children()[0].Offset();
+
// 0 = collapsed with body's margin
- EXPECT_THAT(LayoutUnit(0), container_fragment->Offset().top);
+ EXPECT_THAT(LayoutUnit(0), container_offset.top);
ASSERT_EQ(3UL, container_fragment->Children().size());
- auto* first_child_fragment =
- ToNGPhysicalBoxFragment(container_fragment->Children()[2].get());
+
+ NGPhysicalOffset child_offset = container_fragment->Children()[2].Offset();
+
// 0 = collapsed with container's margin
- EXPECT_THAT(LayoutUnit(0), first_child_fragment->Offset().top);
+ EXPECT_THAT(LayoutUnit(0), child_offset.top);
}
// Verifies the collapsing margins case for the next pairs:
@@ -330,32 +336,34 @@ TEST_F(NGBlockLayoutAlgorithmTest, CollapsingMarginsCase2WithFloats) {
// ** Run LayoutNG algorithm **
scoped_refptr<NGConstraintSpace> space;
- scoped_refptr<NGPhysicalBoxFragment> fragment;
+ scoped_refptr<const NGPhysicalBoxFragment> fragment;
std::tie(fragment, space) = RunBlockLayoutAlgorithmForElement(
GetDocument().getElementsByTagName("html")->item(0));
auto* body_fragment = ToNGPhysicalBoxFragment(fragment->Children()[0].get());
+ NGPhysicalOffset body_offset = fragment->Children()[0].Offset();
// -7 = empty1's margin(-15) + body's margin(8)
- EXPECT_THAT(LayoutUnit(-7), body_fragment->Offset().top);
+ EXPECT_THAT(LayoutUnit(-7), body_offset.top);
ASSERT_EQ(4UL, body_fragment->Children().size());
FragmentChildIterator iterator(body_fragment);
- const auto* first_child_fragment = iterator.NextChild();
- EXPECT_THAT(LayoutUnit(), first_child_fragment->Offset().top);
+ NGPhysicalOffset offset;
+ iterator.NextChild(&offset);
+ EXPECT_THAT(LayoutUnit(), offset.top);
- const auto* float_nonempties_fragment = iterator.NextChild();
+ iterator.NextChild(&offset);
// 70 = first_child's height(50) + first child's margin-bottom(20)
- EXPECT_THAT(float_nonempties_fragment->Offset().top, LayoutUnit(70));
- EXPECT_THAT(float_nonempties_fragment->Offset().left, LayoutUnit(0));
+ EXPECT_THAT(offset.top, LayoutUnit(70));
+ EXPECT_THAT(offset.left, LayoutUnit(0));
- const auto* second_child_fragment = iterator.NextChild();
+ iterator.NextChild(&offset);
// 40 = first_child's height(50) - margin's collapsing result(10)
- EXPECT_THAT(LayoutUnit(40), second_child_fragment->Offset().top);
+ EXPECT_THAT(LayoutUnit(40), offset.top);
- const auto* empty5_fragment = iterator.NextChild();
+ iterator.NextChild(&offset);
// 90 = first_child's height(50) + collapsed margins(-10) +
// second child's height(50)
- EXPECT_THAT(LayoutUnit(90), empty5_fragment->Offset().top);
+ EXPECT_THAT(LayoutUnit(90), offset.top);
// ** Verify layout tree **
Element* first_child = GetDocument().getElementById("first-child");
@@ -434,9 +442,9 @@ TEST_F(NGBlockLayoutAlgorithmTest, CollapsingMarginsCase4) {
</div>
)HTML");
- const NGPhysicalBoxFragment* body_fragment;
- const NGPhysicalBoxFragment* container_fragment;
- const NGPhysicalBoxFragment* child_fragment;
+ NGPhysicalOffset body_offset;
+ NGPhysicalOffset container_offset;
+ NGPhysicalOffset child_offset;
scoped_refptr<const NGPhysicalBoxFragment> fragment;
auto run_test = [&](const Length& container_padding_top) {
Element* container = GetDocument().getElementById("container");
@@ -445,12 +453,14 @@ TEST_F(NGBlockLayoutAlgorithmTest, CollapsingMarginsCase4) {
std::tie(fragment, std::ignore) = RunBlockLayoutAlgorithmForElement(
GetDocument().getElementsByTagName("html")->item(0));
ASSERT_EQ(1UL, fragment->Children().size());
- body_fragment = ToNGPhysicalBoxFragment(fragment->Children()[0].get());
- container_fragment =
+ const NGPhysicalBoxFragment* body_fragment =
+ ToNGPhysicalBoxFragment(fragment->Children()[0].get());
+ body_offset = fragment->Children()[0].Offset();
+ const NGPhysicalBoxFragment* container_fragment =
ToNGPhysicalBoxFragment(body_fragment->Children()[0].get());
+ container_offset = body_fragment->Children()[0].Offset();
ASSERT_EQ(1UL, container_fragment->Children().size());
- child_fragment =
- ToNGPhysicalBoxFragment(container_fragment->Children()[0].get());
+ child_offset = container_fragment->Children()[0].Offset();
};
// with padding
@@ -459,9 +469,9 @@ TEST_F(NGBlockLayoutAlgorithmTest, CollapsingMarginsCase4) {
// container's margin 30
EXPECT_EQ(NGPhysicalSize(LayoutUnit(800), LayoutUnit(500)), fragment->Size());
// 30 = max(body's margin 8, container margin 30)
- EXPECT_EQ(LayoutUnit(30), body_fragment->Offset().top);
+ EXPECT_EQ(LayoutUnit(30), body_offset.top);
// 220 = container's padding top 20 + child's margin
- EXPECT_EQ(LayoutUnit(220), child_fragment->Offset().top);
+ EXPECT_EQ(LayoutUnit(220), child_offset.top);
// without padding
run_test(Length(0, kFixed));
@@ -469,9 +479,9 @@ TEST_F(NGBlockLayoutAlgorithmTest, CollapsingMarginsCase4) {
// child's height 50
EXPECT_EQ(NGPhysicalSize(LayoutUnit(800), LayoutUnit(450)), fragment->Size());
// 200 = (body's margin 8, container's margin 30, child's margin 200)
- EXPECT_EQ(LayoutUnit(200), body_fragment->Offset().top);
+ EXPECT_EQ(LayoutUnit(200), body_offset.top);
// 0 = collapsed margins
- EXPECT_EQ(LayoutUnit(0), child_fragment->Offset().top);
+ EXPECT_EQ(LayoutUnit(0), child_offset.top);
}
// Verifies that margins of 2 adjoining blocks with different writing modes
@@ -502,17 +512,18 @@ TEST_F(NGBlockLayoutAlgorithmTest, CollapsingMarginsCase5) {
<div id='horizontal'></div>
</div>
)HTML");
- scoped_refptr<NGPhysicalBoxFragment> fragment;
+ scoped_refptr<const NGPhysicalBoxFragment> fragment;
std::tie(fragment, std::ignore) = RunBlockLayoutAlgorithmForElement(
GetDocument().getElementsByTagName("html")->item(0));
// body
auto* body_fragment = ToNGPhysicalBoxFragment(fragment->Children()[0].get());
+ NGPhysicalOffset body_offset = fragment->Children()[0].Offset();
// 10 = std::max(body's margin 8, container's margin top)
int body_top_offset = 10;
- EXPECT_THAT(body_fragment->Offset().top, LayoutUnit(body_top_offset));
+ EXPECT_THAT(body_offset.top, LayoutUnit(body_top_offset));
int body_left_offset = 8;
- EXPECT_THAT(body_fragment->Offset().left, LayoutUnit(body_left_offset));
+ EXPECT_THAT(body_offset.left, LayoutUnit(body_left_offset));
// height = 70. std::max(vertical height's 70, horizontal's height's 60)
ASSERT_EQ(NGPhysicalSize(LayoutUnit(784), LayoutUnit(70)),
@@ -522,24 +533,24 @@ TEST_F(NGBlockLayoutAlgorithmTest, CollapsingMarginsCase5) {
// container
auto* container_fragment =
ToNGPhysicalBoxFragment(body_fragment->Children()[0].get());
+ NGPhysicalOffset container_offset = body_fragment->Children()[0].Offset();
// Container's margins are collapsed with body's fragment.
- EXPECT_THAT(container_fragment->Offset().top, LayoutUnit());
- EXPECT_THAT(container_fragment->Offset().left, LayoutUnit());
+ EXPECT_THAT(container_offset.top, LayoutUnit());
+ EXPECT_THAT(container_offset.left, LayoutUnit());
ASSERT_EQ(2UL, container_fragment->Children().size());
// vertical
- auto* vertical_fragment =
- ToNGPhysicalBoxFragment(container_fragment->Children()[0].get());
- EXPECT_THAT(vertical_fragment->Offset().top, LayoutUnit());
- EXPECT_THAT(vertical_fragment->Offset().left, LayoutUnit());
+ NGPhysicalOffset vertical_offset = container_fragment->Children()[0].Offset();
+ EXPECT_THAT(vertical_offset.top, LayoutUnit());
+ EXPECT_THAT(vertical_offset.left, LayoutUnit());
// horizontal
- auto* horizontal_fragment =
- ToNGPhysicalBoxFragment(container_fragment->Children()[1].get());
- EXPECT_THAT(horizontal_fragment->Offset().top, LayoutUnit());
+ NGPhysicalOffset orizontal_offset =
+ container_fragment->Children()[1].Offset();
+ EXPECT_THAT(orizontal_offset.top, LayoutUnit());
// 130 = vertical's width 30 +
// std::max(vertical's margin right 90, horizontal's margin-left 100)
- EXPECT_THAT(horizontal_fragment->Offset().left, LayoutUnit(130));
+ EXPECT_THAT(orizontal_offset.left, LayoutUnit(130));
}
// Verifies that margins collapsing logic works with Layout Inline.
@@ -556,21 +567,19 @@ TEST_F(NGBlockLayoutAlgorithmTest, CollapsingMarginsWithText) {
</style>
<p>Some text</p>
)HTML");
- scoped_refptr<NGPhysicalBoxFragment> html_fragment;
+ scoped_refptr<const NGPhysicalBoxFragment> html_fragment;
std::tie(html_fragment, std::ignore) = RunBlockLayoutAlgorithmForElement(
GetDocument().getElementsByTagName("html")->item(0));
- auto* body_fragment =
+ const NGPhysicalBoxFragment* body_fragment =
ToNGPhysicalBoxFragment(html_fragment->Children()[0].get());
+ NGPhysicalOffset body_offset = html_fragment->Children()[0].Offset();
// 20 = std::max(body's margin, p's margin)
- EXPECT_THAT(body_fragment->Offset(),
- NGPhysicalOffset(LayoutUnit(10), LayoutUnit(20)));
+ EXPECT_THAT(body_offset, NGPhysicalOffset(LayoutUnit(10), LayoutUnit(20)));
- auto* p_fragment =
- ToNGPhysicalBoxFragment(body_fragment->Children()[0].get());
+ NGPhysicalOffset p_offset = body_fragment->Children()[0].Offset();
// Collapsed margins with result = 0.
- EXPECT_THAT(p_fragment->Offset(),
- NGPhysicalOffset(LayoutUnit(20), LayoutUnit(0)));
+ EXPECT_THAT(p_offset, NGPhysicalOffset(LayoutUnit(20), LayoutUnit(0)));
}
// Verifies that the margin strut of a child with a different writing mode does
@@ -603,18 +612,18 @@ TEST_F(NGBlockLayoutAlgorithmTest, CollapsingMarginsCase6) {
ConstructBlockLayoutTestConstraintSpace(
WritingMode::kHorizontalTb, TextDirection::kLtr,
NGLogicalSize(LayoutUnit(500), LayoutUnit(500)));
- scoped_refptr<NGPhysicalBoxFragment> frag =
+ scoped_refptr<const NGPhysicalBoxFragment> frag =
RunBlockLayoutAlgorithm(*space, container);
ASSERT_EQ(frag->Children().size(), 2UL);
const NGPhysicalFragment* child1 = frag->Children()[0].get();
- EXPECT_EQ(0, child1->Offset().top);
+ NGPhysicalOffset child1_offset = frag->Children()[0].Offset();
+ EXPECT_EQ(0, child1_offset.top);
EXPECT_EQ(kHeight, child1->Size().height);
- const NGPhysicalFragment* child2 = frag->Children()[1].get();
- EXPECT_EQ(kHeight + std::max(kMarginBottom, kMarginTop),
- child2->Offset().top);
+ NGPhysicalOffset child2_offset = frag->Children()[1].Offset();
+ EXPECT_EQ(kHeight + std::max(kMarginBottom, kMarginTop), child2_offset.top);
}
// Verifies that a child with clearance - which does nothing - still shifts its
@@ -650,27 +659,28 @@ TEST_F(NGBlockLayoutAlgorithmTest, CollapsingMarginsCase7) {
<div id="inflow"></div>
)HTML");
- scoped_refptr<NGPhysicalBoxFragment> fragment;
+ scoped_refptr<const NGPhysicalBoxFragment> fragment;
std::tie(fragment, std::ignore) = RunBlockLayoutAlgorithmForElement(
GetDocument().getElementsByTagName("html")->item(0));
FragmentChildIterator iterator(fragment.get());
// body
- const NGPhysicalBoxFragment* child = iterator.NextChild();
+ NGPhysicalOffset offset;
+ const NGPhysicalBoxFragment* child = iterator.NextChild(&offset);
EXPECT_EQ(NGPhysicalSize(LayoutUnit(200), LayoutUnit(20)), child->Size());
- EXPECT_EQ(NGPhysicalOffset(LayoutUnit(8), LayoutUnit(20)), child->Offset());
+ EXPECT_EQ(NGPhysicalOffset(LayoutUnit(8), LayoutUnit(20)), offset);
// #zero
iterator.SetParent(child);
- child = iterator.NextChild();
+ child = iterator.NextChild(&offset);
EXPECT_EQ(NGPhysicalSize(LayoutUnit(200), LayoutUnit(0)), child->Size());
- EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(0)), child->Offset());
+ EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(0)), offset);
// #inflow
- child = iterator.NextChild();
+ child = iterator.NextChild(&offset);
EXPECT_EQ(NGPhysicalSize(LayoutUnit(200), LayoutUnit(20)), child->Size());
- EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(0)), child->Offset());
+ EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(0)), offset);
}
// An empty block level element (with margins collapsing through it) has
@@ -906,7 +916,7 @@ TEST_F(NGBlockLayoutAlgorithmTest, BorderAndPadding) {
WritingMode::kHorizontalTb, TextDirection::kLtr,
NGLogicalSize(LayoutUnit(1000), NGSizeIndefinite));
- scoped_refptr<NGPhysicalBoxFragment> frag =
+ scoped_refptr<const NGPhysicalBoxFragment> frag =
RunBlockLayoutAlgorithm(*space, container);
ASSERT_EQ(frag->Children().size(), 1UL);
@@ -922,10 +932,10 @@ TEST_F(NGBlockLayoutAlgorithmTest, BorderAndPadding) {
ASSERT_EQ(static_cast<const NGPhysicalBoxFragment*>(child)->Children().size(),
1UL);
- // div2
- child = static_cast<const NGPhysicalBoxFragment*>(child)->Children()[0].get();
- EXPECT_EQ(kBorderTop + kPaddingTop, child->Offset().top);
- EXPECT_EQ(kBorderLeft + kPaddingLeft, child->Offset().left);
+ NGPhysicalOffset div2_offset =
+ static_cast<const NGPhysicalBoxFragment*>(child)->Children()[0].Offset();
+ EXPECT_EQ(kBorderTop + kPaddingTop, div2_offset.top);
+ EXPECT_EQ(kBorderLeft + kPaddingLeft, div2_offset.left);
}
TEST_F(NGBlockLayoutAlgorithmTest, PercentageResolutionSize) {
@@ -943,7 +953,7 @@ TEST_F(NGBlockLayoutAlgorithmTest, PercentageResolutionSize) {
ConstructBlockLayoutTestConstraintSpace(
WritingMode::kHorizontalTb, TextDirection::kLtr,
NGLogicalSize(LayoutUnit(100), NGSizeIndefinite));
- scoped_refptr<NGPhysicalBoxFragment> frag =
+ scoped_refptr<const NGPhysicalBoxFragment> frag =
RunBlockLayoutAlgorithm(*space, container);
EXPECT_EQ(LayoutUnit(kWidth + kPaddingLeft), frag->Size().width);
@@ -976,7 +986,7 @@ TEST_F(NGBlockLayoutAlgorithmTest, AutoMargin) {
ConstructBlockLayoutTestConstraintSpace(
WritingMode::kHorizontalTb, TextDirection::kLtr,
NGLogicalSize(LayoutUnit(100), NGSizeIndefinite));
- scoped_refptr<NGPhysicalBoxFragment> frag =
+ scoped_refptr<const NGPhysicalBoxFragment> frag =
RunBlockLayoutAlgorithm(*space, container);
EXPECT_EQ(LayoutUnit(kWidth + kPaddingLeft), frag->Size().width);
@@ -984,9 +994,10 @@ TEST_F(NGBlockLayoutAlgorithmTest, AutoMargin) {
ASSERT_EQ(1UL, frag->Children().size());
const NGPhysicalFragment* child = frag->Children()[0].get();
+ NGPhysicalOffset child_offset = frag->Children()[0].Offset();
EXPECT_EQ(LayoutUnit(kChildWidth), child->Size().width);
- EXPECT_EQ(LayoutUnit(kPaddingLeft + 10), child->Offset().left);
- EXPECT_EQ(LayoutUnit(0), child->Offset().top);
+ EXPECT_EQ(LayoutUnit(kPaddingLeft + 10), child_offset.left);
+ EXPECT_EQ(LayoutUnit(0), child_offset.top);
}
// Verifies that floats can be correctly positioned if they are inside of nested
@@ -1035,51 +1046,51 @@ TEST_F(NGBlockLayoutAlgorithmTest, PositionFloatInsideEmptyBlocks) {
// ** Run LayoutNG algorithm **
scoped_refptr<NGConstraintSpace> space;
- scoped_refptr<NGPhysicalBoxFragment> fragment;
+ scoped_refptr<const NGPhysicalBoxFragment> fragment;
std::tie(fragment, space) = RunBlockLayoutAlgorithmForElement(
GetDocument().getElementsByTagName("html")->item(0));
const auto* body_fragment =
ToNGPhysicalBoxFragment(fragment->Children()[0].get());
+ NGPhysicalOffset body_offset = fragment->Children()[0].Offset();
FragmentChildIterator iterator(body_fragment);
// 20 = std::max(empty1's margin, empty2's margin, body's margin)
int body_top_offset = 20;
- EXPECT_THAT(body_fragment->Offset().top, LayoutUnit(body_top_offset));
+ EXPECT_THAT(body_offset.top, LayoutUnit(body_top_offset));
ASSERT_EQ(1UL, body_fragment->Children().size());
const auto* container_fragment = iterator.NextChild();
ASSERT_EQ(1UL, container_fragment->Children().size());
iterator.SetParent(container_fragment);
- const auto* empty1_fragment = iterator.NextChild();
+ NGPhysicalOffset offset;
+ const auto* empty1_fragment = iterator.NextChild(&offset);
// 0, vertical margins got collapsed
- EXPECT_THAT(empty1_fragment->Offset().top, LayoutUnit());
+ EXPECT_THAT(offset.top, LayoutUnit());
// 20 empty1's margin
- EXPECT_THAT(empty1_fragment->Offset().left, LayoutUnit(20));
+ EXPECT_THAT(offset.left, LayoutUnit(20));
ASSERT_EQ(empty1_fragment->Children().size(), 1UL);
iterator.SetParent(empty1_fragment);
- const auto* empty2_fragment = iterator.NextChild();
+ const auto* empty2_fragment = iterator.NextChild(&offset);
// 0, vertical margins got collapsed
- EXPECT_THAT(LayoutUnit(), empty2_fragment->Offset().top);
+ EXPECT_THAT(LayoutUnit(), offset.top);
// 35 = empty1's padding(20) + empty2's padding(15)
- EXPECT_THAT(empty2_fragment->Offset().left, LayoutUnit(35));
+ EXPECT_THAT(offset.left, LayoutUnit(35));
iterator.SetParent(empty2_fragment);
- const auto* left_float_fragment = iterator.NextChild();
+ iterator.NextChild(&offset);
// inline 25 = empty2's padding(15) + left float's margin(10)
// block 10 = left float's margin
- EXPECT_THAT(left_float_fragment->Offset(),
- NGPhysicalOffset(LayoutUnit(25), LayoutUnit(10)));
+ EXPECT_THAT(offset, NGPhysicalOffset(LayoutUnit(25), LayoutUnit(10)));
- const auto* right_float_fragment = iterator.NextChild();
+ iterator.NextChild(&offset);
// inline offset 150 = empty2's padding(15) + right float's margin(10) + right
// float offset(125)
// block offset 15 = right float's margin
LayoutUnit right_float_offset = LayoutUnit(125);
- EXPECT_THAT(
- right_float_fragment->Offset(),
- NGPhysicalOffset(LayoutUnit(25) + right_float_offset, LayoutUnit(15)));
+ EXPECT_THAT(offset, NGPhysicalOffset(LayoutUnit(25) + right_float_offset,
+ LayoutUnit(15)));
// ** Verify layout tree **
Element* left_float = GetDocument().getElementById("left-float");
@@ -1164,7 +1175,7 @@ TEST_F(NGBlockLayoutAlgorithmTest, PositionFloatFragments) {
// ** Run LayoutNG algorithm **
scoped_refptr<NGConstraintSpace> space;
- scoped_refptr<NGPhysicalBoxFragment> fragment;
+ scoped_refptr<const NGPhysicalBoxFragment> fragment;
std::tie(fragment, space) = RunBlockLayoutAlgorithmForElement(
GetDocument().getElementsByTagName("html")->item(0));
@@ -1172,7 +1183,8 @@ TEST_F(NGBlockLayoutAlgorithmTest, PositionFloatFragments) {
ASSERT_EQ(1UL, fragment->Children().size());
const auto* body_fragment =
ToNGPhysicalBoxFragment(fragment->Children()[0].get());
- EXPECT_THAT(LayoutUnit(8), body_fragment->Offset().top);
+ NGPhysicalOffset body_offset = fragment->Children()[0].Offset();
+ EXPECT_THAT(LayoutUnit(8), body_offset.top);
FragmentChildIterator iterator(body_fragment);
const auto* container_fragment = iterator.NextChild();
@@ -1184,8 +1196,9 @@ TEST_F(NGBlockLayoutAlgorithmTest, PositionFloatFragments) {
EXPECT_EQ(8, left_float->OffsetTop());
iterator.SetParent(container_fragment);
- const auto* left_float_fragment = iterator.NextChild();
- EXPECT_THAT(LayoutUnit(), left_float_fragment->Offset().top);
+ NGPhysicalOffset offset;
+ iterator.NextChild(&offset);
+ EXPECT_THAT(LayoutUnit(), offset.top);
Element* left_wide_float = GetDocument().getElementById("left-wide-float");
// left-wide-float is positioned right below left-float as it's too wide.
@@ -1193,16 +1206,16 @@ TEST_F(NGBlockLayoutAlgorithmTest, PositionFloatFragments) {
// left-float's height 30
EXPECT_EQ(38, left_wide_float->OffsetTop());
- const auto* left_wide_float_fragment = iterator.NextChild();
+ iterator.NextChild(&offset);
// 30 = left-float's height.
- EXPECT_THAT(LayoutUnit(30), left_wide_float_fragment->Offset().top);
+ EXPECT_THAT(LayoutUnit(30), offset.top);
Element* regular = GetDocument().getElementById("regular");
// regular_block_offset = body's margin-top 8
EXPECT_EQ(8, regular->OffsetTop());
- const auto* regular_block_fragment = iterator.NextChild();
- EXPECT_THAT(LayoutUnit(), regular_block_fragment->Offset().top);
+ iterator.NextChild(&offset);
+ EXPECT_THAT(LayoutUnit(), offset.top);
Element* right_float = GetDocument().getElementById("right-float");
// 158 = body's margin-left 8 + container's width 200 - right_float's width 50
@@ -1211,11 +1224,11 @@ TEST_F(NGBlockLayoutAlgorithmTest, PositionFloatFragments) {
EXPECT_EQ(158, right_float->OffsetLeft());
EXPECT_EQ(68, right_float->OffsetTop());
- const auto* right_float_fragment = iterator.NextChild();
+ iterator.NextChild(&offset);
// 60 = right_float_block_offset(68) - body's margin(8)
- EXPECT_THAT(LayoutUnit(60), right_float_fragment->Offset().top);
+ EXPECT_THAT(LayoutUnit(60), offset.top);
// 150 = right_float_inline_offset(158) - body's margin(8)
- EXPECT_THAT(LayoutUnit(150), right_float_fragment->Offset().left);
+ EXPECT_THAT(LayoutUnit(150), offset.left);
Element* left_float_with_margin =
GetDocument().getElementById("left-float-with-margin");
@@ -1225,11 +1238,11 @@ TEST_F(NGBlockLayoutAlgorithmTest, PositionFloatFragments) {
// left-float-with-margin's margin(10)
EXPECT_EQ(78, left_float_with_margin->OffsetTop());
- const auto* left_float_with_margin_fragment = iterator.NextChild();
+ iterator.NextChild(&offset);
// 70 = left_float_with_margin_block_offset(78) - body's margin(8)
- EXPECT_THAT(LayoutUnit(70), left_float_with_margin_fragment->Offset().top);
+ EXPECT_THAT(LayoutUnit(70), offset.top);
// 10 = left_float_with_margin_inline_offset(18) - body's margin(8)
- EXPECT_THAT(LayoutUnit(10), left_float_with_margin_fragment->Offset().left);
+ EXPECT_THAT(LayoutUnit(10), offset.left);
}
// Verifies that NG block layout algorithm respects "clear" CSS property.
@@ -1281,11 +1294,11 @@ TEST_F(NGBlockLayoutAlgorithmTest, PositionFragmentsWithClear) {
</div>
)HTML");
- const NGPhysicalBoxFragment* clerance_fragment;
- const NGPhysicalBoxFragment* body_fragment;
- const NGPhysicalBoxFragment* container_fragment;
- const NGPhysicalBoxFragment* block_fragment;
- const NGPhysicalBoxFragment* adjoining_clearance_fragment;
+ NGPhysicalOffset clerance_offset;
+ NGPhysicalOffset body_offset;
+ NGPhysicalOffset container_offset;
+ NGPhysicalOffset block_offset;
+ NGPhysicalOffset adjoining_clearance_offset;
scoped_refptr<const NGPhysicalBoxFragment> fragment;
auto run_with_clearance = [&](EClear clear_value) {
Element* el_with_clear = GetDocument().getElementById("clearance");
@@ -1294,70 +1307,70 @@ TEST_F(NGBlockLayoutAlgorithmTest, PositionFragmentsWithClear) {
std::tie(fragment, std::ignore) = RunBlockLayoutAlgorithmForElement(
GetDocument().getElementsByTagName("html")->item(0));
ASSERT_EQ(1UL, fragment->Children().size());
- body_fragment = ToNGPhysicalBoxFragment(fragment->Children()[0].get());
- container_fragment =
+ const NGPhysicalBoxFragment* body_fragment =
+ ToNGPhysicalBoxFragment(fragment->Children()[0].get());
+ body_offset = fragment->Children()[0].Offset();
+ const NGPhysicalBoxFragment* container_fragment =
ToNGPhysicalBoxFragment(body_fragment->Children()[0].get());
ASSERT_EQ(5UL, container_fragment->Children().size());
- clerance_fragment =
- ToNGPhysicalBoxFragment(container_fragment->Children()[2].get());
- block_fragment =
- ToNGPhysicalBoxFragment(container_fragment->Children()[3].get());
- adjoining_clearance_fragment =
- ToNGPhysicalBoxFragment(container_fragment->Children()[4].get());
+ container_offset = body_fragment->Children()[0].Offset();
+ clerance_offset = container_fragment->Children()[2].Offset();
+ block_offset = container_fragment->Children()[3].Offset();
+ adjoining_clearance_offset = container_fragment->Children()[4].Offset();
};
// clear: none
run_with_clearance(EClear::kNone);
// 20 = std::max(body's margin 8, clearance's margins 20)
- EXPECT_EQ(LayoutUnit(20), body_fragment->Offset().top);
- EXPECT_EQ(LayoutUnit(0), container_fragment->Offset().top);
+ EXPECT_EQ(LayoutUnit(20), body_offset.top);
+ EXPECT_EQ(LayoutUnit(0), container_offset.top);
// 0 = collapsed margins
- EXPECT_EQ(LayoutUnit(0), clerance_fragment->Offset().top);
+ EXPECT_EQ(LayoutUnit(0), clerance_offset.top);
// 100 = clearance's height 60 +
// std::max(clearance's margins 20, block's margins 40)
- EXPECT_EQ(LayoutUnit(100), block_fragment->Offset().top);
+ EXPECT_EQ(LayoutUnit(100), block_offset.top);
// 200 = 100 + block's height 60 + max(adjoining_clearance's margins 30,
// block's margins 40)
- EXPECT_EQ(LayoutUnit(200), adjoining_clearance_fragment->Offset().top);
+ EXPECT_EQ(LayoutUnit(200), adjoining_clearance_offset.top);
// clear: right
run_with_clearance(EClear::kRight);
// 8 = body's margin. This doesn't collapse its margins with 'clearance' block
// as it's not an adjoining block to body.
- EXPECT_EQ(LayoutUnit(8), body_fragment->Offset().top);
- EXPECT_EQ(LayoutUnit(0), container_fragment->Offset().top);
+ EXPECT_EQ(LayoutUnit(8), body_offset.top);
+ EXPECT_EQ(LayoutUnit(0), container_offset.top);
// 170 = float-right's height
- EXPECT_EQ(LayoutUnit(170), clerance_fragment->Offset().top);
+ EXPECT_EQ(LayoutUnit(170), clerance_offset.top);
// 270 = float-right's height + clearance's height 60 +
// max(clearance's margin 20, block margin 40)
- EXPECT_EQ(LayoutUnit(270), block_fragment->Offset().top);
+ EXPECT_EQ(LayoutUnit(270), block_offset.top);
// 370 = block's offset 270 + block's height 60 +
// std::max(block's margin 40, adjoining_clearance's margin 30)
- EXPECT_EQ(LayoutUnit(370), adjoining_clearance_fragment->Offset().top);
+ EXPECT_EQ(LayoutUnit(370), adjoining_clearance_offset.top);
// clear: left
run_with_clearance(EClear::kLeft);
// 8 = body's margin. This doesn't collapse its margins with 'clearance' block
// as it's not an adjoining block to body.
- EXPECT_EQ(LayoutUnit(8), body_fragment->Offset().top);
- EXPECT_EQ(LayoutUnit(0), container_fragment->Offset().top);
+ EXPECT_EQ(LayoutUnit(8), body_offset.top);
+ EXPECT_EQ(LayoutUnit(0), container_offset.top);
// 30 = float_left's height
- EXPECT_EQ(LayoutUnit(30), clerance_fragment->Offset().top);
+ EXPECT_EQ(LayoutUnit(30), clerance_offset.top);
// 130 = float_left's height + clearance's height 60 +
// max(clearance's margin 20, block margin 40)
- EXPECT_EQ(LayoutUnit(130), block_fragment->Offset().top);
+ EXPECT_EQ(LayoutUnit(130), block_offset.top);
// 230 = block's offset 130 + block's height 60 +
// std::max(block's margin 40, adjoining_clearance's margin 30)
- EXPECT_EQ(LayoutUnit(230), adjoining_clearance_fragment->Offset().top);
+ EXPECT_EQ(LayoutUnit(230), adjoining_clearance_offset.top);
// clear: both
// same as clear: right
run_with_clearance(EClear::kBoth);
- EXPECT_EQ(LayoutUnit(8), body_fragment->Offset().top);
- EXPECT_EQ(LayoutUnit(0), container_fragment->Offset().top);
- EXPECT_EQ(LayoutUnit(170), clerance_fragment->Offset().top);
- EXPECT_EQ(LayoutUnit(270), block_fragment->Offset().top);
- EXPECT_EQ(LayoutUnit(370), adjoining_clearance_fragment->Offset().top);
+ EXPECT_EQ(LayoutUnit(8), body_offset.top);
+ EXPECT_EQ(LayoutUnit(0), container_offset.top);
+ EXPECT_EQ(LayoutUnit(170), clerance_offset.top);
+ EXPECT_EQ(LayoutUnit(270), block_offset.top);
+ EXPECT_EQ(LayoutUnit(370), adjoining_clearance_offset.top);
}
// Verifies that we compute the right min and max-content size.
@@ -1497,7 +1510,7 @@ TEST_F(NGBlockLayoutAlgorithmTest, ShrinkToFit) {
ConstructBlockLayoutTestConstraintSpace(
WritingMode::kHorizontalTb, TextDirection::kLtr,
NGLogicalSize(LayoutUnit(100), NGSizeIndefinite), true);
- scoped_refptr<NGPhysicalFragment> frag =
+ scoped_refptr<const NGPhysicalFragment> frag =
RunBlockLayoutAlgorithm(*space, container);
EXPECT_EQ(LayoutUnit(kWidthChild2), frag->Size().width);
@@ -1550,16 +1563,16 @@ TEST_F(NGBlockLayoutAlgorithmTest, PositionEmptyBlocksInNewBfc) {
ToNGPhysicalBoxFragment(html_fragment->Children()[0].get());
auto* container_fragment =
ToNGPhysicalBoxFragment(body_fragment->Children()[0].get());
- auto* empty_block1 =
- ToNGPhysicalBoxFragment(container_fragment->Children()[1].get());
+ NGPhysicalOffset empty_block1_offset =
+ container_fragment->Children()[1].Offset();
// empty-block1's margin == 8
- EXPECT_THAT(empty_block1->Offset(),
+ EXPECT_THAT(empty_block1_offset,
NGPhysicalOffset(LayoutUnit(8), LayoutUnit(8)));
- auto* empty_block2 =
- ToNGPhysicalBoxFragment(container_fragment->Children()[2].get());
+ NGPhysicalOffset empty_block2_offset =
+ container_fragment->Children()[2].Offset();
// empty-block2's margin == 50
- EXPECT_THAT(empty_block2->Offset(),
+ EXPECT_THAT(empty_block2_offset,
NGPhysicalOffset(LayoutUnit(0), LayoutUnit(50)));
}
@@ -1613,7 +1626,7 @@ TEST_F(NGBlockLayoutAlgorithmTest,
)HTML");
// Run LayoutNG algorithm.
- scoped_refptr<NGPhysicalBoxFragment> html_fragment;
+ scoped_refptr<const NGPhysicalBoxFragment> html_fragment;
std::tie(html_fragment, std::ignore) = RunBlockLayoutAlgorithmForElement(
GetDocument().getElementsByTagName("html")->item(0));
auto* body_fragment =
@@ -1623,9 +1636,11 @@ TEST_F(NGBlockLayoutAlgorithmTest,
// Verify #container-clear block
auto* container_clear_fragment =
ToNGPhysicalBoxFragment(body_fragment->Children()[3].get());
+ NGPhysicalOffset container_clear_offset =
+ body_fragment->Children()[3].Offset();
// 60 = block1's height 30 + std::max(block1's margin 20, zero's margin 30)
EXPECT_THAT(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(60)),
- container_clear_fragment->Offset());
+ container_clear_offset);
Element* container_clear = GetDocument().getElementById("container-clear");
// 190 = block1's margin 130 + block1's height 30 +
// std::max(block1's margin 20, zero's margin 30)
@@ -1633,12 +1648,12 @@ TEST_F(NGBlockLayoutAlgorithmTest,
// Verify #clears-right block
ASSERT_EQ(2UL, container_clear_fragment->Children().size());
- auto* clears_right_fragment =
- ToNGPhysicalBoxFragment(container_clear_fragment->Children()[1].get());
+ NGPhysicalOffset clears_right_offset =
+ container_clear_fragment->Children()[1].Offset();
// 20 = right-float's block end offset (130 + 80) -
// container_clear->offsetTop() 190
EXPECT_THAT(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(20)),
- clears_right_fragment->Offset());
+ clears_right_offset);
}
// Tests that a block won't fragment if it doesn't reach the fragmentation line.
@@ -1745,9 +1760,10 @@ TEST_F(NGBlockLayoutAlgorithmTest, InnerChildrenFragmentation) {
ASSERT_FALSE(fragment->BreakToken()->IsFinished());
FragmentChildIterator iterator(ToNGPhysicalBoxFragment(fragment.get()));
- const NGPhysicalBoxFragment* child = iterator.NextChild();
+ NGPhysicalOffset offset;
+ const NGPhysicalBoxFragment* child = iterator.NextChild(&offset);
EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(180)), child->Size());
- EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(20)), child->Offset());
+ EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(20)), offset);
EXPECT_FALSE(iterator.NextChild());
@@ -1759,13 +1775,13 @@ TEST_F(NGBlockLayoutAlgorithmTest, InnerChildrenFragmentation) {
ASSERT_TRUE(fragment->BreakToken()->IsFinished());
iterator.SetParent(ToNGPhysicalBoxFragment(fragment.get()));
- child = iterator.NextChild();
+ child = iterator.NextChild(&offset);
EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(20)), child->Size());
- EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(0)), child->Offset());
+ EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(0)), offset);
- child = iterator.NextChild();
+ child = iterator.NextChild(&offset);
EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(100)), child->Size());
- EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(40)), child->Offset());
+ EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(40)), offset);
EXPECT_FALSE(iterator.NextChild());
}
@@ -1813,9 +1829,10 @@ TEST_F(NGBlockLayoutAlgorithmTest,
ASSERT_FALSE(fragment->BreakToken()->IsFinished());
FragmentChildIterator iterator(ToNGPhysicalBoxFragment(fragment.get()));
- const NGPhysicalBoxFragment* child = iterator.NextChild();
+ NGPhysicalOffset offset;
+ const NGPhysicalBoxFragment* child = iterator.NextChild(&offset);
EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(180)), child->Size());
- EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(20)), child->Offset());
+ EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(20)), offset);
EXPECT_FALSE(iterator.NextChild());
@@ -1827,13 +1844,13 @@ TEST_F(NGBlockLayoutAlgorithmTest,
ASSERT_TRUE(fragment->BreakToken()->IsFinished());
iterator.SetParent(ToNGPhysicalBoxFragment(fragment.get()));
- child = iterator.NextChild();
+ child = iterator.NextChild(&offset);
EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(20)), child->Size());
- EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(0)), child->Offset());
+ EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(0)), offset);
- child = iterator.NextChild();
+ child = iterator.NextChild(&offset);
EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(100)), child->Size());
- EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(40)), child->Offset());
+ EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(40)), offset);
EXPECT_FALSE(iterator.NextChild());
}
@@ -1879,9 +1896,10 @@ TEST_F(NGBlockLayoutAlgorithmTest, InnerChildrenFragmentationSmallHeight) {
ASSERT_FALSE(fragment->BreakToken()->IsFinished());
FragmentChildIterator iterator(ToNGPhysicalBoxFragment(fragment.get()));
- const NGPhysicalBoxFragment* child = iterator.NextChild();
+ NGPhysicalOffset offset;
+ const NGPhysicalBoxFragment* child = iterator.NextChild(&offset);
EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(180)), child->Size());
- EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(20)), child->Offset());
+ EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(20)), offset);
EXPECT_FALSE(iterator.NextChild());
@@ -1893,13 +1911,13 @@ TEST_F(NGBlockLayoutAlgorithmTest, InnerChildrenFragmentationSmallHeight) {
ASSERT_TRUE(fragment->BreakToken()->IsFinished());
iterator.SetParent(ToNGPhysicalBoxFragment(fragment.get()));
- child = iterator.NextChild();
+ child = iterator.NextChild(&offset);
EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(20)), child->Size());
- EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(0)), child->Offset());
+ EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(0)), offset);
- child = iterator.NextChild();
+ child = iterator.NextChild(&offset);
EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(100)), child->Size());
- EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(40)), child->Offset());
+ EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(40)), offset);
EXPECT_FALSE(iterator.NextChild());
}
@@ -1948,14 +1966,15 @@ TEST_F(NGBlockLayoutAlgorithmTest, FloatFragmentationParallelFlows) {
FragmentChildIterator iterator(ToNGPhysicalBoxFragment(fragment.get()));
// First fragment of float1.
- const auto* child = iterator.NextChild();
+ NGPhysicalOffset offset;
+ const auto* child = iterator.NextChild(&offset);
EXPECT_EQ(NGPhysicalSize(LayoutUnit(50), LayoutUnit(150)), child->Size());
- EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(0)), child->Offset());
+ EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(0)), offset);
// First fragment of float2.
- child = iterator.NextChild();
+ child = iterator.NextChild(&offset);
EXPECT_EQ(NGPhysicalSize(LayoutUnit(75), LayoutUnit(150)), child->Size());
- EXPECT_EQ(NGPhysicalOffset(LayoutUnit(65), LayoutUnit(10)), child->Offset());
+ EXPECT_EQ(NGPhysicalOffset(LayoutUnit(65), LayoutUnit(10)), offset);
space = ConstructBlockLayoutTestConstraintSpace(
WritingMode::kHorizontalTb, TextDirection::kLtr,
@@ -1971,14 +1990,14 @@ TEST_F(NGBlockLayoutAlgorithmTest, FloatFragmentationParallelFlows) {
iterator.SetParent(ToNGPhysicalBoxFragment(fragment.get()));
// Second fragment of float1.
- child = iterator.NextChild();
+ child = iterator.NextChild(&offset);
EXPECT_EQ(NGPhysicalSize(LayoutUnit(50), LayoutUnit(50)), child->Size());
- EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(0)), child->Offset());
+ EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(0)), offset);
// Second fragment of float2.
- child = iterator.NextChild();
+ child = iterator.NextChild(&offset);
EXPECT_EQ(NGPhysicalSize(LayoutUnit(75), LayoutUnit(100)), child->Size());
- EXPECT_EQ(NGPhysicalOffset(LayoutUnit(65), LayoutUnit()), child->Offset());
+ EXPECT_EQ(NGPhysicalOffset(LayoutUnit(65), LayoutUnit()), offset);
}
// Tests that float children don't fragment if they aren't in the same writing
@@ -2028,10 +2047,11 @@ TEST_F(NGBlockLayoutAlgorithmTest, FloatFragmentationOrthogonalFlows) {
// float2 should only have one fragment.
FragmentChildIterator iterator(ToNGPhysicalBoxFragment(fragment.get()));
- const auto* child = iterator.NextChild();
- child = iterator.NextChild();
+ NGPhysicalOffset offset;
+ const auto* child = iterator.NextChild(&offset);
+ child = iterator.NextChild(&offset);
EXPECT_EQ(NGPhysicalSize(LayoutUnit(60), LayoutUnit(200)), child->Size());
- EXPECT_EQ(NGPhysicalOffset(LayoutUnit(90), LayoutUnit(50)), child->Offset());
+ EXPECT_EQ(NGPhysicalOffset(LayoutUnit(90), LayoutUnit(50)), offset);
ASSERT_TRUE(child->BreakToken()->IsFinished());
}
@@ -2077,9 +2097,10 @@ TEST_F(NGBlockLayoutAlgorithmTest, FloatFragmentationZeroHeight) {
// First fragment of float.
iterator.SetParent(child);
- child = iterator.NextChild();
+ NGPhysicalOffset offset;
+ child = iterator.NextChild(&offset);
EXPECT_EQ(NGPhysicalSize(LayoutUnit(75), LayoutUnit(150)), child->Size());
- EXPECT_EQ(NGPhysicalOffset(LayoutUnit(10), LayoutUnit(10)), child->Offset());
+ EXPECT_EQ(NGPhysicalOffset(LayoutUnit(10), LayoutUnit(10)), offset);
space = ConstructBlockLayoutTestConstraintSpace(
WritingMode::kHorizontalTb, TextDirection::kLtr,
@@ -2129,9 +2150,9 @@ TEST_F(NGBlockLayoutAlgorithmTest,
</div>
)HTML");
- const NGPhysicalBoxFragment* body_fragment;
- const NGPhysicalBoxFragment* container_fragment;
- const NGPhysicalBoxFragment* new_fc_fragment;
+ NGPhysicalOffset body_offset;
+ NGPhysicalOffset new_fc_offset;
+
scoped_refptr<const NGPhysicalBoxFragment> fragment;
auto run_test = [&](const Length& block_width) {
Element* new_fc_block = GetDocument().getElementById("new-fc");
@@ -2140,32 +2161,29 @@ TEST_F(NGBlockLayoutAlgorithmTest,
std::tie(fragment, std::ignore) = RunBlockLayoutAlgorithmForElement(
GetDocument().getElementsByTagName("html")->item(0));
ASSERT_EQ(1UL, fragment->Children().size());
- body_fragment = ToNGPhysicalBoxFragment(fragment->Children()[0].get());
- container_fragment =
+ const NGPhysicalBoxFragment* body_fragment =
+ ToNGPhysicalBoxFragment(fragment->Children()[0].get());
+ const NGPhysicalBoxFragment* container_fragment =
ToNGPhysicalBoxFragment(body_fragment->Children()[0].get());
ASSERT_EQ(2UL, container_fragment->Children().size());
- new_fc_fragment =
- ToNGPhysicalBoxFragment(container_fragment->Children()[1].get());
+ body_offset = fragment->Children()[0].Offset();
+ new_fc_offset = container_fragment->Children()[1].Offset();
};
// #new-fc is small enough to fit on the same line with #float.
run_test(Length(80, kFixed));
// 100 = float's width, 0 = no margin collapsing
- EXPECT_THAT(new_fc_fragment->Offset(),
- NGPhysicalOffset(LayoutUnit(100), LayoutUnit(0)));
+ EXPECT_THAT(new_fc_offset, NGPhysicalOffset(LayoutUnit(100), LayoutUnit(0)));
// 8 = body's margins, 20 = new-fc's margin top(20) collapses with
// body's margin(8)
- EXPECT_THAT(body_fragment->Offset(),
- NGPhysicalOffset(LayoutUnit(8), LayoutUnit(20)));
+ EXPECT_THAT(body_offset, NGPhysicalOffset(LayoutUnit(8), LayoutUnit(20)));
// #new-fc is too wide to be positioned on the same line with #float
run_test(Length(120, kFixed));
// 30 = #float's height
- EXPECT_THAT(new_fc_fragment->Offset(),
- NGPhysicalOffset(LayoutUnit(0), LayoutUnit(30)));
+ EXPECT_THAT(new_fc_offset, NGPhysicalOffset(LayoutUnit(0), LayoutUnit(30)));
// 8 = body's margins, no margin collapsing
- EXPECT_THAT(body_fragment->Offset(),
- NGPhysicalOffset(LayoutUnit(8), LayoutUnit(8)));
+ EXPECT_THAT(body_offset, NGPhysicalOffset(LayoutUnit(8), LayoutUnit(8)));
}
TEST_F(NGBlockLayoutAlgorithmTest, NewFcAvoidsFloats) {
@@ -2200,13 +2218,14 @@ TEST_F(NGBlockLayoutAlgorithmTest, NewFcAvoidsFloats) {
FragmentChildIterator iterator(ToNGPhysicalBoxFragment(fragment.get()));
- const NGPhysicalBoxFragment* child = iterator.NextChild();
+ NGPhysicalOffset offset;
+ const NGPhysicalBoxFragment* child = iterator.NextChild(&offset);
EXPECT_EQ(NGPhysicalSize(LayoutUnit(100), LayoutUnit(30)), child->Size());
- EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(0)), child->Offset());
+ EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(0)), offset);
- child = iterator.NextChild();
+ child = iterator.NextChild(&offset);
EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(120)), child->Size());
- EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(30)), child->Offset());
+ EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(30)), offset);
}
TEST_F(NGBlockLayoutAlgorithmTest, ZeroBlockSizeAboveEdge) {
@@ -2235,13 +2254,14 @@ TEST_F(NGBlockLayoutAlgorithmTest, ZeroBlockSizeAboveEdge) {
FragmentChildIterator iterator(ToNGPhysicalBoxFragment(fragment.get()));
- const NGPhysicalBoxFragment* child = iterator.NextChild();
+ NGPhysicalOffset offset;
+ const NGPhysicalBoxFragment* child = iterator.NextChild(&offset);
EXPECT_EQ(NGPhysicalSize(LayoutUnit(50), LayoutUnit(50)), child->Size());
- EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(-70)), child->Offset());
+ EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(-70)), offset);
- child = iterator.NextChild();
+ child = iterator.NextChild(&offset);
EXPECT_EQ(NGPhysicalSize(LayoutUnit(70), LayoutUnit(0)), child->Size());
- EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(-10)), child->Offset());
+ EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(-10)), offset);
}
TEST_F(NGBlockLayoutAlgorithmTest, NewFcFirstChildIsZeroBlockSize) {
@@ -2272,17 +2292,18 @@ TEST_F(NGBlockLayoutAlgorithmTest, NewFcFirstChildIsZeroBlockSize) {
FragmentChildIterator iterator(ToNGPhysicalBoxFragment(fragment.get()));
- const NGPhysicalBoxFragment* child = iterator.NextChild();
+ NGPhysicalOffset offset;
+ const NGPhysicalBoxFragment* child = iterator.NextChild(&offset);
EXPECT_EQ(NGPhysicalSize(LayoutUnit(50), LayoutUnit(0)), child->Size());
- EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(-30)), child->Offset());
+ EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(-30)), offset);
- child = iterator.NextChild();
+ child = iterator.NextChild(&offset);
EXPECT_EQ(NGPhysicalSize(LayoutUnit(70), LayoutUnit(0)), child->Size());
- EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(-10)), child->Offset());
+ EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(-10)), offset);
- child = iterator.NextChild();
+ child = iterator.NextChild(&offset);
EXPECT_EQ(NGPhysicalSize(LayoutUnit(90), LayoutUnit(20)), child->Size());
- EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(-10)), child->Offset());
+ EXPECT_EQ(NGPhysicalOffset(LayoutUnit(0), LayoutUnit(-10)), offset);
}
// This test assumes that tables are not yet implemented in LayoutNG.
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 412a763099d..c4e7982af0f 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
@@ -13,6 +13,7 @@
#include "third_party/blink/renderer/core/layout/min_max_size.h"
#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/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"
@@ -29,6 +30,7 @@
#include "third_party/blink/renderer/core/layout/ng/ng_page_layout_algorithm.h"
#include "third_party/blink/renderer/core/layout/shapes/shape_outside_info.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/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/text/writing_mode.h"
@@ -87,7 +89,7 @@ void UpdateLegacyMultiColumnFlowThread(
bool has_processed_first_child = false;
// Stitch the columns together.
- for (const scoped_refptr<NGPhysicalFragment> child : fragment.Children()) {
+ for (const auto& child : fragment.Children()) {
NGFragment child_fragment(writing_mode, *child);
flow_end += child_fragment.BlockSize();
// Non-uniform fragmentainer widths not supported by legacy layout.
@@ -96,8 +98,8 @@ void UpdateLegacyMultiColumnFlowThread(
if (!has_processed_first_child) {
// The offset of the flow thread should be the same as that of the first
// first column.
- flow_thread->SetX(child->Offset().left);
- flow_thread->SetY(child->Offset().top);
+ flow_thread->SetX(child.Offset().left);
+ flow_thread->SetY(child.Offset().top);
flow_thread->SetLogicalWidth(child_fragment.InlineSize());
column_block_size = child_fragment.BlockSize();
has_processed_first_child = true;
@@ -126,45 +128,6 @@ void UpdateLegacyMultiColumnFlowThread(
flow_thread->ClearNeedsLayout();
}
-// For inline children, NG painters handles fragments directly, but there are
-// some cases where we need to copy data to the LayoutObject tree. This function
-// handles such cases.
-void CopyFragmentDataToLayoutBoxForInlineChildren(
- const NGPhysicalContainerFragment& container,
- LayoutUnit initial_container_width,
- bool initial_container_is_flipped,
- NGPhysicalOffset offset = {}) {
- for (const auto& child : container.Children()) {
- if (child->IsContainer()) {
- NGPhysicalOffset child_offset = offset + child->Offset();
-
- // Replaced elements and inline blocks need Location() set relative to
- // their block container.
- LayoutObject* layout_object = child->GetLayoutObject();
- if (layout_object && layout_object->IsBox()) {
- LayoutBox& layout_box = ToLayoutBox(*layout_object);
- NGPhysicalOffset maybe_flipped_offset = child_offset;
- if (initial_container_is_flipped) {
- maybe_flipped_offset.left = initial_container_width -
- child->Size().width -
- maybe_flipped_offset.left;
- }
- layout_box.SetLocation(maybe_flipped_offset.ToLayoutPoint());
- }
-
- // The Location() of inline LayoutObject is relative to the
- // LayoutBlockFlow. If |child| is a block layout root (e.g., inline block,
- // float, etc.), it creates another inline formatting context. Do not copy
- // to its descendants in this case.
- if (!child->IsBlockLayoutRoot()) {
- CopyFragmentDataToLayoutBoxForInlineChildren(
- ToNGPhysicalContainerFragment(*child), initial_container_width,
- initial_container_is_flipped, child_offset);
- }
- }
- }
-}
-
NGConstraintSpaceBuilder CreateConstraintSpaceBuilderForMinMax(
NGBlockNode node) {
return NGConstraintSpaceBuilder(node.Style().GetWritingMode(),
@@ -172,7 +135,7 @@ NGConstraintSpaceBuilder CreateConstraintSpaceBuilderForMinMax(
.SetTextDirection(node.Style().Direction())
.SetIsIntermediateLayout(true)
.SetIsNewFormattingContext(node.CreatesNewFormattingContext())
- .SetFloatsBfcOffset(NGBfcOffset());
+ .SetFloatsBfcBlockOffset(LayoutUnit());
}
} // namespace
@@ -206,7 +169,7 @@ scoped_refptr<NGLayoutResult> NGBlockNode::Layout(
// -dynamic.html
// TODO(layoutng): See if we can optimize this. When we natively
// support relative positioning in NG we can probably remove this,
- box_->SetMayNeedPaintInvalidation();
+ box_->SetShouldCheckForPaintInvalidation();
// We have to re-set the cached result here, because it is used for
// LayoutNGMixin::CurrentFragment and therefore has to be up-to-date.
@@ -214,10 +177,11 @@ scoped_refptr<NGLayoutResult> NGBlockNode::Layout(
// don't re-set the result here.
ToLayoutBlockFlow(box_)->SetCachedLayoutResult(
constraint_space, break_token, layout_result);
- if (!constraint_space.IsIntermediateLayout()) {
- block_flow->ClearPaintFragment();
- if (first_child && first_child.IsInline())
- block_flow->SetPaintFragment(layout_result->PhysicalFragment());
+ if (!constraint_space.IsIntermediateLayout() && first_child &&
+ first_child.IsInline()) {
+ block_flow->UpdatePaintFragmentFromCachedLayoutResult(
+ break_token, layout_result->PhysicalFragment(),
+ layout_result->Offset());
}
return layout_result;
}
@@ -241,20 +205,51 @@ scoped_refptr<NGLayoutResult> NGBlockNode::Layout(
box_->ComputePreferredLogicalWidths();
}
+ PrepareForLayout();
+
+ NGBoxStrut old_scrollbars = GetScrollbarSizes();
layout_result = LayoutWithAlgorithm(*this, constraint_space, break_token,
/* ignored */ nullptr);
- if (block_flow) {
- block_flow->SetCachedLayoutResult(constraint_space, break_token,
- layout_result);
- if (layout_result->Status() == NGLayoutResult::kSuccess &&
- !constraint_space.IsIntermediateLayout())
- block_flow->ClearPaintFragment();
+
+ FinishLayout(constraint_space, break_token, layout_result);
+ if (old_scrollbars != GetScrollbarSizes()) {
+ // If our scrollbars have changed, we need to relayout because either:
+ // - Our size has changed (if shrinking to fit), or
+ // - Space available to our children has changed.
+ // This mirrors legacy code in PaintLayerScrollableArea::UpdateAfterLayout.
+ // TODO(cbiesinger): It seems that we should also check if
+ // PreferredLogicalWidthsDirty() has changed from false to true during
+ // layout, so that we correctly size ourselves when shrinking to fit
+ // and a child gained a vertical scrollbar. However, no test fails
+ // without that check.
+ PaintLayerScrollableArea::FreezeScrollbarsScope freeze_scrollbars;
+ layout_result = LayoutWithAlgorithm(*this, constraint_space, break_token,
+ /* ignored */ nullptr);
+ FinishLayout(constraint_space, break_token, layout_result);
}
- if (IsBlockLayoutComplete(constraint_space, *layout_result)) {
- DCHECK(layout_result->PhysicalFragment());
+ return layout_result;
+}
+
+void NGBlockNode::PrepareForLayout() {
+ if (IsListItem())
+ ToLayoutNGListItem(box_)->UpdateMarkerTextIfNeeded();
+}
- if (block_flow && first_child && first_child.IsInline()) {
+void NGBlockNode::FinishLayout(const NGConstraintSpace& constraint_space,
+ NGBreakToken* break_token,
+ scoped_refptr<NGLayoutResult> layout_result) {
+ if (!IsBlockLayoutComplete(constraint_space, *layout_result))
+ return;
+
+ DCHECK(layout_result->PhysicalFragment());
+
+ if (box_->IsLayoutNGMixin()) {
+ LayoutBlockFlow* block_flow = ToLayoutBlockFlow(box_);
+ block_flow->SetCachedLayoutResult(constraint_space, break_token,
+ layout_result);
+ NGLayoutInputNode first_child = FirstChild();
+ if (first_child && first_child.IsInline()) {
NGBoxStrut scrollbars = GetScrollbarSizes();
CopyFragmentDataToLayoutBoxForInlineChildren(
ToNGPhysicalBoxFragment(*layout_result->PhysicalFragment()),
@@ -262,15 +257,17 @@ scoped_refptr<NGLayoutResult> NGBlockNode::Layout(
scrollbars.block_start,
Style().IsFlippedBlocksWritingMode());
- block_flow->SetPaintFragment(layout_result->PhysicalFragment());
+ block_flow->SetPaintFragment(break_token,
+ layout_result->PhysicalFragment(),
+ layout_result->Offset());
+ } else {
+ // We still need to clear paint fragments in case it had inline children,
+ // and thus had NGPaintFragment.
+ block_flow->SetPaintFragment(break_token, nullptr, NGPhysicalOffset());
}
-
- // TODO(kojii): Even when we paint fragments, there seem to be some data we
- // need to copy to LayoutBox. Review if we can minimize the copy.
- CopyFragmentDataToLayoutBox(constraint_space, *layout_result);
}
- return layout_result;
+ CopyFragmentDataToLayoutBox(constraint_space, *layout_result);
}
MinMaxSize NGBlockNode::ComputeMinMaxSize(
@@ -283,9 +280,9 @@ MinMaxSize NGBlockNode::ComputeMinMaxSize(
MinMaxSize 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() ||
+ if ((!CanUseNewLayout() && !is_orthogonal_flow_root) ||
(is_orthogonal_flow_root && !box_->GetFrameView()->IsInPerformLayout())) {
- return ComputeMinMaxSizeFromLegacy();
+ return ComputeMinMaxSizeFromLegacy(input.size_type);
}
scoped_refptr<NGConstraintSpace> zero_constraint_space =
@@ -300,13 +297,20 @@ MinMaxSize NGBlockNode::ComputeMinMaxSize(
constraint_space = zero_constraint_space.get();
}
- if (is_orthogonal_flow_root) {
+ if (is_orthogonal_flow_root || !CanUseNewLayout()) {
scoped_refptr<NGLayoutResult> layout_result = Layout(*constraint_space);
DCHECK_EQ(layout_result->Status(), NGLayoutResult::kSuccess);
NGBoxFragment fragment(
container_writing_mode,
+ TextDirection::kLtr, // irrelevant here
ToNGPhysicalBoxFragment(*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;
}
@@ -319,13 +323,14 @@ MinMaxSize NGBlockNode::ComputeMinMaxSize(
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();
+ return ComputeMinMaxSizeFromLegacy(input.size_type);
}
// Have to synthesize this value.
scoped_refptr<NGLayoutResult> layout_result = Layout(*zero_constraint_space);
NGBoxFragment min_fragment(
container_writing_mode,
+ TextDirection::kLtr, // irrelevant here
ToNGPhysicalBoxFragment(*layout_result->PhysicalFragment()));
sizes.min_size = min_fragment.Size().inline_size;
@@ -339,22 +344,31 @@ MinMaxSize NGBlockNode::ComputeMinMaxSize(
layout_result = Layout(*infinite_constraint_space);
NGBoxFragment max_fragment(
container_writing_mode,
+ TextDirection::kLtr, // irrelevant here
ToNGPhysicalBoxFragment(*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 {
- // TODO(layout-ng): This could be somewhat optimized by directly calling
- // computeIntrinsicLogicalWidths, but that function is currently private.
- // Consider doing that if this becomes a performance issue.
+MinMaxSize NGBlockNode::ComputeMinMaxSizeFromLegacy(
+ NGMinMaxSizeType type) const {
MinMaxSize sizes;
- sizes.min_size =
- box_->ComputeLogicalWidthUsing(kMainOrPreferredSize, Length(kMinContent),
- LayoutUnit(), box_->ContainingBlock());
- sizes.max_size =
- box_->ComputeLogicalWidthUsing(kMainOrPreferredSize, Length(kMaxContent),
- LayoutUnit(), box_->ContainingBlock());
+ // ComputeIntrinsicLogicalWidths returns content-box + scrollbar.
+ box_->ComputeIntrinsicLogicalWidths(sizes.min_size, sizes.max_size);
+ if (type == NGMinMaxSizeType::kContentBoxSize) {
+ sizes -= LayoutUnit(box_->ScrollbarLogicalWidth());
+ DCHECK_GE(sizes.min_size, LayoutUnit());
+ DCHECK_GE(sizes.max_size, LayoutUnit());
+ } else {
+ sizes += box_->BorderAndPaddingLogicalWidth();
+ }
return sizes;
}
@@ -421,7 +435,8 @@ void NGBlockNode::CopyFragmentDataToLayoutBox(
const NGPhysicalBoxFragment& physical_fragment =
ToNGPhysicalBoxFragment(*layout_result.PhysicalFragment());
- NGBoxFragment fragment(constraint_space.GetWritingMode(), physical_fragment);
+ NGBoxFragment fragment(constraint_space.GetWritingMode(),
+ constraint_space.Direction(), physical_fragment);
NGLogicalSize fragment_logical_size = fragment.Size();
// For each fragment we process, we'll accumulate the logical height and
// logical intrinsic content box height. We reset it at the first fragment,
@@ -436,15 +451,19 @@ void NGBlockNode::CopyFragmentDataToLayoutBox(
} else {
DCHECK_EQ(box_->LogicalWidth(), fragment_logical_size.inline_size)
<< "Variable fragment inline size not supported";
- logical_height = box_->LogicalHeight();
+ logical_height =
+ PreviouslyUsedBlockSpace(constraint_space, physical_fragment);
+ // TODO(layout-ng): We should store this on the break token instead of
+ // relying on previously-stored data. Our relayout in NGBlockNode::Layout
+ // will otherwise lead to wrong data.
intrinsic_content_logical_height = box_->IntrinsicContentLogicalHeight();
}
logical_height += fragment_logical_size.block_size;
intrinsic_content_logical_height += layout_result.IntrinsicBlockSize();
- NGBoxStrut borders = ComputeBorders(constraint_space, Style());
+ NGBoxStrut borders = fragment.Borders();
NGBoxStrut scrollbars = GetScrollbarSizes();
- NGBoxStrut padding = ComputePadding(constraint_space, Style());
+ NGBoxStrut padding = fragment.Padding();
NGBoxStrut border_scrollbar_padding = borders + scrollbars + padding;
if (IsLastFragment(physical_fragment))
@@ -517,7 +536,6 @@ void NGBlockNode::PlaceChildrenInLayoutBox(
const NGPhysicalOffset& offset_from_start) {
for (const auto& child_fragment : physical_fragment.Children()) {
auto* child_object = child_fragment->GetLayoutObject();
- DCHECK(child_fragment->IsPlaced());
// Skip any line-boxes we have as children, this is handled within
// NGInlineNode at the moment.
@@ -525,9 +543,10 @@ void NGBlockNode::PlaceChildrenInLayoutBox(
continue;
const auto& box_fragment = *ToNGPhysicalBoxFragment(child_fragment.get());
- if (IsFirstFragment(constraint_space, box_fragment))
- CopyChildFragmentPosition(box_fragment, offset_from_start);
-
+ if (IsFirstFragment(constraint_space, box_fragment)) {
+ CopyChildFragmentPosition(box_fragment, child_fragment.Offset(),
+ offset_from_start);
+ }
if (child_object->IsLayoutBlockFlow())
ToLayoutBlockFlow(child_object)->AddOverflowFromFloats();
}
@@ -539,7 +558,6 @@ void NGBlockNode::PlaceChildrenInFlowThread(
LayoutUnit flowthread_offset;
for (const auto& child : physical_fragment.Children()) {
// Each anonymous child of a multicol container constitutes one column.
- DCHECK(child->IsPlaced());
DCHECK(child->GetLayoutObject() == box_);
// TODO(mstensho): writing modes
@@ -557,6 +575,7 @@ void NGBlockNode::PlaceChildrenInFlowThread(
// Copies data back to the legacy layout tree for a given child fragment.
void NGBlockNode::CopyChildFragmentPosition(
const NGPhysicalFragment& fragment,
+ const NGPhysicalOffset& fragment_offset,
const NGPhysicalOffset& additional_offset) {
LayoutBox* layout_box = ToLayoutBox(fragment.GetLayoutObject());
if (!layout_box)
@@ -578,8 +597,7 @@ void NGBlockNode::CopyChildFragmentPosition(
// the layout object, except when in vertical-rl: Then it will be the offset
// from the right edge of the container to the right edge of the layout
// object.
- LayoutUnit horizontal_offset =
- fragment.Offset().left + additional_offset.left;
+ LayoutUnit horizontal_offset = fragment_offset.left + additional_offset.left;
bool has_flipped_x_axis =
containing_block->StyleRef().IsFlippedBlocksWritingMode();
if (has_flipped_x_axis) {
@@ -590,7 +608,7 @@ void NGBlockNode::CopyChildFragmentPosition(
container_width - horizontal_offset - fragment.Size().width;
}
layout_box->SetX(horizontal_offset);
- layout_box->SetY(fragment.Offset().top + additional_offset.top);
+ layout_box->SetY(fragment_offset.top + additional_offset.top);
// Floats need an associated FloatingObject for painting.
if (IsFloatFragment(fragment) && containing_block->IsLayoutBlockFlow()) {
@@ -603,13 +621,52 @@ void NGBlockNode::CopyChildFragmentPosition(
else
horizontal_margin_edge_offset -= layout_box->MarginLeft();
floating_object->SetX(horizontal_margin_edge_offset);
- floating_object->SetY(fragment.Offset().top + additional_offset.top -
+ floating_object->SetY(fragment_offset.top + additional_offset.top -
layout_box->MarginTop());
floating_object->SetIsPlaced(true);
floating_object->SetIsInPlacedTree(true);
}
}
+// For inline children, NG painters handles fragments directly, but there are
+// some cases where we need to copy data to the LayoutObject tree. This function
+// handles such cases.
+void NGBlockNode::CopyFragmentDataToLayoutBoxForInlineChildren(
+ const NGPhysicalContainerFragment& container,
+ LayoutUnit initial_container_width,
+ bool initial_container_is_flipped,
+ NGPhysicalOffset offset) {
+ for (const auto& child : container.Children()) {
+ if (child->IsContainer()) {
+ NGPhysicalOffset child_offset = offset + child.Offset();
+
+ // Replaced elements and inline blocks need Location() set relative to
+ // their block container.
+ LayoutObject* layout_object = child->GetLayoutObject();
+ if (layout_object && layout_object->IsBox()) {
+ LayoutBox& layout_box = ToLayoutBox(*layout_object);
+ NGPhysicalOffset maybe_flipped_offset = child_offset;
+ if (initial_container_is_flipped) {
+ maybe_flipped_offset.left = initial_container_width -
+ child->Size().width -
+ maybe_flipped_offset.left;
+ }
+ layout_box.SetLocation(maybe_flipped_offset.ToLayoutPoint());
+ }
+
+ // The Location() of inline LayoutObject is relative to the
+ // 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()) {
+ CopyFragmentDataToLayoutBoxForInlineChildren(
+ ToNGPhysicalContainerFragment(*child), initial_container_width,
+ initial_container_is_flipped, child_offset);
+ }
+ }
+ }
+}
+
bool NGBlockNode::IsInlineLevel() const {
return GetLayoutBox()->IsInline();
}
@@ -663,8 +720,8 @@ scoped_refptr<NGLayoutResult> NGBlockNode::RunOldLayout(
WritingMode writing_mode = Style().GetWritingMode();
const NGConstraintSpace* old_space =
- box_->IsLayoutNGMixin() ? ToLayoutBlockFlow(box_)->CachedConstraintSpace()
- : nullptr;
+ box_->IsLayoutBlock() ? ToLayoutBlock(box_)->CachedConstraintSpace()
+ : nullptr;
if (!old_space || box_->NeedsLayout() || *old_space != constraint_space) {
LayoutUnit inline_size =
Style().LogicalWidth().IsPercent()
@@ -706,6 +763,14 @@ scoped_refptr<NGLayoutResult> NGBlockNode::RunOldLayout(
} else {
box_->ForceLayout();
}
+
+ // Reset the containing block size override size, now that we're done with
+ // subtree layout. Min/max calculation that depends on the block size of the
+ // container (e.g. objects with intrinsic ratio and percentage block size)
+ // in a subsequent layout pass might otherwise become wrong.
+ box_->ClearOverrideContainingBlockContentSize();
+ if (box_->IsLayoutBlock())
+ ToLayoutBlock(box_)->SetCachedConstraintSpace(constraint_space);
}
NGLogicalSize box_size(box_->LogicalWidth(), box_->LogicalHeight());
// TODO(kojii): Implement use_first_line_style.
@@ -714,14 +779,12 @@ scoped_refptr<NGLayoutResult> NGBlockNode::RunOldLayout(
builder.SetIsOldLayoutRoot();
builder.SetInlineSize(box_size.inline_size);
builder.SetBlockSize(box_size.block_size);
- builder.SetPadding(ComputePadding(constraint_space, box_->StyleRef()));
-
- // For now we copy the exclusion space straight through, this is incorrect
- // but needed as not all elements which participate in a BFC are switched
- // over to LayoutNG yet.
- // TODO(ikilpatrick): Remove this once the above isn't true.
- builder.SetExclusionSpace(
- std::make_unique<NGExclusionSpace>(constraint_space.ExclusionSpace()));
+ NGBoxStrut borders(box_->BorderStart(), box_->BorderEnd(),
+ box_->BorderBefore(), box_->BorderAfter());
+ builder.SetBorders(borders);
+ NGBoxStrut padding(box_->PaddingStart(), box_->PaddingEnd(),
+ box_->PaddingBefore(), box_->PaddingAfter());
+ builder.SetPadding(padding);
CopyBaselinesFromOldLayout(constraint_space, &builder);
UpdateShapeOutsideInfoIfNeeded(
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 1872bc7a615..6db2cf1d4fe 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
@@ -18,6 +18,7 @@ class NGConstraintSpace;
class NGFragmentBuilder;
class NGLayoutResult;
class NGPhysicalBoxFragment;
+class NGPhysicalContainerFragment;
class NGPhysicalFragment;
struct MinMaxSize;
struct NGBaselineRequest;
@@ -57,7 +58,7 @@ class CORE_EXPORT NGBlockNode final : public NGLayoutInputNode {
const MinMaxSizeInput&,
const NGConstraintSpace* = nullptr);
- MinMaxSize ComputeMinMaxSizeFromLegacy() const;
+ MinMaxSize ComputeMinMaxSizeFromLegacy(NGMinMaxSizeType) const;
NGBoxStrut GetScrollbarSizes() const;
@@ -96,10 +97,21 @@ class CORE_EXPORT NGBlockNode final : public NGLayoutInputNode {
String ToString() const;
private:
+ void PrepareForLayout();
+
+ void FinishLayout(const NGConstraintSpace&,
+ NGBreakToken*,
+ scoped_refptr<NGLayoutResult>);
+
// After we run the layout algorithm, this function copies back the geometry
// data to the layout box.
void CopyFragmentDataToLayoutBox(const NGConstraintSpace&,
const NGLayoutResult&);
+ void CopyFragmentDataToLayoutBoxForInlineChildren(
+ const NGPhysicalContainerFragment& container,
+ LayoutUnit initial_container_width,
+ bool initial_container_is_flipped,
+ NGPhysicalOffset offset = {});
void PlaceChildrenInLayoutBox(const NGConstraintSpace&,
const NGPhysicalBoxFragment&,
const NGPhysicalOffset& offset_from_start);
@@ -107,6 +119,7 @@ class CORE_EXPORT NGBlockNode final : public NGLayoutInputNode {
const NGPhysicalBoxFragment&);
void CopyChildFragmentPosition(
const NGPhysicalFragment& fragment,
+ const NGPhysicalOffset& fragment_offset,
const NGPhysicalOffset& additional_offset = NGPhysicalOffset());
void CopyBaselinesFromOldLayout(const NGConstraintSpace&, NGFragmentBuilder*);
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 b5a5bf1bb27..516c63595e0 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
@@ -83,4 +83,16 @@ NGLineHeightMetrics NGBoxFragment::BaselineMetrics(
return NGLineHeightMetrics(block_size - block_size / 2, block_size / 2);
}
+NGBoxStrut NGBoxFragment::Borders() const {
+ const auto& physical_fragment = ToNGPhysicalBoxFragment(physical_fragment_);
+ return physical_fragment.Borders().ConvertToLogical(GetWritingMode(),
+ direction_);
+}
+
+NGBoxStrut NGBoxFragment::Padding() const {
+ const auto& physical_fragment = ToNGPhysicalBoxFragment(physical_fragment_);
+ return physical_fragment.Padding().ConvertToLogical(GetWritingMode(),
+ direction_);
+}
+
} // namespace blink
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 93c08fc9c10..b109472cdc2 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
@@ -8,6 +8,7 @@
#include "third_party/blink/renderer/core/core_export.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/platform/text/text_direction.h"
#include "third_party/blink/renderer/platform/text/writing_mode.h"
namespace blink {
@@ -18,8 +19,9 @@ struct NGLineHeightMetrics;
class CORE_EXPORT NGBoxFragment final : public NGFragment {
public:
NGBoxFragment(WritingMode writing_mode,
+ TextDirection direction,
const NGPhysicalBoxFragment& physical_fragment)
- : NGFragment(writing_mode, physical_fragment) {}
+ : NGFragment(writing_mode, physical_fragment), direction_(direction) {}
// Compute baseline metrics (ascent/descent) for this box.
//
@@ -33,6 +35,12 @@ class CORE_EXPORT NGBoxFragment final : public NGFragment {
const NGBaselineRequest&) const;
NGLineHeightMetrics BaselineMetrics(const NGBaselineRequest&,
const NGConstraintSpace&) const;
+
+ NGBoxStrut Borders() const;
+ NGBoxStrut Padding() const;
+
+ protected:
+ TextDirection direction_;
};
DEFINE_TYPE_CASTS(NGBoxFragment,
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 209816b0278..54f9aa4e40e 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
@@ -71,8 +71,10 @@ NGColumnLayoutAlgorithm::NGColumnLayoutAlgorithm(NGBlockNode node,
: NGLayoutAlgorithm(node, space, ToNGBlockBreakToken(break_token)) {}
scoped_refptr<NGLayoutResult> NGColumnLayoutAlgorithm::Layout() {
- NGBoxStrut border_scrollbar_padding =
- CalculateBorderScrollbarPadding(ConstraintSpace(), Node());
+ NGBoxStrut borders = ComputeBorders(ConstraintSpace(), Node());
+ NGBoxStrut scrollbars = Node().GetScrollbarSizes();
+ NGBoxStrut padding = ComputePadding(ConstraintSpace(), Node());
+ NGBoxStrut border_scrollbar_padding = borders + scrollbars + padding;
NGLogicalSize border_box_size =
CalculateBorderBoxSize(ConstraintSpace(), Node());
NGLogicalSize content_box_size =
@@ -111,8 +113,9 @@ scoped_refptr<NGLayoutResult> NGColumnLayoutAlgorithm::Layout() {
NGBlockLayoutAlgorithm child_algorithm(Node(), *child_space.get(),
break_token.get());
+ child_algorithm.SetBoxType(NGPhysicalFragment::kColumnBox);
scoped_refptr<NGLayoutResult> result = child_algorithm.Layout();
- scoped_refptr<NGPhysicalBoxFragment> column(
+ scoped_refptr<const NGPhysicalBoxFragment> column(
ToNGPhysicalBoxFragment(result->PhysicalFragment().get()));
NGLogicalOffset logical_offset(column_inline_offset, column_block_offset);
@@ -131,7 +134,9 @@ scoped_refptr<NGLayoutResult> NGColumnLayoutAlgorithm::Layout() {
separate_leading_margins = false;
}
- LayoutUnit block_size = NGBoxFragment(writing_mode, *column).BlockSize();
+ LayoutUnit block_size =
+ NGBoxFragment(writing_mode, ConstraintSpace().Direction(), *column)
+ .BlockSize();
intrinsic_block_size =
std::max(intrinsic_block_size, column_block_offset + block_size);
@@ -168,7 +173,7 @@ scoped_refptr<NGLayoutResult> NGColumnLayoutAlgorithm::Layout() {
} while (true);
NGOutOfFlowLayoutPart(&container_builder_, Node().IsAbsoluteContainer(),
- Node().IsFixedContainer(), Node().GetScrollbarSizes(),
+ Node().IsFixedContainer(), borders + scrollbars,
ConstraintSpace(), Style())
.Run();
@@ -181,6 +186,7 @@ scoped_refptr<NGLayoutResult> NGColumnLayoutAlgorithm::Layout() {
}
container_builder_.SetInlineSize(border_box_size.inline_size);
container_builder_.SetBlockSize(border_box_size.block_size);
+ container_builder_.SetBorders(ComputeBorders(ConstraintSpace(), Style()));
container_builder_.SetPadding(ComputePadding(ConstraintSpace(), Style()));
return container_builder_.ToBoxFragment();
@@ -190,7 +196,10 @@ base::Optional<MinMaxSize> NGColumnLayoutAlgorithm::ComputeMinMaxSize(
const MinMaxSizeInput& input) const {
// First calculate the min/max sizes of columns.
NGBlockLayoutAlgorithm algorithm(Node(), ConstraintSpace());
- base::Optional<MinMaxSize> min_max_sizes = algorithm.ComputeMinMaxSize(input);
+ MinMaxSizeInput child_input(input);
+ child_input.size_type = NGMinMaxSizeType::kContentBoxSize;
+ base::Optional<MinMaxSize> min_max_sizes =
+ algorithm.ComputeMinMaxSize(child_input);
DCHECK(min_max_sizes.has_value());
MinMaxSize sizes = min_max_sizes.value();
@@ -209,10 +218,13 @@ base::Optional<MinMaxSize> NGColumnLayoutAlgorithm::ComputeMinMaxSize(
sizes.min_size *= column_count;
sizes.max_size *= column_count;
LayoutUnit column_gap = ResolveUsedColumnGap(LayoutUnit(), Style());
- LayoutUnit gap_extra = column_gap * (column_count - 1);
- LayoutUnit border_scrollbar_padding =
- CalculateBorderScrollbarPadding(ConstraintSpace(), node_).InlineSum();
- sizes += gap_extra + border_scrollbar_padding;
+ sizes += column_gap * (column_count - 1);
+
+ if (input.size_type == NGMinMaxSizeType::kBorderBoxSize) {
+ LayoutUnit border_scrollbar_padding =
+ CalculateBorderScrollbarPadding(ConstraintSpace(), node_).InlineSum();
+ sizes += border_scrollbar_padding;
+ }
return sizes;
}
@@ -249,8 +261,7 @@ LayoutUnit NGColumnLayoutAlgorithm::CalculateBalancedColumnBlockSize(
// TODO(mstensho): This is where the fun begins. We need to examine the entire
// fragment tree, not just the root.
- NGFragment fragment(space->GetWritingMode(),
- *result->PhysicalFragment().get());
+ NGFragment fragment(space->GetWritingMode(), *result->PhysicalFragment());
LayoutUnit single_strip_block_size = fragment.BlockSize();
// Some extra care is required the division here. We want a the resulting
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 a01c253edd6..8e4f2d1c591 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
@@ -27,7 +27,7 @@ class NGColumnLayoutAlgorithmTest : public NGBaseLayoutAlgorithmTest {
was_block_fragmentation_enabled_);
}
- scoped_refptr<NGPhysicalBoxFragment> RunBlockLayoutAlgorithm(
+ scoped_refptr<const NGPhysicalBoxFragment> RunBlockLayoutAlgorithm(
const NGConstraintSpace& space,
NGBlockNode node) {
scoped_refptr<NGLayoutResult> result =
@@ -36,7 +36,7 @@ class NGColumnLayoutAlgorithmTest : public NGBaseLayoutAlgorithmTest {
return ToNGPhysicalBoxFragment(result->PhysicalFragment().get());
}
- scoped_refptr<NGPhysicalBoxFragment> RunBlockLayoutAlgorithm(
+ scoped_refptr<const NGPhysicalBoxFragment> RunBlockLayoutAlgorithm(
Element* element) {
NGBlockNode container(ToLayoutBox(element->GetLayoutObject()));
scoped_refptr<NGConstraintSpace> space =
@@ -137,17 +137,18 @@ TEST_F(NGColumnLayoutAlgorithmTest, EmptyBlock) {
iterator.SetParent(fragment);
// first column fragment
- fragment = iterator.NextChild();
+ NGPhysicalOffset offset;
+ fragment = iterator.NextChild(&offset);
ASSERT_TRUE(fragment);
- EXPECT_EQ(NGPhysicalOffset(LayoutUnit(), LayoutUnit()), fragment->Offset());
+ EXPECT_EQ(NGPhysicalOffset(LayoutUnit(), LayoutUnit()), offset);
EXPECT_EQ(NGPhysicalSize(LayoutUnit(100), LayoutUnit()), fragment->Size());
EXPECT_FALSE(iterator.NextChild());
// #child fragment in first column
iterator.SetParent(fragment);
- fragment = iterator.NextChild();
+ fragment = iterator.NextChild(&offset);
ASSERT_TRUE(fragment);
- EXPECT_EQ(NGPhysicalOffset(LayoutUnit(), LayoutUnit()), fragment->Offset());
+ EXPECT_EQ(NGPhysicalOffset(LayoutUnit(), LayoutUnit()), offset);
EXPECT_EQ(NGPhysicalSize(LayoutUnit(100), LayoutUnit()), fragment->Size());
EXPECT_EQ(0UL, fragment->Children().size());
EXPECT_FALSE(iterator.NextChild());
@@ -187,17 +188,18 @@ TEST_F(NGColumnLayoutAlgorithmTest, BlockInOneColumn) {
iterator.SetParent(fragment);
// first column fragment
- fragment = iterator.NextChild();
+ NGPhysicalOffset offset;
+ fragment = iterator.NextChild(&offset);
ASSERT_TRUE(fragment);
- EXPECT_EQ(NGPhysicalOffset(LayoutUnit(), LayoutUnit()), fragment->Offset());
+ EXPECT_EQ(NGPhysicalOffset(LayoutUnit(), LayoutUnit()), offset);
EXPECT_EQ(NGPhysicalSize(LayoutUnit(150), LayoutUnit(100)), fragment->Size());
EXPECT_FALSE(iterator.NextChild());
// #child fragment in first column
iterator.SetParent(fragment);
- fragment = iterator.NextChild();
+ fragment = iterator.NextChild(&offset);
ASSERT_TRUE(fragment);
- EXPECT_EQ(NGPhysicalOffset(LayoutUnit(), LayoutUnit()), fragment->Offset());
+ EXPECT_EQ(NGPhysicalOffset(LayoutUnit(), LayoutUnit()), offset);
EXPECT_EQ(NGPhysicalSize(LayoutUnit(90), LayoutUnit(100)), fragment->Size());
EXPECT_EQ(0UL, fragment->Children().size());
EXPECT_FALSE(iterator.NextChild());
@@ -487,7 +489,7 @@ TEST_F(NGColumnLayoutAlgorithmTest, FloatInOneColumn) {
offset:0,0 size:320x100
offset:0,0 size:100x100
offset:0,0 size:75x100
- offset:0,0 size:0x0
+ offset:75,0 size:0x0
)DUMP";
EXPECT_EQ(expectation, dump);
}
@@ -518,7 +520,7 @@ TEST_F(NGColumnLayoutAlgorithmTest, TwoFloatsInOneColumn) {
offset:0,0 size:100x100
offset:0,0 size:15x100
offset:84,0 size:16x100
- offset:0,0 size:0x0
+ offset:15,0 size:0x0
)DUMP";
EXPECT_EQ(expectation, dump);
}
@@ -549,7 +551,7 @@ TEST_F(NGColumnLayoutAlgorithmTest, TwoFloatsInTwoColumns) {
offset:0,0 size:100x100
offset:0,0 size:15x100
offset:84,0 size:16x100
- offset:0,0 size:0x0
+ offset:15,0 size:0x0
offset:110,0 size:100x50
offset:0,0 size:15x50
offset:84,0 size:16x50
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 f2a01834562..4b0ca0d4c44 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
@@ -17,7 +17,6 @@ namespace blink {
NGConstraintSpace::NGConstraintSpace(
WritingMode writing_mode,
- bool is_orthogonal_writing_mode_root,
TextDirection direction,
NGLogicalSize available_size,
NGLogicalSize percentage_resolution_size,
@@ -25,24 +24,15 @@ NGConstraintSpace::NGConstraintSpace(
NGPhysicalSize initial_containing_block_size,
LayoutUnit fragmentainer_block_size,
LayoutUnit fragmentainer_space_at_bfc_start,
- bool is_fixed_size_inline,
- bool is_fixed_size_block,
- bool fixed_size_block_is_definite,
- bool is_shrink_to_fit,
- bool is_intermediate_layout,
NGFragmentationType block_direction_fragmentation_type,
- bool separate_leading_fragmentainer_margins,
- bool is_new_fc,
- bool is_anonymous,
- bool use_first_line_style,
- bool should_force_clearance,
NGFloatTypes adjoining_floats,
const NGMarginStrut& margin_strut,
const NGBfcOffset& bfc_offset,
- const base::Optional<NGBfcOffset>& floats_bfc_offset,
+ const base::Optional<LayoutUnit>& floats_bfc_block_offset,
const NGExclusionSpace& exclusion_space,
LayoutUnit clearance_offset,
- Vector<NGBaselineRequest>& baseline_requests)
+ Vector<NGBaselineRequest>& baseline_requests,
+ unsigned flags)
: available_size_(available_size),
percentage_resolution_size_(percentage_resolution_size),
parent_percentage_resolution_inline_size_(
@@ -50,25 +40,14 @@ NGConstraintSpace::NGConstraintSpace(
initial_containing_block_size_(initial_containing_block_size),
fragmentainer_block_size_(fragmentainer_block_size),
fragmentainer_space_at_bfc_start_(fragmentainer_space_at_bfc_start),
- is_fixed_size_inline_(is_fixed_size_inline),
- is_fixed_size_block_(is_fixed_size_block),
- fixed_size_block_is_definite_(fixed_size_block_is_definite),
- is_shrink_to_fit_(is_shrink_to_fit),
- is_intermediate_layout_(is_intermediate_layout),
block_direction_fragmentation_type_(block_direction_fragmentation_type),
- separate_leading_fragmentainer_margins_(
- separate_leading_fragmentainer_margins),
- is_new_fc_(is_new_fc),
- is_anonymous_(is_anonymous),
- use_first_line_style_(use_first_line_style),
- should_force_clearance_(should_force_clearance),
adjoining_floats_(adjoining_floats),
writing_mode_(static_cast<unsigned>(writing_mode)),
- is_orthogonal_writing_mode_root_(is_orthogonal_writing_mode_root),
direction_(static_cast<unsigned>(direction)),
+ flags_(flags),
margin_strut_(margin_strut),
bfc_offset_(bfc_offset),
- floats_bfc_offset_(floats_bfc_offset),
+ floats_bfc_block_offset_(floats_bfc_block_offset),
exclusion_space_(std::make_unique<NGExclusionSpace>(exclusion_space)),
clearance_offset_(clearance_offset) {
baseline_requests_.swap(baseline_requests);
@@ -219,23 +198,15 @@ bool NGConstraintSpace::operator==(const NGConstraintSpace& other) const {
fragmentainer_block_size_ == other.fragmentainer_block_size_ &&
fragmentainer_space_at_bfc_start_ ==
other.fragmentainer_space_at_bfc_start_ &&
- is_fixed_size_inline_ == other.is_fixed_size_inline_ &&
- is_fixed_size_block_ == other.is_fixed_size_block_ &&
- is_shrink_to_fit_ == other.is_shrink_to_fit_ &&
- is_intermediate_layout_ == other.is_intermediate_layout_ &&
block_direction_fragmentation_type_ ==
other.block_direction_fragmentation_type_ &&
- is_new_fc_ == other.is_new_fc_ &&
- separate_leading_fragmentainer_margins_ ==
- other.separate_leading_fragmentainer_margins_ &&
- is_anonymous_ == other.is_anonymous_ &&
- should_force_clearance_ == other.should_force_clearance_ &&
+ flags_ == other.flags_ &&
adjoining_floats_ == other.adjoining_floats_ &&
writing_mode_ == other.writing_mode_ &&
direction_ == other.direction_ &&
margin_strut_ == other.margin_strut_ &&
bfc_offset_ == other.bfc_offset_ &&
- floats_bfc_offset_ == other.floats_bfc_offset_ &&
+ floats_bfc_block_offset_ == other.floats_bfc_block_offset_ &&
clearance_offset_ == other.clearance_offset_ &&
baseline_requests_ == other.baseline_requests_;
}
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 2fc95583958..73c7bd7b913 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
@@ -35,6 +35,23 @@ enum NGFragmentationType {
class CORE_EXPORT NGConstraintSpace final
: public RefCounted<NGConstraintSpace> {
public:
+ enum ConstraintSpaceFlags {
+ kOrthogonalWritingModeRoot = 1 << 0,
+ kFixedSizeInline = 1 << 1,
+ kFixedSizeBlock = 1 << 2,
+ kFixedSizeBlockIsDefinite = 1 << 3,
+ kShrinkToFit = 1 << 4,
+ kIntermediateLayout = 1 << 5,
+ kSeparateLeadingFragmentainerMargins = 1 << 6,
+ kNewFormattingContext = 1 << 7,
+ kAnonymous = 1 << 8,
+ kUseFirstLineStyle = 1 << 9,
+ kForceClearance = 1 << 10,
+
+ // Size of bitfield used to store the flags.
+ kNumberOfConstraintSpaceFlags = 11
+ };
+
// Creates NGConstraintSpace representing LayoutObject's containing block.
// This should live on NGBlockNode or another layout bridge and probably take
// a root NGConstraintSpace.
@@ -52,7 +69,7 @@ class CORE_EXPORT NGConstraintSpace final
}
bool IsOrthogonalWritingModeRoot() const {
- return is_orthogonal_writing_mode_root_;
+ return HasFlag(kOrthogonalWritingModeRoot);
}
// The size to use for percentage resolution.
@@ -93,7 +110,7 @@ class CORE_EXPORT NGConstraintSpace final
// Whether the current constraint space is for the newly established
// Formatting Context.
- bool IsNewFormattingContext() const { return is_new_fc_; }
+ bool IsNewFormattingContext() const { return HasFlag(kNewFormattingContext); }
// Return true if we are to separate (i.e. honor, rather than collapse)
// block-start margins at the beginning of fragmentainers. This only makes a
@@ -101,20 +118,20 @@ class CORE_EXPORT NGConstraintSpace final
// block-start margins at the beginning of a fragmentainers are to be
// truncated to 0 if they occur after a soft (unforced) break.
bool HasSeparateLeadingFragmentainerMargins() const {
- return separate_leading_fragmentainer_margins_;
+ return HasFlag(kSeparateLeadingFragmentainerMargins);
}
// Whether the fragment produced from layout should be anonymous, (e.g. it
// may be a column in a multi-column layout). In such cases it shouldn't have
// any borders or padding.
- bool IsAnonymous() const { return is_anonymous_; }
+ bool IsAnonymous() const { return HasFlag(kAnonymous); }
// Whether to use the ':first-line' style or not.
// Note, this is not about the first line of the content to layout, but
// whether the constraint space itself is on the first line, such as when it's
// an inline block.
// Also note this is true only when the document has ':first-line' rules.
- bool UseFirstLineStyle() const { return use_first_line_style_; }
+ bool UseFirstLineStyle() const { return HasFlag(kUseFirstLineStyle); }
// Some layout modes “stretch” their children to a fixed size (e.g. flex,
// grid). These flags represented whether a layout needs to produce a
@@ -123,23 +140,23 @@ class CORE_EXPORT NGConstraintSpace final
//
// If these flags are true, the AvailableSize() is interpreted as the fixed
// border-box size of this box in the respective dimension.
- bool IsFixedSizeInline() const { return is_fixed_size_inline_; }
+ bool IsFixedSizeInline() const { return HasFlag(kFixedSizeInline); }
- bool IsFixedSizeBlock() const { return is_fixed_size_block_; }
+ bool IsFixedSizeBlock() const { return HasFlag(kFixedSizeBlock); }
// Whether a fixed block size should be considered definite.
bool FixedSizeBlockIsDefinite() const {
- return fixed_size_block_is_definite_;
+ return HasFlag(kFixedSizeBlockIsDefinite);
}
// Whether an auto inline-size should be interpreted as shrink-to-fit
// (ie. fit-content). This is used for inline-block, floats, etc.
- bool IsShrinkToFit() const { return is_shrink_to_fit_; }
+ bool IsShrinkToFit() const { return HasFlag(kShrinkToFit); }
// Whether this constraint space is used for an intermediate layout in a
// multi-pass layout. In such a case, we should not copy back the resulting
// layout data to the legacy tree or create a paint fragment from it.
- bool IsIntermediateLayout() const { return is_intermediate_layout_; }
+ bool IsIntermediateLayout() const { return HasFlag(kIntermediateLayout); }
// If specified a layout should produce a Fragment which fragments at the
// blockSize if possible.
@@ -183,8 +200,8 @@ class CORE_EXPORT NGConstraintSpace final
//
// This value is calculated *after* an initial pass of the tree, and should
// only be present during subsequent passes.
- base::Optional<NGBfcOffset> FloatsBfcOffset() const {
- return floats_bfc_offset_;
+ base::Optional<LayoutUnit> FloatsBfcBlockOffset() const {
+ return floats_bfc_block_offset_;
}
// Return the types (none, left, right, both) of preceding adjoining
@@ -223,7 +240,7 @@ class CORE_EXPORT NGConstraintSpace final
// float). So it would just be wrong to check for clearance when we position
// #clearee. Nothing can prevent clearance here. A large margin on the cleared
// child will be canceled out with negative clearance.
- bool ShouldForceClearance() const { return should_force_clearance_; }
+ bool ShouldForceClearance() const { return HasFlag(kForceClearance); }
const Vector<NGBaselineRequest>& BaselineRequests() const {
return baseline_requests_;
@@ -238,7 +255,6 @@ class CORE_EXPORT NGConstraintSpace final
friend class NGConstraintSpaceBuilder;
// Default constructor.
NGConstraintSpace(WritingMode,
- bool is_orthogonal_writing_mode_root,
TextDirection,
NGLogicalSize available_size,
NGLogicalSize percentage_resolution_size,
@@ -246,24 +262,19 @@ class CORE_EXPORT NGConstraintSpace final
NGPhysicalSize initial_containing_block_size,
LayoutUnit fragmentainer_block_size,
LayoutUnit fragmentainer_space_at_bfc_start,
- bool is_fixed_size_inline,
- bool is_fixed_size_block,
- bool fixed_size_block_is_definite,
- bool is_shrink_to_fit,
- bool is_intermediate_layout,
NGFragmentationType block_direction_fragmentation_type,
- bool separate_leading_fragmentainer_margins_,
- bool is_new_fc,
- bool is_anonymous,
- bool use_first_line_style,
- bool should_force_clearance,
NGFloatTypes adjoining_floats,
const NGMarginStrut& margin_strut,
const NGBfcOffset& bfc_offset,
- const base::Optional<NGBfcOffset>& floats_bfc_offset,
+ const base::Optional<LayoutUnit>& floats_bfc_block_offset,
const NGExclusionSpace& exclusion_space,
LayoutUnit clearance_offset,
- Vector<NGBaselineRequest>& baseline_requests);
+ Vector<NGBaselineRequest>& baseline_requests,
+ unsigned flags);
+
+ bool HasFlag(ConstraintSpaceFlags mask) const {
+ return flags_ & static_cast<unsigned>(mask);
+ }
NGLogicalSize available_size_;
NGLogicalSize percentage_resolution_size_;
@@ -273,32 +284,15 @@ class CORE_EXPORT NGConstraintSpace final
LayoutUnit fragmentainer_block_size_;
LayoutUnit fragmentainer_space_at_bfc_start_;
- unsigned is_fixed_size_inline_ : 1;
- unsigned is_fixed_size_block_ : 1;
- unsigned fixed_size_block_is_definite_ : 1;
-
- unsigned is_shrink_to_fit_ : 1;
- unsigned is_intermediate_layout_ : 1;
-
unsigned block_direction_fragmentation_type_ : 2;
- unsigned separate_leading_fragmentainer_margins_ : 1;
-
- // Whether the current constraint space is for the newly established
- // formatting Context
- unsigned is_new_fc_ : 1;
-
- unsigned is_anonymous_ : 1;
- unsigned use_first_line_style_ : 1;
- unsigned should_force_clearance_ : 1;
unsigned adjoining_floats_ : 2; // NGFloatTypes
-
unsigned writing_mode_ : 3;
- unsigned is_orthogonal_writing_mode_root_ : 1;
unsigned direction_ : 1;
+ unsigned flags_ : kNumberOfConstraintSpaceFlags; // ConstraintSpaceFlags
NGMarginStrut margin_strut_;
NGBfcOffset bfc_offset_;
- base::Optional<NGBfcOffset> floats_bfc_offset_;
+ base::Optional<LayoutUnit> floats_bfc_block_offset_;
const std::unique_ptr<const NGExclusionSpace> exclusion_space_;
LayoutUnit clearance_offset_;
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.cc
index f1ed8bb3579..fb9e2d20a1a 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.cc
@@ -13,13 +13,18 @@ NGConstraintSpaceBuilder::NGConstraintSpaceBuilder(
: NGConstraintSpaceBuilder(parent_space.GetWritingMode(),
parent_space.InitialContainingBlockSize()) {
parent_percentage_resolution_size_ = parent_space.PercentageResolutionSize();
- is_intermediate_layout_ = parent_space.IsIntermediateLayout();
+
+ flags_ = NGConstraintSpace::kFixedSizeBlockIsDefinite;
+ if (parent_space.IsIntermediateLayout())
+ flags_ |= NGConstraintSpace::kIntermediateLayout;
}
NGConstraintSpaceBuilder::NGConstraintSpaceBuilder(WritingMode writing_mode,
NGPhysicalSize icb_size)
: initial_containing_block_size_(icb_size),
- parent_writing_mode_(writing_mode) {}
+ parent_writing_mode_(writing_mode) {
+ flags_ = NGConstraintSpace::kFixedSizeBlockIsDefinite;
+}
NGConstraintSpaceBuilder& NGConstraintSpaceBuilder::SetAvailableSize(
NGLogicalSize available_size) {
@@ -51,9 +56,9 @@ NGConstraintSpaceBuilder& NGConstraintSpaceBuilder::SetBfcOffset(
return *this;
}
-NGConstraintSpaceBuilder& NGConstraintSpaceBuilder::SetFloatsBfcOffset(
- const base::Optional<NGBfcOffset>& floats_bfc_offset) {
- floats_bfc_offset_ = floats_bfc_offset;
+NGConstraintSpaceBuilder& NGConstraintSpaceBuilder::SetFloatsBfcBlockOffset(
+ const base::Optional<LayoutUnit>& floats_bfc_block_offset) {
+ floats_bfc_block_offset_ = floats_bfc_block_offset;
return *this;
}
@@ -69,60 +74,12 @@ NGConstraintSpaceBuilder& NGConstraintSpaceBuilder::SetExclusionSpace(
return *this;
}
-NGConstraintSpaceBuilder& NGConstraintSpaceBuilder::SetIsFixedSizeInline(
- bool is_fixed_size_inline) {
- is_fixed_size_inline_ = is_fixed_size_inline;
- return *this;
-}
-
-NGConstraintSpaceBuilder& NGConstraintSpaceBuilder::SetIsFixedSizeBlock(
- bool is_fixed_size_block) {
- is_fixed_size_block_ = is_fixed_size_block;
- return *this;
-}
-
-NGConstraintSpaceBuilder& NGConstraintSpaceBuilder::SetFixedSizeBlockIsDefinite(
- bool fixed_size_block_is_definite) {
- fixed_size_block_is_definite_ = fixed_size_block_is_definite;
- return *this;
-}
-
-NGConstraintSpaceBuilder& NGConstraintSpaceBuilder::SetIsShrinkToFit(
- bool shrink_to_fit) {
- is_shrink_to_fit_ = shrink_to_fit;
- return *this;
-}
-
-NGConstraintSpaceBuilder& NGConstraintSpaceBuilder::SetIsIntermediateLayout(
- bool is_intermediate_layout) {
- is_intermediate_layout_ = is_intermediate_layout;
- return *this;
-}
-
NGConstraintSpaceBuilder& NGConstraintSpaceBuilder::SetFragmentationType(
NGFragmentationType fragmentation_type) {
fragmentation_type_ = fragmentation_type;
return *this;
}
-NGConstraintSpaceBuilder& NGConstraintSpaceBuilder::SetIsNewFormattingContext(
- bool is_new_fc) {
- is_new_fc_ = is_new_fc;
- return *this;
-}
-
-NGConstraintSpaceBuilder& NGConstraintSpaceBuilder::SetIsAnonymous(
- bool is_anonymous) {
- is_anonymous_ = is_anonymous;
- return *this;
-}
-
-NGConstraintSpaceBuilder& NGConstraintSpaceBuilder::SetUseFirstLineStyle(
- bool use_first_line_style) {
- use_first_line_style_ = use_first_line_style;
- return *this;
-}
-
void NGConstraintSpaceBuilder::AddBaselineRequests(
const Vector<NGBaselineRequest>& requests) {
DCHECK(baseline_requests_.IsEmpty());
@@ -150,17 +107,25 @@ scoped_refptr<NGConstraintSpace> NGConstraintSpaceBuilder::ToConstraintSpace(
NGLogicalSize percentage_resolution_size = percentage_resolution_size_;
NGLogicalSize parent_percentage_resolution_size =
parent_percentage_resolution_size_.value_or(percentage_resolution_size);
- bool is_fixed_size_inline = is_fixed_size_inline_;
- bool is_fixed_size_block = is_fixed_size_block_;
- bool fixed_size_block_is_definite = fixed_size_block_is_definite_;
+
+ unsigned resolved_flags = flags_;
+ auto SetResolvedFlag = [&resolved_flags](unsigned mask, bool value) {
+ resolved_flags = (resolved_flags & ~static_cast<unsigned>(mask)) |
+ (-(int32_t)value & static_cast<unsigned>(mask));
+ };
if (!is_in_parallel_flow) {
available_size.Flip();
percentage_resolution_size.Flip();
parent_percentage_resolution_size.Flip();
- is_fixed_size_inline = is_fixed_size_block_;
- is_fixed_size_block = is_fixed_size_inline_;
- fixed_size_block_is_definite = true;
+ SetResolvedFlag(NGConstraintSpace::kFixedSizeInline,
+ flags_ & NGConstraintSpace::kFixedSizeBlock);
+ SetResolvedFlag(NGConstraintSpace::kFixedSizeBlock,
+ flags_ & NGConstraintSpace::kFixedSizeInline);
+ SetResolvedFlag(NGConstraintSpace::kFixedSizeBlockIsDefinite, true);
+ SetResolvedFlag(NGConstraintSpace::kOrthogonalWritingModeRoot, true);
}
+ DCHECK_EQ(resolved_flags & NGConstraintSpace::kOrthogonalWritingModeRoot,
+ !is_in_parallel_flow);
// If inline size is indefinite, use size of initial containing block.
// https://www.w3.org/TR/css-writing-modes-3/#orthogonal-auto
@@ -183,10 +148,10 @@ scoped_refptr<NGConstraintSpace> NGConstraintSpaceBuilder::ToConstraintSpace(
}
}
- DEFINE_STATIC_LOCAL(NGExclusionSpace, empty_exclusion_space, ());
-
+ bool is_new_fc_ = flags_ & NGConstraintSpace::kNewFormattingContext;
DCHECK(!is_new_fc_ || !adjoining_floats_);
+ DEFINE_STATIC_LOCAL(NGExclusionSpace, empty_exclusion_space, ());
const NGExclusionSpace& exclusion_space = (is_new_fc_ || !exclusion_space_)
? empty_exclusion_space
: *exclusion_space_;
@@ -194,25 +159,16 @@ scoped_refptr<NGConstraintSpace> NGConstraintSpaceBuilder::ToConstraintSpace(
NGMarginStrut margin_strut = is_new_fc_ ? NGMarginStrut() : margin_strut_;
LayoutUnit clearance_offset =
is_new_fc_ ? LayoutUnit::Min() : clearance_offset_;
- base::Optional<NGBfcOffset> floats_bfc_offset =
- is_new_fc_ ? base::nullopt : floats_bfc_offset_;
-
- if (floats_bfc_offset) {
- floats_bfc_offset = NGBfcOffset(
- {bfc_offset.line_offset, floats_bfc_offset.value().block_offset});
- }
+ base::Optional<LayoutUnit> floats_bfc_block_offset =
+ is_new_fc_ ? base::nullopt : floats_bfc_block_offset_;
return base::AdoptRef(new NGConstraintSpace(
- out_writing_mode, !is_in_parallel_flow, text_direction_, available_size,
+ out_writing_mode, text_direction_, available_size,
percentage_resolution_size, parent_percentage_resolution_size.inline_size,
initial_containing_block_size_, fragmentainer_block_size_,
- fragmentainer_space_at_bfc_start_, is_fixed_size_inline,
- is_fixed_size_block, fixed_size_block_is_definite, is_shrink_to_fit_,
- is_intermediate_layout_, fragmentation_type_,
- separate_leading_fragmentainer_margins_, is_new_fc_, is_anonymous_,
- use_first_line_style_, should_force_clearance_, adjoining_floats_,
- margin_strut, bfc_offset, floats_bfc_offset, exclusion_space,
- clearance_offset, baseline_requests_));
+ fragmentainer_space_at_bfc_start_, fragmentation_type_, adjoining_floats_,
+ margin_strut, bfc_offset, floats_bfc_block_offset, exclusion_space,
+ clearance_offset, baseline_requests_, resolved_flags));
}
} // namespace blink
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 a23c2d926bb..de7e02eec0a 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
@@ -46,26 +46,51 @@ class CORE_EXPORT NGConstraintSpaceBuilder final {
NGConstraintSpaceBuilder& SetTextDirection(TextDirection);
- NGConstraintSpaceBuilder& SetIsFixedSizeInline(bool is_fixed_size_inline);
- NGConstraintSpaceBuilder& SetIsFixedSizeBlock(bool is_fixed_size_block);
- NGConstraintSpaceBuilder& SetFixedSizeBlockIsDefinite(
- bool fixed_size_block_is_definite);
+ NGConstraintSpaceBuilder& SetIsFixedSizeInline(bool b) {
+ SetFlag(NGConstraintSpace::kFixedSizeInline, b);
+ return *this;
+ }
- NGConstraintSpaceBuilder& SetIsShrinkToFit(bool shrink_to_fit);
+ NGConstraintSpaceBuilder& SetIsFixedSizeBlock(bool b) {
+ SetFlag(NGConstraintSpace::kFixedSizeBlock, b);
+ return *this;
+ }
- NGConstraintSpaceBuilder& SetIsIntermediateLayout(
- bool is_intermediate_layout);
+ NGConstraintSpaceBuilder& SetFixedSizeBlockIsDefinite(bool b) {
+ SetFlag(NGConstraintSpace::kFixedSizeBlockIsDefinite, b);
+ return *this;
+ }
+
+ NGConstraintSpaceBuilder& SetIsShrinkToFit(bool b) {
+ SetFlag(NGConstraintSpace::kShrinkToFit, b);
+ return *this;
+ }
+
+ NGConstraintSpaceBuilder& SetIsIntermediateLayout(bool b) {
+ SetFlag(NGConstraintSpace::kIntermediateLayout, b);
+ return *this;
+ }
NGConstraintSpaceBuilder& SetFragmentationType(NGFragmentationType);
- NGConstraintSpaceBuilder& SetSeparateLeadingFragmentainerMargins(bool val) {
- separate_leading_fragmentainer_margins_ = val;
+ NGConstraintSpaceBuilder& SetSeparateLeadingFragmentainerMargins(bool b) {
+ SetFlag(NGConstraintSpace::kSeparateLeadingFragmentainerMargins, b);
return *this;
}
- NGConstraintSpaceBuilder& SetIsNewFormattingContext(bool is_new_fc);
- NGConstraintSpaceBuilder& SetIsAnonymous(bool is_anonymous);
- NGConstraintSpaceBuilder& SetUseFirstLineStyle(bool use_first_line_style);
+ NGConstraintSpaceBuilder& SetIsNewFormattingContext(bool b) {
+ SetFlag(NGConstraintSpace::kNewFormattingContext, b);
+ return *this;
+ }
+ NGConstraintSpaceBuilder& SetIsAnonymous(bool b) {
+ SetFlag(NGConstraintSpace::kAnonymous, b);
+ return *this;
+ }
+
+ NGConstraintSpaceBuilder& SetUseFirstLineStyle(bool b) {
+ SetFlag(NGConstraintSpace::kUseFirstLineStyle, b);
+ return *this;
+ }
NGConstraintSpaceBuilder& SetAdjoiningFloatTypes(NGFloatTypes floats) {
adjoining_floats_ = floats;
@@ -75,13 +100,13 @@ class CORE_EXPORT NGConstraintSpaceBuilder final {
NGConstraintSpaceBuilder& SetMarginStrut(const NGMarginStrut& margin_strut);
NGConstraintSpaceBuilder& SetBfcOffset(const NGBfcOffset& bfc_offset);
- NGConstraintSpaceBuilder& SetFloatsBfcOffset(
- const base::Optional<NGBfcOffset>& floats_bfc_offset);
+ NGConstraintSpaceBuilder& SetFloatsBfcBlockOffset(
+ const base::Optional<LayoutUnit>&);
NGConstraintSpaceBuilder& SetClearanceOffset(LayoutUnit clearance_offset);
- NGConstraintSpaceBuilder& SetShouldForceClearance() {
- should_force_clearance_ = true;
+ NGConstraintSpaceBuilder& SetShouldForceClearance(bool b) {
+ SetFlag(NGConstraintSpace::kForceClearance, b);
return *this;
}
@@ -102,6 +127,11 @@ class CORE_EXPORT NGConstraintSpaceBuilder final {
scoped_refptr<NGConstraintSpace> ToConstraintSpace(WritingMode);
private:
+ void SetFlag(NGConstraintSpace::ConstraintSpaceFlags mask, bool value) {
+ flags_ = (flags_ & ~static_cast<unsigned>(mask)) |
+ (-(int32_t)value & static_cast<unsigned>(mask));
+ }
+
// Relative to parent_writing_mode_.
NGLogicalSize available_size_;
// Relative to parent_writing_mode_.
@@ -115,20 +145,12 @@ class CORE_EXPORT NGConstraintSpaceBuilder final {
NGFragmentationType fragmentation_type_ = kFragmentNone;
NGFloatTypes adjoining_floats_ = kFloatTypeNone;
TextDirection text_direction_ = TextDirection::kLtr;
- bool is_fixed_size_inline_ = false;
- bool is_fixed_size_block_ = false;
- bool fixed_size_block_is_definite_ = true;
- bool is_shrink_to_fit_ = false;
- bool is_intermediate_layout_ = false;
- bool separate_leading_fragmentainer_margins_ = false;
- bool is_new_fc_ = false;
- bool is_anonymous_ = false;
- bool use_first_line_style_ = false;
- bool should_force_clearance_ = false;
+
+ unsigned flags_;
NGMarginStrut margin_strut_;
NGBfcOffset bfc_offset_;
- base::Optional<NGBfcOffset> floats_bfc_offset_;
+ base::Optional<LayoutUnit> floats_bfc_block_offset_;
const NGExclusionSpace* exclusion_space_ = nullptr;
LayoutUnit clearance_offset_;
Vector<NGBaselineRequest> baseline_requests_;
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 e66e4791e93..7441e914307 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
@@ -27,12 +27,6 @@ NGContainerFragmentBuilder& NGContainerFragmentBuilder::SetInlineSize(
return *this;
}
-NGContainerFragmentBuilder& NGContainerFragmentBuilder::SetBfcOffset(
- const NGBfcOffset& bfc_offset) {
- bfc_offset_ = bfc_offset;
- return *this;
-}
-
NGContainerFragmentBuilder& NGContainerFragmentBuilder::SetEndMarginStrut(
const NGMarginStrut& end_margin_strut) {
end_margin_strut_ = end_margin_strut;
@@ -101,7 +95,7 @@ NGContainerFragmentBuilder& NGContainerFragmentBuilder::AddChild(
}
NGContainerFragmentBuilder& NGContainerFragmentBuilder::AddChild(
- scoped_refptr<NGPhysicalFragment> child,
+ scoped_refptr<const NGPhysicalFragment> child,
const NGLogicalOffset& child_offset) {
if (!has_last_resort_break_) {
if (const auto* token = child->BreakToken()) {
@@ -110,7 +104,7 @@ NGContainerFragmentBuilder& NGContainerFragmentBuilder::AddChild(
has_last_resort_break_ = true;
}
}
- children_.push_back(std::move(child));
+ children_.emplace_back(std::move(child), NGPhysicalOffset());
offsets_.push_back(child_offset);
return *this;
}
@@ -203,17 +197,23 @@ void NGContainerFragmentBuilder::GetAndClearOutOfFlowDescendantCandidates(
oof_positioned_candidates_.clear();
}
-void NGContainerFragmentBuilder::
- MoveOutOfFlowDescendantCandidatesToDescendants() {
+void NGContainerFragmentBuilder::MoveOutOfFlowDescendantCandidatesToDescendants(
+ const LayoutObject* inline_container) {
GetAndClearOutOfFlowDescendantCandidates(&oof_positioned_descendants_,
nullptr);
+ if (inline_container) {
+ for (auto& descendant : oof_positioned_descendants_) {
+ if (!descendant.inline_container)
+ descendant.inline_container = inline_container;
+ }
+ }
}
#ifndef NDEBUG
String NGContainerFragmentBuilder::ToString() const {
StringBuilder builder;
- builder.Append(String::Format("ContainerFragment %.2fx%.2f, Children %zu\n",
+ builder.Append(String::Format("ContainerFragment %.2fx%.2f, Children %u\n",
InlineSize().ToFloat(), BlockSize().ToFloat(),
children_.size()));
for (auto& child : children_) {
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 ce44f7a02ba..ca26100c7ea 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
@@ -13,6 +13,7 @@
#include "third_party/blink/renderer/core/layout/ng/list/ng_unpositioned_list_marker.h"
#include "third_party/blink/renderer/core/layout/ng/ng_base_fragment_builder.h"
#include "third_party/blink/renderer/core/layout/ng/ng_floats_utils.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_link.h"
#include "third_party/blink/renderer/core/layout/ng/ng_out_of_flow_positioned_descendant.h"
#include "third_party/blink/renderer/platform/text/text_direction.h"
#include "third_party/blink/renderer/platform/text/writing_mode.h"
@@ -37,12 +38,23 @@ class CORE_EXPORT NGContainerFragmentBuilder : public NGBaseFragmentBuilder {
NGContainerFragmentBuilder& SetInlineSize(LayoutUnit);
void SetBlockSize(LayoutUnit block_size) { size_.block_size = block_size; }
+ LayoutUnit BfcLineOffset() const { return bfc_line_offset_; }
+ NGContainerFragmentBuilder& SetBfcLineOffset(LayoutUnit bfc_line_offset) {
+ bfc_line_offset_ = bfc_line_offset;
+ return *this;
+ }
+
// The NGBfcOffset is where this fragment was positioned within the BFC. If
// it is not set, this fragment may be placed anywhere within the BFC.
- const base::Optional<NGBfcOffset>& BfcOffset() const { return bfc_offset_; }
- NGContainerFragmentBuilder& SetBfcOffset(const NGBfcOffset&);
- NGContainerFragmentBuilder& ResetBfcOffset() {
- bfc_offset_.reset();
+ const base::Optional<LayoutUnit>& BfcBlockOffset() const {
+ return bfc_block_offset_;
+ }
+ NGContainerFragmentBuilder& SetBfcBlockOffset(LayoutUnit bfc_block_offset) {
+ bfc_block_offset_ = bfc_block_offset;
+ return *this;
+ }
+ NGContainerFragmentBuilder& ResetBfcBlockOffset() {
+ bfc_block_offset_.reset();
return *this;
}
@@ -63,12 +75,10 @@ class CORE_EXPORT NGContainerFragmentBuilder : public NGBaseFragmentBuilder {
// This version of AddChild will not propagate floats/out_of_flow.
// Use the AddChild(NGLayoutResult) variant if NGLayoutResult is available.
virtual NGContainerFragmentBuilder& AddChild(
- scoped_refptr<NGPhysicalFragment>,
+ scoped_refptr<const NGPhysicalFragment>,
const NGLogicalOffset&);
- const Vector<scoped_refptr<NGPhysicalFragment>>& Children() const {
- return children_;
- }
+ const Vector<NGLink>& Children() const { return children_; }
// Builder has non-trivial out-of-flow descendant methods.
// These methods are building blocks for implementation of
@@ -117,8 +127,9 @@ class CORE_EXPORT NGContainerFragmentBuilder : public NGBaseFragmentBuilder {
const LayoutObject* container);
// Utility routine to move all OOF descendant candidates to descendants.
- // Use if fragment cannot hold any OOF children.
- void MoveOutOfFlowDescendantCandidatesToDescendants();
+ // Use if fragment cannot position any OOF children.
+ void MoveOutOfFlowDescendantCandidatesToDescendants(
+ const LayoutObject* inline_container);
NGContainerFragmentBuilder& SetIsPushedByFloats() {
is_pushed_by_floats_ = true;
@@ -185,7 +196,8 @@ class CORE_EXPORT NGContainerFragmentBuilder : public NGBaseFragmentBuilder {
NGLogicalSize size_;
- base::Optional<NGBfcOffset> bfc_offset_;
+ LayoutUnit bfc_line_offset_;
+ base::Optional<LayoutUnit> bfc_block_offset_;
NGMarginStrut end_margin_strut_;
std::unique_ptr<const NGExclusionSpace> exclusion_space_;
@@ -194,7 +206,14 @@ class CORE_EXPORT NGContainerFragmentBuilder : public NGBaseFragmentBuilder {
NGUnpositionedListMarker unpositioned_list_marker_;
- Vector<scoped_refptr<NGPhysicalFragment>> children_;
+ // Store NGLinks rather than NGPhysicalOffsets even though we don't have the
+ // offsets yet to allow us to move the entire vector to the fragment at
+ // construction time.
+ Vector<NGLink> children_;
+
+ // Logical offsets for the children. Stored as logical offsets as we can't
+ // convert to physical offsets until layout of all children has been
+ // determined.
Vector<NGLogicalOffset> offsets_;
NGFloatTypes adjoining_floats_ = kFloatTypeNone;
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 c6e35dfa207..ed84346cc8a 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
@@ -26,11 +26,15 @@ scoped_refptr<NGLayoutResult> NGFlexLayoutAlgorithm::Layout() {
DCHECK(!NeedMinMaxSize(ConstraintSpace(), Style()))
<< "Don't support that yet";
+ NGLogicalSize flex_container_border_box_size =
+ CalculateBorderBoxSize(ConstraintSpace(), Node());
+ NGLogicalSize flex_container_content_box_size = CalculateContentBoxSize(
+ flex_container_border_box_size,
+ CalculateBorderScrollbarPadding(ConstraintSpace(), Node()));
LayoutUnit flex_container_border_box_inline_size =
- ComputeInlineSizeForFragment(ConstraintSpace(), Node());
+ flex_container_border_box_size.inline_size;
LayoutUnit flex_container_content_inline_size =
- flex_container_border_box_inline_size -
- CalculateBorderScrollbarPadding(ConstraintSpace(), Node()).InlineSum();
+ flex_container_content_box_size.inline_size;
Vector<FlexItem> flex_items;
for (NGLayoutInputNode generic_child = Node().FirstChild(); generic_child;
@@ -40,11 +44,8 @@ scoped_refptr<NGLayoutResult> NGFlexLayoutAlgorithm::Layout() {
continue;
NGConstraintSpaceBuilder space_builder(ConstraintSpace());
- // TODO(dgrogan): Set the percentage size also, which is possibly
- // flex_container_content_inline_size. Also change NGSizeIndefinite to
- // container size if it's definite.
- space_builder.SetAvailableSize(
- NGLogicalSize{flex_container_content_inline_size, NGSizeIndefinite});
+ space_builder.SetAvailableSize(flex_container_content_box_size);
+ space_builder.SetPercentageResolutionSize(flex_container_content_box_size);
scoped_refptr<NGConstraintSpace> child_space =
space_builder.ToConstraintSpace(child.Style().GetWritingMode());
@@ -57,10 +58,6 @@ scoped_refptr<NGLayoutResult> NGFlexLayoutAlgorithm::Layout() {
MinMaxSize min_max_sizes_border_box = child.ComputeMinMaxSize(
ConstraintSpace().GetWritingMode(), zero_input, child_space.get());
- // 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_border_box;
if (child.Style().FlexBasis().IsAuto() && child.Style().Width().IsAuto()) {
flex_base_border_box = min_max_sizes_border_box.max_size;
@@ -78,6 +75,10 @@ scoped_refptr<NGLayoutResult> NGFlexLayoutAlgorithm::Layout() {
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.
LayoutUnit flex_base_content_size =
flex_base_border_box - main_axis_border_and_padding;
@@ -104,11 +105,11 @@ scoped_refptr<NGLayoutResult> NGFlexLayoutAlgorithm::Layout() {
NGBoxStrut borders_scrollbar_padding =
CalculateBorderScrollbarPadding(ConstraintSpace(), Node());
- LayoutUnit main_axis_offset = borders_scrollbar_padding.InlineSum();
- LayoutUnit cross_axis_offset = borders_scrollbar_padding.BlockSum();
+ LayoutUnit main_axis_offset = borders_scrollbar_padding.inline_start;
+ LayoutUnit cross_axis_offset = borders_scrollbar_padding.block_start;
FlexLine* line;
while ((line = algorithm.ComputeNextFlexLine(
- flex_container_content_inline_size))) {
+ flex_container_border_box_inline_size))) {
// TODO(dgrogan): This parameter is more complicated for columns.
line->SetContainerMainInnerSize(flex_container_content_inline_size);
line->FreezeInflexibleItems();
@@ -118,11 +119,12 @@ scoped_refptr<NGLayoutResult> NGFlexLayoutAlgorithm::Layout() {
for (size_t i = 0; i < line->line_items.size(); ++i) {
FlexItem& flex_item = line->line_items[i];
NGConstraintSpaceBuilder space_builder(ConstraintSpace());
- // TODO(dgrogan): Set the percentage size also.
- space_builder.SetAvailableSize(
- {flex_item.flexed_content_size +
- flex_item.main_axis_border_and_padding,
- NGSizeIndefinite});
+ NGLogicalSize available_size(flex_item.flexed_content_size +
+ flex_item.main_axis_border_and_padding,
+ flex_container_content_box_size.block_size);
+ space_builder.SetAvailableSize(available_size);
+ space_builder.SetPercentageResolutionSize(
+ flex_container_content_box_size);
space_builder.SetIsFixedSizeInline(true);
scoped_refptr<NGConstraintSpace> child_space =
space_builder.ToConstraintSpace(
@@ -156,6 +158,8 @@ scoped_refptr<NGLayoutResult> NGFlexLayoutAlgorithm::Layout() {
ConstraintSpace(), Style(), intrinsic_block_size);
container_builder_.SetBlockSize(block_size);
container_builder_.SetInlineSize(flex_container_border_box_inline_size);
+ container_builder_.SetBorders(ComputeBorders(ConstraintSpace(), Style()));
+ container_builder_.SetPadding(ComputePadding(ConstraintSpace(), Style()));
return container_builder_.ToBoxFragment();
}
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 c6d40fe1f63..8d6e1997467 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
@@ -12,6 +12,7 @@
#include "third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h"
#include "third_party/blink/renderer/core/layout/ng/ng_container_fragment_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_positioned_float.h"
@@ -37,71 +38,61 @@ NGBfcOffset AdjustToTopEdgeAlignmentRule(
}
NGLayoutOpportunity FindLayoutOpportunityForFloat(
- const NGBfcOffset& origin_offset,
+ const NGLogicalSize& float_available_size,
+ const NGBfcOffset& origin_bfc_offset,
const NGExclusionSpace& exclusion_space,
const NGUnpositionedFloat& unpositioned_float,
+ const NGBoxStrut& fragment_margins,
LayoutUnit inline_size) {
NGBfcOffset adjusted_origin_point =
- AdjustToTopEdgeAlignmentRule(exclusion_space, origin_offset);
+ AdjustToTopEdgeAlignmentRule(exclusion_space, origin_bfc_offset);
LayoutUnit clearance_offset =
exclusion_space.ClearanceOffset(unpositioned_float.ClearType());
AdjustToClearance(clearance_offset, &adjusted_origin_point);
- NGLogicalSize float_size(inline_size + unpositioned_float.margins.InlineSum(),
+ NGLogicalSize float_size(inline_size + fragment_margins.InlineSum(),
LayoutUnit());
- // TODO(ikilpatrick): Don't include the block-start margin of a float which
- // has fragmented.
return exclusion_space.FindLayoutOpportunity(
- adjusted_origin_point, unpositioned_float.available_size.inline_size,
- float_size);
+ adjusted_origin_point, float_available_size.inline_size, float_size);
}
-scoped_refptr<NGConstraintSpace> CreateConstraintSpaceForFloatFromBuilder(
- const NGUnpositionedFloat& unpositioned_float,
- NGConstraintSpaceBuilder& builder) {
- const ComputedStyle& style = unpositioned_float.node.Style();
- return builder.SetPercentageResolutionSize(unpositioned_float.percentage_size)
- .SetAvailableSize(unpositioned_float.available_size)
- .SetIsNewFormattingContext(true)
- .SetIsShrinkToFit(true)
- .SetTextDirection(style.Direction())
- .ToConstraintSpace(style.GetWritingMode());
-}
-
-// Creates a constraint space for an unpositioned float, with the intent to
-// position it.
+// Creates a constraint space for an unpositioned float. origin_block_offset
+// should only be set when we want to fragmentation to occur.
scoped_refptr<NGConstraintSpace> CreateConstraintSpaceForFloat(
+ const NGLogicalSize& float_available_size,
+ const NGLogicalSize& float_percentage_size,
const NGUnpositionedFloat& unpositioned_float,
const NGConstraintSpace& parent_space,
- LayoutUnit origin_block_offset) {
+ base::Optional<LayoutUnit> origin_block_offset = base::nullopt) {
+ const ComputedStyle& style = unpositioned_float.node.Style();
NGConstraintSpaceBuilder builder(parent_space);
- DCHECK_EQ(unpositioned_float.node.Style().GetWritingMode(),
- parent_space.GetWritingMode());
- if (parent_space.HasBlockFragmentation()) {
+ if (origin_block_offset) {
+ DCHECK(parent_space.HasBlockFragmentation());
+ DCHECK_EQ(style.GetWritingMode(), parent_space.GetWritingMode());
+
LayoutUnit fragmentation_offset =
- parent_space.FragmentainerSpaceAtBfcStart() - origin_block_offset;
+ parent_space.FragmentainerSpaceAtBfcStart() -
+ origin_block_offset.value();
builder.SetFragmentainerBlockSize(parent_space.FragmentainerBlockSize());
builder.SetFragmentainerSpaceAtBfcStart(fragmentation_offset);
builder.SetFragmentationType(parent_space.BlockFragmentationType());
} else {
builder.SetFragmentationType(NGFragmentationType::kFragmentNone);
}
- return CreateConstraintSpaceForFloatFromBuilder(unpositioned_float, builder);
-}
-// Creates a constraint space for an unpositioned float, with the intent to
-// simply calculate its inline size.
-scoped_refptr<NGConstraintSpace>
-CreateConstraintSpaceForFloatForInlineSizeCalculation(
- const NGUnpositionedFloat& unpositioned_float,
- const NGConstraintSpace& parent_space) {
- NGConstraintSpaceBuilder builder(parent_space);
- return CreateConstraintSpaceForFloatFromBuilder(unpositioned_float, builder);
+ return builder.SetPercentageResolutionSize(float_percentage_size)
+ .SetAvailableSize(float_available_size)
+ .SetIsNewFormattingContext(true)
+ .SetIsShrinkToFit(true)
+ .SetTextDirection(style.Direction())
+ .ToConstraintSpace(style.GetWritingMode());
}
std::unique_ptr<NGExclusionShapeData> CreateExclusionShapeData(
+ const NGLogicalSize& float_available_size,
+ const NGLogicalSize& float_percentage_size,
const NGBoxStrut& margins,
const LayoutBox* layout_box,
const NGUnpositionedFloat& unpositioned_float,
@@ -125,7 +116,8 @@ std::unique_ptr<NGExclusionShapeData> CreateExclusionShapeData(
break;
case CSSBoxType::kPadding:
shape_insets =
- ComputeBorders(*CreateConstraintSpaceForFloatForInlineSizeCalculation(
+ ComputeBorders(*CreateConstraintSpaceForFloat(
+ float_available_size, float_percentage_size,
unpositioned_float, parent_space),
style)
.ConvertToPhysical(style.GetWritingMode(), style.Direction())
@@ -134,8 +126,9 @@ std::unique_ptr<NGExclusionShapeData> CreateExclusionShapeData(
break;
case CSSBoxType::kContent:
const scoped_refptr<NGConstraintSpace> space =
- CreateConstraintSpaceForFloatForInlineSizeCalculation(
- unpositioned_float, parent_space);
+ CreateConstraintSpaceForFloat(float_available_size,
+ float_percentage_size,
+ unpositioned_float, parent_space);
NGBoxStrut border_padding =
ComputeBorders(*space, style) + ComputePadding(*space, style);
shape_insets =
@@ -153,6 +146,8 @@ std::unique_ptr<NGExclusionShapeData> CreateExclusionShapeData(
// Creates an exclusion from the fragment that will be placed in the provided
// layout opportunity.
scoped_refptr<NGExclusion> CreateExclusion(
+ const NGLogicalSize& float_available_size,
+ const NGLogicalSize& float_percentage_size,
const NGFragment& fragment,
const NGBfcOffset& float_margin_bfc_offset,
const NGBoxStrut& margins,
@@ -161,154 +156,130 @@ scoped_refptr<NGExclusion> CreateExclusion(
const NGConstraintSpace& parent_space,
TextDirection direction,
EFloat type) {
- // TODO(ikilpatrick): Don't include the block-start margin of a float which
- // has fragmented.
NGBfcOffset start_offset = float_margin_bfc_offset;
-
NGBfcOffset end_offset(
- /* line_offset */ start_offset.line_offset +
+ start_offset.line_offset +
(fragment.InlineSize() + margins.InlineSum()).ClampNegativeToZero(),
- /* block_offset */ start_offset.block_offset +
+ start_offset.block_offset +
(fragment.BlockSize() + margins.BlockSum()).ClampNegativeToZero());
std::unique_ptr<NGExclusionShapeData> shape_data =
layout_box->GetShapeOutsideInfo()
- ? CreateExclusionShapeData(margins, layout_box, unpositioned_float,
- parent_space, direction)
+ ? CreateExclusionShapeData(
+ float_available_size, float_percentage_size, margins,
+ layout_box, unpositioned_float, parent_space, direction)
: nullptr;
return NGExclusion::Create(NGBfcRect(start_offset, end_offset), type,
std::move(shape_data));
}
+// Performs layout on a float, without fragmentation, and stores the result on
+// the NGUnpositionedFloat data-structure.
+void LayoutFloatWithoutFragmentation(const NGLogicalSize& float_available_size,
+ const NGLogicalSize& float_percentage_size,
+ const NGConstraintSpace& parent_space,
+ NGUnpositionedFloat* unpositioned_float) {
+ if (unpositioned_float->layout_result)
+ return;
+
+ const scoped_refptr<NGConstraintSpace> space =
+ CreateConstraintSpaceForFloat(float_available_size, float_percentage_size,
+ *unpositioned_float, parent_space);
+
+ unpositioned_float->layout_result = unpositioned_float->node.Layout(*space);
+ unpositioned_float->margins =
+ ComputeMarginsFor(*space, unpositioned_float->node.Style(), parent_space);
+}
+
} // namespace
-LayoutUnit ComputeInlineSizeForUnpositionedFloat(
+LayoutUnit ComputeMarginBoxInlineSizeForUnpositionedFloat(
const NGConstraintSpace& parent_space,
NGUnpositionedFloat* unpositioned_float) {
DCHECK(unpositioned_float);
- const ComputedStyle& style = unpositioned_float->node.Style();
-
- bool is_same_writing_mode =
- style.GetWritingMode() == parent_space.GetWritingMode();
-
- // If we've already performed layout on the unpositioned float, just return
- // the cached value.
- if (unpositioned_float->layout_result) {
- // TODO(layout-ng): Should this use IsParallelWritingMode()?
- DCHECK(!is_same_writing_mode);
- DCHECK(unpositioned_float->layout_result->PhysicalFragment());
- return NGFragment(parent_space.GetWritingMode(),
- *unpositioned_float->layout_result->PhysicalFragment())
- .InlineSize();
- }
+ // NOTE: We can safely use the parent space's available and percentage size
+ // as this function should only be called within an inline context.
+ LayoutFloatWithoutFragmentation(parent_space.AvailableSize(),
+ parent_space.PercentageResolutionSize(),
+ parent_space, unpositioned_float);
+ DCHECK(unpositioned_float->layout_result);
- const scoped_refptr<NGConstraintSpace> space =
- CreateConstraintSpaceForFloatForInlineSizeCalculation(*unpositioned_float,
- parent_space);
-
- // If the float has the same writing mode as the block formatting context we
- // shouldn't perform a full layout just yet. Our position may determine where
- // we fragment. If we cannot use NG for layout of the node, though, we do have
- // to lay out (and just read out the inline size and then discard the result),
- // because NG cannot figure out the size of such objects on its own,
- // especially not for tables.
- if (is_same_writing_mode && unpositioned_float->node.CanUseNewLayout()) {
- return ComputeInlineSizeForFragment(*space.get(), unpositioned_float->node);
- }
-
- // Here we need to lay out the float. However, it is possible that we are
- // not inside Layout, in which case we may not be able to actually lay out
- // the node. Instead, we have to fallback to legacy sizing.
- if (!unpositioned_float->node.GetLayoutBox()
- ->GetFrameView()
- ->IsInPerformLayout()) {
- LayoutBox* box = unpositioned_float->node.GetLayoutBox();
- LayoutBox::LogicalExtentComputedValues values;
- box->ComputeLogicalWidth(values);
- return values.extent_;
- }
-
- // A float which has a different writing mode can't fragment, and we
- // (probably) need to perform a full layout in order to correctly determine
- // its inline size. We are able to cache this result on the unpositioned_float
- // at this stage. If the writing mode is the same, on the other hand, we
- // cannot keep the result around, since the node may fragment (and we need to
- // find its final block position before we can do so).
- auto result = unpositioned_float->node.Layout(*space);
- if (!is_same_writing_mode) {
- // If we are performing layout on a float to determine its inline size it
- // should never have fragmented.
- DCHECK(!unpositioned_float->token);
- unpositioned_float->layout_result = result;
- }
+ const auto& fragment = unpositioned_float->layout_result->PhysicalFragment();
+ DCHECK(fragment);
+ DCHECK(fragment->BreakToken()->IsFinished());
- DCHECK(result->PhysicalFragment());
- const auto& fragment = *result->PhysicalFragment();
-
- DCHECK(fragment.BreakToken()->IsFinished());
-
- return NGFragment(parent_space.GetWritingMode(), fragment).InlineSize();
+ return (NGFragment(parent_space.GetWritingMode(), *fragment).InlineSize() +
+ unpositioned_float->margins.InlineSum())
+ .ClampNegativeToZero();
}
-NGPositionedFloat PositionFloat(LayoutUnit origin_block_offset,
+NGPositionedFloat PositionFloat(const NGLogicalSize& float_available_size,
+ const NGLogicalSize& float_percentage_size,
+ const NGBfcOffset& origin_bfc_offset,
LayoutUnit parent_bfc_block_offset,
NGUnpositionedFloat* unpositioned_float,
const NGConstraintSpace& parent_space,
NGExclusionSpace* exclusion_space) {
DCHECK(unpositioned_float);
- LayoutUnit inline_size =
- ComputeInlineSizeForUnpositionedFloat(parent_space, unpositioned_float);
-
- NGBfcOffset origin_offset = {unpositioned_float->origin_bfc_line_offset,
- origin_block_offset};
-
- // Find a layout opportunity that will fit our float.
- NGLayoutOpportunity opportunity = FindLayoutOpportunityForFloat(
- origin_offset, *exclusion_space, *unpositioned_float, inline_size);
-#if DCHECK_IS_ON()
bool is_same_writing_mode =
unpositioned_float->node.Style().GetWritingMode() ==
parent_space.GetWritingMode();
-#endif
+
+ bool is_fragmentable =
+ is_same_writing_mode && parent_space.HasBlockFragmentation();
scoped_refptr<NGLayoutResult> layout_result;
- // We should only have a fragment if its writing mode is different, i.e. it
- // can't fragment.
- if (unpositioned_float->layout_result) {
-#if DCHECK_IS_ON()
- DCHECK(!is_same_writing_mode);
-#endif
+ NGBoxStrut fragment_margins;
+
+ // We may be able to re-use the fragment from when we calculated the
+ // inline-size, if there is no block fragmentation.
+ if (!is_fragmentable) {
+ LayoutFloatWithoutFragmentation(float_available_size, float_percentage_size,
+ parent_space, unpositioned_float);
layout_result = unpositioned_float->layout_result;
+ fragment_margins = unpositioned_float->margins;
} else {
-#if DCHECK_IS_ON()
- DCHECK(is_same_writing_mode);
-#endif
scoped_refptr<NGConstraintSpace> space = CreateConstraintSpaceForFloat(
- *unpositioned_float, parent_space, origin_block_offset);
+ float_available_size, float_percentage_size, *unpositioned_float,
+ parent_space, origin_bfc_offset.block_offset);
layout_result = unpositioned_float->node.Layout(
*space, unpositioned_float->token.get());
+ fragment_margins = ComputeMarginsFor(
+ *space, unpositioned_float->node.Style(), parent_space);
+
+ // Make the margins fragmentation aware.
+ if (ShouldIgnoreBlockStartMargin(parent_space, unpositioned_float->node,
+ unpositioned_float->token.get()))
+ fragment_margins.block_start = LayoutUnit();
+ if (!layout_result->PhysicalFragment()->BreakToken()->IsFinished())
+ fragment_margins.block_end = LayoutUnit();
}
DCHECK(layout_result->PhysicalFragment());
NGFragment float_fragment(parent_space.GetWritingMode(),
*layout_result->PhysicalFragment());
- LayoutUnit float_margin_box_inline_size =
- float_fragment.InlineSize() + unpositioned_float->margins.InlineSum();
+ // Find a layout opportunity that will fit our float.
+ NGLayoutOpportunity opportunity = FindLayoutOpportunityForFloat(
+ float_available_size, origin_bfc_offset, *exclusion_space,
+ *unpositioned_float, fragment_margins, float_fragment.InlineSize());
// Calculate the float's margin box BFC offset.
NGBfcOffset float_margin_bfc_offset = opportunity.rect.start_offset;
if (unpositioned_float->IsRight()) {
+ LayoutUnit float_margin_box_inline_size =
+ float_fragment.InlineSize() + fragment_margins.InlineSum();
float_margin_bfc_offset.line_offset +=
(opportunity.rect.InlineSize() - float_margin_box_inline_size);
}
// Add the float as an exclusion.
scoped_refptr<NGExclusion> exclusion = CreateExclusion(
- float_fragment, float_margin_bfc_offset, unpositioned_float->margins,
+ float_available_size, float_percentage_size, float_fragment,
+ float_margin_bfc_offset, fragment_margins,
unpositioned_float->node.GetLayoutBox(), *unpositioned_float,
parent_space, parent_space.Direction(),
unpositioned_float->IsRight() ? EFloat::kRight : EFloat::kLeft);
@@ -317,52 +288,50 @@ NGPositionedFloat PositionFloat(LayoutUnit origin_block_offset,
// Adjust the float's bfc_offset to its border-box (instead of margin-box).
NGBfcOffset float_bfc_offset(
float_margin_bfc_offset.line_offset +
- unpositioned_float->margins.LineLeft(parent_space.Direction()),
- float_margin_bfc_offset.block_offset +
- unpositioned_float->margins.block_start);
+ fragment_margins.LineLeft(parent_space.Direction()),
+ float_margin_bfc_offset.block_offset + fragment_margins.block_start);
return NGPositionedFloat(std::move(layout_result), float_bfc_offset);
}
const Vector<NGPositionedFloat> PositionFloats(
- LayoutUnit origin_block_offset,
+ const NGLogicalSize& float_available_size,
+ const NGLogicalSize& float_percentage_size,
+ const NGBfcOffset& origin_bfc_offset,
LayoutUnit parent_bfc_block_offset,
- const Vector<scoped_refptr<NGUnpositionedFloat>>& unpositioned_floats,
+ NGUnpositionedFloatVector& unpositioned_floats,
const NGConstraintSpace& space,
NGExclusionSpace* exclusion_space) {
Vector<NGPositionedFloat> positioned_floats;
positioned_floats.ReserveCapacity(unpositioned_floats.size());
- for (auto& unpositioned_float : unpositioned_floats) {
- positioned_floats.push_back(
- PositionFloat(origin_block_offset, parent_bfc_block_offset,
- unpositioned_float.get(), space, exclusion_space));
+ for (NGUnpositionedFloat& unpositioned_float : unpositioned_floats) {
+ positioned_floats.push_back(PositionFloat(
+ float_available_size, float_percentage_size, origin_bfc_offset,
+ parent_bfc_block_offset, &unpositioned_float, space, exclusion_space));
}
return positioned_floats;
}
-void AddUnpositionedFloat(
- Vector<scoped_refptr<NGUnpositionedFloat>>* unpositioned_floats,
- NGContainerFragmentBuilder* fragment_builder,
- scoped_refptr<NGUnpositionedFloat> unpositioned_float) {
+void AddUnpositionedFloat(NGUnpositionedFloatVector* unpositioned_floats,
+ NGContainerFragmentBuilder* fragment_builder,
+ NGUnpositionedFloat unpositioned_float) {
// The same float node should not be added more than once.
DCHECK(
- !RemoveUnpositionedFloat(unpositioned_floats, unpositioned_float->node));
+ !RemoveUnpositionedFloat(unpositioned_floats, unpositioned_float.node));
- if (fragment_builder && !fragment_builder->BfcOffset()) {
+ if (fragment_builder && !fragment_builder->BfcBlockOffset()) {
fragment_builder->AddAdjoiningFloatTypes(
- unpositioned_float->IsLeft() ? kFloatTypeLeft : kFloatTypeRight);
+ unpositioned_float.IsLeft() ? kFloatTypeLeft : kFloatTypeRight);
}
unpositioned_floats->push_back(std::move(unpositioned_float));
}
-bool RemoveUnpositionedFloat(
- Vector<scoped_refptr<NGUnpositionedFloat>>* unpositioned_floats,
- NGBlockNode float_node) {
- for (scoped_refptr<NGUnpositionedFloat>& unpositioned_float :
- *unpositioned_floats) {
- if (unpositioned_float->node == float_node) {
+bool RemoveUnpositionedFloat(NGUnpositionedFloatVector* unpositioned_floats,
+ NGBlockNode float_node) {
+ for (NGUnpositionedFloat& unpositioned_float : *unpositioned_floats) {
+ if (unpositioned_float.node == float_node) {
unpositioned_floats->erase(&unpositioned_float);
return true;
}
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_floats_utils.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_floats_utils.h
index ffd1b872d72..bcf60702a33 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_floats_utils.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_floats_utils.h
@@ -7,6 +7,7 @@
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_unpositioned_float_vector.h"
#include "third_party/blink/renderer/core/style/computed_style_constants.h"
#include "third_party/blink/renderer/platform/layout_unit.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -17,6 +18,8 @@ class NGBlockNode;
class NGConstraintSpace;
class NGContainerFragmentBuilder;
class NGExclusionSpace;
+struct NGBfcOffset;
+struct NGLogicalSize;
struct NGPositionedFloat;
struct NGUnpositionedFloat;
@@ -29,16 +32,17 @@ enum NGFloatTypeValue {
typedef int NGFloatTypes;
// Returns the inline size (relative to {@code parent_space}) of the
-// unpositioned float. If the float is in a different writing mode, this will
-// perform a layout.
-CORE_EXPORT LayoutUnit
-ComputeInlineSizeForUnpositionedFloat(const NGConstraintSpace& parent_space,
- NGUnpositionedFloat* unpositioned_float);
+// unpositioned float.
+CORE_EXPORT LayoutUnit ComputeMarginBoxInlineSizeForUnpositionedFloat(
+ const NGConstraintSpace& parent_space,
+ NGUnpositionedFloat* unpositioned_float);
// Positions {@code unpositioned_float} into {@code new_parent_space}.
// @returns A positioned float.
CORE_EXPORT NGPositionedFloat
-PositionFloat(LayoutUnit origin_block_offset,
+PositionFloat(const NGLogicalSize& float_available_size,
+ const NGLogicalSize& float_percentage_size,
+ const NGBfcOffset& origin_bfc_offset,
LayoutUnit parent_bfc_block_offset,
NGUnpositionedFloat*,
const NGConstraintSpace& parent_space,
@@ -47,23 +51,23 @@ PositionFloat(LayoutUnit origin_block_offset,
// Positions the list of {@code unpositioned_floats}. Adds them as exclusions to
// {@code space}.
CORE_EXPORT const Vector<NGPositionedFloat> PositionFloats(
- LayoutUnit origin_block_offset,
+ const NGLogicalSize& float_available_size,
+ const NGLogicalSize& float_percentage_size,
+ const NGBfcOffset& origin_bfc_offset,
LayoutUnit container_block_offset,
- const Vector<scoped_refptr<NGUnpositionedFloat>>& unpositioned_floats,
+ NGUnpositionedFloatVector& unpositioned_floats,
const NGConstraintSpace& space,
NGExclusionSpace* exclusion_space);
// Add a pending float to the list. It will be committed (positioned) once we
-// have resolved the BFC offset.
-void AddUnpositionedFloat(
- Vector<scoped_refptr<NGUnpositionedFloat>>* unpositioned_floats,
- NGContainerFragmentBuilder* fragment_builder,
- scoped_refptr<NGUnpositionedFloat> unpositioned_float);
+// have resolved the BFC block offset.
+void AddUnpositionedFloat(NGUnpositionedFloatVector* unpositioned_floats,
+ NGContainerFragmentBuilder* fragment_builder,
+ NGUnpositionedFloat unpositioned_float);
// Remove a pending float from the list.
-bool RemoveUnpositionedFloat(
- Vector<scoped_refptr<NGUnpositionedFloat>>* unpositioned_floats,
- NGBlockNode float_node);
+bool RemoveUnpositionedFloat(NGUnpositionedFloatVector* unpositioned_floats,
+ NGBlockNode float_node);
NGFloatTypes ToFloatTypes(EClear clear);
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_fragment_builder.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_fragment_builder.cc
index 00f5fbe8cec..4197e06e7cf 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_fragment_builder.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_fragment_builder.cc
@@ -68,6 +68,12 @@ NGFragmentBuilder& NGFragmentBuilder::SetIntrinsicBlockSize(
return *this;
}
+NGFragmentBuilder& NGFragmentBuilder::SetBorders(const NGBoxStrut& border) {
+ DCHECK_NE(BoxType(), NGPhysicalFragment::kInlineBox);
+ borders_ = border;
+ return *this;
+}
+
NGFragmentBuilder& NGFragmentBuilder::SetPadding(const NGBoxStrut& padding) {
DCHECK_NE(BoxType(), NGPhysicalFragment::kInlineBox);
padding_ = padding;
@@ -84,7 +90,7 @@ NGFragmentBuilder& NGFragmentBuilder::SetPadding(
}
NGContainerFragmentBuilder& NGFragmentBuilder::AddChild(
- scoped_refptr<NGPhysicalFragment> child,
+ scoped_refptr<const NGPhysicalFragment> child,
const NGLogicalOffset& child_offset) {
switch (child->Type()) {
case NGPhysicalBoxFragment::kFragmentBox:
@@ -181,7 +187,7 @@ NGFragmentBuilder& NGFragmentBuilder::PropagateBreak(
}
NGFragmentBuilder& NGFragmentBuilder::PropagateBreak(
- scoped_refptr<NGPhysicalFragment> child_fragment) {
+ scoped_refptr<const NGPhysicalFragment> child_fragment) {
if (!did_break_) {
const auto* token = child_fragment->BreakToken();
did_break_ = token && !token->IsFinished();
@@ -228,10 +234,8 @@ void NGFragmentBuilder::AddOutOfFlowLegacyCandidate(
}
NGPhysicalFragment::NGBoxType NGFragmentBuilder::BoxType() const {
- if (box_type_ != NGPhysicalFragment::NGBoxType::kNormalBox) {
- DCHECK_EQ(box_type_, BoxTypeFromLayoutObject(layout_object_));
+ if (box_type_ != NGPhysicalFragment::NGBoxType::kNormalBox)
return box_type_;
- }
// When implicit, compute from LayoutObject.
return BoxTypeFromLayoutObject(layout_object_);
@@ -281,11 +285,12 @@ scoped_refptr<NGLayoutResult> NGFragmentBuilder::ToBoxFragment(
NGPhysicalSize physical_size = Size().ConvertToPhysical(GetWritingMode());
NGPhysicalOffsetRect contents_ink_overflow({}, physical_size);
- for (size_t i = 0; i < children_.size(); ++i) {
- NGPhysicalFragment* child = children_[i].get();
- child->SetOffset(offsets_[i].ConvertToPhysical(
- block_or_line_writing_mode, Direction(), physical_size, child->Size()));
- child->PropagateContentsInkOverflow(&contents_ink_overflow);
+ DCHECK_EQ(children_.size(), offsets_.size());
+ for (size_t i = 0; i < children_.size(); i++) {
+ auto& child = children_[i];
+ child.offset_ = offsets_[i].ConvertToPhysical(
+ block_or_line_writing_mode, Direction(), physical_size, child->Size());
+ child->PropagateContentsInkOverflow(&contents_ink_overflow, child.Offset());
}
scoped_refptr<NGBreakToken> break_token;
@@ -305,11 +310,11 @@ scoped_refptr<NGLayoutResult> NGFragmentBuilder::ToBoxFragment(
}
}
- scoped_refptr<NGPhysicalBoxFragment> fragment =
+ scoped_refptr<const NGPhysicalBoxFragment> fragment =
base::AdoptRef(new NGPhysicalBoxFragment(
layout_object_, Style(), style_variant_, physical_size, children_,
- padding_.ConvertToPhysical(GetWritingMode(), Direction())
- .SnapToDevicePixels(),
+ borders_.ConvertToPhysical(GetWritingMode(), Direction()),
+ padding_.ConvertToPhysical(GetWritingMode(), Direction()),
contents_ink_overflow, baselines_, BoxType(), is_old_layout_root_,
border_edges_.ToPhysical(GetWritingMode()), std::move(break_token)));
@@ -317,10 +322,11 @@ scoped_refptr<NGLayoutResult> NGFragmentBuilder::ToBoxFragment(
return base::AdoptRef(new NGLayoutResult(
std::move(fragment), oof_positioned_descendants_, positioned_floats,
- unpositioned_list_marker_, std::move(exclusion_space_), bfc_offset_,
- end_margin_strut_, intrinsic_block_size_, minimal_space_shortage_,
- initial_break_before_, previous_break_after_, has_forced_break_,
- is_pushed_by_floats_, adjoining_floats_, NGLayoutResult::kSuccess));
+ unpositioned_list_marker_, std::move(exclusion_space_), bfc_line_offset_,
+ bfc_block_offset_, end_margin_strut_, intrinsic_block_size_,
+ minimal_space_shortage_, initial_break_before_, previous_break_after_,
+ has_forced_break_, is_pushed_by_floats_, adjoining_floats_,
+ NGLayoutResult::kSuccess));
}
scoped_refptr<NGLayoutResult> NGFragmentBuilder::Abort(
@@ -329,9 +335,9 @@ scoped_refptr<NGLayoutResult> NGFragmentBuilder::Abort(
Vector<NGPositionedFloat> positioned_floats;
return base::AdoptRef(new NGLayoutResult(
nullptr, oof_positioned_descendants, positioned_floats,
- NGUnpositionedListMarker(), nullptr, bfc_offset_, end_margin_strut_,
- LayoutUnit(), LayoutUnit(), EBreakBetween::kAuto, EBreakBetween::kAuto,
- false, false, kFloatTypeNone, status));
+ NGUnpositionedListMarker(), nullptr, bfc_line_offset_, bfc_block_offset_,
+ end_margin_strut_, LayoutUnit(), LayoutUnit(), EBreakBetween::kAuto,
+ EBreakBetween::kAuto, false, false, kFloatTypeNone, status));
}
// Finds FragmentPairs that define inline containing blocks.
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 c1512e5c609..3d454ff3c82 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
@@ -40,13 +40,14 @@ class CORE_EXPORT NGFragmentBuilder final : public NGContainerFragmentBuilder {
~NGFragmentBuilder() override;
NGFragmentBuilder& SetIntrinsicBlockSize(LayoutUnit);
+ NGFragmentBuilder& SetBorders(const NGBoxStrut&);
NGFragmentBuilder& SetPadding(const NGBoxStrut&);
NGFragmentBuilder& SetPadding(const NGLineBoxStrut&);
using NGContainerFragmentBuilder::AddChild;
// Our version of AddChild captures any child NGBreakTokens.
- NGContainerFragmentBuilder& AddChild(scoped_refptr<NGPhysicalFragment>,
+ NGContainerFragmentBuilder& AddChild(scoped_refptr<const NGPhysicalFragment>,
const NGLogicalOffset&) final;
// Remove all children.
@@ -62,7 +63,7 @@ class CORE_EXPORT NGFragmentBuilder final : public NGContainerFragmentBuilder {
// Update if we have fragmented in this flow.
NGFragmentBuilder& PropagateBreak(scoped_refptr<NGLayoutResult>);
- NGFragmentBuilder& PropagateBreak(scoped_refptr<NGPhysicalFragment>);
+ NGFragmentBuilder& PropagateBreak(scoped_refptr<const NGPhysicalFragment>);
void AddOutOfFlowLegacyCandidate(NGBlockNode,
const NGStaticPosition&,
@@ -186,6 +187,7 @@ class CORE_EXPORT NGFragmentBuilder final : public NGContainerFragmentBuilder {
LayoutObject* layout_object_;
LayoutUnit intrinsic_block_size_;
+ NGBoxStrut borders_;
NGBoxStrut padding_;
NGPhysicalFragment::NGBoxType box_type_;
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 9619804199c..f6b09988a80 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
@@ -21,6 +21,7 @@ LayoutUnit PreviouslyUsedBlockSpace(const NGConstraintSpace& constraint_space,
if (!break_token)
return LayoutUnit();
NGBoxFragment logical_fragment(constraint_space.GetWritingMode(),
+ constraint_space.Direction(),
ToNGPhysicalBoxFragment(fragment));
return break_token->UsedBlockSize() - logical_fragment.BlockSize();
}
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 428255389d8..a0bb83d417b 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
@@ -67,8 +67,9 @@ class CORE_EXPORT NGLayoutAlgorithm {
const ComputedStyle& Style() const { return node_.Style(); }
NGBfcOffset ContainerBfcOffset() const {
- DCHECK(container_builder_.BfcOffset().has_value());
- return container_builder_.BfcOffset().value();
+ DCHECK(container_builder_.BfcBlockOffset());
+ return {container_builder_.BfcLineOffset(),
+ container_builder_.BfcBlockOffset().value()};
}
NGInputNodeType Node() const { return node_; }
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 6c457155401..2d72575c6a9 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
@@ -10,6 +10,7 @@
#include "third_party/blink/renderer/core/layout/min_max_size.h"
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_logical_size.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"
@@ -96,6 +97,11 @@ bool NGLayoutInputNode::IsListMarker() const {
return IsBlock() && box_->IsLayoutNGListMarker();
}
+bool NGLayoutInputNode::ListMarkerOccupiesWholeLine() const {
+ DCHECK(IsListMarker());
+ return ToLayoutNGListMarker(box_)->NeedsOccupyWholeLine();
+}
+
bool NGLayoutInputNode::IsAnonymousBlock() const {
return box_->IsAnonymousBlock();
}
@@ -136,9 +142,9 @@ MinMaxSize NGLayoutInputNode::ComputeMinMaxSize(
WritingMode writing_mode,
const MinMaxSizeInput& input,
const NGConstraintSpace* space) {
- return IsInline() ? ToNGInlineNode(*this).ComputeMinMaxSize(input)
- : ToNGBlockNode(*this).ComputeMinMaxSize(writing_mode,
- input, space);
+ if (IsInline())
+ return ToNGInlineNode(*this).ComputeMinMaxSize(writing_mode, input, space);
+ return ToNGBlockNode(*this).ComputeMinMaxSize(writing_mode, input, space);
}
void NGLayoutInputNode::IntrinsicSize(
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 c19c680d819..f50388fe19a 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
@@ -7,6 +7,7 @@
#include "base/optional.h"
#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/layout/ng/geometry/ng_logical_size.h"
#include "third_party/blink/renderer/platform/layout_unit.h"
#include "third_party/blink/renderer/platform/text/writing_mode.h"
@@ -23,12 +24,21 @@ struct MinMaxSize;
struct NGLogicalSize;
struct NGPhysicalSize;
+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.
+// them. Additionally, orthogonal writing mode roots will need the extrinsic
+// block-size of the container.
struct MinMaxSizeInput {
LayoutUnit float_left_inline_size;
LayoutUnit float_right_inline_size;
+
+ // Extrinsic block-size of the containing block.
+ LayoutUnit extrinsic_block_size = NGSizeIndefinite;
+
+ // 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
@@ -60,6 +70,7 @@ class CORE_EXPORT NGLayoutInputNode {
bool ShouldBeConsideredAsReplaced() const;
bool IsListItem() const;
bool IsListMarker() const;
+ bool ListMarkerOccupiesWholeLine() const;
bool IsAnonymousBlock() const;
// If the node is a quirky container for margin collapsing, see:
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 5982eb02b4c..2d4e50fb626 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
@@ -13,12 +13,13 @@
namespace blink {
NGLayoutResult::NGLayoutResult(
- scoped_refptr<NGPhysicalFragment> physical_fragment,
+ scoped_refptr<const NGPhysicalFragment> physical_fragment,
Vector<NGOutOfFlowPositionedDescendant>& oof_positioned_descendants,
Vector<NGPositionedFloat>& positioned_floats,
const NGUnpositionedListMarker& unpositioned_list_marker,
std::unique_ptr<const NGExclusionSpace> exclusion_space,
- const base::Optional<NGBfcOffset> bfc_offset,
+ LayoutUnit bfc_line_offset,
+ const base::Optional<LayoutUnit> bfc_block_offset,
const NGMarginStrut end_margin_strut,
const LayoutUnit intrinsic_block_size,
LayoutUnit minimal_space_shortage,
@@ -28,10 +29,10 @@ NGLayoutResult::NGLayoutResult(
bool is_pushed_by_floats,
NGFloatTypes adjoining_floats,
NGLayoutResultStatus status)
- : physical_fragment_(std::move(physical_fragment)),
- unpositioned_list_marker_(unpositioned_list_marker),
+ : unpositioned_list_marker_(unpositioned_list_marker),
exclusion_space_(std::move(exclusion_space)),
- bfc_offset_(bfc_offset),
+ bfc_line_offset_(bfc_line_offset),
+ bfc_block_offset_(bfc_block_offset),
end_margin_strut_(end_margin_strut),
intrinsic_block_size_(intrinsic_block_size),
minimal_space_shortage_(minimal_space_shortage),
@@ -41,6 +42,7 @@ NGLayoutResult::NGLayoutResult(
is_pushed_by_floats_(is_pushed_by_floats),
adjoining_floats_(adjoining_floats),
status_(status) {
+ root_fragment_.fragment_ = std::move(physical_fragment);
oof_positioned_descendants_.swap(oof_positioned_descendants);
positioned_floats_.swap(positioned_floats);
}
@@ -60,9 +62,9 @@ scoped_refptr<NGLayoutResult> NGLayoutResult::CloneWithoutOffset() const {
exclusion_space = std::make_unique<NGExclusionSpace>(*exclusion_space_);
}
return base::AdoptRef(new NGLayoutResult(
- physical_fragment_->CloneWithoutOffset(), oof_positioned_descendants,
- positioned_floats, unpositioned_list_marker_, std::move(exclusion_space),
- bfc_offset_, end_margin_strut_, intrinsic_block_size_,
+ PhysicalFragment(), oof_positioned_descendants, positioned_floats,
+ unpositioned_list_marker_, std::move(exclusion_space), bfc_line_offset_,
+ bfc_block_offset_, end_margin_strut_, intrinsic_block_size_,
minimal_space_shortage_, initial_break_before_, final_break_after_,
has_forced_break_, is_pushed_by_floats_, adjoining_floats_, Status()));
}
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 89aa6cce96a..84e32ed66ac 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
@@ -11,6 +11,7 @@
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_margin_strut.h"
#include "third_party/blink/renderer/core/layout/ng/list/ng_unpositioned_list_marker.h"
#include "third_party/blink/renderer/core/layout/ng/ng_floats_utils.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_link.h"
#include "third_party/blink/renderer/core/layout/ng/ng_out_of_flow_positioned_descendant.h"
#include "third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h"
#include "third_party/blink/renderer/core/style/computed_style_constants.h"
@@ -31,20 +32,18 @@ class CORE_EXPORT NGLayoutResult : public RefCounted<NGLayoutResult> {
public:
enum NGLayoutResultStatus {
kSuccess = 0,
- kBfcOffsetResolved = 1,
+ kBfcBlockOffsetResolved = 1,
// When adding new values, make sure the bit size of |status_| is large
// enough to store.
};
~NGLayoutResult();
- scoped_refptr<NGPhysicalFragment> PhysicalFragment() const {
- return physical_fragment_;
- }
-
- scoped_refptr<NGPhysicalFragment>& MutablePhysicalFragment() {
- return physical_fragment_;
+ scoped_refptr<const NGPhysicalFragment> PhysicalFragment() const {
+ return root_fragment_.get();
}
+ NGPhysicalOffset Offset() const { return root_fragment_.Offset(); }
+ void SetOffset(NGPhysicalOffset offset) { root_fragment_.offset_ = offset; }
const Vector<NGOutOfFlowPositionedDescendant>&
OutOfFlowPositionedDescendants() const {
@@ -55,7 +54,7 @@ class CORE_EXPORT NGLayoutResult : public RefCounted<NGLayoutResult> {
// the line-box's parent fragment (as floats which occur within a line-box do
// not appear a children).
const Vector<NGPositionedFloat>& PositionedFloats() const {
- DCHECK(physical_fragment_->Type() == NGPhysicalFragment::kFragmentLineBox);
+ DCHECK(root_fragment_->Type() == NGPhysicalFragment::kFragmentLineBox);
return positioned_floats_;
}
@@ -71,12 +70,15 @@ class CORE_EXPORT NGLayoutResult : public RefCounted<NGLayoutResult> {
return static_cast<NGLayoutResultStatus>(status_);
}
- const base::Optional<NGBfcOffset>& BfcOffset() const { return bfc_offset_; }
+ LayoutUnit BfcLineOffset() const { return bfc_line_offset_; }
+ const base::Optional<LayoutUnit>& BfcBlockOffset() const {
+ return bfc_block_offset_;
+ }
const NGMarginStrut EndMarginStrut() const { return end_margin_strut_; }
const LayoutUnit IntrinsicBlockSize() const {
- DCHECK(physical_fragment_->Type() == NGPhysicalFragment::kFragmentBox);
+ DCHECK(root_fragment_->Type() == NGPhysicalFragment::kFragmentBox);
return intrinsic_block_size_;
}
@@ -98,8 +100,8 @@ class CORE_EXPORT NGLayoutResult : public RefCounted<NGLayoutResult> {
bool IsPushedByFloats() const { return is_pushed_by_floats_; }
// Return the types (none, left, right, both) of preceding adjoining
- // floats. These are floats that are added while the in-flow BFC offset is
- // still unknown. The floats may or may not be unpositioned (pending). That
+ // floats. These are floats that are added while the in-flow BFC block offset
+ // is still unknown. The floats may or may not be unpositioned (pending). That
// depends on which layout pass we're in. Adjoining floats should be treated
// differently when calculating clearance on a block with adjoining
// block-start margin (in such cases we will know up front that the block will
@@ -113,13 +115,14 @@ class CORE_EXPORT NGLayoutResult : public RefCounted<NGLayoutResult> {
friend class NGFragmentBuilder;
friend class NGLineBoxFragmentBuilder;
- NGLayoutResult(scoped_refptr<NGPhysicalFragment> physical_fragment,
+ NGLayoutResult(scoped_refptr<const NGPhysicalFragment> physical_fragment,
Vector<NGOutOfFlowPositionedDescendant>&
out_of_flow_positioned_descendants,
Vector<NGPositionedFloat>& positioned_floats,
const NGUnpositionedListMarker& unpositioned_list_marker,
std::unique_ptr<const NGExclusionSpace> exclusion_space,
- const base::Optional<NGBfcOffset> bfc_offset,
+ LayoutUnit bfc_line_offset,
+ const base::Optional<LayoutUnit> bfc_block_offset,
const NGMarginStrut end_margin_strut,
const LayoutUnit intrinsic_block_size,
LayoutUnit minimal_space_shortage,
@@ -130,7 +133,7 @@ class CORE_EXPORT NGLayoutResult : public RefCounted<NGLayoutResult> {
NGFloatTypes adjoining_floats,
NGLayoutResultStatus status);
- scoped_refptr<NGPhysicalFragment> physical_fragment_;
+ NGLink root_fragment_;
Vector<NGOutOfFlowPositionedDescendant> oof_positioned_descendants_;
Vector<NGPositionedFloat> positioned_floats_;
@@ -138,7 +141,8 @@ class CORE_EXPORT NGLayoutResult : public RefCounted<NGLayoutResult> {
NGUnpositionedListMarker unpositioned_list_marker_;
const std::unique_ptr<const NGExclusionSpace> exclusion_space_;
- const base::Optional<NGBfcOffset> bfc_offset_;
+ const LayoutUnit bfc_line_offset_;
+ const base::Optional<LayoutUnit> bfc_block_offset_;
const NGMarginStrut end_margin_strut_;
const LayoutUnit intrinsic_block_size_;
const LayoutUnit minimal_space_shortage_;
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 029a7e4bcef..34d0d0b6458 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
@@ -16,8 +16,8 @@ bool IsBlockLayoutComplete(const NGConstraintSpace& space,
if (space.IsIntermediateLayout())
return false;
// Check that we're done positioning pending floats.
- return !result.AdjoiningFloatTypes() || result.BfcOffset() ||
- space.FloatsBfcOffset();
+ return !result.AdjoiningFloatTypes() || result.BfcBlockOffset() ||
+ space.FloatsBfcBlockOffset();
}
} // namespace blink
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 9a32ed00bee..8c37899f121 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
@@ -49,12 +49,14 @@ bool NeedMinMaxSizeForContentContribution(WritingMode mode,
style.MaxHeight().IsIntrinsic();
}
-LayoutUnit ResolveInlineLength(const NGConstraintSpace& constraint_space,
- const ComputedStyle& style,
- const base::Optional<MinMaxSize>& min_and_max,
- const Length& length,
- LengthResolveType type,
- LengthResolvePhase phase) {
+LayoutUnit ResolveInlineLength(
+ const NGConstraintSpace& constraint_space,
+ const ComputedStyle& style,
+ const base::Optional<MinMaxSize>& min_and_max,
+ const Length& length,
+ LengthResolveType type,
+ LengthResolvePhase phase,
+ const base::Optional<NGBoxStrut>& opt_border_padding) {
DCHECK_GE(constraint_space.AvailableSize().inline_size, LayoutUnit());
DCHECK_GE(constraint_space.PercentageResolutionSize().inline_size,
LayoutUnit());
@@ -68,8 +70,10 @@ LayoutUnit ResolveInlineLength(const NGConstraintSpace& constraint_space,
return LayoutUnit::Max();
}
- NGBoxStrut border_and_padding = ComputeBorders(constraint_space, style) +
- ComputePadding(constraint_space, style);
+ NGBoxStrut border_and_padding =
+ opt_border_padding ? *opt_border_padding
+ : ComputeBorders(constraint_space, style) +
+ ComputePadding(constraint_space, style);
if (type == LengthResolveType::kMinSize && length.IsAuto())
return border_and_padding.InlineSum();
@@ -139,12 +143,14 @@ LayoutUnit ResolveInlineLength(const NGConstraintSpace& constraint_space,
}
}
-LayoutUnit ResolveBlockLength(const NGConstraintSpace& constraint_space,
- const ComputedStyle& style,
- const Length& length,
- LayoutUnit content_size,
- LengthResolveType type,
- LengthResolvePhase phase) {
+LayoutUnit ResolveBlockLength(
+ const NGConstraintSpace& constraint_space,
+ const ComputedStyle& style,
+ const Length& length,
+ LayoutUnit content_size,
+ LengthResolveType type,
+ LengthResolvePhase phase,
+ const base::Optional<NGBoxStrut>& opt_border_padding) {
DCHECK_EQ(constraint_space.GetWritingMode(), style.GetWritingMode());
if (constraint_space.IsAnonymous())
@@ -155,8 +161,10 @@ LayoutUnit ResolveBlockLength(const NGConstraintSpace& constraint_space,
return LayoutUnit::Max();
}
- NGBoxStrut border_and_padding = ComputeBorders(constraint_space, style) +
- ComputePadding(constraint_space, style);
+ NGBoxStrut border_and_padding =
+ opt_border_padding ? *opt_border_padding
+ : ComputeBorders(constraint_space, style) +
+ ComputePadding(constraint_space, style);
if (type == LengthResolveType::kMinSize && length.IsAuto())
return border_and_padding.BlockSum();
@@ -340,6 +348,16 @@ MinMaxSize ComputeMinAndMaxContentContribution(
const MinMaxSizeInput& input,
const NGConstraintSpace* constraint_space) {
LayoutBox* box = node.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(writing_mode, node.Style().GetWritingMode())) {
if (!box->PreferredLogicalWidthsDirty()) {
return {box->MinPreferredLogicalWidth(), box->MaxPreferredLogicalWidth()};
@@ -359,14 +377,14 @@ MinMaxSize ComputeMinAndMaxContentContribution(
if (constraint_space) {
// TODO(layout-ng): Check if our constraint space produces spec-compliant
// outputs.
- // It is important to set a floats bfc offset so that we don't get a
+ // It is important to set a floats bfc block offset so that we don't get a
// partial layout. It is also important that we shrink to fit, by
// definition.
NGConstraintSpaceBuilder builder(*constraint_space);
builder.SetAvailableSize(constraint_space->AvailableSize())
.SetPercentageResolutionSize(
constraint_space->PercentageResolutionSize())
- .SetFloatsBfcOffset(NGBfcOffset())
+ .SetFloatsBfcBlockOffset(LayoutUnit())
.SetIsNewFormattingContext(node.CreatesNewFormattingContext())
.SetIsShrinkToFit(true);
adjusted_constraint_space =
@@ -383,9 +401,11 @@ MinMaxSize ComputeMinAndMaxContentContribution(
return sizes;
}
-LayoutUnit ComputeInlineSizeForFragment(const NGConstraintSpace& space,
- NGLayoutInputNode node,
- const MinMaxSize* override_minmax) {
+LayoutUnit ComputeInlineSizeForFragment(
+ const NGConstraintSpace& space,
+ NGLayoutInputNode node,
+ const base::Optional<NGBoxStrut>& border_padding,
+ const MinMaxSize* override_minmax) {
if (space.IsFixedSizeInline())
return space.AvailableSize().inline_size;
@@ -420,26 +440,31 @@ LayoutUnit ComputeInlineSizeForFragment(const NGConstraintSpace& space,
} else {
min_and_max = node.ComputeMinMaxSize(space.GetWritingMode(),
MinMaxSizeInput(), &space);
+ // Cache these computed values
+ MinMaxSize contribution = ComputeMinAndMaxContentContribution(
+ style.GetWritingMode(), style, min_and_max);
+ box->SetPreferredLogicalWidthsFromNG(contribution);
}
}
LayoutUnit extent = ResolveInlineLength(
space, style, min_and_max, logical_width, LengthResolveType::kContentSize,
- LengthResolvePhase::kLayout);
+ LengthResolvePhase::kLayout, border_padding);
LayoutUnit max = ResolveInlineLength(
space, style, min_and_max, style.LogicalMaxWidth(),
- LengthResolveType::kMaxSize, LengthResolvePhase::kLayout);
+ LengthResolveType::kMaxSize, LengthResolvePhase::kLayout, border_padding);
LayoutUnit min = ResolveInlineLength(
space, style, min_and_max, style.LogicalMinWidth(),
- LengthResolveType::kMinSize, LengthResolvePhase::kLayout);
+ LengthResolveType::kMinSize, LengthResolvePhase::kLayout, border_padding);
return ConstrainByMinMax(extent, min, max);
}
LayoutUnit ComputeBlockSizeForFragment(
const NGConstraintSpace& constraint_space,
const ComputedStyle& style,
- LayoutUnit content_size) {
+ LayoutUnit content_size,
+ const base::Optional<NGBoxStrut>& border_padding) {
if (constraint_space.IsFixedSizeBlock())
return constraint_space.AvailableSize().block_size;
@@ -447,9 +472,11 @@ LayoutUnit ComputeBlockSizeForFragment(
// All handled by the table layout code or not applicable.
return content_size;
}
- LayoutUnit extent = ResolveBlockLength(
- constraint_space, style, style.LogicalHeight(), content_size,
- LengthResolveType::kContentSize, LengthResolvePhase::kLayout);
+
+ LayoutUnit extent =
+ ResolveBlockLength(constraint_space, style, style.LogicalHeight(),
+ content_size, LengthResolveType::kContentSize,
+ LengthResolvePhase::kLayout, border_padding);
if (extent == NGSizeIndefinite) {
DCHECK_EQ(content_size, NGSizeIndefinite);
return extent;
@@ -457,10 +484,10 @@ LayoutUnit ComputeBlockSizeForFragment(
LayoutUnit max = ResolveBlockLength(
constraint_space, style, style.LogicalMaxHeight(), content_size,
- LengthResolveType::kMaxSize, LengthResolvePhase::kLayout);
+ LengthResolveType::kMaxSize, LengthResolvePhase::kLayout, border_padding);
LayoutUnit min = ResolveBlockLength(
constraint_space, style, style.LogicalMinHeight(), content_size,
- LengthResolveType::kMinSize, LengthResolvePhase::kLayout);
+ LengthResolveType::kMinSize, LengthResolvePhase::kLayout, border_padding);
return ConstrainByMinMax(extent, min, max);
}
@@ -603,8 +630,14 @@ LayoutUnit ResolveUsedColumnGap(LayoutUnit available_size,
NGPhysicalBoxStrut ComputePhysicalMargins(
const NGConstraintSpace& constraint_space,
const ComputedStyle& style) {
+ if (style.MarginLeft().IsZero() && style.MarginRight().IsZero() &&
+ style.MarginTop().IsZero() && style.MarginBottom().IsZero()) {
+ return NGPhysicalBoxStrut();
+ }
+
if (constraint_space.IsAnonymous())
return NGPhysicalBoxStrut();
+
NGPhysicalBoxStrut physical_dim;
physical_dim.left =
ResolveMarginPaddingLength(constraint_space, style.MarginLeft());
@@ -624,18 +657,12 @@ NGBoxStrut ComputeMarginsFor(const NGConstraintSpace& constraint_space,
.ConvertToLogical(compute_for.GetWritingMode(), compute_for.Direction());
}
-NGBoxStrut ComputeMarginsForContainer(const NGConstraintSpace& constraint_space,
- const ComputedStyle& style) {
- return ComputePhysicalMargins(constraint_space, style)
- .ConvertToLogical(constraint_space.GetWritingMode(),
- constraint_space.Direction());
-}
-
-NGBoxStrut ComputeMarginsForVisualContainer(
+NGLineBoxStrut ComputeLineMarginsForVisualContainer(
const NGConstraintSpace& constraint_space,
const ComputedStyle& style) {
return ComputePhysicalMargins(constraint_space, style)
- .ConvertToLogical(constraint_space.GetWritingMode(), TextDirection::kLtr);
+ .ConvertToLineLogical(constraint_space.GetWritingMode(),
+ TextDirection::kLtr);
}
NGBoxStrut ComputeMarginsForSelf(const NGConstraintSpace& constraint_space,
@@ -644,6 +671,13 @@ NGBoxStrut ComputeMarginsForSelf(const NGConstraintSpace& constraint_space,
.ConvertToLogical(style.GetWritingMode(), style.Direction());
}
+NGLineBoxStrut ComputeLineMarginsForSelf(
+ const NGConstraintSpace& constraint_space,
+ const ComputedStyle& style) {
+ return ComputePhysicalMargins(constraint_space, style)
+ .ConvertToLineLogical(style.GetWritingMode(), style.Direction());
+}
+
NGBoxStrut ComputeMinMaxMargins(const ComputedStyle& parent_style,
NGLayoutInputNode child) {
// An inline child just produces line-boxes which don't have any margins.
@@ -681,6 +715,28 @@ NGBoxStrut ComputeBorders(const NGConstraintSpace& constraint_space,
return borders;
}
+NGBoxStrut ComputeBorders(const NGConstraintSpace& constraint_space,
+ const NGLayoutInputNode node) {
+ // 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.
+ if (constraint_space.IsAnonymous())
+ return NGBoxStrut();
+
+ if (node.GetLayoutBox()->IsTableCell()) {
+ LayoutBox* box = node.GetLayoutBox();
+ return NGBoxStrut(box->BorderStart(), box->BorderEnd(), box->BorderBefore(),
+ box->BorderAfter());
+ }
+ return ComputeBorders(constraint_space, node.Style());
+}
+
+NGLineBoxStrut ComputeLineBorders(const NGConstraintSpace& constraint_space,
+ const ComputedStyle& style) {
+ return NGLineBoxStrut(ComputeBorders(constraint_space, style),
+ style.IsFlippedLinesWritingMode());
+}
+
NGBoxStrut ComputePadding(const NGConstraintSpace& constraint_space,
const ComputedStyle& style) {
// If we are producing an anonymous fragment (e.g. a column) we shouldn't
@@ -700,6 +756,33 @@ NGBoxStrut ComputePadding(const NGConstraintSpace& constraint_space,
return padding;
}
+NGBoxStrut ComputePadding(const NGConstraintSpace& constraint_space,
+ const NGLayoutInputNode node) {
+ // 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.
+ if (constraint_space.IsAnonymous())
+ return NGBoxStrut();
+
+ NGBoxStrut padding = ComputePadding(constraint_space, node.Style());
+ if (node.GetLayoutBox()->IsTableCell()) {
+ // Use values calculated by the table layout code
+ const LayoutTableCell* cell = ToLayoutTableCell(node.GetLayoutBox());
+ // TODO(karlo): intrinsic padding can sometimes be negative; that
+ // seems insane, but works in the old code; in NG it trips
+ // DCHECKs.
+ padding.block_start += LayoutUnit(cell->IntrinsicPaddingBefore());
+ padding.block_end += LayoutUnit(cell->IntrinsicPaddingAfter());
+ }
+ return padding;
+}
+
+NGLineBoxStrut ComputeLinePadding(const NGConstraintSpace& constraint_space,
+ const ComputedStyle& style) {
+ return NGLineBoxStrut(ComputePadding(constraint_space, style),
+ style.IsFlippedLinesWritingMode());
+}
+
void ResolveInlineMargins(const ComputedStyle& style,
const ComputedStyle& containing_block_style,
LayoutUnit available_inline_size,
@@ -810,37 +893,37 @@ LayoutUnit ConstrainByMinMax(LayoutUnit length,
NGBoxStrut CalculateBorderScrollbarPadding(
const NGConstraintSpace& constraint_space,
const NGBlockNode node) {
- const ComputedStyle& style = node.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.
if (constraint_space.IsAnonymous())
return NGBoxStrut();
- NGBoxStrut border_intrinsic_padding;
- if (node.GetLayoutBox()->IsTableCell()) {
- // Use values calculated by the table layout code
- const LayoutTableCell* cell = ToLayoutTableCell(node.GetLayoutBox());
- // TODO(karlo): intrinsic padding can sometimes be negative; that
- // seems insane, but works in the old code; in NG it trips
- // DCHECKs.
- border_intrinsic_padding = NGBoxStrut(
- cell->BorderStart(), cell->BorderEnd(),
- cell->BorderBefore() + LayoutUnit(cell->IntrinsicPaddingBefore()),
- cell->BorderAfter() + LayoutUnit(cell->IntrinsicPaddingAfter()));
- } else {
- border_intrinsic_padding = ComputeBorders(constraint_space, style);
- }
- return border_intrinsic_padding + ComputePadding(constraint_space, style) +
- node.GetScrollbarSizes();
+ return ComputeBorders(constraint_space, node) +
+ ComputePadding(constraint_space, node) + node.GetScrollbarSizes();
}
-NGLogicalSize CalculateBorderBoxSize(const NGConstraintSpace& constraint_space,
- const NGBlockNode& node,
- LayoutUnit block_content_size) {
- return NGLogicalSize(ComputeInlineSizeForFragment(constraint_space, node),
- ComputeBlockSizeForFragment(
- constraint_space, node.Style(), block_content_size));
+NGLogicalSize CalculateBorderBoxSize(
+ const NGConstraintSpace& constraint_space,
+ const NGBlockNode& node,
+ LayoutUnit block_content_size,
+ const base::Optional<NGBoxStrut>& border_padding) {
+ // If we have a percentage size, we need to set the
+ // HasPercentHeightDescendants flag correctly so that flexboz knows it may
+ // need to redo layout and can also do some performance optimizations.
+ if (node.Style().LogicalHeight().IsPercentOrCalc() ||
+ node.Style().LogicalMinHeight().IsPercentOrCalc() ||
+ node.Style().LogicalMaxHeight().IsPercentOrCalc() ||
+ (node.GetLayoutBox()->IsFlexItem() &&
+ node.Style().FlexBasis().IsPercentOrCalc())) {
+ // This call has the side-effect of setting HasPercentHeightDescendants
+ // correctly.
+ node.GetLayoutBox()->ComputePercentageLogicalHeight(Length(0, kPercent));
+ }
+
+ return NGLogicalSize(
+ ComputeInlineSizeForFragment(constraint_space, node, border_padding),
+ ComputeBlockSizeForFragment(constraint_space, node.Style(),
+ block_content_size, border_padding));
}
NGLogicalSize CalculateContentBoxSize(
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 bfabf58d634..08d23e67d79 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
@@ -54,21 +54,28 @@ CORE_EXPORT bool NeedMinMaxSizeForContentContribution(WritingMode mode,
// (represented by ConstraintSpace) as necessary for things like percents.
//
// MinMaxSize is used only when the length is intrinsic (fit-content, etc)
-CORE_EXPORT LayoutUnit ResolveInlineLength(const NGConstraintSpace&,
- const ComputedStyle&,
- const base::Optional<MinMaxSize>&,
- const Length&,
- LengthResolveType,
- LengthResolvePhase);
+//
+// border_padding can be passed in as an optimization; otherwise this function
+// will compute it itself.
+CORE_EXPORT LayoutUnit ResolveInlineLength(
+ const NGConstraintSpace&,
+ const ComputedStyle&,
+ const base::Optional<MinMaxSize>&,
+ const Length&,
+ LengthResolveType,
+ LengthResolvePhase,
+ const base::Optional<NGBoxStrut>& border_padding = base::nullopt);
// Same as ResolveInlineLength, except here content_size roughly plays the part
// of MinMaxSize.
-CORE_EXPORT LayoutUnit ResolveBlockLength(const NGConstraintSpace&,
- const ComputedStyle&,
- const Length&,
- LayoutUnit content_size,
- LengthResolveType,
- LengthResolvePhase);
+CORE_EXPORT LayoutUnit ResolveBlockLength(
+ const NGConstraintSpace&,
+ const ComputedStyle&,
+ const Length&,
+ LayoutUnit content_size,
+ LengthResolveType,
+ LengthResolvePhase,
+ const base::Optional<NGBoxStrut>& border_padding = base::nullopt);
// Convert margin/border/padding length to a layout unit using the
// given constraint space.
@@ -109,15 +116,20 @@ MinMaxSize ComputeMinAndMaxContentContribution(
// then constrains the result by the resolved min logical width and max logical
// width from the ComputedStyle object. Calls Node::ComputeMinMaxSize if needed.
// override_minmax is provided *solely* for use by unit tests.
-CORE_EXPORT LayoutUnit
-ComputeInlineSizeForFragment(const NGConstraintSpace&,
- NGLayoutInputNode,
- const MinMaxSize* override_minmax = nullptr);
+// border_padding can be passed in as an optimization; otherwise this function
+// will compute it itself.
+CORE_EXPORT LayoutUnit ComputeInlineSizeForFragment(
+ const NGConstraintSpace&,
+ NGLayoutInputNode,
+ const base::Optional<NGBoxStrut>& border_padding = base::nullopt,
+ const MinMaxSize* override_minmax = nullptr);
// Same as ComputeInlineSizeForFragment, but uses height instead of width.
-CORE_EXPORT LayoutUnit ComputeBlockSizeForFragment(const NGConstraintSpace&,
- const ComputedStyle&,
- LayoutUnit content_size);
+CORE_EXPORT LayoutUnit ComputeBlockSizeForFragment(
+ const NGConstraintSpace&,
+ const ComputedStyle&,
+ LayoutUnit content_size,
+ const base::Optional<NGBoxStrut>& border_padding = base::nullopt);
// Computes intrinsic size for replaced elements.
CORE_EXPORT NGLogicalSize
@@ -149,31 +161,51 @@ CORE_EXPORT LayoutUnit ResolveUsedColumnGap(LayoutUnit available_size,
// Compute physical margins.
CORE_EXPORT NGPhysicalBoxStrut ComputePhysicalMargins(const NGConstraintSpace&,
const ComputedStyle&);
+
// Compute margins for the specified NGConstraintSpace.
CORE_EXPORT NGBoxStrut ComputeMarginsFor(const NGConstraintSpace&,
const ComputedStyle&,
const NGConstraintSpace& compute_for);
-// Compute margins for the NGConstraintSpace.
-CORE_EXPORT NGBoxStrut ComputeMarginsForContainer(const NGConstraintSpace&,
- const ComputedStyle&);
-// Compute margins for the NGConstraintSpace in the visual order.
-CORE_EXPORT NGBoxStrut
-ComputeMarginsForVisualContainer(const NGConstraintSpace&,
- const ComputedStyle&);
+
// Compute margins for the style owner.
CORE_EXPORT NGBoxStrut ComputeMarginsForSelf(const NGConstraintSpace&,
const ComputedStyle&);
+// Compute line logical margins for the style owner.
+//
+// The "line" versions compute line-relative logical values. See NGLineBoxStrut
+// for more details.
+CORE_EXPORT NGLineBoxStrut ComputeLineMarginsForSelf(const NGConstraintSpace&,
+ const ComputedStyle&);
+
+// Compute line logical margins for the constraint space, in the visual order
+// (always assumes LTR, ignoring the direction) for inline layout algorithm.
+CORE_EXPORT NGLineBoxStrut
+ComputeLineMarginsForVisualContainer(const NGConstraintSpace&,
+ const ComputedStyle&);
+
// Compute margins for a child during the min-max size calculation.
CORE_EXPORT NGBoxStrut ComputeMinMaxMargins(const ComputedStyle& parent_style,
NGLayoutInputNode child);
-CORE_EXPORT NGBoxStrut ComputeBorders(const NGConstraintSpace& constraint_space,
+CORE_EXPORT NGBoxStrut ComputeBorders(const NGConstraintSpace&,
const ComputedStyle&);
+CORE_EXPORT NGBoxStrut ComputeBorders(const NGConstraintSpace&,
+ const NGLayoutInputNode);
+
+CORE_EXPORT NGLineBoxStrut ComputeLineBorders(const NGConstraintSpace&,
+ const ComputedStyle&);
+
CORE_EXPORT NGBoxStrut ComputePadding(const NGConstraintSpace&,
const ComputedStyle&);
+CORE_EXPORT NGBoxStrut ComputePadding(const NGConstraintSpace&,
+ const NGLayoutInputNode);
+
+CORE_EXPORT NGLineBoxStrut ComputeLinePadding(const NGConstraintSpace&,
+ const ComputedStyle&);
+
// Convert inline margins from computed to used values. This will resolve 'auto'
// values and over-constrainedness. This uses the available size from the
// constraint space and inline size to compute the margins that are auto, if
@@ -205,10 +237,13 @@ NGBoxStrut CalculateBorderScrollbarPadding(
const NGConstraintSpace& constraint_space,
const NGBlockNode node);
+// border_padding can be passed in as an optimization; otherwise this function
+// will compute it itself.
NGLogicalSize CalculateBorderBoxSize(
const NGConstraintSpace& constraint_space,
const NGBlockNode& node,
- LayoutUnit block_content_size = NGSizeIndefinite);
+ LayoutUnit block_content_size = NGSizeIndefinite,
+ const base::Optional<NGBoxStrut>& border_padding = base::nullopt);
NGLogicalSize CalculateContentBoxSize(
const NGLogicalSize border_box_size,
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 a6577d9af92..c0759738e68 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
@@ -89,7 +89,7 @@ class NGLengthUtilsTestWithNode : public NGLayoutTest {
body->SetPreferredLogicalWidthsDirty();
NGBlockNode node(body);
return ::blink::ComputeInlineSizeForFragment(*constraint_space, node,
- &sizes);
+ base::nullopt, &sizes);
}
scoped_refptr<ComputedStyle> style_;
@@ -391,12 +391,13 @@ TEST_F(NGLengthUtilsTest, testMargins) {
scoped_refptr<NGConstraintSpace> constraint_space(
ConstructConstraintSpace(200, 300));
- NGBoxStrut margins = ComputeMarginsForContainer(*constraint_space, *style_);
+ NGPhysicalBoxStrut margins =
+ ComputePhysicalMargins(*constraint_space, *style_);
- EXPECT_EQ(LayoutUnit(20), margins.block_start);
- EXPECT_EQ(LayoutUnit(52), margins.inline_end);
- EXPECT_EQ(LayoutUnit(), margins.block_end);
- EXPECT_EQ(LayoutUnit(22), margins.inline_start);
+ EXPECT_EQ(LayoutUnit(20), margins.top);
+ EXPECT_EQ(LayoutUnit(52), margins.right);
+ EXPECT_EQ(LayoutUnit(), margins.bottom);
+ EXPECT_EQ(LayoutUnit(22), margins.left);
}
TEST_F(NGLengthUtilsTest, testBorders) {
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_link.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_link.h
new file mode 100644
index 00000000000..f7722a7458d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_link.h
@@ -0,0 +1,53 @@
+// 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_LAYOUT_NG_NG_LINK_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_NG_LINK_H_
+
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/layout/ng/geometry/ng_physical_offset.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h"
+#include "third_party/blink/renderer/platform/wtf/vector_traits.h"
+
+namespace blink {
+
+// Class representing the offset of a child fragment relative to the
+// parent fragment. Fragments themselves have no position information
+// allowing entire fragment subtrees to be reused and cached regardless
+// of placement.
+class CORE_EXPORT NGLink {
+ DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
+
+ public:
+ NGLink() = default;
+ NGLink(scoped_refptr<const NGPhysicalFragment> fragment,
+ NGPhysicalOffset offset)
+ : fragment_(fragment), offset_(offset) {}
+ ~NGLink() = default;
+
+ // Returns the offset relative to the parent fragment's content-box.
+ NGPhysicalOffset Offset() const { return offset_; }
+
+ operator bool() const { return fragment_.get(); }
+ const NGPhysicalFragment& operator*() const { return *fragment_.get(); }
+ const NGPhysicalFragment* operator->() const { return fragment_.get(); }
+ const NGPhysicalFragment* get() const { return fragment_.get(); }
+
+ private:
+ scoped_refptr<const NGPhysicalFragment> fragment_;
+ NGPhysicalOffset offset_;
+
+ // The builder classes needs to set the offset_ field during
+ // fragment construciton to allow the child vector to be moved
+ // instead of reconstructed during fragment construction.
+ friend class NGFragmentBuilder;
+ friend class NGLineBoxFragmentBuilder;
+ friend class NGLayoutResult;
+};
+
+} // namespace blink
+
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::NGLink);
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_NG_LINK_H_
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 ecc0b55d5c2..bebfe5f98cc 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
@@ -25,14 +25,12 @@ NGOutOfFlowLayoutPart::NGOutOfFlowLayoutPart(
NGFragmentBuilder* container_builder,
bool contains_absolute,
bool contains_fixed,
- const NGBoxStrut& scrollbar_sizes,
+ const NGBoxStrut& borders_and_scrollers,
const NGConstraintSpace& container_space,
const ComputedStyle& container_style)
: container_builder_(container_builder),
contains_absolute_(contains_absolute),
contains_fixed_(contains_fixed) {
- NGBoxStrut borders_and_scrollers =
- ComputeBorders(container_space, container_style) + scrollbar_sizes;
NGPhysicalBoxStrut physical_borders = borders_and_scrollers.ConvertToPhysical(
container_style.GetWritingMode(), container_style.Direction());
@@ -383,7 +381,10 @@ scoped_refptr<NGLayoutResult> NGOutOfFlowLayoutPart::LayoutDescendant(
layout_result = GenerateFragment(descendant.node, container_info,
block_estimate, node_position);
}
-
+ if (node.GetLayoutBox()->IsLayoutNGObject()) {
+ ToLayoutBlock(node.GetLayoutBox())
+ ->SetIsLegacyInitiatedOutOfFlowLayout(false);
+ }
// Compute logical offset, NGAbsolutePhysicalPosition is calculated relative
// to the padding box so add back the container's borders.
NGBoxStrut inset = node_position.inset.ConvertToLogical(
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 f89781dc8bc..49b8ffb4023 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
@@ -31,10 +31,16 @@ class CORE_EXPORT NGOutOfFlowLayoutPart {
STACK_ALLOCATED();
public:
+ // The container_builder, borders_and_scrollers, container_space and
+ // container_style parameters are all with respect to the containing block of
+ // the relevant out-of-flow positioned descendants. If the CSS "containing
+ // block" of such an out-of-flow positioned descendant isn't a true block (but
+ // e.g. a relatively positioned inline instead), the containing block here is
+ // the containing block of said non-block.
NGOutOfFlowLayoutPart(NGFragmentBuilder* container_builder,
bool contains_absolute,
bool contains_fixed,
- const NGBoxStrut& scrollbar_sizes,
+ const NGBoxStrut& borders_and_scrollers,
const NGConstraintSpace& container_space,
const ComputedStyle& container_style);
@@ -59,6 +65,8 @@ class CORE_EXPORT NGOutOfFlowLayoutPart {
// Inline containing block is positioned wrt default containing block.
struct ContainingBlockInfo {
STACK_ALLOCATED();
+
+ public:
// Containing block style.
const ComputedStyle* style;
// Logical in containing block coordinates.
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_positioned_descendant.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_positioned_descendant.h
index d3d9d360639..2f38cb50241 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_positioned_descendant.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_positioned_descendant.h
@@ -25,11 +25,11 @@ namespace blink {
struct CORE_EXPORT NGOutOfFlowPositionedDescendant {
NGBlockNode node;
NGStaticPosition static_position;
- LayoutObject* inline_container;
+ const LayoutObject* inline_container;
NGOutOfFlowPositionedDescendant(
NGBlockNode node_param,
NGStaticPosition static_position_param,
- LayoutObject* inline_container_param = nullptr)
+ const LayoutObject* inline_container_param = nullptr)
: node(node_param),
static_position(static_position_param),
inline_container(inline_container_param) {}
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 bc3ab40e461..10acb9062d2 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
@@ -22,8 +22,10 @@ NGPageLayoutAlgorithm::NGPageLayoutAlgorithm(NGBlockNode node,
: NGLayoutAlgorithm(node, space, ToNGBlockBreakToken(break_token)) {}
scoped_refptr<NGLayoutResult> NGPageLayoutAlgorithm::Layout() {
- NGBoxStrut border_scrollbar_padding =
- CalculateBorderScrollbarPadding(ConstraintSpace(), Node());
+ NGBoxStrut borders = ComputeBorders(ConstraintSpace(), Node());
+ NGBoxStrut scrollbars = Node().GetScrollbarSizes();
+ NGBoxStrut padding = ComputePadding(ConstraintSpace(), Node());
+ NGBoxStrut border_scrollbar_padding = borders + scrollbars + padding;
NGLogicalSize border_box_size =
CalculateBorderBoxSize(ConstraintSpace(), Node());
NGLogicalSize content_box_size =
@@ -51,12 +53,13 @@ scoped_refptr<NGLayoutResult> NGPageLayoutAlgorithm::Layout() {
NGBlockLayoutAlgorithm child_algorithm(Node(), *child_space.get(),
break_token.get());
scoped_refptr<NGLayoutResult> result = child_algorithm.Layout();
- scoped_refptr<NGPhysicalBoxFragment> page(
+ scoped_refptr<const NGPhysicalBoxFragment> page(
ToNGPhysicalBoxFragment(result->PhysicalFragment().get()));
container_builder_.AddChild(result, page_offset);
- NGBoxFragment logical_fragment(writing_mode, *page);
+ NGBoxFragment logical_fragment(writing_mode, ConstraintSpace().Direction(),
+ *page);
intrinsic_block_size =
std::max(intrinsic_block_size,
page_offset.block_offset + logical_fragment.BlockSize());
@@ -70,10 +73,11 @@ scoped_refptr<NGLayoutResult> NGPageLayoutAlgorithm::Layout() {
border_box_size.block_size = ComputeBlockSizeForFragment(
ConstraintSpace(), Style(), intrinsic_block_size);
container_builder_.SetBlockSize(border_box_size.block_size);
+ container_builder_.SetBorders(ComputeBorders(ConstraintSpace(), Style()));
container_builder_.SetPadding(ComputePadding(ConstraintSpace(), Style()));
NGOutOfFlowLayoutPart(&container_builder_, Node().IsAbsoluteContainer(),
- Node().IsFixedContainer(), Node().GetScrollbarSizes(),
+ Node().IsFixedContainer(), borders + scrollbars,
ConstraintSpace(), Style())
.Run();
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 5379dec7c92..a3753509e90 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
@@ -21,8 +21,9 @@ NGPhysicalBoxFragment::NGPhysicalBoxFragment(
const ComputedStyle& style,
NGStyleVariant style_variant,
NGPhysicalSize size,
- Vector<scoped_refptr<NGPhysicalFragment>>& children,
- const NGPixelSnappedPhysicalBoxStrut& padding,
+ Vector<NGLink>& children,
+ const NGPhysicalBoxStrut& borders,
+ const NGPhysicalBoxStrut& padding,
const NGPhysicalOffsetRect& contents_ink_overflow,
Vector<NGBaseline>& baselines,
NGBoxType box_type,
@@ -39,10 +40,12 @@ NGPhysicalBoxFragment::NGPhysicalBoxFragment(
contents_ink_overflow,
std::move(break_token)),
baselines_(std::move(baselines)),
+ borders_(borders),
padding_(padding) {
DCHECK(baselines.IsEmpty()); // Ensure move semantics is used.
is_old_layout_root_ = is_old_layout_root;
border_edge_ = border_edges;
+ children_inline_ = layout_object && layout_object->ChildrenInline();
// Compute visual contribution from descendant outlines.
NGOutlineUtils::FragmentMap anchor_fragment_map;
@@ -60,12 +63,6 @@ NGPhysicalBoxFragment::NGPhysicalBoxFragment(
!descendant_outlines_.IsEmpty());
}
-bool NGPhysicalBoxFragment::IsFirstLineAnonymousInlineBox() const {
- return IsInlineBox() && UsesFirstLineStyle() &&
- layout_object_->IsAnonymous() && layout_object_->IsLayoutInline() &&
- ToLayoutInline(layout_object_)->IsFirstLineAnonymous();
-}
-
const NGBaseline* NGPhysicalBoxFragment::Baseline(
const NGBaselineRequest& request) const {
for (const auto& baseline : baselines_) {
@@ -82,12 +79,6 @@ bool NGPhysicalBoxFragment::HasSelfPaintingLayer() const {
return ToLayoutBoxModelObject(layout_object)->HasSelfPaintingLayer();
}
-bool NGPhysicalBoxFragment::ChildrenInline() const {
- const LayoutObject* layout_object = GetLayoutObject();
- DCHECK(layout_object);
- return layout_object->ChildrenInline();
-}
-
bool NGPhysicalBoxFragment::HasOverflowClip() const {
const LayoutObject* layout_object = GetLayoutObject();
DCHECK(layout_object);
@@ -124,7 +115,7 @@ NGPhysicalOffsetRect NGPhysicalBoxFragment::ScrollableOverflow() const {
for (const auto& child_fragment : Children()) {
NGPhysicalOffsetRect child_overflow =
child_fragment->ScrollableOverflow();
- child_overflow.offset += child_fragment->Offset();
+ child_overflow.offset += child_fragment.Offset();
overflow.Unite(child_overflow);
}
return overflow;
@@ -205,7 +196,7 @@ void NGPhysicalBoxFragment::AddSelfOutlineRects(
DCHECK(line_child.fragment->GetLayoutObject());
line_child.fragment->GetLayoutObject()->LocalToAncestorRects(
line_child_rects, ToLayoutBoxModelObject(GetLayoutObject()),
- child->Offset().ToLayoutPoint(), additional_offset);
+ child.Offset().ToLayoutPoint(), additional_offset);
if (!line_child_rects.IsEmpty())
outline_rects->push_back(line_child_rects[0]);
}
@@ -247,16 +238,4 @@ UBiDiLevel NGPhysicalBoxFragment::BidiLevel() const {
return self_item->BidiLevel();
}
-scoped_refptr<NGPhysicalFragment> NGPhysicalBoxFragment::CloneWithoutOffset()
- const {
- Vector<scoped_refptr<NGPhysicalFragment>> children_copy(children_);
- Vector<NGBaseline> baselines_copy(baselines_);
- scoped_refptr<NGPhysicalFragment> physical_fragment =
- base::AdoptRef(new NGPhysicalBoxFragment(
- layout_object_, Style(), StyleVariant(), size_, children_copy,
- padding_, contents_ink_overflow_, baselines_copy, BoxType(),
- is_old_layout_root_, border_edge_, break_token_));
- return physical_fragment;
-}
-
} // 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 f3f8a868658..ddf0ea2fe54 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
@@ -21,8 +21,9 @@ class CORE_EXPORT NGPhysicalBoxFragment final
const ComputedStyle& style,
NGStyleVariant style_variant,
NGPhysicalSize size,
- Vector<scoped_refptr<NGPhysicalFragment>>& children,
- const NGPixelSnappedPhysicalBoxStrut& padding,
+ Vector<NGLink>& children,
+ const NGPhysicalBoxStrut& border,
+ const NGPhysicalBoxStrut& padding,
const NGPhysicalOffsetRect& contents_ink_overflow,
Vector<NGBaseline>& baselines,
NGBoxType box_type,
@@ -30,15 +31,18 @@ class CORE_EXPORT NGPhysicalBoxFragment final
unsigned, // NGBorderEdges::Physical
scoped_refptr<NGBreakToken> break_token = nullptr);
- // True if this is an anonymous inline box for ::first-line.
- bool IsFirstLineAnonymousInlineBox() const;
-
const NGBaseline* Baseline(const NGBaselineRequest&) const;
- const NGPixelSnappedPhysicalBoxStrut& Padding() const { return padding_; }
+ const NGPhysicalBoxStrut Borders() const { return borders_; }
+
+ const NGPhysicalBoxStrut Padding() const { return padding_; }
+
+ NGPixelSnappedPhysicalBoxStrut PixelSnappedPadding() const {
+ return padding_.SnapToDevicePixels();
+ }
bool HasSelfPaintingLayer() const;
- bool ChildrenInline() const;
+ bool ChildrenInline() const { return children_inline_; }
// True if overflow != 'visible', except for certain boxes that do not allow
// overflow clip; i.e., AllowOverflowClip() returns false.
@@ -68,11 +72,12 @@ class CORE_EXPORT NGPhysicalBoxFragment final
UBiDiLevel BidiLevel() const override;
- scoped_refptr<NGPhysicalFragment> CloneWithoutOffset() const;
+ scoped_refptr<const NGPhysicalFragment> CloneWithoutOffset() const;
private:
Vector<NGBaseline> baselines_;
- NGPixelSnappedPhysicalBoxStrut padding_;
+ NGPhysicalBoxStrut borders_;
+ NGPhysicalBoxStrut padding_;
NGPhysicalOffsetRect descendant_outlines_;
};
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 ccc8d918fe1..15fe4ce1b59 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
@@ -30,7 +30,7 @@ TEST_F(NGPhysicalBoxFragmentTest, DISABLED_NormalOldLayoutRoot) {
EXPECT_TRUE(fragment->IsBox());
EXPECT_EQ(NGPhysicalFragment::kNormalBox, fragment->BoxType());
EXPECT_TRUE(fragment->IsOldLayoutRoot());
- EXPECT_TRUE(fragment->IsBlockLayoutRoot());
+ EXPECT_TRUE(fragment->IsBlockFormattingContextRoot());
}
// TODO(editing-dev): Once LayoutNG supports editing, we should change this
@@ -44,7 +44,7 @@ TEST_F(NGPhysicalBoxFragmentTest, DISABLED_FloatOldLayoutRoot) {
EXPECT_TRUE(fragment->IsBox());
EXPECT_EQ(NGPhysicalFragment::kFloating, fragment->BoxType());
EXPECT_TRUE(fragment->IsOldLayoutRoot());
- EXPECT_TRUE(fragment->IsBlockLayoutRoot());
+ EXPECT_TRUE(fragment->IsBlockFormattingContextRoot());
}
// TODO(editing-dev): Once LayoutNG supports editing, we should change this
@@ -60,7 +60,7 @@ TEST_F(NGPhysicalBoxFragmentTest, DISABLED_InlineBlockOldLayoutRoot) {
EXPECT_TRUE(fragment->IsBox());
EXPECT_EQ(NGPhysicalFragment::kAtomicInline, fragment->BoxType());
EXPECT_TRUE(fragment->IsOldLayoutRoot());
- EXPECT_TRUE(fragment->IsBlockLayoutRoot());
+ EXPECT_TRUE(fragment->IsBlockFormattingContextRoot());
}
// TODO(editing-dev): Once LayoutNG supports editing, we should change this
@@ -77,7 +77,7 @@ TEST_F(NGPhysicalBoxFragmentTest, DISABLED_OutOfFlowPositionedOldLayoutRoot) {
EXPECT_TRUE(fragment->IsBox());
EXPECT_EQ(NGPhysicalFragment::kOutOfFlowPositioned, fragment->BoxType());
EXPECT_TRUE(fragment->IsOldLayoutRoot());
- EXPECT_TRUE(fragment->IsBlockLayoutRoot());
+ EXPECT_TRUE(fragment->IsBlockFormattingContextRoot());
}
} // namespace blink
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 69deaa9d244..f7faaeb07d1 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
@@ -13,7 +13,7 @@ NGPhysicalContainerFragment::NGPhysicalContainerFragment(
NGPhysicalSize size,
NGFragmentType type,
unsigned sub_type,
- Vector<scoped_refptr<NGPhysicalFragment>>& children,
+ Vector<NGLink>& children,
const NGPhysicalOffsetRect& contents_ink_overflow,
scoped_refptr<NGBreakToken> break_token)
: NGPhysicalFragment(layout_object,
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 52da5f09119..1f9d36442f7 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
@@ -7,6 +7,7 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_physical_offset_rect.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_link.h"
#include "third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -14,9 +15,7 @@ namespace blink {
class CORE_EXPORT NGPhysicalContainerFragment : public NGPhysicalFragment {
public:
- const Vector<scoped_refptr<NGPhysicalFragment>>& Children() const {
- return children_;
- }
+ const Vector<NGLink>& Children() const { return children_; }
// Ink overflow of children in local coordinates.
const NGPhysicalOffsetRect& ContentsInkOverflow() const {
@@ -25,18 +24,17 @@ class CORE_EXPORT NGPhysicalContainerFragment : public NGPhysicalFragment {
protected:
// This modifies the passed-in children vector.
- NGPhysicalContainerFragment(
- LayoutObject*,
- const ComputedStyle&,
- NGStyleVariant,
- NGPhysicalSize,
- NGFragmentType,
- unsigned sub_type,
- Vector<scoped_refptr<NGPhysicalFragment>>& children,
- const NGPhysicalOffsetRect& contents_ink_overflow,
- scoped_refptr<NGBreakToken> = nullptr);
-
- Vector<scoped_refptr<NGPhysicalFragment>> children_;
+ NGPhysicalContainerFragment(LayoutObject*,
+ const ComputedStyle&,
+ NGStyleVariant,
+ NGPhysicalSize,
+ NGFragmentType,
+ unsigned sub_type,
+ Vector<NGLink>& children,
+ const NGPhysicalOffsetRect& contents_ink_overflow,
+ scoped_refptr<NGBreakToken> = nullptr);
+
+ Vector<NGLink> children_;
NGPhysicalOffsetRect contents_ink_overflow_;
};
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 760b1285032..b103ce54703 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
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
#include "third_party/blink/renderer/core/layout/layout_block.h"
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_border_edges.h"
@@ -19,16 +19,18 @@
namespace blink {
namespace {
-bool AppendFragmentOffsetAndSize(const NGPhysicalFragment* fragment,
- StringBuilder* builder,
- NGPhysicalFragment::DumpFlags flags,
- bool has_content) {
+bool AppendFragmentOffsetAndSize(
+ const NGPhysicalFragment* fragment,
+ base::Optional<NGPhysicalOffset> fragment_offset,
+ StringBuilder* builder,
+ NGPhysicalFragment::DumpFlags flags,
+ bool has_content) {
if (flags & NGPhysicalFragment::DumpOffset) {
if (has_content)
builder->Append(" ");
builder->Append("offset:");
- if (fragment->IsPlaced())
- builder->Append(fragment->Offset().ToString());
+ if (fragment_offset)
+ builder->Append(fragment_offset->ToString());
else
builder->Append("unplaced");
has_content = true;
@@ -71,6 +73,9 @@ String StringForBoxType(const NGPhysicalFragment& fragment) {
case NGPhysicalFragment::NGBoxType::kInlineBox:
result.Append("inline");
break;
+ case NGPhysicalFragment::NGBoxType::kColumnBox:
+ result.Append("column");
+ break;
case NGPhysicalFragment::NGBoxType::kAtomicInline:
result.Append("atomic-inline");
break;
@@ -102,6 +107,7 @@ String StringForBoxType(const NGPhysicalFragment& fragment) {
}
void AppendFragmentToString(const NGPhysicalFragment* fragment,
+ base::Optional<NGPhysicalOffset> fragment_offset,
StringBuilder* builder,
NGPhysicalFragment::DumpFlags flags,
unsigned indent = 2) {
@@ -129,8 +135,8 @@ void AppendFragmentToString(const NGPhysicalFragment* fragment,
builder->Append("(self paint)");
}
}
- has_content =
- AppendFragmentOffsetAndSize(fragment, builder, flags, has_content);
+ has_content = AppendFragmentOffsetAndSize(fragment, fragment_offset,
+ builder, flags, has_content);
if (flags & NGPhysicalFragment::DumpNodeName &&
fragment->GetLayoutObject()) {
@@ -142,8 +148,10 @@ void AppendFragmentToString(const NGPhysicalFragment* fragment,
if (flags & NGPhysicalFragment::DumpSubtree) {
const auto& children = box->Children();
- for (unsigned i = 0; i < children.size(); i++)
- AppendFragmentToString(children[i].get(), builder, flags, indent + 2);
+ for (unsigned i = 0; i < children.size(); i++) {
+ AppendFragmentToString(children[i].get(), children[i].Offset(), builder,
+ flags, indent + 2);
+ }
}
return;
}
@@ -153,15 +161,17 @@ void AppendFragmentToString(const NGPhysicalFragment* fragment,
builder->Append("LineBox");
has_content = true;
}
- has_content =
- AppendFragmentOffsetAndSize(fragment, builder, flags, has_content);
+ has_content = AppendFragmentOffsetAndSize(fragment, fragment_offset,
+ builder, flags, has_content);
builder->Append("\n");
if (flags & NGPhysicalFragment::DumpSubtree) {
const auto* line_box = ToNGPhysicalLineBoxFragment(fragment);
const auto& children = line_box->Children();
- for (unsigned i = 0; i < children.size(); i++)
- AppendFragmentToString(children[i].get(), builder, flags, indent + 2);
+ for (unsigned i = 0; i < children.size(); i++) {
+ AppendFragmentToString(children[i].get(), children[i].Offset(), builder,
+ flags, indent + 2);
+ }
return;
}
}
@@ -171,8 +181,8 @@ void AppendFragmentToString(const NGPhysicalFragment* fragment,
builder->Append("Text");
has_content = true;
}
- has_content =
- AppendFragmentOffsetAndSize(fragment, builder, flags, has_content);
+ has_content = AppendFragmentOffsetAndSize(fragment, fragment_offset,
+ builder, flags, has_content);
if (flags & NGPhysicalFragment::DumpTextOffsets) {
const auto* text = ToNGPhysicalTextFragment(fragment);
@@ -192,8 +202,8 @@ void AppendFragmentToString(const NGPhysicalFragment* fragment,
builder->Append("Unknown fragment type");
has_content = true;
}
- has_content =
- AppendFragmentOffsetAndSize(fragment, builder, flags, has_content);
+ has_content = AppendFragmentOffsetAndSize(fragment, fragment_offset, builder,
+ flags, has_content);
builder->Append("\n");
}
@@ -222,7 +232,6 @@ NGPhysicalFragment::NGPhysicalFragment(LayoutObject* layout_object,
type_(type),
sub_type_(sub_type),
is_old_layout_root_(false),
- is_placed_(false),
style_variant_((unsigned)style_variant) {}
// Keep the implementation of the destructor here, to avoid dependencies on
@@ -352,9 +361,17 @@ NGPhysicalOffsetRect NGPhysicalFragment::ScrollableOverflow() const {
}
void NGPhysicalFragment::PropagateContentsInkOverflow(
- NGPhysicalOffsetRect* parent_ink_overflow) const {
+ NGPhysicalOffsetRect* parent_ink_overflow,
+ NGPhysicalOffset fragment_offset) const {
+ // Add in visual overflow from the child. Even if the child clips its
+ // overflow, it may still have visual overflow of its own set from box shadows
+ // or reflections. It is unnecessary to propagate this overflow if we are
+ // clipping our own overflow.
+ if (IsBox() && ToNGPhysicalBoxFragment(*this).HasSelfPaintingLayer())
+ return;
+
NGPhysicalOffsetRect ink_overflow = InkOverflow();
- ink_overflow.offset += Offset();
+ ink_overflow.offset += fragment_offset;
parent_ink_overflow->Unite(ink_overflow);
}
@@ -390,35 +407,10 @@ TextDirection NGPhysicalFragment::ResolvedDirection() const {
return DirectionFromLevel(BidiLevel());
}
-scoped_refptr<NGPhysicalFragment> NGPhysicalFragment::CloneWithoutOffset()
- const {
- switch (Type()) {
- case kFragmentBox:
- return static_cast<const NGPhysicalBoxFragment*>(this)
- ->CloneWithoutOffset();
- break;
- case kFragmentText:
- return static_cast<const NGPhysicalTextFragment*>(this)
- ->CloneWithoutOffset();
- break;
- case kFragmentLineBox:
- return static_cast<const NGPhysicalLineBoxFragment*>(this)
- ->CloneWithoutOffset();
- break;
- default:
- NOTREACHED();
- break;
- }
- return nullptr;
-}
-
String NGPhysicalFragment::ToString() const {
StringBuilder output;
- output.Append(String::Format(
- "Type: '%d' Size: '%s' Offset: '%s' Placed: '%d'", Type(),
- Size().ToString().Ascii().data(),
- is_placed_ ? Offset().ToString().Ascii().data() : "no offset",
- IsPlaced()));
+ output.Append(String::Format("Type: '%d' Size: '%s'", Type(),
+ Size().ToString().Ascii().data()));
switch (Type()) {
case kFragmentBox:
output.Append(String::Format(", BoxType: '%s'",
@@ -439,12 +431,14 @@ String NGPhysicalFragment::ToString() const {
return output.ToString();
}
-String NGPhysicalFragment::DumpFragmentTree(DumpFlags flags,
- unsigned indent) const {
+String NGPhysicalFragment::DumpFragmentTree(
+ DumpFlags flags,
+ base::Optional<NGPhysicalOffset> fragment_offset,
+ unsigned indent) const {
StringBuilder string_builder;
if (flags & DumpHeaderText)
string_builder.Append(".:: LayoutNG Physical Fragment Tree ::.\n");
- AppendFragmentToString(this, &string_builder, flags, indent);
+ AppendFragmentToString(this, fragment_offset, &string_builder, flags, indent);
return string_builder.ToString();
}
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 2f6642cca0a..5c54a5060bd 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
@@ -45,7 +45,7 @@ struct CORE_EXPORT NGPhysicalFragmentTraits {
// NGFragment wrapper classes which transforms information into the logical
// coordinate system.
class CORE_EXPORT NGPhysicalFragment
- : public RefCounted<NGPhysicalFragment, NGPhysicalFragmentTraits> {
+ : public RefCounted<const NGPhysicalFragment, NGPhysicalFragmentTraits> {
public:
enum NGFragmentType {
kFragmentBox = 0,
@@ -57,15 +57,19 @@ class CORE_EXPORT NGPhysicalFragment
enum NGBoxType {
kNormalBox,
kInlineBox,
+ // A multi-column container creates column boxes as its children, which
+ // content is flowed into. https://www.w3.org/TR/css-multicol-1/#column-box
+ kColumnBox,
kAtomicInline,
kFloating,
kOutOfFlowPositioned,
// When adding new values, make sure the bit size of |sub_type_| is large
// enough to store.
- // Also, add after kMinimumBlockLayoutRoot if the box type is a block layout
- // root, or before otherwise. See IsBlockLayoutRoot().
- kMinimumBlockLayoutRoot = kAtomicInline
+ // Also, add after kMinimumBlockFormattingContextRoot if the box type is a
+ // block formatting context root, or before otherwise. See
+ // IsBlockFormattingContextRoot().
+ kMinimumBlockFormattingContextRoot = kAtomicInline
};
~NGPhysicalFragment();
@@ -113,11 +117,9 @@ class CORE_EXPORT NGPhysicalFragment
// Returns whether the fragment is old layout root.
bool IsOldLayoutRoot() const { return is_old_layout_root_; }
- // A block sub-layout starts on this fragment. Inline blocks, floats, out of
- // flow positioned objects are such examples. This is also true on NG/legacy
- // boundary.
- bool IsBlockLayoutRoot() const {
- return (IsBox() && BoxType() >= NGBoxType::kMinimumBlockLayoutRoot) ||
+ bool IsBlockFormattingContextRoot() const {
+ return (IsBox() &&
+ BoxType() >= NGBoxType::kMinimumBlockFormattingContextRoot) ||
IsOldLayoutRoot();
}
@@ -142,13 +144,6 @@ class CORE_EXPORT NGPhysicalFragment
unsigned BorderEdges() const { return border_edge_; }
NGPixelSnappedPhysicalBoxStrut BorderWidths() const;
- // Returns the offset relative to the parent fragment's content-box.
- NGPhysicalOffset Offset() const {
- DCHECK(is_placed_) << "this=" << this << " for layout object "
- << layout_object_;
- return offset_;
- }
-
NGBreakToken* BreakToken() const { return break_token_.get(); }
NGStyleVariant StyleVariant() const {
return static_cast<NGStyleVariant>(style_variant_);
@@ -179,16 +174,8 @@ class CORE_EXPORT NGPhysicalFragment
NGPhysicalOffsetRect ScrollableOverflow() const;
// Unite visual rect to propagate to parent's ContentsVisualRect.
- void PropagateContentsInkOverflow(NGPhysicalOffsetRect*) const;
-
- // Should only be used by the parent fragment's layout.
- void SetOffset(NGPhysicalOffset offset) {
- DCHECK(!is_placed_);
- offset_ = offset;
- is_placed_ = true;
- }
-
- bool IsPlaced() const { return is_placed_; }
+ void PropagateContentsInkOverflow(NGPhysicalOffsetRect*,
+ NGPhysicalOffset) const;
// Returns the bidi level of a text or atomic inline fragment.
virtual UBiDiLevel BidiLevel() const;
@@ -197,8 +184,6 @@ class CORE_EXPORT NGPhysicalFragment
// be confused with the CSS 'direction' property.
virtual TextDirection ResolvedDirection() const;
- scoped_refptr<NGPhysicalFragment> CloneWithoutOffset() const;
-
String ToString() const;
enum DumpFlag {
@@ -216,7 +201,9 @@ class CORE_EXPORT NGPhysicalFragment
};
typedef int DumpFlags;
- String DumpFragmentTree(DumpFlags, unsigned indent = 2) const;
+ String DumpFragmentTree(DumpFlags,
+ base::Optional<NGPhysicalOffset> = base::nullopt,
+ unsigned indent = 2) const;
#ifndef NDEBUG
void ShowFragmentTree() const;
@@ -233,20 +220,22 @@ class CORE_EXPORT NGPhysicalFragment
const Vector<NGInlineItem>& InlineItemsOfContainingBlock() const;
- LayoutObject* layout_object_;
+ LayoutObject* const layout_object_;
scoped_refptr<const ComputedStyle> style_;
- NGPhysicalSize size_;
- NGPhysicalOffset offset_;
+ const NGPhysicalSize size_;
scoped_refptr<NGBreakToken> break_token_;
- unsigned type_ : 2; // NGFragmentType
- unsigned sub_type_ : 3; // Union of NGBoxType and NGTextType
+ const unsigned type_ : 2; // NGFragmentType
+ const unsigned sub_type_ : 3; // Union of NGBoxType and NGTextType
unsigned is_old_layout_root_ : 1;
- unsigned is_placed_ : 1;
unsigned border_edge_ : 4; // NGBorderEdges::Physical
- unsigned style_variant_ : 2; // NGStyleVariant
+ const unsigned style_variant_ : 2; // NGStyleVariant
unsigned base_direction_ : 1; // TextDirection, for NGPhysicalLineBoxFragment
+ // The following bitfield is only to be used by NGPhysicalBoxFragment (it's
+ // defined here to save memory, since that class has no bitfields).
+ unsigned children_inline_ : 1;
+
private:
friend struct NGPhysicalFragmentTraits;
void Destroy() const;
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 a06aa67c30f..97333992027 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
@@ -5,6 +5,8 @@
#include "third_party/blink/renderer/core/layout/ng/ng_space_utils.h"
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_bfc_offset.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/style/computed_style.h"
#include "third_party/blink/renderer/platform/text/writing_mode.h"
@@ -31,4 +33,20 @@ bool AdjustToClearance(LayoutUnit clearance_offset, NGBfcOffset* offset) {
return false;
}
+scoped_refptr<NGConstraintSpace> CreateExtrinsicConstraintSpaceForChild(
+ const NGConstraintSpace& container_constraint_space,
+ LayoutUnit container_extrinsic_block_size,
+ NGLayoutInputNode child) {
+ NGLogicalSize extrinsic_size(NGSizeIndefinite,
+ container_extrinsic_block_size);
+
+ return NGConstraintSpaceBuilder(container_constraint_space)
+ .SetAvailableSize(extrinsic_size)
+ .SetPercentageResolutionSize(extrinsic_size)
+ .SetIsIntermediateLayout(true)
+ .SetIsNewFormattingContext(child.CreatesNewFormattingContext())
+ .SetFloatsBfcBlockOffset(LayoutUnit())
+ .ToConstraintSpace(child.Style().GetWritingMode());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_space_utils.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_space_utils.h
index 66262ad16c3..a14d8574a22 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_space_utils.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_space_utils.h
@@ -5,8 +5,10 @@
#ifndef NGSpaceUtils_h
#define NGSpaceUtils_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/ng_layout_input_node.h"
#include "third_party/blink/renderer/platform/layout_unit.h"
namespace blink {
@@ -24,6 +26,25 @@ bool ShouldShrinkToFit(const ComputedStyle& parent_style,
CORE_EXPORT bool AdjustToClearance(LayoutUnit clearance_offset,
NGBfcOffset* offset);
+// Create a child constraint space with only extrinsic block sizing data. This
+// will and can not be used for final layout, but is needed in an intermediate
+// measure pass that calculates the min/max size contribution from a child that
+// establishes an orthogonal flow root.
+//
+// Note that it's the child's *block* size that will be propagated as min/max
+// inline size to the container. Therefore it's crucial to provide the child
+// with an available inline size (which can be derived from the block size of
+// the container if definite). We'll provide any extrinsic available block size
+// that we have. This includes fixed and resolvable percentage sizes, for
+// instance, while auto will not resolve. If no extrinsic size can be
+// determined, we will resort to using a fallback later on, such as the initial
+// containing block size. Spec:
+// https://www.w3.org/TR/css-writing-modes-3/#orthogonal-auto
+scoped_refptr<NGConstraintSpace> CreateExtrinsicConstraintSpaceForChild(
+ const NGConstraintSpace& container_constraint_space,
+ LayoutUnit container_extrinsic_block_size,
+ NGLayoutInputNode child);
+
} // namespace blink
#endif // NGSpaceUtils_h
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_unpositioned_float.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_unpositioned_float.cc
index 285bee17df4..86a72b6ebce 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_unpositioned_float.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_unpositioned_float.cc
@@ -12,20 +12,9 @@ namespace blink {
// Define the constructor and destructor here, so that we can forward-declare
// more in the header file.
-NGUnpositionedFloat::NGUnpositionedFloat(const NGBoxStrut& margins,
- const NGLogicalSize& available_size,
- const NGLogicalSize& percentage_size,
- LayoutUnit origin_bfc_line_offset,
- LayoutUnit bfc_line_offset,
- NGBlockNode node,
+NGUnpositionedFloat::NGUnpositionedFloat(NGBlockNode node,
NGBlockBreakToken* token)
- : node(node),
- token(token),
- available_size(available_size),
- percentage_size(percentage_size),
- origin_bfc_line_offset(origin_bfc_line_offset),
- bfc_line_offset(bfc_line_offset),
- margins(margins) {}
+ : node(node), token(token) {}
NGUnpositionedFloat::~NGUnpositionedFloat() = default;
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_unpositioned_float.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_unpositioned_float.h
index 761bcc657a2..a94d10aa72a 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_unpositioned_float.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_unpositioned_float.h
@@ -7,72 +7,32 @@
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_box_strut.h"
-#include "third_party/blink/renderer/core/layout/ng/geometry/ng_logical_size.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_layout_result.h"
#include "third_party/blink/renderer/core/style/computed_style_constants.h"
-#include "third_party/blink/renderer/platform/wtf/ref_counted.h"
namespace blink {
-class NGBlockBreakToken;
-class NGLayoutResult;
-
// Struct that keeps all information needed to position floats in LayoutNG.
-struct CORE_EXPORT NGUnpositionedFloat
- : public RefCounted<NGUnpositionedFloat> {
- public:
- static scoped_refptr<NGUnpositionedFloat> Create(
- NGLogicalSize available_size,
- NGLogicalSize percentage_size,
- LayoutUnit origin_bfc_line_offset,
- LayoutUnit bfc_line_offset,
- NGBoxStrut margins,
- NGBlockNode node,
- NGBlockBreakToken* token) {
- return base::AdoptRef(new NGUnpositionedFloat(
- margins, available_size, percentage_size, origin_bfc_line_offset,
- bfc_line_offset, node, token));
- }
+struct CORE_EXPORT NGUnpositionedFloat final {
+ DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
+ public:
+ NGUnpositionedFloat(NGBlockNode node, NGBlockBreakToken* token);
~NGUnpositionedFloat();
NGBlockNode node;
scoped_refptr<NGBlockBreakToken> token;
- // Available size of the constraint space that will be used by
- // NGLayoutOpportunityIterator to position this floating object.
- NGLogicalSize available_size;
- NGLogicalSize percentage_size;
-
- // This is the BFC inline-offset for where we begin searching for layout
- // opportunities for this float.
- LayoutUnit origin_bfc_line_offset;
-
- // This is the BFC inline-offset for the float's parent. This is used for
- // calculating the offset between the float and its parent.
- LayoutUnit bfc_line_offset;
-
- // The margins are relative to the writing mode of the block formatting
- // context. They are stored for convinence and could be recomputed with other
- // data on this object.
- NGBoxStrut margins;
-
- // The layout result for this unpositioned float. This is only present if
- // it's in a different writing mode than the BFC.
+ // layout_result and margins are used as a cache when measuring the
+ // inline_size of a float in an inline context.
scoped_refptr<NGLayoutResult> layout_result;
+ NGBoxStrut margins;
bool IsLeft() const;
bool IsRight() const;
EClear ClearType() const;
-
- private:
- NGUnpositionedFloat(const NGBoxStrut& margins,
- const NGLogicalSize& available_size,
- const NGLogicalSize& percentage_size,
- LayoutUnit origin_bfc_line_offset,
- LayoutUnit bfc_line_offset,
- NGBlockNode node,
- NGBlockBreakToken* token);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_unpositioned_float_vector.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_unpositioned_float_vector.h
new file mode 100644
index 00000000000..3863a12cb25
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_unpositioned_float_vector.h
@@ -0,0 +1,17 @@
+// 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_LAYOUT_NG_NG_UNPOSITIONED_FLOAT_VECTOR_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_NG_UNPOSITIONED_FLOAT_VECTOR_H_
+
+#include "third_party/blink/renderer/platform/wtf/vector.h"
+
+namespace blink {
+
+struct NGUnpositionedFloat;
+typedef Vector<NGUnpositionedFloat, 1> NGUnpositionedFloatVector;
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_NG_UNPOSITIONED_FLOAT_VECTOR_H_
diff --git a/chromium/third_party/blink/renderer/core/layout/order_iterator.cc b/chromium/third_party/blink/renderer/core/layout/order_iterator.cc
index c96716349b3..f239179a6a4 100644
--- a/chromium/third_party/blink/renderer/core/layout/order_iterator.cc
+++ b/chromium/third_party/blink/renderer/core/layout/order_iterator.cc
@@ -63,7 +63,7 @@ LayoutBox* OrderIterator::Next() {
current_child_ = current_child_->NextSiblingBox();
}
} while (!current_child_ ||
- current_child_->Style()->Order() != *order_values_iterator_);
+ current_child_->StyleRef().Order() != *order_values_iterator_);
return current_child_;
}
@@ -79,7 +79,7 @@ OrderIteratorPopulator::~OrderIteratorPopulator() {
}
void OrderIteratorPopulator::CollectChild(const LayoutBox* child) {
- iterator_.order_values_.insert(child->Style()->Order());
+ iterator_.order_values_.insert(child->StyleRef().Order());
}
} // namespace blink
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 af6c5f78871..2f3ab2d35b3 100644
--- a/chromium/third_party/blink/renderer/core/layout/scroll_anchor.cc
+++ b/chromium/third_party/blink/renderer/core/layout/scroll_anchor.cc
@@ -285,7 +285,7 @@ ScrollAnchor::ExamineResult ScrollAnchor::Examine(
if (!CandidateMayMoveWithScroller(candidate, scroller_))
return ExamineResult(kSkip);
- if (candidate->Style()->OverflowAnchor() == EOverflowAnchor::kNone)
+ if (candidate->StyleRef().OverflowAnchor() == EOverflowAnchor::kNone)
return ExamineResult(kSkip);
LayoutRect candidate_rect = RelativeBounds(candidate, scroller_);
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 e35ef1a32f5..00a108458c8 100644
--- a/chromium/third_party/blink/renderer/core/layout/scrollbars_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/scrollbars_test.cc
@@ -20,10 +20,10 @@
#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/core/scroll/scrollbar_theme_overlay_mock.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/graphics/graphics_layer.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay_mock.h"
#include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
#include "third_party/blink/renderer/platform/testing/url_test_helpers.h"
@@ -64,7 +64,7 @@ class ScrollbarsTest : public SimTest {
WebMouseEvent event(
WebInputEvent::kMouseUp, WebFloatPoint(x, y), WebFloatPoint(x, y),
WebPointerProperties::Button::kLeft, 0,
- WebInputEvent::Modifiers::kLeftButtonDown, CurrentTimeTicks());
+ WebInputEvent::Modifiers::kNoModifiers, CurrentTimeTicks());
event.SetFrameScale(1);
GetEventHandler().HandleMouseReleaseEvent(event);
}
@@ -194,6 +194,8 @@ TEST_F(ScrollbarsTest, ScrollbarSizeForUseZoomDSF) {
WebViewImpl* web_view_impl =
web_view_helper.Initialize(nullptr, &client, nullptr, nullptr);
+ // Needed so visual viewport supplies its own scrollbars.
+ web_view_impl->GetSettings()->SetViewportEnabled(true);
web_view_impl->Resize(IntSize(800, 600));
WebURL base_url = URLTestHelpers::ToKURL("http://example.com/");
@@ -572,6 +574,58 @@ TEST_F(ScrollbarsTest, MouseOverScrollbarInCustomCursorElement) {
EXPECT_EQ(Cursor::Type::kPointer, CursorType());
}
+// Ensure mouse cursor should be override when hovering over the custom
+// scrollbar.
+TEST_F(ScrollbarsTest, MouseOverCustomScrollbarInCustomCursorElement) {
+ WebView().Resize(WebSize(250, 250));
+
+ SimRequest request("https://example.com/test.html", "text/html");
+ LoadURL("https://example.com/test.html");
+ request.Complete(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ body {
+ margin: 0;
+ }
+ #d1 {
+ width: 200px;
+ height: 200px;
+ overflow: auto;
+ cursor: move;
+ }
+ #d2 {
+ height: 400px;
+ }
+ ::-webkit-scrollbar {
+ background: none;
+ height: 5px;
+ width: 5px;
+ }
+ ::-webkit-scrollbar-thumb {
+ background-color: black;
+ }
+ </style>
+ <div id='d1'>
+ <div id='d2'></div>
+ </div>
+ )HTML");
+ Compositor().BeginFrame();
+
+ Document& document = GetDocument();
+
+ Element* div = document.getElementById("d1");
+
+ // Ensure hittest has DIV and scrollbar.
+ HitTestResult hit_test_result = HitTest(195, 5);
+
+ EXPECT_EQ(hit_test_result.InnerElement(), div);
+ EXPECT_TRUE(hit_test_result.GetScrollbar());
+
+ HandleMouseMoveEvent(195, 5);
+
+ EXPECT_EQ(Cursor::Type::kMove, CursorType());
+}
+
// Makes sure that mouse hover over an overlay scrollbar doesn't activate
// elements below(except the Element that owns the scrollbar) unless the
// scrollbar is faded out.
@@ -1069,7 +1123,7 @@ TEST_F(ScrollbarsTest, CustomScrollbarChangeToMobileByEmulator) {
DCHECK(!root_scrollable->VerticalScrollbar()->IsOverlayScrollbar());
DCHECK(!root_scrollable->VerticalScrollbar()->GetTheme().IsMockTheme());
- DCHECK(!viewport.LayerForHorizontalScrollbar()->Parent());
+ DCHECK(!viewport.LayerForHorizontalScrollbar());
DCHECK(div_scrollable->VerticalScrollbar());
DCHECK(div_scrollable->VerticalScrollbar()->IsCustomScrollbar());
@@ -1096,7 +1150,7 @@ TEST_F(ScrollbarsTest, CustomScrollbarChangeToMobileByEmulator) {
EXPECT_FALSE(root_scrollable->VerticalScrollbar()->IsOverlayScrollbar());
EXPECT_FALSE(root_scrollable->VerticalScrollbar()->GetTheme().IsMockTheme());
- DCHECK(!viewport.LayerForHorizontalScrollbar()->Parent());
+ DCHECK(!viewport.LayerForHorizontalScrollbar());
EXPECT_TRUE(div_scrollable->VerticalScrollbar());
EXPECT_TRUE(div_scrollable->VerticalScrollbar()->IsCustomScrollbar());
@@ -1359,7 +1413,7 @@ TEST_P(ScrollbarAppearanceTest, NativeScrollbarChangeToMobileByEmulator) {
root_scrollable->VerticalScrollbar()->IsOverlayScrollbar());
DCHECK(!root_scrollable->VerticalScrollbar()->GetTheme().IsMockTheme());
- DCHECK(!viewport.LayerForHorizontalScrollbar()->Parent());
+ DCHECK(!viewport.LayerForHorizontalScrollbar());
DCHECK(div_scrollable->VerticalScrollbar());
DCHECK(!div_scrollable->VerticalScrollbar()->IsCustomScrollbar());
@@ -1392,7 +1446,7 @@ TEST_P(ScrollbarAppearanceTest, NativeScrollbarChangeToMobileByEmulator) {
root_scrollable->VerticalScrollbar()->IsOverlayScrollbar());
EXPECT_FALSE(root_scrollable->VerticalScrollbar()->GetTheme().IsMockTheme());
- DCHECK(!viewport.LayerForHorizontalScrollbar()->Parent());
+ DCHECK(!viewport.LayerForHorizontalScrollbar());
EXPECT_TRUE(div_scrollable->VerticalScrollbar());
EXPECT_FALSE(div_scrollable->VerticalScrollbar()->IsCustomScrollbar());
@@ -1816,6 +1870,41 @@ TEST_F(ScrollbarsTest, AutosizeTest) {
}
}
+TEST_F(ScrollbarsTest, AutosizeAlmostRemovableScrollbar) {
+ ScopedOverlayScrollbarsForTest overlay_scrollbars(false);
+ WebView().EnableAutoResizeMode(WebSize(25, 25), WebSize(800, 600));
+
+ SimRequest resource("https://example.com/test.html", "text/html");
+ LoadURL("https://example.com/test.html");
+ resource.Complete(R"HTML(
+ <style>
+ body { margin: 0; padding: 15px }
+ #b1, #b2 { display: inline-block; width: 205px; height: 45px; }
+ #b1 { background: #888; }
+ #b2 { background: #bbb; }
+ #spacer { width: 400px; height: 490px; background: #eee; }
+ </style>
+ <div id="b1"></div><div id="b2"></div>
+ <div id="spacer"></div>
+ )HTML");
+
+ // Finish loading.
+ test::RunPendingTasks();
+
+ LocalFrameView* frame_view = WebView().MainFrameImpl()->GetFrameView();
+ ScrollableArea* layout_viewport = frame_view->LayoutViewport();
+
+ // Check three times to verify stability.
+ for (int i = 0; i < 3; i++) {
+ frame_view->SetNeedsLayout();
+ Compositor().BeginFrame();
+ EXPECT_TRUE(layout_viewport->VerticalScrollbar());
+ EXPECT_FALSE(layout_viewport->HorizontalScrollbar());
+ EXPECT_EQ(445, frame_view->Width());
+ EXPECT_EQ(600, frame_view->Height());
+ }
+}
+
TEST_F(ScrollbarsTest,
HideTheOverlayScrollbarNotCrashAfterPLSADisposedPaintLayer) {
WebView().Resize(WebSize(200, 200));
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 b940726a77b..45be4d014bc 100644
--- a/chromium/third_party/blink/renderer/core/layout/shapes/shape.h
+++ b/chromium/third_party/blink/renderer/core/layout/shapes/shape.h
@@ -44,6 +44,8 @@ class FloatRoundedRect;
struct LineSegment {
STACK_ALLOCATED();
+
+ public:
LineSegment() : logical_left(0), logical_right(0), is_valid(false) {}
LineSegment(float logical_left, float logical_right)
@@ -68,6 +70,8 @@ class CORE_EXPORT Shape {
public:
struct DisplayPaths {
STACK_ALLOCATED();
+
+ public:
Path shape;
Path margin_shape;
};
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 7c9f0ec90d2..f87c3ff3435 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
@@ -52,7 +52,7 @@ void ShapeOutsideInfo::SetReferenceBoxLogicalSize(
LayoutSize new_reference_box_logical_size) {
const Document& document = layout_box_.GetDocument();
bool is_horizontal_writing_mode =
- layout_box_.ContainingBlock()->Style()->IsHorizontalWritingMode();
+ layout_box_.ContainingBlock()->StyleRef().IsHorizontalWritingMode();
LayoutSize margin_box_for_use_counter = new_reference_box_logical_size;
if (is_horizontal_writing_mode) {
@@ -63,7 +63,7 @@ void ShapeOutsideInfo::SetReferenceBoxLogicalSize(
layout_box_.MarginWidth());
}
- switch (ReferenceBox(*layout_box_.Style()->ShapeOutside())) {
+ switch (ReferenceBox(*layout_box_.StyleRef().ShapeOutside())) {
case CSSBoxType::kMargin:
UseCounter::Count(document, WebFeature::kShapeOutsideMarginBox);
if (is_horizontal_writing_mode)
@@ -176,7 +176,7 @@ std::unique_ptr<Shape> ShapeOutsideInfo::CreateShapeForImage(
float margin) const {
DCHECK(!style_image->IsPendingImage());
const LayoutSize& image_size = RoundedLayoutSize(style_image->ImageSize(
- layout_box_.GetDocument(), layout_box_.Style()->EffectiveZoom(),
+ layout_box_.GetDocument(), layout_box_.StyleRef().EffectiveZoom(),
reference_box_logical_size_));
const LayoutRect& margin_rect =
@@ -216,7 +216,7 @@ const Shape& ShapeOutsideInfo::ComputedShape() const {
: std::max(LayoutUnit(), containing_block.ContentWidth());
float margin =
- FloatValueForLength(layout_box_.Style()->ShapeMargin(),
+ FloatValueForLength(layout_box_.StyleRef().ShapeMargin(),
percentage_resolution_inline_size.ToFloat());
float shape_image_threshold = style.ShapeImageThreshold();
@@ -285,7 +285,7 @@ inline LayoutUnit BorderAndPaddingBeforeInWritingMode(
}
LayoutUnit ShapeOutsideInfo::LogicalTopOffset() const {
- switch (ReferenceBox(*layout_box_.Style()->ShapeOutside())) {
+ switch (ReferenceBox(*layout_box_.StyleRef().ShapeOutside())) {
case CSSBoxType::kMargin:
return -layout_box_.MarginBefore(layout_box_.ContainingBlock()->Style());
case CSSBoxType::kBorder:
@@ -293,11 +293,11 @@ LayoutUnit ShapeOutsideInfo::LogicalTopOffset() const {
case CSSBoxType::kPadding:
return BorderBeforeInWritingMode(
layout_box_,
- layout_box_.ContainingBlock()->Style()->GetWritingMode());
+ layout_box_.ContainingBlock()->StyleRef().GetWritingMode());
case CSSBoxType::kContent:
return BorderAndPaddingBeforeInWritingMode(
layout_box_,
- layout_box_.ContainingBlock()->Style()->GetWritingMode());
+ layout_box_.ContainingBlock()->StyleRef().GetWritingMode());
case CSSBoxType::kMissing:
break;
}
@@ -337,7 +337,7 @@ inline LayoutUnit BorderAndPaddingStartWithStyleForWritingMode(
}
LayoutUnit ShapeOutsideInfo::LogicalLeftOffset() const {
- switch (ReferenceBox(*layout_box_.Style()->ShapeOutside())) {
+ switch (ReferenceBox(*layout_box_.StyleRef().ShapeOutside())) {
case CSSBoxType::kMargin:
return -layout_box_.MarginStart(layout_box_.ContainingBlock()->Style());
case CSSBoxType::kBorder:
@@ -357,7 +357,7 @@ LayoutUnit ShapeOutsideInfo::LogicalLeftOffset() const {
}
bool ShapeOutsideInfo::IsEnabledFor(const LayoutBox& box) {
- ShapeValue* shape_value = box.Style()->ShapeOutside();
+ ShapeValue* shape_value = box.StyleRef().ShapeOutside();
if (!box.IsFloating() || !shape_value)
return false;
@@ -401,7 +401,7 @@ ShapeOutsideDeltas ShapeOutsideInfo::ComputeDeltasForContainingBlockLine(
std::min(line_height, ShapeLogicalBottom() - border_box_line_top));
if (segment.is_valid) {
LayoutUnit logical_left_margin =
- containing_block.Style()->IsLeftToRightDirection()
+ containing_block.StyleRef().IsLeftToRightDirection()
? containing_block.MarginStartForChild(layout_box_)
: containing_block.MarginEndForChild(layout_box_);
LayoutUnit raw_left_margin_box_delta =
@@ -410,7 +410,7 @@ ShapeOutsideDeltas ShapeOutsideInfo::ComputeDeltasForContainingBlockLine(
raw_left_margin_box_delta, LayoutUnit(), float_margin_box_width);
LayoutUnit logical_right_margin =
- containing_block.Style()->IsLeftToRightDirection()
+ containing_block.StyleRef().IsLeftToRightDirection()
? containing_block.MarginEndForChild(layout_box_)
: containing_block.MarginStartForChild(layout_box_);
LayoutUnit raw_right_margin_box_delta =
@@ -443,13 +443,13 @@ LayoutRect ShapeOutsideInfo::ComputedShapePhysicalBoundingBox() const {
ComputedShape().ShapeMarginLogicalBoundingBox();
physical_bounding_box.SetX(physical_bounding_box.X() + LogicalLeftOffset());
- if (layout_box_.Style()->IsFlippedBlocksWritingMode())
+ if (layout_box_.StyleRef().IsFlippedBlocksWritingMode())
physical_bounding_box.SetY(layout_box_.LogicalHeight() -
physical_bounding_box.MaxY());
else
physical_bounding_box.SetY(physical_bounding_box.Y() + LogicalTopOffset());
- if (!layout_box_.Style()->IsHorizontalWritingMode())
+ if (!layout_box_.StyleRef().IsHorizontalWritingMode())
physical_bounding_box = physical_bounding_box.TransposedRect();
else
physical_bounding_box.SetY(physical_bounding_box.Y() + LogicalTopOffset());
@@ -460,15 +460,15 @@ LayoutRect ShapeOutsideInfo::ComputedShapePhysicalBoundingBox() const {
FloatPoint ShapeOutsideInfo::ShapeToLayoutObjectPoint(FloatPoint point) const {
FloatPoint result = FloatPoint(point.X() + LogicalLeftOffset(),
point.Y() + LogicalTopOffset());
- if (layout_box_.Style()->IsFlippedBlocksWritingMode())
+ if (layout_box_.StyleRef().IsFlippedBlocksWritingMode())
result.SetY(layout_box_.LogicalHeight() - result.Y());
- if (!layout_box_.Style()->IsHorizontalWritingMode())
+ if (!layout_box_.StyleRef().IsHorizontalWritingMode())
result = result.TransposedPoint();
return result;
}
FloatSize ShapeOutsideInfo::ShapeToLayoutObjectSize(FloatSize size) const {
- if (!layout_box_.Style()->IsHorizontalWritingMode())
+ if (!layout_box_.StyleRef().IsHorizontalWritingMode())
return size.TransposedSize();
return size;
}
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_block.cc b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_block.cc
index df0f405f749..6f08582ad7a 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_block.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_block.cc
@@ -59,6 +59,11 @@ void LayoutSVGBlock::UpdateFromStyle() {
void LayoutSVGBlock::StyleDidChange(StyleDifference diff,
const ComputedStyle* old_style) {
+ // Since layout depends on the bounds of the filter, we need to force layout
+ // when the filter changes.
+ if (diff.FilterChanged())
+ SetNeedsLayout(LayoutInvalidationReason::kStyleChange);
+
if (diff.NeedsFullLayout()) {
SetNeedsBoundariesUpdate();
if (diff.TransformChanged())
@@ -67,11 +72,12 @@ void LayoutSVGBlock::StyleDidChange(StyleDifference diff,
if (IsBlendingAllowed()) {
bool has_blend_mode_changed =
- (old_style && old_style->HasBlendMode()) == !Style()->HasBlendMode();
- if (Parent() && has_blend_mode_changed)
+ (old_style && old_style->HasBlendMode()) == !StyleRef().HasBlendMode();
+ if (Parent() && has_blend_mode_changed) {
Parent()->DescendantIsolationRequirementsChanged(
- Style()->HasBlendMode() ? kDescendantIsolationRequired
- : kDescendantIsolationNeedsUpdate);
+ StyleRef().HasBlendMode() ? kDescendantIsolationRequired
+ : kDescendantIsolationNeedsUpdate);
+ }
}
LayoutBlock::StyleDidChange(diff, old_style);
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 3dda0b8b574..ee9bba396a1 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
@@ -85,7 +85,7 @@ void LayoutSVGContainer::AddChild(LayoutObject* child,
SVGResourcesCache::ClientWasAddedToTree(*child, child->StyleRef());
bool should_isolate_descendants =
- (child->IsBlendingAllowed() && child->Style()->HasBlendMode()) ||
+ (child->IsBlendingAllowed() && child->StyleRef().HasBlendMode()) ||
child->HasNonIsolatedBlendingDescendants();
if (should_isolate_descendants)
DescendantIsolationRequirementsChanged(kDescendantIsolationRequired);
@@ -96,7 +96,7 @@ void LayoutSVGContainer::RemoveChild(LayoutObject* child) {
LayoutSVGModelObject::RemoveChild(child);
bool had_non_isolated_descendants =
- (child->IsBlendingAllowed() && child->Style()->HasBlendMode()) ||
+ (child->IsBlendingAllowed() && child->StyleRef().HasBlendMode()) ||
child->HasNonIsolatedBlendingDescendants();
if (had_non_isolated_descendants)
DescendantIsolationRequirementsChanged(kDescendantIsolationNeedsUpdate);
@@ -195,7 +195,7 @@ bool LayoutSVGContainer::NodeAtFloatPoint(HitTestResult& result,
// pointer-events: bounding-box makes it possible for containers to be direct
// targets.
- if (Style()->PointerEvents() == EPointerEvents::kBoundingBox) {
+ if (StyleRef().PointerEvents() == EPointerEvents::kBoundingBox) {
// Check for a valid bounding box because it will be invalid for empty
// containers.
if (IsObjectBoundingBoxValid() &&
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_ellipse.cc b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_ellipse.cc
index 10e0f3467e8..2b0bad97a45 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_ellipse.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_ellipse.cc
@@ -75,7 +75,7 @@ void LayoutSVGEllipse::UpdateShapeFromElement() {
fill_bounding_box_ = FloatRect(center_ - radii_, radii_.ScaledBy(2));
stroke_bounding_box_ = fill_bounding_box_;
- if (Style()->SvgStyle().HasStroke())
+ if (StyleRef().SvgStyle().HasStroke())
stroke_bounding_box_.Inflate(StrokeWidth() / 2);
}
@@ -131,7 +131,7 @@ bool LayoutSVGEllipse::ShapeDependentFillContains(
}
bool LayoutSVGEllipse::HasContinuousStroke() const {
- const SVGComputedStyle& svg_style = Style()->SvgStyle();
+ const SVGComputedStyle& svg_style = StyleRef().SvgStyle();
return svg_style.StrokeDashArray()->IsEmpty();
}
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object.cc b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object.cc
index 3d21038a246..007629c67e9 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object.cc
@@ -180,6 +180,9 @@ void LayoutSVGForeignObject::StyleDidChange(StyleDifference diff,
SVGLayoutSupport::IsOverflowHidden(StyleRef()))) {
// See NeedsOverflowClip() in PaintPropertyTreeBuilder for the reason.
SetNeedsPaintPropertyUpdate();
+
+ if (Layer())
+ Layer()->SetNeedsCompositingInputsUpdate();
}
}
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 5ab1d05e39f..6c75a631ea8 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
@@ -127,6 +127,11 @@ void LayoutSVGInline::WillBeDestroyed() {
void LayoutSVGInline::StyleDidChange(StyleDifference diff,
const ComputedStyle* old_style) {
+ // Since layout depends on the bounds of the filter, we need to force layout
+ // when the filter changes.
+ if (diff.FilterChanged())
+ SetNeedsLayout(LayoutInvalidationReason::kStyleChange);
+
if (diff.NeedsFullLayout())
SetNeedsBoundariesUpdate();
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 6af58624b8e..d037cfab686 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
@@ -69,7 +69,7 @@ void LayoutSVGInlineText::StyleDidChange(StyleDifference diff,
UpdateScaledFont();
bool new_preserves =
- Style() ? Style()->WhiteSpace() == EWhiteSpace::kPre : false;
+ Style() ? StyleRef().WhiteSpace() == EWhiteSpace::kPre : false;
bool old_preserves =
old_style ? old_style->WhiteSpace() == EWhiteSpace::kPre : false;
if (old_preserves != new_preserves) {
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_model_object.cc b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_model_object.cc
index 4704f6dd071..1403b5e112d 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_model_object.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_model_object.cc
@@ -126,6 +126,15 @@ void LayoutSVGModelObject::AddLayerHitTestRects(
void LayoutSVGModelObject::StyleDidChange(StyleDifference diff,
const ComputedStyle* old_style) {
+ // Since layout depends on the bounds of the filter, we need to force layout
+ // when the filter changes. We also need to make sure paint will be
+ // performed, since if the filter changed we will not have cached result from
+ // before and thus will not flag paint in ClientLayoutChanged.
+ if (diff.FilterChanged()) {
+ SetNeedsLayoutAndFullPaintInvalidation(
+ LayoutInvalidationReason::kStyleChange);
+ }
+
if (diff.NeedsFullLayout()) {
SetNeedsBoundariesUpdate();
if (diff.TransformChanged())
@@ -134,11 +143,12 @@ void LayoutSVGModelObject::StyleDidChange(StyleDifference diff,
if (IsBlendingAllowed()) {
bool has_blend_mode_changed =
- (old_style && old_style->HasBlendMode()) == !Style()->HasBlendMode();
- if (Parent() && has_blend_mode_changed)
+ (old_style && old_style->HasBlendMode()) == !StyleRef().HasBlendMode();
+ if (Parent() && has_blend_mode_changed) {
Parent()->DescendantIsolationRequirementsChanged(
- Style()->HasBlendMode() ? kDescendantIsolationRequired
- : kDescendantIsolationNeedsUpdate);
+ StyleRef().HasBlendMode() ? kDescendantIsolationRequired
+ : kDescendantIsolationNeedsUpdate);
+ }
if (has_blend_mode_changed)
SetNeedsPaintPropertyUpdate();
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_rect.cc b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_rect.cc
index 81ab1129b3b..aa88e855883 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_rect.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_rect.cc
@@ -117,7 +117,7 @@ bool LayoutSVGRect::ShapeDependentFillContains(const FloatPoint& point,
// Returns true if the stroke is continuous and definitely uses miter joins.
bool LayoutSVGRect::DefinitelyHasSimpleStroke() const {
- const SVGComputedStyle& svg_style = Style()->SvgStyle();
+ const SVGComputedStyle& svg_style = StyleRef().SvgStyle();
// The four angles of a rect are 90 degrees. Using the formula at:
// http://www.w3.org/TR/SVG/painting.html#StrokeMiterlimitProperty
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 c1d14a5c912..ba9064af86d 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
@@ -115,7 +115,7 @@ void LayoutSVGResourceContainer::MarkClientForInvalidation(
// if the client is one that could have a LayoutSVGInlineText use a
// paint invalidation reason that will force paint invalidation of the
// entire <text>/<tspan>/... subtree.
- client.SetShouldDoFullPaintInvalidation(
+ client.SetSubtreeShouldDoFullPaintInvalidation(
PaintInvalidationReason::kSVGResource);
client.InvalidateClipPathCache();
// Invalidate paint properties to update effects if any.
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 9e256694a52..659ee171c0f 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
@@ -127,7 +127,6 @@ bool LayoutSVGResourceMarker::ShouldPaint() const {
}
void LayoutSVGResourceMarker::SetNeedsTransformUpdate() {
- SetMayNeedPaintInvalidationSubtree();
// The transform paint property relies on the SVG transform being up-to-date
// (see: PaintPropertyTreeBuilder::updateTransformForNonRootSVG).
SetNeedsPaintPropertyUpdate();
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 3aa0518cc3a..bb916b86313 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
@@ -66,7 +66,7 @@ sk_sp<const PaintRecord> LayoutSVGResourceMasker::CreatePaintRecord(
PaintRecordBuilder builder(nullptr, &context);
ColorFilter mask_content_filter =
- Style()->SvgStyle().ColorInterpolation() == CI_LINEARRGB
+ StyleRef().SvgStyle().ColorInterpolation() == CI_LINEARRGB
? kColorFilterSRGBToLinearRGB
: kColorFilterNone;
builder.Context().SetColorFilter(mask_content_filter);
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 9f096f3d2a4..e0a7f6de546 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
@@ -74,6 +74,8 @@ class SVGPaintServer {
// is set to a fallback color.
struct SVGPaintDescription {
STACK_ALLOCATED();
+
+ public:
SVGPaintDescription()
: resource(nullptr), is_valid(false), has_fallback(false) {}
SVGPaintDescription(Color color)
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 a7b509a274d..49519a416ee 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
@@ -147,7 +147,7 @@ LayoutUnit LayoutSVGRoot::ComputeReplacedLogicalHeight(
return ContainingBlock()->AvailableLogicalHeight(
kIncludeMarginBorderPadding);
- const Length& logical_height = Style()->LogicalHeight();
+ const Length& logical_height = StyleRef().LogicalHeight();
if (IsDocumentElement() && logical_height.IsPercentOrCalc()) {
return ValueForLength(
logical_height,
@@ -196,8 +196,11 @@ void LayoutSVGRoot::UpdateLayout() {
// mark the entire subtree as needing paint invalidation checking.
if (transform_change != SVGTransformChange::kNone ||
viewport_may_have_changed) {
- SetMayNeedPaintInvalidationSubtree();
+ SetSubtreeShouldCheckForPaintInvalidation();
SetNeedsPaintPropertyUpdate();
+
+ if (Layer())
+ Layer()->SetNeedsCompositingInputsUpdate();
}
SVGSVGElement* svg = ToSVGSVGElement(GetNode());
@@ -230,7 +233,6 @@ void LayoutSVGRoot::UpdateLayout() {
has_box_decoration_background_ = IsDocumentElement()
? StyleRef().HasBoxDecorationBackground()
: HasBoxDecorationBackground();
- InvalidateBackgroundObscurationStatus();
ClearNeedsLayout();
}
@@ -240,9 +242,9 @@ bool LayoutSVGRoot::ShouldApplyViewportClip() const {
// clipped. When the svg is stand-alone (isDocumentElement() == true) the
// viewport clipping should always be applied, noting that the window
// scrollbars should be hidden if overflow=hidden.
- return Style()->OverflowX() == EOverflow::kHidden ||
- Style()->OverflowX() == EOverflow::kAuto ||
- Style()->OverflowX() == EOverflow::kScroll || IsDocumentElement();
+ return StyleRef().OverflowX() == EOverflow::kHidden ||
+ StyleRef().OverflowX() == EOverflow::kAuto ||
+ StyleRef().OverflowX() == EOverflow::kScroll || IsDocumentElement();
}
LayoutRect LayoutSVGRoot::VisualOverflowRect() const {
@@ -324,7 +326,7 @@ void LayoutSVGRoot::AddChild(LayoutObject* child, LayoutObject* before_child) {
SVGResourcesCache::ClientWasAddedToTree(*child, child->StyleRef());
bool should_isolate_descendants =
- (child->IsBlendingAllowed() && child->Style()->HasBlendMode()) ||
+ (child->IsBlendingAllowed() && child->StyleRef().HasBlendMode()) ||
child->HasNonIsolatedBlendingDescendants();
if (should_isolate_descendants)
DescendantIsolationRequirementsChanged(kDescendantIsolationRequired);
@@ -335,7 +337,7 @@ void LayoutSVGRoot::RemoveChild(LayoutObject* child) {
LayoutReplaced::RemoveChild(child);
bool had_non_isolated_descendants =
- (child->IsBlendingAllowed() && child->Style()->HasBlendMode()) ||
+ (child->IsBlendingAllowed() && child->StyleRef().HasBlendMode()) ||
child->HasNonIsolatedBlendingDescendants();
if (had_non_isolated_descendants)
DescendantIsolationRequirementsChanged(kDescendantIsolationNeedsUpdate);
@@ -362,6 +364,8 @@ void LayoutSVGRoot::DescendantIsolationRequirementsChanged(
break;
}
SetNeedsPaintPropertyUpdate();
+ if (Layer())
+ Layer()->SetNeedsCompositingInputsUpdate();
}
void LayoutSVGRoot::InsertedIntoTree() {
@@ -407,7 +411,7 @@ SVGTransformChange LayoutSVGRoot::BuildLocalToBorderBoxTransform() {
SVGTransformChangeDetector change_detector(local_to_border_box_transform_);
SVGSVGElement* svg = ToSVGSVGElement(GetNode());
DCHECK(svg);
- float scale = Style()->EffectiveZoom();
+ float scale = StyleRef().EffectiveZoom();
local_to_border_box_transform_ = svg->ViewBoxToViewTransform(
ContentWidth() / scale, ContentHeight() / scale);
@@ -515,7 +519,7 @@ bool LayoutSVGRoot::NodeAtPoint(HitTestResult& result,
// supported by nodeAtFloatPoint.
bool skip_children = (result.GetHitTestRequest().GetStopNode() == this);
if (!skip_children &&
- (ContentBoxRect().Contains(point_in_border_box) ||
+ (PhysicalContentBoxRect().Contains(point_in_border_box) ||
(!ShouldApplyViewportClip() &&
VisualOverflowRect().Contains(point_in_border_box)))) {
const AffineTransform& local_to_parent_transform =
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 452e6ad9342..69fd4258f7d 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
@@ -139,7 +139,7 @@ FloatRect LayoutSVGShape::ApproximateStrokeBoundingBox(
}
FloatRect LayoutSVGShape::HitTestStrokeBoundingBox() const {
- if (Style()->SvgStyle().HasStroke())
+ if (StyleRef().SvgStyle().HasStroke())
return stroke_bounding_box_;
// Implementation of
@@ -360,7 +360,7 @@ bool LayoutSVGShape::NodeAtFloatPoint(HitTestResult& result,
PointerEventsHitRules hit_rules(
PointerEventsHitRules::SVG_GEOMETRY_HITTESTING,
- result.GetHitTestRequest(), Style()->PointerEvents());
+ result.GetHitTestRequest(), StyleRef().PointerEvents());
if (NodeAtFloatPointInternal(result.GetHitTestRequest(), local_point,
hit_rules)) {
const LayoutPoint& local_layout_point = LayoutPoint(local_point);
@@ -406,7 +406,7 @@ FloatRect LayoutSVGShape::CalculateStrokeBoundingBox() const {
DCHECK(path_);
FloatRect stroke_bounding_box = fill_bounding_box_;
- if (Style()->SvgStyle().HasStroke()) {
+ if (StyleRef().SvgStyle().HasStroke()) {
StrokeData stroke_data;
SVGLayoutSupport::ApplyStrokeStyleToStrokeData(stroke_data, StyleRef(),
*this, DashScaleFactor());
@@ -430,7 +430,7 @@ FloatRect LayoutSVGShape::CalculateStrokeBoundingBox() const {
float LayoutSVGShape::StrokeWidth() const {
SVGLengthContext length_context(GetElement());
- return length_context.ValueForLength(Style()->SvgStyle().StrokeWidth());
+ return length_context.ValueForLength(StyleRef().SvgStyle().StrokeWidth());
}
LayoutSVGShapeRareData& LayoutSVGShape::EnsureRareData() const {
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 0daeb6bdae9..c291ae4913d 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
@@ -86,7 +86,7 @@ class LayoutSVGShape : public LayoutSVGModelObject {
}
bool HasNonScalingStroke() const {
- return Style()->SvgStyle().VectorEffect() == VE_NON_SCALING_STROKE;
+ return StyleRef().SvgStyle().VectorEffect() == VE_NON_SCALING_STROKE;
}
const Path& NonScalingStrokePath() const {
DCHECK(HasNonScalingStroke());
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 a27aece4d05..0d720fe7b75 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
@@ -378,7 +378,7 @@ FloatRect LayoutSVGText::ObjectBoundingBox() const {
FloatRect LayoutSVGText::StrokeBoundingBox() const {
FloatRect stroke_boundaries = ObjectBoundingBox();
- const SVGComputedStyle& svg_style = Style()->SvgStyle();
+ const SVGComputedStyle& svg_style = StyleRef().SvgStyle();
if (!svg_style.HasStroke())
return stroke_boundaries;
@@ -393,7 +393,7 @@ FloatRect LayoutSVGText::VisualRectInLocalSVGCoordinates() const {
FloatRect visual_rect = StrokeBoundingBox();
SVGLayoutSupport::AdjustVisualRectWithResources(*this, visual_rect);
- if (const ShadowList* text_shadow = Style()->TextShadow())
+ if (const ShadowList* text_shadow = StyleRef().TextShadow())
text_shadow->AdjustRectForShadow(visual_rect);
return visual_rect;
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_transformable_container.cc b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_transformable_container.cc
index 5ed2cc592ee..9859027a6fa 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_transformable_container.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_transformable_container.cc
@@ -68,7 +68,6 @@ bool LayoutSVGTransformableContainer::IsChildAllowed(
}
void LayoutSVGTransformableContainer::SetNeedsTransformUpdate() {
- SetMayNeedPaintInvalidationSubtree();
// The transform paint property relies on the SVG transform being up-to-date
// (see: PaintPropertyTreeBuilder::updateTransformForNonRootSVG).
SetNeedsPaintPropertyUpdate();
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_viewport_container.cc b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_viewport_container.cc
index d86c420e289..e03a672ef51 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_viewport_container.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_viewport_container.cc
@@ -56,7 +56,6 @@ void LayoutSVGViewportContainer::UpdateLayout() {
}
void LayoutSVGViewportContainer::SetNeedsTransformUpdate() {
- SetMayNeedPaintInvalidationSubtree();
// The transform paint property relies on the SVG transform being up-to-date
// (see: PaintPropertyTreeBuilder::updateTransformForNonRootSVG).
SetNeedsPaintPropertyUpdate();
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 dbc43c74fee..8737a84c713 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
@@ -216,7 +216,7 @@ bool SVGLayoutSupport::ComputeHasNonIsolatedBlendingDescendants(
const LayoutObjectType* object) {
for (LayoutObject* child = object->FirstChild(); child;
child = child->NextSibling()) {
- if (child->IsBlendingAllowed() && child->Style()->HasBlendMode())
+ if (child->IsBlendingAllowed() && child->StyleRef().HasBlendMode())
return true;
if (child->HasNonIsolatedBlendingDescendants() &&
!WillIsolateBlendingDescendantsForObject(child))
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 3510f53ef7b..2cd2bea2ed9 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
@@ -455,7 +455,7 @@ static inline void WriteSVGInlineTextBox(WTF::TextStream& ts,
LineLayoutSVGInlineText text_line_layout =
LineLayoutSVGInlineText(text_box->GetLineLayoutItem());
- const SVGComputedStyle& svg_style = text_line_layout.Style()->SvgStyle();
+ const SVGComputedStyle& svg_style = text_line_layout.StyleRef().SvgStyle();
String text = text_box->GetLineLayoutItem().GetText();
unsigned fragments_size = fragments.size();
@@ -471,7 +471,7 @@ static inline void WriteSVGInlineTextBox(WTF::TextStream& ts,
ts << "chunk 1 ";
ETextAnchor anchor = svg_style.TextAnchor();
bool is_vertical_text =
- !text_line_layout.Style()->IsHorizontalWritingMode();
+ !text_line_layout.StyleRef().IsHorizontalWritingMode();
if (anchor == TA_MIDDLE) {
ts << "(middle anchor";
if (is_vertical_text)
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 32f59f64a7f..d68462cd375 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
@@ -56,8 +56,8 @@ class SVGMarkerData {
}
void PathIsDone() {
- positions_.push_back(
- MarkerPosition(kEndMarker, origin_, CurrentAngle(kEndMarker)));
+ float angle = clampTo<float>(CurrentAngle(kEndMarker));
+ positions_.push_back(MarkerPosition(kEndMarker, origin_, angle));
}
static inline LayoutSVGResourceMarker* MarkerForType(
@@ -79,97 +79,119 @@ class SVGMarkerData {
}
private:
- float CurrentAngle(SVGMarkerType type) const {
+ static double BisectingAngle(double in_angle, double out_angle) {
+ // WK193015: Prevent bugs due to angles being non-continuous.
+ if (fabs(in_angle - out_angle) > 180)
+ in_angle += 360;
+ return (in_angle + out_angle) / 2;
+ }
+
+ double CurrentAngle(SVGMarkerType type) const {
// For details of this calculation, see:
// http://www.w3.org/TR/SVG/single-page.html#painting-MarkerElement
- FloatPoint in_slope(inslope_points_[1] - inslope_points_[0]);
- FloatPoint out_slope(outslope_points_[1] - outslope_points_[0]);
-
- double in_angle = rad2deg(in_slope.SlopeAngleRadians());
- double out_angle = rad2deg(out_slope.SlopeAngleRadians());
+ double in_angle = rad2deg(FloatPoint(in_slope_).SlopeAngleRadians());
+ double out_angle = rad2deg(FloatPoint(out_slope_).SlopeAngleRadians());
switch (type) {
case kStartMarker:
if (auto_start_reverse_)
out_angle += 180;
- return clampTo<float>(out_angle);
+ return out_angle;
case kMidMarker:
- // WK193015: Prevent bugs due to angles being non-continuous.
- if (fabs(in_angle - out_angle) > 180)
- in_angle += 360;
- return clampTo<float>((in_angle + out_angle) / 2);
+ return BisectingAngle(in_angle, out_angle);
case kEndMarker:
- return clampTo<float>(in_angle);
+ return in_angle;
}
NOTREACHED();
return 0;
}
- void UpdateOutslope(const PathElement& element) {
- outslope_points_[0] = origin_;
- FloatPoint point = element.type == kPathElementCloseSubpath
- ? subpath_start_
- : element.points[0];
- outslope_points_[1] = point;
+ struct SegmentData {
+ FloatSize start_tangent; // Tangent in the start point of the segment.
+ FloatSize end_tangent; // Tangent in the end point of the segment.
+ FloatPoint position; // The end point of the segment.
+ };
+
+ static void ComputeQuadTangents(SegmentData& data,
+ const FloatPoint& start,
+ const FloatPoint& control,
+ const FloatPoint& end) {
+ data.start_tangent = control - start;
+ data.end_tangent = end - control;
+ if (data.start_tangent.IsZero())
+ data.start_tangent = data.end_tangent;
+ else if (data.end_tangent.IsZero())
+ data.end_tangent = data.start_tangent;
}
- void UpdateFromPathElement(const PathElement& element) {
- // First update the outslope for the previous element.
- UpdateOutslope(element);
-
- // Record the marker for the previous element.
- if (element_index_ > 0) {
- SVGMarkerType marker_type =
- element_index_ == 1 ? kStartMarker : kMidMarker;
- positions_.push_back(
- MarkerPosition(marker_type, origin_, CurrentAngle(marker_type)));
- }
-
- // Update our marker data for this element.
- UpdateMarkerDataForPathElement(element);
- ++element_index_;
- }
-
- void UpdateMarkerDataForPathElement(const PathElement& element) {
+ SegmentData ExtractPathElementFeatures(const PathElement& element) const {
+ SegmentData data;
const FloatPoint* points = element.points;
-
switch (element.type) {
- case kPathElementAddQuadCurveToPoint:
- inslope_points_[0] = points[0];
- inslope_points_[1] = points[1];
- origin_ = points[1];
- break;
case kPathElementAddCurveToPoint:
- inslope_points_[0] = points[1];
- inslope_points_[1] = points[2];
- origin_ = points[2];
+ data.position = points[2];
+ data.start_tangent = points[0] - origin_;
+ data.end_tangent = points[2] - points[1];
+ if (data.start_tangent.IsZero())
+ ComputeQuadTangents(data, points[0], points[1], points[2]);
+ else if (data.end_tangent.IsZero())
+ ComputeQuadTangents(data, origin_, points[0], points[1]);
+ break;
+ case kPathElementAddQuadCurveToPoint:
+ data.position = points[1];
+ ComputeQuadTangents(data, origin_, points[0], points[1]);
break;
case kPathElementMoveToPoint:
- subpath_start_ = points[0];
- FALLTHROUGH;
case kPathElementAddLineToPoint:
- UpdateInslope(points[0]);
- origin_ = points[0];
+ data.position = points[0];
+ data.start_tangent = data.position - origin_;
+ data.end_tangent = data.position - origin_;
break;
case kPathElementCloseSubpath:
- UpdateInslope(subpath_start_);
- origin_ = subpath_start_;
- subpath_start_ = FloatPoint();
+ data.position = subpath_start_;
+ data.start_tangent = data.position - origin_;
+ data.end_tangent = data.position - origin_;
+ break;
}
+ return data;
}
- void UpdateInslope(const FloatPoint& point) {
- inslope_points_[0] = origin_;
- inslope_points_[1] = point;
+ void UpdateFromPathElement(const PathElement& element) {
+ SegmentData segment_data = ExtractPathElementFeatures(element);
+
+ // First update the outgoing slope for the previous element.
+ out_slope_ = segment_data.start_tangent;
+
+ // Record the marker for the previous element.
+ if (element_index_ > 0) {
+ SVGMarkerType marker_type =
+ element_index_ == 1 ? kStartMarker : kMidMarker;
+ float angle = clampTo<float>(CurrentAngle(marker_type));
+ positions_.push_back(MarkerPosition(marker_type, origin_, angle));
+ }
+
+ // Update the incoming slope for this marker position.
+ in_slope_ = segment_data.end_tangent;
+
+ // Update marker position.
+ origin_ = segment_data.position;
+
+ // If this is a 'move to' segment, save the point for use with 'close'.
+ if (element.type == kPathElementMoveToPoint)
+ subpath_start_ = element.points[0];
+ else if (element.type == kPathElementCloseSubpath)
+ subpath_start_ = FloatPoint();
+
+ ++element_index_;
}
Vector<MarkerPosition>& positions_;
unsigned element_index_;
FloatPoint origin_;
FloatPoint subpath_start_;
- FloatPoint inslope_points_[2];
- FloatPoint outslope_points_[2];
+ FloatSize in_slope_;
+ FloatSize out_slope_;
bool auto_start_reverse_;
};
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/svg_text_layout_engine_baseline.cc b/chromium/third_party/blink/renderer/core/layout/svg/svg_text_layout_engine_baseline.cc
index bbf32ba3305..c7824b10958 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/svg_text_layout_engine_baseline.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/svg_text_layout_engine_baseline.cc
@@ -62,7 +62,7 @@ SVGTextLayoutEngineBaseline::DominantBaselineToAlignmentBaseline(
DCHECK(text_line_layout);
DCHECK(text_line_layout.Style());
- const SVGComputedStyle& style = text_line_layout.Style()->SvgStyle();
+ const SVGComputedStyle& style = text_line_layout.StyleRef().SvgStyle();
EDominantBaseline baseline = style.DominantBaseline();
if (baseline == DB_AUTO) {
@@ -119,7 +119,7 @@ float SVGTextLayoutEngineBaseline::CalculateAlignmentBaselineShift(
DCHECK(text_line_layout_parent);
EAlignmentBaseline baseline =
- text_line_layout.Style()->SvgStyle().AlignmentBaseline();
+ text_line_layout.StyleRef().SvgStyle().AlignmentBaseline();
if (baseline == AB_AUTO || baseline == AB_BASELINE) {
baseline = DominantBaselineToAlignmentBaseline(is_vertical_text,
text_line_layout_parent);
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 b062998cd71..236be0fde74 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
@@ -108,7 +108,7 @@ static bool QueryTextBox(QueryData* query_data,
LineLayoutSVGInlineText(text_box->GetLineLayoutItem());
query_data->is_vertical_text =
- !query_data->text_line_layout.Style()->IsHorizontalWritingMode();
+ !query_data->text_line_layout.StyleRef().IsHorizontalWritingMode();
// Loop over all text fragments in this text box, firing a callback for each.
for (const SVGTextFragment& fragment : text_box->TextFragments()) {
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 1a8efd8a9d2..7110087f99b 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
@@ -170,9 +170,9 @@ void TableLayoutAlgorithmAuto::FullRecalc() {
for (LayoutTableCol* column = table_->FirstColumn(); column;
column = column->NextColumn()) {
if (column->IsTableColumnGroupWithColumnChildren()) {
- group_logical_width = column->Style()->LogicalWidth();
+ group_logical_width = column->StyleRef().LogicalWidth();
} else {
- Length col_logical_width = column->Style()->LogicalWidth();
+ Length col_logical_width = column->StyleRef().LogicalWidth();
// FIXME: calc() on tables should be handled consistently with other
// lengths. See bug: https://crbug.com/382725
if (col_logical_width.IsCalculated() || col_logical_width.IsAuto())
@@ -242,19 +242,19 @@ static bool ShouldScaleColumnsForSelf(LayoutTable* table) {
// A special case. If this table is not fixed width and contained inside
// a cell, then don't bloat the maxwidth by examining percentage growth.
while (true) {
- Length tw = table->Style()->Width();
+ Length tw = table->StyleRef().Width();
if ((!tw.IsAuto() && !tw.IsPercentOrCalc()) ||
table->IsOutOfFlowPositioned())
return true;
LayoutBlock* cb = table->ContainingBlock();
while (!cb->IsLayoutView() && !cb->IsTableCell() &&
- cb->Style()->Width().IsAuto() && !cb->IsOutOfFlowPositioned())
+ cb->StyleRef().Width().IsAuto() && !cb->IsOutOfFlowPositioned())
cb = cb->ContainingBlock();
// TODO(dgrogan): Should the second clause check for isFixed() instead?
- if (!cb->IsTableCell() || (!cb->Style()->Width().IsAuto() &&
- !cb->Style()->Width().IsPercentOrCalc()))
+ if (!cb->IsTableCell() || (!cb->StyleRef().Width().IsAuto() &&
+ !cb->StyleRef().Width().IsPercentOrCalc()))
return true;
LayoutTableCell* cell = ToLayoutTableCell(cb);
@@ -328,7 +328,7 @@ void TableLayoutAlgorithmAuto::ComputeIntrinsicLogicalWidths(
void TableLayoutAlgorithmAuto::ApplyPreferredLogicalWidthQuirks(
LayoutUnit& min_width,
LayoutUnit& max_width) const {
- Length table_logical_width = table_->Style()->LogicalWidth();
+ Length table_logical_width = table_->StyleRef().LogicalWidth();
if (table_logical_width.IsFixed() && table_logical_width.IsPositive()) {
// |minWidth| is the result of measuring the intrinsic content's size. Keep
// it to make sure we are *never* smaller than the actual content.
@@ -339,7 +339,8 @@ void TableLayoutAlgorithmAuto::ApplyPreferredLogicalWidthQuirks(
min_width = max_width = LayoutUnit(
std::max<int>(min_width.Floor(), table_logical_width.Value()));
- const Length& style_max_logical_width = table_->Style()->LogicalMaxWidth();
+ const Length& style_max_logical_width =
+ table_->StyleRef().LogicalMaxWidth();
if (style_max_logical_width.IsFixed() &&
!style_max_logical_width.IsNegative()) {
min_width = LayoutUnit(
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 7057cd8b8ec..66cba73d13a 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
@@ -98,7 +98,7 @@ int TableLayoutAlgorithmFixed::CalcWidthArray() {
if (col->IsTableColumnGroupWithColumnChildren())
continue;
- Length col_style_logical_width = col->Style()->LogicalWidth();
+ Length col_style_logical_width = col->StyleRef().LogicalWidth();
int effective_col_width = 0;
if (col_style_logical_width.IsFixed() &&
col_style_logical_width.Value() > 0)
@@ -196,7 +196,7 @@ void TableLayoutAlgorithmFixed::ComputeIntrinsicLogicalWidths(
void TableLayoutAlgorithmFixed::ApplyPreferredLogicalWidthQuirks(
LayoutUnit& min_width,
LayoutUnit& max_width) const {
- Length table_logical_width = table_->Style()->LogicalWidth();
+ Length table_logical_width = table_->StyleRef().LogicalWidth();
if (table_logical_width.IsFixed() && table_logical_width.IsPositive()) {
min_width = max_width = LayoutUnit(
max(min_width,
@@ -218,7 +218,7 @@ void TableLayoutAlgorithmFixed::ApplyPreferredLogicalWidthQuirks(
// In this example, the two inner tables should be as large as the outer
// table. We can achieve this effect by making the maxwidth of fixed tables
// with percentage widths be infinite.
- if (table_->Style()->LogicalWidth().IsPercentOrCalc() &&
+ if (table_->StyleRef().LogicalWidth().IsPercentOrCalc() &&
max_width < kTableMaxWidth)
max_width = LayoutUnit(kTableMaxWidth);
}
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 e819f7b4442..5e8973d8121 100644
--- a/chromium/third_party/blink/renderer/core/layout/text_autosizer.cc
+++ b/chromium/third_party/blink/renderer/core/layout/text_autosizer.cc
@@ -101,7 +101,7 @@ static bool IsPotentialClusterRoot(const LayoutObject* layout_object) {
if (!layout_object->IsLayoutBlock())
return false;
if (layout_object->IsInline() &&
- !layout_object->Style()->IsDisplayReplacedType())
+ !layout_object->StyleRef().IsDisplayReplacedType())
return false;
if (layout_object->IsListItemIncludingNG())
return (layout_object->IsFloating() ||
@@ -120,9 +120,9 @@ static bool IsIndependentDescendant(const LayoutBlock* layout_object) {
layout_object->IsFlexibleBoxIncludingDeprecated() ||
(containing_block && containing_block->IsHorizontalWritingMode() !=
layout_object->IsHorizontalWritingMode()) ||
- layout_object->Style()->IsDisplayReplacedType() ||
+ layout_object->StyleRef().IsDisplayReplacedType() ||
layout_object->IsTextArea() ||
- layout_object->Style()->UserModify() != EUserModify::kReadOnly;
+ layout_object->StyleRef().UserModify() != EUserModify::kReadOnly;
}
static bool BlockIsRowOfLinks(const LayoutBlock* block) {
@@ -145,12 +145,12 @@ static bool BlockIsRowOfLinks(const LayoutBlock* block) {
if (!layout_object->IsInline() || layout_object->IsBR())
return false;
}
- if (layout_object->Style()->IsLink()) {
+ if (layout_object->StyleRef().IsLink()) {
link_count++;
if (matching_font_size < 0)
- matching_font_size = layout_object->Style()->SpecifiedFontSize();
+ matching_font_size = layout_object->StyleRef().SpecifiedFontSize();
else if (matching_font_size !=
- layout_object->Style()->SpecifiedFontSize())
+ layout_object->StyleRef().SpecifiedFontSize())
return false;
// Skip traversing descendants of the link.
@@ -211,7 +211,7 @@ static bool BlockSuppressesAutosizing(const LayoutBlock* block) {
// Don't autosize block-level text that can't wrap (as it's likely to
// expand sideways and break the page's layout).
- if (!block->Style()->AutoWrap())
+ if (!block->StyleRef().AutoWrap())
return true;
if (BlockHeightConstrained(block))
@@ -223,7 +223,7 @@ static bool BlockSuppressesAutosizing(const LayoutBlock* block) {
static bool HasExplicitWidth(const LayoutBlock* block) {
// FIXME: This heuristic may need to be expanded to other ways a block can be
// wider or narrower than its parent containing block.
- return block->Style() && block->Style()->Width().IsSpecified();
+ return block->Style() && block->StyleRef().Width().IsSpecified();
}
static LayoutObject* GetParent(const LayoutObject* object) {
@@ -354,14 +354,14 @@ void TextAutosizer::BeginLayout(LayoutBlock* block,
// Cells in auto-layout tables are handled separately by inflateAutoTable.
bool is_auto_table_cell =
block->IsTableCell() &&
- !ToLayoutTableCell(block)->Table()->Style()->IsFixedTableLayout();
+ !ToLayoutTableCell(block)->Table()->StyleRef().IsFixedTableLayout();
if (!is_auto_table_cell && !cluster_stack_.IsEmpty())
Inflate(block, layouter);
}
void TextAutosizer::InflateAutoTable(LayoutTable* table) {
DCHECK(table);
- DCHECK(!table->Style()->IsFixedTableLayout());
+ DCHECK(!table->StyleRef().IsFixedTableLayout());
DCHECK(table->ContainingBlock());
Cluster* cluster = CurrentCluster();
@@ -727,7 +727,7 @@ bool TextAutosizer::ClusterHasEnoughTextToAutosize(
// TextAreas and user-modifiable areas get a free pass to autosize regardless
// of text content.
- if (root->IsTextArea() || (root->Style() && root->Style()->UserModify() !=
+ if (root->IsTextArea() || (root->Style() && root->StyleRef().UserModify() !=
EUserModify::kReadOnly)) {
cluster->has_enough_text_to_autosize_ = kHasEnoughText;
return true;
@@ -763,7 +763,7 @@ bool TextAutosizer::ClusterHasEnoughTextToAutosize(
// layout. These values can be different.
// Note: This is an approximation assuming each character is 1em wide.
length += ToLayoutText(descendant)->GetText().StripWhiteSpace().length() *
- descendant->Style()->SpecifiedFontSize();
+ descendant->StyleRef().SpecifiedFontSize();
if (length >= minimum_text_length_to_autosize) {
cluster->has_enough_text_to_autosize_ = kHasEnoughText;
@@ -988,7 +988,7 @@ float TextAutosizer::WidthFromBlock(const LayoutBlock* block) const {
Length specified_width =
block->IsTableCell()
? ToLayoutTableCell(block)->StyleOrColLogicalWidth()
- : block->Style()->LogicalWidth();
+ : block->StyleRef().LogicalWidth();
if (specified_width.IsFixed()) {
if ((width = specified_width.Value()) > 0)
return width;
@@ -1386,12 +1386,13 @@ TextAutosizer::DeferUpdatePageInfo::~DeferUpdatePageInfo() {
}
}
-float TextAutosizer::ComputeAutosizedFontSize(float specified_size,
- float multiplier) {
+float TextAutosizer::ComputeAutosizedFontSize(float computed_size,
+ float multiplier,
+ float effective_zoom) {
DCHECK_GE(multiplier, 0);
// Somewhat arbitrary "pleasant" font size.
- const float kPleasantSize = 16;
+ const float kPleasantSize = 16 * effective_zoom;
// Multiply fonts that the page author has specified to be larger than
// pleasantSize by less and less, until huge fonts are not increased at all.
@@ -1405,19 +1406,19 @@ float TextAutosizer::ComputeAutosizedFontSize(float specified_size,
// then every 1px increase in specifiedSize increases computedSize by 1px).
const float kGradientAfterPleasantSize = 0.5;
- float computed_size;
+ float auto_sized_size;
// Skip linear backoff for multipliers that shrink the size or when the font
// sizes are small.
- if (multiplier <= 1 || specified_size <= kPleasantSize) {
- computed_size = multiplier * specified_size;
+ if (multiplier <= 1 || computed_size <= kPleasantSize) {
+ auto_sized_size = multiplier * computed_size;
} else {
- computed_size =
+ auto_sized_size =
multiplier * kPleasantSize +
- kGradientAfterPleasantSize * (specified_size - kPleasantSize);
- if (computed_size < specified_size)
- computed_size = specified_size;
+ kGradientAfterPleasantSize * (computed_size - kPleasantSize);
+ if (auto_sized_size < computed_size)
+ auto_sized_size = computed_size;
}
- return computed_size;
+ return auto_sized_size;
}
void TextAutosizer::CheckSuperclusterConsistency() {
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 ad1deecc343..2940200d1bc 100644
--- a/chromium/third_party/blink/renderer/core/layout/text_autosizer.h
+++ b/chromium/third_party/blink/renderer/core/layout/text_autosizer.h
@@ -64,7 +64,11 @@ class CORE_EXPORT TextAutosizer final
static TextAutosizer* Create(const Document* document) {
return new TextAutosizer(document);
}
- static float ComputeAutosizedFontSize(float specified_size, float multiplier);
+
+ // computed_size should include zoom.
+ static float ComputeAutosizedFontSize(float computed_size,
+ float multiplier,
+ float effective_zoom);
void UpdatePageInfoInAllFrames();
void UpdatePageInfo();
@@ -212,6 +216,8 @@ class CORE_EXPORT TextAutosizer final
struct FingerprintSourceData {
STACK_ALLOCATED();
+
+ public:
FingerprintSourceData()
: parent_hash_(0),
qualified_name_hash_(0),
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 6bf81b4f8ef..fde0c2e10ff 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
@@ -78,11 +78,11 @@ TEST_F(TextAutosizerTest, SimpleParagraph) {
)HTML");
Element* autosized = GetDocument().getElementById("autosized");
EXPECT_FLOAT_EQ(16.f,
- autosized->GetLayoutObject()->Style()->SpecifiedFontSize());
+ autosized->GetLayoutObject()->StyleRef().SpecifiedFontSize());
// (specified font-size = 16px) * (viewport width = 800px) /
// (window width = 320px) = 40px.
EXPECT_FLOAT_EQ(40.f,
- autosized->GetLayoutObject()->Style()->ComputedFontSize());
+ autosized->GetLayoutObject()->StyleRef().ComputedFontSize());
}
TEST_F(TextAutosizerTest, TextSizeAdjustDisablesAutosizing) {
@@ -121,16 +121,16 @@ TEST_F(TextAutosizerTest, TextSizeAdjustDisablesAutosizing) {
)HTML");
LayoutObject* text_size_adjust_auto =
GetDocument().getElementById("textSizeAdjustAuto")->GetLayoutObject();
- EXPECT_FLOAT_EQ(16.f, text_size_adjust_auto->Style()->SpecifiedFontSize());
- EXPECT_FLOAT_EQ(40.f, text_size_adjust_auto->Style()->ComputedFontSize());
+ EXPECT_FLOAT_EQ(16.f, text_size_adjust_auto->StyleRef().SpecifiedFontSize());
+ EXPECT_FLOAT_EQ(40.f, text_size_adjust_auto->StyleRef().ComputedFontSize());
LayoutObject* text_size_adjust_none =
GetDocument().getElementById("textSizeAdjustNone")->GetLayoutObject();
- EXPECT_FLOAT_EQ(16.f, text_size_adjust_none->Style()->SpecifiedFontSize());
- EXPECT_FLOAT_EQ(16.f, text_size_adjust_none->Style()->ComputedFontSize());
+ EXPECT_FLOAT_EQ(16.f, text_size_adjust_none->StyleRef().SpecifiedFontSize());
+ EXPECT_FLOAT_EQ(16.f, text_size_adjust_none->StyleRef().ComputedFontSize());
LayoutObject* text_size_adjust100 =
GetDocument().getElementById("textSizeAdjust100")->GetLayoutObject();
- EXPECT_FLOAT_EQ(16.f, text_size_adjust100->Style()->SpecifiedFontSize());
- EXPECT_FLOAT_EQ(16.f, text_size_adjust100->Style()->ComputedFontSize());
+ EXPECT_FLOAT_EQ(16.f, text_size_adjust100->StyleRef().SpecifiedFontSize());
+ EXPECT_FLOAT_EQ(16.f, text_size_adjust100->StyleRef().ComputedFontSize());
}
TEST_F(TextAutosizerTest, ParagraphWithChangingTextSizeAdjustment) {
@@ -154,37 +154,37 @@ TEST_F(TextAutosizerTest, ParagraphWithChangingTextSizeAdjustment) {
)HTML");
Element* autosized_div = GetDocument().getElementById("autosized");
EXPECT_FLOAT_EQ(
- 16.f, autosized_div->GetLayoutObject()->Style()->SpecifiedFontSize());
+ 16.f, autosized_div->GetLayoutObject()->StyleRef().SpecifiedFontSize());
EXPECT_FLOAT_EQ(
- 40.f, autosized_div->GetLayoutObject()->Style()->ComputedFontSize());
+ 40.f, autosized_div->GetLayoutObject()->StyleRef().ComputedFontSize());
autosized_div->setAttribute(HTMLNames::classAttr, "none");
GetDocument().View()->UpdateAllLifecyclePhases();
EXPECT_FLOAT_EQ(
- 16.f, autosized_div->GetLayoutObject()->Style()->SpecifiedFontSize());
+ 16.f, autosized_div->GetLayoutObject()->StyleRef().SpecifiedFontSize());
EXPECT_FLOAT_EQ(
- 16.f, autosized_div->GetLayoutObject()->Style()->ComputedFontSize());
+ 16.f, autosized_div->GetLayoutObject()->StyleRef().ComputedFontSize());
autosized_div->setAttribute(HTMLNames::classAttr, "small");
GetDocument().View()->UpdateAllLifecyclePhases();
EXPECT_FLOAT_EQ(
- 16.f, autosized_div->GetLayoutObject()->Style()->SpecifiedFontSize());
+ 16.f, autosized_div->GetLayoutObject()->StyleRef().SpecifiedFontSize());
EXPECT_FLOAT_EQ(
- 8.f, autosized_div->GetLayoutObject()->Style()->ComputedFontSize());
+ 8.f, autosized_div->GetLayoutObject()->StyleRef().ComputedFontSize());
autosized_div->setAttribute(HTMLNames::classAttr, "large");
GetDocument().View()->UpdateAllLifecyclePhases();
EXPECT_FLOAT_EQ(
- 16.f, autosized_div->GetLayoutObject()->Style()->SpecifiedFontSize());
+ 16.f, autosized_div->GetLayoutObject()->StyleRef().SpecifiedFontSize());
EXPECT_FLOAT_EQ(
- 24.f, autosized_div->GetLayoutObject()->Style()->ComputedFontSize());
+ 24.f, autosized_div->GetLayoutObject()->StyleRef().ComputedFontSize());
autosized_div->removeAttribute(HTMLNames::classAttr);
GetDocument().View()->UpdateAllLifecyclePhases();
EXPECT_FLOAT_EQ(
- 16.f, autosized_div->GetLayoutObject()->Style()->SpecifiedFontSize());
+ 16.f, autosized_div->GetLayoutObject()->StyleRef().SpecifiedFontSize());
EXPECT_FLOAT_EQ(
- 40.f, autosized_div->GetLayoutObject()->Style()->ComputedFontSize());
+ 40.f, autosized_div->GetLayoutObject()->StyleRef().ComputedFontSize());
}
TEST_F(TextAutosizerTest, ZeroTextSizeAdjustment) {
@@ -205,8 +205,8 @@ TEST_F(TextAutosizerTest, ZeroTextSizeAdjustment) {
)HTML");
LayoutObject* text_size_adjust_zero =
GetDocument().getElementById("textSizeAdjustZero")->GetLayoutObject();
- EXPECT_FLOAT_EQ(16.f, text_size_adjust_zero->Style()->SpecifiedFontSize());
- EXPECT_FLOAT_EQ(0.f, text_size_adjust_zero->Style()->ComputedFontSize());
+ EXPECT_FLOAT_EQ(16.f, text_size_adjust_zero->StyleRef().SpecifiedFontSize());
+ EXPECT_FLOAT_EQ(0.f, text_size_adjust_zero->StyleRef().ComputedFontSize());
}
TEST_F(TextAutosizerTest, NegativeTextSizeAdjustment) {
@@ -228,8 +228,9 @@ TEST_F(TextAutosizerTest, NegativeTextSizeAdjustment) {
LayoutObject* text_size_adjust_negative =
GetDocument().getElementById("textSizeAdjustNegative")->GetLayoutObject();
EXPECT_FLOAT_EQ(16.f,
- text_size_adjust_negative->Style()->SpecifiedFontSize());
- EXPECT_FLOAT_EQ(40.f, text_size_adjust_negative->Style()->ComputedFontSize());
+ text_size_adjust_negative->StyleRef().SpecifiedFontSize());
+ EXPECT_FLOAT_EQ(40.f,
+ text_size_adjust_negative->StyleRef().ComputedFontSize());
}
TEST_F(TextAutosizerTest, TextSizeAdjustmentPixelUnits) {
@@ -250,8 +251,9 @@ TEST_F(TextAutosizerTest, TextSizeAdjustmentPixelUnits) {
"</div>");
LayoutObject* text_size_adjust_pixels =
GetDocument().getElementById("textSizeAdjustPixels")->GetLayoutObject();
- EXPECT_FLOAT_EQ(16.f, text_size_adjust_pixels->Style()->SpecifiedFontSize());
- EXPECT_FLOAT_EQ(40.f, text_size_adjust_pixels->Style()->ComputedFontSize());
+ EXPECT_FLOAT_EQ(16.f,
+ text_size_adjust_pixels->StyleRef().SpecifiedFontSize());
+ EXPECT_FLOAT_EQ(40.f, text_size_adjust_pixels->StyleRef().ComputedFontSize());
}
TEST_F(TextAutosizerTest, NestedTextSizeAdjust) {
@@ -281,14 +283,14 @@ TEST_F(TextAutosizerTest, NestedTextSizeAdjust) {
)HTML");
LayoutObject* text_size_adjust_a =
GetDocument().getElementById("textSizeAdjustA")->GetLayoutObject();
- EXPECT_FLOAT_EQ(16.f, text_size_adjust_a->Style()->SpecifiedFontSize());
+ EXPECT_FLOAT_EQ(16.f, text_size_adjust_a->StyleRef().SpecifiedFontSize());
// 16px * 47% = 7.52
- EXPECT_FLOAT_EQ(7.52f, text_size_adjust_a->Style()->ComputedFontSize());
+ EXPECT_FLOAT_EQ(7.52f, text_size_adjust_a->StyleRef().ComputedFontSize());
LayoutObject* text_size_adjust_b =
GetDocument().getElementById("textSizeAdjustB")->GetLayoutObject();
- EXPECT_FLOAT_EQ(16.f, text_size_adjust_b->Style()->SpecifiedFontSize());
+ EXPECT_FLOAT_EQ(16.f, text_size_adjust_b->StyleRef().SpecifiedFontSize());
// 16px * 53% = 8.48
- EXPECT_FLOAT_EQ(8.48f, text_size_adjust_b->Style()->ComputedFontSize());
+ EXPECT_FLOAT_EQ(8.48f, text_size_adjust_b->StyleRef().ComputedFontSize());
}
TEST_F(TextAutosizerTest, PrefixedTextSizeAdjustIsAlias) {
@@ -309,10 +311,10 @@ TEST_F(TextAutosizerTest, PrefixedTextSizeAdjustIsAlias) {
)HTML");
LayoutObject* text_size_adjust =
GetDocument().getElementById("textSizeAdjust")->GetLayoutObject();
- EXPECT_FLOAT_EQ(16.f, text_size_adjust->Style()->SpecifiedFontSize());
- EXPECT_FLOAT_EQ(8.f, text_size_adjust->Style()->ComputedFontSize());
- EXPECT_FLOAT_EQ(.5f,
- text_size_adjust->Style()->GetTextSizeAdjust().Multiplier());
+ EXPECT_FLOAT_EQ(16.f, text_size_adjust->StyleRef().SpecifiedFontSize());
+ EXPECT_FLOAT_EQ(8.f, text_size_adjust->StyleRef().ComputedFontSize());
+ EXPECT_FLOAT_EQ(
+ .5f, text_size_adjust->StyleRef().GetTextSizeAdjust().Multiplier());
}
TEST_F(TextAutosizerTest, AccessibilityFontScaleFactor) {
@@ -334,11 +336,11 @@ TEST_F(TextAutosizerTest, AccessibilityFontScaleFactor) {
)HTML");
Element* autosized = GetDocument().getElementById("autosized");
EXPECT_FLOAT_EQ(16.f,
- autosized->GetLayoutObject()->Style()->SpecifiedFontSize());
+ autosized->GetLayoutObject()->StyleRef().SpecifiedFontSize());
// 1.5 * (specified font-size = 16px) * (viewport width = 800px) /
// (window width = 320px) = 60px.
EXPECT_FLOAT_EQ(60.f,
- autosized->GetLayoutObject()->Style()->ComputedFontSize());
+ autosized->GetLayoutObject()->StyleRef().ComputedFontSize());
}
TEST_F(TextAutosizerTest, AccessibilityFontScaleFactorWithTextSizeAdjustNone) {
@@ -371,19 +373,19 @@ TEST_F(TextAutosizerTest, AccessibilityFontScaleFactorWithTextSizeAdjustNone) {
)HTML");
Element* autosized = GetDocument().getElementById("autosized");
EXPECT_FLOAT_EQ(16.f,
- autosized->GetLayoutObject()->Style()->SpecifiedFontSize());
+ autosized->GetLayoutObject()->StyleRef().SpecifiedFontSize());
// 1.5 * (specified font-size = 16px) = 24px.
EXPECT_FLOAT_EQ(24.f,
- autosized->GetLayoutObject()->Style()->ComputedFontSize());
+ autosized->GetLayoutObject()->StyleRef().ComputedFontSize());
// Because this does not autosize (due to the width), no accessibility font
// scale factor should be applied.
Element* not_autosized = GetDocument().getElementById("notAutosized");
EXPECT_FLOAT_EQ(
- 16.f, not_autosized->GetLayoutObject()->Style()->SpecifiedFontSize());
+ 16.f, not_autosized->GetLayoutObject()->StyleRef().SpecifiedFontSize());
// specified font-size = 16px.
EXPECT_FLOAT_EQ(
- 16.f, not_autosized->GetLayoutObject()->Style()->ComputedFontSize());
+ 16.f, not_autosized->GetLayoutObject()->StyleRef().ComputedFontSize());
}
TEST_F(TextAutosizerTest, ChangingAccessibilityFontScaleFactor) {
@@ -405,21 +407,21 @@ TEST_F(TextAutosizerTest, ChangingAccessibilityFontScaleFactor) {
)HTML");
Element* autosized = GetDocument().getElementById("autosized");
EXPECT_FLOAT_EQ(16.f,
- autosized->GetLayoutObject()->Style()->SpecifiedFontSize());
+ autosized->GetLayoutObject()->StyleRef().SpecifiedFontSize());
// 1.0 * (specified font-size = 16px) * (viewport width = 800px) /
// (window width = 320px) = 40px.
EXPECT_FLOAT_EQ(40.f,
- autosized->GetLayoutObject()->Style()->ComputedFontSize());
+ autosized->GetLayoutObject()->StyleRef().ComputedFontSize());
GetDocument().GetSettings()->SetAccessibilityFontScaleFactor(2);
GetDocument().View()->UpdateAllLifecyclePhases();
EXPECT_FLOAT_EQ(16.f,
- autosized->GetLayoutObject()->Style()->SpecifiedFontSize());
+ autosized->GetLayoutObject()->StyleRef().SpecifiedFontSize());
// 2.0 * (specified font-size = 16px) * (viewport width = 800px) /
// (window width = 320px) = 80px.
EXPECT_FLOAT_EQ(80.f,
- autosized->GetLayoutObject()->Style()->ComputedFontSize());
+ autosized->GetLayoutObject()->StyleRef().ComputedFontSize());
}
TEST_F(TextAutosizerTest, TextSizeAdjustDoesNotDisableAccessibility) {
@@ -452,21 +454,21 @@ TEST_F(TextAutosizerTest, TextSizeAdjustDoesNotDisableAccessibility) {
GetDocument().getElementById("textSizeAdjustNone");
EXPECT_FLOAT_EQ(
16.f,
- text_size_adjust_none->GetLayoutObject()->Style()->SpecifiedFontSize());
+ text_size_adjust_none->GetLayoutObject()->StyleRef().SpecifiedFontSize());
// 1.5 * (specified font-size = 16px) = 24px.
EXPECT_FLOAT_EQ(
24.f,
- text_size_adjust_none->GetLayoutObject()->Style()->ComputedFontSize());
+ text_size_adjust_none->GetLayoutObject()->StyleRef().ComputedFontSize());
Element* text_size_adjust_double =
GetDocument().getElementById("textSizeAdjustDouble");
- EXPECT_FLOAT_EQ(
- 16.f,
- text_size_adjust_double->GetLayoutObject()->Style()->SpecifiedFontSize());
+ EXPECT_FLOAT_EQ(16.f, text_size_adjust_double->GetLayoutObject()
+ ->StyleRef()
+ .SpecifiedFontSize());
// 1.5 * (specified font-size = 16px) * (text size adjustment = 2) = 48px.
- EXPECT_FLOAT_EQ(
- 48.f,
- text_size_adjust_double->GetLayoutObject()->Style()->ComputedFontSize());
+ EXPECT_FLOAT_EQ(48.f, text_size_adjust_double->GetLayoutObject()
+ ->StyleRef()
+ .ComputedFontSize());
// Changing the accessibility font scale factor should change the adjusted
// size.
@@ -475,19 +477,19 @@ TEST_F(TextAutosizerTest, TextSizeAdjustDoesNotDisableAccessibility) {
EXPECT_FLOAT_EQ(
16.f,
- text_size_adjust_none->GetLayoutObject()->Style()->SpecifiedFontSize());
+ text_size_adjust_none->GetLayoutObject()->StyleRef().SpecifiedFontSize());
// 2.0 * (specified font-size = 16px) = 32px.
EXPECT_FLOAT_EQ(
32.f,
- text_size_adjust_none->GetLayoutObject()->Style()->ComputedFontSize());
+ text_size_adjust_none->GetLayoutObject()->StyleRef().ComputedFontSize());
- EXPECT_FLOAT_EQ(
- 16.f,
- text_size_adjust_double->GetLayoutObject()->Style()->SpecifiedFontSize());
+ EXPECT_FLOAT_EQ(16.f, text_size_adjust_double->GetLayoutObject()
+ ->StyleRef()
+ .SpecifiedFontSize());
// 2.0 * (specified font-size = 16px) * (text size adjustment = 2) = 64px.
- EXPECT_FLOAT_EQ(
- 64.f,
- text_size_adjust_double->GetLayoutObject()->Style()->ComputedFontSize());
+ EXPECT_FLOAT_EQ(64.f, text_size_adjust_double->GetLayoutObject()
+ ->StyleRef()
+ .ComputedFontSize());
}
// https://crbug.com/646237
@@ -506,10 +508,10 @@ TEST_F(TextAutosizerTest, DISABLED_TextSizeAdjustWithoutNeedingAutosizing) {
LayoutObject* text_size_adjust =
GetDocument().getElementById("textSizeAdjust")->GetLayoutObject();
- EXPECT_FLOAT_EQ(16.f, text_size_adjust->Style()->SpecifiedFontSize());
- EXPECT_FLOAT_EQ(24.f, text_size_adjust->Style()->ComputedFontSize());
- EXPECT_FLOAT_EQ(1.5f,
- text_size_adjust->Style()->GetTextSizeAdjust().Multiplier());
+ EXPECT_FLOAT_EQ(16.f, text_size_adjust->StyleRef().SpecifiedFontSize());
+ EXPECT_FLOAT_EQ(24.f, text_size_adjust->StyleRef().ComputedFontSize());
+ EXPECT_FLOAT_EQ(
+ 1.5f, text_size_adjust->StyleRef().GetTextSizeAdjust().Multiplier());
}
TEST_F(TextAutosizerTest, DeviceScaleAdjustmentWithViewport) {
@@ -536,23 +538,23 @@ TEST_F(TextAutosizerTest, DeviceScaleAdjustmentWithViewport) {
Element* autosized = GetDocument().getElementById("autosized");
EXPECT_FLOAT_EQ(16.f,
- autosized->GetLayoutObject()->Style()->SpecifiedFontSize());
+ autosized->GetLayoutObject()->StyleRef().SpecifiedFontSize());
// (specified font-size = 16px) * (viewport width = 800px) /
// (window width = 320px) = 40px.
// The device scale adjustment of 1.5 is ignored.
EXPECT_FLOAT_EQ(40.f,
- autosized->GetLayoutObject()->Style()->ComputedFontSize());
+ autosized->GetLayoutObject()->StyleRef().ComputedFontSize());
GetDocument().GetSettings()->SetViewportMetaEnabled(false);
GetDocument().View()->UpdateAllLifecyclePhases();
autosized = GetDocument().getElementById("autosized");
EXPECT_FLOAT_EQ(16.f,
- autosized->GetLayoutObject()->Style()->SpecifiedFontSize());
+ autosized->GetLayoutObject()->StyleRef().SpecifiedFontSize());
// (device scale adjustment = 1.5) * (specified font-size = 16px) *
// (viewport width = 800px) / (window width = 320px) = 60px.
EXPECT_FLOAT_EQ(60.f,
- autosized->GetLayoutObject()->Style()->ComputedFontSize());
+ autosized->GetLayoutObject()->StyleRef().ComputedFontSize());
}
TEST_F(TextAutosizerTest, ChangingSuperClusterFirstText) {
@@ -590,14 +592,14 @@ TEST_F(TextAutosizerTest, ChangingSuperClusterFirstText) {
LayoutObject* long_text =
GetDocument().getElementById("longText")->GetLayoutObject();
- EXPECT_FLOAT_EQ(16.f, long_text->Style()->SpecifiedFontSize());
+ EXPECT_FLOAT_EQ(16.f, long_text->StyleRef().SpecifiedFontSize());
//(specified font-size = 16px) * (block width = 560px) /
// (window width = 320px) = 28px.
- EXPECT_FLOAT_EQ(28.f, long_text->Style()->ComputedFontSize());
+ EXPECT_FLOAT_EQ(28.f, long_text->StyleRef().ComputedFontSize());
LayoutObject* short_text =
GetDocument().getElementById("shortText")->GetLayoutObject();
- EXPECT_FLOAT_EQ(16.f, short_text->Style()->SpecifiedFontSize());
- EXPECT_FLOAT_EQ(28.f, short_text->Style()->ComputedFontSize());
+ EXPECT_FLOAT_EQ(16.f, short_text->StyleRef().SpecifiedFontSize());
+ EXPECT_FLOAT_EQ(28.f, short_text->StyleRef().ComputedFontSize());
}
TEST_F(TextAutosizerTest, ChangingSuperClusterSecondText) {
@@ -635,14 +637,14 @@ TEST_F(TextAutosizerTest, ChangingSuperClusterSecondText) {
LayoutObject* long_text =
GetDocument().getElementById("longText")->GetLayoutObject();
- EXPECT_FLOAT_EQ(16.f, long_text->Style()->SpecifiedFontSize());
+ EXPECT_FLOAT_EQ(16.f, long_text->StyleRef().SpecifiedFontSize());
//(specified font-size = 16px) * (block width = 560px) /
// (window width = 320px) = 28px.
- EXPECT_FLOAT_EQ(28.f, long_text->Style()->ComputedFontSize());
+ EXPECT_FLOAT_EQ(28.f, long_text->StyleRef().ComputedFontSize());
LayoutObject* short_text =
GetDocument().getElementById("shortText")->GetLayoutObject();
- EXPECT_FLOAT_EQ(16.f, short_text->Style()->SpecifiedFontSize());
- EXPECT_FLOAT_EQ(28.f, short_text->Style()->ComputedFontSize());
+ EXPECT_FLOAT_EQ(16.f, short_text->StyleRef().SpecifiedFontSize());
+ EXPECT_FLOAT_EQ(28.f, short_text->StyleRef().ComputedFontSize());
}
TEST_F(TextAutosizerTest, AddingSuperCluster) {
@@ -682,14 +684,14 @@ TEST_F(TextAutosizerTest, AddingSuperCluster) {
LayoutObject* long_text =
GetDocument().getElementById("longText")->GetLayoutObject();
- EXPECT_FLOAT_EQ(16.f, long_text->Style()->SpecifiedFontSize());
+ EXPECT_FLOAT_EQ(16.f, long_text->StyleRef().SpecifiedFontSize());
//(specified font-size = 16px) * (block width = 560px) /
// (window width = 320px) = 28px.
- EXPECT_FLOAT_EQ(28.f, long_text->Style()->ComputedFontSize());
+ EXPECT_FLOAT_EQ(28.f, long_text->StyleRef().ComputedFontSize());
LayoutObject* short_text =
GetDocument().getElementById("shortText")->GetLayoutObject();
- EXPECT_FLOAT_EQ(16.f, short_text->Style()->SpecifiedFontSize());
- EXPECT_FLOAT_EQ(28.f, short_text->Style()->ComputedFontSize());
+ EXPECT_FLOAT_EQ(16.f, short_text->StyleRef().SpecifiedFontSize());
+ EXPECT_FLOAT_EQ(28.f, short_text->StyleRef().ComputedFontSize());
}
TEST_F(TextAutosizerTest, ChangingInheritedClusterTextInsideSuperCluster) {
@@ -728,14 +730,14 @@ TEST_F(TextAutosizerTest, ChangingInheritedClusterTextInsideSuperCluster) {
LayoutObject* long_text =
GetDocument().getElementById("longText")->GetLayoutObject();
- EXPECT_FLOAT_EQ(16.f, long_text->Style()->SpecifiedFontSize());
+ EXPECT_FLOAT_EQ(16.f, long_text->StyleRef().SpecifiedFontSize());
//(specified font-size = 16px) * (block width = 560px) /
// (window width = 320px) = 28px.
- EXPECT_FLOAT_EQ(28.f, long_text->Style()->ComputedFontSize());
+ EXPECT_FLOAT_EQ(28.f, long_text->StyleRef().ComputedFontSize());
LayoutObject* short_text =
GetDocument().getElementById("shortText")->GetLayoutObject();
- EXPECT_FLOAT_EQ(16.f, short_text->Style()->SpecifiedFontSize());
- EXPECT_FLOAT_EQ(28.f, short_text->Style()->ComputedFontSize());
+ EXPECT_FLOAT_EQ(16.f, short_text->StyleRef().SpecifiedFontSize());
+ EXPECT_FLOAT_EQ(28.f, short_text->StyleRef().ComputedFontSize());
}
TEST_F(TextAutosizerTest, AutosizeInnerContentOfRuby) {
@@ -777,20 +779,20 @@ TEST_F(TextAutosizerTest, AutosizeInnerContentOfRuby) {
GetDocument().View()->UpdateAllLifecyclePhases();
Element* ruby_inline = GetDocument().getElementById("rubyInline");
- EXPECT_FLOAT_EQ(16.f,
- ruby_inline->GetLayoutObject()->Style()->SpecifiedFontSize());
+ EXPECT_FLOAT_EQ(
+ 16.f, ruby_inline->GetLayoutObject()->StyleRef().SpecifiedFontSize());
// (specified font-size = 16px) * (viewport width = 800px) /
// (window width = 320px) = 40px.
- EXPECT_FLOAT_EQ(40.f,
- ruby_inline->GetLayoutObject()->Style()->ComputedFontSize());
+ EXPECT_FLOAT_EQ(
+ 40.f, ruby_inline->GetLayoutObject()->StyleRef().ComputedFontSize());
Element* ruby_block = GetDocument().getElementById("rubyBlock");
- EXPECT_FLOAT_EQ(16.f,
- ruby_block->GetLayoutObject()->Style()->SpecifiedFontSize());
+ EXPECT_FLOAT_EQ(
+ 16.f, ruby_block->GetLayoutObject()->StyleRef().SpecifiedFontSize());
// (specified font-size = 16px) * (viewport width = 800px) /
// (window width = 320px) = 40px.
EXPECT_FLOAT_EQ(40.f,
- ruby_block->GetLayoutObject()->Style()->ComputedFontSize());
+ ruby_block->GetLayoutObject()->StyleRef().ComputedFontSize());
}
TEST_F(TextAutosizerTest, ResizeAndGlyphOverflowChanged) {
@@ -868,7 +870,7 @@ TEST_F(TextAutosizerTest, narrowContentInsideNestedWideBlock) {
//(content width = 200px) / (window width = 320px) < 1.0f, multiplier = 1.0,
// font-size = 16px;
EXPECT_FLOAT_EQ(16.f,
- content->GetLayoutObject()->Style()->ComputedFontSize());
+ content->GetLayoutObject()->StyleRef().ComputedFontSize());
}
TEST_F(TextAutosizerTest, LayoutViewWidthProvider) {
@@ -900,7 +902,7 @@ TEST_F(TextAutosizerTest, LayoutViewWidthProvider) {
// (specified font-size = 16px) * (viewport width = 800px) /
// (window width = 320px) = 40px.
EXPECT_FLOAT_EQ(40.f,
- content->GetLayoutObject()->Style()->ComputedFontSize());
+ content->GetLayoutObject()->StyleRef().ComputedFontSize());
GetDocument().getElementById("panel")->SetInnerHTMLFromString("insert text");
content->SetInnerHTMLFromString(content->InnerHTMLAsString());
@@ -909,7 +911,7 @@ TEST_F(TextAutosizerTest, LayoutViewWidthProvider) {
// (specified font-size = 16px) * (viewport width = 800px) /
// (window width = 320px) = 40px.
EXPECT_FLOAT_EQ(40.f,
- content->GetLayoutObject()->Style()->ComputedFontSize());
+ content->GetLayoutObject()->StyleRef().ComputedFontSize());
}
TEST_F(TextAutosizerTest, MultiColumns) {
@@ -942,7 +944,8 @@ TEST_F(TextAutosizerTest, MultiColumns) {
Element* target = GetDocument().getElementById("target");
// (specified font-size = 16px) * ( thread flow layout width = 800px / 3) /
// (window width = 320px) < 16px.
- EXPECT_FLOAT_EQ(16.f, target->GetLayoutObject()->Style()->ComputedFontSize());
+ EXPECT_FLOAT_EQ(16.f,
+ target->GetLayoutObject()->StyleRef().ComputedFontSize());
}
TEST_F(TextAutosizerTest, ScaledbyDSF) {
@@ -970,7 +973,7 @@ TEST_F(TextAutosizerTest, ScaledbyDSF) {
// (specified font-size = 16px) * (thread flow layout width = 800px) /
// (window width = 320px) * (device scale factor) = 40px * device_scale.
EXPECT_FLOAT_EQ(40.0f * device_scale,
- target->GetLayoutObject()->Style()->ComputedFontSize());
+ target->GetLayoutObject()->StyleRef().ComputedFontSize());
}
TEST_F(TextAutosizerTest, ClusterHasNotEnoughTextToAutosizeForZoomDSF) {
@@ -992,7 +995,8 @@ TEST_F(TextAutosizerTest, ClusterHasNotEnoughTextToAutosizeForZoomDSF) {
// minimum_text_length_to_autosize < length. Thus, ClusterMultiplier()
// returns 1 (not multiplied by the accessibility font scale factor).
// computed font-size = specified font-size = 8px.
- EXPECT_FLOAT_EQ(8.0f, target->GetLayoutObject()->Style()->ComputedFontSize());
+ EXPECT_FLOAT_EQ(8.0f,
+ target->GetLayoutObject()->StyleRef().ComputedFontSize());
}
// TODO(jaebaek): Unit tests ClusterHasNotEnoughTextToAutosizeForZoomDSF and
@@ -1029,7 +1033,7 @@ TEST_F(TextAutosizerTest, ClusterHasEnoughTextToAutosizeForZoomDSF) {
// ClusterHasEnoughTextToAutosize() returns true and both accessibility font
// scale factor and device scale factor are multiplied.
EXPECT_FLOAT_EQ(20.0f * device_scale,
- target->GetLayoutObject()->Style()->ComputedFontSize());
+ target->GetLayoutObject()->StyleRef().ComputedFontSize());
}
TEST_F(TextAutosizerTest, AfterPrint) {
@@ -1051,11 +1055,12 @@ TEST_F(TextAutosizerTest, AfterPrint) {
)HTML");
Element* target = GetDocument().getElementById("target");
EXPECT_FLOAT_EQ(20.0f * device_scale,
- target->GetLayoutObject()->Style()->ComputedFontSize());
+ target->GetLayoutObject()->StyleRef().ComputedFontSize());
GetDocument().GetFrame()->StartPrinting(print_size, print_size, 1.0);
- EXPECT_FLOAT_EQ(8.0f, target->GetLayoutObject()->Style()->ComputedFontSize());
+ EXPECT_FLOAT_EQ(8.0f,
+ target->GetLayoutObject()->StyleRef().ComputedFontSize());
GetDocument().GetFrame()->EndPrinting();
EXPECT_FLOAT_EQ(20.0f * device_scale,
- target->GetLayoutObject()->Style()->ComputedFontSize());
+ target->GetLayoutObject()->StyleRef().ComputedFontSize());
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/loader/BUILD.gn b/chromium/third_party/blink/renderer/core/loader/BUILD.gn
index 49b4ead3dc5..7d118b1f513 100644
--- a/chromium/third_party/blink/renderer/core/loader/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/loader/BUILD.gn
@@ -20,9 +20,6 @@ blink_core_sources("loader") {
"document_load_timing.h",
"document_loader.cc",
"document_loader.h",
- "document_threadable_loader.cc",
- "document_threadable_loader.h",
- "document_threadable_loader_client.h",
"empty_clients.cc",
"empty_clients.h",
"form_submission.cc",
@@ -51,6 +48,8 @@ blink_core_sources("loader") {
"link_loader.cc",
"link_loader.h",
"link_loader_client.h",
+ "long_task_detector.cc",
+ "long_task_detector.h",
"mixed_content_checker.cc",
"mixed_content_checker.h",
"modulescript/document_module_script_fetcher.cc",
@@ -81,6 +80,8 @@ blink_core_sources("loader") {
"ping_loader.h",
"prerenderer_client.cc",
"prerenderer_client.h",
+ "previews_resource_loading_hints.cc",
+ "previews_resource_loading_hints.h",
"previews_resource_loading_hints_receiver_impl.cc",
"previews_resource_loading_hints_receiver_impl.h",
"private/frame_client_hints_preferences_context.cc",
@@ -124,12 +125,8 @@ blink_core_sources("loader") {
"threadable_loader.cc",
"threadable_loader.h",
"threadable_loader_client.h",
- "threadable_loading_context.cc",
- "threadable_loading_context.h",
"worker_fetch_context.cc",
"worker_fetch_context.h",
- "worker_threadable_loader.cc",
- "worker_threadable_loader.h",
]
public_deps = [
diff --git a/chromium/third_party/blink/renderer/core/loader/allowed_by_nosniff.cc b/chromium/third_party/blink/renderer/core/loader/allowed_by_nosniff.cc
index 5255c3cb131..6728251249b 100644
--- a/chromium/third_party/blink/renderer/core/loader/allowed_by_nosniff.cc
+++ b/chromium/third_party/blink/renderer/core/loader/allowed_by_nosniff.cc
@@ -127,9 +127,9 @@ bool MimeTypeAsScriptImpl(ExecutionContext* execution_context,
const ResourceResponse& response,
bool is_worker_global_scope) {
// Is it a file:-URL? If so, decide based on file suffix.
- if (RuntimeEnabledFeatures::WorkerNosniffBlockEnabled() &&
- is_worker_global_scope && response.Url().IsLocalFile()) {
- return response.Url().LastPathComponent().EndsWith(".js");
+ if (response.Url().IsLocalFile() &&
+ response.Url().LastPathComponent().EndsWith(".js")) {
+ return true;
}
String mime_type = response.HttpContentType();
diff --git a/chromium/third_party/blink/renderer/core/loader/appcache/OWNERS b/chromium/third_party/blink/renderer/core/loader/appcache/OWNERS
new file mode 100644
index 00000000000..602a916a8b4
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/loader/appcache/OWNERS
@@ -0,0 +1,4 @@
+file://content/browser/appcache/OWNERS
+
+# TEAM: storage-dev@chromium.org
+# COMPONENT: Blink>Storage>AppCache \ No newline at end of file
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 e9ff97a6719..4510299ea08 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
@@ -299,7 +299,7 @@ void ApplicationCacheHost::DispatchDOMEvent(
} else {
event = Event::Create(event_type);
}
- dom_application_cache_->DispatchEvent(event);
+ dom_application_cache_->DispatchEvent(*event);
}
ApplicationCacheHost::Status ApplicationCacheHost::GetStatus() const {
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 53568a1eab5..713843083a6 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
@@ -82,6 +82,8 @@ class CORE_EXPORT ApplicationCacheHost final
struct CacheInfo {
STACK_ALLOCATED();
+
+ public:
CacheInfo(const KURL& manifest,
double creation_time,
double update_time,
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 996c07442f3..9a527a5ef76 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
@@ -10,6 +10,7 @@
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
+#include "third_party/blink/renderer/core/loader/previews_resource_loading_hints.h"
#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"
@@ -64,6 +65,8 @@ const char* GetDestinationFromContext(WebURLRequest::RequestContext context) {
return "object";
case WebURLRequest::kRequestContextScript:
return "script";
+ case WebURLRequest::kRequestContextServiceWorker:
+ return "serviceworker";
case WebURLRequest::kRequestContextSharedWorker:
return "sharedworker";
case WebURLRequest::kRequestContextStyle:
@@ -79,7 +82,6 @@ const char* GetDestinationFromContext(WebURLRequest::RequestContext context) {
case WebURLRequest::kRequestContextImport:
case WebURLRequest::kRequestContextInternal:
case WebURLRequest::kRequestContextPlugin:
- case WebURLRequest::kRequestContextServiceWorker:
return "unknown";
}
NOTREACHED();
@@ -107,12 +109,25 @@ void BaseFetchContext::AddAdditionalRequestHeaders(ResourceRequest& request,
FetchResourceType type) {
bool is_main_resource = type == kFetchMainResource;
if (!is_main_resource) {
+ // TODO(domfarolino): we can probably *just set* the HTTP `Referer` here
+ // no matter what now.
if (!request.DidSetHTTPReferrer()) {
+ String referrer_to_use = request.ReferrerString();
+ ReferrerPolicy referrer_policy_to_use = request.GetReferrerPolicy();
+
+ if (referrer_to_use == Referrer::ClientReferrerString())
+ referrer_to_use = GetFetchClientSettingsObject()->GetOutgoingReferrer();
+
+ if (referrer_policy_to_use == kReferrerPolicyDefault) {
+ referrer_policy_to_use =
+ GetFetchClientSettingsObject()->GetReferrerPolicy();
+ }
+
+ // TODO(domfarolino): Stop storing ResourceRequest's referrer as a header
+ // and store it elsewhere. See https://crbug.com/850813.
request.SetHTTPReferrer(SecurityPolicy::GenerateReferrer(
- GetFetchClientSettingsObject()->GetReferrerPolicy(), request.Url(),
- GetFetchClientSettingsObject()->GetOutgoingReferrer()));
- request.SetHTTPOriginIfNeeded(
- GetFetchClientSettingsObject()->GetSecurityOrigin());
+ referrer_policy_to_use, request.Url(), referrer_to_use));
+ request.SetHTTPOriginIfNeeded(GetSecurityOrigin());
} else {
DCHECK_EQ(SecurityPolicy::GenerateReferrer(request.GetReferrerPolicy(),
request.Url(),
@@ -140,16 +155,15 @@ void BaseFetchContext::AddAdditionalRequestHeaders(ResourceRequest& request,
} else {
OriginAccessEntry access_entry(
request.Url().Protocol(), request.Url().Host(),
- OriginAccessEntry::kAllowRegisterableDomains);
+ network::cors::OriginAccessEntry::kAllowRegisterableDomains);
if (access_entry.MatchesOrigin(*GetSecurityOrigin()) ==
- OriginAccessEntry::kMatchesOrigin) {
+ network::cors::OriginAccessEntry::kMatchesOrigin) {
site_value = "same-site";
}
}
- String value =
- String::Format("destination=%s, target=subresource, site=%s",
- destination_value, site_value);
+ String value = String::Format("destination=%s, site=%s",
+ destination_value, site_value);
request.AddHTTPHeaderField("Sec-Metadata", AtomicString(value));
}
}
@@ -161,11 +175,10 @@ base::Optional<ResourceRequestBlockedReason> BaseFetchContext::CanRequest(
const KURL& url,
const ResourceLoaderOptions& options,
SecurityViolationReportingPolicy reporting_policy,
- FetchParameters::OriginRestriction origin_restriction,
ResourceRequest::RedirectStatus redirect_status) const {
base::Optional<ResourceRequestBlockedReason> blocked_reason =
CanRequestInternal(type, resource_request, url, options, reporting_policy,
- origin_restriction, redirect_status);
+ redirect_status);
if (blocked_reason &&
reporting_policy == SecurityViolationReportingPolicy::kReport) {
DispatchDidBlockRequest(resource_request, options.initiator_info,
@@ -180,6 +193,12 @@ void BaseFetchContext::AddInfoConsoleMessage(const String& message,
ConvertLogSourceToMessageSource(source), kInfoMessageLevel, message));
}
+void BaseFetchContext::AddWarningConsoleMessage(const String& message,
+ LogSource source) const {
+ AddConsoleMessage(ConsoleMessage::Create(
+ ConvertLogSourceToMessageSource(source), kWarningMessageLevel, message));
+}
+
void BaseFetchContext::AddErrorConsoleMessage(const String& message,
LogSource source) const {
AddConsoleMessage(ConsoleMessage::Create(
@@ -262,7 +281,6 @@ BaseFetchContext::CanRequestInternal(
const KURL& url,
const ResourceLoaderOptions& options,
SecurityViolationReportingPolicy reporting_policy,
- FetchParameters::OriginRestriction origin_restriction,
ResourceRequest::RedirectStatus redirect_status) const {
if (IsDetached()) {
if (!resource_request.GetKeepalive() ||
@@ -278,8 +296,7 @@ BaseFetchContext::CanRequestInternal(
if (!security_origin)
security_origin = GetSecurityOrigin();
- if (origin_restriction != FetchParameters::kNoOriginRestriction &&
- security_origin && !security_origin->CanDisplay(url)) {
+ if (security_origin && !security_origin->CanDisplay(url)) {
if (reporting_policy == SecurityViolationReportingPolicy::kReport) {
AddErrorConsoleMessage(
"Not allowed to load local resource: " + url.GetString(), kJSSource);
@@ -289,40 +306,13 @@ BaseFetchContext::CanRequestInternal(
return ResourceRequestBlockedReason::kOther;
}
- // Some types of resources can be loaded only from the same origin. Other
- // types of resources, like Images, Scripts, and CSS, can be loaded from
- // any URL.
- switch (type) {
- case Resource::kMainResource:
- case Resource::kImage:
- case Resource::kCSSStyleSheet:
- case Resource::kScript:
- case Resource::kFont:
- case Resource::kRaw:
- case Resource::kLinkPrefetch:
- case Resource::kTextTrack:
- case Resource::kImportResource:
- case Resource::kAudio:
- case Resource::kVideo:
- case Resource::kManifest:
- case Resource::kMock:
- // By default these types of resources can be loaded from any origin.
- // FIXME: Are we sure about Resource::kFont?
- if (origin_restriction == FetchParameters::kRestrictToSameOrigin &&
- !security_origin->CanRequest(url)) {
- PrintAccessDeniedMessage(url);
- return ResourceRequestBlockedReason::kOrigin;
- }
- break;
- case Resource::kXSLStyleSheet:
- DCHECK(RuntimeEnabledFeatures::XSLTEnabled());
- FALLTHROUGH;
- case Resource::kSVGDocument:
- if (!security_origin->CanRequest(url)) {
- PrintAccessDeniedMessage(url);
- return ResourceRequestBlockedReason::kOrigin;
- }
- break;
+ if (resource_request.GetFetchRequestMode() ==
+ network::mojom::FetchRequestMode::kSameOrigin) {
+ DCHECK(security_origin);
+ if (!security_origin->CanRequest(url)) {
+ PrintAccessDeniedMessage(url);
+ return ResourceRequestBlockedReason::kOrigin;
+ }
}
// User Agent CSS stylesheets should only support loading images and should be
@@ -395,8 +385,16 @@ BaseFetchContext::CanRequestInternal(
if (url.PotentiallyDanglingMarkup() && url.ProtocolIsInHTTPFamily()) {
CountDeprecation(WebFeature::kCanRequestURLHTTPContainingNewline);
- if (RuntimeEnabledFeatures::RestrictCanRequestURLCharacterSetEnabled())
- return ResourceRequestBlockedReason::kOther;
+ return ResourceRequestBlockedReason::kOther;
+ }
+
+ // Loading of a subresource may be blocked by previews resource loading hints.
+ if (GetPreviewsResourceLoadingHints() &&
+ !GetPreviewsResourceLoadingHints()->AllowLoad(
+ url, resource_request.Priority())) {
+ // TODO (tbansal): https://crbug.com/864253. Add a specific reason for why
+ // the resource fetch was blocked.
+ return ResourceRequestBlockedReason::kOther;
}
// Let the client have the final say into whether or not the load should
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 3bb6b18d7fa..9aea189bf95 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
@@ -21,6 +21,7 @@ namespace blink {
class ConsoleMessage;
class KURL;
+class PreviewsResourceLoadingHints;
class SecurityOrigin;
class SubresourceFilter;
class WebSocketHandshakeThrottle;
@@ -37,7 +38,6 @@ class CORE_EXPORT BaseFetchContext : public FetchContext {
const KURL&,
const ResourceLoaderOptions&,
SecurityViolationReportingPolicy,
- FetchParameters::OriginRestriction,
ResourceRequest::RedirectStatus) const override;
base::Optional<ResourceRequestBlockedReason> CheckCSPForRequest(
WebURLRequest::RequestContext,
@@ -52,6 +52,8 @@ class CORE_EXPORT BaseFetchContext : public FetchContext {
const = 0;
virtual KURL GetSiteForCookies() const = 0;
virtual SubresourceFilter* GetSubresourceFilter() const = 0;
+ virtual PreviewsResourceLoadingHints* GetPreviewsResourceLoadingHints()
+ const = 0;
virtual void CountUsage(WebFeature) const = 0;
virtual void CountDeprecation(WebFeature) const = 0;
virtual bool ShouldBlockWebSocketByMixedContentCheck(const KURL&) const = 0;
@@ -59,6 +61,7 @@ class CORE_EXPORT BaseFetchContext : public FetchContext {
CreateWebSocketHandshakeThrottle() = 0;
void AddInfoConsoleMessage(const String&, LogSource) const override;
+ void AddWarningConsoleMessage(const String&, LogSource) const override;
void AddErrorConsoleMessage(const String&, LogSource) const override;
bool IsAdResource(const KURL&,
Resource::Type,
@@ -104,7 +107,6 @@ class CORE_EXPORT BaseFetchContext : public FetchContext {
const KURL&,
const ResourceLoaderOptions&,
SecurityViolationReportingPolicy,
- FetchParameters::OriginRestriction,
ResourceRequest::RedirectStatus) const;
base::Optional<ResourceRequestBlockedReason> CheckCSPForRequestInternal(
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 e6937a748a9..082fdfba2f3 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
@@ -56,6 +56,10 @@ class MockBaseFetchContext final : public BaseFetchContext {
KURL GetSiteForCookies() const override { return KURL(); }
bool AllowScriptFromSource(const KURL&) const override { return false; }
SubresourceFilter* GetSubresourceFilter() const override { return nullptr; }
+ PreviewsResourceLoadingHints* GetPreviewsResourceLoadingHints()
+ const override {
+ return nullptr;
+ }
bool ShouldBlockRequestByInspector(const KURL&) const override {
return false;
}
@@ -306,7 +310,6 @@ TEST_F(BaseFetchContextTest, CanRequest) {
fetch_context_->CanRequest(
Resource::kScript, resource_request, url, options,
SecurityViolationReportingPolicy::kReport,
- FetchParameters::kUseDefaultOriginRestrictionForType,
ResourceRequest::RedirectStatus::kFollowedRedirect));
EXPECT_EQ(1u, policy->violation_reports_sent_.size());
}
@@ -344,28 +347,24 @@ TEST_F(BaseFetchContextTest, CanRequestWhenDetached) {
fetch_context_->CanRequest(
Resource::kRaw, request, url, ResourceLoaderOptions(),
SecurityViolationReportingPolicy::kSuppressReporting,
- FetchParameters::kNoOriginRestriction,
ResourceRequest::RedirectStatus::kNoRedirect));
EXPECT_EQ(base::nullopt,
fetch_context_->CanRequest(
Resource::kRaw, keepalive_request, url, ResourceLoaderOptions(),
SecurityViolationReportingPolicy::kSuppressReporting,
- FetchParameters::kNoOriginRestriction,
ResourceRequest::RedirectStatus::kNoRedirect));
EXPECT_EQ(base::nullopt,
fetch_context_->CanRequest(
Resource::kRaw, request, url, ResourceLoaderOptions(),
SecurityViolationReportingPolicy::kSuppressReporting,
- FetchParameters::kNoOriginRestriction,
ResourceRequest::RedirectStatus::kFollowedRedirect));
EXPECT_EQ(base::nullopt,
fetch_context_->CanRequest(
Resource::kRaw, keepalive_request, url, ResourceLoaderOptions(),
SecurityViolationReportingPolicy::kSuppressReporting,
- FetchParameters::kNoOriginRestriction,
ResourceRequest::RedirectStatus::kFollowedRedirect));
fetch_context_->SetIsDetached(true);
@@ -374,28 +373,24 @@ TEST_F(BaseFetchContextTest, CanRequestWhenDetached) {
fetch_context_->CanRequest(
Resource::kRaw, request, url, ResourceLoaderOptions(),
SecurityViolationReportingPolicy::kSuppressReporting,
- FetchParameters::kNoOriginRestriction,
ResourceRequest::RedirectStatus::kNoRedirect));
EXPECT_EQ(ResourceRequestBlockedReason::kOther,
fetch_context_->CanRequest(
Resource::kRaw, keepalive_request, url, ResourceLoaderOptions(),
SecurityViolationReportingPolicy::kSuppressReporting,
- FetchParameters::kNoOriginRestriction,
ResourceRequest::RedirectStatus::kNoRedirect));
EXPECT_EQ(ResourceRequestBlockedReason::kOther,
fetch_context_->CanRequest(
Resource::kRaw, request, url, ResourceLoaderOptions(),
SecurityViolationReportingPolicy::kSuppressReporting,
- FetchParameters::kNoOriginRestriction,
ResourceRequest::RedirectStatus::kFollowedRedirect));
EXPECT_EQ(base::nullopt,
fetch_context_->CanRequest(
Resource::kRaw, keepalive_request, url, ResourceLoaderOptions(),
SecurityViolationReportingPolicy::kSuppressReporting,
- FetchParameters::kNoOriginRestriction,
ResourceRequest::RedirectStatus::kFollowedRedirect));
}
@@ -412,21 +407,18 @@ TEST_F(BaseFetchContextTest, UACSSTest) {
fetch_context_->CanRequest(
Resource::kScript, resource_request, test_url, options,
SecurityViolationReportingPolicy::kReport,
- FetchParameters::kUseDefaultOriginRestrictionForType,
ResourceRequest::RedirectStatus::kFollowedRedirect));
EXPECT_EQ(ResourceRequestBlockedReason::kOther,
fetch_context_->CanRequest(
Resource::kImage, resource_request, test_url, options,
SecurityViolationReportingPolicy::kReport,
- FetchParameters::kUseDefaultOriginRestrictionForType,
ResourceRequest::RedirectStatus::kFollowedRedirect));
EXPECT_EQ(base::nullopt,
fetch_context_->CanRequest(
Resource::kImage, resource_request, data_url, options,
SecurityViolationReportingPolicy::kReport,
- FetchParameters::kUseDefaultOriginRestrictionForType,
ResourceRequest::RedirectStatus::kFollowedRedirect));
}
@@ -448,7 +440,6 @@ TEST_F(BaseFetchContextTest, UACSSTest_BypassCSP) {
fetch_context_->CanRequest(
Resource::kImage, resource_request, data_url, options,
SecurityViolationReportingPolicy::kReport,
- FetchParameters::kUseDefaultOriginRestrictionForType,
ResourceRequest::RedirectStatus::kFollowedRedirect));
}
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 4bd6c65b6b9..5ad8548e634 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
@@ -120,6 +120,11 @@ void DocumentLoadTiming::SetNavigationStart(TimeTicks navigation_start) {
NotifyDocumentTimingChanged();
}
+void DocumentLoadTiming::SetInputStart(TimeTicks input_start) {
+ input_start_ = input_start;
+ NotifyDocumentTimingChanged();
+}
+
void DocumentLoadTiming::AddRedirect(const KURL& redirecting_url,
const KURL& redirected_url) {
redirect_count_++;
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 afe09495e27..00a92fc9688 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
@@ -26,6 +26,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_DOCUMENT_LOAD_TIMING_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_DOCUMENT_LOAD_TIMING_H_
+#include "base/optional.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/instrumentation/tracing/traced_value.h"
@@ -49,6 +50,8 @@ class CORE_EXPORT DocumentLoadTiming final {
void MarkNavigationStart();
void SetNavigationStart(TimeTicks);
+ void SetInputStart(TimeTicks);
+
void AddRedirect(const KURL& redirecting_url, const KURL& redirected_url);
void SetRedirectStart(TimeTicks);
void SetRedirectEnd(TimeTicks);
@@ -72,6 +75,7 @@ class CORE_EXPORT DocumentLoadTiming final {
has_same_origin_as_previous_document_ = value;
}
+ TimeTicks InputStart() const { return input_start_; }
TimeTicks NavigationStart() const { return navigation_start_; }
TimeTicks UnloadEventStart() const { return unload_event_start_; }
TimeTicks UnloadEventEnd() const { return unload_event_end_; }
@@ -100,6 +104,7 @@ class CORE_EXPORT DocumentLoadTiming final {
TimeTicks reference_monotonic_time_;
TimeDelta reference_wall_time_;
+ TimeTicks input_start_;
TimeTicks navigation_start_;
TimeTicks unload_event_start_;
TimeTicks unload_event_end_;
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 0b35e877723..50296b849c8 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 "base/auto_reset.h"
+#include "third_party/blink/public/common/origin_policy/origin_policy.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_network_provider.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_url_request.h"
@@ -50,7 +51,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/html/html_frame_owner_element.h"
-#include "third_party/blink/renderer/core/html/parser/css_preload_scanner.h"
#include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h"
#include "third_party/blink/renderer/core/html/parser/text_resource_decoder.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
@@ -97,6 +97,7 @@
#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/assertions.h"
+#include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
@@ -174,6 +175,7 @@ void DocumentLoader::Trace(blink::Visitor* visitor) {
visitor->Trace(history_item_);
visitor->Trace(parser_);
visitor->Trace(subresource_filter_);
+ visitor->Trace(resource_loading_hints_);
visitor->Trace(document_load_timing_);
visitor->Trace(application_cache_host_);
visitor->Trace(content_security_policy_);
@@ -208,14 +210,17 @@ const KURL& DocumentLoader::Url() const {
}
Resource* DocumentLoader::StartPreload(Resource::Type type,
- FetchParameters& params,
- CSSPreloaderResourceClient* client) {
+ FetchParameters& params) {
Resource* resource = nullptr;
- DCHECK(!client || type == Resource::kCSSStyleSheet);
switch (type) {
case Resource::kImage:
- if (frame_)
- frame_->MaybeAllowImagePlaceholder(params);
+ if (frame_) {
+ if (frame_->IsClientLoFiAllowed(params.GetResourceRequest())) {
+ params.SetClientLoFiPlaceholder();
+ } else if (frame_->IsLazyLoadingImageAllowed()) {
+ params.SetAllowImagePlaceholder();
+ }
+ }
resource = ImageResource::Fetch(params, Fetcher());
break;
case Resource::kScript:
@@ -223,7 +228,7 @@ Resource* DocumentLoader::StartPreload(Resource::Type type,
resource = ScriptResource::Fetch(params, Fetcher(), nullptr);
break;
case Resource::kCSSStyleSheet:
- resource = CSSStyleSheetResource::Fetch(params, Fetcher(), client);
+ resource = CSSStyleSheetResource::Fetch(params, Fetcher(), nullptr);
break;
case Resource::kFont:
resource = FontResource::Fetch(params, Fetcher(), nullptr);
@@ -254,8 +259,15 @@ void DocumentLoader::SetServiceWorkerNetworkProvider(
}
void DocumentLoader::SetSourceLocation(
- std::unique_ptr<SourceLocation> source_location) {
- source_location_ = std::move(source_location);
+ const WebSourceLocation& source_location) {
+ std::unique_ptr<SourceLocation> location =
+ SourceLocation::Create(source_location.url, source_location.line_number,
+ source_location.column_number, nullptr);
+ source_location_ = std::move(location);
+}
+
+void DocumentLoader::ResetSourceLocation() {
+ source_location_ = nullptr;
}
std::unique_ptr<SourceLocation> DocumentLoader::CopySourceLocation() const {
@@ -608,6 +620,23 @@ void DocumentLoader::ResponseReceived(
if (!frame_->GetSettings()->BypassCSP()) {
content_security_policy_->DidReceiveHeaders(
ContentSecurityPolicyResponseHeaders(response));
+
+ // Handle OriginPolicy. We can skip the entire block if the OP policies have
+ // already been passed down.
+ if (!content_security_policy_->HasPolicyFromSource(
+ kContentSecurityPolicyHeaderSourceOriginPolicy)) {
+ std::unique_ptr<OriginPolicy> origin_policy = OriginPolicy::From(
+ StringUTF8Adaptor(request_.GetOriginPolicy()).AsStringPiece());
+ if (origin_policy) {
+ for (auto csp : origin_policy->GetContentSecurityPolicies()) {
+ content_security_policy_->DidReceiveHeader(
+ WTF::String::FromUTF8(csp.policy.data(), csp.policy.length()),
+ csp.report_only ? kContentSecurityPolicyHeaderTypeReport
+ : kContentSecurityPolicyHeaderTypeEnforce,
+ kContentSecurityPolicyHeaderSourceOriginPolicy);
+ }
+ }
+ }
}
if (!content_security_policy_->AllowAncestors(frame_, response.Url())) {
CancelLoadAfterCSPDenied(response);
@@ -615,7 +644,6 @@ void DocumentLoader::ResponseReceived(
}
if (!frame_->GetSettings()->BypassCSP() &&
- RuntimeEnabledFeatures::EmbedderCSPEnforcementEnabled() &&
!GetFrameLoader().RequiredCSP().IsEmpty()) {
const SecurityOrigin* parent_security_origin =
frame_->Tree().Parent()->GetSecurityContext()->GetSecurityOrigin();
@@ -867,6 +895,7 @@ bool DocumentLoader::MaybeLoadEmpty() {
!GetFrameLoader().StateMachine()->CreatingInitialEmptyDocument())
request_.SetURL(BlankURL());
response_ = ResourceResponse(request_.Url(), "text/html");
+ response_.SetTextEncodingName("utf-8");
FinishedLoading(CurrentTimeTicks());
return true;
}
@@ -1071,7 +1100,7 @@ void DocumentLoader::InstallNewDocument(
Document* document = frame_->DomWindow()->InstallNewDocument(
mime_type,
DocumentInit::Create()
- .WithFrame(frame_)
+ .WithDocumentLoader(this)
.WithURL(url)
.WithOwnerDocument(owner_document)
.WithNewRegistrationContext(),
@@ -1139,7 +1168,7 @@ void DocumentLoader::InstallNewDocument(
parser_->AsScriptableDocumentParser();
if (scriptable_parser && GetResource()) {
scriptable_parser->SetInlineScriptCacheHandler(
- ToRawResource(GetResource())->CacheHandler());
+ ToRawResource(GetResource())->InlineScriptCacheHandler());
}
// FeaturePolicy is reset in the browser process on commit, so this needs to
@@ -1215,7 +1244,12 @@ void DocumentLoader::UpdateNavigationTimings(
base::TimeTicks navigation_start_time,
base::TimeTicks redirect_start_time,
base::TimeTicks redirect_end_time,
- base::TimeTicks fetch_start_time) {
+ base::TimeTicks fetch_start_time,
+ base::TimeTicks input_start_time) {
+ if (!input_start_time.is_null()) {
+ GetTiming().SetInputStart(input_start_time);
+ }
+
// If we don't have any navigation timings yet, just start the navigation.
if (navigation_start_time.is_null()) {
GetTiming().SetNavigationStart(CurrentTimeTicks());
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 ae6d876fe2e..2d105d4013c 100644
--- a/chromium/third_party/blink/renderer/core/loader/document_loader.h
+++ b/chromium/third_party/blink/renderer/core/loader/document_loader.h
@@ -48,6 +48,7 @@
#include "third_party/blink/renderer/core/loader/frame_loader_types.h"
#include "third_party/blink/renderer/core/loader/link_loader.h"
#include "third_party/blink/renderer/core/loader/navigation_policy.h"
+#include "third_party/blink/renderer/core/loader/previews_resource_loading_hints.h"
#include "third_party/blink/renderer/core/page/viewport_description.h"
#include "third_party/blink/renderer/platform/loader/fetch/client_hints_preferences.h"
#include "third_party/blink/renderer/platform/loader/fetch/raw_resource.h"
@@ -63,7 +64,6 @@
namespace blink {
class ApplicationCacheHost;
-class CSSPreloaderResourceClient;
class Document;
class DocumentParser;
class FrameLoader;
@@ -122,6 +122,13 @@ class CORE_EXPORT DocumentLoader
SubresourceFilter* GetSubresourceFilter() const {
return subresource_filter_.Get();
}
+ void SetPreviewsResourceLoadingHints(
+ PreviewsResourceLoadingHints* resource_loading_hints) {
+ resource_loading_hints_ = resource_loading_hints;
+ }
+ PreviewsResourceLoadingHints* GetPreviewsResourceLoadingHints() const {
+ return resource_loading_hints_;
+ }
const SubstituteData& GetSubstituteData() const { return substitute_data_; }
@@ -208,9 +215,7 @@ class CORE_EXPORT DocumentLoader
void DispatchLinkHeaderPreloads(ViewportDescriptionWrapper*,
LinkLoader::MediaPreloadPolicy);
- Resource* StartPreload(Resource::Type,
- FetchParameters&,
- CSSPreloaderResourceClient*);
+ Resource* StartPreload(Resource::Type, FetchParameters&);
void SetServiceWorkerNetworkProvider(
std::unique_ptr<WebServiceWorkerNetworkProvider>);
@@ -222,8 +227,10 @@ class CORE_EXPORT DocumentLoader
return service_worker_network_provider_.get();
}
+ // Allows to specify the SourceLocation that triggered the navigation.
+ void SetSourceLocation(const WebSourceLocation& source_location);
+ void ResetSourceLocation();
std::unique_ptr<SourceLocation> CopySourceLocation() const;
- void SetSourceLocation(std::unique_ptr<SourceLocation>);
void LoadFailed(const ResourceError&);
@@ -268,7 +275,8 @@ class CORE_EXPORT DocumentLoader
void UpdateNavigationTimings(base::TimeTicks navigation_start_time,
base::TimeTicks redirect_start_time,
base::TimeTicks redirect_end_time,
- base::TimeTicks fetch_start_time);
+ base::TimeTicks fetch_start_time,
+ base::TimeTicks input_start_time);
UseCounter& GetUseCounter() { return use_counter_; }
protected:
@@ -364,6 +372,9 @@ class CORE_EXPORT DocumentLoader
Member<SubresourceFilter> subresource_filter_;
+ // Stores the resource loading hints for this document.
+ Member<PreviewsResourceLoadingHints> resource_loading_hints_;
+
// A reference to actual request used to create the data source.
// The only part of this request that should change is the url, and
// that only in the case of a same-document navigation.
diff --git a/chromium/third_party/blink/renderer/core/loader/document_threadable_loader.cc b/chromium/third_party/blink/renderer/core/loader/document_threadable_loader.cc
deleted file mode 100644
index f31e63d0913..00000000000
--- a/chromium/third_party/blink/renderer/core/loader/document_threadable_loader.cc
+++ /dev/null
@@ -1,1259 +0,0 @@
-/*
- * Copyright (C) 2011, 2012 Google Inc. All rights reserved.
- * Copyright (C) 2013, Intel Corporation
- *
- * 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/loader/document_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"
-#include "services/network/public/mojom/cors.mojom-blink.h"
-#include "services/network/public/mojom/fetch_api.mojom-blink.h"
-#include "third_party/blink/public/common/service_worker/service_worker_utils.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_cors.h"
-#include "third_party/blink/public/platform/web_security_origin.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/frame/frame_console.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/web_feature.h"
-#include "third_party/blink/renderer/core/inspector/console_message.h"
-#include "third_party/blink/renderer/core/inspector/inspector_network_agent.h"
-#include "third_party/blink/renderer/core/inspector/inspector_trace_events.h"
-#include "third_party/blink/renderer/core/loader/base_fetch_context.h"
-#include "third_party/blink/renderer/core/loader/document_threadable_loader_client.h"
-#include "third_party/blink/renderer/core/loader/frame_loader.h"
-#include "third_party/blink/renderer/core/loader/threadable_loader_client.h"
-#include "third_party/blink/renderer/core/loader/threadable_loading_context.h"
-#include "third_party/blink/renderer/core/probe/core_probes.h"
-#include "third_party/blink/renderer/platform/exported/wrapped_resource_request.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"
-#include "third_party/blink/renderer/platform/loader/fetch/fetch_parameters.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_loader.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/shared_buffer.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/wtf/assertions.h"
-
-namespace blink {
-
-namespace {
-
-// Fetch API Spec: https://fetch.spec.whatwg.org/#cors-preflight-fetch-0
-AtomicString CreateAccessControlRequestHeadersHeader(
- const HTTPHeaderMap& headers) {
- Vector<String> filtered_headers;
- for (const auto& header : headers) {
- // Exclude CORS-safelisted headers.
- if (CORS::IsCORSSafelistedHeader(header.key, header.value))
- continue;
- // Calling a deprecated function, but eventually this function,
- // |CreateAccessControlRequestHeadersHeader| will be removed.
- // When the request is from a Worker, referrer header was added by
- // WorkerThreadableLoader. But it should not be added to
- // Access-Control-Request-Headers header.
- if (DeprecatedEqualIgnoringCase(header.key, "referer"))
- continue;
- filtered_headers.push_back(header.key.DeprecatedLower());
- }
- if (!filtered_headers.size())
- return g_null_atom;
-
- // Sort header names lexicographically.
- std::sort(filtered_headers.begin(), filtered_headers.end(),
- WTF::CodePointCompareLessThan);
- StringBuilder header_buffer;
- for (const String& header : filtered_headers) {
- if (!header_buffer.IsEmpty())
- header_buffer.Append(",");
- header_buffer.Append(header);
- }
-
- return header_buffer.ToAtomicString();
-}
-
-class EmptyDataHandle final : public WebDataConsumerHandle {
- private:
- class EmptyDataReader final : public WebDataConsumerHandle::Reader {
- public:
- explicit EmptyDataReader(
- WebDataConsumerHandle::Client* client,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner)
- : factory_(this) {
- task_runner->PostTask(
- FROM_HERE, WTF::Bind(&EmptyDataReader::Notify, factory_.GetWeakPtr(),
- WTF::Unretained(client)));
- }
-
- private:
- Result BeginRead(const void** buffer,
- WebDataConsumerHandle::Flags,
- size_t* available) override {
- *available = 0;
- *buffer = nullptr;
- return kDone;
- }
- Result EndRead(size_t) override {
- return WebDataConsumerHandle::kUnexpectedError;
- }
- void Notify(WebDataConsumerHandle::Client* client) {
- client->DidGetReadable();
- }
- base::WeakPtrFactory<EmptyDataReader> factory_;
- };
-
- std::unique_ptr<Reader> ObtainReader(
- Client* client,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner) override {
- return std::make_unique<EmptyDataReader>(client, std::move(task_runner));
- }
- const char* DebugName() const override { return "EmptyDataHandle"; }
-};
-
-} // namespace
-
-// DetachedClient is a ThreadableLoaderClient for a "detached"
-// DocumentThreadableLoader. It's for fetch requests with keepalive set, so
-// it keeps itself alive during loading.
-class DocumentThreadableLoader::DetachedClient final
- : public GarbageCollectedFinalized<DetachedClient>,
- public ThreadableLoaderClient {
- public:
- explicit DetachedClient(DocumentThreadableLoader* loader)
- : self_keep_alive_(this), loader_(loader) {}
- ~DetachedClient() override {}
-
- void DidFinishLoading(unsigned long identifier) override {
- self_keep_alive_.Clear();
- }
- void DidFail(const ResourceError&) override { self_keep_alive_.Clear(); }
- void DidFailRedirectCheck() override { self_keep_alive_.Clear(); }
- void Trace(Visitor* visitor) { visitor->Trace(loader_); }
-
- private:
- SelfKeepAlive<DetachedClient> self_keep_alive_;
- // Keep it alive.
- const Member<DocumentThreadableLoader> loader_;
-};
-
-// Max number of CORS redirects handled in DocumentThreadableLoader. Same number
-// as net/url_request/url_request.cc, and same number as
-// https://fetch.spec.whatwg.org/#concept-http-fetch, Step 4.
-// FIXME: currently the number of redirects is counted and limited here and in
-// net/url_request/url_request.cc separately.
-static const int kMaxCORSRedirects = 20;
-
-// static
-void DocumentThreadableLoader::LoadResourceSynchronously(
- ThreadableLoadingContext& loading_context,
- const ResourceRequest& request,
- ThreadableLoaderClient& client,
- const ThreadableLoaderOptions& options,
- const ResourceLoaderOptions& resource_loader_options) {
- (new DocumentThreadableLoader(loading_context, &client, kLoadSynchronously,
- options, resource_loader_options))
- ->Start(request);
-}
-
-// static
-std::unique_ptr<ResourceRequest>
-DocumentThreadableLoader::CreateAccessControlPreflightRequest(
- const ResourceRequest& request,
- const SecurityOrigin* origin) {
- const KURL& request_url = request.Url();
-
- DCHECK(request_url.User().IsEmpty());
- DCHECK(request_url.Pass().IsEmpty());
-
- std::unique_ptr<ResourceRequest> preflight_request =
- std::make_unique<ResourceRequest>(request_url);
- preflight_request->SetHTTPMethod(HTTPNames::OPTIONS);
- preflight_request->SetHTTPHeaderField(
- HTTPNames::Access_Control_Request_Method, request.HttpMethod());
- preflight_request->SetPriority(request.Priority());
- preflight_request->SetRequestContext(request.GetRequestContext());
- preflight_request->SetFetchCredentialsMode(
- network::mojom::FetchCredentialsMode::kOmit);
- preflight_request->SetSkipServiceWorker(true);
- preflight_request->SetHTTPReferrer(
- Referrer(request.HttpReferrer(), request.GetReferrerPolicy()));
-
- if (request.IsExternalRequest()) {
- preflight_request->SetHTTPHeaderField(
- HTTPNames::Access_Control_Request_External, "true");
- }
-
- const AtomicString request_headers =
- CreateAccessControlRequestHeadersHeader(request.HttpHeaderFields());
- if (request_headers != g_null_atom) {
- preflight_request->SetHTTPHeaderField(
- HTTPNames::Access_Control_Request_Headers, request_headers);
- }
-
- if (origin)
- preflight_request->SetHTTPOrigin(origin);
-
- return preflight_request;
-}
-
-// static
-std::unique_ptr<ResourceRequest>
-DocumentThreadableLoader::CreateAccessControlPreflightRequestForTesting(
- const ResourceRequest& request) {
- return CreateAccessControlPreflightRequest(request, nullptr);
-}
-
-// static
-DocumentThreadableLoader* DocumentThreadableLoader::Create(
- ThreadableLoadingContext& loading_context,
- ThreadableLoaderClient* client,
- const ThreadableLoaderOptions& options,
- const ResourceLoaderOptions& resource_loader_options) {
- return new DocumentThreadableLoader(loading_context, client,
- kLoadAsynchronously, options,
- resource_loader_options);
-}
-
-DocumentThreadableLoader::DocumentThreadableLoader(
- ThreadableLoadingContext& loading_context,
- ThreadableLoaderClient* client,
- BlockingBehavior blocking_behavior,
- const ThreadableLoaderOptions& options,
- const ResourceLoaderOptions& resource_loader_options)
- : client_(client),
- loading_context_(&loading_context),
- options_(options),
- resource_loader_options_(resource_loader_options),
- out_of_blink_cors_(RuntimeEnabledFeatures::OutOfBlinkCORSEnabled()),
- cors_flag_(false),
- security_origin_(resource_loader_options_.security_origin),
- is_using_data_consumer_handle_(false),
- async_(blocking_behavior == kLoadAsynchronously),
- request_context_(WebURLRequest::kRequestContextUnspecified),
- fetch_request_mode_(network::mojom::FetchRequestMode::kSameOrigin),
- fetch_credentials_mode_(network::mojom::FetchCredentialsMode::kOmit),
- timeout_timer_(
- GetExecutionContext()->GetTaskRunner(TaskType::kNetworking),
- this,
- &DocumentThreadableLoader::DidTimeout),
- cors_redirect_limit_(0),
- redirect_mode_(network::mojom::FetchRedirectMode::kFollow),
- override_referrer_(false) {
- DCHECK(client);
-}
-
-void DocumentThreadableLoader::Start(const ResourceRequest& request) {
- // Setting an outgoing referer is only supported in the async code path.
- DCHECK(async_ || request.HttpReferrer().IsEmpty());
-
- bool cors_enabled =
- CORS::IsCORSEnabledRequestMode(request.GetFetchRequestMode());
-
- // kPreventPreflight can be used only when the CORS is enabled.
- DCHECK(request.CORSPreflightPolicy() ==
- network::mojom::CORSPreflightPolicy::kConsiderPreflight ||
- cors_enabled);
-
- if (cors_enabled)
- cors_redirect_limit_ = kMaxCORSRedirects;
-
- request_context_ = request.GetRequestContext();
- fetch_request_mode_ = request.GetFetchRequestMode();
- fetch_credentials_mode_ = request.GetFetchCredentialsMode();
- redirect_mode_ = request.GetFetchRedirectMode();
-
- if (request.GetFetchRequestMode() ==
- network::mojom::FetchRequestMode::kNoCORS) {
- SECURITY_CHECK(WebCORS::IsNoCORSAllowedContext(request_context_));
- } else {
- cors_flag_ = !GetSecurityOrigin()->CanRequest(request.Url());
- }
-
- // The CORS flag variable is not yet used at the step in the spec that
- // corresponds to this line, but divert |cors_flag_| here for convenience.
- if (cors_flag_ && request.GetFetchRequestMode() ==
- network::mojom::FetchRequestMode::kSameOrigin) {
- ThreadableLoaderClient* client = client_;
- Clear();
- ResourceError error = ResourceError::CancelledDueToAccessCheckError(
- request.Url(), ResourceRequestBlockedReason::kOther,
- CORS::GetErrorString(
- CORS::ErrorParameter::CreateForDisallowedByMode(request.Url())));
- GetExecutionContext()->AddConsoleMessage(ConsoleMessage::Create(
- kJSMessageSource, kErrorMessageLevel, error.LocalizedDescription()));
- client->DidFail(error);
- return;
- }
-
- request_started_ = CurrentTimeTicks();
-
- // Save any headers on the request here. If this request redirects
- // cross-origin, we cancel the old request create a new one, and copy these
- // headers.
- request_headers_ = request.HttpHeaderFields();
-
- ResourceRequest new_request(request);
-
- // Set the service worker mode to none if "bypass for network" in DevTools is
- // enabled.
- bool should_bypass_service_worker = false;
- probe::shouldBypassServiceWorker(GetExecutionContext(),
- &should_bypass_service_worker);
- if (should_bypass_service_worker)
- new_request.SetSkipServiceWorker(true);
-
- // In S13nServiceWorker, if the controller service worker has no fetch event
- // handler, it's skipped entirely, so we should treat that case the same as
- // having no controller. In non-S13nServiceWorker, we can't do that since we
- // don't know which service worker will handle the request since it's
- // determined on the browser process and skipWaiting() can happen in the
- // meantime.
- //
- // TODO(crbug.com/715640): When non-S13nServiceWorker is removed,
- // is_controlled_by_service_worker is the same as
- // ControllerServiceWorkerMode::kControlled, so this code can be simplified.
- bool is_controlled_by_service_worker = false;
- switch (
- loading_context_->GetResourceFetcher()->IsControlledByServiceWorker()) {
- case blink::mojom::ControllerServiceWorkerMode::kControlled:
- is_controlled_by_service_worker = true;
- break;
- case blink::mojom::ControllerServiceWorkerMode::kNoFetchEventHandler:
- if (ServiceWorkerUtils::IsServicificationEnabled())
- is_controlled_by_service_worker = false;
- else
- is_controlled_by_service_worker = true;
- break;
- case blink::mojom::ControllerServiceWorkerMode::kNoController:
- is_controlled_by_service_worker = false;
- break;
- }
-
- // Process the CORS protocol inside the DocumentThreadableLoader for the
- // following cases:
- //
- // - When the request is sync or the protocol is unsupported since we can
- // assume that any service worker (SW) is skipped for such requests by
- // content/ code.
- // - When |skip_service_worker| is true, any SW will be skipped.
- // - If we're not yet controlled by a SW, then we're sure that this
- // request won't be intercepted by a SW. In case we end up with
- // sending a CORS preflight request, the actual request to be sent later
- // may be intercepted. This is taken care of in LoadPreflightRequest() by
- // setting |skip_service_worker| to true.
- //
- // From the above analysis, you can see that the request can never be
- // intercepted by a SW inside this if-block. It's because:
- // - |skip_service_worker| needs to be false, and
- // - we're controlled by a SW at this point
- // to allow a SW to intercept the request. Even when the request gets issued
- // asynchronously after performing the CORS preflight, it doesn't get
- // intercepted since LoadPreflightRequest() sets the flag to kNone in advance.
- if (!async_ || new_request.GetSkipServiceWorker() ||
- !SchemeRegistry::ShouldTreatURLSchemeAsAllowingServiceWorkers(
- new_request.Url().Protocol()) ||
- !is_controlled_by_service_worker) {
- DispatchInitialRequest(new_request);
- return;
- }
-
- if (CORS::IsCORSEnabledRequestMode(request.GetFetchRequestMode())) {
- // 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);
- // Skip the service worker for the fallback request.
- fallback_request_for_service_worker_.SetSkipServiceWorker(true);
- }
-
- LoadRequest(new_request, resource_loader_options_);
-}
-
-void DocumentThreadableLoader::DispatchInitialRequest(
- ResourceRequest& request) {
- if (out_of_blink_cors_ || (!request.IsExternalRequest() && !cors_flag_)) {
- LoadRequest(request, resource_loader_options_);
- return;
- }
-
- DCHECK(CORS::IsCORSEnabledRequestMode(request.GetFetchRequestMode()) ||
- request.IsExternalRequest());
-
- MakeCrossOriginAccessRequest(request);
-}
-
-void DocumentThreadableLoader::PrepareCrossOriginRequest(
- ResourceRequest& request) const {
- if (GetSecurityOrigin())
- request.SetHTTPOrigin(GetSecurityOrigin());
- if (override_referrer_)
- request.SetHTTPReferrer(referrer_after_redirect_);
-}
-
-void DocumentThreadableLoader::LoadPreflightRequest(
- const ResourceRequest& actual_request,
- const ResourceLoaderOptions& actual_options) {
- std::unique_ptr<ResourceRequest> preflight_request =
- CreateAccessControlPreflightRequest(actual_request, GetSecurityOrigin());
-
- actual_request_ = actual_request;
- actual_options_ = actual_options;
-
- // Explicitly set |skip_service_worker| to true here. Although the page is
- // not controlled by a SW at this point, a new SW may be controlling the
- // page when this actual request gets sent later. We should not send the
- // actual request to the SW. See https://crbug.com/604583.
- actual_request_.SetSkipServiceWorker(true);
-
- // Create a ResourceLoaderOptions for preflight.
- ResourceLoaderOptions preflight_options = actual_options;
-
- LoadRequest(*preflight_request, preflight_options);
-}
-
-void DocumentThreadableLoader::MakeCrossOriginAccessRequest(
- const ResourceRequest& request) {
- DCHECK(CORS::IsCORSEnabledRequestMode(request.GetFetchRequestMode()) ||
- request.IsExternalRequest());
- DCHECK(client_);
- DCHECK(!GetResource());
-
- // Cross-origin requests are only allowed certain registered schemes. We would
- // catch this when checking response headers later, but there is no reason to
- // send a request, preflighted or not, that's guaranteed to be denied.
- if (!SchemeRegistry::ShouldTreatURLSchemeAsCORSEnabled(
- request.Url().Protocol())) {
- DispatchDidFailAccessControlCheck(
- ResourceError::CancelledDueToAccessCheckError(
- request.Url(), ResourceRequestBlockedReason::kOther,
- String::Format(
- "Cross origin requests are only supported for protocol "
- "schemes: %s.",
- SchemeRegistry::ListOfCORSEnabledURLSchemes().Ascii().data())));
- return;
- }
-
- // Non-secure origins may not make "external requests":
- // https://wicg.github.io/cors-rfc1918/#integration-fetch
- String error_message;
- if (!GetExecutionContext()->IsSecureContext(error_message) &&
- request.IsExternalRequest()) {
- DispatchDidFailAccessControlCheck(
- ResourceError::CancelledDueToAccessCheckError(
- request.Url(), ResourceRequestBlockedReason::kOrigin,
- "Requests to internal network resources are not allowed "
- "from non-secure contexts (see https://goo.gl/Y0ZkNV). "
- "This is an experimental restriction which is part of "
- "'https://mikewest.github.io/cors-rfc1918/'."));
- return;
- }
-
- ResourceRequest cross_origin_request(request);
- ResourceLoaderOptions cross_origin_options(resource_loader_options_);
-
- cross_origin_request.RemoveUserAndPassFromURL();
-
- // Enforce the CORS preflight for checking the Access-Control-Allow-External
- // header. The CORS preflight cache doesn't help for this purpose.
- if (request.IsExternalRequest()) {
- LoadPreflightRequest(cross_origin_request, cross_origin_options);
- return;
- }
-
- if (request.GetFetchRequestMode() !=
- network::mojom::FetchRequestMode::kCORSWithForcedPreflight) {
- if (request.CORSPreflightPolicy() ==
- network::mojom::CORSPreflightPolicy::kPreventPreflight) {
- PrepareCrossOriginRequest(cross_origin_request);
- LoadRequest(cross_origin_request, cross_origin_options);
- return;
- }
-
- DCHECK_EQ(request.CORSPreflightPolicy(),
- network::mojom::CORSPreflightPolicy::kConsiderPreflight);
-
- // We use ContainsOnlyCORSSafelistedOrForbiddenHeaders() here since
- // |request| may have been modified in the process of loading (not from
- // the user's input). For example, referrer. We need to accept them. For
- // security, we must reject forbidden headers/methods at the point we
- // accept user's input. Not here.
- if (CORS::IsCORSSafelistedMethod(request.HttpMethod()) &&
- CORS::ContainsOnlyCORSSafelistedOrForbiddenHeaders(
- request.HttpHeaderFields())) {
- PrepareCrossOriginRequest(cross_origin_request);
- LoadRequest(cross_origin_request, cross_origin_options);
- return;
- }
- }
-
- // Now, we need to check that the request passes the CORS preflight either by
- // issuing a CORS preflight or based on an entry in the CORS preflight cache.
-
- bool should_ignore_preflight_cache = false;
- // Prevent use of the CORS preflight cache when instructed by the DevTools
- // not to use caches.
- probe::shouldForceCORSPreflight(GetExecutionContext(),
- &should_ignore_preflight_cache);
- if (should_ignore_preflight_cache ||
- !CORS::CheckIfRequestCanSkipPreflight(
- GetSecurityOrigin()->ToString(), cross_origin_request.Url(),
- cross_origin_request.GetFetchCredentialsMode(),
- cross_origin_request.HttpMethod(),
- cross_origin_request.HttpHeaderFields())) {
- LoadPreflightRequest(cross_origin_request, cross_origin_options);
- return;
- }
-
- // We don't want any requests that could involve a CORS preflight to get
- // intercepted by a foreign SW, even if we have the result of the preflight
- // cached already. See https://crbug.com/674370.
- cross_origin_request.SetSkipServiceWorker(true);
-
- PrepareCrossOriginRequest(cross_origin_request);
- LoadRequest(cross_origin_request, cross_origin_options);
-}
-
-DocumentThreadableLoader::~DocumentThreadableLoader() {
- // |client_| is a raw pointer and having a non-null |client_| here probably
- // means UaF.
- // In the detached case, |this| is held by DetachedClient defined above, but
- // SelfKeepAlive in DetachedClient is forcibly cancelled on worker thread
- // termination. We can safely ignore this case.
- CHECK(!client_ || detached_);
- DCHECK(!GetResource());
-}
-
-void DocumentThreadableLoader::OverrideTimeout(
- unsigned long timeout_milliseconds) {
- DCHECK(async_);
-
- // |m_requestStartedSeconds| == 0.0 indicates loading is already finished and
- // |m_timeoutTimer| is already stopped, and thus we do nothing for such cases.
- // See https://crbug.com/551663 for details.
- if (request_started_ <= TimeTicks())
- return;
-
- timeout_timer_.Stop();
- // At the time of this method's implementation, it is only ever called by
- // XMLHttpRequest, when the timeout attribute is set after sending the
- // request.
- //
- // The XHR request says to resolve the time relative to when the request
- // was initially sent, however other uses of this method may need to
- // behave differently, in which case this should be re-arranged somehow.
- if (timeout_milliseconds) {
- TimeDelta elapsed_time = CurrentTimeTicks() - request_started_;
- TimeDelta next_fire = TimeDelta::FromMilliseconds(timeout_milliseconds);
- TimeDelta resolved_time = std::max(next_fire - elapsed_time, TimeDelta());
- timeout_timer_.StartOneShot(resolved_time, FROM_HERE);
- }
-}
-
-void DocumentThreadableLoader::Cancel() {
- // Cancel can re-enter, and therefore |resource()| might be null here as a
- // result.
- if (!client_ || !GetResource()) {
- Clear();
- return;
- }
-
- DispatchDidFail(ResourceError::CancelledError(GetResource()->Url()));
-}
-
-void DocumentThreadableLoader::Detach() {
- Resource* resource = GetResource();
- if (!resource)
- return;
- detached_ = true;
- client_ = new DetachedClient(this);
-}
-
-void DocumentThreadableLoader::SetDefersLoading(bool value) {
- if (GetResource() && GetResource()->Loader())
- GetResource()->Loader()->SetDefersLoading(value);
-}
-
-void DocumentThreadableLoader::Clear() {
- client_ = nullptr;
- timeout_timer_.Stop();
- request_started_ = TimeTicks();
- if (GetResource())
- checker_.WillRemoveClient();
- ClearResource();
-}
-
-// In this method, we can clear |request| to tell content::WebURLLoaderImpl of
-// Chromium not to follow the redirect. This works only when this method is
-// called by RawResource::willSendRequest(). If called by
-// RawResource::didAddClient(), clearing |request| won't be propagated to
-// content::WebURLLoaderImpl. So, this loader must also get detached from the
-// resource by calling clearResource().
-// TODO(toyoshim): Implement OOR-CORS mode specific redirect code.
-bool DocumentThreadableLoader::RedirectReceived(
- Resource* resource,
- const ResourceRequest& new_request,
- const ResourceResponse& redirect_response) {
- DCHECK(client_);
- DCHECK_EQ(resource, GetResource());
-
- checker_.RedirectReceived();
-
- const KURL& new_url = new_request.Url();
- const KURL& original_url = redirect_response.Url();
-
- if (!actual_request_.IsNull()) {
- DCHECK(!out_of_blink_cors_);
- ReportResponseReceived(resource->Identifier(), redirect_response);
-
- HandlePreflightFailure(
- original_url, CORS::GetErrorString(
- CORS::ErrorParameter::CreateForDisallowedRedirect()));
-
- return false;
- }
-
- if (redirect_mode_ == network::mojom::FetchRedirectMode::kManual) {
- // We use |redirect_mode_| to check the original redirect mode.
- // |new_request| is a new request for redirect. So we don't set the
- // redirect mode of it in WebURLLoaderImpl::Context::OnReceivedRedirect().
- DCHECK(new_request.UseStreamOnResponse());
- // There is no need to read the body of redirect response because there is
- // no way to read the body of opaque-redirect filtered response's internal
- // response.
- // TODO(horo): If we support any API which expose the internal body, we will
- // have to read the body. And also HTTPCache changes will be needed because
- // it doesn't store the body of redirect responses.
- ResponseReceived(resource, redirect_response,
- std::make_unique<EmptyDataHandle>());
-
- if (client_) {
- DCHECK(actual_request_.IsNull());
- NotifyFinished(resource);
- }
-
- return false;
- }
-
- if (redirect_mode_ == network::mojom::FetchRedirectMode::kError) {
- ThreadableLoaderClient* client = client_;
- Clear();
- client->DidFailRedirectCheck();
-
- return false;
- }
-
- if (out_of_blink_cors_) {
- client_->DidReceiveRedirectTo(new_url);
- if (client_->IsDocumentThreadableLoaderClient()) {
- return static_cast<DocumentThreadableLoaderClient*>(client_)
- ->WillFollowRedirect(new_url, redirect_response);
- }
- return true;
- }
-
- // Allow same origin requests to continue after allowing clients to audit the
- // redirect.
- if (IsAllowedRedirect(new_request.GetFetchRequestMode(), new_url)) {
- client_->DidReceiveRedirectTo(new_url);
- if (client_->IsDocumentThreadableLoaderClient()) {
- return static_cast<DocumentThreadableLoaderClient*>(client_)
- ->WillFollowRedirect(new_url, redirect_response);
- }
- return true;
- }
-
- if (cors_redirect_limit_ <= 0) {
- ThreadableLoaderClient* client = client_;
- Clear();
- client->DidFailRedirectCheck();
- return false;
- }
-
- --cors_redirect_limit_;
-
- probe::didReceiveCORSRedirectResponse(
- GetExecutionContext(), resource->Identifier(),
- GetDocument() && GetDocument()->GetFrame()
- ? GetDocument()->GetFrame()->Loader().GetDocumentLoader()
- : nullptr,
- redirect_response, resource);
-
- base::Optional<network::mojom::CORSError> redirect_error =
- CORS::CheckRedirectLocation(new_url);
- if (redirect_error) {
- DispatchDidFailAccessControlCheck(
- ResourceError::CancelledDueToAccessCheckError(
- original_url, ResourceRequestBlockedReason::kOther,
- CORS::GetErrorString(CORS::ErrorParameter::CreateForRedirectCheck(
- *redirect_error, original_url, new_url))));
- return false;
- }
-
- if (cors_flag_) {
- // The redirect response must pass the access control check if the CORS
- // flag is set.
- base::Optional<network::CORSErrorStatus> access_error = CORS::CheckAccess(
- original_url, redirect_response.HttpStatusCode(),
- redirect_response.HttpHeaderFields(),
- new_request.GetFetchCredentialsMode(), *GetSecurityOrigin());
- if (access_error) {
- DispatchDidFailAccessControlCheck(
- ResourceError::CancelledDueToAccessCheckError(
- original_url, ResourceRequestBlockedReason::kOther,
- CORS::GetErrorString(CORS::ErrorParameter::CreateForAccessCheck(
- *access_error, original_url,
- redirect_response.HttpStatusCode(), *GetSecurityOrigin(),
- request_context_, new_url))));
- return false;
- }
- }
-
- client_->DidReceiveRedirectTo(new_url);
-
- // FIXME: consider combining this with CORS redirect handling performed by
- // CrossOriginAccessControl::handleRedirect().
- if (GetResource())
- checker_.WillRemoveClient();
- ClearResource();
-
- // If
- // - CORS flag is set, and
- // - the origin of the redirect target URL is not same origin with the origin
- // of the current request's URL
- // set the source origin to a unique opaque origin.
- //
- // See https://fetch.spec.whatwg.org/#http-redirect-fetch.
- if (cors_flag_) {
- scoped_refptr<const SecurityOrigin> original_origin =
- SecurityOrigin::Create(original_url);
- scoped_refptr<const SecurityOrigin> new_origin =
- SecurityOrigin::Create(new_url);
- if (!original_origin->IsSameSchemeHostPort(new_origin.get()))
- security_origin_ = SecurityOrigin::CreateUniqueOpaque();
- }
-
- // Set |cors_flag_| so that further logic (corresponds to the main fetch in
- // the spec) will be performed with CORS flag set.
- // See https://fetch.spec.whatwg.org/#http-redirect-fetch.
- cors_flag_ = true;
-
- // Save the referrer to use when following the redirect.
- override_referrer_ = true;
- referrer_after_redirect_ =
- Referrer(new_request.HttpReferrer(), new_request.GetReferrerPolicy());
-
- ResourceRequest cross_origin_request(new_request);
-
- // 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.ClearHTTPOrigin();
- cross_origin_request.ClearHTTPUserAgent();
- // Add any request headers which we previously saved from the
- // original request.
- for (const auto& header : request_headers_)
- cross_origin_request.SetHTTPHeaderField(header.key, header.value);
- MakeCrossOriginAccessRequest(cross_origin_request);
-
- return false;
-}
-
-void DocumentThreadableLoader::RedirectBlocked() {
- checker_.RedirectBlocked();
-
- // Tells the client that a redirect was received but not followed (for an
- // unknown reason).
- ThreadableLoaderClient* client = client_;
- Clear();
- client->DidFailRedirectCheck();
-}
-
-void DocumentThreadableLoader::DataSent(
- Resource* resource,
- unsigned long long bytes_sent,
- unsigned long long total_bytes_to_be_sent) {
- DCHECK(client_);
- DCHECK_EQ(resource, GetResource());
- DCHECK(async_);
-
- checker_.DataSent();
- client_->DidSendData(bytes_sent, total_bytes_to_be_sent);
-}
-
-void DocumentThreadableLoader::DataDownloaded(Resource* resource,
- int data_length) {
- DCHECK(client_);
- DCHECK_EQ(resource, GetResource());
- DCHECK(actual_request_.IsNull());
-
- checker_.DataDownloaded();
- client_->DidDownloadData(data_length);
-}
-
-void DocumentThreadableLoader::DidReceiveResourceTiming(
- Resource* resource,
- const ResourceTimingInfo& info) {
- DCHECK(client_);
- DCHECK_EQ(resource, GetResource());
-
- client_->DidReceiveResourceTiming(info);
-}
-
-void DocumentThreadableLoader::DidDownloadToBlob(
- Resource* resource,
- scoped_refptr<BlobDataHandle> blob) {
- DCHECK(client_);
- DCHECK_EQ(resource, GetResource());
-
- checker_.DidDownloadToBlob();
- client_->DidDownloadToBlob(std::move(blob));
-}
-
-
-void DocumentThreadableLoader::HandlePreflightResponse(
- const ResourceResponse& response) {
- base::Optional<network::CORSErrorStatus> cors_error_status =
- CORS::CheckPreflightAccess(response.Url(), response.HttpStatusCode(),
- response.HttpHeaderFields(),
- actual_request_.GetFetchCredentialsMode(),
- *GetSecurityOrigin());
- if (cors_error_status) {
- HandlePreflightFailure(
- response.Url(),
- CORS::GetErrorString(CORS::ErrorParameter::CreateForAccessCheck(
- *cors_error_status, response.Url(), 0 /* status_code */,
- *GetSecurityOrigin(), request_context_)));
- return;
- }
-
- base::Optional<network::mojom::CORSError> preflight_error =
- CORS::CheckPreflight(response.HttpStatusCode());
- if (preflight_error) {
- HandlePreflightFailure(
- response.Url(), CORS::GetErrorString(
- CORS::ErrorParameter::CreateForPreflightStatusCheck(
- response.HttpStatusCode())));
- return;
- }
-
- if (actual_request_.IsExternalRequest()) {
- base::Optional<network::CORSErrorStatus> external_preflight_status =
- CORS::CheckExternalPreflight(response.HttpHeaderFields());
- if (external_preflight_status) {
- HandlePreflightFailure(
- response.Url(),
- CORS::GetErrorString(
- CORS::ErrorParameter::CreateForExternalPreflightCheck(
- *external_preflight_status)));
- return;
- }
- }
-
- String access_control_error_description;
- if (!CORS::EnsurePreflightResultAndCacheOnSuccess(
- response.HttpHeaderFields(), GetSecurityOrigin()->ToString(),
- actual_request_.Url(), actual_request_.HttpMethod(),
- actual_request_.HttpHeaderFields(),
- actual_request_.GetFetchCredentialsMode(),
- &access_control_error_description)) {
- HandlePreflightFailure(response.Url(), access_control_error_description);
- }
-}
-
-void DocumentThreadableLoader::ReportResponseReceived(
- unsigned long identifier,
- const ResourceResponse& response) {
- LocalFrame* frame = GetDocument() ? GetDocument()->GetFrame() : nullptr;
- if (!frame)
- return;
- DocumentLoader* loader = frame->Loader().GetDocumentLoader();
- probe::didReceiveResourceResponse(GetExecutionContext(), identifier, loader,
- response, GetResource());
- frame->Console().ReportResourceResponseReceived(loader, identifier, response);
-}
-
-void DocumentThreadableLoader::ResponseReceived(
- Resource* resource,
- const ResourceResponse& response,
- std::unique_ptr<WebDataConsumerHandle> handle) {
- DCHECK_EQ(resource, GetResource());
- DCHECK(client_);
-
- checker_.ResponseReceived();
-
- if (handle)
- is_using_data_consumer_handle_ = true;
-
- // TODO(toyoshim): Support OOR-CORS preflight and Service Worker case.
- // Note that CORS-preflight is usually handled in the Network Service side,
- // but still done in Blink side when it is needed on redirects.
- // https://crbug.com/736308.
- if (out_of_blink_cors_ && !response.WasFetchedViaServiceWorker()) {
- DCHECK(actual_request_.IsNull());
- fallback_request_for_service_worker_ = ResourceRequest();
- client_->DidReceiveResponse(resource->Identifier(), response,
- std::move(handle));
- return;
- }
-
- // Code path for legacy Blink CORS.
- if (!actual_request_.IsNull()) {
- ReportResponseReceived(resource->Identifier(), response);
- HandlePreflightResponse(response);
- return;
- }
-
- if (response.WasFetchedViaServiceWorker()) {
- if (response.WasFallbackRequiredByServiceWorker()) {
- // At this point we must have m_fallbackRequestForServiceWorker. (For
- // SharedWorker the request won't be CORS or CORS-with-preflight,
- // therefore fallback-to-network is handled in the browser process when
- // the ServiceWorker does not call respondWith().)
- DCHECK(!fallback_request_for_service_worker_.IsNull());
- ReportResponseReceived(resource->Identifier(), response);
- LoadFallbackRequestForServiceWorker();
- return;
- }
-
- // It's possible that we issue a fetch with request with non "no-cors"
- // mode but get an opaque filtered response if a service worker is involved.
- // We dispatch a CORS failure for the case.
- // TODO(yhirano): This is probably not spec conformant. Fix it after
- // https://github.com/w3c/preload/issues/100 is addressed.
- if (fetch_request_mode_ != network::mojom::FetchRequestMode::kNoCORS &&
- response.ResponseTypeViaServiceWorker() ==
- network::mojom::FetchResponseType::kOpaque) {
- DispatchDidFailAccessControlCheck(
- ResourceError::CancelledDueToAccessCheckError(
- response.Url(), ResourceRequestBlockedReason::kOther,
- CORS::GetErrorString(
- CORS::ErrorParameter::CreateForInvalidResponse(
- response.Url(), *GetSecurityOrigin()))));
- return;
- }
-
- fallback_request_for_service_worker_ = ResourceRequest();
- client_->DidReceiveResponse(resource->Identifier(), response,
- std::move(handle));
- return;
- }
-
- // 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
- // 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
- // loadFallbackRequestForServiceWorker().
- DCHECK(fallback_request_for_service_worker_.IsNull() ||
- GetSecurityOrigin()->CanRequest(
- fallback_request_for_service_worker_.Url()));
- fallback_request_for_service_worker_ = ResourceRequest();
-
- if (CORS::IsCORSEnabledRequestMode(fetch_request_mode_) && cors_flag_) {
- base::Optional<network::CORSErrorStatus> access_error = CORS::CheckAccess(
- response.Url(), response.HttpStatusCode(), response.HttpHeaderFields(),
- fetch_credentials_mode_, *GetSecurityOrigin());
- if (access_error) {
- ReportResponseReceived(resource->Identifier(), response);
- DispatchDidFailAccessControlCheck(
- ResourceError::CancelledDueToAccessCheckError(
- response.Url(), ResourceRequestBlockedReason::kOther,
- CORS::GetErrorString(CORS::ErrorParameter::CreateForAccessCheck(
- *access_error, response.Url(), response.HttpStatusCode(),
- *GetSecurityOrigin(), request_context_))));
- return;
- }
- }
-
- client_->DidReceiveResponse(resource->Identifier(), response,
- std::move(handle));
-}
-
-void DocumentThreadableLoader::SetSerializedCachedMetadata(Resource*,
- const char* data,
- size_t size) {
- checker_.SetSerializedCachedMetadata();
-
- if (!actual_request_.IsNull())
- return;
- client_->DidReceiveCachedMetadata(data, size);
-}
-
-void DocumentThreadableLoader::DataReceived(Resource* resource,
- const char* data,
- size_t data_length) {
- DCHECK_EQ(resource, GetResource());
- DCHECK(client_);
-
- checker_.DataReceived();
-
- if (is_using_data_consumer_handle_)
- return;
-
- // Preflight data should be invisible to clients.
- if (!actual_request_.IsNull())
- return;
-
- DCHECK(fallback_request_for_service_worker_.IsNull());
-
- // TODO(junov): Fix the ThreadableLoader ecosystem to use size_t. Until then,
- // we use safeCast to trap potential overflows.
- client_->DidReceiveData(data, SafeCast<unsigned>(data_length));
-}
-
-void DocumentThreadableLoader::NotifyFinished(Resource* resource) {
- DCHECK(client_);
- DCHECK_EQ(resource, GetResource());
-
- checker_.NotifyFinished(resource);
-
- // Don't throw an exception for failed sync local file loads.
- // TODO(japhet): This logic has been moved around but unchanged since 2007.
- // Tested by fast/xmlhttprequest/xmlhttprequest-missing-file-exception.html
- // Do we still need this?
- bool is_sync_to_local_file = resource->Url().IsLocalFile() && !async_;
-
- if (resource->ErrorOccurred() && !is_sync_to_local_file) {
- DispatchDidFail(resource->GetResourceError());
- return;
- }
-
- DCHECK(fallback_request_for_service_worker_.IsNull());
-
- if (!actual_request_.IsNull()) {
- DCHECK(actual_request_.IsExternalRequest() || cors_flag_);
- LoadActualRequest();
- return;
- }
-
- ThreadableLoaderClient* client = client_;
- // Protect the resource in |didFinishLoading| in order not to release the
- // downloaded file.
- Persistent<Resource> protect = GetResource();
- Clear();
- client->DidFinishLoading(resource->Identifier());
-}
-
-void DocumentThreadableLoader::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
- // 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.
- DCHECK(client_);
-
- DispatchDidFail(ResourceError::TimeoutError(GetResource()->Url()));
-}
-
-void DocumentThreadableLoader::LoadFallbackRequestForServiceWorker() {
- if (GetResource())
- checker_.WillRemoveClient();
- ClearResource();
- ResourceRequest fallback_request(fallback_request_for_service_worker_);
- fallback_request_for_service_worker_ = ResourceRequest();
- DispatchInitialRequest(fallback_request);
-}
-
-void DocumentThreadableLoader::LoadActualRequest() {
- ResourceRequest actual_request = actual_request_;
- ResourceLoaderOptions actual_options = actual_options_;
- actual_request_ = ResourceRequest();
- actual_options_ = ResourceLoaderOptions();
-
- if (GetResource())
- checker_.WillRemoveClient();
- ClearResource();
-
- PrepareCrossOriginRequest(actual_request);
- LoadRequest(actual_request, actual_options);
-}
-
-void DocumentThreadableLoader::HandlePreflightFailure(
- const KURL& url,
- const String& error_description) {
- // Prevent NotifyFinished() from bypassing access check.
- actual_request_ = ResourceRequest();
-
- DispatchDidFailAccessControlCheck(
- ResourceError::CancelledDueToAccessCheckError(
- url, ResourceRequestBlockedReason::kOther, error_description));
-}
-
-void DocumentThreadableLoader::DispatchDidFailAccessControlCheck(
- const ResourceError& error) {
- const String message = "Failed to load " + error.FailingURL() + ": " +
- error.LocalizedDescription();
- GetExecutionContext()->AddConsoleMessage(
- ConsoleMessage::Create(kJSMessageSource, kErrorMessageLevel, message));
-
- ThreadableLoaderClient* client = client_;
- Clear();
- client->DidFail(error);
-}
-
-void DocumentThreadableLoader::DispatchDidFail(const ResourceError& error) {
- if (error.CORSErrorStatus()) {
- DCHECK(out_of_blink_cors_);
- // TODO(toyoshim): Should consider to pass correct arguments instead of
- // KURL(), and 0 to GetErrorString().
- // We still need plumbing some more information.
- GetExecutionContext()->AddConsoleMessage(ConsoleMessage::Create(
- kJSMessageSource, kErrorMessageLevel,
- "Failed to load " + error.FailingURL() + ": " +
- CORS::GetErrorString(CORS::ErrorParameter::Create(
- *error.CORSErrorStatus(),
- KURL(error.FailingURL()), KURL(), 0,
- *GetSecurityOrigin(), request_context_))
- .Utf8()
- .data()));
- }
- ThreadableLoaderClient* client = client_;
- Clear();
- client->DidFail(error);
-}
-
-
-void DocumentThreadableLoader::LoadRequest(
- ResourceRequest& request,
- ResourceLoaderOptions resource_loader_options) {
- resource_loader_options.cors_handling_by_resource_fetcher =
- kDisableCORSHandlingByResourceFetcher;
-
- bool allow_stored_credentials = false;
- switch (request.GetFetchCredentialsMode()) {
- case network::mojom::FetchCredentialsMode::kOmit:
- break;
- case network::mojom::FetchCredentialsMode::kSameOrigin:
- // TODO(toyoshim): It's wrong to use |cors_flag| here. Fix it to use the
- // response tainting.
- //
- // TODO(toyoshim): The credentials mode must work even when the "no-cors"
- // mode is in use. See the following issues:
- // - https://github.com/whatwg/fetch/issues/130
- // - https://github.com/whatwg/fetch/issues/169
- allow_stored_credentials = !cors_flag_;
- break;
- case network::mojom::FetchCredentialsMode::kInclude:
- allow_stored_credentials = true;
- break;
- }
- request.SetAllowStoredCredentials(allow_stored_credentials);
-
- resource_loader_options.security_origin = security_origin_;
-
- if (!actual_request_.IsNull())
- resource_loader_options.data_buffering_policy = kBufferData;
-
- TimeDelta timeout =
- TimeDelta::FromMilliseconds(options_.timeout_milliseconds);
- if (options_.timeout_milliseconds > 0) {
- if (!async_) {
- request.SetTimeoutInterval(timeout);
- } else if (!timeout_timer_.IsActive()) {
- // The timer can be active if this is the actual request of a
- // CORS-with-preflight request.
- timeout_timer_.StartOneShot(timeout, FROM_HERE);
- }
- }
-
- FetchParameters new_params(request, resource_loader_options);
- if (request.GetFetchRequestMode() ==
- network::mojom::FetchRequestMode::kNoCORS) {
- new_params.SetOriginRestriction(FetchParameters::kNoOriginRestriction);
- }
- DCHECK(!GetResource());
-
- checker_.WillAddClient();
- ResourceFetcher* fetcher = loading_context_->GetResourceFetcher();
- if (request.GetRequestContext() == WebURLRequest::kRequestContextVideo ||
- request.GetRequestContext() == WebURLRequest::kRequestContextAudio) {
- DCHECK(async_);
- RawResource::FetchMedia(new_params, fetcher, this);
- } else if (request.GetRequestContext() ==
- WebURLRequest::kRequestContextManifest) {
- DCHECK(async_);
- RawResource::FetchManifest(new_params, fetcher, this);
- } else if (async_) {
- RawResource::Fetch(new_params, fetcher, this);
- } else {
- RawResource::FetchSynchronously(new_params, fetcher, this);
- }
-}
-
-bool DocumentThreadableLoader::IsAllowedRedirect(
- network::mojom::FetchRequestMode fetch_request_mode,
- const KURL& url) const {
- if (fetch_request_mode == network::mojom::FetchRequestMode::kNoCORS)
- return true;
-
- return !cors_flag_ && GetSecurityOrigin()->CanRequest(url);
-}
-
-const SecurityOrigin* DocumentThreadableLoader::GetSecurityOrigin() const {
- return security_origin_
- ? security_origin_.get()
- : loading_context_->GetFetchContext()->GetSecurityOrigin();
-}
-
-Document* DocumentThreadableLoader::GetDocument() const {
- ExecutionContext* context = GetExecutionContext();
- if (context->IsDocument())
- return ToDocument(context);
- return nullptr;
-}
-
-ExecutionContext* DocumentThreadableLoader::GetExecutionContext() const {
- DCHECK(loading_context_);
- return loading_context_->GetExecutionContext();
-}
-
-void DocumentThreadableLoader::Trace(blink::Visitor* visitor) {
- visitor->Trace(loading_context_);
- ThreadableLoader::Trace(visitor);
- RawResourceClient::Trace(visitor);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/loader/document_threadable_loader.h b/chromium/third_party/blink/renderer/core/loader/document_threadable_loader.h
deleted file mode 100644
index 2082201e8a1..00000000000
--- a/chromium/third_party/blink/renderer/core/loader/document_threadable_loader.h
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright (C) 2009, 2012 Google Inc. All rights reserved.
- * Copyright (C) 2013, Intel Corporation
- *
- * 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_LOADER_DOCUMENT_THREADABLE_LOADER_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_DOCUMENT_THREADABLE_LOADER_H_
-
-#include <memory>
-#include "services/network/public/mojom/fetch_api.mojom-blink.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/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/loader/fetch/raw_resource.h"
-#include "third_party/blink/renderer/platform/loader/fetch/resource_error.h"
-#include "third_party/blink/renderer/platform/network/http_header_map.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/forward.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-#include "third_party/blink/renderer/platform/wtf/time.h"
-
-namespace blink {
-
-class Document;
-class KURL;
-class ResourceRequest;
-class SecurityOrigin;
-class ThreadableLoaderClient;
-class ThreadableLoadingContext;
-
-// TODO(horo): We are using this class not only in documents, but also in
-// workers. We should change the name to ThreadableLoaderImpl.
-class CORE_EXPORT DocumentThreadableLoader final : public ThreadableLoader,
- private RawResourceClient {
- USING_GARBAGE_COLLECTED_MIXIN(DocumentThreadableLoader);
-
- public:
- static void LoadResourceSynchronously(ThreadableLoadingContext&,
- const ResourceRequest&,
- ThreadableLoaderClient&,
- const ThreadableLoaderOptions&,
- const ResourceLoaderOptions&);
-
- // Exposed for testing. Code outside this class should not call this function.
- static std::unique_ptr<ResourceRequest>
- CreateAccessControlPreflightRequestForTesting(const ResourceRequest&);
-
- static DocumentThreadableLoader* Create(ThreadableLoadingContext&,
- ThreadableLoaderClient*,
- const ThreadableLoaderOptions&,
- const ResourceLoaderOptions&);
- ~DocumentThreadableLoader() override;
-
- void Start(const ResourceRequest&) override;
-
- void OverrideTimeout(unsigned long timeout) override;
-
- void Cancel() override;
- void Detach() override;
- void SetDefersLoading(bool);
-
- // Exposed for thread-correctness DCHECKs in WorkerThreadableLoader.
- ExecutionContext* GetExecutionContext() const;
-
- void Trace(blink::Visitor*) override;
-
- private:
- class DetachedClient;
- enum BlockingBehavior { kLoadSynchronously, kLoadAsynchronously };
-
- static std::unique_ptr<ResourceRequest> CreateAccessControlPreflightRequest(
- const ResourceRequest&,
- const SecurityOrigin*);
-
- DocumentThreadableLoader(ThreadableLoadingContext&,
- ThreadableLoaderClient*,
- BlockingBehavior,
- const ThreadableLoaderOptions&,
- const ResourceLoaderOptions&);
-
- void Clear();
-
- // ResourceClient
- void NotifyFinished(Resource*) override;
-
- String DebugName() const override { return "DocumentThreadableLoader"; }
-
- // RawResourceClient
- void DataSent(Resource*,
- unsigned long long bytes_sent,
- unsigned long long total_bytes_to_be_sent) override;
- void ResponseReceived(Resource*,
- const ResourceResponse&,
- std::unique_ptr<WebDataConsumerHandle>) override;
- void SetSerializedCachedMetadata(Resource*, const char*, size_t) override;
- void DataReceived(Resource*, const char* data, size_t data_length) override;
- bool RedirectReceived(Resource*,
- const ResourceRequest&,
- const ResourceResponse&) override;
- void RedirectBlocked() override;
- void DataDownloaded(Resource*, int) override;
- void DidReceiveResourceTiming(Resource*, const ResourceTimingInfo&) override;
- void DidDownloadToBlob(Resource*, scoped_refptr<BlobDataHandle>) override;
-
- // Notify Inspector and log to console about resource response. Use this
- // method if response is not going to be finished normally.
- void ReportResponseReceived(unsigned long identifier,
- const ResourceResponse&);
-
- void DidTimeout(TimerBase*);
- // Calls the appropriate loading method according to policy and data about
- // origin. Only for handling the initial load (including fallback after
- // consulting ServiceWorker).
- void DispatchInitialRequest(ResourceRequest&);
- void MakeCrossOriginAccessRequest(const ResourceRequest&);
-
- // Loads m_fallbackRequestForServiceWorker.
- void LoadFallbackRequestForServiceWorker();
- // Issues a CORS preflight.
- void LoadPreflightRequest(const ResourceRequest&,
- const ResourceLoaderOptions&);
- // Loads actual_request_.
- void LoadActualRequest();
- // Clears actual_request_ and reports access control check failure to
- // m_client.
- void HandlePreflightFailure(const KURL&, const String& error_description);
- // Investigates the response for the preflight request. If successful,
- // the actual request will be made later in NotifyFinished().
- void HandlePreflightResponse(const ResourceResponse&);
-
- void DispatchDidFailAccessControlCheck(const ResourceError&);
- void DispatchDidFail(const ResourceError&);
-
- void PrepareCrossOriginRequest(ResourceRequest&) const;
-
- // This method modifies the ResourceRequest by calling
- // SetAllowStoredCredentials() on it based on same-origin-ness and the
- // credentials mode.
- //
- // This method configures the ResourceLoaderOptions so that the underlying
- // ResourceFetcher doesn't perform some part of the CORS logic since this
- // class performs it by itself.
- void LoadRequest(ResourceRequest&, ResourceLoaderOptions);
- bool IsAllowedRedirect(network::mojom::FetchRequestMode, const KURL&) const;
-
- const SecurityOrigin* GetSecurityOrigin() const;
-
- // Returns null if the loader is not associated with Document.
- // TODO(kinuko): Remove dependency to document.
- Document* GetDocument() const;
-
- ThreadableLoaderClient* client_;
- Member<ThreadableLoadingContext> loading_context_;
-
- const ThreadableLoaderOptions options_;
- // Some items may be overridden by m_forceDoNotAllowStoredCredentials and
- // m_securityOrigin. In such a case, build a ResourceLoaderOptions with
- // up-to-date values from them and this variable, and use it.
- const ResourceLoaderOptions resource_loader_options_;
-
- // True when feature OutOfBlinkCORS is enabled (https://crbug.com/736308).
- bool out_of_blink_cors_;
-
- // Corresponds to the CORS flag in the Fetch spec.
- bool cors_flag_;
- scoped_refptr<const SecurityOrigin> security_origin_;
-
- // Set to true when the response data is given to a data consumer handle.
- bool is_using_data_consumer_handle_;
-
- const bool async_;
-
- // Holds the original request context (used for sanity checks).
- WebURLRequest::RequestContext request_context_;
-
- // Saved so that we can use the original value for the modes in
- // ResponseReceived() where |resource| might be a reused one (e.g. preloaded
- // resource) which can have different modes.
- network::mojom::FetchRequestMode fetch_request_mode_;
- network::mojom::FetchCredentialsMode fetch_credentials_mode_;
-
- // Holds the original request for fallback in case the Service Worker
- // does not respond.
- ResourceRequest fallback_request_for_service_worker_;
-
- // Holds the original request and options for it during preflight request
- // handling phase.
- ResourceRequest actual_request_;
- ResourceLoaderOptions actual_options_;
-
- // stores request headers in case of a cross-origin redirect.
- HTTPHeaderMap request_headers_;
-
- TaskRunnerTimer<DocumentThreadableLoader> timeout_timer_;
- TimeTicks request_started_; // Time an asynchronous fetch request is started
-
- // Max number of times that this DocumentThreadableLoader can follow
- // cross-origin redirects. This is used to limit the number of redirects. But
- // this value is not the max number of total redirects allowed, because
- // same-origin redirects are not counted here.
- int cors_redirect_limit_;
-
- network::mojom::FetchRedirectMode redirect_mode_;
-
- // Holds the referrer after a redirect response was received. This referrer is
- // used to populate the HTTP Referer header when following the redirect.
- bool override_referrer_;
- Referrer referrer_after_redirect_;
-
- bool detached_ = false;
-
- RawResourceClientStateChecker checker_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_DOCUMENT_THREADABLE_LOADER_H_
diff --git a/chromium/third_party/blink/renderer/core/loader/document_threadable_loader_client.h b/chromium/third_party/blink/renderer/core/loader/document_threadable_loader_client.h
deleted file mode 100644
index 9554ac3dea4..00000000000
--- a/chromium/third_party/blink/renderer/core/loader/document_threadable_loader_client.h
+++ /dev/null
@@ -1,61 +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.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_DOCUMENT_THREADABLE_LOADER_CLIENT_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_DOCUMENT_THREADABLE_LOADER_CLIENT_H_
-
-#include "base/macros.h"
-#include "third_party/blink/renderer/core/loader/threadable_loader_client.h"
-
-namespace blink {
-
-class KURL;
-class ResourceResponse;
-
-class DocumentThreadableLoaderClient : public ThreadableLoaderClient {
- USING_FAST_MALLOC(DocumentThreadableLoaderClient);
-
- public:
- bool IsDocumentThreadableLoaderClient() final { return true; }
-
- virtual bool WillFollowRedirect(const KURL& new_url,
- const ResourceResponse&) {
- return true;
- }
-
- protected:
- DocumentThreadableLoaderClient() = default;
-
- DISALLOW_COPY_AND_ASSIGN(DocumentThreadableLoaderClient);
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_DOCUMENT_THREADABLE_LOADER_CLIENT_H_
diff --git a/chromium/third_party/blink/renderer/core/loader/document_threadable_loader_test.cc b/chromium/third_party/blink/renderer/core/loader/document_threadable_loader_test.cc
deleted file mode 100644
index b0371724551..00000000000
--- a/chromium/third_party/blink/renderer/core/loader/document_threadable_loader_test.cc
+++ /dev/null
@@ -1,92 +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/loader/document_threadable_loader.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/web_cors.h"
-#include "third_party/blink/renderer/platform/exported/wrapped_resource_response.h"
-#include "third_party/blink/renderer/platform/loader/fetch/resource_response.h"
-
-namespace blink {
-
-namespace {
-
-TEST(DocumentThreadableLoaderCreatePreflightRequestTest, LexicographicalOrder) {
- ResourceRequest request;
- request.AddHTTPHeaderField("Orange", "Orange");
- request.AddHTTPHeaderField("Apple", "Red");
- request.AddHTTPHeaderField("Kiwifruit", "Green");
- request.AddHTTPHeaderField("Content-Type", "application/octet-stream");
- request.AddHTTPHeaderField("Strawberry", "Red");
-
- std::unique_ptr<ResourceRequest> preflight =
- DocumentThreadableLoader::CreateAccessControlPreflightRequestForTesting(
- request);
-
- EXPECT_EQ("apple,content-type,kiwifruit,orange,strawberry",
- preflight->HttpHeaderField("Access-Control-Request-Headers"));
-}
-
-TEST(DocumentThreadableLoaderCreatePreflightRequestTest, ExcludeSimpleHeaders) {
- ResourceRequest request;
- request.AddHTTPHeaderField("Accept", "everything");
- request.AddHTTPHeaderField("Accept-Language", "everything");
- request.AddHTTPHeaderField("Content-Language", "everything");
- request.AddHTTPHeaderField("Save-Data", "on");
-
- std::unique_ptr<ResourceRequest> preflight =
- DocumentThreadableLoader::CreateAccessControlPreflightRequestForTesting(
- request);
-
- // Do not emit empty-valued headers; an empty list of non-"CORS safelisted"
- // request headers should cause "Access-Control-Request-Headers:" to be
- // left out in the preflight request.
- EXPECT_EQ(g_null_atom,
- preflight->HttpHeaderField("Access-Control-Request-Headers"));
-}
-
-TEST(DocumentThreadableLoaderCreatePreflightRequestTest,
- ExcludeSimpleContentTypeHeader) {
- ResourceRequest request;
- request.AddHTTPHeaderField("Content-Type", "text/plain");
-
- std::unique_ptr<ResourceRequest> preflight =
- DocumentThreadableLoader::CreateAccessControlPreflightRequestForTesting(
- request);
-
- // Empty list also; see comment in test above.
- EXPECT_EQ(g_null_atom,
- preflight->HttpHeaderField("Access-Control-Request-Headers"));
-}
-
-TEST(DocumentThreadableLoaderCreatePreflightRequestTest,
- IncludeNonSimpleHeader) {
- ResourceRequest request;
- request.AddHTTPHeaderField("X-Custom-Header", "foobar");
-
- std::unique_ptr<ResourceRequest> preflight =
- DocumentThreadableLoader::CreateAccessControlPreflightRequestForTesting(
- request);
-
- EXPECT_EQ("x-custom-header",
- preflight->HttpHeaderField("Access-Control-Request-Headers"));
-}
-
-TEST(DocumentThreadableLoaderCreatePreflightRequestTest,
- IncludeNonSimpleContentTypeHeader) {
- ResourceRequest request;
- request.AddHTTPHeaderField("Content-Type", "application/octet-stream");
-
- std::unique_ptr<ResourceRequest> preflight =
- DocumentThreadableLoader::CreateAccessControlPreflightRequestForTesting(
- request);
-
- EXPECT_EQ("content-type",
- preflight->HttpHeaderField("Access-Control-Request-Headers"));
-}
-
-} // namespace
-
-} // namespace blink
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 b07f958a261..97f61460de2 100644
--- a/chromium/third_party/blink/renderer/core/loader/empty_clients.cc
+++ b/chromium/third_party/blink/renderer/core/loader/empty_clients.cc
@@ -106,7 +106,8 @@ NavigationPolicy EmptyLocalFrameClient::DecidePolicyForNavigation(
WebTriggeringEventInfo,
HTMLFormElement*,
ContentSecurityPolicyDisposition,
- mojom::blink::BlobURLTokenPtr) {
+ mojom::blink::BlobURLTokenPtr,
+ base::TimeTicks) {
return kNavigationPolicyIgnore;
}
@@ -120,8 +121,8 @@ DocumentLoader* EmptyLocalFrameClient::CreateDocumentLoader(
const SubstituteData& substitute_data,
ClientRedirectPolicy client_redirect_policy,
const base::UnguessableToken& devtools_navigation_token,
- std::unique_ptr<WebDocumentLoader::ExtraData> extra_data,
- const WebNavigationTimings& navigation_timings) {
+ std::unique_ptr<WebNavigationParams> navigation_params,
+ std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) {
DCHECK(frame);
return DocumentLoader::Create(frame, request, substitute_data,
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 dbb68e5e649..21657f6bbb4 100644
--- a/chromium/third_party/blink/renderer/core/loader/empty_clients.h
+++ b/chromium/third_party/blink/renderer/core/loader/empty_clients.h
@@ -266,18 +266,18 @@ class CORE_EXPORT EmptyLocalFrameClient : public LocalFrameClient {
void DispatchDidFinishLoad() override {}
void DispatchDidChangeThemeColor() override {}
- NavigationPolicy DecidePolicyForNavigation(
- const ResourceRequest&,
- Document* origin_document,
- DocumentLoader*,
- WebNavigationType,
- NavigationPolicy,
- bool,
- bool,
- WebTriggeringEventInfo,
- HTMLFormElement*,
- ContentSecurityPolicyDisposition,
- mojom::blink::BlobURLTokenPtr) override;
+ NavigationPolicy DecidePolicyForNavigation(const ResourceRequest&,
+ Document* origin_document,
+ DocumentLoader*,
+ WebNavigationType,
+ NavigationPolicy,
+ bool,
+ bool,
+ WebTriggeringEventInfo,
+ HTMLFormElement*,
+ ContentSecurityPolicyDisposition,
+ mojom::blink::BlobURLTokenPtr,
+ base::TimeTicks) override;
void DispatchWillSendSubmitEvent(HTMLFormElement*) override;
void DispatchWillSubmitForm(HTMLFormElement*) override;
@@ -298,8 +298,8 @@ class CORE_EXPORT EmptyLocalFrameClient : public LocalFrameClient {
const SubstituteData&,
ClientRedirectPolicy,
const base::UnguessableToken& devtools_navigation_token,
- std::unique_ptr<WebDocumentLoader::ExtraData> extra_data,
- const WebNavigationTimings& navigation_timings) override;
+ std::unique_ptr<WebNavigationParams> navigation_params,
+ std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) override;
String UserAgent() override { return ""; }
@@ -414,7 +414,6 @@ class CORE_EXPORT EmptyRemoteFrameClient : public RemoteFrameClient {
void Navigate(const ResourceRequest&,
bool should_replace_current_entry,
mojom::blink::BlobURLTokenPtr) override {}
- void Reload(WebFrameLoadType, ClientRedirectPolicy) override {}
unsigned BackForwardLength() override { return 0; }
void CheckCompleted() override {}
void ForwardPostMessage(MessageEvent*,
@@ -423,8 +422,8 @@ class CORE_EXPORT EmptyRemoteFrameClient : public RemoteFrameClient {
bool has_user_gesture) const override {}
void FrameRectsChanged(const IntRect& local_frame_rect,
const IntRect& transformed_frame_rect) override {}
- void UpdateRemoteViewportIntersection(
- const IntRect& viewport_intersection) override {}
+ void UpdateRemoteViewportIntersection(const IntRect& viewport_intersection,
+ bool occluded_or_obscured) override {}
void AdvanceFocus(WebFocusType, LocalFrame* source) override {}
void VisibilityChanged(bool visible) override {}
void SetIsInert(bool) override {}
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 ef30dcc6ae3..a1693b1505e 100644
--- a/chromium/third_party/blink/renderer/core/loader/form_submission.cc
+++ b/chromium/third_party/blink/renderer/core/loader/form_submission.cc
@@ -207,7 +207,8 @@ FormSubmission* FormSubmission::Create(HTMLFormElement* form,
: copied_attributes.Action());
if (document.GetInsecureRequestPolicy() & kUpgradeInsecureRequests &&
- action_url.ProtocolIs("http")) {
+ action_url.ProtocolIs("http") &&
+ !SecurityOrigin::Create(action_url)->IsPotentiallyTrustworthy()) {
UseCounter::Count(document,
WebFeature::kUpgradeInsecureRequestsUpgradedRequest);
action_url.SetProtocol("https");
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 ccfe5714611..8e3816da3ed 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
@@ -383,6 +383,16 @@ SubresourceFilter* FrameFetchContext::GetSubresourceFilter() const {
return document_loader ? document_loader->GetSubresourceFilter() : nullptr;
}
+PreviewsResourceLoadingHints*
+FrameFetchContext::GetPreviewsResourceLoadingHints() const {
+ if (IsDetached())
+ return nullptr;
+ DocumentLoader* document_loader = MasterDocumentLoader();
+ if (!document_loader)
+ return nullptr;
+ return document_loader->GetPreviewsResourceLoadingHints();
+}
+
LocalFrame* FrameFetchContext::GetFrame() const {
DCHECK(!IsDetached());
@@ -782,7 +792,6 @@ void FrameFetchContext::RecordLoadingActivity(
void FrameFetchContext::DidLoadResource(Resource* resource) {
if (!document_)
return;
- FirstMeaningfulPaintDetector::From(*document_).CheckNetworkStable();
if (LocalFrame* local_frame = document_->GetFrame()) {
if (IdlenessDetector* idleness_detector =
local_frame->GetIdlenessDetector()) {
@@ -809,7 +818,7 @@ void FrameFetchContext::AddResourceTiming(const ResourceTimingInfo& info) {
// Main resource timing information is reported through the owner to be
// passed to the parent frame, if appropriate.
frame->Owner()->AddResourceTiming(info);
- frame->DidSendResourceTimingInfoToParent();
+ frame->SetShouldSendResourceTimingInfoToParent(false);
return;
}
@@ -887,9 +896,12 @@ bool FrameFetchContext::UpdateTimingInfoForIFrameNavigation(
if (!GetFrame()->should_send_resource_timing_info_to_parent())
return false;
// Do not report iframe navigation that restored from history, since its
- // location may have been changed after initial navigation.
- if (MasterDocumentLoader()->LoadType() == WebFrameLoadType::kBackForward)
+ // location may have been changed after initial navigation,
+ if (MasterDocumentLoader()->LoadType() == WebFrameLoadType::kBackForward) {
+ // ...and do not report subsequent navigations in the iframe too.
+ GetFrame()->SetShouldSendResourceTimingInfoToParent(false);
return false;
+ }
return true;
}
@@ -1184,11 +1196,13 @@ bool FrameFetchContext::ShouldBlockFetchByMixedContentCheck(
bool FrameFetchContext::ShouldBlockFetchAsCredentialedSubresource(
const ResourceRequest& resource_request,
const KURL& url) const {
- // BlockCredentialedSubresources has already been checked on the
- // browser-side. It should not be checked a second time here because the
- // renderer-side implementation suffers from https://crbug.com/756846.
- if (!resource_request.CheckForBrowserSideNavigation())
+ // BlockCredentialedSubresources for main resource has already been checked
+ // on the browser-side. It should not be checked a second time here because
+ // the renderer-side implementation suffers from https://crbug.com/756846.
+ if (resource_request.GetFrameType() !=
+ network::mojom::RequestContextFrameType::kNone) {
return false;
+ }
// URLs with no embedded credentials should load correctly.
if (url.User().IsEmpty() && url.Pass().IsEmpty())
@@ -1518,7 +1532,6 @@ base::Optional<ResourceRequestBlockedReason> FrameFetchContext::CanRequest(
const KURL& url,
const ResourceLoaderOptions& options,
SecurityViolationReportingPolicy reporting_policy,
- FetchParameters::OriginRestriction origin_restriction,
ResourceRequest::RedirectStatus redirect_status) const {
if (document_ && document_->IsFreezingInProgress() &&
!resource_request.GetKeepalive()) {
@@ -1528,8 +1541,7 @@ base::Optional<ResourceRequestBlockedReason> FrameFetchContext::CanRequest(
return ResourceRequestBlockedReason::kOther;
}
return BaseFetchContext::CanRequest(type, resource_request, url, options,
- reporting_policy, origin_restriction,
- redirect_status);
+ reporting_policy, redirect_status);
}
} // namespace blink
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 d2a808077e7..a3bbbf7bed0 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
@@ -88,7 +88,6 @@ class CORE_EXPORT FrameFetchContext final : public BaseFetchContext {
const KURL& url,
const ResourceLoaderOptions& options,
SecurityViolationReportingPolicy reporting_policy,
- FetchParameters::OriginRestriction origin_restriction,
ResourceRequest::RedirectStatus redirect_status) const override;
mojom::FetchCacheMode ResourceRequestCachePolicy(
const ResourceRequest&,
@@ -214,6 +213,8 @@ class CORE_EXPORT FrameFetchContext final : public BaseFetchContext {
const override;
KURL GetSiteForCookies() const override;
SubresourceFilter* GetSubresourceFilter() const override;
+ PreviewsResourceLoadingHints* GetPreviewsResourceLoadingHints()
+ const override;
bool AllowScriptFromSource(const KURL&) const override;
bool ShouldBlockRequestByInspector(const KURL&) const override;
void DispatchDidBlockRequest(const 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 ef4702cd0fb..29e6efff9d3 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
@@ -269,8 +269,7 @@ class FrameFetchContextSubresourceFilterTest : public FrameFetchContextTest {
ResourceLoaderOptions options;
return fetch_context->CanRequest(
Resource::kImage, resource_request, input_url, options,
- reporting_policy, FetchParameters::kUseDefaultOriginRestrictionForType,
- ResourceRequest::RedirectStatus::kNoRedirect);
+ reporting_policy, ResourceRequest::RedirectStatus::kNoRedirect);
}
int filtered_load_callback_counter_;
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 29230b12329..50379f81b2b 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
@@ -109,6 +109,11 @@ struct CORE_EXPORT FrameLoadRequest {
should_set_opener_ = should_set_opener;
}
+ const AtomicString& HrefTranslate() { return href_translate_; }
+ void SetHrefTranslate(const AtomicString& translate) {
+ href_translate_ = translate;
+ }
+
ContentSecurityPolicyDisposition ShouldCheckMainWorldContentSecurityPolicy()
const {
return should_check_main_world_content_security_policy_;
@@ -143,6 +148,12 @@ struct CORE_EXPORT FrameLoadRequest {
return result;
}
+ void SetInputStartTime(base::TimeTicks input_start_time) {
+ input_start_time_ = input_start_time;
+ }
+
+ base::TimeTicks GetInputStartTime() const { return input_start_time_; }
+
private:
FrameLoadRequest(Document* origin_document,
const ResourceRequest&,
@@ -154,6 +165,7 @@ struct CORE_EXPORT FrameLoadRequest {
Member<Document> origin_document_;
ResourceRequest resource_request_;
AtomicString frame_name_;
+ AtomicString href_translate_;
SubstituteData substitute_data_;
bool replaces_current_item_;
ClientRedirectPolicy client_redirect_;
@@ -167,6 +179,7 @@ struct CORE_EXPORT FrameLoadRequest {
base::UnguessableToken devtools_navigation_token_;
scoped_refptr<base::RefCountedData<mojom::blink::BlobURLTokenPtr>>
blob_url_token_;
+ base::TimeTicks input_start_time_;
};
} // namespace blink
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 00dd9874383..2f5f0000f69 100644
--- a/chromium/third_party/blink/renderer/core/loader/frame_loader.cc
+++ b/chromium/third_party/blink/renderer/core/loader/frame_loader.cc
@@ -45,10 +45,12 @@
#include "third_party/blink/public/platform/web_url_request.h"
#include "third_party/blink/public/web/web_frame_load_type.h"
#include "third_party/blink/public/web/web_history_item.h"
+#include "third_party/blink/public/web/web_navigation_params.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/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/element.h"
+#include "third_party/blink/renderer/core/dom/ignore_opens_during_unload_count_incrementer.h"
#include "third_party/blink/renderer/core/events/page_transition_event.h"
#include "third_party/blink/renderer/core/frame/content_settings_client.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
@@ -81,6 +83,7 @@
#include "third_party/blink/renderer/core/page/viewport_description.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/scroll/scroll_animator_base.h"
#include "third_party/blink/renderer/core/svg/graphics/svg_image.h"
#include "third_party/blink/renderer/core/xml/parser/xml_document_parser.h"
#include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h"
@@ -96,7 +99,6 @@
#include "third_party/blink/renderer/platform/network/network_utils.h"
#include "third_party/blink/renderer/platform/plugins/plugin_script_forbidden_scope.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
-#include "third_party/blink/renderer/platform/scroll/scroll_animator_base.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"
@@ -170,6 +172,8 @@ 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(
frame_->GetDocument()->GetReferrerPolicy(),
@@ -220,8 +224,8 @@ void FrameLoader::Init() {
provisional_document_loader_ = Client()->CreateDocumentLoader(
frame_, initial_request, SubstituteData(),
ClientRedirectPolicy::kNotClientRedirect,
- base::UnguessableToken::Create(), nullptr /* extra_data */,
- WebNavigationTimings());
+ base::UnguessableToken::Create(), nullptr /* navigation_params */,
+ nullptr /* extra_data */);
provisional_document_loader_->StartLoading();
frame_->GetDocument()->CancelParsing();
@@ -380,6 +384,10 @@ void FrameLoader::ReplaceDocumentWhileExecutingJavaScriptURL(
// child frame during or after detaching children results in an attached
// frame on a detached DOM tree, which is bad.
SubframeLoadingDisabler disabler(document);
+ // https://html.spec.whatwg.org/C/browsing-the-web.html#unload-a-document
+ // The ignore-opens-during-unload counter of the parent Document must be
+ // incremented when unloading its descendants.
+ IgnoreOpensDuringUnloadCountIncrementer ignore_opens_during_unload(document);
frame_->DetachChildren();
// detachChildren() potentially detaches or navigates this frame. The load
@@ -595,20 +603,26 @@ void FrameLoader::SetReferrerForFrameRequest(FrameLoadRequest& frame_request) {
if (!origin_document)
return;
- // Anchor elements with the 'referrerpolicy' attribute will have already set
- // the referrer on the request.
- if (request.DidSetHTTPReferrer())
- return;
if (frame_request.GetShouldSendReferrer() == kNeverSendReferrer)
return;
// Always use the initiating document to generate the referrer. We need to
// generateReferrer(), because we haven't enforced ReferrerPolicy or
// https->http referrer suppression yet.
+ String referrer_to_use = request.ReferrerString();
+ ReferrerPolicy referrer_policy_to_use = request.GetReferrerPolicy();
+
+ if (referrer_to_use == Referrer::ClientReferrerString())
+ referrer_to_use = origin_document->OutgoingReferrer();
+
+ if (referrer_policy_to_use == kReferrerPolicyDefault)
+ referrer_policy_to_use = origin_document->GetReferrerPolicy();
+
Referrer referrer = SecurityPolicy::GenerateReferrer(
- origin_document->GetReferrerPolicy(), request.Url(),
- origin_document->OutgoingReferrer());
+ 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.SetHTTPOriginToMatchReferrerIfNeeded();
}
@@ -623,12 +637,10 @@ WebFrameLoadType FrameLoader::DetermineFrameLoadType(
return WebFrameLoadType::kReplaceCurrentItem;
return WebFrameLoadType::kStandard;
}
- if (request.GetResourceRequest().GetCacheMode() ==
- mojom::FetchCacheMode::kValidateCache)
- return WebFrameLoadType::kReload;
- if (request.GetResourceRequest().GetCacheMode() ==
- mojom::FetchCacheMode::kBypassCache)
- return WebFrameLoadType::kReloadBypassingCache;
+ CHECK_NE(mojom::FetchCacheMode::kValidateCache,
+ request.GetResourceRequest().GetCacheMode());
+ CHECK_NE(mojom::FetchCacheMode::kBypassCache,
+ request.GetResourceRequest().GetCacheMode());
// From the HTML5 spec for location.assign():
// "If the browsing context's session history contains only one Document,
// and that was the about:blank Document created when the browsing context
@@ -764,19 +776,21 @@ void FrameLoader::StartNavigation(const FrameLoadRequest& passed_request,
return;
FrameLoadRequest request(passed_request);
- request.GetResourceRequest().SetHasUserGesture(
- Frame::HasTransientUserActivation(frame_));
+ ResourceRequest& resource_request = request.GetResourceRequest();
+ const KURL& url = resource_request.Url();
+ Document* origin_document = request.OriginDocument();
+
+ resource_request.SetHasUserGesture(Frame::HasTransientUserActivation(frame_));
if (!PrepareRequestForThisFrame(request))
return;
// Form submissions appear to need their special-case of finding the target at
// schedule rather than at fire.
- Frame* target_frame = request.Form()
- ? nullptr
- : frame_->FindFrameForNavigation(
- AtomicString(request.FrameName()), *frame_,
- request.GetResourceRequest().Url());
+ Frame* target_frame =
+ request.Form() ? nullptr
+ : frame_->FindFrameForNavigation(
+ AtomicString(request.FrameName()), *frame_, url);
// Downloads and navigations which specifically target a *new* frame
// (e.g. because of a ctrl-click) should ignore the target.
@@ -802,11 +816,11 @@ void FrameLoader::StartNavigation(const FrameLoadRequest& passed_request,
if (!target_frame && !request.FrameName().IsEmpty()) {
if (policy == kNavigationPolicyDownload) {
- Client()->DownloadURL(request.GetResourceRequest(),
+ Client()->DownloadURL(resource_request,
DownloadCrossOriginRedirects::kFollow);
return; // Navigation/download will be handled by the client.
} else if (should_navigate_target_frame) {
- request.GetResourceRequest().SetFrameType(
+ resource_request.SetFrameType(
network::mojom::RequestContextFrameType::kAuxiliary);
CreateWindowForRequest(request, *frame_);
return; // Navigation will be handled by the new frame/window.
@@ -820,51 +834,147 @@ void FrameLoader::StartNavigation(const FrameLoadRequest& passed_request,
return;
}
- const KURL& url = request.GetResourceRequest().Url();
if (frame_load_type == WebFrameLoadType::kStandard)
frame_load_type = DetermineFrameLoadType(request);
bool same_document_navigation =
policy == kNavigationPolicyCurrentTab &&
- ShouldPerformFragmentNavigation(request.Form(),
- request.GetResourceRequest().HttpMethod(),
- frame_load_type, url);
+ ShouldPerformFragmentNavigation(
+ request.Form(), resource_request.HttpMethod(), frame_load_type, url);
// Perform same document navigation.
if (same_document_navigation) {
CommitSameDocumentNavigation(
- request.GetResourceRequest().Url(), frame_load_type, nullptr,
- request.ClientRedirect(), request.OriginDocument(),
+ url, frame_load_type, nullptr, request.ClientRedirect(),
+ origin_document,
request.TriggeringEventInfo() != WebTriggeringEventInfo::kNotFromEvent);
return;
}
- StartLoad(request, frame_load_type, policy, nullptr,
- true /* check_with_client */, nullptr /* extra_data */,
- WebNavigationTimings());
+ WebNavigationType navigation_type = DetermineNavigationType(
+ frame_load_type, resource_request.HttpBody() || request.Form(),
+ request.TriggeringEventInfo() != WebTriggeringEventInfo::kNotFromEvent);
+ resource_request.SetRequestContext(
+ DetermineRequestContextFromNavigationType(navigation_type));
+ resource_request.SetFrameType(
+ frame_->IsMainFrame() ? network::mojom::RequestContextFrameType::kTopLevel
+ : network::mojom::RequestContextFrameType::kNested);
+
+ if (origin_document && origin_document->GetContentSecurityPolicy()
+ ->ExperimentalFeaturesEnabled()) {
+ WebContentSecurityPolicyList initiator_csp =
+ origin_document->GetContentSecurityPolicy()
+ ->ExposeForNavigationalChecks();
+ resource_request.SetInitiatorCSP(initiator_csp);
+ }
+
+ // Record the latest requiredCSP value that will be used when sending this
+ // request.
+ RecordLatestRequiredCSP();
+
+ // TODO(arthursonzogni): 'frame-src' check is disabled on the
+ // renderer side, but is enforced on the browser side.
+ // See http://crbug.com/692595 for understanding why it
+ // can't be enforced on both sides instead.
+
+ // 'form-action' check in the frame that is navigating is disabled on the
+ // renderer side, but is enforced on the browser side instead.
+ // N.B. check in the frame that initiates the navigation stills occurs in
+ // blink and is not enforced on the browser-side.
+ // TODO(arthursonzogni) The 'form-action' check should be fully disabled
+ // in blink, except when the form submission doesn't trigger a navigation
+ // (i.e. javascript urls). Please see https://crbug.com/701749.
+
+ // Report-only CSP headers are checked in browser.
+ ModifyRequestForCSP(resource_request, origin_document);
+
+ DCHECK(Client()->HasWebView());
+ // Check for non-escaped new lines in the url.
+ if (url.PotentiallyDanglingMarkup() && url.ProtocolIsInHTTPFamily()) {
+ Deprecation::CountDeprecation(
+ frame_, WebFeature::kCanRequestURLHTTPContainingNewline);
+ return;
+ }
+
+ policy = Client()->DecidePolicyForNavigation(
+ resource_request, origin_document, nullptr /* document_loader */,
+ navigation_type, policy,
+ frame_load_type == WebFrameLoadType::kReplaceCurrentItem,
+ request.ClientRedirect() == ClientRedirectPolicy::kClientRedirect,
+ request.TriggeringEventInfo(), request.Form(),
+ request.ShouldCheckMainWorldContentSecurityPolicy(),
+ request.GetBlobURLToken(), request.GetInputStartTime());
+
+ // 'beforeunload' can be fired above, which can detach this frame from inside
+ // the event handler.
+ if (!frame_->GetPage())
+ return;
+
+ if (policy == kNavigationPolicyIgnore)
+ return;
+ DCHECK(policy == kNavigationPolicyCurrentTab ||
+ policy == kNavigationPolicyHandledByClient ||
+ policy == kNavigationPolicyHandledByClientForInitialHistory);
+
+ if (!CancelProvisionalLoaderForNewNavigation(policy))
+ return;
+
+ provisional_document_loader_ = CreateDocumentLoader(
+ resource_request, request, frame_load_type, navigation_type,
+ nullptr /* navigation_params */, nullptr /* extra_data */);
+
+ if (request.Form())
+ Client()->DispatchWillSubmitForm(request.Form());
+
+ provisional_document_loader_->AppendRedirect(
+ provisional_document_loader_->Url());
+ frame_->GetFrameScheduler()->DidStartProvisionalLoad(frame_->IsMainFrame());
+
+ // TODO(ananta):
+ // We should get rid of the dependency on the DocumentLoader in consumers of
+ // the DidStartProvisionalLoad() notification.
+ Client()->DispatchDidStartProvisionalLoad(provisional_document_loader_,
+ resource_request);
+ DCHECK(provisional_document_loader_);
// TODO(csharrison): In M70 when UserActivation v2 should ship, we can remove
// the check that the pages are equal, because consumption should not be
// shared across pages.
- const Document* origin_document = request.OriginDocument();
if (frame_->IsMainFrame() && origin_document &&
frame_->GetPage() == origin_document->GetPage()) {
Frame::ConsumeTransientUserActivation(frame_);
}
+
+ // TODO(dgozman): there is still a possibility of
+ // |kNavigationPolicyCurrentTab| when starting a navigation. Perhaps, we can
+ // just call CommitNavigation in this case instead, maybe from client side?
+ if (policy == kNavigationPolicyCurrentTab) {
+ provisional_document_loader_->StartLoading();
+ // This should happen after the request is sent, so that the state
+ // the inspector stored in the matching frameScheduledClientNavigation()
+ // is available while sending the request.
+ probe::frameClearedScheduledClientNavigation(frame_);
+ } else {
+ DCHECK(policy == kNavigationPolicyHandledByClient);
+ probe::frameScheduledClientNavigation(frame_);
+ }
+
+ TakeObjectSnapshot();
}
void FrameLoader::CommitNavigation(
const FrameLoadRequest& passed_request,
WebFrameLoadType frame_load_type,
HistoryItem* history_item,
- std::unique_ptr<WebDocumentLoader::ExtraData> extra_data,
- const WebNavigationTimings& navigation_timings) {
+ std::unique_ptr<WebNavigationParams> navigation_params,
+ std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) {
CHECK(!passed_request.OriginDocument());
CHECK(passed_request.FrameName().IsEmpty());
CHECK(!passed_request.Form());
CHECK(passed_request.TriggeringEventInfo() ==
WebTriggeringEventInfo::kNotFromEvent);
DCHECK(frame_->GetDocument());
+ DCHECK(Client()->HasWebView());
if (in_stop_all_loaders_ || !frame_->IsNavigationAllowed() ||
frame_->GetDocument()->PageDismissalEventBeingDispatched() !=
@@ -880,13 +990,13 @@ void FrameLoader::CommitNavigation(
// TODO(dgozman): figure out the better place for this check
// to cancel lazy load both on start and commit. Perhaps
- // CreateDocumentLoader() is a good one.
+ // CancelProvisionalLoaderForNewNavigation() is a good one.
if (HTMLFrameOwnerElement* element = frame_->DeprecatedLocalOwner())
element->CancelPendingLazyLoad();
FrameLoadRequest request(passed_request);
- request.GetResourceRequest().SetHasUserGesture(
- Frame::HasTransientUserActivation(frame_));
+ ResourceRequest& resource_request = request.GetResourceRequest();
+ resource_request.SetHasUserGesture(Frame::HasTransientUserActivation(frame_));
if (frame_load_type == WebFrameLoadType::kStandard)
frame_load_type = DetermineFrameLoadType(request);
@@ -899,9 +1009,45 @@ void FrameLoader::CommitNavigation(
// "cross-document" navigation, while it's actually same-document
// with regards to the last commit.
// In this rare case, we intentionally proceed as cross-document.
- StartLoad(request, frame_load_type, kNavigationPolicyCurrentTab, history_item,
- false /* check_with_client */, std::move(extra_data),
- navigation_timings);
+
+ RecordLatestRequiredCSP();
+
+ if (!CancelProvisionalLoaderForNewNavigation(kNavigationPolicyCurrentTab))
+ 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(
+ frame_load_type, resource_request.HttpBody(), false /* have_event */);
+ // TODO(dgozman): should these fields be propagated from StartNavigation
+ // and/or set by the caller instead?
+ resource_request.SetRequestContext(
+ DetermineRequestContextFromNavigationType(navigation_type));
+ resource_request.SetFrameType(
+ frame_->IsMainFrame() ? network::mojom::RequestContextFrameType::kTopLevel
+ : network::mojom::RequestContextFrameType::kNested);
+
+ // TODO(dgozman): get rid of provisional document loader and most of the code
+ // below. We should probably call DocumentLoader::CommitNavigation directly.
+ provisional_document_loader_ = CreateDocumentLoader(
+ resource_request, request, frame_load_type, navigation_type,
+ std::move(navigation_params), std::move(extra_data));
+ provisional_document_loader_->AppendRedirect(
+ provisional_document_loader_->Url());
+ if (IsBackForwardLoadType(frame_load_type)) {
+ DCHECK(history_item);
+ provisional_document_loader_->SetItemForHistoryNavigation(history_item);
+ }
+
+ frame_->GetFrameScheduler()->DidStartProvisionalLoad(frame_->IsMainFrame());
+ Client()->DispatchDidStartProvisionalLoad(provisional_document_loader_,
+ resource_request);
+
+ provisional_document_loader_->StartLoading();
+ probe::frameClearedScheduledClientNavigation(frame_);
+
+ TakeObjectSnapshot();
}
mojom::CommitResult FrameLoader::CommitSameDocumentNavigation(
@@ -1023,6 +1169,11 @@ bool FrameLoader::PrepareForCommit() {
// child frame during or after detaching children results in an attached frame
// on a detached DOM tree, which is bad.
SubframeLoadingDisabler disabler(frame_->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
+ // both when unloading itself and when unloading its descendants.
+ IgnoreOpensDuringUnloadCountIncrementer ignore_opens_during_unload(
+ frame_->GetDocument());
if (document_loader_) {
Client()->DispatchWillCommitProvisionalLoad();
DispatchUnloadEvent();
@@ -1305,85 +1456,52 @@ bool FrameLoader::ShouldClose(bool is_reload) {
if (!page || !page->GetChromeClient().CanOpenBeforeUnloadConfirmPanel())
return true;
- // Store all references to each subframe in advance since beforeunload's event
- // handler may modify frame
- HeapVector<Member<LocalFrame>> target_frames;
- target_frames.push_back(frame_);
+ HeapVector<Member<LocalFrame>> descendant_frames;
for (Frame* child = frame_->Tree().FirstChild(); child;
child = child->Tree().TraverseNext(frame_)) {
// FIXME: There is not yet any way to dispatch events to out-of-process
// frames.
if (child->IsLocalFrame())
- target_frames.push_back(ToLocalFrame(child));
+ descendant_frames.push_back(ToLocalFrame(child));
}
- bool should_close = false;
{
NavigationDisablerForBeforeUnload navigation_disabler;
- size_t i;
-
bool did_allow_navigation = false;
- for (i = 0; i < target_frames.size(); i++) {
- if (!target_frames[i]->Tree().IsDescendantOf(frame_))
- continue;
- if (!target_frames[i]->GetDocument()->DispatchBeforeUnloadEvent(
- page->GetChromeClient(), is_reload, did_allow_navigation))
- break;
- }
- if (i == target_frames.size())
- should_close = true;
- }
-
- return should_close;
-}
+ // https://html.spec.whatwg.org/C/browsing-the-web.html#prompt-to-unload-a-document
-NavigationPolicy FrameLoader::ShouldContinueForNavigationPolicy(
- const ResourceRequest& request,
- Document* origin_document,
- const SubstituteData& substitute_data,
- DocumentLoader* loader,
- ContentSecurityPolicyDisposition
- should_check_main_world_content_security_policy,
- WebNavigationType type,
- NavigationPolicy policy,
- WebFrameLoadType frame_load_type,
- bool is_client_redirect,
- WebTriggeringEventInfo triggering_event_info,
- HTMLFormElement* form,
- mojom::blink::BlobURLTokenPtr blob_url_token,
- bool check_with_client) {
- // Don't ask if we already have the data.
- if (substitute_data.IsValid())
- return kNavigationPolicyCurrentTab;
+ // First deal with this frame.
+ IgnoreOpensDuringUnloadCountIncrementer ignore_opens_during_unload(
+ frame_->GetDocument());
+ if (!frame_->GetDocument()->DispatchBeforeUnloadEvent(
+ page->GetChromeClient(), is_reload, did_allow_navigation))
+ return false;
- // Check for non-escaped new lines in the url.
- if (request.Url().PotentiallyDanglingMarkup() &&
- request.Url().ProtocolIsInHTTPFamily()) {
- Deprecation::CountDeprecation(
- frame_, WebFeature::kCanRequestURLHTTPContainingNewline);
- if (RuntimeEnabledFeatures::RestrictCanRequestURLCharacterSetEnabled())
- return kNavigationPolicyIgnore;
- }
+ // Then deal with descendent frames.
+ for (Member<LocalFrame>& descendant_frame : descendant_frames) {
+ if (!descendant_frame->Tree().IsDescendantOf(frame_))
+ continue;
- if (!check_with_client) {
- DCHECK_EQ(kNavigationPolicyCurrentTab, policy);
- return policy;
+ // There is some confusion in the spec around what counters should be
+ // incremented for a descendant browsing context:
+ // https://github.com/whatwg/html/issues/3899
+ //
+ // Here for implementation ease, we use the current spec behavior, which
+ // is to increment only the counter of the Document on which this is
+ // called, and that of the Document we are firing the beforeunload event
+ // on -- not any intermediate Documents that may be the parent of the
+ // frame being unloaded but is not root Document.
+ IgnoreOpensDuringUnloadCountIncrementer
+ ignore_opens_during_unload_descendant(
+ descendant_frame->GetDocument());
+ if (!descendant_frame->GetDocument()->DispatchBeforeUnloadEvent(
+ page->GetChromeClient(), is_reload, did_allow_navigation))
+ return false;
+ }
}
- bool replaces_current_history_item =
- frame_load_type == WebFrameLoadType::kReplaceCurrentItem;
- policy = Client()->DecidePolicyForNavigation(
- request, origin_document, loader, type, policy,
- replaces_current_history_item, is_client_redirect, triggering_event_info,
- form, should_check_main_world_content_security_policy,
- std::move(blob_url_token));
- DCHECK(policy == kNavigationPolicyCurrentTab ||
- policy == kNavigationPolicyIgnore ||
- policy == kNavigationPolicyHandledByClient ||
- policy == kNavigationPolicyHandledByClientForInitialHistory)
- << policy;
- return policy;
+ return true;
}
void FrameLoader::ClientDroppedNavigation() {
@@ -1404,116 +1522,6 @@ void FrameLoader::ClientDroppedNavigation() {
}
}
-void FrameLoader::StartLoad(
- FrameLoadRequest& frame_load_request,
- WebFrameLoadType type,
- NavigationPolicy navigation_policy,
- HistoryItem* history_item,
- bool check_with_client,
- std::unique_ptr<WebDocumentLoader::ExtraData> extra_data,
- const WebNavigationTimings& navigation_timings) {
- DCHECK(Client()->HasWebView());
- ResourceRequest& resource_request = frame_load_request.GetResourceRequest();
- WebNavigationType navigation_type = DetermineNavigationType(
- type, resource_request.HttpBody() || frame_load_request.Form(),
- frame_load_request.TriggeringEventInfo() !=
- WebTriggeringEventInfo::kNotFromEvent);
- resource_request.SetRequestContext(
- DetermineRequestContextFromNavigationType(navigation_type));
- resource_request.SetFrameType(
- frame_->IsMainFrame() ? network::mojom::RequestContextFrameType::kTopLevel
- : network::mojom::RequestContextFrameType::kNested);
-
- Document* origin_document = frame_load_request.OriginDocument();
- if (origin_document && origin_document->GetContentSecurityPolicy()
- ->ExperimentalFeaturesEnabled()) {
- WebContentSecurityPolicyList initiator_csp =
- origin_document->GetContentSecurityPolicy()
- ->ExposeForNavigationalChecks();
- resource_request.SetInitiatorCSP(initiator_csp);
- }
-
- // Record the latest requiredCSP value that will be used when sending this
- // request.
- RecordLatestRequiredCSP();
-
- // TODO(arthursonzogni): 'frame-src' check is disabled on the
- // renderer side, but is enforced on the browser side.
- // See http://crbug.com/692595 for understanding why it
- // can't be enforced on both sides instead.
-
- // 'form-action' check in the frame that is navigating is disabled on the
- // renderer side, but is enforced on the browser side instead.
- // N.B. check in the frame that initiates the navigation stills occurs in
- // blink and is not enforced on the browser-side.
- // TODO(arthursonzogni) The 'form-action' check should be fully disabled
- // in blink, except when the form submission doesn't trigger a navigation
- // (i.e. javascript urls). Please see https://crbug.com/701749.
-
- // Report-only CSP headers are checked in browser.
- ModifyRequestForCSP(resource_request, origin_document);
-
- navigation_policy = ShouldContinueForNavigationPolicy(
- resource_request, origin_document, frame_load_request.GetSubstituteData(),
- nullptr, frame_load_request.ShouldCheckMainWorldContentSecurityPolicy(),
- navigation_type, navigation_policy, type,
- frame_load_request.ClientRedirect() ==
- ClientRedirectPolicy::kClientRedirect,
- frame_load_request.TriggeringEventInfo(), frame_load_request.Form(),
- frame_load_request.GetBlobURLToken(), check_with_client);
-
- // 'beforeunload' can be fired above, which can detach this frame from inside
- // the event handler.
- if (!frame_->GetPage())
- return;
-
- if (navigation_policy == kNavigationPolicyIgnore) {
- // This could only happen from StartNavigation, which must not clear
- // CheckForBrowserSideNavigation bit.
- CHECK(resource_request.CheckForBrowserSideNavigation());
- return;
- }
-
- if (!CancelProvisionalLoaderForNewNavigation(navigation_policy))
- return;
-
- provisional_document_loader_ = CreateDocumentLoader(
- resource_request, frame_load_request, type, navigation_type,
- std::move(extra_data), navigation_timings);
-
- if (frame_load_request.Form())
- Client()->DispatchWillSubmitForm(frame_load_request.Form());
-
- provisional_document_loader_->AppendRedirect(
- provisional_document_loader_->Url());
-
- if (IsBackForwardLoadType(type)) {
- DCHECK(history_item);
- provisional_document_loader_->SetItemForHistoryNavigation(history_item);
- }
-
- frame_->GetFrameScheduler()->DidStartProvisionalLoad(frame_->IsMainFrame());
-
- // TODO(ananta):
- // We should get rid of the dependency on the DocumentLoader in consumers of
- // the DidStartProvisionalLoad() notification.
- Client()->DispatchDidStartProvisionalLoad(provisional_document_loader_,
- resource_request);
- DCHECK(provisional_document_loader_);
-
- if (navigation_policy == kNavigationPolicyCurrentTab) {
- provisional_document_loader_->StartLoading();
- // This should happen after the request is sent, so that the state
- // the inspector stored in the matching frameScheduledClientNavigation()
- // is available while sending the request.
- probe::frameClearedScheduledClientNavigation(frame_);
- } else {
- probe::frameScheduledClientNavigation(frame_);
- }
-
- TakeObjectSnapshot();
-}
-
bool FrameLoader::CancelProvisionalLoaderForNewNavigation(
NavigationPolicy navigation_policy) {
bool had_placeholder_client_document_loader =
@@ -1628,28 +1636,9 @@ SandboxFlags FrameLoader::EffectiveSandboxFlags() const {
return flags;
}
-WebInsecureRequestPolicy FrameLoader::GetInsecureRequestPolicy() const {
- Frame* parent_frame = frame_->Tree().Parent();
- if (!parent_frame)
- return kLeaveInsecureRequestsAlone;
-
- return parent_frame->GetSecurityContext()->GetInsecureRequestPolicy();
-}
-
-SecurityContext::InsecureNavigationsSet*
-FrameLoader::InsecureNavigationsToUpgrade() const {
- DCHECK(frame_);
- Frame* parent_frame = frame_->Tree().Parent();
- if (!parent_frame)
- return nullptr;
-
- return parent_frame->GetSecurityContext()->InsecureNavigationsToUpgrade();
-}
-
void FrameLoader::ModifyRequestForCSP(ResourceRequest& resource_request,
Document* origin_document) const {
- if (RuntimeEnabledFeatures::EmbedderCSPEnforcementEnabled() &&
- !RequiredCSP().IsEmpty()) {
+ if (!RequiredCSP().IsEmpty()) {
DCHECK(
ContentSecurityPolicy::IsValidCSPAttr(RequiredCSP().GetString(), ""));
resource_request.SetHTTPHeaderField(HTTPNames::Sec_Required_CSP,
@@ -1707,8 +1696,11 @@ void FrameLoader::UpgradeInsecureRequest(ResourceRequest& resource_request,
resource_request.SetUpgradeIfInsecure(true);
KURL url = resource_request.Url();
- if (!url.ProtocolIs("http"))
+
+ if (!url.ProtocolIs("http") ||
+ SecurityOrigin::Create(url)->IsPotentiallyTrustworthy()) {
return;
+ }
if (resource_request.GetFrameType() ==
network::mojom::RequestContextFrameType::kNone ||
@@ -1762,16 +1754,16 @@ DocumentLoader* FrameLoader::CreateDocumentLoader(
const FrameLoadRequest& frame_load_request,
WebFrameLoadType load_type,
WebNavigationType navigation_type,
- std::unique_ptr<WebDocumentLoader::ExtraData> extra_data,
- const WebNavigationTimings& navigation_timings) {
+ std::unique_ptr<WebNavigationParams> navigation_params,
+ std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) {
DocumentLoader* loader = Client()->CreateDocumentLoader(
frame_, request,
frame_load_request.GetSubstituteData().IsValid()
? frame_load_request.GetSubstituteData()
: DefaultSubstituteDataForURL(request.Url()),
frame_load_request.ClientRedirect(),
- frame_load_request.GetDevToolsNavigationToken(), std::move(extra_data),
- navigation_timings);
+ frame_load_request.GetDevToolsNavigationToken(),
+ std::move(navigation_params), std::move(extra_data));
loader->SetLoadType(load_type);
loader->SetNavigationType(navigation_type);
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 60752b5957b..983141261af 100644
--- a/chromium/third_party/blink/renderer/core/loader/frame_loader.h
+++ b/chromium/third_party/blink/renderer/core/loader/frame_loader.h
@@ -39,7 +39,7 @@
#include "third_party/blink/public/web/commit_result.mojom-shared.h"
#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_timings.h"
+#include "third_party/blink/public/web/web_navigation_params.h"
#include "third_party/blink/public/web/web_navigation_type.h"
#include "third_party/blink/public/web/web_triggering_event_info.h"
#include "third_party/blink/renderer/core/core_export.h"
@@ -65,7 +65,6 @@ namespace blink {
class Document;
class DocumentLoader;
class ExecutionContext;
-class HTMLFormElement;
class LocalFrame;
class Frame;
class LocalFrameClient;
@@ -74,6 +73,7 @@ class ResourceError;
class SerializedScriptValue;
class SubstituteData;
struct FrameLoadRequest;
+struct WebNavigationParams;
CORE_EXPORT bool IsBackForwardLoadType(WebFrameLoadType);
CORE_EXPORT bool IsReloadLoadType(WebFrameLoadType);
@@ -111,8 +111,8 @@ class CORE_EXPORT FrameLoader final {
const FrameLoadRequest&,
WebFrameLoadType = WebFrameLoadType::kStandard,
HistoryItem* = nullptr,
- std::unique_ptr<WebDocumentLoader::ExtraData> extra_data = nullptr,
- const WebNavigationTimings& navigation_timings = WebNavigationTimings());
+ std::unique_ptr<WebNavigationParams> navigation_params = nullptr,
+ std::unique_ptr<WebDocumentLoader::ExtraData> extra_data = nullptr);
// Called when the browser process has asked this renderer process to commit a
// same document navigation in that frame. Returns false if the navigation
@@ -166,8 +166,6 @@ class CORE_EXPORT FrameLoader final {
void ForceSandboxFlags(SandboxFlags flags) { forced_sandbox_flags_ |= flags; }
SandboxFlags EffectiveSandboxFlags() const;
- WebInsecureRequestPolicy GetInsecureRequestPolicy() const;
- SecurityContext::InsecureNavigationsSet* InsecureNavigationsToUpgrade() const;
void ModifyRequestForCSP(ResourceRequest&, Document*) const;
Frame* Opener();
@@ -209,23 +207,6 @@ class CORE_EXPORT FrameLoader final {
void SaveScrollState();
void RestoreScrollPositionAndViewState();
- // The navigation should only be continued immediately in this frame if this
- // returns NavigationPolicyCurrentTab.
- NavigationPolicy ShouldContinueForNavigationPolicy(
- const ResourceRequest&,
- Document* origin_document,
- const SubstituteData&,
- DocumentLoader*,
- ContentSecurityPolicyDisposition,
- WebNavigationType,
- NavigationPolicy,
- WebFrameLoadType,
- bool is_client_redirect,
- WebTriggeringEventInfo,
- HTMLFormElement*,
- mojom::blink::BlobURLTokenPtr,
- bool check_with_client);
-
// Note: When a PlzNavigtate navigation is handled by the client, we will
// have created a dummy provisional DocumentLoader, so this will return true
// while the client handles the navigation.
@@ -257,14 +238,6 @@ class CORE_EXPORT FrameLoader final {
// Returns whether we should continue with new navigation.
bool CancelProvisionalLoaderForNewNavigation(NavigationPolicy);
- void StartLoad(FrameLoadRequest&,
- WebFrameLoadType,
- NavigationPolicy,
- HistoryItem*,
- bool check_with_client,
- std::unique_ptr<WebDocumentLoader::ExtraData>,
- const WebNavigationTimings&);
-
void ClearInitialScrollState();
void LoadInSameDocument(const KURL&,
@@ -290,8 +263,8 @@ class CORE_EXPORT FrameLoader final {
const FrameLoadRequest&,
WebFrameLoadType,
WebNavigationType,
- std::unique_ptr<WebDocumentLoader::ExtraData>,
- const WebNavigationTimings&);
+ std::unique_ptr<WebNavigationParams>,
+ std::unique_ptr<WebDocumentLoader::ExtraData>);
LocalFrameClient* Client() const;
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 d590ed74966..79521ab430c 100644
--- a/chromium/third_party/blink/renderer/core/loader/history_item.cc
+++ b/chromium/third_party/blink/renderer/core/loader/history_item.cc
@@ -165,6 +165,8 @@ EncodedFormData* HistoryItem::FormData() {
ResourceRequest HistoryItem::GenerateResourceRequest(
mojom::FetchCacheMode cache_mode) {
ResourceRequest request(url_string_);
+ // 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.SetCacheMode(cache_mode);
if (form_data_) {
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 fb240b62f5e..befb7aee35f 100644
--- a/chromium/third_party/blink/renderer/core/loader/http_equiv.cc
+++ b/chromium/third_party/blink/renderer/core/loader/http_equiv.cc
@@ -205,12 +205,6 @@ void HttpEquiv::ProcessHttpEquivSetCookie(Document& document,
WebFeature::kMetaSetCookieWhenCSPBlocksInlineScript);
}
- if (!RuntimeEnabledFeatures::BlockMetaSetCookieEnabled()) {
- // Exception (for sandboxed documents) ignored.
- document.setCookie(content, IGNORE_EXCEPTION_FOR_TESTING);
- return;
- }
-
document.AddConsoleMessage(ConsoleMessage::Create(
kSecurityMessageSource, kErrorMessageLevel,
String::Format("Blocked setting the `%s` cookie from a `<meta>` tag.",
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 ef0fd583789..f8aa794a713 100644
--- a/chromium/third_party/blink/renderer/core/loader/idleness_detector.cc
+++ b/chromium/third_party/blink/renderer/core/loader/idleness_detector.cc
@@ -9,6 +9,8 @@
#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/frame/settings.h"
+#include "third_party/blink/renderer/core/paint/first_meaningful_paint_detector.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/platform/instrumentation/resource_coordinator/frame_resource_coordinator.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
@@ -125,11 +127,11 @@ TimeTicks IdlenessDetector::GetNetworkIdleTime() {
}
void IdlenessDetector::WillProcessTask(base::TimeTicks start_time) {
- // If we have idle time and we are kNetworkQuietWindow seconds past it, emit
+ // If we have idle time and we are network_quiet_window_ seconds past it, emit
// idle signals.
DocumentLoader* loader = local_frame_->Loader().GetDocumentLoader();
if (in_network_2_quiet_period_ && !network_2_quiet_.is_null() &&
- start_time - network_2_quiet_ > kNetworkQuietWindow) {
+ start_time - network_2_quiet_ > network_quiet_window_) {
probe::lifecycleEvent(local_frame_, loader, "networkAlmostIdle",
TimeTicksInSeconds(network_2_quiet_start_time_));
if (::resource_coordinator::IsPageAlmostIdleSignalEnabled()) {
@@ -139,14 +141,18 @@ void IdlenessDetector::WillProcessTask(base::TimeTicks start_time) {
}
}
local_frame_->GetDocument()->Fetcher()->OnNetworkQuiet();
+ FirstMeaningfulPaintDetector::From(*local_frame_->GetDocument())
+ .OnNetwork2Quiet();
in_network_2_quiet_period_ = false;
network_2_quiet_ = TimeTicks();
}
if (in_network_0_quiet_period_ && !network_0_quiet_.is_null() &&
- start_time - network_0_quiet_ > kNetworkQuietWindow) {
+ start_time - network_0_quiet_ > network_quiet_window_) {
probe::lifecycleEvent(local_frame_, loader, "networkIdle",
TimeTicksInSeconds(network_0_quiet_start_time_));
+ FirstMeaningfulPaintDetector::From(*local_frame_->GetDocument())
+ .OnNetwork0Quiet();
in_network_0_quiet_period_ = false;
network_0_quiet_ = TimeTicks();
}
@@ -170,7 +176,12 @@ IdlenessDetector::IdlenessDetector(LocalFrame* local_frame)
network_quiet_timer_(
local_frame->GetTaskRunner(TaskType::kInternalLoading),
this,
- &IdlenessDetector::NetworkQuietTimerFired) {}
+ &IdlenessDetector::NetworkQuietTimerFired) {
+ if (local_frame->GetSettings()) {
+ network_quiet_window_ = TimeDelta::FromSecondsD(
+ local_frame->GetSettings()->GetNetworkQuietTimeout());
+ }
+}
void IdlenessDetector::Stop() {
network_quiet_timer_.Stop();
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 e898c71fba8..91a63a5e5d9 100644
--- a/chromium/third_party/blink/renderer/core/loader/idleness_detector.h
+++ b/chromium/third_party/blink/renderer/core/loader/idleness_detector.h
@@ -64,6 +64,7 @@ class CORE_EXPORT IdlenessDetector
bool in_network_0_quiet_period_ = true;
bool in_network_2_quiet_period_ = true;
+ TimeDelta network_quiet_window_ = kNetworkQuietWindow;
// Store the accumulated time of network quiet.
TimeTicks network_0_quiet_;
TimeTicks network_2_quiet_;
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 59be0be3554..c95f1ce89b9 100644
--- a/chromium/third_party/blink/renderer/core/loader/image_loader.cc
+++ b/chromium/third_party/blink/renderer/core/loader/image_loader.cc
@@ -39,6 +39,7 @@
#include "third_party/blink/renderer/core/frame/use_counter.h"
#include "third_party/blink/renderer/core/html/cross_origin_attribute.h"
#include "third_party/blink/renderer/core/html/html_image_element.h"
+#include "third_party/blink/renderer/core/html/lazy_load_image_observer.h"
#include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h"
#include "third_party/blink/renderer/core/layout/layout_image.h"
#include "third_party/blink/renderer/core/layout/layout_video.h"
@@ -145,7 +146,8 @@ ImageLoader::ImageLoader(Element* element)
: element_(element),
image_complete_(true),
loading_image_document_(false),
- suppress_error_events_(false) {
+ suppress_error_events_(false),
+ lazy_image_load_state_(LazyImageLoadState::kNone) {
RESOURCE_LOADING_DVLOG(1) << "new ImageLoader " << this;
}
@@ -355,8 +357,14 @@ void ImageLoader::UpdateImageState(ImageResourceContent* new_image_content) {
if (!new_image_content) {
image_resource_for_image_document_ = nullptr;
image_complete_ = true;
+ if (lazy_image_load_state_ == LazyImageLoadState::kDeferred) {
+ LazyLoadImageObserver::StopMonitoring(GetElement());
+ lazy_image_load_state_ = LazyImageLoadState::kFullImage;
+ }
} else {
image_complete_ = false;
+ if (lazy_image_load_state_ == LazyImageLoadState::kDeferred)
+ LazyLoadImageObserver::StartMonitoring(GetElement());
}
delay_until_image_notify_finished_ = nullptr;
}
@@ -396,10 +404,7 @@ void ImageLoader::DoUpdateFromElement(BypassMainWorldBehavior bypass_behavior,
resource_request.SetPreviewsState(WebURLRequest::kPreviewsNoTransform);
}
- if (referrer_policy != kReferrerPolicyDefault) {
- resource_request.SetHTTPReferrer(SecurityPolicy::GenerateReferrer(
- referrer_policy, url, document.OutgoingReferrer()));
- }
+ resource_request.SetReferrerPolicy(referrer_policy);
// Correct the RequestContext if necessary.
if (IsHTMLPictureElement(GetElement()->parentNode()) ||
@@ -435,8 +440,20 @@ void ImageLoader::DoUpdateFromElement(BypassMainWorldBehavior bypass_behavior,
ConfigureRequest(params, bypass_behavior, *element_,
document.GetFrame()->GetClientHintsPreferences());
- if (update_behavior != kUpdateForcedReload && document.GetFrame())
- document.GetFrame()->MaybeAllowImagePlaceholder(params);
+ if (update_behavior != kUpdateForcedReload &&
+ lazy_image_load_state_ == LazyImageLoadState::kNone) {
+ const auto* frame = document.GetFrame();
+ if (frame->IsClientLoFiAllowed(params.GetResourceRequest())) {
+ params.SetClientLoFiPlaceholder();
+ } else if (auto* html_image = ToHTMLImageElementOrNull(GetElement())) {
+ if (html_image->ElementCreatedByParser() &&
+ frame->IsLazyLoadingImageAllowed()) {
+ params.SetAllowImagePlaceholder();
+ lazy_image_load_state_ = LazyImageLoadState::kDeferred;
+ }
+ LazyLoadImageObserver::StartTrackingVisibilityMetrics(html_image);
+ }
+ }
new_image_content = ImageResourceContent::Fetch(params, document.Fetcher());
@@ -554,6 +571,10 @@ void ImageLoader::UpdateFromElement(UpdateFromElementBehavior update_behavior,
image_content_ = nullptr;
image_resource_for_image_document_ = nullptr;
delay_until_image_notify_finished_ = nullptr;
+ if (lazy_image_load_state_ != LazyImageLoadState::kNone) {
+ LazyLoadImageObserver::StopMonitoring(GetElement());
+ lazy_image_load_state_ = LazyImageLoadState::kNone;
+ }
}
// Don't load images for inactive documents. We don't want to slow down the
@@ -630,6 +651,23 @@ void ImageLoader::ImageNotifyFinished(ImageResourceContent* resource) {
else
CHECK(!image_complete_);
+ if (lazy_image_load_state_ == LazyImageLoadState::kDeferred) {
+ // LazyImages: if a placeholder is loaded, suppress load events and do not
+ // consider the image as loaded, except for unblocking document load events.
+ // The final image load (including load events) occurs when the
+ // non-placeholder image loading (triggered by LoadDeferredImage()) is
+ // finished.
+ if (image_content_ && image_content_->GetImage()->IsPlaceholderImage()) {
+ delay_until_image_notify_finished_ = nullptr;
+ return;
+ }
+ // A placeholder was requested, but the result was an error or a full image.
+ // In these cases, consider this as the final image and suppress further
+ // reloading and proceed to the image load completion process below.
+ LazyLoadImageObserver::StopMonitoring(GetElement());
+ lazy_image_load_state_ = LazyImageLoadState::kFullImage;
+ }
+
image_complete_ = true;
delay_until_image_notify_finished_ = nullptr;
@@ -656,6 +694,9 @@ void ImageLoader::ImageNotifyFinished(ImageResourceContent* resource) {
DispatchDecodeRequestsIfComplete();
+ if (auto* html_image = ToHTMLImageElementOrNull(GetElement()))
+ LazyLoadImageObserver::RecordMetricsOnLoadFinished(html_image);
+
if (loading_image_document_) {
CHECK(!pending_load_event_.IsActive());
return;
@@ -748,7 +789,7 @@ void ImageLoader::DispatchPendingLoadEvent(
void ImageLoader::DispatchPendingErrorEvent(
std::unique_ptr<IncrementLoadEventDelayCount> count) {
if (GetElement()->GetDocument().GetFrame())
- GetElement()->DispatchEvent(Event::Create(EventTypeNames::error));
+ GetElement()->DispatchEvent(*Event::Create(EventTypeNames::error));
// Checks Document's load event synchronously here for performance.
// This is safe because DispatchPendingErrorEvent() is called asynchronously.
@@ -786,6 +827,14 @@ ScriptPromise ImageLoader::Decode(ScriptState* script_state,
return request->promise();
}
+void ImageLoader::LoadDeferredImage(ReferrerPolicy referrer_policy) {
+ if (lazy_image_load_state_ != LazyImageLoadState::kDeferred)
+ return;
+ DCHECK(!image_complete_);
+ lazy_image_load_state_ = LazyImageLoadState::kFullImage;
+ UpdateFromElement(kUpdateNormal, referrer_policy);
+}
+
void ImageLoader::ElementDidMoveToNewDocument() {
if (delay_until_do_update_from_element_) {
delay_until_do_update_from_element_->DocumentChanged(
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 decee89e624..10e6da2fd30 100644
--- a/chromium/third_party/blink/renderer/core/loader/image_loader.h
+++ b/chromium/third_party/blink/renderer/core/loader/image_loader.h
@@ -121,6 +121,8 @@ class CORE_EXPORT ImageLoader : public GarbageCollectedFinalized<ImageLoader>,
ScriptPromise Decode(ScriptState*, ExceptionState&);
+ void LoadDeferredImage(ReferrerPolicy);
+
protected:
void ImageChanged(ImageResourceContent*,
CanDeferInvalidation,
@@ -132,6 +134,21 @@ class CORE_EXPORT ImageLoader : public GarbageCollectedFinalized<ImageLoader>,
enum class UpdateType { kAsync, kSync };
+ // LazyImages: Defer the image load until the image is near the viewport.
+ // https://docs.google.com/document/d/1jF1eSOhqTEt0L1WBCccGwH9chxLd9d1Ez0zo11obj14
+ // The state transition is better captured in the below doc.
+ // https://docs.google.com/document/d/1Ym0EOwyZJmaB5afnCVPu0SFb8EWLBj_facm2fK9kgC0/
+ enum class LazyImageLoadState {
+ kNone, // LazyImages not active.
+ kDeferred, // Placeholder is loading/loaded. Full image load not started.
+ // Once the placeholder is loaded, document load event is
+ // unblocked, but image load event is not fired yet.
+ kFullImage // Full image is loading/loaded, due to element coming near the
+ // viewport or if a placeholder load actually fetched the full
+ // image. image_complete_ can differentiate if the fetch is
+ // complete or not. After the fetch, image load event is fired.
+ };
+
// Called from the task or from updateFromElement to initiate the load.
void DoUpdateFromElement(BypassMainWorldBehavior,
UpdateFromElementBehavior,
@@ -212,6 +229,8 @@ class CORE_EXPORT ImageLoader : public GarbageCollectedFinalized<ImageLoader>,
bool loading_image_document_ : 1;
bool suppress_error_events_ : 1;
+ LazyImageLoadState lazy_image_load_state_;
+
// DecodeRequest represents a single request to the Decode() function. The
// decode requests have one of the following states:
//
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 0e62b777501..1e778891b4e 100644
--- a/chromium/third_party/blink/renderer/core/loader/interactive_detector.h
+++ b/chromium/third_party/blink/renderer/core/loader/interactive_detector.h
@@ -10,10 +10,10 @@
#include "base/time/time.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/loader/long_task_detector.h"
#include "third_party/blink/renderer/core/page/page_visibility_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/long_task_detector.h"
#include "third_party/blink/renderer/platform/pod_interval.h"
#include "third_party/blink/renderer/platform/supplementable.h"
#include "third_party/blink/renderer/platform/timer.h"
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 cd77dabebe5..46ceb06aafe 100644
--- a/chromium/third_party/blink/renderer/core/loader/link_loader.cc
+++ b/chromium/third_party/blink/renderer/core/loader/link_loader.cc
@@ -411,10 +411,7 @@ static Resource* PreloadIfNeeded(const LinkLoadParameters& params,
resource_request.SetRequestContext(ResourceFetcher::DetermineRequestContext(
resource_type.value(), ResourceFetcher::kImageNotImageSet, false));
- if (params.referrer_policy != kReferrerPolicyDefault) {
- resource_request.SetHTTPReferrer(SecurityPolicy::GenerateReferrer(
- params.referrer_policy, url, document.OutgoingReferrer()));
- }
+ resource_request.SetReferrerPolicy(params.referrer_policy);
resource_request.SetFetchImportanceMode(
GetFetchImportanceAttributeValue(params.importance));
@@ -438,10 +435,10 @@ static Resource* PreloadIfNeeded(const LinkLoadParameters& params,
}
link_fetch_params.SetLinkPreload(true);
return document.Loader()->StartPreload(resource_type.value(),
- link_fetch_params, nullptr);
+ link_fetch_params);
}
-// https://html.spec.whatwg.org/#link-type-modulepreload
+// https://html.spec.whatwg.org/multipage/links.html#link-type-modulepreload
static void ModulePreloadIfNeeded(const LinkLoadParameters& params,
Document& document,
ViewportDescription* viewport_description,
@@ -547,8 +544,7 @@ static void ModulePreloadIfNeeded(const LinkLoadParameters& params,
ScriptFetchOptions(params.nonce, integrity_metadata, params.integrity,
kNotParserInserted, credentials_mode,
params.referrer_policy),
- Referrer(Referrer::NoReferrer(), params.referrer_policy),
- TextPosition::MinimumPosition());
+ Referrer::NoReferrer(), TextPosition::MinimumPosition());
// Step 11. "Fetch a single module script given url, settings object,
// destination, options, settings object, "client", and with the top-level
@@ -577,14 +573,19 @@ static Resource* PrefetchIfNeeded(const LinkLoadParameters& params,
UseCounter::Count(document, WebFeature::kLinkRelPrefetch);
ResourceRequest resource_request(params.href);
- if (params.referrer_policy != kReferrerPolicyDefault) {
- resource_request.SetHTTPReferrer(SecurityPolicy::GenerateReferrer(
- params.referrer_policy, params.href, document.OutgoingReferrer()));
- }
-
+ resource_request.SetReferrerPolicy(params.referrer_policy);
resource_request.SetFetchImportanceMode(
GetFetchImportanceAttributeValue(params.importance));
+ // If Signed Exchange is enabled, prefer the application/signed-exchange
+ // content type
+ // (https://wicg.github.io/webpackage/draft-yasskin-http-origin-signed-responses.html#internet-media-type-applicationsigned-exchange).
+ if (RuntimeEnabledFeatures::SignedHTTPExchangeEnabled()) {
+ DEFINE_STATIC_LOCAL(const AtomicString, accept_prefetch,
+ ("application/signed-exchange;v=b2;q=0.9,*/*;q=0.8"));
+ resource_request.SetHTTPAccept(accept_prefetch);
+ }
+
ResourceLoaderOptions options;
options.initiator_info.name = FetchInitiatorTypeNames::link;
@@ -702,11 +703,7 @@ void LinkLoader::LoadStylesheet(const LinkLoadParameters& params,
Document& document,
ResourceClient* link_client) {
ResourceRequest resource_request(document.CompleteURL(params.href));
- ReferrerPolicy referrer_policy = params.referrer_policy;
- if (referrer_policy != kReferrerPolicyDefault) {
- resource_request.SetHTTPReferrer(SecurityPolicy::GenerateReferrer(
- referrer_policy, params.href, document.OutgoingReferrer()));
- }
+ resource_request.SetReferrerPolicy(params.referrer_policy);
mojom::FetchImportanceMode importance_mode =
GetFetchImportanceAttributeValue(params.importance);
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 a0d6e29b89c..ce3eadf3cb0 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
@@ -480,7 +480,8 @@ class ModulePreloadTestModulator final : public DummyModulator {
EXPECT_EQ(kNotParserInserted, request.Options().ParserState());
EXPECT_EQ(params_->expected_credentials_mode,
request.Options().CredentialsMode());
- EXPECT_EQ(Referrer::NoReferrer(), request.GetReferrer().referrer);
+ EXPECT_EQ(Referrer::NoReferrer(), request.ReferrerString());
+ EXPECT_EQ(params_->referrer_policy, request.Options().GetReferrerPolicy());
EXPECT_EQ(params_->integrity,
request.Options().GetIntegrityAttributeValue());
EXPECT_EQ(ModuleScriptCustomFetchType::kNone, custom_fetch_type);
diff --git a/chromium/third_party/blink/renderer/platform/long_task_detector.cc b/chromium/third_party/blink/renderer/core/loader/long_task_detector.cc
index c4b1dc858c1..fef8b5a46f1 100644
--- a/chromium/third_party/blink/renderer/platform/long_task_detector.cc
+++ b/chromium/third_party/blink/renderer/core/loader/long_task_detector.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/platform/long_task_detector.h"
+#include "third_party/blink/renderer/core/loader/long_task_detector.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_thread.h"
diff --git a/chromium/third_party/blink/renderer/platform/long_task_detector.h b/chromium/third_party/blink/renderer/core/loader/long_task_detector.h
index 8c0a19ac8f5..41076c7aee6 100644
--- a/chromium/third_party/blink/renderer/platform/long_task_detector.h
+++ b/chromium/third_party/blink/renderer/core/loader/long_task_detector.h
@@ -2,19 +2,19 @@
// Use 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_LONG_TASK_DETECTOR_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_LONG_TASK_DETECTOR_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_LONG_TASK_DETECTOR_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_LONG_TASK_DETECTOR_H_
+#include "base/macros.h"
#include "base/task/sequence_manager/task_time_observer.h"
#include "third_party/blink/public/platform/web_thread.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/platform_export.h"
-#include "third_party/blink/renderer/platform/wtf/noncopyable.h"
#include "third_party/blink/renderer/platform/wtf/time.h"
namespace blink {
-class PLATFORM_EXPORT LongTaskObserver : public GarbageCollectedMixin {
+class CORE_EXPORT LongTaskObserver : public GarbageCollectedMixin {
public:
virtual ~LongTaskObserver() = default;
@@ -26,11 +26,9 @@ class PLATFORM_EXPORT LongTaskObserver : public GarbageCollectedMixin {
// TaskTimeObserver on the main thread and observes every task. When the number
// of LongTaskObservers drop to zero it automatically removes itself as a
// TaskTimeObserver.
-class PLATFORM_EXPORT LongTaskDetector final
+class CORE_EXPORT LongTaskDetector final
: public GarbageCollectedFinalized<LongTaskDetector>,
public base::sequence_manager::TaskTimeObserver {
- WTF_MAKE_NONCOPYABLE(LongTaskDetector);
-
public:
static LongTaskDetector& Instance();
@@ -51,8 +49,10 @@ class PLATFORM_EXPORT LongTaskDetector final
base::TimeTicks end_time) override;
HeapHashSet<Member<LongTaskObserver>> observers_;
+
+ DISALLOW_COPY_AND_ASSIGN(LongTaskDetector);
};
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_LONG_TASK_DETECTOR_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_LONG_TASK_DETECTOR_H_
diff --git a/chromium/third_party/blink/renderer/platform/long_task_detector_test.cc b/chromium/third_party/blink/renderer/core/loader/long_task_detector_test.cc
index bae1d360e32..4e95f720841 100644
--- a/chromium/third_party/blink/renderer/platform/long_task_detector_test.cc
+++ b/chromium/third_party/blink/renderer/core/loader/long_task_detector_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/platform/long_task_detector.h"
+#include "third_party/blink/renderer/core/loader/long_task_detector.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/platform/cross_thread_functional.h"
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 37a297c5d15..13cd030f5f4 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
@@ -209,17 +209,11 @@ bool RequestIsSubframeSubresource(
frame_type != network::mojom::RequestContextFrameType::kNested);
}
-// static
-bool MixedContentChecker::IsMixedContent(const SecurityOrigin* security_origin,
- const KURL& url) {
- if (!SchemeRegistry::ShouldTreatURLSchemeAsRestrictingMixedContent(
- security_origin->Protocol()))
- return false;
-
+static bool IsInsecureUrl(const KURL& url) {
// |url| is mixed content if its origin is not potentially trustworthy nor
- // secure. We do a quick check against `SecurityOrigin::isSecure` to catch
+ // secure. We do a quick check against `SecurityOrigin::IsSecure` to catch
// things like `about:blank`, which cannot be sanely passed into
- // `SecurityOrigin::create` (as their origin depends on their context).
+ // `SecurityOrigin::Create` (as their origin depends on their context).
// blob: and filesystem: URLs never hit the network, and access is restricted
// to same-origin contexts, so they are not blocked either.
bool is_allowed = url.ProtocolIs("blob") || url.ProtocolIs("filesystem") ||
@@ -229,6 +223,29 @@ bool MixedContentChecker::IsMixedContent(const SecurityOrigin* security_origin,
}
// static
+bool MixedContentChecker::IsMixedContent(const SecurityOrigin* security_origin,
+ const KURL& url) {
+ if (!SchemeRegistry::ShouldTreatURLSchemeAsRestrictingMixedContent(
+ security_origin->Protocol()))
+ return false;
+
+ return IsInsecureUrl(url);
+}
+
+// static
+bool MixedContentChecker::IsMixedContent(
+ const FetchClientSettingsObjectImpl& settings,
+ const KURL& url) {
+ switch (settings.GetHttpsState()) {
+ case HttpsState::kNone:
+ return false;
+
+ case HttpsState::kModern:
+ return IsInsecureUrl(url);
+ }
+}
+
+// static
Frame* MixedContentChecker::InWhichFrameIsContentMixed(
Frame* frame,
network::mojom::RequestContextFrameType frame_type,
@@ -457,7 +474,7 @@ bool MixedContentChecker::ShouldBlockFetchOnWorker(
SecurityViolationReportingPolicy reporting_policy,
bool is_worklet_global_scope) {
if (!MixedContentChecker::IsMixedContent(
- worker_fetch_context.GetSecurityOrigin(), url)) {
+ *worker_fetch_context.GetFetchClientSettingsObject(), url)) {
return false;
}
@@ -563,7 +580,7 @@ bool MixedContentChecker::IsWebSocketAllowed(
const WorkerFetchContext& worker_fetch_context,
const KURL& url) {
if (!MixedContentChecker::IsMixedContent(
- worker_fetch_context.GetSecurityOrigin(), url)) {
+ *worker_fetch_context.GetFetchClientSettingsObject(), url)) {
return true;
}
diff --git a/chromium/third_party/blink/renderer/core/loader/mixed_content_checker.h b/chromium/third_party/blink/renderer/core/loader/mixed_content_checker.h
index 2a0a300c78b..b2933519988 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
@@ -44,6 +44,7 @@
namespace blink {
class ConsoleMessage;
+class FetchClientSettingsObjectImpl;
class Frame;
class FrameFetchContext;
class LocalFrame;
@@ -86,6 +87,7 @@ class CORE_EXPORT MixedContentChecker final {
static bool IsWebSocketAllowed(const WorkerFetchContext&, const KURL&);
static bool IsMixedContent(const SecurityOrigin*, const KURL&);
+ static bool IsMixedContent(const FetchClientSettingsObjectImpl&, const KURL&);
static bool IsMixedFormAction(LocalFrame*,
const KURL&,
SecurityViolationReportingPolicy =
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 81cbd3aba62..da5a8736d80 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
@@ -6,8 +6,8 @@
#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/runtime_enabled_features.h"
-#include "third_party/blink/renderer/platform/wtf/text/movable_string.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
@@ -44,8 +44,7 @@ void DocumentModuleScriptFetcher::NotifyFinished(Resource* resource) {
ModuleScriptCreationParams params(
script_resource->GetResponse().Url(), script_resource->SourceText(),
script_resource->GetResourceRequest().GetFetchCredentialsMode(),
- script_resource->CalculateAccessControlStatus(
- fetcher_->Context().GetSecurityOrigin()));
+ script_resource->CalculateAccessControlStatus());
client_->NotifyFetchFinished(params, error_messages);
}
@@ -77,7 +76,7 @@ bool DocumentModuleScriptFetcher::FetchIfLayeredAPI(
}
ModuleScriptCreationParams params(
- layered_api_url, MovableString(source_text.ReleaseImpl()),
+ layered_api_url, ParkableString(source_text.ReleaseImpl()),
fetch_params.GetResourceRequest().GetFetchCredentialsMode(),
kSharableCrossOrigin);
client_->NotifyFetchFinished(params, HeapVector<Member<ConsoleMessage>>());
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 f9d9b548116..a161709660c 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
@@ -7,10 +7,10 @@
#include "base/optional.h"
#include "third_party/blink/public/platform/web_url_request.h"
+#include "third_party/blink/renderer/platform/bindings/parkable_string.h"
#include "third_party/blink/renderer/platform/cross_thread_copier.h"
#include "third_party/blink/renderer/platform/loader/fetch/access_control_status.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
-#include "third_party/blink/renderer/platform/wtf/text/movable_string.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
@@ -20,7 +20,7 @@ class ModuleScriptCreationParams {
public:
ModuleScriptCreationParams(
const KURL& response_url,
- const MovableString& source_text,
+ const ParkableString& source_text,
network::mojom::FetchCredentialsMode fetch_credentials_mode,
AccessControlStatus access_control_status)
: response_url_(response_url),
@@ -39,10 +39,10 @@ class ModuleScriptCreationParams {
GetFetchCredentialsMode(), GetAccessControlStatus());
}
- const KURL& GetResponseUrl() const { return response_url_; };
- const MovableString& GetSourceText() const {
+ const KURL& GetResponseUrl() const { return response_url_; }
+ const ParkableString& GetSourceText() const {
if (is_isolated_) {
- source_text_ = MovableString(isolated_source_text_.ReleaseImpl());
+ source_text_ = ParkableString(isolated_source_text_.ReleaseImpl());
isolated_source_text_ = String();
is_isolated_ = false;
}
@@ -78,7 +78,7 @@ class ModuleScriptCreationParams {
// Mutable because an isolated copy can become bound to a thread when
// calling GetSourceText().
mutable bool is_isolated_;
- mutable MovableString source_text_;
+ mutable ParkableString source_text_;
mutable String isolated_source_text_;
const network::mojom::FetchCredentialsMode fetch_credentials_mode_;
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 687c8cfa85a..518c7d4bf62 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
@@ -8,7 +8,6 @@
#include "third_party/blink/public/platform/web_url_request.h"
#include "third_party/blink/renderer/platform/loader/fetch/script_fetch_options.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/wtf/text/wtf_string.h"
namespace blink {
@@ -24,32 +23,32 @@ class ModuleScriptFetchRequest final {
ModuleScriptFetchRequest(const KURL& url,
WebURLRequest::RequestContext destination,
const ScriptFetchOptions& options,
- const Referrer& referrer,
+ const String& referrer_string,
const TextPosition& referrer_position)
: url_(url),
destination_(destination),
options_(options),
- referrer_(referrer),
+ referrer_string_(referrer_string),
referrer_position_(referrer_position) {}
static ModuleScriptFetchRequest CreateForTest(const KURL& url) {
- return ModuleScriptFetchRequest(url, WebURLRequest::kRequestContextScript,
- ScriptFetchOptions(), Referrer(),
- TextPosition::MinimumPosition());
+ return ModuleScriptFetchRequest(
+ url, WebURLRequest::kRequestContextScript, ScriptFetchOptions(),
+ Referrer::ClientReferrerString(), TextPosition::MinimumPosition());
}
~ModuleScriptFetchRequest() = default;
const KURL& Url() const { return url_; }
WebURLRequest::RequestContext Destination() const { return destination_; }
const ScriptFetchOptions& Options() const { return options_; }
- const Referrer& GetReferrer() const { return referrer_; }
+ const String& ReferrerString() const { return referrer_string_; }
const TextPosition& GetReferrerPosition() const { return referrer_position_; }
private:
const KURL url_;
const WebURLRequest::RequestContext destination_;
const ScriptFetchOptions options_;
- const Referrer referrer_;
+ const String referrer_string_;
const TextPosition referrer_position_;
};
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 5b6548957fa..9ba4cfc2814 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
@@ -92,7 +92,7 @@ void ModuleScriptLoader::Fetch(
custom_fetch_type);
}
-// https://html.spec.whatwg.org/#fetch-a-single-module-script
+// https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-single-module-script
void ModuleScriptLoader::FetchInternal(
const ModuleScriptFetchRequest& module_request,
FetchClientSettingsObjectSnapshot* fetch_client_settings_object,
@@ -122,13 +122,13 @@ void ModuleScriptLoader::FetchInternal(
options.parser_disposition = options_.ParserState();
// As initiator for module script fetch is not specified in HTML spec,
- // we specity "" as initiator per:
+ // we specify "" as initiator per:
// https://fetch.spec.whatwg.org/#concept-request-initiator
options.initiator_info.name = g_empty_atom;
if (level == ModuleGraphLevel::kDependentModuleFetch) {
options.initiator_info.imported_module_referrer =
- module_request.GetReferrer().referrer;
+ module_request.ReferrerString();
options.initiator_info.position = module_request.GetReferrerPosition();
}
@@ -145,6 +145,12 @@ void ModuleScriptLoader::FetchInternal(
// cryptographic nonce, ..." [spec text]
fetch_params.SetContentSecurityPolicyNonce(options_.Nonce());
+ // [SMSR] "... its referrer policy to options's referrer policy." [spec text]
+ // Note: For now this is done below with SetHTTPReferrer()
+ ReferrerPolicy referrer_policy = module_request.Options().GetReferrerPolicy();
+ if (referrer_policy == kReferrerPolicyDefault)
+ referrer_policy = fetch_client_settings_object->GetReferrerPolicy();
+
// Step 5. "... mode is "cors", ..."
// [SMSR] "... and its credentials mode to options's credentials mode."
// [spec text]
@@ -153,14 +159,23 @@ void ModuleScriptLoader::FetchInternal(
options_.CredentialsMode());
// Step 5. "... referrer is referrer, ..." [spec text]
+ // Note: For now this is done below with SetHTTPReferrer()
+ String referrer_string = module_request.ReferrerString();
+ if (referrer_string == Referrer::ClientReferrerString())
+ referrer_string = fetch_client_settings_object->GetOutgoingReferrer();
+
+ // TODO(domfarolino): Stop storing ResourceRequest's referrer as a
+ // blink::Referrer (https://crbug.com/850813).
fetch_params.MutableResourceRequest().SetHTTPReferrer(
- module_request.GetReferrer());
+ SecurityPolicy::GenerateReferrer(referrer_policy,
+ fetch_params.GetResourceRequest().Url(),
+ referrer_string));
// Step 5. "... and client is fetch client settings object." [spec text]
// -> set by ResourceFetcher
// Note: The fetch request's "origin" isn't specified in
- // https://html.spec.whatwg.org/#fetch-a-single-module-script
+ // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-single-module-script
// Thus, the "origin" is "client" per
// https://fetch.spec.whatwg.org/#concept-request-origin
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 0e9271fc523..a89913ce278 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
@@ -186,13 +186,15 @@ void ModuleScriptLoaderTest::InitializeForWorklet() {
GetDocument().Url(), ScriptType::kModule, GetDocument().UserAgent(),
Vector<CSPHeaderAndType>(), GetDocument().GetReferrerPolicy(),
GetDocument().GetSecurityOrigin(), GetDocument().IsSecureContext(),
- nullptr /* worker_clients */, GetDocument().AddressSpace(),
+ GetDocument().GetHttpsState(), nullptr /* worker_clients */,
+ GetDocument().AddressSpace(),
OriginTrialContext::GetTokens(&GetDocument()).get(),
base::UnguessableToken::Create(), nullptr /* worker_settings */,
kV8CacheOptionsDefault, new WorkletModuleResponsesMap);
global_scope_ = new MainThreadWorkletGlobalScope(
&GetFrame(), std::move(creation_params), *reporting_proxy_);
- global_scope_->ScriptController()->InitializeContextIfNeeded("Dummy Context");
+ global_scope_->ScriptController()->InitializeContextIfNeeded("Dummy Context",
+ NullURL());
modulator_ = new ModuleScriptLoaderTestModulator(
global_scope_->ScriptController()->GetScriptState(),
GetDocument().GetSecurityOrigin(), fetcher);
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 67a0ecfa41a..bfd13580d31 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
@@ -163,10 +163,8 @@ void ModuleTreeLinker::FetchRoot(const KURL& original_url,
// 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 (RuntimeEnabledFeatures::LayeredAPIEnabled()) {
- url = blink::layered_api::ResolveFetchingURL(
- url, fetch_client_settings_object_->BaseURL());
- }
+ if (RuntimeEnabledFeatures::LayeredAPIEnabled())
+ url = blink::layered_api::ResolveFetchingURL(url);
#if DCHECK_IS_ON()
url_ = url;
@@ -188,13 +186,11 @@ void ModuleTreeLinker::FetchRoot(const KURL& original_url,
visited_set_.insert(url);
// Step 2. Perform the internal module script graph fetching procedure given
- // ... with the top-level module fetch flag set. ...
- ModuleScriptFetchRequest request(
- url, destination_, options,
- SecurityPolicy::GenerateReferrer(
- options.GetReferrerPolicy(), url,
- fetch_client_settings_object_->GetOutgoingReferrer()),
- TextPosition::MinimumPosition());
+ // url, settings object, destination, options, settings object, visited set,
+ // "client", and with the top-level module fetch flag set.
+ ModuleScriptFetchRequest request(url, destination_, options,
+ Referrer::ClientReferrerString(),
+ TextPosition::MinimumPosition());
InitiateInternalModuleScriptGraphFetching(
request, ModuleGraphLevel::kTopLevelModuleFetch);
@@ -386,11 +382,9 @@ void ModuleTreeLinker::FetchDescendants(ModuleScript* module_script) {
// procedure given url, fetch client settings object, destination, options,
// module script's settings object, visited set, module script's base URL,
// and with the top-level module fetch flag unset. ...
- ModuleScriptFetchRequest request(
- urls[i], destination_, options,
- SecurityPolicy::GenerateReferrer(options.GetReferrerPolicy(), urls[i],
- module_script->BaseURL().GetString()),
- positions[i]);
+ ModuleScriptFetchRequest request(urls[i], destination_, options,
+ module_script->BaseURL().GetString(),
+ positions[i]);
InitiateInternalModuleScriptGraphFetching(
request, ModuleGraphLevel::kDependentModuleFetch);
}
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 54878e001e2..092915a99d8 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
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/loader/modulescript/worker_module_script_fetcher.h"
+#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
#include "third_party/blink/renderer/platform/network/http_names.h"
@@ -61,6 +62,19 @@ void WorkerModuleScriptFetcher::NotifyFinished(Resource* resource) {
// 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().Url();
+ if (request_url != response_url &&
+ !global_scope_->GetSecurityOrigin()->IsSameSchemeHostPort(
+ SecurityOrigin::Create(response_url).get())) {
+ error_messages.push_back(ConsoleMessage::Create(
+ kSecurityMessageSource, kErrorMessageLevel,
+ "Refused to cross-origin redirects of the top-level worker script."));
+ client_->NotifyFetchFinished(base::nullopt, error_messages);
+ return;
+ }
+
// Step 13.3. "Set worker global scope's url to response's url." [spec text]
// Step 13.4. "Set worker global scope's HTTPS state to response's HTTPS
// state." [spec text]
@@ -85,8 +99,7 @@ void WorkerModuleScriptFetcher::NotifyFinished(Resource* resource) {
ModuleScriptCreationParams params(
script_resource->GetResponse().Url(), script_resource->SourceText(),
script_resource->GetResourceRequest().GetFetchCredentialsMode(),
- script_resource->CalculateAccessControlStatus(
- global_scope_->EnsureFetcher()->Context().GetSecurityOrigin()));
+ script_resource->CalculateAccessControlStatus());
// Step 13.7. "Asynchronously complete the perform the fetch steps with
// response." [spec text]
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 4edfaeadd2d..b14d8929c2a 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
@@ -51,8 +51,7 @@ void WorkletModuleScriptFetcher::NotifyFinished(Resource* resource) {
params.emplace(
script_resource->GetResponse().Url(), script_resource->SourceText(),
script_resource->GetResourceRequest().GetFetchCredentialsMode(),
- script_resource->CalculateAccessControlStatus(
- fetcher_->Context().GetSecurityOrigin()));
+ script_resource->CalculateAccessControlStatus());
}
// This will eventually notify |client| passed to
diff --git a/chromium/third_party/blink/renderer/core/loader/navigation_scheduler.cc b/chromium/third_party/blink/renderer/core/loader/navigation_scheduler.cc
index 44e517b77c4..1cdedd5834b 100644
--- a/chromium/third_party/blink/renderer/core/loader/navigation_scheduler.cc
+++ b/chromium/third_party/blink/renderer/core/loader/navigation_scheduler.cc
@@ -54,7 +54,6 @@
#include "third_party/blink/renderer/core/loader/scheduled_navigation.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/histogram.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
#include "third_party/blink/renderer/platform/shared_buffer.h"
@@ -62,53 +61,6 @@
namespace blink {
-namespace {
-
-// Add new scheduled navigation types before ScheduledLastEntry
-enum ScheduledNavigationType {
- kScheduledReload,
- kScheduledFormSubmission,
- kScheduledURLNavigation,
- kScheduledRedirect,
- kScheduledFrameNavigation,
- kScheduledPageBlock,
-
- kScheduledLastEntry
-};
-
-// If the current frame has a provisional document loader, a scheduled
-// navigation might abort that load. Log those occurrences until
-// crbug.com/557430 is resolved.
-void MaybeLogScheduledNavigationClobber(ScheduledNavigationType type,
- LocalFrame* frame) {
- if (!frame->Loader().GetProvisionalDocumentLoader())
- return;
- // Include enumeration values userGesture variants.
- DEFINE_STATIC_LOCAL(EnumerationHistogram,
- scheduled_navigation_clobber_histogram,
- ("Navigation.Scheduled.MaybeCausedAbort",
- ScheduledNavigationType::kScheduledLastEntry * 2));
-
- int value = Frame::HasTransientUserActivation(frame)
- ? type + kScheduledLastEntry
- : type;
- scheduled_navigation_clobber_histogram.Count(value);
-
- DEFINE_STATIC_LOCAL(
- CustomCountHistogram, scheduled_clobber_abort_time_histogram,
- ("Navigation.Scheduled.MaybeCausedAbort.Time", 1, 10000, 50));
- TimeTicks navigation_start = frame->Loader()
- .GetProvisionalDocumentLoader()
- ->GetTiming()
- .NavigationStart();
- if (!navigation_start.is_null()) {
- scheduled_clobber_abort_time_histogram.Count(
- (CurrentTimeTicks() - navigation_start).InSecondsF());
- }
-}
-
-} // namespace
-
unsigned NavigationDisablerForBeforeUnload::navigation_disable_count_ = 0;
class ScheduledURLNavigation : public ScheduledNavigation {
@@ -153,10 +105,6 @@ class ScheduledURLNavigation : public ScheduledNavigation {
request.SetBlobURLToken(std::move(token_clone));
}
- ScheduledNavigationType type =
- IsLocationChange() ? ScheduledNavigationType::kScheduledFrameNavigation
- : ScheduledNavigationType::kScheduledURLNavigation;
- MaybeLogScheduledNavigationClobber(type, frame);
frame->Loader().StartNavigation(request);
}
@@ -188,16 +136,16 @@ class ScheduledRedirect final : public ScheduledURLNavigation {
std::unique_ptr<UserGestureIndicator> gesture_indicator =
CreateUserGestureIndicator();
FrameLoadRequest request(OriginDocument(), ResourceRequest(Url()), "_self");
+ WebFrameLoadType load_type = WebFrameLoadType::kStandard;
request.SetReplacesCurrentItem(ReplacesCurrentItem());
if (EqualIgnoringFragmentIdentifier(frame->GetDocument()->Url(),
request.GetResourceRequest().Url())) {
request.GetResourceRequest().SetCacheMode(
mojom::FetchCacheMode::kValidateCache);
+ load_type = WebFrameLoadType::kReload;
}
request.SetClientRedirect(ClientRedirectPolicy::kClientRedirect);
- MaybeLogScheduledNavigationClobber(
- ScheduledNavigationType::kScheduledRedirect, frame);
- frame->Loader().StartNavigation(request);
+ frame->Loader().StartNavigation(request, load_type);
}
private:
@@ -265,8 +213,6 @@ class ScheduledReload final : public ScheduledNavigation {
return;
FrameLoadRequest request = FrameLoadRequest(nullptr, resource_request);
request.SetClientRedirect(ClientRedirectPolicy::kClientRedirect);
- MaybeLogScheduledNavigationClobber(
- ScheduledNavigationType::kScheduledReload, frame);
frame->Loader().StartNavigation(request, WebFrameLoadType::kReload);
}
@@ -330,8 +276,6 @@ class ScheduledFormSubmission final : public ScheduledNavigation {
FrameLoadRequest frame_request =
submission_->CreateFrameLoadRequest(OriginDocument());
frame_request.SetReplacesCurrentItem(ReplacesCurrentItem());
- MaybeLogScheduledNavigationClobber(
- ScheduledNavigationType::kScheduledFormSubmission, frame);
frame->Loader().StartNavigation(frame_request, WebFrameLoadType::kStandard,
submission_->GetNavigationPolicy());
}
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 5d1aab29d38..76b445b3a08 100644
--- a/chromium/third_party/blink/renderer/core/loader/ping_loader.cc
+++ b/chromium/third_party/blink/renderer/core/loader/ping_loader.cc
@@ -230,8 +230,10 @@ void PingLoader::SendLinkAuditPing(LocalFrame* frame,
}
request.SetKeepalive(true);
- request.SetHTTPReferrer(
- Referrer(Referrer::NoReferrer(), kReferrerPolicyNever));
+ // TODO(domfarolino): Add WPTs ensuring that pings do not have a referrer
+ // header.
+ request.SetReferrerString(Referrer::NoReferrer());
+ request.SetReferrerPolicy(kReferrerPolicyNever);
request.SetRequestContext(WebURLRequest::kRequestContextPing);
FetchParameters params(request);
params.MutableOptions().initiator_info.name = FetchInitiatorTypeNames::ping;
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
new file mode 100644
index 00000000000..86a12caed34
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/loader/previews_resource_loading_hints.cc
@@ -0,0 +1,73 @@
+// 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/loader/previews_resource_loading_hints.h"
+
+#include "base/metrics/histogram_macros.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/document_loader.h"
+#include "third_party/blink/renderer/platform/weborigin/kurl.h"
+
+namespace blink {
+
+// static
+PreviewsResourceLoadingHints* PreviewsResourceLoadingHints::Create(
+ ExecutionContext& execution_context,
+ const std::vector<WTF::String>& subresource_patterns_to_block) {
+ return new PreviewsResourceLoadingHints(&execution_context,
+ subresource_patterns_to_block);
+}
+
+PreviewsResourceLoadingHints::PreviewsResourceLoadingHints(
+ ExecutionContext* execution_context,
+ const std::vector<WTF::String>& subresource_patterns_to_block)
+ : execution_context_(execution_context),
+ subresource_patterns_to_block_(subresource_patterns_to_block) {}
+
+PreviewsResourceLoadingHints::~PreviewsResourceLoadingHints() = default;
+
+bool PreviewsResourceLoadingHints::AllowLoad(
+ const KURL& resource_url,
+ ResourceLoadPriority resource_load_priority) const {
+ if (!resource_url.ProtocolIsInHTTPFamily())
+ return true;
+
+ WTF::String resource_url_string = resource_url.GetString();
+ resource_url_string = resource_url_string.Left(resource_url.PathEnd());
+ bool allow_load = true;
+
+ for (const WTF::String& 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) {
+ allow_load = false;
+ break;
+ }
+ }
+
+ UMA_HISTOGRAM_BOOLEAN("ResourceLoadingHints.ResourceLoadingBlocked",
+ !allow_load);
+ if (!allow_load) {
+ UMA_HISTOGRAM_ENUMERATION(
+ "ResourceLoadingHints.ResourceLoadingBlocked.ResourceLoadPriority."
+ "Blocked",
+ resource_load_priority,
+ static_cast<int>(ResourceLoadPriority::kHighest) + 1);
+ } else {
+ UMA_HISTOGRAM_ENUMERATION(
+ "ResourceLoadingHints.ResourceLoadingBlocked.ResourceLoadPriority."
+ "Allowed",
+ resource_load_priority,
+ static_cast<int>(ResourceLoadPriority::kHighest) + 1);
+ }
+ return allow_load;
+}
+
+void PreviewsResourceLoadingHints::Trace(blink::Visitor* visitor) {
+ visitor->Trace(execution_context_);
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..4998eae6413
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/loader/previews_resource_loading_hints.h
@@ -0,0 +1,56 @@
+// 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_LOADER_PREVIEWS_RESOURCE_LOADING_HINTS_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_PREVIEWS_RESOURCE_LOADING_HINTS_H_
+
+#include <vector>
+
+#include "third_party/blink/renderer/core/core_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/loader/fetch/resource_load_priority.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+
+class ExecutionContext;
+class KURL;
+
+// PreviewsResourceLoadingHints stores the resource loading hints that apply to
+// a single document.
+class CORE_EXPORT PreviewsResourceLoadingHints final
+ : public GarbageCollectedFinalized<PreviewsResourceLoadingHints> {
+ public:
+ static PreviewsResourceLoadingHints* Create(
+ ExecutionContext& execution_context,
+ const std::vector<WTF::String>& subresource_patterns_to_block);
+
+ ~PreviewsResourceLoadingHints();
+
+ // Returns true if load of resource with URL |resource_url| and priority
+ // |resource_load_priority| is allowed as per resource loading hints.
+ bool AllowLoad(const KURL& resource_url,
+ ResourceLoadPriority resource_load_priority) const;
+
+ virtual void Trace(blink::Visitor*);
+
+ private:
+ PreviewsResourceLoadingHints(
+ ExecutionContext* execution_context,
+ const std::vector<WTF::String>& subresource_patterns_to_block);
+
+ Member<ExecutionContext> execution_context_;
+
+ // |subresource_patterns_to_block_| is a collection of subresource patterns
+ // for resources whose loading should be blocked. Each pattern is a
+ // WTF::String. If a subresource URL contains any of the strings specified in
+ // |subresource_patterns_to_block_|, then that subresource's loading could
+ // be blocked.
+ const std::vector<WTF::String> subresource_patterns_to_block_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_PREVIEWS_RESOURCE_LOADING_HINTS_H_
diff --git a/chromium/third_party/blink/renderer/core/loader/previews_resource_loading_hints_receiver_impl.cc b/chromium/third_party/blink/renderer/core/loader/previews_resource_loading_hints_receiver_impl.cc
index 6a1a5e43253..615b19b9b27 100644
--- a/chromium/third_party/blink/renderer/core/loader/previews_resource_loading_hints_receiver_impl.cc
+++ b/chromium/third_party/blink/renderer/core/loader/previews_resource_loading_hints_receiver_impl.cc
@@ -4,14 +4,20 @@
#include "third_party/blink/renderer/core/loader/previews_resource_loading_hints_receiver_impl.h"
+#include <vector>
+
#include "base/metrics/histogram_macros.h"
+#include "third_party/blink/renderer/core/loader/document_loader.h"
+#include "third_party/blink/renderer/core/loader/previews_resource_loading_hints.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
PreviewsResourceLoadingHintsReceiverImpl::
PreviewsResourceLoadingHintsReceiverImpl(
- mojom::blink::PreviewsResourceLoadingHintsReceiverRequest request)
- : binding_(this, std::move(request)) {}
+ mojom::blink::PreviewsResourceLoadingHintsReceiverRequest request,
+ Document* document)
+ : binding_(this, std::move(request)), document_(document) {}
PreviewsResourceLoadingHintsReceiverImpl::
~PreviewsResourceLoadingHintsReceiverImpl() {}
@@ -23,6 +29,16 @@ void PreviewsResourceLoadingHintsReceiverImpl::SetResourceLoadingHints(
UMA_HISTOGRAM_COUNTS_100(
"ResourceLoadingHints.CountBlockedSubresourcePatterns",
resource_loading_hints->subresources_to_block.size());
+
+ std::vector<WTF::String> subresource_patterns_to_block;
+ for (const auto& subresource :
+ resource_loading_hints->subresources_to_block) {
+ subresource_patterns_to_block.push_back(subresource);
+ }
+
+ document_->Loader()->SetPreviewsResourceLoadingHints(
+ PreviewsResourceLoadingHints::Create(*(document_.Get()),
+ subresource_patterns_to_block));
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/loader/previews_resource_loading_hints_receiver_impl.h b/chromium/third_party/blink/renderer/core/loader/previews_resource_loading_hints_receiver_impl.h
index d4a8daf02b2..ffd2e0680ce 100644
--- a/chromium/third_party/blink/renderer/core/loader/previews_resource_loading_hints_receiver_impl.h
+++ b/chromium/third_party/blink/renderer/core/loader/previews_resource_loading_hints_receiver_impl.h
@@ -7,6 +7,8 @@
#include "mojo/public/cpp/bindings/binding.h"
#include "third_party/blink/public/mojom/loader/previews_resource_loading_hints.mojom-blink.h"
+#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
namespace blink {
@@ -16,8 +18,9 @@ namespace blink {
class PreviewsResourceLoadingHintsReceiverImpl
: public mojom::blink::PreviewsResourceLoadingHintsReceiver {
public:
- explicit PreviewsResourceLoadingHintsReceiverImpl(
- mojom::blink::PreviewsResourceLoadingHintsReceiverRequest request);
+ PreviewsResourceLoadingHintsReceiverImpl(
+ mojom::blink::PreviewsResourceLoadingHintsReceiverRequest request,
+ Document* document);
~PreviewsResourceLoadingHintsReceiverImpl() override;
private:
@@ -27,6 +30,8 @@ class PreviewsResourceLoadingHintsReceiverImpl
// TODO(tbansal): https://crbug.com/800641. Consider using a RevocableBinding.
mojo::Binding<mojom::blink::PreviewsResourceLoadingHintsReceiver> binding_;
+ WeakPersistent<Document> document_;
+
DISALLOW_COPY_AND_ASSIGN(PreviewsResourceLoadingHintsReceiverImpl);
};
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
new file mode 100644
index 00000000000..15295e4e57d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/loader/previews_resource_loading_hints_test.cc
@@ -0,0 +1,183 @@
+// 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/loader/previews_resource_loading_hints.h"
+
+#include <memory>
+#include <vector>
+
+#include "base/test/metrics/histogram_tester.h"
+#include "testing/gtest/include/gtest/gtest.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/previews_resource_loading_hints.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/platform/geometry/int_size.h"
+#include "third_party/blink/renderer/platform/loader/fetch/resource_load_priority.h"
+#include "third_party/blink/renderer/platform/testing/url_test_helpers.h"
+#include "third_party/blink/renderer/platform/weborigin/kurl.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+
+namespace {
+
+class PreviewsResourceLoadingHintsTest : public PageTestBase {
+ public:
+ PreviewsResourceLoadingHintsTest() {
+ dummy_page_holder_ = DummyPageHolder::Create(IntSize(1, 1));
+ }
+
+ protected:
+ std::unique_ptr<DummyPageHolder> dummy_page_holder_;
+};
+
+TEST_F(PreviewsResourceLoadingHintsTest, NoPatterns) {
+ std::vector<WTF::String> subresources_to_block;
+
+ PreviewsResourceLoadingHints* hints = PreviewsResourceLoadingHints::Create(
+ dummy_page_holder_->GetDocument(), subresources_to_block);
+ EXPECT_TRUE(hints->AllowLoad(KURL("https://www.example.com/"),
+ ResourceLoadPriority::kHighest));
+}
+
+TEST_F(PreviewsResourceLoadingHintsTest, OnePattern) {
+ std::vector<WTF::String> subresources_to_block;
+ subresources_to_block.push_back("foo.jpg");
+
+ PreviewsResourceLoadingHints* hints = PreviewsResourceLoadingHints::Create(
+ dummy_page_holder_->GetDocument(), subresources_to_block);
+
+ const struct {
+ KURL url;
+ bool allow_load_expected;
+ } tests[] = {
+ {KURL("https://www.example.com/"), true},
+ {KURL("https://www.example.com/foo.js"), true},
+ {KURL("https://www.example.com/foo.jpg"), false},
+ {KURL("https://www.example.com/pages/foo.jpg"), false},
+ {KURL("https://www.example.com/foobar.jpg"), true},
+ {KURL("https://www.example.com/barfoo.jpg"), false},
+ {KURL("http://www.example.com/foo.jpg"), false},
+ {KURL("http://www.example.com/foo.jpg?q=alpha"), false},
+ {KURL("http://www.example.com/bar.jpg?q=foo.jpg"), true},
+ {KURL("http://www.example.com/bar.jpg?q=foo.jpg#foo.jpg"), true},
+ };
+
+ for (const auto& test : tests) {
+ base::HistogramTester histogram_tester;
+ EXPECT_EQ(test.allow_load_expected,
+ hints->AllowLoad(test.url, ResourceLoadPriority::kHighest));
+ histogram_tester.ExpectUniqueSample(
+ "ResourceLoadingHints.ResourceLoadingBlocked",
+ !test.allow_load_expected, 1);
+ if (!test.allow_load_expected) {
+ histogram_tester.ExpectUniqueSample(
+ "ResourceLoadingHints.ResourceLoadingBlocked.ResourceLoadPriority."
+ "Blocked",
+ ResourceLoadPriority::kHighest, 1);
+ histogram_tester.ExpectTotalCount(
+ "ResourceLoadingHints.ResourceLoadingBlocked.ResourceLoadPriority."
+ "Allowed",
+ 0);
+ } else {
+ histogram_tester.ExpectTotalCount(
+ "ResourceLoadingHints.ResourceLoadingBlocked.ResourceLoadPriority."
+ "Blocked",
+ 0);
+ histogram_tester.ExpectUniqueSample(
+ "ResourceLoadingHints.ResourceLoadingBlocked.ResourceLoadPriority."
+ "Allowed",
+ ResourceLoadPriority::kHighest, 1);
+ }
+ }
+}
+
+TEST_F(PreviewsResourceLoadingHintsTest, MultiplePatterns) {
+ std::vector<WTF::String> subresources_to_block;
+ subresources_to_block.push_back(".example1.com/foo.jpg");
+ subresources_to_block.push_back(".example1.com/bar.jpg");
+ subresources_to_block.push_back(".example2.com/baz.jpg");
+
+ PreviewsResourceLoadingHints* hints = PreviewsResourceLoadingHints::Create(
+ dummy_page_holder_->GetDocument(), subresources_to_block);
+
+ const struct {
+ KURL url;
+ bool allow_load_expected;
+ } tests[] = {
+ {KURL("https://www.example1.com/"), true},
+ {KURL("https://www.example1.com/foo.js"), true},
+ {KURL("https://www.example1.com/foo.jpg"), false},
+ {KURL("https://www.example1.com/pages/foo.jpg"), true},
+ {KURL("https://www.example1.com/foobar.jpg"), true},
+ {KURL("https://www.example1.com/barfoo.jpg"), true},
+ {KURL("http://www.example1.com/foo.jpg"), false},
+ {KURL("http://www.example1.com/bar.jpg"), false},
+ {KURL("http://www.example2.com/baz.jpg"), false},
+ {KURL("http://www.example2.com/pages/baz.jpg"), true},
+ {KURL("http://www.example2.com/baz.html"), true},
+ };
+
+ for (const auto& test : tests) {
+ EXPECT_EQ(test.allow_load_expected,
+ hints->AllowLoad(test.url, ResourceLoadPriority::kHighest));
+ }
+}
+
+TEST_F(PreviewsResourceLoadingHintsTest, OnePatternHistogramChecker) {
+ std::vector<WTF::String> subresources_to_block;
+ subresources_to_block.push_back("foo.jpg");
+
+ PreviewsResourceLoadingHints* hints = PreviewsResourceLoadingHints::Create(
+ dummy_page_holder_->GetDocument(), subresources_to_block);
+
+ const struct {
+ KURL url;
+ bool allow_load_expected;
+ ResourceLoadPriority resource_load_priority;
+ } tests[] = {
+ {KURL("https://www.example.com/foo.js"), true,
+ ResourceLoadPriority::kLow},
+ {KURL("https://www.example.com/foo.jpg"), false,
+ ResourceLoadPriority::kLow},
+ {KURL("https://www.example.com/foo.js"), true,
+ ResourceLoadPriority::kMedium},
+ {KURL("https://www.example.com/foo.jpg"), false,
+ ResourceLoadPriority::kMedium},
+ };
+
+ for (const auto& test : tests) {
+ base::HistogramTester histogram_tester;
+ EXPECT_EQ(test.allow_load_expected,
+ hints->AllowLoad(test.url, test.resource_load_priority));
+ histogram_tester.ExpectUniqueSample(
+ "ResourceLoadingHints.ResourceLoadingBlocked",
+ !test.allow_load_expected, 1);
+ if (!test.allow_load_expected) {
+ histogram_tester.ExpectUniqueSample(
+ "ResourceLoadingHints.ResourceLoadingBlocked.ResourceLoadPriority."
+ "Blocked",
+ test.resource_load_priority, 1);
+ histogram_tester.ExpectTotalCount(
+ "ResourceLoadingHints.ResourceLoadingBlocked.ResourceLoadPriority."
+ "Allowed",
+ 0);
+ } else {
+ histogram_tester.ExpectTotalCount(
+ "ResourceLoadingHints.ResourceLoadingBlocked.ResourceLoadPriority."
+ "Blocked",
+ 0);
+ histogram_tester.ExpectUniqueSample(
+ "ResourceLoadingHints.ResourceLoadingBlocked.ResourceLoadPriority."
+ "Allowed",
+ test.resource_load_priority, 1);
+ }
+ }
+}
+
+} // namespace
+
+} // namespace blink
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 8ca4629e98f..2503a8c4133 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
@@ -38,6 +38,8 @@ DocumentResource* DocumentResource::FetchSVGDocument(FetchParameters& params,
ResourceClient* client) {
DCHECK_EQ(params.GetResourceRequest().GetFrameType(),
network::mojom::RequestContextFrameType::kNone);
+ DCHECK_EQ(params.GetResourceRequest().GetFetchRequestMode(),
+ network::mojom::FetchRequestMode::kSameOrigin);
params.SetRequestContext(WebURLRequest::kRequestContextImage);
return ToDocumentResource(
fetcher->RequestResource(params, SVGDocumentResourceFactory(), client));
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 1b2e6a28ecd..c567b71c3d0 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
@@ -24,7 +24,9 @@
#include "third_party/blink/renderer/core/loader/resource/image_resource.h"
#include <stdint.h>
+#include <algorithm>
#include <memory>
+#include <utility>
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/core/loader/resource/image_resource_content.h"
@@ -74,7 +76,8 @@ class ImageResource::ImageResourceInfoImpl final
USING_GARBAGE_COLLECTED_MIXIN(ImageResourceInfoImpl);
public:
- ImageResourceInfoImpl(ImageResource* resource) : resource_(resource) {
+ explicit ImageResourceInfoImpl(ImageResource* resource)
+ : resource_(resource) {
DCHECK(resource_);
}
void Trace(blink::Visitor* visitor) override {
@@ -132,6 +135,14 @@ class ImageResource::ImageResourceInfoImpl final
initiator_name);
}
+ void LoadDeferredImage(ResourceFetcher* fetcher) override {
+ if (resource_->GetType() == Resource::kImage &&
+ resource_->StillNeedsLoad() &&
+ !fetcher->ShouldDeferImageLoad(resource_->Url())) {
+ fetcher->StartLoad(resource_);
+ }
+ }
+
const Member<ImageResource> resource_;
};
@@ -139,7 +150,7 @@ class ImageResource::ImageResourceFactory : public NonTextResourceFactory {
STACK_ALLOCATED();
public:
- ImageResourceFactory(const FetchParameters& fetch_params)
+ explicit ImageResourceFactory(const FetchParameters& fetch_params)
: NonTextResourceFactory(Resource::kImage),
fetch_params_(&fetch_params) {}
@@ -147,7 +158,7 @@ class ImageResource::ImageResourceFactory : public NonTextResourceFactory {
const ResourceLoaderOptions& options) const override {
return new ImageResource(request, options,
ImageResourceContent::CreateNotStarted(),
- fetch_params_->GetPlaceholderImageRequestType() ==
+ fetch_params_->GetImageRequestOptimization() ==
FetchParameters::kAllowPlaceholder);
}
@@ -173,15 +184,16 @@ ImageResource* ImageResource::Fetch(FetchParameters& params,
return resource;
}
-bool ImageResource::CanReuse(
+Resource::MatchStatus ImageResource::CanReuse(
const FetchParameters& params,
scoped_refptr<const SecurityOrigin> new_source_origin) const {
// If the image is a placeholder, but this fetch doesn't allow a
// placeholder, then do not reuse this resource.
- if (params.GetPlaceholderImageRequestType() !=
+ if (params.GetImageRequestOptimization() !=
FetchParameters::kAllowPlaceholder &&
- placeholder_option_ != PlaceholderOption::kDoNotReloadPlaceholder)
- return false;
+ placeholder_option_ != PlaceholderOption::kDoNotReloadPlaceholder) {
+ return MatchStatus::kImagePlaceholder;
+ }
return Resource::CanReuse(params, std::move(new_source_origin));
}
@@ -234,9 +246,8 @@ void ImageResource::OnMemoryDump(WebMemoryDumpLevelOfDetail level_of_detail,
Resource::OnMemoryDump(level_of_detail, memory_dump);
const String name = GetMemoryDumpName() + "/image_content";
auto* dump = memory_dump->CreateMemoryAllocatorDump(name);
- size_t encoded_size =
- content_->HasImage() ? content_->GetImage()->Data()->size() : 0;
- dump->AddScalar("size", "bytes", encoded_size);
+ if (content_->HasImage() && content_->GetImage()->Data())
+ dump->AddScalar("size", "bytes", content_->GetImage()->Data()->size());
}
void ImageResource::Trace(blink::Visitor* visitor) {
@@ -573,7 +584,10 @@ void ImageResource::ReloadIfLoFiOrPlaceholderImage(
DCHECK(!is_scheduling_reload_);
is_scheduling_reload_ = true;
- SetCachePolicyBypassingCache();
+ if (GetResourceRequest().GetPreviewsState() &
+ (WebURLRequest::kClientLoFiOn | WebURLRequest::kServerLoFiOn)) {
+ SetCachePolicyBypassingCache();
+ }
// The reloaded image should not use any previews transformations.
WebURLRequest::PreviewsState previews_state_for_reload =
@@ -629,8 +643,7 @@ void ImageResource::OnePartInMultipartReceived(
if (!GetResponse().IsNull()) {
CHECK_EQ(GetResponse().WasFetchedViaServiceWorker(),
response.WasFetchedViaServiceWorker());
- CHECK_EQ(GetResponse().ResponseTypeViaServiceWorker(),
- response.ResponseTypeViaServiceWorker());
+ CHECK_EQ(GetResponse().GetType(), response.GetType());
}
SetResponse(response);
@@ -671,8 +684,7 @@ bool ImageResource::IsAccessAllowed(
ImageResourceInfo::kHasSingleSecurityOrigin)
return false;
- DCHECK(security_origin);
- if (PassesAccessControlCheck(*security_origin))
+ if (IsSameOriginOrCORSSuccessful())
return true;
return security_origin->CanReadContent(GetResponse().Url());
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 db2a678ae20..32686031826 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
@@ -79,7 +79,7 @@ class CORE_EXPORT ImageResource final
void AllClientsAndObserversRemoved() override;
- bool CanReuse(
+ MatchStatus CanReuse(
const FetchParameters&,
scoped_refptr<const SecurityOrigin> new_source_origin) const override;
bool CanUseCacheValidator() const override;
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 73084594c9c..350dd361f8b 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
@@ -65,6 +65,8 @@ class NullImageResourceInfo final
const KURL&,
const AtomicString& initiator_name) override {}
+ void LoadDeferredImage(ResourceFetcher* fetcher) override {}
+
const KURL url_;
const ResourceResponse response_;
};
@@ -629,4 +631,8 @@ bool ImageResourceContent::IsCacheValidator() const {
return info_->IsCacheValidator();
}
+void ImageResourceContent::LoadDeferredImage(ResourceFetcher* fetcher) {
+ info_->LoadDeferredImage(fetcher);
+}
+
} // 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 5df45ba3f96..cd281a77399 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
@@ -178,6 +178,8 @@ class CORE_EXPORT ImageResourceContent final
bool IsAcceptableContentType();
bool IsAcceptableCompressionRatio();
+ void LoadDeferredImage(ResourceFetcher* fetcher);
+
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 bd48546a49b..ab395091115 100644
--- a/chromium/third_party/blink/renderer/core/loader/resource/image_resource_info.h
+++ b/chromium/third_party/blink/renderer/core/loader/resource/image_resource_info.h
@@ -58,6 +58,8 @@ class CORE_EXPORT ImageResourceInfo : public GarbageCollectedMixin {
const KURL&,
const AtomicString& initiator_name) = 0;
+ virtual void LoadDeferredImage(ResourceFetcher* fetcher) = 0;
+
void Trace(blink::Visitor* visitor) override {}
};
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 3920612fe91..590d49b50dd 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
@@ -195,7 +195,6 @@ void TestThatReloadIsStartedThenServeReload(
ImageResource* image_resource,
ImageResourceContent* content,
MockImageResourceObserver* observer,
- mojom::FetchCacheMode cache_mode_for_reload,
bool placeholder_before_reload) {
const char* data = reinterpret_cast<const char*>(kJpegImage2);
constexpr size_t kDataLength = sizeof(kJpegImage2);
@@ -209,8 +208,6 @@ void TestThatReloadIsStartedThenServeReload(
EXPECT_EQ(placeholder_before_reload, image_resource->ShouldShowPlaceholder());
EXPECT_EQ(g_null_atom,
image_resource->GetResourceRequest().HttpHeaderField("range"));
- EXPECT_EQ(cache_mode_for_reload,
- image_resource->GetResourceRequest().GetCacheMode());
EXPECT_EQ(content, image_resource->GetContent());
EXPECT_FALSE(content->HasImage());
@@ -672,9 +669,9 @@ TEST_P(ImageResourceReloadTest, ReloadIfLoFiOrPlaceholderAfterFinished) {
Resource::kReloadAlways);
EXPECT_EQ(3, observer->ImageChangedCount());
- TestThatReloadIsStartedThenServeReload(
- test_url, image_resource, image_resource->GetContent(), observer.get(),
- mojom::FetchCacheMode::kBypassCache, false);
+ TestThatReloadIsStartedThenServeReload(test_url, image_resource,
+ image_resource->GetContent(),
+ observer.get(), false);
}
TEST_P(ImageResourceReloadTest,
@@ -718,9 +715,9 @@ TEST_P(ImageResourceReloadTest,
Resource::kReloadAlways);
EXPECT_EQ(3, observer->ImageChangedCount());
- TestThatReloadIsStartedThenServeReload(
- test_url, image_resource, image_resource->GetContent(), observer.get(),
- mojom::FetchCacheMode::kBypassCache, false);
+ TestThatReloadIsStartedThenServeReload(test_url, image_resource,
+ image_resource->GetContent(),
+ observer.get(), false);
}
TEST_P(ImageResourceReloadTest,
@@ -802,9 +799,8 @@ TEST_P(ImageResourceReloadTest, ReloadIfLoFiOrPlaceholderViaResourceFetcher) {
EXPECT_EQ(3, observer->ImageChangedCount());
- TestThatReloadIsStartedThenServeReload(
- test_url, image_resource, content, observer.get(),
- mojom::FetchCacheMode::kBypassCache, false);
+ TestThatReloadIsStartedThenServeReload(test_url, image_resource, content,
+ observer.get(), false);
GetMemoryCache()->Remove(image_resource);
}
@@ -836,9 +832,9 @@ TEST_P(ImageResourceReloadTest, ReloadIfLoFiOrPlaceholderBeforeResponse) {
// image is still loading.
EXPECT_FALSE(observer->ImageNotifyFinishedCalled());
- TestThatReloadIsStartedThenServeReload(
- test_url, image_resource, image_resource->GetContent(), observer.get(),
- mojom::FetchCacheMode::kBypassCache, false);
+ TestThatReloadIsStartedThenServeReload(test_url, image_resource,
+ image_resource->GetContent(),
+ observer.get(), false);
}
TEST_P(ImageResourceReloadTest, ReloadIfLoFiOrPlaceholderDuringResponse) {
@@ -887,9 +883,9 @@ TEST_P(ImageResourceReloadTest, ReloadIfLoFiOrPlaceholderDuringResponse) {
// image is still loading.
EXPECT_FALSE(observer->ImageNotifyFinishedCalled());
- TestThatReloadIsStartedThenServeReload(
- test_url, image_resource, image_resource->GetContent(), observer.get(),
- mojom::FetchCacheMode::kBypassCache, false);
+ TestThatReloadIsStartedThenServeReload(test_url, image_resource,
+ image_resource->GetContent(),
+ observer.get(), false);
}
TEST_P(ImageResourceReloadTest, ReloadIfLoFiOrPlaceholderForPlaceholder) {
@@ -901,7 +897,7 @@ TEST_P(ImageResourceReloadTest, ReloadIfLoFiOrPlaceholderForPlaceholder) {
params.SetAllowImagePlaceholder();
ImageResource* image_resource = ImageResource::Fetch(params, fetcher);
EXPECT_EQ(FetchParameters::kAllowPlaceholder,
- params.GetPlaceholderImageRequestType());
+ params.GetImageRequestOptimization());
std::unique_ptr<MockImageResourceObserver> observer =
MockImageResourceObserver::Create(image_resource->GetContent());
@@ -911,9 +907,9 @@ TEST_P(ImageResourceReloadTest, ReloadIfLoFiOrPlaceholderForPlaceholder) {
image_resource->ReloadIfLoFiOrPlaceholderImage(fetcher,
Resource::kReloadAlways);
- TestThatReloadIsStartedThenServeReload(
- test_url, image_resource, image_resource->GetContent(), observer.get(),
- mojom::FetchCacheMode::kBypassCache, false);
+ TestThatReloadIsStartedThenServeReload(test_url, image_resource,
+ image_resource->GetContent(),
+ observer.get(), false);
}
TEST_P(ImageResourceReloadTest, ReloadLoFiImagesWithDuplicateURLs) {
@@ -926,14 +922,14 @@ TEST_P(ImageResourceReloadTest, ReloadLoFiImagesWithDuplicateURLs) {
ImageResource* placeholder_resource =
ImageResource::Fetch(placeholder_params, fetcher);
EXPECT_EQ(FetchParameters::kAllowPlaceholder,
- placeholder_params.GetPlaceholderImageRequestType());
+ placeholder_params.GetImageRequestOptimization());
EXPECT_TRUE(placeholder_resource->ShouldShowPlaceholder());
FetchParameters full_image_params{ResourceRequest(test_url)};
ImageResource* full_image_resource =
ImageResource::Fetch(full_image_params, fetcher);
- EXPECT_EQ(FetchParameters::kDisallowPlaceholder,
- full_image_params.GetPlaceholderImageRequestType());
+ EXPECT_EQ(FetchParameters::kNone,
+ full_image_params.GetImageRequestOptimization());
EXPECT_FALSE(full_image_resource->ShouldShowPlaceholder());
// The |placeholder_resource| should not be reused for the
@@ -1353,8 +1349,7 @@ TEST(ImageResourceTest, FetchDisallowPlaceholder) {
FetchParameters params{ResourceRequest(test_url)};
ImageResource* image_resource = ImageResource::Fetch(params, CreateFetcher());
- EXPECT_EQ(FetchParameters::kDisallowPlaceholder,
- params.GetPlaceholderImageRequestType());
+ EXPECT_EQ(FetchParameters::kNone, params.GetImageRequestOptimization());
std::unique_ptr<MockImageResourceObserver> observer =
MockImageResourceObserver::Create(image_resource->GetContent());
@@ -1369,8 +1364,7 @@ TEST(ImageResourceTest, FetchAllowPlaceholderDataURL) {
FetchParameters params{ResourceRequest(test_url)};
params.SetAllowImagePlaceholder();
ImageResource* image_resource = ImageResource::Fetch(params, CreateFetcher());
- EXPECT_EQ(FetchParameters::kDisallowPlaceholder,
- params.GetPlaceholderImageRequestType());
+ EXPECT_EQ(FetchParameters::kNone, params.GetImageRequestOptimization());
EXPECT_EQ(g_null_atom,
image_resource->GetResourceRequest().HttpHeaderField("range"));
EXPECT_FALSE(image_resource->ShouldShowPlaceholder());
@@ -1384,8 +1378,7 @@ TEST(ImageResourceTest, FetchAllowPlaceholderPostRequest) {
FetchParameters params(resource_request);
params.SetAllowImagePlaceholder();
ImageResource* image_resource = ImageResource::Fetch(params, CreateFetcher());
- EXPECT_EQ(FetchParameters::kDisallowPlaceholder,
- params.GetPlaceholderImageRequestType());
+ EXPECT_EQ(FetchParameters::kNone, params.GetImageRequestOptimization());
EXPECT_EQ(g_null_atom,
image_resource->GetResourceRequest().HttpHeaderField("range"));
EXPECT_FALSE(image_resource->ShouldShowPlaceholder());
@@ -1401,8 +1394,7 @@ TEST(ImageResourceTest, FetchAllowPlaceholderExistingRangeHeader) {
FetchParameters params(resource_request);
params.SetAllowImagePlaceholder();
ImageResource* image_resource = ImageResource::Fetch(params, CreateFetcher());
- EXPECT_EQ(FetchParameters::kDisallowPlaceholder,
- params.GetPlaceholderImageRequestType());
+ EXPECT_EQ(FetchParameters::kNone, params.GetImageRequestOptimization());
EXPECT_EQ("bytes=128-255",
image_resource->GetResourceRequest().HttpHeaderField("range"));
EXPECT_FALSE(image_resource->ShouldShowPlaceholder());
@@ -1418,7 +1410,7 @@ TEST(ImageResourceTest, FetchAllowPlaceholderSuccessful) {
params.SetAllowImagePlaceholder();
ImageResource* image_resource = ImageResource::Fetch(params, CreateFetcher());
EXPECT_EQ(FetchParameters::kAllowPlaceholder,
- params.GetPlaceholderImageRequestType());
+ params.GetImageRequestOptimization());
std::unique_ptr<MockImageResourceObserver> observer =
MockImageResourceObserver::Create(image_resource->GetContent());
@@ -1434,7 +1426,7 @@ TEST(ImageResourceTest, FetchAllowPlaceholderUnsuccessful) {
params.SetAllowImagePlaceholder();
ImageResource* image_resource = ImageResource::Fetch(params, CreateFetcher());
EXPECT_EQ(FetchParameters::kAllowPlaceholder,
- params.GetPlaceholderImageRequestType());
+ params.GetImageRequestOptimization());
EXPECT_EQ("bytes=0-2047",
image_resource->GetResourceRequest().HttpHeaderField("range"));
EXPECT_TRUE(image_resource->ShouldShowPlaceholder());
@@ -1461,9 +1453,9 @@ TEST(ImageResourceTest, FetchAllowPlaceholderUnsuccessful) {
EXPECT_EQ(2, observer->ImageChangedCount());
EXPECT_FALSE(image_resource->ShouldShowPlaceholder());
- TestThatReloadIsStartedThenServeReload(
- test_url, image_resource, image_resource->GetContent(), observer.get(),
- mojom::FetchCacheMode::kBypassCache, false);
+ TestThatReloadIsStartedThenServeReload(test_url, image_resource,
+ image_resource->GetContent(),
+ observer.get(), false);
}
TEST(ImageResourceTest, FetchAllowPlaceholderUnsuccessfulClientLoFi) {
@@ -1476,7 +1468,7 @@ TEST(ImageResourceTest, FetchAllowPlaceholderUnsuccessfulClientLoFi) {
params.SetAllowImagePlaceholder();
ImageResource* image_resource = ImageResource::Fetch(params, CreateFetcher());
EXPECT_EQ(FetchParameters::kAllowPlaceholder,
- params.GetPlaceholderImageRequestType());
+ params.GetImageRequestOptimization());
EXPECT_EQ("bytes=0-2047",
image_resource->GetResourceRequest().HttpHeaderField("range"));
EXPECT_TRUE(image_resource->ShouldShowPlaceholder());
@@ -1502,9 +1494,9 @@ TEST(ImageResourceTest, FetchAllowPlaceholderUnsuccessfulClientLoFi) {
EXPECT_FALSE(observer->ImageNotifyFinishedCalled());
EXPECT_EQ(2, observer->ImageChangedCount());
- TestThatReloadIsStartedThenServeReload(
- test_url, image_resource, image_resource->GetContent(), observer.get(),
- mojom::FetchCacheMode::kBypassCache, true);
+ TestThatReloadIsStartedThenServeReload(test_url, image_resource,
+ image_resource->GetContent(),
+ observer.get(), true);
EXPECT_FALSE(image_resource->GetContent()->GetImage()->IsBitmapImage());
EXPECT_TRUE(image_resource->ShouldShowPlaceholder());
@@ -1537,7 +1529,7 @@ TEST(ImageResourceTest, FetchAllowPlaceholderPartialContentWithoutDimensions) {
ImageResource* image_resource =
ImageResource::Fetch(params, CreateFetcher());
EXPECT_EQ(FetchParameters::kAllowPlaceholder,
- params.GetPlaceholderImageRequestType());
+ params.GetImageRequestOptimization());
EXPECT_EQ("bytes=0-2047",
image_resource->GetResourceRequest().HttpHeaderField("range"));
EXPECT_TRUE(image_resource->ShouldShowPlaceholder());
@@ -1572,7 +1564,7 @@ TEST(ImageResourceTest, FetchAllowPlaceholderPartialContentWithoutDimensions) {
TestThatReloadIsStartedThenServeReload(
test_url, image_resource, image_resource->GetContent(), observer.get(),
- mojom::FetchCacheMode::kBypassCache, test.placeholder_before_reload);
+ test.placeholder_before_reload);
EXPECT_EQ(test.expected_reload_previews_state,
image_resource->GetResourceRequest().GetPreviewsState());
@@ -1687,7 +1679,7 @@ TEST(ImageResourceTest, FetchAllowPlaceholderFullResponseDecodeSuccess) {
ImageResource* image_resource =
ImageResource::Fetch(params, CreateFetcher());
EXPECT_EQ(FetchParameters::kAllowPlaceholder,
- params.GetPlaceholderImageRequestType());
+ params.GetImageRequestOptimization());
EXPECT_EQ("bytes=0-2047",
image_resource->GetResourceRequest().HttpHeaderField("range"));
EXPECT_TRUE(image_resource->ShouldShowPlaceholder());
@@ -1746,7 +1738,7 @@ TEST(ImageResourceTest,
ImageResource* image_resource =
ImageResource::Fetch(params, CreateFetcher());
EXPECT_EQ(FetchParameters::kAllowPlaceholder,
- params.GetPlaceholderImageRequestType());
+ params.GetImageRequestOptimization());
EXPECT_EQ("bytes=0-2047",
image_resource->GetResourceRequest().HttpHeaderField("range"));
EXPECT_TRUE(image_resource->ShouldShowPlaceholder());
@@ -1778,7 +1770,7 @@ TEST(ImageResourceTest,
ImageResource* image_resource =
ImageResource::Fetch(params, CreateFetcher());
EXPECT_EQ(FetchParameters::kAllowPlaceholder,
- params.GetPlaceholderImageRequestType());
+ params.GetImageRequestOptimization());
EXPECT_EQ("bytes=0-2047",
image_resource->GetResourceRequest().HttpHeaderField("range"));
EXPECT_TRUE(image_resource->ShouldShowPlaceholder());
@@ -1798,13 +1790,16 @@ TEST(ImageResourceTest,
// The dimensions could not be extracted, and the response code was a 4xx
// error, so the full original image should be loading.
- TestThatReloadIsStartedThenServeReload(
- test_url, image_resource, image_resource->GetContent(), observer.get(),
- mojom::FetchCacheMode::kBypassCache, false);
+ TestThatReloadIsStartedThenServeReload(test_url, image_resource,
+ image_resource->GetContent(),
+ observer.get(), false);
}
}
TEST(ImageResourceTest, PeriodicFlushTest) {
+ ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
+ platform;
+
EmptyChromeClient* chrome_client = new EmptyChromeClient();
Page::PageClients clients;
FillWithEmptyClients(clients);
@@ -1812,8 +1807,6 @@ TEST(ImageResourceTest, PeriodicFlushTest) {
std::unique_ptr<DummyPageHolder> page_holder = DummyPageHolder::Create(
IntSize(800, 600), &clients, EmptyLocalFrameClient::Create(), nullptr);
- ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
- platform;
KURL test_url(kTestURL);
ScopedMockedURLLoad scoped_mocked_url_load(test_url, GetTestFilePath());
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 d499c831999..986a3aff30e 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
@@ -143,8 +143,7 @@ bool MultipartImageResourceParser::ParseHeaders() {
ResourceResponse response(original_response_.Url());
response.SetWasFetchedViaServiceWorker(
original_response_.WasFetchedViaServiceWorker());
- response.SetResponseTypeViaServiceWorker(
- original_response_.ResponseTypeViaServiceWorker());
+ response.SetType(original_response_.GetType());
for (const auto& header : original_response_.HttpHeaderFields())
response.AddHTTPHeaderField(header.key, header.value);
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 21f66864055..c68af5bc75e 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
@@ -26,6 +26,8 @@
#include "third_party/blink/renderer/core/loader/resource/script_resource.h"
+#include <utility>
+
#include "services/network/public/mojom/request_context_frame_type.mojom-blink.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/loader/subresource_integrity_helper.h"
@@ -36,6 +38,7 @@
#include "third_party/blink/renderer/platform/loader/fetch/integrity_metadata.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_client_walker.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
+#include "third_party/blink/renderer/platform/loader/fetch/script_cached_metadata_handler.h"
#include "third_party/blink/renderer/platform/loader/fetch/text_resource_decoder_options.h"
#include "third_party/blink/renderer/platform/loader/subresource_integrity.h"
#include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h"
@@ -67,109 +70,6 @@ bool IsRequestContextSupported(WebURLRequest::RequestContext request_context) {
} // namespace
-// SingleCachedMetadataHandlerImpl should be created when a response is
-// received, and can be used independently from Resource. - It doesn't have any
-// references to Resource. Necessary data are captured
-// from Resource when the handler is created.
-// - It is not affected by Resource's revalidation on MemoryCache.
-// The validity of the handler is solely checked by |response_url_| and
-// |response_time_| (not by Resource) by the browser process, and the cached
-// metadata written to the handler is rejected if e.g. the disk cache entry
-// has been updated and the handler refers to an older response.
-class ScriptResource::SingleCachedMetadataHandlerImpl final
- : public SingleCachedMetadataHandler {
- public:
- SingleCachedMetadataHandlerImpl(const WTF::TextEncoding&,
- std::unique_ptr<CachedMetadataSender>);
- ~SingleCachedMetadataHandlerImpl() override = default;
- void Trace(blink::Visitor*) override;
- void SetCachedMetadata(uint32_t, const char*, size_t, CacheType) override;
- void ClearCachedMetadata(CacheType) override;
- scoped_refptr<CachedMetadata> GetCachedMetadata(uint32_t) const override;
-
- // This returns the encoding at the time of ResponseReceived().
- // Therefore this does NOT reflect encoding detection from body contents,
- // but the final encoding after the encoding detection can be determined
- // uniquely from Encoding(), provided the body content is the same,
- // as we can assume the encoding detection will results in the same final
- // encoding.
- // TODO(hiroshige): Make this semantics cleaner.
- String Encoding() const override { return String(encoding_.GetName()); }
-
- bool IsServedFromCacheStorage() const override {
- return sender_->IsServedFromCacheStorage();
- }
-
- // Sets the serialized metadata retrieved from the platform's cache.
- void SetSerializedCachedMetadata(const char*, size_t);
-
- private:
- void SendToPlatform();
-
- scoped_refptr<CachedMetadata> cached_metadata_;
- std::unique_ptr<CachedMetadataSender> sender_;
-
- const WTF::TextEncoding encoding_;
-};
-
-ScriptResource::SingleCachedMetadataHandlerImpl::
- SingleCachedMetadataHandlerImpl(
- const WTF::TextEncoding& encoding,
- std::unique_ptr<CachedMetadataSender> sender)
- : sender_(std::move(sender)), encoding_(encoding) {}
-
-void ScriptResource::SingleCachedMetadataHandlerImpl::Trace(
- blink::Visitor* visitor) {
- CachedMetadataHandler::Trace(visitor);
-}
-
-void ScriptResource::SingleCachedMetadataHandlerImpl::SetCachedMetadata(
- uint32_t data_type_id,
- const char* 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.
- DCHECK(!cached_metadata_);
- cached_metadata_ = CachedMetadata::Create(data_type_id, data, size);
- if (cache_type == CachedMetadataHandler::kSendToPlatform)
- SendToPlatform();
-}
-
-void ScriptResource::SingleCachedMetadataHandlerImpl::ClearCachedMetadata(
- CachedMetadataHandler::CacheType cache_type) {
- cached_metadata_ = nullptr;
- if (cache_type == CachedMetadataHandler::kSendToPlatform)
- SendToPlatform();
-}
-
-scoped_refptr<CachedMetadata>
-ScriptResource::SingleCachedMetadataHandlerImpl::GetCachedMetadata(
- uint32_t data_type_id) const {
- if (!cached_metadata_ || cached_metadata_->DataTypeID() != data_type_id)
- return nullptr;
- return cached_metadata_;
-}
-
-void ScriptResource::SingleCachedMetadataHandlerImpl::
- SetSerializedCachedMetadata(const char* data, size_t size) {
- // We only expect to receive cached metadata from the platform once. If this
- // triggers, it indicates an efficiency problem which is most likely
- // unexpected in code designed to improve performance.
- DCHECK(!cached_metadata_);
- cached_metadata_ = CachedMetadata::CreateFromSerializedData(data, size);
-}
-
-void ScriptResource::SingleCachedMetadataHandlerImpl::SendToPlatform() {
- if (cached_metadata_) {
- const Vector<char>& serialized_data = cached_metadata_->SerializedData();
- sender_->Send(serialized_data.data(), serialized_data.size());
- } else {
- sender_->Send(nullptr, 0);
- }
-}
-
ScriptResource* ScriptResource::Fetch(FetchParameters& params,
ResourceFetcher* fetcher,
ResourceClient* client) {
@@ -199,14 +99,14 @@ void ScriptResource::OnMemoryDump(WebMemoryDumpLevelOfDetail level_of_detail,
dump->Guid(), String(WTF::Partitions::kAllocatedObjectPoolName));
}
-const MovableString& ScriptResource::SourceText() {
+const ParkableString& ScriptResource::SourceText() {
DCHECK(IsLoaded());
if (source_text_.IsNull() && Data()) {
String source_text = DecodedText();
ClearData();
SetDecodedSize(source_text.CharactersSizeInBytes());
- source_text_ = MovableString(source_text.ReleaseImpl());
+ source_text_ = ParkableString(source_text.ReleaseImpl());
}
return source_text_;
@@ -218,36 +118,30 @@ SingleCachedMetadataHandler* ScriptResource::CacheHandler() {
CachedMetadataHandler* ScriptResource::CreateCachedMetadataHandler(
std::unique_ptr<CachedMetadataSender> send_callback) {
- return new SingleCachedMetadataHandlerImpl(Encoding(),
- std::move(send_callback));
+ return new ScriptCachedMetadataHandler(Encoding(), std::move(send_callback));
}
void ScriptResource::SetSerializedCachedMetadata(const char* data,
size_t size) {
Resource::SetSerializedCachedMetadata(data, size);
- SingleCachedMetadataHandlerImpl* cache_handler =
- static_cast<SingleCachedMetadataHandlerImpl*>(Resource::CacheHandler());
+ ScriptCachedMetadataHandler* cache_handler =
+ static_cast<ScriptCachedMetadataHandler*>(Resource::CacheHandler());
if (cache_handler) {
cache_handler->SetSerializedCachedMetadata(data, size);
}
}
void ScriptResource::DestroyDecodedDataForFailedRevalidation() {
- source_text_ = MovableString();
+ source_text_ = ParkableString();
SetDecodedSize(0);
}
-AccessControlStatus ScriptResource::CalculateAccessControlStatus(
- const SecurityOrigin* security_origin) const {
- if (GetResponse().WasFetchedViaServiceWorker()) {
- if (GetCORSStatus() == CORSStatus::kServiceWorkerOpaque)
- return kOpaqueResource;
- return kSharableCrossOrigin;
- }
+AccessControlStatus ScriptResource::CalculateAccessControlStatus() const {
+ if (GetCORSStatus() == CORSStatus::kServiceWorkerOpaque)
+ return kOpaqueResource;
- if (security_origin && PassesAccessControlCheck(*security_origin))
+ if (IsSameOriginOrCORSSuccessful())
return kSharableCrossOrigin;
-
return kNotSharableCrossOrigin;
}
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 97dee5e861d..f274de7d55c 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
@@ -26,21 +26,22 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_RESOURCE_SCRIPT_RESOURCE_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_RESOURCE_SCRIPT_RESOURCE_H_
+#include <memory>
+
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/loader/resource/text_resource.h"
+#include "third_party/blink/renderer/platform/bindings/parkable_string.h"
#include "third_party/blink/renderer/platform/loader/fetch/access_control_status.h"
#include "third_party/blink/renderer/platform/loader/fetch/integrity_metadata.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_client.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h"
#include "third_party/blink/renderer/platform/loader/fetch/text_resource_decoder_options.h"
-#include "third_party/blink/renderer/platform/wtf/text/movable_string.h"
namespace blink {
class FetchParameters;
class KURL;
class ResourceFetcher;
-class ScriptResource;
class CORE_EXPORT ScriptResource final : public TextResource {
public:
@@ -69,9 +70,9 @@ class CORE_EXPORT ScriptResource final : public TextResource {
void SetSerializedCachedMetadata(const char*, size_t) override;
- const MovableString& SourceText();
+ const ParkableString& SourceText();
- AccessControlStatus CalculateAccessControlStatus(const SecurityOrigin*) const;
+ AccessControlStatus CalculateAccessControlStatus() const;
SingleCachedMetadataHandler* CacheHandler();
@@ -80,8 +81,6 @@ class CORE_EXPORT ScriptResource final : public TextResource {
std::unique_ptr<CachedMetadataSender> send_callback) override;
private:
- class SingleCachedMetadataHandlerImpl;
-
class ScriptResourceFactory : public ResourceFactory {
public:
ScriptResourceFactory()
@@ -102,11 +101,11 @@ class CORE_EXPORT ScriptResource final : public TextResource {
bool CanUseCacheValidator() const override;
- MovableString source_text_;
+ ParkableString source_text_;
};
DEFINE_RESOURCE_TYPE_CASTS(Script);
} // namespace blink
-#endif
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_RESOURCE_SCRIPT_RESOURCE_H_
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 5716c9ac093..93f68eaf61e 100644
--- a/chromium/third_party/blink/renderer/core/loader/subresource_filter.cc
+++ b/chromium/third_party/blink/renderer/core/loader/subresource_filter.cc
@@ -13,8 +13,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/core/loader/document_loader.h"
-#include "third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.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/text/string_builder.h"
@@ -69,12 +67,6 @@ bool SubresourceFilter::AllowLoad(
}
bool SubresourceFilter::AllowWebSocketConnection(const KURL& url) {
- // WebSocket is handled via document on the main thread unless the
- // experimental off-main-thread WebSocket flag is enabled. See
- // https://crbug.com/825740 for the details of the off-main-thread WebSocket.
- DCHECK(execution_context_->IsDocument() ||
- RuntimeEnabledFeatures::OffMainThreadWebSocketEnabled());
-
WebDocumentSubresourceFilter::LoadPolicy load_policy =
subresource_filter_->GetLoadPolicyForWebSocketConnect(url);
diff --git a/chromium/third_party/blink/renderer/core/loader/text_track_loader.cc b/chromium/third_party/blink/renderer/core/loader/text_track_loader.cc
index a2968adf1b4..455329ba70d 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
@@ -25,6 +25,7 @@
#include "third_party/blink/renderer/core/loader/text_track_loader.h"
+#include "services/network/public/mojom/fetch_api.mojom-shared.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/inspector/console_message.h"
@@ -66,32 +67,6 @@ void TextTrackLoader::CancelLoad() {
ClearResource();
}
-void TextTrackLoader::ResponseReceived(Resource*,
- const ResourceResponse& response,
- std::unique_ptr<WebDataConsumerHandle>) {
- if (response.IsOpaqueResponseFromServiceWorker()) {
- CorsPolicyPreventedLoad(GetDocument().GetSecurityOrigin(),
- response.OriginalURLViaServiceWorker());
- }
-}
-
-bool TextTrackLoader::RedirectReceived(Resource* resource,
- const ResourceRequest& request,
- const ResourceResponse&) {
- DCHECK_EQ(GetResource(), resource);
- if (resource->GetResourceRequest().GetFetchRequestMode() ==
- network::mojom::FetchRequestMode::kCORS ||
- GetDocument().GetSecurityOrigin()->CanRequest(request.Url())) {
- return true;
- }
-
- CorsPolicyPreventedLoad(GetDocument().GetSecurityOrigin(), request.Url());
- if (!cue_load_timer_.IsActive())
- cue_load_timer_.StartOneShot(TimeDelta(), FROM_HERE);
- ClearResource();
- return false;
-}
-
void TextTrackLoader::DataReceived(Resource* resource,
const char* data,
size_t length) {
@@ -106,20 +81,6 @@ void TextTrackLoader::DataReceived(Resource* resource,
cue_parser_->ParseBytes(data, length);
}
-void TextTrackLoader::CorsPolicyPreventedLoad(
- const SecurityOrigin* security_origin,
- const KURL& url) {
- String console_message(
- "Text track from origin '" + SecurityOrigin::Create(url)->ToString() +
- "' has been blocked from loading: Not at same origin as the document, "
- "and parent of track element does not have a 'crossorigin' attribute. "
- "Origin '" +
- security_origin->ToString() + "' is therefore not allowed access.");
- GetDocument().AddConsoleMessage(ConsoleMessage::Create(
- kSecurityMessageSource, kErrorMessageLevel, console_message));
- state_ = kFailed;
-}
-
void TextTrackLoader::NotifyFinished(Resource* resource) {
DCHECK_EQ(GetResource(), resource);
if (cue_parser_)
@@ -145,16 +106,17 @@ bool TextTrackLoader::Load(const KURL& url,
ResourceLoaderOptions options;
options.initiator_info.name = FetchInitiatorTypeNames::track;
+ // Let |request| be the result of creating a potential-CORS request
+ // given |URL|, "track", and |corsAttributeState|, and with the same-origin
+ // fallback flag set.
FetchParameters cue_fetch_params(ResourceRequest(url), options);
- if (cross_origin != kCrossOriginAttributeNotSet) {
+ if (cross_origin == kCrossOriginAttributeNotSet) {
+ cue_fetch_params.MutableResourceRequest().SetFetchRequestMode(
+ network::mojom::FetchRequestMode::kSameOrigin);
+ } else {
cue_fetch_params.SetCrossOriginAccessControl(
GetDocument().GetSecurityOrigin(), cross_origin);
- } else if (!GetDocument().GetSecurityOrigin()->CanRequest(url)) {
- // Text track elements without 'crossorigin' set on the parent are "No
- // CORS"; report error if not same-origin.
- CorsPolicyPreventedLoad(GetDocument().GetSecurityOrigin(), url);
- return false;
}
ResourceFetcher* fetcher = GetDocument().Fetcher();
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 7547f531dba..c5da0c0797f 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
@@ -68,12 +68,6 @@ class TextTrackLoader final : public GarbageCollectedFinalized<TextTrackLoader>,
private:
// RawResourceClient
- void ResponseReceived(Resource*,
- const ResourceResponse&,
- std::unique_ptr<WebDataConsumerHandle>) override;
- bool RedirectReceived(Resource*,
- const ResourceRequest&,
- const ResourceResponse&) override;
void DataReceived(Resource*, const char* data, size_t length) override;
void NotifyFinished(Resource*) override;
String DebugName() const override { return "TextTrackLoader"; }
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 44b688f05be..efbca2cb40e 100644
--- a/chromium/third_party/blink/renderer/core/loader/threadable_loader.cc
+++ b/chromium/third_party/blink/renderer/core/loader/threadable_loader.cc
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2011, 2012 Google Inc. All rights reserved.
+ * Copyright (C) 2013, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -30,35 +31,1082 @@
#include "third_party/blink/renderer/core/loader/threadable_loader.h"
-#include "third_party/blink/renderer/core/execution_context/execution_context.h"
-#include "third_party/blink/renderer/core/loader/document_threadable_loader.h"
-#include "third_party/blink/renderer/core/loader/threadable_loading_context.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"
+#include "services/network/public/mojom/cors.mojom-blink.h"
+#include "services/network/public/mojom/fetch_api.mojom-blink.h"
+#include "third_party/blink/public/common/service_worker/service_worker_utils.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_cors.h"
+#include "third_party/blink/public/platform/web_security_origin.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/frame/frame_console.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/web_feature.h"
+#include "third_party/blink/renderer/core/inspector/console_message.h"
+#include "third_party/blink/renderer/core/inspector/inspector_network_agent.h"
+#include "third_party/blink/renderer/core/inspector/inspector_trace_events.h"
+#include "third_party/blink/renderer/core/loader/base_fetch_context.h"
+#include "third_party/blink/renderer/core/loader/frame_loader.h"
+#include "third_party/blink/renderer/core/loader/threadable_loader_client.h"
+#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/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"
+#include "third_party/blink/renderer/platform/loader/fetch/fetch_parameters.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_loader.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/shared_buffer.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/wtf/assertions.h"
namespace blink {
-ThreadableLoader* ThreadableLoader::Create(
- ExecutionContext& context,
+namespace {
+
+// Fetch API Spec: https://fetch.spec.whatwg.org/#cors-preflight-fetch-0
+AtomicString CreateAccessControlRequestHeadersHeader(
+ const HTTPHeaderMap& headers) {
+ Vector<String> filtered_headers;
+ for (const auto& header : headers) {
+ // Exclude CORS-safelisted headers.
+ if (CORS::IsCORSSafelistedHeader(header.key, header.value))
+ continue;
+ // Calling a deprecated function, but eventually this function,
+ // |CreateAccessControlRequestHeadersHeader| will be removed.
+ // When the request is from a Worker, referrer header was added by
+ // WorkerThreadableLoader. But it should not be added to
+ // Access-Control-Request-Headers header.
+ if (DeprecatedEqualIgnoringCase(header.key, "referer"))
+ continue;
+ filtered_headers.push_back(header.key.DeprecatedLower());
+ }
+ if (!filtered_headers.size())
+ return g_null_atom;
+
+ // Sort header names lexicographically.
+ std::sort(filtered_headers.begin(), filtered_headers.end(),
+ WTF::CodePointCompareLessThan);
+ StringBuilder header_buffer;
+ for (const String& header : filtered_headers) {
+ if (!header_buffer.IsEmpty())
+ header_buffer.Append(",");
+ header_buffer.Append(header);
+ }
+
+ return header_buffer.ToAtomicString();
+}
+
+} // namespace
+
+// DetachedClient is a ThreadableLoaderClient for a "detached"
+// ThreadableLoader. It's for fetch requests with keepalive set, so
+// it keeps itself alive during loading.
+class ThreadableLoader::DetachedClient final
+ : public GarbageCollectedFinalized<DetachedClient>,
+ public ThreadableLoaderClient {
+ public:
+ explicit DetachedClient(ThreadableLoader* loader)
+ : self_keep_alive_(this), loader_(loader) {}
+ ~DetachedClient() override {}
+
+ void DidFinishLoading(unsigned long identifier) override {
+ self_keep_alive_.Clear();
+ }
+ void DidFail(const ResourceError&) override { self_keep_alive_.Clear(); }
+ void DidFailRedirectCheck() override { self_keep_alive_.Clear(); }
+ void Trace(Visitor* visitor) { visitor->Trace(loader_); }
+
+ private:
+ SelfKeepAlive<DetachedClient> self_keep_alive_;
+ // Keep it alive.
+ const Member<ThreadableLoader> loader_;
+};
+
+class ThreadableLoader::AssignOnScopeExit final {
+ STACK_ALLOCATED();
+
+ public:
+ AssignOnScopeExit(const KURL& from, KURL* to) : from_(from), to_(to) {}
+ ~AssignOnScopeExit() { *to_ = from_; }
+
+ private:
+ const KURL& from_;
+ KURL* to_;
+
+ DISALLOW_COPY_AND_ASSIGN(AssignOnScopeExit);
+};
+
+// Max number of CORS redirects handled in ThreadableLoader.
+// See https://fetch.spec.whatwg.org/#http-redirect-fetch.
+// //net/url_request/url_request.cc and
+// //services/network/cors/cors_url_loader.cc also implement the same logic
+// separately.
+static const int kMaxRedirects = 20;
+
+// static
+std::unique_ptr<ResourceRequest>
+ThreadableLoader::CreateAccessControlPreflightRequest(
+ const ResourceRequest& request,
+ const SecurityOrigin* origin) {
+ const KURL& request_url = request.Url();
+
+ DCHECK(request_url.User().IsEmpty());
+ DCHECK(request_url.Pass().IsEmpty());
+
+ std::unique_ptr<ResourceRequest> preflight_request =
+ std::make_unique<ResourceRequest>(request_url);
+ preflight_request->SetHTTPMethod(HTTPNames::OPTIONS);
+ preflight_request->SetHTTPHeaderField(
+ HTTPNames::Access_Control_Request_Method, request.HttpMethod());
+ preflight_request->SetPriority(request.Priority());
+ preflight_request->SetRequestContext(request.GetRequestContext());
+ preflight_request->SetFetchCredentialsMode(
+ network::mojom::FetchCredentialsMode::kOmit);
+ preflight_request->SetSkipServiceWorker(true);
+ // TODO(domfarolino): Use ReferrerString() once https://crbug.com/850813 is
+ // closed and we stop storing the referrer string as a `Referer` header.
+ preflight_request->SetReferrerString(request.HttpReferrer());
+ preflight_request->SetReferrerPolicy(request.GetReferrerPolicy());
+
+ if (request.IsExternalRequest()) {
+ preflight_request->SetHTTPHeaderField(
+ HTTPNames::Access_Control_Request_External, "true");
+ }
+
+ const AtomicString request_headers =
+ CreateAccessControlRequestHeadersHeader(request.HttpHeaderFields());
+ if (request_headers != g_null_atom) {
+ preflight_request->SetHTTPHeaderField(
+ HTTPNames::Access_Control_Request_Headers, request_headers);
+ }
+
+ if (origin)
+ preflight_request->SetHTTPOrigin(origin);
+
+ return preflight_request;
+}
+
+// static
+std::unique_ptr<ResourceRequest>
+ThreadableLoader::CreateAccessControlPreflightRequestForTesting(
+ const ResourceRequest& request) {
+ return CreateAccessControlPreflightRequest(request, nullptr);
+}
+
+ThreadableLoader::ThreadableLoader(
+ ExecutionContext& execution_context,
ThreadableLoaderClient* client,
- const ThreadableLoaderOptions& options,
- const ResourceLoaderOptions& resource_loader_options) {
+ const ResourceLoaderOptions& resource_loader_options)
+ : client_(client),
+ execution_context_(execution_context),
+ resource_loader_options_(resource_loader_options),
+ out_of_blink_cors_(RuntimeEnabledFeatures::OutOfBlinkCORSEnabled()),
+ security_origin_(resource_loader_options_.security_origin),
+ is_using_data_consumer_handle_(false),
+ async_(resource_loader_options.synchronous_policy ==
+ kRequestAsynchronously),
+ request_context_(WebURLRequest::kRequestContextUnspecified),
+ fetch_request_mode_(network::mojom::FetchRequestMode::kSameOrigin),
+ fetch_credentials_mode_(network::mojom::FetchCredentialsMode::kOmit),
+ timeout_timer_(execution_context_->GetTaskRunner(TaskType::kNetworking),
+ this,
+ &ThreadableLoader::DidTimeout),
+ redirect_limit_(kMaxRedirects),
+ redirect_mode_(network::mojom::FetchRedirectMode::kFollow),
+ override_referrer_(false) {
DCHECK(client);
- if (context.IsWorkerGlobalScope())
- ToWorkerGlobalScope(&context)->EnsureFetcher();
- return DocumentThreadableLoader::Create(
- *ThreadableLoadingContext::Create(context), client, options,
- resource_loader_options);
+ if (execution_context_->IsWorkerGlobalScope())
+ ToWorkerGlobalScope(execution_context_)->EnsureFetcher();
}
-void ThreadableLoader::LoadResourceSynchronously(
- ExecutionContext& context,
- const ResourceRequest& request,
- ThreadableLoaderClient& client,
- const ThreadableLoaderOptions& options,
- const ResourceLoaderOptions& resource_loader_options) {
- DocumentThreadableLoader::LoadResourceSynchronously(
- *ThreadableLoadingContext::Create(context), request, client, options,
- resource_loader_options);
+void ThreadableLoader::Start(const ResourceRequest& request) {
+ // Setting an outgoing referer is only supported in the async code path.
+ DCHECK(async_ || request.HttpReferrer().IsEmpty());
+
+ bool cors_enabled =
+ CORS::IsCORSEnabledRequestMode(request.GetFetchRequestMode());
+
+ // kPreventPreflight can be used only when the CORS is enabled.
+ DCHECK(request.CORSPreflightPolicy() ==
+ network::mojom::CORSPreflightPolicy::kConsiderPreflight ||
+ cors_enabled);
+
+ initial_request_url_ = request.Url();
+ last_request_url_ = initial_request_url_;
+ request_context_ = request.GetRequestContext();
+ fetch_request_mode_ = request.GetFetchRequestMode();
+ fetch_credentials_mode_ = request.GetFetchCredentialsMode();
+ redirect_mode_ = request.GetFetchRedirectMode();
+
+ if (request.GetFetchRequestMode() ==
+ network::mojom::FetchRequestMode::kNoCORS) {
+ SECURITY_CHECK(WebCORS::IsNoCORSAllowedContext(request_context_));
+ } else {
+ cors_flag_ = !GetSecurityOrigin()->CanRequest(request.Url());
+ }
+
+ // The CORS flag variable is not yet used at the step in the spec that
+ // corresponds to this line, but divert |cors_flag_| here for convenience.
+ if (cors_flag_ && request.GetFetchRequestMode() ==
+ network::mojom::FetchRequestMode::kSameOrigin) {
+ ThreadableLoaderClient* client = client_;
+ Clear();
+ client->DidFail(ResourceError(
+ request.Url(), network::CORSErrorStatus(
+ network::mojom::CORSError::kDisallowedByMode)));
+ return;
+ }
+
+ request_started_ = CurrentTimeTicks();
+
+ // Save any headers on the request here. If this request redirects
+ // cross-origin, we cancel the old request create a new one, and copy these
+ // headers.
+ request_headers_ = request.HttpHeaderFields();
+
+ ResourceRequest new_request(request);
+
+ // Set the service worker mode to none if "bypass for network" in DevTools is
+ // enabled.
+ bool should_bypass_service_worker = false;
+ probe::shouldBypassServiceWorker(execution_context_,
+ &should_bypass_service_worker);
+ if (should_bypass_service_worker)
+ new_request.SetSkipServiceWorker(true);
+
+ // In S13nServiceWorker, if the controller service worker has no fetch event
+ // handler, it's skipped entirely, so we should treat that case the same as
+ // having no controller. In non-S13nServiceWorker, we can't do that since we
+ // don't know which service worker will handle the request since it's
+ // determined on the browser process and skipWaiting() can happen in the
+ // meantime.
+ //
+ // TODO(crbug.com/715640): When non-S13nServiceWorker is removed,
+ // is_controlled_by_service_worker is the same as
+ // ControllerServiceWorkerMode::kControlled, so this code can be simplified.
+ bool is_controlled_by_service_worker = false;
+ switch (execution_context_->Fetcher()->IsControlledByServiceWorker()) {
+ case blink::mojom::ControllerServiceWorkerMode::kControlled:
+ is_controlled_by_service_worker = true;
+ break;
+ case blink::mojom::ControllerServiceWorkerMode::kNoFetchEventHandler:
+ if (ServiceWorkerUtils::IsServicificationEnabled())
+ is_controlled_by_service_worker = false;
+ else
+ is_controlled_by_service_worker = true;
+ break;
+ case blink::mojom::ControllerServiceWorkerMode::kNoController:
+ is_controlled_by_service_worker = false;
+ break;
+ }
+
+ // Process the CORS protocol inside the ThreadableLoader for the
+ // following cases:
+ //
+ // - When the request is sync or the protocol is unsupported since we can
+ // assume that any service worker (SW) is skipped for such requests by
+ // content/ code.
+ // - When |skip_service_worker| is true, any SW will be skipped.
+ // - If we're not yet controlled by a SW, then we're sure that this
+ // request won't be intercepted by a SW. In case we end up with
+ // sending a CORS preflight request, the actual request to be sent later
+ // may be intercepted. This is taken care of in LoadPreflightRequest() by
+ // setting |skip_service_worker| to true.
+ //
+ // From the above analysis, you can see that the request can never be
+ // intercepted by a SW inside this if-block. It's because:
+ // - |skip_service_worker| needs to be false, and
+ // - we're controlled by a SW at this point
+ // to allow a SW to intercept the request. Even when the request gets issued
+ // asynchronously after performing the CORS preflight, it doesn't get
+ // intercepted since LoadPreflightRequest() sets the flag to kNone in advance.
+ if (!async_ || new_request.GetSkipServiceWorker() ||
+ !SchemeRegistry::ShouldTreatURLSchemeAsAllowingServiceWorkers(
+ new_request.Url().Protocol()) ||
+ !is_controlled_by_service_worker) {
+ DispatchInitialRequest(new_request);
+ return;
+ }
+
+ if (CORS::IsCORSEnabledRequestMode(request.GetFetchRequestMode())) {
+ // 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);
+ // Skip the service worker for the fallback request.
+ fallback_request_for_service_worker_.SetSkipServiceWorker(true);
+ }
+
+ LoadRequest(new_request, resource_loader_options_);
+}
+
+void ThreadableLoader::DispatchInitialRequest(ResourceRequest& request) {
+ if (out_of_blink_cors_ || (!request.IsExternalRequest() && !cors_flag_)) {
+ LoadRequest(request, resource_loader_options_);
+ return;
+ }
+
+ DCHECK(CORS::IsCORSEnabledRequestMode(request.GetFetchRequestMode()) ||
+ request.IsExternalRequest());
+
+ MakeCrossOriginAccessRequest(request);
+}
+
+void ThreadableLoader::PrepareCrossOriginRequest(
+ ResourceRequest& request) const {
+ if (GetSecurityOrigin())
+ request.SetHTTPOrigin(GetSecurityOrigin());
+
+ // TODO(domfarolino): Stop setting the HTTPReferrer header, and instead use
+ // ResourceRequest::referrer_. See https://crbug.com/850813.
+ if (override_referrer_)
+ request.SetHTTPReferrer(referrer_after_redirect_);
+}
+
+void ThreadableLoader::LoadPreflightRequest(
+ const ResourceRequest& actual_request,
+ const ResourceLoaderOptions& actual_options) {
+ std::unique_ptr<ResourceRequest> preflight_request =
+ CreateAccessControlPreflightRequest(actual_request, GetSecurityOrigin());
+
+ actual_request_ = actual_request;
+ actual_options_ = actual_options;
+
+ // Explicitly set |skip_service_worker| to true here. Although the page is
+ // not controlled by a SW at this point, a new SW may be controlling the
+ // page when this actual request gets sent later. We should not send the
+ // actual request to the SW. See https://crbug.com/604583.
+ actual_request_.SetSkipServiceWorker(true);
+
+ // Create a ResourceLoaderOptions for preflight.
+ ResourceLoaderOptions preflight_options = actual_options;
+
+ LoadRequest(*preflight_request, preflight_options);
+}
+
+void ThreadableLoader::MakeCrossOriginAccessRequest(
+ const ResourceRequest& request) {
+ DCHECK(CORS::IsCORSEnabledRequestMode(request.GetFetchRequestMode()) ||
+ request.IsExternalRequest());
+ DCHECK(client_);
+ DCHECK(!GetResource());
+
+ // Cross-origin requests are only allowed certain registered schemes. We would
+ // catch this when checking response headers later, but there is no reason to
+ // send a request, preflighted or not, that's guaranteed to be denied.
+ if (!SchemeRegistry::ShouldTreatURLSchemeAsCORSEnabled(
+ request.Url().Protocol())) {
+ DispatchDidFail(ResourceError(
+ request.Url(), network::CORSErrorStatus(
+ network::mojom::CORSError::kCORSDisabledScheme)));
+ return;
+ }
+
+ // Non-secure origins may not make "external requests":
+ // https://wicg.github.io/cors-rfc1918/#integration-fetch
+ String error_message;
+ // TODO(yhirano): Consider moving this branch elsewhere.
+ if (!execution_context_->IsSecureContext(error_message) &&
+ request.IsExternalRequest()) {
+ // TODO(yhirano): Fix the link.
+ DispatchDidFail(ResourceError::CancelledDueToAccessCheckError(
+ request.Url(), ResourceRequestBlockedReason::kOrigin,
+ "Requests to internal network resources are not allowed "
+ "from non-secure contexts (see https://goo.gl/Y0ZkNV). "
+ "This is an experimental restriction which is part of "
+ "'https://mikewest.github.io/cors-rfc1918/'."));
+ return;
+ }
+
+ ResourceRequest cross_origin_request(request);
+ ResourceLoaderOptions cross_origin_options(resource_loader_options_);
+
+ cross_origin_request.RemoveUserAndPassFromURL();
+
+ // Enforce the CORS preflight for checking the Access-Control-Allow-External
+ // header. The CORS preflight cache doesn't help for this purpose.
+ if (request.IsExternalRequest()) {
+ LoadPreflightRequest(cross_origin_request, cross_origin_options);
+ return;
+ }
+
+ if (request.GetFetchRequestMode() !=
+ network::mojom::FetchRequestMode::kCORSWithForcedPreflight) {
+ if (request.CORSPreflightPolicy() ==
+ network::mojom::CORSPreflightPolicy::kPreventPreflight) {
+ PrepareCrossOriginRequest(cross_origin_request);
+ LoadRequest(cross_origin_request, cross_origin_options);
+ return;
+ }
+
+ DCHECK_EQ(request.CORSPreflightPolicy(),
+ network::mojom::CORSPreflightPolicy::kConsiderPreflight);
+
+ // We use ContainsOnlyCORSSafelistedOrForbiddenHeaders() here since
+ // |request| may have been modified in the process of loading (not from
+ // the user's input). For example, referrer. We need to accept them. For
+ // security, we must reject forbidden headers/methods at the point we
+ // accept user's input. Not here.
+ if (CORS::IsCORSSafelistedMethod(request.HttpMethod()) &&
+ CORS::ContainsOnlyCORSSafelistedOrForbiddenHeaders(
+ request.HttpHeaderFields())) {
+ PrepareCrossOriginRequest(cross_origin_request);
+ LoadRequest(cross_origin_request, cross_origin_options);
+ return;
+ }
+ }
+
+ // Now, we need to check that the request passes the CORS preflight either by
+ // issuing a CORS preflight or based on an entry in the CORS preflight cache.
+
+ bool should_ignore_preflight_cache = false;
+ // Prevent use of the CORS preflight cache when instructed by the DevTools
+ // not to use caches.
+ probe::shouldForceCORSPreflight(execution_context_,
+ &should_ignore_preflight_cache);
+ if (should_ignore_preflight_cache ||
+ !CORS::CheckIfRequestCanSkipPreflight(
+ GetSecurityOrigin()->ToString(), cross_origin_request.Url(),
+ cross_origin_request.GetFetchCredentialsMode(),
+ cross_origin_request.HttpMethod(),
+ cross_origin_request.HttpHeaderFields())) {
+ LoadPreflightRequest(cross_origin_request, cross_origin_options);
+ return;
+ }
+
+ // We don't want any requests that could involve a CORS preflight to get
+ // intercepted by a foreign SW, even if we have the result of the preflight
+ // cached already. See https://crbug.com/674370.
+ cross_origin_request.SetSkipServiceWorker(true);
+
+ PrepareCrossOriginRequest(cross_origin_request);
+ LoadRequest(cross_origin_request, cross_origin_options);
+}
+
+ThreadableLoader::~ThreadableLoader() {
+ // |client_| is a raw pointer and having a non-null |client_| here probably
+ // means UaF.
+ // In the detached case, |this| is held by DetachedClient defined above, but
+ // SelfKeepAlive in DetachedClient is forcibly cancelled on worker thread
+ // termination. We can safely ignore this case.
+ CHECK(!client_ || detached_);
+ DCHECK(!GetResource());
+}
+
+void ThreadableLoader::SetTimeout(const TimeDelta& timeout) {
+ timeout_ = timeout;
+
+ // |request_started_| <= TimeTicks() indicates loading is either not yet
+ // started or is already finished, and thus we don't need to do anything with
+ // timeout_timer_.
+ if (request_started_ <= TimeTicks()) {
+ DCHECK(!timeout_timer_.IsActive());
+ return;
+ }
+
+ DCHECK(async_);
+ timeout_timer_.Stop();
+
+ // At the time of this method's implementation, it is only ever called for an
+ // inflight request by XMLHttpRequest.
+ //
+ // The XHR request says to resolve the time relative to when the request
+ // was initially sent, however other uses of this method may need to
+ // behave differently, in which case this should be re-arranged somehow.
+ if (!timeout_.is_zero()) {
+ TimeDelta elapsed_time = CurrentTimeTicks() - request_started_;
+ TimeDelta resolved_time = std::max(timeout_ - elapsed_time, TimeDelta());
+ timeout_timer_.StartOneShot(resolved_time, FROM_HERE);
+ }
+}
+
+void ThreadableLoader::Cancel() {
+ // Cancel can re-enter, and therefore |resource()| might be null here as a
+ // result.
+ if (!client_ || !GetResource()) {
+ Clear();
+ return;
+ }
+
+ DispatchDidFail(ResourceError::CancelledError(GetResource()->Url()));
+}
+
+void ThreadableLoader::Detach() {
+ Resource* resource = GetResource();
+ if (!resource)
+ return;
+ detached_ = true;
+ client_ = new DetachedClient(this);
+}
+
+void ThreadableLoader::SetDefersLoading(bool value) {
+ if (GetResource() && GetResource()->Loader())
+ GetResource()->Loader()->SetDefersLoading(value);
+}
+
+void ThreadableLoader::Clear() {
+ client_ = nullptr;
+ timeout_timer_.Stop();
+ request_started_ = TimeTicks();
+ if (GetResource())
+ checker_.WillRemoveClient();
+ ClearResource();
+}
+
+// In this method, we can clear |request| to tell content::WebURLLoaderImpl of
+// Chromium not to follow the redirect. This works only when this method is
+// called by RawResource::willSendRequest(). If called by
+// RawResource::didAddClient(), clearing |request| won't be propagated to
+// content::WebURLLoaderImpl. So, this loader must also get detached from the
+// resource by calling clearResource().
+// TODO(toyoshim): Implement OOR-CORS mode specific redirect code.
+bool ThreadableLoader::RedirectReceived(
+ Resource* resource,
+ const ResourceRequest& new_request,
+ const ResourceResponse& redirect_response) {
+ DCHECK(client_);
+ DCHECK_EQ(resource, GetResource());
+ {
+ AssignOnScopeExit assign_on_scope_exit(new_request.Url(),
+ &last_request_url_);
+
+ checker_.RedirectReceived();
+
+ const KURL& new_url = new_request.Url();
+ const KURL& original_url = redirect_response.Url();
+
+ if (out_of_blink_cors_)
+ return client_->WillFollowRedirect(new_url, redirect_response);
+
+ if (!actual_request_.IsNull()) {
+ ReportResponseReceived(resource->Identifier(), redirect_response);
+
+ HandlePreflightFailure(
+ original_url,
+ network::CORSErrorStatus(
+ network::mojom::CORSError::kPreflightDisallowedRedirect));
+ return false;
+ }
+
+ if (cors_flag_) {
+ if (const auto error_status = CORS::CheckAccess(
+ original_url, redirect_response.HttpStatusCode(),
+ redirect_response.HttpHeaderFields(),
+ new_request.GetFetchCredentialsMode(), *GetSecurityOrigin())) {
+ DispatchDidFail(ResourceError(original_url, *error_status));
+ return false;
+ }
+ }
+
+ if (redirect_mode_ == network::mojom::FetchRedirectMode::kError) {
+ bool follow = client_->WillFollowRedirect(new_url, redirect_response);
+ DCHECK(!follow);
+ return false;
+ }
+
+ if (redirect_mode_ == network::mojom::FetchRedirectMode::kManual) {
+ bool follow = client_->WillFollowRedirect(new_url, redirect_response);
+ DCHECK(!follow);
+ return false;
+ }
+
+ DCHECK_EQ(redirect_mode_, network::mojom::FetchRedirectMode::kFollow);
+
+ if (redirect_limit_ <= 0) {
+ ThreadableLoaderClient* client = client_;
+ Clear();
+ client->DidFailRedirectCheck();
+ return false;
+ }
+ --redirect_limit_;
+
+ // Allow same origin requests to continue after allowing clients to audit
+ // the redirect.
+ if (IsAllowedRedirect(new_request.GetFetchRequestMode(), new_url))
+ return client_->WillFollowRedirect(new_url, redirect_response);
+
+ probe::didReceiveCORSRedirectResponse(
+ execution_context_, resource->Identifier(),
+ GetDocument() && GetDocument()->GetFrame()
+ ? GetDocument()->GetFrame()->Loader().GetDocumentLoader()
+ : nullptr,
+ redirect_response, resource);
+
+ if (auto error_status = CORS::CheckRedirectLocation(
+ new_url, fetch_request_mode_, GetSecurityOrigin(),
+ cors_flag_ ? CORSFlag::Set : CORSFlag::Unset)) {
+ DispatchDidFail(ResourceError(original_url, *error_status));
+ return false;
+ }
+
+ if (!client_->WillFollowRedirect(new_url, redirect_response))
+ return false;
+
+ // FIXME: consider combining this with CORS redirect handling performed by
+ // CrossOriginAccessControl::handleRedirect().
+ if (GetResource())
+ checker_.WillRemoveClient();
+ ClearResource();
+
+ // If
+ // - CORS flag is set, and
+ // - the origin of the redirect target URL is not same origin with the
+ // origin of the current request's URL
+ // set the source origin to a unique opaque origin.
+ //
+ // See https://fetch.spec.whatwg.org/#http-redirect-fetch.
+ if (cors_flag_) {
+ scoped_refptr<const SecurityOrigin> original_origin =
+ SecurityOrigin::Create(original_url);
+ scoped_refptr<const SecurityOrigin> new_origin =
+ SecurityOrigin::Create(new_url);
+ if (!original_origin->IsSameSchemeHostPort(new_origin.get()))
+ security_origin_ = SecurityOrigin::CreateUniqueOpaque();
+ }
+
+ // Set |cors_flag_| so that further logic (corresponds to the main fetch in
+ // the spec) will be performed with CORS flag set.
+ // See https://fetch.spec.whatwg.org/#http-redirect-fetch.
+ cors_flag_ = true;
+
+ // 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());
+ }
+ // 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);
+
+ // 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.ClearHTTPOrigin();
+ cross_origin_request.ClearHTTPUserAgent();
+ // Add any request headers which we previously saved from the
+ // original request.
+ for (const auto& header : request_headers_)
+ cross_origin_request.SetHTTPHeaderField(header.key, header.value);
+ MakeCrossOriginAccessRequest(cross_origin_request);
+
+ return false;
+}
+
+void ThreadableLoader::RedirectBlocked() {
+ checker_.RedirectBlocked();
+
+ // Tells the client that a redirect was received but not followed (for an
+ // unknown reason).
+ ThreadableLoaderClient* client = client_;
+ Clear();
+ client->DidFailRedirectCheck();
+}
+
+void ThreadableLoader::DataSent(Resource* resource,
+ unsigned long long bytes_sent,
+ unsigned long long total_bytes_to_be_sent) {
+ DCHECK(client_);
+ DCHECK_EQ(resource, GetResource());
+ DCHECK(async_);
+
+ checker_.DataSent();
+ client_->DidSendData(bytes_sent, total_bytes_to_be_sent);
+}
+
+void ThreadableLoader::DataDownloaded(Resource* resource, int data_length) {
+ DCHECK(client_);
+ DCHECK_EQ(resource, GetResource());
+ DCHECK(actual_request_.IsNull());
+
+ checker_.DataDownloaded();
+ client_->DidDownloadData(data_length);
+}
+
+void ThreadableLoader::DidReceiveResourceTiming(
+ Resource* resource,
+ const ResourceTimingInfo& info) {
+ DCHECK(client_);
+ DCHECK_EQ(resource, GetResource());
+
+ client_->DidReceiveResourceTiming(info);
+}
+
+void ThreadableLoader::DidDownloadToBlob(Resource* resource,
+ scoped_refptr<BlobDataHandle> blob) {
+ DCHECK(client_);
+ DCHECK_EQ(resource, GetResource());
+
+ checker_.DidDownloadToBlob();
+ client_->DidDownloadToBlob(std::move(blob));
+}
+
+void ThreadableLoader::HandlePreflightResponse(
+ const ResourceResponse& response) {
+ base::Optional<network::CORSErrorStatus> cors_error_status =
+ CORS::CheckPreflightAccess(response.Url(), response.HttpStatusCode(),
+ response.HttpHeaderFields(),
+ actual_request_.GetFetchCredentialsMode(),
+ *GetSecurityOrigin());
+ if (cors_error_status) {
+ HandlePreflightFailure(response.Url(), *cors_error_status);
+ return;
+ }
+
+ base::Optional<network::mojom::CORSError> preflight_error =
+ CORS::CheckPreflight(response.HttpStatusCode());
+ if (preflight_error) {
+ HandlePreflightFailure(response.Url(),
+ network::CORSErrorStatus(*preflight_error));
+ return;
+ }
+
+ base::Optional<network::CORSErrorStatus> error_status;
+ if (actual_request_.IsExternalRequest()) {
+ error_status = CORS::CheckExternalPreflight(response.HttpHeaderFields());
+ if (error_status) {
+ HandlePreflightFailure(response.Url(), *error_status);
+ return;
+ }
+ }
+
+ String access_control_error_description;
+ error_status = CORS::EnsurePreflightResultAndCacheOnSuccess(
+ response.HttpHeaderFields(), GetSecurityOrigin()->ToString(),
+ actual_request_.Url(), actual_request_.HttpMethod(),
+ actual_request_.HttpHeaderFields(),
+ actual_request_.GetFetchCredentialsMode());
+ if (error_status)
+ HandlePreflightFailure(response.Url(), *error_status);
+}
+
+void ThreadableLoader::ReportResponseReceived(
+ unsigned long identifier,
+ const ResourceResponse& response) {
+ LocalFrame* frame = GetDocument() ? GetDocument()->GetFrame() : nullptr;
+ if (!frame)
+ return;
+ DocumentLoader* loader = frame->Loader().GetDocumentLoader();
+ probe::didReceiveResourceResponse(execution_context_, identifier, loader,
+ response, GetResource());
+ frame->Console().ReportResourceResponseReceived(loader, identifier, response);
+}
+
+void ThreadableLoader::ResponseReceived(
+ Resource* resource,
+ const ResourceResponse& response,
+ std::unique_ptr<WebDataConsumerHandle> handle) {
+ DCHECK_EQ(resource, GetResource());
+ DCHECK(client_);
+
+ checker_.ResponseReceived();
+
+ if (handle)
+ is_using_data_consumer_handle_ = true;
+
+ // TODO(toyoshim): Support OOR-CORS preflight and Service Worker case.
+ // Note that CORS-preflight is usually handled in the Network Service side,
+ // but still done in Blink side when it is needed on redirects.
+ // https://crbug.com/736308.
+ if (out_of_blink_cors_ && !response.WasFetchedViaServiceWorker()) {
+ DCHECK(actual_request_.IsNull());
+ fallback_request_for_service_worker_ = ResourceRequest();
+ client_->DidReceiveResponse(resource->Identifier(), response,
+ std::move(handle));
+ return;
+ }
+
+ // Code path for legacy Blink CORS.
+ if (!actual_request_.IsNull()) {
+ ReportResponseReceived(resource->Identifier(), response);
+ HandlePreflightResponse(response);
+ return;
+ }
+
+ if (response.WasFetchedViaServiceWorker()) {
+ if (response.WasFallbackRequiredByServiceWorker()) {
+ // At this point we must have m_fallbackRequestForServiceWorker. (For
+ // SharedWorker the request won't be CORS or CORS-with-preflight,
+ // therefore fallback-to-network is handled in the browser process when
+ // the ServiceWorker does not call respondWith().)
+ DCHECK(!fallback_request_for_service_worker_.IsNull());
+ ReportResponseReceived(resource->Identifier(), response);
+ LoadFallbackRequestForServiceWorker();
+ return;
+ }
+
+ // It's possible that we issue a fetch with request with non "no-cors"
+ // mode but get an opaque filtered response if a service worker is involved.
+ // We dispatch a CORS failure for the case.
+ // TODO(yhirano): This is probably not spec conformant. Fix it after
+ // https://github.com/w3c/preload/issues/100 is addressed.
+ if (fetch_request_mode_ != network::mojom::FetchRequestMode::kNoCORS &&
+ response.GetType() == network::mojom::FetchResponseType::kOpaque) {
+ DispatchDidFail(ResourceError(
+ response.Url(), network::CORSErrorStatus(
+ network::mojom::CORSError::kInvalidResponse)));
+ return;
+ }
+
+ fallback_request_for_service_worker_ = ResourceRequest();
+ client_->DidReceiveResponse(resource->Identifier(), response,
+ std::move(handle));
+ return;
+ }
+
+ // 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
+ // 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
+ // loadFallbackRequestForServiceWorker().
+ DCHECK(fallback_request_for_service_worker_.IsNull() ||
+ GetSecurityOrigin()->CanRequest(
+ fallback_request_for_service_worker_.Url()));
+ fallback_request_for_service_worker_ = ResourceRequest();
+
+ if (CORS::IsCORSEnabledRequestMode(fetch_request_mode_) && cors_flag_) {
+ base::Optional<network::CORSErrorStatus> access_error = CORS::CheckAccess(
+ response.Url(), response.HttpStatusCode(), response.HttpHeaderFields(),
+ fetch_credentials_mode_, *GetSecurityOrigin());
+ if (access_error) {
+ ReportResponseReceived(resource->Identifier(), response);
+ DispatchDidFail(ResourceError(response.Url(), *access_error));
+ return;
+ }
+ }
+
+ client_->DidReceiveResponse(resource->Identifier(), response,
+ std::move(handle));
+}
+
+void ThreadableLoader::SetSerializedCachedMetadata(Resource*,
+ const char* data,
+ size_t size) {
+ checker_.SetSerializedCachedMetadata();
+
+ if (!actual_request_.IsNull())
+ return;
+ client_->DidReceiveCachedMetadata(data, size);
+}
+
+void ThreadableLoader::DataReceived(Resource* resource,
+ const char* data,
+ size_t data_length) {
+ DCHECK_EQ(resource, GetResource());
+ DCHECK(client_);
+
+ checker_.DataReceived();
+
+ if (is_using_data_consumer_handle_)
+ return;
+
+ // Preflight data should be invisible to clients.
+ if (!actual_request_.IsNull())
+ return;
+
+ DCHECK(fallback_request_for_service_worker_.IsNull());
+
+ // TODO(junov): Fix the ThreadableLoader ecosystem to use size_t. Until then,
+ // we use safeCast to trap potential overflows.
+ client_->DidReceiveData(data, SafeCast<unsigned>(data_length));
+}
+
+void ThreadableLoader::NotifyFinished(Resource* resource) {
+ DCHECK(client_);
+ DCHECK_EQ(resource, GetResource());
+
+ checker_.NotifyFinished(resource);
+
+ // Don't throw an exception for failed sync local file loads.
+ // TODO(japhet): This logic has been moved around but unchanged since 2007.
+ // Tested by fast/xmlhttprequest/xmlhttprequest-missing-file-exception.html
+ // Do we still need this?
+ bool is_sync_to_local_file = resource->Url().IsLocalFile() && !async_;
+
+ if (resource->ErrorOccurred() && !is_sync_to_local_file) {
+ DispatchDidFail(resource->GetResourceError());
+ return;
+ }
+
+ DCHECK(fallback_request_for_service_worker_.IsNull());
+
+ if (!actual_request_.IsNull()) {
+ DCHECK(actual_request_.IsExternalRequest() || cors_flag_);
+ LoadActualRequest();
+ return;
+ }
+
+ ThreadableLoaderClient* client = client_;
+ // Protect the resource in |didFinishLoading| in order not to release the
+ // downloaded file.
+ Persistent<Resource> protect = GetResource();
+ Clear();
+ client->DidFinishLoading(resource->Identifier());
+}
+
+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
+ // 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.
+ DCHECK(client_);
+
+ DispatchDidFail(ResourceError::TimeoutError(GetResource()->Url()));
+}
+
+void ThreadableLoader::LoadFallbackRequestForServiceWorker() {
+ if (GetResource())
+ checker_.WillRemoveClient();
+ ClearResource();
+ ResourceRequest fallback_request(fallback_request_for_service_worker_);
+ fallback_request_for_service_worker_ = ResourceRequest();
+ DispatchInitialRequest(fallback_request);
+}
+
+void ThreadableLoader::LoadActualRequest() {
+ ResourceRequest actual_request = actual_request_;
+ ResourceLoaderOptions actual_options = actual_options_;
+ actual_request_ = ResourceRequest();
+ actual_options_ = ResourceLoaderOptions();
+
+ if (GetResource())
+ checker_.WillRemoveClient();
+ ClearResource();
+
+ PrepareCrossOriginRequest(actual_request);
+ LoadRequest(actual_request, actual_options);
+}
+
+void ThreadableLoader::HandlePreflightFailure(
+ const KURL& url,
+ const network::CORSErrorStatus& error_status) {
+ // Prevent NotifyFinished() from bypassing access check.
+ actual_request_ = ResourceRequest();
+
+ DispatchDidFail(ResourceError(url, error_status));
+}
+
+void ThreadableLoader::DispatchDidFail(const ResourceError& error) {
+ if (error.CORSErrorStatus()) {
+ String message = CORS::GetErrorString(
+ *error.CORSErrorStatus(), initial_request_url_, last_request_url_,
+ *GetSecurityOrigin(), Resource::kRaw,
+ resource_loader_options_.initiator_info.name);
+ execution_context_->AddConsoleMessage(ConsoleMessage::Create(
+ kJSMessageSource, kErrorMessageLevel, std::move(message)));
+ }
+ ThreadableLoaderClient* client = client_;
+ Clear();
+ client->DidFail(error);
+}
+
+void ThreadableLoader::LoadRequest(
+ ResourceRequest& request,
+ ResourceLoaderOptions resource_loader_options) {
+ resource_loader_options.cors_handling_by_resource_fetcher =
+ kDisableCORSHandlingByResourceFetcher;
+
+ bool allow_stored_credentials = false;
+ switch (request.GetFetchCredentialsMode()) {
+ case network::mojom::FetchCredentialsMode::kOmit:
+ break;
+ case network::mojom::FetchCredentialsMode::kSameOrigin:
+ // TODO(toyoshim): It's wrong to use |cors_flag| here. Fix it to use the
+ // response tainting.
+ //
+ // TODO(toyoshim): The credentials mode must work even when the "no-cors"
+ // mode is in use. See the following issues:
+ // - https://github.com/whatwg/fetch/issues/130
+ // - https://github.com/whatwg/fetch/issues/169
+ allow_stored_credentials = !cors_flag_;
+ break;
+ case network::mojom::FetchCredentialsMode::kInclude:
+ allow_stored_credentials = true;
+ break;
+ }
+ request.SetAllowStoredCredentials(allow_stored_credentials);
+
+ resource_loader_options.security_origin = security_origin_;
+
+ if (!actual_request_.IsNull())
+ resource_loader_options.data_buffering_policy = kBufferData;
+
+ if (!timeout_.is_zero()) {
+ if (!async_) {
+ request.SetTimeoutInterval(timeout_);
+ } else if (!timeout_timer_.IsActive()) {
+ // The timer can be active if this is the actual request of a
+ // CORS-with-preflight request.
+ timeout_timer_.StartOneShot(timeout_, FROM_HERE);
+ }
+ }
+
+ FetchParameters new_params(request, resource_loader_options);
+ DCHECK(!GetResource());
+
+ checker_.WillAddClient();
+ ResourceFetcher* fetcher = execution_context_->Fetcher();
+ if (request.GetRequestContext() == WebURLRequest::kRequestContextVideo ||
+ request.GetRequestContext() == WebURLRequest::kRequestContextAudio) {
+ DCHECK(async_);
+ RawResource::FetchMedia(new_params, fetcher, this);
+ } else if (request.GetRequestContext() ==
+ WebURLRequest::kRequestContextManifest) {
+ DCHECK(async_);
+ RawResource::FetchManifest(new_params, fetcher, this);
+ } else if (async_) {
+ RawResource::Fetch(new_params, fetcher, this);
+ } else {
+ RawResource::FetchSynchronously(new_params, fetcher, this);
+ }
+}
+
+bool ThreadableLoader::IsAllowedRedirect(
+ network::mojom::FetchRequestMode fetch_request_mode,
+ const KURL& url) const {
+ if (fetch_request_mode == network::mojom::FetchRequestMode::kNoCORS)
+ return true;
+
+ return !cors_flag_ && GetSecurityOrigin()->CanRequest(url);
+}
+
+const SecurityOrigin* ThreadableLoader::GetSecurityOrigin() const {
+ return security_origin_ ? security_origin_.get()
+ : execution_context_->GetSecurityOrigin();
+}
+
+Document* ThreadableLoader::GetDocument() const {
+ ExecutionContext* context = execution_context_;
+ if (context->IsDocument())
+ return ToDocument(context);
+ return nullptr;
+}
+
+void ThreadableLoader::Trace(blink::Visitor* visitor) {
+ visitor->Trace(execution_context_);
+ RawResourceClient::Trace(visitor);
}
} // namespace blink
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 c0f81603c1f..edc0e7a63be 100644
--- a/chromium/third_party/blink/renderer/core/loader/threadable_loader.h
+++ b/chromium/third_party/blink/renderer/core/loader/threadable_loader.h
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2009, 2012 Google Inc. All rights reserved.
+ * Copyright (C) 2013, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -34,88 +35,57 @@
#include <memory>
#include "base/macros.h"
+#include "services/network/public/mojom/fetch_api.mojom-blink.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/cross_thread_copier.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/loader/fetch/raw_resource.h"
+#include "third_party/blink/renderer/platform/loader/fetch/resource_error.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h"
+#include "third_party/blink/renderer/platform/network/http_header_map.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/allocator.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/time.h"
namespace blink {
-class ResourceRequest;
class ExecutionContext;
+class Document;
+class KURL;
+class ResourceRequest;
+class SecurityOrigin;
class ThreadableLoaderClient;
-struct ThreadableLoaderOptions {
- DISALLOW_NEW();
- ThreadableLoaderOptions() : timeout_milliseconds(0) {}
-
- // When adding members, CrossThreadThreadableLoaderOptionsData should
- // be updated.
-
- unsigned long timeout_milliseconds;
-};
-
-// Encode AtomicString as String to cross threads.
-struct CrossThreadThreadableLoaderOptionsData {
- STACK_ALLOCATED();
- explicit CrossThreadThreadableLoaderOptionsData(
- const ThreadableLoaderOptions& options)
- : timeout_milliseconds(options.timeout_milliseconds) {}
-
- operator ThreadableLoaderOptions() const {
- ThreadableLoaderOptions options;
- options.timeout_milliseconds = timeout_milliseconds;
- return options;
- }
-
- unsigned long timeout_milliseconds;
-};
-
-template <>
-struct CrossThreadCopier<ThreadableLoaderOptions> {
- typedef CrossThreadThreadableLoaderOptionsData Type;
- static Type Copy(const ThreadableLoaderOptions& options) {
- return CrossThreadThreadableLoaderOptionsData(options);
- }
-};
-
// Useful for doing loader operations from any thread (not threadsafe, just able
// to run on threads other than the main thread).
//
-// Arguments common to both loadResourceSynchronously() and create():
-//
-// - ThreadableLoaderOptions argument configures this ThreadableLoader's
-// behavior.
-//
-// - ResourceLoaderOptions argument will be passed to the FetchParameters
-// that this ThreadableLoader creates. It can be altered e.g. when
-// redirect happens.
-class CORE_EXPORT ThreadableLoader
- : public GarbageCollectedFinalized<ThreadableLoader> {
- public:
- static void LoadResourceSynchronously(ExecutionContext&,
- const ResourceRequest&,
- ThreadableLoaderClient&,
- const ThreadableLoaderOptions&,
- const ResourceLoaderOptions&);
+// Can perform requests either synchronously or asynchronously. Requests are
+// asynchronous by default, and this behavior can be controlled by passing
+// a ResourceLoaderOptions with synchronous_policy == kRequestSynchronously to
+// the constructor.
+// In either case, Start() must be called to actaully begin the request.
+class CORE_EXPORT ThreadableLoader final
+ : public GarbageCollectedFinalized<ThreadableLoader>,
+ private RawResourceClient {
+ USING_GARBAGE_COLLECTED_MIXIN(ThreadableLoader);
- // This method never returns nullptr.
- //
- // This method must always be followed by start() call.
- // ThreadableLoaderClient methods are never called before start() call.
+ public:
+ // ThreadableLoaderClient methods are never called before Start() call.
//
- // The async loading feature is separated into the create() method and
- // and the start() method in order to:
+ // Loading is separated into the constructor and the Start() method in order
+ // to:
// - reduce work done in a constructor
// - not to ask the users to handle failures in the constructor and other
// async failures separately
//
// Loading completes when one of the following methods are called:
- // - didFinishLoading()
- // - didFail()
- // - didFailAccessControlCheck()
- // - didFailRedirectCheck()
+ // - DidFinishLoading()
+ // - DidFail()
+ // - DidFailAccessControlCheck()
+ // - DidFailRedirectCheck()
// After any of these methods is called, the loader won't call any of the
// ThreadableLoaderClient methods.
//
@@ -123,45 +93,186 @@ class CORE_EXPORT ThreadableLoader
// client gets invalid. Also, a user must guarantee that the loading
// completes before the ThreadableLoader is destructed.
//
- // When ThreadableLoader::cancel() is called,
- // ThreadableLoaderClient::didFail() is called with a ResourceError
- // with isCancellation() returning true, if any of didFinishLoading()
- // or didFail.*() methods have not been called yet. (didFail() may be
- // called with a ResourceError with isCancellation() returning true
+ // When ThreadableLoader::Cancel() is called,
+ // ThreadableLoaderClient::DidFail() is called with a ResourceError
+ // with IsCancellation() returning true, if any of DidFinishLoading()
+ // or DidFail.*() methods have not been called yet. (DidFail() may be
+ // called with a ResourceError with IsCancellation() returning true
// also for cancellation happened inside the loader.)
//
// ThreadableLoaderClient methods may call cancel().
- static ThreadableLoader* Create(ExecutionContext&,
- ThreadableLoaderClient*,
- const ThreadableLoaderOptions&,
- const ResourceLoaderOptions&);
+ ThreadableLoader(ExecutionContext&,
+ ThreadableLoaderClient*,
+ const ResourceLoaderOptions&);
+ ~ThreadableLoader() override;
- // The methods on the ThreadableLoaderClient passed on create() call
- // may be called synchronous to start() call.
- virtual void Start(const ResourceRequest&) = 0;
+ // Exposed for testing. Code outside this class should not call this function.
+ static std::unique_ptr<ResourceRequest>
+ CreateAccessControlPreflightRequestForTesting(const ResourceRequest&);
+
+ // Must be called to actually begin the request.
+ void Start(const ResourceRequest&);
// A ThreadableLoader may have a timeout specified. It is possible, in some
// cases, for the timeout to be overridden after the request is sent (for
// example, XMLHttpRequests may override their timeout setting after sending).
//
- // Set a new timeout relative to the time the request started, in
- // milliseconds.
- virtual void OverrideTimeout(unsigned long timeout_milliseconds) = 0;
+ // If the request has already started, the new timeout will be relative to the
+ // time the request started.
+ //
+ // Passing a timeout of zero means there should be no timeout.
+ void SetTimeout(const TimeDelta& timeout);
- // Cancel the request.
- virtual void Cancel() = 0;
+ void Cancel();
- // Detach the loader from the request. This function is for "keepalive"
+ // Detach the loader from the request. This ffunction is for "keepalive"
// requests. No notification will be sent to the client, but the request
// will be processed.
- virtual void Detach() = 0;
+ void Detach();
+
+ void SetDefersLoading(bool);
+
+ void Trace(blink::Visitor* visitor) override;
+
+ private:
+ class AssignOnScopeExit;
+ class DetachedClient;
+
+ static std::unique_ptr<ResourceRequest> CreateAccessControlPreflightRequest(
+ const ResourceRequest&,
+ const SecurityOrigin*);
+
+ void Clear();
+
+ // ResourceClient
+ void NotifyFinished(Resource*) override;
+
+ String DebugName() const override { return "ThreadableLoader"; }
+
+ // RawResourceClient
+ void DataSent(Resource*,
+ unsigned long long bytes_sent,
+ unsigned long long total_bytes_to_be_sent) override;
+ void ResponseReceived(Resource*,
+ const ResourceResponse&,
+ std::unique_ptr<WebDataConsumerHandle>) override;
+ void SetSerializedCachedMetadata(Resource*, const char*, size_t) override;
+ void DataReceived(Resource*, const char* data, size_t data_length) override;
+ bool RedirectReceived(Resource*,
+ const ResourceRequest&,
+ const ResourceResponse&) override;
+ void RedirectBlocked() override;
+ void DataDownloaded(Resource*, int) override;
+ void DidReceiveResourceTiming(Resource*, const ResourceTimingInfo&) override;
+ void DidDownloadToBlob(Resource*, scoped_refptr<BlobDataHandle>) override;
+
+ // Notify Inspector and log to console about resource response. Use this
+ // method if response is not going to be finished normally.
+ void ReportResponseReceived(unsigned long identifier,
+ const ResourceResponse&);
+
+ void DidTimeout(TimerBase*);
+ // Calls the appropriate loading method according to policy and data about
+ // origin. Only for handling the initial load (including fallback after
+ // consulting ServiceWorker).
+ void DispatchInitialRequest(ResourceRequest&);
+ void MakeCrossOriginAccessRequest(const ResourceRequest&);
+
+ // Loads m_fallbackRequestForServiceWorker.
+ void LoadFallbackRequestForServiceWorker();
+ // Issues a CORS preflight.
+ void LoadPreflightRequest(const ResourceRequest&,
+ const ResourceLoaderOptions&);
+ // Loads actual_request_.
+ void LoadActualRequest();
+ // Clears actual_request_ and reports access control check failure to
+ // m_client.
+ void HandlePreflightFailure(const KURL&, const network::CORSErrorStatus&);
+ // Investigates the response for the preflight request. If successful,
+ // the actual request will be made later in NotifyFinished().
+ void HandlePreflightResponse(const ResourceResponse&);
+
+ void DispatchDidFail(const ResourceError&);
+
+ void PrepareCrossOriginRequest(ResourceRequest&) const;
+
+ // This method modifies the ResourceRequest by calling
+ // SetAllowStoredCredentials() on it based on same-origin-ness and the
+ // credentials mode.
+ //
+ // This method configures the ResourceLoaderOptions so that the underlying
+ // ResourceFetcher doesn't perform some part of the CORS logic since this
+ // class performs it by itself.
+ void LoadRequest(ResourceRequest&, ResourceLoaderOptions);
+ bool IsAllowedRedirect(network::mojom::FetchRequestMode, const KURL&) const;
+
+ const SecurityOrigin* GetSecurityOrigin() const;
+
+ // Returns null if the loader is not associated with Document.
+ // TODO(kinuko): Remove dependency to document.
+ Document* GetDocument() const;
+
+ ThreadableLoaderClient* client_;
+ Member<ExecutionContext> execution_context_;
+
+ TimeDelta timeout_;
+ // Some items may be overridden by m_forceDoNotAllowStoredCredentials and
+ // m_securityOrigin. In such a case, build a ResourceLoaderOptions with
+ // up-to-date values from them and this variable, and use it.
+ const ResourceLoaderOptions resource_loader_options_;
+
+ // True when feature OutOfBlinkCORS is enabled (https://crbug.com/736308).
+ bool out_of_blink_cors_;
+
+ // Corresponds to the CORS flag in the Fetch spec.
+ bool cors_flag_ = false;
+ scoped_refptr<const SecurityOrigin> security_origin_;
+
+ // Set to true when the response data is given to a data consumer handle.
+ bool is_using_data_consumer_handle_;
+
+ const bool async_;
+
+ // Holds the original request context (used for sanity checks).
+ WebURLRequest::RequestContext request_context_;
+
+ // Saved so that we can use the original value for the modes in
+ // ResponseReceived() where |resource| might be a reused one (e.g. preloaded
+ // resource) which can have different modes.
+ network::mojom::FetchRequestMode fetch_request_mode_;
+ network::mojom::FetchCredentialsMode fetch_credentials_mode_;
+
+ // Holds the original request for fallback in case the Service Worker
+ // does not respond.
+ ResourceRequest fallback_request_for_service_worker_;
+
+ // Holds the original request and options for it during preflight request
+ // handling phase.
+ ResourceRequest actual_request_;
+ ResourceLoaderOptions actual_options_;
+
+ KURL initial_request_url_;
+ KURL last_request_url_;
+
+ // stores request headers in case of a cross-origin redirect.
+ HTTPHeaderMap request_headers_;
+
+ TaskRunnerTimer<ThreadableLoader> timeout_timer_;
+ TimeTicks request_started_; // Time an asynchronous fetch request is started
+
+ // Max number of times that this ThreadableLoader can follow.
+ int redirect_limit_;
+
+ network::mojom::FetchRedirectMode redirect_mode_;
- virtual ~ThreadableLoader() = default;
+ // Holds the referrer after a redirect response was received. This referrer is
+ // used to populate the HTTP Referer header when following the redirect.
+ bool override_referrer_;
+ Referrer referrer_after_redirect_;
- virtual void Trace(blink::Visitor* visitor) {}
+ bool detached_ = false;
- protected:
- ThreadableLoader() = default;
+ RawResourceClientStateChecker checker_;
DISALLOW_COPY_AND_ASSIGN(ThreadableLoader);
};
diff --git a/chromium/third_party/blink/renderer/core/loader/threadable_loader_client.h b/chromium/third_party/blink/renderer/core/loader/threadable_loader_client.h
index ed55b276890..9eac59edaf5 100644
--- a/chromium/third_party/blink/renderer/core/loader/threadable_loader_client.h
+++ b/chromium/third_party/blink/renderer/core/loader/threadable_loader_client.h
@@ -50,7 +50,12 @@ class CORE_EXPORT ThreadableLoaderClient {
public:
virtual void DidSendData(unsigned long long /*bytesSent*/,
unsigned long long /*totalBytesToBeSent*/) {}
- virtual void DidReceiveRedirectTo(const KURL&) {}
+ // Note that redirects for redirect modes kError and kManual are still
+ // notified here. A client must return false in such cases.
+ virtual bool WillFollowRedirect(const KURL& new_url,
+ const ResourceResponse&) {
+ return true;
+ }
virtual void DidReceiveResponse(unsigned long /*identifier*/,
const ResourceResponse&,
std::unique_ptr<WebDataConsumerHandle>) {}
@@ -61,8 +66,6 @@ class CORE_EXPORT ThreadableLoaderClient {
virtual void DidFailRedirectCheck() {}
virtual void DidReceiveResourceTiming(const ResourceTimingInfo&) {}
- virtual bool IsDocumentThreadableLoaderClient() { return false; }
-
virtual void DidDownloadData(int /*dataLength*/) {}
// Called for requests that had DownloadToBlob set to true. Can be called with
// null if creating the blob failed for some reason (but the download itself
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 0638411771e..600bc9fe3ca 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
@@ -17,11 +17,9 @@
#include "third_party/blink/public/platform/web_url_request.h"
#include "third_party/blink/public/platform/web_url_response.h"
#include "third_party/blink/public/platform/web_worker_fetch_context.h"
-#include "third_party/blink/renderer/core/loader/document_threadable_loader.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/core/loader/threadable_loading_context.h"
#include "third_party/blink/renderer/core/loader/worker_fetch_context.h"
-#include "third_party/blink/renderer/core/loader/worker_threadable_loader.h"
#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
#include "third_party/blink/renderer/core/workers/worker_reporting_proxy.h"
#include "third_party/blink/renderer/core/workers/worker_thread_test_helper.h"
@@ -170,57 +168,37 @@ enum ThreadableLoaderToTest {
kWorkerThreadableLoaderTest,
};
-class ThreadableLoaderTestHelper {
- public:
- virtual ~ThreadableLoaderTestHelper() = default;
-
- virtual void CreateLoader(ThreadableLoaderClient*) = 0;
- virtual void StartLoader(const ResourceRequest&) = 0;
- virtual void CancelLoader() = 0;
- virtual void CancelAndClearLoader() = 0;
- virtual void ClearLoader() = 0;
- virtual Checkpoint& GetCheckpoint() = 0;
- virtual void CallCheckpoint(int) = 0;
- virtual void OnSetUp() = 0;
- virtual void OnServeRequests() = 0;
- virtual void OnTearDown() = 0;
-};
-
-class DocumentThreadableLoaderTestHelper : public ThreadableLoaderTestHelper {
+class ThreadableLoaderTestHelper final {
public:
- DocumentThreadableLoaderTestHelper()
+ ThreadableLoaderTestHelper()
: dummy_page_holder_(DummyPageHolder::Create(IntSize(1, 1))) {
GetDocument().SetURL(KURL("http://fake.url/"));
GetDocument().SetSecurityOrigin(
SecurityOrigin::Create(KURL("http://fake.url/")));
}
- void CreateLoader(ThreadableLoaderClient* client) override {
- ThreadableLoaderOptions options;
+ void CreateLoader(ThreadableLoaderClient* client) {
ResourceLoaderOptions resource_loader_options;
- loader_ = DocumentThreadableLoader::Create(
- *ThreadableLoadingContext::Create(GetDocument()), client, options,
- resource_loader_options);
+ loader_ = new ThreadableLoader(GetDocument(), client,
+ resource_loader_options);
}
- void StartLoader(const ResourceRequest& request) override {
- loader_->Start(request);
- }
+ void StartLoader(const ResourceRequest& request) { loader_->Start(request); }
- void CancelLoader() override { loader_->Cancel(); }
- void CancelAndClearLoader() override {
+ void CancelLoader() { loader_->Cancel(); }
+ void CancelAndClearLoader() {
loader_->Cancel();
loader_ = nullptr;
}
- void ClearLoader() override { loader_ = nullptr; }
- Checkpoint& GetCheckpoint() override { return checkpoint_; }
- void CallCheckpoint(int n) override { checkpoint_.Call(n); }
+ void ClearLoader() { loader_ = nullptr; }
+ Checkpoint& GetCheckpoint() { return checkpoint_; }
+ void CallCheckpoint(int n) { checkpoint_.Call(n); }
- void OnSetUp() override { SetUpMockURLs(); }
+ void OnSetUp() { SetUpMockURLs(); }
- void OnServeRequests() override { ServeAsynchronousRequests(); }
+ void OnServeRequests() { ServeAsynchronousRequests(); }
- void OnTearDown() override {
+ void OnTearDown() {
if (loader_) {
loader_->Cancel();
loader_ = nullptr;
@@ -233,234 +211,13 @@ class DocumentThreadableLoaderTestHelper : public ThreadableLoaderTestHelper {
std::unique_ptr<DummyPageHolder> dummy_page_holder_;
Checkpoint checkpoint_;
- Persistent<DocumentThreadableLoader> loader_;
-};
-
-class WebWorkerFetchContextForTest : public WebWorkerFetchContext {
- public:
- WebWorkerFetchContextForTest(KURL site_for_cookies)
- : site_for_cookies_(site_for_cookies.Copy()) {}
- void SetTerminateSyncLoadEvent(base::WaitableEvent*) override {}
- void InitializeOnWorkerThread() override {}
-
- std::unique_ptr<WebURLLoaderFactory> CreateURLLoaderFactory() override {
- return std::make_unique<WebURLLoaderFactoryWithMock>(
- Platform::Current()->GetURLLoaderMockFactory());
- }
- std::unique_ptr<WebURLLoaderFactory> WrapURLLoaderFactory(
- mojo::ScopedMessagePipeHandle) override {
- return std::make_unique<WebURLLoaderFactoryWithMock>(
- Platform::Current()->GetURLLoaderMockFactory());
- }
-
- void WillSendRequest(WebURLRequest&) override {}
- blink::mojom::ControllerServiceWorkerMode IsControlledByServiceWorker()
- const override {
- return blink::mojom::ControllerServiceWorkerMode::kNoController;
- }
- WebURL SiteForCookies() const override { return site_for_cookies_; }
-
- private:
- WebURL site_for_cookies_;
-
- DISALLOW_COPY_AND_ASSIGN(WebWorkerFetchContextForTest);
+ Persistent<ThreadableLoader> loader_;
};
-class WorkerThreadableLoaderTestHelper : public ThreadableLoaderTestHelper {
+class ThreadableLoaderTest : public testing::Test {
public:
- WorkerThreadableLoaderTestHelper()
- : dummy_page_holder_(DummyPageHolder::Create(IntSize(1, 1))) {
- GetDocument().SetURL(KURL("http://fake.url/"));
- }
-
- void CreateLoader(ThreadableLoaderClient* client) override {
- std::unique_ptr<WaitableEvent> completion_event =
- std::make_unique<WaitableEvent>();
- PostCrossThreadTask(
- *worker_loading_task_runner_, FROM_HERE,
- CrossThreadBind(&WorkerThreadableLoaderTestHelper::WorkerCreateLoader,
- CrossThreadUnretained(this),
- CrossThreadUnretained(client),
- CrossThreadUnretained(completion_event.get())));
- completion_event->Wait();
- }
-
- void StartLoader(const ResourceRequest& request) override {
- std::unique_ptr<WaitableEvent> completion_event =
- std::make_unique<WaitableEvent>();
- PostCrossThreadTask(
- *worker_loading_task_runner_, FROM_HERE,
- CrossThreadBind(&WorkerThreadableLoaderTestHelper::WorkerStartLoader,
- CrossThreadUnretained(this),
- CrossThreadUnretained(completion_event.get()),
- request));
- completion_event->Wait();
- }
-
- // Must be called on the worker thread.
- void CancelLoader() override {
- DCHECK(worker_thread_);
- DCHECK(worker_thread_->IsCurrentThread());
- loader_->Cancel();
- }
-
- void CancelAndClearLoader() override {
- DCHECK(worker_thread_);
- DCHECK(worker_thread_->IsCurrentThread());
- loader_->Cancel();
- loader_ = nullptr;
- }
-
- // Must be called on the worker thread.
- void ClearLoader() override {
- DCHECK(worker_thread_);
- DCHECK(worker_thread_->IsCurrentThread());
- loader_ = nullptr;
- }
-
- Checkpoint& GetCheckpoint() override { return checkpoint_; }
-
- void CallCheckpoint(int n) override {
- test::RunPendingTasks();
-
- std::unique_ptr<WaitableEvent> completion_event =
- std::make_unique<WaitableEvent>();
- PostCrossThreadTask(
- *worker_loading_task_runner_, FROM_HERE,
- CrossThreadBind(&WorkerThreadableLoaderTestHelper::WorkerCallCheckpoint,
- CrossThreadUnretained(this),
- CrossThreadUnretained(completion_event.get()), n));
- completion_event->Wait();
- }
-
- void OnSetUp() override {
- reporting_proxy_ = std::make_unique<WorkerReportingProxy>();
- security_origin_ = GetDocument().GetSecurityOrigin();
- parent_execution_context_task_runners_ =
- ParentExecutionContextTaskRunners::Create(&GetDocument());
- worker_thread_ = std::make_unique<WorkerThreadForTest>(
- ThreadableLoadingContext::Create(GetDocument()), *reporting_proxy_);
- WorkerClients* worker_clients = WorkerClients::Create();
-
- ProvideWorkerFetchContextToWorker(
- worker_clients, std::make_unique<WebWorkerFetchContextForTest>(
- GetDocument().SiteForCookies()));
- worker_thread_->StartWithSourceCode(
- security_origin_.get(), "//fake source code",
- parent_execution_context_task_runners_.Get(), GetDocument().Url(),
- worker_clients);
- worker_thread_->WaitForInit();
- worker_loading_task_runner_ =
- worker_thread_->GetTaskRunner(TaskType::kInternalTest);
-
- PostCrossThreadTask(*worker_loading_task_runner_, FROM_HERE,
- CrossThreadBind(&SetUpMockURLs));
- WaitForWorkerThreadSignal();
- }
-
- void OnServeRequests() override {
- test::RunPendingTasks();
- PostCrossThreadTask(*worker_loading_task_runner_, FROM_HERE,
- CrossThreadBind(&ServeAsynchronousRequests));
- WaitForWorkerThreadSignal();
- }
-
- void OnTearDown() override {
- PostCrossThreadTask(
- *worker_loading_task_runner_, FROM_HERE,
- CrossThreadBind(&WorkerThreadableLoaderTestHelper::ClearLoader,
- CrossThreadUnretained(this)));
- WaitForWorkerThreadSignal();
- PostCrossThreadTask(*worker_loading_task_runner_, FROM_HERE,
- CrossThreadBind(&UnregisterAllURLsAndClearMemoryCache));
- WaitForWorkerThreadSignal();
-
- worker_thread_->Terminate();
- worker_thread_->WaitForShutdownForTesting();
-
- // Needed to clean up the things on the main thread side and
- // avoid Resource leaks.
- test::RunPendingTasks();
- }
-
- private:
- Document& GetDocument() { return dummy_page_holder_->GetDocument(); }
-
- void WorkerCreateLoader(ThreadableLoaderClient* client,
- WaitableEvent* event) {
- DCHECK(worker_thread_);
- DCHECK(worker_thread_->IsCurrentThread());
-
- ThreadableLoaderOptions options;
- ResourceLoaderOptions resource_loader_options;
-
- // Ensure that WorkerThreadableLoader is created.
- // ThreadableLoader::create() determines whether it should create
- // a DocumentThreadableLoader or WorkerThreadableLoader based on
- // isWorkerGlobalScope().
- DCHECK(worker_thread_->GlobalScope()->IsWorkerGlobalScope());
-
- loader_ = ThreadableLoader::Create(*worker_thread_->GlobalScope(), client,
- options, resource_loader_options);
- DCHECK(loader_);
- event->Signal();
- }
-
- void WorkerStartLoader(
- WaitableEvent* event,
- std::unique_ptr<CrossThreadResourceRequestData> request_data) {
- DCHECK(worker_thread_);
- DCHECK(worker_thread_->IsCurrentThread());
-
- ResourceRequest request(request_data.get());
- request.SetFetchCredentialsMode(
- network::mojom::FetchCredentialsMode::kOmit);
- loader_->Start(request);
- event->Signal();
- }
-
- void WorkerCallCheckpoint(WaitableEvent* event, int n) {
- DCHECK(worker_thread_);
- DCHECK(worker_thread_->IsCurrentThread());
- checkpoint_.Call(n);
- event->Signal();
- }
-
- void WaitForWorkerThreadSignal() {
- WaitableEvent event;
- PostCrossThreadTask(
- *worker_loading_task_runner_, FROM_HERE,
- CrossThreadBind(&WaitableEvent::Signal, CrossThreadUnretained(&event)));
- event.Wait();
- }
-
- scoped_refptr<const SecurityOrigin> security_origin_;
- std::unique_ptr<WorkerReportingProxy> reporting_proxy_;
- std::unique_ptr<WorkerThreadForTest> worker_thread_;
-
- std::unique_ptr<DummyPageHolder> dummy_page_holder_;
- // Accessed cross-thread when worker thread posts tasks to the parent.
- CrossThreadPersistent<ParentExecutionContextTaskRunners>
- parent_execution_context_task_runners_;
- scoped_refptr<base::SingleThreadTaskRunner> worker_loading_task_runner_;
- Checkpoint checkpoint_;
- // |m_loader| must be touched only from the worker thread only.
- CrossThreadPersistent<ThreadableLoader> loader_;
-};
-
-class ThreadableLoaderTest
- : public testing::TestWithParam<ThreadableLoaderToTest> {
- public:
- ThreadableLoaderTest() {
- switch (GetParam()) {
- case kDocumentThreadableLoaderTest:
- helper_ = std::make_unique<DocumentThreadableLoaderTestHelper>();
- break;
- case kWorkerThreadableLoaderTest:
- helper_ = std::make_unique<WorkerThreadableLoaderTestHelper>();
- break;
- }
- }
+ ThreadableLoaderTest()
+ : helper_(std::make_unique<ThreadableLoaderTestHelper>()) {}
void StartLoader(const KURL& url,
network::mojom::FetchRequestMode fetch_request_mode =
@@ -501,17 +258,9 @@ class ThreadableLoaderTest
std::unique_ptr<ThreadableLoaderTestHelper> helper_;
};
-INSTANTIATE_TEST_CASE_P(Document,
- ThreadableLoaderTest,
- testing::Values(kDocumentThreadableLoaderTest));
+TEST_F(ThreadableLoaderTest, StartAndStop) {}
-INSTANTIATE_TEST_CASE_P(Worker,
- ThreadableLoaderTest,
- testing::Values(kWorkerThreadableLoaderTest));
-
-TEST_P(ThreadableLoaderTest, StartAndStop) {}
-
-TEST_P(ThreadableLoaderTest, CancelAfterStart) {
+TEST_F(ThreadableLoaderTest, CancelAfterStart) {
InSequence s;
EXPECT_CALL(GetCheckpoint(), Call(1));
CreateLoader();
@@ -528,7 +277,7 @@ TEST_P(ThreadableLoaderTest, CancelAfterStart) {
ServeRequests();
}
-TEST_P(ThreadableLoaderTest, CancelAndClearAfterStart) {
+TEST_F(ThreadableLoaderTest, CancelAndClearAfterStart) {
InSequence s;
EXPECT_CALL(GetCheckpoint(), Call(1));
CreateLoader();
@@ -546,7 +295,7 @@ TEST_P(ThreadableLoaderTest, CancelAndClearAfterStart) {
ServeRequests();
}
-TEST_P(ThreadableLoaderTest, CancelInDidReceiveResponse) {
+TEST_F(ThreadableLoaderTest, CancelInDidReceiveResponse) {
InSequence s;
EXPECT_CALL(GetCheckpoint(), Call(1));
CreateLoader();
@@ -562,7 +311,7 @@ TEST_P(ThreadableLoaderTest, CancelInDidReceiveResponse) {
ServeRequests();
}
-TEST_P(ThreadableLoaderTest, CancelAndClearInDidReceiveResponse) {
+TEST_F(ThreadableLoaderTest, CancelAndClearInDidReceiveResponse) {
InSequence s;
EXPECT_CALL(GetCheckpoint(), Call(1));
CreateLoader();
@@ -579,7 +328,7 @@ TEST_P(ThreadableLoaderTest, CancelAndClearInDidReceiveResponse) {
ServeRequests();
}
-TEST_P(ThreadableLoaderTest, CancelInDidReceiveData) {
+TEST_F(ThreadableLoaderTest, CancelInDidReceiveData) {
InSequence s;
EXPECT_CALL(GetCheckpoint(), Call(1));
CreateLoader();
@@ -596,7 +345,7 @@ TEST_P(ThreadableLoaderTest, CancelInDidReceiveData) {
ServeRequests();
}
-TEST_P(ThreadableLoaderTest, CancelAndClearInDidReceiveData) {
+TEST_F(ThreadableLoaderTest, CancelAndClearInDidReceiveData) {
InSequence s;
EXPECT_CALL(GetCheckpoint(), Call(1));
CreateLoader();
@@ -614,7 +363,7 @@ TEST_P(ThreadableLoaderTest, CancelAndClearInDidReceiveData) {
ServeRequests();
}
-TEST_P(ThreadableLoaderTest, DidFinishLoading) {
+TEST_F(ThreadableLoaderTest, DidFinishLoading) {
InSequence s;
EXPECT_CALL(GetCheckpoint(), Call(1));
CreateLoader();
@@ -623,9 +372,7 @@ TEST_P(ThreadableLoaderTest, DidFinishLoading) {
EXPECT_CALL(GetCheckpoint(), Call(2));
EXPECT_CALL(*Client(), DidReceiveResponseMock(_, _, _));
EXPECT_CALL(*Client(), DidReceiveData(StrEq("fox"), 4));
- // We expect didReceiveResourceTiming() calls in DocumentThreadableLoader;
- // it's used to connect DocumentThreadableLoader to WorkerThreadableLoader,
- // not to ThreadableLoaderClient.
+ // We expect didReceiveResourceTiming() calls in ThreadableLoader.
EXPECT_CALL(*Client(), DidReceiveResourceTiming(_));
EXPECT_CALL(*Client(), DidFinishLoading(_));
@@ -634,7 +381,7 @@ TEST_P(ThreadableLoaderTest, DidFinishLoading) {
ServeRequests();
}
-TEST_P(ThreadableLoaderTest, CancelInDidFinishLoading) {
+TEST_F(ThreadableLoaderTest, CancelInDidFinishLoading) {
InSequence s;
EXPECT_CALL(GetCheckpoint(), Call(1));
CreateLoader();
@@ -652,7 +399,7 @@ TEST_P(ThreadableLoaderTest, CancelInDidFinishLoading) {
ServeRequests();
}
-TEST_P(ThreadableLoaderTest, ClearInDidFinishLoading) {
+TEST_F(ThreadableLoaderTest, ClearInDidFinishLoading) {
InSequence s;
EXPECT_CALL(GetCheckpoint(), Call(1));
CreateLoader();
@@ -670,7 +417,7 @@ TEST_P(ThreadableLoaderTest, ClearInDidFinishLoading) {
ServeRequests();
}
-TEST_P(ThreadableLoaderTest, DidFail) {
+TEST_F(ThreadableLoaderTest, DidFail) {
InSequence s;
EXPECT_CALL(GetCheckpoint(), Call(1));
CreateLoader();
@@ -685,7 +432,7 @@ TEST_P(ThreadableLoaderTest, DidFail) {
ServeRequests();
}
-TEST_P(ThreadableLoaderTest, CancelInDidFail) {
+TEST_F(ThreadableLoaderTest, CancelInDidFail) {
InSequence s;
EXPECT_CALL(GetCheckpoint(), Call(1));
CreateLoader();
@@ -701,7 +448,7 @@ TEST_P(ThreadableLoaderTest, CancelInDidFail) {
ServeRequests();
}
-TEST_P(ThreadableLoaderTest, ClearInDidFail) {
+TEST_F(ThreadableLoaderTest, ClearInDidFail) {
InSequence s;
EXPECT_CALL(GetCheckpoint(), Call(1));
CreateLoader();
@@ -717,19 +464,17 @@ TEST_P(ThreadableLoaderTest, ClearInDidFail) {
ServeRequests();
}
-TEST_P(ThreadableLoaderTest, DidFailInStart) {
+TEST_F(ThreadableLoaderTest, DidFailInStart) {
InSequence s;
EXPECT_CALL(GetCheckpoint(), Call(1));
CreateLoader();
CallCheckpoint(1);
- String error_message = String::Format(
- "Failed to load '%s': Cross origin requests are not allowed by request "
- "mode.",
- ErrorURL().GetString().Utf8().data());
- EXPECT_CALL(*Client(), DidFail(ResourceError::CancelledDueToAccessCheckError(
- ErrorURL(), ResourceRequestBlockedReason::kOther,
- error_message)));
+ EXPECT_CALL(
+ *Client(),
+ DidFail(ResourceError(
+ ErrorURL(), network::CORSErrorStatus(
+ network::mojom::CORSError::kDisallowedByMode))));
EXPECT_CALL(GetCheckpoint(), Call(2));
StartLoader(ErrorURL(), network::mojom::FetchRequestMode::kSameOrigin);
@@ -737,7 +482,7 @@ TEST_P(ThreadableLoaderTest, DidFailInStart) {
ServeRequests();
}
-TEST_P(ThreadableLoaderTest, CancelInDidFailInStart) {
+TEST_F(ThreadableLoaderTest, CancelInDidFailInStart) {
InSequence s;
EXPECT_CALL(GetCheckpoint(), Call(1));
CreateLoader();
@@ -752,7 +497,7 @@ TEST_P(ThreadableLoaderTest, CancelInDidFailInStart) {
ServeRequests();
}
-TEST_P(ThreadableLoaderTest, ClearInDidFailInStart) {
+TEST_F(ThreadableLoaderTest, ClearInDidFailInStart) {
InSequence s;
EXPECT_CALL(GetCheckpoint(), Call(1));
CreateLoader();
@@ -767,27 +512,25 @@ TEST_P(ThreadableLoaderTest, ClearInDidFailInStart) {
ServeRequests();
}
-TEST_P(ThreadableLoaderTest, DidFailAccessControlCheck) {
+TEST_F(ThreadableLoaderTest, DidFailAccessControlCheck) {
InSequence s;
EXPECT_CALL(GetCheckpoint(), Call(1));
CreateLoader();
CallCheckpoint(1);
EXPECT_CALL(GetCheckpoint(), Call(2));
- EXPECT_CALL(
- *Client(),
- DidFail(ResourceError::CancelledDueToAccessCheckError(
- SuccessURL(), ResourceRequestBlockedReason::kOther,
- "No 'Access-Control-Allow-Origin' header is present on the requested "
- "resource. Origin 'http://fake.url' is therefore not allowed "
- "access.")));
+ EXPECT_CALL(*Client(),
+ DidFail(ResourceError(
+ SuccessURL(),
+ network::CORSErrorStatus(
+ network::mojom::CORSError::kMissingAllowOriginHeader))));
StartLoader(SuccessURL(), network::mojom::FetchRequestMode::kCORS);
CallCheckpoint(2);
ServeRequests();
}
-TEST_P(ThreadableLoaderTest, RedirectDidFinishLoading) {
+TEST_F(ThreadableLoaderTest, RedirectDidFinishLoading) {
InSequence s;
EXPECT_CALL(GetCheckpoint(), Call(1));
CreateLoader();
@@ -804,7 +547,7 @@ TEST_P(ThreadableLoaderTest, RedirectDidFinishLoading) {
ServeRequests();
}
-TEST_P(ThreadableLoaderTest, CancelInRedirectDidFinishLoading) {
+TEST_F(ThreadableLoaderTest, CancelInRedirectDidFinishLoading) {
InSequence s;
EXPECT_CALL(GetCheckpoint(), Call(1));
CreateLoader();
@@ -822,7 +565,7 @@ TEST_P(ThreadableLoaderTest, CancelInRedirectDidFinishLoading) {
ServeRequests();
}
-TEST_P(ThreadableLoaderTest, ClearInRedirectDidFinishLoading) {
+TEST_F(ThreadableLoaderTest, ClearInRedirectDidFinishLoading) {
InSequence s;
EXPECT_CALL(GetCheckpoint(), Call(1));
CreateLoader();
@@ -840,7 +583,7 @@ TEST_P(ThreadableLoaderTest, ClearInRedirectDidFinishLoading) {
ServeRequests();
}
-TEST_P(ThreadableLoaderTest, DidFailRedirectCheck) {
+TEST_F(ThreadableLoaderTest, DidFailRedirectCheck) {
InSequence s;
EXPECT_CALL(GetCheckpoint(), Call(1));
CreateLoader();
@@ -854,7 +597,7 @@ TEST_P(ThreadableLoaderTest, DidFailRedirectCheck) {
ServeRequests();
}
-TEST_P(ThreadableLoaderTest, CancelInDidFailRedirectCheck) {
+TEST_F(ThreadableLoaderTest, CancelInDidFailRedirectCheck) {
InSequence s;
EXPECT_CALL(GetCheckpoint(), Call(1));
CreateLoader();
@@ -869,7 +612,7 @@ TEST_P(ThreadableLoaderTest, CancelInDidFailRedirectCheck) {
ServeRequests();
}
-TEST_P(ThreadableLoaderTest, ClearInDidFailRedirectCheck) {
+TEST_F(ThreadableLoaderTest, ClearInDidFailRedirectCheck) {
InSequence s;
EXPECT_CALL(GetCheckpoint(), Call(1));
CreateLoader();
@@ -886,7 +629,7 @@ TEST_P(ThreadableLoaderTest, ClearInDidFailRedirectCheck) {
// This test case checks blink doesn't crash even when the response arrives
// synchronously.
-TEST_P(ThreadableLoaderTest, GetResponseSynchronously) {
+TEST_F(ThreadableLoaderTest, GetResponseSynchronously) {
InSequence s;
EXPECT_CALL(GetCheckpoint(), Call(1));
CreateLoader();
@@ -903,6 +646,74 @@ TEST_P(ThreadableLoaderTest, GetResponseSynchronously) {
CallCheckpoint(2);
}
+TEST(ThreadableLoaderCreatePreflightRequestTest, LexicographicalOrder) {
+ ResourceRequest request;
+ request.AddHTTPHeaderField("Orange", "Orange");
+ request.AddHTTPHeaderField("Apple", "Red");
+ request.AddHTTPHeaderField("Kiwifruit", "Green");
+ request.AddHTTPHeaderField("Content-Type", "application/octet-stream");
+ request.AddHTTPHeaderField("Strawberry", "Red");
+
+ std::unique_ptr<ResourceRequest> preflight =
+ ThreadableLoader::CreateAccessControlPreflightRequestForTesting(request);
+
+ EXPECT_EQ("apple,content-type,kiwifruit,orange,strawberry",
+ preflight->HttpHeaderField("Access-Control-Request-Headers"));
+}
+
+TEST(ThreadableLoaderCreatePreflightRequestTest, ExcludeSimpleHeaders) {
+ ResourceRequest request;
+ request.AddHTTPHeaderField("Accept", "everything");
+ request.AddHTTPHeaderField("Accept-Language", "everything");
+ request.AddHTTPHeaderField("Content-Language", "everything");
+ request.AddHTTPHeaderField("Save-Data", "on");
+
+ std::unique_ptr<ResourceRequest> preflight =
+ ThreadableLoader::CreateAccessControlPreflightRequestForTesting(request);
+
+ // Do not emit empty-valued headers; an empty list of non-"CORS safelisted"
+ // request headers should cause "Access-Control-Request-Headers:" to be
+ // left out in the preflight request.
+ EXPECT_EQ(g_null_atom,
+ preflight->HttpHeaderField("Access-Control-Request-Headers"));
+}
+
+TEST(ThreadableLoaderCreatePreflightRequestTest,
+ ExcludeSimpleContentTypeHeader) {
+ ResourceRequest request;
+ request.AddHTTPHeaderField("Content-Type", "text/plain");
+
+ std::unique_ptr<ResourceRequest> preflight =
+ ThreadableLoader::CreateAccessControlPreflightRequestForTesting(request);
+
+ // Empty list also; see comment in test above.
+ EXPECT_EQ(g_null_atom,
+ preflight->HttpHeaderField("Access-Control-Request-Headers"));
+}
+
+TEST(ThreadableLoaderCreatePreflightRequestTest, IncludeNonSimpleHeader) {
+ ResourceRequest request;
+ request.AddHTTPHeaderField("X-Custom-Header", "foobar");
+
+ std::unique_ptr<ResourceRequest> preflight =
+ ThreadableLoader::CreateAccessControlPreflightRequestForTesting(request);
+
+ EXPECT_EQ("x-custom-header",
+ preflight->HttpHeaderField("Access-Control-Request-Headers"));
+}
+
+TEST(ThreadableLoaderCreatePreflightRequestTest,
+ IncludeNonSimpleContentTypeHeader) {
+ ResourceRequest request;
+ request.AddHTTPHeaderField("Content-Type", "application/octet-stream");
+
+ std::unique_ptr<ResourceRequest> preflight =
+ ThreadableLoader::CreateAccessControlPreflightRequestForTesting(request);
+
+ EXPECT_EQ("content-type",
+ preflight->HttpHeaderField("Access-Control-Request-Headers"));
+}
+
} // namespace
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/loader/threadable_loading_context.cc b/chromium/third_party/blink/renderer/core/loader/threadable_loading_context.cc
deleted file mode 100644
index f709dd0d18a..00000000000
--- a/chromium/third_party/blink/renderer/core/loader/threadable_loading_context.cc
+++ /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.
-
-#include "third_party/blink/renderer/core/loader/threadable_loading_context.h"
-
-#include "third_party/blink/renderer/core/dom/document.h"
-#include "third_party/blink/renderer/core/loader/worker_fetch_context.h"
-#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
-#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
-
-namespace blink {
-
-class DocumentThreadableLoadingContext final : public ThreadableLoadingContext {
- public:
- explicit DocumentThreadableLoadingContext(Document& document)
- : document_(&document) {}
-
- ~DocumentThreadableLoadingContext() override = default;
-
- ResourceFetcher* GetResourceFetcher() override {
- DCHECK(IsContextThread());
- return document_->Fetcher();
- }
-
- ExecutionContext* GetExecutionContext() override {
- DCHECK(IsContextThread());
- return document_.Get();
- }
-
- void Trace(blink::Visitor* visitor) override {
- visitor->Trace(document_);
- ThreadableLoadingContext::Trace(visitor);
- }
-
- private:
- bool IsContextThread() const { return document_->IsContextThread(); }
-
- Member<Document> document_;
-};
-
-class WorkerThreadableLoadingContext : public ThreadableLoadingContext {
- public:
- explicit WorkerThreadableLoadingContext(
- WorkerGlobalScope& worker_global_scope)
- : worker_global_scope_(&worker_global_scope) {}
-
- ~WorkerThreadableLoadingContext() override = default;
-
- ResourceFetcher* GetResourceFetcher() override {
- DCHECK(IsContextThread());
- return worker_global_scope_->EnsureFetcher();
- }
-
- ExecutionContext* GetExecutionContext() override {
- DCHECK(IsContextThread());
- return worker_global_scope_.Get();
- }
-
- void Trace(blink::Visitor* visitor) override {
- visitor->Trace(worker_global_scope_);
- ThreadableLoadingContext::Trace(visitor);
- }
-
- private:
- bool IsContextThread() const {
- DCHECK(worker_global_scope_);
- return worker_global_scope_->IsContextThread();
- }
-
- Member<WorkerGlobalScope> worker_global_scope_;
-};
-
-ThreadableLoadingContext* ThreadableLoadingContext::Create(
- ExecutionContext& context) {
- if (context.IsDocument())
- return new DocumentThreadableLoadingContext(ToDocument(context));
- if (context.IsWorkerGlobalScope())
- return new WorkerThreadableLoadingContext(ToWorkerGlobalScope(context));
- NOTREACHED();
- return nullptr;
-}
-
-BaseFetchContext* ThreadableLoadingContext::GetFetchContext() {
- return static_cast<BaseFetchContext*>(&GetResourceFetcher()->Context());
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/loader/threadable_loading_context.h b/chromium/third_party/blink/renderer/core/loader/threadable_loading_context.h
deleted file mode 100644
index 3d9b6339d58..00000000000
--- a/chromium/third_party/blink/renderer/core/loader/threadable_loading_context.h
+++ /dev/null
@@ -1,41 +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_LOADER_THREADABLE_LOADING_CONTEXT_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_THREADABLE_LOADING_CONTEXT_H_
-
-#include "base/macros.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/forward.h"
-
-namespace blink {
-
-class BaseFetchContext;
-class ExecutionContext;
-class ResourceFetcher;
-
-// A convenient holder for various contexts associated with the loading
-// activity. This should be accessed only from the thread where the loading
-// context is bound to (e.g. on the main thread).
-class CORE_EXPORT ThreadableLoadingContext
- : public GarbageCollected<ThreadableLoadingContext> {
- public:
- static ThreadableLoadingContext* Create(ExecutionContext&);
-
- ThreadableLoadingContext() = default;
- virtual ~ThreadableLoadingContext() = default;
-
- virtual ResourceFetcher* GetResourceFetcher() = 0;
- virtual ExecutionContext* GetExecutionContext() = 0;
- BaseFetchContext* GetFetchContext();
-
- virtual void Trace(blink::Visitor* visitor) {}
-
- DISALLOW_COPY_AND_ASSIGN(ThreadableLoadingContext);
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_THREADABLE_LOADING_CONTEXT_H_
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 315409235c1..d2bb4bed218 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
@@ -107,7 +107,7 @@ WorkerFetchContext::WorkerFetchContext(
SubresourceFilter::Create(global_scope, std::move(web_filter));
}
}
-const FetchClientSettingsObject*
+const FetchClientSettingsObjectImpl*
WorkerFetchContext::GetFetchClientSettingsObject() const {
return fetch_client_settings_object_.Get();
}
@@ -120,6 +120,11 @@ SubresourceFilter* WorkerFetchContext::GetSubresourceFilter() const {
return subresource_filter_.Get();
}
+PreviewsResourceLoadingHints*
+WorkerFetchContext::GetPreviewsResourceLoadingHints() const {
+ return nullptr;
+}
+
bool WorkerFetchContext::AllowScriptFromSource(const KURL& url) const {
WorkerContentSettingsClient* settings_client =
WorkerContentSettingsClient::From(*global_scope_);
@@ -276,6 +281,10 @@ std::unique_ptr<WebURLLoader> WorkerFetchContext::CreateURLLoader(
wrapped, CreateResourceLoadingTaskRunnerHandle());
}
+std::unique_ptr<CodeCacheLoader> WorkerFetchContext::CreateCodeCacheLoader() {
+ return web_context_->CreateCodeCacheLoader();
+}
+
blink::mojom::ControllerServiceWorkerMode
WorkerFetchContext::IsControlledByServiceWorker() const {
return web_context_->IsControlledByServiceWorker();
@@ -292,8 +301,6 @@ void WorkerFetchContext::PrepareRequest(ResourceRequest& request,
DCHECK(!user_agent.IsNull());
request.SetHTTPUserAgent(AtomicString(user_agent));
- FrameLoader::UpgradeInsecureRequest(request, global_scope_);
-
WrappedResourceRequest webreq(request);
web_context_->WillSendRequest(webreq);
}
@@ -390,6 +397,7 @@ void WorkerFetchContext::PopulateResourceRequest(
const ClientHintsPreferences& hints_preferences,
const FetchParameters::ResourceWidth& resource_width,
ResourceRequest& out_request) {
+ FrameLoader::UpgradeInsecureRequest(out_request, global_scope_);
SetFirstPartyCookieAndRequestorOrigin(out_request);
}
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 f1ad8cbc146..e290130323a 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
@@ -37,10 +37,12 @@ class WorkerFetchContext final : public BaseFetchContext {
~WorkerFetchContext() override;
// BaseFetchContext implementation:
- const FetchClientSettingsObject* GetFetchClientSettingsObject()
+ const FetchClientSettingsObjectImpl* GetFetchClientSettingsObject()
const override;
KURL GetSiteForCookies() const override;
SubresourceFilter* GetSubresourceFilter() const override;
+ PreviewsResourceLoadingHints* GetPreviewsResourceLoadingHints()
+ const override;
bool AllowScriptFromSource(const KURL&) const override;
bool ShouldBlockRequestByInspector(const KURL&) const override;
void DispatchDidBlockRequest(const ResourceRequest&,
@@ -74,6 +76,7 @@ class WorkerFetchContext final : public BaseFetchContext {
std::unique_ptr<WebURLLoader> CreateURLLoader(
const ResourceRequest&,
const ResourceLoaderOptions&) override;
+ std::unique_ptr<CodeCacheLoader> CreateCodeCacheLoader() override;
void PrepareRequest(ResourceRequest&, RedirectType) override;
blink::mojom::ControllerServiceWorkerMode IsControlledByServiceWorker()
const override;
diff --git a/chromium/third_party/blink/renderer/core/loader/worker_threadable_loader.cc b/chromium/third_party/blink/renderer/core/loader/worker_threadable_loader.cc
deleted file mode 100644
index 7fe7bf55235..00000000000
--- a/chromium/third_party/blink/renderer/core/loader/worker_threadable_loader.cc
+++ /dev/null
@@ -1,680 +0,0 @@
-/*
- * Copyright (C) 2009, 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/renderer/core/loader/worker_threadable_loader.h"
-
-#include <memory>
-
-#include "base/debug/alias.h"
-#include "third_party/blink/public/platform/task_type.h"
-#include "third_party/blink/renderer/core/loader/document_threadable_loader.h"
-#include "third_party/blink/renderer/core/loader/threadable_loading_context.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/core/workers/worker_thread.h"
-#include "third_party/blink/renderer/core/workers/worker_thread_lifecycle_context.h"
-#include "third_party/blink/renderer/platform/cross_thread_functional.h"
-#include "third_party/blink/renderer/platform/heap/safe_point.h"
-#include "third_party/blink/renderer/platform/loader/fetch/resource_error.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/loader/fetch/resource_timing_info.h"
-#include "third_party/blink/renderer/platform/weborigin/kurl.h"
-#include "third_party/blink/renderer/platform/weborigin/security_policy.h"
-#include "third_party/blink/renderer/platform/wtf/functional.h"
-
-namespace blink {
-
-namespace {
-
-std::unique_ptr<Vector<char>> CreateVectorFromMemoryRegion(
- const char* data,
- unsigned data_length) {
- std::unique_ptr<Vector<char>> buffer =
- std::make_unique<Vector<char>>(data_length);
- memcpy(buffer->data(), data, data_length);
- return buffer;
-}
-
-} // namespace
-
-struct WorkerThreadableLoader::TaskWithLocation final {
- TaskWithLocation(const base::Location& location, CrossThreadClosure task)
- : location_(location), task_(std::move(task)) {}
- TaskWithLocation(TaskWithLocation&& task)
- : TaskWithLocation(task.location_, std::move(task.task_)) {}
- ~TaskWithLocation() = default;
-
- base::Location location_;
- CrossThreadClosure task_;
-};
-
-// Observing functions and wait() need to be called on the worker thread.
-// Setting functions and signal() need to be called on the parent thread.
-// All observing functions must be called after wait() returns, and all
-// setting functions must be called before signal() is called.
-class WorkerThreadableLoader::WaitableEventWithTasks final
- : public ThreadSafeRefCounted<WaitableEventWithTasks> {
- public:
- static scoped_refptr<WaitableEventWithTasks> Create(
- scoped_refptr<base::SingleThreadTaskRunner> worker_loading_task_runner) {
- return base::AdoptRef(
- new WaitableEventWithTasks(worker_loading_task_runner));
- }
-
- void Signal() {
-#if DCHECK_IS_ON()
- DCHECK(!worker_loading_task_runner_->BelongsToCurrentThread());
-#endif
- CHECK(!is_signal_called_);
- is_signal_called_ = true;
- event_.Signal();
- }
- void Wait() {
-#if DCHECK_IS_ON()
- DCHECK(worker_loading_task_runner_->BelongsToCurrentThread());
-#endif
- CHECK(!is_wait_done_);
- event_.Wait();
- is_wait_done_ = true;
- }
-
- // Observing functions
- bool IsAborted() const {
-#if DCHECK_IS_ON()
- DCHECK(worker_loading_task_runner_->BelongsToCurrentThread());
-#endif
- CHECK(is_wait_done_);
- return is_aborted_;
- }
- Vector<TaskWithLocation> Take() {
-#if DCHECK_IS_ON()
- DCHECK(worker_loading_task_runner_->BelongsToCurrentThread());
-#endif
- CHECK(is_wait_done_);
- return std::move(tasks_);
- }
-
- // Setting functions
- void Append(TaskWithLocation task) {
-#if DCHECK_IS_ON()
- DCHECK(!worker_loading_task_runner_->BelongsToCurrentThread());
-#endif
- CHECK(!is_signal_called_);
- tasks_.push_back(std::move(task));
- }
- void SetIsAborted() {
-#if DCHECK_IS_ON()
- DCHECK(!worker_loading_task_runner_->BelongsToCurrentThread());
-#endif
- CHECK(!is_signal_called_);
- is_aborted_ = true;
- }
-
-#if DCHECK_IS_ON()
- // A task runner from the WorkerGlobalScope that requested the fetch.
- // Used for thread correctness DCHECKs.
- scoped_refptr<base::SingleThreadTaskRunner> worker_loading_task_runner_;
-#endif
-
- private:
- explicit WaitableEventWithTasks(
- scoped_refptr<base::SingleThreadTaskRunner> worker_loading_task_runner) {
-#if DCHECK_IS_ON()
- worker_loading_task_runner_ = worker_loading_task_runner;
-#endif
- }
-
- WaitableEvent event_;
- Vector<TaskWithLocation> tasks_;
- bool is_aborted_ = false;
- bool is_signal_called_ = false;
- bool is_wait_done_ = false;
-};
-
-WorkerThreadableLoader::TaskForwarder::TaskForwarder(
- scoped_refptr<WaitableEventWithTasks> event_with_tasks)
- : event_with_tasks_(std::move(event_with_tasks)) {
-#if DCHECK_IS_ON()
- DCHECK(!event_with_tasks_->worker_loading_task_runner_
- ->BelongsToCurrentThread());
-#endif
-}
-
-void WorkerThreadableLoader::TaskForwarder::ForwardTask(
- const base::Location& location,
- CrossThreadClosure task) {
-#if DCHECK_IS_ON()
- DCHECK(!event_with_tasks_->worker_loading_task_runner_
- ->BelongsToCurrentThread());
-#endif
- event_with_tasks_->Append(TaskWithLocation(location, std::move(task)));
-}
-
-void WorkerThreadableLoader::TaskForwarder::ForwardTaskWithDoneSignal(
- const base::Location& location,
- CrossThreadClosure task) {
-#if DCHECK_IS_ON()
- DCHECK(!event_with_tasks_->worker_loading_task_runner_
- ->BelongsToCurrentThread());
-#endif
- event_with_tasks_->Append(TaskWithLocation(location, std::move(task)));
- event_with_tasks_->Signal();
-}
-
-void WorkerThreadableLoader::TaskForwarder::Abort() {
-#if DCHECK_IS_ON()
- DCHECK(!event_with_tasks_->worker_loading_task_runner_
- ->BelongsToCurrentThread());
-#endif
- event_with_tasks_->SetIsAborted();
- event_with_tasks_->Signal();
-}
-
-WorkerThreadableLoader::WorkerThreadableLoader(
- WorkerGlobalScope& worker_global_scope,
- ThreadableLoaderClient* client,
- const ThreadableLoaderOptions& options,
- const ResourceLoaderOptions& resource_loader_options)
- : worker_global_scope_(&worker_global_scope),
- parent_execution_context_task_runners_(
- worker_global_scope.GetThread()
- ->GetParentExecutionContextTaskRunners()),
- client_(client),
- threadable_loader_options_(options),
- resource_loader_options_(resource_loader_options) {
- DCHECK(client);
-}
-
-void WorkerThreadableLoader::LoadResourceSynchronously(
- WorkerGlobalScope& worker_global_scope,
- const ResourceRequest& request,
- ThreadableLoaderClient& client,
- const ThreadableLoaderOptions& options,
- const ResourceLoaderOptions& resource_loader_options) {
- (new WorkerThreadableLoader(worker_global_scope, &client, options,
- resource_loader_options))
- ->Start(request);
-}
-
-WorkerThreadableLoader::~WorkerThreadableLoader() {
- DCHECK(!parent_thread_loader_holder_);
- DCHECK(!client_);
-}
-
-void WorkerThreadableLoader::Start(const ResourceRequest& original_request) {
- DCHECK(worker_global_scope_->IsContextThread());
- ResourceRequest request(original_request);
- if (!request.DidSetHTTPReferrer()) {
- request.SetHTTPReferrer(SecurityPolicy::GenerateReferrer(
- worker_global_scope_->GetReferrerPolicy(), request.Url(),
- worker_global_scope_->OutgoingReferrer()));
- }
-
-
- WorkerThread* worker_thread = worker_global_scope_->GetThread();
- scoped_refptr<base::SingleThreadTaskRunner> worker_loading_task_runner =
- worker_global_scope_->GetTaskRunner(TaskType::kInternalLoading);
- scoped_refptr<WaitableEventWithTasks> event_with_tasks =
- WaitableEventWithTasks::Create(worker_loading_task_runner);
- PostCrossThreadTask(
- *parent_execution_context_task_runners_->Get(TaskType::kInternalLoading),
- FROM_HERE,
- CrossThreadBind(
- &ParentThreadLoaderHolder::CreateAndStart,
- WrapCrossThreadPersistent(this),
- WrapCrossThreadPersistent(worker_thread->GetLoadingContext()),
- std::move(worker_loading_task_runner),
- WrapCrossThreadPersistent(
- worker_thread->GetWorkerThreadLifecycleContext()),
- request, threadable_loader_options_, resource_loader_options_,
- event_with_tasks));
-
- event_with_tasks->Wait();
-
- if (event_with_tasks->IsAborted()) {
- // This thread is going to terminate.
- Cancel();
- return;
- }
-
- for (auto& task : event_with_tasks->Take()) {
- // Store the program counter where the task is posted from, and alias
- // it to ensure it is stored in the crash dump.
- const void* program_counter = task.location_.program_counter();
- base::debug::Alias(&program_counter);
-
- std::move(task.task_).Run();
- }
-}
-
-void WorkerThreadableLoader::OverrideTimeout(
- unsigned long timeout_milliseconds) {
- DCHECK(worker_global_scope_->IsContextThread());
- if (!parent_thread_loader_holder_)
- return;
- PostCrossThreadTask(
- *parent_execution_context_task_runners_->Get(TaskType::kInternalLoading),
- FROM_HERE,
- CrossThreadBind(&ParentThreadLoaderHolder::OverrideTimeout,
- parent_thread_loader_holder_, timeout_milliseconds));
-}
-
-void WorkerThreadableLoader::Cancel() {
- DCHECK(worker_global_scope_->IsContextThread());
- if (parent_thread_loader_holder_) {
- PostCrossThreadTask(*parent_execution_context_task_runners_->Get(
- TaskType::kInternalLoading),
- FROM_HERE,
- CrossThreadBind(&ParentThreadLoaderHolder::Cancel,
- parent_thread_loader_holder_));
- parent_thread_loader_holder_ = nullptr;
- }
-
- if (!client_)
- return;
-
- // If the client hasn't reached a termination state, then transition it
- // by sending a cancellation error.
- // Note: no more client callbacks will be done after this method -- the
- // clearClient() call ensures that.
- DidFail(ResourceError::CancelledError(KURL()));
- DCHECK(!client_);
-}
-
-void WorkerThreadableLoader::Detach() {
- // NOTREACHED
- // Currently only "synchronous" requests are using this class and we will
- // deprecate it in the future. As this method cannot be called for such
- // requests, we don't implement it.
- CHECK(false);
-}
-
-void WorkerThreadableLoader::DidStart(
- ParentThreadLoaderHolder* parent_thread_loader_holder) {
- DCHECK(worker_global_scope_->IsContextThread());
- DCHECK(!parent_thread_loader_holder_);
- DCHECK(parent_thread_loader_holder);
- if (!client_) {
- // The thread is terminating.
- PostCrossThreadTask(*parent_execution_context_task_runners_->Get(
- TaskType::kInternalLoading),
- FROM_HERE,
- CrossThreadBind(&ParentThreadLoaderHolder::Cancel,
- WrapCrossThreadPersistent(
- parent_thread_loader_holder)));
- return;
- }
-
- parent_thread_loader_holder_ = parent_thread_loader_holder;
-}
-
-void WorkerThreadableLoader::DidSendData(
- unsigned long long bytes_sent,
- unsigned long long total_bytes_to_be_sent) {
- DCHECK(worker_global_scope_->IsContextThread());
- if (!client_)
- return;
- client_->DidSendData(bytes_sent, total_bytes_to_be_sent);
-}
-
-void WorkerThreadableLoader::DidReceiveRedirectTo(const KURL& url) {
- DCHECK(worker_global_scope_->IsContextThread());
- if (!client_)
- return;
- client_->DidReceiveRedirectTo(url);
-}
-
-void WorkerThreadableLoader::DidReceiveResponse(
- unsigned long identifier,
- std::unique_ptr<CrossThreadResourceResponseData> response_data,
- std::unique_ptr<WebDataConsumerHandle> handle) {
- DCHECK(worker_global_scope_->IsContextThread());
- if (!client_)
- return;
- ResourceResponse response(response_data.get());
- client_->DidReceiveResponse(identifier, response, std::move(handle));
-}
-
-void WorkerThreadableLoader::DidReceiveData(
- std::unique_ptr<Vector<char>> data) {
- DCHECK(worker_global_scope_->IsContextThread());
- CHECK_LE(data->size(), std::numeric_limits<unsigned>::max());
- if (!client_)
- return;
- client_->DidReceiveData(data->data(), data->size());
-}
-
-void WorkerThreadableLoader::DidReceiveCachedMetadata(
- std::unique_ptr<Vector<char>> data) {
- DCHECK(worker_global_scope_->IsContextThread());
- if (!client_)
- return;
- client_->DidReceiveCachedMetadata(data->data(), data->size());
-}
-
-void WorkerThreadableLoader::DidFinishLoading(unsigned long identifier) {
- DCHECK(worker_global_scope_->IsContextThread());
- if (!client_)
- return;
- auto* client = client_;
- client_ = nullptr;
- parent_thread_loader_holder_ = nullptr;
- client->DidFinishLoading(identifier);
-}
-
-void WorkerThreadableLoader::DidFail(const ResourceError& error) {
- DCHECK(worker_global_scope_->IsContextThread());
- if (!client_)
- return;
- auto* client = client_;
- client_ = nullptr;
- parent_thread_loader_holder_ = nullptr;
- client->DidFail(error);
-}
-
-void WorkerThreadableLoader::DidFailRedirectCheck() {
- DCHECK(worker_global_scope_->IsContextThread());
- if (!client_)
- return;
- auto* client = client_;
- client_ = nullptr;
- parent_thread_loader_holder_ = nullptr;
- client->DidFailRedirectCheck();
-}
-
-void WorkerThreadableLoader::DidDownloadData(int data_length) {
- DCHECK(worker_global_scope_->IsContextThread());
- if (!client_)
- return;
- client_->DidDownloadData(data_length);
-}
-
-void WorkerThreadableLoader::DidDownloadToBlob(
- scoped_refptr<BlobDataHandle> blob) {
- DCHECK(worker_global_scope_->IsContextThread());
- if (!client_)
- return;
- client_->DidDownloadToBlob(std::move(blob));
-}
-
-void WorkerThreadableLoader::DidReceiveResourceTiming(
- std::unique_ptr<CrossThreadResourceTimingInfoData> timing_data) {
- DCHECK(worker_global_scope_->IsContextThread());
- if (!client_)
- return;
- scoped_refptr<ResourceTimingInfo> info(
- ResourceTimingInfo::Adopt(std::move(timing_data)));
- WorkerGlobalScopePerformance::performance(*worker_global_scope_)
- ->GenerateAndAddResourceTiming(*info);
- client_->DidReceiveResourceTiming(*info);
-}
-
-void WorkerThreadableLoader::Trace(blink::Visitor* visitor) {
- visitor->Trace(worker_global_scope_);
- ThreadableLoader::Trace(visitor);
-}
-
-void WorkerThreadableLoader::ParentThreadLoaderHolder::CreateAndStart(
- WorkerThreadableLoader* worker_loader,
- ThreadableLoadingContext* loading_context,
- scoped_refptr<base::SingleThreadTaskRunner> worker_loading_task_runner,
- WorkerThreadLifecycleContext* worker_thread_lifecycle_context,
- std::unique_ptr<CrossThreadResourceRequestData> request,
- const ThreadableLoaderOptions& options,
- const ResourceLoaderOptions& resource_loader_options,
- scoped_refptr<WaitableEventWithTasks> event_with_tasks) {
- DCHECK(loading_context->GetExecutionContext()->IsContextThread());
- DCHECK(event_with_tasks);
- TaskForwarder* forwarder = new TaskForwarder(std::move(event_with_tasks));
-
- ParentThreadLoaderHolder* parent_thread_loader_holder =
- new ParentThreadLoaderHolder(forwarder, worker_thread_lifecycle_context);
- if (parent_thread_loader_holder
- ->WasContextDestroyedBeforeObserverCreation()) {
- // The thread is already terminating.
- forwarder->Abort();
- parent_thread_loader_holder->forwarder_ = nullptr;
- return;
- }
- parent_thread_loader_holder->worker_loader_ = worker_loader;
- forwarder->ForwardTask(
- FROM_HERE,
- CrossThreadBind(&WorkerThreadableLoader::DidStart,
- WrapCrossThreadPersistent(worker_loader),
- WrapCrossThreadPersistent(parent_thread_loader_holder)));
- parent_thread_loader_holder->Start(*loading_context, std::move(request),
- options, resource_loader_options);
-}
-
-WorkerThreadableLoader::ParentThreadLoaderHolder::~ParentThreadLoaderHolder() {
- DCHECK(!worker_loader_);
-}
-
-void WorkerThreadableLoader::ParentThreadLoaderHolder::OverrideTimeout(
- unsigned long timeout_milliseconds) {
- if (!parent_thread_loader_)
- return;
- DCHECK(parent_thread_loader_->GetExecutionContext()->IsContextThread());
- parent_thread_loader_->OverrideTimeout(timeout_milliseconds);
-}
-
-void WorkerThreadableLoader::ParentThreadLoaderHolder::Cancel() {
- worker_loader_ = nullptr;
- if (!parent_thread_loader_)
- return;
- DCHECK(parent_thread_loader_->GetExecutionContext()->IsContextThread());
- parent_thread_loader_->Cancel();
- parent_thread_loader_ = nullptr;
-}
-
-void WorkerThreadableLoader::ParentThreadLoaderHolder::DidSendData(
- unsigned long long bytes_sent,
- unsigned long long total_bytes_to_be_sent) {
- DCHECK(parent_thread_loader_->GetExecutionContext()->IsContextThread());
- CrossThreadPersistent<WorkerThreadableLoader> worker_loader =
- worker_loader_.Get();
- if (!worker_loader || !forwarder_)
- return;
- forwarder_->ForwardTask(
- FROM_HERE,
- CrossThreadBind(&WorkerThreadableLoader::DidSendData, worker_loader,
- bytes_sent, total_bytes_to_be_sent));
-}
-
-void WorkerThreadableLoader::ParentThreadLoaderHolder::DidReceiveRedirectTo(
- const KURL& url) {
- DCHECK(parent_thread_loader_->GetExecutionContext()->IsContextThread());
- CrossThreadPersistent<WorkerThreadableLoader> worker_loader =
- worker_loader_.Get();
- if (!worker_loader || !forwarder_)
- return;
- forwarder_->ForwardTask(
- FROM_HERE, CrossThreadBind(&WorkerThreadableLoader::DidReceiveRedirectTo,
- worker_loader, url));
-}
-
-void WorkerThreadableLoader::ParentThreadLoaderHolder::DidReceiveResponse(
- unsigned long identifier,
- const ResourceResponse& response,
- std::unique_ptr<WebDataConsumerHandle> handle) {
- DCHECK(parent_thread_loader_->GetExecutionContext()->IsContextThread());
- CrossThreadPersistent<WorkerThreadableLoader> worker_loader =
- worker_loader_.Get();
- if (!worker_loader || !forwarder_)
- return;
- forwarder_->ForwardTask(
- FROM_HERE, CrossThreadBind(&WorkerThreadableLoader::DidReceiveResponse,
- worker_loader, identifier, response,
- WTF::Passed(std::move(handle))));
-}
-
-void WorkerThreadableLoader::ParentThreadLoaderHolder::DidReceiveData(
- const char* data,
- unsigned data_length) {
- DCHECK(parent_thread_loader_->GetExecutionContext()->IsContextThread());
- CrossThreadPersistent<WorkerThreadableLoader> worker_loader =
- worker_loader_.Get();
- if (!worker_loader || !forwarder_)
- return;
- forwarder_->ForwardTask(
- FROM_HERE,
- CrossThreadBind(
- &WorkerThreadableLoader::DidReceiveData, worker_loader,
- WTF::Passed(CreateVectorFromMemoryRegion(data, data_length))));
-}
-
-void WorkerThreadableLoader::ParentThreadLoaderHolder::DidDownloadData(
- int data_length) {
- DCHECK(parent_thread_loader_->GetExecutionContext()->IsContextThread());
- CrossThreadPersistent<WorkerThreadableLoader> worker_loader =
- worker_loader_.Get();
- if (!worker_loader || !forwarder_)
- return;
- forwarder_->ForwardTask(
- FROM_HERE, CrossThreadBind(&WorkerThreadableLoader::DidDownloadData,
- worker_loader, data_length));
-}
-
-void WorkerThreadableLoader::ParentThreadLoaderHolder::DidDownloadToBlob(
- scoped_refptr<BlobDataHandle> blob) {
- DCHECK(parent_thread_loader_->GetExecutionContext()->IsContextThread());
- CrossThreadPersistent<WorkerThreadableLoader> worker_loader =
- worker_loader_.Get();
- if (!worker_loader || !forwarder_)
- return;
- forwarder_->ForwardTask(
- FROM_HERE, CrossThreadBind(&WorkerThreadableLoader::DidDownloadToBlob,
- worker_loader, std::move(blob)));
-}
-
-void WorkerThreadableLoader::ParentThreadLoaderHolder::DidReceiveCachedMetadata(
- const char* data,
- int data_length) {
- DCHECK(parent_thread_loader_->GetExecutionContext()->IsContextThread());
- CrossThreadPersistent<WorkerThreadableLoader> worker_loader =
- worker_loader_.Get();
- if (!worker_loader || !forwarder_)
- return;
- forwarder_->ForwardTask(
- FROM_HERE,
- CrossThreadBind(
- &WorkerThreadableLoader::DidReceiveCachedMetadata, worker_loader,
- WTF::Passed(CreateVectorFromMemoryRegion(data, data_length))));
-}
-
-void WorkerThreadableLoader::ParentThreadLoaderHolder::DidFinishLoading(
- unsigned long identifier) {
- DCHECK(parent_thread_loader_->GetExecutionContext()->IsContextThread());
- CrossThreadPersistent<WorkerThreadableLoader> worker_loader =
- worker_loader_.Release();
- if (!worker_loader || !forwarder_)
- return;
- forwarder_->ForwardTaskWithDoneSignal(
- FROM_HERE, CrossThreadBind(&WorkerThreadableLoader::DidFinishLoading,
- worker_loader, identifier));
- forwarder_ = nullptr;
-}
-
-void WorkerThreadableLoader::ParentThreadLoaderHolder::DidFail(
- const ResourceError& error) {
- DCHECK(parent_thread_loader_->GetExecutionContext()->IsContextThread());
- CrossThreadPersistent<WorkerThreadableLoader> worker_loader =
- worker_loader_.Release();
- if (!worker_loader || !forwarder_)
- return;
- forwarder_->ForwardTaskWithDoneSignal(
- FROM_HERE,
- CrossThreadBind(&WorkerThreadableLoader::DidFail, worker_loader, error));
- forwarder_ = nullptr;
-}
-
-void WorkerThreadableLoader::ParentThreadLoaderHolder::DidFailRedirectCheck() {
- DCHECK(parent_thread_loader_->GetExecutionContext()->IsContextThread());
- CrossThreadPersistent<WorkerThreadableLoader> worker_loader =
- worker_loader_.Release();
- if (!worker_loader || !forwarder_)
- return;
- forwarder_->ForwardTaskWithDoneSignal(
- FROM_HERE, CrossThreadBind(&WorkerThreadableLoader::DidFailRedirectCheck,
- worker_loader));
- forwarder_ = nullptr;
-}
-
-void WorkerThreadableLoader::ParentThreadLoaderHolder::DidReceiveResourceTiming(
- const ResourceTimingInfo& info) {
- DCHECK(parent_thread_loader_->GetExecutionContext()->IsContextThread());
- CrossThreadPersistent<WorkerThreadableLoader> worker_loader =
- worker_loader_.Get();
- if (!worker_loader || !forwarder_)
- return;
- forwarder_->ForwardTask(
- FROM_HERE,
- CrossThreadBind(&WorkerThreadableLoader::DidReceiveResourceTiming,
- worker_loader, info));
-}
-
-void WorkerThreadableLoader::ParentThreadLoaderHolder::ContextDestroyed(
- WorkerThreadLifecycleContext*) {
- DCHECK(parent_thread_loader_->GetExecutionContext()->IsContextThread());
- if (forwarder_) {
- forwarder_->Abort();
- forwarder_ = nullptr;
- }
- Cancel();
-}
-
-void WorkerThreadableLoader::ParentThreadLoaderHolder::Trace(
- blink::Visitor* visitor) {
- visitor->Trace(forwarder_);
- visitor->Trace(parent_thread_loader_);
- WorkerThreadLifecycleObserver::Trace(visitor);
-}
-
-WorkerThreadableLoader::ParentThreadLoaderHolder::ParentThreadLoaderHolder(
- TaskForwarder* forwarder,
- WorkerThreadLifecycleContext* context)
- : WorkerThreadLifecycleObserver(context), forwarder_(forwarder) {}
-
-void WorkerThreadableLoader::ParentThreadLoaderHolder::Start(
- ThreadableLoadingContext& loading_context,
- std::unique_ptr<CrossThreadResourceRequestData> request,
- const ThreadableLoaderOptions& options,
- const ResourceLoaderOptions& original_resource_loader_options) {
- DCHECK(loading_context.GetExecutionContext()->IsContextThread());
- ResourceLoaderOptions resource_loader_options =
- original_resource_loader_options;
- resource_loader_options.request_initiator_context = kWorkerContext;
- parent_thread_loader_ = DocumentThreadableLoader::Create(
- loading_context, this, options, resource_loader_options);
- parent_thread_loader_->Start(ResourceRequest(request.get()));
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/loader/worker_threadable_loader.h b/chromium/third_party/blink/renderer/core/loader/worker_threadable_loader.h
deleted file mode 100644
index 25a6b5f9cc8..00000000000
--- a/chromium/third_party/blink/renderer/core/loader/worker_threadable_loader.h
+++ /dev/null
@@ -1,215 +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_CORE_LOADER_WORKER_THREADABLE_LOADER_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_WORKER_THREADABLE_LOADER_H_
-
-#include <memory>
-#include "base/location.h"
-#include "base/memory/scoped_refptr.h"
-#include "base/single_thread_task_runner.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/core/workers/worker_thread.h"
-#include "third_party/blink/renderer/core/workers/worker_thread_lifecycle_observer.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/waitable_event.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-#include "third_party/blink/renderer/platform/wtf/threading.h"
-#include "third_party/blink/renderer/platform/wtf/vector.h"
-
-namespace blink {
-
-class DocumentThreadableLoader;
-class ThreadableLoadingContext;
-class ResourceError;
-class ResourceRequest;
-class ResourceResponse;
-class WorkerGlobalScope;
-class WorkerThreadLifecycleContext;
-struct CrossThreadResourceRequestData;
-struct CrossThreadResourceTimingInfoData;
-
-// A WorkerThreadableLoader is a ThreadableLoader implementation intended to
-// be used in a WebWorker thread. Because redirect handling doesn't perform CORS
-// checks for sync requests, a WorkerThreadableLoader holds a ThreadableLoader
-// in the parent thread and delegates tasks asynchronously to the loader.
-// The parent thread may be the main thread, or in the case of nested workers,
-// a different worker thread.
-//
-// CTP: CrossThreadPersistent
-// CTWP: CrossThreadWeakPersistent
-//
-// ----------------------------------------------------------------
-// +------------------------+
-// raw ptr | ThreadableLoaderClient |
-// +--------> | worker thread |
-// | +------------------------+
-// |
-// +----+------------------+ CTP +------------------------+
-// + WorkerThreadableLoader|<--------+ ParentThreadLoaderHolder |
-// | worker thread +-------->| parent thread |
-// +-----------------------+ CTWP +----------------------+-+
-// |
-// +------------------+ | Member
-// | ThreadableLoader | <---+
-// | parent thread |
-// +------------------+
-//
-class WorkerThreadableLoader final : public ThreadableLoader {
- public:
- static void LoadResourceSynchronously(WorkerGlobalScope&,
- const ResourceRequest&,
- ThreadableLoaderClient&,
- const ThreadableLoaderOptions&,
- const ResourceLoaderOptions&);
- ~WorkerThreadableLoader() override;
-
- // ThreadableLoader functions
- void Start(const ResourceRequest&) override;
- void OverrideTimeout(unsigned long timeout) override;
- void Cancel() override;
- void Detach() override;
-
- void Trace(blink::Visitor*) override;
-
- private:
- struct TaskWithLocation;
- class WaitableEventWithTasks;
- // A TaskForwarder forwards a task to the worker thread.
- class TaskForwarder final : public GarbageCollectedFinalized<TaskForwarder> {
- public:
- explicit TaskForwarder(
- scoped_refptr<WaitableEventWithTasks> event_with_tasks);
- ~TaskForwarder() = default;
- void ForwardTask(const base::Location&, CrossThreadClosure);
- void ForwardTaskWithDoneSignal(const base::Location&, CrossThreadClosure);
- void Abort();
- void Trace(blink::Visitor* visitor) {}
-
- private:
- scoped_refptr<WaitableEventWithTasks> event_with_tasks_;
- };
-
- // An instance of this class lives in the parent thread. It is a
- // ThreadableLoaderClient for a DocumentThreadableLoader and forward
- // notifications to the associated WorkerThreadableLoader living in the
- // worker thread.
- class ParentThreadLoaderHolder final
- : public GarbageCollectedFinalized<ParentThreadLoaderHolder>,
- public ThreadableLoaderClient,
- public WorkerThreadLifecycleObserver {
- USING_GARBAGE_COLLECTED_MIXIN(ParentThreadLoaderHolder);
- USING_PRE_FINALIZER(ParentThreadLoaderHolder, Cancel);
-
- public:
- static void CreateAndStart(WorkerThreadableLoader*,
- ThreadableLoadingContext*,
- scoped_refptr<base::SingleThreadTaskRunner>,
- WorkerThreadLifecycleContext*,
- std::unique_ptr<CrossThreadResourceRequestData>,
- const ThreadableLoaderOptions&,
- const ResourceLoaderOptions&,
- scoped_refptr<WaitableEventWithTasks>);
- ~ParentThreadLoaderHolder() override;
-
- void OverrideTimeout(unsigned long timeout_millisecond);
- void Cancel();
-
- void DidSendData(unsigned long long bytes_sent,
- unsigned long long total_bytes_to_be_sent) override;
- void DidReceiveRedirectTo(const KURL&) override;
- void DidReceiveResponse(unsigned long identifier,
- const ResourceResponse&,
- std::unique_ptr<WebDataConsumerHandle>) override;
- void DidReceiveData(const char*, unsigned data_length) override;
- void DidDownloadData(int data_length) override;
- void DidDownloadToBlob(scoped_refptr<BlobDataHandle>) override;
- void DidReceiveCachedMetadata(const char*, int data_length) override;
- void DidFinishLoading(unsigned long identifier) override;
- void DidFail(const ResourceError&) override;
- void DidFailRedirectCheck() override;
- void DidReceiveResourceTiming(const ResourceTimingInfo&) override;
-
- void ContextDestroyed(WorkerThreadLifecycleContext*) override;
-
- void Trace(blink::Visitor*) override;
-
- private:
- ParentThreadLoaderHolder(TaskForwarder*, WorkerThreadLifecycleContext*);
- void Start(ThreadableLoadingContext&,
- std::unique_ptr<CrossThreadResourceRequestData>,
- const ThreadableLoaderOptions&,
- const ResourceLoaderOptions&);
-
- Member<TaskForwarder> forwarder_;
- Member<DocumentThreadableLoader> parent_thread_loader_;
-
- // |*m_workerLoader| lives in the worker thread.
- CrossThreadWeakPersistent<WorkerThreadableLoader> worker_loader_;
- };
-
- WorkerThreadableLoader(WorkerGlobalScope&,
- ThreadableLoaderClient*,
- const ThreadableLoaderOptions&,
- const ResourceLoaderOptions&);
- void DidStart(ParentThreadLoaderHolder*);
-
- void DidSendData(unsigned long long bytes_sent,
- unsigned long long total_bytes_to_be_sent);
- void DidReceiveRedirectTo(const KURL&);
- void DidReceiveResponse(unsigned long identifier,
- std::unique_ptr<CrossThreadResourceResponseData>,
- std::unique_ptr<WebDataConsumerHandle>);
- void DidReceiveData(std::unique_ptr<Vector<char>> data);
- void DidReceiveCachedMetadata(std::unique_ptr<Vector<char>> data);
- void DidFinishLoading(unsigned long identifier);
- void DidFail(const ResourceError&);
- void DidFailRedirectCheck();
- void DidDownloadData(int data_length);
- void DidDownloadToBlob(scoped_refptr<BlobDataHandle>);
- void DidReceiveResourceTiming(
- std::unique_ptr<CrossThreadResourceTimingInfoData>);
-
- Member<WorkerGlobalScope> worker_global_scope_;
- CrossThreadPersistent<ParentExecutionContextTaskRunners>
- parent_execution_context_task_runners_;
- ThreadableLoaderClient* client_;
-
- ThreadableLoaderOptions threadable_loader_options_;
- ResourceLoaderOptions resource_loader_options_;
-
- // |parent_thread_loader_holder_| lives in the parent thread.
- CrossThreadPersistent<ParentThreadLoaderHolder> parent_thread_loader_holder_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_WORKER_THREADABLE_LOADER_H_
diff --git a/chromium/third_party/blink/renderer/core/messaging/blink_cloneable_message.h b/chromium/third_party/blink/renderer/core/messaging/blink_cloneable_message.h
index f6d052ee401..a51e888047a 100644
--- a/chromium/third_party/blink/renderer/core/messaging/blink_cloneable_message.h
+++ b/chromium/third_party/blink/renderer/core/messaging/blink_cloneable_message.h
@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_MESSAGING_BLINK_CLONEABLE_MESSAGE_H_
#include "base/macros.h"
+#include "base/unguessable_token.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "v8/include/v8-inspector.h"
@@ -25,6 +26,7 @@ struct CORE_EXPORT BlinkCloneableMessage {
scoped_refptr<blink::SerializedScriptValue> message;
v8_inspector::V8StackTraceId sender_stack_trace_id;
+ base::Optional<base::UnguessableToken> locked_agent_cluster_id;
private:
DISALLOW_COPY_AND_ASSIGN(BlinkCloneableMessage);
diff --git a/chromium/third_party/blink/renderer/core/messaging/blink_cloneable_message_struct_traits.cc b/chromium/third_party/blink/renderer/core/messaging/blink_cloneable_message_struct_traits.cc
index 5afbd1bb475..9c00950edb8 100644
--- a/chromium/third_party/blink/renderer/core/messaging/blink_cloneable_message_struct_traits.cc
+++ b/chromium/third_party/blink/renderer/core/messaging/blink_cloneable_message_struct_traits.cc
@@ -41,6 +41,10 @@ bool StructTraits<blink::mojom::blink::CloneableMessage::DataView,
std::make_pair(data.stack_trace_debugger_id_first(),
data.stack_trace_debugger_id_second()));
+ base::Optional<base::UnguessableToken> locked_agent_cluster_id;
+ if (!data.ReadLockedAgentClusterId(&locked_agent_cluster_id))
+ return false;
+ out->locked_agent_cluster_id = locked_agent_cluster_id;
return true;
}
diff --git a/chromium/third_party/blink/renderer/core/messaging/blink_cloneable_message_struct_traits.h b/chromium/third_party/blink/renderer/core/messaging/blink_cloneable_message_struct_traits.h
index 7420e0d0efc..f74cfcb552d 100644
--- a/chromium/third_party/blink/renderer/core/messaging/blink_cloneable_message_struct_traits.h
+++ b/chromium/third_party/blink/renderer/core/messaging/blink_cloneable_message_struct_traits.h
@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_MESSAGING_BLINK_CLONEABLE_MESSAGE_STRUCT_TRAITS_H_
#include "mojo/public/cpp/base/big_buffer.h"
+#include "mojo/public/cpp/base/unguessable_token_mojom_traits.h"
#include "mojo/public/cpp/bindings/array_traits_wtf_vector.h"
#include "mojo/public/cpp/bindings/string_traits_wtf.h"
#include "third_party/blink/public/mojom/message_port/message_port.mojom-blink.h"
@@ -27,20 +28,25 @@ struct CORE_EXPORT StructTraits<blink::mojom::blink::CloneableMessage::DataView,
static Vector<scoped_refptr<blink::BlobDataHandle>> blobs(
blink::BlinkCloneableMessage& input);
- static uint64_t stack_trace_id(blink::BlinkCloneableMessage& input) {
+ static uint64_t stack_trace_id(const blink::BlinkCloneableMessage& input) {
return static_cast<uint64_t>(input.sender_stack_trace_id.id);
}
static int64_t stack_trace_debugger_id_first(
- blink::BlinkCloneableMessage& input) {
+ const blink::BlinkCloneableMessage& input) {
return input.sender_stack_trace_id.debugger_id.first;
}
static int64_t stack_trace_debugger_id_second(
- blink::BlinkCloneableMessage& input) {
+ const blink::BlinkCloneableMessage& input) {
return input.sender_stack_trace_id.debugger_id.second;
}
+ static const base::Optional<base::UnguessableToken>& locked_agent_cluster_id(
+ const blink::BlinkCloneableMessage& input) {
+ return input.locked_agent_cluster_id;
+ }
+
static bool Read(blink::mojom::blink::CloneableMessage::DataView,
blink::BlinkCloneableMessage* out);
};
diff --git a/chromium/third_party/blink/renderer/core/messaging/blink_transferable_message.cc b/chromium/third_party/blink/renderer/core/messaging/blink_transferable_message.cc
index 7872a69b6fc..3bed37ca88c 100644
--- a/chromium/third_party/blink/renderer/core/messaging/blink_transferable_message.cc
+++ b/chromium/third_party/blink/renderer/core/messaging/blink_transferable_message.cc
@@ -36,8 +36,14 @@ BlinkTransferableMessage ToBlinkTransferableMessage(
message.stack_trace_id,
std::make_pair(message.stack_trace_debugger_id_first,
message.stack_trace_debugger_id_second));
+ result.locked_agent_cluster_id = message.locked_agent_cluster_id;
result.ports.AppendRange(message.ports.begin(), message.ports.end());
result.has_user_gesture = message.has_user_gesture;
+ if (message.user_activation) {
+ result.user_activation = mojom::blink::UserActivationSnapshot::New(
+ message.user_activation->has_been_active,
+ message.user_activation->was_active);
+ }
return result;
}
@@ -58,8 +64,14 @@ TransferableMessage ToTransferableMessage(BlinkTransferableMessage message) {
message.sender_stack_trace_id.debugger_id.first;
result.stack_trace_debugger_id_second =
message.sender_stack_trace_id.debugger_id.second;
+ result.locked_agent_cluster_id = message.locked_agent_cluster_id;
result.ports.assign(message.ports.begin(), message.ports.end());
result.has_user_gesture = message.has_user_gesture;
+ if (message.user_activation) {
+ result.user_activation = mojom::UserActivationSnapshot::New(
+ message.user_activation->has_been_active,
+ message.user_activation->was_active);
+ }
return result;
}
diff --git a/chromium/third_party/blink/renderer/core/messaging/blink_transferable_message.h b/chromium/third_party/blink/renderer/core/messaging/blink_transferable_message.h
index 8aeaebeb948..b1ac191382d 100644
--- a/chromium/third_party/blink/renderer/core/messaging/blink_transferable_message.h
+++ b/chromium/third_party/blink/renderer/core/messaging/blink_transferable_message.h
@@ -8,9 +8,11 @@
#include "base/macros.h"
#include "third_party/blink/public/common/message_port/message_port_channel.h"
#include "third_party/blink/public/common/message_port/transferable_message.h"
+#include "third_party/blink/public/mojom/message_port/user_activation_snapshot.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/messaging/blink_cloneable_message.h"
+#include "third_party/blink/renderer/platform/cross_thread_copier.h"
namespace blink {
@@ -29,6 +31,8 @@ struct CORE_EXPORT BlinkTransferableMessage : BlinkCloneableMessage {
bool has_user_gesture = false;
+ mojom::blink::UserActivationSnapshotPtr user_activation;
+
private:
DISALLOW_COPY_AND_ASSIGN(BlinkTransferableMessage);
};
@@ -41,6 +45,15 @@ CORE_EXPORT BlinkTransferableMessage
// longer.
CORE_EXPORT TransferableMessage ToTransferableMessage(BlinkTransferableMessage);
+template <>
+struct CrossThreadCopier<BlinkTransferableMessage> {
+ STATIC_ONLY(CrossThreadCopier);
+ using Type = BlinkTransferableMessage;
+ static Type Copy(Type pointer) {
+ return pointer; // This is in fact a move.
+ }
+};
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_MESSAGING_BLINK_TRANSFERABLE_MESSAGE_H_
diff --git a/chromium/third_party/blink/renderer/core/messaging/blink_transferable_message_struct_traits.cc b/chromium/third_party/blink/renderer/core/messaging/blink_transferable_message_struct_traits.cc
index a223c52a098..06b904b3b14 100644
--- a/chromium/third_party/blink/renderer/core/messaging/blink_transferable_message_struct_traits.cc
+++ b/chromium/third_party/blink/renderer/core/messaging/blink_transferable_message_struct_traits.cc
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/messaging/blink_transferable_message_struct_traits.h"
#include "mojo/public/cpp/base/big_buffer_mojom_traits.h"
+#include "third_party/blink/public/mojom/message_port/message_port.mojom-blink.h"
#include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
#include "third_party/skia/include/core/SkBitmap.h"
@@ -71,7 +72,7 @@ bool StructTraits<blink::mojom::blink::TransferableMessage::DataView,
if (!data.ReadMessage(static_cast<blink::BlinkCloneableMessage*>(out)) ||
!data.ReadArrayBufferContentsArray(&array_buffer_contents_array) ||
!data.ReadImageBitmapContentsArray(&sk_bitmaps) ||
- !data.ReadPorts(&ports)) {
+ !data.ReadPorts(&ports) || !data.ReadUserActivation(&out->user_activation)) {
return false;
}
@@ -98,7 +99,6 @@ bool StructTraits<blink::mojom::blink::TransferableMessage::DataView,
image_bitmap_contents_array.push_back(bitmap_contents);
}
out->message->SetImageBitmapContentsArray(image_bitmap_contents_array);
-
return true;
}
diff --git a/chromium/third_party/blink/renderer/core/messaging/blink_transferable_message_struct_traits.h b/chromium/third_party/blink/renderer/core/messaging/blink_transferable_message_struct_traits.h
index 1efcbb3d203..a2f966f3e57 100644
--- a/chromium/third_party/blink/renderer/core/messaging/blink_transferable_message_struct_traits.h
+++ b/chromium/third_party/blink/renderer/core/messaging/blink_transferable_message_struct_traits.h
@@ -46,6 +46,11 @@ struct CORE_EXPORT
return input.has_user_gesture;
}
+ static const blink::mojom::blink::UserActivationSnapshotPtr& user_activation(
+ const blink::BlinkTransferableMessage& input) {
+ return input.user_activation;
+ }
+
static bool Read(blink::mojom::blink::TransferableMessage::DataView,
blink::BlinkTransferableMessage* out);
};
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 ce45e3fdbea..c12cd58d012 100644
--- a/chromium/third_party/blink/renderer/core/messaging/message_port.cc
+++ b/chromium/third_party/blink/renderer/core/messaging/message_port.cc
@@ -31,14 +31,15 @@
#include "mojo/public/cpp/base/big_buffer_mojom_traits.h"
#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/serialized_script_value.h"
-#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_factory.h"
+#include "third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.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/use_counter.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_struct_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"
@@ -47,8 +48,12 @@
namespace blink {
+// TODO(altimin): Remove these after per-task mojo dispatching.
// The maximum number of MessageEvents to dispatch from one task.
-static const int kMaximumMessagesPerTask = 200;
+constexpr int kMaximumMessagesPerTask = 200;
+// The threshold to stop processing new tasks.
+constexpr base::TimeDelta kYieldThreshold =
+ base::TimeDelta::FromMilliseconds(50);
MessagePort* MessagePort::Create(ExecutionContext& execution_context) {
return new MessagePort(execution_context);
@@ -63,8 +68,18 @@ MessagePort::~MessagePort() {
}
void MessagePort::postMessage(ScriptState* script_state,
- scoped_refptr<SerializedScriptValue> message,
- const MessagePortArray& ports,
+ const ScriptValue& message,
+ Vector<ScriptValue>& transfer,
+ ExceptionState& exception_state) {
+ PostMessageOptions options;
+ if (!transfer.IsEmpty())
+ options.setTransfer(transfer);
+ postMessage(script_state, message, options, exception_state);
+}
+
+void MessagePort::postMessage(ScriptState* script_state,
+ const ScriptValue& message,
+ const PostMessageOptions& options,
ExceptionState& exception_state) {
if (!IsEntangled())
return;
@@ -72,11 +87,17 @@ void MessagePort::postMessage(ScriptState* script_state,
DCHECK(!IsNeutered());
BlinkTransferableMessage msg;
- msg.message = message;
+ Transferables transferables;
+ msg.message = PostMessageHelper::SerializeMessageByMove(
+ script_state->GetIsolate(), message, options, transferables,
+ exception_state);
+ if (exception_state.HadException())
+ return;
+ DCHECK(msg.message);
// Make sure we aren't connected to any of the passed-in ports.
- for (unsigned i = 0; i < ports.size(); ++i) {
- if (ports[i] == this) {
+ for (unsigned i = 0; i < transferables.message_ports.size(); ++i) {
+ if (transferables.message_ports[i] == this) {
exception_state.ThrowDOMException(
DOMExceptionCode::kDataCloneError,
"Port at index " + String::Number(i) + " contains the source port.");
@@ -84,14 +105,23 @@ void MessagePort::postMessage(ScriptState* script_state,
}
}
msg.ports = MessagePort::DisentanglePorts(
- ExecutionContext::From(script_state), ports, exception_state);
+ ExecutionContext::From(script_state), transferables.message_ports,
+ exception_state);
if (exception_state.HadException())
return;
+ msg.user_activation = PostMessageHelper::CreateUserActivationSnapshot(
+ GetExecutionContext(), options);
ThreadDebugger* debugger = ThreadDebugger::From(script_state->GetIsolate());
if (debugger)
msg.sender_stack_trace_id = debugger->StoreCurrentStackTrace("postMessage");
+ if (msg.message->IsLockedToAgentCluster()) {
+ msg.locked_agent_cluster_id = GetExecutionContext()->GetAgentClusterID();
+ } else {
+ msg.locked_agent_cluster_id = base::nullopt;
+ }
+
mojo::Message mojo_message =
mojom::blink::TransferableMessage::WrapAsMessage(std::move(msg));
connector_->Accept(&mojo_message);
@@ -224,7 +254,7 @@ MessagePortArray* MessagePort::EntanglePorts(
return port_array;
}
-MojoHandle MessagePort::EntangledHandleForTesting() const {
+::MojoHandle MessagePort::EntangledHandleForTesting() const {
return connector_->handle().value();
}
@@ -234,17 +264,20 @@ void MessagePort::Trace(blink::Visitor* 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)));
}
- ++messages_in_current_task_;
- if (messages_in_current_task_ > kMaximumMessagesPerTask) {
+ if (ShouldYieldAfterNewMessage()) {
connector_->PauseIncomingMethodCallProcessing();
}
@@ -261,15 +294,29 @@ bool MessagePort::Accept(mojo::Message* mojo_message) {
return true;
}
- MessagePortArray* ports = MessagePort::EntanglePorts(
- *GetExecutionContext(), std::move(message.ports));
- Event* evt = MessageEvent::Create(ports, std::move(message.message));
+ Event* evt;
+ if (!message.locked_agent_cluster_id ||
+ GetExecutionContext()->IsSameAgentCluster(
+ *message.locked_agent_cluster_id)) {
+ MessagePortArray* ports = MessagePort::EntanglePorts(
+ *GetExecutionContext(), std::move(message.ports));
+ UserActivation* user_activation = nullptr;
+ if (message.user_activation) {
+ user_activation =
+ new UserActivation(message.user_activation->has_been_active,
+ message.user_activation->was_active);
+ }
+ evt = MessageEvent::Create(ports, std::move(message.message),
+ user_activation);
+ } else {
+ evt = MessageEvent::CreateError();
+ }
v8::Isolate* isolate = ToIsolate(GetExecutionContext());
ThreadDebugger* debugger = ThreadDebugger::From(isolate);
if (debugger)
debugger->ExternalAsyncTaskStarted(message.sender_stack_trace_id);
- DispatchEvent(evt);
+ DispatchEvent(*evt);
if (debugger)
debugger->ExternalAsyncTaskFinished(message.sender_stack_trace_id);
return true;
@@ -278,9 +325,20 @@ bool MessagePort::Accept(mojo::Message* mojo_message) {
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 f9406552582..cf609e7b2d8 100644
--- a/chromium/third_party/blink/renderer/core/messaging/message_port.h
+++ b/chromium/third_party/blink/renderer/core/messaging/message_port.h
@@ -46,8 +46,8 @@ namespace blink {
class ExceptionState;
class ExecutionContext;
+class PostMessageOptions;
class ScriptState;
-class SerializedScriptValue;
class CORE_EXPORT MessagePort : public EventTargetWithInlineData,
public mojo::MessageReceiver,
@@ -61,10 +61,13 @@ class CORE_EXPORT MessagePort : public EventTargetWithInlineData,
~MessagePort() override;
void postMessage(ScriptState*,
- scoped_refptr<SerializedScriptValue> message,
- const MessagePortArray&,
+ const ScriptValue& message,
+ Vector<ScriptValue>& transfer,
+ ExceptionState&);
+ void postMessage(ScriptState*,
+ const ScriptValue& message,
+ const PostMessageOptions&,
ExceptionState&);
- static bool CanTransferArrayBuffersAndImageBitmaps() { return true; }
void start();
void close();
@@ -124,7 +127,7 @@ class CORE_EXPORT MessagePort : public EventTargetWithInlineData,
bool IsNeutered() const { return !connector_ || !connector_->is_valid(); }
// For testing only: allows inspection of the entangled channel.
- MojoHandle EntangledHandleForTesting() const;
+ ::MojoHandle EntangledHandleForTesting() const;
void Trace(blink::Visitor*) override;
@@ -135,6 +138,7 @@ class CORE_EXPORT MessagePort : public EventTargetWithInlineData,
// mojo::MessageReceiver implementation.
bool Accept(mojo::Message*) override;
void ResetMessageCount();
+ bool ShouldYieldAfterNewMessage();
std::unique_ptr<mojo::Connector> connector_;
int messages_in_current_task_ = 0;
@@ -142,6 +146,8 @@ class CORE_EXPORT MessagePort : public EventTargetWithInlineData,
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 094c3230fcb..60163f12e48 100644
--- a/chromium/third_party/blink/renderer/core/messaging/message_port.idl
+++ b/chromium/third_party/blink/renderer/core/messaging/message_port.idl
@@ -31,7 +31,8 @@
ActiveScriptWrappable,
Exposed=(Window,Worker,AudioWorklet)
] interface MessagePort : EventTarget {
- [PostMessage, RaisesException, Measure] void postMessage(any message, optional sequence<object> transfer = []);
+ [CallWith=ScriptState, RaisesException, Measure] void postMessage(any message, optional sequence<object> transfer = []);
+ [RuntimeEnabled=PostMessageOptions, CallWith=ScriptState, RaisesException, Measure] void postMessage(any message, PostMessageOptions options);
[Measure] void start();
[Measure] void close();
diff --git a/chromium/third_party/blink/renderer/core/messaging/post_message_options.idl b/chromium/third_party/blink/renderer/core/messaging/post_message_options.idl
new file mode 100644
index 00000000000..94df9264d70
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/messaging/post_message_options.idl
@@ -0,0 +1,10 @@
+// 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/whatwg/html/issues/3799
+
+dictionary PostMessageOptions {
+ sequence<object> transfer = [];
+ [RuntimeEnabled=UserActivationAPI] boolean includeUserActivation = false;
+};
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 9932560d840..a77ab768825 100644
--- a/chromium/third_party/blink/renderer/core/mojo/mojo_handle.cc
+++ b/chromium/third_party/blink/renderer/core/mojo/mojo_handle.cc
@@ -221,10 +221,12 @@ void MojoHandle::mapBuffer(unsigned offset,
result_dict.setResult(result);
if (result == MOJO_RESULT_OK) {
WTF::ArrayBufferContents::DataHandle data_handle(
- data, num_bytes, [](void* buffer) {
+ data, num_bytes,
+ [](void* buffer, size_t length, void* alloc_data) {
MojoResult result = MojoUnmapBuffer(buffer);
DCHECK_EQ(result, MOJO_RESULT_OK);
- });
+ },
+ nullptr);
WTF::ArrayBufferContents contents(std::move(data_handle),
WTF::ArrayBufferContents::kNotShared);
result_dict.setBuffer(DOMArrayBuffer::Create(contents));
diff --git a/chromium/third_party/blink/renderer/core/mojo/mojo_handle.h b/chromium/third_party/blink/renderer/core/mojo/mojo_handle.h
index 63ed21cb207..94a4c3e1caf 100644
--- a/chromium/third_party/blink/renderer/core/mojo/mojo_handle.h
+++ b/chromium/third_party/blink/renderer/core/mojo/mojo_handle.h
@@ -27,11 +27,11 @@ class MojoWriteDataResult;
class ScriptState;
class V8MojoWatchCallback;
-class MojoHandle final : public ScriptWrappable {
+class CORE_EXPORT MojoHandle final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
- CORE_EXPORT static MojoHandle* Create(mojo::ScopedHandle);
+ static MojoHandle* Create(mojo::ScopedHandle);
mojo::ScopedHandle TakeHandle();
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 6e7bd8fca53..dc8e2449101 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
@@ -173,7 +173,7 @@ void MojoInterfaceInterceptor::OnInterfaceRequest(
void MojoInterfaceInterceptor::DispatchInterfaceRequestEvent(
mojo::ScopedMessagePipeHandle handle) {
- DispatchEvent(MojoInterfaceRequestEvent::Create(
+ DispatchEvent(*MojoInterfaceRequestEvent::Create(
MojoHandle::Create(mojo::ScopedHandle::From(std::move(handle)))));
}
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 f81321a5111..17e7e45e69a 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,6 +4,7 @@
#include "third_party/blink/renderer/core/mojo/test/mojo_interface_request_event.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"
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 33d9f348c4e..d0508252d7d 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
@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_MOJO_TEST_MOJO_INTERFACE_REQUEST_EVENT_H_
#include "third_party/blink/renderer/core/dom/events/event.h"
+#include "third_party/blink/renderer/core/event_names.h"
namespace blink {
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 a96e0c03616..0f3d66c0dc2 100644
--- a/chromium/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.cc
+++ b/chromium/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.cc
@@ -51,7 +51,8 @@ void OffscreenCanvas::Commit(scoped_refptr<CanvasResource> canvas_resource,
base::TimeTicks commit_start_time = WTF::CurrentTimeTicks();
current_frame_damage_rect_.join(damage_rect);
GetOrCreateResourceDispatcher()->DispatchFrameSync(
- canvas_resource->Bitmap(), commit_start_time, current_frame_damage_rect_);
+ std::move(canvas_resource), commit_start_time, current_frame_damage_rect_,
+ !RenderingContext()->IsOriginTopLeft() /* needs_vertical_flip */);
current_frame_damage_rect_ = SkIRect::MakeEmpty();
}
@@ -321,7 +322,7 @@ CanvasResourceProvider* OffscreenCanvas::GetOrCreateResourceProvider() {
ReplaceResourceProvider(CanvasResourceProvider::Create(
surface_size, usage, SharedGpuContext::ContextProviderWrapper(), 0,
context_->ColorParams(), presentation_mode,
- std::move(dispatcher_weakptr)));
+ std::move(dispatcher_weakptr), false /* is_origin_top_left */));
// The fallback chain for k*CompositedResourceUsage should never fall
// all the way through to BitmapResourceProvider, except in unit tests.
@@ -391,7 +392,8 @@ void OffscreenCanvas::PushFrame(scoped_refptr<CanvasResource> canvas_resource,
return;
base::TimeTicks commit_start_time = WTF::CurrentTimeTicks();
GetOrCreateResourceDispatcher()->DispatchFrame(
- canvas_resource->Bitmap(), commit_start_time, current_frame_damage_rect_);
+ std::move(canvas_resource), commit_start_time, current_frame_damage_rect_,
+ !RenderingContext()->IsOriginTopLeft() /* needs_vertical_flip */);
current_frame_damage_rect_ = SkIRect::MakeEmpty();
}
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 a1c67e02ee8..ef939251a60 100644
--- a/chromium/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h
+++ b/chromium/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h
@@ -9,7 +9,6 @@
#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_image_source.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"
@@ -39,7 +38,6 @@ typedef OffscreenCanvasRenderingContext2DOrWebGLRenderingContextOrWebGL2Renderin
class CORE_EXPORT OffscreenCanvas final
: public EventTargetWithInlineData,
- public CanvasImageSource,
public ImageBitmapSource,
public CanvasRenderingContextHost,
public CanvasResourceDispatcherClient {
@@ -158,7 +156,7 @@ class CORE_EXPORT OffscreenCanvas final
bool IsAccelerated() const final;
DispatchEventResult HostDispatchEvent(Event* event) override {
- return DispatchEvent(event);
+ return DispatchEvent(*event);
}
bool IsWebGL1Enabled() const override { return true; }
diff --git a/chromium/third_party/blink/renderer/core/page/BUILD.gn b/chromium/third_party/blink/renderer/core/page/BUILD.gn
index ec5831d4deb..612cc878402 100644
--- a/chromium/third_party/blink/renderer/core/page/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/page/BUILD.gn
@@ -89,8 +89,6 @@ blink_core_sources("page") {
"spatial_navigation.h",
"touch_adjustment.cc",
"touch_adjustment.h",
- "touch_disambiguation.cc",
- "touch_disambiguation.h",
"validation_message_client.h",
"validation_message_client_impl.cc",
"validation_message_client_impl.h",
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 9849c205f65..1ea9a2938bb 100644
--- a/chromium/third_party/blink/renderer/core/page/chrome_client.cc
+++ b/chromium/third_party/blink/renderer/core/page/chrome_client.cc
@@ -41,7 +41,6 @@ namespace blink {
void ChromeClient::Trace(blink::Visitor* visitor) {
visitor->Trace(last_mouse_over_node_);
- PlatformChromeClient::Trace(visitor);
}
void ChromeClient::InstallSupplements(LocalFrame& frame) {
@@ -188,7 +187,7 @@ void ChromeClient::SetToolTip(LocalFrame& frame,
// Lastly, some elements provide default tooltip strings. e.g. <input
// type="file" multiple> shows a tooltip for the selected filenames.
- if (tool_tip.IsEmpty()) {
+ if (tool_tip.IsNull()) {
if (Node* node = result.InnerNode()) {
if (node->IsElementNode()) {
tool_tip = ToElement(node)->DefaultToolTip();
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 a032cc6d181..ec58708d7e3 100644
--- a/chromium/third_party/blink/renderer/core/page/chrome_client.h
+++ b/chromium/third_party/blink/renderer/core/page/chrome_client.h
@@ -30,6 +30,7 @@
#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_layer_tree_view.h"
#include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/animation_worklet_proxy_client.h"
@@ -42,7 +43,6 @@
#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/platform_chrome_client.h"
#include "third_party/blink/renderer/platform/scroll/scroll_types.h"
#include "third_party/blink/renderer/platform/text/text_direction.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
@@ -86,7 +86,6 @@ class WebDragData;
class WebLayerTreeView;
class WebViewImpl;
-struct CompositedSelection;
struct DateTimeChooserParameters;
struct FrameLoadRequest;
struct ViewportDescription;
@@ -95,8 +94,19 @@ struct WebPoint;
struct WebScreenInfo;
struct WebWindowFeatures;
-class CORE_EXPORT ChromeClient : public PlatformChromeClient {
+class CORE_EXPORT ChromeClient
+ : public GarbageCollectedFinalized<ChromeClient> {
+ DISALLOW_COPY_AND_ASSIGN(ChromeClient);
+
public:
+ virtual ~ChromeClient() = default;
+
+ // Converts the scalar value from the window coordinates to the viewport
+ // scale.
+ virtual float WindowToViewportScalar(const float) const = 0;
+
+ virtual bool IsPopup() { return false; }
+
virtual void ChromeDestroyed() = 0;
// Requests the host invalidate the contents.
@@ -184,10 +194,8 @@ class CORE_EXPORT ChromeClient : public PlatformChromeClient {
virtual WebViewImpl* GetWebView() const = 0;
- // Methods used by PlatformChromeClient.
virtual WebScreenInfo GetScreenInfo() const = 0;
virtual void SetCursor(const Cursor&, LocalFrame* local_root) = 0;
- // End methods used by PlatformChromeClient.
virtual void SetCursorOverridden(bool) = 0;
@@ -217,7 +225,7 @@ class CORE_EXPORT ChromeClient : public PlatformChromeClient {
}
virtual void MainFrameScrollOffsetChanged() const {}
virtual void ResizeAfterLayout() const {}
- virtual void LayoutUpdated() const {}
+ virtual void MainFrameLayoutUpdated() const {}
void MouseDidMoveOverElement(LocalFrame&,
const HitTestLocation&,
@@ -272,9 +280,8 @@ class CORE_EXPORT ChromeClient : public PlatformChromeClient {
virtual void FullscreenElementChanged(Element* old_element,
Element* new_element) {}
- virtual void ClearCompositedSelection(LocalFrame*) {}
- virtual void UpdateCompositedSelection(LocalFrame*,
- const CompositedSelection&) {}
+ virtual void ClearLayerSelection(LocalFrame*) {}
+ virtual void UpdateLayerSelection(LocalFrame*, const cc::LayerSelection&) {}
virtual void SetEventListenerProperties(LocalFrame*,
cc::EventListenerClass,
@@ -362,10 +369,10 @@ class CORE_EXPORT ChromeClient : public PlatformChromeClient {
std::move(callback).Run(false);
}
- void Trace(blink::Visitor*) override;
+ virtual void Trace(blink::Visitor*);
protected:
- ~ChromeClient() override = default;
+ ChromeClient() = default;
virtual void ShowMouseOverURL(const HitTestResult&) = 0;
virtual void SetWindowRect(const IntRect&, LocalFrame&) = 0;
@@ -390,14 +397,9 @@ class CORE_EXPORT ChromeClient : public PlatformChromeClient {
String last_tool_tip_text_;
FRIEND_TEST_ALL_PREFIXES(ChromeClientTest, SetToolTipFlood);
+ FRIEND_TEST_ALL_PREFIXES(ChromeClientTest, SetToolTipEmptyString);
};
-inline ChromeClient* ToChromeClient(PlatformChromeClient* client) {
- // In production code, a PlatformChromeClient instance is always a
- // ChromeClient instance.
- return static_cast<ChromeClient*>(client);
-}
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_PAGE_CHROME_CLIENT_H_
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 5656f762955..642b6ded444 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
@@ -57,12 +57,12 @@
#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_file_chooser_completion_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"
#include "third_party/blink/renderer/core/exported/web_view_impl.h"
#include "third_party/blink/renderer/core/frame/browser_controls.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/frame/use_counter.h"
@@ -90,7 +90,6 @@
#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/page/popup_opening_observer.h"
-#include "third_party/blink/renderer/core/paint/compositing/composited_selection.h"
#include "third_party/blink/renderer/platform/animation/compositor_animation_host.h"
#include "third_party/blink/renderer/platform/cursor.h"
#include "third_party/blink/renderer/platform/exported/wrapped_resource_request.h"
@@ -153,7 +152,9 @@ ChromeClientImpl::ChromeClientImpl(WebViewImpl* web_view)
cursor_overridden_(false),
did_request_non_empty_tool_tip_(false) {}
-ChromeClientImpl::~ChromeClientImpl() = default;
+ChromeClientImpl::~ChromeClientImpl() {
+ DCHECK(file_chooser_queue_.IsEmpty());
+}
ChromeClientImpl* ChromeClientImpl::Create(WebViewImpl* web_view) {
return new ChromeClientImpl(web_view);
@@ -478,8 +479,8 @@ void ChromeClientImpl::ResizeAfterLayout() const {
web_view_->ResizeAfterLayout();
}
-void ChromeClientImpl::LayoutUpdated() const {
- web_view_->LayoutUpdated();
+void ChromeClientImpl::MainFrameLayoutUpdated() const {
+ web_view_->MainFrameLayoutUpdated();
}
void ChromeClientImpl::ShowMouseOverURL(const HitTestResult& result) {
@@ -583,20 +584,48 @@ void ChromeClientImpl::OpenFileChooser(
LocalFrame* frame,
scoped_refptr<FileChooser> file_chooser) {
NotifyPopupOpeningObservers();
- WebLocalFrameClient* client = WebLocalFrameImpl::FromFrame(frame)->Client();
- if (!client)
- return;
Document* doc = frame->GetDocument();
if (doc)
doc->MaybeQueueSendDidEditFieldInInsecureContext();
- const WebFileChooserParams& params = file_chooser->Params();
- WebFileChooserCompletionImpl* chooser_completion =
- new WebFileChooserCompletionImpl(std::move(file_chooser));
- if (client->RunFileChooser(params, chooser_completion))
+
+ static const wtf_size_t kMaximumPendingFileChooseRequests = 4;
+ if (file_chooser_queue_.size() > kMaximumPendingFileChooseRequests) {
+ // This sanity check prevents too many file choose requests from getting
+ // queued which could DoS the user. Getting these is most likely a
+ // programming error (there are many ways to DoS the user so it's not
+ // considered a "real" security check), either in JS requesting many file
+ // choosers to pop up, or in a plugin.
+ //
+ // TODO(brettw): We might possibly want to require a user gesture to open
+ // a file picker, which will address this issue in a better way.
return;
- // Choosing failed, so do callback with an empty list.
- chooser_completion->DidChooseFile(WebVector<WebString>());
+ }
+ file_chooser_queue_.push_back(file_chooser.get());
+ if (file_chooser_queue_.size() == 1) {
+ // Actually show the browse dialog when this is the first request.
+ if (file_chooser->OpenFileChooser(*this))
+ return;
+ // Choosing failed, so try the next chooser.
+ DidCompleteFileChooser(*file_chooser);
+ }
+}
+
+void ChromeClientImpl::DidCompleteFileChooser(FileChooser& chooser) {
+ if (!file_chooser_queue_.IsEmpty() &&
+ file_chooser_queue_.front().get() != &chooser) {
+ // This function is called even if |chooser| wasn't stored in
+ // file_chooser_queue_.
+ return;
+ }
+ file_chooser_queue_.EraseAt(0);
+ if (file_chooser_queue_.IsEmpty())
+ return;
+ FileChooser* next_chooser = file_chooser_queue_.front().get();
+ if (next_chooser->OpenFileChooser(*this))
+ return;
+ // Choosing failed, so try the next chooser.
+ DidCompleteFileChooser(*next_chooser);
}
void ChromeClientImpl::EnumerateChosenDirectory(FileChooser* file_chooser) {
@@ -604,16 +633,11 @@ void ChromeClientImpl::EnumerateChosenDirectory(FileChooser* file_chooser) {
if (!client)
return;
- WebFileChooserCompletionImpl* chooser_completion =
- new WebFileChooserCompletionImpl(file_chooser);
-
DCHECK(file_chooser);
DCHECK(file_chooser->Params().selected_files.size());
-
- // If the enumeration can't happen, call the callback with an empty list.
- if (!client->EnumerateChosenDirectory(
- file_chooser->Params().selected_files[0], chooser_completion))
- chooser_completion->DidChooseFile(WebVector<WebString>());
+ if (client->EnumerateChosenDirectory(file_chooser->Params().selected_files[0],
+ file_chooser))
+ file_chooser->AddRef();
}
Cursor ChromeClientImpl::LastSetCursorForTesting() const {
@@ -748,7 +772,7 @@ void ChromeClientImpl::FullscreenElementChanged(Element* old_element,
web_view_->FullscreenElementChanged(old_element, new_element);
}
-void ChromeClientImpl::ClearCompositedSelection(LocalFrame* frame) {
+void ChromeClientImpl::ClearLayerSelection(LocalFrame* frame) {
WebFrameWidgetBase* widget =
WebLocalFrameImpl::FromFrame(frame)->LocalRootFrameWidget();
WebWidgetClient* client = widget->Client();
@@ -760,9 +784,9 @@ void ChromeClientImpl::ClearCompositedSelection(LocalFrame* frame) {
layer_tree_view->ClearSelection();
}
-void ChromeClientImpl::UpdateCompositedSelection(
+void ChromeClientImpl::UpdateLayerSelection(
LocalFrame* frame,
- const CompositedSelection& selection) {
+ const cc::LayerSelection& selection) {
WebFrameWidgetBase* widget =
WebLocalFrameImpl::FromFrame(frame)->LocalRootFrameWidget();
WebWidgetClient* client = widget->Client();
@@ -770,36 +794,8 @@ void ChromeClientImpl::UpdateCompositedSelection(
if (!client)
return;
- if (WebLayerTreeView* layer_tree_view = widget->GetLayerTreeView()) {
- DCHECK_NE(selection.type, kNoSelection);
-
- cc::LayerSelection cc_selection;
- if (selection.type == kRangeSelection) {
- cc_selection.start.type = selection.start.is_text_direction_rtl
- ? gfx::SelectionBound::Type::RIGHT
- : gfx::SelectionBound::Type::LEFT;
- cc_selection.end.type = selection.end.is_text_direction_rtl
- ? gfx::SelectionBound::Type::LEFT
- : gfx::SelectionBound::Type::RIGHT;
- } else {
- cc_selection.start.type = gfx::SelectionBound::Type::CENTER;
- cc_selection.end.type = gfx::SelectionBound::Type::CENTER;
- }
- cc_selection.start.edge_top =
- gfx::Point(RoundedIntPoint(selection.start.edge_top_in_layer));
- cc_selection.start.edge_bottom =
- gfx::Point(RoundedIntPoint(selection.start.edge_bottom_in_layer));
- cc_selection.start.layer_id = selection.start.layer->CcLayer()->id();
- cc_selection.start.hidden = selection.start.hidden;
- cc_selection.end.edge_top =
- gfx::Point(RoundedIntPoint(selection.end.edge_top_in_layer));
- cc_selection.end.edge_bottom =
- gfx::Point(RoundedIntPoint(selection.end.edge_bottom_in_layer));
- cc_selection.end.layer_id = selection.end.layer->CcLayer()->id();
- cc_selection.end.hidden = selection.end.hidden;
-
- layer_tree_view->RegisterSelection(cc_selection);
- }
+ if (WebLayerTreeView* layer_tree_view = widget->GetLayerTreeView())
+ layer_tree_view->RegisterSelection(selection);
}
bool ChromeClientImpl::HasOpenedPopup() const {
@@ -921,6 +917,9 @@ void ChromeClientImpl::SetEventListenerProperties(
tree_view->EventListenerProperties(
cc::EventListenerClass::kTouchStartOrMove) !=
cc::EventListenerProperties::kNone);
+ } else if (event_class == cc::EventListenerClass::kPointerRawMove) {
+ client->HasPointerRawMoveEventHandlers(
+ properties != cc::EventListenerProperties::kNone);
}
} else {
client->HasTouchEventHandlers(true);
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 5b9a70911d0..9b6d78e6952 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
@@ -116,7 +116,7 @@ class CORE_EXPORT ChromeClientImpl final : public ChromeClient {
float ClampPageScaleFactorToLimits(float scale) const override;
void MainFrameScrollOffsetChanged() const override;
void ResizeAfterLayout() const override;
- void LayoutUpdated() const override;
+ void MainFrameLayoutUpdated() const override;
void ShowMouseOverURL(const HitTestResult&) override;
void SetToolTip(LocalFrame&, const String&, TextDirection) override;
void DispatchViewportPropertiesDidChange(
@@ -165,9 +165,8 @@ class CORE_EXPORT ChromeClientImpl final : public ChromeClient {
void FullscreenElementChanged(Element* old_element,
Element* new_element) override;
- void ClearCompositedSelection(LocalFrame*) override;
- void UpdateCompositedSelection(LocalFrame*,
- const CompositedSelection&) override;
+ void ClearLayerSelection(LocalFrame*) override;
+ void UpdateLayerSelection(LocalFrame*, const cc::LayerSelection&) override;
// ChromeClient methods:
String AcceptLanguages() override;
@@ -176,6 +175,10 @@ class CORE_EXPORT ChromeClientImpl final : public ChromeClient {
// ChromeClientImpl:
void SetNewWindowNavigationPolicy(WebNavigationPolicy);
+ // FileChooser calls this function to kick pending file chooser
+ // requests.
+ void DidCompleteFileChooser(FileChooser& file_chooser);
+
void AutoscrollStart(WebFloatPoint viewport_point, LocalFrame*) override;
void AutoscrollFling(WebFloatSize velocity, LocalFrame*) override;
void AutoscrollEnd(LocalFrame*) override;
@@ -245,9 +248,12 @@ 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_;
bool cursor_overridden_;
bool did_request_non_empty_tool_tip_;
+
+ FRIEND_TEST_ALL_PREFIXES(FileChooserQueueTest, DerefQueuedChooser);
};
DEFINE_TYPE_CASTS(ChromeClientImpl,
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 cff471e3ff2..4e20e238942 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
@@ -42,11 +42,11 @@
#include "third_party/blink/renderer/core/html/forms/color_chooser_client.h"
#include "third_party/blink/renderer/core/html/forms/date_time_chooser.h"
#include "third_party/blink/renderer/core/html/forms/date_time_chooser_client.h"
+#include "third_party/blink/renderer/core/html/forms/file_chooser.h"
#include "third_party/blink/renderer/core/html/forms/html_select_element.h"
#include "third_party/blink/renderer/core/loader/frame_load_request.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/page/scoped_page_pauser.h"
-#include "third_party/blink/renderer/core/paint/compositing/composited_selection.h"
#include "third_party/blink/renderer/platform/language.h"
#include "third_party/blink/renderer/platform/testing/stub_graphics_layer_client.h"
@@ -240,97 +240,64 @@ TEST_F(PagePopupSuppressionTest, SuppressDateTimeChooser) {
EXPECT_TRUE(CanOpenDateTimeChooser());
}
-TEST(ChromeClientImplTest, SelectionHandles) {
- FrameTestHelpers::WebViewHelper helper;
- WebViewImpl* web_view = helper.Initialize();
- ChromeClientImpl* chrome_client_impl =
- ToChromeClientImpl(&web_view->GetPage()->GetChromeClient());
-
- content::LayerTreeView* layer_tree_view = helper.GetLayerTreeView();
- LocalFrame* main_frame = helper.LocalMainFrame()->GetFrame();
-
- auto set_and_get_selection = [&](const CompositedSelection& selection) {
- // Sets the selection on the LayerTreeHost, then return what it set.
- chrome_client_impl->UpdateCompositedSelection(main_frame, selection);
- return layer_tree_view->layer_tree_host()->selection();
- };
-
- StubGraphicsLayerClient graphics_layer_client;
- std::unique_ptr<GraphicsLayer> graphics_layer =
- GraphicsLayer::Create(graphics_layer_client);
-
- CompositedSelection selection;
- cc::LayerSelection cc_selection;
-
- selection.start.layer = graphics_layer.get();
- selection.end.layer = graphics_layer.get();
-
- // An LTR range selection.
- selection.type = kRangeSelection;
- selection.start.is_text_direction_rtl = false;
- selection.end.is_text_direction_rtl = false;
- selection.start.edge_top_in_layer = FloatPoint(1.1f, 2.8f);
- selection.start.edge_bottom_in_layer = FloatPoint(2.9f, 3.2f);
- selection.end.edge_top_in_layer = FloatPoint(4.1f, 5.8f);
- selection.end.edge_bottom_in_layer = FloatPoint(5.9f, 6.2f);
- selection.start.hidden = false;
- selection.end.hidden = false;
-
- cc_selection = set_and_get_selection(selection);
- // LTR means the start is left and the end is right.
- EXPECT_EQ(cc_selection.start.type, gfx::SelectionBound::Type::LEFT);
- EXPECT_EQ(cc_selection.end.type, gfx::SelectionBound::Type::RIGHT);
- EXPECT_EQ(cc_selection.start.hidden, false);
- EXPECT_EQ(cc_selection.end.hidden, false);
- // Points are rounded.
- EXPECT_EQ(cc_selection.start.edge_top, gfx::Point(1, 3));
- EXPECT_EQ(cc_selection.start.edge_bottom, gfx::Point(3, 3));
- EXPECT_EQ(cc_selection.end.edge_top, gfx::Point(4, 6));
- EXPECT_EQ(cc_selection.end.edge_bottom, gfx::Point(6, 6));
-
- // An RTL range selection.
- selection.start.is_text_direction_rtl = true;
- selection.end.is_text_direction_rtl = true;
-
- cc_selection = set_and_get_selection(selection);
- // RTL means the start is right and the end is left.
- EXPECT_EQ(cc_selection.start.type, gfx::SelectionBound::Type::RIGHT);
- EXPECT_EQ(cc_selection.end.type, gfx::SelectionBound::Type::LEFT);
- EXPECT_EQ(cc_selection.start.hidden, false);
- EXPECT_EQ(cc_selection.end.hidden, false);
- EXPECT_EQ(cc_selection.start.edge_top, gfx::Point(1, 3));
- EXPECT_EQ(cc_selection.start.edge_bottom, gfx::Point(3, 3));
- EXPECT_EQ(cc_selection.end.edge_top, gfx::Point(4, 6));
- EXPECT_EQ(cc_selection.end.edge_bottom, gfx::Point(6, 6));
-
- // A hidden range selection.
- selection.start.hidden = true;
- selection.end.hidden = true;
-
- cc_selection = set_and_get_selection(selection);
- EXPECT_EQ(cc_selection.start.type, gfx::SelectionBound::Type::RIGHT);
- EXPECT_EQ(cc_selection.end.type, gfx::SelectionBound::Type::LEFT);
- // The hidden flag is propogated.
- EXPECT_EQ(cc_selection.start.hidden, true);
- EXPECT_EQ(cc_selection.end.hidden, true);
- EXPECT_EQ(cc_selection.start.edge_top, gfx::Point(1, 3));
- EXPECT_EQ(cc_selection.start.edge_bottom, gfx::Point(3, 3));
- EXPECT_EQ(cc_selection.end.edge_top, gfx::Point(4, 6));
- EXPECT_EQ(cc_selection.end.edge_bottom, gfx::Point(6, 6));
-
- // A caret selection.
- selection.type = kCaretSelection;
-
- cc_selection = set_and_get_selection(selection);
- // Caret selections have no left/right, only center.
- EXPECT_EQ(cc_selection.start.type, gfx::SelectionBound::Type::CENTER);
- EXPECT_EQ(cc_selection.end.type, gfx::SelectionBound::Type::CENTER);
- EXPECT_EQ(cc_selection.start.hidden, true);
- EXPECT_EQ(cc_selection.end.hidden, true);
- EXPECT_EQ(cc_selection.start.edge_top, gfx::Point(1, 3));
- EXPECT_EQ(cc_selection.start.edge_bottom, gfx::Point(3, 3));
- EXPECT_EQ(cc_selection.end.edge_top, gfx::Point(4, 6));
- EXPECT_EQ(cc_selection.end.edge_bottom, gfx::Point(6, 6));
+// A WebLocalFrameClient which makes FileChooser::OpenFileChooser() success.
+class FrameClientForFileChooser : public FrameTestHelpers::TestWebFrameClient {
+ bool RunFileChooser(const WebFileChooserParams& params,
+ WebFileChooserCompletion* chooser_completion) override {
+ return true;
+ }
+};
+
+// A FileChooserClient which makes FileChooser::OpenFileChooser() success.
+class MockFileChooserClient
+ : public GarbageCollectedFinalized<MockFileChooserClient>,
+ public FileChooserClient {
+ USING_GARBAGE_COLLECTED_MIXIN(MockFileChooserClient);
+
+ public:
+ explicit MockFileChooserClient(LocalFrame* frame) : frame_(frame) {}
+ void Trace(Visitor* visitor) override {
+ visitor->Trace(frame_);
+ FileChooserClient::Trace(visitor);
+ }
+
+ private:
+ // FilesChosen() and WillOpenPopup() are never called in the test.
+ void FilesChosen(const Vector<FileChooserFileInfo>&) override {}
+ void WillOpenPopup() override {}
+
+ LocalFrame* FrameOrNull() const override { return frame_; }
+
+ Member<LocalFrame> frame_;
+};
+
+class FileChooserQueueTest : public testing::Test {
+ protected:
+ void SetUp() override {
+ web_view_ = helper_.Initialize(&frame_client_);
+ chrome_client_impl_ =
+ ToChromeClientImpl(&web_view_->GetPage()->GetChromeClient());
+ }
+
+ FrameTestHelpers::WebViewHelper helper_;
+ FrameClientForFileChooser frame_client_;
+ WebViewImpl* web_view_;
+ Persistent<ChromeClientImpl> chrome_client_impl_;
+};
+
+TEST_F(FileChooserQueueTest, DerefQueuedChooser) {
+ LocalFrame* frame = helper_.LocalMainFrame()->GetFrame();
+ auto* client = new MockFileChooserClient(frame);
+ WebFileChooserParams params;
+ scoped_refptr<FileChooser> chooser1 = FileChooser::Create(client, params);
+ scoped_refptr<FileChooser> chooser2 = FileChooser::Create(client, params);
+
+ chrome_client_impl_->OpenFileChooser(frame, chooser1);
+ chrome_client_impl_->OpenFileChooser(frame, chooser2);
+ EXPECT_EQ(2u, chrome_client_impl_->file_chooser_queue_.size());
+ chooser2.reset();
+ chrome_client_impl_->DidCompleteFileChooser(*chooser1);
+ EXPECT_EQ(1u, chrome_client_impl_->file_chooser_queue_.size());
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/page/chrome_client_test.cc b/chromium/third_party/blink/renderer/core/page/chrome_client_test.cc
index d97a2f2c88e..baf63b22199 100644
--- a/chromium/third_party/blink/renderer/core/page/chrome_client_test.cc
+++ b/chromium/third_party/blink/renderer/core/page/chrome_client_test.cc
@@ -6,6 +6,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/html/forms/html_input_element.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/core/layout/hit_test_result.h"
@@ -31,7 +32,6 @@ class ChromeClientToolTipLogger : public EmptyChromeClient {
private:
String tool_tip_for_last_set_tool_tip_;
};
-
} // anonymous namespace
class ChromeClientTest : public testing::Test {};
@@ -70,4 +70,32 @@ TEST_F(ChromeClientTest, SetToolTipFlood) {
EXPECT_EQ("updated", logger.ToolTipForLastSetToolTip());
}
+TEST_F(ChromeClientTest, SetToolTipEmptyString) {
+ ChromeClient* client = EmptyChromeClient::Create();
+ HitTestLocation location(LayoutPoint(10, 20));
+ HitTestResult result(HitTestRequest(HitTestRequest::kMove), location);
+ auto& doc = *Document::CreateForTest();
+ auto& input_element = *HTMLInputElement::Create(doc, CreateElementFlags());
+ input_element.setAttribute(HTMLNames::typeAttr, "file");
+
+ result.SetInnerNode(&input_element);
+ client->SetToolTip(*doc.GetFrame(), location, result);
+ EXPECT_EQ("<<NoFileChosenLabel>>", client->last_tool_tip_text_);
+
+ client->last_tool_tip_text_ = String();
+ input_element.removeAttribute(HTMLNames::titleAttr);
+ client->SetToolTip(*doc.GetFrame(), location, result);
+ EXPECT_EQ("<<NoFileChosenLabel>>", client->last_tool_tip_text_);
+
+ client->last_tool_tip_text_ = String();
+ input_element.setAttribute(HTMLNames::titleAttr, g_empty_atom);
+ client->SetToolTip(*doc.GetFrame(), location, result);
+ EXPECT_EQ(g_empty_atom, client->last_tool_tip_text_);
+
+ client->last_tool_tip_text_ = String();
+ input_element.setAttribute(HTMLNames::titleAttr, "test");
+ client->SetToolTip(*doc.GetFrame(), location, result);
+ EXPECT_EQ("test", client->last_tool_tip_text_);
+}
+
} // namespace blink
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 475a2ac3906..32636cc78d6 100644
--- a/chromium/third_party/blink/renderer/core/page/create_window.cc
+++ b/chromium/third_party/blink/renderer/core/page/create_window.cc
@@ -26,12 +26,14 @@
#include "third_party/blink/renderer/core/page/create_window.h"
+#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/network/public/mojom/request_context_frame_type.mojom-blink.h"
#include "third_party/blink/public/platform/web_input_event.h"
#include "third_party/blink/public/platform/web_url_request.h"
#include "third_party/blink/public/web/web_window_features.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/ad_tracker.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
#include "third_party/blink/renderer/core/frame/frame_client.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -195,6 +197,24 @@ static Frame* ReuseExistingWindow(LocalFrame& active_frame,
return nullptr;
}
+static void MaybeLogWindowOpenUKM(LocalFrame& opener_frame) {
+ AdTracker* ad_tracker = opener_frame.GetAdTracker();
+ if (!ad_tracker) {
+ return;
+ }
+
+ ukm::UkmRecorder* ukm_recorder = opener_frame.GetDocument()->UkmRecorder();
+ ukm::SourceId source_id = opener_frame.GetDocument()->UkmSourceID();
+ bool is_ad_subframe = opener_frame.IsAdSubframe();
+ bool is_ad_script_in_stack = ad_tracker->IsAdScriptInStack();
+ if (source_id != ukm::kInvalidSourceId) {
+ ukm::builders::AbusiveExperienceHeuristic(source_id)
+ .SetDidWindowOpenFromAdSubframe(is_ad_subframe)
+ .SetDidWindowOpenFromAdScript(is_ad_script_in_stack)
+ .Record(ukm_recorder);
+ }
+}
+
static Frame* CreateNewWindow(LocalFrame& opener_frame,
const FrameLoadRequest& request,
const WebWindowFeatures& features,
@@ -256,6 +276,7 @@ static Frame* CreateNewWindow(LocalFrame& opener_frame,
page->GetChromeClient().SetWindowRectWithAdjustment(window_rect, frame);
page->GetChromeClient().Show(policy);
+ MaybeLogWindowOpenUKM(opener_frame);
created = true;
return &frame;
}
@@ -364,6 +385,8 @@ DOMWindow* CreateWindow(const String& url_string,
// 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_frame->GetDocument()->GetReferrerPolicy(), completed_url,
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 31d56851f54..a1d141fbc9e 100644
--- a/chromium/third_party/blink/renderer/core/page/drag_controller.cc
+++ b/chromium/third_party/blink/renderer/core/page/drag_controller.cc
@@ -55,6 +55,7 @@
#include "third_party/blink/renderer/core/editing/selection_template.h"
#include "third_party/blink/renderer/core/editing/serializers/serialization.h"
#include "third_party/blink/renderer/core/events/text_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/settings.h"
@@ -470,34 +471,34 @@ DragOperation DragController::OperationForLoad(DragData* drag_data,
// |range|, otherwise returns false.
// TODO(yosin): We should return |VisibleSelection| rather than three values.
static bool SetSelectionToDragCaret(LocalFrame* frame,
- VisibleSelection& drag_caret,
+ const SelectionInDOMTree& drag_caret,
Range*& range,
const LayoutPoint& point) {
- frame->Selection().SetSelectionAndEndTyping(drag_caret.AsSelection());
- if (frame->Selection()
- .ComputeVisibleSelectionInDOMTreeDeprecated()
- .IsNone()) {
- // TODO(editing-dev): The use of
- // updateStyleAndLayoutIgnorePendingStylesheets
- // needs to be audited. See http://crbug.com/590369 for more details.
- // |LocalFrame::positinForPoint()| requires clean layout.
- frame->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
- const PositionWithAffinity& position = frame->PositionForPoint(point);
- if (!position.IsConnected())
- return false;
-
- frame->Selection().SetSelectionAndEndTyping(
- SelectionInDOMTree::Builder().Collapse(position).Build());
- drag_caret =
- frame->Selection().ComputeVisibleSelectionInDOMTreeDeprecated();
- range = CreateRange(drag_caret.ToNormalizedEphemeralRange());
+ frame->Selection().SetSelectionAndEndTyping(drag_caret);
+ // TODO(editing-dev): The use of
+ // UpdateStyleAndLayoutIgnorePendingStylesheets
+ // needs to be audited. See http://crbug.com/590369 for more details.
+ frame->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+ if (!frame->Selection().ComputeVisibleSelectionInDOMTree().IsNone()) {
+ return frame->Selection()
+ .ComputeVisibleSelectionInDOMTree()
+ .IsContentEditable();
}
- return !frame->Selection()
- .ComputeVisibleSelectionInDOMTreeDeprecated()
- .IsNone() &&
- frame->Selection()
- .ComputeVisibleSelectionInDOMTreeDeprecated()
- .IsContentEditable();
+
+ const PositionWithAffinity& position = frame->PositionForPoint(point);
+ if (!position.IsConnected())
+ return false;
+
+ frame->Selection().SetSelectionAndEndTyping(
+ SelectionInDOMTree::Builder().Collapse(position).Build());
+ // TODO(editing-dev): The use of
+ // UpdateStyleAndLayoutIgnorePendingStylesheets
+ // needs to be audited. See http://crbug.com/590369 for more details.
+ frame->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
+ const VisibleSelection& visible_selection =
+ frame->Selection().ComputeVisibleSelectionInDOMTree();
+ range = CreateRange(visible_selection.ToNormalizedEphemeralRange());
+ return !visible_selection.IsNone() && visible_selection.IsContentEditable();
}
DispatchEventResult DragController::DispatchTextInputEventFor(
@@ -517,7 +518,7 @@ DispatchEventResult DragController::DispatchTextInputEventFor(
CreateVisibleSelection(
SelectionInDOMTree::Builder().Collapse(caret_position).Build()));
return target->DispatchEvent(
- TextEvent::CreateForDrop(inner_frame->DomWindow(), text));
+ *TextEvent::CreateForDrop(inner_frame->DomWindow(), text));
}
bool DragController::ConcludeEditDrag(DragData* drag_data) {
@@ -652,7 +653,8 @@ bool DragController::ConcludeEditDrag(DragData* drag_data) {
return false;
}
} else {
- if (SetSelectionToDragCaret(inner_frame, drag_caret, range, point)) {
+ if (SetSelectionToDragCaret(inner_frame, drag_caret.AsSelection(), range,
+ point)) {
DCHECK(document_under_mouse_);
if (!inner_frame->GetEditor().ReplaceSelectionAfterDraggingWithEvents(
element, drag_data, fragment, range,
@@ -667,7 +669,8 @@ bool DragController::ConcludeEditDrag(DragData* drag_data) {
if (text.IsEmpty())
return false;
- if (SetSelectionToDragCaret(inner_frame, drag_caret, range, point)) {
+ if (SetSelectionToDragCaret(inner_frame, drag_caret.AsSelection(), range,
+ point)) {
DCHECK(document_under_mouse_);
if (!inner_frame->GetEditor().ReplaceSelectionAfterDraggingWithEvents(
element, drag_data,
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 e2e6d4af5fa..95812991fa6 100644
--- a/chromium/third_party/blink/renderer/core/page/focus_controller.cc
+++ b/chromium/third_party/blink/renderer/core/page/focus_controller.cc
@@ -399,9 +399,10 @@ inline void DispatchEventsOnWindowAndFocusedElement(Document* document,
DispatchBlurEvent(*document, *focused_element);
}
- if (LocalDOMWindow* window = document->domWindow())
+ if (LocalDOMWindow* window = document->domWindow()) {
window->DispatchEvent(
- Event::Create(focused ? EventTypeNames::focus : EventTypeNames::blur));
+ *Event::Create(focused ? EventTypeNames::focus : EventTypeNames::blur));
+ }
if (focused && document->FocusedElement()) {
Element* focused_element(document->FocusedElement());
// Use focus_type kWebFocusTypePage, same as used in DispatchFocusEvent.
@@ -789,12 +790,13 @@ void FocusController::SetFocusedFrame(Frame* frame, bool notify_embedder) {
// states of both frames.
if (old_frame && old_frame->View()) {
old_frame->Selection().SetFrameIsFocused(false);
- old_frame->DomWindow()->DispatchEvent(Event::Create(EventTypeNames::blur));
+ old_frame->DomWindow()->DispatchEvent(*Event::Create(EventTypeNames::blur));
}
if (new_frame && new_frame->View() && IsFocused()) {
new_frame->Selection().SetFrameIsFocused(true);
- new_frame->DomWindow()->DispatchEvent(Event::Create(EventTypeNames::focus));
+ new_frame->DomWindow()->DispatchEvent(
+ *Event::Create(EventTypeNames::focus));
}
is_changing_focused_frame_ = false;
diff --git a/chromium/third_party/blink/renderer/core/page/page.cc b/chromium/third_party/blink/renderer/core/page/page.cc
index 0f42c3e762d..fc45eecaba6 100644
--- a/chromium/third_party/blink/renderer/core/page/page.cc
+++ b/chromium/third_party/blink/renderer/core/page/page.cc
@@ -39,6 +39,7 @@
#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/link_highlights.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.h"
@@ -64,18 +65,19 @@
#include "third_party/blink/renderer/core/page/scrolling/overscroll_controller.h"
#include "third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h"
#include "third_party/blink/renderer/core/page/scrolling/top_document_root_scroller_controller.h"
-#include "third_party/blink/renderer/core/page/validation_message_client.h"
+#include "third_party/blink/renderer/core/page/validation_message_client_impl.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/scroll/scrollbar_theme.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme_overlay.h"
+#include "third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.h"
#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/loader/fetch/resource_fetcher.h"
#include "third_party/blink/renderer/platform/plugins/plugin_data.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay.h"
-#include "third_party/blink/renderer/platform/scroll/smooth_scroll_sequencer.h"
namespace blink {
@@ -122,11 +124,16 @@ float DeviceScaleFactorDeprecated(LocalFrame* frame) {
return page->DeviceScaleFactorDeprecated();
}
-Page* Page::CreateOrdinary(PageClients& page_clients, Page* opener) {
- Page* page = Create(page_clients);
+Page* Page::Create(PageClients& page_clients) {
+ Page* page = new Page(page_clients);
page->SetPageScheduler(
Platform::Current()->CurrentThread()->Scheduler()->CreatePageScheduler(
page));
+ return page;
+}
+
+Page* Page::CreateOrdinary(PageClients& page_clients, Page* opener) {
+ Page* page = Create(page_clients);
if (opener) {
// Before: ... -> opener -> next -> ...
@@ -154,7 +161,7 @@ Page::Page(PageClients& page_clients)
drag_controller_(DragController::Create(this)),
focus_controller_(FocusController::Create(this)),
context_menu_controller_(ContextMenuController::Create(this)),
- page_scale_constraints_set_(PageScaleConstraintsSet::Create()),
+ page_scale_constraints_set_(PageScaleConstraintsSet::Create(this)),
pointer_lock_controller_(PointerLockController::Create(this)),
browser_controls_(BrowserControls::Create(*this)),
console_message_storage_(new ConsoleMessageStorage()),
@@ -165,6 +172,8 @@ Page::Page(PageClients& page_clients)
OverscrollController::Create(GetVisualViewport(), GetChromeClient())),
link_highlights_(LinkHighlights::Create(*this)),
plugin_data_(nullptr),
+ // TODO(pdr): Initialize |validation_message_client_| lazily.
+ validation_message_client_(ValidationMessageClientImpl::Create(*this)),
opened_by_dom_(false),
tab_key_cycles_through_elements_(true),
paused_(false),
@@ -217,13 +226,6 @@ PageScaleConstraintsSet& Page::GetPageScaleConstraintsSet() {
return *page_scale_constraints_set_;
}
-SmoothScrollSequencer* Page::GetSmoothScrollSequencer() {
- if (!smooth_scroll_sequencer_)
- smooth_scroll_sequencer_ = new SmoothScrollSequencer();
-
- return smooth_scroll_sequencer_.Get();
-}
-
const PageScaleConstraintsSet& Page::GetPageScaleConstraintsSet() const {
return *page_scale_constraints_set_;
}
@@ -358,7 +360,8 @@ static void RestoreSVGImageAnimations() {
}
}
-void Page::SetValidationMessageClient(ValidationMessageClient* client) {
+void Page::SetValidationMessageClientForTesting(
+ ValidationMessageClient* client) {
validation_message_client_ = client;
}
@@ -698,6 +701,7 @@ void Page::DidCommitLoad(LocalFrame* frame) {
GetVisualViewport().SetScrollOffset(ScrollOffset(), kProgrammaticScroll);
hosts_using_features_.UpdateMeasurementsAndClear();
}
+ GetLinkHighlights().ResetForPageNavigation();
}
void Page::AcceptLanguagesChanged() {
@@ -723,9 +727,9 @@ void Page::Trace(blink::Visitor* visitor) {
visitor->Trace(drag_controller_);
visitor->Trace(focus_controller_);
visitor->Trace(context_menu_controller_);
+ visitor->Trace(page_scale_constraints_set_);
visitor->Trace(pointer_lock_controller_);
visitor->Trace(scrolling_coordinator_);
- visitor->Trace(smooth_scroll_sequencer_);
visitor->Trace(browser_controls_);
visitor->Trace(console_message_storage_);
visitor->Trace(global_root_scroller_controller_);
@@ -840,20 +844,6 @@ bool Page::RequestBeginMainFrameNotExpected(bool new_state) {
return false;
}
-ukm::UkmRecorder* Page::GetUkmRecorder() {
- Frame* frame = MainFrame();
- if (!frame->IsLocalFrame())
- return nullptr;
- return ToLocalFrame(frame)->GetDocument()->UkmRecorder();
-}
-
-int64_t Page::GetUkmSourceId() {
- Frame* frame = MainFrame();
- if (!frame->IsLocalFrame())
- return -1;
- return ToLocalFrame(frame)->GetDocument()->UkmSourceID();
-}
-
void Page::AddAutoplayFlags(int32_t value) {
autoplay_flags_ |= value;
}
@@ -866,6 +856,59 @@ int32_t Page::AutoplayFlags() const {
return autoplay_flags_;
}
+namespace {
+
+class ColorOverlay final : public PageOverlay::Delegate {
+ public:
+ explicit ColorOverlay(SkColor color) : color_(color) {}
+
+ private:
+ void PaintPageOverlay(const PageOverlay& page_overlay,
+ GraphicsContext& graphics_context,
+ const IntSize& size) const override {
+ if (DrawingRecorder::UseCachedDrawingIfPossible(
+ graphics_context, page_overlay, DisplayItem::kPageOverlay))
+ return;
+ FloatRect rect(0, 0, size.Width(), size.Height());
+ DrawingRecorder recorder(graphics_context, page_overlay,
+ DisplayItem::kPageOverlay);
+ graphics_context.FillRect(rect, color_);
+ }
+
+ SkColor color_;
+};
+
+} // namespace
+
+void Page::SetPageOverlayColor(SkColor color) {
+ if (page_color_overlay_)
+ page_color_overlay_.reset();
+
+ if (color == Color::kTransparent)
+ return;
+
+ if (!MainFrame() || !MainFrame()->IsLocalFrame())
+ return;
+ auto* local_frame = ToLocalFrame(MainFrame());
+ page_color_overlay_ =
+ PageOverlay::Create(local_frame, std::make_unique<ColorOverlay>(color));
+
+ // Update compositing which will create graphics layers so the page color
+ // update below will be able to attach to the root graphics layer.
+ local_frame->View()->UpdateLifecycleToCompositingCleanPlusScrolling();
+ page_color_overlay_->Update();
+}
+
+void Page::UpdatePageColorOverlay() {
+ if (page_color_overlay_)
+ page_color_overlay_->Update();
+}
+
+void Page::PaintPageColorOverlay() {
+ if (page_color_overlay_)
+ page_color_overlay_->GetGraphicsLayer()->Paint(nullptr);
+}
+
Page::PageClients::PageClients() : chrome_client(nullptr) {}
Page::PageClients::~PageClients() = default;
diff --git a/chromium/third_party/blink/renderer/core/page/page.h b/chromium/third_party/blink/renderer/core/page/page.h
index 1be040296b6..8036e8ad5e0 100644
--- a/chromium/third_party/blink/renderer/core/page/page.h
+++ b/chromium/third_party/blink/renderer/core/page/page.h
@@ -33,6 +33,7 @@
#include "third_party/blink/renderer/core/frame/local_frame.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_overlay.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/page_visibility_state.h"
@@ -69,7 +70,6 @@ class PointerLockController;
class ScopedPagePauser;
class ScrollingCoordinator;
class ScrollbarTheme;
-class SmoothScrollSequencer;
class Settings;
class ConsoleMessageStorage;
class TopDocumentRootScrollerController;
@@ -103,9 +103,7 @@ class CORE_EXPORT Page final : public GarbageCollectedFinalized<Page>,
DISALLOW_COPY_AND_ASSIGN(PageClients);
};
- static Page* Create(PageClients& page_clients) {
- return new Page(page_clients);
- }
+ static Page* Create(PageClients& page_clients);
// An "ordinary" page is a fully-featured page owned by a web view.
static Page* CreateOrdinary(PageClients&, Page* opener);
@@ -183,12 +181,10 @@ class CORE_EXPORT Page final : public GarbageCollectedFinalized<Page>,
ValidationMessageClient& GetValidationMessageClient() const {
return *validation_message_client_;
}
- void SetValidationMessageClient(ValidationMessageClient*);
+ void SetValidationMessageClientForTesting(ValidationMessageClient*);
ScrollingCoordinator* GetScrollingCoordinator();
- SmoothScrollSequencer* GetSmoothScrollSequencer();
-
DOMRectList* NonFastScrollableRectsForTesting(const LocalFrame*);
Settings& GetSettings() const { return *settings_; }
@@ -312,14 +308,18 @@ class CORE_EXPORT Page final : public GarbageCollectedFinalized<Page>,
void ReportIntervention(const String& message) override;
bool RequestBeginMainFrameNotExpected(bool new_state) override;
void SetLifecycleState(PageLifecycleState) override;
- ukm::UkmRecorder* GetUkmRecorder() override;
- int64_t GetUkmSourceId() override;
void AddAutoplayFlags(int32_t flags);
void ClearAutoplayFlags();
int32_t AutoplayFlags() const;
+ void SetPageOverlayColor(SkColor);
+
+ void UpdatePageColorOverlay();
+
+ void PaintPageColorOverlay();
+
private:
friend class ScopedPagePauser;
@@ -356,10 +356,9 @@ class CORE_EXPORT Page final : public GarbageCollectedFinalized<Page>,
const Member<DragController> drag_controller_;
const Member<FocusController> focus_controller_;
const Member<ContextMenuController> context_menu_controller_;
- const std::unique_ptr<PageScaleConstraintsSet> page_scale_constraints_set_;
+ const Member<PageScaleConstraintsSet> page_scale_constraints_set_;
const Member<PointerLockController> pointer_lock_controller_;
Member<ScrollingCoordinator> scrolling_coordinator_;
- Member<SmoothScrollSequencer> smooth_scroll_sequencer_;
const Member<BrowserControls> browser_controls_;
const Member<ConsoleMessageStorage> console_message_storage_;
const Member<TopDocumentRootScrollerController>
@@ -372,6 +371,8 @@ class CORE_EXPORT Page final : public GarbageCollectedFinalized<Page>,
Member<ValidationMessageClient> validation_message_client_;
+ std::unique_ptr<PageOverlay> page_color_overlay_;
+
Deprecation deprecation_;
HostsUsingFeatures hosts_using_features_;
WebWindowFeatures window_features_;
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 8d5ad84758a..19099bd2b50 100644
--- a/chromium/third_party/blink/renderer/core/page/page_animator.cc
+++ b/chromium/third_party/blink/renderer/core/page/page_animator.cc
@@ -10,6 +10,7 @@
#include "third_party/blink/renderer/core/frame/local_frame_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/page/validation_message_client.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
#include "third_party/blink/renderer/core/svg/svg_document_extensions.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
@@ -80,6 +81,8 @@ void PageAnimator::ServiceScriptedAnimations(
document->Lifecycle());
document->ServiceScriptedAnimations(monotonic_animation_start_time);
}
+
+ page_->GetValidationMessageClient().LayoutOverlay();
}
void PageAnimator::SetSuppressFrameRequestsWorkaroundFor704763Only(
@@ -114,4 +117,11 @@ void PageAnimator::UpdateAllLifecyclePhasesExceptPaint(LocalFrame& root_frame) {
view->UpdateAllLifecyclePhasesExceptPaint();
}
+void PageAnimator::UpdateLifecycleToLayoutClean(LocalFrame& root_frame) {
+ LocalFrameView* view = root_frame.View();
+ base::AutoReset<bool> servicing(&updating_layout_and_style_for_painting_,
+ true);
+ view->UpdateLifecycleToLayoutClean();
+}
+
} // 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 5d3531c2f3e..3ee99c449a2 100644
--- a/chromium/third_party/blink/renderer/core/page/page_animator.h
+++ b/chromium/third_party/blink/renderer/core/page/page_animator.h
@@ -33,6 +33,7 @@ class CORE_EXPORT PageAnimator final : public GarbageCollected<PageAnimator> {
// See documents of methods with the same names in LocalFrameView class.
void UpdateAllLifecyclePhases(LocalFrame& root_frame);
void UpdateAllLifecyclePhasesExceptPaint(LocalFrame& root_frame);
+ void UpdateLifecycleToLayoutClean(LocalFrame& root_frame);
AnimationClock& Clock() { return animation_clock_; }
private:
diff --git a/chromium/third_party/blink/renderer/core/page/page_overlay.cc b/chromium/third_party/blink/renderer/core/page/page_overlay.cc
index d7b281fcd5e..5891941425f 100644
--- a/chromium/third_party/blink/renderer/core/page/page_overlay.cc
+++ b/chromium/third_party/blink/renderer/core/page/page_overlay.cc
@@ -47,14 +47,14 @@
namespace blink {
std::unique_ptr<PageOverlay> PageOverlay::Create(
- WebLocalFrameImpl* frame_impl,
+ LocalFrame* local_frame,
std::unique_ptr<PageOverlay::Delegate> delegate) {
- return base::WrapUnique(new PageOverlay(frame_impl, std::move(delegate)));
+ return base::WrapUnique(new PageOverlay(local_frame, std::move(delegate)));
}
-PageOverlay::PageOverlay(WebLocalFrameImpl* frame_impl,
+PageOverlay::PageOverlay(LocalFrame* local_frame,
std::unique_ptr<PageOverlay::Delegate> delegate)
- : frame_impl_(frame_impl), delegate_(std::move(delegate)) {}
+ : frame_(local_frame), delegate_(std::move(delegate)) {}
PageOverlay::~PageOverlay() {
if (!layer_)
@@ -64,18 +64,19 @@ PageOverlay::~PageOverlay() {
}
void PageOverlay::Update() {
- if (!frame_impl_->LocalRootFrameWidget()->IsAcceleratedCompositingActive())
+ if (!frame_)
return;
- LocalFrame* frame = frame_impl_->GetFrame();
- if (!frame)
+ auto* local_root_frame_widget =
+ WebLocalFrameImpl::FromFrame(frame_)->LocalRootFrameWidget();
+ if (!local_root_frame_widget->IsAcceleratedCompositingActive())
return;
if (!layer_) {
GraphicsLayer* parent_layer =
- frame->IsMainFrame()
- ? frame->GetPage()->GetVisualViewport().ContainerLayer()
- : frame_impl_->LocalRootFrameWidget()->RootGraphicsLayer();
+ frame_->IsMainFrame()
+ ? frame_->GetPage()->GetVisualViewport().ContainerLayer()
+ : local_root_frame_widget->RootGraphicsLayer();
if (!parent_layer)
return;
@@ -93,7 +94,7 @@ void PageOverlay::Update() {
IntPoint());
}
- IntSize size = frame->GetPage()->GetVisualViewport().Size();
+ IntSize size = frame_->GetPage()->GetVisualViewport().Size();
if (size != layer_->Size())
layer_->SetSize(size);
@@ -120,7 +121,7 @@ void PageOverlay::PaintContents(const GraphicsLayer* graphics_layer,
}
String PageOverlay::DebugName(const GraphicsLayer*) const {
- return "WebViewImpl Page Overlay Content Layer";
+ return "Page Overlay Content Layer";
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/page/page_overlay.h b/chromium/third_party/blink/renderer/core/page/page_overlay.h
index 96dc2bf7edf..814caa99969 100644
--- a/chromium/third_party/blink/renderer/core/page/page_overlay.h
+++ b/chromium/third_party/blink/renderer/core/page/page_overlay.h
@@ -39,7 +39,7 @@
namespace blink {
class GraphicsContext;
-class WebLocalFrameImpl;
+class LocalFrame;
// Manages a layer that is overlaid on a WebLocalFrame's content.
class CORE_EXPORT PageOverlay : public GraphicsLayerClient,
@@ -56,7 +56,7 @@ class CORE_EXPORT PageOverlay : public GraphicsLayerClient,
};
static std::unique_ptr<PageOverlay> Create(
- WebLocalFrameImpl*,
+ LocalFrame*,
std::unique_ptr<PageOverlay::Delegate>);
~PageOverlay() override;
@@ -80,9 +80,9 @@ class CORE_EXPORT PageOverlay : public GraphicsLayerClient,
String DebugName(const GraphicsLayer*) const override;
private:
- PageOverlay(WebLocalFrameImpl*, std::unique_ptr<PageOverlay::Delegate>);
+ PageOverlay(LocalFrame*, std::unique_ptr<PageOverlay::Delegate>);
- Persistent<WebLocalFrameImpl> frame_impl_;
+ Persistent<LocalFrame> frame_;
std::unique_ptr<PageOverlay::Delegate> delegate_;
std::unique_ptr<GraphicsLayer> layer_;
};
diff --git a/chromium/third_party/blink/renderer/core/page/page_overlay_test.cc b/chromium/third_party/blink/renderer/core/page/page_overlay_test.cc
index c483078197f..3e06ccf329e 100644
--- a/chromium/third_party/blink/renderer/core/page/page_overlay_test.cc
+++ b/chromium/third_party/blink/renderer/core/page/page_overlay_test.cc
@@ -88,7 +88,7 @@ class PageOverlayTest : public testing::Test {
std::unique_ptr<PageOverlay> CreateSolidYellowOverlay() {
return PageOverlay::Create(
- GetWebView()->MainFrameImpl(),
+ GetWebView()->MainFrameImpl()->GetFrame(),
std::make_unique<SolidColorOverlay>(SK_ColorYELLOW));
}
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 9a7c5ec8931..f162ac982d6 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
@@ -61,7 +61,9 @@ void PageWidgetDelegate::UpdateLifecycle(
Page& page,
LocalFrame& root,
WebWidget::LifecycleUpdate requested_update) {
- if (requested_update == WebWidget::LifecycleUpdate::kPrePaint) {
+ if (requested_update == WebWidget::LifecycleUpdate::kLayout) {
+ page.Animator().UpdateLifecycleToLayoutClean(root);
+ } else if (requested_update == WebWidget::LifecycleUpdate::kPrePaint) {
page.Animator().UpdateAllLifecyclePhasesExceptPaint(root);
} else {
page.Animator().UpdateAllLifecyclePhases(root);
@@ -137,6 +139,9 @@ WebInputEventResult PageWidgetDelegate::HandleInputEvent(
// TODO(crbug.com/808089): report across OOPIFs.
if (interactive_detector)
interactive_detector->HandleForInputDelay(event);
+
+ if (LocalFrameView* view = document->View())
+ view->GetJankTracker().NotifyInput(event);
}
if (event.GetModifiers() & WebInputEvent::kIsTouchAccessibility &&
@@ -223,6 +228,7 @@ WebInputEventResult PageWidgetDelegate::HandleInputEvent(
case WebInputEvent::kPointerDown:
case WebInputEvent::kPointerUp:
case WebInputEvent::kPointerMove:
+ case WebInputEvent::kPointerRawMove:
case WebInputEvent::kPointerCancel:
case WebInputEvent::kPointerCausedUaAction:
if (!root || !root->View())
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 a4551c43128..bfeb63e054a 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
@@ -166,7 +166,7 @@ void PointerLockController::EnqueueEvent(const AtomicString& type,
void PointerLockController::EnqueueEvent(const AtomicString& type,
Document* document) {
if (document && document->domWindow()) {
- document->domWindow()->EnqueueDocumentEvent(Event::Create(type),
+ document->domWindow()->EnqueueDocumentEvent(*Event::Create(type),
TaskType::kMiscPlatformAPI);
}
}
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 27d5942d5e2..0dc5f195d90 100644
--- a/chromium/third_party/blink/renderer/core/page/print_context.cc
+++ b/chromium/third_party/blink/renderer/core/page/print_context.cc
@@ -148,11 +148,6 @@ void PrintContext::BeginPrintMode(float width, float height) {
// without going back to screen mode.
is_printing_ = true;
- if (!use_printing_layout_) {
- frame_->StartPrintingWithoutPrintingLayout();
- return;
- }
-
FloatSize original_page_size = FloatSize(width, height);
FloatSize min_layout_size = frame_->ResizePageRectsKeepingRatio(
original_page_size, FloatSize(width * kPrintingMinimumShrinkFactor,
@@ -326,6 +321,10 @@ void PrintContext::Trace(blink::Visitor* visitor) {
visitor->Trace(linked_destinations_);
}
+bool PrintContext::use_printing_layout() const {
+ return use_printing_layout_;
+}
+
ScopedPrintContext::ScopedPrintContext(LocalFrame* frame)
: context_(new PrintContext(frame, /*use_printing_layout=*/true)) {}
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 b54c8164112..7a5f9206888 100644
--- a/chromium/third_party/blink/renderer/core/page/print_context.h
+++ b/chromium/third_party/blink/renderer/core/page/print_context.h
@@ -106,6 +106,8 @@ class CORE_EXPORT PrintContext
virtual void Trace(blink::Visitor*);
+ bool use_printing_layout() const;
+
protected:
friend class PrintContextTest;
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 0477c0deb73..02bb3229c08 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
@@ -14,12 +14,12 @@
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/core/paint/paint_layer_painter.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_record_builder.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h"
#include "third_party/blink/renderer/platform/testing/paint_test_configurations.h"
#include "third_party/blink/renderer/platform/wtf/text/text_stream.h"
#include "third_party/skia/include/core/SkCanvas.h"
@@ -424,7 +424,7 @@ TEST_P(PrintContextFrameTest, DISABLED_SubframePrintPageLayout) {
EXPECT_EQ(child->OffsetWidth(), 800);
EXPECT_EQ(target->OffsetWidth(), 800);
- GetDocument().GetFrame()->StartPrintingWithoutPrintingLayout();
+ GetDocument().GetFrame()->StartPrinting();
EXPECT_EQ(parent->OffsetWidth(), 800);
EXPECT_EQ(child->OffsetWidth(), 800);
EXPECT_EQ(target->OffsetWidth(), 800);
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 a2ea4f5db9b..5228b1fda52 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
@@ -4,10 +4,13 @@
#include "third_party/blink/renderer/core/page/scrolling/overscroll_controller.h"
+#include "cc/input/overscroll_behavior.h"
+#include "third_party/blink/renderer/core/computed_style_base_constants.h"
#include "third_party/blink/renderer/core/frame/visual_viewport.h"
#include "third_party/blink/renderer/core/page/chrome_client.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/graphics/paint/scroll_paint_property_node.h"
#include "third_party/blink/renderer/platform/scroll/scroll_types.h"
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 ce48fb1430c..29446c84265 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
@@ -21,9 +21,9 @@
#include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.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/scrollable_area.h"
#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
-#include "third_party/blink/renderer/platform/scroll/scrollable_area.h"
namespace blink {
@@ -31,7 +31,7 @@ class RootFrameViewport;
namespace {
-bool FillsViewport(const Element& element, bool check_location) {
+bool FillsViewport(const Element& element) {
if (!element.GetLayoutObject())
return false;
@@ -43,28 +43,24 @@ bool FillsViewport(const Element& element, bool check_location) {
return false;
FloatQuad quad = layout_object->LocalToAbsoluteQuad(
- FloatRect(ToLayoutBox(layout_object)->PaddingBoxRect()));
+ FloatRect(ToLayoutBox(layout_object)->PhysicalPaddingBoxRect()));
if (!quad.IsRectilinear())
return false;
- LayoutRect bounding_box(quad.BoundingBox());
+ IntRect bounding_box = EnclosingIntRect(quad.BoundingBox());
- LayoutSize icb_size =
- LayoutSize(top_document.GetLayoutView()->GetLayoutSize());
+ IntSize icb_size = top_document.GetLayoutView()->GetLayoutSize();
float zoom = top_document.GetFrame()->PageZoomFactor();
- LayoutSize controls_hidden_size = LayoutSize(
+ IntSize controls_hidden_size = ExpandedIntSize(
top_document.View()->ViewportSizeForViewportUnits().ScaledBy(zoom));
if (bounding_box.Size() != icb_size &&
bounding_box.Size() != controls_hidden_size)
return false;
- if (!check_location)
- return true;
-
- return bounding_box.Location() == LayoutPoint::Zero();
+ return bounding_box.Location() == IntPoint::Zero();
}
// If the element is an iframe this grabs the ScrollableArea for the owned
@@ -92,6 +88,21 @@ PaintLayerScrollableArea* GetScrollableArea(const Element& element) {
return ToLayoutBox(element.GetLayoutObject())->GetScrollableArea();
}
+bool ScrollsVerticalOverflow(LayoutView& layout_view) {
+ DCHECK(layout_view.GetScrollableArea());
+
+ if (layout_view.Size().IsZero() ||
+ !layout_view.GetScrollableArea()->HasVerticalOverflow() ||
+ !layout_view.ScrollsOverflowY())
+ return false;
+
+ ScrollbarMode h_mode;
+ ScrollbarMode v_mode;
+ layout_view.CalculateScrollbarModes(h_mode, v_mode);
+
+ return v_mode != kScrollbarAlwaysOff;
+}
+
} // namespace
// static
@@ -215,6 +226,11 @@ void RootScrollerController::RecomputeEffectiveRootScroller() {
}
}
}
+ if (auto* object = old_effective_root_scroller->GetLayoutObject())
+ object->SetIsEffectiveRootScroller(false);
+
+ if (auto* object = new_effective_root_scroller->GetLayoutObject())
+ object->SetIsEffectiveRootScroller(true);
}
ApplyRootScrollerProperties(*old_effective_root_scroller);
@@ -257,7 +273,7 @@ bool RootScrollerController::IsValidRootScroller(const Element& element) const {
return false;
}
- if (!FillsViewport(element, true))
+ if (!FillsViewport(element))
return false;
return true;
@@ -369,9 +385,12 @@ void RootScrollerController::ProcessImplicitCandidates() {
if (!document_->GetLayoutView())
return;
- // If the document has scrollable content, that's a good sign we shouldn't
- // implicitly promote anything.
- if (document_->GetLayoutView()->GetScrollableArea()->ScrollsOverflow())
+ if (!document_->GetFrame()->IsMainFrame())
+ return;
+
+ // If the main document has vertical scrolling, that's a good sign we
+ // shouldn't implicitly promote anything.
+ if (ScrollsVerticalOverflow(*document_->GetLayoutView()))
return;
Element* highest_z_element = nullptr;
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 a646b9f5b6e..cdffaa1200b 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
@@ -66,7 +66,7 @@ class CORE_EXPORT RootScrollerController
// This class needs to be informed when the FrameView of its Document changes
// size. This may occur without a layout (e.g. URL bar hiding) so we can't
- // rely on DidUpdateLayout.
+ // rely on DidUpdateMainFrameLayout.
void DidResizeFrameView();
// Called when an iframe in this document has an updated FrameView (e.g.
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 8af7d56aa16..0b7f57bd274 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
@@ -16,6 +16,7 @@
#include "third_party/blink/renderer/core/frame/browser_controls.h"
#include "third_party/blink/renderer/core/frame/dom_visual_viewport.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"
#include "third_party/blink/renderer/core/frame/root_frame_viewport.h"
#include "third_party/blink/renderer/core/frame/visual_viewport.h"
@@ -2335,6 +2336,134 @@ TEST_F(ImplicitRootScrollerSimTest, PromotionChangesLayoutSize) {
<< "Once loaded, the iframe should be promoted.";
}
+// Test that we don't promote any elements implicitly if the main document have
+// vertical overflow.
+TEST_F(ImplicitRootScrollerSimTest, OverflowInMainDocumentRestrictsImplicit) {
+ WebView().ResizeWithBrowserControls(IntSize(800, 600), 50, 0, true);
+ 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;
+ }
+ div {
+ position: absolute;
+ left: 0;
+ top: 0;
+ height: 150%;
+ width: 150%;
+ }
+ </style>
+ <iframe id="container" src="child.html">
+ </iframe>
+ <div id="spacer"></div>
+ )HTML");
+ child_request.Complete(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ body {
+ height: 1000px;
+ }
+ </style>
+ )HTML");
+
+ Compositor().BeginFrame();
+ EXPECT_EQ(GetDocument(),
+ GetDocument().GetRootScrollerController().EffectiveRootScroller())
+ << "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);
+ Compositor().BeginFrame();
+
+ EXPECT_EQ(GetDocument().getElementById("container"),
+ GetDocument().GetRootScrollerController().EffectiveRootScroller())
+ << "Once vertical overflow is removed, the iframe should be promoted.";
+}
+
+TEST_F(ImplicitRootScrollerSimTest, AppliedAtFractionalZoom) {
+ // Matches Pixel 2XL screen size of 412x671 at 3.5 DevicePixelRatio.
+ WebView().SetZoomFactorForDeviceScaleFactor(3.5f);
+ WebView().ResizeWithBrowserControls(IntSize(1442, 2349), 196, 0, true);
+
+ 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 {
+ border: 0;
+ display: block;
+ }
+ </style>
+ <iframe id="container" src="child.html">
+ </iframe>
+ <script>
+ // innerHeight is non-fractional so pages don't have a great way to
+ // set the size to "exctly" 100%. Ensure we still promote in this
+ // common pattern.
+ function resize_handler() {
+ document.getElementById("container").style.height =
+ window.innerHeight + "px";
+ document.getElementById("container").style.width =
+ window.innerWidth + "px";
+ }
+
+ resize_handler();
+ window.addEventHandler('resize', resize_handler);
+ </script>
+ )HTML");
+
+ child_request.Complete(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ body {
+ height: 1000px;
+ }
+ </style>
+ )HTML");
+
+ Compositor().BeginFrame();
+ PaintLayerScrollableArea* area = GetDocument().View()->LayoutViewport();
+ ASSERT_FALSE(area->HasVerticalOverflow());
+
+ EXPECT_EQ(GetDocument().getElementById("container"),
+ GetDocument().GetRootScrollerController().EffectiveRootScroller())
+ << "<iframe> should be promoted when URL bar is hidden";
+
+ WebView().ResizeWithBrowserControls(IntSize(1442, 2545), 196, 0, false);
+ Compositor().BeginFrame();
+
+ EXPECT_EQ(GetDocument().getElementById("container"),
+ GetDocument().GetRootScrollerController().EffectiveRootScroller())
+ << "<iframe> should remain promoted when URL bar is hidden";
+}
+
class RootScrollerHitTest : public RootScrollerTest {
public:
void CheckHitTestAtBottomOfScreen() {
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/root_scroller_util.cc b/chromium/third_party/blink/renderer/core/page/scrolling/root_scroller_util.cc
index 87b8a07185f..9b77a62aeae 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/root_scroller_util.cc
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/root_scroller_util.cc
@@ -66,14 +66,6 @@ PaintLayer* PaintLayerForRootScroller(const Node* node) {
return box->Layer();
}
-bool IsEffective(const LayoutBox& box) {
- if (!box.GetNode())
- return false;
-
- return box.GetNode() ==
- &box.GetDocument().GetRootScrollerController().EffectiveRootScroller();
-}
-
bool IsGlobal(const LayoutBox& box) {
if (!box.GetNode() || !box.GetNode()->GetDocument().GetPage())
return false;
@@ -84,13 +76,6 @@ bool IsGlobal(const LayoutBox& box) {
.GlobalRootScroller();
}
-bool IsEffective(const PaintLayer& layer) {
- if (!layer.GetLayoutBox())
- return false;
-
- return IsEffective(*layer.GetLayoutBox());
-}
-
bool IsGlobal(const PaintLayer& layer) {
if (!layer.GetLayoutBox())
return false;
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/root_scroller_util.h b/chromium/third_party/blink/renderer/core/page/scrolling/root_scroller_util.h
index b6697867349..e614ed73f93 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/root_scroller_util.h
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/root_scroller_util.h
@@ -25,12 +25,6 @@ ScrollableArea* ScrollableAreaForRootScroller(const Node*);
// rather than <html>'s since scrolling is handled by LayoutView.
PaintLayer* PaintLayerForRootScroller(const Node*);
-// Return true if the given object is the effective root scroller in its
-// Document. See |effective root scroller| in README.md. Note: a root scroller
-// always establishes a PaintLayer.
-bool IsEffective(const LayoutBox&);
-bool IsEffective(const PaintLayer&);
-
bool IsGlobal(const LayoutBox&);
bool IsGlobal(const PaintLayer&);
bool IsGlobal(const Element*);
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 7c7b6e706c1..4da47eb4606 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
@@ -7,6 +7,7 @@
#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/core/dom/element.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.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"
@@ -488,6 +489,7 @@ TEST_F(ScrollIntoViewTest, FindDoesNotScrollOverflowHidden) {
ASSERT_EQ(container->scrollTop(), 0);
const int kFindIdentifier = 12345;
WebFindOptions options;
+ options.run_synchronously_for_testing = true;
MainFrame().Find(kFindIdentifier, WebString::FromUTF8("hello"), options,
false);
ASSERT_EQ(container->scrollTop(), 0);
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 3fdcde684b0..e9f67a28cc3 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
@@ -10,9 +10,9 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/element.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"
-#include "third_party/blink/renderer/platform/scroll/scroll_state_data.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
namespace blink {
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 c4aa4af1285..d8f60690d7a 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
@@ -39,6 +39,7 @@
#include "third_party/blink/renderer/core/dom/node.h"
#include "third_party/blink/renderer/core/exported/web_plugin_container_impl.h"
#include "third_party/blink/renderer/core/frame/event_handler_registry.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/page_scale_constraints_set.h"
@@ -64,15 +65,15 @@
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/transforms/transform_state.h"
#if defined(OS_MACOSX)
-#include "third_party/blink/renderer/platform/mac/scroll_animator_mac.h"
+#include "third_party/blink/renderer/core/scroll/scroll_animator_mac.h"
#endif
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_layer_tree_view.h"
+#include "third_party/blink/renderer/core/scroll/scroll_animator_base.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_layer_delegate.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
#include "third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h"
#include "third_party/blink/renderer/platform/scroll/main_thread_scrolling_reason.h"
-#include "third_party/blink/renderer/platform/scroll/scroll_animator_base.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_layer_delegate.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
using blink::WebRect;
@@ -278,8 +279,10 @@ static void UpdateLayerTouchActionRects(GraphicsLayer& layer) {
rect)) {
continue;
}
+ LayoutRect layout_rect = LayoutRect(rect.Rect());
+ layout_rect.MoveBy(-layer.GetOffsetFromTransformNode());
touch_action_rects_in_layer_space.emplace_back(TouchActionRect(
- LayoutRect(rect.Rect()), touch_action_rect.whitelisted_touch_action));
+ layout_rect, touch_action_rect.whitelisted_touch_action));
}
}
layer.CcLayer()->SetTouchActionRegion(
@@ -527,10 +530,10 @@ bool ScrollingCoordinator::UpdateCompositedScrollOffset(
return true;
}
-bool ScrollingCoordinator::ScrollableAreaScrollLayerDidChange(
+void ScrollingCoordinator::ScrollableAreaScrollLayerDidChange(
ScrollableArea* scrollable_area) {
if (!page_ || !page_->MainFrame())
- return false;
+ return;
UpdateUserInputScrollable(scrollable_area);
@@ -613,7 +616,7 @@ bool ScrollingCoordinator::ScrollableAreaScrollLayerDidChange(
}
scrollable_area->LayerForScrollingDidChange(timeline);
- return !!cc_layer;
+ return;
}
using GraphicsLayerHitTestRects =
@@ -841,7 +844,7 @@ void ScrollingCoordinator::Reset(LocalFrame* frame) {
// (although that's not yet implemented - crbug.com/261307).
void ScrollingCoordinator::SetTouchEventTargetRects(
LocalFrame* frame,
- LayerHitTestRects& layer_rects) {
+ const LayerHitTestRects& layer_rects) {
TRACE_EVENT0("input", "ScrollingCoordinator::setTouchEventTargetRects");
DCHECK(!RuntimeEnabledFeatures::PaintTouchActionRectsEnabled());
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 68c91535359..f5af3769226 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
@@ -139,7 +139,7 @@ class CORE_EXPORT ScrollingCoordinator final
// blink uses a separate layer. To ensure the compositor scroll layer has the
// updated scroll container bounds, this needs to be called when the scrolling
// contents layer is resized.
- bool ScrollableAreaScrollLayerDidChange(ScrollableArea*);
+ void ScrollableAreaScrollLayerDidChange(ScrollableArea*);
void ScrollableAreaScrollbarLayerDidChange(ScrollableArea*,
ScrollbarOrientation);
void UpdateLayerPositionConstraint(PaintLayer*);
@@ -192,7 +192,7 @@ class CORE_EXPORT ScrollingCoordinator final
void SetShouldHandleScrollGestureOnMainThreadRegion(const Region&,
LocalFrameView*);
- void SetTouchEventTargetRects(LocalFrame*, LayerHitTestRects&);
+ void SetTouchEventTargetRects(LocalFrame*, const LayerHitTestRects&);
void ComputeTouchEventTargetRects(LocalFrame*, LayerHitTestRects&);
void AddScrollbarLayerGroup(ScrollableArea*,
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_coordinator_test.cc
index 1e48ae9bb27..e4ec06df25e 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_test.cc
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_test.cc
@@ -39,6 +39,7 @@
#include "third_party/blink/renderer/core/css/style_sheet_list.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"
#include "third_party/blink/renderer/core/frame/visual_viewport.h"
#include "third_party/blink/renderer/core/frame/web_frame_widget_base.h"
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 ec73eb3807d..939f7eb4505 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
@@ -127,7 +127,7 @@ void SnapCoordinator::UpdateSnapContainerData(const LayoutBox& snap_container) {
// box. https://drafts.csswg.org/css-overflow-3/#scrollport. So we use the
// LayoutRect of the padding box here. The coordinate is relative to the
// container's border box.
- LayoutRect container_rect(snap_container.PaddingBoxRect());
+ LayoutRect container_rect(snap_container.PhysicalPaddingBoxRect());
const ComputedStyle* container_style = snap_container.Style();
LayoutRectOutsets container_padding(
@@ -281,6 +281,7 @@ void SnapCoordinator::PerformSnapping(const LayoutBox& snap_container,
void SnapCoordinator::SnapContainerDidChange(LayoutBox& snap_container,
ScrollSnapType scroll_snap_type) {
+ snap_container.SetNeedsPaintPropertyUpdate();
if (scroll_snap_type.is_none) {
snap_container_map_.erase(&snap_container);
snap_container.ClearSnapAreas();
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/sticky_position_scrolling_constraints.cc b/chromium/third_party/blink/renderer/core/page/scrolling/sticky_position_scrolling_constraints.cc
index 0aae3ee0748..45646988de0 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/sticky_position_scrolling_constraints.cc
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/sticky_position_scrolling_constraints.cc
@@ -8,11 +8,11 @@
namespace blink {
FloatSize StickyPositionScrollingConstraints::ComputeStickyOffset(
- const FloatRect& overflow_clip_rect,
+ const FloatRect& content_box_rect,
const StickyConstraintsMap& constraints_map) {
- FloatRect sticky_box_rect = scroll_container_relative_sticky_box_rect_;
+ FloatRect sticky_box_rect = scroll_container_relative_sticky_box_rect;
FloatRect containing_block_rect =
- scroll_container_relative_containing_block_rect_;
+ scroll_container_relative_containing_block_rect;
FloatSize ancestor_sticky_box_offset =
AncestorStickyBoxOffset(constraints_map);
FloatSize ancestor_containing_block_offset =
@@ -21,10 +21,10 @@ FloatSize StickyPositionScrollingConstraints::ComputeStickyOffset(
// Adjust the cached rect locations for any sticky ancestor elements. The
// sticky offset applied to those ancestors affects us as follows:
//
- // 1. |nearest_sticky_layer_shifting_sticky_box_| is a sticky layer between
+ // 1. |nearest_sticky_layer_shifting_sticky_box| is a sticky layer between
// ourselves and our containing block, e.g. a nested inline parent.
// It shifts only the sticky_box_rect and not the containing_block_rect.
- // 2. |nearest_sticky_layer_shifting_containing_block_| is a sticky layer
+ // 2. |nearest_sticky_layer_shifting_containing_block| is a sticky layer
// between our containing block (inclusive) and our scroll ancestor
// (exclusive). As such, it shifts both the sticky_box_rect and the
// containing_block_rect.
@@ -43,8 +43,8 @@ FloatSize StickyPositionScrollingConstraints::ComputeStickyOffset(
// As per the spec, 'left' overrides 'right' and 'top' overrides 'bottom'.
FloatRect box_rect = sticky_box_rect;
- if (HasAnchorEdge(kAnchorEdgeRight)) {
- float right_limit = overflow_clip_rect.MaxX() - right_offset_;
+ if (is_anchored_right) {
+ float right_limit = content_box_rect.MaxX() - right_offset;
float right_delta =
std::min<float>(0, right_limit - sticky_box_rect.MaxX());
float available_space =
@@ -55,8 +55,8 @@ FloatSize StickyPositionScrollingConstraints::ComputeStickyOffset(
box_rect.Move(right_delta, 0);
}
- if (HasAnchorEdge(kAnchorEdgeLeft)) {
- float left_limit = overflow_clip_rect.X() + left_offset_;
+ if (is_anchored_left) {
+ float left_limit = content_box_rect.X() + left_offset;
float left_delta = std::max<float>(0, left_limit - sticky_box_rect.X());
float available_space = std::max<float>(
0, containing_block_rect.MaxX() - sticky_box_rect.MaxX());
@@ -66,8 +66,8 @@ FloatSize StickyPositionScrollingConstraints::ComputeStickyOffset(
box_rect.Move(left_delta, 0);
}
- if (HasAnchorEdge(kAnchorEdgeBottom)) {
- float bottom_limit = overflow_clip_rect.MaxY() - bottom_offset_;
+ if (is_anchored_bottom) {
+ float bottom_limit = content_box_rect.MaxY() - bottom_offset;
float bottom_delta =
std::min<float>(0, bottom_limit - sticky_box_rect.MaxY());
float available_space =
@@ -78,8 +78,8 @@ FloatSize StickyPositionScrollingConstraints::ComputeStickyOffset(
box_rect.Move(0, bottom_delta);
}
- if (HasAnchorEdge(kAnchorEdgeTop)) {
- float top_limit = overflow_clip_rect.Y() + top_offset_;
+ if (is_anchored_top) {
+ float top_limit = content_box_rect.Y() + top_offset;
float top_delta = std::max<float>(0, top_limit - sticky_box_rect.Y());
float available_space = std::max<float>(
0, containing_block_rect.MaxY() - sticky_box_rect.MaxY());
@@ -93,44 +93,38 @@ FloatSize StickyPositionScrollingConstraints::ComputeStickyOffset(
// Now that we have computed our current sticky offset, update the cached
// accumulated sticky offsets.
- total_sticky_box_sticky_offset_ = ancestor_sticky_box_offset + sticky_offset;
- total_containing_block_sticky_offset_ = ancestor_sticky_box_offset +
- ancestor_containing_block_offset +
- sticky_offset;
+ total_sticky_box_sticky_offset = ancestor_sticky_box_offset + sticky_offset;
+ total_containing_block_sticky_offset = ancestor_sticky_box_offset +
+ ancestor_containing_block_offset +
+ sticky_offset;
return sticky_offset;
}
FloatSize StickyPositionScrollingConstraints::GetOffsetForStickyPosition(
const StickyConstraintsMap& constraints_map) const {
- FloatSize nearest_sticky_layer_shifting_sticky_box_constraints_offset;
- if (nearest_sticky_layer_shifting_sticky_box_) {
- nearest_sticky_layer_shifting_sticky_box_constraints_offset =
- constraints_map.at(nearest_sticky_layer_shifting_sticky_box_)
- .total_sticky_box_sticky_offset_;
- }
- return total_sticky_box_sticky_offset_ -
- nearest_sticky_layer_shifting_sticky_box_constraints_offset;
+ return total_sticky_box_sticky_offset -
+ AncestorStickyBoxOffset(constraints_map);
}
FloatSize StickyPositionScrollingConstraints::AncestorStickyBoxOffset(
- const StickyConstraintsMap& constraints_map) {
- if (!nearest_sticky_layer_shifting_sticky_box_)
+ const StickyConstraintsMap& constraints_map) const {
+ if (!nearest_sticky_layer_shifting_sticky_box)
return FloatSize();
- DCHECK(constraints_map.Contains(nearest_sticky_layer_shifting_sticky_box_));
- return constraints_map.at(nearest_sticky_layer_shifting_sticky_box_)
- .total_sticky_box_sticky_offset_;
+ DCHECK(constraints_map.Contains(nearest_sticky_layer_shifting_sticky_box));
+ return constraints_map.at(nearest_sticky_layer_shifting_sticky_box)
+ .total_sticky_box_sticky_offset;
}
FloatSize StickyPositionScrollingConstraints::AncestorContainingBlockOffset(
- const StickyConstraintsMap& constraints_map) {
- if (!nearest_sticky_layer_shifting_containing_block_) {
+ const StickyConstraintsMap& constraints_map) const {
+ if (!nearest_sticky_layer_shifting_containing_block) {
return FloatSize();
}
- DCHECK(constraints_map.Contains(
- nearest_sticky_layer_shifting_containing_block_));
- return constraints_map.at(nearest_sticky_layer_shifting_containing_block_)
- .total_containing_block_sticky_offset_;
+ DCHECK(
+ constraints_map.Contains(nearest_sticky_layer_shifting_containing_block));
+ return constraints_map.at(nearest_sticky_layer_shifting_containing_block)
+ .total_containing_block_sticky_offset;
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/sticky_position_scrolling_constraints.h b/chromium/third_party/blink/renderer/core/page/scrolling/sticky_position_scrolling_constraints.h
index 9712076d228..42a1494b574 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/sticky_position_scrolling_constraints.h
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/sticky_position_scrolling_constraints.h
@@ -12,7 +12,7 @@
namespace blink {
class PaintLayer;
-class StickyPositionScrollingConstraints;
+struct StickyPositionScrollingConstraints;
typedef WTF::HashMap<PaintLayer*, StickyPositionScrollingConstraints>
StickyConstraintsMap;
@@ -71,25 +71,13 @@ typedef WTF::HashMap<PaintLayer*, StickyPositionScrollingConstraints>
// already being shifted by its ancestor. To correctly handle such situations we
// apply more complicated logic which is explained in the implementation of
// |ComputeStickyOffset|.
-class StickyPositionScrollingConstraints final {
+struct StickyPositionScrollingConstraints final {
public:
- enum AnchorEdgeFlags {
- kAnchorEdgeLeft = 1 << 0,
- kAnchorEdgeRight = 1 << 1,
- kAnchorEdgeTop = 1 << 2,
- kAnchorEdgeBottom = 1 << 3
- };
- typedef unsigned AnchorEdges;
-
StickyPositionScrollingConstraints()
- : anchor_edges_(0),
- left_offset_(0),
- right_offset_(0),
- top_offset_(0),
- bottom_offset_(0),
- nearest_sticky_layer_shifting_sticky_box_(nullptr),
- nearest_sticky_layer_shifting_containing_block_(nullptr) {}
-
+ : is_anchored_left(false),
+ is_anchored_right(false),
+ is_anchored_top(false),
+ is_anchored_bottom(false) {}
StickyPositionScrollingConstraints(
const StickyPositionScrollingConstraints& other) = default;
@@ -97,7 +85,7 @@ class StickyPositionScrollingConstraints final {
//
// This method is non-const as we cache internal state for performance; see
// documentation in the implementation for details.
- FloatSize ComputeStickyOffset(const FloatRect& overflow_clip_rect,
+ FloatSize ComputeStickyOffset(const FloatRect& content_box_rect,
const StickyConstraintsMap&);
// Returns the last-computed offset of the sticky box from its original
@@ -108,87 +96,15 @@ class StickyPositionScrollingConstraints final {
// element. (Or after prepaint for SlimmingPaintV2).
FloatSize GetOffsetForStickyPosition(const StickyConstraintsMap&) const;
- bool HasAncestorStickyElement() const {
- return nearest_sticky_layer_shifting_sticky_box_ ||
- nearest_sticky_layer_shifting_containing_block_;
- }
-
- AnchorEdges GetAnchorEdges() const { return anchor_edges_; }
- bool HasAnchorEdge(AnchorEdgeFlags flag) const {
- return anchor_edges_ & flag;
- }
- void AddAnchorEdge(AnchorEdgeFlags edge_flag) { anchor_edges_ |= edge_flag; }
-
- float LeftOffset() const { return left_offset_; }
- float RightOffset() const { return right_offset_; }
- float TopOffset() const { return top_offset_; }
- float BottomOffset() const { return bottom_offset_; }
-
- void SetLeftOffset(float offset) { left_offset_ = offset; }
- void SetRightOffset(float offset) { right_offset_ = offset; }
- void SetTopOffset(float offset) { top_offset_ = offset; }
- void SetBottomOffset(float offset) { bottom_offset_ = offset; }
-
- void SetScrollContainerRelativeContainingBlockRect(const FloatRect& rect) {
- scroll_container_relative_containing_block_rect_ = rect;
- }
- const FloatRect& ScrollContainerRelativeContainingBlockRect() const {
- return scroll_container_relative_containing_block_rect_;
- }
-
- void SetScrollContainerRelativeStickyBoxRect(const FloatRect& rect) {
- scroll_container_relative_sticky_box_rect_ = rect;
- }
- const FloatRect& ScrollContainerRelativeStickyBoxRect() const {
- return scroll_container_relative_sticky_box_rect_;
- }
-
- void SetNearestStickyLayerShiftingStickyBox(PaintLayer* layer) {
- nearest_sticky_layer_shifting_sticky_box_ = layer;
- }
- PaintLayer* NearestStickyLayerShiftingStickyBox() const {
- return nearest_sticky_layer_shifting_sticky_box_;
- }
-
- void SetNearestStickyLayerShiftingContainingBlock(PaintLayer* layer) {
- nearest_sticky_layer_shifting_containing_block_ = layer;
- }
- PaintLayer* NearestStickyLayerShiftingContainingBlock() const {
- return nearest_sticky_layer_shifting_containing_block_;
- }
-
- bool operator==(const StickyPositionScrollingConstraints& other) const {
- return left_offset_ == other.left_offset_ &&
- right_offset_ == other.right_offset_ &&
- top_offset_ == other.top_offset_ &&
- bottom_offset_ == other.bottom_offset_ &&
- scroll_container_relative_containing_block_rect_ ==
- other.scroll_container_relative_containing_block_rect_ &&
- scroll_container_relative_sticky_box_rect_ ==
- other.scroll_container_relative_sticky_box_rect_ &&
- nearest_sticky_layer_shifting_sticky_box_ ==
- other.nearest_sticky_layer_shifting_sticky_box_ &&
- nearest_sticky_layer_shifting_containing_block_ ==
- other.nearest_sticky_layer_shifting_containing_block_ &&
- total_sticky_box_sticky_offset_ ==
- other.total_sticky_box_sticky_offset_ &&
- total_containing_block_sticky_offset_ ==
- other.total_containing_block_sticky_offset_;
- }
-
- bool operator!=(const StickyPositionScrollingConstraints& other) const {
- return !(*this == other);
- }
-
- private:
- FloatSize AncestorStickyBoxOffset(const StickyConstraintsMap&);
- FloatSize AncestorContainingBlockOffset(const StickyConstraintsMap&);
+ bool is_anchored_left : 1;
+ bool is_anchored_right : 1;
+ bool is_anchored_top : 1;
+ bool is_anchored_bottom : 1;
- AnchorEdges anchor_edges_;
- float left_offset_;
- float right_offset_;
- float top_offset_;
- float bottom_offset_;
+ float left_offset = 0.f;
+ float right_offset = 0.f;
+ float top_offset = 0.f;
+ float bottom_offset = 0.f;
// The containing block rect and sticky box rect are the basic components
// for calculating the sticky offset to apply after a scroll. Consider the
@@ -203,12 +119,12 @@ class StickyPositionScrollingConstraints final {
// The layout position of the containing block relative to the scroll
// container. When calculating the sticky offset it is used to ensure the
// sticky element stays bounded by its containing block.
- FloatRect scroll_container_relative_containing_block_rect_;
+ FloatRect scroll_container_relative_containing_block_rect;
// The layout position of the sticky element relative to the scroll container.
// When calculating the sticky offset it is used to determine how large the
// offset needs to be to satisfy the sticky constraints.
- FloatRect scroll_container_relative_sticky_box_rect_;
+ FloatRect scroll_container_relative_sticky_box_rect;
// In the case of nested sticky elements the layout position of the sticky
// element and its containing block are not accurate (as they are affected by
@@ -219,9 +135,10 @@ class StickyPositionScrollingConstraints final {
//
// See the implementation of |ComputeStickyOffset| for documentation on how
// these ancestors are used to correct the offset calculation.
- PaintLayer* nearest_sticky_layer_shifting_sticky_box_;
- PaintLayer* nearest_sticky_layer_shifting_containing_block_;
+ PaintLayer* nearest_sticky_layer_shifting_sticky_box = nullptr;
+ PaintLayer* nearest_sticky_layer_shifting_containing_block = nullptr;
+ private:
// For performance we cache our accumulated sticky offset to allow descendant
// sticky elements to offset their constraint rects. Because we can either
// affect a descendant element's sticky box constraint rect or containing
@@ -229,8 +146,8 @@ class StickyPositionScrollingConstraints final {
// The sticky box offset accumulates the chain of sticky elements that are
// between this sticky element and its containing block. Any descendant using
- // |total_sticky_box_sticky_offset_| has the same containing block as this
- // element, so |total_sticky_box_sticky_offset_| does not accumulate
+ // |total_sticky_box_sticky_offset| has the same containing block as this
+ // element, so |total_sticky_box_sticky_offset| does not accumulate
// containing block sticky offsets. For example, consider the following chain:
//
// <div style="position: sticky;">
@@ -241,13 +158,16 @@ class StickyPositionScrollingConstraints final {
//
// In the above example, both outerInline and innerInline have the same
// containing block - the outermost <div>.
- FloatSize total_sticky_box_sticky_offset_;
+ FloatSize total_sticky_box_sticky_offset;
// The containing block offset accumulates all sticky-related offsets between
// this element and the ancestor scroller. If this element is a containing
// block shifting ancestor for some descendant, it shifts the descendant's
// constraint rects by its entire offset.
- FloatSize total_containing_block_sticky_offset_;
+ FloatSize total_containing_block_sticky_offset;
+
+ FloatSize AncestorStickyBoxOffset(const StickyConstraintsMap&) const;
+ FloatSize AncestorContainingBlockOffset(const StickyConstraintsMap&) const;
};
} // 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 380e5cc24d0..b439f2c092f 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
@@ -20,7 +20,7 @@
#include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.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/scroll/scrollable_area.h"
+#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
namespace blink {
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 b7fabf2424c..0115078698b 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
@@ -10,8 +10,8 @@
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/page/scrolling/overscroll_controller.h"
#include "third_party/blink/renderer/core/page/scrolling/scroll_state.h"
+#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
#include "third_party/blink/renderer/platform/geometry/float_size.h"
-#include "third_party/blink/renderer/platform/scroll/scrollable_area.h"
namespace blink {
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 83a8a7c36ea..c0db750f1e2 100644
--- a/chromium/third_party/blink/renderer/core/page/touch_adjustment.cc
+++ b/chromium/third_party/blink/renderer/core/page/touch_adjustment.cc
@@ -23,6 +23,7 @@
#include "third_party/blink/renderer/core/dom/node.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/dom/text.h"
+#include "third_party/blink/renderer/core/editing/editing_behavior.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/frame_selection.h"
@@ -208,31 +209,12 @@ static inline void AppendContextSubtargetsForNode(
return AppendBasicSubtargetsForNode(node, subtargets);
const FrameSelection& frame_selection =
text_layout_object->GetFrame()->Selection();
+ const LayoutTextSelectionStatus& selection_status =
+ frame_selection.ComputeLayoutSelectionStatus(*text_layout_object);
// If selected, make subtargets out of only the selected part of the text.
- int start_pos, end_pos;
- switch (text_layout_object->GetSelectionState()) {
- case SelectionState::kInside:
- start_pos = 0;
- end_pos = text_layout_object->TextLength();
- break;
- case SelectionState::kStart:
- start_pos = frame_selection.LayoutSelectionStart().value();
- end_pos = text_layout_object->TextLength();
- break;
- case SelectionState::kEnd:
- start_pos = 0;
- end_pos = frame_selection.LayoutSelectionEnd().value();
- break;
- case SelectionState::kStartAndEnd:
- start_pos = frame_selection.LayoutSelectionStart().value();
- end_pos = frame_selection.LayoutSelectionEnd().value();
- break;
- default:
- NOTREACHED();
- return;
- }
Vector<FloatQuad> quads;
- text_layout_object->AbsoluteQuadsForRange(quads, start_pos, end_pos);
+ text_layout_object->AbsoluteQuadsForRange(quads, selection_status.start,
+ selection_status.end);
AppendQuadsToSubtargetList(quads, text_node, subtargets);
}
}
diff --git a/chromium/third_party/blink/renderer/core/page/touch_disambiguation.cc b/chromium/third_party/blink/renderer/core/page/touch_disambiguation.cc
deleted file mode 100644
index f6678b7b9b8..00000000000
--- a/chromium/third_party/blink/renderer/core/page/touch_disambiguation.cc
+++ /dev/null
@@ -1,162 +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/core/page/touch_disambiguation.h"
-
-#include <algorithm>
-#include <cmath>
-#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/frame/local_frame.h"
-#include "third_party/blink/renderer/core/frame/local_frame_view.h"
-#include "third_party/blink/renderer/core/html/html_html_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_block.h"
-
-namespace blink {
-
-static IntRect BoundingBoxForEventNodes(Node* event_node) {
- if (!event_node->GetDocument().View())
- return IntRect();
-
- IntRect result;
- Node* node = event_node;
- while (node) {
- // Skip the whole sub-tree if the node doesn't propagate events.
- if (node != event_node && node->WillRespondToMouseClickEvents()) {
- node = NodeTraversal::NextSkippingChildren(*node, event_node);
- continue;
- }
- result.Unite(node->PixelSnappedBoundingBox());
- node = NodeTraversal::Next(*node, event_node);
- }
- return event_node->GetDocument().View()->ConvertToRootFrame(result);
-}
-
-static float ScoreTouchTarget(const IntRect& touch_rect, IntRect bounding_box) {
- if (bounding_box.IsEmpty())
- return 0;
-
- float touch_radius =
- ceil(std::max(touch_rect.Width(), touch_rect.Height()) * 0.5f);
- float score = 1;
-
- IntSize distance = bounding_box.DifferenceToPoint(touch_rect.Center());
- score *= std::max(1 - (abs(distance.Width()) / touch_radius), 0.f);
- score *= std::max(1 - (abs(distance.Height()) / touch_radius), 0.f);
-
- return score;
-}
-
-struct TouchTargetData {
- IntRect window_bounding_box;
- float score;
-};
-
-void FindGoodTouchTargets(const IntRect& touch_box_in_root_frame,
- LocalFrame* main_frame,
- Vector<IntRect>& good_targets,
- HeapVector<Member<Node>>& highlight_nodes) {
- good_targets.clear();
- LayoutPoint hit_point(main_frame->View()->ConvertFromRootFrame(
- touch_box_in_root_frame.Location()));
- HitTestLocation location(
- LayoutRect(hit_point, LayoutSize(touch_box_in_root_frame.Size())));
- HitTestResult result = main_frame->GetEventHandler().HitTestResultAtLocation(
- location, HitTestRequest::kReadOnly | HitTestRequest::kActive |
- HitTestRequest::kListBased);
- const HeapListHashSet<Member<Node>>& hit_results =
- result.ListBasedTestResult();
-
- // Blacklist nodes that are container of disambiguated nodes.
- // It is not uncommon to have a clickable <div> that contains other clickable
- // objects. This heuristic avoids excessive disambiguation in that case.
- HeapHashSet<Member<Node>> black_list;
- for (const auto& hit_result : hit_results) {
- // Ignore any Nodes that can't be clicked on.
- LayoutObject* layout_object = hit_result.Get()->GetLayoutObject();
- if (!layout_object || !hit_result.Get()->WillRespondToMouseClickEvents())
- continue;
-
- // Blacklist all of the Node's containers.
- for (LayoutBlock* container = layout_object->ContainingBlock(); container;
- container = container->ContainingBlock()) {
- Node* container_node = container->GetNode();
- if (!container_node)
- continue;
- if (!black_list.insert(container_node).is_new_entry)
- break;
- }
- }
-
- HeapHashMap<Member<Node>, TouchTargetData> touch_targets;
- float best_score = 0;
- for (const auto& hit_result : hit_results) {
- if (!hit_result)
- continue;
- for (Node& node : NodeTraversal::InclusiveAncestorsOf(*hit_result)) {
- if (black_list.Contains(&node))
- continue;
- if (node.IsDocumentNode() || IsHTMLHtmlElement(node) ||
- IsHTMLBodyElement(node))
- break;
- if (node.WillRespondToMouseClickEvents()) {
- TouchTargetData& target_data =
- touch_targets.insert(&node, TouchTargetData()).stored_value->value;
- target_data.window_bounding_box = BoundingBoxForEventNodes(&node);
- target_data.score = ScoreTouchTarget(touch_box_in_root_frame,
- target_data.window_bounding_box);
- best_score = std::max(best_score, target_data.score);
- break;
- }
- }
- }
-
- // The scoring function uses the overlap area with the fat point as the score.
- // We ignore the candidates that have less than this (empirically tuned)
- // fraction of overlap than the best candidate to avoid excessive popups.
- //
- // If this value were 1, then the disambiguation feature would only be seen
- // when two nodes have precisely the same overlap with the touch radius. If
- // it were 0, then any miniscule overlap with the edge of another node would
- // trigger it.
- const float kRelativeAmbiguityThreshold = 0.75f;
-
- for (const auto& touch_target : touch_targets) {
- if (touch_target.value.score < best_score * kRelativeAmbiguityThreshold)
- continue;
- good_targets.push_back(touch_target.value.window_bounding_box);
- highlight_nodes.push_back(touch_target.key);
- }
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/page/touch_disambiguation.h b/chromium/third_party/blink/renderer/core/page/touch_disambiguation.h
deleted file mode 100644
index 2fe45a0b379..00000000000
--- a/chromium/third_party/blink/renderer/core/page/touch_disambiguation.h
+++ /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.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAGE_TOUCH_DISAMBIGUATION_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_PAGE_TOUCH_DISAMBIGUATION_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/vector.h"
-
-namespace blink {
-
-class LocalFrame;
-class IntRect;
-class Node;
-
-CORE_EXPORT void FindGoodTouchTargets(
- const IntRect& touch_box,
- LocalFrame* main_frame,
- Vector<IntRect>& good_targets,
- HeapVector<Member<Node>>& highlight_nodes);
-
-} // namespace blink
-
-#endif
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 ad3d52a6ac3..52b2a00ef50 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
@@ -32,22 +32,18 @@
#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/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/page/chrome_client.h"
#include "third_party/blink/renderer/core/page/validation_message_overlay_delegate.h"
#include "third_party/blink/renderer/platform/layout_test_support.h"
-#include "third_party/blink/renderer/platform/platform_chrome_client.h"
namespace blink {
-ValidationMessageClientImpl::ValidationMessageClientImpl(WebViewImpl& web_view)
- : web_view_(web_view), current_anchor_(nullptr) {}
+ValidationMessageClientImpl::ValidationMessageClientImpl(Page& page)
+ : page_(&page), current_anchor_(nullptr) {}
-ValidationMessageClientImpl* ValidationMessageClientImpl::Create(
- WebViewImpl& web_view) {
- return new ValidationMessageClientImpl(web_view);
+ValidationMessageClientImpl* ValidationMessageClientImpl::Create(Page& page) {
+ return new ValidationMessageClientImpl(page);
}
ValidationMessageClientImpl::~ValidationMessageClientImpl() = default;
@@ -72,7 +68,7 @@ void ValidationMessageClientImpl::ShowValidationMessage(
HideValidationMessageImmediately(*current_anchor_);
current_anchor_ = &anchor;
message_ = message;
- web_view_.GetChromeClient().RegisterPopupOpeningObserver(this);
+ page_->GetChromeClient().RegisterPopupOpeningObserver(this);
constexpr auto kMinimumTimeToShowValidationMessage =
TimeDelta::FromSeconds(5);
constexpr auto kTimePerCharacter = TimeDelta::FromMilliseconds(50);
@@ -81,17 +77,15 @@ void ValidationMessageClientImpl::ShowValidationMessage(
std::max(kMinimumTimeToShowValidationMessage,
(message.length() + sub_message.length()) * kTimePerCharacter);
- auto* target_frame =
- web_view_.MainFrameImpl()
- ? web_view_.MainFrameImpl()
- : WebLocalFrameImpl::FromFrame(anchor.GetDocument().GetFrame());
+ auto* target_frame = page_->MainFrame() && page_->MainFrame()->IsLocalFrame()
+ ? ToLocalFrame(page_->MainFrame())
+ : anchor.GetDocument().GetFrame();
auto delegate = ValidationMessageOverlayDelegate::Create(
- *web_view_.GetPage(), anchor, message_, message_dir, sub_message,
- sub_message_dir);
+ *page_, anchor, message_, message_dir, sub_message, sub_message_dir);
overlay_delegate_ = delegate.get();
overlay_ = PageOverlay::Create(target_frame, std::move(delegate));
- bool success = target_frame->GetFrameView()
- ->UpdateLifecycleToCompositingCleanPlusScrolling();
+ bool success =
+ target_frame->View()->UpdateLifecycleToCompositingCleanPlusScrolling();
// The lifecycle update should always succeed, because this is not inside
// of a throttling scope.
DCHECK(success);
@@ -130,7 +124,7 @@ void ValidationMessageClientImpl::Reset(TimerBase*) {
finish_time_ = TimeTicks();
overlay_ = nullptr;
overlay_delegate_ = nullptr;
- web_view_.GetChromeClient().UnregisterPopupOpeningObserver(this);
+ page_->GetChromeClient().UnregisterPopupOpeningObserver(this);
}
bool ValidationMessageClientImpl::IsValidationMessageVisible(
@@ -184,6 +178,7 @@ void ValidationMessageClientImpl::PaintOverlay() {
}
void ValidationMessageClientImpl::Trace(blink::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 5aaa1308b0c..b2cce5b34d7 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
@@ -26,7 +26,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAGE_VALIDATION_MESSAGE_CLIENT_IMPL_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_PAGE_VALIDATION_MESSAGE_CLIENT_IMPL_H_
-#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/page/page.h"
#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/geometry/int_rect.h"
@@ -39,22 +39,21 @@ namespace blink {
class LocalFrameView;
class PageOverlay;
class ValidationMessageOverlayDelegate;
-class WebViewImpl;
-class CORE_EXPORT ValidationMessageClientImpl final
+class ValidationMessageClientImpl final
: public GarbageCollectedFinalized<ValidationMessageClientImpl>,
public ValidationMessageClient,
private PopupOpeningObserver {
USING_GARBAGE_COLLECTED_MIXIN(ValidationMessageClientImpl);
public:
- static ValidationMessageClientImpl* Create(WebViewImpl&);
+ static ValidationMessageClientImpl* Create(Page&);
~ValidationMessageClientImpl() override;
void Trace(blink::Visitor*) override;
private:
- ValidationMessageClientImpl(WebViewImpl&);
+ ValidationMessageClientImpl(Page&);
void CheckAnchorStatus(TimerBase*);
LocalFrameView* CurrentView();
void HideValidationMessageImmediately(const Element& anchor);
@@ -75,7 +74,7 @@ class CORE_EXPORT ValidationMessageClientImpl final
// PopupOpeningObserver function
void WillOpenPopup() override;
- WebViewImpl& web_view_;
+ Member<Page> page_;
Member<const Element> current_anchor_;
String message_;
TimeTicks finish_time_;
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 248409df37d..a013c09f835 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
@@ -118,7 +118,7 @@ void ValidationMessageOverlayDelegate::UpdateFrameViewState(
// This manual invalidation is necessary to avoid a DCHECK failure in
// FindVisualRectNeedingUpdateScopeBase::CheckVisualRect().
- FrameView().GetLayoutView()->SetMayNeedPaintInvalidationSubtree();
+ FrameView().GetLayoutView()->SetSubtreeShouldCheckForPaintInvalidation();
FrameView().UpdateAllLifecyclePhases();
}
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 fff7feaf4ac..8451db595bf 100644
--- a/chromium/third_party/blink/renderer/core/page/viewport_test.cc
+++ b/chromium/third_party/blink/renderer/core/page/viewport_test.cc
@@ -45,13 +45,13 @@
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/page/viewport_description.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme.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/int_point.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/length.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h"
#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/testing/url_test_helpers.h"
diff --git a/chromium/third_party/blink/renderer/core/paint/BUILD.gn b/chromium/third_party/blink/renderer/core/paint/BUILD.gn
index 9b23bff71aa..d81d34e2210 100644
--- a/chromium/third_party/blink/renderer/core/paint/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/paint/BUILD.gn
@@ -7,26 +7,18 @@ import("//third_party/blink/renderer/core/core.gni")
blink_core_sources("paint") {
split_count = 2
sources = [
- "adjust_paint_offset_scope.cc",
- "adjust_paint_offset_scope.h",
"applied_decoration_painter.cc",
"applied_decoration_painter.h",
"background_image_geometry.cc",
"background_image_geometry.h",
"block_flow_paint_invalidator.cc",
"block_flow_paint_invalidator.h",
- "block_flow_painter.cc",
- "block_flow_painter.h",
"block_paint_invalidator.cc",
"block_paint_invalidator.h",
"block_painter.cc",
"block_painter.h",
"box_border_painter.cc",
"box_border_painter.h",
- "box_clipper.cc",
- "box_clipper.h",
- "box_clipper_base.cc",
- "box_clipper_base.h",
"box_decoration_data.cc",
"box_decoration_data.h",
"box_model_object_painter.cc",
@@ -49,8 +41,6 @@ blink_core_sources("paint") {
"collapsed_border_painter.h",
"compositing/composited_layer_mapping.cc",
"compositing/composited_layer_mapping.h",
- "compositing/composited_selection.h",
- "compositing/composited_selection_bound.h",
"compositing/compositing_inputs_updater.cc",
"compositing/compositing_inputs_updater.h",
"compositing/compositing_layer_assigner.cc",
@@ -82,8 +72,6 @@ blink_core_sources("paint") {
"ellipsis_box_painter.h",
"embedded_content_painter.cc",
"embedded_content_painter.h",
- "embedded_object_paint_invalidator.cc",
- "embedded_object_paint_invalidator.h",
"embedded_object_painter.cc",
"embedded_object_painter.h",
"fallback_theme.cc",
@@ -106,12 +94,12 @@ blink_core_sources("paint") {
"frame_set_painter.h",
"grid_painter.cc",
"grid_painter.h",
- "html_canvas_paint_invalidator.cc",
- "html_canvas_paint_invalidator.h",
"html_canvas_painter.cc",
"html_canvas_painter.h",
"image_painter.cc",
"image_painter.h",
+ "inline_box_painter_base.cc",
+ "inline_box_painter_base.h",
"inline_flow_box_painter.cc",
"inline_flow_box_painter.h",
"inline_painter.cc",
@@ -130,12 +118,12 @@ blink_core_sources("paint") {
"multi_column_set_painter.h",
"ng/ng_block_flow_painter.cc",
"ng/ng_block_flow_painter.h",
- "ng/ng_box_clipper.cc",
- "ng/ng_box_clipper.h",
"ng/ng_box_fragment_painter.cc",
"ng/ng_box_fragment_painter.h",
"ng/ng_fragment_painter.cc",
"ng/ng_fragment_painter.h",
+ "ng/ng_inline_box_fragment_painter.cc",
+ "ng/ng_inline_box_fragment_painter.h",
"ng/ng_paint_fragment.cc",
"ng/ng_paint_fragment.h",
"ng/ng_paint_fragment_traversal.cc",
@@ -157,6 +145,8 @@ blink_core_sources("paint") {
"object_painter_base.h",
"paint_event.h",
"paint_info.h",
+ "paint_info_with_offset.cc",
+ "paint_info_with_offset.h",
"paint_invalidator.cc",
"paint_invalidator.h",
"paint_layer.cc",
@@ -192,6 +182,8 @@ blink_core_sources("paint") {
"root_inline_box_painter.h",
"rounded_inner_rect_clipper.cc",
"rounded_inner_rect_clipper.h",
+ "scoped_box_clipper.cc",
+ "scoped_box_clipper.h",
"scrollable_area_painter.cc",
"scrollable_area_painter.h",
"scrollbar_painter.cc",
diff --git a/chromium/third_party/blink/renderer/core/paint/DEPS b/chromium/third_party/blink/renderer/core/paint/DEPS
index 6ea8ed7505e..bc2165384f9 100644
--- a/chromium/third_party/blink/renderer/core/paint/DEPS
+++ b/chromium/third_party/blink/renderer/core/paint/DEPS
@@ -2,6 +2,8 @@ include_rules = [
# This goes away after slimming paint v2. For now it violates strict onion
# soup guidelines.
"+cc/layers/picture_layer.h",
+ # For DCHECK.
+ "+base/logging.h",
]
specific_include_rules = {
diff --git a/chromium/third_party/blink/renderer/core/paint/OWNERS b/chromium/third_party/blink/renderer/core/paint/OWNERS
index ffef4feb5d9..d4b697b55dc 100644
--- a/chromium/third_party/blink/renderer/core/paint/OWNERS
+++ b/chromium/third_party/blink/renderer/core/paint/OWNERS
@@ -4,7 +4,6 @@ chrishtr@chromium.org
enne@chromium.org
fmalita@chromium.org
fs@opera.com
-junov@chromium.org
pdr@chromium.org
schenney@chromium.org
senorblanco@chromium.org
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 1c4c1db236e..86da0e15ce0 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
@@ -795,7 +795,6 @@ void BackgroundImageGeometry::CalculateFillTileSize(
// positioning_area_size in that dimension, so that rounding of floating
// point approximation to LayoutUnit do not shrink the image to smaller
// than the positioning_area_size.
- LayoutSize tile_size;
if (type == EFillSizeType::kContain) {
// Snap the dependent dimension to avoid bleeding/blending artifacts
// at the edge of the image when we paint it.
diff --git a/chromium/third_party/blink/renderer/core/paint/block_flow_painter.cc b/chromium/third_party/blink/renderer/core/paint/block_flow_painter.cc
deleted file mode 100644
index cc7810ab6d4..00000000000
--- a/chromium/third_party/blink/renderer/core/paint/block_flow_painter.cc
+++ /dev/null
@@ -1,63 +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/paint/block_flow_painter.h"
-
-#include "third_party/blink/renderer/core/layout/floating_objects.h"
-#include "third_party/blink/renderer/core/layout/layout_block_flow.h"
-#include "third_party/blink/renderer/core/paint/adjust_paint_offset_scope.h"
-#include "third_party/blink/renderer/core/paint/block_painter.h"
-#include "third_party/blink/renderer/core/paint/line_box_list_painter.h"
-#include "third_party/blink/renderer/core/paint/object_painter.h"
-#include "third_party/blink/renderer/core/paint/paint_info.h"
-
-namespace blink {
-
-void BlockFlowPainter::PaintContents(const PaintInfo& paint_info,
- const LayoutPoint& paint_offset) {
- if (paint_info.SuppressPaintingDescendants() &&
- !layout_block_flow_.IsLayoutView()) {
- return;
- }
-
- if (!layout_block_flow_.ChildrenInline()) {
- BlockPainter(layout_block_flow_).PaintContents(paint_info, paint_offset);
- return;
- }
- if (ShouldPaintDescendantOutlines(paint_info.phase)) {
- ObjectPainter(layout_block_flow_).PaintInlineChildrenOutlines(paint_info);
- } else {
- LineBoxListPainter(layout_block_flow_.LineBoxes())
- .Paint(layout_block_flow_, paint_info, paint_offset);
- }
-}
-
-void BlockFlowPainter::PaintFloats(const PaintInfo& paint_info) {
- if (!layout_block_flow_.GetFloatingObjects())
- return;
-
- DCHECK(paint_info.phase == PaintPhase::kFloat ||
- paint_info.phase == PaintPhase::kSelection ||
- paint_info.phase == PaintPhase::kTextClip);
- PaintInfo float_paint_info(paint_info);
- if (paint_info.phase == PaintPhase::kFloat)
- float_paint_info.phase = PaintPhase::kForeground;
-
- for (const auto& floating_object :
- layout_block_flow_.GetFloatingObjects()->Set()) {
- if (!floating_object->ShouldPaint())
- continue;
-
- const LayoutBox* floating_layout_object =
- floating_object->GetLayoutObject();
- // TODO(wangxianzhu): Should this be a DCHECK?
- if (floating_layout_object->HasSelfPaintingLayer())
- continue;
-
- ObjectPainter(*floating_layout_object)
- .PaintAllPhasesAtomically(float_paint_info);
- }
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/block_flow_painter.h b/chromium/third_party/blink/renderer/core/paint/block_flow_painter.h
deleted file mode 100644
index 8f8c8e45508..00000000000
--- a/chromium/third_party/blink/renderer/core/paint/block_flow_painter.h
+++ /dev/null
@@ -1,31 +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_PAINT_BLOCK_FLOW_PAINTER_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_BLOCK_FLOW_PAINTER_H_
-
-#include "third_party/blink/renderer/platform/wtf/allocator.h"
-
-namespace blink {
-
-struct PaintInfo;
-class LayoutBlockFlow;
-class LayoutPoint;
-
-class BlockFlowPainter {
- STACK_ALLOCATED();
-
- public:
- BlockFlowPainter(const LayoutBlockFlow& layout_block_flow)
- : layout_block_flow_(layout_block_flow) {}
- void PaintContents(const PaintInfo&, const LayoutPoint& paint_offset);
- void PaintFloats(const PaintInfo&);
-
- private:
- const LayoutBlockFlow& layout_block_flow_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_BLOCK_FLOW_PAINTER_H_
diff --git a/chromium/third_party/blink/renderer/core/paint/block_paint_invalidator.cc b/chromium/third_party/blink/renderer/core/paint/block_paint_invalidator.cc
index f9a48ba539f..633e8e8c04e 100644
--- a/chromium/third_party/blink/renderer/core/paint/block_paint_invalidator.cc
+++ b/chromium/third_party/blink/renderer/core/paint/block_paint_invalidator.cc
@@ -20,15 +20,12 @@ void BlockPaintInvalidator::ClearPreviousVisualRects() {
block_.GetFrame()->GetPage()->GetDragCaret().ClearPreviousVisualRect(block_);
}
-PaintInvalidationReason BlockPaintInvalidator::InvalidatePaint(
+void BlockPaintInvalidator::InvalidatePaint(
const PaintInvalidatorContext& context) {
- PaintInvalidationReason reason =
- BoxPaintInvalidator(block_, context).InvalidatePaint();
+ BoxPaintInvalidator(block_, context).InvalidatePaint();
block_.GetFrame()->Selection().InvalidatePaint(block_, context);
block_.GetFrame()->GetPage()->GetDragCaret().InvalidatePaint(block_, context);
-
- return reason;
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/block_paint_invalidator.h b/chromium/third_party/blink/renderer/core/paint/block_paint_invalidator.h
index 988b0ce2c9e..7101dbdc7ea 100644
--- a/chromium/third_party/blink/renderer/core/paint/block_paint_invalidator.h
+++ b/chromium/third_party/blink/renderer/core/paint/block_paint_invalidator.h
@@ -20,7 +20,7 @@ class BlockPaintInvalidator {
BlockPaintInvalidator(const LayoutBlock& block) : block_(block) {}
void ClearPreviousVisualRects();
- PaintInvalidationReason InvalidatePaint(const PaintInvalidatorContext&);
+ void InvalidatePaint(const PaintInvalidatorContext&);
private:
const LayoutBlock& block_;
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 3c688a1fe1a..2f631d32e75 100644
--- a/chromium/third_party/blink/renderer/core/paint/block_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/block_painter.cc
@@ -12,13 +12,13 @@
#include "third_party/blink/renderer/core/layout/layout_flexible_box.h"
#include "third_party/blink/renderer/core/layout/layout_inline.h"
#include "third_party/blink/renderer/core/page/page.h"
-#include "third_party/blink/renderer/core/paint/adjust_paint_offset_scope.h"
-#include "third_party/blink/renderer/core/paint/block_flow_painter.h"
-#include "third_party/blink/renderer/core/paint/box_clipper.h"
#include "third_party/blink/renderer/core/paint/box_painter.h"
+#include "third_party/blink/renderer/core/paint/line_box_list_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_info_with_offset.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
+#include "third_party/blink/renderer/core/paint/scoped_box_clipper.h"
#include "third_party/blink/renderer/core/paint/scrollable_area_painter.h"
#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
@@ -28,19 +28,19 @@ namespace blink {
DISABLE_CFI_PERF
void BlockPainter::Paint(const PaintInfo& paint_info) {
- AdjustPaintOffsetScope adjustment(layout_block_, paint_info);
- auto paint_offset = adjustment.PaintOffset();
- auto& local_paint_info = adjustment.MutablePaintInfo();
-
+ PaintInfoWithOffset paint_info_with_offset(layout_block_, paint_info);
// We can't early return if there is no fragment to paint for this block,
// because there may be overflowing children that exist in the painting
- // fragment. We also can't check IntersectsPaintRect() in the case because we
+ // fragment. We also can't check ShouldPaint() in the case because we
// don't have a meaningful paint offset. TODO(wangxianzhu): only paint
// children if !adjustment.FragmentToPaint().
- if (adjustment.FragmentToPaint() &&
- !IntersectsPaintRect(local_paint_info, paint_offset))
+ if (paint_info_with_offset.FragmentToPaint() &&
+ !ShouldPaint(paint_info_with_offset))
return;
+ auto paint_offset = paint_info_with_offset.PaintOffset();
+ auto& local_paint_info = paint_info_with_offset.MutablePaintInfo();
+
PaintPhase original_phase = local_paint_info.phase;
if (original_phase == PaintPhase::kOutline) {
@@ -54,10 +54,34 @@ void BlockPainter::Paint(const PaintInfo& paint_info) {
if (original_phase != PaintPhase::kSelfBlockBackgroundOnly &&
original_phase != PaintPhase::kSelfOutlineOnly) {
- BoxClipper clipper(layout_block_, local_paint_info);
+ base::Optional<ScopedBoxClipper> box_clipper;
+ if (local_paint_info.phase != PaintPhase::kMask)
+ box_clipper.emplace(layout_block_, local_paint_info);
layout_block_.PaintObject(local_paint_info, paint_offset);
}
+ // Carets are painted in the foreground phase, outside of the contents
+ // properties block. Note that caret painting does not seem to correspond to
+ // any painting order steps within the CSS spec.
+ if (original_phase == PaintPhase::kForeground &&
+ layout_block_.ShouldPaintCarets()) {
+ // Apply overflow clip if needed. TODO(wangxianzhu): Move PaintCarets()
+ // under |contents_paint_state| in the above block and let the caret
+ // painters paint in the space of scrolling contents.
+ base::Optional<ScopedPaintChunkProperties> paint_chunk_properties;
+ if (const auto* fragment = paint_info_with_offset.FragmentToPaint()) {
+ if (const auto* properties = fragment->PaintProperties()) {
+ if (const auto* overflow_clip = properties->OverflowClip()) {
+ paint_chunk_properties.emplace(
+ paint_info.context.GetPaintController(), overflow_clip,
+ layout_block_, DisplayItem::kCaret);
+ }
+ }
+ }
+
+ PaintCarets(paint_info, paint_offset);
+ }
+
if (ShouldPaintSelfOutline(original_phase)) {
local_paint_info.phase = PaintPhase::kSelfOutlineOnly;
layout_block_.PaintObject(local_paint_info, paint_offset);
@@ -74,7 +98,7 @@ void BlockPainter::PaintOverflowControlsIfNeeded(
const PaintInfo& paint_info,
const LayoutPoint& paint_offset) {
if (layout_block_.HasOverflowClip() &&
- layout_block_.Style()->Visibility() == EVisibility::kVisible &&
+ layout_block_.StyleRef().Visibility() == EVisibility::kVisible &&
ShouldPaintSelfBlockBackground(paint_info.phase)) {
ScrollableAreaPainter(*layout_block_.Layer()->GetScrollableArea())
.PaintOverflowControls(paint_info, RoundedIntPoint(paint_offset),
@@ -183,15 +207,36 @@ void BlockPainter::RecordHitTestData(const PaintInfo& paint_info,
DISABLE_CFI_PERF
void BlockPainter::PaintObject(const PaintInfo& paint_info,
const LayoutPoint& paint_offset) {
+ const PaintPhase paint_phase = paint_info.phase;
+ // This function implements some of the painting order algorithm (described
+ // within the description of stacking context, here
+ // https://www.w3.org/TR/css-position-3/#det-stacking-context). References are
+ // made below to the step numbers described in that document.
+
+ // If this block has been truncated, early-out here, because it will not be
+ // displayed. A truncated block occurs when text-overflow: ellipsis is set on
+ // a block, and there is not enough room to display all elements. The elements
+ // that don't get shown are "Truncated".
if (layout_block_.IsTruncated())
return;
- const PaintPhase paint_phase = paint_info.phase;
+ // If we're *printing* the foreground, paint the URL.
+ if (paint_phase == PaintPhase::kForeground && paint_info.IsPrinting()) {
+ ObjectPainter(layout_block_)
+ .AddPDFURLRectIfNeeded(paint_info, paint_offset);
+ }
+ // If we're painting our background (either 1. kBlockBackground - background
+ // of the current object and non-self-painting descendants, or 2.
+ // kSelfBlockBackgroundOnly - Paint background of the current object only),
+ // paint those now. This is steps #1, 2, and 4 of the CSS spec (see above).
if (ShouldPaintSelfBlockBackground(paint_phase)) {
- if (layout_block_.Style()->Visibility() == EVisibility::kVisible &&
- layout_block_.HasBoxDecorationBackground())
+ // Paint the background if we're visible and this block has a box decoration
+ // (background, border, appearance, or box shadow).
+ if (layout_block_.StyleRef().Visibility() == EVisibility::kVisible &&
+ layout_block_.HasBoxDecorationBackground()) {
layout_block_.PaintBoxDecorationBackground(paint_info, paint_offset);
+ }
if (RuntimeEnabledFeatures::PaintTouchActionRectsEnabled())
RecordHitTestData(paint_info, paint_offset);
// Record the scroll hit test after the background so background squashing
@@ -199,32 +244,21 @@ void BlockPainter::PaintObject(const PaintInfo& paint_info,
// immediately before the background.
if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
PaintScrollHitTestDisplayItem(paint_info);
- // We're done. We don't bother painting any children.
- if (paint_phase == PaintPhase::kSelfBlockBackgroundOnly)
- return;
- }
-
- if (paint_phase == PaintPhase::kMask &&
- layout_block_.Style()->Visibility() == EVisibility::kVisible) {
- layout_block_.PaintMask(paint_info, paint_offset);
- return;
}
- if (paint_phase == PaintPhase::kForeground && paint_info.IsPrinting())
- ObjectPainter(layout_block_)
- .AddPDFURLRectIfNeeded(paint_info, paint_offset);
-
- if (paint_phase != PaintPhase::kSelfOutlineOnly) {
- base::Optional<ScopedPaintChunkProperties> scoped_scroll_property;
+ // If we're in any phase except *just* the self (outline or background) or a
+ // mask, paint children now. This is step #5, 7, 8, and 9 of the CSS spec (see
+ // above).
+ if (paint_phase != PaintPhase::kSelfOutlineOnly &&
+ paint_phase != PaintPhase::kSelfBlockBackgroundOnly &&
+ paint_phase != PaintPhase::kMask) {
+ // Handle scrolling translation.
base::Optional<PaintInfo> scrolled_paint_info;
if (const auto* fragment = paint_info.FragmentToPaint(layout_block_)) {
const auto* object_properties = fragment->PaintProperties();
auto* scroll_translation =
object_properties ? object_properties->ScrollTranslation() : nullptr;
if (scroll_translation) {
- scoped_scroll_property.emplace(
- paint_info.context.GetPaintController(), scroll_translation,
- layout_block_, DisplayItem::PaintPhaseToScrollType(paint_phase));
scrolled_paint_info.emplace(paint_info);
if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
scrolled_paint_info->UpdateCullRectForScrollingContents(
@@ -236,30 +270,76 @@ void BlockPainter::PaintObject(const PaintInfo& paint_info,
}
}
}
-
const PaintInfo& contents_paint_info =
scrolled_paint_info ? *scrolled_paint_info : paint_info;
+ // Actually paint the contents.
if (layout_block_.IsLayoutBlockFlow()) {
- BlockFlowPainter block_flow_painter(ToLayoutBlockFlow(layout_block_));
- block_flow_painter.PaintContents(contents_paint_info, paint_offset);
- if (paint_phase == PaintPhase::kFloat ||
- paint_phase == PaintPhase::kSelection ||
- paint_phase == PaintPhase::kTextClip)
- block_flow_painter.PaintFloats(contents_paint_info);
+ // All floating descendants will be LayoutBlockFlow objects, and will get
+ // painted here. That is step #5 of the CSS spec (see above).
+ PaintBlockFlowContents(contents_paint_info, paint_offset);
} else {
PaintContents(contents_paint_info, paint_offset);
}
}
+ // If we're painting the outline, paint it now. This is step #10 of the CSS
+ // spec (see above).
if (ShouldPaintSelfOutline(paint_phase))
ObjectPainter(layout_block_).PaintOutline(paint_info, paint_offset);
- // If the caret's node's layout object's containing block is this block, and
- // the paint action is PaintPhaseForeground, then paint the caret.
- if (paint_phase == PaintPhase::kForeground &&
- layout_block_.ShouldPaintCarets())
- PaintCarets(paint_info, paint_offset);
+ // If we're painting a visible mask, paint it now. (This does not correspond
+ // to any painting order steps within the CSS spec.)
+ if (paint_phase == PaintPhase::kMask &&
+ layout_block_.StyleRef().Visibility() == EVisibility::kVisible) {
+ layout_block_.PaintMask(paint_info, paint_offset);
+ }
+}
+
+void BlockPainter::PaintBlockFlowContents(const PaintInfo& paint_info,
+ const LayoutPoint& paint_offset) {
+ DCHECK(layout_block_.IsLayoutBlockFlow());
+ if (layout_block_.IsLayoutView() ||
+ !paint_info.SuppressPaintingDescendants()) {
+ if (!layout_block_.ChildrenInline()) {
+ PaintContents(paint_info, paint_offset);
+ } else if (ShouldPaintDescendantOutlines(paint_info.phase)) {
+ ObjectPainter(layout_block_).PaintInlineChildrenOutlines(paint_info);
+ } else {
+ LineBoxListPainter(ToLayoutBlockFlow(layout_block_).LineBoxes())
+ .Paint(layout_block_, paint_info, paint_offset);
+ }
+ }
+
+ // If we don't have any floats to paint, or we're in the wrong paint phase,
+ // then we're done for now.
+ auto* floating_objects =
+ ToLayoutBlockFlow(layout_block_).GetFloatingObjects();
+ const PaintPhase paint_phase = paint_info.phase;
+ if (!floating_objects || !(paint_phase == PaintPhase::kFloat ||
+ paint_phase == PaintPhase::kSelection ||
+ paint_phase == PaintPhase::kTextClip)) {
+ return;
+ }
+
+ // If we're painting floats (not selections or textclips), change
+ // the paint phase to foreground.
+ PaintInfo float_paint_info(paint_info);
+ if (paint_info.phase == PaintPhase::kFloat)
+ float_paint_info.phase = PaintPhase::kForeground;
+
+ // Paint all floats.
+ for (const auto& floating_object : floating_objects->Set()) {
+ if (!floating_object->ShouldPaint())
+ continue;
+ const LayoutBox* floating_layout_object =
+ floating_object->GetLayoutObject();
+ // TODO(wangxianzhu): Should this be a DCHECK?
+ if (floating_layout_object->HasSelfPaintingLayer())
+ continue;
+ ObjectPainter(*floating_layout_object)
+ .PaintAllPhasesAtomically(float_paint_info);
+ }
}
void BlockPainter::PaintCarets(const PaintInfo& paint_info,
@@ -276,16 +356,16 @@ void BlockPainter::PaintCarets(const PaintInfo& paint_info,
}
DISABLE_CFI_PERF
-bool BlockPainter::IntersectsPaintRect(const PaintInfo& paint_info,
- const LayoutPoint& paint_offset) const {
+bool BlockPainter::ShouldPaint(
+ const PaintInfoWithOffset& paint_info_with_offset) const {
LayoutRect overflow_rect;
- if (paint_info.IsPrinting() && layout_block_.IsAnonymousBlock() &&
- layout_block_.ChildrenInline()) {
- // For case <a href="..."><div>...</div></a>, when m_layoutBlock is the
+ if (paint_info_with_offset.GetPaintInfo().IsPrinting() &&
+ layout_block_.IsAnonymousBlock() && layout_block_.ChildrenInline()) {
+ // For case <a href="..."><div>...</div></a>, when layout_block_ is the
// anonymous container of <a>, the anonymous container's visual overflow is
// empty, but we need to continue painting to output <a>'s PDF URL rect
// which covers the continuations, as if we included <a>'s PDF URL rect into
- // m_layoutBlock's visual overflow.
+ // layout_block_'s visual overflow.
Vector<LayoutRect> rects;
layout_block_.AddElementVisualOverflowRects(rects, LayoutPoint());
overflow_rect = UnionRect(rects);
@@ -307,8 +387,7 @@ bool BlockPainter::IntersectsPaintRect(const PaintInfo& paint_info,
overflow_rect.Move(-layout_block_.ScrolledContentOffset());
}
- overflow_rect.MoveBy(paint_offset);
- return paint_info.GetCullRect().IntersectsCullRect(overflow_rect);
+ return paint_info_with_offset.LocalRectIntersectsCullRect(overflow_rect);
}
void BlockPainter::PaintContents(const PaintInfo& paint_info,
diff --git a/chromium/third_party/blink/renderer/core/paint/block_painter.h b/chromium/third_party/blink/renderer/core/paint/block_painter.h
index 190d45eef13..1bd47cd6c99 100644
--- a/chromium/third_party/blink/renderer/core/paint/block_painter.h
+++ b/chromium/third_party/blink/renderer/core/paint/block_painter.h
@@ -10,6 +10,7 @@
namespace blink {
struct PaintInfo;
+class PaintInfoWithOffset;
class InlineBox;
class LayoutBlock;
class LayoutBox;
@@ -36,10 +37,7 @@ class BlockPainter {
const PaintInfo&);
static void PaintInlineBox(const InlineBox&, const PaintInfo&);
- // The adjustedPaintOffset should include the location (offset) of the object
- // itself.
- bool IntersectsPaintRect(const PaintInfo&,
- const LayoutPoint& paint_offset) const;
+ bool ShouldPaint(const PaintInfoWithOffset&) const;
private:
// Paint scroll hit test placeholders in the correct paint order (see:
@@ -49,6 +47,7 @@ class BlockPainter {
// called in the background paint phase even if there is no other painted
// content.
void RecordHitTestData(const PaintInfo&, const LayoutPoint& paint_offset);
+ void PaintBlockFlowContents(const PaintInfo&, const LayoutPoint&);
void PaintCarets(const PaintInfo&, const LayoutPoint& paint_offset);
const LayoutBlock& layout_block_;
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 779abf9fa7c..168b232ac1a 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
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/paint/block_painter.h"
#include <gtest/gtest.h>
+#include "third_party/blink/renderer/core/dom/events/event_listener.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.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"
diff --git a/chromium/third_party/blink/renderer/core/paint/box_clipper.cc b/chromium/third_party/blink/renderer/core/paint/box_clipper.cc
deleted file mode 100644
index f00a3ca64b4..00000000000
--- a/chromium/third_party/blink/renderer/core/paint/box_clipper.cc
+++ /dev/null
@@ -1,31 +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/paint/box_clipper.h"
-
-#include "third_party/blink/renderer/core/layout/layout_box.h"
-#include "third_party/blink/renderer/core/layout/svg/layout_svg_root.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/platform/graphics/graphics_layer.h"
-#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h"
-#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
-
-namespace blink {
-
-DISABLE_CFI_PERF
-BoxClipper::BoxClipper(const LayoutBox& box, const PaintInfo& paint_info)
- : box_(box), paint_info_(paint_info) {
- DCHECK(paint_info_.phase != PaintPhase::kSelfBlockBackgroundOnly &&
- paint_info_.phase != PaintPhase::kSelfOutlineOnly);
-
- if (paint_info_.phase == PaintPhase::kMask)
- return;
-
- InitializeScopedClipProperty(paint_info.FragmentToPaint(box_), box,
- paint_info);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/box_clipper.h b/chromium/third_party/blink/renderer/core/paint/box_clipper.h
deleted file mode 100644
index e6d49f2d126..00000000000
--- a/chromium/third_party/blink/renderer/core/paint/box_clipper.h
+++ /dev/null
@@ -1,29 +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_PAINT_BOX_CLIPPER_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_BOX_CLIPPER_H_
-
-#include "third_party/blink/renderer/core/paint/box_clipper_base.h"
-#include "third_party/blink/renderer/platform/geometry/layout_point.h"
-#include "third_party/blink/renderer/platform/graphics/paint/display_item.h"
-
-namespace blink {
-
-class LayoutBox;
-
-class BoxClipper : public BoxClipperBase {
- DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
-
- public:
- BoxClipper(const LayoutBox&, const PaintInfo&);
-
- private:
- const LayoutBox& box_;
- const PaintInfo& paint_info_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_BOX_CLIPPER_H_
diff --git a/chromium/third_party/blink/renderer/core/paint/box_clipper_base.cc b/chromium/third_party/blink/renderer/core/paint/box_clipper_base.cc
deleted file mode 100644
index 39ade2308c4..00000000000
--- a/chromium/third_party/blink/renderer/core/paint/box_clipper_base.cc
+++ /dev/null
@@ -1,38 +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/paint/box_clipper_base.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/platform/graphics/graphics_layer.h"
-#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h"
-#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
-
-namespace blink {
-
-DISABLE_CFI_PERF
-void BoxClipperBase::InitializeScopedClipProperty(
- const FragmentData* fragment,
- const DisplayItemClient& client,
- const PaintInfo& paint_info) {
- if (!fragment)
- return;
- const auto* properties = fragment->PaintProperties();
- if (!properties)
- return;
-
- const auto* clip = properties->OverflowClip()
- ? properties->OverflowClip()
- : properties->InnerBorderRadiusClip();
- if (!clip)
- return;
-
- scoped_clip_property_.emplace(paint_info.context.GetPaintController(), clip,
- client,
- paint_info.DisplayItemTypeForClipping());
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/box_clipper_base.h b/chromium/third_party/blink/renderer/core/paint/box_clipper_base.h
deleted file mode 100644
index 9f136b1e55b..00000000000
--- a/chromium/third_party/blink/renderer/core/paint/box_clipper_base.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_BOX_CLIPPER_BASE_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_BOX_CLIPPER_BASE_H_
-
-#include "base/optional.h"
-#include "third_party/blink/renderer/platform/graphics/paint/scoped_paint_chunk_properties.h"
-#include "third_party/blink/renderer/platform/wtf/allocator.h"
-
-namespace blink {
-
-class DisplayItemClient;
-class FragmentData;
-struct PaintInfo;
-
-class BoxClipperBase {
- DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
-
- protected:
- void InitializeScopedClipProperty(const FragmentData*,
- const DisplayItemClient&,
- const PaintInfo&);
-
- base::Optional<ScopedPaintChunkProperties> scoped_clip_property_;
-};
-
-} // namespace blink
-
-#endif // BoxClipper_h
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 526970b70ad..2394a434f44 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
@@ -4,12 +4,10 @@
#include "third_party/blink/renderer/core/paint/box_model_object_painter.h"
-#include "third_party/blink/renderer/core/layout/layout_block_flow.h"
+#include "third_party/blink/renderer/core/layout/layout_block.h"
#include "third_party/blink/renderer/core/layout/layout_box_model_object.h"
-#include "third_party/blink/renderer/core/layout/layout_inline.h"
#include "third_party/blink/renderer/core/layout/line/root_inline_box.h"
#include "third_party/blink/renderer/core/paint/background_image_geometry.h"
-#include "third_party/blink/renderer/core/paint/line_box_list_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"
@@ -54,9 +52,7 @@ BoxModelObjectPainter::BoxModelObjectPainter(const LayoutBoxModelObject& box,
const InlineFlowBox* flow_box)
: BoxPainterBase(&box.GetDocument(),
box.StyleRef(),
- GeneratingNodeForObject(box),
- box.BorderBoxOutsets(),
- box.PaddingOutsets()),
+ GeneratingNodeForObject(box)),
box_model_(box),
flow_box_(flow_box) {}
@@ -85,15 +81,13 @@ void BoxModelObjectPainter::PaintTextClipMask(GraphicsContext& context,
const RootInlineBox& root = flow_box_->Root();
flow_box_->Paint(paint_info, paint_offset - local_offset, root.LineTop(),
root.LineBottom());
+ } else if (box_model_.IsLayoutBlock()) {
+ ToLayoutBlock(box_model_).PaintObject(paint_info, paint_offset);
} else {
- const LineBoxList* line_boxes = nullptr;
- if (box_model_.IsLayoutBlockFlow())
- line_boxes = &ToLayoutBlockFlow(box_model_).LineBoxes();
- else if (box_model_.IsLayoutInline())
- line_boxes = ToLayoutInline(box_model_).LineBoxes();
- if (!line_boxes)
- return;
- LineBoxListPainter(*line_boxes).Paint(box_model_, paint_info, paint_offset);
+ // We should go through the above path for LayoutInlines.
+ DCHECK(!box_model_.IsLayoutInline());
+ // Other types of objects don't have anything meaningful to paint for text
+ // clip mask.
}
}
@@ -115,7 +109,7 @@ LayoutRect BoxModelObjectPainter::AdjustRectForScrolledContent(
// the ends.
IntSize offset = this_box.ScrolledContentOffset();
scrolled_paint_rect.Move(-offset);
- LayoutRectOutsets border = BorderOutsets(info);
+ LayoutRectOutsets border = AdjustedBorderOutsets(info);
scrolled_paint_rect.SetWidth(border.Left() + this_box.ScrollWidth() +
border.Right());
scrolled_paint_rect.SetHeight(this_box.BorderTop() +
@@ -125,6 +119,14 @@ LayoutRect BoxModelObjectPainter::AdjustRectForScrolledContent(
return scrolled_paint_rect;
}
+LayoutRectOutsets BoxModelObjectPainter::ComputeBorders() const {
+ return box_model_.BorderBoxOutsets();
+}
+
+LayoutRectOutsets BoxModelObjectPainter::ComputePadding() const {
+ return box_model_.PaddingOutsets();
+}
+
BoxPainterBase::FillLayerInfo BoxModelObjectPainter::GetFillLayerInfo(
const Color& color,
const FillLayer& bg_layer,
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 8896cdbc546..c1ff417c07f 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
@@ -32,6 +32,8 @@ class BoxModelObjectPainter : public BoxPainterBase {
const PaintInfo&);
protected:
+ LayoutRectOutsets ComputeBorders() const override;
+ LayoutRectOutsets ComputePadding() const override;
BoxPainterBase::FillLayerInfo GetFillLayerInfo(
const Color&,
const FillLayer&,
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 0a6727100a3..7b903f55bc8 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
@@ -27,7 +27,7 @@ PaintInvalidationReason BoxPaintInvalidator::ComputePaintInvalidationReason() {
if ((style.BackgroundLayers().ThisOrNextLayersUseContentBox() ||
style.MaskLayers().ThisOrNextLayersUseContentBox()) &&
- box_.PreviousContentBoxSize() != box_.ContentSize()) {
+ box_.PreviousPhysicalContentBoxRect() != box_.PhysicalContentBoxRect()) {
return PaintInvalidationReason::kGeometry;
}
@@ -225,40 +225,21 @@ void BoxPaintInvalidator::InvalidateBackground() {
}
}
-PaintInvalidationReason BoxPaintInvalidator::InvalidatePaint() {
+void BoxPaintInvalidator::InvalidatePaint() {
InvalidateBackground();
- PaintInvalidationReason reason = ComputePaintInvalidationReason();
- if (reason == PaintInvalidationReason::kIncremental) {
- if (box_.PreviousSize() != box_.Size()) {
- context_.painting_layer->SetNeedsRepaint();
- box_.InvalidateDisplayItemClients(reason);
- } else {
- reason = PaintInvalidationReason::kNone;
- }
-
- // Though we have done incremental invalidation, we still need to call
- // ObjectPaintInvalidator with PaintInvalidationNone to do any other
- // required operations.
- reason = std::max(reason, ObjectPaintInvalidatorWithContext(box_, context_)
- .InvalidatePaintWithComputedReason(
- PaintInvalidationReason::kNone));
- } else {
- reason = ObjectPaintInvalidatorWithContext(box_, context_)
- .InvalidatePaintWithComputedReason(reason);
- }
+ ObjectPaintInvalidatorWithContext(box_, context_)
+ .InvalidatePaintWithComputedReason(ComputePaintInvalidationReason());
if (PaintLayerScrollableArea* area = box_.GetScrollableArea())
area->InvalidatePaintOfScrollControlsIfNeeded(context_);
// This is for the next invalidatePaintIfNeeded so must be at the end.
SavePreviousBoxGeometriesIfNeeded();
-
- return reason;
}
bool BoxPaintInvalidator::
- NeedsToSavePreviousContentBoxSizeOrLayoutOverflowRect() {
+ NeedsToSavePreviousContentBoxRectOrLayoutOverflowRect() {
// The LayoutView depends on the document element's layout overflow rect (see:
// ViewBackgroundShouldFullyInvalidate) and needs to invalidate before the
// document element invalidates. There are few document elements so the
@@ -267,6 +248,11 @@ bool BoxPaintInvalidator::
if (box_.IsDocumentElement())
return true;
+ // Replaced elements are clipped to the content box thus we need to check
+ // for its size.
+ if (box_.IsLayoutReplaced())
+ return true;
+
// Don't save old box geometries if the paint rect is empty because we'll
// fully invalidate once the paint rect becomes non-empty.
if (context_.fragment_data->VisualRect().IsEmpty())
@@ -294,12 +280,12 @@ bool BoxPaintInvalidator::
void BoxPaintInvalidator::SavePreviousBoxGeometriesIfNeeded() {
box_.GetMutableForPainting().SavePreviousSize();
- if (NeedsToSavePreviousContentBoxSizeOrLayoutOverflowRect()) {
+ if (NeedsToSavePreviousContentBoxRectOrLayoutOverflowRect()) {
box_.GetMutableForPainting()
- .SavePreviousContentBoxSizeAndLayoutOverflowRect();
+ .SavePreviousContentBoxRectAndLayoutOverflowRect();
} else {
box_.GetMutableForPainting()
- .ClearPreviousContentBoxSizeAndLayoutOverflowRect();
+ .ClearPreviousContentBoxRectAndLayoutOverflowRect();
}
}
diff --git a/chromium/third_party/blink/renderer/core/paint/box_paint_invalidator.h b/chromium/third_party/blink/renderer/core/paint/box_paint_invalidator.h
index 8f94dba2226..9cd71dc515f 100644
--- a/chromium/third_party/blink/renderer/core/paint/box_paint_invalidator.h
+++ b/chromium/third_party/blink/renderer/core/paint/box_paint_invalidator.h
@@ -25,7 +25,7 @@ class CORE_EXPORT BoxPaintInvalidator {
static void BoxWillBeDestroyed(const LayoutBox&);
- PaintInvalidationReason InvalidatePaint();
+ void InvalidatePaint();
private:
friend class BoxPaintInvalidatorTest;
@@ -43,7 +43,7 @@ class CORE_EXPORT BoxPaintInvalidator {
PaintInvalidationReason ComputePaintInvalidationReason();
- bool NeedsToSavePreviousContentBoxSizeOrLayoutOverflowRect();
+ bool NeedsToSavePreviousContentBoxRectOrLayoutOverflowRect();
void SavePreviousBoxGeometriesIfNeeded();
const LayoutBox& box_;
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 92c92a0ce07..fd7efdadda3 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
@@ -46,7 +46,7 @@ class BoxPaintInvalidatorTest : public PaintControllerPaintTest {
GetDocument().View()->UpdateAllLifecyclePhases();
auto& target = *GetDocument().getElementById("target");
- const auto& box = *ToLayoutBox(target.GetLayoutObject());
+ auto& box = *ToLayoutBox(target.GetLayoutObject());
LayoutRect visual_rect = box.FirstFragment().VisualRect();
LayoutPoint paint_offset = box.FirstFragment().PaintOffset();
@@ -79,6 +79,9 @@ class BoxPaintInvalidatorTest : public PaintControllerPaintTest {
height: 100px;
transform-origin: 0 0;
}
+ .background {
+ background: blue;
+ }
.border {
border-width: 20px 10px;
border-style: solid;
@@ -105,7 +108,6 @@ TEST_P(BoxPaintInvalidatorTest, ComputePaintInvalidationReasonPaintingNothing) {
EXPECT_TRUE(box.PaintedOutputOfObjectHasNoEffectRegardlessOfSize());
LayoutRect visual_rect = box.FirstFragment().VisualRect();
- EXPECT_EQ(LayoutRect(0, 0, 50, 100), visual_rect);
// No geometry change.
EXPECT_EQ(
@@ -139,7 +141,7 @@ TEST_P(BoxPaintInvalidatorTest, ComputePaintInvalidationReasonBasic) {
target.setAttribute(HTMLNames::styleAttr, "background: blue");
GetDocument().View()->UpdateAllLifecyclePhases();
- box.SetMayNeedPaintInvalidation();
+ box.SetShouldCheckForPaintInvalidation();
LayoutRect visual_rect = box.FirstFragment().VisualRect();
EXPECT_EQ(LayoutRect(0, 0, 50, 100), visual_rect);
@@ -186,8 +188,8 @@ TEST_P(BoxPaintInvalidatorTest, ComputePaintInvalidationReasonOtherCases) {
// The target initially has border.
ExpectFullPaintInvalidationOnGeometryChange("With border");
- // Clear border.
- target.setAttribute(HTMLNames::classAttr, "");
+ // Clear border, set background.
+ target.setAttribute(HTMLNames::classAttr, "background");
target.setAttribute(HTMLNames::styleAttr, "border-radius: 5px");
ExpectFullPaintInvalidationOnGeometryChange("With border-radius");
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 beea2b67302..473b45f2f48 100644
--- a/chromium/third_party/blink/renderer/core/paint/box_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/box_painter.cc
@@ -11,7 +11,6 @@
#include "third_party/blink/renderer/core/layout/layout_table.h"
#include "third_party/blink/renderer/core/layout/layout_theme.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object.h"
-#include "third_party/blink/renderer/core/paint/adjust_paint_offset_scope.h"
#include "third_party/blink/renderer/core/paint/background_image_geometry.h"
#include "third_party/blink/renderer/core/paint/box_decoration_data.h"
#include "third_party/blink/renderer/core/paint/box_model_object_painter.h"
@@ -20,6 +19,7 @@
#include "third_party/blink/renderer/core/paint/nine_piece_image_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_info_with_offset.h"
#include "third_party/blink/renderer/core/paint/svg_foreign_object_painter.h"
#include "third_party/blink/renderer/core/paint/theme_painter.h"
#include "third_party/blink/renderer/platform/geometry/layout_point.h"
@@ -33,8 +33,8 @@ namespace blink {
void BoxPainter::Paint(const PaintInfo& paint_info) {
// Default implementation. Just pass paint through to the children.
- AdjustPaintOffsetScope adjustment(layout_box_, paint_info);
- PaintChildren(adjustment.GetPaintInfo());
+ PaintInfoWithOffset paint_info_with_offset(layout_box_, paint_info);
+ PaintChildren(paint_info_with_offset.GetPaintInfo());
}
void BoxPainter::PaintChildren(const PaintInfo& paint_info) {
@@ -78,7 +78,7 @@ void BoxPainter::PaintBoxDecorationBackground(const PaintInfo& paint_info,
}
paint_rect.MoveBy(paint_offset);
- PaintBoxDecorationBackgroundWithRect(paint_info, paint_offset, paint_rect);
+ PaintBoxDecorationBackgroundWithRect(paint_info, paint_rect);
}
LayoutRect BoxPainter::BoundsForDrawingRecorder(
@@ -96,7 +96,6 @@ LayoutRect BoxPainter::BoundsForDrawingRecorder(
void BoxPainter::PaintBoxDecorationBackgroundWithRect(
const PaintInfo& paint_info,
- const LayoutPoint& paint_offset,
const LayoutRect& paint_rect) {
bool painting_overflow_contents = BoxModelObjectPainter::
IsPaintingBackgroundOfPaintContainerIntoScrollingContentsLayer(
@@ -112,8 +111,7 @@ void BoxPainter::PaintBoxDecorationBackgroundWithRect(
// non-delayed-invalidation animated background, which should be ignored.
if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled() &&
(style.Appearance() == kMediaSliderPart ||
- layout_box_.FullPaintInvalidationReason() ==
- PaintInvalidationReason::kDelayedFull)) {
+ layout_box_.ShouldDelayFullPaintInvalidation())) {
cache_skipper.emplace(paint_info.context);
}
@@ -219,7 +217,7 @@ void BoxPainter::PaintBackground(const PaintInfo& paint_info,
BackgroundImageGeometry geometry(layout_box_);
BoxModelObjectPainter box_model_painter(layout_box_);
box_model_painter.PaintFillLayers(paint_info, background_color,
- layout_box_.Style()->BackgroundLayers(),
+ layout_box_.StyleRef().BackgroundLayers(),
paint_rect, geometry, bleed_avoidance);
}
@@ -228,7 +226,7 @@ void BoxPainter::PaintMask(const PaintInfo& paint_info,
DCHECK_EQ(PaintPhase::kMask, paint_info.phase);
if (!layout_box_.HasMask() ||
- layout_box_.Style()->Visibility() != EVisibility::kVisible)
+ layout_box_.StyleRef().Visibility() != EVisibility::kVisible)
return;
if (DrawingRecorder::UseCachedDrawingIfPossible(
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 1bfa1b2bdf1..f61315803e0 100644
--- a/chromium/third_party/blink/renderer/core/paint/box_painter.h
+++ b/chromium/third_party/blink/renderer/core/paint/box_painter.h
@@ -33,7 +33,6 @@ class BoxPainter {
void PaintMaskImages(const PaintInfo&, const LayoutRect&);
void PaintBoxDecorationBackgroundWithRect(const PaintInfo&,
- const LayoutPoint&,
const LayoutRect&);
LayoutRect BoundsForDrawingRecorder(const PaintInfo&,
const LayoutPoint& paint_offset);
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 441e273f7ee..4806f93e23f 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
@@ -572,9 +572,9 @@ LayoutRectOutsets AdjustOutsetsForEdgeInclusion(
} // anonymous namespace
-LayoutRectOutsets BoxPainterBase::BorderOutsets(
+LayoutRectOutsets BoxPainterBase::AdjustedBorderOutsets(
const FillLayerInfo& info) const {
- return AdjustOutsetsForEdgeInclusion(border_, info);
+ return AdjustOutsetsForEdgeInclusion(ComputeBorders(), info);
}
void BoxPainterBase::PaintFillLayer(const PaintInfo& paint_info,
@@ -623,7 +623,9 @@ void BoxPainterBase::PaintFillLayer(const PaintInfo& paint_info,
composite_op = (op == SkBlendMode::kSrcOver) ? bg_op : op;
}
- LayoutRectOutsets border_padding_insets = -(border_ + padding_);
+ LayoutRectOutsets border = ComputeBorders();
+ LayoutRectOutsets padding = ComputePadding();
+ LayoutRectOutsets border_padding_insets = -(border + padding);
FloatRoundedRect border_rect = RoundedBorderRectForClip(
style_, info, bg_layer, rect, object_has_multiple_boxes, flow_box_size,
bleed_avoidance, border_padding_insets);
@@ -659,9 +661,9 @@ void BoxPainterBase::PaintFillLayer(const PaintInfo& paint_info,
// Clip to the padding or content boxes as necessary.
LayoutRect clip_rect = scrolled_paint_rect;
- clip_rect.Contract(AdjustOutsetsForEdgeInclusion(border_, info));
+ clip_rect.Contract(AdjustOutsetsForEdgeInclusion(border, info));
if (bg_layer.Clip() == EFillBox::kContent)
- clip_rect.Contract(AdjustOutsetsForEdgeInclusion(padding_, info));
+ clip_rect.Contract(AdjustOutsetsForEdgeInclusion(padding, info));
background_clip_state_saver.Save();
// TODO(chrishtr): this should be pixel-snapped.
context.Clip(FloatRect(clip_rect));
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 9f4cb7909d3..f0cbcbda06f 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
@@ -5,7 +5,6 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_BOX_PAINTER_BASE_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_BOX_PAINTER_BASE_H_
-#include "base/optional.h"
#include "third_party/blink/renderer/core/layout/background_bleed_avoidance.h"
#include "third_party/blink/renderer/core/style/style_image.h"
#include "third_party/blink/renderer/platform/geometry/layout_rect_outsets.h"
@@ -36,14 +35,8 @@ class BoxPainterBase {
public:
BoxPainterBase(const Document* document,
const ComputedStyle& style,
- Node* node,
- LayoutRectOutsets border,
- LayoutRectOutsets padding)
- : document_(document),
- style_(style),
- node_(node),
- border_(border),
- padding_(padding) {}
+ Node* node)
+ : document_(document), style_(style), node_(node) {}
void PaintFillLayers(const PaintInfo&,
const Color&,
@@ -139,7 +132,9 @@ class BoxPainterBase {
};
protected:
- LayoutRectOutsets BorderOutsets(const FillLayerInfo&) const;
+ virtual LayoutRectOutsets ComputeBorders() const = 0;
+ virtual LayoutRectOutsets ComputePadding() const = 0;
+ LayoutRectOutsets AdjustedBorderOutsets(const FillLayerInfo&) const;
void PaintFillLayerTextFillBox(GraphicsContext&,
const FillLayerInfo&,
Image*,
@@ -169,8 +164,6 @@ class BoxPainterBase {
Member<const Document> document_;
const ComputedStyle& style_;
Member<Node> node_;
- const LayoutRectOutsets border_;
- const LayoutRectOutsets padding_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/collapsed_border_painter.cc b/chromium/third_party/blink/renderer/core/paint/collapsed_border_painter.cc
index 66d874d8132..445cd1fb5d0 100644
--- a/chromium/third_party/blink/renderer/core/paint/collapsed_border_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/collapsed_border_painter.cc
@@ -4,10 +4,10 @@
#include "third_party/blink/renderer/core/paint/collapsed_border_painter.h"
-#include "third_party/blink/renderer/core/paint/adjust_paint_offset_scope.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_info_with_offset.h"
#include "third_party/blink/renderer/core/paint/table_cell_painter.h"
namespace blink {
@@ -335,7 +335,7 @@ static EBorderStyle CollapsedBorderStyle(EBorderStyle style) {
void CollapsedBorderPainter::PaintCollapsedBorders(
const PaintInfo& paint_info) {
- if (cell_.Style()->Visibility() != EVisibility::kVisible)
+ if (cell_.StyleRef().Visibility() != EVisibility::kVisible)
return;
if (!cell_.GetCollapsedBorderValues())
@@ -350,10 +350,10 @@ void CollapsedBorderPainter::PaintCollapsedBorders(
// Now left=start_, right=end_, before_=top, after_=bottom.
// Collapsed borders are half inside and half outside of |rect|.
- AdjustPaintOffsetScope adjustment(cell_, paint_info);
+ PaintInfoWithOffset paint_info_with_offset(cell_, paint_info);
IntRect rect = PixelSnappedIntRect(
TableCellPainter(cell_).PaintRectNotIncludingVisualOverflow(
- adjustment.PaintOffset()));
+ paint_info_with_offset.PaintOffset()));
// |paint_rect| covers the whole collapsed borders.
IntRect paint_rect = rect;
paint_rect.Expand(IntRectOutsets(before_.outer_width, end_.outer_width,
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 5f13a443aff..08987bc62b4 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
@@ -95,16 +95,16 @@ static IntRect ContentsRect(const LayoutObject& layout_object) {
ToLayoutVideo(layout_object).ReplacedContentRect());
}
- return PixelSnappedIntRect(ToLayoutBox(layout_object).ContentBoxRect());
+ return PixelSnappedIntRect(
+ ToLayoutBox(layout_object).PhysicalContentBoxRect());
}
static IntRect BackgroundRect(const LayoutObject& layout_object) {
if (!layout_object.IsBox())
return IntRect();
- LayoutRect rect;
const LayoutBox& box = ToLayoutBox(layout_object);
- return PixelSnappedIntRect(box.BackgroundRect(kBackgroundClipRect));
+ return PixelSnappedIntRect(box.PhysicalBackgroundRect(kBackgroundClipRect));
}
static inline bool IsTextureLayerCanvas(const LayoutObject& layout_object) {
@@ -149,7 +149,7 @@ static bool ContentLayerSupportsDirectBackgroundComposition(
return false;
// If there is no background, there is nothing to support.
- if (!layout_object.Style()->HasBackground())
+ if (!layout_object.StyleRef().HasBackground())
return true;
// Simple background that is contained within the contents rect.
@@ -173,7 +173,7 @@ static inline bool IsAcceleratedContents(LayoutObject& layout_object) {
// Returns true if the compositor will be responsible for applying the sticky
// position offset for this composited layer.
static bool UsesCompositedStickyPosition(PaintLayer& layer) {
- return layer.GetLayoutObject().Style()->HasStickyConstrainedPosition() &&
+ return layer.GetLayoutObject().StyleRef().HasStickyConstrainedPosition() &&
layer.AncestorOverflowLayer()->NeedsCompositedScrolling();
}
@@ -208,12 +208,22 @@ CompositedLayerMapping::CompositedLayerMapping(PaintLayer& layer)
is_main_frame_layout_view_layer_ = true;
CreatePrimaryGraphicsLayer();
+
+ // ImagePainter has a micro-optimization to embed object-fit and clip into
+ // the drawing so the property nodes were omitted if not composited.
+ if (GetLayoutObject().IsLayoutImage())
+ GetLayoutObject().SetNeedsPaintPropertyUpdate();
}
CompositedLayerMapping::~CompositedLayerMapping() {
// Hits in compositing/squashing/squash-onto-nephew.html.
DisableCompositingQueryAsserts disabler;
+ // ImagePainter has a micro-optimization to embed object-fit and clip into
+ // the drawing so the property nodes should be omitted if not composited.
+ if (GetLayoutObject().IsLayoutImage())
+ GetLayoutObject().SetNeedsPaintPropertyUpdate();
+
// Do not leave the destroyed pointer dangling on any Layers that painted to
// this mapping's squashing layer.
for (size_t i = 0; i < squashed_layers_.size(); ++i) {
@@ -342,28 +352,22 @@ void CompositedLayerMapping::UpdateStickyConstraints(
constraints_map.at(&owning_layer_);
constraint.is_sticky = true;
- constraint.is_anchored_left =
- constraints.GetAnchorEdges() &
- StickyPositionScrollingConstraints::kAnchorEdgeLeft;
- constraint.is_anchored_right =
- constraints.GetAnchorEdges() &
- StickyPositionScrollingConstraints::kAnchorEdgeRight;
- constraint.is_anchored_top =
- constraints.GetAnchorEdges() &
- StickyPositionScrollingConstraints::kAnchorEdgeTop;
- constraint.is_anchored_bottom =
- constraints.GetAnchorEdges() &
- StickyPositionScrollingConstraints::kAnchorEdgeBottom;
- constraint.left_offset = constraints.LeftOffset();
- constraint.right_offset = constraints.RightOffset();
- constraint.top_offset = constraints.TopOffset();
- constraint.bottom_offset = constraints.BottomOffset();
+ constraint.is_anchored_left = constraints.is_anchored_left;
+ constraint.is_anchored_right = constraints.is_anchored_right;
+ constraint.is_anchored_top = constraints.is_anchored_top;
+ constraint.is_anchored_bottom = constraints.is_anchored_bottom;
+ constraint.left_offset = constraints.left_offset;
+ constraint.right_offset = constraints.right_offset;
+ constraint.top_offset = constraints.top_offset;
+ constraint.bottom_offset = constraints.bottom_offset;
+ constraint.constraint_box_rect =
+ GetLayoutObject().ComputeStickyConstrainingRect();
constraint.scroll_container_relative_sticky_box_rect =
- EnclosingIntRect(constraints.ScrollContainerRelativeStickyBoxRect());
- constraint.scroll_container_relative_containing_block_rect = EnclosingIntRect(
- constraints.ScrollContainerRelativeContainingBlockRect());
+ RoundedIntRect(constraints.scroll_container_relative_sticky_box_rect);
+ constraint.scroll_container_relative_containing_block_rect = RoundedIntRect(
+ constraints.scroll_container_relative_containing_block_rect);
PaintLayer* sticky_box_shifting_ancestor =
- constraints.NearestStickyLayerShiftingStickyBox();
+ constraints.nearest_sticky_layer_shifting_sticky_box;
if (sticky_box_shifting_ancestor &&
sticky_box_shifting_ancestor->GetCompositedLayerMapping()) {
constraint.nearest_element_shifting_sticky_box =
@@ -372,7 +376,7 @@ void CompositedLayerMapping::UpdateStickyConstraints(
->GetElementId();
}
PaintLayer* containing_block_shifting_ancestor =
- constraints.NearestStickyLayerShiftingContainingBlock();
+ constraints.nearest_sticky_layer_shifting_containing_block;
if (containing_block_shifting_ancestor &&
containing_block_shifting_ancestor->GetCompositedLayerMapping()) {
constraint.nearest_element_shifting_containing_block =
@@ -470,7 +474,7 @@ void CompositedLayerMapping::UpdateContentsOpaque() {
// this for solid color backgrounds the answer will be the same.
scrolling_contents_layer_->SetContentsOpaque(
owning_layer_.BackgroundIsKnownToBeOpaqueInRect(
- ToLayoutBox(GetLayoutObject()).PaddingBoxRect()));
+ ToLayoutBox(GetLayoutObject()).PhysicalPaddingBoxRect()));
if (owning_layer_.GetBackgroundPaintLocation() &
kBackgroundPaintInGraphicsLayer) {
@@ -596,7 +600,7 @@ bool CompositedLayerMapping::AncestorRoundedCornersWillClip(
// decorations.
if ((layer->GetLayoutObject().HasOverflowClip() ||
layer->GetLayoutObject().IsLayoutEmbeddedContent()) &&
- layer->GetLayoutObject().Style()->HasBorderRadius() &&
+ layer->GetLayoutObject().StyleRef().HasBorderRadius() &&
InContainingBlockChain(&owning_layer_, layer)) {
LayoutPoint delta;
layer->ConvertToLayerCoords(clip_inheritance_ancestor_, delta);
@@ -645,8 +649,10 @@ void CompositedLayerMapping::
// FIXME: this should use cached clip rects, but this sometimes give
// inaccurate results (and trips the ASSERTS in PaintLayerClipper).
ClipRectsContext clip_rects_context(
- clip_inheritance_ancestor_, kUncachedClipRects,
- kIgnorePlatformOverlayScrollbarSize, kIgnoreOverflowClip);
+ clip_inheritance_ancestor_,
+ &clip_inheritance_ancestor_->GetLayoutObject().FirstFragment(),
+ kUncachedClipRects, kIgnorePlatformOverlayScrollbarSize,
+ kIgnoreOverflowClip);
ClipRect clip_rect;
owning_layer_.Clipper(PaintLayer::kDoNotUseGeometryMapper)
@@ -761,16 +767,16 @@ bool CompositedLayerMapping::UpdateGraphicsLayerConfiguration(
// If the outline needs to draw over the composited scrolling contents layer
// or scrollbar layers it needs to be drawn into a separate layer.
- int min_border_width =
- std::min(layout_object.Style()->BorderTopWidth(),
- std::min(layout_object.Style()->BorderLeftWidth(),
- std::min(layout_object.Style()->BorderRightWidth(),
- layout_object.Style()->BorderBottomWidth())));
+ int min_border_width = std::min(
+ layout_object.StyleRef().BorderTopWidth(),
+ std::min(layout_object.StyleRef().BorderLeftWidth(),
+ std::min(layout_object.StyleRef().BorderRightWidth(),
+ layout_object.StyleRef().BorderBottomWidth())));
bool needs_decoration_outline_layer =
owning_layer_.GetScrollableArea() &&
owning_layer_.GetScrollableArea()->UsesCompositedScrolling() &&
- layout_object.Style()->HasOutline() &&
- layout_object.Style()->OutlineOffset() < -min_border_width;
+ layout_object.StyleRef().HasOutline() &&
+ layout_object.StyleRef().OutlineOffset() < -min_border_width;
if (UpdateDecorationOutlineLayer(needs_decoration_outline_layer))
layer_config_changed = true;
@@ -890,7 +896,8 @@ bool CompositedLayerMapping::UpdateGraphicsLayerConfiguration(
// Changes to either the internal hierarchy or the mask layer have an impact
// on painting phases, so we need to update when either are updated.
UpdatePaintingPhases();
- // Need to update paint property states of the changed GraphicsLayers.
+ // Need to update paint LayerState of the changed GraphicsLayers.
+ // The pre-paint tree walk does this.
layout_object.SetNeedsPaintPropertyUpdate();
}
@@ -1139,8 +1146,9 @@ void CompositedLayerMapping::UpdateSquashingLayerGeometry(
ToIntSize(graphics_layer_parent_location);
if (new_offset != squashing_layer_offset_from_layout_object_) {
squashing_layer_offset_from_layout_object_ = new_offset;
- // Need to update squashing layer state according to the new offset.
- OwningLayer().GetLayoutObject().SetNeedsPaintPropertyUpdate();
+ // Need to update squashing LayerState according to the new offset.
+ // The pre-paint tree walk does this.
+ GetLayoutObject().SetNeedsPaintPropertyUpdate();
}
*offset_from_transformed_ancestor =
@@ -1162,19 +1170,19 @@ void CompositedLayerMapping::UpdateGraphicsLayerGeometry(
// Set transform property, if it is not animating. We have to do this here
// because the transform is affected by the layer dimensions.
- if (!GetLayoutObject().Style()->IsRunningTransformAnimationOnCompositor())
+ if (!GetLayoutObject().StyleRef().IsRunningTransformAnimationOnCompositor())
UpdateTransform(GetLayoutObject().StyleRef());
// Set opacity, if it is not animating.
- if (!GetLayoutObject().Style()->IsRunningOpacityAnimationOnCompositor())
+ if (!GetLayoutObject().StyleRef().IsRunningOpacityAnimationOnCompositor())
UpdateOpacity(GetLayoutObject().StyleRef());
- if (!GetLayoutObject().Style()->IsRunningFilterAnimationOnCompositor())
+ if (!GetLayoutObject().StyleRef().IsRunningFilterAnimationOnCompositor())
UpdateFilters();
if (!GetLayoutObject()
- .Style()
- ->IsRunningBackdropFilterAnimationOnCompositor())
+ .StyleRef()
+ .IsRunningBackdropFilterAnimationOnCompositor())
UpdateBackdropFilters();
IntRect local_compositing_bounds;
@@ -1265,6 +1273,10 @@ void CompositedLayerMapping::UpdateGraphicsLayerGeometry(
}
void CompositedLayerMapping::UpdateOverscrollBehavior() {
+ // OverscrollBehavior directly set to scroll node when BGPT enabled.
+ if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled())
+ return;
+
EOverscrollBehavior behavior_x =
GetLayoutObject().StyleRef().OverscrollBehaviorX();
EOverscrollBehavior behavior_y =
@@ -1278,6 +1290,10 @@ void CompositedLayerMapping::UpdateOverscrollBehavior() {
}
void CompositedLayerMapping::UpdateSnapContainerData() {
+ // SnapContainerData directly set to scroll node when BGPT enabled.
+ if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled())
+ return;
+
if (!GetLayoutObject().IsBox() || !scrolling_contents_layer_)
return;
@@ -1318,7 +1334,7 @@ void CompositedLayerMapping::UpdateMainGraphicsLayerGeometry(
graphics_layer_->SetContentsVisible(contents_visible);
graphics_layer_->SetBackfaceVisibility(
- GetLayoutObject().Style()->BackfaceVisibility() ==
+ GetLayoutObject().StyleRef().BackfaceVisibility() ==
EBackfaceVisibility::kVisible);
}
@@ -1342,6 +1358,7 @@ void CompositedLayerMapping::ComputeGraphicsLayerParentLocation(
IntSize scroll_offset = layout_box.ScrolledContentOffset();
IntPoint scroll_origin =
compositing_container->GetScrollableArea()->ScrollOrigin();
+ scroll_origin.Move(-layout_box.OriginAdjustmentForScrollbars());
scroll_origin.Move(-layout_box.BorderLeft().ToInt(),
-layout_box.BorderTop().ToInt());
graphics_layer_parent_location = -(scroll_origin + scroll_offset);
@@ -1356,7 +1373,9 @@ void CompositedLayerMapping::UpdateAncestorClippingLayerGeometry(
return;
ClipRectsContext clip_rects_context(
- clip_inheritance_ancestor_, kPaintingClipRectsIgnoringOverflowClip,
+ clip_inheritance_ancestor_,
+ &clip_inheritance_ancestor_->GetLayoutObject().FirstFragment(),
+ kPaintingClipRectsIgnoringOverflowClip,
kIgnorePlatformOverlayScrollbarSize, kIgnoreOverflowClipAndScroll);
ClipRect clip_rect;
@@ -1422,6 +1441,11 @@ void CompositedLayerMapping::UpdateAncestorClippingLayerGeometry(
snapped_clip_rect.Location() - snapped_offset_from_composited_ancestor);
if (ancestor_clipping_mask_layer_) {
+ // Need to update LayerState for the new offset.
+ // The pre-paint tree walk does this.
+ if (ancestor_clipping_layer_->OffsetFromLayoutObject() !=
+ ancestor_clipping_mask_layer_->OffsetFromLayoutObject())
+ GetLayoutObject().SetNeedsPaintPropertyUpdate();
ancestor_clipping_mask_layer_->SetOffsetFromLayoutObject(
ancestor_clipping_layer_->OffsetFromLayoutObject());
ancestor_clipping_mask_layer_->SetSize(ancestor_clipping_layer_->Size());
@@ -1515,7 +1539,7 @@ void CompositedLayerMapping::UpdateOverflowControlsHostLayerGeometry(
overflow_controls_host_layer_->SetSize(border_box.Size());
overflow_controls_host_layer_->SetMasksToBounds(true);
overflow_controls_host_layer_->SetBackfaceVisibility(
- owning_layer_.GetLayoutObject().Style()->BackfaceVisibility() ==
+ owning_layer_.GetLayoutObject().StyleRef().BackfaceVisibility() ==
EBackfaceVisibility::kVisible);
}
@@ -1527,8 +1551,8 @@ void CompositedLayerMapping::UpdateChildContainmentLayerGeometry() {
if (GetLayoutObject().IsLayoutEmbeddedContent()) {
// Embedded content layers do not have a clipping rect defined,
// so use the PaddingBoxRect.
- IntRect clipping_box =
- PixelSnappedIntRect(ToLayoutBox(GetLayoutObject()).PaddingBoxRect());
+ IntRect clipping_box = PixelSnappedIntRect(
+ ToLayoutBox(GetLayoutObject()).PhysicalPaddingBoxRect());
child_containment_layer_->SetSize(clipping_box.Size());
child_containment_layer_->SetOffsetFromLayoutObject(
ToIntSize(clipping_box.Location()));
@@ -1550,7 +1574,7 @@ void CompositedLayerMapping::UpdateChildContainmentLayerGeometry() {
}
if (child_clipping_mask_layer_ && !scrolling_layer_ &&
- !GetLayoutObject().Style()->ClipPath()) {
+ !GetLayoutObject().StyleRef().ClipPath()) {
if (child_clipping_mask_layer_->Size() !=
child_containment_layer_->Size()) {
child_clipping_mask_layer_->SetSize(child_containment_layer_->Size());
@@ -1649,7 +1673,7 @@ void CompositedLayerMapping::UpdateScrollingLayerGeometry(
scrolling_layer_->SetOffsetFromLayoutObject(
ToIntSize(overflow_clip_rect.Location()));
- if (child_clipping_mask_layer_ && !GetLayoutObject().Style()->ClipPath()) {
+ if (child_clipping_mask_layer_ && !GetLayoutObject().StyleRef().ClipPath()) {
child_clipping_mask_layer_->SetPosition(scrolling_layer_->GetPosition());
if (child_clipping_mask_layer_->Size() != scrolling_layer_->Size()) {
child_clipping_mask_layer_->SetSize(scrolling_layer_->Size());
@@ -1659,12 +1683,10 @@ void CompositedLayerMapping::UpdateScrollingLayerGeometry(
ToIntSize(overflow_clip_rect.Location()));
}
- IntSize scroll_size =
- PixelSnappedIntRect(
- LayoutRect(
- LayoutPoint(owning_layer_.SubpixelAccumulation()),
- LayoutSize(layout_box.ScrollWidth(), layout_box.ScrollHeight())))
- .Size();
+ PaintLayerScrollableArea* scrollable_area = owning_layer_.GetScrollableArea();
+ IntSize scroll_size = scrollable_area->PixelSnappedContentsSize(
+ LayoutPoint(owning_layer_.SubpixelAccumulation()));
+
// Ensure scrolling contents are at least as large as the scroll clip
scroll_size = scroll_size.ExpandedTo(overflow_clip_rect.Size());
@@ -1678,40 +1700,24 @@ void CompositedLayerMapping::UpdateScrollingLayerGeometry(
if (scrolling_contents_offset != scrolling_contents_offset_ ||
scroll_size != scrolling_contents_layer_->Size() ||
scroll_container_size_changed) {
- bool coordinator_handles_offset = false;
auto* scrolling_coordinator = owning_layer_.GetScrollingCoordinator();
- auto* scrollable_area = owning_layer_.GetScrollableArea();
- if (scrolling_coordinator && scrollable_area) {
- coordinator_handles_offset =
- scrolling_coordinator->ScrollableAreaScrollLayerDidChange(
- scrollable_area);
- }
- scrolling_contents_layer_->SetPosition(
- coordinator_handles_offset ? FloatPoint()
- : FloatPoint(-ToFloatSize(scroll_position)));
+ scrolling_coordinator->ScrollableAreaScrollLayerDidChange(scrollable_area);
+ scrolling_contents_layer_->SetPosition(FloatPoint());
}
scrolling_contents_offset_ = scrolling_contents_offset;
scrolling_contents_layer_->SetSize(scroll_size);
- IntPoint scrolling_contents_layer_offset_from_layout_object;
- if (PaintLayerScrollableArea* scrollable_area =
- owning_layer_.GetScrollableArea()) {
- scrolling_contents_layer_offset_from_layout_object =
- -scrollable_area->ScrollOrigin();
- }
- scrolling_contents_layer_offset_from_layout_object.MoveBy(
- overflow_clip_rect.Location());
scrolling_contents_layer_->SetOffsetFromLayoutObject(
- ToIntSize(scrolling_contents_layer_offset_from_layout_object));
+ overflow_clip_rect.Location() - scrollable_area->ScrollOrigin());
}
void CompositedLayerMapping::UpdateChildClippingMaskLayerGeometry() {
- if (!child_clipping_mask_layer_ || !GetLayoutObject().Style()->ClipPath() ||
+ if (!child_clipping_mask_layer_ || !GetLayoutObject().StyleRef().ClipPath() ||
!GetLayoutObject().IsBox())
return;
LayoutBox& layout_box = ToLayoutBox(GetLayoutObject());
- IntRect padding_box = EnclosingIntRect(layout_box.PaddingBoxRect());
+ IntRect padding_box = EnclosingIntRect(layout_box.PhysicalPaddingBoxRect());
child_clipping_mask_layer_->SetPosition(graphics_layer_->GetPosition());
if (child_clipping_mask_layer_->Size() != graphics_layer_->Size()) {
@@ -2381,6 +2387,8 @@ void CompositedLayerMapping::UpdateShouldFlattenTransform() {
struct AnimatingData {
STACK_ALLOCATED();
+
+ public:
Persistent<Node> owning_node = nullptr;
Persistent<Element> animating_element = nullptr;
const ComputedStyle* animating_style = nullptr;
@@ -2895,7 +2903,8 @@ void CompositedLayerMapping::UpdateImageContents() {
LayoutObject::ShouldRespectImageOrientation(&image_layout_object));
graphics_layer_->SetFilterQuality(
- GetLayoutObject().Style()->ImageRendering() == EImageRendering::kPixelated
+ GetLayoutObject().StyleRef().ImageRendering() ==
+ EImageRendering::kPixelated
? kNone_SkFilterQuality
: kLow_SkFilterQuality);
@@ -3086,8 +3095,10 @@ void CompositedLayerMapping::LocalClipRectForSquashedLayer(
// FIXME: this is a potential performance issue. We should consider caching
// these clip rects or otherwise optimizing.
- ClipRectsContext clip_rects_context(ancestor_paint_info->paint_layer,
- kUncachedClipRects);
+ ClipRectsContext clip_rects_context(
+ ancestor_paint_info->paint_layer,
+ &ancestor_paint_info->paint_layer->GetLayoutObject().FirstFragment(),
+ kUncachedClipRects);
ClipRect parent_clip_rect;
paint_info.paint_layer->Clipper(PaintLayer::kDoNotUseGeometryMapper)
.CalculateBackgroundClipRect(clip_rects_context, parent_clip_rect);
@@ -3106,7 +3117,7 @@ void CompositedLayerMapping::LocalClipRectForSquashedLayer(
void CompositedLayerMapping::DoPaintTask(
const GraphicsLayerPaintInfo& paint_info,
const GraphicsLayer& graphics_layer,
- const PaintLayerFlags& paint_layer_flags,
+ PaintLayerFlags paint_layer_flags,
GraphicsContext& context,
const IntRect& clip /* In the coords of rootLayer */) const {
FontCachePurgePreventer font_cache_purge_preventer;
@@ -3436,11 +3447,7 @@ void CompositedLayerMapping::PaintContents(
graphics_layer == scrolling_contents_layer_.get() ||
graphics_layer == decoration_outline_layer_.get() ||
graphics_layer == ancestor_clipping_mask_layer_.get()) {
- bool paint_root_background_onto_scrolling_contents_layer =
- background_paints_onto_scrolling_contents_layer_;
- DCHECK(!paint_root_background_onto_scrolling_contents_layer ||
- !foreground_layer_);
- if (paint_root_background_onto_scrolling_contents_layer) {
+ if (background_paints_onto_scrolling_contents_layer_) {
if (graphics_layer == scrolling_contents_layer_.get())
paint_layer_flags &= ~kPaintLayerPaintingSkipRootBackground;
else if (!background_paints_onto_graphics_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 36ca4fc651c..dba808678df 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
@@ -465,7 +465,7 @@ class CORE_EXPORT CompositedLayerMapping final : public GraphicsLayerClient {
void DoPaintTask(const GraphicsLayerPaintInfo&,
const GraphicsLayer&,
- const PaintLayerFlags&,
+ PaintLayerFlags,
GraphicsContext&,
const IntRect& clip) const;
@@ -531,7 +531,7 @@ class CORE_EXPORT CompositedLayerMapping final : public GraphicsLayerClient {
// + overflow_controls_ancestor_clipping_layer_ [OPTIONAL]
// | + overflow_controls_host_layer_ [OPTIONAL]
// | + layer_for_vertical_scrollbar_ [OPTIONAL]
- // | + layer_for_vertical_scrollbar_ [OPTIONAL]
+ // | + layer_for_horizontal_scrollbar_ [OPTIONAL]
// | + layer_for_scroll_corner_ [OPTIONAL]
// + decoration_outline_layer_ [OPTIONAL]
// The overflow controls may need to be repositioned in the graphics layer
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 bc5f72982a3..9ffadd6340f 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
@@ -1038,8 +1038,7 @@ TEST_F(CompositedLayerMappingTest,
mapping->ForegroundLayer()->PaintingPhase());
// Regression test for crbug.com/767908: a foreground layer should also
// participates hit testing.
- EXPECT_TRUE(mapping->ForegroundLayer()
- ->GetHitTestableWithoutDrawsContentForTesting());
+ EXPECT_TRUE(mapping->ForegroundLayer()->GetHitTestableWithoutDrawsContent());
Element* negative_composited_child =
GetDocument().getElementById("negative-composited-child");
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/composited_selection.h b/chromium/third_party/blink/renderer/core/paint/compositing/composited_selection.h
deleted file mode 100644
index 808b2f50ea7..00000000000
--- a/chromium/third_party/blink/renderer/core/paint/compositing/composited_selection.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2015 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_CORE_PAINT_COMPOSITING_COMPOSITED_SELECTION_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_COMPOSITING_COMPOSITED_SELECTION_H_
-
-#include "third_party/blink/renderer/core/editing/selection_type.h"
-#include "third_party/blink/renderer/core/paint/compositing/composited_selection_bound.h"
-#include "third_party/blink/renderer/platform/geometry/float_point.h"
-#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
-#include "third_party/blink/renderer/platform/wtf/allocator.h"
-
-namespace blink {
-
-// The active selection region, containing compositing data for the selection
-// end points as well as metadata for the selection region. Maps to a
-// cc::LayerSelection when the |type| is not kNoSelection.
-struct CompositedSelection {
- STACK_ALLOCATED();
- CompositedSelection() : type(kNoSelection) {}
-
- SelectionType type;
- CompositedSelectionBound start;
- CompositedSelectionBound end;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_COMPOSITING_COMPOSITED_SELECTION_H_
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/composited_selection_bound.h b/chromium/third_party/blink/renderer/core/paint/compositing/composited_selection_bound.h
deleted file mode 100644
index c7253034911..00000000000
--- a/chromium/third_party/blink/renderer/core/paint/compositing/composited_selection_bound.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2014 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_COMPOSITING_COMPOSITED_SELECTION_BOUND_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_COMPOSITING_COMPOSITED_SELECTION_BOUND_H_
-
-#include "third_party/blink/renderer/platform/geometry/float_point.h"
-#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
-#include "third_party/blink/renderer/platform/wtf/allocator.h"
-
-namespace blink {
-
-struct CompositedSelectionBound {
- STACK_ALLOCATED();
- CompositedSelectionBound()
- : layer(nullptr), is_text_direction_rtl(false), hidden(false) {}
-
- // The structure describes the position of a caret in space of the
- // GraphicsLayer the caret resides in. Where edgeTopInLayer is the top point
- // of the caret, usually on the ascend line of the line box, and
- // edgeBottomInLayer it the bottom point, on the baseline of the line box.
- GraphicsLayer* layer;
- FloatPoint edge_top_in_layer;
- FloatPoint edge_bottom_in_layer;
-
- bool is_text_direction_rtl;
-
- // Whether this bound is hidden (clipped out/occluded).
- bool hidden;
-};
-
-} // namespace blink
-
-#endif
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 f7e9bdc5724..60fcf54f708 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
@@ -80,14 +80,31 @@ void CompositingInputsUpdater::UpdateRecursive(PaintLayer* layer,
geometry_map_.PushMappingsToAncestor(layer, layer->Parent());
- PaintLayer* enclosing_composited_layer =
- layer->HasCompositedLayerMapping() ? layer
- : info.enclosing_composited_layer;
+ PaintLayer* enclosing_composited_layer = info.enclosing_composited_layer;
+ PaintLayer* enclosing_squashing_composited_layer =
+ info.enclosing_squashing_composited_layer;
+ switch (layer->GetCompositingState()) {
+ case kNotComposited:
+ break;
+ case kPaintsIntoOwnBacking:
+ enclosing_composited_layer = layer;
+ break;
+ case kPaintsIntoGroupedBacking:
+ enclosing_squashing_composited_layer =
+ &layer->GroupedMapping()->OwningLayer();
+ break;
+ }
+
if (layer->NeedsCompositingInputsUpdate()) {
if (enclosing_composited_layer) {
enclosing_composited_layer->GetCompositedLayerMapping()
->SetNeedsGraphicsLayerUpdate(kGraphicsLayerUpdateSubtree);
}
+ if (enclosing_squashing_composited_layer) {
+ enclosing_squashing_composited_layer->GetCompositedLayerMapping()
+ ->SetNeedsGraphicsLayerUpdate(kGraphicsLayerUpdateSubtree);
+ }
+
update_type = kForceUpdate;
}
@@ -105,6 +122,8 @@ void CompositingInputsUpdater::UpdateRecursive(PaintLayer* layer,
UpdateAncestorDependentCompositingInputs(layer, info);
info.enclosing_composited_layer = enclosing_composited_layer;
+ info.enclosing_squashing_composited_layer =
+ enclosing_squashing_composited_layer;
if (layer->IsRootLayer() || layout_object.HasOverflowClip())
info.last_overflow_clip_layer = layer;
@@ -291,6 +310,7 @@ void CompositingInputsUpdater::UpdateAncestorDependentCompositingInputs(
layer->Clipper(PaintLayer::kDoNotUseGeometryMapper)
.CalculateBackgroundClipRect(
ClipRectsContext(root_layer_,
+ &root_layer_->GetLayoutObject().FirstFragment(),
kAbsoluteClipRectsIgnoringViewportClip,
kIgnorePlatformOverlayScrollbarSize,
kIgnoreOverflowClipAndScroll),
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.h b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.h
index a7c07a1eac4..5303a1e9cc2 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.h
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.h
@@ -36,6 +36,10 @@ class CompositingInputsUpdater {
struct AncestorInfo {
PaintLayer* enclosing_composited_layer = nullptr;
+ // A "squashing composited layer" is a PaintLayer that owns a squashing
+ // layer. This variable stores the squashing composited layer for the
+ // nearest PaintLayer ancestor which is squashed.
+ PaintLayer* enclosing_squashing_composited_layer = nullptr;
PaintLayer* last_overflow_clip_layer = nullptr;
PaintLayer* clip_chain_parent_for_absolute = nullptr;
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 7c36d148bed..1e011f6df64 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
@@ -158,8 +158,8 @@ CompositingLayerAssigner::GetReasonsPreventingSquashing(
if (SquashingWouldExceedSparsityTolerance(layer, squashing_state))
return SquashingDisallowedReason::kSquashingSparsityExceeded;
- if (layer->GetLayoutObject().Style()->HasBlendMode() ||
- squashing_layer.GetLayoutObject().Style()->HasBlendMode())
+ if (layer->GetLayoutObject().StyleRef().HasBlendMode() ||
+ squashing_layer.GetLayoutObject().StyleRef().HasBlendMode())
return SquashingDisallowedReason::kSquashingBlendingIsDisallowed;
if (layer->ClippingContainer() != squashing_layer.ClippingContainer() &&
@@ -196,15 +196,18 @@ CompositingLayerAssigner::GetReasonsPreventingSquashing(
if (layer->NearestFixedPositionLayer() !=
squashing_layer.NearestFixedPositionLayer())
return SquashingDisallowedReason::kNearestFixedPositionMismatch;
- DCHECK_NE(layer->GetLayoutObject().Style()->GetPosition(), EPosition::kFixed);
+ DCHECK_NE(layer->GetLayoutObject().StyleRef().GetPosition(),
+ EPosition::kFixed);
- if ((squashing_layer.GetLayoutObject().Style()->SubtreeWillChangeContents() &&
+ if ((squashing_layer.GetLayoutObject()
+ .StyleRef()
+ .SubtreeWillChangeContents() &&
squashing_layer.GetLayoutObject()
- .Style()
- ->IsRunningAnimationOnCompositor()) ||
+ .StyleRef()
+ .IsRunningAnimationOnCompositor()) ||
squashing_layer.GetLayoutObject()
- .Style()
- ->ShouldCompositeForCurrentAnimations())
+ .StyleRef()
+ .ShouldCompositeForCurrentAnimations())
return SquashingDisallowedReason::kSquashingLayerIsAnimating;
if (layer->EnclosingPaginationLayer())
@@ -311,8 +314,8 @@ void CompositingLayerAssigner::AssignLayersToBackingsInternal(
if (ScrollingCoordinator* scrolling_coordinator =
layer->GetScrollingCoordinator()) {
if (layer->GetLayoutObject()
- .Style()
- ->HasViewportConstrainedPosition()) {
+ .StyleRef()
+ .HasViewportConstrainedPosition()) {
scrolling_coordinator->FrameViewFixedObjectsDidChange(
layer->GetLayoutObject().View()->GetFrameView());
}
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 690b49674b0..2c974bb35ad 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
@@ -256,15 +256,19 @@ bool CompositingReasonFinder::RequiresCompositingForRootScroller(
const PaintLayer& layer) {
// The root scroller needs composited scrolling layers even if it doesn't
// actually have scrolling since CC has these assumptions baked in for the
- // viewport.
+ // viewport. Because this is only needed for CC, we can skip it if compositing
+ // is not enabled.
+ const auto& settings = *layer.GetLayoutObject().GetDocument().GetSettings();
+ if (!settings.GetAcceleratedCompositingEnabled())
+ return false;
return RootScrollerUtil::IsGlobal(layer);
}
bool CompositingReasonFinder::RequiresCompositingForScrollDependentPosition(
const PaintLayer* layer,
bool ignore_lcd_text) const {
- if (!layer->GetLayoutObject().Style()->HasViewportConstrainedPosition() &&
- !layer->GetLayoutObject().Style()->HasStickyConstrainedPosition())
+ if (!layer->GetLayoutObject().StyleRef().HasViewportConstrainedPosition() &&
+ !layer->GetLayoutObject().StyleRef().HasStickyConstrainedPosition())
return false;
if (!(ignore_lcd_text ||
@@ -278,7 +282,7 @@ bool CompositingReasonFinder::RequiresCompositingForScrollDependentPosition(
// Don't promote fixed position elements that are descendants of a non-view
// container, e.g. transformed elements. They will stay fixed wrt the
// container rather than the enclosing frame.
- EPosition position = layer->GetLayoutObject().Style()->GetPosition();
+ EPosition position = layer->GetLayoutObject().StyleRef().GetPosition();
if (position == EPosition::kFixed) {
return layer->FixedToViewport() &&
layout_view_.GetFrameView()->LayoutViewport()->ScrollsOverflow();
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 b32df08233c..e02efa25f26 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
@@ -196,7 +196,6 @@ TEST_F(CompositingReasonFinderTest, OnlyNonTransformedFixedLayersPromoted) {
</div>
)HTML");
- EXPECT_TRUE(RuntimeEnabledFeatures::CompositeOpaqueScrollersEnabled());
Element* parent = GetDocument().getElementById("parent");
Element* fixed = GetDocument().getElementById("fixed");
PaintLayer* paint_layer =
@@ -245,7 +244,6 @@ TEST_F(CompositingReasonFinderTest, OnlyOpaqueFixedLayersPromoted) {
</div>
)HTML");
- EXPECT_TRUE(RuntimeEnabledFeatures::CompositeOpaqueScrollersEnabled());
Element* parent = GetDocument().getElementById("parent");
Element* fixed = GetDocument().getElementById("fixed");
PaintLayer* paint_layer =
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 f4d972924de..3e89c89aca2 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
@@ -192,7 +192,7 @@ static CompositingReasons SubtreeReasonsForCompositing(
//
// TODO(smcgruer): Only composite fixed if needed (http://crbug.com/742213)
const bool ignore_lcd_text = true;
- if (layer->GetLayoutObject().Style()->GetPosition() == EPosition::kFixed ||
+ if (layer->GetLayoutObject().StyleRef().GetPosition() == EPosition::kFixed ||
compositing_reason_finder.RequiresCompositingForScrollDependentPosition(
layer, ignore_lcd_text)) {
subtree_reasons |=
@@ -275,7 +275,7 @@ void CompositingRequirementsUpdater::UpdateRecursive(
bool has_non_root_composited_scrolling_ancestor =
layer->AncestorScrollingLayer() &&
layer->AncestorScrollingLayer()->GetScrollableArea() &&
- layer->AncestorScrollingLayer()->DirectCompositingReasons() &&
+ layer->AncestorScrollingLayer()->NeedsCompositedScrolling() &&
!layer->AncestorScrollingLayer()->IsRootLayer();
bool use_clipped_bounding_rect = !has_non_root_composited_scrolling_ancestor;
@@ -360,13 +360,13 @@ void CompositingRequirementsUpdater::UpdateRecursive(
unclipped_descendants.EraseAt(unclipped_descendants_to_remove.at(
unclipped_descendants_to_remove.size() - i - 1));
}
+ }
- if (reasons_to_composite & CompositingReason::kOutOfFlowClipping) {
- // TODO(schenney): We only need to promote when the clipParent is not a
- // descendant of the ancestor scroller, which we do not check for here.
- // Hence we might be promoting needlessly.
- unclipped_descendants.push_back(layer);
- }
+ if (reasons_to_composite & CompositingReason::kOutOfFlowClipping) {
+ // TODO(schenney): We only need to promote when the clipParent is not a
+ // descendant of the ancestor scroller, which we do not check for here.
+ // Hence we might be promoting needlessly.
+ unclipped_descendants.push_back(layer);
}
IntRect abs_bounds = use_clipped_bounding_rect
@@ -445,7 +445,7 @@ void CompositingRequirementsUpdater::UpdateRecursive(
!layer->DescendantHasDirectOrScrollingCompositingReason() &&
!needs_recursion_for_composited_scrolling_plus_fixed_or_sticky &&
!needs_recursion_for_out_of_flow_descendant &&
- layer->GetLayoutObject().HasOverflowClip() &&
+ layer->GetLayoutObject().ShouldClipOverflow() &&
!layer->HasCompositingDescendant() &&
!layer->DescendantMayNeedCompositingRequirementsUpdate();
@@ -606,7 +606,7 @@ void CompositingRequirementsUpdater::UpdateRecursive(
}
if (will_be_composited_or_squashed &&
- layer->GetLayoutObject().Style()->HasBlendMode()) {
+ layer->GetLayoutObject().StyleRef().HasBlendMode()) {
current_recursion_data.has_unisolated_composited_blending_descendant_ =
true;
}
@@ -627,7 +627,7 @@ void CompositingRequirementsUpdater::UpdateRecursive(
reasons_to_composite & CompositingReason::kInlineTransform;
if ((!child_recursion_data.testing_overlap_ &&
!is_composited_clipping_layer) ||
- layer->GetLayoutObject().Style()->HasCurrentTransformAnimation() ||
+ layer->GetLayoutObject().StyleRef().HasCurrentTransformAnimation() ||
is_composited_with_inline_transform)
current_recursion_data.testing_overlap_ = false;
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 ee6e7881dd5..489b8d3b87e 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
@@ -4,11 +4,11 @@
#include "third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_as_text.h"
+#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
#include "third_party/blink/renderer/platform/geometry/geometry_as_json.h"
#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
#include "third_party/blink/renderer/platform/graphics/logging_canvas.h"
#include "third_party/blink/renderer/platform/json/json_values.h"
-#include "third_party/blink/renderer/platform/scroll/scrollable_area.h"
#include "third_party/blink/renderer/platform/wtf/text/text_stream.h"
namespace blink {
@@ -352,6 +352,24 @@ String GraphicsLayerTreeAsTextForTesting(const GraphicsLayer* layer,
return GraphicsLayerTreeAsJSON(layer, flags)->ToPrettyJSONString();
}
+#if DCHECK_IS_ON()
+void VerboseLogGraphicsLayerTree(const GraphicsLayer* root) {
+ if (!VLOG_IS_ON(2))
+ return;
+
+ using GraphicsLayerTreeMap = HashMap<const GraphicsLayer*, String>;
+ DEFINE_STATIC_LOCAL(GraphicsLayerTreeMap, s_previous_trees, ());
+ LayerTreeFlags flags = VLOG_IS_ON(3) ? 0xffffffff : kOutputAsLayerTree;
+ String new_tree = GraphicsLayerTreeAsTextForTesting(root, flags);
+ auto it = s_previous_trees.find(root);
+ if (it == s_previous_trees.end() || it->value != new_tree) {
+ VLOG(2) << "GraphicsLayer tree:\n" << new_tree.Utf8().data();
+ s_previous_trees.Set(root, new_tree);
+ // For simplification, we don't remove deleted GraphicsLayers from the map.
+ }
+}
+#endif
+
} // namespace blink
#if DCHECK_IS_ON()
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_as_text.h b/chromium/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_as_text.h
index ac28082114d..204e3345252 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_as_text.h
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_as_text.h
@@ -21,6 +21,9 @@ std::unique_ptr<JSONObject> GraphicsLayerTreeAsJSON(const GraphicsLayer*,
String CORE_EXPORT GraphicsLayerTreeAsTextForTesting(const GraphicsLayer*,
LayerTreeFlags);
+#if DCHECK_IS_ON()
+void CORE_EXPORT VerboseLogGraphicsLayerTree(const GraphicsLayer*);
+#endif
} // namespace blink
#if DCHECK_IS_ON()
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 9b87b5cd9eb..9dd55234913 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
@@ -309,11 +309,6 @@ void PaintLayerCompositor::DidLayout() {
// isScrollable method would return a different value.
root_should_always_composite_dirty_ = true;
EnableCompositingModeIfNeeded();
-
- // FIXME: Rather than marking the entire LayoutView as dirty, we should
- // track which Layers moved during layout and only dirty those
- // specific Layers.
- RootLayer()->SetNeedsCompositingInputsUpdate();
}
#if DCHECK_IS_ON()
@@ -325,40 +320,48 @@ void PaintLayerCompositor::AssertNoUnresolvedDirtyBits() {
#endif
-void PaintLayerCompositor::ApplyOverlayFullscreenVideoAdjustmentIfNeeded() {
- in_overlay_fullscreen_video_ = false;
- GraphicsLayer* content_parent = ParentForContentLayers();
- if (!content_parent)
- return;
-
- bool is_local_root = layout_view_.GetFrame()->IsLocalRoot();
+GraphicsLayer* PaintLayerCompositor::OverlayFullscreenVideoGraphicsLayer() {
LayoutVideo* video =
FindFullscreenVideoLayoutObject(layout_view_.GetDocument());
if (!video || !video->Layer()->HasCompositedLayerMapping() ||
!video->VideoElement()->UsesOverlayFullscreenVideo()) {
- return;
+ return nullptr;
}
- GraphicsLayer* video_layer =
- video->Layer()->GetCompositedLayerMapping()->MainGraphicsLayer();
+ return video->Layer()->GetCompositedLayerMapping()->MainGraphicsLayer();
+}
- // The fullscreen video has layer position equal to its enclosing frame's
- // scroll position because fullscreen container is fixed-positioned.
- // We should reset layer position here since we are going to reattach the
- // layer at the very top level.
- video_layer->SetPosition(FloatPoint());
+void PaintLayerCompositor::ApplyOverlayFullscreenVideoAdjustmentIfNeeded() {
+ in_overlay_fullscreen_video_ = false;
+ GraphicsLayer* content_parent = ParentForContentLayers();
+ if (!content_parent)
+ return;
+
+ bool is_local_root = layout_view_.GetFrame()->IsLocalRoot();
+ GraphicsLayer* video_layer = OverlayFullscreenVideoGraphicsLayer();
+ AdjustOverlayFullscreenVideoPosition(video_layer);
// Only steal fullscreen video layer and clear all other layers if we are the
// main frame.
- if (!is_local_root)
+ if (!is_local_root || !video_layer)
return;
content_parent->RemoveAllChildren();
content_parent->AddChild(video_layer);
-
in_overlay_fullscreen_video_ = true;
}
+void PaintLayerCompositor::AdjustOverlayFullscreenVideoPosition(
+ GraphicsLayer* video_layer) {
+ if (!video_layer)
+ return;
+ // The fullscreen video has layer position equal to its enclosing frame's
+ // scroll position because fullscreen container is fixed-positioned.
+ // We should reset layer position here since it is attached at the
+ // very top level.
+ video_layer->SetPosition(FloatPoint());
+}
+
void PaintLayerCompositor::UpdateWithoutAcceleratedCompositing(
CompositingUpdateType update_type) {
DCHECK(!HasAcceleratedCompositing());
@@ -474,16 +477,6 @@ void PaintLayerCompositor::UpdateIfNeeded(
CompositingLayerAssigner layer_assigner(this);
layer_assigner.Assign(update_root, layers_needing_paint_invalidation);
- {
- TRACE_EVENT0("blink",
- "PaintLayerCompositor::updateAfterCompositingChange");
- if (const LocalFrameView::ScrollableAreaSet* scrollable_areas =
- layout_view_.GetFrameView()->ScrollableAreas()) {
- for (PaintLayerScrollableArea* scrollable_area : *scrollable_areas)
- scrollable_area->UpdateAfterCompositingChange();
- }
- }
-
if (layer_assigner.LayersChanged()) {
update_type = std::max(update_type, kCompositingUpdateRebuildTree);
if (ScrollingCoordinator* scrolling_coordinator =
@@ -542,8 +535,9 @@ void PaintLayerCompositor::UpdateIfNeeded(
content_parent->SetChildren(child_list);
}
}
-
ApplyOverlayFullscreenVideoAdjustmentIfNeeded();
+ } else {
+ AdjustOverlayFullscreenVideoPosition(OverlayFullscreenVideoGraphicsLayer());
}
for (unsigned i = 0; i < layers_needing_paint_invalidation.size(); i++) {
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 60d3b44b869..7cf3856bd75 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
@@ -185,6 +185,8 @@ class CORE_EXPORT PaintLayerCompositor {
void EnableCompositingModeIfNeeded();
void ApplyOverlayFullscreenVideoAdjustmentIfNeeded();
+ void AdjustOverlayFullscreenVideoPosition(GraphicsLayer*);
+ GraphicsLayer* OverlayFullscreenVideoGraphicsLayer();
// Checks the given graphics layer against the compositor's horizontal and
// vertical scrollbar graphics layers, returning the associated Scrollbar
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 8032067fad5..1fa15cbb008 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
@@ -64,7 +64,7 @@ ColorFilter CSSMaskPainter::MaskColorFilter(const LayoutObject& object) {
LayoutSVGResourceMasker* masker = resources ? resources->Masker() : nullptr;
if (!masker)
return kColorFilterNone;
- return masker->Style()->SvgStyle().MaskType() == MT_LUMINANCE
+ return masker->StyleRef().SvgStyle().MaskType() == MT_LUMINANCE
? kColorFilterLuminanceToAlpha
: kColorFilterNone;
}
diff --git a/chromium/third_party/blink/renderer/core/paint/decoration_info.h b/chromium/third_party/blink/renderer/core/paint/decoration_info.h
index bd56be60526..a3147cecdcd 100644
--- a/chromium/third_party/blink/renderer/core/paint/decoration_info.h
+++ b/chromium/third_party/blink/renderer/core/paint/decoration_info.h
@@ -23,6 +23,7 @@ enum class ResolvedUnderlinePosition { kRoman, kUnder, kOver };
struct DecorationInfo final {
STACK_ALLOCATED();
+ public:
LayoutUnit width;
FloatPoint local_origin;
bool antialias;
diff --git a/chromium/third_party/blink/renderer/core/paint/details_marker_painter.cc b/chromium/third_party/blink/renderer/core/paint/details_marker_painter.cc
index 7f1868f9870..cb86964b27f 100644
--- a/chromium/third_party/blink/renderer/core/paint/details_marker_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/details_marker_painter.cc
@@ -5,9 +5,9 @@
#include "third_party/blink/renderer/core/paint/details_marker_painter.h"
#include "third_party/blink/renderer/core/layout/layout_details_marker.h"
-#include "third_party/blink/renderer/core/paint/adjust_paint_offset_scope.h"
#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/paint_info_with_offset.h"
#include "third_party/blink/renderer/platform/geometry/layout_point.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
#include "third_party/blink/renderer/platform/graphics/path.h"
@@ -16,7 +16,7 @@ namespace blink {
void DetailsMarkerPainter::Paint(const PaintInfo& paint_info) {
if (paint_info.phase != PaintPhase::kForeground ||
- layout_details_marker_.Style()->Visibility() != EVisibility::kVisible) {
+ layout_details_marker_.StyleRef().Visibility() != EVisibility::kVisible) {
BlockPainter(layout_details_marker_).Paint(paint_info);
return;
}
@@ -25,20 +25,19 @@ void DetailsMarkerPainter::Paint(const PaintInfo& paint_info) {
paint_info.context, layout_details_marker_, paint_info.phase))
return;
- AdjustPaintOffsetScope adjustment(layout_details_marker_, paint_info);
- const auto& local_paint_info = adjustment.GetPaintInfo();
- auto box_origin = adjustment.PaintOffset();
- LayoutRect overflow_rect(layout_details_marker_.VisualOverflowRect());
- overflow_rect.MoveBy(box_origin);
-
- if (!local_paint_info.GetCullRect().IntersectsCullRect(overflow_rect))
+ PaintInfoWithOffset paint_info_with_offset(layout_details_marker_,
+ paint_info);
+ if (!paint_info_with_offset.LocalRectIntersectsCullRect(
+ layout_details_marker_.PhysicalVisualOverflowRect()))
return;
+ const auto& local_paint_info = paint_info_with_offset.GetPaintInfo();
DrawingRecorder recorder(local_paint_info.context, layout_details_marker_,
local_paint_info.phase);
const Color color(layout_details_marker_.ResolveColor(GetCSSPropertyColor()));
local_paint_info.context.SetFillColor(color);
+ auto box_origin = paint_info_with_offset.PaintOffset();
box_origin.Move(
layout_details_marker_.BorderLeft() +
layout_details_marker_.PaddingLeft(),
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 40624d469f5..4777c420468 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
@@ -141,7 +141,6 @@ void DrawDocumentMarker(GraphicsContext& context,
} // anonymous ns
-// TODO(yoichio) : Move this to document_marker_painter.cc
void DocumentMarkerPainter::PaintStyleableMarkerUnderline(
GraphicsContext& context,
const LayoutPoint& box_origin,
@@ -176,6 +175,9 @@ void DocumentMarkerPainter::PaintStyleableMarkerUnderline(
if (marker.HasThicknessThick() && logical_height.ToInt() - baseline >= 2)
line_thickness = 2;
+ // Line thickness should change with zoom.
+ line_thickness *= style.EffectiveZoom();
+
Color marker_color =
marker.UseTextColor()
? style.VisitedDependentColor(GetCSSPropertyWebkitTextFillColor())
@@ -192,7 +194,6 @@ void DocumentMarkerPainter::PaintStyleableMarkerUnderline(
static const int kMisspellingLineThickness = 3;
-// TODO(yoichio): Move this to document_marker_painter.cc
void DocumentMarkerPainter::PaintDocumentMarker(
GraphicsContext& context,
const LayoutPoint& box_origin,
diff --git a/chromium/third_party/blink/renderer/core/paint/embedded_content_painter.cc b/chromium/third_party/blink/renderer/core/paint/embedded_content_painter.cc
index 6945ceba555..4c70338b6b8 100644
--- a/chromium/third_party/blink/renderer/core/paint/embedded_content_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/embedded_content_painter.cc
@@ -7,10 +7,10 @@
#include "base/optional.h"
#include "third_party/blink/renderer/core/frame/embedded_content_view.h"
#include "third_party/blink/renderer/core/layout/layout_embedded_content.h"
-#include "third_party/blink/renderer/core/paint/adjust_paint_offset_scope.h"
#include "third_party/blink/renderer/core/paint/box_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_info_with_offset.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/core/paint/replaced_painter.h"
#include "third_party/blink/renderer/core/paint/scrollable_area_painter.h"
@@ -20,105 +20,12 @@
namespace blink {
-bool EmbeddedContentPainter::IsSelected() const {
- SelectionState s = layout_embedded_content_.GetSelectionState();
- if (s == SelectionState::kNone)
- return false;
-
- return true;
-}
-
-void EmbeddedContentPainter::Paint(const PaintInfo& paint_info) {
- // TODO(crbug.com/797779): For now embedded contents don't know whether
- // they are painted in a fragmented context and may do something bad in a
- // fragmented context, e.g. creating subsequences. Skip cache to avoid that.
- // This will be unnecessary when the contents are fragment aware.
- base::Optional<DisplayItemCacheSkipper> cache_skipper;
- DCHECK(layout_embedded_content_.HasLayer());
- if (layout_embedded_content_.Layer()->EnclosingPaginationLayer())
- cache_skipper.emplace(paint_info.context);
-
- AdjustPaintOffsetScope adjustment(layout_embedded_content_, paint_info);
- const auto& local_paint_info = adjustment.GetPaintInfo();
- auto paint_offset = adjustment.PaintOffset();
- if (!ReplacedPainter(layout_embedded_content_)
- .ShouldPaint(local_paint_info, paint_offset))
- return;
-
- LayoutRect border_rect(paint_offset, layout_embedded_content_.Size());
-
- if (layout_embedded_content_.HasBoxDecorationBackground() &&
- (local_paint_info.phase == PaintPhase::kForeground ||
- local_paint_info.phase == PaintPhase::kSelection)) {
- BoxPainter(layout_embedded_content_)
- .PaintBoxDecorationBackground(local_paint_info, paint_offset);
- }
-
- if (local_paint_info.phase == PaintPhase::kMask) {
- BoxPainter(layout_embedded_content_)
- .PaintMask(local_paint_info, paint_offset);
- return;
- }
-
- if (ShouldPaintSelfOutline(local_paint_info.phase)) {
- ObjectPainter(layout_embedded_content_)
- .PaintOutline(local_paint_info, paint_offset);
- }
-
- if (local_paint_info.phase != PaintPhase::kForeground)
- return;
-
- if (layout_embedded_content_.GetEmbeddedContentView()) {
- base::Optional<ScopedPaintChunkProperties> scoped_paint_chunk_properties;
- if (layout_embedded_content_.Style()->HasBorderRadius()) {
- if (border_rect.IsEmpty())
- return;
-
- const auto* fragment =
- local_paint_info.FragmentToPaint(layout_embedded_content_);
- if (!fragment)
- return;
- const auto* properties = fragment->PaintProperties();
- DCHECK(properties && properties->InnerBorderRadiusClip());
- scoped_paint_chunk_properties.emplace(
- local_paint_info.context.GetPaintController(),
- properties->InnerBorderRadiusClip(), layout_embedded_content_,
- DisplayItem::PaintPhaseToDrawingType(local_paint_info.phase));
- }
-
- layout_embedded_content_.PaintContents(local_paint_info, paint_offset);
- }
-
- // Paint a partially transparent wash over selected EmbeddedContentViews.
- if (IsSelected() && !local_paint_info.IsPrinting() &&
- !DrawingRecorder::UseCachedDrawingIfPossible(local_paint_info.context,
- layout_embedded_content_,
- local_paint_info.phase)) {
- LayoutRect rect = layout_embedded_content_.LocalSelectionRect();
- rect.MoveBy(paint_offset);
- IntRect selection_rect = PixelSnappedIntRect(rect);
- DrawingRecorder recorder(local_paint_info.context, layout_embedded_content_,
- local_paint_info.phase);
- Color selection_bg = SelectionPaintingUtils::SelectionBackgroundColor(
- layout_embedded_content_.GetDocument(),
- layout_embedded_content_.StyleRef(),
- layout_embedded_content_.GetNode());
- local_paint_info.context.FillRect(selection_rect, selection_bg);
- }
-
- if (layout_embedded_content_.CanResize()) {
- ScrollableAreaPainter(
- *layout_embedded_content_.Layer()->GetScrollableArea())
- .PaintResizer(local_paint_info.context, RoundedIntPoint(paint_offset),
- local_paint_info.GetCullRect());
- }
-}
-
-void EmbeddedContentPainter::PaintContents(const PaintInfo& paint_info,
+void EmbeddedContentPainter::PaintReplaced(const PaintInfo& paint_info,
const LayoutPoint& paint_offset) {
EmbeddedContentView* embedded_content_view =
layout_embedded_content_.GetEmbeddedContentView();
- CHECK(embedded_content_view);
+ if (!embedded_content_view)
+ return;
IntPoint paint_location(RoundedIntPoint(
paint_offset +
diff --git a/chromium/third_party/blink/renderer/core/paint/embedded_content_painter.h b/chromium/third_party/blink/renderer/core/paint/embedded_content_painter.h
index ea101cd1d3e..b72a09dc1f5 100644
--- a/chromium/third_party/blink/renderer/core/paint/embedded_content_painter.h
+++ b/chromium/third_party/blink/renderer/core/paint/embedded_content_painter.h
@@ -20,12 +20,9 @@ class EmbeddedContentPainter {
EmbeddedContentPainter(const LayoutEmbeddedContent& layout_embedded_content)
: layout_embedded_content_(layout_embedded_content) {}
- void Paint(const PaintInfo&);
- void PaintContents(const PaintInfo&, const LayoutPoint& paint_offset);
+ void PaintReplaced(const PaintInfo&, const LayoutPoint& paint_offset);
private:
- bool IsSelected() const;
-
const LayoutEmbeddedContent& layout_embedded_content_;
};
diff --git a/chromium/third_party/blink/renderer/core/paint/embedded_object_paint_invalidator.cc b/chromium/third_party/blink/renderer/core/paint/embedded_object_paint_invalidator.cc
deleted file mode 100644
index c81ef415520..00000000000
--- a/chromium/third_party/blink/renderer/core/paint/embedded_object_paint_invalidator.cc
+++ /dev/null
@@ -1,24 +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/paint/embedded_object_paint_invalidator.h"
-
-#include "third_party/blink/renderer/core/exported/web_plugin_container_impl.h"
-#include "third_party/blink/renderer/core/layout/layout_embedded_object.h"
-#include "third_party/blink/renderer/core/paint/box_paint_invalidator.h"
-
-namespace blink {
-
-PaintInvalidationReason EmbeddedObjectPaintInvalidator::InvalidatePaint() {
- PaintInvalidationReason reason =
- BoxPaintInvalidator(embedded_object_, context_).InvalidatePaint();
-
- WebPluginContainerImpl* plugin = embedded_object_.Plugin();
- if (plugin)
- plugin->InvalidatePaint();
-
- return reason;
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/embedded_object_paint_invalidator.h b/chromium/third_party/blink/renderer/core/paint/embedded_object_paint_invalidator.h
deleted file mode 100644
index d9c0a113344..00000000000
--- a/chromium/third_party/blink/renderer/core/paint/embedded_object_paint_invalidator.h
+++ /dev/null
@@ -1,33 +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_PAINT_EMBEDDED_OBJECT_PAINT_INVALIDATOR_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_EMBEDDED_OBJECT_PAINT_INVALIDATOR_H_
-
-#include "third_party/blink/renderer/platform/graphics/paint_invalidation_reason.h"
-#include "third_party/blink/renderer/platform/wtf/allocator.h"
-
-namespace blink {
-
-class LayoutEmbeddedObject;
-struct PaintInvalidatorContext;
-
-class EmbeddedObjectPaintInvalidator {
- STACK_ALLOCATED();
-
- public:
- EmbeddedObjectPaintInvalidator(const LayoutEmbeddedObject& embedded_object,
- const PaintInvalidatorContext& context)
- : embedded_object_(embedded_object), context_(context) {}
-
- PaintInvalidationReason InvalidatePaint();
-
- private:
- const LayoutEmbeddedObject& embedded_object_;
- const PaintInvalidatorContext& context_;
-};
-
-} // namespace blink
-
-#endif
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 2b2790e7d06..8af38dfac51 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
@@ -7,6 +7,7 @@
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/layout/layout_embedded_object.h"
#include "third_party/blink/renderer/core/layout/layout_theme.h"
+#include "third_party/blink/renderer/core/paint/embedded_content_painter.h"
#include "third_party/blink/renderer/core/paint/paint_info.h"
#include "third_party/blink/renderer/platform/fonts/font.h"
#include "third_party/blink/renderer/platform/fonts/font_selector.h"
@@ -37,8 +38,11 @@ static Font ReplacementTextFont() {
void EmbeddedObjectPainter::PaintReplaced(const PaintInfo& paint_info,
const LayoutPoint& paint_offset) {
- if (!layout_embedded_object_.ShowsUnavailablePluginIndicator())
+ if (!layout_embedded_object_.ShowsUnavailablePluginIndicator()) {
+ EmbeddedContentPainter(layout_embedded_object_)
+ .PaintReplaced(paint_info, paint_offset);
return;
+ }
if (paint_info.phase == PaintPhase::kSelection)
return;
@@ -48,7 +52,7 @@ void EmbeddedObjectPainter::PaintReplaced(const PaintInfo& paint_info,
context, layout_embedded_object_, paint_info.phase))
return;
- LayoutRect content_rect(layout_embedded_object_.ContentBoxRect());
+ LayoutRect content_rect(layout_embedded_object_.PhysicalContentBoxRect());
content_rect.MoveBy(paint_offset);
DrawingRecorder recorder(context, layout_embedded_object_, paint_info.phase);
GraphicsContextStateSaver state_saver(context);
diff --git a/chromium/third_party/blink/renderer/core/paint/fieldset_painter.cc b/chromium/third_party/blink/renderer/core/paint/fieldset_painter.cc
index cf136c23230..845d6b93490 100644
--- a/chromium/third_party/blink/renderer/core/paint/fieldset_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/fieldset_painter.cc
@@ -31,7 +31,7 @@ void FieldsetPainter::PaintBoxDecorationBackground(
// FIXME: We need to work with "rl" and "bt" block flow directions. In those
// cases the legend is embedded in the right and bottom borders respectively.
// https://bugs.webkit.org/show_bug.cgi?id=47236
- if (layout_fieldset_.Style()->IsHorizontalWritingMode()) {
+ if (layout_fieldset_.StyleRef().IsHorizontalWritingMode()) {
LayoutUnit y_off =
(legend->Location().Y() > 0)
? LayoutUnit()
@@ -56,8 +56,8 @@ void FieldsetPainter::PaintBoxDecorationBackground(
BackgroundImageGeometry geometry(layout_fieldset_);
BoxModelObjectPainter(layout_fieldset_)
.PaintFillLayers(paint_info, box_decoration_data.background_color,
- layout_fieldset_.Style()->BackgroundLayers(), paint_rect,
- geometry);
+ layout_fieldset_.StyleRef().BackgroundLayers(),
+ paint_rect, geometry);
BoxPainterBase::PaintInsetBoxShadowWithBorderRect(
paint_info, paint_rect, layout_fieldset_.StyleRef());
@@ -71,19 +71,19 @@ void FieldsetPainter::PaintBoxDecorationBackground(
// FIXME: We need to work with "rl" and "bt" block flow directions. In those
// cases the legend is embedded in the right and bottom borders respectively.
// https://bugs.webkit.org/show_bug.cgi?id=47236
- if (layout_fieldset_.Style()->IsHorizontalWritingMode()) {
+ if (layout_fieldset_.StyleRef().IsHorizontalWritingMode()) {
LayoutUnit clip_top = paint_rect.Y();
- LayoutUnit clip_height =
- max(static_cast<LayoutUnit>(layout_fieldset_.Style()->BorderTopWidth()),
- legend->Size().Height() -
- ((legend->Size().Height() - layout_fieldset_.BorderTop()) / 2));
+ LayoutUnit clip_height = max(
+ static_cast<LayoutUnit>(layout_fieldset_.StyleRef().BorderTopWidth()),
+ legend->Size().Height() -
+ ((legend->Size().Height() - layout_fieldset_.BorderTop()) / 2));
graphics_context.ClipOut(
PixelSnappedIntRect(paint_rect.X() + legend->Location().X(), clip_top,
legend->Size().Width(), clip_height));
} else {
LayoutUnit clip_left = paint_rect.X();
LayoutUnit clip_width = max(
- static_cast<LayoutUnit>(layout_fieldset_.Style()->BorderLeftWidth()),
+ static_cast<LayoutUnit>(layout_fieldset_.StyleRef().BorderLeftWidth()),
legend->Size().Width());
graphics_context.ClipOut(
PixelSnappedIntRect(clip_left, paint_rect.Y() + legend->Location().Y(),
@@ -101,7 +101,7 @@ void FieldsetPainter::PaintBoxDecorationBackground(
void FieldsetPainter::PaintMask(const PaintInfo& paint_info,
const LayoutPoint& paint_offset) {
- if (layout_fieldset_.Style()->Visibility() != EVisibility::kVisible ||
+ if (layout_fieldset_.StyleRef().Visibility() != EVisibility::kVisible ||
paint_info.phase != PaintPhase::kMask)
return;
@@ -117,7 +117,7 @@ void FieldsetPainter::PaintMask(const PaintInfo& paint_info,
// FIXME: We need to work with "rl" and "bt" block flow directions. In those
// cases the legend is embedded in the right and bottom borders respectively.
// https://bugs.webkit.org/show_bug.cgi?id=47236
- if (layout_fieldset_.Style()->IsHorizontalWritingMode()) {
+ if (layout_fieldset_.StyleRef().IsHorizontalWritingMode()) {
LayoutUnit y_off =
(legend->Location().Y() > LayoutUnit())
? LayoutUnit()
diff --git a/chromium/third_party/blink/renderer/core/paint/file_upload_control_painter.cc b/chromium/third_party/blink/renderer/core/paint/file_upload_control_painter.cc
index 8f207775a1d..024c736e0e4 100644
--- a/chromium/third_party/blink/renderer/core/paint/file_upload_control_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/file_upload_control_painter.cc
@@ -16,7 +16,7 @@ namespace blink {
void FileUploadControlPainter::PaintObject(const PaintInfo& paint_info,
const LayoutPoint& paint_offset) {
- if (layout_file_upload_control_.Style()->Visibility() !=
+ if (layout_file_upload_control_.StyleRef().Visibility() !=
EVisibility::kVisible)
return;
@@ -25,7 +25,7 @@ void FileUploadControlPainter::PaintObject(const PaintInfo& paint_info,
paint_info.context, layout_file_upload_control_, paint_info.phase)) {
const String& displayed_filename =
layout_file_upload_control_.FileTextValue();
- const Font& font = layout_file_upload_control_.Style()->GetFont();
+ const Font& font = layout_file_upload_control_.StyleRef().GetFont();
TextRun text_run = ConstructTextRun(
font, displayed_filename, layout_file_upload_control_.StyleRef(),
kRespectDirection | kRespectDirectionOverride);
@@ -46,7 +46,7 @@ void FileUploadControlPainter::PaintObject(const PaintInfo& paint_info,
button_width + LayoutFileUploadControl::kAfterButtonSpacing);
float text_width = font.Width(text_run);
LayoutUnit text_x;
- if (layout_file_upload_control_.Style()->IsLeftToRightDirection())
+ if (layout_file_upload_control_.StyleRef().IsLeftToRightDirection())
text_x = content_left + button_and_spacing_width;
else
text_x =
@@ -70,7 +70,7 @@ void FileUploadControlPainter::PaintObject(const PaintInfo& paint_info,
TextRunPaintInfo text_run_paint_info(text_run);
const SimpleFontData* font_data =
- layout_file_upload_control_.Style()->GetFont().PrimaryFont();
+ layout_file_upload_control_.StyleRef().GetFont().PrimaryFont();
if (!font_data)
return;
// FIXME: Shouldn't these offsets be rounded? crbug.com/350474
diff --git a/chromium/third_party/blink/renderer/core/paint/find_properties_needing_update.h b/chromium/third_party/blink/renderer/core/paint/find_properties_needing_update.h
index f27d8d9823d..2d7370eaeea 100644
--- a/chromium/third_party/blink/renderer/core/paint/find_properties_needing_update.h
+++ b/chromium/third_party/blink/renderer/core/paint/find_properties_needing_update.h
@@ -21,9 +21,10 @@ namespace blink {
// using LayoutObject::SetNeedsPaintPropertyUpdate() or by forcing a subtree
// update (see: PaintPropertyTreeBuilderContext::force_subtree_update).
//
-// This scope class works by recording the paint property state of an object
-// before rebuilding properties, forcing the properties to get updated, then
-// checking that the updated properties match the original properties.
+// This scope class works by marking the paint property state as immutable
+// before rebuilding properties, forcing the properties to get updated, which
+// causes object paint properties to DCHECK that property values are not
+// changed.
#define DUMP_PROPERTIES(original, updated) \
"\nOriginal:\n" \
@@ -67,8 +68,10 @@ class FindObjectPropertiesNeedingUpdateScope {
object.GetMutableForPainting()
.SetOnlyThisNeedsPaintPropertyUpdateForTesting();
- if (const auto* properties = fragment_data_.PaintProperties())
- original_properties_ = properties->Clone();
+ if (const auto* properties = fragment_data_.PaintProperties()) {
+ had_original_properties_ = true;
+ properties->SetImmutable();
+ }
if (fragment_data_.HasLocalBorderBoxProperties()) {
original_local_border_box_properties_ =
@@ -83,70 +86,18 @@ class FindObjectPropertiesNeedingUpdateScope {
// property update.
LayoutPoint paint_offset = fragment_data_.PaintOffset();
DCHECK_OBJECT_PROPERTY_EQ(object_, &original_paint_offset_, &paint_offset);
- const auto* object_properties = fragment_data_.PaintProperties();
- if (original_properties_ && object_properties) {
- DCHECK_OBJECT_PROPERTY_EQ(object_,
- original_properties_->PaintOffsetTranslation(),
- object_properties->PaintOffsetTranslation());
- }
// No need to check if an update was already needed.
if (needed_paint_property_update_ || needed_forced_subtree_update_)
return;
- // If these checks fail, the paint properties changed unexpectedly. This is
- // due to missing one of these paint property invalidations:
- // 1) The LayoutObject should have been marked as needing an update with
- // LayoutObject::setNeedsPaintPropertyUpdate().
- // 2) The PrePaintTreeWalk should have had a forced subtree update (see:
- // PaintPropertyTreeBuilderContext::force_subtree_update).
- if (original_properties_ && object_properties) {
- DCHECK_OBJECT_PROPERTY_EQ(object_, original_properties_->Transform(),
- object_properties->Transform());
- DCHECK_OBJECT_PROPERTY_EQ(object_, original_properties_->Effect(),
- object_properties->Effect());
- DCHECK_OBJECT_PROPERTY_EQ(object_, original_properties_->Filter(),
- object_properties->Filter());
- DCHECK_OBJECT_PROPERTY_EQ(object_,
- original_properties_->VerticalScrollbarEffect(),
- object_properties->VerticalScrollbarEffect());
- DCHECK_OBJECT_PROPERTY_EQ(
- object_, original_properties_->HorizontalScrollbarEffect(),
- object_properties->HorizontalScrollbarEffect());
- DCHECK_OBJECT_PROPERTY_EQ(object_, original_properties_->Mask(),
- object_properties->Mask());
- DCHECK_OBJECT_PROPERTY_EQ(object_, original_properties_->ClipPath(),
- object_properties->ClipPath());
- DCHECK_OBJECT_PROPERTY_EQ(object_, original_properties_->ClipPathClip(),
- object_properties->ClipPathClip());
- DCHECK_OBJECT_PROPERTY_EQ(object_, original_properties_->MaskClip(),
- object_properties->MaskClip());
- DCHECK_OBJECT_PROPERTY_EQ(object_, original_properties_->CssClip(),
- object_properties->CssClip());
- DCHECK_OBJECT_PROPERTY_EQ(object_,
- original_properties_->CssClipFixedPosition(),
- object_properties->CssClipFixedPosition());
- DCHECK_OBJECT_PROPERTY_EQ(object_,
- original_properties_->OverflowControlsClip(),
- object_properties->OverflowControlsClip());
- DCHECK_OBJECT_PROPERTY_EQ(object_,
- original_properties_->InnerBorderRadiusClip(),
- object_properties->InnerBorderRadiusClip());
- DCHECK_OBJECT_PROPERTY_EQ(object_, original_properties_->OverflowClip(),
- object_properties->OverflowClip());
- DCHECK_OBJECT_PROPERTY_EQ(object_, original_properties_->Perspective(),
- object_properties->Perspective());
- DCHECK_OBJECT_PROPERTY_EQ(
- object_, original_properties_->SvgLocalToBorderBoxTransform(),
- object_properties->SvgLocalToBorderBoxTransform());
- DCHECK_OBJECT_PROPERTY_EQ(object_, original_properties_->Scroll(),
- object_properties->Scroll());
- DCHECK_OBJECT_PROPERTY_EQ(object_,
- original_properties_->ScrollTranslation(),
- object_properties->ScrollTranslation());
+ const auto* properties = fragment_data_.PaintProperties();
+ if (properties) {
+ DCHECK(had_original_properties_);
+ DCHECK(properties->IsImmutable());
+ properties->SetMutable();
} else {
- DCHECK_EQ(!!original_properties_, !!object_properties)
- << " Object: " << object_.DebugName();
+ DCHECK(!had_original_properties_);
}
if (original_local_border_box_properties_ &&
@@ -174,12 +125,12 @@ class FindObjectPropertiesNeedingUpdateScope {
private:
const LayoutObject& object_;
const FragmentData& fragment_data_;
- bool needed_paint_property_update_;
- bool needed_forced_subtree_update_;
+ bool needed_paint_property_update_ = false;
+ bool needed_forced_subtree_update_ = false;
LayoutPoint original_paint_offset_;
- std::unique_ptr<const ObjectPaintProperties> original_properties_;
std::unique_ptr<const PropertyTreeState>
original_local_border_box_properties_;
+ bool had_original_properties_ = false;
};
} // namespace blink
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 472ac46a524..14797920c21 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
@@ -7,7 +7,6 @@
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/web_layer_tree_view.h"
#include "third_party/blink/renderer/core/css/font_face_set_document.h"
-#include "third_party/blink/renderer/core/frame/settings.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/cross_thread_functional.h"
@@ -34,23 +33,8 @@ FirstMeaningfulPaintDetector& FirstMeaningfulPaintDetector::From(
}
FirstMeaningfulPaintDetector::FirstMeaningfulPaintDetector(
- PaintTiming* paint_timing,
- Document& document)
- : paint_timing_(paint_timing),
- network0_quiet_timer_(
- document.GetTaskRunner(TaskType::kInternalDefault),
- this,
- &FirstMeaningfulPaintDetector::Network0QuietTimerFired),
- network2_quiet_timer_(
- document.GetTaskRunner(TaskType::kInternalDefault),
- this,
- &FirstMeaningfulPaintDetector::Network2QuietTimerFired) {
- if (GetDocument() && GetDocument()->GetSettings()) {
- network2_quiet_window_timeout_ = TimeDelta::FromSecondsD(
- GetDocument()->GetSettings()->GetFMPNetworkQuietTimeout());
- network0_quiet_window_timeout_ = network2_quiet_window_timeout_;
- }
-}
+ PaintTiming* paint_timing)
+ : paint_timing_(paint_timing) {}
Document* FirstMeaningfulPaintDetector::GetDocument() {
return paint_timing_->GetSupplementable();
@@ -123,44 +107,10 @@ void FirstMeaningfulPaintDetector::NotifyInputEvent() {
had_user_input_ = kHadUserInput;
}
-int FirstMeaningfulPaintDetector::ActiveConnections() {
- DCHECK(GetDocument());
- ResourceFetcher* fetcher = GetDocument()->Fetcher();
- return fetcher->BlockingRequestCount() + fetcher->NonblockingRequestCount();
-}
-
-// This function is called when the number of active connections is decreased
-// and when the document is parsed.
-void FirstMeaningfulPaintDetector::CheckNetworkStable() {
- DCHECK(GetDocument());
- if (!GetDocument()->HasFinishedParsing())
- return;
-
- SetNetworkQuietTimers(ActiveConnections());
-}
-
-void FirstMeaningfulPaintDetector::SetNetworkQuietTimers(
- int active_connections) {
- if (!network2_quiet_reached_ && active_connections <= 2) {
- // If activeConnections < 2 and the timer is already running, current
- // 2-quiet window continues; the timer shouldn't be restarted.
- if (active_connections == 2 || !network2_quiet_timer_.IsActive()) {
- network2_quiet_timer_.StartOneShot(network2_quiet_window_timeout_,
- FROM_HERE);
- }
- }
- if (!network0_quiet_reached_ && active_connections == 0) {
- // This restarts 0-quiet timer if it's already running.
- network0_quiet_timer_.StartOneShot(network0_quiet_window_timeout_,
- FROM_HERE);
- }
-}
-
-void FirstMeaningfulPaintDetector::Network0QuietTimerFired(TimerBase*) {
- if (!GetDocument() || network0_quiet_reached_ || ActiveConnections() > 0 ||
- paint_timing_->FirstContentfulPaintRendered().is_null())
- return;
+void FirstMeaningfulPaintDetector::OnNetwork0Quiet() {
network0_quiet_reached_ = true;
+ if (!GetDocument() || paint_timing_->FirstContentfulPaintRendered().is_null())
+ return;
if (!provisional_first_meaningful_paint_.is_null()) {
// Enforce FirstContentfulPaint <= FirstMeaningfulPaint.
@@ -171,8 +121,8 @@ void FirstMeaningfulPaintDetector::Network0QuietTimerFired(TimerBase*) {
ReportHistograms();
}
-void FirstMeaningfulPaintDetector::Network2QuietTimerFired(TimerBase*) {
- if (!GetDocument() || network2_quiet_reached_ || ActiveConnections() > 2 ||
+void FirstMeaningfulPaintDetector::OnNetwork2Quiet() {
+ if (!GetDocument() || network2_quiet_reached_ ||
paint_timing_->FirstContentfulPaintRendered().is_null())
return;
network2_quiet_reached_ = true;
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 ff6f60d8951..8c1c48d78f1 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
@@ -10,7 +10,6 @@
#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"
-#include "third_party/blink/renderer/platform/timer.h"
#include "third_party/blink/renderer/platform/wtf/time.h"
namespace blink {
@@ -29,7 +28,7 @@ class CORE_EXPORT FirstMeaningfulPaintDetector
public:
static FirstMeaningfulPaintDetector& From(Document&);
- FirstMeaningfulPaintDetector(PaintTiming*, Document&);
+ explicit FirstMeaningfulPaintDetector(PaintTiming*);
virtual ~FirstMeaningfulPaintDetector() = default;
void MarkNextPaintAsMeaningfulIfNeeded(const LayoutObjectCounter&,
@@ -38,11 +37,12 @@ class CORE_EXPORT FirstMeaningfulPaintDetector
int visible_height);
void NotifyInputEvent();
void NotifyPaint();
- void CheckNetworkStable();
void ReportSwapTime(PaintEvent,
WebLayerTreeView::SwapResult,
base::TimeTicks);
void NotifyFirstContentfulPaint(TimeTicks swap_stamp);
+ void OnNetwork0Quiet();
+ void OnNetwork2Quiet();
void Trace(blink::Visitor*);
@@ -66,9 +66,6 @@ class CORE_EXPORT FirstMeaningfulPaintDetector
Document* GetDocument();
int ActiveConnections();
- void SetNetworkQuietTimers(int active_connections);
- void Network0QuietTimerFired(TimerBase*);
- void Network2QuietTimerFired(TimerBase*);
void ReportHistograms();
void RegisterNotifySwapTime(PaintEvent);
void SetFirstMeaningfulPaint(TimeTicks stamp, TimeTicks swap_stamp);
@@ -93,8 +90,6 @@ class CORE_EXPORT FirstMeaningfulPaintDetector
TimeTicks first_meaningful_paint2_quiet_;
unsigned outstanding_swap_promise_count_ = 0;
DeferFirstMeaningfulPaint defer_first_meaningful_paint_ = kDoNotDefer;
- TaskRunnerTimer<FirstMeaningfulPaintDetector> network0_quiet_timer_;
- TaskRunnerTimer<FirstMeaningfulPaintDetector> network2_quiet_timer_;
DISALLOW_COPY_AND_ASSIGN(FirstMeaningfulPaintDetector);
};
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 756ad3f1124..a4bd180d19a 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
@@ -20,15 +20,6 @@ class FirstMeaningfulPaintDetectorTest : public PageTestBase {
void SetUp() override {
platform_->AdvanceClock(TimeDelta::FromSeconds(1));
PageTestBase::SetUp();
- ResetNetworkQuietTimer();
- }
-
- // The initial document doesn't need to load any resources other than itself.
- // It means initially, the network quiet timers are already active. This
- // function is used to reset them.
- void ResetNetworkQuietTimer() {
- Detector().network2_quiet_timer_.Stop();
- Detector().network0_quiet_timer_.Stop();
}
TimeTicks AdvanceClockAndGetTime() {
@@ -53,37 +44,22 @@ class FirstMeaningfulPaintDetectorTest : public PageTestBase {
void SimulateNetworkStable() {
GetDocument().SetParsingState(Document::kFinishedParsing);
- Detector().Network0QuietTimerFired(nullptr);
- Detector().Network2QuietTimerFired(nullptr);
+ Detector().OnNetwork0Quiet();
+ Detector().OnNetwork2Quiet();
}
void SimulateNetwork0Quiet() {
GetDocument().SetParsingState(Document::kFinishedParsing);
- Detector().Network0QuietTimerFired(nullptr);
+ Detector().OnNetwork0Quiet();
}
void SimulateNetwork2Quiet() {
GetDocument().SetParsingState(Document::kFinishedParsing);
- Detector().Network2QuietTimerFired(nullptr);
+ Detector().OnNetwork2Quiet();
}
void SimulateUserInput() { Detector().NotifyInputEvent(); }
- void SetActiveConnections(int connections) {
- Detector().SetNetworkQuietTimers(connections);
- }
-
- bool IsNetwork0QuietTimerActive() {
- return Detector().network0_quiet_timer_.IsActive();
- }
-
- bool IsNetwork2QuietTimerActive() {
- return Detector().network2_quiet_timer_.IsActive();
- }
-
- bool HadNetwork0Quiet() { return Detector().network0_quiet_reached_; }
- bool HadNetwork2Quiet() { return Detector().network2_quiet_reached_; }
-
void ClearFirstPaintSwapPromise() {
platform_->AdvanceClock(TimeDelta::FromMilliseconds(1));
GetPaintTiming().ReportSwapTime(PaintEvent::kFirstPaint,
@@ -324,51 +300,6 @@ TEST_F(FirstMeaningfulPaintDetectorTest, Network0QuietThen2Quiet) {
GetPaintTiming().FirstMeaningfulPaintRendered());
}
-TEST_F(FirstMeaningfulPaintDetectorTest, Network0QuietTimer) {
- MarkFirstContentfulPaintAndClearSwapPromise();
-
- SetActiveConnections(1);
- EXPECT_FALSE(IsNetwork0QuietTimerActive());
-
- SetActiveConnections(0);
- platform_->RunForPeriod(GetNetwork0QuietWindowTimeout() -
- TimeDelta::FromMilliseconds(100));
- EXPECT_TRUE(IsNetwork0QuietTimerActive());
- EXPECT_FALSE(HadNetwork0Quiet());
-
- SetActiveConnections(0); // This should reset the 0-quiet timer.
- platform_->RunForPeriod(GetNetwork0QuietWindowTimeout() -
- TimeDelta::FromMilliseconds(100));
- EXPECT_TRUE(IsNetwork0QuietTimerActive());
- EXPECT_FALSE(HadNetwork0Quiet());
-
- platform_->RunForPeriod(TimeDelta::FromMicroseconds(100100));
- EXPECT_TRUE(HadNetwork0Quiet());
-}
-
-TEST_F(FirstMeaningfulPaintDetectorTest, Network2QuietTimer) {
- MarkFirstContentfulPaintAndClearSwapPromise();
-
- SetActiveConnections(3);
- EXPECT_FALSE(IsNetwork2QuietTimerActive());
-
- SetActiveConnections(2);
- platform_->RunForPeriod(GetNetwork2QuietWindowTimeout() -
- TimeDelta::FromMilliseconds(100));
- EXPECT_TRUE(IsNetwork2QuietTimerActive());
- EXPECT_FALSE(HadNetwork2Quiet());
-
- SetActiveConnections(2); // This should reset the 2-quiet timer.
- platform_->RunForPeriod(GetNetwork2QuietWindowTimeout() -
- TimeDelta::FromMilliseconds(100));
- EXPECT_TRUE(IsNetwork2QuietTimerActive());
- EXPECT_FALSE(HadNetwork2Quiet());
-
- SetActiveConnections(1); // This should not reset the 2-quiet timer.
- platform_->RunForPeriod(TimeDelta::FromMicroseconds(100100));
- EXPECT_TRUE(HadNetwork2Quiet());
-}
-
TEST_F(FirstMeaningfulPaintDetectorTest,
FirstMeaningfulPaintAfterUserInteraction) {
MarkFirstContentfulPaintAndClearSwapPromise();
diff --git a/chromium/third_party/blink/renderer/core/paint/fragment_data.cc b/chromium/third_party/blink/renderer/core/paint/fragment_data.cc
index 77d262bef5d..9cf6f03e995 100644
--- a/chromium/third_party/blink/renderer/core/paint/fragment_data.cc
+++ b/chromium/third_party/blink/renderer/core/paint/fragment_data.cc
@@ -15,6 +15,18 @@ FragmentData::RareData::RareData() : unique_id(NewUniqueObjectId()) {}
FragmentData::RareData::~RareData() = default;
+void FragmentData::DestroyTail() {
+ while (next_fragment_) {
+ // Take the following (next-next) fragment, clearing
+ // |next_fragment_->next_fragment_|.
+ std::unique_ptr<FragmentData> next =
+ std::move(next_fragment_->next_fragment_);
+ // Point |next_fragment_| to the following fragment and destroy
+ // the current |next_fragment_|.
+ next_fragment_ = std::move(next);
+ }
+}
+
FragmentData& FragmentData::EnsureNextFragment() {
if (!next_fragment_)
next_fragment_ = std::make_unique<FragmentData>();
@@ -44,6 +56,8 @@ const TransformPaintPropertyNode* FragmentData::PostScrollTranslation() const {
if (const auto* properties = PaintProperties()) {
if (properties->ScrollTranslation())
return properties->ScrollTranslation();
+ if (properties->ReplacedContentTransform())
+ return properties->ReplacedContentTransform();
if (properties->Perspective())
return properties->Perspective();
}
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 4bd3b3198d2..3655ad414ab 100644
--- a/chromium/third_party/blink/renderer/core/paint/fragment_data.h
+++ b/chromium/third_party/blink/renderer/core/paint/fragment_data.h
@@ -21,7 +21,7 @@ class CORE_EXPORT FragmentData {
public:
FragmentData* NextFragment() const { return next_fragment_.get(); }
FragmentData& EnsureNextFragment();
- void ClearNextFragment() { next_fragment_.reset(); }
+ void ClearNextFragment() { DestroyTail(); }
// Visual offset of this fragment's top-left position from the
// "paint offset root" which is the containing root PaintLayer of the root
@@ -141,6 +141,7 @@ class CORE_EXPORT FragmentData {
if (rare_data_)
rare_data_->paint_properties = nullptr;
}
+ void EnsureIdForTesting() { EnsureRareData(); }
// This is a complete set of property nodes that should be used as a
// starting point to paint a LayoutObject. This data is cached because some
@@ -209,9 +210,16 @@ class CORE_EXPORT FragmentData {
const EffectPaintPropertyNode* PreEffect() const;
const EffectPaintPropertyNode* PreFilter() const;
+ ~FragmentData() {
+ if (next_fragment_)
+ DestroyTail();
+ }
+
private:
friend class FragmentDataTest;
+ void DestroyTail();
+
// Contains rare data that that is not needed on all fragments.
struct RareData {
USING_FAST_MALLOC(RareData);
diff --git a/chromium/third_party/blink/renderer/core/paint/frame_set_painter.cc b/chromium/third_party/blink/renderer/core/paint/frame_set_painter.cc
index ac119bf960a..d45b623d7d4 100644
--- a/chromium/third_party/blink/renderer/core/paint/frame_set_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/frame_set_painter.cc
@@ -6,8 +6,8 @@
#include "third_party/blink/renderer/core/html/html_frame_set_element.h"
#include "third_party/blink/renderer/core/layout/layout_frame_set.h"
-#include "third_party/blink/renderer/core/paint/adjust_paint_offset_scope.h"
#include "third_party/blink/renderer/core/paint/paint_info.h"
+#include "third_party/blink/renderer/core/paint/paint_info_with_offset.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
namespace blink {
@@ -154,10 +154,10 @@ void FrameSetPainter::Paint(const PaintInfo& paint_info) {
if (!child)
return;
- AdjustPaintOffsetScope adjustment(layout_frame_set_, paint_info);
- const auto& local_paint_info = adjustment.GetPaintInfo();
+ PaintInfoWithOffset paint_info_with_offset(layout_frame_set_, paint_info);
+ const auto& local_paint_info = paint_info_with_offset.GetPaintInfo();
PaintChildren(local_paint_info);
- PaintBorders(local_paint_info, adjustment.PaintOffset());
+ PaintBorders(local_paint_info, paint_info_with_offset.PaintOffset());
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/grid_painter.cc b/chromium/third_party/blink/renderer/core/paint/grid_painter.cc
index 74bad9d6943..dbb5fe0d03d 100644
--- a/chromium/third_party/blink/renderer/core/paint/grid_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/grid_painter.cc
@@ -80,6 +80,9 @@ void GridPainter::PaintChildren(const PaintInfo& paint_info,
Vector<std::pair<LayoutBox*, size_t>> grid_items_to_be_painted;
+ // TODO(svillar): This way of retrieving cells is extremelly
+ // inefficient for the list-based grid implementation. We must
+ // replace the loop by something else.
for (const auto& row : dirtied_rows) {
for (const auto& column : dirtied_columns) {
const Vector<LayoutBox*, 1>& children =
diff --git a/chromium/third_party/blink/renderer/core/paint/html_canvas_paint_invalidator.cc b/chromium/third_party/blink/renderer/core/paint/html_canvas_paint_invalidator.cc
deleted file mode 100644
index c6e78348807..00000000000
--- a/chromium/third_party/blink/renderer/core/paint/html_canvas_paint_invalidator.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/core/paint/html_canvas_paint_invalidator.h"
-
-#include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h"
-#include "third_party/blink/renderer/core/layout/layout_html_canvas.h"
-#include "third_party/blink/renderer/core/paint/box_paint_invalidator.h"
-#include "third_party/blink/renderer/core/paint/paint_invalidator.h"
-
-namespace blink {
-
-PaintInvalidationReason HTMLCanvasPaintInvalidator::InvalidatePaint() {
- auto* element = ToHTMLCanvasElement(html_canvas_.GetNode());
- if (element->IsDirty())
- element->DoDeferredPaintInvalidation();
-
- return BoxPaintInvalidator(html_canvas_, context_).InvalidatePaint();
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/html_canvas_paint_invalidator.h b/chromium/third_party/blink/renderer/core/paint/html_canvas_paint_invalidator.h
deleted file mode 100644
index fdd94b4aa77..00000000000
--- a/chromium/third_party/blink/renderer/core/paint/html_canvas_paint_invalidator.h
+++ /dev/null
@@ -1,33 +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_PAINT_HTML_CANVAS_PAINT_INVALIDATOR_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_HTML_CANVAS_PAINT_INVALIDATOR_H_
-
-#include "third_party/blink/renderer/platform/graphics/paint_invalidation_reason.h"
-#include "third_party/blink/renderer/platform/wtf/allocator.h"
-
-namespace blink {
-
-class LayoutHTMLCanvas;
-struct PaintInvalidatorContext;
-
-class HTMLCanvasPaintInvalidator {
- STACK_ALLOCATED();
-
- public:
- HTMLCanvasPaintInvalidator(const LayoutHTMLCanvas& html_canvas,
- const PaintInvalidatorContext& context)
- : html_canvas_(html_canvas), context_(context) {}
-
- PaintInvalidationReason InvalidatePaint();
-
- private:
- const LayoutHTMLCanvas& html_canvas_;
- const PaintInvalidatorContext& context_;
-};
-
-} // namespace blink
-
-#endif
diff --git a/chromium/third_party/blink/renderer/core/paint/html_canvas_painter.cc b/chromium/third_party/blink/renderer/core/paint/html_canvas_painter.cc
index be38ebb0e88..a5692927314 100644
--- a/chromium/third_party/blink/renderer/core/paint/html_canvas_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/html_canvas_painter.cc
@@ -33,8 +33,6 @@ void HTMLCanvasPainter::PaintReplaced(const PaintInfo& paint_info,
const LayoutPoint& paint_offset) {
GraphicsContext& context = paint_info.context;
- LayoutRect content_rect = layout_html_canvas_.ContentBoxRect();
- content_rect.MoveBy(paint_offset);
LayoutRect paint_rect = layout_html_canvas_.ReplacedContentRect();
paint_rect.MoveBy(paint_offset);
@@ -45,7 +43,7 @@ void HTMLCanvasPainter::PaintReplaced(const PaintInfo& paint_info,
canvas->RenderingContext() &&
canvas->RenderingContext()->IsComposited()) {
if (cc::Layer* layer = canvas->RenderingContext()->CcLayer()) {
- IntRect pixel_snapped_rect = PixelSnappedIntRect(content_rect);
+ IntRect pixel_snapped_rect = PixelSnappedIntRect(paint_rect);
layer->SetBounds(static_cast<gfx::Size>(pixel_snapped_rect.Size()));
layer->SetIsDrawable(true);
RecordForeignLayer(
@@ -60,22 +58,9 @@ void HTMLCanvasPainter::PaintReplaced(const PaintInfo& paint_info,
return;
DrawingRecorder recorder(context, layout_html_canvas_, paint_info.phase);
-
- bool clip = !content_rect.Contains(paint_rect);
- if (clip) {
- context.Save();
- // TODO(chrishtr): this should be pixel-snapped.
- context.Clip(FloatRect(content_rect));
- }
-
- {
- ScopedInterpolationQuality interpolation_quality_scope(
- context, InterpolationQualityForCanvas(layout_html_canvas_.StyleRef()));
- canvas->Paint(context, paint_rect);
- }
-
- if (clip)
- context.Restore();
+ ScopedInterpolationQuality interpolation_quality_scope(
+ context, InterpolationQualityForCanvas(layout_html_canvas_.StyleRef()));
+ canvas->Paint(context, paint_rect);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/html_canvas_painter_test.cc b/chromium/third_party/blink/renderer/core/paint/html_canvas_painter_test.cc
index 34c5b8d0e00..d0c7c1d11de 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
@@ -22,7 +22,7 @@
#include "third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_wrapper.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
// Integration tests of canvas painting code (in SPv2 mode).
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 43ba924decd..92cc1fe3dba 100644
--- a/chromium/third_party/blink/renderer/core/paint/image_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/image_painter.cc
@@ -15,8 +15,8 @@
#include "third_party/blink/renderer/core/layout/text_run_constructor.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/adjust_paint_offset_scope.h"
#include "third_party/blink/renderer/core/paint/paint_info.h"
+#include "third_party/blink/renderer/core/paint/paint_info_with_offset.h"
#include "third_party/blink/renderer/platform/geometry/layout_point.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"
@@ -61,8 +61,8 @@ void ImagePainter::PaintAreaElementFocusRing(const PaintInfo& paint_info) {
if (path.IsEmpty())
return;
- AdjustPaintOffsetScope adjustment(layout_image_, paint_info);
- auto paint_offset = adjustment.PaintOffset();
+ PaintInfoWithOffset paint_info_with_offset(layout_image_, paint_info);
+ auto paint_offset = paint_info_with_offset.PaintOffset();
path.Translate(FloatSize(paint_offset.X(), paint_offset.Y()));
if (DrawingRecorder::UseCachedDrawingIfPossible(
@@ -76,7 +76,7 @@ void ImagePainter::PaintAreaElementFocusRing(const PaintInfo& paint_info) {
// https://crbug.com/251206
paint_info.context.Save();
- LayoutRect focus_rect = layout_image_.ContentBoxRect();
+ LayoutRect focus_rect = layout_image_.PhysicalContentBoxRect();
focus_rect.MoveBy(paint_offset);
paint_info.context.Clip(PixelSnappedIntRect(focus_rect));
paint_info.context.DrawFocusRing(
@@ -115,8 +115,8 @@ void ImagePainter::PaintReplaced(const PaintInfo& paint_info,
layout_image_.ImageResource()->MaybeAnimated())
cache_skipper.emplace(context);
- LayoutRect content_rect(paint_offset + layout_image_.ContentBoxOffset(),
- content_size);
+ LayoutRect content_rect(
+ paint_offset + layout_image_.PhysicalContentBoxOffset(), content_size);
if (!has_image) {
// Draw an outline rect where the image should be.
diff --git a/chromium/third_party/blink/renderer/core/paint/inline_box_painter_base.cc b/chromium/third_party/blink/renderer/core/paint/inline_box_painter_base.cc
new file mode 100644
index 00000000000..58427321f36
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/paint/inline_box_painter_base.cc
@@ -0,0 +1,112 @@
+// 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/paint/inline_box_painter_base.h"
+
+#include "third_party/blink/renderer/core/paint/background_image_geometry.h"
+#include "third_party/blink/renderer/core/paint/box_painter_base.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/platform/graphics/graphics_context_state_saver.h"
+#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
+
+namespace blink {
+
+void InlineBoxPainterBase::PaintBoxDecorationBackground(
+ BoxPainterBase& box_painter,
+ const PaintInfo& paint_info,
+ const LayoutPoint& paint_offset,
+ LayoutRect adjusted_frame_rect,
+ BackgroundImageGeometry geometry,
+ bool object_has_multiple_boxes,
+ bool include_logical_left_edge,
+ bool include_logical_right_edge) {
+ // Shadow comes first and is behind the background and border.
+ PaintNormalBoxShadow(paint_info, line_style_, adjusted_frame_rect);
+
+ Color background_color =
+ line_style_.VisitedDependentColor(GetCSSPropertyBackgroundColor());
+ PaintFillLayers(box_painter, paint_info, background_color,
+ line_style_.BackgroundLayers(), adjusted_frame_rect, geometry,
+ object_has_multiple_boxes);
+
+ PaintInsetBoxShadow(paint_info, line_style_, adjusted_frame_rect);
+
+ IntRect adjusted_clip_rect;
+ BorderPaintingType border_painting_type = GetBorderPaintType(
+ adjusted_frame_rect, adjusted_clip_rect, object_has_multiple_boxes);
+ switch (border_painting_type) {
+ case kDontPaintBorders:
+ break;
+ case kPaintBordersWithoutClip:
+ BoxPainterBase::PaintBorder(
+ image_observer_, *document_, node_, paint_info, adjusted_frame_rect,
+ line_style_, kBackgroundBleedNone, include_logical_left_edge,
+ include_logical_right_edge);
+ break;
+ case kPaintBordersWithClip:
+ // FIXME: What the heck do we do with RTL here? The math we're using is
+ // obviously not right, but it isn't even clear how this should work at
+ // all.
+ LayoutRect image_strip_paint_rect =
+ PaintRectForImageStrip(adjusted_frame_rect, TextDirection::kLtr);
+ GraphicsContextStateSaver state_saver(paint_info.context);
+ paint_info.context.Clip(adjusted_clip_rect);
+ BoxPainterBase::PaintBorder(image_observer_, *document_, node_,
+ paint_info, image_strip_paint_rect,
+ line_style_);
+ break;
+ }
+}
+
+void InlineBoxPainterBase::PaintFillLayers(BoxPainterBase& box_painter,
+ const PaintInfo& info,
+ const Color& c,
+ const FillLayer& layer,
+ const LayoutRect& rect,
+ BackgroundImageGeometry& geometry,
+ bool object_has_multiple_boxes,
+ SkBlendMode op) {
+ // FIXME: This should be a for loop or similar. It's a little non-trivial to
+ // do so, however, since the layers need to be painted in reverse order.
+ if (layer.Next()) {
+ PaintFillLayers(box_painter, info, c, *layer.Next(), rect, geometry,
+ object_has_multiple_boxes, op);
+ }
+ PaintFillLayer(box_painter, info, c, layer, rect, geometry,
+ object_has_multiple_boxes, op);
+}
+
+void InlineBoxPainterBase::PaintFillLayer(BoxPainterBase& box_painter,
+ const PaintInfo& paint_info,
+ const Color& c,
+ const FillLayer& fill_layer,
+ const LayoutRect& paint_rect,
+ BackgroundImageGeometry& geometry,
+ bool object_has_multiple_boxes,
+ SkBlendMode op) {
+ StyleImage* img = fill_layer.GetImage();
+ bool has_fill_image = img && img->CanRender();
+
+ if (!object_has_multiple_boxes ||
+ (!has_fill_image && !style_.HasBorderRadius())) {
+ box_painter.PaintFillLayer(paint_info, c, fill_layer, paint_rect,
+ kBackgroundBleedNone, geometry, op, false);
+ return;
+ }
+
+ // Handle fill images that clone or spans multiple lines.
+ bool multi_line = object_has_multiple_boxes &&
+ style_.BoxDecorationBreak() != EBoxDecorationBreak::kClone;
+ LayoutRect rect = multi_line
+ ? PaintRectForImageStrip(paint_rect, style_.Direction())
+ : paint_rect;
+ GraphicsContextStateSaver state_saver(paint_info.context);
+ paint_info.context.Clip(PixelSnappedIntRect(paint_rect));
+ box_painter.PaintFillLayer(paint_info, c, fill_layer, rect,
+ kBackgroundBleedNone, geometry, op, multi_line,
+ paint_rect.Size());
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..726ce1ea37c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/paint/inline_box_painter_base.h
@@ -0,0 +1,100 @@
+// 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_PAINT_INLINE_BOX_PAINTER_BASE_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_INLINE_BOX_PAINTER_BASE_H_
+
+#include "third_party/blink/renderer/core/paint/box_painter_base.h"
+#include "third_party/blink/renderer/core/style/shadow_data.h"
+#include "third_party/blink/renderer/platform/graphics/graphics_types.h"
+#include "third_party/blink/renderer/platform/text/text_direction.h"
+#include "third_party/blink/renderer/platform/wtf/allocator.h"
+
+namespace blink {
+
+class Color;
+class FillLayer;
+class IntRect;
+class LayoutPoint;
+class LayoutRect;
+struct PaintInfo;
+class ComputedStyle;
+
+// Common base class for InlineFlowBoxPainter and NGInlineBoxFragmentPainter.
+// Implements layout agnostic inline box painting behavior.
+class InlineBoxPainterBase {
+ STACK_ALLOCATED();
+
+ public:
+ InlineBoxPainterBase(const ImageResourceObserver& image_observer,
+ const Document* document,
+ Node* node,
+ const ComputedStyle& style,
+ const ComputedStyle& line_style)
+ : image_observer_(image_observer),
+ document_(document),
+ node_(node),
+ style_(style),
+ line_style_(line_style) {}
+
+ void PaintBoxDecorationBackground(BoxPainterBase&,
+ const PaintInfo&,
+ const LayoutPoint& paint_offset,
+ LayoutRect adjusted_frame_rect,
+ BackgroundImageGeometry,
+ bool object_has_multiple_boxes,
+ bool include_logical_left_edge,
+ bool include_logical_right_edge);
+
+ protected:
+ void PaintFillLayers(BoxPainterBase&,
+ const PaintInfo&,
+ const Color&,
+ const FillLayer&,
+ const LayoutRect&,
+ BackgroundImageGeometry& geometry,
+ bool object_has_multiple_boxes,
+ SkBlendMode op = SkBlendMode::kSrcOver);
+ void PaintFillLayer(BoxPainterBase&,
+ const PaintInfo&,
+ const Color&,
+ const FillLayer&,
+ const LayoutRect&,
+ BackgroundImageGeometry& geometry,
+ bool object_has_multiple_boxes,
+ SkBlendMode op);
+ virtual void PaintNormalBoxShadow(const PaintInfo&,
+ const ComputedStyle&,
+ const LayoutRect& paint_rect) = 0;
+ virtual void PaintInsetBoxShadow(const PaintInfo&,
+ const ComputedStyle&,
+ const LayoutRect& paint_rect) = 0;
+
+ virtual LayoutRect PaintRectForImageStrip(const LayoutRect&,
+ TextDirection direction) const = 0;
+
+ enum BorderPaintingType {
+ kDontPaintBorders,
+ kPaintBordersWithoutClip,
+ kPaintBordersWithClip
+ };
+ virtual BorderPaintingType GetBorderPaintType(
+ const LayoutRect& adjusted_frame_rect,
+ IntRect& adjusted_clip_rect,
+ bool object_has_multiple_boxes) const = 0;
+
+ const ImageResourceObserver& image_observer_;
+ Member<const Document> document_;
+ Member<Node> node_;
+
+ // Style for the corresponding node.
+ const ComputedStyle& style_;
+
+ // Style taking ::first-line into account.
+ const ComputedStyle& line_style_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_INLINE_BOX_PAINTER_BASE_H_
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 004830e5a87..9726482b230 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
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/paint/inline_flow_box_painter.h"
#include "third_party/blink/renderer/core/layout/api/line_layout_api_shim.h"
+#include "third_party/blink/renderer/core/layout/line/inline_flow_box.h"
#include "third_party/blink/renderer/core/layout/line/root_inline_box.h"
#include "third_party/blink/renderer/core/paint/background_image_geometry.h"
#include "third_party/blink/renderer/core/paint/box_model_object_painter.h"
@@ -16,6 +17,33 @@
namespace blink {
+namespace {
+
+inline Node* GetNode(const LayoutObject* box_model) {
+ Node* node = nullptr;
+ for (const LayoutObject* obj = box_model; obj && !node; obj = obj->Parent())
+ node = obj->GeneratingNode();
+ return node;
+}
+
+inline const LayoutBoxModelObject* GetBoxModelObject(
+ const InlineFlowBox& flow_box) {
+ return ToLayoutBoxModelObject(
+ LineLayoutAPIShim::LayoutObjectFrom(flow_box.BoxModelObject()));
+}
+
+} // anonymous namespace
+
+InlineFlowBoxPainter::InlineFlowBoxPainter(const InlineFlowBox& flow_box)
+ : InlineBoxPainterBase(
+ *GetBoxModelObject(flow_box),
+ &GetBoxModelObject(flow_box)->GetDocument(),
+ GetNode(GetBoxModelObject(flow_box)),
+ flow_box.GetLineLayoutItem().StyleRef(),
+ flow_box.GetLineLayoutItem().StyleRef(flow_box.IsFirstLineStyle())),
+ inline_flow_box_(flow_box) {
+}
+
void InlineFlowBoxPainter::Paint(const PaintInfo& paint_info,
const LayoutPoint& paint_offset,
const LayoutUnit line_top,
@@ -38,7 +66,7 @@ void InlineFlowBoxPainter::Paint(const PaintInfo& paint_info,
if (paint_info.phase == PaintPhase::kForeground) {
// Paint our background, border and box-shadow.
- PaintBoxDecorationBackground(paint_info, paint_offset);
+ PaintBackgroundBorderShadow(paint_info, paint_offset);
}
// Paint our children.
@@ -51,96 +79,6 @@ void InlineFlowBoxPainter::Paint(const PaintInfo& paint_info,
}
}
-void InlineFlowBoxPainter::PaintFillLayers(const PaintInfo& paint_info,
- const Color& c,
- const FillLayer& fill_layer,
- const LayoutRect& rect,
- SkBlendMode op) {
- // FIXME: This should be a for loop or similar. It's a little non-trivial to
- // do so, however, since the layers need to be painted in reverse order.
- if (fill_layer.Next())
- PaintFillLayers(paint_info, c, *fill_layer.Next(), rect, op);
- PaintFillLayer(paint_info, c, fill_layer, rect, op);
-}
-
-void InlineFlowBoxPainter::PaintFillLayer(const PaintInfo& paint_info,
- const Color& c,
- const FillLayer& fill_layer,
- const LayoutRect& rect,
- SkBlendMode op) {
- LayoutBoxModelObject* box_model = ToLayoutBoxModelObject(
- LineLayoutAPIShim::LayoutObjectFrom(inline_flow_box_.BoxModelObject()));
- BackgroundImageGeometry geometry(*box_model);
- StyleImage* img = fill_layer.GetImage();
- bool has_fill_image = img && img->CanRender();
- BoxModelObjectPainter box_model_painter(*box_model, &inline_flow_box_);
- if ((!has_fill_image &&
- !inline_flow_box_.GetLineLayoutItem().Style()->HasBorderRadius()) ||
- (!inline_flow_box_.PrevForSameLayoutObject() &&
- !inline_flow_box_.NextForSameLayoutObject()) ||
- !inline_flow_box_.Parent()) {
- bool object_has_multiple_boxes = false;
- box_model_painter.PaintFillLayer(paint_info, c, fill_layer, rect,
- kBackgroundBleedNone, geometry, op,
- object_has_multiple_boxes);
- } else if (inline_flow_box_.GetLineLayoutItem()
- .Style()
- ->BoxDecorationBreak() == EBoxDecorationBreak::kClone) {
- GraphicsContextStateSaver state_saver(paint_info.context);
- paint_info.context.Clip(PixelSnappedIntRect(rect));
- bool object_has_multiple_boxes = false;
- box_model_painter.PaintFillLayer(paint_info, c, fill_layer, rect,
- kBackgroundBleedNone, geometry, op,
- object_has_multiple_boxes);
- } else {
- // We have a fill image that spans multiple lines.
- // FIXME: frameSize ought to be the same as rect.size().
- LayoutSize frame_size(inline_flow_box_.Width(), inline_flow_box_.Height());
- LayoutRect image_strip_paint_rect = PaintRectForImageStrip(
- rect.Location(), frame_size,
- inline_flow_box_.GetLineLayoutItem().Style()->Direction());
- GraphicsContextStateSaver state_saver(paint_info.context);
- // TODO(chrishtr): this should likely be pixel-snapped.
- paint_info.context.Clip(PixelSnappedIntRect(rect));
- bool object_has_multiple_boxes = true;
- box_model_painter.PaintFillLayer(
- paint_info, c, fill_layer, image_strip_paint_rect, kBackgroundBleedNone,
- geometry, op, object_has_multiple_boxes, rect.Size());
- }
-}
-
-inline bool InlineFlowBoxPainter::ShouldForceIncludeLogicalEdges() const {
- return (!inline_flow_box_.PrevForSameLayoutObject() &&
- !inline_flow_box_.NextForSameLayoutObject()) ||
- !inline_flow_box_.Parent();
-}
-
-inline bool InlineFlowBoxPainter::IncludeLogicalLeftEdgeForBoxShadow() const {
- return ShouldForceIncludeLogicalEdges() ||
- inline_flow_box_.IncludeLogicalLeftEdge();
-}
-
-inline bool InlineFlowBoxPainter::IncludeLogicalRightEdgeForBoxShadow() const {
- return ShouldForceIncludeLogicalEdges() ||
- inline_flow_box_.IncludeLogicalRightEdge();
-}
-
-void InlineFlowBoxPainter::PaintNormalBoxShadow(const PaintInfo& info,
- const ComputedStyle& s,
- const LayoutRect& paint_rect) {
- BoxPainterBase::PaintNormalBoxShadow(info, paint_rect, s,
- IncludeLogicalLeftEdgeForBoxShadow(),
- IncludeLogicalRightEdgeForBoxShadow());
-}
-
-void InlineFlowBoxPainter::PaintInsetBoxShadow(const PaintInfo& info,
- const ComputedStyle& s,
- const LayoutRect& paint_rect) {
- BoxPainterBase::PaintInsetBoxShadowWithBorderRect(
- info, paint_rect, s, IncludeLogicalLeftEdgeForBoxShadow(),
- IncludeLogicalRightEdgeForBoxShadow());
-}
-
static LayoutRect ClipRectForNinePieceImageStrip(const InlineFlowBox& box,
const NinePieceImage& image,
const LayoutRect& paint_rect) {
@@ -170,8 +108,7 @@ static LayoutRect ClipRectForNinePieceImageStrip(const InlineFlowBox& box,
}
LayoutRect InlineFlowBoxPainter::PaintRectForImageStrip(
- const LayoutPoint& paint_offset,
- const LayoutSize& frame_size,
+ const LayoutRect& paint_rect,
TextDirection direction) const {
// We have a fill/border/mask image that spans multiple lines.
// We need to adjust the offset by the width of all previous lines.
@@ -200,27 +137,28 @@ LayoutRect InlineFlowBoxPainter::PaintRectForImageStrip(
total_logical_width += curr->LogicalWidth();
}
LayoutUnit strip_x =
- paint_offset.X() -
+ paint_rect.X() -
(inline_flow_box_.IsHorizontal() ? logical_offset_on_line : LayoutUnit());
LayoutUnit strip_y =
- paint_offset.Y() -
+ paint_rect.Y() -
(inline_flow_box_.IsHorizontal() ? LayoutUnit() : logical_offset_on_line);
LayoutUnit strip_width = inline_flow_box_.IsHorizontal() ? total_logical_width
- : frame_size.Width();
+ : paint_rect.Width();
LayoutUnit strip_height = inline_flow_box_.IsHorizontal()
- ? frame_size.Height()
+ ? paint_rect.Height()
: total_logical_width;
return LayoutRect(strip_x, strip_y, strip_width, strip_height);
}
-InlineFlowBoxPainter::BorderPaintingType
+InlineBoxPainterBase::BorderPaintingType
InlineFlowBoxPainter::GetBorderPaintType(const LayoutRect& adjusted_frame_rect,
- IntRect& adjusted_clip_rect) const {
+ IntRect& adjusted_clip_rect,
+ bool object_has_multiple_boxes) const {
adjusted_clip_rect = PixelSnappedIntRect(adjusted_frame_rect);
if (inline_flow_box_.Parent() &&
- inline_flow_box_.GetLineLayoutItem().Style()->HasBorderDecoration()) {
+ inline_flow_box_.GetLineLayoutItem().StyleRef().HasBorderDecoration()) {
const NinePieceImage& border_image =
- inline_flow_box_.GetLineLayoutItem().Style()->BorderImage();
+ inline_flow_box_.GetLineLayoutItem().StyleRef().BorderImage();
StyleImage* border_image_source = border_image.GetImage();
bool has_border_image =
border_image_source && border_image_source->CanRender();
@@ -242,14 +180,7 @@ InlineFlowBoxPainter::GetBorderPaintType(const LayoutRect& adjusted_frame_rect,
return kDontPaintBorders;
}
-static inline Node* GetNode(const LayoutObject* box_model) {
- Node* node = nullptr;
- for (const LayoutObject* obj = box_model; obj && !node; obj = obj->Parent())
- node = obj->GeneratingNode();
- return node;
-}
-
-void InlineFlowBoxPainter::PaintBoxDecorationBackground(
+void InlineFlowBoxPainter::PaintBackgroundBorderShadow(
const PaintInfo& paint_info,
const LayoutPoint& paint_offset) {
DCHECK(paint_info.phase == PaintPhase::kForeground);
@@ -257,7 +188,7 @@ void InlineFlowBoxPainter::PaintBoxDecorationBackground(
if (RuntimeEnabledFeatures::PaintTouchActionRectsEnabled())
RecordHitTestData(paint_info, paint_offset);
- if (inline_flow_box_.GetLineLayoutItem().Style()->Visibility() !=
+ if (inline_flow_box_.GetLineLayoutItem().StyleRef().Visibility() !=
EVisibility::kVisible)
return;
@@ -265,17 +196,13 @@ void InlineFlowBoxPainter::PaintBoxDecorationBackground(
// boxes for a line may actually have to paint a background.
LayoutObject* inline_flow_box_layout_object =
LineLayoutAPIShim::LayoutObjectFrom(inline_flow_box_.GetLineLayoutItem());
- const ComputedStyle* style_to_use =
- inline_flow_box_.GetLineLayoutItem().Style(
- inline_flow_box_.IsFirstLineStyle());
bool should_paint_box_decoration_background;
if (inline_flow_box_.Parent())
should_paint_box_decoration_background =
inline_flow_box_layout_object->HasBoxDecorationBackground();
else
should_paint_box_decoration_background =
- inline_flow_box_.IsFirstLineStyle() &&
- style_to_use != inline_flow_box_.GetLineLayoutItem().Style();
+ inline_flow_box_.IsFirstLineStyle() && line_style_ != style_;
if (!should_paint_box_decoration_background)
return;
@@ -290,49 +217,16 @@ void InlineFlowBoxPainter::PaintBoxDecorationBackground(
LayoutRect paint_rect = AdjustedPaintRect(paint_offset);
- IntRect adjusted_clip_rect;
- BorderPaintingType border_painting_type =
- GetBorderPaintType(paint_rect, adjusted_clip_rect);
-
- // Shadow comes first and is behind the background and border.
- PaintNormalBoxShadow(paint_info, *style_to_use, paint_rect);
-
- Color background_color = inline_flow_box_layout_object->ResolveColor(
- *style_to_use, GetCSSPropertyBackgroundColor());
- PaintFillLayers(paint_info, background_color,
- style_to_use->BackgroundLayers(), paint_rect);
- PaintInsetBoxShadow(paint_info, *style_to_use, paint_rect);
-
- const LayoutObject* box_model = ToLayoutBoxModelObject(
+ bool object_has_multiple_boxes = inline_flow_box_.PrevForSameLayoutObject() ||
+ inline_flow_box_.NextForSameLayoutObject();
+ const auto& box_model = *ToLayoutBoxModelObject(
LineLayoutAPIShim::LayoutObjectFrom(inline_flow_box_.BoxModelObject()));
-
- switch (border_painting_type) {
- case kDontPaintBorders:
- break;
- case kPaintBordersWithoutClip:
- BoxPainterBase::PaintBorder(*box_model, box_model->GetDocument(),
- GetNode(box_model), paint_info, paint_rect,
- inline_flow_box_.GetLineLayoutItem().StyleRef(
- inline_flow_box_.IsFirstLineStyle()),
- kBackgroundBleedNone,
- inline_flow_box_.IncludeLogicalLeftEdge(),
- inline_flow_box_.IncludeLogicalRightEdge());
- break;
- case kPaintBordersWithClip:
- // FIXME: What the heck do we do with RTL here? The math we're using is
- // obviously not right, but it isn't even clear how this should work at
- // all.
- LayoutRect image_strip_paint_rect = PaintRectForImageStrip(
- paint_rect.Location(), paint_rect.Size(), TextDirection::kLtr);
- GraphicsContextStateSaver state_saver(paint_info.context);
- paint_info.context.Clip(adjusted_clip_rect);
- BoxPainterBase::PaintBorder(*box_model, box_model->GetDocument(),
- GetNode(box_model), paint_info,
- image_strip_paint_rect,
- inline_flow_box_.GetLineLayoutItem().StyleRef(
- inline_flow_box_.IsFirstLineStyle()));
- break;
- }
+ BackgroundImageGeometry geometry(box_model);
+ BoxModelObjectPainter box_painter(box_model, &inline_flow_box_);
+ PaintBoxDecorationBackground(box_painter, paint_info, paint_offset,
+ paint_rect, geometry, object_has_multiple_boxes,
+ inline_flow_box_.IncludeLogicalLeftEdge(),
+ inline_flow_box_.IncludeLogicalRightEdge());
}
void InlineFlowBoxPainter::PaintMask(const PaintInfo& paint_info,
@@ -356,10 +250,15 @@ void InlineFlowBoxPainter::PaintMask(const PaintInfo& paint_info,
const auto& mask_nine_piece_image = box_model.StyleRef().MaskBoxImage();
const auto* mask_box_image = mask_nine_piece_image.GetImage();
+ bool object_has_multiple_boxes = inline_flow_box_.PrevForSameLayoutObject() ||
+ inline_flow_box_.NextForSameLayoutObject();
// Figure out if we need to push a transparency layer to render our mask.
- PaintFillLayers(paint_info, Color::kTransparent,
- box_model.StyleRef().MaskLayers(), paint_rect);
+ BackgroundImageGeometry geometry(box_model);
+ BoxModelObjectPainter box_painter(box_model, &inline_flow_box_);
+ PaintFillLayers(box_painter, paint_info, Color::kTransparent,
+ box_model.StyleRef().MaskLayers(), paint_rect, geometry,
+ object_has_multiple_boxes);
bool has_box_image = mask_box_image && mask_box_image->CanRender();
if (!has_box_image || !mask_box_image->IsLoaded()) {
@@ -380,7 +279,8 @@ void InlineFlowBoxPainter::PaintMask(const PaintInfo& paint_info,
// FIXME: What the heck do we do with RTL here? The math we're using is
// obviously not right, but it isn't even clear how this should work at all.
LayoutRect image_strip_paint_rect = PaintRectForImageStrip(
- paint_rect.Location(), paint_rect.Size(), TextDirection::kLtr);
+ LayoutRect(paint_rect.Location(), paint_rect.Size()),
+ TextDirection::kLtr);
FloatRect clip_rect(ClipRectForNinePieceImageStrip(
inline_flow_box_, mask_nine_piece_image, paint_rect));
GraphicsContextStateSaver state_saver(paint_info.context);
@@ -446,4 +346,20 @@ void InlineFlowBoxPainter::RecordHitTestData(const PaintInfo& paint_info,
TouchActionRect(AdjustedPaintRect(paint_offset), touch_action));
}
+void InlineFlowBoxPainter::PaintNormalBoxShadow(const PaintInfo& info,
+ const ComputedStyle& s,
+ const LayoutRect& paint_rect) {
+ BoxPainterBase::PaintNormalBoxShadow(
+ info, paint_rect, s, inline_flow_box_.IncludeLogicalLeftEdge(),
+ inline_flow_box_.IncludeLogicalRightEdge());
+}
+
+void InlineFlowBoxPainter::PaintInsetBoxShadow(const PaintInfo& info,
+ const ComputedStyle& s,
+ const LayoutRect& paint_rect) {
+ BoxPainterBase::PaintInsetBoxShadowWithBorderRect(
+ info, paint_rect, s, inline_flow_box_.IncludeLogicalLeftEdge(),
+ inline_flow_box_.IncludeLogicalRightEdge());
+}
+
} // namespace blink
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 f3a6ccd1113..9029b8d2b76 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
@@ -5,6 +5,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_INLINE_FLOW_BOX_PAINTER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_INLINE_FLOW_BOX_PAINTER_H_
+#include "third_party/blink/renderer/core/paint/box_model_object_painter.h"
+#include "third_party/blink/renderer/core/paint/inline_box_painter_base.h"
#include "third_party/blink/renderer/core/style/shadow_data.h"
#include "third_party/blink/renderer/platform/graphics/graphics_types.h"
#include "third_party/blink/renderer/platform/text/text_direction.h"
@@ -12,23 +14,19 @@
namespace blink {
-class Color;
-class FillLayer;
class InlineFlowBox;
class IntRect;
class LayoutPoint;
class LayoutRect;
-class LayoutSize;
class LayoutUnit;
struct PaintInfo;
-class ComputedStyle;
-class InlineFlowBoxPainter {
+class InlineFlowBoxPainter : public InlineBoxPainterBase {
STACK_ALLOCATED();
public:
- InlineFlowBoxPainter(const InlineFlowBox& inline_flow_box)
- : inline_flow_box_(inline_flow_box) {}
+ InlineFlowBoxPainter(const InlineFlowBox&);
+
void Paint(const PaintInfo&,
const LayoutPoint& paint_offset,
const LayoutUnit line_top,
@@ -36,40 +34,25 @@ class InlineFlowBoxPainter {
LayoutRect FrameRectClampedToLineTopAndBottomIfNeeded() const;
- private:
- void PaintBoxDecorationBackground(const PaintInfo&,
- const LayoutPoint& paint_offset);
- void PaintMask(const PaintInfo&, const LayoutPoint& paint_offset);
- void PaintFillLayers(const PaintInfo&,
- const Color&,
- const FillLayer&,
- const LayoutRect&,
- SkBlendMode op = SkBlendMode::kSrcOver);
- void PaintFillLayer(const PaintInfo&,
- const Color&,
- const FillLayer&,
- const LayoutRect&,
- SkBlendMode op);
- inline bool ShouldForceIncludeLogicalEdges() const;
- inline bool IncludeLogicalLeftEdgeForBoxShadow() const;
- inline bool IncludeLogicalRightEdgeForBoxShadow() const;
+ protected:
+ LayoutRect PaintRectForImageStrip(const LayoutRect&,
+ TextDirection) const override;
void PaintNormalBoxShadow(const PaintInfo&,
const ComputedStyle&,
- const LayoutRect& paint_rect);
+ const LayoutRect& paint_rect) override;
void PaintInsetBoxShadow(const PaintInfo&,
const ComputedStyle&,
- const LayoutRect& paint_rect);
- LayoutRect PaintRectForImageStrip(const LayoutPoint& paint_offset,
- const LayoutSize& frame_size,
- TextDirection) const;
-
- enum BorderPaintingType {
- kDontPaintBorders,
- kPaintBordersWithoutClip,
- kPaintBordersWithClip
- };
- BorderPaintingType GetBorderPaintType(const LayoutRect& adjusted_frame_rect,
- IntRect& adjusted_clip_rect) const;
+ const LayoutRect& paint_rect) override;
+
+ private:
+ void PaintBackgroundBorderShadow(const PaintInfo&,
+ const LayoutPoint& paint_offset);
+ void PaintMask(const PaintInfo&, const LayoutPoint& paint_offset);
+
+ BorderPaintingType GetBorderPaintType(
+ const LayoutRect& adjusted_frame_rect,
+ IntRect& adjusted_clip_rect,
+ bool object_has_multiple_boxes) const override;
LayoutRect AdjustedPaintRect(const LayoutPoint& paint_offset) const;
diff --git a/chromium/third_party/blink/renderer/core/paint/inline_painter.cc b/chromium/third_party/blink/renderer/core/paint/inline_painter.cc
index f40a16ff8cd..a467c042e0f 100644
--- a/chromium/third_party/blink/renderer/core/paint/inline_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/inline_painter.cc
@@ -6,19 +6,19 @@
#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/paint/adjust_paint_offset_scope.h"
#include "third_party/blink/renderer/core/paint/line_box_list_painter.h"
#include "third_party/blink/renderer/core/paint/ng/ng_paint_fragment.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_info_with_offset.h"
#include "third_party/blink/renderer/platform/geometry/layout_point.h"
namespace blink {
void InlinePainter::Paint(const PaintInfo& paint_info) {
- AdjustPaintOffsetScope adjustment(layout_inline_, paint_info);
- auto paint_offset = adjustment.PaintOffset();
- const auto& local_paint_info = adjustment.GetPaintInfo();
+ PaintInfoWithOffset paint_info_with_offset(layout_inline_, paint_info);
+ auto paint_offset = paint_info_with_offset.PaintOffset();
+ const auto& local_paint_info = paint_info_with_offset.GetPaintInfo();
if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
// Inline box with self painting layer is painted in this code path.
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 4e03b11e1ae..44a593bee79 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
@@ -101,7 +101,7 @@ static void ComputeOriginAndWidthForBox(const InlineTextBox& box,
if (box.Truncation() != kCNoTruncation) {
bool ltr = box.IsLeftToRightDirection();
bool flow_is_ltr =
- box.GetLineLayoutItem().Style()->IsLeftToRightDirection();
+ box.GetLineLayoutItem().StyleRef().IsLeftToRightDirection();
width = LayoutUnit(box.GetLineLayoutItem().Width(
ltr == flow_is_ltr ? box.Start() : box.Start() + box.Truncation(),
ltr == flow_is_ltr ? box.Truncation() : box.Len() - box.Truncation(),
@@ -140,9 +140,9 @@ void InlineTextBoxPainter::Paint(const PaintInfo& paint_info,
bool is_printing = paint_info.IsPrinting();
// Determine whether or not we're selected.
- bool have_selection =
- !is_printing && paint_info.phase != PaintPhase::kTextClip &&
- inline_text_box_.GetSelectionState() != SelectionState::kNone;
+ bool have_selection = !is_printing &&
+ paint_info.phase != PaintPhase::kTextClip &&
+ inline_text_box_.IsSelected();
if (!have_selection && paint_info.phase == PaintPhase::kSelection) {
// When only painting the selection, don't bother to paint if there is none.
return;
@@ -302,8 +302,8 @@ void InlineTextBoxPainter::Paint(const PaintInfo& paint_info,
bool ltr = inline_text_box_.IsLeftToRightDirection();
bool flow_is_ltr = inline_text_box_.GetLineLayoutItem()
.ContainingBlock()
- .Style()
- ->IsLeftToRightDirection();
+ .StyleRef()
+ .IsLeftToRightDirection();
const PaintOffsets& selection_offsets =
ApplyTruncationToPaintOffsets({static_cast<unsigned>(selection_start),
@@ -430,7 +430,7 @@ bool InlineTextBoxPainter::ShouldPaintTextBox(const PaintInfo& paint_info) {
// This code path is only called in PaintPhaseForeground whereas we would
// expect PaintPhaseSelection. The existing haveSelection logic in paint()
// tests for != PaintPhaseTextClip.
- if (inline_text_box_.GetLineLayoutItem().Style()->Visibility() !=
+ if (inline_text_box_.GetLineLayoutItem().StyleRef().Visibility() !=
EVisibility::kVisible ||
inline_text_box_.Truncation() == kCFullTruncation ||
!inline_text_box_.Len())
@@ -451,8 +451,8 @@ InlineTextBoxPainter::ApplyTruncationToPaintOffsets(
bool ltr = inline_text_box_.IsLeftToRightDirection();
bool flow_is_ltr = inline_text_box_.GetLineLayoutItem()
.ContainingBlock()
- .Style()
- ->IsLeftToRightDirection();
+ .StyleRef()
+ .IsLeftToRightDirection();
// truncation is relative to the start of the InlineTextBox, not the text
// node.
@@ -513,13 +513,14 @@ void InlineTextBoxPainter::PaintSingleMarkerBackgroundRun(
if (background_color == Color::kTransparent)
return;
- int delta_y =
- (inline_text_box_.GetLineLayoutItem().Style()->IsFlippedLinesWritingMode()
- ? inline_text_box_.Root().SelectionBottom() -
- inline_text_box_.LogicalBottom()
- : inline_text_box_.LogicalTop() -
- inline_text_box_.Root().SelectionTop())
- .ToInt();
+ int delta_y = (inline_text_box_.GetLineLayoutItem()
+ .StyleRef()
+ .IsFlippedLinesWritingMode()
+ ? inline_text_box_.Root().SelectionBottom() -
+ inline_text_box_.LogicalBottom()
+ : inline_text_box_.LogicalTop() -
+ inline_text_box_.Root().SelectionTop())
+ .ToInt();
int sel_height = inline_text_box_.Root().SelectionHeight().ToInt();
FloatPoint local_origin(box_origin.X().ToFloat(),
box_origin.Y().ToFloat() - delta_y);
@@ -530,12 +531,12 @@ void InlineTextBoxPainter::PaintSingleMarkerBackgroundRun(
DocumentMarkerVector InlineTextBoxPainter::ComputeMarkersToPaint() const {
Node* const node = inline_text_box_.GetLineLayoutItem().GetNode();
- if (!node)
+ if (!node || !node->IsTextNode())
return DocumentMarkerVector();
DocumentMarkerController& document_marker_controller =
inline_text_box_.GetLineLayoutItem().GetDocument().Markers();
- return document_marker_controller.ComputeMarkersToPaint(*node);
+ return document_marker_controller.ComputeMarkersToPaint(ToText(*node));
}
void InlineTextBoxPainter::PaintDocumentMarkers(
@@ -646,8 +647,8 @@ void InlineTextBoxPainter::PaintDocumentMarker(GraphicsContext& context,
// Calculate start & width
int delta_y = (inline_text_box_.GetLineLayoutItem()
- .Style()
- ->IsFlippedLinesWritingMode()
+ .StyleRef()
+ .IsFlippedLinesWritingMode()
? inline_text_box_.Root().SelectionBottom() -
inline_text_box_.LogicalBottom()
: inline_text_box_.LogicalTop() -
@@ -689,8 +690,8 @@ LayoutRect InlineTextBoxPainter::GetSelectionRect(
bool ltr = inline_text_box_.IsLeftToRightDirection();
bool flow_is_ltr = inline_text_box_.GetLineLayoutItem()
.ContainingBlock()
- .Style()
- ->IsLeftToRightDirection();
+ .StyleRef()
+ .IsLeftToRightDirection();
if (inline_text_box_.Truncation() != kCNoTruncation) {
// In a mixed-direction flow the ellipsis is at the start of the text
// so we need to start after it. Otherwise we just need to make sure
@@ -723,10 +724,12 @@ LayoutRect InlineTextBoxPainter::GetSelectionRect(
LayoutUnit selection_bottom = inline_text_box_.Root().SelectionBottom();
LayoutUnit selection_top = inline_text_box_.Root().SelectionTop();
- int delta_y = RoundToInt(
- inline_text_box_.GetLineLayoutItem().Style()->IsFlippedLinesWritingMode()
- ? selection_bottom - inline_text_box_.LogicalBottom()
- : inline_text_box_.LogicalTop() - selection_top);
+ int delta_y =
+ RoundToInt(inline_text_box_.GetLineLayoutItem()
+ .StyleRef()
+ .IsFlippedLinesWritingMode()
+ ? selection_bottom - inline_text_box_.LogicalBottom()
+ : inline_text_box_.LogicalTop() - selection_top);
int sel_height = std::max(0, RoundToInt(selection_bottom - selection_top));
FloatPoint local_origin(box_rect.X().ToFloat(),
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 683971be2ce..6a2ea276ed8 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
@@ -88,12 +88,10 @@ LinkHighlightImpl::LinkHighlightImpl(Node* node)
DCHECK(compositor_animation_);
compositor_animation_->SetAnimationDelegate(this);
- CompositorElementId element_id =
- CompositorElementIdFromUniqueObjectId(unique_id_);
- compositor_animation_->AttachElement(element_id);
+ compositor_animation_->AttachElement(element_id());
content_layer_->SetIsDrawable(true);
content_layer_->SetOpacity(1);
- content_layer_->SetElementId(element_id);
+ content_layer_->SetElementId(element_id());
geometry_needs_update_ = true;
}
@@ -108,6 +106,11 @@ LinkHighlightImpl::~LinkHighlightImpl() {
}
void LinkHighlightImpl::ReleaseResources() {
+ if (!node_)
+ return;
+
+ if (auto* layout_object = node_->GetLayoutObject())
+ layout_object->SetNeedsPaintPropertyUpdate();
node_.Clear();
}
@@ -267,7 +270,8 @@ LinkHighlightImpl::PaintContentsToDisplayList(
PaintFlags flags;
flags.setStyle(PaintFlags::kFill_Style);
flags.setAntiAlias(true);
- flags.setColor(node_->GetLayoutObject()->Style()->TapHighlightColor().Rgb());
+ flags.setColor(
+ node_->GetLayoutObject()->StyleRef().TapHighlightColor().Rgb());
canvas->drawPath(path_.GetSkPath(), flags);
display_list->StartPaint();
@@ -395,4 +399,20 @@ CompositorAnimation* LinkHighlightImpl::GetCompositorAnimation() const {
return compositor_animation_.get();
}
+CompositorElementId LinkHighlightImpl::element_id() {
+ return CompositorElementIdFromUniqueObjectId(unique_id_);
+}
+
+const EffectPaintPropertyNode* LinkHighlightImpl::effect() {
+ if (!node_)
+ return nullptr;
+
+ if (auto* layout_object = node_->GetLayoutObject()) {
+ if (auto* properties = layout_object->FirstFragment().PaintProperties())
+ return properties->LinkHighlightEffect();
+ }
+
+ return nullptr;
+}
+
} // namespace blink
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 2158cf774e1..0ead7e9d11a 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
@@ -60,6 +60,11 @@ class CORE_EXPORT LinkHighlightImpl final : public LinkHighlight,
~LinkHighlightImpl() override;
void StartHighlightAnimationIfNeeded();
+
+ // Recalculates |path_| based on |node_|'s geometry and updates the link
+ // highlight layer. To avoid re-computing |path_|, a dirty bit is used
+ // (see |geometry_needs_update_| and |Invalidate()|) which is based on raster
+ // invalidation of the owning graphics layer.
void UpdateGeometry();
// cc::ContentLayerClient implementation.
@@ -86,6 +91,12 @@ class CORE_EXPORT LinkHighlightImpl final : public LinkHighlight,
return current_graphics_layer_;
}
+ Node* GetNode() const { return node_; }
+
+ CompositorElementId element_id();
+
+ const EffectPaintPropertyNode* effect() override;
+
private:
LinkHighlightImpl(Node*);
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 1739a05d66b..3282070f328 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
@@ -27,6 +27,7 @@
#include <memory>
+#include "cc/trees/layer_tree_host.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_float_point.h"
@@ -45,41 +46,75 @@
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.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/page/touch_disambiguation.h"
#include "third_party/blink/renderer/platform/animation/compositor_animation_timeline.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/geometry/int_rect.h"
+#include "third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h"
#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
#include "third_party/blink/renderer/platform/testing/url_test_helpers.h"
namespace blink {
-namespace {
-
-GestureEventWithHitTestResults GetTargetedEvent(WebViewImpl* web_view_impl,
- WebGestureEvent& touch_event) {
- WebGestureEvent scaled_event = TransformWebGestureEvent(
- web_view_impl->MainFrameImpl()->GetFrameView(), touch_event);
- return web_view_impl->GetPage()
- ->DeprecatedLocalMainFrame()
- ->GetEventHandler()
- .TargetGestureEvent(scaled_event, true);
-}
-
-std::string LinkRegisterMockedURLLoad() {
- WebURL url = URLTestHelpers::RegisterMockedURLLoadFromBase(
- WebString::FromUTF8("http://www.test.com/"), test::CoreTestDataPath(),
- WebString::FromUTF8("test_touch_link_highlight.html"));
- return url.GetString().Utf8();
-}
-
-} // namespace
-
-TEST(LinkHighlightImplTest, verifyWebViewImplIntegration) {
- const std::string url = LinkRegisterMockedURLLoad();
- FrameTestHelpers::WebViewHelper web_view_helper;
- WebViewImpl* web_view_impl = web_view_helper.InitializeAndLoad(url);
+class LinkHighlightImplTest : public testing::Test,
+ public testing::WithParamInterface<bool>,
+ private ScopedBlinkGenPropertyTreesForTest {
+ public:
+ LinkHighlightImplTest() : ScopedBlinkGenPropertyTreesForTest(GetParam()) {}
+
+ protected:
+ GestureEventWithHitTestResults GetTargetedEvent(
+ WebGestureEvent& touch_event) {
+ WebGestureEvent scaled_event = TransformWebGestureEvent(
+ web_view_helper_.GetWebView()->MainFrameImpl()->GetFrameView(),
+ touch_event);
+ return web_view_helper_.GetWebView()
+ ->GetPage()
+ ->DeprecatedLocalMainFrame()
+ ->GetEventHandler()
+ .TargetGestureEvent(scaled_event, true);
+ }
+
+ void SetUp() override {
+ WebURL url = URLTestHelpers::RegisterMockedURLLoadFromBase(
+ WebString::FromUTF8("http://www.test.com/"), test::CoreTestDataPath(),
+ WebString::FromUTF8("test_touch_link_highlight.html"));
+ web_view_helper_.InitializeAndLoad(url.GetString().Utf8());
+ }
+
+ void TearDown() override {
+ Platform::Current()
+ ->GetURLLoaderMockFactory()
+ ->UnregisterAllURLsAndClearMemoryCache();
+
+ // Ensure we fully clean up while scoped settings are enabled. Without this,
+ // garbage collection would occur after ScopedBlinkGenPropertyTreesForTest
+ // is out of scope, so the settings would not apply in some destructors.
+ web_view_helper_.Reset();
+ ThreadState::Current()->CollectAllGarbage();
+ }
+
+ size_t ContentLayerCount() {
+ // paint_artifact_compositor()->EnableExtraDataForTesting() should be called
+ // before using this function.
+ DCHECK(paint_artifact_compositor()->GetExtraDataForTesting());
+ return paint_artifact_compositor()
+ ->GetExtraDataForTesting()
+ ->content_layers.size();
+ }
+
+ PaintArtifactCompositor* paint_artifact_compositor() {
+ auto* local_frame_view = web_view_helper_.LocalMainFrame()->GetFrameView();
+ return local_frame_view->GetPaintArtifactCompositorForTesting();
+ }
+
+ FrameTestHelpers::WebViewHelper web_view_helper_;
+};
+
+INSTANTIATE_TEST_CASE_P(All, LinkHighlightImplTest, testing::Bool());
+
+TEST_P(LinkHighlightImplTest, verifyWebViewImplIntegration) {
+ WebViewImpl* web_view_impl = web_view_helper_.GetWebView();
int page_width = 640;
int page_height = 480;
web_view_impl->Resize(WebSize(page_width, page_height));
@@ -94,17 +129,14 @@ TEST(LinkHighlightImplTest, verifyWebViewImplIntegration) {
// .html file.
touch_event.SetPositionInWidget(WebFloatPoint(20, 20));
- ASSERT_TRUE(
- web_view_impl->BestTapNode(GetTargetedEvent(web_view_impl, touch_event)));
+ ASSERT_TRUE(web_view_impl->BestTapNode(GetTargetedEvent(touch_event)));
touch_event.SetPositionInWidget(WebFloatPoint(20, 40));
- EXPECT_FALSE(
- web_view_impl->BestTapNode(GetTargetedEvent(web_view_impl, touch_event)));
+ EXPECT_FALSE(web_view_impl->BestTapNode(GetTargetedEvent(touch_event)));
touch_event.SetPositionInWidget(WebFloatPoint(20, 20));
// Shouldn't crash.
- web_view_impl->EnableTapHighlightAtPoint(
- GetTargetedEvent(web_view_impl, touch_event));
+ web_view_impl->EnableTapHighlightAtPoint(GetTargetedEvent(touch_event));
const auto& highlights =
web_view_impl->GetPage()->GetLinkHighlights().link_highlights_;
@@ -113,8 +145,7 @@ TEST(LinkHighlightImplTest, verifyWebViewImplIntegration) {
// Find a target inside a scrollable div
touch_event.SetPositionInWidget(WebFloatPoint(20, 100));
- web_view_impl->EnableTapHighlightAtPoint(
- GetTargetedEvent(web_view_impl, touch_event));
+ web_view_impl->EnableTapHighlightAtPoint(GetTargetedEvent(touch_event));
ASSERT_TRUE(highlights.at(0));
// Enesure the timeline was added to a host.
@@ -126,24 +157,16 @@ TEST(LinkHighlightImplTest, verifyWebViewImplIntegration) {
// Don't highlight if no "hand cursor"
touch_event.SetPositionInWidget(
WebFloatPoint(20, 220)); // An A-link with cross-hair cursor.
- web_view_impl->EnableTapHighlightAtPoint(
- GetTargetedEvent(web_view_impl, touch_event));
+ web_view_impl->EnableTapHighlightAtPoint(GetTargetedEvent(touch_event));
ASSERT_EQ(0U, highlights.size());
touch_event.SetPositionInWidget(WebFloatPoint(20, 260)); // A text input box.
- web_view_impl->EnableTapHighlightAtPoint(
- GetTargetedEvent(web_view_impl, touch_event));
+ web_view_impl->EnableTapHighlightAtPoint(GetTargetedEvent(touch_event));
ASSERT_EQ(0U, highlights.size());
-
- Platform::Current()
- ->GetURLLoaderMockFactory()
- ->UnregisterAllURLsAndClearMemoryCache();
}
-TEST(LinkHighlightImplTest, resetDuringNodeRemoval) {
- const std::string url = LinkRegisterMockedURLLoad();
- FrameTestHelpers::WebViewHelper web_view_helper;
- WebViewImpl* web_view_impl = web_view_helper.InitializeAndLoad(url);
+TEST_P(LinkHighlightImplTest, resetDuringNodeRemoval) {
+ WebViewImpl* web_view_impl = web_view_helper_.GetWebView();
int page_width = 640;
int page_height = 480;
@@ -156,8 +179,7 @@ TEST(LinkHighlightImplTest, resetDuringNodeRemoval) {
kWebGestureDeviceTouchscreen);
touch_event.SetPositionInWidget(WebFloatPoint(20, 20));
- GestureEventWithHitTestResults targeted_event =
- GetTargetedEvent(web_view_impl, touch_event);
+ GestureEventWithHitTestResults targeted_event = GetTargetedEvent(touch_event);
Node* touch_node = web_view_impl->BestTapNode(targeted_event);
ASSERT_TRUE(touch_node);
@@ -168,22 +190,16 @@ TEST(LinkHighlightImplTest, resetDuringNodeRemoval) {
GraphicsLayer* highlight_layer =
highlights.link_highlights_.at(0)->CurrentGraphicsLayerForTesting();
ASSERT_TRUE(highlight_layer);
- EXPECT_TRUE(highlight_layer->GetLinkHighlight(0));
+ EXPECT_TRUE(highlight_layer->GetLinkHighlights().at(0));
touch_node->remove(IGNORE_EXCEPTION_FOR_TESTING);
web_view_impl->UpdateAllLifecyclePhases();
- EXPECT_EQ(0U, highlight_layer->NumLinkHighlights());
-
- Platform::Current()
- ->GetURLLoaderMockFactory()
- ->UnregisterAllURLsAndClearMemoryCache();
+ EXPECT_EQ(0U, highlight_layer->GetLinkHighlights().size());
}
// A lifetime test: delete LayerTreeView while running LinkHighlights.
-TEST(LinkHighlightImplTest, resetLayerTreeView) {
- const std::string url = LinkRegisterMockedURLLoad();
- FrameTestHelpers::WebViewHelper web_view_helper;
- WebViewImpl* web_view_impl = web_view_helper.InitializeAndLoad(url);
+TEST_P(LinkHighlightImplTest, resetLayerTreeView) {
+ WebViewImpl* web_view_impl = web_view_helper_.GetWebView();
int page_width = 640;
int page_height = 480;
@@ -196,8 +212,7 @@ TEST(LinkHighlightImplTest, resetLayerTreeView) {
kWebGestureDeviceTouchscreen);
touch_event.SetPositionInWidget(WebFloatPoint(20, 20));
- GestureEventWithHitTestResults targeted_event =
- GetTargetedEvent(web_view_impl, touch_event);
+ GestureEventWithHitTestResults targeted_event = GetTargetedEvent(touch_event);
Node* touch_node = web_view_impl->BestTapNode(targeted_event);
ASSERT_TRUE(touch_node);
@@ -209,45 +224,57 @@ TEST(LinkHighlightImplTest, resetLayerTreeView) {
GraphicsLayer* highlight_layer =
highlights.at(0)->CurrentGraphicsLayerForTesting();
ASSERT_TRUE(highlight_layer);
- EXPECT_TRUE(highlight_layer->GetLinkHighlight(0));
-
- Platform::Current()
- ->GetURLLoaderMockFactory()
- ->UnregisterAllURLsAndClearMemoryCache();
+ EXPECT_TRUE(highlight_layer->GetLinkHighlights().at(0));
}
-TEST(LinkHighlightImplTest, multipleHighlights) {
- const std::string url = LinkRegisterMockedURLLoad();
- FrameTestHelpers::WebViewHelper web_view_helper;
- WebViewImpl* web_view_impl = web_view_helper.InitializeAndLoad(url);
+TEST_P(LinkHighlightImplTest, HighlightLayerEffectNode) {
+ // This is testing the blink->cc layer integration.
+ if (!RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled())
+ return;
int page_width = 640;
int page_height = 480;
+ WebViewImpl* web_view_impl = web_view_helper_.GetWebView();
web_view_impl->Resize(WebSize(page_width, page_height));
+
+ paint_artifact_compositor()->EnableExtraDataForTesting();
web_view_impl->UpdateAllLifecyclePhases();
+ size_t layer_count_before_highlight = ContentLayerCount();
- WebGestureEvent touch_event;
- touch_event.SetPositionInWidget(WebFloatPoint(50, 310));
- touch_event.data.tap.width = 30;
- touch_event.data.tap.height = 30;
-
- Vector<IntRect> good_targets;
- HeapVector<Member<Node>> highlight_nodes;
- IntRect bounding_box(
- touch_event.PositionInWidget().x - touch_event.data.tap.width / 2,
- touch_event.PositionInWidget().y - touch_event.data.tap.height / 2,
- touch_event.data.tap.width, touch_event.data.tap.height);
- FindGoodTouchTargets(bounding_box, web_view_impl->MainFrameImpl()->GetFrame(),
- good_targets, highlight_nodes);
-
- web_view_impl->EnableTapHighlights(highlight_nodes);
- const auto& highlights =
- web_view_impl->GetPage()->GetLinkHighlights().link_highlights_;
- EXPECT_EQ(2U, highlights.size());
+ WebGestureEvent touch_event(WebInputEvent::kGestureShowPress,
+ WebInputEvent::kNoModifiers,
+ WebInputEvent::GetStaticTimeStampForTests(),
+ kWebGestureDeviceTouchscreen);
+ touch_event.SetPositionInWidget(WebFloatPoint(20, 20));
+
+ GestureEventWithHitTestResults targeted_event = GetTargetedEvent(touch_event);
+ Node* touch_node = web_view_impl->BestTapNode(targeted_event);
+ ASSERT_TRUE(touch_node);
- Platform::Current()
- ->GetURLLoaderMockFactory()
- ->UnregisterAllURLsAndClearMemoryCache();
+ web_view_impl->EnableTapHighlightAtPoint(targeted_event);
+ // The highlight should create one additional layer.
+ EXPECT_EQ(layer_count_before_highlight + 1, ContentLayerCount());
+
+ const auto& highlights = web_view_impl->GetPage()->GetLinkHighlights();
+ auto* highlight = highlights.link_highlights_.at(0).get();
+ ASSERT_TRUE(highlight);
+
+ // Check that the link highlight cc layer has a cc effect property tree node.
+ auto* layer = highlight->Layer();
+ auto effect_tree_index = layer->effect_tree_index();
+ auto* property_trees = layer->layer_tree_host()->property_trees();
+ EXPECT_EQ(
+ effect_tree_index,
+ property_trees->element_id_to_effect_node_index[layer->element_id()]);
+ // The link highlight cc effect node should correspond to the blink effect
+ // node.
+ EXPECT_EQ(highlight->effect()->GetCompositorElementId(), layer->element_id());
+ EXPECT_TRUE(highlight->effect()->RequiresCompositingForAnimation());
+
+ touch_node->remove(IGNORE_EXCEPTION_FOR_TESTING);
+ web_view_impl->UpdateAllLifecyclePhases();
+ // Removing the highlight layer should drop the cc layer count by one.
+ EXPECT_EQ(layer_count_before_highlight, ContentLayerCount());
}
} // 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 a591be96a34..833bda68337 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
@@ -4,13 +4,12 @@
#include "third_party/blink/renderer/core/paint/list_marker_painter.h"
-#include "third_party/blink/renderer/core/layout/api/selection_state.h"
#include "third_party/blink/renderer/core/layout/layout_list_item.h"
#include "third_party/blink/renderer/core/layout/layout_list_marker.h"
#include "third_party/blink/renderer/core/layout/list_marker_text.h"
-#include "third_party/blink/renderer/core/paint/adjust_paint_offset_scope.h"
#include "third_party/blink/renderer/core/paint/box_model_object_painter.h"
#include "third_party/blink/renderer/core/paint/paint_info.h"
+#include "third_party/blink/renderer/core/paint/paint_info_with_offset.h"
#include "third_party/blink/renderer/core/paint/selection_painting_utils.h"
#include "third_party/blink/renderer/core/paint/text_painter.h"
#include "third_party/blink/renderer/platform/fonts/text_run_paint_info.h"
@@ -55,22 +54,21 @@ void ListMarkerPainter::Paint(const PaintInfo& paint_info) {
if (paint_info.phase != PaintPhase::kForeground)
return;
- if (layout_list_marker_.Style()->Visibility() != EVisibility::kVisible)
+ if (layout_list_marker_.StyleRef().Visibility() != EVisibility::kVisible)
return;
if (DrawingRecorder::UseCachedDrawingIfPossible(
paint_info.context, layout_list_marker_, paint_info.phase))
return;
- AdjustPaintOffsetScope adjustment(layout_list_marker_, paint_info);
- const auto& local_paint_info = adjustment.GetPaintInfo();
- auto box_origin = adjustment.PaintOffset();
- LayoutRect overflow_rect(layout_list_marker_.VisualOverflowRect());
- overflow_rect.MoveBy(box_origin);
-
- if (!local_paint_info.GetCullRect().IntersectsCullRect(overflow_rect))
+ PaintInfoWithOffset paint_info_with_offset(layout_list_marker_, paint_info);
+ if (!paint_info_with_offset.LocalRectIntersectsCullRect(
+ layout_list_marker_.PhysicalVisualOverflowRect()))
return;
+ const auto& local_paint_info = paint_info_with_offset.GetPaintInfo();
+ auto box_origin = paint_info_with_offset.PaintOffset();
+
DrawingRecorder recorder(local_paint_info.context, layout_list_marker_,
local_paint_info.phase);
@@ -90,15 +88,6 @@ void ListMarkerPainter::Paint(const PaintInfo& paint_info) {
layout_list_marker_.StyleRef(), FloatSize(marker.Size()))
.get(),
Image::kSyncDecode, FloatRect(marker));
- if (layout_list_marker_.GetSelectionState() != SelectionState::kNone) {
- LayoutRect sel_rect = layout_list_marker_.LocalSelectionRect();
- sel_rect.MoveBy(box_origin);
- Color selection_bg = SelectionPaintingUtils::SelectionBackgroundColor(
- layout_list_marker_.ListItem()->GetDocument(),
- layout_list_marker_.ListItem()->StyleRef(),
- layout_list_marker_.ListItem()->GetNode());
- context.FillRect(PixelSnappedIntRect(sel_rect), selection_bg);
- }
return;
}
@@ -126,12 +115,12 @@ void ListMarkerPainter::Paint(const PaintInfo& paint_info) {
// Apply the color to the list marker text.
context.SetFillColor(color);
- const Font& font = layout_list_marker_.Style()->GetFont();
+ const Font& font = layout_list_marker_.StyleRef().GetFont();
TextRun text_run = ConstructTextRun(font, layout_list_marker_.GetText(),
layout_list_marker_.StyleRef());
GraphicsContextStateSaver state_saver(context, false);
- if (!layout_list_marker_.Style()->IsHorizontalWritingMode()) {
+ if (!layout_list_marker_.StyleRef().IsHorizontalWritingMode()) {
marker.MoveBy(-box_origin);
marker = marker.TransposedRect();
marker.MoveBy(
@@ -146,7 +135,7 @@ void ListMarkerPainter::Paint(const PaintInfo& paint_info) {
TextRunPaintInfo text_run_paint_info(text_run);
text_run_paint_info.bounds = FloatRect(EnclosingIntRect(marker));
const SimpleFontData* font_data =
- layout_list_marker_.Style()->GetFont().PrimaryFont();
+ layout_list_marker_.StyleRef().GetFont().PrimaryFont();
FloatPoint text_origin =
FloatPoint(marker.X().Round(),
marker.Y().Round() +
@@ -168,16 +157,16 @@ void ListMarkerPainter::Paint(const PaintInfo& paint_info) {
}
const UChar suffix =
- ListMarkerText::Suffix(layout_list_marker_.Style()->ListStyleType(),
+ ListMarkerText::Suffix(layout_list_marker_.StyleRef().ListStyleType(),
layout_list_marker_.ListItem()->Value());
UChar suffix_str[2] = {suffix, static_cast<UChar>(' ')};
TextRun suffix_run =
ConstructTextRun(font, suffix_str, 2, layout_list_marker_.StyleRef(),
- layout_list_marker_.Style()->Direction());
+ layout_list_marker_.StyleRef().Direction());
TextRunPaintInfo suffix_run_info(suffix_run);
suffix_run_info.bounds = FloatRect(EnclosingIntRect(marker));
- if (layout_list_marker_.Style()->IsLeftToRightDirection()) {
+ if (layout_list_marker_.StyleRef().IsLeftToRightDirection()) {
context.DrawText(font, text_run_paint_info, text_origin);
context.DrawText(font, suffix_run_info,
text_origin + FloatSize(IntSize(font.Width(text_run), 0)));
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 04eef4d7a3e..2f55be43865 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
@@ -16,7 +16,7 @@ namespace blink {
void MultiColumnSetPainter::PaintObject(const PaintInfo& paint_info,
const LayoutPoint& paint_offset) {
- if (layout_multi_column_set_.Style()->Visibility() != EVisibility::kVisible)
+ if (layout_multi_column_set_.StyleRef().Visibility() != EVisibility::kVisible)
return;
BlockPainter(layout_multi_column_set_).PaintObject(paint_info, paint_offset);
@@ -54,7 +54,7 @@ void MultiColumnSetPainter::PaintColumnRules(const PaintInfo& paint_info,
layout_multi_column_set_.MultiColumnBlockFlow()->StyleRef();
EBorderStyle rule_style = block_style.ColumnRuleStyle();
bool left_to_right =
- layout_multi_column_set_.Style()->IsLeftToRightDirection();
+ layout_multi_column_set_.StyleRef().IsLeftToRightDirection();
BoxSide box_side = layout_multi_column_set_.IsHorizontalWritingMode()
? left_to_right ? BoxSide::kLeft : BoxSide::kRight
: left_to_right ? BoxSide::kTop : BoxSide::kBottom;
diff --git a/chromium/third_party/blink/renderer/core/paint/ng/ng_box_clipper.cc b/chromium/third_party/blink/renderer/core/paint/ng/ng_box_clipper.cc
deleted file mode 100644
index 78b60daf91c..00000000000
--- a/chromium/third_party/blink/renderer/core/paint/ng/ng_box_clipper.cc
+++ /dev/null
@@ -1,27 +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/paint/ng/ng_box_clipper.h"
-
-#include "third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h"
-#include "third_party/blink/renderer/core/paint/paint_info.h"
-#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
-
-namespace blink {
-
-NGBoxClipper::NGBoxClipper(const NGPaintFragment& fragment,
- const PaintInfo& paint_info) {
- DCHECK(paint_info.phase != PaintPhase::kSelfBlockBackgroundOnly &&
- paint_info.phase != PaintPhase::kSelfOutlineOnly);
-
- if (paint_info.phase == PaintPhase::kMask)
- return;
-
- DCHECK(fragment.GetLayoutObject());
- InitializeScopedClipProperty(
- paint_info.FragmentToPaint(*fragment.GetLayoutObject()), fragment,
- paint_info);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/ng/ng_box_clipper.h b/chromium/third_party/blink/renderer/core/paint/ng/ng_box_clipper.h
deleted file mode 100644
index 243be3539d5..00000000000
--- a/chromium/third_party/blink/renderer/core/paint/ng/ng_box_clipper.h
+++ /dev/null
@@ -1,23 +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 NGBoxClipper_h
-#define NGBoxClipper_h
-
-#include "third_party/blink/renderer/core/paint/box_clipper_base.h"
-
-namespace blink {
-
-class NGPaintFragment;
-
-class NGBoxClipper : public BoxClipperBase {
- DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
-
- public:
- NGBoxClipper(const NGPaintFragment&, const PaintInfo&);
-};
-
-} // namespace blink
-
-#endif // NGBoxClipper_h
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 67dc662e244..727387e24f1 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,9 @@
#include "third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.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"
#include "third_party/blink/renderer/core/layout/background_bleed_avoidance.h"
#include "third_party/blink/renderer/core/layout/hit_test_location.h"
#include "third_party/blink/renderer/core/layout/hit_test_result.h"
@@ -17,18 +20,20 @@
#include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/layout_ng_mixin.h"
#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
-#include "third_party/blink/renderer/core/paint/adjust_paint_offset_scope.h"
+#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/paint/background_image_geometry.h"
#include "third_party/blink/renderer/core/paint/box_decoration_data.h"
#include "third_party/blink/renderer/core/paint/list_marker_painter.h"
-#include "third_party/blink/renderer/core/paint/ng/ng_box_clipper.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_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"
#include "third_party/blink/renderer/core/paint/paint_info.h"
+#include "third_party/blink/renderer/core/paint/paint_info_with_offset.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/core/paint/paint_phase.h"
+#include "third_party/blink/renderer/core/paint/scoped_box_clipper.h"
#include "third_party/blink/renderer/core/paint/scrollable_area_painter.h"
#include "third_party/blink/renderer/platform/geometry/layout_rect_outsets.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context_state_saver.h"
@@ -115,16 +120,20 @@ bool HitTestCulledInlineAncestors(HitTestResult& result,
return false;
}
+// Returns if this fragment may not be laid out by LayoutNG.
+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();
+}
+
} // anonymous namespace
NGBoxFragmentPainter::NGBoxFragmentPainter(const NGPaintFragment& box)
- : BoxPainterBase(
- &box.GetLayoutObject()->GetDocument(),
- box.Style(),
- box.GetLayoutObject()->GeneratingNode(),
- BoxStrutToLayoutRectOutsets(box.PhysicalFragment().BorderWidths()),
- BoxStrutToLayoutRectOutsets(
- ToNGPhysicalBoxFragment(box.PhysicalFragment()).Padding())),
+ : BoxPainterBase(&box.GetLayoutObject()->GetDocument(),
+ box.Style(),
+ box.GetLayoutObject()->GeneratingNode()),
box_fragment_(box),
border_edges_(
NGBorderEdges::FromPhysical(box.PhysicalFragment().BorderEdges(),
@@ -133,16 +142,15 @@ NGBoxFragmentPainter::NGBoxFragmentPainter(const NGPaintFragment& box)
}
void NGBoxFragmentPainter::Paint(const PaintInfo& paint_info) {
- AdjustPaintOffsetScope adjustment(box_fragment_, paint_info);
- auto& info = adjustment.MutablePaintInfo();
- auto paint_offset = adjustment.PaintOffset();
-
- if (!IntersectsPaintRect(info, paint_offset))
+ PaintInfoWithOffset paint_info_with_offset(box_fragment_, paint_info);
+ if (!ShouldPaint(paint_info_with_offset))
return;
+ PaintInfo& info = paint_info_with_offset.MutablePaintInfo();
if (PhysicalFragment().IsAtomicInline())
return PaintAtomicInline(info);
+ LayoutPoint paint_offset = paint_info_with_offset.PaintOffset();
PaintPhase original_phase = info.phase;
if (original_phase == PaintPhase::kOutline) {
@@ -156,11 +164,12 @@ void NGBoxFragmentPainter::Paint(const PaintInfo& paint_info) {
if (original_phase != PaintPhase::kSelfBlockBackgroundOnly &&
original_phase != PaintPhase::kSelfOutlineOnly) {
- base::Optional<NGBoxClipper> box_clipper;
+ base::Optional<ScopedBoxClipper> box_clipper;
if (original_phase == PaintPhase::kForeground ||
original_phase == PaintPhase::kFloat ||
- original_phase == PaintPhase::kDescendantOutlinesOnly)
+ original_phase == PaintPhase::kDescendantOutlinesOnly) {
box_clipper.emplace(box_fragment_, info);
+ }
PaintObject(info, paint_offset);
}
@@ -176,17 +185,6 @@ void NGBoxFragmentPainter::Paint(const PaintInfo& paint_info) {
PaintOverflowControlsIfNeeded(info, paint_offset);
}
-void NGBoxFragmentPainter::PaintInlineBox(const PaintInfo& paint_info,
- const LayoutPoint& paint_offset) {
- const LayoutPoint adjusted_paint_offset =
- paint_offset + box_fragment_.Offset().ToLayoutPoint();
- if (paint_info.phase == PaintPhase::kForeground &&
- box_fragment_.Style().Visibility() == EVisibility::kVisible)
- PaintBoxDecorationBackground(paint_info, adjusted_paint_offset);
-
- PaintObject(paint_info, adjusted_paint_offset, true);
-}
-
void NGBoxFragmentPainter::PaintObject(
const PaintInfo& paint_info,
const LayoutPoint& paint_offset,
@@ -274,12 +272,25 @@ void NGBoxFragmentPainter::PaintObject(
if (ShouldPaintSelfOutline(paint_phase))
NGFragmentPainter(box_fragment_).PaintOutline(paint_info, paint_offset);
- // TODO(layout-dev): Implement once we have selections in LayoutNG.
- // If the caret's node's layout object's containing block is this block, and
+
+ // If the caret's node's fragment's containing block is this block, and
// the paint action is PaintPhaseForeground, then paint the caret.
- // if (paint_phase == PaintPhase::kForeground &&
- // box_fragment_.ShouldPaintCarets())
- // PaintCarets(paint_info, paint_offset);
+ if (paint_phase == PaintPhase::kForeground &&
+ box_fragment_.ShouldPaintCarets())
+ PaintCarets(paint_info, paint_offset);
+}
+
+void NGBoxFragmentPainter::PaintCarets(const PaintInfo& paint_info,
+ const LayoutPoint& paint_offset) {
+ LocalFrame* frame = box_fragment_.GetLayoutObject()->GetFrame();
+
+ if (box_fragment_.ShouldPaintCursorCaret())
+ frame->Selection().PaintCaret(paint_info.context, paint_offset);
+
+ if (box_fragment_.ShouldPaintDragCaret()) {
+ frame->GetPage()->GetDragCaret().PaintDragCaret(frame, paint_info.context,
+ paint_offset);
+ }
}
void NGBoxFragmentPainter::PaintBlockFlowContents(
@@ -335,25 +346,12 @@ void NGBoxFragmentPainter::PaintInlineChild(const NGPaintFragment& child,
} else if (fragment.Type() == NGPhysicalFragment::kFragmentBox) {
if (child.HasSelfPaintingLayer())
return;
- NGBoxFragmentPainter(child).PaintInlineBox(descendants_info, paint_offset);
+ NGInlineBoxFragmentPainter(child).Paint(descendants_info, paint_offset);
} else {
NOTREACHED();
}
}
-namespace {
-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 back.
- if (fragment.IsBlockLayoutRoot())
- return true;
-
- // TODO(kojii): Review if this is still needed.
- LayoutObject* layout_object = fragment.GetLayoutObject();
- return layout_object->IsLayoutReplaced();
-}
-} // anonymous namespace
-
void NGBoxFragmentPainter::PaintBlockChildren(const PaintInfo& paint_info) {
for (const auto& child : box_fragment_.Children()) {
const NGPhysicalFragment& fragment = child->PhysicalFragment();
@@ -372,7 +370,7 @@ void NGBoxFragmentPainter::PaintBlockChildren(const PaintInfo& paint_info) {
}
void NGBoxFragmentPainter::PaintFloatingChildren(
- const Vector<std::unique_ptr<NGPaintFragment>>& children,
+ const Vector<scoped_refptr<NGPaintFragment>>& children,
const PaintInfo& paint_info) {
for (const auto& child : children) {
const NGPhysicalFragment& fragment = child->PhysicalFragment();
@@ -440,7 +438,6 @@ void NGBoxFragmentPainter::PaintBoxDecorationBackground(
NGPhysicalSize size = box_fragment_.Size();
paint_rect = LayoutRect(LayoutPoint(), LayoutSize(size.width, size.height));
}
-
paint_rect.MoveBy(paint_offset);
bool painting_overflow_contents =
@@ -536,9 +533,9 @@ void NGBoxFragmentPainter::PaintInlineChildBoxUsingLegacyFallback(
void NGBoxFragmentPainter::PaintAllPhasesAtomically(
const PaintInfo& paint_info,
bool is_self_painting) {
- AdjustPaintOffsetScope adjustment(box_fragment_, paint_info);
- auto paint_offset = adjustment.PaintOffset();
- PaintInfo local_paint_info = adjustment.MutablePaintInfo();
+ PaintInfoWithOffset paint_info_with_offset(box_fragment_, paint_info);
+ auto paint_offset = paint_info_with_offset.PaintOffset();
+ PaintInfo& local_paint_info = paint_info_with_offset.MutablePaintInfo();
// Pass PaintPhaseSelection and PaintPhaseTextClip is handled by the regular
// foreground paint implementation. We don't need complete painting for these
@@ -561,7 +558,7 @@ void NGBoxFragmentPainter::PaintAllPhasesAtomically(
local_paint_info.phase = PaintPhase::kFloat;
PaintObject(local_paint_info, paint_offset);
{
- NGBoxClipper box_clipper(box_fragment_, local_paint_info);
+ ScopedBoxClipper box_clipper(box_fragment_, local_paint_info);
local_paint_info.phase = PaintPhase::kForeground;
PaintObject(local_paint_info, paint_offset);
}
@@ -573,7 +570,7 @@ void NGBoxFragmentPainter::PaintAllPhasesAtomically(
}
void NGBoxFragmentPainter::PaintLineBoxChildren(
- const Vector<std::unique_ptr<NGPaintFragment>>& line_boxes,
+ const Vector<scoped_refptr<NGPaintFragment>>& line_boxes,
const PaintInfo& paint_info,
const LayoutPoint& paint_offset) {
DCHECK(!ShouldPaintSelfOutline(paint_info.phase) &&
@@ -616,25 +613,13 @@ void NGBoxFragmentPainter::PaintLineBoxChildren(
}
void NGBoxFragmentPainter::PaintInlineChildren(
- const Vector<std::unique_ptr<NGPaintFragment>>& inline_children,
+ const Vector<scoped_refptr<NGPaintFragment>>& inline_children,
const PaintInfo& paint_info,
const LayoutPoint& paint_offset) {
for (const auto& child : inline_children) {
if (child->PhysicalFragment().IsFloating())
continue;
if (child->PhysicalFragment().IsAtomicInline()) {
- // legacy_paint_offset is local, so we need to remove the offset to
- // lineBox.
- LayoutPoint legacy_paint_offset = paint_offset;
- const NGPaintFragment* parent = child->Parent();
- while (parent && (parent->PhysicalFragment().IsBox() ||
- parent->PhysicalFragment().IsLineBox())) {
- legacy_paint_offset -= parent->Offset().ToLayoutPoint();
- if (parent->PhysicalFragment().IsLineBox())
- break;
- parent = parent->Parent();
- }
-
PaintAtomicInlineChild(*child, paint_info);
} else {
PaintInlineChild(*child, paint_info, paint_offset);
@@ -643,7 +628,7 @@ void NGBoxFragmentPainter::PaintInlineChildren(
}
void NGBoxFragmentPainter::PaintInlineChildrenOutlines(
- const Vector<std::unique_ptr<NGPaintFragment>>& line_boxes,
+ const Vector<scoped_refptr<NGPaintFragment>>& line_boxes,
const PaintInfo& paint_info,
const LayoutPoint& paint_offset) {
// TODO(layout-dev): Implement.
@@ -760,14 +745,11 @@ void NGBoxFragmentPainter::PaintOverflowControlsIfNeeded(
}
}
-bool NGBoxFragmentPainter::IntersectsPaintRect(
- const PaintInfo& paint_info,
- const LayoutPoint& paint_offset) const {
- // TODO(layout-dev): Add support for scrolling, see
- // BlockPainter::IntersectsPaintRect.
- LayoutRect overflow_rect(box_fragment_.SelfInkOverflow());
- overflow_rect.MoveBy(paint_offset);
- return paint_info.GetCullRect().IntersectsCullRect(overflow_rect);
+bool NGBoxFragmentPainter::ShouldPaint(
+ const PaintInfoWithOffset& paint_info_with_offset) const {
+ // TODO(layout-dev): Add support for scrolling, see BlockPainter::ShouldPaint.
+ return paint_info_with_offset.LocalRectIntersectsCullRect(
+ box_fragment_.SelfInkOverflow());
}
void NGBoxFragmentPainter::PaintTextClipMask(GraphicsContext& context,
@@ -776,15 +758,21 @@ void NGBoxFragmentPainter::PaintTextClipMask(GraphicsContext& context,
bool object_has_multiple_boxes) {
PaintInfo paint_info(context, mask_rect, PaintPhase::kTextClip,
kGlobalPaintNormalPhase, 0);
- const LayoutSize local_offset = box_fragment_.Offset().ToLayoutSize();
- if (PhysicalFragment().IsBlockFlow()) {
- // TODO(layout-dev): Add support for box-decoration-break: slice
- // See BoxModelObjectPainter::LogicalOffsetOnLine
- // if (box_fragment_.Style().BoxDecorationBreak() ==
- // EBoxDecorationBreak::kSlice) {
- // local_offset -= LogicalOffsetOnLine(*flow_box_);
- //}
- PaintBlockFlowContents(paint_info, paint_offset - local_offset);
+ LayoutSize local_offset = box_fragment_.Offset().ToLayoutSize();
+ if (object_has_multiple_boxes) {
+ NGInlineBoxFragmentPainter inline_box_painter(box_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 -= box_fragment_.Style().IsHorizontalWritingMode()
+ ? line_offset
+ : line_offset.TransposedSize();
+ }
+ inline_box_painter.Paint(paint_info, paint_offset - local_offset);
} else {
PaintObject(paint_info, paint_offset - local_offset);
}
@@ -808,12 +796,23 @@ LayoutRect NGBoxFragmentPainter::AdjustRectForScrolledContent(
// the ends.
IntSize offset = physical.ScrolledContentOffset();
scrolled_paint_rect.Move(-offset);
- LayoutRectOutsets borders = BorderOutsets(info);
+ LayoutRectOutsets borders = AdjustedBorderOutsets(info);
scrolled_paint_rect.SetSize(physical.ScrollSize() + borders.Size());
}
return scrolled_paint_rect;
}
+LayoutRectOutsets NGBoxFragmentPainter::ComputeBorders() const {
+ return BoxStrutToLayoutRectOutsets(
+ box_fragment_.PhysicalFragment().BorderWidths());
+}
+
+LayoutRectOutsets NGBoxFragmentPainter::ComputePadding() const {
+ return BoxStrutToLayoutRectOutsets(
+ ToNGPhysicalBoxFragment(box_fragment_.PhysicalFragment())
+ .PixelSnappedPadding());
+}
+
BoxPainterBase::FillLayerInfo NGBoxFragmentPainter::GetFillLayerInfo(
const Color& color,
const FillLayer& bg_layer,
@@ -924,7 +923,11 @@ bool NGBoxFragmentPainter::HitTestTextFragment(
HitTestResult& result,
const NGPaintFragment& text_paint_fragment,
const HitTestLocation& location_in_container,
- const LayoutPoint& physical_offset) {
+ const LayoutPoint& physical_offset,
+ HitTestAction action) {
+ if (action != kHitTestForeground)
+ return false;
+
const NGPhysicalFragment& text_fragment =
text_paint_fragment.PhysicalFragment();
LayoutSize size(text_fragment.Size().width, text_fragment.Size().height);
@@ -969,17 +972,13 @@ bool NGBoxFragmentPainter::HitTestLineBoxFragment(
const HitTestLocation& location_in_container,
const LayoutPoint& physical_offset,
HitTestAction action) {
- if (action != kHitTestForeground)
- return false;
-
- const LayoutSize size = fragment.Size().ToLayoutSize();
-
- // TODO(xiaochengh): Hit test ellipsis box.
-
if (HitTestChildren(result, fragment.Children(), location_in_container,
physical_offset, action))
return true;
+ if (action != kHitTestForeground)
+ return false;
+
if (!VisibleToHitTestRequest(result.GetHitTestRequest()))
return false;
@@ -988,6 +987,7 @@ bool NGBoxFragmentPainter::HitTestLineBoxFragment(
if (HitTestClippedOutByBorder(location_in_container, overflow_location))
return false;
+ const LayoutSize size = fragment.Size().ToLayoutSize();
const LayoutRect bounds_rect(physical_offset, size);
const ComputedStyle& containing_box_style = box_fragment_.Style();
if (containing_box_style.HasBorderRadius() &&
@@ -1011,48 +1011,68 @@ bool NGBoxFragmentPainter::HitTestLineBoxFragment(
bounds_rect) == kStopHitTesting;
}
+bool NGBoxFragmentPainter::HitTestChildBoxFragment(
+ HitTestResult& result,
+ const NGPaintFragment& paint_fragment,
+ const HitTestLocation& location_in_container,
+ const LayoutPoint& physical_offset,
+ HitTestAction action) {
+ const NGPhysicalFragment& fragment = paint_fragment.PhysicalFragment();
+ if (fragment.IsFloating() && action != kHitTestFloat)
+ return false;
+ // Lines and inlines are hit tested only in the foreground phase.
+ if (fragment.IsInline() && action != kHitTestForeground)
+ 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());
+ return NGBoxFragmentPainter(paint_fragment)
+ .NodeAtPoint(result, location_in_container, physical_offset, action);
+ }
+
+ LayoutBox* const layout_box = ToLayoutBox(fragment.GetLayoutObject());
+
+ // To be passed as |accumulated_offset| to legacy hit test functions of
+ // LayoutBox or subclass overrides, where it isn't in any well-defined
+ // coordinate space, but only equals the difference below.
+ const LayoutPoint fallback_accumulated_offset =
+ physical_offset - ToLayoutSize(layout_box->Location());
+
+ // 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.
+ const bool should_hit_test_all_phases =
+ fragment.IsAtomicInline() || fragment.IsFloating();
+ return should_hit_test_all_phases
+ ? layout_box->HitTestAllPhases(result, location_in_container,
+ fallback_accumulated_offset)
+ : layout_box->NodeAtPoint(result, location_in_container,
+ fallback_accumulated_offset, action);
+}
+
bool NGBoxFragmentPainter::HitTestChildren(
HitTestResult& result,
- const Vector<std::unique_ptr<NGPaintFragment>>& children,
+ const Vector<scoped_refptr<NGPaintFragment>>& children,
const HitTestLocation& location_in_container,
const LayoutPoint& accumulated_offset,
HitTestAction action) {
for (auto iter = children.rbegin(); iter != children.rend(); iter++) {
- const std::unique_ptr<NGPaintFragment>& child = *iter;
+ const scoped_refptr<NGPaintFragment>& child = *iter;
+ const NGPhysicalOffset offset = child->Offset();
if (child->HasSelfPaintingLayer())
continue;
const NGPhysicalFragment& fragment = child->PhysicalFragment();
const LayoutPoint child_physical_offset =
- accumulated_offset + fragment.Offset().ToLayoutPoint();
+ accumulated_offset + offset.ToLayoutPoint();
bool stop_hit_testing = false;
if (fragment.Type() == NGPhysicalFragment::kFragmentBox) {
- if (FragmentRequiresLegacyFallback(fragment)) {
- // Hit test all phases of an inline-block/table or replaced element
- // atomically, as if it created its own stacking context. (See Appendix
- // E.2, section 7.4 on inline block/table elements in CSS2.2 spec)
- bool should_hit_test_all_phases = fragment.IsAtomicInline();
- // To be passed as |accumulated_offset| to legacy hit test functions of
- // LayoutBox or subclass overrides, where it isn't in any well-defined
- // coordinate space, but only equals the difference below.
- LayoutPoint fallback_accumulated_offset =
- child_physical_offset -
- ToLayoutSize(ToLayoutBox(fragment.GetLayoutObject())->Location());
- if (should_hit_test_all_phases) {
- stop_hit_testing = fragment.GetLayoutObject()->HitTestAllPhases(
- result, location_in_container, fallback_accumulated_offset);
- } else {
- stop_hit_testing = fragment.GetLayoutObject()->NodeAtPoint(
- result, location_in_container, fallback_accumulated_offset,
- action);
- }
- } else {
- // TODO(layout-dev): Implement HitTestAllPhases in NG after we stop
- // falling back to legacy for atomic inlines.
- stop_hit_testing = NGBoxFragmentPainter(*child).NodeAtPoint(
- result, location_in_container, child_physical_offset, action);
- }
+ stop_hit_testing = HitTestChildBoxFragment(
+ result, *child, location_in_container, child_physical_offset, action);
} else if (fragment.Type() == NGPhysicalFragment::kFragmentLineBox) {
stop_hit_testing = HitTestLineBoxFragment(
@@ -1062,12 +1082,12 @@ bool NGBoxFragmentPainter::HitTestChildren(
// TODO(eae): Should this hit test on the text itself or the containing
// node?
stop_hit_testing = HitTestTextFragment(
- result, *child, location_in_container, child_physical_offset);
+ result, *child, location_in_container, child_physical_offset, action);
}
if (stop_hit_testing)
return true;
- if (!fragment.IsInline())
+ if (!fragment.IsInline() || action != kHitTestForeground)
continue;
// Hit test culled inline boxes between |fragment| and its parent fragment.
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 fcd0338c8ca..1b58dee34cf 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
@@ -23,6 +23,7 @@ class HitTestResult;
class LayoutRect;
class NGPaintFragment;
class NGPhysicalFragment;
+class PaintInfoWithOffset;
struct PaintInfo;
// Painter for LayoutNG box fragments, paints borders and background. Delegates
@@ -34,7 +35,9 @@ class NGBoxFragmentPainter : public BoxPainterBase {
NGBoxFragmentPainter(const NGPaintFragment&);
void Paint(const PaintInfo&);
- void PaintInlineBox(const PaintInfo&, const LayoutPoint& paint_offset);
+ void PaintObject(const PaintInfo&,
+ const LayoutPoint&,
+ bool suppress_box_decoration_background = false);
// Hit tests this box fragment.
// @param physical_offset Physical offset of this box fragment in paint layer.
@@ -45,6 +48,8 @@ class NGBoxFragmentPainter : public BoxPainterBase {
HitTestAction);
protected:
+ LayoutRectOutsets ComputeBorders() const override;
+ LayoutRectOutsets ComputePadding() const override;
BoxPainterBase::FillLayerInfo GetFillLayerInfo(
const Color&,
const FillLayer&,
@@ -62,29 +67,25 @@ class NGBoxFragmentPainter : public BoxPainterBase {
bool IsPaintingBackgroundOfPaintContainerIntoScrollingContentsLayer(
const NGPaintFragment&,
const PaintInfo&);
- bool IntersectsPaintRect(const PaintInfo&,
- const LayoutPoint& paint_offset) const;
+ bool ShouldPaint(const PaintInfoWithOffset&) const;
void PaintBoxDecorationBackground(const PaintInfo&,
const LayoutPoint& paint_offset);
void PaintAllPhasesAtomically(const PaintInfo&,
bool is_self_painting);
void PaintBlockChildren(const PaintInfo&);
- void PaintLineBoxChildren(const Vector<std::unique_ptr<NGPaintFragment>>&,
+ void PaintLineBoxChildren(const Vector<scoped_refptr<NGPaintFragment>>&,
const PaintInfo&,
const LayoutPoint& paint_offset);
- void PaintInlineChildren(const Vector<std::unique_ptr<NGPaintFragment>>&,
+ void PaintInlineChildren(const Vector<scoped_refptr<NGPaintFragment>>&,
const PaintInfo&,
const LayoutPoint& paint_offset);
void PaintInlineChildrenOutlines(
- const Vector<std::unique_ptr<NGPaintFragment>>&,
+ const Vector<scoped_refptr<NGPaintFragment>>&,
const PaintInfo&,
const LayoutPoint& paint_offset);
void PaintInlineChildBoxUsingLegacyFallback(const NGPhysicalFragment&,
const PaintInfo&);
- void PaintObject(const PaintInfo&,
- const LayoutPoint&,
- bool suppress_box_decoration_background = false);
void PaintBlockFlowContents(const PaintInfo&,
const LayoutPoint& paint_offset);
void PaintInlineChild(const NGPaintFragment&,
@@ -94,7 +95,7 @@ class NGBoxFragmentPainter : public BoxPainterBase {
void PaintTextChild(const NGPaintFragment&,
const PaintInfo&,
const LayoutPoint& paint_offset);
- void PaintFloatingChildren(const Vector<std::unique_ptr<NGPaintFragment>>&,
+ void PaintFloatingChildren(const Vector<scoped_refptr<NGPaintFragment>>&,
const PaintInfo&);
void PaintFloats(const PaintInfo&);
void PaintMask(const PaintInfo&, const LayoutPoint& paint_offset);
@@ -108,6 +109,7 @@ class NGBoxFragmentPainter : public BoxPainterBase {
void PaintSymbol(const NGPaintFragment&,
const PaintInfo&,
const LayoutPoint& paint_offset);
+ void PaintCarets(const PaintInfo&, const LayoutPoint& paint_offset);
bool IsInSelfHitTestingPhase(HitTestAction) const;
bool VisibleToHitTestRequest(const HitTestRequest&) const;
@@ -118,17 +120,28 @@ class NGBoxFragmentPainter : public BoxPainterBase {
// box in paint layer. Note that this includes scrolling offset when the
// container has 'overflow: scroll'.
bool HitTestChildren(HitTestResult&,
- const Vector<std::unique_ptr<NGPaintFragment>>&,
+ const Vector<scoped_refptr<NGPaintFragment>>&,
const HitTestLocation& location_in_container,
const LayoutPoint& physical_offset,
HitTestAction);
+ // 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&,
+ const NGPaintFragment&,
+ const HitTestLocation& location_in_container,
+ const LayoutPoint& physical_offset,
+ HitTestAction);
+
// Hit tests the given text fragment.
// @param physical_offset Physical offset of the text fragment in paint layer.
bool HitTestTextFragment(HitTestResult&,
const NGPaintFragment&,
const HitTestLocation& location_in_container,
- const LayoutPoint& physical_offset);
+ const LayoutPoint& physical_offset,
+ HitTestAction);
// Hit tests the given line box fragment.
// @param physical_offset Physical offset of the line box fragment in paint
@@ -151,7 +164,6 @@ class NGBoxFragmentPainter : public BoxPainterBase {
const NGPhysicalBoxFragment& PhysicalFragment() const;
const NGPaintFragment& box_fragment_;
-
NGBorderEdges border_edges_;
};
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
new file mode 100644
index 00000000000..c884762044b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/paint/ng/ng_inline_box_fragment_painter.cc
@@ -0,0 +1,227 @@
+// 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/paint/ng/ng_inline_box_fragment_painter.h"
+
+#include "third_party/blink/renderer/core/layout/background_bleed_avoidance.h"
+#include "third_party/blink/renderer/core/layout/layout_object.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_fragment.h"
+#include "third_party/blink/renderer/core/paint/background_image_geometry.h"
+#include "third_party/blink/renderer/core/paint/ng/ng_paint_fragment.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_phase.h"
+#include "third_party/blink/renderer/core/style/nine_piece_image.h"
+#include "third_party/blink/renderer/platform/graphics/graphics_context_state_saver.h"
+#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
+
+namespace blink {
+
+NGInlineBoxFragmentPainter::NGInlineBoxFragmentPainter(
+ const NGPaintFragment& inline_box_fragment)
+ : InlineBoxPainterBase(
+ inline_box_fragment,
+ &inline_box_fragment.GetLayoutObject()->GetDocument(),
+ inline_box_fragment.GetLayoutObject()->GeneratingNode(),
+ inline_box_fragment.Style(),
+ // TODO(layout-dev): Should be first-line style.
+ inline_box_fragment.Style()),
+ inline_box_fragment_(inline_box_fragment),
+ border_edges_(NGBorderEdges::FromPhysical(
+ inline_box_fragment.PhysicalFragment().BorderEdges(),
+ inline_box_fragment.Style().GetWritingMode())) {
+}
+
+void NGInlineBoxFragmentPainter::Paint(const PaintInfo& paint_info,
+ const LayoutPoint& paint_offset) {
+ const LayoutPoint adjusted_paint_offset =
+ paint_offset + inline_box_fragment_.Offset().ToLayoutPoint();
+ if (paint_info.phase == PaintPhase::kForeground)
+ PaintBackgroundBorderShadow(paint_info, adjusted_paint_offset);
+
+ NGBoxFragmentPainter box_painter(inline_box_fragment_);
+ box_painter.PaintObject(paint_info, adjusted_paint_offset, true);
+}
+
+void NGInlineBoxFragmentPainter::PaintBackgroundBorderShadow(
+ const PaintInfo& paint_info,
+ const LayoutPoint& paint_offset) {
+ DCHECK(paint_info.phase == PaintPhase::kForeground);
+ if (inline_box_fragment_.Style().Visibility() != EVisibility::kVisible)
+ return;
+
+ // You can use p::first-line to specify a background. If so, the direct child
+ // inline boxes of line boxes may actually have to paint a background.
+ // TODO(layout-dev): Cache HasBoxDecorationBackground on the fragment like
+ // we do for LayoutObject. Querying Style each time is too costly.
+ bool should_paint_box_decoration_background =
+ inline_box_fragment_.GetLayoutObject()->HasBoxDecorationBackground() ||
+ inline_box_fragment_.PhysicalFragment().UsesFirstLineStyle();
+
+ if (!should_paint_box_decoration_background)
+ return;
+
+ if (DrawingRecorder::UseCachedDrawingIfPossible(
+ paint_info.context, inline_box_fragment_,
+ DisplayItem::kBoxDecorationBackground))
+ return;
+
+ DrawingRecorder recorder(paint_info.context, inline_box_fragment_,
+ DisplayItem::kBoxDecorationBackground);
+
+ LayoutRect frame_rect =
+ inline_box_fragment_.PhysicalFragment().LocalRect().ToLayoutRect();
+ LayoutPoint adjusted_paint_offset = paint_offset;
+
+ LayoutRect adjusted_frame_rect =
+ LayoutRect(adjusted_paint_offset, frame_rect.Size());
+
+ NGPaintFragment::FragmentRange fragments =
+ inline_box_fragment_.InlineFragmentsFor(
+ inline_box_fragment_.GetLayoutObject());
+ NGPaintFragment::FragmentRange::iterator iter = fragments.begin();
+ bool object_has_multiple_boxes = ++iter != fragments.end();
+
+ // TODO(eae): Switch to LayoutNG version of BackgroundImageGeometry.
+ BackgroundImageGeometry geometry(*static_cast<const LayoutBoxModelObject*>(
+ inline_box_fragment_.GetLayoutObject()));
+ NGBoxFragmentPainter box_painter(inline_box_fragment_);
+ PaintBoxDecorationBackground(
+ box_painter, paint_info, paint_offset, adjusted_frame_rect, geometry,
+ object_has_multiple_boxes, border_edges_.line_left,
+ border_edges_.line_right);
+}
+
+void NGInlineBoxFragmentPainter::ComputeFragmentOffsetOnLine(
+ TextDirection direction,
+ LayoutUnit* offset_on_line,
+ LayoutUnit* total_width) const {
+ WritingMode writing_mode = inline_box_fragment_.Style().GetWritingMode();
+ NGPaintFragment::FragmentRange fragments =
+ inline_box_fragment_.InlineFragmentsFor(
+ 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_fragment_) {
+ before_self = false;
+ continue;
+ }
+ if (before_self)
+ before += NGFragment(writing_mode, iter->PhysicalFragment()).InlineSize();
+ else
+ after += NGFragment(writing_mode, iter->PhysicalFragment()).InlineSize();
+ }
+
+ NGFragment logical_fragment(writing_mode,
+ inline_box_fragment_.PhysicalFragment());
+ *total_width = before + after + logical_fragment.InlineSize();
+
+ // We're iterating over the fragments in physical order before so we need to
+ // swap before and after for RTL.
+ *offset_on_line = direction == TextDirection::kLtr ? before : after;
+}
+
+LayoutRect NGInlineBoxFragmentPainter::PaintRectForImageStrip(
+ const LayoutRect& paint_rect,
+ TextDirection direction) const {
+ // We have a fill/border/mask image that spans multiple lines.
+ // We need to adjust the offset by the width of all previous lines.
+ // Think of background painting on inlines as though you had one long line, a
+ // single continuous strip. Even though that strip has been broken up across
+ // multiple lines, you still paint it as though you had one single line. This
+ // means each line has to pick up the background where the previous line left
+ // off.
+ LayoutUnit offset_on_line;
+ LayoutUnit total_width;
+ ComputeFragmentOffsetOnLine(direction, &offset_on_line, &total_width);
+
+ if (inline_box_fragment_.Style().IsHorizontalWritingMode()) {
+ return LayoutRect(paint_rect.X() - offset_on_line, paint_rect.Y(),
+ total_width, paint_rect.Height());
+ }
+ return LayoutRect(paint_rect.X(), paint_rect.Y() - offset_on_line,
+ paint_rect.Width(), total_width);
+}
+
+static LayoutRect NGClipRectForNinePieceImageStrip(
+ const ComputedStyle& style,
+ const NGBorderEdges& border_edges,
+ const NinePieceImage& image,
+ const LayoutRect& paint_rect) {
+ LayoutRect clip_rect(paint_rect);
+ LayoutRectOutsets outsets = style.ImageOutsets(image);
+ if (style.IsHorizontalWritingMode()) {
+ clip_rect.SetY(paint_rect.Y() - outsets.Top());
+ clip_rect.SetHeight(paint_rect.Height() + outsets.Top() + outsets.Bottom());
+ if (border_edges.line_left) {
+ clip_rect.SetX(paint_rect.X() - outsets.Left());
+ clip_rect.SetWidth(paint_rect.Width() + outsets.Left());
+ }
+ if (border_edges.line_right)
+ clip_rect.SetWidth(clip_rect.Width() + outsets.Right());
+ } else {
+ clip_rect.SetX(paint_rect.X() - outsets.Left());
+ clip_rect.SetWidth(paint_rect.Width() + outsets.Left() + outsets.Right());
+ if (border_edges.line_left) {
+ clip_rect.SetY(paint_rect.Y() - outsets.Top());
+ clip_rect.SetHeight(paint_rect.Height() + outsets.Top());
+ }
+ if (border_edges.line_right)
+ clip_rect.SetHeight(clip_rect.Height() + outsets.Bottom());
+ }
+ return clip_rect;
+}
+
+InlineBoxPainterBase::BorderPaintingType
+NGInlineBoxFragmentPainter::GetBorderPaintType(
+ const LayoutRect& adjusted_frame_rect,
+ IntRect& adjusted_clip_rect,
+ bool object_has_multiple_boxes) const {
+ adjusted_clip_rect = PixelSnappedIntRect(adjusted_frame_rect);
+ if (inline_box_fragment_.Parent() &&
+ inline_box_fragment_.Style().HasBorderDecoration()) {
+ const NinePieceImage& border_image =
+ inline_box_fragment_.Style().BorderImage();
+ StyleImage* border_image_source = border_image.GetImage();
+ bool has_border_image =
+ border_image_source && border_image_source->CanRender();
+ if (has_border_image && !border_image_source->IsLoaded())
+ return kDontPaintBorders;
+
+ // The simple case is where we either have no border image or we are the
+ // only box for this object. In those cases only a single call to draw is
+ // required.
+ if (!has_border_image || !object_has_multiple_boxes)
+ return kPaintBordersWithoutClip;
+
+ // We have a border image that spans multiple lines.
+ adjusted_clip_rect = PixelSnappedIntRect(NGClipRectForNinePieceImageStrip(
+ inline_box_fragment_.Style(), border_edges_, border_image,
+ adjusted_frame_rect));
+ return kPaintBordersWithClip;
+ }
+ return kDontPaintBorders;
+}
+
+void NGInlineBoxFragmentPainter::PaintNormalBoxShadow(
+ const PaintInfo& info,
+ const ComputedStyle& s,
+ const LayoutRect& paint_rect) {
+ BoxPainterBase::PaintNormalBoxShadow(
+ info, paint_rect, s, border_edges_.line_left, border_edges_.line_right);
+}
+
+void NGInlineBoxFragmentPainter::PaintInsetBoxShadow(
+ const PaintInfo& info,
+ const ComputedStyle& s,
+ const LayoutRect& paint_rect) {
+ BoxPainterBase::PaintInsetBoxShadowWithBorderRect(
+ info, paint_rect, s, border_edges_.line_left, border_edges_.line_right);
+}
+
+} // 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
new file mode 100644
index 00000000000..881e314410e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/paint/ng/ng_inline_box_fragment_painter.h
@@ -0,0 +1,59 @@
+// 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_PAINT_NG_NG_INLINE_BOX_FRAGMENT_PAINTER_H_
+#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/paint/inline_box_painter_base.h"
+#include "third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h"
+
+#include "third_party/blink/renderer/platform/wtf/allocator.h"
+#include "third_party/skia/include/core/SkBlendMode.h"
+
+namespace blink {
+
+class LayoutRect;
+class NGPaintFragment;
+struct PaintInfo;
+
+// Painter for LayoutNG inline box fragments. Delegates to NGBoxFragmentPainter
+// for all box painting logic that isn't specific to inline boxes.
+class NGInlineBoxFragmentPainter : public InlineBoxPainterBase {
+ STACK_ALLOCATED();
+
+ public:
+ NGInlineBoxFragmentPainter(const NGPaintFragment&);
+
+ void Paint(const PaintInfo&, const LayoutPoint& paint_offset);
+ void ComputeFragmentOffsetOnLine(TextDirection,
+ LayoutUnit* offset_on_line,
+ LayoutUnit* total_width) const;
+
+ protected:
+ LayoutRect PaintRectForImageStrip(const LayoutRect&,
+ TextDirection direction) const override;
+
+ BorderPaintingType GetBorderPaintType(
+ const LayoutRect& adjusted_frame_rect,
+ IntRect& adjusted_clip_rect,
+ bool object_has_multiple_boxes) const override;
+ void PaintNormalBoxShadow(const PaintInfo&,
+ const ComputedStyle&,
+ const LayoutRect& paint_rect) override;
+ void PaintInsetBoxShadow(const PaintInfo&,
+ const ComputedStyle&,
+ const LayoutRect& paint_rect) override;
+
+ private:
+ void PaintBackgroundBorderShadow(const PaintInfo&,
+ const LayoutPoint& paint_offset);
+
+ const NGPaintFragment& inline_box_fragment_;
+ NGBorderEdges border_edges_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_NG_NG_INLINE_BOX_FRAGMENT_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 25d6ac1a8d6..513a66e689a 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
@@ -13,7 +13,6 @@
#include "third_party/blink/renderer/core/layout/layout_inline.h"
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_logical_rect.h"
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_physical_offset_rect.h"
-#include "third_party/blink/renderer/core/layout/ng/inline/ng_abstract_inline_text_box.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_caret_position.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h"
@@ -26,6 +25,7 @@
#include "third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h"
#include "third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h"
+#include "third_party/blink/renderer/core/paint/ng/ng_inline_box_fragment_painter.h"
namespace blink {
@@ -152,28 +152,74 @@ bool IsLastBRInPage(const NGPhysicalTextFragment& text_fragment) {
NGPaintFragment::NGPaintFragment(
scoped_refptr<const NGPhysicalFragment> fragment,
+ NGPhysicalOffset offset,
NGPaintFragment* parent)
- : physical_fragment_(std::move(fragment)), parent_(parent) {
+ : physical_fragment_(std::move(fragment)),
+ offset_(offset),
+ parent_(parent) {
DCHECK(physical_fragment_);
}
NGPaintFragment::~NGPaintFragment() {
- NGAbstractInlineTextBox::WillDestroy(this);
+ DCHECK(!next_for_same_layout_object_);
}
-std::unique_ptr<NGPaintFragment> NGPaintFragment::Create(
- scoped_refptr<const NGPhysicalFragment> fragment) {
- std::unique_ptr<NGPaintFragment> paint_fragment =
- std::make_unique<NGPaintFragment>(std::move(fragment), nullptr);
+scoped_refptr<NGPaintFragment> NGPaintFragment::Create(
+ scoped_refptr<const NGPhysicalFragment> fragment,
+ NGPhysicalOffset offset) {
+ DCHECK(fragment);
+
+ scoped_refptr<NGPaintFragment> paint_fragment =
+ base::AdoptRef(new NGPaintFragment(std::move(fragment), offset, nullptr));
HashMap<const LayoutObject*, NGPaintFragment*> last_fragment_map;
paint_fragment->PopulateDescendants(NGPhysicalOffset(),
- &paint_fragment->first_fragment_map_,
&last_fragment_map);
return paint_fragment;
}
+void NGPaintFragment::UpdatePhysicalFragmentFromCachedLayoutResult(
+ scoped_refptr<const NGPhysicalFragment> fragment) {
+ DCHECK(fragment);
+
+#if DCHECK_IS_ON()
+ // When updating to a cached layout result, only offset can change. Check
+ // children do not change.
+ const NGPhysicalContainerFragment& container_fragment =
+ ToNGPhysicalContainerFragment(*fragment);
+ DCHECK_EQ(Children().size(), container_fragment.Children().size());
+ for (unsigned i = 0; i < container_fragment.Children().size(); i++) {
+ DCHECK_EQ(Children()[i]->physical_fragment_.get(),
+ container_fragment.Children()[i].get());
+ }
+#endif
+
+ physical_fragment_ = fragment;
+}
+
+NGPaintFragment* NGPaintFragment::Last(const NGBreakToken& break_token) {
+ for (NGPaintFragment* fragment = this; fragment;
+ fragment = fragment->next_fragmented_.get()) {
+ if (fragment->PhysicalFragment().BreakToken() == &break_token)
+ return fragment;
+ }
+ return nullptr;
+}
+
+NGPaintFragment* NGPaintFragment::Last() {
+ for (NGPaintFragment* fragment = this;;) {
+ NGPaintFragment* next = fragment->next_fragmented_.get();
+ if (!next)
+ return fragment;
+ fragment = next;
+ }
+}
+
+void NGPaintFragment::SetNext(scoped_refptr<NGPaintFragment> fragment) {
+ next_fragmented_ = std::move(fragment);
+}
+
bool NGPaintFragment::IsDescendantOfNotSelf(
const NGPaintFragment& ancestor) const {
for (const NGPaintFragment* fragment = Parent(); fragment;
@@ -210,7 +256,6 @@ LayoutRect NGPaintFragment::ChildrenInkOverflow() const {
// Populate descendants from NGPhysicalFragment tree.
void NGPaintFragment::PopulateDescendants(
const NGPhysicalOffset inline_offset_to_container_box,
- HashMap<const LayoutObject*, NGPaintFragment*>* first_fragment_map,
HashMap<const LayoutObject*, NGPaintFragment*>* last_fragment_map) {
DCHECK(children_.IsEmpty());
const NGPhysicalFragment& fragment = PhysicalFragment();
@@ -221,48 +266,60 @@ void NGPaintFragment::PopulateDescendants(
children_.ReserveCapacity(container.Children().size());
for (const auto& child_fragment : container.Children()) {
- std::unique_ptr<NGPaintFragment> child =
- std::make_unique<NGPaintFragment>(child_fragment, this);
-
- // Create a linked list for each LayoutObject.
- //
- // |first_fragment_map| and |last_fragment_map| each keeps the first and the
- // last of the list of fragments for a LayoutObject. We use two maps because
- // |last_fragment_map| is needed only while creating lists, while
- // |first_fragment_map| is kept for later queries. This may change when we
- // use fields in LayoutObject to keep the first fragments.
- if (LayoutObject* layout_object = child_fragment->GetLayoutObject()) {
- auto add_result = last_fragment_map->insert(layout_object, child.get());
- if (add_result.is_new_entry) {
- DCHECK(first_fragment_map->find(layout_object) ==
- first_fragment_map->end());
- first_fragment_map->insert(layout_object, child.get());
- } else {
- DCHECK(first_fragment_map->find(layout_object) !=
- first_fragment_map->end());
- DCHECK(add_result.stored_value->value);
- add_result.stored_value->value->next_fragment_ = child.get();
- add_result.stored_value->value = child.get();
+ scoped_refptr<NGPaintFragment> child = base::AdoptRef(new NGPaintFragment(
+ child_fragment.get(), child_fragment.Offset(), this));
+
+ if (!child_fragment->IsFloating() &&
+ !child_fragment->IsOutOfFlowPositioned() &&
+ !child_fragment->IsListMarker()) {
+ if (LayoutObject* layout_object = child_fragment->GetLayoutObject()) {
+ child->AssociateWithLayoutObject(layout_object, last_fragment_map);
}
- }
- child->inline_offset_to_container_box_ =
- inline_offset_to_container_box + child_fragment->Offset();
+ child->inline_offset_to_container_box_ =
+ inline_offset_to_container_box + child_fragment.Offset();
+ }
- // Recurse chlidren, except when this is a block layout root.
- // TODO(kojii): At the block layout root, chlidren maybe for NGPaint,
- // LayoutNG but not for NGPaint, or legacy. In order to get the maximum
- // test coverage, split the NGPaintFragment tree at all possible engine
- // boundaries.
- if (!child_fragment->IsBlockLayoutRoot()) {
+ // Recurse children, except when this is a block formatting context root.
+ // TODO(kojii): At the block formatting context root, children may be for
+ // NGPaint, LayoutNG but not for NGPaint, or legacy. In order to get the
+ // maximum test coverage, split the NGPaintFragment tree at all possible
+ // engine boundaries.
+ if (!child_fragment->IsBlockFormattingContextRoot()) {
child->PopulateDescendants(child->inline_offset_to_container_box_,
- first_fragment_map, last_fragment_map);
+ last_fragment_map);
}
children_.push_back(std::move(child));
}
}
+// Add to a linked list for each LayoutObject.
+void NGPaintFragment::AssociateWithLayoutObject(
+ LayoutObject* layout_object,
+ HashMap<const LayoutObject*, NGPaintFragment*>* last_fragment_map) {
+ DCHECK(layout_object);
+
+ // TODO(kojii): The LayoutObject is inline, except for column container
+ // fragment. We should have better way to distinguish it, probably after we
+ // determined the generated fragment tree for multicol with fragmentations
+ // supported.
+ if (!layout_object->IsInline()) {
+ DCHECK(Parent() && layout_object == Parent()->GetLayoutObject());
+ return;
+ }
+
+ auto add_result = last_fragment_map->insert(layout_object, this);
+ if (add_result.is_new_entry) {
+ DCHECK(!layout_object->FirstInlineFragment());
+ layout_object->SetFirstInlineFragment(this);
+ } else {
+ DCHECK(add_result.stored_value->value);
+ add_result.stored_value->value->next_for_same_layout_object_ = this;
+ add_result.stored_value->value = this;
+ }
+}
+
NGPaintFragment* NGPaintFragment::GetForInlineContainer(
const LayoutObject* layout_object) {
DCHECK(layout_object && layout_object->IsInline());
@@ -270,28 +327,46 @@ NGPaintFragment* NGPaintFragment::GetForInlineContainer(
// the LayoutObject is a box (i.e., atomic inline, including inline block and
// replaced elements.)
if (LayoutObject* parent = layout_object->Parent()) {
- if (LayoutBlockFlow* block_flow = parent->EnclosingNGBlockFlow())
- return block_flow->PaintFragment();
+ if (LayoutBlockFlow* block_flow = parent->EnclosingNGBlockFlow()) {
+ if (NGPaintFragment* fragment = block_flow->PaintFragment())
+ return fragment;
+
+ // TODO(kojii): IsLayoutFlowThread should probably be done in
+ // EnclosingNGBlockFlow(), but there seem to be both expectations today.
+ // This needs cleanup.
+ if (block_flow->IsLayoutFlowThread()) {
+ DCHECK(block_flow->Parent() &&
+ block_flow->Parent()->IsLayoutBlockFlow());
+ return ToLayoutBlockFlow(block_flow->Parent())->PaintFragment();
+ }
+ }
}
return nullptr;
}
NGPaintFragment::FragmentRange NGPaintFragment::InlineFragmentsFor(
const LayoutObject* layout_object) {
- DCHECK(layout_object && layout_object->IsInline());
- if (const NGPaintFragment* root = GetForInlineContainer(layout_object)) {
- auto it = root->first_fragment_map_.find(layout_object);
- if (it != root->first_fragment_map_.end())
- return FragmentRange(it->value);
-
- // Reaching here means that there are no fragments for the LayoutObject.
- // Culled inline box is one, but can be space-only LayoutText that were
- // collapsed out.
- return FragmentRange(nullptr);
- }
+ DCHECK(layout_object && layout_object->IsInline() &&
+ !layout_object->IsFloatingOrOutOfFlowPositioned());
+
+ if (layout_object->IsInLayoutNGInlineFormattingContext())
+ return FragmentRange(layout_object->FirstInlineFragment());
return FragmentRange(nullptr, false);
}
+void NGPaintFragment::ResetInlineFragmentsFor(
+ const LayoutObject* layout_object) {
+ // Because |next_for_same_layout_object_| can be the last reference, we should
+ // have another reference during resetting |next_for_same_layout_object_|
+ // |FragmentRange|..
+ scoped_refptr<NGPaintFragment> current = layout_object->FirstInlineFragment();
+ while (current) {
+ scoped_refptr<NGPaintFragment> next;
+ next.swap(current->next_for_same_layout_object_);
+ current.swap(next);
+ }
+}
+
bool NGPaintFragment::FlippedLocalVisualRectFor(
const LayoutObject* layout_object,
LayoutRect* visual_rect) {
@@ -345,7 +420,7 @@ void NGPaintFragment::PaintInlineBoxForDescendants(
DCHECK(layout_object);
for (const auto& child : Children()) {
if (child->GetLayoutObject() == layout_object) {
- NGBoxFragmentPainter(*child).PaintInlineBox(
+ NGInlineBoxFragmentPainter(*child).Paint(
paint_info, paint_offset + offset.ToLayoutPoint() /*, paint_offset*/);
continue;
}
@@ -456,7 +531,9 @@ PositionWithAffinity NGPaintFragment::PositionForPointInInlineLevelBox(
DCHECK(!PhysicalFragment().IsBlockFlow());
const NGLogicalOffset logical_point = point.ConvertToLogical(
- Style().GetWritingMode(), Style().Direction(), Size(), NGPhysicalSize());
+ Style().GetWritingMode(), Style().Direction(), Size(),
+ // |point| is actually a pixel with size 1x1.
+ NGPhysicalSize(LayoutUnit(1), LayoutUnit(1)));
const LayoutUnit inline_point = logical_point.inline_offset;
// Stores the closest child before |point| in the inline direction. Used if we
@@ -519,7 +596,9 @@ PositionWithAffinity NGPaintFragment::PositionForPointInInlineFormattingContext(
DCHECK(ToNGPhysicalBoxFragment(PhysicalFragment()).ChildrenInline());
const NGLogicalOffset logical_point = point.ConvertToLogical(
- Style().GetWritingMode(), Style().Direction(), Size(), NGPhysicalSize());
+ Style().GetWritingMode(), Style().Direction(), Size(),
+ // |point| is actually a pixel with size 1x1.
+ NGPhysicalSize(LayoutUnit(1), LayoutUnit(1)));
const LayoutUnit block_point = logical_point.block_offset;
// Stores the closest line box child above |point| in the block direction.
@@ -533,18 +612,6 @@ PositionWithAffinity NGPaintFragment::PositionForPointInInlineFormattingContext(
LayoutUnit closest_line_after_block_offset = LayoutUnit::Max();
for (const auto& child : Children()) {
- // Try to resolve if |point| falls in a non-line-box child completely.
- if (!child->PhysicalFragment().IsLineBox()) {
- if (point.left >= child->Offset().left &&
- point.left <= child->Offset().left + child->Size().width &&
- point.top >= child->Offset().top &&
- point.top <= child->Offset().top + child->Size().height) {
- if (auto child_position = PositionForPointInChild(*child, point))
- return child_position.value();
- }
- continue;
- }
-
if (!child->PhysicalFragment().IsLineBox() || child->Children().IsEmpty())
continue;
@@ -591,7 +658,7 @@ PositionWithAffinity NGPaintFragment::PositionForPointInInlineFormattingContext(
// TODO(xiaochengh): Looking at only the closest lines may not be enough,
// when we have multiple lines full of pseudo elements. Fix it.
- // TODO(xiaochengh): Consider floats.
+ // TODO(xiaochengh): Consider floats. See crbug.com/758526.
return PositionWithAffinity();
}
@@ -644,6 +711,22 @@ Node* NGPaintFragment::NodeForHitTest() const {
return nullptr;
}
+bool NGPaintFragment::ShouldPaintCursorCaret() const {
+ // TODO(xiaochengh): Merge cursor caret painting functions from LayoutBlock to
+ // FrameSelection.
+ if (!GetLayoutObject()->IsLayoutBlock())
+ return false;
+ return ToLayoutBlock(GetLayoutObject())->ShouldPaintCursorCaret();
+}
+
+bool NGPaintFragment::ShouldPaintDragCaret() const {
+ // TODO(xiaochengh): Merge drag caret painting functions from LayoutBlock to
+ // DragCaret.
+ if (!GetLayoutObject()->IsLayoutBlock())
+ return false;
+ return ToLayoutBlock(GetLayoutObject())->ShouldPaintDragCaret();
+}
+
// ----
NGPaintFragment& NGPaintFragment::FragmentRange::front() const {
@@ -659,6 +742,15 @@ NGPaintFragment& NGPaintFragment::FragmentRange::back() const {
return *last;
}
+wtf_size_t NGPaintFragment::FragmentRange::size() const {
+ wtf_size_t size = 0;
+ for (NGPaintFragment* fragment : *this) {
+ ANALYZER_ALLOW_UNUSED(fragment);
+ ++size;
+ }
+ return size;
+}
+
String NGPaintFragment::DebugName() const {
StringBuilder name;
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 370ad8cd32e..9442b8a60b9 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
@@ -34,23 +34,37 @@ struct PaintInfo;
// (See https://drafts.csswg.org/css-backgrounds-3/#the-background-image)
// - image (<img>, svg <image>) or video (<video>) elements that are
// placeholders for displaying them.
-class CORE_EXPORT NGPaintFragment : public DisplayItemClient,
+class CORE_EXPORT NGPaintFragment : public RefCounted<NGPaintFragment>,
+ public DisplayItemClient,
public ImageResourceObserver {
public:
- NGPaintFragment(scoped_refptr<const NGPhysicalFragment>, NGPaintFragment*);
+ NGPaintFragment(scoped_refptr<const NGPhysicalFragment>,
+ NGPhysicalOffset offset,
+ NGPaintFragment*);
~NGPaintFragment() override;
- static std::unique_ptr<NGPaintFragment> Create(
- scoped_refptr<const NGPhysicalFragment>);
+
+ static scoped_refptr<NGPaintFragment> Create(
+ scoped_refptr<const NGPhysicalFragment>,
+ NGPhysicalOffset offset);
const NGPhysicalFragment& PhysicalFragment() const {
return *physical_fragment_;
}
+ void UpdatePhysicalFragmentFromCachedLayoutResult(
+ scoped_refptr<const NGPhysicalFragment>);
+
+ // Next/last fragment for when this is fragmented.
+ NGPaintFragment* Next() { return next_fragmented_.get(); }
+ void SetNext(scoped_refptr<NGPaintFragment>);
+ NGPaintFragment* Last();
+ NGPaintFragment* Last(const NGBreakToken&);
+
// The parent NGPaintFragment. This is nullptr for a root; i.e., when parent
// is not for NGPaint. In the first phase, this means that this is a root of
// an inline formatting context.
NGPaintFragment* Parent() const { return parent_; }
- const Vector<std::unique_ptr<NGPaintFragment>>& Children() const {
+ const Vector<scoped_refptr<NGPaintFragment>>& Children() const {
return children_;
}
// Note, as the name implies, |IsDescendantOfNotSelf| returns false for the
@@ -124,7 +138,7 @@ class CORE_EXPORT NGPaintFragment : public DisplayItemClient,
return PhysicalFragment().GetLayoutObject();
}
const ComputedStyle& Style() const { return PhysicalFragment().Style(); }
- NGPhysicalOffset Offset() const { return PhysicalFragment().Offset(); }
+ NGPhysicalOffset Offset() const { return offset_; }
NGPhysicalSize Size() const { return PhysicalFragment().Size(); }
// Converts the given point, relative to the fragment itself, into a position
@@ -135,6 +149,14 @@ class CORE_EXPORT NGPaintFragment : public DisplayItemClient,
// from GetNode() when this fragment is content of a pseudo node.
Node* NodeForHitTest() const;
+ // Utility functions for caret painting. Note that carets are painted as part
+ // of the containing block's foreground.
+ bool ShouldPaintCursorCaret() const;
+ bool ShouldPaintDragCaret() const;
+ bool ShouldPaintCarets() const {
+ return ShouldPaintCursorCaret() || ShouldPaintDragCaret();
+ }
+
// A range of fragments for |FragmentsFor()|.
class CORE_EXPORT FragmentRange {
public:
@@ -160,7 +182,7 @@ class CORE_EXPORT NGPaintFragment : public DisplayItemClient,
NGPaintFragment* operator->() const { return current_; }
iterator& operator++() {
CHECK(current_);
- current_ = current_->next_fragment_;
+ current_ = current_->next_for_same_layout_object_.get();
return *this;
}
bool operator==(const iterator& other) const {
@@ -183,10 +205,14 @@ class CORE_EXPORT NGPaintFragment : public DisplayItemClient,
// Returns the last |NGPaintFragment| in |FragmentRange| as STL container.
// It is error to call |back()| for empty range.
- // Note: The complicity of |back()| is O(n) where n is number of elements
+ // Note: The complexity of |back()| is O(n) where n is number of elements
// in this |FragmentRange|.
NGPaintFragment& back() const;
+ // Returns number of fragments in this range. The complexity is O(n) where n
+ // is number of elements.
+ wtf_size_t size() const;
+
private:
NGPaintFragment* first_;
bool is_in_layout_ng_inline_formatting_context_;
@@ -204,6 +230,10 @@ class CORE_EXPORT NGPaintFragment : public DisplayItemClient,
// for a LayoutObject.
static FragmentRange InlineFragmentsFor(const LayoutObject*);
+ // Reset a range of NGPaintFragment in an inline formatting context that are
+ // for a LayoutObject.
+ static void ResetInlineFragmentsFor(const LayoutObject*);
+
// Computes LocalVisualRect for an inline LayoutObject in the
// LayoutObject::LocalVisualRect semantics; i.e., physical coordinates with
// flipped block-flow direction. See layout/README.md for the coordinate
@@ -215,7 +245,9 @@ class CORE_EXPORT NGPaintFragment : public DisplayItemClient,
private:
void PopulateDescendants(
const NGPhysicalOffset inline_offset_to_container_box,
- HashMap<const LayoutObject*, NGPaintFragment*>* first_fragment_map,
+ HashMap<const LayoutObject*, NGPaintFragment*>* last_fragment_map);
+ void AssociateWithLayoutObject(
+ LayoutObject*,
HashMap<const LayoutObject*, NGPaintFragment*>* last_fragment_map);
// Helps for PositionForPoint() when |this| falls in different categories.
@@ -230,24 +262,16 @@ class CORE_EXPORT NGPaintFragment : public DisplayItemClient,
//
scoped_refptr<const NGPhysicalFragment> physical_fragment_;
+ NGPhysicalOffset offset_;
NGPaintFragment* parent_;
- Vector<std::unique_ptr<NGPaintFragment>> children_;
+ Vector<scoped_refptr<NGPaintFragment>> children_;
- NGPaintFragment* next_fragment_ = nullptr;
- NGPhysicalOffset inline_offset_to_container_box_;
+ // The next fragment for when this is fragmented.
+ scoped_refptr<NGPaintFragment> next_fragmented_;
- // Maps LayoutObject to NGPaintFragment for the root of an inline formatting
- // context.
- // TODO(kojii): This is to be stored in fields of LayoutObject where they are
- // no longer used in NGPaint, specifically:
- // LayoutText::first_text_box_
- // LayoutInline::line_boxes_
- // LayotuBox::inline_box_wrapper_
- // but doing so is likely to have some impacts on the performance.
- // Alternatively we can keep in the root NGPaintFragment. Having this in all
- // NGPaintFragment is tentative.
- HashMap<const LayoutObject*, NGPaintFragment*> first_fragment_map_;
+ scoped_refptr<NGPaintFragment> next_for_same_layout_object_;
+ NGPhysicalOffset inline_offset_to_container_box_;
//
// Following fields are computed in the pre-paint phase.
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 aad88b113e8..21ec3583c6c 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
@@ -30,7 +30,7 @@ void CollectPaintFragments(const NGPaintFragment& container,
result->push_back(fragment_with_offset);
}
if (filter.IsTraverse(child.get())) {
- CollectPaintFragments(*child.get(), fragment_with_offset.container_offset,
+ CollectPaintFragments(*child, fragment_with_offset.container_offset,
filter, result);
}
}
@@ -56,7 +56,7 @@ class InlineFilter {
}
bool IsTraverse(const NGPaintFragment* fragment) {
return fragment->PhysicalFragment().IsContainer() &&
- !fragment->PhysicalFragment().IsBlockLayoutRoot();
+ !fragment->PhysicalFragment().IsBlockFormattingContextRoot();
}
};
diff --git a/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_traversal.h b/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_traversal.h
index e1de32a0e64..c212076677b 100644
--- a/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_traversal.h
+++ b/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_traversal.h
@@ -27,6 +27,7 @@ struct CORE_EXPORT NGPaintFragmentWithContainerOffset {
struct CORE_EXPORT NGPaintFragmentTraversalContext {
STACK_ALLOCATED();
+ public:
static NGPaintFragmentTraversalContext Create(const NGPaintFragment*);
bool IsNull() const { return !parent; }
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 fcf2c77a241..e9a7f1b5242 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
@@ -27,7 +27,7 @@ class NGPaintFragmentTraversalTest : public RenderingTest,
root_fragment_ = layout_block_flow_->PaintFragment();
}
- const Vector<std::unique_ptr<NGPaintFragment>>& RootChildren() const {
+ const Vector<scoped_refptr<NGPaintFragment>>& RootChildren() const {
return root_fragment_->Children();
}
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 ac5b860c2f5..4910c70fbab 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
@@ -73,7 +73,7 @@ DocumentMarkerVector ComputeMarkersToPaint(
const NGPaintFragment& paint_fragment) {
// TODO(yoichio): Handle first-letter
Node* const node = paint_fragment.GetNode();
- if (!node)
+ if (!node || !node->IsTextNode())
return DocumentMarkerVector();
// We don't paint any marker on ellipsis.
if (paint_fragment.PhysicalFragment().StyleVariant() ==
@@ -82,11 +82,12 @@ DocumentMarkerVector ComputeMarkersToPaint(
DocumentMarkerController& document_marker_controller =
node->GetDocument().Markers();
- return document_marker_controller.ComputeMarkersToPaint(*node);
+ return document_marker_controller.ComputeMarkersToPaint(ToText(*node));
}
unsigned GetTextContentOffset(const Text& text, unsigned offset) {
- const Position position(text, offset);
+ // TODO(yoichio): Sanitize DocumentMarker around text length.
+ const Position position(text, std::min(offset, text.length()));
const NGOffsetMapping* const offset_mapping =
NGOffsetMapping::GetFor(position);
DCHECK(offset_mapping);
@@ -274,9 +275,6 @@ void NGTextFragmentPainter::Paint(const PaintInfo& paint_info,
if (!ShouldPaintTextFragment(text_fragment, style))
return;
- NGPhysicalSize size_;
- NGPhysicalOffset offset_;
-
// We round the y-axis to ensure consistent line heights.
LayoutPoint adjusted_paint_offset =
LayoutPoint(paint_offset.X(), LayoutUnit(paint_offset.Y().Round()));
diff --git a/chromium/third_party/blink/renderer/core/paint/nine_piece_image_grid.h b/chromium/third_party/blink/renderer/core/paint/nine_piece_image_grid.h
index 8797bce666f..a014db71c3a 100644
--- a/chromium/third_party/blink/renderer/core/paint/nine_piece_image_grid.h
+++ b/chromium/third_party/blink/renderer/core/paint/nine_piece_image_grid.h
@@ -71,6 +71,8 @@ class CORE_EXPORT NinePieceImageGrid {
struct CORE_EXPORT NinePieceDrawInfo {
STACK_ALLOCATED();
+
+ public:
bool is_drawable;
bool is_corner_piece;
FloatRect destination;
diff --git a/chromium/third_party/blink/renderer/core/paint/nine_piece_image_grid_test.cc b/chromium/third_party/blink/renderer/core/paint/nine_piece_image_grid_test.cc
index 3aaa55af317..ca9f272a56a 100644
--- a/chromium/third_party/blink/renderer/core/paint/nine_piece_image_grid_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/nine_piece_image_grid_test.cc
@@ -93,7 +93,6 @@ TEST_F(NinePieceImageGridTest, NinePieceImagePainting_TopLeftDrawable) {
IntSize image_size(100, 100);
IntRect border_image_area(0, 0, 100, 100);
- IntRectOutsets border_widths(10, 10, 10, 10);
const struct {
IntRectOutsets border_widths;
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 88f1a5c66ed..d1a31aa00f4 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
@@ -141,13 +141,13 @@ void ObjectPaintInvalidator::
DCHECK(!RuntimeEnabledFeatures::SlimmingPaintV2Enabled());
SlowSetPaintingLayerNeedsRepaint();
// This method may be used to invalidate paint of objects changing paint
- // invalidation container. Clear previous visual rects on the original paint
- // invalidation container to avoid under-invalidation if the visual rect on
- // the new paint invalidation container happens to be the same as the old one.
+ // invalidation container. Visual rects don't have to be cleared, since they
+ // are relative to the transform ancestor.
+ // TODO(vmpstr): After paint containment isolation is in place, we might not
+ // have to recurse past the paint containment boundary.
TraverseNonCompositingDescendantsInPaintOrder(
object_, [](const LayoutObject& object) {
SetPaintingLayerNeedsRepaintDuringTraverse(object);
- object.GetMutableForPainting().ClearPreviousVisualRects();
});
}
@@ -285,7 +285,7 @@ ObjectPaintInvalidatorWithContext::ComputePaintInvalidationReason() {
}
DISABLE_CFI_PERF
-void ObjectPaintInvalidatorWithContext::InvalidateSelection(
+PaintInvalidationReason ObjectPaintInvalidatorWithContext::InvalidateSelection(
PaintInvalidationReason reason) {
// In LayoutNG, if NGPaintFragment paints the selection, we invalidate for
// selection change in PaintInvalidator.
@@ -294,15 +294,15 @@ void ObjectPaintInvalidatorWithContext::InvalidateSelection(
!object_.IsLayoutReplaced() &&
NGPaintFragment::InlineFragmentsFor(&object_)
.IsInLayoutNGInlineFormattingContext())
- return;
+ return reason;
// Update selection rect when we are doing full invalidation with geometry
// change (in case that the object is moved, composite status changed, etc.)
// or shouldInvalidationSelection is set (in case that the selection itself
// changed).
- bool full_invalidation = IsImmediateFullPaintInvalidationReason(reason);
+ bool full_invalidation = IsFullPaintInvalidationReason(reason);
if (!full_invalidation && !object_.ShouldInvalidateSelection())
- return;
+ return reason;
LayoutRect old_selection_rect = object_.SelectionVisualRect();
LayoutRect new_selection_rect;
@@ -320,70 +320,54 @@ void ObjectPaintInvalidatorWithContext::InvalidateSelection(
object_.GetMutableForPainting().SetSelectionVisualRect(new_selection_rect);
if (full_invalidation)
- return;
+ return reason;
+
+ const LayoutRect invalidation_rect =
+ UnionRect(new_selection_rect, old_selection_rect);
+ if (invalidation_rect.IsEmpty())
+ return reason;
object_.GetMutableForPainting().SetPartialInvalidationVisualRect(
- UnionRect(object_.PartialInvalidationVisualRect(),
- UnionRect(new_selection_rect, old_selection_rect)));
- context_.painting_layer->SetNeedsRepaint();
- object_.InvalidateDisplayItemClients(PaintInvalidationReason::kSelection);
+ UnionRect(object_.PartialInvalidationVisualRect(), invalidation_rect));
+ return PaintInvalidationReason::kSelection;
}
DISABLE_CFI_PERF
-void ObjectPaintInvalidatorWithContext::InvalidatePartialRect(
+PaintInvalidationReason
+ObjectPaintInvalidatorWithContext::InvalidatePartialRect(
PaintInvalidationReason reason) {
- if (IsImmediateFullPaintInvalidationReason(reason))
- return;
+ if (IsFullPaintInvalidationReason(reason))
+ return reason;
auto rect = object_.PartialInvalidationLocalRect();
if (rect.IsEmpty())
- return;
+ return reason;
context_.MapLocalRectToVisualRect(object_, rect);
if (rect.IsEmpty())
- return;
+ return reason;
object_.GetMutableForPainting().SetPartialInvalidationVisualRect(
UnionRect(object_.PartialInvalidationVisualRect(), rect));
- context_.painting_layer->SetNeedsRepaint();
- object_.InvalidateDisplayItemClients(PaintInvalidationReason::kRectangle);
+ return PaintInvalidationReason::kRectangle;
}
DISABLE_CFI_PERF
-PaintInvalidationReason
-ObjectPaintInvalidatorWithContext::InvalidatePaintWithComputedReason(
+void ObjectPaintInvalidatorWithContext::InvalidatePaintWithComputedReason(
PaintInvalidationReason reason) {
DCHECK(!(context_.subtree_flags &
PaintInvalidatorContext::kSubtreeNoInvalidation));
- // This is before InvalidateSelection before the latter will accumulate
- // selection visual rects to the partial rect mapped in the former.
- InvalidatePartialRect(reason);
-
- // We need to invalidate the selection before checking for whether we are
- // doing a full invalidation. This is because we need to update the previous
- // selection rect regardless.
- InvalidateSelection(reason);
-
- switch (reason) {
- case PaintInvalidationReason::kNone:
- if (object_.IsSVG() &&
- (context_.subtree_flags &
- PaintInvalidatorContext::kSubtreeSVGResourceChange)) {
- reason = PaintInvalidationReason::kSVGResource;
- break;
- }
- return PaintInvalidationReason::kNone;
- case PaintInvalidationReason::kDelayedFull:
- return PaintInvalidationReason::kDelayedFull;
- default:
- DCHECK(IsImmediateFullPaintInvalidationReason(reason));
- }
+ // InvalidatePartialRect is before InvalidateSelection because the latter will
+ // accumulate selection visual rects to the partial rect mapped in the former.
+ reason = InvalidatePartialRect(reason);
+ reason = InvalidateSelection(reason);
+ if (reason == PaintInvalidationReason::kNone)
+ return;
context_.painting_layer->SetNeedsRepaint();
object_.InvalidateDisplayItemClients(reason);
- return reason;
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/object_paint_invalidator.h b/chromium/third_party/blink/renderer/core/paint/object_paint_invalidator.h
index af5aad1808c..a0605c26e95 100644
--- a/chromium/third_party/blink/renderer/core/paint/object_paint_invalidator.h
+++ b/chromium/third_party/blink/renderer/core/paint/object_paint_invalidator.h
@@ -56,17 +56,16 @@ class ObjectPaintInvalidatorWithContext : public ObjectPaintInvalidator {
const PaintInvalidatorContext& context)
: ObjectPaintInvalidator(object), context_(context) {}
- PaintInvalidationReason InvalidatePaint() {
- return InvalidatePaintWithComputedReason(ComputePaintInvalidationReason());
+ void InvalidatePaint() {
+ InvalidatePaintWithComputedReason(ComputePaintInvalidationReason());
}
PaintInvalidationReason ComputePaintInvalidationReason();
- PaintInvalidationReason InvalidatePaintWithComputedReason(
- PaintInvalidationReason);
+ void InvalidatePaintWithComputedReason(PaintInvalidationReason);
private:
- void InvalidateSelection(PaintInvalidationReason);
- void InvalidatePartialRect(PaintInvalidationReason);
+ PaintInvalidationReason InvalidateSelection(PaintInvalidationReason);
+ PaintInvalidationReason InvalidatePartialRect(PaintInvalidationReason);
const PaintInvalidatorContext& context_;
};
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 30701f663e6..88c8cfd8d3e 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
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/paint/object_paint_invalidator.h"
+#include "testing/gmock/include/gmock/gmock-matchers.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/core/editing/frame_selection.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
@@ -16,6 +17,9 @@ namespace blink {
using ObjectPaintInvalidatorTest = RenderingTest;
+using PaintInvalidation = LocalFrameView::ObjectPaintInvalidation;
+using ::testing::ElementsAre;
+
TEST_F(ObjectPaintInvalidatorTest,
TraverseNonCompositingDescendantsInPaintOrder) {
if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
@@ -49,23 +53,23 @@ TEST_F(ObjectPaintInvalidatorTest,
ObjectPaintInvalidator(*GetLayoutObjectByElementId("container"))
.InvalidateDisplayItemClientsIncludingNonCompositingDescendants(
PaintInvalidationReason::kSubtree);
- std::unique_ptr<JSONArray> invalidations =
- GetDocument().View()->TrackedObjectPaintInvalidationsAsJSON();
+ EXPECT_THAT(*GetDocument().View()->TrackedObjectPaintInvalidations(),
+ ElementsAre(
+ PaintInvalidation{
+ GetLayoutObjectByElementId("container")->DebugName(),
+ PaintInvalidationReason::kSubtree},
+ PaintInvalidation{
+ GetLayoutObjectByElementId("normal-child")->DebugName(),
+ PaintInvalidationReason::kSubtree},
+ PaintInvalidation{
+ GetLayoutObjectByElementId("stacked-child")->DebugName(),
+ PaintInvalidationReason::kSubtree},
+ PaintInvalidation{
+ GetLayoutObjectByElementId(
+ "stacked-child-of-composited-non-stacking-context")
+ ->DebugName(),
+ PaintInvalidationReason::kSubtree}));
GetDocument().View()->SetTracksPaintInvalidations(false);
-
- ASSERT_EQ(4u, invalidations->size());
- String s;
- JSONObject::Cast(invalidations->at(0))->Get("object")->AsString(&s);
- EXPECT_EQ(GetLayoutObjectByElementId("container")->DebugName(), s);
- JSONObject::Cast(invalidations->at(1))->Get("object")->AsString(&s);
- EXPECT_EQ(GetLayoutObjectByElementId("normal-child")->DebugName(), s);
- JSONObject::Cast(invalidations->at(2))->Get("object")->AsString(&s);
- EXPECT_EQ(GetLayoutObjectByElementId("stacked-child")->DebugName(), s);
- JSONObject::Cast(invalidations->at(3))->Get("object")->AsString(&s);
- EXPECT_EQ(GetLayoutObjectByElementId(
- "stacked-child-of-composited-non-stacking-context")
- ->DebugName(),
- s);
}
TEST_F(ObjectPaintInvalidatorTest, TraverseFloatUnderCompositedInline) {
@@ -137,21 +141,17 @@ TEST_F(ObjectPaintInvalidatorTest, TraverseFloatUnderCompositedInline) {
EXPECT_TRUE(composited_container_layer->NeedsRepaint());
EXPECT_FALSE(span_layer->NeedsRepaint());
- std::unique_ptr<JSONArray> invalidations =
- GetDocument().View()->TrackedObjectPaintInvalidationsAsJSON();
+ EXPECT_THAT(
+ *GetDocument().View()->TrackedObjectPaintInvalidations(),
+ ElementsAre(PaintInvalidation{composited_container->DebugName(),
+ PaintInvalidationReason::kSubtree},
+ PaintInvalidation{containing_block->DebugName(),
+ PaintInvalidationReason::kSubtree},
+ PaintInvalidation{target->DebugName(),
+ PaintInvalidationReason::kSubtree},
+ PaintInvalidation{"LayoutText #text",
+ PaintInvalidationReason::kSubtree}));
GetDocument().View()->SetTracksPaintInvalidations(false);
-
- ASSERT_EQ(4u, invalidations->size());
- String s;
- JSONObject::Cast(invalidations->at(0))->Get("object")->AsString(&s);
- EXPECT_EQ(composited_container->DebugName(), s);
- JSONObject::Cast(invalidations->at(1))->Get("object")->AsString(&s);
- EXPECT_EQ(containing_block->DebugName(), s);
- JSONObject::Cast(invalidations->at(2))->Get("object")->AsString(&s);
- EXPECT_EQ(target->DebugName(), s);
- // This is the text node after the span.
- JSONObject::Cast(invalidations->at(3))->Get("object")->AsString(&s);
- EXPECT_EQ("LayoutText #text", s);
}
TEST_F(ObjectPaintInvalidatorTest,
@@ -206,21 +206,17 @@ TEST_F(ObjectPaintInvalidatorTest,
EXPECT_FALSE(span_layer->NeedsRepaint());
EXPECT_FALSE(inner_span_layer->NeedsRepaint());
- std::unique_ptr<JSONArray> invalidations =
- GetDocument().View()->TrackedObjectPaintInvalidationsAsJSON();
+ EXPECT_THAT(
+ *GetDocument().View()->TrackedObjectPaintInvalidations(),
+ ElementsAre(PaintInvalidation{composited_container->DebugName(),
+ PaintInvalidationReason::kSubtree},
+ PaintInvalidation{containing_block->DebugName(),
+ PaintInvalidationReason::kSubtree},
+ PaintInvalidation{target->DebugName(),
+ PaintInvalidationReason::kSubtree},
+ PaintInvalidation{"LayoutText #text",
+ PaintInvalidationReason::kSubtree}));
GetDocument().View()->SetTracksPaintInvalidations(false);
-
- ASSERT_EQ(4u, invalidations->size());
- String s;
- JSONObject::Cast(invalidations->at(0))->Get("object")->AsString(&s);
- EXPECT_EQ(composited_container->DebugName(), s);
- JSONObject::Cast(invalidations->at(1))->Get("object")->AsString(&s);
- EXPECT_EQ(containing_block->DebugName(), s);
- JSONObject::Cast(invalidations->at(2))->Get("object")->AsString(&s);
- EXPECT_EQ(target->DebugName(), s);
- // This is the text node after the span.
- JSONObject::Cast(invalidations->at(3))->Get("object")->AsString(&s);
- EXPECT_EQ("LayoutText #text", s);
}
TEST_F(ObjectPaintInvalidatorTest, TraverseStackedFloatUnderCompositedInline) {
@@ -252,18 +248,15 @@ TEST_F(ObjectPaintInvalidatorTest, TraverseStackedFloatUnderCompositedInline) {
PaintInvalidationReason::kSubtree);
EXPECT_TRUE(span_layer->NeedsRepaint());
- std::unique_ptr<JSONArray> invalidations =
- GetDocument().View()->TrackedObjectPaintInvalidationsAsJSON();
+ EXPECT_THAT(
+ *GetDocument().View()->TrackedObjectPaintInvalidations(),
+ ElementsAre(PaintInvalidation{span->DebugName(),
+ PaintInvalidationReason::kSubtree},
+ PaintInvalidation{"LayoutText #text",
+ PaintInvalidationReason::kSubtree},
+ PaintInvalidation{target->DebugName(),
+ PaintInvalidationReason::kSubtree}));
GetDocument().View()->SetTracksPaintInvalidations(false);
-
- ASSERT_EQ(3u, invalidations->size());
- String s;
- JSONObject::Cast(invalidations->at(0))->Get("object")->AsString(&s);
- EXPECT_EQ(span->DebugName(), s);
- JSONObject::Cast(invalidations->at(1))->Get("object")->AsString(&s);
- EXPECT_EQ("LayoutText #text", s);
- JSONObject::Cast(invalidations->at(2))->Get("object")->AsString(&s);
- EXPECT_EQ(target->DebugName(), s);
}
TEST_F(ObjectPaintInvalidatorTest, InvalidatePaintRectangle) {
@@ -279,7 +272,7 @@ TEST_F(ObjectPaintInvalidatorTest, InvalidatePaintRectangle) {
EXPECT_EQ(LayoutRect(10, 10, 50, 50), target->PartialInvalidationLocalRect());
target->InvalidatePaintRectangle(LayoutRect(30, 30, 60, 60));
EXPECT_EQ(LayoutRect(10, 10, 80, 80), target->PartialInvalidationLocalRect());
- EXPECT_TRUE(target->MayNeedPaintInvalidation());
+ EXPECT_TRUE(target->ShouldCheckForPaintInvalidation());
GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
EXPECT_EQ(LayoutRect(), target->PartialInvalidationLocalRect());
@@ -297,19 +290,12 @@ TEST_F(ObjectPaintInvalidatorTest, InvalidatePaintRectangle) {
EXPECT_EQ(LayoutRect(), target->PartialInvalidationLocalRect());
EXPECT_EQ(LayoutRect(), target->PartialInvalidationVisualRect());
- auto object_invalidations =
- GetDocument().View()->TrackedObjectPaintInvalidationsAsJSON();
- ASSERT_EQ(2u, object_invalidations->size());
- for (int i = 0; i < 2; i++) {
- String s;
- const auto* entry = JSONObject::Cast(object_invalidations->at(i));
- entry->Get("reason")->AsString(&s);
- EXPECT_EQ(String(PaintInvalidationReasonToString(
- PaintInvalidationReason::kRectangle)),
- s);
- entry->Get("object")->AsString(&s);
- EXPECT_EQ(target->DebugName(), s);
- }
+ EXPECT_THAT(
+ *GetDocument().View()->TrackedObjectPaintInvalidations(),
+ ElementsAre(PaintInvalidation{target->DebugName(),
+ PaintInvalidationReason::kRectangle},
+ PaintInvalidation{target->DebugName(),
+ PaintInvalidationReason::kRectangle}));
const auto& raster_invalidations = GetLayoutView()
.Layer()
@@ -345,7 +331,7 @@ TEST_F(ObjectPaintInvalidatorTest, Selection) {
// Simulate a change without full invalidation or selection change.
GetDocument().View()->SetTracksPaintInvalidations(true);
- target->SetMayNeedPaintInvalidation();
+ target->SetShouldCheckForPaintInvalidation();
GetDocument().View()->UpdateAllLifecyclePhases();
EXPECT_TRUE(graphics_layer->GetRasterInvalidationTracking()
->Invalidations()
diff --git a/chromium/third_party/blink/renderer/core/paint/object_paint_properties.h b/chromium/third_party/blink/renderer/core/paint/object_paint_properties.h
index 736b174648d..f1c172a6d95 100644
--- a/chromium/third_party/blink/renderer/core/paint/object_paint_properties.h
+++ b/chromium/third_party/blink/renderer/core/paint/object_paint_properties.h
@@ -43,6 +43,58 @@ class CORE_EXPORT ObjectPaintProperties {
return base::WrapUnique(new ObjectPaintProperties());
}
+ ~ObjectPaintProperties() { DCHECK(!is_immutable_); }
+
+ class UpdateResult {
+ public:
+ bool Unchanged() const { return result_ == kUnchanged; }
+ bool NewNodeCreated() const { return result_ == kNewNodeCreated; }
+
+ private:
+ friend class ObjectPaintProperties;
+ enum Result { kUnchanged, kValueChanged, kNewNodeCreated };
+ UpdateResult(Result r) : result_(r) {}
+ Result result_;
+ };
+
+// The following defines 3 functions and one variable:
+// - Foo(): a getter for the property.
+// - UpdateFoo(): an update function.
+// - ClearFoo(): a clear function
+// - foo_: the variable itself.
+//
+// Note that clear* functions return true if the property tree structure
+// changes (an existing node was deleted), and false otherwise. See the
+// class-level comment ("update & clear implementation note") for details
+// about why this is needed for efficient updates.
+#define ADD_NODE(type, function, variable) \
+ const type##PaintPropertyNode* function() const { return variable.get(); } \
+ UpdateResult Update##function(const type##PaintPropertyNode& parent, \
+ type##PaintPropertyNode::State&& state) { \
+ auto result = Update(variable, parent, std::move(state)); \
+ DCHECK(!is_immutable_ || result.Unchanged()) \
+ << "Value changed while immutable. New state:\n" \
+ << *variable; \
+ return result; \
+ } \
+ bool Clear##function() { \
+ DCHECK(!is_immutable_ || !variable) \
+ << "Value cleared while immutable. Old state:\n" \
+ << *variable; \
+ return Clear(variable); \
+ } \
+ \
+ private: \
+ scoped_refptr<type##PaintPropertyNode> variable; \
+ \
+ public:
+// (End of ADD_NODE definition)
+
+#define ADD_TRANSFORM(function, variable) \
+ ADD_NODE(Transform, function, variable)
+#define ADD_EFFECT(function, variable) ADD_NODE(Effect, function, variable)
+#define ADD_CLIP(function, variable) ADD_NODE(Clip, function, variable)
+
// The hierarchy of the transform subtree created by a LayoutObject is as
// follows:
// [ paintOffsetTranslation ] Normally paint offset is accumulated
@@ -52,33 +104,23 @@ class CORE_EXPORT ObjectPaintProperties {
// +---[ transform ] The space created by CSS transform.
// | This is the local border box space.
// +---[ perspective ] The space created by CSS perspective.
- // +---[ svgLocalToBorderBoxTransform ] Additional transform for
- // children of the outermost root SVG.
- // OR (SVG does not support scrolling.)
+ // +---[ replacedContentTransform ] Additional transform for replaced
+ // elements to implement object-fit.
+ // OR (Replaced elements don't scroll.)
// +---[ scrollTranslation ] The space created by overflow clip.
- const TransformPaintPropertyNode* PaintOffsetTranslation() const {
- return paint_offset_translation_.get();
- }
- const TransformPaintPropertyNode* Transform() const {
- return transform_.get();
- }
- const TransformPaintPropertyNode* Perspective() const {
- return perspective_.get();
- }
- const TransformPaintPropertyNode* SvgLocalToBorderBoxTransform() const {
- return svg_local_to_border_box_transform_.get();
- }
- const ScrollPaintPropertyNode* Scroll() const { return scroll_.get(); }
- const TransformPaintPropertyNode* ScrollTranslation() const {
- return scroll_translation_.get();
- }
+ ADD_TRANSFORM(PaintOffsetTranslation, paint_offset_translation_);
+ ADD_TRANSFORM(Transform, transform_);
+ ADD_TRANSFORM(Perspective, perspective_);
+ ADD_TRANSFORM(ReplacedContentTransform, replaced_content_transform_);
+ ADD_TRANSFORM(ScrollTranslation, scroll_translation_);
+ ADD_NODE(Scroll, Scroll, scroll_);
// The hierarchy of the effect subtree created by a LayoutObject is as
// follows:
// [ effect ]
- // | Isolated group to apply various CSS effects, including opacity,
- // | mix-blend-mode, and for isolation if a mask needs to be applied or
- // | backdrop-dependent children are present.
+ // | Isolated group to apply various CSS effects, including opacity,
+ // | mix-blend-mode, and for isolation if a mask needs to be applied or
+ // | backdrop-dependent children are present.
// +-[ filter ]
// | Isolated group for CSS filter.
// +-[ vertical/horizontal scrollbar effect ]
@@ -88,19 +130,19 @@ class CORE_EXPORT ObjectPaintProperties {
// | Isolated group for painting the CSS mask. This node will have
// | SkBlendMode::kDstIn and shall paint last, i.e. after masked contents.
// +-[ clip path ]
- // Isolated group for painting the CSS clip-path. This node will have
- // SkBlendMode::kDstIn and shall paint last, i.e. after clipped
- // contents.
- const EffectPaintPropertyNode* Effect() const { return effect_.get(); }
- const EffectPaintPropertyNode* Filter() const { return filter_.get(); }
- const EffectPaintPropertyNode* VerticalScrollbarEffect() const {
- return vertical_scrollbar_effect_.get();
- }
- const EffectPaintPropertyNode* HorizontalScrollbarEffect() const {
- return horizontal_scrollbar_effect_.get();
- }
- const EffectPaintPropertyNode* Mask() const { return mask_.get(); }
- const EffectPaintPropertyNode* ClipPath() const { return clip_path_.get(); }
+ // | Isolated group for painting the CSS clip-path. This node will have
+ // | SkBlendMode::kDstIn and shall paint last, i.e. after clipped
+ // | contents.
+ // +-[ link highlight effect ]
+ // The link highlight effect is only used for link highlight animations
+ // and should never have descendants.
+ ADD_EFFECT(Effect, effect_);
+ ADD_EFFECT(Filter, filter_);
+ ADD_EFFECT(VerticalScrollbarEffect, vertical_scrollbar_effect_);
+ ADD_EFFECT(HorizontalScrollbarEffect, horizontal_scrollbar_effect_);
+ ADD_EFFECT(Mask, mask_);
+ ADD_EFFECT(ClipPath, clip_path_);
+ ADD_EFFECT(LinkHighlightEffect, link_highlight_effect_);
// The hierarchy of the clip subtree created by a LayoutObject is as follows:
// [ fragment clip ]
@@ -135,216 +177,25 @@ class CORE_EXPORT ObjectPaintProperties {
// [ css clip fixed position ]
// Clip created by CSS clip. Only exists if the current clip includes
// some clip that doesn't apply to our fixed position descendants.
- const ClipPaintPropertyNode* FragmentClip() const {
- return fragment_clip_.get();
- }
- const ClipPaintPropertyNode* ClipPathClip() const {
- return clip_path_clip_.get();
- }
- const ClipPaintPropertyNode* MaskClip() const { return mask_clip_.get(); }
- const ClipPaintPropertyNode* CssClip() const { return css_clip_.get(); }
- const ClipPaintPropertyNode* CssClipFixedPosition() const {
- return css_clip_fixed_position_.get();
- }
- const ClipPaintPropertyNode* OverflowControlsClip() const {
- return overflow_controls_clip_.get();
- }
- const ClipPaintPropertyNode* InnerBorderRadiusClip() const {
- return inner_border_radius_clip_.get();
- }
- const ClipPaintPropertyNode* OverflowClip() const {
- return overflow_clip_.get();
- }
-
- // The following clear* functions return true if the property tree structure
- // changes (an existing node was deleted), and false otherwise. See the
- // class-level comment ("update & clear implementation note") for details
- // about why this is needed for efficient updates.
- bool ClearPaintOffsetTranslation() {
- return Clear(paint_offset_translation_);
- }
- bool ClearTransform() { return Clear(transform_); }
- bool ClearEffect() { return Clear(effect_); }
- bool ClearFilter() { return Clear(filter_); }
- bool ClearVerticalScrollbarEffect() {
- return Clear(vertical_scrollbar_effect_);
- }
- bool ClearHorizontalScrollbarEffect() {
- return Clear(horizontal_scrollbar_effect_);
- }
- bool ClearMask() { return Clear(mask_); }
- bool ClearClipPath() { return Clear(clip_path_); }
- bool ClearFragmentClip() { return Clear(fragment_clip_); }
- bool ClearClipPathClip() { return Clear(clip_path_clip_); }
- bool ClearMaskClip() { return Clear(mask_clip_); }
- bool ClearCssClip() { return Clear(css_clip_); }
- bool ClearCssClipFixedPosition() { return Clear(css_clip_fixed_position_); }
- bool ClearOverflowControlsClip() { return Clear(overflow_controls_clip_); }
- bool ClearInnerBorderRadiusClip() { return Clear(inner_border_radius_clip_); }
- bool ClearOverflowClip() { return Clear(overflow_clip_); }
- bool ClearPerspective() { return Clear(perspective_); }
- bool ClearSvgLocalToBorderBoxTransform() {
- return Clear(svg_local_to_border_box_transform_);
- }
- bool ClearScroll() { return Clear(scroll_); }
- bool ClearScrollTranslation() { return Clear(scroll_translation_); }
-
- class UpdateResult {
- public:
- bool Unchanged() const { return result_ == kUnchanged; }
- bool NewNodeCreated() const { return result_ == kNewNodeCreated; }
-
- private:
- friend class ObjectPaintProperties;
- enum Result { kUnchanged, kValueChanged, kNewNodeCreated };
- UpdateResult(Result r) : result_(r) {}
- Result result_;
- };
-
- UpdateResult UpdatePaintOffsetTranslation(
- const TransformPaintPropertyNode& parent,
- TransformPaintPropertyNode::State&& state) {
- return Update(paint_offset_translation_, parent, std::move(state));
- }
- UpdateResult UpdateTransform(const TransformPaintPropertyNode& parent,
- TransformPaintPropertyNode::State&& state) {
- return Update(transform_, parent, std::move(state));
- }
- UpdateResult UpdatePerspective(const TransformPaintPropertyNode& parent,
- TransformPaintPropertyNode::State&& state) {
- return Update(perspective_, parent, std::move(state));
- }
- UpdateResult UpdateSvgLocalToBorderBoxTransform(
- const TransformPaintPropertyNode& parent,
- TransformPaintPropertyNode::State&& state) {
- DCHECK(!ScrollTranslation()) << "SVG elements cannot scroll so there "
- "should never be both a scroll translation "
- "and an SVG local to border box transform.";
- return Update(svg_local_to_border_box_transform_, parent, std::move(state));
- }
- UpdateResult UpdateScroll(const ScrollPaintPropertyNode& parent,
- ScrollPaintPropertyNode::State&& state) {
- return Update(scroll_, parent, std::move(state));
- }
- UpdateResult UpdateScrollTranslation(
- const TransformPaintPropertyNode& parent,
- TransformPaintPropertyNode::State&& state) {
- DCHECK(!SvgLocalToBorderBoxTransform())
- << "SVG elements cannot scroll so there should never be both a scroll "
- "translation and an SVG local to border box transform.";
- return Update(scroll_translation_, parent, std::move(state));
- }
- UpdateResult UpdateEffect(const EffectPaintPropertyNode& parent,
- EffectPaintPropertyNode::State&& state) {
- return Update(effect_, parent, std::move(state));
- }
- UpdateResult UpdateFilter(const EffectPaintPropertyNode& parent,
- EffectPaintPropertyNode::State&& state) {
- return Update(filter_, parent, std::move(state));
- }
- UpdateResult UpdateVerticalScrollbarEffect(
- const EffectPaintPropertyNode& parent,
- EffectPaintPropertyNode::State&& state) {
- return Update(vertical_scrollbar_effect_, parent, std::move(state));
- }
- UpdateResult UpdateHorizontalScrollbarEffect(
- const EffectPaintPropertyNode& parent,
- EffectPaintPropertyNode::State&& state) {
- return Update(horizontal_scrollbar_effect_, parent, std::move(state));
- }
- UpdateResult UpdateMask(const EffectPaintPropertyNode& parent,
- EffectPaintPropertyNode::State&& state) {
- return Update(mask_, parent, std::move(state));
- }
- UpdateResult UpdateClipPath(const EffectPaintPropertyNode& parent,
- EffectPaintPropertyNode::State&& state) {
- return Update(clip_path_, parent, std::move(state));
- }
- UpdateResult UpdateFragmentClip(const ClipPaintPropertyNode& parent,
- ClipPaintPropertyNode::State&& state) {
- return Update(fragment_clip_, parent, std::move(state));
- }
- UpdateResult UpdateClipPathClip(const ClipPaintPropertyNode& parent,
- ClipPaintPropertyNode::State&& state) {
- return Update(clip_path_clip_, parent, std::move(state));
- }
- UpdateResult UpdateMaskClip(const ClipPaintPropertyNode& parent,
- ClipPaintPropertyNode::State&& state) {
- return Update(mask_clip_, parent, std::move(state));
- }
- UpdateResult UpdateCssClip(const ClipPaintPropertyNode& parent,
- ClipPaintPropertyNode::State&& state) {
- return Update(css_clip_, parent, std::move(state));
- }
- UpdateResult UpdateCssClipFixedPosition(
- const ClipPaintPropertyNode& parent,
- ClipPaintPropertyNode::State&& state) {
- return Update(css_clip_fixed_position_, parent, std::move(state));
- }
- UpdateResult UpdateOverflowControlsClip(
- const ClipPaintPropertyNode& parent,
- ClipPaintPropertyNode::State&& state) {
- return Update(overflow_controls_clip_, parent, std::move(state));
- }
- UpdateResult UpdateInnerBorderRadiusClip(
- const ClipPaintPropertyNode& parent,
- ClipPaintPropertyNode::State&& state) {
- return Update(inner_border_radius_clip_, parent, std::move(state));
- }
- UpdateResult UpdateOverflowClip(const ClipPaintPropertyNode& parent,
- ClipPaintPropertyNode::State&& state) {
- return Update(overflow_clip_, parent, std::move(state));
- }
+ ADD_CLIP(FragmentClip, fragment_clip_);
+ ADD_CLIP(ClipPathClip, clip_path_clip_);
+ ADD_CLIP(MaskClip, mask_clip_);
+ ADD_CLIP(CssClip, css_clip_);
+ ADD_CLIP(CssClipFixedPosition, css_clip_fixed_position_);
+ ADD_CLIP(OverflowControlsClip, overflow_controls_clip_);
+ ADD_CLIP(InnerBorderRadiusClip, inner_border_radius_clip_);
+ ADD_CLIP(OverflowClip, overflow_clip_);
#if DCHECK_IS_ON()
- // Used by FindPropertiesNeedingUpdate.h for recording the current properties.
- std::unique_ptr<ObjectPaintProperties> Clone() const {
- std::unique_ptr<ObjectPaintProperties> cloned = Create();
- if (paint_offset_translation_)
- cloned->paint_offset_translation_ = paint_offset_translation_->Clone();
- if (transform_)
- cloned->transform_ = transform_->Clone();
- if (effect_)
- cloned->effect_ = effect_->Clone();
- if (filter_)
- cloned->filter_ = filter_->Clone();
- if (vertical_scrollbar_effect_)
- cloned->vertical_scrollbar_effect_ = vertical_scrollbar_effect_->Clone();
- if (horizontal_scrollbar_effect_) {
- cloned->horizontal_scrollbar_effect_ =
- horizontal_scrollbar_effect_->Clone();
- }
- if (mask_)
- cloned->mask_ = mask_->Clone();
- if (clip_path_)
- cloned->clip_path_ = clip_path_->Clone();
- if (fragment_clip_)
- cloned->fragment_clip_ = fragment_clip_->Clone();
- if (clip_path_clip_)
- cloned->clip_path_clip_ = clip_path_clip_->Clone();
- if (mask_clip_)
- cloned->mask_clip_ = mask_clip_->Clone();
- if (css_clip_)
- cloned->css_clip_ = css_clip_->Clone();
- if (css_clip_fixed_position_)
- cloned->css_clip_fixed_position_ = css_clip_fixed_position_->Clone();
- if (overflow_controls_clip_)
- cloned->overflow_controls_clip_ = overflow_controls_clip_->Clone();
- if (inner_border_radius_clip_)
- cloned->inner_border_radius_clip_ = inner_border_radius_clip_->Clone();
- if (overflow_clip_)
- cloned->overflow_clip_ = overflow_clip_->Clone();
- if (perspective_)
- cloned->perspective_ = perspective_->Clone();
- if (svg_local_to_border_box_transform_) {
- cloned->svg_local_to_border_box_transform_ =
- svg_local_to_border_box_transform_->Clone();
- }
- if (scroll_)
- cloned->scroll_ = scroll_->Clone();
- if (scroll_translation_)
- cloned->scroll_translation_ = scroll_translation_->Clone();
- return cloned;
+ // Used by FindPropertiesNeedingUpdate.h for verifying state doesn't change.
+ void SetImmutable() const { is_immutable_ = true; }
+ bool IsImmutable() const { return is_immutable_; }
+ void SetMutable() const { is_immutable_ = false; }
+
+ void Validate() {
+ DCHECK(!ScrollTranslation() || !ReplacedContentTransform())
+ << "Replaced elements don't scroll so there should never be both a "
+ "scroll translation and a replaced content transform.";
}
#endif
@@ -379,29 +230,9 @@ class CORE_EXPORT ObjectPaintProperties {
return UpdateResult::kNewNodeCreated;
}
- // ATTENTION! Make sure to keep FindPropertiesNeedingUpdate.h in sync when
- // new properites are added!
- scoped_refptr<TransformPaintPropertyNode> paint_offset_translation_;
- scoped_refptr<TransformPaintPropertyNode> transform_;
- scoped_refptr<EffectPaintPropertyNode> effect_;
- scoped_refptr<EffectPaintPropertyNode> filter_;
- scoped_refptr<EffectPaintPropertyNode> vertical_scrollbar_effect_;
- scoped_refptr<EffectPaintPropertyNode> horizontal_scrollbar_effect_;
- scoped_refptr<EffectPaintPropertyNode> mask_;
- scoped_refptr<EffectPaintPropertyNode> clip_path_;
- scoped_refptr<ClipPaintPropertyNode> fragment_clip_;
- scoped_refptr<ClipPaintPropertyNode> clip_path_clip_;
- scoped_refptr<ClipPaintPropertyNode> mask_clip_;
- scoped_refptr<ClipPaintPropertyNode> css_clip_;
- scoped_refptr<ClipPaintPropertyNode> css_clip_fixed_position_;
- scoped_refptr<ClipPaintPropertyNode> overflow_controls_clip_;
- scoped_refptr<ClipPaintPropertyNode> inner_border_radius_clip_;
- scoped_refptr<ClipPaintPropertyNode> overflow_clip_;
- scoped_refptr<TransformPaintPropertyNode> perspective_;
- // TODO(pdr): Only LayoutSVGRoot needs this and it should be moved there.
- scoped_refptr<TransformPaintPropertyNode> svg_local_to_border_box_transform_;
- scoped_refptr<ScrollPaintPropertyNode> scroll_;
- scoped_refptr<TransformPaintPropertyNode> scroll_translation_;
+ // This is used in DCHECKs only, but is not guarded by DCHECK_IS_ON() because
+ // we can't have a similar guard in a macro definition.
+ mutable bool is_immutable_ = false;
DISALLOW_COPY_AND_ASSIGN(ObjectPaintProperties);
};
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 f5ac9b23465..9445e34562c 100644
--- a/chromium/third_party/blink/renderer/core/paint/object_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/object_painter.cc
@@ -113,7 +113,7 @@ void ObjectPainter::AddPDFURLRectIfNeeded(const PaintInfo& paint_info,
}
void ObjectPainter::PaintAllPhasesAtomically(const PaintInfo& paint_info) {
- // Pass PaintPhaseSelection and PaintPhaseTextClip to the descendants so that
+ // Pass kSelection 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 ||
diff --git a/chromium/third_party/blink/renderer/core/paint/object_painter.h b/chromium/third_party/blink/renderer/core/paint/object_painter.h
index be00a3352c5..351c2e5a951 100644
--- a/chromium/third_party/blink/renderer/core/paint/object_painter.h
+++ b/chromium/third_party/blink/renderer/core/paint/object_painter.h
@@ -39,9 +39,8 @@ class ObjectPainter : public ObjectPainterBase {
//
// It is expected that the caller will call this function independent of the
// value of paintInfo.phase, and this function will do atomic paint (for
- // PaintPhaseForeground), normal paint (for PaintPhaseSelection and
- // PaintPhaseTextClip) or nothing (other paint phases) according to
- // paintInfo.phase.
+ // kForeground), normal paint (for kSelection and kTextClip) or nothing (other
+ // paint phases) according to paintInfo.phase.
void PaintAllPhasesAtomically(const PaintInfo&);
const LayoutObject& layout_object_;
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 b4e59a12038..e3e42047e41 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
@@ -645,7 +645,8 @@ TEST_P(PaintAndRasterInvalidationTest, RecalcOverflowInvalidatesBackground) {
ScrollableArea* scrollable_area = GetDocument().View()->LayoutViewport();
ASSERT_EQ(scrollable_area->MaximumScrollOffset().Height(), 0);
- EXPECT_FALSE(GetDocument().GetLayoutView()->MayNeedPaintInvalidation());
+ EXPECT_FALSE(
+ GetDocument().GetLayoutView()->ShouldCheckForPaintInvalidation());
Element* container = GetDocument().getElementById("container");
container->setAttribute(HTMLNames::styleAttr,
@@ -653,7 +654,7 @@ TEST_P(PaintAndRasterInvalidationTest, RecalcOverflowInvalidatesBackground) {
GetDocument().UpdateStyleAndLayoutTree();
EXPECT_EQ(scrollable_area->MaximumScrollOffset().Height(), 1000);
- EXPECT_TRUE(GetDocument().GetLayoutView()->MayNeedPaintInvalidation());
+ EXPECT_TRUE(GetDocument().GetLayoutView()->ShouldCheckForPaintInvalidation());
}
TEST_P(PaintAndRasterInvalidationTest,
@@ -696,17 +697,26 @@ TEST_P(PaintAndRasterInvalidationTest, DelayedFullPaintInvalidation) {
auto* target = GetLayoutObjectByElementId("target");
target->SetShouldDoFullPaintInvalidationWithoutGeometryChange(
- PaintInvalidationReason::kDelayedFull);
- EXPECT_EQ(PaintInvalidationReason::kDelayedFull,
+ PaintInvalidationReason::kForTesting);
+ target->SetShouldDelayFullPaintInvalidation();
+ EXPECT_FALSE(target->ShouldDoFullPaintInvalidation());
+ EXPECT_TRUE(target->ShouldDelayFullPaintInvalidation());
+ EXPECT_EQ(PaintInvalidationReason::kForTesting,
target->FullPaintInvalidationReason());
EXPECT_FALSE(target->NeedsPaintOffsetAndVisualRectUpdate());
+ EXPECT_TRUE(target->ShouldCheckForPaintInvalidation());
+ EXPECT_TRUE(target->Parent()->ShouldCheckForPaintInvalidation());
GetDocument().View()->SetTracksPaintInvalidations(true);
GetDocument().View()->UpdateAllLifecyclePhases();
EXPECT_FALSE(GetRasterInvalidationTracking()->HasInvalidations());
- EXPECT_EQ(PaintInvalidationReason::kDelayedFull,
+ EXPECT_FALSE(target->ShouldDoFullPaintInvalidation());
+ EXPECT_TRUE(target->ShouldDelayFullPaintInvalidation());
+ EXPECT_EQ(PaintInvalidationReason::kForTesting,
target->FullPaintInvalidationReason());
EXPECT_FALSE(target->NeedsPaintOffsetAndVisualRectUpdate());
+ EXPECT_TRUE(target->ShouldCheckForPaintInvalidation());
+ EXPECT_TRUE(target->Parent()->ShouldCheckForPaintInvalidation());
GetDocument().View()->SetTracksPaintInvalidations(false);
GetDocument().View()->SetTracksPaintInvalidations(true);
@@ -716,9 +726,12 @@ TEST_P(PaintAndRasterInvalidationTest, DelayedFullPaintInvalidation) {
EXPECT_THAT(GetRasterInvalidationTracking()->Invalidations(),
UnorderedElementsAre(RasterInvalidationInfo{
target, target->DebugName(), IntRect(0, 4000, 100, 100),
- PaintInvalidationReason::kFull}));
+ PaintInvalidationReason::kForTesting}));
EXPECT_EQ(PaintInvalidationReason::kNone,
target->FullPaintInvalidationReason());
+ EXPECT_FALSE(target->ShouldDelayFullPaintInvalidation());
+ EXPECT_FALSE(target->ShouldCheckForPaintInvalidation());
+ EXPECT_FALSE(target->Parent()->ShouldCheckForPaintInvalidation());
EXPECT_FALSE(target->NeedsPaintOffsetAndVisualRectUpdate());
GetDocument().View()->SetTracksPaintInvalidations(false);
};
@@ -748,14 +761,6 @@ TEST_P(PaintAndRasterInvalidationTest, SVGHiddenContainer) {
GetDocument().View()->SetTracksPaintInvalidations(true);
ToElement(mask_rect->GetNode())->setAttribute("x", "20");
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
-
- EXPECT_EQ(PaintInvalidationReason::kFull,
- real_rect->GetPaintInvalidationReason());
- // mask_rect is not cached and validated by any PaintController.
- EXPECT_EQ(PaintInvalidationReason::kJustCreated,
- mask_rect->GetPaintInvalidationReason());
-
GetDocument().View()->UpdateAllLifecyclePhases();
EXPECT_EQ(LayoutRect(), mask_rect->FirstFragment().VisualRect());
@@ -854,6 +859,62 @@ TEST_P(PaintAndRasterInvalidationTest, PaintPropertyChange) {
GetDocument().View()->SetTracksPaintInvalidations(false);
}
+TEST_P(PaintAndRasterInvalidationTest, ResizeContainerOfFixedSizeSVG) {
+ SetBodyInnerHTML(R"HTML(
+ <div id="target" style="width: 100px; height: 100px">
+ <svg viewBox="0 0 200 200" width="100" height="100">
+ <rect id="rect" width="100%" height="100%"/>
+ </svg>
+ </div>
+ )HTML");
+
+ Element* target = GetDocument().getElementById("target");
+ GetDocument().View()->SetTracksPaintInvalidations(true);
+ target->setAttribute(HTMLNames::styleAttr, "width: 200px; height: 200px");
+ GetDocument().View()->UpdateAllLifecyclePhases();
+
+ // No raster invalidations because the resized-div doesn't paint anything by
+ // itself, and the svg is fixed sized.
+ EXPECT_THAT(GetRasterInvalidationTracking()->Invalidations(),
+ UnorderedElementsAre());
+ // At least we don't invalidate paint of the SVG rect.
+ for (const auto& paint_invalidation :
+ *GetDocument().View()->TrackedObjectPaintInvalidations()) {
+ EXPECT_NE(GetLayoutObjectByElementId("rect")->DebugName(),
+ paint_invalidation.name);
+ }
+
+ GetDocument().View()->SetTracksPaintInvalidations(false);
+}
+
+TEST_P(PaintAndRasterInvalidationTest, ScrollingInvalidatesStickyOffset) {
+ SetBodyInnerHTML(R"HTML(
+ <div id="scroller" style="width:300px; height:200px; overflow:scroll">
+ <div id="sticky" style="position:sticky; top:50px;
+ width:50px; height:100px; background:red;">
+ <div id="inner" style="width:100px; height:50px; background:red;">
+ </div>
+ </div>
+ <div style="height:1000px;"></div>
+ </div>
+ )HTML");
+
+ Element* scroller = GetDocument().getElementById("scroller");
+ scroller->setScrollTop(100);
+
+ const auto* sticky = GetLayoutObjectByElementId("sticky");
+ EXPECT_TRUE(sticky->ShouldCheckForPaintInvalidation());
+ EXPECT_EQ(LayoutPoint(0, 50), sticky->FirstFragment().PaintOffset());
+ const auto* inner = GetLayoutObjectByElementId("inner");
+ EXPECT_EQ(LayoutPoint(0, 50), inner->FirstFragment().PaintOffset());
+
+ GetDocument().View()->UpdateAllLifecyclePhases();
+
+ EXPECT_FALSE(sticky->ShouldCheckForPaintInvalidation());
+ EXPECT_EQ(LayoutPoint(0, 150), sticky->FirstFragment().PaintOffset());
+ EXPECT_EQ(LayoutPoint(0, 150), inner->FirstFragment().PaintOffset());
+}
+
class PaintInvalidatorTestClient : public EmptyChromeClient {
public:
void InvalidateRect(const IntRect&) override {
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 7de9c6fa26c..f97a7e13108 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
@@ -98,7 +98,12 @@ TEST_P(PaintControllerPaintTest, ChunkIdClientCacheFlag) {
// Verify that the background does not scroll.
const PaintChunk& background_chunk = RootPaintController().PaintChunks()[0];
auto* transform = background_chunk.properties.Transform();
- EXPECT_EQ(nullptr, transform->ScrollNode());
+ // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // scrolling.
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ EXPECT_FALSE(transform->ScrollNode());
+ else
+ EXPECT_TRUE(transform->ScrollNode());
const EffectPaintPropertyNode* effect_node =
div.FirstFragment().PaintProperties()->Effect();
diff --git a/chromium/third_party/blink/renderer/core/paint/adjust_paint_offset_scope.cc b/chromium/third_party/blink/renderer/core/paint/paint_info_with_offset.cc
index e0f8049d30d..f2586bd0952 100644
--- a/chromium/third_party/blink/renderer/core/paint/adjust_paint_offset_scope.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_info_with_offset.cc
@@ -2,11 +2,11 @@
// Use 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/adjust_paint_offset_scope.h"
+#include "third_party/blink/renderer/core/paint/paint_info_with_offset.h"
namespace blink {
-void AdjustPaintOffsetScope::AdjustForPaintOffsetTranslation(
+void PaintInfoWithOffset::AdjustForPaintOffsetTranslation(
const LayoutObject& object,
const TransformPaintPropertyNode* paint_offset_translation) {
if (input_paint_info_.context.InDrawingRecorder()) {
@@ -32,7 +32,7 @@ void AdjustPaintOffsetScope::AdjustForPaintOffsetTranslation(
paint_offset_translation->Matrix().ToAffineTransform());
}
-void AdjustPaintOffsetScope::FinishPaintOffsetTranslationAsDrawing() {
+void PaintInfoWithOffset::FinishPaintOffsetTranslationAsDrawing() {
// This scope should not interlace with scopes of DrawingRecorders.
DCHECK(paint_offset_translation_as_drawing_);
DCHECK(input_paint_info_.context.InDrawingRecorder());
diff --git a/chromium/third_party/blink/renderer/core/paint/adjust_paint_offset_scope.h b/chromium/third_party/blink/renderer/core/paint/paint_info_with_offset.h
index b698402e038..bd8a00b261a 100644
--- a/chromium/third_party/blink/renderer/core/paint/adjust_paint_offset_scope.h
+++ b/chromium/third_party/blink/renderer/core/paint/paint_info_with_offset.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_PAINT_ADJUST_PAINT_OFFSET_SCOPE_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_ADJUST_PAINT_OFFSET_SCOPE_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_PAINT_INFO_WITH_OFFSET_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_PAINT_INFO_WITH_OFFSET_H_
#include "third_party/blink/renderer/core/layout/layout_box_model_object.h"
#include "third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h"
@@ -14,15 +14,14 @@ namespace blink {
// Adjusts cull rect of the input PaintInfo and finds the paint offset for a
// LayoutObject or an NGPaintFragment before painting. Normally a
-// Paint(const PaintInfo&) method creates an AdjustPaintOffsetScope and holds it
+// Paint(const PaintInfo&) method creates an PaintInfoWithOffset and holds it
// in the stack, and passes it to other PaintXXX() methods that paint different
// parts of the object.
-class AdjustPaintOffsetScope {
+class PaintInfoWithOffset {
STACK_ALLOCATED();
public:
- AdjustPaintOffsetScope(const LayoutObject& object,
- const PaintInfo& paint_info)
+ PaintInfoWithOffset(const LayoutObject& object, const PaintInfo& paint_info)
: fragment_to_paint_(paint_info.FragmentToPaint(object)),
input_paint_info_(paint_info) {
if (!fragment_to_paint_) {
@@ -41,11 +40,11 @@ class AdjustPaintOffsetScope {
}
}
- AdjustPaintOffsetScope(const NGPaintFragment& fragment,
- const PaintInfo& paint_info)
- : AdjustPaintOffsetScope(*fragment.GetLayoutObject(), paint_info) {}
+ PaintInfoWithOffset(const NGPaintFragment& fragment,
+ const PaintInfo& paint_info)
+ : PaintInfoWithOffset(*fragment.GetLayoutObject(), paint_info) {}
- ~AdjustPaintOffsetScope() {
+ ~PaintInfoWithOffset() {
if (paint_offset_translation_as_drawing_)
FinishPaintOffsetTranslationAsDrawing();
}
@@ -70,6 +69,13 @@ class AdjustPaintOffsetScope {
const FragmentData* FragmentToPaint() const { return fragment_to_paint_; }
+ bool LocalRectIntersectsCullRect(const LayoutRect& local_rect) const {
+ LayoutRect rect_in_paint_info_space = local_rect;
+ rect_in_paint_info_space.MoveBy(PaintOffset());
+ return GetPaintInfo().GetCullRect().IntersectsCullRect(
+ rect_in_paint_info_space);
+ }
+
private:
void AdjustForPaintOffsetTranslation(
const LayoutObject&,
@@ -86,4 +92,4 @@ class AdjustPaintOffsetScope {
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_ADJUST_PAINT_OFFSET_SCOPE_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_PAINT_INFO_WITH_OFFSET_H_
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 5ac372b76b0..29de612ed87 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_invalidator.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_invalidator.cc
@@ -409,7 +409,7 @@ static void InvalidateChromeClient(
auto* frame_view = paint_invalidation_container.GetFrameView();
DCHECK(!frame_view->GetFrame().OwnerLayoutObject());
- if (auto* client = ToChromeClient(frame_view->GetChromeClient())) {
+ if (auto* client = frame_view->GetChromeClient()) {
client->InvalidateRect(IntRect(IntPoint(), frame_view->Size()));
}
}
@@ -501,27 +501,22 @@ void PaintInvalidator::InvalidatePaint(
UpdateVisualRect(object, *fragment_data, context);
}
- PaintInvalidationReason reason = object.InvalidatePaint(context);
- switch (reason) {
- case PaintInvalidationReason::kDelayedFull:
- pending_delayed_paint_invalidations_.push_back(&object);
- break;
- case PaintInvalidationReason::kSubtree:
- context.subtree_flags |=
- (PaintInvalidatorContext::kSubtreeFullInvalidation |
- PaintInvalidatorContext::
- kSubtreeFullInvalidationForStackedContents);
- break;
- case PaintInvalidationReason::kSVGResource:
- context.subtree_flags |=
- PaintInvalidatorContext::kSubtreeSVGResourceChange;
- break;
- default:
- break;
- }
+ object.InvalidatePaint(context);
+ }
+
+ auto reason = static_cast<const DisplayItemClient&>(object)
+ .GetPaintInvalidationReason();
+ if (object.ShouldDelayFullPaintInvalidation() &&
+ !IsFullPaintInvalidationReason(reason))
+ pending_delayed_paint_invalidations_.push_back(&object);
+
+ if (object.SubtreeShouldDoFullPaintInvalidation()) {
+ context.subtree_flags |=
+ PaintInvalidatorContext::kSubtreeFullInvalidation |
+ PaintInvalidatorContext::kSubtreeFullInvalidationForStackedContents;
}
- if (object.MayNeedPaintInvalidationSubtree()) {
+ if (object.SubtreeShouldCheckForPaintInvalidation()) {
context.subtree_flags |=
PaintInvalidatorContext::kSubtreeInvalidationChecking;
}
@@ -547,16 +542,13 @@ void PaintInvalidator::InvalidatePaint(
// TODO(wangxianzhu): Do we need this for SPv2?
if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled() &&
!context.paint_invalidation_container->IsPaintInvalidationContainer() &&
- object.GetPaintInvalidationReason() != PaintInvalidationReason::kNone)
+ reason != PaintInvalidationReason::kNone)
InvalidateChromeClient(*context.paint_invalidation_container);
}
void PaintInvalidator::ProcessPendingDelayedPaintInvalidations() {
- for (auto* target : pending_delayed_paint_invalidations_) {
- target->GetMutableForPainting()
- .SetShouldDoFullPaintInvalidationWithoutGeometryChange(
- PaintInvalidationReason::kDelayedFull);
- }
+ for (auto* target : pending_delayed_paint_invalidations_)
+ target->GetMutableForPainting().SetShouldDelayFullPaintInvalidation();
}
} // namespace blink
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 7cb3e82dde0..d6e96c5b29d 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_invalidator.h
+++ b/chromium/third_party/blink/renderer/core/paint/paint_invalidator.h
@@ -8,6 +8,7 @@
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/paint/paint_property_tree_builder.h"
#include "third_party/blink/renderer/platform/geometry/layout_rect.h"
+#include "third_party/blink/renderer/platform/graphics/paint_invalidation_reason.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
@@ -58,8 +59,7 @@ struct CORE_EXPORT PaintInvalidatorContext {
return subtree_flags &
(kSubtreeInvalidationChecking | kSubtreeVisualRectUpdate |
kSubtreeFullInvalidation |
- kSubtreeFullInvalidationForStackedContents |
- kSubtreeSVGResourceChange);
+ kSubtreeFullInvalidationForStackedContents);
}
const PaintInvalidatorContext* ParentContext() const {
@@ -78,10 +78,9 @@ struct CORE_EXPORT PaintInvalidatorContext {
kSubtreeVisualRectUpdate = 1 << 1,
kSubtreeFullInvalidation = 1 << 2,
kSubtreeFullInvalidationForStackedContents = 1 << 3,
- kSubtreeSVGResourceChange = 1 << 4,
// For repeated objects inside multicolumn.
- kSubtreeSlowPathRect = 1 << 5,
+ kSubtreeSlowPathRect = 1 << 4,
// When this flag is set, no paint or raster invalidation will be issued
// for the subtree.
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 c3c2671146b..339a2705049 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_layer.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_layer.cc
@@ -68,7 +68,6 @@
#include "third_party/blink/renderer/core/layout/svg/layout_svg_resource_clipper.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_root.h"
#include "third_party/blink/renderer/core/page/page.h"
-#include "third_party/blink/renderer/core/page/scrolling/root_scroller_util.h"
#include "third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h"
#include "third_party/blink/renderer/core/page/scrolling/sticky_position_scrolling_constraints.h"
#include "third_party/blink/renderer/core/paint/box_reflection_utils.h"
@@ -152,7 +151,6 @@ PaintLayer::PaintLayer(LayoutBoxModelObject& layout_object)
needs_ancestor_dependent_compositing_inputs_update_(true),
child_needs_compositing_inputs_update_(true),
has_compositing_descendant_(false),
- is_all_scrolling_content_composited_(false),
should_isolate_composited_descendants_(false),
lost_grouped_mapping_(false),
needs_repaint_(false),
@@ -326,13 +324,15 @@ void PaintLayer::UpdateLayerPositionsAfterLayout() {
}
void PaintLayer::UpdateLayerPositionRecursive(
- UpdateLayerPositionBehavior behavior) {
+ UpdateLayerPositionBehavior behavior,
+ bool dirty_compositing_if_needed) {
+ LayoutPoint old_location = location_;
switch (behavior) {
case AllLayers:
UpdateLayerPosition();
break;
case OnlyStickyLayers:
- if (GetLayoutObject().Style()->HasStickyConstrainedPosition())
+ if (GetLayoutObject().StyleRef().HasStickyConstrainedPosition())
UpdateLayerPosition();
if (PaintLayerScrollableArea* scroller = GetScrollableArea()) {
if (!scroller->HasStickyDescendants())
@@ -343,24 +343,21 @@ void PaintLayer::UpdateLayerPositionRecursive(
NOTREACHED();
}
+ if (dirty_compositing_if_needed && location_ != old_location)
+ SetNeedsCompositingInputsUpdate();
+
for (PaintLayer* child = FirstChild(); child; child = child->NextSibling())
- child->UpdateLayerPositionRecursive(behavior);
+ child->UpdateLayerPositionRecursive(behavior, dirty_compositing_if_needed);
}
bool PaintLayer::SticksToScroller() const {
- if (GetLayoutObject().Style()->GetPosition() != EPosition::kSticky)
+ if (!GetLayoutObject().StyleRef().HasStickyConstrainedPosition())
return false;
- if (auto* ancestor_scrollable_area =
- AncestorOverflowLayer()->GetScrollableArea()) {
- return ancestor_scrollable_area->GetStickyConstraintsMap()
- .at(const_cast<PaintLayer*>(this))
- .GetAnchorEdges();
- }
- return false;
+ return AncestorOverflowLayer()->GetScrollableArea();
}
bool PaintLayer::FixedToViewport() const {
- if (GetLayoutObject().Style()->GetPosition() != EPosition::kFixed)
+ if (GetLayoutObject().StyleRef().GetPosition() != EPosition::kFixed)
return false;
// TODO(pdr): This approach of calculating the nearest scroll node is O(n).
@@ -422,12 +419,14 @@ void PaintLayer::UpdateLayerPositionsAfterOverflowScroll() {
// offset is not included in clip rects. Therefore, we do not need to clear
// them when that PaintLayer is scrolled. We also don't need to update layer
// positions, because they also do not depend on the root's scroll offset.
- if (GetScrollableArea()->HasStickyDescendants())
- UpdateLayerPositionRecursive(OnlyStickyLayers);
+ if (GetScrollableArea()->HasStickyDescendants()) {
+ UpdateLayerPositionRecursive(OnlyStickyLayers,
+ /* dirty_compositing */ false);
+ }
return;
}
ClearClipRects();
- UpdateLayerPositionRecursive(AllLayers);
+ UpdateLayerPositionRecursive(AllLayers, /* dirty_compositing */ false);
}
void PaintLayer::UpdateTransformationMatrix() {
@@ -435,7 +434,7 @@ void PaintLayer::UpdateTransformationMatrix() {
LayoutBox* box = GetLayoutBox();
DCHECK(box);
transform->MakeIdentity();
- box->Style()->ApplyTransform(
+ box->StyleRef().ApplyTransform(
*transform, box->Size(), ComputedStyle::kIncludeTransformOrigin,
ComputedStyle::kIncludeMotionPath,
ComputedStyle::kIncludeIndependentTransformProperties);
@@ -705,34 +704,6 @@ void PaintLayer::MarkAncestorChainForDescendantDependentFlagsUpdate() {
}
}
-// FIXME: this is quite brute-force. We could be more efficient if we were to
-// track state and update it as appropriate as changes are made in the layout
-// tree.
-void PaintLayer::UpdateScrollingStateAfterCompositingChange() {
- TRACE_EVENT0("blink",
- "PaintLayer::updateScrollingStateAfterCompositingChange");
- is_all_scrolling_content_composited_ = true;
- for (LayoutObject* r = GetLayoutObject().SlowFirstChild(); r;
- r = r->NextSibling()) {
- if (!r->HasLayer()) {
- is_all_scrolling_content_composited_ = false;
- return;
- }
- }
-
- for (PaintLayer* child = FirstChild(); child; child = child->NextSibling()) {
- if (child->GetCompositingState() == kNotComposited) {
- is_all_scrolling_content_composited_ = false;
- return;
- } else if (!child->GetLayoutObject().StyleRef().IsStackingContext()) {
- // If the child is composited, but not a stacking context, it may paint
- // negative z-index descendants into an ancestor's GraphicsLayer.
- is_all_scrolling_content_composited_ = false;
- return;
- }
- }
-}
-
void PaintLayer::UpdateDescendantDependentFlags() {
if (needs_descendant_dependent_flags_update_) {
bool old_has_non_isolated_descendant_with_blend_mode =
@@ -805,14 +776,14 @@ void PaintLayer::UpdateDescendantDependentFlags() {
}
bool previously_has_visible_content = has_visible_content_;
- if (GetLayoutObject().Style()->Visibility() == EVisibility::kVisible) {
+ if (GetLayoutObject().StyleRef().Visibility() == EVisibility::kVisible) {
has_visible_content_ = true;
} else {
// layer may be hidden but still have some visible content, check for this
has_visible_content_ = false;
LayoutObject* r = GetLayoutObject().SlowFirstChild();
while (r) {
- if (r->Style()->Visibility() == EVisibility::kVisible &&
+ if (r->StyleRef().Visibility() == EVisibility::kVisible &&
(!r->HasLayer() || !r->EnclosingLayer()->IsSelfPaintingLayer())) {
has_visible_content_ = true;
break;
@@ -837,11 +808,11 @@ void PaintLayer::UpdateDescendantDependentFlags() {
if (HasVisibleContent() != previously_has_visible_content) {
SetNeedsCompositingInputsUpdateInternal();
- // We need to tell m_layoutObject to recheck its rect because we
+ // We need to tell layout_object_ to recheck its rect because we
// pretend that invisible LayoutObjects have 0x0 rects. Changing
// visibility therefore changes our rect and we need to visit
- // this LayoutObject during the invalidateTreeIfNeeded walk.
- layout_object_.SetMayNeedPaintInvalidation();
+ // this LayoutObject during the PrePaintTreeWalk.
+ layout_object_.SetShouldCheckForPaintInvalidation();
}
Update3DTransformedDescendantStatus();
@@ -917,7 +888,7 @@ void PaintLayer::UpdateLayerPosition() {
if (GetLayoutObject().IsOutOfFlowPositioned() &&
container.IsLayoutInline() &&
container.CanContainOutOfFlowPositionedElement(
- GetLayoutObject().Style()->GetPosition())) {
+ GetLayoutObject().StyleRef().GetPosition())) {
// Adjust offset for absolute under in-flow positioned inline.
LayoutSize offset =
ToLayoutInline(container).OffsetForInFlowPositionedInline(
@@ -955,6 +926,9 @@ bool PaintLayer::UpdateSize() {
} else if (LayoutBox* box = GetLayoutBox()) {
size_ = box->Size();
}
+ if (old_size != size_)
+ SetNeedsCompositingInputsUpdate();
+
return old_size != size_;
}
@@ -1423,10 +1397,10 @@ PaintLayer* PaintLayer::RemoveChild(PaintLayer* old_child) {
}
// Dirty the z-order list in which we are contained.
PaintLayerStackingNode::DirtyStackingContextZOrderLists(old_child);
- MarkAncestorChainForDescendantDependentFlagsUpdate();
+ SetNeedsCompositingInputsUpdate();
}
- if (GetLayoutObject().Style()->Visibility() != EVisibility::kVisible)
+ if (GetLayoutObject().StyleRef().Visibility() != EVisibility::kVisible)
DirtyVisibleContentStatus();
old_child->SetPreviousSibling(nullptr);
@@ -1478,8 +1452,7 @@ void PaintLayer::RemoveOnlyThisLayerAfterStyleChange(
// can't see this layer (which has been removed) so won't do this for us.
ObjectPaintInvalidator(GetLayoutObject())
.InvalidatePaintIncludingNonCompositingDescendants();
- GetLayoutObject()
- .SetShouldDoFullPaintInvalidationIncludingNonCompositingDescendants();
+ GetLayoutObject().SetSubtreeShouldDoFullPaintInvalidation();
did_set_paint_invalidation = true;
}
}
@@ -1691,7 +1664,7 @@ bool PaintLayer::HasOverflowControls() const {
return scrollable_area_ &&
(scrollable_area_->HasScrollbar() ||
scrollable_area_->ScrollCorner() ||
- GetLayoutObject().Style()->Resize() != EResize::kNone);
+ GetLayoutObject().StyleRef().Resize() != EResize::kNone);
}
void PaintLayer::AppendSingleFragmentIgnoringPagination(
@@ -1704,7 +1677,8 @@ void PaintLayer::AppendSingleFragmentIgnoringPagination(
const LayoutSize& sub_pixel_accumulation) const {
PaintLayerFragment fragment;
ClipRectsContext clip_rects_context(
- root_layer, kUncachedClipRects, overlay_scrollbar_clip_behavior,
+ root_layer, &root_layer->GetLayoutObject().FirstFragment(),
+ kUncachedClipRects, overlay_scrollbar_clip_behavior,
respect_overflow_clip, sub_pixel_accumulation);
Clipper(kUseGeometryMapper)
.CalculateRects(clip_rects_context, &GetLayoutObject().FirstFragment(),
@@ -1742,9 +1716,15 @@ void PaintLayer::CollectFragments(
const LayoutPoint* offset_from_root,
const LayoutSize& sub_pixel_accumulation) const {
PaintLayerFragment fragment;
- ClipRectsContext clip_rects_context(
- root_layer, kUncachedClipRects, overlay_scrollbar_clip_behavior,
- respect_overflow_clip, sub_pixel_accumulation);
+
+ // If |root_layer| is inside the same pagination container as |this|, and
+ // there is no compositing boundary inside pagination (this is what
+ // ShouldFragmentCompositedBounds() checks), then try to match
+ // fragments from |root_layer| to |this|, so that any
+ // fragment clip for |root_layer|'s fragment matches |this|'s.
+ bool should_match_fragments = root_layer->EnclosingPaginationLayer() &&
+ root_layer->EnclosingPaginationLayer() == EnclosingPaginationLayer() &&
+ ShouldFragmentCompositedBounds();
// The inherited offset_from_root does not include any pagination offsets.
// In the presence of fragmentation, we cannot use it. Note that we may also
@@ -1755,6 +1735,29 @@ void PaintLayer::CollectFragments(
!GetLayoutObject().FirstFragment().NextFragment();
for (auto* fragment_data = &GetLayoutObject().FirstFragment(); fragment_data;
fragment_data = fragment_data->NextFragment()) {
+ const FragmentData* root_fragment =
+ &root_layer->GetLayoutObject().FirstFragment();
+ if (should_match_fragments) {
+ for (root_fragment = &root_layer->GetLayoutObject().FirstFragment();
+ root_fragment; root_fragment = root_fragment->NextFragment()) {
+ if (root_fragment->LogicalTopInFlowThread() ==
+ fragment_data->LogicalTopInFlowThread())
+ break;
+ }
+ }
+
+ bool cant_find_fragment = !root_fragment;
+ if (cant_find_fragment) {
+ // Fall back to the first fragment, in order to have
+ // PaintLayerClipper at least compute |fragment.layer_bounds|.
+ root_fragment = &root_layer->GetLayoutObject().FirstFragment();
+ }
+
+ ClipRectsContext clip_rects_context(
+ root_layer, root_fragment, kUncachedClipRects,
+ overlay_scrollbar_clip_behavior, respect_overflow_clip,
+ sub_pixel_accumulation);
+
Clipper(kUseGeometryMapper)
.CalculateRects(
clip_rects_context, fragment_data, dirty_rect,
@@ -1762,6 +1765,13 @@ void PaintLayer::CollectFragments(
fragment.foreground_rect,
offset_from_root_can_be_used ? offset_from_root : nullptr);
+ if (cant_find_fragment) {
+ // If we couldn't find a matching fragment when |should_match_fragments|
+ // was true, then fall back to no clip.
+ fragment.background_rect.Reset();
+ fragment.foreground_rect.Reset();
+ }
+
fragment.fragment_data = fragment_data;
fragment.pagination_offset = fragment_data->PaginationOffset();
@@ -1965,6 +1975,12 @@ PaintLayer* PaintLayer::HitTestLayer(
if (!IsSelfPaintingLayer() && !HasSelfPaintingLayerDescendant())
return nullptr;
+ if ((result.GetHitTestRequest().GetType() &
+ HitTestRequest::kIgnoreZeroOpacityObjects) &&
+ !layout_object.HasNonZeroEffectiveOpacity()) {
+ return nullptr;
+ }
+
ShouldRespectOverflowClipType clip_behavior = kRespectOverflowClip;
if (result.GetHitTestRequest().IgnoreClipping())
clip_behavior = kIgnoreOverflowClip;
@@ -1988,9 +2004,10 @@ PaintLayer* PaintLayer::HitTestLayer(
ClipRect clip_rect;
Clipper(PaintLayer::kUseGeometryMapper)
.CalculateBackgroundClipRect(
- ClipRectsContext(root_layer, kUncachedClipRects,
- kExcludeOverlayScrollbarSizeForHitTesting,
- clip_behavior),
+ ClipRectsContext(
+ root_layer, &root_layer->GetLayoutObject().FirstFragment(),
+ kUncachedClipRects, kExcludeOverlayScrollbarSizeForHitTesting,
+ clip_behavior),
clip_rect);
// Go ahead and test the enclosing clip now.
if (!clip_rect.Intersects(recursion_data.location))
@@ -2090,8 +2107,8 @@ PaintLayer* PaintLayer::HitTestLayer(
candidate_layer = hit_layer;
}
- // Collect the fragments. This will compute the clip rectangles for each layer
- // fragment.
+ // Collect the fragments. This will compute the clip rectangles for each
+ // layer fragment.
base::Optional<PaintLayerFragments> layer_fragments;
LayoutPoint offset;
if (recursion_data.intersects_location) {
@@ -2171,7 +2188,7 @@ PaintLayer* PaintLayer::HitTestLayer(
inside_fragment_background_rect) &&
IsHitCandidate(this, false, z_offset_for_contents_ptr,
unflattened_transform_state.get())) {
- if (recursion_data.original_location.IsRectBasedTest())
+ if (result.GetHitTestRequest().ListBased())
result.Append(temp_result);
else
result = temp_result;
@@ -2294,7 +2311,7 @@ bool PaintLayer::HitTestContents(HitTestResult& result,
if (!GetLayoutObject().HitTestAllPhases(result, hit_test_location,
fragment_offset, hit_test_filter)) {
// It's wrong to set innerNode, but then claim that you didn't hit anything,
- // unless it is a rect-based test.
+ // unless it is a list-based test.
DCHECK(!result.InnerNode() || (result.GetHitTestRequest().ListBased() &&
result.ListBasedTestResult().size()));
return false;
@@ -2395,8 +2412,6 @@ PaintLayer* PaintLayer::HitTestChildren(
// If it is a list-based test, we can safely append the temporary result
// since it might had hit nodes but not necesserily had hitLayer set.
- DCHECK(!recursion_data.original_location.IsRectBasedTest() ||
- result.GetHitTestRequest().ListBased());
if (result.GetHitTestRequest().ListBased())
result.Append(temp_result);
@@ -2433,24 +2448,23 @@ bool PaintLayer::HitTestClippedOutByClipPath(
DCHECK(IsSelfPaintingLayer());
DCHECK(root_layer);
- LayoutRect reference_box(
- ClipPathClipper::LocalReferenceBox(GetLayoutObject()));
+ LayoutRect origin;
if (EnclosingPaginationLayer())
- ConvertFromFlowThreadToVisualBoundingBoxInAncestor(root_layer,
- reference_box);
+ ConvertFromFlowThreadToVisualBoundingBoxInAncestor(root_layer, origin);
else
- ConvertToLayerCoords(root_layer, reference_box);
+ ConvertToLayerCoords(root_layer, origin);
- FloatPoint point(hit_test_location.Point());
- FloatRect float_reference_box(reference_box);
+ FloatPoint point(hit_test_location.Point() - origin.Location());
+ FloatRect reference_box(
+ ClipPathClipper::LocalReferenceBox(GetLayoutObject()));
ClipPathOperation* clip_path_operation =
- GetLayoutObject().Style()->ClipPath();
+ GetLayoutObject().StyleRef().ClipPath();
DCHECK(clip_path_operation);
if (clip_path_operation->GetType() == ClipPathOperation::SHAPE) {
ShapeClipPathOperation* clip_path =
ToShapeClipPathOperation(clip_path_operation);
- return !clip_path->GetPath(float_reference_box).Contains(point);
+ return !clip_path->GetPath(reference_box).Contains(point);
}
DCHECK_EQ(clip_path_operation->GetType(), ClipPathOperation::REFERENCE);
SVGResource* resource =
@@ -2469,8 +2483,8 @@ bool PaintLayer::HitTestClippedOutByClipPath(
// not zoomed.
float inverse_zoom = 1 / GetLayoutObject().StyleRef().EffectiveZoom();
point.Scale(inverse_zoom, inverse_zoom);
- float_reference_box.Scale(inverse_zoom);
- return !clipper->HitTestClipContent(float_reference_box, point);
+ reference_box.Scale(inverse_zoom);
+ return !clipper->HitTestClipContent(reference_box, point);
}
bool PaintLayer::IntersectsDamageRect(
@@ -2500,7 +2514,7 @@ bool PaintLayer::IntersectsDamageRect(
LayoutRect PaintLayer::LogicalBoundingBox() const {
LayoutRect rect = GetLayoutObject().VisualOverflowRect();
- if (RootScrollerUtil::IsEffective(*this) || IsRootLayer()) {
+ if (GetLayoutObject().IsEffectiveRootScroller() || IsRootLayer()) {
rect.Unite(LayoutRect(rect.Location(),
GetLayoutObject().View()->ViewRect().Size()));
}
@@ -2621,7 +2635,7 @@ LayoutRect PaintLayer::BoundingBoxForCompositingInternal(
!HasVisibleDescendant())
return LayoutRect();
- if (RootScrollerUtil::IsEffective(*this) || IsRootLayer()) {
+ if (GetLayoutObject().IsEffectiveRootScroller() || IsRootLayer()) {
// In root layer scrolling mode, the main GraphicsLayer is the size of the
// layout viewport. In non-RLS mode, it is the union of the layout viewport
// and the document's layout overflow rect.
@@ -2732,10 +2746,6 @@ BackgroundPaintLocation PaintLayer::GetBackgroundPaintLocation(
else
location = GetLayoutObject().GetBackgroundPaintLocation(reasons);
}
- if (!IsRootLayer() && stacking_node_) {
- if (StackingNode()->HasNegativeZOrderList())
- location = kBackgroundPaintInGraphicsLayer;
- }
return location;
}
@@ -2838,7 +2848,7 @@ bool PaintLayer::CompositesWithTransform() const {
}
bool PaintLayer::CompositesWithOpacity() const {
- return OpacityAncestor() || GetLayoutObject().Style()->HasOpacity();
+ return OpacityAncestor() || GetLayoutObject().StyleRef().HasOpacity();
}
bool PaintLayer::BackgroundIsKnownToBeOpaqueInRect(
@@ -2849,14 +2859,14 @@ bool PaintLayer::BackgroundIsKnownToBeOpaqueInRect(
// We can't use hasVisibleContent(), because that will be true if our
// layoutObject is hidden, but some child is visible and that child doesn't
// cover the entire rect.
- if (GetLayoutObject().Style()->Visibility() != EVisibility::kVisible)
+ if (GetLayoutObject().StyleRef().Visibility() != EVisibility::kVisible)
return false;
if (GetLayoutObject().HasMask() || GetLayoutObject().HasClipPath())
return false;
if (PaintsWithFilters() &&
- GetLayoutObject().Style()->Filter().HasFilterThatAffectsOpacity())
+ GetLayoutObject().StyleRef().Filter().HasFilterThatAffectsOpacity())
return false;
// FIXME: Handle simple transforms.
@@ -2864,7 +2874,7 @@ bool PaintLayer::BackgroundIsKnownToBeOpaqueInRect(
return false;
if (!RuntimeEnabledFeatures::CompositeOpaqueFixedPositionEnabled() &&
- GetLayoutObject().Style()->GetPosition() == EPosition::kFixed &&
+ GetLayoutObject().StyleRef().GetPosition() == EPosition::kFixed &&
GetCompositingState() != kPaintsIntoOwnBacking)
return false;
@@ -2932,7 +2942,9 @@ void PaintLayer::UpdateSelfPaintingLayer() {
SetNeedsRepaint();
is_self_painting_layer_ = is_self_painting_layer;
self_painting_status_changed_ = true;
- SetNeedsRepaint();
+ // Self-painting change can change the compositing container chain;
+ // invalidate the new chain in addition to the old one.
+ MarkCompositingContainerChainForNeedsRepaint();
if (PaintLayer* parent = Parent()) {
parent->MarkAncestorChainForDescendantDependentFlagsUpdate();
@@ -2975,8 +2987,8 @@ bool PaintLayer::HasNonEmptyChildLayoutObjects() const {
}
bool PaintLayer::HasBoxDecorationsOrBackground() const {
- return GetLayoutObject().Style()->HasBoxDecorations() ||
- GetLayoutObject().Style()->HasBackground();
+ return GetLayoutObject().StyleRef().HasBoxDecorations() ||
+ GetLayoutObject().StyleRef().HasBackground();
}
bool PaintLayer::HasVisibleBoxDecorations() const {
@@ -3067,14 +3079,14 @@ bool PaintLayer::AttemptDirectCompositingUpdate(
// Layers even when the non-transparent Layers are already a
// stacking context.
if (diff.OpacityChanged() &&
- layout_object_.Style()->HasOpacity() != old_style->HasOpacity())
+ layout_object_.StyleRef().HasOpacity() != old_style->HasOpacity())
return false;
// Changes in pointer-events affect hit test visibility of the scrollable
// area and its |m_scrollsOverflow| value which determines if the layer
// requires composited scrolling or not.
if (scrollable_area_ &&
- layout_object_.Style()->PointerEvents() != old_style->PointerEvents())
+ layout_object_.StyleRef().PointerEvents() != old_style->PointerEvents())
return false;
UpdateTransform(old_style, GetLayoutObject().StyleRef());
@@ -3101,8 +3113,12 @@ bool PaintLayer::AttemptDirectCompositingUpdate(
void PaintLayer::StyleDidChange(StyleDifference diff,
const ComputedStyle* old_style) {
UpdateScrollableArea();
- if (AttemptDirectCompositingUpdate(diff, old_style))
+
+ if (AttemptDirectCompositingUpdate(diff, old_style)) {
+ if (diff.HasDifference())
+ GetLayoutObject().SetNeedsPaintPropertyUpdate();
return;
+ }
if (PaintLayerStackingNode::StyleDidChange(this, old_style))
MarkAncestorChainForDescendantDependentFlagsUpdate();
@@ -3118,13 +3134,47 @@ void PaintLayer::StyleDidChange(StyleDifference diff,
const ComputedStyle& new_style = GetLayoutObject().StyleRef();
+ if (diff.CompositingReasonsChanged()) {
+ SetNeedsCompositingInputsUpdate();
+ } else {
+ // For querying stale GetCompositingState().
+ DisableCompositingQueryAsserts disable;
+
+ // Compositing inputs update is required when the PaintLayer is currently
+ // composited. This is because even style changes as simple as background
+ // color change, or pointer-events state change, can update compositing
+ // state.
+ if (old_style && GetCompositingState() == kPaintsIntoOwnBacking)
+ SetNeedsCompositingInputsUpdate();
+ }
+
+ if (diff.NeedsLayout())
+ SetNeedsCompositingInputsUpdate();
+
+ // A scroller that changes background color might become opaque or not
+ // opaque, which in turn affects whether it can be composited on low-DPI
+ // screens.
+ if (GetScrollableArea() && GetScrollableArea()->ScrollsOverflow() &&
+ diff.HasDifference()) {
+ SetNeedsCompositingInputsUpdate();
+ }
+
+ if (diff.TransformChanged() || diff.OpacityChanged() ||
+ diff.ZIndexChanged() || diff.FilterChanged() ||
+ diff.BackdropFilterChanged() || diff.CssClipChanged() ||
+ diff.BlendModeChanged() || diff.MaskChanged()) {
+ GetLayoutObject().SetNeedsPaintPropertyUpdate();
+ SetNeedsCompositingInputsUpdate();
+ }
+
+ // HasNonContainedAbsolutePositionDescendant depends on position changes.
+ if (!old_style || old_style->GetPosition() != new_style.GetPosition())
+ MarkAncestorChainForDescendantDependentFlagsUpdate();
+
UpdateTransform(old_style, new_style);
UpdateFilters(old_style, new_style);
UpdateClipPath(old_style, new_style);
- SetNeedsCompositingInputsUpdate();
- GetLayoutObject().SetNeedsPaintPropertyUpdate();
-
if (!NeedsRepaint()) {
if (diff.ZIndexChanged()) {
// We don't need to invalidate paint of objects when paint order
@@ -3220,7 +3270,7 @@ void PaintLayer::RemoveAncestorOverflowLayer(const PaintLayer* removed_layer) {
// sticky viewport constrained object, it is no longer known to be
// constrained by the root.
if (AncestorOverflowLayer()->IsRootLayer() &&
- GetLayoutObject().Style()->HasStickyConstrainedPosition()) {
+ GetLayoutObject().StyleRef().HasStickyConstrainedPosition()) {
if (LocalFrameView* frame_view = GetLayoutObject().GetFrameView())
frame_view->RemoveViewportConstrainedObject(GetLayoutObject());
}
@@ -3301,7 +3351,7 @@ void PaintLayer::ComputeSelfHitTestRects(
if (!Size().IsEmpty()) {
Vector<TouchActionRect> rect;
TouchAction whitelisted_touch_action =
- GetLayoutObject().Style()->GetEffectiveTouchAction() &
+ GetLayoutObject().StyleRef().GetEffectiveTouchAction() &
supported_fast_actions;
if (GetLayoutBox() && GetLayoutBox()->ScrollsOverflow()) {
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 2f8f0bf9288..523e3cbc4aa 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_layer.h
+++ b/chromium/third_party/blink/renderer/core/paint/paint_layer.h
@@ -261,7 +261,7 @@ class CORE_EXPORT PaintLayer : public DisplayItemClient {
bool IsTransparent() const {
return GetLayoutObject().IsTransparent() ||
- GetLayoutObject().Style()->HasBlendMode() ||
+ GetLayoutObject().StyleRef().HasBlendMode() ||
GetLayoutObject().HasMask();
}
@@ -353,12 +353,6 @@ class CORE_EXPORT PaintLayer : public DisplayItemClient {
// True if this layer container layoutObjects that paint.
bool HasNonEmptyChildLayoutObjects() const;
- // Will ensure that isAllScrollingContentComposited() is up to date.
- void UpdateScrollingStateAfterCompositingChange();
- bool IsAllScrollingContentComposited() const {
- return is_all_scrolling_content_composited_;
- }
-
// Gets the ancestor layer that serves as the containing block (in the sense
// of LayoutObject::container() instead of LayoutObject::containingBlock())
// of this layer. Normally the parent layer is the containing layer, except
@@ -492,7 +486,9 @@ class CORE_EXPORT PaintLayer : public DisplayItemClient {
// Note that this transform does not have the perspective-origin baked in.
TransformationMatrix PerspectiveTransform() const;
FloatPoint PerspectiveOrigin() const;
- bool Preserves3D() const { return GetLayoutObject().Style()->Preserves3D(); }
+ bool Preserves3D() const {
+ return GetLayoutObject().StyleRef().Preserves3D();
+ }
bool Has3DTransform() const {
return rare_data_ && rare_data_->transform &&
!rare_data_->transform->IsAffine();
@@ -502,7 +498,7 @@ class CORE_EXPORT PaintLayer : public DisplayItemClient {
// https://bugs.webkit.org/show_bug.cgi?id=106959
bool ShouldPreserve3D() const {
return !GetLayoutObject().HasReflection() &&
- GetLayoutObject().Style()->Preserves3D();
+ GetLayoutObject().StyleRef().Preserves3D();
}
// Returns |true| if any property that renders using filter operations is
@@ -1109,7 +1105,8 @@ class CORE_EXPORT PaintLayer : public DisplayItemClient {
bool HasOverflowControls() const;
enum UpdateLayerPositionBehavior { AllLayers, OnlyStickyLayers };
- void UpdateLayerPositionRecursive(UpdateLayerPositionBehavior = AllLayers);
+ void UpdateLayerPositionRecursive(UpdateLayerPositionBehavior = AllLayers,
+ bool dirty_compositing_if_needed = true);
void SetNextSibling(PaintLayer* next) { next_ = next; }
void SetPreviousSibling(PaintLayer* prev) { previous_ = prev; }
@@ -1277,11 +1274,6 @@ class CORE_EXPORT PaintLayer : public DisplayItemClient {
// the tree of z-order lists.
unsigned has_compositing_descendant_ : 1;
- // True iff we have scrollable overflow and all children of layout_object_ are
- // known to paint exclusively into their own composited layers. Set by
- // updateScrollingStateAfterCompositingChange().
- unsigned is_all_scrolling_content_composited_ : 1;
-
// Should be for stacking contexts having unisolated blending descendants.
unsigned should_isolate_composited_descendants_ : 1;
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_layer_clipper.cc b/chromium/third_party/blink/renderer/core/paint/paint_layer_clipper.cc
index 7d3d6388cca..bc74390a5db 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_layer_clipper.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_layer_clipper.cc
@@ -214,7 +214,10 @@ void PaintLayerClipper::ClearClipRectsIncludingDescendants(
LayoutRect PaintLayerClipper::LocalClipRect(
const PaintLayer& clipping_root_layer) const {
- ClipRectsContext context(&clipping_root_layer, kPaintingClipRects);
+ ClipRectsContext context(
+ &clipping_root_layer,
+ &clipping_root_layer.GetLayoutObject().FirstFragment(),
+ kPaintingClipRects);
if (use_geometry_mapper_) {
ClipRect clip_rect;
CalculateBackgroundClipRectWithGeometryMapper(
@@ -228,14 +231,10 @@ LayoutRect PaintLayerClipper::LocalClipRect(
// The rect now needs to be transformed to the local space of this
// PaintLayer.
// TODO(chrishtr): not correct for fragmentation.
- premapped_rect.MoveBy(
- context.root_layer->GetLayoutObject().FirstFragment().PaintOffset());
+ premapped_rect.MoveBy(context.root_fragment->PaintOffset());
const auto* clip_root_layer_transform =
- clipping_root_layer.GetLayoutObject()
- .FirstFragment()
- .LocalBorderBoxProperties()
- .Transform();
+ context.root_fragment->LocalBorderBoxProperties().Transform();
const auto* layer_transform = layer_.GetLayoutObject()
.FirstFragment()
.LocalBorderBoxProperties()
@@ -295,14 +294,12 @@ void PaintLayerClipper::CalculateRectsWithGeometryMapper(
} else {
const auto* current_transform =
fragment_data.PreEffectProperties().Transform();
- const auto& root_fragment =
- context.root_layer->GetLayoutObject().FirstFragment();
const auto* root_transform =
- root_fragment.LocalBorderBoxProperties().Transform();
+ context.root_fragment->LocalBorderBoxProperties().Transform();
if (&layer_ == context.root_layer ||
current_transform == root_transform) {
layer_bounds.MoveBy(fragment_data.PaintOffset());
- layer_bounds.MoveBy(-root_fragment.PaintOffset());
+ layer_bounds.MoveBy(-context.root_fragment->PaintOffset());
} else {
const TransformationMatrix& transform =
GeometryMapper::SourceToDestinationProjection(current_transform,
@@ -314,7 +311,7 @@ void PaintLayerClipper::CalculateRectsWithGeometryMapper(
// point error.
layer_bounds.Move(
LayoutSize((float)transform.E(), (float)transform.F()));
- layer_bounds.MoveBy(-root_fragment.PaintOffset());
+ layer_bounds.MoveBy(-context.root_fragment->PaintOffset());
} else {
// This branch can happen due to perspective transforms.
// TODO(chrishtr): investigate whether the paint code is broken
@@ -535,8 +532,7 @@ void PaintLayerClipper::CalculateBackgroundClipRectWithGeometryMapper(
if (!output.IsInfinite()) {
// TODO(chrishtr): generalize to multiple fragments.
- output.MoveBy(
- -context.root_layer->GetLayoutObject().FirstFragment().PaintOffset());
+ output.MoveBy(-context.root_fragment->PaintOffset());
output.Move(context.sub_pixel_accumulation);
}
}
@@ -550,20 +546,15 @@ void PaintLayerClipper::InitializeCommonClipRectState(
DCHECK(fragment_data.HasLocalBorderBoxProperties());
source_property_tree_state = fragment_data.LocalBorderBoxProperties();
- DCHECK(context.root_layer->GetLayoutObject()
- .FirstFragment()
- .HasLocalBorderBoxProperties());
- destination_property_tree_state = context.root_layer->GetLayoutObject()
- .FirstFragment()
- .LocalBorderBoxProperties();
+ DCHECK(context.root_fragment->HasLocalBorderBoxProperties());
+ destination_property_tree_state =
+ context.root_fragment->LocalBorderBoxProperties();
- const auto& ancestor_fragment_data =
- context.root_layer->GetLayoutObject().FirstFragment();
if (context.ShouldRespectRootLayerClip()) {
- destination_property_tree_state.SetClip(ancestor_fragment_data.PreClip());
+ destination_property_tree_state.SetClip(context.root_fragment->PreClip());
} else {
destination_property_tree_state.SetClip(
- ancestor_fragment_data.PostOverflowClip());
+ context.root_fragment->PostOverflowClip());
}
}
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_layer_clipper.h b/chromium/third_party/blink/renderer/core/paint/paint_layer_clipper.h
index 9df1f85fb59..50bde01ed1e 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_layer_clipper.h
+++ b/chromium/third_party/blink/renderer/core/paint/paint_layer_clipper.h
@@ -70,6 +70,7 @@ class ClipRectsContext {
public:
ClipRectsContext(
const PaintLayer* root,
+ const FragmentData* fragment,
ClipRectsCacheSlot slot,
OverlayScrollbarClipBehavior overlay_scrollbar_clip_behavior =
kIgnorePlatformOverlayScrollbarSize,
@@ -77,6 +78,7 @@ class ClipRectsContext {
kRespectOverflowClip,
const LayoutSize& accumulation = LayoutSize())
: root_layer(root),
+ root_fragment(fragment),
overlay_scrollbar_clip_behavior(overlay_scrollbar_clip_behavior),
cache_slot_(slot),
sub_pixel_accumulation(accumulation),
@@ -89,6 +91,7 @@ class ClipRectsContext {
bool ShouldRespectRootLayerClip() const;
const PaintLayer* root_layer;
+ const FragmentData* root_fragment;
const OverlayScrollbarClipBehavior overlay_scrollbar_clip_behavior;
private:
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 aadfe40237e..df01f76103e 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
@@ -42,7 +42,8 @@ TEST_F(PaintLayerClipperTest, ParentBackgroundClipRectSubpixelAccumulation) {
PaintLayer* target_paint_layer =
ToLayoutBoxModelObject(target->GetLayoutObject())->Layer();
ClipRectsContext context(
- GetDocument().GetLayoutView()->Layer(), kUncachedClipRects,
+ GetDocument().GetLayoutView()->Layer(),
+ &GetDocument().GetLayoutView()->FirstFragment(), kUncachedClipRects,
kIgnorePlatformOverlayScrollbarSize, kIgnoreOverflowClip,
LayoutSize(FloatSize(0.25, 0.35)));
@@ -71,7 +72,8 @@ TEST_F(PaintLayerClipperTest, BackgroundClipRectSubpixelAccumulation) {
PaintLayer* target_paint_layer =
ToLayoutBoxModelObject(target->GetLayoutObject())->Layer();
ClipRectsContext context(
- GetDocument().GetLayoutView()->Layer(), kUncachedClipRects,
+ GetDocument().GetLayoutView()->Layer(),
+ &GetDocument().GetLayoutView()->FirstFragment(), kUncachedClipRects,
kIgnorePlatformOverlayScrollbarSize, kIgnoreOverflowClip,
LayoutSize(FloatSize(0.25, 0.35)));
@@ -102,7 +104,8 @@ TEST_F(PaintLayerClipperTest, SVGBackgroundClipRectSubpixelAccumulation) {
PaintLayer* target_paint_layer =
ToLayoutBoxModelObject(target->GetLayoutObject())->Layer();
ClipRectsContext context(
- GetDocument().GetLayoutView()->Layer(), kUncachedClipRects,
+ GetDocument().GetLayoutView()->Layer(),
+ &GetDocument().GetLayoutView()->FirstFragment(), kUncachedClipRects,
kIgnorePlatformOverlayScrollbarSize, kIgnoreOverflowClip,
LayoutSize(FloatSize(0.25, 0.35)));
@@ -135,7 +138,8 @@ TEST_F(PaintLayerClipperTest, LayoutSVGRoot) {
// When RLS is enabled, the LayoutView will have a composited scrolling layer,
// so don't apply an overflow clip.
ClipRectsContext context(
- GetDocument().GetLayoutView()->Layer(), kUncachedClipRects,
+ GetDocument().GetLayoutView()->Layer(),
+ &GetDocument().GetLayoutView()->FirstFragment(), kUncachedClipRects,
kIgnorePlatformOverlayScrollbarSize, kIgnoreOverflowClip,
LayoutSize(FloatSize(0.25, 0.35)));
LayoutRect layer_bounds;
@@ -165,7 +169,8 @@ TEST_F(PaintLayerClipperTest, ControlClip) {
// When RLS is enabled, the LayoutView will have a composited scrolling layer,
// so don't apply an overflow clip.
ClipRectsContext context(
- GetDocument().GetLayoutView()->Layer(), kUncachedClipRects,
+ GetDocument().GetLayoutView()->Layer(),
+ &GetDocument().GetLayoutView()->FirstFragment(), kUncachedClipRects,
kIgnorePlatformOverlayScrollbarSize, kIgnoreOverflowClip);
LayoutRect layer_bounds;
ClipRect background_rect, foreground_rect;
@@ -203,7 +208,8 @@ TEST_F(PaintLayerClipperTest, RoundedClip) {
PaintLayer* target_paint_layer =
ToLayoutBoxModelObject(target->GetLayoutObject())->Layer();
ClipRectsContext context(
- GetDocument().GetLayoutView()->Layer(), kUncachedClipRects,
+ GetDocument().GetLayoutView()->Layer(),
+ &GetDocument().GetLayoutView()->FirstFragment(), kUncachedClipRects,
kIgnorePlatformOverlayScrollbarSize, kIgnoreOverflowClip);
LayoutRect layer_bounds;
@@ -242,7 +248,10 @@ TEST_F(PaintLayerClipperTest, RoundedClipNested) {
PaintLayer* child_paint_layer =
ToLayoutBoxModelObject(child->GetLayoutObject())->Layer();
- ClipRectsContext context(parent_paint_layer, kUncachedClipRects);
+ ClipRectsContext context(
+ parent_paint_layer,
+ &parent_paint_layer->GetLayoutObject().FirstFragment(),
+ kUncachedClipRects);
LayoutRect layer_bounds;
ClipRect background_rect, foreground_rect;
@@ -277,7 +286,8 @@ TEST_F(PaintLayerClipperTest, ControlClipSelect) {
PaintLayer* target_paint_layer =
ToLayoutBoxModelObject(target->GetLayoutObject())->Layer();
ClipRectsContext context(
- GetDocument().GetLayoutView()->Layer(), kUncachedClipRects,
+ GetDocument().GetLayoutView()->Layer(),
+ &GetDocument().GetLayoutView()->FirstFragment(), kUncachedClipRects,
kIgnorePlatformOverlayScrollbarSize, kIgnoreOverflowClip);
LayoutRect layer_bounds;
@@ -311,6 +321,7 @@ TEST_F(PaintLayerClipperTest, LayoutSVGRootChild) {
PaintLayer* target_paint_layer =
ToLayoutBoxModelObject(target->GetLayoutObject())->Layer();
ClipRectsContext context(GetDocument().GetLayoutView()->Layer(),
+ &GetDocument().GetLayoutView()->FirstFragment(),
kUncachedClipRects);
LayoutRect layer_bounds;
ClipRect background_rect, foreground_rect;
@@ -334,7 +345,8 @@ TEST_F(PaintLayerClipperTest, ContainPaintClip) {
PaintLayer* layer =
ToLayoutBoxModelObject(GetLayoutObjectByElementId("target"))->Layer();
- ClipRectsContext context(layer, kPaintingClipRectsIgnoringOverflowClip,
+ ClipRectsContext context(layer, &layer->GetLayoutObject().FirstFragment(),
+ kPaintingClipRectsIgnoringOverflowClip,
kIgnorePlatformOverlayScrollbarSize,
kIgnoreOverflowClip);
LayoutRect layer_bounds;
@@ -348,7 +360,8 @@ TEST_F(PaintLayerClipperTest, ContainPaintClip) {
EXPECT_EQ(background_rect.Rect(), foreground_rect.Rect());
EXPECT_EQ(LayoutRect(0, 0, 200, 200), layer_bounds);
- ClipRectsContext context_clip(layer, kUncachedClipRects);
+ ClipRectsContext context_clip(
+ layer, &layer->GetLayoutObject().FirstFragment(), kUncachedClipRects);
layer->Clipper(PaintLayer::kUseGeometryMapper)
.CalculateRects(context_clip, &layer->GetLayoutObject().FirstFragment(),
@@ -370,7 +383,8 @@ TEST_F(PaintLayerClipperTest, NestedContainPaintClip) {
PaintLayer* layer =
ToLayoutBoxModelObject(GetLayoutObjectByElementId("target"))->Layer();
ClipRectsContext context(
- layer->Parent(), kPaintingClipRectsIgnoringOverflowClip,
+ layer->Parent(), &layer->Parent()->GetLayoutObject().FirstFragment(),
+ kPaintingClipRectsIgnoringOverflowClip,
kIgnorePlatformOverlayScrollbarSize, kIgnoreOverflowClip);
LayoutRect layer_bounds;
ClipRect background_rect, foreground_rect;
@@ -382,7 +396,9 @@ TEST_F(PaintLayerClipperTest, NestedContainPaintClip) {
EXPECT_EQ(LayoutRect(0, 0, 200, 400), foreground_rect.Rect());
EXPECT_EQ(LayoutRect(0, 0, 200, 400), layer_bounds);
- ClipRectsContext context_clip(layer->Parent(), kUncachedClipRects);
+ ClipRectsContext context_clip(
+ layer->Parent(), &layer->Parent()->GetLayoutObject().FirstFragment(),
+ kUncachedClipRects);
layer->Clipper(PaintLayer::kUseGeometryMapper)
.CalculateRects(context_clip, &layer->GetLayoutObject().FirstFragment(),
@@ -502,7 +518,8 @@ TEST_F(PaintLayerClipperTest, CSSClip) {
PaintLayer* target =
ToLayoutBoxModelObject(GetLayoutObjectByElementId("target"))->Layer();
- ClipRectsContext context(target, kUncachedClipRects);
+ ClipRectsContext context(target, &target->GetLayoutObject().FirstFragment(),
+ kUncachedClipRects);
LayoutRect infinite_rect(LayoutRect::InfiniteIntRect());
LayoutRect layer_bounds(infinite_rect);
ClipRect background_rect(infinite_rect);
@@ -531,7 +548,8 @@ TEST_F(PaintLayerClipperTest, Filter) {
ToLayoutBoxModelObject(GetLayoutObjectByElementId("target"))->Layer();
// First test clip rects in the target layer itself.
- ClipRectsContext context(target, kUncachedClipRects);
+ ClipRectsContext context(target, &target->GetLayoutObject().FirstFragment(),
+ kUncachedClipRects);
LayoutRect infinite_rect(LayoutRect::InfiniteIntRect());
LayoutRect layer_bounds(infinite_rect);
ClipRect background_rect(infinite_rect);
@@ -560,7 +578,9 @@ TEST_F(PaintLayerClipperTest, Filter) {
EXPECT_EQ(LayoutRect(40, 40, 100, 200), foreground_rect.Rect());
// Test mapping to the root layer.
- ClipRectsContext root_context(GetLayoutView().Layer(), kUncachedClipRects);
+ ClipRectsContext root_context(GetLayoutView().Layer(),
+ &GetLayoutView().FirstFragment(),
+ kUncachedClipRects);
background_rect = infinite_rect;
foreground_rect = infinite_rect;
target->Clipper(PaintLayer::kUseGeometryMapper)
@@ -608,7 +628,8 @@ TEST_F(PaintLayerClipperTest, IgnoreRootLayerClipWithCSSClip) {
ToLayoutBoxModelObject(GetLayoutObjectByElementId("root"))->Layer();
PaintLayer* target =
ToLayoutBoxModelObject(GetLayoutObjectByElementId("target"))->Layer();
- ClipRectsContext context(root, kPaintingClipRectsIgnoringOverflowClip,
+ ClipRectsContext context(root, &root->GetLayoutObject().FirstFragment(),
+ kPaintingClipRectsIgnoringOverflowClip,
kIgnorePlatformOverlayScrollbarSize,
kIgnoreOverflowClip);
LayoutRect infinite_rect(LayoutRect::InfiniteIntRect());
@@ -643,7 +664,8 @@ TEST_F(PaintLayerClipperTest, IgnoreRootLayerClipWithOverflowClip) {
ToLayoutBoxModelObject(GetLayoutObjectByElementId("root"))->Layer();
PaintLayer* target =
ToLayoutBoxModelObject(GetLayoutObjectByElementId("target"))->Layer();
- ClipRectsContext context(root, kPaintingClipRectsIgnoringOverflowClip,
+ ClipRectsContext context(root, &root->GetLayoutObject().FirstFragment(),
+ kPaintingClipRectsIgnoringOverflowClip,
kIgnorePlatformOverlayScrollbarSize,
kIgnoreOverflowClip);
LayoutRect infinite_rect(LayoutRect::InfiniteIntRect());
@@ -679,7 +701,8 @@ TEST_F(PaintLayerClipperTest, IgnoreRootLayerClipWithBothClip) {
ToLayoutBoxModelObject(GetLayoutObjectByElementId("root"))->Layer();
PaintLayer* target =
ToLayoutBoxModelObject(GetLayoutObjectByElementId("target"))->Layer();
- ClipRectsContext context(root, kPaintingClipRectsIgnoringOverflowClip,
+ ClipRectsContext context(root, &root->GetLayoutObject().FirstFragment(),
+ kPaintingClipRectsIgnoringOverflowClip,
kIgnorePlatformOverlayScrollbarSize,
kIgnoreOverflowClip);
LayoutRect infinite_rect(LayoutRect::InfiniteIntRect());
@@ -708,8 +731,9 @@ TEST_F(PaintLayerClipperTest, Fragmentation) {
Element* root = GetDocument().getElementById("root");
PaintLayer* root_paint_layer =
ToLayoutBoxModelObject(root->GetLayoutObject())->Layer();
- ClipRectsContext context(root_paint_layer, kUncachedClipRects,
- kIgnorePlatformOverlayScrollbarSize);
+ ClipRectsContext context(
+ root_paint_layer, &root_paint_layer->GetLayoutObject().FirstFragment(),
+ kUncachedClipRects, kIgnorePlatformOverlayScrollbarSize);
LayoutRect layer_bounds;
ClipRect background_rect, foreground_rect;
@@ -728,9 +752,9 @@ TEST_F(PaintLayerClipperTest, Fragmentation) {
&target_paint_layer->GetLayoutObject().FirstFragment(),
nullptr, layer_bounds, background_rect, foreground_rect);
- EXPECT_EQ(LayoutRect(FloatRect(-1.0e6, -1.0e6, 1.0001e6, 1.0001e6)),
+ EXPECT_EQ(LayoutRect(FloatRect(-1.0e6, -1.0e6, 2.0000e6, 1.0001e6)),
background_rect.Rect());
- EXPECT_EQ(LayoutRect(FloatRect(-1.0e6, -1.0e6, 1.0001e6, 1.0001e6)),
+ EXPECT_EQ(LayoutRect(FloatRect(-1.0e6, -1.0e6, 2.0000e6, 1.0001e6)),
foreground_rect.Rect());
EXPECT_EQ(LayoutRect(FloatRect(0, 0, 100, 200)), layer_bounds);
@@ -740,9 +764,9 @@ TEST_F(PaintLayerClipperTest, Fragmentation) {
target_paint_layer->GetLayoutObject().FirstFragment().NextFragment(),
nullptr, layer_bounds, background_rect, foreground_rect);
- EXPECT_EQ(LayoutRect(FloatRect(100, 0, 1000000, 999900)),
+ EXPECT_EQ(LayoutRect(FloatRect(-999900, 0, 2000000, 999900)),
background_rect.Rect());
- EXPECT_EQ(LayoutRect(FloatRect(100, 0, 1000000, 999900)),
+ EXPECT_EQ(LayoutRect(FloatRect(-999900, 0, 2000000, 999900)),
foreground_rect.Rect());
// Layer bounds adjusted for pagination offset of second fragment.
EXPECT_EQ(LayoutRect(FloatRect(100, -100, 100, 200)), layer_bounds);
@@ -767,8 +791,10 @@ TEST_F(PaintLayerClipperTest, ScrollbarClipBehaviorChild) {
PaintLayer* child_paint_layer =
ToLayoutBoxModelObject(child->GetLayoutObject())->Layer();
- ClipRectsContext context(parent_paint_layer, kUncachedClipRects,
- kExcludeOverlayScrollbarSizeForHitTesting);
+ ClipRectsContext context(
+ parent_paint_layer,
+ &parent_paint_layer->GetLayoutObject().FirstFragment(),
+ kUncachedClipRects, kExcludeOverlayScrollbarSizeForHitTesting);
LayoutRect layer_bounds;
ClipRect background_rect, foreground_rect;
@@ -810,8 +836,9 @@ TEST_F(PaintLayerClipperTest, ScrollbarClipBehaviorChildScrollBetween) {
PaintLayer* child_paint_layer =
ToLayoutBoxModelObject(child->GetLayoutObject())->Layer();
- ClipRectsContext context(root_paint_layer, kUncachedClipRects,
- kExcludeOverlayScrollbarSizeForHitTesting);
+ ClipRectsContext context(
+ root_paint_layer, &root_paint_layer->GetLayoutObject().FirstFragment(),
+ kUncachedClipRects, kExcludeOverlayScrollbarSizeForHitTesting);
LayoutRect layer_bounds;
ClipRect background_rect, foreground_rect;
@@ -854,8 +881,10 @@ TEST_F(PaintLayerClipperTest, ScrollbarClipBehaviorParent) {
PaintLayer* child_paint_layer =
ToLayoutBoxModelObject(child->GetLayoutObject())->Layer();
- ClipRectsContext context(parent_paint_layer, kUncachedClipRects,
- kExcludeOverlayScrollbarSizeForHitTesting);
+ ClipRectsContext context(
+ parent_paint_layer,
+ &parent_paint_layer->GetLayoutObject().FirstFragment(),
+ kUncachedClipRects, kExcludeOverlayScrollbarSizeForHitTesting);
LayoutRect layer_bounds;
ClipRect background_rect, foreground_rect;
@@ -905,6 +934,7 @@ TEST_F(PaintLayerClipperTest, FixedLayerClipRectInDocumentSpace) {
target_layer->Clipper(PaintLayer::kDoNotUseGeometryMapper)
.CalculateBackgroundClipRect(
ClipRectsContext(GetDocument().GetLayoutView()->Layer(),
+ &GetDocument().GetLayoutView()->FirstFragment(),
kAbsoluteClipRectsIgnoringViewportClip,
kIgnorePlatformOverlayScrollbarSize,
kIgnoreOverflowClipAndScroll),
@@ -919,6 +949,7 @@ TEST_F(PaintLayerClipperTest, FixedLayerClipRectInDocumentSpace) {
target_layer->Clipper(PaintLayer::kDoNotUseGeometryMapper)
.CalculateBackgroundClipRect(
ClipRectsContext(GetDocument().GetLayoutView()->Layer(),
+ &GetDocument().GetLayoutView()->FirstFragment(),
kAbsoluteClipRectsIgnoringViewportClip,
kIgnorePlatformOverlayScrollbarSize,
kIgnoreOverflowClipAndScroll),
@@ -955,6 +986,7 @@ TEST_F(PaintLayerClipperTest,
target_layer->Clipper(PaintLayer::kDoNotUseGeometryMapper)
.CalculateBackgroundClipRect(
ClipRectsContext(GetDocument().GetLayoutView()->Layer(),
+ &GetDocument().GetLayoutView()->FirstFragment(),
kAbsoluteClipRectsIgnoringViewportClip,
kIgnorePlatformOverlayScrollbarSize,
kIgnoreOverflowClipAndScroll),
@@ -969,6 +1001,7 @@ TEST_F(PaintLayerClipperTest,
target_layer->Clipper(PaintLayer::kDoNotUseGeometryMapper)
.CalculateBackgroundClipRect(
ClipRectsContext(GetDocument().GetLayoutView()->Layer(),
+ &GetDocument().GetLayoutView()->FirstFragment(),
kAbsoluteClipRectsIgnoringViewportClip,
kIgnorePlatformOverlayScrollbarSize,
kIgnoreOverflowClipAndScroll),
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 170a7d0697c..30b9d0709d5 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
@@ -49,14 +49,6 @@ struct PaintLayerFragment {
DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
public:
- void SetRects(const LayoutRect& bounds,
- const ClipRect& background,
- const ClipRect& foreground) {
- layer_bounds = bounds;
- background_rect = background;
- foreground_rect = foreground;
- }
-
void MoveBy(const LayoutPoint& offset) {
layer_bounds.MoveBy(offset);
background_rect.MoveBy(offset);
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 dcf00696a24..152b2ecec32 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
@@ -15,7 +15,6 @@
#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/display_item_cache_skipper.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"
@@ -97,24 +96,6 @@ bool PaintLayerPainter::PaintedOutputInvisible(
return false;
}
-bool PaintLayerPainter::ShouldAdjustPaintingRoot(
- const PaintLayerPaintingInfo& painting_info,
- PaintLayerFlags paint_flags) {
- // Cull rects and clips can't be propagated into a different 2D transform
- // space.
- if (paint_layer_.PaintsWithTransform(painting_info.GetGlobalPaintFlags()) &&
- !(paint_flags & kPaintLayerAppliedTransform))
- return true;
-
- // Cull rects and clips can't be propagated across a filter which moves
- // pixels, since the input of the filter may be outside the cull rect/clips
- // yet still result in painted output.
- if (paint_layer_.HasFilterThatMovesPixels())
- return true;
-
- return false;
-}
-
PaintResult PaintLayerPainter::Paint(
GraphicsContext& context,
const PaintLayerPaintingInfo& painting_info,
@@ -155,34 +136,18 @@ PaintResult PaintLayerPainter::Paint(
return kFullyPainted;
}
+ // If the transform can't be inverted, then don't paint anything.
+ if (paint_layer_.PaintsWithTransform(painting_info.GetGlobalPaintFlags()) &&
+ !paint_layer_.RenderableTransform(painting_info.GetGlobalPaintFlags())
+ .IsInvertible()) {
+ return kFullyPainted;
+ }
+
if (paint_layer_.PaintsWithTransparency(painting_info.GetGlobalPaintFlags()))
paint_flags |= kPaintLayerHaveTransparency;
- // The painting root should be adjusted if clips or cull rects for the
- // current root don't make sense for content underneath |paint_layer_|.
- // See ShouldAdjustPaintingRoot for examples when this is the case.
- // In these cases, we reset the cull rect to infinite, collect fragments,
- // and paint each fragment's subtree separately.
- if (ShouldAdjustPaintingRoot(painting_info, paint_flags))
- return PaintLayerWithAdjustedRoot(context, painting_info, paint_flags);
-
- return PaintLayerContentsCompositingAllPhases(context, painting_info,
- paint_flags);
-}
-
-PaintResult PaintLayerPainter::PaintLayerContentsCompositingAllPhases(
- GraphicsContext& context,
- const PaintLayerPaintingInfo& painting_info,
- PaintLayerFlags paint_flags,
- const PaintLayerFragment* fragment) {
- DCHECK(paint_layer_.IsSelfPaintingLayer() ||
- paint_layer_.HasSelfPaintingLayerDescendant());
-
- PaintLayerFlags local_paint_flags =
- paint_flags & ~(kPaintLayerAppliedTransform);
- local_paint_flags |= kPaintLayerPaintingCompositingAllPhases;
- return PaintLayerContents(context, painting_info, local_paint_flags,
- fragment);
+ paint_flags |= kPaintLayerPaintingCompositingAllPhases;
+ return PaintLayerContents(context, painting_info, paint_flags);
}
static bool ShouldCreateSubsequence(const PaintLayer& paint_layer,
@@ -267,42 +232,55 @@ static bool ShouldRepaintSubsequence(
void PaintLayerPainter::AdjustForPaintProperties(
PaintLayerPaintingInfo& painting_info,
PaintLayerFlags& paint_flags) {
- // Paint properties for transforms, composited layers or LayoutView is already
- // taken care of.
- // TODO(wangxianzhu): Also use this for PaintsWithTransform() and remove
- // PaintLayerWithTransform().
- if (&paint_layer_ == painting_info.root_layer ||
- paint_layer_.PaintsWithTransform(painting_info.GetGlobalPaintFlags()) ||
- paint_layer_.PaintsIntoOwnOrGroupedBacking(
- painting_info.GetGlobalPaintFlags()) ||
- paint_layer_.GetLayoutObject().IsLayoutView())
- return;
-
+ // TODO(wangxianzhu): Make this function fragment aware.
const auto& current_fragment = paint_layer_.GetLayoutObject().FirstFragment();
- const auto* current_transform =
- current_fragment.LocalBorderBoxProperties().Transform();
- const auto& root_fragment =
- painting_info.root_layer->GetLayoutObject().FirstFragment();
- const auto* root_transform =
- root_fragment.LocalBorderBoxProperties().Transform();
- if (current_transform == root_transform)
+
+ bool use_infinite_dirty_rect =
+ // Cull rects and clips can't be propagated across a filter which moves
+ // pixels, since the input of the filter may be outside the cull rect /
+ // clips yet still result in painted output.
+ paint_layer_.HasFilterThatMovesPixels() ||
+ // We do not apply cull rect optimizations across transforms for two
+ // reasons:
+ // 1) Performance: We can optimize transform changes by not repainting.
+ // 2) Complexity: Difficulty updating clips when ancestor transforms
+ // change.
+ // For these reasons, we use an infinite dirty rect here.
+ paint_layer_.PaintsWithTransform(painting_info.GetGlobalPaintFlags());
+
+ if (use_infinite_dirty_rect)
+ painting_info.paint_dirty_rect = LayoutRect(LayoutRect::InfiniteIntRect());
+
+ if (painting_info.root_layer == &paint_layer_)
return;
- // painting_info.paint_dirty_rect is currently in |painting_info.root_layer|'s
- // pixel-snapped border box space. We need to adjust it into |paint_layer_|'s
- // space. This handles the following cases:
- // - The current layer has PaintOffsetTranslation;
- // - The current layer's transform state escapes the root layers contents
- // transform, e.g. a fixed-position layer;
- // - Scroll offsets.
- const auto& matrix = GeometryMapper::SourceToDestinationProjection(
- root_transform, current_transform);
- painting_info.paint_dirty_rect.MoveBy(
- RoundedIntPoint(root_fragment.PaintOffset()));
- painting_info.paint_dirty_rect =
- matrix.MapRect(painting_info.paint_dirty_rect);
- painting_info.paint_dirty_rect.MoveBy(
- -RoundedIntPoint(current_fragment.PaintOffset()));
+ if (!use_infinite_dirty_rect) {
+ const auto* current_transform =
+ current_fragment.LocalBorderBoxProperties().Transform();
+ const auto& root_fragment =
+ painting_info.root_layer->GetLayoutObject().FirstFragment();
+ const auto* root_transform =
+ root_fragment.LocalBorderBoxProperties().Transform();
+ if (current_transform == root_transform)
+ return;
+
+ // painting_info.paint_dirty_rect is currently in
+ // |painting_info.root_layer|'s pixel-snapped border box space. We need to
+ // adjust it into |paint_layer_|'s space.
+ // This handles the following cases:
+ // - The current layer has PaintOffsetTranslation;
+ // - The current layer's transform state escapes the root layers contents
+ // transform, e.g. a fixed-position layer;
+ // - Scroll offsets.
+ const auto& matrix = GeometryMapper::SourceToDestinationProjection(
+ root_transform, current_transform);
+ painting_info.paint_dirty_rect.MoveBy(
+ RoundedIntPoint(root_fragment.PaintOffset()));
+ painting_info.paint_dirty_rect =
+ matrix.MapRect(painting_info.paint_dirty_rect);
+ painting_info.paint_dirty_rect.MoveBy(
+ -RoundedIntPoint(current_fragment.PaintOffset()));
+ }
// Make the current layer the new root layer.
painting_info.root_layer = &paint_layer_;
@@ -311,7 +289,7 @@ void PaintLayerPainter::AdjustForPaintProperties(
paint_flags &= ~kPaintLayerPaintingOverflowContents;
paint_flags &= ~kPaintLayerPaintingCompositingScrollingPhase;
- // TODO(chrishtr): is this correct for fragmentation?
+ // TODO(wangxianzhu): Make this function fragment aware.
if (current_fragment.PaintProperties() &&
current_fragment.PaintProperties()->PaintOffsetTranslation()) {
painting_info.sub_pixel_accumulation =
@@ -322,8 +300,7 @@ void PaintLayerPainter::AdjustForPaintProperties(
PaintResult PaintLayerPainter::PaintLayerContents(
GraphicsContext& context,
const PaintLayerPaintingInfo& painting_info_arg,
- PaintLayerFlags paint_flags_arg,
- const PaintLayerFragment* fragment) {
+ PaintLayerFlags paint_flags_arg) {
PaintLayerFlags paint_flags = paint_flags_arg;
PaintResult result = kFullyPainted;
@@ -344,7 +321,6 @@ PaintResult PaintLayerPainter::PaintLayerContents(
DCHECK(paint_layer_.IsSelfPaintingLayer() ||
paint_layer_.HasSelfPaintingLayerDescendant());
- DCHECK(!(paint_flags & kPaintLayerAppliedTransform));
bool is_self_painting_layer = paint_layer_.IsSelfPaintingLayer();
bool is_painting_overlay_scrollbars =
@@ -367,19 +343,20 @@ PaintResult PaintLayerPainter::PaintLayerContents(
bool should_paint_self_outline =
is_self_painting_layer && !is_painting_overlay_scrollbars &&
(is_painting_composited_decoration ||
- (!is_painting_scrolling_content && !is_painting_mask)) &&
+ (!is_painting_overflow_contents && !is_painting_mask)) &&
paint_layer_.GetLayoutObject().StyleRef().HasOutline();
LayoutSize subpixel_accumulation =
paint_layer_.GetCompositingState() == kPaintsIntoOwnBacking
? paint_layer_.SubpixelAccumulation()
: painting_info_arg.sub_pixel_accumulation;
- ShouldRespectOverflowClipType respect_overflow_clip =
- ShouldRespectOverflowClip(paint_flags, paint_layer_.GetLayoutObject());
PaintLayerPaintingInfo painting_info = painting_info_arg;
AdjustForPaintProperties(painting_info, paint_flags);
+ ShouldRespectOverflowClipType respect_overflow_clip =
+ ShouldRespectOverflowClip(paint_flags, paint_layer_.GetLayoutObject());
+
bool should_create_subsequence = ShouldCreateSubsequence(
paint_layer_, context, painting_info_arg, paint_flags);
@@ -466,32 +443,17 @@ PaintResult PaintLayerPainter::PaintLayerContents(
respect_overflow_clip = kIgnoreOverflowClip;
}
- if (fragment) {
- // We are painting a single specified fragment.
- // TODO(wangxianzhu): we could use |fragment| directly, but because
- // the value of |fragment| is for SPv175 only for descendants to find the
- // correct fragment state, we don't bother to modify SPv1 code with
- // the risk of regressions. Eventually we will remove the whole
- // PaintLayerWithTransform() path.
- paint_layer_for_fragments->AppendSingleFragmentIgnoringPagination(
- layer_fragments, local_painting_info.root_layer,
- &local_painting_info.paint_dirty_rect,
- kIgnorePlatformOverlayScrollbarSize, respect_overflow_clip,
- &offset_from_root, local_painting_info.sub_pixel_accumulation);
- layer_fragments[0].fragment_data = fragment->fragment_data;
- } else {
- paint_layer_for_fragments->CollectFragments(
- layer_fragments, local_painting_info.root_layer,
- &local_painting_info.paint_dirty_rect,
- kIgnorePlatformOverlayScrollbarSize, respect_overflow_clip,
- &offset_from_root, local_painting_info.sub_pixel_accumulation);
-
- // PaintLayer::CollectFragments depends on the paint dirty rect in
- // complicated ways. For now, always assume a partially painted output
- // for fragmented content.
- if (layer_fragments.size() > 1)
- result = kMayBeClippedByPaintDirtyRect;
- }
+ paint_layer_for_fragments->CollectFragments(
+ layer_fragments, local_painting_info.root_layer,
+ &local_painting_info.paint_dirty_rect,
+ kIgnorePlatformOverlayScrollbarSize, respect_overflow_clip,
+ &offset_from_root, local_painting_info.sub_pixel_accumulation);
+
+ // PaintLayer::CollectFragments depends on the paint dirty rect in
+ // complicated ways. For now, always assume a partially painted output
+ // for fragmented content.
+ if (layer_fragments.size() > 1)
+ result = kMayBeClippedByPaintDirtyRect;
if (paint_flags & kPaintLayerPaintingAncestorClippingMaskPhase) {
// Fragment offsets have been computed in the clipping container's
@@ -708,137 +670,6 @@ static void ForAllFragments(GraphicsContext& context,
}
}
-PaintResult PaintLayerPainter::PaintLayerWithAdjustedRoot(
- GraphicsContext& context,
- const PaintLayerPaintingInfo& painting_info,
- PaintLayerFlags paint_flags) {
- TransformationMatrix layer_transform =
- paint_layer_.RenderableTransform(painting_info.GetGlobalPaintFlags());
- // If the transform can't be inverted, then don't paint anything.
- if (!layer_transform.IsInvertible())
- return kFullyPainted;
-
- // FIXME: We should make sure that we don't walk past paintingInfo.rootLayer
- // here. m_paintLayer may be the "root", and then we should avoid looking at
- // its parent.
- PaintLayer* parent_layer = paint_layer_.Parent();
-
- PaintResult result = kFullyPainted;
- PaintLayerFragments layer_fragments;
-
- // This works around a bug in squashed-layer painting.
- // Squashed layers paint into a backing in its compositing container's
- // space, but painting_info.root_layer points to the squashed layer
- // itself, thus PaintLayerClipper would return a clip rect in the
- // squashed layer's local space, instead of the backing's space.
- // Fortunately, CompositedLayerMapping::DoPaintTask already applied
- // appropriate ancestor clip for us, so we can simply skip it.
- bool is_squashed_layer = painting_info.root_layer == &paint_layer_;
-
- if (is_squashed_layer) {
- // We don't need to collect any fragments in the regular way here. We have
- // already calculated a clip rectangle for the ancestry if it was needed,
- // and clipping this layer is something that can be done further down the
- // path, when the transform has been applied.
- PaintLayerFragment fragment;
- fragment.background_rect = painting_info.paint_dirty_rect;
- fragment.fragment_data = &paint_layer_.GetLayoutObject().FirstFragment();
- layer_fragments.push_back(fragment);
- } else if (parent_layer) {
- ShouldRespectOverflowClipType respect_overflow_clip =
- ShouldRespectOverflowClip(paint_flags, paint_layer_.GetLayoutObject());
- paint_layer_.CollectFragments(
- layer_fragments, painting_info.root_layer,
- &painting_info.paint_dirty_rect, kIgnorePlatformOverlayScrollbarSize,
- respect_overflow_clip, nullptr, painting_info.sub_pixel_accumulation);
- // PaintLayer::CollectFragments depends on the paint dirty rect in
- // complicated ways. For now, always assume a partially painted output
- // for fragmented content.
- if (layer_fragments.size() > 1)
- result = kMayBeClippedByPaintDirtyRect;
- }
-
- // We have to skip cache for fragments under transform because we will paint
- // all the fragments of sublayers in each fragment like the following:
- // fragment 0 { sub-layer fragment 0; sub-layer fragment 1 }
- // fragment 1 { sub-layer fragment 0; sub-layer fragment 1 }
- base::Optional<DisplayItemCacheSkipper> cache_skipper;
- if (layer_fragments.size() > 1)
- cache_skipper.emplace(context);
-
- ForAllFragments(
- context, layer_fragments, [&](const PaintLayerFragment& fragment) {
- if (paint_layer_.PaintsWithTransform(
- painting_info.GetGlobalPaintFlags())) {
- if (PaintFragmentByApplyingTransform(context, painting_info,
- paint_flags, fragment) ==
- kMayBeClippedByPaintDirtyRect)
- result = kMayBeClippedByPaintDirtyRect;
- } else {
- if (PaintSingleFragment(context, painting_info, paint_flags, fragment,
- painting_info.sub_pixel_accumulation) ==
- kMayBeClippedByPaintDirtyRect)
- result = kMayBeClippedByPaintDirtyRect;
- }
- });
- return result;
-}
-
-PaintResult PaintLayerPainter::PaintFragmentByApplyingTransform(
- GraphicsContext& context,
- const PaintLayerPaintingInfo& painting_info,
- PaintLayerFlags paint_flags,
- const PaintLayerFragment& fragment) {
- // This involves subtracting out the position of the layer in our current
- // coordinate space, but preserving the accumulated error for sub-pixel
- // layout.
- LayoutPoint delta;
- paint_layer_.ConvertToLayerCoords(painting_info.root_layer, delta);
- delta.MoveBy(fragment.pagination_offset);
- delta += painting_info.sub_pixel_accumulation;
- IntPoint rounded_delta = RoundedIntPoint(delta);
-
- TransformationMatrix transform(
- paint_layer_.RenderableTransform(painting_info.GetGlobalPaintFlags()));
- transform.PostTranslate(rounded_delta.X(), rounded_delta.Y());
-
- LayoutSize new_sub_pixel_accumulation;
- if (transform.IsIdentityOrTranslation())
- new_sub_pixel_accumulation += delta - rounded_delta;
- // Otherwise discard the sub-pixel remainder because paint offset can't be
- // transformed by a non-translation transform.
- return PaintSingleFragment(context, painting_info, paint_flags, fragment,
- new_sub_pixel_accumulation);
-}
-
-PaintResult PaintLayerPainter::PaintSingleFragment(
- GraphicsContext& context,
- const PaintLayerPaintingInfo& painting_info,
- PaintLayerFlags paint_flags,
- const PaintLayerFragment& fragment,
- const LayoutSize& subpixel_accumulation) {
- // Now do a paint with the root layer shifted to be us.
-
- // We do not apply cull rect optimizations across transforms for two reasons:
- // 1) Performance: We can optimize transform changes by not repainting.
- // 2) Complexity: Difficulty updating clips when ancestor transforms change.
- // For these reasons, we use an infinite dirty rect here.
- PaintLayerPaintingInfo new_paint_info(
- &paint_layer_, LayoutRect(LayoutRect::InfiniteIntRect()),
- painting_info.GetGlobalPaintFlags(), subpixel_accumulation);
-
- if (&paint_layer_ != painting_info.root_layer) {
- // Remove skip root background flag when we're painting with a new root.
- paint_flags &= ~kPaintLayerPaintingSkipRootBackground;
- // When painting a new root we are no longer painting overflow contents.
- paint_flags &= ~kPaintLayerPaintingOverflowContents;
- paint_flags &= ~kPaintLayerPaintingCompositingScrollingPhase;
- }
-
- return PaintLayerContentsCompositingAllPhases(context, new_paint_info,
- paint_flags, &fragment);
-}
-
PaintResult PaintLayerPainter::PaintChildren(
unsigned children_to_visit,
GraphicsContext& context,
@@ -943,23 +774,23 @@ void PaintLayerPainter::PaintFragmentWithPhase(
LayoutRect new_cull_rect(clip_rect.Rect());
// We paint in the containing transform node's space. Now |new_cull_rect| is
// in the pixel-snapped border box space of |painting_info.root_layer|.
- // Adjust it to the correct space. |paint_offset| is already in the correct
- // space.
+ // Adjust it to the correct space.
new_cull_rect.MoveBy(
RoundedIntPoint(painting_info.root_layer->GetLayoutObject()
.FirstFragment()
.PaintOffset()));
+ // If we had pending stylesheets, we should avoid painting descendants of
+ // layout view to avoid FOUC.
+ bool suppress_painting_descendants = paint_layer_.GetLayoutObject()
+ .GetDocument()
+ .DidLayoutWithPendingStylesheets();
PaintInfo paint_info(context, PixelSnappedIntRect(new_cull_rect), phase,
painting_info.GetGlobalPaintFlags(), paint_flags,
&painting_info.root_layer->GetLayoutObject(),
fragment.fragment_data
? fragment.fragment_data->LogicalTopInFlowThread()
: LayoutUnit(),
- // If we had pending stylesheets, we should avoid
- // painting descendants of layout view to avoid FOUC.
- paint_layer_.GetLayoutObject()
- .GetDocument()
- .DidLayoutWithPendingStylesheets());
+ suppress_painting_descendants);
paint_layer_.GetLayoutObject().Paint(paint_info);
}
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 7b7c47fc956..14e0cafb7d0 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
@@ -43,12 +43,10 @@ class CORE_EXPORT PaintLayerPainter {
const PaintLayerPaintingInfo&,
PaintLayerFlags);
// PaintLayerContents() assumes that the caller will clip to the bounds of the
- // painting dirty rect if necessary. If PaintLayerFragment is not nullptr,
- // only the specified fragment will be painted.
+ // painting dirty rect if necessary.
PaintResult PaintLayerContents(GraphicsContext&,
const PaintLayerPaintingInfo&,
- PaintLayerFlags,
- const PaintLayerFragment* = nullptr);
+ PaintLayerFlags);
void PaintOverlayScrollbars(GraphicsContext&,
const LayoutRect& damage_rect,
@@ -62,27 +60,6 @@ class CORE_EXPORT PaintLayerPainter {
private:
friend class PaintLayerPainterTest;
- bool ShouldAdjustPaintingRoot(const PaintLayerPaintingInfo& painting_info,
- PaintLayerFlags paint_flags);
-
- PaintResult PaintLayerContentsCompositingAllPhases(
- GraphicsContext&,
- const PaintLayerPaintingInfo&,
- PaintLayerFlags,
- const PaintLayerFragment* = nullptr);
- PaintResult PaintLayerWithAdjustedRoot(GraphicsContext&,
- const PaintLayerPaintingInfo&,
- PaintLayerFlags);
- PaintResult PaintFragmentByApplyingTransform(GraphicsContext&,
- const PaintLayerPaintingInfo&,
- PaintLayerFlags,
- const PaintLayerFragment&);
- PaintResult PaintSingleFragment(GraphicsContext&,
- const PaintLayerPaintingInfo&,
- PaintLayerFlags,
- const PaintLayerFragment&,
- const LayoutSize& subpixel_accumulation);
-
PaintResult PaintChildren(unsigned children_to_visit,
GraphicsContext&,
const PaintLayerPaintingInfo&,
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_layer_painting_info.h b/chromium/third_party/blink/renderer/core/paint/paint_layer_painting_info.h
index 1adbacd3d11..3c90598c7fe 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_layer_painting_info.h
+++ b/chromium/third_party/blink/renderer/core/paint/paint_layer_painting_info.h
@@ -45,10 +45,16 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_PAINT_LAYER_PAINTING_INFO_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_PAINT_LAYER_PAINTING_INFO_H_
+#include "base/logging.h"
#include "third_party/blink/renderer/core/paint/paint_phase.h"
#include "third_party/blink/renderer/platform/geometry/layout_rect.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
+#if DCHECK_IS_ON()
+#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#endif
+
namespace blink {
class PaintLayer;
@@ -56,7 +62,6 @@ class PaintLayer;
enum PaintLayerFlag {
kPaintLayerNoFlag = 0,
kPaintLayerHaveTransparency = 1,
- kPaintLayerAppliedTransform = 1 << 1,
kPaintLayerUncachedClipRects = 1 << 2,
kPaintLayerPaintingOverlayScrollbars = 1 << 3,
kPaintLayerPaintingCompositingBackgroundPhase = 1 << 4,
@@ -81,6 +86,8 @@ typedef unsigned PaintLayerFlags;
struct PaintLayerPaintingInfo {
STACK_ALLOCATED();
+
+ public:
PaintLayerPaintingInfo(PaintLayer* in_root_layer,
const LayoutRect& in_dirty_rect,
GlobalPaintFlags global_paint_flags,
@@ -101,6 +108,60 @@ struct PaintLayerPaintingInfo {
const GlobalPaintFlags global_paint_flags_;
};
+#if DCHECK_IS_ON()
+inline String PaintLayerFlagsToDebugString(PaintLayerFlags flags) {
+ if (flags == 0)
+ return "(kPaintLayerNoFlag)";
+
+ StringBuilder builder;
+ builder.Append("(");
+ bool need_separator = false;
+ auto append = [&builder, &need_separator](const char* str) {
+ if (need_separator)
+ builder.Append("|");
+ builder.Append(str);
+ need_separator = true;
+ };
+
+ if (flags & kPaintLayerPaintingCompositingAllPhases) {
+ append("kPaintLayerPaintingCompositingAllPhases");
+ } else {
+ if (flags & kPaintLayerPaintingCompositingBackgroundPhase)
+ append("kPaintLayerPaintingCompositingBackgroundPhase");
+ if (flags & kPaintLayerPaintingCompositingForegroundPhase)
+ append("kPaintLayerPaintingCompositingForegroundPhase");
+ if (flags & kPaintLayerPaintingCompositingMaskPhase)
+ append("kPaintLayerPaintingCompositingMaskPhase");
+ if (flags & kPaintLayerPaintingCompositingDecorationPhase)
+ append("kPaintLayerPaintingCompositingDecorationPhase");
+ }
+
+ if (flags & kPaintLayerHaveTransparency)
+ append("kPaintLayerHaveTransparency");
+ if (flags & kPaintLayerUncachedClipRects)
+ append("kPaintLayerUncachedClipRects");
+ if (flags & kPaintLayerPaintingOverlayScrollbars)
+ append("kPaintLayerPaintingOverlayScrollbars");
+ if (flags & kPaintLayerPaintingCompositingScrollingPhase)
+ append("kPaintLayerPaintingCompositingScrollingPhase");
+ if (flags & kPaintLayerPaintingOverflowContents)
+ append("kPaintLayerPaintingOverflowContents");
+ if (flags & kPaintLayerPaintingSkipRootBackground)
+ append("kPaintLayerPaintingSkipRootBackground");
+ if (flags & kPaintLayerPaintingChildClippingMaskPhase)
+ append("kPaintLayerPaintingChildClippingMaskPhase");
+ if (flags & kPaintLayerPaintingAncestorClippingMaskPhase)
+ append("kPaintLayerPaintingAncestorClippingMaskPhase");
+ if (flags & kPaintLayerPaintingRenderingClipPathAsMask)
+ append("kPaintLayerPaintingRenderingClipPathAsMask");
+ if (flags & kPaintLayerPaintingRenderingResourceSubtree)
+ append("kPaintLayerPaintingRenderingResourceSubtree");
+
+ builder.Append(")");
+ return builder.ToString();
+}
+#endif // DCHECK_IS_ON()
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_PAINT_LAYER_PAINTING_INFO_H_
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc b/chromium/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
index ee72a82c200..a7062dead31 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
@@ -89,12 +89,12 @@
#include "third_party/blink/renderer/core/paint/find_paint_offset_and_visual_rect_needing_update.h"
#include "third_party/blink/renderer/core/paint/paint_invalidator.h"
#include "third_party/blink/renderer/core/paint/paint_layer_fragment.h"
+#include "third_party/blink/renderer/core/scroll/scroll_animator_base.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
+#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/scroll/scroll_alignment.h"
-#include "third_party/blink/renderer/platform/scroll/scroll_animator_base.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h"
-#include "third_party/blink/renderer/platform/scroll/smooth_scroll_sequencer.h"
namespace blink {
@@ -238,7 +238,7 @@ bool PaintLayerScrollableArea::IsThrottled() const {
return GetLayoutBox()->GetFrame()->ShouldThrottleRendering();
}
-PlatformChromeClient* PaintLayerScrollableArea::GetChromeClient() const {
+ChromeClient* PaintLayerScrollableArea::GetChromeClient() const {
if (HasBeenDisposed())
return nullptr;
if (Page* page = GetLayoutBox()->GetFrame()->GetPage())
@@ -250,9 +250,8 @@ SmoothScrollSequencer* PaintLayerScrollableArea::GetSmoothScrollSequencer()
const {
if (HasBeenDisposed())
return nullptr;
- if (Page* page = GetLayoutBox()->GetFrame()->GetPage())
- return page->GetSmoothScrollSequencer();
- return nullptr;
+
+ return &GetLayoutBox()->GetFrame()->GetSmoothScrollSequencer();
}
GraphicsLayer* PaintLayerScrollableArea::LayerForScrolling() const {
@@ -354,7 +353,7 @@ IntRect PaintLayerScrollableArea::ScrollCornerRect() const {
// (b) Both scrollbars are present.
bool has_horizontal_bar = HorizontalScrollbar();
bool has_vertical_bar = VerticalScrollbar();
- bool has_resizer = GetLayoutBox()->Style()->Resize() != EResize::kNone;
+ bool has_resizer = GetLayoutBox()->StyleRef().Resize() != EResize::kNone;
if ((has_horizontal_bar && has_vertical_bar) ||
(has_resizer && (has_horizontal_bar || has_vertical_bar))) {
return CornerRect(GetLayoutBox()->PixelSnappedBorderBoxRect(
@@ -510,18 +509,27 @@ void PaintLayerScrollableArea::UpdateScrollOffset(
void PaintLayerScrollableArea::InvalidatePaintForScrollOffsetChange(
bool offset_was_zero) {
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
- // "background-attachment: local" causes the background of this element to
- // change position due to scroll so a paint invalidation is needed.
- // TODO(pdr): This invalidation can be removed if the local background
- // attachment is painted into the scrolling contents.
- if (ScrollsOverflow() &&
- GetLayoutBox()->Style()->BackgroundLayers().Attachment() ==
- EFillAttachment::kLocal) {
+ InvalidatePaintForStickyDescendants();
+
+ bool requires_paint_invalidation = false;
+
+ // "background-attachment: local" causes the background of this element to
+ // change position due to scroll so a paint invalidation is needed.
+ // TODO(pdr): This invalidation can be removed if the local background
+ // attachment is painted into the scrolling contents.
+ if (ScrollsOverflow() &&
+ GetLayoutBox()->StyleRef().BackgroundLayers().Attachment() ==
+ EFillAttachment::kLocal) {
+ if (!UsesCompositedScrolling())
+ requires_paint_invalidation = true;
+
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
GetLayoutBox()->SetShouldDoFullPaintInvalidation();
return;
}
+ }
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
// TODO(pdr): If this is the root frame, descendants with fixed background
// attachments need to be invalidated.
@@ -538,43 +546,31 @@ void PaintLayerScrollableArea::InvalidatePaintForScrollOffsetChange(
// PaintLayer to just check for interest rect changes instead of doing a
// full repaint.
bool needs_repaint_for_interest_rect = true;
- if (needs_repaint_for_overflow_hidden || needs_repaint_for_interest_rect) {
+ if (needs_repaint_for_overflow_hidden || needs_repaint_for_interest_rect)
Layer()->SetNeedsRepaint();
- return;
- }
return;
}
- bool requires_paint_invalidation = true;
-
LocalFrameView* frame_view = GetLayoutBox()->GetFrameView();
bool is_root_layer = Layer()->IsRootLayer();
- if (GetLayoutBox()->View()->Compositor()->InCompositingMode()) {
- bool only_scrolled_composited_layers =
- ScrollsOverflow() && Layer()->IsAllScrollingContentComposited() &&
- GetLayoutBox()->Style()->BackgroundLayers().Attachment() !=
- EFillAttachment::kLocal;
+ frame_view->InvalidateBackgroundAttachmentFixedDescendants(*GetLayoutBox());
- if (UsesCompositedScrolling() || only_scrolled_composited_layers)
- requires_paint_invalidation = false;
- }
-
- if (requires_paint_invalidation || is_root_layer)
- frame_view->InvalidateBackgroundAttachmentFixedDescendants(*GetLayoutBox());
-
- if (!requires_paint_invalidation && is_root_layer) {
- // Some special invalidations for the root layer.
- if (frame_view->HasViewportConstrainedObjects()) {
- if (!frame_view->InvalidateViewportConstrainedObjects())
- requires_paint_invalidation = true;
- }
- InvalidatePaintForStickyDescendants();
+ if (is_root_layer && frame_view->HasViewportConstrainedObjects() &&
+ !frame_view->InvalidateViewportConstrainedObjects()) {
+ requires_paint_invalidation = true;
}
if (requires_paint_invalidation) {
GetLayoutBox()->SetShouldDoFullPaintInvalidation();
- GetLayoutBox()->SetMayNeedPaintInvalidationSubtree();
+ GetLayoutBox()->SetSubtreeShouldCheckForPaintInvalidation();
+ } else if (!UsesCompositedScrolling()) {
+ // If any scrolling content might have ben clipped by a cull rect, then
+ // that cull rect could be affected by scroll offset. For composited
+ // scrollers, this will be taken care of by the interest rect computation
+ // in CompositedLayerMapping.
+ // TODO(chrishtr): replace this shortcut with interest rects.
+ Layer()->SetNeedsRepaint();
}
}
@@ -681,13 +677,22 @@ LayoutRect PaintLayerScrollableArea::VisibleScrollSnapportRect(
}
IntSize PaintLayerScrollableArea::ContentsSize() const {
- return IntSize(PixelSnappedScrollWidth(), PixelSnappedScrollHeight());
+ LayoutPoint offset(
+ GetLayoutBox()->ClientLeft() + GetLayoutBox()->Location().X(),
+ GetLayoutBox()->ClientTop() + GetLayoutBox()->Location().Y());
+ return PixelSnappedContentsSize(offset);
+}
+
+IntSize PaintLayerScrollableArea::PixelSnappedContentsSize(
+ const LayoutPoint& paint_offset) const {
+ return PixelSnappedIntSize(overflow_rect_.Size(), paint_offset);
}
void PaintLayerScrollableArea::ContentsResized() {
ScrollableArea::ContentsResized();
// Need to update the bounds of the scroll property.
GetLayoutBox()->SetNeedsPaintPropertyUpdate();
+ Layer()->SetNeedsCompositingInputsUpdate();
}
IntPoint PaintLayerScrollableArea::LastKnownMousePosition() const {
@@ -797,8 +802,8 @@ bool PaintLayerScrollableArea::UserInputScrollable(
}
EOverflow overflow_style = (orientation == kHorizontalScrollbar)
- ? GetLayoutBox()->Style()->OverflowX()
- : GetLayoutBox()->Style()->OverflowY();
+ ? GetLayoutBox()->StyleRef().OverflowX()
+ : GetLayoutBox()->StyleRef().OverflowY();
return (overflow_style == EOverflow::kScroll ||
overflow_style == EOverflow::kAuto ||
overflow_style == EOverflow::kOverlay);
@@ -838,16 +843,6 @@ LayoutUnit PaintLayerScrollableArea::ScrollHeight() const {
return overflow_rect_.Height();
}
-int PaintLayerScrollableArea::PixelSnappedScrollWidth() const {
- return SnapSizeToPixel(ScrollWidth(), GetLayoutBox()->ClientLeft() +
- GetLayoutBox()->Location().X());
-}
-
-int PaintLayerScrollableArea::PixelSnappedScrollHeight() const {
- return SnapSizeToPixel(ScrollHeight(), GetLayoutBox()->ClientTop() +
- GetLayoutBox()->Location().Y());
-}
-
void PaintLayerScrollableArea::UpdateScrollOrigin() {
// This should do nothing prior to first layout; the if-clause will catch
// that.
@@ -950,6 +945,19 @@ void PaintLayerScrollableArea::UpdateAfterLayout() {
SetHasHorizontalScrollbar(needs_horizontal_scrollbar);
SetHasVerticalScrollbar(needs_vertical_scrollbar);
+ // If we change scrollbars on the layout viewport, the visual viewport
+ // needs to update paint properties to account for the correct
+ // scrollbounds.
+ if (LocalFrameView* frame_view = GetLayoutBox()->GetFrameView()) {
+ if (this == frame_view->LayoutViewport()) {
+ GetLayoutBox()
+ ->GetFrame()
+ ->GetPage()
+ ->GetVisualViewport()
+ .SetNeedsPaintPropertiesUpdate();
+ }
+ }
+
if (HasScrollbar())
UpdateScrollCornerStyle();
@@ -960,46 +968,47 @@ void PaintLayerScrollableArea::UpdateAfterLayout() {
GetLayoutBox()->GetDocument().SetAnnotatedRegionsDirty(true);
// Our proprietary overflow: overlay value doesn't trigger a layout.
- // If the box is managed by LayoutNG, don't go here. We don't want to
- // re-enter the NG layout algorithm for this box from here.
if (((horizontal_scrollbar_should_change &&
- GetLayoutBox()->Style()->OverflowX() != EOverflow::kOverlay) ||
+ GetLayoutBox()->StyleRef().OverflowX() != EOverflow::kOverlay) ||
(vertical_scrollbar_should_change &&
- GetLayoutBox()->Style()->OverflowY() != EOverflow::kOverlay)) &&
- !IsManagedByLayoutNG(*GetLayoutBox())) {
+ GetLayoutBox()->StyleRef().OverflowY() != EOverflow::kOverlay))) {
if ((vertical_scrollbar_should_change &&
GetLayoutBox()->IsHorizontalWritingMode()) ||
(horizontal_scrollbar_should_change &&
!GetLayoutBox()->IsHorizontalWritingMode())) {
GetLayoutBox()->SetPreferredLogicalWidthsDirty();
}
- if (PreventRelayoutScope::RelayoutIsPrevented()) {
- // We're not doing re-layout right now, but we still want to
- // add the scrollbar to the logical width now, to facilitate parent
- // layout.
- GetLayoutBox()->UpdateLogicalWidth();
- PreventRelayoutScope::SetBoxNeedsLayout(*this, had_horizontal_scrollbar,
- had_vertical_scrollbar);
- } else {
- in_overflow_relayout_ = true;
- SubtreeLayoutScope layout_scope(*GetLayoutBox());
- layout_scope.SetNeedsLayout(
- GetLayoutBox(), LayoutInvalidationReason::kScrollbarChanged);
- if (GetLayoutBox()->IsLayoutBlock()) {
- LayoutBlock* block = ToLayoutBlock(GetLayoutBox());
- block->ScrollbarsChanged(horizontal_scrollbar_should_change,
- vertical_scrollbar_should_change);
- block->UpdateBlockLayout(true);
+ // If the box is managed by LayoutNG, don't go here. We don't want to
+ // re-enter the NG layout algorithm for this box from here.
+ if (!IsManagedByLayoutNG(*GetLayoutBox())) {
+ if (PreventRelayoutScope::RelayoutIsPrevented()) {
+ // We're not doing re-layout right now, but we still want to
+ // add the scrollbar to the logical width now, to facilitate parent
+ // layout.
+ GetLayoutBox()->UpdateLogicalWidth();
+ PreventRelayoutScope::SetBoxNeedsLayout(
+ *this, had_horizontal_scrollbar, had_vertical_scrollbar);
} else {
- GetLayoutBox()->UpdateLayout();
+ in_overflow_relayout_ = true;
+ SubtreeLayoutScope layout_scope(*GetLayoutBox());
+ layout_scope.SetNeedsLayout(
+ GetLayoutBox(), LayoutInvalidationReason::kScrollbarChanged);
+ if (GetLayoutBox()->IsLayoutBlock()) {
+ LayoutBlock* block = ToLayoutBlock(GetLayoutBox());
+ block->ScrollbarsChanged(horizontal_scrollbar_should_change,
+ vertical_scrollbar_should_change);
+ block->UpdateBlockLayout(true);
+ } else {
+ GetLayoutBox()->UpdateLayout();
+ }
+ in_overflow_relayout_ = false;
+ scrollbar_manager_.DestroyDetachedScrollbars();
+ }
+ LayoutObject* parent = GetLayoutBox()->Parent();
+ if (parent && parent->IsFlexibleBox()) {
+ ToLayoutFlexibleBox(parent)->ClearCachedMainSizeForChild(
+ *GetLayoutBox());
}
- in_overflow_relayout_ = false;
- scrollbar_manager_.DestroyDetachedScrollbars();
- }
- LayoutObject* parent = GetLayoutBox()->Parent();
- if (parent && parent->IsFlexibleBox()) {
- ToLayoutFlexibleBox(parent)->ClearCachedMainSizeForChild(
- *GetLayoutBox());
}
}
}
@@ -1082,7 +1091,8 @@ void PaintLayerScrollableArea::DidChangeGlobalRootScroller() {
bool PaintLayerScrollableArea::ShouldPerformScrollAnchoring() const {
return scroll_anchor_.HasScroller() && GetLayoutBox() &&
- GetLayoutBox()->Style()->OverflowAnchor() != EOverflowAnchor::kNone &&
+ GetLayoutBox()->StyleRef().OverflowAnchor() !=
+ EOverflowAnchor::kNone &&
!GetLayoutBox()->GetDocument().FinishingOrIsPrinting();
}
@@ -1109,7 +1119,7 @@ PaintLayerScrollableArea::GetTimerTaskRunner() const {
}
ScrollBehavior PaintLayerScrollableArea::ScrollBehaviorStyle() const {
- return GetLayoutBox()->Style()->GetScrollBehavior();
+ return GetLayoutBox()->StyleRef().GetScrollBehavior();
}
bool PaintLayerScrollableArea::HasHorizontalOverflow() const {
@@ -1168,7 +1178,7 @@ void PaintLayerScrollableArea::UpdateAfterStyleChange(
old_background =
old_style->VisitedDependentColor(GetCSSPropertyBackgroundColor());
}
- Color new_background = GetLayoutBox()->Style()->VisitedDependentColor(
+ Color new_background = GetLayoutBox()->StyleRef().VisitedDependentColor(
GetCSSPropertyBackgroundColor());
if (new_background != old_background) {
@@ -1203,13 +1213,13 @@ void PaintLayerScrollableArea::UpdateAfterStyleChange(
// When switching to another value, we need to re-enable them (see bug 11985).
if (HasHorizontalScrollbar() && old_style &&
old_style->OverflowX() == EOverflow::kScroll &&
- GetLayoutBox()->Style()->OverflowX() != EOverflow::kScroll) {
+ GetLayoutBox()->StyleRef().OverflowX() != EOverflow::kScroll) {
HorizontalScrollbar()->SetEnabled(true);
}
if (HasVerticalScrollbar() && old_style &&
old_style->OverflowY() == EOverflow::kScroll &&
- GetLayoutBox()->Style()->OverflowY() != EOverflow::kScroll) {
+ GetLayoutBox()->StyleRef().OverflowY() != EOverflow::kScroll) {
VerticalScrollbar()->SetEnabled(true);
}
@@ -1225,10 +1235,6 @@ void PaintLayerScrollableArea::UpdateAfterStyleChange(
UpdateResizerStyle(old_style);
}
-void PaintLayerScrollableArea::UpdateAfterCompositingChange() {
- Layer()->UpdateScrollingStateAfterCompositingChange();
-}
-
void PaintLayerScrollableArea::UpdateAfterOverflowRecalc() {
UpdateScrollDimensions();
UpdateScrollbarProportions();
@@ -1344,13 +1350,13 @@ static inline const LayoutObject& ScrollbarStyleSource(
// can scroll.
Element* body = doc.body();
if (body && body->GetLayoutObject() && body->GetLayoutObject()->IsBox() &&
- body->GetLayoutObject()->Style()->HasPseudoStyle(kPseudoIdScrollbar))
+ body->GetLayoutObject()->StyleRef().HasPseudoStyle(kPseudoIdScrollbar))
return *body->GetLayoutObject();
// If the <body> didn't have a custom style, then the root element might.
Element* doc_element = doc.documentElement();
if (doc_element && doc_element->GetLayoutObject() &&
- doc_element->GetLayoutObject()->Style()->HasPseudoStyle(
+ doc_element->GetLayoutObject()->StyleRef().HasPseudoStyle(
kPseudoIdScrollbar))
return *doc_element->GetLayoutObject();
}
@@ -1589,7 +1595,7 @@ int PaintLayerScrollableArea::VerticalScrollbarWidth(
return 0;
if (overlay_scrollbar_clip_behavior ==
kIgnorePlatformAndCSSOverlayScrollbarSize &&
- GetLayoutBox()->Style()->OverflowY() == EOverflow::kOverlay) {
+ GetLayoutBox()->StyleRef().OverflowY() == EOverflow::kOverlay) {
return 0;
}
if ((overlay_scrollbar_clip_behavior == kIgnorePlatformOverlayScrollbarSize ||
@@ -1608,7 +1614,7 @@ int PaintLayerScrollableArea::HorizontalScrollbarHeight(
return 0;
if (overlay_scrollbar_clip_behavior ==
kIgnorePlatformAndCSSOverlayScrollbarSize &&
- GetLayoutBox()->Style()->OverflowX() == EOverflow::kOverlay) {
+ GetLayoutBox()->StyleRef().OverflowX() == EOverflow::kOverlay) {
return 0;
}
if ((overlay_scrollbar_clip_behavior == kIgnorePlatformOverlayScrollbarSize ||
@@ -1693,7 +1699,7 @@ bool PaintLayerScrollableArea::HitTestOverflowControls(
return false;
IntRect resize_control_rect;
- if (GetLayoutBox()->Style()->Resize() != EResize::kNone) {
+ if (GetLayoutBox()->StyleRef().Resize() != EResize::kNone) {
resize_control_rect =
ResizerCornerRect(GetLayoutBox()->PixelSnappedBorderBoxRect(
Layer()->SubpixelAccumulation()),
@@ -1749,7 +1755,7 @@ bool PaintLayerScrollableArea::HitTestOverflowControls(
IntRect PaintLayerScrollableArea::ResizerCornerRect(
const IntRect& bounds,
ResizerHitTestType resizer_hit_test_type) const {
- if (GetLayoutBox()->Style()->Resize() == EResize::kNone)
+ if (GetLayoutBox()->StyleRef().Resize() == EResize::kNone)
return IntRect();
IntRect corner = CornerRect(bounds);
@@ -1860,7 +1866,7 @@ void PaintLayerScrollableArea::UpdateResizerStyle(
void PaintLayerScrollableArea::InvalidateAllStickyConstraints() {
if (PaintLayerScrollableAreaRareData* d = RareData()) {
for (PaintLayer* sticky_layer : d->sticky_constraints_map_.Keys()) {
- if (sticky_layer->GetLayoutObject().Style()->GetPosition() ==
+ if (sticky_layer->GetLayoutObject().StyleRef().GetPosition() ==
EPosition::kSticky)
sticky_layer->SetNeedsCompositingInputsUpdate();
}
@@ -1874,7 +1880,7 @@ void PaintLayerScrollableArea::InvalidateStickyConstraintsFor(
if (PaintLayerScrollableAreaRareData* d = RareData()) {
d->sticky_constraints_map_.erase(layer);
if (needs_compositing_update &&
- layer->GetLayoutObject().Style()->HasStickyConstrainedPosition())
+ layer->GetLayoutObject().StyleRef().HasStickyConstrainedPosition())
layer->SetNeedsCompositingInputsUpdate();
}
}
@@ -1897,10 +1903,8 @@ bool PaintLayerScrollableArea::HasNonCompositedStickyDescendants() const {
void PaintLayerScrollableArea::InvalidatePaintForStickyDescendants() {
if (PaintLayerScrollableAreaRareData* d = RareData()) {
- for (PaintLayer* sticky_layer : d->sticky_constraints_map_.Keys()) {
- sticky_layer->GetLayoutObject()
- .SetShouldDoFullPaintInvalidationIncludingNonCompositingDescendants();
- }
+ for (PaintLayer* sticky_layer : d->sticky_constraints_map_.Keys())
+ sticky_layer->GetLayoutObject().SetShouldCheckForPaintInvalidation();
}
}
@@ -1945,7 +1949,7 @@ void PaintLayerScrollableArea::Resize(const IntPoint& pos,
Document& document = element->GetDocument();
- float zoom_factor = GetLayoutBox()->Style()->EffectiveZoom();
+ float zoom_factor = GetLayoutBox()->StyleRef().EffectiveZoom();
IntSize new_offset =
OffsetFromResizeCorner(document.View()->ConvertFromRootFrame(pos));
@@ -1967,9 +1971,9 @@ void PaintLayerScrollableArea::Resize(const IntPoint& pos,
current_size);
bool is_box_sizing_border =
- GetLayoutBox()->Style()->BoxSizing() == EBoxSizing::kBorderBox;
+ GetLayoutBox()->StyleRef().BoxSizing() == EBoxSizing::kBorderBox;
- EResize resize = GetLayoutBox()->Style()->Resize();
+ EResize resize = GetLayoutBox()->StyleRef().Resize();
if (resize != EResize::kVertical && difference.Width()) {
if (element->IsFormControlElement()) {
// Make implicit margins from the theme explicit (see
@@ -2048,7 +2052,7 @@ LayoutRect PaintLayerScrollableArea::ScrollIntoView(
params.GetScrollType() == kUserScroll);
ScrollBehavior behavior =
DetermineScrollBehavior(params.GetScrollBehavior(),
- GetLayoutBox()->Style()->GetScrollBehavior());
+ GetLayoutBox()->StyleRef().GetScrollBehavior());
GetSmoothScrollSequencer()->QueueAnimation(this, new_scroll_offset,
behavior);
} else {
@@ -2089,7 +2093,8 @@ void PaintLayerScrollableArea::UpdateScrollableAreaSet() {
((HasHorizontalOverflow() && GetLayoutBox()->ScrollsOverflowX()) ||
(HasVerticalOverflow() && GetLayoutBox()->ScrollsOverflowY()));
- bool is_visible_to_hit_test = GetLayoutBox()->Style()->VisibleToHitTesting();
+ bool is_visible_to_hit_test =
+ GetLayoutBox()->StyleRef().VisibleToHitTesting();
bool did_scroll_overflow = scrolls_overflow_;
if (GetLayoutBox()->IsLayoutView()) {
ScrollbarMode h_mode;
@@ -2238,13 +2243,12 @@ bool PaintLayerScrollableArea::ComputeNeedsCompositedScrolling(
// TODO(flackr): Allow integer transforms as long as all of the ancestor
// transforms are also integer.
bool background_supports_lcd_text =
- RuntimeEnabledFeatures::CompositeOpaqueScrollersEnabled() &&
- layer->GetLayoutObject().Style()->IsStackingContext() &&
+ layer->GetLayoutObject().StyleRef().IsStackingContext() &&
layer->GetBackgroundPaintLocation(
&non_composited_main_thread_scrolling_reasons_) &
kBackgroundPaintInScrollingContents &&
layer->BackgroundIsKnownToBeOpaqueInRect(
- ToLayoutBox(layer->GetLayoutObject()).PaddingBoxRect()) &&
+ ToLayoutBox(layer->GetLayoutObject()).PhysicalPaddingBoxRect()) &&
!layer->CompositesWithTransform() && !layer->CompositesWithOpacity();
// TODO(crbug.com/839341): Remove ScrollTimeline check once we support
@@ -2262,11 +2266,11 @@ bool PaintLayerScrollableArea::ComputeNeedsCompositedScrolling(
MainThreadScrollingReason::kHasTransformAndLCDText;
}
if (!layer->BackgroundIsKnownToBeOpaqueInRect(
- ToLayoutBox(layer->GetLayoutObject()).PaddingBoxRect())) {
+ ToLayoutBox(layer->GetLayoutObject()).PhysicalPaddingBoxRect())) {
non_composited_main_thread_scrolling_reasons_ |=
MainThreadScrollingReason::kBackgroundNotOpaqueInRectAndLCDText;
}
- if (!layer->GetLayoutObject().Style()->IsStackingContext()) {
+ if (!layer->GetLayoutObject().StyleRef().IsStackingContext()) {
non_composited_main_thread_scrolling_reasons_ |=
MainThreadScrollingReason::kIsNotStackingContextAndLCDText;
}
@@ -2314,7 +2318,7 @@ bool PaintLayerScrollableArea::VisualViewportSuppliesScrollbars() const {
}
bool PaintLayerScrollableArea::ScheduleAnimation() {
- if (ChromeClient* client = ToChromeClient(GetChromeClient())) {
+ if (ChromeClient* client = GetChromeClient()) {
client->ScheduleAnimation(GetLayoutBox()->GetFrame()->View());
return true;
}
@@ -2784,7 +2788,7 @@ void PaintLayerScrollableArea::SetScrollCornerAndResizerVisualRect(
}
void PaintLayerScrollableArea::ScrollControlWasSetNeedsPaintInvalidation() {
- GetLayoutBox()->SetMayNeedPaintInvalidation();
+ GetLayoutBox()->SetShouldCheckForPaintInvalidation();
}
void PaintLayerScrollableArea::DidScrollWithScrollbar(
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 e0190ee92a5..4dc348ced67 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
@@ -50,9 +50,9 @@
#include "third_party/blink/renderer/core/layout/scroll_anchor.h"
#include "third_party/blink/renderer/core/page/scrolling/sticky_position_scrolling_constraints.h"
#include "third_party/blink/renderer/core/paint/paint_layer_fragment.h"
+#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/scroll/scroll_types.h"
-#include "third_party/blink/renderer/platform/scroll/scrollable_area.h"
namespace blink {
@@ -65,7 +65,6 @@ class LayoutScrollbarPart;
struct PaintInvalidatorContext;
class PaintLayer;
class ScrollingCoordinator;
-class StickyPositionScrollingConstraints;
class SubtreeLayoutScope;
struct CORE_EXPORT PaintLayerScrollableAreaRareData {
@@ -263,7 +262,7 @@ class CORE_EXPORT PaintLayerScrollableArea final
}
bool IsThrottled() const override;
- PlatformChromeClient* GetChromeClient() const override;
+ ChromeClient* GetChromeClient() const override;
SmoothScrollSequencer* GetSmoothScrollSequencer() const override;
@@ -318,6 +317,11 @@ class CORE_EXPORT PaintLayerScrollableArea final
LayoutRect VisibleScrollSnapportRect(
IncludeScrollbarsInRect = kExcludeScrollbars) const override;
IntSize ContentsSize() const override;
+
+ // Similar to |ContentsSize| but snapped considering |paint_offset| which can
+ // have subpixel accumulation.
+ IntSize PixelSnappedContentsSize(const LayoutPoint& paint_offset) const;
+
void ContentsResized() override;
IntPoint LastKnownMousePosition() const override;
bool ScrollAnimatorEnabled() const override;
@@ -373,8 +377,6 @@ class CORE_EXPORT PaintLayerScrollableArea final
void UpdateAfterStyleChange(const ComputedStyle*);
void UpdateAfterOverflowRecalc();
- void UpdateAfterCompositingChange();
-
bool HasScrollbar() const {
return HasHorizontalScrollbar() || HasVerticalScrollbar();
}
@@ -397,8 +399,6 @@ class CORE_EXPORT PaintLayerScrollableArea final
LayoutUnit ScrollWidth() const;
LayoutUnit ScrollHeight() const;
- int PixelSnappedScrollWidth() const;
- int PixelSnappedScrollHeight() const;
int VerticalScrollbarWidth(
OverlayScrollbarClipBehavior =
@@ -542,14 +542,14 @@ class CORE_EXPORT PaintLayerScrollableArea final
bool VisualViewportSuppliesScrollbars() const override;
+ bool HasHorizontalOverflow() const;
+ bool HasVerticalOverflow() const;
+
void Trace(blink::Visitor*) override;
private:
explicit PaintLayerScrollableArea(PaintLayer&);
- bool HasHorizontalOverflow() const;
- bool HasVerticalOverflow() const;
-
bool NeedsScrollbarReconstruction() const;
void ResetScrollOriginChanged() { scroll_origin_changed_ = false; }
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 4d989ee50b1..bde7ecf39d4 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,10 +8,10 @@
#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/paint/paint_layer.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme.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/scroll/scroll_types.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h"
using testing::_;
@@ -154,9 +154,9 @@ TEST_F(PaintLayerScrollableAreaTest,
</div>
)HTML");
- // #scroller1 cannot paint background into scrolling contents layer because it
- // has a negative z-index child.
- EXPECT_EQ(kBackgroundPaintInGraphicsLayer,
+ // #scroller1 can paint background into scrolling contents layer even with a
+ // negative z-index child.
+ EXPECT_EQ(kBackgroundPaintInScrollingContents,
GetBackgroundPaintLocation("scroller1"));
// #scroller2 cannot paint background into scrolling contents layer because it
@@ -249,8 +249,6 @@ TEST_F(PaintLayerScrollableAreaTest,
}
TEST_F(PaintLayerScrollableAreaTest, OpaqueContainedLayersPromoted) {
- ScopedCompositeOpaqueScrollersForTest composite_opaque_scrollers(true);
-
SetBodyInnerHTML(R"HTML(
<style>
#scroller { overflow: scroll; height: 200px; width: 200px;
@@ -262,7 +260,6 @@ TEST_F(PaintLayerScrollableAreaTest, OpaqueContainedLayersPromoted) {
)HTML");
GetDocument().View()->UpdateAllLifecyclePhases();
- EXPECT_TRUE(RuntimeEnabledFeatures::CompositeOpaqueScrollersEnabled());
Element* scroller = GetDocument().getElementById("scroller");
PaintLayer* paint_layer =
ToLayoutBoxModelObject(scroller->GetLayoutObject())->Layer();
@@ -276,8 +273,6 @@ TEST_F(PaintLayerScrollableAreaTest, OpaqueContainedLayersPromoted) {
// Promoting the scroller would also require promoting the positioned div
// which would lose subpixel anti-aliasing due to its transparent background.
TEST_F(PaintLayerScrollableAreaTest, NonContainedLayersNotPromoted) {
- ScopedCompositeOpaqueScrollersForTest composite_opaque_scrollers(true);
-
SetBodyInnerHTML(R"HTML(
<style>
#scroller { overflow: scroll; height: 200px; width: 200px;
@@ -293,7 +288,6 @@ TEST_F(PaintLayerScrollableAreaTest, NonContainedLayersNotPromoted) {
)HTML");
GetDocument().View()->UpdateAllLifecyclePhases();
- EXPECT_TRUE(RuntimeEnabledFeatures::CompositeOpaqueScrollersEnabled());
Element* scroller = GetDocument().getElementById("scroller");
PaintLayer* paint_layer =
ToLayoutBoxModelObject(scroller->GetLayoutObject())->Layer();
@@ -303,8 +297,6 @@ TEST_F(PaintLayerScrollableAreaTest, NonContainedLayersNotPromoted) {
}
TEST_F(PaintLayerScrollableAreaTest, TransparentLayersNotPromoted) {
- ScopedCompositeOpaqueScrollersForTest composite_opaque_scrollers(true);
-
SetBodyInnerHTML(R"HTML(
<style>
#scroller { overflow: scroll; height: 200px; width: 200px; background:
@@ -316,7 +308,6 @@ TEST_F(PaintLayerScrollableAreaTest, TransparentLayersNotPromoted) {
)HTML");
GetDocument().View()->UpdateAllLifecyclePhases();
- EXPECT_TRUE(RuntimeEnabledFeatures::CompositeOpaqueScrollersEnabled());
Element* scroller = GetDocument().getElementById("scroller");
PaintLayer* paint_layer =
ToLayoutBoxModelObject(scroller->GetLayoutObject())->Layer();
@@ -326,8 +317,6 @@ TEST_F(PaintLayerScrollableAreaTest, TransparentLayersNotPromoted) {
}
TEST_F(PaintLayerScrollableAreaTest, OpaqueLayersDepromotedOnStyleChange) {
- ScopedCompositeOpaqueScrollersForTest composite_opaque_scrollers(true);
-
SetBodyInnerHTML(R"HTML(
<style>
#scroller { overflow: scroll; height: 200px; width: 200px; background:
@@ -338,7 +327,6 @@ TEST_F(PaintLayerScrollableAreaTest, OpaqueLayersDepromotedOnStyleChange) {
)HTML");
GetDocument().View()->UpdateAllLifecyclePhases();
- EXPECT_TRUE(RuntimeEnabledFeatures::CompositeOpaqueScrollersEnabled());
Element* scroller = GetDocument().getElementById("scroller");
PaintLayer* paint_layer =
ToLayoutBoxModelObject(scroller->GetLayoutObject())->Layer();
@@ -357,8 +345,6 @@ TEST_F(PaintLayerScrollableAreaTest, OpaqueLayersDepromotedOnStyleChange) {
}
TEST_F(PaintLayerScrollableAreaTest, OpaqueLayersPromotedOnStyleChange) {
- ScopedCompositeOpaqueScrollersForTest composite_opaque_scrollers(true);
-
SetBodyInnerHTML(R"HTML(
<style>
#scroller { overflow: scroll; height: 200px; width: 200px; background:
@@ -369,14 +355,13 @@ TEST_F(PaintLayerScrollableAreaTest, OpaqueLayersPromotedOnStyleChange) {
)HTML");
GetDocument().View()->UpdateAllLifecyclePhases();
- EXPECT_TRUE(RuntimeEnabledFeatures::CompositeOpaqueScrollersEnabled());
Element* scroller = GetDocument().getElementById("scroller");
PaintLayer* paint_layer =
ToLayoutBoxModelObject(scroller->GetLayoutObject())->Layer();
ASSERT_TRUE(paint_layer);
EXPECT_FALSE(paint_layer->NeedsCompositedScrolling());
- // Change the background to transparent
+ // Change the background to opaque
scroller->setAttribute(HTMLNames::styleAttr,
"background: white local content-box;");
GetDocument().View()->UpdateAllLifecyclePhases();
@@ -392,8 +377,6 @@ TEST_F(PaintLayerScrollableAreaTest, OpaqueLayersPromotedOnStyleChange) {
// TODO(flackr): Allow integer transforms as long as all of the ancestor
// transforms are also integer.
TEST_F(PaintLayerScrollableAreaTest, OnlyNonTransformedOpaqueLayersPromoted) {
- ScopedCompositeOpaqueScrollersForTest composite_opaque_scrollers(true);
-
SetBodyInnerHTML(R"HTML(
<style>
#scroller { overflow: scroll; height: 200px; width: 200px; background:
@@ -406,7 +389,6 @@ TEST_F(PaintLayerScrollableAreaTest, OnlyNonTransformedOpaqueLayersPromoted) {
)HTML");
GetDocument().View()->UpdateAllLifecyclePhases();
- EXPECT_TRUE(RuntimeEnabledFeatures::CompositeOpaqueScrollersEnabled());
Element* parent = GetDocument().getElementById("parent");
Element* scroller = GetDocument().getElementById("scroller");
PaintLayer* paint_layer =
@@ -447,8 +429,6 @@ TEST_F(PaintLayerScrollableAreaTest, OnlyNonTransformedOpaqueLayersPromoted) {
// Test that opacity applied to the scroller or an ancestor will cause the
// scrolling contents layer to not be promoted.
TEST_F(PaintLayerScrollableAreaTest, OnlyOpaqueLayersPromoted) {
- ScopedCompositeOpaqueScrollersForTest composite_opaque_scrollers(true);
-
SetBodyInnerHTML(R"HTML(
<style>
#scroller { overflow: scroll; height: 200px; width: 200px; background:
@@ -461,7 +441,6 @@ TEST_F(PaintLayerScrollableAreaTest, OnlyOpaqueLayersPromoted) {
)HTML");
GetDocument().View()->UpdateAllLifecyclePhases();
- EXPECT_TRUE(RuntimeEnabledFeatures::CompositeOpaqueScrollersEnabled());
Element* parent = GetDocument().getElementById("parent");
Element* scroller = GetDocument().getElementById("scroller");
PaintLayer* paint_layer =
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 a4e23b70397..c004c6bef6e 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_phase.h
+++ b/chromium/third_party/blink/renderer/core/paint/paint_phase.h
@@ -49,7 +49,7 @@ enum class PaintPhase {
kBlockBackground = 0,
//
// The following two values are added besides the normal
- // PaintPhaseBlockBackground to distinguish backgrounds for the object itself
+ // kBlockBackground to distinguish backgrounds for the object itself
// and for descendants, because the two backgrounds are often painted with
// different scroll offsets and clips.
//
@@ -57,8 +57,8 @@ enum class PaintPhase {
kSelfBlockBackgroundOnly = 1,
// Paint backgrounds of non-self-painting descendants only. The painter should
// call each non-self-painting child's paint method by passing
- // paintInfo.forDescendants() which converts
- // PaintPhaseDescendantsBlockBackgroundsOnly to PaintPhaseBlockBackground.
+ // paintInfo.forDescendants() which converts kDescendantBlockBackgroundsOnly
+ // to kBlockBackground.
kDescendantBlockBackgroundsOnly = 2,
// Float phase
@@ -79,8 +79,8 @@ enum class PaintPhase {
kSelfOutlineOnly = 6,
// Paint outlines of non-self-painting descendants only. The painter should
// call each non-self-painting child's paint method by passing
- // paintInfo.forDescendants() which
- // converts PaintPhaseDescendantsOutlinesOnly to PaintPhaseBlockOutline.
+ // paintInfo.forDescendants() which converts kDescendantOutlinesOnly to
+ // kOutline.
kDescendantOutlinesOnly = 7,
// The below are auxiliary phases which are used to paint special effects.
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 b1a44f09e08..2f681f511b0 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
@@ -7,6 +7,7 @@
#include <memory>
#include "third_party/blink/renderer/core/animation/scroll_timeline.h"
#include "third_party/blink/renderer/core/dom/dom_node_ids.h"
+#include "third_party/blink/renderer/core/frame/link_highlights.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"
@@ -24,6 +25,7 @@
#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/page/page.h"
+#include "third_party/blink/renderer/core/page/scrolling/snap_coordinator.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/compositing/compositing_reason_finder.h"
@@ -35,6 +37,8 @@
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
#include "third_party/blink/renderer/core/paint/paint_property_tree_printer.h"
#include "third_party/blink/renderer/core/paint/svg_root_painter.h"
+#include "third_party/blink/renderer/platform/graphics/bitmap_image.h"
+#include "third_party/blink/renderer/platform/scroll/overscroll_behavior.h"
#include "third_party/blink/renderer/platform/transforms/transform_state.h"
#include "third_party/blink/renderer/platform/transforms/transformation_matrix.h"
@@ -59,8 +63,7 @@ void VisualViewportPaintPropertyTreeBuilder::Update(
PaintPropertyTreeBuilderFragmentContext& context = full_context.fragments[0];
- visual_viewport.UpdatePaintPropertyNodes(context.current.transform,
- context.current.scroll);
+ visual_viewport.UpdatePaintPropertyNodesIfNeeded(context);
context.current.transform = visual_viewport.GetScrollTranslationNode();
context.absolute_position.transform =
@@ -134,6 +137,7 @@ class FragmentPaintPropertyTreeBuilder {
ALWAYS_INLINE void UpdateTransform();
ALWAYS_INLINE void UpdateTransformForNonRootSVG();
ALWAYS_INLINE void UpdateEffect();
+ ALWAYS_INLINE void UpdateLinkHighlightEffect();
ALWAYS_INLINE void UpdateFilter();
ALWAYS_INLINE void UpdateFragmentClip();
ALWAYS_INLINE void UpdateCssClip();
@@ -144,7 +148,7 @@ class FragmentPaintPropertyTreeBuilder {
ALWAYS_INLINE void UpdateInnerBorderRadiusClip();
ALWAYS_INLINE void UpdateOverflowClip();
ALWAYS_INLINE void UpdatePerspective();
- ALWAYS_INLINE void UpdateSvgLocalToBorderBoxTransform();
+ ALWAYS_INLINE void UpdateReplacedContentTransform();
ALWAYS_INLINE void UpdateScrollAndScrollTranslation();
ALWAYS_INLINE void UpdateOutOfFlowContext();
@@ -185,23 +189,39 @@ class FragmentPaintPropertyTreeBuilder {
bool property_added_or_removed_ = false;
};
+static bool IsRootScroller(const LayoutBox& box) {
+ auto* scrollable_area = box.GetScrollableArea();
+ DCHECK(scrollable_area);
+ auto* layer = scrollable_area->Layer();
+ return layer &&
+ CompositingReasonFinder::RequiresCompositingForRootScroller(*layer);
+}
+
+static bool HasScrollsOverflow(const LayoutBox& box) {
+ // TODO(crbug.com/839341): Remove ScrollTimeline check once we support
+ // main-thread AnimationWorklet and don't need to promote the scroll-source.
+ return box.GetScrollableArea()->ScrollsOverflow() ||
+ ScrollTimeline::HasActiveScrollTimeline(box.GetNode());
+}
+
static bool NeedsScrollNode(const LayoutObject& object) {
if (!object.HasOverflowClip())
return false;
- // TODO(crbug.com/839341): Remove ScrollTimeline check once we support
- // main-thread AnimationWorklet and don't need to promote the scroll-source.
- return ToLayoutBox(object).GetScrollableArea()->ScrollsOverflow() ||
- ScrollTimeline::HasActiveScrollTimeline(object.GetNode());
+ const LayoutBox& box = ToLayoutBox(object);
+ // TODO(pdr): SPV2 has invalidation issues (crbug.com/732611) as well as
+ // subpixel issues (crbug.com/693741) which prevent us from compositing the
+ // root scroller.
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ return HasScrollsOverflow(box);
+ return HasScrollsOverflow(box) || IsRootScroller(box);
}
static CompositingReasons CompositingReasonsForScroll(const LayoutBox& box) {
CompositingReasons compositing_reasons = CompositingReason::kNone;
- if (auto* scrollable_area = box.GetScrollableArea()) {
- if (auto* layer = scrollable_area->Layer()) {
- if (CompositingReasonFinder::RequiresCompositingForRootScroller(*layer))
- compositing_reasons |= CompositingReason::kRootScroller;
- }
- }
+
+ if (IsRootScroller(box))
+ compositing_reasons |= CompositingReason::kRootScroller;
+
// TODO(pdr): Set other compositing reasons for scroll here, see:
// PaintLayerScrollableArea::ComputeNeedsCompositedScrolling.
return compositing_reasons;
@@ -217,8 +237,26 @@ static bool NeedsScrollOrScrollTranslation(const LayoutObject& object) {
return !scroll_offset.IsZero() || NeedsScrollNode(object);
}
-static bool NeedsSVGLocalToBorderBoxTransform(const LayoutObject& object) {
- return object.IsSVGRoot();
+static bool NeedsReplacedContentTransform(const LayoutObject& object) {
+ // Quick reject.
+ if (!object.IsLayoutReplaced())
+ return false;
+
+ if (object.IsSVGRoot())
+ return true;
+
+ // Only directly composited images need a transform node to scale contents
+ // to the object-fit box. Note that we don't actually know whether the image
+ // will be directly composited. This condition is relaxed to stay on the
+ // safe side.
+ // TODO(crbug.com/875110): Figure out the condition for SPv2.
+ bool is_spv1_composited =
+ object.HasLayer() &&
+ ToLayoutBoxModelObject(object).Layer()->GetCompositedLayerMapping();
+ if (object.IsImage() && is_spv1_composited)
+ return true;
+
+ return false;
}
static bool NeedsPaintOffsetTranslationForScrollbars(
@@ -260,7 +298,7 @@ static bool NeedsPaintOffsetTranslation(const LayoutObject& object) {
return true;
if (NeedsPaintOffsetTranslationForScrollbars(box_model))
return true;
- if (NeedsSVGLocalToBorderBoxTransform(object))
+ if (NeedsReplacedContentTransform(object))
return true;
// Don't let paint offset cross composited layer boundaries, to avoid
@@ -322,6 +360,11 @@ void FragmentPaintPropertyTreeBuilder::UpdatePaintOffsetTranslation(
paint_offset_translation->Y());
state.flattens_inherited_transform =
context_.current.should_flatten_inherited_transform;
+
+ state.affected_by_outer_viewport_bounds_delta =
+ object_.StyleRef().GetPosition() == EPosition::kFixed &&
+ !object_.StyleRef().Bottom().IsAuto();
+
if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled() ||
RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled())
state.rendering_context_id = context_.current.rendering_context_id;
@@ -590,14 +633,26 @@ void FragmentPaintPropertyTreeBuilder::UpdateEffect() {
object_, context_.current.paint_offset);
bool has_clip_path =
style.ClipPath() && fragment_data_.ClipPathBoundingBox();
- bool has_spv1_composited_clip_path =
- has_clip_path && object_.HasLayer() &&
+ bool is_spv1_composited =
+ object_.HasLayer() &&
ToLayoutBoxModelObject(object_).Layer()->GetCompositedLayerMapping();
+ bool has_spv1_composited_clip_path = has_clip_path && is_spv1_composited;
bool has_mask_based_clip_path =
has_clip_path && !fragment_data_.ClipPathPath();
base::Optional<IntRect> clip_path_clip;
if (has_spv1_composited_clip_path || has_mask_based_clip_path) {
clip_path_clip = fragment_data_.ClipPathBoundingBox();
+ } else if (!mask_clip && is_spv1_composited &&
+ ToLayoutBoxModelObject(object_)
+ .Layer()
+ ->GetCompositedLayerMapping()
+ ->MaskLayer()) {
+ // TODO(crbug.com/856818): This should never happen.
+ // This is a band-aid to avoid nullptr properties on the mask layer
+ // crashing the renderer, but will result in incorrect rendering.
+ NOTREACHED();
+ has_spv1_composited_clip_path = true;
+ clip_path_clip = IntRect();
}
if (mask_clip || clip_path_clip) {
IntRect combined_clip = mask_clip ? *mask_clip : *clip_path_clip;
@@ -693,6 +748,39 @@ void FragmentPaintPropertyTreeBuilder::UpdateEffect() {
}
}
+static bool NeedsLinkHighlightEffect(const LayoutObject& object) {
+ auto* page = object.GetFrame()->GetPage();
+ return page->GetLinkHighlights().NeedsHighlightEffect(object);
+}
+
+void FragmentPaintPropertyTreeBuilder::UpdateLinkHighlightEffect() {
+ if (NeedsPaintPropertyUpdate()) {
+ if (NeedsLinkHighlightEffect(object_)) {
+ // While the link highlight uses the current transform space for
+ // positioning, it's parent effect is the root so that it is not affected
+ // by enclosing filters.
+ const auto& parent = EffectPaintPropertyNode::Root();
+ EffectPaintPropertyNode::State link_highlight_state;
+ link_highlight_state.local_transform_space = context_.current.transform;
+ link_highlight_state.compositor_element_id =
+ object_.GetFrame()->GetPage()->GetLinkHighlights().element_id(
+ object_);
+ link_highlight_state.direct_compositing_reasons =
+ CompositingReason::kActiveOpacityAnimation;
+ // Unlike other property nodes, link highlight effect nodes are guaranteed
+ // to be leaf nodes and do not require subtree invalidation, so we do not
+ // call |OnUpdate| here.
+ properties_->UpdateLinkHighlightEffect(parent,
+ std::move(link_highlight_state));
+ } else {
+ // Unlike other property nodes, link highlight effect nodes are guaranteed
+ // to be leaf nodes and do not require subtree invalidation, so we do not
+ // call |OnClear| here.
+ properties_->ClearLinkHighlightEffect();
+ }
+ }
+}
+
static bool NeedsFilter(const LayoutObject& object) {
// TODO(trchen): SVG caches filters in SVGResources. Implement it.
if (object.IsBoxModelObject() && ToLayoutBoxModelObject(object).Layer() &&
@@ -871,26 +959,6 @@ void FragmentPaintPropertyTreeBuilder::UpdateClipPathClip(
}
}
-void FragmentPaintPropertyTreeBuilder::UpdateLocalBorderBoxContext() {
- if (!NeedsPaintPropertyUpdate())
- return;
-
- if (!object_.HasLayer() && !NeedsPaintOffsetTranslation(object_) &&
- !NeedsFilter(object_)) {
- fragment_data_.ClearLocalBorderBoxProperties();
- } else {
- PropertyTreeState local_border_box =
- PropertyTreeState(context_.current.transform, context_.current.clip,
- context_.current_effect);
-
- if (!fragment_data_.HasLocalBorderBoxProperties() ||
- local_border_box != fragment_data_.LocalBorderBoxProperties())
- property_added_or_removed_ = true;
-
- fragment_data_.SetLocalBorderBoxProperties(std::move(local_border_box));
- }
-}
-
// Returns true if we are printing which was initiated by the frame. We should
// ignore clipping and scroll transform on contents. WebLocalFrameImpl will
// issue artificial page clip for each page, and always print from the origin
@@ -915,7 +983,34 @@ static bool IsPrintingRootLayoutView(const LayoutObject& object) {
return !ToLocalFrame(parent_frame)->GetDocument()->Printing();
}
+static bool NeedsOverflowClipForReplacedContents(
+ const LayoutReplaced& replaced) {
+ // <svg> may optionally allow overflow. If an overflow clip is required,
+ // always create it without checking whether the actual content overflows.
+ if (replaced.IsSVGRoot())
+ return ToLayoutSVGRoot(replaced).ShouldApplyViewportClip();
+
+ if (replaced.StyleRef().HasBorderRadius())
+ return true;
+
+ // Non-composited images have a micro-optimization to embed clip rects into
+ // the drawings instead of using a clip node.
+ bool is_spv1_composited =
+ replaced.HasLayer() && replaced.Layer()->GetCompositedLayerMapping();
+ if (replaced.IsImage() && !is_spv1_composited)
+ return false;
+
+ // Embedded objects are always sized to fit the content rect.
+ if (replaced.IsLayoutEmbeddedContent())
+ return false;
+
+ return true;
+}
+
static bool NeedsOverflowClip(const LayoutObject& object) {
+ if (object.IsLayoutReplaced())
+ return NeedsOverflowClipForReplacedContents(ToLayoutReplaced(object));
+
if (object.IsSVGViewportContainer() &&
SVGLayoutSupport::IsOverflowHidden(object))
return true;
@@ -924,6 +1019,26 @@ static bool NeedsOverflowClip(const LayoutObject& object) {
!IsPrintingRootLayoutView(object);
}
+void FragmentPaintPropertyTreeBuilder::UpdateLocalBorderBoxContext() {
+ if (!NeedsPaintPropertyUpdate())
+ return;
+
+ if (!object_.HasLayer() && !NeedsPaintOffsetTranslation(object_) &&
+ !NeedsFilter(object_) && !NeedsOverflowClip(object_)) {
+ fragment_data_.ClearLocalBorderBoxProperties();
+ } else {
+ PropertyTreeState local_border_box =
+ PropertyTreeState(context_.current.transform, context_.current.clip,
+ context_.current_effect);
+
+ if (!fragment_data_.HasLocalBorderBoxProperties() ||
+ local_border_box != fragment_data_.LocalBorderBoxProperties())
+ property_added_or_removed_ = true;
+
+ fragment_data_.SetLocalBorderBoxProperties(std::move(local_border_box));
+ }
+}
+
bool FragmentPaintPropertyTreeBuilder::NeedsOverflowControlsClip() const {
if (!object_.HasOverflowClip())
return false;
@@ -943,16 +1058,15 @@ bool FragmentPaintPropertyTreeBuilder::NeedsOverflowControlsClip() const {
}
static bool NeedsInnerBorderRadiusClip(const LayoutObject& object) {
- if (!object.StyleRef().HasBorderRadius())
+ // Replaced elements don't have scrollbars thus needs no separate clip
+ // for the padding box (InnerBorderRadiusClip) and the client box (padding
+ // box minus scrollbar, OverflowClip).
+ // Furthermore, replaced elements clip to the content box instead,
+ if (object.IsLayoutReplaced())
return false;
- if (object.IsBox() && NeedsOverflowClip(object))
- return true;
- // LayoutReplaced applies inner border-radius clip on the foreground. This
- // doesn't apply to SVGRoot which uses the NeedsOverflowClip() rule above.
- // This includes iframes which applies border-radius clip on the subdocument.
- if (object.IsLayoutReplaced() && !object.IsSVGRoot())
- return true;
- return false;
+
+ return object.StyleRef().HasBorderRadius() && object.IsBox() &&
+ NeedsOverflowClip(object);
}
static LayoutPoint VisualOffsetFromPaintOffsetRoot(
@@ -963,7 +1077,7 @@ static LayoutPoint VisualOffsetFromPaintOffsetRoot(
LayoutPoint result = child->VisualOffsetFromAncestor(painting_layer);
if (!paint_offset_root->HasLayer() ||
ToLayoutBoxModelObject(paint_offset_root)->Layer() != painting_layer) {
- result.Move(-paint_offset_root->OffsetFromAncestorContainer(
+ result.Move(-paint_offset_root->OffsetFromAncestor(
&painting_layer->GetLayoutObject()));
}
@@ -1007,18 +1121,8 @@ void FragmentPaintPropertyTreeBuilder::UpdateInnerBorderRadiusClip() {
const LayoutBox& box = ToLayoutBox(object_);
ClipPaintPropertyNode::State state;
state.local_transform_space = context_.current.transform;
- if (box.IsLayoutReplaced()) {
- // LayoutReplaced clips the foreground by rounded inner content box.
- state.clip_rect = box.StyleRef().GetRoundedInnerBorderFor(
- LayoutRect(context_.current.paint_offset, box.Size()),
- LayoutRectOutsets(-(box.PaddingTop() + box.BorderTop()),
- -(box.PaddingRight() + box.BorderRight()),
- -(box.PaddingBottom() + box.BorderBottom()),
- -(box.PaddingLeft() + box.BorderLeft())));
- } else {
- state.clip_rect = box.StyleRef().GetRoundedInnerBorderFor(
- LayoutRect(context_.current.paint_offset, box.Size()));
- }
+ state.clip_rect = box.StyleRef().GetRoundedInnerBorderFor(
+ LayoutRect(context_.current.paint_offset, box.Size()));
OnUpdateClip(properties_->UpdateInnerBorderRadiusClip(
*context_.current.clip, std::move(state)));
} else {
@@ -1051,6 +1155,15 @@ static bool CanOmitOverflowClip(const LayoutObject& object) {
if (block.HasControlClip() || block.ShouldPaintCarets())
return false;
+ if (object.IsLayoutReplaced()) {
+ const LayoutReplaced& replaced = ToLayoutReplaced(object);
+ if (replaced.StyleRef().HasBorderRadius())
+ return false;
+ LayoutRect replaced_content_rect = replaced.ReplacedContentRect();
+ return replaced_content_rect.IsEmpty() ||
+ replaced.PhysicalContentBoxRect().Contains(replaced_content_rect);
+ }
+
// We need OverflowClip for hit-testing if the clip rect excluding overlay
// scrollbars is different from the normal clip rect.
auto clip_rect = block.OverflowClipRect(LayoutPoint());
@@ -1069,7 +1182,26 @@ void FragmentPaintPropertyTreeBuilder::UpdateOverflowClip() {
ClipPaintPropertyNode::State state;
state.local_transform_space = context_.current.transform;
- if (object_.IsBox()) {
+ if (object_.IsLayoutReplaced()) {
+ const LayoutReplaced& replaced = ToLayoutReplaced(object_);
+ // LayoutReplaced clips the foreground by rounded content box.
+ state.clip_rect = replaced.StyleRef().GetRoundedInnerBorderFor(
+ LayoutRect(context_.current.paint_offset, replaced.Size()),
+ LayoutRectOutsets(
+ -(replaced.PaddingTop() + replaced.BorderTop()),
+ -(replaced.PaddingRight() + replaced.BorderRight()),
+ -(replaced.PaddingBottom() + replaced.BorderBottom()),
+ -(replaced.PaddingLeft() + replaced.BorderLeft())));
+ 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();
+ adjusted_rect.SetSize(
+ FloatSize(replaced.ReplacedContentRect().Size()));
+ state.clip_rect.SetRect(adjusted_rect);
+ }
+ } else if (object_.IsBox()) {
state.clip_rect = ToClipRect(ToLayoutBox(object_).OverflowClipRect(
context_.current.paint_offset));
state.clip_rect_excluding_overlay_scrollbars =
@@ -1143,33 +1275,74 @@ void FragmentPaintPropertyTreeBuilder::UpdatePerspective() {
}
}
-void FragmentPaintPropertyTreeBuilder::UpdateSvgLocalToBorderBoxTransform() {
+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();
+ float y_scale = dst_rect.Height() / src_rect.Height();
+ float x_offset = dst_rect.X() - src_rect.X() * x_scale;
+ float y_offset = dst_rect.Y() - src_rect.Y() * y_scale;
+ return AffineTransform(x_scale, 0.f, 0.f, y_scale, x_offset, y_offset);
+}
+
+void FragmentPaintPropertyTreeBuilder::UpdateReplacedContentTransform() {
DCHECK(properties_);
- if (!object_.IsSVGRoot())
- return;
- if (NeedsPaintPropertyUpdate()) {
- AffineTransform transform_to_border_box =
- SVGRootPainter(ToLayoutSVGRoot(object_))
- .TransformToPixelSnappedBorderBox(context_.current.paint_offset);
- if (!transform_to_border_box.IsIdentity() &&
- NeedsSVGLocalToBorderBoxTransform(object_)) {
- OnUpdate(properties_->UpdateSvgLocalToBorderBoxTransform(
+ if (NeedsPaintPropertyUpdate() && !NeedsReplacedContentTransform(object_)) {
+ OnClear(properties_->ClearReplacedContentTransform());
+ } else if (NeedsPaintPropertyUpdate()) {
+ AffineTransform content_to_parent_space;
+ if (object_.IsSVGRoot()) {
+ content_to_parent_space =
+ SVGRootPainter(ToLayoutSVGRoot(object_))
+ .TransformToPixelSnappedBorderBox(context_.current.paint_offset);
+ } else if (object_.IsImage()) {
+ const LayoutImage& layout_image = ToLayoutImage(object_);
+ LayoutRect layout_replaced_rect = layout_image.ReplacedContentRect();
+ layout_replaced_rect.MoveBy(context_.current.paint_offset);
+ IntRect replaced_rect = PixelSnappedIntRect(layout_replaced_rect);
+ scoped_refptr<Image> image = layout_image.ImageResource()->GetImage(
+ LayoutSize(replaced_rect.Size()));
+ if (image && !image->IsNull()) {
+ IntRect src_rect = image->Rect();
+ if (ImageWasTransposed(layout_image, *image))
+ src_rect = src_rect.TransposedRect();
+ content_to_parent_space =
+ RectToRect(FloatRect(src_rect), FloatRect(replaced_rect));
+ }
+ } else {
+ NOTREACHED();
+ }
+ if (!content_to_parent_space.IsIdentity()) {
+ OnUpdate(properties_->UpdateReplacedContentTransform(
*context_.current.transform,
- TransformPaintPropertyNode::State{transform_to_border_box}));
+ TransformPaintPropertyNode::State{content_to_parent_space}));
} else {
- OnClear(properties_->ClearSvgLocalToBorderBoxTransform());
+ OnClear(properties_->ClearReplacedContentTransform());
}
}
- if (properties_->SvgLocalToBorderBoxTransform()) {
- context_.current.transform = properties_->SvgLocalToBorderBoxTransform();
- context_.current.should_flatten_inherited_transform = false;
- context_.current.rendering_context_id = 0;
+ if (object_.IsSVGRoot()) {
+ // SVG painters don't use paint offset. The paint offset is baked into
+ // the transform node instead.
+ context_.current.paint_offset = LayoutPoint();
+
+ // Only <svg> paints its subtree as replaced contents. Other replaced
+ // element type may have shadow DOM that should not be affected by the
+ // replaced object fit.
+ if (properties_->ReplacedContentTransform()) {
+ context_.current.transform = properties_->ReplacedContentTransform();
+ context_.current.should_flatten_inherited_transform = false;
+ context_.current.rendering_context_id = 0;
+ }
}
- // The paint offset is included in |transformToBorderBox| so SVG does not need
- // to handle paint offset internally.
- context_.current.paint_offset = LayoutPoint();
}
static MainThreadScrollingReasons GetMainThreadScrollingReasons(
@@ -1206,7 +1379,9 @@ void FragmentPaintPropertyTreeBuilder::UpdateScrollAndScrollTranslation() {
box.OverflowClipRect(context_.current.paint_offset));
state.contents_rect = IntRect(
-scrollable_area->ScrollOrigin() + state.container_rect.Location(),
- scrollable_area->ContentsSize());
+ scrollable_area->PixelSnappedContentsSize(
+ context_.current.paint_offset));
+
// In flipped blocks writing mode, if there is scrollbar on the right,
// we move the contents to the left with extra amount of ScrollTranslation
// (-VerticalScrollbarWidth, 0). As contents_rect is in the space of
@@ -1237,6 +1412,17 @@ void FragmentPaintPropertyTreeBuilder::UpdateScrollAndScrollTranslation() {
RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled())
state.compositor_element_id = scrollable_area->GetCompositorElementId();
+ state.overscroll_behavior = OverscrollBehavior(
+ static_cast<OverscrollBehavior::OverscrollBehaviorType>(
+ box.StyleRef().OverscrollBehaviorX()),
+ static_cast<OverscrollBehavior::OverscrollBehaviorType>(
+ box.StyleRef().OverscrollBehaviorY()));
+
+ auto* snap_coordinator = box.GetDocument().GetSnapCoordinator();
+ if (snap_coordinator) {
+ state.snap_container_data = snap_coordinator->GetSnapContainerData(box);
+ }
+
OnUpdate(properties_->UpdateScroll(*context_.current.scroll,
std::move(state)));
@@ -1297,17 +1483,15 @@ void FragmentPaintPropertyTreeBuilder::UpdateScrollAndScrollTranslation() {
if (properties_->Scroll())
context_.current.scroll = properties_->Scroll();
- if (properties_->ScrollTranslation()) {
+ if (properties_->ScrollTranslation())
context_.current.transform = properties_->ScrollTranslation();
- context_.current.should_flatten_inherited_transform = false;
- }
}
void FragmentPaintPropertyTreeBuilder::UpdateOutOfFlowContext() {
if (!object_.IsBoxModelObject() && !properties_)
return;
- if (object_.IsLayoutBlockFlow()) {
+ if (object_.IsLayoutBlock()) {
context_.paint_offset_for_float = context_.current.paint_offset;
// TODO(crbug.com/858843): For now floating object's PhysicalLocation() is
// in the scrolling contents space, so if there is scrollbar on the left,
@@ -1387,13 +1571,27 @@ static bool IsRepeatingTableSection(const LayoutObject& object) {
static LayoutRect BoundingBoxInPaginationContainer(
const LayoutObject& object,
const PaintLayer& enclosing_pagination_layer) {
- // Non-boxes that have no layer paint in the space of their containing block.
- if (!object.IsBox() && !object.HasLayer()) {
+ // The special path for fragmented layers ensures that the bounding box also
+ // covers contents visual overflow, so that the fragments will cover all
+ // fragments of contents except for self-painting layers, because we initiate
+ // fragment painting of contents from the layer.
+ if (object.HasLayer() &&
+ ToLayoutBoxModelObject(object)
+ .Layer()
+ ->ShouldFragmentCompositedBounds() &&
+ // Table section may repeat, and doesn't need the special layer path
+ // because it doesn't have contents visual overflow.
+ !object.IsTableSection()) {
+ return ToLayoutBoxModelObject(object).Layer()->PhysicalBoundingBox(
+ &enclosing_pagination_layer);
+ }
+
+ // Non-boxes paint in the space of their containing block.
+ if (!object.IsBox()) {
const LayoutBox& containining_block = *object.ContainingBlock();
LayoutRect bounds_rect;
- // For non-SVG we can get a more accurate result
- // with LocalVisualRect, instead of falling back to the bounds of the
- // enclosing block.
+ // For non-SVG we can get a more accurate result with LocalVisualRect,
+ // instead of falling back to the bounds of the enclosing block.
if (!object.IsSVG()) {
bounds_rect = object.LocalVisualRect();
containining_block.FlipForWritingMode(bounds_rect);
@@ -1405,17 +1603,6 @@ static LayoutRect BoundingBoxInPaginationContainer(
enclosing_pagination_layer);
}
- // The special path for layers ensures that the bounding box also covers
- // contents visual overflow, so that the fragments will cover all fragments of
- // contents except for self-painting layers, because we initiate fragment
- // painting of contents from the layer.
- // Table section may repeat, and doesn't need the special layer path because
- // it doesn't have contents visual overflow.
- if (object.HasLayer() && !object.IsTableSection()) {
- return ToLayoutBoxModelObject(object).Layer()->PhysicalBoundingBox(
- &enclosing_pagination_layer);
- }
-
// Compute the bounding box without transforms.
// The object is guaranteed to be a box due to the logic above.
const LayoutBox& box = ToLayoutBox(object);
@@ -1612,6 +1799,10 @@ void FragmentPaintPropertyTreeBuilder::SetNeedsPaintPropertyUpdateIfNeeded() {
box.GetMutableForPainting().SetNeedsPaintPropertyUpdate();
}
+ if (box.IsLayoutReplaced() &&
+ box.PreviousPhysicalContentBoxRect() != box.PhysicalContentBoxRect())
+ box.GetMutableForPainting().SetNeedsPaintPropertyUpdate();
+
if (box.Size() == box.PreviousSize())
return;
@@ -1662,9 +1853,12 @@ void FragmentPaintPropertyTreeBuilder::UpdateForObjectLocationAndSize(
// the entire subtree on paint offset changes.
full_context_.force_subtree_update = true;
- object_.GetMutableForPainting().SetMayNeedPaintInvalidation();
+ object_.GetMutableForPainting().SetShouldCheckForPaintInvalidation();
fragment_data_.SetPaintOffset(context_.current.paint_offset);
fragment_data_.InvalidateClipPathCache();
+
+ object_.GetFrameView()->SetNeedsIntersectionObservation(
+ LocalFrameView::kDesired);
}
if (paint_offset_translation)
@@ -1722,6 +1916,7 @@ void FragmentPaintPropertyTreeBuilder::UpdateForSelf() {
UpdateTransform();
UpdateClipPathClip(false);
UpdateEffect();
+ UpdateLinkHighlightEffect();
UpdateClipPathClip(true); // Special pass for SPv1 composited clip-path.
UpdateCssClip();
UpdateFilter();
@@ -1740,10 +1935,15 @@ void FragmentPaintPropertyTreeBuilder::UpdateForChildren() {
UpdateInnerBorderRadiusClip();
UpdateOverflowClip();
UpdatePerspective();
- UpdateSvgLocalToBorderBoxTransform();
+ UpdateReplacedContentTransform();
UpdateScrollAndScrollTranslation();
}
UpdateOutOfFlowContext();
+
+#if DCHECK_IS_ON()
+ if (properties_)
+ properties_->Validate();
+#endif
}
} // namespace
@@ -1812,6 +2012,7 @@ void PaintPropertyTreeBuilder::UpdateCompositedLayerPaginationOffset() {
// under the pagination layer. SPv1* doesn't fragment composited layers,
// but we still need to set correct pagination offset for correct paint
// offset calculation.
+ DCHECK(!context_.painting_layer->ShouldFragmentCompositedBounds());
FragmentData& first_fragment =
object_.GetMutableForPainting().FirstFragment();
bool is_paint_invalidation_container = object_.IsPaintInvalidationContainer();
@@ -2201,6 +2402,14 @@ void PaintPropertyTreeBuilder::CreateFragmentContextsInFlowThread(
if (object_.HasLayer()) {
// 1. Compute clip in flow thread space.
fragment_clip = iterator.ClipRectInFlowThread();
+
+ // We skip empty clip fragments, since they can share the same logical top
+ // with the subsequent fragments. Since we skip drawing empty fragments
+ // anyway, it doesn't affect the paint output, but it allows us to use
+ // logical top to uniquely identify fragments in an object.
+ if (fragment_clip->IsEmpty())
+ continue;
+
// 2. Convert #1 to visual coordinates in the space of the flow thread.
fragment_clip->MoveBy(pagination_offset);
// 3. Adjust #2 to visual coordinates in the containing "paint offset"
@@ -2366,10 +2575,11 @@ bool PaintPropertyTreeBuilder::UpdateFragments() {
bool needs_paint_properties =
object_.StyleRef().ClipPath() || NeedsPaintOffsetTranslation(object_) ||
NeedsTransform(object_) || NeedsClipPathClip(object_) ||
- NeedsEffect(object_) || NeedsTransformForNonRootSVG(object_) ||
- NeedsFilter(object_) || NeedsCssClip(object_) ||
- NeedsInnerBorderRadiusClip(object_) || NeedsOverflowClip(object_) ||
- NeedsPerspective(object_) || NeedsSVGLocalToBorderBoxTransform(object_) ||
+ NeedsEffect(object_) || NeedsLinkHighlightEffect(object_) ||
+ NeedsTransformForNonRootSVG(object_) || NeedsFilter(object_) ||
+ NeedsCssClip(object_) || NeedsInnerBorderRadiusClip(object_) ||
+ NeedsOverflowClip(object_) || NeedsPerspective(object_) ||
+ NeedsReplacedContentTransform(object_) ||
NeedsScrollOrScrollTranslation(object_);
// Need of fragmentation clip will be determined in CreateFragmentContexts().
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 07e48113cb5..ef159373872 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
@@ -7,6 +7,7 @@
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/visual_viewport.h"
#include "third_party/blink/renderer/core/html/html_iframe_element.h"
+#include "third_party/blink/renderer/core/layout/layout_flow_thread.h"
#include "third_party/blink/renderer/core/layout/layout_image.h"
#include "third_party/blink/renderer/core/layout/layout_table_cell.h"
#include "third_party/blink/renderer/core/layout/layout_table_section.h"
@@ -145,9 +146,9 @@ TEST_P(PaintPropertyTreeBuilderTest, FixedPosition) {
auto* positioned_scroll_translation =
positioned_scroll_properties->ScrollTranslation();
auto* positioned_scroll_node = positioned_scroll_translation->ScrollNode();
- // TODO(bokan): Viewport property node generation has been disabled
- // temporarily with the flag off to diagnose https//crbug.com/868927.
- if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
+ // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // scrolling.
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
EXPECT_EQ(GetDocument()
.GetPage()
->GetVisualViewport()
@@ -155,7 +156,7 @@ TEST_P(PaintPropertyTreeBuilderTest, FixedPosition) {
->ScrollNode(),
positioned_scroll_node->Parent());
} else {
- EXPECT_TRUE(positioned_scroll_node->Parent()->IsRoot());
+ EXPECT_EQ(DocScroll(), positioned_scroll_node->Parent());
}
EXPECT_EQ(TransformationMatrix().Translate(0, -3),
positioned_scroll_translation->Matrix());
@@ -183,17 +184,17 @@ TEST_P(PaintPropertyTreeBuilderTest, FixedPosition) {
auto* transformed_scroll_translation =
transformed_scroll_properties->ScrollTranslation();
auto* transformed_scroll_node = transformed_scroll_translation->ScrollNode();
- // TODO(bokan): Viewport property node generation has been disabled
- // temporarily with the flag off to diagnose https//crbug.com/868927.
- if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
+ // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // scrolling.
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
EXPECT_EQ(GetDocument()
.GetPage()
->GetVisualViewport()
.GetScrollTranslationNode()
->ScrollNode(),
- transformed_scroll_node->Parent());
+ positioned_scroll_node->Parent());
} else {
- EXPECT_TRUE(transformed_scroll_node->Parent()->IsRoot());
+ EXPECT_EQ(DocScroll(), transformed_scroll_node->Parent());
}
EXPECT_EQ(TransformationMatrix().Translate(0, -5),
transformed_scroll_translation->Matrix());
@@ -398,13 +399,13 @@ TEST_P(PaintPropertyTreeBuilderTest, DocScrollingTraditional) {
LocalFrameView* frame_view = GetDocument().View();
frame_view->UpdateAllLifecyclePhases();
EXPECT_EQ(TransformationMatrix(), DocPreTranslation()->Matrix());
- // TODO(bokan): Viewport property node generation has been disabled
- // temporarily with the flag off to diagnose https//crbug.com/868927.
- if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled() ||
+ RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
EXPECT_EQ(
GetDocument().GetPage()->GetVisualViewport().GetScrollTranslationNode(),
DocPreTranslation()->Parent());
} else {
+ // Pre-BGPT we don't create the visual viewport property nodes.
EXPECT_TRUE(DocPreTranslation()->Parent()->IsRoot());
}
EXPECT_EQ(TransformationMatrix().Translate(0, -100),
@@ -449,8 +450,15 @@ TEST_P(PaintPropertyTreeBuilderTest, Perspective) {
// paint offset.
EXPECT_EQ(FloatPoint3D(250, 250, 0),
perspective_properties->Perspective()->Origin());
- EXPECT_EQ(DocPreTranslation(),
- perspective_properties->Perspective()->Parent());
+ // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // scrolling.
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ EXPECT_EQ(DocPreTranslation(),
+ perspective_properties->Perspective()->Parent());
+ } else {
+ EXPECT_EQ(DocScrollTranslation(),
+ perspective_properties->Perspective()->Parent());
+ }
// Adding perspective doesn't clear paint offset. The paint offset will be
// passed down to children.
@@ -471,8 +479,15 @@ TEST_P(PaintPropertyTreeBuilderTest, Perspective) {
perspective_properties->Perspective()->Matrix());
EXPECT_EQ(FloatPoint3D(250, 250, 0),
perspective_properties->Perspective()->Origin());
- EXPECT_EQ(DocPreTranslation(),
- perspective_properties->Perspective()->Parent());
+ // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // scrolling.
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ EXPECT_EQ(DocPreTranslation(),
+ perspective_properties->Perspective()->Parent());
+ } else {
+ EXPECT_EQ(DocScrollTranslation(),
+ perspective_properties->Perspective()->Parent());
+ }
perspective->setAttribute(HTMLNames::styleAttr, "perspective-origin: 5% 20%");
GetDocument().View()->UpdateAllLifecyclePhases();
@@ -480,8 +495,15 @@ TEST_P(PaintPropertyTreeBuilderTest, Perspective) {
perspective_properties->Perspective()->Matrix());
EXPECT_EQ(FloatPoint3D(70, 160, 0),
perspective_properties->Perspective()->Origin());
- EXPECT_EQ(DocPreTranslation(),
- perspective_properties->Perspective()->Parent());
+ // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // scrolling.
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ EXPECT_EQ(DocPreTranslation(),
+ perspective_properties->Perspective()->Parent());
+ } else {
+ EXPECT_EQ(DocScrollTranslation(),
+ perspective_properties->Perspective()->Parent());
+ }
}
TEST_P(PaintPropertyTreeBuilderTest, Transform) {
@@ -688,8 +710,15 @@ TEST_P(PaintPropertyTreeBuilderTest, RelativePositionInline) {
inline_block->GetLayoutObject()->FirstFragment().PaintProperties();
EXPECT_EQ(TransformationMatrix().Translate(135, 490),
inline_block_properties->PaintOffsetTranslation()->Matrix());
- EXPECT_EQ(DocPreTranslation(),
- inline_block_properties->PaintOffsetTranslation()->Parent());
+ // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // scrolling.
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ EXPECT_EQ(DocPreTranslation(),
+ inline_block_properties->PaintOffsetTranslation()->Parent());
+ } else {
+ EXPECT_EQ(DocScrollTranslation(),
+ inline_block_properties->PaintOffsetTranslation()->Parent());
+ }
CHECK_EXACT_VISUAL_RECT(LayoutRect(135, 490, 10, 20),
inline_block->GetLayoutObject(),
GetDocument().View()->GetLayoutView());
@@ -1011,10 +1040,17 @@ TEST_P(PaintPropertyTreeBuilderTest, TransformNodesInSVG) {
EXPECT_EQ(
TransformationMatrix().Translate(70, 25),
svg_root_with3d_transform_properties->PaintOffsetTranslation()->Matrix());
- EXPECT_EQ(
- DocPreTranslation(),
- svg_root_with3d_transform_properties->PaintOffsetTranslation()->Parent());
-
+ // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // scrolling.
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ EXPECT_EQ(DocPreTranslation(),
+ svg_root_with3d_transform_properties->PaintOffsetTranslation()
+ ->Parent());
+ } else {
+ EXPECT_EQ(DocScrollTranslation(),
+ svg_root_with3d_transform_properties->PaintOffsetTranslation()
+ ->Parent());
+ }
LayoutObject& rect_with2d_transform =
*GetLayoutObjectByElementId("rectWith2dTransform");
const ObjectPaintProperties* rect_with2d_transform_properties =
@@ -1061,19 +1097,17 @@ TEST_P(PaintPropertyTreeBuilderTest, SVGViewBoxTransform) {
svg_with_view_box.FirstFragment().PaintProperties();
EXPECT_EQ(TransformationMatrix().Translate3d(1, 2, 3),
svg_with_view_box_properties->Transform()->Matrix());
- EXPECT_EQ(
- TransformationMatrix().Translate(-50, -50),
- svg_with_view_box_properties->SvgLocalToBorderBoxTransform()->Matrix());
- EXPECT_EQ(
- svg_with_view_box_properties->SvgLocalToBorderBoxTransform()->Parent(),
- svg_with_view_box_properties->Transform());
+ EXPECT_EQ(TransformationMatrix().Translate(-50, -50),
+ svg_with_view_box_properties->ReplacedContentTransform()->Matrix());
+ EXPECT_EQ(svg_with_view_box_properties->ReplacedContentTransform()->Parent(),
+ svg_with_view_box_properties->Transform());
LayoutObject& rect = *GetLayoutObjectByElementId("rect");
const ObjectPaintProperties* rect_properties =
rect.FirstFragment().PaintProperties();
EXPECT_EQ(TransformationMatrix().Translate(100, 100),
rect_properties->Transform()->Matrix());
- EXPECT_EQ(svg_with_view_box_properties->SvgLocalToBorderBoxTransform(),
+ EXPECT_EQ(svg_with_view_box_properties->ReplacedContentTransform(),
rect_properties->Transform()->Parent());
}
@@ -1098,9 +1132,16 @@ TEST_P(PaintPropertyTreeBuilderTest, SVGRootPaintOffsetTransformNode) {
EXPECT_EQ(
FloatSize(50, 25),
svg_properties->PaintOffsetTranslation()->Matrix().To2DTranslation());
- EXPECT_EQ(nullptr, svg_properties->SvgLocalToBorderBoxTransform());
- EXPECT_EQ(DocPreTranslation(),
- svg_properties->PaintOffsetTranslation()->Parent());
+ EXPECT_EQ(nullptr, svg_properties->ReplacedContentTransform());
+ // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // scrolling.
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ EXPECT_EQ(DocPreTranslation(),
+ svg_properties->PaintOffsetTranslation()->Parent());
+ } else {
+ EXPECT_EQ(DocScrollTranslation(),
+ svg_properties->PaintOffsetTranslation()->Parent());
+ }
}
TEST_P(PaintPropertyTreeBuilderTest, SVGRootLocalToBorderBoxTransformNode) {
@@ -1127,11 +1168,11 @@ TEST_P(PaintPropertyTreeBuilderTest, SVGRootLocalToBorderBoxTransformNode) {
EXPECT_EQ(TransformationMatrix().Translate(5, 7),
svg_properties->Transform()->Matrix());
EXPECT_EQ(TransformationMatrix().Translate(11, 11).Scale(100.0 / 13.0),
- svg_properties->SvgLocalToBorderBoxTransform()->Matrix());
+ svg_properties->ReplacedContentTransform()->Matrix());
EXPECT_EQ(svg_properties->PaintOffsetTranslation(),
svg_properties->Transform()->Parent());
EXPECT_EQ(svg_properties->Transform(),
- svg_properties->SvgLocalToBorderBoxTransform()->Parent());
+ svg_properties->ReplacedContentTransform()->Parent());
// Ensure the rect's transform is a child of the local to border box
// transform.
@@ -1140,7 +1181,7 @@ TEST_P(PaintPropertyTreeBuilderTest, SVGRootLocalToBorderBoxTransformNode) {
rect.FirstFragment().PaintProperties();
EXPECT_EQ(TransformationMatrix().Translate(17, 19),
rect_properties->Transform()->Matrix());
- EXPECT_EQ(svg_properties->SvgLocalToBorderBoxTransform(),
+ EXPECT_EQ(svg_properties->ReplacedContentTransform(),
rect_properties->Transform()->Parent());
}
@@ -1161,15 +1202,15 @@ TEST_P(PaintPropertyTreeBuilderTest, SVGNestedViewboxTransforms) {
EXPECT_EQ(TransformationMatrix().Translate(11, 11),
svg_properties->Transform()->Matrix());
EXPECT_EQ(TransformationMatrix().Scale(2),
- svg_properties->SvgLocalToBorderBoxTransform()->Matrix());
+ svg_properties->ReplacedContentTransform()->Matrix());
LayoutObject& nested_svg = *GetLayoutObjectByElementId("nestedSvg");
const ObjectPaintProperties* nested_svg_properties =
nested_svg.FirstFragment().PaintProperties();
EXPECT_EQ(TransformationMatrix().Scale(10),
nested_svg_properties->Transform()->Matrix());
- EXPECT_EQ(nullptr, nested_svg_properties->SvgLocalToBorderBoxTransform());
- EXPECT_EQ(svg_properties->SvgLocalToBorderBoxTransform(),
+ EXPECT_EQ(nullptr, nested_svg_properties->ReplacedContentTransform());
+ EXPECT_EQ(svg_properties->ReplacedContentTransform(),
nested_svg_properties->Transform()->Parent());
LayoutObject& rect = *GetLayoutObjectByElementId("rect");
@@ -1464,11 +1505,21 @@ TEST_P(PaintPropertyTreeBuilderTest, ControlClip) {
LayoutObject& button = *GetLayoutObjectByElementId("button");
const ObjectPaintProperties* button_properties =
button.FirstFragment().PaintProperties();
- // No scroll translation because the document does not scroll (not enough
- // content).
- EXPECT_TRUE(!DocScrollTranslation());
- EXPECT_EQ(DocPreTranslation(),
- button_properties->OverflowClip()->LocalTransformSpace());
+ // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // scrolling.
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ EXPECT_TRUE(DocPreTranslation());
+ EXPECT_FALSE(DocScrollTranslation());
+ EXPECT_EQ(DocPreTranslation(),
+ button_properties->OverflowClip()->LocalTransformSpace());
+ } else {
+ // Always create scroll translation for layout view even the document does
+ // not scroll (not enough content).
+ EXPECT_TRUE(DocScrollTranslation());
+ EXPECT_EQ(DocScrollTranslation(),
+ button_properties->OverflowClip()->LocalTransformSpace());
+ }
+
EXPECT_EQ(FloatRoundedRect(5, 5, 335, 113),
button_properties->OverflowClip()->ClipRect());
EXPECT_EQ(DocContentClip(), button_properties->OverflowClip()->Parent());
@@ -1494,9 +1545,16 @@ TEST_P(PaintPropertyTreeBuilderTest, ControlClipInsideForeignObject) {
LayoutObject& button = *GetLayoutObjectByElementId("button");
const ObjectPaintProperties* button_properties =
button.FirstFragment().PaintProperties();
- // No scroll translation because the document does not scroll (not enough
- // content).
- EXPECT_TRUE(!DocScrollTranslation());
+ // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // scrolling.
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ EXPECT_FALSE(DocScrollTranslation());
+ } else {
+ // Always create scroll translation for layout view even the document does
+ // not scroll (not enough content).
+ EXPECT_TRUE(DocScrollTranslation());
+ }
+
EXPECT_EQ(FloatRoundedRect(2, 2, 341, 119),
button_properties->OverflowClip()->ClipRect());
CHECK_EXACT_VISUAL_RECT(LayoutRect(8, 8, 345, 123), &button,
@@ -1526,11 +1584,20 @@ TEST_P(PaintPropertyTreeBuilderTest, BorderRadiusClip) {
LayoutObject& div = *GetLayoutObjectByElementId("div");
const ObjectPaintProperties* div_properties =
div.FirstFragment().PaintProperties();
- // No scroll translation because the document does not scroll (not enough
- // content).
- EXPECT_TRUE(!DocScrollTranslation());
- EXPECT_EQ(DocPreTranslation(),
- div_properties->OverflowClip()->LocalTransformSpace());
+
+ // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // scrolling.
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ EXPECT_FALSE(DocScrollTranslation());
+ EXPECT_EQ(DocPreTranslation(),
+ div_properties->OverflowClip()->LocalTransformSpace());
+ } else {
+ // Always create scroll translation for layout view even the document does
+ // not scroll (not enough content).
+ EXPECT_TRUE(DocScrollTranslation());
+ EXPECT_EQ(DocScrollTranslation(),
+ div_properties->OverflowClip()->LocalTransformSpace());
+ }
// The overflow clip rect includes only the padding box.
// padding box = border box(500+60+50, 400+45+55) - border outset(60+50,
// 45+55) - scrollbars(15, 15)
@@ -1538,7 +1605,14 @@ TEST_P(PaintPropertyTreeBuilderTest, BorderRadiusClip) {
div_properties->OverflowClip()->ClipRect());
const ClipPaintPropertyNode* border_radius_clip =
div_properties->OverflowClip()->Parent();
- EXPECT_EQ(DocPreTranslation(), border_radius_clip->LocalTransformSpace());
+ // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // scrolling.
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ EXPECT_EQ(DocPreTranslation(), border_radius_clip->LocalTransformSpace());
+ } else {
+ EXPECT_EQ(DocScrollTranslation(),
+ border_radius_clip->LocalTransformSpace());
+ }
// The border radius clip is the area enclosed by inner border edge, including
// the scrollbars. As the border-radius is specified in outer radius, the
// inner radius is calculated by:
@@ -1842,8 +1916,15 @@ TEST_P(PaintPropertyTreeBuilderTest, TableCellLayoutLocation) {
LayoutObject& target = *GetLayoutObjectByElementId("target");
EXPECT_EQ(LayoutPoint(170, 170), target.FirstFragment().PaintOffset());
- EXPECT_EQ(DocPreTranslation(),
- target.FirstFragment().LocalBorderBoxProperties().Transform());
+ // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // scrolling.
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ EXPECT_EQ(DocPreTranslation(),
+ target.FirstFragment().LocalBorderBoxProperties().Transform());
+ } else {
+ EXPECT_EQ(DocScrollTranslation(),
+ target.FirstFragment().LocalBorderBoxProperties().Transform());
+ }
CHECK_EXACT_VISUAL_RECT(LayoutRect(170, 170, 100, 100), &target,
GetDocument().View()->GetLayoutView());
}
@@ -1880,8 +1961,15 @@ TEST_P(PaintPropertyTreeBuilderTest, CSSClipFixedPositionDescendant) {
const ObjectPaintProperties* clip_properties =
clip.FirstFragment().PaintProperties();
EXPECT_EQ(DocContentClip(), clip_properties->CssClip()->Parent());
- EXPECT_EQ(DocPreTranslation(),
- clip_properties->CssClip()->LocalTransformSpace());
+ // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // scrolling.
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ EXPECT_EQ(DocPreTranslation(),
+ clip_properties->CssClip()->LocalTransformSpace());
+ } else {
+ EXPECT_EQ(DocScrollTranslation(),
+ clip_properties->CssClip()->LocalTransformSpace());
+ }
EXPECT_EQ(FloatRoundedRect(FloatRect(absolute_clip_rect)),
clip_properties->CssClip()->ClipRect());
CHECK_VISUAL_RECT(absolute_clip_rect, &clip,
@@ -1936,11 +2024,19 @@ TEST_P(PaintPropertyTreeBuilderTest, CSSClipAbsPositionDescendant) {
const ObjectPaintProperties* clip_properties =
clip->FirstFragment().PaintProperties();
EXPECT_EQ(DocContentClip(), clip_properties->CssClip()->Parent());
- // No scroll translation because the document does not scroll (not enough
- // content).
- EXPECT_TRUE(!DocScrollTranslation());
- EXPECT_EQ(DocPreTranslation(),
- clip_properties->CssClip()->LocalTransformSpace());
+ // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // scrolling.
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ EXPECT_FALSE(DocScrollTranslation());
+ EXPECT_EQ(DocPreTranslation(),
+ clip_properties->CssClip()->LocalTransformSpace());
+ } else {
+ // Always create scroll translation for layout view even the document does
+ // not scroll (not enough content).
+ EXPECT_TRUE(DocScrollTranslation());
+ EXPECT_EQ(DocScrollTranslation(),
+ clip_properties->CssClip()->LocalTransformSpace());
+ }
EXPECT_EQ(FloatRoundedRect(FloatRect(absolute_clip_rect)),
clip_properties->CssClip()->ClipRect());
CHECK_VISUAL_RECT(absolute_clip_rect, clip,
@@ -1952,8 +2048,17 @@ TEST_P(PaintPropertyTreeBuilderTest, CSSClipAbsPositionDescendant) {
auto* absolute = GetLayoutObjectByElementId("absolute");
EXPECT_EQ(clip_properties->CssClip(),
absolute->FirstFragment().LocalBorderBoxProperties().Clip());
- EXPECT_EQ(DocPreTranslation(),
- absolute->FirstFragment().LocalBorderBoxProperties().Transform());
+ // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // scrolling.
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ EXPECT_FALSE(DocScrollTranslation());
+ EXPECT_EQ(DocPreTranslation(),
+ absolute->FirstFragment().LocalBorderBoxProperties().Transform());
+ } else {
+ EXPECT_TRUE(DocScrollTranslation());
+ EXPECT_EQ(DocScrollTranslation(),
+ absolute->FirstFragment().LocalBorderBoxProperties().Transform());
+ }
EXPECT_EQ(LayoutPoint(777, 777), absolute->FirstFragment().PaintOffset());
CHECK_VISUAL_RECT(LayoutRect(), absolute,
GetDocument().View()->GetLayoutView(),
@@ -1989,11 +2094,19 @@ TEST_P(PaintPropertyTreeBuilderTest, CSSClipSubpixel) {
const ObjectPaintProperties* clip_properties =
clip->FirstFragment().PaintProperties();
EXPECT_EQ(DocContentClip(), clip_properties->CssClip()->Parent());
- // No scroll translation because the document does not scroll (not enough
- // content).
- EXPECT_TRUE(!DocScrollTranslation());
- EXPECT_EQ(DocPreTranslation(),
- clip_properties->CssClip()->LocalTransformSpace());
+ // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // scrolling.
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ EXPECT_TRUE(DocPreTranslation());
+ EXPECT_EQ(DocPreTranslation(),
+ clip_properties->CssClip()->LocalTransformSpace());
+ } else {
+ // Always create scroll translation for layout view even the document does
+ // not scroll (not enough content).
+ EXPECT_TRUE(DocScrollTranslation());
+ EXPECT_EQ(DocScrollTranslation(),
+ clip_properties->CssClip()->LocalTransformSpace());
+ }
EXPECT_EQ(FloatRoundedRect(FloatRect(absolute_clip_rect)),
clip_properties->CssClip()->ClipRect());
}
@@ -2037,11 +2150,19 @@ TEST_P(PaintPropertyTreeBuilderTest, CSSClipFixedPositionDescendantNonShared) {
const ObjectPaintProperties* overflow_properties =
overflow.FirstFragment().PaintProperties();
EXPECT_EQ(DocContentClip(), overflow_properties->OverflowClip()->Parent());
- // No scroll translation because the document does not scroll (not enough
- // content).
- EXPECT_TRUE(!DocScrollTranslation());
- EXPECT_EQ(DocPreTranslation(),
- overflow_properties->ScrollTranslation()->Parent()->Parent());
+ // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // scrolling.
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ EXPECT_TRUE(DocPreTranslation());
+ EXPECT_EQ(DocPreTranslation(),
+ overflow_properties->ScrollTranslation()->Parent()->Parent());
+ } else {
+ // Always create scroll translation for layout view even the document does
+ // not scroll (not enough content).
+ EXPECT_TRUE(DocScrollTranslation());
+ EXPECT_EQ(DocScrollTranslation(),
+ overflow_properties->ScrollTranslation()->Parent()->Parent());
+ }
CHECK_EXACT_VISUAL_RECT(LayoutRect(0, 0, 50, 50), &overflow,
GetDocument().View()->GetLayoutView());
@@ -2500,7 +2621,7 @@ TEST_P(PaintPropertyTreeBuilderTest, SvgPixelSnappingShouldResetPaintOffset) {
svg_with_transform_properties->Transform()->Matrix());
EXPECT_EQ(LayoutPoint(FloatPoint(0.1, 0)),
svg_with_transform.FirstFragment().PaintOffset());
- EXPECT_TRUE(svg_with_transform_properties->SvgLocalToBorderBoxTransform() ==
+ EXPECT_TRUE(svg_with_transform_properties->ReplacedContentTransform() ==
nullptr);
LayoutObject& rect_with_transform = *GetLayoutObjectByElementId("rect");
@@ -2534,7 +2655,7 @@ TEST_P(PaintPropertyTreeBuilderTest, SvgRootAndForeignObjectPixelSnapping) {
svg_properties->PaintOffsetTranslation()->Matrix().To2DTranslation());
EXPECT_EQ(LayoutPoint(LayoutUnit(-0.40625), LayoutUnit(0.3)),
svg->FirstFragment().PaintOffset());
- EXPECT_EQ(nullptr, svg_properties->SvgLocalToBorderBoxTransform());
+ EXPECT_EQ(nullptr, svg_properties->ReplacedContentTransform());
const auto* foreign_object = GetLayoutObjectByElementId("foreign");
const auto* foreign_object_properties =
foreign_object->FirstFragment().PaintProperties();
@@ -2985,21 +3106,44 @@ TEST_P(PaintPropertyTreeBuilderTest, OverflowClipContentsTreeState) {
clipper->FirstFragment().PaintProperties();
LayoutObject* child = GetLayoutObjectByElementId("child");
- // No scroll translation because the document does not scroll (not enough
- // content).
- EXPECT_TRUE(!DocScrollTranslation());
- EXPECT_EQ(DocPreTranslation(),
- clipper->FirstFragment().LocalBorderBoxProperties().Transform());
+ // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // scrolling.
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ EXPECT_FALSE(DocScrollTranslation());
+ EXPECT_TRUE(DocPreTranslation());
+ EXPECT_EQ(DocPreTranslation(),
+ clipper->FirstFragment().LocalBorderBoxProperties().Transform());
+ } else {
+ // Always create scroll translation for layout view even the document does
+ // not scroll (not enough content).
+ EXPECT_TRUE(DocScrollTranslation());
+ EXPECT_EQ(DocScrollTranslation(),
+ clipper->FirstFragment().LocalBorderBoxProperties().Transform());
+ }
EXPECT_EQ(DocContentClip(),
clipper->FirstFragment().LocalBorderBoxProperties().Clip());
auto contents_properties = clipper->FirstFragment().ContentsProperties();
EXPECT_EQ(LayoutPoint(30, 20), clipper->FirstFragment().PaintOffset());
- EXPECT_EQ(DocPreTranslation(), contents_properties.Transform());
+
+ // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // scrolling.
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ EXPECT_EQ(DocPreTranslation(), contents_properties.Transform());
+ } else {
+ EXPECT_EQ(DocScrollTranslation(), contents_properties.Transform());
+ }
EXPECT_EQ(clip_properties->OverflowClip(), contents_properties.Clip());
- EXPECT_EQ(DocPreTranslation(),
- child->FirstFragment().LocalBorderBoxProperties().Transform());
+ // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // scrolling.
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ EXPECT_EQ(DocPreTranslation(),
+ child->FirstFragment().LocalBorderBoxProperties().Transform());
+ } else {
+ EXPECT_EQ(DocScrollTranslation(),
+ child->FirstFragment().LocalBorderBoxProperties().Transform());
+ }
EXPECT_EQ(clip_properties->OverflowClip(),
child->FirstFragment().LocalBorderBoxProperties().Clip());
@@ -3024,21 +3168,43 @@ TEST_P(PaintPropertyTreeBuilderTest, ContainsPaintContentsTreeState) {
clipper->FirstFragment().PaintProperties();
LayoutObject* child = GetLayoutObjectByElementId("child");
- // No scroll translation because the document does not scroll (not enough
- // content).
- EXPECT_TRUE(!DocScrollTranslation());
- EXPECT_EQ(DocPreTranslation(),
- clipper->FirstFragment().LocalBorderBoxProperties().Transform());
+ // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // scrolling.
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ EXPECT_FALSE(DocScrollTranslation());
+ EXPECT_TRUE(DocPreTranslation());
+ EXPECT_EQ(DocPreTranslation(),
+ clipper->FirstFragment().LocalBorderBoxProperties().Transform());
+ } else {
+ // Always create scroll translation for layout view even the document does
+ // not scroll (not enough content).
+ EXPECT_TRUE(DocScrollTranslation());
+ EXPECT_EQ(DocScrollTranslation(),
+ clipper->FirstFragment().LocalBorderBoxProperties().Transform());
+ }
EXPECT_EQ(DocContentClip(),
clipper->FirstFragment().LocalBorderBoxProperties().Clip());
auto contents_properties = clipper->FirstFragment().ContentsProperties();
EXPECT_EQ(LayoutPoint(30, 20), clipper->FirstFragment().PaintOffset());
- EXPECT_EQ(DocPreTranslation(), contents_properties.Transform());
+ // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // scrolling.
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ EXPECT_EQ(DocPreTranslation(), contents_properties.Transform());
+ } else {
+ EXPECT_EQ(DocScrollTranslation(), contents_properties.Transform());
+ }
EXPECT_EQ(clip_properties->OverflowClip(), contents_properties.Clip());
- EXPECT_EQ(DocPreTranslation(),
- child->FirstFragment().LocalBorderBoxProperties().Transform());
+ // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // scrolling.
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ EXPECT_EQ(DocPreTranslation(),
+ child->FirstFragment().LocalBorderBoxProperties().Transform());
+ } else {
+ EXPECT_EQ(DocScrollTranslation(),
+ child->FirstFragment().LocalBorderBoxProperties().Transform());
+ }
EXPECT_EQ(clip_properties->OverflowClip(),
child->FirstFragment().LocalBorderBoxProperties().Clip());
@@ -3160,25 +3326,39 @@ TEST_P(PaintPropertyTreeBuilderTest, CssClipContentsTreeState) {
clipper->FirstFragment().PaintProperties();
LayoutObject* child = GetLayoutObjectByElementId("child");
- // No scroll translation because the document does not scroll (not enough
- // content).
- EXPECT_TRUE(!DocScrollTranslation());
- EXPECT_EQ(DocPreTranslation(),
- clipper->FirstFragment().LocalBorderBoxProperties().Transform());
+ // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // scrolling.
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ EXPECT_TRUE(DocPreTranslation());
+ EXPECT_EQ(DocPreTranslation(),
+ clipper->FirstFragment().LocalBorderBoxProperties().Transform());
+ } else {
+ // Always create scroll translation for layout view even the document does
+ // not scroll (not enough content).
+ EXPECT_TRUE(DocScrollTranslation());
+ EXPECT_EQ(DocScrollTranslation(),
+ clipper->FirstFragment().LocalBorderBoxProperties().Transform());
+ }
// CSS clip on an element causes it to clip itself, not just descendants.
EXPECT_EQ(clip_properties->CssClip(),
clipper->FirstFragment().LocalBorderBoxProperties().Clip());
auto contents_properties = clipper->FirstFragment().ContentsProperties();
EXPECT_EQ(LayoutPoint(30, 20), clipper->FirstFragment().PaintOffset());
- EXPECT_EQ(DocPreTranslation(), contents_properties.Transform());
+ // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // scrolling.
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ EXPECT_EQ(DocPreTranslation(), contents_properties.Transform());
+ } else {
+ EXPECT_EQ(DocScrollTranslation(), contents_properties.Transform());
+ }
EXPECT_EQ(clip_properties->CssClip(), contents_properties.Clip());
CHECK_EXACT_VISUAL_RECT(LayoutRect(0, 0, 400, 500), child, clipper);
}
TEST_P(PaintPropertyTreeBuilderTest,
- SvgLocalToBorderBoxTransformContentsTreeState) {
+ ReplacedContentTransformContentsTreeState) {
SetBodyInnerHTML(R"HTML(
<style>
body {
@@ -3199,24 +3379,31 @@ TEST_P(PaintPropertyTreeBuilderTest,
LayoutObject& svg_with_view_box =
*GetLayoutObjectByElementId("svgWithViewBox");
- EXPECT_EQ(DocPreTranslation(), svg_with_view_box.FirstFragment()
- .LocalBorderBoxProperties()
- .Transform()
- ->Parent());
- EXPECT_EQ(FloatSize(30, 20), svg_with_view_box.FirstFragment()
- .LocalBorderBoxProperties()
- .Transform()
- ->Matrix()
- .To2DTranslation());
-
+ const auto* paint_offset_translation = svg_with_view_box.FirstFragment()
+ .PaintProperties()
+ ->PaintOffsetTranslation();
+ EXPECT_EQ(
+ paint_offset_translation,
+ svg_with_view_box.FirstFragment().LocalBorderBoxProperties().Transform());
+ // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // scrolling.
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ EXPECT_EQ(DocPreTranslation(), paint_offset_translation->Parent());
+ } else {
+ EXPECT_EQ(DocScrollTranslation(), paint_offset_translation->Parent());
+ }
+ EXPECT_EQ(FloatSize(30, 20),
+ paint_offset_translation->Matrix().To2DTranslation());
EXPECT_EQ(LayoutPoint(0, 0), svg_with_view_box.FirstFragment().PaintOffset());
- auto contents_properties =
- svg_with_view_box.FirstFragment().ContentsProperties();
- EXPECT_EQ(svg_with_view_box.FirstFragment()
- .PaintProperties()
- ->PaintOffsetTranslation(),
- contents_properties.Transform());
- EXPECT_EQ(DocPreTranslation(), contents_properties.Transform()->Parent());
+
+ const auto* replaced_content_transform = svg_with_view_box.FirstFragment()
+ .PaintProperties()
+ ->ReplacedContentTransform();
+ EXPECT_EQ(replaced_content_transform,
+ svg_with_view_box.FirstFragment().ContentsProperties().Transform());
+ EXPECT_EQ(paint_offset_translation, replaced_content_transform->Parent());
+ EXPECT_EQ(FloatSize(-50, -50),
+ replaced_content_transform->Matrix().To2DTranslation());
}
TEST_P(PaintPropertyTreeBuilderTest, OverflowHiddenScrollProperties) {
@@ -3277,12 +3464,18 @@ TEST_P(PaintPropertyTreeBuilderTest, FrameOverflowHiddenScrollProperties) {
GetDocument().View()->UpdateAllLifecyclePhases();
- // Because the overflow hidden does not scroll and only has a static scroll
- // offset, there should be a scroll translation node but no scroll node.
EXPECT_EQ(TransformationMatrix().Translate(0, -37),
DocScrollTranslation()->Matrix());
- EXPECT_EQ(nullptr, DocScrollTranslation()->ScrollNode());
- EXPECT_EQ(nullptr, DocScroll());
+
+ // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // scrolling.
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ EXPECT_EQ(nullptr, DocScrollTranslation()->ScrollNode());
+ EXPECT_EQ(nullptr, DocScroll());
+ } else {
+ EXPECT_TRUE(DocScrollTranslation()->ScrollNode());
+ EXPECT_TRUE(DocScroll());
+ }
}
TEST_P(PaintPropertyTreeBuilderTest, NestedScrollProperties) {
@@ -3327,9 +3520,9 @@ TEST_P(PaintPropertyTreeBuilderTest, NestedScrollProperties) {
auto* scroll_a_translation =
overflow_a_scroll_properties->ScrollTranslation();
auto* overflow_a_scroll_node = scroll_a_translation->ScrollNode();
- // TODO(bokan): Viewport property node generation has been disabled
- // temporarily with the flag off to diagnose https//crbug.com/868927.
- if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
+ // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // scrolling.
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
EXPECT_EQ(GetDocument()
.GetPage()
->GetVisualViewport()
@@ -3337,7 +3530,7 @@ TEST_P(PaintPropertyTreeBuilderTest, NestedScrollProperties) {
->ScrollNode(),
overflow_a_scroll_node->Parent());
} else {
- EXPECT_TRUE(overflow_a_scroll_node->Parent()->IsRoot());
+ EXPECT_EQ(DocScroll(), overflow_a_scroll_node->Parent());
}
EXPECT_EQ(TransformationMatrix().Translate(0, -37),
scroll_a_translation->Matrix());
@@ -3455,7 +3648,8 @@ TEST_P(PaintPropertyTreeBuilderTest, PositionedScrollerIsNotNested) {
auto* fixed_overflow_scroll_node = fixed_scroll_translation->ScrollNode();
// The fixed position overflow scroll node is parented under the root, not the
// dom-order parent or frame's scroll.
- if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled() ||
+ RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
EXPECT_EQ(GetDocument()
.GetPage()
->GetVisualViewport()
@@ -3463,6 +3657,7 @@ TEST_P(PaintPropertyTreeBuilderTest, PositionedScrollerIsNotNested) {
->ScrollNode(),
fixed_overflow_scroll_node->Parent());
} else {
+ // Pre-BGPT we don't create the visual viewport property nodes.
EXPECT_TRUE(fixed_overflow_scroll_node->Parent()->IsRoot());
}
EXPECT_EQ(TransformationMatrix().Translate(0, -43),
@@ -3520,9 +3715,9 @@ TEST_P(PaintPropertyTreeBuilderTest, NestedPositionedScrollProperties) {
auto* scroll_a_translation =
overflow_a_scroll_properties->ScrollTranslation();
auto* overflow_a_scroll_node = scroll_a_translation->ScrollNode();
- // TODO(bokan): Viewport property node generation has been disabled
- // temporarily with the flag off to diagnose https//crbug.com/868927.
- if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
+ // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // scrolling.
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
EXPECT_EQ(GetDocument()
.GetPage()
->GetVisualViewport()
@@ -3530,7 +3725,7 @@ TEST_P(PaintPropertyTreeBuilderTest, NestedPositionedScrollProperties) {
->ScrollNode(),
overflow_a_scroll_node->Parent());
} else {
- EXPECT_TRUE(overflow_a_scroll_node->Parent()->IsRoot());
+ EXPECT_EQ(DocScroll(), overflow_a_scroll_node->Parent());
}
EXPECT_EQ(TransformationMatrix().Translate(0, -37),
scroll_a_translation->Matrix());
@@ -3779,7 +3974,7 @@ TEST_P(PaintPropertyTreeBuilderTest, FragmentsUnderMultiColumn) {
const auto* fragment_clip =
FragmentAt(flowthread, 0).PaintProperties()->FragmentClip();
ASSERT_NE(nullptr, fragment_clip);
- EXPECT_EQ(FloatRect(-1000000, -1000000, 1000100, 1000030),
+ EXPECT_EQ(FloatRect(-1000000, -1000000, 2000000, 1000030),
fragment_clip->ClipRect().Rect());
EXPECT_EQ(fragment_clip,
FragmentAt(relpos, 0).LocalBorderBoxProperties().Clip());
@@ -3794,7 +3989,8 @@ TEST_P(PaintPropertyTreeBuilderTest, FragmentsUnderMultiColumn) {
EXPECT_EQ(LayoutUnit(30), FragmentAt(flowthread, 1).LogicalTopInFlowThread());
fragment_clip = FragmentAt(flowthread, 1).PaintProperties()->FragmentClip();
ASSERT_NE(nullptr, fragment_clip);
- EXPECT_EQ(FloatRect(100, 0, 1000000, 30), fragment_clip->ClipRect().Rect());
+ EXPECT_EQ(FloatRect(-999900, 0, 2000000, 30),
+ fragment_clip->ClipRect().Rect());
EXPECT_EQ(fragment_clip,
FragmentAt(relpos, 1).LocalBorderBoxProperties().Clip());
@@ -3807,7 +4003,7 @@ TEST_P(PaintPropertyTreeBuilderTest, FragmentsUnderMultiColumn) {
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, 1000100, 30),
+ EXPECT_EQ(FloatRect(-1000000, 80, 2000000, 30),
fragment_clip->ClipRect().Rect());
EXPECT_EQ(fragment_clip,
FragmentAt(relpos, 2).LocalBorderBoxProperties().Clip());
@@ -3822,7 +4018,7 @@ TEST_P(PaintPropertyTreeBuilderTest, FragmentsUnderMultiColumn) {
EXPECT_EQ(LayoutUnit(90), FragmentAt(flowthread, 3).LogicalTopInFlowThread());
fragment_clip = FragmentAt(flowthread, 3).PaintProperties()->FragmentClip();
ASSERT_NE(nullptr, fragment_clip);
- EXPECT_EQ(FloatRect(100, 80, 1000000, 999910),
+ EXPECT_EQ(FloatRect(-999900, 80, 2000000, 999910),
fragment_clip->ClipRect().Rect());
EXPECT_EQ(fragment_clip,
FragmentAt(relpos, 3).LocalBorderBoxProperties().Clip());
@@ -4734,21 +4930,49 @@ TEST_P(PaintPropertyTreeBuilderTest, SVGHiddenResource) {
transform_outside_use_properties->Transform()->Parent());
}
-TEST_P(PaintPropertyTreeBuilderTest, SVGRootBlending) {
+TEST_P(PaintPropertyTreeBuilderTest, SVGBlending) {
SetBodyInnerHTML(R"HTML(
- <svg id='svgroot' 'width=100' height='100'
+ <svg id='svgroot' width='100' height='100'
style='position: relative; z-index: 0'>
- <rect width='100' height='100' fill='#00FF00'
- style='mix-blend-mode: difference'/>
+ <rect id='rect' width='100' height='100' fill='#00FF00'
+ style='mix-blend-mode: difference'/>
</svg>
)HTML");
- LayoutObject& svg_root = *GetLayoutObjectByElementId("svgroot");
- const ObjectPaintProperties* svg_root_properties =
- svg_root.FirstFragment().PaintProperties();
- EXPECT_TRUE(svg_root_properties->Effect());
+ const auto* rect_properties = PaintPropertiesForElement("rect");
+ ASSERT_TRUE(rect_properties->Effect());
+ EXPECT_EQ(SkBlendMode::kDifference, rect_properties->Effect()->BlendMode());
+
+ const auto* svg_root_properties = PaintPropertiesForElement("svgroot");
+ ASSERT_TRUE(svg_root_properties->Effect());
+ EXPECT_EQ(SkBlendMode::kSrcOver, svg_root_properties->Effect()->BlendMode());
+
EXPECT_EQ(&EffectPaintPropertyNode::Root(),
svg_root_properties->Effect()->Parent());
+ EXPECT_EQ(svg_root_properties->Effect(), rect_properties->Effect()->Parent());
+}
+
+TEST_P(PaintPropertyTreeBuilderTest, SVGRootBlending) {
+ SetBodyInnerHTML(R"HTML(
+ <svg id='svgroot' 'width=100' height='100' style='mix-blend-mode: multiply'>
+ </svg>
+ )HTML");
+
+ const auto* html_properties = GetDocument()
+ .documentElement()
+ ->GetLayoutObject()
+ ->FirstFragment()
+ .PaintProperties();
+ ASSERT_TRUE(html_properties->Effect());
+ EXPECT_EQ(SkBlendMode::kSrcOver, html_properties->Effect()->BlendMode());
+
+ const auto* svg_root_properties = PaintPropertiesForElement("svgroot");
+ ASSERT_TRUE(svg_root_properties->Effect());
+ EXPECT_EQ(SkBlendMode::kMultiply, svg_root_properties->Effect()->BlendMode());
+
+ EXPECT_EQ(&EffectPaintPropertyNode::Root(),
+ html_properties->Effect()->Parent());
+ EXPECT_EQ(html_properties->Effect(), svg_root_properties->Effect()->Parent());
}
TEST_P(PaintPropertyTreeBuilderTest, ScrollBoundsOffset) {
@@ -4785,9 +5009,9 @@ TEST_P(PaintPropertyTreeBuilderTest, ScrollBoundsOffset) {
auto* scroll_translation = scroll_properties->ScrollTranslation();
auto* paint_offset_translation = scroll_properties->PaintOffsetTranslation();
auto* scroll_node = scroll_translation->ScrollNode();
- // TODO(bokan): Viewport property node generation has been disabled
- // temporarily with the flag off to diagnose https//crbug.com/868927.
- if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
+ // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // scrolling.
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
EXPECT_EQ(GetDocument()
.GetPage()
->GetVisualViewport()
@@ -4795,7 +5019,7 @@ TEST_P(PaintPropertyTreeBuilderTest, ScrollBoundsOffset) {
->ScrollNode(),
scroll_node->Parent());
} else {
- EXPECT_TRUE(scroll_node->Parent()->IsRoot());
+ EXPECT_EQ(DocScroll(), scroll_node->Parent());
}
EXPECT_EQ(TransformationMatrix().Translate(0, -42),
scroll_translation->Matrix());
@@ -4879,15 +5103,22 @@ TEST_P(PaintPropertyTreeBuilderTest, FrameBorderRadius) {
)HTML");
const auto* properties = PaintPropertiesForElement("iframe");
- const auto* border_radius_clip = properties->InnerBorderRadiusClip();
+ const auto* border_radius_clip = properties->OverflowClip();
ASSERT_NE(nullptr, border_radius_clip);
FloatSize radius(30, 30);
EXPECT_EQ(FloatRoundedRect(FloatRect(28, 28, 200, 200), radius, radius,
radius, radius),
border_radius_clip->ClipRect());
EXPECT_EQ(DocContentClip(), border_radius_clip->Parent());
- EXPECT_EQ(DocPreTranslation(), border_radius_clip->LocalTransformSpace());
- EXPECT_EQ(nullptr, properties->OverflowClip());
+ // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // scrolling.
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ EXPECT_EQ(DocPreTranslation(), border_radius_clip->LocalTransformSpace());
+ } else {
+ EXPECT_EQ(DocScrollTranslation(),
+ border_radius_clip->LocalTransformSpace());
+ }
+ EXPECT_EQ(nullptr, properties->InnerBorderRadiusClip());
}
TEST_P(PaintPropertyTreeBuilderTest, NoPropertyForSVGTextWithReflection) {
@@ -4906,15 +5137,22 @@ TEST_P(PaintPropertyTreeBuilderTest, ImageBorderRadius) {
)HTML");
const auto* properties = PaintPropertiesForElement("img");
- const auto* border_radius_clip = properties->InnerBorderRadiusClip();
+ const auto* border_radius_clip = properties->OverflowClip();
ASSERT_NE(nullptr, border_radius_clip);
FloatSize radius(20, 20);
EXPECT_EQ(FloatRoundedRect(FloatRect(18, 18, 50, 50), radius, radius, radius,
radius),
border_radius_clip->ClipRect());
EXPECT_EQ(DocContentClip(), border_radius_clip->Parent());
- EXPECT_EQ(DocPreTranslation(), border_radius_clip->LocalTransformSpace());
- EXPECT_EQ(nullptr, properties->OverflowClip());
+ // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // scrolling.
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ EXPECT_EQ(DocPreTranslation(), border_radius_clip->LocalTransformSpace());
+ } else {
+ EXPECT_EQ(DocScrollTranslation(),
+ border_radius_clip->LocalTransformSpace());
+ }
+ EXPECT_EQ(nullptr, properties->InnerBorderRadiusClip());
}
TEST_P(PaintPropertyTreeBuilderTest, FrameClipWhenPrinting) {
@@ -5048,9 +5286,10 @@ TEST_P(PaintPropertyTreeBuilderTest, FragmentClipPixelSnapped) {
const auto* second_clip =
FragmentAt(flow_thread, 1).PaintProperties()->FragmentClip();
- EXPECT_EQ(FloatRect(-999992, -999992, 1000025, 1000050),
+ EXPECT_EQ(FloatRect(-999992, -999992, 2000000, 1000050),
first_clip->ClipRect().Rect());
- EXPECT_EQ(FloatRect(33, 8, 1000000, 999951), second_clip->ClipRect().Rect());
+ EXPECT_EQ(FloatRect(-999967, 8, 2000000, 999951),
+ second_clip->ClipRect().Rect());
}
TEST_P(PaintPropertyTreeBuilderTest,
@@ -5149,9 +5388,15 @@ TEST_P(PaintPropertyTreeBuilderTest, RootHasCompositedScrolling) {
Element* force_scroll_element = GetDocument().getElementById("forceScroll");
force_scroll_element->setAttribute(HTMLNames::styleAttr, "");
GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
- // Without scrolling, the root should not have direct compositing reasons or
- // even a scroll node.
- EXPECT_EQ(nullptr, DocScrollTranslation());
+ // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // scrolling.
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ EXPECT_FALSE(DocScrollTranslation());
+ } else {
+ // Always create scroll translation for layout view even the document does
+ // not scroll (not enough content).
+ EXPECT_TRUE(DocScrollTranslation());
+ }
}
TEST_P(PaintPropertyTreeBuilderTest, IframeDoesNotRequireCompositedScrolling) {
@@ -5544,7 +5789,7 @@ TEST_P(PaintPropertyTreeBuilderTest, ImageWithInvertFilterUpdated) {
ToLayoutImage(GetLayoutObjectByElementId("img"))
->UpdateShouldInvertColorForTest(false);
GetDocument().View()->UpdateAllLifecyclePhases();
- EXPECT_EQ(nullptr, PaintPropertiesForElement("img"));
+ EXPECT_FALSE(PaintPropertiesForElement("img"));
}
TEST_P(PaintPropertyTreeBuilderTest, LayeredImageWithInvertFilter) {
@@ -5577,7 +5822,7 @@ TEST_P(PaintPropertyTreeBuilderTest, LayeredImageWithInvertFilterUpdated) {
ToLayoutImage(GetLayoutObjectByElementId("img"))
->UpdateShouldInvertColorForTest(false);
GetDocument().View()->UpdateAllLifecyclePhases();
- EXPECT_EQ(nullptr, PaintPropertiesForElement("img"));
+ EXPECT_FALSE(PaintPropertiesForElement("img"));
}
TEST_P(PaintPropertyTreeBuilderTest,
@@ -5634,4 +5879,133 @@ TEST_P(PaintPropertyTreeBuilderTest,
EXPECT_EQ(LayoutPoint(100, 85), paint_offset("float-right-rtl-vlr"));
}
+TEST_P(PaintPropertyTreeBuilderTest, ClipInvalidationForReplacedElement) {
+ // Non-composited LayoutImage has a micro-optimization to embed object-fit
+ // and clip to the drawing, thus not creating nodes.
+ // SPv2 makes everything non-composited essentially.
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ return;
+ // This test verifies clip nodes are correctly updated in response to
+ // content box mutation.
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ img {
+ box-sizing: border-box;
+ width: 8px;
+ height: 8px;
+ object-fit: none;
+ will-change: transform;
+ }
+ </style>
+ <!-- An image of 10x10 white pixels. -->
+ <img id="target" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAA
+ AAKCAIAAAACUFjqAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gcVABQvx8CBmA
+ AAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAFUlEQVQY02P
+ 8//8/A27AxIAXjFRpAKXjAxH/0Dm5AAAAAElFTkSuQmCC"/>
+ )HTML");
+
+ {
+ const auto* properties = PaintPropertiesForElement("target");
+ ASSERT_TRUE(properties);
+ ASSERT_TRUE(properties->OverflowClip());
+ EXPECT_EQ(FloatRect(0, 0, 8, 8),
+ properties->OverflowClip()->ClipRect().Rect());
+ }
+
+ GetDocument().getElementById("target")->setAttribute(
+ HTMLNames::styleAttr, "padding: 1px 2px 3px 4px;");
+ GetDocument().View()->UpdateAllLifecyclePhases();
+
+ {
+ const auto* properties = PaintPropertiesForElement("target");
+ ASSERT_TRUE(properties);
+ ASSERT_TRUE(properties->OverflowClip());
+ EXPECT_EQ(FloatRect(4, 1, 2, 4),
+ properties->OverflowClip()->ClipRect().Rect());
+ }
+}
+
+TEST_P(PaintPropertyTreeBuilderTest, SubpixelPositionedScrollNode) {
+ SetBodyInnerHTML(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ #scroller {
+ position: relative;
+ top: 0.5625px;
+ width: 200px;
+ height: 200.8125px;
+ overflow: auto;
+ }
+ #space {
+ width: 1000px;
+ height: 200.8125px;
+ }
+ </style>
+ <div id="scroller">
+ <div id="space"></div>
+ </div>
+ )HTML");
+
+ const auto* properties = PaintPropertiesForElement("scroller");
+ const auto* scroll_node = properties->ScrollTranslation()->ScrollNode();
+ EXPECT_EQ(IntRect(0, 0, 200, 200), scroll_node->ContainerRect());
+ EXPECT_EQ(IntRect(0, 0, 1000, 200), scroll_node->ContentsRect());
+}
+
+TEST_P(PaintPropertyTreeBuilderTest,
+ LayoutMenuListHasOverlowAndLocalBorderBoxProperties) {
+ SetBodyInnerHTML(R"HTML(
+ <!doctype HTML>
+ <select id="selection" style="width: 80px;">
+ <option>lorem ipsum dolor</option>
+ </select>
+ )HTML");
+
+ const auto& fragment = GetDocument()
+ .getElementById("selection")
+ ->GetLayoutObject()
+ ->FirstFragment();
+
+ EXPECT_TRUE(fragment.PaintProperties());
+ EXPECT_TRUE(fragment.PaintProperties()->OverflowClip());
+ ASSERT_TRUE(fragment.HasLocalBorderBoxProperties());
+ EXPECT_EQ(fragment.ContentsProperties().Clip(),
+ fragment.PaintProperties()->OverflowClip());
+}
+
+TEST_P(PaintPropertyTreeBuilderTest, SkipEmptyClipFragments) {
+ SetBodyInnerHTML(R"HTML(
+ <!doctype HTML>
+ <style>h4 { column-span: all; }</style>
+ <div id="container" style="columns:1;">
+ lorem
+ <h4>hi</h4>
+ <div><h4>hello</h4></div>
+ ipsum
+ </div>
+ )HTML");
+
+ const auto* flow_thread = GetDocument()
+ .getElementById("container")
+ ->GetLayoutObject()
+ ->SlowFirstChild();
+ EXPECT_TRUE(flow_thread->IsLayoutFlowThread());
+ EXPECT_TRUE(ToLayoutFlowThread(flow_thread)->IsLayoutMultiColumnFlowThread());
+
+ // FragmentainerIterator would return 3 things:
+ // 1. A fragment that contains "lorem" and is interrupted by the first h4,
+ // since it's column-span: all.
+ // 2. A fragment that starts at the inner div of height 0 and is immediately
+ // interrupted by a nested h4.
+ // 3. A fragment that contains "ipsum".
+ //
+ // The second fragment would have an empty clip and the same logical top as
+ // the third fragment. This test ensures that this fragment is not present in
+ // the LayoutMultiColumnFlowThread's fragments.
+ EXPECT_EQ(2u, NumFragments(flow_thread));
+ EXPECT_NE(
+ flow_thread->FirstFragment().LogicalTopInFlowThread(),
+ flow_thread->FirstFragment().NextFragment()->LogicalTopInFlowThread());
+}
+
} // namespace blink
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 e407f3d2d33..c2d5fa070e0 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
@@ -68,6 +68,7 @@ class PropertyTreePrinterTraits<TransformPaintPropertyNode> {
static void AddVisualViewportProperties(
const VisualViewport& visual_viewport,
PropertyTreePrinter<TransformPaintPropertyNode>& printer) {
+ printer.AddNode(visual_viewport.GetOverscrollElasticityTransformNode());
printer.AddNode(visual_viewport.GetPageScaleNode());
printer.AddNode(visual_viewport.GetScrollTranslationNode());
}
@@ -78,7 +79,7 @@ class PropertyTreePrinterTraits<TransformPaintPropertyNode> {
printer.AddNode(properties.PaintOffsetTranslation());
printer.AddNode(properties.Transform());
printer.AddNode(properties.Perspective());
- printer.AddNode(properties.SvgLocalToBorderBoxTransform());
+ printer.AddNode(properties.ReplacedContentTransform());
printer.AddNode(properties.ScrollTranslation());
}
};
@@ -170,8 +171,8 @@ void UpdateDebugNames(const LayoutObject& object,
object);
SetDebugName(properties.Transform(), "Transform", object);
SetDebugName(properties.Perspective(), "Perspective", object);
- SetDebugName(properties.SvgLocalToBorderBoxTransform(),
- "SvgLocalToBorderBoxTransform", object);
+ SetDebugName(properties.ReplacedContentTransform(),
+ "ReplacedContentTransform", object);
SetDebugName(properties.ScrollTranslation(), "ScrollTranslation", object);
SetDebugName(properties.FragmentClip(), "FragmentClip", object);
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 9c0248b1125..5ec00c40bd9 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
@@ -268,10 +268,8 @@ TEST_P(PaintPropertyTreeUpdateTest,
->ScrollTranslation()
->ScrollNode()
->HasBackgroundAttachmentFixedDescendants());
-
- // TODO(bokan): Viewport property node generation has been disabled
- // temporarily with the flag off to diagnose https//crbug.com/868927.
- if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled() ||
+ RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
EXPECT_EQ(visual_viewport.GetScrollNode(), overflow_b->GetLayoutObject()
->FirstFragment()
.PaintProperties()
@@ -279,13 +277,14 @@ TEST_P(PaintPropertyTreeUpdateTest,
->ScrollNode()
->Parent());
} else {
+ // Pre-BGPT we don't create the visual viewport property nodes.
EXPECT_TRUE(overflow_b->GetLayoutObject()
- ->FirstFragment()
- .PaintProperties()
- ->ScrollTranslation()
- ->ScrollNode()
- ->Parent()
- ->IsRoot());
+ ->FirstFragment()
+ .PaintProperties()
+ ->ScrollTranslation()
+ ->ScrollNode()
+ ->Parent()
+ ->IsRoot());
}
// Removing a main thread scrolling reason should update the entire tree.
@@ -803,6 +802,37 @@ TEST_P(PaintPropertyTreeUpdateTest, ScrollBoundsChange) {
EXPECT_EQ(IntRect(0, 0, 200, 300), scroll_node->ContentsRect());
}
+// The scrollbars are attached to the visual viewport but created by (and have
+// space saved by) the frame view. So we need to exclude them from the container
+// rect but also from the contents rect because we don't want to be able to
+// scroll into the region saved for scrollbars.
+TEST_P(PaintPropertyTreeUpdateTest,
+ ViewportContentsAndContainerRectsDoNotIncludeScrollbar) {
+ // Pre-BGPT we don't create the visual viewport property nodes.
+ if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled() &&
+ !RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled())
+ return;
+
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ ::-webkit-scrollbar {width: 20px; height: 20px}
+ body {height: 10000px; width: 10000px; margin: 0;}
+ </style>
+ )HTML");
+
+ VisualViewport& visual_viewport =
+ GetDocument().GetPage()->GetVisualViewport();
+
+ // TODO(bokan): Viewport property node generation has been disabled
+ // temporarily with the flag off to diagnose https://crbug.com/868927.
+ if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
+ EXPECT_EQ(IntRect(0, 0, 780, 580),
+ visual_viewport.GetScrollNode()->ContainerRect());
+ EXPECT_EQ(IntRect(0, 0, 780, 580),
+ visual_viewport.GetScrollNode()->ContentsRect());
+ }
+}
+
TEST_P(PaintPropertyTreeUpdateTest, ScrollbarWidthChange) {
SetBodyInnerHTML(R"HTML(
<style>::-webkit-scrollbar {width: 20px; height: 20px}</style>
@@ -1202,36 +1232,36 @@ TEST_P(PaintPropertyTreeUpdateTest,
auto* flow_thread = GetLayoutObjectByElementId("multicol")->SlowFirstChild();
ASSERT_EQ(2u, NumFragments(flow_thread));
- EXPECT_EQ(50, FragmentAt(flow_thread, 0)
- .PaintProperties()
- ->FragmentClip()
- ->ClipRect()
- .Rect()
- .MaxX());
- EXPECT_EQ(50, FragmentAt(flow_thread, 1)
- .PaintProperties()
- ->FragmentClip()
- ->ClipRect()
- .Rect()
- .X());
+ EXPECT_EQ(1000000, FragmentAt(flow_thread, 0)
+ .PaintProperties()
+ ->FragmentClip()
+ ->ClipRect()
+ .Rect()
+ .MaxX());
+ EXPECT_EQ(-999950, FragmentAt(flow_thread, 1)
+ .PaintProperties()
+ ->FragmentClip()
+ ->ClipRect()
+ .Rect()
+ .X());
GetDocument()
.getElementById("container")
->setAttribute(HTMLNames::styleAttr, "width: 500px");
GetDocument().View()->UpdateAllLifecyclePhases();
ASSERT_EQ(2u, NumFragments(flow_thread));
- EXPECT_EQ(250, FragmentAt(flow_thread, 0)
- .PaintProperties()
- ->FragmentClip()
- ->ClipRect()
- .Rect()
- .MaxX());
- EXPECT_EQ(250, FragmentAt(flow_thread, 1)
- .PaintProperties()
- ->FragmentClip()
- ->ClipRect()
- .Rect()
- .X());
+ EXPECT_EQ(1000000, FragmentAt(flow_thread, 0)
+ .PaintProperties()
+ ->FragmentClip()
+ ->ClipRect()
+ .Rect()
+ .MaxX());
+ EXPECT_EQ(-999750, FragmentAt(flow_thread, 1)
+ .PaintProperties()
+ ->FragmentClip()
+ ->ClipRect()
+ .Rect()
+ .X());
}
TEST_P(PaintPropertyTreeUpdateTest,
@@ -1264,4 +1294,52 @@ TEST_P(PaintPropertyTreeUpdateTest,
EXPECT_EQ(props->Effect()->BlendMode(), SkBlendMode::kLighten);
}
+TEST_P(PaintPropertyTreeUpdateTest, EnsureSnapContainerData) {
+ SetBodyInnerHTML(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ body {
+ overflow: scroll;
+ scroll-snap-type: both proximity;
+ height: 300px;
+ width: 300px;
+ margin: 0px;
+ padding: 0px;
+ }
+ #container {
+ margin: 0px;
+ padding: 0px;
+ width: 600px;
+ height: 2000px;
+ }
+ #area {
+ position: relative;
+ left: 100px;
+ top: 700px;
+ width: 200px;
+ height: 200px;
+ scroll-snap-align: start;
+ }
+
+ </style>
+
+ <div id="container">
+ <div id="area"></div>
+ </div>
+ )HTML");
+
+ GetDocument().View()->Resize(300, 300);
+ GetDocument().View()->UpdateAllLifecyclePhases();
+
+ auto doc_snap_container_data = DocScroll()->SnapContainerData();
+ ASSERT_TRUE(doc_snap_container_data);
+ EXPECT_EQ(doc_snap_container_data->scroll_snap_type().axis, SnapAxis::kBoth);
+ EXPECT_EQ(doc_snap_container_data->scroll_snap_type().strictness,
+ SnapStrictness::kProximity);
+ EXPECT_EQ(doc_snap_container_data->rect(), gfx::RectF(0, 0, 300, 300));
+ EXPECT_EQ(doc_snap_container_data->size(), 1u);
+ EXPECT_EQ(doc_snap_container_data->at(0).rect,
+ gfx::RectF(100, 700, 200, 200));
+}
+
} // namespace blink
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 950858001dd..b9963652687 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_timing.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_timing.cc
@@ -157,7 +157,7 @@ void PaintTiming::Trace(blink::Visitor* visitor) {
PaintTiming::PaintTiming(Document& document)
: Supplement<Document>(document),
- fmp_detector_(new FirstMeaningfulPaintDetector(this, document)) {}
+ fmp_detector_(new FirstMeaningfulPaintDetector(this)) {}
LocalFrame* PaintTiming::GetFrame() const {
return GetSupplementable()->GetFrame();
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 78fa2485612..06303df473e 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
@@ -46,7 +46,8 @@ void PrePaintTreeWalk::WalkTree(LocalFrameView& root_frame_view) {
if (needs_tree_builder_context_update)
GeometryMapper::ClearCache();
- if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
+ if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled() ||
+ RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
VisualViewportPaintPropertyTreeBuilder::Update(
root_frame_view.GetPage()->GetVisualViewport(),
*context_storage_.back().tree_builder_context);
@@ -167,6 +168,12 @@ bool HasBlockingTouchEventHandler(const LayoutObject& object) {
}
auto* node = object.GetNode();
+ if (!node && object.IsLayoutBlockFlow() &&
+ ToLayoutBlockFlow(object).IsAnonymousBlockContinuation()) {
+ // An anonymous continuation does not have handlers so we need to check the
+ // DOM ancestor for handlers using |NodeForHitTest|.
+ node = object.NodeForHitTest();
+ }
if (!node)
return false;
return HasBlockingTouchEventHandler(*object.GetFrame(), *node);
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 7ba16801482..3b5719b59f8 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
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/paint/pre_paint_tree_walk.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/core/dom/events/event_listener.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/layout/layout_tree_as_text.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
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 b6219caf7b1..b0580f48ccb 100644
--- a/chromium/third_party/blink/renderer/core/paint/replaced_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/replaced_painter.cc
@@ -8,31 +8,43 @@
#include "third_party/blink/renderer/core/layout/api/selection_state.h"
#include "third_party/blink/renderer/core/layout/layout_replaced.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_root.h"
-#include "third_party/blink/renderer/core/paint/adjust_paint_offset_scope.h"
#include "third_party/blink/renderer/core/paint/box_painter.h"
#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.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_info_with_offset.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/core/paint/rounded_inner_rect_clipper.h"
+#include "third_party/blink/renderer/core/paint/scrollable_area_painter.h"
#include "third_party/blink/renderer/core/paint/selection_painting_utils.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_paint_chunk_properties.h"
namespace blink {
void ReplacedPainter::Paint(const PaintInfo& paint_info) {
- AdjustPaintOffsetScope adjustment(layout_replaced_, paint_info);
- const auto& local_paint_info = adjustment.GetPaintInfo();
- auto paint_offset = adjustment.PaintOffset();
+ // TODO(crbug.com/797779): For now embedded contents don't know whether
+ // they are painted in a fragmented context and may do something bad in a
+ // fragmented context, e.g. creating subsequences. Skip cache to avoid that.
+ // This will be unnecessary when the contents are fragment aware.
+ base::Optional<DisplayItemCacheSkipper> cache_skipper;
+ if (layout_replaced_.IsLayoutEmbeddedContent()) {
+ DCHECK(layout_replaced_.HasLayer());
+ if (layout_replaced_.Layer()->EnclosingPaginationLayer())
+ cache_skipper.emplace(paint_info.context);
+ }
- if (!ShouldPaint(local_paint_info, paint_offset))
+ PaintInfoWithOffset paint_info_with_offset(layout_replaced_, paint_info);
+ if (!ShouldPaint(paint_info_with_offset))
return;
+ const auto& local_paint_info = paint_info_with_offset.GetPaintInfo();
+ auto paint_offset = paint_info_with_offset.PaintOffset();
LayoutRect border_rect(paint_offset, layout_replaced_.Size());
if (ShouldPaintSelfBlockBackground(local_paint_info.phase)) {
- if (layout_replaced_.Style()->Visibility() == EVisibility::kVisible &&
+ if (layout_replaced_.StyleRef().Visibility() == EVisibility::kVisible &&
layout_replaced_.HasBoxDecorationBackground()) {
if (layout_replaced_.HasLayer() &&
layout_replaced_.Layer()->GetCompositingState() ==
@@ -42,8 +54,8 @@ void ReplacedPainter::Paint(const PaintInfo& paint_info) {
->DrawsBackgroundOntoContentLayer())
return;
- layout_replaced_.PaintBoxDecorationBackground(local_paint_info,
- paint_offset);
+ BoxPainter(layout_replaced_)
+ .PaintBoxDecorationBackground(local_paint_info, paint_offset);
}
// We're done. We don't bother painting any children.
if (local_paint_info.phase == PaintPhase::kSelfBlockBackgroundOnly)
@@ -51,7 +63,7 @@ void ReplacedPainter::Paint(const PaintInfo& paint_info) {
}
if (local_paint_info.phase == PaintPhase::kMask) {
- layout_replaced_.PaintMask(local_paint_info, paint_offset);
+ BoxPainter(layout_replaced_).PaintMask(local_paint_info, paint_offset);
return;
}
@@ -70,45 +82,68 @@ void ReplacedPainter::Paint(const PaintInfo& paint_info) {
layout_replaced_.GetSelectionState() == SelectionState::kNone)
return;
- {
+ bool skip_clip = layout_replaced_.IsSVGRoot() &&
+ !ToLayoutSVGRoot(layout_replaced_).ShouldApplyViewportClip();
+ if (skip_clip || !layout_replaced_.PhysicalContentBoxRect().IsEmpty()) {
+ PaintInfo transformed_paint_info = local_paint_info;
base::Optional<ScopedPaintChunkProperties> chunk_properties;
- bool completely_clipped_out = false;
-
- if (layout_replaced_.Style()->HasBorderRadius() && border_rect.IsEmpty())
- completely_clipped_out = true;
-
- if (!layout_replaced_.IsSVGRoot()) {
- if (const auto* fragment = paint_info.FragmentToPaint(layout_replaced_)) {
- if (const auto* paint_properties = fragment->PaintProperties()) {
- // Check filter for optimized image policy violation highlights, which
- // may be applied locally.
- if (paint_properties->Filter() &&
- (!layout_replaced_.HasLayer() ||
- !layout_replaced_.Layer()->IsSelfPaintingLayer())) {
- chunk_properties.emplace(
- local_paint_info.context.GetPaintController(),
- fragment->ContentsProperties(), layout_replaced_,
- DisplayItem::PaintPhaseToDrawingType(local_paint_info.phase));
- } else if (layout_replaced_.Style()->HasBorderRadius()) {
- DCHECK(paint_properties->InnerBorderRadiusClip());
- chunk_properties.emplace(
- local_paint_info.context.GetPaintController(),
- paint_properties->InnerBorderRadiusClip(), layout_replaced_,
- DisplayItem::PaintPhaseToDrawingType(local_paint_info.phase));
- }
+ if (const auto* fragment = paint_info.FragmentToPaint(layout_replaced_)) {
+ if (const auto* paint_properties = fragment->PaintProperties()) {
+ PropertyTreeState new_properties =
+ local_paint_info.context.GetPaintController()
+ .CurrentPaintChunkProperties();
+ bool property_changed = false;
+ if (paint_properties->ReplacedContentTransform() &&
+ layout_replaced_.IsSVGRoot()) {
+ new_properties.SetTransform(
+ paint_properties->ReplacedContentTransform());
+ DCHECK(paint_properties->ReplacedContentTransform()
+ ->Matrix()
+ .IsAffine());
+ transformed_paint_info.UpdateCullRect(
+ paint_properties->ReplacedContentTransform()
+ ->Matrix()
+ .ToAffineTransform());
+ property_changed = true;
+ }
+ bool painter_implements_content_box_clip =
+ layout_replaced_.IsLayoutImage();
+ if (paint_properties->OverflowClip() &&
+ (!painter_implements_content_box_clip ||
+ layout_replaced_.StyleRef().HasBorderRadius())) {
+ new_properties.SetClip(paint_properties->OverflowClip());
+ property_changed = true;
+ }
+ // Check filter for optimized image policy violation highlights, which
+ // may be applied locally.
+ if (paint_properties->Filter() &&
+ (!layout_replaced_.HasLayer() ||
+ !layout_replaced_.Layer()->IsSelfPaintingLayer())) {
+ new_properties.SetEffect(paint_properties->Filter());
+ property_changed = true;
+ }
+ if (property_changed) {
+ chunk_properties.emplace(
+ local_paint_info.context.GetPaintController(), new_properties,
+ layout_replaced_, paint_info.DisplayItemTypeForClipping());
}
}
}
- if (!completely_clipped_out)
- layout_replaced_.PaintReplaced(local_paint_info, paint_offset);
+ layout_replaced_.PaintReplaced(transformed_paint_info, paint_offset);
+ }
+
+ if (layout_replaced_.CanResize()) {
+ ScrollableAreaPainter(*layout_replaced_.Layer()->GetScrollableArea())
+ .PaintResizer(local_paint_info.context, RoundedIntPoint(paint_offset),
+ local_paint_info.GetCullRect());
}
// The selection tint never gets clipped by border-radius rounding, since we
// want it to run right up to the edges of surrounding content.
bool draw_selection_tint =
local_paint_info.phase == PaintPhase::kForeground &&
- layout_replaced_.GetSelectionState() != SelectionState::kNone &&
+ IsSelected(layout_replaced_.GetSelectionState()) &&
!local_paint_info.IsPrinting();
if (draw_selection_tint && !DrawingRecorder::UseCachedDrawingIfPossible(
local_paint_info.context, layout_replaced_,
@@ -128,8 +163,9 @@ void ReplacedPainter::Paint(const PaintInfo& paint_info) {
}
}
-bool ReplacedPainter::ShouldPaint(const PaintInfo& paint_info,
- const LayoutPoint& paint_offset) const {
+bool ReplacedPainter::ShouldPaint(
+ const PaintInfoWithOffset& paint_info_with_offset) const {
+ const auto& paint_info = paint_info_with_offset.GetPaintInfo();
if (paint_info.phase != PaintPhase::kForeground &&
!ShouldPaintSelfOutline(paint_info.phase) &&
paint_info.phase != PaintPhase::kSelection &&
@@ -144,14 +180,13 @@ bool ReplacedPainter::ShouldPaint(const PaintInfo& paint_info,
// But if it's an SVG root, there can be children, so we'll check visibility
// later.
if (!layout_replaced_.IsSVGRoot() &&
- layout_replaced_.Style()->Visibility() != EVisibility::kVisible)
+ layout_replaced_.StyleRef().Visibility() != EVisibility::kVisible)
return false;
- LayoutRect paint_rect(layout_replaced_.VisualOverflowRect());
- paint_rect.Unite(layout_replaced_.LocalSelectionRect());
- paint_rect.MoveBy(paint_offset);
-
- if (!paint_info.GetCullRect().IntersectsCullRect(paint_rect))
+ LayoutRect local_rect(layout_replaced_.VisualOverflowRect());
+ local_rect.Unite(layout_replaced_.LocalSelectionRect());
+ layout_replaced_.FlipForWritingMode(local_rect);
+ if (!paint_info_with_offset.LocalRectIntersectsCullRect(local_rect))
return false;
return true;
diff --git a/chromium/third_party/blink/renderer/core/paint/replaced_painter.h b/chromium/third_party/blink/renderer/core/paint/replaced_painter.h
index 6cbc1381215..b0579dd9e29 100644
--- a/chromium/third_party/blink/renderer/core/paint/replaced_painter.h
+++ b/chromium/third_party/blink/renderer/core/paint/replaced_painter.h
@@ -10,7 +10,7 @@
namespace blink {
struct PaintInfo;
-class LayoutPoint;
+class PaintInfoWithOffset;
class LayoutReplaced;
class ReplacedPainter {
@@ -22,7 +22,7 @@ class ReplacedPainter {
void Paint(const PaintInfo&);
- bool ShouldPaint(const PaintInfo&, const LayoutPoint& paint_offset) const;
+ bool ShouldPaint(const PaintInfoWithOffset&) const;
private:
const LayoutReplaced& layout_replaced_;
diff --git a/chromium/third_party/blink/renderer/core/paint/root_inline_box_painter.cc b/chromium/third_party/blink/renderer/core/paint/root_inline_box_painter.cc
index 9b62f7fe4f1..8c24758eaa9 100644
--- a/chromium/third_party/blink/renderer/core/paint/root_inline_box_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/root_inline_box_painter.cc
@@ -16,7 +16,7 @@ void RootInlineBoxPainter::PaintEllipsisBox(const PaintInfo& paint_info,
LayoutUnit line_top,
LayoutUnit line_bottom) const {
if (root_inline_box_.HasEllipsisBox() &&
- root_inline_box_.GetLineLayoutItem().Style()->Visibility() ==
+ root_inline_box_.GetLineLayoutItem().StyleRef().Visibility() ==
EVisibility::kVisible &&
paint_info.phase == PaintPhase::kForeground)
root_inline_box_.GetEllipsisBox()->Paint(paint_info, paint_offset, line_top,
diff --git a/chromium/third_party/blink/renderer/core/paint/scoped_box_clipper.cc b/chromium/third_party/blink/renderer/core/paint/scoped_box_clipper.cc
new file mode 100644
index 00000000000..02e32a3312b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/paint/scoped_box_clipper.cc
@@ -0,0 +1,45 @@
+// 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/paint/scoped_box_clipper.h"
+
+#include "third_party/blink/renderer/core/layout/layout_box.h"
+#include "third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h"
+#include "third_party/blink/renderer/core/paint/paint_info.h"
+
+namespace blink {
+
+DISABLE_CFI_PERF
+ScopedBoxClipper::ScopedBoxClipper(const LayoutBox& box,
+ const PaintInfo& paint_info) {
+ InitializeScopedProperties(paint_info.FragmentToPaint(box), box, paint_info);
+}
+
+DISABLE_CFI_PERF
+ScopedBoxClipper::ScopedBoxClipper(const NGPaintFragment& fragment,
+ const PaintInfo& paint_info) {
+ DCHECK(fragment.GetLayoutObject());
+ InitializeScopedProperties(
+ paint_info.FragmentToPaint(*fragment.GetLayoutObject()), fragment,
+ paint_info);
+}
+
+void ScopedBoxClipper::InitializeScopedProperties(
+ const FragmentData* fragment_data,
+ const DisplayItemClient& client,
+ const PaintInfo& paint_info) {
+ DCHECK(paint_info.phase != PaintPhase::kSelfBlockBackgroundOnly &&
+ paint_info.phase != PaintPhase::kSelfOutlineOnly &&
+ paint_info.phase != PaintPhase::kMask);
+ if (!fragment_data || !fragment_data->HasLocalBorderBoxProperties())
+ return;
+
+ const PropertyTreeState& contents_properties =
+ fragment_data->ContentsProperties();
+ scoped_properties_.emplace(paint_info.context.GetPaintController(),
+ contents_properties, client,
+ paint_info.DisplayItemTypeForClipping());
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/scoped_box_clipper.h b/chromium/third_party/blink/renderer/core/paint/scoped_box_clipper.h
new file mode 100644
index 00000000000..c73b866ee76
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/paint/scoped_box_clipper.h
@@ -0,0 +1,48 @@
+// 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_PAINT_SCOPED_BOX_CLIPPER_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_SCOPED_BOX_CLIPPER_H_
+
+#include "base/optional.h"
+#include "third_party/blink/renderer/platform/graphics/paint/scoped_paint_chunk_properties.h"
+#include "third_party/blink/renderer/platform/wtf/allocator.h"
+
+namespace blink {
+
+class DisplayItemClient;
+class FragmentData;
+class LayoutBox;
+class NGPaintFragment;
+struct PaintInfo;
+
+// Within the scope of this object:
+// - OverflowClip is applied if it exists
+// - If it doesn't exist, then InnerBorderRadiusClip is applied if it exists.
+// - If it doesn't exist, then properties are not modified.
+// TODO(vmpstr): It should be possible to make this apply ContentsProperties
+// instead of a contents clip only. However, there are situation where the
+// LocalBorderBoxProperties().Clip(), which would be the fallback if neither
+// OverflowClip nor InnerBorderRadiusClip exist, is not the correct clip to
+// apply. We need to audit the usage to figure in which situations we want
+// BoxClipper and in which situations we want OverflowClip or
+// InnerBorderRadiusClip only.
+class ScopedBoxClipper {
+ DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
+
+ public:
+ ScopedBoxClipper(const LayoutBox&, const PaintInfo&);
+ ScopedBoxClipper(const NGPaintFragment&, const PaintInfo&);
+
+ private:
+ void InitializeScopedProperties(const FragmentData*,
+ const DisplayItemClient&,
+ const PaintInfo&);
+
+ base::Optional<ScopedPaintChunkProperties> scoped_properties_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_SCOPED_BOX_BOX_CLIPPER_H_
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 e466c1d7666..13aa91a200f 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
@@ -5,26 +5,26 @@
#include "third_party/blink/renderer/core/paint/scrollable_area_painter.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
+#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/paint/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_scrollable_area.h"
#include "third_party/blink/renderer/core/paint/scrollbar_painter.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context_state_saver.h"
#include "third_party/blink/renderer/platform/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/platform_chrome_client.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h"
namespace blink {
void ScrollableAreaPainter::PaintResizer(GraphicsContext& context,
const IntPoint& paint_offset,
const CullRect& cull_rect) {
- if (GetScrollableArea().GetLayoutBox()->Style()->Resize() == EResize::kNone)
+ if (GetScrollableArea().GetLayoutBox()->StyleRef().Resize() == EResize::kNone)
return;
IntRect abs_rect = GetScrollableArea().ResizerCornerRect(
diff --git a/chromium/third_party/blink/renderer/core/paint/scrollbar_painter.h b/chromium/third_party/blink/renderer/core/paint/scrollbar_painter.h
index e73f507251f..e5962c33628 100644
--- a/chromium/third_party/blink/renderer/core/paint/scrollbar_painter.h
+++ b/chromium/third_party/blink/renderer/core/paint/scrollbar_painter.h
@@ -6,8 +6,8 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_SCROLLBAR_PAINTER_H_
#include "base/macros.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar.h"
namespace blink {
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 93d3611f8ac..da912121bb8 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
@@ -19,7 +19,7 @@ namespace blink {
void SVGImagePainter::Paint(const PaintInfo& paint_info) {
if (paint_info.phase != PaintPhase::kForeground ||
- layout_svg_image_.Style()->Visibility() != EVisibility::kVisible ||
+ layout_svg_image_.StyleRef().Visibility() != EVisibility::kVisible ||
!layout_svg_image_.ImageResource()->HasImage())
return;
@@ -41,6 +41,8 @@ void SVGImagePainter::Paint(const PaintInfo& paint_info) {
!DrawingRecorder::UseCachedDrawingIfPossible(
paint_context.GetPaintInfo().context, layout_svg_image_,
paint_context.GetPaintInfo().phase)) {
+ if (RuntimeEnabledFeatures::PaintTouchActionRectsEnabled())
+ SVGModelObjectPainter::RecordHitTestData(layout_svg_image_, paint_info);
DrawingRecorder recorder(paint_context.GetPaintInfo().context,
layout_svg_image_,
paint_context.GetPaintInfo().phase);
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 fd52c1fc3e1..8fd023450ce 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
@@ -11,7 +11,6 @@
#include "third_party/blink/renderer/core/editing/markers/text_match_marker.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/layout/api/line_layout_api_shim.h"
-#include "third_party/blink/renderer/core/layout/api/selection_state.h"
#include "third_party/blink/renderer/core/layout/layout_theme.h"
#include "third_party/blink/renderer/core/layout/line/inline_flow_box.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_inline_text.h"
@@ -49,7 +48,7 @@ bool SVGInlineTextBoxPainter::ShouldPaintSelection(
// pattern or feImage (element reference.)
if (paint_info.IsRenderingResourceSubtree())
return false;
- return svg_inline_text_box_.GetSelectionState() != SelectionState::kNone;
+ return svg_inline_text_box_.IsSelected();
}
static bool HasShadow(const PaintInfo& paint_info, const ComputedStyle& style) {
@@ -77,7 +76,7 @@ void SVGInlineTextBoxPainter::Paint(const PaintInfo& paint_info,
paint_info.phase == PaintPhase::kSelection);
DCHECK(svg_inline_text_box_.Truncation() == kCNoTruncation);
- if (svg_inline_text_box_.GetLineLayoutItem().Style()->Visibility() !=
+ if (svg_inline_text_box_.GetLineLayoutItem().StyleRef().Visibility() !=
EVisibility::kVisible ||
!svg_inline_text_box_.Len())
return;
@@ -209,7 +208,7 @@ void SVGInlineTextBoxPainter::PaintTextFragments(
void SVGInlineTextBoxPainter::PaintSelectionBackground(
const PaintInfo& paint_info) {
- if (svg_inline_text_box_.GetLineLayoutItem().Style()->Visibility() !=
+ if (svg_inline_text_box_.GetLineLayoutItem().StyleRef().Visibility() !=
EVisibility::kVisible)
return;
@@ -263,7 +262,7 @@ static inline LayoutObject* FindLayoutObjectDefininingTextDecoration(
LineLayoutAPIShim::LayoutObjectFrom(parent_box->GetLineLayoutItem());
if (layout_object->Style() &&
- layout_object->Style()->GetTextDecoration() != TextDecoration::kNone)
+ layout_object->StyleRef().GetTextDecoration() != TextDecoration::kNone)
break;
parent_box = parent_box->Parent();
@@ -303,8 +302,8 @@ void SVGInlineTextBoxPainter::PaintDecoration(const PaintInfo& paint_info,
TextDecoration decoration,
const SVGTextFragment& fragment) {
if (svg_inline_text_box_.GetLineLayoutItem()
- .Style()
- ->TextDecorationsInEffect() == TextDecoration::kNone)
+ .StyleRef()
+ .TextDecorationsInEffect() == TextDecoration::kNone)
return;
if (fragment.width <= 0)
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 956f01cec5d..c53a8fe760e 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,6 +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_data.h"
namespace blink {
@@ -28,12 +29,32 @@ 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) {
+ 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.EffectiveWhitelistedTouchAction();
+ if (touch_action == TouchAction::kTouchActionAuto)
+ return;
+
+ auto rect =
+ LayoutRect(layout_svg_model_object.VisualRectInLocalSVGCoordinates());
+ HitTestData::RecordTouchActionRect(paint_info.context,
+ layout_svg_model_object,
+ TouchActionRect(rect, touch_action));
+}
+
void SVGModelObjectPainter::PaintOutline(const PaintInfo& paint_info) {
if (paint_info.phase != PaintPhase::kForeground)
return;
- if (layout_svg_model_object_.Style()->Visibility() != EVisibility::kVisible)
+ if (layout_svg_model_object_.StyleRef().Visibility() != EVisibility::kVisible)
return;
- if (!layout_svg_model_object_.Style()->OutlineWidth())
+ if (!layout_svg_model_object_.StyleRef().OutlineWidth())
return;
PaintInfo outline_paint_info(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 6f3df6d6c43..12d300447c8 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
@@ -16,6 +16,13 @@ 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)
: layout_svg_model_object_(layout_svg_model_object) {}
diff --git a/chromium/third_party/blink/renderer/core/paint/svg_paint_context.h b/chromium/third_party/blink/renderer/core/paint/svg_paint_context.h
index 261639650c5..a2b4da9c9fa 100644
--- a/chromium/third_party/blink/renderer/core/paint/svg_paint_context.h
+++ b/chromium/third_party/blink/renderer/core/paint/svg_paint_context.h
@@ -49,6 +49,8 @@ class SVGTransformContext {
SVGTransformContext(const PaintInfo& paint_info,
const LayoutObject& object,
const AffineTransform& transform) {
+ DCHECK(object.IsSVGChild());
+
const auto* fragment = paint_info.FragmentToPaint(object);
if (!fragment)
return;
@@ -56,19 +58,7 @@ class SVGTransformContext {
if (!properties)
return;
- const TransformPaintPropertyNode* transform_node;
- if (object.IsSVGRoot()) {
- // If a transform exists, we can rely on a layer existing to apply it.
- DCHECK(!properties || !properties->Transform() || object.HasLayer());
- transform_node = properties->SvgLocalToBorderBoxTransform();
- } else {
- DCHECK(object.IsSVG());
- // Should only be used by LayoutSVGRoot.
- DCHECK(!properties->SvgLocalToBorderBoxTransform());
- transform_node = properties->Transform();
- }
-
- if (transform_node) {
+ if (const auto* transform_node = properties->Transform()) {
DCHECK(transform_node->Matrix() == transform.ToTransformationMatrix());
transform_property_scope_.emplace(
paint_info.context.GetPaintController(), transform_node, object,
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 8c7b6fb0fc0..09673542044 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
@@ -23,8 +23,7 @@ void SVGRootInlineBoxPainter::Paint(const PaintInfo& paint_info,
paint_info.phase == PaintPhase::kSelection);
bool has_selection =
- !paint_info.IsPrinting() &&
- svg_root_inline_box_.GetSelectionState() != SelectionState::kNone;
+ !paint_info.IsPrinting() && svg_root_inline_box_.IsSelected();
PaintInfo paint_info_before_filtering(paint_info);
if (has_selection && !DrawingRecorder::UseCachedDrawingIfPossible(
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 448e42aed97..676dc4b0035 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
@@ -7,7 +7,6 @@
#include "base/optional.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_root.h"
#include "third_party/blink/renderer/core/layout/svg/svg_layout_support.h"
-#include "third_party/blink/renderer/core/paint/box_clipper.h"
#include "third_party/blink/renderer/core/paint/box_painter.h"
#include "third_party/blink/renderer/core/paint/object_paint_properties.h"
#include "third_party/blink/renderer/core/paint/paint_info.h"
@@ -51,21 +50,7 @@ void SVGRootPainter::PaintReplaced(const PaintInfo& paint_info,
if (svg->HasEmptyViewBox())
return;
- // Apply initial viewport clip.
- base::Optional<BoxClipper> box_clipper;
- if (layout_svg_root_.ShouldApplyViewportClip()) {
- // TODO(pdr): Clip the paint info cull rect here.
- box_clipper.emplace(layout_svg_root_, paint_info);
- }
-
- PaintInfo paint_info_before_filtering(paint_info);
- AffineTransform transform_to_border_box =
- TransformToPixelSnappedBorderBox(paint_offset);
- paint_info_before_filtering.UpdateCullRect(transform_to_border_box);
- SVGTransformContext transform_context(
- paint_info_before_filtering, layout_svg_root_, transform_to_border_box);
-
- SVGPaintContext paint_context(layout_svg_root_, paint_info_before_filtering);
+ SVGPaintContext paint_context(layout_svg_root_, paint_info);
if (paint_context.GetPaintInfo().phase == PaintPhase::kForeground &&
!paint_context.ApplyClipMaskAndFilterIfNecessary())
return;
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 2c8ed987c4a..6eba756a0a7 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
@@ -42,7 +42,7 @@ static SkPath::FillType FillRuleFromStyle(const PaintInfo& paint_info,
void SVGShapePainter::Paint(const PaintInfo& paint_info) {
if (paint_info.phase != PaintPhase::kForeground ||
- layout_svg_shape_.Style()->Visibility() != EVisibility::kVisible ||
+ layout_svg_shape_.StyleRef().Visibility() != EVisibility::kVisible ||
layout_svg_shape_.IsShapeEmpty())
return;
@@ -64,10 +64,13 @@ void SVGShapePainter::Paint(const PaintInfo& paint_info) {
!DrawingRecorder::UseCachedDrawingIfPossible(
paint_context.GetPaintInfo().context, layout_svg_shape_,
paint_context.GetPaintInfo().phase)) {
+ if (RuntimeEnabledFeatures::PaintTouchActionRectsEnabled())
+ SVGModelObjectPainter::RecordHitTestData(layout_svg_shape_, paint_info);
DrawingRecorder recorder(paint_context.GetPaintInfo().context,
layout_svg_shape_,
paint_context.GetPaintInfo().phase);
- const SVGComputedStyle& svg_style = layout_svg_shape_.Style()->SvgStyle();
+ const SVGComputedStyle& svg_style =
+ layout_svg_shape_.StyleRef().SvgStyle();
bool should_anti_alias = svg_style.ShapeRendering() != SR_CRISPEDGES &&
svg_style.ShapeRendering() != SR_OPTIMIZESPEED;
@@ -176,7 +179,7 @@ void SVGShapePainter::FillShape(GraphicsContext& context,
void SVGShapePainter::StrokeShape(GraphicsContext& context,
const PaintFlags& flags) {
- if (!layout_svg_shape_.Style()->SvgStyle().HasVisibleStroke())
+ if (!layout_svg_shape_.StyleRef().SvgStyle().HasVisibleStroke())
return;
switch (layout_svg_shape_.GeometryCodePath()) {
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 ece2cac98d8..cfdbd55c7ec 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
@@ -22,6 +22,8 @@ void SVGTextPainter::Paint(const PaintInfo& paint_info) {
block_info, layout_svg_text_,
layout_svg_text_.LocalToSVGParentTransform());
+ if (RuntimeEnabledFeatures::PaintTouchActionRectsEnabled())
+ RecordHitTestData(paint_info);
BlockPainter(layout_svg_text_).Paint(block_info);
// Paint the outlines, if any
@@ -31,4 +33,22 @@ void SVGTextPainter::Paint(const PaintInfo& paint_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_.EffectiveWhitelistedTouchAction();
+ if (touch_action == TouchAction::kTouchActionAuto)
+ return;
+
+ auto rect = LayoutRect(layout_svg_text_.VisualRectInLocalSVGCoordinates());
+ HitTestData::RecordTouchActionRect(paint_info.context, layout_svg_text_,
+ TouchActionRect(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 71733c41054..ff43ec26180 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,6 +21,11 @@ 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_cell_paint_invalidator.cc b/chromium/third_party/blink/renderer/core/paint/table_cell_paint_invalidator.cc
index db26d502637..f15db7c6c5e 100644
--- a/chromium/third_party/blink/renderer/core/paint/table_cell_paint_invalidator.cc
+++ b/chromium/third_party/blink/renderer/core/paint/table_cell_paint_invalidator.cc
@@ -16,12 +16,16 @@
namespace blink {
+static bool DisplayItemClientIsFullyInvalidated(
+ const DisplayItemClient& client) {
+ return IsFullPaintInvalidationReason(client.GetPaintInvalidationReason());
+}
+
void TableCellPaintInvalidator::InvalidateContainerForCellGeometryChange(
const LayoutObject& container,
const PaintInvalidatorContext& container_context) {
// We only need to do this if the container hasn't been fully invalidated.
- DCHECK(
- !IsFullPaintInvalidationReason(container.GetPaintInvalidationReason()));
+ DCHECK(!DisplayItemClientIsFullyInvalidated(container));
// At this time we have already walked the container for paint invalidation,
// so we should invalidate the container immediately here instead of setting
@@ -30,7 +34,7 @@ void TableCellPaintInvalidator::InvalidateContainerForCellGeometryChange(
container.InvalidateDisplayItemClients(PaintInvalidationReason::kGeometry);
}
-PaintInvalidationReason TableCellPaintInvalidator::InvalidatePaint() {
+void TableCellPaintInvalidator::InvalidatePaint() {
// The cell's containing row and section paint backgrounds behind the cell,
// and the row or table paints collapsed borders. If the cell's geometry
// changed and the containers which will paint backgrounds and/or collapsed
@@ -40,7 +44,7 @@ PaintInvalidationReason TableCellPaintInvalidator::InvalidatePaint() {
const auto& row = *cell_.Row();
const auto& section = *row.Section();
const auto& table = *section.Table();
- if (!IsFullPaintInvalidationReason(row.GetPaintInvalidationReason()) &&
+ if (!DisplayItemClientIsFullyInvalidated(row) &&
(row.StyleRef().HasBackground() ||
(table.HasCollapsedBorders() &&
LIKELY(!table.ShouldPaintAllCollapsedBorders())))) {
@@ -48,13 +52,13 @@ PaintInvalidationReason TableCellPaintInvalidator::InvalidatePaint() {
}
if (UNLIKELY(table.ShouldPaintAllCollapsedBorders()) &&
- !IsFullPaintInvalidationReason(table.GetPaintInvalidationReason())) {
+ !DisplayItemClientIsFullyInvalidated(table)) {
DCHECK(table.HasCollapsedBorders());
InvalidateContainerForCellGeometryChange(
table, *context_.ParentContext()->ParentContext()->ParentContext());
}
- if (!IsFullPaintInvalidationReason(section.GetPaintInvalidationReason())) {
+ if (!DisplayItemClientIsFullyInvalidated(section)) {
bool section_paints_background = section.StyleRef().HasBackground();
if (!section_paints_background) {
auto col_and_colgroup = section.Table()->ColElementAtAbsoluteColumn(
@@ -72,7 +76,7 @@ PaintInvalidationReason TableCellPaintInvalidator::InvalidatePaint() {
}
}
- return BlockPaintInvalidator(cell_).InvalidatePaint(context_);
+ BlockPaintInvalidator(cell_).InvalidatePaint(context_);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/table_cell_paint_invalidator.h b/chromium/third_party/blink/renderer/core/paint/table_cell_paint_invalidator.h
index b2d129e125e..e5a30863bac 100644
--- a/chromium/third_party/blink/renderer/core/paint/table_cell_paint_invalidator.h
+++ b/chromium/third_party/blink/renderer/core/paint/table_cell_paint_invalidator.h
@@ -22,7 +22,7 @@ class TableCellPaintInvalidator {
const PaintInvalidatorContext& context)
: cell_(cell), context_(context) {}
- PaintInvalidationReason InvalidatePaint();
+ void InvalidatePaint();
private:
void InvalidateContainerForCellGeometryChange(
diff --git a/chromium/third_party/blink/renderer/core/paint/table_cell_painter.cc b/chromium/third_party/blink/renderer/core/paint/table_cell_painter.cc
index 226d0345c22..4d2ec4d19b0 100644
--- a/chromium/third_party/blink/renderer/core/paint/table_cell_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/table_cell_painter.cc
@@ -5,7 +5,6 @@
#include "third_party/blink/renderer/core/paint/table_cell_painter.h"
#include "third_party/blink/renderer/core/layout/layout_table_cell.h"
-#include "third_party/blink/renderer/core/paint/adjust_paint_offset_scope.h"
#include "third_party/blink/renderer/core/paint/background_image_geometry.h"
#include "third_party/blink/renderer/core/paint/block_painter.h"
#include "third_party/blink/renderer/core/paint/box_model_object_painter.h"
@@ -13,6 +12,7 @@
#include "third_party/blink/renderer/core/paint/box_painter_base.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_info_with_offset.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context_state_saver.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
@@ -23,19 +23,20 @@ void TableCellPainter::PaintContainerBackgroundBehindCell(
const LayoutObject& background_object) {
DCHECK(background_object != layout_table_cell_);
- if (layout_table_cell_.Style()->Visibility() != EVisibility::kVisible)
+ if (layout_table_cell_.StyleRef().Visibility() != EVisibility::kVisible)
return;
LayoutTable* table = layout_table_cell_.Table();
if (!table->ShouldCollapseBorders() &&
- layout_table_cell_.Style()->EmptyCells() == EEmptyCells::kHide &&
+ layout_table_cell_.StyleRef().EmptyCells() == EEmptyCells::kHide &&
!layout_table_cell_.FirstChild())
return;
- AdjustPaintOffsetScope adjustment(layout_table_cell_, paint_info);
+ PaintInfoWithOffset paint_info_with_offset(layout_table_cell_, paint_info);
auto paint_rect =
- PaintRectNotIncludingVisualOverflow(adjustment.PaintOffset());
- PaintBackground(adjustment.GetPaintInfo(), paint_rect, background_object);
+ PaintRectNotIncludingVisualOverflow(paint_info_with_offset.PaintOffset());
+ PaintBackground(paint_info_with_offset.GetPaintInfo(), paint_rect,
+ background_object);
}
void TableCellPainter::PaintBackground(const PaintInfo& paint_info,
@@ -123,13 +124,13 @@ void TableCellPainter::PaintBoxDecorationBackground(
void TableCellPainter::PaintMask(const PaintInfo& paint_info,
const LayoutPoint& paint_offset) {
- if (layout_table_cell_.Style()->Visibility() != EVisibility::kVisible ||
+ if (layout_table_cell_.StyleRef().Visibility() != EVisibility::kVisible ||
paint_info.phase != PaintPhase::kMask)
return;
LayoutTable* table_elt = layout_table_cell_.Table();
if (!table_elt->ShouldCollapseBorders() &&
- layout_table_cell_.Style()->EmptyCells() == EEmptyCells::kHide &&
+ layout_table_cell_.StyleRef().EmptyCells() == EEmptyCells::kHide &&
!layout_table_cell_.FirstChild())
return;
diff --git a/chromium/third_party/blink/renderer/core/paint/table_paint_invalidator.cc b/chromium/third_party/blink/renderer/core/paint/table_paint_invalidator.cc
index ac25e889885..515292251b0 100644
--- a/chromium/third_party/blink/renderer/core/paint/table_paint_invalidator.cc
+++ b/chromium/third_party/blink/renderer/core/paint/table_paint_invalidator.cc
@@ -14,9 +14,8 @@
namespace blink {
-PaintInvalidationReason TablePaintInvalidator::InvalidatePaint() {
- PaintInvalidationReason reason =
- BoxPaintInvalidator(table_, context_).InvalidatePaint();
+void TablePaintInvalidator::InvalidatePaint() {
+ BoxPaintInvalidator(table_, context_).InvalidatePaint();
// If any col changed background, we need to invalidate all sections because
// col background paints into section's background display item.
@@ -29,7 +28,7 @@ PaintInvalidationReason TablePaintInvalidator::InvalidatePaint() {
// LayoutTableCol uses the table's localVisualRect(). Should check column
// for paint invalidation when table's visual rect changed.
if (visual_rect_changed)
- col->SetMayNeedPaintInvalidation();
+ col->SetShouldCheckForPaintInvalidation();
// This ensures that the backgroundChangedSinceLastPaintInvalidation flag
// is up-to-date.
col->EnsureIsReadyForPaintInvalidation();
@@ -52,8 +51,6 @@ PaintInvalidationReason TablePaintInvalidator::InvalidatePaint() {
*section, PaintInvalidationReason::kStyle);
}
}
-
- return reason;
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/table_paint_invalidator.h b/chromium/third_party/blink/renderer/core/paint/table_paint_invalidator.h
index 315a9bd3a2a..2bcadfbd4b5 100644
--- a/chromium/third_party/blink/renderer/core/paint/table_paint_invalidator.h
+++ b/chromium/third_party/blink/renderer/core/paint/table_paint_invalidator.h
@@ -21,7 +21,7 @@ class TablePaintInvalidator {
const PaintInvalidatorContext& context)
: table_(table), context_(context) {}
- PaintInvalidationReason InvalidatePaint();
+ void InvalidatePaint();
private:
const LayoutTable& table_;
diff --git a/chromium/third_party/blink/renderer/core/paint/table_painter.cc b/chromium/third_party/blink/renderer/core/paint/table_painter.cc
index 8b84ce98f07..24100593c72 100644
--- a/chromium/third_party/blink/renderer/core/paint/table_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/table_painter.cc
@@ -7,7 +7,6 @@
#include "third_party/blink/renderer/core/layout/collapsed_border_value.h"
#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/paint/box_clipper.h"
#include "third_party/blink/renderer/core/paint/box_painter.h"
#include "third_party/blink/renderer/core/paint/object_painter.h"
#include "third_party/blink/renderer/core/paint/paint_info.h"
@@ -44,7 +43,7 @@ void TablePainter::PaintObject(const PaintInfo& paint_info,
if (layout_table_.HasCollapsedBorders() &&
ShouldPaintDescendantBlockBackgrounds(paint_phase) &&
- layout_table_.Style()->Visibility() == EVisibility::kVisible) {
+ layout_table_.StyleRef().Visibility() == EVisibility::kVisible) {
PaintCollapsedBorders(paint_info_for_descendants);
}
}
@@ -57,18 +56,18 @@ void TablePainter::PaintBoxDecorationBackground(
const PaintInfo& paint_info,
const LayoutPoint& paint_offset) {
if (!layout_table_.HasBoxDecorationBackground() ||
- layout_table_.Style()->Visibility() != EVisibility::kVisible)
+ layout_table_.StyleRef().Visibility() != EVisibility::kVisible)
return;
LayoutRect rect(paint_offset, layout_table_.Size());
layout_table_.SubtractCaptionRect(rect);
BoxPainter(layout_table_)
- .PaintBoxDecorationBackgroundWithRect(paint_info, paint_offset, rect);
+ .PaintBoxDecorationBackgroundWithRect(paint_info, rect);
}
void TablePainter::PaintMask(const PaintInfo& paint_info,
const LayoutPoint& paint_offset) {
- if (layout_table_.Style()->Visibility() != EVisibility::kVisible ||
+ if (layout_table_.StyleRef().Visibility() != EVisibility::kVisible ||
paint_info.phase != PaintPhase::kMask)
return;
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 e7e29a96740..79e5c5f1fe0 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
@@ -6,12 +6,12 @@
#include "third_party/blink/renderer/core/layout/layout_table_cell.h"
#include "third_party/blink/renderer/core/layout/layout_table_row.h"
-#include "third_party/blink/renderer/core/paint/adjust_paint_offset_scope.h"
#include "third_party/blink/renderer/core/paint/box_painter.h"
#include "third_party/blink/renderer/core/paint/box_painter_base.h"
#include "third_party/blink/renderer/core/paint/collapsed_border_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_info_with_offset.h"
#include "third_party/blink/renderer/core/paint/table_cell_painter.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
@@ -50,9 +50,10 @@ void TableRowPainter::Paint(const PaintInfo& paint_info) {
void TableRowPainter::PaintOutline(const PaintInfo& paint_info) {
DCHECK(ShouldPaintSelfOutline(paint_info.phase));
- AdjustPaintOffsetScope adjustment(layout_table_row_, paint_info);
+ PaintInfoWithOffset paint_info_with_offset(layout_table_row_, paint_info);
ObjectPainter(layout_table_row_)
- .PaintOutline(adjustment.GetPaintInfo(), adjustment.PaintOffset());
+ .PaintOutline(paint_info_with_offset.GetPaintInfo(),
+ paint_info_with_offset.PaintOffset());
}
void TableRowPainter::HandleChangedPartialPaint(
@@ -77,14 +78,14 @@ void TableRowPainter::PaintBoxDecorationBackground(
HandleChangedPartialPaint(paint_info, dirtied_columns);
+ PaintInfoWithOffset paint_info_with_offset(layout_table_row_, paint_info);
if (DrawingRecorder::UseCachedDrawingIfPossible(
paint_info.context, layout_table_row_,
DisplayItem::kBoxDecorationBackground))
return;
- AdjustPaintOffsetScope adjustment(layout_table_row_, paint_info);
- const auto& local_paint_info = adjustment.GetPaintInfo();
- auto paint_offset = adjustment.PaintOffset();
+ const auto& local_paint_info = paint_info_with_offset.GetPaintInfo();
+ auto paint_offset = paint_info_with_offset.PaintOffset();
DrawingRecorder recorder(local_paint_info.context, layout_table_row_,
DisplayItem::kBoxDecorationBackground);
LayoutRect paint_rect(paint_offset, layout_table_row_.Size());
@@ -114,6 +115,7 @@ void TableRowPainter::PaintBoxDecorationBackground(
void TableRowPainter::PaintCollapsedBorders(const PaintInfo& paint_info,
const CellSpan& dirtied_columns) {
+ PaintInfoWithOffset paint_state(layout_table_row_, paint_info);
base::Optional<DrawingRecorder> recorder;
if (LIKELY(!layout_table_row_.Table()->ShouldPaintAllCollapsedBorders())) {
@@ -133,8 +135,10 @@ void TableRowPainter::PaintCollapsedBorders(const PaintInfo& paint_info,
unsigned row = layout_table_row_.RowIndex();
for (unsigned c = std::min(dirtied_columns.End(), section->NumCols(row));
c > dirtied_columns.Start(); c--) {
- if (const auto* cell = section->OriginatingCellAt(row, c - 1))
- CollapsedBorderPainter(*cell).PaintCollapsedBorders(paint_info);
+ if (const auto* cell = section->OriginatingCellAt(row, c - 1)) {
+ CollapsedBorderPainter(*cell).PaintCollapsedBorders(
+ paint_state.GetPaintInfo());
+ }
}
}
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 85d6a08aae0..a9867f60f19 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
@@ -8,14 +8,14 @@
#include "third_party/blink/renderer/core/layout/layout_table_cell.h"
#include "third_party/blink/renderer/core/layout/layout_table_col.h"
#include "third_party/blink/renderer/core/layout/layout_table_row.h"
-#include "third_party/blink/renderer/core/paint/adjust_paint_offset_scope.h"
-#include "third_party/blink/renderer/core/paint/box_clipper.h"
#include "third_party/blink/renderer/core/paint/box_painter.h"
#include "third_party/blink/renderer/core/paint/box_painter_base.h"
#include "third_party/blink/renderer/core/paint/collapsed_border_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_info_with_offset.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
+#include "third_party/blink/renderer/core/paint/scoped_box_clipper.h"
#include "third_party/blink/renderer/core/paint/table_cell_painter.h"
#include "third_party/blink/renderer/core/paint/table_row_painter.h"
#include "third_party/blink/renderer/platform/graphics/paint/display_item_cache_skipper.h"
@@ -65,14 +65,16 @@ void TableSectionPainter::PaintSection(const PaintInfo& paint_info) {
if (!total_rows || !total_cols)
return;
- AdjustPaintOffsetScope adjustment(layout_table_section_, paint_info);
- const auto& local_paint_info = adjustment.GetPaintInfo();
- auto paint_offset = adjustment.PaintOffset();
+ PaintInfoWithOffset paint_info_with_offset(layout_table_section_, paint_info);
+ const auto& local_paint_info = paint_info_with_offset.GetPaintInfo();
+ auto paint_offset = paint_info_with_offset.PaintOffset();
if (local_paint_info.phase != PaintPhase::kSelfOutlineOnly) {
- base::Optional<BoxClipper> box_clipper;
- if (local_paint_info.phase != PaintPhase::kSelfBlockBackgroundOnly)
+ base::Optional<ScopedBoxClipper> box_clipper;
+ if (local_paint_info.phase != PaintPhase::kSelfBlockBackgroundOnly &&
+ local_paint_info.phase != PaintPhase::kMask) {
box_clipper.emplace(layout_table_section_, local_paint_info);
+ }
PaintObject(local_paint_info, paint_offset);
}
@@ -125,10 +127,12 @@ void TableSectionPainter::PaintCollapsedSectionBorders(
!layout_table_section_.Table()->EffectiveColumns().size())
return;
- AdjustPaintOffsetScope adjustment(layout_table_section_, paint_info);
- const auto& local_paint_info = adjustment.GetPaintInfo();
- auto paint_offset = adjustment.PaintOffset();
- BoxClipper box_clipper(layout_table_section_, local_paint_info);
+ PaintInfoWithOffset paint_info_with_offset(layout_table_section_, paint_info);
+ const auto& local_paint_info = paint_info_with_offset.GetPaintInfo();
+ auto paint_offset = paint_info_with_offset.PaintOffset();
+ base::Optional<ScopedBoxClipper> box_clipper;
+ if (local_paint_info.phase != PaintPhase::kMask)
+ box_clipper.emplace(layout_table_section_, local_paint_info);
CellSpan dirtied_rows;
CellSpan dirtied_columns;
diff --git a/chromium/third_party/blink/renderer/core/paint/text_control_single_line_painter.cc b/chromium/third_party/blink/renderer/core/paint/text_control_single_line_painter.cc
index b63136d1b29..a048658b6c3 100644
--- a/chromium/third_party/blink/renderer/core/paint/text_control_single_line_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/text_control_single_line_painter.cc
@@ -6,8 +6,8 @@
#include "third_party/blink/renderer/core/layout/layout_text_control_single_line.h"
#include "third_party/blink/renderer/core/layout/layout_theme.h"
-#include "third_party/blink/renderer/core/paint/adjust_paint_offset_scope.h"
#include "third_party/blink/renderer/core/paint/block_painter.h"
+#include "third_party/blink/renderer/core/paint/paint_info_with_offset.h"
#include "third_party/blink/renderer/core/paint/theme_painter.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
@@ -26,7 +26,7 @@ void TextControlSingleLinePainter::Paint(const PaintInfo& paint_info) {
DrawingRecorder recorder(paint_info.context, text_control_,
DisplayItem::kCapsLockIndicator);
- LayoutRect contents_rect = text_control_.ContentBoxRect();
+ LayoutRect contents_rect = text_control_.PhysicalContentBoxRect();
// Center in the block progression direction.
if (text_control_.IsHorizontalWritingMode()) {
@@ -38,12 +38,11 @@ void TextControlSingleLinePainter::Paint(const PaintInfo& paint_info) {
}
// Convert the rect into the coords used for painting the content.
- AdjustPaintOffsetScope adjustment(text_control_, paint_info);
- const auto& local_paint_info = adjustment.GetPaintInfo();
- contents_rect.MoveBy(adjustment.PaintOffset());
+ PaintInfoWithOffset paint_info_with_offset(text_control_, paint_info);
+ contents_rect.MoveBy(paint_info_with_offset.PaintOffset());
IntRect snapped_rect = PixelSnappedIntRect(contents_rect);
LayoutTheme::GetTheme().Painter().PaintCapsLockIndicator(
- text_control_, local_paint_info, snapped_rect);
+ text_control_, paint_info_with_offset.GetPaintInfo(), snapped_rect);
}
} // namespace blink
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 4bf2199dfab..b333afebf69 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
@@ -15,6 +15,8 @@ class ShadowList;
struct CORE_EXPORT TextPaintStyle {
STACK_ALLOCATED();
+
+ public:
Color current_color;
Color fill_color;
Color stroke_color;
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 7e32057cc7c..ed220102bb9 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
@@ -128,7 +128,7 @@ IntRect ConvertToPaintingRect(const LayoutObject& input_layout_object,
const IntRect& local_offset) {
// Compute an offset between the partLayoutObject and the inputLayoutObject.
LayoutSize offset_from_input_layout_object =
- -part_layout_object.OffsetFromAncestorContainer(&input_layout_object);
+ -part_layout_object.OffsetFromAncestor(&input_layout_object);
// Move the rect into partLayoutObject's coords.
part_rect.Move(offset_from_input_layout_object);
// Account for the local drawing offset.
@@ -455,7 +455,7 @@ bool ThemePainterDefault::PaintSearchFieldCancelButton(
if (!base_layout_object.IsBox())
return false;
const LayoutBox& input_layout_box = ToLayoutBox(base_layout_object);
- LayoutRect input_content_box = input_layout_box.ContentBoxRect();
+ LayoutRect input_content_box = input_layout_box.PhysicalContentBoxRect();
// Make sure the scaled button stays square and will fit in its parent's box.
LayoutUnit cancel_button_size =
@@ -466,7 +466,7 @@ bool ThemePainterDefault::PaintSearchFieldCancelButton(
// pixel off-center, it will be one pixel closer to the bottom of the field.
// This tends to look better with the text.
LayoutRect cancel_button_rect(
- cancel_button_object.OffsetFromAncestorContainer(&input_layout_box)
+ cancel_button_object.OffsetFromAncestor(&input_layout_box)
.Width(),
input_content_box.Y() +
(input_content_box.Height() - cancel_button_size + 1) / 2,
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 f3badfd3a61..1284f57910a 100644
--- a/chromium/third_party/blink/renderer/core/paint/video_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/video_painter.cc
@@ -38,7 +38,7 @@ void VideoPainter::PaintReplaced(const PaintInfo& paint_info,
return;
GraphicsContext& context = paint_info.context;
- LayoutRect content_rect = layout_video_.ContentBoxRect();
+ LayoutRect content_rect = layout_video_.PhysicalContentBoxRect();
content_rect.MoveBy(paint_offset);
// Video frames are only painted in software for printing or capturing node
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 7b9edc2b0e4..f9a0e750158 100644
--- a/chromium/third_party/blink/renderer/core/paint/view_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/view_painter.cc
@@ -87,7 +87,7 @@ void ViewPainter::PaintBoxDecorationBackground(const PaintInfo& paint_info) {
document.GetSettings()->GetShouldClearDocumentBackground());
Color base_background_color =
paints_base_background ? frame_view.BaseBackgroundColor() : Color();
- Color root_background_color = layout_view_.Style()->VisitedDependentColor(
+ Color root_background_color = layout_view_.StyleRef().VisitedDependentColor(
GetCSSPropertyBackgroundColor());
const LayoutObject* root_object =
document.documentElement() ? document.documentElement()->GetLayoutObject()
@@ -104,7 +104,7 @@ void ViewPainter::PaintBoxDecorationBackground(const PaintInfo& paint_info) {
// 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_.Style()->BackgroundLayers().GetImage())
+ layout_view_.StyleRef().BackgroundLayers().GetImage())
context.FillRect(background_rect, Color::kWhite, SkBlendMode::kSrc);
return;
}
@@ -165,7 +165,7 @@ void ViewPainter::PaintBoxDecorationBackground(const PaintInfo& paint_info) {
bool should_draw_background_in_separate_buffer =
BoxModelObjectPainter(layout_view_)
.CalculateFillLayerOcclusionCulling(
- reversed_paint_list, layout_view_.Style()->BackgroundLayers());
+ reversed_paint_list, layout_view_.StyleRef().BackgroundLayers());
DCHECK(reversed_paint_list.size());
// If the root background color is opaque, isolation group can be skipped
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 c27d6a39794..ca88e70dcc1 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
@@ -11,8 +11,7 @@ callback ResizeObserverCallback = void (sequence<ResizeObserverEntry> entries, R
[
ActiveScriptWrappable,
Constructor(ResizeObserverCallback callback),
- ConstructorCallWith=Document,
- RuntimeEnabled=ResizeObserver
+ ConstructorCallWith=Document
] interface ResizeObserver {
void observe(Element target);
void unobserve(Element target);
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 29e5d96e0ed..835d47f6dff 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
@@ -4,9 +4,7 @@
// https://wicg.github.io/ResizeObserver/#resize-observer-entry-interface
-[
- RuntimeEnabled=ResizeObserver
-] interface ResizeObserverEntry {
+interface ResizeObserverEntry {
readonly attribute Element target;
readonly attribute DOMRectReadOnly contentRect;
};
diff --git a/chromium/third_party/blink/renderer/core/scheduler/frame_throttling_test.cc b/chromium/third_party/blink/renderer/core/scheduler/frame_throttling_test.cc
index f73992413f1..dd9ee9bb314 100644
--- a/chromium/third_party/blink/renderer/core/scheduler/frame_throttling_test.cc
+++ b/chromium/third_party/blink/renderer/core/scheduler/frame_throttling_test.cc
@@ -204,10 +204,9 @@ TEST_P(FrameThrottlingTest, IntersectionObservationOverridesThrottling) {
inner_view->SetShouldDoFullPaintInvalidation(
PaintInvalidationReason::kForTesting);
inner_view->Layer()->SetNeedsRepaint();
- EXPECT_FALSE(inner_frame_document->View()
- ->GetLayoutView()
- ->FullPaintInvalidationReason() ==
- PaintInvalidationReason::kNone);
+ EXPECT_TRUE(inner_frame_document->View()
+ ->GetLayoutView()
+ ->ShouldDoFullPaintInvalidation());
inner_view->Compositor()->SetNeedsCompositingUpdate(
kCompositingUpdateRebuildTree);
EXPECT_EQ(kCompositingUpdateRebuildTree,
@@ -219,10 +218,9 @@ TEST_P(FrameThrottlingTest, IntersectionObservationOverridesThrottling) {
EXPECT_TRUE(inner_frame_document->View()->ShouldThrottleRendering());
EXPECT_FALSE(inner_view->NeedsLayout());
- EXPECT_FALSE(inner_frame_document->View()
- ->GetLayoutView()
- ->FullPaintInvalidationReason() ==
- PaintInvalidationReason::kNone);
+ EXPECT_TRUE(inner_frame_document->View()
+ ->GetLayoutView()
+ ->ShouldDoFullPaintInvalidation());
EXPECT_EQ(kCompositingUpdateRebuildTree,
inner_view->Compositor()->pending_update_type_);
EXPECT_TRUE(inner_view->Layer()->NeedsRepaint());
diff --git a/chromium/third_party/blink/renderer/core/scheduler/throttling_test.cc b/chromium/third_party/blink/renderer/core/scheduler/throttling_test.cc
index 0dd5b4bb449..f7469418b18 100644
--- a/chromium/third_party/blink/renderer/core/scheduler/throttling_test.cc
+++ b/chromium/third_party/blink/renderer/core/scheduler/throttling_test.cc
@@ -13,6 +13,7 @@
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
using testing::ElementsAre;
+using testing::AnyOf;
namespace blink {
@@ -71,7 +72,7 @@ TEST_F(BackgroundRendererThrottlingTest, BackgroundRenderersAreThrottled) {
" console.log('called f');"
" setTimeout(f, 10, repetitions - 1);"
" }"
- " setTimeout(f, 10, 3);"
+ " setTimeout(f, 10, 50);"
"</script>)");
Platform::Current()
@@ -80,12 +81,12 @@ TEST_F(BackgroundRendererThrottlingTest, BackgroundRenderersAreThrottled) {
->GetWebMainThreadSchedulerForTest()
->SetRendererBackgrounded(true);
- // Make sure that we run a task once a second.
- for (int i = 0; i < 3; ++i) {
- test::RunDelayedTasks(TimeDelta::FromSeconds(1));
- EXPECT_THAT(ConsoleMessages(), ElementsAre("called f"));
- ConsoleMessages().clear();
- }
+ // Make sure that we run no more than one task a second.
+ test::RunDelayedTasks(TimeDelta::FromMilliseconds(3000));
+ EXPECT_THAT(
+ ConsoleMessages(),
+ AnyOf(ElementsAre("called f", "called f", "called f"),
+ ElementsAre("called f", "called f", "called f", "called f")));
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/script/classic_pending_script.cc b/chromium/third_party/blink/renderer/core/script/classic_pending_script.cc
index 9ead234760b..4465f132544 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
@@ -18,6 +18,7 @@
#include "third_party/blink/renderer/core/script/document_write_intervention.h"
#include "third_party/blink/renderer/core/script/script_loader.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
+#include "third_party/blink/renderer/platform/histogram.h"
#include "third_party/blink/renderer/platform/loader/fetch/cached_metadata.h"
#include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h"
#include "third_party/blink/renderer/platform/loader/fetch/raw_resource.h"
@@ -87,7 +88,10 @@ ClassicPendingScript::ClassicPendingScript(
is_external_(is_external),
ready_state_(is_external ? kWaitingForResource : kReady),
integrity_failure_(false),
- is_currently_streaming_(false) {
+ is_currently_streaming_(false),
+ not_streamed_reason_(is_external
+ ? ScriptStreamer::kDidntTryToStartStreaming
+ : ScriptStreamer::kInlineScript) {
CHECK(GetElement());
MemoryCoordinator::Instance().RegisterClient(this);
}
@@ -102,6 +106,87 @@ NOINLINE void ClassicPendingScript::CheckState() const {
CHECK(GetResource() || !streamer_);
}
+namespace {
+
+enum class StreamedBoolean {
+ // Must match BooleanStreamed in enums.xml.
+ kNotStreamed = 0,
+ kStreamed = 1,
+ kMaxValue = kStreamed
+};
+
+void RecordStartedStreamingHistogram(ScriptSchedulingType type,
+ bool did_use_streamer) {
+ StreamedBoolean streamed = did_use_streamer ? StreamedBoolean::kStreamed
+ : StreamedBoolean::kNotStreamed;
+ switch (type) {
+ case ScriptSchedulingType::kParserBlocking: {
+ UMA_HISTOGRAM_ENUMERATION(
+ "WebCore.Scripts.ParsingBlocking.StartedStreaming", streamed);
+ break;
+ }
+ case ScriptSchedulingType::kDefer: {
+ UMA_HISTOGRAM_ENUMERATION("WebCore.Scripts.Deferred.StartedStreaming",
+ streamed);
+ break;
+ }
+ case ScriptSchedulingType::kAsync: {
+ UMA_HISTOGRAM_ENUMERATION("WebCore.Scripts.Async.StartedStreaming",
+ streamed);
+ break;
+ }
+ default: {
+ UMA_HISTOGRAM_ENUMERATION("WebCore.Scripts.Other.StartedStreaming",
+ streamed);
+ break;
+ }
+ }
+}
+
+void RecordNotStreamingReasonHistogram(
+ ScriptSchedulingType type,
+ ScriptStreamer::NotStreamingReason reason) {
+ switch (type) {
+ case ScriptSchedulingType::kParserBlocking: {
+ UMA_HISTOGRAM_ENUMERATION(
+ "WebCore.Scripts.ParsingBlocking.NotStreamingReason", reason,
+ ScriptStreamer::NotStreamingReason::kCount);
+ break;
+ }
+ case ScriptSchedulingType::kDefer: {
+ UMA_HISTOGRAM_ENUMERATION("WebCore.Scripts.Deferred.NotStreamingReason",
+ reason,
+ ScriptStreamer::NotStreamingReason::kCount);
+ break;
+ }
+ case ScriptSchedulingType::kAsync: {
+ UMA_HISTOGRAM_ENUMERATION("WebCore.Scripts.Async.NotStreamingReason",
+ reason,
+ ScriptStreamer::NotStreamingReason::kCount);
+ break;
+ }
+ default: {
+ UMA_HISTOGRAM_ENUMERATION("WebCore.Scripts.Other.NotStreamingReason",
+ reason,
+ ScriptStreamer::NotStreamingReason::kCount);
+ break;
+ }
+ }
+}
+
+} // namespace
+
+void ClassicPendingScript::RecordStreamingHistogram(
+ ScriptSchedulingType type,
+ bool can_use_streamer,
+ ScriptStreamer::NotStreamingReason reason) {
+ RecordStartedStreamingHistogram(type, can_use_streamer);
+ if (!can_use_streamer) {
+ DCHECK_NE(ScriptStreamer::kInvalid, reason);
+ RecordNotStreamingReasonHistogram(type, reason);
+ }
+}
+
void ClassicPendingScript::Prefinalize() {
// TODO(hiroshige): Consider moving this to ScriptStreamer's prefinalizer.
// https://crbug.com/715309
@@ -246,12 +331,13 @@ static SingleCachedMetadataHandler* GetInlineCacheHandler(const String& source,
return document_cache_handler->HandlerForSource(source);
}
-ClassicScript* ClassicPendingScript::GetSource(const KURL& document_url,
- bool& error_occurred) const {
+ClassicScript* ClassicPendingScript::GetSource(const KURL& document_url) const {
CheckState();
DCHECK(IsReady());
- error_occurred = ErrorOccurred();
+ if (ready_state_ == kErrorOccurred)
+ return nullptr;
+
if (!is_external_) {
SingleCachedMetadataHandler* cache_handler = nullptr;
// We only create an inline cache handler for html-embedded scripts, not
@@ -266,6 +352,11 @@ ClassicScript* ClassicPendingScript::GetSource(const KURL& document_url,
cache_handler = GetInlineCacheHandler(source_text_for_inline_script_,
GetElement()->GetDocument());
}
+
+ DCHECK(!streamer_);
+ DCHECK_EQ(not_streamed_reason_, ScriptStreamer::kInlineScript);
+ RecordStreamingHistogram(GetSchedulingType(), false, not_streamed_reason_);
+
ScriptSourceCode source_code(source_text_for_inline_script_,
source_location_type_, cache_handler,
document_url, StartingPosition());
@@ -280,20 +371,37 @@ ClassicScript* ClassicPendingScript::GetSource(const KURL& document_url,
if (!AllowedByNosniff::MimeTypeAsScript(
GetElement()->GetDocument().ContextDocument(),
resource->GetResponse())) {
- error_occurred = true;
+ return nullptr;
}
- bool streamer_ready = (ready_state_ == kReady) && streamer_ &&
- !streamer_->StreamingSuppressed();
- ScriptSourceCode source_code(streamer_ready ? streamer_ : nullptr, resource);
+ // Check if we can use the script streamer.
+ bool streamer_ready = false;
+ ScriptStreamer::NotStreamingReason not_streamed_reason = not_streamed_reason_;
+ if (streamer_) {
+ DCHECK_EQ(not_streamed_reason, ScriptStreamer::kInvalid);
+ if (streamer_->StreamingSuppressed()) {
+ not_streamed_reason = streamer_->StreamingSuppressedReason();
+ } else if (ready_state_ == kErrorOccurred) {
+ not_streamed_reason = ScriptStreamer::kErrorOccurred;
+ } else if (ready_state_ == kReadyStreaming) {
+ not_streamed_reason = ScriptStreamer::kStreamerNotReadyOnGetSource;
+ } else {
+ // Streamer can be used to compile script.
+ DCHECK_EQ(ready_state_, kReady);
+ streamer_ready = true;
+ }
+ }
+ RecordStreamingHistogram(GetSchedulingType(), streamer_ready,
+ not_streamed_reason);
+
+ ScriptSourceCode source_code(streamer_ready ? streamer_ : nullptr, resource,
+ not_streamed_reason);
// The base URL for external classic script is
// "the URL from which the script was obtained" [spec text]
// https://html.spec.whatwg.org/multipage/webappapis.html#concept-script-base-url
const KURL& base_url = source_code.Url();
- return ClassicScript::Create(
- source_code, base_url, options_,
- resource->CalculateAccessControlStatus(
- GetElement()->GetDocument().GetSecurityOrigin()));
+ return ClassicScript::Create(source_code, base_url, options_,
+ resource->CalculateAccessControlStatus());
}
void ClassicPendingScript::SetStreamer(ScriptStreamer* streamer) {
@@ -316,11 +424,6 @@ bool ClassicPendingScript::IsReady() const {
return ready_state_ >= kReady;
}
-bool ClassicPendingScript::ErrorOccurred() const {
- CheckState();
- return ready_state_ == kErrorOccurred;
-}
-
void ClassicPendingScript::AdvanceReadyState(ReadyState new_ready_state) {
// We will allow exactly these state transitions:
//
@@ -392,7 +495,6 @@ void ClassicPendingScript::OnPurgeMemory() {
}
bool ClassicPendingScript::StartStreamingIfPossible(
- ScriptStreamer::Type streamer_type,
base::OnceClosure done) {
if (IsCurrentlyStreaming())
return false;
@@ -431,7 +533,7 @@ bool ClassicPendingScript::StartStreamingIfPossible(
// callbacks, while async + in-order scripts all do control-like activities
// (like posting new tasks). Use the 'control' queue only for control tasks.
// (More details in discussion for cl 500147.)
- auto task_type = streamer_type == ScriptStreamer::kParsingBlocking
+ auto task_type = GetSchedulingType() == ScriptSchedulingType::kParserBlocking
? TaskType::kNetworking
: TaskType::kNetworkingControl;
@@ -439,8 +541,9 @@ bool ClassicPendingScript::StartStreamingIfPossible(
DCHECK(!IsCurrentlyStreaming());
DCHECK(!streamer_done_);
ScriptStreamer::StartStreaming(
- this, streamer_type, document->GetFrame()->GetSettings(), script_state,
- document->GetTaskRunner(task_type));
+ this, document->GetFrame()->GetSettings(), script_state,
+ document->GetTaskRunner(task_type), &not_streamed_reason_);
+ DCHECK(streamer_ || not_streamed_reason_ != ScriptStreamer::kInvalid);
bool success = streamer_ && !streamer_->IsStreamingFinished();
// If we have successfully started streaming, we are required to call the
diff --git a/chromium/third_party/blink/renderer/core/script/classic_pending_script.h b/chromium/third_party/blink/renderer/core/script/classic_pending_script.h
index 677b2f9a390..bd220ad85e4 100644
--- a/chromium/third_party/blink/renderer/core/script/classic_pending_script.h
+++ b/chromium/third_party/blink/renderer/core/script/classic_pending_script.h
@@ -59,18 +59,19 @@ class CORE_EXPORT ClassicPendingScript final : public PendingScript,
return blink::ScriptType::kClassic;
}
- ClassicScript* GetSource(const KURL& document_url,
- bool& error_occurred) const override;
+ ClassicScript* GetSource(const KURL& document_url) const override;
bool IsReady() const override;
bool IsExternal() const override { return is_external_; }
- bool ErrorOccurred() const override;
bool WasCanceled() const override;
- bool StartStreamingIfPossible(ScriptStreamer::Type,
- base::OnceClosure) override;
+ bool StartStreamingIfPossible(base::OnceClosure) override;
bool IsCurrentlyStreaming() const override;
KURL UrlForTracing() const override;
void DisposeInternal() override;
+ void SetNotStreamingReasonForTest(ScriptStreamer::NotStreamingReason reason) {
+ not_streamed_reason_ = reason;
+ }
+
void Prefinalize();
private:
@@ -100,7 +101,6 @@ class CORE_EXPORT ClassicPendingScript final : public PendingScript,
void FinishWaitingForStreaming();
void FinishReadyStreaming();
void CancelStreaming();
-
void CheckState() const override;
// ResourceClient
@@ -108,6 +108,11 @@ class CORE_EXPORT ClassicPendingScript final : public PendingScript,
String DebugName() const override { return "PendingScript"; }
void DataReceived(Resource*, const char*, size_t) override;
+ static void RecordStreamingHistogram(
+ ScriptSchedulingType type,
+ bool can_use_streamer,
+ ScriptStreamer::NotStreamingReason reason);
+
// MemoryCoordinatorClient
void OnPurgeMemory() override;
@@ -148,6 +153,9 @@ class CORE_EXPORT ClassicPendingScript final : public PendingScript,
// (See also: crbug.com/754360)
bool is_currently_streaming_;
+ // Specifies the reason that script was never streamed.
+ ScriptStreamer::NotStreamingReason not_streamed_reason_;
+
// This is a temporary flag to confirm that ClassicPendingScript is not
// touched after its refinalizer call and thus https://crbug.com/715309
// doesn't break assumptions.
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 555574abd02..b6e52379535 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
@@ -131,7 +131,7 @@ class CaptureExportedStringFunction final : public ScriptFunction {
v8::Local<v8::Value> exported_value =
module_namespace->Get(context, V8String(isolate, export_name_))
.ToLocalChecked();
- captured_value_ = ToCoreString(exported_value->ToString());
+ captured_value_ = ToCoreString(exported_value->ToString(isolate));
return ScriptValue();
}
@@ -165,11 +165,11 @@ class CaptureErrorFunction final : public ScriptFunction {
v8::Local<v8::Value> name =
error_object->Get(context, V8String(isolate, "name")).ToLocalChecked();
- name_ = ToCoreString(name->ToString());
+ name_ = ToCoreString(name->ToString(isolate));
v8::Local<v8::Value> message =
error_object->Get(context, V8String(isolate, "message"))
.ToLocalChecked();
- message_ = ToCoreString(message->ToString());
+ message_ = ToCoreString(message->ToString(isolate));
return ScriptValue();
}
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 36257cd0a42..a591220218c 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
@@ -34,6 +34,11 @@ const String FetchClientSettingsObjectImpl::GetOutgoingReferrer() const {
return execution_context_->OutgoingReferrer();
}
+HttpsState FetchClientSettingsObjectImpl::GetHttpsState() const {
+ DCHECK(execution_context_->IsContextThread());
+ return execution_context_->GetHttpsState();
+}
+
void FetchClientSettingsObjectImpl::Trace(Visitor* visitor) {
visitor->Trace(execution_context_);
FetchClientSettingsObject::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/script/fetch_client_settings_object_impl.h b/chromium/third_party/blink/renderer/core/script/fetch_client_settings_object_impl.h
index 7f1e29c1ceb..e6f284b971f 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
@@ -9,6 +9,7 @@
#include "third_party/blink/renderer/core/script/fetch_client_settings_object.h"
#include "third_party/blink/renderer/platform/cross_thread_copier.h"
#include "third_party/blink/renderer/platform/heap/member.h"
+#include "third_party/blink/renderer/platform/loader/fetch/https_state.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/weborigin/referrer_policy.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
@@ -35,6 +36,8 @@ class CORE_EXPORT FetchClientSettingsObjectImpl final
ReferrerPolicy GetReferrerPolicy() const override;
const String GetOutgoingReferrer() const override;
+ HttpsState GetHttpsState() const;
+
void Trace(Visitor* visitor) override;
private:
diff --git a/chromium/third_party/blink/renderer/core/script/html_parser_script_runner.cc b/chromium/third_party/blink/renderer/core/script/html_parser_script_runner.cc
index 8fa3c5aa45a..008ee437a53 100644
--- a/chromium/third_party/blink/renderer/core/script/html_parser_script_runner.cc
+++ b/chromium/third_party/blink/renderer/core/script/html_parser_script_runner.cc
@@ -80,14 +80,9 @@ std::unique_ptr<TracedValue> GetTraceArgsForScriptElement(
}
void DoExecuteScript(PendingScript* pending_script, const KURL& document_url) {
- ScriptElementBase* element = pending_script->GetElement();
- const char* const trace_event_name =
- pending_script->ErrorOccurred()
- ? "HTMLParserScriptRunner ExecuteScriptFailed"
- : "HTMLParserScriptRunner ExecuteScript";
- TRACE_EVENT_WITH_FLOW1("blink", trace_event_name, element,
- TRACE_EVENT_FLAG_FLOW_IN, "data",
- GetTraceArgsForScriptElement(pending_script));
+ TRACE_EVENT_WITH_FLOW1("blink", "HTMLParserScriptRunner ExecuteScript",
+ pending_script->GetElement(), TRACE_EVENT_FLAG_FLOW_IN,
+ "data", GetTraceArgsForScriptElement(pending_script));
pending_script->ExecuteScriptBlock(document_url);
}
@@ -185,40 +180,81 @@ bool HTMLParserScriptRunner::IsParserBlockingScriptReady() {
return ParserBlockingScript()->IsReady();
}
-// This has two callers and corresponds to different concepts in the spec:
-// - When called from executeParsingBlockingScripts(), this corresponds to some
-// steps of the "Otherwise" Clause of 'An end tag whose tag name is "script"'
-// [scriptEndTag]
-// https://html.spec.whatwg.org/multipage/parsing.html#scriptEndTag
-// - When called from executeScriptsWaitingForParsing(), this corresponds
-// [ESB]
-// https://html.spec.whatwg.org/multipage/scripting.html#execute-the-script-block
-// and thus currently this function does more than specced.
-// TODO(hiroshige): Make the spec and implementation consistent.
-void HTMLParserScriptRunner::ExecutePendingScriptAndDispatchEvent(
- PendingScript* pending_script,
- ScriptStreamer::Type pending_script_type) {
+// Corresponds to some steps of the "Otherwise" Clause of 'An end tag whose
+// tag name is "script"'
+// https://html.spec.whatwg.org/multipage/parsing.html#scriptEndTag
+void HTMLParserScriptRunner::
+ ExecutePendingParserBlockingScriptAndDispatchEvent() {
// Stop watching loads before executeScript to prevent recursion if the script
// reloads itself.
// TODO(kouhei): Consider merging this w/ pendingScript->dispose() after the
// if block.
+ // TODO(kouhei, hiroshige): Consider merging this w/ the code clearing
+ // |parser_blocking_script_| below.
+ PendingScript* pending_script = parser_blocking_script_;
pending_script->StopWatchingForLoad();
if (!IsExecutingScript()) {
+ // TODO(kouhei, hiroshige): Investigate why we need checkpoint here.
Microtask::PerformCheckpoint(V8PerIsolateData::MainThreadIsolate());
- if (pending_script_type == ScriptStreamer::kParsingBlocking) {
- // The parser cannot be unblocked as a microtask requested another
- // resource
- if (!document_->IsScriptExecutionReady())
- return;
- }
+ // The parser cannot be unblocked as a microtask requested another
+ // resource
+ if (!document_->IsScriptExecutionReady())
+ return;
}
- // <spec label="scriptEndTag" step="B.1">Let the script be the pending
+ // <spec step="B.1">Let the script be the pending
// parsing-blocking script. There is no longer a pending parsing-blocking
// script.</spec>
- if (pending_script_type == ScriptStreamer::kParsingBlocking) {
- parser_blocking_script_ = nullptr;
+ parser_blocking_script_ = nullptr;
+
+ {
+ // <spec step="B.7">Increment the parser's script
+ // nesting level by one (it should be zero before this step, so this sets it
+ // to one).</spec>
+ HTMLParserReentryPermit::ScriptNestingLevelIncrementer
+ nesting_level_incrementer =
+ reentry_permit_->IncrementScriptNestingLevel();
+
+ // TODO(hiroshige): Remove IgnoreDestructiveWriteCountIncrementer here,
+ // according to the spec. After https://crbug.com/721914 is resolved,
+ // |document_| is equal to the element's context document used in
+ // PendingScript::ExecuteScriptBlockInternal(), and thus this can be removed
+ // more easily.
+ IgnoreDestructiveWriteCountIncrementer
+ ignore_destructive_write_count_incrementer(document_);
+
+ // <spec step="B.8">Execute the script.</spec>
+ DCHECK(IsExecutingScript());
+ DoExecuteScript(pending_script, DocumentURLForScriptExecution(document_));
+
+ // <spec step="B.9">Decrement the parser's script
+ // nesting level by one. If the parser's script nesting level is zero (which
+ // it always should be at this point), then set the parser pause flag to
+ // false.</spec>
+ //
+ // This is implemented by ~ScriptNestingLevelIncrementer().
+ }
+
+ DCHECK(!IsExecutingScript());
+}
+
+// Should be correspond to
+// https://html.spec.whatwg.org/multipage/scripting.html#execute-the-script-block
+// but currently does more than specced, because historically this and
+// ExecutePendingParserBlockingScriptAndDispatchEvent() was the same method.
+// TODO(hiroshige): Make this spec-conformant.
+void HTMLParserScriptRunner::ExecutePendingDeferredScriptAndDispatchEvent(
+ PendingScript* pending_script) {
+ // Stop watching loads before executeScript to prevent recursion if the script
+ // reloads itself.
+ // TODO(kouhei): Consider merging this w/ pendingScript->dispose() after the
+ // if block.
+ pending_script->StopWatchingForLoad();
+
+ if (!IsExecutingScript()) {
+ // TODO(kouhei, hiroshige): Investigate why we need checkpoint here.
+ Microtask::PerformCheckpoint(V8PerIsolateData::MainThreadIsolate());
}
{
@@ -345,8 +381,7 @@ void HTMLParserScriptRunner::ExecuteParsingBlockingScripts() {
InsertionPointRecord insertion_point_record(host_->InputStream());
// 1., 7.--9.
- ExecutePendingScriptAndDispatchEvent(parser_blocking_script_,
- ScriptStreamer::kParsingBlocking);
+ ExecutePendingParserBlockingScriptAndDispatchEvent();
// <spec step="B.10">Let the insertion point be undefined again.</spec>
//
@@ -411,7 +446,7 @@ bool HTMLParserScriptRunner::ExecuteScriptsWaitingForParsing() {
// <spec step="3.2">Execute the first script in the list of scripts that
// will execute when the document has finished parsing.</spec>
- ExecutePendingScriptAndDispatchEvent(first, ScriptStreamer::kDeferred);
+ ExecutePendingDeferredScriptAndDispatchEvent(first);
// FIXME: What is this m_document check for?
if (!document_)
@@ -442,8 +477,7 @@ void HTMLParserScriptRunner::RequestParsingBlockingScript(
// Callers will attempt to run the m_parserBlockingScript if possible before
// returning control to the parser.
if (!ParserBlockingScript()->IsReady()) {
- parser_blocking_script_->StartStreamingIfPossible(
- ScriptStreamer::kParsingBlocking, base::OnceClosure());
+ parser_blocking_script_->StartStreamingIfPossible(base::OnceClosure());
parser_blocking_script_->WatchForLoad(this);
}
}
@@ -457,8 +491,7 @@ void HTMLParserScriptRunner::RequestDeferredScript(
return;
if (!pending_script->IsReady()) {
- pending_script->StartStreamingIfPossible(ScriptStreamer::kDeferred,
- base::OnceClosure());
+ pending_script->StartStreamingIfPossible(base::OnceClosure());
}
DCHECK(pending_script->IsExternalOrModule());
diff --git a/chromium/third_party/blink/renderer/core/script/html_parser_script_runner.h b/chromium/third_party/blink/renderer/core/script/html_parser_script_runner.h
index a5e1596e083..3d49f8c6051 100644
--- a/chromium/third_party/blink/renderer/core/script/html_parser_script_runner.h
+++ b/chromium/third_party/blink/renderer/core/script/html_parser_script_runner.h
@@ -28,7 +28,6 @@
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
-#include "third_party/blink/renderer/bindings/core/v8/script_streamer.h"
#include "third_party/blink/renderer/core/html/parser/html_parser_reentry_permit.h"
#include "third_party/blink/renderer/core/script/pending_script.h"
#include "third_party/blink/renderer/platform/bindings/name_client.h"
@@ -110,8 +109,8 @@ class HTMLParserScriptRunner final
// PendingScriptClient
void PendingScriptFinished(PendingScript*) override;
- void ExecutePendingScriptAndDispatchEvent(PendingScript*,
- ScriptStreamer::Type);
+ void ExecutePendingParserBlockingScriptAndDispatchEvent();
+ void ExecutePendingDeferredScriptAndDispatchEvent(PendingScript*);
void ExecuteParsingBlockingScripts();
void RequestParsingBlockingScript(ScriptLoader*);
diff --git a/chromium/third_party/blink/renderer/core/script/layered_api.cc b/chromium/third_party/blink/renderer/core/script/layered_api.cc
index 9460bb6fc00..ccb19051c12 100644
--- a/chromium/third_party/blink/renderer/core/script/layered_api.cc
+++ b/chromium/third_party/blink/renderer/core/script/layered_api.cc
@@ -60,7 +60,7 @@ bool IsImplemented(const String& name) {
} // namespace
// https://github.com/drufball/layered-apis/blob/master/spec.md#user-content-layered-api-fetching-url
-KURL ResolveFetchingURL(const KURL& url, const KURL& base_url) {
+KURL ResolveFetchingURL(const KURL& url) {
// <spec step="1">If url's scheme is not "std", return url.</spec>
if (!url.ProtocolIs(kStdScheme))
return url;
@@ -68,39 +68,18 @@ KURL ResolveFetchingURL(const KURL& url, const KURL& base_url) {
// <spec step="2">Let path be url's path[0].</spec>
const String path = url.GetPath();
- // <spec step="3">Let identifier be the portion of path before the first
- // U+007C (|), or all of path if no U+007C is present.</spec>
- //
- // <spec step="4">Let fallback be the portion of path after the first U+007C,
- // or null if no U+007C is present.</spec>
- String identifier;
- String fallback;
- const size_t separator_position = path.find('|');
- if (separator_position != WTF::kNotFound) {
- identifier = path.Substring(0, separator_position);
- fallback = path.Substring(separator_position + 1);
- } else {
- identifier = path;
- }
-
// <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(identifier)) {
+ if (IsImplemented(path)) {
StringBuilder url_string;
url_string.Append(kStdScheme);
url_string.Append(":");
- url_string.Append(identifier);
+ url_string.Append(path);
return KURL(NullURL(), url_string.ToString());
}
- // <spec step="6">If fallback is null, return failure.</spec>
- if (fallback.IsNull())
- return NullURL();
-
- // <spec step="7">Return the result of parsing fallback with the base URL
- // baseURLForFallback.</spec>
- return KURL(base_url, fallback);
+ return NullURL();
}
KURL GetInternalURL(const KURL& url) {
diff --git a/chromium/third_party/blink/renderer/core/script/layered_api.h b/chromium/third_party/blink/renderer/core/script/layered_api.h
index 87f8e598914..37f948c0b93 100644
--- a/chromium/third_party/blink/renderer/core/script/layered_api.h
+++ b/chromium/third_party/blink/renderer/core/script/layered_api.h
@@ -17,11 +17,11 @@ namespace blink {
// https://docs.google.com/document/d/1V-WaCZQbBcQJRSYSYBb8Y6p0DOdDpiNDSmD41ui_73s/edit
namespace layered_api {
-// <spec
-// href="https://github.com/drufball/layered-apis/blob/master/spec.md#user-content-layered-api-fetching-url">
-// This operation maps URLs of the form std:x|y to either std:x or y
-// URLs.</spec>
-CORE_EXPORT KURL ResolveFetchingURL(const KURL&, const KURL& base_url);
+// 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 KURL&);
// Returns std-internal://x/index.js if the URL is Layered API, or null URL
// otherwise (not specced).
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
index ae780318baf..c935ed0b831 100644
--- a/chromium/third_party/blink/renderer/core/script/layered_api_test.cc
+++ b/chromium/third_party/blink/renderer/core/script/layered_api_test.cc
@@ -15,31 +15,17 @@ namespace {
TEST(LayeredAPITest, ResolveFetchingURL) {
KURL base_url("https://example.com/base/path/");
- EXPECT_EQ(ResolveFetchingURL(KURL("https://example.com/"), base_url),
+ EXPECT_EQ(ResolveFetchingURL(KURL("https://example.com/")),
KURL("https://example.com/"));
- EXPECT_EQ(ResolveFetchingURL(KURL("std:blank"), base_url), KURL("std:blank"));
- EXPECT_EQ(ResolveFetchingURL(KURL("std:blank|https://fallback.example.com/"),
- base_url),
- KURL("std:blank"));
- EXPECT_EQ(
- ResolveFetchingURL(KURL("std:blank|https://:invalid-url"), base_url),
- KURL("std:blank"));
-
- EXPECT_EQ(ResolveFetchingURL(KURL("std:none"), base_url), NullURL());
- EXPECT_EQ(ResolveFetchingURL(KURL("std:none|https://fallback.example.com/"),
- base_url),
- KURL("https://fallback.example.com/"));
- EXPECT_FALSE(
- ResolveFetchingURL(KURL("std:none|https://:invalid-url"), base_url)
- .IsValid());
-
- EXPECT_EQ(ResolveFetchingURL(KURL("std:none|fallback.js"), base_url),
- KURL("https://example.com/base/path/fallback.js"));
- EXPECT_EQ(ResolveFetchingURL(KURL("std:none|./fallback.js"), base_url),
- KURL("https://example.com/base/path/fallback.js"));
- EXPECT_EQ(ResolveFetchingURL(KURL("std:none|/fallback.js"), base_url),
- KURL("https://example.com/fallback.js"));
+ EXPECT_EQ(ResolveFetchingURL(KURL("std:blank")), KURL("std:blank"));
+
+ EXPECT_EQ(ResolveFetchingURL(KURL("std:none")), NullURL());
+
+ // Fallback syntax is currently disabled and rejected.
+ // https://crbug.com/864748
+ EXPECT_EQ(ResolveFetchingURL(KURL("std:blank|https://example.com/")),
+ NullURL());
}
TEST(LayeredAPITest, GetInternalURL) {
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 77ccd8dc740..27a94b14d3f 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
@@ -32,6 +32,7 @@ class MockScriptElementBase
MOCK_CONST_METHOD0(EventAttributeValue, String());
MOCK_CONST_METHOD0(ForAttributeValue, String());
MOCK_CONST_METHOD0(IntegrityAttributeValue, String());
+ MOCK_CONST_METHOD0(ReferrerPolicyAttributeValue, String());
MOCK_CONST_METHOD0(LanguageAttributeValue, String());
MOCK_CONST_METHOD0(NomoduleAttributeValue, bool());
MOCK_CONST_METHOD0(SourceAttributeValue, String());
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 13915b3d97e..f3f3203f0a5 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
@@ -121,7 +121,7 @@ KURL ModulatorImplBase::ResolveModuleSpecifier(const String& module_request,
// specifier. If parsed is not failure, then return the layered API fetching
// URL given parsed and script's base URL.</spec>
if (RuntimeEnabledFeatures::LayeredAPIEnabled())
- return blink::layered_api::ResolveFetchingURL(url, base_url);
+ return blink::layered_api::ResolveFetchingURL(url);
return url;
}
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 0432bb25c02..9926a088a78 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
@@ -107,14 +107,14 @@ class ModuleMapTestModulator final : public DummyModulator {
USING_GARBAGE_COLLECTED_MIXIN(TestModuleScriptFetcher);
public:
- TestModuleScriptFetcher(ModuleMapTestModulator* modulator)
+ explicit TestModuleScriptFetcher(ModuleMapTestModulator* modulator)
: modulator_(modulator) {}
void Fetch(FetchParameters& request,
ModuleGraphLevel,
ModuleScriptFetcher::Client* client) override {
TestRequest* test_request = new TestRequest(
ModuleScriptCreationParams(
- request.Url(), MovableString(String("").ReleaseImpl()),
+ request.Url(), ParkableString(String("").ReleaseImpl()),
request.GetResourceRequest().GetFetchCredentialsMode(),
kSharableCrossOrigin),
client);
diff --git a/chromium/third_party/blink/renderer/core/script/module_pending_script.cc b/chromium/third_party/blink/renderer/core/script/module_pending_script.cc
index 8ad0afe2431..cfe0735ec4f 100644
--- a/chromium/third_party/blink/renderer/core/script/module_pending_script.cc
+++ b/chromium/third_party/blink/renderer/core/script/module_pending_script.cc
@@ -65,16 +65,9 @@ void ModulePendingScript::NotifyModuleTreeLoadFinished() {
PendingScriptFinished();
}
-Script* ModulePendingScript::GetSource(const KURL& document_url,
- bool& error_occurred) const {
+Script* ModulePendingScript::GetSource(const KURL& document_url) const {
CHECK(IsReady());
- error_occurred = ErrorOccurred();
return GetModuleScript();
}
-bool ModulePendingScript::ErrorOccurred() const {
- CHECK(IsReady());
- return !GetModuleScript();
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/script/module_pending_script.h b/chromium/third_party/blink/renderer/core/script/module_pending_script.h
index 15be60e0760..916b07376a3 100644
--- a/chromium/third_party/blink/renderer/core/script/module_pending_script.h
+++ b/chromium/third_party/blink/renderer/core/script/module_pending_script.h
@@ -72,17 +72,12 @@ class CORE_EXPORT ModulePendingScript : public PendingScript {
// PendingScript
ScriptType GetScriptType() const override { return ScriptType::kModule; }
- Script* GetSource(const KURL& document_url,
- bool& error_occurred) const override;
+ Script* GetSource(const KURL& document_url) const override;
bool IsReady() const override { return ready_; }
bool IsExternal() const override { return is_external_; }
- bool ErrorOccurred() const override;
bool WasCanceled() const override { return false; }
- bool StartStreamingIfPossible(ScriptStreamer::Type,
- base::OnceClosure) override {
- return false;
- }
+ bool StartStreamingIfPossible(base::OnceClosure) override { return false; }
bool IsCurrentlyStreaming() const override { return false; }
KURL UrlForTracing() const override { return NullURL(); }
diff --git a/chromium/third_party/blink/renderer/core/script/module_script.cc b/chromium/third_party/blink/renderer/core/script/module_script.cc
index 513b8de9641..b344ffdb75e 100644
--- a/chromium/third_party/blink/renderer/core/script/module_script.cc
+++ b/chromium/third_party/blink/renderer/core/script/module_script.cc
@@ -12,7 +12,7 @@
namespace blink {
// https://html.spec.whatwg.org/multipage/webappapis.html#creating-a-module-script
-ModuleScript* ModuleScript::Create(const MovableString& original_source_text,
+ModuleScript* ModuleScript::Create(const ParkableString& original_source_text,
Modulator* modulator,
const KURL& source_url,
const KURL& base_url,
@@ -21,7 +21,7 @@ ModuleScript* ModuleScript::Create(const MovableString& original_source_text,
const TextPosition& start_position) {
// <spec step="1">If scripting is disabled for settings's responsible browsing
// context, then set source to the empty string.</spec>
- MovableString source_text;
+ ParkableString source_text;
if (!modulator->IsScriptingDisabled())
source_text = original_source_text;
@@ -101,14 +101,14 @@ ModuleScript* ModuleScript::CreateForTest(Modulator* modulator,
ScriptModule record,
const KURL& base_url,
const ScriptFetchOptions& options) {
- MovableString dummy_source_text(String("").ReleaseImpl());
+ ParkableString dummy_source_text(String("").ReleaseImpl());
KURL dummy_source_url;
return CreateInternal(dummy_source_text, modulator, record, dummy_source_url,
base_url, options, TextPosition::MinimumPosition());
}
// https://html.spec.whatwg.org/multipage/webappapis.html#creating-a-module-script
-ModuleScript* ModuleScript::CreateInternal(const MovableString& source_text,
+ModuleScript* ModuleScript::CreateInternal(const ParkableString& source_text,
Modulator* modulator,
ScriptModule result,
const KURL& source_url,
@@ -141,7 +141,7 @@ ModuleScript::ModuleScript(Modulator* settings_object,
const KURL& source_url,
const KURL& base_url,
const ScriptFetchOptions& fetch_options,
- const MovableString& source_text,
+ const ParkableString& source_text,
const TextPosition& start_position)
: Script(fetch_options, base_url),
settings_object_(settings_object),
diff --git a/chromium/third_party/blink/renderer/core/script/module_script.h b/chromium/third_party/blink/renderer/core/script/module_script.h
index eb1c6efb967..961507271f9 100644
--- a/chromium/third_party/blink/renderer/core/script/module_script.h
+++ b/chromium/third_party/blink/renderer/core/script/module_script.h
@@ -11,12 +11,12 @@
#include "third_party/blink/renderer/core/script/modulator.h"
#include "third_party/blink/renderer/core/script/script.h"
#include "third_party/blink/renderer/platform/bindings/name_client.h"
+#include "third_party/blink/renderer/platform/bindings/parkable_string.h"
#include "third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.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/kurl_hash.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
-#include "third_party/blink/renderer/platform/wtf/text/movable_string.h"
#include "third_party/blink/renderer/platform/wtf/text/text_position.h"
namespace blink {
@@ -27,7 +27,7 @@ class CORE_EXPORT ModuleScript final : public Script, public NameClient {
public:
// https://html.spec.whatwg.org/multipage/webappapis.html#creating-a-module-script
static ModuleScript* Create(
- const MovableString& source_text,
+ const ParkableString& source_text,
Modulator*,
const KURL& source_url,
const KURL& base_url,
@@ -71,10 +71,10 @@ class CORE_EXPORT ModuleScript final : public Script, public NameClient {
const KURL& source_url,
const KURL& base_url,
const ScriptFetchOptions&,
- const MovableString& source_text,
+ const ParkableString& source_text,
const TextPosition& start_position);
- static ModuleScript* CreateInternal(const MovableString& source_text,
+ static ModuleScript* CreateInternal(const ParkableString& source_text,
Modulator*,
ScriptModule,
const KURL& source_url,
@@ -136,7 +136,7 @@ class CORE_EXPORT ModuleScript final : public Script, public NameClient {
TraceWrapperV8Reference<v8::Value> error_to_rethrow_;
// For CSP check.
- const MovableString source_text_;
+ const ParkableString source_text_;
const TextPosition start_position_;
HashMap<String, KURL> specifier_to_url_cache_;
@@ -147,4 +147,4 @@ CORE_EXPORT std::ostream& operator<<(std::ostream&, const ModuleScript&);
} // namespace blink
-#endif
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_MODULE_SCRIPT_H_
diff --git a/chromium/third_party/blink/renderer/core/script/pending_script.cc b/chromium/third_party/blink/renderer/core/script/pending_script.cc
index fbca3f9d4e8..2a3901ed167 100644
--- a/chromium/third_party/blink/renderer/core/script/pending_script.cc
+++ b/chromium/third_party/blink/renderer/core/script/pending_script.cc
@@ -138,18 +138,21 @@ void PendingScript::ExecuteScriptBlock(const KURL& document_url) {
return;
}
- // Do not execute module scripts if they are moved between documents.
- // TODO(hiroshige): Also do not execute classic scripts. crbug.com/721914
- if (OriginalContextDocument() != context_document &&
- GetScriptType() == ScriptType::kModule) {
- Dispose();
- return;
+ if (OriginalContextDocument() != context_document) {
+ if (GetScriptType() == ScriptType::kModule) {
+ // Do not execute module scripts if they are moved between documents.
+ Dispose();
+ return;
+ }
+
+ // TODO(hiroshige): Also do not execute classic scripts.
+ // https://crbug.com/721914
+ UseCounter::Count(frame, WebFeature::kEvaluateScriptMovedBetweenDocuments);
}
- bool error_occurred = false;
- Script* script = GetSource(document_url, error_occurred);
+ Script* script = GetSource(document_url);
- if (!error_occurred && !IsExternal()) {
+ if (script && !IsExternal()) {
bool should_bypass_main_world_csp =
frame->GetScriptController().ShouldBypassMainWorldCSP();
@@ -160,7 +163,7 @@ void PendingScript::ExecuteScriptBlock(const KURL& document_url) {
ContentSecurityPolicy::InlineType::kBlock)) {
// Consider as if "the script's script is null" retrospectively,
// if the CSP check fails, which is considered as load failure.
- error_occurred = true;
+ script = nullptr;
}
}
@@ -175,15 +178,13 @@ void PendingScript::ExecuteScriptBlock(const KURL& document_url) {
// ExecuteScriptBlockInternal() is split just in order to prevent accidential
// access to |this| after Dispose().
- ExecuteScriptBlockInternal(script, error_occurred, element, was_canceled,
- is_external, created_during_document_write,
- parser_blocking_load_start_time,
- is_controlled_by_script_runner);
+ ExecuteScriptBlockInternal(
+ script, element, was_canceled, is_external, created_during_document_write,
+ parser_blocking_load_start_time, is_controlled_by_script_runner);
}
void PendingScript::ExecuteScriptBlockInternal(
Script* script,
- bool error_occurred,
ScriptElementBase* element,
bool was_canceled,
bool is_external,
@@ -195,7 +196,7 @@ void PendingScript::ExecuteScriptBlockInternal(
// <spec step="2">If the script's script is null, fire an event named error at
// the element, and return.</spec>
- if (error_occurred) {
+ if (!script) {
element->DispatchErrorEvent();
return;
}
diff --git a/chromium/third_party/blink/renderer/core/script/pending_script.h b/chromium/third_party/blink/renderer/core/script/pending_script.h
index 3f641b695c0..d031cc77698 100644
--- a/chromium/third_party/blink/renderer/core/script/pending_script.h
+++ b/chromium/third_party/blink/renderer/core/script/pending_script.h
@@ -28,7 +28,6 @@
#include "base/macros.h"
#include "third_party/blink/public/platform/web_scoped_virtual_time_pauser.h"
-#include "third_party/blink/renderer/bindings/core/v8/script_streamer.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/script/script.h"
#include "third_party/blink/renderer/core/script/script_element_base.h"
@@ -88,18 +87,16 @@ class CORE_EXPORT PendingScript
virtual void Trace(blink::Visitor*);
const char* NameInHeapSnapshot() const override { return "PendingScript"; }
- virtual Script* GetSource(const KURL& document_url,
- bool& error_occurred) const = 0;
+ // Returns nullptr when "script's script is null", i.e. an error occurred.
+ virtual Script* GetSource(const KURL& document_url) const = 0;
// https://html.spec.whatwg.org/multipage/scripting.html#the-script-is-ready
virtual bool IsReady() const = 0;
virtual bool IsExternal() const = 0;
- virtual bool ErrorOccurred() const = 0;
virtual bool WasCanceled() const = 0;
// Support for script streaming.
- virtual bool StartStreamingIfPossible(ScriptStreamer::Type,
- base::OnceClosure) = 0;
+ virtual bool StartStreamingIfPossible(base::OnceClosure) = 0;
virtual bool IsCurrentlyStreaming() const = 0;
// Used only for tracing, and can return a null URL.
@@ -152,7 +149,6 @@ class CORE_EXPORT PendingScript
private:
static void ExecuteScriptBlockInternal(
Script*,
- bool error_occurred,
ScriptElementBase*,
bool was_canceled,
bool is_external,
diff --git a/chromium/third_party/blink/renderer/core/script/resources/layered_api/async-local-storage/index.js b/chromium/third_party/blink/renderer/core/script/resources/layered_api/async-local-storage/index.js
index c7149cb30ce..b3971d06895 100644
--- a/chromium/third_party/blink/renderer/core/script/resources/layered_api/async-local-storage/index.js
+++ b/chromium/third_party/blink/renderer/core/script/resources/layered_api/async-local-storage/index.js
@@ -1,20 +1,27 @@
// TODOs/spec-noncompliances:
-// - Susceptible to tampering of built-in prototypes and globals. We want to work on tooling to ameliorate that.
-// - Uses symbols for information hiding but those are interceptable and forgeable. Need private fields/methods.
+// - Susceptible to tampering of built-in prototypes and globals. We want to
+// work on tooling to ameliorate that.
-const databaseName = Symbol("[[DatabaseName]]");
-const databasePromise = Symbol("[[DatabasePromise]]");
+// TODO: Use private fields when those ship.
+const databaseName = new WeakMap();
+const databasePromise = new WeakMap();
+
+if (!self.isSecureContext) {
+ throw new DOMException(
+ 'Async local storage is only available in secure contexts',
+ 'SecurityError');
+}
export class StorageArea {
constructor(name) {
- this[databasePromise] = null;
- this[databaseName] = "async-local-storage:" + `${name}`;
+ databasePromise.set(this, null);
+ databaseName.set(this, `async-local-storage:${name}`);
}
async set(key, value) {
throwForDisallowedKey(key);
- return performDatabaseOperation(this, "readwrite", (transaction, store) => {
+ return performDatabaseOperation(this, 'readwrite', (transaction, store) => {
store.put(value, key);
return new Promise((resolve, reject) => {
@@ -28,7 +35,7 @@ export class StorageArea {
async get(key) {
throwForDisallowedKey(key);
- return performDatabaseOperation(this, "readonly", (transaction, store) => {
+ return performDatabaseOperation(this, 'readonly', (transaction, store) => {
const request = store.get(key);
return new Promise((resolve, reject) => {
@@ -41,7 +48,7 @@ export class StorageArea {
async has(key) {
throwForDisallowedKey(key);
- return performDatabaseOperation(this, "readonly", (transaction, store) => {
+ return performDatabaseOperation(this, 'readonly', (transaction, store) => {
const request = store.count(key);
return new Promise((resolve, reject) => {
@@ -54,7 +61,7 @@ export class StorageArea {
async delete(key) {
throwForDisallowedKey(key);
- return performDatabaseOperation(this, "readwrite", (transaction, store) => {
+ return performDatabaseOperation(this, 'readwrite', (transaction, store) => {
store.delete(key);
return new Promise((resolve, reject) => {
@@ -66,28 +73,27 @@ export class StorageArea {
}
async clear() {
- if (!(databasePromise in this)) {
- return Promise.reject(new TypeError("Invalid this value"));
+ if (!databasePromise.has(this)) {
+ return Promise.reject(new TypeError('Invalid this value'));
}
- if (this[databasePromise] !== null) {
- return this[databasePromise].then(
- () => {
- this[databasePromise] = null;
- return deleteDatabase(this[databaseName]);
- },
- () => {
- this[databasePromise] = null;
- return deleteDatabase(this[databaseName]);
- }
- );
+ if (databasePromise.get(this) !== null) {
+ return databasePromise.get(this).then(
+ () => {
+ databasePromise.set(this, null);
+ return deleteDatabase(databaseName.get(this));
+ },
+ () => {
+ databasePromise.set(this, null);
+ return deleteDatabase(databaseName.get(this));
+ });
}
- return deleteDatabase(this[databaseName]);
+ return deleteDatabase(databaseName.get(this));
}
async keys() {
- return performDatabaseOperation(this, "readonly", (transaction, store) => {
+ return performDatabaseOperation(this, 'readonly', (transaction, store) => {
const request = store.getAllKeys(undefined);
return new Promise((resolve, reject) => {
@@ -98,7 +104,7 @@ export class StorageArea {
}
async values() {
- return performDatabaseOperation(this, "readonly", (transaction, store) => {
+ return performDatabaseOperation(this, 'readonly', (transaction, store) => {
const request = store.getAll(undefined);
return new Promise((resolve, reject) => {
@@ -109,7 +115,7 @@ export class StorageArea {
}
async entries() {
- return performDatabaseOperation(this, "readonly", (transaction, store) => {
+ return performDatabaseOperation(this, 'readonly', (transaction, store) => {
const keysRequest = store.getAllKeys(undefined);
const valuesRequest = store.getAll(undefined);
@@ -125,48 +131,44 @@ export class StorageArea {
}
get backingStore() {
- if (!(databasePromise in this)) {
- throw new TypeError("Invalid this value");
+ if (!databasePromise.has(this)) {
+ throw new TypeError('Invalid this value');
}
- return {
- database: this[databaseName],
- store: "store",
- version: 1
- };
+ return {database: databaseName.get(this), store: 'store', version: 1};
}
}
-export const storage = new StorageArea("default");
+export const storage = new StorageArea('default');
function performDatabaseOperation(area, mode, steps) {
- if (!(databasePromise in area)) {
- return Promise.reject(new TypeError("Invalid this value"));
+ if (!databasePromise.has(area)) {
+ return Promise.reject(new TypeError('Invalid this value'));
}
- if (area[databasePromise] === null) {
+ if (databasePromise.get(area) === null) {
initializeDatabasePromise(area);
}
- return area[databasePromise].then(database => {
- const transaction = database.transaction("store", mode);
- const store = transaction.objectStore("store");
+ return databasePromise.get(area).then(database => {
+ const transaction = database.transaction('store', mode);
+ const store = transaction.objectStore('store');
return steps(transaction, store);
});
}
function initializeDatabasePromise(area) {
- area[databasePromise] = new Promise((resolve, reject) => {
- const request = self.indexedDB.open(area[databaseName], 1);
+ databasePromise.set(area, new Promise((resolve, reject) => {
+ const request = self.indexedDB.open(databaseName.get(area), 1);
request.onsuccess = () => {
const database = request.result;
- database.onclose = () => area[databasePromise] = null;
+ database.onclose = () => databasePromise.set(area, null);
database.onversionchange = () => {
database.close();
- area[databasePromise] = null;
- }
+ databasePromise.set(area, null);
+ };
resolve(database);
};
@@ -174,16 +176,16 @@ function initializeDatabasePromise(area) {
request.onupgradeneeded = () => {
try {
- request.result.createObjectStore("store");
+ request.result.createObjectStore('store');
} catch (e) {
reject(e);
}
};
- });
+ }));
}
function isAllowedAsAKey(value) {
- if (typeof value === "number" || typeof value === "string") {
+ if (typeof value === 'number' || typeof value === 'string') {
return true;
}
@@ -210,24 +212,26 @@ function isDate(value) {
try {
Date.prototype.getTime.call(value);
return true;
- } catch (e) { // TODO: remove useless binding
+ } catch {
return false;
}
}
-const byteLengthGetter = Object.getOwnPropertyDescriptor(ArrayBuffer.prototype, "byteLength").get;
+const byteLengthGetter =
+ Object.getOwnPropertyDescriptor(ArrayBuffer.prototype, 'byteLength').get;
function isArrayBuffer(value) {
try {
byteLengthGetter.call(value);
return true;
- } catch (e) { // TODO: remove useless binding
+ } catch {
return false;
}
}
function throwForDisallowedKey(key) {
if (!isAllowedAsAKey(key)) {
- throw new DOMException("The given value is not allowed as a key", "DataError");
+ throw new DOMException(
+ 'The given value is not allowed as a key', 'DataError');
}
}
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 076c45a8be7..7f6e6fa21c4 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
@@ -50,6 +50,7 @@ class CORE_EXPORT ScriptElementBase : public GarbageCollectedMixin {
virtual bool NomoduleAttributeValue() const = 0;
virtual String SourceAttributeValue() const = 0;
virtual String TypeAttributeValue() const = 0;
+ virtual String ReferrerPolicyAttributeValue() const = 0;
virtual String TextFromChildren() = 0;
virtual bool HasSourceAttribute() const = 0;
diff --git a/chromium/third_party/blink/renderer/core/script/script_loader.cc b/chromium/third_party/blink/renderer/core/script/script_loader.cc
index a413f0f0ae8..abd35d737b6 100644
--- a/chromium/third_party/blink/renderer/core/script/script_loader.cc
+++ b/chromium/third_party/blink/renderer/core/script/script_loader.cc
@@ -47,6 +47,7 @@
#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/platform/bindings/parkable_string.h"
#include "third_party/blink/renderer/platform/feature_policy/feature_policy.h"
#include "third_party/blink/renderer/platform/histogram.h"
#include "third_party/blink/renderer/platform/loader/fetch/access_control_status.h"
@@ -55,8 +56,8 @@
#include "third_party/blink/renderer/platform/loader/subresource_integrity.h"
#include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
+#include "third_party/blink/renderer/platform/weborigin/security_policy.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
-#include "third_party/blink/renderer/platform/wtf/text/movable_string.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
@@ -300,15 +301,24 @@ bool ScriptLoader::PrepareScript(const TextPosition& script_start_position,
//
// FIXME: If script is parser inserted, verify it's still in the original
// document.
+
+ // <spec step="11">If scripting is disabled for the script element, then
+ // return. The script is not executed.</spec>
+ //
+ // <spec
+ // href="https://html.spec.whatwg.org/multipage/webappapis.html#concept-n-noscript">
+ // Scripting is disabled for a node if [the node's node document has no
+ // browsing context], or if scripting is disabled in that browsing context.
+ // </spec>
Document& element_document = element_->GetDocument();
- Document* context_document = element_document.ContextDocument();
+ // TODO(timothygu): Investigate if we could switch from ExecutingFrame() to
+ // ExecutingWindow().
if (!element_document.ExecutingFrame())
return false;
+
+ Document* context_document = element_document.ContextDocument();
if (!context_document || !context_document->ExecutingFrame())
return false;
-
- // <spec step="11">If scripting is disabled for the script element, then
- // return. The script is not executed.</spec>
if (!context_document->CanExecuteScripts(kAboutToExecuteScript))
return false;
@@ -363,10 +373,13 @@ bool ScriptLoader::PrepareScript(const TextPosition& script_start_position,
// <spec step="20">Let referrer policy be the current state of the element's
// referrerpolicy content attribute.</spec>
- // TODO(domfarolino): Implement referrerpolicy attribute on script elements.
- // As a stopgap, we set |referrer_policy| to document's referrer policy to
- // keep the backward compatibility (https://crbug.com/841673).
- ReferrerPolicy referrer_policy = element_document.GetReferrerPolicy();
+ String referrerpolicy_attr = element_->ReferrerPolicyAttributeValue();
+ ReferrerPolicy referrer_policy = kReferrerPolicyDefault;
+ if (!referrerpolicy_attr.IsEmpty()) {
+ SecurityPolicy::ReferrerPolicyFromString(
+ referrerpolicy_attr, kDoNotSupportReferrerPolicyLegacyKeywords,
+ &referrer_policy);
+ }
// <spec step="21">Let parser metadata be "parser-inserted" if the script
// element has been flagged as "parser-inserted", and "not-parser-inserted"
@@ -395,7 +408,7 @@ bool ScriptLoader::PrepareScript(const TextPosition& script_start_position,
// <spec step="22">Let options be a script fetch options whose cryptographic
// nonce is cryptographic nonce, integrity metadata is integrity metadata,
// parser metadata is parser metadata, credentials mode is module script
- // credentials mode, and referrer policy is referrer_policy.</spec>
+ // credentials mode, and referrer policy is referrer policy.</spec>
ScriptFetchOptions options(nonce, integrity_metadata, integrity_attr,
parser_state, credentials_mode, referrer_policy);
@@ -546,7 +559,7 @@ bool ScriptLoader::PrepareScript(const TextPosition& script_start_position,
Modulator* modulator = Modulator::From(
ToScriptStateForMainWorld(context_document->GetFrame()));
ModuleScript* module_script = ModuleScript::Create(
- MovableString(element_->TextFromChildren().Impl()), modulator,
+ ParkableString(element_->TextFromChildren().Impl()), modulator,
source_url, base_url, options, kSharableCrossOrigin, position);
// <spec step="25.2.B.2">If this returns null, set the script's script
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 1490a3ccdb7..e5da031810c 100644
--- a/chromium/third_party/blink/renderer/core/script/script_runner.cc
+++ b/chromium/third_party/blink/renderer/core/script/script_runner.cc
@@ -29,7 +29,6 @@
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/web_thread.h"
-#include "third_party/blink/renderer/bindings/core/v8/script_streamer.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/script/script_loader.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -307,7 +306,6 @@ bool ScriptRunner::DoTryStream(PendingScript* pending_script) {
#endif
bool success = pending_script->StartStreamingIfPossible(
- ScriptStreamer::kAsync,
WTF::Bind(&ScriptRunner::NotifyScriptStreamerFinished,
WrapWeakPersistent(this)));
#ifndef NDEBUG
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 0b6d8bdf6dc..07a6a9329e3 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
@@ -37,9 +37,8 @@ class MockPendingScript : public PendingScript {
MOCK_CONST_METHOD0(GetScriptType, ScriptType());
MOCK_CONST_METHOD1(CheckMIMETypeBeforeRunScript, bool(Document*));
- MOCK_CONST_METHOD2(GetSource, Script*(const KURL&, bool&));
+ MOCK_CONST_METHOD1(GetSource, Script*(const KURL&));
MOCK_CONST_METHOD0(IsExternal, bool());
- MOCK_CONST_METHOD0(ErrorOccurred, bool());
MOCK_CONST_METHOD0(WasCanceled, bool());
MOCK_CONST_METHOD0(UrlForTracing, KURL());
MOCK_METHOD0(RemoveFromMemoryCache, void());
@@ -61,8 +60,7 @@ class MockPendingScript : public PendingScript {
state_ = State::kReadyToBeStreamed;
}
- bool StartStreamingIfPossible(ScriptStreamer::Type type,
- base::OnceClosure closure) override {
+ bool StartStreamingIfPossible(base::OnceClosure closure) override {
if (state_ != State::kReadyToBeStreamed)
return false;
diff --git a/chromium/third_party/blink/renderer/core/scroll/BUILD.gn b/chromium/third_party/blink/renderer/core/scroll/BUILD.gn
new file mode 100644
index 00000000000..b0ae575da50
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/scroll/BUILD.gn
@@ -0,0 +1,61 @@
+# 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.
+
+import("//third_party/blink/renderer/core/core.gni")
+
+blink_core_sources("scroll") {
+ sources = [
+ "ns_scroller_imp_details.h",
+ "programmatic_scroll_animator.cc",
+ "programmatic_scroll_animator.h",
+ "scroll_animator.cc",
+ "scroll_animator.h",
+ "scroll_animator_base.cc",
+ "scroll_animator_base.h",
+ "scroll_animator_compositor_coordinator.cc",
+ "scroll_animator_compositor_coordinator.h",
+ "scroll_animator_mac.h",
+ "scroll_animator_mac.mm",
+ "scroll_customization.cc",
+ "scroll_customization.h",
+ "scroll_state_data.h",
+ "scrollable_area.cc",
+ "scrollable_area.h",
+ "scrollbar.cc",
+ "scrollbar.h",
+ "scrollbar_layer_delegate.cc",
+ "scrollbar_layer_delegate.h",
+ "scrollbar_test_suite.h",
+ "scrollbar_theme.cc",
+ "scrollbar_theme.h",
+ "scrollbar_theme_android.cc",
+ "scrollbar_theme_mac.h",
+ "scrollbar_theme_mac.mm",
+ "scrollbar_theme_mock.cc",
+ "scrollbar_theme_mock.h",
+ "scrollbar_theme_overlay.cc",
+ "scrollbar_theme_overlay.h",
+ "scrollbar_theme_overlay_mock.h",
+ "smooth_scroll_sequencer.cc",
+ "smooth_scroll_sequencer.h",
+ "web_scroll_into_view_params.cc",
+ ]
+
+ if (is_mac) {
+ sources -= [
+ "scroll_animator.cc",
+ "scroll_animator.h",
+ ]
+ sources += [
+ "web_scrollbar_theme.mm",
+ ]
+ }
+
+ if (use_default_render_theme) {
+ sources += [
+ "scrollbar_theme_aura.cc",
+ "scrollbar_theme_aura.h",
+ ]
+ }
+}
diff --git a/chromium/third_party/blink/renderer/platform/mac/ns_scroller_imp_details.h b/chromium/third_party/blink/renderer/core/scroll/ns_scroller_imp_details.h
index c5b7581b5f0..4ffa7b29d4c 100644
--- a/chromium/third_party/blink/renderer/platform/mac/ns_scroller_imp_details.h
+++ b/chromium/third_party/blink/renderer/core/scroll/ns_scroller_imp_details.h
@@ -23,8 +23,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WebCore_NSScrollerImpDetails_h
-#define WebCore_NSScrollerImpDetails_h
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_NS_SCROLLER_IMP_DETAILS_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_NS_SCROLLER_IMP_DETAILS_H_
#import <AvailabilityMacros.h>
@@ -91,4 +91,4 @@
- (void)endScrollGesture;
@end
-#endif // WebCore_NSScrollerImpDetails_h
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_NS_SCROLLER_IMP_DETAILS_H_
diff --git a/chromium/third_party/blink/renderer/platform/scroll/programmatic_scroll_animator.cc b/chromium/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.cc
index ee1eb0892b5..76be7aa30e6 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/programmatic_scroll_animator.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.cc
@@ -2,16 +2,16 @@
// Use 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/scroll/programmatic_scroll_animator.h"
+#include "third_party/blink/renderer/core/scroll/programmatic_scroll_animator.h"
#include <memory>
#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
+#include "third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.h"
#include "third_party/blink/renderer/platform/animation/compositor_keyframe_model.h"
#include "third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.h"
#include "third_party/blink/renderer/platform/geometry/int_size.h"
#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
-#include "third_party/blink/renderer/platform/scroll/scrollable_area.h"
-#include "third_party/blink/renderer/platform/scroll/smooth_scroll_sequencer.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/platform/scroll/programmatic_scroll_animator.h b/chromium/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.h
index 150fac9da5c..f85c44383f0 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/programmatic_scroll_animator.h
+++ b/chromium/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.h
@@ -2,14 +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_PLATFORM_SCROLL_PROGRAMMATIC_SCROLL_ANIMATOR_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_PROGRAMMATIC_SCROLL_ANIMATOR_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_PROGRAMMATIC_SCROLL_ANIMATOR_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_PROGRAMMATIC_SCROLL_ANIMATOR_H_
#include <memory>
+#include "third_party/blink/renderer/core/scroll/scroll_animator_compositor_coordinator.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/scroll/scroll_animator_compositor_coordinator.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/noncopyable.h"
namespace blink {
@@ -25,7 +24,7 @@ class CompositorScrollOffsetAnimationCurve;
// ScrollAnimatorMac.
class ProgrammaticScrollAnimator : public ScrollAnimatorCompositorCoordinator {
- WTF_MAKE_NONCOPYABLE(ProgrammaticScrollAnimator);
+ DISALLOW_COPY_AND_ASSIGN(ProgrammaticScrollAnimator);
public:
static ProgrammaticScrollAnimator* Create(ScrollableArea* scrollable_area) {
@@ -73,4 +72,4 @@ class ProgrammaticScrollAnimator : public ScrollAnimatorCompositorCoordinator {
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_PROGRAMMATIC_SCROLL_ANIMATOR_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_PROGRAMMATIC_SCROLL_ANIMATOR_H_
diff --git a/chromium/third_party/blink/renderer/platform/scroll/scroll_animator.cc b/chromium/third_party/blink/renderer/core/scroll/scroll_animator.cc
index 565abbea0c0..f4ed1cbd064 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/scroll_animator.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/scroll_animator.cc
@@ -28,7 +28,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "third_party/blink/renderer/platform/scroll/scroll_animator.h"
+#include "third_party/blink/renderer/core/scroll/scroll_animator.h"
#include <memory>
@@ -36,11 +36,11 @@
#include "cc/animation/scroll_offset_animation_curve.h"
#include "cc/layers/picture_layer.h"
#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
#include "third_party/blink/renderer/platform/animation/compositor_keyframe_model.h"
#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/scroll/main_thread_scrolling_reason.h"
-#include "third_party/blink/renderer/platform/scroll/scrollable_area.h"
#include "third_party/blink/renderer/platform/wtf/time.h"
namespace blink {
@@ -169,7 +169,7 @@ bool ScrollAnimator::WillAnimateToOffset(const ScrollOffset& target_offset) {
// of sending to the compositor.
if (run_state_ == RunState::kRunningOnMainThread) {
animation_curve_->UpdateTarget(
- time_function_() - start_time_,
+ TimeDelta::FromSecondsD(time_function_() - start_time_),
CompositorOffsetFromBlinkOffset(target_offset));
return true;
}
@@ -329,7 +329,7 @@ void ScrollAnimator::UpdateCompositorAnimations() {
// ::adjustScrollOffsetAnimation should have made the necessary
// adjustment to the curve.
animation_curve_->UpdateTarget(
- time_function_() - start_time_,
+ TimeDelta::FromSecondsD(time_function_() - start_time_),
CompositorOffsetFromBlinkOffset(target_offset_));
}
diff --git a/chromium/third_party/blink/renderer/platform/scroll/scroll_animator.h b/chromium/third_party/blink/renderer/core/scroll/scroll_animator.h
index ef0292bd759..9d57d96f402 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/scroll_animator.h
+++ b/chromium/third_party/blink/renderer/core/scroll/scroll_animator.h
@@ -28,14 +28,14 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLL_ANIMATOR_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLL_ANIMATOR_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLL_ANIMATOR_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLL_ANIMATOR_H_
#include <memory>
+#include "third_party/blink/renderer/core/scroll/scroll_animator_base.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/animation/compositor_scroll_offset_animation_curve.h"
-#include "third_party/blink/renderer/platform/scroll/scroll_animator_base.h"
#include "third_party/blink/renderer/platform/timer.h"
namespace blink {
@@ -97,7 +97,7 @@ class CompositorAnimationTimeline;
// animations is shared with ProgrammaticScrollAnimator, and lives mostly in the
// common base class ScrollAnimatorCompositorCoordinator.
-class PLATFORM_EXPORT ScrollAnimator : public ScrollAnimatorBase {
+class CORE_EXPORT ScrollAnimator : public ScrollAnimatorBase {
public:
explicit ScrollAnimator(ScrollableArea*,
WTF::TimeFunction = WTF::CurrentTimeTicksInSeconds);
@@ -161,4 +161,4 @@ class PLATFORM_EXPORT ScrollAnimator : public ScrollAnimatorBase {
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLL_ANIMATOR_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLL_ANIMATOR_H_
diff --git a/chromium/third_party/blink/renderer/platform/scroll/scroll_animator_base.cc b/chromium/third_party/blink/renderer/core/scroll/scroll_animator_base.cc
index db194b61fe3..f14d68871f5 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/scroll_animator_base.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/scroll_animator_base.cc
@@ -28,9 +28,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "third_party/blink/renderer/platform/scroll/scroll_animator_base.h"
+#include "third_party/blink/renderer/core/scroll/scroll_animator_base.h"
-#include "third_party/blink/renderer/platform/scroll/scrollable_area.h"
+#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/platform/scroll/scroll_animator_base.h b/chromium/third_party/blink/renderer/core/scroll/scroll_animator_base.h
index 6f7c3321727..48470ab6789 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/scroll_animator_base.h
+++ b/chromium/third_party/blink/renderer/core/scroll/scroll_animator_base.h
@@ -28,12 +28,12 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLL_ANIMATOR_BASE_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLL_ANIMATOR_BASE_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLL_ANIMATOR_BASE_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLL_ANIMATOR_BASE_H_
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/scroll/scroll_animator_compositor_coordinator.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/platform_export.h"
-#include "third_party/blink/renderer/platform/scroll/scroll_animator_compositor_coordinator.h"
#include "third_party/blink/renderer/platform/scroll/scroll_types.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
@@ -50,7 +50,7 @@ class Scrollbar;
// ScrollAnimatorBase is directly instantiated when scroll animations are
// disabled. In this case, all scrolls are instantaneous.
-class PLATFORM_EXPORT ScrollAnimatorBase
+class CORE_EXPORT ScrollAnimatorBase
: public ScrollAnimatorCompositorCoordinator {
public:
static ScrollAnimatorBase* Create(ScrollableArea*);
@@ -125,4 +125,4 @@ class PLATFORM_EXPORT ScrollAnimatorBase
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLL_ANIMATOR_BASE_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLL_ANIMATOR_BASE_H_
diff --git a/chromium/third_party/blink/renderer/platform/scroll/scroll_animator_compositor_coordinator.cc b/chromium/third_party/blink/renderer/core/scroll/scroll_animator_compositor_coordinator.cc
index 85be672cf90..c462ba8da6b 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/scroll_animator_compositor_coordinator.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/scroll_animator_compositor_coordinator.cc
@@ -2,20 +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/platform/scroll/scroll_animator_compositor_coordinator.h"
+#include "third_party/blink/renderer/core/scroll/scroll_animator_compositor_coordinator.h"
#include <memory>
#include "cc/animation/scroll_offset_animation_curve.h"
#include "cc/layers/picture_layer.h"
#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
#include "third_party/blink/renderer/platform/animation/compositor_animation.h"
#include "third_party/blink/renderer/platform/animation/compositor_animation_host.h"
#include "third_party/blink/renderer/platform/animation/compositor_animation_timeline.h"
#include "third_party/blink/renderer/platform/animation/compositor_keyframe_model.h"
#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
-#include "third_party/blink/renderer/platform/scroll/scrollable_area.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/platform/scroll/scroll_animator_compositor_coordinator.h b/chromium/third_party/blink/renderer/core/scroll/scroll_animator_compositor_coordinator.h
index 949bada88dc..c2dbda10b9c 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/scroll_animator_compositor_coordinator.h
+++ b/chromium/third_party/blink/renderer/core/scroll/scroll_animator_compositor_coordinator.h
@@ -2,21 +2,20 @@
// Use 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_SCROLL_SCROLL_ANIMATOR_COMPOSITOR_COORDINATOR_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLL_ANIMATOR_COMPOSITOR_COORDINATOR_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLL_ANIMATOR_COMPOSITOR_COORDINATOR_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLL_ANIMATOR_COMPOSITOR_COORDINATOR_H_
#include <memory>
#include "base/gtest_prod_util.h"
#include "cc/animation/animation_curve.h"
#include "cc/animation/scroll_offset_animations.h"
+#include "third_party/blink/renderer/core/core_export.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/graphics/compositor_element_id.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/scroll/scroll_types.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/noncopyable.h"
namespace blink {
@@ -31,11 +30,11 @@ class CompositorKeyframeModel;
//
// See ScrollAnimator.h for more information about scroll animations.
-class PLATFORM_EXPORT ScrollAnimatorCompositorCoordinator
+class CORE_EXPORT ScrollAnimatorCompositorCoordinator
: public GarbageCollectedFinalized<ScrollAnimatorCompositorCoordinator>,
private CompositorAnimationClient,
CompositorAnimationDelegate {
- WTF_MAKE_NONCOPYABLE(ScrollAnimatorCompositorCoordinator);
+ DISALLOW_COPY_AND_ASSIGN(ScrollAnimatorCompositorCoordinator);
USING_PRE_FINALIZER(ScrollAnimatorCompositorCoordinator, Dispose);
public:
@@ -196,4 +195,4 @@ class PLATFORM_EXPORT ScrollAnimatorCompositorCoordinator
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLL_ANIMATOR_COMPOSITOR_COORDINATOR_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLL_ANIMATOR_COMPOSITOR_COORDINATOR_H_
diff --git a/chromium/third_party/blink/renderer/platform/mac/scroll_animator_mac.h b/chromium/third_party/blink/renderer/core/scroll/scroll_animator_mac.h
index 289c2c0cdcd..de89825379d 100644
--- a/chromium/third_party/blink/renderer/platform/mac/scroll_animator_mac.h
+++ b/chromium/third_party/blink/renderer/core/scroll/scroll_animator_mac.h
@@ -23,16 +23,16 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_MAC_SCROLL_ANIMATOR_MAC_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MAC_SCROLL_ANIMATOR_MAC_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLL_ANIMATOR_MAC_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLL_ANIMATOR_MAC_H_
#include <memory>
#include "base/single_thread_task_runner.h"
+#include "third_party/blink/renderer/core/scroll/scroll_animator_base.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/heap/handle.h"
-#include "third_party/blink/renderer/platform/scroll/scroll_animator_base.h"
#include "third_party/blink/renderer/platform/timer.h"
#include "third_party/blink/renderer/platform/web_task_runner.h"
#include "third_party/blink/renderer/platform/wtf/retain_ptr.h"
@@ -90,7 +90,7 @@ class Scrollbar;
// ExpansionTransition), scrollbar paint timer, plumbing of scrollbar paint
// invalidations.
-class PLATFORM_EXPORT ScrollAnimatorMac : public ScrollAnimatorBase {
+class CORE_EXPORT ScrollAnimatorMac : public ScrollAnimatorBase {
USING_PRE_FINALIZER(ScrollAnimatorMac, Dispose);
public:
@@ -175,4 +175,4 @@ class PLATFORM_EXPORT ScrollAnimatorMac : public ScrollAnimatorBase {
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MAC_SCROLL_ANIMATOR_MAC_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLL_ANIMATOR_MAC_H_
diff --git a/chromium/third_party/blink/renderer/platform/mac/scroll_animator_mac.mm b/chromium/third_party/blink/renderer/core/scroll/scroll_animator_mac.mm
index 84f2c3ef4e0..29f3f3e7411 100644
--- a/chromium/third_party/blink/renderer/platform/mac/scroll_animator_mac.mm
+++ b/chromium/third_party/blink/renderer/core/scroll/scroll_animator_mac.mm
@@ -23,21 +23,21 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "third_party/blink/renderer/platform/mac/scroll_animator_mac.h"
+#include "third_party/blink/renderer/core/scroll/scroll_animator_mac.h"
#import <AppKit/AppKit.h>
#include <memory>
#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/core/scroll/ns_scroller_imp_details.h"
+#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme_mac.h"
#include "third_party/blink/renderer/platform/animation/timing_function.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/mac/block_exceptions.h"
-#include "third_party/blink/renderer/platform/mac/ns_scroller_imp_details.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
-#include "third_party/blink/renderer/platform/scroll/scrollable_area.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme_mac.h"
#include "third_party/blink/renderer/platform/timer.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
diff --git a/chromium/third_party/blink/renderer/platform/scroll/scroll_animator_test.cc b/chromium/third_party/blink/renderer/core/scroll/scroll_animator_test.cc
index 8a8441ebcc7..14951e6f426 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/scroll_animator_test.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/scroll_animator_test.cc
@@ -25,7 +25,7 @@
// Tests for the ScrollAnimator class.
-#include "third_party/blink/renderer/platform/scroll/scroll_animator.h"
+#include "third_party/blink/renderer/core/scroll/scroll_animator.h"
#include "base/single_thread_task_runner.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -33,12 +33,12 @@
#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_thread.h"
+#include "third_party/blink/renderer/core/scroll/scroll_animator_base.h"
+#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
#include "third_party/blink/renderer/platform/geometry/float_point.h"
#include "third_party/blink/renderer/platform/geometry/int_rect.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
-#include "third_party/blink/renderer/platform/scroll/scroll_animator_base.h"
-#include "third_party/blink/renderer/platform/scroll/scrollable_area.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/platform/scroll/scroll_customization.cc b/chromium/third_party/blink/renderer/core/scroll/scroll_customization.cc
index 203b5b63996..6199fc2f2c9 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/scroll_customization.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/scroll_customization.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/platform/scroll/scroll_customization.h"
+#include "third_party/blink/renderer/core/scroll/scroll_customization.h"
namespace blink {
namespace ScrollCustomization {
diff --git a/chromium/third_party/blink/renderer/platform/scroll/scroll_customization.h b/chromium/third_party/blink/renderer/core/scroll/scroll_customization.h
index dfa89edb213..224ce4263df 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/scroll_customization.h
+++ b/chromium/third_party/blink/renderer/core/scroll/scroll_customization.h
@@ -2,12 +2,12 @@
// Use 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_SCROLL_SCROLL_CUSTOMIZATION_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLL_CUSTOMIZATION_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLL_CUSTOMIZATION_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLL_CUSTOMIZATION_H_
#include <stdint.h>
-#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/core/core_export.h"
namespace blink {
namespace ScrollCustomization {
@@ -25,9 +25,9 @@ constexpr ScrollDirection kScrollDirectionPanY =
constexpr ScrollDirection kScrollDirectionAuto =
kScrollDirectionPanX | kScrollDirectionPanY;
-PLATFORM_EXPORT ScrollDirection GetScrollDirectionFromDeltas(double delta_x,
- double delta_y);
+CORE_EXPORT ScrollDirection GetScrollDirectionFromDeltas(double delta_x,
+ double delta_y);
} // namespace ScrollCustomization
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLL_CUSTOMIZATION_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLL_CUSTOMIZATION_H_
diff --git a/chromium/third_party/blink/renderer/platform/scroll/scroll_state_data.h b/chromium/third_party/blink/renderer/core/scroll/scroll_state_data.h
index db10c3d0d83..a97ba8ab003 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/scroll_state_data.h
+++ b/chromium/third_party/blink/renderer/core/scroll/scroll_state_data.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_PLATFORM_SCROLL_SCROLL_STATE_DATA_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLL_STATE_DATA_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLL_STATE_DATA_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLL_STATE_DATA_H_
#include "cc/input/scroll_state.h"
diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollable_area.cc b/chromium/third_party/blink/renderer/core/scroll/scrollable_area.cc
index 95c660bb23d..64c22032262 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/scrollable_area.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollable_area.cc
@@ -29,27 +29,27 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "third_party/blink/renderer/platform/scroll/scrollable_area.h"
+#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
#include "build/build_config.h"
#include "cc/layers/picture_layer.h"
#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/core/page/chrome_client.h"
+#include "third_party/blink/renderer/core/scroll/programmatic_scroll_animator.h"
+#include "third_party/blink/renderer/core/scroll/scroll_animator_base.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
+#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/instrumentation/tracing/trace_event.h"
-#include "third_party/blink/renderer/platform/platform_chrome_client.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
#include "third_party/blink/renderer/platform/scroll/main_thread_scrolling_reason.h"
-#include "third_party/blink/renderer/platform/scroll/programmatic_scroll_animator.h"
-#include "third_party/blink/renderer/platform/scroll/scroll_animator_base.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h"
-#include "third_party/blink/renderer/platform/scroll/smooth_scroll_sequencer.h"
static const int kPixelsPerLineStep = 40;
static const float kMinFractionToStepWhenPaging = 0.875f;
namespace blink {
-int ScrollableArea::PixelsPerLineStep(PlatformChromeClient* host) {
+int ScrollableArea::PixelsPerLineStep(ChromeClient* host) {
if (!host)
return kPixelsPerLineStep;
return host->WindowToViewportScalar(kPixelsPerLineStep);
diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollable_area.h b/chromium/third_party/blink/renderer/core/scroll/scrollable_area.h
index a517e8a183a..2734d4bf383 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/scrollable_area.h
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollable_area.h
@@ -23,20 +23,19 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLLABLE_AREA_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLLABLE_AREA_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLLABLE_AREA_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLLABLE_AREA_H_
+#include "third_party/blink/renderer/core/core_export.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/geometry/layout_rect.h"
#include "third_party/blink/renderer/platform/graphics/color.h"
#include "third_party/blink/renderer/platform/graphics/compositor_element_id.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
-#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/scroll/scroll_types.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
-#include "third_party/blink/renderer/platform/wtf/noncopyable.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace base {
@@ -51,7 +50,7 @@ class GraphicsLayer;
class LayoutBox;
class LayoutObject;
class PaintLayer;
-class PlatformChromeClient;
+class ChromeClient;
class ProgrammaticScrollAnimator;
class ScrollAnchor;
class ScrollAnimatorBase;
@@ -65,11 +64,11 @@ enum IncludeScrollbarsInRect {
kIncludeScrollbars,
};
-class PLATFORM_EXPORT ScrollableArea : public GarbageCollectedMixin {
- WTF_MAKE_NONCOPYABLE(ScrollableArea);
+class CORE_EXPORT ScrollableArea : public GarbageCollectedMixin {
+ DISALLOW_COPY_AND_ASSIGN(ScrollableArea);
public:
- static int PixelsPerLineStep(PlatformChromeClient*);
+ static int PixelsPerLineStep(ChromeClient*);
static float MinFractionToStepWhenPaging();
int MaxOverlapBetweenPages() const;
@@ -79,7 +78,7 @@ class PLATFORM_EXPORT ScrollableArea : public GarbageCollectedMixin {
return std::isfinite(value) ? value : 0.0;
}
- virtual PlatformChromeClient* GetChromeClient() const { return nullptr; }
+ virtual ChromeClient* GetChromeClient() const { return nullptr; }
virtual SmoothScrollSequencer* GetSmoothScrollSequencer() const {
return nullptr;
@@ -481,4 +480,4 @@ class PLATFORM_EXPORT ScrollableArea : public GarbageCollectedMixin {
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLLABLE_AREA_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLLABLE_AREA_H_
diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollable_area_test.cc b/chromium/third_party/blink/renderer/core/scroll/scrollable_area_test.cc
index 0f47eea58f0..4e97cdc15d8 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/scrollable_area_test.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollable_area_test.cc
@@ -2,19 +2,18 @@
// Use 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/scroll/scrollable_area.h"
+#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
-#include "base/message_loop/message_loop.h"
#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/scroll/scroll_animator_base.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_test_suite.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme_mock.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme_overlay_mock.h"
#include "third_party/blink/renderer/platform/graphics/color.h"
#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
-#include "third_party/blink/renderer/platform/scroll/scroll_animator_base.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_test_suite.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme_mock.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay_mock.h"
#include "third_party/blink/renderer/platform/testing/fake_graphics_layer.h"
#include "third_party/blink/renderer/platform/testing/fake_graphics_layer_client.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
@@ -36,10 +35,7 @@ class ScrollbarThemeWithMockInvalidation : public ScrollbarThemeMock {
} // namespace
-class ScrollableAreaTest : public testing::Test {
- private:
- base::MessageLoop message_loop_;
-};
+class ScrollableAreaTest : public testing::Test {};
TEST_F(ScrollableAreaTest, ScrollAnimatorCurrentPositionShouldBeSync) {
ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollbar.cc b/chromium/third_party/blink/renderer/core/scroll/scrollbar.cc
index 89b50db2f45..b9ef07d8ce9 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/scrollbar.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollbar.cc
@@ -23,25 +23,25 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "third_party/blink/renderer/platform/scroll/scrollbar.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar.h"
#include <algorithm>
#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/platform/web_scrollbar_overlay_color_theme.h"
+#include "third_party/blink/renderer/core/page/chrome_client.h"
+#include "third_party/blink/renderer/core/scroll/scroll_animator_base.h"
+#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
+#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/graphics/paint/cull_rect.h"
-#include "third_party/blink/renderer/platform/platform_chrome_client.h"
-#include "third_party/blink/renderer/platform/scroll/scroll_animator_base.h"
-#include "third_party/blink/renderer/platform/scroll/scrollable_area.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h"
namespace blink {
Scrollbar::Scrollbar(ScrollableArea* scrollable_area,
ScrollbarOrientation orientation,
ScrollbarControlSize control_size,
- PlatformChromeClient* chrome_client,
+ ChromeClient* chrome_client,
ScrollbarTheme* theme)
: scrollable_area_(scrollable_area),
orientation_(orientation),
diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollbar.h b/chromium/third_party/blink/renderer/core/scroll/scrollbar.h
index 780489ec217..e1ccef37b8a 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/scrollbar.h
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollbar.h
@@ -23,9 +23,10 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLLBAR_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLLBAR_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLLBAR_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLLBAR_H_
+#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/graphics/compositor_element_id.h"
#include "third_party/blink/renderer/platform/graphics/paint/display_item.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -38,19 +39,19 @@ namespace blink {
class CullRect;
class GraphicsContext;
class IntRect;
-class PlatformChromeClient;
+class ChromeClient;
class ScrollableArea;
class ScrollbarTheme;
class WebGestureEvent;
class WebMouseEvent;
-class PLATFORM_EXPORT Scrollbar : public GarbageCollectedFinalized<Scrollbar>,
- public DisplayItemClient {
+class CORE_EXPORT Scrollbar : public GarbageCollectedFinalized<Scrollbar>,
+ public DisplayItemClient {
public:
static Scrollbar* Create(ScrollableArea* scrollable_area,
ScrollbarOrientation orientation,
ScrollbarControlSize size,
- PlatformChromeClient* chrome_client) {
+ ChromeClient* chrome_client) {
return new Scrollbar(scrollable_area, orientation, size, chrome_client);
}
@@ -199,7 +200,7 @@ class PLATFORM_EXPORT Scrollbar : public GarbageCollectedFinalized<Scrollbar>,
Scrollbar(ScrollableArea*,
ScrollbarOrientation,
ScrollbarControlSize,
- PlatformChromeClient* = nullptr,
+ ChromeClient* = nullptr,
ScrollbarTheme* = nullptr);
void AutoscrollTimerFired(TimerBase*);
@@ -213,7 +214,7 @@ class PLATFORM_EXPORT Scrollbar : public GarbageCollectedFinalized<Scrollbar>,
ScrollbarOrientation orientation_;
ScrollbarControlSize control_size_;
ScrollbarTheme& theme_;
- Member<PlatformChromeClient> chrome_client_;
+ Member<ChromeClient> chrome_client_;
int visible_size_;
int total_size_;
@@ -247,4 +248,4 @@ class PLATFORM_EXPORT Scrollbar : public GarbageCollectedFinalized<Scrollbar>,
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLLBAR_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLLBAR_H_
diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_layer_delegate.cc b/chromium/third_party/blink/renderer/core/scroll/scrollbar_layer_delegate.cc
index ed9bf154117..2641a2553b2 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_layer_delegate.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollbar_layer_delegate.cc
@@ -2,17 +2,17 @@
// Use 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/scroll/scrollbar_layer_delegate.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_layer_delegate.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/scrollable_area.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_canvas.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_record_builder.h"
#include "third_party/blink/renderer/platform/scroll/scroll_types.h"
-#include "third_party/blink/renderer/platform/scroll/scrollable_area.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h"
#include "ui/gfx/skia_util.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_layer_delegate.h b/chromium/third_party/blink/renderer/core/scroll/scrollbar_layer_delegate.h
index f8d52474cea..77b2b6e3a4a 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_layer_delegate.h
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollbar_layer_delegate.h
@@ -2,16 +2,16 @@
// Use 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_SCROLL_SCROLLBAR_LAYER_DELEGATE_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLLBAR_LAYER_DELEGATE_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLLBAR_LAYER_DELEGATE_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLLBAR_LAYER_DELEGATE_H_
#include <memory>
#include "base/macros.h"
#include "cc/input/scrollbar.h"
#include "cc/paint/paint_canvas.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/platform_export.h"
namespace cc {
class PaintCanvas;
@@ -24,7 +24,7 @@ class ScrollbarTheme;
// Implementation of cc::Scrollbar, providing a delegate to query about
// scrollbar state and to paint the image in the scrollbar.
-class PLATFORM_EXPORT ScrollbarLayerDelegate : public cc::Scrollbar {
+class CORE_EXPORT ScrollbarLayerDelegate : public cc::Scrollbar {
public:
ScrollbarLayerDelegate(blink::Scrollbar& scrollbar,
float device_scale_factor);
@@ -63,4 +63,4 @@ class PLATFORM_EXPORT ScrollbarLayerDelegate : public cc::Scrollbar {
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLLBAR_LAYER_DELEGATE_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLLBAR_LAYER_DELEGATE_H_
diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_test_suite.h b/chromium/third_party/blink/renderer/core/scroll/scrollbar_test_suite.h
index 60224eb7367..500c7ec53eb 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_test_suite.h
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollbar_test_suite.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_PLATFORM_SCROLL_SCROLLBAR_TEST_SUITE_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLLBAR_TEST_SUITE_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLLBAR_TEST_SUITE_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLLBAR_TEST_SUITE_H_
#include <memory>
#include "base/single_thread_task_runner.h"
@@ -11,16 +11,16 @@
#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_thread.h"
+#include "third_party/blink/renderer/core/loader/empty_clients.h"
+#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme_mock.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
-#include "third_party/blink/renderer/platform/platform_chrome_client.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
-#include "third_party/blink/renderer/platform/scroll/scrollable_area.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme_mock.h"
namespace blink {
-class MockPlatformChromeClient : public PlatformChromeClient {
+class MockPlatformChromeClient : public EmptyChromeClient {
public:
MockPlatformChromeClient() : is_popup_(false) {}
@@ -89,7 +89,7 @@ class MockScrollableArea : public GarbageCollectedFinalized<MockScrollableArea>,
return blink::scheduler::GetSingleThreadTaskRunnerForTesting();
}
- PlatformChromeClient* GetChromeClient() const override {
+ ChromeClient* GetChromeClient() const override {
return chrome_client_.Get();
}
diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme.cc b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme.cc
index a3352ccbcc3..80bc7e39309 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme.cc
@@ -23,7 +23,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
#include "base/optional.h"
#include "build/build_config.h"
@@ -31,6 +31,9 @@
#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_mock.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme_overlay_mock.h"
#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"
@@ -39,9 +42,6 @@
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme_mock.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay_mock.h"
#if !defined(OS_MACOSX)
#include "third_party/blink/public/platform/web_theme_engine.h"
diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme.h b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme.h
index d1f4289e463..847d8ef95e5 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme.h
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme.h
@@ -23,15 +23,15 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLLBAR_THEME_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLLBAR_THEME_H_
+#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/scrollbar.h"
#include "third_party/blink/renderer/platform/geometry/int_rect.h"
#include "third_party/blink/renderer/platform/graphics/paint/display_item.h"
-#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/scroll/scroll_types.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar.h"
namespace blink {
@@ -39,8 +39,8 @@ class CullRect;
class GraphicsContext;
class WebMouseEvent;
-class PLATFORM_EXPORT ScrollbarTheme {
- WTF_MAKE_NONCOPYABLE(ScrollbarTheme);
+class CORE_EXPORT ScrollbarTheme {
+ DISALLOW_COPY_AND_ASSIGN(ScrollbarTheme);
USING_FAST_MALLOC(ScrollbarTheme);
public:
diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_android.cc b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_android.cc
index 325abb2a37b..d1a6e11ea2d 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_android.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_android.cc
@@ -23,9 +23,9 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme_overlay.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_aura.cc b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_aura.cc
index 5b4a5f8f79d..0d3b2ee7430 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_aura.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_aura.cc
@@ -28,21 +28,21 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme_aura.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme_aura.h"
#include "build/build_config.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"
+#include "third_party/blink/renderer/core/scroll/scrollbar.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme_overlay.h"
#include "third_party/blink/renderer/platform/geometry/int_rect_outsets.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
#include "third_party/blink/renderer/platform/layout_test_support.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
-#include "third_party/blink/renderer/platform/scroll/scrollable_area.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_aura.h b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_aura.h
index 2742065caeb..61188a174b2 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_aura.h
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_aura.h
@@ -28,15 +28,15 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLLBAR_THEME_AURA_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLLBAR_THEME_AURA_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLLBAR_THEME_AURA_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLLBAR_THEME_AURA_H_
#include "base/gtest_prod_util.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
namespace blink {
-class PLATFORM_EXPORT ScrollbarThemeAura : public ScrollbarTheme {
+class CORE_EXPORT ScrollbarThemeAura : public ScrollbarTheme {
public:
int ScrollbarThickness(ScrollbarControlSize) override;
diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_aura_test.cc b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_aura_test.cc
index 058bf7aaa46..8540f7d046f 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_aura_test.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_aura_test.cc
@@ -2,10 +2,9 @@
// Use 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/scroll/scrollbar_theme_aura.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme_aura.h"
-#include "base/message_loop/message_loop.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_test_suite.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"
namespace blink {
@@ -30,10 +29,7 @@ class ScrollbarThemeAuraButtonOverride final : public ScrollbarThemeAura {
} // namespace
-class ScrollbarThemeAuraTest : public testing::Test {
- private:
- base::MessageLoop message_loop_;
-};
+class ScrollbarThemeAuraTest : public testing::Test {};
TEST_F(ScrollbarThemeAuraTest, ButtonSizeHorizontal) {
ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_mac.h b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.h
index 4259a28587e..a67a4e59bcc 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_mac.h
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.h
@@ -23,13 +23,14 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLLBAR_THEME_MAC_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLLBAR_THEME_MAC_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLLBAR_THEME_MAC_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLLBAR_THEME_MAC_H_
#include <AppKit/AppKit.h>
-#include "third_party/blink/renderer/platform/mac/ns_scroller_imp_details.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h"
+#include "third_party/blink/renderer/core/scroll/ns_scroller_imp_details.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
+#include "third_party/blink/renderer/platform/scroll/web_scrollbar_theme_client.h"
typedef id ScrollbarPainter;
@@ -37,18 +38,14 @@ namespace blink {
class Pattern;
-class PLATFORM_EXPORT ScrollbarThemeMac : public ScrollbarTheme {
+class PLATFORM_EXPORT ScrollbarThemeMac : public ScrollbarTheme,
+ public WebScrollbarThemeClient {
public:
+ ScrollbarThemeMac();
~ScrollbarThemeMac() override;
void RegisterScrollbar(Scrollbar&) override;
void UnregisterScrollbar(Scrollbar&) override;
- void PreferencesChanged(float initial_button_delay,
- float autoscroll_button_delay,
- NSScrollerStyle preferred_scroller_style,
- bool redraw,
- WebScrollbarButtonsPlacement,
- bool jump_on_track_click);
bool SupportsControlTints() const override { return true; }
@@ -97,6 +94,8 @@ class PLATFORM_EXPORT ScrollbarThemeMac : public ScrollbarTheme {
float ThumbOpacity(const Scrollbar&) const override;
+ void PreferencesChanged() override;
+
static NSScrollerStyle RecommendedScrollerStyle();
static void SetJumpOnTrackClick(bool);
@@ -131,6 +130,6 @@ class PLATFORM_EXPORT ScrollbarThemeMac : public ScrollbarTheme {
scoped_refptr<Pattern> overhang_pattern_;
};
-}
+} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLLBAR_THEME_MAC_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLLBAR_THEME_MAC_H_
diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_mac.mm b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.mm
index d15d6f2630f..f67fa198ed0 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_mac.mm
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.mm
@@ -23,21 +23,22 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme_mac.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme_mac.h"
#include <Carbon/Carbon.h>
#include "skia/ext/skia_utils_mac.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"
+#include "third_party/blink/renderer/core/scroll/scroll_animator_mac.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context_state_saver.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
#include "third_party/blink/renderer/platform/mac/color_mac.h"
#include "third_party/blink/renderer/platform/mac/local_current_graphics_context.h"
-#include "third_party/blink/renderer/platform/mac/ns_scroller_imp_details.h"
-#include "third_party/blink/renderer/platform/mac/scroll_animator_mac.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/retain_ptr.h"
@@ -103,11 +104,6 @@ static ScrollbarSet& GetScrollbarSet() {
return set;
}
-static float g_initial_button_delay = 0.5f;
-static float g_autoscroll_button_delay = 0.05f;
-static NSScrollerStyle g_preferred_scroller_style = NSScrollerStyleLegacy;
-static bool g_jump_on_track_click = false;
-
typedef PersistentHeapHashMap<WeakMember<Scrollbar>,
RetainPtr<BlinkScrollbarObserver>>
ScrollbarPainterMap;
@@ -126,6 +122,10 @@ static bool SupportsExpandedScrollbars() {
return global_supports_expanded_scrollbars;
}
+ScrollbarThemeMac::ScrollbarThemeMac() {
+ WebScrollbarTheme::RegisterClient(*this);
+}
+
ScrollbarTheme& ScrollbarTheme::NativeTheme() {
DEFINE_STATIC_LOCAL(ScrollbarThemeMac, overlay_theme, ());
return overlay_theme;
@@ -144,37 +144,19 @@ bool ScrollbarThemeMac::ShouldCenterOnThumb(const Scrollbar& scrollbar,
const WebMouseEvent& event) {
bool alt_key_pressed = event.GetModifiers() & WebInputEvent::kAltKey;
return (event.button == WebPointerProperties::Button::kLeft) &&
- (g_jump_on_track_click != alt_key_pressed);
-}
-
-ScrollbarThemeMac::~ScrollbarThemeMac() {}
-
-void ScrollbarThemeMac::PreferencesChanged(
- float initial_button_delay,
- float autoscroll_button_delay,
- NSScrollerStyle preferred_scroller_style,
- bool redraw,
- WebScrollbarButtonsPlacement button_placement,
- bool jump_on_track_click) {
- UpdateButtonPlacement(button_placement);
- g_initial_button_delay = initial_button_delay;
- g_autoscroll_button_delay = autoscroll_button_delay;
- g_preferred_scroller_style = preferred_scroller_style;
- g_jump_on_track_click = jump_on_track_click;
- if (redraw && !GetScrollbarSet().IsEmpty()) {
- for (const auto& scrollbar : GetScrollbarSet()) {
- scrollbar->StyleChanged();
- scrollbar->SetNeedsPaintInvalidation(kAllParts);
- }
- }
+ (WebScrollbarTheme::JumpOnTrackClick() != alt_key_pressed);
+}
+
+ScrollbarThemeMac::~ScrollbarThemeMac() {
+ WebScrollbarTheme::UnregisterClient(*this);
}
TimeDelta ScrollbarThemeMac::InitialAutoscrollTimerDelay() {
- return TimeDelta::FromSecondsD(g_initial_button_delay);
+ return TimeDelta::FromSecondsD(WebScrollbarTheme::InitialButtonDelay());
}
TimeDelta ScrollbarThemeMac::AutoscrollTimerDelay() {
- return TimeDelta::FromSecondsD(g_autoscroll_button_delay);
+ return TimeDelta::FromSecondsD(WebScrollbarTheme::AutoscrollButtonDelay());
}
bool ScrollbarThemeMac::ShouldDragDocumentInsteadOfThumb(
@@ -419,11 +401,19 @@ float ScrollbarThemeMac::ThumbOpacity(const Scrollbar& scrollbar) const {
return [scrollbar_painter knobAlpha];
}
+void ScrollbarThemeMac::PreferencesChanged() {
+ for (const auto& scrollbar : GetScrollbarSet()) {
+ scrollbar->StyleChanged();
+ scrollbar->SetNeedsPaintInvalidation(kAllParts);
+ }
+}
+
// static
NSScrollerStyle ScrollbarThemeMac::RecommendedScrollerStyle() {
if (RuntimeEnabledFeatures::OverlayScrollbarsEnabled())
return NSScrollerStyleOverlay;
- return g_preferred_scroller_style;
+ return static_cast<NSScrollerStyle>(
+ WebScrollbarTheme::PreferredScrollerStyle());
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_mock.cc b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_mock.cc
index 73b2b3536c2..8922c77d531 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_mock.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_mock.cc
@@ -23,12 +23,12 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme_mock.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme_mock.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_mock.h b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_mock.h
index e463fdf755e..9f6e237ae0c 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_mock.h
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_mock.h
@@ -23,16 +23,16 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLLBAR_THEME_MOCK_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLLBAR_THEME_MOCK_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLLBAR_THEME_MOCK_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLLBAR_THEME_MOCK_H_
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
namespace blink {
// Scrollbar theme used in image snapshots, to eliminate appearance differences
// between platforms.
-class PLATFORM_EXPORT ScrollbarThemeMock : public ScrollbarTheme {
+class CORE_EXPORT ScrollbarThemeMock : public ScrollbarTheme {
public:
int ScrollbarThickness(ScrollbarControlSize = kRegularScrollbar) override;
bool UsesOverlayScrollbars() const override;
@@ -69,4 +69,4 @@ class PLATFORM_EXPORT ScrollbarThemeMock : public ScrollbarTheme {
};
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLLBAR_THEME_MOCK_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLLBAR_THEME_MOCK_H_
diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay.cc b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_overlay.cc
index 33121af31c5..030453c17ba 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_overlay.cc
@@ -23,14 +23,14 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme_overlay.h"
#include "third_party/blink/public/platform/platform.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/scrollbar.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar.h"
#include "third_party/blink/renderer/platform/transforms/transformation_matrix.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay.h b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_overlay.h
index b36d9ccc594..a3595feacba 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay.h
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_overlay.h
@@ -23,17 +23,17 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLLBAR_THEME_OVERLAY_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLLBAR_THEME_OVERLAY_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLLBAR_THEME_OVERLAY_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLLBAR_THEME_OVERLAY_H_
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
#include "third_party/blink/renderer/platform/graphics/color.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h"
namespace blink {
// This scrollbar theme is used to get overlay scrollbar for platforms other
// than Mac. Mac's overlay scrollbars are in ScrollbarThemeMac*.
-class PLATFORM_EXPORT ScrollbarThemeOverlay : public ScrollbarTheme {
+class CORE_EXPORT ScrollbarThemeOverlay : public ScrollbarTheme {
public:
enum HitTestBehavior { kAllowHitTest, kDisallowHitTest };
diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay_mock.h b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_overlay_mock.h
index 0a38a31ca9c..342bae0200f 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay_mock.h
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_overlay_mock.h
@@ -28,14 +28,14 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLLBAR_THEME_OVERLAY_MOCK_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLLBAR_THEME_OVERLAY_MOCK_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLLBAR_THEME_OVERLAY_MOCK_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLLBAR_THEME_OVERLAY_MOCK_H_
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme_overlay.h"
namespace blink {
-class PLATFORM_EXPORT ScrollbarThemeOverlayMock : public ScrollbarThemeOverlay {
+class CORE_EXPORT ScrollbarThemeOverlayMock : public ScrollbarThemeOverlay {
public:
ScrollbarThemeOverlayMock()
: ScrollbarThemeOverlay(3, 4, kDisallowHitTest, Color(128, 128, 128)) {}
@@ -68,4 +68,4 @@ class PLATFORM_EXPORT ScrollbarThemeOverlayMock : public ScrollbarThemeOverlay {
};
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLLBAR_THEME_OVERLAY_MOCK_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLLBAR_THEME_OVERLAY_MOCK_H_
diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay_test.cc b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_overlay_test.cc
index f711b205e3e..8a387729a71 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay_test.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_overlay_test.cc
@@ -2,10 +2,9 @@
// Use 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/scroll/scrollbar_theme_overlay.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme_overlay.h"
-#include "base/message_loop/message_loop.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_test_suite.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"
namespace blink {
@@ -13,10 +12,7 @@ namespace blink {
using testing::NiceMock;
using testing::Return;
-class ScrollbarThemeOverlayTest : public testing::Test {
- private:
- base::MessageLoop message_loop_;
-};
+class ScrollbarThemeOverlayTest : public testing::Test {};
TEST_F(ScrollbarThemeOverlayTest, PaintInvalidation) {
ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
diff --git a/chromium/third_party/blink/renderer/platform/scroll/smooth_scroll_sequencer.cc b/chromium/third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.cc
index 31fce84c37a..0ed920fd269 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/smooth_scroll_sequencer.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.cc
@@ -2,10 +2,10 @@
// Use 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/scroll/smooth_scroll_sequencer.h"
+#include "third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.h"
-#include "third_party/blink/renderer/platform/scroll/programmatic_scroll_animator.h"
-#include "third_party/blink/renderer/platform/scroll/scrollable_area.h"
+#include "third_party/blink/renderer/core/scroll/programmatic_scroll_animator.h"
+#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/platform/scroll/smooth_scroll_sequencer.h b/chromium/third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.h
index 0af018e513c..a5d028e4b7f 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/smooth_scroll_sequencer.h
+++ b/chromium/third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.h
@@ -1,10 +1,12 @@
// 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.
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SMOOTH_SCROLL_SEQUENCER_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SMOOTH_SCROLL_SEQUENCER_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SMOOTH_SCROLL_SEQUENCER_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SMOOTH_SCROLL_SEQUENCER_H_
#include <utility>
+
+#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/scroll/scroll_types.h"
@@ -37,7 +39,7 @@ struct SequencedScroll final : public GarbageCollected<SequencedScroll> {
// A sequencer that queues the nested scrollers from inside to outside,
// so that they can be animated from outside to inside when smooth scroll
// is called.
-class PLATFORM_EXPORT SmoothScrollSequencer final
+class CORE_EXPORT SmoothScrollSequencer final
: public GarbageCollected<SmoothScrollSequencer> {
public:
SmoothScrollSequencer() = default;
@@ -61,4 +63,4 @@ class PLATFORM_EXPORT SmoothScrollSequencer final
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SMOOTH_SCROLL_SEQUENCER_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SMOOTH_SCROLL_SEQUENCER_H_
diff --git a/chromium/third_party/blink/renderer/platform/scroll/web_scroll_into_view_params.cc b/chromium/third_party/blink/renderer/core/scroll/web_scroll_into_view_params.cc
index d766d5c70ea..d766d5c70ea 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/web_scroll_into_view_params.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/web_scroll_into_view_params.cc
diff --git a/chromium/third_party/blink/renderer/platform/scroll/web_scrollbar_theme.mm b/chromium/third_party/blink/renderer/core/scroll/web_scrollbar_theme.mm
index d55393282ae..86a570a40d9 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/web_scrollbar_theme.mm
+++ b/chromium/third_party/blink/renderer/core/scroll/web_scrollbar_theme.mm
@@ -32,8 +32,8 @@
#import <AppKit/AppKit.h>
-#include "third_party/blink/renderer/platform/mac/ns_scroller_imp_details.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme_mac.h"
+#include "third_party/blink/renderer/core/scroll/ns_scroller_imp_details.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme_mac.h"
namespace blink {
@@ -44,21 +44,58 @@ static_assert(static_cast<NSScrollerStyle>(kScrollerStyleOverlay) ==
NSScrollerStyleOverlay,
"ScrollerStyleOverlay must match NSScrollerStyleOverlay");
+typedef WTF::HashSet<WebScrollbarThemeClient*> ClientSet;
+
+static ClientSet& GetClientSet() {
+ DEFINE_STATIC_LOCAL(ClientSet, set, ());
+ return set;
+}
+
+static float s_initial_button_delay = 0.5f;
+static float s_autoscroll_button_delay = 0.05f;
+static ScrollerStyle s_preferred_scroller_style = kScrollerStyleLegacy;
+static bool s_jump_on_track_click = false;
+
void WebScrollbarTheme::UpdateScrollbarsWithNSDefaults(
float initial_button_delay,
float autoscroll_button_delay,
ScrollerStyle preferred_scroller_style,
bool redraw,
- WebScrollbarButtonsPlacement button_placement,
bool jump_on_track_click) {
- ScrollbarTheme& theme = ScrollbarTheme::DeprecatedStaticGetTheme();
- if (theme.IsMockTheme())
- return;
-
- static_cast<ScrollbarThemeMac&>(theme).PreferencesChanged(
- initial_button_delay, autoscroll_button_delay,
- static_cast<NSScrollerStyle>(preferred_scroller_style), redraw,
- button_placement, jump_on_track_click);
+ s_initial_button_delay = initial_button_delay;
+ s_autoscroll_button_delay = autoscroll_button_delay;
+ s_preferred_scroller_style = preferred_scroller_style;
+ s_jump_on_track_click = jump_on_track_click;
+
+ if (redraw && !GetClientSet().IsEmpty()) {
+ for (auto* client : GetClientSet()) {
+ client->PreferencesChanged();
+ }
+ }
+}
+
+float WebScrollbarTheme::InitialButtonDelay() {
+ return s_initial_button_delay;
+}
+
+float WebScrollbarTheme::AutoscrollButtonDelay() {
+ return s_autoscroll_button_delay;
+}
+
+ScrollerStyle WebScrollbarTheme::PreferredScrollerStyle() {
+ return s_preferred_scroller_style;
+}
+
+bool WebScrollbarTheme::JumpOnTrackClick() {
+ return s_jump_on_track_click;
+}
+
+void WebScrollbarTheme::RegisterClient(WebScrollbarThemeClient& client) {
+ GetClientSet().insert(&client);
+}
+
+void WebScrollbarTheme::UnregisterClient(WebScrollbarThemeClient& client) {
+ GetClientSet().erase(&client);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/streams/BUILD.gn b/chromium/third_party/blink/renderer/core/streams/BUILD.gn
index 6aa0055d442..e57e413c52e 100644
--- a/chromium/third_party/blink/renderer/core/streams/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/streams/BUILD.gn
@@ -9,6 +9,11 @@ blink_core_sources("streams") {
"readable_stream_default_controller_wrapper.h",
"readable_stream_operations.cc",
"readable_stream_operations.h",
+ "transform_stream.cc",
+ "transform_stream.h",
+ "transform_stream_default_controller.cc",
+ "transform_stream_default_controller.h",
+ "transform_stream_transformer.h",
"underlying_source_base.cc",
"underlying_source_base.h",
]
diff --git a/chromium/third_party/blink/renderer/core/streams/ReadableStream.js b/chromium/third_party/blink/renderer/core/streams/ReadableStream.js
index a5ec08c1abf..159462bf22b 100644
--- a/chromium/third_party/blink/renderer/core/streams/ReadableStream.js
+++ b/chromium/third_party/blink/renderer/core/streams/ReadableStream.js
@@ -147,9 +147,9 @@
}
InitializeReadableStream(this);
- const type = underlyingSource.type;
const size = strategy.size;
let highWaterMark = strategy.highWaterMark;
+ const type = underlyingSource.type;
const typeString = String(type);
if (typeString === 'bytes') {
@@ -160,12 +160,13 @@
throw new RangeError(streamErrors.invalidType);
}
+ const sizeAlgorithm = MakeSizeAlgorithmFromSizeFunction(size);
+
if (highWaterMark === undefined) {
highWaterMark = 1;
}
highWaterMark = ValidateAndNormalizeHighWaterMark(highWaterMark);
- const sizeAlgorithm = MakeSizeAlgorithmFromSizeFunction(size);
SetUpReadableStreamDefaultControllerFromUnderlyingSource(
this, underlyingSource, highWaterMark, sizeAlgorithm,
enableBlinkLockNotifications);
@@ -277,6 +278,7 @@
let shuttingDown = false;
const promise = v8.createPromise();
let reading = false;
+ let lastWrite;
if (checkInitialState()) {
// Need to detect closing and error when we are not reading.
@@ -340,21 +342,18 @@
return;
}
reading = true;
- // TODO(ricea): Delay reads heuristically when desiredSize is low.
thenPromise(
ReadableStreamDefaultReaderRead(reader), readFulfilled, readRejected);
}
function readFulfilled({value, done}) {
reading = false;
- if (shuttingDown) {
- return;
- }
if (done) {
readableClosed();
return;
}
const write = binding.WritableStreamDefaultWriterWrite(writer, value);
+ lastWrite = write;
thenPromise(write, undefined, writableError);
pump();
}
@@ -421,7 +420,13 @@
return;
}
shuttingDown = true;
- const p = applyFunction(action, undefined, args);
+ let p;
+ if (shouldWriteQueuedChunks()) {
+ p = thenPromise(writeQueuedChunks(),
+ () => applyFunction(action, undefined, args));
+ } else {
+ p = applyFunction(action, undefined, args);
+ }
thenPromise(
p, () => finalize(originalError, errorGiven),
newError => finalize(newError, true));
@@ -432,7 +437,11 @@
return;
}
shuttingDown = true;
- finalize(error, errorGiven);
+ if (shouldWriteQueuedChunks()) {
+ thenPromise(writeQueuedChunks(), () => finalize(error, errorGiven));
+ } else {
+ finalize(error, errorGiven);
+ }
}
function finalize(error, errorGiven) {
@@ -445,6 +454,22 @@
}
}
+ function shouldWriteQueuedChunks() {
+ return binding.isWritableStreamWritable(dest) &&
+ !binding.WritableStreamCloseQueuedOrInFlight(dest);
+ }
+
+ function writeQueuedChunks() {
+ if (lastWrite) {
+ // "Wait until every chunk that has been read has been written (i.e.
+ // the corresponding promises have settled)"
+ // This implies that we behave the same whether the promise fulfills or
+ // rejects.
+ return thenPromise(lastWrite, () => undefined, () => undefined);
+ }
+ return Promise_resolve(undefined);
+ }
+
return promise;
}
@@ -590,9 +615,9 @@
// Abstract Operations Used By Controllers
//
- function ReadableStreamAddReadRequest(stream) {
+ function ReadableStreamAddReadRequest(stream, forAuthorCode) {
const promise = v8.createPromise();
- stream[_reader][_readRequests].push(promise);
+ stream[_reader][_readRequests].push({promise, forAuthorCode});
return promise;
}
@@ -625,13 +650,27 @@
if (IsReadableStreamDefaultReader(reader) === true) {
reader[_readRequests].forEach(
request =>
- resolvePromise(request, CreateIterResultObject(undefined, true)));
+ resolvePromise(
+ request.promise,
+ ReadableStreamCreateReadResult(undefined, true,
+ request.forAuthorCode)));
reader[_readRequests] = new binding.SimpleQueue();
}
resolvePromise(reader[_closedPromise], undefined);
}
+ function ReadableStreamCreateReadResult(value, done, forAuthorCode) {
+ // assert(typeof done === 'boolean', 'Type(_done_) is Boolean.');
+ if (forAuthorCode) {
+ return {value, done};
+ }
+ const obj = ObjectCreate(null);
+ obj.value = value;
+ obj.done = done;
+ return obj;
+ }
+
function ReadableStreamError(stream, e) {
ReadableStreamSetState(stream, STATE_ERRORED);
stream[_storedError] = e;
@@ -642,7 +681,8 @@
}
if (IsReadableStreamDefaultReader(reader) === true) {
- reader[_readRequests].forEach(request => rejectPromise(request, e));
+ reader[_readRequests].forEach(request =>
+ rejectPromise(request.promise, e));
reader[_readRequests] = new binding.SimpleQueue();
}
@@ -652,7 +692,9 @@
function ReadableStreamFulfillReadRequest(stream, chunk, done) {
const readRequest = stream[_reader][_readRequests].shift();
- resolvePromise(readRequest, CreateIterResultObject(chunk, done));
+ resolvePromise(readRequest.promise,
+ ReadableStreamCreateReadResult(chunk, done,
+ readRequest.forAuthorCode));
}
function ReadableStreamGetNumReadRequests(stream) {
@@ -708,7 +750,7 @@
return Promise_reject(new TypeError(errReadReleasedReader));
}
- return ReadableStreamDefaultReaderRead(this);
+ return ReadableStreamDefaultReaderRead(this, true);
}
releaseLock() {
@@ -796,19 +838,21 @@
reader[_ownerReadableStream] = undefined;
}
- function ReadableStreamDefaultReaderRead(reader) {
+ function ReadableStreamDefaultReaderRead(reader, forAuthorCode = false) {
const stream = reader[_ownerReadableStream];
stream[_readableStreamBits] |= DISTURBED;
switch (ReadableStreamGetState(stream)) {
case STATE_CLOSED:
- return Promise_resolve(CreateIterResultObject(undefined, true));
+ return Promise_resolve(ReadableStreamCreateReadResult(undefined, true,
+ forAuthorCode));
case STATE_ERRORED:
return Promise_reject(stream[_storedError]);
default:
- return ReadableStreamDefaultControllerPull(stream[_controller]);
+ return ReadableStreamDefaultControllerPull(stream[_controller],
+ forAuthorCode);
}
}
@@ -888,7 +932,7 @@
}
// [[PullSteps]] in the standard.
- function ReadableStreamDefaultControllerPull(controller) {
+ function ReadableStreamDefaultControllerPull(controller, forAuthorCode) {
const stream = controller[_controlledReadableStream];
if (controller[_queue].length > 0) {
@@ -902,10 +946,11 @@
ReadableStreamDefaultControllerCallPullIfNeeded(controller);
}
- return Promise_resolve(CreateIterResultObject(chunk, false));
+ return Promise_resolve(ReadableStreamCreateReadResult(chunk, false,
+ forAuthorCode));
}
- const pendingPromise = ReadableStreamAddReadRequest(stream);
+ const pendingPromise = ReadableStreamAddReadRequest(stream, forAuthorCode);
ReadableStreamDefaultControllerCallPullIfNeeded(controller);
return pendingPromise;
}
@@ -963,6 +1008,7 @@
const desiredSize =
ReadableStreamDefaultControllerGetDesiredSize(controller);
+ // assert(desiredSize !== null, '_desiredSize_ is not *null*.');
return desiredSize > 0;
}
@@ -1124,14 +1170,6 @@
}
//
- // Other helpers
- //
-
- function CreateIterResultObject(value, done) {
- return {value, done};
- }
-
- //
// Accessors used by TransformStream
//
@@ -1147,6 +1185,14 @@
return stream[_storedError];
}
+ // TODO(ricea): Remove this once the C++ code switches to calling
+ // CreateReadableStream().
+ function createReadableStreamWithExternalController(underlyingSource,
+ strategy) {
+ return new ReadableStream(
+ underlyingSource, strategy, createWithExternalControllerSentinel);
+ }
+
//
// Additions to the global
//
@@ -1158,49 +1204,40 @@
writable: true
});
- //
- // Exports to Blink
- //
-
- binding.AcquireReadableStreamDefaultReader =
- AcquireReadableStreamDefaultReader;
- binding.IsReadableStream = IsReadableStream;
- binding.IsReadableStreamDisturbed = IsReadableStreamDisturbed;
- binding.IsReadableStreamLocked = IsReadableStreamLocked;
- binding.IsReadableStreamReadable = IsReadableStreamReadable;
- binding.IsReadableStreamClosed = IsReadableStreamClosed;
- binding.IsReadableStreamErrored = IsReadableStreamErrored;
- binding.IsReadableStreamDefaultReader = IsReadableStreamDefaultReader;
- binding.ReadableStreamDefaultReaderRead = ReadableStreamDefaultReaderRead;
- binding.ReadableStreamTee = ReadableStreamTee;
-
- binding.ReadableStreamDefaultControllerClose =
- ReadableStreamDefaultControllerClose;
- binding.ReadableStreamDefaultControllerGetDesiredSize =
- ReadableStreamDefaultControllerGetDesiredSize;
- binding.ReadableStreamDefaultControllerEnqueue =
- ReadableStreamDefaultControllerEnqueue;
- binding.ReadableStreamDefaultControllerError =
- ReadableStreamDefaultControllerError;
- // TODO(ricea): Remove this once the C++ code switches to calling
- // CreateReadableStream().
- binding.createReadableStreamWithExternalController =
- (underlyingSource, strategy) => {
- return new ReadableStream(
- underlyingSource, strategy, createWithExternalControllerSentinel);
- };
-
- //
- // Exports to TransformStream
- //
- binding.CreateReadableStream = CreateReadableStream;
- binding.ReadableStreamDefaultControllerCanCloseOrEnqueue =
- ReadableStreamDefaultControllerCanCloseOrEnqueue;
- binding.ReadableStreamDefaultControllerHasBackpressure =
- ReadableStreamDefaultControllerHasBackpressure;
-
- binding.getReadableStreamEnqueueError = getReadableStreamEnqueueError;
- binding.getReadableStreamController = getReadableStreamController;
- binding.getReadableStreamStoredError = getReadableStreamStoredError;
+ Object.assign(binding, {
+ //
+ // ReadableStream exports to Blink C++
+ //
+ AcquireReadableStreamDefaultReader,
+ createReadableStreamWithExternalController,
+ IsReadableStream,
+ IsReadableStreamDisturbed,
+ IsReadableStreamLocked,
+ IsReadableStreamReadable,
+ IsReadableStreamClosed,
+ IsReadableStreamErrored,
+ IsReadableStreamDefaultReader,
+ ReadableStreamDefaultReaderRead,
+ ReadableStreamTee,
+
+ //
+ // Controller exports to Blink C++
+ //
+ ReadableStreamDefaultControllerClose,
+ ReadableStreamDefaultControllerGetDesiredSize,
+ ReadableStreamDefaultControllerEnqueue,
+ ReadableStreamDefaultControllerError,
+
+ //
+ // Exports to TransformStream
+ //
+ CreateReadableStream,
+ ReadableStreamDefaultControllerCanCloseOrEnqueue,
+ ReadableStreamDefaultControllerHasBackpressure,
+
+ getReadableStreamEnqueueError,
+ getReadableStreamController,
+ getReadableStreamStoredError,
+ });
});
diff --git a/chromium/third_party/blink/renderer/core/streams/TransformStream.js b/chromium/third_party/blink/renderer/core/streams/TransformStream.js
index fc8f9695ce9..e8ec397c34c 100644
--- a/chromium/third_party/blink/renderer/core/streams/TransformStream.js
+++ b/chromium/third_party/blink/renderer/core/streams/TransformStream.js
@@ -23,7 +23,12 @@
const _writable = v8.createPrivateSymbol('[[writable]]');
const _controlledTransformStream =
v8.createPrivateSymbol('[[controlledTransformStream]]');
+
+ // Unlike the version in the standard, the controller is passed to this.
const _flushAlgorithm = v8.createPrivateSymbol('[[flushAlgorithm]]');
+
+ // Unlike the version in the standard, the controller is passed in as the
+ // second argument.
const _transformAlgorithm = v8.createPrivateSymbol('[[transformAlgorithm]]');
// Javascript functions. It is important to use these copies, as the ones on
@@ -45,7 +50,7 @@
const {
hasOwnPropertyNoThrow,
resolvePromise,
- CreateAlgorithmFromUnderlyingMethodPassingController,
+ CreateAlgorithmFromUnderlyingMethod,
CallOrNoop1,
MakeSizeAlgorithmFromSizeFunction,
PromiseCall2,
@@ -66,31 +71,33 @@
useCounted = true;
}
- // readable and writableType are extension points for future byte streams.
- const readableType = transformer.readableType;
- if (readableType !== undefined) {
- throw new RangeError(streamErrors.invalidType);
- }
+ const writableSizeFunction = writableStrategy.size;
+ let writableHighWaterMark = writableStrategy.highWaterMark;
+ const readableSizeFunction = readableStrategy.size;
+ let readableHighWaterMark = readableStrategy.highWaterMark;
+
+ // readable and writableType are extension points for future byte streams.
const writableType = transformer.writableType;
if (writableType !== undefined) {
throw new RangeError(streamErrors.invalidType);
}
- const writableSizeFunction = writableStrategy.size;
const writableSizeAlgorithm =
MakeSizeAlgorithmFromSizeFunction(writableSizeFunction);
- let writableHighWaterMark = writableStrategy.highWaterMark;
if (writableHighWaterMark === undefined) {
writableHighWaterMark = 1;
}
writableHighWaterMark =
ValidateAndNormalizeHighWaterMark(writableHighWaterMark);
- const readableSizeFunction = readableStrategy.size;
+ const readableType = transformer.readableType;
+ if (readableType !== undefined) {
+ throw new RangeError(streamErrors.invalidType);
+ }
+
const readableSizeAlgorithm =
MakeSizeAlgorithmFromSizeFunction(readableSizeFunction);
- let readableHighWaterMark = readableStrategy.highWaterMark;
if (readableHighWaterMark === undefined) {
readableHighWaterMark = 0;
}
@@ -127,6 +134,8 @@
const TransformStream_prototype = TransformStream.prototype;
+ // The controller is passed to |transformAlgorithm| and |flushAlgorithm|,
+ // unlike in the standard.
function CreateTransformStream(
startAlgorithm, transformAlgorithm, flushAlgorithm, writableHighWaterMark,
writableSizeAlgorithm, readableHighWaterMark, readableSizeAlgorithm) {
@@ -207,6 +216,8 @@
}
function TransformStreamErrorWritableAndUnblockWrite(stream, e) {
+ TransformStreamDefaultControllerClearAlgorithms(
+ stream[_transformStreamController]);
binding.WritableStreamDefaultControllerErrorIfNeeded(
binding.getWritableStreamController(stream[_writable]), e);
@@ -300,14 +311,8 @@
if (typeof transformMethod !== 'function') {
throw new TypeError('transformer.transform is not a function');
}
- transformAlgorithm = chunk => {
- const transformPromise =
- PromiseCall2(transformMethod, transformer, chunk, controller);
- return thenPromise(transformPromise, undefined, e => {
- TransformStreamError(stream, e);
- throw e;
- });
- };
+ transformAlgorithm = chunk =>
+ PromiseCall2(transformMethod, transformer, chunk, controller);
} else {
transformAlgorithm = chunk => {
try {
@@ -318,12 +323,17 @@
}
};
}
- const flushAlgorithm = CreateAlgorithmFromUnderlyingMethodPassingController(
- transformer, 'flush', 0, controller, 'transformer.flush');
+ const flushAlgorithm = CreateAlgorithmFromUnderlyingMethod(
+ transformer, 'flush', 1, 'transformer.flush');
SetUpTransformStreamDefaultController(
stream, controller, transformAlgorithm, flushAlgorithm);
}
+ function TransformStreamDefaultControllerClearAlgorithms(controller) {
+ controller[_transformAlgorithm] = undefined;
+ controller[_flushAlgorithm] = undefined;
+ }
+
function TransformStreamDefaultControllerEnqueue(controller, chunk) {
const stream = controller[_controlledTransformStream];
const readableController =
@@ -353,6 +363,14 @@
TransformStreamError(controller[_controlledTransformStream], e);
}
+ function TransformStreamDefaultControllerPerformTransform(controller, chunk) {
+ const transformPromise = controller[_transformAlgorithm](chunk, controller);
+ return thenPromise(transformPromise, undefined, r => {
+ TransformStreamError(controller[_controlledTransformStream], r);
+ throw r;
+ });
+ }
+
function TransformStreamDefaultControllerTerminate(controller) {
const stream = controller[_controlledTransformStream];
const readableController =
@@ -388,11 +406,12 @@
// assert(binding.isWritableStreamWritable(writable),
// `state is "writable"`);
- return controller[_transformAlgorithm](chunk);
+ return TransformStreamDefaultControllerPerformTransform(controller,
+ chunk);
});
}
- return controller[_transformAlgorithm](chunk);
+ return TransformStreamDefaultControllerPerformTransform(controller, chunk);
}
function TransformStreamDefaultSinkAbortAlgorithm(stream, reason) {
@@ -402,8 +421,9 @@
function TransformStreamDefaultSinkCloseAlgorithm(stream) {
const readable = stream[_readable];
-
- const flushPromise = stream[_transformStreamController][_flushAlgorithm]();
+ const controller = stream[_transformStreamController];
+ const flushPromise = controller[_flushAlgorithm](controller);
+ TransformStreamDefaultControllerClearAlgorithms(controller);
return thenPromise(
flushPromise,
@@ -435,6 +455,22 @@
return stream[_backpressureChangePromise];
}
+ // A wrapper for CreateTransformStream() with only the arguments that
+ // blink::TransformStream needs. |transformAlgorithm| and |flushAlgorithm| are
+ // passed the controller, unlike in the standard.
+ function createTransformStreamSimple(transformAlgorithm, flushAlgorithm) {
+ return CreateTransformStream(() => Promise_resolve(),
+ transformAlgorithm, flushAlgorithm);
+ }
+
+ function getTransformStreamReadable(stream) {
+ return stream[_readable];
+ }
+
+ function getTransformStreamWritable(stream) {
+ return stream[_writable];
+ }
+
//
// Additions to the global object
//
@@ -449,5 +485,10 @@
//
// Exports to Blink
//
- binding.CreateTransformStream = CreateTransformStream;
+ Object.assign(binding, {
+ createTransformStreamSimple,
+ TransformStreamDefaultControllerEnqueue,
+ getTransformStreamReadable,
+ getTransformStreamWritable
+ });
});
diff --git a/chromium/third_party/blink/renderer/core/streams/WritableStream.js b/chromium/third_party/blink/renderer/core/streams/WritableStream.js
index 56805f1a5d0..3ee1c57e3ea 100644
--- a/chromium/third_party/blink/renderer/core/streams/WritableStream.js
+++ b/chromium/third_party/blink/renderer/core/streams/WritableStream.js
@@ -144,9 +144,9 @@
}
InitializeWritableStream(this);
- const type = underlyingSink.type;
const size = strategy.size;
let highWaterMark = strategy.highWaterMark;
+ const type = underlyingSink.type;
if (type !== undefined) {
throw new RangeError(streamErrors.invalidType);
}
@@ -822,7 +822,9 @@
// or impossible, so use static dispatch for now. This will have to be fixed
// when adding a byte controller.
function WritableStreamDefaultControllerAbortSteps(controller, reason) {
- return controller[_abortAlgorithm](reason);
+ const result = controller[_abortAlgorithm](reason);
+ WritableStreamDefaultControllerClearAlgorithms(controller);
+ return result;
}
function WritableStreamDefaultControllerErrorSteps(controller) {
@@ -897,6 +899,12 @@
sizeAlgorithm);
}
+ function WritableStreamDefaultControllerClearAlgorithms(controller) {
+ controller[_writeAlgorithm] = undefined;
+ controller[_closeAlgorithm] = undefined;
+ controller[_abortAlgorithm] = undefined;
+ }
+
function WritableStreamDefaultControllerClose(controller) {
EnqueueValueWithSize(controller, 'close', 0);
WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller);
@@ -979,6 +987,7 @@
// assert(controller[_queue].length === 0,
// 'controller.[[queue]] is empty.');
const sinkClosePromise = controller[_closeAlgorithm]();
+ WritableStreamDefaultControllerClearAlgorithms(controller);
thenPromise(
sinkClosePromise, () => WritableStreamFinishInFlightClose(stream),
reason => WritableStreamFinishInFlightCloseWithError(stream, reason));
@@ -1005,6 +1014,10 @@
WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller);
},
reason => {
+ const state = stream[_stateAndFlags] & STATE_MASK;
+ if (state === WRITABLE) {
+ WritableStreamDefaultControllerClearAlgorithms(controller);
+ }
WritableStreamFinishInFlightWriteWithError(stream, reason);
});
}
@@ -1019,6 +1032,7 @@
const stream = controller[_controlledWritableStream];
// assert((stream[_stateAndFlags] & STATE_MASK) === WRITABLE,
// '_stream_.[[state]] is `"writable"`.');
+ WritableStreamDefaultControllerClearAlgorithms(controller);
WritableStreamStartErroring(stream, error);
}
@@ -1035,33 +1049,29 @@
// TODO(ricea): Exports to Blink
- // Exports for ReadableStream
- binding.AcquireWritableStreamDefaultWriter =
- AcquireWritableStreamDefaultWriter;
- binding.IsWritableStream = IsWritableStream;
- binding.isWritableStreamClosingOrClosed = isWritableStreamClosingOrClosed;
- binding.isWritableStreamErrored = isWritableStreamErrored;
- binding.IsWritableStreamLocked = IsWritableStreamLocked;
- binding.WritableStreamAbort = WritableStreamAbort;
- binding.WritableStreamDefaultWriterCloseWithErrorPropagation =
- WritableStreamDefaultWriterCloseWithErrorPropagation;
- binding.getWritableStreamDefaultWriterClosedPromise =
- getWritableStreamDefaultWriterClosedPromise;
- binding.WritableStreamDefaultWriterGetDesiredSize =
- WritableStreamDefaultWriterGetDesiredSize;
- binding.getWritableStreamDefaultWriterReadyPromise =
- getWritableStreamDefaultWriterReadyPromise;
- binding.WritableStreamDefaultWriterRelease =
- WritableStreamDefaultWriterRelease;
- binding.WritableStreamDefaultWriterWrite = WritableStreamDefaultWriterWrite;
- binding.getWritableStreamStoredError = getWritableStreamStoredError;
-
- // Exports for TransformStream
- binding.CreateWritableStream = CreateWritableStream;
- binding.WritableStream = WritableStream;
- binding.WritableStreamDefaultControllerErrorIfNeeded =
- WritableStreamDefaultControllerErrorIfNeeded;
- binding.isWritableStreamWritable = isWritableStreamWritable;
- binding.isWritableStreamErroring = isWritableStreamErroring;
- binding.getWritableStreamController = getWritableStreamController;
+ Object.assign(binding, {
+ // Exports for ReadableStream
+ AcquireWritableStreamDefaultWriter,
+ IsWritableStream,
+ isWritableStreamClosingOrClosed,
+ isWritableStreamErrored,
+ isWritableStreamWritable,
+ IsWritableStreamLocked,
+ WritableStreamAbort,
+ WritableStreamCloseQueuedOrInFlight,
+ WritableStreamDefaultWriterCloseWithErrorPropagation,
+ getWritableStreamDefaultWriterClosedPromise,
+ WritableStreamDefaultWriterGetDesiredSize,
+ getWritableStreamDefaultWriterReadyPromise,
+ WritableStreamDefaultWriterRelease,
+ WritableStreamDefaultWriterWrite,
+ getWritableStreamStoredError,
+
+ // Additional exports for TransformStream
+ CreateWritableStream,
+ WritableStream,
+ WritableStreamDefaultControllerErrorIfNeeded,
+ isWritableStreamErroring,
+ getWritableStreamController,
+ });
});
diff --git a/chromium/third_party/blink/renderer/core/streams/readable_stream_operations_test.cc b/chromium/third_party/blink/renderer/core/streams/readable_stream_operations_test.cc
index 33154781e83..17abd6959d0 100644
--- a/chromium/third_party/blink/renderer/core/streams/readable_stream_operations_test.cc
+++ b/chromium/third_party/blink/renderer/core/streams/readable_stream_operations_test.cc
@@ -62,7 +62,7 @@ class Iteration final : public GarbageCollectedFinalized<Iteration> {
is_valid_ = false;
return;
}
- value_ = ToCoreString(value->ToString());
+ value_ = ToCoreString(value->ToString(v.GetScriptState()->GetIsolate()));
}
bool IsSet() const { return is_set_; }
diff --git a/chromium/third_party/blink/renderer/core/streams/transform_stream.cc b/chromium/third_party/blink/renderer/core/streams/transform_stream.cc
new file mode 100644
index 00000000000..4ca38c83616
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/streams/transform_stream.cc
@@ -0,0 +1,176 @@
+// 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/streams/transform_stream.h"
+
+#include "third_party/blink/renderer/bindings/core/v8/generated_code_helper.h"
+#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/script_value.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_script_runner.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/platform/bindings/exception_state.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"
+
+namespace blink {
+
+// Base class for FlushAlgorithm and TransformAlgorithm. Contains common
+// construction code and members.
+class TransformStream::Algorithm : public ScriptFunction {
+ public:
+ // This is templated just to avoid having two identical copies of the
+ // function.
+ template <typename T>
+ static v8::Local<v8::Function> Create(TransformStreamTransformer* transformer,
+ ScriptState* script_state,
+ ExceptionState& exception_state) {
+ auto* algorithm = new T(transformer, script_state, exception_state);
+ return algorithm->BindToV8Function();
+ }
+
+ void Trace(Visitor* visitor) override {
+ visitor->Trace(transformer_);
+ ScriptFunction::Trace(visitor);
+ }
+
+ protected:
+ Algorithm(TransformStreamTransformer* transformer,
+ ScriptState* script_state,
+ ExceptionState& exception_state)
+ : ScriptFunction(script_state),
+ transformer_(transformer),
+ context_(exception_state.Context()),
+ interface_name_(exception_state.InterfaceName()),
+ property_name_(exception_state.PropertyName()) {}
+
+ // AlgorithmScope holds the stack-allocated objects used by the CallRaw()
+ // methods for FlushAlgorithm and TransformAlgorithm.
+ class AlgorithmScope {
+ STACK_ALLOCATED();
+
+ public:
+ AlgorithmScope(Algorithm* owner,
+ const v8::FunctionCallbackInfo<v8::Value>& info,
+ v8::Local<v8::Value> controller)
+ : controller_(owner->GetScriptState(), controller),
+ exception_state_(owner->GetScriptState()->GetIsolate(),
+ owner->context_,
+ owner->interface_name_,
+ owner->property_name_),
+ reject_promise_scope_(info, exception_state_) {}
+
+ TransformStreamDefaultController* GetController() { return &controller_; }
+
+ ExceptionState* GetExceptionState() { return &exception_state_; }
+
+ private:
+ TransformStreamDefaultController controller_;
+ ExceptionState exception_state_;
+ ExceptionToRejectPromiseScope reject_promise_scope_;
+ };
+
+ Member<TransformStreamTransformer> transformer_;
+ const ExceptionState::ContextType context_;
+ const char* const interface_name_;
+ const char* const property_name_;
+};
+
+class TransformStream::FlushAlgorithm : public TransformStream::Algorithm {
+ protected:
+ using Algorithm::Algorithm;
+
+ private:
+ void CallRaw(const v8::FunctionCallbackInfo<v8::Value>& info) override {
+ DCHECK_EQ(info.Length(), 1);
+ AlgorithmScope algorithm_scope(this, info, info[0]);
+ ExceptionState& exception_state = *algorithm_scope.GetExceptionState();
+
+ transformer_->Flush(algorithm_scope.GetController(), exception_state);
+ if (exception_state.HadException())
+ return;
+ V8SetReturnValue(info,
+ ScriptPromise::CastUndefined(GetScriptState()).V8Value());
+ }
+};
+
+class TransformStream::TransformAlgorithm : public TransformStream::Algorithm {
+ protected:
+ using Algorithm::Algorithm;
+
+ private:
+ void CallRaw(const v8::FunctionCallbackInfo<v8::Value>& info) override {
+ DCHECK_EQ(info.Length(), 2);
+ AlgorithmScope algorithm_scope(this, info, info[1]);
+ ExceptionState& exception_state = *algorithm_scope.GetExceptionState();
+
+ transformer_->Transform(info[0], algorithm_scope.GetController(),
+ exception_state);
+ if (exception_state.HadException())
+ return;
+ V8SetReturnValue(info,
+ ScriptPromise::CastUndefined(GetScriptState()).V8Value());
+ }
+};
+
+TransformStream::TransformStream() = default;
+
+TransformStream::~TransformStream() = default;
+
+void TransformStream::Init(TransformStreamTransformer* transformer,
+ ScriptState* script_state,
+ ExceptionState& exception_state) {
+ auto transform_algorithm = Algorithm::Create<TransformAlgorithm>(
+ transformer, script_state, exception_state);
+ auto flush_algorithm = Algorithm::Create<FlushAlgorithm>(
+ transformer, script_state, exception_state);
+ v8::Local<v8::Value> args[] = {transform_algorithm, flush_algorithm};
+ v8::TryCatch block(script_state->GetIsolate());
+ v8::Local<v8::Value> stream;
+ if (!V8ScriptRunner::CallExtra(script_state, "createTransformStreamSimple",
+ args)
+ .ToLocal(&stream)) {
+ DCHECK(block.HasCaught());
+ exception_state.RethrowV8Exception(block.Exception());
+ return;
+ }
+ DCHECK(!block.HasCaught());
+ DCHECK(stream->IsObject());
+ stream_.Set(script_state->GetIsolate(), stream);
+}
+
+ScriptValue TransformStream::Readable(ScriptState* script_state,
+ ExceptionState& exception_state) const {
+ return Accessor("getTransformStreamReadable", script_state, exception_state);
+}
+
+ScriptValue TransformStream::Writable(ScriptState* script_state,
+ ExceptionState& exception_state) const {
+ return Accessor("getTransformStreamWritable", script_state, exception_state);
+}
+
+void TransformStream::Trace(Visitor* visitor) {
+ visitor->Trace(stream_);
+}
+
+ScriptValue TransformStream::Accessor(const char* accessor_function_name,
+ ScriptState* script_state,
+ ExceptionState& exception_state) const {
+ v8::Local<v8::Value> result;
+ v8::Local<v8::Value> args[] = {stream_.NewLocal(script_state->GetIsolate())};
+ DCHECK(args[0]->IsObject());
+ v8::TryCatch block(script_state->GetIsolate());
+ if (!V8ScriptRunner::CallExtra(script_state, accessor_function_name, args)
+ .ToLocal(&result)) {
+ DCHECK(block.HasCaught());
+ exception_state.RethrowV8Exception(block.Exception());
+ return ScriptValue();
+ }
+ DCHECK(!block.HasCaught());
+ return ScriptValue(script_state, result);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/streams/transform_stream.h b/chromium/third_party/blink/renderer/core/streams/transform_stream.h
new file mode 100644
index 00000000000..1fb4cead703
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/streams/transform_stream.h
@@ -0,0 +1,66 @@
+// 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_STREAMS_TRANSFORM_STREAM_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_TRANSFORM_STREAM_H_
+
+#include "base/macros.h"
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h"
+#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
+#include "v8/include/v8.h"
+
+namespace blink {
+
+class ExceptionState;
+class ScriptState;
+class ScriptValue;
+class TransformStreamTransformer;
+class Visitor;
+
+// Creates and wraps a JavaScript TransformStream object with a transformation
+// defined in C++. Provides access to the readable and writable streams.
+//
+// On-heap references to this class must always be via a TraceWrapperMember, and
+// must always have an ancestor in the V8 heap, or |stream_| will be lost.
+//
+// To ensure that the JS TransformStream is always referenced, this class uses
+// two-stage construction. After calling the constructor, store the reference
+// in a TraceWrapperMember before calling Init(). Init() must always be called
+// before using the instance.
+class CORE_EXPORT TransformStream final
+ : public GarbageCollectedFinalized<TransformStream> {
+ public:
+ TransformStream();
+ ~TransformStream();
+
+ // If HadException is true on return, the object is invalid and should be
+ // destroyed.
+ void Init(TransformStreamTransformer*, ScriptState*, ExceptionState&);
+
+ ScriptValue Readable(ScriptState*, ExceptionState&) const;
+ ScriptValue Writable(ScriptState*, ExceptionState&) const;
+
+ void Trace(Visitor*);
+
+ private:
+ // These are class-scoped to avoid name clashes in jumbo builds.
+ class Algorithm;
+ class FlushAlgorithm;
+ class TransformAlgorithm;
+
+ // Common implementation for Readable() and Writable() accessors.
+ ScriptValue Accessor(const char* accessor_function_name,
+ ScriptState*,
+ ExceptionState&) const;
+
+ TraceWrapperV8Reference<v8::Value> stream_;
+
+ DISALLOW_COPY_AND_ASSIGN(TransformStream);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_TRANSFORM_STREAM_H_
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
new file mode 100644
index 00000000000..8f232895f99
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/streams/transform_stream_default_controller.cc
@@ -0,0 +1,32 @@
+// 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/streams/transform_stream_default_controller.h"
+
+#include "third_party/blink/renderer/bindings/core/v8/v8_script_runner.h"
+
+namespace blink {
+
+TransformStreamDefaultController::TransformStreamDefaultController(
+ ScriptState* script_state,
+ v8::Local<v8::Value> controller)
+ : script_state_(script_state), controller_(controller) {
+ DCHECK(controller->IsObject());
+}
+
+void TransformStreamDefaultController::Enqueue(
+ v8::Local<v8::Value> chunk,
+ ExceptionState& exception_state) {
+ DCHECK(controller_->IsObject());
+ v8::Local<v8::Value> args[] = {controller_, chunk};
+ v8::TryCatch block(script_state_->GetIsolate());
+ V8ScriptRunner::CallExtra(script_state_,
+ "TransformStreamDefaultControllerEnqueue", args);
+ if (block.HasCaught()) {
+ exception_state.RethrowV8Exception(block.Exception());
+ return;
+ }
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..c60dd5cf4c3
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/streams/transform_stream_default_controller.h
@@ -0,0 +1,39 @@
+// 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_STREAMS_TRANSFORM_STREAM_DEFAULT_CONTROLLER_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_TRANSFORM_STREAM_DEFAULT_CONTROLLER_H_
+
+#include "base/macros.h"
+#include "third_party/blink/renderer/core/core_export.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/member.h"
+#include "v8/include/v8.h"
+
+namespace blink {
+
+// Thin wrapper for the JavaScript TransformStreamDefaultController object. The
+// API mimics the JavaScript API
+// https://streams.spec.whatwg.org/#ts-default-controller-class but unneeded
+// parts have not been implemented.
+class CORE_EXPORT TransformStreamDefaultController final {
+ STACK_ALLOCATED();
+
+ public:
+ TransformStreamDefaultController(ScriptState*,
+ v8::Local<v8::Value> controller);
+
+ void Enqueue(v8::Local<v8::Value> chunk, ExceptionState&);
+
+ private:
+ Member<ScriptState> script_state_;
+ v8::Local<v8::Value> controller_;
+
+ DISALLOW_COPY_AND_ASSIGN(TransformStreamDefaultController);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_TRANSFORM_STREAM_DEFAULT_CONTROLLER_H_
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
new file mode 100644
index 00000000000..26247670aed
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/streams/transform_stream_test.cc
@@ -0,0 +1,502 @@
+// 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/streams/transform_stream.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/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/bindings/core/v8/v8_extras_test_utils.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_iterator_result_value.h"
+#include "third_party/blink/renderer/core/streams/readable_stream_operations.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/testing/dummy_page_holder.h"
+#include "third_party/blink/renderer/core/testing/garbage_collected_script_wrappable.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/bindings/script_state.h"
+#include "third_party/blink/renderer/platform/bindings/to_v8.h"
+#include "third_party/blink/renderer/platform/bindings/trace_wrapper_member.h"
+#include "third_party/blink/renderer/platform/bindings/v8_binding.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#include "v8/include/v8.h"
+
+namespace blink {
+
+namespace {
+
+using ::testing::_;
+using ::testing::Mock;
+
+class TransformStreamTest : public ::testing::Test {
+ public:
+ void TearDown() override {
+ if (holder_)
+ ClearHolder();
+ }
+
+ void Init(TransformStreamTransformer* transformer,
+ ScriptState* script_state,
+ ExceptionState& exception_state) {
+ holder_ = new Holder(script_state);
+ holder_->Stream()->Init(transformer, script_state, exception_state);
+ }
+
+ TransformStream* Stream() const { return holder_->Stream(); }
+
+ // This takes the |readable| and |writable| properties of the TransformStream
+ // and copies them onto the global object so they can be accessed by Eval().
+ void CopyReadableAndWritableToGlobal(const V8TestingScope& scope) {
+ auto* script_state = scope.GetScriptState();
+ ScriptValue readable =
+ Stream()->Readable(script_state, ASSERT_NO_EXCEPTION);
+ ScriptValue writable =
+ Stream()->Writable(script_state, ASSERT_NO_EXCEPTION);
+ v8::Local<v8::Object> global = script_state->GetContext()->Global();
+ EXPECT_TRUE(global
+ ->Set(scope.GetContext(),
+ V8String(scope.GetIsolate(), "readable"),
+ readable.V8Value())
+ .IsJust());
+ EXPECT_TRUE(global
+ ->Set(scope.GetContext(),
+ V8String(scope.GetIsolate(), "writable"),
+ writable.V8Value())
+ .IsJust());
+ }
+
+ void ClearHolder() {
+ holder_->Destroy();
+ holder_ = nullptr;
+ }
+
+ private:
+ // In normal use, TransformStream will be referenced by a ScriptWrappable and
+ // so will be visible to the V8 garbage collector via wrapper tracing. For
+ // testing purposes we need a dummy ScriptWrappable object to do the same
+ // thing.
+ // TODO(ricea): Remove this once unified GC has replaced wrapper tracing.
+ class Holder : public GarbageCollectedScriptWrappable {
+ public:
+ explicit Holder(ScriptState* script_state)
+ : GarbageCollectedScriptWrappable("Holder"),
+ this_as_v8_value_(
+ ScriptValue(script_state, ToV8(this, script_state))),
+ stream_(new TransformStream()) {}
+
+ // Destroy() must be called to break the reference cycle.
+ void Destroy() {
+ this_as_v8_value_.Clear();
+ stream_ = nullptr;
+ }
+
+ TransformStream* Stream() const { return stream_.Get(); }
+
+ void Trace(Visitor* visitor) override {
+ visitor->Trace(stream_);
+ GarbageCollectedScriptWrappable::Trace(visitor);
+ }
+
+ private:
+ // Self-reference to keep this object referenced from V8.
+ ScriptValue this_as_v8_value_;
+ TraceWrapperMember<TransformStream> stream_;
+ };
+
+ Persistent<Holder> holder_;
+};
+
+class IdentityTransformer final : public TransformStreamTransformer {
+ public:
+ void Transform(v8::Local<v8::Value> chunk,
+ TransformStreamDefaultController* controller,
+ ExceptionState& exception_state) override {
+ controller->Enqueue(chunk, exception_state);
+ }
+
+ void Flush(TransformStreamDefaultController* controller,
+ ExceptionState& exception_state) override {}
+};
+
+class MockTransformStreamTransformer : public TransformStreamTransformer {
+ public:
+ MOCK_METHOD3(Transform,
+ void(v8::Local<v8::Value> chunk,
+ TransformStreamDefaultController*,
+ ExceptionState&));
+ MOCK_METHOD2(Flush, void(TransformStreamDefaultController*, ExceptionState&));
+};
+
+// If this doesn't work then nothing else will.
+TEST_F(TransformStreamTest, Construct) {
+ V8TestingScope scope;
+ Init(new IdentityTransformer(), scope.GetScriptState(), ASSERT_NO_EXCEPTION);
+ EXPECT_TRUE(Stream());
+}
+
+TEST_F(TransformStreamTest, Accessors) {
+ V8TestingScope scope;
+ Init(new IdentityTransformer(), scope.GetScriptState(), ASSERT_NO_EXCEPTION);
+ ScriptValue readable =
+ Stream()->Readable(scope.GetScriptState(), ASSERT_NO_EXCEPTION);
+ ScriptValue writable =
+ Stream()->Writable(scope.GetScriptState(), ASSERT_NO_EXCEPTION);
+ EXPECT_TRUE(readable.IsObject());
+ EXPECT_TRUE(writable.IsObject());
+ EXPECT_TRUE(ReadableStreamOperations::IsReadableStream(
+ scope.GetScriptState(), readable, ASSERT_NO_EXCEPTION)
+ .value_or(false));
+ // TODO(ricea): Check writable too once we have a wrapper for
+ // IsWritableStream().
+}
+
+TEST_F(TransformStreamTest, TransformIsCalled) {
+ V8TestingScope scope;
+ auto* mock = new ::testing::StrictMock<MockTransformStreamTransformer>();
+ Init(mock, scope.GetScriptState(), ASSERT_NO_EXCEPTION);
+ // Need to run microtasks so the startAlgorithm promise resolves.
+ v8::MicrotasksScope::PerformCheckpoint(scope.GetIsolate());
+ CopyReadableAndWritableToGlobal(scope);
+
+ EXPECT_CALL(*mock, Transform(_, _, _));
+
+ // The initial read is needed to relieve backpressure.
+ EvalWithPrintingError(&scope,
+ "readable.getReader().read();\n"
+ "const writer = writable.getWriter();\n"
+ "writer.write('a');\n");
+
+ Mock::VerifyAndClear(mock);
+ Mock::AllowLeak(mock);
+}
+
+TEST_F(TransformStreamTest, FlushIsCalled) {
+ V8TestingScope scope;
+ auto* mock = new ::testing::StrictMock<MockTransformStreamTransformer>();
+ Init(mock, scope.GetScriptState(), ASSERT_NO_EXCEPTION);
+ // Need to run microtasks so the startAlgorithm promise resolves.
+ v8::MicrotasksScope::PerformCheckpoint(scope.GetIsolate());
+ CopyReadableAndWritableToGlobal(scope);
+
+ EXPECT_CALL(*mock, Flush(_, _));
+
+ EvalWithPrintingError(&scope,
+ "const writer = writable.getWriter();\n"
+ "writer.close();\n");
+
+ Mock::VerifyAndClear(mock);
+ Mock::AllowLeak(mock);
+}
+
+class ExpectNotReached : public ScriptFunction {
+ public:
+ static v8::Local<v8::Function> Create(ScriptState* script_state) {
+ auto* self = new ExpectNotReached(script_state);
+ return self->BindToV8Function();
+ }
+
+ private:
+ explicit ExpectNotReached(ScriptState* script_state)
+ : ScriptFunction(script_state) {}
+
+ ScriptValue Call(ScriptValue) override {
+ ADD_FAILURE() << "ExpectNotReached was reached";
+ return ScriptValue();
+ }
+};
+
+// Fails the test if the iterator passed to the function does not have a value
+// of exactly |expected|.
+class ExpectChunkIsString : public ScriptFunction {
+ public:
+ static v8::Local<v8::Function> Create(ScriptState* script_state,
+ const String& expected,
+ bool* called) {
+ auto* self = new ExpectChunkIsString(script_state, expected, called);
+ return self->BindToV8Function();
+ }
+
+ private:
+ ExpectChunkIsString(ScriptState* script_state,
+ const String& expected,
+ bool* called)
+ : ScriptFunction(script_state), expected_(expected), called_(called) {}
+
+ ScriptValue Call(ScriptValue value) override {
+ *called_ = true;
+ if (!value.IsObject()) {
+ ADD_FAILURE() << "iterator must be an object";
+ return ScriptValue();
+ }
+ bool done = false;
+ auto* script_state = GetScriptState();
+ auto chunk = V8UnpackIteratorResult(
+ script_state,
+ value.V8Value()->ToObject(script_state->GetContext()).ToLocalChecked(),
+ &done);
+ EXPECT_FALSE(done);
+ EXPECT_FALSE(chunk.IsEmpty());
+ EXPECT_EQ(ToCoreStringWithUndefinedOrNullCheck(chunk.ToLocalChecked()),
+ expected_);
+ return ScriptValue();
+ }
+
+ String expected_;
+ bool* called_;
+};
+
+class ExpectTypeError : public ScriptFunction {
+ public:
+ static v8::Local<v8::Function> Create(ScriptState* script_state,
+ const String& message,
+ bool* called) {
+ auto* self = new ExpectTypeError(script_state, message, called);
+ return self->BindToV8Function();
+ }
+
+ private:
+ ExpectTypeError(ScriptState* script_state,
+ const String& message,
+ bool* called)
+ : ScriptFunction(script_state), message_(message), called_(called) {}
+
+ ScriptValue Call(ScriptValue value) override {
+ *called_ = true;
+ EXPECT_TRUE(IsTypeError(GetScriptState(), value, message_));
+ return ScriptValue();
+ }
+
+ static bool IsTypeError(ScriptState* script_state,
+ ScriptValue value,
+ const String& message) {
+ v8::Local<v8::Object> object;
+ if (!value.V8Value()
+ ->ToObject(script_state->GetContext())
+ .ToLocal(&object)) {
+ return false;
+ }
+ if (!object->IsNativeError())
+ return false;
+ return Has(script_state, object, "name", "TypeError") &&
+ Has(script_state, object, "message", message);
+ }
+
+ static bool Has(ScriptState* script_state,
+ v8::Local<v8::Object> object,
+ const String& key,
+ const String& value) {
+ auto context = script_state->GetContext();
+ auto* isolate = script_state->GetIsolate();
+ v8::Local<v8::Value> actual;
+ return object->Get(context, V8AtomicString(isolate, key))
+ .ToLocal(&actual) &&
+ ToCoreStringWithUndefinedOrNullCheck(actual) == value;
+ }
+
+ String message_;
+ bool* called_;
+};
+
+TEST_F(TransformStreamTest, EnqueueFromTransform) {
+ V8TestingScope scope;
+ auto* script_state = scope.GetScriptState();
+ Init(new IdentityTransformer(), script_state, ASSERT_NO_EXCEPTION);
+
+ CopyReadableAndWritableToGlobal(scope);
+
+ EvalWithPrintingError(&scope,
+ "const writer = writable.getWriter();\n"
+ "writer.write('a');\n");
+
+ ScriptValue readable = Stream()->Readable(script_state, ASSERT_NO_EXCEPTION);
+ ScriptValue reader = ReadableStreamOperations::GetReader(
+ script_state, readable, ASSERT_NO_EXCEPTION);
+ bool chunk_seen = false;
+ ReadableStreamOperations::DefaultReaderRead(script_state, reader)
+ .Then(ExpectChunkIsString::Create(script_state, "a", &chunk_seen),
+ ExpectNotReached::Create(script_state));
+ v8::MicrotasksScope::PerformCheckpoint(scope.GetIsolate());
+ EXPECT_TRUE(chunk_seen);
+}
+
+TEST_F(TransformStreamTest, EnqueueFromFlush) {
+ class EnqueueFromFlushTransformer : public TransformStreamTransformer {
+ public:
+ EnqueueFromFlushTransformer(v8::Local<v8::Object> global,
+ v8::Isolate* isolate)
+ : global_(global), isolate_(isolate) {}
+
+ void Transform(v8::Local<v8::Value>,
+ TransformStreamDefaultController*,
+ ExceptionState&) override {}
+ void Flush(TransformStreamDefaultController* controller,
+ ExceptionState& exception_state) override {
+ controller->Enqueue(ToV8("a", global_, isolate_), exception_state);
+ }
+
+ private:
+ v8::Local<v8::Object> global_;
+ v8::Isolate* isolate_;
+ };
+ V8TestingScope scope;
+ auto* script_state = scope.GetScriptState();
+ Init(new EnqueueFromFlushTransformer(scope.GetContext()->Global(),
+ scope.GetIsolate()),
+ script_state, ASSERT_NO_EXCEPTION);
+
+ CopyReadableAndWritableToGlobal(scope);
+
+ EvalWithPrintingError(&scope,
+ "const writer = writable.getWriter();\n"
+ "writer.close();\n");
+
+ ScriptValue readable = Stream()->Readable(script_state, ASSERT_NO_EXCEPTION);
+ ScriptValue reader = ReadableStreamOperations::GetReader(
+ script_state, readable, ASSERT_NO_EXCEPTION);
+ bool chunkSeen = false;
+ ReadableStreamOperations::DefaultReaderRead(script_state, reader)
+ .Then(ExpectChunkIsString::Create(script_state, "a", &chunkSeen),
+ ExpectNotReached::Create(script_state));
+ v8::MicrotasksScope::PerformCheckpoint(scope.GetIsolate());
+ EXPECT_TRUE(chunkSeen);
+}
+
+TEST_F(TransformStreamTest, ThrowFromTransform) {
+ static constexpr char kMessage[] = "errorInTransform";
+ class ThrowFromTransformTransformer : public TransformStreamTransformer {
+ public:
+ void Transform(v8::Local<v8::Value>,
+ TransformStreamDefaultController*,
+ ExceptionState& exception_state) override {
+ exception_state.ThrowTypeError(kMessage);
+ }
+ void Flush(TransformStreamDefaultController*, ExceptionState&) override {}
+ };
+ V8TestingScope scope;
+ auto* script_state = scope.GetScriptState();
+ Init(new ThrowFromTransformTransformer(), script_state, ASSERT_NO_EXCEPTION);
+
+ CopyReadableAndWritableToGlobal(scope);
+
+ ScriptValue promise =
+ EvalWithPrintingError(&scope,
+ "const writer = writable.getWriter();\n"
+ "writer.write('a');\n");
+
+ ScriptValue readable = Stream()->Readable(script_state, ASSERT_NO_EXCEPTION);
+ ScriptValue reader = ReadableStreamOperations::GetReader(
+ script_state, readable, ASSERT_NO_EXCEPTION);
+ bool readableTypeErrorThrown = false;
+ bool writableTypeErrorThrown = false;
+ ReadableStreamOperations::DefaultReaderRead(script_state, reader)
+ .Then(ExpectNotReached::Create(script_state),
+ ExpectTypeError::Create(script_state, kMessage,
+ &readableTypeErrorThrown));
+ ScriptPromise::Cast(script_state, promise)
+ .Then(ExpectNotReached::Create(script_state),
+ ExpectTypeError::Create(script_state, kMessage,
+ &writableTypeErrorThrown));
+ v8::MicrotasksScope::PerformCheckpoint(scope.GetIsolate());
+ EXPECT_TRUE(readableTypeErrorThrown);
+ EXPECT_TRUE(writableTypeErrorThrown);
+}
+
+TEST_F(TransformStreamTest, ThrowFromFlush) {
+ static constexpr char kMessage[] = "errorInFlush";
+ class ThrowFromFlushTransformer : public TransformStreamTransformer {
+ public:
+ void Transform(v8::Local<v8::Value>,
+ TransformStreamDefaultController*,
+ ExceptionState&) override {}
+ void Flush(TransformStreamDefaultController*,
+ ExceptionState& exception_state) override {
+ exception_state.ThrowTypeError(kMessage);
+ }
+ };
+ V8TestingScope scope;
+ auto* script_state = scope.GetScriptState();
+ Init(new ThrowFromFlushTransformer(), script_state, ASSERT_NO_EXCEPTION);
+
+ CopyReadableAndWritableToGlobal(scope);
+
+ ScriptValue promise =
+ EvalWithPrintingError(&scope,
+ "const writer = writable.getWriter();\n"
+ "writer.close();\n");
+
+ ScriptValue readable = Stream()->Readable(script_state, ASSERT_NO_EXCEPTION);
+ ScriptValue reader = ReadableStreamOperations::GetReader(
+ script_state, readable, ASSERT_NO_EXCEPTION);
+ bool readableTypeErrorThrown = false;
+ bool writableTypeErrorThrown = false;
+ ReadableStreamOperations::DefaultReaderRead(script_state, reader)
+ .Then(ExpectNotReached::Create(script_state),
+ ExpectTypeError::Create(script_state, kMessage,
+ &readableTypeErrorThrown));
+ ScriptPromise::Cast(script_state, promise)
+ .Then(ExpectNotReached::Create(script_state),
+ ExpectTypeError::Create(script_state, kMessage,
+ &writableTypeErrorThrown));
+ v8::MicrotasksScope::PerformCheckpoint(scope.GetIsolate());
+ EXPECT_TRUE(readableTypeErrorThrown);
+ EXPECT_TRUE(writableTypeErrorThrown);
+}
+
+// Verify that the JavaScript TransformStream object is kept alive by the C++
+// TransformStream object.
+TEST_F(TransformStreamTest, SurvivesGarbageCollectionWhenTraced) {
+ auto page_holder = DummyPageHolder::Create();
+ Persistent<ScriptState> script_state =
+ ToScriptStateForMainWorld(page_holder->GetDocument().GetFrame());
+ {
+ ScriptState::Scope scope(script_state);
+ Init(new IdentityTransformer(), script_state, ASSERT_NO_EXCEPTION);
+ }
+ Microtask::PerformCheckpoint(script_state->GetIsolate());
+ script_state->GetIsolate()->RequestGarbageCollectionForTesting(
+ v8::Isolate::kFullGarbageCollection);
+ ScriptState::Scope scope(script_state);
+ ScriptValue readable = Stream()->Readable(script_state, ASSERT_NO_EXCEPTION);
+ EXPECT_TRUE(readable.IsObject());
+ EXPECT_TRUE(ReadableStreamOperations::IsReadableStream(script_state, readable,
+ ASSERT_NO_EXCEPTION)
+ .value_or(false));
+}
+
+// Verify that JS TransformStream is collected when it is not reachable from V8.
+// TODO(ricea): Remove this test when unified garbage collection is introduced,
+// as it will fail.
+#if GTEST_HAS_DEATH_TEST
+#define MAYBE_IsGarbageCollectedWhenNotTraced IsGarbageCollectedWhenNotTraced
+#else
+#define MAYBE_IsGarbageCollectedWhenNotTraced \
+ DISABLED_IsGarbageCollectedWhenNotTraced
+#endif
+TEST_F(TransformStreamTest, MAYBE_IsGarbageCollectedWhenNotTraced) {
+ auto page_holder = DummyPageHolder::Create();
+ Persistent<ScriptState> script_state =
+ ToScriptStateForMainWorld(page_holder->GetDocument().GetFrame());
+ {
+ ScriptState::Scope scope(script_state);
+ Init(new IdentityTransformer(), script_state, ASSERT_NO_EXCEPTION);
+ }
+ Persistent<TransformStream> stream = Stream();
+ ClearHolder();
+ Microtask::PerformCheckpoint(script_state->GetIsolate());
+ script_state->GetIsolate()->RequestGarbageCollectionForTesting(
+ v8::Isolate::kFullGarbageCollection);
+ ScriptState::Scope scope(script_state);
+ // This emits a warning that death tests are unsafe with threads, but it works
+ // anyway. The crash message depends on whether DCHECK is enabled or not, so
+ // the regex it is required to match is empty.
+ EXPECT_DEATH(stream->Readable(script_state, ASSERT_NO_EXCEPTION), "");
+}
+
+} // namespace
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/streams/transform_stream_transformer.h b/chromium/third_party/blink/renderer/core/streams/transform_stream_transformer.h
new file mode 100644
index 00000000000..46b7f9a7eb9
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/streams/transform_stream_transformer.h
@@ -0,0 +1,48 @@
+// 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_STREAMS_TRANSFORM_STREAM_TRANSFORMER_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_TRANSFORM_STREAM_TRANSFORMER_H_
+
+#include "base/macros.h"
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
+#include "v8/include/v8.h"
+
+namespace blink {
+
+class ExceptionState;
+class TransformStreamDefaultController;
+class Visitor;
+
+// Interface to be implemented by C++ code that needs to create a
+// TransformStream. Very similar to the JavaScript [Transformer
+// API](https://streams.spec.whatwg.org/#transformer-api), but asynchronous
+// transforms are not currently supported. Errors should be signalled by
+// exceptions.
+//
+// An instance is stored in a JS object as a Persistent reference, so to avoid
+// uncollectable cycles implementations must not directly or indirectly strongly
+// reference any JS object.
+class CORE_EXPORT TransformStreamTransformer
+ : public GarbageCollectedFinalized<TransformStreamTransformer> {
+ public:
+ TransformStreamTransformer() = default;
+ virtual ~TransformStreamTransformer() = default;
+
+ virtual void Transform(v8::Local<v8::Value> chunk,
+ TransformStreamDefaultController*,
+ ExceptionState&) = 0;
+ virtual void Flush(TransformStreamDefaultController*, ExceptionState&) = 0;
+
+ virtual void Trace(Visitor*) {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TransformStreamTransformer);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_TRANSFORM_STREAM_TRANSFORMER_H_
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 4ff9f1e3a61..ec9a5083fd3 100644
--- a/chromium/third_party/blink/renderer/core/style/computed_style.cc
+++ b/chromium/third_party/blink/renderer/core/style/computed_style.cc
@@ -52,6 +52,7 @@
#include "third_party/blink/renderer/core/style/quotes_data.h"
#include "third_party/blink/renderer/core/style/shadow_list.h"
#include "third_party/blink/renderer/core/style/style_difference.h"
+#include "third_party/blink/renderer/core/style/style_fetched_image.h"
#include "third_party/blink/renderer/core/style/style_image.h"
#include "third_party/blink/renderer/core/style/style_inherited_variables.h"
#include "third_party/blink/renderer/core/style/style_non_inherited_variables.h"
@@ -815,6 +816,9 @@ void ComputedStyle::UpdatePropertySpecificDifferences(
diff.SetTextDecorationOrColorChanged();
}
+ if (ComputedStyleBase::UpdatePropertySpecificDifferencesMask(*this, other))
+ diff.SetMaskChanged();
+
bool has_clip = HasOutOfFlowPosition() && !HasAutoClip();
bool other_has_clip = other.HasOutOfFlowPosition() && !other.HasAutoClip();
if (has_clip != other_has_clip ||
@@ -1017,6 +1021,18 @@ InterpolationQuality ComputedStyle::GetInterpolationQuality() const {
return kInterpolationDefault;
}
+void ComputedStyle::LoadDeferredImages(Document& document) const {
+ if (HasBackgroundImage()) {
+ for (const FillLayer* background_layer = &BackgroundLayers();
+ background_layer; background_layer = background_layer->Next()) {
+ if (StyleImage* image = background_layer->GetImage()) {
+ if (image->IsImageResource() && image->IsLazyloadPossiblyDeferred())
+ ToStyleFetchedImage(image)->LoadDeferredImage(document);
+ }
+ }
+ }
+}
+
void ComputedStyle::ApplyTransform(
TransformationMatrix& result,
const LayoutSize& border_box_size,
@@ -1780,9 +1796,9 @@ Length ComputedStyle::LineHeight() const {
// too, though this involves messily poking into CalcExpressionLength.
if (lh.IsFixed()) {
float multiplier = TextAutosizingMultiplier();
- return Length(
- TextAutosizer::ComputeAutosizedFontSize(lh.Value(), multiplier),
- kFixed);
+ return Length(TextAutosizer::ComputeAutosizedFontSize(
+ lh.Value(), multiplier, EffectiveZoom()),
+ kFixed);
}
return lh;
@@ -1848,12 +1864,12 @@ void ComputedStyle::SetTextAutosizingMultiplier(float multiplier) {
FontSelector* current_font_selector = GetFont().GetFontSelector();
FontDescription desc(GetFontDescription());
desc.SetSpecifiedSize(size);
- desc.SetComputedSize(size);
- float autosized_font_size =
- TextAutosizer::ComputeAutosizedFontSize(size, multiplier);
- float computed_size = autosized_font_size * EffectiveZoom();
- desc.SetComputedSize(std::min(kMaximumAllowedFontSize, computed_size));
+ float computed_size = size * EffectiveZoom();
+
+ float autosized_font_size = TextAutosizer::ComputeAutosizedFontSize(
+ computed_size, multiplier, EffectiveZoom());
+ desc.SetComputedSize(std::min(kMaximumAllowedFontSize, autosized_font_size));
SetFontDescription(desc);
GetFont().Update(current_font_selector);
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 2847c7d7e0e..d6d38c2ae0a 100644
--- a/chromium/third_party/blink/renderer/core/style/computed_style.h
+++ b/chromium/third_party/blink/renderer/core/style/computed_style.h
@@ -287,8 +287,8 @@ class ComputedStyle : public ComputedStyleBase,
StyleDifference VisualInvalidationDiff(const Document&,
const ComputedStyle&) const;
- void InheritFrom(const ComputedStyle& inherit_parent,
- IsAtShadowBoundary = kNotAtShadowBoundary);
+ CORE_EXPORT void InheritFrom(const ComputedStyle& inherit_parent,
+ IsAtShadowBoundary = kNotAtShadowBoundary);
void CopyNonInheritedFromCached(const ComputedStyle&);
PseudoId StyleType() const { return static_cast<PseudoId>(StyleTypeInternal()); }
@@ -1079,8 +1079,8 @@ class ComputedStyle : public ComputedStyleBase,
void ClearResetDirectives();
// Variables.
- StyleInheritedVariables* InheritedVariables() const;
- StyleNonInheritedVariables* NonInheritedVariables() const;
+ CORE_EXPORT StyleInheritedVariables* InheritedVariables() const;
+ CORE_EXPORT StyleNonInheritedVariables* NonInheritedVariables() const;
void SetUnresolvedInheritedVariable(const AtomicString&,
scoped_refptr<CSSVariableData>);
@@ -1479,10 +1479,10 @@ class ComputedStyle : public ComputedStyleBase,
}
bool BorderSizeEquals(const ComputedStyle& o) const {
- return BorderLeftWidthInternal() == o.BorderLeftWidthInternal() &&
- BorderTopWidthInternal() == o.BorderTopWidthInternal() &&
- BorderRightWidthInternal() == o.BorderRightWidthInternal() &&
- BorderBottomWidthInternal() == o.BorderBottomWidthInternal();
+ return BorderLeftWidth() == o.BorderLeftWidth() &&
+ BorderTopWidth() == o.BorderTopWidth() &&
+ BorderRightWidth() == o.BorderRightWidth() &&
+ BorderBottomWidth() == o.BorderBottomWidth();
}
BorderValue BorderBeforeUsing(const ComputedStyle& other) const {
@@ -2220,9 +2220,7 @@ class ComputedStyle : public ComputedStyleBase,
InterpolationQuality GetInterpolationQuality() const;
bool CanGeneratePseudoElement(PseudoId pseudo) const {
- // The first letter pseudo element has to look up the tree and see if any
- // of the ancestors are first letter.
- if (pseudo != kPseudoIdFirstLetter && !HasPseudoStyle(pseudo))
+ if (!HasPseudoStyle(pseudo))
return false;
if (Display() == EDisplay::kNone)
return false;
@@ -2234,6 +2232,9 @@ class ComputedStyle : public ComputedStyleBase,
return pseudo == kPseudoIdBefore || pseudo == kPseudoIdAfter;
}
+ // Load the images of CSS properties that were deferred by LazyLoad.
+ void LoadDeferredImages(Document&) const;
+
private:
void SetVisitedLinkBackgroundColor(const StyleColor& v) {
SetVisitedLinkBackgroundColorInternal(v);
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 db7bb165995..55d364d3494 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
@@ -286,4 +286,69 @@ TEST(ComputedStyleTest, CursorList) {
EXPECT_EQ(*style, *other);
}
+TEST(ComputedStyleTest, BorderStyle) {
+ scoped_refptr<ComputedStyle> style = ComputedStyle::Create();
+ scoped_refptr<ComputedStyle> other = ComputedStyle::Create();
+ style->SetBorderLeftStyle(EBorderStyle::kSolid);
+ style->SetBorderTopStyle(EBorderStyle::kSolid);
+ style->SetBorderRightStyle(EBorderStyle::kSolid);
+ style->SetBorderBottomStyle(EBorderStyle::kSolid);
+ other->SetBorderLeftStyle(EBorderStyle::kSolid);
+ other->SetBorderTopStyle(EBorderStyle::kSolid);
+ other->SetBorderRightStyle(EBorderStyle::kSolid);
+ other->SetBorderBottomStyle(EBorderStyle::kSolid);
+
+ EXPECT_TRUE(style->BorderSizeEquals(*other));
+ style->SetBorderLeftWidth(1.0);
+ EXPECT_FALSE(style->BorderSizeEquals(*other));
+ other->SetBorderLeftWidth(1.0);
+ EXPECT_TRUE(style->BorderSizeEquals(*other));
+
+ EXPECT_TRUE(style->BorderSizeEquals(*other));
+ style->SetBorderTopWidth(1.0);
+ EXPECT_FALSE(style->BorderSizeEquals(*other));
+ other->SetBorderTopWidth(1.0);
+ EXPECT_TRUE(style->BorderSizeEquals(*other));
+
+ EXPECT_TRUE(style->BorderSizeEquals(*other));
+ style->SetBorderRightWidth(1.0);
+ EXPECT_FALSE(style->BorderSizeEquals(*other));
+ other->SetBorderRightWidth(1.0);
+ EXPECT_TRUE(style->BorderSizeEquals(*other));
+
+ EXPECT_TRUE(style->BorderSizeEquals(*other));
+ style->SetBorderBottomWidth(1.0);
+ EXPECT_FALSE(style->BorderSizeEquals(*other));
+ other->SetBorderBottomWidth(1.0);
+ EXPECT_TRUE(style->BorderSizeEquals(*other));
+
+ style->SetBorderLeftStyle(EBorderStyle::kHidden);
+ EXPECT_FALSE(style->BorderSizeEquals(*other));
+ style->SetBorderLeftStyle(EBorderStyle::kNone);
+ EXPECT_FALSE(style->BorderSizeEquals(*other));
+ style->SetBorderLeftStyle(EBorderStyle::kSolid);
+ EXPECT_TRUE(style->BorderSizeEquals(*other));
+
+ style->SetBorderTopStyle(EBorderStyle::kHidden);
+ EXPECT_FALSE(style->BorderSizeEquals(*other));
+ style->SetBorderTopStyle(EBorderStyle::kNone);
+ EXPECT_FALSE(style->BorderSizeEquals(*other));
+ style->SetBorderTopStyle(EBorderStyle::kSolid);
+ EXPECT_TRUE(style->BorderSizeEquals(*other));
+
+ style->SetBorderRightStyle(EBorderStyle::kHidden);
+ EXPECT_FALSE(style->BorderSizeEquals(*other));
+ style->SetBorderRightStyle(EBorderStyle::kNone);
+ EXPECT_FALSE(style->BorderSizeEquals(*other));
+ style->SetBorderRightStyle(EBorderStyle::kSolid);
+ EXPECT_TRUE(style->BorderSizeEquals(*other));
+
+ style->SetBorderBottomStyle(EBorderStyle::kHidden);
+ EXPECT_FALSE(style->BorderSizeEquals(*other));
+ style->SetBorderBottomStyle(EBorderStyle::kNone);
+ EXPECT_FALSE(style->BorderSizeEquals(*other));
+ style->SetBorderBottomStyle(EBorderStyle::kSolid);
+ EXPECT_TRUE(style->BorderSizeEquals(*other));
+}
+
} // namespace blink
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 356d681070d..2d9e0133d95 100644
--- a/chromium/third_party/blink/renderer/core/style/style_difference.h
+++ b/chromium/third_party/blink/renderer/core/style/style_difference.h
@@ -27,6 +27,7 @@ class StyleDifference {
// decorations or properties dependent on color (e.g., border or outline).
kTextDecorationOrColorChanged = 1 << 6,
kBlendModeChanged = 1 << 7,
+ kMaskChanged = 1 << 8,
// If you add a value here, be sure to update kPropertyDifferenceCount.
};
@@ -146,6 +147,11 @@ class StyleDifference {
property_specific_differences_ |= kTextDecorationOrColorChanged;
}
+ bool MaskChanged() const {
+ return property_specific_differences_ & kMaskChanged;
+ }
+ void SetMaskChanged() { property_specific_differences_ |= kMaskChanged; }
+
bool ScrollAnchorDisablingPropertyChanged() const {
return scroll_anchor_disabling_property_changed_;
}
@@ -156,7 +162,7 @@ class StyleDifference {
void SetCompositingReasonsChanged() { composited_reasons_changed_ = true; }
private:
- static constexpr int kPropertyDifferenceCount = 8;
+ static constexpr int kPropertyDifferenceCount = 9;
friend CORE_EXPORT std::ostream& operator<<(std::ostream&,
const StyleDifference&);
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 0a9447455a4..9e31e747ce9 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
@@ -34,9 +34,12 @@
namespace blink {
StyleFetchedImage::StyleFetchedImage(const Document& document,
- FetchParameters& params)
+ FetchParameters& params,
+ bool is_lazyload_possibly_deferred)
: document_(&document), url_(params.Url()) {
is_image_resource_ = true;
+ is_lazyload_possibly_deferred_ = is_lazyload_possibly_deferred;
+
image_ = ImageResourceContent::Fetch(params, document_->Fetcher());
image_->AddObserver(this);
// ResourceFetcher is not determined from StyleFetchedImage and it is
@@ -142,6 +145,13 @@ bool StyleFetchedImage::KnownToBeOpaque(const Document&,
return image_->GetImage()->CurrentFrameKnownToBeOpaque();
}
+void StyleFetchedImage::LoadDeferredImage(const Document& document) {
+ DCHECK(is_lazyload_possibly_deferred_);
+ is_lazyload_possibly_deferred_ = false;
+ document_ = &document;
+ image_->LoadDeferredImage(document_->Fetcher());
+}
+
void StyleFetchedImage::Trace(blink::Visitor* visitor) {
visitor->Trace(image_);
visitor->Trace(document_);
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 60a4bfc3546..b70e2654f4b 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
@@ -41,8 +41,9 @@ class StyleFetchedImage final : public StyleImage,
public:
static StyleFetchedImage* Create(const Document& document,
- FetchParameters& params) {
- return new StyleFetchedImage(document, params);
+ FetchParameters& params,
+ bool is_lazyload_deferred) {
+ return new StyleFetchedImage(document, params, is_lazyload_deferred);
}
~StyleFetchedImage() override;
@@ -70,10 +71,14 @@ class StyleFetchedImage final : public StyleImage,
bool KnownToBeOpaque(const Document&, const ComputedStyle&) const override;
ImageResourceContent* CachedImage() const override;
+ void LoadDeferredImage(const Document& document);
+
void Trace(blink::Visitor*) override;
private:
- StyleFetchedImage(const Document&, FetchParameters&);
+ StyleFetchedImage(const Document&,
+ FetchParameters&,
+ bool is_lazyload_deferred);
void Dispose();
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 6aa247dc28c..4f90fd4c809 100644
--- a/chromium/third_party/blink/renderer/core/style/style_image.h
+++ b/chromium/third_party/blink/renderer/core/style/style_image.h
@@ -139,6 +139,13 @@ class CORE_EXPORT StyleImage : public GarbageCollectedFinalized<StyleImage> {
}
ALWAYS_INLINE bool IsPaintImage() const { return is_paint_image_; }
+ bool IsLazyloadPossiblyDeferred() const {
+ return is_lazyload_possibly_deferred_;
+ }
+ void SetIsLazyloadPossiblyDeferred(bool is_lazyload_possibly_deferred) {
+ is_lazyload_possibly_deferred_ = is_lazyload_possibly_deferred;
+ }
+
virtual void Trace(blink::Visitor* visitor) {}
protected:
@@ -147,12 +154,14 @@ class CORE_EXPORT StyleImage : public GarbageCollectedFinalized<StyleImage> {
is_pending_image_(false),
is_generated_image_(false),
is_image_resource_set_(false),
- is_paint_image_(false) {}
+ is_paint_image_(false),
+ is_lazyload_possibly_deferred_(false) {}
bool is_image_resource_ : 1;
bool is_pending_image_ : 1;
bool is_generated_image_ : 1;
bool is_image_resource_set_ : 1;
bool is_paint_image_ : 1;
+ bool is_lazyload_possibly_deferred_ : 1;
FloatSize ApplyZoom(const FloatSize&, float multiplier) const;
FloatSize ImageSizeForSVGImage(SVGImage*,
diff --git a/chromium/third_party/blink/renderer/core/style/style_inherited_variables.cc b/chromium/third_party/blink/renderer/core/style/style_inherited_variables.cc
index 8678a01c3f0..6d2b2632474 100644
--- a/chromium/third_party/blink/renderer/core/style/style_inherited_variables.cc
+++ b/chromium/third_party/blink/renderer/core/style/style_inherited_variables.cc
@@ -39,6 +39,7 @@ StyleInheritedVariables::StyleInheritedVariables(
registered_data_ = other.registered_data_;
root_ = other.root_;
}
+ needs_resolution_ = other.needs_resolution_;
}
CSSVariableData* StyleInheritedVariables::GetVariable(
diff --git a/chromium/third_party/blink/renderer/core/style/style_inherited_variables.h b/chromium/third_party/blink/renderer/core/style/style_inherited_variables.h
index faadb12d7c0..affa9406308 100644
--- a/chromium/third_party/blink/renderer/core/style/style_inherited_variables.h
+++ b/chromium/third_party/blink/renderer/core/style/style_inherited_variables.h
@@ -14,7 +14,8 @@
namespace blink {
-class StyleInheritedVariables : public RefCounted<StyleInheritedVariables> {
+class CORE_EXPORT StyleInheritedVariables
+ : public RefCounted<StyleInheritedVariables> {
public:
static scoped_refptr<StyleInheritedVariables> Create() {
return base::AdoptRef(new StyleInheritedVariables());
@@ -31,6 +32,8 @@ class StyleInheritedVariables : public RefCounted<StyleInheritedVariables> {
void SetVariable(const AtomicString& name,
scoped_refptr<CSSVariableData> value) {
+ needs_resolution_ = needs_resolution_ || value->NeedsVariableResolution() ||
+ value->NeedsUrlResolution();
data_.Set(name, std::move(value));
}
CSSVariableData* GetVariable(const AtomicString& name) const;
@@ -44,8 +47,11 @@ class StyleInheritedVariables : public RefCounted<StyleInheritedVariables> {
// using a fallback.
HashSet<AtomicString> GetCustomPropertyNames() const;
+ bool NeedsResolution() const { return needs_resolution_; }
+ void ClearNeedsResolution() { needs_resolution_ = false; }
+
private:
- StyleInheritedVariables() : root_(nullptr) {}
+ StyleInheritedVariables() : root_(nullptr), needs_resolution_(false) {}
StyleInheritedVariables(StyleInheritedVariables& other);
friend class CSSVariableResolver;
@@ -53,6 +59,7 @@ class StyleInheritedVariables : public RefCounted<StyleInheritedVariables> {
HashMap<AtomicString, scoped_refptr<CSSVariableData>> data_;
PersistentHeapHashMap<AtomicString, Member<CSSValue>> registered_data_;
scoped_refptr<StyleInheritedVariables> root_;
+ bool needs_resolution_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/style/style_non_inherited_variables.cc b/chromium/third_party/blink/renderer/core/style/style_non_inherited_variables.cc
index 7496efd1488..cfb063b81d2 100644
--- a/chromium/third_party/blink/renderer/core/style/style_non_inherited_variables.cc
+++ b/chromium/third_party/blink/renderer/core/style/style_non_inherited_variables.cc
@@ -42,6 +42,7 @@ StyleNonInheritedVariables::StyleNonInheritedVariables(
StyleNonInheritedVariables& other) {
data_ = other.data_;
registered_data_ = other.registered_data_;
+ needs_resolution_ = other.needs_resolution_;
}
HashSet<AtomicString> StyleNonInheritedVariables::GetCustomPropertyNames()
diff --git a/chromium/third_party/blink/renderer/core/style/style_non_inherited_variables.h b/chromium/third_party/blink/renderer/core/style/style_non_inherited_variables.h
index 926fe199530..c154f20de89 100644
--- a/chromium/third_party/blink/renderer/core/style/style_non_inherited_variables.h
+++ b/chromium/third_party/blink/renderer/core/style/style_non_inherited_variables.h
@@ -17,7 +17,7 @@
namespace blink {
-class StyleNonInheritedVariables {
+class CORE_EXPORT StyleNonInheritedVariables {
public:
static std::unique_ptr<StyleNonInheritedVariables> Create() {
return base::WrapUnique(new StyleNonInheritedVariables);
@@ -34,6 +34,8 @@ class StyleNonInheritedVariables {
void SetVariable(const AtomicString& name,
scoped_refptr<CSSVariableData> value) {
+ needs_resolution_ = needs_resolution_ || value->NeedsVariableResolution() ||
+ value->NeedsUrlResolution();
data_.Set(name, std::move(value));
}
CSSVariableData* GetVariable(const AtomicString& name) const;
@@ -46,14 +48,18 @@ class StyleNonInheritedVariables {
HashSet<AtomicString> GetCustomPropertyNames() const;
+ bool NeedsResolution() const { return needs_resolution_; }
+ void ClearNeedsResolution() { needs_resolution_ = false; }
+
private:
- StyleNonInheritedVariables() = default;
+ StyleNonInheritedVariables() : needs_resolution_(false) {}
StyleNonInheritedVariables(StyleNonInheritedVariables&);
friend class CSSVariableResolver;
HashMap<AtomicString, scoped_refptr<CSSVariableData>> data_;
PersistentHeapHashMap<AtomicString, Member<CSSValue>> registered_data_;
+ bool needs_resolution_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/svg/animation/smil_time_container.cc b/chromium/third_party/blink/renderer/core/svg/animation/smil_time_container.cc
index f53feeb9419..d5c29f46d4d 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
@@ -79,9 +79,11 @@ void SMILTimeContainer::Schedule(SVGSMILElement* animation,
DCHECK(!prevent_scheduled_animations_changes_);
#endif
- ElementAttributePair key(target, attribute_name);
+ AttributeAnimationsMap& attribute_map =
+ scheduled_animations_.insert(target, AttributeAnimationsMap())
+ .stored_value->value;
Member<AnimationsLinkedHashSet>& scheduled =
- scheduled_animations_.insert(key, nullptr).stored_value->value;
+ attribute_map.insert(attribute_name, nullptr).stored_value->value;
if (!scheduled)
scheduled = new AnimationsLinkedHashSet;
DCHECK(!scheduled->Contains(animation));
@@ -101,16 +103,20 @@ void SMILTimeContainer::Unschedule(SVGSMILElement* animation,
DCHECK(!prevent_scheduled_animations_changes_);
#endif
- ElementAttributePair key(target, attribute_name);
- GroupedAnimationsMap::iterator it = scheduled_animations_.find(key);
- DCHECK_NE(it, scheduled_animations_.end());
- AnimationsLinkedHashSet* scheduled = it->value.Get();
- DCHECK(scheduled);
+ GroupedAnimationsMap::iterator it = scheduled_animations_.find(target);
+ CHECK(it != scheduled_animations_.end());
+ AttributeAnimationsMap& attribute_map = it->value;
+ AttributeAnimationsMap::iterator attribute_map_it =
+ attribute_map.find(attribute_name);
+ DCHECK(attribute_map_it != attribute_map.end());
+ AnimationsLinkedHashSet* scheduled = attribute_map_it->value;
AnimationsLinkedHashSet::iterator it_animation = scheduled->find(animation);
DCHECK(it_animation != scheduled->end());
scheduled->erase(it_animation);
if (scheduled->IsEmpty())
+ attribute_map.erase(attribute_map_it);
+ if (attribute_map.IsEmpty())
scheduled_animations_.erase(it);
}
@@ -229,13 +235,13 @@ void SMILTimeContainer::SetElapsed(double elapsed) {
#if DCHECK_IS_ON()
prevent_scheduled_animations_changes_ = true;
#endif
- for (const auto& entry : scheduled_animations_) {
- if (!entry.key.first)
- continue;
-
- AnimationsLinkedHashSet* scheduled = entry.value.Get();
- for (SVGSMILElement* element : *scheduled)
- element->Reset();
+ for (const auto& attribute_entry : scheduled_animations_) {
+ for (const auto& entry : attribute_entry.value) {
+ const AnimationsLinkedHashSet* scheduled = entry.value;
+ for (SVGSMILElement* element : *scheduled) {
+ element->Reset();
+ }
+ }
}
#if DCHECK_IS_ON()
prevent_scheduled_animations_changes_ = false;
@@ -428,62 +434,66 @@ SMILTime SMILTimeContainer::UpdateAnimations(double elapsed,
if (document_order_indexes_dirty_)
UpdateDocumentOrderIndexes();
- HeapHashSet<ElementAttributePair> invalid_keys;
using AnimationsVector = HeapVector<Member<SVGSMILElement>>;
AnimationsVector animations_to_apply;
AnimationsVector scheduled_animations_in_same_group;
- for (const auto& entry : scheduled_animations_) {
- if (!entry.key.first || entry.value->IsEmpty()) {
- invalid_keys.insert(entry.key);
- continue;
- }
-
- // Sort according to priority. Elements with later begin time have higher
- // priority. In case of a tie, document order decides.
- // FIXME: This should also consider timing relationships between the
- // elements. Dependents have higher priority.
- CopyToVector(*entry.value, scheduled_animations_in_same_group);
- std::sort(scheduled_animations_in_same_group.begin(),
- scheduled_animations_in_same_group.end(),
- PriorityCompare(elapsed));
-
- AnimationsVector sandwich;
- for (const auto& it_animation : scheduled_animations_in_same_group) {
- SVGSMILElement* animation = it_animation.Get();
- DCHECK_EQ(animation->TimeContainer(), this);
- DCHECK(animation->HasValidTarget());
-
- // This will calculate the contribution from the animation and update
- // timing.
- if (animation->Progress(elapsed, seek_to_time)) {
- sandwich.push_back(animation);
- } else {
- animation->ClearAnimatedType();
+ for (auto& attribute_entry : scheduled_animations_) {
+ AttributeAnimationsMap& attribute_map = attribute_entry.value;
+ Vector<QualifiedName> invalid_keys;
+ for (const auto& entry : attribute_map) {
+ DCHECK(entry.value);
+ if (entry.value->IsEmpty()) {
+ invalid_keys.push_back(entry.key);
+ continue;
}
- SMILTime next_fire_time = animation->NextProgressTime();
- if (next_fire_time.IsFinite())
- earliest_fire_time = std::min(next_fire_time, earliest_fire_time);
- }
+ // Sort according to priority. Elements with later begin time have higher
+ // priority. In case of a tie, document order decides.
+ // FIXME: This should also consider timing relationships between the
+ // elements. Dependents have higher priority.
+ CopyToVector(*entry.value, scheduled_animations_in_same_group);
+ std::sort(scheduled_animations_in_same_group.begin(),
+ scheduled_animations_in_same_group.end(),
+ PriorityCompare(elapsed));
+
+ AnimationsVector sandwich;
+ for (const auto& it_animation : scheduled_animations_in_same_group) {
+ SVGSMILElement* animation = it_animation.Get();
+ DCHECK_EQ(animation->TimeContainer(), this);
+ DCHECK(animation->HasValidTarget());
+
+ // This will calculate the contribution from the animation and update
+ // timing.
+ if (animation->Progress(elapsed, seek_to_time)) {
+ sandwich.push_back(animation);
+ } else {
+ animation->ClearAnimatedType();
+ }
+
+ SMILTime next_fire_time = animation->NextProgressTime();
+ if (next_fire_time.IsFinite())
+ earliest_fire_time = std::min(next_fire_time, earliest_fire_time);
+ }
- if (!sandwich.IsEmpty()) {
- // Results are accumulated to the first animation that animates and
- // contributes to a particular element/attribute pair.
- // Only reset the animated type to the base value once for
- // the lowest priority animation that animates and
- // contributes to a particular element/attribute pair.
- SVGSMILElement* result_element = sandwich.front();
- result_element->ResetAnimatedType();
-
- // Go through the sandwich from lowest prio to highest and generate
- // the animated value (if any.)
- for (const auto& animation : sandwich)
- animation->UpdateAnimatedValue(result_element);
-
- animations_to_apply.push_back(result_element);
+ if (!sandwich.IsEmpty()) {
+ // Results are accumulated to the first animation that animates and
+ // contributes to a particular element/attribute pair.
+ // Only reset the animated type to the base value once for
+ // the lowest priority animation that animates and
+ // contributes to a particular element/attribute pair.
+ SVGSMILElement* result_element = sandwich.front();
+ result_element->ResetAnimatedType();
+
+ // Go through the sandwich from lowest prio to highest and generate
+ // the animated value (if any.)
+ for (const auto& animation : sandwich)
+ animation->UpdateAnimatedValue(result_element);
+
+ animations_to_apply.push_back(result_element);
+ }
}
+ attribute_map.RemoveAll(invalid_keys);
}
- scheduled_animations_.RemoveAll(invalid_keys);
if (animations_to_apply.IsEmpty()) {
#if DCHECK_IS_ON()
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 3927b28f766..231d376e6b4 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
@@ -135,10 +135,11 @@ class SMILTimeContainer : public GarbageCollectedFinalized<SMILTimeContainer> {
TaskRunnerTimer<SMILTimeContainer> wakeup_timer_;
TaskRunnerTimer<SMILTimeContainer> animation_policy_once_timer_;
- using ElementAttributePair = std::pair<WeakMember<SVGElement>, QualifiedName>;
using AnimationsLinkedHashSet = HeapLinkedHashSet<WeakMember<SVGSMILElement>>;
+ using AttributeAnimationsMap =
+ HeapHashMap<QualifiedName, Member<AnimationsLinkedHashSet>>;
using GroupedAnimationsMap =
- HeapHashMap<ElementAttributePair, Member<AnimationsLinkedHashSet>>;
+ HeapHashMap<WeakMember<SVGElement>, AttributeAnimationsMap>;
GroupedAnimationsMap scheduled_animations_;
Member<SVGSVGElement> owner_svg_element_;
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 472b2eb5832..26c17905555 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
@@ -302,10 +302,10 @@ void SVGSMILElement::Reset() {
}
Node::InsertionNotificationRequest SVGSMILElement::InsertedInto(
- ContainerNode* root_parent) {
+ ContainerNode& root_parent) {
SVGElement::InsertedInto(root_parent);
- if (!root_parent->isConnected())
+ if (!root_parent.isConnected())
return kInsertionDone;
UseCounter::Count(GetDocument(), WebFeature::kSVGSMILElementInDocument);
@@ -338,8 +338,8 @@ Node::InsertionNotificationRequest SVGSMILElement::InsertedInto(
return kInsertionDone;
}
-void SVGSMILElement::RemovedFrom(ContainerNode* root_parent) {
- if (root_parent->isConnected()) {
+void SVGSMILElement::RemovedFrom(ContainerNode& root_parent) {
+ if (root_parent.isConnected()) {
ClearResourceAndEventBaseReferences();
ClearConditions();
SetTargetElement(nullptr);
@@ -1253,9 +1253,9 @@ void SVGSMILElement::DispatchPendingEvent(const AtomicString& event_type) {
if (event_type == "repeatn") {
unsigned repeat_event_count = repeat_event_count_list_.front();
repeat_event_count_list_.EraseAt(0);
- DispatchEvent(RepeatEvent::Create(event_type, repeat_event_count));
+ DispatchEvent(*RepeatEvent::Create(event_type, repeat_event_count));
} else {
- DispatchEvent(Event::Create(event_type));
+ DispatchEvent(*Event::Create(event_type));
}
}
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 410f9b04f04..b6545a42e20 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
@@ -51,8 +51,8 @@ class CORE_EXPORT SVGSMILElement : public SVGElement, public SVGTests {
void ParseAttribute(const AttributeModificationParams&) override;
void SvgAttributeChanged(const QualifiedName&) override;
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
- void RemovedFrom(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
+ void RemovedFrom(ContainerNode&) override;
virtual bool HasValidTarget();
virtual void AnimationAttributeChanged() = 0;
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 cfbb9f3b0ab..e7da7c0979a 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
@@ -187,7 +187,7 @@ IntSize SVGImage::ContainerSize() const {
return container_size;
// Assure that a container size is always given for a non-identity zoom level.
- DCHECK_EQ(layout_object->Style()->EffectiveZoom(), 1);
+ DCHECK_EQ(layout_object->StyleRef().EffectiveZoom(), 1);
// No set container size; use concrete object size.
return intrinsic_size_;
diff --git a/chromium/third_party/blink/renderer/core/svg/properties/svg_animated_property.cc b/chromium/third_party/blink/renderer/core/svg/properties/svg_animated_property.cc
index da86da6e6bd..6615fdd8e87 100644
--- a/chromium/third_party/blink/renderer/core/svg/properties/svg_animated_property.cc
+++ b/chromium/third_party/blink/renderer/core/svg/properties/svg_animated_property.cc
@@ -44,6 +44,7 @@ SVGAnimatedPropertyBase::SVGAnimatedPropertyBase(
// property enum. CSS properties that don't fit in this bitfield are never
// used here. See static_assert in header.
css_property_id_(static_cast<unsigned>(css_property_id)),
+ base_value_needs_synchronization_(false),
context_element_(context_element),
attribute_name_(attribute_name) {
DCHECK(context_element_);
@@ -54,17 +55,43 @@ SVGAnimatedPropertyBase::SVGAnimatedPropertyBase(
SVGAnimatedPropertyBase::~SVGAnimatedPropertyBase() = default;
+void SVGAnimatedPropertyBase::Trace(Visitor* visitor) {
+ visitor->Trace(context_element_);
+}
+
void SVGAnimatedPropertyBase::AnimationEnded() {
SynchronizeAttribute();
}
+bool SVGAnimatedPropertyBase::NeedsSynchronizeAttribute() const {
+ // DOM attribute synchronization is only needed if a change has been made
+ // through JavaScript (via a tear-off or primitive) or the property is being
+ // animated. This prevents unnecessary attribute creation on the target
+ // element.
+ return base_value_needs_synchronization_ || IsAnimating();
+}
+
void SVGAnimatedPropertyBase::SynchronizeAttribute() {
AtomicString value(CurrentValueBase()->ValueAsString());
context_element_->SetSynchronizedLazyAttribute(attribute_name_, value);
+ base_value_needs_synchronization_ = false;
+}
+
+void SVGAnimatedPropertyBase::BaseValueChanged() {
+ DCHECK(context_element_);
+ DCHECK(attribute_name_ != QualifiedName::Null());
+ base_value_needs_synchronization_ = true;
+ context_element_->InvalidateSVGAttributes();
+ context_element_->SvgAttributeBaseValChanged(attribute_name_);
+}
+
+void SVGAnimatedPropertyBase::EnsureAnimValUpdated() {
+ DCHECK(context_element_);
+ context_element_->EnsureAttributeAnimValUpdated();
}
bool SVGAnimatedPropertyBase::IsSpecified() const {
- return IsAnimating() || contextElement()->hasAttribute(AttributeName());
+ return IsAnimating() || ContextElement()->hasAttribute(AttributeName());
}
} // namespace blink
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 4032183191d..57d4047c136 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
@@ -32,10 +32,13 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_SVG_PROPERTIES_SVG_ANIMATED_PROPERTY_H_
#include "base/macros.h"
+#include "third_party/blink/renderer/core/css_property_names.h"
+#include "third_party/blink/renderer/core/dom/qualified_name.h"
#include "third_party/blink/renderer/core/svg/properties/svg_property_info.h"
#include "third_party/blink/renderer/core/svg/properties/svg_property_tear_off.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/bindings/trace_wrapper_member.h"
+#include "third_party/blink/renderer/platform/heap/member.h"
namespace blink {
@@ -54,15 +57,15 @@ class SVGAnimatedPropertyBase : public GarbageCollectedMixin {
virtual void SetAnimatedValue(SVGPropertyBase*) = 0;
virtual void AnimationEnded();
- virtual SVGParsingError SetBaseValueAsString(const String&) = 0;
- virtual bool NeedsSynchronizeAttribute() = 0;
+ virtual SVGParsingError AttributeChanged(const String&) = 0;
+ virtual bool NeedsSynchronizeAttribute() const;
virtual void SynchronizeAttribute();
AnimatedPropertyType GetType() const {
return static_cast<AnimatedPropertyType>(type_);
}
- SVGElement* contextElement() const { return context_element_; }
+ SVGElement* ContextElement() const { return context_element_; }
const QualifiedName& AttributeName() const { return attribute_name_; }
@@ -76,9 +79,10 @@ class SVGAnimatedPropertyBase : public GarbageCollectedMixin {
bool IsSpecified() const;
- void Trace(blink::Visitor* visitor) override {
- visitor->Trace(context_element_);
- }
+ void Trace(Visitor*) override;
+
+ void BaseValueChanged();
+ void EnsureAnimValUpdated();
protected:
SVGAnimatedPropertyBase(AnimatedPropertyType,
@@ -86,6 +90,10 @@ class SVGAnimatedPropertyBase : public GarbageCollectedMixin {
const QualifiedName& attribute_name,
CSSPropertyID = CSSPropertyInvalid);
+ void ClearBaseValueNeedsSynchronization() {
+ base_value_needs_synchronization_ = false;
+ }
+
private:
static_assert(kNumberOfAnimatedPropertyTypes <= (1u << 5),
"enough bits for AnimatedPropertyType (type_)");
@@ -95,6 +103,7 @@ class SVGAnimatedPropertyBase : public GarbageCollectedMixin {
const unsigned type_ : 5;
const unsigned css_property_id_ : kCssPropertyBits;
+ unsigned base_value_needs_synchronization_ : 1;
TraceWrapperMember<SVGElement> context_element_;
const QualifiedName& attribute_name_;
DISALLOW_COPY_AND_ASSIGN(SVGAnimatedPropertyBase);
@@ -119,7 +128,8 @@ class SVGAnimatedPropertyCommon : public SVGAnimatedPropertyBase {
bool IsAnimating() const override { return current_value_; }
- SVGParsingError SetBaseValueAsString(const String& value) override {
+ SVGParsingError AttributeChanged(const String& value) override {
+ ClearBaseValueNeedsSynchronization();
return base_value_->SetValueAsString(value);
}
@@ -168,18 +178,6 @@ template <typename Property,
typename PrimitiveType = typename Property::PrimitiveType>
class SVGAnimatedProperty : public SVGAnimatedPropertyCommon<Property> {
public:
- bool NeedsSynchronizeAttribute() override {
- // DOM attribute synchronization is only needed if tear-off is being touched
- // from javascript or the property is being animated. This prevents
- // unnecessary attribute creation on target element.
- return base_value_updated_ || this->IsAnimating();
- }
-
- void SynchronizeAttribute() override {
- SVGAnimatedPropertyBase::SynchronizeAttribute();
- base_value_updated_ = false;
- }
-
// SVGAnimated* DOM Spec implementations:
// baseVal()/setBaseVal()/animVal() are only to be used from SVG DOM
@@ -188,15 +186,11 @@ class SVGAnimatedProperty : public SVGAnimatedPropertyCommon<Property> {
void setBaseVal(PrimitiveType value, ExceptionState&) {
this->BaseValue()->SetValue(value);
- base_value_updated_ = true;
-
- DCHECK(this->AttributeName() != QualifiedName::Null());
- this->contextElement()->InvalidateSVGAttributes();
- this->contextElement()->SvgAttributeBaseValChanged(this->AttributeName());
+ this->BaseValueChanged();
}
PrimitiveType animVal() {
- this->contextElement()->EnsureAttributeAnimValUpdated();
+ this->EnsureAnimValUpdated();
return this->CurrentValue()->Value();
}
@@ -208,10 +202,7 @@ class SVGAnimatedProperty : public SVGAnimatedPropertyCommon<Property> {
: SVGAnimatedPropertyCommon<Property>(context_element,
attribute_name,
initial_value,
- css_property_id),
- base_value_updated_(false) {}
-
- bool base_value_updated_;
+ css_property_id) {}
};
// Implementation of SVGAnimatedProperty which uses tear-off value types.
@@ -241,13 +232,6 @@ class SVGAnimatedProperty<Property, TearOffType, void>
UpdateAnimValTearOffIfNeeded();
}
- bool NeedsSynchronizeAttribute() override {
- // DOM attribute synchronization is only needed if tear-off is being touched
- // from javascript or the property is being animated. This prevents
- // unnecessary attribute creation on target element.
- return base_val_tear_off_ || this->IsAnimating();
- }
-
// SVGAnimated* DOM Spec implementations:
// baseVal()/animVal() are only to be used from SVG DOM implementation.
@@ -255,8 +239,7 @@ class SVGAnimatedProperty<Property, TearOffType, void>
virtual TearOffType* baseVal() {
if (!base_val_tear_off_) {
base_val_tear_off_ =
- TearOffType::Create(this->BaseValue(), this->contextElement(),
- kPropertyIsNotAnimVal, this->AttributeName());
+ TearOffType::Create(this->BaseValue(), this, kPropertyIsNotAnimVal);
}
return base_val_tear_off_;
}
@@ -264,8 +247,7 @@ class SVGAnimatedProperty<Property, TearOffType, void>
TearOffType* animVal() {
if (!anim_val_tear_off_) {
anim_val_tear_off_ =
- TearOffType::Create(this->CurrentValue(), this->contextElement(),
- kPropertyIsAnimVal, this->AttributeName());
+ TearOffType::Create(this->CurrentValue(), this, kPropertyIsAnimVal);
}
return anim_val_tear_off_;
}
@@ -317,12 +299,6 @@ class SVGAnimatedProperty<Property, void, void>
initial_value, css_property_id);
}
- bool NeedsSynchronizeAttribute() override {
- // DOM attribute synchronization is only needed if the property is being
- // animated.
- return this->IsAnimating();
- }
-
protected:
SVGAnimatedProperty(SVGElement* context_element,
const QualifiedName& attribute_name,
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 8bb717a88e0..7cc6aabb077 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
@@ -137,6 +137,8 @@ class SVGListPropertyHelper : public SVGPropertyHelper<Derived> {
float percentage,
AnimationMode);
+ String SerializeList() const;
+
virtual ItemPropertyType* CreatePaddingItem() const {
return ItemPropertyType::Create();
}
@@ -224,17 +226,6 @@ ItemProperty* SVGListPropertyHelper<Derived, ItemProperty>::ReplaceItem(
if (!CheckIndexBound(index, exception_state))
return nullptr;
- if (values_.IsEmpty()) {
- // 'newItem' already lived in our list, we removed it, and now we're empty,
- // which means there's nothing to replace.
- // TODO(fs): This should not cause us to throw an exception.
- exception_state.ThrowDOMException(
- DOMExceptionCode::kIndexSizeError,
- String::Format("Failed to replace the provided item at index %zu.",
- index));
- return nullptr;
- }
-
// Update the value at the desired position 'index'.
Member<ItemPropertyType>& position = values_[index];
DCHECK_EQ(position->OwnerList(), this);
@@ -251,8 +242,8 @@ bool SVGListPropertyHelper<Derived, ItemProperty>::CheckIndexBound(
if (index >= values_.size()) {
exception_state.ThrowDOMException(
DOMExceptionCode::kIndexSizeError,
- ExceptionMessages::IndexExceedsMaximumBound("index", index,
- values_.size()));
+ ExceptionMessages::IndexExceedsMaximumBound(
+ "index", index, static_cast<size_t>(values_.size())));
return false;
}
return true;
@@ -296,6 +287,24 @@ bool SVGListPropertyHelper<Derived, ItemProperty>::AdjustFromToListValues(
return true;
}
+template <typename Derived, typename ItemProperty>
+String SVGListPropertyHelper<Derived, ItemProperty>::SerializeList() const {
+ if (values_.IsEmpty())
+ return String();
+
+ StringBuilder builder;
+
+ auto it = values_.begin();
+ auto it_end = values_.end();
+ while (it != it_end) {
+ builder.Append((*it)->ValueAsString());
+ ++it;
+ if (it != it_end)
+ builder.Append(' ');
+ }
+ return builder.ToString();
+}
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_SVG_PROPERTIES_SVG_LIST_PROPERTY_HELPER_H_
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 78aa5bab91b..f9104dc7090 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
@@ -46,8 +46,7 @@ class ListItemPropertyTraits {
static ItemPropertyType* GetValueForInsertionFromTearOff(
ItemTearOffType* new_item,
- SVGElement* context_element,
- const QualifiedName& attribute_name) {
+ SVGAnimatedPropertyBase* binding) {
// |newItem| is immutable, OR
// |newItem| belongs to a SVGElement, but it does not belong to an animated
// list, e.g. "textElement.x.baseVal.appendItem(rectElement.width.baseVal)"
@@ -55,7 +54,7 @@ class ListItemPropertyTraits {
// the same values as newItem and this item is inserted into the list.
// Otherwise, newItem itself is inserted into the list.
if (new_item->IsImmutable() || new_item->Target()->OwnerList() ||
- new_item->contextElement()) {
+ new_item->ContextElement()) {
// We have to copy the incoming |newItem|,
// Otherwise we'll end up having two tearoffs that operate on the same
// SVGProperty. Consider the example below: SVGRectElements
@@ -67,17 +66,15 @@ class ListItemPropertyTraits {
return new_item->Target()->Clone();
}
- new_item->AttachToSVGElementAttribute(context_element, attribute_name);
+ new_item->Bind(binding);
return new_item->Target();
}
static ItemTearOffType* CreateTearOff(
ItemPropertyType* value,
- SVGElement* context_element,
- PropertyIsAnimValType property_is_anim_val,
- const QualifiedName& attribute_name) {
- return ItemTearOffType::Create(value, context_element, property_is_anim_val,
- attribute_name);
+ SVGAnimatedPropertyBase* binding,
+ PropertyIsAnimValType property_is_anim_val) {
+ return ItemTearOffType::Create(value, binding, property_is_anim_val);
}
};
@@ -100,6 +97,7 @@ class SVGListPropertyTearOffHelper : public SVGPropertyTearOff<ListProperty> {
return;
}
ToDerived()->Target()->Clear();
+ ToDerived()->CommitChange();
}
ItemTearOffType* initialize(ItemTearOffType* item,
@@ -183,32 +181,27 @@ class SVGListPropertyTearOffHelper : public SVGPropertyTearOff<ListProperty> {
}
protected:
- SVGListPropertyTearOffHelper(
- ListPropertyType* target,
- SVGElement* context_element,
- PropertyIsAnimValType property_is_anim_val,
- const QualifiedName& attribute_name = QualifiedName::Null())
+ SVGListPropertyTearOffHelper(ListPropertyType* target,
+ SVGAnimatedPropertyBase* binding,
+ PropertyIsAnimValType property_is_anim_val)
: SVGPropertyTearOff<ListPropertyType>(target,
- context_element,
- property_is_anim_val,
- attribute_name) {}
+ binding,
+ property_is_anim_val) {}
ItemPropertyType* GetValueForInsertionFromTearOff(ItemTearOffType* new_item) {
return ItemTraits::GetValueForInsertionFromTearOff(
- new_item, ToDerived()->contextElement(), ToDerived()->AttributeName());
+ new_item, ToDerived()->GetBinding());
}
ItemTearOffType* CreateItemTearOff(ItemPropertyType* value) {
if (!value)
return nullptr;
- if (value->OwnerList() == ToDerived()->Target())
- return ItemTraits::CreateTearOff(value, ToDerived()->contextElement(),
- ToDerived()->PropertyIsAnimVal(),
- ToDerived()->AttributeName());
-
- return ItemTraits::CreateTearOff(value, nullptr, kPropertyIsNotAnimVal,
- QualifiedName::Null());
+ if (value->OwnerList() == ToDerived()->Target()) {
+ return ItemTraits::CreateTearOff(value, ToDerived()->GetBinding(),
+ ToDerived()->PropertyIsAnimVal());
+ }
+ return ItemTraits::CreateTearOff(value, nullptr, kPropertyIsNotAnimVal);
}
private:
diff --git a/chromium/third_party/blink/renderer/core/svg/properties/svg_property_tear_off.cc b/chromium/third_party/blink/renderer/core/svg/properties/svg_property_tear_off.cc
index d3a40e45d37..1db1f82f94f 100644
--- a/chromium/third_party/blink/renderer/core/svg/properties/svg_property_tear_off.cc
+++ b/chromium/third_party/blink/renderer/core/svg/properties/svg_property_tear_off.cc
@@ -30,25 +30,59 @@
#include "third_party/blink/renderer/core/svg/properties/svg_property_tear_off.h"
+#include "third_party/blink/renderer/core/svg/properties/svg_animated_property.h"
#include "third_party/blink/renderer/core/svg/svg_element.h"
#include "third_party/blink/renderer/platform/bindings/exception_messages.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
namespace blink {
+SVGPropertyTearOffBase::SVGPropertyTearOffBase(
+ SVGAnimatedPropertyBase* binding,
+ PropertyIsAnimValType property_is_anim_val)
+ : context_element_(binding ? binding->ContextElement() : nullptr),
+ binding_(binding),
+ property_is_anim_val_(property_is_anim_val) {}
+
+SVGPropertyTearOffBase::SVGPropertyTearOffBase(SVGElement* context_element)
+ : context_element_(context_element),
+ binding_(nullptr),
+ property_is_anim_val_(kPropertyIsNotAnimVal) {}
+
+void SVGPropertyTearOffBase::Trace(Visitor* visitor) {
+ visitor->Trace(context_element_);
+ visitor->Trace(binding_);
+ ScriptWrappable::Trace(visitor);
+}
+
void SVGPropertyTearOffBase::ThrowReadOnly(ExceptionState& exception_state) {
exception_state.ThrowDOMException(
DOMExceptionCode::kNoModificationAllowedError,
ExceptionMessages::ReadOnly());
}
+void SVGPropertyTearOffBase::Bind(SVGAnimatedPropertyBase* binding) {
+ DCHECK(!IsImmutable());
+ DCHECK(binding);
+ DCHECK(binding->ContextElement());
+ context_element_ = binding->ContextElement();
+ binding_ = binding;
+}
+
void SVGPropertyTearOffBase::CommitChange() {
+ // Immutable (or animVal) objects should never mutate, so this hook should
+ // never be called in those cases.
DCHECK(!IsImmutable());
- if (!contextElement() || IsAnimVal())
+ DCHECK(!IsAnimVal());
+ if (!binding_)
return;
- DCHECK(attribute_name_ != QualifiedName::Null());
- contextElement()->InvalidateSVGAttributes();
- contextElement()->SvgAttributeBaseValChanged(attribute_name_);
+ binding_->BaseValueChanged();
+}
+
+void SVGPropertyTearOffBase::EnsureAnimValUpdated() {
+ DCHECK(IsImmutable());
+ DCHECK(binding_);
+ binding_->EnsureAnimValUpdated();
}
} // namespace blink
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 d1107a4a36e..8b857a28fe9 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
@@ -31,15 +31,16 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SVG_PROPERTIES_SVG_PROPERTY_TEAR_OFF_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_SVG_PROPERTIES_SVG_PROPERTY_TEAR_OFF_H_
-#include "third_party/blink/renderer/core/dom/qualified_name.h"
#include "third_party/blink/renderer/core/svg/properties/svg_property.h"
-#include "third_party/blink/renderer/core/svg/svg_element.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+#include "third_party/blink/renderer/platform/bindings/trace_wrapper_member.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
namespace blink {
class ExceptionState;
+class SVGAnimatedPropertyBase;
+class SVGElement;
enum PropertyIsAnimValType { kPropertyIsNotAnimVal, kPropertyIsAnimVal };
@@ -56,42 +57,26 @@ class SVGPropertyTearOffBase : public ScriptWrappable {
virtual void CommitChange();
- SVGElement* contextElement() const { return context_element_; }
+ SVGAnimatedPropertyBase* GetBinding() { return binding_; }
+ SVGElement* ContextElement() const { return context_element_; }
- const QualifiedName& AttributeName() { return attribute_name_; }
+ void Bind(SVGAnimatedPropertyBase* binding);
- void AttachToSVGElementAttribute(SVGElement* context_element,
- const QualifiedName& attribute_name) {
- DCHECK(!IsImmutable());
- DCHECK(context_element);
- DCHECK(attribute_name != QualifiedName::Null());
- context_element_ = context_element;
- // Requires SVGPropertyTearOffBase to be the left-most class in the
- // inheritance hierarchy.
- ScriptWrappableMarkingVisitor::WriteBarrier(context_element_.Get());
- attribute_name_ = attribute_name;
- }
-
- void Trace(blink::Visitor* visitor) override {
- visitor->Trace(context_element_);
- ScriptWrappable::Trace(visitor);
- }
+ void Trace(Visitor*) override;
static void ThrowReadOnly(ExceptionState&);
protected:
- SVGPropertyTearOffBase(SVGElement* context_element,
- PropertyIsAnimValType property_is_anim_val,
- const QualifiedName& attribute_name)
- : context_element_(context_element),
- property_is_anim_val_(property_is_anim_val),
- attribute_name_(attribute_name) {}
+ SVGPropertyTearOffBase(SVGAnimatedPropertyBase* binding,
+ PropertyIsAnimValType property_is_anim_val);
+ SVGPropertyTearOffBase(SVGElement* context_element);
+
+ void EnsureAnimValUpdated();
private:
TraceWrapperMember<SVGElement> context_element_;
-
+ Member<SVGAnimatedPropertyBase> binding_;
PropertyIsAnimValType property_is_anim_val_;
- QualifiedName attribute_name_;
};
template <typename Property>
@@ -99,7 +84,7 @@ class SVGPropertyTearOff : public SVGPropertyTearOffBase {
public:
Property* Target() {
if (IsAnimVal())
- contextElement()->EnsureAttributeAnimValUpdated();
+ EnsureAnimValUpdated();
return target_.Get();
}
@@ -113,13 +98,13 @@ class SVGPropertyTearOff : public SVGPropertyTearOffBase {
protected:
SVGPropertyTearOff(Property* target,
- SVGElement* context_element,
- PropertyIsAnimValType property_is_anim_val,
- const QualifiedName& attribute_name)
- : SVGPropertyTearOffBase(context_element,
- property_is_anim_val,
- attribute_name),
- target_(target) {
+ SVGAnimatedPropertyBase* binding,
+ PropertyIsAnimValType property_is_anim_val)
+ : SVGPropertyTearOffBase(binding, property_is_anim_val), target_(target) {
+ DCHECK(target_);
+ }
+ SVGPropertyTearOff(Property* target, SVGElement* context_element)
+ : SVGPropertyTearOffBase(context_element), target_(target) {
DCHECK(target_);
}
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 a6328c0ec3d..14afe3d3752 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
@@ -104,11 +104,11 @@ LayoutObject* SVGAElement::CreateLayoutObject(const ComputedStyle&) {
return new LayoutSVGTransformableContainer(this);
}
-void SVGAElement::DefaultEventHandler(Event* event) {
+void SVGAElement::DefaultEventHandler(Event& event) {
if (IsLink()) {
if (IsFocused() && IsEnterKeyKeydownEvent(event)) {
- event->SetDefaultHandled();
- DispatchSimulatedClick(event);
+ event.SetDefaultHandled();
+ DispatchSimulatedClick(&event);
return;
}
@@ -120,7 +120,7 @@ void SVGAElement::DefaultEventHandler(Event* event) {
GetTreeScope().getElementById(AtomicString(url.Substring(1)));
if (target_element && IsSVGSMILElement(*target_element)) {
ToSVGSMILElement(target_element)->BeginByLinkActivation();
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
return;
}
}
@@ -128,7 +128,7 @@ void SVGAElement::DefaultEventHandler(Event* event) {
AtomicString target(svg_target_->CurrentValue()->Value());
if (target.IsEmpty() && FastGetAttribute(XLinkNames::showAttr) == "new")
target = AtomicString("_blank");
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
LocalFrame* frame = GetDocument().GetFrame();
if (!frame)
@@ -137,11 +137,11 @@ void SVGAElement::DefaultEventHandler(Event* event) {
&GetDocument(), ResourceRequest(GetDocument().CompleteURL(url)),
target);
frame_request.SetTriggeringEventInfo(
- event->isTrusted() ? WebTriggeringEventInfo::kFromTrustedEvent
- : WebTriggeringEventInfo::kFromUntrustedEvent);
+ event.isTrusted() ? WebTriggeringEventInfo::kFromTrustedEvent
+ : WebTriggeringEventInfo::kFromUntrustedEvent);
frame->Loader().StartNavigation(frame_request,
WebFrameLoadType::kStandard,
- NavigationPolicyFromEvent(event));
+ NavigationPolicyFromEvent(&event));
return;
}
}
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 1743279b89e..d6d7e1592cb 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
@@ -48,7 +48,7 @@ class CORE_EXPORT SVGAElement final : public SVGGraphicsElement,
LayoutObject* CreateLayoutObject(const ComputedStyle&) override;
- void DefaultEventHandler(Event*) override;
+ void DefaultEventHandler(Event&) override;
bool HasActivationBehavior() const override;
bool IsLiveLink() const override { return IsLink(); }
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_angle_tear_off.cc b/chromium/third_party/blink/renderer/core/svg/svg_angle_tear_off.cc
index c518e19eb2c..7683bd3e514 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_angle_tear_off.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_angle_tear_off.cc
@@ -30,19 +30,16 @@
#include "third_party/blink/renderer/core/svg/svg_angle_tear_off.h"
-#include "third_party/blink/renderer/core/svg/svg_element.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
namespace blink {
SVGAngleTearOff::SVGAngleTearOff(SVGAngle* target_property,
- SVGElement* context_element,
- PropertyIsAnimValType property_is_anim_val,
- const QualifiedName& attribute_name)
+ SVGAnimatedPropertyBase* binding,
+ PropertyIsAnimValType property_is_anim_val)
: SVGPropertyTearOff<SVGAngle>(target_property,
- context_element,
- property_is_anim_val,
- attribute_name) {}
+ binding,
+ property_is_anim_val) {}
SVGAngleTearOff::~SVGAngleTearOff() = default;
@@ -133,8 +130,7 @@ void SVGAngleTearOff::setValueAsString(const String& value,
}
SVGAngleTearOff* SVGAngleTearOff::CreateDetached() {
- return Create(SVGAngle::Create(), nullptr, kPropertyIsNotAnimVal,
- QualifiedName::Null());
+ return Create(SVGAngle::Create(), nullptr, kPropertyIsNotAnimVal);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_angle_tear_off.h b/chromium/third_party/blink/renderer/core/svg/svg_angle_tear_off.h
index 5a9cc686826..951cf98744a 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_angle_tear_off.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_angle_tear_off.h
@@ -41,11 +41,9 @@ class SVGAngleTearOff final : public SVGPropertyTearOff<SVGAngle> {
public:
static SVGAngleTearOff* Create(SVGAngle* target,
- SVGElement* context_element,
- PropertyIsAnimValType property_is_anim_val,
- const QualifiedName& attribute_name) {
- return new SVGAngleTearOff(target, context_element, property_is_anim_val,
- attribute_name);
+ SVGAnimatedPropertyBase* binding,
+ PropertyIsAnimValType property_is_anim_val) {
+ return new SVGAngleTearOff(target, binding, property_is_anim_val);
}
static SVGAngleTearOff* CreateDetached();
@@ -83,9 +81,8 @@ class SVGAngleTearOff final : public SVGPropertyTearOff<SVGAngle> {
private:
SVGAngleTearOff(SVGAngle*,
- SVGElement*,
- PropertyIsAnimValType,
- const QualifiedName&);
+ SVGAnimatedPropertyBase* binding,
+ PropertyIsAnimValType);
bool HasExposedAngleUnit() {
return Target()->UnitType() <= SVGAngle::kSvgAngletypeGrad;
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 74905760299..a642c1cc0ac 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
@@ -136,17 +136,17 @@ bool SVGAnimateElement::IsSVGAnimationAttributeSettingJavaScriptURL(
}
Node::InsertionNotificationRequest SVGAnimateElement::InsertedInto(
- ContainerNode* root_parent) {
+ ContainerNode& root_parent) {
SVGAnimationElement::InsertedInto(root_parent);
- if (root_parent->isConnected()) {
+ if (root_parent.isConnected()) {
SetAttributeName(ConstructQualifiedName(
*this, FastGetAttribute(SVGNames::attributeNameAttr)));
}
return kInsertionDone;
}
-void SVGAnimateElement::RemovedFrom(ContainerNode* root_parent) {
- if (root_parent->isConnected())
+void SVGAnimateElement::RemovedFrom(ContainerNode& root_parent) {
+ if (root_parent.isConnected())
SetAttributeName(AnyQName());
SVGAnimationElement::RemovedFrom(root_parent);
}
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 4f344be0a72..0a300c31b9e 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
@@ -98,8 +98,8 @@ class CORE_EXPORT SVGAnimateElement : public SVGAnimationElement {
void SetAttributeType(const AtomicString&);
- InsertionNotificationRequest InsertedInto(ContainerNode*) final;
- void RemovedFrom(ContainerNode*) final;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) final;
+ void RemovedFrom(ContainerNode&) final;
virtual void ResolveTargetProperty();
void ClearTargetProperty();
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 9769ff07fe3..47ddc36a7e5 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
@@ -51,7 +51,7 @@ void SVGAnimatedAngle::Trace(blink::Visitor* visitor) {
ScriptWrappable::Trace(visitor);
}
-bool SVGAnimatedAngle::NeedsSynchronizeAttribute() {
+bool SVGAnimatedAngle::NeedsSynchronizeAttribute() const {
return orient_type_->NeedsSynchronizeAttribute() ||
SVGAnimatedProperty<SVGAngle>::NeedsSynchronizeAttribute();
}
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 4015b78b385..3e8761e6faf 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
@@ -55,7 +55,7 @@ class SVGAnimatedAngle final : public ScriptWrappable,
}
// SVGAnimatedPropertyBase:
- bool NeedsSynchronizeAttribute() override;
+ bool NeedsSynchronizeAttribute() const override;
void SynchronizeAttribute() override;
void SetAnimatedValue(SVGPropertyBase*) override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_enumeration_base.cc b/chromium/third_party/blink/renderer/core/svg/svg_animated_enumeration_base.cc
index 525251a00a7..2f3be22d5b9 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_animated_enumeration_base.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_enumeration_base.cc
@@ -30,7 +30,6 @@
#include "third_party/blink/renderer/core/svg/svg_animated_enumeration_base.h"
-#include "third_party/blink/renderer/core/svg/svg_element.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_href.cc b/chromium/third_party/blink/renderer/core/svg/svg_animated_href.cc
index 391bc60b0c8..2cfdfe71a05 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
@@ -44,20 +44,20 @@ const SVGString* SVGAnimatedHref::CurrentValue() const {
}
String SVGAnimatedHref::baseVal() {
- UseCounter::Count(contextElement()->GetDocument(),
+ UseCounter::Count(ContextElement()->GetDocument(),
WebFeature::kSVGHrefBaseVal);
return BackingString()->SVGAnimatedString::baseVal();
}
void SVGAnimatedHref::setBaseVal(const String& value,
ExceptionState& exception_state) {
- UseCounter::Count(contextElement()->GetDocument(),
+ UseCounter::Count(ContextElement()->GetDocument(),
WebFeature::kSVGHrefBaseVal);
return BackingString()->SVGAnimatedString::setBaseVal(value, exception_state);
}
String SVGAnimatedHref::animVal() {
- UseCounter::Count(contextElement()->GetDocument(),
+ UseCounter::Count(ContextElement()->GetDocument(),
WebFeature::kSVGHrefAnimVal);
return BackingString()->SVGAnimatedString::animVal();
}
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 fd690d339ab..1b311097ddb 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
@@ -31,7 +31,6 @@
#include "third_party/blink/renderer/core/svg/svg_animated_integer.h"
#include "third_party/blink/renderer/core/svg/svg_animated_integer_optional_integer.h"
-#include "third_party/blink/renderer/core/svg/svg_element.h"
namespace blink {
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 3016a0725f1..9d4b1ceb9a7 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
@@ -30,8 +30,6 @@
#include "third_party/blink/renderer/core/svg/svg_animated_integer_optional_integer.h"
-#include "third_party/blink/renderer/core/svg/svg_element.h"
-
namespace blink {
SVGAnimatedIntegerOptionalInteger::SVGAnimatedIntegerOptionalInteger(
@@ -75,7 +73,7 @@ void SVGAnimatedIntegerOptionalInteger::AnimationEnded() {
second_integer_->AnimationEnded();
}
-bool SVGAnimatedIntegerOptionalInteger::NeedsSynchronizeAttribute() {
+bool SVGAnimatedIntegerOptionalInteger::NeedsSynchronizeAttribute() const {
return first_integer_->NeedsSynchronizeAttribute() ||
second_integer_->NeedsSynchronizeAttribute();
}
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 061edcea405..09e6942ae26 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
}
void SetAnimatedValue(SVGPropertyBase*) override;
- bool NeedsSynchronizeAttribute() override;
+ bool NeedsSynchronizeAttribute() const override;
void AnimationEnded() override;
SVGAnimatedInteger* FirstInteger() { return first_integer_.Get(); }
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 b44a605ebd1..e1d5587832e 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
@@ -38,8 +38,9 @@ void SVGAnimatedLength::SetDefaultValueAsString(const String& value) {
BaseValue()->SetValueAsString(value);
}
-SVGParsingError SVGAnimatedLength::SetBaseValueAsString(const String& value) {
- SVGParsingError parse_status = BaseValue()->SetValueAsString(value);
+SVGParsingError SVGAnimatedLength::AttributeChanged(const String& value) {
+ SVGParsingError parse_status =
+ SVGAnimatedProperty<SVGLength>::AttributeChanged(value);
if (parse_status != SVGParseStatus::kNoError)
BaseValue()->NewValueSpecifiedUnits(CSSPrimitiveValue::UnitType::kUserUnits,
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 eab3f978005..9384ee5bf59 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
@@ -53,7 +53,7 @@ class SVGAnimatedLength : public ScriptWrappable,
}
void SetDefaultValueAsString(const String&);
- SVGParsingError SetBaseValueAsString(const String&) override;
+ SVGParsingError AttributeChanged(const String&) override;
const CSSValue& CssValue() const {
return CurrentValue()->AsCSSPrimitiveValue();
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 c712644904f..04abbd92fbb 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
@@ -31,7 +31,6 @@
#include "third_party/blink/renderer/core/svg/svg_animated_number.h"
#include "third_party/blink/renderer/core/svg/svg_animated_number_optional_number.h"
-#include "third_party/blink/renderer/core/svg/svg_element.h"
namespace blink {
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 15281345e77..86d0c73a7d3 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
@@ -19,8 +19,6 @@
#include "third_party/blink/renderer/core/svg/svg_animated_number_optional_number.h"
-#include "third_party/blink/renderer/core/svg/svg_element.h"
-
namespace blink {
SVGAnimatedNumberOptionalNumber::SVGAnimatedNumberOptionalNumber(
@@ -62,7 +60,7 @@ void SVGAnimatedNumberOptionalNumber::AnimationEnded() {
second_number_->AnimationEnded();
}
-bool SVGAnimatedNumberOptionalNumber::NeedsSynchronizeAttribute() {
+bool SVGAnimatedNumberOptionalNumber::NeedsSynchronizeAttribute() const {
return first_number_->NeedsSynchronizeAttribute() ||
second_number_->NeedsSynchronizeAttribute();
}
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 27f46eaff4f..a8170da3048 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
}
void SetAnimatedValue(SVGPropertyBase*) override;
- bool NeedsSynchronizeAttribute() override;
+ bool NeedsSynchronizeAttribute() const override;
void AnimationEnded() override;
SVGAnimatedNumber* FirstNumber() { return first_number_.Get(); }
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 10d501be602..7c1efbcf948 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
@@ -127,11 +127,6 @@ void SVGDocumentExtensions::RemoveSVGRootWithRelativeLengthDescendents(
relative_length_svg_roots_.erase(svg_root);
}
-bool SVGDocumentExtensions::IsSVGRootWithRelativeLengthDescendents(
- SVGSVGElement* svg_root) const {
- return relative_length_svg_roots_.Contains(svg_root);
-}
-
void SVGDocumentExtensions::InvalidateSVGRootsWithRelativeLengthDescendents(
SubtreeLayoutScope* scope) {
#if DCHECK_IS_ON()
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 817b1d7e1c7..7972d0aff3a 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
@@ -60,7 +60,6 @@ class SVGDocumentExtensions
void AddSVGRootWithRelativeLengthDescendents(SVGSVGElement*);
void RemoveSVGRootWithRelativeLengthDescendents(SVGSVGElement*);
- bool IsSVGRootWithRelativeLengthDescendents(SVGSVGElement*) const;
void InvalidateSVGRootsWithRelativeLengthDescendents(SubtreeLayoutScope*);
bool ZoomAndPanEnabled() const;
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 e9a1fd9dd0e..8f49111f42c 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_element.cc
@@ -312,17 +312,6 @@ static inline bool TransformUsesBoxSize(const ComputedStyle& style) {
static FloatRect ComputeTransformReferenceBox(const SVGElement& element) {
const LayoutObject& layout_object = *element.GetLayoutObject();
const ComputedStyle& style = layout_object.StyleRef();
- if (!RuntimeEnabledFeatures::CSSTransformBoxEnabled()) {
- FloatRect reference_box = layout_object.ObjectBoundingBox();
- // Set the reference origin to zero when transform-origin (x/y) has a
- // non-percentage unit.
- const TransformOrigin& transform_origin = style.GetTransformOrigin();
- if (transform_origin.X().GetType() != kPercent)
- reference_box.SetX(0);
- if (transform_origin.Y().GetType() != kPercent)
- reference_box.SetY(0);
- return reference_box;
- }
if (style.TransformBox() == ETransformBox::kFillBox)
return layout_object.ObjectBoundingBox();
DCHECK_EQ(style.TransformBox(), ETransformBox::kViewBox);
@@ -378,7 +367,7 @@ AffineTransform SVGElement::CalculateTransform(
}
Node::InsertionNotificationRequest SVGElement::InsertedInto(
- ContainerNode* root_parent) {
+ ContainerNode& root_parent) {
Element::InsertedInto(root_parent);
UpdateRelativeLengthsInformation();
@@ -393,26 +382,26 @@ Node::InsertionNotificationRequest SVGElement::InsertedInto(
return kInsertionDone;
}
-void SVGElement::RemovedFrom(ContainerNode* root_parent) {
- bool was_in_document = root_parent->isConnected();
+void SVGElement::RemovedFrom(ContainerNode& root_parent) {
+ bool was_in_document = root_parent.isConnected();
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->IsSVGElement() && !parentNode()) {
+ if (root_parent.IsSVGElement() && !parentNode()) {
DCHECK(ToSVGElement(root_parent)
- ->elements_with_relative_lengths_.Contains(this));
- ToSVGElement(root_parent)->UpdateRelativeLengthsInformation(false, this);
+ .elements_with_relative_lengths_.Contains(this));
+ ToSVGElement(root_parent).UpdateRelativeLengthsInformation(false, this);
}
elements_with_relative_lengths_.clear();
}
- SECURITY_DCHECK(!root_parent->IsSVGElement() ||
+ SECURITY_DCHECK(!root_parent.IsSVGElement() ||
!ToSVGElement(root_parent)
- ->elements_with_relative_lengths_.Contains(this));
+ .elements_with_relative_lengths_.Contains(this));
Element::RemovedFrom(root_parent);
@@ -682,36 +671,30 @@ bool SVGElement::InUseShadowTree() const {
}
void SVGElement::ParseAttribute(const AttributeModificationParams& params) {
+ // Note about the 'class' attribute:
+ // The "special storage" (SVGAnimatedString) for the 'class' attribute (and
+ // the 'className' property) is updated by the follow block (|class_name_|
+ // registered in |attribute_to_property_map_|.). SvgAttributeChanged then
+ // triggers the resulting style updates (instead of
+ // Element::ParseAttribute). We don't tell Element about the change to avoid
+ // parsing the class list twice.
if (SVGAnimatedPropertyBase* property = PropertyFromAttribute(params.name)) {
- SVGParsingError parse_error =
- property->SetBaseValueAsString(params.new_value);
+ SVGParsingError parse_error = property->AttributeChanged(params.new_value);
ReportAttributeParsingError(parse_error, params.name, params.new_value);
return;
}
- if (params.name == HTMLNames::classAttr) {
- // SVG animation has currently requires special storage of values so we set
- // the className here. svgAttributeChanged actually causes the resulting
- // style updates (instead of Element::parseAttribute). We don't
- // tell Element about the change to avoid parsing the class list twice
- SVGParsingError parse_error =
- class_name_->SetBaseValueAsString(params.new_value);
- ReportAttributeParsingError(parse_error, params.name, params.new_value);
- } else if (params.name == tabindexAttr) {
- Element::ParseAttribute(params);
- } else {
- // standard events
- const AtomicString& event_name =
- HTMLElement::EventNameForAttributeName(params.name);
- if (!event_name.IsNull()) {
- SetAttributeEventListener(
- event_name,
- CreateAttributeEventListener(this, params.name, params.new_value,
- EventParameterName()));
- } else {
- Element::ParseAttribute(params);
- }
+ const AtomicString& event_name =
+ HTMLElement::EventNameForAttributeName(params.name);
+ if (!event_name.IsNull()) {
+ SetAttributeEventListener(
+ event_name,
+ CreateAttributeEventListener(this, params.name, params.new_value,
+ EventParameterName()));
+ return;
}
+
+ Element::ParseAttribute(params);
}
// If the attribute is not present in the map, the map will return the "empty
@@ -918,7 +901,7 @@ bool SVGElement::SendSVGLoadEventIfPossible() {
return false;
if ((IsStructurallyExternal() || IsSVGSVGElement(*this)) &&
HasLoadListener(this))
- DispatchEvent(Event::Create(EventTypeNames::load));
+ DispatchEvent(*Event::Create(EventTypeNames::load));
return true;
}
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 84db978d817..4a0a16c8981 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_element.h
@@ -229,8 +229,8 @@ class CORE_EXPORT SVGElement : public Element {
const AtomicString&,
MutableCSSPropertyValueSet*) override;
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
- void RemovedFrom(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
+ void RemovedFrom(ContainerNode&) override;
void ChildrenChanged(const ChildrenChange&) override;
static CSSPropertyID CssPropertyIdForSVGAttributeName(const QualifiedName&);
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 63170c477b0..0536c880dee 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
@@ -44,7 +44,7 @@ class SVGAnimatedOrder : public SVGAnimatedIntegerOptionalInteger {
return new SVGAnimatedOrder(context_element);
}
- SVGParsingError SetBaseValueAsString(const String&) override;
+ SVGParsingError AttributeChanged(const String&) override;
protected:
SVGAnimatedOrder(SVGElement* context_element)
@@ -64,9 +64,9 @@ class SVGAnimatedOrder : public SVGAnimatedIntegerOptionalInteger {
}
};
-SVGParsingError SVGAnimatedOrder::SetBaseValueAsString(const String& value) {
+SVGParsingError SVGAnimatedOrder::AttributeChanged(const String& value) {
SVGParsingError parse_status =
- SVGAnimatedIntegerOptionalInteger::SetBaseValueAsString(value);
+ SVGAnimatedIntegerOptionalInteger::AttributeChanged(value);
// Check for semantic errors.
parse_status = CheckValue(parse_status, FirstInteger()->BaseValue()->Value());
parse_status =
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 54ece7a76d7..53b5eaed280 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
@@ -67,7 +67,7 @@ bool SVGFEDiffuseLightingElement::SetFilterEffectAttribute(
DCHECK(layout_object);
DCHECK(layout_object->Style());
return diffuse_lighting->SetLightingColor(
- layout_object->Style()->SvgStyle().LightingColor());
+ layout_object->StyleRef().SvgStyle().LightingColor());
}
if (attr_name == SVGNames::surfaceScaleAttr)
return diffuse_lighting->SetSurfaceScale(
@@ -151,7 +151,7 @@ FilterEffect* SVGFEDiffuseLightingElement::Build(
return nullptr;
DCHECK(layout_object->Style());
- Color color = layout_object->Style()->SvgStyle().LightingColor();
+ Color color = layout_object->StyleRef().SvgStyle().LightingColor();
const SVGFELightElement* light_node =
SVGFELightElement::FindLightElement(*this);
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 751caf8bd25..cc7cccdc78e 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
@@ -103,7 +103,7 @@ FilterEffect* SVGFEDropShadowElement::Build(SVGFilterBuilder* filter_builder,
return nullptr;
DCHECK(layout_object->Style());
- const SVGComputedStyle& svg_style = layout_object->Style()->SvgStyle();
+ const SVGComputedStyle& svg_style = layout_object->StyleRef().SvgStyle();
Color color = svg_style.FloodColor();
float opacity = svg_style.FloodOpacity();
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fe_flood_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_fe_flood_element.cc
index 53558414d33..0600bab1960 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_fe_flood_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_fe_flood_element.cc
@@ -56,7 +56,7 @@ FilterEffect* SVGFEFloodElement::Build(SVGFilterBuilder*, Filter* filter) {
return nullptr;
DCHECK(layout_object->Style());
- const SVGComputedStyle& svg_style = layout_object->Style()->SvgStyle();
+ const SVGComputedStyle& svg_style = layout_object->StyleRef().SvgStyle();
Color color = svg_style.FloodColor();
float opacity = svg_style.FloodOpacity();
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 f44a7400511..475a22e09c6 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
@@ -124,15 +124,15 @@ void SVGFEImageElement::SvgAttributeChanged(const QualifiedName& attr_name) {
}
Node::InsertionNotificationRequest SVGFEImageElement::InsertedInto(
- ContainerNode* root_parent) {
+ ContainerNode& root_parent) {
SVGFilterPrimitiveStandardAttributes::InsertedInto(root_parent);
BuildPendingResource();
return kInsertionDone;
}
-void SVGFEImageElement::RemovedFrom(ContainerNode* root_parent) {
+void SVGFEImageElement::RemovedFrom(ContainerNode& root_parent) {
SVGFilterPrimitiveStandardAttributes::RemovedFrom(root_parent);
- if (root_parent->isConnected())
+ if (root_parent.isConnected())
ClearResourceReferences();
}
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 69815802ea2..759f6ad3cb2 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
@@ -65,8 +65,8 @@ class SVGFEImageElement final : public SVGFilterPrimitiveStandardAttributes,
void ClearImageResource();
void BuildPendingResource() override;
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
- void RemovedFrom(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
+ void RemovedFrom(ContainerNode&) override;
Member<SVGAnimatedPreserveAspectRatio> preserve_aspect_ratio_;
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 8b665f733f0..88f88f9599d 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
@@ -77,7 +77,7 @@ bool SVGFESpecularLightingElement::SetFilterEffectAttribute(
DCHECK(layout_object);
DCHECK(layout_object->Style());
return specular_lighting->SetLightingColor(
- layout_object->Style()->SvgStyle().LightingColor());
+ layout_object->StyleRef().SvgStyle().LightingColor());
}
if (attr_name == SVGNames::surfaceScaleAttr)
return specular_lighting->SetSurfaceScale(
@@ -164,7 +164,7 @@ FilterEffect* SVGFESpecularLightingElement::Build(
return nullptr;
DCHECK(layout_object->Style());
- Color color = layout_object->Style()->SvgStyle().LightingColor();
+ Color color = layout_object->StyleRef().SvgStyle().LightingColor();
const SVGFELightElement* light_node =
SVGFELightElement::FindLightElement(*this);
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 7328b6ef3a7..4fab93100d3 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
@@ -35,16 +35,15 @@ class SVGAnimatedViewBoxRect : public SVGAnimatedRect {
return new SVGAnimatedViewBoxRect(context_element);
}
- SVGParsingError SetBaseValueAsString(const String&) override;
+ SVGParsingError AttributeChanged(const String&) override;
protected:
SVGAnimatedViewBoxRect(SVGElement* context_element)
: SVGAnimatedRect(context_element, SVGNames::viewBoxAttr) {}
};
-SVGParsingError SVGAnimatedViewBoxRect::SetBaseValueAsString(
- const String& value) {
- SVGParsingError parse_status = SVGAnimatedRect::SetBaseValueAsString(value);
+SVGParsingError SVGAnimatedViewBoxRect::AttributeChanged(const String& value) {
+ SVGParsingError parse_status = SVGAnimatedRect::AttributeChanged(value);
if (parse_status == SVGParseStatus::kNoError &&
(BaseValue()->Width() < 0 || BaseValue()->Height() < 0)) {
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 97ee5aae7aa..78b2eabe57b 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
@@ -46,9 +46,8 @@ class SVGAnimatedPathLength final : public SVGAnimatedNumber {
return new SVGAnimatedPathLength(context_element);
}
- SVGParsingError SetBaseValueAsString(const String& value) override {
- SVGParsingError parse_status =
- SVGAnimatedNumber::SetBaseValueAsString(value);
+ SVGParsingError AttributeChanged(const String& value) override {
+ SVGParsingError parse_status = SVGAnimatedNumber::AttributeChanged(value);
if (parse_status == SVGParseStatus::kNoError && BaseValue()->Value() < 0)
parse_status = SVGParseStatus::kNegativeValue;
return parse_status;
@@ -96,7 +95,7 @@ bool SVGGeometryElement::isPointInFill(SVGPointTearOff* point) const {
HitTestRequest request(HitTestRequest::kReadOnly);
PointerEventsHitRules hit_rules(
PointerEventsHitRules::SVG_GEOMETRY_HITTESTING, request,
- GetLayoutObject()->Style()->PointerEvents());
+ GetLayoutObject()->StyleRef().PointerEvents());
hit_rules.can_hit_stroke = false;
return ToLayoutSVGShape(GetLayoutObject())
->NodeAtFloatPointInternal(request, point->Target()->Value(), hit_rules);
@@ -113,7 +112,7 @@ bool SVGGeometryElement::isPointInStroke(SVGPointTearOff* point) const {
HitTestRequest request(HitTestRequest::kReadOnly);
PointerEventsHitRules hit_rules(
PointerEventsHitRules::SVG_GEOMETRY_HITTESTING, request,
- GetLayoutObject()->Style()->PointerEvents());
+ GetLayoutObject()->StyleRef().PointerEvents());
hit_rules.can_hit_fill = false;
return ToLayoutSVGShape(GetLayoutObject())
->NodeAtFloatPointInternal(request, point->Target()->Value(), hit_rules);
@@ -125,7 +124,7 @@ Path SVGGeometryElement::ToClipPath() const {
DCHECK(GetLayoutObject());
DCHECK(GetLayoutObject()->Style());
- path.SetWindRule(GetLayoutObject()->Style()->SvgStyle().ClipRule());
+ path.SetWindRule(GetLayoutObject()->StyleRef().SvgStyle().ClipRule());
return path;
}
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 fe3fcd9450f..033e8c5177c 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
@@ -128,16 +128,16 @@ void SVGGradientElement::SvgAttributeChanged(const QualifiedName& attr_name) {
}
Node::InsertionNotificationRequest SVGGradientElement::InsertedInto(
- ContainerNode* root_parent) {
+ ContainerNode& root_parent) {
SVGElement::InsertedInto(root_parent);
- if (root_parent->isConnected())
+ if (root_parent.isConnected())
BuildPendingResource();
return kInsertionDone;
}
-void SVGGradientElement::RemovedFrom(ContainerNode* root_parent) {
+void SVGGradientElement::RemovedFrom(ContainerNode& root_parent) {
SVGElement::RemovedFrom(root_parent);
- if (root_parent->isConnected())
+ if (root_parent.isConnected())
ClearResourceReferences();
}
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 48d4b365e02..2e6116e01cc 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
@@ -81,8 +81,8 @@ class SVGGradientElement : public SVGElement, public SVGURIReference {
const AtomicString&,
MutableCSSPropertyValueSet*) override;
- InsertionNotificationRequest InsertedInto(ContainerNode*) final;
- void RemovedFrom(ContainerNode*) final;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) final;
+ void RemovedFrom(ContainerNode&) final;
void ChildrenChanged(const ChildrenChange&) final;
void BuildPendingResource() override;
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 3a846fc5b1e..3e7ca19ea77 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
@@ -154,8 +154,7 @@ void SVGImageElement::SvgAttributeChanged(const QualifiedName& attr_name) {
void SVGImageElement::ParseAttribute(
const AttributeModificationParams& params) {
- if (params.name == SVGNames::decodingAttr &&
- RuntimeEnabledFeatures::ImageDecodingAttributeEnabled()) {
+ if (params.name == SVGNames::decodingAttr) {
UseCounter::Count(GetDocument(), WebFeature::kImageDecodingAttribute);
decoding_mode_ = ParseImageDecodingMode(params.new_value);
} else {
@@ -189,11 +188,11 @@ void SVGImageElement::AttachLayoutTree(AttachContext& context) {
}
Node::InsertionNotificationRequest SVGImageElement::InsertedInto(
- ContainerNode* root_parent) {
+ ContainerNode& root_parent) {
// A previous loader update may have failed to actually fetch the image if
// the document was inactive. In that case, force a re-update (but don't
// clear previous errors).
- if (root_parent->isConnected() && !GetImageLoader().GetContent())
+ if (root_parent.isConnected() && !GetImageLoader().GetContent())
GetImageLoader().UpdateFromElement(ImageLoader::kUpdateNormal);
return SVGGraphicsElement::InsertedInto(root_parent);
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 48e8bb1a396..d8e7c3598d3 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
@@ -81,7 +81,7 @@ class CORE_EXPORT SVGImageElement final
void ParseAttribute(const AttributeModificationParams&) override;
void AttachLayoutTree(AttachContext&) override;
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
LayoutObject* CreateLayoutObject(const ComputedStyle&) override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_image_element.idl b/chromium/third_party/blink/renderer/core/svg/svg_image_element.idl
index 33f1d31b7f0..2d60cf099e3 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_image_element.idl
+++ b/chromium/third_party/blink/renderer/core/svg/svg_image_element.idl
@@ -33,9 +33,9 @@
[MeasureAs=SVG1DOMImageElement] readonly attribute SVGAnimatedLength width;
[MeasureAs=SVG1DOMImageElement] readonly attribute SVGAnimatedLength height;
[MeasureAs=SVG1DOMImageElement] readonly attribute SVGAnimatedPreserveAspectRatio preserveAspectRatio;
- [RuntimeEnabled=ImageDecodingAttribute, CEReactions, Reflect, ReflectOnly=("async", "sync", "auto"), ReflectMissing="auto", ReflectInvalid="auto"] attribute DOMString decoding;
+ [CEReactions, Reflect, ReflectOnly=("async", "sync", "auto"), ReflectMissing="auto", ReflectInvalid="auto"] attribute DOMString decoding;
- [RuntimeEnabled=JSImageDecode, CallWith=ScriptState, RaisesException] Promise decode();
+ [CallWith=ScriptState, RaisesException] Promise decode();
};
SVGImageElement implements SVGURIReference;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_image_loader.cc b/chromium/third_party/blink/renderer/core/svg/svg_image_loader.cc
index f4e6d92a588..a7ce9fe9322 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_image_loader.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_image_loader.cc
@@ -29,7 +29,7 @@ SVGImageLoader::SVGImageLoader(SVGImageElement* node) : ImageLoader(node) {}
void SVGImageLoader::DispatchLoadEvent() {
if (GetContent()->ErrorOccurred()) {
- GetElement()->DispatchEvent(Event::Create(EventTypeNames::error));
+ GetElement()->DispatchEvent(*Event::Create(EventTypeNames::error));
} else {
SVGImageElement* image_element = ToSVGImageElement(GetElement());
image_element->SendSVGLoadEventToSelfAndAncestorChainIfPossible();
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 e153f5a8859..955d428226d 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
@@ -43,21 +43,7 @@ SVGPropertyBase* SVGLengthList::CloneForAnimation(const String& value) const {
}
String SVGLengthList::ValueAsString() const {
- StringBuilder builder;
-
- ConstIterator it = begin();
- ConstIterator it_end = end();
- if (it != it_end) {
- builder.Append(it->ValueAsString());
- ++it;
-
- for (; it != it_end; ++it) {
- builder.Append(' ');
- builder.Append(it->ValueAsString());
- }
- }
-
- return builder.ToString();
+ return SVGListPropertyHelper<SVGLengthList, SVGLength>::SerializeList();
}
template <typename CharType>
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_length_list_tear_off.h b/chromium/third_party/blink/renderer/core/svg/svg_length_list_tear_off.h
index 122cb250e28..cd50f249b38 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_length_list_tear_off.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_length_list_tear_off.h
@@ -43,24 +43,19 @@ class SVGLengthListTearOff final
public:
static SVGLengthListTearOff* Create(
SVGLengthList* target,
- SVGElement* context_element,
- PropertyIsAnimValType property_is_anim_val,
- const QualifiedName& attribute_name = QualifiedName::Null()) {
- return new SVGLengthListTearOff(target, context_element,
- property_is_anim_val, attribute_name);
+ SVGAnimatedPropertyBase* binding,
+ PropertyIsAnimValType property_is_anim_val) {
+ return new SVGLengthListTearOff(target, binding, property_is_anim_val);
}
private:
- SVGLengthListTearOff(
- SVGLengthList* target,
- SVGElement* context_element,
- PropertyIsAnimValType property_is_anim_val,
- const QualifiedName& attribute_name = QualifiedName::Null())
+ SVGLengthListTearOff(SVGLengthList* target,
+ SVGAnimatedPropertyBase* binding,
+ PropertyIsAnimValType property_is_anim_val)
: SVGListPropertyTearOffHelper<SVGLengthListTearOff, SVGLengthList>(
target,
- context_element,
- property_is_anim_val,
- attribute_name) {}
+ binding,
+ property_is_anim_val) {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_length_tear_off.cc b/chromium/third_party/blink/renderer/core/svg/svg_length_tear_off.cc
index 43aec9b463a..7990ebb3b60 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_length_tear_off.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_length_tear_off.cc
@@ -117,12 +117,12 @@ SVGLengthMode SVGLengthTearOff::UnitMode() {
}
float SVGLengthTearOff::value(ExceptionState& exception_state) {
- if (Target()->IsRelative() && !CanResolveRelativeUnits(contextElement())) {
+ if (Target()->IsRelative() && !CanResolveRelativeUnits(ContextElement())) {
exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
"Could not resolve relative length.");
return 0;
}
- SVGLengthContext length_context(contextElement());
+ SVGLengthContext length_context(ContextElement());
return Target()->Value(length_context);
}
@@ -131,12 +131,12 @@ void SVGLengthTearOff::setValue(float value, ExceptionState& exception_state) {
ThrowReadOnly(exception_state);
return;
}
- if (Target()->IsRelative() && !CanResolveRelativeUnits(contextElement())) {
+ if (Target()->IsRelative() && !CanResolveRelativeUnits(ContextElement())) {
exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
"Could not resolve relative length.");
return;
}
- SVGLengthContext length_context(contextElement());
+ SVGLengthContext length_context(ContextElement());
if (Target()->IsCalculated())
Target()->SetValueAsNumber(value);
else
@@ -227,28 +227,23 @@ void SVGLengthTearOff::convertToSpecifiedUnits(
}
if ((Target()->IsRelative() ||
CSSPrimitiveValue::IsRelativeUnit(ToCSSUnitType(unit_type))) &&
- !CanResolveRelativeUnits(contextElement())) {
+ !CanResolveRelativeUnits(ContextElement())) {
exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
"Could not resolve relative length.");
return;
}
- SVGLengthContext length_context(contextElement());
+ SVGLengthContext length_context(ContextElement());
Target()->ConvertToSpecifiedUnits(ToCSSUnitType(unit_type), length_context);
CommitChange();
}
SVGLengthTearOff::SVGLengthTearOff(SVGLength* target,
- SVGElement* context_element,
- PropertyIsAnimValType property_is_anim_val,
- const QualifiedName& attribute_name)
- : SVGPropertyTearOff<SVGLength>(target,
- context_element,
- property_is_anim_val,
- attribute_name) {}
+ SVGAnimatedPropertyBase* binding,
+ PropertyIsAnimValType property_is_anim_val)
+ : SVGPropertyTearOff<SVGLength>(target, binding, property_is_anim_val) {}
SVGLengthTearOff* SVGLengthTearOff::CreateDetached() {
- return Create(SVGLength::Create(), nullptr, kPropertyIsNotAnimVal,
- QualifiedName::Null());
+ return Create(SVGLength::Create(), nullptr, kPropertyIsNotAnimVal);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_length_tear_off.h b/chromium/third_party/blink/renderer/core/svg/svg_length_tear_off.h
index 0bf9d3c9d45..0181b86b45d 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_length_tear_off.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_length_tear_off.h
@@ -56,11 +56,9 @@ class SVGLengthTearOff final : public SVGPropertyTearOff<SVGLength> {
};
static SVGLengthTearOff* Create(SVGLength* target,
- SVGElement* context_element,
- PropertyIsAnimValType property_is_anim_val,
- const QualifiedName& attribute_name) {
- return new SVGLengthTearOff(target, context_element, property_is_anim_val,
- attribute_name);
+ SVGAnimatedPropertyBase* binding,
+ PropertyIsAnimValType property_is_anim_val) {
+ return new SVGLengthTearOff(target, binding, property_is_anim_val);
}
static SVGLengthTearOff* CreateDetached();
@@ -81,9 +79,8 @@ class SVGLengthTearOff final : public SVGPropertyTearOff<SVGLength> {
private:
SVGLengthTearOff(SVGLength*,
- SVGElement* context_element,
- PropertyIsAnimValType,
- const QualifiedName& attribute_name);
+ SVGAnimatedPropertyBase* binding,
+ PropertyIsAnimValType);
};
} // namespace blink
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 606a1cfc3a4..b56fee08e19 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
@@ -30,7 +30,6 @@
#include "third_party/blink/renderer/core/svg/svg_matrix_tear_off.h"
-#include "third_party/blink/renderer/core/svg/svg_element.h"
#include "third_party/blink/renderer/core/svg/svg_transform_tear_off.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
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 6bc80cf6681..8256e3f48f1 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
@@ -62,17 +62,17 @@ void SVGMPathElement::ClearResourceReferences() {
}
Node::InsertionNotificationRequest SVGMPathElement::InsertedInto(
- ContainerNode* root_parent) {
+ ContainerNode& root_parent) {
SVGElement::InsertedInto(root_parent);
- if (root_parent->isConnected())
+ if (root_parent.isConnected())
BuildPendingResource();
return kInsertionDone;
}
-void SVGMPathElement::RemovedFrom(ContainerNode* root_parent) {
+void SVGMPathElement::RemovedFrom(ContainerNode& root_parent) {
SVGElement::RemovedFrom(root_parent);
- NotifyParentOfPathChange(root_parent);
- if (root_parent->isConnected())
+ NotifyParentOfPathChange(&root_parent);
+ if (root_parent.isConnected())
ClearResourceReferences();
}
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 5bf2525f2aa..6bd308b33a0 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
@@ -47,8 +47,8 @@ class SVGMPathElement final : public SVGElement, public SVGURIReference {
void BuildPendingResource() override;
void ClearResourceReferences();
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
- void RemovedFrom(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
+ void RemovedFrom(ContainerNode&) override;
void SvgAttributeChanged(const QualifiedName&) override;
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 98c08cb98f3..43af35172d8 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
@@ -32,21 +32,7 @@ SVGNumberList::SVGNumberList() = default;
SVGNumberList::~SVGNumberList() = default;
String SVGNumberList::ValueAsString() const {
- StringBuilder builder;
-
- ConstIterator it = begin();
- ConstIterator it_end = end();
- if (it != it_end) {
- builder.Append(it->ValueAsString());
- ++it;
-
- for (; it != it_end; ++it) {
- builder.Append(' ');
- builder.Append(it->ValueAsString());
- }
- }
-
- return builder.ToString();
+ return SVGListPropertyHelper<SVGNumberList, SVGNumber>::SerializeList();
}
template <typename CharType>
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_number_list_tear_off.h b/chromium/third_party/blink/renderer/core/svg/svg_number_list_tear_off.h
index fa5b5022a09..dab0a184dd6 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_number_list_tear_off.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_number_list_tear_off.h
@@ -43,23 +43,19 @@ class SVGNumberListTearOff final
public:
static SVGNumberListTearOff* Create(
SVGNumberList* target,
- SVGElement* context_element,
- PropertyIsAnimValType property_is_anim_val,
- const QualifiedName& attribute_name) {
- return new SVGNumberListTearOff(target, context_element,
- property_is_anim_val, attribute_name);
+ SVGAnimatedPropertyBase* binding,
+ PropertyIsAnimValType property_is_anim_val) {
+ return new SVGNumberListTearOff(target, binding, property_is_anim_val);
}
private:
SVGNumberListTearOff(SVGNumberList* target,
- SVGElement* context_element,
- PropertyIsAnimValType property_is_anim_val,
- const QualifiedName& attribute_name)
+ SVGAnimatedPropertyBase* binding,
+ PropertyIsAnimValType property_is_anim_val)
: SVGListPropertyTearOffHelper<SVGNumberListTearOff, SVGNumberList>(
target,
- context_element,
- property_is_anim_val,
- attribute_name) {}
+ binding,
+ property_is_anim_val) {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_number_tear_off.cc b/chromium/third_party/blink/renderer/core/svg/svg_number_tear_off.cc
index 27b2dbef3ae..1026ac69ef9 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_number_tear_off.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_number_tear_off.cc
@@ -30,18 +30,12 @@
#include "third_party/blink/renderer/core/svg/svg_number_tear_off.h"
-#include "third_party/blink/renderer/core/svg/svg_element.h"
-
namespace blink {
SVGNumberTearOff::SVGNumberTearOff(SVGNumber* target,
- SVGElement* context_element,
- PropertyIsAnimValType property_is_anim_val,
- const QualifiedName& attribute_name)
- : SVGPropertyTearOff<SVGNumber>(target,
- context_element,
- property_is_anim_val,
- attribute_name) {}
+ SVGAnimatedPropertyBase* binding,
+ PropertyIsAnimValType property_is_anim_val)
+ : SVGPropertyTearOff<SVGNumber>(target, binding, property_is_anim_val) {}
void SVGNumberTearOff::setValue(float f, ExceptionState& exception_state) {
if (IsImmutable()) {
@@ -53,8 +47,7 @@ void SVGNumberTearOff::setValue(float f, ExceptionState& exception_state) {
}
SVGNumberTearOff* SVGNumberTearOff::CreateDetached() {
- return Create(SVGNumber::Create(), nullptr, kPropertyIsNotAnimVal,
- QualifiedName::Null());
+ return Create(SVGNumber::Create(), nullptr, kPropertyIsNotAnimVal);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_number_tear_off.h b/chromium/third_party/blink/renderer/core/svg/svg_number_tear_off.h
index 5b0050ab60b..cdc90fcb7f6 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_number_tear_off.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_number_tear_off.h
@@ -41,11 +41,9 @@ class SVGNumberTearOff : public SVGPropertyTearOff<SVGNumber> {
public:
static SVGNumberTearOff* Create(SVGNumber* target,
- SVGElement* context_element,
- PropertyIsAnimValType property_is_anim_val,
- const QualifiedName& attribute_name) {
- return new SVGNumberTearOff(target, context_element, property_is_anim_val,
- attribute_name);
+ SVGAnimatedPropertyBase* binding,
+ PropertyIsAnimValType property_is_anim_val) {
+ return new SVGNumberTearOff(target, binding, property_is_anim_val);
}
static SVGNumberTearOff* CreateDetached();
@@ -54,9 +52,8 @@ class SVGNumberTearOff : public SVGPropertyTearOff<SVGNumber> {
protected:
SVGNumberTearOff(SVGNumber*,
- SVGElement* context_element,
- PropertyIsAnimValType,
- const QualifiedName& attribute_name);
+ SVGAnimatedPropertyBase* binding,
+ PropertyIsAnimValType);
};
} // 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 ca81e776842..9e4f84abaaf 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
@@ -63,6 +63,8 @@ static inline bool IsAbsolutePathSegType(const SVGPathSegType type) {
struct PathSegmentData {
STACK_ALLOCATED();
+
+ public:
PathSegmentData()
: command(kPathSegUnknown), arc_sweep(false), arc_large(false) {}
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 241cdadf3bf..1f96415490b 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
@@ -123,13 +123,13 @@ void SVGPathElement::InvalidateMPathDependencies() {
}
Node::InsertionNotificationRequest SVGPathElement::InsertedInto(
- ContainerNode* root_parent) {
+ ContainerNode& root_parent) {
SVGGeometryElement::InsertedInto(root_parent);
InvalidateMPathDependencies();
return kInsertionDone;
}
-void SVGPathElement::RemovedFrom(ContainerNode* root_parent) {
+void SVGPathElement::RemovedFrom(ContainerNode& root_parent) {
SVGGeometryElement::RemovedFrom(root_parent);
InvalidateMPathDependencies();
}
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 247481d26b5..3543b903aeb 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
@@ -63,8 +63,8 @@ class SVGPathElement final : public SVGGeometryElement {
const AtomicString&,
MutableCSSPropertyValueSet*) override;
- Node::InsertionNotificationRequest InsertedInto(ContainerNode*) override;
- void RemovedFrom(ContainerNode*) override;
+ Node::InsertionNotificationRequest InsertedInto(ContainerNode&) override;
+ void RemovedFrom(ContainerNode&) override;
void InvalidateMPathDependencies();
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 822f622a2bc..9f1ddb679ee 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
@@ -163,16 +163,16 @@ void SVGPatternElement::SvgAttributeChanged(const QualifiedName& attr_name) {
}
Node::InsertionNotificationRequest SVGPatternElement::InsertedInto(
- ContainerNode* root_parent) {
+ ContainerNode& root_parent) {
SVGElement::InsertedInto(root_parent);
- if (root_parent->isConnected())
+ if (root_parent.isConnected())
BuildPendingResource();
return kInsertionDone;
}
-void SVGPatternElement::RemovedFrom(ContainerNode* root_parent) {
+void SVGPatternElement::RemovedFrom(ContainerNode& root_parent) {
SVGElement::RemovedFrom(root_parent);
- if (root_parent->isConnected())
+ if (root_parent.isConnected())
ClearResourceReferences();
}
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 e5a6c56fe5c..1775ff6ee9e 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
@@ -93,8 +93,8 @@ class SVGPatternElement final : public SVGElement,
MutableCSSPropertyValueSet*) override;
void SvgAttributeChanged(const QualifiedName&) override;
- InsertionNotificationRequest InsertedInto(ContainerNode*) final;
- void RemovedFrom(ContainerNode*) final;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) final;
+ void RemovedFrom(ContainerNode&) final;
void ChildrenChanged(const ChildrenChange&) override;
void BuildPendingResource() override;
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 cf8c3cbc226..f7324d0f3eb 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
@@ -33,21 +33,7 @@ SVGPointList::SVGPointList() = default;
SVGPointList::~SVGPointList() = default;
String SVGPointList::ValueAsString() const {
- StringBuilder builder;
-
- ConstIterator it = begin();
- ConstIterator it_end = end();
- if (it != it_end) {
- builder.Append(it->ValueAsString());
- ++it;
-
- for (; it != it_end; ++it) {
- builder.Append(' ');
- builder.Append(it->ValueAsString());
- }
- }
-
- return builder.ToString();
+ return SVGListPropertyHelper<SVGPointList, SVGPoint>::SerializeList();
}
template <typename CharType>
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_point_list_tear_off.h b/chromium/third_party/blink/renderer/core/svg/svg_point_list_tear_off.h
index 71cdf2f6278..e29f06e308e 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_point_list_tear_off.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_point_list_tear_off.h
@@ -41,24 +41,21 @@ class SVGPointListTearOff final
DEFINE_WRAPPERTYPEINFO();
public:
- static SVGPointListTearOff* Create(SVGPointList* target,
- SVGElement* context_element,
- PropertyIsAnimValType property_is_anim_val,
- const QualifiedName& attribute_name) {
- return new SVGPointListTearOff(target, context_element,
- property_is_anim_val, attribute_name);
+ static SVGPointListTearOff* Create(
+ SVGPointList* target,
+ SVGAnimatedPropertyBase* binding,
+ PropertyIsAnimValType property_is_anim_val) {
+ return new SVGPointListTearOff(target, binding, property_is_anim_val);
}
private:
SVGPointListTearOff(SVGPointList* target,
- SVGElement* context_element,
- PropertyIsAnimValType property_is_anim_val,
- const QualifiedName& attribute_name)
+ SVGAnimatedPropertyBase* binding,
+ PropertyIsAnimValType property_is_anim_val)
: SVGListPropertyTearOffHelper<SVGPointListTearOff, SVGPointList>(
target,
- context_element,
- property_is_anim_val,
- attribute_name) {}
+ binding,
+ property_is_anim_val) {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_point_tear_off.cc b/chromium/third_party/blink/renderer/core/svg/svg_point_tear_off.cc
index c9f7dc71e2f..8b278e3a0b2 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_point_tear_off.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_point_tear_off.cc
@@ -30,19 +30,17 @@
#include "third_party/blink/renderer/core/svg/svg_point_tear_off.h"
-#include "third_party/blink/renderer/core/svg/svg_element.h"
#include "third_party/blink/renderer/core/svg/svg_matrix_tear_off.h"
namespace blink {
SVGPointTearOff::SVGPointTearOff(SVGPoint* target,
- SVGElement* context_element,
- PropertyIsAnimValType property_is_anim_val,
- const QualifiedName& attribute_name)
- : SVGPropertyTearOff<SVGPoint>(target,
- context_element,
- property_is_anim_val,
- attribute_name) {}
+ SVGAnimatedPropertyBase* binding,
+ PropertyIsAnimValType property_is_anim_val)
+ : SVGPropertyTearOff<SVGPoint>(target, binding, property_is_anim_val) {}
+
+SVGPointTearOff::SVGPointTearOff(SVGPoint* target, SVGElement* context_element)
+ : SVGPropertyTearOff<SVGPoint>(target, context_element) {}
void SVGPointTearOff::setX(float f, ExceptionState& exception_state) {
if (IsImmutable()) {
@@ -68,8 +66,7 @@ SVGPointTearOff* SVGPointTearOff::matrixTransform(SVGMatrixTearOff* matrix) {
}
SVGPointTearOff* SVGPointTearOff::CreateDetached(const FloatPoint& point) {
- return Create(SVGPoint::Create(point), nullptr, kPropertyIsNotAnimVal,
- QualifiedName::Null());
+ return Create(SVGPoint::Create(point), nullptr, kPropertyIsNotAnimVal);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_point_tear_off.h b/chromium/third_party/blink/renderer/core/svg/svg_point_tear_off.h
index 3655eef6715..2caab949654 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_point_tear_off.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_point_tear_off.h
@@ -43,11 +43,13 @@ class SVGPointTearOff : public SVGPropertyTearOff<SVGPoint> {
public:
static SVGPointTearOff* Create(SVGPoint* target,
- SVGElement* context_element,
- PropertyIsAnimValType property_is_anim_val,
- const QualifiedName& attribute_name) {
- return new SVGPointTearOff(target, context_element, property_is_anim_val,
- attribute_name);
+ SVGAnimatedPropertyBase* binding,
+ PropertyIsAnimValType property_is_anim_val) {
+ return new SVGPointTearOff(target, binding, property_is_anim_val);
+ }
+ static SVGPointTearOff* Create(SVGPoint* target,
+ SVGElement* context_element) {
+ return new SVGPointTearOff(target, context_element);
}
static SVGPointTearOff* CreateDetached(const FloatPoint&);
@@ -60,9 +62,9 @@ class SVGPointTearOff : public SVGPropertyTearOff<SVGPoint> {
protected:
SVGPointTearOff(SVGPoint*,
- SVGElement* context_element,
- PropertyIsAnimValType,
- const QualifiedName& attribute_name);
+ SVGAnimatedPropertyBase* binding,
+ PropertyIsAnimValType);
+ SVGPointTearOff(SVGPoint*, SVGElement*);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_preserve_aspect_ratio_tear_off.cc b/chromium/third_party/blink/renderer/core/svg/svg_preserve_aspect_ratio_tear_off.cc
index 643e441c637..b7abe8044b2 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_preserve_aspect_ratio_tear_off.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_preserve_aspect_ratio_tear_off.cc
@@ -30,7 +30,6 @@
#include "third_party/blink/renderer/core/svg/svg_preserve_aspect_ratio_tear_off.h"
-#include "third_party/blink/renderer/core/svg/svg_element.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
namespace blink {
@@ -72,12 +71,10 @@ void SVGPreserveAspectRatioTearOff::setMeetOrSlice(
SVGPreserveAspectRatioTearOff::SVGPreserveAspectRatioTearOff(
SVGPreserveAspectRatio* target,
- SVGElement* context_element,
- PropertyIsAnimValType property_is_anim_val,
- const QualifiedName& attribute_name)
+ SVGAnimatedPropertyBase* binding,
+ PropertyIsAnimValType property_is_anim_val)
: SVGPropertyTearOff<SVGPreserveAspectRatio>(target,
- context_element,
- property_is_anim_val,
- attribute_name) {}
+ binding,
+ property_is_anim_val) {}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_preserve_aspect_ratio_tear_off.h b/chromium/third_party/blink/renderer/core/svg/svg_preserve_aspect_ratio_tear_off.h
index 3d3b30617dd..a2b3d6d9600 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_preserve_aspect_ratio_tear_off.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_preserve_aspect_ratio_tear_off.h
@@ -75,11 +75,10 @@ class SVGPreserveAspectRatioTearOff final
static SVGPreserveAspectRatioTearOff* Create(
SVGPreserveAspectRatio* target,
- SVGElement* context_element,
- PropertyIsAnimValType property_is_anim_val,
- const QualifiedName& attribute_name) {
- return new SVGPreserveAspectRatioTearOff(
- target, context_element, property_is_anim_val, attribute_name);
+ SVGAnimatedPropertyBase* binding,
+ PropertyIsAnimValType property_is_anim_val) {
+ return new SVGPreserveAspectRatioTearOff(target, binding,
+ property_is_anim_val);
}
void setAlign(unsigned short, ExceptionState&);
@@ -89,9 +88,8 @@ class SVGPreserveAspectRatioTearOff final
private:
SVGPreserveAspectRatioTearOff(SVGPreserveAspectRatio*,
- SVGElement* context_element,
- PropertyIsAnimValType,
- const QualifiedName& attribute_name);
+ SVGAnimatedPropertyBase* binding,
+ PropertyIsAnimValType);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_rect_tear_off.cc b/chromium/third_party/blink/renderer/core/svg/svg_rect_tear_off.cc
index f4d1e67091a..ecfc42a1812 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_rect_tear_off.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_rect_tear_off.cc
@@ -30,18 +30,12 @@
#include "third_party/blink/renderer/core/svg/svg_rect_tear_off.h"
-#include "third_party/blink/renderer/core/svg/svg_element.h"
-
namespace blink {
SVGRectTearOff::SVGRectTearOff(SVGRect* target,
- SVGElement* context_element,
- PropertyIsAnimValType property_is_anim_val,
- const QualifiedName& attribute_name)
- : SVGPropertyTearOff<SVGRect>(target,
- context_element,
- property_is_anim_val,
- attribute_name) {}
+ SVGAnimatedPropertyBase* binding,
+ PropertyIsAnimValType property_is_anim_val)
+ : SVGPropertyTearOff<SVGRect>(target, binding, property_is_anim_val) {}
void SVGRectTearOff::setX(float f, ExceptionState& exception_state) {
if (IsImmutable()) {
@@ -80,8 +74,7 @@ void SVGRectTearOff::setHeight(float f, ExceptionState& exception_state) {
}
SVGRectTearOff* SVGRectTearOff::CreateDetached(const FloatRect& rect) {
- return Create(SVGRect::Create(rect), nullptr, kPropertyIsNotAnimVal,
- QualifiedName::Null());
+ return Create(SVGRect::Create(rect), nullptr, kPropertyIsNotAnimVal);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_rect_tear_off.h b/chromium/third_party/blink/renderer/core/svg/svg_rect_tear_off.h
index 042071a9b11..dad272d61b5 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_rect_tear_off.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_rect_tear_off.h
@@ -41,11 +41,9 @@ class SVGRectTearOff : public SVGPropertyTearOff<SVGRect> {
public:
static SVGRectTearOff* Create(SVGRect* target,
- SVGElement* context_element,
- PropertyIsAnimValType property_is_anim_val,
- const QualifiedName& attribute_name) {
- return new SVGRectTearOff(target, context_element, property_is_anim_val,
- attribute_name);
+ SVGAnimatedPropertyBase* binding,
+ PropertyIsAnimValType property_is_anim_val) {
+ return new SVGRectTearOff(target, binding, property_is_anim_val);
}
static SVGRectTearOff* CreateDetached(const FloatRect&);
@@ -60,9 +58,8 @@ class SVGRectTearOff : public SVGPropertyTearOff<SVGRect> {
private:
SVGRectTearOff(SVGRect*,
- SVGElement* context_element,
- PropertyIsAnimValType,
- const QualifiedName& attribute_name);
+ SVGAnimatedPropertyBase* binding,
+ PropertyIsAnimValType);
};
} // namespace blink
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 4fe24df9ab8..7e633505609 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_resource.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_resource.cc
@@ -128,6 +128,8 @@ void ExternalSVGResource::Load(const Document& document) {
ResourceLoaderOptions options;
options.initiator_info.name = FetchInitiatorTypeNames::css;
FetchParameters params(ResourceRequest(url_), options);
+ params.MutableResourceRequest().SetFetchRequestMode(
+ network::mojom::FetchRequestMode::kSameOrigin);
resource_document_ =
DocumentResource::FetchSVGDocument(params, document.Fetcher(), this);
target_ = ResolveTarget();
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_script_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_script_element.cc
index 12bee5bfbc3..b81bf537688 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
@@ -68,7 +68,7 @@ void SVGScriptElement::SvgAttributeChanged(const QualifiedName& attr_name) {
}
Node::InsertionNotificationRequest SVGScriptElement::InsertedInto(
- ContainerNode* root_parent) {
+ ContainerNode& root_parent) {
SVGElement::InsertedInto(root_parent);
return kInsertionShouldCallDidNotifySubtreeInsertions;
}
@@ -155,12 +155,12 @@ Element* SVGScriptElement::CloneWithoutAttributesAndChildren(
}
void SVGScriptElement::DispatchLoadEvent() {
- DispatchEvent(Event::Create(EventTypeNames::load));
+ DispatchEvent(*Event::Create(EventTypeNames::load));
have_fired_load_ = true;
}
void SVGScriptElement::DispatchErrorEvent() {
- DispatchEvent(Event::Create(EventTypeNames::error));
+ DispatchEvent(*Event::Create(EventTypeNames::error));
}
void SVGScriptElement::SetScriptElementForBinding(
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 350c0859dc8..157afbae070 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
@@ -55,7 +55,7 @@ class SVGScriptElement final : public SVGElement,
SVGScriptElement(Document&, const CreateElementFlags);
void ParseAttribute(const AttributeModificationParams&) override;
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
void DidNotifySubtreeInsertionsToDocument() override;
void ChildrenChanged(const ChildrenChange&) override;
void DidMoveToNewDocument(Document& old_document) override;
@@ -75,6 +75,7 @@ class SVGScriptElement final : public SVGElement,
String EventAttributeValue() const override { return String(); }
String ForAttributeValue() const override { return String(); }
String IntegrityAttributeValue() const override { return String(); }
+ String ReferrerPolicyAttributeValue() const override { return String(); }
String LanguageAttributeValue() const override { return String(); }
bool NomoduleAttributeValue() const override { return false; }
String SourceAttributeValue() const override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_static_string_list.cc b/chromium/third_party/blink/renderer/core/svg/svg_static_string_list.cc
index fb00b5dbfc3..8e65930283b 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
@@ -30,7 +30,6 @@
#include "third_party/blink/renderer/core/svg/svg_static_string_list.h"
-#include "third_party/blink/renderer/core/svg/svg_element.h"
#include "third_party/blink/renderer/core/svg/svg_string_list_tear_off.h"
namespace blink {
@@ -78,19 +77,16 @@ void SVGStaticStringList::AnimationEnded() {
NOTREACHED();
}
-bool SVGStaticStringList::NeedsSynchronizeAttribute() {
- return tear_off_;
-}
-
SVGStringListTearOff* SVGStaticStringList::TearOff() {
- if (!tear_off_)
- tear_off_ = SVGStringListTearOff::Create(
- value_, contextElement(), kPropertyIsNotAnimVal, AttributeName());
-
+ if (!tear_off_) {
+ tear_off_ =
+ SVGStringListTearOff::Create(value_, this, kPropertyIsNotAnimVal);
+ }
return tear_off_.Get();
}
-SVGParsingError SVGStaticStringList::SetBaseValueAsString(const String& value) {
+SVGParsingError SVGStaticStringList::AttributeChanged(const String& value) {
+ ClearBaseValueNeedsSynchronization();
return value_->SetValueAsString(value);
}
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 2298ebe0f23..e5d13aba912 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
@@ -62,9 +62,8 @@ class SVGStaticStringList final
SVGPropertyBase* CreateAnimatedValue() override;
void SetAnimatedValue(SVGPropertyBase*) override;
void AnimationEnded() override;
- bool NeedsSynchronizeAttribute() override;
- SVGParsingError SetBaseValueAsString(const String&) override;
+ SVGParsingError AttributeChanged(const String&) override;
SVGStringList* Value() { return value_.Get(); }
SVGStringListTearOff* TearOff();
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_string_list.cc b/chromium/third_party/blink/renderer/core/svg/svg_string_list.cc
index aeb1453f482..e3e1c5ac297 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_string_list.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_string_list.cc
@@ -20,7 +20,6 @@
#include "third_party/blink/renderer/core/svg/svg_string_list.h"
-#include "third_party/blink/renderer/core/svg/svg_element.h"
#include "third_party/blink/renderer/core/svg/svg_parser_utilities.h"
#include "third_party/blink/renderer/platform/bindings/exception_messages.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -116,6 +115,9 @@ SVGParsingError SVGStringList::SetValueAsString(const String& data) {
}
String SVGStringList::ValueAsString() const {
+ if (values_.IsEmpty())
+ return String();
+
StringBuilder builder;
Vector<String>::const_iterator it = values_.begin();
@@ -138,8 +140,8 @@ bool SVGStringList::CheckIndexBound(size_t index,
if (index >= values_.size()) {
exception_state.ThrowDOMException(
DOMExceptionCode::kIndexSizeError,
- ExceptionMessages::IndexExceedsMaximumBound("index", index,
- values_.size()));
+ ExceptionMessages::IndexExceedsMaximumBound(
+ "index", index, static_cast<size_t>(values_.size())));
return false;
}
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_string_list_tear_off.cc b/chromium/third_party/blink/renderer/core/svg/svg_string_list_tear_off.cc
index 676cab9e0bb..356a4351efb 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_string_list_tear_off.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_string_list_tear_off.cc
@@ -30,18 +30,13 @@
#include "third_party/blink/renderer/core/svg/svg_string_list_tear_off.h"
-#include "third_party/blink/renderer/core/svg/svg_element.h"
-
namespace blink {
SVGStringListTearOff::SVGStringListTearOff(
SVGStringList* target,
- SVGElement* context_element,
- PropertyIsAnimValType property_is_anim_val,
- const QualifiedName& attribute_name)
- : SVGPropertyTearOff<SVGStringList>(target,
- context_element,
- property_is_anim_val,
- attribute_name) {}
+ SVGAnimatedPropertyBase* binding,
+ PropertyIsAnimValType property_is_anim_val)
+ : SVGPropertyTearOff<SVGStringList>(target, binding, property_is_anim_val) {
+}
} // namespace blink
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 84a310532a6..0860fb5f8c1 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
@@ -42,11 +42,9 @@ class SVGStringListTearOff : public SVGPropertyTearOff<SVGStringList> {
public:
static SVGStringListTearOff* Create(
SVGStringList* target,
- SVGElement* context_element,
- PropertyIsAnimValType property_is_anim_val,
- const QualifiedName& attribute_name) {
- return new SVGStringListTearOff(target, context_element,
- property_is_anim_val, attribute_name);
+ SVGAnimatedPropertyBase* binding,
+ PropertyIsAnimValType property_is_anim_val) {
+ return new SVGStringListTearOff(target, binding, property_is_anim_val);
}
// SVGStringList DOM interface:
@@ -130,9 +128,8 @@ class SVGStringListTearOff : public SVGPropertyTearOff<SVGStringList> {
protected:
SVGStringListTearOff(SVGStringList*,
- SVGElement*,
- PropertyIsAnimValType,
- const QualifiedName&);
+ SVGAnimatedPropertyBase* binding,
+ PropertyIsAnimValType);
};
} // namespace blink
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 df0dd356ebc..ce6165abab3 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
@@ -103,7 +103,7 @@ void SVGStyleElement::FinishParsingChildren() {
}
Node::InsertionNotificationRequest SVGStyleElement::InsertedInto(
- ContainerNode* insertion_point) {
+ ContainerNode& insertion_point) {
SVGElement::InsertedInto(insertion_point);
if (isConnected()) {
if (StyleElement::ProcessStyleSheet(GetDocument(), *this) ==
@@ -115,9 +115,9 @@ Node::InsertionNotificationRequest SVGStyleElement::InsertedInto(
return kInsertionDone;
}
-void SVGStyleElement::RemovedFrom(ContainerNode* insertion_point) {
+void SVGStyleElement::RemovedFrom(ContainerNode& insertion_point) {
SVGElement::RemovedFrom(insertion_point);
- StyleElement::RemovedFrom(*this, insertion_point);
+ StyleElement::RemovedFrom(*this, &insertion_point);
}
void SVGStyleElement::ChildrenChanged(const ChildrenChange& change) {
@@ -139,7 +139,7 @@ void SVGStyleElement::NotifyLoadedSheetAndAllCriticalSubresources(
}
void SVGStyleElement::DispatchPendingEvent() {
- DispatchEvent(Event::Create(EventTypeNames::error));
+ DispatchEvent(*Event::Create(EventTypeNames::error));
}
void SVGStyleElement::Trace(blink::Visitor* 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 477c72042e2..763e0b14fe0 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
@@ -57,8 +57,8 @@ class SVGStyleElement final : public SVGElement, public StyleElement {
SVGStyleElement(Document&, const CreateElementFlags);
void ParseAttribute(const AttributeModificationParams&) override;
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
- void RemovedFrom(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
+ void RemovedFrom(ContainerNode&) override;
void ChildrenChanged(const ChildrenChange&) override;
void FinishParsingChildren() 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 3402a3c1831..f681199c635 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
@@ -122,16 +122,13 @@ class SVGCurrentTranslateTearOff : public SVGPointTearOff {
}
void CommitChange() override {
- DCHECK(contextElement());
- ToSVGSVGElement(contextElement())->UpdateUserTransform();
+ DCHECK(ContextElement());
+ ToSVGSVGElement(ContextElement())->UpdateUserTransform();
}
private:
SVGCurrentTranslateTearOff(SVGSVGElement* context_element)
- : SVGPointTearOff(context_element->translation_,
- context_element,
- kPropertyIsNotAnimVal,
- QualifiedName::Null()) {}
+ : SVGPointTearOff(context_element->translation_, context_element) {}
};
SVGPointTearOff* SVGSVGElement::currentTranslateFromJavascript() {
@@ -202,7 +199,7 @@ void SVGSVGElement::ParseAttribute(const AttributeModificationParams& params) {
name == SVGNames::widthAttr ? width_ : height_;
SVGParsingError parse_error;
if (!value.IsNull())
- parse_error = property->SetBaseValueAsString(value);
+ parse_error = property->AttributeChanged(value);
if (parse_error != SVGParseStatus::kNoError || value.IsNull())
property->SetDefaultValueAsString("100%");
ReportAttributeParsingError(parse_error, name, value);
@@ -332,7 +329,7 @@ bool SVGSVGElement::CheckIntersectionOrEnclosure(
LayoutObject* layout_object = element.GetLayoutObject();
DCHECK(!layout_object || layout_object->Style());
if (!layout_object ||
- layout_object->Style()->PointerEvents() == EPointerEvents::kNone)
+ layout_object->StyleRef().PointerEvents() == EPointerEvents::kNone)
return false;
if (!IsIntersectionOrEnclosureTarget(layout_object))
@@ -523,10 +520,10 @@ LayoutObject* SVGSVGElement::CreateLayoutObject(const ComputedStyle&) {
}
Node::InsertionNotificationRequest SVGSVGElement::InsertedInto(
- ContainerNode* root_parent) {
- if (root_parent->isConnected()) {
+ ContainerNode& root_parent) {
+ if (root_parent.isConnected()) {
UseCounter::Count(GetDocument(), WebFeature::kSVGSVGElementInDocument);
- if (root_parent->GetDocument().IsXMLDocument())
+ if (root_parent.GetDocument().IsXMLDocument())
UseCounter::Count(GetDocument(), WebFeature::kSVGSVGElementInXMLDocument);
if (RuntimeEnabledFeatures::SMILEnabled()) {
@@ -544,8 +541,8 @@ Node::InsertionNotificationRequest SVGSVGElement::InsertedInto(
return SVGGraphicsElement::InsertedInto(root_parent);
}
-void SVGSVGElement::RemovedFrom(ContainerNode* root_parent) {
- if (root_parent->isConnected()) {
+void SVGSVGElement::RemovedFrom(ContainerNode& root_parent) {
+ if (root_parent.isConnected()) {
SVGDocumentExtensions& svg_extensions = GetDocument().AccessSVGExtensions();
svg_extensions.RemoveTimeContainer(this);
svg_extensions.RemoveSVGRootWithRelativeLengthDescendents(this);
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 f843f67f7c5..550b9290cd1 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
@@ -129,8 +129,8 @@ class SVGSVGElement final : public SVGGraphicsElement,
bool LayoutObjectIsNeeded(const ComputedStyle&) const override;
LayoutObject* CreateLayoutObject(const ComputedStyle&) override;
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
- void RemovedFrom(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
+ void RemovedFrom(ContainerNode&) override;
void SvgAttributeChanged(const QualifiedName&) override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_tests.cc b/chromium/third_party/blink/renderer/core/svg/svg_tests.cc
index 4ef738bc748..7a9f9127ed3 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_tests.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_tests.cc
@@ -53,11 +53,18 @@ SVGStringListTearOff* SVGTests::systemLanguage() {
return system_language_->TearOff();
}
+static bool IsLangTagPrefix(const String& lang_tag, const String& language) {
+ if (!lang_tag.StartsWithIgnoringASCIICase(language))
+ return false;
+ return lang_tag.length() == language.length() ||
+ lang_tag[language.length()] == '-';
+}
+
bool SVGTests::IsValid() const {
if (system_language_->IsSpecified()) {
bool match_found = false;
- for (const auto& value : system_language_->Value()->Values()) {
- if (value.length() == 2 && DefaultLanguage().StartsWith(value)) {
+ for (const auto& lang_tag : system_language_->Value()->Values()) {
+ if (IsLangTagPrefix(lang_tag, DefaultLanguage())) {
match_found = true;
break;
}
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 42871653d94..c342f76ee7e 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
@@ -59,7 +59,7 @@ class SVGAnimatedTextLength final : public SVGAnimatedLength {
SVGLengthTearOff* baseVal() override {
SVGTextContentElement* text_content_element =
- ToSVGTextContentElement(contextElement());
+ ToSVGTextContentElement(ContextElement());
if (!text_content_element->TextLengthIsSpecifiedByUser())
BaseValue()->NewValueSpecifiedUnits(
CSSPrimitiveValue::UnitType::kNumber,
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 90d0e3eb79e..6c419aad771 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
@@ -137,15 +137,15 @@ void SVGTextPathElement::BuildPendingResource() {
}
Node::InsertionNotificationRequest SVGTextPathElement::InsertedInto(
- ContainerNode* root_parent) {
+ ContainerNode& root_parent) {
SVGTextContentElement::InsertedInto(root_parent);
BuildPendingResource();
return kInsertionDone;
}
-void SVGTextPathElement::RemovedFrom(ContainerNode* root_parent) {
+void SVGTextPathElement::RemovedFrom(ContainerNode& root_parent) {
SVGTextContentElement::RemovedFrom(root_parent);
- if (root_parent->isConnected())
+ if (root_parent.isConnected())
ClearResourceReferences();
}
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 a06acd17856..a1816bc891e 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
@@ -81,8 +81,8 @@ class SVGTextPathElement final : public SVGTextContentElement,
void ClearResourceReferences();
void BuildPendingResource() override;
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
- void RemovedFrom(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
+ void RemovedFrom(ContainerNode&) override;
void SvgAttributeChanged(const QualifiedName&) override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_title_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_title_element.cc
index 17071c20a99..c98d0599bfc 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_title_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_title_element.cc
@@ -35,18 +35,18 @@ inline SVGTitleElement::SVGTitleElement(Document& document)
DEFINE_NODE_FACTORY(SVGTitleElement)
Node::InsertionNotificationRequest SVGTitleElement::InsertedInto(
- ContainerNode* root_parent) {
+ ContainerNode& root_parent) {
SVGElement::InsertedInto(root_parent);
- if (!root_parent->isConnected())
+ if (!root_parent.isConnected())
return kInsertionDone;
if (HasChildren() && GetDocument().IsSVGDocument())
GetDocument().SetTitleElement(this);
return kInsertionDone;
}
-void SVGTitleElement::RemovedFrom(ContainerNode* root_parent) {
+void SVGTitleElement::RemovedFrom(ContainerNode& root_parent) {
SVGElement::RemovedFrom(root_parent);
- if (root_parent->isConnected() && GetDocument().IsSVGDocument())
+ if (root_parent.isConnected() && GetDocument().IsSVGDocument())
GetDocument().RemoveTitle(this);
}
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_title_element.h b/chromium/third_party/blink/renderer/core/svg/svg_title_element.h
index 3f67126348b..6b662d3de67 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_title_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_title_element.h
@@ -36,8 +36,8 @@ class SVGTitleElement final : public SVGElement {
private:
explicit SVGTitleElement(Document&);
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
- void RemovedFrom(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
+ void RemovedFrom(ContainerNode&) override;
void ChildrenChanged(const ChildrenChange&) override;
bool LayoutObjectIsNeeded(const ComputedStyle&) const override {
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 1d5285ccdc9..f00965a4bdf 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
@@ -363,18 +363,7 @@ SVGTransformType ParseTransformType(const String& string) {
}
String SVGTransformList::ValueAsString() const {
- StringBuilder builder;
-
- ConstIterator it = begin();
- ConstIterator it_end = end();
- while (it != it_end) {
- builder.Append(it->ValueAsString());
- ++it;
- if (it != it_end)
- builder.Append(' ');
- }
-
- return builder.ToString();
+ return SVGListPropertyHelper<SVGTransformList, SVGTransform>::SerializeList();
}
SVGParsingError SVGTransformList::SetValueAsString(const String& value) {
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_transform_list_tear_off.cc b/chromium/third_party/blink/renderer/core/svg/svg_transform_list_tear_off.cc
index 7e1ee963933..070b685f8fb 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_transform_list_tear_off.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_transform_list_tear_off.cc
@@ -36,14 +36,12 @@ namespace blink {
SVGTransformListTearOff::SVGTransformListTearOff(
SVGTransformList* target,
- SVGElement* context_element,
- PropertyIsAnimValType property_is_anim_val,
- const QualifiedName& attribute_name = QualifiedName::Null())
+ SVGAnimatedPropertyBase* binding,
+ PropertyIsAnimValType property_is_anim_val)
: SVGListPropertyTearOffHelper<SVGTransformListTearOff, SVGTransformList>(
target,
- context_element,
- property_is_anim_val,
- attribute_name) {}
+ binding,
+ property_is_anim_val) {}
SVGTransformListTearOff::~SVGTransformListTearOff() = default;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_transform_list_tear_off.h b/chromium/third_party/blink/renderer/core/svg/svg_transform_list_tear_off.h
index fe8fa28a37a..4819715f240 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_transform_list_tear_off.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_transform_list_tear_off.h
@@ -47,11 +47,9 @@ class SVGTransformListTearOff final
public:
static SVGTransformListTearOff* Create(
SVGTransformList* target,
- SVGElement* context_element,
- PropertyIsAnimValType property_is_anim_val,
- const QualifiedName& attribute_name) {
- return new SVGTransformListTearOff(target, context_element,
- property_is_anim_val, attribute_name);
+ SVGAnimatedPropertyBase* binding,
+ PropertyIsAnimValType property_is_anim_val) {
+ return new SVGTransformListTearOff(target, binding, property_is_anim_val);
}
~SVGTransformListTearOff() override;
@@ -61,9 +59,8 @@ class SVGTransformListTearOff final
private:
SVGTransformListTearOff(SVGTransformList*,
- SVGElement*,
- PropertyIsAnimValType,
- const QualifiedName&);
+ SVGAnimatedPropertyBase* binding,
+ PropertyIsAnimValType);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_transform_tear_off.cc b/chromium/third_party/blink/renderer/core/svg/svg_transform_tear_off.cc
index fa15a5379a3..83e32e181b7 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
@@ -30,20 +30,15 @@
#include "third_party/blink/renderer/core/svg/svg_transform_tear_off.h"
-#include "third_party/blink/renderer/core/svg/svg_element.h"
#include "third_party/blink/renderer/core/svg/svg_matrix_tear_off.h"
namespace blink {
SVGTransformTearOff::SVGTransformTearOff(
SVGTransform* target,
- SVGElement* context_element,
- PropertyIsAnimValType property_is_anim_val,
- const QualifiedName& attribute_name)
- : SVGPropertyTearOff<SVGTransform>(target,
- context_element,
- property_is_anim_val,
- attribute_name) {}
+ SVGAnimatedPropertyBase* binding,
+ PropertyIsAnimValType property_is_anim_val)
+ : SVGPropertyTearOff<SVGTransform>(target, binding, property_is_anim_val) {}
SVGTransformTearOff::~SVGTransformTearOff() = default;
@@ -54,12 +49,12 @@ void SVGTransformTearOff::Trace(blink::Visitor* visitor) {
SVGTransformTearOff* SVGTransformTearOff::CreateDetached() {
return Create(SVGTransform::Create(blink::kSvgTransformMatrix), nullptr,
- kPropertyIsNotAnimVal, QualifiedName::Null());
+ kPropertyIsNotAnimVal);
}
SVGTransformTearOff* SVGTransformTearOff::Create(SVGMatrixTearOff* matrix) {
return Create(SVGTransform::Create(matrix->Value()), nullptr,
- kPropertyIsNotAnimVal, QualifiedName::Null());
+ kPropertyIsNotAnimVal);
}
SVGMatrixTearOff* SVGTransformTearOff::matrix() {
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 98f524f1a58..c9901d9a6ad 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
@@ -52,12 +52,11 @@ class SVGTransformTearOff final : public SVGPropertyTearOff<SVGTransform> {
kSvgTransformSkewy = blink::kSvgTransformSkewy,
};
- static SVGTransformTearOff* Create(SVGTransform* target,
- SVGElement* context_element,
- PropertyIsAnimValType property_is_anim_val,
- const QualifiedName& attribute_name) {
- return new SVGTransformTearOff(target, context_element,
- property_is_anim_val, attribute_name);
+ static SVGTransformTearOff* Create(
+ SVGTransform* target,
+ SVGAnimatedPropertyBase* binding,
+ PropertyIsAnimValType property_is_anim_val) {
+ return new SVGTransformTearOff(target, binding, property_is_anim_val);
}
static SVGTransformTearOff* CreateDetached();
static SVGTransformTearOff* Create(SVGMatrixTearOff*);
@@ -79,9 +78,8 @@ class SVGTransformTearOff final : public SVGPropertyTearOff<SVGTransform> {
private:
SVGTransformTearOff(SVGTransform*,
- SVGElement* context_element,
- PropertyIsAnimValType,
- const QualifiedName& attribute_name);
+ SVGAnimatedPropertyBase* binding,
+ PropertyIsAnimValType);
Member<SVGMatrixTearOff> matrix_tearoff_;
};
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 bdbc55c8092..e7a380160f8 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
@@ -25,7 +25,6 @@
#include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h"
#include "third_party/blink/renderer/core/svg/svg_element.h"
#include "third_party/blink/renderer/core/xlink_names.h"
-#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
namespace blink {
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 efa593f34ec..9b0d5050fc7 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
@@ -26,12 +26,15 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/svg/svg_animated_href.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/weborigin/kurl.h"
namespace blink {
class Document;
class Element;
class IdTargetObserver;
+class SVGElement;
+class TreeScope;
class CORE_EXPORT SVGURIReference : public GarbageCollectedMixin {
public:
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 06df52944f0..b013b75b95b 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
@@ -112,11 +112,11 @@ static inline bool IsWellFormedDocument(Document* document) {
#endif
Node::InsertionNotificationRequest SVGUseElement::InsertedInto(
- ContainerNode* root_parent) {
+ ContainerNode& root_parent) {
// This functions exists to assure assumptions made in the code regarding
// SVGElementInstance creation/destruction are satisfied.
SVGGraphicsElement::InsertedInto(root_parent);
- if (!root_parent->isConnected())
+ if (!root_parent.isConnected())
return kInsertionDone;
#if DCHECK_IS_ON()
DCHECK(!target_element_instance_ || !IsWellFormedDocument(&GetDocument()));
@@ -125,9 +125,9 @@ Node::InsertionNotificationRequest SVGUseElement::InsertedInto(
return kInsertionDone;
}
-void SVGUseElement::RemovedFrom(ContainerNode* root_parent) {
+void SVGUseElement::RemovedFrom(ContainerNode& root_parent) {
SVGGraphicsElement::RemovedFrom(root_parent);
- if (root_parent->isConnected()) {
+ if (root_parent.isConnected()) {
ClearResourceReference();
CancelShadowTreeRecreation();
}
@@ -212,6 +212,8 @@ void SVGUseElement::UpdateTargetReference() {
ResourceLoaderOptions options;
options.initiator_info.name = localName();
FetchParameters params(ResourceRequest(element_url_), options);
+ params.MutableResourceRequest().SetFetchRequestMode(
+ network::mojom::FetchRequestMode::kSameOrigin);
DocumentResource::FetchSVGDocument(params, GetDocument().Fetcher(), this);
}
@@ -698,7 +700,7 @@ FloatRect SVGUseElement::GetBBox() {
void SVGUseElement::DispatchPendingEvent() {
DCHECK(IsStructurallyExternal());
DCHECK(have_fired_load_event_);
- DispatchEvent(Event::Create(EventTypeNames::load));
+ DispatchEvent(*Event::Create(EventTypeNames::load));
}
void SVGUseElement::NotifyFinished(Resource* resource) {
@@ -708,7 +710,7 @@ void SVGUseElement::NotifyFinished(Resource* resource) {
InvalidateShadowTree();
if (!ResourceIsValid()) {
- DispatchEvent(Event::Create(EventTypeNames::error));
+ DispatchEvent(*Event::Create(EventTypeNames::error));
} else if (!resource->WasCanceled()) {
if (have_fired_load_event_)
return;
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 5bbe0d33cea..f231c9fc15e 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
@@ -75,8 +75,8 @@ class SVGUseElement final : public SVGGraphicsElement,
bool IsStructurallyExternal() const override;
- InsertionNotificationRequest InsertedInto(ContainerNode*) override;
- void RemovedFrom(ContainerNode*) override;
+ InsertionNotificationRequest InsertedInto(ContainerNode&) override;
+ void RemovedFrom(ContainerNode&) override;
void SvgAttributeChanged(const QualifiedName&) override;
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 b86cc174ffe..366e634980e 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
@@ -7,9 +7,9 @@
#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/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/loader/fetch/memory_cache.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/core/testing/data/content_editable_multiline.html b/chromium/third_party/blink/renderer/core/testing/data/content_editable_multiline.html
new file mode 100644
index 00000000000..078342b6537
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/testing/data/content_editable_multiline.html
@@ -0,0 +1 @@
+<span contenteditable="true">0123456789<br>abcdefghijklmnopqrstuvwxyz</span> \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/core/testing/data/disambiguation_popup.html b/chromium/third_party/blink/renderer/core/testing/data/disambiguation_popup.html
deleted file mode 100644
index b1af285ce61..00000000000
--- a/chromium/third_party/blink/renderer/core/testing/data/disambiguation_popup.html
+++ /dev/null
@@ -1,30 +0,0 @@
-<html>
-<head>
-<title>Disambiguation Popup Test</title>
-<style type="text/css">
-.horizontal-link {
- display:block;
- width:200px;
- height:30px;
- margin:20px;
- background-color:#ccccff;
-}
-.vertical-link {
- display:inline-block;
- width:30px;
- height:200px;
- margin:10px;
- background-color:#ccccff;
-}
-</style>
-</head>
-<body style="margin:0px;">
-<a href="#" class="horizontal-link" style="margin:100px">Link</a>
-<a href="#" class="horizontal-link">Link 1</a>
-<a href="#" class="horizontal-link">Link 2</a>
-<a href="#" class="horizontal-link">Link 3</a>
-<a href="#" class="horizontal-link">Link 4</a>
-<a href="#" class="horizontal-link">Link 5</a>
-<a href="#" class="vertical-link">Link 1</a><a href="#" class="vertical-link">Link 2</a><a href="#" class="vertical-link">Link 3</a><a href="#" class="vertical-link">Link 4</a><a href="#" class="vertical-link">Link 5</a>
-</body>
-</html>
diff --git a/chromium/third_party/blink/renderer/core/testing/data/disambiguation_popup_200_by_800.html b/chromium/third_party/blink/renderer/core/testing/data/disambiguation_popup_200_by_800.html
deleted file mode 100644
index ab0f4e3367e..00000000000
--- a/chromium/third_party/blink/renderer/core/testing/data/disambiguation_popup_200_by_800.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <meta name="viewport" content="width=200">
-
- <style type="text/css">
- body {
- margin: 0px;
- }
- .upper {
- background-color: #ffbbaa;
- width: 200px;
- height: 400px;
- }
- .lower {
- background-color: #ffddaa;
- width: 200px;
- height: 400px;
- }
- .horizontal-link {
- display:block;
- width:200px;
- height:30px;
- margin-top:2px;
- background-color:#ccccff;
- }
- </style>
- </head>
- <body>
- <div class="upper"></div>
- <div class="lower">
- <div style="height:200px"></div>
- <a href="#" class="horizontal-link">Link 1</a>
- <a href="#" class="horizontal-link">Link 2</a>
- </div>
- </body>
-</html>
diff --git a/chromium/third_party/blink/renderer/core/testing/data/disambiguation_popup_blacklist.html b/chromium/third_party/blink/renderer/core/testing/data/disambiguation_popup_blacklist.html
deleted file mode 100644
index 8c19676b4cc..00000000000
--- a/chromium/third_party/blink/renderer/core/testing/data/disambiguation_popup_blacklist.html
+++ /dev/null
@@ -1,36 +0,0 @@
-<html>
- <head>
- <style>
- div {
- height: 100px;
- margin: 0px;
- text-align: center;
- width: 100%;
- }
- div.tightlyPacked {
- background-color: pink;
- border: 1px solid black;
- }
- div.bugContainer {
- background-color: cyan;
- }
- </style>
- </head>
- <body>
- <div class="tightlyPacked" onclick="window.location='#first';">
- <div>Leaf node #1</div>
- </div>
- <div class="tightlyPacked" onclick="window.location='#second';">
- <div>Leaf node #2</div>
- </div>
- <div></div>
- <div class="bugContainer" onclick="window.location='#third';">
- <p class="title">
- <a class="title" href="#fourth">Random link</a>
- </p>
- <p>
- Breaking node
- </p>
- </div>
- </body>
-</html>
diff --git a/chromium/third_party/blink/renderer/core/testing/data/disambiguation_popup_mobile_site.html b/chromium/third_party/blink/renderer/core/testing/data/disambiguation_popup_mobile_site.html
deleted file mode 100644
index 3d468f2e00a..00000000000
--- a/chromium/third_party/blink/renderer/core/testing/data/disambiguation_popup_mobile_site.html
+++ /dev/null
@@ -1,31 +0,0 @@
-<html>
-<head>
-<title>Disambiguation Popup Test</title>
-<style type="text/css">
-.horizontal-link {
- display:block;
- width:200px;
- height:30px;
- margin:20px;
- background-color:#ccccff;
-}
-.vertical-link {
- display:inline-block;
- width:30px;
- height:200px;
- margin:10px;
- background-color:#ccccff;
-}
-</style>
-<meta name="viewport" content="width=device-width">
-</head>
-<body style="margin:0px;">
-<a href="#" class="horizontal-link" style="margin:100px">Link</a>
-<a href="#" class="horizontal-link">Link 1</a>
-<a href="#" class="horizontal-link">Link 2</a>
-<a href="#" class="horizontal-link">Link 3</a>
-<a href="#" class="horizontal-link">Link 4</a>
-<a href="#" class="horizontal-link">Link 5</a>
-<a href="#" class="vertical-link">Link 1</a><a href="#" class="vertical-link">Link 2</a><a href="#" class="vertical-link">Link 3</a><a href="#" class="vertical-link">Link 4</a><a href="#" class="vertical-link">Link 5</a>
-</body>
-</html>
diff --git a/chromium/third_party/blink/renderer/core/testing/data/disambiguation_popup_no_container.html b/chromium/third_party/blink/renderer/core/testing/data/disambiguation_popup_no_container.html
deleted file mode 100644
index 7d2af3e748d..00000000000
--- a/chromium/third_party/blink/renderer/core/testing/data/disambiguation_popup_no_container.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<html>
-<head>
-<title>Disambiguation Popup Test</title>
-<style type="text/css">
-.outer-div {
- display:block;
- width:200px;
- height:200px;
- margin:0px;
- padding:50px;
- background-color:#ffcccc;
-}
-.inner-link {
- display:block;
- width:200px;
- height:200px;
- margin:0px;
- background-color:#ccffcc;
-}
-</style>
-</head>
-<body style="margin:0px;">
-<div class="outer-div" onclick=";"><a href="#" class="inner-link"></a></a>
-</body>
-</html>
diff --git a/chromium/third_party/blink/renderer/core/testing/data/disambiguation_popup_page_scale.html b/chromium/third_party/blink/renderer/core/testing/data/disambiguation_popup_page_scale.html
deleted file mode 100644
index 0b8b7f5dfac..00000000000
--- a/chromium/third_party/blink/renderer/core/testing/data/disambiguation_popup_page_scale.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<html>
-<head>
-<title>Disambiguation Popup Test</title>
-<style type="text/css">
-.link {
- display:block;
- position:absolute;
- width:200px;
- height:30px;
- background-color:#ccccff;
-}
-</style>
-</head>
-<body>
-<a href="#" class="link" style="left:50px;top:50px;">Link 1</a>
-<a href="#" class="link" style="left:50px;top:80px;">Link 2</a>
-<a href="#" class="link" style="left:200px;top:150px;">Link 3</a>
-<a href="#" class="link" style="left:200px;top:200px;">Link 4</a>
-</body>
-</html>
diff --git a/chromium/third_party/blink/renderer/core/testing/data/disambiguation_popup_viewport_site.html b/chromium/third_party/blink/renderer/core/testing/data/disambiguation_popup_viewport_site.html
deleted file mode 100644
index 9042185edbb..00000000000
--- a/chromium/third_party/blink/renderer/core/testing/data/disambiguation_popup_viewport_site.html
+++ /dev/null
@@ -1,38 +0,0 @@
-<html>
-<head>
-<title>Disambiguation Popup Test</title>
-<style type="text/css">
-@viewport {
- width: auto;
- height: auto;
- min-zoom: auto;
- max-zoom: auto;
- zoom: auto;
- user-zoom: zoom;
-}
-.horizontal-link {
- display:block;
- width:200px;
- height:30px;
- margin:20px;
- background-color:#ccccff;
-}
-.vertical-link {
- display:inline-block;
- width:30px;
- height:200px;
- margin:10px;
- background-color:#ccccff;
-}
-</style>
-</head>
-<body style="margin:0px;">
-<a href="#" class="horizontal-link" style="margin:100px">Link</a>
-<a href="#" class="horizontal-link">Link 1</a>
-<a href="#" class="horizontal-link">Link 2</a>
-<a href="#" class="horizontal-link">Link 3</a>
-<a href="#" class="horizontal-link">Link 4</a>
-<a href="#" class="horizontal-link">Link 5</a>
-<a href="#" class="vertical-link">Link 1</a><a href="#" class="vertical-link">Link 2</a><a href="#" class="vertical-link">Link 3</a><a href="#" class="vertical-link">Link 4</a><a href="#" class="vertical-link">Link 5</a>
-</body>
-</html>
diff --git a/chromium/third_party/blink/renderer/core/testing/data/input_placeholder.html b/chromium/third_party/blink/renderer/core/testing/data/input_placeholder.html
new file mode 100644
index 00000000000..bde311a331e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/testing/data/input_placeholder.html
@@ -0,0 +1 @@
+<input id="input" type="text" name="name" placeholder="username" />
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 0c3275090d6..a8f5e173e41 100644
--- a/chromium/third_party/blink/renderer/core/testing/dictionary_test.cc
+++ b/chromium/third_party/blink/renderer/core/testing/dictionary_test.cc
@@ -100,6 +100,7 @@ void DictionaryTest::set(const InternalDictionary& testing_dictionary) {
testing_dictionary.internalEnumOrInternalEnumSequenceMember();
}
any_member_ = testing_dictionary.anyMember();
+ callback_function_member_ = testing_dictionary.callbackFunctionMember();
}
void DictionaryTest::get(InternalDictionary& result) {
@@ -155,6 +156,7 @@ void DictionaryTest::get(InternalDictionary& result) {
result.setInternalEnumOrInternalEnumSequenceMember(
internal_enum_or_internal_enum_sequence_);
result.setAnyMember(any_member_);
+ result.setCallbackFunctionMember(callback_function_member_);
}
ScriptValue DictionaryTest::getDictionaryMemberProperties(
@@ -221,7 +223,7 @@ String DictionaryTest::stringFromIterable(
v8::Local<v8::Value> value;
if (iterator.GetValue().ToLocal(&value))
- result.Append(ToCoreString(value->ToString()));
+ result.Append(ToCoreString(value->ToString(script_state->GetIsolate())));
}
return result.ToString();
@@ -258,6 +260,7 @@ void DictionaryTest::Reset() {
internal_enum_or_internal_enum_sequence_ =
InternalEnumOrInternalEnumSequence();
any_member_ = ScriptValue();
+ callback_function_member_ = nullptr;
}
void DictionaryTest::Trace(blink::Visitor* visitor) {
@@ -265,6 +268,7 @@ void DictionaryTest::Trace(blink::Visitor* visitor) {
visitor->Trace(element_or_null_member_);
visitor->Trace(double_or_string_sequence_member_);
visitor->Trace(event_target_or_null_member_);
+ visitor->Trace(callback_function_member_);
ScriptWrappable::Trace(visitor);
}
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 34157aa4058..eb66e37b4d1 100644
--- a/chromium/third_party/blink/renderer/core/testing/dictionary_test.h
+++ b/chromium/third_party/blink/renderer/core/testing/dictionary_test.h
@@ -9,6 +9,7 @@
#include "third_party/blink/renderer/bindings/core/v8/double_or_string.h"
#include "third_party/blink/renderer/bindings/core/v8/internal_enum_or_internal_enum_sequence.h"
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_test_callback.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/heap/handle.h"
@@ -92,6 +93,7 @@ class DictionaryTest : public ScriptWrappable {
base::Optional<HashMap<String, String>> dictionary_member_properties_;
InternalEnumOrInternalEnumSequence internal_enum_or_internal_enum_sequence_;
ScriptValue any_member_;
+ TraceWrapperMember<V8TestCallback> callback_function_member_;
};
} // namespace blink
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 c9df0aaf210..edb29e145db 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
@@ -87,7 +87,7 @@ class DummyPageHolder {
Persistent<Page> page_;
// The LocalFrame is accessed from worker threads by unit tests
- // (WorkerThreadableLoaderTest), hence we need to allow cross-thread
+ // (ThreadableLoaderTest), hence we need to allow cross-thread
// usage of |m_frame|.
//
// TODO: rework the tests to not require cross-thread access.
diff --git a/chromium/third_party/blink/renderer/core/testing/gc_object_liveness_observer.h b/chromium/third_party/blink/renderer/core/testing/gc_object_liveness_observer.h
new file mode 100644
index 00000000000..e713a435446
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/testing/gc_object_liveness_observer.h
@@ -0,0 +1,45 @@
+// 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_GC_OBJECT_LIVENESS_OBSERVER_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_TESTING_GC_OBJECT_LIVENESS_OBSERVER_H_
+
+#include <memory>
+
+#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/wtf/allocator.h"
+
+namespace blink {
+
+// Observer that can be used to track whether an object has been reclaimed by
+// the garbage collector.
+template <typename T>
+class GCObjectLivenessObserver {
+ STACK_ALLOCATED();
+
+ public:
+ GCObjectLivenessObserver() = default;
+
+ explicit GCObjectLivenessObserver(T* object)
+ : holder_(
+ std::unique_ptr<WeakPersistent<T>>{new WeakPersistent<T>(object)}) {
+ }
+
+ void Observe(T* object) {
+ DCHECK(!holder_.get());
+ holder_.reset(new WeakPersistent<T>(object));
+ }
+
+ bool WasCollected() const { return !holder_->Get(); }
+
+ private:
+ // WeakPersistent needs to be allocated separately to allow using
+ // GCObjectLivenessObserver from stack. Otherwise, Oilpan could treat pointers
+ // reachable from stack as strong.
+ std::unique_ptr<WeakPersistent<T>> holder_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_TESTING_GC_OBJECT_LIVENESS_OBSERVER_H_
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 ef18a2ca4fa..6a87abda00d 100644
--- a/chromium/third_party/blink/renderer/core/testing/internal_dictionary.idl
+++ b/chromium/third_party/blink/renderer/core/testing/internal_dictionary.idl
@@ -36,4 +36,5 @@ dictionary InternalDictionary {
Dictionary dictionaryMember;
(InternalEnum or sequence<InternalEnum>) internalEnumOrInternalEnumSequenceMember;
any anyMember;
+ TestCallback callbackFunctionMember;
};
diff --git a/chromium/third_party/blink/renderer/core/testing/internals.cc b/chromium/third_party/blink/renderer/core/testing/internals.cc
index 37cab2836be..1b9f5ff8b64 100644
--- a/chromium/third_party/blink/renderer/core/testing/internals.cc
+++ b/chromium/third_party/blink/renderer/core/testing/internals.cc
@@ -72,7 +72,7 @@
#include "third_party/blink/renderer/core/editing/plain_text_range.h"
#include "third_party/blink/renderer/core/editing/selection_template.h"
#include "third_party/blink/renderer/core/editing/serializers/serialization.h"
-#include "third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_callback.h"
+#include "third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller.h"
#include "third_party/blink/renderer/core/editing/spellcheck/spell_check_requester.h"
#include "third_party/blink/renderer/core/editing/spellcheck/spell_checker.h"
#include "third_party/blink/renderer/core/frame/event_handler_registry.h"
@@ -125,6 +125,9 @@
#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/scroll/programmatic_scroll_animator.h"
+#include "third_party/blink/renderer/core/scroll/scroll_animator_base.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
#include "third_party/blink/renderer/core/style_property_shorthand.h"
#include "third_party/blink/renderer/core/svg/svg_image_element.h"
#include "third_party/blink/renderer/core/svg_names.h"
@@ -161,9 +164,6 @@
#include "third_party/blink/renderer/platform/loader/fetch/resource_load_priority.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/scroll/programmatic_scroll_animator.h"
-#include "third_party/blink/renderer/platform/scroll/scroll_animator_base.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h"
#include "third_party/blink/renderer/platform/testing/url_test_helpers.h"
#include "third_party/blink/renderer/platform/text/layout_locale.h"
#include "third_party/blink/renderer/platform/weborigin/scheme_registry.h"
@@ -175,7 +175,7 @@
namespace blink {
-using ui::mojom::ImeTextSpanThickness;
+using ws::mojom::ImeTextSpanThickness;
namespace {
@@ -225,7 +225,7 @@ static base::Optional<DocumentMarker::MarkerType> MarkerTypeFrom(
static base::Optional<DocumentMarker::MarkerTypes> MarkerTypesFrom(
const String& marker_type) {
if (marker_type.IsEmpty() || DeprecatedEqualIgnoringCase(marker_type, "all"))
- return DocumentMarker::AllMarkers();
+ return DocumentMarker::MarkerTypes::All();
base::Optional<DocumentMarker::MarkerType> type = MarkerTypeFrom(marker_type);
if (!type)
return base::nullopt;
@@ -242,12 +242,6 @@ static ScrollableArea* ScrollableAreaForNode(Node* node) {
if (!node)
return nullptr;
- if (node->IsDocumentNode()) {
- // This can be removed after root layer scrolling is enabled.
- if (LocalFrameView* frame_view = ToDocument(node)->View())
- return frame_view->LayoutViewport();
- }
-
LayoutObject* layout_object = node->GetLayoutObject();
if (!layout_object || !layout_object->IsBox())
return nullptr;
@@ -942,7 +936,7 @@ unsigned Internals::markerCountForNode(Node* node,
return node->GetDocument()
.Markers()
- .MarkersFor(node, marker_types.value())
+ .MarkersFor(ToText(*node), marker_types.value())
.size();
}
@@ -950,9 +944,8 @@ unsigned Internals::activeMarkerCountForNode(Node* node) {
DCHECK(node);
// Only TextMatch markers can be active.
- DocumentMarker::MarkerType marker_type = DocumentMarker::kTextMatch;
- DocumentMarkerVector markers =
- node->GetDocument().Markers().MarkersFor(node, marker_type);
+ DocumentMarkerVector markers = node->GetDocument().Markers().MarkersFor(
+ ToText(*node), DocumentMarker::MarkerTypes::TextMatch());
unsigned active_marker_count = 0;
for (const auto& marker : markers) {
@@ -977,8 +970,8 @@ DocumentMarker* Internals::MarkerAt(Node* node,
return nullptr;
}
- DocumentMarkerVector markers =
- node->GetDocument().Markers().MarkersFor(node, marker_types.value());
+ DocumentMarkerVector markers = node->GetDocument().Markers().MarkersFor(
+ ToText(*node), marker_types.value());
if (markers.size() <= index)
return nullptr;
return markers[index];
@@ -1325,15 +1318,16 @@ void Internals::setAutofilledValue(Element* element,
}
if (auto* input = ToHTMLInputElementOrNull(*element)) {
- input->DispatchScopedEvent(Event::CreateBubble(EventTypeNames::keydown));
+ input->DispatchScopedEvent(*Event::CreateBubble(EventTypeNames::keydown));
input->SetAutofillValue(value);
- input->DispatchScopedEvent(Event::CreateBubble(EventTypeNames::keyup));
+ input->DispatchScopedEvent(*Event::CreateBubble(EventTypeNames::keyup));
}
if (auto* textarea = ToHTMLTextAreaElementOrNull(*element)) {
- textarea->DispatchScopedEvent(Event::CreateBubble(EventTypeNames::keydown));
+ textarea->DispatchScopedEvent(
+ *Event::CreateBubble(EventTypeNames::keydown));
textarea->SetAutofillValue(value);
- textarea->DispatchScopedEvent(Event::CreateBubble(EventTypeNames::keyup));
+ textarea->DispatchScopedEvent(*Event::CreateBubble(EventTypeNames::keyup));
}
if (auto* select = ToHTMLSelectElementOrNull(*element))
@@ -1589,7 +1583,7 @@ String Internals::idleTimeSpellCheckerState(Document* document,
ExceptionState& exception_state) {
static const char* const kTexts[] = {
#define V(state) #state,
- FOR_EACH_IDLE_SPELL_CHECK_CALLBACK_STATE(V)
+ FOR_EACH_IDLE_SPELL_CHECK_CONTROLLER_STATE(V)
#undef V
};
@@ -1600,10 +1594,10 @@ String Internals::idleTimeSpellCheckerState(Document* document,
return String();
}
- IdleSpellCheckCallback::State state = document->GetFrame()
- ->GetSpellChecker()
- .GetIdleSpellCheckCallback()
- .GetState();
+ IdleSpellCheckController::State state = document->GetFrame()
+ ->GetSpellChecker()
+ .GetIdleSpellCheckController()
+ .GetState();
auto* const* const it = std::begin(kTexts) + static_cast<size_t>(state);
DCHECK_GE(it, std::begin(kTexts)) << "Unknown state value";
DCHECK_LT(it, std::end(kTexts)) << "Unknown state value";
@@ -1621,7 +1615,7 @@ void Internals::runIdleTimeSpellChecker(Document* document,
document->GetFrame()
->GetSpellChecker()
- .GetIdleSpellCheckCallback()
+ .GetIdleSpellCheckController()
.ForceInvocationForTesting();
}
@@ -3060,7 +3054,7 @@ ScriptPromise Internals::addOneToPromise(ScriptState* script_state,
ScriptPromise Internals::promiseCheck(ScriptState* script_state,
long arg1,
bool arg2,
- const Dictionary& arg3,
+ const ScriptValue& arg3,
const String& arg4,
const Vector<String>& arg5,
ExceptionState& exception_state) {
@@ -3074,7 +3068,7 @@ ScriptPromise Internals::promiseCheck(ScriptState* script_state,
ScriptPromise Internals::promiseCheckWithoutExceptionState(
ScriptState* script_state,
- const Dictionary& arg1,
+ const ScriptValue& arg1,
const String& arg2,
const Vector<String>& arg3) {
return ScriptPromise::Cast(script_state,
@@ -3452,4 +3446,9 @@ void Internals::BypassLongCompileThresholdOnce(
}
return performance_monitor->BypassLongCompileThresholdOnceForTesting();
}
+
+unsigned Internals::LifecycleUpdateCount() const {
+ return document_->View()->LifecycleUpdateCountForTesting();
+}
+
} // 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 0a744c0afba..804debacfab 100644
--- a/chromium/third_party/blink/renderer/core/testing/internals.h
+++ b/chromium/third_party/blink/renderer/core/testing/internals.h
@@ -49,7 +49,6 @@ class DOMRectReadOnly;
class DOMArrayBuffer;
class DOMPoint;
class DOMWindow;
-class Dictionary;
class DictionaryTest;
class Document;
class DocumentMarker;
@@ -469,12 +468,12 @@ class Internals final : public ScriptWrappable {
ScriptPromise promiseCheck(ScriptState*,
long,
bool,
- const Dictionary&,
+ const ScriptValue&,
const String&,
const Vector<String>&,
ExceptionState&);
ScriptPromise promiseCheckWithoutExceptionState(ScriptState*,
- const Dictionary&,
+ const ScriptValue&,
const String&,
const Vector<String>&);
ScriptPromise promiseCheckRange(ScriptState*, long);
@@ -588,6 +587,10 @@ class Internals final : public ScriptWrappable {
void BypassLongCompileThresholdOnce(ExceptionState&);
+ // The number of calls to update the blink lifecycle (see:
+ // LocalFrameView::UpdateLifecyclePhasesInternal).
+ unsigned LifecycleUpdateCount() const;
+
private:
explicit Internals(ExecutionContext*);
Document* ContextDocument() const;
diff --git a/chromium/third_party/blink/renderer/core/testing/internals.idl b/chromium/third_party/blink/renderer/core/testing/internals.idl
index aaec0fa87a1..fc81aaaac0b 100644
--- a/chromium/third_party/blink/renderer/core/testing/internals.idl
+++ b/chromium/third_party/blink/renderer/core/testing/internals.idl
@@ -310,8 +310,8 @@ enum EffectiveConnectionType {
[CallWith=ScriptState] Promise createResolvedPromise(any value);
[CallWith=ScriptState] Promise createRejectedPromise(any reason);
[CallWith=ScriptState] Promise addOneToPromise(Promise promise);
- [CallWith=ScriptState, RaisesException] Promise promiseCheck(long arg1, boolean arg2, Dictionary arg3, DOMString arg4, sequence<DOMString> arg5);
- [CallWith=ScriptState] Promise promiseCheckWithoutExceptionState(Dictionary arg1, DOMString arg2, DOMString... variadic);
+ [CallWith=ScriptState, RaisesException] Promise promiseCheck(long arg1, boolean arg2, object arg3, DOMString arg4, sequence<DOMString> arg5);
+ [CallWith=ScriptState] Promise promiseCheckWithoutExceptionState(object arg1, DOMString arg2, DOMString... variadic);
[CallWith=ScriptState] Promise promiseCheckRange([EnforceRange] octet arg1);
[CallWith=ScriptState] Promise promiseCheckOverload(Location arg1);
[CallWith=ScriptState] Promise promiseCheckOverload(Document arg1);
@@ -407,4 +407,8 @@ enum EffectiveConnectionType {
// PerformanceMonitor for testing. "PerformanceObserver should be observing
// 'longtask' while calling BypassLongCompileThresholdOnce.
[RaisesException] void BypassLongCompileThresholdOnce();
+
+ // The number of calls to update the blink lifecycle (see:
+ // LocalFrameView::UpdateLifecyclePhasesInternal).
+ unsigned long LifecycleUpdateCount();
};
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 d642abe7c61..3564a566fb5 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
@@ -34,6 +34,10 @@ class NullExecutionContext
void DisableEval(const String&) override {}
String UserAgent() const override { return String(); }
+ HttpsState GetHttpsState() const override {
+ return CalculateHttpsState(GetSecurityOrigin());
+ }
+
EventTarget* ErrorEventTarget() override { return nullptr; }
bool TasksNeedPause() override { return tasks_need_pause_; }
@@ -42,6 +46,9 @@ class NullExecutionContext
void DidUpdateSecurityOrigin() override {}
SecurityContext& GetSecurityContext() override { return *this; }
DOMTimerCoordinator* Timers() override { return nullptr; }
+ const base::UnguessableToken& GetAgentClusterID() const final {
+ return base::UnguessableToken::Null();
+ }
void AddConsoleMessage(ConsoleMessage*) override {}
void ExceptionThrown(ErrorEvent*) override {}
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 d3c91c868f6..d4d083f529d 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
@@ -137,4 +137,10 @@ FocusController& PageTestBase::GetFocusController() const {
return GetDocument().GetPage()->GetFocusController();
}
+void PageTestBase::EnablePlatform() {
+ DCHECK(!platform_);
+ platform_ = std::make_unique<
+ ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>>();
+}
+
} // namespace blink
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 c09bef01efc..0b1eb9c1eec 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
@@ -7,6 +7,7 @@
#include <gtest/gtest.h>
#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
+#include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h"
namespace blink {
@@ -53,8 +54,19 @@ class PageTestBase : public testing::Test {
protected:
void LoadAhem();
+ void EnablePlatform();
+
+ ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>&
+ platform() {
+ return *platform_;
+ }
private:
+ // The order is important: |platform_| must be destroyed after
+ // |dummy_page_holder_| is destroyed.
+ std::unique_ptr<
+ ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>>
+ platform_;
std::unique_ptr<DummyPageHolder> dummy_page_holder_;
};
diff --git a/chromium/third_party/blink/renderer/core/testing/sim/sim_canvas.cc b/chromium/third_party/blink/renderer/core/testing/sim/sim_canvas.cc
index d133a09fb7a..8ea1b96e428 100644
--- a/chromium/third_party/blink/renderer/core/testing/sim/sim_canvas.cc
+++ b/chromium/third_party/blink/renderer/core/testing/sim/sim_canvas.cc
@@ -116,16 +116,6 @@ void SimCanvas::onDrawPosTextH(const void* text,
SkCanvas::onDrawPosTextH(text, byte_length, xpos, const_y, paint);
}
-void SimCanvas::onDrawTextOnPath(const void* text,
- size_t byte_length,
- const SkPath& path,
- const SkMatrix* matrix,
- const SkPaint& paint) {
- DrawScope scope;
- AddCommand(CommandType::kText, paint.getColor());
- SkCanvas::onDrawTextOnPath(text, byte_length, path, matrix, paint);
-}
-
void SimCanvas::onDrawTextBlob(const SkTextBlob* blob,
SkScalar x,
SkScalar y,
diff --git a/chromium/third_party/blink/renderer/core/testing/sim/sim_canvas.h b/chromium/third_party/blink/renderer/core/testing/sim/sim_canvas.h
index 34958086532..4c40108a576 100644
--- a/chromium/third_party/blink/renderer/core/testing/sim/sim_canvas.h
+++ b/chromium/third_party/blink/renderer/core/testing/sim/sim_canvas.h
@@ -76,11 +76,6 @@ class SimCanvas : public SkCanvas {
const SkScalar xpos[],
SkScalar const_y,
const SkPaint&) override;
- void onDrawTextOnPath(const void* text,
- size_t byte_length,
- const SkPath&,
- const SkMatrix*,
- const SkPaint&) override;
void onDrawTextBlob(const SkTextBlob*,
SkScalar x,
SkScalar y,
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 b816ca7ff90..c6a502ef7ba 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
@@ -6,13 +6,13 @@
#include "content/test/test_blink_web_unit_test_support.h"
#include "third_party/blink/public/platform/web_cache.h"
-#include "third_party/blink/public/web/web_navigation_timings.h"
+#include "third_party/blink/public/web/web_navigation_params.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_dom_window.h"
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
#include "third_party/blink/renderer/platform/layout_test_support.h"
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
namespace blink {
@@ -61,7 +61,8 @@ void SimTest::LoadURL(const String& url) {
WebURLRequest request{KURL(url)};
WebView().MainFrameImpl()->CommitNavigation(
request, WebFrameLoadType::kStandard, WebHistoryItem(), false,
- base::UnguessableToken::Create(), nullptr, WebNavigationTimings());
+ base::UnguessableToken::Create(), nullptr /* navigation_params */,
+ nullptr /* extra_data */);
}
LocalDOMWindow& SimTest::Window() {
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 7e798b1f878..a9632d1e5d9 100644
--- a/chromium/third_party/blink/renderer/core/testing/type_conversions.h
+++ b/chromium/third_party/blink/renderer/core/testing/type_conversions.h
@@ -37,17 +37,15 @@ class TypeConversions final : public ScriptWrappable {
public:
static TypeConversions* Create() { return new TypeConversions(); }
- long testLong() { return long_; }
- void setTestLong(long value) { long_ = value; }
- unsigned long testUnsignedLong() { return unsigned_long_; }
- void setTestUnsignedLong(unsigned long value) { unsigned_long_ = value; }
-
- long long testLongLong() { return long_long_; }
- void setTestLongLong(long long value) { long_long_ = value; }
- unsigned long long testUnsignedLongLong() { return unsigned_long_long_; }
- void setTestUnsignedLongLong(unsigned long long value) {
- unsigned_long_long_ = value;
- }
+ int32_t testLong() { return long_; }
+ void setTestLong(int32_t value) { long_ = value; }
+ uint32_t testUnsignedLong() { return unsigned_long_; }
+ void setTestUnsignedLong(uint32_t value) { unsigned_long_ = value; }
+
+ int64_t testLongLong() { return long_long_; }
+ void setTestLongLong(int64_t value) { long_long_ = value; }
+ uint64_t testUnsignedLongLong() { return unsigned_long_long_; }
+ void setTestUnsignedLongLong(uint64_t value) { unsigned_long_long_ = value; }
int8_t testByte() { return byte_; }
void setTestByte(int8_t value) { byte_ = value; }
@@ -81,10 +79,10 @@ class TypeConversions final : public ScriptWrappable {
short_(0),
unsigned_short_(0) {}
- long long_;
- unsigned long unsigned_long_;
- long long long_long_;
- unsigned long long unsigned_long_long_;
+ int32_t long_;
+ uint32_t unsigned_long_;
+ int64_t long_long_;
+ uint64_t unsigned_long_long_;
int8_t byte_;
uint8_t octet_;
int16_t short_;
diff --git a/chromium/third_party/blink/renderer/core/testing/use_mock_scrollbar_settings.h b/chromium/third_party/blink/renderer/core/testing/use_mock_scrollbar_settings.h
index 45e00a5cde9..5e867ff5212 100644
--- a/chromium/third_party/blink/renderer/core/testing/use_mock_scrollbar_settings.h
+++ b/chromium/third_party/blink/renderer/core/testing/use_mock_scrollbar_settings.h
@@ -5,7 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_TESTING_USE_MOCK_SCROLLBAR_SETTINGS_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_TESTING_USE_MOCK_SCROLLBAR_SETTINGS_H_
-#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h"
+#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/core/timing/BUILD.gn b/chromium/third_party/blink/renderer/core/timing/BUILD.gn
index 43ca5d90707..1ffeeff11b2 100644
--- a/chromium/third_party/blink/renderer/core/timing/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/timing/BUILD.gn
@@ -46,6 +46,8 @@ blink_core_sources("timing") {
"sub_task_attribution.h",
"task_attribution_timing.cc",
"task_attribution_timing.h",
+ "time_clamper.cc",
+ "time_clamper.h",
"window_performance.cc",
"window_performance.h",
"worker_global_scope_performance.cc",
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 d1ad5e978f8..acef9dfbddf 100644
--- a/chromium/third_party/blink/renderer/core/timing/event_timing.cc
+++ b/chromium/third_party/blink/renderer/core/timing/event_timing.cc
@@ -6,6 +6,7 @@
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/events/pointer_event.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/timing/dom_window_performance.h"
#include "third_party/blink/renderer/core/timing/performance_event_timing.h"
#include "third_party/blink/renderer/platform/wtf/time.h"
diff --git a/chromium/third_party/blink/renderer/core/timing/memory_info.cc b/chromium/third_party/blink/renderer/core/timing/memory_info.cc
index fd257d682a6..3c83c4480a6 100644
--- a/chromium/third_party/blink/renderer/core/timing/memory_info.cc
+++ b/chromium/third_party/blink/renderer/core/timing/memory_info.cc
@@ -81,7 +81,8 @@ class HeapSizeCache {
TimeDelta delta_allowed = precision == MemoryInfo::Precision::Bucketized
? kTwentyMinutes
: kFiftyMs;
- if (now - last_update_time_ >= delta_allowed) {
+ if (!last_update_time_.has_value() ||
+ now - last_update_time_.value() >= delta_allowed) {
Update(precision);
last_update_time_ = now;
}
@@ -97,7 +98,7 @@ class HeapSizeCache {
info_.js_heap_size_limit = QuantizeMemorySize(info_.js_heap_size_limit);
}
- TimeTicks last_update_time_;
+ base::Optional<TimeTicks> last_update_time_;
HeapInfo info_;
DISALLOW_COPY_AND_ASSIGN(HeapSizeCache);
@@ -157,10 +158,16 @@ size_t QuantizeMemorySize(size_t size) {
MemoryInfo::MemoryInfo(Precision precision) {
// With the experimental PreciseMemoryInfoEnabled flag on, we will not
- // bucketize or cache values.
+ // bucketize or cache values, regardless of the value of |precision|. When the
+ // flag is off then our cache is used and |precision| determines the
+ // granularity of the values and the timer of the cache we use.
if (RuntimeEnabledFeatures::PreciseMemoryInfoEnabled())
GetHeapSize(info_);
- HeapSizeCache::ForCurrentThread().GetCachedHeapSize(info_, precision);
+ else
+ HeapSizeCache::ForCurrentThread().GetCachedHeapSize(info_, precision);
+ // The values must have been computed, so totalJSHeapSize must be greater than
+ // 0.
+ DCHECK_GT(totalJSHeapSize(), 0u);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/timing/memory_info_test.cc b/chromium/third_party/blink/renderer/core/timing/memory_info_test.cc
index 90b1e3da954..5cebb2fb437 100644
--- a/chromium/third_party/blink/renderer/core/timing/memory_info_test.cc
+++ b/chromium/third_party/blink/renderer/core/timing/memory_info_test.cc
@@ -32,6 +32,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/platform/testing/runtime_enabled_features_test_helpers.h"
#include "third_party/blink/renderer/platform/wtf/time.h"
namespace blink {
@@ -204,4 +205,50 @@ TEST_F(MemoryInfoTest, Precise) {
}
}
+TEST_F(MemoryInfoTest, FlagEnabled) {
+ ScopedPreciseMemoryInfoForTest precise_memory_info(true);
+ V8TestingScope scope;
+ v8::Isolate* isolate = scope.GetIsolate();
+ std::vector<v8::Local<v8::ArrayBuffer>> objects;
+
+ // Using MemoryInfo::Precision::Bucketized to ensure that the runtime-enabled
+ // flag overrides the Precision passed onto the method.
+ MemoryInfo* precise_memory =
+ MemoryInfo::Create(MemoryInfo::Precision::Bucketized);
+ // Check that the precise values are monotone and not heavily rounded.
+ CheckValues(precise_memory, MemoryInfo::Precision::Precise);
+
+ // Allocate an object in heap and keep it in a vector to make sure that it
+ // does not get accidentally GC'd. This single ArrayBuffer should be enough to
+ // be noticed by the used heap size immediately since the
+ // PreciseMemoryInfoEnabled flag is on.
+ objects.push_back(v8::ArrayBuffer::New(isolate, 100));
+ MemoryInfo* precise_memory2 =
+ MemoryInfo::Create(MemoryInfo::Precision::Bucketized);
+ CheckValues(precise_memory2, MemoryInfo::Precision::Precise);
+ // The old precise JS heap size value must NOT be equal to the new value.
+ EXPECT_NE(precise_memory2->usedJSHeapSize(),
+ precise_memory->usedJSHeapSize());
+}
+
+TEST_F(MemoryInfoTest, ZeroTime) {
+ // In this test, we make sure that even if the CurrentTimeTicks() value is
+ // very close to 0, we still obtain memory information from the first call to
+ // MemoryInfo::Create. We cannot just subtract CurrentTimeTicks() here
+ // because many places have DCHECKs for !time.is_null(), which would be hit if
+ // we set the clock to be exactly 0.
+ AdvanceClock(-CurrentTimeTicksInSeconds() + 0.0001);
+ V8TestingScope scope;
+ v8::Isolate* isolate = scope.GetIsolate();
+ std::vector<v8::Local<v8::ArrayBuffer>> objects;
+ objects.push_back(v8::ArrayBuffer::New(isolate, 100));
+
+ MemoryInfo* precise_memory =
+ MemoryInfo::Create(MemoryInfo::Precision::Precise);
+ CheckValues(precise_memory, MemoryInfo::Precision::Precise);
+ EXPECT_LT(0u, precise_memory->usedJSHeapSize());
+ EXPECT_LT(0u, precise_memory->totalJSHeapSize());
+ EXPECT_LT(0u, precise_memory->jsHeapSizeLimit());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/timing/performance.cc b/chromium/third_party/blink/renderer/core/timing/performance.cc
index 99375ad1b0e..abab35e7359 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance.cc
+++ b/chromium/third_party/blink/renderer/core/timing/performance.cc
@@ -50,10 +50,10 @@
#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/time_clamper.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_response.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_timing_info.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
-#include "third_party/blink/renderer/platform/time_clamper.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "third_party/blink/renderer/platform/wtf/time.h"
@@ -85,14 +85,12 @@ DOMHighResTimeStamp GetUnixAtZeroMonotonic() {
using PerformanceObserverVector = HeapVector<Member<PerformanceObserver>>;
static const size_t kDefaultResourceTimingBufferSize = 250;
-static const size_t kDefaultFrameTimingBufferSize = 150;
constexpr size_t kDefaultEventTimingBufferSize = 150;
Performance::Performance(
TimeTicks time_origin,
scoped_refptr<base::SingleThreadTaskRunner> task_runner)
- : frame_timing_buffer_size_(kDefaultFrameTimingBufferSize),
- resource_timing_buffer_size_(kDefaultResourceTimingBufferSize),
+ : resource_timing_buffer_size_(kDefaultResourceTimingBufferSize),
event_timing_buffer_max_size_(kDefaultEventTimingBufferSize),
user_timing_(nullptr),
time_origin_(time_origin),
@@ -143,7 +141,6 @@ PerformanceEntryVector Performance::getEntries() {
// calls this method.
if (navigation_timing_)
entries.push_back(navigation_timing_);
- entries.AppendVector(frame_timing_buffer_);
if (user_timing_) {
entries.AppendVector(user_timing_->GetMarks());
@@ -189,14 +186,6 @@ PerformanceEntryVector Performance::getEntriesByType(
if (navigation_timing_)
entries.push_back(navigation_timing_);
break;
- case PerformanceEntry::kComposite:
- case PerformanceEntry::kRender:
- for (const auto& frame : frame_timing_buffer_) {
- if (type == frame->EntryTypeEnum()) {
- entries.push_back(frame);
- }
- }
- break;
case PerformanceEntry::kMark:
if (user_timing_)
entries.AppendVector(user_timing_->GetMarks());
@@ -230,7 +219,7 @@ PerformanceEntryVector Performance::getEntriesByType(
}
PerformanceEntryVector Performance::getEntriesByName(
- const String& name,
+ const AtomicString& name,
const AtomicString& entry_type) {
PerformanceEntryVector entries;
PerformanceEntry::EntryType type =
@@ -273,15 +262,6 @@ PerformanceEntryVector Performance::getEntriesByName(
entries.push_back(navigation_timing_);
}
- if (entry_type.IsNull() || type == PerformanceEntry::kComposite ||
- type == PerformanceEntry::kRender) {
- for (const auto& frame : frame_timing_buffer_) {
- if (frame->name() == name &&
- (entry_type.IsNull() || entry_type == frame->entryType()))
- entries.push_back(frame);
- }
- }
-
if (user_timing_) {
if (entry_type.IsNull() || type == PerformanceEntry::kMark)
entries.AppendVector(user_timing_->GetMarks(name));
@@ -309,7 +289,7 @@ void Performance::clearResourceTimings() {
void Performance::setResourceTimingBufferSize(unsigned size) {
resource_timing_buffer_size_ = size;
if (IsResourceTimingBufferFull())
- DispatchEvent(Event::Create(EventTypeNames::resourcetimingbufferfull));
+ DispatchEvent(*Event::Create(EventTypeNames::resourcetimingbufferfull));
}
bool Performance::PassesTimingAllowCheck(
@@ -490,7 +470,7 @@ void Performance::AddEventTimingBuffer(PerformanceEventTiming& entry) {
event_timing_buffer_.push_back(&entry);
if (IsEventTimingBufferFull())
- DispatchEvent(Event::Create(EventTypeNames::eventtimingbufferfull));
+ DispatchEvent(*Event::Create(EventTypeNames::eventtimingbufferfull));
}
unsigned Performance::EventTimingBufferSize() const {
@@ -504,7 +484,7 @@ void Performance::clearEventTimings() {
void Performance::setEventTimingBufferMaxSize(unsigned size) {
event_timing_buffer_max_size_ = size;
if (IsEventTimingBufferFull())
- DispatchEvent(Event::Create(EventTypeNames::eventtimingbufferfull));
+ DispatchEvent(*Event::Create(EventTypeNames::eventtimingbufferfull));
}
void Performance::AddFirstPaintTiming(TimeTicks start_time) {
@@ -518,9 +498,6 @@ void Performance::AddFirstContentfulPaintTiming(TimeTicks start_time) {
void Performance::AddPaintTiming(PerformancePaintTiming::PaintType type,
TimeTicks start_time) {
- if (!RuntimeEnabledFeatures::PerformancePaintTimingEnabled())
- return;
-
PerformanceEntry* entry = new PerformancePaintTiming(
type, MonotonicTimeToDOMHighResTimeStamp(start_time));
// Always buffer First Paint & First Contentful Paint.
@@ -535,7 +512,7 @@ void Performance::AddResourceTimingBuffer(PerformanceEntry& entry) {
resource_timing_buffer_.push_back(&entry);
if (IsResourceTimingBufferFull())
- DispatchEvent(Event::Create(EventTypeNames::resourcetimingbufferfull));
+ DispatchEvent(*Event::Create(EventTypeNames::resourcetimingbufferfull));
}
bool Performance::IsResourceTimingBufferFull() {
@@ -545,7 +522,7 @@ bool Performance::IsResourceTimingBufferFull() {
void Performance::AddLongTaskTiming(
TimeTicks start_time,
TimeTicks end_time,
- const String& name,
+ const AtomicString& name,
const String& frame_src,
const String& frame_id,
const String& frame_name,
@@ -567,7 +544,7 @@ void Performance::AddLongTaskTiming(
}
PerformanceMark* Performance::mark(ScriptState* script_state,
- const String& mark_name,
+ const AtomicString& mark_name,
ExceptionState& exception_state) {
DoubleOrPerformanceMarkOptions startOrOptions;
return this->mark(script_state, mark_name, startOrOptions, exception_state);
@@ -575,7 +552,7 @@ PerformanceMark* Performance::mark(ScriptState* script_state,
PerformanceMark* Performance::mark(
ScriptState* script_state,
- const String& mark_name,
+ const AtomicString& mark_name,
DoubleOrPerformanceMarkOptions& start_time_or_mark_options,
ExceptionState& exception_state) {
if (!RuntimeEnabledFeatures::CustomUserTimingEnabled()) {
@@ -610,14 +587,14 @@ PerformanceMark* Performance::mark(
return performance_mark;
}
-void Performance::clearMarks(const String& mark_name) {
+void Performance::clearMarks(const AtomicString& mark_name) {
if (!user_timing_)
user_timing_ = UserTiming::Create(*this);
user_timing_->ClearMarks(mark_name);
}
PerformanceMeasure* Performance::measure(ScriptState* script_state,
- const String& measure_name,
+ const AtomicString& measure_name,
ExceptionState& exception_state) {
return measureInternal(script_state, measure_name,
NativeValueTraits<StringOrDouble>::NullValue(),
@@ -628,22 +605,22 @@ PerformanceMeasure* Performance::measure(ScriptState* script_state,
PerformanceMeasure* Performance::measure(
ScriptState* script_state,
- const String& measure_name,
+ const AtomicString& measure_name,
const StringOrDoubleOrPerformanceMeasureOptions& start_or_options,
ExceptionState& exception_state) {
return measureInternal(script_state, measure_name, start_or_options,
- NativeValueTraits<StringOrDouble>::NullValue(), true,
+ NativeValueTraits<StringOrDouble>::NullValue(),
exception_state);
}
PerformanceMeasure* Performance::measure(
ScriptState* script_state,
- const String& measure_name,
+ const AtomicString& measure_name,
const StringOrDoubleOrPerformanceMeasureOptions& start_or_options,
const StringOrDouble& end,
ExceptionState& exception_state) {
return measureInternal(script_state, measure_name, start_or_options, end,
- false, exception_state);
+ exception_state);
}
// |start_or_options|: while in options type, the value is an object {start,
@@ -665,10 +642,9 @@ PerformanceMeasure* Performance::measure(
// distinguish between (null or undefined) and empty.
PerformanceMeasure* Performance::measureInternal(
ScriptState* script_state,
- const String& measure_name,
+ const AtomicString& measure_name,
const StringOrDoubleOrPerformanceMeasureOptions& start_or_options,
const StringOrDouble& end,
- bool end_is_empty,
ExceptionState& exception_state) {
if (RuntimeEnabledFeatures::CustomUserTimingEnabled()) {
if (start_or_options.IsPerformanceMeasureOptions()) {
@@ -717,7 +693,7 @@ PerformanceMeasure* Performance::measureInternal(
StringOrDouble::FromString(start_or_options.GetAsString());
} else {
DCHECK(start_or_options.IsNull());
- converted_start = StringOrDouble::FromString("null");
+ DCHECK(converted_start.IsNull());
}
StringOrDouble converted_end;
@@ -728,11 +704,7 @@ PerformanceMeasure* Performance::measureInternal(
String::NumberToStringECMAScript(end.GetAsDouble()));
} else {
DCHECK(end.IsNull());
- if (end_is_empty) {
- converted_end = NativeValueTraits<StringOrDouble>::NullValue();
- } else {
- converted_end = StringOrDouble::FromString("null");
- }
+ DCHECK(converted_end.IsNull());
}
measureInternal(script_state, measure_name, converted_start, converted_end,
ScriptValue::CreateNull(script_state), exception_state);
@@ -743,7 +715,7 @@ PerformanceMeasure* Performance::measureInternal(
PerformanceMeasure* Performance::measureInternal(
ScriptState* script_state,
- const String& measure_name,
+ const AtomicString& measure_name,
const StringOrDouble& start,
const StringOrDouble& end,
const ScriptValue& detail,
@@ -761,7 +733,7 @@ PerformanceMeasure* Performance::measureInternal(
return performance_measure;
}
-void Performance::clearMeasures(const String& measure_name) {
+void Performance::clearMeasures(const AtomicString& measure_name) {
if (!user_timing_)
user_timing_ = UserTiming::Create(*this);
user_timing_->ClearMeasures(measure_name);
@@ -888,7 +860,6 @@ void Performance::BuildJSONValue(V8ObjectBuilder& builder) const {
}
void Performance::Trace(blink::Visitor* visitor) {
- visitor->Trace(frame_timing_buffer_);
visitor->Trace(resource_timing_buffer_);
visitor->Trace(event_timing_buffer_);
visitor->Trace(navigation_timing_);
diff --git a/chromium/third_party/blink/renderer/core/timing/performance.h b/chromium/third_party/blink/renderer/core/timing/performance.h
index 9126b86b62a..a18ae1c0eb0 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance.h
+++ b/chromium/third_party/blink/renderer/core/timing/performance.h
@@ -115,7 +115,7 @@ class CORE_EXPORT Performance : public EventTargetWithInlineData {
PerformanceEntryVector getEntries();
PerformanceEntryVector getEntriesByType(const AtomicString& entry_type);
- PerformanceEntryVector getEntriesByName(const String& name,
+ PerformanceEntryVector getEntriesByName(const AtomicString& name,
const AtomicString& entry_type);
void clearResourceTimings();
@@ -126,7 +126,7 @@ class CORE_EXPORT Performance : public EventTargetWithInlineData {
void AddLongTaskTiming(
TimeTicks start_time,
TimeTicks end_time,
- const String& name,
+ const AtomicString& name,
const String& culprit_frame_src,
const String& culprit_frame_id,
const String& culprit_frame_name,
@@ -161,34 +161,36 @@ class CORE_EXPORT Performance : public EventTargetWithInlineData {
void setEventTimingBufferMaxSize(unsigned);
DEFINE_ATTRIBUTE_EVENT_LISTENER(eventtimingbufferfull);
- PerformanceMark* mark(ScriptState*, const String& mark_name, ExceptionState&);
+ PerformanceMark* mark(ScriptState*,
+ const AtomicString& mark_name,
+ ExceptionState&);
PerformanceMark* mark(
ScriptState*,
- const String& mark_name,
+ const AtomicString& mark_name,
DoubleOrPerformanceMarkOptions& start_time_or_mark_options,
ExceptionState&);
- void clearMarks(const String& mark_name);
+ void clearMarks(const AtomicString& mark_name);
PerformanceMeasure* measure(ScriptState*,
- const String& measure_name,
+ const AtomicString& measure_name,
ExceptionState&);
PerformanceMeasure* measure(
ScriptState*,
- const String& measure_name,
+ const AtomicString& measure_name,
const StringOrDoubleOrPerformanceMeasureOptions& start_or_options,
ExceptionState&);
PerformanceMeasure* measure(
ScriptState*,
- const String& measure_name,
+ const AtomicString& measure_name,
const StringOrDoubleOrPerformanceMeasureOptions& start_or_options,
const StringOrDouble& end,
ExceptionState&);
- void clearMeasures(const String& measure_name);
+ void clearMeasures(const AtomicString& measure_name);
void UnregisterPerformanceObserver(PerformanceObserver&);
void RegisterPerformanceObserver(PerformanceObserver&);
@@ -215,14 +217,13 @@ class CORE_EXPORT Performance : public EventTargetWithInlineData {
PerformanceMeasure* measureInternal(
ScriptState*,
- const String& measure_name,
+ const AtomicString& measure_name,
const StringOrDoubleOrPerformanceMeasureOptions& start,
const StringOrDouble& end,
- bool end_is_empty,
ExceptionState&);
PerformanceMeasure* measureInternal(ScriptState*,
- const String& measure_name,
+ const AtomicString& measure_name,
const StringOrDouble& start,
const StringOrDouble& end,
const ScriptValue& detail,
@@ -249,8 +250,6 @@ class CORE_EXPORT Performance : public EventTargetWithInlineData {
virtual void BuildJSONValue(V8ObjectBuilder&) const;
- PerformanceEntryVector frame_timing_buffer_;
- unsigned frame_timing_buffer_size_;
PerformanceEntryVector resource_timing_buffer_;
unsigned resource_timing_buffer_size_;
PerformanceEntryVector event_timing_buffer_;
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_entry.cc b/chromium/third_party/blink/renderer/core/timing/performance_entry.cc
index 2ad3ed885c5..02881092b93 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_entry.cc
+++ b/chromium/third_party/blink/renderer/core/timing/performance_entry.cc
@@ -33,6 +33,7 @@
#include "base/atomic_sequence_num.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/core/performance_entry_names.h"
namespace blink {
@@ -40,7 +41,7 @@ namespace {
static base::AtomicSequenceNumber index_seq;
}
-PerformanceEntry::PerformanceEntry(const String& name,
+PerformanceEntry::PerformanceEntry(const AtomicString& name,
double start_time,
double finish_time)
: duration_(finish_time - start_time),
@@ -50,10 +51,6 @@ PerformanceEntry::PerformanceEntry(const String& name,
PerformanceEntry::~PerformanceEntry() = default;
-String PerformanceEntry::name() const {
- return name_;
-}
-
DOMHighResTimeStamp PerformanceEntry::startTime() const {
return start_time_;
}
@@ -62,107 +59,25 @@ DOMHighResTimeStamp PerformanceEntry::duration() const {
return duration_;
}
-const AtomicString& PerformanceEntry::CompositeKeyword() {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<AtomicString>, composite, ());
- if (!composite.IsSet())
- *composite = "composite";
- return *composite;
-}
-
-const AtomicString& PerformanceEntry::EventKeyword() {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<AtomicString>, event, ());
- if (!event.IsSet())
- *event = "event";
- return *event;
-}
-
-const AtomicString& PerformanceEntry::FirstInputKeyword() {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<AtomicString>, firstInput, ());
- if (!firstInput.IsSet())
- *firstInput = "firstInput";
- return *firstInput;
-}
-
-const AtomicString& PerformanceEntry::LongtaskKeyword() {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<AtomicString>, longtask, ());
- if (!longtask.IsSet())
- *longtask = "longtask";
- return *longtask;
-}
-
-const AtomicString& PerformanceEntry::MarkKeyword() {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<AtomicString>, mark, ());
- if (!mark.IsSet())
- *mark = "mark";
- return *mark;
-}
-
-const AtomicString& PerformanceEntry::MeasureKeyword() {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<AtomicString>, measure, ());
- if (!measure.IsSet())
- *measure = "measure";
- return *measure;
-}
-
-const AtomicString& PerformanceEntry::NavigationKeyword() {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<AtomicString>, navigation, ());
- if (!navigation.IsSet())
- *navigation = "navigation";
- return *navigation;
-}
-
-const AtomicString& PerformanceEntry::PaintKeyword() {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<AtomicString>, paint, ());
- if (!paint.IsSet())
- *paint = "paint";
- return *paint;
-}
-
-const AtomicString& PerformanceEntry::RenderKeyword() {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<AtomicString>, render, ());
- if (!render.IsSet())
- *render = "render";
- return *render;
-}
-
-const AtomicString& PerformanceEntry::ResourceKeyword() {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<AtomicString>, resource, ());
- if (!resource.IsSet())
- *resource = "resource";
- return *resource;
-}
-
-const AtomicString& PerformanceEntry::TaskattributionKeyword() {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<AtomicString>, taskattribution,
- ());
- if (!taskattribution.IsSet())
- *taskattribution = "taskattribution";
- return *taskattribution;
-}
-
PerformanceEntry::EntryType PerformanceEntry::ToEntryTypeEnum(
const AtomicString& entry_type) {
- if (entry_type == CompositeKeyword())
- return kComposite;
- if (entry_type == LongtaskKeyword())
+ if (entry_type == PerformanceEntryNames::longtask)
return kLongTask;
- if (entry_type == MarkKeyword())
+ if (entry_type == PerformanceEntryNames::mark)
return kMark;
- if (entry_type == MeasureKeyword())
+ if (entry_type == PerformanceEntryNames::measure)
return kMeasure;
- if (entry_type == RenderKeyword())
- return kRender;
- if (entry_type == ResourceKeyword())
+ if (entry_type == PerformanceEntryNames::resource)
return kResource;
- if (entry_type == NavigationKeyword())
+ if (entry_type == PerformanceEntryNames::navigation)
return kNavigation;
- if (entry_type == TaskattributionKeyword())
+ if (entry_type == PerformanceEntryNames::taskattribution)
return kTaskAttribution;
- if (entry_type == PaintKeyword())
+ if (entry_type == PerformanceEntryNames::paint)
return kPaint;
- if (entry_type == EventKeyword())
+ if (entry_type == PerformanceEntryNames::event)
return kEvent;
- if (entry_type == FirstInputKeyword())
+ if (entry_type == PerformanceEntryNames::firstInput)
return kFirstInput;
return kInvalid;
}
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_entry.h b/chromium/third_party/blink/renderer/core/timing/performance_entry.h
index 286b860cb77..e75cd5ef9a2 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_entry.h
+++ b/chromium/third_party/blink/renderer/core/timing/performance_entry.h
@@ -56,19 +56,17 @@ class CORE_EXPORT PerformanceEntry : public ScriptWrappable {
enum EntryType : PerformanceEntryType {
kInvalid = 0,
kNavigation = 1 << 0,
- kComposite = 1 << 1,
- kMark = 1 << 2,
- kMeasure = 1 << 3,
- kRender = 1 << 4,
- kResource = 1 << 5,
- kLongTask = 1 << 6,
- kTaskAttribution = 1 << 7,
- kPaint = 1 << 8,
- kEvent = 1 << 9,
- kFirstInput = 1 << 10,
+ kMark = 1 << 1,
+ kMeasure = 1 << 2,
+ kResource = 1 << 3,
+ kLongTask = 1 << 4,
+ kTaskAttribution = 1 << 5,
+ kPaint = 1 << 6,
+ kEvent = 1 << 7,
+ kFirstInput = 1 << 8,
};
- String name() const;
+ const AtomicString& name() const { return name_; }
DOMHighResTimeStamp startTime() const;
virtual AtomicString entryType() const = 0;
virtual PerformanceEntryType EntryTypeEnum() const = 0;
@@ -81,8 +79,6 @@ class CORE_EXPORT PerformanceEntry : public ScriptWrappable {
ScriptValue toJSONForBinding(ScriptState*) const;
bool IsResource() const { return EntryTypeEnum() == kResource; }
- bool IsRender() const { return EntryTypeEnum() == kRender; }
- bool IsComposite() const { return EntryTypeEnum() == kComposite; }
bool IsMark() const { return EntryTypeEnum() == kMark; }
bool IsMeasure() const { return EntryTypeEnum() == kMeasure; }
@@ -93,22 +89,11 @@ class CORE_EXPORT PerformanceEntry : public ScriptWrappable {
return a->startTime() < b->startTime();
}
- static const AtomicString& CompositeKeyword();
- static const AtomicString& EventKeyword();
- static const AtomicString& FirstInputKeyword();
- static const AtomicString& LongtaskKeyword();
- static const AtomicString& MarkKeyword();
- static const AtomicString& MeasureKeyword();
- static const AtomicString& NavigationKeyword();
- static const AtomicString& PaintKeyword();
- static const AtomicString& RenderKeyword();
- static const AtomicString& ResourceKeyword();
- static const AtomicString& TaskattributionKeyword();
static PerformanceEntry::EntryType ToEntryTypeEnum(
const AtomicString& entry_type);
protected:
- PerformanceEntry(const String& name,
+ PerformanceEntry(const AtomicString& name,
double start_time,
double finish_time);
virtual void BuildJSONValue(V8ObjectBuilder&) const;
@@ -117,7 +102,7 @@ class CORE_EXPORT PerformanceEntry : public ScriptWrappable {
double duration_;
private:
- const String name_;
+ const AtomicString name_;
const double start_time_;
const int index_;
};
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_entry_names.json5 b/chromium/third_party/blink/renderer/core/timing/performance_entry_names.json5
new file mode 100644
index 00000000000..cb06acc1208
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/timing/performance_entry_names.json5
@@ -0,0 +1,18 @@
+{
+ metadata: {
+ namespace: "PerformanceEntry",
+ export: "CORE_EXPORT",
+ },
+
+ data: [
+ "event",
+ "firstInput",
+ "longtask",
+ "mark",
+ "measure",
+ "navigation",
+ "paint",
+ "resource",
+ "taskattribution",
+ ],
+}
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 5fe4adc18a3..a31aacdfc50 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
@@ -5,12 +5,13 @@
#include "third_party/blink/renderer/core/timing/performance_event_timing.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h"
+#include "third_party/blink/renderer/core/performance_entry_names.h"
namespace blink {
// static
PerformanceEventTiming* PerformanceEventTiming::Create(
- const String& event_type,
+ const AtomicString& event_type,
DOMHighResTimeStamp start_time,
DOMHighResTimeStamp processing_start,
DOMHighResTimeStamp processing_end,
@@ -18,23 +19,23 @@ PerformanceEventTiming* PerformanceEventTiming::Create(
// TODO(npm): enable this DCHECK once https://crbug.com/852846 is fixed.
// DCHECK_LE(start_time, processing_start);
DCHECK_LE(processing_start, processing_end);
- return new PerformanceEventTiming(
- event_type, PerformanceEntry::EventKeyword(), start_time,
- processing_start, processing_end, cancelable);
+ return new PerformanceEventTiming(event_type, PerformanceEntryNames::event,
+ start_time, processing_start,
+ processing_end, cancelable);
}
// static
PerformanceEventTiming* PerformanceEventTiming::CreateFirstInputTiming(
PerformanceEventTiming* entry) {
PerformanceEventTiming* first_input = new PerformanceEventTiming(
- entry->name(), PerformanceEntry::FirstInputKeyword(), entry->startTime(),
+ entry->name(), PerformanceEntryNames::firstInput, entry->startTime(),
entry->processingStart(), entry->processingEnd(), entry->cancelable());
first_input->SetDuration(entry->duration());
return first_input;
}
PerformanceEventTiming::PerformanceEventTiming(
- const String& event_type,
+ const AtomicString& event_type,
const AtomicString& entry_type,
DOMHighResTimeStamp start_time,
DOMHighResTimeStamp processing_start,
@@ -49,7 +50,7 @@ PerformanceEventTiming::PerformanceEventTiming(
PerformanceEventTiming::~PerformanceEventTiming() = default;
PerformanceEntryType PerformanceEventTiming::EntryTypeEnum() const {
- return entry_type_ == PerformanceEntry::EventKeyword()
+ return entry_type_ == PerformanceEntryNames::event
? PerformanceEntry::EntryType::kEvent
: PerformanceEntry::EntryType::kFirstInput;
}
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 3337b234aa7..5adb3198776 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
@@ -16,7 +16,7 @@ class CORE_EXPORT PerformanceEventTiming final : public PerformanceEntry {
DEFINE_WRAPPERTYPEINFO();
public:
- static PerformanceEventTiming* Create(const String& event_type,
+ static PerformanceEventTiming* Create(const AtomicString& event_type,
DOMHighResTimeStamp start_time,
DOMHighResTimeStamp processing_start,
DOMHighResTimeStamp processing_end,
@@ -42,7 +42,7 @@ class CORE_EXPORT PerformanceEventTiming final : public PerformanceEntry {
void Trace(blink::Visitor*) override;
private:
- PerformanceEventTiming(const String& event_type,
+ PerformanceEventTiming(const AtomicString& event_type,
const AtomicString& entry_type,
DOMHighResTimeStamp start_time,
DOMHighResTimeStamp processing_start,
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 ba90d25a0ff..8db17dc3810 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
@@ -6,6 +6,7 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h"
#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/sub_task_attribution.h"
#include "third_party/blink/renderer/core/timing/task_attribution_timing.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
@@ -16,10 +17,10 @@ namespace blink {
PerformanceLongTaskTiming* PerformanceLongTaskTiming::Create(
double start_time,
double end_time,
- String name,
- String frame_src,
- String frame_id,
- String frame_name,
+ const AtomicString& name,
+ const String& frame_src,
+ const String& frame_id,
+ const String& frame_name,
const SubTaskAttribution::EntriesVector& sub_task_attributions) {
return new PerformanceLongTaskTiming(start_time, end_time, name, frame_src,
frame_id, frame_name,
@@ -29,10 +30,10 @@ PerformanceLongTaskTiming* PerformanceLongTaskTiming::Create(
PerformanceLongTaskTiming::PerformanceLongTaskTiming(
double start_time,
double end_time,
- String name,
- String culprit_frame_src,
- String culprit_frame_id,
- String culprit_frame_name,
+ const AtomicString& name,
+ const String& culprit_frame_src,
+ const String& culprit_frame_id,
+ const String& culprit_frame_name,
const SubTaskAttribution::EntriesVector& sub_task_attributions)
: PerformanceEntry(name, start_time, end_time) {
// Only one possible container type exists currently: "iframe".
@@ -56,7 +57,7 @@ PerformanceLongTaskTiming::PerformanceLongTaskTiming(
PerformanceLongTaskTiming::~PerformanceLongTaskTiming() = default;
AtomicString PerformanceLongTaskTiming::entryType() const {
- return PerformanceEntry::LongtaskKeyword();
+ return PerformanceEntryNames::longtask;
}
PerformanceEntryType PerformanceLongTaskTiming::EntryTypeEnum() const {
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 cb9fd59559c..7d7750834d2 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
@@ -23,10 +23,10 @@ class PerformanceLongTaskTiming final : public PerformanceEntry {
static PerformanceLongTaskTiming* Create(
double start_time,
double end_time,
- String name,
- String frame_src,
- String frame_id,
- String frame_name,
+ const AtomicString& name,
+ const String& frame_src,
+ const String& frame_id,
+ const String& frame_name,
const SubTaskAttribution::EntriesVector& sub_task_attributions);
AtomicString entryType() const override;
@@ -40,10 +40,10 @@ class PerformanceLongTaskTiming final : public PerformanceEntry {
PerformanceLongTaskTiming(
double start_time,
double end_time,
- String name,
- String frame_src,
- String frame_id,
- String frame_name,
+ const AtomicString& name,
+ const String& frame_src,
+ const String& frame_id,
+ const String& frame_name,
const SubTaskAttribution::EntriesVector& sub_task_attributions);
~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 8c5d0b606e3..18e421e0155 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_mark.cc
+++ b/chromium/third_party/blink/renderer/core/timing/performance_mark.cc
@@ -6,11 +6,12 @@
#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/serialization/serialized_script_value_factory.h"
+#include "third_party/blink/renderer/core/performance_entry_names.h"
namespace blink {
PerformanceMark::PerformanceMark(ScriptState* script_state,
- const String& name,
+ const AtomicString& name,
double start_time,
const ScriptValue& detail)
: PerformanceEntry(name, start_time, start_time) {
@@ -22,7 +23,7 @@ PerformanceMark::PerformanceMark(ScriptState* script_state,
}
AtomicString PerformanceMark::entryType() const {
- return PerformanceEntry::MarkKeyword();
+ return PerformanceEntryNames::mark;
}
PerformanceEntryType PerformanceMark::EntryTypeEnum() const {
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 9af17a7beca..fdd362f3bb3 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_mark.h
+++ b/chromium/third_party/blink/renderer/core/timing/performance_mark.h
@@ -38,7 +38,7 @@ class CORE_EXPORT PerformanceMark final : public PerformanceEntry {
public:
static PerformanceMark* Create(ScriptState* script_state,
- const String& name,
+ const AtomicString& name,
double start_time,
const ScriptValue& detail) {
return new PerformanceMark(script_state, name, start_time, detail);
@@ -53,7 +53,7 @@ class CORE_EXPORT PerformanceMark final : public PerformanceEntry {
private:
PerformanceMark(ScriptState*,
- const String& name,
+ const AtomicString& name,
double start_time,
const ScriptValue& detail);
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 ab06293a79b..d31f4bed1fa 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_measure.cc
+++ b/chromium/third_party/blink/renderer/core/timing/performance_measure.cc
@@ -6,11 +6,12 @@
#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/performance_entry_names.h"
namespace blink {
PerformanceMeasure::PerformanceMeasure(ScriptState* script_state,
- const String& name,
+ const AtomicString& name,
double start_time,
double end_time,
const ScriptValue& detail)
@@ -30,7 +31,7 @@ ScriptValue PerformanceMeasure::detail(ScriptState* script_state) const {
}
AtomicString PerformanceMeasure::entryType() const {
- return PerformanceEntry::MeasureKeyword();
+ return PerformanceEntryNames::measure;
}
PerformanceEntryType PerformanceMeasure::EntryTypeEnum() const {
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 86b17ba2ac2..43ba5068dfd 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_measure.h
+++ b/chromium/third_party/blink/renderer/core/timing/performance_measure.h
@@ -39,7 +39,7 @@ class PerformanceMeasure final : public PerformanceEntry {
public:
static PerformanceMeasure* Create(ScriptState* script_state,
- const String& name,
+ const AtomicString& name,
double start_time,
double end_time,
const ScriptValue& detail) {
@@ -57,7 +57,7 @@ class PerformanceMeasure final : public PerformanceEntry {
private:
PerformanceMeasure(ScriptState*,
- const String& name,
+ const AtomicString& name,
double start_time,
double end_time,
const ScriptValue& detail);
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 26859323bd6..607eb330e45 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
@@ -11,6 +11,7 @@
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/loader/document_load_timing.h"
#include "third_party/blink/renderer/core/loader/document_loader.h"
+#include "third_party/blink/renderer/core/performance_entry_names.h"
#include "third_party/blink/renderer/core/timing/performance.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_timing_info.h"
@@ -22,7 +23,8 @@ PerformanceNavigationTiming::PerformanceNavigationTiming(
TimeTicks time_origin,
const WebVector<WebServerTimingInfo>& server_timing)
: PerformanceResourceTiming(
- info ? info->FinalResponse().Url().GetString() : "",
+ info ? AtomicString(info->FinalResponse().Url().GetString())
+ : g_empty_atom,
time_origin,
server_timing),
ContextClient(frame),
@@ -34,7 +36,7 @@ PerformanceNavigationTiming::PerformanceNavigationTiming(
PerformanceNavigationTiming::~PerformanceNavigationTiming() = default;
AtomicString PerformanceNavigationTiming::entryType() const {
- return PerformanceEntry::NavigationKeyword();
+ return PerformanceEntryNames::navigation;
}
PerformanceEntryType PerformanceNavigationTiming::EntryTypeEnum() const {
@@ -117,7 +119,7 @@ AtomicString PerformanceNavigationTiming::GetNavigationType(
}
AtomicString PerformanceNavigationTiming::initiatorType() const {
- return PerformanceEntry::NavigationKeyword();
+ return PerformanceEntryNames::navigation;
}
bool PerformanceNavigationTiming::GetAllowRedirectDetails() const {
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_paint_timing.cc b/chromium/third_party/blink/renderer/core/timing/performance_paint_timing.cc
index 1342c50ed28..d6d0ce5c1fd 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_paint_timing.cc
+++ b/chromium/third_party/blink/renderer/core/timing/performance_paint_timing.cc
@@ -5,9 +5,31 @@
#include "third_party/blink/renderer/core/timing/performance_paint_timing.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h"
+#include "third_party/blink/renderer/core/performance_entry_names.h"
namespace blink {
+namespace {
+
+AtomicString FromPaintTypeToString(PerformancePaintTiming::PaintType type) {
+ DCHECK(IsMainThread());
+ switch (type) {
+ case PerformancePaintTiming::PaintType::kFirstPaint: {
+ DEFINE_STATIC_LOCAL(const AtomicString, kFirstPaint, ("first-paint"));
+ return kFirstPaint;
+ }
+ case PerformancePaintTiming::PaintType::kFirstContentfulPaint: {
+ DEFINE_STATIC_LOCAL(const AtomicString, kFirstContentfulPaint,
+ ("first-contentful-paint"));
+ return kFirstContentfulPaint;
+ }
+ }
+ NOTREACHED();
+ return g_empty_atom;
+}
+
+} // namespace
+
PerformancePaintTiming::PerformancePaintTiming(PaintType type,
double start_time)
: PerformanceEntry(FromPaintTypeToString(type),
@@ -17,21 +39,11 @@ PerformancePaintTiming::PerformancePaintTiming(PaintType type,
PerformancePaintTiming::~PerformancePaintTiming() = default;
AtomicString PerformancePaintTiming::entryType() const {
- return PerformanceEntry::PaintKeyword();
+ return PerformanceEntryNames::paint;
}
PerformanceEntryType PerformancePaintTiming::EntryTypeEnum() const {
return PerformanceEntry::EntryType::kPaint;
}
-String PerformancePaintTiming::FromPaintTypeToString(PaintType type) {
- switch (type) {
- case PaintType::kFirstPaint:
- return "first-paint";
- case PaintType::kFirstContentfulPaint:
- return "first-contentful-paint";
- }
- NOTREACHED();
- return "";
-}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_paint_timing.h b/chromium/third_party/blink/renderer/core/timing/performance_paint_timing.h
index c67d510cbb6..30db71cda88 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_paint_timing.h
+++ b/chromium/third_party/blink/renderer/core/timing/performance_paint_timing.h
@@ -21,9 +21,8 @@ class CORE_EXPORT PerformancePaintTiming final : public PerformanceEntry {
AtomicString entryType() const override;
PerformanceEntryType EntryTypeEnum() const override;
-
- static String FromPaintTypeToString(PaintType);
};
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_TIMING_PERFORMANCE_PAINT_TIMING_H_
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_paint_timing.idl b/chromium/third_party/blink/renderer/core/timing/performance_paint_timing.idl
index a09c5a021bb..e6094b6f64e 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_paint_timing.idl
+++ b/chromium/third_party/blink/renderer/core/timing/performance_paint_timing.idl
@@ -4,7 +4,5 @@
// https://w3c.github.io/paint-timing/#sec-PerformancePaintTiming
-[
- RuntimeEnabled=PerformancePaintTiming
-] interface PerformancePaintTiming : PerformanceEntry {
+interface PerformancePaintTiming : PerformanceEntry {
};
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 385b4c12cd5..3a28e131a35 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
@@ -33,6 +33,7 @@
#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"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_initiator_type_names.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_request.h"
@@ -76,7 +77,7 @@ PerformanceResourceTiming::PerformanceResourceTiming(
// This constructor is for PerformanceNavigationTiming.
PerformanceResourceTiming::PerformanceResourceTiming(
- const String& name,
+ const AtomicString& name,
TimeTicks time_origin,
const WebVector<WebServerTimingInfo>& server_timing)
: PerformanceEntry(name, 0.0, 0.0),
@@ -87,7 +88,7 @@ PerformanceResourceTiming::PerformanceResourceTiming(
PerformanceResourceTiming::~PerformanceResourceTiming() = default;
AtomicString PerformanceResourceTiming::entryType() const {
- return PerformanceEntry::ResourceKeyword();
+ return PerformanceEntryNames::resource;
}
PerformanceEntryType PerformanceResourceTiming::EntryTypeEnum() const {
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 5c8d447816e..2235b7ec5fb 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
@@ -87,7 +87,7 @@ class CORE_EXPORT PerformanceResourceTiming : public PerformanceEntry {
// This constructor is for PerformanceNavigationTiming.
// Related doc: https://goo.gl/uNecAj.
- PerformanceResourceTiming(const String& name,
+ PerformanceResourceTiming(const AtomicString& name,
TimeTicks time_origin,
const WebVector<WebServerTimingInfo>&);
virtual AtomicString AlpnNegotiatedProtocol() const;
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_resource_timing.idl b/chromium/third_party/blink/renderer/core/timing/performance_resource_timing.idl
index 59386eb4c38..068e2415d67 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_resource_timing.idl
+++ b/chromium/third_party/blink/renderer/core/timing/performance_resource_timing.idl
@@ -49,6 +49,6 @@ interface PerformanceResourceTiming : PerformanceEntry {
[MeasureAs=PerformanceResourceTimingSizes] readonly attribute unsigned long long transferSize;
[MeasureAs=PerformanceResourceTimingSizes] readonly attribute unsigned long long encodedBodySize;
[MeasureAs=PerformanceResourceTimingSizes] readonly attribute unsigned long long decodedBodySize;
- [RuntimeEnabled=ServerTiming] readonly attribute FrozenArray<PerformanceServerTiming> serverTiming;
+ readonly attribute FrozenArray<PerformanceServerTiming> serverTiming;
serializer = {inherit, attribute};
};
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 a375765fa1b..9bc079fc244 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
@@ -29,15 +29,13 @@ ScriptValue PerformanceServerTiming::toJSONForBinding(
WebVector<WebServerTimingInfo> PerformanceServerTiming::ParseServerTiming(
const ResourceTimingInfo& info) {
WebVector<WebServerTimingInfo> result;
- if (RuntimeEnabledFeatures::ServerTimingEnabled()) {
- const ResourceResponse& response = info.FinalResponse();
- std::unique_ptr<ServerTimingHeaderVector> headers = ParseServerTimingHeader(
- response.HttpHeaderField(HTTPNames::Server_Timing));
- result.reserve(headers->size());
- for (const auto& header : *headers) {
- result.emplace_back(header->Name(), header->Duration(),
- header->Description());
- }
+ const ResourceResponse& response = info.FinalResponse();
+ std::unique_ptr<ServerTimingHeaderVector> headers = ParseServerTimingHeader(
+ response.HttpHeaderField(HTTPNames::Server_Timing));
+ result.reserve(headers->size());
+ for (const auto& header : *headers) {
+ result.emplace_back(header->Name(), header->Duration(),
+ header->Description());
}
return result;
}
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_server_timing.idl b/chromium/third_party/blink/renderer/core/timing/performance_server_timing.idl
index f96527f64f0..b5b34606b09 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_server_timing.idl
+++ b/chromium/third_party/blink/renderer/core/timing/performance_server_timing.idl
@@ -5,7 +5,6 @@
// https://w3c.github.io/server-timing/#dom-performanceservertiming
[
- RuntimeEnabled=ServerTiming,
Exposed=(Window,Worker)
] interface PerformanceServerTiming {
readonly attribute DOMString name;
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 19a80e7a71f..9c69c3ed3cd 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_timing.cc
+++ b/chromium/third_party/blink/renderer/core/timing/performance_timing.cc
@@ -66,6 +66,14 @@ unsigned long long PerformanceTiming::navigationStart() const {
return MonotonicTimeToIntegerMilliseconds(timing->NavigationStart());
}
+unsigned long long PerformanceTiming::inputStart() const {
+ DocumentLoadTiming* timing = GetDocumentLoadTiming();
+ if (!timing)
+ return 0;
+
+ return MonotonicTimeToIntegerMilliseconds(timing->InputStart());
+}
+
unsigned long long PerformanceTiming::unloadEventStart() const {
DocumentLoadTiming* timing = GetDocumentLoadTiming();
if (!timing)
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 1564890b224..143c07921dd 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_timing.h
+++ b/chromium/third_party/blink/renderer/core/timing/performance_timing.h
@@ -63,6 +63,7 @@ class CORE_EXPORT PerformanceTiming final : public ScriptWrappable,
}
unsigned long long navigationStart() const;
+ unsigned long long inputStart() const;
unsigned long long unloadEventStart() const;
unsigned long long unloadEventEnd() const;
unsigned long long redirectStart() const;
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_user_timing.cc b/chromium/third_party/blink/renderer/core/timing/performance_user_timing.cc
index 50db0c4d6ae..595cb53dc12 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
@@ -38,37 +38,38 @@ namespace blink {
namespace {
-using RestrictedKeyMap = HashMap<String, NavigationTimingFunction>;
+using RestrictedKeyMap = HashMap<AtomicString, NavigationTimingFunction>;
const RestrictedKeyMap& GetRestrictedKeyMap() {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- RestrictedKeyMap, 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;
+ 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
@@ -88,7 +89,7 @@ static void InsertPerformanceEntry(PerformanceEntryMap& performance_entry_map,
}
static void ClearPeformanceEntries(PerformanceEntryMap& performance_entry_map,
- const String& name) {
+ const AtomicString& name) {
if (name.IsNull()) {
performance_entry_map.clear();
return;
@@ -99,7 +100,7 @@ static void ClearPeformanceEntries(PerformanceEntryMap& performance_entry_map,
}
PerformanceMark* UserTiming::Mark(ScriptState* script_state,
- const String& mark_name,
+ const AtomicString& mark_name,
const DOMHighResTimeStamp& start_time,
const ScriptValue& detail,
ExceptionState& exception_state) {
@@ -123,11 +124,11 @@ PerformanceMark* UserTiming::Mark(ScriptState* script_state,
return mark;
}
-void UserTiming::ClearMarks(const String& mark_name) {
+void UserTiming::ClearMarks(const AtomicString& mark_name) {
ClearPeformanceEntries(marks_map_, mark_name);
}
-double UserTiming::FindExistingMarkStartTime(const String& 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();
@@ -155,8 +156,10 @@ double UserTiming::FindExistingMarkStartTime(const String& mark_name,
double UserTiming::FindStartMarkOrTime(const StringOrDouble& start,
ExceptionState& exception_state) {
- if (start.IsString())
- return FindExistingMarkStartTime(start.GetAsString(), exception_state);
+ if (start.IsString()) {
+ return FindExistingMarkStartTime(AtomicString(start.GetAsString()),
+ exception_state);
+ }
if (start.IsDouble())
return start.GetAsDouble();
NOTREACHED();
@@ -164,7 +167,7 @@ double UserTiming::FindStartMarkOrTime(const StringOrDouble& start,
}
PerformanceMeasure* UserTiming::Measure(ScriptState* script_state,
- const String& measure_name,
+ const AtomicString& measure_name,
const StringOrDouble& start,
const StringOrDouble& end,
const ScriptValue& detail,
@@ -216,7 +219,7 @@ PerformanceMeasure* UserTiming::Measure(ScriptState* script_state,
return measure;
}
-void UserTiming::ClearMeasures(const String& measure_name) {
+void UserTiming::ClearMeasures(const AtomicString& measure_name) {
ClearPeformanceEntries(measures_map_, measure_name);
}
@@ -232,7 +235,7 @@ static PerformanceEntryVector ConvertToEntrySequence(
static PerformanceEntryVector GetEntrySequenceByName(
const PerformanceEntryMap& performance_entry_map,
- const String& name) {
+ const AtomicString& name) {
PerformanceEntryVector entries;
PerformanceEntryMap::const_iterator it = performance_entry_map.find(name);
@@ -246,7 +249,7 @@ PerformanceEntryVector UserTiming::GetMarks() const {
return ConvertToEntrySequence(marks_map_);
}
-PerformanceEntryVector UserTiming::GetMarks(const String& name) const {
+PerformanceEntryVector UserTiming::GetMarks(const AtomicString& name) const {
return GetEntrySequenceByName(marks_map_, name);
}
@@ -254,7 +257,7 @@ PerformanceEntryVector UserTiming::GetMeasures() const {
return ConvertToEntrySequence(measures_map_);
}
-PerformanceEntryVector UserTiming::GetMeasures(const String& name) const {
+PerformanceEntryVector UserTiming::GetMeasures(const AtomicString& name) const {
return GetEntrySequenceByName(measures_map_, name);
}
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 829da5438ac..a824355d4dd 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
@@ -39,7 +39,7 @@ class Performance;
typedef unsigned long long (
PerformanceTiming::*NavigationTimingFunction)() const;
-using PerformanceEntryMap = HeapHashMap<String, PerformanceEntryVector>;
+using PerformanceEntryMap = HeapHashMap<AtomicString, PerformanceEntryVector>;
class UserTiming final : public GarbageCollected<UserTiming> {
public:
@@ -48,32 +48,33 @@ class UserTiming final : public GarbageCollected<UserTiming> {
}
PerformanceMark* Mark(ScriptState*,
- const String& mark_name,
+ const AtomicString& mark_name,
const DOMHighResTimeStamp& start_time,
const ScriptValue& detail,
ExceptionState&);
- void ClearMarks(const String& mark_name);
+ void ClearMarks(const AtomicString& mark_name);
PerformanceMeasure* Measure(ScriptState*,
- const String& measure_name,
+ const AtomicString& measure_name,
const StringOrDouble& start,
const StringOrDouble& end,
const ScriptValue& detail,
ExceptionState&);
- void ClearMeasures(const String& measure_name);
+ void ClearMeasures(const AtomicString& measure_name);
PerformanceEntryVector GetMarks() const;
PerformanceEntryVector GetMeasures() const;
- PerformanceEntryVector GetMarks(const String& name) const;
- PerformanceEntryVector GetMeasures(const String& name) const;
+ PerformanceEntryVector GetMarks(const AtomicString& name) const;
+ PerformanceEntryVector GetMeasures(const AtomicString& name) const;
void Trace(blink::Visitor*);
private:
explicit UserTiming(Performance&);
- double FindExistingMarkStartTime(const String& mark_name, ExceptionState&);
+ double FindExistingMarkStartTime(const AtomicString& mark_name,
+ ExceptionState&);
double FindStartMarkOrTime(const StringOrDouble& start, ExceptionState&);
Member<Performance> performance_;
diff --git a/chromium/third_party/blink/renderer/core/timing/sub_task_attribution.cc b/chromium/third_party/blink/renderer/core/timing/sub_task_attribution.cc
index 00a872aea96..e7079af56a7 100644
--- a/chromium/third_party/blink/renderer/core/timing/sub_task_attribution.cc
+++ b/chromium/third_party/blink/renderer/core/timing/sub_task_attribution.cc
@@ -6,8 +6,8 @@
namespace blink {
-SubTaskAttribution::SubTaskAttribution(String sub_task_name,
- String script_url,
+SubTaskAttribution::SubTaskAttribution(const AtomicString& sub_task_name,
+ const String& script_url,
TimeTicks start_time,
TimeDelta duration)
: sub_task_name_(sub_task_name),
diff --git a/chromium/third_party/blink/renderer/core/timing/sub_task_attribution.h b/chromium/third_party/blink/renderer/core/timing/sub_task_attribution.h
index eef79dcda5b..d34b0498a39 100644
--- a/chromium/third_party/blink/renderer/core/timing/sub_task_attribution.h
+++ b/chromium/third_party/blink/renderer/core/timing/sub_task_attribution.h
@@ -18,18 +18,19 @@ class SubTaskAttribution {
public:
using EntriesVector = Vector<std::unique_ptr<SubTaskAttribution>>;
- static std::unique_ptr<SubTaskAttribution> Create(String sub_task_name,
- String script_url,
- TimeTicks start_time,
- TimeDelta duration) {
+ static std::unique_ptr<SubTaskAttribution> Create(
+ const AtomicString& sub_task_name,
+ const String& script_url,
+ TimeTicks start_time,
+ TimeDelta duration) {
return std::make_unique<SubTaskAttribution>(sub_task_name, script_url,
start_time, duration);
}
- SubTaskAttribution(String sub_task_name,
- String script_url,
+ SubTaskAttribution(const AtomicString& sub_task_name,
+ const String& script_url,
TimeTicks start_time,
TimeDelta duration);
- inline String subTaskName() const { return sub_task_name_; }
+ inline AtomicString subTaskName() const { return sub_task_name_; }
inline String scriptURL() const { return script_url_; }
inline TimeTicks startTime() const { return start_time_; }
inline TimeDelta duration() const { return duration_; }
@@ -48,7 +49,7 @@ class SubTaskAttribution {
}
private:
- String sub_task_name_;
+ AtomicString sub_task_name_;
String script_url_;
TimeTicks start_time_;
TimeDelta duration_;
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 1308fd60626..e52f954168f 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
@@ -6,17 +6,18 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h"
#include "third_party/blink/renderer/core/frame/dom_window.h"
+#include "third_party/blink/renderer/core/performance_entry_names.h"
namespace blink {
-TaskAttributionTiming::TaskAttributionTiming(String name,
- String container_type,
- String container_src,
- String container_id,
- String container_name,
+TaskAttributionTiming::TaskAttributionTiming(const AtomicString& name,
+ const String& container_type,
+ const String& container_src,
+ const String& container_id,
+ const String& container_name,
double start_time,
double finish_time,
- String script_url)
+ const String& script_url)
: PerformanceEntry(name, start_time, finish_time),
container_type_(container_type),
container_src_(container_src),
@@ -27,7 +28,7 @@ TaskAttributionTiming::TaskAttributionTiming(String name,
TaskAttributionTiming::~TaskAttributionTiming() = default;
AtomicString TaskAttributionTiming::entryType() const {
- return PerformanceEntry::TaskattributionKeyword();
+ return PerformanceEntryNames::taskattribution;
}
PerformanceEntryType TaskAttributionTiming::EntryTypeEnum() const {
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 875a306da22..835fdf73970 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
@@ -17,25 +17,25 @@ class TaskAttributionTiming final : public PerformanceEntry {
public:
// Used when the LongTaskV2 flag is enabled.
- static TaskAttributionTiming* Create(String type,
- String container_type,
- String container_src,
- String container_id,
- String container_name,
+ static TaskAttributionTiming* Create(const AtomicString& type,
+ const String& container_type,
+ const String& container_src,
+ const String& container_id,
+ const String& container_name,
double start_time,
double finish_time,
- String script_url) {
+ const String& script_url) {
return new TaskAttributionTiming(type, container_type, container_src,
container_id, container_name, start_time,
finish_time, script_url);
}
// Used when the LongTaskV2 flag is disabled.
- static TaskAttributionTiming* Create(String type,
- String container_type,
- String container_src,
- String container_id,
- String container_name) {
+ static TaskAttributionTiming* Create(const AtomicString& type,
+ const String& container_type,
+ const String& container_src,
+ const String& container_id,
+ const String& container_name) {
return new TaskAttributionTiming(type, container_type, container_src,
container_id, container_name, 0.0, 0.0,
g_empty_string);
@@ -55,14 +55,14 @@ class TaskAttributionTiming final : public PerformanceEntry {
~TaskAttributionTiming() override;
private:
- TaskAttributionTiming(String type,
- String container_type,
- String container_src,
- String container_id,
- String container_name,
+ TaskAttributionTiming(const AtomicString& type,
+ const String& container_type,
+ const String& container_src,
+ const String& container_id,
+ const String& container_name,
double start_time,
double finish_time,
- String script_url);
+ const String& script_url);
void BuildJSONValue(V8ObjectBuilder&) const override;
String container_type_;
diff --git a/chromium/third_party/blink/renderer/platform/time_clamper.cc b/chromium/third_party/blink/renderer/core/timing/time_clamper.cc
index ab38f2afa44..01468cec2e9 100644
--- a/chromium/third_party/blink/renderer/platform/time_clamper.cc
+++ b/chromium/third_party/blink/renderer/core/timing/time_clamper.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/platform/time_clamper.h"
+#include "third_party/blink/renderer/core/timing/time_clamper.h"
#include "base/bit_cast.h"
#include "base/rand_util.h"
@@ -15,13 +15,19 @@ namespace blink {
TimeClamper::TimeClamper() : secret_(base::RandUint64()) {}
double TimeClamper::ClampTimeResolution(double time_seconds) const {
- DCHECK_GE(time_seconds, 0);
+ bool was_negative = false;
+ if (time_seconds < 0) {
+ was_negative = true;
+ time_seconds = -time_seconds;
+ }
double interval = floor(time_seconds / kResolutionSeconds);
double clamped_time = interval * kResolutionSeconds;
double tick_threshold = ThresholdFor(clamped_time);
if (time_seconds >= tick_threshold)
- return (interval + 1) * kResolutionSeconds;
+ clamped_time = (interval + 1) * kResolutionSeconds;
+ if (was_negative)
+ clamped_time = -clamped_time;
return clamped_time;
}
diff --git a/chromium/third_party/blink/renderer/platform/time_clamper.h b/chromium/third_party/blink/renderer/core/timing/time_clamper.h
index 76e2888e8e7..b1bfc222e4a 100644
--- a/chromium/third_party/blink/renderer/platform/time_clamper.h
+++ b/chromium/third_party/blink/renderer/core/timing/time_clamper.h
@@ -2,17 +2,17 @@
// Use 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_TIME_CLAMPER_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_TIME_CLAMPER_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_TIMING_TIME_CLAMPER_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_TIMING_TIME_CLAMPER_H_
#include "base/macros.h"
-#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/core/core_export.h"
#include <stdint.h>
namespace blink {
-class PLATFORM_EXPORT TimeClamper {
+class CORE_EXPORT TimeClamper {
public:
static constexpr double kResolutionSeconds = 0.0001;
@@ -39,4 +39,4 @@ class PLATFORM_EXPORT TimeClamper {
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_TIME_CLAMPER_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_TIMING_TIME_CLAMPER_H_
diff --git a/chromium/third_party/blink/renderer/platform/time_clamper_test.cc b/chromium/third_party/blink/renderer/core/timing/time_clamper_test.cc
index f519dcfb692..21cb8ce7d2f 100644
--- a/chromium/third_party/blink/renderer/platform/time_clamper_test.cc
+++ b/chromium/third_party/blink/renderer/core/timing/time_clamper_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/platform/time_clamper.h"
+#include "third_party/blink/renderer/core/timing/time_clamper.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -45,6 +45,16 @@ TEST(TimeClamperTest, ClampingIsConsistent) {
}
}
+TEST(TimeClamperTest, ClampingNegativeNumbersIsConsistent) {
+ TimeClamper clamper;
+ for (double time_seconds = -kInterval * 100; time_seconds <= 0;
+ time_seconds += kInterval * 0.1) {
+ double t1 = clamper.ClampTimeResolution(time_seconds);
+ double t2 = clamper.ClampTimeResolution(time_seconds);
+ EXPECT_EQ(t1, t2);
+ }
+}
+
TEST(TimeClamperTest, ClampingIsPerInstance) {
const double kEpsilon = 1e-10;
TimeClamper clamper1;
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 8e24fd6ef25..c74b79eef98 100644
--- a/chromium/third_party/blink/renderer/core/timing/window_performance.cc
+++ b/chromium/third_party/blink/renderer/core/timing/window_performance.cc
@@ -55,17 +55,6 @@
static constexpr base::TimeDelta kLongTaskObserverThreshold =
base::TimeDelta::FromMilliseconds(50);
-static const char kUnknownAttribution[] = "unknown";
-static const char kAmbiguousAttribution[] = "multiple-contexts";
-static const char kSameOriginAttribution[] = "same-origin";
-static const char kSameOriginSelfAttribution[] = "self";
-static const char kSameOriginAncestorAttribution[] = "same-origin-ancestor";
-static const char kSameOriginDescendantAttribution[] = "same-origin-descendant";
-static const char kCrossOriginAncestorAttribution[] = "cross-origin-ancestor";
-static const char kCrossOriginDescendantAttribution[] =
- "cross-origin-descendant";
-static const char kCrossOriginAttribution[] = "cross-origin-unreachable";
-
namespace blink {
namespace {
@@ -87,21 +76,45 @@ String GetFrameAttribute(HTMLFrameOwnerElement* frame_owner,
return attr_value;
}
-const char* SameOriginAttribution(Frame* observer_frame, Frame* culprit_frame) {
+const AtomicString& SelfKeyword() {
+ DEFINE_STATIC_LOCAL(const AtomicString, kSelfAttribution, ("self"));
+ return kSelfAttribution;
+}
+
+const AtomicString& SameOriginAncestorKeyword() {
+ DEFINE_STATIC_LOCAL(const AtomicString, kSameOriginAncestorAttribution,
+ ("same-origin-ancestor"));
+ return kSameOriginAncestorAttribution;
+}
+
+const AtomicString& SameOriginDescendantKeyword() {
+ DEFINE_STATIC_LOCAL(const AtomicString, kSameOriginDescendantAttribution,
+ ("same-origin-descendant"));
+ return kSameOriginDescendantAttribution;
+}
+
+const AtomicString& SameOriginKeyword() {
+ DEFINE_STATIC_LOCAL(const AtomicString, kSameOriginAttribution,
+ ("same-origin"));
+ return kSameOriginAttribution;
+}
+
+AtomicString SameOriginAttribution(Frame* observer_frame,
+ Frame* culprit_frame) {
+ DCHECK(IsMainThread());
if (observer_frame == culprit_frame)
- return kSameOriginSelfAttribution;
+ return SelfKeyword();
if (observer_frame->Tree().IsDescendantOf(culprit_frame))
- return kSameOriginAncestorAttribution;
+ return SameOriginAncestorKeyword();
if (culprit_frame->Tree().IsDescendantOf(observer_frame))
- return kSameOriginDescendantAttribution;
- return kSameOriginAttribution;
+ return SameOriginDescendantKeyword();
+ return SameOriginKeyword();
}
-bool IsSameOrigin(String key) {
- return key == kSameOriginAttribution ||
- key == kSameOriginDescendantAttribution ||
- key == kSameOriginAncestorAttribution ||
- key == kSameOriginSelfAttribution;
+bool IsSameOrigin(const AtomicString& key) {
+ DCHECK(IsMainThread());
+ return key == SameOriginKeyword() || key == SameOriginDescendantKeyword() ||
+ key == SameOriginAncestorKeyword() || key == SelfKeyword();
}
} // namespace
@@ -172,7 +185,8 @@ WindowPerformance::CreateNavigationTimingInstance() {
return nullptr;
const DocumentLoader* document_loader =
GetFrame()->Loader().GetDocumentLoader();
- DCHECK(document_loader);
+ if (!document_loader)
+ return nullptr;
ResourceTimingInfo* info = document_loader->GetNavigationTimingInfo();
if (!info)
return nullptr;
@@ -228,18 +242,22 @@ static bool CanAccessOrigin(Frame* frame1, Frame* frame2) {
* See detailed Security doc here: http://bit.ly/2duD3F7
*/
// static
-std::pair<String, DOMWindow*> WindowPerformance::SanitizedAttribution(
+std::pair<AtomicString, DOMWindow*> WindowPerformance::SanitizedAttribution(
ExecutionContext* task_context,
bool has_multiple_contexts,
LocalFrame* observer_frame) {
+ DCHECK(IsMainThread());
if (has_multiple_contexts) {
// Unable to attribute, multiple script execution contents were involved.
+ DEFINE_STATIC_LOCAL(const AtomicString, kAmbiguousAttribution,
+ ("multiple-contexts"));
return std::make_pair(kAmbiguousAttribution, nullptr);
}
if (!task_context || !task_context->IsDocument() ||
!ToDocument(task_context)->GetFrame()) {
// Unable to attribute as no script was involved.
+ DEFINE_STATIC_LOCAL(const AtomicString, kUnknownAttribution, ("unknown"));
return std::make_pair(kUnknownAttribution, nullptr);
}
@@ -266,12 +284,18 @@ std::pair<String, DOMWindow*> WindowPerformance::SanitizedAttribution(
last_cross_origin_frame = frame;
}
}
+ DEFINE_STATIC_LOCAL(const AtomicString, kCrossOriginDescendantAttribution,
+ ("cross-origin-descendant"));
return std::make_pair(kCrossOriginDescendantAttribution,
last_cross_origin_frame->DomWindow());
}
if (observer_frame->Tree().IsDescendantOf(culprit_frame)) {
+ DEFINE_STATIC_LOCAL(const AtomicString, kCrossOriginAncestorAttribution,
+ ("cross-origin-ancestor"));
return std::make_pair(kCrossOriginAncestorAttribution, nullptr);
}
+ DEFINE_STATIC_LOCAL(const AtomicString, kCrossOriginAttribution,
+ ("cross-origin-unreachable"));
return std::make_pair(kCrossOriginAttribution, nullptr);
}
@@ -283,7 +307,7 @@ void WindowPerformance::ReportLongTask(
const SubTaskAttribution::EntriesVector& sub_task_attributions) {
if (!GetFrame())
return;
- std::pair<String, DOMWindow*> attribution =
+ std::pair<AtomicString, DOMWindow*> attribution =
WindowPerformance::SanitizedAttribution(
task_context, has_multiple_contexts, GetFrame());
DOMWindow* culprit_dom_window = attribution.second;
@@ -316,7 +340,7 @@ bool WindowPerformance::ObservingEventTimingEntries() {
return HasObserverFor(PerformanceEntry::kEvent);
}
-void WindowPerformance::RegisterEventTiming(String event_type,
+void WindowPerformance::RegisterEventTiming(const AtomicString& event_type,
TimeTicks start_time,
TimeTicks processing_start,
TimeTicks processing_end,
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 6cb0beb5b32..736343a2af7 100644
--- a/chromium/third_party/blink/renderer/core/timing/window_performance.h
+++ b/chromium/third_party/blink/renderer/core/timing/window_performance.h
@@ -73,7 +73,7 @@ class CORE_EXPORT WindowPerformance final : public Performance,
// This method creates a PerformanceEventTiming and if needed creates a swap
// promise to calculate the |duration| attribute when such promise is
// resolved.
- void RegisterEventTiming(String event_type,
+ void RegisterEventTiming(const AtomicString& event_type,
TimeTicks start_time,
TimeTicks processing_start,
TimeTicks processing_end,
@@ -86,7 +86,7 @@ class CORE_EXPORT WindowPerformance final : public Performance,
PerformanceNavigationTiming* CreateNavigationTimingInstance() override;
- static std::pair<String, DOMWindow*> SanitizedAttribution(
+ static std::pair<AtomicString, DOMWindow*> SanitizedAttribution(
ExecutionContext*,
bool has_multiple_contexts,
LocalFrame* observer_frame);
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 181b469ecc1..a1b0e2691e8 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
@@ -144,7 +144,8 @@ TEST_F(WindowPerformanceTest, NavigateAway) {
EXPECT_TRUE(ObservingLongTasks());
// Simulate navigation commit.
- DocumentInit init = DocumentInit::Create().WithFrame(GetFrame());
+ DocumentInit init = DocumentInit::Create().WithDocumentLoader(
+ GetFrame()->Loader().GetDocumentLoader());
GetDocument()->Shutdown();
GetFrame()->SetDOMWindow(LocalDOMWindow::Create(*GetFrame()));
GetFrame()->DomWindow()->InstallNewDocument(AtomicString(), init, false);
@@ -178,7 +179,7 @@ TEST(PerformanceLifetimeTest, SurviveContextSwitch) {
page_holder->GetDocument().Shutdown();
page_holder->GetFrame().DomWindow()->InstallNewDocument(
AtomicString(),
- DocumentInit::Create().WithFrame(&page_holder->GetFrame()), false);
+ DocumentInit::Create().WithDocumentLoader(document_loader), false);
EXPECT_EQ(perf, DOMWindowPerformance::performance(
*page_holder->GetFrame().DomWindow()));
@@ -198,22 +199,22 @@ TEST_F(WindowPerformanceTest, EnsureEntryListOrder) {
DummyExceptionStateForTesting exception_state;
clock.Advance(TimeDelta::FromSeconds(2));
for (int i = 0; i < 8; i++) {
- performance_->mark(scope.GetScriptState(), String::Number(i),
+ performance_->mark(scope.GetScriptState(), AtomicString::Number(i),
exception_state);
}
clock.Advance(TimeDelta::FromSeconds(2));
for (int i = 8; i < 17; i++) {
- performance_->mark(scope.GetScriptState(), String::Number(i),
+ performance_->mark(scope.GetScriptState(), AtomicString::Number(i),
exception_state);
}
PerformanceEntryVector entries = performance_->getEntries();
EXPECT_EQ(17U, entries.size());
for (int i = 0; i < 8; i++) {
- EXPECT_EQ(String::Number(i), entries[i]->name());
+ EXPECT_EQ(AtomicString::Number(i), entries[i]->name());
EXPECT_NEAR(2000, entries[i]->startTime(), 0.005);
}
for (int i = 8; i < 17; i++) {
- EXPECT_EQ(String::Number(i), entries[i]->name());
+ EXPECT_EQ(AtomicString::Number(i), entries[i]->name());
EXPECT_NEAR(4000, entries[i]->startTime(), 0.005);
}
}
@@ -305,7 +306,7 @@ TEST_F(WindowPerformanceTest, MultipleEventsSameSwap) {
// Test for existence of 'firstInput' given different types of first events.
TEST_F(WindowPerformanceTest, FirstInput) {
struct {
- String event_type;
+ AtomicString event_type;
bool should_report;
} inputs[] = {{"click", true}, {"keydown", true},
{"keypress", false}, {"pointerdown", false},
@@ -329,7 +330,7 @@ TEST_F(WindowPerformanceTest, FirstInput) {
// Test that the 'firstInput' is populated after some irrelevant events are
// ignored.
TEST_F(WindowPerformanceTest, FirstInputAfterIgnored) {
- String several_events[] = {"mousemove", "mouseover", "mousedown"};
+ AtomicString several_events[] = {"mousemove", "mouseover", "mousedown"};
for (const auto& event : several_events) {
performance_->RegisterEventTiming(
event, GetTimeOrigin(),
diff --git a/chromium/third_party/blink/renderer/core/trustedtypes/BUILD.gn b/chromium/third_party/blink/renderer/core/trustedtypes/BUILD.gn
index 36b86dcfbd9..a06047961d0 100644
--- a/chromium/third_party/blink/renderer/core/trustedtypes/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/trustedtypes/BUILD.gn
@@ -8,8 +8,14 @@ blink_core_sources("trustedtypes") {
sources = [
"trusted_html.cc",
"trusted_html.h",
+ "trusted_script.cc",
+ "trusted_script.h",
"trusted_script_url.cc",
"trusted_script_url.h",
+ "trusted_type_policy.cc",
+ "trusted_type_policy.h",
+ "trusted_type_policy_factory.cc",
+ "trusted_type_policy_factory.h",
"trusted_url.cc",
"trusted_url.h",
]
diff --git a/chromium/third_party/blink/renderer/core/trustedtypes/trusted_html.cc b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_html.cc
index 2b1cf3fa061..54b6f1a6e45 100644
--- a/chromium/third_party/blink/renderer/core/trustedtypes/trusted_html.cc
+++ b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_html.cc
@@ -4,7 +4,10 @@
#include "third_party/blink/renderer/core/trustedtypes/trusted_html.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/platform/bindings/script_state.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
namespace blink {
@@ -30,6 +33,25 @@ TrustedHTML* TrustedHTML::unsafelyCreate(ScriptState* script_state,
return TrustedHTML::Create(html);
}
+String TrustedHTML::GetString(StringOrTrustedHTML stringOrHTML,
+ const Document* doc,
+ ExceptionState& exception_state) {
+ DCHECK(stringOrHTML.IsString() ||
+ RuntimeEnabledFeatures::TrustedDOMTypesEnabled());
+ DCHECK(!stringOrHTML.IsNull());
+
+ if (!stringOrHTML.IsTrustedHTML() && doc && doc->RequireTrustedTypes()) {
+ exception_state.ThrowTypeError(
+ "This document requires `TrustedHTML` assignment.");
+ return g_empty_string;
+ }
+
+ String markup = stringOrHTML.IsString()
+ ? stringOrHTML.GetAsString()
+ : stringOrHTML.GetAsTrustedHTML()->toString();
+ return markup;
+}
+
String TrustedHTML::toString() const {
return html_;
}
diff --git a/chromium/third_party/blink/renderer/core/trustedtypes/trusted_html.h b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_html.h
index f9cf7a8b22d..423b8c016bb 100644
--- a/chromium/third_party/blink/renderer/core/trustedtypes/trusted_html.h
+++ b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_html.h
@@ -12,7 +12,10 @@
namespace blink {
+class Document;
+class ExceptionState;
class ScriptState;
+class StringOrTrustedHTML;
class CORE_EXPORT TrustedHTML final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
@@ -26,6 +29,7 @@ class CORE_EXPORT TrustedHTML final : public ScriptWrappable {
String toString() const;
static TrustedHTML* escape(ScriptState*, const String& html);
static TrustedHTML* unsafelyCreate(ScriptState*, const String& html);
+ static String GetString(StringOrTrustedHTML, const Document*, ExceptionState&);
private:
TrustedHTML(const String& html);
diff --git a/chromium/third_party/blink/renderer/core/trustedtypes/trusted_script.cc b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_script.cc
new file mode 100644
index 00000000000..a260b3799b7
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_script.cc
@@ -0,0 +1,40 @@
+// 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/trustedtypes/trusted_script.h"
+
+#include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_script.h"
+#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+
+namespace blink {
+
+TrustedScript::TrustedScript(const String& script) : script_(script) {}
+
+String TrustedScript::GetString(StringOrTrustedScript string_or_trusted_script,
+ const Document* doc,
+ ExceptionState& exception_state) {
+ DCHECK(string_or_trusted_script.IsString() ||
+ RuntimeEnabledFeatures::TrustedDOMTypesEnabled());
+ DCHECK(!string_or_trusted_script.IsNull());
+
+ if (!string_or_trusted_script.IsTrustedScript() && doc &&
+ doc->RequireTrustedTypes()) {
+ exception_state.ThrowTypeError(
+ "This document requires `TrustedScript` assignment.");
+ return g_empty_string;
+ }
+
+ String markup =
+ string_or_trusted_script.IsString()
+ ? string_or_trusted_script.GetAsString()
+ : string_or_trusted_script.GetAsTrustedScript()->toString();
+ return markup;
+}
+
+String TrustedScript::toString() const {
+ return script_;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/trustedtypes/trusted_script.h b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_script.h
new file mode 100644
index 00000000000..d94f19347c9
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_script.h
@@ -0,0 +1,42 @@
+// 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_TRUSTEDTYPES_TRUSTED_SCRIPT_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_TRUSTEDTYPES_TRUSTED_SCRIPT_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/text/wtf_string.h"
+
+namespace blink {
+
+class Document;
+class ExceptionState;
+class StringOrTrustedScript;
+
+class CORE_EXPORT TrustedScript final : public ScriptWrappable {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ static TrustedScript* Create(const String& script) {
+ return new TrustedScript(script);
+ }
+
+ // TrustedScript.idl
+ String toString() const;
+
+ static String GetString(StringOrTrustedScript,
+ const Document*,
+ ExceptionState&);
+
+ private:
+ TrustedScript(const String& script);
+
+ const String script_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_TRUSTEDTYPES_TRUSTED_SCRIPT_H_
diff --git a/chromium/third_party/blink/renderer/core/trustedtypes/trusted_script.idl b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_script.idl
new file mode 100644
index 00000000000..0d74f210bf4
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_script.idl
@@ -0,0 +1,14 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// https://github.com/wicg/trusted-types
+
+typedef (DOMString or TrustedScript) ScriptString;
+
+[
+ Exposed=(Window,Worker),
+ RuntimeEnabled=TrustedDOMTypes
+] interface TrustedScript {
+ 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
new file mode 100644
index 00000000000..b632dfc3e2f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.cc
@@ -0,0 +1,124 @@
+// 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/trustedtypes/trusted_type_policy.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_url.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/bindings/to_v8.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+
+namespace blink {
+
+TrustedTypePolicy::TrustedTypePolicy(
+ const String& policy_name,
+ const TrustedTypePolicyOptions& policy_options,
+ bool exposed)
+ : name_(policy_name), policy_options_(policy_options) {
+ policy_options_.setExposed(exposed);
+}
+
+TrustedTypePolicy* TrustedTypePolicy::Create(
+ const String& policy_name,
+ const TrustedTypePolicyOptions& policy_options,
+ bool exposed) {
+ return new TrustedTypePolicy(policy_name, policy_options, exposed);
+}
+
+TrustedHTML* TrustedTypePolicy::createHTML(ScriptState* script_state,
+ const String& input,
+ ExceptionState& exception_state) {
+ if (!policy_options_.createHTML()) {
+ exception_state.ThrowTypeError(
+ "Policy " + name_ +
+ "'s TrustedTypePolicyOptions did not specify a 'createHTML' member.");
+ return nullptr;
+ }
+ v8::TryCatch try_catch(script_state->GetIsolate());
+ String html;
+ if (!policy_options_.createHTML()->Invoke(nullptr, input).To(&html)) {
+ DCHECK(try_catch.HasCaught());
+ exception_state.RethrowV8Exception(try_catch.Exception());
+ return nullptr;
+ }
+ return TrustedHTML::Create(html);
+}
+
+TrustedScript* TrustedTypePolicy::createScript(
+ ScriptState* script_state,
+ const String& input,
+ ExceptionState& exception_state) {
+ if (!policy_options_.createScript()) {
+ exception_state.ThrowTypeError(
+ "Policy " + name_ +
+ "'s TrustedTypePolicyOptions did not specify a 'createScript' member.");
+ return nullptr;
+ }
+ v8::TryCatch try_catch(script_state->GetIsolate());
+ String script;
+ if (!policy_options_.createScript()->Invoke(nullptr, input).To(&script)) {
+ DCHECK(try_catch.HasCaught());
+ exception_state.RethrowV8Exception(try_catch.Exception());
+ return nullptr;
+ }
+ return TrustedScript::Create(script);
+}
+
+TrustedScriptURL* TrustedTypePolicy::createScriptURL(
+ ScriptState* script_state,
+ const String& input,
+ ExceptionState& exception_state) {
+ if (!policy_options_.createScriptURL()) {
+ exception_state.ThrowTypeError("Policy " + name_ +
+ "'s TrustedTypePolicyOptions did not "
+ "specify a 'createScriptURL' member.");
+ return nullptr;
+ }
+ v8::TryCatch try_catch(script_state->GetIsolate());
+ String script_url;
+ if (!policy_options_.createScriptURL()
+ ->Invoke(nullptr, input)
+ .To(&script_url)) {
+ DCHECK(try_catch.HasCaught());
+ exception_state.RethrowV8Exception(try_catch.Exception());
+ return nullptr;
+ }
+ return TrustedScriptURL::Create(KURL(script_url));
+}
+
+TrustedURL* TrustedTypePolicy::createURL(ScriptState* script_state,
+ const String& input,
+ ExceptionState& exception_state) {
+ if (!policy_options_.createURL()) {
+ exception_state.ThrowTypeError(
+ "Policy " + name_ +
+ "'s TrustedTypePolicyOptions did not specify a 'createURL' member.");
+ return nullptr;
+ }
+ v8::TryCatch try_catch(script_state->GetIsolate());
+ String url;
+ if (!policy_options_.createURL()->Invoke(nullptr, input).To(&url)) {
+ DCHECK(try_catch.HasCaught());
+ exception_state.RethrowV8Exception(try_catch.Exception());
+ return nullptr;
+ }
+ return TrustedURL::Create(KURL(url));
+}
+
+String TrustedTypePolicy::name() const {
+ return name_;
+}
+
+bool TrustedTypePolicy::exposed() const {
+ return policy_options_.exposed();
+}
+
+void TrustedTypePolicy::Trace(blink::Visitor* visitor) {
+ visitor->Trace(policy_options_);
+ ScriptWrappable::Trace(visitor);
+}
+} // namespace blink
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
new file mode 100644
index 00000000000..35b1e18dbf0
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.h
@@ -0,0 +1,54 @@
+// 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_TRUSTEDTYPES_TRUSTED_TYPE_POLICY_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_TRUSTEDTYPES_TRUSTED_TYPE_POLICY_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/bindings/trace_wrapper_member.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+
+class ExceptionState;
+class TrustedHTML;
+class TrustedScript;
+class TrustedScriptURL;
+class TrustedURL;
+
+class CORE_EXPORT TrustedTypePolicy final : public ScriptWrappable {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ static TrustedTypePolicy* Create(const String& policy_name,
+ const TrustedTypePolicyOptions&,
+ bool exposed);
+
+ TrustedHTML* createHTML(ScriptState*, const String&, ExceptionState&);
+ TrustedScript* createScript(ScriptState*, const String&, ExceptionState&);
+ TrustedScriptURL* createScriptURL(ScriptState*,
+ const String&,
+ ExceptionState&);
+ TrustedURL* createURL(ScriptState*, const String&, ExceptionState&);
+
+ String name() const;
+
+ bool exposed() const;
+
+ void Trace(blink::Visitor*) override;
+
+ private:
+ TrustedTypePolicy(const String& policy_name,
+ const TrustedTypePolicyOptions&,
+ bool exposed);
+
+ String name_;
+ TrustedTypePolicyOptions policy_options_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_TRUSTEDTYPES_TRUSTED_TYPE_POLICY_H_
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
new file mode 100644
index 00000000000..4c36933bddf
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.idl
@@ -0,0 +1,15 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://github.com/wicg/trusted-types
+[
+ Exposed=(Window),
+ RuntimeEnabled=TrustedDOMTypes
+] interface TrustedTypePolicy {
+ readonly attribute DOMString name;
+ [CallWith=ScriptState, RaisesException] TrustedHTML createHTML(DOMString input);
+ [CallWith=ScriptState, RaisesException] TrustedScript createScript(DOMString input);
+ [CallWith=ScriptState, RaisesException] TrustedScriptURL createScriptURL(DOMString input);
+ [CallWith=ScriptState, RaisesException] TrustedURL createURL(DOMString input);
+};
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
new file mode 100644
index 00000000000..cdcd58885aa
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.cc
@@ -0,0 +1,56 @@
+// 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/trustedtypes/trusted_type_policy_factory.h"
+
+#include "third_party/blink/renderer/core/trustedtypes/trusted_type_policy.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/wtf/text/string_hash.h"
+
+namespace blink {
+
+TrustedTypePolicy* TrustedTypePolicyFactory::createPolicy(
+ const String& policy_name,
+ const TrustedTypePolicyOptions& policy_options,
+ bool exposed,
+ ExceptionState& exception_state) {
+ if (policy_map_.Contains(policy_name)) {
+ exception_state.ThrowTypeError("Policy with name" + policy_name +
+ " already exists.");
+ return nullptr;
+ }
+ TrustedTypePolicy* policy =
+ TrustedTypePolicy::Create(policy_name, policy_options, exposed);
+ policy_map_.insert(policy_name, policy);
+ return policy;
+}
+
+TrustedTypePolicy* TrustedTypePolicyFactory::getExposedPolicy(
+ const String& policy_name) {
+ TrustedTypePolicy* p = policy_map_.at(policy_name);
+ if (p && p->exposed()) {
+ return p;
+ }
+ return nullptr;
+}
+
+TrustedTypePolicyFactory::TrustedTypePolicyFactory(LocalFrame* frame)
+ : DOMWindowClient(frame) {}
+
+Vector<String> TrustedTypePolicyFactory::getPolicyNames() const {
+ Vector<String> policyNames;
+ for (const String name : policy_map_.Keys()) {
+ policyNames.push_back(name);
+ }
+ return policyNames;
+}
+
+void TrustedTypePolicyFactory::Trace(blink::Visitor* visitor) {
+ ScriptWrappable::Trace(visitor);
+ DOMWindowClient::Trace(visitor);
+ visitor->Trace(policy_map_);
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..35a6313312f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.h
@@ -0,0 +1,50 @@
+// 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_TRUSTEDTYPES_TRUSTED_TYPE_POLICY_FACTORY_H_
+#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/dom/context_lifecycle_observer.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/heap/heap_allocator.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+
+class ExceptionState;
+class LocalFrame;
+class TrustedTypePolicy;
+
+class CORE_EXPORT TrustedTypePolicyFactory final : public ScriptWrappable,
+ public DOMWindowClient {
+ DEFINE_WRAPPERTYPEINFO();
+ USING_GARBAGE_COLLECTED_MIXIN(TrustedTypePolicyFactory);
+
+ public:
+ static TrustedTypePolicyFactory* Create(LocalFrame* frame) {
+ return new TrustedTypePolicyFactory(frame);
+ }
+
+ TrustedTypePolicy* createPolicy(const String&,
+ const TrustedTypePolicyOptions&,
+ bool exposed,
+ ExceptionState&);
+
+ TrustedTypePolicy* getExposedPolicy(const String&);
+
+ Vector<String> getPolicyNames() const;
+
+ void Trace(blink::Visitor*) override;
+
+ private:
+ explicit TrustedTypePolicyFactory(LocalFrame*);
+
+ HeapHashMap<String, Member<TrustedTypePolicy>> policy_map_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_TRUSTEDTYPES_TRUSTED_TYPE_POLICY_FACTORY_H_
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
new file mode 100644
index 00000000000..e42e08e48d4
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.idl
@@ -0,0 +1,15 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://github.com/wicg/trusted-types
+
+[
+ Exposed=(Window),
+ RuntimeEnabled=TrustedDOMTypes
+] interface TrustedTypePolicyFactory {
+ [RaisesException] TrustedTypePolicy createPolicy(DOMString policyName, TrustedTypePolicyOptions policyOptions, optional boolean exposed = false);
+ TrustedTypePolicy getExposedPolicy(DOMString policyName);
+ // All the policy object names that have been created
+ [Affects=Nothing] sequence<DOMString> getPolicyNames();
+};
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
new file mode 100644
index 00000000000..7d5720e381f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_options.idl
@@ -0,0 +1,17 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://github.com/wicg/trusted-types
+
+dictionary TrustedTypePolicyOptions {
+ CreateHTMLCallback createHTML;
+ CreateScriptCallback createScript;
+ CreateURLCallback createScriptURL;
+ CreateURLCallback createURL;
+ boolean exposed = false;
+};
+
+callback CreateHTMLCallback = DOMString (DOMString input);
+callback CreateScriptCallback = DOMString (DOMString input);
+callback CreateURLCallback = USVString (DOMString input);
diff --git a/chromium/third_party/blink/renderer/core/trustedtypes/trusted_url.cc b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_url.cc
index aca934aa777..38e6d98182f 100644
--- a/chromium/third_party/blink/renderer/core/trustedtypes/trusted_url.cc
+++ b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_url.cc
@@ -4,8 +4,11 @@
#include "third_party/blink/renderer/core/trustedtypes/trusted_url.h"
+#include "third_party/blink/renderer/bindings/core/v8/usv_string_or_trusted_url.h"
+#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
namespace blink {
@@ -26,6 +29,25 @@ TrustedURL* TrustedURL::unsafelyCreate(ScriptState* script_state,
ExecutionContext::From(script_state)->CompleteURL(url));
}
+String TrustedURL::GetString(USVStringOrTrustedURL stringOrURL,
+ const Document* doc,
+ ExceptionState& exception_state) {
+ DCHECK(stringOrURL.IsUSVString() ||
+ RuntimeEnabledFeatures::TrustedDOMTypesEnabled());
+ DCHECK(!stringOrURL.IsNull());
+
+ if (!stringOrURL.IsTrustedURL() && doc && doc->RequireTrustedTypes()) {
+ exception_state.ThrowTypeError(
+ "This document requires `TrustedURL` assignment.");
+ return g_empty_string;
+ }
+
+ String markup = stringOrURL.IsUSVString()
+ ? stringOrURL.GetAsUSVString()
+ : stringOrURL.GetAsTrustedURL()->toString();
+ return markup;
+}
+
String TrustedURL::toString() const {
return url_.GetString();
}
diff --git a/chromium/third_party/blink/renderer/core/trustedtypes/trusted_url.h b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_url.h
index 09fcec5de6e..6e33c23fd7f 100644
--- a/chromium/third_party/blink/renderer/core/trustedtypes/trusted_url.h
+++ b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_url.h
@@ -13,7 +13,10 @@
namespace blink {
+class Document;
+class ExceptionState;
class ScriptState;
+class USVStringOrTrustedURL;
class CORE_EXPORT TrustedURL final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
@@ -25,6 +28,9 @@ class CORE_EXPORT TrustedURL final : public ScriptWrappable {
String toString() const;
static TrustedURL* create(ScriptState*, const String& url);
static TrustedURL* unsafelyCreate(ScriptState*, const String& url);
+ static String GetString(USVStringOrTrustedURL,
+ const Document*,
+ ExceptionState&);
private:
TrustedURL(const KURL&);
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 e4e9c0a05eb..15d92a80d0c 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
@@ -75,8 +75,12 @@ v8::Local<v8::Object> DOMArrayBuffer::Wrap(
DCHECK(!DOMDataStore::ContainsWrapper(this, isolate));
const WrapperTypeInfo* wrapper_type_info = this->GetWrapperTypeInfo();
- v8::Local<v8::Object> wrapper =
- v8::ArrayBuffer::New(isolate, Data(), ByteLength());
+
+ v8::Local<v8::Object> wrapper;
+ {
+ v8::Context::Scope context_scope(creation_context->CreationContext());
+ wrapper = v8::ArrayBuffer::New(isolate, Data(), ByteLength());
+ }
return AssociateWithWrapper(isolate, wrapper_type_info, wrapper);
}
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 23defdf7bc9..5b000ded31c 100644
--- a/chromium/third_party/blink/renderer/core/url/dom_url.cc
+++ b/chromium/third_party/blink/renderer/core/url/dom_url.cc
@@ -55,10 +55,6 @@ void DOMURL::Trace(blink::Visitor* visitor) {
ScriptWrappable::Trace(visitor);
}
-void DOMURL::setHref(const String& value) {
- SetInput(value);
-}
-
void DOMURL::SetInput(const String& value) {
KURL url(BlankURL(), value);
if (url.IsValid()) {
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 56d52e56cba..3a7d578c6b1 100644
--- a/chromium/third_party/blink/renderer/core/url/dom_url.h
+++ b/chromium/third_party/blink/renderer/core/url/dom_url.h
@@ -70,8 +70,6 @@ class DOMURL final : public ScriptWrappable, public DOMURLUtils {
void Trace(blink::Visitor*) override;
- void setHref(const String&);
-
private:
friend class URLSearchParams;
DOMURL(const String& url, const KURL& base, ExceptionState&);
diff --git a/chromium/third_party/blink/renderer/core/url/dom_url_utils.cc b/chromium/third_party/blink/renderer/core/url/dom_url_utils.cc
index 928053a4236..6e05c1b6ee7 100644
--- a/chromium/third_party/blink/renderer/core/url/dom_url_utils.cc
+++ b/chromium/third_party/blink/renderer/core/url/dom_url_utils.cc
@@ -26,9 +26,6 @@
#include "third_party/blink/renderer/core/url/dom_url_utils.h"
-#include "third_party/blink/renderer/bindings/core/v8/usv_string_or_trusted_url.h"
-#include "third_party/blink/renderer/core/dom/document.h"
-#include "third_party/blink/renderer/core/trustedtypes/trusted_url.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/weborigin/known_ports.h"
@@ -36,25 +33,7 @@ namespace blink {
DOMURLUtils::~DOMURLUtils() = default;
-void DOMURLUtils::setHref(ScriptState* script_state,
- const USVStringOrTrustedURL& stringOrUrl,
- ExceptionState& exception_state) {
- DCHECK(stringOrUrl.IsUSVString() ||
- RuntimeEnabledFeatures::TrustedDOMTypesEnabled());
- DCHECK(!stringOrUrl.IsNull());
-
- if (ExecutionContext::From(script_state)->IsDocument()) {
- Document* document = ToDocument((ExecutionContext::From(script_state)));
- if (!stringOrUrl.IsTrustedURL() && document->RequireTrustedTypes()) {
- exception_state.ThrowTypeError(
- "This document requires `TrustedURL` assignment.");
- return;
- }
- }
-
- String value = stringOrUrl.IsUSVString()
- ? stringOrUrl.GetAsUSVString()
- : stringOrUrl.GetAsTrustedURL()->toString();
+void DOMURLUtils::setHref(const String& value) {
SetInput(value);
}
diff --git a/chromium/third_party/blink/renderer/core/url/dom_url_utils.h b/chromium/third_party/blink/renderer/core/url/dom_url_utils.h
index 2432755144a..75f00cea919 100644
--- a/chromium/third_party/blink/renderer/core/url/dom_url_utils.h
+++ b/chromium/third_party/blink/renderer/core/url/dom_url_utils.h
@@ -33,10 +33,7 @@
namespace blink {
-class ExceptionState;
-class ScriptState;
class KURL;
-class USVStringOrTrustedURL;
class CORE_EXPORT DOMURLUtils : public DOMURLUtilsReadOnly {
public:
@@ -44,7 +41,7 @@ class CORE_EXPORT DOMURLUtils : public DOMURLUtilsReadOnly {
virtual void SetInput(const String&) = 0;
~DOMURLUtils() override;
- void setHref(ScriptState*, const USVStringOrTrustedURL&, ExceptionState&);
+ void setHref(const String&);
void setProtocol(const String&);
void setUsername(const String&);
diff --git a/chromium/third_party/blink/renderer/core/url/dom_url_utils_read_only.cc b/chromium/third_party/blink/renderer/core/url/dom_url_utils_read_only.cc
index fdb51e4aaf9..ad8b10277e9 100644
--- a/chromium/third_party/blink/renderer/core/url/dom_url_utils_read_only.cc
+++ b/chromium/third_party/blink/renderer/core/url/dom_url_utils_read_only.cc
@@ -33,14 +33,14 @@
namespace blink {
-String DOMURLUtilsReadOnly::href(ScriptState*, ExceptionState&) {
+String DOMURLUtilsReadOnly::href(ExceptionState&) {
const KURL& kurl = Url();
if (kurl.IsNull())
return Input();
return kurl.GetString();
}
-void DOMURLUtilsReadOnly::href(ScriptState*, USVStringOrTrustedURL& result) {
+void DOMURLUtilsReadOnly::href(USVStringOrTrustedURL& result) {
result.SetUSVString(href());
}
diff --git a/chromium/third_party/blink/renderer/core/url/dom_url_utils_read_only.h b/chromium/third_party/blink/renderer/core/url/dom_url_utils_read_only.h
index 6544b7186d8..ef99f711ce7 100644
--- a/chromium/third_party/blink/renderer/core/url/dom_url_utils_read_only.h
+++ b/chromium/third_party/blink/renderer/core/url/dom_url_utils_read_only.h
@@ -35,7 +35,6 @@
namespace blink {
class ExceptionState;
-class ScriptState;
class USVStringOrTrustedURL;
class CORE_EXPORT DOMURLUtilsReadOnly {
@@ -44,8 +43,8 @@ class CORE_EXPORT DOMURLUtilsReadOnly {
virtual String Input() const = 0;
virtual ~DOMURLUtilsReadOnly() = default;
- void href(ScriptState*, USVStringOrTrustedURL&);
- String href(ScriptState* = nullptr, ExceptionState& = ASSERT_NO_EXCEPTION);
+ void href(USVStringOrTrustedURL&);
+ String href(ExceptionState& = ASSERT_NO_EXCEPTION);
static String origin(const KURL&);
String origin() { return origin(Url()); }
diff --git a/chromium/third_party/blink/renderer/core/workers/BUILD.gn b/chromium/third_party/blink/renderer/core/workers/BUILD.gn
index 57a956328fd..ac2bd37fe12 100644
--- a/chromium/third_party/blink/renderer/core/workers/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/workers/BUILD.gn
@@ -78,10 +78,6 @@ blink_core_sources("workers") {
"worker_settings.h",
"worker_thread.cc",
"worker_thread.h",
- "worker_thread_lifecycle_context.cc",
- "worker_thread_lifecycle_context.h",
- "worker_thread_lifecycle_observer.cc",
- "worker_thread_lifecycle_observer.h",
"worklet.cc",
"worklet.h",
"worklet_global_scope.cc",
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 a403a854b17..4940115b85e 100644
--- a/chromium/third_party/blink/renderer/core/workers/dedicated_worker.cc
+++ b/chromium/third_party/blink/renderer/core/workers/dedicated_worker.cc
@@ -12,6 +12,7 @@
#include "third_party/blink/public/platform/web_content_settings_client.h"
#include "third_party/blink/public/platform/web_layer_tree_view.h"
#include "third_party/blink/public/web/web_local_frame_client.h"
+#include "third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.h"
#include "third_party/blink/renderer/core/core_initializer.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/events/message_event.h"
@@ -19,6 +20,7 @@
#include "third_party/blink/renderer/core/frame/use_counter.h"
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
#include "third_party/blink/renderer/core/inspector/main_thread_debugger.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"
@@ -64,9 +66,9 @@ DedicatedWorker* DedicatedWorker::Create(ExecutionContext* context,
return nullptr;
}
- KURL script_url = ResolveURL(context, url, exception_state,
- WebURLRequest::kRequestContextScript);
- if (!script_url.IsValid()) {
+ KURL script_request_url = ResolveURL(context, url, exception_state,
+ WebURLRequest::kRequestContextScript);
+ if (!script_request_url.IsValid()) {
// Don't throw an exception here because it's already thrown in
// ResolveURL().
return nullptr;
@@ -86,20 +88,21 @@ DedicatedWorker* DedicatedWorker::Create(ExecutionContext* context,
if (context->IsWorkerGlobalScope())
UseCounter::Count(context, WebFeature::kNestedDedicatedWorker);
- DedicatedWorker* worker = new DedicatedWorker(context, script_url, options);
+ DedicatedWorker* worker =
+ new DedicatedWorker(context, script_request_url, options);
worker->Start();
return worker;
}
DedicatedWorker::DedicatedWorker(ExecutionContext* context,
- const KURL& script_url,
+ const KURL& script_request_url,
const WorkerOptions& options)
: AbstractWorker(context),
- script_url_(script_url),
+ script_request_url_(script_request_url),
options_(options),
context_proxy_(new DedicatedWorkerMessagingProxy(context, this)) {
DCHECK(context->IsContextThread());
- DCHECK(script_url_.IsValid());
+ DCHECK(script_request_url_.IsValid());
DCHECK(context_proxy_);
}
@@ -109,20 +112,47 @@ DedicatedWorker::~DedicatedWorker() {
}
void DedicatedWorker::postMessage(ScriptState* script_state,
- scoped_refptr<SerializedScriptValue> message,
- const MessagePortArray& ports,
+ const ScriptValue& message,
+ Vector<ScriptValue>& transfer,
+ ExceptionState& exception_state) {
+ PostMessageOptions options;
+ if (!transfer.IsEmpty())
+ options.setTransfer(transfer);
+ postMessage(script_state, message, options, exception_state);
+}
+
+void DedicatedWorker::postMessage(ScriptState* script_state,
+ const ScriptValue& message,
+ const PostMessageOptions& options,
ExceptionState& exception_state) {
DCHECK(GetExecutionContext()->IsContextThread());
+
+ BlinkTransferableMessage transferable_message;
+ Transferables transferables;
+ scoped_refptr<SerializedScriptValue> serialized_message =
+ PostMessageHelper::SerializeMessageByMove(script_state->GetIsolate(),
+ message, options, transferables,
+ exception_state);
+ if (exception_state.HadException())
+ return;
+ DCHECK(serialized_message);
+ transferable_message.message = serialized_message;
+
// Disentangle the port in preparation for sending it to the remote context.
- auto channels = MessagePort::DisentanglePorts(
- ExecutionContext::From(script_state), ports, exception_state);
+ transferable_message.ports = MessagePort::DisentanglePorts(
+ ExecutionContext::From(script_state), transferables.message_ports,
+ exception_state);
if (exception_state.HadException())
return;
- v8_inspector::V8StackTraceId stack_id =
+ transferable_message.user_activation =
+ PostMessageHelper::CreateUserActivationSnapshot(GetExecutionContext(),
+ options);
+
+ transferable_message.sender_stack_trace_id =
ThreadDebugger::From(script_state->GetIsolate())
->StoreCurrentStackTrace("Worker.postMessage");
- context_proxy_->PostMessageToWorkerGlobalScope(std::move(message),
- std::move(channels), stack_id);
+ context_proxy_->PostMessageToWorkerGlobalScope(
+ std::move(transferable_message));
}
// https://html.spec.whatwg.org/multipage/workers.html#worker-processing-model
@@ -142,13 +172,13 @@ void DedicatedWorker::Start() {
network::mojom::FetchRequestMode::kSameOrigin;
network::mojom::FetchCredentialsMode fetch_credentials_mode =
network::mojom::FetchCredentialsMode::kSameOrigin;
- if (script_url_.ProtocolIsData()) {
+ if (script_request_url_.ProtocolIsData()) {
fetch_request_mode = network::mojom::FetchRequestMode::kNoCORS;
fetch_credentials_mode = network::mojom::FetchCredentialsMode::kInclude;
}
classic_script_loader_ = WorkerClassicScriptLoader::Create();
- classic_script_loader_->LoadAsynchronously(
- *GetExecutionContext(), script_url_,
+ classic_script_loader_->LoadTopLevelScriptAsynchronously(
+ *GetExecutionContext(), script_request_url_,
WebURLRequest::kRequestContextWorker, fetch_request_mode,
fetch_credentials_mode,
GetExecutionContext()->GetSecurityContext().AddressSpace(),
@@ -168,8 +198,9 @@ void DedicatedWorker::Start() {
auto* outside_settings_object =
new FetchClientSettingsObjectSnapshot(*GetExecutionContext());
context_proxy_->StartWorkerGlobalScope(
- CreateGlobalScopeCreationParams(), options_, script_url_,
- outside_settings_object, stack_id, String() /* source_code */);
+ CreateGlobalScopeCreationParams(script_request_url_), options_,
+ script_request_url_, outside_settings_object, stack_id,
+ String() /* source_code */);
return;
}
NOTREACHED() << "Invalid type: " << options_.type();
@@ -217,6 +248,10 @@ bool DedicatedWorker::HasPendingActivity() const {
return context_proxy_->HasPendingActivity() || classic_script_loader_;
}
+const String DedicatedWorker::Name() const {
+ return options_.name();
+}
+
WorkerClients* DedicatedWorker::CreateWorkerClients() {
WorkerClients* worker_clients = WorkerClients::Create();
CoreInitializer::GetInstance().ProvideLocalFileSystemToWorker(
@@ -252,7 +287,7 @@ void DedicatedWorker::OnFinished(const v8_inspector::V8StackTraceId& stack_id) {
if (classic_script_loader_->Canceled()) {
// Do nothing.
} else if (classic_script_loader_->Failed()) {
- DispatchEvent(Event::CreateCancelable(EventTypeNames::error));
+ DispatchEvent(*Event::CreateCancelable(EventTypeNames::error));
} else {
ReferrerPolicy referrer_policy = kReferrerPolicyDefault;
if (!classic_script_loader_->GetReferrerPolicy().IsNull()) {
@@ -260,13 +295,17 @@ void DedicatedWorker::OnFinished(const v8_inspector::V8StackTraceId& stack_id) {
classic_script_loader_->GetReferrerPolicy(),
kDoNotSupportReferrerPolicyLegacyKeywords, &referrer_policy);
}
+ const KURL script_response_url = classic_script_loader_->ResponseURL();
+ DCHECK(script_request_url_ == script_response_url ||
+ SecurityOrigin::AreSameSchemeHostPort(script_request_url_,
+ script_response_url));
std::unique_ptr<GlobalScopeCreationParams> creation_params =
- CreateGlobalScopeCreationParams();
+ CreateGlobalScopeCreationParams(script_response_url);
creation_params->referrer_policy = referrer_policy;
auto* outside_settings_object =
new FetchClientSettingsObjectSnapshot(*GetExecutionContext());
context_proxy_->StartWorkerGlobalScope(
- std::move(creation_params), options_, script_url_,
+ std::move(creation_params), options_, script_response_url,
outside_settings_object, stack_id,
classic_script_loader_->SourceText());
probe::scriptImported(GetExecutionContext(),
@@ -277,7 +316,7 @@ void DedicatedWorker::OnFinished(const v8_inspector::V8StackTraceId& stack_id) {
}
std::unique_ptr<GlobalScopeCreationParams>
-DedicatedWorker::CreateGlobalScopeCreationParams() {
+DedicatedWorker::CreateGlobalScopeCreationParams(const KURL& script_url) {
base::UnguessableToken devtools_worker_token;
std::unique_ptr<WorkerSettings> settings;
if (GetExecutionContext()->IsDocument()) {
@@ -296,18 +335,20 @@ DedicatedWorker::CreateGlobalScopeCreationParams() {
ScriptType script_type = (options_.type() == "classic") ? ScriptType::kClassic
: ScriptType::kModule;
return std::make_unique<GlobalScopeCreationParams>(
- script_url_, script_type, GetExecutionContext()->UserAgent(),
+ script_url, script_type, GetExecutionContext()->UserAgent(),
GetExecutionContext()->GetContentSecurityPolicy()->Headers(),
kReferrerPolicyDefault, GetExecutionContext()->GetSecurityOrigin(),
- GetExecutionContext()->IsSecureContext(), CreateWorkerClients(),
+ GetExecutionContext()->IsSecureContext(),
+ GetExecutionContext()->GetHttpsState(), CreateWorkerClients(),
GetExecutionContext()->GetSecurityContext().AddressSpace(),
OriginTrialContext::GetTokens(GetExecutionContext()).get(),
devtools_worker_token, std::move(settings), kV8CacheOptionsDefault,
nullptr /* worklet_module_responses_map */,
ConnectToWorkerInterfaceProvider(GetExecutionContext(),
- SecurityOrigin::Create(script_url_)),
+ SecurityOrigin::Create(script_url)),
CreateBeginFrameProviderParams(),
- GetExecutionContext()->GetSecurityContext().GetFeaturePolicy());
+ GetExecutionContext()->GetSecurityContext().GetFeaturePolicy(),
+ GetExecutionContext()->GetAgentClusterID());
}
const AtomicString& DedicatedWorker::InterfaceName() const {
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 4e7dea55c4d..042df39af3d 100644
--- a/chromium/third_party/blink/renderer/core/workers/dedicated_worker.h
+++ b/chromium/third_party/blink/renderer/core/workers/dedicated_worker.h
@@ -27,6 +27,7 @@ namespace blink {
class DedicatedWorkerMessagingProxy;
class ExceptionState;
class ExecutionContext;
+class PostMessageOptions;
class ScriptState;
class WorkerClassicScriptLoader;
class WorkerClients;
@@ -55,10 +56,13 @@ class CORE_EXPORT DedicatedWorker final
~DedicatedWorker() override;
void postMessage(ScriptState*,
- scoped_refptr<SerializedScriptValue> message,
- const MessagePortArray&,
+ const ScriptValue& message,
+ Vector<ScriptValue>& transfer,
+ ExceptionState&);
+ void postMessage(ScriptState*,
+ const ScriptValue& message,
+ const PostMessageOptions&,
ExceptionState&);
- static bool CanTransferArrayBuffersAndImageBitmaps() { return true; }
void terminate();
BeginFrameProviderParams CreateBeginFrameProviderParams();
@@ -69,19 +73,23 @@ class CORE_EXPORT DedicatedWorker final
// (via AbstractWorker -> EventTargetWithInlineData -> EventTarget).
bool HasPendingActivity() const final;
+ // Returns the name specified by WorkerOptions.
+ const String Name() const;
+
DEFINE_ATTRIBUTE_EVENT_LISTENER(message);
void Trace(blink::Visitor*) override;
private:
DedicatedWorker(ExecutionContext*,
- const KURL& script_url,
+ const KURL& script_request_url,
const WorkerOptions&);
// Starts the worker.
void Start();
- std::unique_ptr<GlobalScopeCreationParams> CreateGlobalScopeCreationParams();
+ std::unique_ptr<GlobalScopeCreationParams> CreateGlobalScopeCreationParams(
+ const KURL& script_url);
WorkerClients* CreateWorkerClients();
@@ -92,7 +100,7 @@ class CORE_EXPORT DedicatedWorker final
// Implements EventTarget (via AbstractWorker -> EventTargetWithInlineData).
const AtomicString& InterfaceName() const final;
- const KURL script_url_;
+ const KURL script_request_url_;
const WorkerOptions options_;
const Member<DedicatedWorkerMessagingProxy> context_proxy_;
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 58166d3552e..ec38d83db01 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
@@ -31,11 +31,13 @@
#include "third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h"
#include <memory>
+#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/worker_or_worklet_script_controller.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/thread_debugger.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/script/fetch_client_settings_object_snapshot.h"
#include "third_party/blink/renderer/core/script/modulator.h"
@@ -50,10 +52,12 @@
namespace blink {
DedicatedWorkerGlobalScope::DedicatedWorkerGlobalScope(
+ const String& name,
std::unique_ptr<GlobalScopeCreationParams> creation_params,
DedicatedWorkerThread* thread,
base::TimeTicks time_origin)
- : WorkerGlobalScope(std::move(creation_params), thread, time_origin) {}
+ : WorkerGlobalScope(std::move(creation_params), thread, time_origin),
+ name_(name) {}
DedicatedWorkerGlobalScope::~DedicatedWorkerGlobalScope() = default;
@@ -82,21 +86,45 @@ void DedicatedWorkerGlobalScope::ImportModuleScript(
new WorkerModuleTreeClient(modulator));
}
-void DedicatedWorkerGlobalScope::postMessage(
- ScriptState* script_state,
- scoped_refptr<SerializedScriptValue> message,
- const MessagePortArray& ports,
- ExceptionState& exception_state) {
+const String DedicatedWorkerGlobalScope::name() const {
+ return name_;
+}
+
+void DedicatedWorkerGlobalScope::postMessage(ScriptState* script_state,
+ const ScriptValue& message,
+ Vector<ScriptValue>& transfer,
+ ExceptionState& exception_state) {
+ PostMessageOptions options;
+ if (!transfer.IsEmpty())
+ options.setTransfer(transfer);
+ postMessage(script_state, message, options, exception_state);
+}
+
+void DedicatedWorkerGlobalScope::postMessage(ScriptState* script_state,
+ const ScriptValue& message,
+ const PostMessageOptions& options,
+ ExceptionState& exception_state) {
+ Transferables transferables;
+ scoped_refptr<SerializedScriptValue> serialized_message =
+ PostMessageHelper::SerializeMessageByMove(script_state->GetIsolate(),
+ message, options, transferables,
+ exception_state);
+ if (exception_state.HadException())
+ return;
+ DCHECK(serialized_message);
+ BlinkTransferableMessage transferable_message;
+ transferable_message.message = serialized_message;
// Disentangle the port in preparation for sending it to the remote context.
- auto channels = MessagePort::DisentanglePorts(
- ExecutionContext::From(script_state), ports, exception_state);
+ transferable_message.ports = MessagePort::DisentanglePorts(
+ ExecutionContext::From(script_state), transferables.message_ports,
+ exception_state);
if (exception_state.HadException())
return;
ThreadDebugger* debugger = ThreadDebugger::From(script_state->GetIsolate());
- v8_inspector::V8StackTraceId stack_id =
+ transferable_message.sender_stack_trace_id =
debugger->StoreCurrentStackTrace("postMessage");
- WorkerObjectProxy().PostMessageToWorkerObject(std::move(message),
- std::move(channels), stack_id);
+ WorkerObjectProxy().PostMessageToWorkerObject(
+ std::move(transferable_message));
}
DedicatedWorkerObjectProxy& DedicatedWorkerGlobalScope::WorkerObjectProxy()
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 645565126ed..02be7b949de 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
@@ -41,6 +41,7 @@ namespace blink {
class DedicatedWorkerObjectProxy;
class DedicatedWorkerThread;
+class PostMessageOptions;
class ScriptState;
struct GlobalScopeCreationParams;
@@ -48,7 +49,8 @@ class CORE_EXPORT DedicatedWorkerGlobalScope final : public WorkerGlobalScope {
DEFINE_WRAPPERTYPEINFO();
public:
- DedicatedWorkerGlobalScope(std::unique_ptr<GlobalScopeCreationParams>,
+ DedicatedWorkerGlobalScope(const String& name,
+ std::unique_ptr<GlobalScopeCreationParams>,
DedicatedWorkerThread*,
base::TimeTicks time_origin);
~DedicatedWorkerGlobalScope() override;
@@ -64,12 +66,16 @@ class CORE_EXPORT DedicatedWorkerGlobalScope final : public WorkerGlobalScope {
FetchClientSettingsObjectSnapshot* outside_settings_object,
network::mojom::FetchCredentialsMode) override;
+ const String name() const;
+
void postMessage(ScriptState*,
- scoped_refptr<SerializedScriptValue>,
- const MessagePortArray&,
+ const ScriptValue& message,
+ Vector<ScriptValue>& transfer,
+ ExceptionState&);
+ void postMessage(ScriptState*,
+ const ScriptValue& message,
+ const PostMessageOptions&,
ExceptionState&);
-
- static bool CanTransferArrayBuffersAndImageBitmaps() { return true; }
DEFINE_ATTRIBUTE_EVENT_LISTENER(message);
DEFINE_ATTRIBUTE_EVENT_LISTENER(messageerror);
@@ -77,6 +83,9 @@ class CORE_EXPORT DedicatedWorkerGlobalScope final : public WorkerGlobalScope {
void Trace(blink::Visitor*) override;
DedicatedWorkerObjectProxy& WorkerObjectProxy() const;
+
+ private:
+ const String name_;
};
DEFINE_TYPE_CASTS(DedicatedWorkerGlobalScope,
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 3e9922e6154..3e8c7eb18de 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
@@ -34,7 +34,10 @@
Global=(Worker,DedicatedWorker),
Exposed=DedicatedWorker
] interface DedicatedWorkerGlobalScope : WorkerGlobalScope {
- [PostMessage, RaisesException] void postMessage(any message, optional sequence<object> transfer = []);
+ [Replaceable] readonly attribute DOMString name;
+
+ [CallWith=ScriptState, RaisesException] void postMessage(any message, optional sequence<object> transfer = []);
+ [RuntimeEnabled=PostMessageOptions, CallWith=ScriptState, RaisesException] void postMessage(any message, 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 4e5a9048649..c3b6dbf8599 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
@@ -14,6 +14,7 @@
#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/inspector/thread_debugger.h"
+#include "third_party/blink/renderer/core/messaging/blink_transferable_message.h"
#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"
@@ -25,12 +26,6 @@
namespace blink {
-struct DedicatedWorkerMessagingProxy::QueuedTask {
- scoped_refptr<SerializedScriptValue> message;
- Vector<MessagePortChannel> channels;
- v8_inspector::V8StackTraceId stack_id;
-};
-
DedicatedWorkerMessagingProxy::DedicatedWorkerMessagingProxy(
ExecutionContext* execution_context,
DedicatedWorker* worker_object)
@@ -76,24 +71,21 @@ void DedicatedWorkerMessagingProxy::StartWorkerGlobalScope(
}
void DedicatedWorkerMessagingProxy::PostMessageToWorkerGlobalScope(
- scoped_refptr<SerializedScriptValue> message,
- Vector<MessagePortChannel> channels,
- const v8_inspector::V8StackTraceId& stack_id) {
+ BlinkTransferableMessage message) {
DCHECK(IsParentContextThread());
if (AskedToTerminate())
return;
if (!was_script_evaluated_) {
- queued_early_tasks_.push_back(
- QueuedTask{std::move(message), std::move(channels), stack_id});
+ queued_early_tasks_.push_back(std::move(message));
return;
}
PostCrossThreadTask(
*GetWorkerThread()->GetTaskRunner(TaskType::kPostedMessage), FROM_HERE,
CrossThreadBind(
&DedicatedWorkerObjectProxy::ProcessMessageFromWorkerObject,
- CrossThreadUnretained(&WorkerObjectProxy()), std::move(message),
- WTF::Passed(std::move(channels)),
- CrossThreadUnretained(GetWorkerThread()), stack_id));
+ CrossThreadUnretained(&WorkerObjectProxy()),
+ WTF::Passed(std::move(message)),
+ CrossThreadUnretained(GetWorkerThread())));
}
bool DedicatedWorkerMessagingProxy::HasPendingActivity() const {
@@ -105,7 +97,7 @@ void DedicatedWorkerMessagingProxy::DidEvaluateScript(bool success) {
DCHECK(IsParentContextThread());
was_script_evaluated_ = true;
- Vector<QueuedTask> tasks;
+ Vector<BlinkTransferableMessage> tasks;
queued_early_tasks_.swap(tasks);
// The worker thread can already be terminated.
@@ -123,28 +115,25 @@ void DedicatedWorkerMessagingProxy::DidEvaluateScript(bool success) {
CrossThreadBind(
&DedicatedWorkerObjectProxy::ProcessMessageFromWorkerObject,
CrossThreadUnretained(&WorkerObjectProxy()),
- WTF::Passed(std::move(task.message)),
- WTF::Passed(std::move(task.channels)),
- CrossThreadUnretained(GetWorkerThread()), task.stack_id));
+ WTF::Passed(std::move(task)),
+ CrossThreadUnretained(GetWorkerThread())));
}
}
void DedicatedWorkerMessagingProxy::PostMessageToWorkerObject(
- scoped_refptr<SerializedScriptValue> message,
- Vector<MessagePortChannel> channels,
- const v8_inspector::V8StackTraceId& stack_id) {
+ BlinkTransferableMessage message) {
DCHECK(IsParentContextThread());
if (!worker_object_ || AskedToTerminate())
return;
ThreadDebugger* debugger =
ThreadDebugger::From(ToIsolate(GetExecutionContext()));
- MessagePortArray* ports =
- MessagePort::EntanglePorts(*GetExecutionContext(), std::move(channels));
- debugger->ExternalAsyncTaskStarted(stack_id);
+ MessagePortArray* ports = MessagePort::EntanglePorts(
+ *GetExecutionContext(), std::move(message.ports));
+ debugger->ExternalAsyncTaskStarted(message.sender_stack_trace_id);
worker_object_->DispatchEvent(
- MessageEvent::Create(ports, std::move(message)));
- debugger->ExternalAsyncTaskFinished(stack_id);
+ *MessageEvent::Create(ports, std::move(message.message)));
+ debugger->ExternalAsyncTaskFinished(message.sender_stack_trace_id);
}
void DedicatedWorkerMessagingProxy::DispatchErrorEvent(
@@ -165,7 +154,8 @@ void DedicatedWorkerMessagingProxy::DispatchErrorEvent(
// https://html.spec.whatwg.org/multipage/workers.html#runtime-script-errors-2
ErrorEvent* event =
ErrorEvent::Create(error_message, location->Clone(), nullptr);
- if (worker_object_->DispatchEvent(event) != DispatchEventResult::kNotCanceled)
+ if (worker_object_->DispatchEvent(*event) !=
+ DispatchEventResult::kNotCanceled)
return;
// The worker thread can already be terminated.
@@ -203,8 +193,8 @@ DedicatedWorkerMessagingProxy::CreateBackingThreadStartupData(
std::unique_ptr<WorkerThread>
DedicatedWorkerMessagingProxy::CreateWorkerThread() {
- return DedicatedWorkerThread::Create(CreateThreadableLoadingContext(),
- WorkerObjectProxy());
+ return DedicatedWorkerThread::Create(
+ worker_object_->Name(), GetExecutionContext(), WorkerObjectProxy());
}
} // namespace blink
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 7fcb3fd5eeb..12fbe5e99b6 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
@@ -9,6 +9,7 @@
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "base/optional.h"
+#include "third_party/blink/public/mojom/message_port/message_port.mojom-blink.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/messaging/message_port.h"
#include "third_party/blink/renderer/core/workers/global_scope_creation_params.h"
@@ -17,16 +18,11 @@
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/weborigin/referrer_policy.h"
-namespace v8_inspector {
-struct V8StackTraceId;
-}
-
namespace blink {
class DedicatedWorker;
class DedicatedWorkerObjectProxy;
class FetchClientSettingsObjectSnapshot;
-class SerializedScriptValue;
class WorkerOptions;
// A proxy class to talk to the DedicatedWorkerGlobalScope on a worker thread
@@ -46,18 +42,14 @@ class CORE_EXPORT DedicatedWorkerMessagingProxy
FetchClientSettingsObjectSnapshot* outside_settings_object,
const v8_inspector::V8StackTraceId&,
const String& source_code);
- void PostMessageToWorkerGlobalScope(scoped_refptr<SerializedScriptValue>,
- Vector<MessagePortChannel>,
- const v8_inspector::V8StackTraceId&);
+ void PostMessageToWorkerGlobalScope(BlinkTransferableMessage);
bool HasPendingActivity() const;
// These methods come from worker context thread via
// DedicatedWorkerObjectProxy and are called on the parent context thread.
void DidEvaluateScript(bool success);
- void PostMessageToWorkerObject(scoped_refptr<SerializedScriptValue>,
- Vector<MessagePortChannel>,
- const v8_inspector::V8StackTraceId&);
+ void PostMessageToWorkerObject(BlinkTransferableMessage);
void DispatchErrorEvent(const String& error_message,
std::unique_ptr<SourceLocation>,
int exception_id);
@@ -92,8 +84,7 @@ class CORE_EXPORT DedicatedWorkerMessagingProxy
// Tasks are queued here until worker scripts are evaluated on the worker
// global scope.
- struct QueuedTask;
- Vector<QueuedTask> queued_early_tasks_;
+ Vector<BlinkTransferableMessage> queued_early_tasks_;
DISALLOW_COPY_AND_ASSIGN(DedicatedWorkerMessagingProxy);
};
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 ec1d5b186f2..ef290620f8a 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
@@ -41,6 +41,7 @@
#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"
+#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/inspector/thread_debugger.h"
#include "third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.h"
@@ -64,31 +65,34 @@ std::unique_ptr<DedicatedWorkerObjectProxy> DedicatedWorkerObjectProxy::Create(
DedicatedWorkerObjectProxy::~DedicatedWorkerObjectProxy() = default;
void DedicatedWorkerObjectProxy::PostMessageToWorkerObject(
- scoped_refptr<SerializedScriptValue> message,
- Vector<MessagePortChannel> channels,
- const v8_inspector::V8StackTraceId& stack_id) {
+ BlinkTransferableMessage message) {
PostCrossThreadTask(
*GetParentExecutionContextTaskRunners()->Get(TaskType::kPostedMessage),
FROM_HERE,
CrossThreadBind(&DedicatedWorkerMessagingProxy::PostMessageToWorkerObject,
- messaging_proxy_weak_ptr_, std::move(message),
- WTF::Passed(std::move(channels)), stack_id));
+ messaging_proxy_weak_ptr_,
+ WTF::Passed(std::move(message))));
}
void DedicatedWorkerObjectProxy::ProcessMessageFromWorkerObject(
- scoped_refptr<SerializedScriptValue> message,
- Vector<MessagePortChannel> channels,
- WorkerThread* worker_thread,
- const v8_inspector::V8StackTraceId& stack_id) {
+ BlinkTransferableMessage message,
+ WorkerThread* worker_thread) {
WorkerGlobalScope* global_scope =
ToWorkerGlobalScope(worker_thread->GlobalScope());
MessagePortArray* ports =
- MessagePort::EntanglePorts(*global_scope, std::move(channels));
+ MessagePort::EntanglePorts(*global_scope, std::move(message.ports));
ThreadDebugger* debugger = ThreadDebugger::From(worker_thread->GetIsolate());
- debugger->ExternalAsyncTaskStarted(stack_id);
- global_scope->DispatchEvent(MessageEvent::Create(ports, std::move(message)));
- debugger->ExternalAsyncTaskFinished(stack_id);
+ debugger->ExternalAsyncTaskStarted(message.sender_stack_trace_id);
+ UserActivation* user_activation = nullptr;
+ if (message.user_activation) {
+ user_activation =
+ new UserActivation(message.user_activation->has_been_active,
+ message.user_activation->was_active);
+ }
+ global_scope->DispatchEvent(*MessageEvent::Create(
+ ports, std::move(message.message), user_activation));
+ debugger->ExternalAsyncTaskFinished(message.sender_stack_trace_id);
}
void DedicatedWorkerObjectProxy::ProcessUnhandledException(
@@ -111,12 +115,6 @@ void DedicatedWorkerObjectProxy::ReportException(
WTF::Passed(location->Clone()), exception_id));
}
-void DedicatedWorkerObjectProxy::DidCreateWorkerGlobalScope(
- WorkerOrWorkletGlobalScope* global_scope) {
- DCHECK(!worker_global_scope_);
- worker_global_scope_ = ToWorkerGlobalScope(global_scope);
-}
-
void DedicatedWorkerObjectProxy::DidEvaluateClassicScript(bool success) {
PostCrossThreadTask(
*GetParentExecutionContextTaskRunners()->Get(TaskType::kInternalDefault),
@@ -133,10 +131,6 @@ void DedicatedWorkerObjectProxy::DidEvaluateModuleScript(bool success) {
messaging_proxy_weak_ptr_, success));
}
-void DedicatedWorkerObjectProxy::WillDestroyWorkerGlobalScope() {
- worker_global_scope_ = nullptr;
-}
-
DedicatedWorkerObjectProxy::DedicatedWorkerObjectProxy(
DedicatedWorkerMessagingProxy* messaging_proxy_weak_ptr,
ParentExecutionContextTaskRunners* parent_execution_context_task_runners)
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 5c7d55ba1fd..3d78c12a8a1 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,22 +35,17 @@
#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"
#include "third_party/blink/renderer/platform/heap/handle.h"
-namespace v8_inspector {
-struct V8StackTraceId;
-} // namespace v8_inspector
-
namespace blink {
class DedicatedWorkerMessagingProxy;
class ParentExecutionContextTaskRunners;
class ThreadedMessagingProxyBase;
-class WorkerGlobalScope;
-class WorkerOrWorkletGlobalScope;
class WorkerThread;
// A proxy class to talk to a DedicatedWorker object on the main thread via the
@@ -65,23 +60,16 @@ class CORE_EXPORT DedicatedWorkerObjectProxy : public ThreadedObjectProxyBase {
ParentExecutionContextTaskRunners*);
~DedicatedWorkerObjectProxy() override;
- void PostMessageToWorkerObject(scoped_refptr<SerializedScriptValue>,
- Vector<MessagePortChannel>,
- const v8_inspector::V8StackTraceId&);
+ void PostMessageToWorkerObject(BlinkTransferableMessage);
void ProcessUnhandledException(int exception_id, WorkerThread*);
- void ProcessMessageFromWorkerObject(scoped_refptr<SerializedScriptValue>,
- Vector<MessagePortChannel>,
- WorkerThread*,
- const v8_inspector::V8StackTraceId&);
+ void ProcessMessageFromWorkerObject(BlinkTransferableMessage, WorkerThread*);
// ThreadedObjectProxyBase overrides.
void ReportException(const String& error_message,
std::unique_ptr<SourceLocation>,
int exception_id) override;
- void DidCreateWorkerGlobalScope(WorkerOrWorkletGlobalScope*) override;
void DidEvaluateClassicScript(bool success) override;
void DidEvaluateModuleScript(bool success) override;
- void WillDestroyWorkerGlobalScope() override;
protected:
DedicatedWorkerObjectProxy(DedicatedWorkerMessagingProxy*,
@@ -99,7 +87,6 @@ class CORE_EXPORT DedicatedWorkerObjectProxy : public ThreadedObjectProxyBase {
CrossThreadWeakPersistent<DedicatedWorkerMessagingProxy>
messaging_proxy_weak_ptr_;
- CrossThreadPersistent<WorkerGlobalScope> worker_global_scope_;
DISALLOW_COPY_AND_ASSIGN(DedicatedWorkerObjectProxy);
};
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 424710beba0..72c5f55c221 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
@@ -30,7 +30,8 @@ namespace blink {
class DedicatedWorkerThreadForTest final : public DedicatedWorkerThread {
public:
DedicatedWorkerThreadForTest(DedicatedWorkerObjectProxy& worker_object_proxy)
- : DedicatedWorkerThread(nullptr /* ThreadableLoadingContext */,
+ : DedicatedWorkerThread("fake worker name",
+ nullptr /* parent_execution_context*/,
worker_object_proxy) {
worker_backing_thread_ = WorkerBackingThread::Create(
WebThreadCreationParams(WebThreadType::kTestThread));
@@ -39,7 +40,7 @@ class DedicatedWorkerThreadForTest final : public DedicatedWorkerThread {
WorkerOrWorkletGlobalScope* CreateWorkerGlobalScope(
std::unique_ptr<GlobalScopeCreationParams> creation_params) override {
auto* global_scope = new DedicatedWorkerGlobalScope(
- std::move(creation_params), this, time_origin_);
+ "fake worker name", std::move(creation_params), this, time_origin_);
// Initializing a global scope with a dummy creation params may emit warning
// messages (e.g., invalid CSP directives). Clear them here for tests that
// check console messages (i.e., UseCounter tests).
@@ -133,10 +134,12 @@ class DedicatedWorkerMessagingProxyForTest
std::make_unique<GlobalScopeCreationParams>(
script_url, ScriptType::kClassic, "fake user agent", headers,
kReferrerPolicyDefault, security_origin_.get(),
- false /* starter_secure_context */, nullptr /* worker_clients */,
- mojom::IPAddressSpace::kLocal, nullptr /* origin_trial_tokens */,
- base::UnguessableToken::Create(), std::move(worker_settings),
- kV8CacheOptionsDefault, nullptr /* worklet_module_responses_map */),
+ false /* starter_secure_context */,
+ CalculateHttpsState(security_origin_.get()),
+ nullptr /* worker_clients */, mojom::IPAddressSpace::kLocal,
+ nullptr /* origin_trial_tokens */, base::UnguessableToken::Create(),
+ std::move(worker_settings), kV8CacheOptionsDefault,
+ nullptr /* worklet_module_responses_map */),
WorkerBackingThreadStartupData(
WorkerBackingThreadStartupData::HeapLimitMode::kDefault,
WorkerBackingThreadStartupData::AtomicsWaitMode::kAllow));
@@ -150,25 +153,14 @@ class DedicatedWorkerMessagingProxyForTest
}
void Trace(blink::Visitor* visitor) override {
- visitor->Trace(mock_worker_thread_lifecycle_observer_);
DedicatedWorkerMessagingProxy::Trace(visitor);
}
private:
std::unique_ptr<WorkerThread> CreateWorkerThread() override {
- auto worker_thread =
- std::make_unique<DedicatedWorkerThreadForTest>(WorkerObjectProxy());
- mock_worker_thread_lifecycle_observer_ =
- new MockWorkerThreadLifecycleObserver(
- worker_thread->GetWorkerThreadLifecycleContext());
- EXPECT_CALL(*mock_worker_thread_lifecycle_observer_,
- ContextDestroyed(testing::_))
- .Times(1);
- return std::move(worker_thread);
+ return std::make_unique<DedicatedWorkerThreadForTest>(WorkerObjectProxy());
}
- Member<MockWorkerThreadLifecycleObserver>
- mock_worker_thread_lifecycle_observer_;
scoped_refptr<const SecurityOrigin> security_origin_;
};
@@ -188,9 +180,8 @@ class DedicatedWorkerTest : public PageTestBase {
}
void DispatchMessageEvent() {
- WorkerMessagingProxy()->PostMessageToWorkerGlobalScope(
- nullptr /* message */, Vector<MessagePortChannel>(),
- v8_inspector::V8StackTraceId());
+ BlinkTransferableMessage message;
+ WorkerMessagingProxy()->PostMessageToWorkerGlobalScope(std::move(message));
}
DedicatedWorkerMessagingProxyForTest* WorkerMessagingProxy() {
diff --git a/chromium/third_party/blink/renderer/core/workers/dedicated_worker_thread.cc b/chromium/third_party/blink/renderer/core/workers/dedicated_worker_thread.cc
index 595cb4f3085..b081cbf0a75 100644
--- a/chromium/third_party/blink/renderer/core/workers/dedicated_worker_thread.cc
+++ b/chromium/third_party/blink/renderer/core/workers/dedicated_worker_thread.cc
@@ -45,34 +45,28 @@
namespace blink {
-namespace {
-
-FrameOrWorkerScheduler* GetFrameOrWorkerScheduler(
- ThreadableLoadingContext* loading_context) {
- // |loading_context| can be null in unittests.
- if (!loading_context)
- return nullptr;
- return loading_context->GetExecutionContext()->GetScheduler();
-}
-
-} // namespace
-
std::unique_ptr<DedicatedWorkerThread> DedicatedWorkerThread::Create(
- ThreadableLoadingContext* loading_context,
+ const String& name,
+ ExecutionContext* parent_execution_context,
DedicatedWorkerObjectProxy& worker_object_proxy) {
- return base::WrapUnique(
- new DedicatedWorkerThread(loading_context, worker_object_proxy));
+ return base::WrapUnique(new DedicatedWorkerThread(
+ name, parent_execution_context, worker_object_proxy));
}
DedicatedWorkerThread::DedicatedWorkerThread(
- ThreadableLoadingContext* loading_context,
+ const String& name,
+ ExecutionContext* parent_execution_context,
DedicatedWorkerObjectProxy& worker_object_proxy)
- : WorkerThread(loading_context, worker_object_proxy),
- worker_backing_thread_(WorkerBackingThread::Create(
- WebThreadCreationParams(GetThreadType())
- .SetFrameOrWorkerScheduler(
- GetFrameOrWorkerScheduler(loading_context)))),
- worker_object_proxy_(worker_object_proxy) {}
+ : WorkerThread(worker_object_proxy),
+ name_(name.IsolatedCopy()),
+ worker_object_proxy_(worker_object_proxy) {
+ FrameOrWorkerScheduler* scheduler =
+ parent_execution_context ? parent_execution_context->GetScheduler()
+ : nullptr;
+ worker_backing_thread_ =
+ WorkerBackingThread::Create(WebThreadCreationParams(GetThreadType())
+ .SetFrameOrWorkerScheduler(scheduler));
+}
DedicatedWorkerThread::~DedicatedWorkerThread() = default;
@@ -82,7 +76,7 @@ void DedicatedWorkerThread::ClearWorkerBackingThread() {
WorkerOrWorkletGlobalScope* DedicatedWorkerThread::CreateWorkerGlobalScope(
std::unique_ptr<GlobalScopeCreationParams> creation_params) {
- return new DedicatedWorkerGlobalScope(std::move(creation_params), this,
+ return new DedicatedWorkerGlobalScope(name_, std::move(creation_params), this,
time_origin_);
}
diff --git a/chromium/third_party/blink/renderer/core/workers/dedicated_worker_thread.h b/chromium/third_party/blink/renderer/core/workers/dedicated_worker_thread.h
index 784aebc14d0..01466db33d7 100644
--- a/chromium/third_party/blink/renderer/core/workers/dedicated_worker_thread.h
+++ b/chromium/third_party/blink/renderer/core/workers/dedicated_worker_thread.h
@@ -41,7 +41,8 @@ struct GlobalScopeCreationParams;
class CORE_EXPORT DedicatedWorkerThread : public WorkerThread {
public:
static std::unique_ptr<DedicatedWorkerThread> Create(
- ThreadableLoadingContext*,
+ const String& name,
+ ExecutionContext* parent_execution_context,
DedicatedWorkerObjectProxy&);
~DedicatedWorkerThread() override;
@@ -56,7 +57,9 @@ class CORE_EXPORT DedicatedWorkerThread : public WorkerThread {
private:
friend class DedicatedWorkerThreadForTest;
- DedicatedWorkerThread(ThreadableLoadingContext*, DedicatedWorkerObjectProxy&);
+ DedicatedWorkerThread(const String& name,
+ ExecutionContext* parent_execution_context,
+ DedicatedWorkerObjectProxy&);
WorkerOrWorkletGlobalScope* CreateWorkerGlobalScope(
std::unique_ptr<GlobalScopeCreationParams>) override;
@@ -65,6 +68,7 @@ class CORE_EXPORT DedicatedWorkerThread : public WorkerThread {
}
std::unique_ptr<WorkerBackingThread> worker_backing_thread_;
+ const String name_;
DedicatedWorkerObjectProxy& worker_object_proxy_;
};
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 e95d125e0db..ea64dec36c7 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
@@ -17,6 +17,7 @@ GlobalScopeCreationParams::GlobalScopeCreationParams(
ReferrerPolicy referrer_policy,
const SecurityOrigin* starter_origin,
bool starter_secure_context,
+ HttpsState starter_https_state,
WorkerClients* worker_clients,
mojom::IPAddressSpace address_space,
const Vector<String>* origin_trial_tokens,
@@ -27,13 +28,15 @@ GlobalScopeCreationParams::GlobalScopeCreationParams(
service_manager::mojom::blink::InterfaceProviderPtrInfo
interface_provider_info,
BeginFrameProviderParams begin_frame_provider_params,
- const FeaturePolicy* parent_feature_policy)
+ const FeaturePolicy* parent_feature_policy,
+ base::UnguessableToken agent_cluster_id)
: script_url(script_url.Copy()),
script_type(script_type),
user_agent(user_agent.IsolatedCopy()),
referrer_policy(referrer_policy),
starter_origin(starter_origin ? starter_origin->IsolatedCopy() : nullptr),
starter_secure_context(starter_secure_context),
+ starter_https_state(starter_https_state),
worker_clients(worker_clients),
address_space(address_space),
parent_devtools_token(parent_devtools_token),
@@ -47,7 +50,8 @@ GlobalScopeCreationParams::GlobalScopeCreationParams(
worker_feature_policy(FeaturePolicy::CreateFromParentPolicy(
parent_feature_policy,
ParsedFeaturePolicy() /* container_policy */,
- starter_origin->ToUrlOrigin())) {
+ starter_origin->ToUrlOrigin())),
+ agent_cluster_id(agent_cluster_id) {
this->content_security_policy_parsed_headers.ReserveInitialCapacity(
content_security_policy_parsed_headers.size());
for (const auto& header : content_security_policy_parsed_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 8a1c3c8bec9..f96f537e64a 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
@@ -20,6 +20,7 @@
#include "third_party/blink/renderer/core/workers/worker_settings.h"
#include "third_party/blink/renderer/core/workers/worklet_module_responses_map.h"
#include "third_party/blink/renderer/platform/graphics/begin_frame_provider.h"
+#include "third_party/blink/renderer/platform/loader/fetch/https_state.h"
#include "third_party/blink/renderer/platform/network/content_security_policy_parsers.h"
#include "third_party/blink/renderer/platform/network/content_security_policy_response_headers.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
@@ -44,6 +45,7 @@ struct CORE_EXPORT GlobalScopeCreationParams final {
ReferrerPolicy referrer_policy,
const SecurityOrigin*,
bool starter_secure_context,
+ HttpsState starter_https_state,
WorkerClients*,
mojom::IPAddressSpace,
const Vector<String>* origin_trial_tokens,
@@ -53,11 +55,25 @@ struct CORE_EXPORT GlobalScopeCreationParams final {
WorkletModuleResponsesMap*,
service_manager::mojom::blink::InterfaceProviderPtrInfo = {},
BeginFrameProviderParams begin_frame_provider_params = {},
- const FeaturePolicy* parent_feature_policy = nullptr);
+ const FeaturePolicy* parent_feature_policy = nullptr,
+ base::UnguessableToken agent_cluster_id = {});
~GlobalScopeCreationParams() = default;
+ // The URL to be used as the worker global scope's URL.
+ // According to the spec, this should be response URL of the top-level
+ // worker script after the top-level worker script is loaded.
+ // https://html.spec.whatwg.org/multipage/workers.html#run-a-worker
+ //
+ // However, this can't be set to response URL in case of module workers or
+ // off-the-main-thread fetch, because at the time of GlobalScopeCreationParams
+ // creation the response of worker script is not yet received. Therefore,
+ // the worker global scope's URL should be set to the response URL outside
+ // GlobalScopeCreationParams, but this mechanism is not yet implemented.
+ // TODO(crbug/861564): implement this and set the response URL to module
+ // workers.
KURL script_url;
+
ScriptType script_type;
String user_agent;
@@ -95,6 +111,8 @@ struct CORE_EXPORT GlobalScopeCreationParams final {
// The value should be supplied as the result of Document.IsSecureContext().
bool starter_secure_context;
+ HttpsState starter_https_state;
+
// This object is created and initialized on the thread creating
// a new worker context, but ownership of it and this
// GlobalScopeCreationParams structure is passed along to the new worker
@@ -122,6 +140,11 @@ struct CORE_EXPORT GlobalScopeCreationParams final {
std::unique_ptr<FeaturePolicy> worker_feature_policy;
+ // Set when the worker/worklet has the same AgentClusterID as the execution
+ // context that created it (e.g. for a dedicated worker).
+ // See https://tc39.github.io/ecma262/#sec-agent-clusters
+ base::UnguessableToken agent_cluster_id;
+
DISALLOW_COPY_AND_ASSIGN(GlobalScopeCreationParams);
};
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 12ede974d2e..fef14c2896f 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
@@ -67,8 +67,9 @@ class MainThreadWorkletTest : public PageTestBase {
document->Url(), ScriptType::kModule, document->UserAgent(),
document->GetContentSecurityPolicy()->Headers(),
document->GetReferrerPolicy(), document->GetSecurityOrigin(),
- document->IsSecureContext(), nullptr /* worker_clients */,
- document->AddressSpace(), OriginTrialContext::GetTokens(document).get(),
+ document->IsSecureContext(), document->GetHttpsState(),
+ nullptr /* worker_clients */, document->AddressSpace(),
+ OriginTrialContext::GetTokens(document).get(),
base::UnguessableToken::Create(), nullptr /* worker_settings */,
kV8CacheOptionsDefault, new WorkletModuleResponsesMap);
global_scope_ = new MainThreadWorkletGlobalScope(
diff --git a/chromium/third_party/blink/renderer/core/workers/shared_worker_thread.cc b/chromium/third_party/blink/renderer/core/workers/shared_worker_thread.cc
index c881ea5b0eb..f11d6d2ba5f 100644
--- a/chromium/third_party/blink/renderer/core/workers/shared_worker_thread.cc
+++ b/chromium/third_party/blink/renderer/core/workers/shared_worker_thread.cc
@@ -39,9 +39,8 @@ namespace blink {
SharedWorkerThread::SharedWorkerThread(
const String& name,
- ThreadableLoadingContext* loading_context,
WorkerReportingProxy& worker_reporting_proxy)
- : WorkerThread(loading_context, worker_reporting_proxy),
+ : WorkerThread(worker_reporting_proxy),
worker_backing_thread_(WorkerBackingThread::Create(
WebThreadCreationParams(GetThreadType()))),
name_(name.IsolatedCopy()) {}
diff --git a/chromium/third_party/blink/renderer/core/workers/shared_worker_thread.h b/chromium/third_party/blink/renderer/core/workers/shared_worker_thread.h
index b080b178698..654c37d6101 100644
--- a/chromium/third_party/blink/renderer/core/workers/shared_worker_thread.h
+++ b/chromium/third_party/blink/renderer/core/workers/shared_worker_thread.h
@@ -42,7 +42,6 @@ struct GlobalScopeCreationParams;
class CORE_EXPORT SharedWorkerThread : public WorkerThread {
public:
SharedWorkerThread(const String& name,
- ThreadableLoadingContext*,
WorkerReportingProxy&);
~SharedWorkerThread() override;
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 f77c4affa4d..4dc16a548ea 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
@@ -13,7 +13,6 @@
#include "third_party/blink/renderer/core/frame/deprecation.h"
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
#include "third_party/blink/renderer/core/loader/document_loader.h"
-#include "third_party/blink/renderer/core/loader/threadable_loading_context.h"
#include "third_party/blink/renderer/core/loader/worker_fetch_context.h"
#include "third_party/blink/renderer/core/workers/global_scope_creation_params.h"
#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
@@ -186,12 +185,6 @@ void ThreadedMessagingProxyBase::PostMessageToPageInspector(
worker_inspector_proxy_->DispatchMessageFromWorker(session_id, message);
}
-ThreadableLoadingContext*
-ThreadedMessagingProxyBase::CreateThreadableLoadingContext() const {
- DCHECK(IsParentContextThread());
- return ThreadableLoadingContext::Create(*execution_context_);
-}
-
ExecutionContext* ThreadedMessagingProxyBase::GetExecutionContext() const {
DCHECK(IsParentContextThread());
return execution_context_;
diff --git a/chromium/third_party/blink/renderer/core/workers/threaded_messaging_proxy_base.h b/chromium/third_party/blink/renderer/core/workers/threaded_messaging_proxy_base.h
index d53cf9d7067..fa6c682bd40 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
@@ -25,7 +25,6 @@ namespace blink {
class ExecutionContext;
class SourceLocation;
-class ThreadableLoadingContext;
class WorkerInspectorProxy;
struct GlobalScopeCreationParams;
@@ -77,8 +76,6 @@ class CORE_EXPORT ThreadedMessagingProxyBase
std::unique_ptr<GlobalScopeCreationParams>,
const base::Optional<WorkerBackingThreadStartupData>&);
- ThreadableLoadingContext* CreateThreadableLoadingContext() const;
-
ExecutionContext* GetExecutionContext() const;
ParentExecutionContextTaskRunners* GetParentExecutionContextTaskRunners()
const;
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 260f497dba5..7378f9824dc 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
@@ -59,11 +59,14 @@ void ThreadedWorkletMessagingProxy::Initialize(
document->Url(), ScriptType::kModule, document->UserAgent(),
csp->Headers(), document->GetReferrerPolicy(),
document->GetSecurityOrigin(), document->IsSecureContext(),
- worker_clients, document->AddressSpace(),
+ document->GetHttpsState(), worker_clients, document->AddressSpace(),
OriginTrialContext::GetTokens(document).get(),
base::UnguessableToken::Create(),
std::make_unique<WorkerSettings>(document->GetSettings()),
- kV8CacheOptionsDefault, module_responses_map);
+ kV8CacheOptionsDefault, module_responses_map,
+ service_manager::mojom::blink::InterfaceProviderPtrInfo(),
+ BeginFrameProviderParams(), nullptr /* parent_feature_policy */,
+ document->GetAgentClusterID());
// Worklets share the pre-initialized backing thread so that we don't have to
// specify the backing thread startup data.
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 28a13f09d22..d80755fb622 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
@@ -58,7 +58,7 @@ class ThreadedWorkletThreadForTest : public WorkerThread {
public:
explicit ThreadedWorkletThreadForTest(
WorkerReportingProxy& worker_reporting_proxy)
- : WorkerThread(nullptr, worker_reporting_proxy) {}
+ : WorkerThread(worker_reporting_proxy) {}
~ThreadedWorkletThreadForTest() override = default;
WorkerBackingThread& GetWorkerBackingThread() override {
@@ -203,8 +203,8 @@ class ThreadedWorkletMessagingProxyForTest
document->Url(), ScriptType::kModule, document->UserAgent(),
document->GetContentSecurityPolicy()->Headers(),
document->GetReferrerPolicy(), document->GetSecurityOrigin(),
- document->IsSecureContext(), worker_clients,
- document->AddressSpace(),
+ document->IsSecureContext(), document->GetHttpsState(),
+ worker_clients, document->AddressSpace(),
OriginTrialContext::GetTokens(document).get(),
base::UnguessableToken::Create(), std::move(worker_settings),
kV8CacheOptionsDefault, new WorkletModuleResponsesMap),
diff --git a/chromium/third_party/blink/renderer/core/workers/worker.idl b/chromium/third_party/blink/renderer/core/workers/worker.idl
index 7cd1f5cd43c..463f2518a88 100644
--- a/chromium/third_party/blink/renderer/core/workers/worker.idl
+++ b/chromium/third_party/blink/renderer/core/workers/worker.idl
@@ -37,7 +37,8 @@
] interface Worker : EventTarget {
void terminate();
- [PostMessage, RaisesException] void postMessage(any message, optional sequence<object> transfer);
+ [CallWith=ScriptState, RaisesException] void postMessage(any message, optional sequence<object> transfer=[]);
+ [RuntimeEnabled=PostMessageOptions, CallWith=ScriptState, RaisesException] void postMessage(any message, PostMessageOptions options);
attribute EventHandler onmessage;
};
diff --git a/chromium/third_party/blink/renderer/core/workers/worker_animation_frame_provider.cc b/chromium/third_party/blink/renderer/core/workers/worker_animation_frame_provider.cc
index bdbf04b6888..5bd5134604b 100644
--- a/chromium/third_party/blink/renderer/core/workers/worker_animation_frame_provider.cc
+++ b/chromium/third_party/blink/renderer/core/workers/worker_animation_frame_provider.cc
@@ -22,6 +22,10 @@ WorkerAnimationFrameProvider::WorkerAnimationFrameProvider(
int WorkerAnimationFrameProvider::RegisterCallback(
FrameRequestCallbackCollection::FrameCallback* callback) {
+ if (!begin_frame_provider_->IsValidFrameProvider()) {
+ return WorkerAnimationFrameProvider::kInvalidCallbackId;
+ }
+
FrameRequestCallbackCollection::CallbackId id =
callback_collection_.RegisterCallback(callback);
begin_frame_provider_->RequestBeginFrame();
diff --git a/chromium/third_party/blink/renderer/core/workers/worker_animation_frame_provider.h b/chromium/third_party/blink/renderer/core/workers/worker_animation_frame_provider.h
index d7759cb33f3..386e133fa34 100644
--- a/chromium/third_party/blink/renderer/core/workers/worker_animation_frame_provider.h
+++ b/chromium/third_party/blink/renderer/core/workers/worker_animation_frame_provider.h
@@ -48,6 +48,8 @@ class CORE_EXPORT WorkerAnimationFrameProvider
void RegisterOffscreenCanvas(OffscreenCanvas*);
void DeregisterOffscreenCanvas(OffscreenCanvas*);
+ static const int kInvalidCallbackId = -1;
+
protected:
WorkerAnimationFrameProvider(
ExecutionContext* context,
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 21d16b4c20b..ade0105a42b 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
@@ -32,7 +32,7 @@ Mutex& IsolatesMutex() {
HashSet<v8::Isolate*>& Isolates() {
#if DCHECK_IS_ON()
- DCHECK(IsolatesMutex().Locked());
+ IsolatesMutex().AssertAcquired();
#endif
static HashSet<v8::Isolate*>& isolates = *new HashSet<v8::Isolate*>();
return isolates;
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 6e803af108f..fae3bbccaf0 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
@@ -51,9 +51,9 @@ WorkerClassicScriptLoader::WorkerClassicScriptLoader()
: response_address_space_(mojom::IPAddressSpace::kPublic) {}
WorkerClassicScriptLoader::~WorkerClassicScriptLoader() {
- // If |m_threadableLoader| is still working, we have to cancel it here.
- // Otherwise didFail() of the deleted |this| will be called from
- // DocumentThreadableLoader::notifyFinished() when the frame will be
+ // If |threadable_loader_| is still working, we have to cancel it here.
+ // Otherwise DidFail() of the deleted |this| will be called from
+ // ThreadableLoader::NotifyFinished() when the frame will be
// destroyed.
if (need_to_cancel_)
Cancel();
@@ -75,17 +75,17 @@ void WorkerClassicScriptLoader::LoadSynchronously(
SECURITY_DCHECK(execution_context.IsWorkerGlobalScope());
- ThreadableLoaderOptions options;
-
ResourceLoaderOptions resource_loader_options;
resource_loader_options.parser_disposition =
ParserDisposition::kNotParserInserted;
+ resource_loader_options.synchronous_policy = kRequestSynchronously;
- ThreadableLoader::LoadResourceSynchronously(execution_context, request, *this,
- options, resource_loader_options);
+ threadable_loader_ = new ThreadableLoader(
+ execution_context, this, resource_loader_options);
+ threadable_loader_->Start(request);
}
-void WorkerClassicScriptLoader::LoadAsynchronously(
+void WorkerClassicScriptLoader::LoadTopLevelScriptAsynchronously(
ExecutionContext& execution_context,
const KURL& url,
WebURLRequest::RequestContext request_context,
@@ -99,6 +99,7 @@ void WorkerClassicScriptLoader::LoadAsynchronously(
finished_callback_ = std::move(finished_callback);
url_ = url;
execution_context_ = &execution_context;
+ forbid_cross_origin_redirects_ = true;
ResourceRequest request(url);
request.SetHTTPMethod(HTTPNames::GET);
@@ -108,8 +109,6 @@ void WorkerClassicScriptLoader::LoadAsynchronously(
request.SetFetchRequestMode(fetch_request_mode);
request.SetFetchCredentialsMode(fetch_credentials_mode);
- ThreadableLoaderOptions options;
-
ResourceLoaderOptions resource_loader_options;
// During create, callbacks may happen which could remove the last reference
@@ -118,8 +117,8 @@ void WorkerClassicScriptLoader::LoadAsynchronously(
// (E.g. see crbug.com/524694 for why we can't easily remove this protect)
scoped_refptr<WorkerClassicScriptLoader> protect(this);
need_to_cancel_ = true;
- threadable_loader_ = ThreadableLoader::Create(
- execution_context, this, options, resource_loader_options);
+ threadable_loader_ = new ThreadableLoader(
+ execution_context, this, resource_loader_options);
threadable_loader_->Start(request);
if (failed_)
NotifyFinished();
@@ -143,8 +142,26 @@ void WorkerClassicScriptLoader::DidReceiveResponse(
NotifyError();
return;
}
+
+ if (forbid_cross_origin_redirects_ && url_ != response.Url() &&
+ !SecurityOrigin::AreSameSchemeHostPort(url_, response.Url())) {
+ // Forbid cross-origin redirects to ensure the request and response URLs
+ // have the same SecurityOrigin.
+ execution_context_->AddConsoleMessage(ConsoleMessage::Create(
+ kSecurityMessageSource, kErrorMessageLevel,
+ "Refused to cross-origin redirects of the top-level worker script."));
+ NotifyError();
+ return;
+ }
+
identifier_ = identifier;
- response_url_ = response.Url();
+ if (response.WasFetchedViaServiceWorker() &&
+ !response.OriginalURLViaServiceWorker().IsEmpty()) {
+ response_url_ = response.OriginalURLViaServiceWorker();
+ } else {
+ response_url_ = response.Url();
+ }
+
response_encoding_ = response.TextEncodingName();
app_cache_id_ = response.AppCacheID();
@@ -219,12 +236,12 @@ String WorkerClassicScriptLoader::SourceText() {
void WorkerClassicScriptLoader::NotifyError() {
failed_ = true;
- // notifyError() could be called before ThreadableLoader::create() returns
- // e.g. from didFail(), and in that case m_threadableLoader is not yet set
+ // NotifyError() could be called before ThreadableLoader::Create() returns
+ // e.g. from DidFail(), and in that case threadable_loader_ is not yet set
// (i.e. still null).
- // Since the callback invocation in notifyFinished() potentially delete
+ // Since the callback invocation in NotifyFinished() potentially delete
// |this| object, the callback invocation should be postponed until the
- // create() call returns. See loadAsynchronously() for the postponed call.
+ // create() call returns. See LoadAsynchronously() for the postponed call.
if (threadable_loader_)
NotifyFinished();
}
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 402db730327..b0d43dfa025 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
@@ -61,23 +61,25 @@ class CORE_EXPORT WorkerClassicScriptLoader final
return base::AdoptRef(new WorkerClassicScriptLoader());
}
+ // For importScript().
void LoadSynchronously(ExecutionContext&,
const KURL&,
WebURLRequest::RequestContext,
mojom::IPAddressSpace);
- // Note that callbacks could be invoked before loadAsynchronously() returns.
- void LoadAsynchronously(ExecutionContext&,
- const KURL&,
- WebURLRequest::RequestContext,
- network::mojom::FetchRequestMode,
- network::mojom::FetchCredentialsMode,
- mojom::IPAddressSpace,
- base::OnceClosure response_callback,
- base::OnceClosure finished_callback);
-
- // This will immediately invoke |finishedCallback| if loadAsynchronously()
- // is in progress.
+ // Note that callbacks could be invoked before
+ // LoadTopLevelScriptAsynchronously() returns.
+ void LoadTopLevelScriptAsynchronously(ExecutionContext&,
+ const KURL&,
+ WebURLRequest::RequestContext,
+ network::mojom::FetchRequestMode,
+ network::mojom::FetchCredentialsMode,
+ mojom::IPAddressSpace,
+ base::OnceClosure response_callback,
+ base::OnceClosure finished_callback);
+
+ // This will immediately invoke |finishedCallback| if
+ // LoadTopLevelScriptAsynchronously() is in progress.
void Cancel();
String SourceText();
@@ -96,9 +98,6 @@ class CORE_EXPORT WorkerClassicScriptLoader final
ContentSecurityPolicy* GetContentSecurityPolicy() {
return content_security_policy_.Get();
}
- ContentSecurityPolicy* ReleaseContentSecurityPolicy() {
- return content_security_policy_.Release();
- }
const String& GetReferrerPolicy() const { return referrer_policy_; }
@@ -147,6 +146,8 @@ class CORE_EXPORT WorkerClassicScriptLoader final
bool canceled_ = false;
bool need_to_cancel_ = false;
+ bool forbid_cross_origin_redirects_ = false;
+
unsigned long identifier_ = 0;
long long app_cache_id_ = 0;
std::unique_ptr<Vector<char>> cached_metadata_;
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 e5fe2f5574e..93f1dd6df22 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
@@ -44,7 +44,7 @@
#include "third_party/blink/renderer/core/inspector/console_message_storage.h"
#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/worker_threadable_loader.h"
+#include "third_party/blink/renderer/core/loader/threadable_loader.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/global_scope_creation_params.h"
@@ -344,7 +344,10 @@ WorkerGlobalScope::WorkerGlobalScope(
font_selector_(OffscreenFontSelector::Create(this)),
animation_frame_provider_(WorkerAnimationFrameProvider::Create(
this,
- creation_params->begin_frame_provider_params)) {
+ creation_params->begin_frame_provider_params)),
+ agent_cluster_id_(creation_params->agent_cluster_id.is_empty()
+ ? base::UnguessableToken::Create()
+ : creation_params->agent_cluster_id) {
InstanceCounters::IncrementCounter(
InstanceCounters::kWorkerGlobalScopeCounter);
scoped_refptr<SecurityOrigin> security_origin = SecurityOrigin::Create(url_);
@@ -353,6 +356,13 @@ WorkerGlobalScope::WorkerGlobalScope(
creation_params->starter_origin->CreatePrivilegeData());
}
SetSecurityOrigin(std::move(security_origin));
+
+ // https://html.spec.whatwg.org/#run-a-worker
+ // 4. Set worker global scope's HTTPS state to response's HTTPS state. [spec
+ // text]
+ https_state_ = CalculateHttpsState(GetSecurityOrigin(),
+ creation_params->starter_https_state);
+
InitContentSecurityPolicyFromVector(
creation_params->content_security_policy_parsed_headers);
BindContentSecurityPolicyToExecutionContext();
@@ -405,12 +415,21 @@ void WorkerGlobalScope::RemoveURLFromMemoryCache(const KURL& url) {
CrossThreadBind(&RemoveURLFromMemoryCacheInternal, url));
}
-int WorkerGlobalScope::requestAnimationFrame(V8FrameRequestCallback* callback) {
+int WorkerGlobalScope::requestAnimationFrame(V8FrameRequestCallback* callback,
+ ExceptionState& exception_state) {
FrameRequestCallbackCollection::V8FrameCallback* frame_callback =
FrameRequestCallbackCollection::V8FrameCallback::Create(callback);
frame_callback->SetUseLegacyTimeBase(true);
- return animation_frame_provider_->RegisterCallback(frame_callback);
+ int ret = animation_frame_provider_->RegisterCallback(frame_callback);
+
+ if (ret == WorkerAnimationFrameProvider::kInvalidCallbackId) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kNotSupportedError,
+ "requestAnimationFrame not supported in this Worker.");
+ }
+
+ return ret;
}
void WorkerGlobalScope::cancelAnimationFrame(int id) {
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 61e7370f9bf..7f9a88fe6c3 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
@@ -112,6 +112,10 @@ class CORE_EXPORT WorkerGlobalScope
bool IsContextThread() const final;
const KURL& BaseURL() const final { return url_; }
String UserAgent() const final { return user_agent_; }
+ HttpsState GetHttpsState() const override { return https_state_; }
+ const base::UnguessableToken& GetAgentClusterID() const final {
+ return agent_cluster_id_;
+ }
DOMTimerCoordinator* Timers() final { return &timers_; }
SecurityContext& GetSecurityContext() final { return *this; }
@@ -150,7 +154,7 @@ class CORE_EXPORT WorkerGlobalScope
// FontFaceSource on the IDL.
FontFaceSet* fonts();
- int requestAnimationFrame(V8FrameRequestCallback* callback);
+ int requestAnimationFrame(V8FrameRequestCallback* callback, ExceptionState&);
void cancelAnimationFrame(int id);
WorkerAnimationFrameProvider* GetAnimationFrameProvider() {
@@ -226,6 +230,10 @@ class CORE_EXPORT WorkerGlobalScope
TraceWrapperMember<WorkerAnimationFrameProvider> animation_frame_provider_;
service_manager::InterfaceProvider interface_provider_;
+
+ const base::UnguessableToken agent_cluster_id_;
+
+ HttpsState https_state_;
};
DEFINE_TYPE_CASTS(WorkerGlobalScope,
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 b36e8c297a5..1e5fd34d1e4 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
@@ -69,7 +69,7 @@
// TODO(fserb): temporarly until we can enable the interface below.
[RuntimeEnabled=OffscreenCanvasText] readonly attribute FontFaceSet fonts;
- [RuntimeEnabled=OffscreenCanvas] long requestAnimationFrame(FrameRequestCallback callback);
+ [RuntimeEnabled=OffscreenCanvas, RaisesException] long requestAnimationFrame(FrameRequestCallback callback);
[RuntimeEnabled=OffscreenCanvas] void cancelAnimationFrame(long handle);
};
diff --git a/chromium/third_party/blink/renderer/core/workers/worker_options.idl b/chromium/third_party/blink/renderer/core/workers/worker_options.idl
index 5a96bbaa58b..238820038e6 100644
--- a/chromium/third_party/blink/renderer/core/workers/worker_options.idl
+++ b/chromium/third_party/blink/renderer/core/workers/worker_options.idl
@@ -6,8 +6,7 @@
dictionary WorkerOptions {
WorkerType type = "classic";
RequestCredentials credentials = "same-origin";
- // TODO(nhiroki): Implement "name" option (https://crbug.com/721219)
- // DOMString name = "";
+ DOMString name = "";
};
enum WorkerType { "classic", "module" };
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 c006e6490f1..bdc30cfab3e 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
@@ -126,18 +126,6 @@ bool WorkerOrWorkletGlobalScope::CanExecuteScripts(
void WorkerOrWorkletGlobalScope::Dispose() {
DCHECK(script_controller_);
- // Event listeners would keep DOMWrapperWorld objects alive for too long.
- // Also, they have references to JS objects, which become dangling once Heap
- // is destroyed.
- HeapHashSet<Member<V8AbstractEventListener>> listeners;
- listeners.swap(event_listeners_);
- while (!listeners.IsEmpty()) {
- for (const auto& listener : listeners)
- listener->ClearListenerObject();
- listeners.clear();
- // Pick up any additions made while iterating.
- listeners.swap(event_listeners_);
- }
RemoveAllEventListeners();
script_controller_->Dispose();
@@ -149,22 +137,6 @@ void WorkerOrWorkletGlobalScope::Dispose() {
}
}
-void WorkerOrWorkletGlobalScope::RegisterEventListener(
- V8AbstractEventListener* event_listener) {
- // TODO(sof): remove once crbug.com/677654 has been diagnosed.
- CHECK(&ThreadState::FromObject(this)->Heap() ==
- &ThreadState::FromObject(event_listener)->Heap());
- bool new_entry = event_listeners_.insert(event_listener).is_new_entry;
- CHECK(new_entry);
-}
-
-void WorkerOrWorkletGlobalScope::DeregisterEventListener(
- V8AbstractEventListener* event_listener) {
- auto it = event_listeners_.find(event_listener);
- CHECK(it != event_listeners_.end() || IsClosing());
- event_listeners_.erase(it);
-}
-
void WorkerOrWorkletGlobalScope::SetModulator(Modulator* modulator) {
modulator_ = modulator;
}
@@ -230,7 +202,6 @@ void WorkerOrWorkletGlobalScope::FetchModuleScript(
void WorkerOrWorkletGlobalScope::Trace(blink::Visitor* visitor) {
visitor->Trace(resource_fetcher_);
visitor->Trace(script_controller_);
- visitor->Trace(event_listeners_);
visitor->Trace(modulator_);
EventTargetWithInlineData::Trace(visitor);
ExecutionContext::Trace(visitor);
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 bf40a501a2d..c99979d21dc 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
@@ -25,7 +25,6 @@ class FetchClientSettingsObjectSnapshot;
class Modulator;
class ModuleTreeClient;
class ResourceFetcher;
-class V8AbstractEventListener;
class WorkerOrWorkletScriptController;
class WorkerReportingProxy;
class WorkerThread;
@@ -73,9 +72,6 @@ class CORE_EXPORT WorkerOrWorkletGlobalScope : public EventTargetWithInlineData,
// sub-classes to perform any cleanup needed.
virtual void Dispose();
- void RegisterEventListener(V8AbstractEventListener*);
- void DeregisterEventListener(V8AbstractEventListener*);
-
void SetModulator(Modulator*);
// Called from UseCounter to record API use in this execution context.
@@ -125,8 +121,6 @@ class CORE_EXPORT WorkerOrWorkletGlobalScope : public EventTargetWithInlineData,
WorkerReportingProxy& reporting_proxy_;
- HeapHashSet<Member<V8AbstractEventListener>> event_listeners_;
-
// This is the set of features that this worker has used.
BitVector used_features_;
diff --git a/chromium/third_party/blink/renderer/core/workers/worker_reporting_proxy.h b/chromium/third_party/blink/renderer/core/workers/worker_reporting_proxy.h
index 7ff01d3fe20..26ef69a26aa 100644
--- a/chromium/third_party/blink/renderer/core/workers/worker_reporting_proxy.h
+++ b/chromium/third_party/blink/renderer/core/workers/worker_reporting_proxy.h
@@ -37,7 +37,6 @@
#include "third_party/blink/renderer/core/frame/web_feature_forward.h"
#include "third_party/blink/renderer/core/inspector/console_types.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/network/content_security_policy_response_headers.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
namespace blink {
@@ -74,15 +73,8 @@ class CORE_EXPORT WorkerReportingProxy {
// Invoked when the worker's main script is loaded on
// WorkerThread::InitializeOnWorkerThread(). Only invoked when the script was
// loaded on the worker thread, i.e., via InstalledScriptsManager rather than
- // via ResourceLoader. ContentSecurityPolicy and ReferrerPolicy are read from
- // the response header of the main script.
- // This may block until CSP/ReferrerPolicy are set on the main thread
- // since they are required for script evaluation, which happens soon after
- // this function is called.
- // Called before WillEvaluateClassicScript().
- virtual void DidLoadInstalledScript(
- const ContentSecurityPolicyResponseHeaders&,
- const String& referrer_policy_on_worker_thread) {}
+ // via ResourceLoader. Called before WillEvaluateClassicScript().
+ virtual void DidLoadInstalledScript() {}
// Invoked when the main classic script is about to be evaluated.
virtual void WillEvaluateClassicScript(size_t script_size,
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 6b4a2ce0552..0e1ce1e2ffc 100644
--- a/chromium/third_party/blink/renderer/core/workers/worker_thread.cc
+++ b/chromium/third_party/blink/renderer/core/workers/worker_thread.cc
@@ -48,7 +48,6 @@
#include "third_party/blink/renderer/core/workers/worker_reporting_proxy.h"
#include "third_party/blink/renderer/platform/bindings/microtask.h"
#include "third_party/blink/renderer/platform/cross_thread_functional.h"
-#include "third_party/blink/renderer/platform/heap/safe_point.h"
#include "third_party/blink/renderer/platform/heap/thread_state.h"
#include "third_party/blink/renderer/platform/histogram.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
@@ -87,6 +86,28 @@ static int GetNextWorkerThreadId() {
return next_worker_thread_id;
}
+// RefCountedWaitableEvent makes WaitableEvent thread-safe refcounted.
+// WorkerThread retains references to the event from both the parent context
+// thread and the worker thread with this wrapper. See
+// WorkerThread::PerformShutdownOnWorkerThread() for details.
+class WorkerThread::RefCountedWaitableEvent
+ : public WTF::ThreadSafeRefCounted<RefCountedWaitableEvent> {
+ public:
+ static scoped_refptr<RefCountedWaitableEvent> Create() {
+ return base::AdoptRef<RefCountedWaitableEvent>(new RefCountedWaitableEvent);
+ }
+
+ void Wait() { event_.Wait(); }
+ void Signal() { event_.Signal(); }
+
+ private:
+ RefCountedWaitableEvent() = default;
+
+ base::WaitableEvent event_;
+
+ DISALLOW_COPY_AND_ASSIGN(RefCountedWaitableEvent);
+};
+
WorkerThread::~WorkerThread() {
MutexLocker lock(ThreadSetMutex());
DCHECK(WorkerThreads().Contains(this));
@@ -112,7 +133,7 @@ void WorkerThread::Start(
// Synchronously initialize the per-global-scope scheduler to prevent someone
// from posting a task to the thread before the scheduler is ready.
- WaitableEvent waitable_event;
+ base::WaitableEvent waitable_event;
GetWorkerBackingThread().BackingThread().PostTask(
FROM_HERE,
CrossThreadBind(&WorkerThread::InitializeSchedulerOnWorkerThread,
@@ -171,7 +192,6 @@ void WorkerThread::Terminate() {
// period.
ScheduleToTerminateScriptExecution();
- worker_thread_lifecycle_context_->NotifyContextDestroyed();
inspector_task_runner_->Dispose();
GetWorkerBackingThread().BackingThread().PostTask(
@@ -202,7 +222,7 @@ void WorkerThread::TerminateAllWorkersForTesting() {
}
for (WorkerThread* thread : threads)
- thread->shutdown_event_->Wait();
+ thread->WaitForShutdownForTesting();
// Destruct base::Thread and join the underlying system threads.
for (WorkerThread* thread : threads)
@@ -241,13 +261,6 @@ bool WorkerThread::IsCurrentThread() {
return GetWorkerBackingThread().BackingThread().IsCurrentThread();
}
-ThreadableLoadingContext* WorkerThread::GetLoadingContext() {
- DCHECK(IsCurrentThread());
- // This should be never called after the termination sequence starts.
- DCHECK(loading_context_);
- return loading_context_;
-}
-
void WorkerThread::AppendDebuggerTask(CrossThreadClosure task) {
DCHECK_CALLED_ON_VALID_THREAD(parent_thread_checker_);
inspector_task_runner_->AppendTask(std::move(task));
@@ -311,6 +324,11 @@ bool WorkerThread::IsForciblyTerminated() {
return false;
}
+void WorkerThread::WaitForShutdownForTesting() {
+ DCHECK_CALLED_ON_VALID_THREAD(parent_thread_checker_);
+ shutdown_event_->Wait();
+}
+
ExitCode WorkerThread::GetExitCodeForTesting() {
MutexLocker lock(mutex_);
return exit_code_;
@@ -339,18 +357,13 @@ void WorkerThread::ChildThreadTerminatedOnWorkerThread(WorkerThread* child) {
PerformShutdownOnWorkerThread();
}
-WorkerThread::WorkerThread(ThreadableLoadingContext* loading_context,
- WorkerReportingProxy& worker_reporting_proxy)
+WorkerThread::WorkerThread(WorkerReportingProxy& worker_reporting_proxy)
: time_origin_(CurrentTimeTicks()),
worker_thread_id_(GetNextWorkerThreadId()),
forcible_termination_delay_(kForcibleTerminationDelay),
devtools_worker_token_(base::UnguessableToken::Create()),
- loading_context_(loading_context),
worker_reporting_proxy_(worker_reporting_proxy),
- shutdown_event_(std::make_unique<WaitableEvent>(
- WaitableEvent::ResetPolicy::kManual,
- WaitableEvent::InitialState::kNonSignaled)),
- worker_thread_lifecycle_context_(new WorkerThreadLifecycleContext) {
+ shutdown_event_(RefCountedWaitableEvent::Create()) {
MutexLocker lock(ThreadSetMutex());
WorkerThreads().insert(this);
}
@@ -401,7 +414,7 @@ void WorkerThread::EnsureScriptExecutionTerminates(ExitCode exit_code) {
}
void WorkerThread::InitializeSchedulerOnWorkerThread(
- WaitableEvent* waitable_event) {
+ base::WaitableEvent* waitable_event) {
DCHECK(IsCurrentThread());
DCHECK(!worker_scheduler_);
scheduler::WebThreadImplForWorkerScheduler& web_thread_for_worker =
@@ -431,6 +444,8 @@ void WorkerThread::InitializeOnWorkerThread(
}
GetWorkerBackingThread().BackingThread().AddTaskObserver(this);
+ const KURL url_for_debugger = global_scope_creation_params->script_url;
+
console_message_storage_ = new ConsoleMessageStorage();
global_scope_ =
CreateWorkerGlobalScope(std::move(global_scope_creation_params));
@@ -447,7 +462,7 @@ void WorkerThread::InitializeOnWorkerThread(
// TODO(nhiroki): Handle a case where the script controller fails to
// initialize the context.
if (GlobalScope()->ScriptController()->InitializeContextIfNeeded(
- String())) {
+ String(), url_for_debugger)) {
worker_reporting_proxy_.DidInitializeWorkerContext();
v8::HandleScope handle_scope(GetIsolate());
Platform::Current()->WorkerContextCreated(
@@ -557,18 +572,25 @@ void WorkerThread::PerformShutdownOnWorkerThread() {
debugger->WorkerThreadDestroyed(this);
console_message_storage_.Clear();
- loading_context_.Clear();
if (IsOwningBackingThread())
GetWorkerBackingThread().ShutdownOnBackingThread();
- // We must not touch workerBackingThread() from now on.
+ // We must not touch GetWorkerBackingThread() from now on.
+
+ // Keep the reference to the shutdown event in a local variable so that the
+ // worker thread can signal it even after calling DidTerminateWorkerThread(),
+ // which may destroy |this|.
+ scoped_refptr<RefCountedWaitableEvent> shutdown_event = shutdown_event_;
// Notify the proxy that the WorkerOrWorkletGlobalScope has been disposed
// of. This can free this thread object, hence it must not be touched
// afterwards.
GetWorkerReportingProxy().DidTerminateWorkerThread();
- shutdown_event_->Signal();
+ // This should be signaled at the end because this may induce the main thread
+ // to clear the worker backing thread and stop thread execution in the system
+ // level.
+ shutdown_event->Signal();
}
void WorkerThread::SetThreadState(ThreadState next_thread_state) {
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 b87706015e4..aa25d12ae00 100644
--- a/chromium/third_party/blink/renderer/core/workers/worker_thread.h
+++ b/chromium/third_party/blink/renderer/core/workers/worker_thread.h
@@ -32,6 +32,7 @@
#include "base/memory/scoped_refptr.h"
#include "base/optional.h"
#include "base/single_thread_task_runner.h"
+#include "base/synchronization/waitable_event.h"
#include "base/thread_annotations.h"
#include "base/unguessable_token.h"
#include "services/network/public/mojom/fetch_api.mojom-shared.h"
@@ -39,14 +40,10 @@
#include "third_party/blink/public/platform/web_thread_type.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/core/loader/threadable_loading_context.h"
#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/core/workers/worker_inspector_proxy.h"
-#include "third_party/blink/renderer/core/workers/worker_thread_lifecycle_context.h"
-#include "third_party/blink/renderer/core/workers/worker_thread_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/scheduler/public/worker_scheduler.h"
-#include "third_party/blink/renderer/platform/waitable_event.h"
#include "third_party/blink/renderer/platform/web_task_runner.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
@@ -151,9 +148,6 @@ class CORE_EXPORT WorkerThread : public WebThread::TaskObserver {
bool IsCurrentThread();
- // Called on the worker thread.
- ThreadableLoadingContext* GetLoadingContext();
-
WorkerReportingProxy& GetWorkerReportingProxy() const {
return worker_reporting_proxy_;
}
@@ -175,12 +169,6 @@ class CORE_EXPORT WorkerThread : public WebThread::TaskObserver {
WorkerOrWorkletGlobalScope* GlobalScope();
WorkerInspectorController* GetWorkerInspectorController();
- // Called for creating WorkerThreadLifecycleObserver on both the main thread
- // and the worker thread.
- WorkerThreadLifecycleContext* GetWorkerThreadLifecycleContext() const {
- return worker_thread_lifecycle_context_;
- }
-
// Number of active worker threads.
static unsigned WorkerThreadCount();
@@ -194,7 +182,7 @@ class CORE_EXPORT WorkerThread : public WebThread::TaskObserver {
bool IsForciblyTerminated() LOCKS_EXCLUDED(mutex_);
- void WaitForShutdownForTesting() { shutdown_event_->Wait(); }
+ void WaitForShutdownForTesting();
ExitCode GetExitCodeForTesting() LOCKS_EXCLUDED(mutex_);
ParentExecutionContextTaskRunners* GetParentExecutionContextTaskRunners()
@@ -222,7 +210,7 @@ class CORE_EXPORT WorkerThread : public WebThread::TaskObserver {
void ChildThreadTerminatedOnWorkerThread(WorkerThread*);
protected:
- WorkerThread(ThreadableLoadingContext*, WorkerReportingProxy&);
+ explicit WorkerThread(WorkerReportingProxy&);
virtual WebThreadType GetThreadType() const = 0;
@@ -274,7 +262,7 @@ class CORE_EXPORT WorkerThread : public WebThread::TaskObserver {
void EnsureScriptExecutionTerminates(ExitCode) LOCKS_EXCLUDED(mutex_);
// These are called in this order during worker thread startup.
- void InitializeSchedulerOnWorkerThread(WaitableEvent*);
+ void InitializeSchedulerOnWorkerThread(base::WaitableEvent*);
void InitializeOnWorkerThread(
std::unique_ptr<GlobalScopeCreationParams>,
const base::Optional<WorkerBackingThreadStartupData>&,
@@ -317,10 +305,6 @@ class CORE_EXPORT WorkerThread : public WebThread::TaskObserver {
scoped_refptr<InspectorTaskRunner> inspector_task_runner_;
const base::UnguessableToken devtools_worker_token_;
- // Created on the main thread, passed to the worker thread but should kept
- // being accessed only on the main thread.
- CrossThreadPersistent<ThreadableLoadingContext> loading_context_;
-
WorkerReportingProxy& worker_reporting_proxy_;
CrossThreadPersistent<ParentExecutionContextTaskRunners>
@@ -339,18 +323,16 @@ class CORE_EXPORT WorkerThread : public WebThread::TaskObserver {
CrossThreadPersistent<WorkerOrWorkletGlobalScope> global_scope_;
CrossThreadPersistent<WorkerInspectorController> worker_inspector_controller_;
- // Signaled when the thread completes termination on the worker thread.
- std::unique_ptr<WaitableEvent> shutdown_event_;
+ // Signaled when the thread completes termination on the worker thread. Only
+ // the parent context thread should wait on this event after calling
+ // Terminate().
+ class RefCountedWaitableEvent;
+ scoped_refptr<RefCountedWaitableEvent> shutdown_event_;
// Used to cancel a scheduled forcible termination task. See
// mayForciblyTerminateExecution() for details.
TaskHandle forcible_termination_task_handle_;
- // Created on the main thread heap, but will be accessed cross-thread
- // when worker thread posts tasks.
- CrossThreadPersistent<WorkerThreadLifecycleContext>
- worker_thread_lifecycle_context_;
-
HashSet<WorkerThread*> child_threads_;
THREAD_CHECKER(parent_thread_checker_);
diff --git a/chromium/third_party/blink/renderer/core/workers/worker_thread_lifecycle_context.cc b/chromium/third_party/blink/renderer/core/workers/worker_thread_lifecycle_context.cc
deleted file mode 100644
index 85cf484c61a..00000000000
--- a/chromium/third_party/blink/renderer/core/workers/worker_thread_lifecycle_context.cc
+++ /dev/null
@@ -1,26 +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/workers/worker_thread_lifecycle_context.h"
-
-#include "third_party/blink/renderer/core/workers/worker_thread_lifecycle_observer.h"
-
-namespace blink {
-
-WorkerThreadLifecycleContext::WorkerThreadLifecycleContext() {
- DETACH_FROM_THREAD(thread_checker_);
-}
-
-WorkerThreadLifecycleContext::~WorkerThreadLifecycleContext() {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-}
-
-void WorkerThreadLifecycleContext::NotifyContextDestroyed() {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK(!was_context_destroyed_);
- was_context_destroyed_ = true;
- LifecycleNotifier::NotifyContextDestroyed();
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/workers/worker_thread_lifecycle_context.h b/chromium/third_party/blink/renderer/core/workers/worker_thread_lifecycle_context.h
deleted file mode 100644
index 0dec708ca30..00000000000
--- a/chromium/third_party/blink/renderer/core/workers/worker_thread_lifecycle_context.h
+++ /dev/null
@@ -1,43 +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_WORKERS_WORKER_THREAD_LIFECYCLE_CONTEXT_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_WORKERS_WORKER_THREAD_LIFECYCLE_CONTEXT_H_
-
-#include "base/macros.h"
-#include "base/threading/thread_checker.h"
-#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
-#include "third_party/blink/renderer/platform/lifecycle_notifier.h"
-
-namespace blink {
-
-class WorkerThreadLifecycleObserver;
-
-// Used for notifying observers on the creating thread of worker thread
-// termination. The lifetime of this class is equal to that of WorkerThread.
-// Created and destructed on the thread that constructed the worker.
-class CORE_EXPORT WorkerThreadLifecycleContext final
- : public GarbageCollectedFinalized<WorkerThreadLifecycleContext>,
- public LifecycleNotifier<WorkerThreadLifecycleContext,
- WorkerThreadLifecycleObserver> {
- USING_GARBAGE_COLLECTED_MIXIN(WorkerThreadLifecycleContext);
-
- public:
- WorkerThreadLifecycleContext();
- ~WorkerThreadLifecycleContext() override;
- void NotifyContextDestroyed() override;
-
- private:
- friend class WorkerThreadLifecycleObserver;
- bool was_context_destroyed_ = false;
-
- THREAD_CHECKER(thread_checker_);
-
- DISALLOW_COPY_AND_ASSIGN(WorkerThreadLifecycleContext);
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_WORKERS_WORKER_THREAD_LIFECYCLE_CONTEXT_H_
diff --git a/chromium/third_party/blink/renderer/core/workers/worker_thread_lifecycle_observer.cc b/chromium/third_party/blink/renderer/core/workers/worker_thread_lifecycle_observer.cc
deleted file mode 100644
index c6d5f91200b..00000000000
--- a/chromium/third_party/blink/renderer/core/workers/worker_thread_lifecycle_observer.cc
+++ /dev/null
@@ -1,23 +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/workers/worker_thread_lifecycle_observer.h"
-
-#include "third_party/blink/renderer/core/workers/worker_thread.h"
-#include "third_party/blink/renderer/core/workers/worker_thread_lifecycle_context.h"
-#include "third_party/blink/renderer/platform/wtf/assertions.h"
-#include "third_party/blink/renderer/platform/wtf/wtf.h"
-
-namespace blink {
-
-WorkerThreadLifecycleObserver::WorkerThreadLifecycleObserver(
- WorkerThreadLifecycleContext* worker_thread_lifecycle_context)
- : LifecycleObserver(worker_thread_lifecycle_context),
- was_context_destroyed_before_observer_creation_(
- worker_thread_lifecycle_context->was_context_destroyed_) {
-}
-
-WorkerThreadLifecycleObserver::~WorkerThreadLifecycleObserver() = default;
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/workers/worker_thread_lifecycle_observer.h b/chromium/third_party/blink/renderer/core/workers/worker_thread_lifecycle_observer.h
deleted file mode 100644
index 55cba3459d9..00000000000
--- a/chromium/third_party/blink/renderer/core/workers/worker_thread_lifecycle_observer.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_WORKERS_WORKER_THREAD_LIFECYCLE_OBSERVER_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_WORKERS_WORKER_THREAD_LIFECYCLE_OBSERVER_H_
-
-#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/platform/lifecycle_observer.h"
-
-namespace blink {
-
-class WorkerThreadLifecycleContext;
-
-// An interface for observing worker thread termination from the main thread.
-// This may be useful, for example, when an object living on the main thread
-// needs to release references to objects on the worker thread before it gets
-// terminated.
-//
-// A class that inherits this interface should override
-// LifecycleObserver::contextDestroyed() that is called on the main thread when
-// the worker thread is about to terminate. While contextDestroyed() is called,
-// it is guaranteed that the worker thread is still alive.
-//
-// A newly created observer should firstly check whether the worker thread is
-// alive by wasContextDestroyedBeforeObserverCreation(). If this return true,
-// the worker thread has already been terminated before the observer is created,
-// and contextDestroyed() is never notified.
-class CORE_EXPORT WorkerThreadLifecycleObserver
- : public LifecycleObserver<WorkerThreadLifecycleContext,
- WorkerThreadLifecycleObserver> {
- public:
- virtual void ContextDestroyed(WorkerThreadLifecycleContext*) {}
-
- protected:
- explicit WorkerThreadLifecycleObserver(WorkerThreadLifecycleContext*);
- virtual ~WorkerThreadLifecycleObserver();
-
- bool WasContextDestroyedBeforeObserverCreation() const {
- return was_context_destroyed_before_observer_creation_;
- }
-
- private:
- const bool was_context_destroyed_before_observer_creation_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_WORKERS_WORKER_THREAD_LIFECYCLE_OBSERVER_H_
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 719b92186f1..5477003ee24 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
@@ -115,7 +115,7 @@ void CreateNestedWorkerThenTerminateParent(
.Times(1);
nested_worker_helper->worker_thread = std::make_unique<WorkerThreadForTest>(
- nullptr, *nested_worker_helper->reporting_proxy);
+ *nested_worker_helper->reporting_proxy);
nested_worker_helper->worker_thread->StartWithSourceCode(
SecurityOrigin::Create(KURL("http://fake.url/")).get(),
"//fake source code", ParentExecutionContextTaskRunners::Create());
@@ -147,8 +147,6 @@ void VerifyParentAndChildAreTerminated(WorkerThread* parent_thread,
EXPECT_TRUE(parent_thread->IsCurrentThread());
EXPECT_EQ(ExitCode::kGracefullyTerminated,
parent_thread->GetExitCodeForTesting());
- EXPECT_EQ(ExitCode::kGracefullyTerminated,
- nested_worker_helper->worker_thread->GetExitCodeForTesting());
EXPECT_NE(nullptr, parent_thread->GlobalScope());
parent_thread->ChildThreadTerminatedOnWorkerThread(
@@ -169,10 +167,7 @@ class WorkerThreadTest : public testing::Test {
void SetUp() override {
reporting_proxy_ = std::make_unique<MockWorkerReportingProxy>();
security_origin_ = SecurityOrigin::Create(KURL("http://fake.url/"));
- worker_thread_ =
- std::make_unique<WorkerThreadForTest>(nullptr, *reporting_proxy_);
- lifecycle_observer_ = new MockWorkerThreadLifecycleObserver(
- worker_thread_->GetWorkerThreadLifecycleContext());
+ worker_thread_ = std::make_unique<WorkerThreadForTest>(*reporting_proxy_);
}
void TearDown() override {}
@@ -208,7 +203,6 @@ class WorkerThreadTest : public testing::Test {
EXPECT_CALL(*reporting_proxy_, DidEvaluateClassicScript(true)).Times(1);
EXPECT_CALL(*reporting_proxy_, WillDestroyWorkerGlobalScope()).Times(1);
EXPECT_CALL(*reporting_proxy_, DidTerminateWorkerThread()).Times(1);
- EXPECT_CALL(*lifecycle_observer_, ContextDestroyed(_)).Times(1);
}
void ExpectReportingCallsForWorkerPossiblyTerminatedBeforeInitialization() {
@@ -222,7 +216,6 @@ class WorkerThreadTest : public testing::Test {
EXPECT_CALL(*reporting_proxy_, WillDestroyWorkerGlobalScope())
.Times(AtMost(1));
EXPECT_CALL(*reporting_proxy_, DidTerminateWorkerThread()).Times(1);
- EXPECT_CALL(*lifecycle_observer_, ContextDestroyed(_)).Times(1);
}
void ExpectReportingCallsForWorkerForciblyTerminated() {
@@ -233,7 +226,6 @@ class WorkerThreadTest : public testing::Test {
EXPECT_CALL(*reporting_proxy_, DidEvaluateClassicScript(false)).Times(1);
EXPECT_CALL(*reporting_proxy_, WillDestroyWorkerGlobalScope()).Times(1);
EXPECT_CALL(*reporting_proxy_, DidTerminateWorkerThread()).Times(1);
- EXPECT_CALL(*lifecycle_observer_, ContextDestroyed(_)).Times(1);
}
ExitCode GetExitCode() { return worker_thread_->GetExitCodeForTesting(); }
@@ -241,7 +233,6 @@ class WorkerThreadTest : public testing::Test {
scoped_refptr<const SecurityOrigin> security_origin_;
std::unique_ptr<MockWorkerReportingProxy> reporting_proxy_;
std::unique_ptr<WorkerThreadForTest> worker_thread_;
- Persistent<MockWorkerThreadLifecycleObserver> lifecycle_observer_;
};
TEST_F(WorkerThreadTest, ShouldTerminateScriptExecution) {
@@ -389,7 +380,6 @@ TEST_F(WorkerThreadTest, Terminate_WhileDebuggerTaskIsRunningOnInitialization) {
EXPECT_CALL(*reporting_proxy_, DidInitializeWorkerContext()).Times(1);
EXPECT_CALL(*reporting_proxy_, WillDestroyWorkerGlobalScope()).Times(1);
EXPECT_CALL(*reporting_proxy_, DidTerminateWorkerThread()).Times(1);
- EXPECT_CALL(*lifecycle_observer_, ContextDestroyed(_)).Times(1);
Vector<CSPHeaderAndType> headers{
{"contentSecurityPolicy", kContentSecurityPolicyHeaderTypeReport}};
@@ -398,9 +388,10 @@ TEST_F(WorkerThreadTest, Terminate_WhileDebuggerTaskIsRunningOnInitialization) {
std::make_unique<GlobalScopeCreationParams>(
KURL("http://fake.url/"), ScriptType::kClassic, "fake user agent",
headers, kReferrerPolicyDefault, security_origin_.get(),
- false /* starter_secure_context */, nullptr /* workerClients */,
- mojom::IPAddressSpace::kLocal, nullptr /* originTrialToken */,
- base::UnguessableToken::Create(),
+ false /* starter_secure_context */,
+ CalculateHttpsState(security_origin_.get()),
+ nullptr /* workerClients */, mojom::IPAddressSpace::kLocal,
+ nullptr /* originTrialToken */, base::UnguessableToken::Create(),
std::make_unique<WorkerSettings>(Settings::Create().get()),
kV8CacheOptionsDefault, nullptr /* worklet_module_responses_map */);
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 4e6c5b3b294..d5ffccb9f4e 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
@@ -25,7 +25,6 @@
#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/core/workers/worker_thread_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/network/content_security_policy_parsers.h"
@@ -40,22 +39,6 @@
namespace blink {
-class MockWorkerThreadLifecycleObserver final
- : public GarbageCollectedFinalized<MockWorkerThreadLifecycleObserver>,
- public WorkerThreadLifecycleObserver {
- USING_GARBAGE_COLLECTED_MIXIN(MockWorkerThreadLifecycleObserver);
-
- public:
- explicit MockWorkerThreadLifecycleObserver(
- WorkerThreadLifecycleContext* context)
- : WorkerThreadLifecycleObserver(context) {}
-
- MOCK_METHOD1(ContextDestroyed, void(WorkerThreadLifecycleContext*));
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockWorkerThreadLifecycleObserver);
-};
-
class FakeWorkerGlobalScope : public WorkerGlobalScope {
public:
FakeWorkerGlobalScope(
@@ -85,9 +68,9 @@ class FakeWorkerGlobalScope : public WorkerGlobalScope {
class WorkerThreadForTest : public WorkerThread {
public:
- WorkerThreadForTest(ThreadableLoadingContext* loading_context,
- WorkerReportingProxy& mock_worker_reporting_proxy)
- : WorkerThread(loading_context, mock_worker_reporting_proxy),
+ explicit WorkerThreadForTest(
+ WorkerReportingProxy& mock_worker_reporting_proxy)
+ : WorkerThread(mock_worker_reporting_proxy),
worker_backing_thread_(WorkerBackingThread::Create(
WebThreadCreationParams(WebThreadType::kTestThread))) {}
@@ -109,7 +92,8 @@ class WorkerThreadForTest : public WorkerThread {
auto creation_params = std::make_unique<GlobalScopeCreationParams>(
script_url, ScriptType::kClassic, "fake user agent", headers,
kReferrerPolicyDefault, security_origin,
- false /* starter_secure_context */, worker_clients,
+ false /* starter_secure_context */,
+ CalculateHttpsState(security_origin), worker_clients,
mojom::IPAddressSpace::kLocal, nullptr,
base::UnguessableToken::Create(),
std::make_unique<WorkerSettings>(Settings::Create().get()),
diff --git a/chromium/third_party/blink/renderer/core/workers/worklet.cc b/chromium/third_party/blink/renderer/core/workers/worklet.cc
index 4eabae2562d..6a78f298ef5 100644
--- a/chromium/third_party/blink/renderer/core/workers/worklet.cc
+++ b/chromium/third_party/blink/renderer/core/workers/worklet.cc
@@ -76,9 +76,10 @@ ScriptPromise Worklet::addModule(ScriptState* script_state,
// loading.
GetExecutionContext()
->GetTaskRunner(TaskType::kInternalLoading)
- ->PostTask(FROM_HERE, WTF::Bind(&Worklet::FetchAndInvokeScript,
- WrapPersistent(this), module_url_record,
- options, WrapPersistent(pending_tasks)));
+ ->PostTask(FROM_HERE,
+ WTF::Bind(&Worklet::FetchAndInvokeScript, WrapPersistent(this),
+ module_url_record, options.credentials(),
+ WrapPersistent(pending_tasks)));
return promise;
}
@@ -108,7 +109,7 @@ WorkletGlobalScopeProxy* Worklet::FindAvailableGlobalScope() {
// algorithm:
// https://drafts.css-houdini.org/worklets/#dom-worklet-addmodule
void Worklet::FetchAndInvokeScript(const KURL& module_url_record,
- const WorkletOptions& options,
+ const String& credentials,
WorkletPendingTasks* pending_tasks) {
DCHECK(IsMainThread());
if (!GetExecutionContext())
@@ -116,8 +117,7 @@ void Worklet::FetchAndInvokeScript(const KURL& module_url_record,
// Step 6: "Let credentialOptions be the credentials member of options."
network::mojom::FetchCredentialsMode credentials_mode;
- bool result =
- Request::ParseCredentialsMode(options.credentials(), &credentials_mode);
+ bool result = Request::ParseCredentialsMode(credentials, &credentials_mode);
DCHECK(result);
// Step 7: "Let outsideSettings be the relevant settings object of this."
diff --git a/chromium/third_party/blink/renderer/core/workers/worklet.h b/chromium/third_party/blink/renderer/core/workers/worklet.h
index 06e36dc6761..696843c15d5 100644
--- a/chromium/third_party/blink/renderer/core/workers/worklet.h
+++ b/chromium/third_party/blink/renderer/core/workers/worklet.h
@@ -66,7 +66,7 @@ class CORE_EXPORT Worklet : public ScriptWrappable,
private:
virtual void FetchAndInvokeScript(const KURL& module_url_record,
- const WorkletOptions&,
+ const String& credentials,
WorkletPendingTasks*);
// Returns true if there are no global scopes or additional global scopes are
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 5135d01f291..e1a10f75897 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
@@ -39,7 +39,12 @@ WorkletGlobalScope::WorkletGlobalScope(
user_agent_(creation_params->user_agent),
document_security_origin_(creation_params->starter_origin),
document_secure_context_(creation_params->starter_secure_context),
- module_responses_map_(creation_params->module_responses_map) {
+ module_responses_map_(creation_params->module_responses_map),
+ // Step 4. "Let inheritedHTTPSState be outsideSettings's HTTPS state."
+ https_state_(creation_params->starter_https_state),
+ agent_cluster_id_(creation_params->agent_cluster_id.is_empty()
+ ? base::UnguessableToken::Create()
+ : creation_params->agent_cluster_id) {
// Step 2: "Let inheritedAPIBaseURL be outsideSettings's API base URL."
// |url_| is the inheritedAPIBaseURL passed from the parent Document.
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 c19ef393d82..bdf2e2f141c 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
@@ -50,6 +50,17 @@ class CORE_EXPORT WorkletGlobalScope
String UserAgent() const final { return user_agent_; }
SecurityContext& GetSecurityContext() final { return *this; }
bool IsSecureContext(String& error_message) const final;
+ const base::UnguessableToken& GetAgentClusterID() const final {
+ // Currently, worklet agents have no clearly defined owner. See
+ // https://html.spec.whatwg.org/multipage/webappapis.html#integration-with-the-javascript-agent-cluster-formalism
+ //
+ // However, it is intended that a SharedArrayBuffer can be shared with a
+ // worklet, e.g. the AudioWorklet. If this WorkletGlobalScope's creation
+ // params included an agent cluster ID, we'll assume that this worklet is
+ // in the same agent cluster. See
+ // https://bugs.chromium.org/p/chromium/issues/detail?id=892067.
+ return agent_cluster_id_;
+ }
DOMTimerCoordinator* Timers() final {
// WorkletGlobalScopes don't have timers.
@@ -88,6 +99,8 @@ class CORE_EXPORT WorkletGlobalScope
void Trace(blink::Visitor*) override;
+ HttpsState GetHttpsState() const override { return https_state_; }
+
protected:
// Partial implementation of the "set up a worklet environment settings
// object" algorithm:
@@ -116,6 +129,10 @@ class CORE_EXPORT WorkletGlobalScope
const bool document_secure_context_;
CrossThreadPersistent<WorkletModuleResponsesMap> module_responses_map_;
+
+ const HttpsState https_state_;
+
+ const base::UnguessableToken agent_cluster_id_;
};
DEFINE_TYPE_CASTS(WorkletGlobalScope,
diff --git a/chromium/third_party/blink/renderer/core/workers/worklet_thread_holder.h b/chromium/third_party/blink/renderer/core/workers/worklet_thread_holder.h
index 2c783faca90..4da9d4551a2 100644
--- a/chromium/third_party/blink/renderer/core/workers/worklet_thread_holder.h
+++ b/chromium/third_party/blink/renderer/core/workers/worklet_thread_holder.h
@@ -98,13 +98,13 @@ class WorkletThreadHolder {
WaitableEvent waitable_event;
thread_->BackingThread().PostTask(
FROM_HERE,
- CrossThreadBind(&WorkletThreadHolder::ShutdownOnWorlketThread,
+ CrossThreadBind(&WorkletThreadHolder::ShutdownOnWorkletThread,
CrossThreadUnretained(this),
CrossThreadUnretained(&waitable_event)));
waitable_event.Wait();
}
- void ShutdownOnWorlketThread(WaitableEvent* waitable_event) {
+ void ShutdownOnWorkletThread(WaitableEvent* waitable_event) {
thread_->ShutdownOnBackingThread();
waitable_event->Signal();
}
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 b322ad3ac99..5b9e53b5a97 100644
--- a/chromium/third_party/blink/renderer/core/xml/dom_parser.cc
+++ b/chromium/third_party/blink/renderer/core/xml/dom_parser.cc
@@ -32,21 +32,12 @@ namespace blink {
Document* DOMParser::parseFromString(const StringOrTrustedHTML& stringOrHTML,
const String& type,
ExceptionState& exception_state) {
- DCHECK(stringOrHTML.IsString() ||
- RuntimeEnabledFeatures::TrustedDOMTypesEnabled());
- DCHECK(!stringOrHTML.IsNull());
- if (context_document_ && stringOrHTML.IsString() &&
- context_document_->RequireTrustedTypes()) {
- exception_state.ThrowTypeError(
- "This document requires `TrustedHTML` assignment.");
- return nullptr;
+ String value =
+ TrustedHTML::GetString(stringOrHTML, context_document_, exception_state);
+ if (!exception_state.HadException()) {
+ return parseFromStringInternal(value, type);
}
-
- String valueString = stringOrHTML.IsString()
- ? stringOrHTML.GetAsString()
- : stringOrHTML.GetAsTrustedHTML()->toString();
-
- return parseFromStringInternal(valueString, type);
+ return nullptr;
}
Document* DOMParser::parseFromStringInternal(const String& str,
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 e245e40d55c..5880f2a21f3 100644
--- a/chromium/third_party/blink/renderer/core/xml/xpath_parser.h
+++ b/chromium/third_party/blink/renderer/core/xml/xpath_parser.h
@@ -46,6 +46,8 @@ class Parser;
struct Token {
STACK_ALLOCATED();
+
+ public:
int type;
String str;
Step::Axis axis;
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 bf18794d9a6..59349d62453 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
@@ -227,7 +227,8 @@ void XSLStyleSheet::LoadChildSheet(const String& href) {
fetch_options.initiator_info.name = FetchInitiatorTypeNames::xml;
FetchParameters params(
ResourceRequest(OwnerDocument()->CompleteURL(url_string)), fetch_options);
- params.SetOriginRestriction(FetchParameters::kRestrictToSameOrigin);
+ params.MutableResourceRequest().SetFetchRequestMode(
+ network::mojom::FetchRequestMode::kSameOrigin);
XSLStyleSheetResource* resource = XSLStyleSheetResource::FetchSynchronously(
params, OwnerDocument()->Fetcher());
if (!resource->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 b59f7fc0cff..c421ca1189f 100644
--- a/chromium/third_party/blink/renderer/core/xml/xslt_processor.cc
+++ b/chromium/third_party/blink/renderer/core/xml/xslt_processor.cc
@@ -70,7 +70,11 @@ Document* XSLTProcessor::CreateDocumentFromSource(
if (owner_document == source_node)
url = owner_document->Url();
- DocumentInit init = DocumentInit::Create().WithFrame(frame).WithURL(url);
+ DocumentInit init =
+ DocumentInit::Create()
+ .WithDocumentLoader(frame ? frame->Loader().GetDocumentLoader()
+ : nullptr)
+ .WithURL(url);
String document_source = source_string;
bool force_xhtml = source_mime_type == "text/plain";
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 bb879481ed5..1a0862042a4 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
@@ -109,7 +109,6 @@ static xmlDocPtr DocLoaderFunc(const xmlChar* uri,
ResourceLoaderOptions fetch_options;
fetch_options.initiator_info.name = FetchInitiatorTypeNames::xml;
FetchParameters params(ResourceRequest(url), fetch_options);
- params.SetOriginRestriction(FetchParameters::kRestrictToSameOrigin);
params.MutableResourceRequest().SetFetchRequestMode(
network::mojom::FetchRequestMode::kSameOrigin);
Resource* resource =
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 bebe41442b7..c35bbd7e1c0 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
@@ -477,7 +477,7 @@ void XMLHttpRequest::setTimeout(unsigned timeout,
return;
}
- timeout_milliseconds_ = timeout;
+ timeout_ = TimeDelta::FromMilliseconds(timeout);
// From http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute:
// Note: This implies that the timeout attribute can be set while fetching is
@@ -486,7 +486,7 @@ void XMLHttpRequest::setTimeout(unsigned timeout,
//
// The timeout may be overridden after send.
if (loader_)
- loader_->OverrideTimeout(timeout);
+ loader_->SetTimeout(timeout_);
}
void XMLHttpRequest::setResponseType(const String& response_type,
@@ -686,7 +686,7 @@ void XMLHttpRequest::open(const AtomicString& method,
}
// Similarly, timeouts are disabled for synchronous requests as well.
- if (timeout_milliseconds_ > 0) {
+ if (!timeout_.is_zero()) {
exception_state.ThrowDOMException(
DOMExceptionCode::kInvalidAccessError,
"Synchronous requests must not set a timeout.");
@@ -747,7 +747,8 @@ bool XMLHttpRequest::InitSend(ExceptionState& exception_state) {
if (!async_) {
if (GetExecutionContext()->IsDocument() &&
!GetDocument()->GetFrame()->IsFeatureEnabled(
- mojom::FeaturePolicyFeature::kSyncXHR)) {
+ mojom::FeaturePolicyFeature::kSyncXHR,
+ ReportOptions::kReportOnFailure)) {
LogConsoleError(GetExecutionContext(),
"Synchronous requests are disabled by Feature Policy.");
HandleNetworkError();
@@ -827,12 +828,10 @@ void XMLHttpRequest::send(Document* document, ExceptionState& exception_state) {
scoped_refptr<EncodedFormData> http_body;
if (AreMethodAndURLValidForSend()) {
- // FIXME: Per https://xhr.spec.whatwg.org/#dom-xmlhttprequest-send the
- // Content-Type header and whether to serialize as HTML or XML should
- // depend on |document->isHTMLDocument()|.
- if (!HasContentTypeRequestHeader())
- SetRequestHeaderInternal(HTTPNames::Content_Type,
- "application/xml;charset=UTF-8");
+ if (document->IsHTMLDocument())
+ UpdateContentTypeAndCharset("text/html;charset=UTF-8", "UTF-8");
+ else if (document->IsXMLDocument())
+ UpdateContentTypeAndCharset("application/xml;charset=UTF-8", "UTF-8");
String body = CreateMarkup(document);
@@ -1028,7 +1027,7 @@ void XMLHttpRequest::CreateRequest(scoped_refptr<EncodedFormData> http_body,
if (http_body && upload_) {
upload_events = upload_->HasEventListeners();
upload_->DispatchEvent(
- ProgressEvent::Create(EventTypeNames::loadstart, false, 0, 0));
+ *ProgressEvent::Create(EventTypeNames::loadstart, false, 0, 0));
// See above.
if (!send_flag_ || loader_)
return;
@@ -1074,9 +1073,6 @@ void XMLHttpRequest::CreateRequest(scoped_refptr<EncodedFormData> http_body,
if (request_headers_.size() > 0)
request.AddHTTPHeaderFields(request_headers_);
- ThreadableLoaderOptions options;
- options.timeout_milliseconds = timeout_milliseconds_;
-
ResourceLoaderOptions resource_loader_options;
resource_loader_options.security_origin = GetSecurityOrigin();
resource_loader_options.initiator_info.name =
@@ -1124,29 +1120,29 @@ void XMLHttpRequest::CreateRequest(scoped_refptr<EncodedFormData> http_body,
// TODO(yhirano): Turn this CHECK into DCHECK: see https://crbug.com/570946.
CHECK(!loader_);
DCHECK(send_flag_);
- loader_ = ThreadableLoader::Create(execution_context, this, options,
- resource_loader_options);
- loader_->Start(request);
-
- return;
- }
-
- // Use count for XHR synchronous requests.
- UseCounter::Count(&execution_context, WebFeature::kXMLHttpRequestSynchronous);
- if (GetExecutionContext()->IsDocument()) {
- // Update histogram for usage of sync xhr within pagedismissal.
- auto pagedismissal = GetDocument()->PageDismissalEventBeingDispatched();
- if (pagedismissal != Document::kNoDismissal) {
- UseCounter::Count(GetDocument(), WebFeature::kSyncXhrInPageDismissal);
- DEFINE_STATIC_LOCAL(EnumerationHistogram, syncxhr_pagedismissal_histogram,
- ("XHR.Sync.PageDismissal", 5));
- syncxhr_pagedismissal_histogram.Count(pagedismissal);
+ } else {
+ // Use count for XHR synchronous requests.
+ UseCounter::Count(&execution_context, WebFeature::kXMLHttpRequestSynchronous);
+ if (GetExecutionContext()->IsDocument()) {
+ // Update histogram for usage of sync xhr within pagedismissal.
+ auto pagedismissal = GetDocument()->PageDismissalEventBeingDispatched();
+ if (pagedismissal != Document::kNoDismissal) {
+ UseCounter::Count(GetDocument(), WebFeature::kSyncXhrInPageDismissal);
+ DEFINE_STATIC_LOCAL(EnumerationHistogram, syncxhr_pagedismissal_histogram,
+ ("XHR.Sync.PageDismissal", 5));
+ syncxhr_pagedismissal_histogram.Count(pagedismissal);
+ }
}
+ resource_loader_options.synchronous_policy = kRequestSynchronously;
}
- ThreadableLoader::LoadResourceSynchronously(execution_context, request, *this,
- options, resource_loader_options);
- ThrowForLoadFailureIfNeeded(exception_state, String());
+ loader_ = new ThreadableLoader(execution_context, this,
+ resource_loader_options);
+ loader_->SetTimeout(timeout_);
+ loader_->Start(request);
+
+ if (!async_)
+ ThrowForLoadFailureIfNeeded(exception_state, String());
}
void XMLHttpRequest::abort() {
@@ -1223,7 +1219,7 @@ bool XMLHttpRequest::InternalAbort() {
if (!loader_)
return true;
- // Cancelling the ThreadableLoader m_loader may result in calling
+ // Cancelling the ThreadableLoader loader_ may result in calling
// window.onload synchronously. If such an onload handler contains open()
// call on the same XMLHttpRequest object, reentry happens.
//
@@ -1545,7 +1541,7 @@ void XMLHttpRequest::UpdateContentTypeAndCharset(
// http://xhr.spec.whatwg.org/#the-send()-method step 4's concilliation of
// "charset=" in any author-provided Content-Type: request header.
String content_type = request_headers_.Get(HTTPNames::Content_Type);
- if (content_type.IsEmpty()) {
+ if (content_type.IsNull()) {
SetRequestHeaderInternal(HTTPNames::Content_Type, default_content_type);
return;
}
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 479cac9f6c3..81175c12081 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
@@ -151,7 +151,7 @@ class XMLHttpRequest final : public XMLHttpRequestEventTarget,
Document* responseXML(ExceptionState&);
Blob* ResponseBlob();
DOMArrayBuffer* ResponseArrayBuffer();
- unsigned timeout() const { return timeout_milliseconds_; }
+ unsigned timeout() const { return timeout_.InMilliseconds(); }
void setTimeout(unsigned timeout, ExceptionState&);
ResponseTypeCode GetResponseTypeCode() const { return response_type_code_; }
String responseType();
@@ -311,7 +311,7 @@ class XMLHttpRequest final : public XMLHttpRequestEventTarget,
// Not converted to ASCII lowercase. Must be lowered later or compared
// using case insensitive comparison functions if needed.
AtomicString mime_type_override_;
- unsigned long timeout_milliseconds_ = 0;
+ TimeDelta timeout_;
TraceWrapperMember<Blob> response_blob_;
Member<ThreadableLoader> loader_;
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 c4ccc751976..d7cc325a65d 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
@@ -96,7 +96,7 @@ void XMLHttpRequestProgressEventThrottle::DispatchProgressEvent(
// we don't have to worry about event dispatching while suspended.
if (type != EventTypeNames::progress) {
target_->DispatchEvent(
- ProgressEvent::Create(type, length_computable, loaded, total));
+ *ProgressEvent::Create(type, length_computable, loaded, total));
return;
}
@@ -133,7 +133,7 @@ void XMLHttpRequestProgressEventThrottle::DispatchReadyStateChangeEvent(
// readystatechange should have been already dispatched if necessary.
probe::AsyncTask async_task(target_->GetExecutionContext(), target_,
"progress", target_->IsAsync());
- target_->DispatchEvent(event);
+ target_->DispatchEvent(*event);
}
}
@@ -147,7 +147,7 @@ void XMLHttpRequestProgressEventThrottle::DispatchProgressProgressEvent(
target_->GetExecutionContext(), target_));
probe::AsyncTask async_task(target_->GetExecutionContext(), target_,
"progress", target_->IsAsync());
- target_->DispatchEvent(Event::Create(EventTypeNames::readystatechange));
+ target_->DispatchEvent(*Event::Create(EventTypeNames::readystatechange));
}
if (target_->readyState() != state)
@@ -156,7 +156,7 @@ void XMLHttpRequestProgressEventThrottle::DispatchProgressProgressEvent(
has_dispatched_progress_progress_event_ = true;
probe::AsyncTask async_task(target_->GetExecutionContext(), target_,
"progress", target_->IsAsync());
- target_->DispatchEvent(progress_event);
+ target_->DispatchEvent(*progress_event);
}
void XMLHttpRequestProgressEventThrottle::Fired() {
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 bded997a569..7eef081acea 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
@@ -53,8 +53,8 @@ void XMLHttpRequestUpload::DispatchProgressEvent(
last_total_bytes_to_be_sent_ = total_bytes_to_be_sent;
probe::AsyncTask async_task(GetExecutionContext(), xml_http_request_,
"progress", xml_http_request_->IsAsync());
- DispatchEvent(ProgressEvent::Create(EventTypeNames::progress, true,
- bytes_sent, total_bytes_to_be_sent));
+ DispatchEvent(*ProgressEvent::Create(EventTypeNames::progress, true,
+ bytes_sent, total_bytes_to_be_sent));
}
void XMLHttpRequestUpload::DispatchEventAndLoadEnd(
@@ -67,9 +67,9 @@ void XMLHttpRequestUpload::DispatchEventAndLoadEnd(
probe::AsyncTask async_task(GetExecutionContext(), xml_http_request_, "event",
xml_http_request_->IsAsync());
DispatchEvent(
- ProgressEvent::Create(type, length_computable, bytes_sent, total));
- DispatchEvent(ProgressEvent::Create(EventTypeNames::loadend,
- length_computable, bytes_sent, total));
+ *ProgressEvent::Create(type, length_computable, bytes_sent, total));
+ DispatchEvent(*ProgressEvent::Create(EventTypeNames::loadend,
+ length_computable, bytes_sent, total));
}
void XMLHttpRequestUpload::HandleRequestError(const AtomicString& type) {
@@ -77,9 +77,9 @@ void XMLHttpRequestUpload::HandleRequestError(const AtomicString& type) {
last_bytes_sent_ <= last_total_bytes_to_be_sent_;
probe::AsyncTask async_task(GetExecutionContext(), xml_http_request_, "error",
xml_http_request_->IsAsync());
- DispatchEvent(ProgressEvent::Create(EventTypeNames::progress,
- length_computable, last_bytes_sent_,
- last_total_bytes_to_be_sent_));
+ DispatchEvent(*ProgressEvent::Create(EventTypeNames::progress,
+ length_computable, last_bytes_sent_,
+ last_total_bytes_to_be_sent_));
DispatchEventAndLoadEnd(type, length_computable, last_bytes_sent_,
last_total_bytes_to_be_sent_);
}
diff --git a/chromium/third_party/blink/renderer/devtools/BUILD.gn b/chromium/third_party/blink/renderer/devtools/BUILD.gn
index e21a157ae92..a3b41d2ce8b 100644
--- a/chromium/third_party/blink/renderer/devtools/BUILD.gn
+++ b/chromium/third_party/blink/renderer/devtools/BUILD.gn
@@ -87,8 +87,6 @@ all_devtools_files = [
"front_end/bindings_test_runner/module.json",
"front_end/bindings_test_runner/PersistenceTestRunner.js",
"front_end/bindings_test_runner/OverridesTestRunner.js",
- "front_end/browser_components/ImagePreview.js",
- "front_end/browser_components/imagePreview.css",
"front_end/browser_console/BrowserConsole.js",
"front_end/browser_console/module.json",
"front_end/browser_debugger/DOMBreakpointsSidebarPane.js",
@@ -99,9 +97,7 @@ all_devtools_files = [
"front_end/browser_debugger/eventListenerBreakpoints.css",
"front_end/browser_debugger/module.json",
"front_end/browser_debugger/xhrBreakpointsSidebarPane.css",
- "front_end/browser_sdk/HAREntry.js",
"front_end/browser_sdk/LogManager.js",
- "front_end/browser_sdk/NetworkLog.js",
"front_end/browser_sdk/module.json",
"front_end/changes/ChangesHighlighter.js",
"front_end/changes/changesView.css",
@@ -164,6 +160,8 @@ all_devtools_files = [
"front_end/common/UIString.js",
"front_end/common/Worker.js",
"front_end/components/DockController.js",
+ "front_end/components/ImagePreview.js",
+ "front_end/components/imagePreview.css",
"front_end/components/JSPresentationUtils.js",
"front_end/components/Linkifier.js",
"front_end/components/TargetDetachedDialog.js",
@@ -179,6 +177,7 @@ all_devtools_files = [
"front_end/console/consoleView.css",
"front_end/console/consoleContextSelector.css",
"front_end/console/consolePinPane.css",
+ "front_end/console/consolePrompt.css",
"front_end/console/consoleSidebar.css",
"front_end/console/ConsoleView.js",
"front_end/console/ConsoleViewMessage.js",
@@ -449,6 +448,7 @@ all_devtools_files = [
"front_end/object_ui/customPreviewComponent.css",
"front_end/object_ui/CustomPreviewComponent.js",
"front_end/object_ui/JavaScriptAutocomplete.js",
+ "front_end/object_ui/JavaScriptREPL.js",
"front_end/object_ui/module.json",
"front_end/object_ui/objectPopover.css",
"front_end/object_ui/ObjectPopoverHelper.js",
@@ -490,6 +490,7 @@ all_devtools_files = [
"front_end/persistence/Persistence.js",
"front_end/persistence/PersistenceActions.js",
"front_end/persistence/PersistenceUtils.js",
+ "front_end/persistence/PlatformFileSystem.js",
"front_end/persistence/workspaceSettingsTab.css",
"front_end/persistence/WorkspaceSettingsTab.js",
"front_end/platform/module.json",
@@ -588,10 +589,12 @@ all_devtools_files = [
"front_end/sdk/DOMModel.js",
"front_end/sdk/EmulationModel.js",
"front_end/sdk/FilmStripModel.js",
+ "front_end/sdk/HARLog.js",
"front_end/sdk/HeapProfilerModel.js",
"front_end/sdk/LayerTreeBase.js",
"front_end/sdk/LogModel.js",
"front_end/sdk/module.json",
+ "front_end/sdk/NetworkLog.js",
"front_end/sdk/NetworkManager.js",
"front_end/sdk/NetworkRequest.js",
"front_end/sdk/OverlayModel.js",
@@ -637,9 +640,8 @@ all_devtools_files = [
"front_end/settings/settingsScreen.css",
"front_end/settings/SettingsScreen.js",
"front_end/snippets/module.json",
- "front_end/snippets/ScriptSnippetModel.js",
+ "front_end/snippets/ScriptSnippetFileSystem.js",
"front_end/snippets/SnippetsQuickOpen.js",
- "front_end/snippets/SnippetStorage.js",
"front_end/source_frame/fontView.css",
"front_end/source_frame/FontView.js",
"front_end/source_frame/imageView.css",
@@ -684,6 +686,7 @@ all_devtools_files = [
"front_end/sources/scopeChainSidebarPane.css",
"front_end/sources/ScopeChainSidebarPane.js",
"front_end/sources/ScriptFormatterEditorAction.js",
+ "front_end/sources/ScriptOriginPlugin.js",
"front_end/sources/SearchSourcesView.js",
"front_end/sources/serviceWorkersSidebar.css",
"front_end/sources/SimpleHistoryManager.js",
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/Images/whatsnew.png b/chromium/third_party/blink/renderer/devtools/front_end/Images/whatsnew.png
index fd0ab7ae41e..4dcaa26a841 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/Images/whatsnew.png
+++ b/chromium/third_party/blink/renderer/devtools/front_end/Images/whatsnew.png
Binary files differ
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/OWNERS b/chromium/third_party/blink/renderer/devtools/front_end/OWNERS
index 12637c58cc4..f31f5664378 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/OWNERS
+++ b/chromium/third_party/blink/renderer/devtools/front_end/OWNERS
@@ -1,5 +1,7 @@
alph@chromium.org
caseq@chromium.org
dgozman@chromium.org
+einbinder@chromium.org
+luoe@chromium.org
lushnikov@chromium.org
pfeldman@chromium.org
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/Runtime.js b/chromium/third_party/blink/renderer/devtools/front_end/Runtime.js
index f48f9e4c6cf..5e6e5f1a0eb 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/Runtime.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/Runtime.js
@@ -971,7 +971,10 @@ Runtime.ExperimentsSupport = class {
*/
isEnabled(experimentName) {
this._checkExperiment(experimentName);
-
+ // Check for explicitly disabled experiments first - the code could call setEnable(false) on the experiment enabled
+ // by default and we should respect that.
+ if (Runtime._experimentsSetting()[experimentName] === false)
+ return false;
if (this._enabledTransiently[experimentName])
return true;
if (!this.supportEnabled())
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/audits2/Audits2ProtocolService.js b/chromium/third_party/blink/renderer/devtools/front_end/audits2/Audits2ProtocolService.js
index 99c2b816302..3d3e6759cc2 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/audits2/Audits2ProtocolService.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/audits2/Audits2ProtocolService.js
@@ -74,7 +74,7 @@ Audits2.ProtocolService = class extends Common.Object {
* @param {string} message
*/
_sendProtocolMessage(message) {
- this._rawConnection.sendMessage(message);
+ this._rawConnection.sendRawMessage(message);
}
/**
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/audits2/Audits2StatusView.js b/chromium/third_party/blink/renderer/devtools/front_end/audits2/Audits2StatusView.js
index 3198f953edd..52e44fb27fa 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/audits2/Audits2StatusView.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/audits2/Audits2StatusView.js
@@ -285,7 +285,7 @@ Audits2.StatusView.StatusPhases = [
{
id: 'auditing',
progressBarClass: 'auditing',
- message: 'Almost there! Lighthouse is now generating your own special pretty report!',
+ message: 'Almost there! Lighthouse is now generating your report.',
statusMessagePrefix: 'Evaluating',
order: 30,
}
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/bindings/BlackboxManager.js b/chromium/third_party/blink/renderer/devtools/front_end/bindings/BlackboxManager.js
index f8f4face142..0e6aab390f3 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/bindings/BlackboxManager.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/bindings/BlackboxManager.js
@@ -13,17 +13,13 @@ Bindings.BlackboxManager = class {
this._debuggerWorkspaceBinding = debuggerWorkspaceBinding;
SDK.targetManager.addModelListener(
- SDK.DebuggerModel, SDK.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this);
- SDK.targetManager.addModelListener(
- SDK.DebuggerModel, SDK.DebuggerModel.Events.GlobalObjectCleared, this._globalObjectCleared, this);
+ SDK.DebuggerModel, SDK.DebuggerModel.Events.GlobalObjectCleared, this._clearCacheIfNeeded.bind(this), this);
Common.moduleSetting('skipStackFramesPattern').addChangeListener(this._patternChanged.bind(this));
Common.moduleSetting('skipContentScripts').addChangeListener(this._patternChanged.bind(this));
/** @type {!Set<function()>} */
this._listeners = new Set();
- /** @type {!Map<!SDK.DebuggerModel, !Map<string, !Array<!Protocol.Debugger.ScriptPosition>>>} */
- this._debuggerModelData = new Map();
/** @type {!Map<string, boolean>} */
this._isBlackboxedURLCache = new Map();
@@ -50,6 +46,9 @@ Bindings.BlackboxManager = class {
*/
modelAdded(debuggerModel) {
this._setBlackboxPatterns(debuggerModel);
+ const sourceMapManager = debuggerModel.sourceMapManager();
+ sourceMapManager.addEventListener(SDK.SourceMapManager.Events.SourceMapAttached, this._sourceMapAttached, this);
+ sourceMapManager.addEventListener(SDK.SourceMapManager.Events.SourceMapDetached, this._sourceMapDetached, this);
}
/**
@@ -57,8 +56,15 @@ Bindings.BlackboxManager = class {
* @param {!SDK.DebuggerModel} debuggerModel
*/
modelRemoved(debuggerModel) {
- this._debuggerModelData.delete(debuggerModel);
- this._isBlackboxedURLCache.clear();
+ this._clearCacheIfNeeded();
+ const sourceMapManager = debuggerModel.sourceMapManager();
+ sourceMapManager.removeEventListener(SDK.SourceMapManager.Events.SourceMapAttached, this._sourceMapAttached, this);
+ sourceMapManager.removeEventListener(SDK.SourceMapManager.Events.SourceMapDetached, this._sourceMapDetached, this);
+ }
+
+ _clearCacheIfNeeded() {
+ if (this._isBlackboxedURLCache.size > 1024)
+ this._isBlackboxedURLCache.clear();
}
/**
@@ -76,32 +82,6 @@ Bindings.BlackboxManager = class {
}
/**
- * @param {!SDK.DebuggerModel.Location} location
- * @return {boolean}
- */
- isBlackboxedRawLocation(location) {
- const script = location.script();
- if (!script)
- return false;
- const positions = this._scriptPositions(script);
- if (!positions)
- return this._isBlackboxedScript(script);
- const index = positions.lowerBound(location, comparator);
- return !!(index % 2);
-
- /**
- * @param {!SDK.DebuggerModel.Location} a
- * @param {!Protocol.Debugger.ScriptPosition} b
- * @return {number}
- */
- function comparator(a, b) {
- if (a.lineNumber !== b.lineNumber)
- return a.lineNumber - b.lineNumber;
- return a.columnNumber - b.columnNumber;
- }
- }
-
- /**
* @param {!Workspace.UISourceCode} uiSourceCode
* @return {boolean}
*/
@@ -125,57 +105,76 @@ Bindings.BlackboxManager = class {
if (isContentScript && Common.moduleSetting('skipContentScripts').get())
return true;
const regex = Common.moduleSetting('skipStackFramesPattern').asRegExp();
- const isBlackboxed = regex && regex.test(url);
+ const isBlackboxed = (regex && regex.test(url)) || false;
this._isBlackboxedURLCache.set(url, isBlackboxed);
return isBlackboxed;
}
/**
+ * @param {!Common.Event} event
+ */
+ _sourceMapAttached(event) {
+ const script = /** @type {!SDK.Script} */ (event.data.client);
+ const sourceMap = /** @type {!SDK.SourceMap} */ (event.data.sourceMap);
+ this._updateScriptRanges(script, sourceMap);
+ }
+
+ /**
+ * @param {!Common.Event} event
+ */
+ _sourceMapDetached(event) {
+ const script = /** @type {!SDK.Script} */ (event.data.client);
+ this._updateScriptRanges(script, null);
+ }
+
+ /**
* @param {!SDK.Script} script
* @param {?SDK.SourceMap} sourceMap
* @return {!Promise<undefined>}
*/
- sourceMapLoaded(script, sourceMap) {
- if (!sourceMap)
- return Promise.resolve();
- const previousScriptState = this._scriptPositions(script);
- if (!previousScriptState)
- return Promise.resolve();
-
- const hasBlackboxedMappings = sourceMap.sourceURLs().some(url => this.isBlackboxedURL(url));
- const mappings = hasBlackboxedMappings ? sourceMap.mappings().slice() : [];
- if (!mappings.length) {
- if (previousScriptState.length > 0)
- return this._setScriptState(script, []);
- return Promise.resolve();
+ async _updateScriptRanges(script, sourceMap) {
+ let hasBlackboxedMappings = false;
+ if (!Bindings.blackboxManager.isBlackboxedURL(script.sourceURL, script.isContentScript()))
+ hasBlackboxedMappings = sourceMap ? sourceMap.sourceURLs().some(url => this.isBlackboxedURL(url)) : false;
+ if (!hasBlackboxedMappings) {
+ if (script[Bindings.BlackboxManager._blackboxedRanges] && await script.setBlackboxedRanges([]))
+ delete script[Bindings.BlackboxManager._blackboxedRanges];
+ this._debuggerWorkspaceBinding.updateLocations(script);
+ return;
}
- mappings.sort(mappingComparator);
+ const mappings = sourceMap.mappings();
+ const newRanges = [];
let currentBlackboxed = false;
- let isBlackboxed = false;
- const positions = [];
- // If content in script file begin is not mapped and one or more ranges are blackboxed then blackbox it.
if (mappings[0].lineNumber !== 0 || mappings[0].columnNumber !== 0) {
- positions.push({lineNumber: 0, columnNumber: 0});
+ newRanges.push({lineNumber: 0, columnNumber: 0});
currentBlackboxed = true;
}
for (const mapping of mappings) {
if (mapping.sourceURL && currentBlackboxed !== this.isBlackboxedURL(mapping.sourceURL)) {
- positions.push({lineNumber: mapping.lineNumber, columnNumber: mapping.columnNumber});
+ newRanges.push({lineNumber: mapping.lineNumber, columnNumber: mapping.columnNumber});
currentBlackboxed = !currentBlackboxed;
}
- isBlackboxed = currentBlackboxed || isBlackboxed;
}
- return this._setScriptState(script, !isBlackboxed ? [] : positions);
+
+ const oldRanges = script[Bindings.BlackboxManager._blackboxedRanges] || [];
+ if (!isEqual(oldRanges, newRanges) && await script.setBlackboxedRanges(newRanges))
+ script[Bindings.BlackboxManager._blackboxedRanges] = newRanges;
+ this._debuggerWorkspaceBinding.updateLocations(script);
+
/**
- * @param {!SDK.SourceMapEntry} a
- * @param {!SDK.SourceMapEntry} b
- * @return {number}
+ * @param {!Array<!{lineNumber: number, columnNumber: number}>} rangesA
+ * @param {!Array<!{lineNumber: number, columnNumber: number}>} rangesB
+ * @return {boolean}
*/
- function mappingComparator(a, b) {
- if (a.lineNumber !== b.lineNumber)
- return a.lineNumber - b.lineNumber;
- return a.columnNumber - b.columnNumber;
+ function isEqual(rangesA, rangesB) {
+ if (rangesA.length !== rangesB.length)
+ return false;
+ for (let i = 0; i < rangesA.length; ++i) {
+ if (rangesA[i].lineNumber !== rangesB[i].lineNumber || rangesA[i].columnNumber !== rangesB[i].columnNumber)
+ return false;
+ }
+ return true;
}
}
@@ -269,31 +268,22 @@ Bindings.BlackboxManager = class {
Common.moduleSetting('skipStackFramesPattern').setAsArray(regexPatterns);
}
- _patternChanged() {
+ async _patternChanged() {
this._isBlackboxedURLCache.clear();
/** @type {!Array<!Promise>} */
const promises = [];
for (const debuggerModel of SDK.targetManager.models(SDK.DebuggerModel)) {
promises.push(this._setBlackboxPatterns(debuggerModel));
+ const sourceMapManager = debuggerModel.sourceMapManager();
for (const script of debuggerModel.scripts())
- promises.push(this._addScript(script).then(loadSourceMap.bind(this, script)));
- }
- Promise.all(promises).then(() => {
- const listeners = Array.from(this._listeners);
- for (const listener of listeners)
- listener();
- this._patternChangeFinishedForTests();
- });
-
- /**
- * @param {!SDK.Script} script
- * @return {!Promise<undefined>}
- * @this {Bindings.BlackboxManager}
- */
- function loadSourceMap(script) {
- return this.sourceMapLoaded(script, this._debuggerWorkspaceBinding.sourceMapForScript(script));
+ promises.push(this._updateScriptRanges(script, sourceMapManager.sourceMapForClient(script)));
}
+ await Promise.all(promises);
+ const listeners = Array.from(this._listeners);
+ for (const listener of listeners)
+ listener();
+ this._patternChangeFinishedForTests();
}
_patternChangeFinishedForTests() {
@@ -301,105 +291,6 @@ Bindings.BlackboxManager = class {
}
/**
- * @param {!Common.Event} event
- */
- _globalObjectCleared(event) {
- const debuggerModel = /** @type {!SDK.DebuggerModel} */ (event.data);
- this._debuggerModelData.delete(debuggerModel);
- this._isBlackboxedURLCache.clear();
- }
-
- /**
- * @param {!Common.Event} event
- */
- _parsedScriptSource(event) {
- const script = /** @type {!SDK.Script} */ (event.data);
- this._addScript(script);
- }
-
- /**
- * @param {!SDK.Script} script
- * @return {!Promise<undefined>}
- */
- _addScript(script) {
- if (!script.sourceURL && !script.sourceMapURL)
- return Promise.resolve();
- const blackboxed = this._isBlackboxedScript(script);
- return this._setScriptState(script, blackboxed ? [{lineNumber: 0, columnNumber: 0}] : []);
- }
-
- /**
- * @param {!SDK.Script} script
- * @return {boolean}
- */
- _isBlackboxedScript(script) {
- return this.isBlackboxedURL(script.sourceURL, script.isContentScript());
- }
-
- /**
- * @param {!SDK.Script} script
- * @return {?Array<!Protocol.Debugger.ScriptPosition>}
- */
- _scriptPositions(script) {
- if (this._debuggerModelData.has(script.debuggerModel))
- return this._debuggerModelData.get(script.debuggerModel).get(script.scriptId) || null;
- return null;
- }
-
- /**
- * @param {!SDK.Script} script
- * @param {!Array<!Protocol.Debugger.ScriptPosition>} positions
- */
- _setScriptPositions(script, positions) {
- const debuggerModel = script.debuggerModel;
- if (!this._debuggerModelData.has(debuggerModel))
- this._debuggerModelData.set(debuggerModel, new Map());
- this._debuggerModelData.get(debuggerModel).set(script.scriptId, positions);
- }
-
- /**
- * @param {!SDK.Script} script
- * @param {!Array<!Protocol.Debugger.ScriptPosition>} positions
- * @return {!Promise<undefined>}
- */
- _setScriptState(script, positions) {
- const previousScriptState = this._scriptPositions(script);
- if (previousScriptState) {
- let hasChanged = false;
- hasChanged = previousScriptState.length !== positions.length;
- for (let i = 0; !hasChanged && i < positions.length; ++i) {
- hasChanged = positions[i].lineNumber !== previousScriptState[i].lineNumber ||
- positions[i].columnNumber !== previousScriptState[i].columnNumber;
- }
- if (!hasChanged)
- return Promise.resolve();
- } else {
- if (positions.length === 0)
- return Promise.resolve().then(updateState.bind(this, false));
- }
-
- return script.setBlackboxedRanges(positions).then(updateState.bind(this));
-
- /**
- * @param {boolean} success
- * @this {Bindings.BlackboxManager}
- */
- function updateState(success) {
- if (success) {
- this._setScriptPositions(script, positions);
- this._debuggerWorkspaceBinding.updateLocations(script);
- const isBlackboxed = positions.length !== 0;
- if (!isBlackboxed && script.sourceMapURL)
- this._debuggerWorkspaceBinding.maybeLoadSourceMap(script);
- } else {
- const hasPositions = !!this._scriptPositions(script);
- if (!hasPositions)
- this._setScriptPositions(script, []);
- }
- }
- }
-
- /**
* @param {string} url
* @return {string}
*/
@@ -430,5 +321,7 @@ Bindings.BlackboxManager = class {
}
};
+Bindings.BlackboxManager._blackboxedRanges = Symbol('blackboxedRanged');
+
/** @type {!Bindings.BlackboxManager} */
Bindings.blackboxManager;
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/bindings/BreakpointManager.js b/chromium/third_party/blink/renderer/devtools/front_end/bindings/BreakpointManager.js
index d57b5ff054d..2230513c879 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/bindings/BreakpointManager.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/bindings/BreakpointManager.js
@@ -43,14 +43,12 @@ Bindings.BreakpointManager = class extends Common.Object {
this._targetManager = targetManager;
this._debuggerWorkspaceBinding = debuggerWorkspaceBinding;
- /** @type {!Map<!Workspace.UISourceCode, !Map<number, !Map<number, !Array<!Bindings.BreakpointManager.Breakpoint>>>>} */
+ /** @type {!Map<!Workspace.UISourceCode, !Map<string, !Bindings.BreakpointManager.BreakpointLocation>>} */
this._breakpointsForUISourceCode = new Map();
/** @type {!Map<string, !Bindings.BreakpointManager.Breakpoint>} */
this._breakpointByStorageId = new Map();
- this._workspace.addEventListener(Workspace.Workspace.Events.ProjectRemoved, this._projectRemoved, this);
this._workspace.addEventListener(Workspace.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this);
- this._workspace.addEventListener(Workspace.Workspace.Events.UISourceCodeRemoved, this._uiSourceCodeRemoved, this);
}
/**
@@ -99,23 +97,6 @@ Bindings.BreakpointManager = class extends Common.Object {
}
/**
- * @param {!Common.Event} event
- */
- _uiSourceCodeRemoved(event) {
- const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
- this._removeUISourceCode(uiSourceCode);
- }
-
- /**
- * @param {!Workspace.UISourceCode} uiSourceCode
- */
- _removeUISourceCode(uiSourceCode) {
- const breakpoints = uiSourceCode[Bindings.BreakpointManager._breakpointsSymbol] || new Set();
- for (const breakpoint of breakpoints)
- breakpoint._resetLocations();
- }
-
- /**
* @param {!Workspace.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @param {number} columnNumber
@@ -146,8 +127,8 @@ Bindings.BreakpointManager = class extends Common.Object {
const itemId = Bindings.BreakpointManager._breakpointStorageId(uiSourceCode.url(), lineNumber, columnNumber);
let breakpoint = this._breakpointByStorageId.get(itemId);
if (breakpoint) {
- breakpoint.setPrimaryUISourceCode(uiSourceCode);
breakpoint._updateState(condition, enabled);
+ breakpoint.setPrimaryUISourceCode(uiSourceCode);
breakpoint._updateBreakpoint();
return breakpoint;
}
@@ -158,27 +139,12 @@ Bindings.BreakpointManager = class extends Common.Object {
}
/**
- * @param {!Workspace.UISourceCode} uiSourceCode
- * @param {number} lineNumber
- * @return {!Array<!Bindings.BreakpointManager.Breakpoint>}
- */
- findBreakpoints(uiSourceCode, lineNumber) {
- const breakpoints = this._breakpointsForUISourceCode.get(uiSourceCode);
- const lineBreakpoints = breakpoints ? breakpoints.get(lineNumber) : null;
- return lineBreakpoints ? lineBreakpoints.valuesArray()[0] : [];
- }
-
- /**
- * @param {!Workspace.UISourceCode} uiSourceCode
- * @param {number} lineNumber
- * @param {number} columnNumber
- * @return {?Bindings.BreakpointManager.Breakpoint}
+ * @param {!Workspace.UILocation} uiLocation
+ * @return {?Bindings.BreakpointManager.BreakpointLocation}
*/
- findBreakpoint(uiSourceCode, lineNumber, columnNumber) {
- const breakpoints = this._breakpointsForUISourceCode.get(uiSourceCode);
- const lineBreakpoints = breakpoints ? breakpoints.get(lineNumber) : null;
- const columnBreakpoints = lineBreakpoints ? lineBreakpoints.get(columnNumber) : null;
- return columnBreakpoints ? columnBreakpoints[0] : null;
+ findBreakpoint(uiLocation) {
+ const breakpoints = this._breakpointsForUISourceCode.get(uiLocation.uiSourceCode);
+ return breakpoints ? (breakpoints.get(uiLocation.id())) || null : null;
}
/**
@@ -187,11 +153,24 @@ Bindings.BreakpointManager = class extends Common.Object {
* @return {!Promise<!Array<!Workspace.UILocation>>}
*/
possibleBreakpoints(uiSourceCode, textRange) {
- const startLocation = Bindings.debuggerWorkspaceBinding.uiLocationToRawLocation(
+ const startLocations = Bindings.debuggerWorkspaceBinding.uiLocationToRawLocations(
uiSourceCode, textRange.startLine, textRange.startColumn);
- const endLocation =
- Bindings.debuggerWorkspaceBinding.uiLocationToRawLocation(uiSourceCode, textRange.endLine, textRange.endColumn);
- if (!startLocation || !endLocation || startLocation.debuggerModel !== endLocation.debuggerModel)
+ const endLocations = Bindings.debuggerWorkspaceBinding.uiLocationToRawLocations(
+ uiSourceCode, textRange.endLine, textRange.endColumn);
+ const endLocationByModel = new Map();
+ for (const location of endLocations)
+ endLocationByModel.set(location.debuggerModel, location);
+ let startLocation = null;
+ let endLocation = null;
+ for (const location of startLocations) {
+ const endLocationCandidate = endLocationByModel.get(location.debuggerModel);
+ if (endLocationCandidate) {
+ startLocation = location;
+ endLocation = endLocationCandidate;
+ break;
+ }
+ }
+ if (!startLocation || !endLocation)
return Promise.resolve([]);
return startLocation.debuggerModel
@@ -223,101 +202,24 @@ Bindings.BreakpointManager = class extends Common.Object {
/**
* @param {!Workspace.UISourceCode} uiSourceCode
- * @return {!Array.<!Bindings.BreakpointManager.Breakpoint>}
- */
- breakpointsForUISourceCode(uiSourceCode) {
- let result = [];
- const uiSourceCodeBreakpoints = this._breakpointsForUISourceCode.get(uiSourceCode);
- const breakpoints = uiSourceCodeBreakpoints ? uiSourceCodeBreakpoints.valuesArray() : [];
- for (let i = 0; i < breakpoints.length; ++i) {
- const lineBreakpoints = breakpoints[i];
- const columnBreakpointArrays = lineBreakpoints ? lineBreakpoints.valuesArray() : [];
- result = result.concat.apply(result, columnBreakpointArrays);
- }
- return result;
- }
-
- /**
- * @return {!Array.<!Bindings.BreakpointManager.Breakpoint>}
- */
- _allBreakpoints() {
- let result = [];
- const uiSourceCodes = this._breakpointsForUISourceCode.keysArray();
- for (let i = 0; i < uiSourceCodes.length; ++i)
- result = result.concat(this.breakpointsForUISourceCode(uiSourceCodes[i]));
- return result;
- }
-
- /**
- * @param {!Workspace.UISourceCode} uiSourceCode
- * @return {!Array.<!{breakpoint: !Bindings.BreakpointManager.Breakpoint, uiLocation: !Workspace.UILocation}>}
+ * @return {!Array<!Bindings.BreakpointManager.BreakpointLocation>}
*/
breakpointLocationsForUISourceCode(uiSourceCode) {
- const uiSourceCodeBreakpoints = this._breakpointsForUISourceCode.get(uiSourceCode);
- const lineNumbers = uiSourceCodeBreakpoints ? uiSourceCodeBreakpoints.keysArray() : [];
- const result = [];
- for (let i = 0; i < lineNumbers.length; ++i) {
- const lineBreakpoints = uiSourceCodeBreakpoints.get(lineNumbers[i]);
- const columnNumbers = lineBreakpoints.keysArray();
- for (let j = 0; j < columnNumbers.length; ++j) {
- const columnBreakpoints = lineBreakpoints.get(columnNumbers[j]);
- const lineNumber = parseInt(lineNumbers[i], 10);
- const columnNumber = parseInt(columnNumbers[j], 10);
- for (let k = 0; k < columnBreakpoints.length; ++k) {
- const breakpoint = columnBreakpoints[k];
- const uiLocation = uiSourceCode.uiLocation(lineNumber, columnNumber);
- result.push({breakpoint: breakpoint, uiLocation: uiLocation});
- }
- }
- }
- return result;
+ const breakpoints = this._breakpointsForUISourceCode.get(uiSourceCode);
+ return breakpoints ? Array.from(breakpoints.values()) : [];
}
/**
- * @return {!Array.<!{breakpoint: !Bindings.BreakpointManager.Breakpoint, uiLocation: !Workspace.UILocation}>}
+ * @return {!Array<!Bindings.BreakpointManager.BreakpointLocation>}
*/
allBreakpointLocations() {
let result = [];
- const uiSourceCodes = this._breakpointsForUISourceCode.keysArray();
- for (let i = 0; i < uiSourceCodes.length; ++i)
- result = result.concat(this.breakpointLocationsForUISourceCode(uiSourceCodes[i]));
+ for (const breakpoints of this._breakpointsForUISourceCode.values())
+ result = result.concat(Array.from(breakpoints.values()));
return result;
}
/**
- * @param {boolean} toggleState
- */
- toggleAllBreakpoints(toggleState) {
- const breakpoints = this._allBreakpoints();
- for (let i = 0; i < breakpoints.length; ++i)
- breakpoints[i].setEnabled(toggleState);
- }
-
- removeAllBreakpoints() {
- const breakpoints = this._allBreakpoints();
- for (let i = 0; i < breakpoints.length; ++i)
- breakpoints[i].remove(false /* keepInStorage */);
- }
-
- /**
- * @param {!Set<!Bindings.BreakpointManager.Breakpoint>} selectedBreakpoints
- */
- removeOtherBreakpoints(selectedBreakpoints) {
- const allBreakpoints = this._allBreakpoints();
- allBreakpoints.forEach(breakpoint => {
- if (!selectedBreakpoints.has(breakpoint))
- breakpoint.remove(false /* keepInStorage */);
- });
- }
-
- _projectRemoved(event) {
- const project = /** @type {!Workspace.Project} */ (event.data);
- const uiSourceCodes = project.uiSourceCodes();
- for (let i = 0; i < uiSourceCodes.length; ++i)
- this._removeUISourceCode(uiSourceCodes[i]);
- }
-
- /**
* @param {!Bindings.BreakpointManager.Breakpoint} breakpoint
* @param {boolean} removeFromStorage
*/
@@ -337,19 +239,9 @@ Bindings.BreakpointManager = class extends Common.Object {
breakpoints = new Map();
this._breakpointsForUISourceCode.set(uiLocation.uiSourceCode, breakpoints);
}
- let lineBreakpoints = breakpoints.get(uiLocation.lineNumber);
- if (!lineBreakpoints) {
- lineBreakpoints = new Map();
- breakpoints.set(uiLocation.lineNumber, lineBreakpoints);
- }
- let columnBreakpoints = lineBreakpoints.get(uiLocation.columnNumber);
- if (!columnBreakpoints) {
- columnBreakpoints = [];
- lineBreakpoints.set(uiLocation.columnNumber, columnBreakpoints);
- }
- columnBreakpoints.push(breakpoint);
- this.dispatchEventToListeners(
- Bindings.BreakpointManager.Events.BreakpointAdded, {breakpoint: breakpoint, uiLocation: uiLocation});
+ const breakpointLocation = {breakpoint: breakpoint, uiLocation: uiLocation};
+ breakpoints.set(uiLocation.id(), breakpointLocation);
+ this.dispatchEventToListeners(Bindings.BreakpointManager.Events.BreakpointAdded, breakpointLocation);
}
/**
@@ -360,20 +252,12 @@ Bindings.BreakpointManager = class extends Common.Object {
const breakpoints = this._breakpointsForUISourceCode.get(uiLocation.uiSourceCode);
if (!breakpoints)
return;
-
- const lineBreakpoints = breakpoints.get(uiLocation.lineNumber);
- if (!lineBreakpoints)
- return;
- const columnBreakpoints = lineBreakpoints.get(uiLocation.columnNumber);
- if (!columnBreakpoints)
+ const breakpointLocation = breakpoints.get(uiLocation.id()) || null;
+ if (!breakpointLocation)
return;
- columnBreakpoints.remove(breakpoint);
- if (!columnBreakpoints.length)
- lineBreakpoints.remove(uiLocation.columnNumber);
- if (!lineBreakpoints.size)
- breakpoints.remove(uiLocation.lineNumber);
- if (!breakpoints.size)
- this._breakpointsForUISourceCode.remove(uiLocation.uiSourceCode);
+ breakpoints.delete(uiLocation.id());
+ if (breakpoints.size === 0)
+ this._breakpointsForUISourceCode.delete(uiLocation.uiSourceCode);
this.dispatchEventToListeners(
Bindings.BreakpointManager.Events.BreakpointRemoved, {breakpoint: breakpoint, uiLocation: uiLocation});
}
@@ -385,6 +269,12 @@ Bindings.BreakpointManager.Events = {
BreakpointRemoved: Symbol('breakpoint-removed')
};
+/** @typedef {{
+ * breakpoint: !Bindings.BreakpointManager.Breakpoint,
+ * uiLocation: !Workspace.UILocation
+ * }}
+ */
+Bindings.BreakpointManager.BreakpointLocation;
/**
* @unrestricted
@@ -406,20 +296,19 @@ Bindings.BreakpointManager.Breakpoint = class {
this._lineNumber = lineNumber;
this._columnNumber = columnNumber;
- this.setPrimaryUISourceCode(primaryUISourceCode);
-
- /** @type {!Map<string, number>} */
- this._numberOfDebuggerLocationForUILocation = new Map();
+ /** @type {?Workspace.UILocation} */
+ this._defaultUILocation = null;
+ /** @type {!Set<!Workspace.UILocation>} */
+ this._uiLocations = new Set();
/** @type {string} */ this._condition;
/** @type {boolean} */ this._enabled;
/** @type {boolean} */ this._isRemoved;
- /** @type {!Workspace.UILocation|undefined} */ this._fakePrimaryLocation;
- this._currentState = null;
/** @type {!Map.<!SDK.DebuggerModel, !Bindings.BreakpointManager.ModelBreakpoint>}*/
this._modelBreakpoints = new Map();
this._updateState(condition, enabled);
+ this.setPrimaryUISourceCode(primaryUISourceCode);
this._breakpointManager._targetManager.observeModels(SDK.DebuggerModel, this);
}
@@ -454,15 +343,14 @@ Bindings.BreakpointManager.Breakpoint = class {
* @param {?Workspace.UISourceCode} primaryUISourceCode
*/
setPrimaryUISourceCode(primaryUISourceCode) {
- const symbol = Bindings.BreakpointManager._breakpointsSymbol;
- if (this._primaryUISourceCode)
- this._primaryUISourceCode[symbol].delete(this);
- this._primaryUISourceCode = primaryUISourceCode;
- if (!primaryUISourceCode)
- return;
- if (!this._primaryUISourceCode[symbol])
- this._primaryUISourceCode[symbol] = new Set();
- this._primaryUISourceCode[symbol].add(this);
+ if (this._uiLocations.size === 0 && this._defaultUILocation)
+ this._breakpointManager._uiLocationRemoved(this, this._defaultUILocation);
+ if (primaryUISourceCode)
+ this._defaultUILocation = primaryUISourceCode.uiLocation(this._lineNumber, this._columnNumber);
+ else
+ this._defaultUILocation = null;
+ if (this._uiLocations.size === 0 && this._defaultUILocation && !this._isRemoved)
+ this._breakpointManager._uiLocationAdded(this, this._defaultUILocation);
}
/**
@@ -487,38 +375,25 @@ Bindings.BreakpointManager.Breakpoint = class {
}
/**
- * @param {?Workspace.UILocation} oldUILocation
- * @param {!Workspace.UILocation} newUILocation
+ * @param {!Workspace.UILocation} uiLocation
*/
- _replaceUILocation(oldUILocation, newUILocation) {
+ _uiLocationAdded(uiLocation) {
if (this._isRemoved)
return;
-
- this._removeUILocation(oldUILocation, true);
- this._removeFakeBreakpointAtPrimaryLocation();
-
- const current = (this._numberOfDebuggerLocationForUILocation.get(newUILocation.id()) || 0) + 1;
- this._numberOfDebuggerLocationForUILocation.set(newUILocation.id(), current);
- if (current === 1)
- this._breakpointManager._uiLocationAdded(this, newUILocation);
+ if (this._uiLocations.size === 0 && this._defaultUILocation)
+ this._breakpointManager._uiLocationRemoved(this, this._defaultUILocation);
+ this._uiLocations.add(uiLocation);
+ this._breakpointManager._uiLocationAdded(this, uiLocation);
}
/**
- * @param {?Workspace.UILocation} uiLocation
- * @param {boolean=} muteCreationFakeBreakpoint
+ * @param {!Workspace.UILocation} uiLocation
*/
- _removeUILocation(uiLocation, muteCreationFakeBreakpoint) {
- if (!uiLocation || !this._numberOfDebuggerLocationForUILocation.has(uiLocation.id()))
- return;
- const current = (this._numberOfDebuggerLocationForUILocation.get(uiLocation.id()) || 0) - 1;
- this._numberOfDebuggerLocationForUILocation.set(uiLocation.id(), current);
- if (current !== 0)
- return;
-
- this._numberOfDebuggerLocationForUILocation.delete(uiLocation.id());
+ _uiLocationRemoved(uiLocation) {
+ this._uiLocations.delete(uiLocation);
this._breakpointManager._uiLocationRemoved(this, uiLocation);
- if (!muteCreationFakeBreakpoint)
- this._fakeBreakpointAtPrimaryLocation();
+ if (this._uiLocations.size === 0 && this._defaultUILocation && !this._isRemoved)
+ this._breakpointManager._uiLocationAdded(this, this._defaultUILocation);
}
/**
@@ -563,8 +438,6 @@ Bindings.BreakpointManager.Breakpoint = class {
}
_updateBreakpoint() {
- this._removeFakeBreakpointAtPrimaryLocation();
- this._fakeBreakpointAtPrimaryLocation();
const modelBreakpoints = this._modelBreakpoints.valuesArray();
for (let i = 0; i < modelBreakpoints.length; ++i)
modelBreakpoints[i]._scheduleUpdateInDebugger();
@@ -576,23 +449,15 @@ Bindings.BreakpointManager.Breakpoint = class {
remove(keepInStorage) {
this._isRemoved = true;
const removeFromStorage = !keepInStorage;
- this._removeFakeBreakpointAtPrimaryLocation();
const modelBreakpoints = this._modelBreakpoints.valuesArray();
for (let i = 0; i < modelBreakpoints.length; ++i) {
modelBreakpoints[i]._scheduleUpdateInDebugger();
modelBreakpoints[i]._removeEventListeners();
}
- this.setPrimaryUISourceCode(null);
this._breakpointManager._removeBreakpoint(this, removeFromStorage);
this._breakpointManager._targetManager.unobserveModels(SDK.DebuggerModel, this);
- }
-
- /**
- * @param {!SDK.DebuggerModel} debuggerModel
- */
- _updateInDebuggerForModel(debuggerModel) {
- this._modelBreakpoints.get(debuggerModel)._scheduleUpdateInDebugger();
+ this.setPrimaryUISourceCode(null);
}
/**
@@ -602,36 +467,14 @@ Bindings.BreakpointManager.Breakpoint = class {
return Bindings.BreakpointManager._breakpointStorageId(this._url, this._lineNumber, this._columnNumber);
}
- _fakeBreakpointAtPrimaryLocation() {
- if (this._isRemoved || this._numberOfDebuggerLocationForUILocation.size || this._fakePrimaryLocation)
- return;
-
- if (!this._primaryUISourceCode)
- return;
-
- this._fakePrimaryLocation = this._primaryUISourceCode.uiLocation(this._lineNumber, this._columnNumber);
- if (this._fakePrimaryLocation)
- this._breakpointManager._uiLocationAdded(this, this._fakePrimaryLocation);
- }
-
- _removeFakeBreakpointAtPrimaryLocation() {
- if (this._fakePrimaryLocation) {
- this._breakpointManager._uiLocationRemoved(this, this._fakePrimaryLocation);
- delete this._fakePrimaryLocation;
- }
- }
-
_resetLocations() {
this.setPrimaryUISourceCode(null);
- this._removeFakeBreakpointAtPrimaryLocation();
const modelBreakpoints = this._modelBreakpoints.valuesArray();
for (let i = 0; i < modelBreakpoints.length; ++i)
modelBreakpoints[i]._resetLocations();
}
};
-Bindings.BreakpointManager._breakpointsSymbol = Symbol('breakpoints');
-
/**
* @unrestricted
*/
@@ -648,7 +491,7 @@ Bindings.BreakpointManager.ModelBreakpoint = class {
this._liveLocations = new Bindings.LiveLocationPool();
- /** @type {!Map<string, !Workspace.UILocation>} */
+ /** @type {!Map<!Bindings.LiveLocation, !Workspace.UILocation>} */
this._uiLocations = new Map();
this._debuggerModel.addEventListener(
SDK.DebuggerModel.Events.DebuggerWasDisabled, this._cleanUpAfterDebuggerIsGone, this);
@@ -664,7 +507,7 @@ Bindings.BreakpointManager.ModelBreakpoint = class {
_resetLocations() {
for (const uiLocation of this._uiLocations.values())
- this._breakpoint._removeUILocation(uiLocation);
+ this._breakpoint._uiLocationRemoved(uiLocation);
this._uiLocations.clear();
this._liveLocations.disposeAll();
@@ -692,7 +535,8 @@ Bindings.BreakpointManager.ModelBreakpoint = class {
* @return {boolean}
*/
_scriptDiverged() {
- const uiSourceCode = this._breakpoint._primaryUISourceCode;
+ const uiLocation = this._breakpoint._defaultUILocation;
+ const uiSourceCode = uiLocation ? uiLocation.uiSourceCode : null;
if (!uiSourceCode)
return false;
const scriptFile = this._debuggerWorkspaceBinding.scriptFile(uiSourceCode, this._debuggerModel);
@@ -710,15 +554,18 @@ Bindings.BreakpointManager.ModelBreakpoint = class {
return;
}
- const uiSourceCode = this._breakpoint._primaryUISourceCode;
+ const uiLocation = this._breakpoint._defaultUILocation;
+ const uiSourceCode = uiLocation ? uiLocation.uiSourceCode : null;
const lineNumber = this._breakpoint._lineNumber;
const columnNumber = this._breakpoint._columnNumber;
const condition = this._breakpoint.condition();
- let debuggerLocation = uiSourceCode &&
- Bindings.debuggerWorkspaceBinding.uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber);
- if (debuggerLocation && debuggerLocation.debuggerModel !== this._debuggerModel)
- debuggerLocation = null;
+ let debuggerLocation = null;
+ if (uiSourceCode) {
+ const locations =
+ Bindings.debuggerWorkspaceBinding.uiLocationToRawLocations(uiSourceCode, lineNumber, columnNumber);
+ debuggerLocation = locations.find(location => location.debuggerModel === this._debuggerModel);
+ }
let newState;
if (this._breakpoint._isRemoved || !this._breakpoint.enabled() || this._scriptDiverged()) {
newState = null;
@@ -731,10 +578,6 @@ Bindings.BreakpointManager.ModelBreakpoint = class {
newState = new Bindings.BreakpointManager.Breakpoint.State(
null, script.scriptId, script.hash, debuggerLocation.lineNumber, debuggerLocation.columnNumber, condition);
}
- } else if (this._breakpoint._currentState && this._breakpoint._currentState.url) {
- const position = this._breakpoint._currentState;
- newState = new Bindings.BreakpointManager.Breakpoint.State(
- position.url, null, null, position.lineNumber, position.columnNumber, condition);
} else if (uiSourceCode) {
newState = new Bindings.BreakpointManager.Breakpoint.State(
uiSourceCode.url(), null, null, lineNumber, columnNumber, condition);
@@ -744,8 +587,6 @@ Bindings.BreakpointManager.ModelBreakpoint = class {
return;
}
- this._breakpoint._currentState = newState;
-
if (this._debuggerId) {
await this._refreshBreakpoint();
callback();
@@ -828,16 +669,26 @@ Bindings.BreakpointManager.ModelBreakpoint = class {
}
/**
- * @param {!SDK.DebuggerModel.Location} location
* @param {!Bindings.LiveLocation} liveLocation
*/
- _locationUpdated(location, liveLocation) {
- const uiLocation = liveLocation.uiLocation();
- if (!uiLocation)
- return;
- const oldUILocation = this._uiLocations.get(location.id()) || null;
- this._uiLocations.set(location.id(), uiLocation);
- this._breakpoint._replaceUILocation(oldUILocation, uiLocation);
+ _locationUpdated(liveLocation) {
+ const oldUILocation = this._uiLocations.get(liveLocation);
+ if (oldUILocation)
+ this._breakpoint._uiLocationRemoved(oldUILocation);
+ let uiLocation = liveLocation.uiLocation();
+
+ if (uiLocation) {
+ const breakpointLocation = this._breakpoint._breakpointManager.findBreakpoint(uiLocation);
+ if (breakpointLocation && breakpointLocation.uiLocation !== breakpointLocation.breakpoint._defaultUILocation)
+ uiLocation = null;
+ }
+
+ if (uiLocation) {
+ this._uiLocations.set(liveLocation, uiLocation);
+ this._breakpoint._uiLocationAdded(uiLocation);
+ } else {
+ this._uiLocations.delete(liveLocation);
+ }
}
/**
@@ -848,15 +699,13 @@ Bindings.BreakpointManager.ModelBreakpoint = class {
const uiLocation = this._debuggerWorkspaceBinding.rawLocationToUILocation(location);
if (!uiLocation)
return false;
- const breakpoint = this._breakpoint._breakpointManager.findBreakpoint(
- uiLocation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber);
- if (breakpoint && breakpoint !== this._breakpoint) {
+ const breakpointLocation = this._breakpoint._breakpointManager.findBreakpoint(uiLocation);
+ if (breakpointLocation && breakpointLocation.breakpoint !== this._breakpoint) {
// location clash
this._breakpoint.remove(false /* keepInStorage */);
return false;
}
- this._debuggerWorkspaceBinding.createLiveLocation(
- location, this._locationUpdated.bind(this, location), this._liveLocations);
+ this._debuggerWorkspaceBinding.createLiveLocation(location, this._locationUpdated.bind(this), this._liveLocations);
return true;
}
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/bindings/CompilerScriptMapping.js b/chromium/third_party/blink/renderer/devtools/front_end/bindings/CompilerScriptMapping.js
index d484ae0daca..846be51b0a1 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/bindings/CompilerScriptMapping.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/bindings/CompilerScriptMapping.js
@@ -167,22 +167,22 @@ Bindings.CompilerScriptMapping = class {
* @param {!Workspace.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @param {number} columnNumber
- * @return {?SDK.DebuggerModel.Location}
+ * @return {!Array<!SDK.DebuggerModel.Location>}
*/
- uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber) {
+ uiLocationToRawLocations(uiSourceCode, lineNumber, columnNumber) {
const sourceMap = uiSourceCode[Bindings.CompilerScriptMapping._sourceMapSymbol];
if (!sourceMap)
- return null;
+ return [];
const scripts = this._sourceMapManager.clientsForSourceMap(sourceMap);
- const script = scripts.length ? scripts[0] : null;
- if (!script)
- return null;
+ if (!scripts.length)
+ return [];
const entry = sourceMap.sourceLineMapping(uiSourceCode.url(), lineNumber, columnNumber);
if (!entry)
- return null;
- return this._debuggerModel.createRawLocation(
- script, entry.lineNumber + script.lineOffset,
- !entry.lineNumber ? entry.columnNumber + script.columnOffset : entry.columnNumber);
+ return [];
+ return scripts.map(
+ script => this._debuggerModel.createRawLocation(
+ script, entry.lineNumber + script.lineOffset,
+ !entry.lineNumber ? entry.columnNumber + script.columnOffset : entry.columnNumber));
}
/**
@@ -213,7 +213,6 @@ Bindings.CompilerScriptMapping = class {
if (Bindings.blackboxManager.isBlackboxedURL(script.sourceURL, script.isContentScript()))
return;
- Bindings.blackboxManager.sourceMapLoaded(script, sourceMap);
this._populateSourceMapSources(script, sourceMap);
this._sourceMapAttachedForTest(sourceMap);
@@ -245,16 +244,6 @@ Bindings.CompilerScriptMapping = class {
}
/**
- * @param {!SDK.Script} script
- */
- maybeLoadSourceMap(script) {
- const sourceMap = this._sourceMapManager.sourceMapForClient(script);
- if (!sourceMap)
- return;
- this._populateSourceMapSources(script, sourceMap);
- }
-
- /**
* @param {?SDK.SourceMap} sourceMap
*/
_sourceMapAttachedForTest(sourceMap) {
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/bindings/DebuggerWorkspaceBinding.js b/chromium/third_party/blink/renderer/devtools/front_end/bindings/DebuggerWorkspaceBinding.js
index 8b971eb46f3..b3bba8a2325 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/bindings/DebuggerWorkspaceBinding.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/bindings/DebuggerWorkspaceBinding.js
@@ -131,21 +131,17 @@ Bindings.DebuggerWorkspaceBinding = class {
* @param {!Workspace.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @param {number} columnNumber
- * @return {?SDK.DebuggerModel.Location}
+ * @return {!Array<!SDK.DebuggerModel.Location>}
*/
- uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber) {
- for (let i = 0; i < this._sourceMappings.length; ++i) {
- const rawLocation = this._sourceMappings[i].uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber);
- if (rawLocation)
- return rawLocation;
- }
-
- for (const modelData of this._debuggerModelToData.values()) {
- const rawLocation = modelData._uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber);
- if (rawLocation)
- return rawLocation;
- }
- return null;
+ uiLocationToRawLocations(uiSourceCode, lineNumber, columnNumber) {
+ let locations = [];
+ for (let i = 0; i < this._sourceMappings.length && !locations.length; ++i)
+ locations = this._sourceMappings[i].uiLocationToRawLocations(uiSourceCode, lineNumber, columnNumber);
+ if (locations.length)
+ return locations;
+ for (const modelData of this._debuggerModelToData.values())
+ locations.push(...modelData._uiLocationToRawLocations(uiSourceCode, lineNumber, columnNumber));
+ return locations;
}
/**
@@ -153,10 +149,13 @@ Bindings.DebuggerWorkspaceBinding = class {
* @return {!Workspace.UILocation}
*/
normalizeUILocation(uiLocation) {
- const rawLocation =
- this.uiLocationToRawLocation(uiLocation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber);
- if (rawLocation)
- return this.rawLocationToUILocation(rawLocation) || uiLocation;
+ const rawLocations =
+ this.uiLocationToRawLocations(uiLocation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber);
+ for (const location of rawLocations) {
+ const uiLocationCandidate = this.rawLocationToUILocation(location);
+ if (uiLocationCandidate)
+ return uiLocationCandidate;
+ }
return uiLocation;
}
@@ -182,16 +181,6 @@ Bindings.DebuggerWorkspaceBinding = class {
}
/**
- * @param {!SDK.Script} script
- */
- maybeLoadSourceMap(script) {
- const modelData = this._debuggerModelToData.get(script.debuggerModel);
- if (!modelData)
- return;
- modelData._compilerMapping.maybeLoadSourceMap(script);
- }
-
- /**
* @param {!Common.Event} event
*/
_globalObjectCleared(event) {
@@ -319,16 +308,20 @@ Bindings.DebuggerWorkspaceBinding.ModelData = class {
* @param {!Workspace.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @param {number} columnNumber
- * @return {?SDK.DebuggerModel.Location}
+ * @return {!Array<!SDK.DebuggerModel.Location>}
*/
- _uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber) {
- let rawLocation = null;
- rawLocation = rawLocation || this._compilerMapping.uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber);
- rawLocation = rawLocation || this._resourceMapping.uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber);
- rawLocation =
- rawLocation || Bindings.resourceMapping.uiLocationToJSLocation(uiSourceCode, lineNumber, columnNumber);
- rawLocation = rawLocation || this._defaultMapping.uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber);
- return rawLocation;
+ _uiLocationToRawLocations(uiSourceCode, lineNumber, columnNumber) {
+ let locations = this._compilerMapping.uiLocationToRawLocations(uiSourceCode, lineNumber, columnNumber);
+ locations = locations.length ?
+ locations :
+ this._resourceMapping.uiLocationToRawLocations(uiSourceCode, lineNumber, columnNumber);
+ locations = locations.length ?
+ locations :
+ Bindings.resourceMapping.uiLocationToJSLocations(uiSourceCode, lineNumber, columnNumber);
+ locations = locations.length ?
+ locations :
+ this._defaultMapping.uiLocationToRawLocations(uiSourceCode, lineNumber, columnNumber);
+ return locations;
}
/**
@@ -387,7 +380,8 @@ Bindings.DebuggerWorkspaceBinding.Location = class extends Bindings.LiveLocation
* @return {boolean}
*/
isBlackboxed() {
- return Bindings.blackboxManager.isBlackboxedRawLocation(this._rawLocation);
+ const uiLocation = this.uiLocation();
+ return uiLocation ? Bindings.blackboxManager.isBlackboxedUISourceCode(uiLocation.uiSourceCode) : false;
}
};
@@ -466,9 +460,9 @@ Bindings.DebuggerSourceMapping.prototype = {
* @param {!Workspace.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @param {number} columnNumber
- * @return {?SDK.DebuggerModel.Location}
+ * @return {!Array<!SDK.DebuggerModel.Location>}
*/
- uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber) {},
+ uiLocationToRawLocations(uiSourceCode, lineNumber, columnNumber) {},
};
/**
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/bindings/DefaultScriptMapping.js b/chromium/third_party/blink/renderer/devtools/front_end/bindings/DefaultScriptMapping.js
index dab1e802e9c..26fea9642b4 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/bindings/DefaultScriptMapping.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/bindings/DefaultScriptMapping.js
@@ -47,10 +47,9 @@ Bindings.DefaultScriptMapping = class {
debuggerModel.addEventListener(SDK.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this),
debuggerModel.addEventListener(SDK.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this),
debuggerModel.addEventListener(
- SDK.DebuggerModel.Events.FailedToParseScriptSource, this._parsedScriptSource, this),
- debuggerModel.addEventListener(
SDK.DebuggerModel.Events.DiscardedAnonymousScriptSource, this._discardedScriptSource, this)
];
+ this._scriptSymbol = Symbol('symbol');
}
/**
@@ -58,7 +57,8 @@ Bindings.DefaultScriptMapping = class {
* @return {?SDK.Script}
*/
static scriptForUISourceCode(uiSourceCode) {
- return uiSourceCode[Bindings.DefaultScriptMapping._scriptSymbol] || null;
+ const scripts = uiSourceCode[Bindings.DefaultScriptMapping._scriptsSymbol];
+ return scripts ? scripts.values().next().value : null;
}
/**
@@ -83,17 +83,17 @@ Bindings.DefaultScriptMapping = class {
* @param {!Workspace.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @param {number} columnNumber
- * @return {?SDK.DebuggerModel.Location}
+ * @return {!Array<!SDK.DebuggerModel.Location>}
*/
- uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber) {
- const script = uiSourceCode[Bindings.DefaultScriptMapping._scriptSymbol];
+ uiLocationToRawLocations(uiSourceCode, lineNumber, columnNumber) {
+ const script = uiSourceCode[this._scriptSymbol];
if (!script)
- return null;
+ return [];
if (script.isInlineScriptWithSourceURL()) {
- return this._debuggerModel.createRawLocation(
- script, lineNumber + script.lineOffset, lineNumber ? columnNumber : columnNumber + script.columnOffset);
+ return [this._debuggerModel.createRawLocation(
+ script, lineNumber + script.lineOffset, lineNumber ? columnNumber : columnNumber + script.columnOffset)];
}
- return this._debuggerModel.createRawLocation(script, lineNumber, columnNumber);
+ return [this._debuggerModel.createRawLocation(script, lineNumber, columnNumber)];
}
/**
@@ -105,7 +105,11 @@ Bindings.DefaultScriptMapping = class {
const url = 'debugger:///VM' + script.scriptId + (name ? ' ' + name : '');
const uiSourceCode = this._project.createUISourceCode(url, Common.resourceTypes.Script);
- uiSourceCode[Bindings.DefaultScriptMapping._scriptSymbol] = script;
+ uiSourceCode[this._scriptSymbol] = script;
+ if (!uiSourceCode[Bindings.DefaultScriptMapping._scriptsSymbol])
+ uiSourceCode[Bindings.DefaultScriptMapping._scriptsSymbol] = new Set([script]);
+ else
+ uiSourceCode[Bindings.DefaultScriptMapping._scriptsSymbol].add(script);
script[Bindings.DefaultScriptMapping._uiSourceCodeSymbol] = uiSourceCode;
this._project.addUISourceCodeWithProvider(uiSourceCode, script, null, 'text/javascript');
this._debuggerWorkspaceBinding.updateLocations(script);
@@ -120,7 +124,10 @@ Bindings.DefaultScriptMapping = class {
if (!uiSourceCode)
return;
delete script[Bindings.DefaultScriptMapping._uiSourceCodeSymbol];
- delete uiSourceCode[Bindings.DefaultScriptMapping._scriptSymbol];
+ delete uiSourceCode[this._scriptSymbol];
+ uiSourceCode[Bindings.DefaultScriptMapping._scriptsSymbol].delete(script);
+ if (!uiSourceCode[Bindings.DefaultScriptMapping._scriptsSymbol].size)
+ delete uiSourceCode[Bindings.DefaultScriptMapping._scriptsSymbol];
this._project.removeUISourceCode(uiSourceCode.url());
}
@@ -135,5 +142,5 @@ Bindings.DefaultScriptMapping = class {
}
};
-Bindings.DefaultScriptMapping._scriptSymbol = Symbol('symbol');
+Bindings.DefaultScriptMapping._scriptsSymbol = Symbol('symbol');
Bindings.DefaultScriptMapping._uiSourceCodeSymbol = Symbol('uiSourceCodeSymbol');
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/bindings/PresentationConsoleMessageHelper.js b/chromium/third_party/blink/renderer/devtools/front_end/bindings/PresentationConsoleMessageHelper.js
index f639ae65f92..41c62e7f3a6 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/bindings/PresentationConsoleMessageHelper.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/bindings/PresentationConsoleMessageHelper.js
@@ -94,9 +94,6 @@ Bindings.PresentationConsoleMessageHelper = class {
// TODO(dgozman): setImmediate because we race with DebuggerWorkspaceBinding on ParsedScriptSource event delivery.
debuggerModel.addEventListener(
SDK.DebuggerModel.Events.ParsedScriptSource, event => setImmediate(this._parsedScriptSource.bind(this, event)));
- debuggerModel.addEventListener(
- SDK.DebuggerModel.Events.FailedToParseScriptSource,
- event => setImmediate(this._parsedScriptSource.bind(this, event)));
debuggerModel.addEventListener(SDK.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
this._locationPool = new Bindings.LiveLocationPool();
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/bindings/ResourceMapping.js b/chromium/third_party/blink/renderer/devtools/front_end/bindings/ResourceMapping.js
index 2acdd1280c3..c26e2741cc7 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/bindings/ResourceMapping.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/bindings/ResourceMapping.js
@@ -95,18 +95,19 @@ Bindings.ResourceMapping = class {
* @param {!Workspace.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @param {number} columnNumber
- * @return {?SDK.DebuggerModel.Location}
+ * @return {!Array<!SDK.DebuggerModel.Location>}
*/
- uiLocationToJSLocation(uiSourceCode, lineNumber, columnNumber) {
+ uiLocationToJSLocations(uiSourceCode, lineNumber, columnNumber) {
if (!uiSourceCode[Bindings.ResourceMapping._symbol])
- return null;
+ return [];
const target = Bindings.NetworkProject.targetForUISourceCode(uiSourceCode);
if (!target)
- return null;
+ return [];
const debuggerModel = target.model(SDK.DebuggerModel);
if (!debuggerModel)
- return null;
- return debuggerModel.createRawLocationByURL(uiSourceCode.url(), lineNumber, columnNumber);
+ return [];
+ const location = debuggerModel.createRawLocationByURL(uiSourceCode.url(), lineNumber, columnNumber);
+ return location ? [location] : [];
}
/**
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/bindings/ResourceScriptMapping.js b/chromium/third_party/blink/renderer/devtools/front_end/bindings/ResourceScriptMapping.js
index f6eea9a66ba..92bcbcfd4f6 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/bindings/ResourceScriptMapping.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/bindings/ResourceScriptMapping.js
@@ -53,8 +53,6 @@ Bindings.ResourceScriptMapping = class {
this._eventListeners = [
this._debuggerModel.addEventListener(SDK.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this),
this._debuggerModel.addEventListener(
- SDK.DebuggerModel.Events.FailedToParseScriptSource, this._parsedScriptSource, this),
- this._debuggerModel.addEventListener(
SDK.DebuggerModel.Events.GlobalObjectCleared, this._globalObjectCleared, this),
runtimeModel.addEventListener(
SDK.RuntimeModel.Events.ExecutionContextDestroyed, this._executionContextDestroyed, this),
@@ -113,18 +111,18 @@ Bindings.ResourceScriptMapping = class {
* @param {!Workspace.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @param {number} columnNumber
- * @return {?SDK.DebuggerModel.Location}
+ * @return {!Array<!SDK.DebuggerModel.Location>}
*/
- uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber) {
+ uiLocationToRawLocations(uiSourceCode, lineNumber, columnNumber) {
const scriptFile = this._uiSourceCodeToScriptFile.get(uiSourceCode);
if (!scriptFile)
- return null;
+ return [];
const script = scriptFile._script;
if (script.isInlineScriptWithSourceURL()) {
- return this._debuggerModel.createRawLocation(
- script, lineNumber + script.lineOffset, lineNumber ? columnNumber : columnNumber + script.columnOffset);
+ return [this._debuggerModel.createRawLocation(
+ script, lineNumber + script.lineOffset, lineNumber ? columnNumber : columnNumber + script.columnOffset)];
}
- return this._debuggerModel.createRawLocation(script, lineNumber, columnNumber);
+ return [this._debuggerModel.createRawLocation(script, lineNumber, columnNumber)];
}
/**
@@ -308,7 +306,8 @@ Bindings.ResourceScriptFile = class extends Common.Object {
if (!this._script)
return;
const debuggerModel = this._resourceScriptMapping._debuggerModel;
- const breakpoints = Bindings.breakpointManager.breakpointsForUISourceCode(this._uiSourceCode);
+ const breakpoints = Bindings.breakpointManager.breakpointLocationsForUISourceCode(this._uiSourceCode)
+ .map(breakpointLocation => breakpointLocation.breakpoint);
const source = this._uiSourceCode.workingCopy();
debuggerModel.setScriptSource(this._script.scriptId, source, scriptSourceWasSet.bind(this));
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/browser_components/module.json b/chromium/third_party/blink/renderer/devtools/front_end/browser_components/module.json
deleted file mode 100644
index bf178cbff78..00000000000
--- a/chromium/third_party/blink/renderer/devtools/front_end/browser_components/module.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "dependencies": [
- "browser_sdk",
- "components"
- ],
- "scripts": [
- "ImagePreview.js"
- ],
- "resources": [
- "imagePreview.css"
- ]
-}
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/browser_console/BrowserConsole.js b/chromium/third_party/blink/renderer/devtools/front_end/browser_console/BrowserConsole.js
index aee39714f7f..a98df127fc4 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/browser_console/BrowserConsole.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/browser_console/BrowserConsole.js
@@ -15,7 +15,7 @@ BrowserConsole.BrowserConsole = class {
*/
appendApplicableItems(event, contextMenu, object) {
const consoleMessage = /** @type {!SDK.ConsoleMessage} */ (object);
- const request = BrowserSDK.NetworkLog.requestForConsoleMessage(consoleMessage);
+ const request = SDK.NetworkLog.requestForConsoleMessage(consoleMessage);
if (request && SDK.NetworkManager.canReplayRequest(request)) {
contextMenu.debugSection().appendItem(
Common.UIString('Replay XHR'), SDK.NetworkManager.replayRequest.bind(null, request));
@@ -30,7 +30,7 @@ BrowserConsole.BrowserConsole = class {
*/
render(object, options) {
const consoleMessage = /** @type {!SDK.ConsoleMessage} */ (object);
- const request = BrowserSDK.NetworkLog.requestForConsoleMessage(consoleMessage);
+ const request = SDK.NetworkLog.requestForConsoleMessage(consoleMessage);
let messageElement = null;
if (request) {
messageElement = createElement('span');
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/browser_sdk/LogManager.js b/chromium/third_party/blink/renderer/devtools/front_end/browser_sdk/LogManager.js
index 0681aa91f52..8fa6c8b0913 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/browser_sdk/LogManager.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/browser_sdk/LogManager.js
@@ -41,7 +41,7 @@ BrowserSDK.LogManager = class {
data.entry.timestamp, undefined, undefined, data.entry.workerId);
if (data.entry.networkRequestId)
- BrowserSDK.networkLog.associateConsoleMessageWithRequest(consoleMessage, data.entry.networkRequestId);
+ SDK.networkLog.associateConsoleMessageWithRequest(consoleMessage, data.entry.networkRequestId);
SDK.consoleModel.addMessage(consoleMessage);
}
};
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/browser_sdk/module.json b/chromium/third_party/blink/renderer/devtools/front_end/browser_sdk/module.json
index 445eb49f7a4..1c276e0fa19 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/browser_sdk/module.json
+++ b/chromium/third_party/blink/renderer/devtools/front_end/browser_sdk/module.json
@@ -22,9 +22,7 @@
}
],
"scripts": [
- "LogManager.js",
- "NetworkLog.js",
- "HAREntry.js"
+ "LogManager.js"
],
"dependencies": [
"sdk"
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/changes/ChangesSidebar.js b/chromium/third_party/blink/renderer/devtools/front_end/changes/ChangesSidebar.js
index e5cb9bdaa6e..e1788dfd0ac 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/changes/ChangesSidebar.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/changes/ChangesSidebar.js
@@ -103,7 +103,7 @@ Changes.ChangesSidebar.UISourceCodeTreeElement = class extends UI.TreeElement {
this.listItemElement.classList.add('navigator-' + uiSourceCode.contentType().name() + '-tree-item');
let iconType = 'largeicon-navigator-file';
- if (this.uiSourceCode.contentType() === Common.resourceTypes.Snippet)
+ if (Snippets.isSnippetsUISourceCode(this.uiSourceCode))
iconType = 'largeicon-navigator-snippet';
const defaultIcon = UI.Icon.create(iconType, 'icon');
this.setLeadingIcons([defaultIcon]);
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/changes/module.json b/chromium/third_party/blink/renderer/devtools/front_end/changes/module.json
index 1875abc0e48..667b334a71e 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/changes/module.json
+++ b/chromium/third_party/blink/renderer/devtools/front_end/changes/module.json
@@ -24,6 +24,7 @@
"diff",
"bindings",
"persistence",
+ "snippets",
"ui"
],
"scripts": [
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm/activeline.js b/chromium/third_party/blink/renderer/devtools/front_end/cm/activeline.js
index aa295d0d86c..c7b14ce07fb 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/cm/activeline.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/cm/activeline.js
@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
+// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm/closebrackets.js b/chromium/third_party/blink/renderer/devtools/front_end/cm/closebrackets.js
index 460f662f804..ce1a4ac6b15 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/cm/closebrackets.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/cm/closebrackets.js
@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
+// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -129,16 +129,14 @@
else
curType = "skip";
} else if (identical && cur.ch > 1 && triples.indexOf(ch) >= 0 &&
- cm.getRange(Pos(cur.line, cur.ch - 2), cur) == ch + ch &&
- (cur.ch <= 2 || cm.getRange(Pos(cur.line, cur.ch - 3), Pos(cur.line, cur.ch - 2)) != ch)) {
+ cm.getRange(Pos(cur.line, cur.ch - 2), cur) == ch + ch) {
+ if (cur.ch > 2 && /\bstring/.test(cm.getTokenTypeAt(Pos(cur.line, cur.ch - 2)))) return CodeMirror.Pass;
curType = "addFour";
} else if (identical) {
var prev = cur.ch == 0 ? " " : cm.getRange(Pos(cur.line, cur.ch - 1), cur)
if (!CodeMirror.isWordChar(next) && prev != ch && !CodeMirror.isWordChar(prev)) curType = "both";
else return CodeMirror.Pass;
- } else if (opening && (cm.getLine(cur.line).length == cur.ch ||
- isClosingBracket(next, pairs) ||
- /\s/.test(next))) {
+ } else if (opening) {
curType = "both";
} else {
return CodeMirror.Pass;
@@ -175,11 +173,6 @@
});
}
- function isClosingBracket(ch, pairs) {
- var pos = pairs.lastIndexOf(ch);
- return pos > -1 && pos % 2 == 1;
- }
-
function charsAround(cm, pos) {
var str = cm.getRange(Pos(pos.line, pos.ch - 1),
Pos(pos.line, pos.ch + 1));
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm/codemirror.css b/chromium/third_party/blink/renderer/devtools/front_end/cm/codemirror.css
index 3360cac9c42..fdbf48c3994 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/cm/codemirror.css
+++ b/chromium/third_party/blink/renderer/devtools/front_end/cm/codemirror.css
@@ -118,7 +118,7 @@
.CodeMirror-linewidget {
position: relative;
z-index: 2;
- overflow: auto;
+ padding: 0.1px; /* Force widget margins to stay inside of the container */
}
.CodeMirror-widget {}
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm/codemirror.js b/chromium/third_party/blink/renderer/devtools/front_end/cm/codemirror.js
index 069c5796ca3..eaea2faa043 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/cm/codemirror.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/cm/codemirror.js
@@ -1,7 +1,7 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
+// Distributed under an MIT license: https://codemirror.net/LICENSE
-// This is CodeMirror (http://codemirror.net), a code editor
+// This is CodeMirror (https://codemirror.net), a code editor
// implemented in JavaScript on top of the browser's DOM.
//
// You can find some technical background for some of the code below
@@ -746,6 +746,16 @@ function collapsedSpanAtSide(line, start) {
function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true) }
function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false) }
+function collapsedSpanAround(line, ch) {
+ var sps = sawCollapsedSpans && line.markedSpans, found;
+ if (sps) { for (var i = 0; i < sps.length; ++i) {
+ var sp = sps[i];
+ if (sp.marker.collapsed && (sp.from == null || sp.from < ch) && (sp.to == null || sp.to > ch) &&
+ (!found || compareCollapsedMarkers(found, sp.marker) < 0)) { found = sp.marker; }
+ } }
+ return found
+}
+
// Test whether there exists a collapsed span that partially
// overlaps (covers the start or end, but not both) of a new span.
// Such overlap is not allowed.
@@ -2780,12 +2790,11 @@ function coordsChar(cm, x, y) {
var lineObj = getLine(doc, lineN);
for (;;) {
var found = coordsCharInner(cm, lineObj, lineN, x, y);
- var merged = collapsedSpanAtEnd(lineObj);
- var mergedPos = merged && merged.find(0, true);
- if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0))
- { lineN = lineNo(lineObj = mergedPos.to.line); }
- else
- { return found }
+ var collapsed = collapsedSpanAround(lineObj, found.ch + (found.xRel > 0 ? 1 : 0));
+ if (!collapsed) { return found }
+ var rangeEnd = collapsed.find(1);
+ if (rangeEnd.line == lineN) { return rangeEnd }
+ lineObj = getLine(doc, lineN = rangeEnd.line);
}
}
@@ -3545,6 +3554,7 @@ var NativeScrollbars = function(place, scroll, cm) {
this.cm = cm;
var vert = this.vert = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar");
var horiz = this.horiz = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar");
+ vert.tabIndex = horiz.tabIndex = -1;
place(vert); place(horiz);
on(vert, "scroll", function () {
@@ -4796,7 +4806,7 @@ function addChangeToHistory(doc, change, selAfter, opId) {
if ((hist.lastOp == opId ||
hist.lastOrigin == change.origin && change.origin &&
- ((change.origin.charAt(0) == "+" && doc.cm && hist.lastModTime > time - doc.cm.options.historyEventDelay) ||
+ ((change.origin.charAt(0) == "+" && hist.lastModTime > time - (doc.cm ? doc.cm.options.historyEventDelay : 500)) ||
change.origin.charAt(0) == "*")) &&
(cur = lastChangeEvent(hist, hist.lastOp == opId))) {
// Merge this change into the last event
@@ -5225,7 +5235,8 @@ function makeChangeInner(doc, change) {
// Revert a change stored in a document's history.
function makeChangeFromHistory(doc, type, allowSelectionOnly) {
- if (doc.cm && doc.cm.state.suppressEdits && !allowSelectionOnly) { return }
+ var suppress = doc.cm && doc.cm.state.suppressEdits;
+ if (suppress && !allowSelectionOnly) { return }
var hist = doc.history, event, selAfter = doc.sel;
var source = type == "undo" ? hist.done : hist.undone, dest = type == "undo" ? hist.undone : hist.done;
@@ -5250,8 +5261,10 @@ function makeChangeFromHistory(doc, type, allowSelectionOnly) {
return
}
selAfter = event;
- }
- else { break }
+ } else if (suppress) {
+ source.push(event);
+ return
+ } else { break }
}
// Build up a reverse change object to add to the opposite history
@@ -5694,7 +5707,7 @@ LineWidget.prototype.changed = function () {
this.height = null;
var diff = widgetHeight(this) - oldH;
if (!diff) { return }
- updateLineHeight(line, line.height + diff);
+ if (!lineIsHidden(this.doc, line)) { updateLineHeight(line, line.height + diff); }
if (cm) {
runInOp(cm, function () {
cm.curOp.forceUpdate = true;
@@ -5727,7 +5740,7 @@ function addLineWidget(doc, handle, node, options) {
}
return true
});
- signalLater(cm, "lineWidgetAdded", cm, widget, typeof handle == "number" ? handle : lineNo(handle));
+ if (cm) { signalLater(cm, "lineWidgetAdded", cm, widget, typeof handle == "number" ? handle : lineNo(handle)); }
return widget
}
@@ -6576,8 +6589,6 @@ function registerGlobalHandlers() {
// Called when the window resizes
function onResize(cm) {
var d = cm.display;
- if (d.lastWrapHeight == d.wrapper.clientHeight && d.lastWrapWidth == d.wrapper.clientWidth)
- { return }
// Might be a text scaling operation, clear size caches.
d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;
d.scrollbarsClipped = false;
@@ -6585,11 +6596,11 @@ function onResize(cm) {
}
var keyNames = {
- 3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt",
+ 3: "Pause", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt",
19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End",
36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert",
46: "Delete", 59: ";", 61: "=", 91: "Mod", 92: "Mod", 93: "Mod",
- 106: "*", 107: "=", 109: "-", 110: ".", 111: "/", 127: "Delete",
+ 106: "*", 107: "=", 109: "-", 110: ".", 111: "/", 127: "Delete", 145: "ScrollLock",
173: "-", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\",
221: "]", 222: "'", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete",
63273: "Home", 63275: "End", 63276: "PageUp", 63277: "PageDown", 63302: "Insert"
@@ -6623,7 +6634,7 @@ keyMap.pcDefault = {
"Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll",
"Ctrl-[": "indentLess", "Ctrl-]": "indentMore",
"Ctrl-U": "undoSelection", "Shift-Ctrl-U": "redoSelection", "Alt-U": "redoSelection",
- fallthrough: "basic"
+ "fallthrough": "basic"
};
// Very basic readline/emacs-style bindings, which are standard on Mac.
keyMap.emacsy = {
@@ -6641,7 +6652,7 @@ keyMap.macDefault = {
"Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll",
"Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delWrappedLineLeft", "Cmd-Delete": "delWrappedLineRight",
"Cmd-U": "undoSelection", "Shift-Cmd-U": "redoSelection", "Ctrl-Up": "goDocStart", "Ctrl-Down": "goDocEnd",
- fallthrough: ["basic", "emacsy"]
+ "fallthrough": ["basic", "emacsy"]
};
keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault;
@@ -6736,6 +6747,9 @@ function keyName(event, noShift) {
if (presto && event.keyCode == 34 && event["char"]) { return false }
var name = keyNames[event.keyCode];
if (name == null || event.altGraphKey) { return false }
+ // Ctrl-ScrollLock has keyCode 3, same as Ctrl-Pause,
+ // so we'll use event.code when available (Chrome 48+, FF 38+, Safari 10.1+)
+ if (event.keyCode == 3 && event.code) { name = event.code; }
return addModifierNames(name, event, noShift)
}
@@ -7318,8 +7332,8 @@ function leftButtonStartDrag(cm, event, pos, behavior) {
var dragEnd = operation(cm, function (e) {
if (webkit) { display.scroller.draggable = false; }
cm.state.draggingText = false;
- off(document, "mouseup", dragEnd);
- off(document, "mousemove", mouseMove);
+ off(display.wrapper.ownerDocument, "mouseup", dragEnd);
+ off(display.wrapper.ownerDocument, "mousemove", mouseMove);
off(display.scroller, "dragstart", dragStart);
off(display.scroller, "drop", dragEnd);
if (!moved) {
@@ -7328,7 +7342,7 @@ function leftButtonStartDrag(cm, event, pos, behavior) {
{ extendSelection(cm.doc, pos, null, null, behavior.extend); }
// Work around unexplainable focus problem in IE9 (#2127) and Chrome (#3081)
if (webkit || ie && ie_version == 9)
- { setTimeout(function () {document.body.focus(); display.input.focus();}, 20); }
+ { setTimeout(function () {display.wrapper.ownerDocument.body.focus(); display.input.focus();}, 20); }
else
{ display.input.focus(); }
}
@@ -7343,8 +7357,8 @@ function leftButtonStartDrag(cm, event, pos, behavior) {
dragEnd.copy = !behavior.moveOnDrag;
// IE's approach to draggable
if (display.scroller.dragDrop) { display.scroller.dragDrop(); }
- on(document, "mouseup", dragEnd);
- on(document, "mousemove", mouseMove);
+ on(display.wrapper.ownerDocument, "mouseup", dragEnd);
+ on(display.wrapper.ownerDocument, "mousemove", mouseMove);
on(display.scroller, "dragstart", dragStart);
on(display.scroller, "drop", dragEnd);
@@ -7476,19 +7490,19 @@ function leftButtonSelect(cm, event, start, behavior) {
counter = Infinity;
e_preventDefault(e);
display.input.focus();
- off(document, "mousemove", move);
- off(document, "mouseup", up);
+ off(display.wrapper.ownerDocument, "mousemove", move);
+ off(display.wrapper.ownerDocument, "mouseup", up);
doc.history.lastSelOrigin = null;
}
var move = operation(cm, function (e) {
- if (!e_button(e)) { done(e); }
+ if (e.buttons === 0 || !e_button(e)) { done(e); }
else { extend(e); }
});
var up = operation(cm, done);
cm.state.selectingText = up;
- on(document, "mousemove", move);
- on(document, "mouseup", up);
+ on(display.wrapper.ownerDocument, "mousemove", move);
+ on(display.wrapper.ownerDocument, "mouseup", up);
}
// Used when mouse-selecting to adjust the anchor to the proper side
@@ -7618,6 +7632,7 @@ function defineOptions(CodeMirror) {
clearCaches(cm);
regChange(cm);
}, true);
+
option("lineSeparator", null, function (cm, val) {
cm.doc.lineSep = val;
if (!val) { return }
@@ -7719,6 +7734,7 @@ function defineOptions(CodeMirror) {
option("tabindex", null, function (cm, val) { return cm.display.input.getField().tabIndex = val || ""; });
option("autofocus", null);
option("direction", "ltr", function (cm, val) { return cm.doc.setDirection(val); }, true);
+ option("phrases", null);
}
function guttersChanged(cm) {
@@ -7770,6 +7786,7 @@ function CodeMirror$1(place, options) {
var doc = options.value;
if (typeof doc == "string") { doc = new Doc(doc, options.mode, null, options.lineSeparator, options.direction); }
+ else if (options.mode) { doc.modeOption = options.mode; }
this.doc = doc;
var input = new CodeMirror$1.inputStyles[options.inputStyle](this);
@@ -8024,7 +8041,7 @@ function applyTextInput(cm, inserted, deleted, sel, origin) {
var paste = cm.state.pasteIncoming || origin == "paste";
var textLines = splitLinesAuto(inserted), multiPaste = null;
- // When pasing N lines into N selections, insert one line per selection
+ // When pasting N lines into N selections, insert one line per selection
if (paste && sel.ranges.length > 1) {
if (lastCopied && lastCopied.text.join("\n") == inserted) {
if (sel.ranges.length % lastCopied.text.length == 0) {
@@ -8556,6 +8573,11 @@ var addEditorMethods = function(CodeMirror) {
return old
}),
+ phrase: function(phraseText) {
+ var phrases = this.options.phrases;
+ return phrases && Object.prototype.hasOwnProperty.call(phrases, phraseText) ? phrases[phraseText] : phraseText
+ },
+
getInputField: function(){return this.display.input.getField()},
getWrapperElement: function(){return this.display.wrapper},
getScrollerElement: function(){return this.display.scroller},
@@ -8760,8 +8782,12 @@ ContentEditableInput.prototype.showSelection = function (info, takeFocus) {
this.showMultipleSelections(info);
};
+ContentEditableInput.prototype.getSelection = function () {
+ return this.cm.display.wrapper.ownerDocument.getSelection()
+};
+
ContentEditableInput.prototype.showPrimarySelection = function () {
- var sel = window.getSelection(), cm = this.cm, prim = cm.doc.sel.primary();
+ var sel = this.getSelection(), cm = this.cm, prim = cm.doc.sel.primary();
var from = prim.from(), to = prim.to();
if (cm.display.viewTo == cm.display.viewFrom || from.line >= cm.display.viewTo || to.line < cm.display.viewFrom) {
@@ -8828,13 +8854,13 @@ ContentEditableInput.prototype.showMultipleSelections = function (info) {
};
ContentEditableInput.prototype.rememberSelection = function () {
- var sel = window.getSelection();
+ var sel = this.getSelection();
this.lastAnchorNode = sel.anchorNode; this.lastAnchorOffset = sel.anchorOffset;
this.lastFocusNode = sel.focusNode; this.lastFocusOffset = sel.focusOffset;
};
ContentEditableInput.prototype.selectionInEditor = function () {
- var sel = window.getSelection();
+ var sel = this.getSelection();
if (!sel.rangeCount) { return false }
var node = sel.getRangeAt(0).commonAncestorContainer;
return contains(this.div, node)
@@ -8869,14 +8895,14 @@ ContentEditableInput.prototype.receivedFocus = function () {
};
ContentEditableInput.prototype.selectionChanged = function () {
- var sel = window.getSelection();
+ var sel = this.getSelection();
return sel.anchorNode != this.lastAnchorNode || sel.anchorOffset != this.lastAnchorOffset ||
sel.focusNode != this.lastFocusNode || sel.focusOffset != this.lastFocusOffset
};
ContentEditableInput.prototype.pollSelection = function () {
if (this.readDOMTimeout != null || this.gracePeriod || !this.selectionChanged()) { return }
- var sel = window.getSelection(), cm = this.cm;
+ var sel = this.getSelection(), cm = this.cm;
// On Android Chrome (version 56, at least), backspacing into an
// uneditable block element will put the cursor in that element,
// and then, because it's not editable, hide the virtual keyboard.
@@ -9010,7 +9036,7 @@ ContentEditableInput.prototype.setUneditable = function (node) {
};
ContentEditableInput.prototype.onKeyPress = function (e) {
- if (e.charCode == 0) { return }
+ if (e.charCode == 0 || this.composing) { return }
e.preventDefault();
if (!this.cm.isReadOnly())
{ operation(this.cm, applyTextInput)(this.cm, String.fromCharCode(e.charCode == null ? e.keyCode : e.charCode), 0); }
@@ -9050,12 +9076,13 @@ function isInGutter(node) {
function badPos(pos, bad) { if (bad) { pos.bad = true; } return pos }
function domTextBetween(cm, from, to, fromLine, toLine) {
- var text = "", closing = false, lineSep = cm.doc.lineSeparator();
+ var text = "", closing = false, lineSep = cm.doc.lineSeparator(), extraLinebreak = false;
function recognizeMarker(id) { return function (marker) { return marker.id == id; } }
function close() {
if (closing) {
text += lineSep;
- closing = false;
+ if (extraLinebreak) { text += lineSep; }
+ closing = extraLinebreak = false;
}
}
function addText(str) {
@@ -9067,8 +9094,8 @@ function domTextBetween(cm, from, to, fromLine, toLine) {
function walk(node) {
if (node.nodeType == 1) {
var cmText = node.getAttribute("cm-text");
- if (cmText != null) {
- addText(cmText || node.textContent.replace(/\u200b/g, ""));
+ if (cmText) {
+ addText(cmText);
return
}
var markerID = node.getAttribute("cm-marker"), range$$1;
@@ -9079,19 +9106,24 @@ function domTextBetween(cm, from, to, fromLine, toLine) {
return
}
if (node.getAttribute("contenteditable") == "false") { return }
- var isBlock = /^(pre|div|p)$/i.test(node.nodeName);
+ var isBlock = /^(pre|div|p|li|table|br)$/i.test(node.nodeName);
+ if (!/^br$/i.test(node.nodeName) && node.textContent.length == 0) { return }
+
if (isBlock) { close(); }
for (var i = 0; i < node.childNodes.length; i++)
{ walk(node.childNodes[i]); }
+
+ if (/^(pre|p)$/i.test(node.nodeName)) { extraLinebreak = true; }
if (isBlock) { closing = true; }
} else if (node.nodeType == 3) {
- addText(node.nodeValue);
+ addText(node.nodeValue.replace(/\u200b/g, "").replace(/\u00a0/g, " "));
}
}
for (;;) {
walk(from);
if (from == to) { break }
from = from.nextSibling;
+ extraLinebreak = false;
}
return text
}
@@ -9192,13 +9224,10 @@ TextareaInput.prototype.init = function (display) {
var this$1 = this;
var input = this, cm = this.cm;
+ this.createField(display);
+ var te = this.textarea;
- // Wraps and hides input textarea
- var div = this.wrapper = hiddenTextarea();
- // The semihidden textarea that is focused when the editor is
- // focused, and receives input.
- var te = this.textarea = div.firstChild;
- display.wrapper.insertBefore(div, display.wrapper.firstChild);
+ display.wrapper.insertBefore(this.wrapper, display.wrapper.firstChild);
// Needed to hide big blue blinking cursor on Mobile Safari (doesn't seem to work in iOS 8 anymore)
if (ios) { te.style.width = "0px"; }
@@ -9265,6 +9294,14 @@ TextareaInput.prototype.init = function (display) {
});
};
+TextareaInput.prototype.createField = function (_display) {
+ // Wraps and hides input textarea
+ this.wrapper = hiddenTextarea();
+ // The semihidden textarea that is focused when the editor is
+ // focused, and receives input.
+ this.textarea = this.wrapper.firstChild;
+};
+
TextareaInput.prototype.prepareSelection = function () {
// Redraw the selection and/or cursor
var cm = this.cm, display = cm.display, doc = cm.doc;
@@ -9658,7 +9695,7 @@ CodeMirror$1.fromTextArea = fromTextArea;
addLegacyProps(CodeMirror$1);
-CodeMirror$1.version = "5.31.1";
+CodeMirror$1.version = "5.39.3";
return CodeMirror$1;
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm/comment.js b/chromium/third_party/blink/renderer/devtools/front_end/cm/comment.js
index 84c67edf789..8394e85a4da 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/cm/comment.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/cm/comment.js
@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
+// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm/markselection.js b/chromium/third_party/blink/renderer/devtools/front_end/cm/markselection.js
index 1602acc3deb..adfaa62d1a6 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/cm/markselection.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/cm/markselection.js
@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
+// Distributed under an MIT license: https://codemirror.net/LICENSE
// Because sometimes you need to mark the selected *text*.
//
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm/matchbrackets.js b/chromium/third_party/blink/renderer/devtools/front_end/cm/matchbrackets.js
index 4d7a230855a..c918c3f99f1 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/cm/matchbrackets.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/cm/matchbrackets.js
@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
+// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -102,18 +102,23 @@
}
}
- var currentlyHighlighted = null;
function doMatchBrackets(cm) {
cm.operation(function() {
- if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;}
- currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets);
+ if (cm.state.matchBrackets.currentlyHighlighted) {
+ cm.state.matchBrackets.currentlyHighlighted();
+ cm.state.matchBrackets.currentlyHighlighted = null;
+ }
+ cm.state.matchBrackets.currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets);
});
}
CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) {
if (old && old != CodeMirror.Init) {
cm.off("cursorActivity", doMatchBrackets);
- if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;}
+ if (cm.state.matchBrackets && cm.state.matchBrackets.currentlyHighlighted) {
+ cm.state.matchBrackets.currentlyHighlighted();
+ cm.state.matchBrackets.currentlyHighlighted = null;
+ }
}
if (val) {
cm.state.matchBrackets = typeof val == "object" ? val : {};
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm/multiplex.js b/chromium/third_party/blink/renderer/devtools/front_end/cm/multiplex.js
index 3d8b34c4520..738ea98a0de 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/cm/multiplex.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/cm/multiplex.js
@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
+// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -50,7 +50,15 @@ CodeMirror.multiplexingMode = function(outer /*, others */) {
if (found == stream.pos) {
if (!other.parseDelimiters) stream.match(other.open);
state.innerActive = other;
- state.inner = CodeMirror.startState(other.mode, outer.indent ? outer.indent(state.outer, "") : 0);
+
+ // Get the outer indent, making sure to handle CodeMirror.Pass
+ var outerIndent = 0;
+ if (outer.indent) {
+ var possibleOuterIndent = outer.indent(state.outer, "");
+ if (possibleOuterIndent !== CodeMirror.Pass) outerIndent = possibleOuterIndent;
+ }
+
+ state.inner = CodeMirror.startState(other.mode, outerIndent);
return other.delimStyle && (other.delimStyle + " " + other.delimStyle + "-open");
} else if (found != -1 && found < cutOff) {
cutOff = found;
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm/overlay.js b/chromium/third_party/blink/renderer/devtools/front_end/cm/overlay.js
index 4a9f99a072e..839d9e552ec 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/cm/overlay.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/cm/overlay.js
@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
+// Distributed under an MIT license: https://codemirror.net/LICENSE
// Utility function that allows modes to be combined. The mode given
// as the base argument takes care of most of the normal mode
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm_headless/headlesscodemirror.js b/chromium/third_party/blink/renderer/devtools/front_end/cm_headless/headlesscodemirror.js
index f7aec5b6d52..690a123ef99 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/cm_headless/headlesscodemirror.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/cm_headless/headlesscodemirror.js
@@ -2,7 +2,7 @@
// from CodeMirror distribution
(function(window) {
// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
+// Distributed under an MIT license: https://codemirror.net/LICENSE
window.CodeMirror = {};
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/clike.js b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/clike.js
index 02a85319ff0..42033bd0a0d 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/clike.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/clike.js
@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
+// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -216,15 +216,15 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
indent: function(state, textAfter) {
if (state.tokenize != tokenBase && state.tokenize != null || state.typeAtEndOfLine) return CodeMirror.Pass;
var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
+ var closing = firstChar == ctx.type;
if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev;
if (parserConfig.dontIndentStatements)
while (ctx.type == "statement" && parserConfig.dontIndentStatements.test(ctx.info))
ctx = ctx.prev
if (hooks.indent) {
- var hook = hooks.indent(state, ctx, textAfter);
+ var hook = hooks.indent(state, ctx, textAfter, indentUnit);
if (typeof hook == "number") return hook
}
- var closing = firstChar == ctx.type;
var switchBlock = ctx.prev && ctx.prev.info == "switch";
if (parserConfig.allmanIndentation && /[{(]/.test(firstChar)) {
while (ctx.type != "top" && ctx.type != "}") ctx = ctx.prev
@@ -374,7 +374,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
blockKeywords: words("case do else for if switch while struct"),
defKeywords: words("struct"),
typeFirstDefinitions: true,
- atoms: words("null true false"),
+ atoms: words("NULL true false"),
hooks: {"#": cppHook, "*": pointerHook},
modeProps: {fold: ["brace", "include"]}
});
@@ -390,7 +390,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
blockKeywords: words("catch class do else finally for if struct switch try while"),
defKeywords: words("class namespace struct enum union"),
typeFirstDefinitions: true,
- atoms: words("true false null"),
+ atoms: words("true false NULL"),
dontIndentStatements: /^template$/,
isIdentifierChar: /[\w\$_~\xa1-\uffff]/,
hooks: {
@@ -489,6 +489,27 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
return "string";
}
+ function tokenNestedComment(depth) {
+ return function (stream, state) {
+ var ch
+ while (ch = stream.next()) {
+ if (ch == "*" && stream.eat("/")) {
+ if (depth == 1) {
+ state.tokenize = null
+ break
+ } else {
+ state.tokenize = tokenNestedComment(depth - 1)
+ return state.tokenize(stream, state)
+ }
+ } else if (ch == "/" && stream.eat("*")) {
+ state.tokenize = tokenNestedComment(depth + 1)
+ return state.tokenize(stream, state)
+ }
+ }
+ return "comment"
+ }
+ }
+
def("text/x-scala", {
name: "clike",
keywords: words(
@@ -544,6 +565,12 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
} else {
return false
}
+ },
+
+ "/": function(stream, state) {
+ if (!stream.eat("*")) return false
+ state.tokenize = tokenNestedComment(1)
+ return state.tokenize(stream, state)
}
},
modeProps: {closeBrackets: {triples: '"'}}
@@ -570,34 +597,51 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
name: "clike",
keywords: words(
/*keywords*/
- "package as typealias class interface this super val " +
- "var fun for is in This throw return " +
+ "package as typealias class interface this super val operator " +
+ "var fun for is in This throw return annotation " +
"break continue object if else while do try when !in !is as? " +
/*soft keywords*/
"file import where by get set abstract enum open inner override private public internal " +
"protected catch finally out final vararg reified dynamic companion constructor init " +
"sealed field property receiver param sparam lateinit data inline noinline tailrec " +
- "external annotation crossinline const operator infix suspend"
+ "external annotation crossinline const operator infix suspend actual expect setparam"
),
types: words(
/* package java.lang */
"Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " +
"Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " +
"Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " +
- "StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void"
+ "StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void Annotation Any BooleanArray " +
+ "ByteArray Char CharArray DeprecationLevel DoubleArray Enum FloatArray Function Int IntArray Lazy " +
+ "LazyThreadSafetyMode LongArray Nothing ShortArray Unit"
),
intendSwitch: false,
indentStatements: false,
multiLineStrings: true,
- number: /^(?:0x[a-f\d_]+|0b[01_]+|(?:[\d_]+\.?\d*|\.\d+)(?:e[-+]?[\d_]+)?)(u|ll?|l|f)?/i,
+ number: /^(?:0x[a-f\d_]+|0b[01_]+|(?:[\d_]+(\.\d+)?|\.\d+)(?:e[-+]?[\d_]+)?)(u|ll?|l|f)?/i,
blockKeywords: words("catch class do else finally for if where try while enum"),
defKeywords: words("class val var object interface fun"),
atoms: words("true false null this"),
hooks: {
+ "@": function(stream) {
+ stream.eatWhile(/[\w\$_]/);
+ return "meta";
+ },
'"': function(stream, state) {
state.tokenize = tokenKotlinString(stream.match('""'));
return state.tokenize(stream, state);
+ },
+ indent: function(state, ctx, textAfter, indentUnit) {
+ var firstChar = textAfter && textAfter.charAt(0);
+ if ((state.prevToken == "}" || state.prevToken == ")") && textAfter == "")
+ return state.indented;
+ if (state.prevToken == "operator" && textAfter != "}" ||
+ state.prevToken == "variable" && firstChar == "." ||
+ (state.prevToken == "}" || state.prevToken == ")") && firstChar == ".")
+ return indentUnit * 2 + ctx.indented;
+ if (ctx.align && ctx.type == "}")
+ return ctx.indented + (state.context.type == (textAfter || "").charAt(0) ? 0 : indentUnit);
}
},
modeProps: {closeBrackets: {triples: '"'}}
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/clojure.js b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/clojure.js
index ed6af2c83c1..2015edff148 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/clojure.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/clojure.js
@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
+// Distributed under an MIT license: https://codemirror.net/LICENSE
/**
* Author: Hans Engel
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/coffeescript.js b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/coffeescript.js
index ae955db344a..a54e9d5ed0a 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/coffeescript.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/coffeescript.js
@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
+// Distributed under an MIT license: https://codemirror.net/LICENSE
/**
* Link to the project's GitHub page:
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/jsx.js b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/jsx.js
index 45c3024aba3..2c91beb955f 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/jsx.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/jsx.js
@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
+// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -26,7 +26,7 @@
}
CodeMirror.defineMode("jsx", function(config, modeConfig) {
- var xmlMode = CodeMirror.getMode(config, {name: "xml", allowMissing: true, multilineTagIndentPastTag: false})
+ var xmlMode = CodeMirror.getMode(config, {name: "xml", allowMissing: true, multilineTagIndentPastTag: false, allowMissingTagName: true})
var jsMode = CodeMirror.getMode(config, modeConfig && modeConfig.base || "javascript")
function flatXMLIndent(state) {
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/livescript.js b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/livescript.js
index 1e363f87699..595e067d16b 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/livescript.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/livescript.js
@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
+// Distributed under an MIT license: https://codemirror.net/LICENSE
/**
* Link to the project's GitHub page:
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/markdown.js b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/markdown.js
index 61e0c4fc123..442ab6b95b9 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/markdown.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/markdown.js
@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
+// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -90,7 +90,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
, setextHeaderRE = /^ *(?:\={1,}|-{1,})\s*$/
, textRE = /^[^#!\[\]*_\\<>` "'(~:]+/
, fencedCodeRE = /^(~~~+|```+)[ \t]*([\w+#-]*)[^\n`]*$/
- , linkDefRE = /^\s*\[[^\]]+?\]:\s*\S+(\s*\S*\s*)?$/ // naive link-definition
+ , linkDefRE = /^\s*\[[^\]]+?\]:.*$/ // naive link-definition
, punctuation = /[!\"#$%&\'()*+,\-\.\/:;<=>?@\[\\\]^_`{|}~\u2014]/
, expandedTab = " " // CommonMark specifies tab as 4 spaces
@@ -126,8 +126,17 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
// Reset state.indentedCode
state.indentedCode = false;
if (state.f == htmlBlock) {
- state.f = inlineNormal;
- state.block = blockNormal;
+ var exit = htmlModeMissing
+ if (!exit) {
+ var inner = CodeMirror.innerMode(htmlMode, state.htmlState)
+ exit = inner.mode.name == "xml" && inner.state.tagStart === null &&
+ (!inner.state.context && inner.state.tokenize.isInText)
+ }
+ if (exit) {
+ state.f = inlineNormal;
+ state.block = blockNormal;
+ state.htmlState = null;
+ }
}
// Reset state.trailingSpace
state.trailingSpace = 0;
@@ -497,6 +506,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
}
if (ch === '[' && !state.image) {
+ if (state.linkText && stream.match(/^.*?\]/)) return getType(state)
state.linkText = true;
if (modeCfg.highlightFormatting) state.formatting = "link";
return getType(state);
@@ -534,7 +544,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
return type + tokenTypes.linkEmail;
}
- if (modeCfg.xml && ch === '<' && stream.match(/^(!--|[a-z]+(?:\s+[a-z_:.\-]+(?:\s*=\s*[^ >]+)?)*\s*>)/i, false)) {
+ if (modeCfg.xml && ch === '<' && stream.match(/^(!--|\?|!\[CDATA\[|[a-z][a-z0-9-]*(?:\s+[a-z_:.\-]+(?:\s*=\s*[^>]+)?)*\s*(?:>|$))/i, false)) {
var end = stream.string.indexOf(">", stream.pos);
if (end != -1) {
var atts = stream.string.substring(stream.start, end);
@@ -619,7 +629,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
}
if (ch === ' ') {
- if (stream.match(/ +$/, false)) {
+ if (stream.match(/^ +$/, false)) {
state.trailingSpace++;
} else if (state.trailingSpace) {
state.trailingSpaceNewLine = true;
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/php.js b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/php.js
index 589c9a66395..80e2f20bf18 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/php.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/php.js
@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
+// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/python.js b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/python.js
index c3187932073..623c03f7f0f 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/python.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/python.js
@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
+// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -41,7 +41,7 @@
CodeMirror.defineMode("python", function(conf, parserConf) {
var ERRORCLASS = "error";
- var delimiters = parserConf.delimiters || parserConf.singleDelimiters || /^[\(\)\[\]\{\}@,:`=;\.]/;
+ var delimiters = parserConf.delimiters || parserConf.singleDelimiters || /^[\(\)\[\]\{\}@,:`=;\.\\]/;
// (Backwards-compatiblity with old, cumbersome config system)
var operators = [parserConf.singleOperators, parserConf.doubleOperators, parserConf.doubleDelimiters, parserConf.tripleDelimiters,
parserConf.operators || /^([-+*/%\/&|^]=?|[<>=]+|\/\/=?|\*\*=?|!=|[~!@])/]
@@ -62,7 +62,7 @@
var identifiers = parserConf.identifiers|| /^[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*/;
myKeywords = myKeywords.concat(["nonlocal", "False", "True", "None", "async", "await"]);
myBuiltins = myBuiltins.concat(["ascii", "bytes", "exec", "print"]);
- var stringPrefixes = new RegExp("^(([rbuf]|(br))?('{3}|\"{3}|['\"]))", "i");
+ var stringPrefixes = new RegExp("^(([rbuf]|(br)|(fr))?('{3}|\"{3}|['\"]))", "i");
} else {
var identifiers = parserConf.identifiers|| /^[_A-Za-z][_A-Za-z0-9]*/;
myKeywords = myKeywords.concat(["exec", "print"]);
@@ -76,9 +76,10 @@
// tokenizers
function tokenBase(stream, state) {
- if (stream.sol()) state.indent = stream.indentation()
+ var sol = stream.sol() && state.lastToken != "\\"
+ if (sol) state.indent = stream.indentation()
// Handle scope changes
- if (stream.sol() && top(state).type == "py") {
+ if (sol && top(state).type == "py") {
var scopeOffset = top(state).offset;
if (stream.eatSpace()) {
var lineOffset = stream.indentation();
@@ -100,13 +101,8 @@
function tokenBaseInner(stream, state) {
if (stream.eatSpace()) return null;
- var ch = stream.peek();
-
// Handle Comments
- if (ch == "#") {
- stream.skipToEnd();
- return "comment";
- }
+ if (stream.match(/^#.*/)) return "comment";
// Handle Number Literals
if (stream.match(/^[0-9\.]/, false)) {
@@ -146,8 +142,14 @@
// Handle Strings
if (stream.match(stringPrefixes)) {
- state.tokenize = tokenStringFactory(stream.current());
- return state.tokenize(stream, state);
+ var isFmtString = stream.current().toLowerCase().indexOf('f') !== -1;
+ if (!isFmtString) {
+ state.tokenize = tokenStringFactory(stream.current());
+ return state.tokenize(stream, state);
+ } else {
+ state.tokenize = formatStringFactory(stream.current(), state.tokenize);
+ return state.tokenize(stream, state);
+ }
}
for (var i = 0; i < operators.length; i++)
@@ -178,6 +180,77 @@
return ERRORCLASS;
}
+ function formatStringFactory(delimiter, tokenOuter) {
+ while ("rubf".indexOf(delimiter.charAt(0).toLowerCase()) >= 0)
+ delimiter = delimiter.substr(1);
+
+ var singleline = delimiter.length == 1;
+ var OUTCLASS = "string";
+
+ function tokenFString(stream, state) {
+ // inside f-str Expression
+ if (stream.match(delimiter)) {
+ // expression ends pre-maturally, but very common in editing
+ // Could show error to remind users to close brace here
+ state.tokenize = tokenString
+ return OUTCLASS;
+ } else if (stream.match('{')) {
+ // starting brace, if not eaten below
+ return "punctuation";
+ } else if (stream.match('}')) {
+ // return to regular inside string state
+ state.tokenize = tokenString
+ return "punctuation";
+ } else {
+ // use tokenBaseInner to parse the expression
+ return tokenBaseInner(stream, state);
+ }
+ }
+
+ function tokenString(stream, state) {
+ while (!stream.eol()) {
+ stream.eatWhile(/[^'"\{\}\\]/);
+ if (stream.eat("\\")) {
+ stream.next();
+ if (singleline && stream.eol())
+ return OUTCLASS;
+ } else if (stream.match(delimiter)) {
+ state.tokenize = tokenOuter;
+ return OUTCLASS;
+ } else if (stream.match('{{')) {
+ // ignore {{ in f-str
+ return OUTCLASS;
+ } else if (stream.match('{', false)) {
+ // switch to nested mode
+ state.tokenize = tokenFString
+ if (stream.current()) {
+ return OUTCLASS;
+ } else {
+ // need to return something, so eat the starting {
+ stream.next();
+ return "punctuation";
+ }
+ } else if (stream.match('}}')) {
+ return OUTCLASS;
+ } else if (stream.match('}')) {
+ // single } in f-string is an error
+ return ERRORCLASS;
+ } else {
+ stream.eat(/['"]/);
+ }
+ }
+ if (singleline) {
+ if (parserConf.singleLineStringErrors)
+ return ERRORCLASS;
+ else
+ state.tokenize = tokenOuter;
+ }
+ return OUTCLASS;
+ }
+ tokenString.isString = true;
+ return tokenString;
+ }
+
function tokenStringFactory(delimiter) {
while ("rubf".indexOf(delimiter.charAt(0).toLowerCase()) >= 0)
delimiter = delimiter.substr(1);
@@ -258,14 +331,16 @@
if (current == ":" && !state.lambda && top(state).type == "py")
pushPyScope(state);
- var delimiter_index = current.length == 1 ? "[({".indexOf(current) : -1;
- if (delimiter_index != -1)
- pushBracketScope(stream, state, "])}".slice(delimiter_index, delimiter_index+1));
+ if (current.length == 1 && !/string|comment/.test(style)) {
+ var delimiter_index = "[({".indexOf(current);
+ if (delimiter_index != -1)
+ pushBracketScope(stream, state, "])}".slice(delimiter_index, delimiter_index+1));
- delimiter_index = "])}".indexOf(current);
- if (delimiter_index != -1) {
- if (top(state).type == current) state.indent = state.scopes.pop().offset - hangingIndent
- else return ERRORCLASS;
+ delimiter_index = "])}".indexOf(current);
+ if (delimiter_index != -1) {
+ if (top(state).type == current) state.indent = state.scopes.pop().offset - hangingIndent
+ else return ERRORCLASS;
+ }
}
if (state.dedent > 0 && stream.eol() && top(state).type == "py") {
if (state.scopes.length > 1) state.scopes.pop();
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/shell.js b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/shell.js
index 9b8b90b3056..0e667e6a54f 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/shell.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/shell.js
@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
+// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -31,7 +31,7 @@ CodeMirror.defineMode('shell', function() {
// Commands
define('builtin', 'ab awk bash beep cat cc cd chown chmod chroot clear cp ' +
'curl cut diff echo find gawk gcc get git grep hg kill killall ln ls make ' +
- 'mkdir openssl mv nc node npm ping ps restart rm rmdir sed service sh ' +
+ 'mkdir openssl mv nc nl node npm ping ps restart rm rmdir sed service sh ' +
'shopt shred source sort sleep ssh start stop su sudo svn tee telnet top ' +
'touch vi vim wall wc wget who write yes zsh');
@@ -84,29 +84,38 @@ CodeMirror.defineMode('shell', function() {
function tokenString(quote, style) {
var close = quote == "(" ? ")" : quote == "{" ? "}" : quote
return function(stream, state) {
- var next, end = false, escaped = false;
+ var next, escaped = false;
while ((next = stream.next()) != null) {
if (next === close && !escaped) {
- end = true;
+ state.tokens.shift();
break;
- }
- if (next === '$' && !escaped && quote !== "'") {
+ } else if (next === '$' && !escaped && quote !== "'" && stream.peek() != close) {
escaped = true;
stream.backUp(1);
state.tokens.unshift(tokenDollar);
break;
- }
- if (!escaped && next === quote && quote !== close) {
+ } else if (!escaped && quote !== close && next === quote) {
state.tokens.unshift(tokenString(quote, style))
return tokenize(stream, state)
+ } else if (!escaped && /['"]/.test(next) && !/['"]/.test(quote)) {
+ state.tokens.unshift(tokenStringStart(next, "string"));
+ stream.backUp(1);
+ break;
}
escaped = !escaped && next === '\\';
}
- if (end) state.tokens.shift();
return style;
};
};
+ function tokenStringStart(quote, style) {
+ return function(stream, state) {
+ state.tokens[0] = tokenString(quote, style)
+ stream.next()
+ return tokenize(stream, state)
+ }
+ }
+
var tokenDollar = function(stream, state) {
if (state.tokens.length > 1) stream.eat('$');
var ch = stream.next()
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/stylus.js b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/stylus.js
index b83be16f42b..dbe241d6132 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/stylus.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/cm_modes/stylus.js
@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
+// Distributed under an MIT license: https://codemirror.net/LICENSE
// Stylus mode created by Dmitry Kiselyov http://git.io/AaRB
@@ -76,7 +76,7 @@
if (ch == "#") {
stream.next();
// Hex color
- if (stream.match(/^[0-9a-f]{6}|[0-9a-f]{3}/i)) {
+ if (stream.match(/^[0-9a-f]{3}([0-9a-f]([0-9a-f]{2}){0,2})?\b/i)) {
return ["atom", "atom"];
}
// ID selector
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/css.js b/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/css.js
index 00e9b3df132..8b5722905de 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/css.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/css.js
@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
+// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -77,9 +77,9 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
return ret("qualifier", "qualifier");
} else if (/[:;{}\[\]\(\)]/.test(ch)) {
return ret(null, ch);
- } else if ((ch == "u" && stream.match(/rl(-prefix)?\(/)) ||
- (ch == "d" && stream.match("omain(")) ||
- (ch == "r" && stream.match("egexp("))) {
+ } else if (((ch == "u" || ch == "U") && stream.match(/rl(-prefix)?\(/i)) ||
+ ((ch == "d" || ch == "D") && stream.match("omain(", true, true)) ||
+ ((ch == "r" || ch == "R") && stream.match("egexp(", true, true))) {
stream.backUp(1);
state.tokenize = tokenParenthesized;
return ret("property", "word");
@@ -162,16 +162,16 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
return pushContext(state, stream, "block");
} else if (type == "}" && state.context.prev) {
return popContext(state);
- } else if (supportsAtComponent && /@component/.test(type)) {
+ } else if (supportsAtComponent && /@component/i.test(type)) {
return pushContext(state, stream, "atComponentBlock");
- } else if (/^@(-moz-)?document$/.test(type)) {
+ } else if (/^@(-moz-)?document$/i.test(type)) {
return pushContext(state, stream, "documentTypes");
- } else if (/^@(media|supports|(-moz-)?document|import)$/.test(type)) {
+ } else if (/^@(media|supports|(-moz-)?document|import)$/i.test(type)) {
return pushContext(state, stream, "atBlock");
- } else if (/^@(font-face|counter-style)/.test(type)) {
+ } else if (/^@(font-face|counter-style)/i.test(type)) {
state.stateArg = type;
return "restricted_atBlock_before";
- } else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) {
+ } else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/i.test(type)) {
return "keyframes";
} else if (type && type.charAt(0) == "@") {
return pushContext(state, stream, "at");
@@ -793,7 +793,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
},
"@": function(stream) {
if (stream.eat("{")) return [null, "interpolation"];
- if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/, false)) return false;
+ if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/i, false)) return false;
stream.eatWhile(/[\w\\\-]/);
if (stream.match(/^\s*:/, false))
return ["variable-2", "variable-definition"];
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/htmlembedded.js b/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/htmlembedded.js
index 464dc57f838..439e63a4276 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/htmlembedded.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/htmlembedded.js
@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
+// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -14,7 +14,16 @@
"use strict";
CodeMirror.defineMode("htmlembedded", function(config, parserConfig) {
+ var closeComment = parserConfig.closeComment || "--%>"
return CodeMirror.multiplexingMode(CodeMirror.getMode(config, "htmlmixed"), {
+ open: parserConfig.openComment || "<%--",
+ close: closeComment,
+ delimStyle: "comment",
+ mode: {token: function(stream) {
+ stream.skipTo(closeComment) || stream.skipToEnd()
+ return "comment"
+ }}
+ }, {
open: parserConfig.open || parserConfig.scriptStartRegex || "<%",
close: parserConfig.close || parserConfig.scriptEndRegex || "%>",
mode: CodeMirror.getMode(config, parserConfig.scriptingModeSpec)
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/htmlmixed.js b/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/htmlmixed.js
index 33398ec5c0b..c9925384776 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/htmlmixed.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/htmlmixed.js
@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
+// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/javascript.js b/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/javascript.js
index 139e53dfe4c..a31ffff8ef3 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/javascript.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/javascript.js
@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
+// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -26,7 +26,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"), D = kw("keyword d");
var operator = kw("operator"), atom = {type: "atom", style: "atom"};
- var jsKeywords = {
+ return {
"if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
"return": D, "break": D, "continue": D, "new": kw("new"), "delete": C, "void": C, "throw": C,
"debugger": kw("debugger"), "var": kw("var"), "const": kw("var"), "let": kw("var"),
@@ -38,33 +38,6 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
"yield": C, "export": kw("export"), "import": kw("import"), "extends": C,
"await": C
};
-
- // Extend the 'normal' keywords with the TypeScript language extensions
- if (isTS) {
- var type = {type: "variable", style: "type"};
- var tsKeywords = {
- // object-like things
- "interface": kw("class"),
- "implements": C,
- "namespace": C,
-
- // scope modifiers
- "public": kw("modifier"),
- "private": kw("modifier"),
- "protected": kw("modifier"),
- "abstract": kw("modifier"),
- "readonly": kw("modifier"),
-
- // types
- "string": type, "number": type, "boolean": type, "any": type
- };
-
- for (var attr in tsKeywords) {
- jsKeywords[attr] = tsKeywords[attr];
- }
- }
-
- return jsKeywords;
}();
var isOperatorChar = /[+\-*&%=<>!?|~^@]/;
@@ -102,17 +75,10 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
return ret(ch);
} else if (ch == "=" && stream.eat(">")) {
return ret("=>", "operator");
- } else if (ch == "0" && stream.eat(/x/i)) {
- stream.eatWhile(/[\da-f]/i);
- return ret("number", "number");
- } else if (ch == "0" && stream.eat(/o/i)) {
- stream.eatWhile(/[0-7]/i);
- return ret("number", "number");
- } else if (ch == "0" && stream.eat(/b/i)) {
- stream.eatWhile(/[01]/i);
+ } else if (ch == "0" && stream.match(/^(?:x[\da-f]+|o[0-7]+|b[01]+)n?/i)) {
return ret("number", "number");
} else if (/\d/.test(ch)) {
- stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
+ stream.match(/^\d*(?:n|(?:\.\d*)?(?:[eE][+\-]?\d+)?)?/);
return ret("number", "number");
} else if (ch == "/") {
if (stream.eat("*")) {
@@ -123,7 +89,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
return ret("comment", "comment");
} else if (expressionAllowed(stream, state, 1)) {
readRegexp(stream);
- stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/);
+ stream.match(/^\b(([gimyus])(?![gimyus]*\2))+\b/);
return ret("regexp", "string-2");
} else {
stream.eat("=");
@@ -153,7 +119,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
var kw = keywords[word]
return ret(kw.type, kw.style, word)
}
- if (word == "async" && stream.match(/^(\s|\/\*.*?\*\/)*[\(\w]/, false))
+ if (word == "async" && stream.match(/^(\s|\/\*.*?\*\/)*[\[\(\w]/, false))
return ret("async", "keyword", word)
}
return ret("variable", "variable", word)
@@ -292,35 +258,68 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
pass.apply(null, arguments);
return true;
}
+ function inList(name, list) {
+ for (var v = list; v; v = v.next) if (v.name == name) return true
+ return false;
+ }
function register(varname) {
- function inList(list) {
- for (var v = list; v; v = v.next)
- if (v.name == varname) return true;
- return false;
- }
var state = cx.state;
cx.marked = "def";
if (state.context) {
- if (inList(state.localVars)) return;
- state.localVars = {name: varname, next: state.localVars};
+ if (state.lexical.info == "var" && state.context && state.context.block) {
+ // FIXME function decls are also not block scoped
+ var newContext = registerVarScoped(varname, state.context)
+ if (newContext != null) {
+ state.context = newContext
+ return
+ }
+ } else if (!inList(varname, state.localVars)) {
+ state.localVars = new Var(varname, state.localVars)
+ return
+ }
+ }
+ // Fall through means this is global
+ if (parserConfig.globalVars && !inList(varname, state.globalVars))
+ state.globalVars = new Var(varname, state.globalVars)
+ }
+ function registerVarScoped(varname, context) {
+ if (!context) {
+ return null
+ } else if (context.block) {
+ var inner = registerVarScoped(varname, context.prev)
+ if (!inner) return null
+ if (inner == context.prev) return context
+ return new Context(inner, context.vars, true)
+ } else if (inList(varname, context.vars)) {
+ return context
} else {
- if (inList(state.globalVars)) return;
- if (parserConfig.globalVars)
- state.globalVars = {name: varname, next: state.globalVars};
+ return new Context(context.prev, new Var(varname, context.vars), false)
}
}
+ function isModifier(name) {
+ return name == "public" || name == "private" || name == "protected" || name == "abstract" || name == "readonly"
+ }
+
// Combinators
- var defaultVars = {name: "this", next: {name: "arguments"}};
+ function Context(prev, vars, block) { this.prev = prev; this.vars = vars; this.block = block }
+ function Var(name, next) { this.name = name; this.next = next }
+
+ var defaultVars = new Var("this", new Var("arguments", null))
function pushcontext() {
- cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
- cx.state.localVars = defaultVars;
+ cx.state.context = new Context(cx.state.context, cx.state.localVars, false)
+ cx.state.localVars = defaultVars
+ }
+ function pushblockcontext() {
+ cx.state.context = new Context(cx.state.context, cx.state.localVars, true)
+ cx.state.localVars = null
}
function popcontext() {
- cx.state.localVars = cx.state.context.vars;
- cx.state.context = cx.state.context.prev;
+ cx.state.localVars = cx.state.context.vars
+ cx.state.context = cx.state.context.prev
}
+ popcontext.lex = true
function pushlex(type, info) {
var result = function() {
var state = cx.state, indent = state.indented;
@@ -345,19 +344,19 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
function expect(wanted) {
function exp(type) {
if (type == wanted) return cont();
- else if (wanted == ";") return pass();
+ else if (wanted == ";" || type == "}" || type == ")" || type == "]") return pass();
else return cont(exp);
};
return exp;
}
function statement(type, value) {
- if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex);
+ if (type == "var") return cont(pushlex("vardef", value), vardef, expect(";"), poplex);
if (type == "keyword a") return cont(pushlex("form"), parenExpr, statement, poplex);
if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
if (type == "keyword d") return cx.stream.match(/^\s*$/, false) ? cont() : cont(pushlex("stat"), maybeexpression, expect(";"), poplex);
if (type == "debugger") return cont(expect(";"));
- if (type == "{") return cont(pushlex("}"), block, poplex);
+ if (type == "{") return cont(pushlex("}"), pushblockcontext, block, poplex, popcontext);
if (type == ";") return cont();
if (type == "if") {
if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex)
@@ -366,44 +365,51 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
}
if (type == "function") return cont(functiondef);
if (type == "for") return cont(pushlex("form"), forspec, statement, poplex);
+ if (type == "class" || (isTS && value == "interface")) { cx.marked = "keyword"; return cont(pushlex("form"), className, poplex); }
if (type == "variable") {
- if (isTS && value == "type") {
- cx.marked = "keyword"
- return cont(typeexpr, expect("operator"), typeexpr, expect(";"));
- } else if (isTS && value == "declare") {
+ if (isTS && value == "declare") {
cx.marked = "keyword"
return cont(statement)
- } else if (isTS && (value == "module" || value == "enum") && cx.stream.match(/^\s*\w/, false)) {
+ } else if (isTS && (value == "module" || value == "enum" || value == "type") && cx.stream.match(/^\s*\w/, false)) {
+ cx.marked = "keyword"
+ if (value == "enum") return cont(enumdef);
+ else if (value == "type") return cont(typeexpr, expect("operator"), typeexpr, expect(";"));
+ else return cont(pushlex("form"), pattern, expect("{"), pushlex("}"), block, poplex, poplex)
+ } else if (isTS && value == "namespace") {
cx.marked = "keyword"
- return cont(pushlex("form"), pattern, expect("{"), pushlex("}"), block, poplex, poplex)
+ return cont(pushlex("form"), expression, block, poplex)
+ } else if (isTS && value == "abstract") {
+ cx.marked = "keyword"
+ return cont(statement)
} else {
return cont(pushlex("stat"), maybelabel);
}
}
- if (type == "switch") return cont(pushlex("form"), parenExpr, expect("{"), pushlex("}", "switch"),
- block, poplex, poplex);
+ if (type == "switch") return cont(pushlex("form"), parenExpr, expect("{"), pushlex("}", "switch"), pushblockcontext,
+ block, poplex, poplex, popcontext);
if (type == "case") return cont(expression, expect(":"));
if (type == "default") return cont(expect(":"));
- if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
- statement, poplex, popcontext);
- if (type == "class") return cont(pushlex("form"), className, poplex);
+ if (type == "catch") return cont(pushlex("form"), pushcontext, maybeCatchBinding, statement, poplex, popcontext);
if (type == "export") return cont(pushlex("stat"), afterExport, poplex);
if (type == "import") return cont(pushlex("stat"), afterImport, poplex);
if (type == "async") return cont(statement)
if (value == "@") return cont(expression, statement)
return pass(pushlex("stat"), expression, expect(";"), poplex);
}
- function expression(type) {
- return expressionInner(type, false);
+ function maybeCatchBinding(type) {
+ if (type == "(") return cont(funarg, expect(")"))
}
- function expressionNoComma(type) {
- return expressionInner(type, true);
+ function expression(type, value) {
+ return expressionInner(type, value, false);
+ }
+ function expressionNoComma(type, value) {
+ return expressionInner(type, value, true);
}
function parenExpr(type) {
if (type != "(") return pass()
return cont(pushlex(")"), expression, expect(")"), poplex)
}
- function expressionInner(type, noComma) {
+ function expressionInner(type, value, noComma) {
if (cx.state.fatArrowAt == cx.stream.start) {
var body = noComma ? arrowBodyNoComma : arrowBody;
if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, expect("=>"), body, popcontext);
@@ -413,7 +419,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
if (type == "function") return cont(functiondef, maybeop);
- if (type == "class") return cont(pushlex("form"), classExpression, poplex);
+ if (type == "class" || (isTS && value == "interface")) { cx.marked = "keyword"; return cont(pushlex("form"), classExpression, poplex); }
if (type == "keyword c" || type == "async") return cont(noComma ? expressionNoComma : expression);
if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop);
if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
@@ -421,6 +427,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (type == "{") return contCommasep(objprop, "}", null, maybeop);
if (type == "quasi") return pass(quasi, maybeop);
if (type == "new") return cont(maybeTarget(noComma));
+ if (type == "import") return cont(expression);
return cont();
}
function maybeexpression(type) {
@@ -438,6 +445,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
if (type == "operator") {
if (/\+\+|--/.test(value) || isTS && value == "!") return cont(me);
+ if (isTS && value == "<" && cx.stream.match(/^([^>]|<.*?>)*>\s*\(/, false))
+ return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, me);
if (value == "?") return cont(expression, expect(":"), expr);
return cont(expr);
}
@@ -509,10 +518,11 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
return cont(afterprop);
} else if (type == "jsonld-keyword") {
return cont(afterprop);
- } else if (type == "modifier") {
+ } else if (isTS && isModifier(value)) {
+ cx.marked = "keyword"
return cont(objprop)
} else if (type == "[") {
- return cont(expression, expect("]"), afterprop);
+ return cont(expression, maybetype, expect("]"), afterprop);
} else if (type == "spread") {
return cont(expressionNoComma, afterprop);
} else if (value == "*") {
@@ -564,20 +574,32 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (value == "?") return cont(maybetype);
}
}
+ function mayberettype(type) {
+ if (isTS && type == ":") {
+ if (cx.stream.match(/^\s*\w+\s+is\b/, false)) return cont(expression, isKW, typeexpr)
+ else return cont(typeexpr)
+ }
+ }
+ function isKW(_, value) {
+ if (value == "is") {
+ cx.marked = "keyword"
+ return cont()
+ }
+ }
function typeexpr(type, value) {
+ if (value == "keyof" || value == "typeof") {
+ cx.marked = "keyword"
+ return cont(value == "keyof" ? typeexpr : expressionNoComma)
+ }
if (type == "variable" || value == "void") {
- if (value == "keyof") {
- cx.marked = "keyword"
- return cont(typeexpr)
- } else {
- cx.marked = "type"
- return cont(afterType)
- }
+ cx.marked = "type"
+ return cont(afterType)
}
if (type == "string" || type == "number" || type == "atom") return cont(afterType);
if (type == "[") return cont(pushlex("]"), commasep(typeexpr, "]", ","), poplex, afterType)
if (type == "{") return cont(pushlex("}"), commasep(typeprop, "}", ",;"), poplex, afterType)
if (type == "(") return cont(commasep(typearg, ")"), maybeReturnType)
+ if (type == "<") return cont(commasep(typeexpr, ">"), typeexpr)
}
function maybeReturnType(type) {
if (type == "=>") return cont(typeexpr)
@@ -594,15 +616,16 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
return cont(expression, maybetype, expect("]"), typeprop)
}
}
- function typearg(type) {
- if (type == "variable") return cont(typearg)
- else if (type == ":") return cont(typeexpr)
+ function typearg(type, value) {
+ if (type == "variable" && cx.stream.match(/^\s*[?:]/, false) || value == "?") return cont(typearg)
+ if (type == ":") return cont(typeexpr)
+ return pass(typeexpr)
}
function afterType(type, value) {
if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType)
- if (value == "|" || type == ".") return cont(typeexpr)
+ if (value == "|" || type == "." || value == "&") return cont(typeexpr)
if (type == "[") return cont(expect("]"), afterType)
- if (value == "extends") return cont(typeexpr)
+ if (value == "extends" || value == "implements") { cx.marked = "keyword"; return cont(typeexpr) }
}
function maybeTypeArgs(_, value) {
if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType)
@@ -613,11 +636,12 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
function maybeTypeDefault(_, value) {
if (value == "=") return cont(typeexpr)
}
- function vardef() {
+ function vardef(_, value) {
+ if (value == "enum") {cx.marked = "keyword"; return cont(enumdef)}
return pass(pattern, maybetype, maybeAssign, vardefCont);
}
function pattern(type, value) {
- if (type == "modifier") return cont(pattern)
+ if (isTS && isModifier(value)) { cx.marked = "keyword"; return cont(pattern) }
if (type == "variable") { register(value); return cont(); }
if (type == "spread") return cont(pattern);
if (type == "[") return contCommasep(pattern, "]");
@@ -642,7 +666,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
function maybeelse(type, value) {
if (type == "keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex);
}
- function forspec(type) {
+ function forspec(type, value) {
+ if (value == "await") return cont(forspec);
if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex);
}
function forspec1(type) {
@@ -666,12 +691,13 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
function functiondef(type, value) {
if (value == "*") {cx.marked = "keyword"; return cont(functiondef);}
if (type == "variable") {register(value); return cont(functiondef);}
- if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, maybetype, statement, popcontext);
+ if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, mayberettype, statement, popcontext);
if (isTS && value == "<") return cont(pushlex(">"), commasep(typeparam, ">"), poplex, functiondef)
}
function funarg(type, value) {
if (value == "@") cont(expression, funarg)
- if (type == "spread" || type == "modifier") return cont(funarg);
+ if (type == "spread") return cont(funarg);
+ if (isTS && isModifier(value)) { cx.marked = "keyword"; return cont(funarg); }
return pass(pattern, maybetype, maybeAssign);
}
function classExpression(type, value) {
@@ -684,14 +710,16 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
}
function classNameAfter(type, value) {
if (value == "<") return cont(pushlex(">"), commasep(typeparam, ">"), poplex, classNameAfter)
- if (value == "extends" || value == "implements" || (isTS && type == ","))
+ if (value == "extends" || value == "implements" || (isTS && type == ",")) {
+ if (value == "implements") cx.marked = "keyword";
return cont(isTS ? typeexpr : expression, classNameAfter);
+ }
if (type == "{") return cont(pushlex("}"), classBody, poplex);
}
function classBody(type, value) {
- if (type == "modifier" || type == "async" ||
+ if (type == "async" ||
(type == "variable" &&
- (value == "static" || value == "get" || value == "set") &&
+ (value == "static" || value == "get" || value == "set" || (isTS && isModifier(value))) &&
cx.stream.match(/^\s+[\w$\xa1-\uffff]/, false))) {
cx.marked = "keyword";
return cont(classBody);
@@ -701,7 +729,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
return cont(isTS ? classfield : functiondef, classBody);
}
if (type == "[")
- return cont(expression, expect("]"), isTS ? classfield : functiondef, classBody)
+ return cont(expression, maybetype, expect("]"), isTS ? classfield : functiondef, classBody)
if (value == "*") {
cx.marked = "keyword";
return cont(classBody);
@@ -728,6 +756,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
}
function afterImport(type) {
if (type == "string") return cont();
+ if (type == "(") return pass(expression);
return pass(importSpec, maybeMoreImports, maybeFrom);
}
function importSpec(type, value) {
@@ -749,6 +778,12 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (type == "]") return cont();
return pass(commasep(expressionNoComma, "]"));
}
+ function enumdef() {
+ return pass(pushlex("form"), pattern, expect("{"), pushlex("}"), commasep(enummember, "}"), poplex, poplex)
+ }
+ function enummember() {
+ return pass(pattern, maybeAssign);
+ }
function isContinuedStatement(state, textAfter) {
return state.lastType == "operator" || state.lastType == "," ||
@@ -772,7 +807,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
cc: [],
lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
localVars: parserConfig.localVars,
- context: parserConfig.localVars && {vars: parserConfig.localVars},
+ context: parserConfig.localVars && new Context(null, null, false),
indented: basecolumn || 0
};
if (parserConfig.globalVars && typeof parserConfig.globalVars == "object")
@@ -813,7 +848,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
lexical = lexical.prev;
var type = lexical.type, closing = firstChar == type;
- if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0);
+ if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info.length + 1 : 0);
else if (type == "form" && firstChar == "{") return lexical.indented;
else if (type == "form") return lexical.indented + indentUnit;
else if (type == "stat")
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/xml.js b/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/xml.js
index a36573949eb..b67bf850b1f 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/xml.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/cm_web_modes/xml.js
@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
+// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -52,6 +52,7 @@ var xmlConfig = {
doNotIndent: {},
allowUnquoted: false,
allowMissing: false,
+ allowMissingTagName: false,
caseFold: false
}
@@ -162,8 +163,9 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
stream.next();
}
return style;
- };
+ }
}
+
function doctype(depth) {
return function(stream, state) {
var ch;
@@ -226,6 +228,9 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
state.tagName = stream.current();
setStyle = "tag";
return attrState;
+ } else if (config.allowMissingTagName && type == "endTag") {
+ setStyle = "tag bracket";
+ return attrState(type, stream, state);
} else {
setStyle = "error";
return tagNameState;
@@ -244,6 +249,9 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
setStyle = "tag error";
return closeStateErr;
}
+ } else if (config.allowMissingTagName && type == "endTag") {
+ setStyle = "tag bracket";
+ return closeState(type, stream, state);
} else {
setStyle = "error";
return closeStateErr;
@@ -391,4 +399,4 @@ CodeMirror.defineMIME("application/xml", "xml");
if (!CodeMirror.mimeModes.hasOwnProperty("text/html"))
CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});
-}); \ No newline at end of file
+});
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/common/ResourceType.js b/chromium/third_party/blink/renderer/devtools/front_end/common/ResourceType.js
index 75d32a15fd3..ebc106c12ec 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/common/ResourceType.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/common/ResourceType.js
@@ -92,6 +92,14 @@ Common.ResourceType = class {
}
/**
+ * @param {string} ext
+ * @return {string|undefined}
+ */
+ static mimeFromExtension(ext) {
+ return Common.ResourceType._mimeTypeByExtension.get(ext);
+ }
+
+ /**
* @return {string}
*/
name() {
@@ -123,7 +131,7 @@ Common.ResourceType = class {
* @return {boolean}
*/
isScript() {
- return this._name === 'script' || this._name === 'sm-script' || this._name === 'snippet';
+ return this._name === 'script' || this._name === 'sm-script';
}
/**
@@ -219,7 +227,6 @@ Common.resourceTypes = {
Fetch: new Common.ResourceType('fetch', 'Fetch', Common.resourceCategories.XHR, true),
EventSource: new Common.ResourceType('eventsource', 'EventSource', Common.resourceCategories.XHR, true),
Script: new Common.ResourceType('script', 'Script', Common.resourceCategories.Script, true),
- Snippet: new Common.ResourceType('snippet', 'Snippet', Common.resourceCategories.Script, true),
Stylesheet: new Common.ResourceType('stylesheet', 'Stylesheet', Common.resourceCategories.Stylesheet, true),
Image: new Common.ResourceType('image', 'Image', Common.resourceCategories.Image, false),
Media: new Common.ResourceType('media', 'Media', Common.resourceCategories.Media, false),
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/browser_components/ImagePreview.js b/chromium/third_party/blink/renderer/devtools/front_end/components/ImagePreview.js
index 4abc3c31009..f278a498908 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/browser_components/ImagePreview.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/components/ImagePreview.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-BrowserComponents.ImagePreview = class {
+Components.ImagePreview = class {
/**
* @param {!SDK.Target} target
* @param {string} originalImageURL
@@ -41,7 +41,7 @@ BrowserComponents.ImagePreview = class {
function buildContent() {
const container = createElement('table');
- UI.appendStyle(container, 'browser_components/imagePreview.css');
+ UI.appendStyle(container, 'components/imagePreview.css');
container.className = 'image-preview-container';
const naturalWidth = precomputedFeatures ? precomputedFeatures.naturalWidth : imageElement.naturalWidth;
const naturalHeight = precomputedFeatures ? precomputedFeatures.naturalHeight : imageElement.naturalHeight;
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/components/JSPresentationUtils.js b/chromium/third_party/blink/renderer/devtools/front_end/components/JSPresentationUtils.js
index 9dd411d5946..9ad19488ade 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/components/JSPresentationUtils.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/components/JSPresentationUtils.js
@@ -43,7 +43,6 @@ Components.JSPresentationUtils.buildStackTracePreviewContents = function(
element.style.display = 'inline-block';
const shadowRoot = UI.createShadowRootWithCoreStyles(element, 'components/jsUtils.css');
const contentElement = shadowRoot.createChild('table', 'stack-preview-container');
- const debuggerModel = target ? target.model(SDK.DebuggerModel) : null;
let totalHiddenCallFramesCount = 0;
/**
@@ -59,15 +58,11 @@ Components.JSPresentationUtils.buildStackTracePreviewContents = function(
const link = linkifier.maybeLinkifyConsoleCallFrame(target, stackFrame);
if (link) {
link.addEventListener('contextmenu', populateContextMenu.bind(null, link));
- if (debuggerModel) {
- const location = debuggerModel.createRawLocationByScriptId(
- stackFrame.scriptId, stackFrame.lineNumber, stackFrame.columnNumber);
- if (location && Bindings.blackboxManager.isBlackboxedRawLocation(location)) {
- row.classList.add('blackboxed');
- ++hiddenCallFrames;
- }
+ const uiLocation = Components.Linkifier.uiLocation(link);
+ if (uiLocation && Bindings.blackboxManager.isBlackboxedUISourceCode(uiLocation.uiSourceCode)) {
+ row.classList.add('blackboxed');
+ ++hiddenCallFrames;
}
-
row.createChild('td').textContent = ' @ ';
row.createChild('td').appendChild(link);
}
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/browser_components/imagePreview.css b/chromium/third_party/blink/renderer/devtools/front_end/components/imagePreview.css
index 08020e5bdec..08020e5bdec 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/browser_components/imagePreview.css
+++ b/chromium/third_party/blink/renderer/devtools/front_end/components/imagePreview.css
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/components/module.json b/chromium/third_party/blink/renderer/devtools/front_end/components/module.json
index 8986fdfe000..b7b5ca9282e 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/components/module.json
+++ b/chromium/third_party/blink/renderer/devtools/front_end/components/module.json
@@ -7,11 +7,13 @@
"scripts": [
"JSPresentationUtils.js",
"DockController.js",
+ "ImagePreview.js",
"Linkifier.js",
"Reload.js",
"TargetDetachedDialog.js"
],
"resources": [
+ "imagePreview.css",
"jsUtils.css"
]
}
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/console/ConsolePinPane.js b/chromium/third_party/blink/renderer/devtools/front_end/console/ConsolePinPane.js
index c806078b6ee..325fa85556f 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/console/ConsolePinPane.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/console/ConsolePinPane.js
@@ -2,15 +2,24 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-Console.ConsolePinPane = class extends UI.VBox {
+Console.ConsolePinPane = class extends UI.ThrottledWidget {
constructor() {
- super(true);
+ super(true, 250);
this.registerRequiredCSS('console/consolePinPane.css');
+ this.registerRequiredCSS('object_ui/objectValue.css');
this.contentElement.classList.add('console-pins', 'monospace');
this.contentElement.addEventListener('contextmenu', this._contextMenuEventFired.bind(this), false);
/** @type {!Set<!Console.ConsolePin>} */
this._pins = new Set();
+ this._pinsSetting = Common.settings.createLocalSetting('consolePins', []);
+ for (const expression of this._pinsSetting.get())
+ this.addPin(expression);
+ }
+
+ _savePins() {
+ const toSave = Array.from(this._pins).map(pin => pin.expression());
+ this._pinsSetting.set(toSave);
}
/**
@@ -23,11 +32,12 @@ Console.ConsolePinPane = class extends UI.VBox {
const targetPinElement = target.enclosingNodeOrSelfWithClass('console-pin');
if (targetPinElement) {
const targetPin = targetPinElement[Console.ConsolePin._PinSymbol];
- contextMenu.editSection().appendItem(ls`Edit pin`, targetPin.focus.bind(targetPin));
- contextMenu.editSection().appendItem(ls`Remove pin`, this._removePin.bind(this, targetPin));
+ contextMenu.editSection().appendItem(ls`Edit expression`, targetPin.focus.bind(targetPin));
+ contextMenu.editSection().appendItem(ls`Remove expression`, this._removePin.bind(this, targetPin));
+ targetPin.appendToContextMenu(contextMenu);
}
}
- contextMenu.editSection().appendItem(ls`Remove all pins`, this._removeAllPins.bind(this));
+ contextMenu.editSection().appendItem(ls`Remove all expressions`, this._removeAllPins.bind(this));
contextMenu.show();
}
@@ -42,41 +52,66 @@ Console.ConsolePinPane = class extends UI.VBox {
_removePin(pin) {
pin.element().remove();
this._pins.delete(pin);
+ this._savePins();
}
/**
* @param {string} expression
+ * @param {boolean=} userGesture
*/
- addPin(expression) {
- const pin = new Console.ConsolePin(expression, this._removePin.bind(this));
+ addPin(expression, userGesture) {
+ const pin = new Console.ConsolePin(expression, this);
this.contentElement.appendChild(pin.element());
this._pins.add(pin);
- pin.focus();
+ this._savePins();
+ if (userGesture)
+ pin.focus();
+ this.update();
+ }
+
+ /**
+ * @override
+ */
+ doUpdate() {
+ if (!this._pins.size || !this.isShowing())
+ return Promise.resolve();
+ if (this.isShowing())
+ this.update();
+ const updatePromises = Array.from(this._pins, pin => pin.updatePreview());
+ return Promise.all(updatePromises).then(this._updatedForTest.bind(this));
+ }
+
+ _updatedForTest() {
}
};
-Console.ConsolePin = class {
+Console.ConsolePin = class extends Common.Object {
/**
* @param {string} expression
- * @param {function(!Console.ConsolePin)} onRemove
+ * @param {!Console.ConsolePinPane} pinPane
*/
- constructor(expression, onRemove) {
+ constructor(expression, pinPane) {
+ super();
const deletePinIcon = UI.Icon.create('smallicon-cross', 'console-delete-pin');
- deletePinIcon.addEventListener('click', () => onRemove(this));
+ deletePinIcon.addEventListener('click', () => pinPane._removePin(this));
const fragment = UI.Fragment.build`
<div class='console-pin'>
${deletePinIcon}
<div class='console-pin-name' $='name'></div>
- <div class='console-pin-preview'>${ls`not available`}</div>
+ <div class='console-pin-preview' $='preview'>${ls`not available`}</div>
</div>`;
this._pinElement = fragment.element();
+ this._pinPreview = fragment.$('preview');
const nameElement = fragment.$('name');
nameElement.title = expression;
this._pinElement[Console.ConsolePin._PinSymbol] = this;
+ /** @type {?SDK.RemoteObject} */
+ this._resultObject = null;
/** @type {?UI.TextEditor} */
this._editor = null;
+ this._committedExpression = expression;
this._editorPromise = self.runtime.extension(UI.TextEditorFactory).instance().then(factory => {
this._editor = factory.createEditor({
@@ -86,18 +121,34 @@ Console.ConsolePin = class {
autoHeight: true,
placeholder: ls`Expression`
});
+ this._editor.configureAutocomplete(ObjectUI.JavaScriptAutocompleteConfig.createConfigForEditor(this._editor));
this._editor.widget().show(nameElement);
this._editor.widget().element.classList.add('console-pin-editor');
this._editor.widget().element.tabIndex = -1;
this._editor.setText(expression);
this._editor.widget().element.addEventListener('keydown', event => {
- if (event.key === 'Tab')
+ if (event.key === 'Tab' && !this._editor.text())
event.consume();
}, true);
+ this._editor.widget().element.addEventListener('focusout', event => {
+ const text = this._editor.text();
+ const trimmedText = text.trim();
+ if (text.length !== trimmedText.length)
+ this._editor.setText(trimmedText);
+ this._committedExpression = trimmedText;
+ pinPane._savePins();
+ });
});
}
/**
+ * @return {string}
+ */
+ expression() {
+ return this._committedExpression;
+ }
+
+ /**
* @return {!Element}
*/
element() {
@@ -109,6 +160,46 @@ Console.ConsolePin = class {
this._editor.widget().focus();
this._editor.setSelection(TextUtils.TextRange.createFromLocation(Infinity, Infinity));
}
+
+ /**
+ * @param {!UI.ContextMenu} contextMenu
+ */
+ appendToContextMenu(contextMenu) {
+ if (this._resultObject)
+ contextMenu.appendApplicableItems(this._resultObject);
+ }
+
+ /**
+ * @return {!Promise}
+ */
+ async updatePreview() {
+ if (!this._editor)
+ return;
+ const text = this._editor.textWithCurrentSuggestion().trim();
+ const isEditing = this._pinElement.hasFocus();
+ const throwOnSideEffect = isEditing && text !== this._committedExpression;
+ const timeout = throwOnSideEffect ? 250 : undefined;
+ const {preview, result} = await ObjectUI.JavaScriptREPL.evaluateAndBuildPreview(
+ text, throwOnSideEffect, timeout, !isEditing /* allowErrors */);
+ this._resultObject = result ? (result.object || null) : null;
+ const previewText = preview.deepTextContent();
+ if (!previewText || previewText !== this._pinPreview.deepTextContent()) {
+ this._pinPreview.removeChildren();
+ if (result && SDK.RuntimeModel.isSideEffectFailure(result)) {
+ const sideEffectLabel = this._pinPreview.createChild('span', 'object-value-calculate-value-button');
+ sideEffectLabel.textContent = `(...)`;
+ sideEffectLabel.title = ls`Evaluate, allowing side effects`;
+ } else if (previewText) {
+ this._pinPreview.appendChild(preview);
+ } else if (!isEditing) {
+ this._pinPreview.createTextChild(ls`not available`);
+ }
+ this._pinPreview.title = previewText;
+ }
+
+ const isError = result && result.exceptionDetails && !SDK.RuntimeModel.isSideEffectFailure(result);
+ this._pinElement.classList.toggle('error-level', isError);
+ }
};
Console.ConsolePin._PinSymbol = Symbol('pinSymbol');
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/console/ConsolePrompt.js b/chromium/third_party/blink/renderer/devtools/front_end/console/ConsolePrompt.js
index 96070e1e0e6..77f40a15994 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/console/ConsolePrompt.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/console/ConsolePrompt.js
@@ -5,6 +5,7 @@
Console.ConsolePrompt = class extends UI.Widget {
constructor() {
super();
+ this.registerRequiredCSS('console/consolePrompt.css');
this._addCompletionsFromHistory = true;
this._history = new Console.ConsoleHistoryManager();
@@ -23,10 +24,6 @@ Console.ConsolePrompt = class extends UI.Widget {
this._eagerEvalSetting.addChangeListener(this._eagerSettingChanged.bind(this));
this._eagerPreviewElement.classList.toggle('hidden', !this._eagerEvalSetting.get());
- // TODO(luoe): split out prompt styles into ConsolePrompt.css.
- const pinsEnabled = Runtime.experiments.isEnabled('pinnedExpressions');
- if (pinsEnabled)
- this.element.style.marginRight = '20px';
this.element.tabIndex = 0;
/** @type {?Promise} */
this._previewRequestForTest = null;
@@ -34,6 +31,8 @@ Console.ConsolePrompt = class extends UI.Widget {
/** @type {?UI.AutocompleteConfig} */
this._defaultAutocompleteConfig = null;
+ this._highlightingNode = false;
+
self.runtime.extension(UI.TextEditorFactory).instance().then(gotFactory.bind(this));
/**
@@ -54,13 +53,6 @@ Console.ConsolePrompt = class extends UI.Widget {
this._editor.widget().show(this.element);
this._editor.addEventListener(UI.TextEditor.Events.TextChanged, this._onTextChanged, this);
this._editor.addEventListener(UI.TextEditor.Events.SuggestionChanged, this._onTextChanged, this);
- if (pinsEnabled) {
- const pinButton = this.element.createChild('span', 'command-pin-button');
- pinButton.title = ls`Pin expression`;
- pinButton.addEventListener('click', () => {
- this.dispatchEventToListeners(Console.ConsolePrompt.Events.ExpressionPinned, this.text());
- });
- }
if (this._isBelowPromptEnabled)
this.element.appendChild(this._eagerPreviewElement);
@@ -104,40 +96,28 @@ Console.ConsolePrompt = class extends UI.Widget {
*/
async _requestPreview() {
const text = this._editor.textWithCurrentSuggestion().trim();
- const executionContext = UI.context.flavor(SDK.ExecutionContext);
- if (!executionContext || !text || text.length > Console.ConsolePrompt._MaxLengthForEvaluation) {
- this._innerPreviewElement.removeChildren();
- return;
- }
-
- const options = {
- expression: SDK.RuntimeModel.wrapObjectLiteralExpressionIfNeeded(text),
- includeCommandLineAPI: true,
- generatePreview: true,
- throwOnSideEffect: true,
- timeout: 500
- };
- const result = await executionContext.evaluate(options, true /* userGesture */, false /* awaitPromise */);
+ const {preview, result} =
+ await ObjectUI.JavaScriptREPL.evaluateAndBuildPreview(text, true /* throwOnSideEffect */, 500);
this._innerPreviewElement.removeChildren();
- if (result.error)
- return;
-
- if (result.exceptionDetails) {
- const exception = result.exceptionDetails.exception.description;
- if (exception.startsWith('TypeError: '))
- this._innerPreviewElement.textContent = exception;
- return;
+ if (preview.deepTextContent() !== this._editor.textWithCurrentSuggestion().trim())
+ this._innerPreviewElement.appendChild(preview);
+ if (result && result.object && result.object.subtype === 'node') {
+ this._highlightingNode = true;
+ SDK.OverlayModel.highlightObjectAsDOMNode(result.object);
+ } else if (this._highlightingNode) {
+ this._highlightingNode = false;
+ SDK.OverlayModel.hideDOMNodeHighlight();
}
+ }
- const {preview, type, subtype, description} = result.object;
- if (preview && type === 'object' && subtype !== 'node') {
- this._formatter.appendObjectPreview(this._innerPreviewElement, preview, false /* isEntry */);
- } else {
- const nonObjectPreview = this._formatter.renderPropertyPreview(type, subtype, description.trimEnd(400));
- this._innerPreviewElement.appendChild(nonObjectPreview);
+ /**
+ * @override
+ */
+ willHide() {
+ if (this._highlightingNode) {
+ this._highlightingNode = false;
+ SDK.OverlayModel.hideDOMNodeHighlight();
}
- if (this._innerPreviewElement.deepTextContent() === this._editor.textWithCurrentSuggestion().trim())
- this._innerPreviewElement.removeChildren();
}
/**
@@ -262,23 +242,15 @@ Console.ConsolePrompt = class extends UI.Widget {
if (!str.length)
return;
- const currentExecutionContext = UI.context.flavor(SDK.ExecutionContext);
- if (!this._isCaretAtEndOfPrompt() || !currentExecutionContext) {
- this._appendCommand(str, true);
+ if (!this._isCaretAtEndOfPrompt()) {
+ await this._appendCommand(str, true);
return;
}
- const result = await currentExecutionContext.runtimeModel.compileScript(str, '', false, currentExecutionContext.id);
- if (str !== this.text())
- return;
- const exceptionDetails = result.exceptionDetails;
- if (exceptionDetails &&
- (exceptionDetails.exception.description.startsWith('SyntaxError: Unexpected end of input') ||
- exceptionDetails.exception.description.startsWith('SyntaxError: Unterminated template literal'))) {
+
+ if (await ObjectUI.JavaScriptAutocomplete.isExpressionComplete(str))
+ await this._appendCommand(str, true);
+ else
this._editor.newlineAndIndent();
- this._enterProcessedForTest();
- return;
- }
- await this._appendCommand(str, true);
this._enterProcessedForTest();
}
@@ -292,15 +264,10 @@ Console.ConsolePrompt = class extends UI.Widget {
if (currentExecutionContext) {
const executionContext = currentExecutionContext;
const message = SDK.consoleModel.addCommandMessage(executionContext, text);
- text = SDK.RuntimeModel.wrapObjectLiteralExpressionIfNeeded(text);
- let preprocessed = false;
- if (text.indexOf('await') !== -1) {
- const preprocessedText = await Formatter.formatterWorkerPool().preprocessTopLevelAwaitExpressions(text);
- preprocessed = !!preprocessedText;
- text = preprocessedText || text;
- }
+ const wrappedResult = await ObjectUI.JavaScriptREPL.preprocessExpression(text);
SDK.consoleModel.evaluateCommandInConsole(
- executionContext, message, text, useCommandLineAPI, /* awaitPromise */ preprocessed);
+ executionContext, message, wrappedResult.text, useCommandLineAPI,
+ /* awaitPromise */ wrappedResult.preprocessed);
if (Console.ConsolePanel.instance().isShowing())
Host.userMetrics.actionTaken(Host.UserMetrics.Action.CommandEvaluatedInConsolePanel);
}
@@ -362,12 +329,6 @@ Console.ConsolePrompt = class extends UI.Widget {
};
/**
- * @const
- * @type {number}
- */
-Console.ConsolePrompt._MaxLengthForEvaluation = 2000;
-
-/**
* @unrestricted
*/
Console.ConsoleHistoryManager = class {
@@ -458,6 +419,5 @@ Console.ConsoleHistoryManager = class {
};
Console.ConsolePrompt.Events = {
- ExpressionPinned: Symbol('ExpressionPinned'),
TextChanged: Symbol('TextChanged')
};
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleView.js b/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleView.js
index d380af97275..598276af7ca 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleView.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleView.js
@@ -105,9 +105,13 @@ Console.ConsoleView = class extends UI.VBox {
toolbar.appendSeparator();
toolbar.appendToolbarItem(this._consoleContextSelector.toolbarItem());
toolbar.appendSeparator();
+ if (Runtime.experiments.isEnabled('pinnedExpressions')) {
+ toolbar.appendToolbarItem(UI.Toolbar.createActionButton(
+ /** @type {!UI.Action }*/ (UI.actionRegistry.action('console.create-pin'))));
+ }
+ toolbar.appendSeparator();
toolbar.appendToolbarItem(this._filter._textFilterUI);
toolbar.appendToolbarItem(this._filter._levelMenuButton);
- toolbar.appendToolbarItem(groupSimilarToggle);
toolbar.appendToolbarItem(this._progressToolbarItem);
rightToolbar.appendSeparator();
rightToolbar.appendToolbarItem(this._filterStatusText);
@@ -136,6 +140,7 @@ Console.ConsoleView = class extends UI.VBox {
settingsToolbarLeft.appendToolbarItem(this._hideNetworkMessagesCheckbox);
settingsToolbarLeft.appendToolbarItem(this._preserveLogCheckbox);
settingsToolbarLeft.appendToolbarItem(filterByExecutionContextCheckbox);
+ settingsToolbarLeft.appendToolbarItem(groupSimilarToggle);
const settingsToolbarRight = new UI.Toolbar('', settingsPane.element);
settingsToolbarRight.makeVertical();
@@ -157,6 +162,10 @@ Console.ConsoleView = class extends UI.VBox {
this._pinPane = new Console.ConsolePinPane();
this._pinPane.element.classList.add('console-view-pinpane');
this._pinPane.show(this._contentsElement);
+ this._pinPane.element.addEventListener('keydown', event => {
+ if (event.key === 'Enter' && event.ctrlKey)
+ this._prompt.focus();
+ });
}
this._viewport = new Console.ConsoleViewport(this);
@@ -198,7 +207,6 @@ Console.ConsoleView = class extends UI.VBox {
this._prompt = new Console.ConsolePrompt();
this._prompt.show(this._promptElement);
this._prompt.element.addEventListener('keydown', this._promptKeyDown.bind(this), true);
- this._prompt.addEventListener(Console.ConsolePrompt.Events.ExpressionPinned, this._promptExpressionPinned, this);
this._prompt.addEventListener(Console.ConsolePrompt.Events.TextChanged, this._promptTextChanged, this);
this._consoleHistoryAutocompleteSetting.addChangeListener(this._consoleHistoryAutocompleteChanged, this);
@@ -583,7 +591,7 @@ Console.ConsoleView = class extends UI.VBox {
if (!this._currentGroup.messagesHidden()) {
const originatingMessage = viewMessage.consoleMessage().originatingMessage();
if (lastMessage && originatingMessage && lastMessage.consoleMessage() === originatingMessage)
- lastMessage.toMessageElement().classList.add('console-adjacent-user-command-result');
+ viewMessage.toMessageElement().classList.add('console-adjacent-user-command-result');
this._visibleViewMessages.push(viewMessage);
this._searchMessage(this._visibleViewMessages.length - 1);
@@ -705,6 +713,8 @@ Console.ConsoleView = class extends UI.VBox {
_tryToCollapseMessages(viewMessage, lastMessage) {
const timestampsShown = this._timestampsSetting.get();
if (!timestampsShown && lastMessage && !viewMessage.consoleMessage().isGroupMessage() &&
+ viewMessage.consoleMessage().type !== SDK.ConsoleMessage.MessageType.Command &&
+ viewMessage.consoleMessage().type !== SDK.ConsoleMessage.MessageType.Result &&
viewMessage.consoleMessage().isEqual(lastMessage.consoleMessage())) {
lastMessage.incrementRepeatCount();
if (viewMessage.isLastInSimilarGroup())
@@ -1155,14 +1165,6 @@ Console.ConsoleView = class extends UI.VBox {
this._updateStickToBottomOnMouseUp();
}
- /**
- * @param {!Common.Event} event
- */
- _promptExpressionPinned(event) {
- const text = /** @type {string} */ (event.data);
- this._pinPane.addPin(text);
- }
-
_promptTextChanged() {
this._viewport.setStickToBottom(this._isScrolledToBottom());
this._promptTextChangedForTest();
@@ -1505,6 +1507,11 @@ Console.ConsoleView.ActionDelegate = class {
case 'console.clear.history':
Console.ConsoleView.instance()._clearHistory();
return true;
+ case 'console.create-pin':
+ if (Runtime.experiments.isEnabled('pinnedExpressions')) {
+ Console.ConsoleView.instance()._pinPane.addPin('', true /* userGesture */);
+ return true;
+ }
}
return false;
}
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleViewMessage.js b/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleViewMessage.js
index fdc97909bcd..783c7ca88f2 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleViewMessage.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleViewMessage.js
@@ -93,7 +93,7 @@ Console.ConsoleViewMessage = class {
*/
willHide() {
this._isVisible = false;
- this._cachedHeight = this.contentElement().offsetHeight;
+ this._cachedHeight = this.element().offsetHeight;
}
/**
@@ -125,9 +125,9 @@ Console.ConsoleViewMessage = class {
*/
_buildTableMessage() {
const formattedMessage = createElementWithClass('span', 'source-code');
- const anchorElement = this._buildMessageAnchor();
- if (anchorElement)
- formattedMessage.appendChild(anchorElement);
+ this._anchorElement = this._buildMessageAnchor();
+ if (this._anchorElement)
+ formattedMessage.appendChild(this._anchorElement);
const badgeElement = this._buildMessageBadge();
if (badgeElement)
formattedMessage.appendChild(badgeElement);
@@ -279,9 +279,9 @@ Console.ConsoleViewMessage = class {
messageElement.classList.add('console-message-text');
const formattedMessage = createElementWithClass('span', 'source-code');
- const anchorElement = this._buildMessageAnchor();
- if (anchorElement)
- formattedMessage.appendChild(anchorElement);
+ this._anchorElement = this._buildMessageAnchor();
+ if (this._anchorElement)
+ formattedMessage.appendChild(this._anchorElement);
const badgeElement = this._buildMessageBadge();
if (badgeElement)
formattedMessage.appendChild(badgeElement);
@@ -796,6 +796,8 @@ Console.ConsoleViewMessage = class {
}
function integerFormatter(obj) {
+ if (obj.type === 'bigint')
+ return obj.description;
if (typeof obj.value !== 'number')
return 'NaN';
return Math.floor(obj.value);
@@ -921,8 +923,10 @@ Console.ConsoleViewMessage = class {
*/
matchesFilterRegex(regexObject) {
regexObject.lastIndex = 0;
- const text = this.contentElement().deepTextContent();
- return regexObject.test(text);
+ const contentElement = this.contentElement();
+ const anchorText = this._anchorElement ? this._anchorElement.deepTextContent() : '';
+ return (anchorText && regexObject.test(anchorText.trim())) ||
+ regexObject.test(contentElement.deepTextContent().slice(anchorText.length));
}
/**
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleViewport.js b/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleViewport.js
index 023ecc6d35d..dad10ac84d1 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleViewport.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/console/ConsoleViewport.js
@@ -51,6 +51,9 @@ Console.ConsoleViewport = class {
this._topGapElement.textContent = '\uFEFF';
this._bottomGapElement.textContent = '\uFEFF';
+ UI.ARIAUtils.markAsHidden(this._topGapElement);
+ UI.ARIAUtils.markAsHidden(this._bottomGapElement);
+
this._provider = provider;
this.element.addEventListener('scroll', this._onScroll.bind(this), false);
this.element.addEventListener('copy', this._onCopy.bind(this), false);
@@ -166,13 +169,22 @@ Console.ConsoleViewport = class {
}
_rebuildCumulativeHeightsIfNeeded() {
+ let totalCachedHeight = 0;
+ let totalMeasuredHeight = 0;
// Check whether current items in DOM have changed heights. Tolerate 1-pixel
// error due to double-to-integer rounding errors.
for (let i = 0; i < this._renderedItems.length; ++i) {
const cachedItemHeight = this._cachedItemHeight(this._firstActiveIndex + i);
- if (Math.abs(cachedItemHeight - this._renderedItems[i].element().offsetHeight) > 1) {
+ const measuredHeight = this._renderedItems[i].element().offsetHeight;
+ if (Math.abs(cachedItemHeight - measuredHeight) > 1) {
+ this._rebuildCumulativeHeights();
+ return;
+ }
+ totalMeasuredHeight += measuredHeight;
+ totalCachedHeight += cachedItemHeight;
+ if (Math.abs(totalCachedHeight - totalMeasuredHeight) > 1) {
this._rebuildCumulativeHeights();
- break;
+ return;
}
}
}
@@ -534,6 +546,9 @@ Console.ConsoleViewport = class {
const lastVisibleIndex = this.lastVisibleIndex();
if (index > firstVisibleIndex && index < lastVisibleIndex)
return;
+ // If the prompt is visible, then the last item must be fully on screen.
+ if (index === lastVisibleIndex && this._cumulativeHeights[index] <= this.element.scrollTop + this._visibleHeight())
+ return;
if (makeLast)
this.forceScrollItemToBeLast(index);
else if (index <= firstVisibleIndex)
@@ -553,6 +568,8 @@ Console.ConsoleViewport = class {
if (this.element.isScrolledToBottom())
this.setStickToBottom(true);
this.refresh();
+ // After refresh, the item is in DOM, but may not be visible (items above were larger than expected).
+ this.renderedElementAt(index).scrollIntoView(true /* alignTop */);
}
/**
@@ -566,6 +583,8 @@ Console.ConsoleViewport = class {
if (this.element.isScrolledToBottom())
this.setStickToBottom(true);
this.refresh();
+ // After refresh, the item is in DOM, but may not be visible (items above were larger than expected).
+ this.renderedElementAt(index).scrollIntoView(false /* alignTop */);
}
/**
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/console/consolePinPane.css b/chromium/third_party/blink/renderer/devtools/front_end/console/consolePinPane.css
index c71d0e75ead..5fbf25d8378 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/console/consolePinPane.css
+++ b/chromium/third_party/blink/renderer/devtools/front_end/console/consolePinPane.css
@@ -7,25 +7,43 @@
.console-pins {
overflow-y: auto;
background: var(--toolbar-bg-color);
+ --error-background-color: hsl(0, 100%, 97%);
+ --error-border-color: hsl(0, 100%, 92%);
+ --error-text-color: red;
+}
+
+:host-context(.-theme-with-dark-background) .console-pins {
+ --error-background-color: hsl(0, 100%, 8%);
+ --error-border-color: rgb(92, 0, 0);
+ --error-text-color: hsl(0, 100%, 75%);
}
.console-pins:not(:empty) {
border-bottom: 1px solid var(--divider-color);
- padding: 5px 28px 0 24px;
}
.console-pin {
- margin-bottom: 2px;
position: relative;
user-select: text;
flex: none;
- padding-bottom: 6px;
+ padding: 2px 0 6px 24px;
}
.console-pin:not(:last-child) {
border-bottom: 1px solid #e4e4e4;
}
+.console-pin:not(:last-child).error-level:not(:focus-within) {
+ border-top: 1px solid var(--error-border-color);
+ border-bottom: 1px solid var(--error-border-color);
+ margin-top: -1px;
+}
+
+.console-pin.error-level:not(:focus-within) {
+ background-color: var(--error-background-color);
+ color: var(--error-text-color);
+}
+
.console-pin-name {
margin-left: -4px;
margin-bottom: 1px;
@@ -38,13 +56,18 @@
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
+ min-height: 13px;
+}
+
+:host-context(.-theme-with-dark-background) .console-delete-pin {
+ filter: brightness(2);
}
.console-delete-pin {
position: absolute;
- top: 6px;
- left: -16px;
- opacity: 0.5;
+ top: 8px;
+ left: 8px;
+ opacity: 0.7;
cursor: pointer;
}
@@ -54,9 +77,10 @@
.console-pin-name:focus-within {
background: #fff;
- box-shadow: var(--focus-ring-active-shadow);
+ box-shadow: var(--focus-ring-active-shadow) inset;
}
+.console-pin:focus-within .console-pin-preview,
.console-pin-name:not(:focus-within):not(:hover) {
opacity: 0.6;
}
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/console/consolePrompt.css b/chromium/third_party/blink/renderer/devtools/front_end/console/consolePrompt.css
new file mode 100644
index 00000000000..203afb7685f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/devtools/front_end/console/consolePrompt.css
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+
+#console-prompt .CodeMirror {
+ padding: 3px 0 1px 0;
+}
+
+#console-prompt .CodeMirror-line {
+ padding-top: 0;
+}
+
+#console-prompt .CodeMirror-lines {
+ padding-top: 0;
+}
+
+#console-prompt .console-prompt-icon {
+ position: absolute;
+ left: -13px;
+ top: 5px;
+ -webkit-user-select: none;
+}
+
+.console-eager-preview {
+ padding-bottom: 2px;
+ opacity: 0.6;
+ position: relative;
+ height: 15px;
+}
+
+.console-eager-inner-preview {
+ text-overflow: ellipsis;
+ overflow: hidden;
+ margin-left: 4px;
+ height: 100%;
+}
+
+.console-eager-inner-preview * {
+ white-space: nowrap;
+}
+
+.console-eager-inner-preview:empty,
+.console-eager-inner-preview:empty + .preview-result-icon {
+ opacity: 0;
+}
+
+.preview-result-icon {
+ position: absolute;
+ left: -13px;
+ top: 1px;
+}
+
+.command-pin-button::before {
+ content: '\1f4cc';
+}
+
+.command-pin-button {
+ cursor: pointer;
+ position: absolute;
+ top: 1px;
+ right: -40px;
+ opacity: 0;
+ width: 40px;
+}
+
+#console-prompt:hover .command-pin-button {
+ opacity: 0.12;
+}
+
+.-theme-with-dark-background #console-prompt:hover .command-pin-button {
+ opacity: 0.25;
+}
+
+#console-prompt:hover .command-pin-button:hover {
+ opacity: 0.6;
+}
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/console/consoleView.css b/chromium/third_party/blink/renderer/devtools/front_end/console/consoleView.css
index ecc43036f56..17e99cb9519 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/console/consoleView.css
+++ b/chromium/third_party/blink/renderer/devtools/front_end/console/consoleView.css
@@ -30,6 +30,15 @@
.console-view {
background-color: white;
overflow: hidden;
+ --message-border-color: rgb(240, 240, 240);
+ --warning-border-color: hsl(50, 100%, 88%);
+ --error-border-color: hsl(0, 100%, 92%);
+}
+
+.-theme-with-dark-background .console-view {
+ --message-border-color: rgb(58, 58, 58);
+ --warning-border-color: rgb(102, 85, 0);
+ --error-border-color: rgb(92, 0, 0);
}
.console-toolbar-container {
@@ -67,7 +76,6 @@
#console-messages {
flex: 1 1;
- padding: 2px 0;
overflow-y: auto;
word-wrap: break-word;
-webkit-user-select: text;
@@ -81,32 +89,13 @@
min-height: 18px; /* Sync with ConsoleViewMessage.js */
}
-#console-prompt .CodeMirror {
- padding: 3px 0 1px 0;
-}
-
-#console-prompt .CodeMirror-line {
- padding-top: 0;
-}
-
-#console-prompt .CodeMirror-lines {
- padding-top: 0;
-}
-
-#console-prompt .console-prompt-icon {
- position: absolute;
- left: -13px;
- top: 5px;
- -webkit-user-select: none;
-}
-
.console-message,
.console-user-command {
clear: right;
position: relative;
padding: 3px 22px 1px 0;
margin-left: 24px;
- min-height: 18px; /* Sync with ConsoleViewMessage.js */
+ min-height: 17px; /* Sync with ConsoleViewMessage.js */
flex: auto;
display: flex;
}
@@ -199,23 +188,38 @@
.console-message-wrapper {
display: flex;
- border-bottom: 1px solid rgb(240, 240, 240);
+ border-top: 1px solid var(--message-border-color);
+ border-bottom: 1px solid transparent;
+}
+
+.console-message-wrapper:first-of-type {
+ border-top-color: transparent;
}
-.console-message-wrapper.console-adjacent-user-command-result {
- border-bottom: none;
+.console-message-wrapper.console-adjacent-user-command-result:not(.console-error-level):not(.console-warning-level) {
+ border-top: none;
}
-.console-message-wrapper.console-error-level {
- border-top: 1px solid hsl(0, 100%, 92%);
- border-bottom: 1px solid hsl(0, 100%, 92%);
- margin-top: -1px;
+.console-message-wrapper.console-error-level,
+.console-message-wrapper.console-error-level + .console-message-wrapper:not(.console-warning-level) {
+ border-top-color: var(--error-border-color);
}
-.console-message-wrapper.console-warning-level {
- border-top: 1px solid hsl(50, 100%, 88%);
- border-bottom: 1px solid hsl(50, 100%, 88%);
- margin-top: -1px;
+.console-message-wrapper.console-warning-level,
+.console-message-wrapper.console-warning-level + .console-message-wrapper:not(.console-error-level) {
+ border-top-color: var(--warning-border-color);
+}
+
+.console-message-wrapper:last-of-type {
+ border-bottom-color: var(--message-border-color);
+}
+
+.console-message-wrapper.console-error-level:last-of-type {
+ border-bottom-color: var(--error-border-color);
+}
+
+.console-message-wrapper.console-warning-level:last-of-type {
+ border-bottom-color: var(--warning-border-color);
}
.console-message-wrapper .nesting-level-marker {
@@ -351,6 +355,10 @@
clear: both;
}
+.console-message .source-code {
+ line-height: 1.2;
+}
+
.console-message-anchor {
float: right;
text-align: right;
@@ -437,61 +445,7 @@
max-height: 100%;
}
-.console-eager-preview {
- padding-bottom: 2px;
- opacity: 0.6;
- position: relative;
- height: 15px;
-}
-
-.console-eager-inner-preview {
- text-overflow: ellipsis;
- overflow: hidden;
- margin-left: 4px;
- height: 100%;
-}
-
-.console-eager-inner-preview * {
- white-space: nowrap;
-}
-
-.console-eager-inner-preview:empty,
-.console-eager-inner-preview:empty + .preview-result-icon {
- opacity: 0;
-}
-
-.preview-result-icon {
- position: absolute;
- left: -13px;
- top: 1px;
-}
-
.console-view-pinpane {
flex: none;
max-height: 200px;
}
-
-.command-pin-button::before {
- content: '\1f4cc';
-}
-
-.command-pin-button {
- cursor: pointer;
- position: absolute;
- top: 1px;
- right: -40px;
- opacity: 0;
- width: 40px;
-}
-
-#console-prompt:hover .command-pin-button {
- opacity: 0.12;
-}
-
-.-theme-with-dark-background #console-prompt:hover .command-pin-button {
- opacity: 0.25;
-}
-
-#console-prompt:hover .command-pin-button:hover {
- opacity: 0.6;
-}
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/console/module.json b/chromium/third_party/blink/renderer/devtools/front_end/console/module.json
index 16fd2bdfbcc..a60af8b676d 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/console/module.json
+++ b/chromium/third_party/blink/renderer/devtools/front_end/console/module.json
@@ -60,6 +60,14 @@
"className": "Console.ConsoleView.ActionDelegate"
},
{
+ "type": "action",
+ "category": "Console",
+ "actionId": "console.create-pin",
+ "iconClass": "largeicon-visibility",
+ "className": "Console.ConsoleView.ActionDelegate",
+ "title": "Create live expression"
+ },
+ {
"type": "setting",
"category": "Console",
"title": "Hide network messages",
@@ -199,6 +207,7 @@
"resources": [
"consoleContextSelector.css",
"consolePinPane.css",
+ "consolePrompt.css",
"consoleSidebar.css",
"consoleView.css"
]
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/console_test_runner/ConsoleTestRunner.js b/chromium/third_party/blink/renderer/devtools/front_end/console_test_runner/ConsoleTestRunner.js
index e72a511fa43..dc28c73c702 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/console_test_runner/ConsoleTestRunner.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/console_test_runner/ConsoleTestRunner.js
@@ -611,14 +611,12 @@ ConsoleTestRunner.dumpStackTraces = function() {
};
/**
- * Returns actual visible indices. Messages in the margin are treated as NOT visible.
* @return {!{first: number, last: number, count: number}}
*/
ConsoleTestRunner.visibleIndices = function() {
const consoleView = Console.ConsoleView.instance();
const viewport = consoleView._viewport;
const viewportRect = viewport.element.getBoundingClientRect();
- const viewportPadding = parseFloat(window.getComputedStyle(viewport.element).paddingTop);
let first = -1;
let last = -1;
let count = 0;
@@ -628,8 +626,7 @@ ConsoleTestRunner.visibleIndices = function() {
if (!item._element || !item._element.isConnected)
continue;
const itemRect = item._element.getBoundingClientRect();
- const isVisible = (itemRect.bottom > viewportRect.top + viewportPadding + 1) &&
- (itemRect.top <= viewportRect.bottom - viewportPadding - 1);
+ const isVisible = (itemRect.bottom > viewportRect.top + 1) && (itemRect.top <= viewportRect.bottom - 1);
if (isVisible) {
first = first === -1 ? i : first;
last = i;
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/coverage/CoverageDecorationManager.js b/chromium/third_party/blink/renderer/devtools/front_end/coverage/CoverageDecorationManager.js
index aec0f908e95..8aa45139ba7 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/coverage/CoverageDecorationManager.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/coverage/CoverageDecorationManager.js
@@ -138,8 +138,9 @@ Coverage.CoverageDecorationManager = class {
const result = [];
const contentType = uiSourceCode.contentType();
if (contentType.hasScripts()) {
- let location = Bindings.debuggerWorkspaceBinding.uiLocationToRawLocation(uiSourceCode, line, column);
- if (location && location.script()) {
+ let locations = Bindings.debuggerWorkspaceBinding.uiLocationToRawLocations(uiSourceCode, line, column);
+ locations = locations.filter(location => !!location.script());
+ for (let location of locations) {
const script = location.script();
if (script.isInlineScript() && contentType.isDocument()) {
if (comparePositions(script.lineOffset, script.columnOffset, location.lineNumber, location.columnNumber) >
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/devtools_app.json b/chromium/third_party/blink/renderer/devtools/front_end/devtools_app.json
index e4441585647..02e578e0178 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/devtools_app.json
+++ b/chromium/third_party/blink/renderer/devtools/front_end/devtools_app.json
@@ -3,7 +3,6 @@
{ "name": "emulation", "type": "autostart" },
{ "name": "inspector_main", "type": "autostart" },
{ "name": "mobile_throttling", "type": "autostart" },
- { "name": "browser_components", "type": "autostart" },
{ "name": "accessibility", "type": "remote" },
{ "name": "animation" },
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/devtools_compatibility.js b/chromium/third_party/blink/renderer/devtools/front_end/devtools_compatibility.js
index e4ddb5052d8..4489c397916 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/devtools_compatibility.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/devtools_compatibility.js
@@ -517,6 +517,13 @@
/**
* @override
+ * @param {string} url
+ */
+ close(url) {
+ }
+
+ /**
+ * @override
* @param {string} message
*/
sendMessageToBackend(message) {
@@ -812,59 +819,6 @@
}
/**
- * Support for legacy front-ends (<M28).
- * @return {boolean}
- */
- canInspectWorkers() {
- return true;
- }
-
- /**
- * Support for legacy front-ends (<M28).
- * @return {boolean}
- */
- canSaveAs() {
- return true;
- }
-
- /**
- * Support for legacy front-ends (<M28).
- * @return {boolean}
- */
- canSave() {
- return true;
- }
-
- /**
- * Support for legacy front-ends (<M28).
- */
- loaded() {
- }
-
- /**
- * Support for legacy front-ends (<M28).
- * @return {string}
- */
- hiddenPanels() {
- return '';
- }
-
- /**
- * Support for legacy front-ends (<M28).
- * @return {string}
- */
- localizedStringsURL() {
- return '';
- }
-
- /**
- * Support for legacy front-ends (<M28).
- * @param {string} url
- */
- close(url) {
- }
-
- /**
* Support for legacy front-ends (<M44).
* @param {number} actionCode
*/
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/elements/ElementsPanel.js b/chromium/third_party/blink/renderer/devtools/front_end/elements/ElementsPanel.js
index 8979f943dba..7ae9081d399 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/elements/ElementsPanel.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/elements/ElementsPanel.js
@@ -483,7 +483,7 @@ Elements.ElementsPanel = class extends UI.Panel {
const node = this.selectedDOMNode();
if (!node)
return false;
- const preview = await BrowserComponents.ImagePreview.build(
+ const preview = await Components.ImagePreview.build(
node.domModel().target(), link[Elements.ElementsTreeElement.HrefSymbol], true);
if (preview)
popover.contentElement.appendChild(preview);
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/elements/ElementsTreeOutline.js b/chromium/third_party/blink/renderer/devtools/front_end/elements/ElementsTreeOutline.js
index e5c1c4f8401..8cc0dcd20f7 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/elements/ElementsTreeOutline.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/elements/ElementsTreeOutline.js
@@ -529,7 +529,7 @@ Elements.ElementsTreeOutline = class extends UI.TreeOutline {
const listItem = link.enclosingNodeOrSelfWithNodeName('li');
const node = /** @type {!Elements.ElementsTreeElement} */ (listItem.treeElement).node();
const precomputedFeatures = await this._loadDimensionsForNode(node);
- const preview = await BrowserComponents.ImagePreview.build(
+ const preview = await Components.ImagePreview.build(
node.domModel().target(), link[Elements.ElementsTreeElement.HrefSymbol], true, precomputedFeatures);
if (preview)
popover.contentElement.appendChild(preview);
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/elements/StylesSidebarPane.js b/chromium/third_party/blink/renderer/devtools/front_end/elements/StylesSidebarPane.js
index b199ff8cf8d..55888d9ec65 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/elements/StylesSidebarPane.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/elements/StylesSidebarPane.js
@@ -1007,38 +1007,23 @@ Elements.StylePropertiesSection = class {
const menuButton = new UI.ToolbarButton('', 'largeicon-menu');
menuButton.element.tabIndex = -1;
sectionToolbar.appendToolbarItem(menuButton);
- setItemsVisibility.call(this, items, false);
- sectionToolbar.element.addEventListener('mouseenter', setItemsVisibility.bind(this, items, true));
- sectionToolbar.element.addEventListener('mouseleave', setItemsVisibility.bind(this, items, false));
+ setItemsVisibility(items, false);
+ sectionToolbar.element.addEventListener('mouseenter', setItemsVisibility.bind(null, items, true));
+ sectionToolbar.element.addEventListener('mouseleave', setItemsVisibility.bind(null, items, false));
UI.ARIAUtils.markAsHidden(sectionToolbar.element);
/**
* @param {!Array<!UI.ToolbarButton>} items
* @param {boolean} value
- * @this {Elements.StylePropertiesSection}
*/
function setItemsVisibility(items, value) {
for (let i = 0; i < items.length; ++i)
items[i].setVisible(value);
menuButton.setVisible(!value);
- if (this._isSASSStyle())
- newRuleButton.setVisible(false);
}
}
/**
- * @return {boolean}
- */
- _isSASSStyle() {
- const header =
- this._style.styleSheetId ? this._style.cssModel().styleSheetHeaderForId(this._style.styleSheetId) : null;
- if (!header)
- return false;
- const sourceMap = header.cssModel().sourceMapManager().sourceMapForClient(header);
- return sourceMap ? sourceMap.editable() : false;
- }
-
- /**
* @return {!SDK.CSSStyleDeclaration}
*/
style() {
@@ -1561,7 +1546,7 @@ Elements.StylePropertiesSection = class {
return;
}
- if (!this.editable || this._isSASSStyle())
+ if (!this.editable)
return;
const config = new UI.InplaceEditor.Config(
@@ -1675,7 +1660,7 @@ Elements.StylePropertiesSection = class {
}
_startEditingAtFirstPosition() {
- if (!this.editable || this._isSASSStyle())
+ if (!this.editable)
return;
if (!this._style.parentRule) {
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/elements/module.json b/chromium/third_party/blink/renderer/devtools/front_end/elements/module.json
index b655b00e9a2..6cffd5fed7f 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/elements/module.json
+++ b/chromium/third_party/blink/renderer/devtools/front_end/elements/module.json
@@ -289,7 +289,7 @@
}
],
"dependencies": [
- "browser_components",
+ "components",
"extensions",
"inline_editor",
"color_picker",
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/event_listeners/EventListenersView.js b/chromium/third_party/blink/renderer/devtools/front_end/event_listeners/EventListenersView.js
index f3fe2b55785..b1875f3dca1 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/event_listeners/EventListenersView.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/event_listeners/EventListenersView.js
@@ -22,6 +22,8 @@ EventListeners.EventListenersView = class extends UI.VBox {
this._treeOutline.registerRequiredCSS('event_listeners/eventListenersView.css');
this._treeOutline.setComparator(EventListeners.EventListenersTreeElement.comparator);
this._treeOutline.element.classList.add('monospace');
+ this._treeOutline.setShowSelectionOnKeyboardFocus(true);
+ this._treeOutline.setFocusable(true);
this.element.appendChild(this._treeOutline.element);
this._emptyHolder = createElementWithClass('div', 'gray-info-message');
this._emptyHolder.textContent = Common.UIString('No event listeners');
@@ -182,12 +184,17 @@ EventListeners.EventListenersView = class extends UI.VBox {
addEmptyHolderIfNeeded() {
let allHidden = true;
+ let firstVisibleChild = null;
for (const eventType of this._treeOutline.rootElement().children()) {
eventType.hidden = !eventType.firstChild();
allHidden = allHidden && eventType.hidden;
+ if (!firstVisibleChild && !eventType.hidden)
+ firstVisibleChild = eventType;
}
if (allHidden && !this._emptyHolder.parentNode)
this.element.appendChild(this._emptyHolder);
+ if (firstVisibleChild)
+ firstVisibleChild.select(true /* omitFocus */);
}
reset() {
@@ -213,7 +220,6 @@ EventListeners.EventListenersTreeElement = class extends UI.TreeElement {
constructor(type, linkifier, changeCallback) {
super(type);
this.toggleOnClick = true;
- this.selectable = false;
this._linkifier = linkifier;
this._changeCallback = changeCallback;
}
@@ -255,7 +261,6 @@ EventListeners.ObjectEventListenerBar = class extends UI.TreeElement {
super('', true);
this._eventListener = eventListener;
this.editable = false;
- this.selectable = false;
this._setTitle(object, linkifier);
this._changeCallback = changeCallback;
}
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/extensions/ExtensionAPI.js b/chromium/third_party/blink/renderer/devtools/front_end/extensions/ExtensionAPI.js
index d4a2f35999b..4a413d1b533 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/extensions/ExtensionAPI.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/extensions/ExtensionAPI.js
@@ -89,11 +89,13 @@ function defineCommonExtensionSymbols(apiPrivate) {
* @param {!ExtensionDescriptor} extensionInfo
* @param {string} inspectedTabId
* @param {string} themeName
+ * @param {!Array<number>} keysToForward
* @param {number} injectedScriptId
* @param {function(!Object, !Object)} testHook
* @suppressGlobalPropertiesCheck
*/
-function injectedExtensionAPI(extensionInfo, inspectedTabId, themeName, testHook, injectedScriptId) {
+function injectedExtensionAPI(extensionInfo, inspectedTabId, themeName, keysToForward, testHook, injectedScriptId) {
+ const keysToForwardSet = new Set(keysToForward);
const chrome = window.chrome || {};
const devtools_descriptor = Object.getOwnPropertyDescriptor(chrome, 'devtools');
if (devtools_descriptor)
@@ -637,14 +639,26 @@ function injectedExtensionAPI(extensionInfo, inspectedTabId, themeName, testHook
let forwardTimer = null;
function forwardKeyboardEvent(event) {
+ let modifiers = 0;
+ if (event.shiftKey)
+ modifiers |= 1;
+ if (event.ctrlKey)
+ modifiers |= 2;
+ if (event.altKey)
+ modifiers |= 4;
+ if (event.metaKey)
+ modifiers |= 8;
+ const num = (event.keyCode & 255) | (modifiers << 8);
// We only care about global hotkeys, not about random text
- if (!event.ctrlKey && !event.altKey && !event.metaKey && !/^F\d+$/.test(event.key) && event.key !== 'Escape')
+ if (!keysToForwardSet.has(num))
return;
+ event.preventDefault();
const requestPayload = {
eventType: event.type,
ctrlKey: event.ctrlKey,
altKey: event.altKey,
metaKey: event.metaKey,
+ shiftKey: event.shiftKey,
keyIdentifier: event.keyIdentifier,
key: event.key,
code: event.code,
@@ -664,7 +678,6 @@ function injectedExtensionAPI(extensionInfo, inspectedTabId, themeName, testHook
}
document.addEventListener('keydown', forwardKeyboardEvent, false);
- document.addEventListener('keypress', forwardKeyboardEvent, false);
/**
* @constructor
@@ -795,11 +808,12 @@ function injectedExtensionAPI(extensionInfo, inspectedTabId, themeName, testHook
* @param {!ExtensionDescriptor} extensionInfo
* @param {string} inspectedTabId
* @param {string} themeName
+ * @param {!Array<number>} keysToForward
* @param {function(!Object, !Object)|undefined} testHook
* @return {string}
*/
-function buildExtensionAPIInjectedScript(extensionInfo, inspectedTabId, themeName, testHook) {
- const argumentsJSON = [extensionInfo, inspectedTabId || null, themeName].map(_ => JSON.stringify(_)).join(',');
+function buildExtensionAPIInjectedScript(extensionInfo, inspectedTabId, themeName, keysToForward, testHook) {
+ const argumentsJSON = [extensionInfo, inspectedTabId || null, themeName, keysToForward].map(_ => JSON.stringify(_)).join(',');
if (!testHook)
testHook = () => {};
return '(function(injectedScriptId){ ' + defineCommonExtensionSymbols.toString() + ';' +
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/extensions/ExtensionServer.js b/chromium/third_party/blink/renderer/devtools/front_end/extensions/ExtensionServer.js
index cb93140bfe1..f633923b7d0 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/extensions/ExtensionServer.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/extensions/ExtensionServer.js
@@ -378,7 +378,7 @@ Extensions.ExtensionServer = class extends Common.Object {
return this._status.OK();
}
- const request = BrowserSDK.networkLog.requestForURL(message.url);
+ const request = SDK.networkLog.requestForURL(message.url);
if (request) {
Common.Revealer.reveal(request);
return this._status.OK();
@@ -434,8 +434,8 @@ Extensions.ExtensionServer = class extends Common.Object {
}
async _onGetHAR() {
- const requests = BrowserSDK.networkLog.requests();
- const harLog = await BrowserSDK.HARLog.build(requests);
+ const requests = SDK.networkLog.requests();
+ const harLog = await SDK.HARLog.build(requests);
for (let i = 0; i < harLog.entries.length; ++i)
harLog.entries[i]._requestId = this._requestId(requests[i]);
return harLog;
@@ -560,8 +560,6 @@ Extensions.ExtensionServer = class extends Common.Object {
* @suppressGlobalPropertiesCheck
*/
function handleEventEntry(entry) {
- if (!entry.ctrlKey && !entry.altKey && !entry.metaKey && !/^F\d+$/.test(entry.key) && entry.key !== 'Escape')
- return;
// Fool around closure compiler -- it has its own notion of both KeyboardEvent constructor
// and initKeyboardEvent methods and overriding these in externs.js does not have effect.
const event = new window.KeyboardEvent(entry.eventType, {
@@ -640,7 +638,7 @@ Extensions.ExtensionServer = class extends Common.Object {
async _notifyRequestFinished(event) {
const request = /** @type {!SDK.NetworkRequest} */ (event.data);
- const entry = await BrowserSDK.HAREntry.build(request);
+ const entry = await SDK.HARLog.Entry.build(request);
this._postNotification(Extensions.extensionAPI.Events.NetworkRequestFinished, this._requestId(request), entry);
}
@@ -703,6 +701,7 @@ Extensions.ExtensionServer = class extends Common.Object {
// See ExtensionAPI.js for details.
const injectedAPI = buildExtensionAPIInjectedScript(
extensionInfo, this._inspectedTabId, UI.themeSupport.themeName(),
+ UI.shortcutRegistry.globalShortcutKeys(),
Extensions.extensionServer['_extensionAPITestHook']);
InspectorFrontendHost.setInjectedScriptForOrigin(extensionOrigin, injectedAPI);
this._registeredExtensions[extensionOrigin] = {name: name};
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/formatter_worker/FormatterWorker.js b/chromium/third_party/blink/renderer/devtools/front_end/formatter_worker/FormatterWorker.js
index cb05d741488..064e04cf5db 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/formatter_worker/FormatterWorker.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/formatter_worker/FormatterWorker.js
@@ -152,8 +152,15 @@ FormatterWorker.evaluatableJavaScriptSubstring = function(content) {
*/
FormatterWorker.preprocessTopLevelAwaitExpressions = function(content) {
let wrapped = '(async () => {' + content + '})()';
- const root = acorn.parse(wrapped, {ecmaVersion: 9});
- const body = root.body[0].expression.callee.body;
+ let root;
+ let body;
+ try {
+ root = acorn.parse(wrapped, {ecmaVersion: 9});
+ body = root.body[0].expression.callee.body;
+ } catch (e) {
+ postMessage('');
+ return;
+ }
const changes = [];
let containsAwait = false;
let containsReturn = false;
@@ -236,7 +243,11 @@ FormatterWorker.preprocessTopLevelAwaitExpressions = function(content) {
* @param {string} content
*/
FormatterWorker.javaScriptIdentifiers = function(content) {
- const root = acorn.parse(content, {ranges: false, ecmaVersion: 9});
+ let root = null;
+ try {
+ root = acorn.parse(content, {ranges: false, ecmaVersion: 9});
+ } catch (e) {
+ }
/** @type {!Array<!ESTree.Node>} */
const identifiers = [];
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/har_importer/HARImporter.js b/chromium/third_party/blink/renderer/devtools/front_end/har_importer/HARImporter.js
index 260f476eb67..ce1e59a8b71 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/har_importer/HARImporter.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/har_importer/HARImporter.js
@@ -15,7 +15,7 @@ HARImporter.Importer = class {
log.entries.sort((a, b) => a.startedDateTime - b.startedDateTime);
- /** @type {!Map<string, !BrowserSDK.PageLoad>} */
+ /** @type {!Map<string, !SDK.NetworkLog.PageLoad>} */
const pageLoads = new Map();
/** @type {!Array<!SDK.NetworkRequest>} */
const requests = [];
@@ -39,10 +39,10 @@ HARImporter.Importer = class {
/**
* @param {!HARImporter.HARPage} page
* @param {!SDK.NetworkRequest} mainRequest
- * @return {!BrowserSDK.PageLoad}
+ * @return {!SDK.NetworkLog.PageLoad}
*/
static _buildPageLoad(page, mainRequest) {
- const pageLoad = new BrowserSDK.PageLoad(mainRequest);
+ const pageLoad = new SDK.NetworkLog.PageLoad(mainRequest);
pageLoad.startTime = page.startedDateTime;
pageLoad.contentLoadTime = page.pageTimings.onContentLoad * 1000;
pageLoad.loadTime = page.pageTimings.onLoad * 1000;
@@ -52,7 +52,7 @@ HARImporter.Importer = class {
/**
* @param {!SDK.NetworkRequest} request
* @param {!HARImporter.HAREntry} entry
- * @param {?BrowserSDK.PageLoad} pageLoad
+ * @param {?SDK.NetworkLog.PageLoad} pageLoad
*/
static _fillRequestFromHAREntry(request, entry, pageLoad) {
// Request data.
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/heap_profiler_test_runner/HeapProfilerTestRunner.js b/chromium/third_party/blink/renderer/devtools/front_end/heap_profiler_test_runner/HeapProfilerTestRunner.js
index 9d2ce468d1d..ba2379884cf 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/heap_profiler_test_runner/HeapProfilerTestRunner.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/heap_profiler_test_runner/HeapProfilerTestRunner.js
@@ -42,7 +42,8 @@ HeapProfilerTestRunner.createHeapSnapshotMockFactories = function() {
node_fields: ['type', 'name', 'id', 'self_size', 'retained_size', 'dominator', 'edge_count'],
node_types: [['hidden', 'object'], '', '', '', '', '', ''],
edge_fields: ['type', 'name_or_index', 'to_node'],
- edge_types: [['element', 'property', 'shortcut'], '', '']
+ edge_types: [['element', 'property', 'shortcut'], '', ''],
+ location_fields: ['object_index', 'script_id', 'line', 'column']
},
node_count: 6,
@@ -55,6 +56,9 @@ HeapProfilerTestRunner.createHeapSnapshotMockFactories = function() {
],
edges: [1, 6, 7, 1, 7, 14, 0, 1, 14, 1, 8, 21, 1, 9, 21, 1, 10, 28, 1, 11, 35],
+
+ locations: [0, 1, 2, 3, 18, 2, 3, 4],
+
strings: ['', 'A', 'B', 'C', 'D', 'E', 'a', 'b', 'ac', 'bc', 'bd', 'ce']
};
};
@@ -76,7 +80,8 @@ HeapProfilerTestRunner.createHeapSnapshotMockFactories = function() {
node_fields: ['type', 'name', 'id', 'edge_count'],
node_types: [['hidden', 'object', 'synthetic'], '', '', ''],
edge_fields: ['type', 'name_or_index', 'to_node'],
- edge_types: [['element', 'hidden', 'internal'], '', '']
+ edge_types: [['element', 'hidden', 'internal'], '', ''],
+ location_fields: ['object_index', 'script_id', 'line', 'column']
},
node_count: 13,
@@ -93,6 +98,8 @@ HeapProfilerTestRunner.createHeapSnapshotMockFactories = function() {
24, 0, 2, 28, 1, 3, 32, 0, 1, 36, 0, 1, 40, 2, 12, 44, 2, 1, 48
],
+ locations: [0, 2, 1, 1, 6, 2, 2, 2],
+
strings: ['', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'M', 'N', 'Window', 'native']
});
};
@@ -233,6 +240,7 @@ HeapProfilerTestRunner.createHeapSnapshotMockFactories = function() {
'nodes': [],
'edges': [],
+ 'locations': [],
'strings': []
};
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/heap_snapshot_model/HeapSnapshotModel.js b/chromium/third_party/blink/renderer/devtools/front_end/heap_snapshot_model/HeapSnapshotModel.js
index 02d0cf93560..aeb766a1ad3 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/heap_snapshot_model/HeapSnapshotModel.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/heap_snapshot_model/HeapSnapshotModel.js
@@ -411,3 +411,19 @@ HeapSnapshotModel.Samples = class {
this.sizes = sizes;
}
};
+
+/**
+ * @unrestricted
+ */
+HeapSnapshotModel.Location = class {
+ /**
+ * @param {number} scriptId
+ * @param {number} lineNumber
+ * @param {number} columnNumber
+ */
+ constructor(scriptId, lineNumber, columnNumber) {
+ this.scriptId = scriptId;
+ this.lineNumber = lineNumber;
+ this.columnNumber = columnNumber;
+ }
+}; \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/heap_snapshot_worker/HeapSnapshot.js b/chromium/third_party/blink/renderer/devtools/front_end/heap_snapshot_worker/HeapSnapshot.js
index e710051a3cd..8c67f784b0e 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/heap_snapshot_worker/HeapSnapshot.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/heap_snapshot_worker/HeapSnapshot.js
@@ -838,6 +838,8 @@ HeapSnapshotWorker.HeapSnapshot = class {
this._samples = null;
/** @type {!Array.<string>} */
this.strings = profile.strings;
+ /** @type {!Array.<number>} */
+ this._locations = profile.locations;
this._progress = progress;
this._noDistance = -5;
@@ -890,6 +892,14 @@ HeapSnapshotWorker.HeapSnapshot = class {
this._edgeWeakType = this._edgeTypes.indexOf('weak');
this._edgeInvisibleType = this._edgeTypes.indexOf('invisible');
+ const location_fields = meta.location_fields || [];
+
+ this._locationIndexOffset = location_fields.indexOf('object_index');
+ this._locationScriptIdOffset = location_fields.indexOf('script_id');
+ this._locationLineOffset = location_fields.indexOf('line');
+ this._locationColumnOffset = location_fields.indexOf('column');
+ this._locationFieldCount = location_fields.length;
+
this.nodeCount = this.nodes.length / this._nodeFieldCount;
this._edgeCount = this.containmentEdges.length / this._edgeFieldsCount;
@@ -924,6 +934,8 @@ HeapSnapshotWorker.HeapSnapshot = class {
this.calculateStatistics();
this._progress.updateStatus('Calculating samples\u2026');
this._buildSamples();
+ this._progress.updateStatus('Building locations\u2026');
+ this._buildLocationMap();
this._progress.updateStatus('Finished processing.');
if (this._profile.snapshot.trace_function_count) {
@@ -1870,6 +1882,30 @@ HeapSnapshotWorker.HeapSnapshot = class {
this._samples = new HeapSnapshotModel.Samples(timestamps, lastAssignedIds, sizeForRange);
}
+ _buildLocationMap() {
+ /** @type {!Map<number, !HeapSnapshotModel.Location>} */
+ const map = new Map();
+ const locations = this._locations;
+
+ for (let i = 0; i < locations.length; i += this._locationFieldCount) {
+ const nodeIndex = locations[i + this._locationIndexOffset];
+ const scriptId = locations[i + this._locationScriptIdOffset];
+ const line = locations[i + this._locationLineOffset];
+ const col = locations[i + this._locationColumnOffset];
+ map.set(nodeIndex, new HeapSnapshotModel.Location(scriptId, line, col));
+ }
+
+ this._locationMap = map;
+ }
+
+ /**
+ * @param {number} nodeIndex
+ * @return {?HeapSnapshotModel.Location}
+ */
+ getLocation(nodeIndex) {
+ return this._locationMap.get(nodeIndex) || null;
+ }
+
/**
* @return {?HeapSnapshotModel.Samples}
*/
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/heap_snapshot_worker/HeapSnapshotLoader.js b/chromium/third_party/blink/renderer/devtools/front_end/heap_snapshot_worker/HeapSnapshotLoader.js
index 6c0abf3aa04..6f49288eba4 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/heap_snapshot_worker/HeapSnapshotLoader.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/heap_snapshot_worker/HeapSnapshotLoader.js
@@ -107,7 +107,7 @@ HeapSnapshotWorker.HeapSnapshotLoader = class {
_parseStringsArray() {
this._progress.updateStatus('Parsing strings\u2026');
const closingBracketIndex = this._json.lastIndexOf(']');
- if (closingBracketIndex === -1)
+ if (closingBracketIndex === -1 || this._state !== 'accumulate-strings')
throw new Error('Incomplete JSON');
this._json = this._json.slice(0, closingBracketIndex + 1);
this._snapshot.strings = JSON.parse(this._json);
@@ -198,7 +198,7 @@ HeapSnapshotWorker.HeapSnapshotLoader = class {
this._state = 'find-samples';
this._progress.updateStatus('Loading samples\u2026');
} else {
- this._state = 'find-strings';
+ this._state = 'find-locations';
}
break;
}
@@ -277,6 +277,39 @@ HeapSnapshotWorker.HeapSnapshotLoader = class {
return;
this._snapshot.samples = this._array;
this._array = null;
+ this._state = 'find-locations';
+ this._progress.updateStatus('Loading locations\u2026');
+ break;
+ }
+ case 'find-locations': {
+ if (!this._snapshot.snapshot.meta.location_fields) {
+ // The property `locations` was added retroactively, so older
+ // snapshots might not contain it. In this case just expect `strings`
+ // as next property.
+ this._snapshot.locations = [];
+ this._array = null;
+ this._state = 'find-strings';
+ break;
+ }
+
+ const locationsToken = '"locations"';
+ const locationsTokenIndex = this._json.indexOf(locationsToken);
+ if (locationsTokenIndex === -1)
+ return;
+ const bracketIndex = this._json.indexOf('[', locationsTokenIndex);
+ if (bracketIndex === -1)
+ return;
+ this._json = this._json.slice(bracketIndex + 1);
+ this._array = [];
+ this._arrayIndex = 0;
+ this._state = 'parse-locations';
+ break;
+ }
+ case 'parse-locations': {
+ if (this._parseUintArray())
+ return;
+ this._snapshot.locations = this._array;
+ this._array = null;
this._state = 'find-strings';
this._progress.updateStatus('Loading strings\u2026');
break;
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/help/ReleaseNoteText.js b/chromium/third_party/blink/renderer/devtools/front_end/help/ReleaseNoteText.js
index a149c0e8e78..fcb2c368557 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/help/ReleaseNoteText.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/help/ReleaseNoteText.js
@@ -13,6 +13,44 @@ const commandMenuShortcut = Host.isMac() ? 'Command + Shift + P' : 'Control + Sh
/** @type {!Array<!Help.ReleaseNote>} */
Help.releaseNoteText = [
{
+ version: 12,
+ header: 'Highlights from the Chrome 70 update',
+ highlights: [
+ {
+ title: 'Live Expressions in the Console',
+ subtitle: 'Pin expressions to the top of the Console to monitor their values in real-time.',
+ link: 'https://developers.google.com/web/updates/2018/08/devtools#watch',
+ },
+ {
+ title: 'Highlight DOM nodes during Eager Evaluation',
+ subtitle: 'Type an expression that evaluates to a node to highlight that node in the viewport.',
+ link: 'https://developers.google.com/web/updates/2018/08/devtools#nodes',
+ },
+ {
+ title: 'Autocomplete Conditional Breakpoints',
+ subtitle: 'Type expressions quickly and accurately.',
+ link: 'https://developers.google.com/web/updates/2018/08/devtools#autocomplete',
+ },
+ {
+ title: 'Performance panel optimizations',
+ subtitle: 'Faster loading and processing of Performance recordings.',
+ link: 'https://developers.google.com/web/updates/2018/08/devtools#performance',
+ },
+ {
+ title: 'More reliable debugging',
+ subtitle: 'Bug fixes for sourcemaps and blackboxing.',
+ link: 'https://developers.google.com/web/updates/2018/08/devtools#debugging',
+ },
+ {
+ title: 'Debug Node.js apps with ndb',
+ subtitle:
+ 'Detect and attach to child processes, place breakpoints before modules are required, edit files within DevTools, and more.',
+ link: 'https://developers.google.com/web/updates/2018/08/devtools#ndb',
+ },
+ ],
+ link: 'https://developers.google.com/web/updates/2018/08/devtools',
+ },
+ {
version: 11,
header: 'Highlights from the Chrome 68 update',
highlights: [
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/host/InspectorFrontendHost.js b/chromium/third_party/blink/renderer/devtools/front_end/host/InspectorFrontendHost.js
index b12d858aa15..2dd46365728 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/host/InspectorFrontendHost.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/host/InspectorFrontendHost.js
@@ -46,6 +46,10 @@ Host.InspectorFrontendHostStub = class {
event.stopPropagation();
}
document.addEventListener('keydown', stopEventPropagation, true);
+ /**
+ * @type {!Map<string, !Array<string>>}
+ */
+ this._urlsBeingSaved = new Map();
}
/**
@@ -197,8 +201,13 @@ Host.InspectorFrontendHostStub = class {
* @param {boolean} forceSaveAs
*/
save(url, content, forceSaveAs) {
- Common.console.error('Saving files is not enabled in hosted mode. Please inspect using chrome://inspect');
- this.events.dispatchEventToListeners(InspectorFrontendHostAPI.Events.CanceledSaveURL, url);
+ let buffer = this._urlsBeingSaved.get(url);
+ if (!buffer) {
+ buffer = [];
+ this._urlsBeingSaved.set(url, buffer);
+ }
+ buffer.push(content);
+ this.events.dispatchEventToListeners(InspectorFrontendHostAPI.Events.SavedURL, {url, fileSystemPath: url});
}
/**
@@ -207,7 +216,24 @@ Host.InspectorFrontendHostStub = class {
* @param {string} content
*/
append(url, content) {
- Common.console.error('Saving files is not enabled in hosted mode. Please inspect using chrome://inspect');
+ const buffer = this._urlsBeingSaved.get(url);
+ buffer.push(content);
+ this.events.dispatchEventToListeners(InspectorFrontendHostAPI.Events.AppendedToURL, url);
+ }
+
+ /**
+ * @override
+ * @param {string} url
+ */
+ close(url) {
+ const buffer = this._urlsBeingSaved.get(url);
+ this._urlsBeingSaved.delete(url);
+ const fileName = url ? url.trimURL().removeURLFragment() : '';
+ const link = createElement('a');
+ link.download = fileName;
+ const blob = new Blob([buffer.join('')], {type: 'text/plain'});
+ link.href = URL.createObjectURL(blob);
+ link.click();
}
/**
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/host/InspectorFrontendHostAPI.js b/chromium/third_party/blink/renderer/devtools/front_end/host/InspectorFrontendHostAPI.js
index 6c0bc59cd53..93b1dc56a89 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/host/InspectorFrontendHostAPI.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/host/InspectorFrontendHostAPI.js
@@ -100,12 +100,6 @@ InspectorFrontendHostAPI.prototype = {
*/
addFileSystem(type) {},
- /**
- * @param {string} url
- * @param {string} content
- */
- append(url, content) {},
-
loadCompleted() {},
/**
@@ -183,6 +177,17 @@ InspectorFrontendHostAPI.prototype = {
save(url, content, forceSaveAs) {},
/**
+ * @param {string} url
+ * @param {string} content
+ */
+ append(url, content) {},
+
+ /**
+ * @param {string} url
+ */
+ close(url) {},
+
+ /**
* @param {number} requestId
* @param {string} fileSystemPath
* @param {string} query
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/inline_editor/CSSShadowEditor.js b/chromium/third_party/blink/renderer/devtools/front_end/inline_editor/CSSShadowEditor.js
index ddaa9f85a41..5bf765f6c9c 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/inline_editor/CSSShadowEditor.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/inline_editor/CSSShadowEditor.js
@@ -86,8 +86,8 @@ InlineEditor.CSSShadowEditor = class extends UI.VBox {
*/
setModel(model) {
this._model = model;
- this._typeField.hidden = !model.isBoxShadow();
- this._spreadField.hidden = !model.isBoxShadow();
+ this._typeField.classList.toggle('hidden', !model.isBoxShadow());
+ this._spreadField.classList.toggle('hidden', !model.isBoxShadow());
this._updateUI();
}
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/inspector_main/module.json b/chromium/third_party/blink/renderer/devtools/front_end/inspector_main/module.json
index 24aa03bb647..99baa98c7f8 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/inspector_main/module.json
+++ b/chromium/third_party/blink/renderer/devtools/front_end/inspector_main/module.json
@@ -14,7 +14,7 @@
"bindings": [
{
"platform": "windows,linux",
- "shortcut": "F5 Ctrl+R"
+ "shortcut": "Ctrl+R F5"
},
{
"platform": "mac",
@@ -31,7 +31,7 @@
"bindings": [
{
"platform": "windows,linux",
- "shortcut": "Shift+F5 Ctrl+F5 Ctrl+Shift+F5 Shift+Ctrl+R"
+ "shortcut": "Shift+Ctrl+R Shift+F5 Ctrl+F5 Ctrl+Shift+F5"
},
{
"platform": "mac",
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/main/Main.js b/chromium/third_party/blink/renderer/devtools/front_end/main/Main.js
index c275c351749..cbb0a62e42e 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/main/Main.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/main/Main.js
@@ -131,6 +131,7 @@ Main.Main = class {
Runtime.experiments.register('timelineShowAllEvents', 'Timeline: show all events', true);
Runtime.experiments.register('timelineTracingJSProfile', 'Timeline: tracing based JS profiler', true);
Runtime.experiments.register('timelineV8RuntimeCallStats', 'Timeline: V8 Runtime Call Stats on Timeline', true);
+ Runtime.experiments.register('timelineWebGL', 'Timeline: WebGL-based flamechart');
Runtime.experiments.cleanUpStaleExperiments();
@@ -143,10 +144,14 @@ Main.Main = class {
Runtime.experiments.enableForTest('networkSearch');
if (testPath.indexOf('console/viewport-testing/') !== -1)
Runtime.experiments.enableForTest('consoleBelowPrompt');
+ if (testPath.indexOf('console/') !== -1)
+ Runtime.experiments.enableForTest('pinnedExpressions');
}
- Runtime.experiments.setDefaultExperiments(
- ['colorContrastRatio', 'stepIntoAsync', 'oopifInlineDOM', 'consoleBelowPrompt', 'timelineTracingJSProfile']);
+ Runtime.experiments.setDefaultExperiments([
+ 'colorContrastRatio', 'stepIntoAsync', 'oopifInlineDOM', 'consoleBelowPrompt', 'timelineTracingJSProfile',
+ 'pinnedExpressions'
+ ]);
}
/**
@@ -516,7 +521,8 @@ Main.Main.MainMenuItem = class {
'Placement of DevTools relative to the page. (%s to restore last position)', toggleDockSideShorcuts[0].name);
dockItemElement.appendChild(titleElement);
const dockItemToolbar = new UI.Toolbar('', dockItemElement);
- dockItemToolbar.makeBlueOnHover();
+ if (Host.isMac() && !UI.themeSupport.hasTheme())
+ dockItemToolbar.makeBlueOnHover();
const undock = new UI.ToolbarToggle(Common.UIString('Undock into separate window'), 'largeicon-undock');
const bottom = new UI.ToolbarToggle(Common.UIString('Dock to bottom'), 'largeicon-dock-to-bottom');
const right = new UI.ToolbarToggle(Common.UIString('Dock to right'), 'largeicon-dock-to-right');
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/main/module.json b/chromium/third_party/blink/renderer/devtools/front_end/main/module.json
index 3c439d87fdd..fc5bb81909a 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/main/module.json
+++ b/chromium/third_party/blink/renderer/devtools/front_end/main/module.json
@@ -40,7 +40,7 @@
"type": "action",
"category": "Drawer",
"actionId": "main.toggle-drawer",
- "className": "UI.InspectorView.DrawerToggleActionDelegate",
+ "className": "UI.InspectorView.ActionDelegate",
"order": 101,
"title": "Toggle drawer",
"bindings": [
@@ -51,6 +51,36 @@
},
{
"type": "action",
+ "actionId": "main.next-tab",
+ "className": "UI.InspectorView.ActionDelegate",
+ "bindings": [
+ {
+ "platform": "windows,linux",
+ "shortcut": "Ctrl+]"
+ },
+ {
+ "platform": "mac",
+ "shortcut": "Meta+]"
+ }
+ ]
+ },
+ {
+ "type": "action",
+ "actionId": "main.previous-tab",
+ "className": "UI.InspectorView.ActionDelegate",
+ "bindings": [
+ {
+ "platform": "windows,linux",
+ "shortcut": "Ctrl+["
+ },
+ {
+ "platform": "mac",
+ "shortcut": "Meta+["
+ }
+ ]
+ },
+ {
+ "type": "action",
"actionId": "main.debug-reload",
"className": "Main.ReloadActionDelegate",
"bindings": [
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/network/HARWriter.js b/chromium/third_party/blink/renderer/devtools/front_end/network/HARWriter.js
index 52aa0b0b80c..b7f20e88d8a 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/network/HARWriter.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/network/HARWriter.js
@@ -54,7 +54,7 @@ Network.HARWriter = class {
progress.setTitle(Common.UIString('Collecting content\u2026'));
progress.setTotalWork(requests.length);
- const harLog = await BrowserSDK.HARLog.build(requests);
+ const harLog = await SDK.HARLog.build(requests);
const promises = [];
for (let i = 0; i < requests.length; i++) {
const promise = requests[i].contentData();
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkDataGridNode.js b/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkDataGridNode.js
index cbc6fb46691..5f3e50400aa 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkDataGridNode.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkDataGridNode.js
@@ -546,7 +546,7 @@ Network.NetworkRequestNode = class extends Network.NetworkNode {
showingInitiatorChainChanged() {
const showInitiatorChain = this.showingInitiatorChain();
- const initiatorGraph = BrowserSDK.networkLog.initiatorGraphForRequest(this._request);
+ const initiatorGraph = SDK.networkLog.initiatorGraphForRequest(this._request);
for (const request of initiatorGraph.initiators) {
if (request === this._request)
continue;
@@ -636,7 +636,7 @@ Network.NetworkRequestNode = class extends Network.NetworkNode {
* @return {boolean}
*/
isNavigationRequest() {
- const pageLoad = BrowserSDK.PageLoad.forRequest(this._request);
+ const pageLoad = SDK.NetworkLog.PageLoad.forRequest(this._request);
return pageLoad ? pageLoad.mainRequest === this._request : false;
}
@@ -882,7 +882,7 @@ Network.NetworkRequestNode = class extends Network.NetworkNode {
_renderInitiatorCell(cell) {
this._initiatorCell = cell;
const request = this._request;
- const initiator = BrowserSDK.networkLog.initiatorInfoForRequest(request);
+ const initiator = SDK.networkLog.initiatorInfoForRequest(request);
const timing = request.timing;
if (timing && timing.pushStart)
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkLogView.js b/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkLogView.js
index 19bc05754ef..f338f7375ac 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkLogView.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkLogView.js
@@ -146,9 +146,9 @@ Network.NetworkLogView = class extends UI.VBox {
.addChangeListener(this._invalidateAllItems.bind(this, false), this);
SDK.targetManager.observeModels(SDK.NetworkManager, this);
- BrowserSDK.networkLog.addEventListener(BrowserSDK.NetworkLog.Events.RequestAdded, this._onRequestUpdated, this);
- BrowserSDK.networkLog.addEventListener(BrowserSDK.NetworkLog.Events.RequestUpdated, this._onRequestUpdated, this);
- BrowserSDK.networkLog.addEventListener(BrowserSDK.NetworkLog.Events.Reset, this._reset, this);
+ SDK.networkLog.addEventListener(SDK.NetworkLog.Events.RequestAdded, this._onRequestUpdated, this);
+ SDK.networkLog.addEventListener(SDK.NetworkLog.Events.RequestUpdated, this._onRequestUpdated, this);
+ SDK.networkLog.addEventListener(SDK.NetworkLog.Events.Reset, this._reset, this);
this._updateGroupByFrame();
Common.moduleSetting('network.group-by-frame').addChangeListener(() => this._updateGroupByFrame());
@@ -466,7 +466,7 @@ Network.NetworkLogView = class extends UI.VBox {
this._harLoadFailed(e);
return;
}
- BrowserSDK.networkLog.importRequests(HARImporter.Importer.requestsFromHARLog(harRoot.log));
+ SDK.networkLog.importRequests(HARImporter.Importer.requestsFromHARLog(harRoot.log));
}
/**
@@ -691,7 +691,7 @@ Network.NetworkLogView = class extends UI.VBox {
let maxTime = -1;
let nodeCount = 0;
- for (const request of BrowserSDK.networkLog.requests()) {
+ for (const request of SDK.networkLog.requests()) {
const node = request[Network.NetworkLogView._networkNodeSymbol];
if (!node)
continue;
@@ -797,7 +797,7 @@ Network.NetworkLogView = class extends UI.VBox {
* @param {boolean=} deferUpdate
*/
_invalidateAllItems(deferUpdate) {
- this._staleRequests = new Set(BrowserSDK.networkLog.requests());
+ this._staleRequests = new Set(SDK.networkLog.requests());
if (deferUpdate)
this.scheduleRefresh();
else
@@ -1228,12 +1228,12 @@ Network.NetworkLogView = class extends UI.VBox {
}
_harRequests() {
- const httpRequests = BrowserSDK.networkLog.requests().filter(Network.NetworkLogView.HTTPRequestsFilter);
+ const httpRequests = SDK.networkLog.requests().filter(Network.NetworkLogView.HTTPRequestsFilter);
return httpRequests.filter(Network.NetworkLogView.FinishedRequestsFilter);
}
async _copyAll() {
- const harArchive = {log: await BrowserSDK.HARLog.build(this._harRequests())};
+ const harArchive = {log: await SDK.HARLog.build(this._harRequests())};
InspectorFrontendHost.copyText(JSON.stringify(harArchive, null, 2));
}
@@ -1250,7 +1250,7 @@ Network.NetworkLogView = class extends UI.VBox {
* @param {string} platform
*/
async _copyAllCurlCommand(platform) {
- const requests = BrowserSDK.networkLog.requests();
+ const requests = SDK.networkLog.requests();
const commands = await Promise.all(requests.map(request => this._generateCurlCommand(request, platform)));
if (platform === 'win')
InspectorFrontendHost.copyText(commands.join(' &\r\n'));
@@ -1268,7 +1268,7 @@ Network.NetworkLogView = class extends UI.VBox {
}
async _copyAllFetchCall() {
- const requests = BrowserSDK.networkLog.requests();
+ const requests = SDK.networkLog.requests();
const commands = await Promise.all(requests.map(request => this._generateFetchCall(request)));
InspectorFrontendHost.copyText(commands.join(' ;\n'));
}
@@ -1282,7 +1282,7 @@ Network.NetworkLogView = class extends UI.VBox {
}
async _copyAllPowerShellCommand() {
- const requests = BrowserSDK.networkLog.requests();
+ const requests = SDK.networkLog.requests();
const commands = await Promise.all(requests.map(request => this._generatePowerShellCommand(request)));
InspectorFrontendHost.copyText(commands.join(';\r\n'));
}
@@ -1544,8 +1544,7 @@ Network.NetworkLogView = class extends UI.VBox {
const headers = {};
for (const headerArray of headerData)
- headers[headerArray[0]] = headers[headerArray[1]];
-
+ headers[headerArray[0]] = headerArray[1];
const credentials =
request.requestCookies || requestHeaders.some(({name}) => credentialHeaders[name.toLowerCase()]) ? 'include' :
@@ -1561,7 +1560,7 @@ Network.NetworkLogView = class extends UI.VBox {
const fetchOptions = {
credentials,
- headers,
+ headers: Object.keys(headers).length ? headers : void 0,
referrer,
referrerPolicy,
body: requestBody,
@@ -1631,23 +1630,19 @@ Network.NetworkLogView = class extends UI.VBox {
* @return {string}
*/
function escapeCharacter(x) {
- let code = x.charCodeAt(0);
- if (code < 256) {
- // Add leading zero when needed to not care about the next character.
- return code < 16 ? '\\x0' + code.toString(16) : '\\x' + code.toString(16);
- }
- code = code.toString(16);
- return '\\u' + ('0000' + code).substr(code.length, 4);
+ const code = x.charCodeAt(0);
+ // Add leading zero when needed to not care about the next character.
+ return code < 16 ? '\\u0' + code.toString(16) : '\\u' + code.toString(16);
}
- if (/[^\x20-\x7E]|\'/.test(str)) {
+ if (/[\u0000-\u001f\u007f-\u009f]|\'/.test(str)) {
// Use ANSI-C quoting syntax.
return '$\'' +
str.replace(/\\/g, '\\\\')
.replace(/\'/g, '\\\'')
.replace(/\n/g, '\\n')
.replace(/\r/g, '\\r')
- .replace(/[^\x20-\x7E]/g, escapeCharacter) +
+ .replace(/[\u0000-\u001f\u007f-\u009f]/g, escapeCharacter) +
'\'';
} else {
// Use single quote syntax.
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkPanel.js b/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkPanel.js
index 1d2fc78d0f1..06013d284b8 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkPanel.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkPanel.js
@@ -137,9 +137,9 @@ Network.NetworkPanel = class extends UI.Panel {
SDK.ResourceTreeModel, SDK.ResourceTreeModel.Events.WillReloadPage, this._willReloadPage, this);
SDK.targetManager.addModelListener(SDK.ResourceTreeModel, SDK.ResourceTreeModel.Events.Load, this._load, this);
this._networkLogView.addEventListener(Network.NetworkLogView.Events.RequestSelected, this._onRequestSelected, this);
- BrowserSDK.networkLog.addEventListener(BrowserSDK.NetworkLog.Events.RequestAdded, this._onUpdateRequest, this);
- BrowserSDK.networkLog.addEventListener(BrowserSDK.NetworkLog.Events.RequestUpdated, this._onUpdateRequest, this);
- BrowserSDK.networkLog.addEventListener(BrowserSDK.NetworkLog.Events.Reset, this._onNetworkLogReset, this);
+ SDK.networkLog.addEventListener(SDK.NetworkLog.Events.RequestAdded, this._onUpdateRequest, this);
+ SDK.networkLog.addEventListener(SDK.NetworkLog.Events.RequestUpdated, this._onUpdateRequest, this);
+ SDK.networkLog.addEventListener(SDK.NetworkLog.Events.Reset, this._onNetworkLogReset, this);
}
/**
@@ -191,7 +191,7 @@ Network.NetworkPanel = class extends UI.Panel {
}
this._panelToolbar.appendToolbarItem(UI.Toolbar.createActionButton(this._toggleRecordAction));
const clearButton = new UI.ToolbarButton(Common.UIString('Clear'), 'largeicon-clear');
- clearButton.addEventListener(UI.ToolbarButton.Events.Click, () => BrowserSDK.networkLog.reset(), this);
+ clearButton.addEventListener(UI.ToolbarButton.Events.Click, () => SDK.networkLog.reset(), this);
this._panelToolbar.appendToolbarItem(clearButton);
this._panelToolbar.appendSeparator();
const recordFilmStripButton = new UI.ToolbarSettingToggle(
@@ -255,7 +255,7 @@ Network.NetworkPanel = class extends UI.Panel {
_toggleRecording() {
if (!this._preserveLogSetting.get() && !this._toggleRecordAction.toggled())
- BrowserSDK.networkLog.reset();
+ SDK.networkLog.reset();
this._toggleRecord(!this._toggleRecordAction.toggled());
}
@@ -269,7 +269,7 @@ Network.NetworkPanel = class extends UI.Panel {
this._filmStripRecorder.stopRecording(this._filmStripAvailable.bind(this));
// TODO(einbinder) This should be moved to a setting/action that NetworkLog owns but NetworkPanel controls, but
// always be present in the command menu.
- BrowserSDK.networkLog.setIsRecording(toggled);
+ SDK.networkLog.setIsRecording(toggled);
}
/**
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkSearchScope.js b/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkSearchScope.js
index 8320051a51b..57afb465813 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkSearchScope.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/network/NetworkSearchScope.js
@@ -24,8 +24,7 @@ Network.NetworkSearchScope = class {
*/
async performSearch(searchConfig, progress, searchResultCallback, searchFinishedCallback) {
const promises = [];
- const requests =
- BrowserSDK.networkLog.requests().filter(request => searchConfig.filePathMatchesFileQuery(request.url()));
+ const requests = SDK.networkLog.requests().filter(request => searchConfig.filePathMatchesFileQuery(request.url()));
progress.setTotalWork(requests.length);
for (const request of requests) {
const promise = this._searchRequest(searchConfig, request, progress);
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/network/networkConfigView.css b/chromium/third_party/blink/renderer/devtools/front_end/network/networkConfigView.css
index 5c9f81f3ea7..6c5ede0de91 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/network/networkConfigView.css
+++ b/chromium/third_party/blink/renderer/devtools/front_end/network/networkConfigView.css
@@ -64,7 +64,6 @@
.network-config-ua input:not(.dt-radio-button) {
display: block;
width: calc(100% - 20px);
- max-width: 250px;
}
.network-config-ua input[readonly] {
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/network_test_runner/NetworkTestRunner.js b/chromium/third_party/blink/renderer/devtools/front_end/network_test_runner/NetworkTestRunner.js
index 869853fea89..95f78d89e6a 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/network_test_runner/NetworkTestRunner.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/network_test_runner/NetworkTestRunner.js
@@ -54,7 +54,7 @@ NetworkTestRunner.networkWaterfallColumn = function() {
};
NetworkTestRunner.networkRequests = function() {
- return Array.from(BrowserSDK.networkLog.requests());
+ return Array.from(SDK.networkLog.requests());
};
NetworkTestRunner.dumpNetworkRequests = function() {
@@ -71,7 +71,7 @@ NetworkTestRunner.dumpNetworkRequests = function() {
};
NetworkTestRunner.dumpNetworkRequestsWithSignedExchangeInfo = function() {
- for (const request of BrowserSDK.networkLog.requests()) {
+ for (const request of SDK.networkLog.requests()) {
TestRunner.addResult(`* ${request.url()}`);
TestRunner.addResult(` failed: ${!!request.failed}`);
TestRunner.addResult(` statusCode: ${request.statusCode}`);
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/object_ui/JavaScriptAutocomplete.js b/chromium/third_party/blink/renderer/devtools/front_end/object_ui/JavaScriptAutocomplete.js
index cddc8a81818..ddbfbc95e58 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/object_ui/JavaScriptAutocomplete.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/object_ui/JavaScriptAutocomplete.js
@@ -559,7 +559,7 @@ ObjectUI.JavaScriptAutocomplete = class {
allProperties.add(property);
if (property.startsWith(query))
- caseSensitivePrefix.push({text: property, priority: 4});
+ caseSensitivePrefix.push({text: property, priority: property === query ? 5 : 4});
else if (lowerCaseProperty.startsWith(lowerCaseQuery))
caseInsensitivePrefix.push({text: property, priority: 3});
else if (property.indexOf(query) !== -1)
@@ -596,6 +596,23 @@ ObjectUI.JavaScriptAutocomplete = class {
return -1;
return String.naturalOrderComparator(a, b);
}
+
+ /**
+ * @param {string} expression
+ * @return {!Promise<boolean>}
+ */
+ static async isExpressionComplete(expression) {
+ const currentExecutionContext = UI.context.flavor(SDK.ExecutionContext);
+ if (!currentExecutionContext)
+ return true;
+ const result =
+ await currentExecutionContext.runtimeModel.compileScript(expression, '', false, currentExecutionContext.id);
+ if (!result.exceptionDetails)
+ return true;
+ const description = result.exceptionDetails.exception.description;
+ return !description.startsWith('SyntaxError: Unexpected end of input') &&
+ !description.startsWith('SyntaxError: Unterminated template literal');
+ }
};
/** @typedef {{title:(string|undefined), items:Array<string>}} */
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/object_ui/JavaScriptREPL.js b/chromium/third_party/blink/renderer/devtools/front_end/object_ui/JavaScriptREPL.js
new file mode 100644
index 00000000000..bdec0d7627d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/devtools/front_end/object_ui/JavaScriptREPL.js
@@ -0,0 +1,105 @@
+// 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.
+
+ObjectUI.JavaScriptREPL = class {
+ /**
+ * @param {string} code
+ * @return {string}
+ */
+ static wrapObjectLiteral(code) {
+ // Only parenthesize what appears to be an object literal.
+ if (!(/^\s*\{/.test(code) && /\}\s*$/.test(code)))
+ return code;
+
+ const parse = (async () => 0).constructor;
+ try {
+ // Check if the code can be interpreted as an expression.
+ parse('return ' + code + ';');
+
+ // No syntax error! Does it work parenthesized?
+ const wrappedCode = '(' + code + ')';
+ parse(wrappedCode);
+
+ return wrappedCode;
+ } catch (e) {
+ return code;
+ }
+ }
+
+ /**
+ * @param {string} text
+ * @return {!Promise<!{text: string, preprocessed: boolean}>}
+ */
+ static async preprocessExpression(text) {
+ text = ObjectUI.JavaScriptREPL.wrapObjectLiteral(text);
+ let preprocessed = false;
+ if (text.indexOf('await') !== -1) {
+ const preprocessedText = await Formatter.formatterWorkerPool().preprocessTopLevelAwaitExpressions(text);
+ preprocessed = !!preprocessedText;
+ text = preprocessedText || text;
+ }
+ return {text, preprocessed};
+ }
+
+ /**
+ * @param {string} text
+ * @param {boolean} throwOnSideEffect
+ * @param {number=} timeout
+ * @param {boolean=} allowErrors
+ * @return {!Promise<!{preview: !DocumentFragment, result: ?SDK.RuntimeModel.EvaluationResult}>}
+ */
+ static async evaluateAndBuildPreview(text, throwOnSideEffect, timeout, allowErrors) {
+ const executionContext = UI.context.flavor(SDK.ExecutionContext);
+ const isTextLong = text.length > ObjectUI.JavaScriptREPL._MaxLengthForEvaluation;
+ if (!text || !executionContext || (throwOnSideEffect && isTextLong))
+ return {preview: createDocumentFragment(), result: null};
+
+ const wrappedResult = await ObjectUI.JavaScriptREPL.preprocessExpression(text);
+ const options = {
+ expression: wrappedResult.text,
+ generatePreview: true,
+ includeCommandLineAPI: true,
+ throwOnSideEffect: throwOnSideEffect,
+ timeout: timeout
+ };
+ const result = await executionContext.evaluate(
+ options, false /* userGesture */, wrappedResult.preprocessed /* awaitPromise */);
+ const preview = ObjectUI.JavaScriptREPL._buildEvaluationPreview(result, allowErrors);
+ return {preview, result};
+ }
+
+ /**
+ * @param {!SDK.RuntimeModel.EvaluationResult} result
+ * @param {boolean=} allowErrors
+ * @return {!DocumentFragment}
+ */
+ static _buildEvaluationPreview(result, allowErrors) {
+ const fragment = createDocumentFragment();
+ if (result.error)
+ return fragment;
+
+ if (result.exceptionDetails && result.exceptionDetails.exception && result.exceptionDetails.exception.description) {
+ const exception = result.exceptionDetails.exception.description;
+ if (exception.startsWith('TypeError: ') || allowErrors)
+ fragment.createChild('span').textContent = result.exceptionDetails.text + ' ' + exception;
+ return fragment;
+ }
+
+ const formatter = new ObjectUI.RemoteObjectPreviewFormatter();
+ const {preview, type, subtype, description} = result.object;
+ if (preview && type === 'object' && subtype !== 'node') {
+ formatter.appendObjectPreview(fragment, preview, false /* isEntry */);
+ } else {
+ const nonObjectPreview = formatter.renderPropertyPreview(type, subtype, description.trimEnd(400));
+ fragment.appendChild(nonObjectPreview);
+ }
+ return fragment;
+ }
+};
+
+/**
+ * @const
+ * @type {number}
+ */
+ObjectUI.JavaScriptREPL._MaxLengthForEvaluation = 2000;
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/object_ui/ObjectPopoverHelper.js b/chromium/third_party/blink/renderer/devtools/front_end/object_ui/ObjectPopoverHelper.js
index 5fe611ed978..44b1ee92035 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/object_ui/ObjectPopoverHelper.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/object_ui/ObjectPopoverHelper.js
@@ -71,7 +71,8 @@ ObjectUI.ObjectPopoverHelper = class {
const titleElement = popoverContentElement.createChild('div', 'monospace object-popover-title');
titleElement.createChild('span').textContent = description;
linkifier = new Components.Linkifier();
- const section = new ObjectUI.ObjectPropertiesSection(result, '', linkifier);
+ const section = new ObjectUI.ObjectPropertiesSection(
+ result, '', linkifier, undefined, undefined, undefined, true /* showOverflow */);
section.element.classList.add('object-popover-tree');
section.titleLessMode();
popoverContentElement.appendChild(section.element);
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/object_ui/ObjectPropertiesSection.js b/chromium/third_party/blink/renderer/devtools/front_end/object_ui/ObjectPropertiesSection.js
index 88a7f85ddff..076cf7645d0 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/object_ui/ObjectPropertiesSection.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/object_ui/ObjectPropertiesSection.js
@@ -35,13 +35,16 @@ ObjectUI.ObjectPropertiesSection = class extends UI.TreeOutlineInShadow {
* @param {?string=} emptyPlaceholder
* @param {boolean=} ignoreHasOwnProperty
* @param {!Array.<!SDK.RemoteObjectProperty>=} extraProperties
+ * @param {boolean=} showOverflow
*/
- constructor(object, title, linkifier, emptyPlaceholder, ignoreHasOwnProperty, extraProperties) {
+ constructor(object, title, linkifier, emptyPlaceholder, ignoreHasOwnProperty, extraProperties, showOverflow) {
super();
this._object = object;
this._editable = true;
- this.hideOverflow();
- this.setFocusable(false);
+ if (!showOverflow)
+ this.hideOverflow();
+ this.setFocusable(true);
+ this.setShowSelectionOnKeyboardFocus(true);
this._objectTreeElement = new ObjectUI.ObjectPropertiesSection.RootElement(
object, linkifier, emptyPlaceholder, ignoreHasOwnProperty, extraProperties);
this.appendChild(this._objectTreeElement);
@@ -435,7 +438,7 @@ ObjectUI.ObjectPropertiesSection.RootElement = class extends UI.TreeElement {
this._emptyPlaceholder = emptyPlaceholder;
this.setExpandable(true);
- this.selectable = false;
+ this.selectable = true;
this.toggleOnClick = true;
this.listItemElement.classList.add('object-properties-section-root-element');
this._linkifier = linkifier;
@@ -490,7 +493,6 @@ ObjectUI.ObjectPropertyTreeElement = class extends UI.TreeElement {
this.property = property;
this.toggleOnClick = true;
- this.selectable = false;
/** @type {!Array.<!Object>} */
this._highlightChanges = [];
this._linkifier = linkifier;
@@ -792,7 +794,7 @@ ObjectUI.ObjectPropertyTreeElement = class extends UI.TreeElement {
this.expandedValueElement = this._createExpandedValueElement(this.property.value);
this.listItemElement.removeChildren();
- this._rowContainer = UI.html`<span>${this.nameElement}: ${this.valueElement}</span>`;
+ this._rowContainer = UI.html`<span class='name-and-value'>${this.nameElement}: ${this.valueElement}</span>`;
this.listItemElement.appendChild(this._rowContainer);
}
@@ -864,6 +866,7 @@ ObjectUI.ObjectPropertyTreeElement = class extends UI.TreeElement {
const proxyElement =
this._prompt.attachAndStartEditing(this._editableDiv, this._editingCommitted.bind(this, originalContent));
+ proxyElement.classList.add('property-prompt');
this.listItemElement.getComponentSelection().selectAllChildren(this._editableDiv);
proxyElement.addEventListener('keydown', this._promptKeyDown.bind(this, originalContent), false);
}
@@ -918,7 +921,7 @@ ObjectUI.ObjectPropertyTreeElement = class extends UI.TreeElement {
*/
async _applyExpression(expression) {
const property = SDK.RemoteObject.toCallArgument(this.property.symbol || this.property.name);
- expression = SDK.RuntimeModel.wrapObjectLiteralExpressionIfNeeded(expression.trim());
+ expression = ObjectUI.JavaScriptREPL.wrapObjectLiteral(expression.trim());
if (this.property.synthetic) {
let invalidate = false;
@@ -1000,7 +1003,6 @@ ObjectUI.ArrayGroupingTreeElement = class extends UI.TreeElement {
constructor(object, fromIndex, toIndex, propertyCount, linkifier) {
super(String.sprintf('[%d \u2026 %d]', fromIndex, toIndex), true);
this.toggleOnClick = true;
- this.selectable = false;
this._fromIndex = fromIndex;
this._toIndex = toIndex;
this._object = object;
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/object_ui/RemoteObjectPreviewFormatter.js b/chromium/third_party/blink/renderer/devtools/front_end/object_ui/RemoteObjectPreviewFormatter.js
index 3a67026133a..37c61c7f280 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/object_ui/RemoteObjectPreviewFormatter.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/object_ui/RemoteObjectPreviewFormatter.js
@@ -32,7 +32,7 @@ ObjectUI.RemoteObjectPreviewFormatter = class {
}
/**
- * @param {!Element} parentElement
+ * @param {!DocumentFragment|!Element} parentElement
* @param {!Protocol.Runtime.ObjectPreview} preview
* @param {boolean} isEntry
*/
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/object_ui/module.json b/chromium/third_party/blink/renderer/devtools/front_end/object_ui/module.json
index 3cfab8316a3..d56753b9a10 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/object_ui/module.json
+++ b/chromium/third_party/blink/renderer/devtools/front_end/object_ui/module.json
@@ -19,6 +19,7 @@
"ObjectPopoverHelper.js",
"ObjectPropertiesSection.js",
"JavaScriptAutocomplete.js",
+ "JavaScriptREPL.js",
"RemoteObjectPreviewFormatter.js"
],
"resources": [
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/object_ui/objectPropertiesSection.css b/chromium/third_party/blink/renderer/devtools/front_end/object_ui/objectPropertiesSection.css
index 6b4df5f92e9..1ef1a87609d 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/object_ui/objectPropertiesSection.css
+++ b/chromium/third_party/blink/renderer/devtools/front_end/object_ui/objectPropertiesSection.css
@@ -50,3 +50,18 @@
.object-properties-section .editable-div {
overflow: hidden;
}
+
+.name-and-value {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ line-height: normal;
+}
+
+.editing-sub-part .name-and-value {
+ overflow: visible;
+ display: inline-flex;
+}
+
+.property-prompt {
+ margin-left: 4px;
+}
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/perf_ui/FlameChart.js b/chromium/third_party/blink/renderer/devtools/front_end/perf_ui/FlameChart.js
index 327fd7a722b..86f2a163a4a 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/perf_ui/FlameChart.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/perf_ui/FlameChart.js
@@ -73,13 +73,18 @@ PerfUI.FlameChart = class extends UI.VBox {
this._groupExpansionState = groupExpansionSetting && groupExpansionSetting.get() || {};
this._flameChartDelegate = flameChartDelegate;
+ this._useWebGL = Runtime.experiments.isEnabled('timelineWebGL');
this._chartViewport = new PerfUI.ChartViewport(this);
this._chartViewport.show(this.contentElement);
this._dataProvider = dataProvider;
this._viewportElement = this._chartViewport.viewportElement;
- this._canvas = /** @type {!HTMLCanvasElement} */ (this._viewportElement.createChild('canvas'));
+ if (this._useWebGL) {
+ this._canvasGL = /** @type {!HTMLCanvasElement} */ (this._viewportElement.createChild('canvas', 'fill'));
+ this._initWebGL();
+ }
+ this._canvas = /** @type {!HTMLCanvasElement} */ (this._viewportElement.createChild('canvas', 'fill'));
this._canvas.tabIndex = 0;
this.setDefaultFocusedElement(this._canvas);
@@ -204,6 +209,12 @@ PerfUI.FlameChart = class extends UI.VBox {
this._canvas.height = height;
this._canvas.style.width = `${width / ratio}px`;
this._canvas.style.height = `${height / ratio}px`;
+ if (this._useWebGL) {
+ this._canvasGL.width = width;
+ this._canvasGL.height = height;
+ this._canvasGL.style.width = `${width / ratio}px`;
+ this._canvasGL.style.height = `${height / ratio}px`;
+ }
}
/**
@@ -683,6 +694,8 @@ PerfUI.FlameChart = class extends UI.VBox {
const ratio = window.devicePixelRatio;
const top = this._chartViewport.scrollOffset();
context.scale(ratio, ratio);
+ context.fillStyle = 'rgba(0, 0, 0, 0)';
+ context.fillRect(0, 0, width, height);
context.translate(0, -top);
const defaultFont = '11px ' + Host.fontFamily();
context.font = defaultFont;
@@ -696,17 +709,9 @@ PerfUI.FlameChart = class extends UI.VBox {
const markerIndices = [];
const textPadding = this._textPadding;
const minTextWidth = 2 * textPadding + UI.measureTextWidth(context, '\u2026');
+ const minTextWidthDuration = this._chartViewport.pixelToTimeOffset(minTextWidth);
const minVisibleBarLevel = Math.max(this._visibleLevelOffsets.upperBound(top) - 1, 0);
- context.save();
- this._forEachGroup((offset, index, group, isFirst, groupHeight) => {
- if (index === this._selectedGroup) {
- context.fillStyle = this._selectedGroupBackroundColor;
- context.fillRect(0, offset, width, groupHeight - group.style.padding);
- }
- });
- context.restore();
-
/** @type {!Map<string, !Array<number>>} */
const colorBuckets = new Map();
for (let level = minVisibleBarLevel; level < this._dataProvider.maxStackDepth(); ++level) {
@@ -724,10 +729,19 @@ PerfUI.FlameChart = class extends UI.VBox {
let lastDrawOffset = Infinity;
for (let entryIndexOnLevel = rightIndexOnLevel; entryIndexOnLevel >= 0; --entryIndexOnLevel) {
const entryIndex = levelIndexes[entryIndexOnLevel];
+ let duration = entryTotalTimes[entryIndex];
+ if (isNaN(duration))
+ markerIndices.push(entryIndex);
+ duration = duration || 0;
+ if (duration >= minTextWidthDuration || this._forceDecorationCache[entryIndex])
+ titleIndices.push(entryIndex);
+
const entryStartTime = entryStartTimes[entryIndex];
- const entryOffsetRight = entryStartTime + (entryTotalTimes[entryIndex] || 0);
+ const entryOffsetRight = entryStartTime + duration;
if (entryOffsetRight <= this._chartViewport.windowLeftTime())
break;
+ if (this._useWebGL)
+ continue;
const barX = this._timeToPositionClipped(entryStartTime);
// Check if the entry entirely fits into an already drawn pixel, we can just skip drawing it.
@@ -735,7 +749,7 @@ PerfUI.FlameChart = class extends UI.VBox {
continue;
lastDrawOffset = barX;
- const color = this._dataProvider.entryColor(entryIndex);
+ const color = this._entryColorsCache[entryIndex];
let bucket = colorBuckets.get(color);
if (!bucket) {
bucket = [];
@@ -745,37 +759,47 @@ PerfUI.FlameChart = class extends UI.VBox {
}
}
- const colors = colorBuckets.keysArray();
- // We don't use for-of here because it's slow.
- for (let c = 0; c < colors.length; ++c) {
- const color = colors[c];
- const indexes = colorBuckets.get(color);
- context.beginPath();
- for (let i = 0; i < indexes.length; ++i) {
- const entryIndex = indexes[i];
- const entryStartTime = entryStartTimes[entryIndex];
- const barX = this._timeToPositionClipped(entryStartTime);
- const duration = entryTotalTimes[entryIndex];
- const barLevel = entryLevels[entryIndex];
- const barHeight = this._levelHeight(barLevel);
- const barY = this._levelToOffset(barLevel);
- if (isNaN(duration)) {
- context.moveTo(barX + this._markerRadius, barY + barHeight / 2);
- context.arc(barX, barY + barHeight / 2, this._markerRadius, 0, Math.PI * 2);
- markerIndices.push(entryIndex);
- continue;
+ if (this._useWebGL) {
+ this._drawGL();
+ } else {
+ context.save();
+ this._forEachGroupInViewport((offset, index, group, isFirst, groupHeight) => {
+ if (index === this._selectedGroup) {
+ context.fillStyle = this._selectedGroupBackroundColor;
+ context.fillRect(0, offset, width, groupHeight - group.style.padding);
}
- const barRight = this._timeToPositionClipped(entryStartTime + duration);
- const barWidth = Math.max(barRight - barX, 1);
- if (color)
- context.rect(barX, barY, barWidth - 0.4, barHeight - 1);
- if (barWidth > minTextWidth || this._dataProvider.forceDecoration(entryIndex))
- titleIndices.push(entryIndex);
+ });
+ context.restore();
+
+ const colors = colorBuckets.keysArray();
+ // We don't use for-of here because it's slow.
+ for (let c = 0; c < colors.length; ++c) {
+ const color = colors[c];
+ const indexes = colorBuckets.get(color);
+ context.beginPath();
+ for (let i = 0; i < indexes.length; ++i) {
+ const entryIndex = indexes[i];
+ const entryStartTime = entryStartTimes[entryIndex];
+ const barX = this._timeToPositionClipped(entryStartTime);
+ const duration = entryTotalTimes[entryIndex];
+ const barLevel = entryLevels[entryIndex];
+ const barHeight = this._levelHeight(barLevel);
+ const barY = this._levelToOffset(barLevel);
+ if (isNaN(duration)) {
+ context.moveTo(barX + this._markerRadius, barY + barHeight / 2);
+ context.arc(barX, barY + barHeight / 2, this._markerRadius, 0, Math.PI * 2);
+ continue;
+ }
+ const barRight = this._timeToPositionClipped(entryStartTime + duration);
+ const barWidth = Math.max(barRight - barX, 1);
+ if (color)
+ context.rect(barX, barY, barWidth - 0.4, barHeight - 1);
+ }
+ if (!color)
+ continue;
+ context.fillStyle = color;
+ context.fill();
}
- if (!color)
- continue;
- context.fillStyle = color;
- context.fill();
}
context.beginPath();
@@ -834,6 +858,218 @@ PerfUI.FlameChart = class extends UI.VBox {
this._updateMarkerHighlight();
}
+ _initWebGL() {
+ const gl = /** @type {?WebGLRenderingContext} */ (this._canvasGL.getContext('webgl'));
+ if (!gl) {
+ console.error('Failed to obtain WebGL context.');
+ this._useWebGL = false; // Fallback to use canvas.
+ return;
+ }
+
+ const vertexShaderSource = `
+ attribute vec2 aVertexPosition;
+ attribute float aVertexColor;
+
+ uniform vec2 uScalingFactor;
+ uniform vec2 uShiftVector;
+
+ varying mediump vec2 vPalettePosition;
+
+ void main() {
+ vec2 shiftedPosition = aVertexPosition - uShiftVector;
+ gl_Position = vec4(shiftedPosition * uScalingFactor + vec2(-1.0, 1.0), 0.0, 1.0);
+ vPalettePosition = vec2(aVertexColor, 0.5);
+ }`;
+
+ const fragmentShaderSource = `
+ varying mediump vec2 vPalettePosition;
+ uniform sampler2D uSampler;
+
+ void main() {
+ gl_FragColor = texture2D(uSampler, vPalettePosition);
+ }`;
+
+ /**
+ * @param {!WebGLRenderingContext} gl
+ * @param {number} type
+ * @param {string} source
+ * @return {?WebGLShader}
+ */
+ function loadShader(gl, type, source) {
+ const shader = gl.createShader(type);
+ gl.shaderSource(shader, source);
+ gl.compileShader(shader);
+ if (gl.getShaderParameter(shader, gl.COMPILE_STATUS))
+ return shader;
+ console.error('Shader compile error: ' + gl.getShaderInfoLog(shader));
+ gl.deleteShader(shader);
+ return null;
+ }
+
+ const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
+ const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
+
+ const shaderProgram = gl.createProgram();
+ gl.attachShader(shaderProgram, vertexShader);
+ gl.attachShader(shaderProgram, fragmentShader);
+ gl.linkProgram(shaderProgram);
+
+ if (gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
+ this._shaderProgram = shaderProgram;
+ gl.useProgram(shaderProgram);
+ } else {
+ console.error('Unable to initialize the shader program: ' + gl.getProgramInfoLog(shaderProgram));
+ this._shaderProgram = null;
+ }
+
+ this._vertexBuffer = gl.createBuffer();
+ this._colorBuffer = gl.createBuffer();
+
+ this._uScalingFactor = gl.getUniformLocation(shaderProgram, 'uScalingFactor');
+ this._uShiftVector = gl.getUniformLocation(shaderProgram, 'uShiftVector');
+ const uSampler = gl.getUniformLocation(shaderProgram, 'uSampler');
+ gl.uniform1i(uSampler, 0);
+ this._aVertexPosition = gl.getAttribLocation(this._shaderProgram, 'aVertexPosition');
+ this._aVertexColor = gl.getAttribLocation(this._shaderProgram, 'aVertexColor');
+ gl.enableVertexAttribArray(this._aVertexPosition);
+ gl.enableVertexAttribArray(this._aVertexColor);
+ }
+
+ _setupGLGeometry() {
+ const gl = /** @type {?WebGLRenderingContext} */ (this._canvasGL.getContext('webgl'));
+ if (!gl)
+ return;
+
+ const timelineData = this._timelineData();
+ if (!timelineData)
+ return;
+
+ const entryTotalTimes = timelineData.entryTotalTimes;
+ const entryStartTimes = timelineData.entryStartTimes;
+ const entryLevels = timelineData.entryLevels;
+
+ const verticesPerBar = 6;
+ const vertexArray = new Float32Array(entryTotalTimes.length * verticesPerBar * 2);
+ let colorArray = new Uint8Array(entryTotalTimes.length * verticesPerBar);
+ let vertex = 0;
+ /** @type {!Map<string, number>} */
+ const parsedColorCache = new Map();
+ /** @type {!Array<number>} */
+ const colors = [];
+
+ const collapsedOverviewLevels = new Array(this._visibleLevels.length);
+ const groups = this._rawTimelineData.groups || [];
+ this._forEachGroup((offset, index, group) => {
+ if (group.style.useFirstLineForOverview || !this._isGroupCollapsible(index) || group.expanded)
+ return;
+ let nextGroup = index + 1;
+ while (nextGroup < groups.length && groups[nextGroup].style.nestingLevel > group.style.nestingLevel)
+ ++nextGroup;
+ const endLevel = nextGroup < groups.length ? groups[nextGroup].startLevel : this._dataProvider.maxStackDepth();
+ for (let i = group.startLevel; i < endLevel; ++i)
+ collapsedOverviewLevels[i] = offset;
+ });
+
+ for (let i = 0; i < entryTotalTimes.length; ++i) {
+ const level = entryLevels[i];
+ const collapsedGroupOffset = collapsedOverviewLevels[level];
+ if (!this._visibleLevels[level] && !collapsedGroupOffset)
+ continue;
+ const color = this._entryColorsCache[i];
+ if (!color)
+ continue;
+ let colorIndex = parsedColorCache.get(color);
+ if (colorIndex === undefined) {
+ const rgba = Common.Color.parse(color).canonicalRGBA();
+ rgba[3] = Math.round(rgba[3] * 255);
+ colorIndex = colors.length / 4;
+ colors.push(...rgba);
+ if (colorIndex === 256)
+ colorArray = new Uint16Array(colorArray);
+ parsedColorCache.set(color, colorIndex);
+ }
+ for (let j = 0; j < verticesPerBar; ++j)
+ colorArray[vertex + j] = colorIndex;
+
+ const vpos = vertex * 2;
+ const x0 = entryStartTimes[i] - this._minimumBoundary;
+ const x1 = x0 + entryTotalTimes[i];
+ const y0 = collapsedGroupOffset || this._levelToOffset(level);
+ const y1 = y0 + this._levelHeight(level) - 1;
+ vertexArray[vpos + 0] = x0;
+ vertexArray[vpos + 1] = y0;
+ vertexArray[vpos + 2] = x1;
+ vertexArray[vpos + 3] = y0;
+ vertexArray[vpos + 4] = x0;
+ vertexArray[vpos + 5] = y1;
+ vertexArray[vpos + 6] = x0;
+ vertexArray[vpos + 7] = y1;
+ vertexArray[vpos + 8] = x1;
+ vertexArray[vpos + 9] = y0;
+ vertexArray[vpos + 10] = x1;
+ vertexArray[vpos + 11] = y1;
+
+ vertex += verticesPerBar;
+ }
+ this._vertexCount = vertex;
+
+ const paletteTexture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, paletteTexture);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ gl.activeTexture(gl.TEXTURE0);
+
+ const numColors = colors.length / 4;
+ const useShortForColors = numColors >= 256;
+ const width = !useShortForColors ? 256 : Math.min(1 << 16, gl.getParameter(gl.MAX_TEXTURE_SIZE));
+ console.assert(numColors <= width, 'Too many colors');
+ const height = 1;
+ const colorIndexType = useShortForColors ? gl.UNSIGNED_SHORT : gl.UNSIGNED_BYTE;
+ if (useShortForColors) {
+ const factor = (1 << 16) / width;
+ for (let i = 0; i < vertex; ++i)
+ colorArray[i] *= factor;
+ }
+
+ const pixels = new Uint8Array(width * 4);
+ pixels.set(colors);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, vertexArray, gl.STATIC_DRAW);
+ gl.vertexAttribPointer(this._aVertexPosition, /* vertexComponents */ 2, gl.FLOAT, false, 0, 0);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, this._colorBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, colorArray, gl.STATIC_DRAW);
+ gl.vertexAttribPointer(this._aVertexColor, /* colorComponents */ 1, colorIndexType, true, 0, 0);
+ }
+
+ _drawGL() {
+ const gl = /** @type {?WebGLRenderingContext} */ (this._canvasGL.getContext('webgl'));
+ if (!gl)
+ return;
+ const timelineData = this._timelineData();
+ if (!timelineData)
+ return;
+
+ if (!this._prevTimelineData || timelineData.entryTotalTimes !== this._prevTimelineData.entryTotalTimes) {
+ this._prevTimelineData = timelineData;
+ this._setupGLGeometry();
+ }
+
+ gl.viewport(0, 0, this._canvasGL.width, this._canvasGL.height);
+
+ if (!this._vertexCount)
+ return;
+
+ const viewportScale = [2.0 / this.boundarySpan(), -2.0 * window.devicePixelRatio / this._canvasGL.height];
+ const viewportShift = [this.minimumBoundary() - this.zeroTime(), this._chartViewport.scrollOffset()];
+ gl.uniform2fv(this._uScalingFactor, viewportScale);
+ gl.uniform2fv(this._uShiftVector, viewportShift);
+
+ gl.drawArrays(gl.TRIANGLES, 0, this._vertexCount);
+ }
+
/**
* @param {number} width
* @param {number} height
@@ -857,7 +1093,7 @@ PerfUI.FlameChart = class extends UI.VBox {
context.font = defaultFont;
context.fillStyle = UI.themeSupport.patchColorText('#fff', colorUsage.Background);
- this._forEachGroup((offset, index, group) => {
+ this._forEachGroupInViewport((offset, index, group) => {
const paddingHeight = group.style.padding;
if (paddingHeight < 5)
return;
@@ -868,7 +1104,7 @@ PerfUI.FlameChart = class extends UI.VBox {
context.strokeStyle = UI.themeSupport.patchColorText('#eee', colorUsage.Background);
context.beginPath();
- this._forEachGroup((offset, index, group, isFirst) => {
+ this._forEachGroupInViewport((offset, index, group, isFirst) => {
if (isFirst || group.style.padding < 4)
return;
hLine(offset - 2.5);
@@ -876,7 +1112,7 @@ PerfUI.FlameChart = class extends UI.VBox {
hLine(lastGroupOffset + 1.5);
context.stroke();
- this._forEachGroup((offset, index, group) => {
+ this._forEachGroupInViewport((offset, index, group) => {
if (group.style.useFirstLineForOverview)
return;
if (!this._isGroupCollapsible(index) || group.expanded) {
@@ -886,6 +1122,8 @@ PerfUI.FlameChart = class extends UI.VBox {
}
return;
}
+ if (this._useWebGL)
+ return;
let nextGroup = index + 1;
while (nextGroup < groups.length && groups[nextGroup].style.nestingLevel > group.style.nestingLevel)
nextGroup++;
@@ -894,7 +1132,7 @@ PerfUI.FlameChart = class extends UI.VBox {
});
context.save();
- this._forEachGroup((offset, index, group) => {
+ this._forEachGroupInViewport((offset, index, group) => {
context.font = group.style.font;
if (this._isGroupCollapsible(index) && !group.expanded || group.style.shareHeaderLine) {
const width = this._labelWidthForGroup(context, group) + 2;
@@ -916,7 +1154,7 @@ PerfUI.FlameChart = class extends UI.VBox {
context.fillStyle = UI.themeSupport.patchColorText('#6e6e6e', colorUsage.Foreground);
context.beginPath();
- this._forEachGroup((offset, index, group) => {
+ this._forEachGroupInViewport((offset, index, group) => {
if (this._isGroupCollapsible(index)) {
drawExpansionArrow.call(
this, this._expansionArrowIndent * (group.style.nestingLevel + 1),
@@ -929,7 +1167,7 @@ PerfUI.FlameChart = class extends UI.VBox {
context.beginPath();
context.stroke();
- this._forEachGroup((offset, index, group, isFirst, groupHeight) => {
+ this._forEachGroupInViewport((offset, index, group, isFirst, groupHeight) => {
if (index === this._selectedGroup) {
const lineWidth = 2;
const bracketLength = 10;
@@ -973,7 +1211,6 @@ PerfUI.FlameChart = class extends UI.VBox {
* @param {function(number, number, !PerfUI.FlameChart.Group, boolean, number)} callback
*/
_forEachGroup(callback) {
- const top = this._chartViewport.scrollOffset();
const groups = this._rawTimelineData.groups || [];
if (!groups.length)
return;
@@ -983,8 +1220,6 @@ PerfUI.FlameChart = class extends UI.VBox {
for (let i = 0; i < groups.length; ++i) {
const groupTop = groupOffsets[i];
const group = groups[i];
- if (groupTop - group.style.padding > top + this._offsetHeight)
- break;
let firstGroup = true;
while (groupStack.peekLast().nestingLevel >= group.style.nestingLevel) {
groupStack.pop();
@@ -994,13 +1229,27 @@ PerfUI.FlameChart = class extends UI.VBox {
const thisGroupVisible = parentGroupVisible && (!this._isGroupCollapsible(i) || group.expanded);
groupStack.push({nestingLevel: group.style.nestingLevel, visible: thisGroupVisible});
const nextOffset = i === groups.length - 1 ? groupOffsets[i + 1] + group.style.padding : groupOffsets[i + 1];
- if (!parentGroupVisible || nextOffset < top)
+ if (!parentGroupVisible)
continue;
callback(groupTop, i, group, firstGroup, nextOffset - groupTop);
}
}
/**
+ * @param {function(number, number, !PerfUI.FlameChart.Group, boolean, number)} callback
+ */
+ _forEachGroupInViewport(callback) {
+ const top = this._chartViewport.scrollOffset();
+ this._forEachGroup((groupTop, index, group, firstGroup, height) => {
+ if (groupTop - group.style.padding > top + this._offsetHeight)
+ return;
+ if (groupTop + height < top)
+ return;
+ callback(groupTop, index, group, firstGroup, height);
+ });
+ }
+
+ /**
* @param {!CanvasRenderingContext2D} context
* @param {!PerfUI.FlameChart.Group} group
* @return {number}
@@ -1041,7 +1290,7 @@ PerfUI.FlameChart = class extends UI.VBox {
if (entryEndTime <= timeWindowLeft)
break;
lastDrawOffset = barX;
- const color = this._dataProvider.entryColor(entryIndex);
+ const color = this._entryColorsCache[entryIndex];
const endBarX = this._timeToPositionClipped(entryEndTime);
if (group.style.useDecoratorsForOverview && this._dataProvider.forceDecoration(entryIndex)) {
const unclippedBarX = this._chartViewport.timeToPosition(entryStartTime);
@@ -1197,6 +1446,8 @@ PerfUI.FlameChart = class extends UI.VBox {
this._visibleLevels = null;
this._groupOffsets = null;
this._rawTimelineData = null;
+ this._forceDecorationCache = null;
+ this._entryColorsCache = null;
this._rawTimelineDataLength = 0;
this._selectedGroup = -1;
this._flameChartDelegate.updateSelectedGroup(this, null);
@@ -1205,6 +1456,12 @@ PerfUI.FlameChart = class extends UI.VBox {
this._rawTimelineData = timelineData;
this._rawTimelineDataLength = timelineData.entryStartTimes.length;
+ this._forceDecorationCache = new Int8Array(this._rawTimelineDataLength);
+ this._entryColorsCache = new Array(this._rawTimelineDataLength);
+ for (let i = 0; i < this._rawTimelineDataLength; ++i) {
+ this._forceDecorationCache[i] = this._dataProvider.forceDecoration(i) ? 1 : 0;
+ this._entryColorsCache[i] = this._dataProvider.entryColor(i);
+ }
const entryCounters = new Uint32Array(this._dataProvider.maxStackDepth() + 1);
for (let i = 0; i < timelineData.entryLevels.length; ++i)
@@ -1293,6 +1550,8 @@ PerfUI.FlameChart = class extends UI.VBox {
if (groupIndex >= 0)
this._groupOffsets[groupIndex + 1] = currentOffset;
this._visibleLevelOffsets[level] = currentOffset;
+ if (this._useWebGL)
+ this._setupGLGeometry();
}
/**
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/persistence/Automapping.js b/chromium/third_party/blink/renderer/devtools/front_end/persistence/Automapping.js
index ab71f335d83..68feae279ac 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/persistence/Automapping.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/persistence/Automapping.js
@@ -114,8 +114,7 @@ Persistence.Automapping = class {
_onUISourceCodeAdded(uiSourceCode) {
const project = uiSourceCode.project();
if (project.type() === Workspace.projectTypes.FileSystem) {
- // Never do bindings to filesystems that are typed to another client.
- if (Persistence.FileSystemWorkspaceBinding.fileSystemType(project))
+ if (!Persistence.FileSystemWorkspaceBinding.fileSystemSupportsAutomapping(project))
return;
this._filesIndex.addPath(uiSourceCode.url());
this._fileSystemUISourceCodes.set(uiSourceCode.url(), uiSourceCode);
@@ -179,6 +178,8 @@ Persistence.Automapping = class {
async function validateStatus(status) {
if (!status)
return null;
+ if (networkSourceCode[Persistence.Automapping._processingPromise] !== createBindingPromise)
+ return null;
if (status.network.contentType().isFromSourceMap() || !status.fileSystem.contentType().isTextType())
return status;
@@ -297,7 +298,7 @@ Persistence.Automapping = class {
* @return {!Promise<?Persistence.AutomappingStatus>}
*/
_createBinding(networkSourceCode) {
- if (networkSourceCode.url().startsWith('file://')) {
+ if (networkSourceCode.url().startsWith('file://') || networkSourceCode.url().startsWith('snippet://')) {
const fileSourceCode = this._fileSystemUISourceCodes.get(networkSourceCode.url());
const status =
fileSourceCode ? new Persistence.AutomappingStatus(networkSourceCode, fileSourceCode, false) : null;
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/persistence/FileSystemWorkspaceBinding.js b/chromium/third_party/blink/renderer/devtools/front_end/persistence/FileSystemWorkspaceBinding.js
index ceb171c55b8..bbf6ce73481 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/persistence/FileSystemWorkspaceBinding.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/persistence/FileSystemWorkspaceBinding.js
@@ -71,6 +71,16 @@ Persistence.FileSystemWorkspaceBinding = class {
}
/**
+ * @param {!Workspace.UISourceCode} uiSourceCode
+ * @return {string}
+ */
+ static tooltipForUISourceCode(uiSourceCode) {
+ const fileSystem =
+ /** @type {!Persistence.FileSystemWorkspaceBinding.FileSystem}*/ (uiSourceCode.project())._fileSystem;
+ return fileSystem.tooltipForURL(uiSourceCode.url());
+ }
+
+ /**
* @param {!Workspace.Project} project
* @return {string}
*/
@@ -82,6 +92,16 @@ Persistence.FileSystemWorkspaceBinding = class {
/**
* @param {!Workspace.Project} project
+ * @return {boolean}
+ */
+ static fileSystemSupportsAutomapping(project) {
+ const fileSystem =
+ /** @type {!Persistence.FileSystemWorkspaceBinding.FileSystem}*/ (project)._fileSystem;
+ return fileSystem.supportsAutomapping();
+ }
+
+ /**
+ * @param {!Workspace.Project} project
* @param {string} relativePath
* @return {string}
*/
@@ -91,23 +111,6 @@ Persistence.FileSystemWorkspaceBinding = class {
}
/**
- * @param {string} extension
- * @return {!Common.ResourceType}
- */
- static _contentTypeForExtension(extension) {
- if (Persistence.FileSystemWorkspaceBinding._styleSheetExtensions.has(extension))
- return Common.resourceTypes.Stylesheet;
- if (Persistence.FileSystemWorkspaceBinding._documentExtensions.has(extension))
- return Common.resourceTypes.Document;
- if (Persistence.FileSystemWorkspaceBinding._imageExtensions.has(extension))
- return Common.resourceTypes.Image;
- if (Persistence.FileSystemWorkspaceBinding._scriptExtensions.has(extension))
- return Common.resourceTypes.Script;
- return Persistence.FileSystemWorkspaceBinding._binaryExtensions.has(extension) ? Common.resourceTypes.Other :
- Common.resourceTypes.Document;
- }
-
- /**
* @param {string} projectId
* @return {string}
*/
@@ -134,12 +137,12 @@ Persistence.FileSystemWorkspaceBinding = class {
* @param {!Common.Event} event
*/
_onFileSystemAdded(event) {
- const fileSystem = /** @type {!Persistence.IsolatedFileSystem} */ (event.data);
+ const fileSystem = /** @type {!Persistence.PlatformFileSystem} */ (event.data);
this._addFileSystem(fileSystem);
}
/**
- * @param {!Persistence.IsolatedFileSystem} fileSystem
+ * @param {!Persistence.PlatformFileSystem} fileSystem
*/
_addFileSystem(fileSystem) {
const boundFileSystem = new Persistence.FileSystemWorkspaceBinding.FileSystem(this, fileSystem, this._workspace);
@@ -150,7 +153,7 @@ Persistence.FileSystemWorkspaceBinding = class {
* @param {!Common.Event} event
*/
_onFileSystemRemoved(event) {
- const fileSystem = /** @type {!Persistence.IsolatedFileSystem} */ (event.data);
+ const fileSystem = /** @type {!Persistence.PlatformFileSystem} */ (event.data);
const boundFileSystem = this._boundFileSystems.get(fileSystem.path());
boundFileSystem.dispose();
this._boundFileSystems.remove(fileSystem.path());
@@ -192,17 +195,6 @@ Persistence.FileSystemWorkspaceBinding = class {
}
};
-Persistence.FileSystemWorkspaceBinding._styleSheetExtensions = new Set(['css', 'scss', 'sass', 'less']);
-Persistence.FileSystemWorkspaceBinding._documentExtensions = new Set(['htm', 'html', 'asp', 'aspx', 'phtml', 'jsp']);
-Persistence.FileSystemWorkspaceBinding._scriptExtensions = new Set([
- 'asp', 'aspx', 'c', 'cc', 'cljs', 'coffee', 'cpp', 'cs', 'dart', 'java', 'js',
- 'jsp', 'jsx', 'h', 'm', 'mjs', 'mm', 'py', 'sh', 'ts', 'tsx', 'ls'
-]);
-
-Persistence.FileSystemWorkspaceBinding._imageExtensions = Persistence.IsolatedFileSystem.ImageExtensions;
-
-Persistence.FileSystemWorkspaceBinding._binaryExtensions = Persistence.IsolatedFileSystem.BinaryExtensions;
-
/**
* @implements {Workspace.Project}
* @unrestricted
@@ -210,7 +202,7 @@ Persistence.FileSystemWorkspaceBinding._binaryExtensions = Persistence.IsolatedF
Persistence.FileSystemWorkspaceBinding.FileSystem = class extends Workspace.ProjectStore {
/**
* @param {!Persistence.FileSystemWorkspaceBinding} fileSystemWorkspaceBinding
- * @param {!Persistence.IsolatedFileSystem} isolatedFileSystem
+ * @param {!Persistence.PlatformFileSystem} isolatedFileSystem
* @param {!Workspace.Workspace} workspace
*/
constructor(fileSystemWorkspaceBinding, isolatedFileSystem, workspace) {
@@ -246,7 +238,7 @@ Persistence.FileSystemWorkspaceBinding.FileSystem = class extends Workspace.Proj
* @return {string}
*/
mimeType(uiSourceCode) {
- return Common.ResourceType.mimeFromURL(uiSourceCode.url()) || 'text/plain';
+ return this._fileSystem.mimeFromPath(uiSourceCode.url());
}
/**
@@ -383,9 +375,8 @@ Persistence.FileSystemWorkspaceBinding.FileSystem = class extends Workspace.Proj
const parentPath = filePath.substring(0, slash);
filePath = parentPath + '/' + newName;
filePath = filePath.substr(1);
- const extension = this._extensionForPath(newName);
const newURL = this._fileSystemBaseURL + filePath;
- const newContentType = Persistence.FileSystemWorkspaceBinding._contentTypeForExtension(extension);
+ const newContentType = this._fileSystem.contentType(newName);
this.renameUISourceCode(uiSourceCode, newName);
callback(true, newName, newURL, newContentType);
}
@@ -445,14 +436,6 @@ Persistence.FileSystemWorkspaceBinding.FileSystem = class extends Workspace.Proj
this._fileSystem.indexContent(progress);
}
- /**
- * @param {string} path
- * @return {string}
- */
- _extensionForPath(path) {
- return Common.ParsedURL.extractExtension(path);
- }
-
populate() {
const chunkSize = 1000;
const filePaths = this._fileSystem.initialFilePaths();
@@ -497,7 +480,7 @@ Persistence.FileSystemWorkspaceBinding.FileSystem = class extends Workspace.Proj
* @return {boolean}
*/
canExcludeFolder(path) {
- return !!path && Persistence.FileSystemWorkspaceBinding.fileSystemType(this) !== 'overrides';
+ return this._fileSystem.canExcludeFolder(path);
}
/**
@@ -552,9 +535,7 @@ Persistence.FileSystemWorkspaceBinding.FileSystem = class extends Workspace.Proj
* @return {!Workspace.UISourceCode}
*/
_addFile(filePath) {
- const extension = this._extensionForPath(filePath);
- const contentType = Persistence.FileSystemWorkspaceBinding._contentTypeForExtension(extension);
-
+ const contentType = this._fileSystem.contentType(filePath);
const uiSourceCode = this.createUISourceCode(this._fileSystemBaseURL + filePath, contentType);
this.addUISourceCode(uiSourceCode);
return uiSourceCode;
@@ -569,7 +550,7 @@ Persistence.FileSystemWorkspaceBinding.FileSystem = class extends Workspace.Proj
return;
const uiSourceCode = this.uiSourceCodeForURL(path);
if (!uiSourceCode) {
- const contentType = Persistence.FileSystemWorkspaceBinding._contentTypeForExtension(this._extensionForPath(path));
+ const contentType = this._fileSystem.contentType(path);
this.addUISourceCode(this.createUISourceCode(path, contentType));
return;
}
@@ -577,6 +558,14 @@ Persistence.FileSystemWorkspaceBinding.FileSystem = class extends Workspace.Proj
uiSourceCode.checkContentUpdated();
}
+ /**
+ * @param {string} url
+ * @return {string}
+ */
+ tooltipForURL(url) {
+ return this._fileSystem.tooltipForURL(url);
+ }
+
dispose() {
this.removeProject();
}
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/persistence/IsolatedFileSystem.js b/chromium/third_party/blink/renderer/devtools/front_end/persistence/IsolatedFileSystem.js
index 40ecbcf75d8..5756f749b99 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/persistence/IsolatedFileSystem.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/persistence/IsolatedFileSystem.js
@@ -27,11 +27,10 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-
/**
* @unrestricted
*/
-Persistence.IsolatedFileSystem = class {
+Persistence.IsolatedFileSystem = class extends Persistence.PlatformFileSystem {
/**
* @param {!Persistence.IsolatedFileSystemManager} manager
* @param {string} path
@@ -40,11 +39,10 @@ Persistence.IsolatedFileSystem = class {
* @param {string} type
*/
constructor(manager, path, embedderPath, domFileSystem, type) {
+ super(path, type);
this._manager = manager;
- this._path = path;
this._embedderPath = embedderPath;
this._domFileSystem = domFileSystem;
- this._type = type;
this._excludedFoldersSetting = Common.settings.createLocalSetting('workspaceExcludedFolders', {});
/** @type {!Set<string>} */
this._excludedFolders = new Set(this._excludedFoldersSetting.get()[path] || []);
@@ -100,6 +98,7 @@ Persistence.IsolatedFileSystem = class {
}
/**
+ * @override
* @param {string} path
* @return {!Promise<?{modificationTime: !Date, size: number}>}
*/
@@ -127,6 +126,7 @@ Persistence.IsolatedFileSystem = class {
}
/**
+ * @override
* @return {!Array<string>}
*/
initialFilePaths() {
@@ -134,6 +134,7 @@ Persistence.IsolatedFileSystem = class {
}
/**
+ * @override
* @return {!Array<string>}
*/
initialGitFolders() {
@@ -141,13 +142,7 @@ Persistence.IsolatedFileSystem = class {
}
/**
- * @return {string}
- */
- path() {
- return this._path;
- }
-
- /**
+ * @override
* @return {string}
*/
embedderPath() {
@@ -155,13 +150,6 @@ Persistence.IsolatedFileSystem = class {
}
/**
- * @return {string}
- */
- type() {
- return this._type;
- }
-
- /**
* @return {!Promise}
*/
_initializeFilePaths() {
@@ -191,7 +179,7 @@ Persistence.IsolatedFileSystem = class {
}
if (this.isFileExcluded(entry.fullPath + '/')) {
this._excludedEmbedderFolders.push(
- Common.ParsedURL.urlToPlatformPath(this._path + entry.fullPath, Host.isWin()));
+ Common.ParsedURL.urlToPlatformPath(this.path() + entry.fullPath, Host.isWin()));
continue;
}
++pendingRequests;
@@ -239,6 +227,7 @@ Persistence.IsolatedFileSystem = class {
}
/**
+ * @override
* @param {string} path
* @param {?string} name
* @return {!Promise<?string>}
@@ -268,7 +257,7 @@ Persistence.IsolatedFileSystem = class {
}
const errorMessage = Persistence.IsolatedFileSystem.errorMessage(error);
console.error(
- errorMessage + ' when testing if file exists \'' + (this._path + '/' + path + '/' + nameCandidate) +
+ errorMessage + ' when testing if file exists \'' + (this.path() + '/' + path + '/' + nameCandidate) +
'\'');
resolve(null);
});
@@ -277,6 +266,7 @@ Persistence.IsolatedFileSystem = class {
}
/**
+ * @override
* @param {string} path
* @return {!Promise<boolean>}
*/
@@ -306,12 +296,13 @@ Persistence.IsolatedFileSystem = class {
*/
function errorHandler(error) {
const errorMessage = Persistence.IsolatedFileSystem.errorMessage(error);
- console.error(errorMessage + ' when deleting file \'' + (this._path + '/' + path) + '\'');
+ console.error(errorMessage + ' when deleting file \'' + (this.path() + '/' + path) + '\'');
resolveCallback(false);
}
}
/**
+ * @override
* @param {string} path
* @return {!Promise<?Blob>}
*/
@@ -331,13 +322,14 @@ Persistence.IsolatedFileSystem = class {
}
const errorMessage = Persistence.IsolatedFileSystem.errorMessage(error);
- console.error(errorMessage + ' when getting content for file \'' + (this._path + '/' + path) + '\'');
+ console.error(errorMessage + ' when getting content for file \'' + (this.path() + '/' + path) + '\'');
resolve(null);
}
});
}
/**
+ * @override
* @param {string} path
* @param {function(?string,boolean)} callback
*/
@@ -381,6 +373,7 @@ Persistence.IsolatedFileSystem = class {
}
/**
+ * @override
* @param {string} path
* @param {string} content
* @param {boolean} isBase64
@@ -429,12 +422,13 @@ Persistence.IsolatedFileSystem = class {
*/
function errorHandler(error) {
const errorMessage = Persistence.IsolatedFileSystem.errorMessage(error);
- console.error(errorMessage + ' when setting content for file \'' + (this._path + '/' + path) + '\'');
+ console.error(errorMessage + ' when setting content for file \'' + (this.path() + '/' + path) + '\'');
callback();
}
}
/**
+ * @override
* @param {string} path
* @param {string} newName
* @param {function(boolean, string=)} callback
@@ -503,7 +497,7 @@ Persistence.IsolatedFileSystem = class {
*/
function errorHandler(error) {
const errorMessage = Persistence.IsolatedFileSystem.errorMessage(error);
- console.error(errorMessage + ' when renaming file \'' + (this._path + '/' + path) + '\' to \'' + newName + '\'');
+ console.error(errorMessage + ' when renaming file \'' + (this.path() + '/' + path) + '\' to \'' + newName + '\'');
callback(false);
}
}
@@ -562,11 +556,12 @@ Persistence.IsolatedFileSystem = class {
_saveExcludedFolders() {
const settingValue = this._excludedFoldersSetting.get();
- settingValue[this._path] = this._excludedFolders.valuesArray();
+ settingValue[this.path()] = this._excludedFolders.valuesArray();
this._excludedFoldersSetting.set(settingValue);
}
/**
+ * @override
* @param {string} path
*/
addExcludedFolder(path) {
@@ -576,6 +571,7 @@ Persistence.IsolatedFileSystem = class {
}
/**
+ * @override
* @param {string} path
*/
removeExcludedFolder(path) {
@@ -584,13 +580,17 @@ Persistence.IsolatedFileSystem = class {
this._manager.dispatchEventToListeners(Persistence.IsolatedFileSystemManager.Events.ExcludedFolderRemoved, path);
}
+ /**
+ * @override
+ */
fileSystemRemoved() {
const settingValue = this._excludedFoldersSetting.get();
- delete settingValue[this._path];
+ delete settingValue[this.path()];
this._excludedFoldersSetting.set(settingValue);
}
/**
+ * @override
* @param {string} folderPath
* @return {boolean}
*/
@@ -602,6 +602,7 @@ Persistence.IsolatedFileSystem = class {
}
/**
+ * @override
* @return {!Set<string>}
*/
excludedFolders() {
@@ -609,6 +610,7 @@ Persistence.IsolatedFileSystem = class {
}
/**
+ * @override
* @param {string} query
* @param {!Common.Progress} progress
* @return {!Promise<!Array<string>>}
@@ -629,6 +631,7 @@ Persistence.IsolatedFileSystem = class {
}
/**
+ * @override
* @param {!Common.Progress} progress
*/
indexContent(progress) {
@@ -636,8 +639,70 @@ Persistence.IsolatedFileSystem = class {
const requestId = this._manager.registerProgress(progress);
InspectorFrontendHost.indexPath(requestId, this._embedderPath, JSON.stringify(this._excludedEmbedderFolders));
}
+
+ /**
+ * @override
+ * @param {string} path
+ * @return {string}
+ */
+ mimeFromPath(path) {
+ return Common.ResourceType.mimeFromURL(path) || 'text/plain';
+ }
+
+ /**
+ * @override
+ * @param {string} path
+ * @return {boolean}
+ */
+ canExcludeFolder(path) {
+ return !!path && this.type() !== 'overrides';
+ }
+
+ /**
+ * @override
+ * @param {string} path
+ * @return {!Common.ResourceType}
+ */
+ contentType(path) {
+ const extension = Common.ParsedURL.extractExtension(path);
+ if (Persistence.IsolatedFileSystem._styleSheetExtensions.has(extension))
+ return Common.resourceTypes.Stylesheet;
+ if (Persistence.IsolatedFileSystem._documentExtensions.has(extension))
+ return Common.resourceTypes.Document;
+ if (Persistence.IsolatedFileSystem.ImageExtensions.has(extension))
+ return Common.resourceTypes.Image;
+ if (Persistence.IsolatedFileSystem._scriptExtensions.has(extension))
+ return Common.resourceTypes.Script;
+ return Persistence.IsolatedFileSystem.BinaryExtensions.has(extension) ? Common.resourceTypes.Other :
+ Common.resourceTypes.Document;
+ }
+
+ /**
+ * @override
+ * @param {string} url
+ * @return {string}
+ */
+ tooltipForURL(url) {
+ const path = Common.ParsedURL.urlToPlatformPath(url, Host.isWin()).trimMiddle(150);
+ return ls`Linked to ${path}`;
+ }
+
+ /**
+ * @override
+ * @return {boolean}
+ */
+ supportsAutomapping() {
+ return this.type() !== 'overrides';
+ }
};
+Persistence.IsolatedFileSystem._styleSheetExtensions = new Set(['css', 'scss', 'sass', 'less']);
+Persistence.IsolatedFileSystem._documentExtensions = new Set(['htm', 'html', 'asp', 'aspx', 'phtml', 'jsp']);
+Persistence.IsolatedFileSystem._scriptExtensions = new Set([
+ 'asp', 'aspx', 'c', 'cc', 'cljs', 'coffee', 'cpp', 'cs', 'dart', 'java', 'js',
+ 'jsp', 'jsx', 'h', 'm', 'mjs', 'mm', 'py', 'sh', 'ts', 'tsx', 'ls'
+]);
+
Persistence.IsolatedFileSystem.ImageExtensions =
new Set(['jpeg', 'jpg', 'svg', 'gif', 'webp', 'png', 'ico', 'tiff', 'tif', 'bmp']);
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/persistence/IsolatedFileSystemManager.js b/chromium/third_party/blink/renderer/devtools/front_end/persistence/IsolatedFileSystemManager.js
index 4cc6233dd8f..3ea1dc843db 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/persistence/IsolatedFileSystemManager.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/persistence/IsolatedFileSystemManager.js
@@ -35,7 +35,7 @@ Persistence.IsolatedFileSystemManager = class extends Common.Object {
constructor() {
super();
- /** @type {!Map<string, !Persistence.IsolatedFileSystem>} */
+ /** @type {!Map<string, !Persistence.PlatformFileSystem>} */
this._fileSystems = new Map();
/** @type {!Map<number, function(!Array.<string>)>} */
this._callbacks = new Map();
@@ -107,7 +107,7 @@ Persistence.IsolatedFileSystemManager = class extends Common.Object {
}
/**
- * @param {!Persistence.IsolatedFileSystem} fileSystem
+ * @param {!Persistence.PlatformFileSystem} fileSystem
*/
removeFileSystem(fileSystem) {
InspectorFrontendHost.removeFileSystem(fileSystem.embedderPath());
@@ -133,7 +133,7 @@ Persistence.IsolatedFileSystemManager = class extends Common.Object {
return promise.then(storeFileSystem.bind(this));
/**
- * @param {?Persistence.IsolatedFileSystem} fileSystem
+ * @param {?Persistence.PlatformFileSystem} fileSystem
* @this {Persistence.IsolatedFileSystemManager}
*/
function storeFileSystem(fileSystem) {
@@ -147,6 +147,15 @@ Persistence.IsolatedFileSystemManager = class extends Common.Object {
}
/**
+ * @param {string} fileSystemURL
+ * @param {!Persistence.PlatformFileSystem} fileSystem
+ */
+ addPlatformFileSystem(fileSystemURL, fileSystem) {
+ this._fileSystems.set(fileSystemURL, fileSystem);
+ this.dispatchEventToListeners(Persistence.IsolatedFileSystemManager.Events.FileSystemAdded, fileSystem);
+ }
+
+ /**
* @param {!Common.Event} event
*/
async _onFileSystemAdded(event) {
@@ -224,7 +233,7 @@ Persistence.IsolatedFileSystemManager = class extends Common.Object {
/**
* @param {string} fileSystemPath
- * @return {?Persistence.IsolatedFileSystem}
+ * @return {?Persistence.PlatformFileSystem}
*/
fileSystem(fileSystemPath) {
return this._fileSystems.get(fileSystemPath) || null;
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/persistence/Persistence.js b/chromium/third_party/blink/renderer/devtools/front_end/persistence/Persistence.js
index 98a938efdb3..14accb96faf 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/persistence/Persistence.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/persistence/Persistence.js
@@ -275,7 +275,8 @@ Persistence.Persistence = class extends Common.Object {
* @param {!Workspace.UISourceCode} to
*/
_moveBreakpoints(from, to) {
- const breakpoints = this._breakpointManager.breakpointsForUISourceCode(from);
+ const breakpoints = this._breakpointManager.breakpointLocationsForUISourceCode(from).map(
+ breakpointLocation => breakpointLocation.breakpoint);
for (const breakpoint of breakpoints) {
breakpoint.remove(false /* keepInStorage */);
this._breakpointManager.setBreakpoint(
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/persistence/PersistenceUtils.js b/chromium/third_party/blink/renderer/devtools/front_end/persistence/PersistenceUtils.js
index 2db1e914195..ec923cf2a42 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/persistence/PersistenceUtils.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/persistence/PersistenceUtils.js
@@ -11,10 +11,8 @@ Persistence.PersistenceUtils = class {
const binding = Persistence.persistence.binding(uiSourceCode);
if (!binding)
return '';
- if (uiSourceCode === binding.network) {
- const path = Common.ParsedURL.urlToPlatformPath(binding.fileSystem.url(), Host.isWin()).trimMiddle(150);
- return ls`Linked to ${path}`;
- }
+ if (uiSourceCode === binding.network)
+ return Persistence.FileSystemWorkspaceBinding.tooltipForUISourceCode(binding.fileSystem);
if (binding.network.contentType().isFromSourceMap())
return Common.UIString('Linked to source map: %s', binding.network.url().trimMiddle(150));
return Common.UIString('Linked to %s', binding.network.url().trimMiddle(150));
@@ -27,6 +25,8 @@ Persistence.PersistenceUtils = class {
static iconForUISourceCode(uiSourceCode) {
const binding = Persistence.persistence.binding(uiSourceCode);
if (binding) {
+ if (!binding.fileSystem.url().startsWith('file://'))
+ return null;
const icon = UI.Icon.create('mediumicon-file-sync');
icon.title = Persistence.PersistenceUtils.tooltipForUISourceCode(binding.network);
// TODO(allada) This will not work properly with dark theme.
@@ -34,8 +34,10 @@ Persistence.PersistenceUtils = class {
icon.style.filter = 'hue-rotate(160deg)';
return icon;
}
- if (uiSourceCode.project().type() !== Workspace.projectTypes.FileSystem)
+ if (uiSourceCode.project().type() !== Workspace.projectTypes.FileSystem ||
+ !uiSourceCode.url().startsWith('file://'))
return null;
+
const icon = UI.Icon.create('mediumicon-file');
icon.title = Persistence.PersistenceUtils.tooltipForUISourceCode(uiSourceCode);
return icon;
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/persistence/PlatformFileSystem.js b/chromium/third_party/blink/renderer/devtools/front_end/persistence/PlatformFileSystem.js
new file mode 100644
index 00000000000..e37a4e54bee
--- /dev/null
+++ b/chromium/third_party/blink/renderer/devtools/front_end/persistence/PlatformFileSystem.js
@@ -0,0 +1,194 @@
+// 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.
+
+Persistence.PlatformFileSystem = class {
+ /**
+ * @param {string} path
+ * @param {string} type
+ */
+ constructor(path, type) {
+ this._path = path;
+ this._type = type;
+ }
+
+ /**
+ * @param {string} path
+ * @return {!Promise<?{modificationTime: !Date, size: number}>}
+ */
+ getMetadata(path) {
+ return Promise.resolve(/** @type ?{modificationTime: !Date, size: number} */ (null));
+ }
+
+ /**
+ * @return {!Array<string>}
+ */
+ initialFilePaths() {
+ return [];
+ }
+
+ /**
+ * @return {!Array<string>}
+ */
+ initialGitFolders() {
+ return [];
+ }
+
+ /**
+ * @return {string}
+ */
+ path() {
+ return this._path;
+ }
+
+ /**
+ * @return {string}
+ */
+ embedderPath() {
+ throw new Error('Not implemented');
+ }
+
+ /**
+ * @return {string}
+ */
+ type() {
+ // TODO(kozyatinskiy): remove type, overrides should implement this interface.
+ return this._type;
+ }
+
+ /**
+ * @param {string} path
+ * @param {?string} name
+ * @return {!Promise<?string>}
+ */
+ async createFile(path, name) {
+ return Promise.resolve(null);
+ }
+
+ /**
+ * @param {string} path
+ * @return {!Promise<boolean>}
+ */
+ deleteFile(path) {
+ return Promise.resolve(false);
+ }
+
+ /**
+ * @param {string} path
+ * @return {!Promise<?Blob>}
+ */
+ requestFileBlob(path) {
+ return Promise.resolve(/** @type {?Blob} */ (null));
+ }
+
+ /**
+ * @param {string} path
+ * @param {function(?string,boolean)} callback
+ */
+ requestFileContent(path, callback) {
+ callback(null, false);
+ }
+
+ /**
+ * @param {string} path
+ * @param {string} content
+ * @param {boolean} isBase64
+ */
+ setFileContent(path, content, isBase64) {
+ throw new Error('Not implemented');
+ }
+
+ /**
+ * @param {string} path
+ * @param {string} newName
+ * @param {function(boolean, string=)} callback
+ */
+ renameFile(path, newName, callback) {
+ callback(false);
+ }
+
+ /**
+ * @param {string} path
+ */
+ addExcludedFolder(path) {
+ }
+
+ /**
+ * @param {string} path
+ */
+ removeExcludedFolder(path) {
+ }
+
+ fileSystemRemoved() {
+ }
+
+ /**
+ * @param {string} folderPath
+ * @return {boolean}
+ */
+ isFileExcluded(folderPath) {
+ return false;
+ }
+
+ /**
+ * @return {!Set<string>}
+ */
+ excludedFolders() {
+ return new Set();
+ }
+
+ /**
+ * @param {string} query
+ * @param {!Common.Progress} progress
+ * @return {!Promise<!Array<string>>}
+ */
+ searchInPath(query, progress) {
+ return Promise.resolve([]);
+ }
+
+ /**
+ * @param {!Common.Progress} progress
+ */
+ indexContent(progress) {
+ setImmediate(() => progress.done());
+ }
+
+ /**
+ * @param {string} path
+ * @return {string}
+ */
+ mimeFromPath(path) {
+ throw new Error('Not implemented');
+ }
+
+ /**
+ * @param {string} path
+ * @return {boolean}
+ */
+ canExcludeFolder(path) {
+ return false;
+ }
+
+ /**
+ * @param {string} path
+ * @return {!Common.ResourceType}
+ */
+ contentType(path) {
+ throw new Error('Not implemented');
+ }
+
+ /**
+ * @param {string} url
+ * @return {string}
+ */
+ tooltipForURL(url) {
+ throw new Error('Not implemented');
+ }
+
+ /**
+ * @return {boolean}
+ */
+ supportsAutomapping() {
+ throw new Error('Not implemented');
+ }
+};
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/persistence/WorkspaceSettingsTab.js b/chromium/third_party/blink/renderer/devtools/front_end/persistence/WorkspaceSettingsTab.js
index 7cb2637574d..59308118e36 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/persistence/WorkspaceSettingsTab.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/persistence/WorkspaceSettingsTab.js
@@ -15,21 +15,17 @@ Persistence.WorkspaceSettingsTab = class extends UI.VBox {
Persistence.isolatedFileSystemManager.addEventListener(
Persistence.IsolatedFileSystemManager.Events.FileSystemAdded,
- event => this._fileSystemAdded(/** @type {!Persistence.IsolatedFileSystem} */ (event.data)), this);
+ event => this._fileSystemAdded(/** @type {!Persistence.PlatformFileSystem} */ (event.data)), this);
Persistence.isolatedFileSystemManager.addEventListener(
Persistence.IsolatedFileSystemManager.Events.FileSystemRemoved,
- event => this._fileSystemRemoved(/** @type {!Persistence.IsolatedFileSystem} */ (event.data)), this);
+ event => this._fileSystemRemoved(/** @type {!Persistence.PlatformFileSystem} */ (event.data)), this);
const folderExcludePatternInput = this._createFolderExcludePatternInput();
folderExcludePatternInput.classList.add('folder-exclude-pattern');
this.containerElement.appendChild(folderExcludePatternInput);
const div = this.containerElement.createChild('div', 'settings-info-message');
- div.createTextChild(Common.UIString('Mappings are inferred automatically. Please '));
- div.appendChild(UI.XLink.create(
- 'https://bugs.chromium.org/p/chromium/issues/entry?template=Defect%20report%20from%20user&components=Platform%3EDevTools%3EAuthoring&comment=DevTools%20failed%20to%20link%20network%20resource%20to%20filesystem.%0A%0APlatform%3A%20%3CLinux%2FWin%2FMac%3E%0AChrome%20version%3A%20%3Cyour%20chrome%20version%3E%0A%0AWhat%20are%20the%20details%20of%20your%20project%3F%0A-%20Source%20code%20(if%20any)%3A%20http%3A%2F%2Fgithub.com%2Fexample%2Fexample%0A-%20Build%20System%3A%20gulp%2Fgrunt%2Fwebpack%2Frollup%2F...%0A-%20HTTP%20server%3A%20node%20HTTP%2Fnginx%2Fapache...%0A%0AAssets%20failed%20to%20link%20(or%20incorrectly%20linked)%3A%0A1.%0A2.%0A3.%0A%0AIf%20possible%2C%20please%20attach%20a%20screenshot%20of%20network%20sources%20navigator%20which%20should%0Ashow%20which%20resources%20failed%20to%20map',
- Common.UIString('report')));
- div.createTextChild(Common.UIString(' any bugs.'));
+ div.createTextChild(Common.UIString('Mappings are inferred automatically.'));
this._fileSystemsListContainer = this.containerElement.createChild('div', '');
@@ -79,7 +75,7 @@ Persistence.WorkspaceSettingsTab = class extends UI.VBox {
}
/**
- * @param {!Persistence.IsolatedFileSystem} fileSystem
+ * @param {!Persistence.PlatformFileSystem} fileSystem
*/
_addItem(fileSystem) {
const networkPersistenceProject = Persistence.networkPersistenceManager.project();
@@ -98,7 +94,7 @@ Persistence.WorkspaceSettingsTab = class extends UI.VBox {
}
/**
- * @param {!Persistence.IsolatedFileSystem} fileSystem
+ * @param {!Persistence.PlatformFileSystem} fileSystem
* @return {!Element}
*/
_renderFileSystem(fileSystem) {
@@ -124,7 +120,7 @@ Persistence.WorkspaceSettingsTab = class extends UI.VBox {
}
/**
- * @param {!Persistence.IsolatedFileSystem} fileSystem
+ * @param {!Persistence.PlatformFileSystem} fileSystem
*/
_removeFileSystemClicked(fileSystem) {
Persistence.isolatedFileSystemManager.removeFileSystem(fileSystem);
@@ -135,14 +131,14 @@ Persistence.WorkspaceSettingsTab = class extends UI.VBox {
}
/**
- * @param {!Persistence.IsolatedFileSystem} fileSystem
+ * @param {!Persistence.PlatformFileSystem} fileSystem
*/
_fileSystemAdded(fileSystem) {
this._addItem(fileSystem);
}
/**
- * @param {!Persistence.IsolatedFileSystem} fileSystem
+ * @param {!Persistence.PlatformFileSystem} fileSystem
*/
_fileSystemRemoved(fileSystem) {
const mappingView = this._mappingViewByPath.get(fileSystem.path());
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/persistence/module.json b/chromium/third_party/blink/renderer/devtools/front_end/persistence/module.json
index 254391aed64..9b3b1c9467c 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/persistence/module.json
+++ b/chromium/third_party/blink/renderer/devtools/front_end/persistence/module.json
@@ -44,6 +44,7 @@
}
],
"scripts": [
+ "PlatformFileSystem.js",
"IsolatedFileSystem.js",
"IsolatedFileSystemManager.js",
"FileSystemWorkspaceBinding.js",
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapProfileView.js b/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapProfileView.js
index 4662fcb6404..78d5314fa80 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapProfileView.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapProfileView.js
@@ -55,10 +55,30 @@ Profiler.HeapProfileView = class extends Profiler.ProfileView {
populateTextView(view) {
const guides = '+!:|';
let text = `Sampling memory profile.\n\nDate/Time: ${new Date()}\n` +
- `Report Version: 7\nNode weight: 1 KiB\n----\n\nCall graph:\n`;
+ `Report Version: 7\n` +
+ `App Version: ${/Chrom\S*/.exec(navigator.appVersion)[0] || 'Unknown'}\n` +
+ `Node Weight: 1 KiB\n` +
+ `Total Size: ${Math.round(this.profile.root.total / 1024)} KiB\n` +
+ `----\n\nCall graph:\n`;
const sortedChildren = this.profile.root.children.sort((a, b) => b.total - a.total);
+ const modules = this.profile.modules.map(
+ m => Object.assign({address: BigInt(m.baseAddress), endAddress: BigInt(m.baseAddress) + BigInt(m.size)}, m));
+ modules.sort((m1, m2) => m1.address > m2.address ? 1 : m1.address < m2.address ? -1 : 0);
for (const child of sortedChildren)
printTree(' ', child !== sortedChildren.peekLast(), child);
+
+ text += '\nBinary Images:\n';
+ for (const module of modules) {
+ const fileName = /[^/\\]*$/.exec(module.name)[0];
+ const version = '1.0';
+ const formattedUuid = module.uuid.includes('-') ?
+ module.uuid :
+ module.uuid.replace(/(.{8})(.{4})(.{4})(.{4})(.{12}).*/, '$1-$2-$3-$4-$5');
+ text += `${('0x' + module.address.toString(16)).padStart(18)} - `;
+ text += `${('0x' + (module.endAddress - BigInt(1)).toString(16)).padStart(18)}`;
+ text += ` ${fileName} (${version}) <${formattedUuid}> ${module.name}\n`;
+ }
+
view.contentElement.createChild('pre', 'profile-text-view monospace').textContent = text;
/**
@@ -67,10 +87,27 @@ Profiler.HeapProfileView = class extends Profiler.ProfileView {
* @param {!SDK.ProfileNode} node
*/
function printTree(padding, drawGuide, node) {
- const isAddress = node.functionName.startsWith('0x');
- const functionName = isAddress ? '???' : node.functionName;
- const address = isAddress ? node.functionName : '???';
- text += `${padding}${Math.round(node.total / 1024)} ${functionName} [${address}]\n`;
+ const addressText = /0x[0-9a-f]*|[0-9]*/.exec(node.functionName)[0] || '';
+ let module;
+ if (addressText) {
+ const address = BigInt(addressText);
+ const pos = modules.upperBound(address, (address, module) => address - module.address);
+ if (pos > 0 && address < modules[pos - 1].endAddress)
+ module = modules[pos - 1];
+ }
+ const functionName =
+ (addressText ? node.functionName.substr(addressText.length + 1) : node.functionName) || '???';
+ text += `${padding}${Math.round(node.total / 1024)} ${functionName} `;
+ if (module) {
+ const fileName = /[^/\\]*$/.exec(module.name);
+ if (fileName)
+ text += `(in ${fileName}) `;
+ const offset = BigInt(addressText) - module.address;
+ text += `load address ${module.baseAddress} + 0x${offset.toString(16)} `;
+ }
+ if (addressText)
+ text += `[${addressText}]`;
+ text += '\n';
const guideChar = drawGuide ? guides[padding.length / 2 % guides.length] : ' ';
const nextPadding = padding + guideChar + ' ';
const sortedChildren = node.children.sort((a, b) => b.total - a.total);
@@ -351,8 +388,8 @@ Profiler.SamplingNativeHeapSnapshotBrowserType = class extends Profiler.Sampling
* @param {!SDK.HeapProfilerModel} heapProfilerModel
* @return {!Promise<!Protocol.HeapProfiler.SamplingHeapProfile>}
*/
- _takeNativeSnapshot(heapProfilerModel) {
- return heapProfilerModel.takeNativeBrowserSnapshot();
+ async _takeNativeSnapshot(heapProfilerModel) {
+ return await heapProfilerModel.takeNativeBrowserSnapshot();
}
};
@@ -442,6 +479,7 @@ Profiler.SamplingHeapProfileModel = class extends SDK.ProfileTreeModel {
constructor(profile) {
super();
this.initialize(translateProfileTree(profile.head));
+ this.modules = profile.modules || [];
/**
* @param {!Protocol.HeapProfiler.SamplingHeapProfileNode} root
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotGridNodes.js b/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotGridNodes.js
index a4b53344b8f..584e5791cbd 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotGridNodes.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotGridNodes.js
@@ -584,11 +584,9 @@ Profiler.HeapSnapshotGenericObjectNode = class extends Profiler.HeapSnapshotGrid
* @param {!Element} div
*/
async _appendSourceLocation(div) {
- if (this._type !== 'closure')
- return;
const linkContainer = UI.html`<span class="heap-object-source-link" />`;
div.appendChild(linkContainer);
- const link = await this._dataGrid.dataDisplayDelegate().linkifyObject(String(this.snapshotNodeId));
+ const link = await this._dataGrid.dataDisplayDelegate().linkifyObject(this.snapshotNodeIndex);
if (link)
linkContainer.appendChild(link);
else
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotProxy.js b/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotProxy.js
index 98c2f67a071..d6757820067 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotProxy.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotProxy.js
@@ -451,6 +451,14 @@ Profiler.HeapSnapshotProxy = class extends Profiler.HeapSnapshotProxyObject {
}
/**
+ * @param {number} nodeIndex
+ * @return {!Promise<?HeapSnapshotModel.Location>}
+ */
+ getLocation(nodeIndex) {
+ return this._callMethodPromise('getLocation', nodeIndex);
+ }
+
+ /**
* @return {!Promise.<?HeapSnapshotModel.Samples>}
*/
getSamples() {
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotView.js b/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotView.js
index 57bf5fb754f..84fd1dc807c 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotView.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotView.js
@@ -204,18 +204,22 @@ Profiler.HeapSnapshotView = class extends UI.SimpleView {
/**
* @override
- * @param {!Protocol.HeapProfiler.HeapSnapshotObjectId} snapshotObjectId
+ * @param {number} nodeIndex
* @return {!Promise<?Element>}
*/
- async linkifyObject(snapshotObjectId) {
+ async linkifyObject(nodeIndex) {
const heapProfilerModel = this._profile.heapProfilerModel();
- const remoteObject = await heapProfilerModel.objectForSnapshotObjectId(String(snapshotObjectId), 'link');
- if (!remoteObject || remoteObject.type !== 'function')
+ // heapProfilerModel is null if snapshot was loaded from file
+ if (!heapProfilerModel)
return null;
- const functionDetails = await remoteObject.debuggerModel().functionDetailsPromise(remoteObject);
- if (!functionDetails || !functionDetails.location)
+ const location = await this._profile.getLocation(nodeIndex);
+ if (!location)
+ return null;
+ const debuggerModel = heapProfilerModel.runtimeModel().debuggerModel();
+ const rawLocation = debuggerModel.createRawLocationByScriptId(
+ String(location.scriptId), location.lineNumber, location.columnNumber);
+ if (!rawLocation)
return null;
- const rawLocation = functionDetails.location;
const sourceURL = rawLocation.script() && rawLocation.script().sourceURL;
return sourceURL && this._linkifier ? this._linkifier.linkifyRawLocation(rawLocation, sourceURL) : null;
}
@@ -1373,6 +1377,14 @@ Profiler.HeapProfileHeader = class extends Profiler.ProfileHeader {
}
/**
+ * @param {number} nodeIndex
+ * @return {!Promise<?HeapSnapshotModel.Location>}
+ */
+ getLocation(nodeIndex) {
+ return this._snapshotProxy.getLocation(nodeIndex);
+ }
+
+ /**
* @override
* @param {!Profiler.ProfileType.DataDisplayDelegate} dataDisplayDelegate
* @return {!Profiler.ProfileSidebarTreeElement}
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfileDataGrid.js b/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfileDataGrid.js
index 8ac82b605c9..646b521634c 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfileDataGrid.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfileDataGrid.js
@@ -35,6 +35,10 @@ Profiler.ProfileDataGridNode = class extends DataGrid.DataGridNode {
constructor(profileNode, owningTree, hasChildren) {
super(null, hasChildren);
+ this._searchMatchedSelfColumn = false;
+ this._searchMatchedTotalColumn = false;
+ this._searchMatchedFunctionColumn = false;
+
this.profileNode = profileNode;
this.tree = owningTree;
/** @type {!Map<string, !Profiler.ProfileDataGridNode>} */
@@ -476,9 +480,9 @@ Profiler.ProfileDataGridTree = class {
* @return {boolean}
*/
function matchesQuery(profileDataGridNode) {
- delete profileDataGridNode._searchMatchedSelfColumn;
- delete profileDataGridNode._searchMatchedTotalColumn;
- delete profileDataGridNode._searchMatchedFunctionColumn;
+ profileDataGridNode._searchMatchedSelfColumn = false;
+ profileDataGridNode._searchMatchedTotalColumn = false;
+ profileDataGridNode._searchMatchedFunctionColumn = false;
if (percentUnits) {
if (lessThan) {
@@ -565,9 +569,9 @@ Profiler.ProfileDataGridTree = class {
if (this._searchResults) {
for (let i = 0; i < this._searchResults.length; ++i) {
const profileNode = this._searchResults[i].profileNode;
- delete profileNode._searchMatchedSelfColumn;
- delete profileNode._searchMatchedTotalColumn;
- delete profileNode._searchMatchedFunctionColumn;
+ profileNode._searchMatchedSelfColumn = false;
+ profileNode._searchMatchedTotalColumn = false;
+ profileNode._searchMatchedFunctionColumn = false;
profileNode.refresh();
}
}
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfileType.js b/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfileType.js
index 2058baa102f..da6ce76f096 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfileType.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfileType.js
@@ -247,8 +247,8 @@ Profiler.ProfileType.DataDisplayDelegate.prototype = {
showObject(snapshotObjectId, perspectiveName) {},
/**
- * @param {!Protocol.HeapProfiler.HeapSnapshotObjectId} snapshotObjectId
+ * @param {number} nodeIndex
* @return {!Promise<?Element>}
*/
- async linkifyObject(snapshotObjectId) {}
+ async linkifyObject(nodeIndex) {}
};
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfilesPanel.js b/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfilesPanel.js
index 25d33073763..d7d5ffe0aec 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfilesPanel.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/profiler/ProfilesPanel.js
@@ -384,10 +384,10 @@ Profiler.ProfilesPanel = class extends UI.PanelWithSidebar {
/**
* @override
- * @param {!Protocol.HeapProfiler.HeapSnapshotObjectId} snapshotObjectId
+ * @param {number} nodeIndex
* @return {!Promise<?Element>}
*/
- async linkifyObject(snapshotObjectId) {
+ async linkifyObject(nodeIndex) {
return null;
}
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/protocol/InspectorBackend.js b/chromium/third_party/blink/renderer/devtools/front_end/protocol/InspectorBackend.js
index b73d299c689..d4d9a4a6125 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/protocol/InspectorBackend.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/protocol/InspectorBackend.js
@@ -180,24 +180,39 @@ Protocol.InspectorBackend.DevToolsStubErrorCode = -32015;
Protocol.inspectorBackend = new Protocol.InspectorBackend();
/**
- * @interface
+ * @unrestricted
*/
-Protocol.InspectorBackend.Connection = function() {};
+Protocol.InspectorBackend.Connection = class {
+ /**
+ * @param {string} domain
+ * @param {!Protocol.InspectorBackend.Connection.MessageObject} messageObject
+ */
+ sendMessage(domain, messageObject) {
+ this.sendRawMessage(JSON.stringify(messageObject));
+ }
-Protocol.InspectorBackend.Connection.prototype = {
/**
* @param {string} message
*/
- sendMessage(message) {},
+ sendRawMessage(message) {}
/**
* @return {!Promise}
*/
- disconnect() {},
+ disconnect() {}
};
/**
* @typedef {!{
+ * id: number,
+ * method: string,
+ * params: (!Object|undefined)
+ * }}
+ */
+Protocol.InspectorBackend.Connection.MessageObject;
+
+/**
+ * @typedef {!{
* onMessage: function((!Object|string)),
* onDisconnect: function(string)
* }}
@@ -287,17 +302,16 @@ Protocol.TargetBase = class extends Common.Object {
messageObject.params = params;
const wrappedCallback = this._wrap(callback, domain, method);
- const message = JSON.stringify(messageObject);
if (Protocol.InspectorBackend.Options.dumpInspectorProtocolMessages)
- this._dumpProtocolMessage('frontend: ' + message, '[FE] ' + domain);
+ this._dumpProtocolMessage('frontend: ' + JSON.stringify(messageObject), '[FE] ' + domain);
if (this.hasEventListeners(Protocol.TargetBase.Events.MessageSent)) {
this.dispatchEventToListeners(
Protocol.TargetBase.Events.MessageSent,
{domain, method, params: JSON.parse(JSON.stringify(params)), id: messageId});
}
- this._connection.sendMessage(message);
+ this._connection.sendMessage(domain, messageObject);
++this._pendingResponsesCount;
this._callbacks[messageId] = wrappedCallback;
}
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/resources/ServiceWorkerCacheViews.js b/chromium/third_party/blink/renderer/devtools/front_end/resources/ServiceWorkerCacheViews.js
index 15f5494ddb2..642804df148 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/resources/ServiceWorkerCacheViews.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/resources/ServiceWorkerCacheViews.js
@@ -341,8 +341,6 @@ Resources.ServiceWorkerCacheView.DataGridNode = class extends DataGrid.DataGridN
this._path = Common.ParsedURL.extractPath(request.url());
if (!this._path)
this._path = request.url();
- if (this._path.length > 1 && this._path.startsWith('/'))
- this._path = this._path.substring(1);
this._request = request;
}
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sdk/CSSMetadata.js b/chromium/third_party/blink/renderer/devtools/front_end/sdk/CSSMetadata.js
index 70eae3ceac3..aa75a6a6674 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/sdk/CSSMetadata.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk/CSSMetadata.js
@@ -195,6 +195,11 @@ SDK.CSSMetadata = class {
const entry = SDK.CSSMetadata._propertyDataMap[propertyName] || SDK.CSSMetadata._propertyDataMap[unprefixedName];
if (entry && entry.values)
acceptedKeywords.pushAll(entry.values);
+ const commonKeywords = ['auto', 'none'];
+ for (const commonKeyword of commonKeywords) {
+ if (CSS.supports(propertyName, commonKeyword))
+ acceptedKeywords.push(commonKeyword);
+ }
if (this.isColorAwareProperty(propertyName)) {
acceptedKeywords.push('currentColor');
for (const color in Common.Color.Nicknames)
@@ -227,7 +232,7 @@ SDK.cssMetadata = function() {
SDK.CSSMetadata._distanceProperties = new Set([
'background-position', 'border-spacing', 'bottom', 'font-size', 'height', 'left', 'letter-spacing', 'max-height',
'max-width', 'min-height', 'min-width', 'right', 'text-indent', 'top', 'width', 'word-spacing', 'grid-row-gap',
- 'grid-column-gap'
+ 'grid-column-gap', 'row-gap'
]);
SDK.CSSMetadata._bezierAwareProperties = new Set([
@@ -291,18 +296,17 @@ SDK.CSSMetadata._colorAwareProperties = new Set([
]);
SDK.CSSMetadata._propertyDataMap = {
- 'table-layout': {values: ['auto', 'fixed']},
+ 'table-layout': {values: ['fixed']},
'visibility': {values: ['hidden', 'visible', 'collapse']},
'background-repeat': {values: ['repeat', 'repeat-x', 'repeat-y', 'no-repeat', 'space', 'round']},
- 'content': {values: ['none', 'normal', 'close-quote', 'no-close-quote', 'no-open-quote', 'open-quote']},
- 'list-style-image': {values: ['none']},
- 'clear': {values: ['none', 'left', 'right', 'both']},
- 'overflow-x': {values: ['hidden', 'auto', 'visible', 'overlay', 'scroll']},
+ 'content': {values: ['normal', 'close-quote', 'no-close-quote', 'no-open-quote', 'open-quote']},
+ 'clear': {values: ['left', 'right', 'both']},
+ 'overflow-x': {values: ['hidden', 'visible', 'overlay', 'scroll', '-webkit-paged-x', '-webkit-paged-y']},
'stroke-linejoin': {values: ['round', 'miter', 'bevel']},
'baseline-shift': {values: ['baseline', 'sub', 'super']},
'border-bottom-width': {values: ['medium', 'thick', 'thin']},
'margin-top-collapse': {values: ['collapse', 'separate', 'discard']},
- 'max-height': {values: ['none', 'min-content', 'max-content', '-webkit-fill-available', 'fit-content']},
+ 'max-height': {values: ['min-content', 'max-content', '-webkit-fill-available', 'fit-content']},
'box-orient': {
values: ['horizontal', 'vertical', 'inline-axis', 'block-axis'],
},
@@ -313,22 +317,21 @@ SDK.CSSMetadata._propertyDataMap = {
]
},
'border-left-width': {values: ['medium', 'thick', 'thin']},
- 'box-shadow': {values: ['inset', 'none']},
+ 'box-shadow': {values: ['inset']},
'-webkit-writing-mode': {values: ['horizontal-tb', 'vertical-rl', 'vertical-lr']},
'writing-mode':
{values: ['lr', 'rl', 'tb', 'lr-tb', 'rl-tb', 'tb-rl', 'horizontal-tb', 'vertical-rl', 'vertical-lr']},
'border-collapse': {values: ['collapse', 'separate']},
- 'page-break-inside': {values: ['auto', 'avoid']},
+ 'page-break-inside': {values: ['avoid']},
'border-top-width': {values: ['medium', 'thick', 'thin']},
- 'outline-style':
- {values: ['auto', 'none', 'inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double']},
+ 'outline-style': {values: ['inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double', 'hidden']},
'cursor': {
values: [
- 'none',
'copy',
- 'auto',
'crosshair',
'default',
+ 'grab',
+ 'grabbing',
'pointer',
'move',
'vertical-text',
@@ -365,19 +368,21 @@ SDK.CSSMetadata._propertyDataMap = {
]
},
'border-width': {values: ['medium', 'thick', 'thin']},
- 'border-style':
- {values: ['none', 'hidden', 'inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double']},
- 'size': {values: ['auto', 'a3', 'a4', 'a5', 'b4', 'b5', 'landscape', 'ledger', 'legal', 'letter', 'portrait']},
- 'background-size': {values: ['auto', 'contain', 'cover']},
+ 'border-style': {values: ['hidden', 'inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double']},
+ 'size': {values: ['a3', 'a4', 'a5', 'b4', 'b5', 'landscape', 'ledger', 'legal', 'letter', 'portrait']},
+ 'background-size': {values: ['contain', 'cover']},
'direction': {values: ['ltr', 'rtl']},
'enable-background': {values: ['accumulate', 'new']},
- 'float': {values: ['none', 'left', 'right']},
- 'overflow-y': {values: ['hidden', 'auto', 'visible', 'overlay', 'scroll', '-webkit-paged-x', '-webkit-paged-y']},
+ 'float': {values: ['left', 'right']},
+ 'overflow-y': {values: ['hidden', 'visible', 'overlay', 'scroll', '-webkit-paged-x', '-webkit-paged-y']},
'margin-bottom-collapse': {values: ['collapse', 'separate', 'discard']},
'box-reflect': {values: ['left', 'right', 'above', 'below']},
- 'overflow': {values: ['hidden', 'auto', 'visible', 'overlay', 'scroll', '-webkit-paged-x', '-webkit-paged-y']},
- 'contain': {values: ['none', 'strict', 'content', 'size', 'layout', 'style', 'paint']},
- 'text-rendering': {values: ['auto', 'optimizeSpeed', 'optimizeLegibility', 'geometricPrecision']},
+ 'overflow': {values: ['hidden', 'visible', 'overlay', 'scroll', '-webkit-paged-x', '-webkit-paged-y']},
+ 'overscroll-behavior': {values: ['contain']},
+ 'overscroll-behavior-x': {values: ['contain']},
+ 'overscroll-behavior-y': {values: ['contain']},
+ 'contain': {values: ['strict', 'content', 'size', 'layout', 'style', 'paint']},
+ 'text-rendering': {values: ['optimizeSpeed', 'optimizeLegibility', 'geometricPrecision']},
'text-align': {
values: [
'-webkit-auto', 'start', 'end', 'left', 'right', 'center', 'justify', '-webkit-left', '-webkit-right',
@@ -385,25 +390,23 @@ SDK.CSSMetadata._propertyDataMap = {
]
},
'list-style-position': {values: ['outside', 'inside']},
- 'margin-bottom': {values: ['auto']},
- 'color-interpolation': {values: ['auto', 'sRGB', 'linearRGB']},
+ 'color-interpolation': {values: ['sRGB', 'linearRGB']},
'background-origin': {values: ['border-box', 'content-box', 'padding-box']},
'word-wrap': {values: ['normal', 'break-word']},
'font-weight':
{values: ['normal', 'bold', 'bolder', 'lighter', '100', '200', '300', '400', '500', '600', '700', '800', '900']},
'margin-before-collapse': {values: ['collapse', 'separate', 'discard']},
- 'text-transform': {values: ['none', 'capitalize', 'uppercase', 'lowercase']},
+ 'text-transform': {values: ['capitalize', 'uppercase', 'lowercase']},
'border-right-style':
- {values: ['none', 'hidden', 'inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double']},
+ {values: ['hidden', 'inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double']},
'border-left-style':
- {values: ['none', 'hidden', 'inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double']},
- '-webkit-text-emphasis': {values: ['circle', 'filled', 'open', 'dot', 'double-circle', 'triangle', 'sesame', 'none']},
+ {values: ['hidden', 'inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double']},
+ '-webkit-text-emphasis': {values: ['circle', 'filled', 'open', 'dot', 'double-circle', 'triangle', 'sesame']},
'font-style': {values: ['italic', 'oblique', 'normal']},
- 'speak': {values: ['none', 'normal', 'spell-out', 'digits', 'literal-punctuation', 'no-punctuation']},
- 'color-rendering': {values: ['auto', 'optimizeSpeed', 'optimizeQuality']},
+ 'speak': {values: ['normal', 'spell-out', 'digits', 'literal-punctuation', 'no-punctuation']},
+ 'color-rendering': {values: ['optimizeSpeed', 'optimizeQuality']},
'list-style-type': {
values: [
- 'none',
'disc',
'circle',
'square',
@@ -461,14 +464,11 @@ SDK.CSSMetadata._propertyDataMap = {
'katakana-iroha'
]
},
- 'text-combine-upright': {values: ['none', 'all']},
- '-webkit-text-combine': {values: ['none', 'horizontal']},
+ 'text-combine-upright': {values: ['all']},
+ '-webkit-text-combine': {values: ['horizontal']},
'text-orientation': {values: ['mixed', 'upright', 'sideways', 'sideways-right']},
'outline': {
- values: [
- 'none', 'inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double', 'medium', 'auto', 'thick',
- 'thin'
- ]
+ values: ['inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', 'thin']
},
'font': {
values: [
@@ -518,13 +518,12 @@ SDK.CSSMetadata._propertyDataMap = {
},
'dominant-baseline': {
values: [
- 'middle', 'auto', 'central', 'text-before-edge', 'text-after-edge', 'ideographic', 'alphabetic', 'hanging',
+ 'middle', 'central', 'text-before-edge', 'text-after-edge', 'ideographic', 'alphabetic', 'hanging',
'mathematical', 'use-script', 'no-change', 'reset-size'
]
},
'display': {
values: [
- 'none',
'inline',
'block',
'flow-root',
@@ -550,55 +549,48 @@ SDK.CSSMetadata._propertyDataMap = {
]
},
'-webkit-text-emphasis-position': {values: ['over', 'under']},
- 'image-rendering': {values: ['auto', 'pixelated', '-webkit-optimize-contrast']},
+ 'image-rendering': {values: ['pixelated', '-webkit-optimize-contrast', 'optimizeSpeed', 'optimizeQuality']},
'alignment-baseline': {
values: [
- 'baseline', 'middle', 'auto', 'before-edge', 'after-edge', 'central', 'text-before-edge', 'text-after-edge',
+ 'baseline', 'middle', 'before-edge', 'after-edge', 'central', 'text-before-edge', 'text-after-edge',
'ideographic', 'alphabetic', 'hanging', 'mathematical'
]
},
'outline-width': {values: ['medium', 'thick', 'thin']},
'box-align': {values: ['baseline', 'center', 'stretch', 'start', 'end']},
'border-right-width': {values: ['medium', 'thick', 'thin']},
- 'border-top-style':
- {values: ['none', 'hidden', 'inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double']},
+ 'border-top-style': {values: ['hidden', 'inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double']},
'line-height': {values: ['normal']},
'text-overflow': {values: ['clip', 'ellipsis']},
'overflow-wrap': {values: ['normal', 'break-word']},
'box-direction': {values: ['normal', 'reverse']},
'margin-after-collapse': {values: ['collapse', 'separate', 'discard']},
- 'page-break-before': {values: ['left', 'right', 'auto', 'always', 'avoid']},
- 'border-image': {values: ['repeat', 'stretch', 'none', 'space', 'round']},
- 'text-decoration': {
- values: ['none', 'blink', 'line-through', 'overline', 'underline', 'wavy', 'double', 'solid', 'dashed', 'dotted']
- },
+ 'page-break-before': {values: ['left', 'right', 'always', 'avoid']},
+ 'border-image': {values: ['repeat', 'stretch', 'space', 'round']},
+ 'text-decoration':
+ {values: ['blink', 'line-through', 'overline', 'underline', 'wavy', 'double', 'solid', 'dashed', 'dotted']},
'position': {values: ['absolute', 'fixed', 'relative', 'static', 'sticky']},
'font-family':
{values: ['serif', 'sans-serif', 'cursive', 'fantasy', 'monospace', '-webkit-body', '-webkit-pictograph']},
- 'text-overflow-mode': {values: ['clip', 'ellipsis']},
'border-bottom-style':
- {values: ['none', 'hidden', 'inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double']},
+ {values: ['hidden', 'inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double']},
'unicode-bidi': {values: ['normal', 'bidi-override', 'embed', 'isolate', 'isolate-override', 'plaintext']},
'clip-rule': {values: ['nonzero', 'evenodd']},
- 'margin-left': {values: ['auto']},
- 'margin-top': {values: ['auto']},
'zoom': {values: ['normal']},
- 'max-width': {values: ['none', 'min-content', 'max-content', '-webkit-fill-available', 'fit-content']},
+ 'max-width': {values: ['min-content', 'max-content', '-webkit-fill-available', 'fit-content']},
'caption-side': {values: ['top', 'bottom']},
'empty-cells': {values: ['hide', 'show']},
'pointer-events': {
values: [
- 'none', 'all', 'auto', 'visible', 'visiblepainted', 'visiblefill', 'visiblestroke', 'painted', 'fill', 'stroke',
- 'bounding-box'
+ 'all', 'visible', 'visiblepainted', 'visiblefill', 'visiblestroke', 'painted', 'fill', 'stroke', 'bounding-box'
]
},
'letter-spacing': {values: ['normal']},
'background-clip': {values: ['border-box', 'content-box', 'padding-box']},
- '-webkit-font-smoothing': {values: ['none', 'auto', 'antialiased', 'subpixel-antialiased']},
+ '-webkit-font-smoothing': {values: ['antialiased', 'subpixel-antialiased']},
'border': {
values: [
- 'none', 'hidden', 'inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick',
- 'thin'
+ 'hidden', 'inset', 'groove', 'ridge', 'outset', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', 'thin'
]
},
'font-size': {
@@ -610,7 +602,6 @@ SDK.CSSMetadata._propertyDataMap = {
values: [
'small-caps',
'normal',
- 'none',
'common-ligatures',
'no-common-ligatures',
'discretionary-ligatures',
@@ -648,25 +639,19 @@ SDK.CSSMetadata._propertyDataMap = {
['baseline', 'middle', 'sub', 'super', 'text-top', 'text-bottom', 'top', 'bottom', '-webkit-baseline-middle']
},
'white-space': {values: ['normal', 'nowrap', 'pre', 'pre-line', 'pre-wrap']},
- 'page-break-after': {values: ['left', 'right', 'auto', 'always', 'avoid']},
- 'clip-path': {values: ['none']},
- 'margin': {values: ['auto']},
- 'margin-right': {values: ['auto']},
+ 'page-break-after': {values: ['left', 'right', 'always', 'avoid']},
'word-break': {values: ['normal', 'break-all', 'break-word', 'keep-all']},
'word-spacing': {values: ['normal']},
- '-webkit-text-emphasis-style':
- {values: ['circle', 'filled', 'open', 'dot', 'double-circle', 'triangle', 'sesame', 'none']},
+ '-webkit-text-emphasis-style': {values: ['circle', 'filled', 'open', 'dot', 'double-circle', 'triangle', 'sesame']},
'transform': {
values: [
- 'scale', 'scaleX', 'scaleY', 'scale3d', 'rotate', 'rotateX', 'rotateY',
- 'rotateZ', 'rotate3d', 'skew', 'skewX', 'skewY', 'translate', 'translateX',
- 'translateY', 'translateZ', 'translate3d', 'matrix', 'matrix3d', 'perspective', 'none'
+ 'scale', 'scaleX', 'scaleY', 'scale3d', 'rotate', 'rotateX', 'rotateY',
+ 'rotateZ', 'rotate3d', 'skew', 'skewX', 'skewY', 'translate', 'translateX',
+ 'translateY', 'translateZ', 'translate3d', 'matrix', 'matrix3d', 'perspective'
]
},
- 'image-resolution': {values: ['from-image', 'snap']},
'box-sizing': {values: ['content-box', 'border-box']},
- 'clip': {values: ['auto']},
- 'resize': {values: ['none', 'both', 'horizontal', 'vertical', 'auto']},
+ 'resize': {values: ['both', 'horizontal', 'vertical']},
'align-content': {
values: [
'normal', 'baseline', 'space-between', 'space-around', 'space-evenly', 'stretch', 'unsafe', 'safe', 'center',
@@ -694,36 +679,35 @@ SDK.CSSMetadata._propertyDataMap = {
'justify-items': {
values: [
'normal', 'stretch', 'baseline', 'unsafe', 'safe', 'center', 'start', 'end', 'self-start', 'self-end',
- 'flex-start', 'flex-end', 'left', 'right', 'legacy', 'auto'
+ 'flex-start', 'flex-end', 'left', 'right', 'legacy'
]
},
'place-items': {
values: [
- 'auto', 'normal', 'stretch', 'baseline', 'unsafe', 'safe', 'center', 'start', 'end', 'self-start', 'self-end',
+ 'normal', 'stretch', 'baseline', 'unsafe', 'safe', 'center', 'start', 'end', 'self-start', 'self-end',
'flex-start', 'flex-end', 'left', 'right'
]
},
'align-self': {
values: [
- 'auto', 'normal', 'stretch', 'baseline', 'unsafe', 'safe', 'center', 'start', 'end', 'self-start', 'self-end',
+ 'normal', 'stretch', 'baseline', 'unsafe', 'safe', 'center', 'start', 'end', 'self-start', 'self-end',
'flex-start', 'flex-end', 'left', 'right'
]
},
'justify-self': {
values: [
- 'auto', 'normal', 'stretch', 'baseline', 'unsafe', 'safe', 'center', 'start', 'end', 'self-start', 'self-end',
+ 'normal', 'stretch', 'baseline', 'unsafe', 'safe', 'center', 'start', 'end', 'self-start', 'self-end',
'flex-start', 'flex-end', 'left', 'right'
]
},
'place-self': {
values: [
- 'auto', 'normal', 'stretch', 'baseline', 'unsafe', 'safe', 'center', 'start', 'end', 'self-start', 'self-end',
+ 'normal', 'stretch', 'baseline', 'unsafe', 'safe', 'center', 'start', 'end', 'self-start', 'self-end',
'flex-start', 'flex-end', 'left', 'right'
]
},
'flex-direction': {values: ['row', 'row-reverse', 'column', 'column-reverse']},
'flex-wrap': {values: ['nowrap', 'wrap', 'wrap-reverse']},
- 'perspective': {values: ['none']},
'perspective-origin': {values: ['left', 'center', 'right', 'top', 'bottom']},
'transform-origin': {values: ['left', 'center', 'right', 'top', 'bottom']},
'transform-style': {values: ['flat', 'preserve-3d']},
@@ -741,30 +725,28 @@ SDK.CSSMetadata._propertyDataMap = {
},
'animation-direction': {values: ['normal', 'reverse', 'alternate', 'alternate-reverse']},
'animation-play-state': {values: ['running', 'paused']},
- 'animation-fill-mode': {values: ['none', 'forwards', 'backwards', 'both']},
+ 'animation-fill-mode': {values: ['forwards', 'backwards', 'both']},
'-webkit-backface-visibility': {values: ['visible', 'hidden']},
'-webkit-box-decoration-break': {values: ['slice', 'clone']},
'-webkit-column-break-after':
- {values: ['auto', 'always', 'avoid', 'left', 'right', 'page', 'column', 'avoid-page', 'avoid-column']},
+ {values: ['always', 'avoid', 'left', 'right', 'page', 'column', 'avoid-page', 'avoid-column']},
'-webkit-column-break-before':
- {values: ['auto', 'always', 'avoid', 'left', 'right', 'page', 'column', 'avoid-page', 'avoid-column']},
- '-webkit-column-break-inside': {values: ['auto', 'avoid', 'avoid-page', 'avoid-column']},
- '-webkit-column-span': {values: ['none', 'all']},
- '-webkit-column-count': {values: ['auto']},
+ {values: ['always', 'avoid', 'left', 'right', 'page', 'column', 'avoid-page', 'avoid-column']},
+ '-webkit-column-break-inside': {values: ['avoid', 'avoid-page', 'avoid-column']},
+ '-webkit-column-span': {values: ['all']},
'-webkit-column-gap': {values: ['normal']},
'filter': {
values: [
'url', 'blur', 'brightness', 'contrast', 'drop-shadow', 'grayscale', 'hue-rotate', 'invert', 'opacity',
- 'saturate', 'sepia', 'none'
+ 'saturate', 'sepia'
]
},
- 'line-break': {values: ['auto', 'loose', 'normal', 'strict', 'after-white-space']},
- 'user-select': {values: ['none', 'text', 'all', 'auto']},
+ 'line-break': {values: ['loose', 'normal', 'strict', 'after-white-space']},
+ 'user-select': {values: ['text', 'all']},
'-webkit-user-modify': {values: ['read-only', 'read-write', 'read-write-plaintext-only']},
- 'text-align-last': {values: ['auto', 'start', 'end', 'left', 'right', 'center', 'justify']},
- '-webkit-text-decoration-line': {values: ['none', 'underline', 'overline', 'line-through', 'blink']},
+ 'text-align-last': {values: ['start', 'end', 'left', 'right', 'center', 'justify']},
+ '-webkit-text-decoration-line': {values: ['underline', 'overline', 'line-through', 'blink']},
'-webkit-text-decoration-style': {values: ['solid', 'double', 'dotted', 'dashed', 'wavy']},
- '-webkit-text-decoration-skip': {values: ['none', 'objects', 'spaces', 'ink', 'edges', 'box-decoration']},
'mix-blend-mode': {
values: [
'normal', 'multiply', 'screen', 'overlay', 'darken', 'lighten', 'color-dodge', 'color-burn', 'hard-light',
@@ -777,35 +759,26 @@ SDK.CSSMetadata._propertyDataMap = {
'soft-light', 'difference', 'exclusion', 'hue', 'saturation', 'color', 'luminosity', 'unset'
]
},
- 'caret-color': {values: ['auto']},
- 'grid-template-columns': {values: ['none', 'auto', 'min-content', 'max-content']},
- 'grid-template-rows': {values: ['none', 'auto', 'min-content', 'max-content']},
- 'grid-template-areas': {values: ['none']},
- 'grid-template': {values: ['none']},
- 'grid-auto-columns': {values: ['auto', 'min-content', 'max-content']},
- 'grid-auto-rows': {values: ['auto', 'min-content', 'max-content']},
+ 'grid-template-columns': {values: ['min-content', 'max-content']},
+ 'grid-template-rows': {values: ['min-content', 'max-content']},
+ 'grid-auto-columns': {values: ['min-content', 'max-content']},
+ 'grid-auto-rows': {values: ['min-content', 'max-content']},
'grid-auto-flow': {values: ['row', 'column', 'dense']},
- 'grid': {values: ['none']},
- 'grid-row-start': {values: ['auto']},
- 'grid-column-start': {values: ['auto']},
- 'grid-row-end': {values: ['auto']},
- 'grid-column-end': {values: ['auto']},
- 'grid-row': {values: ['auto']},
- 'grid-column': {values: ['auto']},
- 'grid-area': {values: ['auto']},
+ 'row-gap': {values: ['normal']},
'animation-iteration-count': {values: ['infinite']},
'font-feature-settings': {values: ['normal']},
- 'font-kerning': {values: ['none', 'normal', 'auto']},
- 'font-size-adjust': {values: ['none']},
+ 'font-kerning': {values: ['normal']},
'font-variant-caps':
{values: ['small-caps', 'all-small-caps', 'petite-caps', 'all-petite-caps', 'unicase', 'titling-caps', 'normal']},
'font-variant-east-asian': {
- values:
- ['jis78', 'jis83', 'jis90', 'jis04', 'simplified', 'traditional', 'full-width', 'proportional-width', 'ruby']
+ values: [
+ 'jis78', 'jis83', 'jis90', 'jis04', 'simplified', 'traditional', 'full-width', 'proportional-width', 'ruby',
+ 'normal'
+ ]
},
'font-variant-ligatures': {
values: [
- 'none', 'common-ligatures', 'no-common-ligatures', 'discretionary-ligatures', 'no-discretionary-ligatures',
+ 'common-ligatures', 'no-common-ligatures', 'discretionary-ligatures', 'no-discretionary-ligatures',
'historical-ligatures', 'no-historical-ligatures', 'contextual', 'no-contextual', 'normal'
]
},
@@ -816,17 +789,14 @@ SDK.CSSMetadata._propertyDataMap = {
]
},
'font-variation-settings': {values: ['normal']},
- '-webkit-locale': {values: ['auto']},
- 'backdrop-filter': {values: ['none']},
'backface-visibility': {values: ['hidden', 'visible']},
'background': {
values: [
- 'none', 'repeat', 'repeat-x', 'repeat-y', 'no-repeat', 'top', 'bottom', 'left', 'right', 'center', 'fixed',
- 'local', 'scroll', 'space', 'round', 'border-box', 'content-box', 'padding-box'
+ 'repeat', 'repeat-x', 'repeat-y', 'no-repeat', 'top', 'bottom', 'left', 'right', 'center', 'fixed', 'local',
+ 'scroll', 'space', 'round', 'border-box', 'content-box', 'padding-box'
]
},
'background-attachment': {values: ['fixed', 'local', 'scroll']},
- 'background-image': {values: ['none']},
'background-position': {values: ['top', 'bottom', 'left', 'right', 'center']},
'background-position-x': {values: ['left', 'right', 'center']},
'background-position-y': {values: ['top', 'bottom', 'center']},
@@ -834,68 +804,50 @@ SDK.CSSMetadata._propertyDataMap = {
'background-repeat-y': {values: ['repeat', 'no-repeat']},
'border-bottom': {
values: [
- 'none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick',
- 'thin'
+ 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', 'thin'
]
},
'border-image-repeat': {values: ['repeat', 'stretch', 'space', 'round']},
- 'border-image-source': {values: ['none']},
- 'border-image-width': {values: ['auto']},
'border-left': {
values: [
- 'none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick',
- 'thin'
+ 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', 'thin'
]
},
'border-right': {
values: [
- 'none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick',
- 'thin'
+ 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', 'thin'
]
},
'border-top': {
values: [
- 'none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick',
- 'thin'
+ 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', 'thin'
]
},
- 'bottom': {values: ['auto']},
- 'break-after':
- {values: ['left', 'right', 'auto', 'avoid', 'column', 'avoid-page', 'page', 'recto', 'verso', 'avoid-column']},
+ 'break-after': {values: ['left', 'right', 'avoid', 'column', 'avoid-page', 'page', 'recto', 'verso', 'avoid-column']},
'break-before':
- {values: ['left', 'right', 'auto', 'avoid', 'column', 'avoid-page', 'page', 'recto', 'verso', 'avoid-column']},
- 'break-inside': {values: ['auto', 'avoid', 'avoid-page', 'avoid-column']},
- 'buffered-rendering': {values: ['auto', 'static', 'dynamic']},
- 'color-interpolation-filters': {values: ['auto', 'srgb', 'linearrgb']},
- 'column-count': {values: ['auto']},
- 'column-fill': {values: ['auto', 'balance']},
+ {values: ['left', 'right', 'avoid', 'column', 'avoid-page', 'page', 'recto', 'verso', 'avoid-column']},
+ 'break-inside': {values: ['avoid', 'avoid-page', 'avoid-column']},
+ 'buffered-rendering': {values: ['static', 'dynamic']},
+ 'color-interpolation-filters': {values: ['srgb', 'linearrgb']},
+ 'column-fill': {values: ['balance']},
'column-gap': {values: ['normal']},
'column-rule': {
values: [
- 'none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick',
- 'thin'
+ 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', 'thin'
]
},
'column-rule-style':
- {values: ['none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double']},
+ {values: ['hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double']},
'column-rule-width': {values: ['medium', 'thick', 'thin']},
- 'column-span': {values: ['none', 'all']},
- 'column-width': {values: ['auto']},
- 'columns': {values: ['auto']},
- 'd': {values: ['none']},
- 'fill': {values: ['none']},
+ 'column-span': {values: ['all']},
'fill-rule': {values: ['nonzero', 'evenodd']},
- 'flex': {values: ['none', 'auto']},
- 'flex-basis': {values: ['auto']},
'flex-flow': {values: ['nowrap', 'row', 'row-reverse', 'column', 'column-reverse', 'wrap', 'wrap-reverse']},
- 'height': {values: ['auto', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
- 'hyphens': {values: ['none', 'manual']},
- 'inline-size': {values: ['auto', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
- 'isolation': {values: ['auto', 'isolate']},
- 'left': {values: ['auto']},
+ 'height': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
+ 'hyphens': {values: ['manual']},
+ 'inline-size': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
+ 'isolation': {values: ['isolate']},
'list-style': {
values: [
- 'none',
'outside',
'inside',
'disc',
@@ -955,38 +907,24 @@ SDK.CSSMetadata._propertyDataMap = {
'katakana-iroha'
]
},
- 'marker': {values: ['none']},
- 'marker-end': {values: ['none']},
- 'marker-mid': {values: ['none']},
- 'marker-start': {values: ['none']},
- 'mask': {values: ['none']},
- 'mask-source-type': {values: ['auto', 'alpha', 'luminance']},
+ 'mask-source-type': {values: ['alpha', 'luminance']},
'mask-type': {values: ['alpha', 'luminance']},
- 'max-block-size': {values: ['none', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
- 'max-inline-size': {values: ['none', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
- 'min-block-size': {values: ['auto', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
- 'min-height': {values: ['auto', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
- 'min-inline-size': {values: ['auto', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
- 'min-width': {values: ['auto', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
- 'object-fit': {values: ['none', 'contain', 'cover', 'fill', 'scale-down']},
+ 'max-block-size': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
+ 'max-inline-size': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
+ 'min-block-size': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
+ 'min-height': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
+ 'min-inline-size': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
+ 'min-width': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
+ 'object-fit': {values: ['contain', 'cover', 'fill', 'scale-down']},
'object-position': {values: ['top', 'bottom', 'left', 'right', 'center']},
- 'offset-anchor': {values: ['top', 'bottom', 'left', 'right', 'center', 'auto']},
- 'offset-path': {values: ['none']},
- 'offset-position': {values: ['top', 'bottom', 'left', 'right', 'center', 'auto']},
- 'offset-rotate': {values: ['auto', 'reverse']},
- 'overflow-anchor': {values: ['none', 'auto', 'visible']},
+ 'offset-anchor': {values: ['top', 'bottom', 'left', 'right', 'center']},
+ 'offset-position': {values: ['top', 'bottom', 'left', 'right', 'center']},
+ 'offset-rotate': {values: ['reverse']},
+ 'overflow-anchor': {values: ['visible']},
'paint-order': {values: ['normal', 'fill', 'stroke', 'markers']},
- 'quotes': {values: ['none']},
- 'right': {values: ['auto']},
- 'rotate': {values: ['none']},
- 'rx': {values: ['auto']},
- 'ry': {values: ['auto']},
- 'scale': {values: ['none']},
- 'scroll-behavior': {values: ['auto', 'smooth']},
+ 'scroll-behavior': {values: ['smooth']},
'scroll-customization': {
values: [
- 'none',
- 'auto',
'pan-x',
'pan-y',
'pan-left',
@@ -995,32 +933,24 @@ SDK.CSSMetadata._propertyDataMap = {
'pan-down',
]
},
- 'shape-outside': {values: ['none', 'border-box', 'content-box', 'padding-box', 'margin-box']},
- 'shape-rendering': {values: ['auto', 'optimizespeed', 'geometricprecision', 'crispedges']},
- 'stroke': {values: ['none']},
- 'stroke-dasharray': {values: ['none']},
+ 'scroll-snap-align': {values: ['start', 'end', 'center']},
+ 'scroll-snap-stop': {values: ['normal', 'always']},
+ 'scroll-snap-type': {values: ['x', 'y', 'block', 'inline', 'both', 'mandatory', 'proximity']},
+ 'shape-outside': {values: ['border-box', 'content-box', 'padding-box', 'margin-box']},
+ 'shape-rendering': {values: ['optimizespeed', 'geometricprecision', 'crispedges']},
'stroke-linecap': {values: ['square', 'round', 'butt']},
'text-anchor': {values: ['middle', 'start', 'end']},
- 'text-decoration-line': {values: ['none', 'blink', 'line-through', 'overline', 'underline']},
- 'text-decoration-skip': {values: ['objects', 'ink']},
+ 'text-decoration-line': {values: ['blink', 'line-through', 'overline', 'underline']},
'text-decoration-style': {values: ['dotted', 'dashed', 'solid', 'double', 'wavy']},
- 'text-justify': {values: ['none', 'inter-word', 'distribute', 'auto']},
- 'text-shadow': {values: ['none']},
- 'text-size-adjust': {values: ['none', 'auto']},
- 'text-underline-position': {values: ['auto', 'under']},
- 'top': {values: ['auto']},
- 'touch-action': {
- values: [
- 'none', 'auto', 'pan-x', 'pan-y', 'pan-left', 'pan-right', 'pan-up', 'pan-down', 'manipulation', 'pinch-zoom'
- ]
- },
+ 'text-justify': {values: ['inter-word', 'distribute']},
+ 'text-underline-position': {values: ['under']},
+ 'touch-action':
+ {values: ['pan-x', 'pan-y', 'pan-left', 'pan-right', 'pan-up', 'pan-down', 'manipulation', 'pinch-zoom']},
'transform-box': {values: ['border-box', 'fill-box', 'view-box']},
- 'translate': {values: ['none']},
- 'vector-effect': {values: ['none', 'non-scaling-stroke']},
+ 'vector-effect': {values: ['non-scaling-stroke']},
'-webkit-app-region': {values: ['drag', 'no-drag']},
'-webkit-appearance': {
values: [
- 'none',
'checkbox',
'radio',
'push-button',
@@ -1065,54 +995,42 @@ SDK.CSSMetadata._propertyDataMap = {
},
'-webkit-border-after': {
values: [
- 'none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick',
- 'thin'
+ 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', 'thin'
]
},
'-webkit-border-after-style':
- {values: ['none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double']},
+ {values: ['hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double']},
'-webkit-border-after-width': {values: ['medium', 'thick', 'thin']},
'-webkit-border-before': {
values: [
- 'none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick',
- 'thin'
+ 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', 'thin'
]
},
'-webkit-border-before-style':
- {values: ['none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double']},
+ {values: ['hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double']},
'-webkit-border-before-width': {values: ['medium', 'thick', 'thin']},
'-webkit-border-end': {
values: [
- 'none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick',
- 'thin'
+ 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', 'thin'
]
},
'-webkit-border-end-style':
- {values: ['none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double']},
+ {values: ['hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double']},
'-webkit-border-end-width': {values: ['medium', 'thick', 'thin']},
'-webkit-border-start': {
values: [
- 'none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick',
- 'thin'
+ 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double', 'medium', 'thick', 'thin'
]
},
'-webkit-border-start-style':
- {values: ['none', 'hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double']},
+ {values: ['hidden', 'inset', 'groove', 'outset', 'ridge', 'dotted', 'dashed', 'solid', 'double']},
'-webkit-border-start-width': {values: ['medium', 'thick', 'thin']},
'-webkit-box-pack': {values: ['center', 'justify', 'start', 'end']},
- '-webkit-highlight': {values: ['none']},
- '-webkit-hyphenate-character': {values: ['auto']},
- '-webkit-logical-height': {values: ['auto', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
- '-webkit-logical-width': {values: ['auto', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
- '-webkit-margin-after': {values: ['auto']},
- '-webkit-margin-before': {values: ['auto']},
+ '-webkit-logical-height': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
+ '-webkit-logical-width': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
'-webkit-margin-collapse': {values: ['collapse', 'separate', 'discard']},
- '-webkit-margin-end': {values: ['auto']},
- '-webkit-margin-start': {values: ['auto']},
- '-webkit-mask-box-image': {values: ['none', 'repeat', 'stretch', 'space', 'round']},
+ '-webkit-mask-box-image': {values: ['repeat', 'stretch', 'space', 'round']},
'-webkit-mask-box-image-repeat': {values: ['repeat', 'stretch', 'space', 'round']},
- '-webkit-mask-box-image-source': {values: ['none']},
- '-webkit-mask-box-image-width': {values: ['auto']},
'-webkit-mask-clip': {values: ['text', 'border', 'border-box', 'content', 'content-box', 'padding', 'padding-box']},
'-webkit-mask-composite': {
values: [
@@ -1120,35 +1038,29 @@ SDK.CSSMetadata._propertyDataMap = {
'destination-out', 'destination-atop', 'xor', 'plus-lighter'
]
},
- '-webkit-mask-image': {values: ['none']},
'-webkit-mask-origin': {values: ['border', 'border-box', 'content', 'content-box', 'padding', 'padding-box']},
'-webkit-mask-position': {values: ['top', 'bottom', 'left', 'right', 'center']},
'-webkit-mask-position-x': {values: ['left', 'right', 'center']},
'-webkit-mask-position-y': {values: ['top', 'bottom', 'center']},
'-webkit-mask-repeat': {values: ['repeat', 'repeat-x', 'repeat-y', 'no-repeat', 'space', 'round']},
- '-webkit-mask-size': {values: ['auto', 'contain', 'cover']},
- '-webkit-max-logical-height':
- {values: ['none', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
- '-webkit-max-logical-width':
- {values: ['none', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
- '-webkit-min-logical-height':
- {values: ['auto', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
- '-webkit-min-logical-width':
- {values: ['auto', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
+ '-webkit-mask-size': {values: ['contain', 'cover']},
+ '-webkit-max-logical-height': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
+ '-webkit-max-logical-width': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
+ '-webkit-min-logical-height': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
+ '-webkit-min-logical-width': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
'-webkit-perspective-origin-x': {values: ['left', 'right', 'center']},
'-webkit-perspective-origin-y': {values: ['top', 'bottom', 'center']},
'-webkit-print-color-adjust': {values: ['economy', 'exact']},
'-webkit-rtl-ordering': {values: ['logical', 'visual']},
'-webkit-ruby-position': {values: ['after', 'before']},
- '-webkit-text-decorations-in-effect': {values: ['none', 'blink', 'line-through', 'overline', 'underline']},
- '-webkit-text-security': {values: ['none', 'disc', 'circle', 'square']},
+ '-webkit-text-decorations-in-effect': {values: ['blink', 'line-through', 'overline', 'underline']},
+ '-webkit-text-security': {values: ['disc', 'circle', 'square']},
'-webkit-text-stroke': {values: ['medium', 'thick', 'thin']},
'-webkit-text-stroke-width': {values: ['medium', 'thick', 'thin']},
'-webkit-transform-origin-x': {values: ['left', 'right', 'center']},
'-webkit-transform-origin-y': {values: ['top', 'bottom', 'center']},
- '-webkit-user-drag': {values: ['none', 'auto', 'element']},
- 'width': {values: ['auto', '-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
- 'z-index': {values: ['auto']}
+ '-webkit-user-drag': {values: ['element']},
+ 'width': {values: ['-webkit-fill-available', 'min-content', 'max-content', 'fit-content']},
};
// Weight of CSS properties based on their usage from https://www.chromestatus.com/metrics/css/popularity
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sdk/CSSModel.js b/chromium/third_party/blink/renderer/devtools/front_end/sdk/CSSModel.js
index d8d152cf189..b27a970036a 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/sdk/CSSModel.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk/CSSModel.js
@@ -105,129 +105,18 @@ SDK.CSSModel = class extends SDK.SDKModel {
* @param {boolean} majorChange
* @return {!Promise<boolean>}
*/
- setStyleText(styleSheetId, range, text, majorChange) {
- const original = this._innerSetStyleTexts.bind(this, [styleSheetId], [range], [text], majorChange);
- const header = this.styleSheetHeaderForId(styleSheetId);
- if (!header)
- return original();
-
- const sourceMap = this._sourceMapManager.sourceMapForClient(header);
- if (!sourceMap)
- return original();
-
- const originalAndDetach = originalAndDetachIfSuccess.bind(this, header);
-
- if (!sourceMap.editable())
- return original();
-
- return /** @type {!Promise<boolean>} */ (
- sourceMap.editCompiled([range], [text]).then(onEditingDone.bind(this)).catch(onError.bind(this, header)));
-
- /**
- * @param {?SDK.SourceMap.EditResult} editResult
- * @return {!Promise<boolean>}
- * @this {SDK.CSSModel}
- */
- function onEditingDone(editResult) {
- if (!editResult)
- return Promise.resolve(false);
-
- let edits = editResult.compiledEdits;
- if (!edits.length)
- return onCSSPatched.call(this, editResult, true);
-
- edits.sort(TextUtils.SourceEdit.comparator);
- edits = edits.reverse();
-
- const styleSheetIds = [];
- const ranges = [];
- const texts = [];
- for (const edit of edits) {
- styleSheetIds.push(header.id);
- ranges.push(edit.oldRange);
- texts.push(edit.newText);
- }
- return this._innerSetStyleTexts(styleSheetIds, ranges, texts, majorChange)
- .then(onCSSPatched.bind(this, editResult));
- }
-
- /**
- * @param {!SDK.SourceMap.EditResult} editResult
- * @param {boolean} success
- * @return {!Promise<boolean>}
- * @this {SDK.CSSModel}
- */
- function onCSSPatched(editResult, success) {
- if (!success)
- return originalAndDetach();
-
- this._sourceMapManager.applySourceMapEdit(editResult);
- return Promise.resolve(true);
- }
-
- /**
- * @param {!SDK.CSSStyleSheetHeader} header
- * @param {*} error
- * @return {!Promise<boolean>}
- * @this {SDK.CSSModel}
- */
- function onError(header, error) {
- Common.console.error(Common.UIString('LiveSASS failed: %s', sourceMap.compiledURL()));
- console.error(error);
- this._sourceMapManager.detachSourceMap(header);
- return original();
- }
-
- /**
- * @param {!SDK.CSSStyleSheetHeader} header
- * @return {!Promise<boolean>}
- * @this {SDK.CSSModel}
- */
- function originalAndDetachIfSuccess(header) {
- return this._innerSetStyleTexts([styleSheetId], [range], [text], majorChange).then(detachIfSuccess.bind(this));
-
- /**
- * @param {boolean} success
- * @return {boolean}
- * @this {SDK.CSSModel}
- */
- function detachIfSuccess(success) {
- if (success)
- this._sourceMapManager.detachSourceMap(header);
- return success;
- }
- }
- }
-
- /**
- * @param {!Array<!Protocol.CSS.StyleSheetId>} styleSheetIds
- * @param {!Array<!TextUtils.TextRange>} ranges
- * @param {!Array<string>} texts
- * @param {boolean} majorChange
- * @return {!Promise<boolean>}
- */
- async _innerSetStyleTexts(styleSheetIds, ranges, texts, majorChange) {
- console.assert(
- styleSheetIds.length === ranges.length && ranges.length === texts.length, 'Array lengths must be equal');
- const edits = [];
- const ensureContentPromises = [];
- for (let i = 0; i < styleSheetIds.length; ++i) {
- edits.push({styleSheetId: styleSheetIds[i], range: ranges[i].serializeToObject(), text: texts[i]});
- ensureContentPromises.push(this._ensureOriginalStyleSheetText(styleSheetIds[i]));
- }
-
+ async setStyleText(styleSheetId, range, text, majorChange) {
try {
- await Promise.all(ensureContentPromises);
- const stylePayloads = await this._agent.setStyleTexts(edits);
+ await this._ensureOriginalStyleSheetText(styleSheetId);
- if (!stylePayloads || stylePayloads.length !== ranges.length)
+ const stylePayloads =
+ await this._agent.setStyleTexts([{styleSheetId: styleSheetId, range: range.serializeToObject(), text: text}]);
+ if (!stylePayloads || stylePayloads.length !== 1)
return false;
this._domModel.markUndoableState(!majorChange);
- for (let i = 0; i < ranges.length; ++i) {
- const edit = new SDK.CSSModel.Edit(styleSheetIds[i], ranges[i], texts[i], stylePayloads[i]);
- this._fireStyleSheetChanged(styleSheetIds[i], edit);
- }
+ const edit = new SDK.CSSModel.Edit(styleSheetId, range, text, stylePayloads[0]);
+ this._fireStyleSheetChanged(styleSheetId, edit);
return true;
} catch (e) {
return false;
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sdk/Connections.js b/chromium/third_party/blink/renderer/devtools/front_end/sdk/Connections.js
index 01811b8f4ff..112423b791f 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/sdk/Connections.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk/Connections.js
@@ -1,15 +1,16 @@
// Copyright (c) 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.
+
/**
- * @implements {Protocol.InspectorBackend.Connection}
* @unrestricted
*/
-SDK.MainConnection = class {
+SDK.MainConnection = class extends Protocol.InspectorBackend.Connection {
/**
* @param {!Protocol.InspectorBackend.Connection.Params} params
*/
constructor(params) {
+ super();
this._onMessage = params.onMessage;
this._onDisconnect = params.onDisconnect;
this._disconnected = false;
@@ -25,7 +26,7 @@ SDK.MainConnection = class {
* @override
* @param {string} message
*/
- sendMessage(message) {
+ sendRawMessage(message) {
if (!this._disconnected)
InspectorFrontendHost.sendMessageToBackend(message);
}
@@ -77,16 +78,16 @@ SDK.MainConnection = class {
};
/**
- * @implements {Protocol.InspectorBackend.Connection}
* @unrestricted
*/
-SDK.WebSocketConnection = class {
+SDK.WebSocketConnection = class extends Protocol.InspectorBackend.Connection {
/**
* @param {string} url
* @param {function()} onWebSocketDisconnect
* @param {!Protocol.InspectorBackend.Connection.Params} params
*/
constructor(url, onWebSocketDisconnect, params) {
+ super();
this._socket = new WebSocket(url);
this._socket.onerror = this._onError.bind(this);
this._socket.onopen = this._onOpen.bind(this);
@@ -137,7 +138,7 @@ SDK.WebSocketConnection = class {
* @override
* @param {string} message
*/
- sendMessage(message) {
+ sendRawMessage(message) {
if (this._connected)
this._socket.send(message);
else
@@ -160,14 +161,14 @@ SDK.WebSocketConnection = class {
};
/**
- * @implements {Protocol.InspectorBackend.Connection}
* @unrestricted
*/
-SDK.StubConnection = class {
+SDK.StubConnection = class extends Protocol.InspectorBackend.Connection {
/**
* @param {!Protocol.InspectorBackend.Connection.Params} params
*/
constructor(params) {
+ super();
this._onMessage = params.onMessage;
this._onDisconnect = params.onDisconnect;
}
@@ -176,7 +177,7 @@ SDK.StubConnection = class {
* @override
* @param {string} message
*/
- sendMessage(message) {
+ sendRawMessage(message) {
setTimeout(this._respondWithError.bind(this, message), 0);
}
@@ -205,16 +206,14 @@ SDK.StubConnection = class {
}
};
-/**
- * @implements {Protocol.InspectorBackend.Connection}
- */
-SDK.ChildConnection = class {
+SDK.ChildConnection = class extends Protocol.InspectorBackend.Connection {
/**
* @param {!Protocol.TargetAgent} agent
* @param {string} sessionId
* @param {!Protocol.InspectorBackend.Connection.Params} params
*/
constructor(agent, sessionId, params) {
+ super();
this._agent = agent;
this._sessionId = sessionId;
this.onMessage = params.onMessage;
@@ -225,7 +224,7 @@ SDK.ChildConnection = class {
* @override
* @param {string} message
*/
- sendMessage(message) {
+ sendRawMessage(message) {
this._agent.sendMessageToTarget(message, this._sessionId);
}
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sdk/DebuggerModel.js b/chromium/third_party/blink/renderer/devtools/front_end/sdk/DebuggerModel.js
index 5bc6a1cf215..7bc0762f73c 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/sdk/DebuggerModel.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk/DebuggerModel.js
@@ -551,11 +551,13 @@ SDK.DebuggerModel = class extends SDK.SDKModel {
* @param {boolean} hasSourceURLComment
* @param {boolean} hasSyntaxError
* @param {number} length
+ * @param {?Protocol.Runtime.StackTrace} originStackTrace
* @return {!SDK.Script}
*/
_parsedScriptSource(
scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash,
- executionContextAuxData, isLiveEdit, sourceMapURL, hasSourceURLComment, hasSyntaxError, length) {
+ executionContextAuxData, isLiveEdit, sourceMapURL, hasSourceURLComment, hasSyntaxError, length,
+ originStackTrace) {
let isContentScript = false;
if (executionContextAuxData && ('isDefault' in executionContextAuxData))
isContentScript = !executionContextAuxData['isDefault'];
@@ -569,12 +571,10 @@ SDK.DebuggerModel = class extends SDK.SDKModel {
}
const script = new SDK.Script(
this, scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId,
- this._internString(hash), isContentScript, isLiveEdit, sourceMapURL, hasSourceURLComment, length);
+ this._internString(hash), isContentScript, isLiveEdit, sourceMapURL, hasSourceURLComment, length,
+ originStackTrace);
this._registerScript(script);
- if (!hasSyntaxError)
- this.dispatchEventToListeners(SDK.DebuggerModel.Events.ParsedScriptSource, script);
- else
- this.dispatchEventToListeners(SDK.DebuggerModel.Events.FailedToParseScriptSource, script);
+ this.dispatchEventToListeners(SDK.DebuggerModel.Events.ParsedScriptSource, script);
const sourceMapId =
SDK.DebuggerModel._sourceMapId(script.executionContextId, script.sourceURL, script.sourceMapURL);
@@ -1017,13 +1017,14 @@ SDK.DebuggerDispatcher = class {
* @param {boolean=} hasSourceURL
* @param {boolean=} isModule
* @param {number=} length
+ * @param {!Protocol.Runtime.StackTrace=} stackTrace
*/
scriptParsed(
scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash,
- executionContextAuxData, isLiveEdit, sourceMapURL, hasSourceURL, isModule, length) {
+ executionContextAuxData, isLiveEdit, sourceMapURL, hasSourceURL, isModule, length, stackTrace) {
this._debuggerModel._parsedScriptSource(
scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash,
- executionContextAuxData, !!isLiveEdit, sourceMapURL, !!hasSourceURL, false, length || 0);
+ executionContextAuxData, !!isLiveEdit, sourceMapURL, !!hasSourceURL, false, length || 0, stackTrace || null);
}
/**
@@ -1041,13 +1042,14 @@ SDK.DebuggerDispatcher = class {
* @param {boolean=} hasSourceURL
* @param {boolean=} isModule
* @param {number=} length
+ * @param {!Protocol.Runtime.StackTrace=} stackTrace
*/
scriptFailedToParse(
scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash,
- executionContextAuxData, sourceMapURL, hasSourceURL, isModule, length) {
+ executionContextAuxData, sourceMapURL, hasSourceURL, isModule, length, stackTrace) {
this._debuggerModel._parsedScriptSource(
scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash,
- executionContextAuxData, false, sourceMapURL, !!hasSourceURL, true, length || 0);
+ executionContextAuxData, false, sourceMapURL, !!hasSourceURL, true, length || 0, stackTrace || null);
}
/**
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/browser_sdk/HAREntry.js b/chromium/third_party/blink/renderer/devtools/front_end/sdk/HARLog.js
index cf907216d85..9ad29cb1de0 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/browser_sdk/HAREntry.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk/HARLog.js
@@ -36,7 +36,87 @@
/**
* @unrestricted
*/
-BrowserSDK.HAREntry = class {
+SDK.HARLog = class {
+ /**
+ * @param {!SDK.NetworkRequest} request
+ * @param {number} monotonicTime
+ * @return {!Date}
+ */
+ static pseudoWallTime(request, monotonicTime) {
+ return new Date(request.pseudoWallTime(monotonicTime) * 1000);
+ }
+
+ /**
+ * @param {!Array.<!SDK.NetworkRequest>} requests
+ * @return {!Promise<!Object>}
+ */
+ static async build(requests) {
+ const log = new SDK.HARLog();
+ const entryPromises = [];
+ for (const request of requests)
+ entryPromises.push(SDK.HARLog.Entry.build(request));
+ const entries = await Promise.all(entryPromises);
+ return {version: '1.2', creator: log._creator(), pages: log._buildPages(requests), entries: entries};
+ }
+
+ _creator() {
+ const webKitVersion = /AppleWebKit\/([^ ]+)/.exec(window.navigator.userAgent);
+
+ return {name: 'WebInspector', version: webKitVersion ? webKitVersion[1] : 'n/a'};
+ }
+
+ /**
+ * @param {!Array.<!SDK.NetworkRequest>} requests
+ * @return {!Array.<!Object>}
+ */
+ _buildPages(requests) {
+ const seenIdentifiers = {};
+ const pages = [];
+ for (let i = 0; i < requests.length; ++i) {
+ const request = requests[i];
+ const page = SDK.NetworkLog.PageLoad.forRequest(request);
+ if (!page || seenIdentifiers[page.id])
+ continue;
+ seenIdentifiers[page.id] = true;
+ pages.push(this._convertPage(page, request));
+ }
+ return pages;
+ }
+
+ /**
+ * @param {!SDK.NetworkLog.PageLoad} page
+ * @param {!SDK.NetworkRequest} request
+ * @return {!Object}
+ */
+ _convertPage(page, request) {
+ return {
+ startedDateTime: SDK.HARLog.pseudoWallTime(request, page.startTime).toJSON(),
+ id: 'page_' + page.id,
+ title: page.url, // We don't have actual page title here. URL is probably better than nothing.
+ pageTimings: {
+ onContentLoad: this._pageEventTime(page, page.contentLoadTime),
+ onLoad: this._pageEventTime(page, page.loadTime)
+ }
+ };
+ }
+
+ /**
+ * @param {!SDK.NetworkLog.PageLoad} page
+ * @param {number} time
+ * @return {number}
+ */
+ _pageEventTime(page, time) {
+ const startTime = page.startTime;
+ if (time === -1 || startTime === -1)
+ return -1;
+ return SDK.HARLog.Entry._toMilliseconds(time - startTime);
+ }
+};
+
+/**
+ * @unrestricted
+ */
+SDK.HARLog.Entry = class {
/**
* @param {!SDK.NetworkRequest} request
*/
@@ -57,7 +137,7 @@ BrowserSDK.HAREntry = class {
* @return {!Promise<!Object>}
*/
static async build(request) {
- const harEntry = new BrowserSDK.HAREntry(request);
+ const harEntry = new SDK.HARLog.Entry(request);
let ipAddress = harEntry._request.remoteAddress();
const portPositionInString = ipAddress.lastIndexOf(':');
if (portPositionInString !== -1)
@@ -70,7 +150,7 @@ BrowserSDK.HAREntry = class {
time += Math.max(t, 0);
const entry = {
- startedDateTime: BrowserSDK.HARLog.pseudoWallTime(harEntry._request, harEntry._request.issueTime()).toJSON(),
+ startedDateTime: SDK.HARLog.pseudoWallTime(harEntry._request, harEntry._request.issueTime()).toJSON(),
time: time,
request: await harEntry._buildRequest(),
response: harEntry._buildResponse(),
@@ -86,7 +166,7 @@ BrowserSDK.HAREntry = class {
if (harEntry._request.connectionId !== '0')
entry.connection = harEntry._request.connectionId;
- const page = BrowserSDK.PageLoad.forRequest(harEntry._request);
+ const page = SDK.NetworkLog.PageLoad.forRequest(harEntry._request);
if (page)
entry.pageref = 'page_' + page.id;
return entry;
@@ -150,7 +230,7 @@ BrowserSDK.HAREntry = class {
}
/**
- * @return {!BrowserSDK.HAREntry.Timing}
+ * @return {!SDK.HARLog.Entry.Timing}
*/
_buildTimings() {
// Order of events: request_start = 0, [proxy], [dns], [connect [ssl]], [send], duration
@@ -162,7 +242,7 @@ BrowserSDK.HAREntry = class {
const queuedTime = (issueTime < startTime) ? startTime - issueTime : -1;
result.blocked = queuedTime;
- result._blocked_queueing = BrowserSDK.HAREntry._toMilliseconds(queuedTime);
+ result._blocked_queueing = SDK.HARLog.Entry._toMilliseconds(queuedTime);
let highestTime = 0;
if (timing) {
@@ -207,11 +287,11 @@ BrowserSDK.HAREntry = class {
const requestTime = timing ? timing.requestTime : startTime;
const waitStart = highestTime;
- const waitEnd = BrowserSDK.HAREntry._toMilliseconds(this._request.responseReceivedTime - requestTime);
+ const waitEnd = SDK.HARLog.Entry._toMilliseconds(this._request.responseReceivedTime - requestTime);
result.wait = waitEnd - waitStart;
const receiveStart = waitEnd;
- const receiveEnd = BrowserSDK.HAREntry._toMilliseconds(this._request.endTime - issueTime);
+ const receiveEnd = SDK.HARLog.Entry._toMilliseconds(this._request.endTime - issueTime);
result.receive = Math.max(receiveEnd - receiveStart, 0);
return result;
@@ -273,7 +353,7 @@ BrowserSDK.HAREntry = class {
value: cookie.value(),
path: cookie.path(),
domain: cookie.domain(),
- expires: cookie.expiresDate(BrowserSDK.HARLog.pseudoWallTime(this._request, this._request.startTime)),
+ expires: cookie.expiresDate(SDK.HARLog.pseudoWallTime(this._request, this._request.startTime)),
httpOnly: cookie.httpOnly(),
secure: cookie.secure()
};
@@ -323,85 +403,4 @@ BrowserSDK.HAREntry = class {
_blocked_queueing: number,
_blocked_proxy: (number|undefined)
}} */
-BrowserSDK.HAREntry.Timing;
-
-
-/**
- * @unrestricted
- */
-BrowserSDK.HARLog = class {
- /**
- * @param {!SDK.NetworkRequest} request
- * @param {number} monotonicTime
- * @return {!Date}
- */
- static pseudoWallTime(request, monotonicTime) {
- return new Date(request.pseudoWallTime(monotonicTime) * 1000);
- }
-
- /**
- * @param {!Array.<!SDK.NetworkRequest>} requests
- * @return {!Promise<!Object>}
- */
- static async build(requests) {
- const log = new BrowserSDK.HARLog();
- const entryPromises = [];
- for (const request of requests)
- entryPromises.push(BrowserSDK.HAREntry.build(request));
- const entries = await Promise.all(entryPromises);
- return {version: '1.2', creator: log._creator(), pages: log._buildPages(requests), entries: entries};
- }
-
- _creator() {
- const webKitVersion = /AppleWebKit\/([^ ]+)/.exec(window.navigator.userAgent);
-
- return {name: 'WebInspector', version: webKitVersion ? webKitVersion[1] : 'n/a'};
- }
-
- /**
- * @param {!Array.<!SDK.NetworkRequest>} requests
- * @return {!Array.<!Object>}
- */
- _buildPages(requests) {
- const seenIdentifiers = {};
- const pages = [];
- for (let i = 0; i < requests.length; ++i) {
- const request = requests[i];
- const page = BrowserSDK.PageLoad.forRequest(request);
- if (!page || seenIdentifiers[page.id])
- continue;
- seenIdentifiers[page.id] = true;
- pages.push(this._convertPage(page, request));
- }
- return pages;
- }
-
- /**
- * @param {!BrowserSDK.PageLoad} page
- * @param {!SDK.NetworkRequest} request
- * @return {!Object}
- */
- _convertPage(page, request) {
- return {
- startedDateTime: BrowserSDK.HARLog.pseudoWallTime(request, page.startTime).toJSON(),
- id: 'page_' + page.id,
- title: page.url, // We don't have actual page title here. URL is probably better than nothing.
- pageTimings: {
- onContentLoad: this._pageEventTime(page, page.contentLoadTime),
- onLoad: this._pageEventTime(page, page.loadTime)
- }
- };
- }
-
- /**
- * @param {!BrowserSDK.PageLoad} page
- * @param {number} time
- * @return {number}
- */
- _pageEventTime(page, time) {
- const startTime = page.startTime;
- if (time === -1 || startTime === -1)
- return -1;
- return BrowserSDK.HAREntry._toMilliseconds(time - startTime);
- }
-};
+SDK.HARLog.Entry.Timing; \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sdk/HeapProfilerModel.js b/chromium/third_party/blink/renderer/devtools/front_end/sdk/HeapProfilerModel.js
index f1330463f27..7de66309643 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/sdk/HeapProfilerModel.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk/HeapProfilerModel.js
@@ -55,7 +55,7 @@ SDK.HeapProfilerModel = class extends SDK.SDKModel {
}
/**
- * @return {!Promise<!Protocol.HeapProfiler.SamplingHeapProfile>}
+ * @return {!Promise<!SDK.HeapProfilerModel.NativeHeapProfile>}
*/
async stopNativeSampling() {
const rawProfile = await this._memoryAgent.getSamplingProfile();
@@ -64,7 +64,7 @@ SDK.HeapProfilerModel = class extends SDK.SDKModel {
}
/**
- * @return {!Promise<!Protocol.HeapProfiler.SamplingHeapProfile>}
+ * @return {!Promise<!SDK.HeapProfilerModel.NativeHeapProfile>}
*/
async takeNativeSnapshot() {
const rawProfile = await this._memoryAgent.getAllTimeSamplingProfile();
@@ -72,7 +72,7 @@ SDK.HeapProfilerModel = class extends SDK.SDKModel {
}
/**
- * @return {!Promise<!Protocol.HeapProfiler.SamplingHeapProfile>}
+ * @return {!Promise<!SDK.HeapProfilerModel.NativeHeapProfile>}
*/
async takeNativeBrowserSnapshot() {
const rawProfile = await this._memoryAgent.getBrowserSamplingProfile();
@@ -81,10 +81,11 @@ SDK.HeapProfilerModel = class extends SDK.SDKModel {
/**
* @param {!Protocol.Memory.SamplingProfile} rawProfile
- * @return {!Protocol.HeapProfiler.SamplingHeapProfile}
+ * @return {!SDK.HeapProfilerModel.NativeHeapProfile}
*/
_convertNativeProfile(rawProfile) {
- const head = {children: new Map(), selfSize: 0, callFrame: {functionName: '(root)', url: ''}};
+ const head = /** @type {!Protocol.HeapProfiler.SamplingHeapProfileNode} */
+ ({children: new Map(), selfSize: 0, callFrame: {functionName: '(root)', url: ''}});
for (const sample of rawProfile.samples) {
const node = sample.stack.reverse().reduce((node, name) => {
let child = node.children.get(name);
@@ -108,7 +109,7 @@ SDK.HeapProfilerModel = class extends SDK.SDKModel {
}
convertChildren(head);
- return /** @type {!Protocol.HeapProfiler.SamplingHeapProfile} */ ({head});
+ return new SDK.HeapProfilerModel.NativeHeapProfile(head, rawProfile.modules);
}
/**
@@ -218,6 +219,20 @@ SDK.HeapProfilerModel.Events = {
};
/**
+ * @extends {Protocol.HeapProfiler.SamplingHeapProfile}
+ */
+SDK.HeapProfilerModel.NativeHeapProfile = class {
+ /**
+ * @param {!Protocol.HeapProfiler.SamplingHeapProfileNode} head
+ * @param {!Array<!Protocol.Memory.Module>} modules
+ */
+ constructor(head, modules) {
+ this.head = head;
+ this.modules = modules;
+ }
+};
+
+/**
* @extends {Protocol.HeapProfilerDispatcher}
* @unrestricted
*/
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/browser_sdk/NetworkLog.js b/chromium/third_party/blink/renderer/devtools/front_end/sdk/NetworkLog.js
index 78447fddd68..bcb9bf82b25 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/browser_sdk/NetworkLog.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk/NetworkLog.js
@@ -31,14 +31,14 @@
/**
* @implements {SDK.SDKModelObserver<!SDK.NetworkManager>}
*/
-BrowserSDK.NetworkLog = class extends Common.Object {
+SDK.NetworkLog = class extends Common.Object {
constructor() {
super();
/** @type {!Array<!SDK.NetworkRequest>} */
this._requests = [];
/** @type {!Set<!SDK.NetworkRequest>} */
this._requestsSet = new Set();
- /** @type {!Map<!SDK.NetworkManager, !BrowserSDK.PageLoad>} */
+ /** @type {!Map<!SDK.NetworkManager, !SDK.NetworkLog.PageLoad>} */
this._pageLoadForManager = new Map();
this._isRecording = true;
SDK.targetManager.observeModels(SDK.NetworkManager, this);
@@ -72,7 +72,7 @@ BrowserSDK.NetworkLog = class extends Common.Object {
SDK.ResourceTreeModel.Events.DOMContentLoaded, this._onDOMContentLoaded.bind(this, resourceTreeModel)));
}
- networkManager[BrowserSDK.NetworkLog._events] = eventListeners;
+ networkManager[SDK.NetworkLog._events] = eventListeners;
}
/**
@@ -87,7 +87,7 @@ BrowserSDK.NetworkLog = class extends Common.Object {
* @param {!SDK.NetworkManager} networkManager
*/
_removeNetworkManagerListeners(networkManager) {
- Common.EventTarget.removeEventListeners(networkManager[BrowserSDK.NetworkLog._events]);
+ Common.EventTarget.removeEventListeners(networkManager[SDK.NetworkLog._events]);
}
/**
@@ -152,9 +152,9 @@ BrowserSDK.NetworkLog = class extends Common.Object {
* @param {!SDK.NetworkRequest} request
*/
_initializeInitiatorSymbolIfNeeded(request) {
- if (!request[BrowserSDK.NetworkLog._initiatorDataSymbol]) {
- /** @type {!{info: ?BrowserSDK.NetworkLog._InitiatorInfo, chain: !Set<!SDK.NetworkRequest>, request: (?SDK.NetworkRequest|undefined)}} */
- request[BrowserSDK.NetworkLog._initiatorDataSymbol] = {
+ if (!request[SDK.NetworkLog._initiatorDataSymbol]) {
+ /** @type {!{info: ?SDK.NetworkLog._InitiatorInfo, chain: !Set<!SDK.NetworkRequest>, request: (?SDK.NetworkRequest|undefined)}} */
+ request[SDK.NetworkLog._initiatorDataSymbol] = {
info: null,
chain: null,
request: undefined,
@@ -164,12 +164,12 @@ BrowserSDK.NetworkLog = class extends Common.Object {
/**
* @param {!SDK.NetworkRequest} request
- * @return {!BrowserSDK.NetworkLog._InitiatorInfo}
+ * @return {!SDK.NetworkLog._InitiatorInfo}
*/
initiatorInfoForRequest(request) {
this._initializeInitiatorSymbolIfNeeded(request);
- if (request[BrowserSDK.NetworkLog._initiatorDataSymbol].info)
- return request[BrowserSDK.NetworkLog._initiatorDataSymbol].info;
+ if (request[SDK.NetworkLog._initiatorDataSymbol].info)
+ return request[SDK.NetworkLog._initiatorDataSymbol].info;
let type = SDK.NetworkRequest.InitiatorType.Other;
let url = '';
@@ -215,7 +215,7 @@ BrowserSDK.NetworkLog = class extends Common.Object {
}
}
- request[BrowserSDK.NetworkLog._initiatorDataSymbol].info = {
+ request[SDK.NetworkLog._initiatorDataSymbol].info = {
type: type,
url: url,
lineNumber: lineNumber,
@@ -223,12 +223,12 @@ BrowserSDK.NetworkLog = class extends Common.Object {
scriptId: scriptId,
stack: initiatorStack
};
- return request[BrowserSDK.NetworkLog._initiatorDataSymbol].info;
+ return request[SDK.NetworkLog._initiatorDataSymbol].info;
}
/**
* @param {!SDK.NetworkRequest} request
- * @return {!BrowserSDK.NetworkLog.InitiatorGraph}
+ * @return {!SDK.NetworkLog.InitiatorGraph}
*/
initiatorGraphForRequest(request) {
/** @type {!Set<!SDK.NetworkRequest>} */
@@ -249,7 +249,7 @@ BrowserSDK.NetworkLog = class extends Common.Object {
_initiatorChain(request) {
this._initializeInitiatorSymbolIfNeeded(request);
let initiatorChainCache =
- /** @type {?Set<!SDK.NetworkRequest>} */ (request[BrowserSDK.NetworkLog._initiatorDataSymbol].chain);
+ /** @type {?Set<!SDK.NetworkRequest>} */ (request[SDK.NetworkLog._initiatorDataSymbol].chain);
if (initiatorChainCache)
return initiatorChainCache;
@@ -257,8 +257,8 @@ BrowserSDK.NetworkLog = class extends Common.Object {
let checkRequest = request;
do {
- if (checkRequest[BrowserSDK.NetworkLog._initiatorDataSymbol].chain) {
- initiatorChainCache.addAll(checkRequest[BrowserSDK.NetworkLog._initiatorDataSymbol].chain);
+ if (checkRequest[SDK.NetworkLog._initiatorDataSymbol].chain) {
+ initiatorChainCache.addAll(checkRequest[SDK.NetworkLog._initiatorDataSymbol].chain);
break;
}
if (initiatorChainCache.has(checkRequest))
@@ -266,7 +266,7 @@ BrowserSDK.NetworkLog = class extends Common.Object {
initiatorChainCache.add(checkRequest);
checkRequest = this._initiatorRequest(checkRequest);
} while (checkRequest);
- request[BrowserSDK.NetworkLog._initiatorDataSymbol].chain = initiatorChainCache;
+ request[SDK.NetworkLog._initiatorDataSymbol].chain = initiatorChainCache;
return initiatorChainCache;
}
@@ -276,13 +276,13 @@ BrowserSDK.NetworkLog = class extends Common.Object {
*/
_initiatorRequest(request) {
this._initializeInitiatorSymbolIfNeeded(request);
- if (request[BrowserSDK.NetworkLog._initiatorDataSymbol].request !== undefined)
- return request[BrowserSDK.NetworkLog._initiatorDataSymbol].request;
+ if (request[SDK.NetworkLog._initiatorDataSymbol].request !== undefined)
+ return request[SDK.NetworkLog._initiatorDataSymbol].request;
const url = this.initiatorInfoForRequest(request).url;
const networkManager = SDK.NetworkManager.forRequest(request);
- request[BrowserSDK.NetworkLog._initiatorDataSymbol].request =
+ request[SDK.NetworkLog._initiatorDataSymbol].request =
networkManager ? this._requestByManagerAndURL(networkManager, url) : null;
- return request[BrowserSDK.NetworkLog._initiatorDataSymbol].request;
+ return request[SDK.NetworkLog._initiatorDataSymbol].request;
}
_willReloadPage() {
@@ -303,7 +303,7 @@ BrowserSDK.NetworkLog = class extends Common.Object {
const oldRequestsSet = this._requestsSet;
this._requests = [];
this._requestsSet = new Set();
- this.dispatchEventToListeners(BrowserSDK.NetworkLog.Events.Reset);
+ this.dispatchEventToListeners(SDK.NetworkLog.Events.Reset);
// Preserve requests from the new session.
let currentPageLoad = null;
@@ -312,7 +312,7 @@ BrowserSDK.NetworkLog = class extends Common.Object {
if (request.loaderId !== mainFrame.loaderId)
continue;
if (!currentPageLoad) {
- currentPageLoad = new BrowserSDK.PageLoad(request);
+ currentPageLoad = new SDK.NetworkLog.PageLoad(request);
let redirectSource = request.redirectSource();
while (redirectSource) {
requestsToAdd.push(redirectSource);
@@ -327,14 +327,14 @@ BrowserSDK.NetworkLog = class extends Common.Object {
this._requests.push(request);
this._requestsSet.add(request);
currentPageLoad.bindRequest(request);
- this.dispatchEventToListeners(BrowserSDK.NetworkLog.Events.RequestAdded, request);
+ this.dispatchEventToListeners(SDK.NetworkLog.Events.RequestAdded, request);
}
if (Common.moduleSetting('network_log.preserve-log').get()) {
for (const request of oldRequestsSet) {
this._requests.push(request);
this._requestsSet.add(request);
- this.dispatchEventToListeners(BrowserSDK.NetworkLog.Events.RequestAdded, request);
+ this.dispatchEventToListeners(SDK.NetworkLog.Events.RequestAdded, request);
}
}
@@ -352,7 +352,7 @@ BrowserSDK.NetworkLog = class extends Common.Object {
for (const request of requests) {
this._requests.push(request);
this._requestsSet.add(request);
- this.dispatchEventToListeners(BrowserSDK.NetworkLog.Events.RequestAdded, request);
+ this.dispatchEventToListeners(SDK.NetworkLog.Events.RequestAdded, request);
}
}
@@ -367,7 +367,7 @@ BrowserSDK.NetworkLog = class extends Common.Object {
const pageLoad = manager ? this._pageLoadForManager.get(manager) : null;
if (pageLoad)
pageLoad.bindRequest(request);
- this.dispatchEventToListeners(BrowserSDK.NetworkLog.Events.RequestAdded, request);
+ this.dispatchEventToListeners(SDK.NetworkLog.Events.RequestAdded, request);
}
/**
@@ -377,7 +377,7 @@ BrowserSDK.NetworkLog = class extends Common.Object {
const request = /** @type {!SDK.NetworkRequest} */ (event.data);
if (!this._requestsSet.has(request))
return;
- this.dispatchEventToListeners(BrowserSDK.NetworkLog.Events.RequestUpdated, request);
+ this.dispatchEventToListeners(SDK.NetworkLog.Events.RequestUpdated, request);
}
/**
@@ -385,7 +385,7 @@ BrowserSDK.NetworkLog = class extends Common.Object {
*/
_onRequestRedirect(event) {
const request = /** @type {!SDK.NetworkRequest} */ (event.data);
- delete request[BrowserSDK.NetworkLog._initiatorDataSymbol];
+ delete request[SDK.NetworkLog._initiatorDataSymbol];
}
/**
@@ -418,7 +418,7 @@ BrowserSDK.NetworkLog = class extends Common.Object {
this._pageLoadForManager.delete(manager);
}
- this.dispatchEventToListeners(BrowserSDK.NetworkLog.Events.Reset);
+ this.dispatchEventToListeners(SDK.NetworkLog.Events.Reset);
}
/**
@@ -447,7 +447,7 @@ BrowserSDK.NetworkLog = class extends Common.Object {
const request = this.requestByManagerAndId(networkManager, requestId);
if (!request)
return;
- consoleMessage[BrowserSDK.NetworkLog._requestSymbol] = request;
+ consoleMessage[SDK.NetworkLog._requestSymbol] = request;
const initiator = request.initiator();
if (initiator) {
consoleMessage.stackTrace = initiator.stack || undefined;
@@ -463,16 +463,16 @@ BrowserSDK.NetworkLog = class extends Common.Object {
* @return {?SDK.NetworkRequest}
*/
static requestForConsoleMessage(consoleMessage) {
- return consoleMessage[BrowserSDK.NetworkLog._requestSymbol] || null;
+ return consoleMessage[SDK.NetworkLog._requestSymbol] || null;
}
};
-BrowserSDK.PageLoad = class {
+SDK.NetworkLog.PageLoad = class {
/**
* @param {!SDK.NetworkRequest} mainRequest
*/
constructor(mainRequest) {
- this.id = ++BrowserSDK.PageLoad._lastIdentifier;
+ this.id = ++SDK.NetworkLog.PageLoad._lastIdentifier;
this.url = mainRequest.url();
this.startTime = mainRequest.startTime;
/** @type {number} */
@@ -491,53 +491,53 @@ BrowserSDK.PageLoad = class {
if (!this.mainRequest.finished)
await this.mainRequest.once(SDK.NetworkRequest.Events.FinishedLoading);
const saveDataHeader = this.mainRequest.requestHeaderValue('Save-Data');
- if (!BrowserSDK.PageLoad._dataSaverMessageWasShown && saveDataHeader && saveDataHeader === 'on') {
+ if (!SDK.NetworkLog.PageLoad._dataSaverMessageWasShown && saveDataHeader && saveDataHeader === 'on') {
const message = Common.UIString(
'Consider disabling %s while debugging. For more info see: %s', Common.UIString('Chrome Data Saver'),
'https://support.google.com/chrome/?p=datasaver');
manager.dispatchEventToListeners(
SDK.NetworkManager.Events.MessageGenerated,
{message: message, requestId: this.mainRequest.requestId(), warning: true});
- BrowserSDK.PageLoad._dataSaverMessageWasShown = true;
+ SDK.NetworkLog.PageLoad._dataSaverMessageWasShown = true;
}
}
/**
* @param {!SDK.NetworkRequest} request
- * @return {?BrowserSDK.PageLoad}
+ * @return {?SDK.NetworkLog.PageLoad}
*/
static forRequest(request) {
- return request[BrowserSDK.PageLoad._pageLoadForRequestSymbol] || null;
+ return request[SDK.NetworkLog.PageLoad._pageLoadForRequestSymbol] || null;
}
/**
* @param {!SDK.NetworkRequest} request
*/
bindRequest(request) {
- request[BrowserSDK.PageLoad._pageLoadForRequestSymbol] = this;
+ request[SDK.NetworkLog.PageLoad._pageLoadForRequestSymbol] = this;
}
};
-BrowserSDK.PageLoad._lastIdentifier = 0;
-BrowserSDK.PageLoad._pageLoadForRequestSymbol = Symbol('PageLoadForRequest');
-BrowserSDK.NetworkLog._requestSymbol = Symbol('_request');
+SDK.NetworkLog.PageLoad._lastIdentifier = 0;
+SDK.NetworkLog.PageLoad._pageLoadForRequestSymbol = Symbol('PageLoadForRequest');
+SDK.NetworkLog._requestSymbol = Symbol('_request');
-BrowserSDK.PageLoad._dataSaverMessageWasShown = false;
+SDK.NetworkLog.PageLoad._dataSaverMessageWasShown = false;
/** @typedef {!{initiators: !Set<!SDK.NetworkRequest>, initiated: !Set<!SDK.NetworkRequest>}} */
-BrowserSDK.NetworkLog.InitiatorGraph;
+SDK.NetworkLog.InitiatorGraph;
-BrowserSDK.NetworkLog.Events = {
+SDK.NetworkLog.Events = {
Reset: Symbol('Reset'),
RequestAdded: Symbol('RequestAdded'),
RequestUpdated: Symbol('RequestUpdated')
};
/** @typedef {!{type: !SDK.NetworkRequest.InitiatorType, url: string, lineNumber: number, columnNumber: number, scriptId: ?string, stack: ?Protocol.Runtime.StackTrace}} */
-BrowserSDK.NetworkLog._InitiatorInfo;
+SDK.NetworkLog._InitiatorInfo;
-BrowserSDK.NetworkLog._initiatorDataSymbol = Symbol('InitiatorData');
-BrowserSDK.NetworkLog._events = Symbol('BrowserSDK.NetworkLog.events');
+SDK.NetworkLog._initiatorDataSymbol = Symbol('InitiatorData');
+SDK.NetworkLog._events = Symbol('SDK.NetworkLog.events');
-/** @type {!BrowserSDK.NetworkLog} */
-BrowserSDK.networkLog = new BrowserSDK.NetworkLog();
+/** @type {!SDK.NetworkLog} */
+SDK.networkLog = new SDK.NetworkLog();
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sdk/RuntimeModel.js b/chromium/third_party/blink/renderer/devtools/front_end/sdk/RuntimeModel.js
index 3356ea5e604..9821eebc461 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/sdk/RuntimeModel.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk/RuntimeModel.js
@@ -54,27 +54,13 @@ SDK.RuntimeModel = class extends SDK.SDKModel {
}
/**
- * @param {string} code
- * @return {string}
+ * @param {!SDK.RuntimeModel.EvaluationResult} response
*/
- static wrapObjectLiteralExpressionIfNeeded(code) {
- // Only parenthesize what appears to be an object literal.
- if (!(/^\s*\{/.test(code) && /\}\s*$/.test(code)))
- return code;
-
- const parse = (async () => 0).constructor;
- try {
- // Check if the code can be interpreted as an expression.
- parse('return ' + code + ';');
-
- // No syntax error! Does it work parenthesized?
- const wrappedCode = '(' + code + ')';
- parse(wrappedCode);
-
- return wrappedCode;
- } catch (e) {
- return code;
- }
+ static isSideEffectFailure(response) {
+ const exceptionDetails = !response[Protocol.Error] && response.exceptionDetails;
+ return !!(
+ exceptionDetails && exceptionDetails.exception && exceptionDetails.exception.description &&
+ exceptionDetails.exception.description.startsWith('EvalError: Possible side-effect in debug-evaluate'));
}
/**
@@ -493,12 +479,8 @@ SDK.RuntimeModel = class extends SDK.SDKModel {
const response = await this._agent.invoke_evaluate(
{expression: SDK.RuntimeModel._sideEffectTestExpression, contextId: testContext.id, throwOnSideEffect: true});
- const exceptionDetails = !response[Protocol.Error] && response.exceptionDetails;
- const supports =
- !!(exceptionDetails && exceptionDetails.exception &&
- exceptionDetails.exception.description.startsWith('EvalError: Possible side-effect in debug-evaluate'));
- this._hasSideEffectSupport = supports;
- return supports;
+ this._hasSideEffectSupport = SDK.RuntimeModel.isSideEffectFailure(response);
+ return this._hasSideEffectSupport;
}
/**
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sdk/Script.js b/chromium/third_party/blink/renderer/devtools/front_end/sdk/Script.js
index 7a2a8228de7..14c5d7d2f08 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/sdk/Script.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk/Script.js
@@ -43,10 +43,11 @@ SDK.Script = class {
* @param {string|undefined} sourceMapURL
* @param {boolean} hasSourceURL
* @param {number} length
+ * @param {?Protocol.Runtime.StackTrace} originStackTrace
*/
constructor(
debuggerModel, scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash,
- isContentScript, isLiveEdit, sourceMapURL, hasSourceURL, length) {
+ isContentScript, isLiveEdit, sourceMapURL, hasSourceURL, length, originStackTrace) {
this.debuggerModel = debuggerModel;
this.scriptId = scriptId;
this.sourceURL = sourceURL;
@@ -64,6 +65,7 @@ SDK.Script = class {
this.contentLength = length;
this._originalContentProvider = null;
this._originalSource = null;
+ this.originStackTrace = originStackTrace;
}
/**
@@ -141,7 +143,10 @@ SDK.Script = class {
if (!this.scriptId)
return '';
const source = await this.debuggerModel.target().debuggerAgent().getScriptSource(this.scriptId);
- this._source = source ? SDK.Script._trimSourceURLComment(source) : '';
+ if (source && this.hasSourceURL)
+ this._source = SDK.Script._trimSourceURLComment(source);
+ else
+ this._source = source || '';
if (this._originalSource === null)
this._originalSource = this._source;
return this._source;
@@ -254,10 +259,7 @@ SDK.Script = class {
async setBlackboxedRanges(positions) {
const response = await this.debuggerModel.target().debuggerAgent().invoke_setBlackboxedRanges(
{scriptId: this.scriptId, positions});
- const error = response[Protocol.Error];
- if (error)
- console.error(error);
- return !error;
+ return !response[Protocol.Error];
}
};
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sdk/SourceMap.js b/chromium/third_party/blink/renderer/devtools/front_end/sdk/SourceMap.js
index 20c4181754b..1a40f512f05 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/sdk/SourceMap.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk/SourceMap.js
@@ -136,18 +136,6 @@ SDK.SourceMap.prototype = {
* @return {?SDK.SourceMapEntry}
*/
findEntry(lineNumber, columnNumber) {},
-
- /**
- * @return {boolean}
- */
- editable() {},
-
- /**
- * @param {!Array<!TextUtils.TextRange>} ranges
- * @param {!Array<string>} texts
- * @return {!Promise<?SDK.SourceMap.EditResult>}
- */
- editCompiled(ranges, texts) {},
};
/**
@@ -167,20 +155,6 @@ SDK.SourceMap.EditResult = class {
};
/**
- * @interface
- */
-SDK.SourceMapFactory = function() {};
-
-SDK.SourceMapFactory.prototype = {
- /**
- * @param {!SDK.Target} target
- * @param {!SDK.SourceMap} sourceMap
- * @return {!Promise<?SDK.SourceMap>}
- */
- editableSourceMap(target, sourceMap) {},
-};
-
-/**
* @implements {SDK.SourceMap}
* @unrestricted
*/
@@ -298,24 +272,6 @@ SDK.TextSourceMap = class {
/**
* @override
- * @return {boolean}
- */
- editable() {
- return false;
- }
-
- /**
- * @override
- * @param {!Array<!TextUtils.TextRange>} ranges
- * @param {!Array<string>} texts
- * @return {!Promise<?SDK.SourceMap.EditResult>}
- */
- editCompiled(ranges, texts) {
- return Promise.resolve(/** @type {?SDK.SourceMap.EditResult} */ (null));
- }
-
- /**
- * @override
* @param {number} lineNumber in compiled resource
* @param {number} columnNumber in compiled resource
* @return {?SDK.SourceMapEntry}
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sdk/SourceMapManager.js b/chromium/third_party/blink/renderer/devtools/front_end/sdk/SourceMapManager.js
index 0298991f1c8..6024d21cd0e 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/sdk/SourceMapManager.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk/SourceMapManager.js
@@ -141,31 +141,12 @@ SDK.SourceMapManager = class extends Common.Object {
}
if (!this._sourceMapURLToLoadingClients.has(sourceMapURL)) {
SDK.TextSourceMap.load(sourceMapURL, sourceURL)
- .then(onTextSourceMapLoaded.bind(this, sourceMapURL))
.then(onSourceMap.bind(this, sourceMapURL));
}
this._sourceMapURLToLoadingClients.set(sourceMapURL, client);
/**
* @param {string} sourceMapURL
- * @param {?SDK.TextSourceMap} sourceMap
- * @return {!Promise<?SDK.SourceMap>}
- * @this {SDK.SourceMapManager}
- */
- function onTextSourceMapLoaded(sourceMapURL, sourceMap) {
- if (!sourceMap)
- return Promise.resolve(/** @type {?SDK.SourceMap} */ (null));
- const factoryExtension = this._factoryForSourceMap(sourceMap);
- if (!factoryExtension)
- return Promise.resolve(/** @type {?SDK.SourceMap} */ (sourceMap));
- return factoryExtension.instance()
- .then(factory => factory.editableSourceMap(this._target, sourceMap))
- .then(map => map || sourceMap)
- .catchException(/** @type {?SDK.SourceMap} */ (null));
- }
-
- /**
- * @param {string} sourceMapURL
* @param {?SDK.SourceMap} sourceMap
* @this {SDK.SourceMapManager}
*/
@@ -199,22 +180,6 @@ SDK.SourceMapManager = class extends Common.Object {
}
/**
- * @param {!SDK.SourceMap} sourceMap
- * @return {?Runtime.Extension}
- */
- _factoryForSourceMap(sourceMap) {
- const sourceExtensions = new Set();
- for (const url of sourceMap.sourceURLs())
- sourceExtensions.add(Common.ParsedURL.extractExtension(url));
- for (const runtimeExtension of self.runtime.extensions(SDK.SourceMapFactory)) {
- const supportedExtensions = new Set(runtimeExtension.descriptor()['extensions']);
- if (supportedExtensions.containsAll(sourceExtensions))
- return runtimeExtension;
- }
- return null;
- }
-
- /**
* @param {!T} client
*/
detachSourceMap(client) {
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sdk/module.json b/chromium/third_party/blink/renderer/devtools/front_end/sdk/module.json
index 7edcfedf2c0..89048fb52ac 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/sdk/module.json
+++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk/module.json
@@ -284,6 +284,7 @@
"DOMModel.js",
"DebuggerModel.js",
"EmulationModel.js",
+ "HARLog.js",
"LayerTreeBase.js",
"LogModel.js",
"ServiceWorkerManager.js",
@@ -301,6 +302,7 @@
"SourceMap.js",
"SourceMapManager.js",
"NetworkManager.js",
+ "NetworkLog.js",
"NetworkRequest.js",
"PaintProfiler.js",
"HeapProfilerModel.js",
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sdk_test_runner/PageMockTestRunner.js b/chromium/third_party/blink/renderer/devtools/front_end/sdk_test_runner/PageMockTestRunner.js
index a6bf418966d..d062f78d520 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/sdk_test_runner/PageMockTestRunner.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/sdk_test_runner/PageMockTestRunner.js
@@ -190,7 +190,7 @@ SDKTestRunner.PageMock = class {
return true;
}
- _dispatch(id, methodName, params, message) {
+ _dispatch(id, methodName, params) {
const handler = (this._isSupportedDomain(methodName) ? this._dispatchMap[methodName] : null);
if (handler)
@@ -230,9 +230,8 @@ MockPageConnection = class {
setTimeout(() => this._onMessage.call(null, JSON.stringify(message)), 0);
}
- sendMessage(message) {
- const json = JSON.parse(message);
- this._page._dispatch(json.id, json.method, json.params, message);
+ sendMessage(domain, message) {
+ this._page._dispatch(message.id, message.method, message.params);
}
disconnect() {
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/snippets/ScriptSnippetFileSystem.js b/chromium/third_party/blink/renderer/devtools/front_end/snippets/ScriptSnippetFileSystem.js
new file mode 100644
index 00000000000..2f3c1c4ce4c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/devtools/front_end/snippets/ScriptSnippetFileSystem.js
@@ -0,0 +1,220 @@
+// 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.
+
+Snippets.SnippetFileSystem = class extends Persistence.PlatformFileSystem {
+ constructor() {
+ super('snippet://', 'snippets');
+ this._lastSnippetIdentifierSetting = Common.settings.createSetting('scriptSnippets_lastIdentifier', 0);
+ this._snippetsSetting = Common.settings.createSetting('scriptSnippets', []);
+ }
+
+ /**
+ * @override
+ * @return {!Array<string>}
+ */
+ initialFilePaths() {
+ const savedSnippets = this._snippetsSetting.get();
+ return savedSnippets.map(snippet => escape(snippet.name));
+ }
+
+ /**
+ * @override
+ * @param {string} path
+ * @param {?string} name
+ * @return {!Promise<?string>}
+ */
+ async createFile(path, name) {
+ const nextId = this._lastSnippetIdentifierSetting.get() + 1;
+ this._lastSnippetIdentifierSetting.set(nextId);
+
+ const snippetName = `Script snippet #${nextId}`;
+ const snippets = this._snippetsSetting.get();
+ snippets.push({name: snippetName, content: ''});
+ this._snippetsSetting.set(snippets);
+
+ return escape(snippetName);
+ }
+
+ /**
+ * @override
+ * @param {string} path
+ * @return {!Promise<boolean>}
+ */
+ async deleteFile(path) {
+ const name = unescape(path.substring(1));
+ const allSnippets = this._snippetsSetting.get();
+ const snippets = allSnippets.filter(snippet => snippet.name !== name);
+ if (allSnippets.length !== snippets.length) {
+ this._snippetsSetting.set(snippets);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * @override
+ * @param {string} path
+ * @param {function(?string,boolean)} callback
+ */
+ requestFileContent(path, callback) {
+ const name = unescape(path.substring(1));
+ const snippet = this._snippetsSetting.get().find(snippet => snippet.name === name);
+ callback(snippet ? snippet.content : null, /* encoded */ false);
+ }
+
+ /**
+ * @override
+ * @param {string} path
+ * @param {string} content
+ * @param {boolean} isBase64
+ */
+ async setFileContent(path, content, isBase64) {
+ const name = unescape(path.substring(1));
+ const snippets = this._snippetsSetting.get();
+ const snippet = snippets.find(snippet => snippet.name === name);
+ if (snippet) {
+ snippet.content = content;
+ this._snippetsSetting.set(snippets);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * @override
+ * @param {string} path
+ * @param {string} newName
+ * @param {function(boolean, string=)} callback
+ */
+ renameFile(path, newName, callback) {
+ const name = unescape(path.substring(1));
+ const snippets = this._snippetsSetting.get();
+ const snippet = snippets.find(snippet => snippet.name === name);
+ newName = newName.trim();
+ if (!snippet || newName.length === 0 || snippets.find(snippet => snippet.name === newName)) {
+ callback(false);
+ return;
+ }
+ snippet.name = newName;
+ this._snippetsSetting.set(snippets);
+ callback(true, newName);
+ }
+
+ /**
+ * @override
+ * @param {string} query
+ * @param {!Common.Progress} progress
+ * @return {!Promise<!Array<string>>}
+ */
+ async searchInPath(query, progress) {
+ const re = new RegExp(query.escapeForRegExp(), 'i');
+ const snippets = this._snippetsSetting.get().filter(snippet => snippet.content.match(re));
+ return snippets.map(snippet => escape(snippet.name));
+ }
+
+ /**
+ * @override
+ * @param {string} path
+ * @return {string}
+ */
+ mimeFromPath(path) {
+ return 'text/javascript';
+ }
+
+ /**
+ * @override
+ * @param {string} path
+ * @return {!Common.ResourceType}
+ */
+ contentType(path) {
+ return Common.resourceTypes.Script;
+ }
+
+ /**
+ * @override
+ * @param {string} url
+ * @return {string}
+ */
+ tooltipForURL(url) {
+ return ls`Linked to ${unescape(url.substring(this.path().length))}`;
+ }
+
+ /**
+ * @override
+ * @return {boolean}
+ */
+ supportsAutomapping() {
+ return true;
+ }
+};
+
+/**
+ * @param {!Workspace.UISourceCode} uiSourceCode
+ */
+Snippets.evaluateScriptSnippet = async function(uiSourceCode) {
+ if (!uiSourceCode.url().startsWith('snippet://'))
+ return;
+
+ const executionContext = UI.context.flavor(SDK.ExecutionContext);
+ if (!executionContext)
+ return;
+
+ const runtimeModel = executionContext.runtimeModel;
+
+ await uiSourceCode.requestContent();
+ uiSourceCode.commitWorkingCopy();
+ const expression = uiSourceCode.workingCopy();
+ Common.console.show();
+
+ const url = uiSourceCode.url();
+ let scriptId;
+ {
+ const result = await runtimeModel.compileScript(expression, url, true, executionContext.id);
+ if (!result.scriptId && !result.exceptionDetails)
+ return;
+ if (!result.scriptId) {
+ SDK.consoleModel.addMessage(SDK.ConsoleMessage.fromException(
+ runtimeModel, result.exceptionDetails, /* messageType */ undefined, /* timestamp */ undefined, url));
+ return;
+ }
+ scriptId = result.scriptId;
+ }
+ const result = await runtimeModel.runScript(
+ scriptId, executionContext.id, 'console', /* silent */ false, /* includeCommandLineAPI */ true,
+ /* returnByValue */ false, /* generatePreview */ true);
+ if (!result.object && !result.exceptionDetails)
+ return;
+ if (result.object) {
+ const consoleMessage = new SDK.ConsoleMessage(
+ runtimeModel, SDK.ConsoleMessage.MessageSource.JS, SDK.ConsoleMessage.MessageLevel.Info, '',
+ SDK.ConsoleMessage.MessageType.Result, url, undefined, undefined, [result.object], undefined, undefined,
+ executionContext.id, scriptId);
+ SDK.consoleModel.addMessage(consoleMessage);
+ } else {
+ SDK.consoleModel.addMessage(
+ SDK.ConsoleMessage.fromException(runtimeModel, result.exceptionDetails, undefined, undefined, url));
+ }
+};
+
+/**
+ * @param {!Workspace.UISourceCode} uiSourceCode
+ * @return {boolean}
+ */
+Snippets.isSnippetsUISourceCode = function(uiSourceCode) {
+ return uiSourceCode.url().startsWith('snippet://');
+};
+
+/**
+ * @param {!Workspace.Project} project
+ * @return {boolean}
+ */
+Snippets.isSnippetsProject = function(project) {
+ return project.type() === Workspace.projectTypes.FileSystem &&
+ Persistence.FileSystemWorkspaceBinding.fileSystemType(project) === 'snippets';
+};
+
+Persistence.isolatedFileSystemManager.addPlatformFileSystem('snippet://', new Snippets.SnippetFileSystem());
+Snippets.project = /** @type {!Workspace.Project} */ (
+ Workspace.workspace.projectsForType(Workspace.projectTypes.FileSystem)
+ .find(project => Persistence.FileSystemWorkspaceBinding.fileSystemType(project) === 'snippets'));
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/snippets/ScriptSnippetModel.js b/chromium/third_party/blink/renderer/devtools/front_end/snippets/ScriptSnippetModel.js
deleted file mode 100644
index 1420585297d..00000000000
--- a/chromium/third_party/blink/renderer/devtools/front_end/snippets/ScriptSnippetModel.js
+++ /dev/null
@@ -1,608 +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.
- */
-/**
- * @unrestricted
- * @implements {SDK.SDKModelObserver<!SDK.DebuggerModel>}
- * @implements {Bindings.DebuggerSourceMapping}
- */
-Snippets.ScriptSnippetModel = class extends Common.Object {
- /**
- * @param {!Workspace.Workspace} workspace
- */
- constructor(workspace) {
- super();
- this._workspace = workspace;
- /** @type {!Object.<string, !Workspace.UISourceCode>} */
- this._uiSourceCodeForSnippetId = {};
- /** @type {!Map.<!Workspace.UISourceCode, string>} */
- this._snippetIdForUISourceCode = new Map();
-
- /** @type {!Map.<!SDK.DebuggerModel, !Snippets.SnippetScriptMapping>} */
- this._mappingForDebuggerModel = new Map();
- this._snippetStorage = new Snippets.SnippetStorage('script', 'Script snippet #');
- this._lastSnippetEvaluationIndexSetting = Common.settings.createSetting('lastSnippetEvaluationIndex', 0);
- this._project = new Snippets.SnippetsProject(workspace, this);
- this._loadSnippets();
- SDK.targetManager.observeModels(SDK.DebuggerModel, this);
- Bindings.debuggerWorkspaceBinding.addSourceMapping(this);
- }
-
- /**
- * @override
- * @param {!SDK.DebuggerModel} debuggerModel
- */
- modelAdded(debuggerModel) {
- this._mappingForDebuggerModel.set(debuggerModel, new Snippets.SnippetScriptMapping(debuggerModel, this));
- }
-
- /**
- * @override
- * @param {!SDK.DebuggerModel} debuggerModel
- */
- modelRemoved(debuggerModel) {
- this._mappingForDebuggerModel.remove(debuggerModel);
- }
-
- /**
- * @override
- * @param {!SDK.DebuggerModel.Location} rawLocation
- * @return {?Workspace.UILocation}
- */
- rawLocationToUILocation(rawLocation) {
- const mapping = this._mappingForDebuggerModel.get(rawLocation.debuggerModel);
- if (!mapping)
- return null;
- return mapping.rawLocationToUILocation(rawLocation);
- }
-
- /**
- * @override
- * @param {!Workspace.UISourceCode} uiSourceCode
- * @param {number} lineNumber
- * @param {number} columnNumber
- * @return {?SDK.DebuggerModel.Location}
- */
- uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber) {
- for (const mapping of this._mappingForDebuggerModel.values()) {
- const rawLocation = mapping.uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber);
- if (rawLocation)
- return rawLocation;
- }
- return null;
- }
-
- /**
- * @param {!SDK.DebuggerModel} debuggerModel
- * @return {!Snippets.SnippetScriptMapping|undefined}
- */
- snippetScriptMapping(debuggerModel) {
- return this._mappingForDebuggerModel.get(debuggerModel);
- }
-
- /**
- * @return {!Workspace.Project}
- */
- project() {
- return this._project;
- }
-
- _loadSnippets() {
- for (const snippet of this._snippetStorage.snippets())
- this._addScriptSnippet(snippet);
- }
-
- /**
- * @param {string} content
- * @return {!Workspace.UISourceCode}
- */
- createScriptSnippet(content) {
- const snippet = this._snippetStorage.createSnippet();
- snippet.content = content;
- return this._addScriptSnippet(snippet);
- }
-
- /**
- * @param {!Snippets.Snippet} snippet
- * @return {!Workspace.UISourceCode}
- */
- _addScriptSnippet(snippet) {
- const uiSourceCode = this._project.addSnippet(snippet.name, new Snippets.SnippetContentProvider(snippet));
- uiSourceCode.addEventListener(Workspace.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this);
- this._snippetIdForUISourceCode.set(uiSourceCode, snippet.id);
- const breakpointLocations = this._removeBreakpoints(uiSourceCode);
- this._restoreBreakpoints(uiSourceCode, breakpointLocations);
- this._uiSourceCodeForSnippetId[snippet.id] = uiSourceCode;
- return uiSourceCode;
- }
-
- /**
- * @param {!Common.Event} event
- */
- _workingCopyChanged(event) {
- const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
- this._scriptSnippetEdited(uiSourceCode);
- }
-
- /**
- * @param {!Workspace.UISourceCode} uiSourceCode
- */
- deleteScriptSnippet(uiSourceCode) {
- const snippetId = this._snippetIdForUISourceCode.get(uiSourceCode) || '';
- const snippet = this._snippetStorage.snippetForId(snippetId);
- if (!snippet)
- return;
- this._snippetStorage.deleteSnippet(snippet);
- this._removeBreakpoints(uiSourceCode);
- this._releaseSnippetScript(uiSourceCode);
- delete this._uiSourceCodeForSnippetId[snippet.id];
- this._snippetIdForUISourceCode.remove(uiSourceCode);
- this._project.removeFile(snippet.name);
- }
-
- /**
- * @param {string} name
- * @param {string} newName
- * @param {function(boolean, string=)} callback
- */
- renameScriptSnippet(name, newName, callback) {
- newName = newName.trim();
- if (!newName || newName.indexOf('/') !== -1 || name === newName || this._snippetStorage.snippetForName(newName)) {
- callback(false);
- return;
- }
- const snippet = this._snippetStorage.snippetForName(name);
- console.assert(snippet, 'Snippet \'' + name + '\' was not found.');
- const uiSourceCode = this._uiSourceCodeForSnippetId[snippet.id];
- console.assert(uiSourceCode, 'No uiSourceCode was found for snippet \'' + name + '\'.');
-
- const breakpointLocations = this._removeBreakpoints(uiSourceCode);
- snippet.name = newName;
- this._restoreBreakpoints(uiSourceCode, breakpointLocations);
- callback(true, newName);
- }
-
- /**
- * @param {string} name
- * @param {string} newContent
- */
- _setScriptSnippetContent(name, newContent) {
- const snippet = this._snippetStorage.snippetForName(name);
- snippet.content = newContent;
- }
-
- /**
- * @param {!Workspace.UISourceCode} uiSourceCode
- */
- _scriptSnippetEdited(uiSourceCode) {
- const breakpointLocations = this._removeBreakpoints(uiSourceCode);
- this._releaseSnippetScript(uiSourceCode);
- this._restoreBreakpoints(uiSourceCode, breakpointLocations);
- this._mappingForDebuggerModel.valuesArray().forEach(function(mapping) {
- mapping._restoreBreakpoints(uiSourceCode, breakpointLocations);
- });
- }
-
- /**
- * @return {number}
- */
- _nextEvaluationIndex() {
- const evaluationIndex = this._lastSnippetEvaluationIndexSetting.get() + 1;
- this._lastSnippetEvaluationIndexSetting.set(evaluationIndex);
- return evaluationIndex;
- }
-
- /**
- * @param {!SDK.ExecutionContext} executionContext
- * @param {!Workspace.UISourceCode} uiSourceCode
- * @return {!Promise<undefined>}
- */
- async evaluateScriptSnippet(executionContext, uiSourceCode) {
- console.assert(uiSourceCode.project().type() === Workspace.projectTypes.Snippets);
- let breakpointLocations = this._removeBreakpoints(uiSourceCode);
- this._releaseSnippetScript(uiSourceCode);
- this._restoreBreakpoints(uiSourceCode, breakpointLocations);
-
- const runtimeModel = executionContext.runtimeModel;
- const debuggerModel = executionContext.debuggerModel;
- const evaluationIndex = this._nextEvaluationIndex();
- const mapping = this._mappingForDebuggerModel.get(debuggerModel);
- mapping._setEvaluationIndex(evaluationIndex, uiSourceCode);
- const evaluationUrl = mapping._evaluationSourceURL(uiSourceCode);
- await uiSourceCode.requestContent();
- const expression = uiSourceCode.workingCopy();
- Common.console.show();
- const result = await runtimeModel.compileScript(expression, '', true, executionContext.id);
- if (!result || mapping.evaluationIndex(uiSourceCode) !== evaluationIndex)
- return;
- const script = /** @type {!SDK.Script} */ (
- debuggerModel.scriptForId(/** @type {string} */ (result.scriptId || result.exceptionDetails.scriptId)));
- mapping._addScript(script, uiSourceCode);
- if (!result.scriptId) {
- this._printRunOrCompileScriptResultFailure(
- runtimeModel, /** @type {!Protocol.Runtime.ExceptionDetails} */ (result.exceptionDetails), evaluationUrl);
- return;
- }
-
- breakpointLocations = this._removeBreakpoints(uiSourceCode);
- this._restoreBreakpoints(uiSourceCode, breakpointLocations);
-
- this._runScript(script.scriptId, executionContext, evaluationUrl);
- }
-
- /**
- * @param {!Protocol.Runtime.ScriptId} scriptId
- * @param {!SDK.ExecutionContext} executionContext
- * @param {?string=} sourceURL
- */
- async _runScript(scriptId, executionContext, sourceURL) {
- const runtimeModel = executionContext.runtimeModel;
- const result = await runtimeModel.runScript(
- scriptId, executionContext.id, 'console', /* silent */ false, /* includeCommandLineAPI */ true,
- /* returnByValue */ false, /* generatePreview */ true);
- if (result.error)
- return;
- if (!result.exceptionDetails)
- this._printRunScriptResult(runtimeModel, result.object || null, scriptId, sourceURL);
- else
- this._printRunOrCompileScriptResultFailure(runtimeModel, result.exceptionDetails, sourceURL);
- }
-
- /**
- * @param {!SDK.RuntimeModel} runtimeModel
- * @param {?SDK.RemoteObject} result
- * @param {!Protocol.Runtime.ScriptId} scriptId
- * @param {?string=} sourceURL
- */
- _printRunScriptResult(runtimeModel, result, scriptId, sourceURL) {
- const consoleMessage = new SDK.ConsoleMessage(
- runtimeModel, SDK.ConsoleMessage.MessageSource.JS, SDK.ConsoleMessage.MessageLevel.Info, '',
- SDK.ConsoleMessage.MessageType.Result, sourceURL, undefined, undefined, [result], undefined, undefined,
- undefined, scriptId);
- SDK.consoleModel.addMessage(consoleMessage);
- }
-
- /**
- * @param {!SDK.RuntimeModel} runtimeModel
- * @param {!Protocol.Runtime.ExceptionDetails} exceptionDetails
- * @param {?string=} sourceURL
- */
- _printRunOrCompileScriptResultFailure(runtimeModel, exceptionDetails, sourceURL) {
- SDK.consoleModel.addMessage(
- SDK.ConsoleMessage.fromException(runtimeModel, exceptionDetails, undefined, undefined, sourceURL || undefined));
- }
-
- /**
- * @param {!Workspace.UISourceCode} uiSourceCode
- * @return {!Array.<!{breakpoint: !Bindings.BreakpointManager.Breakpoint, uiLocation: !Workspace.UILocation}>}
- */
- _removeBreakpoints(uiSourceCode) {
- const breakpointLocations = Bindings.breakpointManager.breakpointLocationsForUISourceCode(uiSourceCode);
- for (let i = 0; i < breakpointLocations.length; ++i)
- breakpointLocations[i].breakpoint.remove(false /* keepInStorage */);
- return breakpointLocations;
- }
-
- /**
- * @param {!Workspace.UISourceCode} uiSourceCode
- * @param {!Array.<!{breakpoint: !Bindings.BreakpointManager.Breakpoint, uiLocation: !Workspace.UILocation}>} breakpointLocations
- */
- _restoreBreakpoints(uiSourceCode, breakpointLocations) {
- for (let i = 0; i < breakpointLocations.length; ++i) {
- const uiLocation = breakpointLocations[i].uiLocation;
- const breakpoint = breakpointLocations[i].breakpoint;
- Bindings.breakpointManager.setBreakpoint(
- uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber, breakpoint.condition(), breakpoint.enabled());
- }
- }
-
- /**
- * @param {!Workspace.UISourceCode} uiSourceCode
- */
- _releaseSnippetScript(uiSourceCode) {
- this._mappingForDebuggerModel.valuesArray().forEach(function(mapping) {
- mapping._releaseSnippetScript(uiSourceCode);
- });
- }
-
- /**
- * @param {string} sourceURL
- * @return {?string}
- */
- _snippetIdForSourceURL(sourceURL) {
- const snippetPrefix = Snippets.ScriptSnippetModel.snippetSourceURLPrefix;
- if (!sourceURL.startsWith(snippetPrefix))
- return null;
- const splitURL = sourceURL.substring(snippetPrefix.length).split('_');
- const snippetId = splitURL[0];
- return snippetId;
- }
-};
-
-Snippets.ScriptSnippetModel.snippetSourceURLPrefix = 'snippets:///';
-
-/**
- * @unrestricted
- */
-Snippets.SnippetScriptMapping = class {
- /**
- * @param {!SDK.DebuggerModel} debuggerModel
- * @param {!Snippets.ScriptSnippetModel} scriptSnippetModel
- */
- constructor(debuggerModel, scriptSnippetModel) {
- this._debuggerModel = debuggerModel;
- this._scriptSnippetModel = scriptSnippetModel;
- /** @type {!Object.<string, !Workspace.UISourceCode>} */
- this._uiSourceCodeForScriptId = {};
- /** @type {!Map.<!Workspace.UISourceCode, !SDK.Script>} */
- this._scriptForUISourceCode = new Map();
- /** @type {!Map.<!Workspace.UISourceCode, number>} */
- this._evaluationIndexForUISourceCode = new Map();
- debuggerModel.addEventListener(SDK.DebuggerModel.Events.GlobalObjectCleared, this._reset, this);
- }
-
- /**
- * @param {!Workspace.UISourceCode} uiSourceCode
- */
- _releaseSnippetScript(uiSourceCode) {
- const script = this._scriptForUISourceCode.get(uiSourceCode);
- if (!script)
- return;
-
- delete this._uiSourceCodeForScriptId[script.scriptId];
- this._scriptForUISourceCode.remove(uiSourceCode);
- this._evaluationIndexForUISourceCode.remove(uiSourceCode);
- }
-
- /**
- * @param {number} evaluationIndex
- * @param {!Workspace.UISourceCode} uiSourceCode
- */
- _setEvaluationIndex(evaluationIndex, uiSourceCode) {
- this._evaluationIndexForUISourceCode.set(uiSourceCode, evaluationIndex);
- }
-
- /**
- * @param {!Workspace.UISourceCode} uiSourceCode
- * @return {number|undefined}
- */
- evaluationIndex(uiSourceCode) {
- return this._evaluationIndexForUISourceCode.get(uiSourceCode);
- }
-
- /**
- * @param {!Workspace.UISourceCode} uiSourceCode
- * @return {string}
- */
- _evaluationSourceURL(uiSourceCode) {
- const evaluationSuffix = '_' + this._evaluationIndexForUISourceCode.get(uiSourceCode);
- const snippetId = this._scriptSnippetModel._snippetIdForUISourceCode.get(uiSourceCode);
- return Snippets.ScriptSnippetModel.snippetSourceURLPrefix + snippetId + evaluationSuffix;
- }
-
- _reset() {
- this._uiSourceCodeForScriptId = {};
- this._scriptForUISourceCode.clear();
- this._evaluationIndexForUISourceCode.clear();
- }
-
- /**
- * @param {!SDK.DebuggerModel.Location} rawLocation
- * @return {?Workspace.UILocation}
- */
- rawLocationToUILocation(rawLocation) {
- const debuggerModelLocation = /** @type {!SDK.DebuggerModel.Location} */ (rawLocation);
- const uiSourceCode = this._uiSourceCodeForScriptId[debuggerModelLocation.scriptId];
- if (!uiSourceCode)
- return null;
-
- return uiSourceCode.uiLocation(debuggerModelLocation.lineNumber, debuggerModelLocation.columnNumber || 0);
- }
-
- /**
- * @param {!Workspace.UISourceCode} uiSourceCode
- * @param {number} lineNumber
- * @param {number} columnNumber
- * @return {?SDK.DebuggerModel.Location}
- */
- uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber) {
- const script = this._scriptForUISourceCode.get(uiSourceCode);
- if (!script)
- return null;
-
- return this._debuggerModel.createRawLocation(script, lineNumber, columnNumber);
- }
-
- /**
- * @param {!SDK.Script} script
- * @param {!Workspace.UISourceCode} uiSourceCode
- */
- _addScript(script, uiSourceCode) {
- console.assert(!this._scriptForUISourceCode.get(uiSourceCode));
- this._uiSourceCodeForScriptId[script.scriptId] = uiSourceCode;
- this._scriptForUISourceCode.set(uiSourceCode, script);
- Bindings.debuggerWorkspaceBinding.updateLocations(script);
- }
-
- /**
- * @param {!Workspace.UISourceCode} uiSourceCode
- * @param {!Array.<!{breakpoint: !Bindings.BreakpointManager.Breakpoint, uiLocation: !Workspace.UILocation}>} breakpointLocations
- */
- _restoreBreakpoints(uiSourceCode, breakpointLocations) {
- const script = this._scriptForUISourceCode.get(uiSourceCode);
- if (!script)
- return;
- const rawLocation =
- /** @type {!SDK.DebuggerModel.Location} */ (this._debuggerModel.createRawLocation(script, 0, 0));
- const uiLocation = Bindings.debuggerWorkspaceBinding.rawLocationToUILocation(rawLocation);
- if (uiLocation)
- this._scriptSnippetModel._restoreBreakpoints(uiLocation.uiSourceCode, breakpointLocations);
- }
-};
-
-/**
- * @implements {Common.ContentProvider}
- * @unrestricted
- */
-Snippets.SnippetContentProvider = class {
- /**
- * @param {!Snippets.Snippet} snippet
- */
- constructor(snippet) {
- this._snippet = snippet;
- }
-
- /**
- * @override
- * @return {string}
- */
- contentURL() {
- return '';
- }
-
- /**
- * @override
- * @return {!Common.ResourceType}
- */
- contentType() {
- return Common.resourceTypes.Snippet;
- }
-
- /**
- * @override
- * @return {!Promise<boolean>}
- */
- contentEncoded() {
- return Promise.resolve(false);
- }
-
- /**
- * @override
- * @return {!Promise<?string>}
- */
- requestContent() {
- return Promise.resolve(/** @type {?string} */ (this._snippet.content));
- }
-
- /**
- * @override
- * @param {string} query
- * @param {boolean} caseSensitive
- * @param {boolean} isRegex
- * @return {!Promise<!Array<!Common.ContentProvider.SearchMatch>>}
- */
- async searchInContent(query, caseSensitive, isRegex) {
- return Common.ContentProvider.performSearchInContent(this._snippet.content, query, caseSensitive, isRegex);
- }
-};
-
-/**
- * @unrestricted
- */
-Snippets.SnippetsProject = class extends Bindings.ContentProviderBasedProject {
- /**
- * @param {!Workspace.Workspace} workspace
- * @param {!Snippets.ScriptSnippetModel} model
- */
- constructor(workspace, model) {
- super(workspace, 'snippets:', Workspace.projectTypes.Snippets, '', false /* isServiceProject */);
- this._model = model;
- }
-
- /**
- * @param {string} name
- * @param {!Common.ContentProvider} contentProvider
- * @return {!Workspace.UISourceCode}
- */
- addSnippet(name, contentProvider) {
- return this.addContentProvider(name, contentProvider, 'text/javascript');
- }
-
- /**
- * @override
- * @return {boolean}
- */
- canSetFileContent() {
- return true;
- }
-
- /**
- * @override
- * @param {!Workspace.UISourceCode} uiSourceCode
- * @param {string} newContent
- * @param {boolean} isBase64
- * @return {!Promise}
- */
- async setFileContent(uiSourceCode, newContent, isBase64) {
- this._model._setScriptSnippetContent(uiSourceCode.url(), newContent);
- }
-
- /**
- * @override
- * @return {boolean}
- */
- canRename() {
- return true;
- }
-
- /**
- * @override
- * @param {string} url
- * @param {string} newName
- * @param {function(boolean, string=)} callback
- */
- performRename(url, newName, callback) {
- this._model.renameScriptSnippet(url, newName, callback);
- }
-
- /**
- * @override
- * @param {string} url
- * @param {?string} name
- * @param {string} content
- * @param {boolean=} isBase64
- * @return {!Promise<?Workspace.UISourceCode>}
- */
- createFile(url, name, content, isBase64) {
- return /** @type {!Promise<?Workspace.UISourceCode>} */ (Promise.resolve(this._model.createScriptSnippet(content)));
- }
-
- /**
- * @override
- * @param {!Workspace.UISourceCode} uiSourceCode
- */
- deleteFile(uiSourceCode) {
- this._model.deleteScriptSnippet(uiSourceCode);
- }
-};
-
-/**
- * @type {!Snippets.ScriptSnippetModel}
- */
-Snippets.scriptSnippetModel = new Snippets.ScriptSnippetModel(Workspace.workspace);
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/snippets/SnippetStorage.js b/chromium/third_party/blink/renderer/devtools/front_end/snippets/SnippetStorage.js
deleted file mode 100644
index 3f0bff09db1..00000000000
--- a/chromium/third_party/blink/renderer/devtools/front_end/snippets/SnippetStorage.js
+++ /dev/null
@@ -1,200 +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.
- */
-
-/**
- * @unrestricted
- */
-Snippets.SnippetStorage = class extends Common.Object {
- constructor(settingPrefix, namePrefix) {
- super();
- /** @type {!Map<string,!Snippets.Snippet>} */
- this._snippets = new Map();
-
- this._lastSnippetIdentifierSetting = Common.settings.createSetting(settingPrefix + 'Snippets_lastIdentifier', 0);
- this._snippetsSetting = Common.settings.createSetting(settingPrefix + 'Snippets', []);
- this._namePrefix = namePrefix;
-
- this._loadSettings();
- }
-
- get namePrefix() {
- return this._namePrefix;
- }
-
- _saveSettings() {
- const savedSnippets = [];
- for (const snippet of this._snippets.values())
- savedSnippets.push(snippet.serializeToObject());
- this._snippetsSetting.set(savedSnippets);
- }
-
- /**
- * @return {!Array<!Snippets.Snippet>}
- */
- snippets() {
- return this._snippets.valuesArray();
- }
-
- /**
- * @param {string} id
- * @return {?Snippets.Snippet}
- */
- snippetForId(id) {
- return this._snippets.get(id);
- }
-
- /**
- * @param {string} name
- * @return {?Snippets.Snippet}
- */
- snippetForName(name) {
- for (const snippet of this._snippets.values()) {
- if (snippet.name === name)
- return snippet;
- }
- return null;
- }
-
- _loadSettings() {
- const savedSnippets = this._snippetsSetting.get();
- for (let i = 0; i < savedSnippets.length; ++i)
- this._snippetAdded(Snippets.Snippet.fromObject(this, savedSnippets[i]));
- }
-
- /**
- * @param {!Snippets.Snippet} snippet
- */
- deleteSnippet(snippet) {
- this._snippets.delete(snippet.id);
- this._saveSettings();
- }
-
- /**
- * @return {!Snippets.Snippet}
- */
- createSnippet() {
- const nextId = this._lastSnippetIdentifierSetting.get() + 1;
- const snippetId = String(nextId);
- this._lastSnippetIdentifierSetting.set(nextId);
- const snippet = new Snippets.Snippet(this, snippetId);
- this._snippetAdded(snippet);
- this._saveSettings();
- return snippet;
- }
-
- /**
- * @param {!Snippets.Snippet} snippet
- */
- _snippetAdded(snippet) {
- this._snippets.set(snippet.id, snippet);
- }
-};
-
-/**
- * @unrestricted
- */
-Snippets.Snippet = class extends Common.Object {
- /**
- * @param {!Snippets.SnippetStorage} storage
- * @param {string} id
- * @param {string=} name
- * @param {string=} content
- */
- constructor(storage, id, name, content) {
- super();
- this._storage = storage;
- this._id = id;
- this._name = name || storage.namePrefix + id;
- this._content = content || '';
- }
-
- /**
- * @param {!Snippets.SnippetStorage} storage
- * @param {!Object} serializedSnippet
- * @return {!Snippets.Snippet}
- */
- static fromObject(storage, serializedSnippet) {
- return new Snippets.Snippet(storage, serializedSnippet.id, serializedSnippet.name, serializedSnippet.content);
- }
-
- /**
- * @return {string}
- */
- get id() {
- return this._id;
- }
-
- /**
- * @return {string}
- */
- get name() {
- return this._name;
- }
-
- /**
- * @param {string} name
- */
- set name(name) {
- if (this._name === name)
- return;
-
- this._name = name;
- this._storage._saveSettings();
- }
-
- /**
- * @return {string}
- */
- get content() {
- return this._content;
- }
-
- /**
- * @param {string} content
- */
- set content(content) {
- if (this._content === content)
- return;
-
- this._content = content;
- this._storage._saveSettings();
- }
-
- /**
- * @return {!Object}
- */
- serializeToObject() {
- const serializedSnippet = {};
- serializedSnippet.id = this.id;
- serializedSnippet.name = this.name;
- serializedSnippet.content = this.content;
- return serializedSnippet;
- }
-};
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/snippets/SnippetsQuickOpen.js b/chromium/third_party/blink/renderer/devtools/front_end/snippets/SnippetsQuickOpen.js
index ba86f8d37f0..c48bf1ab339 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/snippets/SnippetsQuickOpen.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/snippets/SnippetsQuickOpen.js
@@ -16,9 +16,7 @@ Snippets.SnippetsQuickOpen = class extends QuickOpen.FilteredListWidget.Provider
selectItem(itemIndex, promptValue) {
if (itemIndex === null)
return;
- const currentExecutionContext = UI.context.flavor(SDK.ExecutionContext);
- if (currentExecutionContext)
- Snippets.scriptSnippetModel.evaluateScriptSnippet(currentExecutionContext, this._snippets[itemIndex]);
+ Snippets.evaluateScriptSnippet(this._snippets[itemIndex]);
}
/**
@@ -34,7 +32,7 @@ Snippets.SnippetsQuickOpen = class extends QuickOpen.FilteredListWidget.Provider
* @override
*/
attach() {
- this._snippets = Snippets.scriptSnippetModel.project().uiSourceCodes();
+ this._snippets = Snippets.project.uiSourceCodes();
}
/**
@@ -70,7 +68,7 @@ Snippets.SnippetsQuickOpen = class extends QuickOpen.FilteredListWidget.Provider
* @param {!Element} subtitleElement
*/
renderItem(itemIndex, query, titleElement, subtitleElement) {
- titleElement.textContent = this._snippets[itemIndex].name();
+ titleElement.textContent = unescape(this._snippets[itemIndex].name());
titleElement.classList.add('monospace');
QuickOpen.FilteredListWidget.highlightRanges(titleElement, query, true);
}
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/snippets/module.json b/chromium/third_party/blink/renderer/devtools/front_end/snippets/module.json
index 79774a6b7fb..a5c80f51009 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/snippets/module.json
+++ b/chromium/third_party/blink/renderer/devtools/front_end/snippets/module.json
@@ -7,10 +7,9 @@
"className": "Snippets.SnippetsQuickOpen"
}
],
- "dependencies": ["bindings", "quick_open"],
+ "dependencies": ["bindings", "quick_open", "persistence"],
"scripts": [
- "SnippetStorage.js",
- "ScriptSnippetModel.js",
+ "ScriptSnippetFileSystem.js",
"SnippetsQuickOpen.js"
]
}
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/source_frame/JSONView.js b/chromium/third_party/blink/renderer/devtools/front_end/source_frame/JSONView.js
index e49356679f9..7199d3ece3e 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/source_frame/JSONView.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/source_frame/JSONView.js
@@ -166,7 +166,8 @@ SourceFrame.JSONView = class extends UI.VBox {
const obj = SDK.RemoteObject.fromLocalObject(this._parsedJSON.data);
const title = this._parsedJSON.prefix + obj.description + this._parsedJSON.suffix;
- this._treeOutline = new ObjectUI.ObjectPropertiesSection(obj, title);
+ this._treeOutline = new ObjectUI.ObjectPropertiesSection(
+ obj, title, undefined, undefined, undefined, undefined, true /* showOverflow */);
this._treeOutline.enableContextMenu();
this._treeOutline.setEditable(false);
this._treeOutline.expand();
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/CallStackSidebarPane.js b/chromium/third_party/blink/renderer/devtools/front_end/sources/CallStackSidebarPane.js
index 0f4a03f1e63..c0285a1c80b 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/sources/CallStackSidebarPane.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/CallStackSidebarPane.js
@@ -52,12 +52,14 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView {
this.contentElement.appendChild(this._showMoreMessageElement);
this._showBlackboxed = false;
- Bindings.blackboxManager.addChangeListener(this._update.bind(this));
this._locationPool = new Bindings.LiveLocationPool();
this._updateThrottler = new Common.Throttler(100);
this._maxAsyncStackChainDepth = Sources.CallStackSidebarPane._defaultMaxAsyncStackChainDepth;
this._update();
+
+ this._updateItemThrottler = new Common.Throttler(100);
+ this._scheduledForUpdateItems = new Set();
}
/**
@@ -93,17 +95,12 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView {
let debuggerModel = details.debuggerModel;
this._notPausedMessageElement.classList.add('hidden');
- const showBlackboxed = this._showBlackboxed ||
- details.callFrames.every(frame => Bindings.blackboxManager.isBlackboxedRawLocation(frame.location()));
-
- let hiddenCallFramesCount = 0;
- let items = details.callFrames.map(frame => ({debuggerCallFrame: frame, debuggerModel: debuggerModel}));
- if (!showBlackboxed) {
- items = items.filter(
- item => !Bindings.blackboxManager.isBlackboxedRawLocation(
- /** @type {!SDK.DebuggerModel.Location} */ (this._itemLocation(item))));
- hiddenCallFramesCount += details.callFrames.length - items.length;
- }
+ const items = details.callFrames.map(frame => {
+ const item = Sources.CallStackSidebarPane.Item.createForDebuggerCallFrame(
+ frame, this._locationPool, this._refreshItem.bind(this));
+ item[Sources.CallStackSidebarPane._debuggerCallFrameSymbol] = frame;
+ return item;
+ });
let asyncStackTrace = details.asyncStackTrace;
if (!asyncStackTrace && details.asyncStackTraceId) {
@@ -124,19 +121,8 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView {
title = UI.asyncStackTraceLabel(asyncStackTrace.description);
}
- let asyncItems =
- asyncStackTrace.callFrames.map(frame => ({runtimeCallFrame: frame, debuggerModel: debuggerModel}));
- if (!showBlackboxed) {
- asyncItems = asyncItems.filter(
- item => !Bindings.blackboxManager.isBlackboxedRawLocation(
- /** @type {!SDK.DebuggerModel.Location} */ (this._itemLocation(item))));
- hiddenCallFramesCount += asyncStackTrace.callFrames.length - asyncItems.length;
- }
-
- if (asyncItems.length) {
- items.push({asyncStackHeader: title});
- items = items.concat(asyncItems);
- }
+ items.push(...Sources.CallStackSidebarPane.Item.createItemsForAsyncStack(
+ title, debuggerModel, asyncStackTrace.callFrames, this._locationPool, this._refreshItem.bind(this)));
--maxAsyncStackChainDepth;
peviousStackTrace = asyncStackTrace.callFrames;
@@ -150,24 +136,7 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView {
asyncStackTrace = null;
}
}
- if (asyncStackTrace)
- this._showMoreMessageElement.classList.remove('hidden');
- else
- this._showMoreMessageElement.classList.add('hidden');
-
- if (!hiddenCallFramesCount) {
- this._blackboxedMessageElement.classList.add('hidden');
- } else {
- if (hiddenCallFramesCount === 1) {
- this._blackboxedMessageElement.firstChild.textContent =
- Common.UIString('1 stack frame is hidden (blackboxed).');
- } else {
- this._blackboxedMessageElement.firstChild.textContent =
- Common.UIString('%d stack frames are hidden (blackboxed).', hiddenCallFramesCount);
- }
- this._blackboxedMessageElement.classList.remove('hidden');
- }
-
+ this._showMoreMessageElement.classList.toggle('hidden', !asyncStackTrace);
this._items.replaceAll(items);
if (this._maxAsyncStackChainDepth === Sources.CallStackSidebarPane._defaultMaxAsyncStackChainDepth)
this._list.selectNextItem(true /* canWrap */, false /* center */);
@@ -178,6 +147,43 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView {
}
/**
+ * @param {!Sources.CallStackSidebarPane.Item} item
+ */
+ _refreshItem(item) {
+ this._scheduledForUpdateItems.add(item);
+ this._updateItemThrottler.schedule(innerUpdate.bind(this));
+
+ /**
+ * @this {!Sources.CallStackSidebarPane}
+ * @return {!Promise<undefined>}
+ */
+ function innerUpdate() {
+ const items = Array.from(this._scheduledForUpdateItems);
+ this._scheduledForUpdateItems.clear();
+
+ this._muteActivateItem = true;
+ if (!this._showBlackboxed && this._items.every(item => item.isBlackboxed)) {
+ this._showBlackboxed = true;
+ for (let i = 0; i < this._items.length; ++i)
+ this._list.refreshItemByIndex(i);
+ this._blackboxedMessageElement.classList.toggle('hidden', true);
+ } else {
+ const itemsSet = new Set(items);
+ let hasBlackboxed = false;
+ for (let i = 0; i < this._items.length; ++i) {
+ const item = this._items.at(i);
+ if (itemsSet.has(item))
+ this._list.refreshItemByIndex(i);
+ hasBlackboxed = hasBlackboxed || item.isBlackboxed;
+ }
+ this._blackboxedMessageElement.classList.toggle('hidden', this._showBlackboxed || !hasBlackboxed);
+ }
+ delete this._muteActivateItem;
+ return Promise.resolve();
+ }
+ }
+
+ /**
* @override
* @param {!Sources.CallStackSidebarPane.Item} item
* @return {!Element}
@@ -185,31 +191,16 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView {
createElementForItem(item) {
const element = createElementWithClass('div', 'call-frame-item');
const title = element.createChild('div', 'call-frame-item-title');
- title.createChild('div', 'call-frame-title-text').textContent = this._itemTitle(item);
- if (item.asyncStackHeader)
+ title.createChild('div', 'call-frame-title-text').textContent = item.title;
+ if (item.isAsyncHeader) {
element.classList.add('async-header');
-
- const location = this._itemLocation(item);
- if (location) {
- if (Bindings.blackboxManager.isBlackboxedRawLocation(location))
- element.classList.add('blackboxed-call-frame');
-
- /**
- * @param {!Bindings.LiveLocation} liveLocation
- */
- function updateLocation(liveLocation) {
- const uiLocation = liveLocation.uiLocation();
- if (!uiLocation)
- return;
- const text = uiLocation.linkText();
- linkElement.textContent = text.trimMiddle(30);
- linkElement.title = text;
- }
-
+ } else {
const linkElement = element.createChild('div', 'call-frame-location');
- Bindings.debuggerWorkspaceBinding.createCallFrameLiveLocation(location, updateLocation, this._locationPool);
+ linkElement.textContent = item.linkText.trimMiddle(30);
+ linkElement.title = item.linkText;
+ element.classList.toggle('blackboxed-call-frame', item.isBlackboxed);
}
-
+ element.classList.toggle('hidden', !this._showBlackboxed && item.isBlackboxed);
element.appendChild(UI.Icon.create('smallicon-thick-right-arrow', 'selected-call-frame-icon'));
return element;
}
@@ -230,7 +221,7 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView {
* @return {boolean}
*/
isItemSelectable(item) {
- return !!item.debuggerCallFrame;
+ return !!item[Sources.CallStackSidebarPane._debuggerCallFrameSymbol];
}
/**
@@ -250,45 +241,19 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView {
}
/**
- * @param {!Sources.CallStackSidebarPane.Item} item
- * @return {string}
- */
- _itemTitle(item) {
- if (item.debuggerCallFrame)
- return UI.beautifyFunctionName(item.debuggerCallFrame.functionName);
- if (item.runtimeCallFrame)
- return UI.beautifyFunctionName(item.runtimeCallFrame.functionName);
- return item.asyncStackHeader || '';
- }
-
- /**
- * @param {!Sources.CallStackSidebarPane.Item} item
- * @return {?SDK.DebuggerModel.Location}
- */
- _itemLocation(item) {
- if (item.debuggerCallFrame)
- return item.debuggerCallFrame.location();
- if (!item.debuggerModel)
- return null;
- if (item.runtimeCallFrame) {
- const frame = item.runtimeCallFrame;
- return new SDK.DebuggerModel.Location(item.debuggerModel, frame.scriptId, frame.lineNumber, frame.columnNumber);
- }
- return null;
- }
-
- /**
* @return {!Element}
*/
_createBlackboxedMessageElement() {
const element = createElementWithClass('div', 'blackboxed-message');
element.createChild('span');
const showAllLink = element.createChild('span', 'link');
- showAllLink.textContent = Common.UIString('Show');
+ showAllLink.textContent = Common.UIString('Show blackboxed frames');
showAllLink.addEventListener('click', () => {
this._showBlackboxed = true;
- this._update();
- }, false);
+ for (const item of this._items)
+ this._refreshItem(item);
+ this._blackboxedMessageElement.classList.toggle('hidden', true);
+ });
return element;
}
@@ -315,13 +280,12 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView {
if (!item)
return;
const contextMenu = new UI.ContextMenu(event);
- if (item.debuggerCallFrame)
- contextMenu.defaultSection().appendItem(Common.UIString('Restart frame'), () => item.debuggerCallFrame.restart());
+ const debuggerCallFrame = item[Sources.CallStackSidebarPane._debuggerCallFrameSymbol];
+ if (debuggerCallFrame)
+ contextMenu.defaultSection().appendItem(Common.UIString('Restart frame'), () => debuggerCallFrame.restart());
contextMenu.defaultSection().appendItem(Common.UIString('Copy stack trace'), this._copyStackTrace.bind(this));
- const location = this._itemLocation(item);
- const uiLocation = location ? Bindings.debuggerWorkspaceBinding.rawLocationToUILocation(location) : null;
- if (uiLocation)
- this.appendBlackboxURLContextMenuItems(contextMenu, uiLocation.uiSourceCode);
+ if (item.uiLocation)
+ this.appendBlackboxURLContextMenuItems(contextMenu, item.uiLocation.uiSourceCode);
contextMenu.show();
}
@@ -338,14 +302,15 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView {
* @param {!Sources.CallStackSidebarPane.Item} item
*/
_activateItem(item) {
- const location = this._itemLocation(item);
- if (!location)
+ const uiLocation = item.uiLocation;
+ if (this._muteActivateItem || !uiLocation)
return;
- if (item.debuggerCallFrame && UI.context.flavor(SDK.DebuggerModel.CallFrame) !== item.debuggerCallFrame) {
- item.debuggerModel.setSelectedCallFrame(item.debuggerCallFrame);
- UI.context.setFlavor(SDK.DebuggerModel.CallFrame, item.debuggerCallFrame);
+ const debuggerCallFrame = item[Sources.CallStackSidebarPane._debuggerCallFrameSymbol];
+ if (debuggerCallFrame && UI.context.flavor(SDK.DebuggerModel.CallFrame) !== debuggerCallFrame) {
+ debuggerCallFrame.debuggerModel.setSelectedCallFrame(debuggerCallFrame);
+ UI.context.setFlavor(SDK.DebuggerModel.CallFrame, debuggerCallFrame);
} else {
- Common.Revealer.reveal(Bindings.debuggerWorkspaceBinding.rawLocationToUILocation(location));
+ Common.Revealer.reveal(uiLocation);
}
}
@@ -401,30 +366,20 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView {
_copyStackTrace() {
const text = [];
for (const item of this._items) {
- let itemText = this._itemTitle(item);
- const location = this._itemLocation(item);
- const uiLocation = location ? Bindings.debuggerWorkspaceBinding.rawLocationToUILocation(location) : null;
- if (uiLocation)
- itemText += ' (' + uiLocation.linkText(true /* skipTrim */) + ')';
+ let itemText = item.title;
+ if (item.uiLocation)
+ itemText += ' (' + item.uiLocation.linkText(true /* skipTrim */) + ')';
text.push(itemText);
}
InspectorFrontendHost.copyText(text.join('\n'));
}
};
+Sources.CallStackSidebarPane._debuggerCallFrameSymbol = Symbol('debuggerCallFrame');
+Sources.CallStackSidebarPane._elementSymbol = Symbol('element');
Sources.CallStackSidebarPane._defaultMaxAsyncStackChainDepth = 32;
/**
- * @typedef {{
- * debuggerCallFrame: (SDK.DebuggerModel.CallFrame|undefined),
- * asyncStackHeader: (string|undefined),
- * runtimeCallFrame: (Protocol.Runtime.CallFrame|undefined),
- * debuggerModel: (!SDK.DebuggerModel|undefined)
- * }}
- */
-Sources.CallStackSidebarPane.Item;
-
-/**
* @implements {UI.ActionDelegate}
*/
Sources.CallStackSidebarPane.ActionDelegate = class {
@@ -447,3 +402,94 @@ Sources.CallStackSidebarPane.ActionDelegate = class {
return false;
}
};
+
+Sources.CallStackSidebarPane.Item = class {
+ /**
+ * @param {!SDK.DebuggerModel.CallFrame} frame
+ * @param {!Bindings.LiveLocationPool} locationPool
+ * @param {function(!Sources.CallStackSidebarPane.Item)} updateDelegate
+ * @return {!Sources.CallStackSidebarPane.Item}
+ */
+ static createForDebuggerCallFrame(frame, locationPool, updateDelegate) {
+ const item = new Sources.CallStackSidebarPane.Item(UI.beautifyFunctionName(frame.functionName), updateDelegate);
+ Bindings.debuggerWorkspaceBinding.createCallFrameLiveLocation(
+ frame.location(), item._update.bind(item), locationPool);
+ return item;
+ }
+
+ /**
+ * @param {string} title
+ * @param {?SDK.DebuggerModel} debuggerModel
+ * @param {!Array<!Protocol.Runtime.CallFrame>} frames
+ * @param {!Bindings.LiveLocationPool} locationPool
+ * @param {function(!Sources.CallStackSidebarPane.Item)} updateDelegate
+ * @return {!Array<!Sources.CallStackSidebarPane.Item>}
+ */
+ static createItemsForAsyncStack(title, debuggerModel, frames, locationPool, updateDelegate) {
+ const whiteboxedItemsSymbol = Symbol('whiteboxedItems');
+ const asyncHeaderItem = new Sources.CallStackSidebarPane.Item(title, updateDelegate);
+ asyncHeaderItem[whiteboxedItemsSymbol] = new Set();
+ asyncHeaderItem.isAsyncHeader = true;
+
+ const asyncFrameItems = frames.map(frame => {
+ const item = new Sources.CallStackSidebarPane.Item(UI.beautifyFunctionName(frame.functionName), update);
+ const rawLocation = debuggerModel ?
+ debuggerModel.createRawLocationByScriptId(frame.scriptId, frame.lineNumber, frame.columnNumber) :
+ null;
+ if (!rawLocation) {
+ item.linkText = (frame.url || '<unknown>') + ':' + (frame.lineNumber + 1);
+ item.updateDelegate(item);
+ } else {
+ Bindings.debuggerWorkspaceBinding.createCallFrameLiveLocation(
+ rawLocation, item._update.bind(item), locationPool);
+ }
+ return item;
+ });
+
+ updateDelegate(asyncHeaderItem);
+ return [asyncHeaderItem, ...asyncFrameItems];
+
+ /**
+ * @param {!Sources.CallStackSidebarPane.Item} item
+ */
+ function update(item) {
+ updateDelegate(item);
+ let shouldUpdate = false;
+ const items = asyncHeaderItem[whiteboxedItemsSymbol];
+ if (item.isBlackboxed) {
+ items.delete(item);
+ shouldUpdate = items.size === 0;
+ } else {
+ shouldUpdate = items.size === 0;
+ items.add(item);
+ }
+ asyncHeaderItem.isBlackboxed = asyncHeaderItem[whiteboxedItemsSymbol].size === 0;
+ if (shouldUpdate)
+ updateDelegate(asyncHeaderItem);
+ }
+ }
+
+ /**
+ * @param {string} title
+ * @param {function(!Sources.CallStackSidebarPane.Item)} updateDelegate
+ */
+ constructor(title, updateDelegate) {
+ this.isBlackboxed = false;
+ this.title = title;
+ this.linkText = '';
+ this.uiLocation = null;
+ this.isAsyncHeader = false;
+ this.updateDelegate = updateDelegate;
+ }
+
+ /**
+ * @param {!Bindings.LiveLocation} liveLocation
+ */
+ _update(liveLocation) {
+ const uiLocation = liveLocation.uiLocation();
+ this.isBlackboxed = uiLocation ? Bindings.blackboxManager.isBlackboxedUISourceCode(uiLocation.uiSourceCode) : false;
+ this.linkText = uiLocation ? uiLocation.linkText() : '';
+ this.uiLocation = uiLocation;
+ this.updateDelegate(this);
+ }
+};
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/DebuggerPausedMessage.js b/chromium/third_party/blink/renderer/devtools/front_end/sources/DebuggerPausedMessage.js
index 4ad256df3d7..f70671d2d4e 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/sources/DebuggerPausedMessage.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/DebuggerPausedMessage.js
@@ -108,9 +108,7 @@ Sources.DebuggerPausedMessage = class {
messageWrapper = buildWrapper(Common.UIString('Paused before potential out-of-memory crash'));
} else if (details.callFrames.length) {
const uiLocation = debuggerWorkspaceBinding.rawLocationToUILocation(details.callFrames[0].location());
- const breakpoint = uiLocation ?
- breakpointManager.findBreakpoint(uiLocation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber) :
- null;
+ const breakpoint = uiLocation ? breakpointManager.findBreakpoint(uiLocation) : null;
const defaultText = breakpoint ? Common.UIString('Paused on breakpoint') : Common.UIString('Debugger paused');
messageWrapper = buildWrapper(defaultText);
} else {
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/DebuggerPlugin.js b/chromium/third_party/blink/renderer/devtools/front_end/sources/DebuggerPlugin.js
index 2e0970490ba..b719c593f7e 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/sources/DebuggerPlugin.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/DebuggerPlugin.js
@@ -40,10 +40,6 @@ Sources.DebuggerPlugin = class extends Sources.UISourceCodeFrame.Plugin {
this._uiSourceCode = uiSourceCode;
this._transformer = transformer;
- /** @type {?Element} */
- this._conditionEditorElement = null;
- /** @type {?Element} */
- this._conditionElement = null;
/** @type {?Workspace.UILocation} */
this._executionLocation = null;
this._controlDown = false;
@@ -120,7 +116,7 @@ Sources.DebuggerPlugin = class extends Sources.UISourceCodeFrame.Plugin {
this._updateScriptFiles();
- if (this._uiSourceCode.isDirty() && !this._supportsEnabledBreakpointsWhileEditing()) {
+ if (this._uiSourceCode.isDirty()) {
this._muted = true;
this._mutedFromStart = true;
} else {
@@ -334,7 +330,7 @@ Sources.DebuggerPlugin = class extends Sources.UISourceCodeFrame.Plugin {
}
_workingCopyChanged() {
- if (this._supportsEnabledBreakpointsWhileEditing() || this._scriptFileForDebuggerModel.size)
+ if (this._scriptFileForDebuggerModel.size)
return;
if (this._uiSourceCode.isDirty())
@@ -348,22 +344,15 @@ Sources.DebuggerPlugin = class extends Sources.UISourceCodeFrame.Plugin {
*/
_workingCopyCommitted(event) {
this._scriptsPanel.updateLastModificationTime();
- if (this._supportsEnabledBreakpointsWhileEditing())
- return;
-
if (!this._scriptFileForDebuggerModel.size)
this._restoreBreakpointsAfterEditing();
}
_didMergeToVM() {
- if (this._supportsEnabledBreakpointsWhileEditing())
- return;
this._restoreBreakpointsIfConsistentScripts();
}
_didDivergeFromVM() {
- if (this._supportsEnabledBreakpointsWhileEditing())
- return;
this._muteBreakpointsWhileEditing();
}
@@ -375,10 +364,6 @@ Sources.DebuggerPlugin = class extends Sources.UISourceCodeFrame.Plugin {
this._muted = true;
}
- _supportsEnabledBreakpointsWhileEditing() {
- return this._uiSourceCode.project().type() === Workspace.projectTypes.Snippets;
- }
-
_restoreBreakpointsIfConsistentScripts() {
const scriptFiles = this._scriptFileForDebuggerModel.valuesArray();
for (let i = 0; i < scriptFiles.length; ++i) {
@@ -476,6 +461,8 @@ Sources.DebuggerPlugin = class extends Sources.UISourceCodeFrame.Plugin {
const tokenBefore = this._textEditor.tokenAtTextPosition(editorLineNumber, startHighlight - 2);
if (!tokenBefore || !tokenBefore.type)
return null;
+ if (tokenBefore.type === 'js-meta')
+ break;
startHighlight = tokenBefore.startColumn;
}
}
@@ -646,52 +633,64 @@ Sources.DebuggerPlugin = class extends Sources.UISourceCodeFrame.Plugin {
* @param {?Bindings.BreakpointManager.Breakpoint} breakpoint
* @param {?{lineNumber: number, columnNumber: number}} location
*/
- _editBreakpointCondition(editorLineNumber, breakpoint, location) {
- this._conditionElement = this._createConditionElement(editorLineNumber);
- this._textEditor.addDecoration(this._conditionElement, editorLineNumber);
+ async _editBreakpointCondition(editorLineNumber, breakpoint, location) {
+ const conditionElement = createElementWithClass('div', 'source-frame-breakpoint-condition');
+ const labelElement = conditionElement.createChild('label', 'source-frame-breakpoint-message');
+ labelElement.htmlFor = 'source-frame-breakpoint-condition';
+ labelElement.createTextChild(
+ Common.UIString('The breakpoint on line %d will stop only if this expression is true:', editorLineNumber + 1));
+
+
+ this._textEditor.addDecoration(conditionElement, editorLineNumber);
+
+ /** @type {!UI.TextEditorFactory} */
+ const factory = await self.runtime.extension(UI.TextEditorFactory).instance();
+ const editor =
+ factory.createEditor({lineNumbers: false, lineWrapping: true, mimeType: 'javascript', autoHeight: true});
+ editor.widget().show(conditionElement);
+ if (breakpoint)
+ editor.setText(breakpoint.condition());
+ editor.setSelection(editor.fullRange());
+ editor.configureAutocomplete(ObjectUI.JavaScriptAutocompleteConfig.createConfigForEditor(editor));
+ editor.widget().element.addEventListener('keydown', async event => {
+ if (isEnterKey(event) && !event.shiftKey) {
+ event.consume(true);
+ const expression = editor.text();
+ if (event.ctrlKey || await ObjectUI.JavaScriptAutocomplete.isExpressionComplete(expression))
+ finishEditing.call(this, true);
+ else
+ editor.newlineAndIndent();
+ }
+ if (isEscKey(event))
+ finishEditing.call(this, false);
+ }, true);
+ editor.widget().focus();
+ editor.widget().element.id = 'source-frame-breakpoint-condition';
+ editor.widget().element.addEventListener('blur', event => {
+ if (event.relatedTarget && !event.relatedTarget.isSelfOrDescendant(editor.widget().element))
+ finishEditing.call(this, true);
+ }, true);
+ let finished = false;
/**
* @this {Sources.DebuggerPlugin}
*/
- function finishEditing(committed, element, newText) {
- this._textEditor.removeDecoration(/** @type {!Element} */ (this._conditionElement), editorLineNumber);
- this._conditionEditorElement = null;
- this._conditionElement = null;
+ function finishEditing(committed) {
+ if (finished)
+ return;
+ finished = true;
+ editor.widget().detach();
+ this._textEditor.removeDecoration(/** @type {!Element} */ (conditionElement), editorLineNumber);
if (!committed)
return;
if (breakpoint)
- breakpoint.setCondition(newText);
+ breakpoint.setCondition(editor.text().trim());
else if (location)
- this._setBreakpoint(location.lineNumber, location.columnNumber, newText, true);
+ this._setBreakpoint(location.lineNumber, location.columnNumber, editor.text().trim(), true);
else
- this._createNewBreakpoint(editorLineNumber, newText, true);
+ this._createNewBreakpoint(editorLineNumber, editor.text().trim(), true);
}
-
- const config = new UI.InplaceEditor.Config(finishEditing.bind(this, true), finishEditing.bind(this, false));
- UI.InplaceEditor.startEditing(/** @type {!Element} */ (this._conditionEditorElement), config);
- this._conditionEditorElement.value = breakpoint ? breakpoint.condition() : '';
- this._conditionEditorElement.select();
- }
-
- /**
- * @param {number} editorLineNumber
- * @return {!Element}
- */
- _createConditionElement(editorLineNumber) {
- const conditionElement = createElementWithClass('div', 'source-frame-breakpoint-condition');
-
- const labelElement = conditionElement.createChild('label', 'source-frame-breakpoint-message');
- labelElement.htmlFor = 'source-frame-breakpoint-condition';
- labelElement.createTextChild(
- Common.UIString('The breakpoint on line %d will stop only if this expression is true:', editorLineNumber + 1));
-
- const editorElement = UI.createInput('monospace', 'text');
- conditionElement.appendChild(editorElement);
- editorElement.id = 'source-frame-breakpoint-condition';
- this._conditionEditorElement = editorElement;
-
- return conditionElement;
}
/**
@@ -1265,8 +1264,6 @@ Sources.DebuggerPlugin = class extends Sources.UISourceCodeFrame.Plugin {
const uiLocation = /** @type {!Workspace.UILocation} */ (event.data.uiLocation);
if (uiLocation.uiSourceCode !== this._uiSourceCode)
return true;
- if (this._supportsEnabledBreakpointsWhileEditing())
- return false;
if (this._muted)
return true;
const scriptFiles = this._scriptFileForDebuggerModel.valuesArray();
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/JavaScriptBreakpointsSidebarPane.js b/chromium/third_party/blink/renderer/devtools/front_end/sources/JavaScriptBreakpointsSidebarPane.js
index 7d7f1e1b80c..281c34c35c8 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/sources/JavaScriptBreakpointsSidebarPane.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/JavaScriptBreakpointsSidebarPane.js
@@ -25,7 +25,9 @@ Sources.JavaScriptBreakpointsSidebarPane = class extends UI.ThrottledWidget {
* @return {!Promise<?>}
*/
doUpdate() {
- const breakpointLocations = this._breakpointManager.allBreakpointLocations();
+ const breakpointLocations = this._breakpointManager.allBreakpointLocations().filter(
+ breakpointLocation =>
+ breakpointLocation.uiLocation.uiSourceCode.project().type() !== Workspace.projectTypes.Debugger);
if (!breakpointLocations.length) {
this._listElement = null;
this.contentElement.removeChildren();
@@ -80,7 +82,7 @@ Sources.JavaScriptBreakpointsSidebarPane = class extends UI.ThrottledWidget {
const hasEnabled = locations.some(location => location.breakpoint.enabled());
const hasDisabled = locations.some(location => !location.breakpoint.enabled());
promises.push(this._resetEntry(/** @type {!Element}*/ (entry), uiLocation, isSelected, hasEnabled, hasDisabled));
-
+ entry[Sources.JavaScriptBreakpointsSidebarPane._breakpointLocationsSymbol] = locations;
if (isSelected)
shouldShowView = true;
entry = entry.nextSibling;
@@ -94,8 +96,7 @@ Sources.JavaScriptBreakpointsSidebarPane = class extends UI.ThrottledWidget {
UI.viewManager.showView('sources.jsBreakpoints');
this._listElement.classList.toggle(
'breakpoints-list-deactivated', !Common.moduleSetting('breakpointsActive').get());
- Promise.all(promises).then(() => this._didUpdateForTest());
- return Promise.resolve();
+ return Promise.all(promises).then(() => this._didUpdateForTest());
}
/**
@@ -135,24 +136,20 @@ Sources.JavaScriptBreakpointsSidebarPane = class extends UI.ThrottledWidget {
/**
* @param {!Event} event
- * @return {?Workspace.UILocation}
+ * @return {!Array<!Bindings.BreakpointManager.BreakpointLocation>}
*/
- _uiLocationFromEvent(event) {
+ _breakpointLocations(event) {
const node = event.target.enclosingNodeOrSelfWithClass('breakpoint-entry');
if (!node)
- return null;
- return node[Sources.JavaScriptBreakpointsSidebarPane._locationSymbol] || null;
+ return [];
+ return node[Sources.JavaScriptBreakpointsSidebarPane._breakpointLocationsSymbol] || [];
}
/**
* @param {!Event} event
*/
_breakpointCheckboxClicked(event) {
- const uiLocation = this._uiLocationFromEvent(event);
- if (!uiLocation)
- return;
-
- const breakpoints = this._breakpointManager.findBreakpoints(uiLocation.uiSourceCode, uiLocation.lineNumber);
+ const breakpoints = this._breakpointLocations(event).map(breakpointLocation => breakpointLocation.breakpoint);
const newState = event.target.checkboxElement.checked;
for (const breakpoint of breakpoints)
breakpoint.setEnabled(newState);
@@ -163,7 +160,12 @@ Sources.JavaScriptBreakpointsSidebarPane = class extends UI.ThrottledWidget {
* @param {!Event} event
*/
_revealLocation(event) {
- const uiLocation = this._uiLocationFromEvent(event);
+ const uiLocations = this._breakpointLocations(event).map(breakpointLocation => breakpointLocation.uiLocation);
+ let uiLocation = null;
+ for (const uiLocationCandidate of uiLocations) {
+ if (!uiLocation || uiLocationCandidate.columnNumber < uiLocation.columnNumber)
+ uiLocation = uiLocationCandidate;
+ }
if (uiLocation)
Common.Revealer.reveal(uiLocation);
}
@@ -172,11 +174,7 @@ Sources.JavaScriptBreakpointsSidebarPane = class extends UI.ThrottledWidget {
* @param {!Event} event
*/
_breakpointContextMenu(event) {
- const uiLocation = this._uiLocationFromEvent(event);
- if (!uiLocation)
- return;
-
- const breakpoints = this._breakpointManager.findBreakpoints(uiLocation.uiSourceCode, uiLocation.lineNumber);
+ const breakpoints = this._breakpointLocations(event).map(breakpointLocation => breakpointLocation.breakpoint);
const contextMenu = new UI.ContextMenu(event);
const removeEntryTitle = breakpoints.length > 1 ? Common.UIString('Remove all breakpoints in line') :
@@ -192,25 +190,44 @@ Sources.JavaScriptBreakpointsSidebarPane = class extends UI.ThrottledWidget {
if (breakpoints.some(breakpoint => !breakpoint.enabled())) {
const enableTitle = Common.UIString('Enable all breakpoints');
- contextMenu.defaultSection().appendItem(
- enableTitle, this._breakpointManager.toggleAllBreakpoints.bind(this._breakpointManager, true));
+ contextMenu.defaultSection().appendItem(enableTitle, this._toggleAllBreakpoints.bind(this, true));
}
if (breakpoints.some(breakpoint => breakpoint.enabled())) {
const disableTitle = Common.UIString('Disable all breakpoints');
- contextMenu.defaultSection().appendItem(
- disableTitle, this._breakpointManager.toggleAllBreakpoints.bind(this._breakpointManager, false));
+ contextMenu.defaultSection().appendItem(disableTitle, this._toggleAllBreakpoints.bind(this, false));
}
const removeAllTitle = Common.UIString('Remove all breakpoints');
- contextMenu.defaultSection().appendItem(
- removeAllTitle, this._breakpointManager.removeAllBreakpoints.bind(this._breakpointManager));
+ contextMenu.defaultSection().appendItem(removeAllTitle, this._removeAllBreakpoints.bind(this));
const removeOtherTitle = Common.UIString('Remove other breakpoints');
contextMenu.defaultSection().appendItem(
- removeOtherTitle,
- this._breakpointManager.removeOtherBreakpoints.bind(this._breakpointManager, new Set(breakpoints)));
+ removeOtherTitle, this._removeOtherBreakpoints.bind(this, new Set(breakpoints)));
contextMenu.show();
}
/**
+ * @param {boolean} toggleState
+ */
+ _toggleAllBreakpoints(toggleState) {
+ for (const breakpointLocation of this._breakpointManager.allBreakpointLocations())
+ breakpointLocation.breakpoint.setEnabled(toggleState);
+ }
+
+ _removeAllBreakpoints() {
+ for (const breakpointLocation of this._breakpointManager.allBreakpointLocations())
+ breakpointLocation.breakpoint.remove(false /* keepInStorage */);
+ }
+
+ /**
+ * @param {!Set<!Bindings.BreakpointManager.Breakpoint>} selectedBreakpoints
+ */
+ _removeOtherBreakpoints(selectedBreakpoints) {
+ for (const breakpointLocation of this._breakpointManager.allBreakpointLocations()) {
+ if (!selectedBreakpoints.has(breakpointLocation.breakpoint))
+ breakpointLocation.breakpoint.remove(false /* keepInStorage */);
+ }
+ }
+
+ /**
* @override
* @param {?Object} object
*/
@@ -225,3 +242,4 @@ Sources.JavaScriptBreakpointsSidebarPane = class extends UI.ThrottledWidget {
Sources.JavaScriptBreakpointsSidebarPane._locationSymbol = Symbol('location');
Sources.JavaScriptBreakpointsSidebarPane._checkboxLabelSymbol = Symbol('checkbox-label');
Sources.JavaScriptBreakpointsSidebarPane._snippetElementSymbol = Symbol('snippet-element');
+Sources.JavaScriptBreakpointsSidebarPane._breakpointLocationsSymbol = Symbol('locations');
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/JavaScriptCompilerPlugin.js b/chromium/third_party/blink/renderer/devtools/front_end/sources/JavaScriptCompilerPlugin.js
index 575db346563..9e87115e507 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/sources/JavaScriptCompilerPlugin.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/JavaScriptCompilerPlugin.js
@@ -31,7 +31,7 @@ Sources.JavaScriptCompilerPlugin = class extends Sources.UISourceCodeFrame.Plugi
static accepts(uiSourceCode) {
if (uiSourceCode.extension() === 'js')
return true;
- if (uiSourceCode.project().type() === Workspace.projectTypes.Snippets)
+ if (Snippets.isSnippetsUISourceCode(uiSourceCode))
return true;
for (const debuggerModel of SDK.targetManager.models(SDK.DebuggerModel)) {
if (Bindings.debuggerWorkspaceBinding.scriptFile(uiSourceCode, debuggerModel))
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/NavigatorView.js b/chromium/third_party/blink/renderer/devtools/front_end/sources/NavigatorView.js
index 959ac9629e3..668372bba1f 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/sources/NavigatorView.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/NavigatorView.js
@@ -345,7 +345,7 @@ Sources.NavigatorView = class extends UI.VBox {
*/
_projectAdded(project) {
if (!this.acceptProject(project) || project.type() !== Workspace.projectTypes.FileSystem ||
- this._rootNode.child(project.id()))
+ Snippets.isSnippetsProject(project) || this._rootNode.child(project.id()))
return;
this._rootNode.appendChild(new Sources.NavigatorGroupTreeNode(
this, project, project.id(), Sources.NavigatorView.Types.FileSystem, project.displayName()));
@@ -418,7 +418,7 @@ Sources.NavigatorView = class extends UI.VBox {
* @return {!Sources.NavigatorTreeNode}
*/
_folderNode(uiSourceCode, project, target, frame, projectOrigin, path, fromSourceMap) {
- if (project.type() === Workspace.projectTypes.Snippets)
+ if (Snippets.isSnippetsUISourceCode(uiSourceCode))
return this._rootNode;
if (target && !this._groupByFolder && !fromSourceMap)
@@ -586,12 +586,6 @@ Sources.NavigatorView = class extends UI.VBox {
/**
* @param {!Workspace.UISourceCode} uiSourceCode
*/
- sourceDeleted(uiSourceCode) {
- }
-
- /**
- * @param {!Workspace.UISourceCode} uiSourceCode
- */
_removeUISourceCode(uiSourceCode) {
const nodes = this._uiSourceCodeNodes.get(uiSourceCode);
for (const node of nodes)
@@ -997,7 +991,10 @@ Sources.NavigatorSourceTreeElement = class extends UI.TreeElement {
const binding = Persistence.persistence.binding(this._uiSourceCode);
if (binding) {
const container = createElementWithClass('span', 'icon-stack');
- const icon = UI.Icon.create('largeicon-navigator-file-sync', 'icon');
+ let iconType = 'largeicon-navigator-file-sync';
+ if (Snippets.isSnippetsUISourceCode(binding.fileSystem))
+ iconType = 'largeicon-navigator-snippet';
+ const icon = UI.Icon.create(iconType, 'icon');
const badge = UI.Icon.create('badge-navigator-file-sync', 'icon-badge');
// TODO(allada) This does not play well with dark theme. Add an actual icon and use it.
if (Persistence.networkPersistenceManager.project() === binding.fileSystem.project())
@@ -1008,7 +1005,7 @@ Sources.NavigatorSourceTreeElement = class extends UI.TreeElement {
this.setLeadingIcons([container]);
} else {
let iconType = 'largeicon-navigator-file';
- if (this._uiSourceCode.contentType() === Common.resourceTypes.Snippet)
+ if (Snippets.isSnippetsUISourceCode(this._uiSourceCode))
iconType = 'largeicon-navigator-snippet';
const defaultIcon = UI.Icon.create(iconType, 'icon');
this.setLeadingIcons([defaultIcon]);
@@ -1106,7 +1103,6 @@ Sources.NavigatorSourceTreeElement = class extends UI.TreeElement {
* @return {boolean}
*/
ondelete() {
- this._navigatorView.sourceDeleted(this.uiSourceCode);
return true;
}
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/ScriptOriginPlugin.js b/chromium/third_party/blink/renderer/devtools/front_end/sources/ScriptOriginPlugin.js
new file mode 100644
index 00000000000..238f2483737
--- /dev/null
+++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/ScriptOriginPlugin.js
@@ -0,0 +1,53 @@
+// 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.
+
+Sources.ScriptOriginPlugin = class extends Sources.UISourceCodeFrame.Plugin {
+ /**
+ * @param {!SourceFrame.SourcesTextEditor} textEditor
+ * @param {!Workspace.UISourceCode} uiSourceCode
+ */
+ constructor(textEditor, uiSourceCode) {
+ super();
+ this._textEditor = textEditor;
+ this._uiSourceCode = uiSourceCode;
+ }
+
+ /**
+ * @override
+ * @param {!Workspace.UISourceCode} uiSourceCode
+ * @return {boolean}
+ */
+ static accepts(uiSourceCode) {
+ return !!Sources.ScriptOriginPlugin._script(uiSourceCode);
+ }
+
+ /**
+ * @override
+ * @return {!Array<!UI.ToolbarItem>}
+ */
+ rightToolbarItems() {
+ const script = Sources.ScriptOriginPlugin._script(this._uiSourceCode);
+ if (!script || !script.originStackTrace)
+ return [];
+ const link = Sources.ScriptOriginPlugin._linkifier.linkifyStackTraceTopFrame(
+ script.debuggerModel.target(), script.originStackTrace);
+ return [new UI.ToolbarItem(link)];
+ }
+
+ /**
+ * @param {!Workspace.UISourceCode} uiSourceCode
+ * @return {?SDK.Script}
+ */
+ static _script(uiSourceCode) {
+ const locations = Bindings.debuggerWorkspaceBinding.uiLocationToRawLocations(uiSourceCode, 0, 0);
+ for (const location of locations) {
+ const script = location.script();
+ if (script.originStackTrace)
+ return script;
+ }
+ return null;
+ }
+};
+
+Sources.ScriptOriginPlugin._linkifier = new Components.Linkifier(); \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/SnippetsPlugin.js b/chromium/third_party/blink/renderer/devtools/front_end/sources/SnippetsPlugin.js
index 019ab5545ec..c55334719f7 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/sources/SnippetsPlugin.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/SnippetsPlugin.js
@@ -19,7 +19,7 @@ Sources.SnippetsPlugin = class extends Sources.UISourceCodeFrame.Plugin {
* @return {boolean}
*/
static accepts(uiSourceCode) {
- return uiSourceCode.project().type() === Workspace.projectTypes.Snippets;
+ return Snippets.isSnippetsUISourceCode(uiSourceCode);
}
/**
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/SourceFormatter.js b/chromium/third_party/blink/renderer/devtools/front_end/sources/SourceFormatter.js
index 527fe64ac75..86e202c3860 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/sources/SourceFormatter.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/SourceFormatter.js
@@ -176,17 +176,18 @@ Sources.SourceFormatter.ScriptMapping = class {
* @param {!Workspace.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @param {number} columnNumber
- * @return {?SDK.DebuggerModel.Location}
+ * @return {!Array<!SDK.DebuggerModel.Location>}
*/
- uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber) {
+ uiLocationToRawLocations(uiSourceCode, lineNumber, columnNumber) {
const formatData = Sources.SourceFormatData._for(uiSourceCode);
if (!formatData)
- return null;
+ return [];
const originalLocation = formatData.mapping.formattedToOriginal(lineNumber, columnNumber);
const scripts = this._scriptsForUISourceCode(formatData.originalSourceCode);
if (!scripts.length)
- return null;
- return scripts[0].debuggerModel.createRawLocation(scripts[0], originalLocation[0], originalLocation[1]);
+ return [];
+ return scripts.map(
+ script => script.debuggerModel.createRawLocation(script, originalLocation[0], originalLocation[1]));
}
/**
@@ -223,9 +224,8 @@ Sources.SourceFormatter.ScriptMapping = class {
}
}
if (uiSourceCode.contentType().isScript()) {
- const rawLocation = Bindings.debuggerWorkspaceBinding.uiLocationToRawLocation(uiSourceCode, 0, 0);
- if (rawLocation)
- return [rawLocation.script()];
+ const rawLocations = Bindings.debuggerWorkspaceBinding.uiLocationToRawLocations(uiSourceCode, 0, 0);
+ return rawLocations.map(location => location.script());
}
return [];
}
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/SourceMapNamesResolver.js b/chromium/third_party/blink/renderer/devtools/front_end/sources/SourceMapNamesResolver.js
index 2990a5efb83..e72955c87dd 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/sources/SourceMapNamesResolver.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/SourceMapNamesResolver.js
@@ -228,22 +228,25 @@ Sources.SourceMapNamesResolver.resolveExpression = function(
if (!uiSourceCode.contentType().isFromSourceMap())
return Promise.resolve('');
- return Sources.SourceMapNamesResolver._allVariablesInCallFrame(callFrame).then(findCompiledName);
+ return Sources.SourceMapNamesResolver._allVariablesInCallFrame(callFrame).then(
+ reverseMapping => findCompiledName(callFrame.debuggerModel, reverseMapping));
/**
+ * @param {!SDK.DebuggerModel} debuggerModel
* @param {!Map<string, string>} reverseMapping
* @return {!Promise<string>}
*/
- function findCompiledName(reverseMapping) {
+ function findCompiledName(debuggerModel, reverseMapping) {
if (reverseMapping.has(originalText))
return Promise.resolve(reverseMapping.get(originalText) || '');
return Sources.SourceMapNamesResolver._resolveExpression(
- uiSourceCode, lineNumber, startColumnNumber, endColumnNumber);
+ debuggerModel, uiSourceCode, lineNumber, startColumnNumber, endColumnNumber);
}
};
/**
+ * @param {!SDK.DebuggerModel} debuggerModel
* @param {!Workspace.UISourceCode} uiSourceCode
* @param {number} lineNumber
* @param {number} startColumnNumber
@@ -251,9 +254,10 @@ Sources.SourceMapNamesResolver.resolveExpression = function(
* @return {!Promise<string>}
*/
Sources.SourceMapNamesResolver._resolveExpression = function(
- uiSourceCode, lineNumber, startColumnNumber, endColumnNumber) {
- const rawLocation =
- Bindings.debuggerWorkspaceBinding.uiLocationToRawLocation(uiSourceCode, lineNumber, startColumnNumber);
+ debuggerModel, uiSourceCode, lineNumber, startColumnNumber, endColumnNumber) {
+ const rawLocations =
+ Bindings.debuggerWorkspaceBinding.uiLocationToRawLocations(uiSourceCode, lineNumber, startColumnNumber);
+ const rawLocation = rawLocations.find(location => location.debuggerModel === debuggerModel);
if (!rawLocation)
return Promise.resolve('');
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/SourcesNavigator.js b/chromium/third_party/blink/renderer/devtools/front_end/sources/SourcesNavigator.js
index 70db55da7d5..072c3238073 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/sources/SourcesNavigator.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/SourcesNavigator.js
@@ -96,7 +96,8 @@ Sources.FilesNavigatorView = class extends Sources.NavigatorView {
*/
acceptProject(project) {
return project.type() === Workspace.projectTypes.FileSystem &&
- Persistence.FileSystemWorkspaceBinding.fileSystemType(project) !== 'overrides';
+ Persistence.FileSystemWorkspaceBinding.fileSystemType(project) !== 'overrides' &&
+ !Snippets.isSnippetsProject(project);
}
/**
@@ -208,7 +209,7 @@ Sources.SnippetsNavigatorView = class extends Sources.NavigatorView {
super();
const toolbar = new UI.Toolbar('navigator-toolbar');
const newButton = new UI.ToolbarButton('', 'largeicon-add', Common.UIString('New snippet'));
- newButton.addEventListener(UI.ToolbarButton.Events.Click, this._handleCreateSnippet.bind(this));
+ newButton.addEventListener(UI.ToolbarButton.Events.Click, () => this.create(Snippets.project, ''));
toolbar.appendToolbarItem(newButton);
this.contentElement.insertBefore(toolbar.element, this.contentElement.firstChild);
}
@@ -219,7 +220,7 @@ Sources.SnippetsNavigatorView = class extends Sources.NavigatorView {
* @return {boolean}
*/
acceptProject(project) {
- return project.type() === Workspace.projectTypes.Snippets;
+ return Snippets.isSnippetsProject(project);
}
/**
@@ -228,7 +229,7 @@ Sources.SnippetsNavigatorView = class extends Sources.NavigatorView {
*/
handleContextMenu(event) {
const contextMenu = new UI.ContextMenu(event);
- contextMenu.headerSection().appendItem(Common.UIString('New'), this._handleCreateSnippet.bind(this));
+ contextMenu.headerSection().appendItem(Common.UIString('New'), () => this.create(Snippets.project, ''));
contextMenu.show();
}
@@ -240,12 +241,10 @@ Sources.SnippetsNavigatorView = class extends Sources.NavigatorView {
handleFileContextMenu(event, node) {
const uiSourceCode = node.uiSourceCode();
const contextMenu = new UI.ContextMenu(event);
-
- contextMenu.headerSection().appendItem(
- Common.UIString('Run'), this._handleEvaluateSnippet.bind(this, uiSourceCode));
- contextMenu.newSection().appendItem(Common.UIString('New'), this._handleCreateSnippet.bind(this));
- contextMenu.editSection().appendItem(Common.UIString('Rename'), this.rename.bind(this, node));
- contextMenu.editSection().appendItem(Common.UIString('Remove'), this._handleRemoveSnippet.bind(this, uiSourceCode));
+ contextMenu.headerSection().appendItem(Common.UIString('Run'), () => Snippets.evaluateScriptSnippet(uiSourceCode));
+ contextMenu.editSection().appendItem(Common.UIString('Rename\u2026'), () => this.rename(node, false));
+ contextMenu.editSection().appendItem(
+ Common.UIString('Remove'), () => uiSourceCode.project().deleteFile(uiSourceCode));
contextMenu.saveSection().appendItem(Common.UIString('Save as...'), this._handleSaveAs.bind(this, uiSourceCode));
contextMenu.show();
}
@@ -253,45 +252,12 @@ Sources.SnippetsNavigatorView = class extends Sources.NavigatorView {
/**
* @param {!Workspace.UISourceCode} uiSourceCode
*/
- _handleEvaluateSnippet(uiSourceCode) {
- const executionContext = UI.context.flavor(SDK.ExecutionContext);
- if (!executionContext)
- return;
- Snippets.scriptSnippetModel.evaluateScriptSnippet(executionContext, uiSourceCode);
- }
-
- /**
- * @param {!Workspace.UISourceCode} uiSourceCode
- */
async _handleSaveAs(uiSourceCode) {
- if (uiSourceCode.project().type() !== Workspace.projectTypes.Snippets)
- return;
-
uiSourceCode.commitWorkingCopy();
const content = await uiSourceCode.requestContent();
Workspace.fileManager.save(uiSourceCode.url(), content, true);
Workspace.fileManager.close(uiSourceCode.url());
}
-
- /**
- * @param {!Workspace.UISourceCode} uiSourceCode
- */
- _handleRemoveSnippet(uiSourceCode) {
- if (uiSourceCode.project().type() !== Workspace.projectTypes.Snippets)
- return;
- uiSourceCode.remove();
- }
-
- _handleCreateSnippet() {
- this.create(Snippets.scriptSnippetModel.project(), '');
- }
-
- /**
- * @override
- */
- sourceDeleted(uiSourceCode) {
- this._handleRemoveSnippet(uiSourceCode);
- }
};
/**
@@ -307,8 +273,7 @@ Sources.SnippetsNavigatorView.CreatingActionDelegate = class {
handleAction(context, actionId) {
switch (actionId) {
case 'sources.create-snippet':
- const uiSourceCode = Snippets.scriptSnippetModel.createScriptSnippet('');
- Common.Revealer.reveal(uiSourceCode);
+ Snippets.project.createFile('', null, '').then(uiSourceCode => Common.Revealer.reveal(uiSourceCode));
return true;
case 'sources.add-folder-to-workspace':
Persistence.isolatedFileSystemManager.addFileSystem();
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/SourcesPanel.js b/chromium/third_party/blink/renderer/devtools/front_end/sources/SourcesPanel.js
index 8204f2279b0..bf86dd9075e 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/sources/SourcesPanel.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/SourcesPanel.js
@@ -81,9 +81,10 @@ Sources.SourcesPanel = class extends UI.Panel {
if (UI.viewManager.hasViewsForLocation('run-view-sidebar')) {
const navigatorSplitWidget = new UI.SplitWidget(false, true, 'sourcePanelNavigatorSidebarSplitViewState');
navigatorSplitWidget.setMainWidget(tabbedPane);
- navigatorSplitWidget.setSidebarWidget(
- UI.viewManager.createTabbedLocation(this._revealNavigatorSidebar.bind(this), 'run-view-sidebar')
- .tabbedPane());
+ const runViewTabbedPane =
+ UI.viewManager.createTabbedLocation(this._revealNavigatorSidebar.bind(this), 'run-view-sidebar').tabbedPane();
+ navigatorSplitWidget.setSidebarWidget(runViewTabbedPane);
+ navigatorSplitWidget.installResizer(runViewTabbedPane.headerElement());
this.editorView.setSidebarWidget(navigatorSplitWidget);
} else {
this.editorView.setSidebarWidget(tabbedPane);
@@ -529,23 +530,11 @@ Sources.SourcesPanel = class extends UI.Panel {
Common.moduleSetting('pauseOnExceptionEnabled').set(!this._pauseOnExceptionButton.toggled());
}
- /**
- * @return {boolean}
- */
_runSnippet() {
const uiSourceCode = this._sourcesView.currentUISourceCode();
if (!uiSourceCode)
- return false;
-
- const currentExecutionContext = UI.context.flavor(SDK.ExecutionContext);
- if (!currentExecutionContext)
- return false;
-
- if (uiSourceCode.project().type() !== Workspace.projectTypes.Snippets)
- return false;
-
- Snippets.scriptSnippetModel.evaluateScriptSnippet(currentExecutionContext, uiSourceCode);
- return true;
+ return;
+ Snippets.evaluateScriptSnippet(uiSourceCode);
}
/**
@@ -672,9 +661,10 @@ Sources.SourcesPanel = class extends UI.Panel {
if (!executionContext)
return;
// Always use 0 column.
- const rawLocation =
- Bindings.debuggerWorkspaceBinding.uiLocationToRawLocation(uiLocation.uiSourceCode, uiLocation.lineNumber, 0);
- if (!rawLocation || rawLocation.debuggerModel !== executionContext.debuggerModel)
+ const rawLocations =
+ Bindings.debuggerWorkspaceBinding.uiLocationToRawLocations(uiLocation.uiSourceCode, uiLocation.lineNumber, 0);
+ const rawLocation = rawLocations.find(location => location.debuggerModel === executionContext.debuggerModel);
+ if (!rawLocation)
return;
if (!this._prepareToResume())
return;
@@ -868,7 +858,7 @@ Sources.SourcesPanel = class extends UI.Panel {
const executionContext = /** @type {!SDK.ExecutionContext} */ (currentExecutionContext);
let text = /** @type {string} */ (callFunctionResult.object.value);
const message = SDK.consoleModel.addCommandMessage(executionContext, text);
- text = SDK.RuntimeModel.wrapObjectLiteralExpressionIfNeeded(text);
+ text = ObjectUI.JavaScriptREPL.wrapObjectLiteral(text);
SDK.consoleModel.evaluateCommandInConsole(
executionContext, message, text,
/* useCommandLineAPI */ false, /* awaitPromise */ false);
@@ -1202,7 +1192,7 @@ Sources.SourcesPanel.DebuggingActionDelegate = class {
const executionContext = UI.context.flavor(SDK.ExecutionContext);
if (executionContext) {
const message = SDK.consoleModel.addCommandMessage(executionContext, text);
- text = SDK.RuntimeModel.wrapObjectLiteralExpressionIfNeeded(text);
+ text = ObjectUI.JavaScriptREPL.wrapObjectLiteral(text);
SDK.consoleModel.evaluateCommandInConsole(
executionContext, message, text, /* useCommandLineAPI */ true, /* awaitPromise */ false);
}
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/TabbedEditorContainer.js b/chromium/third_party/blink/renderer/devtools/front_end/sources/TabbedEditorContainer.js
index 3c3ba2976f6..caf96b1982f 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/sources/TabbedEditorContainer.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/TabbedEditorContainer.js
@@ -379,11 +379,10 @@ Sources.TabbedEditorContainer = class extends Common.Object {
if (!this._currentFile)
return;
- const currentProjectType = this._currentFile.project().type();
- const addedProjectType = uiSourceCode.project().type();
- const snippetsProjectType = Workspace.projectTypes.Snippets;
- if (this._history.index(this._currentFile.url()) && currentProjectType === snippetsProjectType &&
- addedProjectType !== snippetsProjectType)
+
+ const currentProjectIsSnippets = Snippets.isSnippetsUISourceCode(this._currentFile);
+ const addedProjectIsSnippets = Snippets.isSnippetsUISourceCode(uiSourceCode);
+ if (this._history.index(this._currentFile.url()) && currentProjectIsSnippets && !addedProjectIsSnippets)
this._innerShowFile(uiSourceCode, false);
}
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/UISourceCodeFrame.js b/chromium/third_party/blink/renderer/devtools/front_end/sources/UISourceCodeFrame.js
index 47de6207236..47cb6bc733e 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/sources/UISourceCodeFrame.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/UISourceCodeFrame.js
@@ -323,6 +323,8 @@ Sources.UISourceCodeFrame = class extends SourceFrame.SourceFrame {
this._plugins.push(new Sources.JavaScriptCompilerPlugin(this.textEditor, pluginUISourceCode));
if (Sources.SnippetsPlugin.accepts(pluginUISourceCode))
this._plugins.push(new Sources.SnippetsPlugin(this.textEditor, pluginUISourceCode));
+ if (Sources.ScriptOriginPlugin.accepts(pluginUISourceCode))
+ this._plugins.push(new Sources.ScriptOriginPlugin(this.textEditor, pluginUISourceCode));
if (!this.pretty && Runtime.experiments.isEnabled('sourceDiff') &&
Sources.GutterDiffPlugin.accepts(pluginUISourceCode))
this._plugins.push(new Sources.GutterDiffPlugin(this.textEditor, pluginUISourceCode));
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/module.json b/chromium/third_party/blink/renderer/devtools/front_end/sources/module.json
index 2097f804d21..451a843622c 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/sources/module.json
+++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/module.json
@@ -863,7 +863,8 @@
"SourcesSearchScope.js",
"SourcesPanel.js",
"JavaScriptCompilerPlugin.js",
- "SnippetsPlugin.js"
+ "SnippetsPlugin.js",
+ "ScriptOriginPlugin.js"
],
"resources": [
"callStackSidebarPane.css",
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources/sourcesView.css b/chromium/third_party/blink/renderer/devtools/front_end/sources/sourcesView.css
index 6b27b3e74c9..42b8ab26914 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/sources/sourcesView.css
+++ b/chromium/third_party/blink/renderer/devtools/front_end/sources/sourcesView.css
@@ -85,6 +85,7 @@
width: 100%;
box-shadow: none !important;
outline: none !important;
+ background: white;
}
@-webkit-keyframes source-frame-value-update-highlight-animation {
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/sources_test_runner/DebuggerTestRunner.js b/chromium/third_party/blink/renderer/devtools/front_end/sources_test_runner/DebuggerTestRunner.js
index b6a62667481..8ea7e66bfd3 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/sources_test_runner/DebuggerTestRunner.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/sources_test_runner/DebuggerTestRunner.js
@@ -299,7 +299,8 @@ SourcesTestRunner.captureStackTraceIntoString = function(callFrames, asyncStackT
const location = locationFunction.call(frame);
const script = location.script();
const uiLocation = Bindings.debuggerWorkspaceBinding.rawLocationToUILocation(location);
- const isFramework = Bindings.blackboxManager.isBlackboxedRawLocation(location);
+ const isFramework =
+ uiLocation ? Bindings.blackboxManager.isBlackboxedUISourceCode(uiLocation.uiSourceCode) : false;
if (options.dropFrameworkCallFrames && isFramework)
continue;
@@ -446,6 +447,14 @@ SourcesTestRunner.waitForScriptSource = function(scriptName, callback) {
SourcesTestRunner.waitForScriptSource.bind(SourcesTestRunner, scriptName, callback));
};
+SourcesTestRunner.objectForPopover = function(sourceFrame, lineNumber, columnNumber) {
+ const debuggerPlugin = SourcesTestRunner.debuggerPlugin(sourceFrame);
+ const {x, y} = debuggerPlugin._textEditor.cursorPositionToCoordinates(lineNumber, columnNumber);
+ const promise = TestRunner.addSnifferPromise(ObjectUI.ObjectPopoverHelper, 'buildObjectPopover');
+ debuggerPlugin._getPopoverRequest({x, y}).show(new UI.GlassPane());
+ return promise;
+};
+
SourcesTestRunner.setBreakpoint = function(sourceFrame, lineNumber, condition, enabled) {
const debuggerPlugin = SourcesTestRunner.debuggerPlugin(sourceFrame);
if (!debuggerPlugin._muted)
@@ -454,7 +463,11 @@ SourcesTestRunner.setBreakpoint = function(sourceFrame, lineNumber, condition, e
SourcesTestRunner.removeBreakpoint = function(sourceFrame, lineNumber) {
const debuggerPlugin = SourcesTestRunner.debuggerPlugin(sourceFrame);
- debuggerPlugin._breakpointManager.findBreakpoints(sourceFrame._uiSourceCode, lineNumber)[0].remove();
+ const breakpointLocations = debuggerPlugin._breakpointManager.allBreakpointLocations();
+ const breakpointLocation = breakpointLocations.find(
+ breakpointLocation => breakpointLocation.uiLocation.uiSourceCode === sourceFrame._uiSourceCode &&
+ breakpointLocation.uiLocation.lineNumber === lineNumber);
+ breakpointLocation.breakpoint.remove();
};
SourcesTestRunner.createNewBreakpoint = function(sourceFrame, lineNumber, condition, enabled) {
@@ -481,8 +494,8 @@ SourcesTestRunner.waitBreakpointSidebarPane = function(waitUntilResolved) {
if (!waitUntilResolved)
return;
- for (const breakpoint of Bindings.breakpointManager._allBreakpoints()) {
- if (breakpoint._fakePrimaryLocation && breakpoint.enabled())
+ for (const {breakpoint} of Bindings.breakpointManager.allBreakpointLocations()) {
+ if (breakpoint._uiLocations.size === 0 && breakpoint.enabled())
return SourcesTestRunner.waitBreakpointSidebarPane();
}
}
@@ -693,8 +706,8 @@ SourcesTestRunner.waitDebuggerPluginBreakpoints = function(sourceFrame) {
}
function checkIfReady() {
- for (const breakpoint of Bindings.breakpointManager._allBreakpoints()) {
- if (breakpoint._fakePrimaryLocation && breakpoint.enabled())
+ for (const {breakpoint} of Bindings.breakpointManager.allBreakpointLocations()) {
+ if (breakpoint._uiLocations.size === 0 && breakpoint.enabled())
return waitUpdate().then(checkIfReady);
}
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/test_runner/TestRunner.js b/chromium/third_party/blink/renderer/devtools/front_end/test_runner/TestRunner.js
index b2631c68434..034aa81a84d 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/test_runner/TestRunner.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/test_runner/TestRunner.js
@@ -326,6 +326,7 @@ TestRunner.textContentWithoutStyles = function(node) {
* @param {!SDK.Target} target
*/
TestRunner._setupTestHelpers = function(target) {
+ TestRunner.BrowserAgent = target.browserAgent();
TestRunner.CSSAgent = target.cssAgent();
TestRunner.DeviceOrientationAgent = target.deviceOrientationAgent();
TestRunner.DOMAgent = target.domAgent();
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/text_editor/CodeMirrorTextEditor.js b/chromium/third_party/blink/renderer/devtools/front_end/text_editor/CodeMirrorTextEditor.js
index 2b6ef3b892a..601007786a1 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/text_editor/CodeMirrorTextEditor.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/text_editor/CodeMirrorTextEditor.js
@@ -74,7 +74,7 @@ TextEditor.CodeMirrorTextEditor = class extends UI.VBox {
'Delete': 'delCharAfter',
'Backspace': 'delCharBefore',
'Tab': 'defaultTab',
- 'Shift-Tab': 'indentLess',
+ 'Shift-Tab': 'indentLessOrPass',
'Enter': 'newlineAndIndent',
'Ctrl-Space': 'autocomplete',
'Esc': 'dismiss',
@@ -1326,6 +1326,20 @@ CodeMirror.commands.selectCamelRight = TextEditor.CodeMirrorTextEditor.moveCamel
/**
* @param {!CodeMirror} codeMirror
+ * @return {!Object|undefined}
+ */
+CodeMirror.commands.indentLessOrPass = function(codeMirror) {
+ const selections = codeMirror.listSelections();
+ if (selections.length === 1) {
+ const range = TextEditor.CodeMirrorUtils.toRange(selections[0].anchor, selections[0].head);
+ if (range.isEmpty() && !/^\s/.test(codeMirror.getLine(range.startLine)))
+ return CodeMirror.Pass;
+ }
+ codeMirror.execCommand('indentLess');
+};
+
+/**
+ * @param {!CodeMirror} codeMirror
*/
CodeMirror.commands.gotoMatchingBracket = function(codeMirror) {
const updatedSelections = [];
@@ -1371,6 +1385,7 @@ CodeMirror.commands.redoAndReveal = function(codemirror) {
};
/**
+ * @param {!CodeMirror} codemirror
* @return {!Object|undefined}
*/
CodeMirror.commands.dismiss = function(codemirror) {
@@ -1389,6 +1404,7 @@ CodeMirror.commands.dismiss = function(codemirror) {
};
/**
+ * @param {!CodeMirror} codemirror
* @return {!Object|undefined}
*/
CodeMirror.commands.goSmartPageUp = function(codemirror) {
@@ -1398,6 +1414,7 @@ CodeMirror.commands.goSmartPageUp = function(codemirror) {
};
/**
+ * @param {!CodeMirror} codemirror
* @return {!Object|undefined}
*/
CodeMirror.commands.goSmartPageDown = function(codemirror) {
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/text_editor/cmdevtools.css b/chromium/third_party/blink/renderer/devtools/front_end/text_editor/cmdevtools.css
index f30c3340dbe..6d42b866b0e 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/text_editor/cmdevtools.css
+++ b/chromium/third_party/blink/renderer/devtools/front_end/text_editor/cmdevtools.css
@@ -245,22 +245,22 @@
opacity: 1;
}
-div.CodeMirror span.CodeMirror-matchingbracket {
+div.CodeMirror:focus-within span.CodeMirror-matchingbracket {
background-color: rgba(0, 0, 0, 0.07);
border-bottom: 1px solid rgba(0, 0, 0, 0.5);
}
-div.CodeMirror span.CodeMirror-nonmatchingbracket {
+div.CodeMirror:focus-within span.CodeMirror-nonmatchingbracket {
background-color: rgba(255, 0, 0, 0.07);
border-bottom: 1px solid rgba(255, 0, 0, 0.5);
}
-.-theme-with-dark-background div.CodeMirror span.CodeMirror-matchingbracket {
+.-theme-with-dark-background div.CodeMirror:focus-within span.CodeMirror-matchingbracket {
border-bottom: 1px solid rgb(217,217,217);
background-color:initial;
}
-.-theme-with-dark-background div.CodeMirror span.CodeMirror-nonmatchingbracket {
+.-theme-with-dark-background div.CodeMirror:focus-within span.CodeMirror-nonmatchingbracket {
border-bottom: 1px solid rgb(255, 26, 26);
background-color:initial;
}
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineController.js b/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineController.js
index 1cf667ee673..63d73d1426a 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineController.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineController.js
@@ -13,6 +13,7 @@ Timeline.TimelineController = class {
* @param {!Timeline.TimelineController.Client} client
*/
constructor(target, client) {
+ this._target = target;
this._tracingManager = target.model(SDK.TracingManager);
this._performanceModel = new Timeline.PerformanceModel();
this._performanceModel.setMainTarget(target);
@@ -34,7 +35,7 @@ Timeline.TimelineController = class {
* @return {!SDK.Target}
*/
mainTarget() {
- return this._tracingManager.target();
+ return this._target;
}
/**
@@ -93,9 +94,11 @@ Timeline.TimelineController = class {
*/
async stopRecording() {
const tracingStoppedPromises = [];
- tracingStoppedPromises.push(new Promise(resolve => this._tracingCompleteCallback = resolve));
+ if (this._tracingManager)
+ tracingStoppedPromises.push(new Promise(resolve => this._tracingCompleteCallback = resolve));
tracingStoppedPromises.push(this._stopProfilingOnAllModels());
- this._tracingManager.stop();
+ if (this._tracingManager)
+ this._tracingManager.stop();
tracingStoppedPromises.push(SDK.targetManager.resumeAllTargets());
this._client.loadingStarted();
@@ -171,14 +174,16 @@ Timeline.TimelineController = class {
* @param {boolean=} enableJSSampling
* @return {!Promise}
*/
- _startRecordingWithCategories(categories, enableJSSampling) {
+ async _startRecordingWithCategories(categories, enableJSSampling) {
SDK.targetManager.suspendAllTargets();
- const profilingStartedPromise = enableJSSampling && !Runtime.experiments.isEnabled('timelineTracingJSProfile') ?
- this._startProfilingOnAllModels() :
- Promise.resolve();
+ if (enableJSSampling && !Runtime.experiments.isEnabled('timelineTracingJSProfile'))
+ await this._startProfilingOnAllModels();
+ if (!this._tracingManager)
+ return;
+
const samplingFrequencyHz = Common.moduleSetting('highResolutionCpuProfiling').get() ? 10000 : 1000;
const options = 'sampling-frequency=' + samplingFrequencyHz;
- return profilingStartedPromise.then(() => this._tracingManager.start(this, categories, options));
+ return this._tracingManager.start(this, categories, options);
}
/**
@@ -294,6 +299,16 @@ Timeline.TimelineController = class {
const pid = mainMetaEvent.thread.process().id();
const mainCpuProfile = this._cpuProfiles.get(this._tracingManager.target().id());
this._injectCpuProfileEvent(pid, mainMetaEvent.thread.id(), mainCpuProfile);
+ } else {
+ // Or there was no tracing manager in the main target at all, in this case build the model full
+ // of cpu profiles.
+ let tid = 0;
+ for (const pair of this._cpuProfiles) {
+ const target = SDK.targetManager.targetById(pair[0]);
+ const name = target && target.name();
+ this._tracingModel.addEvents(TimelineModel.TimelineJSProfileProcessor.buildTraceProfileFromCpuProfile(
+ pair[1], ++tid, /* injectPageEvent */ tid === 1, name));
+ }
}
}
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineLoader.js b/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineLoader.js
index fb7920ab0c6..65bf6f98d41 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineLoader.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineLoader.js
@@ -221,7 +221,8 @@ Timeline.TimelineLoader = class {
let traceEvents;
try {
const profile = JSON.parse(text);
- traceEvents = TimelineModel.TimelineJSProfileProcessor.buildTraceProfileFromCpuProfile(profile);
+ traceEvents = TimelineModel.TimelineJSProfileProcessor.buildTraceProfileFromCpuProfile(
+ profile, /* tid */ 1, /* injectPageEvent */ true);
} catch (e) {
this._reportErrorAndCancelLoading(Common.UIString('Malformed CPU profile format'));
return;
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineUIUtils.js b/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineUIUtils.js
index 628d07051ba..9e7c3642c72 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineUIUtils.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/timeline/TimelineUIUtils.js
@@ -179,10 +179,6 @@ Timeline.TimelineUIUtils = class {
eventStyles[recordTypes.LatencyInfo] =
new Timeline.TimelineRecordStyle(Common.UIString('Input Latency'), categories['scripting']);
- eventStyles[recordTypes.GCIdleLazySweep] =
- new Timeline.TimelineRecordStyle(Common.UIString('DOM GC'), categories['scripting']);
- eventStyles[recordTypes.GCCompleteSweep] =
- new Timeline.TimelineRecordStyle(Common.UIString('DOM GC'), categories['scripting']);
eventStyles[recordTypes.GCCollectGarbage] =
new Timeline.TimelineRecordStyle(Common.UIString('DOM GC'), categories['scripting']);
@@ -604,18 +600,6 @@ Timeline.TimelineUIUtils = class {
detailsText = eventData && eventData['name'];
break;
- case recordType.GCIdleLazySweep:
- detailsText = Common.UIString('idle sweep');
- break;
-
- case recordType.GCCompleteSweep:
- detailsText = Common.UIString('complete sweep');
- break;
-
- case recordType.GCCollectGarbage:
- detailsText = Common.UIString('collect');
- break;
-
case recordType.AsyncTask:
detailsText = eventData ? eventData['name'] : null;
break;
@@ -688,9 +672,6 @@ Timeline.TimelineUIUtils = class {
case recordType.WebSocketSendHandshakeRequest:
case recordType.WebSocketReceiveHandshakeResponse:
case recordType.WebSocketDestroy:
- case recordType.GCIdleLazySweep:
- case recordType.GCCompleteSweep:
- case recordType.GCCollectGarbage:
detailsText = Timeline.TimelineUIUtils.buildDetailsTextForTraceEvent(event, target);
break;
case recordType.PaintImage:
@@ -785,7 +766,7 @@ Timeline.TimelineUIUtils = class {
let previewElement = null;
const url = TimelineModel.TimelineData.forEvent(event).url;
if (url)
- previewElement = await BrowserComponents.ImagePreview.build(target, url, false);
+ previewElement = await Components.ImagePreview.build(target, url, false);
else if (TimelineModel.TimelineData.forEvent(event).picture)
previewElement = await Timeline.TimelineUIUtils.buildPicturePreviewContent(event, target);
event[Timeline.TimelineUIUtils._previewElementSymbol] = previewElement;
@@ -1076,36 +1057,38 @@ Timeline.TimelineUIUtils = class {
static statsForTimeRange(events, startTime, endTime) {
if (!events.length)
return {'idle': endTime - startTime};
- const symbol = Timeline.TimelineUIUtils._categoryBreakdownCacheSymbol;
- Timeline.TimelineUIUtils._buildRangeStatsCacheIfNeeded(events);
-
- const before = findCachedStatsAfterTime(startTime);
- const statsBefore =
- subtractStats(before.stats, Timeline.TimelineUIUtils._slowStatsForTimeRange(events, startTime, before.time));
-
- const after = findCachedStatsAfterTime(endTime);
- const statsAfter =
- subtractStats(after.stats, Timeline.TimelineUIUtils._slowStatsForTimeRange(events, endTime, after.time));
- const aggregatedStats = subtractStats(statsAfter, statsBefore);
+ buildRangeStatsCacheIfNeeded(events);
+ const aggregatedStats = subtractStats(aggregatedStatsAtTime(endTime), aggregatedStatsAtTime(startTime));
const aggregatedTotal = Object.values(aggregatedStats).reduce((a, b) => a + b, 0);
aggregatedStats['idle'] = Math.max(0, endTime - startTime - aggregatedTotal);
return aggregatedStats;
/**
- * @param {number} atTime
- * @return {!{time: number, stats: !Object<string, number>}}
+ * @param {number} time
+ * @return {!Object}
*/
- function findCachedStatsAfterTime(atTime) {
- let index = events.lowerBound(atTime, (time, event) => time - (event.endTime || event.startTime));
- while (index < events.length && !events[index][symbol])
- index++;
- if (index === events.length) {
- const lastEvent = events.peekLast();
- return {time: lastEvent.endTime || lastEvent.startTime, stats: events[symbol]};
+ function aggregatedStatsAtTime(time) {
+ const stats = {};
+ const cache = events[Timeline.TimelineUIUtils._categoryBreakdownCacheSymbol];
+ for (const category in cache) {
+ const categoryCache = cache[category];
+ const index = categoryCache.time.upperBound(time);
+ let value;
+ if (index === 0) {
+ value = 0;
+ } else if (index === categoryCache.time.length) {
+ value = categoryCache.value.peekLast();
+ } else {
+ const t0 = categoryCache.time[index - 1];
+ const t1 = categoryCache.time[index];
+ const v0 = categoryCache.value[index - 1];
+ const v1 = categoryCache.value[index];
+ value = v0 + (v1 - v0) * (time - t0) / (t1 - t0);
+ }
+ stats[category] = value;
}
- const event = events[index];
- return {time: event.endTime || event.startTime, stats: event[symbol]};
+ return stats;
}
/**
@@ -1119,82 +1102,84 @@ Timeline.TimelineUIUtils = class {
result[key] -= b[key];
return result;
}
- }
-
- /**
- * @param {!Array<!SDK.TracingModel.Event>} events
- * @param {number} startTime
- * @param {number} endTime
- */
- static _slowStatsForTimeRange(events, startTime, endTime) {
- /** @type {!Object<string, number>} */
- const stats = {};
- const ownTimes = [];
-
- TimelineModel.TimelineModel.forEachEvent(
- events, onStartEvent, onEndEvent, undefined, startTime, endTime, Timeline.TimelineUIUtils._filterForStats());
/**
- * @param {!SDK.TracingModel.Event} e
+ * @param {!Array<!SDK.TracingModel.Event>} events
*/
- function onStartEvent(e) {
- const duration = Math.min(e.endTime, endTime) - Math.max(e.startTime, startTime);
- if (ownTimes.length)
- ownTimes[ownTimes.length - 1] -= duration;
- ownTimes.push(duration);
- }
+ function buildRangeStatsCacheIfNeeded(events) {
+ if (events[Timeline.TimelineUIUtils._categoryBreakdownCacheSymbol])
+ return;
- /**
- * @param {!SDK.TracingModel.Event} e
- */
- function onEndEvent(e) {
- const category = Timeline.TimelineUIUtils.eventStyle(e).category.name;
- stats[category] = (stats[category] || 0) + ownTimes.pop();
- }
- return stats;
- }
+ // aggeregatedStats is a map by categories. For each category there's an array
+ // containing sorted time points which records accumulated value of the category.
+ const aggregatedStats = {};
+ const categoryStack = [];
+ let lastTime = 0;
+ TimelineModel.TimelineModel.forEachEvent(
+ events, onStartEvent, onEndEvent, undefined, undefined, undefined, filterForStats());
+
+ /**
+ * @return {function(!SDK.TracingModel.Event):boolean}
+ */
+ function filterForStats() {
+ const visibleEventsFilter = Timeline.TimelineUIUtils.visibleEventsFilter();
+ return event => visibleEventsFilter.accept(event) || SDK.TracingModel.isTopLevelEvent(event);
+ }
- /**
- * @return {function(!SDK.TracingModel.Event):boolean}
- */
- static _filterForStats() {
- const visibleEventsFilter = Timeline.TimelineUIUtils.visibleEventsFilter();
- return event => visibleEventsFilter.accept(event) || SDK.TracingModel.isTopLevelEvent(event);
- }
+ /**
+ * @param {string} category
+ * @param {number} time
+ */
+ function updateCategory(category, time) {
+ let statsArrays = aggregatedStats[category];
+ if (!statsArrays) {
+ statsArrays = {time: [], value: []};
+ aggregatedStats[category] = statsArrays;
+ }
+ if (statsArrays.time.length && statsArrays.time.peekLast() === time)
+ return;
+ const lastValue = statsArrays.value.length ? statsArrays.value.peekLast() : 0;
+ statsArrays.value.push(lastValue + time - lastTime);
+ statsArrays.time.push(time);
+ }
- /**
- * @param {!Array<!SDK.TracingModel.Event>} events
- */
- static _buildRangeStatsCacheIfNeeded(events) {
- if (events[Timeline.TimelineUIUtils._categoryBreakdownCacheSymbol])
- return;
+ /**
+ * @param {?string} from
+ * @param {?string} to
+ * @param {number} time
+ */
+ function categoryChange(from, to, time) {
+ if (from)
+ updateCategory(from, time);
+ lastTime = time;
+ if (to)
+ updateCategory(to, time);
+ }
- const aggregatedStats = {};
- const ownTimes = [];
- TimelineModel.TimelineModel.forEachEvent(
- events, onStartEvent, onEndEvent, undefined, undefined, undefined, Timeline.TimelineUIUtils._filterForStats());
+ /**
+ * @param {!SDK.TracingModel.Event} e
+ */
+ function onStartEvent(e) {
+ const category = Timeline.TimelineUIUtils.eventStyle(e).category.name;
+ const parentCategory = categoryStack.length ? categoryStack.peekLast() : null;
+ if (category !== parentCategory)
+ categoryChange(parentCategory, category, e.startTime);
+ categoryStack.push(category);
+ }
- /**
- * @param {!SDK.TracingModel.Event} e
- */
- function onStartEvent(e) {
- if (ownTimes.length)
- ownTimes[ownTimes.length - 1] -= e.duration;
- ownTimes.push(e.duration);
- }
+ /**
+ * @param {!SDK.TracingModel.Event} e
+ */
+ function onEndEvent(e) {
+ const category = categoryStack.pop();
+ const parentCategory = categoryStack.length ? categoryStack.peekLast() : null;
+ if (category !== parentCategory)
+ categoryChange(category, parentCategory, e.endTime);
+ }
- /**
- * @param {!SDK.TracingModel.Event} e
- */
- function onEndEvent(e) {
- const category = Timeline.TimelineUIUtils.eventStyle(e).category.name;
- aggregatedStats[category] = (aggregatedStats[category] || 0) + ownTimes.pop();
- if (!ownTimes.length)
- e[Timeline.TimelineUIUtils._categoryBreakdownCacheSymbol] = Object.assign({}, aggregatedStats);
+ const obj = /** @type {!Object} */ (events);
+ obj[Timeline.TimelineUIUtils._categoryBreakdownCacheSymbol] = aggregatedStats;
}
-
- const obj = /** @type {!Object} */ (events);
- obj[Timeline.TimelineUIUtils._categoryBreakdownCacheSymbol] = Object.assign({}, aggregatedStats);
}
/**
@@ -1256,7 +1241,7 @@ Timeline.TimelineUIUtils = class {
}
if (!request.previewElement && request.url && target)
- request.previewElement = await BrowserComponents.ImagePreview.build(target, request.url, false);
+ request.previewElement = await Components.ImagePreview.build(target, request.url, false);
if (request.previewElement)
contentHelper.appendElementRow(Common.UIString('Preview'), request.previewElement);
return contentHelper.fragment;
@@ -1496,7 +1481,7 @@ Timeline.TimelineUIUtils = class {
if (!imageURL)
return null;
const container = createElement('div');
- UI.appendStyle(container, 'browser_components/imagePreview.css');
+ UI.appendStyle(container, 'components/imagePreview.css');
container.classList.add('image-preview-container', 'vbox', 'link');
const img = container.createChild('img');
img.src = imageURL;
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/timeline/module.json b/chromium/third_party/blink/renderer/devtools/front_end/timeline/module.json
index 75f4094f494..f175531a90f 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/timeline/module.json
+++ b/chromium/third_party/blink/renderer/devtools/front_end/timeline/module.json
@@ -218,7 +218,7 @@
}
],
"dependencies": [
- "browser_components",
+ "components",
"layer_viewer",
"timeline_model",
"perf_ui",
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/timeline_model/TimelineJSProfile.js b/chromium/third_party/blink/renderer/devtools/front_end/timeline_model/TimelineJSProfile.js
index d544dd72ede..df66bb983d8 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/timeline_model/TimelineJSProfile.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/timeline_model/TimelineJSProfile.js
@@ -227,13 +227,20 @@ TimelineModel.TimelineJSProfileProcessor = class {
/**
* @param {*} profile
+ * @param {number} tid
+ * @param {boolean} injectPageEvent
+ * @param {?string=} name
* @return {!Array<!SDK.TracingManager.EventPayload>}
*/
- static buildTraceProfileFromCpuProfile(profile) {
- if (!profile)
- return [];
+ static buildTraceProfileFromCpuProfile(profile, tid, injectPageEvent, name) {
const events = [];
- appendEvent('TracingStartedInPage', {'sessionId': '1'}, 0, 0, 'M');
+ if (injectPageEvent)
+ appendEvent('TracingStartedInPage', {data: {'sessionId': '1'}}, 0, 0, 'M');
+ if (!name)
+ name = ls`Thread ${tid}`;
+ appendEvent(SDK.TracingModel.MetadataEvent.ThreadName, {name}, 0, 0, 'M', '__metadata');
+ if (!profile)
+ return events;
const idToNode = new Map();
const nodes = profile['nodes'];
for (let i = 0; i < nodes.length; ++i)
@@ -263,11 +270,11 @@ TimelineModel.TimelineJSProfileProcessor = class {
} else {
// A JS function.
if (!functionEvent)
- functionEvent = appendEvent('FunctionCall', {'sessionId': '1'}, currentTime);
+ functionEvent = appendEvent('FunctionCall', {data: {'sessionId': '1'}}, currentTime);
}
}
closeEvents();
- appendEvent('CpuProfile', {'cpuProfile': profile}, profile.endTime, 0, 'I');
+ appendEvent('CpuProfile', {data: {'cpuProfile': profile}}, profile.endTime, 0, 'I');
return events;
function closeEvents() {
@@ -281,23 +288,16 @@ TimelineModel.TimelineJSProfileProcessor = class {
/**
* @param {string} name
- * @param {*} data
+ * @param {*} args
* @param {number} ts
* @param {number=} dur
* @param {string=} ph
* @param {string=} cat
* @return {!SDK.TracingManager.EventPayload}
*/
- function appendEvent(name, data, ts, dur, ph, cat) {
- const event = /** @type {!SDK.TracingManager.EventPayload} */ ({
- cat: cat || 'disabled-by-default-devtools.timeline',
- name: name,
- ph: ph || 'X',
- pid: 1,
- tid: 1,
- ts: ts,
- args: {data: data}
- });
+ function appendEvent(name, args, ts, dur, ph, cat) {
+ const event = /** @type {!SDK.TracingManager.EventPayload} */ (
+ {cat: cat || 'disabled-by-default-devtools.timeline', name, ph: ph || 'X', pid: 1, tid, ts, args});
if (dur)
event.dur = dur;
events.push(event);
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/timeline_model/TimelineModel.js b/chromium/third_party/blink/renderer/devtools/front_end/timeline_model/TimelineModel.js
index d5a6910fb15..332ace621d7 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/timeline_model/TimelineModel.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/timeline_model/TimelineModel.js
@@ -180,8 +180,9 @@ TimelineModel.TimelineModel = class {
* @param {!SDK.TracingModel} tracingModel
*/
_processGenericTrace(tracingModel) {
- const browserMainThread =
- SDK.TracingModel.browserMainThread(tracingModel) || tracingModel.sortedProcesses()[0].sortedThreads()[0];
+ let browserMainThread = SDK.TracingModel.browserMainThread(tracingModel);
+ if (!browserMainThread && tracingModel.sortedProcesses().length)
+ browserMainThread = tracingModel.sortedProcesses()[0].sortedThreads()[0];
for (const process of tracingModel.sortedProcesses()) {
for (const thread of process.sortedThreads()) {
this._processThreadEvents(
@@ -200,6 +201,8 @@ TimelineModel.TimelineModel = class {
const metaEvent = metadataEvents.page[i];
const process = metaEvent.thread.process();
const endTime = i + 1 < length ? metadataEvents.page[i + 1].startTime : Infinity;
+ if (startTime === endTime)
+ continue;
this._legacyCurrentPage = metaEvent.args['data'] && metaEvent.args['data']['page'];
for (const thread of process.sortedThreads()) {
let workerUrl = null;
@@ -1274,9 +1277,7 @@ TimelineModel.TimelineModel.RecordType = {
InputLatencyMouseMove: 'InputLatency::MouseMove',
InputLatencyMouseWheel: 'InputLatency::MouseWheel',
ImplSideFling: 'InputHandlerProxy::HandleGestureFling::started',
- GCIdleLazySweep: 'ThreadState::performIdleLazySweep',
- GCCompleteSweep: 'ThreadState::completeSweep',
- GCCollectGarbage: 'BlinkGCMarking',
+ GCCollectGarbage: 'BlinkGC.AtomicPhase',
CryptoDoEncrypt: 'DoEncrypt',
CryptoDoEncryptReply: 'DoEncryptReply',
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/ui/ARIAUtils.js b/chromium/third_party/blink/renderer/devtools/front_end/ui/ARIAUtils.js
index 7cf6d2f0333..376b50d328e 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/ui/ARIAUtils.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/ui/ARIAUtils.js
@@ -56,6 +56,20 @@ UI.ARIAUtils.markAsTextBox = function(element) {
/**
* @param {!Element} element
*/
+UI.ARIAUtils.markAsMenu = function(element) {
+ element.setAttribute('role', 'menu');
+};
+
+/**
+ * @param {!Element} element
+ */
+UI.ARIAUtils.markAsMenuItem = function(element) {
+ element.setAttribute('role', 'menuitem');
+};
+
+/**
+ * @param {!Element} element
+ */
UI.ARIAUtils.markAsHidden = function(element) {
element.setAttribute('aria-hidden', 'true');
};
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/ui/InspectorView.js b/chromium/third_party/blink/renderer/devtools/front_end/ui/InspectorView.js
index ac09596a632..2a4f6ed8a35 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/ui/InspectorView.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/ui/InspectorView.js
@@ -284,16 +284,6 @@ UI.InspectorView = class extends UI.VBox {
}
}
}
-
- if (event.key === '[') {
- this._tabbedPane.selectPrevTab();
- event.consume(true);
- }
-
- if (event.key === ']') {
- this._tabbedPane.selectNextTab();
- event.consume(true);
- }
}
/**
@@ -358,7 +348,7 @@ UI.inspectorView;
* @implements {UI.ActionDelegate}
* @unrestricted
*/
-UI.InspectorView.DrawerToggleActionDelegate = class {
+UI.InspectorView.ActionDelegate = class {
/**
* @override
* @param {!UI.Context} context
@@ -366,10 +356,20 @@ UI.InspectorView.DrawerToggleActionDelegate = class {
* @return {boolean}
*/
handleAction(context, actionId) {
- if (UI.inspectorView.drawerVisible())
- UI.inspectorView._closeDrawer();
- else
- UI.inspectorView._showDrawer(true);
- return true;
+ switch (actionId) {
+ case 'main.toggle-drawer':
+ if (UI.inspectorView.drawerVisible())
+ UI.inspectorView._closeDrawer();
+ else
+ UI.inspectorView._showDrawer(true);
+ return true;
+ case 'main.next-tab':
+ UI.inspectorView._tabbedPane.selectNextTab();
+ return true;
+ case 'main.previous-tab':
+ UI.inspectorView._tabbedPane.selectPrevTab();
+ return true;
+ }
+ return false;
}
};
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/ui/ListControl.js b/chromium/third_party/blink/renderer/devtools/front_end/ui/ListControl.js
index 56f19464826..f30619c0739 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/ui/ListControl.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/ui/ListControl.js
@@ -136,6 +136,14 @@ UI.ListControl = class {
console.error('Item to refresh is not present');
return;
}
+ this.refreshItemByIndex(index);
+ }
+
+ /**
+ * @param {number} index
+ */
+ refreshItemByIndex(index) {
+ const item = this._model.at(index);
this._itemToElement.delete(item);
this.invalidateRange(index, index + 1);
if (this._selectedIndex !== -1)
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/ui/ShortcutRegistry.js b/chromium/third_party/blink/renderer/devtools/front_end/ui/ShortcutRegistry.js
index 6b72862fccf..0178835dbff 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/ui/ShortcutRegistry.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/ui/ShortcutRegistry.js
@@ -35,6 +35,20 @@ UI.ShortcutRegistry = class {
}
/**
+ * @return {!Array<number>}
+ */
+ globalShortcutKeys() {
+ const keys = [];
+ for (const key of this._defaultKeyToActions.keysArray()) {
+ const actions = this._defaultKeyToActions.get(key).valuesArray();
+ const applicableActions = this._actionRegistry.applicableActions(actions, new UI.Context());
+ if (applicableActions.length)
+ keys.push(Number(key));
+ }
+ return keys;
+ }
+
+ /**
* @param {string} actionId
* @return {!Array.<!UI.KeyboardShortcut.Descriptor>}
*/
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/ui/SoftContextMenu.js b/chromium/third_party/blink/renderer/devtools/front_end/ui/SoftContextMenu.js
index 79304c3b102..aff0106c20b 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/ui/SoftContextMenu.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/ui/SoftContextMenu.js
@@ -36,6 +36,8 @@ UI.SoftContextMenu = class {
this._items = items;
this._itemSelectedCallback = itemSelectedCallback;
this._parentMenu = parentMenu;
+ /** @type {?Element} */
+ this._highlightedMenuItemElement = null;
}
/**
@@ -60,7 +62,8 @@ UI.SoftContextMenu = class {
this._parentMenu ? UI.GlassPane.AnchorBehavior.PreferRight : UI.GlassPane.AnchorBehavior.PreferBottom);
this._contextMenuElement = this._glassPane.contentElement.createChild('div', 'soft-context-menu');
- this._contextMenuElement.tabIndex = 0;
+ this._contextMenuElement.tabIndex = -1;
+ UI.ARIAUtils.markAsMenu(this._contextMenuElement);
this._contextMenuElement.addEventListener('mouseup', e => e.consume(), false);
this._contextMenuElement.addEventListener('keydown', this._menuKeyDown.bind(this), false);
@@ -106,6 +109,8 @@ UI.SoftContextMenu = class {
return this._createSubMenu(item);
const menuItemElement = createElementWithClass('div', 'soft-context-menu-item');
+ menuItemElement.tabIndex = -1;
+ UI.ARIAUtils.markAsMenuItem(menuItemElement);
const checkMarkElement = UI.Icon.create('smallicon-checkmark', 'checkmark');
menuItemElement.appendChild(checkMarkElement);
if (!item.checked)
@@ -131,12 +136,22 @@ UI.SoftContextMenu = class {
menuItemElement.addEventListener('mouseleave', this._menuItemMouseLeave.bind(this), false);
menuItemElement._actionId = item.id;
+
+ let accessibleName = item.label;
+ if (item.checked)
+ accessibleName += ', checked';
+ if (item.shortcut)
+ accessibleName += ', ' + item.shortcut;
+ UI.ARIAUtils.setAccessibleName(menuItemElement, accessibleName);
+
return menuItemElement;
}
_createSubMenu(item) {
const menuItemElement = createElementWithClass('div', 'soft-context-menu-item');
menuItemElement._subItems = item.subItems;
+ menuItemElement.tabIndex = -1;
+ UI.ARIAUtils.markAsMenuItem(menuItemElement);
// Occupy the same space on the left in all items.
const checkMarkElement = UI.Icon.create('smallicon-checkmark', 'soft-context-menu-item-checkmark');
@@ -146,8 +161,13 @@ UI.SoftContextMenu = class {
menuItemElement.createTextChild(item.label);
- const subMenuArrowElement = menuItemElement.createChild('span', 'soft-context-menu-item-submenu-arrow');
- subMenuArrowElement.textContent = '\u25B6'; // BLACK RIGHT-POINTING TRIANGLE
+ if (Host.isMac() && !UI.themeSupport.hasTheme()) {
+ const subMenuArrowElement = menuItemElement.createChild('span', 'soft-context-menu-item-submenu-arrow');
+ subMenuArrowElement.textContent = '\u25B6'; // BLACK RIGHT-POINTING TRIANGLE
+ } else {
+ const subMenuArrowElement = UI.Icon.create('smallicon-triangle-right', 'soft-context-menu-item-submenu-arrow');
+ menuItemElement.appendChild(subMenuArrowElement);
+ }
menuItemElement.addEventListener('mousedown', this._menuItemMouseDown.bind(this), false);
menuItemElement.addEventListener('mouseup', this._menuItemMouseUp.bind(this), false);
@@ -254,9 +274,10 @@ UI.SoftContextMenu = class {
}
this._highlightedMenuItemElement = menuItemElement;
if (this._highlightedMenuItemElement) {
- this._highlightedMenuItemElement.classList.add('force-white-icons');
+ if (UI.themeSupport.hasTheme() || Host.isMac())
+ this._highlightedMenuItemElement.classList.add('force-white-icons');
this._highlightedMenuItemElement.classList.add('soft-context-menu-item-mouse-over');
- this._contextMenuElement.focus();
+ this._highlightedMenuItemElement.focus();
if (scheduleSubMenu && this._highlightedMenuItemElement._subItems &&
!this._highlightedMenuItemElement._subMenuTimer) {
this._highlightedMenuItemElement._subMenuTimer =
@@ -268,7 +289,9 @@ UI.SoftContextMenu = class {
_highlightPrevious() {
let menuItemElement = this._highlightedMenuItemElement ? this._highlightedMenuItemElement.previousSibling :
this._contextMenuElement.lastChild;
- while (menuItemElement && (menuItemElement._isSeparator || menuItemElement._isCustom))
+ while (menuItemElement &&
+ (menuItemElement._isSeparator || menuItemElement._isCustom ||
+ menuItemElement.classList.contains('soft-context-menu-disabled')))
menuItemElement = menuItemElement.previousSibling;
if (menuItemElement)
this._highlightMenuItem(menuItemElement, false);
@@ -277,7 +300,9 @@ UI.SoftContextMenu = class {
_highlightNext() {
let menuItemElement = this._highlightedMenuItemElement ? this._highlightedMenuItemElement.nextSibling :
this._contextMenuElement.firstChild;
- while (menuItemElement && (menuItemElement._isSeparator || menuItemElement._isCustom))
+ while (menuItemElement &&
+ (menuItemElement._isSeparator || menuItemElement._isCustom ||
+ menuItemElement.classList.contains('soft-context-menu-disabled')))
menuItemElement = menuItemElement.nextSibling;
if (menuItemElement)
this._highlightMenuItem(menuItemElement, false);
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/ui/TabbedPane.js b/chromium/third_party/blink/renderer/devtools/front_end/ui/TabbedPane.js
index 44db82d8534..b1d9560bc79 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/ui/TabbedPane.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/ui/TabbedPane.js
@@ -560,6 +560,8 @@ UI.TabbedPane = class extends UI.VBox {
_createDropDownButton() {
const dropDownContainer = createElementWithClass('div', 'tabbed-pane-header-tabs-drop-down-container');
const chevronIcon = UI.Icon.create('largeicon-chevron', 'chevron-icon');
+ UI.ARIAUtils.markAsButton(dropDownContainer);
+ UI.ARIAUtils.setAccessibleName(dropDownContainer, ls`More tabs`);
dropDownContainer.appendChild(chevronIcon);
dropDownContainer.addEventListener('click', this._dropDownClicked.bind(this));
dropDownContainer.addEventListener('mousedown', event => {
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/ui/inspectorCommon.css b/chromium/third_party/blink/renderer/devtools/front_end/ui/inspectorCommon.css
index 2e7fa6ecce4..824db97feb5 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/ui/inspectorCommon.css
+++ b/chromium/third_party/blink/renderer/devtools/front_end/ui/inspectorCommon.css
@@ -137,9 +137,8 @@ iframe.widget {
.highlighted-search-result {
border-radius: 1px;
- padding: 1px;
- margin: -1px;
background-color: rgba(255, 255, 0, 0.8);
+ outline: 1px solid rgba(255, 255, 0, 0.8);
}
.-theme-with-dark-background .highlighted-search-result,
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/ui/softContextMenu.css b/chromium/third_party/blink/renderer/devtools/front_end/ui/softContextMenu.css
index e159a13f0d3..ced1f40738d 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/ui/softContextMenu.css
+++ b/chromium/third_party/blink/renderer/devtools/front_end/ui/softContextMenu.css
@@ -5,19 +5,32 @@
*/
.soft-context-menu {
- border: 1px solid rgba(196, 196, 196, 0.9);
- border-top: 1px solid rgba(196, 196, 196, 0.5);
+ overflow-y: auto;
+ min-width: 160px !important;
/* NOTE: Keep padding in sync with padding adjustment in SoftContextMenu.js */
padding: 4px 0 4px 0;
+ border: 1px solid #b9b9b9;
+ background-color: #FFF;
+ box-shadow: var(--drop-shadow);
+ --context-menu-hover-bg: #ebebeb;
+ --context-menu-hover-color: #222;
+ --context-menu-seperator-color: var(--divider-color);
+}
+
+:host:host-context(.platform-mac):host-context(html:not(.-theme-with-dark-background)) .soft-context-menu {
+ border: 1px solid rgba(196, 196, 196, 0.9);
+ border-top: 1px solid rgba(196, 196, 196, 0.5);
border-radius: 4px;
background-color: rgb(240, 240, 240);
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.25);
- overflow-y: auto;
- min-width: 160px !important;
+ --context-menu-hover-color: #FFF;
+ --context-menu-seperator-color: rgb(222, 222, 222);
}
:host-context(.-theme-with-dark-background) .soft-context-menu {
- box-shadow: 0 5px 10px rgba(0, 0, 0, 0.25);
+ --context-menu-hover-bg: var(--selection-bg-color);
+ --context-menu-hover-color: var(--selection-fg-color);
+ border: none;
}
.soft-context-menu-item {
@@ -45,33 +58,34 @@
.soft-context-menu-separator > .separator-line {
margin: 0;
height: 5px;
- border-bottom: 1px solid rgb(222, 222, 222);
+ border-bottom: 1px solid var(--context-menu-seperator-color);
pointer-events: none;
}
.soft-context-menu-item-mouse-over,
.-theme-selection-color {
- border-top: 1px solid var(--selection-bg-color);
- border-bottom: 1px solid var(--selection-bg-color);
- background-color: var(--selection-bg-color);
- color: white;
+ border-top: 1px solid var(--context-menu-hover-bg);
+ border-bottom: 1px solid var(--context-menu-hover-bg);
+ background-color: var(--context-menu-hover-bg);
+ color: var(--context-menu-hover-color);
}
-:host-context(.platform-mac) .soft-context-menu-item-mouse-over, -theme-preserve {
+:host:host-context(.platform-mac):host-context(html:not(.-theme-with-dark-background)) .soft-context-menu-item-mouse-over {
border-top: 1px solid transparent;
border-bottom: 1px solid transparent;
background-image: linear-gradient(to right, hsl(214, 81%, 60%), hsl(214, 100%, 56%));
}
-:host-context(.platform-mac) .separator-line {
+:host:host-context(.platform-mac):host-context(html:not(.-theme-with-dark-background)) .separator-line {
border-width: 2px;
}
.soft-context-menu-item-submenu-arrow {
pointer-events: none;
font-size: 11px;
- flex: 1 1 auto;
text-align: right;
+ align-self: center;
+ margin-left: auto;
}
.soft-context-menu-item-mouse-over .soft-context-menu-item-checkmark {
@@ -103,6 +117,11 @@
margin: auto 5px auto 0px;
}
+:host-context(.-theme-with-dark-background) .checkmark {
+ filter: invert(80%);
+}
+
.soft-context-menu-item-mouse-over .checkmark {
opacity: 1;
+ filter: none;
}
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/ui/treeoutline.css b/chromium/third_party/blink/renderer/devtools/front_end/ui/treeoutline.css
index 59abb4602d2..b83ae08c0b7 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/ui/treeoutline.css
+++ b/chromium/third_party/blink/renderer/devtools/front_end/ui/treeoutline.css
@@ -21,7 +21,7 @@
position: relative;
}
-.tree-outline li.hovered:not(.selected) .selection {
+.tree-outline:not(.hide-selection-when-blurred) li.hovered:not(.selected) .selection {
display: block;
left: 3px;
right: 3px;
@@ -35,27 +35,27 @@
margin-left: -10000px;
}
-.tree-outline li.selected .selection {
+.tree-outline:not(.hide-selection-when-blurred) li.selected .selection {
display: block;
background-color: var(--selection-inactive-bg-color);
}
-.tree-outline li.in-clipboard .highlight {
+.tree-outline:not(.hide-selection-when-blurred) li.in-clipboard .highlight {
outline: 1px dotted darkgrey;
}
-.tree-outline li.elements-drag-over .selection {
+.tree-outline:not(.hide-selection-when-blurred) li.elements-drag-over .selection {
display: block;
margin-top: -2px;
border-top: 2px solid;
border-top-color: var(--selection-bg-color);
}
-ol.tree-outline li.selected:focus .selection {
+ol.tree-outline:not(.hide-selection-when-blurred) li.selected:focus .selection {
background-color: var(--selection-bg-color);
}
-ol.tree-outline li.parent.selected:focus::before {
+ol.tree-outline:not(.hide-selection-when-blurred) li.parent.selected:focus::before {
background-color: var(--selection-fg-color);
}
@@ -81,11 +81,11 @@ ol.tree-outline,
min-height: 16px;
}
-ol.tree-outline li.selected:focus {
+ol.tree-outline:not(.hide-selection-when-blurred) li.selected:focus {
color: var(--selection-fg-color);
}
-ol.tree-outline li.selected:focus * {
+ol.tree-outline:not(.hide-selection-when-blurred) li.selected:focus * {
color: inherit;
}
@@ -107,11 +107,11 @@ ol.tree-outline li.selected:focus * {
-webkit-user-select: none;
-webkit-mask-image: url(Images/treeoutlineTriangles.png);
-webkit-mask-size: 32px 24px;
- content: "aa";
- color: transparent;
+ content: "\00a0\00a0";
text-shadow: none;
margin-right: -2px;
height: 12px;
+ width: 13px;
}
.tree-outline li:not(.parent)::before {
@@ -157,3 +157,13 @@ ol.tree-outline li.selected:focus * {
.tree-outline.tree-outline-dense ol {
padding-left: 10px;
}
+
+.tree-outline.hide-selection-when-blurred .selected:focus[data-keyboard-focus="true"] {
+ background: rgba(0, 0, 0, 0.08);
+ border-radius: 2px;
+}
+
+.tree-outline-disclosure:not(.tree-outline-disclosure-hide-overflow) .tree-outline.hide-selection-when-blurred .selected:focus[data-keyboard-focus="true"] {
+ width: fit-content;
+ padding-right: 3px;
+}
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/ui/treeoutline.js b/chromium/third_party/blink/renderer/devtools/front_end/ui/treeoutline.js
index 20a000dcab7..df4d0185bd8 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/ui/treeoutline.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/ui/treeoutline.js
@@ -43,6 +43,7 @@ UI.TreeOutline = class extends Common.Object {
this.contentElement = this._rootElement._childrenListNode;
this.contentElement.addEventListener('keydown', this._treeKeyDown.bind(this), true);
+ this._showSelectionOnKeyboardFocus = false;
this._focusable = true;
this.setFocusable(this._focusable);
if (this._focusable)
@@ -51,6 +52,14 @@ UI.TreeOutline = class extends Common.Object {
UI.ARIAUtils.markAsTree(this.element);
}
+ /**
+ * @param {boolean} show
+ */
+ setShowSelectionOnKeyboardFocus(show) {
+ this.contentElement.classList.toggle('hide-selection-when-blurred', show);
+ this._showSelectionOnKeyboardFocus = show;
+ }
+
_createRootElement() {
this._rootElement = new UI.TreeElement();
this._rootElement.treeOutline = this;
@@ -793,7 +802,9 @@ UI.TreeElement = class {
if (element.treeElement !== this || element.hasSelection())
return;
- const toggleOnClick = this.toggleOnClick && !this.selectable;
+ console.assert(!!this.treeOutline);
+ const showSelectionOnKeyboardFocus = this.treeOutline ? this.treeOutline._showSelectionOnKeyboardFocus : false;
+ const toggleOnClick = this.toggleOnClick && (showSelectionOnKeyboardFocus || !this.selectable);
const isInTriangle = this.isEventWithinDisclosureTriangle(event);
if (!toggleOnClick && !isInTriangle)
return;
@@ -1068,11 +1079,13 @@ UI.TreeElement = class {
}
_onFocus() {
- this._listItemNode.classList.add('force-white-icons');
+ if (!this.treeOutline.contentElement.classList.contains('hide-selection-when-blurred'))
+ this._listItemNode.classList.add('force-white-icons');
}
_onBlur() {
- this._listItemNode.classList.remove('force-white-icons');
+ if (!this.treeOutline.contentElement.classList.contains('hide-selection-when-blurred'))
+ this._listItemNode.classList.remove('force-white-icons');
}
/**
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/worker_app.json b/chromium/third_party/blink/renderer/devtools/front_end/worker_app.json
index deadd1ff68c..bb5c7d438ff 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/worker_app.json
+++ b/chromium/third_party/blink/renderer/devtools/front_end/worker_app.json
@@ -2,7 +2,6 @@
"modules" : [
{ "name": "mobile_throttling", "type": "autostart" },
{ "name": "worker_main", "type": "autostart" },
- { "name": "browser_components", "type": "autostart" },
{ "name": "browser_console" },
{ "name": "browser_debugger" },
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/workspace/FileManager.js b/chromium/third_party/blink/renderer/devtools/front_end/workspace/FileManager.js
index 16063e8311a..740a6ecdb4c 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/workspace/FileManager.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/workspace/FileManager.js
@@ -51,8 +51,9 @@ Workspace.FileManager = class extends Common.Object {
*/
save(url, content, forceSaveAs) {
// Remove this url from the saved URLs while it is being saved.
+ const result = new Promise(resolve => this._saveCallbacks.set(url, resolve));
InspectorFrontendHost.save(url, content, forceSaveAs);
- return new Promise(resolve => this._saveCallbacks.set(url, resolve));
+ return result;
}
/**
@@ -89,7 +90,7 @@ Workspace.FileManager = class extends Common.Object {
* @param {string} url
*/
close(url) {
- // Currently a no-op.
+ InspectorFrontendHost.close(url);
}
/**
diff --git a/chromium/third_party/blink/renderer/devtools/front_end/workspace/Workspace.js b/chromium/third_party/blink/renderer/devtools/front_end/workspace/Workspace.js
index 83e676e48a8..54a4c98e345 100644
--- a/chromium/third_party/blink/renderer/devtools/front_end/workspace/Workspace.js
+++ b/chromium/third_party/blink/renderer/devtools/front_end/workspace/Workspace.js
@@ -213,7 +213,6 @@ Workspace.projectTypes = {
Debugger: 'debugger',
Formatter: 'formatter',
Network: 'network',
- Snippets: 'snippets',
FileSystem: 'filesystem',
ContentScripts: 'contentscripts',
Service: 'service'
diff --git a/chromium/third_party/blink/renderer/modules/BUILD.gn b/chromium/third_party/blink/renderer/modules/BUILD.gn
index 6561c4f9cb5..6f94a382cec 100644
--- a/chromium/third_party/blink/renderer/modules/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/BUILD.gn
@@ -97,7 +97,6 @@ target("jumbo_" + modules_target_type, "modules") {
"//third_party/blink/renderer/modules/beacon",
"//third_party/blink/renderer/modules/bluetooth",
"//third_party/blink/renderer/modules/broadcastchannel",
- "//third_party/blink/renderer/modules/budget",
"//third_party/blink/renderer/modules/cache_storage",
"//third_party/blink/renderer/modules/canvas",
"//third_party/blink/renderer/modules/clipboard",
@@ -163,6 +162,8 @@ target("jumbo_" + modules_target_type, "modules") {
"//third_party/blink/renderer/modules/webusb",
"//third_party/blink/renderer/modules/xr",
"//third_party/icu",
+ "//third_party/webrtc/pc:libjingle_peerconnection",
+ "//third_party/webrtc_overrides:init_webrtc",
"//third_party/zlib",
]
@@ -241,7 +242,6 @@ jumbo_source_set("unit_tests") {
"animationworklet/worklet_animation_test.cc",
"background_fetch/background_fetch_icon_loader_test.cc",
"background_fetch/background_fetch_manager_test.cc",
- "background_fetch/background_fetch_settled_fetches_test.cc",
"cache_storage/cache_test.cc",
"canvas/canvas2d/canvas_rendering_context_2d_api_test.cc",
"canvas/canvas2d/canvas_rendering_context_2d_test.cc",
@@ -264,6 +264,7 @@ jumbo_source_set("unit_tests") {
"indexeddb/mock_web_idb_database.cc",
"indexeddb/mock_web_idb_database.h",
"manifest/image_resource_type_converters_test.cc",
+ "media_controls/elements/media_control_display_cutout_fullscreen_button_element_test.cc",
"media_controls/elements/media_control_input_element_test.cc",
"media_controls/elements/media_control_loading_panel_element_test.cc",
"media_controls/elements/media_control_overlay_play_button_element_test.cc",
@@ -295,6 +296,7 @@ jumbo_source_set("unit_tests") {
"payments/payments_validators_test.cc",
"peerconnection/rtc_data_channel_test.cc",
"peerconnection/rtc_peer_connection_test.cc",
+ "picture_in_picture/html_video_element_picture_in_picture_test.cc",
"presentation/mock_presentation_service.h",
"presentation/presentation_availability_state_test.cc",
"presentation/presentation_availability_test.cc",
diff --git a/chromium/third_party/blink/renderer/modules/DEPS b/chromium/third_party/blink/renderer/modules/DEPS
index f861230e084..20352caf078 100644
--- a/chromium/third_party/blink/renderer/modules/DEPS
+++ b/chromium/third_party/blink/renderer/modules/DEPS
@@ -1,6 +1,7 @@
include_rules = [
"+base/atomic_sequence_num.h",
"+base/memory/scoped_refptr.h",
+ "+mojo/public/cpp/bindings",
"+services/network/public/cpp/shared_url_loader_factory.h",
"+services/service_manager/public/mojom/interface_provider.mojom-blink.h",
"+third_party/blink/public/common",
diff --git a/chromium/third_party/blink/renderer/modules/OWNERS b/chromium/third_party/blink/renderer/modules/OWNERS
index 84b8d7d5c7d..731bf092854 100644
--- a/chromium/third_party/blink/renderer/modules/OWNERS
+++ b/chromium/third_party/blink/renderer/modules/OWNERS
@@ -7,6 +7,7 @@ mlamouri@chromium.org
# Reviewers for inspector-related code:
dgozman@chromium.org
pfeldman@chromium.org
+caseq@chromium.org
# TEAM: platform-architecture-dev@chromium.org
# COMPONENT: Blink>Internals>Modularization
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 f48838b0f46..cac291e66d8 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
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/core/accessibility/ax_context.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/html/html_body_element.h"
@@ -24,9 +25,8 @@ class AccessibilityObjectModelTest
protected:
AXObjectCacheImpl* AXObjectCache() {
- GetDocument().GetSettings()->SetAccessibilityEnabled(true);
return static_cast<AXObjectCacheImpl*>(
- GetDocument().GetOrCreateAXObjectCache());
+ GetDocument().ExistingAXObjectCache());
}
};
@@ -34,6 +34,7 @@ TEST_F(AccessibilityObjectModelTest, DOMElementsHaveAnAccessibleNode) {
SimRequest main_resource("https://example.com/", "text/html");
LoadURL("https://example.com/");
main_resource.Complete("<button id=button>Click me</button>");
+ AXContext ax_context(GetDocument());
auto* button = GetDocument().getElementById("button");
EXPECT_NE(nullptr, button->accessibleNode());
@@ -45,6 +46,7 @@ TEST_F(AccessibilityObjectModelTest, SetAccessibleNodeRole) {
SimRequest main_resource("https://example.com/", "text/html");
LoadURL("https://example.com/");
main_resource.Complete("<button id=button>Click me</button>");
+ AXContext ax_context(GetDocument());
auto* cache = AXObjectCache();
ASSERT_NE(nullptr, cache);
@@ -66,6 +68,7 @@ TEST_F(AccessibilityObjectModelTest, AOMDoesNotReflectARIA) {
SimRequest main_resource("https://example.com/", "text/html");
LoadURL("https://example.com/");
main_resource.Complete("<input id=textbox>");
+ AXContext ax_context(GetDocument());
// Set ARIA attributes.
auto* textbox = GetDocument().getElementById("textbox");
@@ -96,6 +99,7 @@ TEST_F(AccessibilityObjectModelTest, AOMPropertiesCanBeCleared) {
SimRequest main_resource("https://example.com/", "text/html");
LoadURL("https://example.com/");
main_resource.Complete("<input type=button id=button>");
+ AXContext ax_context(GetDocument());
// Set ARIA attributes.
auto* button = GetDocument().getElementById("button");
@@ -141,6 +145,7 @@ TEST_F(AccessibilityObjectModelTest, RangeProperties) {
SimRequest main_resource("https://example.com/", "text/html");
LoadURL("https://example.com/");
main_resource.Complete("<div role=slider id=slider>");
+ AXContext ax_context(GetDocument());
auto* slider = GetDocument().getElementById("slider");
ASSERT_NE(nullptr, slider);
@@ -164,6 +169,7 @@ TEST_F(AccessibilityObjectModelTest, Level) {
SimRequest main_resource("https://example.com/", "text/html");
LoadURL("https://example.com/");
main_resource.Complete("<div role=heading id=heading>");
+ AXContext ax_context(GetDocument());
auto* heading = GetDocument().getElementById("heading");
ASSERT_NE(nullptr, heading);
@@ -180,6 +186,7 @@ TEST_F(AccessibilityObjectModelTest, ListItem) {
LoadURL("https://example.com/");
main_resource.Complete(
"<div role=list><div role=listitem id=listitem></div></div>");
+ AXContext ax_context(GetDocument());
auto* listitem = GetDocument().getElementById("listitem");
ASSERT_NE(nullptr, listitem);
@@ -204,6 +211,7 @@ TEST_F(AccessibilityObjectModelTest, Grid) {
</div>
</div>
)HTML");
+ AXContext ax_context(GetDocument());
auto* grid = GetDocument().getElementById("grid");
ASSERT_NE(nullptr, grid);
@@ -293,6 +301,7 @@ TEST_F(AccessibilityObjectModelTest, SparseAttributes) {
<div id=error role=article>Error</div>
<div id=error2 role=banner>Error 2</div>
)HTML");
+ AXContext ax_context(GetDocument());
auto* target = GetDocument().getElementById("target");
auto* cache = AXObjectCache();
@@ -360,6 +369,7 @@ TEST_F(AccessibilityObjectModelTest, LabeledBy) {
<label id=l2>Label 2</label>
<label id=l3>Label 3</label>
)HTML");
+ AXContext ax_context(GetDocument());
auto* target = GetDocument().getElementById("target");
auto* l1 = GetDocument().getElementById("l1");
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_inline_text_box.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_inline_text_box.cc
index a0ef93d085c..2a3837fb577 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_inline_text_box.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_inline_text_box.cc
@@ -75,9 +75,8 @@ void AXInlineTextBox::GetRelativeBounds(AXObject** out_container,
// Subtract the local bounding box of the parent because they're
// both in the same coordinate system.
- LayoutObject* parent_layout_object = ParentObject()->GetLayoutObject();
FloatRect parent_bounding_box =
- parent_layout_object->LocalBoundingBoxRectForAccessibility();
+ ParentObject()->LocalBoundingBoxRectForAccessibility();
out_bounds_in_container.MoveBy(-parent_bounding_box.Location());
}
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 8fad56dd79e..83d3bc2792d 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
@@ -212,7 +212,9 @@ static LayoutBoxModelObject* NextContinuation(LayoutObject* layout_object) {
AXLayoutObject::AXLayoutObject(LayoutObject* layout_object,
AXObjectCacheImpl& ax_object_cache)
: AXNodeObject(layout_object->GetNode(), ax_object_cache),
- layout_object_(layout_object) {
+ layout_object_(layout_object),
+ is_autofill_available_(false) {
+// TODO(aleventhal) Get correct current state of autofill.
#if DCHECK_IS_ON()
layout_object_->SetHasAXObject(true);
#endif
@@ -233,6 +235,16 @@ LayoutBoxModelObject* AXLayoutObject::GetLayoutBoxModelObject() const {
return ToLayoutBoxModelObject(layout_object_);
}
+bool IsProgrammaticallyScrollable(LayoutBox* box) {
+ if (!box->HasOverflowClip()) {
+ // If overflow is visible it is not scrollable.
+ return false;
+ }
+ // Return true if the content is larger than the available space.
+ return box->PixelSnappedScrollWidth() != box->PixelSnappedClientWidth() ||
+ box->PixelSnappedScrollHeight() != box->PixelSnappedClientHeight();
+}
+
ScrollableArea* AXLayoutObject::GetScrollableAreaIfScrollable() const {
if (IsWebArea())
return DocumentFrameView()->LayoutViewport();
@@ -241,10 +253,24 @@ ScrollableArea* AXLayoutObject::GetScrollableAreaIfScrollable() const {
return nullptr;
LayoutBox* box = ToLayoutBox(layout_object_);
- if (!box->CanBeScrolledAndHasScrollableArea())
- return nullptr;
- return box->GetScrollableArea();
+ // This should possibly use box->CanBeScrolledAndHasScrollableArea() as it
+ // used to; however, accessibility must consider any kind of non-visible
+ // overflow as programmatically scrollable. Unfortunately
+ // LayoutBox::CanBeScrolledAndHasScrollableArea() method calls
+ // LayoutBox::CanBeProgramaticallyScrolled() which does not consider
+ // visibility:hidden content to be programmatically scrollable, although it
+ // certainly is, and can even be scrolled by selecting and using shift+arrow
+ // keys. It should be noticed that the new code used here reduces the overall
+ // amount of work as well.
+ // It is not sufficient to expose it only in the anoymous child, because that
+ // child is truncated in platform accessibility trees, which present the
+ // textfield as a leaf.
+ ScrollableArea* scrollable_area = box->GetScrollableArea();
+ if (scrollable_area && IsProgrammaticallyScrollable(box))
+ return scrollable_area;
+
+ return nullptr;
}
static bool IsImageOrAltText(LayoutBoxModelObject* box, Node* node) {
@@ -280,14 +306,14 @@ AccessibilityRole AXLayoutObject::NativeAccessibilityRoleIgnoringAria() const {
if (node && node->IsLink())
return kImageMapRole;
if (IsHTMLInputElement(node))
- return HasPopup() ? kPopUpButtonRole : kButtonRole;
+ return ButtonRoleType();
if (IsSVGImage())
return kSVGRootRole;
+
return kImageRole;
}
- // Note: if JavaScript is disabled, the layoutObject won't be a
- // LayoutHTMLCanvas.
- if (IsHTMLCanvasElement(node) && layout_object_->IsCanvas())
+
+ if (IsHTMLCanvasElement(node))
return kCanvasRole;
if (css_box && css_box->IsLayoutView())
@@ -651,7 +677,7 @@ bool AXLayoutObject::ComputeAccessibilityIsIgnored(
if (layout_object_->IsBR())
return false;
- if (CanSetFocusAttribute())
+ if (CanSetFocusAttribute() && GetNode() && !IsHTMLBodyElement(GetNode()))
return false;
if (IsLink())
@@ -767,12 +793,15 @@ bool AXLayoutObject::ComputeAccessibilityIsIgnored(
if (IsCanvas()) {
if (CanvasHasFallbackContent())
return false;
- LayoutHTMLCanvas* canvas = ToLayoutHTMLCanvas(layout_object_);
- if (canvas->Size().Height() <= 1 || canvas->Size().Width() <= 1) {
+
+ const auto* canvas = ToLayoutHTMLCanvasOrNull(layout_object_);
+ if (canvas &&
+ (canvas->Size().Height() <= 1 || canvas->Size().Width() <= 1)) {
if (ignored_reasons)
ignored_reasons->push_back(IgnoredReason(kAXProbablyPresentational));
return true;
}
+
// Otherwise fall through; use presence of help text, title, or description
// to decide.
}
@@ -1100,7 +1129,7 @@ String AXLayoutObject::ImageDataUrl(const IntSize& max_size) const {
if (!buffer)
return String();
- return buffer->ToDataURL("image/png", 1.0);
+ return buffer->ToDataURL(kMimeTypePng, 1.0);
}
String AXLayoutObject::GetText() const {
@@ -1873,15 +1902,19 @@ AXObject* AXLayoutObject::RawNextSibling() const {
}
void AXLayoutObject::AddChildren() {
- DCHECK(!IsDetached());
+ if (IsDetached())
+ return;
+
+ if (IsHTMLCanvasElement(GetNode()))
+ return AXNodeObject::AddChildren();
+
// 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;
- HeapVector<Member<AXObject>> owned_children;
+ AXObjectVector owned_children;
ComputeAriaOwnsChildren(owned_children);
for (AXObject* obj = RawFirstChild(); obj; obj = obj->RawNextSibling()) {
@@ -1894,7 +1927,6 @@ void AXLayoutObject::AddChildren() {
AddHiddenChildren();
AddPopupChildren();
AddImageMapChildren();
- AddCanvasChildren();
AddRemoteSVGChildren();
AddTableChildren();
AddInlineTextBoxChildren(false);
@@ -2289,7 +2321,7 @@ bool AXLayoutObject::OnNativeSetSelectionAction(const AXSelection& selection) {
if (anchor_object->GetLayoutObject()->GetNode() &&
anchor_object->GetLayoutObject()->GetNode()->DispatchEvent(
- Event::CreateCancelableBubble(EventTypeNames::selectstart)) !=
+ *Event::CreateCancelableBubble(EventTypeNames::selectstart)) !=
DispatchEventResult::kNotCanceled)
return false;
@@ -2443,6 +2475,16 @@ void AXLayoutObject::HandleAriaExpandedChanged() {
}
}
+void AXLayoutObject::HandleAutofillStateChanged(bool is_available) {
+ if (is_autofill_available_ != is_available) {
+ is_autofill_available_ = is_available;
+ // Reusing the value change event in order to invalidate, even though the
+ // value did not necessarily change.
+ // TODO(dmazzoni) change to using a MarkDirty() API.
+ AXObjectCache().PostNotification(this, AXObjectCacheImpl::kAXValueChanged);
+ }
+}
+
void AXLayoutObject::TextChanged() {
if (!layout_object_)
return;
@@ -3344,18 +3386,6 @@ void AXLayoutObject::AddImageMapChildren() {
}
}
-void AXLayoutObject::AddCanvasChildren() {
- if (!IsHTMLCanvasElement(GetNode()))
- return;
-
- // If it's a canvas, it won't have laid out children, but it might have
- // accessible fallback content. Clear m_haveChildren because
- // AXNodeObject::addChildren will expect it to be false.
- DCHECK(!children_.size());
- have_children_ = false;
- AXNodeObject::AddChildren();
-}
-
void AXLayoutObject::AddPopupChildren() {
if (!IsHTMLInputElement(GetNode()))
return;
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 7c97731fc2e..f7b2597c2ee 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
@@ -80,6 +80,7 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject {
bool IsAXLayoutObject() const override { return true; }
// Check object role or purpose.
+ bool IsAutofillAvailable() override { return is_autofill_available_; }
bool IsEditable() const override;
bool IsRichlyEditable() const override;
bool IsLinked() const override;
@@ -179,6 +180,8 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject {
// Notifications that this object may have changed.
void HandleActiveDescendantChanged() override;
void HandleAriaExpandedChanged() override;
+ // Called when autofill becomes available/unavailable on a form control.
+ void HandleAutofillStateChanged(bool) override;
void TextChanged() override;
// Text metrics. Most of these should be deprecated, needs major cleanup.
@@ -217,7 +220,6 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject {
void OffsetBoundingBoxForRemoteSVGElement(LayoutRect&) const;
void AddHiddenChildren();
void AddImageMapChildren();
- void AddCanvasChildren();
void AddPopupChildren();
void AddRemoteSVGChildren();
void AddTableChildren();
@@ -235,6 +237,8 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject {
bool CanIgnoreSpaceNextTo(LayoutObject*, bool is_after) const;
bool HasAriaCellRole(Element*) const;
+ bool is_autofill_available_;
+
DISALLOW_COPY_AND_ASSIGN(AXLayoutObject);
};
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_media_controls.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_media_controls.cc
index c56b578d7ff..66bef28d1da 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_media_controls.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_media_controls.cc
@@ -92,6 +92,7 @@ AXObject* AccessibilityMediaControl::Create(
case kMediaScrubbingMessage:
case kMediaEnterPictureInPictureButton:
case kMediaExitPictureInPictureButton:
+ case kMediaDisplayCutoutFullscreenButton:
return new AccessibilityMediaControl(layout_object, ax_object_cache);
}
@@ -179,6 +180,9 @@ String AccessibilityMediaControl::TextAlternative(
case kMediaExitPictureInPictureButton:
return QueryString(
WebLocalizedString::kAXMediaExitPictureInPictureButton);
+ case kMediaDisplayCutoutFullscreenButton:
+ return QueryString(
+ WebLocalizedString::kAXMediaDisplayCutoutFullscreenButton);
case kMediaSlider:
NOTREACHED();
return QueryString(WebLocalizedString::kAXMediaDefault);
@@ -229,6 +233,9 @@ String AccessibilityMediaControl::Description(
case kMediaExitPictureInPictureButton:
return QueryString(
WebLocalizedString::kAXMediaExitPictureInPictureButtonHelp);
+ case kMediaDisplayCutoutFullscreenButton:
+ return QueryString(
+ WebLocalizedString::kAXMediaDisplayCutoutFullscreenButtonHelp);
case kMediaSliderThumb:
case kMediaTextTrackList:
case kMediaTimelineContainer:
@@ -278,6 +285,7 @@ AccessibilityRole AccessibilityMediaControl::RoleValue() const {
case kMediaCastOffButton:
case kMediaEnterPictureInPictureButton:
case kMediaExitPictureInPictureButton:
+ case kMediaDisplayCutoutFullscreenButton:
return kButtonRole;
case kMediaTimelineContainer:
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 013f944fc80..40cae4314eb 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
@@ -41,6 +41,7 @@
#include "third_party/blink/renderer/core/editing/editing_utilities.h"
#include "third_party/blink/renderer/core/editing/markers/document_marker_controller.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
+#include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h"
#include "third_party/blink/renderer/core/html/forms/html_field_set_element.h"
#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
#include "third_party/blink/renderer/core/html/forms/html_label_element.h"
@@ -283,6 +284,12 @@ bool AXNodeObject::IsDescendantOfElementType(
return false;
}
+// TODO(accessibility) Needs a new name as it does check ARIA, including
+// checking the @role for an iframe, and @aria-haspopup/aria-pressed via
+// ButtonType().
+// TODO(accessibility) This value is cached in native_role_ so it needs to
+// be recached if anything it depends on change, such as IsClickable(),
+// DataList(), aria-pressed, the parent's tag, role on an iframe, etc.
AccessibilityRole AXNodeObject::NativeAccessibilityRoleIgnoringAria() const {
if (!GetNode())
return kUnknownRole;
@@ -453,6 +460,7 @@ AccessibilityRole AXNodeObject::NativeAccessibilityRoleIgnoringAria() const {
if (GetNode()->HasTagName(sectionTag))
return kRegionRole;
+ // TODO(accessibility): http://crbug.com/873118
if (GetNode()->HasTagName(addressTag))
return kContentInfoRole;
@@ -464,7 +472,8 @@ AccessibilityRole AXNodeObject::NativeAccessibilityRoleIgnoringAria() const {
if (IsHTMLHtmlElement(*GetNode()))
return kIgnoredRole;
- if (IsHTMLIFrameElement(*GetNode())) {
+ // Treat <iframe> and <frame> the same.
+ if (IsHTMLIFrameElement(*GetNode()) || IsHTMLFrameElement(*GetNode())) {
const AtomicString& aria_role =
GetAOMPropertyOrARIAAttribute(AOMStringProperty::kRole);
if (aria_role == "none" || aria_role == "presentation")
@@ -1057,14 +1066,10 @@ bool AXNodeObject::IsRequired() const {
}
bool AXNodeObject::CanvasHasFallbackContent() const {
- Node* node = this->GetNode();
- if (!IsHTMLCanvasElement(node))
+ if (IsDetached())
return false;
-
- // If it has any children that are elements, we'll assume it might be fallback
- // content. If it has no children or its only children are not elements
- // (e.g. just text nodes), it doesn't have fallback content.
- return ElementTraversal::FirstChild(*node);
+ Node* node = this->GetNode();
+ return IsHTMLCanvasElement(node) && node->hasChildren();
}
int AXNodeObject::HeadingLevel() const {
@@ -1180,7 +1185,8 @@ void AXNodeObject::Markers(Vector<DocumentMarker::MarkerType>& marker_types,
return;
DocumentMarkerController& marker_controller = GetDocument()->Markers();
- DocumentMarkerVector markers = marker_controller.MarkersFor(GetNode());
+ DocumentMarkerVector markers =
+ marker_controller.MarkersFor(ToText(*GetNode()));
for (size_t i = 0; i < markers.size(); ++i) {
DocumentMarker* marker = markers[i];
if (MarkerTypeIsUsedForAccessibility(marker->GetType())) {
@@ -2079,15 +2085,13 @@ AXObject* AXNodeObject::RawNextSibling() const {
}
void AXNodeObject::AddChildren() {
- DCHECK(!IsDetached());
+ if (IsDetached())
+ 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_);
-
- if (!node_)
- return;
-
have_children_ = true;
// The only time we add children from the DOM tree to a node with a
@@ -2095,7 +2099,7 @@ void AXNodeObject::AddChildren() {
if (GetLayoutObject() && !IsHTMLCanvasElement(*node_))
return;
- HeapVector<Member<AXObject>> owned_children;
+ AXObjectVector owned_children;
ComputeAriaOwnsChildren(owned_children);
for (Node& child : NodeTraversal::ChildrenOf(*node_)) {
@@ -2400,6 +2404,10 @@ void AXNodeObject::ChildrenChanged() {
if (!CanHaveChildren() || cached_is_descendant_of_leaf_node_)
return;
+ // Calling CanHaveChildren(), above, can occasionally detach |this|.
+ if (IsDetached())
+ return;
+
AXObjectCache().PostNotification(this, AXObjectCacheImpl::kAXChildrenChanged);
// Go up the accessibility parent chain, but only if the element already
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 936c36e1b2f..dcc25560fb0 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_object.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -60,6 +60,7 @@
#include "third_party/blink/renderer/platform/scroll/scroll_alignment.h"
#include "third_party/blink/renderer/platform/text/platform_locale.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
+#include "third_party/blink/renderer/platform/wtf/not_found.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -95,7 +96,9 @@ const RoleEntry kRoles[] = {{"alert", kAlertRole},
{"application", kApplicationRole},
{"article", kArticleRole},
{"banner", kBannerRole},
+ {"blockquote", kBlockquoteRole},
{"button", kButtonRole},
+ {"caption", kCaptionRole},
{"cell", kCellRole},
{"checkbox", kCheckBoxRole},
{"columnheader", kColumnHeaderRole},
@@ -183,6 +186,7 @@ const RoleEntry kRoles[] = {{"alert", kAlertRole},
{"none", kNoneRole},
{"note", kNoteRole},
{"option", kListBoxOptionRole},
+ {"paragraph", kParagraphRole},
{"presentation", kPresentationalRole},
{"progressbar", kProgressIndicatorRole},
{"radio", kRadioButtonRole},
@@ -895,6 +899,11 @@ void AXObject::UpdateCachedAttributeValuesIfNeeded() const {
if (parent)
parent->ChildrenChanged();
}
+
+ if (GetLayoutObject() && GetLayoutObject()->IsText()) {
+ cached_local_bounding_box_rect_for_accessibility_ =
+ GetLayoutObject()->LocalBoundingBoxRectForAccessibility();
+ }
}
bool AXObject::AccessibilityIsIgnoredByDefault(
@@ -1076,7 +1085,7 @@ bool AXObject::DispatchEventToAOMEventListeners(Event& event) {
break;
event.SetCurrentTarget(event_path[i]);
- event_path[i]->FireEventListeners(&event);
+ event_path[i]->FireEventListeners(event);
if (event.PropagationStopped())
return true;
}
@@ -1084,7 +1093,7 @@ bool AXObject::DispatchEventToAOMEventListeners(Event& event) {
// Targeting phase.
event.SetEventPhase(Event::kAtTarget);
event.SetCurrentTarget(event_path[0]);
- event_path[0]->FireEventListeners(&event);
+ event_path[0]->FireEventListeners(event);
if (event.PropagationStopped())
return true;
@@ -1092,7 +1101,7 @@ bool AXObject::DispatchEventToAOMEventListeners(Event& event) {
event.SetEventPhase(Event::kBubblingPhase);
for (size_t i = 1; i < event_path.size(); i++) {
event.SetCurrentTarget(event_path[i]);
- event_path[i]->FireEventListeners(&event);
+ event_path[i]->FireEventListeners(event);
if (event.PropagationStopped())
return true;
}
@@ -1835,14 +1844,9 @@ int AXObject::IndexInParent() const {
if (!ParentObjectUnignored())
return 0;
- const auto& siblings = ParentObjectUnignored()->Children();
- int child_count = siblings.size();
-
- for (int index = 0; index < child_count; ++index) {
- if (siblings[index].Get() == this)
- return index;
- }
- return 0;
+ const AXObjectVector& siblings = ParentObjectUnignored()->Children();
+ size_t index = siblings.Find(this);
+ return (index == kNotFound) ? 0 : static_cast<int>(index);
}
bool AXObject::IsLiveRegion() const {
@@ -2092,6 +2096,9 @@ AXObject* AXObject::NextSibling() const {
if (!parent)
return nullptr;
+ if (AccessibilityIsIgnored())
+ NOTREACHED() << "We don't support finding siblings for ignored objects.";
+
if (IndexInParent() < parent->ChildCount() - 1)
return *(parent->Children().begin() + IndexInParent() + 1);
@@ -2103,6 +2110,9 @@ AXObject* AXObject::PreviousSibling() const {
if (!parent)
return nullptr;
+ if (AccessibilityIsIgnored())
+ NOTREACHED() << "We don't support finding siblings for ignored objects.";
+
if (IndexInParent() > 0)
return *(parent->Children().begin() + IndexInParent() - 1);
@@ -2110,11 +2120,17 @@ AXObject* AXObject::PreviousSibling() const {
}
AXObject* AXObject::NextInTreeObject(bool can_wrap_to_first_element) const {
- if (ChildCount())
- return FirstChild();
+ // We don't support finding the next sibling for an ignored object, so we
+ // return the next sibling of the deepest unignored ancestor, which is the
+ // next best thing that doesn't violate next-in-order semantics.
+ if (!AccessibilityIsIgnored()) {
+ if (ChildCount())
+ return FirstChild();
+
+ if (NextSibling())
+ return NextSibling();
+ }
- if (NextSibling())
- return NextSibling();
AXObject* current_object = const_cast<AXObject*>(this);
while (current_object->ParentObjectUnignored()) {
current_object = current_object->ParentObjectUnignored();
@@ -2127,7 +2143,10 @@ AXObject* AXObject::NextInTreeObject(bool can_wrap_to_first_element) const {
}
AXObject* AXObject::PreviousInTreeObject(bool can_wrap_to_last_element) const {
- AXObject* sibling = PreviousSibling();
+ // We don't support finding the previous sibling for an ignored object, so we
+ // return the deepest unignored ancestor instead, which is the next best thing
+ // that doesn't violate previous-in-order semantics.
+ AXObject* sibling = AccessibilityIsIgnored() ? nullptr : PreviousSibling();
if (!sibling) {
if (ParentObjectUnignored())
return ParentObjectUnignored();
@@ -2759,7 +2778,7 @@ void AXObject::GetRelativeBounds(AXObject** out_container,
if (layout_object->IsBox() && layout_object->GetNode() &&
layout_object->GetNode()->IsFrameOwnerElement()) {
out_bounds_in_container =
- FloatRect(ToLayoutBox(layout_object)->ContentBoxRect());
+ FloatRect(ToLayoutBox(layout_object)->PhysicalContentBoxRect());
}
// If the container has a scroll offset, subtract that out because we want our
@@ -2782,6 +2801,14 @@ void AXObject::GetRelativeBounds(AXObject** out_container,
}
}
+FloatRect AXObject::LocalBoundingBoxRectForAccessibility() {
+ if (!GetLayoutObject())
+ return FloatRect();
+ DCHECK(GetLayoutObject()->IsText());
+ UpdateCachedAttributeValuesIfNeeded();
+ return cached_local_bounding_box_rect_for_accessibility_;
+}
+
LayoutRect AXObject::GetBoundsInFrameCoordinates() const {
AXObject* container = nullptr;
FloatRect bounds;
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 1b84d5cf49b..12df974b31e 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_object.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_object.h
@@ -516,6 +516,7 @@ class MODULES_EXPORT AXObject : public GarbageCollectedFinalized<AXObject> {
bool IsWebArea() const { return RoleValue() == kWebAreaRole; }
// Check object state.
+ virtual bool IsAutofillAvailable() { return false; }
virtual bool IsClickable() const;
virtual bool IsCollapsed() const { return false; }
virtual AccessibilityExpanded IsExpanded() const {
@@ -772,6 +773,8 @@ class MODULES_EXPORT AXObject : public GarbageCollectedFinalized<AXObject> {
SkMatrix44& out_container_transform,
bool* clips_children = nullptr) const;
+ FloatRect LocalBoundingBoxRectForAccessibility();
+
// Get the bounds in frame-relative coordinates as a LayoutRect.
LayoutRect GetBoundsInFrameCoordinates() const;
@@ -950,6 +953,7 @@ class MODULES_EXPORT AXObject : public GarbageCollectedFinalized<AXObject> {
// Notifications that this object may have changed.
virtual void ChildrenChanged() {}
virtual void HandleActiveDescendantChanged() {}
+ virtual void HandleAutofillStateChanged(bool) {}
virtual void HandleAriaExpandedChanged() {}
virtual void SelectionChanged();
virtual void TextChanged() {}
@@ -1059,6 +1063,7 @@ class MODULES_EXPORT AXObject : public GarbageCollectedFinalized<AXObject> {
mutable Member<AXObject> cached_live_region_root_;
mutable int cached_aria_column_index_;
mutable int cached_aria_row_index_;
+ mutable FloatRect cached_local_bounding_box_rect_for_accessibility_;
Member<AXObjectCacheImpl> ax_object_cache_;
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 840c6bbae9b..009e2d02edb 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
@@ -162,9 +162,6 @@ AXObject* AXObjectCacheImpl::FocusedImageMapUIElement(
}
AXObject* AXObjectCacheImpl::FocusedObject() {
- if (!AccessibilityEnabled())
- return nullptr;
-
Node* focused_node = document_->FocusedElement();
if (!focused_node)
focused_node = document_;
@@ -964,7 +961,8 @@ void AXObjectCacheImpl::HandlePossibleRoleChange(Node* node) {
void AXObjectCacheImpl::HandleAttributeChanged(const QualifiedName& attr_name,
Element* element) {
- if (attr_name == roleAttr || attr_name == typeAttr || attr_name == sizeAttr)
+ if (attr_name == roleAttr || attr_name == typeAttr || attr_name == sizeAttr ||
+ attr_name == aria_haspopupAttr)
HandlePossibleRoleChange(element);
else if (attr_name == altAttr || attr_name == titleAttr)
TextChanged(element);
@@ -1002,6 +1000,12 @@ void AXObjectCacheImpl::HandleAttributeChanged(const QualifiedName& attr_name,
PostNotification(element, AXObjectCacheImpl::kAXAriaAttributeChanged);
}
+void AXObjectCacheImpl::HandleAutofillStateChanged(Element* elem,
+ bool is_available) {
+ if (AXObject* obj = Get(elem))
+ obj->HandleAutofillStateChanged(is_available);
+}
+
void AXObjectCacheImpl::LabelChanged(Element* element) {
TextChanged(ToHTMLLabelElement(element)->control());
}
@@ -1028,13 +1032,6 @@ Settings* AXObjectCacheImpl::GetSettings() {
return document_->GetSettings();
}
-bool AXObjectCacheImpl::AccessibilityEnabled() {
- Settings* settings = this->GetSettings();
- if (!settings)
- return false;
- return settings->GetAccessibilityEnabled();
-}
-
bool AXObjectCacheImpl::InlineTextBoxAccessibilityEnabled() {
Settings* settings = this->GetSettings();
if (!settings)
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 0cacaaa4600..185c3fe3d47 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
@@ -138,6 +138,7 @@ class MODULES_EXPORT AXObjectCacheImpl
void HandleAttributeChanged(const QualifiedName& attr_name,
Element*) override;
+ void HandleAutofillStateChanged(Element*, bool) override;
void HandleFocusedUIElementChanged(Node* old_focused_node,
Node* new_focused_node) override;
void HandleInitialFocus() override;
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 54fce28e26a..dd812d09eed 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_position.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_position.cc
@@ -5,8 +5,10 @@
#include "third_party/blink/renderer/modules/accessibility/ax_position.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"
#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/editing/ephemeral_range.h"
#include "third_party/blink/renderer/core/editing/iterators/character_iterator.h"
#include "third_party/blink/renderer/core/editing/iterators/text_iterator.h"
@@ -19,44 +21,49 @@
namespace blink {
// static
-const AXPosition AXPosition::CreatePositionBeforeObject(const AXObject& child) {
+const AXPosition AXPosition::CreatePositionBeforeObject(
+ const AXObject& child,
+ const AXPositionAdjustmentBehavior adjustment_behavior) {
if (child.IsDetached())
return {};
// If |child| is a text object, make behavior the same as
// |CreateFirstPositionInObject| so that equality would hold.
if (child.IsTextObject())
- return CreateFirstPositionInObject(child);
+ return CreateFirstPositionInObject(child, adjustment_behavior);
const AXObject* parent = child.ParentObjectUnignored();
DCHECK(parent);
AXPosition position(*parent);
position.text_offset_or_child_index_ = child.IndexInParent();
DCHECK(position.IsValid());
- return position.AsUnignoredPosition();
+ return position.AsUnignoredPosition(adjustment_behavior);
}
// static
-const AXPosition AXPosition::CreatePositionAfterObject(const AXObject& child) {
+const AXPosition AXPosition::CreatePositionAfterObject(
+ const AXObject& child,
+ const AXPositionAdjustmentBehavior adjustment_behavior) {
if (child.IsDetached())
return {};
// If |child| is a text object, make behavior the same as
// |CreateLastPositionInObject| so that equality would hold.
if (child.IsTextObject())
- return CreateLastPositionInObject(child);
+ return CreateLastPositionInObject(child, adjustment_behavior);
const AXObject* parent = child.ParentObjectUnignored();
DCHECK(parent);
AXPosition position(*parent);
position.text_offset_or_child_index_ = child.IndexInParent() + 1;
DCHECK(position.IsValid());
- return position.AsUnignoredPosition();
+ return position.AsUnignoredPosition(adjustment_behavior);
}
// static
const AXPosition AXPosition::CreateFirstPositionInObject(
- const AXObject& container) {
+ const AXObject& container,
+ const AXPositionAdjustmentBehavior adjustment_behavior) {
if (container.IsDetached())
return {};
@@ -64,7 +71,7 @@ const AXPosition AXPosition::CreateFirstPositionInObject(
AXPosition position(container);
position.text_offset_or_child_index_ = 0;
DCHECK(position.IsValid());
- return position.AsUnignoredPosition();
+ return position.AsUnignoredPosition(adjustment_behavior);
}
const AXObject* unignored_container = container.AccessibilityIsIgnored()
@@ -74,12 +81,13 @@ const AXPosition AXPosition::CreateFirstPositionInObject(
AXPosition position(*unignored_container);
position.text_offset_or_child_index_ = 0;
DCHECK(position.IsValid());
- return position.AsUnignoredPosition();
+ return position.AsUnignoredPosition(adjustment_behavior);
}
// static
const AXPosition AXPosition::CreateLastPositionInObject(
- const AXObject& container) {
+ const AXObject& container,
+ const AXPositionAdjustmentBehavior adjustment_behavior) {
if (container.IsDetached())
return {};
@@ -87,7 +95,7 @@ const AXPosition AXPosition::CreateLastPositionInObject(
AXPosition position(container);
position.text_offset_or_child_index_ = position.MaxTextOffset();
DCHECK(position.IsValid());
- return position.AsUnignoredPosition();
+ return position.AsUnignoredPosition(adjustment_behavior);
}
const AXObject* unignored_container = container.AccessibilityIsIgnored()
@@ -97,14 +105,15 @@ const AXPosition AXPosition::CreateLastPositionInObject(
AXPosition position(*unignored_container);
position.text_offset_or_child_index_ = unignored_container->ChildCount();
DCHECK(position.IsValid());
- return position.AsUnignoredPosition();
+ return position.AsUnignoredPosition(adjustment_behavior);
}
// static
const AXPosition AXPosition::CreatePositionInTextObject(
const AXObject& container,
const int offset,
- const TextAffinity affinity) {
+ const TextAffinity affinity,
+ const AXPositionAdjustmentBehavior adjustment_behavior) {
if (container.IsDetached() || !container.IsTextObject())
return {};
@@ -112,12 +121,14 @@ const AXPosition AXPosition::CreatePositionInTextObject(
position.text_offset_or_child_index_ = offset;
position.affinity_ = affinity;
DCHECK(position.IsValid());
- return position.AsUnignoredPosition();
+ return position.AsUnignoredPosition(adjustment_behavior);
}
// static
-const AXPosition AXPosition::FromPosition(const Position& position,
- const TextAffinity affinity) {
+const AXPosition AXPosition::FromPosition(
+ const Position& position,
+ const TextAffinity affinity,
+ const AXPositionAdjustmentBehavior adjustment_behavior) {
if (position.IsNull() || position.IsOrphan())
return {};
@@ -131,49 +142,137 @@ const AXPosition AXPosition::FromPosition(const Position& position,
auto* ax_object_cache_impl = static_cast<AXObjectCacheImpl*>(ax_object_cache);
const Position& parent_anchored_position = position.ToOffsetInAnchor();
- const Node* anchor_node = parent_anchored_position.AnchorNode();
- DCHECK(anchor_node);
- const AXObject* container = ax_object_cache_impl->GetOrCreate(anchor_node);
- DCHECK(container);
+ const Node* container_node = parent_anchored_position.AnchorNode();
+ DCHECK(container_node);
+ const AXObject* container = ax_object_cache_impl->GetOrCreate(container_node);
+ if (!container)
+ return {};
- AXPosition ax_position(*container);
- if (anchor_node->IsTextNode()) {
+ if (container_node->IsTextNode()) {
+ if (container->AccessibilityIsIgnored()) {
+ // Find the closest DOM sibling that is unignored in the accessibility
+ // tree.
+ switch (adjustment_behavior) {
+ case AXPositionAdjustmentBehavior::kMoveRight: {
+ const AXObject* next_container = FindNeighboringUnignoredObject(
+ *document, *container_node, container_node->parentNode(),
+ adjustment_behavior);
+ if (next_container) {
+ return CreatePositionBeforeObject(*next_container,
+ adjustment_behavior);
+ }
+
+ // Do the next best thing by moving up to the unignored parent if it
+ // exists.
+ if (!container || !container->ParentObjectUnignored())
+ return {};
+ return CreateLastPositionInObject(*container->ParentObjectUnignored(),
+ adjustment_behavior);
+ }
+
+ case AXPositionAdjustmentBehavior::kMoveLeft: {
+ const AXObject* previous_container = FindNeighboringUnignoredObject(
+ *document, *container_node, container_node->parentNode(),
+ adjustment_behavior);
+ if (previous_container) {
+ return CreatePositionAfterObject(*previous_container,
+ adjustment_behavior);
+ }
+
+ // Do the next best thing by moving up to the unignored parent if it
+ // exists.
+ if (!container || !container->ParentObjectUnignored())
+ return {};
+ return CreateFirstPositionInObject(
+ *container->ParentObjectUnignored(), adjustment_behavior);
+ }
+ }
+ }
+
+ AXPosition ax_position(*container);
// Convert from a DOM offset that may have uncompressed white space to a
// character offset.
// TODO(nektar): Use LayoutNG offset mapping instead of
// |TextIterator|.
- const auto first_position = Position::FirstPositionInNode(*anchor_node);
+ const auto first_position = Position::FirstPositionInNode(*container_node);
int offset =
TextIterator::RangeLength(first_position, parent_anchored_position);
ax_position.text_offset_or_child_index_ = offset;
- } else {
- // |ComputeNodeAfterPosition| returns nullptr for "after children"
- // positions.
- const Node* node_after_position = position.ComputeNodeAfterPosition();
- if (!node_after_position) {
- ax_position.text_offset_or_child_index_ = container->ChildCount();
+ ax_position.affinity_ = affinity;
+ DCHECK(ax_position.IsValid());
+ return ax_position;
+ }
+
+ DCHECK(container_node->IsContainerNode());
+ if (container->AccessibilityIsIgnored()) {
+ container = container->ParentObjectUnignored();
+ // |container_node| could potentially become nullptr if the unignored parent
+ // is an anonymous layout block.
+ container_node = container->GetNode();
+ }
+
+ if (!container)
+ return {};
+
+ AXPosition ax_position(*container);
+ // |ComputeNodeAfterPosition| returns nullptr for "after children"
+ // positions.
+ const Node* node_after_position = position.ComputeNodeAfterPosition();
+ if (!node_after_position) {
+ ax_position.text_offset_or_child_index_ = container->ChildCount();
+
} else {
const AXObject* ax_child =
ax_object_cache_impl->GetOrCreate(node_after_position);
DCHECK(ax_child);
- if (ax_child->IsDescendantOf(*container)) {
- ax_position.text_offset_or_child_index_ = ax_child->IndexInParent();
- } else {
- return CreatePositionBeforeObject(*ax_child);
+
+ if (ax_child->AccessibilityIsIgnored()) {
+ // Find the closest DOM sibling that is unignored in the accessibility
+ // tree.
+ switch (adjustment_behavior) {
+ case AXPositionAdjustmentBehavior::kMoveRight: {
+ const AXObject* next_child = FindNeighboringUnignoredObject(
+ *document, *node_after_position,
+ ToContainerNodeOrNull(container_node), adjustment_behavior);
+ if (next_child) {
+ return CreatePositionBeforeObject(*next_child,
+ adjustment_behavior);
+ }
+
+ return CreateLastPositionInObject(*container, adjustment_behavior);
+ }
+
+ case AXPositionAdjustmentBehavior::kMoveLeft: {
+ const AXObject* previous_child = FindNeighboringUnignoredObject(
+ *document, *node_after_position,
+ ToContainerNodeOrNull(container_node), adjustment_behavior);
+ if (previous_child) {
+ return CreatePositionAfterObject(*previous_child,
+ adjustment_behavior);
+ }
+
+ return CreateFirstPositionInObject(*container, adjustment_behavior);
+ }
+ }
+ }
+
+ if (!container->Children().Contains(ax_child)) {
+ // The |ax_child| is aria-owned by another object.
+ return CreatePositionBeforeObject(*ax_child, adjustment_behavior);
}
+
+ ax_position.text_offset_or_child_index_ = ax_child->IndexInParent();
}
- }
- ax_position.affinity_ = affinity;
- DCHECK(ax_position.IsValid());
- return ax_position.AsUnignoredPosition();
+ return ax_position;
}
// static
const AXPosition AXPosition::FromPosition(
- const PositionWithAffinity& position_with_affinity) {
+ const PositionWithAffinity& position_with_affinity,
+ const AXPositionAdjustmentBehavior adjustment_behavior) {
return FromPosition(position_with_affinity.GetPosition(),
- position_with_affinity.Affinity());
+ position_with_affinity.Affinity(), adjustment_behavior);
}
AXPosition::AXPosition()
@@ -285,62 +384,76 @@ const AXPosition AXPosition::CreateNextPosition() const {
if (!IsValid())
return {};
- if (IsTextPosition() && TextOffset() < MaxTextOffset())
- return CreatePositionInTextObject(*container_object_, TextOffset() + 1);
+ if (IsTextPosition() && TextOffset() < MaxTextOffset()) {
+ return CreatePositionInTextObject(*container_object_, (TextOffset() + 1),
+ TextAffinity::kDownstream,
+ AXPositionAdjustmentBehavior::kMoveRight);
+ }
+ // Handles both an "after children" position, or a text position that is right
+ // after the last character.
const AXObject* child = ChildAfterTreePosition();
- // Handles both an "after children" position, or a text position that is after
- // the last character.
if (!child) {
const AXObject* next_in_order = container_object_->NextInTreeObject();
if (!next_in_order || !next_in_order->ParentObjectUnignored())
return {};
- return CreatePositionBeforeObject(*next_in_order);
+
+ return CreatePositionBeforeObject(*next_in_order,
+ AXPositionAdjustmentBehavior::kMoveRight);
}
if (!child->ParentObjectUnignored())
return {};
- return CreatePositionAfterObject(*child);
+
+ return CreatePositionAfterObject(*child,
+ AXPositionAdjustmentBehavior::kMoveRight);
}
const AXPosition AXPosition::CreatePreviousPosition() const {
if (!IsValid())
return {};
- if (IsTextPosition() && TextOffset() > 0)
- return CreatePositionInTextObject(*container_object_, TextOffset() - 1);
+ if (IsTextPosition() && TextOffset() > 0) {
+ return CreatePositionInTextObject(*container_object_, (TextOffset() - 1),
+ TextAffinity::kDownstream,
+ AXPositionAdjustmentBehavior::kMoveLeft);
+ }
const AXObject* child = ChildAfterTreePosition();
+ const AXObject* object_before_position = nullptr;
// Handles both an "after children" position, or a text position that is
// before the first character.
if (!child) {
if (container_object_->ChildCount()) {
const AXObject* last_child = container_object_->LastChild();
// Dont skip over any intervening text.
- if (last_child->IsTextObject())
- return CreatePositionAfterObject(*last_child);
+ if (last_child->IsTextObject()) {
+ return CreatePositionAfterObject(
+ *last_child, AXPositionAdjustmentBehavior::kMoveLeft);
+ }
- return CreatePositionBeforeObject(*last_child);
+ return CreatePositionBeforeObject(
+ *last_child, AXPositionAdjustmentBehavior::kMoveLeft);
}
- const AXObject* previous_in_order =
- container_object_->PreviousInTreeObject();
- if (!previous_in_order || !previous_in_order->ParentObjectUnignored())
- return {};
- return CreatePositionAfterObject(*previous_in_order);
+ object_before_position = container_object_->PreviousInTreeObject();
+ } else {
+ object_before_position = child->PreviousInTreeObject();
}
- const AXObject* object_before_position = child->PreviousInTreeObject();
if (!object_before_position ||
!object_before_position->ParentObjectUnignored()) {
return {};
}
// Dont skip over any intervening text.
- if (object_before_position->IsTextObject())
- return CreatePositionAfterObject(*object_before_position);
+ if (object_before_position->IsTextObject()) {
+ return CreatePositionAfterObject(*object_before_position,
+ AXPositionAdjustmentBehavior::kMoveLeft);
+ }
- return CreatePositionBeforeObject(*object_before_position);
+ return CreatePositionBeforeObject(*object_before_position,
+ AXPositionAdjustmentBehavior::kMoveLeft);
}
const AXPosition AXPosition::AsUnignoredPosition(
@@ -349,30 +462,55 @@ const AXPosition AXPosition::AsUnignoredPosition(
return {};
// There are four possibilities:
+ //
// 1. The container object is ignored and this is not a text position or an
// "after children" position. Try to find the equivalent position in the
// unignored parent.
- // 2. The container object is ignored and this is a text
- // position. Adjust to the position immediately to the left or to the right,
- // based on the adjustment behavior, possibly changing to a non-text position
- // and recurse. 3. The position is an "after children" position, but the last
- // child is ignored. Do the same as 2. 4. The object after the position is
- // ignored, but the container object is not. Do the same as 2.
+ //
+ // 2. The position is a text position and the container object is ignored.
+ // Return a "before children" or an "after children" position anchored at the
+ // container's unignored parent.
+ //
+ // 3. The container object is ignored and this is an "after children"
+ // position. Find the next object in the tree and recurse.
+ //
+ // 4. The child after a tree position is ignored, but the container object is
+ // not. Return an "after children" position.
const AXObject* container = container_object_;
const AXObject* child = ChildAfterTreePosition();
- const AXObject* last_child = container->LastChild();
// Case 1.
+ // Neither text positions nor "after children" positions have a |child|
+ // object.
if (container->AccessibilityIsIgnored() && child) {
- return CreatePositionBeforeObject(*child).AsUnignoredPosition(
- adjustment_behavior);
+ // |CreatePositionBeforeObject| already finds the unignored parent before
+ // creating the new position, so we don't need to replicate the logic here.
+ return CreatePositionBeforeObject(*child, adjustment_behavior);
}
- // Cases 2, 3 and 4.
- if (container->AccessibilityIsIgnored() ||
- (!child && last_child && last_child->AccessibilityIsIgnored()) ||
- (child && child->AccessibilityIsIgnored())) {
+ // Cases 2 and 3.
+ if (container->AccessibilityIsIgnored()) {
+ // Case 2.
+ if (IsTextPosition()) {
+ if (!container->ParentObjectUnignored())
+ return {};
+
+ // Calling |CreateNextPosition| or |CreatePreviousPosition| is not
+ // appropriate here because they will go through the text position
+ // character by character which is unnecessary, in addition to skipping
+ // any unignored siblings.
+ switch (adjustment_behavior) {
+ case AXPositionAdjustmentBehavior::kMoveRight:
+ return CreateLastPositionInObject(*container->ParentObjectUnignored(),
+ adjustment_behavior);
+ case AXPositionAdjustmentBehavior::kMoveLeft:
+ return CreateFirstPositionInObject(
+ *container->ParentObjectUnignored(), adjustment_behavior);
+ }
+ }
+
+ // Case 3.
switch (adjustment_behavior) {
case AXPositionAdjustmentBehavior::kMoveRight:
return CreateNextPosition().AsUnignoredPosition(adjustment_behavior);
@@ -382,6 +520,11 @@ const AXPosition AXPosition::AsUnignoredPosition(
}
}
+ // Case 4.
+ if (child && child->AccessibilityIsIgnored())
+ return CreateLastPositionInObject(*container);
+
+ // The position is not ignored.
return *this;
}
@@ -430,19 +573,22 @@ 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())
return *this;
DCHECK(container->IsAXLayoutObject())
<< "Non virtual and non mock AX objects that are not associated to a DOM "
"node should have an associated layout object.";
- const Node* anchor_node =
+ const Node* container_node =
ToAXLayoutObject(container)->GetNodeOrContainingBlockNode();
- DCHECK(anchor_node)
+ DCHECK(container_node)
<< "All anonymous layout objects should have a containing block element.";
DCHECK(!container->IsDetached());
auto& ax_object_cache_impl = container->AXObjectCache();
- const AXObject* new_container = ax_object_cache_impl.GetOrCreate(anchor_node);
+ const AXObject* new_container =
+ ax_object_cache_impl.GetOrCreate(container_node);
DCHECK(new_container);
AXPosition position(*new_container);
if (new_container == container->ParentObjectUnignored()) {
@@ -465,30 +611,59 @@ const PositionWithAffinity AXPosition::ToPositionWithAffinity(
if (!adjusted_position.IsTextPosition()) {
// AX positions that are unumbiguously at the start or end of a container,
// should convert to the corresponding DOM positions at the start or end of
- // the same container. Other child positions in the accessibility tree
- // should recompute their parent in the DOM tree, because they might be ARIA
- // owned by a different object in the accessibility tree than in the DOM
- // tree, or their parent in the accessibility tree might be ignored.
-
- if (adjusted_position.ChildIndex() == 0) {
- // Creates a |PositionAnchorType::kBeforeChildren| position.
- return PositionWithAffinity(
- Position::FirstPositionInNode(*container_node), affinity_);
+ // their parent node. Other child positions in the accessibility tree should
+ // recompute their parent in the DOM tree, because they might be ARIA owned
+ // by a different object in the accessibility tree than in the DOM tree, or
+ // their parent in the accessibility tree might be ignored.
+
+ const AXObject* child = adjusted_position.ChildAfterTreePosition();
+ if (child) {
+ const Node* child_node = child->GetNode();
+ DCHECK(child_node) << "AX objects used in AX positions that are valid "
+ "DOM positions should always be connected to their "
+ "DOM nodes.";
+ if (child_node->NodeIndex() == 0) {
+ // Creates a |PositionAnchorType::kBeforeChildren| position.
+ container_node = child_node->parentNode();
+ DCHECK(container_node);
+ return PositionWithAffinity(
+ Position::FirstPositionInNode(*container_node), affinity_);
+ }
+
+ // Creates a |PositionAnchorType::kOffsetInAnchor| position.
+ return PositionWithAffinity(Position::InParentBeforeNode(*child_node),
+ affinity_);
}
- if (adjusted_position.ChildIndex() == container_object_->ChildCount()) {
- // Creates a |PositionAnchorType::kAfterChildren| position.
- return PositionWithAffinity(Position::LastPositionInNode(*container_node),
+ // "After children" positions.
+ const AXObject* last_child = container_object_->LastChild();
+ if (last_child) {
+ const Node* last_child_node = last_child->GetNode();
+ DCHECK(last_child_node) << "AX objects used in AX positions that are "
+ "valid DOM positions should always be "
+ "connected to their DOM nodes.";
+
+ // Check if this is an "after children" position in the DOM as well.
+ if ((last_child_node->NodeIndex() + 1) ==
+ container_node->CountChildren()) {
+ // Creates a |PositionAnchorType::kAfterChildren| position.
+ container_node = last_child_node->parentNode();
+ DCHECK(container_node);
+ return PositionWithAffinity(
+ Position::LastPositionInNode(*container_node), affinity_);
+ }
+
+ // Do the next best thing by creating a
+ // |PositionAnchorType::kOffsetInAnchor| position after the last unignored
+ // child.
+ return PositionWithAffinity(Position::InParentAfterNode(*last_child_node),
affinity_);
}
- // Creates a |PositionAnchorType::kOffsetInAnchor| position.
- const AXObject* ax_child =
- *(adjusted_position.container_object_->Children().begin() +
- adjusted_position.ChildIndex());
- DCHECK(ax_child);
- return PositionWithAffinity(
- Position::InParentBeforeNode(*(ax_child->GetNode())), affinity_);
+ // The |AXObject| container has no children. Do the next best thing by
+ // creating a |PositionAnchorType::kBeforeChildren| position.
+ return PositionWithAffinity(Position::FirstPositionInNode(*container_node),
+ affinity_);
}
// TODO(nektar): Use LayoutNG offset mapping instead of |TextIterator|.
@@ -500,6 +675,44 @@ const PositionWithAffinity AXPosition::ToPositionWithAffinity(
return PositionWithAffinity(range.EndPosition(), affinity_);
}
+// static
+const AXObject* AXPosition::FindNeighboringUnignoredObject(
+ const Document& document,
+ const Node& child_node,
+ const ContainerNode* container_node,
+ const AXPositionAdjustmentBehavior adjustment_behavior) {
+ AXObjectCache* ax_object_cache = document.ExistingAXObjectCache();
+ if (!ax_object_cache)
+ return nullptr;
+
+ auto* ax_object_cache_impl = static_cast<AXObjectCacheImpl*>(ax_object_cache);
+ switch (adjustment_behavior) {
+ case AXPositionAdjustmentBehavior::kMoveRight: {
+ const Node* next_node = &child_node;
+ while ((next_node = NodeTraversal::NextSkippingChildren(
+ *next_node, container_node))) {
+ const AXObject* next_object =
+ ax_object_cache_impl->GetOrCreate(next_node);
+ if (next_object && !next_object->AccessibilityIsIgnored())
+ return next_object;
+ }
+ return nullptr;
+ }
+
+ case AXPositionAdjustmentBehavior::kMoveLeft: {
+ const Node* previous_node = &child_node;
+ while ((previous_node = NodeTraversal::PreviousSkippingChildren(
+ *previous_node, container_node))) {
+ const AXObject* previous_object =
+ ax_object_cache_impl->GetOrCreate(previous_node);
+ if (previous_object && !previous_object->AccessibilityIsIgnored())
+ return previous_object;
+ }
+ return nullptr;
+ }
+ }
+}
+
bool operator==(const AXPosition& a, const AXPosition& b) {
DCHECK(a.IsValid() && b.IsValid());
if (*a.ContainerObject() != *b.ContainerObject())
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_position.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_position.h
index bbae2cbe4e4..fe5b0e1b185 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_position.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_position.h
@@ -18,6 +18,9 @@
namespace blink {
class AXObject;
+class ContainerNode;
+class Document;
+class Node;
// When converting to a DOM position from an |AXPosition| or vice versa, and the
// corresponding position is invalid, doesn't exist, or is inside an ignored
@@ -39,19 +42,44 @@ class MODULES_EXPORT AXPosition final {
DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
public:
- static const AXPosition CreatePositionBeforeObject(const AXObject& child);
- static const AXPosition CreatePositionAfterObject(const AXObject& child);
+ //
+ // Convert between DOM and AX positions and vice versa.
+ // |Create...| and |FromPosition| methods will by default skip over any
+ // ignored object and return the next unignored position to the right of that
+ // object.
+ //
+
+ static const AXPosition CreatePositionBeforeObject(
+ const AXObject& child,
+ const AXPositionAdjustmentBehavior =
+ AXPositionAdjustmentBehavior::kMoveRight);
+ static const AXPosition CreatePositionAfterObject(
+ const AXObject& child,
+ const AXPositionAdjustmentBehavior =
+ AXPositionAdjustmentBehavior::kMoveRight);
static const AXPosition CreateFirstPositionInObject(
- const AXObject& container);
- static const AXPosition CreateLastPositionInObject(const AXObject& container);
+ const AXObject& container,
+ const AXPositionAdjustmentBehavior =
+ AXPositionAdjustmentBehavior::kMoveRight);
+ static const AXPosition CreateLastPositionInObject(
+ const AXObject& container,
+ const AXPositionAdjustmentBehavior =
+ AXPositionAdjustmentBehavior::kMoveRight);
static const AXPosition CreatePositionInTextObject(
const AXObject& container,
const int offset,
- const TextAffinity = TextAffinity::kDownstream);
+ const TextAffinity = TextAffinity::kDownstream,
+ const AXPositionAdjustmentBehavior =
+ AXPositionAdjustmentBehavior::kMoveRight);
static const AXPosition FromPosition(
const Position&,
- const TextAffinity = TextAffinity::kDownstream);
- static const AXPosition FromPosition(const PositionWithAffinity&);
+ const TextAffinity = TextAffinity::kDownstream,
+ const AXPositionAdjustmentBehavior =
+ AXPositionAdjustmentBehavior::kMoveRight);
+ static const AXPosition FromPosition(
+ const PositionWithAffinity&,
+ const AXPositionAdjustmentBehavior =
+ AXPositionAdjustmentBehavior::kMoveRight);
// Creates an empty position. |IsValid| will return false.
AXPosition();
@@ -104,13 +132,13 @@ class MODULES_EXPORT AXPosition final {
// tree appear as children of its immediate unignored parent.
const AXPosition AsUnignoredPosition(
const AXPositionAdjustmentBehavior =
- AXPositionAdjustmentBehavior::kMoveLeft) const;
+ AXPositionAdjustmentBehavior::kMoveRight) const;
// Adjusts the position by skipping over any objects that don't have a
// corresponding |node| in the DOM tree, e.g. list bullets.
const AXPosition AsValidDOMPosition(
const AXPositionAdjustmentBehavior =
- AXPositionAdjustmentBehavior::kMoveLeft) const;
+ AXPositionAdjustmentBehavior::kMoveRight) const;
// Converts to a DOM position.
const PositionWithAffinity ToPositionWithAffinity(
@@ -121,6 +149,18 @@ class MODULES_EXPORT AXPosition final {
// Only used by static Create... methods.
explicit AXPosition(const AXObject& container);
+ // Searches the DOM tree starting from a particular child node within a
+ // particular container node, and in the direction indicated by the adjustment
+ // behavior, until it finds a node whose corresponding AX object is not
+ // ignored. Returns nullptr if an unignored object is not found within the
+ // provided container node. The container node could be nullptr if the whole
+ // DOM tree needs to be searched.
+ static const AXObject* FindNeighboringUnignoredObject(
+ const Document& document,
+ const Node& child_node,
+ const ContainerNode* container_node,
+ const AXPositionAdjustmentBehavior adjustment_behavior);
+
// The |AXObject| in which the position is present.
// Only valid during a single document lifecycle hence no need to maintain a
// strong reference to it.
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_position_test.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_position_test.cc
index 505af19e76f..ce0fbac4342 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_position_test.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_position_test.cc
@@ -8,6 +8,7 @@
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/dom/node.h"
#include "third_party/blink/renderer/core/editing/position.h"
+#include "third_party/blink/renderer/core/editing/text_affinity.h"
#include "third_party/blink/renderer/core/html/html_element.h"
#include "third_party/blink/renderer/modules/accessibility/ax_object.h"
#include "third_party/blink/renderer/modules/accessibility/testing/accessibility_test.h"
@@ -34,14 +35,14 @@ constexpr char kCSSBeforeAndAfter[] = R"HTML(
constexpr char kHTMLTable[] = R"HTML(
<p id="before">Before table.</p>
<table id="table" border="1">
- <thead>
+ <thead id="thead">
<tr id="headerRow">
<th id="firstHeaderCell">Number</th>
<th>Month</th>
<th id="lastHeaderCell">Expenses</th>
</tr>
</thead>
- <tbody>
+ <tbody id="tbody">
<tr id="firstRow">
<th id="firstCell">1</th>
<td>Jan</td>
@@ -617,37 +618,162 @@ TEST_F(AccessibilityTest, AXPositionFromDOMPositionWithWhiteSpace) {
// beginning of the next.
//
-TEST_F(AccessibilityTest, PositionInTextWithAffinity) {}
-
-TEST_F(AccessibilityTest, PositionFromTextPositionWithAffinity) {}
+TEST_F(AccessibilityTest, PositionInTextWithAffinity) {
+ SetBodyInnerHTML(R"HTML(<p id="paragraph">Hello</p>)HTML");
+ const Node* text = GetElementById("paragraph")->firstChild();
+ ASSERT_NE(nullptr, text);
+ ASSERT_TRUE(text->IsTextNode());
+ const AXObject* ax_static_text =
+ GetAXObjectByElementId("paragraph")->FirstChild();
+ ASSERT_NE(nullptr, ax_static_text);
+ ASSERT_EQ(AccessibilityRole::kStaticTextRole, ax_static_text->RoleValue());
-TEST_F(AccessibilityTest, PositionInTextWithAffinityAndWhiteSpace) {}
+ // Converting from AX to DOM positions should maintain affinity.
+ const auto ax_position = AXPosition::CreatePositionInTextObject(
+ *ax_static_text, 3, TextAffinity::kUpstream);
+ const auto position = ax_position.ToPositionWithAffinity();
+ EXPECT_EQ(TextAffinity::kUpstream, position.Affinity());
-TEST_F(AccessibilityTest, PositionFromTextPositionWithAffinityAndWhiteSpace) {}
+ // Converting from DOM to AX positions should maintain affinity.
+ const auto ax_position_from_dom = AXPosition::FromPosition(position);
+ EXPECT_EQ(TextAffinity::kUpstream, ax_position.Affinity());
+}
//
-// Test converting to and from accessibility positions with offsets in labels
-// and alt text. Alt text, aria-label and other ARIA relationships can cause the
-// accessible name of an object to be different than its DOM text.
+// Test converting to and from accessibility positions with offsets in HTML
+// labels. HTML labels are ignored in the accessibility tree when associated
+// with checkboxes and radio buttons.
//
-TEST_F(AccessibilityTest, PositionInHTMLLabel) {}
+TEST_F(AccessibilityTest, PositionInHTMLLabel) {
+ SetBodyInnerHTML(R"HTML(
+ <label id="label" for="input">
+ Label text.
+ </label>
+ <p id="paragraph">Intervening paragraph.</p>
+ <input id="input" type="checkbox" checked>
+ )HTML");
-TEST_F(AccessibilityTest, PositionInARIALabel) {}
+ const Node* label = GetElementById("label");
+ ASSERT_NE(nullptr, label);
+ const Node* label_text = label->firstChild();
+ ASSERT_NE(nullptr, label_text);
+ ASSERT_TRUE(label_text->IsTextNode());
+ const Node* paragraph = GetElementById("paragraph");
+ ASSERT_NE(nullptr, paragraph);
-TEST_F(AccessibilityTest, PositionInARIALabelledBy) {}
+ const AXObject* ax_root = GetAXRootObject();
+ ASSERT_NE(nullptr, ax_root);
+ ASSERT_EQ(AccessibilityRole::kWebAreaRole, ax_root->RoleValue());
+ // The HTML label element should be ignored.
+ const AXObject* ax_label = GetAXObjectByElementId("label");
+ ASSERT_NE(nullptr, ax_label);
+ ASSERT_TRUE(ax_label->AccessibilityIsIgnored());
+ const AXObject* ax_paragraph = GetAXObjectByElementId("paragraph");
+ ASSERT_NE(nullptr, ax_paragraph);
+ ASSERT_EQ(AccessibilityRole::kParagraphRole, ax_paragraph->RoleValue());
+
+ // All of the following DOM positions should be ignored in the accessibility
+ // tree.
+ const auto position_before = Position::BeforeNode(*label);
+ const auto position_before_text = Position::BeforeNode(*label_text);
+ const auto position_in_text = Position::FirstPositionInNode(*label_text);
+ const auto position_after = Position::AfterNode(*label);
+
+ for (const auto& position : {position_before, position_before_text,
+ position_in_text, position_after}) {
+ const auto ax_position =
+ AXPosition::FromPosition(position, TextAffinity::kDownstream,
+ AXPositionAdjustmentBehavior::kMoveLeft);
+ EXPECT_FALSE(ax_position.IsTextPosition());
+ EXPECT_EQ(ax_root, ax_position.ContainerObject());
+ EXPECT_EQ(0, ax_position.ChildIndex());
+ EXPECT_EQ(ax_paragraph, ax_position.ChildAfterTreePosition());
+
+ const auto position_from_ax = ax_position.ToPositionWithAffinity();
+ EXPECT_EQ(GetDocument().body(), position_from_ax.AnchorNode());
+ EXPECT_EQ(3, position_from_ax.GetPosition().OffsetInContainerNode());
+ EXPECT_EQ(paragraph,
+ position_from_ax.GetPosition().ComputeNodeAfterPosition());
+ }
+}
-TEST_F(AccessibilityTest, PositionInPlaceholder) {}
+//
+// Objects with "display: none" or the "hidden" attribute are accessibility
+// ignored.
+//
-TEST_F(AccessibilityTest, PositionInAltText) {}
+TEST_F(AccessibilityTest, PositionInIgnoredObject) {
+ SetBodyInnerHTML(R"HTML(
+ <div id="hidden" hidden>Hidden.</div><p id="visible">Visible.</p>
+ )HTML");
-TEST_F(AccessibilityTest, PositionInTitle) {}
+ const Node* hidden = GetElementById("hidden");
+ ASSERT_NE(nullptr, hidden);
+ const Node* visible = GetElementById("visible");
+ ASSERT_NE(nullptr, visible);
-//
-// Some objects are accessibility ignored.
-//
+ const AXObject* ax_root = GetAXRootObject();
+ ASSERT_NE(nullptr, ax_root);
+ ASSERT_EQ(AccessibilityRole::kWebAreaRole, ax_root->RoleValue());
+ ASSERT_EQ(1, ax_root->ChildCount());
+ const AXObject* ax_visible = ax_root->FirstChild();
+ ASSERT_NE(nullptr, ax_visible);
+ ASSERT_EQ(AccessibilityRole::kParagraphRole, ax_visible->RoleValue());
+
+ // The fact that there is a hidden object before |visible| should not affect
+ // setting a position before it.
+ const auto ax_position_before_visible =
+ AXPosition::CreatePositionBeforeObject(*ax_visible);
+ const auto position_before_visible =
+ ax_position_before_visible.ToPositionWithAffinity();
+ EXPECT_EQ(GetDocument().body(), position_before_visible.AnchorNode());
+ EXPECT_EQ(2, position_before_visible.GetPosition().OffsetInContainerNode());
+ EXPECT_EQ(visible,
+ position_before_visible.GetPosition().ComputeNodeAfterPosition());
+
+ const auto ax_position_before_visible_from_dom =
+ AXPosition::FromPosition(position_before_visible);
+ EXPECT_EQ(ax_position_before_visible, ax_position_before_visible_from_dom);
+ EXPECT_EQ(ax_visible,
+ ax_position_before_visible_from_dom.ChildAfterTreePosition());
+
+ // A position at the beginning of the body will appear to be before the hidden
+ // element in the DOM, but it should be before the visible object in the
+ // accessibility tree since the hidden element is not in the tree. Hence, when
+ // converting to the corresponding DOM position, it should be before the
+ // visible element in the DOM as well.
+ const auto ax_position_first =
+ AXPosition::CreateFirstPositionInObject(*ax_root);
+ const auto position_first = ax_position_first.ToPositionWithAffinity();
+ EXPECT_EQ(GetDocument().body(), position_first.AnchorNode());
+ EXPECT_FALSE(position_first.GetPosition().IsBeforeChildren());
+ EXPECT_EQ(2, position_first.GetPosition().OffsetInContainerNode());
+ EXPECT_EQ(visible, position_first.GetPosition().ComputeNodeAfterPosition());
+
+ const auto ax_position_first_from_dom =
+ AXPosition::FromPosition(position_first);
+ EXPECT_EQ(ax_position_first, ax_position_first_from_dom);
+ EXPECT_EQ(ax_visible, ax_position_first_from_dom.ChildAfterTreePosition());
+
+ // A DOM position before |hidden| should convert to an accessibility position
+ // before |visible|.
+ const auto position_before = Position::BeforeNode(*hidden);
+ const auto ax_position_before_from_dom =
+ AXPosition::FromPosition(position_before);
+ EXPECT_EQ(ax_root, ax_position_before_from_dom.ContainerObject());
+ EXPECT_EQ(0, ax_position_before_from_dom.ChildIndex());
+ EXPECT_EQ(ax_visible, ax_position_before_from_dom.ChildAfterTreePosition());
-TEST_F(AccessibilityTest, PositionInIgnoredObject) {}
+ // A DOM position after |hidden| should convert to an accessibility position
+ // before |visible|.
+ const auto position_after = Position::AfterNode(*hidden);
+ const auto ax_position_after_from_dom =
+ AXPosition::FromPosition(position_after);
+ EXPECT_EQ(ax_root, ax_position_after_from_dom.ContainerObject());
+ EXPECT_EQ(0, ax_position_after_from_dom.ChildIndex());
+ EXPECT_EQ(ax_visible, ax_position_after_from_dom.ChildAfterTreePosition());
+}
//
// Aria-hidden can cause things in the DOM to be hidden from accessibility.
@@ -655,12 +781,18 @@ TEST_F(AccessibilityTest, PositionInIgnoredObject) {}
TEST_F(AccessibilityTest, BeforePositionInARIAHiddenShouldSkipARIAHidden) {
SetBodyInnerHTML(R"HTML(
- <p id="before">Before aria-hidden.</p>
- <p id="ariaHidden" aria-hidden="true">Aria-hidden.</p>
- <p id="after">After aria-hidden.</p>
+ <div role="main" id="container">
+ <p id="before">Before aria-hidden.</p>
+ <p id="ariaHidden" aria-hidden="true">Aria-hidden.</p>
+ <p id="after">After aria-hidden.</p>
+ </div>
)HTML");
+
+ const Node* container = GetElementById("container");
+ ASSERT_NE(nullptr, container);
const Node* after = GetElementById("after");
ASSERT_NE(nullptr, after);
+
const AXObject* ax_before = GetAXObjectByElementId("before");
ASSERT_NE(nullptr, ax_before);
ASSERT_EQ(AccessibilityRole::kParagraphRole, ax_before->RoleValue());
@@ -672,7 +804,7 @@ TEST_F(AccessibilityTest, BeforePositionInARIAHiddenShouldSkipARIAHidden) {
const auto ax_position = AXPosition::CreatePositionAfterObject(*ax_before);
const auto position = ax_position.ToPositionWithAffinity();
- EXPECT_EQ(GetDocument().body(), position.AnchorNode());
+ EXPECT_EQ(container, position.AnchorNode());
EXPECT_EQ(5, position.GetPosition().OffsetInContainerNode());
EXPECT_EQ(after, position.GetPosition().ComputeNodeAfterPosition());
@@ -687,12 +819,14 @@ TEST_F(AccessibilityTest, PreviousPositionAfterARIAHiddenShouldSkipARIAHidden) {
<p id="ariaHidden" aria-hidden="true">Aria-hidden.</p>
<p id="after">After aria-hidden.</p>
)HTML");
+
const Node* before = GetElementById("before");
ASSERT_NE(nullptr, before);
ASSERT_NE(nullptr, before->firstChild());
ASSERT_TRUE(before->firstChild()->IsTextNode());
const Node* after = GetElementById("after");
ASSERT_NE(nullptr, after);
+
const AXObject* ax_after = GetAXObjectByElementId("after");
ASSERT_NE(nullptr, ax_after);
ASSERT_EQ(AccessibilityRole::kParagraphRole, ax_after->RoleValue());
@@ -722,21 +856,22 @@ TEST_F(AccessibilityTest, PreviousPositionAfterARIAHiddenShouldSkipARIAHidden) {
EXPECT_EQ(nullptr, ax_position_previous_from_dom.ChildAfterTreePosition());
}
-TEST_F(AccessibilityTest, DISABLED_FromPositionInARIAHidden) {
+TEST_F(AccessibilityTest, FromPositionInARIAHidden) {
SetBodyInnerHTML(R"HTML(
- <p id="before">Before aria-hidden.</p>
- <p id="ariaHidden" aria-hidden="true">Aria-hidden.</p>
- <p id="after">After aria-hidden.</p>
+ <div role="main" id="container">
+ <p id="before">Before aria-hidden.</p>
+ <p id="ariaHidden" aria-hidden="true">Aria-hidden.</p>
+ <p id="after">After aria-hidden.</p>
+ </div>
)HTML");
+
const Node* hidden = GetElementById("ariaHidden");
ASSERT_NE(nullptr, hidden);
- const Node* text = hidden->firstChild();
- ASSERT_NE(nullptr, text);
- ASSERT_TRUE(text->IsTextNode());
- const AXObject* ax_root = GetAXRootObject();
- ASSERT_NE(nullptr, ax_root);
- ASSERT_EQ(AccessibilityRole::kWebAreaRole, ax_root->RoleValue());
- ASSERT_EQ(2, ax_root->ChildCount());
+
+ const AXObject* ax_container = GetAXObjectByElementId("container");
+ ASSERT_NE(nullptr, ax_container);
+ ASSERT_EQ(AccessibilityRole::kMainRole, ax_container->RoleValue());
+ ASSERT_EQ(2, ax_container->ChildCount());
const AXObject* ax_after = GetAXObjectByElementId("after");
ASSERT_NE(nullptr, ax_after);
ASSERT_EQ(AccessibilityRole::kParagraphRole, ax_after->RoleValue());
@@ -744,27 +879,28 @@ TEST_F(AccessibilityTest, DISABLED_FromPositionInARIAHidden) {
ASSERT_TRUE(GetAXObjectByElementId("ariaHidden")->AccessibilityIsIgnored());
const auto position_first = Position::FirstPositionInNode(*hidden);
- const auto position_last = Position::LastPositionInNode(*hidden);
const auto position_before = Position::BeforeNode(*hidden);
const auto position_after = Position::AfterNode(*hidden);
- const auto position_text = Position::EditingPositionOf(text, 3);
- const auto positions = {position_first, position_last, position_before,
- position_after, position_text};
+ const auto positions = {position_first, position_before, position_after};
for (const auto& position : positions) {
- const auto ax_position_left = AXPosition::FromPosition(position);
+ const auto ax_position_left =
+ AXPosition::FromPosition(position, TextAffinity::kDownstream,
+ AXPositionAdjustmentBehavior::kMoveLeft);
EXPECT_TRUE(ax_position_left.IsValid());
EXPECT_FALSE(ax_position_left.IsTextPosition());
- EXPECT_EQ(ax_root, ax_position_left.ContainerObject());
+ EXPECT_EQ(ax_container, ax_position_left.ContainerObject());
EXPECT_EQ(1, ax_position_left.ChildIndex());
EXPECT_EQ(ax_after, ax_position_left.ChildAfterTreePosition());
- const auto ax_position_right = AXPosition::FromPosition(position);
+ const auto ax_position_right =
+ AXPosition::FromPosition(position, TextAffinity::kDownstream,
+ AXPositionAdjustmentBehavior::kMoveRight);
EXPECT_TRUE(ax_position_right.IsValid());
EXPECT_FALSE(ax_position_right.IsTextPosition());
- EXPECT_EQ(ax_root, ax_position_left.ContainerObject());
- EXPECT_EQ(2, ax_position_left.ChildIndex());
- EXPECT_EQ(nullptr, ax_position_left.ChildAfterTreePosition());
+ EXPECT_EQ(ax_container, ax_position_right.ContainerObject());
+ EXPECT_EQ(1, ax_position_right.ChildIndex());
+ EXPECT_EQ(ax_after, ax_position_right.ChildAfterTreePosition());
}
}
@@ -773,19 +909,107 @@ TEST_F(AccessibilityTest, DISABLED_FromPositionInARIAHidden) {
// in the layout tree.
//
-TEST_F(AccessibilityTest, PositionInCanvas) {}
+TEST_F(AccessibilityTest, PositionInCanvas) {
+ SetBodyInnerHTML(R"HTML(
+ <canvas id="canvas1" width="100" height="100">Fallback text</canvas>
+ <canvas id="canvas2" width="100" height="100">
+ <button id="button">Fallback button</button>
+ </canvas>
+ )HTML");
+
+ const Node* canvas_1 = GetElementById("canvas1");
+ ASSERT_NE(nullptr, canvas_1);
+ const Node* text = canvas_1->firstChild();
+ ASSERT_NE(nullptr, text);
+ ASSERT_TRUE(text->IsTextNode());
+ const Node* canvas_2 = GetElementById("canvas2");
+ ASSERT_NE(nullptr, canvas_2);
+ const Node* button = GetElementById("button");
+ ASSERT_NE(nullptr, button);
+
+ const AXObject* ax_canvas_1 = GetAXObjectByElementId("canvas1");
+ ASSERT_NE(nullptr, ax_canvas_1);
+ ASSERT_EQ(AccessibilityRole::kCanvasRole, ax_canvas_1->RoleValue());
+ const AXObject* ax_text = ax_canvas_1->FirstChild();
+ ASSERT_NE(nullptr, ax_text);
+ ASSERT_EQ(AccessibilityRole::kStaticTextRole, ax_text->RoleValue());
+ const AXObject* ax_canvas_2 = GetAXObjectByElementId("canvas2");
+ ASSERT_NE(nullptr, ax_canvas_2);
+ ASSERT_EQ(AccessibilityRole::kCanvasRole, ax_canvas_2->RoleValue());
+ const AXObject* ax_button = GetAXObjectByElementId("button");
+ ASSERT_NE(nullptr, ax_button);
+ ASSERT_EQ(AccessibilityRole::kButtonRole, ax_button->RoleValue());
+
+ const auto ax_position_1 =
+ AXPosition::CreateFirstPositionInObject(*ax_canvas_1);
+ EXPECT_FALSE(ax_position_1.IsTextPosition());
+ EXPECT_EQ(ax_canvas_1, ax_position_1.ContainerObject());
+ EXPECT_EQ(0, ax_position_1.ChildIndex());
+ EXPECT_EQ(ax_text, ax_position_1.ChildAfterTreePosition());
+
+ const auto position_1 = ax_position_1.ToPositionWithAffinity();
+ EXPECT_EQ(canvas_1, position_1.AnchorNode());
+ EXPECT_TRUE(position_1.GetPosition().IsBeforeChildren());
+ EXPECT_EQ(text, position_1.GetPosition().ComputeNodeAfterPosition());
+
+ const auto ax_position_from_dom_1 = AXPosition::FromPosition(position_1);
+ EXPECT_EQ(ax_position_1, ax_position_from_dom_1);
+
+ const auto ax_position_2 = AXPosition::CreatePositionBeforeObject(*ax_text);
+ EXPECT_TRUE(ax_position_2.IsTextPosition());
+ EXPECT_EQ(ax_text, ax_position_2.ContainerObject());
+ EXPECT_EQ(0, ax_position_2.TextOffset());
+
+ const auto position_2 = ax_position_2.ToPositionWithAffinity();
+ EXPECT_EQ(text, position_2.AnchorNode());
+ EXPECT_EQ(0, position_2.GetPosition().OffsetInContainerNode());
+
+ const auto ax_position_from_dom_2 = AXPosition::FromPosition(position_2);
+ EXPECT_EQ(ax_position_2, ax_position_from_dom_2);
+
+ const auto ax_position_3 =
+ AXPosition::CreateLastPositionInObject(*ax_canvas_2);
+ EXPECT_FALSE(ax_position_3.IsTextPosition());
+ EXPECT_EQ(ax_canvas_2, ax_position_3.ContainerObject());
+ EXPECT_EQ(1, ax_position_3.ChildIndex());
+ EXPECT_EQ(nullptr, ax_position_3.ChildAfterTreePosition());
+
+ const auto position_3 = ax_position_3.ToPositionWithAffinity();
+ EXPECT_EQ(canvas_2, position_3.AnchorNode());
+ // There is a line break between the start of the canvas and the button.
+ EXPECT_EQ(2, position_3.GetPosition().ComputeOffsetInContainerNode());
+
+ const auto ax_position_from_dom_3 = AXPosition::FromPosition(position_3);
+ EXPECT_EQ(ax_position_3, ax_position_from_dom_3);
+
+ const auto ax_position_4 = AXPosition::CreatePositionBeforeObject(*ax_button);
+ EXPECT_FALSE(ax_position_4.IsTextPosition());
+ EXPECT_EQ(ax_canvas_2, ax_position_4.ContainerObject());
+ EXPECT_EQ(0, ax_position_4.ChildIndex());
+ EXPECT_EQ(ax_button, ax_position_4.ChildAfterTreePosition());
+
+ const auto position_4 = ax_position_4.ToPositionWithAffinity();
+ EXPECT_EQ(canvas_2, position_4.AnchorNode());
+ // There is a line break between the start of the canvas and the button.
+ EXPECT_EQ(1, position_4.GetPosition().ComputeOffsetInContainerNode());
+ EXPECT_EQ(button, position_4.GetPosition().ComputeNodeAfterPosition());
+
+ const auto ax_position_from_dom_4 = AXPosition::FromPosition(position_4);
+ EXPECT_EQ(ax_position_4, ax_position_from_dom_4);
+}
//
// Some layout objects, e.g. list bullets and CSS::before/after content, appear
// in the accessibility tree but are not present in the DOM.
//
-TEST_F(AccessibilityTest, DISABLED_PositionBeforeListMarker) {
+TEST_F(AccessibilityTest, PositionBeforeListMarker) {
SetBodyInnerHTML(R"HTML(
<ul id="list">
<li id="listItem">Item.</li>
</ul>
)HTML");
+
const Node* list = GetElementById("list");
ASSERT_NE(nullptr, list);
const Node* item = GetElementById("listItem");
@@ -793,6 +1017,7 @@ TEST_F(AccessibilityTest, DISABLED_PositionBeforeListMarker) {
const Node* text = item->firstChild();
ASSERT_NE(nullptr, text);
ASSERT_TRUE(text->IsTextNode());
+
const AXObject* ax_item = GetAXObjectByElementId("listItem");
ASSERT_NE(nullptr, ax_item);
ASSERT_EQ(AccessibilityRole::kListItemRole, ax_item->RoleValue());
@@ -801,47 +1026,63 @@ TEST_F(AccessibilityTest, DISABLED_PositionBeforeListMarker) {
ASSERT_NE(nullptr, ax_marker);
ASSERT_EQ(AccessibilityRole::kListMarkerRole, ax_marker->RoleValue());
+ //
+ // Test adjusting invalid DOM positions to the left.
+ //
+
const auto ax_position_1 = AXPosition::CreateFirstPositionInObject(*ax_item);
+ EXPECT_EQ(ax_item, ax_position_1.ContainerObject());
+ EXPECT_FALSE(ax_position_1.IsTextPosition());
+ EXPECT_EQ(0, ax_position_1.ChildIndex());
+ EXPECT_EQ(ax_marker, ax_position_1.ChildAfterTreePosition());
+
const auto position_1 = ax_position_1.ToPositionWithAffinity(
AXPositionAdjustmentBehavior::kMoveLeft);
EXPECT_EQ(list, position_1.AnchorNode());
- EXPECT_TRUE(position_1.GetPosition().IsBeforeChildren());
+ // There is a line break between the start of the list and the first item.
+ EXPECT_EQ(1, position_1.GetPosition().OffsetInContainerNode());
EXPECT_EQ(item, position_1.GetPosition().ComputeNodeAfterPosition());
const auto ax_position_from_dom_1 = AXPosition::FromPosition(position_1);
- EXPECT_EQ(ax_position_1, ax_position_from_dom_1);
- EXPECT_EQ(ax_marker, ax_position_from_dom_1.ChildAfterTreePosition());
+ EXPECT_EQ(
+ ax_position_1.AsValidDOMPosition(AXPositionAdjustmentBehavior::kMoveLeft),
+ ax_position_from_dom_1);
+ EXPECT_EQ(ax_item, ax_position_from_dom_1.ChildAfterTreePosition());
const auto ax_position_2 = AXPosition::CreatePositionBeforeObject(*ax_marker);
+ EXPECT_EQ(ax_item, ax_position_2.ContainerObject());
+ EXPECT_FALSE(ax_position_2.IsTextPosition());
+ EXPECT_EQ(0, ax_position_2.ChildIndex());
+ EXPECT_EQ(ax_marker, ax_position_2.ChildAfterTreePosition());
+
const auto position_2 = ax_position_2.ToPositionWithAffinity(
AXPositionAdjustmentBehavior::kMoveLeft);
EXPECT_EQ(list, position_2.AnchorNode());
- EXPECT_TRUE(position_2.GetPosition().IsBeforeChildren());
+ // There is a line break between the start of the list and the first item.
+ EXPECT_EQ(1, position_2.GetPosition().OffsetInContainerNode());
EXPECT_EQ(item, position_2.GetPosition().ComputeNodeAfterPosition());
const auto ax_position_from_dom_2 = AXPosition::FromPosition(position_2);
- EXPECT_EQ(ax_position_2, ax_position_from_dom_2);
- EXPECT_EQ(ax_marker, ax_position_from_dom_2.ChildAfterTreePosition());
+ EXPECT_EQ(
+ ax_position_2.AsValidDOMPosition(AXPositionAdjustmentBehavior::kMoveLeft),
+ ax_position_from_dom_2);
+ EXPECT_EQ(ax_item, ax_position_from_dom_2.ChildAfterTreePosition());
+
+ //
+ // Test adjusting the same invalid positions to the right.
+ //
const auto position_3 = ax_position_1.ToPositionWithAffinity(
AXPositionAdjustmentBehavior::kMoveRight);
- EXPECT_EQ(list, position_3.AnchorNode());
+ EXPECT_EQ(item, position_3.AnchorNode());
EXPECT_TRUE(position_3.GetPosition().IsBeforeChildren());
- EXPECT_EQ(item, position_3.GetPosition().ComputeNodeAfterPosition());
-
- const auto ax_position_from_dom_3 = AXPosition::FromPosition(position_3);
- EXPECT_EQ(ax_position_1, ax_position_from_dom_3);
- EXPECT_EQ(ax_marker, ax_position_from_dom_3.ChildAfterTreePosition());
+ EXPECT_EQ(text, position_3.GetPosition().ComputeNodeAfterPosition());
const auto position_4 = ax_position_2.ToPositionWithAffinity(
AXPositionAdjustmentBehavior::kMoveRight);
- EXPECT_EQ(list, position_4.AnchorNode());
+ EXPECT_EQ(item, position_4.AnchorNode());
EXPECT_TRUE(position_4.GetPosition().IsBeforeChildren());
- EXPECT_EQ(item, position_4.GetPosition().ComputeNodeAfterPosition());
-
- const auto ax_position_from_dom_4 = AXPosition::FromPosition(position_4);
- EXPECT_EQ(ax_position_2, ax_position_from_dom_4);
- EXPECT_EQ(ax_marker, ax_position_from_dom_4.ChildAfterTreePosition());
+ EXPECT_EQ(text, position_4.GetPosition().ComputeNodeAfterPosition());
}
TEST_F(AccessibilityTest, PositionAfterListMarker) {
@@ -850,11 +1091,13 @@ TEST_F(AccessibilityTest, PositionAfterListMarker) {
<li id="listItem">Item.</li>
</ol>
)HTML");
+
const Node* item = GetElementById("listItem");
ASSERT_NE(nullptr, item);
const Node* text = item->firstChild();
ASSERT_NE(nullptr, text);
ASSERT_TRUE(text->IsTextNode());
+
const AXObject* ax_item = GetAXObjectByElementId("listItem");
ASSERT_NE(nullptr, ax_item);
ASSERT_EQ(AccessibilityRole::kListItemRole, ax_item->RoleValue());
@@ -869,7 +1112,7 @@ TEST_F(AccessibilityTest, PositionAfterListMarker) {
const auto ax_position = AXPosition::CreatePositionAfterObject(*ax_marker);
const auto position = ax_position.ToPositionWithAffinity();
EXPECT_EQ(item, position.AnchorNode());
- EXPECT_EQ(0, position.GetPosition().OffsetInContainerNode());
+ EXPECT_TRUE(position.GetPosition().IsBeforeChildren());
EXPECT_EQ(text, position.GetPosition().ComputeNodeAfterPosition());
const auto ax_position_from_dom = AXPosition::FromPosition(position);
@@ -970,44 +1213,60 @@ TEST_F(AccessibilityTest, PositionBeforeAndAfterTable) {
TEST_F(AccessibilityTest, PositionAtStartAndEndOfTable) {
SetBodyInnerHTML(kHTMLTable);
- const Node* table = GetElementById("table");
- ASSERT_NE(nullptr, table);
- const Node* last_cell = GetElementById("lastCell");
- ASSERT_NE(nullptr, last_cell);
- const Node* last_cell_text = last_cell->firstChild();
- ASSERT_NE(nullptr, last_cell_text);
- ASSERT_TRUE(last_cell_text->IsTextNode());
+
+ // In the accessibility tree, the thead and tbody elements are ignored, but
+ // they are used as anchors when converting an AX position to a DOM position
+ // because they are the closest anchor to the first and last unignored AX
+ // positions inside the table.
+ const Node* thead = GetElementById("thead");
+ ASSERT_NE(nullptr, thead);
+ const Node* header_row = GetElementById("headerRow");
+ ASSERT_NE(nullptr, header_row);
+ const Node* tbody = GetElementById("tbody");
+ ASSERT_NE(nullptr, tbody);
+
const AXObject* ax_table = GetAXObjectByElementId("table");
ASSERT_NE(nullptr, ax_table);
ASSERT_EQ(AccessibilityRole::kTableRole, ax_table->RoleValue());
+ const AXObject* ax_header_row = GetAXObjectByElementId("headerRow");
+ ASSERT_NE(nullptr, ax_header_row);
+ ASSERT_EQ(AccessibilityRole::kRowRole, ax_header_row->RoleValue());
const auto ax_position_at_start =
AXPosition::CreateFirstPositionInObject(*ax_table);
const auto position_at_start = ax_position_at_start.ToPositionWithAffinity();
- EXPECT_EQ(table, position_at_start.AnchorNode());
- EXPECT_TRUE(position_at_start.GetPosition().IsBeforeChildren());
+ EXPECT_EQ(thead, position_at_start.AnchorNode());
+ EXPECT_EQ(1, position_at_start.GetPosition().OffsetInContainerNode());
+ EXPECT_EQ(header_row,
+ position_at_start.GetPosition().ComputeNodeAfterPosition());
const auto ax_position_at_start_from_dom =
AXPosition::FromPosition(position_at_start);
EXPECT_EQ(ax_position_at_start, ax_position_at_start_from_dom);
+ EXPECT_EQ(ax_header_row,
+ ax_position_at_start_from_dom.ChildAfterTreePosition());
const auto ax_position_at_end =
AXPosition::CreateLastPositionInObject(*ax_table);
const auto position_at_end = ax_position_at_end.ToPositionWithAffinity();
- EXPECT_EQ(table, position_at_end.AnchorNode());
- EXPECT_TRUE(position_at_end.GetPosition().IsAfterChildren());
+ EXPECT_EQ(tbody, position_at_end.AnchorNode());
+ // There are three rows and a line break before and after each one.
+ EXPECT_EQ(6, position_at_end.GetPosition().OffsetInContainerNode());
const auto ax_position_at_end_from_dom =
AXPosition::FromPosition(position_at_end);
- EXPECT_EQ(ax_position_at_end.AsValidDOMPosition(),
- ax_position_at_end_from_dom);
+ EXPECT_EQ(ax_position_at_end, ax_position_at_end_from_dom);
EXPECT_EQ(nullptr, ax_position_at_end_from_dom.ChildAfterTreePosition());
}
TEST_F(AccessibilityTest, PositionInTableHeader) {
SetBodyInnerHTML(kHTMLTable);
+
const Node* header_row = GetElementById("headerRow");
ASSERT_NE(nullptr, header_row);
+ const Node* first_header_cell = GetElementById("firstHeaderCell");
+ ASSERT_NE(nullptr, first_header_cell);
+
const AXObject* ax_first_header_cell =
GetAXObjectByElementId("firstHeaderCell");
ASSERT_NE(nullptr, ax_first_header_cell);
@@ -1023,30 +1282,39 @@ TEST_F(AccessibilityTest, PositionInTableHeader) {
AXPosition::CreatePositionBeforeObject(*ax_first_header_cell);
const auto position_before = ax_position_before.ToPositionWithAffinity();
EXPECT_EQ(header_row, position_before.AnchorNode());
- EXPECT_TRUE(position_before.GetPosition().IsBeforeChildren());
+ EXPECT_EQ(1, position_before.GetPosition().OffsetInContainerNode());
+ EXPECT_EQ(first_header_cell,
+ position_before.GetPosition().ComputeNodeAfterPosition());
const auto ax_position_before_from_dom =
AXPosition::FromPosition(position_before);
EXPECT_EQ(ax_position_before, ax_position_before_from_dom);
+ EXPECT_EQ(ax_first_header_cell,
+ ax_position_before_from_dom.ChildAfterTreePosition());
const auto ax_position_after =
AXPosition::CreatePositionAfterObject(*ax_last_header_cell);
const auto position_after = ax_position_after.ToPositionWithAffinity();
EXPECT_EQ(header_row, position_after.AnchorNode());
- EXPECT_TRUE(position_after.GetPosition().IsAfterChildren());
- EXPECT_EQ(nullptr, position_after.GetPosition().ComputeNodeAfterPosition());
+ // There are three header cells and a line break before and after each one.
+ EXPECT_EQ(6, position_after.GetPosition().OffsetInContainerNode());
const auto ax_position_after_from_dom =
AXPosition::FromPosition(position_after);
EXPECT_EQ(ax_position_after, ax_position_after_from_dom);
+ EXPECT_EQ(nullptr, ax_position_after_from_dom.ChildAfterTreePosition());
}
TEST_F(AccessibilityTest, PositionInTableRow) {
SetBodyInnerHTML(kHTMLTable);
+
const Node* first_row = GetElementById("firstRow");
ASSERT_NE(nullptr, first_row);
+ const Node* first_cell = GetElementById("firstCell");
+ ASSERT_NE(nullptr, first_cell);
const Node* last_row = GetElementById("lastRow");
ASSERT_NE(nullptr, last_row);
+
const AXObject* ax_first_cell = GetAXObjectByElementId("firstCell");
ASSERT_NE(nullptr, ax_first_cell);
ASSERT_EQ(AccessibilityRole::kRowHeaderRole, ax_first_cell->RoleValue());
@@ -1058,31 +1326,39 @@ TEST_F(AccessibilityTest, PositionInTableRow) {
AXPosition::CreatePositionBeforeObject(*ax_first_cell);
const auto position_before = ax_position_before.ToPositionWithAffinity();
EXPECT_EQ(first_row, position_before.AnchorNode());
- EXPECT_TRUE(position_before.GetPosition().IsBeforeChildren());
+ EXPECT_EQ(1, position_before.GetPosition().OffsetInContainerNode());
+ EXPECT_EQ(first_cell,
+ position_before.GetPosition().ComputeNodeAfterPosition());
const auto ax_position_before_from_dom =
AXPosition::FromPosition(position_before);
EXPECT_EQ(ax_position_before, ax_position_before_from_dom);
+ EXPECT_EQ(ax_first_cell,
+ ax_position_before_from_dom.ChildAfterTreePosition());
const auto ax_position_after =
AXPosition::CreatePositionAfterObject(*ax_last_cell);
const auto position_after = ax_position_after.ToPositionWithAffinity();
EXPECT_EQ(last_row, position_after.AnchorNode());
- EXPECT_TRUE(position_after.GetPosition().IsAfterChildren());
- EXPECT_EQ(nullptr, position_after.GetPosition().ComputeNodeAfterPosition());
+ // There are three cells on the last row and a line break before and after
+ // each one.
+ EXPECT_EQ(6, position_after.GetPosition().OffsetInContainerNode());
const auto ax_position_after_from_dom =
AXPosition::FromPosition(position_after);
EXPECT_EQ(ax_position_after, ax_position_after_from_dom);
+ EXPECT_EQ(nullptr, ax_position_after_from_dom.ChildAfterTreePosition());
}
TEST_F(AccessibilityTest, DISABLED_PositionInVirtualAOMNode) {
ScopedAccessibilityObjectModelForTest(true);
SetBodyInnerHTML(kAOM);
+
const Node* parent = GetElementById("aomParent");
ASSERT_NE(nullptr, parent);
const Node* after = GetElementById("after");
ASSERT_NE(nullptr, after);
+
const AXObject* ax_parent = GetAXObjectByElementId("aomParent");
ASSERT_NE(nullptr, ax_parent);
ASSERT_EQ(AccessibilityRole::kGenericContainerRole, ax_parent->RoleValue());
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_selection.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_selection.cc
index 1446e00a430..f0b89089f9c 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_selection.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_selection.cc
@@ -71,6 +71,54 @@ const AXSelection AXSelection::Builder::Build() {
return selection_;
}
+// static
+const AXSelection AXSelection::FromSelection(
+ const SelectionInDOMTree& selection,
+ const AXSelectionBehavior selection_behavior) {
+ if (selection.IsNone())
+ return {};
+ DCHECK(selection.AssertValid());
+
+ const Position dom_base = selection.Base();
+ const Position dom_extent = selection.Extent();
+ const TextAffinity base_affinity = TextAffinity::kDownstream;
+ const TextAffinity extent_affinity = selection.Affinity();
+
+ AXPositionAdjustmentBehavior base_adjustment =
+ AXPositionAdjustmentBehavior::kMoveRight;
+ AXPositionAdjustmentBehavior extent_adjustment =
+ AXPositionAdjustmentBehavior::kMoveRight;
+ switch (selection_behavior) {
+ case AXSelectionBehavior::kShrinkToValidDOMRange:
+ if (selection.IsBaseFirst()) {
+ base_adjustment = AXPositionAdjustmentBehavior::kMoveRight;
+ extent_adjustment = AXPositionAdjustmentBehavior::kMoveLeft;
+ } else {
+ base_adjustment = AXPositionAdjustmentBehavior::kMoveLeft;
+ extent_adjustment = AXPositionAdjustmentBehavior::kMoveRight;
+ }
+ break;
+ case AXSelectionBehavior::kExtendToValidDOMRange:
+ if (selection.IsBaseFirst()) {
+ base_adjustment = AXPositionAdjustmentBehavior::kMoveLeft;
+ extent_adjustment = AXPositionAdjustmentBehavior::kMoveRight;
+ } else {
+ base_adjustment = AXPositionAdjustmentBehavior::kMoveRight;
+ extent_adjustment = AXPositionAdjustmentBehavior::kMoveLeft;
+ }
+ break;
+ }
+
+ const auto ax_base =
+ AXPosition::FromPosition(dom_base, base_affinity, base_adjustment);
+ const auto ax_extent =
+ AXPosition::FromPosition(dom_extent, extent_affinity, extent_adjustment);
+
+ AXSelection::Builder selection_builder;
+ selection_builder.SetBase(ax_base).SetExtent(ax_extent);
+ return selection_builder.Build();
+}
+
AXSelection::AXSelection() : base_(), extent_() {
#if DCHECK_IS_ON()
dom_tree_version_ = 0;
@@ -104,9 +152,9 @@ const SelectionInDOMTree AXSelection::AsSelection(
return {};
AXPositionAdjustmentBehavior base_adjustment =
- AXPositionAdjustmentBehavior::kMoveLeft;
+ AXPositionAdjustmentBehavior::kMoveRight;
AXPositionAdjustmentBehavior extent_adjustment =
- AXPositionAdjustmentBehavior::kMoveLeft;
+ AXPositionAdjustmentBehavior::kMoveRight;
switch (selection_behavior) {
case AXSelectionBehavior::kShrinkToValidDOMRange:
if (base_ <= extent_) {
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_selection.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_selection.h
index 122c4e0071f..4571bc5b89b 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_selection.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_selection.h
@@ -31,6 +31,10 @@ class MODULES_EXPORT AXSelection final {
public:
class Builder;
+ static const AXSelection FromSelection(
+ const SelectionInDOMTree&,
+ const AXSelectionBehavior = AXSelectionBehavior::kExtendToValidDOMRange);
+
AXSelection(const AXSelection&) = default;
AXSelection& operator=(const AXSelection&) = default;
~AXSelection() = default;
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 8d23a21457b..bcabc2dc064 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
@@ -6,8 +6,10 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/core/dom/node.h"
+#include "third_party/blink/renderer/core/editing/frame_selection.h"
#include "third_party/blink/renderer/core/editing/position.h"
#include "third_party/blink/renderer/core/editing/selection_template.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/modules/accessibility/ax_object.h"
#include "third_party/blink/renderer/modules/accessibility/ax_position.h"
#include "third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.h"
@@ -20,9 +22,11 @@ namespace blink {
TEST_F(AccessibilitySelectionTest, SetSelectionInText) {
SetBodyInnerHTML(R"HTML(<p id='paragraph'>Hello</p>)HTML");
+
const Node* text = GetElementById("paragraph")->firstChild();
ASSERT_NE(nullptr, text);
ASSERT_TRUE(text->IsTextNode());
+
const AXObject* ax_static_text =
GetAXObjectByElementId("paragraph")->FirstChild();
ASSERT_NE(nullptr, ax_static_text);
@@ -45,9 +49,11 @@ TEST_F(AccessibilitySelectionTest, SetSelectionInText) {
TEST_F(AccessibilitySelectionTest, SetSelectionInTextWithWhiteSpace) {
SetBodyInnerHTML(R"HTML(<p id='paragraph'> Hello</p>)HTML");
+
const Node* text = GetElementById("paragraph")->firstChild();
ASSERT_NE(nullptr, text);
ASSERT_TRUE(text->IsTextNode());
+
const AXObject* ax_static_text =
GetAXObjectByElementId("paragraph")->FirstChild();
ASSERT_NE(nullptr, ax_static_text);
@@ -75,10 +81,55 @@ TEST_F(AccessibilitySelectionTest, SetSelectionInTextWithWhiteSpace) {
// |AXSelection| to valid endpoints.
//
+TEST_F(AccessibilitySelectionTest, SetSelectionInARIAHidden) {
+ SetSelectionText(R"HTML(
+ <div role="main">
+ <p>Before aria-hidden.</p>
+ ^<p aria-hidden="true">Aria-hidden 1.</p>
+ <p>In the middle of aria-hidden.</p>
+ <p aria-hidden="true">Aria-hidden 2.</p>|
+ <p>After aria-hidden.</p>
+ </div>
+ )HTML");
+
+ const SelectionInDOMTree selection =
+ GetFrame().Selection().GetSelectionInDOMTree();
+
+ const auto ax_selection_shrink = AXSelection::FromSelection(
+ selection, AXSelectionBehavior::kShrinkToValidDOMRange);
+ EXPECT_EQ("", GetSelectionText(ax_selection_shrink));
+
+ const auto ax_selection_extend = AXSelection::FromSelection(
+ selection, AXSelectionBehavior::kExtendToValidDOMRange);
+ EXPECT_EQ("", GetSelectionText(ax_selection_extend));
+}
+
//
// Set selection tests.
// Setting the selection from an |AXSelection| that has endpoints which are not
// present in the layout tree should shring the selection to visible endpoints.
//
+TEST_F(AccessibilitySelectionTest, SetSelectionAroundListBullet) {
+ SetSelectionText(R"HTML(
+ <div role="main">
+ <ul>
+ ^<li>Item 1.</li>
+ <li>Item 2.</li>|
+ </ul>
+ </div>
+ )HTML");
+
+ const SelectionInDOMTree selection =
+ GetFrame().Selection().GetSelectionInDOMTree();
+
+ const auto ax_selection_shrink = AXSelection::FromSelection(
+ selection, AXSelectionBehavior::kShrinkToValidDOMRange);
+ EXPECT_EQ("", GetSelectionText(ax_selection_shrink));
+
+ const auto ax_selection_extend = AXSelection::FromSelection(
+ selection, AXSelectionBehavior::kExtendToValidDOMRange);
+ EXPECT_EQ("", GetSelectionText(ax_selection_extend));
+}
+
} // namespace blink
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 5a08266ddbf..33993771b77 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
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.h"
#include <memory>
+#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/dom/dom_node_ids.h"
#include "third_party/blink/renderer/core/dom/element.h"
@@ -487,21 +488,20 @@ Response InspectorAccessibilityAgent::getPartialAXTree(
LocalFrame* local_frame = document.GetFrame();
if (!local_frame)
return Response::Error("Frame is detached.");
- std::unique_ptr<ScopedAXObjectCache> scoped_cache =
- ScopedAXObjectCache::Create(document);
- AXObjectCacheImpl* cache = ToAXObjectCacheImpl(scoped_cache->Get());
+ AXContext ax_context(document);
+ AXObjectCacheImpl& cache = ToAXObjectCacheImpl(ax_context.GetAXObjectCache());
- AXObject* inspected_ax_object = cache->GetOrCreate(dom_node);
+ AXObject* inspected_ax_object = cache.GetOrCreate(dom_node);
*nodes = protocol::Array<protocol::Accessibility::AXNode>::create();
if (!inspected_ax_object || inspected_ax_object->AccessibilityIsIgnored()) {
(*nodes)->addItem(BuildObjectForIgnoredNode(dom_node, inspected_ax_object,
fetch_relatives.fromMaybe(true),
- *nodes, *cache));
+ *nodes, cache));
return Response::OK();
} else {
(*nodes)->addItem(
BuildProtocolAXObject(*inspected_ax_object, inspected_ax_object,
- fetch_relatives.fromMaybe(true), *nodes, *cache));
+ fetch_relatives.fromMaybe(true), *nodes, cache));
}
if (!inspected_ax_object)
@@ -512,7 +512,7 @@ Response InspectorAccessibilityAgent::getPartialAXTree(
return Response::OK();
if (fetch_relatives.fromMaybe(true))
- AddAncestors(*parent, inspected_ax_object, *nodes, *cache);
+ AddAncestors(*parent, inspected_ax_object, *nodes, cache);
return Response::OK();
}
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 9a91e8f4d82..13950c5ba70 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
@@ -4,6 +4,8 @@
#include "third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.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/node.h"
#include "third_party/blink/renderer/core/html/html_element.h"
#include "third_party/blink/renderer/modules/accessibility/ax_object.h"
@@ -144,7 +146,9 @@ class AXSelectionSerializer final {
// Deserializes an HTML snippet with or without selection markers to an
// accessibility tree. A '^' could be present at the selection anchor offset and
// a '|' at the focus offset. If multiple markers are present, the deserializer
-// will DCHECK. If there are no markers, no selection will be made.
+// will DCHECK. If there are no markers, no selection will be made. We don't
+// allow '^' and '|' markers to appear in anything other than the contents of an
+// HTML node, e.g. they are not permitted in aria-labels.
class AXSelectionDeserializer final {
STACK_ALLOCATED();
@@ -156,11 +160,12 @@ class AXSelectionDeserializer final {
// Creates an accessibility tree rooted at the given HTML element from the
// provided HTML snippet, selects the part of the tree indicated by the
// selection markers in the snippet if present, and returns the tree's root.
- AXObject* Deserialize(const std::string& html_snippet, HTMLElement& element) {
+ const AXSelection Deserialize(const std::string& html_snippet,
+ HTMLElement& element) {
element.SetInnerHTMLFromString(String::FromUTF8(html_snippet.c_str()));
AXObject* root = ax_object_cache_->GetOrCreate(&element);
if (!root)
- return nullptr;
+ return AXSelection::Builder().Build();
FindSelectionMarkers(*root);
if (base_ && extent_) {
@@ -168,33 +173,56 @@ class AXSelectionDeserializer final {
AXSelection ax_selection =
builder.SetBase(base_).SetExtent(extent_).Build();
ax_selection.Select();
+ return ax_selection;
}
- return root;
+ return AXSelection::Builder().Build();
}
private:
void HandleCharacterData(const AXObject& text_object) {
+ CharacterData* const node = ToCharacterData(text_object.GetNode());
int base_offset = -1;
int extent_offset = -1;
- String name = text_object.ComputedName();
- for (unsigned i = 0; i < name.length(); ++i) {
- const UChar character = name[i];
+ StringBuilder builder;
+ for (unsigned i = 0; i < node->length(); ++i) {
+ const UChar character = node->data()[i];
if (character == '^') {
- DCHECK_EQ(base_offset, -1) << text_object;
+ DCHECK_EQ(base_offset, -1) << "Only one '^' is allowed " << text_object;
base_offset = static_cast<int>(i);
continue;
}
if (character == '|') {
- DCHECK_EQ(extent_offset, -1) << text_object;
+ DCHECK_EQ(extent_offset, -1)
+ << "Only one '|' is allowed " << text_object;
extent_offset = static_cast<int>(i);
continue;
}
+ builder.Append(character);
}
+ LOG(ERROR) << "Nektar\n" << base_offset << extent_offset;
if (base_offset == -1 && extent_offset == -1)
return;
+ // Remove the markers, otherwise they would be duplicated if the AX
+ // selection is re-serialized.
+ node->setData(builder.ToString());
+
+ if (node->length() == 0) {
+ // Since the text object contains only selection markers, this indicates
+ // that this is a request for a non-text selection.
+ if (base_offset >= 0)
+ base_ = AXPosition::CreatePositionBeforeObject(text_object);
+ if (extent_offset >= 0)
+ extent_ = AXPosition::CreatePositionBeforeObject(text_object);
+
+ ContainerNode* const parent_node = node->parentNode();
+ DCHECK(parent_node);
+ parent_node->removeChild(node);
+ return;
+ }
+
if (base_offset >= 0)
base_ = AXPosition::CreatePositionInTextObject(text_object, base_offset);
if (extent_offset >= 0) {
@@ -245,16 +273,16 @@ std::string AccessibilitySelectionTest::GetSelectionText(
return AXSelectionSerializer(selection).Serialize(subtree);
}
-AXObject* AccessibilitySelectionTest::SetSelectionText(
+const AXSelection AccessibilitySelectionTest::SetSelectionText(
const std::string& selection_text) const {
HTMLElement* body = GetDocument().body();
if (!body)
- return nullptr;
+ return AXSelection::Builder().Build();
return AXSelectionDeserializer(GetAXObjectCache())
.Deserialize(selection_text, *body);
}
-AXObject* AccessibilitySelectionTest::SetSelectionText(
+const AXSelection AccessibilitySelectionTest::SetSelectionText(
const std::string& selection_text,
HTMLElement& element) const {
return AXSelectionDeserializer(GetAXObjectCache())
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 9f8dcd76fb6..0ee6a45a9e3 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
@@ -35,12 +35,12 @@ class AccessibilitySelectionTest : public AccessibilityTest {
// Sets |selection_text| as inner HTML of the document body and returns the
// root of the accessibility tree at body.
- AXObject* SetSelectionText(const std::string& selection_text) const;
+ const AXSelection SetSelectionText(const std::string& selection_text) const;
// Sets |selection_text| as inner HTML of |element| and returns the root of
// the accessibility subtree at |element|.
- AXObject* SetSelectionText(const std::string& selection_text,
- HTMLElement& element) const;
+ const AXSelection SetSelectionText(const std::string& selection_text,
+ HTMLElement& element) const;
};
} // 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 c2f07058807..4cbf314bec5 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
@@ -18,20 +18,12 @@ AccessibilityTest::AccessibilityTest(LocalFrameClient* local_frame_client)
void AccessibilityTest::SetUp() {
RenderingTest::SetUp();
- DCHECK(GetDocument().GetSettings());
- GetDocument().GetSettings()->SetAccessibilityEnabled(true);
-}
-
-void AccessibilityTest::TearDown() {
- GetDocument().ClearAXObjectCache();
- DCHECK(GetDocument().GetSettings());
- GetDocument().GetSettings()->SetAccessibilityEnabled(false);
- RenderingTest::TearDown();
+ ax_context_.reset(new AXContext(GetDocument()));
}
AXObjectCacheImpl& AccessibilityTest::GetAXObjectCache() const {
auto* ax_object_cache =
- ToAXObjectCacheImpl(GetDocument().GetOrCreateAXObjectCache());
+ ToAXObjectCacheImpl(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 b15f578efa9..2b2a4542e80 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
@@ -9,6 +9,7 @@
#include <sstream>
#include <string>
+#include "third_party/blink/renderer/core/accessibility/ax_context.h"
#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
@@ -26,7 +27,6 @@ class AccessibilityTest : public RenderingTest {
protected:
void SetUp() override;
- void TearDown() override;
AXObjectCacheImpl& GetAXObjectCache() const;
@@ -43,6 +43,8 @@ class AccessibilityTest : public RenderingTest {
std::ostringstream& PrintAXTreeHelper(std::ostringstream&,
const AXObject* root,
size_t level) const;
+
+ std::unique_ptr<AXContext> ax_context_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/BUILD.gn b/chromium/third_party/blink/renderer/modules/animationworklet/BUILD.gn
index 9d3f18b510f..54193864a31 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/BUILD.gn
@@ -22,6 +22,7 @@ blink_modules_sources("animationworklet") {
"animator_definition.h",
"css_animation_worklet.cc",
"css_animation_worklet.h",
+ "effect_proxy.cc",
"effect_proxy.h",
"worklet_animation.cc",
"worklet_animation.h",
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 d6f189521a5..e559ac300fa 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
@@ -24,9 +24,9 @@ void UpdateAnimation(Animator* animator,
WorkletAnimationId id,
double current_time,
CompositorMutatorOutputState* result) {
- CompositorMutatorOutputState::AnimationState animation_output;
+ CompositorMutatorOutputState::AnimationState animation_output(id,
+ base::nullopt);
if (animator->Animate(script_state, current_time, &animation_output)) {
- animation_output.worklet_animation_id = id;
result->animations.push_back(std::move(animation_output));
}
}
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.idl b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.idl
index 7383d146622..ad2d2f2d382 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.idl
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.idl
@@ -2,10 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// https://wicg.github.io/animation-worklet/#animationworkletglobalscope
+
[
Exposed=AnimationWorklet,
Global=(Worklet,AnimationWorklet),
OriginTrialEnabled=AnimationWorklet
] interface AnimationWorkletGlobalScope : WorkletGlobalScope {
- [MeasureAs=AnimationWorkletRegisterAnimator, RaisesException] void registerAnimator(DOMString name, Function animatorConstructor);
+ // TODO(yukishiino): |animatorConstructor| should be of callback function
+ // type (should be: callback T = any ()).
+ [MeasureAs=AnimationWorkletRegisterAnimator, RaisesException] void registerAnimator(DOMString name, CallbackFunctionTreatedAsScriptValue animatorConstructor);
};
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope_test.cc b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope_test.cc
index 461b599e5bb..04887c17559 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope_test.cc
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope_test.cc
@@ -75,7 +75,7 @@ class AnimationWorkletGlobalScopeTest : public PageTestBase {
std::unique_ptr<AnimationWorkletThread> CreateAnimationWorkletThread(
AnimationWorkletProxyClient* proxy_client) {
std::unique_ptr<AnimationWorkletThread> thread =
- AnimationWorkletThread::Create(nullptr, *reporting_proxy_);
+ AnimationWorkletThread::Create(*reporting_proxy_);
WorkerClients* clients = WorkerClients::Create();
if (proxy_client)
@@ -86,8 +86,8 @@ class AnimationWorkletGlobalScopeTest : public PageTestBase {
std::make_unique<GlobalScopeCreationParams>(
document->Url(), ScriptType::kModule, document->UserAgent(),
Vector<CSPHeaderAndType>(), document->GetReferrerPolicy(),
- document->GetSecurityOrigin(), document->IsSecureContext(), clients,
- document->AddressSpace(),
+ document->GetSecurityOrigin(), document->IsSecureContext(),
+ document->GetHttpsState(), clients, document->AddressSpace(),
OriginTrialContext::GetTokens(document).get(),
base::UnguessableToken::Create(), nullptr /* worker_settings */,
kV8CacheOptionsDefault, new WorkletModuleResponsesMap),
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 f3d76abe898..ab0cd3764d2 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
@@ -21,8 +21,7 @@ AnimationWorkletMessagingProxy::~AnimationWorkletMessagingProxy() = default;
std::unique_ptr<WorkerThread>
AnimationWorkletMessagingProxy::CreateWorkerThread() {
- return AnimationWorkletThread::Create(CreateThreadableLoadingContext(),
- WorkletObjectProxy());
+ return AnimationWorkletThread::Create(WorkletObjectProxy());
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_thread.cc b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_thread.cc
index 59557d877e9..cd9d5f2ce83 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_thread.cc
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_thread.cc
@@ -5,7 +5,6 @@
#include "third_party/blink/renderer/modules/animationworklet/animation_worklet_thread.h"
#include "base/memory/ptr_util.h"
-#include "third_party/blink/renderer/core/loader/threadable_loading_context.h"
#include "third_party/blink/renderer/core/workers/global_scope_creation_params.h"
#include "third_party/blink/renderer/core/workers/worker_backing_thread.h"
#include "third_party/blink/renderer/core/workers/worklet_thread_holder.h"
@@ -17,21 +16,18 @@
namespace blink {
std::unique_ptr<AnimationWorkletThread> AnimationWorkletThread::Create(
- ThreadableLoadingContext* loading_context,
WorkerReportingProxy& worker_reporting_proxy) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("animation-worklet"),
"AnimationWorkletThread::create");
DCHECK(IsMainThread());
- return base::WrapUnique(
- new AnimationWorkletThread(loading_context, worker_reporting_proxy));
+ return base::WrapUnique(new AnimationWorkletThread(worker_reporting_proxy));
}
template class WorkletThreadHolder<AnimationWorkletThread>;
AnimationWorkletThread::AnimationWorkletThread(
- ThreadableLoadingContext* loading_context,
WorkerReportingProxy& worker_reporting_proxy)
- : WorkerThread(loading_context, worker_reporting_proxy) {}
+ : WorkerThread(worker_reporting_proxy) {}
AnimationWorkletThread::~AnimationWorkletThread() = default;
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_thread.h b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_thread.h
index 17371e8bbf6..78fe953d9de 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_thread.h
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_thread.h
@@ -11,7 +11,6 @@
namespace blink {
-class ThreadableLoadingContext;
class WorkerReportingProxy;
// Represents the shared backing thread that is used by all animation worklets
@@ -19,7 +18,6 @@ class WorkerReportingProxy;
class MODULES_EXPORT AnimationWorkletThread final : public WorkerThread {
public:
static std::unique_ptr<AnimationWorkletThread> Create(
- ThreadableLoadingContext*,
WorkerReportingProxy&);
~AnimationWorkletThread() override;
@@ -42,7 +40,7 @@ class MODULES_EXPORT AnimationWorkletThread final : public WorkerThread {
static WebThread* GetSharedBackingThread();
private:
- AnimationWorkletThread(ThreadableLoadingContext*, WorkerReportingProxy&);
+ explicit AnimationWorkletThread(WorkerReportingProxy&);
WorkerOrWorkletGlobalScope* CreateWorkerGlobalScope(
std::unique_ptr<GlobalScopeCreationParams>) final;
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_thread_test.cc b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_thread_test.cc
index 2d9fd362ed9..c1b6d4aa1ec 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_thread_test.cc
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_thread_test.cc
@@ -82,14 +82,14 @@ class AnimationWorkletThreadTest : public PageTestBase {
new TestAnimationWorkletProxyClient());
std::unique_ptr<AnimationWorkletThread> thread =
- AnimationWorkletThread::Create(nullptr, *reporting_proxy_);
+ AnimationWorkletThread::Create(*reporting_proxy_);
Document* document = &GetDocument();
thread->Start(
std::make_unique<GlobalScopeCreationParams>(
document->Url(), ScriptType::kModule, document->UserAgent(),
Vector<CSPHeaderAndType>(), document->GetReferrerPolicy(),
- document->GetSecurityOrigin(), document->IsSecureContext(), clients,
- document->AddressSpace(),
+ document->GetSecurityOrigin(), document->IsSecureContext(),
+ document->GetHttpsState(), clients, document->AddressSpace(),
OriginTrialContext::GetTokens(document).get(),
base::UnguessableToken::Create(), nullptr /* worker_settings */,
kV8CacheOptionsDefault, new WorkletModuleResponsesMap),
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animator.cc b/chromium/third_party/blink/renderer/modules/animationworklet/animator.cc
index 1ef75ab8ac2..01716224d8d 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/animator.cc
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/animator.cc
@@ -61,7 +61,7 @@ bool Animator::Animate(ScriptState* script_state,
if (block.HasCaught())
return false;
- output->local_time = effect_->GetLocalTime();
+ output->local_time = effect_->local_time();
return true;
}
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 eb1beab1083..b3756c49021 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
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/modules/animationworklet/css_animation_worklet.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"
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/effect_proxy.cc b/chromium/third_party/blink/renderer/modules/animationworklet/effect_proxy.cc
new file mode 100644
index 00000000000..708eac5f3c4
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/effect_proxy.cc
@@ -0,0 +1,37 @@
+// 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/animationworklet/effect_proxy.h"
+
+namespace blink {
+
+EffectProxy::EffectProxy() : local_time_(base::nullopt) {}
+
+void EffectProxy::setLocalTime(double time_ms, bool is_null) {
+ if (is_null) {
+ local_time_.reset();
+ return;
+ }
+ // Convert double to TimeDelta because cc/animation expects TimeDelta.
+ //
+ // Note on precision loss: 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_ = WTF::TimeDelta::FromMillisecondsD(time_ms);
+}
+
+double EffectProxy::localTime(bool& is_null) const {
+ is_null = !local_time_.has_value();
+ return local_time_.value_or(base::TimeDelta()).InMillisecondsF();
+}
+
+base::Optional<WTF::TimeDelta> EffectProxy::local_time() const {
+ return local_time_;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/effect_proxy.h b/chromium/third_party/blink/renderer/modules/animationworklet/effect_proxy.h
index d81378c2142..91f74500a9b 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/effect_proxy.h
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/effect_proxy.h
@@ -17,27 +17,14 @@ class MODULES_EXPORT EffectProxy : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
- EffectProxy() = default;
+ EffectProxy();
- void setLocalTime(double time_ms) {
- // Convert double to TimeDelta because cc/animation expects TimeDelta.
- //
- // Note on precision loss: 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_ = WTF::TimeDelta::FromMillisecondsD(time_ms);
- }
-
- double localTime() const { return local_time_.InMillisecondsF(); }
-
- WTF::TimeDelta GetLocalTime() const { return local_time_; }
+ void setLocalTime(double time_ms, bool is_null);
+ double localTime(bool& is_null) const;
+ base::Optional<WTF::TimeDelta> local_time() const;
private:
- WTF::TimeDelta local_time_;
+ base::Optional<WTF::TimeDelta> local_time_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/effect_proxy.idl b/chromium/third_party/blink/renderer/modules/animationworklet/effect_proxy.idl
index 3774c0a73d2..9afe3a2599d 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/effect_proxy.idl
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/effect_proxy.idl
@@ -8,5 +8,5 @@
Exposed=AnimationWorklet,
OriginTrialEnabled=AnimationWorklet
] interface EffectProxy {
- attribute unrestricted double localTime;
+ attribute unrestricted double? localTime;
}; \ No newline at end of file
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 957407a7a36..c9789998870 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc
@@ -406,7 +406,8 @@ bool WorkletAnimation::StartOnCompositor(String* failure_message) {
double playback_rate = 1;
CompositorAnimations::FailureCode failure_code =
- GetEffect()->CheckCanStartAnimationOnCompositor(playback_rate);
+ GetEffect()->CheckCanStartAnimationOnCompositor(
+ base::Optional<CompositorElementIdSet>(), playback_rate);
if (!failure_code.Ok()) {
play_state_ = Animation::kIdle;
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 a52b949a720..ca3880c3278 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
@@ -20,23 +20,22 @@ namespace {
KeyframeEffectModelBase* CreateEffectModel() {
StringKeyframeVector frames_mixed_properties;
- scoped_refptr<StringKeyframe> keyframe = StringKeyframe::Create();
+ Persistent<StringKeyframe> keyframe = StringKeyframe::Create();
keyframe->SetOffset(0);
keyframe->SetCSSPropertyValue(CSSPropertyOpacity, "0",
SecureContextMode::kInsecureContext, nullptr);
- frames_mixed_properties.push_back(std::move(keyframe));
+ frames_mixed_properties.push_back(keyframe);
keyframe = StringKeyframe::Create();
keyframe->SetOffset(1);
keyframe->SetCSSPropertyValue(CSSPropertyOpacity, "1",
SecureContextMode::kInsecureContext, nullptr);
- frames_mixed_properties.push_back(std::move(keyframe));
+ frames_mixed_properties.push_back(keyframe);
return StringKeyframeEffectModel::Create(frames_mixed_properties);
}
KeyframeEffect* CreateKeyframeEffect(Element* element) {
Timing timing;
timing.iteration_duration = 30;
- timing.playback_rate = 1;
return KeyframeEffect::Create(element, CreateEffectModel(), timing);
}
diff --git a/chromium/third_party/blink/renderer/modules/app_banner/app_banner_controller.cc b/chromium/third_party/blink/renderer/modules/app_banner/app_banner_controller.cc
index b747c915b81..818b31ea2d8 100644
--- a/chromium/third_party/blink/renderer/modules/app_banner/app_banner_controller.cc
+++ b/chromium/third_party/blink/renderer/modules/app_banner/app_banner_controller.cc
@@ -9,7 +9,7 @@
#include "mojo/public/cpp/bindings/strong_binding.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/dom_window.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/app_banner/before_install_prompt_event.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
@@ -42,7 +42,7 @@ void AppBannerController::BannerPromptRequest(
}
mojom::AppBannerPromptReply reply =
- frame_->DomWindow()->DispatchEvent(BeforeInstallPromptEvent::Create(
+ frame_->DomWindow()->DispatchEvent(*BeforeInstallPromptEvent::Create(
EventTypeNames::beforeinstallprompt, *frame_, std::move(service_ptr),
std::move(event_request), platforms, require_gesture)) ==
DispatchEventResult::kNotCanceled
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 4b13f92e3d4..333d7bc3947 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
@@ -81,8 +81,9 @@ ScriptPromise BeforeInstallPromptEvent::prompt(ScriptState* script_state) {
ExecutionContext* context = ExecutionContext::From(script_state);
Document* doc = ToDocumentOrNull(context);
+
if (require_gesture_ &&
- !Frame::HasTransientUserActivation(doc ? doc->GetFrame() : nullptr)) {
+ !Frame::ConsumeTransientUserActivation(doc ? doc->GetFrame() : nullptr)) {
return ScriptPromise::RejectWithDOMException(
script_state,
DOMException::Create(
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 831d97f4fff..9b7f031e89c 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/BUILD.gn
@@ -8,32 +8,24 @@ blink_modules_sources("background_fetch") {
sources = [
"background_fetch_bridge.cc",
"background_fetch_bridge.h",
- "background_fetch_click_event.cc",
- "background_fetch_click_event.h",
"background_fetch_event.cc",
"background_fetch_event.h",
- "background_fetch_fail_event.cc",
- "background_fetch_fail_event.h",
"background_fetch_fetch.cc",
"background_fetch_fetch.h",
"background_fetch_icon_loader.cc",
"background_fetch_icon_loader.h",
"background_fetch_manager.cc",
"background_fetch_manager.h",
+ "background_fetch_record.cc",
+ "background_fetch_record.h",
"background_fetch_registration.cc",
"background_fetch_registration.h",
- "background_fetch_settled_event.cc",
- "background_fetch_settled_event.h",
"background_fetch_settled_fetch.cc",
"background_fetch_settled_fetch.h",
- "background_fetch_settled_fetches.cc",
- "background_fetch_settled_fetches.h",
"background_fetch_type_converters.cc",
"background_fetch_type_converters.h",
- "background_fetch_update_event.cc",
- "background_fetch_update_event.h",
- "background_fetched_event.cc",
- "background_fetched_event.h",
+ "background_fetch_update_ui_event.cc",
+ "background_fetch_update_ui_event.h",
"service_worker_global_scope_background_fetch.h",
"service_worker_registration_background_fetch.cc",
"service_worker_registration_background_fetch.h",
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 2ed7682ebcf..e5bc03686bc 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
@@ -46,6 +46,19 @@ void BackgroundFetchBridge::GetIconDisplaySize(
GetService()->GetIconDisplaySize(std::move(callback));
}
+void BackgroundFetchBridge::MatchRequests(
+ const String& developer_id,
+ const String& unique_id,
+ base::Optional<WebServiceWorkerRequest> request_to_match,
+ mojom::blink::QueryParamsPtr cache_query_params,
+ bool match_all,
+ mojom::blink::BackgroundFetchService::MatchRequestsCallback callback) {
+ GetService()->MatchRequests(
+ GetSupplementable()->WebRegistration()->RegistrationId(), developer_id,
+ unique_id, std::move(request_to_match), std::move(cache_query_params),
+ match_all, std::move(callback));
+}
+
void BackgroundFetchBridge::Fetch(
const String& developer_id,
Vector<WebServiceWorkerRequest> requests,
@@ -69,10 +82,17 @@ void BackgroundFetchBridge::Abort(const String& developer_id,
void BackgroundFetchBridge::UpdateUI(const String& developer_id,
const String& unique_id,
const String& title,
+ const SkBitmap& icon,
UpdateUICallback callback) {
+ if (title.IsNull() && icon.isNull()) {
+ std::move(callback).Run(
+ mojom::blink::BackgroundFetchError::INVALID_ARGUMENT);
+ return;
+ }
+
GetService()->UpdateUI(
GetSupplementable()->WebRegistration()->RegistrationId(), developer_id,
- unique_id, title, std::move(callback));
+ unique_id, title, icon, std::move(callback));
}
void BackgroundFetchBridge::GetRegistration(const String& developer_id,
@@ -92,6 +112,7 @@ void BackgroundFetchBridge::DidGetRegistration(
if (registration) {
DCHECK_EQ(error, mojom::blink::BackgroundFetchError::NONE);
+ DCHECK_EQ(registration->state(), "pending");
registration->Initialize(GetSupplementable());
}
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 652f8ff66bb..b6dba87ebab 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
@@ -59,12 +59,27 @@ class BackgroundFetchBridge final
// Gets the size of the icon to be displayed in Background Fetch UI.
void GetIconDisplaySize(GetIconDisplaySizeCallback callback);
+ // Matches completed requests for the fetch associated with the |developer_id|
+ // and |unique_id| and returns the {request, response} pairs based on the rest
+ // of the arguments. If |filter_by_request| is true, only response(s) for
+ // |request_to_match| are returned. |cache_query_params| are options for the
+ // query to the cache storage. |match_all|, when true, returns all responses
+ // from the result set, and when false, returns only the first one.
+ void MatchRequests(
+ const String& developer_id,
+ const String& unique_id,
+ base::Optional<WebServiceWorkerRequest> request_to_match,
+ mojom::blink::QueryParamsPtr cache_query_params,
+ bool match_all,
+ mojom::blink::BackgroundFetchService::MatchRequestsCallback callback);
+
// Updates the user interface for the Background Fetch identified by
- // |unique_id| with the updated |title|. Will invoke the |callback| when the
- // interface has been requested to update.
+ // |unique_id| with the updated |title| or |icon|. Will invoke the |callback|
+ // when the interface has been requested to update.
void UpdateUI(const String& developer_id,
const String& unique_id,
const String& title,
+ const SkBitmap& icon,
UpdateUICallback callback);
// Aborts the active Background Fetch for |unique_id|. Will invoke the
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_click_event.cc b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_click_event.cc
deleted file mode 100644
index 3d8d773ec08..00000000000
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_click_event.cc
+++ /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.
-
-#include "third_party/blink/renderer/modules/background_fetch/background_fetch_click_event.h"
-
-#include "third_party/blink/renderer/modules/background_fetch/background_fetch_click_event_init.h"
-#include "third_party/blink/renderer/modules/event_modules_names.h"
-
-namespace blink {
-
-BackgroundFetchClickEvent::BackgroundFetchClickEvent(
- const AtomicString& type,
- const BackgroundFetchClickEventInit& initializer,
- WaitUntilObserver* observer)
- : BackgroundFetchEvent(type, initializer, observer),
- state_(initializer.state()) {}
-
-BackgroundFetchClickEvent::~BackgroundFetchClickEvent() = default;
-
-AtomicString BackgroundFetchClickEvent::state() const {
- return state_;
-}
-
-const AtomicString& BackgroundFetchClickEvent::InterfaceName() const {
- return EventNames::BackgroundFetchClickEvent;
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_click_event.h b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_click_event.h
deleted file mode 100644
index b4a2327079a..00000000000
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_click_event.h
+++ /dev/null
@@ -1,55 +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_BACKGROUND_FETCH_BACKGROUND_FETCH_CLICK_EVENT_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_FETCH_BACKGROUND_FETCH_CLICK_EVENT_H_
-
-#include "third_party/blink/renderer/modules/background_fetch/background_fetch_event.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/text/atomic_string.h"
-
-namespace blink {
-
-class BackgroundFetchClickEventInit;
-class WaitUntilObserver;
-
-class MODULES_EXPORT BackgroundFetchClickEvent final
- : public BackgroundFetchEvent {
- DEFINE_WRAPPERTYPEINFO();
-
- public:
- static BackgroundFetchClickEvent* Create(
- const AtomicString& type,
- const BackgroundFetchClickEventInit& initializer) {
- return new BackgroundFetchClickEvent(type, initializer,
- nullptr /* observer */);
- }
-
- static BackgroundFetchClickEvent* Create(
- const AtomicString& type,
- const BackgroundFetchClickEventInit& initializer,
- WaitUntilObserver* observer) {
- return new BackgroundFetchClickEvent(type, initializer, observer);
- }
-
- ~BackgroundFetchClickEvent() override;
-
- // Web Exposed attribute defined in the IDL file.
- AtomicString state() const;
-
- // ExtendableEvent interface.
- const AtomicString& InterfaceName() const override;
-
- private:
- BackgroundFetchClickEvent(const AtomicString& type,
- const BackgroundFetchClickEventInit& initializer,
- WaitUntilObserver* observer);
-
- AtomicString state_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_FETCH_BACKGROUND_FETCH_CLICK_EVENT_H_
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_click_event.idl b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_click_event.idl
deleted file mode 100644
index 08591605e3f..00000000000
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_click_event.idl
+++ /dev/null
@@ -1,15 +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.
-
-// https://wicg.github.io/background-fetch/#background-fetch-click-event
-
-enum BackgroundFetchState { "pending", "succeeded", "failed" };
-
-[
- Constructor(DOMString type, BackgroundFetchClickEventInit init),
- Exposed=ServiceWorker,
- RuntimeEnabled=BackgroundFetch
-] interface BackgroundFetchClickEvent : BackgroundFetchEvent {
- readonly attribute BackgroundFetchState state;
-};
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_click_event_init.idl b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_click_event_init.idl
deleted file mode 100644
index cf1cb863239..00000000000
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_click_event_init.idl
+++ /dev/null
@@ -1,9 +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.
-
-// https://wicg.github.io/background-fetch/#background-fetch-click-event
-
-dictionary BackgroundFetchClickEventInit : BackgroundFetchEventInit {
- required BackgroundFetchState state;
-};
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 5033231c78b..0dfa3935bd9 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
@@ -5,6 +5,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/modules/background_fetch/background_fetch_registration.h"
#include "third_party/blink/renderer/modules/event_modules_names.h"
namespace blink {
@@ -14,16 +15,21 @@ BackgroundFetchEvent::BackgroundFetchEvent(
const BackgroundFetchEventInit& initializer,
WaitUntilObserver* observer)
: ExtendableEvent(type, initializer, observer),
- developer_id_(initializer.id()) {}
+ registration_(initializer.registration()) {}
BackgroundFetchEvent::~BackgroundFetchEvent() = default;
-String BackgroundFetchEvent::id() const {
- return developer_id_;
+BackgroundFetchRegistration* BackgroundFetchEvent::registration() const {
+ return registration_;
}
const AtomicString& BackgroundFetchEvent::InterfaceName() const {
return EventNames::BackgroundFetchEvent;
}
+void BackgroundFetchEvent::Trace(blink::Visitor* visitor) {
+ visitor->Trace(registration_);
+ ExtendableEvent::Trace(visitor);
+}
+
} // namespace blink
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 19d07114b9b..9656152cdd4 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
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_FETCH_BACKGROUND_FETCH_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_FETCH_BACKGROUND_FETCH_EVENT_H_
+#include "third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom-blink.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/platform/heap/handle.h"
@@ -13,6 +14,7 @@
namespace blink {
class BackgroundFetchEventInit;
+class BackgroundFetchRegistration;
class WaitUntilObserver;
class MODULES_EXPORT BackgroundFetchEvent : public ExtendableEvent {
@@ -34,21 +36,21 @@ class MODULES_EXPORT BackgroundFetchEvent : public ExtendableEvent {
~BackgroundFetchEvent() override;
- // Web Exposed attribute defined in the IDL file. Corresponds to the
- // |developer_id| used elsewhere in the codebase.
- String id() const;
+ // Web Exposed attribute defined in the IDL file.
+ BackgroundFetchRegistration* registration() const;
// ExtendableEvent interface.
const AtomicString& InterfaceName() const override;
+ void Trace(blink::Visitor* visitor) override;
+
protected:
BackgroundFetchEvent(const AtomicString& type,
const BackgroundFetchEventInit& initializer,
WaitUntilObserver* observer);
- // Corresponds to IDL 'id' attribute. Not unique - an active registration can
- // have the same |developer_id_| as one or more inactive registrations.
- String developer_id_;
+ // Corresponds to the 'registration' attribute in the idl.
+ Member<BackgroundFetchRegistration> registration_;
};
} // namespace blink
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 632db60111f..e4c633e4e3c 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
@@ -9,5 +9,5 @@
Exposed=ServiceWorker,
RuntimeEnabled=BackgroundFetch
] interface BackgroundFetchEvent : ExtendableEvent {
- readonly attribute DOMString id;
+ readonly attribute BackgroundFetchRegistration registration;
};
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_event_init.idl b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_event_init.idl
index 24194f4e808..191ccd15b8c 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_event_init.idl
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_event_init.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://wicg.github.io/background-fetch/#background-fetch-event
+// https://wicg.github.io/background-fetch/#dictdef-backgroundfetcheventinit
dictionary BackgroundFetchEventInit : ExtendableEventInit {
- required DOMString id;
-};
+ required BackgroundFetchRegistration registration;
+}; \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_fail_event.cc b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_fail_event.cc
deleted file mode 100644
index 50e51d50dd3..00000000000
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_fail_event.cc
+++ /dev/null
@@ -1,55 +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/background_fetch/background_fetch_fail_event.h"
-
-#include "third_party/blink/public/platform/modules/background_fetch/web_background_fetch_settled_fetch.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_fail_event_init.h"
-#include "third_party/blink/renderer/modules/background_fetch/background_fetch_settled_fetch.h"
-#include "third_party/blink/renderer/modules/event_modules_names.h"
-
-namespace blink {
-
-BackgroundFetchFailEvent::BackgroundFetchFailEvent(
- const AtomicString& type,
- const BackgroundFetchFailEventInit& initializer)
- : BackgroundFetchEvent(type, initializer, nullptr /* observer */),
- fetches_(initializer.fetches()) {}
-
-BackgroundFetchFailEvent::BackgroundFetchFailEvent(
- const AtomicString& type,
- const BackgroundFetchFailEventInit& initializer,
- const WebVector<WebBackgroundFetchSettledFetch>& fetches,
- ScriptState* script_state,
- WaitUntilObserver* observer)
- : BackgroundFetchEvent(type, initializer, observer) {
- fetches_.ReserveInitialCapacity(fetches.size());
- for (const WebBackgroundFetchSettledFetch& fetch : fetches) {
- auto* settled_fetch = BackgroundFetchSettledFetch::Create(
- Request::Create(script_state, fetch.request),
- Response::Create(script_state, fetch.response));
-
- fetches_.push_back(settled_fetch);
- }
-}
-
-BackgroundFetchFailEvent::~BackgroundFetchFailEvent() = default;
-
-HeapVector<Member<BackgroundFetchSettledFetch>>
-BackgroundFetchFailEvent::fetches() const {
- return fetches_;
-}
-
-const AtomicString& BackgroundFetchFailEvent::InterfaceName() const {
- return EventNames::BackgroundFetchFailEvent;
-}
-
-void BackgroundFetchFailEvent::Trace(blink::Visitor* visitor) {
- visitor->Trace(fetches_);
- BackgroundFetchEvent::Trace(visitor);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_fail_event.h b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_fail_event.h
deleted file mode 100644
index d8a6e91668f..00000000000
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_fail_event.h
+++ /dev/null
@@ -1,67 +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_BACKGROUND_FETCH_BACKGROUND_FETCH_FAIL_EVENT_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_FETCH_BACKGROUND_FETCH_FAIL_EVENT_H_
-
-#include "third_party/blink/public/platform/web_vector.h"
-#include "third_party/blink/renderer/modules/background_fetch/background_fetch_event.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/text/atomic_string.h"
-
-namespace blink {
-
-class BackgroundFetchFailEventInit;
-class BackgroundFetchSettledFetch;
-class ScriptState;
-struct WebBackgroundFetchSettledFetch;
-
-class MODULES_EXPORT BackgroundFetchFailEvent final
- : public BackgroundFetchEvent {
- DEFINE_WRAPPERTYPEINFO();
-
- public:
- static BackgroundFetchFailEvent* Create(
- const AtomicString& type,
- const BackgroundFetchFailEventInit& initializer) {
- return new BackgroundFetchFailEvent(type, initializer);
- }
-
- static BackgroundFetchFailEvent* Create(
- const AtomicString& type,
- const BackgroundFetchFailEventInit& initializer,
- const WebVector<WebBackgroundFetchSettledFetch>& fetches,
- ScriptState* script_state,
- WaitUntilObserver* observer) {
- return new BackgroundFetchFailEvent(type, initializer, fetches,
- script_state, observer);
- }
-
- ~BackgroundFetchFailEvent() override;
-
- // Web Exposed attribute defined in the IDL file.
- HeapVector<Member<BackgroundFetchSettledFetch>> fetches() const;
-
- // ExtendableEvent interface.
- const AtomicString& InterfaceName() const override;
-
- void Trace(blink::Visitor* visitor) override;
-
- private:
- BackgroundFetchFailEvent(const AtomicString& type,
- const BackgroundFetchFailEventInit& initializer);
- BackgroundFetchFailEvent(
- const AtomicString& type,
- const BackgroundFetchFailEventInit& initializer,
- const WebVector<WebBackgroundFetchSettledFetch>& fetches,
- ScriptState* script_state,
- WaitUntilObserver* observer);
-
- HeapVector<Member<BackgroundFetchSettledFetch>> fetches_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_FETCH_BACKGROUND_FETCH_FAIL_EVENT_H_
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_fail_event.idl b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_fail_event.idl
deleted file mode 100644
index 1f86f8e7918..00000000000
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_fail_event.idl
+++ /dev/null
@@ -1,13 +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.
-
-// https://wicg.github.io/background-fetch/#background-fetch-fail-event
-
-[
- Constructor(DOMString type, BackgroundFetchFailEventInit init),
- Exposed=ServiceWorker,
- RuntimeEnabled=BackgroundFetch
-] interface BackgroundFetchFailEvent : BackgroundFetchEvent {
- readonly attribute FrozenArray<BackgroundFetchSettledFetch> fetches;
-};
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 3c346b726be..419441d0ecb 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
@@ -5,30 +5,39 @@
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.h"
#include "skia/ext/image_operations.h"
+#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/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/loader/threadable_loader.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/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/graphics/color_behavior.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
#include "third_party/blink/renderer/platform/image-decoders/image_decoder.h"
#include "third_party/blink/renderer/platform/image-decoders/image_frame.h"
+#include "third_party/blink/renderer/platform/image-decoders/segment_reader.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/scheduler/public/background_scheduler.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/text/string_impl.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/threading.h"
namespace blink {
namespace {
-const unsigned long kIconFetchTimeoutInMs = 30000;
-const int kMinimumIconSizeInPx = 16;
-const double kAnySizeScore = 0.8;
-const double kUnspecifiedSizeScore = 0.4;
+constexpr unsigned long kIconFetchTimeoutInMs = 30000;
+constexpr int kMinimumIconSizeInPx = 0;
+
+// Because including base::ClampToRange would be a dependency violation.
+int ClampToRange(const int value, const int min, const int max) {
+ return std::min(std::max(value, min), max);
+}
} // namespace
@@ -57,24 +66,23 @@ void BackgroundFetchIconLoader::DidGetIconDisplaySizeIfSoLoadIcon(
ExecutionContext* execution_context,
IconCallback icon_callback,
const WebSize& icon_display_size_pixels) {
- if (icon_display_size_pixels.IsEmpty()) {
+ icon_display_size_pixels_ = 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()) {
std::move(icon_callback).Run(SkBitmap());
return;
}
- int best_icon_index =
- PickBestIconForDisplay(execution_context, icon_display_size_pixels);
- if (best_icon_index < 0) {
+ KURL best_icon_url = PickBestIconForDisplay(execution_context);
+ if (best_icon_url.IsEmpty()) {
// None of the icons provided was suitable.
std::move(icon_callback).Run(SkBitmap());
return;
}
- KURL best_icon_url =
- execution_context->CompleteURL(icons_[best_icon_index].src());
- icon_callback_ = std::move(icon_callback);
- ThreadableLoaderOptions threadable_loader_options;
- threadable_loader_options.timeout_milliseconds = kIconFetchTimeoutInMs;
+ icon_callback_ = std::move(icon_callback);
ResourceLoaderOptions resource_loader_options;
if (execution_context->IsWorkerGlobalScope())
@@ -85,101 +93,27 @@ void BackgroundFetchIconLoader::DidGetIconDisplaySizeIfSoLoadIcon(
resource_request.SetPriority(ResourceLoadPriority::kMedium);
resource_request.SetRequestorOrigin(execution_context->GetSecurityOrigin());
- threadable_loader_ = ThreadableLoader::Create(*execution_context, this,
- threadable_loader_options,
- resource_loader_options);
-
+ threadable_loader_ =
+ new ThreadableLoader(*execution_context, this, resource_loader_options);
+ threadable_loader_->SetTimeout(
+ TimeDelta::FromMilliseconds(kIconFetchTimeoutInMs));
threadable_loader_->Start(resource_request);
}
-int BackgroundFetchIconLoader::PickBestIconForDisplay(
- ExecutionContext* execution_context,
- const WebSize& icon_display_size_pixels) {
- int best_index = -1;
- double best_score = 0.0;
- for (size_t i = 0; i < icons_.size(); ++i) {
- // If the icon has no or invalid src, move on.
- if (!icons_[i].hasSrc())
- continue;
- KURL icon_url = execution_context->CompleteURL(icons_[i].src());
- if (!icon_url.IsValid() || icon_url.IsEmpty())
- continue;
-
- double score = GetIconScore(icons_[i], icon_display_size_pixels.width);
- if (!score)
- continue;
- // According to the spec, if two icons get the same score, we must use the
- // one that's declared last. (https://w3c.github.io/manifest/#icons-member).
- if (score >= best_score) {
- best_score = score;
- best_index = i;
- }
+KURL BackgroundFetchIconLoader::PickBestIconForDisplay(
+ ExecutionContext* execution_context) {
+ std::vector<Manifest::ImageResource> icons;
+ for (auto& icon : icons_) {
+ // Update the src of |icon| to include the base URL in case relative paths
+ // were used.
+ icon.setSrc(execution_context->CompleteURL(icon.src()));
+ icons.emplace_back(blink::ConvertManifestImageResource(icon));
}
- return best_index;
-}
-// The scoring works as follows:
-// When the size is "any", the icon size score is kAnySizeScore.
-// If unspecified, use the unspecified size score, kUnspecifiedSizeScore as
-// icon score.
-
-// For other sizes, the icon score lies in [0,1] and is computed by multiplying
-// the dominant size score and aspect ratio score.
-//
-// The dominant size score lies in [0, 1] and is computed using
-// dominant size and and |ideal_size|:
-// - If dominant_size < kMinimumIconSizeInPx, the size score is 0.0.
-// - For all other sizes, the score is calculated as
-// 1/(1 + abs(dominant_size-ideal_size))
-// - If dominant_size < ideal_size, there is an upscaling penalty, which is
-// dominant_size/ideal_size.
-//
-// The aspect ratio score lies in [0, 1] and is computed by dividing the short
-// edge length by the long edge. (Bias towards square icons assumed).
-//
-// Note: If this is an ico file containing multiple sizes, return the best
-// score.
-double BackgroundFetchIconLoader::GetIconScore(ManifestImageResource icon,
- const int ideal_size) {
- // Extract sizes from the icon definition, expressed as "<width>x<height>
- // <width>x<height> ...."
- if (!icon.hasSizes() || icon.sizes().IsEmpty())
- return kUnspecifiedSizeScore;
-
- String sizes = icon.sizes();
- // if any size is set to "any" return kAnySizeScore;
- if (sizes.LowerASCII() == "any")
- return kAnySizeScore;
-
- Vector<String> sizes_str;
- sizes.Split(" ", false /* allow_empty_entries*/, sizes_str);
-
- // Pick the first size.
- // TODO(nator): Add support for multiple sizes (.ico files).
- Vector<String> width_and_height_str;
- sizes_str[0].Split("x", false /* allow_empty_entries */,
- width_and_height_str);
- // If sizes isn't in this format, consider it as 'unspecified'.
- if (width_and_height_str.size() != 2)
- return kUnspecifiedSizeScore;
- double width = width_and_height_str[0].ToDouble();
- double height = width_and_height_str[1].ToDouble();
-
- // Compute dominant size score
- int dominant_size = std::max(width, height);
- int short_size = std::min(width, height);
- if (dominant_size < kMinimumIconSizeInPx)
- return 0.0;
-
- double dominant_size_score = 1.0 / (1.0 + abs(dominant_size - ideal_size));
- if (dominant_size < ideal_size)
- dominant_size_score = dominant_size_score * dominant_size / ideal_size;
- // Compute aspect ratio score. If dominant_size is zero, we'd have returned
- // by now.
- double aspect_ratio_score = short_size / dominant_size;
-
- // Compute icon score.
- return aspect_ratio_score * dominant_size_score;
+ // TODO(crbug.com/868875): Handle cases where `sizes` or `purpose` is empty.
+ return KURL(ManifestIconSelector::FindBestMatchingIcon(
+ std::move(icons), icon_display_size_pixels_.height, kMinimumIconSizeInPx,
+ Manifest::ImageResource::Purpose::ANY));
}
void BackgroundFetchIconLoader::Stop() {
@@ -204,22 +138,69 @@ void BackgroundFetchIconLoader::DidFinishLoading(
unsigned long resource_identifier) {
if (stopped_)
return;
- if (data_) {
- // Decode data.
- const bool data_complete = true;
- std::unique_ptr<ImageDecoder> decoder = ImageDecoder::Create(
- data_, data_complete, ImageDecoder::kAlphaPremultiplied,
- ImageDecoder::kDefaultBitDepth, ColorBehavior::TransformToSRGB());
- if (decoder) {
- // the |ImageFrame*| is owned by the decoder.
- ImageFrame* image_frame = decoder->DecodeFrameBufferAtIndex(0);
- if (image_frame) {
- std::move(icon_callback_).Run(image_frame->Bitmap());
- return;
+
+ if (!data_) {
+ RunCallbackWithEmptyBitmap();
+ return;
+ }
+
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner =
+ Platform::Current()->CurrentThread()->GetTaskRunner();
+
+ BackgroundScheduler::PostOnBackgroundThread(
+ FROM_HERE,
+ CrossThreadBind(
+ &BackgroundFetchIconLoader::DecodeAndResizeImageOnBackgroundThread,
+ WrapCrossThreadPersistent(this), std::move(task_runner),
+ SegmentReader::CreateFromSharedBuffer(std::move(data_))));
+}
+
+void BackgroundFetchIconLoader::DecodeAndResizeImageOnBackgroundThread(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ scoped_refptr<SegmentReader> data) {
+ DCHECK(task_runner);
+ DCHECK(data);
+
+ // Explicitly pass in the |icon_display_size_pixels_| to benefit from decoders
+ // that have optimizations for partial decoding.
+ std::unique_ptr<ImageDecoder> decoder = ImageDecoder::Create(
+ std::move(data), /* data_complete= */ true,
+ ImageDecoder::kAlphaPremultiplied, ImageDecoder::kDefaultBitDepth,
+ ColorBehavior::TransformToSRGB(),
+ {icon_display_size_pixels_.width, icon_display_size_pixels_.height});
+
+ if (decoder) {
+ ImageFrame* image_frame = decoder->DecodeFrameBufferAtIndex(0);
+ if (image_frame) {
+ decoded_icon_ = image_frame->Bitmap();
+
+ int width = decoded_icon_.width();
+ int height = decoded_icon_.height();
+
+ // If the |decoded_icon_| is larger than |icon_display_size_pixels_|
+ // permits, we need to resize it as well. This can be done synchronously
+ // given that we're on a background thread already.
+ double scale = std::min(
+ static_cast<double>(icon_display_size_pixels_.width) / width,
+ static_cast<double>(icon_display_size_pixels_.height) / height);
+
+ if (scale < 1) {
+ width = ClampToRange(scale * width, 1, icon_display_size_pixels_.width);
+ height =
+ ClampToRange(scale * height, 1, icon_display_size_pixels_.height);
+
+ // Use the RESIZE_GOOD quality allowing the implementation to pick an
+ // appropriate method for the resize. Can be increased to RESIZE_BETTER
+ // or RESIZE_BEST if the quality looks poor.
+ decoded_icon_ = skia::ImageOperations::Resize(
+ decoded_icon_, skia::ImageOperations::RESIZE_GOOD, width, height);
}
}
}
- RunCallbackWithEmptyBitmap();
+
+ PostCrossThreadTask(*task_runner, FROM_HERE,
+ CrossThreadBind(&BackgroundFetchIconLoader::RunCallback,
+ WrapCrossThreadPersistent(this)));
}
void BackgroundFetchIconLoader::DidFail(const ResourceError& error) {
@@ -230,13 +211,18 @@ void BackgroundFetchIconLoader::DidFailRedirectCheck() {
RunCallbackWithEmptyBitmap();
}
-void BackgroundFetchIconLoader::RunCallbackWithEmptyBitmap() {
+void BackgroundFetchIconLoader::RunCallback() {
// If this has been stopped it is not desirable to trigger further work,
// there is a shutdown of some sort in progress.
if (stopped_)
return;
- std::move(icon_callback_).Run(SkBitmap());
+ std::move(icon_callback_).Run(decoded_icon_);
+}
+
+void BackgroundFetchIconLoader::RunCallbackWithEmptyBitmap() {
+ DCHECK(decoded_icon_.isNull());
+ RunCallback();
}
} // namespace blink
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 400dc73c7f2..2e7a2c83d66 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
@@ -10,7 +10,6 @@
#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/background_fetch/background_fetch_type_converters.h"
-#include "third_party/blink/renderer/modules/manifest/image_resource.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/shared_buffer.h"
#include "third_party/skia/include/core/SkBitmap.h"
@@ -18,6 +17,7 @@
namespace blink {
class BackgroundFetchBridge;
+class SegmentReader;
struct WebSize;
class MODULES_EXPORT BackgroundFetchIconLoader final
@@ -31,16 +31,12 @@ class MODULES_EXPORT BackgroundFetchIconLoader final
BackgroundFetchIconLoader();
~BackgroundFetchIconLoader() override;
- // Scales down |icon| and returns result. If it is already small enough,
- // |icon| is returned unchanged.
- static SkBitmap ScaleDownIfNeeded(const SkBitmap& icon);
-
// Asynchronously download an icon from the given url, decodes the loaded
// data, and passes the bitmap to the given callback.
void Start(BackgroundFetchBridge* bridge,
ExecutionContext* execution_context,
HeapVector<ManifestImageResource> icons,
- IconCallback callback);
+ IconCallback icon_callback);
// Cancels the pending load, if there is one. The |icon_callback_| will not
// be run.
@@ -59,6 +55,8 @@ class MODULES_EXPORT BackgroundFetchIconLoader final
private:
friend class BackgroundFetchIconLoaderTest;
+
+ void RunCallback();
void RunCallbackWithEmptyBitmap();
// Callback for BackgroundFetchBridge::GetIconDisplaySize()
@@ -68,20 +66,37 @@ class MODULES_EXPORT BackgroundFetchIconLoader final
const WebSize& icon_display_size_pixels);
// Picks the best icon from the list of developer provided icons, for current
- // display, given the ideal |icon_display_size_pixels|, and returns its index
- // in the icons_ array.
- int PickBestIconForDisplay(ExecutionContext* execution_context,
- const WebSize& icon_display_size_pixels);
+ // display, given the ideal |icon_display_size_pixels_|, and returns its KURL.
+ // If none of the icons is appropriate, this returns an empty URL.
+ KURL PickBestIconForDisplay(ExecutionContext* execution_context);
- // Get a score for the given icon, based on ideal_size. The icon with the
- // highest score is chosen.
- double GetIconScore(ManifestImageResource icon, const int ideal_size);
+ // Decodes the |data| to a SkBitmap using the image decoders and resizes it to
+ // be no larger than |icon_display_size_pixels_|.
+ void DecodeAndResizeImageOnBackgroundThread(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ scoped_refptr<SegmentReader> data);
+
+ // Called when the image has been decoded and resized on a background thread.
+ void DidFinishDecoding();
- bool stopped_ = false;
- scoped_refptr<SharedBuffer> data_;
- IconCallback icon_callback_;
HeapVector<ManifestImageResource> icons_;
+ IconCallback icon_callback_;
+
Member<ThreadableLoader> threadable_loader_;
+
+ // Size at which the icon will be presented to the user.
+ WebSize icon_display_size_pixels_;
+
+ // Data received from the ThreadableLoader. Will be invalidated when decoding
+ // of the image data starts.
+ scoped_refptr<SharedBuffer> data_;
+
+ // Result of decoding the icon on the background thread.
+ SkBitmap decoded_icon_;
+
+ // Whether the icon loading operation has been stopped. The process should
+ // be aborted then, and |icon_callback_| must not be invoked anymore.
+ bool stopped_ = false;
};
} // namespace blink
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 df73355f7ad..f0b678602c2 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
@@ -28,10 +28,11 @@ enum class BackgroundFetchLoadState {
constexpr char kBackgroundFetchImageLoaderBaseUrl[] = "http://test.com/";
constexpr char kBackgroundFetchImageLoaderBaseDir[] = "notifications/";
+constexpr char kBackgroundFetchImageLoaderIcon500x500FullPath[] =
+ "http://test.com/500x500.png";
constexpr char kBackgroundFetchImageLoaderIcon500x500[] = "500x500.png";
constexpr char kBackgroundFetchImageLoaderIcon48x48[] = "48x48.png";
constexpr char kBackgroundFetchImageLoaderIcon3000x2000[] = "3000x2000.png";
-constexpr char kBackgroundFetchImageLoaderIcon[] = "3000x2000.png";
} // namespace
@@ -44,7 +45,13 @@ class BackgroundFetchIconLoaderTest : public PageTestBase {
->UnregisterAllURLsAndClearMemoryCache();
}
- void SetUp() override { PageTestBase::SetUp(IntSize()); }
+ void SetUp() override {
+ PageTestBase::SetUp(IntSize());
+ GetDocument().SetBaseURLOverride(KURL(kBackgroundFetchImageLoaderBaseUrl));
+ RegisterMockedURL(kBackgroundFetchImageLoaderIcon500x500);
+ RegisterMockedURL(kBackgroundFetchImageLoaderIcon48x48);
+ RegisterMockedURL(kBackgroundFetchImageLoaderIcon3000x2000);
+ }
// Registers a mocked URL.
WebURL RegisterMockedURL(const String& file_name) {
@@ -57,40 +64,50 @@ class BackgroundFetchIconLoaderTest : public PageTestBase {
// Callback for BackgroundFetchIconLoader. This will set up the state of the
// load as either success or failed based on whether the bitmap is empty.
- void IconLoaded(const SkBitmap& bitmap) {
- if (!bitmap.empty())
+ void IconLoaded(base::OnceClosure quit_closure, const SkBitmap& bitmap) {
+ bitmap_ = bitmap;
+
+ if (!bitmap_.isNull())
loaded_ = BackgroundFetchLoadState::kLoadSuccessful;
else
loaded_ = BackgroundFetchLoadState::kLoadFailed;
+
+ std::move(quit_closure).Run();
}
ManifestImageResource CreateTestIcon(const String& url_str,
const String& size) {
- KURL url = RegisterMockedURL(url_str);
ManifestImageResource icon;
- icon.setSrc(url.GetString());
+ icon.setSrc(url_str);
icon.setType("image/png");
icon.setSizes(size);
+ icon.setPurpose("any");
return icon;
}
- int PickRightIcon(HeapVector<ManifestImageResource> icons,
- const WebSize& ideal_display_size) {
+ KURL PickRightIcon(HeapVector<ManifestImageResource> icons,
+ const WebSize& ideal_display_size) {
loader_->icons_ = std::move(icons);
- return loader_->PickBestIconForDisplay(GetContext(), ideal_display_size);
+ loader_->icon_display_size_pixels_ = ideal_display_size;
+
+ return loader_->PickBestIconForDisplay(GetContext());
}
- void LoadIcon(const KURL& url) {
+ void LoadIcon(const KURL& url,
+ const WebSize& maximum_size,
+ base::OnceClosure quit_closure) {
ManifestImageResource icon;
icon.setSrc(url.GetString());
icon.setType("image/png");
icon.setSizes("500x500");
+ icon.setPurpose("ANY");
HeapVector<ManifestImageResource> icons(1, icon);
loader_->icons_ = std::move(icons);
loader_->DidGetIconDisplaySizeIfSoLoadIcon(
GetContext(),
- Bind(&BackgroundFetchIconLoaderTest::IconLoaded, WTF::Unretained(this)),
- WebSize(192, 192));
+ WTF::Bind(&BackgroundFetchIconLoaderTest::IconLoaded,
+ WTF::Unretained(this), WTF::Passed(std::move(quit_closure))),
+ maximum_size);
}
ExecutionContext* GetContext() const { return &GetDocument(); }
@@ -98,67 +115,70 @@ class BackgroundFetchIconLoaderTest : public PageTestBase {
protected:
ScopedTestingPlatformSupport<TestingPlatformSupport> platform_;
BackgroundFetchLoadState loaded_ = BackgroundFetchLoadState::kNotLoaded;
+ SkBitmap bitmap_;
private:
Persistent<BackgroundFetchIconLoader> loader_;
};
TEST_F(BackgroundFetchIconLoaderTest, SuccessTest) {
- KURL url = RegisterMockedURL(kBackgroundFetchImageLoaderIcon500x500);
- LoadIcon(url);
+ base::RunLoop run_loop;
+
+ WebSize maximum_size{192, 168};
+ LoadIcon(KURL(kBackgroundFetchImageLoaderIcon500x500FullPath), maximum_size,
+ run_loop.QuitClosure());
+
platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
- EXPECT_EQ(BackgroundFetchLoadState::kLoadSuccessful, loaded_);
-}
-TEST_F(BackgroundFetchIconLoaderTest, PickRightIconTest) {
- ManifestImageResource icon0 =
- CreateTestIcon(kBackgroundFetchImageLoaderIcon500x500, "500x500");
- ManifestImageResource icon1 =
- CreateTestIcon(kBackgroundFetchImageLoaderIcon48x48, "48x48");
- ManifestImageResource icon2 =
- CreateTestIcon(kBackgroundFetchImageLoaderIcon3000x2000, "3000x2000");
+ run_loop.Run();
- HeapVector<ManifestImageResource> icons;
- icons.push_back(icon0);
- icons.push_back(icon1);
- icons.push_back(icon2);
+ ASSERT_EQ(BackgroundFetchLoadState::kLoadSuccessful, loaded_);
+ ASSERT_FALSE(bitmap_.drawsNothing());
- int index = PickRightIcon(std::move(icons), WebSize(50, 50));
- EXPECT_EQ(index, 1);
+ // Resizing a 500x500 image to fit on a canvas of 192x168 pixels should yield
+ // a decoded image size of 168x168, avoiding image data to get lost.
+ EXPECT_EQ(bitmap_.width(), 168);
+ EXPECT_EQ(bitmap_.height(), 168);
}
-TEST_F(BackgroundFetchIconLoaderTest, PickRightIconGivenAnyTest) {
- ManifestImageResource icon0 =
- CreateTestIcon(kBackgroundFetchImageLoaderIcon500x500, "500x500");
- ManifestImageResource icon1 =
- CreateTestIcon(kBackgroundFetchImageLoaderIcon48x48, "48x48");
- ManifestImageResource icon2 =
- CreateTestIcon(kBackgroundFetchImageLoaderIcon, "any");
+TEST_F(BackgroundFetchIconLoaderTest, PickIconRelativePath) {
+ HeapVector<ManifestImageResource> icons;
+ icons.push_back(
+ CreateTestIcon(kBackgroundFetchImageLoaderIcon500x500, "500x500"));
+ KURL best_icon = PickRightIcon(std::move(icons), WebSize(500, 500));
+ ASSERT_TRUE(best_icon.IsValid());
+ EXPECT_EQ(best_icon, KURL(kBackgroundFetchImageLoaderIcon500x500FullPath));
+}
+
+TEST_F(BackgroundFetchIconLoaderTest, PickIconFullPath) {
HeapVector<ManifestImageResource> icons;
- icons.push_back(icon0);
- icons.push_back(icon1);
- icons.push_back(icon2);
+ icons.push_back(CreateTestIcon(kBackgroundFetchImageLoaderIcon500x500FullPath,
+ "500x500"));
- int index = PickRightIcon(std::move(icons), WebSize(50, 50));
- EXPECT_EQ(index, 2);
+ KURL best_icon = PickRightIcon(std::move(icons), WebSize(500, 500));
+ ASSERT_TRUE(best_icon.IsValid());
+ EXPECT_EQ(best_icon, KURL(kBackgroundFetchImageLoaderIcon500x500FullPath));
}
-TEST_F(BackgroundFetchIconLoaderTest, PickRightIconWithTieBreakTest) {
- // Test that if two icons get the same score, the one declared last gets
- // picked.
+TEST_F(BackgroundFetchIconLoaderTest, PickRightIcon) {
ManifestImageResource icon0 =
CreateTestIcon(kBackgroundFetchImageLoaderIcon500x500, "500x500");
ManifestImageResource icon1 =
CreateTestIcon(kBackgroundFetchImageLoaderIcon48x48, "48x48");
ManifestImageResource icon2 =
- CreateTestIcon(kBackgroundFetchImageLoaderIcon3000x2000, "48x48");
+ CreateTestIcon(kBackgroundFetchImageLoaderIcon3000x2000, "3000x2000");
+
HeapVector<ManifestImageResource> icons;
icons.push_back(icon0);
icons.push_back(icon1);
icons.push_back(icon2);
- int index = PickRightIcon(std::move(icons), WebSize(50, 50));
- EXPECT_EQ(index, 2);
+
+ KURL best_icon = PickRightIcon(std::move(icons), WebSize(42, 42));
+ ASSERT_TRUE(best_icon.IsValid());
+ // We expect the smallest Icon larger than the ideal display size.
+ EXPECT_EQ(best_icon, KURL(KURL(kBackgroundFetchImageLoaderBaseUrl),
+ kBackgroundFetchImageLoaderIcon48x48));
}
} // namespace blink
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 04edc0b08dc..dbe549d7100 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
@@ -4,11 +4,15 @@
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_manager.h"
+#include "base/memory/scoped_refptr.h"
+#include "base/metrics/histogram_macros.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_request.h"
#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/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"
#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/frame/deprecation.h"
@@ -20,8 +24,10 @@
#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/service_worker/service_worker_registration.h"
+#include "third_party/blink/renderer/platform/bindings/exception_code.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"
#include "third_party/blink/renderer/platform/loader/cors/cors.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_utils.h"
#include "third_party/blink/renderer/platform/network/network_utils.h"
@@ -29,7 +35,6 @@
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
#include "third_party/skia/include/core/SkBitmap.h"
-
namespace blink {
namespace {
@@ -85,22 +90,8 @@ bool ShouldBlockMixedContent(ExecutionContext* execution_context,
const KURL& request_url) {
// TODO(crbug.com/757441): Using MixedContentChecker::ShouldBlockFetch would
// log better metrics.
- if (MixedContentChecker::IsMixedContent(
- execution_context->GetSecurityOrigin(), request_url)) {
- return true;
- }
-
- // Normally requests from e.g. http://127.0.0.1 aren't subject to Mixed
- // Content checks even though that is a secure context. Since this is a new
- // API only exposed on secure contexts, be strict pending the discussion in
- // https://groups.google.com/a/chromium.org/d/topic/security-dev/29Ftfgn-w0I/discussion
- // https://w3c.github.io/webappsec-mixed-content/#a-priori-authenticated-url
- if (!SecurityOrigin::Create(request_url)->IsPotentiallyTrustworthy() &&
- !request_url.ProtocolIsData()) {
- return true;
- }
-
- return false;
+ return MixedContentChecker::IsMixedContent(
+ execution_context->GetSecurityOrigin(), request_url);
}
bool ShouldBlockDanglingMarkup(const KURL& request_url) {
@@ -156,6 +147,31 @@ bool ShouldBlockCORSPreflight(ExecutionContext* execution_context,
return false;
}
+scoped_refptr<BlobDataHandle> ExtractBlobHandle(
+ Request* request,
+ ExceptionState& exception_state) {
+ DCHECK(request);
+
+ if (request->IsBodyLocked(exception_state) == Body::BodyLocked::kLocked ||
+ request->IsBodyUsed(exception_state) == Body::BodyUsed::kUsed) {
+ DCHECK(!exception_state.HadException());
+ exception_state.ThrowTypeError("Request body is already used");
+ return nullptr;
+ }
+
+ BodyStreamBuffer* buffer = request->BodyBuffer();
+ if (!buffer)
+ return nullptr;
+
+ auto blob_handle = buffer->DrainAsBlobDataHandle(
+ BytesConsumer::BlobSizePolicy::kDisallowBlobWithInvalidSize,
+ exception_state);
+ if (exception_state.HadException())
+ return nullptr;
+
+ return blob_handle;
+}
+
} // namespace
BackgroundFetchManager::BackgroundFetchManager(
@@ -209,6 +225,14 @@ ScriptPromise BackgroundFetchManager::fetch(
"that URL is invalid");
}
+ // https://wicg.github.io/background-fetch/#dom-backgroundfetchmanager-fetch
+ // ""If |internalRequest|’s mode is "no-cors", then return a promise
+ // rejected with a TypeError.""
+ if (web_request.Mode() == network::mojom::FetchRequestMode::kNoCORS) {
+ return RejectWithTypeError(script_state, request_url,
+ "the request mode must not be no-cors");
+ }
+
// Check this before mixed content, so that if mixed content is blocked by
// CSP they get a CSP warning rather than a mixed content warning.
if (ShouldBlockDueToCSP(execution_context, request_url)) {
@@ -267,8 +291,8 @@ ScriptPromise BackgroundFetchManager::fetch(
return promise;
}
- DidLoadIcons(id, std::move(web_requests), std::move(options_ptr),
- WrapPersistent(resolver), SkBitmap());
+ DidLoadIcons(id, std::move(web_requests), std::move(options_ptr), resolver,
+ SkBitmap());
return promise;
}
@@ -278,15 +302,23 @@ void BackgroundFetchManager::DidLoadIcons(
mojom::blink::BackgroundFetchOptionsPtr options,
ScriptPromiseResolver* resolver,
const SkBitmap& icon) {
- bridge_->Fetch(id, std::move(web_requests), std::move(options), icon,
- WTF::Bind(&BackgroundFetchManager::DidFetch,
- WrapPersistent(this), WrapPersistent(resolver)));
+ bridge_->Fetch(
+ id, std::move(web_requests), std::move(options), icon,
+ WTF::Bind(&BackgroundFetchManager::DidFetch, WrapPersistent(this),
+ WrapPersistent(resolver), base::Time::Now()));
}
void BackgroundFetchManager::DidFetch(
ScriptPromiseResolver* resolver,
+ base::Time time_started,
mojom::blink::BackgroundFetchError error,
BackgroundFetchRegistration* registration) {
+ UMA_HISTOGRAM_TIMES("BackgroundFetch.Manager.FetchDuration",
+ base::Time::Now() - time_started);
+
+ ScriptState* script_state = resolver->GetScriptState();
+ ScriptState::Scope scope(script_state);
+
switch (error) {
case mojom::blink::BackgroundFetchError::NONE:
DCHECK(registration);
@@ -294,21 +326,30 @@ void BackgroundFetchManager::DidFetch(
return;
case mojom::blink::BackgroundFetchError::DUPLICATED_DEVELOPER_ID:
DCHECK(!registration);
- resolver->Reject(DOMException::Create(
- DOMExceptionCode::kInvalidStateError,
+ resolver->Reject(V8ThrowException::CreateTypeError(
+ script_state->GetIsolate(),
"There already is a registration for the given id."));
return;
+ case mojom::blink::BackgroundFetchError::PERMISSION_DENIED:
+ resolver->Reject(V8ThrowException::CreateTypeError(
+ script_state->GetIsolate(),
+ "This origin does not have permission to start a fetch."));
+ return;
case mojom::blink::BackgroundFetchError::STORAGE_ERROR:
DCHECK(!registration);
- resolver->Reject(DOMException::Create(
- DOMExceptionCode::kAbortError,
+ resolver->Reject(V8ThrowException::CreateTypeError(
+ script_state->GetIsolate(),
"Failed to store registration due to I/O error."));
return;
case mojom::blink::BackgroundFetchError::SERVICE_WORKER_UNAVAILABLE:
- resolver->Reject(DOMException::Create(
- DOMExceptionCode::kInvalidStateError,
+ resolver->Reject(V8ThrowException::CreateTypeError(
+ script_state->GetIsolate(),
"There is no service worker available to service the fetch."));
return;
+ case mojom::blink::BackgroundFetchError::QUOTA_EXCEEDED:
+ resolver->Reject(DOMException::Create(
+ DOMExceptionCode::kQuotaExceededError, "Quota exceeded."));
+ return;
case mojom::blink::BackgroundFetchError::INVALID_ARGUMENT:
case mojom::blink::BackgroundFetchError::INVALID_ID:
// Not applicable for this callback.
@@ -320,20 +361,18 @@ void BackgroundFetchManager::DidFetch(
ScriptPromise BackgroundFetchManager::get(ScriptState* script_state,
const String& id) {
- if (!registration_->active()) {
- return ScriptPromise::Reject(
- script_state,
- V8ThrowException::CreateTypeError(script_state->GetIsolate(),
- "No active registration available on "
- "the ServiceWorkerRegistration."));
- }
+ // 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())
+ return ScriptPromise::CastUndefined(script_state);
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
ScriptPromise promise = resolver->Promise();
bridge_->GetRegistration(
id, WTF::Bind(&BackgroundFetchManager::DidGetRegistration,
- WrapPersistent(this), WrapPersistent(resolver)));
+ WrapPersistent(this), WrapPersistent(resolver),
+ base::Time::Now()));
return promise;
}
@@ -375,11 +414,15 @@ Vector<WebServiceWorkerRequest> BackgroundFetchManager::CreateWebRequestVector(
DCHECK(request);
request->PopulateWebServiceWorkerRequest(web_requests[i]);
+ web_requests[i].SetBlobDataHandle(
+ ExtractBlobHandle(request, exception_state));
}
} else if (requests.IsRequest()) {
DCHECK(requests.GetAsRequest());
web_requests.resize(1);
requests.GetAsRequest()->PopulateWebServiceWorkerRequest(web_requests[0]);
+ web_requests[0].SetBlobDataHandle(
+ ExtractBlobHandle(requests.GetAsRequest(), exception_state));
} else if (requests.IsUSVString()) {
Request* request = Request::Create(script_state, requests.GetAsUSVString(),
exception_state);
@@ -399,13 +442,24 @@ Vector<WebServiceWorkerRequest> BackgroundFetchManager::CreateWebRequestVector(
void BackgroundFetchManager::DidGetRegistration(
ScriptPromiseResolver* resolver,
+ base::Time time_started,
mojom::blink::BackgroundFetchError error,
BackgroundFetchRegistration* registration) {
+ UMA_HISTOGRAM_TIMES("BackgroundFetch.Manager.GetDuration",
+ base::Time::Now() - time_started);
+
+ ScriptState* script_state = resolver->GetScriptState();
+ ScriptState::Scope scope(script_state);
+
switch (error) {
case mojom::blink::BackgroundFetchError::NONE:
- case mojom::blink::BackgroundFetchError::INVALID_ID:
+ DCHECK(registration);
resolver->Resolve(registration);
return;
+ case mojom::blink::BackgroundFetchError::INVALID_ID:
+ DCHECK(!registration);
+ resolver->Resolve(v8::Undefined(script_state->GetIsolate()));
+ return;
case mojom::blink::BackgroundFetchError::STORAGE_ERROR:
DCHECK(!registration);
resolver->Reject(
@@ -419,6 +473,8 @@ void BackgroundFetchManager::DidGetRegistration(
return;
case mojom::blink::BackgroundFetchError::DUPLICATED_DEVELOPER_ID:
case mojom::blink::BackgroundFetchError::INVALID_ARGUMENT:
+ case mojom::blink::BackgroundFetchError::PERMISSION_DENIED:
+ case mojom::blink::BackgroundFetchError::QUOTA_EXCEEDED:
// Not applicable for this callback.
break;
}
@@ -427,28 +483,33 @@ void BackgroundFetchManager::DidGetRegistration(
}
ScriptPromise BackgroundFetchManager::getIds(ScriptState* script_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()) {
- return ScriptPromise::Reject(
- script_state,
- V8ThrowException::CreateTypeError(script_state->GetIsolate(),
- "No active registration available on "
- "the ServiceWorkerRegistration."));
+ return ScriptPromise::Cast(script_state,
+ v8::Array::New(script_state->GetIsolate()));
}
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
ScriptPromise promise = resolver->Promise();
- bridge_->GetDeveloperIds(
- WTF::Bind(&BackgroundFetchManager::DidGetDeveloperIds,
- WrapPersistent(this), WrapPersistent(resolver)));
+ bridge_->GetDeveloperIds(WTF::Bind(
+ &BackgroundFetchManager::DidGetDeveloperIds, WrapPersistent(this),
+ WrapPersistent(resolver), base::Time::Now()));
return promise;
}
void BackgroundFetchManager::DidGetDeveloperIds(
ScriptPromiseResolver* resolver,
+ base::Time time_started,
mojom::blink::BackgroundFetchError error,
const Vector<String>& developer_ids) {
+ UMA_HISTOGRAM_TIMES("BackgroundFetch.Manager.GetIdsDuration",
+ base::Time::Now() - time_started);
+
+ ScriptState::Scope scope(resolver->GetScriptState());
+
switch (error) {
case mojom::blink::BackgroundFetchError::NONE:
resolver->Resolve(developer_ids);
@@ -462,7 +523,9 @@ void BackgroundFetchManager::DidGetDeveloperIds(
case mojom::blink::BackgroundFetchError::DUPLICATED_DEVELOPER_ID:
case mojom::blink::BackgroundFetchError::INVALID_ARGUMENT:
case mojom::blink::BackgroundFetchError::INVALID_ID:
+ case mojom::blink::BackgroundFetchError::PERMISSION_DENIED:
case mojom::blink::BackgroundFetchError::SERVICE_WORKER_UNAVAILABLE:
+ case mojom::blink::BackgroundFetchError::QUOTA_EXCEEDED:
// Not applicable for this callback.
break;
}
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 0c543914025..ac445e7d1d0 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
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_FETCH_BACKGROUND_FETCH_MANAGER_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_FETCH_BACKGROUND_FETCH_MANAGER_H_
+#include "base/time/time.h"
#include "third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h"
@@ -77,12 +78,15 @@ class MODULES_EXPORT BackgroundFetchManager final
ScriptPromiseResolver* resolver,
const SkBitmap& icon);
void DidFetch(ScriptPromiseResolver* resolver,
+ base::Time time_started,
mojom::blink::BackgroundFetchError error,
BackgroundFetchRegistration* registration);
void DidGetRegistration(ScriptPromiseResolver* script_state,
+ base::Time time_started,
mojom::blink::BackgroundFetchError error,
BackgroundFetchRegistration* registration);
void DidGetDeveloperIds(ScriptPromiseResolver* script_state,
+ base::Time time_started,
mojom::blink::BackgroundFetchError error,
const Vector<String>& developer_ids);
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 c962f63da35..063d42f25d4 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
@@ -14,6 +14,7 @@
#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"
namespace blink {
@@ -175,4 +176,48 @@ TEST_F(BackgroundFetchManagerTest, SequenceWithNullValue) {
ESErrorType::kTypeError);
}
+TEST_F(BackgroundFetchManagerTest, BlobsExtracted) {
+ V8TestingScope scope;
+
+ KURL image_url("https://www.example.com/my_image.png");
+ KURL icon_url("https://www.example.com/my_icon.jpg");
+
+ // Create first request with a body.
+ String body_text = "cat_pic";
+ RequestInit request_init;
+ request_init.setMethod("POST");
+ request_init.setBody(blink::ScriptValue(
+ scope.GetScriptState(), ToV8(body_text, scope.GetScriptState())));
+ Request* image_request =
+ Request::Create(scope.GetScriptState(), image_url.GetString(),
+ request_init, scope.GetExceptionState());
+ ASSERT_FALSE(scope.GetExceptionState().HadException());
+ ASSERT_TRUE(image_request);
+ ASSERT_TRUE(image_request->HasBody());
+
+ // Create second request without a body.
+ RequestOrUSVString icon_request =
+ RequestOrUSVString::FromUSVString(icon_url.GetString());
+
+ // Create a request sequence with both requests.
+ HeapVector<RequestOrUSVString> request_sequence;
+ request_sequence.push_back(RequestOrUSVString::FromRequest(image_request));
+ request_sequence.push_back(icon_request);
+
+ RequestOrUSVStringOrRequestOrUSVStringSequence requests =
+ RequestOrUSVStringOrRequestOrUSVStringSequence::
+ FromRequestOrUSVStringSequence(request_sequence);
+
+ // Extract the blobs.
+ auto web_requests = CreateWebRequestVector(scope, requests);
+ ASSERT_FALSE(scope.GetExceptionState().HadException());
+
+ ASSERT_EQ(web_requests.size(), 2u);
+
+ ASSERT_TRUE(web_requests[0].GetBlobDataHandle());
+ EXPECT_EQ(web_requests[0].GetBlobDataHandle()->size(), body_text.length());
+
+ EXPECT_FALSE(web_requests[1].GetBlobDataHandle());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_options.idl b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_options.idl
index c80d491e1ce..c30c3686396 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_options.idl
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_options.idl
@@ -2,11 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// https://wicg.github.io/background-fetch/#background-fetch-manager
+// https://wicg.github.io/background-fetch/#dictdef-backgroundfetchoptions
-dictionary BackgroundFetchOptions {
- sequence<ImageResource> icons = [];
- DOMString title = "";
- [ImplementedAs=downloadTotal] unsigned long long totalDownloadSize = 0;
+dictionary BackgroundFetchOptions : BackgroundFetchUIOptions {
unsigned long long downloadTotal = 0;
};
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
new file mode 100644
index 00000000000..a7dd3a6581b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_record.cc
@@ -0,0 +1,46 @@
+// 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/background_fetch/background_fetch_record.h"
+
+#include "third_party/blink/renderer/core/fetch/request.h"
+#include "third_party/blink/renderer/core/fetch/response.h"
+
+namespace blink {
+
+BackgroundFetchRecord::BackgroundFetchRecord(Request* request,
+ Response* response)
+ : request_(request), response_(response) {
+ DCHECK(request_);
+}
+
+BackgroundFetchRecord::~BackgroundFetchRecord() = default;
+
+ScriptPromise BackgroundFetchRecord::responseReady(ScriptState* script_state) {
+ if (!response_ready_property_) {
+ response_ready_property_ =
+ new ResponseReadyProperty(ExecutionContext::From(script_state), this,
+ ResponseReadyProperty::kResponseReady);
+ }
+ if (!response_) {
+ response_ = Response::Create(ExecutionContext::From(script_state),
+ nullptr /* FetchResponseData */);
+ }
+ DCHECK(response_);
+ response_ready_property_->Resolve(response_);
+ return response_ready_property_->Promise(script_state->World());
+}
+
+Request* BackgroundFetchRecord::request() const {
+ return request_;
+}
+
+void BackgroundFetchRecord::Trace(blink::Visitor* visitor) {
+ visitor->Trace(request_);
+ visitor->Trace(response_);
+ visitor->Trace(response_ready_property_);
+ ScriptWrappable::Trace(visitor);
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..4ff0a63b6cf
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_record.h
@@ -0,0 +1,45 @@
+// 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_BACKGROUND_FETCH_BACKGROUND_FETCH_RECORD_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_FETCH_BACKGROUND_FETCH_RECORD_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/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+#include "third_party/blink/renderer/platform/heap/handle.h"
+
+namespace blink {
+
+class Request;
+class Response;
+
+class MODULES_EXPORT BackgroundFetchRecord final : public ScriptWrappable {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ explicit BackgroundFetchRecord(Request* request,
+ Response* response = nullptr);
+ ~BackgroundFetchRecord() override;
+
+ Request* request() const;
+ ScriptPromise responseReady(ScriptState* script_state);
+
+ void Trace(blink::Visitor* visitor) override;
+
+ private:
+ using ResponseReadyProperty =
+ ScriptPromiseProperty<Member<BackgroundFetchRecord>,
+ Member<Response>,
+ Member<DOMException>>;
+ Member<Request> request_;
+ Member<Response> response_;
+ Member<ResponseReadyProperty> response_ready_property_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_FETCH_BACKGROUND_FETCH_RECORD_H_
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_record.idl b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_record.idl
new file mode 100644
index 00000000000..a3e4080f498
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_record.idl
@@ -0,0 +1,13 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://wicg.github.io/background-fetch/#background-fetch-record
+
+[
+ Exposed=(ServiceWorker),
+ RuntimeEnabled=BackgroundFetch
+] interface BackgroundFetchRecord {
+ readonly attribute Request request;
+ [CallWith=ScriptState] readonly attribute Promise<Response> responseReady;
+}; \ No newline at end of file
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 15567ad0284..bf5b6d9e84c 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
@@ -4,9 +4,18 @@
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h"
+#include "base/optional.h"
+#include "third_party/blink/public/platform/modules/background_fetch/web_background_fetch_registration.h"
+#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom-blink.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"
+#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_record.h"
+#include "third_party/blink/renderer/modules/background_fetch/background_fetch_settled_fetch.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"
@@ -20,15 +29,35 @@ BackgroundFetchRegistration::BackgroundFetchRegistration(
unsigned long long upload_total,
unsigned long long uploaded,
unsigned long long download_total,
- unsigned long long downloaded)
+ unsigned long long downloaded,
+ mojom::BackgroundFetchState state,
+ mojom::BackgroundFetchFailureReason failure_reason)
: developer_id_(developer_id),
unique_id_(unique_id),
upload_total_(upload_total),
uploaded_(uploaded),
download_total_(download_total),
downloaded_(downloaded),
+ state_(state),
+ failure_reason_(failure_reason),
observer_binding_(this) {}
+BackgroundFetchRegistration::BackgroundFetchRegistration(
+ ServiceWorkerRegistration* registration,
+ const WebBackgroundFetchRegistration& web_registration)
+ : developer_id_(web_registration.developer_id),
+ unique_id_(web_registration.unique_id),
+ upload_total_(web_registration.upload_total),
+ uploaded_(web_registration.uploaded),
+ download_total_(web_registration.download_total),
+ downloaded_(web_registration.downloaded),
+ state_(web_registration.state),
+ failure_reason_(web_registration.failure_reason),
+ observer_binding_(this) {
+ DCHECK(registration);
+ Initialize(registration);
+}
+
BackgroundFetchRegistration::~BackgroundFetchRegistration() = default;
void BackgroundFetchRegistration::Initialize(
@@ -59,7 +88,7 @@ void BackgroundFetchRegistration::OnProgress(uint64_t upload_total,
return;
DCHECK(context->IsContextThread());
- DispatchEvent(Event::Create(EventTypeNames::progress));
+ DispatchEvent(*Event::Create(EventTypeNames::progress));
}
String BackgroundFetchRegistration::id() const {
@@ -104,15 +133,109 @@ ScriptPromise BackgroundFetchRegistration::abort(ScriptState* script_state) {
return promise;
}
+ScriptPromise BackgroundFetchRegistration::match(
+ ScriptState* script_state,
+ const RequestOrUSVString& request,
+ const CacheQueryOptions& options,
+ ExceptionState& exception_state) {
+ return MatchImpl(
+ script_state, base::make_optional<RequestOrUSVString>(request),
+ Cache::ToQueryParams(options), exception_state, /* match_all = */ false);
+}
+
+ScriptPromise BackgroundFetchRegistration::matchAll(
+ ScriptState* script_state,
+ ExceptionState& exception_state) {
+ return MatchImpl(script_state, /* request = */ base::nullopt,
+ /* cache_query_options = */ nullptr, exception_state,
+ /* match_all = */ true);
+}
+
+ScriptPromise BackgroundFetchRegistration::matchAll(
+ ScriptState* script_state,
+ const RequestOrUSVString& request,
+ const CacheQueryOptions& options,
+ ExceptionState& exception_state) {
+ return MatchImpl(
+ script_state, base::make_optional<RequestOrUSVString>(request),
+ Cache::ToQueryParams(options), exception_state, /* match_all = */ true);
+}
+
+ScriptPromise BackgroundFetchRegistration::MatchImpl(
+ ScriptState* script_state,
+ base::Optional<RequestOrUSVString> request,
+ mojom::blink::QueryParamsPtr cache_query_params,
+ ExceptionState& exception_state,
+ bool match_all) {
+ ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+ ScriptPromise promise = resolver->Promise();
+
+ // Convert |request| to WebServiceWorkerRequest.
+ base::Optional<WebServiceWorkerRequest> request_to_match;
+ if (request.has_value()) {
+ if (request->IsRequest()) {
+ request->GetAsRequest()->PopulateWebServiceWorkerRequest(
+ request_to_match.value());
+ } else {
+ Request* new_request = Request::Create(
+ script_state, request->GetAsUSVString(), exception_state);
+ if (exception_state.HadException())
+ return ScriptPromise();
+ new_request->PopulateWebServiceWorkerRequest(request_to_match.value());
+ }
+ }
+
+ DCHECK(registration_);
+
+ BackgroundFetchBridge::From(registration_)
+ ->MatchRequests(
+ developer_id_, unique_id_, request_to_match,
+ std::move(cache_query_params), match_all,
+ WTF::Bind(&BackgroundFetchRegistration::DidGetMatchingRequests,
+ WrapPersistent(this), WrapPersistent(resolver), match_all));
+ return promise;
+}
+
+void BackgroundFetchRegistration::DidGetMatchingRequests(
+ ScriptPromiseResolver* resolver,
+ bool return_all,
+ Vector<mojom::blink::BackgroundFetchSettledFetchPtr> settled_fetches) {
+ ScriptState* script_state = resolver->GetScriptState();
+ // Do not remove this, |scope| is needed for calling ToV8()
+ ScriptState::Scope scope(script_state);
+ HeapVector<Member<BackgroundFetchRecord>> to_return;
+ to_return.ReserveInitialCapacity(settled_fetches.size());
+ for (const auto& fetch : settled_fetches) {
+ if (fetch->response->response_type ==
+ network::mojom::FetchResponseType::kError) {
+ // Resolve with undefined.
+ resolver->Resolve();
+ return;
+ }
+ BackgroundFetchRecord* record = new BackgroundFetchRecord(
+ Request::Create(script_state, fetch->request),
+ Response::Create(script_state, *fetch->response));
+ to_return.push_back(record);
+ }
+
+ if (!return_all) {
+ DCHECK_EQ(settled_fetches.size(), 1u);
+ DCHECK_EQ(to_return.size(), 1u);
+ resolver->Resolve(to_return[0]);
+ return;
+ }
+ resolver->Resolve(to_return);
+}
+
void BackgroundFetchRegistration::DidAbort(
ScriptPromiseResolver* resolver,
mojom::blink::BackgroundFetchError error) {
switch (error) {
case mojom::blink::BackgroundFetchError::NONE:
- resolver->Resolve(true /* success */);
+ resolver->Resolve(/* success = */ true);
return;
case mojom::blink::BackgroundFetchError::INVALID_ID:
- resolver->Resolve(false /* success */);
+ resolver->Resolve(/* success = */ false);
return;
case mojom::blink::BackgroundFetchError::STORAGE_ERROR:
resolver->Reject(DOMException::Create(
@@ -122,6 +245,8 @@ void BackgroundFetchRegistration::DidAbort(
case mojom::blink::BackgroundFetchError::SERVICE_WORKER_UNAVAILABLE:
case mojom::blink::BackgroundFetchError::DUPLICATED_DEVELOPER_ID:
case mojom::blink::BackgroundFetchError::INVALID_ARGUMENT:
+ case mojom::blink::BackgroundFetchError::PERMISSION_DENIED:
+ case mojom::blink::BackgroundFetchError::QUOTA_EXCEEDED:
// Not applicable for this callback.
break;
}
@@ -129,11 +254,43 @@ void BackgroundFetchRegistration::DidAbort(
NOTREACHED();
}
+const String BackgroundFetchRegistration::state() const {
+ switch (state_) {
+ case mojom::BackgroundFetchState::SUCCESS:
+ return "success";
+ case mojom::BackgroundFetchState::FAILURE:
+ return "failure";
+ case mojom::BackgroundFetchState::PENDING:
+ return "pending";
+ }
+ NOTREACHED();
+}
+
+const String BackgroundFetchRegistration::failureReason() const {
+ switch (failure_reason_) {
+ case mojom::BackgroundFetchFailureReason::NONE:
+ return "";
+ case mojom::BackgroundFetchFailureReason::CANCELLED_FROM_UI:
+ case mojom::BackgroundFetchFailureReason::CANCELLED_BY_DEVELOPER:
+ return "aborted";
+ case mojom::BackgroundFetchFailureReason::BAD_STATUS:
+ return "bad-status";
+ case mojom::BackgroundFetchFailureReason::SERVICE_WORKER_UNAVAILABLE:
+ case mojom::BackgroundFetchFailureReason::FETCH_ERROR:
+ return "fetch-error";
+ case mojom::BackgroundFetchFailureReason::QUOTA_EXCEEDED:
+ return "quota-exceeded";
+ case mojom::BackgroundFetchFailureReason::TOTAL_DOWNLOAD_SIZE_EXCEEDED:
+ return "total-download-exceeded";
+ }
+ NOTREACHED();
+}
+
void BackgroundFetchRegistration::Dispose() {
observer_binding_.Close();
}
-void BackgroundFetchRegistration::Trace(blink::Visitor* visitor) {
+void BackgroundFetchRegistration::Trace(Visitor* visitor) {
visitor->Trace(registration_);
EventTargetWithInlineData::Trace(visitor);
}
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 9a53882be32..4d94efee4b5 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
@@ -16,9 +16,12 @@
namespace blink {
+class CacheQueryOptions;
class ScriptPromiseResolver;
class ScriptState;
class ServiceWorkerRegistration;
+class RequestOrUSVString;
+struct WebBackgroundFetchRegistration;
// Represents an individual Background Fetch registration. Gives developers
// access to its properties, options, and enables them to abort the fetch.
@@ -29,12 +32,20 @@ class BackgroundFetchRegistration final
USING_PRE_FINALIZER(BackgroundFetchRegistration, Dispose);
public:
- BackgroundFetchRegistration(const String& developer_id,
- const String& unique_id,
- unsigned long long upload_total,
- unsigned long long uploaded,
- unsigned long long download_total,
- unsigned long long downloaded);
+ BackgroundFetchRegistration(
+ const String& developer_id,
+ const String& unique_id,
+ unsigned long long upload_total,
+ unsigned long long uploaded,
+ unsigned long long download_total,
+ unsigned long long downloaded,
+ mojom::BackgroundFetchState state,
+ mojom::BackgroundFetchFailureReason failure_reason);
+
+ BackgroundFetchRegistration(
+ ServiceWorkerRegistration* registration,
+ const WebBackgroundFetchRegistration& web_registration);
+
~BackgroundFetchRegistration() override;
// Initializes the BackgroundFetchRegistration to be associated with the given
@@ -51,11 +62,25 @@ class BackgroundFetchRegistration final
// Web Exposed attribute defined in the IDL file. Corresponds to the
// |developer_id| used elsewhere in the codebase.
String id() const;
+ ScriptPromise match(ScriptState* script_state,
+ const RequestOrUSVString& request,
+ const CacheQueryOptions& options,
+ ExceptionState& exception_state);
+ ScriptPromise matchAll(ScriptState* scrip_state,
+ ExceptionState& exception_state);
+ ScriptPromise matchAll(ScriptState* script_state,
+ const RequestOrUSVString& request,
+ const CacheQueryOptions& options,
+ ExceptionState& exception_state);
unsigned long long uploadTotal() const;
unsigned long long uploaded() const;
unsigned long long downloadTotal() const;
unsigned long long downloaded() const;
+ const String state() const;
+ const String failureReason() const;
+
+ const String& unique_id() const { return unique_id_; }
DEFINE_ATTRIBUTE_EVENT_LISTENER(progress);
@@ -72,6 +97,15 @@ class BackgroundFetchRegistration final
private:
void DidAbort(ScriptPromiseResolver* resolver,
mojom::blink::BackgroundFetchError error);
+ ScriptPromise MatchImpl(ScriptState* script_state,
+ base::Optional<RequestOrUSVString> request,
+ mojom::blink::QueryParamsPtr cache_query_params,
+ ExceptionState& exception_state,
+ bool match_all);
+ void DidGetMatchingRequests(
+ ScriptPromiseResolver* resolver,
+ bool return_all,
+ Vector<mojom::blink::BackgroundFetchSettledFetchPtr> settled_fetches);
Member<ServiceWorkerRegistration> registration_;
@@ -88,6 +122,8 @@ class BackgroundFetchRegistration final
unsigned long long uploaded_;
unsigned long long download_total_;
unsigned long long downloaded_;
+ mojom::BackgroundFetchState state_;
+ mojom::BackgroundFetchFailureReason failure_reason_;
mojo::Binding<blink::mojom::blink::BackgroundFetchRegistrationObserver>
observer_binding_;
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 e7d73a6749f..bb5a4c5bbd6 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
@@ -3,6 +3,22 @@
// found in the LICENSE file.
// https://wicg.github.io/background-fetch/#background-fetch-registration
+enum BackgroundFetchState { "pending", "success", "failure" };
+
+enum BackgroundFetchFailureReason {
+ "",
+ // The operation was aborted by the user, or abort() was called.
+ "aborted",
+ // A response had a not-ok-status.
+ "bad-status",
+ // A fetch failed for other reasons, e.g. CORS, MIX, an invalid partial response,
+ // or a general network failure for a fetch that cannot be retried.
+ "fetch-error",
+ // Storage quota was reached during the operation.
+ "quota-exceeded",
+ // The provided downloadTotal was exceeded.
+ "total-download-exceeded"
+};
[
Exposed=(Window,Worker),
@@ -13,9 +29,15 @@
readonly attribute unsigned long long uploaded;
readonly attribute unsigned long long downloadTotal;
readonly attribute unsigned long long downloaded;
- // TODO(crbug.com/699957): Implement the `activeFetches` attribute.
+ readonly attribute BackgroundFetchState state;
+ readonly attribute BackgroundFetchFailureReason failureReason;
attribute EventHandler onprogress;
[CallWith=ScriptState] Promise<boolean> abort();
+
+ // TODO(crbug.com/875201): Change to (Window,Worker) once we support
+ // match() and matchAll() for active fetches.
+ [CallWith=ScriptState, Exposed=ServiceWorker, RaisesException] Promise<BackgroundFetchRecord> match(RequestInfo request, optional CacheQueryOptions options);
+ [CallWith=ScriptState, Exposed=ServiceWorker, RaisesException] Promise<sequence<BackgroundFetchRecord>> matchAll(optional RequestInfo request, optional CacheQueryOptions options);
};
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_event.cc b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_event.cc
deleted file mode 100644
index 68f65c9c871..00000000000
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_event.cc
+++ /dev/null
@@ -1,35 +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/background_fetch/background_fetch_settled_event.h"
-
-namespace blink {
-
-BackgroundFetchSettledEvent::BackgroundFetchSettledEvent(
- const AtomicString& type,
- const BackgroundFetchSettledEventInit& initializer,
- const String& unique_id,
- WaitUntilObserver* observer)
- : BackgroundFetchEvent(type, initializer, observer),
- unique_id_(unique_id),
- fetches_(*initializer.fetches()) {}
-
-BackgroundFetchSettledEvent::BackgroundFetchSettledEvent(
- const AtomicString& type,
- const BackgroundFetchSettledEventInit& initializer)
- : BackgroundFetchEvent(type, initializer, nullptr),
- fetches_(*initializer.fetches()) {}
-
-BackgroundFetchSettledEvent::~BackgroundFetchSettledEvent() = default;
-
-BackgroundFetchSettledFetches* BackgroundFetchSettledEvent::fetches() const {
- return fetches_;
-}
-
-void BackgroundFetchSettledEvent::Trace(blink::Visitor* visitor) {
- visitor->Trace(fetches_);
- BackgroundFetchEvent::Trace(visitor);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_event.h b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_event.h
deleted file mode 100644
index ec39d90d81f..00000000000
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_event.h
+++ /dev/null
@@ -1,67 +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_BACKGROUND_FETCH_BACKGROUND_FETCH_SETTLED_EVENT_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_FETCH_BACKGROUND_FETCH_SETTLED_EVENT_H_
-
-#include "third_party/blink/renderer/modules/background_fetch/background_fetch_event.h"
-#include "third_party/blink/renderer/modules/background_fetch/background_fetch_settled_event_init.h"
-#include "third_party/blink/renderer/modules/background_fetch/background_fetch_settled_fetches.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/heap/member.h"
-#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
-
-namespace blink {
-
-// Event for interacting with fetch requests that have completed.
-class MODULES_EXPORT BackgroundFetchSettledEvent : public BackgroundFetchEvent {
- DEFINE_WRAPPERTYPEINFO();
-
- public:
- static BackgroundFetchSettledEvent* Create(
- const AtomicString& type,
- const BackgroundFetchSettledEventInit& initializer) {
- return new BackgroundFetchSettledEvent(type, initializer);
- }
-
- static BackgroundFetchSettledEvent* Create(
- const AtomicString& type,
- const BackgroundFetchSettledEventInit& initializer,
- const String& unique_id,
- WaitUntilObserver* observer = nullptr) {
- return new BackgroundFetchSettledEvent(type, initializer, unique_id,
- observer);
- }
-
- ~BackgroundFetchSettledEvent() override;
-
- // Web Exposed attribute defined in the IDL file.
- BackgroundFetchSettledFetches* fetches() const;
-
- void Trace(blink::Visitor* visitor) override;
-
- protected:
- BackgroundFetchSettledEvent(
- const AtomicString& type,
- const BackgroundFetchSettledEventInit& initializer,
- const String& unique_id,
- WaitUntilObserver* observer = nullptr);
-
- BackgroundFetchSettledEvent(
- const AtomicString& type,
- const BackgroundFetchSettledEventInit& initializer);
-
- // Globally unique ID for the registration, generated in content/. Used to
- // distinguish registrations in case a developer re-uses |developer_id_|s. Not
- // exposed to JavaScript.
- String unique_id_;
-
- private:
- Member<BackgroundFetchSettledFetches> fetches_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_FETCH_BACKGROUND_FETCH_SETTLED_EVENT_H_
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_event.idl b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_event.idl
deleted file mode 100644
index cabb460b20a..00000000000
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_event.idl
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// https://wicg.github.io/background-fetch/#backgroundfetchsettledevent
-
-[
- Constructor(DOMString type, BackgroundFetchSettledEventInit init),
- Exposed=ServiceWorker,
- RuntimeEnabled=BackgroundFetch
-] interface BackgroundFetchSettledEvent : BackgroundFetchEvent {
- readonly attribute BackgroundFetchSettledFetches fetches;
-};
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_event_init.idl b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_event_init.idl
deleted file mode 100644
index d65dc5198d5..00000000000
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_event_init.idl
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// https://wicg.github.io/background-fetch/#backgroundfetchsettledevent
-
-dictionary BackgroundFetchSettledEventInit : BackgroundFetchEventInit {
- required BackgroundFetchSettledFetches fetches;
-}; \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_fetch.h b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_fetch.h
index e82979af9f9..49831fedcb0 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_fetch.h
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_fetch.h
@@ -14,8 +14,8 @@ class Request;
class Response;
// Interface for providing developers access to the Request/Response pairs when
-// a background fetch has settled, either through the `backgroundfetched` event
-// in case of success, or `backgroundfetchfail` in case of failure.
+// a background fetch has settled, either through the `backgroundfetchsuccess`
+// event in case of success, or `backgroundfetchfail` in case of failure.
class BackgroundFetchSettledFetch final : public BackgroundFetchFetch {
DEFINE_WRAPPERTYPEINFO();
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_fetches.cc b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_fetches.cc
deleted file mode 100644
index 0b8c0b22b73..00000000000
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_fetches.cc
+++ /dev/null
@@ -1,53 +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/background_fetch/background_fetch_settled_fetches.h"
-
-#include "third_party/blink/renderer/core/fetch/request.h"
-#include "third_party/blink/renderer/core/fetch/response.h"
-
-namespace blink {
-
-BackgroundFetchSettledFetches::BackgroundFetchSettledFetches(
- ScriptState* script_state,
- const WebVector<WebBackgroundFetchSettledFetch>& fetches) {
- fetches_.ReserveInitialCapacity(fetches.size());
- for (const WebBackgroundFetchSettledFetch& fetch : fetches) {
- auto* settled_fetch = BackgroundFetchSettledFetch::Create(
- Request::Create(script_state, fetch.request),
- Response::Create(script_state, fetch.response));
- fetches_.push_back(settled_fetch);
- }
-}
-
-ScriptPromise BackgroundFetchSettledFetches::match(
- ScriptState* script_state,
- const RequestOrUSVString& request) {
- for (const auto& fetch : fetches_) {
- if (request.IsNull())
- continue;
-
- String request_string = request.IsUSVString()
- ? request.GetAsUSVString()
- : request.GetAsRequest()->url().GetString();
-
- // TODO(crbug.com/824765): Update the resolve condition once behavior of
- // match is defined.
- if (request_string == fetch->request()->url())
- return ScriptPromise::Cast(script_state, ToV8(fetch, script_state));
- }
- return ScriptPromise::Cast(script_state,
- v8::Null(script_state->GetIsolate()));
-}
-
-ScriptPromise BackgroundFetchSettledFetches::values(ScriptState* script_state) {
- return ScriptPromise::Cast(script_state, ToV8(fetches_, script_state));
-}
-
-void BackgroundFetchSettledFetches::Trace(blink::Visitor* visitor) {
- visitor->Trace(fetches_);
- ScriptWrappable::Trace(visitor);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_fetches.h b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_fetches.h
deleted file mode 100644
index bc3b679fa01..00000000000
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_fetches.h
+++ /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.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_FETCH_BACKGROUND_FETCH_SETTLED_FETCHES_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_FETCH_BACKGROUND_FETCH_SETTLED_FETCHES_H_
-
-#include "third_party/blink/public/platform/modules/background_fetch/web_background_fetch_settled_fetch.h"
-#include "third_party/blink/public/platform/web_vector.h"
-#include "third_party/blink/renderer/bindings/core/v8/request_or_usv_string.h"
-#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
-#include "third_party/blink/renderer/modules/background_fetch/background_fetch_settled_fetch.h"
-#include "third_party/blink/renderer/modules/modules_export.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"
-
-namespace blink {
-
-class MODULES_EXPORT BackgroundFetchSettledFetches final
- : public ScriptWrappable {
- DEFINE_WRAPPERTYPEINFO();
-
- public:
- static BackgroundFetchSettledFetches* Create(
- ScriptState* script_state,
- const WebVector<WebBackgroundFetchSettledFetch>& fetches) {
- return new BackgroundFetchSettledFetches(script_state, fetches);
- }
-
- ~BackgroundFetchSettledFetches() override = default;
-
- // Web Exposed functions defined in the IDL file.
- ScriptPromise match(ScriptState* script_state,
- const RequestOrUSVString& request);
- ScriptPromise values(ScriptState* script_state);
-
- void Trace(blink::Visitor* visitor) override;
-
- private:
- BackgroundFetchSettledFetches(
- ScriptState* script_state,
- const WebVector<WebBackgroundFetchSettledFetch>& fetches);
-
- HeapVector<Member<BackgroundFetchSettledFetch>> fetches_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_FETCH_BACKGROUND_FETCH_SETTLED_FETCHES_H_
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_fetches.idl b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_fetches.idl
deleted file mode 100644
index adf377cf254..00000000000
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_fetches.idl
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// https://wicg.github.io/background-fetch/#backgroundfetchsettledevent
-
-[
- Exposed=ServiceWorker,
- RuntimeEnabled=BackgroundFetch
-] interface BackgroundFetchSettledFetches {
- [CallWith=ScriptState] Promise<BackgroundFetchSettledFetch> match(RequestInfo request);
- [CallWith=ScriptState] Promise<FrozenArray<BackgroundFetchSettledFetch>> values();
-};
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_fetches_test.cc b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_fetches_test.cc
deleted file mode 100644
index 03eca52773a..00000000000
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_settled_fetches_test.cc
+++ /dev/null
@@ -1,157 +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/background_fetch/background_fetch_settled_fetches.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_core.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
-#include "third_party/blink/renderer/core/fetch/request.h"
-
-namespace blink {
-
-namespace {
-
-WebVector<WebBackgroundFetchSettledFetch> CreateSettledFetches(
- const std::vector<String>& request_urls) {
- WebVector<WebBackgroundFetchSettledFetch> settled_fetches;
- settled_fetches.reserve(request_urls.size());
- for (const auto& request_url : request_urls) {
- WebBackgroundFetchSettledFetch settled_fetch;
- settled_fetch.request.SetURL(WebURL(KURL(request_url)));
- settled_fetches.emplace_back(settled_fetch);
- }
- return settled_fetches;
-}
-
-class TestScriptFunctionHandler {
- // Stats filled by the functions executed by test promises.
- struct CallStats {
- size_t num_calls = 0;
- ScriptValue value;
- };
-
- // ScriptFunction run by test promises. Extracts the resolved value.
- class TestScriptFunction : public ScriptFunction {
- public:
- static v8::Local<v8::Function> CreateFunction(ScriptState* script_state,
- CallStats* stats) {
- return (new TestScriptFunction(script_state, stats))->BindToV8Function();
- }
-
- ScriptValue Call(ScriptValue value) override {
- stats_->value = value;
- stats_->num_calls++;
- return ScriptValue();
- }
-
- private:
- TestScriptFunction(ScriptState* script_state, CallStats* stats)
- : ScriptFunction(script_state), stats_(stats) {}
- // Pointer to the private CallStats member variable in
- // TestScriptFunctionHandler. Whenever the associated function is called,
- // the CallStats variable is updated. Internal values can be accessed via
- // the public getters.
- CallStats* stats_;
- };
-
- public:
- TestScriptFunctionHandler() = default;
-
- v8::Local<v8::Function> GetFunction(ScriptState* script_state) {
- return TestScriptFunction::CreateFunction(script_state, &stats_);
- }
-
- size_t NumCalls() const { return stats_.num_calls; }
- ScriptValue Value() const { return stats_.value; }
-
- private:
- CallStats stats_;
-};
-
-ScriptValue ResolvePromise(ScriptState* script_state, ScriptPromise& promise) {
- TestScriptFunctionHandler resolved;
- TestScriptFunctionHandler rejected;
-
- promise.Then(resolved.GetFunction(script_state),
- rejected.GetFunction(script_state));
-
- v8::MicrotasksScope::PerformCheckpoint(promise.GetIsolate());
-
- EXPECT_EQ(1ul, resolved.NumCalls());
- EXPECT_EQ(0ul, rejected.NumCalls());
-
- return resolved.Value();
-}
-
-} // namespace
-
-TEST(BackgroundFetchSettledFetchesTest, MatchNullValue) {
- V8TestingScope scope;
- RequestOrUSVString null_request;
-
- auto settled_fetches = CreateSettledFetches({"foo.com"});
- auto* bgf_settled_fetches = BackgroundFetchSettledFetches::Create(
- scope.GetScriptState(), settled_fetches);
-
- ScriptPromise promise =
- bgf_settled_fetches->match(scope.GetScriptState(), null_request);
-
- ScriptValue value = ResolvePromise(scope.GetScriptState(), promise);
- EXPECT_TRUE(value.IsNull());
-}
-
-TEST(BackgroundFetchSettledFetchesTest, MatchUSVString) {
- V8TestingScope scope;
- auto matched_request = RequestOrUSVString::FromUSVString("http://foo.com/");
- auto unmatched_request = RequestOrUSVString::FromUSVString("http://bar.com/");
-
- auto settled_fetches = CreateSettledFetches(
- {"http://t1.net/", "http://foo.com/", "http://t3.net/"});
- auto* bgf_settled_fetches = BackgroundFetchSettledFetches::Create(
- scope.GetScriptState(), settled_fetches);
-
- ScriptPromise matched_promise =
- bgf_settled_fetches->match(scope.GetScriptState(), matched_request);
- ScriptPromise unmatched_promise =
- bgf_settled_fetches->match(scope.GetScriptState(), unmatched_request);
-
- ScriptValue matched_value =
- ResolvePromise(scope.GetScriptState(), matched_promise);
- EXPECT_TRUE(matched_value.IsObject());
-
- ScriptValue unmatched_value =
- ResolvePromise(scope.GetScriptState(), unmatched_promise);
- EXPECT_TRUE(unmatched_value.IsNull());
-}
-
-TEST(BackgroundFetchSettledFetchesTest, MatchRequest) {
- V8TestingScope scope;
-
- auto matched_request = RequestOrUSVString::FromRequest(Request::Create(
- scope.GetScriptState(), "http://foo.com/", scope.GetExceptionState()));
- auto unmatched_request = RequestOrUSVString::FromRequest(Request::Create(
- scope.GetScriptState(), "http://bar.com/", scope.GetExceptionState()));
-
- auto settled_fetches = CreateSettledFetches(
- {"http://t1.net/", "http://foo.com/", "http://t3.net/"});
- auto* bgf_settled_fetches = BackgroundFetchSettledFetches::Create(
- scope.GetScriptState(), settled_fetches);
-
- ScriptPromise matched_promise =
- bgf_settled_fetches->match(scope.GetScriptState(), matched_request);
- ScriptPromise unmatched_promise =
- bgf_settled_fetches->match(scope.GetScriptState(), unmatched_request);
-
- ScriptValue matched_value =
- ResolvePromise(scope.GetScriptState(), matched_promise);
- EXPECT_TRUE(matched_value.IsObject());
-
- ScriptValue unmatched_value =
- ResolvePromise(scope.GetScriptState(), unmatched_promise);
- EXPECT_TRUE(unmatched_value.IsNull());
-}
-
-} // namespace blink
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 719b38baa80..92b011daf5e 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
@@ -22,7 +22,8 @@ TypeConverter<blink::BackgroundFetchRegistration*,
return new blink::BackgroundFetchRegistration(
mojo_registration->developer_id, mojo_registration->unique_id,
mojo_registration->upload_total, mojo_registration->uploaded,
- mojo_registration->download_total, mojo_registration->downloaded);
+ mojo_registration->download_total, mojo_registration->downloaded,
+ mojo_registration->state, mojo_registration->failure_reason);
}
blink::mojom::blink::BackgroundFetchOptionsPtr TypeConverter<
@@ -42,7 +43,7 @@ blink::mojom::blink::BackgroundFetchOptionsPtr TypeConverter<
mojo_options->icons = std::move(mojo_icons);
mojo_options->download_total = options.downloadTotal();
- mojo_options->title = options.title();
+ mojo_options->title = options.hasTitle() ? options.title() : "";
return mojo_options;
}
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_ui_options.idl b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_ui_options.idl
new file mode 100644
index 00000000000..26c20e8c316
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_ui_options.idl
@@ -0,0 +1,10 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://wicg.github.io/background-fetch/#dictdef-backgroundfetchuioptions
+
+dictionary BackgroundFetchUIOptions {
+ sequence<ImageResource> icons = [];
+ DOMString? title;
+};
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_event.cc b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_event.cc
deleted file mode 100644
index c1aeb79d544..00000000000
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_event.cc
+++ /dev/null
@@ -1,85 +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/background_fetch/background_fetch_update_event.h"
-
-#include "third_party/blink/public/platform/modules/background_fetch/web_background_fetch_settled_fetch.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/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_settled_fetch.h"
-#include "third_party/blink/renderer/modules/background_fetch/background_fetched_event_init.h"
-#include "third_party/blink/renderer/modules/event_modules_names.h"
-#include "third_party/blink/renderer/platform/bindings/script_state.h"
-
-namespace blink {
-
-BackgroundFetchUpdateEvent::BackgroundFetchUpdateEvent(
- const AtomicString& type,
- const BackgroundFetchSettledEventInit& initializer)
- : BackgroundFetchSettledEvent(type, initializer) {}
-
-BackgroundFetchUpdateEvent::BackgroundFetchUpdateEvent(
- const AtomicString& type,
- const BackgroundFetchSettledEventInit& initializer,
- const String& unique_id,
- ScriptState* script_state,
- WaitUntilObserver* observer,
- ServiceWorkerRegistration* registration)
- : BackgroundFetchSettledEvent(type, initializer, unique_id, observer),
- registration_(registration) {}
-
-BackgroundFetchUpdateEvent::~BackgroundFetchUpdateEvent() = default;
-
-void BackgroundFetchUpdateEvent::Trace(blink::Visitor* visitor) {
- visitor->Trace(registration_);
- BackgroundFetchSettledEvent::Trace(visitor);
-}
-
-ScriptPromise BackgroundFetchUpdateEvent::updateUI(ScriptState* script_state,
- const String& title) {
- if (!registration_) {
- // Return a Promise that will never settle when a developer calls this
- // method on a BackgroundFetchedEvent instance they created themselves.
- return ScriptPromise();
- }
- DCHECK(!unique_id_.IsEmpty());
-
- ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
- ScriptPromise promise = resolver->Promise();
-
- BackgroundFetchBridge::From(registration_)
- ->UpdateUI(id(), unique_id_, title,
- WTF::Bind(&BackgroundFetchUpdateEvent::DidUpdateUI,
- WrapPersistent(this), WrapPersistent(resolver)));
-
- return promise;
-}
-
-void BackgroundFetchUpdateEvent::DidUpdateUI(
- ScriptPromiseResolver* resolver,
- mojom::blink::BackgroundFetchError error) {
- switch (error) {
- case mojom::blink::BackgroundFetchError::NONE:
- case mojom::blink::BackgroundFetchError::INVALID_ID:
- resolver->Resolve();
- return;
- case mojom::blink::BackgroundFetchError::STORAGE_ERROR:
- resolver->Reject(
- DOMException::Create(DOMExceptionCode::kAbortError,
- "Failed to update UI due to I/O error."));
- return;
- case mojom::blink::BackgroundFetchError::DUPLICATED_DEVELOPER_ID:
- case mojom::blink::BackgroundFetchError::INVALID_ARGUMENT:
- case mojom::blink::BackgroundFetchError::SERVICE_WORKER_UNAVAILABLE:
- // Not applicable for this callback.
- break;
- }
-
- NOTREACHED();
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_event.h b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_event.h
deleted file mode 100644
index 56832347ef2..00000000000
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_event.h
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_FETCH_BACKGROUND_FETCH_UPDATE_EVENT_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_FETCH_BACKGROUND_FETCH_UPDATE_EVENT_H_
-
-#include "third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom-blink.h"
-#include "third_party/blink/renderer/modules/background_fetch/background_fetch_settled_event.h"
-#include "third_party/blink/renderer/modules/service_worker/service_worker_registration.h"
-
-namespace blink {
-
-// Event for interacting with fetch requests that have completed.
-class MODULES_EXPORT BackgroundFetchUpdateEvent final
- : public BackgroundFetchSettledEvent {
- DEFINE_WRAPPERTYPEINFO();
-
- public:
- static BackgroundFetchUpdateEvent* Create(
- const AtomicString& type,
- const BackgroundFetchSettledEventInit& initializer) {
- return new BackgroundFetchUpdateEvent(type, initializer);
- }
-
- static BackgroundFetchUpdateEvent* Create(
- const AtomicString& type,
- const BackgroundFetchSettledEventInit& initializer,
- const String& unique_id,
- ScriptState* script_state,
- WaitUntilObserver* observer,
- ServiceWorkerRegistration* registration) {
- return new BackgroundFetchUpdateEvent(type, initializer, unique_id,
- script_state, observer, registration);
- }
-
- ~BackgroundFetchUpdateEvent() override;
-
- // Web Exposed method defined in the IDL file.
- ScriptPromise updateUI(ScriptState* script_state, const String& title);
-
- void Trace(blink::Visitor* visitor) override;
-
- private:
- BackgroundFetchUpdateEvent(
- const AtomicString& type,
- const BackgroundFetchSettledEventInit& initializer);
-
- BackgroundFetchUpdateEvent(const AtomicString& type,
- const BackgroundFetchSettledEventInit&,
- const String& unique_id,
- ScriptState* script_state,
- WaitUntilObserver* observer,
- ServiceWorkerRegistration* registration);
-
- void DidUpdateUI(ScriptPromiseResolver* resolver,
- mojom::blink::BackgroundFetchError error);
-
- Member<ServiceWorkerRegistration> registration_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_FETCH_BACKGROUND_FETCH_UPDATE_EVENT_H_
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_event.idl b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_event.idl
deleted file mode 100644
index c9c79482c09..00000000000
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_event.idl
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// https://wicg.github.io/background-fetch/#backgroundfetchupdateevent
-
-[
- Constructor(DOMString type, BackgroundFetchSettledEventInit init),
- Exposed=ServiceWorker,
- RuntimeEnabled=BackgroundFetch
-]
-interface BackgroundFetchUpdateEvent : BackgroundFetchSettledEvent {
- [CallWith=ScriptState] Promise<void> updateUI(DOMString title);
-}; \ No newline at end of file
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
new file mode 100644
index 00000000000..20080f5a5c6
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.cc
@@ -0,0 +1,124 @@
+// 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/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/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_settled_fetch.h"
+#include "third_party/blink/renderer/modules/background_fetch/background_fetch_ui_options.h"
+#include "third_party/blink/renderer/modules/event_modules_names.h"
+#include "third_party/blink/renderer/platform/bindings/script_state.h"
+
+namespace blink {
+
+BackgroundFetchUpdateUIEvent::BackgroundFetchUpdateUIEvent(
+ const AtomicString& type,
+ const BackgroundFetchEventInit& initializer)
+ : BackgroundFetchEvent(type, initializer, nullptr /* observer */) {}
+
+BackgroundFetchUpdateUIEvent::BackgroundFetchUpdateUIEvent(
+ const AtomicString& type,
+ const BackgroundFetchEventInit& initializer,
+ WaitUntilObserver* observer,
+ ServiceWorkerRegistration* registration)
+ : BackgroundFetchEvent(type, initializer, observer),
+ service_worker_registration_(registration) {}
+
+BackgroundFetchUpdateUIEvent::~BackgroundFetchUpdateUIEvent() = default;
+
+void BackgroundFetchUpdateUIEvent::Trace(blink::Visitor* visitor) {
+ visitor->Trace(service_worker_registration_);
+ visitor->Trace(loader_);
+ BackgroundFetchEvent::Trace(visitor);
+}
+
+ScriptPromise BackgroundFetchUpdateUIEvent::updateUI(
+ ScriptState* script_state,
+ const BackgroundFetchUIOptions& ui_options) {
+ if (update_ui_called_) {
+ // Return a rejected promise as this method should only be called once.
+ return ScriptPromise::Reject(
+ script_state,
+ V8ThrowException::CreateTypeError(script_state->GetIsolate(),
+ "updateUI may only be called once."));
+ }
+
+ update_ui_called_ = true;
+
+ if (!service_worker_registration_) {
+ // Return a Promise that will never settle when a developer calls this
+ // method on a BackgroundFetchSuccessEvent instance they created themselves.
+ // TODO(crbug.com/872768): Figure out if this is the right thing to do
+ // vs reacting eagerly.
+ return ScriptPromise();
+ }
+ DCHECK(!registration_->unique_id().IsEmpty());
+
+ if (!ui_options.hasTitle() && ui_options.icons().IsEmpty()) {
+ // Nothing to update, just return a resolved promise.
+ return ScriptPromise::CastUndefined(script_state);
+ }
+
+ ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+ ScriptPromise promise = resolver->Promise();
+
+ if (ui_options.icons().IsEmpty()) {
+ DidGetIcon(resolver, ui_options.title(), SkBitmap());
+ } else {
+ DCHECK(!loader_);
+ loader_ = new BackgroundFetchIconLoader();
+ DCHECK(loader_);
+ loader_->Start(BackgroundFetchBridge::From(service_worker_registration_),
+ ExecutionContext::From(script_state), ui_options.icons(),
+ WTF::Bind(&BackgroundFetchUpdateUIEvent::DidGetIcon,
+ WrapPersistent(this), WrapPersistent(resolver),
+ ui_options.title()));
+ }
+
+ return promise;
+}
+
+void BackgroundFetchUpdateUIEvent::DidGetIcon(ScriptPromiseResolver* resolver,
+ const String& title,
+ const SkBitmap& icon) {
+ BackgroundFetchBridge::From(service_worker_registration_)
+ ->UpdateUI(registration_->id(), registration_->unique_id(), title, icon,
+ WTF::Bind(&BackgroundFetchUpdateUIEvent::DidUpdateUI,
+ WrapPersistent(this), WrapPersistent(resolver)));
+}
+
+void BackgroundFetchUpdateUIEvent::DidUpdateUI(
+ ScriptPromiseResolver* resolver,
+ mojom::blink::BackgroundFetchError error) {
+ switch (error) {
+ case mojom::blink::BackgroundFetchError::NONE:
+ case mojom::blink::BackgroundFetchError::INVALID_ID:
+ resolver->Resolve();
+ return;
+ case mojom::blink::BackgroundFetchError::STORAGE_ERROR:
+ resolver->Reject(
+ DOMException::Create(DOMExceptionCode::kAbortError,
+ "Failed to update UI due to I/O error."));
+ return;
+ case mojom::blink::BackgroundFetchError::DUPLICATED_DEVELOPER_ID:
+ case mojom::blink::BackgroundFetchError::INVALID_ARGUMENT:
+ case mojom::blink::BackgroundFetchError::SERVICE_WORKER_UNAVAILABLE:
+ case mojom::blink::BackgroundFetchError::PERMISSION_DENIED:
+ case mojom::blink::BackgroundFetchError::QUOTA_EXCEEDED:
+ // Not applicable for this callback.
+ break;
+ }
+
+ NOTREACHED();
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..81d9e85d77c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.h
@@ -0,0 +1,77 @@
+// 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_BACKGROUND_FETCH_BACKGROUND_FETCH_UPDATE_UI_EVENT_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_FETCH_BACKGROUND_FETCH_UPDATE_UI_EVENT_H_
+
+#include "third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom-blink.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/modules/background_fetch/background_fetch_event.h"
+#include "third_party/blink/renderer/modules/service_worker/service_worker_registration.h"
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+
+namespace blink {
+
+class BackgroundFetchEvent;
+class BackgroundFetchIconLoader;
+class BackgroundFetchUIOptions;
+class ScriptPromiseResolver;
+class WaitUntilObserver;
+
+// Event for interacting with fetch requests that have completed.
+class MODULES_EXPORT BackgroundFetchUpdateUIEvent final
+ : public BackgroundFetchEvent {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ static BackgroundFetchUpdateUIEvent* Create(
+ const AtomicString& type,
+ const BackgroundFetchEventInit& initializer) {
+ return new BackgroundFetchUpdateUIEvent(type, initializer);
+ }
+
+ static BackgroundFetchUpdateUIEvent* Create(
+ const AtomicString& type,
+ const BackgroundFetchEventInit& initializer,
+ WaitUntilObserver* observer,
+ ServiceWorkerRegistration* registration) {
+ return new BackgroundFetchUpdateUIEvent(type, initializer, observer,
+ registration);
+ }
+
+ ~BackgroundFetchUpdateUIEvent() override;
+
+ // Web Exposed method defined in the IDL file.
+ ScriptPromise updateUI(ScriptState* script_state,
+ const BackgroundFetchUIOptions& ui_options);
+
+ void Trace(blink::Visitor* visitor) override;
+
+ private:
+ BackgroundFetchUpdateUIEvent(const AtomicString& type,
+ const BackgroundFetchEventInit& initializer);
+
+ BackgroundFetchUpdateUIEvent(const AtomicString& type,
+ const BackgroundFetchEventInit& init,
+ WaitUntilObserver* observer,
+ ServiceWorkerRegistration* registration);
+
+ void DidGetIcon(ScriptPromiseResolver* resolver,
+ const String& title,
+ const SkBitmap& icon);
+
+ void DidUpdateUI(ScriptPromiseResolver* resolver,
+ mojom::blink::BackgroundFetchError error);
+
+ bool update_ui_called_ = false;
+
+ Member<ServiceWorkerRegistration> service_worker_registration_;
+ Member<BackgroundFetchIconLoader> loader_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_FETCH_BACKGROUND_FETCH_UPDATE_UI_EVENT_H_
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
new file mode 100644
index 00000000000..b494c006376
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.idl
@@ -0,0 +1,13 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://wicg.github.io/background-fetch/#background-fetch-update-ui-event
+
+[
+ Constructor(DOMString type, BackgroundFetchEventInit init),
+ Exposed=ServiceWorker,
+ RuntimeEnabled=BackgroundFetch
+] interface BackgroundFetchUpdateUIEvent : BackgroundFetchEvent {
+ [CallWith=ScriptState] Promise<void> updateUI(BackgroundFetchUIOptions options);
+}; \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetched_event.cc b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetched_event.cc
deleted file mode 100644
index 5416bd27470..00000000000
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetched_event.cc
+++ /dev/null
@@ -1,107 +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/background_fetch/background_fetched_event.h"
-
-#include "third_party/blink/public/platform/modules/background_fetch/web_background_fetch_settled_fetch.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/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_settled_fetch.h"
-#include "third_party/blink/renderer/modules/background_fetch/background_fetched_event_init.h"
-#include "third_party/blink/renderer/modules/event_modules_names.h"
-#include "third_party/blink/renderer/platform/bindings/script_state.h"
-
-namespace blink {
-
-BackgroundFetchedEvent::BackgroundFetchedEvent(
- const AtomicString& type,
- const BackgroundFetchedEventInit& initializer)
- : BackgroundFetchEvent(type, initializer, nullptr /* observer */),
- fetches_(initializer.fetches()) {}
-
-BackgroundFetchedEvent::BackgroundFetchedEvent(
- const AtomicString& type,
- const BackgroundFetchedEventInit& initializer,
- const String& unique_id,
- const WebVector<WebBackgroundFetchSettledFetch>& fetches,
- ScriptState* script_state,
- WaitUntilObserver* observer,
- ServiceWorkerRegistration* registration)
- : BackgroundFetchEvent(type, initializer, observer),
- unique_id_(unique_id),
- registration_(registration) {
- fetches_.ReserveInitialCapacity(fetches.size());
- for (const WebBackgroundFetchSettledFetch& fetch : fetches) {
- auto* settled_fetch = BackgroundFetchSettledFetch::Create(
- Request::Create(script_state, fetch.request),
- Response::Create(script_state, fetch.response));
-
- fetches_.push_back(settled_fetch);
- }
-}
-
-BackgroundFetchedEvent::~BackgroundFetchedEvent() = default;
-
-HeapVector<Member<BackgroundFetchSettledFetch>>
-BackgroundFetchedEvent::fetches() const {
- return fetches_;
-}
-
-ScriptPromise BackgroundFetchedEvent::updateUI(ScriptState* script_state,
- const String& title) {
- if (!registration_) {
- // Return a Promise that will never settle when a developer calls this
- // method on a BackgroundFetchedEvent instance they created themselves.
- return ScriptPromise();
- }
- DCHECK(!unique_id_.IsEmpty());
-
- ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
- ScriptPromise promise = resolver->Promise();
-
- BackgroundFetchBridge::From(registration_)
- ->UpdateUI(id(), unique_id_, title,
- WTF::Bind(&BackgroundFetchedEvent::DidUpdateUI,
- WrapPersistent(this), WrapPersistent(resolver)));
-
- return promise;
-}
-
-void BackgroundFetchedEvent::DidUpdateUI(
- ScriptPromiseResolver* resolver,
- mojom::blink::BackgroundFetchError error) {
- switch (error) {
- case mojom::blink::BackgroundFetchError::NONE:
- case mojom::blink::BackgroundFetchError::INVALID_ID:
- resolver->Resolve();
- return;
- case mojom::blink::BackgroundFetchError::STORAGE_ERROR:
- resolver->Reject(
- DOMException::Create(DOMExceptionCode::kAbortError,
- "Failed to update UI due to I/O error."));
- return;
- case mojom::blink::BackgroundFetchError::SERVICE_WORKER_UNAVAILABLE:
- case mojom::blink::BackgroundFetchError::DUPLICATED_DEVELOPER_ID:
- case mojom::blink::BackgroundFetchError::INVALID_ARGUMENT:
- // Not applicable for this callback.
- break;
- }
-
- NOTREACHED();
-}
-
-const AtomicString& BackgroundFetchedEvent::InterfaceName() const {
- return EventNames::BackgroundFetchedEvent;
-}
-
-void BackgroundFetchedEvent::Trace(blink::Visitor* visitor) {
- visitor->Trace(fetches_);
- visitor->Trace(registration_);
- BackgroundFetchEvent::Trace(visitor);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetched_event.h b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetched_event.h
deleted file mode 100644
index d86e7392196..00000000000
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetched_event.h
+++ /dev/null
@@ -1,87 +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_BACKGROUND_FETCH_BACKGROUND_FETCHED_EVENT_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_FETCH_BACKGROUND_FETCHED_EVENT_H_
-
-#include "third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom-blink.h"
-#include "third_party/blink/public/platform/web_vector.h"
-#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
-#include "third_party/blink/renderer/modules/background_fetch/background_fetch_event.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/text/atomic_string.h"
-
-namespace blink {
-
-class BackgroundFetchSettledFetch;
-class BackgroundFetchedEventInit;
-class ScriptPromiseResolver;
-class ScriptState;
-class ServiceWorkerRegistration;
-struct WebBackgroundFetchSettledFetch;
-
-class MODULES_EXPORT BackgroundFetchedEvent final
- : public BackgroundFetchEvent {
- DEFINE_WRAPPERTYPEINFO();
-
- public:
- static BackgroundFetchedEvent* Create(
- const AtomicString& type,
- const BackgroundFetchedEventInit& initializer) {
- return new BackgroundFetchedEvent(type, initializer);
- }
-
- static BackgroundFetchedEvent* Create(
- const AtomicString& type,
- const BackgroundFetchedEventInit& initializer,
- const String& unique_id,
- const WebVector<WebBackgroundFetchSettledFetch>& fetches,
- ScriptState* script_state,
- WaitUntilObserver* observer,
- ServiceWorkerRegistration* registration) {
- return new BackgroundFetchedEvent(type, initializer, unique_id, fetches,
- script_state, observer, registration);
- }
-
- ~BackgroundFetchedEvent() override;
-
- // Web Exposed attribute defined in the IDL file.
- HeapVector<Member<BackgroundFetchSettledFetch>> fetches() const;
-
- // Web Exposed method defined in the IDL file.
- ScriptPromise updateUI(ScriptState* script_state, const String& title);
-
- // ExtendableEvent interface.
- const AtomicString& InterfaceName() const override;
-
- void Trace(blink::Visitor* visitor) override;
-
- private:
- BackgroundFetchedEvent(const AtomicString& type,
- const BackgroundFetchedEventInit& initializer);
- BackgroundFetchedEvent(
- const AtomicString& type,
- const BackgroundFetchedEventInit& initializer,
- const String& unique_id,
- const WebVector<WebBackgroundFetchSettledFetch>& fetches,
- ScriptState* script_state,
- WaitUntilObserver* observer,
- ServiceWorkerRegistration* registration);
-
- void DidUpdateUI(ScriptPromiseResolver* resolver,
- mojom::blink::BackgroundFetchError error);
-
- // Globally unique ID for the registration, generated in content/. Used to
- // distinguish registrations in case a developer re-uses |developer_id_|s. Not
- // exposed to JavaScript.
- String unique_id_;
-
- HeapVector<Member<BackgroundFetchSettledFetch>> fetches_;
- Member<ServiceWorkerRegistration> registration_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_FETCH_BACKGROUND_FETCHED_EVENT_H_
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetched_event.idl b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetched_event.idl
deleted file mode 100644
index 22268218e32..00000000000
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetched_event.idl
+++ /dev/null
@@ -1,15 +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.
-
-// https://wicg.github.io/background-fetch/#background-fetch-end-event
-
-[
- Constructor(DOMString type, BackgroundFetchedEventInit init),
- Exposed=ServiceWorker,
- RuntimeEnabled=BackgroundFetch
-] interface BackgroundFetchedEvent : BackgroundFetchEvent {
- readonly attribute FrozenArray<BackgroundFetchSettledFetch> fetches;
-
- [CallWith=ScriptState] Promise<void> updateUI(DOMString title);
-};
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetched_event_init.idl b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetched_event_init.idl
deleted file mode 100644
index 68d6f6841cb..00000000000
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetched_event_init.idl
+++ /dev/null
@@ -1,9 +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.
-
-// https://wicg.github.io/background-fetch/#background-fetch-end-event
-
-dictionary BackgroundFetchedEventInit : BackgroundFetchEventInit {
- required sequence<BackgroundFetchSettledFetch> fetches;
-};
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/service_worker_global_scope_background_fetch.h b/chromium/third_party/blink/renderer/modules/background_fetch/service_worker_global_scope_background_fetch.h
index 1b4588709ed..eca44d20b60 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/service_worker_global_scope_background_fetch.h
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/service_worker_global_scope_background_fetch.h
@@ -14,7 +14,7 @@ class ServiceWorkerGlobalScopeBackgroundFetch {
STATIC_ONLY(ServiceWorkerGlobalScopeBackgroundFetch);
public:
- DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(backgroundfetched);
+ DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(backgroundfetchsuccess);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(backgroundfetchfail);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(backgroundfetchabort);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(backgroundfetchclick);
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/service_worker_global_scope_background_fetch.idl b/chromium/third_party/blink/renderer/modules/background_fetch/service_worker_global_scope_background_fetch.idl
index 19322597b39..2f9f6c023e5 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/service_worker_global_scope_background_fetch.idl
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/service_worker_global_scope_background_fetch.idl
@@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// https://wicg.github.io/background-fetch/#events
+// https://wicg.github.io/background-fetch/#extensions-to-service-worker-global
[
ImplementedAs=ServiceWorkerGlobalScopeBackgroundFetch,
RuntimeEnabled=BackgroundFetch
] partial interface ServiceWorkerGlobalScope {
- attribute EventHandler onbackgroundfetched;
+ attribute EventHandler onbackgroundfetchsuccess;
attribute EventHandler onbackgroundfetchfail;
attribute EventHandler onbackgroundfetchabort;
attribute EventHandler onbackgroundfetchclick;
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 826039ea127..81f73d98547 100644
--- a/chromium/third_party/blink/renderer/modules/battery/battery_manager.cc
+++ b/chromium/third_party/blink/renderer/modules/battery/battery_manager.cc
@@ -74,13 +74,13 @@ void BatteryManager::DidUpdateData() {
return;
if (battery_status_.Charging() != old_status.Charging())
- DispatchEvent(Event::Create(EventTypeNames::chargingchange));
+ DispatchEvent(*Event::Create(EventTypeNames::chargingchange));
if (battery_status_.charging_time() != old_status.charging_time())
- DispatchEvent(Event::Create(EventTypeNames::chargingtimechange));
+ DispatchEvent(*Event::Create(EventTypeNames::chargingtimechange));
if (battery_status_.discharging_time() != old_status.discharging_time())
- DispatchEvent(Event::Create(EventTypeNames::dischargingtimechange));
+ DispatchEvent(*Event::Create(EventTypeNames::dischargingtimechange));
if (battery_status_.Level() != old_status.Level())
- DispatchEvent(Event::Create(EventTypeNames::levelchange));
+ DispatchEvent(*Event::Create(EventTypeNames::levelchange));
}
void BatteryManager::RegisterWithDispatcher() {
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 76f9ced64b6..0707a4f3a49 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_device.cc
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_device.cc
@@ -79,7 +79,7 @@ bool BluetoothDevice::IsValidDescriptor(const String& descriptor_instance_id) {
void BluetoothDevice::ClearAttributeInstanceMapAndFireEvent() {
attribute_instance_map_->Clear();
- DispatchEvent(Event::CreateBubble(EventTypeNames::gattserverdisconnected));
+ DispatchEvent(*Event::CreateBubble(EventTypeNames::gattserverdisconnected));
}
const WTF::AtomicString& BluetoothDevice::InterfaceName() const {
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 7203e783c46..af626a26b23 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
@@ -18,6 +18,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/wtf/functional.h"
#include <memory>
#include <utility>
@@ -55,7 +56,7 @@ void BluetoothRemoteGATTCharacteristic::RemoteCharacteristicValueChanged(
if (!GetGatt()->connected())
return;
this->SetValue(BluetoothRemoteGATTUtils::ConvertWTFVectorToDataView(value));
- DispatchEvent(Event::Create(EventTypeNames::characteristicvaluechanged));
+ DispatchEvent(*Event::Create(EventTypeNames::characteristicvaluechanged));
}
void BluetoothRemoteGATTCharacteristic::ContextDestroyed(ExecutionContext*) {
@@ -110,7 +111,7 @@ void BluetoothRemoteGATTCharacteristic::ReadValueCallback(
DOMDataView* dom_data_view =
BluetoothRemoteGATTUtils::ConvertWTFVectorToDataView(value.value());
SetValue(dom_data_view);
- DispatchEvent(Event::Create(EventTypeNames::characteristicvaluechanged));
+ DispatchEvent(*Event::Create(EventTypeNames::characteristicvaluechanged));
resolver->Resolve(dom_data_view);
} else {
resolver->Reject(BluetoothError::CreateDOMException(result));
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 dc208ba618e..e371e82132d 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
@@ -16,6 +16,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_uuid.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
namespace blink {
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 2a9b6c406e0..7a4a0efb5a3 100644
--- a/chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.cc
+++ b/chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.cc
@@ -96,10 +96,18 @@ void BroadcastChannel::Trace(blink::Visitor* visitor) {
void BroadcastChannel::OnMessage(BlinkCloneableMessage message) {
// Queue a task to dispatch the event.
- MessageEvent* event = MessageEvent::Create(
- nullptr, std::move(message.message),
- GetExecutionContext()->GetSecurityOrigin()->ToString());
- EnqueueEvent(event, TaskType::kInternalMedia);
+ MessageEvent* event;
+ if (!message.locked_agent_cluster_id ||
+ GetExecutionContext()->IsSameAgentCluster(
+ *message.locked_agent_cluster_id)) {
+ event = MessageEvent::Create(
+ nullptr, std::move(message.message),
+ GetExecutionContext()->GetSecurityOrigin()->ToString());
+ } else {
+ event = MessageEvent::CreateError(
+ GetExecutionContext()->GetSecurityOrigin()->ToString());
+ }
+ EnqueueEvent(*event, TaskType::kPostedMessage);
}
void BroadcastChannel::OnError() {
diff --git a/chromium/third_party/blink/renderer/modules/budget/BUILD.gn b/chromium/third_party/blink/renderer/modules/budget/BUILD.gn
deleted file mode 100644
index 7c16bbc6ed2..00000000000
--- a/chromium/third_party/blink/renderer/modules/budget/BUILD.gn
+++ /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.
-
-import("//third_party/blink/renderer/modules/modules.gni")
-
-blink_modules_sources("budget") {
- sources = [
- "budget_service.cc",
- "budget_service.h",
- "budget_state.cc",
- "budget_state.h",
- "navigator_budget.cc",
- "navigator_budget.h",
- "worker_navigator_budget.cc",
- "worker_navigator_budget.h",
- ]
-}
diff --git a/chromium/third_party/blink/renderer/modules/budget/DEPS b/chromium/third_party/blink/renderer/modules/budget/DEPS
deleted file mode 100644
index 5dbe03ed711..00000000000
--- a/chromium/third_party/blink/renderer/modules/budget/DEPS
+++ /dev/null
@@ -1,3 +0,0 @@
-include_rules = [
- "+services/service_manager/public/cpp",
-]
diff --git a/chromium/third_party/blink/renderer/modules/budget/OWNERS b/chromium/third_party/blink/renderer/modules/budget/OWNERS
deleted file mode 100644
index a45ee20e9de..00000000000
--- a/chromium/third_party/blink/renderer/modules/budget/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-peter@chromium.org
-
-# TEAM: platform-capabilities@chromium.org
-# COMPONENT: Blink>PushAPI
diff --git a/chromium/third_party/blink/renderer/modules/budget/budget_service.cc b/chromium/third_party/blink/renderer/modules/budget/budget_service.cc
deleted file mode 100644
index 97471dabb5d..00000000000
--- a/chromium/third_party/blink/renderer/modules/budget/budget_service.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/modules/budget/budget_service.h"
-
-#include "services/service_manager/public/cpp/interface_provider.h"
-#include "third_party/blink/public/platform/modules/budget_service/budget_service.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/core/dom/dom_exception.h"
-#include "third_party/blink/renderer/core/execution_context/execution_context.h"
-#include "third_party/blink/renderer/modules/budget/budget_state.h"
-#include "third_party/blink/renderer/platform/bindings/script_state.h"
-#include "third_party/blink/renderer/platform/wtf/functional.h"
-
-namespace blink {
-namespace {
-
-mojom::blink::BudgetOperationType StringToOperationType(
- const AtomicString& operation) {
- if (operation == "silent-push")
- return mojom::blink::BudgetOperationType::SILENT_PUSH;
-
- return mojom::blink::BudgetOperationType::INVALID_OPERATION;
-}
-
-DOMException* ErrorTypeToException(mojom::blink::BudgetServiceErrorType error) {
- switch (error) {
- case mojom::blink::BudgetServiceErrorType::NONE:
- return nullptr;
- case mojom::blink::BudgetServiceErrorType::DATABASE_ERROR:
- return DOMException::Create(DOMExceptionCode::kDataError,
- "Error reading the budget database.");
- case mojom::blink::BudgetServiceErrorType::NOT_SUPPORTED:
- return DOMException::Create(DOMExceptionCode::kNotSupportedError,
- "Requested opration was not supported");
- }
- NOTREACHED();
- return nullptr;
-}
-
-} // namespace
-
-BudgetService::BudgetService(
- service_manager::InterfaceProvider* interface_provider) {
- interface_provider->GetInterface(mojo::MakeRequest(&service_));
-
- // Set a connection error handler, so that if an embedder doesn't
- // implement a BudgetSerice mojo service, the developer will get a
- // actionable information.
- service_.set_connection_error_handler(
- WTF::Bind(&BudgetService::OnConnectionError, WrapWeakPersistent(this)));
-}
-
-BudgetService::~BudgetService() = default;
-
-ScriptPromise BudgetService::getCost(ScriptState* script_state,
- const AtomicString& operation) {
- DCHECK(service_);
-
- mojom::blink::BudgetOperationType type = StringToOperationType(operation);
- DCHECK_NE(type, mojom::blink::BudgetOperationType::INVALID_OPERATION);
-
- ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
- ScriptPromise promise = resolver->Promise();
-
- // Get the cost for the action from the browser BudgetService.
- service_->GetCost(type,
- WTF::Bind(&BudgetService::GotCost, WrapPersistent(this),
- WrapPersistent(resolver)));
- return promise;
-}
-
-void BudgetService::GotCost(ScriptPromiseResolver* resolver,
- double cost) const {
- resolver->Resolve(cost);
-}
-
-ScriptPromise BudgetService::getBudget(ScriptState* script_state) {
- DCHECK(service_);
-
- ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
- ScriptPromise promise = resolver->Promise();
-
- // Get the budget from the browser BudgetService.
- service_->GetBudget(WTF::Bind(&BudgetService::GotBudget, WrapPersistent(this),
- WrapPersistent(resolver)));
- return promise;
-}
-
-void BudgetService::GotBudget(
- ScriptPromiseResolver* resolver,
- mojom::blink::BudgetServiceErrorType error,
- const WTF::Vector<mojom::blink::BudgetStatePtr> expectations) const {
- if (error != mojom::blink::BudgetServiceErrorType::NONE) {
- resolver->Reject(ErrorTypeToException(error));
- return;
- }
-
- // Copy the chunks into the budget array.
- HeapVector<Member<BudgetState>> budget(expectations.size());
- for (size_t i = 0; i < expectations.size(); i++) {
- // Return the largest integer less than the budget, so it's easier for
- // developer to reason about budget. Flooring is also significant from a
- // privacy perspective, as we don't want to share precise data as it could
- // aid fingerprinting. See https://crbug.com/710809.
- budget[i] = new BudgetState(floor(expectations[i]->budget_at),
- expectations[i]->time);
- }
-
- resolver->Resolve(budget);
-}
-
-ScriptPromise BudgetService::reserve(ScriptState* script_state,
- const AtomicString& operation) {
- DCHECK(service_);
-
- mojom::blink::BudgetOperationType type = StringToOperationType(operation);
- DCHECK_NE(type, mojom::blink::BudgetOperationType::INVALID_OPERATION);
-
- ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
- ScriptPromise promise = resolver->Promise();
-
- // Call to the BudgetService to place the reservation.
- service_->Reserve(
- type, WTF::Bind(&BudgetService::GotReservation, WrapPersistent(this),
- WrapPersistent(resolver)));
- return promise;
-}
-
-void BudgetService::GotReservation(ScriptPromiseResolver* resolver,
- mojom::blink::BudgetServiceErrorType error,
- bool success) const {
- if (error != mojom::blink::BudgetServiceErrorType::NONE) {
- resolver->Reject(ErrorTypeToException(error));
- return;
- }
-
- resolver->Resolve(success);
-}
-
-void BudgetService::OnConnectionError() {
- LOG(ERROR) << "Unable to connect to the Mojo BudgetService.";
- // TODO(harkness): Reject in flight promises.
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/budget/budget_service.h b/chromium/third_party/blink/renderer/modules/budget/budget_service.h
deleted file mode 100644
index 7cdc81227c3..00000000000
--- a/chromium/third_party/blink/renderer/modules/budget/budget_service.h
+++ /dev/null
@@ -1,66 +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_BUDGET_BUDGET_SERVICE_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_BUDGET_BUDGET_SERVICE_H_
-
-#include "third_party/blink/public/platform/modules/budget_service/budget_service.mojom-blink.h"
-#include "third_party/blink/renderer/modules/modules_export.h"
-#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
-
-namespace service_manager {
-class InterfaceProvider;
-}
-
-namespace blink {
-
-class ScriptPromise;
-class ScriptPromiseResolver;
-class ScriptState;
-
-// This is the entry point into the browser for the BudgetService API, which is
-// designed to give origins the ability to perform background operations
-// on the user's behalf.
-class BudgetService final : public ScriptWrappable {
- DEFINE_WRAPPERTYPEINFO();
-
- public:
- static BudgetService* Create(
- service_manager::InterfaceProvider* interface_provider) {
- return new BudgetService(interface_provider);
- }
-
- ~BudgetService() override;
-
- // Implementation of the Budget API interface.
- ScriptPromise getCost(ScriptState* script_state,
- const AtomicString& operation);
- ScriptPromise getBudget(ScriptState* script_state);
- ScriptPromise reserve(ScriptState* script_state,
- const AtomicString& operation);
-
- private:
- // Callbacks from the BudgetService to the blink layer.
- void GotCost(ScriptPromiseResolver* resolver, double cost) const;
- void GotBudget(
- ScriptPromiseResolver* resolver,
- mojom::blink::BudgetServiceErrorType error,
- const WTF::Vector<mojom::blink::BudgetStatePtr> expectations) const;
- void GotReservation(ScriptPromiseResolver* resolver,
- mojom::blink::BudgetServiceErrorType error,
- bool success) const;
-
- // Error handler for use if mojo service doesn't connect.
- void OnConnectionError();
-
- explicit BudgetService(
- service_manager::InterfaceProvider* interface_provider);
-
- // Pointer to the Mojo service which will proxy calls to the browser.
- mojom::blink::BudgetServicePtr service_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_BUDGET_BUDGET_SERVICE_H_
diff --git a/chromium/third_party/blink/renderer/modules/budget/budget_service.idl b/chromium/third_party/blink/renderer/modules/budget/budget_service.idl
deleted file mode 100644
index 9f3e6c76199..00000000000
--- a/chromium/third_party/blink/renderer/modules/budget/budget_service.idl
+++ /dev/null
@@ -1,19 +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://wicg.github.io/budget-api/#budget-service-interface
-
-enum OperationType {
- "silent-push"
-};
-
-[
- RuntimeEnabled=Budget,
- SecureContext,
- Exposed=(Window,Worker)
-] interface BudgetService {
- [OriginTrialEnabled=BudgetQuery, CallWith=ScriptState, MeasureAs=BudgetAPIGetCost] Promise<double> getCost(OperationType operation);
- [OriginTrialEnabled=BudgetQuery, CallWith=ScriptState, MeasureAs=BudgetAPIGetBudget] Promise<sequence<BudgetState>> getBudget();
- [CallWith=ScriptState] Promise<boolean> reserve(OperationType operation);
-};
diff --git a/chromium/third_party/blink/renderer/modules/budget/budget_state.cc b/chromium/third_party/blink/renderer/modules/budget/budget_state.cc
deleted file mode 100644
index fe3f1918e81..00000000000
--- a/chromium/third_party/blink/renderer/modules/budget/budget_state.cc
+++ /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.
-
-#include "third_party/blink/renderer/modules/budget/budget_state.h"
-
-namespace blink {
-
-BudgetState::BudgetState() : budget_at_(0), time_(DOMTimeStamp()) {}
-
-BudgetState::BudgetState(double budget_at, DOMTimeStamp time)
- : budget_at_(budget_at), time_(time) {}
-
-BudgetState::BudgetState(const BudgetState& other)
- : budget_at_(other.budget_at_), time_(other.time_) {}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/budget/budget_state.h b/chromium/third_party/blink/renderer/modules/budget/budget_state.h
deleted file mode 100644
index 9c0017336d8..00000000000
--- a/chromium/third_party/blink/renderer/modules/budget/budget_state.h
+++ /dev/null
@@ -1,39 +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_BUDGET_BUDGET_STATE_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_BUDGET_BUDGET_STATE_H_
-
-#include "third_party/blink/renderer/core/dom/dom_time_stamp.h"
-#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
-#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
-
-namespace blink {
-
-class BudgetService;
-
-// This exposes the BudgetState interface which is returned from BudgetService
-// when there is a GetBudget call.
-class BudgetState final : public ScriptWrappable {
- DEFINE_WRAPPERTYPEINFO();
-
- public:
- BudgetState();
- BudgetState(double budget_at, DOMTimeStamp);
- BudgetState(const BudgetState& other);
-
- double budgetAt() const { return budget_at_; }
- DOMTimeStamp time() const { return time_; }
-
- void SetBudgetAt(const double budget_at) { budget_at_ = budget_at; }
- void SetTime(const DOMTimeStamp& time) { time_ = time; }
-
- private:
- double budget_at_;
- DOMTimeStamp time_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_BUDGET_BUDGET_STATE_H_
diff --git a/chromium/third_party/blink/renderer/modules/budget/budget_state.idl b/chromium/third_party/blink/renderer/modules/budget/budget_state.idl
deleted file mode 100644
index 41e6f4d6625..00000000000
--- a/chromium/third_party/blink/renderer/modules/budget/budget_state.idl
+++ /dev/null
@@ -1,13 +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://wicg.github.io/budget-api/#budget-state-interface
-
-[
- OriginTrialEnabled=BudgetQuery,
- Exposed=(Window,Worker)
-] interface BudgetState {
- readonly attribute double budgetAt;
- readonly attribute DOMTimeStamp time;
-};
diff --git a/chromium/third_party/blink/renderer/modules/budget/navigator_budget.cc b/chromium/third_party/blink/renderer/modules/budget/navigator_budget.cc
deleted file mode 100644
index 8eaf0bdb20c..00000000000
--- a/chromium/third_party/blink/renderer/modules/budget/navigator_budget.cc
+++ /dev/null
@@ -1,53 +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/budget/navigator_budget.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/navigator.h"
-#include "third_party/blink/renderer/modules/budget/budget_service.h"
-
-namespace blink {
-
-NavigatorBudget::NavigatorBudget(Navigator& navigator)
- : Supplement<Navigator>(navigator) {}
-
-// static
-const char NavigatorBudget::kSupplementName[] = "NavigatorBudget";
-
-// static
-NavigatorBudget& NavigatorBudget::From(Navigator& navigator) {
- // Get the unique NavigatorBudget associated with this navigator.
- NavigatorBudget* navigator_budget =
- Supplement<Navigator>::From<NavigatorBudget>(navigator);
- if (!navigator_budget) {
- // If there isn't one already, create it now and associate it.
- navigator_budget = new NavigatorBudget(navigator);
- ProvideTo(navigator, navigator_budget);
- }
- return *navigator_budget;
-}
-
-BudgetService* NavigatorBudget::budget(ExecutionContext* context) {
- if (!budget_) {
- if (auto* interface_provider = context->GetInterfaceProvider()) {
- budget_ = BudgetService::Create(interface_provider);
- }
- }
- return budget_.Get();
-}
-
-// static
-BudgetService* NavigatorBudget::budget(ExecutionContext* context,
- Navigator& navigator) {
- return NavigatorBudget::From(navigator).budget(context);
-}
-
-void NavigatorBudget::Trace(blink::Visitor* visitor) {
- visitor->Trace(budget_);
- Supplement<Navigator>::Trace(visitor);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/budget/navigator_budget.h b/chromium/third_party/blink/renderer/modules/budget/navigator_budget.h
deleted file mode 100644
index 73f68230dca..00000000000
--- a/chromium/third_party/blink/renderer/modules/budget/navigator_budget.h
+++ /dev/null
@@ -1,40 +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_BUDGET_NAVIGATOR_BUDGET_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_BUDGET_NAVIGATOR_BUDGET_H_
-
-#include "third_party/blink/renderer/core/frame/navigator.h"
-#include "third_party/blink/renderer/platform/supplementable.h"
-
-namespace blink {
-
-class BudgetService;
-class Navigator;
-
-// This exposes the budget object on the Navigator partial interface.
-class NavigatorBudget final : public GarbageCollected<NavigatorBudget>,
- public Supplement<Navigator> {
- USING_GARBAGE_COLLECTED_MIXIN(NavigatorBudget);
- WTF_MAKE_NONCOPYABLE(NavigatorBudget);
-
- public:
- static const char kSupplementName[];
-
- static NavigatorBudget& From(Navigator& navigator);
-
- static BudgetService* budget(ExecutionContext* context, Navigator& navigator);
- BudgetService* budget(ExecutionContext* context);
-
- void Trace(blink::Visitor* visitor) override;
-
- private:
- explicit NavigatorBudget(Navigator& navigator);
-
- Member<BudgetService> budget_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_BUDGET_NAVIGATOR_BUDGET_H_
diff --git a/chromium/third_party/blink/renderer/modules/budget/navigator_budget.idl b/chromium/third_party/blink/renderer/modules/budget/navigator_budget.idl
deleted file mode 100644
index 525dc1de844..00000000000
--- a/chromium/third_party/blink/renderer/modules/budget/navigator_budget.idl
+++ /dev/null
@@ -1,12 +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://wicg.github.io/budget-api/#navigator-workernavigator-extensions
-
-[
- ImplementedAs=NavigatorBudget,
- RuntimeEnabled=Budget
-] partial interface Navigator {
- [SameObject, CallWith=ExecutionContext] readonly attribute BudgetService budget;
-};
diff --git a/chromium/third_party/blink/renderer/modules/budget/worker_navigator_budget.cc b/chromium/third_party/blink/renderer/modules/budget/worker_navigator_budget.cc
deleted file mode 100644
index bfd92d2bb41..00000000000
--- a/chromium/third_party/blink/renderer/modules/budget/worker_navigator_budget.cc
+++ /dev/null
@@ -1,54 +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/budget/worker_navigator_budget.h"
-
-#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
-#include "third_party/blink/renderer/core/workers/worker_navigator.h"
-#include "third_party/blink/renderer/core/workers/worker_thread.h"
-#include "third_party/blink/renderer/modules/budget/budget_service.h"
-
-namespace blink {
-
-WorkerNavigatorBudget::WorkerNavigatorBudget(WorkerNavigator& worker_navigator)
- : Supplement<WorkerNavigator>(worker_navigator) {}
-
-// static
-const char WorkerNavigatorBudget::kSupplementName[] = "WorkerNavigatorBudget";
-
-// static
-WorkerNavigatorBudget& WorkerNavigatorBudget::From(
- WorkerNavigator& worker_navigator) {
- // Get the unique WorkerNavigatorBudget associated with this workerNavigator.
- WorkerNavigatorBudget* worker_navigator_budget =
- Supplement<WorkerNavigator>::From<WorkerNavigatorBudget>(
- worker_navigator);
- if (!worker_navigator_budget) {
- // If there isn't one already, create it now and associate it.
- worker_navigator_budget = new WorkerNavigatorBudget(worker_navigator);
- ProvideTo(worker_navigator, worker_navigator_budget);
- }
- return *worker_navigator_budget;
-}
-
-BudgetService* WorkerNavigatorBudget::budget(ExecutionContext* context) {
- if (!budget_) {
- budget_ = BudgetService::Create(context->GetInterfaceProvider());
- }
- return budget_.Get();
-}
-
-// static
-BudgetService* WorkerNavigatorBudget::budget(
- ExecutionContext* context,
- WorkerNavigator& worker_navigator) {
- return WorkerNavigatorBudget::From(worker_navigator).budget(context);
-}
-
-void WorkerNavigatorBudget::Trace(blink::Visitor* visitor) {
- visitor->Trace(budget_);
- Supplement<WorkerNavigator>::Trace(visitor);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/budget/worker_navigator_budget.h b/chromium/third_party/blink/renderer/modules/budget/worker_navigator_budget.h
deleted file mode 100644
index 994b0843599..00000000000
--- a/chromium/third_party/blink/renderer/modules/budget/worker_navigator_budget.h
+++ /dev/null
@@ -1,45 +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_BUDGET_WORKER_NAVIGATOR_BUDGET_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_BUDGET_WORKER_NAVIGATOR_BUDGET_H_
-
-#include "third_party/blink/renderer/core/workers/worker_navigator.h"
-#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
-#include "third_party/blink/renderer/platform/supplementable.h"
-#include "third_party/blink/renderer/platform/wtf/noncopyable.h"
-
-namespace blink {
-
-class BudgetService;
-class ExecutionContext;
-class WorkerNavigator;
-
-// This exposes the budget object on the WorkerNavigator partial interface.
-class WorkerNavigatorBudget final
- : public GarbageCollected<WorkerNavigatorBudget>,
- public Supplement<WorkerNavigator> {
- USING_GARBAGE_COLLECTED_MIXIN(WorkerNavigatorBudget);
- WTF_MAKE_NONCOPYABLE(WorkerNavigatorBudget);
-
- public:
- static const char kSupplementName[];
-
- static WorkerNavigatorBudget& From(WorkerNavigator& worker_navigator);
-
- static BudgetService* budget(ExecutionContext* context,
- WorkerNavigator& worker_navigator);
- BudgetService* budget(ExecutionContext* context);
-
- void Trace(blink::Visitor* visitor) override;
-
- private:
- explicit WorkerNavigatorBudget(WorkerNavigator& worker_navigator);
-
- Member<BudgetService> budget_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_BUDGET_WORKER_NAVIGATOR_BUDGET_H_
diff --git a/chromium/third_party/blink/renderer/modules/budget/worker_navigator_budget.idl b/chromium/third_party/blink/renderer/modules/budget/worker_navigator_budget.idl
deleted file mode 100644
index 8f4f2b51ee6..00000000000
--- a/chromium/third_party/blink/renderer/modules/budget/worker_navigator_budget.idl
+++ /dev/null
@@ -1,12 +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://wicg.github.io/budget-api/#navigator-workernavigator-extensions
-
-[
- ImplementedAs=WorkerNavigatorBudget,
- RuntimeEnabled=Budget
-] partial interface WorkerNavigator {
- [SameObject, CallWith=ExecutionContext] readonly attribute BudgetService budget;
-};
diff --git a/chromium/third_party/blink/renderer/modules/cache_storage/OWNERS b/chromium/third_party/blink/renderer/modules/cache_storage/OWNERS
index 896667353f4..9ba85db50d7 100644
--- a/chromium/third_party/blink/renderer/modules/cache_storage/OWNERS
+++ b/chromium/third_party/blink/renderer/modules/cache_storage/OWNERS
@@ -5,6 +5,7 @@ falken@chromium.org
horo@chromium.org
nhiroki@chromium.org
jkarlin@chromium.org
+pwnall@chromium.org
# TEAM: storage-dev@chromium.org
# COMPONENT: Blink>Storage>CacheStorage
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 e79bf5c55d4..6808dec50a9 100644
--- a/chromium/third_party/blink/renderer/modules/cache_storage/cache.cc
+++ b/chromium/third_party/blink/renderer/modules/cache_storage/cache.cc
@@ -8,6 +8,7 @@
#include <utility>
#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"
#include "third_party/blink/public/platform/modules/cache_storage/cache_storage.mojom-blink.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_response.h"
#include "third_party/blink/renderer/bindings/core/v8/callback_promise_adapter.h"
@@ -25,6 +26,7 @@
#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/use_counter.h"
#include "third_party/blink/renderer/core/html/parser/text_resource_decoder.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/modules/cache_storage/cache_storage_error.h"
@@ -90,10 +92,11 @@ class Cache::FetchResolvedForAdd final : public ScriptFunction {
static v8::Local<v8::Function> Create(
ScriptState* script_state,
Cache* cache,
+ const String& method_name,
const HeapVector<Member<Request>>& requests,
const ExceptionState& exception_state) {
- FetchResolvedForAdd* self =
- new FetchResolvedForAdd(script_state, cache, requests, exception_state);
+ FetchResolvedForAdd* self = new FetchResolvedForAdd(
+ script_state, cache, method_name, requests, exception_state);
return self->BindToV8Function();
}
@@ -130,8 +133,8 @@ class Cache::FetchResolvedForAdd final : public ScriptFunction {
for (const auto& response : responses)
RecordResponseTypeForAdd(response);
- ScriptPromise put_promise = cache_->PutImpl(GetScriptState(), requests_,
- responses, exception_state);
+ ScriptPromise put_promise = cache_->PutImpl(
+ GetScriptState(), method_name_, requests_, responses, exception_state);
return ScriptValue(GetScriptState(), put_promise.V8Value());
}
@@ -144,16 +147,19 @@ class Cache::FetchResolvedForAdd final : public ScriptFunction {
private:
FetchResolvedForAdd(ScriptState* script_state,
Cache* cache,
+ const String& method_name,
const HeapVector<Member<Request>>& requests,
const ExceptionState& exception_state)
: ScriptFunction(script_state),
cache_(cache),
+ method_name_(method_name),
requests_(requests),
context_type_(exception_state.Context()),
property_name_(exception_state.PropertyName()),
interface_name_(exception_state.InterfaceName()) {}
Member<Cache> cache_;
+ const String method_name_;
HeapVector<Member<Request>> requests_;
ExceptionState::ContextType context_type_;
const char* property_name_;
@@ -165,9 +171,11 @@ class Cache::BarrierCallbackForPut final
public:
BarrierCallbackForPut(int number_of_operations,
Cache* cache,
+ const String& method_name,
ScriptPromiseResolver* resolver)
: number_of_remaining_operations_(number_of_operations),
cache_(cache),
+ method_name_(method_name),
resolver_(resolver) {
DCHECK_LT(0, number_of_remaining_operations_);
batch_operations_.resize(number_of_operations);
@@ -184,21 +192,49 @@ class Cache::BarrierCallbackForPut final
MaybeReportInstalledScripts();
cache_->cache_ptr_->Batch(
std::move(batch_operations_),
+ RuntimeEnabledFeatures::CacheStorageAddAllRejectsDuplicatesEnabled(),
WTF::Bind(
- [](ScriptPromiseResolver* resolver, TimeTicks start_time,
- mojom::blink::CacheStorageError error) {
- if (!resolver->GetExecutionContext() ||
- resolver->GetExecutionContext()->IsContextDestroyed())
+ [](const String& method_name, ScriptPromiseResolver* resolver,
+ TimeTicks start_time,
+ mojom::blink::CacheStorageVerboseErrorPtr error) {
+ ExecutionContext* context = resolver->GetExecutionContext();
+ if (!context || context->IsContextDestroyed())
return;
- if (error == mojom::blink::CacheStorageError::kSuccess) {
- UMA_HISTOGRAM_TIMES("ServiceWorkerCache.Cache.Batch",
- TimeTicks::Now() - start_time);
+ String message;
+ if (error->message) {
+ message.append(method_name);
+ message.append(": ");
+ message.append(error->message);
+ }
+ if (error->value == mojom::blink::CacheStorageError::kSuccess) {
+ UMA_HISTOGRAM_LONG_TIMES("ServiceWorkerCache.Cache.Put",
+ TimeTicks::Now() - start_time);
resolver->Resolve();
+ if (message) {
+ context->AddConsoleMessage(ConsoleMessage::Create(
+ kJSMessageSource, kWarningMessageLevel, message));
+
+ // If the message indicates there were duplicate requests in
+ // the batch argument list, but the operation succeeded
+ // anyway, then record the UseCounter event. We use string
+ // matching on the message to avoid temporarily plumbing
+ // additional meta data through the operation result.
+ // TODO(crbug.com/877737): Remove this once the
+ // cache.addAll() duplicate rejection finally ships.
+ if (error->message.Contains(
+ blink::cache_storage::
+ kDuplicateOperationBaseMessage)) {
+ UseCounter::Count(
+ context,
+ WebFeature::kCacheStorageAddAllSuccessWithDuplicate);
+ }
+ }
} else {
- resolver->Reject(CacheStorageError::CreateException(error));
+ resolver->Reject(
+ CacheStorageError::CreateException(error->value, message));
}
},
- WrapPersistent(resolver_.Get()), TimeTicks::Now()));
+ method_name_, WrapPersistent(resolver_.Get()), TimeTicks::Now()));
}
void OnError(const String& error_message) {
@@ -267,6 +303,7 @@ class Cache::BarrierCallbackForPut final
bool completed_ = false;
int number_of_remaining_operations_;
Member<Cache> cache_;
+ const String method_name_;
Member<ScriptPromiseResolver> resolver_;
Vector<mojom::blink::BatchOperationPtr> batch_operations_;
};
@@ -456,7 +493,7 @@ ScriptPromise Cache::add(ScriptState* script_state,
return ScriptPromise();
}
- return AddAllImpl(script_state, requests, exception_state);
+ return AddAllImpl(script_state, "Cache.add()", requests, exception_state);
}
ScriptPromise Cache::addAll(ScriptState* script_state,
@@ -474,7 +511,7 @@ ScriptPromise Cache::addAll(ScriptState* script_state,
}
}
- return AddAllImpl(script_state, requests, exception_state);
+ return AddAllImpl(script_state, "Cache.addAll()", requests, exception_state);
}
ScriptPromise Cache::Delete(ScriptState* script_state,
@@ -497,7 +534,7 @@ ScriptPromise Cache::put(ScriptState* script_state,
ExceptionState& exception_state) {
DCHECK(!request.IsNull());
if (request.IsRequest()) {
- return PutImpl(script_state,
+ return PutImpl(script_state, "Cache.put()",
HeapVector<Member<Request>>(1, request.GetAsRequest()),
HeapVector<Member<Response>>(1, response), exception_state);
}
@@ -505,7 +542,8 @@ ScriptPromise Cache::put(ScriptState* script_state,
Request::Create(script_state, request.GetAsUSVString(), exception_state);
if (exception_state.HadException())
return ScriptPromise();
- return PutImpl(script_state, HeapVector<Member<Request>>(1, new_request),
+ return PutImpl(script_state, "Cache.put()",
+ HeapVector<Member<Request>>(1, new_request),
HeapVector<Member<Response>>(1, response), exception_state);
}
@@ -566,6 +604,7 @@ ScriptPromise Cache::MatchImpl(ScriptState* script_state,
web_request, ToQueryParams(options),
WTF::Bind(
[](ScriptPromiseResolver* resolver, TimeTicks start_time,
+ const CacheQueryOptions& options,
mojom::blink::MatchResultPtr result) {
if (!resolver->GetExecutionContext() ||
resolver->GetExecutionContext()->IsContextDestroyed())
@@ -581,14 +620,24 @@ ScriptPromise Cache::MatchImpl(ScriptState* script_state,
break;
}
} else {
- UMA_HISTOGRAM_TIMES("ServiceWorkerCache.Cache.Match",
- TimeTicks::Now() - start_time);
+ TimeDelta elapsed = TimeTicks::Now() - start_time;
+ UMA_HISTOGRAM_LONG_TIMES("ServiceWorkerCache.Cache.Match2",
+ elapsed);
+ if (options.hasIgnoreSearch() && options.ignoreSearch()) {
+ UMA_HISTOGRAM_LONG_TIMES(
+ "ServiceWorkerCache.Cache.Match2.IgnoreSearchEnabled",
+ elapsed);
+ } else {
+ UMA_HISTOGRAM_LONG_TIMES(
+ "ServiceWorkerCache.Cache.Match2.IgnoreSearchDisabled",
+ elapsed);
+ }
ScriptState::Scope scope(resolver->GetScriptState());
resolver->Resolve(Response::Create(resolver->GetScriptState(),
*result->get_response()));
}
},
- WrapPersistent(resolver), TimeTicks::Now()));
+ WrapPersistent(resolver), TimeTicks::Now(), options));
return promise;
}
@@ -613,6 +662,7 @@ ScriptPromise Cache::MatchAllImpl(ScriptState* script_state,
web_request, ToQueryParams(options),
WTF::Bind(
[](ScriptPromiseResolver* resolver, TimeTicks start_time,
+ const CacheQueryOptions& options,
mojom::blink::MatchAllResultPtr result) {
if (!resolver->GetExecutionContext() ||
resolver->GetExecutionContext()->IsContextDestroyed())
@@ -621,8 +671,18 @@ ScriptPromise Cache::MatchAllImpl(ScriptState* script_state,
resolver->Reject(
CacheStorageError::CreateException(result->get_status()));
} else {
- UMA_HISTOGRAM_TIMES("ServiceWorkerCache.Cache.MatchAll",
- TimeTicks::Now() - start_time);
+ TimeDelta elapsed = TimeTicks::Now() - start_time;
+ UMA_HISTOGRAM_LONG_TIMES("ServiceWorkerCache.Cache.MatchAll2",
+ elapsed);
+ if (options.hasIgnoreSearch() && options.ignoreSearch()) {
+ UMA_HISTOGRAM_LONG_TIMES(
+ "ServiceWorkerCache.Cache.MatchAll2.IgnoreSearchEnabled",
+ elapsed);
+ } else {
+ UMA_HISTOGRAM_LONG_TIMES(
+ "ServiceWorkerCache.Cache.MatchAll2.IgnoreSearchDisabled",
+ elapsed);
+ }
ScriptState::Scope scope(resolver->GetScriptState());
HeapVector<Member<Response>> responses;
responses.ReserveInitialCapacity(result->get_responses().size());
@@ -633,11 +693,12 @@ ScriptPromise Cache::MatchAllImpl(ScriptState* script_state,
resolver->Resolve(responses);
}
},
- WrapPersistent(resolver), TimeTicks::Now()));
+ WrapPersistent(resolver), TimeTicks::Now(), options));
return promise;
}
ScriptPromise Cache::AddAllImpl(ScriptState* script_state,
+ const String& method_name,
const HeapVector<Member<Request>>& requests,
ExceptionState& exception_state) {
if (requests.IsEmpty())
@@ -669,8 +730,8 @@ ScriptPromise Cache::AddAllImpl(ScriptState* script_state,
}
return ScriptPromise::All(script_state, promises)
- .Then(FetchResolvedForAdd::Create(script_state, this, requests,
- exception_state));
+ .Then(FetchResolvedForAdd::Create(script_state, this, method_name,
+ requests, exception_state));
}
ScriptPromise Cache::DeleteImpl(ScriptState* script_state,
@@ -692,39 +753,65 @@ ScriptPromise Cache::DeleteImpl(ScriptState* script_state,
cache_ptr_->Batch(
std::move(batch_operations),
+ RuntimeEnabledFeatures::CacheStorageAddAllRejectsDuplicatesEnabled(),
WTF::Bind(
[](ScriptPromiseResolver* resolver, TimeTicks start_time,
- mojom::blink::CacheStorageError error) {
- if (!resolver->GetExecutionContext() ||
- resolver->GetExecutionContext()->IsContextDestroyed())
+ const CacheQueryOptions& options,
+ mojom::blink::CacheStorageVerboseErrorPtr error) {
+ ExecutionContext* context = resolver->GetExecutionContext();
+ if (!context || context->IsContextDestroyed())
return;
- if (error != mojom::blink::CacheStorageError::kSuccess) {
- switch (error) {
+ String message;
+ if (error->message) {
+ message.append("Cache.delete(): ");
+ message.append(error->message);
+ }
+ bool report_to_console = false;
+ if (error->value != mojom::blink::CacheStorageError::kSuccess) {
+ switch (error->value) {
case mojom::blink::CacheStorageError::kErrorNotFound:
+ report_to_console = true;
resolver->Resolve(false);
break;
default:
- resolver->Reject(CacheStorageError::CreateException(error));
+ resolver->Reject(CacheStorageError::CreateException(
+ error->value, message));
break;
}
} else {
- UMA_HISTOGRAM_TIMES("ServiceWorkerCache.Cache.Batch",
- TimeTicks::Now() - start_time);
+ TimeDelta elapsed = TimeTicks::Now() - start_time;
+ UMA_HISTOGRAM_LONG_TIMES("ServiceWorkerCache.Cache.Delete",
+ elapsed);
+ if (options.hasIgnoreSearch() && options.ignoreSearch()) {
+ UMA_HISTOGRAM_LONG_TIMES(
+ "ServiceWorkerCache.Cache.Delete.IgnoreSearchEnabled",
+ elapsed);
+ } else {
+ UMA_HISTOGRAM_LONG_TIMES(
+ "ServiceWorkerCache.Cache.Delete.IgnoreSearchDisabled",
+ elapsed);
+ }
+ report_to_console = true;
resolver->Resolve(true);
}
+ if (report_to_console && message) {
+ context->AddConsoleMessage(ConsoleMessage::Create(
+ kJSMessageSource, kWarningMessageLevel, message));
+ }
},
- WrapPersistent(resolver), TimeTicks::Now()));
+ WrapPersistent(resolver), TimeTicks::Now(), options));
return promise;
}
ScriptPromise Cache::PutImpl(ScriptState* script_state,
+ const String& method_name,
const HeapVector<Member<Request>>& requests,
const HeapVector<Member<Response>>& responses,
ExceptionState& exception_state) {
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
const ScriptPromise promise = resolver->Promise();
BarrierCallbackForPut* barrier_callback =
- new BarrierCallbackForPut(requests.size(), this, resolver);
+ new BarrierCallbackForPut(requests.size(), this, method_name, resolver);
for (size_t i = 0; i < requests.size(); ++i) {
KURL url(NullURL(), requests[i]->url());
@@ -825,6 +912,7 @@ ScriptPromise Cache::KeysImpl(ScriptState* script_state,
web_request, ToQueryParams(options),
WTF::Bind(
[](ScriptPromiseResolver* resolver, TimeTicks start_time,
+ const CacheQueryOptions& options,
mojom::blink::CacheKeysResultPtr result) {
if (!resolver->GetExecutionContext() ||
resolver->GetExecutionContext()->IsContextDestroyed())
@@ -833,8 +921,18 @@ ScriptPromise Cache::KeysImpl(ScriptState* script_state,
resolver->Reject(
CacheStorageError::CreateException(result->get_status()));
} else {
- UMA_HISTOGRAM_TIMES("ServiceWorkerCache.Cache.Keys",
- TimeTicks::Now() - start_time);
+ TimeDelta elapsed = TimeTicks::Now() - start_time;
+ UMA_HISTOGRAM_LONG_TIMES("ServiceWorkerCache.Cache.Keys2",
+ elapsed);
+ if (options.hasIgnoreSearch() && options.ignoreSearch()) {
+ UMA_HISTOGRAM_TIMES(
+ "ServiceWorkerCache.Cache.Keys2.IgnoreSearchEnabled",
+ elapsed);
+ } else {
+ UMA_HISTOGRAM_TIMES(
+ "ServiceWorkerCache.Cache.Keys2.IgnoreSearchDisabled",
+ elapsed);
+ }
ScriptState::Scope scope(resolver->GetScriptState());
HeapVector<Member<Request>> requests;
requests.ReserveInitialCapacity(result->get_keys().size());
@@ -845,7 +943,7 @@ ScriptPromise Cache::KeysImpl(ScriptState* script_state,
resolver->Resolve(requests);
}
},
- WrapPersistent(resolver), TimeTicks::Now()));
+ WrapPersistent(resolver), TimeTicks::Now(), options));
return promise;
}
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 2667e9b8d6e..ed03b363274 100644
--- a/chromium/third_party/blink/renderer/modules/cache_storage/cache.h
+++ b/chromium/third_party/blink/renderer/modules/cache_storage/cache.h
@@ -82,12 +82,14 @@ class MODULES_EXPORT Cache final : public ScriptWrappable {
const Request*,
const CacheQueryOptions&);
ScriptPromise AddAllImpl(ScriptState*,
+ const String& method_name,
const HeapVector<Member<Request>>&,
ExceptionState&);
ScriptPromise DeleteImpl(ScriptState*,
const Request*,
const CacheQueryOptions&);
ScriptPromise PutImpl(ScriptState*,
+ const String& method_name,
const HeapVector<Member<Request>>&,
const HeapVector<Member<Response>>&,
ExceptionState&);
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 a7550dd7cd2..e8efc430dc8 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
@@ -179,6 +179,7 @@ ScriptPromise CacheStorage::MatchImpl(ScriptState* script_state,
web_request, Cache::ToQueryParams(options),
WTF::Bind(
[](ScriptPromiseResolver* resolver, TimeTicks start_time,
+ const CacheQueryOptions& options,
mojom::blink::MatchResultPtr result) {
if (!resolver->GetExecutionContext() ||
resolver->GetExecutionContext()->IsContextDestroyed())
@@ -196,14 +197,26 @@ ScriptPromise CacheStorage::MatchImpl(ScriptState* script_state,
break;
}
} else {
- UMA_HISTOGRAM_TIMES("ServiceWorkerCache.CacheStorage.Match",
- TimeTicks::Now() - start_time);
+ TimeDelta elapsed = TimeTicks::Now() - start_time;
+ UMA_HISTOGRAM_LONG_TIMES("ServiceWorkerCache.CacheStorage.Match2",
+ elapsed);
+ if (options.hasIgnoreSearch() && options.ignoreSearch()) {
+ UMA_HISTOGRAM_LONG_TIMES(
+ "ServiceWorkerCache.CacheStorage.Match2."
+ "IgnoreSearchEnabled",
+ elapsed);
+ } else {
+ UMA_HISTOGRAM_LONG_TIMES(
+ "ServiceWorkerCache.CacheStorage.Match2."
+ "IgnoreSearchDisabled",
+ elapsed);
+ }
ScriptState::Scope scope(resolver->GetScriptState());
resolver->Resolve(Response::Create(resolver->GetScriptState(),
*result->get_response()));
}
},
- WrapPersistent(resolver), TimeTicks::Now()));
+ WrapPersistent(resolver), TimeTicks::Now(), options));
return promise;
}
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 0cb27077dba..7ecd2d0ca81 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
@@ -10,33 +10,67 @@
namespace blink {
-DOMException* CacheStorageError::CreateException(
- mojom::CacheStorageError web_error) {
+namespace {
+
+String GetDefaultMessage(mojom::CacheStorageError web_error) {
switch (web_error) {
- case mojom::CacheStorageError::kErrorNotImplemented:
- return DOMException::Create(DOMExceptionCode::kNotSupportedError,
- "Method is not implemented.");
+ case mojom::CacheStorageError::kSuccess:
+ // This function should only be called with an error.
+ break;
+ case mojom::CacheStorageError::kErrorExists:
+ return "Entry already exists.";
+ case mojom::CacheStorageError::kErrorStorage:
+ return "Unexpected internal error.";
case mojom::CacheStorageError::kErrorNotFound:
- return DOMException::Create(DOMExceptionCode::kNotFoundError,
- "Entry was not found.");
+ return "Entry was not found.";
+ case mojom::CacheStorageError::kErrorQuotaExceeded:
+ return "Quota exceeded.";
+ case mojom::CacheStorageError::kErrorCacheNameNotFound:
+ return "Cache was not found.";
+ case mojom::CacheStorageError::kErrorQueryTooLarge:
+ return "Operation too large.";
+ case mojom::CacheStorageError::kErrorNotImplemented:
+ return "Method is not implemented.";
+ case mojom::CacheStorageError::kErrorDuplicateOperation:
+ return "Duplicate operation.";
+ }
+ NOTREACHED();
+ return String();
+}
+
+} // namespace
+
+DOMException* CacheStorageError::CreateException(
+ mojom::CacheStorageError web_error,
+ const String& message) {
+ String final_message = message ? message : GetDefaultMessage(web_error);
+ switch (web_error) {
+ case mojom::CacheStorageError::kSuccess:
+ // This function should only be called with an error.
+ break;
case mojom::CacheStorageError::kErrorExists:
return DOMException::Create(DOMExceptionCode::kInvalidAccessError,
- "Entry already exists.");
+ final_message);
+ case mojom::CacheStorageError::kErrorStorage:
+ return DOMException::Create(DOMExceptionCode::kUnknownError,
+ final_message);
+ case mojom::CacheStorageError::kErrorNotFound:
+ return DOMException::Create(DOMExceptionCode::kNotFoundError,
+ final_message);
case mojom::CacheStorageError::kErrorQuotaExceeded:
return DOMException::Create(DOMExceptionCode::kQuotaExceededError,
- "Quota exceeded.");
+ final_message);
case mojom::CacheStorageError::kErrorCacheNameNotFound:
return DOMException::Create(DOMExceptionCode::kNotFoundError,
- "Cache was not found.");
+ final_message);
case mojom::CacheStorageError::kErrorQueryTooLarge:
- return DOMException::Create(DOMExceptionCode::kAbortError,
- "Operation too large.");
- case mojom::CacheStorageError::kErrorStorage:
- return DOMException::Create(DOMExceptionCode::kUnknownError,
- "Unexpected internal error.");
- case mojom::CacheStorageError::kSuccess:
- // This function should only be called with an error.
- break;
+ return DOMException::Create(DOMExceptionCode::kAbortError, final_message);
+ case mojom::CacheStorageError::kErrorNotImplemented:
+ return DOMException::Create(DOMExceptionCode::kNotSupportedError,
+ final_message);
+ case mojom::CacheStorageError::kErrorDuplicateOperation:
+ return DOMException::Create(DOMExceptionCode::kInvalidStateError,
+ final_message);
}
NOTREACHED();
return nullptr;
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 670142ff066..515fe9de7c9 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
@@ -25,7 +25,8 @@ class CacheStorageError {
return CreateException(web_error);
}
- static DOMException* CreateException(mojom::CacheStorageError web_error);
+ static DOMException* CreateException(mojom::CacheStorageError web_error,
+ const String& message = String());
};
} // namespace blink
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 e12bd8cab32..77710ea24af 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
@@ -40,6 +40,7 @@
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
using blink::mojom::CacheStorageError;
+using blink::mojom::blink::CacheStorageVerboseError;
namespace blink {
@@ -174,10 +175,11 @@ class ErrorCacheForTests : public mojom::blink::CacheStorageCache {
std::move(callback).Run(std::move(result));
}
void Batch(Vector<mojom::blink::BatchOperationPtr> batch_operations,
+ bool fail_on_duplicates,
BatchCallback callback) override {
last_error_web_cache_method_called_ = "dispatchBatch";
CheckBatchOperationsIfProvided(batch_operations);
- std::move(callback).Run(error_);
+ std::move(callback).Run(CacheStorageVerboseError::New(error_, String()));
}
protected:
@@ -686,8 +688,10 @@ class MatchAllAndBatchTestCache : public NotImplementedErrorCache {
std::move(callback).Run(std::move(result));
}
void Batch(Vector<mojom::blink::BatchOperationPtr> batch_operations,
+ bool fail_on_duplicates,
BatchCallback callback) override {
- std::move(callback).Run(mojom::blink::CacheStorageError::kSuccess);
+ std::move(callback).Run(CacheStorageVerboseError::New(
+ mojom::blink::CacheStorageError::kSuccess, String()));
}
private:
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 7152bec8894..fac5814cd84 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
@@ -161,6 +161,8 @@ CString CacheStorageErrorString(mojom::blink::CacheStorageError error) {
return CString("operation too large.");
case mojom::blink::CacheStorageError::kErrorStorage:
return CString("storage failure.");
+ case mojom::blink::CacheStorageError::kErrorDuplicateOperation:
+ return CString("duplicate operation.");
case mojom::blink::CacheStorageError::kSuccess:
// This function should only be called upon error.
break;
@@ -554,17 +556,18 @@ void InspectorCacheStorageAgent::deleteEntry(
cache_ptr.Bind(std::move(result->get_cache()));
auto* cache = cache_ptr.get();
cache->Batch(
- std::move(batch_operations),
+ std::move(batch_operations), true /* fail_on_duplicates */,
WTF::Bind(
[](mojom::blink::CacheStorageCacheAssociatedPtr cache_ptr,
std::unique_ptr<DeleteEntryCallback> callback,
- mojom::blink::CacheStorageError error) {
- if (error !=
+ mojom::blink::CacheStorageVerboseErrorPtr error) {
+ if (error->value !=
mojom::blink::CacheStorageError::kSuccess) {
callback->sendFailure(
ProtocolResponse::Error(String::Format(
"Error deleting cache entry: %s",
- CacheStorageErrorString(error).data())));
+ CacheStorageErrorString(error->value)
+ .data())));
} else {
callback->sendSuccess();
}
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 a854c832f36..8c7e75769ee 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
@@ -168,6 +168,12 @@ bool CanvasRenderingContext2D::IsAccelerated() const {
return layer_bridge->IsAccelerated();
}
+bool CanvasRenderingContext2D::IsOriginTopLeft() const {
+ // Accelerated 2D contexts have the origin of coordinates on the bottom left,
+ // except if they are single buffered (needed for front buffer rendering).
+ return !IsAccelerated() || canvas()->ResourceProvider()->IsSingleBuffered();
+}
+
bool CanvasRenderingContext2D::IsComposited() const {
return IsAccelerated();
}
@@ -223,7 +229,7 @@ void CanvasRenderingContext2D::Trace(blink::Visitor* visitor) {
void CanvasRenderingContext2D::DispatchContextLostEvent(TimerBase*) {
if (canvas() && ContextLostRestoredEventsEnabled()) {
Event* event = Event::CreateCancelable(EventTypeNames::contextlost);
- canvas()->DispatchEvent(event);
+ canvas()->DispatchEvent(*event);
if (event->defaultPrevented()) {
context_restorable_ = false;
}
@@ -268,7 +274,7 @@ void CanvasRenderingContext2D::DispatchContextRestoredEvent(TimerBase*) {
context_lost_mode_ = kNotLostContext;
if (ContextLostRestoredEventsEnabled()) {
Event* event(Event::Create(EventTypeNames::contextrestored));
- canvas()->DispatchEvent(event);
+ canvas()->DispatchEvent(*event);
}
}
@@ -649,7 +655,7 @@ HitTestCanvasResult* CanvasRenderingContext2D::GetControlAndIdIfHitRegionExists(
FloatPoint local_pos =
box->AbsoluteToLocal(FloatPoint(location), kUseTransforms);
if (box->HasBorderOrPadding())
- local_pos.Move(-box->ContentBoxOffset());
+ local_pos.Move(-box->PhysicalContentBoxOffset());
float scaleWidth = box->ContentWidth().ToFloat() == 0.0f
? 1.0f
: canvas()->width() / box->ContentWidth();
@@ -903,9 +909,8 @@ const Font& CanvasRenderingContext2D::AccessFont() {
void CanvasRenderingContext2D::SetIsHidden(bool hidden) {
if (IsPaintable())
canvas()->GetCanvas2DLayerBridge()->SetIsHidden(hidden);
- if (hidden) {
+ if (hidden)
PruneLocalFontCache(0);
- }
}
bool CanvasRenderingContext2D::IsTransformInvertible() const {
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 093d6c344c0..ca5ab3b5dda 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
@@ -244,6 +244,7 @@ class MODULES_EXPORT CanvasRenderingContext2D final
bool Is2d() const override { return true; }
bool IsComposited() const override;
bool IsAccelerated() const override;
+ bool IsOriginTopLeft() const override;
bool HasAlpha() const override { return CreationAttributes().alpha; }
void SetIsHidden(bool) override;
void Stop() final;
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 7b1ec006673..23d92874005 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/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"
#include "third_party/blink/renderer/core/frame/settings.h"
@@ -309,7 +310,6 @@ void ResetCanvasForAccessibilityRectTest(Document& document) {
padding:10px; margin:5px;'>
<button id='button'></button></canvas>
)HTML");
- document.GetSettings()->SetAccessibilityEnabled(true);
HTMLCanvasElement* canvas =
ToHTMLCanvasElement(document.getElementById("canvas"));
@@ -324,6 +324,7 @@ void ResetCanvasForAccessibilityRectTest(Document& document) {
TEST_F(CanvasRenderingContext2DAPITest, AccessibilityRectTestForAddHitRegion) {
ResetCanvasForAccessibilityRectTest(GetDocument());
+ AXContext ax_context(GetDocument());
Element* button_element = GetDocument().getElementById("button");
HTMLCanvasElement* canvas =
@@ -353,6 +354,7 @@ TEST_F(CanvasRenderingContext2DAPITest, AccessibilityRectTestForAddHitRegion) {
TEST_F(CanvasRenderingContext2DAPITest,
AccessibilityRectTestForDrawFocusIfNeeded) {
ResetCanvasForAccessibilityRectTest(GetDocument());
+ AXContext ax_context(GetDocument());
Element* button_element = GetDocument().getElementById("button");
HTMLCanvasElement* canvas =
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 baf2fde9d3a..ff04d8d5ec3 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
@@ -327,8 +327,10 @@ sk_sp<PaintFilter> CanvasRenderingContext2DState::GetFilter(
if (!resolved_filter_) {
// Update the filter value to the proper base URL if needed.
- if (filter_value_->MayContainUrl())
+ if (filter_value_->MayContainUrl()) {
+ style_resolution_host->GetDocument().UpdateStyleAndLayout();
filter_value_->ReResolveUrl(style_resolution_host->GetDocument());
+ }
scoped_refptr<ComputedStyle> filter_style = ComputedStyle::Create();
// Must set font in case the filter uses any font-relative units (em, ex)
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 5c679f97538..896ba70a40e 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
@@ -35,7 +35,6 @@
#include "third_party/blink/renderer/platform/graphics/test/fake_web_graphics_context_3d_provider.h"
#include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
-#include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h"
#include "third_party/skia/include/core/SkColorSpaceXform.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkSurface.h"
@@ -120,16 +119,15 @@ class CanvasRenderingContext2DTest : public PageTestBase {
return CanvasElement().GetGPUMemoryUsage();
}
void DrawSomething() {
- Canvas2DLayerBridge* bridge = CanvasElement().GetCanvas2DLayerBridge();
- bridge->DidDraw(FloatRect(0, 0, 1, 1));
- bridge->FinalizeFrame();
+ CanvasElement().DidDraw();
+ CanvasElement().FinalizeFrame();
// Grabbing an image forces a flush
- bridge->NewImageSnapshot(kPreferAcceleration);
+ CanvasElement().Snapshot(kBackBuffer, kPreferAcceleration);
}
- void CreateContext(OpacityMode,
- String color_space = String(),
- LinearPixelMathState = kLinearPixelMathDisabled);
+ enum LatencyMode { kNormalLatency, kLowLatency };
+
+ void CreateContext(OpacityMode, LatencyMode = kNormalLatency);
ScriptState* GetScriptState() {
return ToScriptStateForMainWorld(canvas_element_->GetFrame());
}
@@ -185,19 +183,12 @@ CanvasRenderingContext2DTest::CanvasRenderingContext2DTest()
opaque_bitmap_(IntSize(10, 10), kOpaqueBitmap),
alpha_bitmap_(IntSize(10, 10), kTransparentBitmap) {}
-void CanvasRenderingContext2DTest::CreateContext(
- OpacityMode opacity_mode,
- String color_space,
- LinearPixelMathState LinearPixelMath_state) {
+void CanvasRenderingContext2DTest::CreateContext(OpacityMode opacity_mode,
+ LatencyMode latency_mode) {
String canvas_type("2d");
CanvasContextCreationAttributesCore attributes;
attributes.alpha = opacity_mode == kNonOpaque;
- if (!color_space.IsEmpty()) {
- attributes.color_space = color_space;
- if (LinearPixelMath_state == kLinearPixelMathEnabled) {
- attributes.pixel_format = "float16";
- }
- }
+ attributes.low_latency = latency_mode == kLowLatency;
canvas_element_->GetCanvasRenderingContext(canvas_type, attributes);
}
@@ -1116,25 +1107,17 @@ TEST_F(CanvasRenderingContext2DTest, ColorManagedPutImageDataOnP3Canvas) {
class CanvasRenderingContext2DTestWithTestingPlatform
: public CanvasRenderingContext2DTest {
protected:
+ CanvasRenderingContext2DTestWithTestingPlatform() {
+ EnablePlatform();
+ platform()->AdvanceClockSeconds(1.); // For non-zero DocumentParserTimings.
+ }
+
void SetUp() override {
- platform_ = std::make_unique<ScopedTestingPlatformSupport<
- TestingPlatformSupportWithMockScheduler>>();
- (*platform_)
- ->AdvanceClockSeconds(1.); // For non-zero DocumentParserTimings.
CanvasRenderingContext2DTest::SetUp();
GetDocument().View()->UpdateLayout();
}
- void TearDown() override {
- platform_.reset();
- CanvasRenderingContext2DTest::TearDown();
- }
-
- void RunUntilIdle() { (*platform_)->RunUntilIdle(); }
-
- std::unique_ptr<
- ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>>
- platform_;
+ void RunUntilIdle() { platform()->RunUntilIdle(); }
};
// https://crbug.com/708445: When the Canvas2DLayerBridge hibernates or wakes up
@@ -1209,4 +1192,22 @@ TEST_F(CanvasRenderingContext2DTestWithTestingPlatform,
EXPECT_FALSE(layer->NeedsCompositingInputsUpdate());
}
+TEST_F(CanvasRenderingContext2DTest, LowLatencyIsSingleBuffered) {
+ CreateContext(kNonOpaque, kLowLatency);
+ // No need to set-up the layer bridge when testing low latency mode.
+ DrawSomething();
+ auto frame1_resource =
+ CanvasElement()
+ .GetOrCreateCanvasResourceProvider(kPreferNoAcceleration)
+ ->ProduceFrame();
+ EXPECT_TRUE(!!frame1_resource);
+ DrawSomething();
+ auto frame2_resource =
+ CanvasElement()
+ .GetOrCreateCanvasResourceProvider(kPreferNoAcceleration)
+ ->ProduceFrame();
+ EXPECT_TRUE(!!frame2_resource);
+ EXPECT_EQ(frame1_resource.get(), frame2_resource.get());
+}
+
} // namespace blink
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 082758b8fa0..a0cd0e0d391 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
@@ -28,6 +28,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_PATH_2D_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_PATH_2D_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_matrix_tear_off.h"
@@ -44,11 +45,16 @@ class MODULES_EXPORT Path2D final : public ScriptWrappable, public CanvasPath {
WTF_MAKE_NONCOPYABLE(Path2D);
public:
- static Path2D* Create() { return new Path2D; }
- static Path2D* Create(const String& path_data) {
- return new Path2D(path_data);
+ static Path2D* Create(Path2DOrString pathorstring) {
+ DCHECK(!pathorstring.IsNull());
+ if (pathorstring.IsPath2D())
+ return new Path2D(pathorstring.GetAsPath2D());
+ if (pathorstring.IsString())
+ return new Path2D(pathorstring.GetAsString());
+ NOTREACHED();
+ return nullptr;
}
- static Path2D* Create(Path2D* path) { return new Path2D(path); }
+ static Path2D* Create() { return new Path2D; }
static Path2D* Create(const Path& path) { return new Path2D(path); }
const Path& GetPath() const { return path_; }
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 047b0201aa7..44642f2ca57 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,9 +29,7 @@
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#path2d
[
- Constructor,
- Constructor(Path2D path),
- Constructor(DOMString text),
+ Constructor(optional (Path2D or DOMString) path),
Exposed(Worker OffscreenCanvas, Window StableBlinkFeatures, PaintWorklet StableBlinkFeatures)
] interface Path2D {
diff --git a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/OffscreenCanvas-commit.md b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/OffscreenCanvas-commit.md
index 8995bba6417..dba5c99e60e 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/OffscreenCanvas-commit.md
+++ b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/OffscreenCanvas-commit.md
@@ -192,8 +192,8 @@ placeholder canvas.
The image resources of OffscreenCanvas’s 2d rendering context are centrally
managed by a CanvasResourceProvider instance. CanvasResourceProvider is an
abstract class that encapsulates a drawable graphics resources and its
-implementations could be managing different specific resource types, ranging
-from Gpu textures, Gpu memory buffer, to shared bitmap in RAM. When `commit()`
+implementations and could be managing different specific resource types, ranging
+from Gpu textures, Gpu Memory Buffers, to shared bitmap in RAM. When `commit()`
is invoked by the user, an image snapshot would be taken from the SkSurface
managed by the CanvasResourceProvider; the SkSurface can be on Gpu context (see
SkSurface::MakeRenderTarget()) or on RAM memory (see SkSurface::MakeRaster()).
@@ -218,10 +218,9 @@ handled by a release callback. This release callback is saved in the
DrawingBuffer instance and is swapped only when a new `commit()` is coming or
the DrawingBuffer is destructed; when the swapping happens, the previously
saved callback will be run, releasing the ColorBuffer that holds up the GPU
-memory resource (see DrawingBuffer::SwapPreviousFrameCallback()) . This
-release mechanism is not consistent with the rest of canvas resource; ideally,
-everything should be kept under CanvasResourceProvider; this might be a future
-to-do item.
+memory resource. This release mechanism is not consistent with the rest of
+canvas resource; ideally, everything should be kept under
+CanvasResourceProvider; this might be a future to-do item.
## Preparing the CompositorFrame
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 6c64e148dc0..9dc633c5e85 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
@@ -127,7 +127,7 @@ base::Optional<WebCanonicalCookie> ToWebCanonicalCookie(
return WebCanonicalCookie::Create(
name, value, domain, options.path(), WTF::Time() /*creation*/, expires,
- WTF::Time() /*last_access*/, secure, options.httpOnly(), same_site,
+ WTF::Time() /*last_access*/, secure, false /*http_only*/, same_site,
WebCanonicalCookie::kDefaultPriority);
}
@@ -273,7 +273,6 @@ ScriptPromise CookieStore::set(ScriptState* script_state,
set_options.setDomain(options.domain());
set_options.setPath(options.path());
set_options.setSecure(options.secure());
- set_options.setHttpOnly(options.httpOnly());
set_options.setSameSite(options.sameSite());
return set(script_state, set_options, exception_state);
}
@@ -309,8 +308,8 @@ ScriptPromise CookieStore::Delete(ScriptState* script_state,
set_options.setExpires(0);
set_options.setDomain(options.domain());
set_options.setPath(options.path());
- set_options.setSecure(options.secure());
- set_options.setSameSite(options.sameSite());
+ set_options.setSecure(true);
+ set_options.setSameSite("strict");
return DoWrite(script_state, set_options, exception_state);
}
@@ -416,7 +415,7 @@ void CookieStore::OnCookieChange(
// The backend only reported OVERWRITE events, which are dropped.
return;
}
- DispatchEvent(CookieChangeEvent::Create(
+ DispatchEvent(*CookieChangeEvent::Create(
EventTypeNames::change, std::move(changed), std::move(deleted)));
}
diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_delete_options.idl b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_delete_options.idl
index e17292e3a14..d3b03cbf627 100644
--- a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_delete_options.idl
+++ b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_delete_options.idl
@@ -8,6 +8,4 @@ dictionary CookieStoreDeleteOptions {
required USVString name;
USVString? domain = null;
USVString path = "/";
- boolean secure = true;
- CookieSameSite sameSite = "strict";
};
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 2cde6845880..4a01a9fa6a3 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
@@ -15,6 +15,5 @@ dictionary CookieStoreSetOptions {
USVString? domain = null;
USVString path = "/";
boolean secure = true;
- boolean httpOnly = false;
CookieSameSite sameSite = "strict";
};
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 11ea9bfd54a..5d9c7b68b00 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
@@ -6,7 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_CREDENTIALMANAGER_CREDENTIAL_MANAGER_PROXY_H_
#include "third_party/blink/public/platform/modules/credentialmanager/credential_manager.mojom-blink.h"
-#include "third_party/blink/public/platform/modules/webauth/authenticator.mojom-blink.h"
+#include "third_party/blink/public/platform/modules/webauthn/authenticator.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"
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 b12f9dda52a..54615eef0ef 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
@@ -202,6 +202,10 @@ AuthenticatorTransport TypeConverter<AuthenticatorTransport, String>::Convert(
return AuthenticatorTransport::NFC;
if (transport == "ble")
return AuthenticatorTransport::BLE;
+ if (transport == "cable")
+ return AuthenticatorTransport::CABLE;
+ if (transport == "internal")
+ return AuthenticatorTransport::INTERNAL;
NOTREACHED();
return AuthenticatorTransport::USB;
}
@@ -309,6 +313,11 @@ TypeConverter<PublicKeyCredentialDescriptorPtr,
mojo_descriptor->transports.push_back(
ConvertTo<AuthenticatorTransport>(transport));
}
+ } else {
+ mojo_descriptor->transports = {
+ AuthenticatorTransport::USB, AuthenticatorTransport::BLE,
+ AuthenticatorTransport::NFC, AuthenticatorTransport::CABLE,
+ AuthenticatorTransport::INTERNAL};
}
return mojo_descriptor;
}
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.h b/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.h
index 44769ec78ef..987e102a7ad 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.h
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.h
@@ -6,7 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_CREDENTIALMANAGER_CREDENTIAL_MANAGER_TYPE_CONVERTERS_H_
#include "third_party/blink/public/platform/modules/credentialmanager/credential_manager.mojom-blink.h"
-#include "third_party/blink/public/platform/modules/webauth/authenticator.mojom-blink.h"
+#include "third_party/blink/public/platform/modules/webauthn/authenticator.mojom-blink.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/credentialmanager/credentials_container.cc b/chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc
index c67b013a996..863f1fd71b0 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc
@@ -154,8 +154,9 @@ bool CheckPublicKeySecurityRequirements(ScriptPromiseResolver* resolver,
// TODO(crbug.com/803077): Avoid constructing an OriginAccessEntry just
// for the IP address check.
- OriginAccessEntry access_entry(origin->Protocol(), effective_domain,
- blink::OriginAccessEntry::kAllowSubdomains);
+ OriginAccessEntry access_entry(
+ origin->Protocol(), effective_domain,
+ network::cors::OriginAccessEntry::MatchMode::kAllowSubdomains);
if (effective_domain.IsEmpty() || access_entry.HostIsIPAddress()) {
resolver->Reject(
DOMException::Create(DOMExceptionCode::kSecurityError,
@@ -167,11 +168,12 @@ bool CheckPublicKeySecurityRequirements(ScriptPromiseResolver* resolver,
// https://w3c.github.io/webauthn/#CreateCred-DetermineRpId and
// https://w3c.github.io/webauthn/#GetAssn-DetermineRpId.
if (!relying_party_id.IsNull()) {
- OriginAccessEntry access_entry(origin->Protocol(), relying_party_id,
- blink::OriginAccessEntry::kAllowSubdomains);
+ OriginAccessEntry access_entry(
+ origin->Protocol(), relying_party_id,
+ network::cors::OriginAccessEntry::kAllowSubdomains);
if (relying_party_id.IsEmpty() ||
access_entry.MatchesDomain(*origin) !=
- blink::OriginAccessEntry::kMatchesOrigin) {
+ network::cors::OriginAccessEntry::kMatchesOrigin) {
resolver->Reject(DOMException::Create(
DOMExceptionCode::kSecurityError,
"The relying party ID '" + relying_party_id +
@@ -378,7 +380,9 @@ void OnGetAssertionComplete(
authenticator_buffer,
signature_buffer, user_handle);
AuthenticationExtensionsClientOutputs extension_outputs;
- extension_outputs.setAppid(credential->echo_appid_extension);
+ if (credential->echo_appid_extension) {
+ extension_outputs.setAppid(credential->appid_extension);
+ }
resolver->Resolve(PublicKeyCredential::Create(credential->info->id, raw_id,
authenticator_response,
extension_outputs));
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 42eb8035c98..2e8d07119b7 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
@@ -17,6 +17,7 @@
#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_frame.h"
+#include "third_party/blink/renderer/core/testing/gc_object_liveness_observer.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/platform/testing/unit_test_helpers.h"
@@ -121,11 +122,11 @@ class CredentialManagerTestingContext {
// document is destored while a call is pending, it can still be freed up.
TEST(CredentialsContainerTest, PendingGetRequest_NoGCCycles) {
MockCredentialManager mock_credential_manager;
- WeakPersistent<Document> weak_document;
+ GCObjectLivenessObserver<Document> document_observer;
{
CredentialManagerTestingContext context(&mock_credential_manager);
- weak_document = context.GetDocument();
+ document_observer.Observe(context.GetDocument());
CredentialsContainer::Create()->get(context.GetScriptState(),
CredentialRequestOptions());
mock_credential_manager.WaitForCallToGet();
@@ -134,7 +135,7 @@ TEST(CredentialsContainerTest, PendingGetRequest_NoGCCycles) {
V8GCController::CollectAllGarbageForTesting(v8::Isolate::GetCurrent());
ThreadState::Current()->CollectAllGarbage();
- ASSERT_EQ(nullptr, weak_document.Get());
+ ASSERT_TRUE(document_observer.WasCollected());
mock_credential_manager.InvokeGetCallback();
mock_credential_manager.WaitForConnectionError();
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/public_key_credential_descriptor.idl b/chromium/third_party/blink/renderer/modules/credentialmanager/public_key_credential_descriptor.idl
index fcd20a069a5..99b03e230fa 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/public_key_credential_descriptor.idl
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/public_key_credential_descriptor.idl
@@ -7,7 +7,9 @@
enum AuthenticatorTransport {
"usb",
"nfc",
- "ble"
+ "ble",
+ "cable",
+ "internal"
};
// https://w3c.github.io/webauthn/#dictdef-publickeycredentialdescriptor
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 1649646bc71..09be5881be2 100644
--- a/chromium/third_party/blink/renderer/modules/crypto/normalize_algorithm.h
+++ b/chromium/third_party/blink/renderer/modules/crypto/normalize_algorithm.h
@@ -45,6 +45,8 @@ namespace blink {
struct AlgorithmError {
STACK_ALLOCATED();
+
+ public:
WebCryptoErrorType error_type;
WebString error_details;
};
diff --git a/chromium/third_party/blink/renderer/modules/csspaint/OWNERS b/chromium/third_party/blink/renderer/modules/csspaint/OWNERS
index 2f8630d2964..b9770dac9db 100644
--- a/chromium/third_party/blink/renderer/modules/csspaint/OWNERS
+++ b/chromium/third_party/blink/renderer/modules/csspaint/OWNERS
@@ -1,6 +1,5 @@
flackr@chromium.org
ikilpatrick@chromium.org
-junov@chromium.org
xidachen@chromium.org
# TEAM: style-dev@chromium.org
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 5f12f8a56aa..69116afaa98 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
@@ -98,10 +98,11 @@ PaintWorkletGlobalScope* PaintWorkletGlobalScope::Create(
reporting_proxy, pending_generator_registry);
String context_name("PaintWorklet #");
context_name.append(String::Number(global_scope_number));
- global_scope->ScriptController()->InitializeContextIfNeeded(context_name);
+ global_scope->ScriptController()->InitializeContextIfNeeded(context_name,
+ NullURL());
MainThreadDebugger::Instance()->ContextCreated(
global_scope->ScriptController()->GetScriptState(),
- global_scope->GetFrame(), global_scope->GetSecurityOrigin());
+ global_scope->GetFrame(), global_scope->DocumentSecurityOrigin());
return global_scope;
}
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 cef58d789db..fa669fad094 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,5 +9,7 @@
Global=(Worklet,PaintWorklet)
] interface PaintWorkletGlobalScope : WorkletGlobalScope {
[Measure] readonly attribute unrestricted double devicePixelRatio;
- [Measure, RaisesException] void registerPaint(DOMString name, Function paintCtor);
+ // TODO(yukishiino): |paintCtor| should be of callback function type
+ // (should be: callback T = any ()).
+ [Measure, RaisesException] void registerPaint(DOMString name, CallbackFunctionTreatedAsScriptValue paintCtor);
};
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 7ded3e21f87..c3da5aac23f 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
@@ -45,8 +45,8 @@ PaintWorkletGlobalScopeProxy::PaintWorkletGlobalScopeProxy(
document->Url(), ScriptType::kModule, document->UserAgent(),
document->GetContentSecurityPolicy()->Headers(),
document->GetReferrerPolicy(), document->GetSecurityOrigin(),
- document->IsSecureContext(), worker_clients, document->AddressSpace(),
- OriginTrialContext::GetTokens(document).get(),
+ document->IsSecureContext(), document->GetHttpsState(), worker_clients,
+ document->AddressSpace(), OriginTrialContext::GetTokens(document).get(),
base::UnguessableToken::Create(), nullptr /* worker_settings */,
kV8CacheOptionsDefault, module_responses_map);
global_scope_ = PaintWorkletGlobalScope::Create(
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 399ac3e87e6..89112176e96 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/BUILD.gn
@@ -12,8 +12,6 @@ blink_modules_sources("device_orientation") {
"device_motion_controller.h",
"device_motion_data.cc",
"device_motion_data.h",
- "device_motion_dispatcher.cc",
- "device_motion_dispatcher.h",
"device_motion_event.cc",
"device_motion_event.h",
"device_motion_event_pump.cc",
@@ -24,8 +22,6 @@ blink_modules_sources("device_orientation") {
"device_orientation_controller.h",
"device_orientation_data.cc",
"device_orientation_data.h",
- "device_orientation_dispatcher.cc",
- "device_orientation_dispatcher.h",
"device_orientation_event.cc",
"device_orientation_event.h",
"device_orientation_event_pump.cc",
@@ -38,8 +34,4 @@ blink_modules_sources("device_orientation") {
"dom_window_device_motion.h",
"dom_window_device_orientation.h",
]
-
- deps = [
- "//services/device/public/cpp/generic_sensor:shared_with_blink",
- ]
}
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/DEPS b/chromium/third_party/blink/renderer/modules/device_orientation/DEPS
index 71a097e78ee..7c1b789abcd 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/DEPS
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/DEPS
@@ -1,11 +1,6 @@
include_rules = [
"+base/run_loop.h",
"+mojo/public/cpp/bindings/binding.h",
-
- # NOTE: These files are POD structs used to interpret shared memory across
- # the Device Sensors implementation and the Blink client.
- "+services/device/public/cpp/generic_sensor/orientation_data.h",
-
"+services/device/public/mojom/sensor.mojom-blink.h",
"+services/device/public/mojom/sensor_provider.mojom-blink.h",
"+services/device/public/cpp/test/fake_sensor_and_provider.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 f1f4dbf278d..01c1ade0c72 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
@@ -10,8 +10,8 @@
#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_dispatcher.h"
#include "third_party/blink/renderer/modules/device_orientation/device_motion_event.h"
+#include "third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.h"
#include "third_party/blink/renderer/modules/device_orientation/device_orientation_controller.h"
#include "third_party/blink/renderer/modules/event_modules.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
@@ -78,21 +78,33 @@ void DeviceMotionController::DidAddEventListener(
}
bool DeviceMotionController::HasLastData() {
- return DeviceMotionDispatcher::Instance().LatestDeviceMotionData();
+ return motion_event_pump_
+ ? motion_event_pump_->LatestDeviceMotionData() != nullptr
+ : false;
}
void DeviceMotionController::RegisterWithDispatcher() {
- DeviceMotionDispatcher::Instance().AddController(this);
+ if (!motion_event_pump_) {
+ LocalFrame* frame = GetDocument().GetFrame();
+ if (!frame)
+ return;
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner =
+ frame->GetTaskRunner(TaskType::kSensor);
+ motion_event_pump_ = new DeviceMotionEventPump(task_runner);
+ }
+ motion_event_pump_->AddController(this);
}
void DeviceMotionController::UnregisterWithDispatcher() {
- DeviceMotionDispatcher::Instance().RemoveController(this);
+ if (motion_event_pump_)
+ motion_event_pump_->RemoveController(this);
}
Event* DeviceMotionController::LastEvent() const {
return DeviceMotionEvent::Create(
EventTypeNames::devicemotion,
- DeviceMotionDispatcher::Instance().LatestDeviceMotionData());
+ motion_event_pump_ ? motion_event_pump_->LatestDeviceMotionData()
+ : nullptr);
}
bool DeviceMotionController::IsNullEvent(Event* event) const {
@@ -106,6 +118,7 @@ const AtomicString& DeviceMotionController::EventTypeName() const {
void DeviceMotionController::Trace(blink::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 107bb0d4c2f..e8b62cca1e1 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
@@ -12,6 +12,7 @@
namespace blink {
class Event;
+class DeviceMotionEventPump;
class MODULES_EXPORT DeviceMotionController final
: public DeviceSingleWindowEventController,
@@ -34,7 +35,7 @@ class MODULES_EXPORT DeviceMotionController final
private:
explicit DeviceMotionController(Document&);
- // Inherited from DeviceEventControllerBase.
+ // Inherited from PlatformEventController.
void RegisterWithDispatcher() override;
void UnregisterWithDispatcher() override;
bool HasLastData() override;
@@ -43,6 +44,8 @@ class MODULES_EXPORT DeviceMotionController final
Event* LastEvent() const override;
const AtomicString& EventTypeName() const override;
bool IsNullEvent(Event*) const override;
+
+ Member<DeviceMotionEventPump> motion_event_pump_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_dispatcher.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_dispatcher.cc
deleted file mode 100644
index 5b46504a08f..00000000000
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_dispatcher.cc
+++ /dev/null
@@ -1,80 +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/renderer/modules/device_orientation/device_motion_dispatcher.h"
-
-#include "third_party/blink/renderer/modules/device_orientation/device_motion_controller.h"
-#include "third_party/blink/renderer/modules/device_orientation/device_motion_data.h"
-#include "third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.h"
-
-namespace blink {
-
-DeviceMotionDispatcher& DeviceMotionDispatcher::Instance() {
- DEFINE_STATIC_LOCAL(DeviceMotionDispatcher, device_motion_dispatcher,
- (new DeviceMotionDispatcher));
- return device_motion_dispatcher;
-}
-
-DeviceMotionDispatcher::DeviceMotionDispatcher() = default;
-
-DeviceMotionDispatcher::~DeviceMotionDispatcher() = default;
-
-void DeviceMotionDispatcher::Trace(blink::Visitor* visitor) {
- visitor->Trace(last_device_motion_data_);
- PlatformEventDispatcher::Trace(visitor);
-}
-
-void DeviceMotionDispatcher::StartListening(LocalFrame* frame) {
- // TODO(crbug.com/850619): ensure a valid frame is passed
- if (!frame)
- return;
- if (!event_pump_) {
- event_pump_ = std::make_unique<DeviceMotionEventPump>(
- frame->GetTaskRunner(TaskType::kSensor));
- }
- event_pump_->Start(frame, this);
-}
-
-void DeviceMotionDispatcher::StopListening() {
- if (event_pump_)
- event_pump_->Stop();
- last_device_motion_data_.Clear();
-}
-
-void DeviceMotionDispatcher::DidChangeDeviceMotion(DeviceMotionData* motion) {
- last_device_motion_data_ = motion;
- NotifyControllers();
-}
-
-const DeviceMotionData* DeviceMotionDispatcher::LatestDeviceMotionData() {
- return last_device_motion_data_.Get();
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_dispatcher.h b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_dispatcher.h
deleted file mode 100644
index 70e76a1c15d..00000000000
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_dispatcher.h
+++ /dev/null
@@ -1,77 +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.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_DEVICE_ORIENTATION_DEVICE_MOTION_DISPATCHER_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_DEVICE_ORIENTATION_DEVICE_MOTION_DISPATCHER_H_
-
-#include "base/memory/scoped_refptr.h"
-#include "third_party/blink/public/platform/modules/device_orientation/web_device_motion_listener.h"
-#include "third_party/blink/renderer/core/frame/platform_event_dispatcher.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
-
-namespace blink {
-
-class DeviceMotionData;
-class DeviceMotionEventPump;
-
-// This class listens to device motion data and notifies all registered
-// controllers.
-class DeviceMotionDispatcher final
- : public GarbageCollectedFinalized<DeviceMotionDispatcher>,
- public PlatformEventDispatcher,
- public WebDeviceMotionListener {
- USING_GARBAGE_COLLECTED_MIXIN(DeviceMotionDispatcher);
-
- public:
- static DeviceMotionDispatcher& Instance();
- ~DeviceMotionDispatcher() override;
-
- // Note that the returned object is owned by this class.
- const DeviceMotionData* LatestDeviceMotionData();
-
- // Inherited from WebDeviceMotionListener.
- void DidChangeDeviceMotion(DeviceMotionData*) override;
-
- void Trace(blink::Visitor*) override;
-
- private:
- DeviceMotionDispatcher();
-
- // Inherited from PlatformEventDispatcher.
- void StartListening(LocalFrame*) override;
- void StopListening() override;
-
- Member<DeviceMotionData> last_device_motion_data_;
- std::unique_ptr<DeviceMotionEventPump> event_pump_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_DEVICE_ORIENTATION_DEVICE_MOTION_DISPATCHER_H_
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 06aab06b84a..0ef859cca95 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
@@ -20,11 +20,9 @@ constexpr double kDefaultPumpDelayMilliseconds =
namespace blink {
-template class DeviceSensorEventPump<blink::WebDeviceMotionListener>;
-
DeviceMotionEventPump::DeviceMotionEventPump(
scoped_refptr<base::SingleThreadTaskRunner> task_runner)
- : DeviceSensorEventPump<blink::WebDeviceMotionListener>(task_runner),
+ : DeviceSensorEventPump(task_runner),
accelerometer_(this, device::mojom::blink::SensorType::ACCELEROMETER),
linear_acceleration_sensor_(
this,
@@ -35,6 +33,22 @@ DeviceMotionEventPump::~DeviceMotionEventPump() {
StopIfObserving();
}
+DeviceMotionData* DeviceMotionEventPump::LatestDeviceMotionData() {
+ return data_.Get();
+}
+
+void DeviceMotionEventPump::Trace(blink::Visitor* visitor) {
+ visitor->Trace(data_);
+ PlatformEventDispatcher::Trace(visitor);
+}
+
+void DeviceMotionEventPump::StartListening(LocalFrame* frame) {
+ // TODO(crbug.com/850619): ensure a valid frame is passed
+ if (!frame)
+ return;
+ Start(frame);
+}
+
void DeviceMotionEventPump::SendStartMessage(LocalFrame* frame) {
if (!sensor_provider_) {
DCHECK(frame);
@@ -43,7 +57,7 @@ void DeviceMotionEventPump::SendStartMessage(LocalFrame* frame) {
mojo::MakeRequest(&sensor_provider_));
sensor_provider_.set_connection_error_handler(
WTF::Bind(&DeviceSensorEventPump::HandleSensorProviderError,
- WTF::Unretained(this)));
+ WrapPersistent(this)));
}
accelerometer_.Start(sensor_provider_.get());
@@ -51,6 +65,11 @@ void DeviceMotionEventPump::SendStartMessage(LocalFrame* frame) {
gyroscope_.Start(sensor_provider_.get());
}
+void DeviceMotionEventPump::StopListening() {
+ Stop();
+ data_.Clear();
+}
+
void DeviceMotionEventPump::SendStopMessage() {
// SendStopMessage() gets called both when the page visibility changes and if
// all device motion event listeners are unregistered. Since removing the
@@ -63,13 +82,13 @@ void DeviceMotionEventPump::SendStopMessage() {
}
void DeviceMotionEventPump::FireEvent(TimerBase*) {
- DCHECK(listener());
-
DeviceMotionData* data = GetDataFromSharedMemory();
// data is null if not all sensors are active
- if (data)
- listener()->DidChangeDeviceMotion(data);
+ if (data) {
+ data_ = data;
+ NotifyControllers();
+ }
}
bool DeviceMotionEventPump::SensorsReadyOrErrored() const {
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 4d616365b3d..751d5660bc3 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
@@ -6,20 +6,30 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_DEVICE_ORIENTATION_DEVICE_MOTION_EVENT_PUMP_H_
#include "base/macros.h"
-#include "third_party/blink/public/platform/modules/device_orientation/web_device_motion_listener.h"
+#include "third_party/blink/renderer/core/frame/platform_event_dispatcher.h"
#include "third_party/blink/renderer/modules/device_orientation/device_sensor_event_pump.h"
#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/heap/handle.h"
namespace blink {
class DeviceMotionData;
class MODULES_EXPORT DeviceMotionEventPump
- : public DeviceSensorEventPump<blink::WebDeviceMotionListener> {
+ : public GarbageCollectedFinalized<DeviceMotionEventPump>,
+ public DeviceSensorEventPump,
+ public PlatformEventDispatcher {
+ USING_GARBAGE_COLLECTED_MIXIN(DeviceMotionEventPump);
+
public:
explicit DeviceMotionEventPump(scoped_refptr<base::SingleThreadTaskRunner>);
~DeviceMotionEventPump() override;
+ // Note that the returned object is owned by this class.
+ DeviceMotionData* LatestDeviceMotionData();
+
+ void Trace(blink::Visitor*) override;
+
// DeviceSensorEventPump:
void SendStartMessage(LocalFrame* frame) override;
void SendStopMessage() override;
@@ -35,11 +45,17 @@ class MODULES_EXPORT DeviceMotionEventPump
private:
friend class DeviceMotionEventPumpTest;
+ // Inherited from PlatformEventDispatcher.
+ void StartListening(LocalFrame*) override;
+ void StopListening() override;
+
// DeviceSensorEventPump:
bool SensorsReadyOrErrored() const override;
DeviceMotionData* GetDataFromSharedMemory();
+ Member<DeviceMotionData> data_;
+
DISALLOW_COPY_AND_ASSIGN(DeviceMotionEventPump);
};
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump_unittest.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump_unittest.cc
index 868c4f6cecf..a9d5238ec33 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump_unittest.cc
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump_unittest.cc
@@ -9,8 +9,8 @@
#include "base/run_loop.h"
#include "services/device/public/cpp/test/fake_sensor_and_provider.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/modules/device_orientation/web_device_motion_listener.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
+#include "third_party/blink/renderer/core/frame/platform_event_controller.h"
#include "third_party/blink/renderer/modules/device_orientation/device_motion_data.h"
#include "third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
@@ -20,16 +20,24 @@ namespace blink {
using device::FakeSensorProvider;
-class MockDeviceMotionListener : public blink::WebDeviceMotionListener {
+class MockDeviceMotionController final
+ : public GarbageCollectedFinalized<MockDeviceMotionController>,
+ public PlatformEventController {
+ USING_GARBAGE_COLLECTED_MIXIN(MockDeviceMotionController);
+
public:
- MockDeviceMotionListener()
- : did_change_device_motion_(false), number_of_events_(0) {
- data_ = DeviceMotionData::Create();
+ explicit MockDeviceMotionController(DeviceMotionEventPump* motion_pump)
+ : PlatformEventController(nullptr),
+ did_change_device_motion_(false),
+ motion_pump_(motion_pump) {}
+ ~MockDeviceMotionController() override {}
+
+ void Trace(Visitor* visitor) override {
+ PlatformEventController::Trace(visitor);
+ visitor->Trace(motion_pump_);
}
- ~MockDeviceMotionListener() override {}
- void DidChangeDeviceMotion(DeviceMotionData* data) override {
- data_ = data;
+ void DidUpdateData() override {
did_change_device_motion_ = true;
++number_of_events_;
}
@@ -38,27 +46,26 @@ class MockDeviceMotionListener : public blink::WebDeviceMotionListener {
int number_of_events() const { return number_of_events_; }
- const DeviceMotionData* data() const { return data_.Get(); }
+ void RegisterWithDispatcher() override { motion_pump_->AddController(this); }
- private:
- bool did_change_device_motion_;
- int number_of_events_;
- Persistent<DeviceMotionData> data_;
+ bool HasLastData() override { return motion_pump_->LatestDeviceMotionData(); }
- DISALLOW_COPY_AND_ASSIGN(MockDeviceMotionListener);
-};
+ void UnregisterWithDispatcher() override {
+ motion_pump_->RemoveController(this);
+ }
-class DeviceMotionEventPumpForTesting : public DeviceMotionEventPump {
- public:
- explicit DeviceMotionEventPumpForTesting(
- scoped_refptr<base::SingleThreadTaskRunner> task_runner)
- : DeviceMotionEventPump(task_runner) {}
- ~DeviceMotionEventPumpForTesting() override {}
+ const DeviceMotionData* data() {
+ return motion_pump_->LatestDeviceMotionData();
+ };
- int pump_delay_microseconds() const { return kDefaultPumpDelayMicroseconds; }
+ DeviceMotionEventPump* motion_pump() { return motion_pump_.Get(); }
private:
- DISALLOW_COPY_AND_ASSIGN(DeviceMotionEventPumpForTesting);
+ bool did_change_device_motion_;
+ int number_of_events_;
+ Member<DeviceMotionEventPump> motion_pump_;
+
+ DISALLOW_COPY_AND_ASSIGN(MockDeviceMotionController);
};
class DeviceMotionEventPumpTest : public testing::Test {
@@ -67,40 +74,43 @@ class DeviceMotionEventPumpTest : public testing::Test {
protected:
void SetUp() override {
- motion_pump_.reset(new DeviceMotionEventPumpForTesting(
- base::ThreadTaskRunnerHandle::Get()));
device::mojom::SensorProviderPtrInfo sensor_provider_ptr_info;
sensor_provider_.Bind(mojo::MakeRequest(&sensor_provider_ptr_info));
- motion_pump_->SetSensorProviderForTesting(
+ auto* motion_pump =
+ new DeviceMotionEventPump(base::ThreadTaskRunnerHandle::Get());
+ motion_pump->SetSensorProviderForTesting(
device::mojom::blink::SensorProviderPtr(
device::mojom::blink::SensorProviderPtrInfo(
sensor_provider_ptr_info.PassHandle(),
device::mojom::SensorProvider::Version_)));
- listener_.reset(new MockDeviceMotionListener);
+ controller_ = new MockDeviceMotionController(motion_pump);
ExpectAllThreeSensorsStateToBe(
DeviceMotionEventPump::SensorState::NOT_INITIALIZED);
EXPECT_EQ(DeviceMotionEventPump::PumpState::STOPPED,
- motion_pump()->GetPumpStateForTesting());
+ controller_->motion_pump()->GetPumpStateForTesting());
}
- void FireEvent() { motion_pump_->FireEvent(nullptr); }
+ void FireEvent() { controller_->motion_pump()->FireEvent(nullptr); }
void ExpectAccelerometerStateToBe(
DeviceMotionEventPump::SensorState expected_sensor_state) {
- EXPECT_EQ(expected_sensor_state, motion_pump_->accelerometer_.sensor_state);
+ EXPECT_EQ(expected_sensor_state,
+ controller_->motion_pump()->accelerometer_.sensor_state);
}
void ExpectLinearAccelerationSensorStateToBe(
DeviceMotionEventPump::SensorState expected_sensor_state) {
- EXPECT_EQ(expected_sensor_state,
- motion_pump_->linear_acceleration_sensor_.sensor_state);
+ EXPECT_EQ(
+ expected_sensor_state,
+ controller_->motion_pump()->linear_acceleration_sensor_.sensor_state);
}
void ExpectGyroscopeStateToBe(
DeviceMotionEventPump::SensorState expected_sensor_state) {
- EXPECT_EQ(expected_sensor_state, motion_pump_->gyroscope_.sensor_state);
+ EXPECT_EQ(expected_sensor_state,
+ controller_->motion_pump()->gyroscope_.sensor_state);
}
void ExpectAllThreeSensorsStateToBe(
@@ -110,52 +120,50 @@ class DeviceMotionEventPumpTest : public testing::Test {
ExpectGyroscopeStateToBe(expected_sensor_state);
}
- DeviceMotionEventPumpForTesting* motion_pump() { return motion_pump_.get(); }
-
- MockDeviceMotionListener* listener() { return listener_.get(); }
+ MockDeviceMotionController* controller() { return controller_.Get(); }
FakeSensorProvider* sensor_provider() { return &sensor_provider_; }
private:
- std::unique_ptr<DeviceMotionEventPumpForTesting> motion_pump_;
- std::unique_ptr<MockDeviceMotionListener> listener_;
+ Persistent<MockDeviceMotionController> controller_;
+
FakeSensorProvider sensor_provider_;
DISALLOW_COPY_AND_ASSIGN(DeviceMotionEventPumpTest);
};
TEST_F(DeviceMotionEventPumpTest, MultipleStartAndStopWithWait) {
- motion_pump()->Start(nullptr, listener());
+ controller()->motion_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::ACTIVE);
EXPECT_EQ(DeviceMotionEventPump::PumpState::RUNNING,
- motion_pump()->GetPumpStateForTesting());
+ controller()->motion_pump()->GetPumpStateForTesting());
- motion_pump()->Stop();
+ controller()->motion_pump()->Stop();
base::RunLoop().RunUntilIdle();
ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::SUSPENDED);
EXPECT_EQ(DeviceMotionEventPump::PumpState::STOPPED,
- motion_pump()->GetPumpStateForTesting());
+ controller()->motion_pump()->GetPumpStateForTesting());
- motion_pump()->Start(nullptr, listener());
+ controller()->motion_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::ACTIVE);
EXPECT_EQ(DeviceMotionEventPump::PumpState::RUNNING,
- motion_pump()->GetPumpStateForTesting());
+ controller()->motion_pump()->GetPumpStateForTesting());
- motion_pump()->Stop();
+ controller()->motion_pump()->Stop();
base::RunLoop().RunUntilIdle();
ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::SUSPENDED);
EXPECT_EQ(DeviceMotionEventPump::PumpState::STOPPED,
- motion_pump()->GetPumpStateForTesting());
+ controller()->motion_pump()->GetPumpStateForTesting());
}
TEST_F(DeviceMotionEventPumpTest, CallStop) {
- motion_pump()->Stop();
+ controller()->motion_pump()->Stop();
base::RunLoop().RunUntilIdle();
ExpectAllThreeSensorsStateToBe(
@@ -163,26 +171,26 @@ TEST_F(DeviceMotionEventPumpTest, CallStop) {
}
TEST_F(DeviceMotionEventPumpTest, CallStartAndStop) {
- motion_pump()->Start(nullptr, listener());
- motion_pump()->Stop();
+ controller()->motion_pump()->Start(nullptr);
+ controller()->motion_pump()->Stop();
base::RunLoop().RunUntilIdle();
ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::SUSPENDED);
}
TEST_F(DeviceMotionEventPumpTest, CallStartMultipleTimes) {
- motion_pump()->Start(nullptr, listener());
- motion_pump()->Start(nullptr, listener());
- motion_pump()->Stop();
+ controller()->motion_pump()->Start(nullptr);
+ controller()->motion_pump()->Start(nullptr);
+ controller()->motion_pump()->Stop();
base::RunLoop().RunUntilIdle();
ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::SUSPENDED);
}
TEST_F(DeviceMotionEventPumpTest, CallStopMultipleTimes) {
- motion_pump()->Start(nullptr, listener());
- motion_pump()->Stop();
- motion_pump()->Stop();
+ controller()->motion_pump()->Start(nullptr);
+ controller()->motion_pump()->Stop();
+ controller()->motion_pump()->Stop();
base::RunLoop().RunUntilIdle();
ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::SUSPENDED);
@@ -190,20 +198,21 @@ TEST_F(DeviceMotionEventPumpTest, CallStopMultipleTimes) {
// Test multiple DeviceSensorEventPump::Start() calls only bind sensor once.
TEST_F(DeviceMotionEventPumpTest, SensorOnlyBindOnce) {
- motion_pump()->Start(nullptr, listener());
- motion_pump()->Stop();
- motion_pump()->Start(nullptr, listener());
+ controller()->motion_pump()->Start(nullptr);
+ controller()->motion_pump()->Stop();
+ controller()->motion_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::ACTIVE);
- motion_pump()->Stop();
+ controller()->motion_pump()->Stop();
ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::SUSPENDED);
}
TEST_F(DeviceMotionEventPumpTest, AllSensorsAreActive) {
- motion_pump()->Start(nullptr, listener());
+ controller()->RegisterWithDispatcher();
+ controller()->motion_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::ACTIVE);
@@ -214,9 +223,8 @@ TEST_F(DeviceMotionEventPumpTest, AllSensorsAreActive) {
FireEvent();
- EXPECT_TRUE(listener()->did_change_device_motion());
-
- const DeviceMotionData* received_data = listener()->data();
+ const DeviceMotionData* received_data = controller()->data();
+ EXPECT_TRUE(controller()->did_change_device_motion());
EXPECT_TRUE(received_data->GetAccelerationIncludingGravity()->CanProvideX());
EXPECT_EQ(1, received_data->GetAccelerationIncludingGravity()->X());
@@ -239,7 +247,7 @@ TEST_F(DeviceMotionEventPumpTest, AllSensorsAreActive) {
EXPECT_TRUE(received_data->GetRotationRate()->CanProvideGamma());
EXPECT_EQ(gfx::RadToDeg(9.0), received_data->GetRotationRate()->Gamma());
- motion_pump()->Stop();
+ controller()->motion_pump()->Stop();
ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::SUSPENDED);
}
@@ -247,7 +255,8 @@ TEST_F(DeviceMotionEventPumpTest, AllSensorsAreActive) {
TEST_F(DeviceMotionEventPumpTest, TwoSensorsAreActive) {
sensor_provider()->set_linear_acceleration_sensor_is_available(false);
- motion_pump()->Start(nullptr, listener());
+ controller()->RegisterWithDispatcher();
+ controller()->motion_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectAccelerometerStateToBe(DeviceMotionEventPump::SensorState::ACTIVE);
@@ -260,8 +269,8 @@ TEST_F(DeviceMotionEventPumpTest, TwoSensorsAreActive) {
FireEvent();
- const DeviceMotionData* received_data = listener()->data();
- EXPECT_TRUE(listener()->did_change_device_motion());
+ const DeviceMotionData* received_data = controller()->data();
+ EXPECT_TRUE(controller()->did_change_device_motion());
EXPECT_TRUE(received_data->GetAccelerationIncludingGravity()->CanProvideX());
EXPECT_EQ(1, received_data->GetAccelerationIncludingGravity()->X());
@@ -281,7 +290,7 @@ TEST_F(DeviceMotionEventPumpTest, TwoSensorsAreActive) {
EXPECT_TRUE(received_data->GetRotationRate()->CanProvideGamma());
EXPECT_EQ(gfx::RadToDeg(9.0), received_data->GetRotationRate()->Gamma());
- motion_pump()->Stop();
+ controller()->motion_pump()->Stop();
ExpectAccelerometerStateToBe(DeviceMotionEventPump::SensorState::SUSPENDED);
ExpectLinearAccelerationSensorStateToBe(
@@ -290,7 +299,8 @@ TEST_F(DeviceMotionEventPumpTest, TwoSensorsAreActive) {
}
TEST_F(DeviceMotionEventPumpTest, SomeSensorDataFieldsNotAvailable) {
- motion_pump()->Start(nullptr, listener());
+ controller()->RegisterWithDispatcher();
+ controller()->motion_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::ACTIVE);
@@ -301,8 +311,8 @@ TEST_F(DeviceMotionEventPumpTest, SomeSensorDataFieldsNotAvailable) {
FireEvent();
- const DeviceMotionData* received_data = listener()->data();
- EXPECT_TRUE(listener()->did_change_device_motion());
+ const DeviceMotionData* received_data = controller()->data();
+ EXPECT_TRUE(controller()->did_change_device_motion());
EXPECT_FALSE(received_data->GetAccelerationIncludingGravity()->CanProvideX());
EXPECT_TRUE(received_data->GetAccelerationIncludingGravity()->CanProvideY());
@@ -322,7 +332,7 @@ TEST_F(DeviceMotionEventPumpTest, SomeSensorDataFieldsNotAvailable) {
EXPECT_EQ(gfx::RadToDeg(8.0), received_data->GetRotationRate()->Beta());
EXPECT_FALSE(received_data->GetRotationRate()->CanProvideGamma());
- motion_pump()->Stop();
+ controller()->motion_pump()->Stop();
ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::SUSPENDED);
}
@@ -333,7 +343,8 @@ TEST_F(DeviceMotionEventPumpTest, FireAllNullEvent) {
sensor_provider()->set_linear_acceleration_sensor_is_available(false);
sensor_provider()->set_gyroscope_is_available(false);
- motion_pump()->Start(nullptr, listener());
+ controller()->RegisterWithDispatcher();
+ controller()->motion_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectAllThreeSensorsStateToBe(
@@ -341,8 +352,8 @@ TEST_F(DeviceMotionEventPumpTest, FireAllNullEvent) {
FireEvent();
- const DeviceMotionData* received_data = listener()->data();
- EXPECT_TRUE(listener()->did_change_device_motion());
+ const DeviceMotionData* received_data = controller()->data();
+ EXPECT_TRUE(controller()->did_change_device_motion());
EXPECT_FALSE(received_data->GetAcceleration()->CanProvideX());
EXPECT_FALSE(received_data->GetAcceleration()->CanProvideY());
@@ -356,7 +367,7 @@ TEST_F(DeviceMotionEventPumpTest, FireAllNullEvent) {
EXPECT_FALSE(received_data->GetRotationRate()->CanProvideBeta());
EXPECT_FALSE(received_data->GetRotationRate()->CanProvideGamma());
- motion_pump()->Stop();
+ controller()->motion_pump()->Stop();
ExpectAllThreeSensorsStateToBe(
DeviceMotionEventPump::SensorState::NOT_INITIALIZED);
@@ -364,28 +375,29 @@ TEST_F(DeviceMotionEventPumpTest, FireAllNullEvent) {
TEST_F(DeviceMotionEventPumpTest,
NotFireEventWhenSensorReadingTimeStampIsZero) {
- motion_pump()->Start(nullptr, listener());
+ controller()->RegisterWithDispatcher();
+ controller()->motion_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::ACTIVE);
FireEvent();
- EXPECT_FALSE(listener()->did_change_device_motion());
+ EXPECT_FALSE(controller()->did_change_device_motion());
sensor_provider()->UpdateAccelerometerData(1, 2, 3);
FireEvent();
- EXPECT_FALSE(listener()->did_change_device_motion());
+ EXPECT_FALSE(controller()->did_change_device_motion());
sensor_provider()->UpdateLinearAccelerationSensorData(4, 5, 6);
FireEvent();
- EXPECT_FALSE(listener()->did_change_device_motion());
+ EXPECT_FALSE(controller()->did_change_device_motion());
sensor_provider()->UpdateGyroscopeData(7, 8, 9);
FireEvent();
// Event is fired only after all the available sensors have data.
- EXPECT_TRUE(listener()->did_change_device_motion());
+ EXPECT_TRUE(controller()->did_change_device_motion());
- motion_pump()->Stop();
+ controller()->motion_pump()->Stop();
ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::SUSPENDED);
}
@@ -396,9 +408,10 @@ TEST_F(DeviceMotionEventPumpTest,
TEST_F(DeviceMotionEventPumpTest, PumpThrottlesEventRate) {
// Confirm that the delay for pumping events is 60 Hz.
EXPECT_GE(60, WTF::Time::kMicrosecondsPerSecond /
- motion_pump()->pump_delay_microseconds());
+ DeviceMotionEventPump::kDefaultPumpDelayMicroseconds);
- motion_pump()->Start(nullptr, listener());
+ controller()->RegisterWithDispatcher();
+ controller()->motion_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::ACTIVE);
@@ -412,14 +425,14 @@ TEST_F(DeviceMotionEventPumpTest, PumpThrottlesEventRate) {
FROM_HERE, loop.QuitWhenIdleClosure(),
WTF::TimeDelta::FromMilliseconds(100));
loop.Run();
- motion_pump()->Stop();
+ controller()->motion_pump()->Stop();
ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::SUSPENDED);
- // Check that the blink::WebDeviceMotionListener does not receive excess
+ // Check that the PlatformEventController does not receive excess
// events.
- EXPECT_TRUE(listener()->did_change_device_motion());
- EXPECT_GE(6, listener()->number_of_events());
+ EXPECT_TRUE(controller()->did_change_device_motion());
+ EXPECT_GE(6, controller()->number_of_events());
}
} // namespace blink
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 becd631742e..d671f10e015 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
@@ -6,7 +6,7 @@
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/frame/settings.h"
-#include "third_party/blink/renderer/modules/device_orientation/device_orientation_dispatcher.h"
+#include "third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump.h"
namespace blink {
@@ -66,11 +66,6 @@ void DeviceOrientationAbsoluteController::DidAddEventListener(
DeviceSingleWindowEventController::DidAddEventListener(window, event_type);
}
-DeviceOrientationDispatcher&
-DeviceOrientationAbsoluteController::DispatcherInstance() const {
- return DeviceOrientationDispatcher::Instance(true);
-}
-
const AtomicString& DeviceOrientationAbsoluteController::EventTypeName() const {
return EventTypeNames::deviceorientationabsolute;
}
@@ -79,4 +74,8 @@ void DeviceOrientationAbsoluteController::Trace(blink::Visitor* visitor) {
DeviceOrientationController::Trace(visitor);
}
+void DeviceOrientationAbsoluteController::RegisterWithDispatcher() {
+ RegisterWithOrientationEventPump(true /* absolute */);
+}
+
} // namespace blink
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 23227c705df..e8e2e28d0ed 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
@@ -26,10 +26,12 @@ class MODULES_EXPORT DeviceOrientationAbsoluteController final
void Trace(blink::Visitor*) override;
private:
+ // Inherited from PlatformEventController.
+ void RegisterWithDispatcher() override;
+
explicit DeviceOrientationAbsoluteController(Document&);
// Inherited from DeviceOrientationController.
- DeviceOrientationDispatcher& DispatcherInstance() const override;
const AtomicString& EventTypeName() const override;
};
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 198eed07893..6df6db6ba2e 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
@@ -12,8 +12,8 @@
#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_dispatcher.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/feature_policy/feature_policy.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
@@ -94,7 +94,9 @@ void DeviceOrientationController::DidAddEventListener(
DeviceOrientationData* DeviceOrientationController::LastData() const {
return override_orientation_data_
? override_orientation_data_.Get()
- : DispatcherInstance().LatestDeviceOrientationData();
+ : orientation_event_pump_
+ ? orientation_event_pump_->LatestDeviceOrientationData()
+ : nullptr;
}
bool DeviceOrientationController::HasLastData() {
@@ -102,11 +104,12 @@ bool DeviceOrientationController::HasLastData() {
}
void DeviceOrientationController::RegisterWithDispatcher() {
- DispatcherInstance().AddController(this);
+ RegisterWithOrientationEventPump(false /* absolute */);
}
void DeviceOrientationController::UnregisterWithDispatcher() {
- DispatcherInstance().RemoveController(this);
+ if (orientation_event_pump_)
+ orientation_event_pump_->RemoveController(this);
}
Event* DeviceOrientationController::LastEvent() const {
@@ -137,17 +140,27 @@ void DeviceOrientationController::ClearOverride() {
DidUpdateData();
}
-DeviceOrientationDispatcher& DeviceOrientationController::DispatcherInstance()
- const {
- return DeviceOrientationDispatcher::Instance(false);
-}
-
void DeviceOrientationController::Trace(blink::Visitor* visitor) {
visitor->Trace(override_orientation_data_);
+ visitor->Trace(orientation_event_pump_);
DeviceSingleWindowEventController::Trace(visitor);
Supplement<Document>::Trace(visitor);
}
+void DeviceOrientationController::RegisterWithOrientationEventPump(
+ bool absolute) {
+ if (!orientation_event_pump_) {
+ LocalFrame* frame = GetDocument().GetFrame();
+ if (!frame)
+ return;
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner =
+ frame->GetTaskRunner(TaskType::kSensor);
+ orientation_event_pump_ =
+ new DeviceOrientationEventPump(task_runner, absolute);
+ }
+ orientation_event_pump_->AddController(this);
+}
+
// static
void DeviceOrientationController::LogToConsolePolicyFeaturesDisabled(
LocalFrame* frame,
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 fdd13f6e781..3985fdec55c 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
@@ -12,7 +12,7 @@
namespace blink {
class DeviceOrientationData;
-class DeviceOrientationDispatcher;
+class DeviceOrientationEventPump;
class Event;
class MODULES_EXPORT DeviceOrientationController
@@ -43,11 +43,12 @@ class MODULES_EXPORT DeviceOrientationController
protected:
explicit DeviceOrientationController(Document&);
+ void RegisterWithOrientationEventPump(bool absolute);
- virtual DeviceOrientationDispatcher& DispatcherInstance() const;
+ Member<DeviceOrientationEventPump> orientation_event_pump_;
private:
- // Inherited from DeviceEventControllerBase.
+ // Inherited from PlatformEventController.
void RegisterWithDispatcher() override;
void UnregisterWithDispatcher() override;
bool HasLastData() override;
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 9c22671ad25..f8c415301c4 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,6 @@
#include "third_party/blink/renderer/modules/device_orientation/device_orientation_data.h"
-#include "services/device/public/cpp/generic_sensor/orientation_data.h"
#include "third_party/blink/renderer/modules/device_orientation/device_orientation_event_init.h"
namespace blink {
@@ -56,20 +55,6 @@ DeviceOrientationData* DeviceOrientationData::Create(
return DeviceOrientationData::Create(alpha, beta, gamma, init.absolute());
}
-DeviceOrientationData* DeviceOrientationData::Create(
- const device::OrientationData& data) {
- base::Optional<double> alpha;
- base::Optional<double> beta;
- base::Optional<double> gamma;
- if (data.has_alpha)
- alpha = data.alpha;
- if (data.has_beta)
- beta = data.beta;
- if (data.has_gamma)
- gamma = data.gamma;
- return DeviceOrientationData::Create(alpha, beta, gamma, data.absolute);
-}
-
DeviceOrientationData::DeviceOrientationData() : absolute_(false) {}
DeviceOrientationData::DeviceOrientationData(
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 b2d771ba848..cba97f33d1c 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
@@ -30,10 +30,6 @@
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
-namespace device {
-class OrientationData;
-}
-
namespace blink {
class DeviceOrientationEventInit;
@@ -47,7 +43,6 @@ class MODULES_EXPORT DeviceOrientationData final
const base::Optional<double>& gamma,
bool absolute);
static DeviceOrientationData* Create(const DeviceOrientationEventInit&);
- static DeviceOrientationData* Create(const device::OrientationData&);
void Trace(blink::Visitor* visitor) {}
double Alpha() const;
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_dispatcher.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_dispatcher.cc
deleted file mode 100644
index 8a15c24af20..00000000000
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_dispatcher.cc
+++ /dev/null
@@ -1,97 +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/renderer/modules/device_orientation/device_orientation_dispatcher.h"
-
-#include "third_party/blink/renderer/modules/device_orientation/device_orientation_controller.h"
-#include "third_party/blink/renderer/modules/device_orientation/device_orientation_data.h"
-#include "third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump.h"
-
-namespace blink {
-
-DeviceOrientationDispatcher& DeviceOrientationDispatcher::Instance(
- bool absolute) {
- if (absolute) {
- DEFINE_STATIC_LOCAL(DeviceOrientationDispatcher,
- device_orientation_absolute_dispatcher,
- (new DeviceOrientationDispatcher(absolute)));
- return device_orientation_absolute_dispatcher;
- }
- DEFINE_STATIC_LOCAL(DeviceOrientationDispatcher,
- device_orientation_dispatcher,
- (new DeviceOrientationDispatcher(absolute)));
- return device_orientation_dispatcher;
-}
-
-DeviceOrientationDispatcher::DeviceOrientationDispatcher(bool absolute)
- : absolute_(absolute) {}
-
-DeviceOrientationDispatcher::~DeviceOrientationDispatcher() = default;
-
-void DeviceOrientationDispatcher::Trace(blink::Visitor* visitor) {
- visitor->Trace(last_device_orientation_data_);
- PlatformEventDispatcher::Trace(visitor);
-}
-
-void DeviceOrientationDispatcher::StartListening(LocalFrame* frame) {
- // TODO(crbug.com/850619): ensure a valid frame is passed
- if (!frame)
- return;
- if (!event_pump_) {
- event_pump_ = std::make_unique<DeviceOrientationEventPump>(
- frame->GetTaskRunner(TaskType::kSensor), absolute_);
- }
- event_pump_->Start(frame, this);
-}
-
-void DeviceOrientationDispatcher::StopListening() {
- if (event_pump_)
- event_pump_->Stop();
- last_device_orientation_data_.Clear();
-}
-
-void DeviceOrientationDispatcher::DidChangeDeviceOrientation(
- const device::OrientationData& motion) {
- last_device_orientation_data_ = DeviceOrientationData::Create(motion);
- NotifyControllers();
-}
-
-DeviceOrientationData*
-DeviceOrientationDispatcher::LatestDeviceOrientationData() {
- return last_device_orientation_data_.Get();
-}
-
-WebPlatformEventType DeviceOrientationDispatcher::GetWebPlatformEventType()
- const {
- return (absolute_) ? kWebPlatformEventTypeDeviceOrientationAbsolute
- : kWebPlatformEventTypeDeviceOrientation;
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_dispatcher.h b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_dispatcher.h
deleted file mode 100644
index 62a9453ad32..00000000000
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_dispatcher.h
+++ /dev/null
@@ -1,86 +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.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_DEVICE_ORIENTATION_DEVICE_ORIENTATION_DISPATCHER_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_DEVICE_ORIENTATION_DEVICE_ORIENTATION_DISPATCHER_H_
-
-#include "base/memory/scoped_refptr.h"
-#include "third_party/blink/public/platform/modules/device_orientation/web_device_orientation_listener.h"
-#include "third_party/blink/public/platform/web_platform_event_type.h"
-#include "third_party/blink/renderer/core/frame/platform_event_dispatcher.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
-
-namespace device {
-class OrientationData;
-}
-
-namespace blink {
-
-class DeviceOrientationData;
-class DeviceOrientationEventPump;
-
-// This class listens to device orientation data and notifies all registered
-// controllers.
-class DeviceOrientationDispatcher final
- : public GarbageCollectedFinalized<DeviceOrientationDispatcher>,
- public PlatformEventDispatcher,
- public WebDeviceOrientationListener {
- USING_GARBAGE_COLLECTED_MIXIN(DeviceOrientationDispatcher);
-
- public:
- static DeviceOrientationDispatcher& Instance(bool absolute);
- ~DeviceOrientationDispatcher() override;
-
- // Note that the returned object is owned by this class.
- // FIXME: make the return value const, see crbug.com/233174.
- DeviceOrientationData* LatestDeviceOrientationData();
-
- // Inherited from WebDeviceOrientationListener.
- void DidChangeDeviceOrientation(const device::OrientationData&) override;
-
- void Trace(blink::Visitor*) override;
-
- private:
- explicit DeviceOrientationDispatcher(bool absolute);
-
- // Inherited from PlatformEventDispatcher.
- void StartListening(LocalFrame* frame) override;
- void StopListening() override;
-
- WebPlatformEventType GetWebPlatformEventType() const;
-
- const bool absolute_;
- Member<DeviceOrientationData> last_device_orientation_data_;
- std::unique_ptr<DeviceOrientationEventPump> event_pump_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_DEVICE_ORIENTATION_DEVICE_ORIENTATION_DISPATCHER_H_
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 459caef8295..362f5c3f7d1 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
@@ -7,44 +7,40 @@
#include "services/device/public/mojom/sensor.mojom-blink.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
+#include "third_party/blink/renderer/modules/device_orientation/device_orientation_data.h"
#include "third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump.h"
namespace {
-bool IsAngleDifferentThreshold(bool has_angle1,
- double angle1,
- bool has_angle2,
- double angle2) {
- if (has_angle1 != has_angle2)
- return true;
-
- return (has_angle1 &&
- std::fabs(angle1 - angle2) >=
- blink::DeviceOrientationEventPump::kOrientationThreshold);
+bool IsAngleDifferentThreshold(double angle1, double angle2) {
+ return (std::fabs(angle1 - angle2) >=
+ blink::DeviceOrientationEventPump::kOrientationThreshold);
}
-bool IsSignificantlyDifferent(const device::OrientationData& data1,
- const device::OrientationData& data2) {
- return IsAngleDifferentThreshold(data1.has_alpha, data1.alpha,
- data2.has_alpha, data2.alpha) ||
- IsAngleDifferentThreshold(data1.has_beta, data1.beta, data2.has_beta,
- data2.beta) ||
- IsAngleDifferentThreshold(data1.has_gamma, data1.gamma,
- data2.has_gamma, data2.gamma);
+bool IsSignificantlyDifferent(const blink::DeviceOrientationData* data1,
+ const blink::DeviceOrientationData* data2) {
+ if (data1->CanProvideAlpha() != data2->CanProvideAlpha() ||
+ data1->CanProvideBeta() != data2->CanProvideBeta() ||
+ data1->CanProvideGamma() != data2->CanProvideGamma())
+ return true;
+ return (data1->CanProvideAlpha() &&
+ IsAngleDifferentThreshold(data1->Alpha(), data2->Alpha())) ||
+ (data1->CanProvideBeta() &&
+ IsAngleDifferentThreshold(data1->Beta(), data2->Beta())) ||
+ (data1->CanProvideGamma() &&
+ IsAngleDifferentThreshold(data1->Gamma(), data2->Gamma()));
}
} // namespace
namespace blink {
-template class DeviceSensorEventPump<blink::WebDeviceOrientationListener>;
-
const double DeviceOrientationEventPump::kOrientationThreshold = 0.1;
DeviceOrientationEventPump::DeviceOrientationEventPump(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
bool absolute)
- : DeviceSensorEventPump<blink::WebDeviceOrientationListener>(task_runner),
+ : DeviceSensorEventPump(task_runner),
relative_orientation_sensor_(
this,
device::mojom::SensorType::RELATIVE_ORIENTATION_EULER_ANGLES),
@@ -58,6 +54,23 @@ DeviceOrientationEventPump::~DeviceOrientationEventPump() {
StopIfObserving();
}
+DeviceOrientationData*
+DeviceOrientationEventPump::LatestDeviceOrientationData() {
+ return data_.Get();
+}
+
+void DeviceOrientationEventPump::Trace(blink::Visitor* visitor) {
+ visitor->Trace(data_);
+ PlatformEventDispatcher::Trace(visitor);
+}
+
+void DeviceOrientationEventPump::StartListening(LocalFrame* frame) {
+ // TODO(crbug.com/850619): ensure a valid frame is passed
+ if (!frame)
+ return;
+ Start(frame);
+}
+
void DeviceOrientationEventPump::SendStartMessage(LocalFrame* frame) {
if (!sensor_provider_) {
DCHECK(frame);
@@ -66,7 +79,7 @@ void DeviceOrientationEventPump::SendStartMessage(LocalFrame* frame) {
mojo::MakeRequest(&sensor_provider_));
sensor_provider_.set_connection_error_handler(
WTF::Bind(&DeviceSensorEventPump::HandleSensorProviderError,
- WTF::Unretained(this)));
+ WrapPersistent(this)));
}
if (absolute_) {
@@ -78,6 +91,11 @@ void DeviceOrientationEventPump::SendStartMessage(LocalFrame* frame) {
}
}
+void DeviceOrientationEventPump::StopListening() {
+ Stop();
+ data_.Clear();
+}
+
void DeviceOrientationEventPump::SendStopMessage() {
// SendStopMessage() gets called both when the page visibility changes and if
// all device orientation event listeners are unregistered. Since removing
@@ -105,19 +123,15 @@ void DeviceOrientationEventPump::SendStopMessage() {
// data when stopping. If we don't reset here as well, then when starting back
// up we won't notify DeviceOrientationDispatcher of the orientation, since
// we think it hasn't changed.
- data_ = device::OrientationData();
+ data_ = nullptr;
}
void DeviceOrientationEventPump::FireEvent(TimerBase*) {
- device::OrientationData data;
-
- DCHECK(listener());
-
- GetDataFromSharedMemory(&data);
+ DeviceOrientationData* data = GetDataFromSharedMemory();
if (ShouldFireEvent(data)) {
data_ = data;
- listener()->DidChangeDeviceOrientation(data);
+ NotifyControllers();
}
}
@@ -152,60 +166,67 @@ bool DeviceOrientationEventPump::SensorsReadyOrErrored() const {
return true;
}
-void DeviceOrientationEventPump::GetDataFromSharedMemory(
- device::OrientationData* data) {
- data->all_available_sensors_are_active = true;
+DeviceOrientationData* DeviceOrientationEventPump::GetDataFromSharedMemory() {
+ base::Optional<double> alpha;
+ base::Optional<double> beta;
+ base::Optional<double> gamma;
+ bool absolute = false;
if (!absolute_ && relative_orientation_sensor_.SensorReadingCouldBeRead()) {
// For DeviceOrientation Event, this provides relative orientation data.
- data->all_available_sensors_are_active =
- relative_orientation_sensor_.reading.timestamp() != 0.0;
- if (!data->all_available_sensors_are_active)
- return;
- data->alpha = relative_orientation_sensor_.reading.orientation_euler.z;
- data->beta = relative_orientation_sensor_.reading.orientation_euler.x;
- data->gamma = relative_orientation_sensor_.reading.orientation_euler.y;
- data->has_alpha = !std::isnan(
- relative_orientation_sensor_.reading.orientation_euler.z.value());
- data->has_beta = !std::isnan(
- relative_orientation_sensor_.reading.orientation_euler.x.value());
- data->has_gamma = !std::isnan(
- relative_orientation_sensor_.reading.orientation_euler.y.value());
- data->absolute = false;
+ if (relative_orientation_sensor_.reading.timestamp() == 0.0)
+ return nullptr;
+
+ if (!std::isnan(
+ relative_orientation_sensor_.reading.orientation_euler.z.value()))
+ alpha = relative_orientation_sensor_.reading.orientation_euler.z;
+
+ if (!std::isnan(
+ relative_orientation_sensor_.reading.orientation_euler.x.value()))
+ beta = relative_orientation_sensor_.reading.orientation_euler.x;
+
+ if (!std::isnan(
+ relative_orientation_sensor_.reading.orientation_euler.y.value()))
+ gamma = relative_orientation_sensor_.reading.orientation_euler.y;
} else if (absolute_orientation_sensor_.SensorReadingCouldBeRead()) {
// For DeviceOrientationAbsolute Event, this provides absolute orientation
// data.
//
// For DeviceOrientation Event, this provides absolute orientation data if
// relative orientation data is not available.
- data->all_available_sensors_are_active =
- absolute_orientation_sensor_.reading.timestamp() != 0.0;
- if (!data->all_available_sensors_are_active)
- return;
- data->alpha = absolute_orientation_sensor_.reading.orientation_euler.z;
- data->beta = absolute_orientation_sensor_.reading.orientation_euler.x;
- data->gamma = absolute_orientation_sensor_.reading.orientation_euler.y;
- data->has_alpha = !std::isnan(
- absolute_orientation_sensor_.reading.orientation_euler.z.value());
- data->has_beta = !std::isnan(
- absolute_orientation_sensor_.reading.orientation_euler.x.value());
- data->has_gamma = !std::isnan(
- absolute_orientation_sensor_.reading.orientation_euler.y.value());
- data->absolute = true;
+ if (absolute_orientation_sensor_.reading.timestamp() == 0.0)
+ return nullptr;
+
+ if (!std::isnan(
+ absolute_orientation_sensor_.reading.orientation_euler.z.value()))
+ alpha = absolute_orientation_sensor_.reading.orientation_euler.z;
+
+ if (!std::isnan(
+ absolute_orientation_sensor_.reading.orientation_euler.x.value()))
+ beta = absolute_orientation_sensor_.reading.orientation_euler.x;
+
+ if (!std::isnan(
+ absolute_orientation_sensor_.reading.orientation_euler.y.value()))
+ gamma = absolute_orientation_sensor_.reading.orientation_euler.y;
+
+ absolute = true;
} else {
- data->absolute = absolute_;
+ absolute = absolute_;
}
+
+ return DeviceOrientationData::Create(alpha, beta, gamma, absolute);
}
bool DeviceOrientationEventPump::ShouldFireEvent(
- const device::OrientationData& data) const {
- if (!data.all_available_sensors_are_active)
+ const DeviceOrientationData* data) const {
+ // |data| is null if not all sensors are active
+ if (!data)
return false;
- if (!data.has_alpha && !data.has_beta && !data.has_gamma) {
- // no data can be provided, this is an all-null event.
+ // when the state changes from not having data to having data,
+ // the event should be fired
+ if (!data_)
return true;
- }
return IsSignificantlyDifferent(data_, 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 cc2122b9680..fca10da6f98 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
@@ -6,15 +6,19 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_DEVICE_ORIENTATION_DEVICE_ORIENTATION_EVENT_PUMP_H_
#include "base/macros.h"
-#include "services/device/public/cpp/generic_sensor/orientation_data.h"
-#include "third_party/blink/public/platform/modules/device_orientation/web_device_orientation_listener.h"
+#include "third_party/blink/renderer/core/frame/platform_event_dispatcher.h"
#include "third_party/blink/renderer/modules/device_orientation/device_sensor_event_pump.h"
#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/heap/handle.h"
namespace blink {
class MODULES_EXPORT DeviceOrientationEventPump
- : public DeviceSensorEventPump<blink::WebDeviceOrientationListener> {
+ : public GarbageCollectedFinalized<DeviceOrientationEventPump>,
+ public DeviceSensorEventPump,
+ public PlatformEventDispatcher {
+ USING_GARBAGE_COLLECTED_MIXIN(DeviceOrientationEventPump);
+
public:
// Angle threshold beyond which two orientation events are considered
// sufficiently different.
@@ -23,8 +27,14 @@ class MODULES_EXPORT DeviceOrientationEventPump
explicit DeviceOrientationEventPump(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
bool absolute);
+
~DeviceOrientationEventPump() override;
+ // Note that the returned object is owned by this class.
+ DeviceOrientationData* LatestDeviceOrientationData();
+
+ void Trace(blink::Visitor*) override;
+
// DeviceSensorEventPump:
void SendStartMessage(LocalFrame* frame) override;
void SendStopMessage() override;
@@ -41,17 +51,21 @@ class MODULES_EXPORT DeviceOrientationEventPump
friend class DeviceOrientationEventPumpTest;
friend class DeviceAbsoluteOrientationEventPumpTest;
+ // Inherited from PlatformEventDispatcher.
+ void StartListening(LocalFrame*) override;
+ void StopListening() override;
+
// DeviceSensorEventPump:
bool SensorsReadyOrErrored() const override;
- void GetDataFromSharedMemory(device::OrientationData* data);
+ DeviceOrientationData* GetDataFromSharedMemory();
- bool ShouldFireEvent(const device::OrientationData& data) const;
+ bool ShouldFireEvent(const DeviceOrientationData* data) const;
bool absolute_;
bool fall_back_to_absolute_orientation_sensor_;
bool should_suspend_absolute_orientation_sensor_ = false;
- device::OrientationData data_;
+ Member<DeviceOrientationData> data_;
DISALLOW_COPY_AND_ASSIGN(DeviceOrientationEventPump);
};
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump_unittest.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump_unittest.cc
index 95b644c61b2..64c5535d345 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump_unittest.cc
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump_unittest.cc
@@ -7,12 +7,13 @@
#include <memory>
#include "base/run_loop.h"
-#include "services/device/public/cpp/generic_sensor/orientation_data.h"
#include "services/device/public/cpp/test/fake_sensor_and_provider.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/modules/device_orientation/web_device_orientation_listener.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
+#include "third_party/blink/renderer/core/frame/platform_event_controller.h"
+#include "third_party/blink/renderer/modules/device_orientation/device_orientation_data.h"
#include "third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
namespace {
@@ -24,19 +25,25 @@ namespace blink {
using device::FakeSensorProvider;
-class MockDeviceOrientationListener
- : public blink::WebDeviceOrientationListener {
+class MockDeviceOrientationController final
+ : public GarbageCollectedFinalized<MockDeviceOrientationController>,
+ public PlatformEventController {
+ USING_GARBAGE_COLLECTED_MIXIN(MockDeviceOrientationController);
+
public:
- MockDeviceOrientationListener() : did_change_device_orientation_(false) {
- memset(&data_, 0, sizeof(data_));
+ explicit MockDeviceOrientationController(
+ DeviceOrientationEventPump* orientation_pump)
+ : PlatformEventController(nullptr),
+ did_change_device_orientation_(false),
+ orientation_pump_(orientation_pump) {}
+ ~MockDeviceOrientationController() override {}
+
+ void Trace(Visitor* visitor) override {
+ PlatformEventController::Trace(visitor);
+ visitor->Trace(orientation_pump_);
}
- ~MockDeviceOrientationListener() override {}
- void DidChangeDeviceOrientation(
- const device::OrientationData& data) override {
- memcpy(&data_, &data, sizeof(data));
- did_change_device_orientation_ = true;
- }
+ void DidUpdateData() override { did_change_device_orientation_ = true; }
bool did_change_device_orientation() const {
return did_change_device_orientation_;
@@ -44,25 +51,32 @@ class MockDeviceOrientationListener
void set_did_change_device_orientation(bool value) {
did_change_device_orientation_ = value;
}
- const device::OrientationData& data() const { return data_; }
- private:
- bool did_change_device_orientation_;
- device::OrientationData data_;
+ void RegisterWithDispatcher() override {
+ orientation_pump_->AddController(this);
+ }
- DISALLOW_COPY_AND_ASSIGN(MockDeviceOrientationListener);
-};
+ bool HasLastData() override {
+ return orientation_pump_->LatestDeviceOrientationData();
+ }
-class DeviceOrientationEventPumpForTesting : public DeviceOrientationEventPump {
- public:
- explicit DeviceOrientationEventPumpForTesting(
- scoped_refptr<base::SingleThreadTaskRunner> task_runner,
- bool absolute)
- : DeviceOrientationEventPump(task_runner, absolute) {}
- ~DeviceOrientationEventPumpForTesting() override {}
+ void UnregisterWithDispatcher() override {
+ orientation_pump_->RemoveController(this);
+ }
+
+ const DeviceOrientationData* data() {
+ return orientation_pump_->LatestDeviceOrientationData();
+ };
+
+ DeviceOrientationEventPump* orientation_pump() {
+ return orientation_pump_.Get();
+ }
private:
- DISALLOW_COPY_AND_ASSIGN(DeviceOrientationEventPumpForTesting);
+ bool did_change_device_orientation_;
+ Member<DeviceOrientationEventPump> orientation_pump_;
+
+ DISALLOW_COPY_AND_ASSIGN(MockDeviceOrientationController);
};
class DeviceOrientationEventPumpTest : public testing::Test {
@@ -71,95 +85,92 @@ class DeviceOrientationEventPumpTest : public testing::Test {
protected:
void SetUp() override {
- orientation_pump_.reset(new DeviceOrientationEventPumpForTesting(
- base::ThreadTaskRunnerHandle::Get(), false /* absolute */));
device::mojom::SensorProviderPtrInfo sensor_provider_ptr_info;
sensor_provider_.Bind(mojo::MakeRequest(&sensor_provider_ptr_info));
- orientation_pump_->SetSensorProviderForTesting(
+ auto* orientation_pump = new DeviceOrientationEventPump(
+ base::ThreadTaskRunnerHandle::Get(), false /* absolute */);
+ orientation_pump->SetSensorProviderForTesting(
device::mojom::blink::SensorProviderPtr(
device::mojom::blink::SensorProviderPtrInfo(
sensor_provider_ptr_info.PassHandle(),
device::mojom::SensorProvider::Version_)));
- listener_.reset(new MockDeviceOrientationListener);
+ controller_ = new MockDeviceOrientationController(orientation_pump);
ExpectRelativeOrientationSensorStateToBe(
DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
ExpectAbsoluteOrientationSensorStateToBe(
DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
EXPECT_EQ(DeviceOrientationEventPump::PumpState::STOPPED,
- orientation_pump()->GetPumpStateForTesting());
+ controller_->orientation_pump()->GetPumpStateForTesting());
}
- void FireEvent() { orientation_pump_->FireEvent(nullptr); }
+ void FireEvent() { controller_->orientation_pump()->FireEvent(nullptr); }
void ExpectRelativeOrientationSensorStateToBe(
DeviceOrientationEventPump::SensorState expected_sensor_state) {
EXPECT_EQ(expected_sensor_state,
- orientation_pump_->relative_orientation_sensor_.sensor_state);
+ controller_->orientation_pump()
+ ->relative_orientation_sensor_.sensor_state);
}
void ExpectAbsoluteOrientationSensorStateToBe(
DeviceOrientationEventPump::SensorState expected_sensor_state) {
EXPECT_EQ(expected_sensor_state,
- orientation_pump_->absolute_orientation_sensor_.sensor_state);
+ controller_->orientation_pump()
+ ->absolute_orientation_sensor_.sensor_state);
}
- DeviceOrientationEventPump* orientation_pump() {
- return orientation_pump_.get();
- }
-
- MockDeviceOrientationListener* listener() { return listener_.get(); }
+ MockDeviceOrientationController* controller() { return controller_.Get(); }
FakeSensorProvider* sensor_provider() { return &sensor_provider_; }
private:
- std::unique_ptr<DeviceOrientationEventPumpForTesting> orientation_pump_;
- std::unique_ptr<MockDeviceOrientationListener> listener_;
+ Persistent<MockDeviceOrientationController> controller_;
FakeSensorProvider sensor_provider_;
DISALLOW_COPY_AND_ASSIGN(DeviceOrientationEventPumpTest);
};
TEST_F(DeviceOrientationEventPumpTest, MultipleStartAndStopWithWait) {
- orientation_pump()->Start(nullptr, listener());
+ controller()->orientation_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectRelativeOrientationSensorStateToBe(
DeviceOrientationEventPump::SensorState::ACTIVE);
EXPECT_EQ(DeviceOrientationEventPump::PumpState::RUNNING,
- orientation_pump()->GetPumpStateForTesting());
+ controller()->orientation_pump()->GetPumpStateForTesting());
- orientation_pump()->Stop();
+ controller()->orientation_pump()->Stop();
base::RunLoop().RunUntilIdle();
ExpectRelativeOrientationSensorStateToBe(
DeviceOrientationEventPump::SensorState::SUSPENDED);
EXPECT_EQ(DeviceOrientationEventPump::PumpState::STOPPED,
- orientation_pump()->GetPumpStateForTesting());
+ controller()->orientation_pump()->GetPumpStateForTesting());
- orientation_pump()->Start(nullptr, listener());
+ controller()->orientation_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectRelativeOrientationSensorStateToBe(
DeviceOrientationEventPump::SensorState::ACTIVE);
EXPECT_EQ(DeviceOrientationEventPump::PumpState::RUNNING,
- orientation_pump()->GetPumpStateForTesting());
+ controller()->orientation_pump()->GetPumpStateForTesting());
- orientation_pump()->Stop();
+ controller()->orientation_pump()->Stop();
base::RunLoop().RunUntilIdle();
ExpectRelativeOrientationSensorStateToBe(
DeviceOrientationEventPump::SensorState::SUSPENDED);
EXPECT_EQ(DeviceOrientationEventPump::PumpState::STOPPED,
- orientation_pump()->GetPumpStateForTesting());
+ controller()->orientation_pump()->GetPumpStateForTesting());
}
TEST_F(DeviceOrientationEventPumpTest,
MultipleStartAndStopWithWaitWithSensorFallback) {
sensor_provider()->set_relative_orientation_sensor_is_available(false);
- orientation_pump()->Start(nullptr, listener());
+ controller()->orientation_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectRelativeOrientationSensorStateToBe(
@@ -167,9 +178,9 @@ TEST_F(DeviceOrientationEventPumpTest,
ExpectAbsoluteOrientationSensorStateToBe(
DeviceOrientationEventPump::SensorState::ACTIVE);
EXPECT_EQ(DeviceOrientationEventPump::PumpState::RUNNING,
- orientation_pump()->GetPumpStateForTesting());
+ controller()->orientation_pump()->GetPumpStateForTesting());
- orientation_pump()->Stop();
+ controller()->orientation_pump()->Stop();
base::RunLoop().RunUntilIdle();
ExpectRelativeOrientationSensorStateToBe(
@@ -177,9 +188,9 @@ TEST_F(DeviceOrientationEventPumpTest,
ExpectAbsoluteOrientationSensorStateToBe(
DeviceOrientationEventPump::SensorState::SUSPENDED);
EXPECT_EQ(DeviceOrientationEventPump::PumpState::STOPPED,
- orientation_pump()->GetPumpStateForTesting());
+ controller()->orientation_pump()->GetPumpStateForTesting());
- orientation_pump()->Start(nullptr, listener());
+ controller()->orientation_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectRelativeOrientationSensorStateToBe(
@@ -187,9 +198,9 @@ TEST_F(DeviceOrientationEventPumpTest,
ExpectAbsoluteOrientationSensorStateToBe(
DeviceOrientationEventPump::SensorState::ACTIVE);
EXPECT_EQ(DeviceOrientationEventPump::PumpState::RUNNING,
- orientation_pump()->GetPumpStateForTesting());
+ controller()->orientation_pump()->GetPumpStateForTesting());
- orientation_pump()->Stop();
+ controller()->orientation_pump()->Stop();
base::RunLoop().RunUntilIdle();
ExpectRelativeOrientationSensorStateToBe(
@@ -197,11 +208,11 @@ TEST_F(DeviceOrientationEventPumpTest,
ExpectAbsoluteOrientationSensorStateToBe(
DeviceOrientationEventPump::SensorState::SUSPENDED);
EXPECT_EQ(DeviceOrientationEventPump::PumpState::STOPPED,
- orientation_pump()->GetPumpStateForTesting());
+ controller()->orientation_pump()->GetPumpStateForTesting());
}
TEST_F(DeviceOrientationEventPumpTest, CallStop) {
- orientation_pump()->Stop();
+ controller()->orientation_pump()->Stop();
base::RunLoop().RunUntilIdle();
ExpectRelativeOrientationSensorStateToBe(
@@ -211,7 +222,7 @@ TEST_F(DeviceOrientationEventPumpTest, CallStop) {
TEST_F(DeviceOrientationEventPumpTest, CallStopWithSensorFallback) {
sensor_provider()->set_relative_orientation_sensor_is_available(false);
- orientation_pump()->Stop();
+ controller()->orientation_pump()->Stop();
base::RunLoop().RunUntilIdle();
ExpectRelativeOrientationSensorStateToBe(
@@ -221,8 +232,8 @@ TEST_F(DeviceOrientationEventPumpTest, CallStopWithSensorFallback) {
}
TEST_F(DeviceOrientationEventPumpTest, CallStartAndStop) {
- orientation_pump()->Start(nullptr, listener());
- orientation_pump()->Stop();
+ controller()->orientation_pump()->Start(nullptr);
+ controller()->orientation_pump()->Stop();
base::RunLoop().RunUntilIdle();
ExpectRelativeOrientationSensorStateToBe(
@@ -232,8 +243,8 @@ TEST_F(DeviceOrientationEventPumpTest, CallStartAndStop) {
TEST_F(DeviceOrientationEventPumpTest, CallStartAndStopWithSensorFallback) {
sensor_provider()->set_relative_orientation_sensor_is_available(false);
- orientation_pump()->Start(nullptr, listener());
- orientation_pump()->Stop();
+ controller()->orientation_pump()->Start(nullptr);
+ controller()->orientation_pump()->Stop();
base::RunLoop().RunUntilIdle();
ExpectRelativeOrientationSensorStateToBe(
@@ -243,9 +254,9 @@ TEST_F(DeviceOrientationEventPumpTest, CallStartAndStopWithSensorFallback) {
}
TEST_F(DeviceOrientationEventPumpTest, CallStartMultipleTimes) {
- orientation_pump()->Start(nullptr, listener());
- orientation_pump()->Start(nullptr, listener());
- orientation_pump()->Stop();
+ controller()->orientation_pump()->Start(nullptr);
+ controller()->orientation_pump()->Start(nullptr);
+ controller()->orientation_pump()->Stop();
base::RunLoop().RunUntilIdle();
ExpectRelativeOrientationSensorStateToBe(
@@ -256,9 +267,9 @@ TEST_F(DeviceOrientationEventPumpTest,
CallStartMultipleTimesWithSensorFallback) {
sensor_provider()->set_relative_orientation_sensor_is_available(false);
- orientation_pump()->Start(nullptr, listener());
- orientation_pump()->Start(nullptr, listener());
- orientation_pump()->Stop();
+ controller()->orientation_pump()->Start(nullptr);
+ controller()->orientation_pump()->Start(nullptr);
+ controller()->orientation_pump()->Stop();
base::RunLoop().RunUntilIdle();
ExpectRelativeOrientationSensorStateToBe(
@@ -268,9 +279,9 @@ TEST_F(DeviceOrientationEventPumpTest,
}
TEST_F(DeviceOrientationEventPumpTest, CallStopMultipleTimes) {
- orientation_pump()->Start(nullptr, listener());
- orientation_pump()->Stop();
- orientation_pump()->Stop();
+ controller()->orientation_pump()->Start(nullptr);
+ controller()->orientation_pump()->Stop();
+ controller()->orientation_pump()->Stop();
base::RunLoop().RunUntilIdle();
ExpectRelativeOrientationSensorStateToBe(
@@ -281,9 +292,9 @@ TEST_F(DeviceOrientationEventPumpTest,
CallStopMultipleTimesWithSensorFallback) {
sensor_provider()->set_relative_orientation_sensor_is_available(false);
- orientation_pump()->Start(nullptr, listener());
- orientation_pump()->Stop();
- orientation_pump()->Stop();
+ controller()->orientation_pump()->Start(nullptr);
+ controller()->orientation_pump()->Stop();
+ controller()->orientation_pump()->Stop();
base::RunLoop().RunUntilIdle();
ExpectRelativeOrientationSensorStateToBe(
@@ -294,15 +305,15 @@ TEST_F(DeviceOrientationEventPumpTest,
// Test a sequence of Start(), Stop(), Start() calls only bind sensor once.
TEST_F(DeviceOrientationEventPumpTest, SensorOnlyBindOnce) {
- orientation_pump()->Start(nullptr, listener());
- orientation_pump()->Stop();
- orientation_pump()->Start(nullptr, listener());
+ controller()->orientation_pump()->Start(nullptr);
+ controller()->orientation_pump()->Stop();
+ controller()->orientation_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectRelativeOrientationSensorStateToBe(
DeviceOrientationEventPump::SensorState::ACTIVE);
- orientation_pump()->Stop();
+ controller()->orientation_pump()->Stop();
ExpectRelativeOrientationSensorStateToBe(
DeviceOrientationEventPump::SensorState::SUSPENDED);
@@ -313,9 +324,9 @@ TEST_F(DeviceOrientationEventPumpTest, SensorOnlyBindOnce) {
TEST_F(DeviceOrientationEventPumpTest, SensorOnlyBindOnceWithSensorFallback) {
sensor_provider()->set_relative_orientation_sensor_is_available(false);
- orientation_pump()->Start(nullptr, listener());
- orientation_pump()->Stop();
- orientation_pump()->Start(nullptr, listener());
+ controller()->orientation_pump()->Start(nullptr);
+ controller()->orientation_pump()->Stop();
+ controller()->orientation_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectRelativeOrientationSensorStateToBe(
@@ -323,7 +334,7 @@ TEST_F(DeviceOrientationEventPumpTest, SensorOnlyBindOnceWithSensorFallback) {
ExpectAbsoluteOrientationSensorStateToBe(
DeviceOrientationEventPump::SensorState::ACTIVE);
- orientation_pump()->Stop();
+ controller()->orientation_pump()->Stop();
ExpectRelativeOrientationSensorStateToBe(
DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
@@ -332,7 +343,8 @@ TEST_F(DeviceOrientationEventPumpTest, SensorOnlyBindOnceWithSensorFallback) {
}
TEST_F(DeviceOrientationEventPumpTest, SensorIsActive) {
- orientation_pump()->Start(nullptr, listener());
+ controller()->RegisterWithDispatcher();
+ controller()->orientation_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectRelativeOrientationSensorStateToBe(
@@ -343,20 +355,20 @@ TEST_F(DeviceOrientationEventPumpTest, SensorIsActive) {
FireEvent();
- device::OrientationData received_data = listener()->data();
- EXPECT_TRUE(listener()->did_change_device_orientation());
+ const DeviceOrientationData* received_data = controller()->data();
+ EXPECT_TRUE(controller()->did_change_device_orientation());
// DeviceOrientation Event provides relative orientation data when it is
// available.
- EXPECT_DOUBLE_EQ(1, received_data.alpha);
- EXPECT_TRUE(received_data.has_alpha);
- EXPECT_DOUBLE_EQ(2, received_data.beta);
- EXPECT_TRUE(received_data.has_beta);
- EXPECT_DOUBLE_EQ(3, received_data.gamma);
- EXPECT_TRUE(received_data.has_gamma);
- EXPECT_FALSE(received_data.absolute);
+ EXPECT_DOUBLE_EQ(1, received_data->Alpha());
+ EXPECT_TRUE(received_data->CanProvideAlpha());
+ EXPECT_DOUBLE_EQ(2, received_data->Beta());
+ EXPECT_TRUE(received_data->CanProvideBeta());
+ EXPECT_DOUBLE_EQ(3, received_data->Gamma());
+ EXPECT_TRUE(received_data->CanProvideGamma());
+ EXPECT_FALSE(received_data->Absolute());
- orientation_pump()->Stop();
+ controller()->orientation_pump()->Stop();
ExpectRelativeOrientationSensorStateToBe(
DeviceOrientationEventPump::SensorState::SUSPENDED);
@@ -365,7 +377,8 @@ TEST_F(DeviceOrientationEventPumpTest, SensorIsActive) {
TEST_F(DeviceOrientationEventPumpTest, SensorIsActiveWithSensorFallback) {
sensor_provider()->set_relative_orientation_sensor_is_available(false);
- orientation_pump()->Start(nullptr, listener());
+ controller()->RegisterWithDispatcher();
+ controller()->orientation_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectRelativeOrientationSensorStateToBe(
@@ -378,23 +391,24 @@ TEST_F(DeviceOrientationEventPumpTest, SensorIsActiveWithSensorFallback) {
FireEvent();
- device::OrientationData received_data = listener()->data();
- EXPECT_TRUE(listener()->did_change_device_orientation());
+ const DeviceOrientationData* received_data = controller()->data();
+ EXPECT_TRUE(controller()->did_change_device_orientation());
// DeviceOrientation Event provides absolute orientation data when relative
// orientation data is not available but absolute orientation data is
// available.
- EXPECT_DOUBLE_EQ(4, received_data.alpha);
- EXPECT_TRUE(received_data.has_alpha);
- EXPECT_DOUBLE_EQ(5, received_data.beta);
- EXPECT_TRUE(received_data.has_beta);
- EXPECT_DOUBLE_EQ(6, received_data.gamma);
- EXPECT_TRUE(received_data.has_gamma);
+ EXPECT_DOUBLE_EQ(4, received_data->Alpha());
+ EXPECT_TRUE(received_data->CanProvideAlpha());
+ EXPECT_DOUBLE_EQ(5, received_data->Beta());
+ EXPECT_TRUE(received_data->CanProvideBeta());
+ EXPECT_DOUBLE_EQ(6, received_data->Gamma());
+ EXPECT_TRUE(received_data->CanProvideGamma());
+
// Since no relative orientation data is available, DeviceOrientationEvent
// fallback to provide absolute orientation data.
- EXPECT_TRUE(received_data.absolute);
+ EXPECT_TRUE(received_data->Absolute());
- orientation_pump()->Stop();
+ controller()->orientation_pump()->Stop();
ExpectRelativeOrientationSensorStateToBe(
DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
@@ -403,7 +417,8 @@ TEST_F(DeviceOrientationEventPumpTest, SensorIsActiveWithSensorFallback) {
}
TEST_F(DeviceOrientationEventPumpTest, SomeSensorDataFieldsNotAvailable) {
- orientation_pump()->Start(nullptr, listener());
+ controller()->RegisterWithDispatcher();
+ controller()->orientation_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectRelativeOrientationSensorStateToBe(
@@ -414,17 +429,17 @@ TEST_F(DeviceOrientationEventPumpTest, SomeSensorDataFieldsNotAvailable) {
FireEvent();
- device::OrientationData received_data = listener()->data();
- EXPECT_TRUE(listener()->did_change_device_orientation());
+ const DeviceOrientationData* received_data = controller()->data();
+ EXPECT_TRUE(controller()->did_change_device_orientation());
- EXPECT_FALSE(received_data.has_alpha);
- EXPECT_DOUBLE_EQ(2, received_data.beta);
- EXPECT_TRUE(received_data.has_beta);
- EXPECT_DOUBLE_EQ(3, received_data.gamma);
- EXPECT_TRUE(received_data.has_gamma);
- EXPECT_FALSE(received_data.absolute);
+ EXPECT_FALSE(received_data->CanProvideAlpha());
+ EXPECT_DOUBLE_EQ(2, received_data->Beta());
+ EXPECT_TRUE(received_data->CanProvideBeta());
+ EXPECT_DOUBLE_EQ(3, received_data->Gamma());
+ EXPECT_TRUE(received_data->CanProvideGamma());
+ EXPECT_FALSE(received_data->Absolute());
- orientation_pump()->Stop();
+ controller()->orientation_pump()->Stop();
ExpectRelativeOrientationSensorStateToBe(
DeviceOrientationEventPump::SensorState::SUSPENDED);
@@ -434,7 +449,8 @@ TEST_F(DeviceOrientationEventPumpTest,
SomeSensorDataFieldsNotAvailableWithSensorFallback) {
sensor_provider()->set_relative_orientation_sensor_is_available(false);
- orientation_pump()->Start(nullptr, listener());
+ controller()->RegisterWithDispatcher();
+ controller()->orientation_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectRelativeOrientationSensorStateToBe(
@@ -447,22 +463,22 @@ TEST_F(DeviceOrientationEventPumpTest,
FireEvent();
- device::OrientationData received_data = listener()->data();
- EXPECT_TRUE(listener()->did_change_device_orientation());
+ const DeviceOrientationData* received_data = controller()->data();
+ EXPECT_TRUE(controller()->did_change_device_orientation());
// DeviceOrientation Event provides absolute orientation data when relative
// orientation data is not available but absolute orientation data is
// available.
- EXPECT_DOUBLE_EQ(4, received_data.alpha);
- EXPECT_TRUE(received_data.has_alpha);
- EXPECT_FALSE(received_data.has_beta);
- EXPECT_DOUBLE_EQ(6, received_data.gamma);
- EXPECT_TRUE(received_data.has_gamma);
+ EXPECT_DOUBLE_EQ(4, received_data->Alpha());
+ EXPECT_TRUE(received_data->CanProvideAlpha());
+ EXPECT_FALSE(received_data->CanProvideBeta());
+ EXPECT_DOUBLE_EQ(6, received_data->Gamma());
+ EXPECT_TRUE(received_data->CanProvideGamma());
// Since no relative orientation data is available, DeviceOrientationEvent
// fallback to provide absolute orientation data.
- EXPECT_TRUE(received_data.absolute);
+ EXPECT_TRUE(received_data->Absolute());
- orientation_pump()->Stop();
+ controller()->orientation_pump()->Stop();
ExpectRelativeOrientationSensorStateToBe(
DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
@@ -475,7 +491,8 @@ TEST_F(DeviceOrientationEventPumpTest, FireAllNullEvent) {
sensor_provider()->set_relative_orientation_sensor_is_available(false);
sensor_provider()->set_absolute_orientation_sensor_is_available(false);
- orientation_pump()->Start(nullptr, listener());
+ controller()->RegisterWithDispatcher();
+ controller()->orientation_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectRelativeOrientationSensorStateToBe(
@@ -485,15 +502,15 @@ TEST_F(DeviceOrientationEventPumpTest, FireAllNullEvent) {
FireEvent();
- device::OrientationData received_data = listener()->data();
- EXPECT_TRUE(listener()->did_change_device_orientation());
+ const DeviceOrientationData* received_data = controller()->data();
+ EXPECT_TRUE(controller()->did_change_device_orientation());
- EXPECT_FALSE(received_data.has_alpha);
- EXPECT_FALSE(received_data.has_beta);
- EXPECT_FALSE(received_data.has_gamma);
- EXPECT_FALSE(received_data.absolute);
+ EXPECT_FALSE(received_data->CanProvideAlpha());
+ EXPECT_FALSE(received_data->CanProvideBeta());
+ EXPECT_FALSE(received_data->CanProvideGamma());
+ EXPECT_FALSE(received_data->Absolute());
- orientation_pump()->Stop();
+ controller()->orientation_pump()->Stop();
ExpectRelativeOrientationSensorStateToBe(
DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
@@ -503,7 +520,8 @@ TEST_F(DeviceOrientationEventPumpTest, FireAllNullEvent) {
TEST_F(DeviceOrientationEventPumpTest,
NotFireEventWhenSensorReadingTimeStampIsZero) {
- orientation_pump()->Start(nullptr, listener());
+ controller()->RegisterWithDispatcher();
+ controller()->orientation_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectRelativeOrientationSensorStateToBe(
@@ -511,9 +529,9 @@ TEST_F(DeviceOrientationEventPumpTest,
FireEvent();
- EXPECT_FALSE(listener()->did_change_device_orientation());
+ EXPECT_FALSE(controller()->did_change_device_orientation());
- orientation_pump()->Stop();
+ controller()->orientation_pump()->Stop();
ExpectRelativeOrientationSensorStateToBe(
DeviceOrientationEventPump::SensorState::SUSPENDED);
@@ -523,7 +541,8 @@ TEST_F(DeviceOrientationEventPumpTest,
NotFireEventWhenSensorReadingTimeStampIsZeroWithSensorFallback) {
sensor_provider()->set_relative_orientation_sensor_is_available(false);
- orientation_pump()->Start(nullptr, listener());
+ controller()->RegisterWithDispatcher();
+ controller()->orientation_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectRelativeOrientationSensorStateToBe(
@@ -533,9 +552,9 @@ TEST_F(DeviceOrientationEventPumpTest,
FireEvent();
- EXPECT_FALSE(listener()->did_change_device_orientation());
+ EXPECT_FALSE(controller()->did_change_device_orientation());
- orientation_pump()->Stop();
+ controller()->orientation_pump()->Stop();
ExpectRelativeOrientationSensorStateToBe(
DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
@@ -544,7 +563,8 @@ TEST_F(DeviceOrientationEventPumpTest,
}
TEST_F(DeviceOrientationEventPumpTest, UpdateRespectsOrientationThreshold) {
- orientation_pump()->Start(nullptr, listener());
+ controller()->RegisterWithDispatcher();
+ controller()->orientation_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectRelativeOrientationSensorStateToBe(
@@ -555,20 +575,20 @@ TEST_F(DeviceOrientationEventPumpTest, UpdateRespectsOrientationThreshold) {
FireEvent();
- device::OrientationData received_data = listener()->data();
- EXPECT_TRUE(listener()->did_change_device_orientation());
+ const DeviceOrientationData* received_data = controller()->data();
+ EXPECT_TRUE(controller()->did_change_device_orientation());
// DeviceOrientation Event provides relative orientation data when it is
// available.
- EXPECT_DOUBLE_EQ(1, received_data.alpha);
- EXPECT_TRUE(received_data.has_alpha);
- EXPECT_DOUBLE_EQ(2, received_data.beta);
- EXPECT_TRUE(received_data.has_beta);
- EXPECT_DOUBLE_EQ(3, received_data.gamma);
- EXPECT_TRUE(received_data.has_gamma);
- EXPECT_FALSE(received_data.absolute);
+ EXPECT_DOUBLE_EQ(1, received_data->Alpha());
+ EXPECT_TRUE(received_data->CanProvideAlpha());
+ EXPECT_DOUBLE_EQ(2, received_data->Beta());
+ EXPECT_TRUE(received_data->CanProvideBeta());
+ EXPECT_DOUBLE_EQ(3, received_data->Gamma());
+ EXPECT_TRUE(received_data->CanProvideGamma());
+ EXPECT_FALSE(received_data->Absolute());
- listener()->set_did_change_device_orientation(false);
+ controller()->set_did_change_device_orientation(false);
sensor_provider()->UpdateRelativeOrientationSensorData(
1 + DeviceOrientationEventPump::kOrientationThreshold / 2.0 /* alpha */,
@@ -576,18 +596,18 @@ TEST_F(DeviceOrientationEventPumpTest, UpdateRespectsOrientationThreshold) {
FireEvent();
- received_data = listener()->data();
- EXPECT_FALSE(listener()->did_change_device_orientation());
+ received_data = controller()->data();
+ EXPECT_FALSE(controller()->did_change_device_orientation());
- EXPECT_DOUBLE_EQ(1, received_data.alpha);
- EXPECT_TRUE(received_data.has_alpha);
- EXPECT_DOUBLE_EQ(2, received_data.beta);
- EXPECT_TRUE(received_data.has_beta);
- EXPECT_DOUBLE_EQ(3, received_data.gamma);
- EXPECT_TRUE(received_data.has_gamma);
- EXPECT_FALSE(received_data.absolute);
+ EXPECT_DOUBLE_EQ(1, received_data->Alpha());
+ EXPECT_TRUE(received_data->CanProvideAlpha());
+ EXPECT_DOUBLE_EQ(2, received_data->Beta());
+ EXPECT_TRUE(received_data->CanProvideBeta());
+ EXPECT_DOUBLE_EQ(3, received_data->Gamma());
+ EXPECT_TRUE(received_data->CanProvideGamma());
+ EXPECT_FALSE(received_data->Absolute());
- listener()->set_did_change_device_orientation(false);
+ controller()->set_did_change_device_orientation(false);
sensor_provider()->UpdateRelativeOrientationSensorData(
1 + DeviceOrientationEventPump::kOrientationThreshold /* alpha */,
@@ -595,19 +615,19 @@ TEST_F(DeviceOrientationEventPumpTest, UpdateRespectsOrientationThreshold) {
FireEvent();
- received_data = listener()->data();
- EXPECT_TRUE(listener()->did_change_device_orientation());
+ received_data = controller()->data();
+ EXPECT_TRUE(controller()->did_change_device_orientation());
EXPECT_DOUBLE_EQ(1 + DeviceOrientationEventPump::kOrientationThreshold,
- received_data.alpha);
- EXPECT_TRUE(received_data.has_alpha);
- EXPECT_DOUBLE_EQ(2, received_data.beta);
- EXPECT_TRUE(received_data.has_beta);
- EXPECT_DOUBLE_EQ(3, received_data.gamma);
- EXPECT_TRUE(received_data.has_gamma);
- EXPECT_FALSE(received_data.absolute);
+ received_data->Alpha());
+ EXPECT_TRUE(received_data->CanProvideAlpha());
+ EXPECT_DOUBLE_EQ(2, received_data->Beta());
+ EXPECT_TRUE(received_data->CanProvideBeta());
+ EXPECT_DOUBLE_EQ(3, received_data->Gamma());
+ EXPECT_TRUE(received_data->CanProvideGamma());
+ EXPECT_FALSE(received_data->Absolute());
- orientation_pump()->Stop();
+ controller()->orientation_pump()->Stop();
ExpectRelativeOrientationSensorStateToBe(
DeviceOrientationEventPump::SensorState::SUSPENDED);
@@ -617,7 +637,8 @@ TEST_F(DeviceOrientationEventPumpTest,
UpdateRespectsOrientationThresholdWithSensorFallback) {
sensor_provider()->set_relative_orientation_sensor_is_available(false);
- orientation_pump()->Start(nullptr, listener());
+ controller()->RegisterWithDispatcher();
+ controller()->orientation_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectRelativeOrientationSensorStateToBe(
@@ -630,23 +651,23 @@ TEST_F(DeviceOrientationEventPumpTest,
FireEvent();
- device::OrientationData received_data = listener()->data();
- EXPECT_TRUE(listener()->did_change_device_orientation());
+ const DeviceOrientationData* received_data = controller()->data();
+ EXPECT_TRUE(controller()->did_change_device_orientation());
// DeviceOrientation Event provides absolute orientation data when relative
// orientation data is not available but absolute orientation data is
// available.
- EXPECT_DOUBLE_EQ(4, received_data.alpha);
- EXPECT_TRUE(received_data.has_alpha);
- EXPECT_DOUBLE_EQ(5, received_data.beta);
- EXPECT_TRUE(received_data.has_beta);
- EXPECT_DOUBLE_EQ(6, received_data.gamma);
- EXPECT_TRUE(received_data.has_gamma);
+ EXPECT_DOUBLE_EQ(4, received_data->Alpha());
+ EXPECT_TRUE(received_data->CanProvideAlpha());
+ EXPECT_DOUBLE_EQ(5, received_data->Beta());
+ EXPECT_TRUE(received_data->CanProvideBeta());
+ EXPECT_DOUBLE_EQ(6, received_data->Gamma());
+ EXPECT_TRUE(received_data->CanProvideGamma());
// Since no relative orientation data is available, DeviceOrientationEvent
// fallback to provide absolute orientation data.
- EXPECT_TRUE(received_data.absolute);
+ EXPECT_TRUE(received_data->Absolute());
- listener()->set_did_change_device_orientation(false);
+ controller()->set_did_change_device_orientation(false);
sensor_provider()->UpdateAbsoluteOrientationSensorData(
4 /* alpha */,
@@ -655,18 +676,18 @@ TEST_F(DeviceOrientationEventPumpTest,
FireEvent();
- received_data = listener()->data();
- EXPECT_FALSE(listener()->did_change_device_orientation());
+ received_data = controller()->data();
+ EXPECT_FALSE(controller()->did_change_device_orientation());
- EXPECT_DOUBLE_EQ(4, received_data.alpha);
- EXPECT_TRUE(received_data.has_alpha);
- EXPECT_DOUBLE_EQ(5, received_data.beta);
- EXPECT_TRUE(received_data.has_beta);
- EXPECT_DOUBLE_EQ(6, received_data.gamma);
- EXPECT_TRUE(received_data.has_gamma);
- EXPECT_TRUE(received_data.absolute);
+ EXPECT_DOUBLE_EQ(4, received_data->Alpha());
+ EXPECT_TRUE(received_data->CanProvideAlpha());
+ EXPECT_DOUBLE_EQ(5, received_data->Beta());
+ EXPECT_TRUE(received_data->CanProvideBeta());
+ EXPECT_DOUBLE_EQ(6, received_data->Gamma());
+ EXPECT_TRUE(received_data->CanProvideGamma());
+ EXPECT_TRUE(received_data->Absolute());
- listener()->set_did_change_device_orientation(false);
+ controller()->set_did_change_device_orientation(false);
sensor_provider()->UpdateAbsoluteOrientationSensorData(
4 /* alpha */,
@@ -676,20 +697,20 @@ TEST_F(DeviceOrientationEventPumpTest,
FireEvent();
- received_data = listener()->data();
- EXPECT_TRUE(listener()->did_change_device_orientation());
+ received_data = controller()->data();
+ EXPECT_TRUE(controller()->did_change_device_orientation());
- EXPECT_DOUBLE_EQ(4, received_data.alpha);
- EXPECT_TRUE(received_data.has_alpha);
+ EXPECT_DOUBLE_EQ(4, received_data->Alpha());
+ EXPECT_TRUE(received_data->CanProvideAlpha());
EXPECT_DOUBLE_EQ(
5 + DeviceOrientationEventPump::kOrientationThreshold + kEpsilon,
- received_data.beta);
- EXPECT_TRUE(received_data.has_beta);
- EXPECT_DOUBLE_EQ(6, received_data.gamma);
- EXPECT_TRUE(received_data.has_gamma);
- EXPECT_TRUE(received_data.absolute);
+ received_data->Beta());
+ EXPECT_TRUE(received_data->CanProvideBeta());
+ EXPECT_DOUBLE_EQ(6, received_data->Gamma());
+ EXPECT_TRUE(received_data->CanProvideGamma());
+ EXPECT_TRUE(received_data->Absolute());
- orientation_pump()->Stop();
+ controller()->orientation_pump()->Stop();
ExpectRelativeOrientationSensorStateToBe(
DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
@@ -703,85 +724,80 @@ class DeviceAbsoluteOrientationEventPumpTest : public testing::Test {
protected:
void SetUp() override {
- absolute_orientation_pump_.reset(new DeviceOrientationEventPumpForTesting(
- base::ThreadTaskRunnerHandle::Get(), true /* absolute */));
device::mojom::SensorProviderPtrInfo sensor_provider_ptr_info;
sensor_provider_.Bind(mojo::MakeRequest(&sensor_provider_ptr_info));
- absolute_orientation_pump_->SetSensorProviderForTesting(
+ auto* absolute_orientation_pump = new DeviceOrientationEventPump(
+ base::ThreadTaskRunnerHandle::Get(), true /* absolute */);
+ absolute_orientation_pump->SetSensorProviderForTesting(
device::mojom::blink::SensorProviderPtr(
device::mojom::blink::SensorProviderPtrInfo(
sensor_provider_ptr_info.PassHandle(),
device::mojom::SensorProvider::Version_)));
- listener_.reset(new MockDeviceOrientationListener);
+ controller_ =
+ new MockDeviceOrientationController(absolute_orientation_pump);
ExpectAbsoluteOrientationSensorStateToBe(
DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
EXPECT_EQ(DeviceOrientationEventPump::PumpState::STOPPED,
- absolute_orientation_pump()->GetPumpStateForTesting());
+ controller_->orientation_pump()->GetPumpStateForTesting());
}
- void FireEvent() { absolute_orientation_pump_->FireEvent(nullptr); }
+ void FireEvent() { controller_->orientation_pump()->FireEvent(nullptr); }
void ExpectAbsoluteOrientationSensorStateToBe(
DeviceOrientationEventPump::SensorState expected_sensor_state) {
- EXPECT_EQ(
- expected_sensor_state,
- absolute_orientation_pump_->absolute_orientation_sensor_.sensor_state);
- }
-
- DeviceOrientationEventPump* absolute_orientation_pump() {
- return absolute_orientation_pump_.get();
+ EXPECT_EQ(expected_sensor_state,
+ controller_->orientation_pump()
+ ->absolute_orientation_sensor_.sensor_state);
}
- MockDeviceOrientationListener* listener() { return listener_.get(); }
+ MockDeviceOrientationController* controller() { return controller_.Get(); }
FakeSensorProvider* sensor_provider() { return &sensor_provider_; }
private:
- std::unique_ptr<DeviceOrientationEventPumpForTesting>
- absolute_orientation_pump_;
- std::unique_ptr<MockDeviceOrientationListener> listener_;
+ Persistent<MockDeviceOrientationController> controller_;
FakeSensorProvider sensor_provider_;
DISALLOW_COPY_AND_ASSIGN(DeviceAbsoluteOrientationEventPumpTest);
};
TEST_F(DeviceAbsoluteOrientationEventPumpTest, MultipleStartAndStopWithWait) {
- absolute_orientation_pump()->Start(nullptr, listener());
+ controller()->orientation_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectAbsoluteOrientationSensorStateToBe(
DeviceOrientationEventPump::SensorState::ACTIVE);
EXPECT_EQ(DeviceOrientationEventPump::PumpState::RUNNING,
- absolute_orientation_pump()->GetPumpStateForTesting());
+ controller()->orientation_pump()->GetPumpStateForTesting());
- absolute_orientation_pump()->Stop();
+ controller()->orientation_pump()->Stop();
base::RunLoop().RunUntilIdle();
ExpectAbsoluteOrientationSensorStateToBe(
DeviceOrientationEventPump::SensorState::SUSPENDED);
EXPECT_EQ(DeviceOrientationEventPump::PumpState::STOPPED,
- absolute_orientation_pump()->GetPumpStateForTesting());
+ controller()->orientation_pump()->GetPumpStateForTesting());
- absolute_orientation_pump()->Start(nullptr, listener());
+ controller()->orientation_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectAbsoluteOrientationSensorStateToBe(
DeviceOrientationEventPump::SensorState::ACTIVE);
EXPECT_EQ(DeviceOrientationEventPump::PumpState::RUNNING,
- absolute_orientation_pump()->GetPumpStateForTesting());
+ controller()->orientation_pump()->GetPumpStateForTesting());
- absolute_orientation_pump()->Stop();
+ controller()->orientation_pump()->Stop();
base::RunLoop().RunUntilIdle();
ExpectAbsoluteOrientationSensorStateToBe(
DeviceOrientationEventPump::SensorState::SUSPENDED);
EXPECT_EQ(DeviceOrientationEventPump::PumpState::STOPPED,
- absolute_orientation_pump()->GetPumpStateForTesting());
+ controller()->orientation_pump()->GetPumpStateForTesting());
}
TEST_F(DeviceAbsoluteOrientationEventPumpTest, CallStop) {
- absolute_orientation_pump()->Stop();
+ controller()->orientation_pump()->Stop();
base::RunLoop().RunUntilIdle();
ExpectAbsoluteOrientationSensorStateToBe(
@@ -789,8 +805,8 @@ TEST_F(DeviceAbsoluteOrientationEventPumpTest, CallStop) {
}
TEST_F(DeviceAbsoluteOrientationEventPumpTest, CallStartAndStop) {
- absolute_orientation_pump()->Start(nullptr, listener());
- absolute_orientation_pump()->Stop();
+ controller()->orientation_pump()->Start(nullptr);
+ controller()->orientation_pump()->Stop();
base::RunLoop().RunUntilIdle();
ExpectAbsoluteOrientationSensorStateToBe(
@@ -798,9 +814,9 @@ TEST_F(DeviceAbsoluteOrientationEventPumpTest, CallStartAndStop) {
}
TEST_F(DeviceAbsoluteOrientationEventPumpTest, CallStartMultipleTimes) {
- absolute_orientation_pump()->Start(nullptr, listener());
- absolute_orientation_pump()->Start(nullptr, listener());
- absolute_orientation_pump()->Stop();
+ controller()->orientation_pump()->Start(nullptr);
+ controller()->orientation_pump()->Start(nullptr);
+ controller()->orientation_pump()->Stop();
base::RunLoop().RunUntilIdle();
ExpectAbsoluteOrientationSensorStateToBe(
@@ -808,9 +824,9 @@ TEST_F(DeviceAbsoluteOrientationEventPumpTest, CallStartMultipleTimes) {
}
TEST_F(DeviceAbsoluteOrientationEventPumpTest, CallStopMultipleTimes) {
- absolute_orientation_pump()->Start(nullptr, listener());
- absolute_orientation_pump()->Stop();
- absolute_orientation_pump()->Stop();
+ controller()->orientation_pump()->Start(nullptr);
+ controller()->orientation_pump()->Stop();
+ controller()->orientation_pump()->Stop();
base::RunLoop().RunUntilIdle();
ExpectAbsoluteOrientationSensorStateToBe(
@@ -819,22 +835,23 @@ TEST_F(DeviceAbsoluteOrientationEventPumpTest, CallStopMultipleTimes) {
// Test multiple DeviceSensorEventPump::Start() calls only bind sensor once.
TEST_F(DeviceAbsoluteOrientationEventPumpTest, SensorOnlyBindOnce) {
- absolute_orientation_pump()->Start(nullptr, listener());
- absolute_orientation_pump()->Stop();
- absolute_orientation_pump()->Start(nullptr, listener());
+ controller()->orientation_pump()->Start(nullptr);
+ controller()->orientation_pump()->Stop();
+ controller()->orientation_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectAbsoluteOrientationSensorStateToBe(
DeviceOrientationEventPump::SensorState::ACTIVE);
- absolute_orientation_pump()->Stop();
+ controller()->orientation_pump()->Stop();
ExpectAbsoluteOrientationSensorStateToBe(
DeviceOrientationEventPump::SensorState::SUSPENDED);
}
TEST_F(DeviceAbsoluteOrientationEventPumpTest, SensorIsActive) {
- absolute_orientation_pump()->Start(nullptr, listener());
+ controller()->RegisterWithDispatcher();
+ controller()->orientation_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectAbsoluteOrientationSensorStateToBe(
@@ -845,18 +862,18 @@ TEST_F(DeviceAbsoluteOrientationEventPumpTest, SensorIsActive) {
FireEvent();
- device::OrientationData received_data = listener()->data();
- EXPECT_TRUE(listener()->did_change_device_orientation());
+ const DeviceOrientationData* received_data = controller()->data();
+ EXPECT_TRUE(controller()->did_change_device_orientation());
- EXPECT_DOUBLE_EQ(4, received_data.alpha);
- EXPECT_TRUE(received_data.has_alpha);
- EXPECT_DOUBLE_EQ(5, received_data.beta);
- EXPECT_TRUE(received_data.has_beta);
- EXPECT_DOUBLE_EQ(6, received_data.gamma);
- EXPECT_TRUE(received_data.has_gamma);
- EXPECT_TRUE(received_data.absolute);
+ EXPECT_DOUBLE_EQ(4, received_data->Alpha());
+ EXPECT_TRUE(received_data->CanProvideAlpha());
+ EXPECT_DOUBLE_EQ(5, received_data->Beta());
+ EXPECT_TRUE(received_data->CanProvideBeta());
+ EXPECT_DOUBLE_EQ(6, received_data->Gamma());
+ EXPECT_TRUE(received_data->CanProvideGamma());
+ EXPECT_TRUE(received_data->Absolute());
- absolute_orientation_pump()->Stop();
+ controller()->orientation_pump()->Stop();
ExpectAbsoluteOrientationSensorStateToBe(
DeviceOrientationEventPump::SensorState::SUSPENDED);
@@ -864,7 +881,8 @@ TEST_F(DeviceAbsoluteOrientationEventPumpTest, SensorIsActive) {
TEST_F(DeviceAbsoluteOrientationEventPumpTest,
SomeSensorDataFieldsNotAvailable) {
- absolute_orientation_pump()->Start(nullptr, listener());
+ controller()->RegisterWithDispatcher();
+ controller()->orientation_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectAbsoluteOrientationSensorStateToBe(
@@ -875,17 +893,17 @@ TEST_F(DeviceAbsoluteOrientationEventPumpTest,
FireEvent();
- device::OrientationData received_data = listener()->data();
- EXPECT_TRUE(listener()->did_change_device_orientation());
+ const DeviceOrientationData* received_data = controller()->data();
+ EXPECT_TRUE(controller()->did_change_device_orientation());
- EXPECT_DOUBLE_EQ(4, received_data.alpha);
- EXPECT_TRUE(received_data.has_alpha);
- EXPECT_FALSE(received_data.has_beta);
- EXPECT_DOUBLE_EQ(6, received_data.gamma);
- EXPECT_TRUE(received_data.has_gamma);
- EXPECT_TRUE(received_data.absolute);
+ EXPECT_DOUBLE_EQ(4, received_data->Alpha());
+ EXPECT_TRUE(received_data->CanProvideAlpha());
+ EXPECT_FALSE(received_data->CanProvideBeta());
+ EXPECT_DOUBLE_EQ(6, received_data->Gamma());
+ EXPECT_TRUE(received_data->CanProvideGamma());
+ EXPECT_TRUE(received_data->Absolute());
- absolute_orientation_pump()->Stop();
+ controller()->orientation_pump()->Stop();
ExpectAbsoluteOrientationSensorStateToBe(
DeviceOrientationEventPump::SensorState::SUSPENDED);
@@ -895,7 +913,8 @@ TEST_F(DeviceAbsoluteOrientationEventPumpTest, FireAllNullEvent) {
// No active sensor.
sensor_provider()->set_absolute_orientation_sensor_is_available(false);
- absolute_orientation_pump()->Start(nullptr, listener());
+ controller()->RegisterWithDispatcher();
+ controller()->orientation_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectAbsoluteOrientationSensorStateToBe(
@@ -903,15 +922,15 @@ TEST_F(DeviceAbsoluteOrientationEventPumpTest, FireAllNullEvent) {
FireEvent();
- device::OrientationData received_data = listener()->data();
- EXPECT_TRUE(listener()->did_change_device_orientation());
+ const DeviceOrientationData* received_data = controller()->data();
+ EXPECT_TRUE(controller()->did_change_device_orientation());
- EXPECT_FALSE(received_data.has_alpha);
- EXPECT_FALSE(received_data.has_beta);
- EXPECT_FALSE(received_data.has_gamma);
- EXPECT_TRUE(received_data.absolute);
+ EXPECT_FALSE(received_data->CanProvideAlpha());
+ EXPECT_FALSE(received_data->CanProvideBeta());
+ EXPECT_FALSE(received_data->CanProvideGamma());
+ EXPECT_TRUE(received_data->Absolute());
- absolute_orientation_pump()->Stop();
+ controller()->orientation_pump()->Stop();
ExpectAbsoluteOrientationSensorStateToBe(
DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
@@ -919,7 +938,8 @@ TEST_F(DeviceAbsoluteOrientationEventPumpTest, FireAllNullEvent) {
TEST_F(DeviceAbsoluteOrientationEventPumpTest,
NotFireEventWhenSensorReadingTimeStampIsZero) {
- absolute_orientation_pump()->Start(nullptr, listener());
+ controller()->RegisterWithDispatcher();
+ controller()->orientation_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectAbsoluteOrientationSensorStateToBe(
@@ -927,9 +947,9 @@ TEST_F(DeviceAbsoluteOrientationEventPumpTest,
FireEvent();
- EXPECT_FALSE(listener()->did_change_device_orientation());
+ EXPECT_FALSE(controller()->did_change_device_orientation());
- absolute_orientation_pump()->Stop();
+ controller()->orientation_pump()->Stop();
ExpectAbsoluteOrientationSensorStateToBe(
DeviceOrientationEventPump::SensorState::SUSPENDED);
@@ -937,7 +957,8 @@ TEST_F(DeviceAbsoluteOrientationEventPumpTest,
TEST_F(DeviceAbsoluteOrientationEventPumpTest,
UpdateRespectsOrientationThreshold) {
- absolute_orientation_pump()->Start(nullptr, listener());
+ controller()->RegisterWithDispatcher();
+ controller()->orientation_pump()->Start(nullptr);
base::RunLoop().RunUntilIdle();
ExpectAbsoluteOrientationSensorStateToBe(
@@ -948,18 +969,18 @@ TEST_F(DeviceAbsoluteOrientationEventPumpTest,
FireEvent();
- device::OrientationData received_data = listener()->data();
- EXPECT_TRUE(listener()->did_change_device_orientation());
+ const DeviceOrientationData* received_data = controller()->data();
+ EXPECT_TRUE(controller()->did_change_device_orientation());
- EXPECT_DOUBLE_EQ(4, received_data.alpha);
- EXPECT_TRUE(received_data.has_alpha);
- EXPECT_DOUBLE_EQ(5, received_data.beta);
- EXPECT_TRUE(received_data.has_beta);
- EXPECT_DOUBLE_EQ(6, received_data.gamma);
- EXPECT_TRUE(received_data.has_gamma);
- EXPECT_TRUE(received_data.absolute);
+ EXPECT_DOUBLE_EQ(4, received_data->Alpha());
+ EXPECT_TRUE(received_data->CanProvideAlpha());
+ EXPECT_DOUBLE_EQ(5, received_data->Beta());
+ EXPECT_TRUE(received_data->CanProvideBeta());
+ EXPECT_DOUBLE_EQ(6, received_data->Gamma());
+ EXPECT_TRUE(received_data->CanProvideGamma());
+ EXPECT_TRUE(received_data->Absolute());
- listener()->set_did_change_device_orientation(false);
+ controller()->set_did_change_device_orientation(false);
sensor_provider()->UpdateAbsoluteOrientationSensorData(
4 /* alpha */,
@@ -968,18 +989,18 @@ TEST_F(DeviceAbsoluteOrientationEventPumpTest,
FireEvent();
- received_data = listener()->data();
- EXPECT_FALSE(listener()->did_change_device_orientation());
+ received_data = controller()->data();
+ EXPECT_FALSE(controller()->did_change_device_orientation());
- EXPECT_DOUBLE_EQ(4, received_data.alpha);
- EXPECT_TRUE(received_data.has_alpha);
- EXPECT_DOUBLE_EQ(5, received_data.beta);
- EXPECT_TRUE(received_data.has_beta);
- EXPECT_DOUBLE_EQ(6, received_data.gamma);
- EXPECT_TRUE(received_data.has_gamma);
- EXPECT_TRUE(received_data.absolute);
+ EXPECT_DOUBLE_EQ(4, received_data->Alpha());
+ EXPECT_TRUE(received_data->CanProvideAlpha());
+ EXPECT_DOUBLE_EQ(5, received_data->Beta());
+ EXPECT_TRUE(received_data->CanProvideBeta());
+ EXPECT_DOUBLE_EQ(6, received_data->Gamma());
+ EXPECT_TRUE(received_data->CanProvideGamma());
+ EXPECT_TRUE(received_data->Absolute());
- listener()->set_did_change_device_orientation(false);
+ controller()->set_did_change_device_orientation(false);
sensor_provider()->UpdateAbsoluteOrientationSensorData(
4 /* alpha */,
@@ -989,20 +1010,20 @@ TEST_F(DeviceAbsoluteOrientationEventPumpTest,
FireEvent();
- received_data = listener()->data();
- EXPECT_TRUE(listener()->did_change_device_orientation());
+ received_data = controller()->data();
+ EXPECT_TRUE(controller()->did_change_device_orientation());
- EXPECT_DOUBLE_EQ(4, received_data.alpha);
- EXPECT_TRUE(received_data.has_alpha);
+ EXPECT_DOUBLE_EQ(4, received_data->Alpha());
+ EXPECT_TRUE(received_data->CanProvideAlpha());
EXPECT_DOUBLE_EQ(
5 + DeviceOrientationEventPump::kOrientationThreshold + kEpsilon,
- received_data.beta);
- EXPECT_TRUE(received_data.has_beta);
- EXPECT_DOUBLE_EQ(6, received_data.gamma);
- EXPECT_TRUE(received_data.has_gamma);
- EXPECT_TRUE(received_data.absolute);
+ received_data->Beta());
+ EXPECT_TRUE(received_data->CanProvideBeta());
+ EXPECT_DOUBLE_EQ(6, received_data->Gamma());
+ EXPECT_TRUE(received_data->CanProvideGamma());
+ EXPECT_TRUE(received_data->Absolute());
- absolute_orientation_pump()->Stop();
+ controller()->orientation_pump()->Stop();
ExpectAbsoluteOrientationSensorStateToBe(
DeviceOrientationEventPump::SensorState::SUSPENDED);
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_inspector_agent.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_inspector_agent.cc
index c9144c4fde2..5e777aab9b4 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
@@ -15,19 +15,16 @@ namespace blink {
using protocol::Response;
-namespace DeviceOrientationInspectorAgentState {
-static const char kAlpha[] = "alpha";
-static const char kBeta[] = "beta";
-static const char kGamma[] = "gamma";
-static const char kOverrideEnabled[] = "overrideEnabled";
-}
-
DeviceOrientationInspectorAgent::~DeviceOrientationInspectorAgent() = default;
DeviceOrientationInspectorAgent::DeviceOrientationInspectorAgent(
InspectedFrames* inspected_frames)
: inspected_frames_(inspected_frames),
- sensor_agent_(new SensorInspectorAgent(inspected_frames->Root())) {}
+ sensor_agent_(new SensorInspectorAgent(inspected_frames->Root())),
+ enabled_(&agent_state_, /*default_value=*/false),
+ alpha_(&agent_state_, /*default_value=*/0.0),
+ beta_(&agent_state_, /*default_value=*/0.0),
+ gamma_(&agent_state_, /*default_value=*/0.0) {}
void DeviceOrientationInspectorAgent::Trace(blink::Visitor* visitor) {
visitor->Trace(inspected_frames_);
@@ -44,11 +41,10 @@ Response DeviceOrientationInspectorAgent::setDeviceOrientationOverride(
double alpha,
double beta,
double gamma) {
- state_->setBoolean(DeviceOrientationInspectorAgentState::kOverrideEnabled,
- true);
- state_->setDouble(DeviceOrientationInspectorAgentState::kAlpha, alpha);
- state_->setDouble(DeviceOrientationInspectorAgentState::kBeta, beta);
- state_->setDouble(DeviceOrientationInspectorAgentState::kGamma, gamma);
+ enabled_.Set(true);
+ alpha_.Set(alpha);
+ beta_.Set(beta);
+ gamma_.Set(gamma);
if (Controller()) {
Controller()->SetOverride(
DeviceOrientationData::Create(alpha, beta, gamma, false));
@@ -58,17 +54,11 @@ Response DeviceOrientationInspectorAgent::setDeviceOrientationOverride(
}
Response DeviceOrientationInspectorAgent::clearDeviceOrientationOverride() {
- state_->setBoolean(DeviceOrientationInspectorAgentState::kOverrideEnabled,
- false);
- if (Controller())
- Controller()->ClearOverride();
- sensor_agent_->Disable();
- return Response::OK();
+ return disable();
}
Response DeviceOrientationInspectorAgent::disable() {
- state_->setBoolean(DeviceOrientationInspectorAgentState::kOverrideEnabled,
- false);
+ agent_state_.ClearAllFields();
if (Controller())
Controller()->ClearOverride();
sensor_agent_->Disable();
@@ -76,20 +66,12 @@ Response DeviceOrientationInspectorAgent::disable() {
}
void DeviceOrientationInspectorAgent::Restore() {
- if (!Controller())
+ if (!Controller() || !enabled_.Get())
return;
- if (state_->booleanProperty(
- DeviceOrientationInspectorAgentState::kOverrideEnabled, false)) {
- double alpha = 0;
- state_->getDouble(DeviceOrientationInspectorAgentState::kAlpha, &alpha);
- double beta = 0;
- state_->getDouble(DeviceOrientationInspectorAgentState::kBeta, &beta);
- double gamma = 0;
- state_->getDouble(DeviceOrientationInspectorAgentState::kGamma, &gamma);
- Controller()->SetOverride(
- DeviceOrientationData::Create(alpha, beta, gamma, false));
- sensor_agent_->SetOrientationSensorOverride(alpha, beta, gamma);
- }
+ Controller()->SetOverride(DeviceOrientationData::Create(
+ alpha_.Get(), beta_.Get(), gamma_.Get(), false));
+ sensor_agent_->SetOrientationSensorOverride(alpha_.Get(), beta_.Get(),
+ gamma_.Get());
}
void DeviceOrientationInspectorAgent::DidCommitLoadForLocalFrame(
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 67cdd984b70..e9d4bb27b00 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
@@ -38,7 +38,10 @@ class MODULES_EXPORT DeviceOrientationInspectorAgent final
Member<InspectedFrames> inspected_frames_;
Member<SensorInspectorAgent> sensor_agent_;
-
+ InspectorAgentState::Boolean enabled_;
+ InspectorAgentState::Double alpha_;
+ InspectorAgentState::Double beta_;
+ InspectorAgentState::Double gamma_;
DISALLOW_COPY_AND_ASSIGN(DeviceOrientationInspectorAgent);
};
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_event_pump.h b/chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_event_pump.h
index bf83aeb8c40..e64fabaa170 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_event_pump.h
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_event_pump.h
@@ -14,8 +14,6 @@
#include "services/device/public/cpp/generic_sensor/sensor_reading.h"
#include "services/device/public/cpp/generic_sensor/sensor_reading_shared_buffer_reader.h"
#include "services/device/public/mojom/sensor_provider.mojom-blink.h"
-#include "third_party/blink/public/platform/modules/device_orientation/web_device_motion_listener.h"
-#include "third_party/blink/public/platform/modules/device_orientation/web_device_orientation_listener.h"
#include "third_party/blink/renderer/platform/timer.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
@@ -23,7 +21,6 @@ namespace blink {
class LocalFrame;
-template <typename ListenerType>
class DeviceSensorEventPump {
public:
// Default rate for firing events.
@@ -55,8 +52,7 @@ class DeviceSensorEventPump {
SUSPENDED
};
- virtual void Start(LocalFrame* frame,
- blink::WebPlatformEventListener* listener) {
+ virtual void Start(LocalFrame* frame) {
DVLOG(2) << "requested start";
if (state_ != PumpState::STOPPED)
@@ -67,7 +63,6 @@ class DeviceSensorEventPump {
state_ = PumpState::PENDING_START;
DCHECK(!is_observing_);
- listener_ = static_cast<ListenerType*>(listener);
is_observing_ = true;
SendStartMessage(frame);
@@ -86,7 +81,6 @@ class DeviceSensorEventPump {
timer_.Stop();
DCHECK(is_observing_);
- listener_ = nullptr;
is_observing_ = false;
SendStopMessage();
@@ -134,8 +128,6 @@ class DeviceSensorEventPump {
// TaskRunnerTimer class
virtual void FireEvent(TimerBase*) = 0;
- ListenerType* listener() { return listener_; }
-
struct SensorEntry : public device::mojom::blink::SensorClient {
SensorEntry(DeviceSensorEventPump* pump,
device::mojom::blink::SensorType sensor_type)
@@ -334,7 +326,6 @@ class DeviceSensorEventPump {
PumpState state_;
bool is_observing_ = false;
- ListenerType* listener_ = nullptr;
TaskRunnerTimer<DeviceSensorEventPump> timer_;
DISALLOW_COPY_AND_ASSIGN(DeviceSensorEventPump);
diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/encrypted_media_utils.cc b/chromium/third_party/blink/renderer/modules/encryptedmedia/encrypted_media_utils.cc
index d604ed69e24..29e135167f6 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/encrypted_media_utils.cc
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/encrypted_media_utils.cc
@@ -4,12 +4,15 @@
#include "third_party/blink/renderer/modules/encryptedmedia/encrypted_media_utils.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+
namespace blink {
namespace {
const char kTemporary[] = "temporary";
const char kPersistentLicense[] = "persistent-license";
+const char kPersistentUsageRecord[] = "persistent-usage-record";
} // namespace
@@ -54,6 +57,11 @@ WebEncryptedMediaSessionType EncryptedMediaUtils::ConvertToSessionType(
return WebEncryptedMediaSessionType::kTemporary;
if (session_type == kPersistentLicense)
return WebEncryptedMediaSessionType::kPersistentLicense;
+ if (session_type == kPersistentUsageRecord &&
+ RuntimeEnabledFeatures::
+ EncryptedMediaPersistentUsageRecordSessionEnabled()) {
+ return WebEncryptedMediaSessionType::kPersistentUsageRecord;
+ }
// |sessionType| is not restricted in the idl, so anything is possible.
return WebEncryptedMediaSessionType::kUnknown;
@@ -67,10 +75,14 @@ String EncryptedMediaUtils::ConvertFromSessionType(
return kTemporary;
case WebEncryptedMediaSessionType::kPersistentLicense:
return kPersistentLicense;
- // TODO(crbug.com/856925): Add support for kPersistentUsageRecord.
case WebEncryptedMediaSessionType::kPersistentUsageRecord:
+ if (RuntimeEnabledFeatures::
+ EncryptedMediaPersistentUsageRecordSessionEnabled()) {
+ return kPersistentUsageRecord;
+ }
+ FALLTHROUGH;
case WebEncryptedMediaSessionType::kUnknown:
- // Chromium should not use Unknown.
+ // Unexpected session type from Chromium.
NOTREACHED();
return String();
}
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 05b5a3fefef..482abd90ebb 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
@@ -900,7 +900,7 @@ void MediaKeySession::Message(MessageType message_type,
MediaKeyMessageEvent* event =
MediaKeyMessageEvent::Create(EventTypeNames::message, init);
event->SetTarget(this);
- async_event_queue_->EnqueueEvent(FROM_HERE, event);
+ async_event_queue_->EnqueueEvent(FROM_HERE, *event);
}
void MediaKeySession::Close() {
@@ -985,7 +985,7 @@ void MediaKeySession::KeysStatusesChange(
// at the session.
Event* event = Event::Create(EventTypeNames::keystatuseschange);
event->SetTarget(this);
- async_event_queue_->EnqueueEvent(FROM_HERE, event);
+ async_event_queue_->EnqueueEvent(FROM_HERE, *event);
// 6. Queue a task to run the attempt to resume playback if necessary
// algorithm on each of the media element(s) whose mediaKeys attribute
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 15ddb62e6e3..110d58bb9c0 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.cc
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.cc
@@ -43,6 +43,7 @@
#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/instance_counters.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/timer.h"
#define MEDIA_KEYS_LOG_LEVEL 3
@@ -233,6 +234,21 @@ MediaKeySession* MediaKeys::createSession(ScriptState* script_state,
DVLOG(MEDIA_KEYS_LOG_LEVEL)
<< __func__ << "(" << this << ") " << session_type_string;
+ // [RuntimeEnabled] does not work with enum values. So we have to check it
+ // here. See https://crbug.com/871867 for details.
+ if (!RuntimeEnabledFeatures::
+ EncryptedMediaPersistentUsageRecordSessionEnabled() &&
+ session_type_string == "persistent-usage-record") {
+ DVLOG(MEDIA_KEYS_LOG_LEVEL)
+ << __func__ << ": 'persistent-usage-record' support not enabled.";
+ // The message here is carefully chosen to be exactly the same as what the
+ // generated bindings would generate for invalid enum values.
+ exception_state.ThrowTypeError(
+ "The provided value 'persistent-usage-record' is not a valid enum "
+ "value of type MediaKeySessionType.");
+ return nullptr;
+ }
+
// From http://w3c.github.io/encrypted-media/#createSession
// When this method is invoked, the user agent must run the following steps:
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 d1f69ae6287..8fd2d114db7 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.idl
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.idl
@@ -26,6 +26,7 @@
enum MediaKeySessionType {
"temporary",
"persistent-license",
+ "persistent-usage-record",
};
[
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 313725cdcb0..9a0acee798e 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
@@ -301,24 +301,19 @@ ScriptPromise NavigatorRequestMediaKeySystemAccess::requestMediaKeySystemAccess(
ExecutionContext* execution_context = ExecutionContext::From(script_state);
Document* document = ToDocument(execution_context);
- if (RuntimeEnabledFeatures::FeaturePolicyForPermissionsEnabled()) {
- if (!document->GetFrame() ||
- !document->GetFrame()->IsFeatureEnabled(
- mojom::FeaturePolicyFeature::kEncryptedMedia)) {
- UseCounter::Count(document,
- WebFeature::kEncryptedMediaDisabledByFeaturePolicy);
- document->AddConsoleMessage(
- ConsoleMessage::Create(kJSMessageSource, kWarningMessageLevel,
- kEncryptedMediaFeaturePolicyConsoleWarning));
- return ScriptPromise::RejectWithDOMException(
- script_state,
- DOMException::Create(
- DOMExceptionCode::kSecurityError,
- "requestMediaKeySystemAccess is disabled by feature policy."));
- }
- } else {
- Deprecation::CountDeprecationFeaturePolicy(
- *document, mojom::FeaturePolicyFeature::kEncryptedMedia);
+ if (!document->GetFrame() ||
+ !document->GetFrame()->IsFeatureEnabled(
+ mojom::FeaturePolicyFeature::kEncryptedMedia)) {
+ UseCounter::Count(document,
+ WebFeature::kEncryptedMediaDisabledByFeaturePolicy);
+ document->AddConsoleMessage(
+ ConsoleMessage::Create(kJSMessageSource, kWarningMessageLevel,
+ kEncryptedMediaFeaturePolicyConsoleWarning));
+ return ScriptPromise::RejectWithDOMException(
+ script_state,
+ DOMException::Create(
+ DOMExceptionCode::kSecurityError,
+ "requestMediaKeySystemAccess is disabled by feature policy."));
}
// From https://w3c.github.io/encrypted-media/#requestMediaKeySystemAccess
diff --git a/chromium/third_party/blink/renderer/modules/event_target_modules_names.json5 b/chromium/third_party/blink/renderer/modules/event_target_modules_names.json5
index b98a20d37db..65975c81c70 100644
--- a/chromium/third_party/blink/renderer/modules/event_target_modules_names.json5
+++ b/chromium/third_party/blink/renderer/modules/event_target_modules_names.json5
@@ -30,6 +30,7 @@
"modules/netinfo/NetworkInformation",
"modules/notifications/Notification",
"modules/payments/PaymentRequest",
+ "modules/peerconnection/RTCIceTransport",
"modules/permissions/PermissionStatus",
"modules/picture_in_picture/HTMLVideoElementPictureInPicture",
"modules/picture_in_picture/PictureInPictureWindow",
@@ -48,6 +49,8 @@
"modules/speech/SpeechSynthesis",
"modules/speech/SpeechSynthesisUtterance",
"modules/vr/VRDisplay",
+ "modules/wake_lock/WakeLock",
+ "modules/wake_lock/WakeLockRequest",
"modules/webaudio/AudioContext",
"modules/webaudio/AudioNode",
"modules/webmidi/MIDIAccess",
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 92ed79a1e5c..8c68e3c1bd2 100644
--- a/chromium/third_party/blink/renderer/modules/eventsource/event_source.cc
+++ b/chromium/third_party/blink/renderer/modules/eventsource/event_source.cc
@@ -151,17 +151,13 @@ void EventSource::Connect() {
const SecurityOrigin* origin = execution_context.GetSecurityOrigin();
- ThreadableLoaderOptions options;
-
ResourceLoaderOptions resource_loader_options;
resource_loader_options.data_buffering_policy = kDoNotBufferData;
resource_loader_options.security_origin = origin;
probe::willSendEventSourceRequest(&execution_context, this);
- // probe::documentThreadableLoaderStartedLoadingForClient
- // will be called synchronously.
- loader_ = ThreadableLoader::Create(execution_context, this, options,
- resource_loader_options);
+ loader_ =
+ new ThreadableLoader(execution_context, this, resource_loader_options);
loader_->Start(request);
}
@@ -176,7 +172,7 @@ void EventSource::ScheduleReconnect() {
state_ = kConnecting;
connect_timer_.StartOneShot(TimeDelta::FromMilliseconds(reconnect_delay_),
FROM_HERE);
- DispatchEvent(Event::Create(EventTypeNames::error));
+ DispatchEvent(*Event::Create(EventTypeNames::error));
}
void EventSource::ConnectTimerFired(TimerBase*) {
@@ -277,7 +273,7 @@ void EventSource::DidReceiveResponse(
last_event_id = parser_->LastEventId();
}
parser_ = new EventSourceParser(last_event_id, this);
- DispatchEvent(Event::Create(EventTypeNames::open));
+ DispatchEvent(*Event::Create(EventTypeNames::open));
} else {
loader_->Cancel();
}
@@ -337,7 +333,7 @@ void EventSource::OnMessageEvent(const AtomicString& event_type,
probe::willDispatchEventSourceEvent(GetExecutionContext(),
resource_identifier_, event_type,
last_event_id, data);
- DispatchEvent(e);
+ DispatchEvent(*e);
}
void EventSource::OnReconnectionTimeSet(unsigned long long reconnection_time) {
@@ -351,7 +347,7 @@ void EventSource::AbortConnectionAttempt() {
state_ = kClosed;
NetworkRequestEnded();
- DispatchEvent(Event::Create(EventTypeNames::error));
+ DispatchEvent(*Event::Create(EventTypeNames::error));
}
void EventSource::ContextDestroyed(ExecutionContext*) {
diff --git a/chromium/third_party/blink/renderer/modules/exported/BUILD.gn b/chromium/third_party/blink/renderer/modules/exported/BUILD.gn
index e27cd8b34ef..e3030b08a39 100644
--- a/chromium/third_party/blink/renderer/modules/exported/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/exported/BUILD.gn
@@ -6,6 +6,7 @@ import("//third_party/blink/renderer/modules/modules.gni")
blink_modules_sources("exported") {
sources = [
"web_apply_constraints_request.cc",
+ "web_ax_context.cc",
"web_ax_object.cc",
"web_crypto_normalize.cc",
"web_dom_file_system.cc",
diff --git a/chromium/third_party/blink/renderer/modules/exported/web_ax_context.cc b/chromium/third_party/blink/renderer/modules/exported/web_ax_context.cc
new file mode 100644
index 00000000000..699672a30c2
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/exported/web_ax_context.cc
@@ -0,0 +1,25 @@
+// 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/web/web_ax_context.h"
+
+#include "third_party/blink/public/web/web_document.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/dom/document.h"
+#include "third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h"
+
+namespace blink {
+
+WebAXContext::WebAXContext(WebDocument root_document)
+ : private_(new AXContext(*root_document.Unwrap<Document>())) {}
+
+WebAXContext::~WebAXContext() {}
+
+WebAXObject WebAXContext::Root() const {
+ return WebAXObject(
+ static_cast<AXObjectCacheImpl*>(&private_->GetAXObjectCache())->Root());
+}
+
+} // namespace blink
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 d998979df5c..28a9aa8b13a 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
@@ -111,18 +111,6 @@ static bool IsLayoutClean(Document* document) {
}
#endif
-WebScopedAXContext::WebScopedAXContext(WebDocument& root_document)
- : private_(ScopedAXObjectCache::Create(*root_document.Unwrap<Document>())) {
-}
-
-WebScopedAXContext::~WebScopedAXContext() {
- private_.reset(nullptr);
-}
-
-WebAXObject WebScopedAXContext::Root() const {
- return WebAXObject(static_cast<AXObjectCacheImpl*>(private_->Get())->Root());
-}
-
void WebAXObject::Reset() {
private_.Reset();
}
@@ -237,6 +225,13 @@ bool WebAXObject::IsAnchor() const {
return private_->IsAnchor();
}
+bool WebAXObject::IsAutofillAvailable() const {
+ if (IsDetached())
+ return false;
+
+ return private_->IsAutofillAvailable();
+}
+
WebString WebAXObject::AriaAutoComplete() const {
if (IsDetached())
return WebString();
@@ -1439,7 +1434,7 @@ WebAXObject WebAXObject::FromWebNode(const WebNode& web_node) {
WebAXObject WebAXObject::FromWebDocument(const WebDocument& web_document) {
const Document* document = web_document.ConstUnwrap<Document>();
AXObjectCacheImpl* cache =
- ToAXObjectCacheImpl(document->GetOrCreateAXObjectCache());
+ ToAXObjectCacheImpl(document->ExistingAXObjectCache());
return cache ? WebAXObject(cache->GetOrCreate(document->GetLayoutView()))
: WebAXObject();
}
@@ -1449,7 +1444,7 @@ WebAXObject WebAXObject::FromWebDocumentByID(const WebDocument& web_document,
int ax_id) {
const Document* document = web_document.ConstUnwrap<Document>();
AXObjectCacheImpl* cache =
- ToAXObjectCacheImpl(document->GetOrCreateAXObjectCache());
+ ToAXObjectCacheImpl(document->ExistingAXObjectCache());
return cache ? WebAXObject(cache->ObjectFromAXID(ax_id)) : WebAXObject();
}
@@ -1458,7 +1453,7 @@ WebAXObject WebAXObject::FromWebDocumentFocused(
const WebDocument& web_document) {
const Document* document = web_document.ConstUnwrap<Document>();
AXObjectCacheImpl* cache =
- ToAXObjectCacheImpl(document->GetOrCreateAXObjectCache());
+ ToAXObjectCacheImpl(document->ExistingAXObjectCache());
return cache ? WebAXObject(cache->FocusedObject()) : WebAXObject();
}
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 79e77e2904f..7c24cfabb2a 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
@@ -70,7 +70,7 @@ WebDOMFileSystem WebDOMFileSystem::Create(WebLocalFrame* frame,
DCHECK(ToWebLocalFrameImpl(frame)->GetFrame());
DOMFileSystem* dom_file_system = DOMFileSystem::Create(
ToWebLocalFrameImpl(frame)->GetFrame()->GetDocument(), name,
- static_cast<FileSystemType>(type), root_url);
+ static_cast<mojom::blink::FileSystemType>(type), root_url);
if (serializable_type == kSerializableTypeSerializable)
dom_file_system->MakeClonable();
return WebDOMFileSystem(dom_file_system);
@@ -92,13 +92,13 @@ WebString WebDOMFileSystem::GetName() const {
WebFileSystem::Type WebDOMFileSystem::GetType() const {
DCHECK(private_.Get());
switch (private_->GetType()) {
- case kFileSystemTypeTemporary:
+ case blink::mojom::FileSystemType::kTemporary:
return WebFileSystem::kTypeTemporary;
- case kFileSystemTypePersistent:
+ case blink::mojom::FileSystemType::kPersistent:
return WebFileSystem::kTypePersistent;
- case kFileSystemTypeIsolated:
+ case blink::mojom::FileSystemType::kIsolated:
return WebFileSystem::kTypeIsolated;
- case kFileSystemTypeExternal:
+ case blink::mojom::FileSystemType::kExternal:
return WebFileSystem::kTypeExternal;
default:
NOTREACHED();
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 320fb9937ff..360d0299fe6 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
@@ -45,7 +45,6 @@
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/loader/frame_load_request.h"
-#include "third_party/blink/renderer/core/loader/threadable_loading_context.h"
#include "third_party/blink/renderer/core/loader/worker_fetch_context.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/core/script/script.h"
@@ -67,7 +66,9 @@
#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/shared_buffer.h"
+#include "third_party/blink/renderer/platform/weborigin/referrer_policy.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/wtf/functional.h"
namespace blink {
@@ -248,14 +249,6 @@ void WebEmbeddedWorkerImpl::PostMessageToPageInspector(int session_id,
worker_inspector_proxy_->DispatchMessageFromWorker(session_id, message);
}
-void WebEmbeddedWorkerImpl::SetContentSecurityPolicyAndReferrerPolicy(
- ContentSecurityPolicy* content_security_policy,
- String referrer_policy) {
- DCHECK(IsMainThread());
- shadow_page_->SetContentSecurityPolicyAndReferrerPolicy(
- content_security_policy, std::move(referrer_policy));
-}
-
std::unique_ptr<WebApplicationCacheHost>
WebEmbeddedWorkerImpl::CreateApplicationCacheHost(
WebApplicationCacheHostClient*) {
@@ -285,7 +278,7 @@ void WebEmbeddedWorkerImpl::OnShadowPageInitialized() {
// worker.
DCHECK(!main_script_loader_);
main_script_loader_ = WorkerClassicScriptLoader::Create();
- main_script_loader_->LoadAsynchronously(
+ main_script_loader_->LoadTopLevelScriptAsynchronously(
*shadow_page_->GetDocument(), worker_start_data_.script_url,
WebURLRequest::kRequestContextServiceWorker,
network::mojom::FetchRequestMode::kSameOrigin,
@@ -336,6 +329,7 @@ void WebEmbeddedWorkerImpl::StartWorkerThread() {
// (crbug.com/254993)
const SecurityOrigin* starter_origin = document->GetSecurityOrigin();
bool starter_secure_context = document->IsSecureContext();
+ const HttpsState starter_https_state = document->GetHttpsState();
WorkerClients* worker_clients = WorkerClients::Create();
ProvideIndexedDBClientToWorker(worker_clients,
@@ -372,17 +366,22 @@ void WebEmbeddedWorkerImpl::StartWorkerThread() {
// |main_script_loader_| isn't created if the InstalledScriptsManager had the
// script.
if (main_script_loader_) {
- // We need to set the CSP to both the shadow page's document and the
- // ServiceWorkerGlobalScope.
- SetContentSecurityPolicyAndReferrerPolicy(
- main_script_loader_->ReleaseContentSecurityPolicy(),
- main_script_loader_->GetReferrerPolicy());
+ ContentSecurityPolicy* content_security_policy =
+ main_script_loader_->GetContentSecurityPolicy();
+ ReferrerPolicy referrer_policy = kReferrerPolicyDefault;
+ if (!main_script_loader_->GetReferrerPolicy().IsNull()) {
+ SecurityPolicy::ReferrerPolicyFromHeaderValue(
+ main_script_loader_->GetReferrerPolicy(),
+ kDoNotSupportReferrerPolicyLegacyKeywords, &referrer_policy);
+ }
global_scope_creation_params = std::make_unique<GlobalScopeCreationParams>(
worker_start_data_.script_url, script_type,
worker_start_data_.user_agent,
- document->GetContentSecurityPolicy()->Headers(),
- document->GetReferrerPolicy(), starter_origin, starter_secure_context,
- worker_clients, main_script_loader_->ResponseAddressSpace(),
+ content_security_policy ? content_security_policy->Headers()
+ : Vector<CSPHeaderAndType>(),
+ referrer_policy, starter_origin, starter_secure_context,
+ starter_https_state, worker_clients,
+ main_script_loader_->ResponseAddressSpace(),
main_script_loader_->OriginTrialTokens(), devtools_worker_token_,
std::move(worker_settings),
static_cast<V8CacheOptions>(worker_start_data_.v8_cache_options),
@@ -392,14 +391,13 @@ void WebEmbeddedWorkerImpl::StartWorkerThread() {
cached_meta_data = main_script_loader_->ReleaseCachedMetadata();
main_script_loader_ = nullptr;
} else {
- // ContentSecurityPolicy and ReferrerPolicy are applied to |document| at
- // SetContentSecurityPolicyAndReferrerPolicy() before evaluating the main
- // script.
+ // We don't have to set ContentSecurityPolicy and ReferrerPolicy. They're
+ // served by the installed scripts manager on the worker thread.
global_scope_creation_params = std::make_unique<GlobalScopeCreationParams>(
worker_start_data_.script_url, script_type,
worker_start_data_.user_agent, Vector<CSPHeaderAndType>(),
kReferrerPolicyDefault, starter_origin, starter_secure_context,
- worker_clients, worker_start_data_.address_space,
+ starter_https_state, worker_clients, worker_start_data_.address_space,
nullptr /* OriginTrialTokens */, devtools_worker_token_,
std::move(worker_settings),
static_cast<V8CacheOptions>(worker_start_data_.v8_cache_options),
@@ -413,7 +411,6 @@ void WebEmbeddedWorkerImpl::StartWorkerThread() {
}
worker_thread_ = std::make_unique<ServiceWorkerThread>(
- ThreadableLoadingContext::Create(*document),
ServiceWorkerGlobalScopeProxy::Create(*this, *worker_context_client_),
std::move(installed_scripts_manager_), std::move(cache_storage_info_));
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 d8d935f1bfc..ffb8994e780 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
@@ -46,7 +46,6 @@
namespace blink {
-class ContentSecurityPolicy;
class ServiceWorkerInstalledScriptsManager;
class WorkerClassicScriptLoader;
class WorkerInspectorProxy;
@@ -76,13 +75,6 @@ class MODULES_EXPORT WebEmbeddedWorkerImpl final
void PostMessageToPageInspector(int session_id, const WTF::String&);
- // Applies the specified CSP and referrer policy to the worker, so that
- // fetches initiated by the worker (other than for the main worker script
- // itself) are affected by these policies. This must be called before starting
- // script execution on the worker thread.
- void SetContentSecurityPolicyAndReferrerPolicy(ContentSecurityPolicy*,
- String referrer_policy);
-
// WorkerShadowPage::Client overrides.
std::unique_ptr<WebApplicationCacheHost> CreateApplicationCacheHost(
WebApplicationCacheHostClient*) override;
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
index ad2a3120184..20f62db2e54 100644
--- 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
@@ -57,6 +57,11 @@ void WebUserMediaRequest::Reset() {
private_.Reset();
}
+WebUserMediaRequest::MediaType WebUserMediaRequest::MediaRequestType() const {
+ DCHECK(!IsNull());
+ return private_->MediaRequestType();
+}
+
bool WebUserMediaRequest::Audio() const {
DCHECK(!IsNull());
return private_->Audio();
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/BUILD.gn b/chromium/third_party/blink/renderer/modules/filesystem/BUILD.gn
index 66d03403cd0..2e158d69650 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/filesystem/BUILD.gn
@@ -42,9 +42,17 @@ blink_modules_sources("filesystem") {
"file_entry.h",
"file_entry_sync.cc",
"file_entry_sync.h",
+ "file_system_base_handle.cc",
+ "file_system_base_handle.h",
"file_system_callbacks.cc",
"file_system_callbacks.h",
"file_system_client.h",
+ "file_system_directory_handle.cc",
+ "file_system_directory_handle.h",
+ "file_system_file_handle.cc",
+ "file_system_file_handle.h",
+ "file_system_writer.cc",
+ "file_system_writer.h",
"file_writer.cc",
"file_writer.h",
"file_writer_base.cc",
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 1e8b83c7a8a..9616f291b02 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
@@ -19,7 +19,8 @@ DOMFileSystem* DevToolsHostFileSystem::isolatedFileSystem(
const String& root_url) {
ExecutionContext* context = host.FrontendFrame()->GetDocument();
return DOMFileSystem::Create(context, file_system_name,
- kFileSystemTypeIsolated, KURL(root_url));
+ mojom::blink::FileSystemType::kIsolated,
+ KURL(root_url));
}
void DevToolsHostFileSystem::upgradeDraggedFileSystemPermissions(
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 c858480e039..7bed6982573 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
@@ -100,10 +100,7 @@ EntrySyncHeapVector DirectoryReaderSync::readEntries(
ErrorCallbackHelper::Create(this), DOMFileSystemBase::kSynchronous);
}
- if (error_code_ == FileError::kOK && has_more_entries_ &&
- entries_.IsEmpty()) {
- CHECK(Filesystem()->WaitForAdditionalResult(callbacks_id_));
- }
+ DCHECK(!has_more_entries_);
if (error_code_ != FileError::kOK) {
FileError::ThrowDOMException(exception_state, error_code_);
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 6a1f851054a..5e5f3e8e37b 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
@@ -65,7 +65,7 @@ void RunCallback(ExecutionContext* execution_context,
// static
DOMFileSystem* DOMFileSystem::Create(ExecutionContext* context,
const String& name,
- FileSystemType type,
+ mojom::blink::FileSystemType type,
const KURL& root_url) {
return new DOMFileSystem(context, name, type, root_url);
}
@@ -94,13 +94,13 @@ DOMFileSystem* DOMFileSystem::CreateIsolatedFileSystem(
root_url.Append('/');
return DOMFileSystem::Create(context, filesystem_name.ToString(),
- kFileSystemTypeIsolated,
+ mojom::blink::FileSystemType::kIsolated,
KURL(root_url.ToString()));
}
DOMFileSystem::DOMFileSystem(ExecutionContext* context,
const String& name,
- FileSystemType type,
+ mojom::blink::FileSystemType type,
const KURL& root_url)
: DOMFileSystemBase(context, name, type, root_url),
ContextClient(context),
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 d2f3e6b4cfa..a1e90d31579 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
@@ -55,7 +55,7 @@ class MODULES_EXPORT DOMFileSystem final
public:
static DOMFileSystem* Create(ExecutionContext*,
const String& name,
- FileSystemType,
+ mojom::blink::FileSystemType,
const KURL& root_url);
// Creates a new isolated file system for the given filesystemId.
@@ -93,7 +93,7 @@ class MODULES_EXPORT DOMFileSystem final
private:
DOMFileSystem(ExecutionContext*,
const String& name,
- FileSystemType,
+ mojom::blink::FileSystemType,
const KURL& root_url);
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 e1ed5f7f958..c8e148aad92 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
@@ -58,7 +58,7 @@ const char DOMFileSystemBase::kExternalPathPrefix[] = "external";
DOMFileSystemBase::DOMFileSystemBase(ExecutionContext* context,
const String& name,
- FileSystemType type,
+ mojom::blink::FileSystemType type,
const KURL& root_url)
: context_(context),
name_(name),
@@ -84,20 +84,22 @@ const SecurityOrigin* DOMFileSystemBase::GetSecurityOrigin() const {
return context_->GetSecurityOrigin();
}
-bool DOMFileSystemBase::IsValidType(FileSystemType type) {
- return type == kFileSystemTypeTemporary ||
- type == kFileSystemTypePersistent || type == kFileSystemTypeIsolated ||
- type == kFileSystemTypeExternal;
+bool DOMFileSystemBase::IsValidType(mojom::blink::FileSystemType type) {
+ return type == mojom::blink::FileSystemType::kTemporary ||
+ type == mojom::blink::FileSystemType::kPersistent ||
+ type == mojom::blink::FileSystemType::kIsolated ||
+ type == mojom::blink::FileSystemType::kExternal;
}
-KURL DOMFileSystemBase::CreateFileSystemRootURL(const String& origin,
- FileSystemType type) {
+KURL DOMFileSystemBase::CreateFileSystemRootURL(
+ const String& origin,
+ mojom::blink::FileSystemType type) {
String type_string;
- if (type == kFileSystemTypeTemporary)
+ if (type == mojom::blink::FileSystemType::kTemporary)
type_string = kTemporaryPathPrefix;
- else if (type == kFileSystemTypePersistent)
+ else if (type == mojom::blink::FileSystemType::kPersistent)
type_string = kPersistentPathPrefix;
- else if (type == kFileSystemTypeExternal)
+ else if (type == mojom::blink::FileSystemType::kExternal)
type_string = kExternalPathPrefix;
else
return KURL();
@@ -108,7 +110,7 @@ KURL DOMFileSystemBase::CreateFileSystemRootURL(const String& origin,
bool DOMFileSystemBase::SupportsToURL() const {
DCHECK(IsValidType(type_));
- return type_ != kFileSystemTypeIsolated;
+ return type_ != mojom::blink::FileSystemType::kIsolated;
}
KURL DOMFileSystemBase::CreateFileSystemURL(const EntryBase* entry) const {
@@ -118,7 +120,7 @@ KURL DOMFileSystemBase::CreateFileSystemURL(const EntryBase* entry) const {
KURL DOMFileSystemBase::CreateFileSystemURL(const String& full_path) const {
DCHECK(DOMFilePath::IsAbsolute(full_path));
- if (GetType() == kFileSystemTypeExternal) {
+ if (GetType() == mojom::blink::FileSystemType::kExternal) {
// For external filesystem originString could be different from what we have
// in m_filesystemRootURL.
StringBuilder result;
@@ -143,7 +145,7 @@ KURL DOMFileSystemBase::CreateFileSystemURL(const String& full_path) const {
return url;
}
-bool DOMFileSystemBase::PathToAbsolutePath(FileSystemType type,
+bool DOMFileSystemBase::PathToAbsolutePath(mojom::blink::FileSystemType type,
const EntryBase* base,
String path,
String& absolute_path) {
@@ -153,25 +155,26 @@ bool DOMFileSystemBase::PathToAbsolutePath(FileSystemType type,
path = DOMFilePath::Append(base->fullPath(), path);
absolute_path = DOMFilePath::RemoveExtraParentReferences(path);
- return (type != kFileSystemTypeTemporary &&
- type != kFileSystemTypePersistent) ||
+ return (type != mojom::blink::FileSystemType::kTemporary &&
+ type != mojom::blink::FileSystemType::kPersistent) ||
DOMFilePath::IsValidPath(absolute_path);
}
-bool DOMFileSystemBase::PathPrefixToFileSystemType(const String& path_prefix,
- FileSystemType& type) {
+bool DOMFileSystemBase::PathPrefixToFileSystemType(
+ const String& path_prefix,
+ mojom::blink::FileSystemType& type) {
if (path_prefix == kTemporaryPathPrefix) {
- type = kFileSystemTypeTemporary;
+ type = mojom::blink::FileSystemType::kTemporary;
return true;
}
if (path_prefix == kPersistentPathPrefix) {
- type = kFileSystemTypePersistent;
+ type = mojom::blink::FileSystemType::kPersistent;
return true;
}
if (path_prefix == kExternalPathPrefix) {
- type = kFileSystemTypeExternal;
+ type = mojom::blink::FileSystemType::kExternal;
return true;
}
@@ -180,7 +183,7 @@ bool DOMFileSystemBase::PathPrefixToFileSystemType(const String& path_prefix,
File* DOMFileSystemBase::CreateFile(const FileMetadata& metadata,
const KURL& file_system_url,
- FileSystemType type,
+ mojom::blink::FileSystemType type,
const String name) {
// For regular filesystem types (temporary or persistent), we should not cache
// file metadata as it could change File semantics. For other filesystem
@@ -189,12 +192,14 @@ File* DOMFileSystemBase::CreateFile(const FileMetadata& metadata,
// pass it to File constructor (so we may cache the metadata).
// FIXME: We should use the snapshot metadata for all files.
// https://www.w3.org/Bugs/Public/show_bug.cgi?id=17746
- if (type == kFileSystemTypeTemporary || type == kFileSystemTypePersistent)
+ if (type == mojom::blink::FileSystemType::kTemporary ||
+ type == mojom::blink::FileSystemType::kPersistent)
return File::CreateForFileSystemFile(metadata.platform_path, name);
- const File::UserVisibility user_visibility = (type == kFileSystemTypeExternal)
- ? File::kIsUserVisible
- : File::kIsNotUserVisible;
+ const File::UserVisibility user_visibility =
+ (type == mojom::blink::FileSystemType::kExternal)
+ ? File::kIsUserVisible
+ : File::kIsNotUserVisible;
if (!metadata.platform_path.IsEmpty()) {
// If the platformPath in the returned metadata is given, we create a File
@@ -469,15 +474,13 @@ int DOMFileSystemBase::ReadDirectory(
std::move(callbacks));
}
-bool DOMFileSystemBase::WaitForAdditionalResult(int callbacks_id) {
- if (!FileSystem())
- return false;
- return FileSystem()->WaitForAdditionalResult(callbacks_id);
-}
-
-STATIC_ASSERT_ENUM(WebFileSystem::kTypeTemporary, kFileSystemTypeTemporary);
-STATIC_ASSERT_ENUM(WebFileSystem::kTypePersistent, kFileSystemTypePersistent);
-STATIC_ASSERT_ENUM(WebFileSystem::kTypeExternal, kFileSystemTypeExternal);
-STATIC_ASSERT_ENUM(WebFileSystem::kTypeIsolated, kFileSystemTypeIsolated);
+STATIC_ASSERT_ENUM(WebFileSystem::kTypeTemporary,
+ mojom::blink::FileSystemType::kTemporary);
+STATIC_ASSERT_ENUM(WebFileSystem::kTypePersistent,
+ mojom::blink::FileSystemType::kPersistent);
+STATIC_ASSERT_ENUM(WebFileSystem::kTypeExternal,
+ mojom::blink::FileSystemType::kExternal);
+STATIC_ASSERT_ENUM(WebFileSystem::kTypeIsolated,
+ mojom::blink::FileSystemType::kIsolated);
} // namespace blink
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 e5c710d97ec..76496faac03 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
@@ -31,12 +31,12 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_DOM_FILE_SYSTEM_BASE_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_DOM_FILE_SYSTEM_BASE_H_
+#include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink.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/file_system_type.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/text/wtf_string.h"
@@ -81,7 +81,7 @@ class MODULES_EXPORT DOMFileSystemBase : public ScriptWrappable {
virtual void ReportError(ErrorCallbackBase*, FileError::ErrorCode) = 0;
const String& name() const { return name_; }
- FileSystemType GetType() const { return type_; }
+ mojom::blink::FileSystemType GetType() const { return type_; }
KURL RootURL() const { return filesystem_root_url_; }
WebFileSystem* FileSystem() const;
const SecurityOrigin* GetSecurityOrigin() const;
@@ -92,20 +92,21 @@ class MODULES_EXPORT DOMFileSystemBase : public ScriptWrappable {
void MakeClonable() { clonable_ = true; }
bool Clonable() const { return clonable_; }
- static bool IsValidType(FileSystemType);
- static KURL CreateFileSystemRootURL(const String& origin, FileSystemType);
+ static bool IsValidType(mojom::blink::FileSystemType);
+ static KURL CreateFileSystemRootURL(const String& origin,
+ mojom::blink::FileSystemType);
bool SupportsToURL() const;
KURL CreateFileSystemURL(const EntryBase*) const;
KURL CreateFileSystemURL(const String& full_path) const;
- static bool PathToAbsolutePath(FileSystemType,
+ static bool PathToAbsolutePath(mojom::blink::FileSystemType,
const EntryBase*,
String path,
String& absolute_path);
static bool PathPrefixToFileSystemType(const String& path_prefix,
- FileSystemType&);
+ mojom::blink::FileSystemType&);
static File* CreateFile(const FileMetadata&,
const KURL& file_system_url,
- FileSystemType,
+ mojom::blink::FileSystemType,
const String name);
// Actual FileSystem API implementations. All the validity checks on virtual
@@ -154,14 +155,13 @@ class MODULES_EXPORT DOMFileSystemBase : public ScriptWrappable {
EntriesCallbacks::OnDidGetEntriesCallback*,
ErrorCallbackBase*,
SynchronousType = kAsynchronous);
- bool WaitForAdditionalResult(int callbacks_id);
void Trace(blink::Visitor*) override;
protected:
DOMFileSystemBase(ExecutionContext*,
const String& name,
- FileSystemType,
+ mojom::blink::FileSystemType,
const KURL& root_url);
friend class DOMFileSystemBaseTest;
@@ -169,7 +169,7 @@ class MODULES_EXPORT DOMFileSystemBase : public ScriptWrappable {
Member<ExecutionContext> context_;
String name_;
- FileSystemType type_;
+ mojom::blink::FileSystemType type_;
KURL filesystem_root_url_;
bool clonable_;
};
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base_test.cc b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base_test.cc
index 861da30d6eb..586b10b6c04 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base_test.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base_test.cc
@@ -27,11 +27,11 @@ class DOMFileSystemBaseTest : public testing::Test {
TEST_F(DOMFileSystemBaseTest, externalFilesystemFilesAreUserVisible) {
KURL root_url = DOMFileSystemBase::CreateFileSystemRootURL(
- "http://chromium.org/", kFileSystemTypeExternal);
+ "http://chromium.org/", mojom::blink::FileSystemType::kExternal);
- File* file = DOMFileSystemBase::CreateFile(file_metadata_, root_url,
- kFileSystemTypeExternal,
- "dom_file_system_base_test.cc");
+ File* file = DOMFileSystemBase::CreateFile(
+ file_metadata_, root_url, mojom::blink::FileSystemType::kExternal,
+ "dom_file_system_base_test.cc");
EXPECT_TRUE(file);
EXPECT_TRUE(file->HasBackingFile());
EXPECT_EQ(File::kIsUserVisible, file->GetUserVisibility());
@@ -41,11 +41,11 @@ TEST_F(DOMFileSystemBaseTest, externalFilesystemFilesAreUserVisible) {
TEST_F(DOMFileSystemBaseTest, temporaryFilesystemFilesAreNotUserVisible) {
KURL root_url = DOMFileSystemBase::CreateFileSystemRootURL(
- "http://chromium.org/", kFileSystemTypeTemporary);
+ "http://chromium.org/", mojom::blink::FileSystemType::kTemporary);
- File* file = DOMFileSystemBase::CreateFile(file_metadata_, root_url,
- kFileSystemTypeTemporary,
- "UserVisibleName.txt");
+ File* file = DOMFileSystemBase::CreateFile(
+ file_metadata_, root_url, mojom::blink::FileSystemType::kTemporary,
+ "UserVisibleName.txt");
EXPECT_TRUE(file);
EXPECT_TRUE(file->HasBackingFile());
EXPECT_EQ(File::kIsNotUserVisible, file->GetUserVisibility());
@@ -55,11 +55,11 @@ TEST_F(DOMFileSystemBaseTest, temporaryFilesystemFilesAreNotUserVisible) {
TEST_F(DOMFileSystemBaseTest, persistentFilesystemFilesAreNotUserVisible) {
KURL root_url = DOMFileSystemBase::CreateFileSystemRootURL(
- "http://chromium.org/", kFileSystemTypePersistent);
+ "http://chromium.org/", mojom::blink::FileSystemType::kPersistent);
- File* file = DOMFileSystemBase::CreateFile(file_metadata_, root_url,
- kFileSystemTypePersistent,
- "UserVisibleName.txt");
+ File* file = DOMFileSystemBase::CreateFile(
+ file_metadata_, root_url, mojom::blink::FileSystemType::kPersistent,
+ "UserVisibleName.txt");
EXPECT_TRUE(file);
EXPECT_TRUE(file->HasBackingFile());
EXPECT_EQ(File::kIsNotUserVisible, file->GetUserVisibility());
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 4bcbb4d3797..e560d7ae23b 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
@@ -57,7 +57,7 @@ DOMFileSystemSync* DOMFileSystemSync::Create(DOMFileSystemBase* file_system) {
DOMFileSystemSync::DOMFileSystemSync(ExecutionContext* context,
const String& name,
- FileSystemType type,
+ mojom::blink::FileSystemType type,
const KURL& root_url)
: DOMFileSystemBase(context, name, type, root_url),
root_entry_(DirectoryEntrySync::Create(this, DOMFilePath::kRoot)) {}
@@ -95,7 +95,7 @@ class CreateFileHelper final : public AsyncFileSystemCallbacks {
CreateFileResult* result,
const String& name,
const KURL& url,
- FileSystemType type) {
+ mojom::blink::FileSystemType type) {
return base::WrapUnique(static_cast<AsyncFileSystemCallbacks*>(
new CreateFileHelper(result, name, url, type)));
}
@@ -126,13 +126,13 @@ class CreateFileHelper final : public AsyncFileSystemCallbacks {
CreateFileHelper(CreateFileResult* result,
const String& name,
const KURL& url,
- FileSystemType type)
+ mojom::blink::FileSystemType type)
: result_(result), name_(name), url_(url), type_(type) {}
Persistent<CreateFileResult> result_;
String name_;
KURL url_;
- FileSystemType type_;
+ mojom::blink::FileSystemType type_;
};
} // namespace
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 474cbda4888..b4d4f863f78 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
@@ -48,7 +48,7 @@ class DOMFileSystemSync final : public DOMFileSystemBase {
public:
static DOMFileSystemSync* Create(ExecutionContext* context,
const String& name,
- FileSystemType type,
+ mojom::blink::FileSystemType type,
const KURL& root_url) {
return new DOMFileSystemSync(context, name, type, root_url);
}
@@ -69,7 +69,7 @@ class DOMFileSystemSync final : public DOMFileSystemBase {
private:
DOMFileSystemSync(ExecutionContext*,
const String& name,
- FileSystemType,
+ mojom::blink::FileSystemType,
const KURL& root_url);
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 1f14b4284ef..cf8d2aa0ef2 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
@@ -25,14 +25,16 @@
#include "third_party/blink/renderer/modules/filesystem/dom_window_file_system.h"
+#include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/fileapi/file_error.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/use_counter.h"
#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/local_file_system.h"
-#include "third_party/blink/renderer/platform/file_system_type.h"
#include "third_party/blink/renderer/platform/weborigin/scheme_registry.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
@@ -64,7 +66,8 @@ void DOMWindowFileSystem::webkitRequestFileSystem(
UseCounter::Count(document, WebFeature::kFileAccessedFileSystem);
}
- FileSystemType file_system_type = static_cast<FileSystemType>(type);
+ mojom::blink::FileSystemType file_system_type =
+ static_cast<mojom::blink::FileSystemType>(type);
if (!DOMFileSystemBase::IsValidType(file_system_type)) {
DOMFileSystem::ReportError(document,
ScriptErrorCallback::Wrap(error_callback),
@@ -121,11 +124,39 @@ void DOMWindowFileSystem::webkitResolveLocalFileSystemURL(
static_assert(
static_cast<int>(DOMWindowFileSystem::kTemporary) ==
- static_cast<int>(kFileSystemTypeTemporary),
+ static_cast<int>(mojom::blink::FileSystemType::kTemporary),
"DOMWindowFileSystem::kTemporary should match FileSystemTypeTemporary");
static_assert(
static_cast<int>(DOMWindowFileSystem::kPersistent) ==
- static_cast<int>(kFileSystemTypePersistent),
+ static_cast<int>(mojom::blink::FileSystemType::kPersistent),
"DOMWindowFileSystem::kPersistent should match FileSystemTypePersistent");
+ScriptPromise DOMWindowFileSystem::chooseFileSystemEntries(
+ ScriptState* script_state,
+ LocalDOMWindow& window) {
+ if (!window.IsCurrentlyDisplayedInFrame()) {
+ return ScriptPromise::RejectWithDOMException(
+ script_state, DOMException::Create(DOMExceptionCode::kAbortError));
+ }
+
+ Document* document = window.document();
+ if (!document) {
+ return ScriptPromise::RejectWithDOMException(
+ script_state, DOMException::Create(DOMExceptionCode::kAbortError));
+ }
+
+ if (!Frame::HasTransientUserActivation(window.GetFrame())) {
+ return ScriptPromise::RejectWithDOMException(
+ script_state,
+ DOMException::Create(
+ DOMExceptionCode::kSecurityError,
+ "Must be handling a user gesture to show a file picker."));
+ }
+
+ auto* resolver = ScriptPromiseResolver::Create(script_state);
+ ScriptPromise result = resolver->Promise();
+ LocalFileSystem::From(*document)->ChooseEntry(resolver);
+ return result;
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/dom_window_file_system.h b/chromium/third_party/blink/renderer/modules/filesystem/dom_window_file_system.h
index af59998b938..a12e3beeb9b 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/dom_window_file_system.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/dom_window_file_system.h
@@ -33,6 +33,8 @@
namespace blink {
class LocalDOMWindow;
+class ScriptPromise;
+class ScriptState;
class V8EntryCallback;
class V8ErrorCallback;
class V8FileSystemCallback;
@@ -51,12 +53,14 @@ class DOMWindowFileSystem {
V8EntryCallback*,
V8ErrorCallback*);
- // They are placed here and in all capital letters so they can be checked
- // against the constants in the IDL at compile time.
+ // Defined here so they can be checked against the constants in the IDL at
+ // compile time.
enum {
kTemporary,
kPersistent,
};
+
+ static ScriptPromise chooseFileSystemEntries(ScriptState*, LocalDOMWindow&);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/entry.cc b/chromium/third_party/blink/renderer/modules/filesystem/entry.cc
index 4013042b8bc..154ff61722a 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/entry.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/entry.cc
@@ -44,7 +44,7 @@ Entry::Entry(DOMFileSystemBase* file_system, const String& full_path)
: EntryBase(file_system, full_path) {}
DOMFileSystem* Entry::filesystem(ScriptState* script_state) const {
- if (file_system_->GetType() == kFileSystemTypeIsolated) {
+ if (file_system_->GetType() == mojom::blink::FileSystemType::kIsolated) {
UseCounter::Count(
ExecutionContext::From(script_state),
WebFeature::kEntry_Filesystem_AttributeGetter_IsolatedFileSystem);
@@ -55,7 +55,7 @@ DOMFileSystem* Entry::filesystem(ScriptState* script_state) const {
void Entry::getMetadata(ScriptState* script_state,
V8MetadataCallback* success_callback,
V8ErrorCallback* error_callback) {
- if (file_system_->GetType() == kFileSystemTypeIsolated) {
+ if (file_system_->GetType() == mojom::blink::FileSystemType::kIsolated) {
UseCounter::Count(ExecutionContext::From(script_state),
WebFeature::kEntry_GetMetadata_Method_IsolatedFileSystem);
}
@@ -70,7 +70,7 @@ void Entry::moveTo(ScriptState* script_state,
const String& name,
V8EntryCallback* success_callback,
V8ErrorCallback* error_callback) const {
- if (file_system_->GetType() == kFileSystemTypeIsolated) {
+ if (file_system_->GetType() == mojom::blink::FileSystemType::kIsolated) {
UseCounter::Count(ExecutionContext::From(script_state),
WebFeature::kEntry_MoveTo_Method_IsolatedFileSystem);
}
@@ -85,7 +85,7 @@ void Entry::copyTo(ScriptState* script_state,
const String& name,
V8EntryCallback* success_callback,
V8ErrorCallback* error_callback) const {
- if (file_system_->GetType() == kFileSystemTypeIsolated) {
+ if (file_system_->GetType() == mojom::blink::FileSystemType::kIsolated) {
UseCounter::Count(ExecutionContext::From(script_state),
WebFeature::kEntry_CopyTo_Method_IsolatedFileSystem);
}
@@ -98,7 +98,7 @@ void Entry::copyTo(ScriptState* script_state,
void Entry::remove(ScriptState* script_state,
V8VoidCallback* success_callback,
V8ErrorCallback* error_callback) const {
- if (file_system_->GetType() == kFileSystemTypeIsolated) {
+ if (file_system_->GetType() == mojom::blink::FileSystemType::kIsolated) {
UseCounter::Count(ExecutionContext::From(script_state),
WebFeature::kEntry_Remove_Method_IsolatedFileSystem);
}
@@ -110,7 +110,7 @@ void Entry::remove(ScriptState* script_state,
void Entry::getParent(ScriptState* script_state,
V8EntryCallback* success_callback,
V8ErrorCallback* error_callback) const {
- if (file_system_->GetType() == kFileSystemTypeIsolated) {
+ if (file_system_->GetType() == mojom::blink::FileSystemType::kIsolated) {
UseCounter::Count(ExecutionContext::From(script_state),
WebFeature::kEntry_GetParent_Method_IsolatedFileSystem);
}
@@ -120,7 +120,7 @@ void Entry::getParent(ScriptState* script_state,
}
String Entry::toURL(ScriptState* script_state) const {
- if (file_system_->GetType() == kFileSystemTypeIsolated) {
+ if (file_system_->GetType() == mojom::blink::FileSystemType::kIsolated) {
UseCounter::Count(ExecutionContext::From(script_state),
WebFeature::kEntry_ToURL_Method_IsolatedFileSystem);
}
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/entry.idl b/chromium/third_party/blink/renderer/modules/filesystem/entry.idl
index dae22a8edd7..b05d3055315 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/entry.idl
+++ b/chromium/third_party/blink/renderer/modules/filesystem/entry.idl
@@ -52,4 +52,11 @@
// TODO(crbug.com/841185): |successCallback| and |errorCallback| are not
// nullable in the spec.
[CallWith=ScriptState] void getParent(optional EntryCallback? successCallback, optional ErrorCallback? errorCallback);
+
+ // Primarily exposed for testing, to give script some way of getting new
+ // style handles.
+ // TODO(mek): Remove this method once API to get new-style file handles
+ // directly has been implemented.
+ [RuntimeEnabled=WritableFiles]
+ FileSystemBaseHandle asFileSystemHandle();
};
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..b2e0c94926e 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/entry_base.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/entry_base.cc
@@ -32,6 +32,8 @@
#include "third_party/blink/renderer/modules/filesystem/dom_file_path.h"
#include "third_party/blink/renderer/modules/filesystem/dom_file_system_base.h"
+#include "third_party/blink/renderer/modules/filesystem/file_system_directory_handle.h"
+#include "third_party/blink/renderer/modules/filesystem/file_system_file_handle.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
namespace blink {
@@ -55,6 +57,13 @@ String EntryBase::toURL() const {
return cached_url_;
}
+FileSystemBaseHandle* EntryBase::asFileSystemHandle() const {
+ if (isFile())
+ return new FileSystemFileHandle(filesystem(), fullPath());
+ DCHECK(isDirectory());
+ return new FileSystemDirectoryHandle(filesystem(), fullPath());
+}
+
void EntryBase::Trace(blink::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..8b4a96b15a9 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/entry_base.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/entry_base.h
@@ -40,6 +40,7 @@ namespace blink {
class DOMFileSystemBase;
class EntrySync;
+class FileSystemBaseHandle;
// A common base class for Entry and EntrySync.
class MODULES_EXPORT EntryBase : public ScriptWrappable {
@@ -56,6 +57,8 @@ class MODULES_EXPORT EntryBase : public ScriptWrappable {
String toURL() const;
+ FileSystemBaseHandle* asFileSystemHandle() const;
+
void Trace(blink::Visitor*) override;
protected:
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_base_handle.cc b/chromium/third_party/blink/renderer/modules/filesystem/file_system_base_handle.cc
new file mode 100644
index 00000000000..f991bfb05f4
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_base_handle.cc
@@ -0,0 +1,26 @@
+// 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/filesystem/file_system_base_handle.h"
+
+#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/modules/filesystem/dom_file_system_base.h"
+#include "third_party/blink/renderer/modules/filesystem/file_system_callbacks.h"
+
+namespace blink {
+
+FileSystemBaseHandle::FileSystemBaseHandle(DOMFileSystemBase* file_system,
+ const String& full_path)
+ : EntryBase(file_system, full_path) {}
+
+ScriptPromise FileSystemBaseHandle::getParent(ScriptState* script_state) {
+ auto* resolver = ScriptPromiseResolver::Create(script_state);
+ ScriptPromise result = resolver->Promise();
+ filesystem()->GetParent(
+ this, new EntryCallbacks::OnDidGetEntryPromiseImpl(resolver),
+ new PromiseErrorCallback(resolver));
+ return result;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_base_handle.h b/chromium/third_party/blink/renderer/modules/filesystem/file_system_base_handle.h
new file mode 100644
index 00000000000..991b19dbc71
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_base_handle.h
@@ -0,0 +1,25 @@
+// 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_FILESYSTEM_FILE_SYSTEM_BASE_HANDLE_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_FILE_SYSTEM_BASE_HANDLE_H_
+
+#include "third_party/blink/renderer/modules/filesystem/entry_base.h"
+
+namespace blink {
+class ScriptPromise;
+class ScriptState;
+
+class FileSystemBaseHandle : public EntryBase {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ explicit FileSystemBaseHandle(DOMFileSystemBase*, const String& full_path);
+
+ ScriptPromise getParent(ScriptState*);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_FILE_SYSTEM_BASE_HANDLE_H_
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_base_handle.idl b/chromium/third_party/blink/renderer/modules/filesystem/file_system_base_handle.idl
new file mode 100644
index 00000000000..70d7786e194
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_base_handle.idl
@@ -0,0 +1,20 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://github.com/WICG/writable-files/blob/master/EXPLAINER.md
+[
+ RuntimeEnabled=WritableFiles,
+ NoInterfaceObject
+] interface FileSystemBaseHandle {
+ // Brand checking APIs because javascript makes it otherwise really hard to
+ // figure out what type an object is when you don't know in which global
+ // (i.e. iframe) the object was created.
+ readonly attribute boolean isFile;
+ readonly attribute boolean isDirectory;
+
+ readonly attribute USVString name;
+
+ [CallWith=ScriptState] Promise<FileSystemDirectoryHandle> getParent();
+ // TODO(mek): Other methods to move/copy/delete entries.
+};
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 49f8b95e141..139e795f2d0 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
@@ -34,6 +34,8 @@
#include "base/memory/ptr_util.h"
#include "third_party/blink/public/platform/web_file_writer.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/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/fileapi/file.h"
#include "third_party/blink/renderer/core/fileapi/file_error.h"
@@ -44,6 +46,7 @@
#include "third_party/blink/renderer/modules/filesystem/dom_file_system_base.h"
#include "third_party/blink/renderer/modules/filesystem/entry.h"
#include "third_party/blink/renderer/modules/filesystem/file_entry.h"
+#include "third_party/blink/renderer/modules/filesystem/file_system_base_handle.h"
#include "third_party/blink/renderer/modules/filesystem/file_writer.h"
#include "third_party/blink/renderer/modules/filesystem/metadata.h"
#include "third_party/blink/renderer/platform/file_metadata.h"
@@ -127,6 +130,20 @@ void ScriptErrorCallback::Invoke(FileError::ErrorCode error) {
ScriptErrorCallback::ScriptErrorCallback(V8ErrorCallback* callback)
: callback_(ToV8PersistentCallbackInterface(callback)) {}
+// PromiseErrorCallback -------------------------------------------------------
+
+PromiseErrorCallback::PromiseErrorCallback(ScriptPromiseResolver* resolver)
+ : resolver_(resolver) {}
+
+void PromiseErrorCallback::Trace(Visitor* visitor) {
+ ErrorCallbackBase::Trace(visitor);
+ visitor->Trace(resolver_);
+}
+
+void PromiseErrorCallback::Invoke(FileError::ErrorCode error) {
+ resolver_->Reject(FileError::CreateDOMException(error));
+}
+
// EntryCallbacks -------------------------------------------------------------
void EntryCallbacks::OnDidGetEntryV8Impl::Trace(blink::Visitor* visitor) {
@@ -138,6 +155,19 @@ void EntryCallbacks::OnDidGetEntryV8Impl::OnSuccess(Entry* entry) {
callback_->InvokeAndReportException(nullptr, entry);
}
+EntryCallbacks::OnDidGetEntryPromiseImpl::OnDidGetEntryPromiseImpl(
+ ScriptPromiseResolver* resolver)
+ : resolver_(resolver) {}
+
+void EntryCallbacks::OnDidGetEntryPromiseImpl::Trace(Visitor* visitor) {
+ OnDidGetEntryCallback::Trace(visitor);
+ visitor->Trace(resolver_);
+}
+
+void EntryCallbacks::OnDidGetEntryPromiseImpl::OnSuccess(Entry* entry) {
+ resolver_->Resolve(entry->asFileSystemHandle());
+}
+
std::unique_ptr<AsyncFileSystemCallbacks> EntryCallbacks::Create(
OnDidGetEntryCallback* success_callback,
ErrorCallbackBase* error_callback,
@@ -239,7 +269,7 @@ std::unique_ptr<AsyncFileSystemCallbacks> FileSystemCallbacks::Create(
OnDidOpenFileSystemCallback* success_callback,
ErrorCallbackBase* error_callback,
ExecutionContext* context,
- FileSystemType type) {
+ mojom::blink::FileSystemType type) {
return base::WrapUnique(
new FileSystemCallbacks(success_callback, error_callback, context, type));
}
@@ -248,7 +278,7 @@ FileSystemCallbacks::FileSystemCallbacks(
OnDidOpenFileSystemCallback* success_callback,
ErrorCallbackBase* error_callback,
ExecutionContext* context,
- FileSystemType type)
+ mojom::blink::FileSystemType type)
: FileSystemCallbacksBase(error_callback, nullptr, context),
success_callback_(success_callback),
type_(type) {}
@@ -284,7 +314,7 @@ ResolveURICallbacks::ResolveURICallbacks(
void ResolveURICallbacks::DidResolveURL(const String& name,
const KURL& root_url,
- FileSystemType type,
+ mojom::blink::FileSystemType type,
const String& file_path,
bool is_directory) {
DOMFileSystem* filesystem =
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 024a3db834f..b14c82c7fab 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
@@ -33,6 +33,7 @@
#include <memory>
+#include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_void_callback.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_entry_callback.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_error_callback.h"
@@ -43,7 +44,6 @@
#include "third_party/blink/renderer/core/fileapi/file_error.h"
#include "third_party/blink/renderer/modules/filesystem/entry_heap_vector.h"
#include "third_party/blink/renderer/platform/async_file_system_callbacks.h"
-#include "third_party/blink/renderer/platform/file_system_type.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"
@@ -59,6 +59,7 @@ class File;
class FileMetadata;
class FileWriterBase;
class Metadata;
+class ScriptPromiseResolver;
// Passed to DOMFileSystem implementations that may report errors. Subclasses
// may capture the error for throwing on return to script (for synchronous APIs)
@@ -117,6 +118,16 @@ class ScriptErrorCallback final : public ErrorCallbackBase {
Member<V8PersistentCallbackInterface<V8ErrorCallback>> callback_;
};
+class PromiseErrorCallback final : public ErrorCallbackBase {
+ public:
+ explicit PromiseErrorCallback(ScriptPromiseResolver*);
+ void Trace(Visitor*) override;
+ void Invoke(FileError::ErrorCode) override;
+
+ private:
+ Member<ScriptPromiseResolver> resolver_;
+};
+
class EntryCallbacks final : public FileSystemCallbacksBase {
public:
class OnDidGetEntryCallback
@@ -145,6 +156,16 @@ class EntryCallbacks final : public FileSystemCallbacksBase {
Member<V8PersistentCallbackInterface<V8EntryCallback>> callback_;
};
+ class OnDidGetEntryPromiseImpl : public OnDidGetEntryCallback {
+ public:
+ explicit OnDidGetEntryPromiseImpl(ScriptPromiseResolver*);
+ void Trace(Visitor*) override;
+ void OnSuccess(Entry*) override;
+
+ private:
+ Member<ScriptPromiseResolver> resolver_;
+ };
+
static std::unique_ptr<AsyncFileSystemCallbacks> Create(
OnDidGetEntryCallback*,
ErrorCallbackBase*,
@@ -232,16 +253,16 @@ class FileSystemCallbacks final : public FileSystemCallbacksBase {
OnDidOpenFileSystemCallback*,
ErrorCallbackBase*,
ExecutionContext*,
- FileSystemType);
+ mojom::blink::FileSystemType);
void DidOpenFileSystem(const String& name, const KURL& root_url) override;
private:
FileSystemCallbacks(OnDidOpenFileSystemCallback*,
ErrorCallbackBase*,
ExecutionContext*,
- FileSystemType);
+ mojom::blink::FileSystemType);
Persistent<OnDidOpenFileSystemCallback> success_callback_;
- FileSystemType type_;
+ mojom::blink::FileSystemType type_;
};
class ResolveURICallbacks final : public FileSystemCallbacksBase {
@@ -253,7 +274,7 @@ class ResolveURICallbacks final : public FileSystemCallbacksBase {
Create(OnDidGetEntryCallback*, ErrorCallbackBase*, ExecutionContext*);
void DidResolveURL(const String& name,
const KURL& root_url,
- FileSystemType,
+ mojom::blink::FileSystemType,
const String& file_path,
bool is_directry) override;
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_client.h b/chromium/third_party/blink/renderer/modules/filesystem/file_system_client.h
index 3a46194cba4..2986f22349b 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/file_system_client.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_client.h
@@ -32,8 +32,8 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_FILE_SYSTEM_CLIENT_H_
#include <memory>
+#include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink.h"
#include "third_party/blink/renderer/modules/modules_export.h"
-#include "third_party/blink/renderer/platform/file_system_type.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/noncopyable.h"
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_handle.cc b/chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_handle.cc
new file mode 100644
index 00000000000..c10c7a481db
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_handle.cc
@@ -0,0 +1,39 @@
+// 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/filesystem/file_system_directory_handle.h"
+
+#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/modules/filesystem/dom_file_system_base.h"
+#include "third_party/blink/renderer/modules/filesystem/file_system_callbacks.h"
+
+namespace blink {
+
+FileSystemDirectoryHandle::FileSystemDirectoryHandle(
+ DOMFileSystemBase* file_system,
+ const String& full_path)
+ : FileSystemBaseHandle(file_system, full_path) {}
+
+ScriptPromise FileSystemDirectoryHandle::getFile(ScriptState* script_state,
+ const String& name) {
+ auto* resolver = ScriptPromiseResolver::Create(script_state);
+ ScriptPromise result = resolver->Promise();
+ filesystem()->GetFile(this, name, FileSystemFlags(),
+ new EntryCallbacks::OnDidGetEntryPromiseImpl(resolver),
+ new PromiseErrorCallback(resolver));
+ return result;
+}
+
+ScriptPromise FileSystemDirectoryHandle::getDirectory(ScriptState* script_state,
+ const String& name) {
+ auto* resolver = ScriptPromiseResolver::Create(script_state);
+ ScriptPromise result = resolver->Promise();
+ filesystem()->GetDirectory(
+ this, name, FileSystemFlags(),
+ new EntryCallbacks::OnDidGetEntryPromiseImpl(resolver),
+ new PromiseErrorCallback(resolver));
+ return result;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_handle.h b/chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_handle.h
new file mode 100644
index 00000000000..cd3fd96fc8c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_handle.h
@@ -0,0 +1,25 @@
+// 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_FILESYSTEM_FILE_SYSTEM_DIRECTORY_HANDLE_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_FILE_SYSTEM_DIRECTORY_HANDLE_H_
+
+#include "third_party/blink/renderer/modules/filesystem/file_system_base_handle.h"
+
+namespace blink {
+
+class FileSystemDirectoryHandle : public FileSystemBaseHandle {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ FileSystemDirectoryHandle(DOMFileSystemBase*, const String& full_path);
+
+ bool isDirectory() const override { return true; }
+ ScriptPromise getFile(ScriptState*, const String& name);
+ ScriptPromise getDirectory(ScriptState*, const String& name);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_FILE_SYSTEM_DIRECTORY_HANDLE_H_
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_handle.idl b/chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_handle.idl
new file mode 100644
index 00000000000..1b13904a04c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_directory_handle.idl
@@ -0,0 +1,12 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://github.com/WICG/writable-files/blob/master/EXPLAINER.md
+[
+ RuntimeEnabled=WritableFiles
+] interface FileSystemDirectoryHandle : FileSystemBaseHandle {
+ [CallWith=ScriptState] Promise<FileSystemFileHandle> getFile(USVString name);
+ [CallWith=ScriptState] Promise<FileSystemDirectoryHandle> getDirectory(USVString name);
+ // TODO(mek): Other methods such as getEntries etc.
+};
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_file_handle.cc b/chromium/third_party/blink/renderer/modules/filesystem/file_system_file_handle.cc
new file mode 100644
index 00000000000..91deae419cf
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_file_handle.cc
@@ -0,0 +1,93 @@
+// 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/filesystem/file_system_file_handle.h"
+
+#include "third_party/blink/public/mojom/filesystem/file_writer.mojom-blink.h"
+#include "third_party/blink/public/platform/web_file_system.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/fileapi/file.h"
+#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_writer.h"
+
+namespace blink {
+
+namespace {
+
+class CreateWriterCallbacks
+ : public WebCallbacks<mojo::ScopedMessagePipeHandle, base::File::Error> {
+ public:
+ explicit CreateWriterCallbacks(ScriptPromiseResolver* resolver)
+ : resolver_(resolver) {}
+
+ void OnSuccess(mojo::ScopedMessagePipeHandle handle) override {
+ mojom::blink::FileWriterPtr mojo_writer(mojom::blink::FileWriterPtrInfo(
+ std::move(handle), mojom::blink::FileWriter::Version_));
+ resolver_->Resolve(new FileSystemWriter(std::move(mojo_writer)));
+ }
+
+ void OnError(base::File::Error error) override {
+ resolver_->Reject(FileError::CreateDOMException(error));
+ }
+
+ private:
+ Persistent<ScriptPromiseResolver> resolver_;
+};
+
+class OnDidCreateSnapshotFilePromise
+ : public SnapshotFileCallback::OnDidCreateSnapshotFileCallback {
+ public:
+ explicit OnDidCreateSnapshotFilePromise(ScriptPromiseResolver* resolver)
+ : resolver_(resolver) {}
+ void Trace(Visitor* visitor) override {
+ OnDidCreateSnapshotFileCallback::Trace(visitor);
+ visitor->Trace(resolver_);
+ }
+ void OnSuccess(File* file) override { resolver_->Resolve(file); }
+
+ private:
+ Member<ScriptPromiseResolver> resolver_;
+};
+
+} // namespace
+
+FileSystemFileHandle::FileSystemFileHandle(DOMFileSystemBase* file_system,
+ const String& full_path)
+ : FileSystemBaseHandle(file_system, full_path) {}
+
+ScriptPromise FileSystemFileHandle::createWriter(ScriptState* script_state) {
+ if (!filesystem()->FileSystem()) {
+ return ScriptPromise::RejectWithDOMException(
+ script_state, FileError::CreateDOMException(FileError::kAbortErr));
+ }
+
+ auto* resolver = ScriptPromiseResolver::Create(script_state);
+ ScriptPromise result = resolver->Promise();
+ filesystem()->FileSystem()->CreateFileWriter(
+ filesystem()->CreateFileSystemURL(this),
+ std::make_unique<CreateWriterCallbacks>(resolver));
+ return result;
+}
+
+ScriptPromise FileSystemFileHandle::getFile(ScriptState* script_state) {
+ if (!filesystem()->FileSystem()) {
+ return ScriptPromise::RejectWithDOMException(
+ script_state, FileError::CreateDOMException(FileError::kAbortErr));
+ }
+
+ auto* resolver = ScriptPromiseResolver::Create(script_state);
+ ScriptPromise result = resolver->Promise();
+ KURL file_system_url = filesystem()->CreateFileSystemURL(this);
+ filesystem()->FileSystem()->CreateSnapshotFileAndReadMetadata(
+ file_system_url,
+ SnapshotFileCallback::Create(filesystem(), name(), file_system_url,
+ new OnDidCreateSnapshotFilePromise(resolver),
+ new PromiseErrorCallback(resolver),
+ ExecutionContext::From(script_state)));
+ return result;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_file_handle.h b/chromium/third_party/blink/renderer/modules/filesystem/file_system_file_handle.h
new file mode 100644
index 00000000000..76bb76d15fd
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_file_handle.h
@@ -0,0 +1,25 @@
+// 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_FILESYSTEM_FILE_SYSTEM_FILE_HANDLE_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_FILE_SYSTEM_FILE_HANDLE_H_
+
+#include "third_party/blink/renderer/modules/filesystem/file_system_base_handle.h"
+
+namespace blink {
+
+class FileSystemFileHandle : public FileSystemBaseHandle {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ FileSystemFileHandle(DOMFileSystemBase*, const String& full_path);
+
+ bool isFile() const override { return true; }
+ ScriptPromise createWriter(ScriptState*);
+ ScriptPromise getFile(ScriptState*);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_FILE_SYSTEM_FILE_HANDLE_H_
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_file_handle.idl b/chromium/third_party/blink/renderer/modules/filesystem/file_system_file_handle.idl
new file mode 100644
index 00000000000..7b554909e65
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_file_handle.idl
@@ -0,0 +1,11 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://github.com/WICG/writable-files/blob/master/EXPLAINER.md
+[
+ RuntimeEnabled=WritableFiles
+] interface FileSystemFileHandle : FileSystemBaseHandle {
+ [CallWith=ScriptState] Promise<FileSystemWriter> createWriter();
+ [CallWith=ScriptState] Promise<File> getFile();
+};
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_writer.cc b/chromium/third_party/blink/renderer/modules/filesystem/file_system_writer.cc
new file mode 100644
index 00000000000..ab254de4e6e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_writer.cc
@@ -0,0 +1,86 @@
+// 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/filesystem/file_system_writer.h"
+
+#include "third_party/blink/renderer/bindings/core/v8/script_promise.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/fileapi/file_error.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
+
+namespace blink {
+
+FileSystemWriter::FileSystemWriter(mojom::blink::FileWriterPtr writer)
+ : writer_(std::move(writer)) {
+ DCHECK(writer_);
+}
+
+ScriptPromise FileSystemWriter::write(ScriptState* script_state,
+ uint64_t position,
+ Blob* blob) {
+ if (!writer_ || pending_operation_) {
+ return ScriptPromise::RejectWithDOMException(
+ script_state,
+ DOMException::Create(DOMExceptionCode::kInvalidStateError));
+ }
+ pending_operation_ = ScriptPromiseResolver::Create(script_state);
+ ScriptPromise result = pending_operation_->Promise();
+ writer_->Write(
+ position, blob->AsMojoBlob(),
+ WTF::Bind(&FileSystemWriter::WriteComplete, WrapPersistent(this)));
+ return result;
+}
+
+ScriptPromise FileSystemWriter::truncate(ScriptState* script_state,
+ uint64_t size) {
+ if (!writer_ || pending_operation_) {
+ return ScriptPromise::RejectWithDOMException(
+ script_state,
+ DOMException::Create(DOMExceptionCode::kInvalidStateError));
+ }
+ pending_operation_ = ScriptPromiseResolver::Create(script_state);
+ ScriptPromise result = pending_operation_->Promise();
+ writer_->Truncate(size, WTF::Bind(&FileSystemWriter::TruncateComplete,
+ WrapPersistent(this)));
+ return result;
+}
+
+ScriptPromise FileSystemWriter::close(ScriptState* script_state) {
+ if (!writer_) {
+ return ScriptPromise::RejectWithDOMException(
+ script_state,
+ DOMException::Create(DOMExceptionCode::kInvalidStateError));
+ }
+ writer_ = nullptr;
+ return ScriptPromise::CastUndefined(script_state);
+}
+
+void FileSystemWriter::Trace(Visitor* visitor) {
+ ScriptWrappable::Trace(visitor);
+ visitor->Trace(pending_operation_);
+}
+
+void FileSystemWriter::WriteComplete(base::File::Error result,
+ uint64_t bytes_written) {
+ DCHECK(pending_operation_);
+ if (result == base::File::FILE_OK) {
+ pending_operation_->Resolve();
+ } else {
+ pending_operation_->Reject(FileError::CreateDOMException(result));
+ }
+ pending_operation_ = nullptr;
+}
+
+void FileSystemWriter::TruncateComplete(base::File::Error result) {
+ DCHECK(pending_operation_);
+ if (result == base::File::FILE_OK) {
+ pending_operation_->Resolve();
+ } else {
+ pending_operation_->Reject(FileError::CreateDOMException(result));
+ }
+ pending_operation_ = nullptr;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_writer.h b/chromium/third_party/blink/renderer/modules/filesystem/file_system_writer.h
new file mode 100644
index 00000000000..f00cd9f417f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_writer.h
@@ -0,0 +1,41 @@
+// 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_FILESYSTEM_FILE_SYSTEM_WRITER_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_FILE_SYSTEM_WRITER_H_
+
+#include "third_party/blink/public/mojom/filesystem/file_writer.mojom-blink.h"
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+
+namespace blink {
+
+class Blob;
+class ScriptPromise;
+class ScriptPromiseResolver;
+class ScriptState;
+
+class FileSystemWriter final : public ScriptWrappable {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ explicit FileSystemWriter(mojom::blink::FileWriterPtr);
+
+ ScriptPromise write(ScriptState*, uint64_t position, Blob*);
+ ScriptPromise truncate(ScriptState*, uint64_t size);
+ ScriptPromise close(ScriptState*);
+
+ void Trace(Visitor*) override;
+
+ private:
+ void WriteComplete(base::File::Error result, uint64_t bytes_written);
+ void TruncateComplete(base::File::Error result);
+
+ mojom::blink::FileWriterPtr writer_;
+
+ Member<ScriptPromiseResolver> pending_operation_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_FILE_SYSTEM_WRITER_H_
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_writer.idl b/chromium/third_party/blink/renderer/modules/filesystem/file_system_writer.idl
new file mode 100644
index 00000000000..c4362be6e59
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_writer.idl
@@ -0,0 +1,15 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://github.com/WICG/writable-files/blob/master/EXPLAINER.md
+[
+ NoInterfaceObject,
+ RuntimeEnabled=WritableFiles
+] interface FileSystemWriter {
+ // TODO(mek): Support other types, such as ReadableStream, by using 'any'.
+ [CallWith=ScriptState] Promise<void> write(unsigned long long position, Blob data);
+ [CallWith=ScriptState] Promise<void> truncate(unsigned long long size);
+
+ [CallWith=ScriptState] Promise<void> close();
+};
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 1736ebc2407..b8f8bb66861 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/file_writer.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_writer.cc
@@ -293,7 +293,7 @@ void FileWriter::FireEvent(const AtomicString& type) {
probe::AsyncTask async_task(GetExecutionContext(), this);
++recursion_depth_;
DispatchEvent(
- ProgressEvent::Create(type, true, bytes_written_, bytes_to_write_));
+ *ProgressEvent::Create(type, true, bytes_written_, bytes_to_write_));
--recursion_depth_;
DCHECK_GE(recursion_depth_, 0);
}
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 18a481a788a..4eb2801f037 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
@@ -31,14 +31,21 @@
#include "third_party/blink/renderer/modules/filesystem/local_file_system.h"
#include <memory>
+#include "base/feature_list.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/web_file_system.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/fileapi/file_error.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/workers/worker_global_scope.h"
+#include "third_party/blink/renderer/modules/filesystem/directory_entry.h"
+#include "third_party/blink/renderer/modules/filesystem/dom_file_system.h"
#include "third_party/blink/renderer/modules/filesystem/file_system_client.h"
#include "third_party/blink/renderer/platform/async_file_system_callbacks.h"
#include "third_party/blink/renderer/platform/content_setting_callbacks.h"
@@ -90,7 +97,7 @@ void LocalFileSystem::ResolveURL(
void LocalFileSystem::RequestFileSystem(
ExecutionContext* context,
- FileSystemType type,
+ mojom::blink::FileSystemType type,
long long size,
std::unique_ptr<AsyncFileSystemCallbacks> callbacks) {
CallbackWrapper* wrapper = new CallbackWrapper(std::move(callbacks));
@@ -104,6 +111,70 @@ void LocalFileSystem::RequestFileSystem(
WrapPersistent(wrapper)));
}
+namespace {
+
+class ChooseEntryCallbacks : public WebFileSystem::ChooseEntryCallbacks {
+ public:
+ ChooseEntryCallbacks(ScriptPromiseResolver* resolver, bool return_multiple)
+ : resolver_(resolver), return_multiple_(return_multiple) {}
+
+ void OnSuccess(WebVector<WebFileSystem::FileSystemEntry> entries) override {
+ ScriptState::Scope scope(resolver_->GetScriptState());
+ if (return_multiple_) {
+ Vector<ScriptPromise> result;
+ result.ReserveInitialCapacity(entries.size());
+ for (const auto& entry : entries)
+ result.emplace_back(CreateFileHandle(entry));
+ resolver_->Resolve(ScriptPromise::All(resolver_->GetScriptState(), result)
+ .GetScriptValue());
+ } else {
+ DCHECK_EQ(1u, entries.size());
+ resolver_->Resolve(CreateFileHandle(entries[0]).GetScriptValue());
+ }
+ }
+
+ void OnError(base::File::Error error) override {
+ resolver_->Reject(FileError::CreateDOMException(error));
+ }
+
+ private:
+ ScriptPromise CreateFileHandle(const WebFileSystem::FileSystemEntry& entry) {
+ auto* new_resolver =
+ ScriptPromiseResolver::Create(resolver_->GetScriptState());
+ ScriptPromise result = new_resolver->Promise();
+ auto* fs = DOMFileSystem::CreateIsolatedFileSystem(
+ resolver_->GetExecutionContext(), entry.file_system_id);
+ // TODO(mek): Try to create handle directly rather than having to do more
+ // IPCs to get the actual entries.
+ fs->GetFile(fs->root(), entry.base_name, FileSystemFlags(),
+ new EntryCallbacks::OnDidGetEntryPromiseImpl(new_resolver),
+ new PromiseErrorCallback(new_resolver));
+ return result;
+ }
+
+ Persistent<ScriptPromiseResolver> resolver_;
+ bool return_multiple_;
+};
+
+} // namespace
+
+void LocalFileSystem::ChooseEntry(ScriptPromiseResolver* resolver) {
+ if (!base::FeatureList::IsEnabled(blink::features::kWritableFilesAPI)) {
+ resolver->Reject(FileError::CreateDOMException(FileError::kAbortErr));
+ return;
+ }
+
+ WebFileSystem* file_system = GetFileSystem();
+ if (!file_system) {
+ resolver->Reject(FileError::CreateDOMException(FileError::kAbortErr));
+ return;
+ }
+
+ file_system->ChooseEntry(
+ Supplement<LocalFrame>::GetSupplementable()->Client()->GetWebFrame(),
+ std::make_unique<ChooseEntryCallbacks>(resolver, false));
+}
+
WebFileSystem* LocalFileSystem::GetFileSystem() const {
Platform* platform = Platform::Current();
if (!platform)
@@ -145,9 +216,10 @@ void LocalFileSystem::FileSystemNotAllowedInternal(ExecutionContext* context,
FileError::kAbortErr));
}
-void LocalFileSystem::FileSystemAllowedInternal(ExecutionContext* context,
- FileSystemType type,
- CallbackWrapper* callbacks) {
+void LocalFileSystem::FileSystemAllowedInternal(
+ ExecutionContext* context,
+ mojom::blink::FileSystemType type,
+ CallbackWrapper* callbacks) {
WebFileSystem* file_system = GetFileSystem();
if (!file_system) {
FileSystemNotAvailable(context, callbacks);
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 10289752635..f62847ca161 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
@@ -32,10 +32,10 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_LOCAL_FILE_SYSTEM_H_
#include <memory>
+#include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/workers/worker_clients.h"
#include "third_party/blink/renderer/platform/bindings/name_client.h"
-#include "third_party/blink/renderer/platform/file_system_type.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/supplementable.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
@@ -48,6 +48,7 @@ class CallbackWrapper;
class FileSystemClient;
class ExecutionContext;
class KURL;
+class ScriptPromiseResolver;
class WebFileSystem;
class LocalFileSystem final : public GarbageCollectedFinalized<LocalFileSystem>,
@@ -68,10 +69,12 @@ class LocalFileSystem final : public GarbageCollectedFinalized<LocalFileSystem>,
const KURL&,
std::unique_ptr<AsyncFileSystemCallbacks>);
void RequestFileSystem(ExecutionContext*,
- FileSystemType,
+ mojom::blink::FileSystemType,
long long size,
std::unique_ptr<AsyncFileSystemCallbacks>);
+ void ChooseEntry(ScriptPromiseResolver*);
+
FileSystemClient& Client() const { return *client_; }
static LocalFileSystem* From(ExecutionContext&);
@@ -88,7 +91,7 @@ class LocalFileSystem final : public GarbageCollectedFinalized<LocalFileSystem>,
base::OnceClosure denied);
void FileSystemNotAllowedInternal(ExecutionContext*, CallbackWrapper*);
void FileSystemAllowedInternal(ExecutionContext*,
- FileSystemType,
+ mojom::blink::FileSystemType,
CallbackWrapper*);
void ResolveURLInternal(ExecutionContext*, const KURL&, CallbackWrapper*);
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..39bd2744cfb 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
@@ -37,4 +37,11 @@
// TODO(crbug.com/841185): |errorCallback| is not nullable in the spec.
[RuntimeEnabled=FileSystem] void webkitResolveLocalFileSystemURL(DOMString url,
EntryCallback successCallback, optional ErrorCallback? errorCallback);
+
+ // https://github.com/WICG/writable-files/blob/master/EXPLAINER.md
+ // TODO(crbug.com/878581): This needs some kind of options dictionary.
+ // TODO(crbug.com/878566): This should be SecureContext, but that is
+ // currently broken.
+ [RuntimeEnabled=WritableFiles, CallWith=ScriptState]
+ Promise<(FileSystemBaseHandle or sequence<FileSystemBaseHandle>)> chooseFileSystemEntries();
};
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/worker_global_scope_file_system.cc b/chromium/third_party/blink/renderer/modules/filesystem/worker_global_scope_file_system.cc
index f7c40b2fbab..26b2ce2eeea 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/worker_global_scope_file_system.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/worker_global_scope_file_system.cc
@@ -29,6 +29,7 @@
#include <memory>
+#include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink.h"
#include "third_party/blink/renderer/core/fileapi/file_error.h"
#include "third_party/blink/renderer/core/frame/use_counter.h"
#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
@@ -40,7 +41,6 @@
#include "third_party/blink/renderer/modules/filesystem/local_file_system.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/file_system_type.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
namespace blink {
@@ -61,7 +61,8 @@ void WorkerGlobalScopeFileSystem::webkitRequestFileSystem(
UseCounter::Count(secure_context, WebFeature::kFileAccessedFileSystem);
}
- FileSystemType file_system_type = static_cast<FileSystemType>(type);
+ mojom::blink::FileSystemType file_system_type =
+ static_cast<mojom::blink::FileSystemType>(type);
if (!DOMFileSystemBase::IsValidType(file_system_type)) {
DOMFileSystem::ReportError(&worker,
ScriptErrorCallback::Wrap(error_callback),
@@ -91,7 +92,8 @@ DOMFileSystemSync* WorkerGlobalScopeFileSystem::webkitRequestFileSystemSync(
UseCounter::Count(secure_context, WebFeature::kFileAccessedFileSystem);
}
- FileSystemType file_system_type = static_cast<FileSystemType>(type);
+ mojom::blink::FileSystemType file_system_type =
+ static_cast<mojom::blink::FileSystemType>(type);
if (!DOMFileSystemBase::IsValidType(file_system_type)) {
exception_state.ThrowDOMException(
DOMExceptionCode::kInvalidModificationError,
@@ -178,11 +180,11 @@ EntrySync* WorkerGlobalScopeFileSystem::webkitResolveLocalFileSystemSyncURL(
}
static_assert(static_cast<int>(WorkerGlobalScopeFileSystem::kTemporary) ==
- static_cast<int>(kFileSystemTypeTemporary),
+ static_cast<int>(mojom::blink::FileSystemType::kTemporary),
"WorkerGlobalScopeFileSystem::kTemporary should match "
"FileSystemTypeTemporary");
static_assert(static_cast<int>(WorkerGlobalScopeFileSystem::kPersistent) ==
- static_cast<int>(kFileSystemTypePersistent),
+ static_cast<int>(mojom::blink::FileSystemType::kPersistent),
"WorkerGlobalScopeFileSystem::kPersistent should match "
"FileSystemTypePersistent");
diff --git a/chromium/third_party/blink/renderer/modules/gamepad/gamepad.idl b/chromium/third_party/blink/renderer/modules/gamepad/gamepad.idl
index 4d5cc263263..e4abab52994 100644
--- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad.idl
+++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad.idl
@@ -43,7 +43,7 @@ interface Gamepad {
// https://github.com/w3c/gamepad/pull/68
[RuntimeEnabled=GamepadVibration, MeasureAs=GamepadVibrationActuator] readonly attribute GamepadHapticActuator? vibrationActuator;
- [RuntimeEnabled=GamepadExtensions, MeasureAs=GamepadPose] readonly attribute GamepadPose? pose;
+ [OriginTrialEnabled=GamepadExtensions, MeasureAs=GamepadPose] readonly attribute GamepadPose? pose;
[OriginTrialEnabled=WebXRGamepadSupport, MeasureAs=GamepadHand] readonly attribute GamepadHand hand;
// https://w3c.github.io/webvr/#interface-gamepad
diff --git a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.cc b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.cc
index 20abe6a14d9..f3771a13499 100644
--- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.cc
+++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.cc
@@ -26,7 +26,7 @@ void GamepadDispatcher::SampleGamepads(device::Gamepads& gamepads) {
}
void GamepadDispatcher::PlayVibrationEffectOnce(
- int pad_index,
+ uint32_t pad_index,
device::mojom::blink::GamepadHapticEffectType type,
device::mojom::blink::GamepadEffectParametersPtr params,
GamepadHapticsManager::PlayVibrationEffectOnceCallback callback) {
@@ -36,7 +36,7 @@ void GamepadDispatcher::PlayVibrationEffectOnce(
}
void GamepadDispatcher::ResetVibrationActuator(
- int pad_index,
+ uint32_t pad_index,
GamepadHapticsManager::ResetVibrationActuatorCallback callback) {
InitializeHaptics();
gamepad_haptics_manager_->ResetVibrationActuator(pad_index,
@@ -58,21 +58,27 @@ void GamepadDispatcher::Trace(blink::Visitor* visitor) {
PlatformEventDispatcher::Trace(visitor);
}
-void GamepadDispatcher::DidConnectGamepad(unsigned index,
+void GamepadDispatcher::DidConnectGamepad(uint32_t index,
const device::Gamepad& gamepad) {
DispatchDidConnectOrDisconnectGamepad(index, gamepad, true);
}
-void GamepadDispatcher::DidDisconnectGamepad(unsigned index,
+void GamepadDispatcher::DidDisconnectGamepad(uint32_t index,
const device::Gamepad& gamepad) {
DispatchDidConnectOrDisconnectGamepad(index, gamepad, false);
}
+void GamepadDispatcher::ButtonOrAxisDidChange(uint32_t index,
+ const device::Gamepad& gamepad) {
+ DCHECK_LT(index, device::Gamepads::kItemsLengthCap);
+ NotifyControllers();
+}
+
void GamepadDispatcher::DispatchDidConnectOrDisconnectGamepad(
- unsigned index,
+ uint32_t index,
const device::Gamepad& gamepad,
bool connected) {
- DCHECK(index < device::Gamepads::kItemsLengthCap);
+ DCHECK_LT(index, device::Gamepads::kItemsLengthCap);
DCHECK_EQ(connected, gamepad.connected);
NotifyControllers();
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 381b073c6c9..b809d7b3f33 100644
--- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.h
+++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.h
@@ -27,12 +27,12 @@ class GamepadDispatcher final
void SampleGamepads(device::Gamepads&);
- void PlayVibrationEffectOnce(int pad_index,
+ void PlayVibrationEffectOnce(uint32_t pad_index,
device::mojom::blink::GamepadHapticEffectType,
device::mojom::blink::GamepadEffectParametersPtr,
device::mojom::blink::GamepadHapticsManager::
PlayVibrationEffectOnceCallback);
- void ResetVibrationActuator(int pad_index,
+ void ResetVibrationActuator(uint32_t pad_index,
device::mojom::blink::GamepadHapticsManager::
ResetVibrationActuatorCallback);
@@ -44,14 +44,15 @@ class GamepadDispatcher final
void InitializeHaptics();
// WebGamepadListener
- void DidConnectGamepad(unsigned index, const device::Gamepad&) override;
- void DidDisconnectGamepad(unsigned index, const device::Gamepad&) override;
+ void DidConnectGamepad(uint32_t index, const device::Gamepad&) override;
+ void DidDisconnectGamepad(uint32_t index, const device::Gamepad&) override;
+ void ButtonOrAxisDidChange(uint32_t index, const device::Gamepad&) override;
// PlatformEventDispatcher
void StartListening(LocalFrame* frame) override;
void StopListening() override;
- void DispatchDidConnectOrDisconnectGamepad(unsigned index,
+ void DispatchDidConnectOrDisconnectGamepad(uint32_t index,
const device::Gamepad&,
bool connected);
diff --git a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_pose.idl b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_pose.idl
index e9f87f53295..05495f25d8c 100644
--- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_pose.idl
+++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_pose.idl
@@ -4,7 +4,7 @@
// https://w3c.github.io/gamepad/extensions.html#gamepadpose-interface
[
- RuntimeEnabled=GamepadExtensions
+ OriginTrialEnabled=GamepadExtensions
] interface GamepadPose {
[MeasureAs=GamepadPoseHasOrientation] readonly attribute boolean hasOrientation;
[MeasureAs=GamepadPoseHasPosition] readonly attribute boolean hasPosition;
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 5b8aac1da21..54491f6ad98 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
@@ -110,7 +110,7 @@ void GamepadSharedMemoryReader::SampleGamepads(device::Gamepads& gamepads) {
// 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 (unsigned i = 0; i < device::Gamepads::kItemsLengthCap; i++)
+ for (size_t i = 0; i < device::Gamepads::kItemsLengthCap; i++)
gamepads.items[i].connected = false;
}
}
@@ -121,7 +121,7 @@ GamepadSharedMemoryReader::~GamepadSharedMemoryReader() {
}
void GamepadSharedMemoryReader::GamepadConnected(
- int index,
+ uint32_t index,
const device::Gamepad& gamepad) {
// The browser already checks if the user actually interacted with a device.
ever_interacted_with_ = true;
@@ -131,10 +131,17 @@ void GamepadSharedMemoryReader::GamepadConnected(
}
void GamepadSharedMemoryReader::GamepadDisconnected(
- int index,
+ uint32_t index,
const device::Gamepad& gamepad) {
if (listener_)
listener_->DidDisconnectGamepad(index, gamepad);
}
+void GamepadSharedMemoryReader::GamepadButtonOrAxisChanged(
+ uint32_t index,
+ const device::Gamepad& gamepad) {
+ if (listener_)
+ listener_->ButtonOrAxisDidChange(index, gamepad);
+}
+
} // namespace blink
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 f1342ccd183..f1022927b62 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
@@ -37,8 +37,12 @@ class GamepadSharedMemoryReader : public device::mojom::blink::GamepadObserver {
private:
// device::mojom::blink::GamepadObserver methods.
- void GamepadConnected(int index, const device::Gamepad& gamepad) override;
- void GamepadDisconnected(int index, const device::Gamepad& gamepad) override;
+ void GamepadConnected(uint32_t index,
+ const device::Gamepad& gamepad) override;
+ void GamepadDisconnected(uint32_t index,
+ const device::Gamepad& gamepad) override;
+ void GamepadButtonOrAxisChanged(uint32_t index,
+ const device::Gamepad& gamepad) override;
base::ReadOnlySharedMemoryRegion renderer_shared_buffer_region_;
base::ReadOnlySharedMemoryMapping renderer_shared_buffer_mapping_;
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 a6e566ae2b4..71e9b2285ec 100644
--- a/chromium/third_party/blink/renderer/modules/gamepad/navigator_gamepad.cc
+++ b/chromium/third_party/blink/renderer/modules/gamepad/navigator_gamepad.cc
@@ -88,7 +88,7 @@ bool HasUserActivation(GamepadList* gamepads) {
} // namespace
template <typename T>
-static void SampleGamepad(unsigned index,
+static void SampleGamepad(size_t index,
T& gamepad,
const device::Gamepad& device_gamepad,
const TimeTicks& navigation_start) {
@@ -138,7 +138,7 @@ static void SampleGamepads(ListType* into,
GamepadDispatcher::Instance().SampleGamepads(gamepads);
- for (unsigned i = 0; i < device::Gamepads::kItemsLengthCap; ++i) {
+ for (size_t i = 0; i < device::Gamepads::kItemsLengthCap; ++i) {
device::Gamepad& web_gamepad = gamepads.items[i];
bool hide_xr_gamepad = false;
@@ -146,7 +146,7 @@ static void SampleGamepads(ListType* into,
bool webxr_enabled =
(context && OriginTrials::WebXRGamepadSupportEnabled(context) &&
OriginTrials::WebXREnabled(context));
- bool webvr_enabled = (context && RuntimeEnabledFeatures::WebVREnabled());
+ bool webvr_enabled = (context && OriginTrials::WebVREnabled(context));
if (!webxr_enabled && !webvr_enabled) {
// If neither WebXR nor WebVR are enabled, we should not expose XR-
@@ -256,7 +256,7 @@ void NavigatorGamepad::DispatchOneEvent() {
const AtomicString& event_name = gamepad->connected()
? EventTypeNames::gamepadconnected
: EventTypeNames::gamepaddisconnected;
- DomWindow()->DispatchEvent(GamepadEvent::Create(
+ DomWindow()->DispatchEvent(*GamepadEvent::Create(
event_name, Event::Bubbles::kNo, Event::Cancelable::kYes, gamepad));
if (!pending_events_.IsEmpty()) {
@@ -384,7 +384,7 @@ void NavigatorGamepad::SampleAndCheckConnectedGamepads() {
bool NavigatorGamepad::CheckConnectedGamepads(GamepadList* old_gamepads,
GamepadList* new_gamepads) {
int disconnection_count = 0;
- for (unsigned i = 0; i < device::Gamepads::kItemsLengthCap; ++i) {
+ for (size_t i = 0; i < device::Gamepads::kItemsLengthCap; ++i) {
Gamepad* old_gamepad = old_gamepads ? old_gamepads->item(i) : nullptr;
Gamepad* new_gamepad = new_gamepads->item(i);
bool connected, disconnected;
diff --git a/chromium/third_party/blink/renderer/modules/geolocation/geolocation.cc b/chromium/third_party/blink/renderer/modules/geolocation/geolocation.cc
index 102af1a7056..b5b03638b30 100644
--- a/chromium/third_party/blink/renderer/modules/geolocation/geolocation.cc
+++ b/chromium/third_party/blink/renderer/modules/geolocation/geolocation.cc
@@ -151,10 +151,6 @@ void Geolocation::RecordOriginTypeAccess() const {
UseCounter::Count(document, WebFeature::kGeolocationSecureOrigin);
UseCounter::CountCrossOriginIframe(
*document, WebFeature::kGeolocationSecureOriginIframe);
- if (!RuntimeEnabledFeatures::FeaturePolicyForPermissionsEnabled()) {
- Deprecation::CountDeprecationFeaturePolicy(
- *document, mojom::FeaturePolicyFeature::kGeolocation);
- }
} else if (GetFrame()
->GetSettings()
->GetAllowGeolocationOnInsecureOrigins()) {
@@ -169,10 +165,6 @@ void Geolocation::RecordOriginTypeAccess() const {
WebFeature::kGeolocationInsecureOriginIframeDeprecatedNotRemoved);
HostsUsingFeatures::CountAnyWorld(
*document, HostsUsingFeatures::Feature::kGeolocationInsecureHost);
- if (!RuntimeEnabledFeatures::FeaturePolicyForPermissionsEnabled()) {
- Deprecation::CountDeprecationFeaturePolicy(
- *document, mojom::FeaturePolicyFeature::kGeolocation);
- }
} else {
Deprecation::CountDeprecation(document,
WebFeature::kGeolocationInsecureOrigin);
@@ -189,7 +181,6 @@ void Geolocation::getCurrentPosition(V8PositionCallback* success_callback,
if (!GetFrame())
return;
- ReportGeolocationViolation(GetDocument());
probe::breakableLocation(GetDocument(), "Geolocation.getCurrentPosition");
GeoNotifier* notifier =
@@ -206,7 +197,6 @@ int Geolocation::watchPosition(V8PositionCallback* success_callback,
if (!GetFrame())
return 0;
- ReportGeolocationViolation(GetDocument());
probe::breakableLocation(GetDocument(), "Geolocation.watchPosition");
GeoNotifier* notifier =
@@ -234,20 +224,19 @@ void Geolocation::StartRequest(GeoNotifier* notifier) {
return;
}
- if (RuntimeEnabledFeatures::FeaturePolicyForPermissionsEnabled()) {
- if (!GetFrame()->IsFeatureEnabled(
- mojom::FeaturePolicyFeature::kGeolocation)) {
- UseCounter::Count(GetDocument(),
- WebFeature::kGeolocationDisabledByFeaturePolicy);
- GetDocument()->AddConsoleMessage(
- ConsoleMessage::Create(kJSMessageSource, kWarningMessageLevel,
- kFeaturePolicyConsoleWarning));
- notifier->SetFatalError(PositionError::Create(
- PositionError::kPermissionDenied, kFeaturePolicyErrorMessage));
- return;
- }
+ if (!GetFrame()->IsFeatureEnabled(mojom::FeaturePolicyFeature::kGeolocation,
+ ReportOptions::kReportOnFailure)) {
+ UseCounter::Count(GetDocument(),
+ WebFeature::kGeolocationDisabledByFeaturePolicy);
+ GetDocument()->AddConsoleMessage(ConsoleMessage::Create(
+ kJSMessageSource, kErrorMessageLevel, kFeaturePolicyConsoleWarning));
+ notifier->SetFatalError(PositionError::Create(
+ PositionError::kPermissionDenied, kFeaturePolicyErrorMessage));
+ return;
}
+ ReportGeolocationViolation(GetDocument());
+
if (HaveSuitableCachedPosition(notifier->Options())) {
notifier->SetUseCachedPosition();
} else {
diff --git a/chromium/third_party/blink/renderer/modules/geolocation/geoposition.h b/chromium/third_party/blink/renderer/modules/geolocation/geoposition.h
index b985d3d5b6b..cbb5c44e949 100644
--- a/chromium/third_party/blink/renderer/modules/geolocation/geoposition.h
+++ b/chromium/third_party/blink/renderer/modules/geolocation/geoposition.h
@@ -26,6 +26,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_GEOLOCATION_GEOPOSITION_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_GEOLOCATION_GEOPOSITION_H_
+#include "third_party/blink/renderer/core/dom/dom_time_stamp.h"
#include "third_party/blink/renderer/modules/event_modules.h"
#include "third_party/blink/renderer/modules/geolocation/coordinates.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
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 e9d81621b24..e76a6b3f4cd 100644
--- a/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.cc
+++ b/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.cc
@@ -25,6 +25,7 @@
#include "third_party/blink/renderer/modules/mediastream/media_track_constraints.h"
#include "third_party/blink/renderer/platform/mojo/mojo_helper.h"
#include "third_party/blink/renderer/platform/waitable_event.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/BUILD.gn b/chromium/third_party/blink/renderer/modules/indexeddb/BUILD.gn
index 58571e7a975..b16dcc0321f 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/BUILD.gn
@@ -22,7 +22,6 @@ blink_modules_sources("indexeddb") {
"idb_event_dispatcher.h",
"idb_factory.cc",
"idb_factory.h",
- "idb_histograms.h",
"idb_index.cc",
"idb_index.h",
"idb_key.cc",
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/OWNERS b/chromium/third_party/blink/renderer/modules/indexeddb/OWNERS
index acc03749c6c..a740487227f 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/OWNERS
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/OWNERS
@@ -1,6 +1,4 @@
file://content/browser/indexed_db/OWNERS
-pwnall@chromium.org
-
# TEAM: storage-dev@chromium.org
# COMPONENT: Blink>Storage>IndexedDB
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 32306872aa6..0a815c75f30 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_cursor.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_cursor.cc
@@ -314,8 +314,9 @@ void IDBCursor::Continue(std::unique_ptr<IDBKey> key,
request_->SetPendingCursor(this);
request_->AssignNewMetrics(std::move(metrics));
got_value_ = false;
- backend_->Continue(WebIDBKeyView(key.get()), WebIDBKeyView(primary_key.get()),
- request_->CreateWebCallbacks().release());
+ backend_->CursorContinue(WebIDBKeyView(key.get()),
+ WebIDBKeyView(primary_key.get()),
+ request_->CreateWebCallbacks().release());
}
IDBRequest* IDBCursor::Delete(ScriptState* script_state,
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 1ef44a2f655..64cec7cd8dc 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_cursor.h
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_cursor.h
@@ -28,8 +28,8 @@
#include <memory>
#include "base/memory/scoped_refptr.h"
+#include "third_party/blink/public/common/indexeddb/web_idb_types.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_cursor.h"
-#include "third_party/blink/public/platform/modules/indexeddb/web_idb_types.h"
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/bindings/modules/v8/idb_object_store_or_idb_index.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_key.h"
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 d1cf066bd13..91223d4d4d5 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
@@ -27,8 +27,8 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_INDEXEDDB_IDB_CURSOR_WITH_VALUE_H_
#include <memory>
+#include "third_party/blink/public/common/indexeddb/web_idb_types.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_cursor.h"
-#include "third_party/blink/public/platform/modules/indexeddb/web_idb_types.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_cursor.h"
#include "third_party/blink/renderer/modules/indexeddb/indexed_db.h"
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 75ccc9d068c..6a1da96df88 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.cc
@@ -27,11 +27,11 @@
#include "base/atomic_sequence_num.h"
#include "base/optional.h"
+#include "third_party/blink/public/common/indexeddb/web_idb_types.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_database_callbacks.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_database_exception.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_key_path.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_observation.h"
-#include "third_party/blink/public/platform/modules/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_binding_for_modules.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_idb_observer_callback.h"
@@ -265,7 +265,6 @@ IDBObjectStore* IDBDatabase::createObjectStore(
bool auto_increment,
ExceptionState& exception_state) {
IDB_TRACE("IDBDatabase::createObjectStore");
- RecordApiCallsHistogram(kIDBCreateObjectStoreCall);
if (!version_change_transaction_) {
exception_state.ThrowDOMException(
@@ -331,7 +330,6 @@ IDBObjectStore* IDBDatabase::createObjectStore(
void IDBDatabase::deleteObjectStore(const String& name,
ExceptionState& exception_state) {
IDB_TRACE("IDBDatabase::deleteObjectStore");
- RecordApiCallsHistogram(kIDBDeleteObjectStoreCall);
if (!version_change_transaction_) {
exception_state.ThrowDOMException(
DOMExceptionCode::kInvalidStateError,
@@ -371,7 +369,6 @@ IDBTransaction* IDBDatabase::transaction(
const String& mode_string,
ExceptionState& exception_state) {
IDB_TRACE("IDBDatabase::transaction");
- RecordApiCallsHistogram(kIDBTransactionCall);
HashSet<String> scope;
if (store_names.IsString()) {
@@ -500,19 +497,19 @@ void IDBDatabase::OnVersionChange(int64_t old_version, int64_t new_version) {
void IDBDatabase::EnqueueEvent(Event* event) {
DCHECK(GetExecutionContext());
event->SetTarget(this);
- event_queue_->EnqueueEvent(FROM_HERE, event);
+ event_queue_->EnqueueEvent(FROM_HERE, *event);
}
-DispatchEventResult IDBDatabase::DispatchEventInternal(Event* event) {
+DispatchEventResult IDBDatabase::DispatchEventInternal(Event& event) {
IDB_TRACE("IDBDatabase::dispatchEvent");
if (!GetExecutionContext())
return DispatchEventResult::kCanceledBeforeDispatch;
- DCHECK(event->type() == EventTypeNames::versionchange ||
- event->type() == EventTypeNames::close);
+ DCHECK(event.type() == EventTypeNames::versionchange ||
+ event.type() == EventTypeNames::close);
DispatchEventResult dispatch_result =
EventTarget::DispatchEventInternal(event);
- if (event->type() == EventTypeNames::versionchange && !close_pending_ &&
+ if (event.type() == EventTypeNames::versionchange && !close_pending_ &&
backend_)
backend_->VersionChangeIgnored();
return dispatch_result;
@@ -598,13 +595,6 @@ ExecutionContext* IDBDatabase::GetExecutionContext() const {
return ContextLifecycleObserver::GetExecutionContext();
}
-void IDBDatabase::RecordApiCallsHistogram(IndexedDatabaseMethods method) {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- EnumerationHistogram, api_calls_histogram,
- ("WebCore.IndexedDB.FrontEndAPICalls", kIDBMethodsMax));
- api_calls_histogram.Count(method);
-}
-
STATIC_ASSERT_ENUM(kWebIDBDatabaseExceptionUnknownError,
DOMExceptionCode::kUnknownError);
STATIC_ASSERT_ENUM(kWebIDBDatabaseExceptionConstraintError,
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 183bfbd4ced..90c1175dff3 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.h
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.h
@@ -38,7 +38,6 @@
#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_histograms.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"
@@ -171,11 +170,9 @@ class MODULES_EXPORT IDBDatabase final
static const char kTransactionReadOnlyErrorMessage[];
static const char kDatabaseClosedErrorMessage[];
- static void RecordApiCallsHistogram(IndexedDatabaseMethods);
-
protected:
// EventTarget
- DispatchEventResult DispatchEventInternal(Event*) override;
+ DispatchEventResult DispatchEventInternal(Event&) override;
private:
IDBDatabase(ExecutionContext*,
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_event_dispatcher.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_event_dispatcher.cc
index 7d2b7e99983..67f5ea8fdb2 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_event_dispatcher.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_event_dispatcher.cc
@@ -34,37 +34,37 @@
namespace blink {
DispatchEventResult IDBEventDispatcher::Dispatch(
- Event* event,
+ Event& event,
HeapVector<Member<EventTarget>>& event_targets) {
size_t size = event_targets.size();
DCHECK(size);
- event->SetEventPhase(Event::kCapturingPhase);
+ event.SetEventPhase(Event::kCapturingPhase);
for (size_t i = size - 1; i; --i) { // Don't do the first element.
- event->SetCurrentTarget(event_targets[i].Get());
+ event.SetCurrentTarget(event_targets[i].Get());
event_targets[i]->FireEventListeners(event);
- if (event->PropagationStopped())
+ if (event.PropagationStopped())
goto doneDispatching;
}
- event->SetEventPhase(Event::kAtTarget);
- event->SetCurrentTarget(event_targets[0].Get());
+ event.SetEventPhase(Event::kAtTarget);
+ event.SetCurrentTarget(event_targets[0].Get());
event_targets[0]->FireEventListeners(event);
- if (event->PropagationStopped() || !event->bubbles() || event->cancelBubble())
+ if (event.PropagationStopped() || !event.bubbles() || event.cancelBubble())
goto doneDispatching;
- event->SetEventPhase(Event::kBubblingPhase);
+ event.SetEventPhase(Event::kBubblingPhase);
for (size_t i = 1; i < size; ++i) { // Don't do the first element.
- event->SetCurrentTarget(event_targets[i].Get());
+ event.SetCurrentTarget(event_targets[i].Get());
event_targets[i]->FireEventListeners(event);
- if (event->PropagationStopped() || event->cancelBubble())
+ if (event.PropagationStopped() || event.cancelBubble())
goto doneDispatching;
}
doneDispatching:
- event->SetCurrentTarget(nullptr);
- event->SetEventPhase(Event::kNone);
- return EventTarget::GetDispatchEventResult(*event);
+ event.SetCurrentTarget(nullptr);
+ event.SetEventPhase(Event::kNone);
+ return EventTarget::GetDispatchEventResult(event);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_event_dispatcher.h b/chromium/third_party/blink/renderer/modules/indexeddb/idb_event_dispatcher.h
index 62b32eca5da..d9f56850143 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_event_dispatcher.h
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_event_dispatcher.h
@@ -45,7 +45,7 @@ class IDBEventDispatcher {
public:
// The second argument contains the target first and then its ancestors in
// order of how the event bubbles.
- static DispatchEventResult Dispatch(Event*, HeapVector<Member<EventTarget>>&);
+ static DispatchEventResult Dispatch(Event&, HeapVector<Member<EventTarget>>&);
};
} // namespace blink
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 15d4f746059..4dd5232c63f 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_factory.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_factory.cc
@@ -64,6 +64,12 @@ static bool IsContextValid(ExecutionContext* context) {
return true;
}
+WebIDBFactory* IDBFactory::GetFactory() {
+ if (!web_idb_factory_)
+ web_idb_factory_ = Platform::Current()->CreateIdbFactory();
+ return web_idb_factory_.get();
+}
+
IDBRequest* IDBFactory::GetDatabaseNames(ScriptState* script_state,
ExceptionState& exception_state) {
IDB_TRACE("IDBFactory::getDatabaseNamesRequestSetup");
@@ -94,7 +100,7 @@ IDBRequest* IDBFactory::GetDatabaseNames(ScriptState* script_state,
return request;
}
- Platform::Current()->IdbFactory()->GetDatabaseNames(
+ GetFactory()->GetDatabaseNames(
request->CreateWebCallbacks().release(),
WebSecurityOrigin(
ExecutionContext::From(script_state)->GetSecurityOrigin()),
@@ -120,7 +126,6 @@ IDBOpenDBRequest* IDBFactory::OpenInternal(ScriptState* script_state,
ExceptionState& exception_state) {
IDB_TRACE1("IDBFactory::open", "name", name.Utf8());
IDBRequest::AsyncTraceState metrics("IDBFactory::open");
- IDBDatabase::RecordApiCallsHistogram(kIDBOpenCall);
DCHECK(version >= 1 || version == IDBDatabaseMetadata::kNoVersion);
if (!IsContextValid(ExecutionContext::From(script_state)))
return nullptr;
@@ -150,7 +155,7 @@ IDBOpenDBRequest* IDBFactory::OpenInternal(ScriptState* script_state,
return request;
}
- Platform::Current()->IdbFactory()->Open(
+ GetFactory()->Open(
name, version, transaction_id, request->CreateWebCallbacks().release(),
database_callbacks->CreateWebCallbacks().release(),
WebSecurityOrigin(
@@ -190,7 +195,6 @@ IDBOpenDBRequest* IDBFactory::DeleteDatabaseInternal(
bool force_close) {
IDB_TRACE1("IDBFactory::deleteDatabase", "name", name.Utf8());
IDBRequest::AsyncTraceState metrics("IDBFactory::deleteDatabase");
- IDBDatabase::RecordApiCallsHistogram(kIDBDeleteDatabaseCall);
if (!IsContextValid(ExecutionContext::From(script_state)))
return nullptr;
if (!ExecutionContext::From(script_state)
@@ -217,7 +221,7 @@ IDBOpenDBRequest* IDBFactory::DeleteDatabaseInternal(
return request;
}
- Platform::Current()->IdbFactory()->DeleteDatabase(
+ GetFactory()->DeleteDatabase(
name, request->CreateWebCallbacks().release(),
WebSecurityOrigin(
ExecutionContext::From(script_state)->GetSecurityOrigin()),
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_factory.h b/chromium/third_party/blink/renderer/modules/indexeddb/idb_factory.h
index a422f572843..bc541748cff 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_factory.h
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_factory.h
@@ -28,6 +28,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_INDEXEDDB_IDB_FACTORY_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_INDEXEDDB_IDB_FACTORY_H_
+#include "third_party/blink/public/platform/modules/indexeddb/web_idb_factory.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_open_db_request.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -67,6 +68,8 @@ class IDBFactory final : public ScriptWrappable {
private:
IDBFactory();
+ WebIDBFactory* GetFactory();
+
IDBOpenDBRequest* OpenInternal(ScriptState*,
const String& name,
int64_t version,
@@ -76,6 +79,8 @@ class IDBFactory final : public ScriptWrappable {
const String& name,
ExceptionState&,
bool);
+
+ std::unique_ptr<WebIDBFactory> web_idb_factory_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_factory.idl b/chromium/third_party/blink/renderer/modules/indexeddb/idb_factory.idl
index 497f1310d09..57cc48a7c61 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_factory.idl
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_factory.idl
@@ -28,8 +28,13 @@
[
Exposed=(Window,Worker)
] interface IDBFactory {
- [NewObject, CallWith=ScriptState, RaisesException] IDBOpenDBRequest open(DOMString name,
- optional [EnforceRange] unsigned long long version);
+ [
+ NewObject,
+ CallWith=ScriptState,
+ Measure,
+ RaisesException
+ ] IDBOpenDBRequest open(DOMString name,
+ optional [EnforceRange] unsigned long long version);
[NewObject, CallWith=ScriptState, RaisesException] IDBOpenDBRequest deleteDatabase(DOMString name);
[CallWith=ScriptState, RaisesException] short cmp(any first, any second);
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_histograms.h b/chromium/third_party/blink/renderer/modules/indexeddb/idb_histograms.h
deleted file mode 100644
index d4ee5318f65..00000000000
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_histograms.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.
- * 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 GOOGLE 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_MODULES_INDEXEDDB_IDB_HISTOGRAMS_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_INDEXEDDB_IDB_HISTOGRAMS_H_
-
-namespace blink {
-
-enum IndexedDatabaseMethods {
- kIDBCreateObjectStoreCall,
- kIDBDeleteObjectStoreCall,
- kIDBTransactionCall,
- kIDBDeleteDatabaseCall,
- kIDBOpenCall,
- kIDBMethodsMax,
-};
-
-} // namespace blink
-
-#endif
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 00bc1ac278b..99a48241580 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_index.h
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_index.h
@@ -26,9 +26,9 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_INDEXEDDB_IDB_INDEX_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_INDEXEDDB_IDB_INDEX_H_
+#include "third_party/blink/public/common/indexeddb/web_idb_types.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_cursor.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_database.h"
-#include "third_party/blink/public/platform/modules/indexeddb/web_idb_types.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_cursor.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_key_path.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_key_range.h"
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_key.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_key.cc
index e2a6651e9fe..114db34fb2a 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_key.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_key.cc
@@ -28,8 +28,8 @@
#include <algorithm>
#include <memory>
+#include "third_party/blink/public/common/indexeddb/web_idb_types.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_key.h"
-#include "third_party/blink/public/platform/modules/indexeddb/web_idb_types.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_key_path.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_key_path.cc
index 35d82482ee5..3e1c12b4acf 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_key_path.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_key_path.cc
@@ -25,7 +25,7 @@
#include "third_party/blink/renderer/modules/indexeddb/idb_key_path.h"
-#include "third_party/blink/public/platform/modules/indexeddb/web_idb_types.h"
+#include "third_party/blink/public/common/indexeddb/web_idb_types.h"
#include "third_party/blink/renderer/platform/wtf/ascii_ctype.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/dtoa.h"
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 8284b43f1c1..4174356a2c4 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
@@ -27,9 +27,9 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_INDEXEDDB_IDB_OBJECT_STORE_H_
#include "base/memory/scoped_refptr.h"
+#include "third_party/blink/public/common/indexeddb/web_idb_types.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_cursor.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_database.h"
-#include "third_party/blink/public/platform/modules/indexeddb/web_idb_types.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_cursor.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_index.h"
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 7ad94c52ed4..f9a97d65457 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_observation.h
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_observation.h
@@ -7,7 +7,7 @@
#include <memory>
-#include "third_party/blink/public/platform/modules/indexeddb/web_idb_types.h"
+#include "third_party/blink/public/common/indexeddb/web_idb_types.h"
#include "third_party/blink/renderer/bindings/core/v8/script_value.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/indexeddb/idb_observer.h b/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer.h
index 78ac326ef80..b51ec3c3a03 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer.h
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer.h
@@ -5,7 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_INDEXEDDB_IDB_OBSERVER_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_INDEXEDDB_IDB_OBSERVER_H_
-#include "third_party/blink/public/platform/modules/indexeddb/web_idb_types.h"
+#include "third_party/blink/public/common/indexeddb/web_idb_types.h"
#include "third_party/blink/renderer/modules/modules_export.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/indexeddb/idb_open_db_request.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_open_db_request.cc
index 38205ce3f8b..25779b6f514 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
@@ -186,10 +186,10 @@ bool IDBOpenDBRequest::ShouldEnqueueEvent() const {
return true;
}
-DispatchEventResult IDBOpenDBRequest::DispatchEventInternal(Event* event) {
+DispatchEventResult IDBOpenDBRequest::DispatchEventInternal(Event& event) {
// If the connection closed between onUpgradeNeeded and the delivery of the
// "success" event, an "error" event should be fired instead.
- if (event->type() == EventTypeNames::success &&
+ if (event.type() == EventTypeNames::success &&
ResultAsAny()->GetType() == IDBAny::kIDBDatabaseType &&
ResultAsAny()->IdbDatabase()->IsClosePending()) {
SetResult(nullptr);
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 6f9efa55e19..36d9ecb4be5 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
@@ -71,7 +71,7 @@ class MODULES_EXPORT IDBOpenDBRequest final : public IDBRequest {
bool ShouldEnqueueEvent() const override;
// EventTarget
- DispatchEventResult DispatchEventInternal(Event*) override;
+ DispatchEventResult DispatchEventInternal(Event&) override;
private:
IDBOpenDBRequest(ScriptState*,
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 49cdcc08c0f..9729f0d46e3 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_request.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_request.cc
@@ -53,6 +53,7 @@
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/histogram.h"
#include "third_party/blink/renderer/platform/shared_buffer.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
using blink::WebIDBCursor;
@@ -631,15 +632,15 @@ ExecutionContext* IDBRequest::GetExecutionContext() const {
return PausableObject::GetExecutionContext();
}
-DispatchEventResult IDBRequest::DispatchEventInternal(Event* event) {
+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);
+ DCHECK_EQ(event.target(), this);
- if (event->type() != EventTypeNames::blocked)
+ if (event.type() != EventTypeNames::blocked)
ready_state_ = DONE;
HeapVector<Member<EventTarget>> targets;
@@ -656,7 +657,7 @@ DispatchEventResult IDBRequest::DispatchEventInternal(Event* event) {
// Cursor properties should not be updated until the success event is being
// dispatched.
IDBCursor* cursor_to_notify = nullptr;
- if (event->type() == EventTypeNames::success) {
+ if (event.type() == EventTypeNames::success) {
cursor_to_notify = GetResultCursor();
if (cursor_to_notify) {
cursor_to_notify->SetValueReady(std::move(cursor_key_),
@@ -665,23 +666,23 @@ DispatchEventResult IDBRequest::DispatchEventInternal(Event* event) {
}
}
- if (event->type() == EventTypeNames::upgradeneeded) {
+ if (event.type() == EventTypeNames::upgradeneeded) {
DCHECK(!did_fire_upgrade_needed_event_);
did_fire_upgrade_needed_event_ = true;
}
// FIXME: When we allow custom event dispatching, this will probably need to
// change.
- DCHECK(event->type() == EventTypeNames::success ||
- event->type() == EventTypeNames::error ||
- event->type() == EventTypeNames::blocked ||
- event->type() == EventTypeNames::upgradeneeded)
- << "event type was " << event->type();
+ DCHECK(event.type() == EventTypeNames::success ||
+ event.type() == EventTypeNames::error ||
+ event.type() == EventTypeNames::blocked ||
+ event.type() == EventTypeNames::upgradeneeded)
+ << "event type was " << event.type();
const bool set_transaction_active =
transaction_ &&
- (event->type() == EventTypeNames::success ||
- event->type() == EventTypeNames::upgradeneeded ||
- (event->type() == EventTypeNames::error && !request_aborted_));
+ (event.type() == EventTypeNames::success ||
+ event.type() == EventTypeNames::upgradeneeded ||
+ (event.type() == EventTypeNames::error && !request_aborted_));
if (set_transaction_active)
transaction_->SetActive(true);
@@ -693,7 +694,7 @@ DispatchEventResult IDBRequest::DispatchEventInternal(Event* event) {
if (transaction_ && ready_state_ == DONE)
transaction_->UnregisterRequest(this);
- did_throw_in_event_handler_ = false;
+ event.SetTarget(this);
DispatchEventResult dispatch_result =
IDBEventDispatcher::Dispatch(event, targets);
@@ -702,12 +703,14 @@ DispatchEventResult IDBRequest::DispatchEventInternal(Event* event) {
// this request doesn't receive a second error) and before deactivating
// (which might trigger commit).
if (!request_aborted_) {
- if (did_throw_in_event_handler_) {
+ // Transactions should be aborted after event dispatch if an exception was
+ // not caught.
+ if (event.LegacyDidListenersThrow()) {
transaction_->SetError(
DOMException::Create(DOMExceptionCode::kAbortError,
"Uncaught exception in event handler."));
transaction_->abort(IGNORE_EXCEPTION_FOR_TESTING);
- } else if (event->type() == EventTypeNames::error &&
+ } else if (event.type() == EventTypeNames::error &&
dispatch_result == DispatchEventResult::kNotCanceled) {
transaction_->SetError(error_);
transaction_->abort(IGNORE_EXCEPTION_FOR_TESTING);
@@ -725,16 +728,12 @@ DispatchEventResult IDBRequest::DispatchEventInternal(Event* event) {
// An upgradeneeded event will always be followed by a success or error event,
// so must be kept alive.
- if (ready_state_ == DONE && event->type() != EventTypeNames::upgradeneeded)
+ if (ready_state_ == DONE && event.type() != EventTypeNames::upgradeneeded)
has_pending_activity_ = false;
return dispatch_result;
}
-void IDBRequest::UncaughtExceptionInEventHandler() {
- did_throw_in_event_handler_ = true;
-}
-
void IDBRequest::TransactionDidFinishAndDispatch() {
DCHECK(transaction_);
DCHECK(transaction_->IsVersionChange());
@@ -761,7 +760,7 @@ void IDBRequest::EnqueueEvent(Event* event) {
event->SetTarget(this);
- event_queue_->EnqueueEvent(FROM_HERE, event);
+ event_queue_->EnqueueEvent(FROM_HERE, *event);
}
} // namespace blink
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 51017b09d7a..5e1980d87e4 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_request.h
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_request.h
@@ -33,8 +33,8 @@
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
+#include "third_party/blink/public/common/indexeddb/web_idb_types.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_cursor.h"
-#include "third_party/blink/public/platform/modules/indexeddb/web_idb_types.h"
#include "third_party/blink/public/platform/web_blob_info.h"
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
@@ -294,7 +294,6 @@ class MODULES_EXPORT IDBRequest : public EventTargetWithInlineData,
// EventTarget
const AtomicString& InterfaceName() const override;
ExecutionContext* GetExecutionContext() const final;
- void UncaughtExceptionInEventHandler() final;
// Called by a version change transaction that has finished to set this
// request back from DONE (following "upgradeneeded") back to PENDING (for
@@ -344,7 +343,7 @@ class MODULES_EXPORT IDBRequest : public EventTargetWithInlineData,
virtual void EnqueueResponse(int64_t);
// EventTarget
- DispatchEventResult DispatchEventInternal(Event*) override;
+ DispatchEventResult DispatchEventInternal(Event&) override;
// Can be nullptr for requests that are not associated with a transaction,
// i.e. delete requests and completed or unsuccessful open requests.
@@ -408,12 +407,6 @@ class MODULES_EXPORT IDBRequest : public EventTargetWithInlineData,
bool prevent_propagation_ = false;
bool result_dirty_ = true;
- // Transactions should be aborted after event dispatch if an exception was
- // not caught. This is cleared before dispatch, set by a call to
- // UncaughtExceptionInEventHandler() during dispatch, and checked afterwards
- // to abort if necessary.
- bool did_throw_in_event_handler_ = false;
-
// Pointer back to the WebIDBCallbacks that holds a persistent reference to
// this object.
WebIDBCallbacks* web_callbacks_ = nullptr;
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 68b3d5d58b7..588891f366f 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction.cc
@@ -39,6 +39,7 @@
#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/wtf/functional.h"
#include <memory>
@@ -517,7 +518,7 @@ const char* IDBTransaction::InactiveErrorMessage() const {
return nullptr;
}
-DispatchEventResult IDBTransaction::DispatchEventInternal(Event* event) {
+DispatchEventResult IDBTransaction::DispatchEventInternal(Event& event) {
IDB_TRACE1("IDBTransaction::dispatchEvent", "txn.id", id_);
if (!GetExecutionContext()) {
state_ = kFinished;
@@ -526,7 +527,7 @@ DispatchEventResult IDBTransaction::DispatchEventInternal(Event* event) {
DCHECK_NE(state_, kFinished);
DCHECK(has_pending_activity_);
DCHECK(GetExecutionContext());
- DCHECK_EQ(event->target(), this);
+ DCHECK_EQ(event.target(), this);
state_ = kFinished;
HeapVector<Member<EventTarget>> targets;
@@ -535,8 +536,8 @@ DispatchEventResult IDBTransaction::DispatchEventInternal(Event* event) {
// FIXME: When we allow custom event dispatching, this will probably need to
// change.
- DCHECK(event->type() == EventTypeNames::complete ||
- event->type() == EventTypeNames::abort);
+ DCHECK(event.type() == EventTypeNames::complete ||
+ event.type() == EventTypeNames::abort);
DispatchEventResult dispatch_result =
IDBEventDispatcher::Dispatch(event, targets);
// FIXME: Try to construct a test where |this| outlives openDBRequest and we
@@ -557,7 +558,7 @@ void IDBTransaction::EnqueueEvent(Event* event) {
return;
event->SetTarget(this);
- event_queue_->EnqueueEvent(FROM_HERE, event);
+ event_queue_->EnqueueEvent(FROM_HERE, *event);
}
void IDBTransaction::AbortOutstandingRequests() {
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 5a2970a568d..bfb15df7825 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction.h
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction.h
@@ -28,8 +28,8 @@
#include <memory>
+#include "third_party/blink/public/common/indexeddb/web_idb_types.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_database.h"
-#include "third_party/blink/public/platform/modules/indexeddb/web_idb_types.h"
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/dom/dom_string_list.h"
@@ -161,7 +161,7 @@ class MODULES_EXPORT IDBTransaction final
protected:
// EventTarget
- DispatchEventResult DispatchEventInternal(Event*) override;
+ DispatchEventResult DispatchEventInternal(Event&) override;
private:
using IDBObjectStoreMap = HeapHashMap<String, Member<IDBObjectStore>>;
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 126c8529d9c..cf13a66dd43 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_value.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_value.cc
@@ -86,7 +86,7 @@ void IDBValue::SetData(scoped_refptr<SharedBuffer> new_data) {
DCHECK(new_data) << "Value unwrapping must result in a non-empty buffer";
int64_t old_external_allocated_size = external_allocated_size_;
- external_allocated_size_ = data_->size();
+ external_allocated_size_ = new_data->size();
isolate_->AdjustAmountOfExternalAllocatedMemory(external_allocated_size_ -
old_external_allocated_size);
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 55d4faf286d..f3a15b9c5e6 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
@@ -27,7 +27,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_INDEXEDDB_IDB_VERSION_CHANGE_EVENT_H_
#include "base/optional.h"
-#include "third_party/blink/public/platform/modules/indexeddb/web_idb_types.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/modules/event_modules.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_any.h"
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 c3f3e7a21a5..d0776114b01 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
@@ -33,8 +33,8 @@
#include <memory>
#include <utility>
+#include "third_party/blink/public/common/indexeddb/web_idb_types.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_cursor.h"
-#include "third_party/blink/public/platform/modules/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/core/dom/document.h"
@@ -90,11 +90,6 @@ typedef blink::protocol::IndexedDB::Backend::DeleteDatabaseCallback
DeleteDatabaseCallback;
namespace blink {
-
-namespace IndexedDBAgentState {
-static const char kIndexedDBAgentEnabled[] = "indexedDBAgentEnabled";
-};
-
namespace {
const char kIndexedDBObjectGroup[] = "indexeddb";
@@ -754,15 +749,15 @@ class DataLoader final : public ExecutableWithDatabase<RequestDataCallback> {
InspectorIndexedDBAgent::InspectorIndexedDBAgent(
InspectedFrames* inspected_frames,
v8_inspector::V8InspectorSession* v8_session)
- : inspected_frames_(inspected_frames), v8_session_(v8_session) {}
+ : inspected_frames_(inspected_frames),
+ v8_session_(v8_session),
+ enabled_(&agent_state_, /*default_value=*/false) {}
InspectorIndexedDBAgent::~InspectorIndexedDBAgent() = default;
void InspectorIndexedDBAgent::Restore() {
- if (state_->booleanProperty(IndexedDBAgentState::kIndexedDBAgentEnabled,
- false)) {
+ if (enabled_.Get())
enable();
- }
}
void InspectorIndexedDBAgent::DidCommitLoadForLocalFrame(LocalFrame* frame) {
@@ -773,12 +768,12 @@ void InspectorIndexedDBAgent::DidCommitLoadForLocalFrame(LocalFrame* frame) {
}
Response InspectorIndexedDBAgent::enable() {
- state_->setBoolean(IndexedDBAgentState::kIndexedDBAgentEnabled, true);
+ enabled_.Set(true);
return Response::OK();
}
Response InspectorIndexedDBAgent::disable() {
- state_->setBoolean(IndexedDBAgentState::kIndexedDBAgentEnabled, false);
+ enabled_.Clear();
v8_session_->releaseObjectGroup(
ToV8InspectorStringView(kIndexedDBObjectGroup));
return Response::OK();
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 9b4cd6db42e..5c101559fb0 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
@@ -86,6 +86,7 @@ class MODULES_EXPORT InspectorIndexedDBAgent final
private:
Member<InspectedFrames> inspected_frames_;
v8_inspector::V8InspectorSession* v8_session_;
+ InspectorAgentState::Boolean enabled_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/window_indexed_database.idl b/chromium/third_party/blink/renderer/modules/indexeddb/window_indexed_database.idl
index 183376fbd21..63647b5a9c2 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/window_indexed_database.idl
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/window_indexed_database.idl
@@ -27,5 +27,5 @@
[
ImplementedAs=GlobalIndexedDB
] partial interface Window {
- [MeasureAs=UnprefixedIndexedDB] readonly attribute IDBFactory indexedDB;
+ readonly attribute IDBFactory indexedDB;
};
diff --git a/chromium/third_party/blink/renderer/modules/installation/installation_service_impl.cc b/chromium/third_party/blink/renderer/modules/installation/installation_service_impl.cc
index 72a6b0866b8..b41e4328d61 100644
--- a/chromium/third_party/blink/renderer/modules/installation/installation_service_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/installation/installation_service_impl.cc
@@ -33,7 +33,7 @@ void InstallationServiceImpl::OnInstall() {
if (!dom_window)
return;
- dom_window->DispatchEvent(Event::Create(EventTypeNames::appinstalled));
+ dom_window->DispatchEvent(*Event::Create(EventTypeNames::appinstalled));
}
} // namespace blink
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 c4d58193ebf..ab964f11fae 100644
--- a/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout.cc
+++ b/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout.cc
@@ -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/core/frame/local_frame.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/modules/locks/lock.idl b/chromium/third_party/blink/renderer/modules/locks/lock.idl
index df2dd986550..24d444a7bb9 100644
--- a/chromium/third_party/blink/renderer/modules/locks/lock.idl
+++ b/chromium/third_party/blink/renderer/modules/locks/lock.idl
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// https://github.com/inexorabletash/web-locks
+// https://wicg.github.io/web-locks/#lock
[
SecureContext,
Exposed=(Window,Worker),
diff --git a/chromium/third_party/blink/renderer/modules/locks/lock_info.idl b/chromium/third_party/blink/renderer/modules/locks/lock_info.idl
index 93eae86f36a..f788995aa55 100644
--- a/chromium/third_party/blink/renderer/modules/locks/lock_info.idl
+++ b/chromium/third_party/blink/renderer/modules/locks/lock_info.idl
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// https://github.com/inexorabletash/web-locks
+// https://wicg.github.io/web-locks/#dictdef-lockinfo
dictionary LockInfo {
DOMString name;
LockMode mode;
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 5655ca1640b..7c2ec8810d2 100644
--- a/chromium/third_party/blink/renderer/modules/locks/lock_manager.cc
+++ b/chromium/third_party/blink/renderer/modules/locks/lock_manager.cc
@@ -102,6 +102,10 @@ class LockManager::LockRequestImpl final
}
void Failed() override {
+ // Ensure a local reference to the callback's wrapper is retained, as it
+ // can no longer be traced once removed from |manager_|'s list.
+ auto* callback = ToV8PersistentCallbackFunction(callback_.Release());
+
manager_->RemovePendingRequest(this);
binding_.Close();
@@ -113,7 +117,7 @@ class LockManager::LockRequestImpl final
// the lock was not available.
ScriptState::Scope scope(script_state);
v8::TryCatch try_catch(script_state->GetIsolate());
- v8::Maybe<ScriptValue> result = callback_->Invoke(nullptr, nullptr);
+ v8::Maybe<ScriptValue> result = callback->Invoke(nullptr, nullptr);
if (try_catch.HasCaught()) {
resolver_->Reject(try_catch.Exception());
} else if (!result.IsNothing()) {
@@ -125,6 +129,10 @@ class LockManager::LockRequestImpl final
DCHECK(binding_.is_bound());
DCHECK(handle.is_bound());
+ // Ensure a local reference to the callback's wrapper is retained, as it
+ // can no longer be traced once removed from |manager_|'s list.
+ auto* callback = ToV8PersistentCallbackFunction(callback_.Release());
+
manager_->RemovePendingRequest(this);
binding_.Close();
@@ -140,7 +148,7 @@ class LockManager::LockRequestImpl final
ScriptState::Scope scope(script_state);
v8::TryCatch try_catch(script_state->GetIsolate());
- v8::Maybe<ScriptValue> result = callback_->Invoke(nullptr, lock);
+ v8::Maybe<ScriptValue> result = callback->Invoke(nullptr, lock);
if (try_catch.HasCaught()) {
lock->HoldUntil(
ScriptPromise::Reject(script_state, try_catch.Exception()),
diff --git a/chromium/third_party/blink/renderer/modules/locks/lock_manager.idl b/chromium/third_party/blink/renderer/modules/locks/lock_manager.idl
index e2185dfd616..cfc6025d34a 100644
--- a/chromium/third_party/blink/renderer/modules/locks/lock_manager.idl
+++ b/chromium/third_party/blink/renderer/modules/locks/lock_manager.idl
@@ -2,9 +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/inexorabletash/web-locks
-
+// https://wicg.github.io/web-locks/#callbackdef-lockgrantedcallback
callback LockGrantedCallback = any (Lock lock);
+
+// https://wicg.github.io/web-locks/#lockmanager
[
SecureContext,
Exposed=(Window,Worker),
diff --git a/chromium/third_party/blink/renderer/modules/locks/lock_manager_snapshot.idl b/chromium/third_party/blink/renderer/modules/locks/lock_manager_snapshot.idl
index 279b5edcd14..a53b8e5166a 100644
--- a/chromium/third_party/blink/renderer/modules/locks/lock_manager_snapshot.idl
+++ b/chromium/third_party/blink/renderer/modules/locks/lock_manager_snapshot.idl
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// https://github.com/inexorabletash/web-locks
+// https://wicg.github.io/web-locks/#dictdef-lockmanagersnapshot
dictionary LockManagerSnapshot {
sequence<LockInfo> held;
sequence<LockInfo> pending;
diff --git a/chromium/third_party/blink/renderer/modules/locks/lock_options.idl b/chromium/third_party/blink/renderer/modules/locks/lock_options.idl
index cbe48a9984c..6afdfd8744f 100644
--- a/chromium/third_party/blink/renderer/modules/locks/lock_options.idl
+++ b/chromium/third_party/blink/renderer/modules/locks/lock_options.idl
@@ -2,9 +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/inexorabletash/web-locks
+// https://wicg.github.io/web-locks/#enumdef-lockmode
enum LockMode { "shared", "exclusive" };
+// https://wicg.github.io/web-locks/#dictdef-lockoptions
dictionary LockOptions {
LockMode mode = "exclusive";
boolean ifAvailable = false;
diff --git a/chromium/third_party/blink/renderer/modules/locks/navigator_locks.idl b/chromium/third_party/blink/renderer/modules/locks/navigator_locks.idl
index 3ee3ff4a71b..7b9ef29b067 100644
--- a/chromium/third_party/blink/renderer/modules/locks/navigator_locks.idl
+++ b/chromium/third_party/blink/renderer/modules/locks/navigator_locks.idl
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// https://github.com/inexorabletash/web-locks
+// https://wicg.github.io/web-locks/#navigatorlocks
[
SecureContext,
Exposed=Window,
diff --git a/chromium/third_party/blink/renderer/modules/locks/worker_navigator_locks.idl b/chromium/third_party/blink/renderer/modules/locks/worker_navigator_locks.idl
index 3dc5d025f1d..c8d07dc6945 100644
--- a/chromium/third_party/blink/renderer/modules/locks/worker_navigator_locks.idl
+++ b/chromium/third_party/blink/renderer/modules/locks/worker_navigator_locks.idl
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// https://github.com/inexorabletash/web-locks
+// https://wicg.github.io/web-locks/#navigatorlocks
[
SecureContext,
Exposed=Worker,
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 6068f41d522..fa484250d3c 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
@@ -9,6 +9,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/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"
@@ -105,3 +106,31 @@ blink::mojom::blink::ManifestImageResourcePtr TypeConverter<
}
} // namespace mojo
+
+namespace blink {
+
+Manifest::ImageResource ConvertManifestImageResource(
+ const ManifestImageResource& icon) {
+ Manifest::ImageResource manifest_icon;
+ manifest_icon.src = blink::KURL(icon.src());
+ manifest_icon.type = WebString(mojo::ParseType(icon.type())).Utf16();
+
+ // Parse 'purpose'
+ const auto purposes = mojo::ParsePurpose(icon.purpose());
+ // ParsePurpose() would've weeded out any purposes that're not ANY or BADGE.
+ for (auto purpose : purposes) {
+ manifest_icon.purpose.emplace_back(
+ purpose == mojo::Purpose::ANY
+ ? Manifest::ImageResource::Purpose::ANY
+ : Manifest::ImageResource::Purpose::BADGE);
+ }
+ // Parse 'sizes'.
+ WTF::Vector<WebSize> sizes = mojo::ParseSizes(icon.sizes());
+ for (const auto& size : sizes) {
+ manifest_icon.sizes.emplace_back(gfx::Size(size.height, size.width));
+ }
+
+ return manifest_icon;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/manifest/image_resource_type_converters.h b/chromium/third_party/blink/renderer/modules/manifest/image_resource_type_converters.h
index 4f0f1a45cc7..ad5589be61b 100644
--- a/chromium/third_party/blink/renderer/modules/manifest/image_resource_type_converters.h
+++ b/chromium/third_party/blink/renderer/modules/manifest/image_resource_type_converters.h
@@ -5,10 +5,18 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MANIFEST_IMAGE_RESOURCE_TYPE_CONVERTERS_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_MANIFEST_IMAGE_RESOURCE_TYPE_CONVERTERS_H_
+#include "third_party/blink/public/common/manifest/manifest.h"
#include "third_party/blink/public/mojom/manifest/manifest.mojom-blink.h"
-#include "third_party/blink/renderer/modules/manifest/image_resource.h"
#include "third_party/blink/renderer/modules/modules_export.h"
+namespace blink {
+
+class ManifestImageResource;
+MODULES_EXPORT Manifest::ImageResource ConvertManifestImageResource(
+ const ManifestImageResource& image_resource);
+
+} // namespace blink
+
namespace mojo {
template <>
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 4f86f8a710f..a1bf8f1046e 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
@@ -7,6 +7,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#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/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -184,6 +185,22 @@ TEST(ImageResourceConverter, ExampleValueTest) {
EXPECT_EQ(expected_resource, ManifestImageResource::From(resource));
}
+TEST(ImageResourceConverter, BlinkToMojoTypeTest) {
+ blink::ManifestImageResource icon;
+ icon.setSrc("http://example.com/lolcat.jpg");
+ icon.setPurpose("BADGE");
+ icon.setSizes("32x32 64x64 128x128");
+ icon.setType("image/jpeg");
+
+ blink::Manifest::ImageResource mojo_icon =
+ blink::ConvertManifestImageResource(icon);
+ EXPECT_EQ(mojo_icon.src.spec(), "http://example.com/lolcat.jpg");
+ EXPECT_EQ(mojo_icon.type, blink::WebString("image/jpeg").Utf16());
+ EXPECT_EQ(mojo_icon.sizes[1], gfx::Size(64, 64));
+ EXPECT_EQ(mojo_icon.purpose[0],
+ blink::Manifest::ImageResource::Purpose::BADGE);
+}
+
} // namespace
} // namespace mojo
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/BUILD.gn b/chromium/third_party/blink/renderer/modules/media_controls/BUILD.gn
index ec9163260ae..f15b852a55a 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/media_controls/BUILD.gn
@@ -15,6 +15,8 @@ blink_modules_sources("media_controls") {
"elements/media_control_cast_button_element.h",
"elements/media_control_current_time_display_element.cc",
"elements/media_control_current_time_display_element.h",
+ "elements/media_control_display_cutout_fullscreen_button_element.cc",
+ "elements/media_control_display_cutout_fullscreen_button_element.h",
"elements/media_control_div_element.cc",
"elements/media_control_div_element.h",
"elements/media_control_download_button_element.cc",
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_button_panel_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_button_panel_element.cc
index 7c21b9a4003..c58efc14de9 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_button_panel_element.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_button_panel_element.cc
@@ -15,7 +15,7 @@ MediaControlButtonPanelElement::MediaControlButtonPanelElement(
SetShadowPseudoId(AtomicString("-internal-media-controls-button-panel"));
}
-bool MediaControlButtonPanelElement::KeepEventInNode(Event* event) {
+bool MediaControlButtonPanelElement::KeepEventInNode(const Event& event) const {
return MediaControlElementsHelper::IsUserInteractionEvent(event);
}
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_button_panel_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_button_panel_element.h
index d8bb310ffbe..5807f54568b 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_button_panel_element.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_button_panel_element.h
@@ -20,7 +20,7 @@ class MediaControlButtonPanelElement final : public MediaControlDivElement {
explicit MediaControlButtonPanelElement(MediaControlsImpl&);
private:
- bool KeepEventInNode(Event*) override;
+ bool KeepEventInNode(const Event&) const override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_cast_button_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_cast_button_element.cc
index 6fd6c4713b6..ea489594c5b 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_cast_button_element.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_cast_button_element.cc
@@ -92,8 +92,8 @@ const char* MediaControlCastButtonElement::GetNameForHistograms() const {
: IsOverflowElement() ? "CastOverflowButton" : "CastButton";
}
-void MediaControlCastButtonElement::DefaultEventHandler(Event* event) {
- if (event->type() == EventTypeNames::click) {
+void MediaControlCastButtonElement::DefaultEventHandler(Event& event) {
+ if (event.type() == EventTypeNames::click) {
if (is_overlay_button_) {
Platform::Current()->RecordAction(
UserMetricsAction("Media.Controls.CastOverlay"));
@@ -114,7 +114,7 @@ void MediaControlCastButtonElement::DefaultEventHandler(Event* event) {
MediaControlInputElement::DefaultEventHandler(event);
}
-bool MediaControlCastButtonElement::KeepEventInNode(Event* event) {
+bool MediaControlCastButtonElement::KeepEventInNode(const Event& event) const {
return MediaControlElementsHelper::IsUserInteractionEvent(event);
}
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_cast_button_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_cast_button_element.h
index 4e9375ef0b3..0b0a774a010 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_cast_button_element.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_cast_button_element.h
@@ -33,8 +33,8 @@ class MediaControlCastButtonElement final : public MediaControlInputElement {
const char* GetNameForHistograms() const final;
private:
- void DefaultEventHandler(Event*) final;
- bool KeepEventInNode(Event*) final;
+ void DefaultEventHandler(Event&) final;
+ bool KeepEventInNode(const Event&) const final;
bool IsPlayingRemotely() const;
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_display_cutout_fullscreen_button_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_display_cutout_fullscreen_button_element.cc
new file mode 100644
index 00000000000..f284d1737c0
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_display_cutout_fullscreen_button_element.cc
@@ -0,0 +1,50 @@
+// 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/media_controls/elements/media_control_display_cutout_fullscreen_button_element.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/viewport_data.h"
+#include "third_party/blink/renderer/core/html/media/html_media_element.h"
+#include "third_party/blink/renderer/core/input_type_names.h"
+#include "third_party/blink/renderer/modules/media_controls/media_controls_impl.h"
+
+namespace blink {
+
+MediaControlDisplayCutoutFullscreenButtonElement::
+ MediaControlDisplayCutoutFullscreenButtonElement(
+ MediaControlsImpl& media_controls)
+ : MediaControlInputElement(media_controls,
+ kMediaDisplayCutoutFullscreenButton) {
+ setType(InputTypeNames::button);
+ SetShadowPseudoId(AtomicString(
+ "-internal-media-controls-display-cutout-fullscreen-button"));
+ SetIsWanted(false);
+}
+
+bool MediaControlDisplayCutoutFullscreenButtonElement::
+ WillRespondToMouseClickEvents() {
+ return true;
+}
+
+void MediaControlDisplayCutoutFullscreenButtonElement::DefaultEventHandler(
+ Event& event) {
+ if (event.type() == EventTypeNames::click) {
+ // The button shouldn't be visible if not in fullscreen.
+ DCHECK(MediaElement().IsFullscreen());
+
+ GetDocument().GetViewportData().SetExpandIntoDisplayCutout(
+ !GetDocument().GetViewportData().GetExpandIntoDisplayCutout());
+ event.SetDefaultHandled();
+ }
+ HTMLInputElement::DefaultEventHandler(event);
+}
+
+const char*
+MediaControlDisplayCutoutFullscreenButtonElement::GetNameForHistograms() const {
+ return "DisplayCutoutFullscreenButton";
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_display_cutout_fullscreen_button_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_display_cutout_fullscreen_button_element.h
new file mode 100644
index 00000000000..629626252c4
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_display_cutout_fullscreen_button_element.h
@@ -0,0 +1,33 @@
+// 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_MEDIA_CONTROLS_ELEMENTS_MEDIA_CONTROL_DISPLAY_CUTOUT_FULLSCREEN_BUTTON_ELEMENT_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_ELEMENTS_MEDIA_CONTROL_DISPLAY_CUTOUT_FULLSCREEN_BUTTON_ELEMENT_H_
+
+#include "third_party/blink/renderer/modules/media_controls/elements/media_control_input_element.h"
+
+namespace blink {
+
+class Event;
+class MediaControlsImpl;
+
+class MediaControlDisplayCutoutFullscreenButtonElement final
+ : public MediaControlInputElement {
+ public:
+ MODULES_EXPORT explicit MediaControlDisplayCutoutFullscreenButtonElement(
+ MediaControlsImpl&);
+
+ // MediaControlInputElement overrides.
+ bool WillRespondToMouseClickEvents() override;
+
+ protected:
+ const char* GetNameForHistograms() const override;
+
+ private:
+ void DefaultEventHandler(Event&) override;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_ELEMENTS_MEDIA_CONTROL_DISPLAY_CUTOUT_FULLSCREEN_BUTTON_ELEMENT_H_
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
new file mode 100644
index 00000000000..cf3cd3b40ae
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_display_cutout_fullscreen_button_element_test.cc
@@ -0,0 +1,120 @@
+// 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/media_controls/elements/media_control_display_cutout_fullscreen_button_element.h"
+
+#include "third_party/blink/public/mojom/page/display_cutout.mojom-blink.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"
+#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/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/runtime_enabled_features.h"
+#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
+
+namespace blink {
+
+namespace {
+
+class MockDisplayCutoutChromeClient : public EmptyChromeClient {
+ public:
+ // ChromeClient overrides:
+ void EnterFullscreen(LocalFrame& frame, const FullscreenOptions&) override {
+ Fullscreen::DidEnterFullscreen(*frame.GetDocument());
+ }
+ void ExitFullscreen(LocalFrame& frame) override {
+ Fullscreen::DidExitFullscreen(*frame.GetDocument());
+ }
+};
+
+} // namespace
+
+class MediaControlDisplayCutoutFullscreenButtonElementTest
+ : public PageTestBase {
+ public:
+ static TouchEventInit GetValidTouchEventInit() { return TouchEventInit(); }
+
+ void SetUp() override {
+ chrome_client_ = new MockDisplayCutoutChromeClient();
+
+ Page::PageClients clients;
+ FillWithEmptyClients(clients);
+ clients.chrome_client = chrome_client_.Get();
+ SetupPageWithClients(&clients, EmptyLocalFrameClient::Create());
+
+ RuntimeEnabledFeatures::SetDisplayCutoutAPIEnabled(true);
+
+ video_ = HTMLVideoElement::Create(GetDocument());
+ GetDocument().body()->AppendChild(video_);
+ controls_ = new MediaControlsImpl(*video_);
+ controls_->InitializeControls();
+ display_cutout_fullscreen_button_ =
+ controls_->display_cutout_fullscreen_button_;
+ }
+
+ mojom::ViewportFit CurrentViewportFit() const {
+ return GetDocument().GetViewportData().GetCurrentViewportFitForTests();
+ }
+
+ void SimulateEnterFullscreen() {
+ {
+ std::unique_ptr<UserGestureIndicator> gesture =
+ Frame::NotifyUserActivation(GetDocument().GetFrame());
+ Fullscreen::RequestFullscreen(*video_);
+ }
+
+ test::RunPendingTasks();
+ GetDocument().ServiceScriptedAnimations(base::TimeTicks());
+
+ EXPECT_TRUE(video_->IsFullscreen());
+ }
+
+ void SimulateExitFullscreen() {
+ Fullscreen::FullyExitFullscreen(GetDocument());
+
+ GetDocument().ServiceScriptedAnimations(base::TimeTicks());
+
+ EXPECT_FALSE(video_->IsFullscreen());
+ }
+
+ protected:
+ Persistent<MockDisplayCutoutChromeClient> chrome_client_;
+ Persistent<HTMLVideoElement> video_;
+ Persistent<MediaControlDisplayCutoutFullscreenButtonElement>
+ display_cutout_fullscreen_button_;
+ Persistent<MediaControlsImpl> controls_;
+};
+
+TEST_F(MediaControlDisplayCutoutFullscreenButtonElementTest,
+ Fullscreen_ButtonVisiblilty) {
+ EXPECT_FALSE(display_cutout_fullscreen_button_->IsWanted());
+
+ SimulateEnterFullscreen();
+
+ EXPECT_TRUE(display_cutout_fullscreen_button_->IsWanted());
+
+ SimulateExitFullscreen();
+
+ EXPECT_FALSE(display_cutout_fullscreen_button_->IsWanted());
+}
+
+TEST_F(MediaControlDisplayCutoutFullscreenButtonElementTest,
+ Fullscreen_ButtonTogglesDisplayCutoutFullscreen) {
+ SimulateEnterFullscreen();
+
+ EXPECT_EQ(mojom::ViewportFit::kAuto, CurrentViewportFit());
+
+ display_cutout_fullscreen_button_->DispatchSimulatedClick(
+ nullptr, kSendNoEvents, SimulatedClickCreationScope::kFromUserAgent);
+ EXPECT_EQ(mojom::ViewportFit::kCoverForcedByUserAgent, CurrentViewportFit());
+
+ display_cutout_fullscreen_button_->DispatchSimulatedClick(
+ nullptr, kSendNoEvents, SimulatedClickCreationScope::kFromUserAgent);
+ EXPECT_EQ(mojom::ViewportFit::kAuto, CurrentViewportFit());
+}
+
+} // namespace blink
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 938d9c1ef5a..50c19e07bc6 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
@@ -69,9 +69,9 @@ void MediaControlDownloadButtonElement::UpdateShownState() {
}
}
-void MediaControlDownloadButtonElement::DefaultEventHandler(Event* event) {
+void MediaControlDownloadButtonElement::DefaultEventHandler(Event& event) {
const KURL& url = MediaElement().currentSrc();
- if (event->type() == EventTypeNames::click &&
+ if (event.type() == EventTypeNames::click &&
!(url.IsNull() || url.IsEmpty())) {
Platform::Current()->RecordAction(
UserMetricsAction("Media.Controls.Download"));
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 887c909ab1f..991b212030e 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
@@ -42,7 +42,7 @@ class MODULES_EXPORT MediaControlDownloadButtonElement final
kCount // Keep last.
};
- void DefaultEventHandler(Event*) final;
+ void DefaultEventHandler(Event&) final;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_element_type.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_element_type.h
index e0efbcb3162..d5a73cc191b 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_element_type.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_element_type.h
@@ -38,6 +38,7 @@ enum MediaControlElementType {
kMediaScrubbingMessage,
kMediaEnterPictureInPictureButton,
kMediaExitPictureInPictureButton,
+ kMediaDisplayCutoutFullscreenButton,
};
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_ELEMENTS_MEDIA_CONTROL_ELEMENT_TYPE_H_
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 699db2a5ee7..088518dbaba 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
@@ -17,18 +17,18 @@
namespace blink {
// static
-bool MediaControlElementsHelper::IsUserInteractionEvent(Event* event) {
- const AtomicString& type = event->type();
+bool MediaControlElementsHelper::IsUserInteractionEvent(const Event& event) {
+ const AtomicString& type = event.type();
return type == EventTypeNames::pointerdown ||
type == EventTypeNames::pointerup ||
type == EventTypeNames::mousedown || type == EventTypeNames::mouseup ||
type == EventTypeNames::click || type == EventTypeNames::dblclick ||
- event->IsKeyboardEvent() || event->IsTouchEvent();
+ event.IsKeyboardEvent() || event.IsTouchEvent();
}
// static
bool MediaControlElementsHelper::IsUserInteractionEventForSlider(
- Event* event,
+ const Event& event,
LayoutObject* layout_object) {
// It is unclear if this can be converted to isUserInteractionEvent(), since
// mouse* events seem to be eaten during a drag anyway, see
@@ -45,7 +45,7 @@ bool MediaControlElementsHelper::IsUserInteractionEventForSlider(
if (slider && !slider->InDragMode())
return false;
- const AtomicString& type = event->type();
+ const AtomicString& type = event.type();
return type == EventTypeNames::mouseover ||
type == EventTypeNames::mouseout ||
type == EventTypeNames::mousemove ||
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_elements_helper.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_elements_helper.h
index e3d04eee637..adc67d95da1 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_elements_helper.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_elements_helper.h
@@ -30,11 +30,11 @@ class MediaControlElementsHelper final {
STATIC_ONLY(MediaControlElementsHelper);
public:
- static bool IsUserInteractionEvent(Event*);
+ static bool IsUserInteractionEvent(const Event&);
// Sliders (the volume control and timeline) need to capture some additional
// events used when dragging the thumb.
- static bool IsUserInteractionEventForSlider(Event*, LayoutObject*);
+ static bool IsUserInteractionEventForSlider(const Event&, LayoutObject*);
// Returns the MediaControlElementType associated with a given |Node|. The
// |node| _must_ be a media control element.
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_fullscreen_button_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_fullscreen_button_element.cc
index 3ac97ca28b4..b3ae69b8ecd 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_fullscreen_button_element.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_fullscreen_button_element.cc
@@ -48,14 +48,14 @@ const char* MediaControlFullscreenButtonElement::GetNameForHistograms() const {
return IsOverflowElement() ? "FullscreenOverflowButton" : "FullscreenButton";
}
-void MediaControlFullscreenButtonElement::DefaultEventHandler(Event* event) {
- if (event->type() == EventTypeNames::click) {
+void MediaControlFullscreenButtonElement::DefaultEventHandler(Event& event) {
+ if (event.type() == EventTypeNames::click) {
RecordClickMetrics();
if (MediaElement().IsFullscreen())
GetMediaControls().ExitFullscreen();
else
GetMediaControls().EnterFullscreen();
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
}
MediaControlInputElement::DefaultEventHandler(event);
}
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_fullscreen_button_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_fullscreen_button_element.h
index a7cdbc7b311..776b1115d9e 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_fullscreen_button_element.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_fullscreen_button_element.h
@@ -29,7 +29,7 @@ class MediaControlFullscreenButtonElement final
const char* GetNameForHistograms() const override;
private:
- void DefaultEventHandler(Event*) override;
+ void DefaultEventHandler(Event&) override;
void RecordClickMetrics();
};
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 0d57f19264a..806b4ea1fe2 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
@@ -198,8 +198,8 @@ void MediaControlInputElement::UpdateShownState() {
MediaControlElementBase::UpdateShownState();
}
-void MediaControlInputElement::DefaultEventHandler(Event* event) {
- if (event->type() == EventTypeNames::click)
+void MediaControlInputElement::DefaultEventHandler(Event& event) {
+ if (event.type() == EventTypeNames::click)
MaybeRecordInteracted();
HTMLInputElement::DefaultEventHandler(event);
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 d392c81038c..0fc1d31cbd1 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
@@ -53,7 +53,7 @@ class MODULES_EXPORT MediaControlInputElement : public HTMLInputElement,
virtual WebLocalizedString::Name GetOverflowStringName() const;
// Implements a default event handler to record interaction on click.
- void DefaultEventHandler(Event*) override;
+ void DefaultEventHandler(Event&) override;
// Implements MediaControlElementBase.
void UpdateShownState() override;
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 620d7160f19..dfb4d440740 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
@@ -89,18 +89,20 @@ void MediaControlLoadingPanelElement::PopulateShadowDOM() {
// created by the animation.
HTMLDivElement* mask1 =
MediaControlElementsHelper::CreateDivWithId("spinner-mask-1", layer);
- mask1_background_ = MediaControlElementsHelper::CreateDivWithId(
- "spinner-mask-1-background", mask1);
+ mask1_background_ = MediaControlElementsHelper::CreateDiv(
+ "-internal-media-controls-loading-panel-spinner-mask-1-background",
+ mask1);
HTMLDivElement* mask2 =
MediaControlElementsHelper::CreateDivWithId("spinner-mask-2", layer);
- mask2_background_ = MediaControlElementsHelper::CreateDivWithId(
- "spinner-mask-2-background", mask2);
+ mask2_background_ = MediaControlElementsHelper::CreateDiv(
+ "-internal-media-controls-loading-panel-spinner-mask-2-background",
+ mask2);
event_listener_ = new MediaControlAnimationEventListener(this);
}
void MediaControlLoadingPanelElement::RemovedFrom(
- ContainerNode* insertion_point) {
+ ContainerNode& insertion_point) {
if (event_listener_) {
event_listener_->Detach();
event_listener_.Clear();
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_loading_panel_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_loading_panel_element.h
index 15b30a4931e..c18ffda7ea4 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_loading_panel_element.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_loading_panel_element.h
@@ -70,7 +70,7 @@ class MODULES_EXPORT MediaControlLoadingPanelElement final
void PopulateShadowDOM();
// Cleans up the event listener when this element is removed from the DOM.
- void RemovedFrom(ContainerNode*) override;
+ void RemovedFrom(ContainerNode&) override;
// This counts how many animation iterations the background elements have
// played.
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_loading_panel_element_test.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_loading_panel_element_test.cc
index 27a0c7e2829..813235783e9 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_loading_panel_element_test.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_loading_panel_element_test.cc
@@ -169,7 +169,7 @@ class MediaControlLoadingPanelElementTest : public PageTestBase {
void TriggerEvent(const AtomicString& name) {
Event* event = Event::Create(name);
- loading_element_->mask1_background_->DispatchEvent(event);
+ loading_element_->mask1_background_->DispatchEvent(*event);
}
Persistent<HTMLMediaElement> media_element_;
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_mute_button_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_mute_button_element.cc
index 155419ebe6e..34f2affb6ad 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_mute_button_element.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_mute_button_element.cc
@@ -50,8 +50,8 @@ const char* MediaControlMuteButtonElement::GetNameForHistograms() const {
return IsOverflowElement() ? "MuteOverflowButton" : "MuteButton";
}
-void MediaControlMuteButtonElement::DefaultEventHandler(Event* event) {
- if (event->type() == EventTypeNames::click) {
+void MediaControlMuteButtonElement::DefaultEventHandler(Event& event) {
+ if (event.type() == EventTypeNames::click) {
if (MediaElement().muted()) {
Platform::Current()->RecordAction(
UserMetricsAction("Media.Controls.Unmute"));
@@ -61,7 +61,7 @@ void MediaControlMuteButtonElement::DefaultEventHandler(Event* event) {
}
MediaElement().setMuted(!MediaElement().muted());
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
}
MediaControlInputElement::DefaultEventHandler(event);
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_mute_button_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_mute_button_element.h
index ae9cd018429..10e9e75e732 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_mute_button_element.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_mute_button_element.h
@@ -26,7 +26,7 @@ class MediaControlMuteButtonElement final : public MediaControlInputElement {
const char* GetNameForHistograms() const override;
private:
- void DefaultEventHandler(Event*) override;
+ void DefaultEventHandler(Event&) override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overflow_menu_button_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overflow_menu_button_element.cc
index 2de2daf278a..cb2ffa7acc1 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overflow_menu_button_element.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overflow_menu_button_element.cc
@@ -41,10 +41,10 @@ void MediaControlOverflowMenuButtonElement::UpdateShownState() {
}
}
-void MediaControlOverflowMenuButtonElement::DefaultEventHandler(Event* event) {
+void MediaControlOverflowMenuButtonElement::DefaultEventHandler(Event& event) {
// Only respond to a click event if we are not disabled.
if (!hasAttribute(HTMLNames::disabledAttr) &&
- event->type() == EventTypeNames::click) {
+ event.type() == EventTypeNames::click) {
if (GetMediaControls().OverflowMenuVisible()) {
Platform::Current()->RecordAction(
UserMetricsAction("Media.Controls.OverflowClose"));
@@ -54,7 +54,7 @@ void MediaControlOverflowMenuButtonElement::DefaultEventHandler(Event* event) {
}
GetMediaControls().ToggleOverflowMenu();
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
}
MediaControlInputElement::DefaultEventHandler(event);
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overflow_menu_button_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overflow_menu_button_element.h
index 47f94bc40a0..bf65cb6fc5c 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overflow_menu_button_element.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overflow_menu_button_element.h
@@ -27,7 +27,7 @@ class MediaControlOverflowMenuButtonElement final
void UpdateShownState() final;
private:
- void DefaultEventHandler(Event*) override;
+ void DefaultEventHandler(Event&) override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overflow_menu_list_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overflow_menu_list_element.cc
index 5012a090020..cb7d4e67ef0 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overflow_menu_list_element.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overflow_menu_list_element.cc
@@ -37,9 +37,9 @@ void MediaControlOverflowMenuListElement::MaybeRecordTimeTaken(
time_shown_.reset();
}
-void MediaControlOverflowMenuListElement::DefaultEventHandler(Event* event) {
- if (event->type() == EventTypeNames::click)
- event->SetDefaultHandled();
+void MediaControlOverflowMenuListElement::DefaultEventHandler(Event& event) {
+ if (event.type() == EventTypeNames::click)
+ event.SetDefaultHandled();
MediaControlPopupMenuElement::DefaultEventHandler(event);
}
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overflow_menu_list_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overflow_menu_list_element.h
index aaf61b2c7ad..4da049d2d2f 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overflow_menu_list_element.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overflow_menu_list_element.h
@@ -33,7 +33,7 @@ class MediaControlOverflowMenuListElement final
};
void MaybeRecordTimeTaken(TimeTakenHistogram);
- void DefaultEventHandler(Event*) override;
+ void DefaultEventHandler(Event&) override;
TaskHandle current_task_handle_;
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_enclosure_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_enclosure_element.cc
index 46fd015babd..1e80f7fcd8b 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_enclosure_element.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_enclosure_element.cc
@@ -15,13 +15,13 @@ MediaControlOverlayEnclosureElement::MediaControlOverlayEnclosureElement(
SetShadowPseudoId(AtomicString("-webkit-media-controls-overlay-enclosure"));
}
-void MediaControlOverlayEnclosureElement::DefaultEventHandler(Event* event) {
+void MediaControlOverlayEnclosureElement::DefaultEventHandler(Event& event) {
// When the user interacts with the media element, the Cast overlay button
// needs to be shown.
- if (event->type() == EventTypeNames::gesturetap ||
- event->type() == EventTypeNames::click ||
- event->type() == EventTypeNames::pointerover ||
- event->type() == EventTypeNames::pointermove) {
+ if (event.type() == EventTypeNames::gesturetap ||
+ event.type() == EventTypeNames::click ||
+ event.type() == EventTypeNames::pointerover ||
+ event.type() == EventTypeNames::pointermove) {
GetMediaControls().ShowOverlayCastButtonIfNeeded();
}
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_enclosure_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_enclosure_element.h
index f91049dfbb5..b43bba8a0e0 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_enclosure_element.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_enclosure_element.h
@@ -17,7 +17,7 @@ class MediaControlOverlayEnclosureElement final
public:
explicit MediaControlOverlayEnclosureElement(MediaControlsImpl&);
- void DefaultEventHandler(Event*) override;
+ void DefaultEventHandler(Event&) override;
};
} // namespace blink
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 f65966ea56b..485796cea4b 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
@@ -216,16 +216,16 @@ void MediaControlOverlayPlayButtonElement::MaybeJump(int seconds) {
left_jump_arrow_->Show();
}
-void MediaControlOverlayPlayButtonElement::DefaultEventHandler(Event* event) {
+void MediaControlOverlayPlayButtonElement::DefaultEventHandler(Event& event) {
if (ShouldCausePlayPause(event)) {
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
MaybePlayPause();
- } else if (event->type() == EventTypeNames::click) {
- event->SetDefaultHandled();
+ } else if (event.type() == EventTypeNames::click) {
+ event.SetDefaultHandled();
- DCHECK(event->IsMouseEvent());
- MouseEvent* mouse_event = ToMouseEvent(event);
- DCHECK(mouse_event->HasPosition());
+ DCHECK(event.IsMouseEvent());
+ auto& mouse_event = ToMouseEvent(event);
+ DCHECK(mouse_event.HasPosition());
if (!tap_timer_.IsActive()) {
// If there was not a previous touch and this was outside of the button
@@ -233,7 +233,7 @@ void MediaControlOverlayPlayButtonElement::DefaultEventHandler(Event* event) {
// case their is a second tap.
if (tap_timer_.IsActive())
return;
- tap_was_touch_event_ = MediaControlsImpl::IsTouchEvent(event);
+ tap_was_touch_event_ = MediaControlsImpl::IsTouchEvent(&event);
tap_timer_.StartOneShot(kDoubleTapDelay, FROM_HERE);
} else {
// Cancel the play pause event.
@@ -241,12 +241,12 @@ void MediaControlOverlayPlayButtonElement::DefaultEventHandler(Event* event) {
// If both taps were touch events, then jump.
if (tap_was_touch_event_.value() &&
- MediaControlsImpl::IsTouchEvent(event)) {
+ MediaControlsImpl::IsTouchEvent(&event)) {
// Jump forwards or backwards based on the position of the tap.
WebSize element_size =
MediaControlElementsHelper::GetSizeOrDefault(*this, WebSize(0, 0));
- if (mouse_event->clientX() >= element_size.width / 2) {
+ if (mouse_event.clientX() >= element_size.width / 2) {
MaybeJump(kNumberOfSecondsToJump);
} else {
MaybeJump(kNumberOfSecondsToJump * -1);
@@ -267,26 +267,27 @@ void MediaControlOverlayPlayButtonElement::DefaultEventHandler(Event* event) {
MediaControlInputElement::DefaultEventHandler(event);
}
-bool MediaControlOverlayPlayButtonElement::KeepEventInNode(Event* event) {
+bool MediaControlOverlayPlayButtonElement::KeepEventInNode(
+ const Event& event) const {
// We only care about user interaction events.
if (!MediaControlElementsHelper::IsUserInteractionEvent(event))
return false;
// For mouse events, only keep in node if they're on the internal button.
- if (event->IsMouseEvent() && MediaControlsImpl::IsModern())
+ if (event.IsMouseEvent() && MediaControlsImpl::IsModern())
return IsMouseEventOnInternalButton(ToMouseEvent(event));
return true;
}
bool MediaControlOverlayPlayButtonElement::ShouldCausePlayPause(
- Event* event) const {
+ const Event& event) const {
// Only click events cause a play/pause.
- if (event->type() != EventTypeNames::click)
+ if (event.type() != EventTypeNames::click)
return false;
// Double tap to navigate should only be available on modern controls.
- if (!MediaControlsImpl::IsModern() || !event->IsMouseEvent())
+ if (!MediaControlsImpl::IsModern() || !event.IsMouseEvent())
return true;
// TODO(beccahughes): Move to PointerEvent.
@@ -294,9 +295,16 @@ bool MediaControlOverlayPlayButtonElement::ShouldCausePlayPause(
}
bool MediaControlOverlayPlayButtonElement::IsMouseEventOnInternalButton(
- MouseEvent* mouse_event) const {
- // If no position data available, default to yes.
- if (!mouse_event->HasPosition())
+ const MouseEvent& mouse_event) const {
+ // If we don't have the necessary pieces to calculate whether the event is
+ // within the bounds of the button, default to yes.
+ if (!mouse_event.HasPosition() || !isConnected() ||
+ !GetDocument().GetLayoutView() || !MediaElement().ShouldShowControls()) {
+ return true;
+ }
+
+ // If there is no layout view, default to yes.
+ if (!GetDocument().GetLayoutView())
return true;
// Find the zoom-adjusted internal button bounding box.
@@ -310,7 +318,7 @@ bool MediaControlOverlayPlayButtonElement::IsMouseEventOnInternalButton(
// Check the button and a margin around it.
return IsPointInRect(*box, kInnerButtonTouchPaddingSize,
- mouse_event->clientX(), mouse_event->clientY());
+ mouse_event.clientX(), mouse_event.clientY());
}
WebSize MediaControlOverlayPlayButtonElement::GetSizeOrDefault() const {
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 144654ce9aa..d2eec864f5b 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
@@ -29,7 +29,7 @@ class MODULES_EXPORT MediaControlOverlayPlayButtonElement final
// MediaControlInputElement overrides.
void UpdateDisplayType() override;
- void OnMediaKeyboardEvent(Event* event) { DefaultEventHandler(event); }
+ void OnMediaKeyboardEvent(Event* event) { DefaultEventHandler(*event); }
WebSize GetSizeOrDefault() const final;
@@ -79,11 +79,11 @@ class MODULES_EXPORT MediaControlOverlayPlayButtonElement final
void TapTimerFired(TimerBase*);
- void DefaultEventHandler(Event*) override;
- bool KeepEventInNode(Event*) override;
+ void DefaultEventHandler(Event&) override;
+ bool KeepEventInNode(const Event&) const override;
- bool ShouldCausePlayPause(Event*) const;
- bool IsMouseEventOnInternalButton(MouseEvent*) const;
+ bool ShouldCausePlayPause(const Event&) const;
+ bool IsMouseEventOnInternalButton(const MouseEvent&) const;
void MaybePlayPause();
void MaybeJump(int);
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element_test.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element_test.cc
index e9ebad645f1..a6cf60699f9 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element_test.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element_test.cc
@@ -8,7 +8,13 @@
#include "third_party/blink/renderer/core/css/css_property_value_set.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/core/events/mouse_event.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
+#include "third_party/blink/renderer/core/html/html_html_element.h"
+#include "third_party/blink/renderer/core/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"
+#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
namespace blink {
@@ -39,7 +45,40 @@ class MediaControlOverlayPlayButtonElementTest : public PageTestBase {
void SimulateAnimationIteration() {
Event* event = Event::Create(EventTypeNames::animationiteration);
- GetElementById("arrow-3")->DispatchEvent(event);
+ GetElementById("arrow-3")->DispatchEvent(*event);
+ }
+
+ Document& CreateTestDocumentWithBody() {
+ Document* document = Document::CreateForTest();
+ HTMLHtmlElement* html = HTMLHtmlElement::Create(*document);
+ document->AppendChild(html);
+ document->documentElement()->SetInnerHTMLFromString("<body></body>");
+ return *document;
+ }
+
+ void CreateTestOverlayPlayButton(Document& test_document) {
+ // Create a video element so that a MediaControlsImpl is created.
+ HTMLVideoElement* media_element = HTMLVideoElement::Create(test_document);
+ media_element->SetBooleanAttribute(HTMLNames::controlsAttr, true);
+ test_document.body()->AppendChild(media_element);
+
+ MediaControlsImpl* media_controls =
+ static_cast<MediaControlsImpl*>(media_element->GetMediaControls());
+ ASSERT_NE(nullptr, media_controls);
+
+ // Create a MediaControlOverlayPlayButtonElement for testing.
+ overlay_play_button_ =
+ new MediaControlOverlayPlayButtonElement(*media_controls);
+ }
+
+ void SimulateKeepEventInNode() {
+ MouseEventInit mouse_initializer;
+ mouse_initializer.setView(GetDocument().domWindow());
+ mouse_initializer.setButton(1);
+
+ MouseEvent* mouse_event =
+ MouseEvent::Create(nullptr, EventTypeNames::click, mouse_initializer);
+ overlay_play_button_->KeepEventInNode(*mouse_event);
}
private:
@@ -54,6 +93,7 @@ class MediaControlOverlayPlayButtonElementTest : public PageTestBase {
return GetDocument().body()->getElementById(id);
}
+ Persistent<MediaControlOverlayPlayButtonElement> overlay_play_button_;
Persistent<MediaControlOverlayPlayButtonElement::AnimatedArrow>
arrow_element_;
};
@@ -79,4 +119,12 @@ TEST_F(MediaControlOverlayPlayButtonElementTest, ShowIncrementsCounter) {
ExpectPresentAndShown();
}
+TEST_F(MediaControlOverlayPlayButtonElementTest,
+ KeepEventInNodeWithoutLayoutViewDoesntCrash) {
+ ScopedModernMediaControlsForTest enable_modern_media_controls(true);
+ Document& document_without_layout_view = CreateTestDocumentWithBody();
+ CreateTestOverlayPlayButton(document_without_layout_view);
+ SimulateKeepEventInNode();
+}
+
} // namespace blink
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 259f7edd83c..b4d02b11036 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
@@ -6,6 +6,7 @@
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
+#include "third_party/blink/renderer/core/dom/events/event_listener.h"
#include "third_party/blink/renderer/core/html/media/html_media_element.h"
#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"
@@ -124,7 +125,7 @@ void MediaControlPanelElement::MakeTransparent() {
opaque_ = false;
}
-void MediaControlPanelElement::RemovedFrom(ContainerNode*) {
+void MediaControlPanelElement::RemovedFrom(ContainerNode&) {
DetachTransitionEventListener();
}
@@ -164,17 +165,17 @@ void MediaControlPanelElement::DetachTransitionEventListener() {
event_listener_->Detach();
}
-void MediaControlPanelElement::DefaultEventHandler(Event* event) {
+void MediaControlPanelElement::DefaultEventHandler(Event& event) {
// Suppress the media element activation behavior (toggle play/pause) when
// any part of the control panel is clicked.
- if (event->type() == EventTypeNames::click) {
- event->SetDefaultHandled();
+ if (event.type() == EventTypeNames::click) {
+ event.SetDefaultHandled();
return;
}
HTMLDivElement::DefaultEventHandler(event);
}
-bool MediaControlPanelElement::KeepEventInNode(Event* event) {
+bool MediaControlPanelElement::KeepEventInNode(const Event& event) const {
return !MediaControlsImpl::IsModern() &&
MediaControlElementsHelper::IsUserInteractionEvent(event);
}
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 aed4691dec3..301e1a26722 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
@@ -29,7 +29,7 @@ class MODULES_EXPORT MediaControlPanelElement final
void SetKeepDisplayedForAccessibility(bool);
// Node override;
- void RemovedFrom(ContainerNode*) override;
+ void RemovedFrom(ContainerNode&) override;
void Trace(blink::Visitor*) override;
@@ -44,8 +44,8 @@ class MODULES_EXPORT MediaControlPanelElement final
void EnsureTransitionEventListener();
void DetachTransitionEventListener();
- void DefaultEventHandler(Event*) override;
- bool KeepEventInNode(Event*) override;
+ void DefaultEventHandler(Event&) override;
+ bool KeepEventInNode(const Event&) const override;
void DidBecomeVisible();
void HandleTransitionEndEvent();
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element_test.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element_test.cc
index 92c35bd668c..d158961a2b5 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element_test.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element_test.cc
@@ -53,7 +53,7 @@ class MediaControlPanelElementTest : public PageTestBase {
private:
void TriggerEvent(const AtomicString& name) {
Event* event = Event::Create(name);
- GetPanel().DispatchEvent(event);
+ GetPanel().DispatchEvent(*event);
}
Persistent<HTMLMediaElement> media_element_;
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 cd492d9f641..3c6c79872a8 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
@@ -65,8 +65,8 @@ const char* MediaControlPictureInPictureButtonElement::GetNameForHistograms()
}
void MediaControlPictureInPictureButtonElement::DefaultEventHandler(
- Event* event) {
- if (event->type() == EventTypeNames::click) {
+ Event& event) {
+ if (event.type() == EventTypeNames::click) {
PictureInPictureControllerImpl& controller =
PictureInPictureControllerImpl::From(MediaElement().GetDocument());
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_picture_in_picture_button_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_picture_in_picture_button_element.h
index 13c85750a47..4a395d2bf12 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_picture_in_picture_button_element.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_picture_in_picture_button_element.h
@@ -23,13 +23,13 @@ class MediaControlPictureInPictureButtonElement final
WebLocalizedString::Name GetOverflowStringName() const override;
bool HasOverflowButton() const override;
- void OnMediaKeyboardEvent(Event* event) { DefaultEventHandler(event); }
+ void OnMediaKeyboardEvent(Event* event) { DefaultEventHandler(*event); }
protected:
const char* GetNameForHistograms() const override;
private:
- void DefaultEventHandler(Event*) override;
+ void DefaultEventHandler(Event&) override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_play_button_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_play_button_element.cc
index 7f4ef3c8d55..e358f0005b7 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_play_button_element.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_play_button_element.cc
@@ -48,8 +48,8 @@ const char* MediaControlPlayButtonElement::GetNameForHistograms() const {
return IsOverflowElement() ? "PlayPauseOverflowButton" : "PlayPauseButton";
}
-void MediaControlPlayButtonElement::DefaultEventHandler(Event* event) {
- if (event->type() == EventTypeNames::click) {
+void MediaControlPlayButtonElement::DefaultEventHandler(Event& event) {
+ if (event.type() == EventTypeNames::click) {
if (MediaElement().paused()) {
Platform::Current()->RecordAction(
UserMetricsAction("Media.Controls.Play"));
@@ -68,7 +68,7 @@ void MediaControlPlayButtonElement::DefaultEventHandler(Event* event) {
MediaElement().TogglePlayState();
UpdateDisplayType();
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
}
MediaControlInputElement::DefaultEventHandler(event);
}
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_play_button_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_play_button_element.h
index 4767a15046a..279d966a786 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_play_button_element.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_play_button_element.h
@@ -22,13 +22,13 @@ class MediaControlPlayButtonElement final : public MediaControlInputElement {
WebLocalizedString::Name GetOverflowStringName() const override;
bool HasOverflowButton() const override;
- void OnMediaKeyboardEvent(Event* event) { DefaultEventHandler(event); }
+ void OnMediaKeyboardEvent(Event* event) { DefaultEventHandler(*event); }
protected:
const char* GetNameForHistograms() const override;
private:
- void DefaultEventHandler(Event*) override;
+ void DefaultEventHandler(Event&) override;
};
} // namespace blink
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 18460abfdde..03276daaf1d 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
@@ -142,26 +142,26 @@ void MediaControlPopupMenuElement::OnItemSelected() {
SetIsWanted(false);
}
-void MediaControlPopupMenuElement::DefaultEventHandler(Event* event) {
- if (event->type() == EventTypeNames::pointermove) {
- ToElement(event->target()->ToNode())->focus();
- } else if (event->type() == EventTypeNames::focusout) {
+void MediaControlPopupMenuElement::DefaultEventHandler(Event& event) {
+ if (event.type() == EventTypeNames::pointermove) {
+ ToElement(event.target()->ToNode())->focus();
+ } else if (event.type() == EventTypeNames::focusout) {
GetDocument()
.GetTaskRunner(TaskType::kMediaElementEvent)
->PostTask(FROM_HERE,
WTF::Bind(&MediaControlPopupMenuElement::HideIfNotFocused,
WrapWeakPersistent(this)));
- } else if (event->type() == EventTypeNames::click) {
+ } else if (event.type() == EventTypeNames::click) {
OnItemSelected();
- event->stopPropagation();
- event->SetDefaultHandled();
+ event.stopPropagation();
+ event.SetDefaultHandled();
}
MediaControlDivElement::DefaultEventHandler(event);
}
-void MediaControlPopupMenuElement::RemovedFrom(ContainerNode* container) {
+void MediaControlPopupMenuElement::RemovedFrom(ContainerNode& container) {
if (IsWanted())
SetIsWanted(false);
event_listener_ = nullptr;
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 042dc8a2ae2..691f301be7d 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,8 +25,8 @@ class MediaControlPopupMenuElement : public MediaControlDivElement {
virtual void OnItemSelected();
// Node override.
- void DefaultEventHandler(Event*) override;
- void RemovedFrom(ContainerNode*) override;
+ void DefaultEventHandler(Event&) override;
+ void RemovedFrom(ContainerNode&) override;
void Trace(blink::Visitor*) override;
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 8f5a631fa87..0e1c05cd686 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
@@ -46,9 +46,9 @@ class MODULES_EXPORT MediaControlSliderElement
Element& GetTrackElement();
- private:
float ZoomFactor() const;
+ private:
Position before_segment_position_;
Position after_segment_position_;
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_text_track_list_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_text_track_list_element.cc
index bee8c4bb3f4..c04a9512b28 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_text_track_list_element.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_text_track_list_element.cc
@@ -70,15 +70,15 @@ Element* MediaControlTextTrackListElement::PopupAnchor() const {
return &GetMediaControls().ToggleClosedCaptions();
}
-void MediaControlTextTrackListElement::DefaultEventHandler(Event* event) {
- if (event->type() == EventTypeNames::click) {
+void MediaControlTextTrackListElement::DefaultEventHandler(Event& event) {
+ if (event.type() == EventTypeNames::click) {
// This handles the back button click. Clicking on a menu item triggers the
// change event instead.
GetMediaControls().ToggleOverflowMenu();
- event->SetDefaultHandled();
- } else if (event->type() == EventTypeNames::change) {
+ event.SetDefaultHandled();
+ } else if (event.type() == EventTypeNames::change) {
// Identify which input element was selected and set track to showing
- Node* target = event->target()->ToNode();
+ Node* target = event.target()->ToNode();
if (!target || !target->IsElementNode())
return;
@@ -91,7 +91,7 @@ void MediaControlTextTrackListElement::DefaultEventHandler(Event* event) {
MediaElement().DisableAutomaticTextTrackSelection();
}
- event->SetDefaultHandled();
+ event.SetDefaultHandled();
}
MediaControlPopupMenuElement::DefaultEventHandler(event);
}
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_text_track_list_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_text_track_list_element.h
index 7cc4031bc7c..1c9b7ae61be 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_text_track_list_element.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_text_track_list_element.h
@@ -25,7 +25,7 @@ class MediaControlTextTrackListElement final
Element* PopupAnchor() const final;
private:
- void DefaultEventHandler(Event*) override;
+ void DefaultEventHandler(Event&) override;
void RefreshTextTrackListMenu();
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 62ef007e5f6..456171e86fd 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
@@ -12,6 +12,7 @@
#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/html/html_div_element.h"
#include "third_party/blink/renderer/core/html/html_style_element.h"
#include "third_party/blink/renderer/core/html/media/html_media_element.h"
@@ -104,51 +105,52 @@ const char* MediaControlTimelineElement::GetNameForHistograms() const {
return "TimelineSlider";
}
-void MediaControlTimelineElement::DefaultEventHandler(Event* event) {
+void MediaControlTimelineElement::DefaultEventHandler(Event& event) {
if (!isConnected() || !GetDocument().IsActive() || controls_hidden_)
return;
RenderBarSegments();
- if (BeginScrubbingEvent(*event)) {
+ if (BeginScrubbingEvent(event)) {
Platform::Current()->RecordAction(
UserMetricsAction("Media.Controls.ScrubbingBegin"));
- GetMediaControls().BeginScrubbing(MediaControlsImpl::IsTouchEvent(event));
+ GetMediaControls().BeginScrubbing(MediaControlsImpl::IsTouchEvent(&event));
Element* thumb = UserAgentShadowRoot()->getElementById(
ShadowElementNames::SliderThumb());
- bool started_from_thumb = thumb && thumb == event->target()->ToNode();
+ bool started_from_thumb = thumb && thumb == event.target()->ToNode();
metrics_.StartGesture(started_from_thumb);
- } else if (EndScrubbingEvent(*event)) {
+ } else if (EndScrubbingEvent(event)) {
Platform::Current()->RecordAction(
UserMetricsAction("Media.Controls.ScrubbingEnd"));
GetMediaControls().EndScrubbing();
metrics_.RecordEndGesture(TrackWidth(), MediaElement().duration());
}
- if (event->type() == EventTypeNames::keydown) {
+ if (event.type() == EventTypeNames::keydown) {
metrics_.StartKey();
}
- if (event->type() == EventTypeNames::keyup && event->IsKeyboardEvent()) {
- metrics_.RecordEndKey(TrackWidth(), ToKeyboardEvent(event)->keyCode());
+ if (event.type() == EventTypeNames::keyup && event.IsKeyboardEvent()) {
+ metrics_.RecordEndKey(TrackWidth(), ToKeyboardEvent(event).keyCode());
}
MediaControlInputElement::DefaultEventHandler(event);
- if (event->IsMouseEvent() || event->IsKeyboardEvent() ||
- event->IsGestureEvent() || event->IsPointerEvent()) {
+ if (event.IsMouseEvent() || event.IsKeyboardEvent() ||
+ event.IsGestureEvent() || event.IsPointerEvent()) {
MaybeRecordInteracted();
}
// Update the value based on the touchmove event.
- if (is_touching_ && event->type() == EventTypeNames::touchmove) {
- TouchEvent* touch_event = ToTouchEvent(event);
- if (touch_event->touches()->length() != 1)
+ if (is_touching_ && event.type() == EventTypeNames::touchmove) {
+ auto& touch_event = ToTouchEvent(event);
+ if (touch_event.touches()->length() != 1)
return;
- const Touch* touch = touch_event->touches()->item(0);
- double position = max(0.0, fmin(1.0, touch->clientX() / TrackWidth()));
+ const Touch* touch = touch_event.touches()->item(0);
+ double position =
+ max(0.0, fmin(1.0, touch->clientX() / TrackWidth() * ZoomFactor()));
SetPosition(position * MediaElement().duration());
- } else if (event->type() != EventTypeNames::input) {
+ } else if (event.type() != EventTypeNames::input) {
return;
}
@@ -172,7 +174,7 @@ void MediaControlTimelineElement::DefaultEventHandler(Event* event) {
GetMediaControls().UpdateCurrentTimeDisplay();
}
-bool MediaControlTimelineElement::KeepEventInNode(Event* event) {
+bool MediaControlTimelineElement::KeepEventInNode(const Event& event) const {
return MediaControlElementsHelper::IsUserInteractionEventForSlider(
event, GetLayoutObject());
}
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 bed92378d16..b46f24692fa 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
@@ -29,7 +29,7 @@ class MediaControlTimelineElement : public MediaControlSliderElement {
void OnPlaying();
- void OnMediaKeyboardEvent(Event* event) { DefaultEventHandler(event); }
+ void OnMediaKeyboardEvent(Event* event) { DefaultEventHandler(*event); }
void RenderBarSegments();
@@ -43,8 +43,8 @@ class MediaControlTimelineElement : public MediaControlSliderElement {
const char* GetNameForHistograms() const override;
private:
- void DefaultEventHandler(Event*) override;
- bool KeepEventInNode(Event*) override;
+ void DefaultEventHandler(Event&) override;
+ bool KeepEventInNode(const Event&) const override;
// Checks if we can begin or end a scrubbing event. If the event is a pointer
// event then it needs to start and end with valid pointer events. If the
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 7d63848146f..b0697b0be55 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
@@ -55,7 +55,7 @@ TEST_F(MediaControlTimelineElementTest, PointerDownPausesPlayback) {
ASSERT_FALSE(Video()->paused());
Timeline()->DispatchEvent(
- PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
+ *PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
EXPECT_TRUE(Video()->paused());
}
@@ -65,7 +65,7 @@ TEST_F(MediaControlTimelineElementTest, PointerDownRightClickNoOp) {
PointerEventInit init = GetValidPointerEventInit();
init.setButton(static_cast<int>(WebPointerProperties::Button::kRight));
- Timeline()->DispatchEvent(PointerEvent::Create("pointerdown", init));
+ Timeline()->DispatchEvent(*PointerEvent::Create("pointerdown", init));
EXPECT_FALSE(Video()->paused());
}
@@ -75,7 +75,7 @@ TEST_F(MediaControlTimelineElementTest, PointerDownNotPrimaryNoOp) {
PointerEventInit init = GetValidPointerEventInit();
init.setIsPrimary(false);
- Timeline()->DispatchEvent(PointerEvent::Create("pointerdown", init));
+ Timeline()->DispatchEvent(*PointerEvent::Create("pointerdown", init));
EXPECT_FALSE(Video()->paused());
}
@@ -84,9 +84,9 @@ TEST_F(MediaControlTimelineElementTest, PointerUpResumesPlayback) {
ASSERT_FALSE(Video()->paused());
Timeline()->DispatchEvent(
- PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
+ *PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
Timeline()->DispatchEvent(
- PointerEvent::Create("pointerup", GetValidPointerEventInit()));
+ *PointerEvent::Create("pointerup", GetValidPointerEventInit()));
EXPECT_FALSE(Video()->paused());
}
@@ -95,11 +95,11 @@ TEST_F(MediaControlTimelineElementTest, PointerUpRightClickNoOp) {
ASSERT_FALSE(Video()->paused());
Timeline()->DispatchEvent(
- PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
+ *PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
PointerEventInit init = GetValidPointerEventInit();
init.setButton(static_cast<int>(WebPointerProperties::Button::kRight));
- Timeline()->DispatchEvent(PointerEvent::Create("pointerup", init));
+ Timeline()->DispatchEvent(*PointerEvent::Create("pointerup", init));
EXPECT_TRUE(Video()->paused());
}
@@ -108,11 +108,11 @@ TEST_F(MediaControlTimelineElementTest, PointerUpNotPrimaryNoOp) {
ASSERT_FALSE(Video()->paused());
Timeline()->DispatchEvent(
- PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
+ *PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
PointerEventInit init = GetValidPointerEventInit();
init.setIsPrimary(false);
- Timeline()->DispatchEvent(PointerEvent::Create("pointerup", init));
+ Timeline()->DispatchEvent(*PointerEvent::Create("pointerup", init));
EXPECT_TRUE(Video()->paused());
}
@@ -121,9 +121,9 @@ TEST_F(MediaControlTimelineElementTest, PointerOutDoesNotResume) {
ASSERT_FALSE(Video()->paused());
Timeline()->DispatchEvent(
- PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
+ *PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
Timeline()->DispatchEvent(
- PointerEvent::Create("pointerout", GetValidPointerEventInit()));
+ *PointerEvent::Create("pointerout", GetValidPointerEventInit()));
EXPECT_TRUE(Video()->paused());
}
@@ -132,9 +132,9 @@ TEST_F(MediaControlTimelineElementTest, PointerMoveDoesNotResume) {
ASSERT_FALSE(Video()->paused());
Timeline()->DispatchEvent(
- PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
+ *PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
Timeline()->DispatchEvent(
- PointerEvent::Create("pointermove", GetValidPointerEventInit()));
+ *PointerEvent::Create("pointermove", GetValidPointerEventInit()));
EXPECT_TRUE(Video()->paused());
}
@@ -143,9 +143,9 @@ TEST_F(MediaControlTimelineElementTest, PointerCancelResumesPlayback) {
ASSERT_FALSE(Video()->paused());
Timeline()->DispatchEvent(
- PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
+ *PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
Timeline()->DispatchEvent(
- PointerEvent::Create("pointercancel", GetValidPointerEventInit()));
+ *PointerEvent::Create("pointercancel", GetValidPointerEventInit()));
EXPECT_FALSE(Video()->paused());
}
@@ -154,7 +154,7 @@ TEST_F(MediaControlTimelineElementTest, TouchStartPausesPlayback) {
ASSERT_FALSE(Video()->paused());
Timeline()->DispatchEvent(
- TouchEvent::Create("touchstart", GetValidTouchEventInit()));
+ *TouchEvent::Create("touchstart", GetValidTouchEventInit()));
EXPECT_TRUE(Video()->paused());
}
@@ -163,9 +163,9 @@ TEST_F(MediaControlTimelineElementTest, TouchEndResumesPlayback) {
ASSERT_FALSE(Video()->paused());
Timeline()->DispatchEvent(
- TouchEvent::Create("touchstart", GetValidTouchEventInit()));
+ *TouchEvent::Create("touchstart", GetValidTouchEventInit()));
Timeline()->DispatchEvent(
- TouchEvent::Create("touchend", GetValidTouchEventInit()));
+ *TouchEvent::Create("touchend", GetValidTouchEventInit()));
EXPECT_FALSE(Video()->paused());
}
@@ -174,9 +174,9 @@ TEST_F(MediaControlTimelineElementTest, TouchCancelResumesPlayback) {
ASSERT_FALSE(Video()->paused());
Timeline()->DispatchEvent(
- TouchEvent::Create("touchstart", GetValidTouchEventInit()));
+ *TouchEvent::Create("touchstart", GetValidTouchEventInit()));
Timeline()->DispatchEvent(
- TouchEvent::Create("touchcancel", GetValidTouchEventInit()));
+ *TouchEvent::Create("touchcancel", GetValidTouchEventInit()));
EXPECT_FALSE(Video()->paused());
}
@@ -185,9 +185,9 @@ TEST_F(MediaControlTimelineElementTest, ChangeResumesPlayback) {
ASSERT_FALSE(Video()->paused());
Timeline()->DispatchEvent(
- TouchEvent::Create("touchstart", GetValidTouchEventInit()));
+ *TouchEvent::Create("touchstart", GetValidTouchEventInit()));
Timeline()->DispatchEvent(
- TouchEvent::Create("change", GetValidTouchEventInit()));
+ *TouchEvent::Create("change", GetValidTouchEventInit()));
EXPECT_FALSE(Video()->paused());
}
@@ -196,9 +196,9 @@ TEST_F(MediaControlTimelineElementTest, TouchMoveDoesNotResume) {
ASSERT_FALSE(Video()->paused());
Timeline()->DispatchEvent(
- TouchEvent::Create("touchstart", GetValidTouchEventInit()));
+ *TouchEvent::Create("touchstart", GetValidTouchEventInit()));
Timeline()->DispatchEvent(
- TouchEvent::Create("touchmove", GetValidTouchEventInit()));
+ *TouchEvent::Create("touchmove", GetValidTouchEventInit()));
EXPECT_TRUE(Video()->paused());
}
@@ -207,9 +207,9 @@ TEST_F(MediaControlTimelineElementTest, TouchMoveAfterPointerDoesNotResume) {
ASSERT_FALSE(Video()->paused());
Timeline()->DispatchEvent(
- PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
+ *PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
Timeline()->DispatchEvent(
- TouchEvent::Create("touchmove", GetValidTouchEventInit()));
+ *TouchEvent::Create("touchmove", GetValidTouchEventInit()));
EXPECT_TRUE(Video()->paused());
}
@@ -218,9 +218,9 @@ TEST_F(MediaControlTimelineElementTest, TouchEndAfterPointerDoesNotResume) {
ASSERT_FALSE(Video()->paused());
Timeline()->DispatchEvent(
- PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
+ *PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
Timeline()->DispatchEvent(
- TouchEvent::Create("touchend", GetValidTouchEventInit()));
+ *TouchEvent::Create("touchend", GetValidTouchEventInit()));
EXPECT_TRUE(Video()->paused());
}
@@ -229,9 +229,9 @@ TEST_F(MediaControlTimelineElementTest, TouchCancelAfterPointerDoesNotResume) {
ASSERT_FALSE(Video()->paused());
Timeline()->DispatchEvent(
- PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
+ *PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
Timeline()->DispatchEvent(
- TouchEvent::Create("touchcancel", GetValidTouchEventInit()));
+ *TouchEvent::Create("touchcancel", GetValidTouchEventInit()));
EXPECT_TRUE(Video()->paused());
}
@@ -240,9 +240,9 @@ TEST_F(MediaControlTimelineElementTest, ChangeAfterPointerDoesNotResume) {
ASSERT_FALSE(Video()->paused());
Timeline()->DispatchEvent(
- PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
+ *PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
Timeline()->DispatchEvent(
- TouchEvent::Create("change", GetValidTouchEventInit()));
+ *TouchEvent::Create("change", GetValidTouchEventInit()));
EXPECT_TRUE(Video()->paused());
}
@@ -251,9 +251,9 @@ TEST_F(MediaControlTimelineElementTest, PointerUpAfterTouchDoesNotResume) {
ASSERT_FALSE(Video()->paused());
Timeline()->DispatchEvent(
- TouchEvent::Create("touchstart", GetValidTouchEventInit()));
+ *TouchEvent::Create("touchstart", GetValidTouchEventInit()));
Timeline()->DispatchEvent(
- PointerEvent::Create("pointerup", GetValidPointerEventInit()));
+ *PointerEvent::Create("pointerup", GetValidPointerEventInit()));
EXPECT_TRUE(Video()->paused());
}
@@ -262,9 +262,9 @@ TEST_F(MediaControlTimelineElementTest, PointerCancelAfterTouchDoesNotResume) {
ASSERT_FALSE(Video()->paused());
Timeline()->DispatchEvent(
- TouchEvent::Create("touchstart", GetValidTouchEventInit()));
+ *TouchEvent::Create("touchstart", GetValidTouchEventInit()));
Timeline()->DispatchEvent(
- PointerEvent::Create("pointercancel", GetValidPointerEventInit()));
+ *PointerEvent::Create("pointercancel", GetValidPointerEventInit()));
EXPECT_TRUE(Video()->paused());
}
@@ -273,11 +273,11 @@ TEST_F(MediaControlTimelineElementTest, UpgradePointerEventToTouchAllowed) {
ASSERT_FALSE(Video()->paused());
Timeline()->DispatchEvent(
- PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
+ *PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
Timeline()->DispatchEvent(
- TouchEvent::Create("touchstart", GetValidTouchEventInit()));
+ *TouchEvent::Create("touchstart", GetValidTouchEventInit()));
Timeline()->DispatchEvent(
- TouchEvent::Create("touchend", GetValidTouchEventInit()));
+ *TouchEvent::Create("touchend", GetValidTouchEventInit()));
EXPECT_FALSE(Video()->paused());
}
@@ -286,11 +286,11 @@ TEST_F(MediaControlTimelineElementTest, UpgradeTouchEventToPointerDenied) {
ASSERT_FALSE(Video()->paused());
Timeline()->DispatchEvent(
- TouchEvent::Create("touchstart", GetValidTouchEventInit()));
+ *TouchEvent::Create("touchstart", GetValidTouchEventInit()));
Timeline()->DispatchEvent(
- PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
+ *PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
Timeline()->DispatchEvent(
- PointerEvent::Create("pointerup", GetValidPointerEventInit()));
+ *PointerEvent::Create("pointerup", GetValidPointerEventInit()));
EXPECT_TRUE(Video()->paused());
}
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_toggle_closed_captions_button_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_toggle_closed_captions_button_element.cc
index a58b550a85c..fae04b5917a 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_toggle_closed_captions_button_element.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_toggle_closed_captions_button_element.cc
@@ -103,8 +103,8 @@ MediaControlToggleClosedCaptionsButtonElement::GetNameForHistograms() const {
}
void MediaControlToggleClosedCaptionsButtonElement::DefaultEventHandler(
- Event* event) {
- if (event->type() == EventTypeNames::click) {
+ Event& event) {
+ if (event.type() == EventTypeNames::click) {
if (MediaElement().textTracks()->length() == 1) {
// If only one track exists, toggle it on/off
if (MediaElement().textTracks()->HasShowingTracks())
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_toggle_closed_captions_button_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_toggle_closed_captions_button_element.h
index 1d1b48de01e..470b3c2724d 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_toggle_closed_captions_button_element.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_toggle_closed_captions_button_element.h
@@ -29,7 +29,7 @@ class MODULES_EXPORT MediaControlToggleClosedCaptionsButtonElement final
const char* GetNameForHistograms() const override;
private:
- void DefaultEventHandler(Event*) override;
+ void DefaultEventHandler(Event&) override;
};
} // 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 8c4b29a5347..afc97376393 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
@@ -48,28 +48,28 @@ const char* MediaControlVolumeSliderElement::GetNameForHistograms() const {
return "VolumeSlider";
}
-void MediaControlVolumeSliderElement::DefaultEventHandler(Event* event) {
+void MediaControlVolumeSliderElement::DefaultEventHandler(Event& event) {
if (!isConnected() || !GetDocument().IsActive())
return;
MediaControlInputElement::DefaultEventHandler(event);
- if (event->IsMouseEvent() || event->IsKeyboardEvent() ||
- event->IsGestureEvent() || event->IsPointerEvent()) {
+ if (event.IsMouseEvent() || event.IsKeyboardEvent() ||
+ event.IsGestureEvent() || event.IsPointerEvent()) {
MaybeRecordInteracted();
}
- if (event->type() == EventTypeNames::pointerdown) {
+ if (event.type() == EventTypeNames::pointerdown) {
Platform::Current()->RecordAction(
UserMetricsAction("Media.Controls.VolumeChangeBegin"));
}
- if (event->type() == EventTypeNames::pointerup) {
+ if (event.type() == EventTypeNames::pointerup) {
Platform::Current()->RecordAction(
UserMetricsAction("Media.Controls.VolumeChangeEnd"));
}
- if (event->type() == EventTypeNames::input) {
+ if (event.type() == EventTypeNames::input) {
double volume = value().ToDouble();
MediaElement().setVolume(volume);
MediaElement().setMuted(false);
@@ -82,7 +82,8 @@ void MediaControlVolumeSliderElement::SetVolumeInternal(double volume) {
SetAfterSegmentPosition(MediaControlSliderElement::Position(0, volume));
}
-bool MediaControlVolumeSliderElement::KeepEventInNode(Event* event) {
+bool MediaControlVolumeSliderElement::KeepEventInNode(
+ const Event& event) const {
return MediaControlElementsHelper::IsUserInteractionEventForSlider(
event, GetLayoutObject());
}
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_volume_slider_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_volume_slider_element.h
index afaa5ff338b..2e9962f5c25 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_volume_slider_element.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_volume_slider_element.h
@@ -23,14 +23,14 @@ class MediaControlVolumeSliderElement final : public MediaControlSliderElement {
bool WillRespondToMouseMoveEvents() override;
bool WillRespondToMouseClickEvents() override;
- void OnMediaKeyboardEvent(Event* event) { DefaultEventHandler(event); }
+ void OnMediaKeyboardEvent(Event* event) { DefaultEventHandler(*event); }
protected:
const char* GetNameForHistograms() const override;
private:
- void DefaultEventHandler(Event*) override;
- bool KeepEventInNode(Event*) override;
+ void DefaultEventHandler(Event&) override;
+ bool KeepEventInNode(const Event&) const override;
void SetVolumeInternal(double);
};
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 22e5a529922..bd53ac69e41 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
@@ -119,7 +119,8 @@ class MediaControlsDisplayCutoutDelegateTest : public PageTestBase {
}
void SimulateEvent(TouchEvent* event) {
- GetVideoElement().FireEventListeners(event);
+ DCHECK(event);
+ GetVideoElement().FireEventListeners(*event);
}
TouchList* CreateTouchListWithOnePoint(int x, int y) {
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 5ca3a5f8314..fa2415ecb14 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
@@ -54,6 +54,7 @@
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_button_panel_element.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_cast_button_element.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_current_time_display_element.h"
+#include "third_party/blink/renderer/modules/media_controls/elements/media_control_display_cutout_fullscreen_button_element.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_download_button_element.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_elements_helper.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_fullscreen_button_element.h"
@@ -369,6 +370,7 @@ MediaControlsImpl::MediaControlsImpl(HTMLMediaElement& media_element)
picture_in_picture_button_(nullptr),
cast_button_(nullptr),
fullscreen_button_(nullptr),
+ display_cutout_fullscreen_button_(nullptr),
download_button_(nullptr),
media_event_listener_(new MediaControlsMediaEventListener(this)),
orientation_lock_delegate_(nullptr),
@@ -513,6 +515,8 @@ MediaControlsImpl* MediaControlsImpl::Create(HTMLMediaElement& media_element,
// | (-internal-media-controls-text-track-list-kind-captions)
// +-MediaControlTextTrackListItemSubtitles
// (-internal-media-controls-text-track-list-kind-subtitles)
+// +-MediaControlDisplayCutoutFullscreenElement
+// (-internal-media-controls-display-cutout-fullscreen-button)
void MediaControlsImpl::InitializeControls() {
if (IsModern() && ShouldShowVideoControls()) {
loading_panel_ = new MediaControlLoadingPanelElement(*this);
@@ -573,6 +577,12 @@ void MediaControlsImpl::InitializeControls() {
ShouldShowPictureInPictureButton(MediaElement()));
}
+ if (RuntimeEnabledFeatures::DisplayCutoutAPIEnabled() &&
+ MediaElement().IsHTMLVideoElement()) {
+ display_cutout_fullscreen_button_ =
+ new MediaControlDisplayCutoutFullscreenButtonElement(*this);
+ }
+
fullscreen_button_ = new MediaControlFullscreenButtonElement(*this);
download_button_ = new MediaControlDownloadButtonElement(*this);
cast_button_ = new MediaControlCastButtonElement(*this, false);
@@ -627,6 +637,9 @@ void MediaControlsImpl::PopulatePanel() {
Element* button_panel = panel_;
if (IsModern() && ShouldShowVideoControls()) {
MaybeParserAppendChild(panel_, scrubbing_message_);
+ if (display_cutout_fullscreen_button_)
+ panel_->ParserAppendChild(display_cutout_fullscreen_button_);
+
panel_->ParserAppendChild(overlay_play_button_);
panel_->ParserAppendChild(media_button_panel_);
button_panel = media_button_panel_;
@@ -662,7 +675,7 @@ void MediaControlsImpl::PopulatePanel() {
}
Node::InsertionNotificationRequest MediaControlsImpl::InsertedInto(
- ContainerNode* root) {
+ ContainerNode& root) {
if (!MediaElement().isConnected())
return HTMLDivElement::InsertedInto(root);
@@ -795,9 +808,11 @@ MediaControlsImpl::ControlsState MediaControlsImpl::State() const {
return ControlsState::kStopped;
}
-void MediaControlsImpl::RemovedFrom(ContainerNode*) {
+void MediaControlsImpl::RemovedFrom(ContainerNode& insertion_point) {
DCHECK(!MediaElement().isConnected());
+ HTMLDivElement::RemovedFrom(insertion_point);
+
// TODO(mlamouri): we hide show the controls instead of having
// HTMLMediaElement do it.
@@ -1411,7 +1426,7 @@ void MediaControlsImpl::OnAccessibleFocus() {
MaybeShow();
}
-void MediaControlsImpl::DefaultEventHandler(Event* event) {
+void MediaControlsImpl::DefaultEventHandler(Event& event) {
HTMLDivElement::DefaultEventHandler(event);
// Do not handle events to not interfere with the rest of the page if no
@@ -1423,7 +1438,7 @@ void MediaControlsImpl::DefaultEventHandler(Event* event) {
// event, to allow the hide-timer to do the right thing when it fires.
// FIXME: Preferably we would only do this when we're actually handling the
// event here ourselves.
- bool is_touch_event = IsTouchEvent(event);
+ bool is_touch_event = IsTouchEvent(&event);
hide_timer_behavior_flags_ |=
is_touch_event ? kIgnoreControlsHover : kIgnoreNone;
@@ -1431,46 +1446,46 @@ void MediaControlsImpl::DefaultEventHandler(Event* event) {
// random behavior. The expect behaviour for touch is that a tap will show the
// controls and they will hide when the timer to hide fires.
if (is_touch_event)
- HandleTouchEvent(event);
+ HandleTouchEvent(&event);
- if (event->type() == EventTypeNames::mouseover && !is_touch_event)
+ if (event.type() == EventTypeNames::mouseover && !is_touch_event)
is_touch_interaction_ = false;
- if ((event->type() == EventTypeNames::pointerover ||
- event->type() == EventTypeNames::pointermove ||
- event->type() == EventTypeNames::pointerout) &&
+ if ((event.type() == EventTypeNames::pointerover ||
+ event.type() == EventTypeNames::pointermove ||
+ event.type() == EventTypeNames::pointerout) &&
!is_touch_interaction_) {
- HandlePointerEvent(event);
+ HandlePointerEvent(&event);
}
// If the user is interacting with the controls via the keyboard, don't hide
// the controls. This will fire when the user tabs between controls (focusin)
// or when they seek either the timeline or volume sliders (input).
- if (event->type() == EventTypeNames::focusin ||
- event->type() == EventTypeNames::input) {
+ if (event.type() == EventTypeNames::focusin ||
+ event.type() == EventTypeNames::input) {
ResetHideMediaControlsTimer();
}
- if (event->IsKeyboardEvent() &&
+ if (event.IsKeyboardEvent() &&
!IsSpatialNavigationEnabled(GetDocument().GetFrame())) {
- const String& key = ToKeyboardEvent(event)->key();
- if (key == "Enter" || ToKeyboardEvent(event)->keyCode() == ' ') {
+ const String& key = ToKeyboardEvent(event).key();
+ if (key == "Enter" || ToKeyboardEvent(event).keyCode() == ' ') {
if (IsModern()) {
- overlay_play_button_->OnMediaKeyboardEvent(event);
+ overlay_play_button_->OnMediaKeyboardEvent(&event);
} else {
- play_button_->OnMediaKeyboardEvent(event);
+ play_button_->OnMediaKeyboardEvent(&event);
}
return;
}
if (key == "ArrowLeft" || key == "ArrowRight" || key == "Home" ||
key == "End") {
- timeline_->OnMediaKeyboardEvent(event);
+ timeline_->OnMediaKeyboardEvent(&event);
return;
}
// We don't allow the user to change the volume on modern media controls.
if (!IsModern() && (key == "ArrowDown" || key == "ArrowUp")) {
for (int i = 0; i < 5; i++)
- volume_slider_->OnMediaKeyboardEvent(event);
+ volume_slider_->OnMediaKeyboardEvent(&event);
return;
}
}
@@ -1705,12 +1720,18 @@ void MediaControlsImpl::OnLoadedMetadata() {
void MediaControlsImpl::OnEnteredFullscreen() {
fullscreen_button_->SetIsFullscreen(true);
+ if (display_cutout_fullscreen_button_)
+ display_cutout_fullscreen_button_->SetIsWanted(true);
+
StopHideMediaControlsTimer();
StartHideMediaControlsTimer();
}
void MediaControlsImpl::OnExitedFullscreen() {
fullscreen_button_->SetIsFullscreen(false);
+ if (display_cutout_fullscreen_button_)
+ display_cutout_fullscreen_button_->SetIsWanted(false);
+
StopHideMediaControlsTimer();
StartHideMediaControlsTimer();
}
@@ -2065,6 +2086,7 @@ void MediaControlsImpl::Trace(blink::Visitor* visitor) {
visitor->Trace(download_iph_manager_);
visitor->Trace(media_button_panel_);
visitor->Trace(loading_panel_);
+ visitor->Trace(display_cutout_fullscreen_button_);
MediaControls::Trace(visitor);
HTMLDivElement::Trace(visitor);
}
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 28ef1e8e192..e87c133017e 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
@@ -49,6 +49,7 @@ class MediaControlDownloadButtonElement;
class MediaControlFullscreenButtonElement;
class MediaControlLoadingPanelElement;
class MediaControlMuteButtonElement;
+class MediaControlDisplayCutoutFullscreenButtonElement;
class MediaControlOverflowMenuButtonElement;
class MediaControlOverflowMenuListElement;
class MediaControlOverlayEnclosureElement;
@@ -85,8 +86,8 @@ class MODULES_EXPORT MediaControlsImpl final : public HTMLDivElement,
static bool IsTouchEvent(Event*);
// Node override.
- Node::InsertionNotificationRequest InsertedInto(ContainerNode*) override;
- void RemovedFrom(ContainerNode*) override;
+ Node::InsertionNotificationRequest InsertedInto(ContainerNode&) override;
+ void RemovedFrom(ContainerNode&) override;
// MediaControls implementation.
void MaybeShow() override;
@@ -207,6 +208,7 @@ class MODULES_EXPORT MediaControlsImpl final : public HTMLDivElement,
friend class MediaControlsRotateToFullscreenDelegateTest;
friend class MediaControlsImplTest;
friend class MediaControlsImplInProductHelpTest;
+ friend class MediaControlDisplayCutoutFullscreenButtonElementTest;
friend class MediaControlTimelineElementTest;
// Need to be members of MediaControls for private member access.
@@ -292,7 +294,7 @@ class MODULES_EXPORT MediaControlsImpl final : public HTMLDivElement,
// Node
bool IsMediaControls() const override { return true; }
bool WillRespondToMouseMoveEvents() override { return true; }
- void DefaultEventHandler(Event*) override;
+ void DefaultEventHandler(Event&) override;
bool ContainsRelatedTarget(Event*);
void HandlePointerEvent(Event*);
@@ -319,7 +321,7 @@ class MODULES_EXPORT MediaControlsImpl final : public HTMLDivElement,
void OnExitedFullscreen();
void OnPictureInPictureChanged();
void OnPanelKeypress();
- void OnMediaKeyboardEvent(Event* event) { DefaultEventHandler(event); }
+ void OnMediaKeyboardEvent(Event* event) { DefaultEventHandler(*event); }
void OnWaiting();
void OnLoadingProgress();
void OnLoadedData();
@@ -348,6 +350,8 @@ class MODULES_EXPORT MediaControlsImpl final : public HTMLDivElement,
Member<MediaControlCastButtonElement> cast_button_;
Member<MediaControlFullscreenButtonElement> fullscreen_button_;
+ Member<MediaControlDisplayCutoutFullscreenButtonElement>
+ display_cutout_fullscreen_button_;
Member<MediaControlDownloadButtonElement> download_button_;
Member<MediaControlsMediaEventListener> media_event_listener_;
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 4bd7baed6c9..a772b25a7f5 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
@@ -43,7 +43,6 @@
#include "third_party/blink/renderer/platform/testing/empty_web_media_player.h"
#include "third_party/blink/renderer/platform/testing/histogram_tester.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.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"
// The MediaTimelineWidths histogram suffix expected to be encountered in these
@@ -159,7 +158,7 @@ bool IsElementVisible(Element& element) {
}
void SimulateTransitionEnd(Element& element) {
- element.DispatchEvent(Event::Create(EventTypeNames::transitionend));
+ element.DispatchEvent(*Event::Create(EventTypeNames::transitionend));
}
// This must match MediaControlDownloadButtonElement::DownloadActionMetrics.
@@ -997,10 +996,13 @@ TEST_F(MediaControlsImplTest, TimeIsCorrectlyFormatted) {
namespace {
class MediaControlsImplTestWithMockScheduler : public MediaControlsImplTest {
+ public:
+ MediaControlsImplTestWithMockScheduler() { EnablePlatform(); }
+
protected:
void SetUp() override {
// DocumentParserTiming has DCHECKS to make sure time > 0.0.
- platform_->AdvanceClockSeconds(1);
+ platform()->AdvanceClockSeconds(1);
MediaControlsImplTest::SetUp();
}
@@ -1011,9 +1013,6 @@ class MediaControlsImplTestWithMockScheduler : public MediaControlsImplTest {
return false;
return style->GetPropertyValue(CSSPropertyCursor) == "none";
}
-
- ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
- platform_;
};
} // namespace
@@ -1031,23 +1030,23 @@ TEST_F(MediaControlsImplTestWithMockScheduler,
EXPECT_TRUE(IsElementVisible(*panel));
// Tabbing between controls prevents controls from hiding.
- platform_->RunForPeriodSeconds(2);
- MediaControls().DispatchEvent(Event::Create("focusin"));
- platform_->RunForPeriodSeconds(2);
+ platform()->RunForPeriodSeconds(2);
+ MediaControls().DispatchEvent(*Event::Create("focusin"));
+ platform()->RunForPeriodSeconds(2);
EXPECT_TRUE(IsElementVisible(*panel));
// Seeking on the timeline or volume bar prevents controls from hiding.
- MediaControls().DispatchEvent(Event::Create("input"));
- platform_->RunForPeriodSeconds(2);
+ MediaControls().DispatchEvent(*Event::Create("input"));
+ platform()->RunForPeriodSeconds(2);
EXPECT_TRUE(IsElementVisible(*panel));
// Pressing a key prevents controls from hiding.
- MediaControls().PanelElement()->DispatchEvent(Event::Create("keypress"));
- platform_->RunForPeriodSeconds(2);
+ MediaControls().PanelElement()->DispatchEvent(*Event::Create("keypress"));
+ platform()->RunForPeriodSeconds(2);
EXPECT_TRUE(IsElementVisible(*panel));
// Once user interaction stops, controls can hide.
- platform_->RunForPeriodSeconds(2);
+ platform()->RunForPeriodSeconds(2);
SimulateTransitionEnd(*panel);
EXPECT_FALSE(IsElementVisible(*panel));
}
@@ -1063,20 +1062,20 @@ TEST_F(MediaControlsImplTestWithMockScheduler, CursorHidesWhenControlsHide) {
MediaControls().MediaElement().Play();
// Tabbing into the controls shows the controls and therefore the cursor.
- MediaControls().DispatchEvent(Event::Create("focusin"));
+ MediaControls().DispatchEvent(*Event::Create("focusin"));
EXPECT_FALSE(IsCursorHidden());
// Once the controls hide, the cursor is hidden.
- platform_->RunForPeriodSeconds(4);
+ platform()->RunForPeriodSeconds(4);
EXPECT_TRUE(IsCursorHidden());
// If the mouse moves, the controls are shown and the cursor is no longer
// hidden.
- MediaControls().DispatchEvent(Event::Create("pointermove"));
+ MediaControls().DispatchEvent(*Event::Create("pointermove"));
EXPECT_FALSE(IsCursorHidden());
// Once the controls hide again, the cursor is hidden again.
- platform_->RunForPeriodSeconds(4);
+ platform()->RunForPeriodSeconds(4);
EXPECT_TRUE(IsCursorHidden());
}
@@ -1088,18 +1087,18 @@ TEST_F(MediaControlsImplTestWithMockScheduler, AccessibleFocusShowsControls) {
MediaControls().MediaElement().SetSrc("http://example.com");
MediaControls().MediaElement().Play();
- platform_->RunForPeriodSeconds(2);
+ platform()->RunForPeriodSeconds(2);
EXPECT_TRUE(IsElementVisible(*panel));
MediaControls().OnAccessibleFocus();
- platform_->RunForPeriodSeconds(2);
+ platform()->RunForPeriodSeconds(2);
EXPECT_TRUE(IsElementVisible(*panel));
- platform_->RunForPeriodSeconds(2);
+ platform()->RunForPeriodSeconds(2);
EXPECT_FALSE(IsElementVisible(*panel));
MediaControls().OnAccessibleFocus();
- platform_->RunForPeriodSeconds(2);
+ platform()->RunForPeriodSeconds(2);
EXPECT_TRUE(IsElementVisible(*panel));
}
@@ -1112,11 +1111,11 @@ TEST_F(MediaControlsImplTestWithMockScheduler,
MediaControls().MediaElement().SetSrc("http://example.com");
MediaControls().MediaElement().Play();
- platform_->RunForPeriodSeconds(2);
+ platform()->RunForPeriodSeconds(2);
EXPECT_TRUE(IsElementVisible(*panel));
MediaControls().OnAccessibleFocus();
- platform_->RunForPeriodSeconds(4);
+ platform()->RunForPeriodSeconds(4);
EXPECT_FALSE(IsElementVisible(*panel));
// Display is none but can't be checked via InlineStyle. Adding checks of this
@@ -1329,7 +1328,7 @@ TEST_F(MediaControlsImplTest, CastOverlayShowsOnSomeEvents) {
for (auto* const event_name :
{"gesturetap", "click", "pointerover", "pointermove"}) {
- overlay_enclosure->DispatchEvent(Event::Create(event_name));
+ overlay_enclosure->DispatchEvent(*Event::Create(event_name));
EXPECT_TRUE(IsElementVisible(*cast_overlay_button));
SimulateHideMediaControlsTimerFired();
@@ -1337,6 +1336,12 @@ TEST_F(MediaControlsImplTest, CastOverlayShowsOnSomeEvents) {
}
}
+TEST_F(MediaControlsImplTest, isConnected) {
+ EXPECT_TRUE(MediaControls().isConnected());
+ MediaControls().MediaElement().remove();
+ EXPECT_FALSE(MediaControls().isConnected());
+}
+
class ModernMediaControlsImplTest : public MediaControlsImplTest {
public:
void SetUp() override {
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 c01ec30bd36..ee2a82dbb4c 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
@@ -150,7 +150,7 @@ class MediaControlsRotateToFullscreenDelegateTest
}
void DispatchEvent(EventTarget& target, const AtomicString& type) {
- target.DispatchEvent(Event::Create(type));
+ target.DispatchEvent(*Event::Create(type));
}
void InitScreenAndVideo(WebScreenOrientationType initial_screen_orientation,
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/resources/ic_display_cutout_fullscreen.svg b/chromium/third_party/blink/renderer/modules/media_controls/resources/ic_display_cutout_fullscreen.svg
new file mode 100644
index 00000000000..e5d2096c99e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/media_controls/resources/ic_display_cutout_fullscreen.svg
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="15px" height="15px" viewBox="0 0 15 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="square" stroke-linejoin="round">
+ <g transform="translate(-622.000000, -2.000000)" fill-rule="nonzero" stroke="#FFFFFF" stroke-width="2">
+ <g transform="translate(624.000000, 4.000000)">
+ <path d="M0,0 L11.3137085,11.3137085" />
+ <path d="M7,1.77635684e-15 L11.2426407,4.24264069" />
+ </g>
+ </g>
+ </g>
+</svg>
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls.css b/chromium/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls.css
index c02f8468adb..ba69e49f0e7 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls.css
+++ b/chromium/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls.css
@@ -186,6 +186,7 @@ video::-webkit-media-controls-mute-button,
video::-internal-media-controls-cast-icon,
video::-webkit-media-controls-fullscreen-button,
audio::-webkit-media-controls-fullscreen-button,
+video::-internal-media-controls-display-cutout-fullscreen-button,
video::-internal-media-controls-cast-button,
audio::-internal-media-controls-cast-button,
video::-internal-media-controls-overflow-button,
@@ -210,6 +211,7 @@ video::-internal-media-controls-picture-in-picture-button {
video::-webkit-media-controls.sizing-small input[pseudo="-webkit-media-controls-play-button" i],
video::-webkit-media-controls.sizing-small input[pseudo="-webkit-media-controls-mute-button" i],
video::-webkit-media-controls.sizing-small input[pseudo="-webkit-media-controls-fullscreen-button" i],
+video::-webkit-media-controls.sizing-small input[pseudo="-internal-media-controls-display-cutout-fullscreen-button" i],
video::-webkit-media-controls.sizing-small input[pseudo="-internal-media-controls-overflow-button" i] {
width: 48px;
height: 48px;
@@ -219,6 +221,7 @@ video::-webkit-media-controls.sizing-small input[pseudo="-internal-media-control
video::-webkit-media-controls.sizing-medium input[pseudo="-webkit-media-controls-play-button" i],
video::-webkit-media-controls.sizing-medium input[pseudo="-webkit-media-controls-mute-button" i],
video::-webkit-media-controls.sizing-medium input[pseudo="-webkit-media-controls-fullscreen-button" i],
+video::-webkit-media-controls.sizing-medium input[pseudo="-internal-media-controls-display-cutout-fullscreen-button" i],
video::-webkit-media-controls.sizing-medium input[pseudo="-internal-media-controls-overflow-button" i] {
width: 64px;
height: 64px;
@@ -230,6 +233,7 @@ video::-webkit-media-controls.sizing-medium input[pseudo="-internal-media-contro
video::-webkit-media-controls.sizing-large input[pseudo="-webkit-media-controls-play-button" i],
video::-webkit-media-controls.sizing-large input[pseudo="-webkit-media-controls-mute-button" i],
video::-webkit-media-controls.sizing-large input[pseudo="-webkit-media-controls-fullscreen-button" i],
+video::-webkit-media-controls.sizing-large input[pseudo="-internal-media-controls-display-cutout-fullscreen-button" i],
video::-webkit-media-controls.sizing-large input[pseudo="-internal-media-controls-overflow-button" i] {
width: 64px;
height: 64px;
@@ -296,6 +300,14 @@ video::-webkit-media-controls:not(.audio-only) [pseudo="-webkit-media-controls-p
background-image: -webkit-image-set(url(ic_volume_off_white.svg) 1x);
}
+video::-internal-media-controls-display-cutout-fullscreen-button {
+ background-image: -webkit-image-set(url(ic_display_cutout_fullscreen.svg) 1x);
+ position: absolute;
+ top: 4px;
+ right: 4px;
+ z-index: 1;
+}
+
audio::-webkit-media-controls-fullscreen-button,
video::-webkit-media-controls-fullscreen-button {
background-image: -webkit-image-set(url(ic_fullscreen.svg) 1x);
@@ -316,6 +328,7 @@ audio::-webkit-media-controls-mute-button:disabled,
video::-internal-media-controls-overflow-button:disabled,
video::-webkit-media-controls-mute-button:disabled,
video::-webkit-media-controls-fullscreen-button:disabled {
+ background-color: initial;
opacity: 0.3;
}
@@ -382,6 +395,15 @@ video::-webkit-media-controls-overlay-play-button {
transition: opacity 0.25s cubic-bezier(0.25, 0.1, 0.25, 1);
}
+/**
+ * The overlay-play-button is disabled if the video element is loaded via
+ * MHTML, and a ruleset for input[type=button]:disabled in themeWin.css has
+ * higher priority than the above ruleset.
+ */
+video::-webkit-media-controls-overlay-play-button:disabled {
+ background: transparent;
+}
+
video::-webkit-media-controls-overlay-play-button.hidden {
opacity: 0;
transition: opacity 0.75s cubic-bezier(0.25, 0.1, 0.25, 1);
@@ -547,6 +569,20 @@ video::-webkit-media-controls.sizing-large div[pseudo="-internal-media-controls-
/ -2);
}
+div[pseudo="-internal-media-controls-loading-panel" i]::-internal-media-controls-loading-panel-spinner-mask-1-background {
+ left: 0;
+ background-image: -webkit-image-set(
+ url(default_100_percent/modern/loading_mask_1.svg) 1x);
+ background-position: center left;
+}
+
+div[pseudo="-internal-media-controls-loading-panel" i]::-internal-media-controls-loading-panel-spinner-mask-2-background {
+ left: -100%;
+ background-image: -webkit-image-set(
+ url(default_100_percent/modern/loading_mask_2.svg) 1x);
+ background-position: center right;
+}
+
input[pseudo="-webkit-media-controls-timeline" i]::-internal-media-controls-segmented-track {
-webkit-appearance: -internal-media-control;
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls_loading.css b/chromium/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls_loading.css
index 0e50b93f03d..932651f1f63 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls_loading.css
+++ b/chromium/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls_loading.css
@@ -64,8 +64,8 @@
right: -50%;
}
-#spinner-mask-1-background,
-#spinner-mask-2-background {
+div[pseudo="-internal-media-controls-loading-panel-spinner-mask-1-background"],
+div[pseudo="-internal-media-controls-loading-panel-spinner-mask-2-background"] {
position: absolute;
background-repeat: no-repeat;
width: 200%;
@@ -77,19 +77,11 @@
animation-fill-mode: forwards;
}
-#spinner-mask-1-background {
- left: 0;
- background-image: -webkit-image-set(
- url(default_100_percent/modern/loading_mask_1.svg) 1x);
- background-position: center left;
+div[pseudo="-internal-media-controls-loading-panel-spinner-mask-1-background"] {
animation-name: mask-1-spin;
}
-#spinner-mask-2-background {
- left: -100%;
- background-image: -webkit-image-set(
- url(default_100_percent/modern/loading_mask_2.svg) 1x);
- background-position: center right;
+div[pseudo="-internal-media-controls-loading-panel-spinner-mask-2-background"] {
animation-name: mask-2-spin;
}
diff --git a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_media_element_capture.idl b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_media_element_capture.idl
index 8b8f92dfdaf..f8e28bb90fa 100644
--- a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_media_element_capture.idl
+++ b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_media_element_capture.idl
@@ -5,9 +5,7 @@
// https://w3c.github.io/mediacapture-fromelement/#html-media-element-media-capture-extensions
[
- ImplementedAs=HTMLMediaElementCapture,
- RuntimeEnabled=MediaCaptureFromVideo
+ ImplementedAs=HTMLMediaElementCapture
] partial interface HTMLMediaElement {
[RaisesException, CallWith=ScriptState] MediaStream captureStream();
- // TODO(mcasas): Implement captureStreamUntilEnded() http://crbug.com/575495.
};
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 06ae24723c4..7aaa74951db 100644
--- a/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder.cc
+++ b/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder.cc
@@ -397,7 +397,7 @@ void MediaRecorder::DispatchScheduledEvent() {
events.swap(scheduled_events_);
for (const auto& event : events)
- DispatchEvent(event);
+ DispatchEvent(*event);
}
void MediaRecorder::Trace(blink::Visitor* visitor) {
diff --git a/chromium/third_party/blink/renderer/modules/mediasource/media_source.cc b/chromium/third_party/blink/renderer/modules/mediasource/media_source.cc
index 4852e555429..1fba87ab4b0 100644
--- a/chromium/third_party/blink/renderer/modules/mediasource/media_source.cc
+++ b/chromium/third_party/blink/renderer/modules/mediasource/media_source.cc
@@ -851,7 +851,7 @@ void MediaSource::ScheduleEvent(const AtomicString& event_name) {
Event* event = Event::Create(event_name);
event->SetTarget(this);
- async_event_queue_->EnqueueEvent(FROM_HERE, event);
+ async_event_queue_->EnqueueEvent(FROM_HERE, *event);
}
URLRegistry& MediaSource::Registry() const {
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 6aaa0b9bcb4..8007d2c1f32 100644
--- a/chromium/third_party/blink/renderer/modules/mediasource/source_buffer.cc
+++ b/chromium/third_party/blink/renderer/modules/mediasource/source_buffer.cc
@@ -1188,7 +1188,7 @@ void SourceBuffer::ScheduleEvent(const AtomicString& event_name) {
Event* event = Event::Create(event_name);
event->SetTarget(this);
- async_event_queue_->EnqueueEvent(FROM_HERE, event);
+ async_event_queue_->EnqueueEvent(FROM_HERE, *event);
}
bool SourceBuffer::PrepareAppend(double media_time,
diff --git a/chromium/third_party/blink/renderer/modules/mediasource/source_buffer.idl b/chromium/third_party/blink/renderer/modules/mediasource/source_buffer.idl
index 5c56ebfc9b4..6ba59576401 100644
--- a/chromium/third_party/blink/renderer/modules/mediasource/source_buffer.idl
+++ b/chromium/third_party/blink/renderer/modules/mediasource/source_buffer.idl
@@ -74,7 +74,7 @@ enum AppendMode {
[RaisesException] void remove(double start, unrestricted double end);
// Explicitly change the container or codecs
- [RaisesException, RuntimeEnabled=MediaSourceExperimental] void changeType(DOMString type);
+ [RaisesException, Measure] void changeType(DOMString type);
// Gets or sets the TrackDefaultList this SourceBuffer may consult during
// the initialization segment algorithm.
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 7c86cfe167c..44ceda95a19 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
@@ -71,7 +71,7 @@ void SourceBufferList::ScheduleEvent(const AtomicString& event_name) {
Event* event = Event::Create(event_name);
event->SetTarget(this);
- async_event_queue_->EnqueueEvent(FROM_HERE, event);
+ async_event_queue_->EnqueueEvent(FROM_HERE, *event);
}
const AtomicString& SourceBufferList::InterfaceName() const {
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/BUILD.gn b/chromium/third_party/blink/renderer/modules/mediastream/BUILD.gn
index eac66d37de2..0503186677f 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/mediastream/BUILD.gn
@@ -30,6 +30,8 @@ blink_modules_sources("mediastream") {
"media_stream_track_content_hint.h",
"media_stream_track_event.cc",
"media_stream_track_event.h",
+ "navigator_display_media.cc",
+ "navigator_display_media.h",
"navigator_media_stream.cc",
"navigator_media_stream.h",
"navigator_user_media.cc",
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 dc8304c11cf..068058a8acb 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
@@ -231,12 +231,12 @@ static bool Parse(const Dictionary& constraints_dictionary,
if (!ok || optional_constraints.IsUndefinedOrNull())
return false;
- size_t number_of_constraints;
+ uint32_t number_of_constraints;
ok = optional_constraints.length(number_of_constraints);
if (!ok)
return false;
- for (size_t i = 0; i < number_of_constraints; ++i) {
+ for (uint32_t i = 0; i < number_of_constraints; ++i) {
Dictionary constraint;
ok = optional_constraints.Get(i, constraint);
if (!ok || constraint.IsUndefinedOrNull())
@@ -827,7 +827,7 @@ LongOrConstrainLongRange ConvertLong(const LongConstraint& input,
NakedValueDisposition naked_treatment) {
LongOrConstrainLongRange output_union;
if (UseNakedNumeric(input, naked_treatment)) {
- output_union.SetLong(GetNakedValue<long>(input, naked_treatment));
+ output_union.SetLong(GetNakedValue<uint32_t>(input, naked_treatment));
} else if (!input.IsEmpty()) {
ConstrainLongRange output;
if (input.HasExact())
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 0d835761e04..03a93fb8a5c 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_devices.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_devices.cc
@@ -20,7 +20,6 @@
#include "third_party/blink/renderer/modules/mediastream/media_stream_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/modules/mediastream/user_media_request.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
@@ -105,6 +104,16 @@ ScriptPromise MediaDevices::enumerateDevices(ScriptState* script_state) {
ScriptPromise MediaDevices::getUserMedia(ScriptState* script_state,
const MediaStreamConstraints& options,
ExceptionState& exception_state) {
+ return SendUserMediaRequest(script_state,
+ WebUserMediaRequest::MediaType::kUserMedia,
+ options, exception_state);
+}
+
+ScriptPromise MediaDevices::SendUserMediaRequest(
+ ScriptState* script_state,
+ WebUserMediaRequest::MediaType media_type,
+ const MediaStreamConstraints& options,
+ ExceptionState& exception_state) {
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
PromiseResolverCallbacks* callbacks =
PromiseResolverCallbacks::Create(resolver);
@@ -121,7 +130,7 @@ ScriptPromise MediaDevices::getUserMedia(ScriptState* script_state,
MediaErrorState error_state;
UserMediaRequest* request = UserMediaRequest::Create(
- document, user_media, options, callbacks, error_state);
+ document, user_media, media_type, options, callbacks, error_state);
if (!request) {
DCHECK(error_state.HadException());
if (error_state.CanGenerateException()) {
@@ -224,7 +233,7 @@ void MediaDevices::DispatchScheduledEvent() {
events.swap(scheduled_events_);
for (const auto& event : events)
- DispatchEvent(event);
+ DispatchEvent(*event);
}
void MediaDevices::StartObserving() {
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 00171c23913..b8a99e5e3d6 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_devices.h
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_devices.h
@@ -13,6 +13,7 @@
#include "third_party/blink/renderer/core/dom/pausable_object.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/async_method_runner.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
@@ -44,6 +45,10 @@ class MODULES_EXPORT MediaDevices final
ScriptPromise getUserMedia(ScriptState*,
const MediaStreamConstraints&,
ExceptionState&);
+ ScriptPromise SendUserMediaRequest(ScriptState*,
+ WebUserMediaRequest::MediaType,
+ const MediaStreamConstraints&,
+ ExceptionState&);
// EventTarget overrides.
const AtomicString& InterfaceName() const override;
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 99bea50b140..d48dfc7daa1 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream.cc
@@ -492,7 +492,7 @@ void MediaStream::ScheduledEventTimerFired(TimerBase*) {
HeapVector<Member<Event>>::iterator it = events.begin();
for (; it != events.end(); ++it)
- DispatchEvent((*it).Release());
+ DispatchEvent(*it->Release());
events.clear();
}
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 3f8ac81c741..666ef98d3a4 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
@@ -581,14 +581,14 @@ void MediaStreamTrack::SourceChangedState() {
switch (ready_state_) {
case MediaStreamSource::kReadyStateLive:
component_->SetMuted(false);
- DispatchEvent(Event::Create(EventTypeNames::unmute));
+ DispatchEvent(*Event::Create(EventTypeNames::unmute));
break;
case MediaStreamSource::kReadyStateMuted:
component_->SetMuted(true);
- DispatchEvent(Event::Create(EventTypeNames::mute));
+ DispatchEvent(*Event::Create(EventTypeNames::mute));
break;
case MediaStreamSource::kReadyStateEnded:
- DispatchEvent(Event::Create(EventTypeNames::ended));
+ DispatchEvent(*Event::Create(EventTypeNames::ended));
PropagateTrackEnded();
break;
}
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track_content_hint.idl b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track_content_hint.idl
index c333f0e9f77..cd35bda184a 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track_content_hint.idl
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track_content_hint.idl
@@ -7,5 +7,5 @@
ImplementedAs=MediaStreamTrackContentHint,
RuntimeEnabled=MediaStreamTrackContentHint
] partial interface MediaStreamTrack {
- attribute DOMString contentHint;
+ [Measure] attribute DOMString contentHint;
};
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/navigator_display_media.cc b/chromium/third_party/blink/renderer/modules/mediastream/navigator_display_media.cc
new file mode 100644
index 00000000000..a78d87f61ee
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/mediastream/navigator_display_media.cc
@@ -0,0 +1,33 @@
+// 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/mediastream/navigator_display_media.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/core/dom/dom_exception.h"
+#include "third_party/blink/renderer/modules/mediastream/media_devices.h"
+#include "third_party/blink/renderer/modules/mediastream/navigator_user_media.h"
+
+namespace blink {
+
+ScriptPromise NavigatorDisplayMedia::getDisplayMedia(
+ ScriptState* script_state,
+ Navigator& navigator,
+ const MediaStreamConstraints& options,
+ ExceptionState& exception_state) {
+ MediaDevices* const media_devices =
+ NavigatorUserMedia::mediaDevices(navigator);
+ if (!media_devices) {
+ return ScriptPromise::RejectWithDOMException(
+ script_state, DOMException::Create(DOMExceptionCode::kNotSupportedError,
+ "Current frame is detached."));
+ }
+
+ return media_devices->SendUserMediaRequest(
+ script_state, WebUserMediaRequest::MediaType::kDisplayMedia, options,
+ exception_state);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/navigator_display_media.h b/chromium/third_party/blink/renderer/modules/mediastream/navigator_display_media.h
new file mode 100644
index 00000000000..ab22babc8e8
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/mediastream/navigator_display_media.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_MODULES_MEDIASTREAM_NAVIGATOR_DISPLAY_MEDIA_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_NAVIGATOR_DISPLAY_MEDIA_H_
+
+#include "third_party/blink/renderer/platform/wtf/allocator.h"
+
+#include "third_party/blink/renderer/core/frame/navigator.h"
+
+namespace blink {
+
+class ExceptionState;
+class MediaStreamConstraints;
+class ScriptPromise;
+class ScriptState;
+
+class NavigatorDisplayMedia {
+ STATIC_ONLY(NavigatorDisplayMedia);
+
+ public:
+ static ScriptPromise getDisplayMedia(ScriptState*,
+ Navigator&,
+ const MediaStreamConstraints&,
+ ExceptionState&);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_NAVIGATOR_DISPLAY_MEDIA_H_
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/navigator_display_media.idl b/chromium/third_party/blink/renderer/modules/mediastream/navigator_display_media.idl
new file mode 100644
index 00000000000..8afdc7e3710
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/mediastream/navigator_display_media.idl
@@ -0,0 +1,12 @@
+// 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://w3c.github.io/mediacapture-screen-share/
+[
+ ImplementedAs = NavigatorDisplayMedia,
+ RuntimeEnabled = GetDisplayMedia
+] partial interface Navigator {
+ [CallWith = ScriptState, RaisesException] Promise<MediaStream>
+ getDisplayMedia(optional MediaStreamConstraints constraints);
+};
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 2d824337fd0..68eb294ad3c 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
@@ -46,10 +46,10 @@ UserMediaClient::UserMediaClient(WebUserMediaClient* client)
void UserMediaClient::RequestUserMedia(UserMediaRequest* request) {
if (client_) {
client_->RequestUserMedia(request);
- } else {
- request->Fail(WebUserMediaRequest::Error::kNotSupported,
- "User Media support is disabled");
+ return;
}
+ request->Fail(WebUserMediaRequest::Error::kNotSupported,
+ "User Media support is disabled");
}
void UserMediaClient::CancelUserMediaRequest(UserMediaRequest* request) {
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 71c2aa70a0d..03c2b2a3c38 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
@@ -362,6 +362,7 @@ class UserMediaRequest::V8Callbacks final : public UserMediaRequest::Callbacks {
UserMediaRequest* UserMediaRequest::Create(
ExecutionContext* context,
UserMediaController* controller,
+ WebUserMediaRequest::MediaType media_type,
const MediaStreamConstraints& options,
Callbacks* callbacks,
MediaErrorState& error_state) {
@@ -375,6 +376,30 @@ UserMediaRequest* UserMediaRequest::Create(
if (error_state.HadException())
return nullptr;
+ if (media_type == WebUserMediaRequest::MediaType::kDisplayMedia) {
+ // TODO(emircan): Support constraints after the spec change.
+ // https://w3c.github.io/mediacapture-screen-share/#constraints
+ // 5.2 Constraining Display Surface Selection
+ // The getDisplayMedia function does not permit the use of constraints for
+ // selection of a source as described in the getUserMedia() algorithm.
+ // Prior to invoking the getUserMedia() algorithm, if either of the video
+ // and audio attributes are set to a MediaTrackConstraints value (as
+ // opposed to being absent or set to a Boolean value), reject the promise
+ // with a InvalidAccessError and abort.
+ if (options.audio().IsMediaTrackConstraints() ||
+ options.video().IsMediaTrackConstraints()) {
+ error_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidAccessError,
+ "getDisplayMedia() does not permit the use of constraints.");
+ return nullptr;
+ }
+ // TODO(emircan): Enable when audio capture is supported.
+ if (!options.audio().IsNull() && options.audio().GetAsBoolean()) {
+ error_state.ThrowTypeError("Audio is not supported");
+ return nullptr;
+ }
+ }
+
if (audio.IsNull() && video.IsNull()) {
error_state.ThrowTypeError(
"At least one of audio and video must be requested");
@@ -386,7 +411,8 @@ UserMediaRequest* UserMediaRequest::Create(
if (!video.IsNull())
CountVideoConstraintUses(context, video);
- return new UserMediaRequest(context, controller, audio, video, callbacks);
+ return new UserMediaRequest(context, controller, media_type, audio, video,
+ callbacks);
}
UserMediaRequest* UserMediaRequest::Create(
@@ -396,23 +422,27 @@ UserMediaRequest* UserMediaRequest::Create(
V8NavigatorUserMediaSuccessCallback* success_callback,
V8NavigatorUserMediaErrorCallback* error_callback,
MediaErrorState& error_state) {
- return Create(context, controller, options,
- V8Callbacks::Create(success_callback, error_callback),
+ return Create(context, controller, WebUserMediaRequest::MediaType::kUserMedia,
+ options, V8Callbacks::Create(success_callback, error_callback),
error_state);
}
UserMediaRequest* UserMediaRequest::CreateForTesting(
const WebMediaConstraints& audio,
const WebMediaConstraints& video) {
- return new UserMediaRequest(nullptr, nullptr, audio, video, nullptr);
+ return new UserMediaRequest(nullptr, nullptr,
+ WebUserMediaRequest::MediaType::kUserMedia, audio,
+ video, nullptr);
}
UserMediaRequest::UserMediaRequest(ExecutionContext* context,
UserMediaController* controller,
+ WebUserMediaRequest::MediaType media_type,
WebMediaConstraints audio,
WebMediaConstraints video,
Callbacks* callbacks)
: ContextLifecycleObserver(context),
+ media_type_(media_type),
audio_(audio),
video_(video),
should_disable_hardware_noise_suppression_(
@@ -432,6 +462,10 @@ UserMediaRequest::UserMediaRequest(ExecutionContext* context,
UserMediaRequest::~UserMediaRequest() = default;
+WebUserMediaRequest::MediaType UserMediaRequest::MediaRequestType() const {
+ return media_type_;
+}
+
bool UserMediaRequest::Audio() const {
return !audio_.IsNull();
}
@@ -463,27 +497,19 @@ bool UserMediaRequest::IsSecureContextUse(String& error_message) {
// Feature policy deprecation messages.
if (Audio()) {
- if (RuntimeEnabledFeatures::FeaturePolicyForPermissionsEnabled()) {
- if (!document->GetFrame()->IsFeatureEnabled(
- mojom::FeaturePolicyFeature::kMicrophone)) {
- UseCounter::Count(
- document, WebFeature::kMicrophoneDisabledByFeaturePolicyEstimate);
- }
- } else {
- Deprecation::CountDeprecationFeaturePolicy(
- *document, mojom::FeaturePolicyFeature::kMicrophone);
+ if (!document->GetFrame()->IsFeatureEnabled(
+ mojom::FeaturePolicyFeature::kMicrophone,
+ ReportOptions::kReportOnFailure)) {
+ UseCounter::Count(
+ document, WebFeature::kMicrophoneDisabledByFeaturePolicyEstimate);
}
}
if (Video()) {
- if (RuntimeEnabledFeatures::FeaturePolicyForPermissionsEnabled()) {
- if (!document->GetFrame()->IsFeatureEnabled(
- mojom::FeaturePolicyFeature::kCamera)) {
- UseCounter::Count(document,
- WebFeature::kCameraDisabledByFeaturePolicyEstimate);
- }
- } else {
- Deprecation::CountDeprecationFeaturePolicy(
- *document, mojom::FeaturePolicyFeature::kCamera);
+ if (!document->GetFrame()->IsFeatureEnabled(
+ mojom::FeaturePolicyFeature::kCamera,
+ ReportOptions::kReportOnFailure)) {
+ UseCounter::Count(document,
+ WebFeature::kCameraDisabledByFeaturePolicyEstimate);
}
}
@@ -526,14 +552,12 @@ void UserMediaRequest::Succeed(MediaStreamDescriptor* stream_descriptor) {
MediaStreamTrackVector audio_tracks = stream->getAudioTracks();
for (MediaStreamTrackVector::iterator iter = audio_tracks.begin();
iter != audio_tracks.end(); ++iter) {
- (*iter)->Component()->Source()->SetConstraints(audio_);
(*iter)->SetConstraints(audio_);
}
MediaStreamTrackVector video_tracks = stream->getVideoTracks();
for (MediaStreamTrackVector::iterator iter = video_tracks.begin();
iter != video_tracks.end(); ++iter) {
- (*iter)->Component()->Source()->SetConstraints(video_);
(*iter)->SetConstraints(video_);
}
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 21c2f14a731..4809285a8e2 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
@@ -73,6 +73,7 @@ class MODULES_EXPORT UserMediaRequest final
static UserMediaRequest* Create(ExecutionContext*,
UserMediaController*,
+ WebUserMediaRequest::MediaType media_type,
const MediaStreamConstraints& options,
Callbacks*,
MediaErrorState&);
@@ -94,6 +95,7 @@ class MODULES_EXPORT UserMediaRequest final
void FailConstraint(const String& constraint_name, const String& message);
void Fail(WebUserMediaRequest::Error name, const String& message);
+ WebUserMediaRequest::MediaType MediaRequestType() const;
bool Audio() const;
bool Video() const;
WebMediaConstraints AudioConstraints() const;
@@ -115,10 +117,12 @@ class MODULES_EXPORT UserMediaRequest final
private:
UserMediaRequest(ExecutionContext*,
UserMediaController*,
+ WebUserMediaRequest::MediaType media_type,
WebMediaConstraints audio,
WebMediaConstraints video,
Callbacks*);
+ WebUserMediaRequest::MediaType media_type_;
WebMediaConstraints audio_;
WebMediaConstraints video_;
bool should_disable_hardware_noise_suppression_;
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 4531e3f0d32..1b46d11ac4f 100644
--- a/chromium/third_party/blink/renderer/modules/modules_idl_files.gni
+++ b/chromium/third_party/blink/renderer/modules/modules_idl_files.gni
@@ -64,17 +64,13 @@ modules_idl_files =
"animationworklet/effect_proxy.idl",
"animationworklet/worklet_animation.idl",
"app_banner/before_install_prompt_event.idl",
- "background_fetch/background_fetch_click_event.idl",
"background_fetch/background_fetch_event.idl",
- "background_fetch/background_fetch_fail_event.idl",
"background_fetch/background_fetch_fetch.idl",
"background_fetch/background_fetch_manager.idl",
+ "background_fetch/background_fetch_record.idl",
"background_fetch/background_fetch_registration.idl",
- "background_fetch/background_fetch_settled_event.idl",
"background_fetch/background_fetch_settled_fetch.idl",
- "background_fetch/background_fetch_settled_fetches.idl",
- "background_fetch/background_fetch_update_event.idl",
- "background_fetch/background_fetched_event.idl",
+ "background_fetch/background_fetch_update_ui_event.idl",
"background_sync/sync_event.idl",
"background_sync/sync_manager.idl",
"battery/battery_manager.idl",
@@ -87,8 +83,6 @@ modules_idl_files =
"bluetooth/bluetooth_remote_gatt_service.idl",
"bluetooth/bluetooth_uuid.idl",
"broadcastchannel/broadcast_channel.idl",
- "budget/budget_service.idl",
- "budget/budget_state.idl",
"cache_storage/cache.idl",
"cache_storage/cache_storage.idl",
"canvas/canvas2d/canvas_gradient.idl",
@@ -140,7 +134,11 @@ modules_idl_files =
"filesystem/file_callback.idl",
"filesystem/file_entry.idl",
"filesystem/file_entry_sync.idl",
+ "filesystem/file_system_base_handle.idl",
+ "filesystem/file_system_directory_handle.idl",
+ "filesystem/file_system_file_handle.idl",
"filesystem/file_system_callback.idl",
+ "filesystem/file_system_writer.idl",
"filesystem/file_writer.idl",
"filesystem/file_writer_callback.idl",
"filesystem/file_writer_sync.idl",
@@ -220,9 +218,12 @@ modules_idl_files =
"peerconnection/rtc_data_channel.idl",
"peerconnection/rtc_data_channel_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_event.idl",
+ "peerconnection/rtc_quic_stream.idl",
+ "peerconnection/rtc_quic_transport.idl",
"peerconnection/rtc_rtp_contributing_source.idl",
"peerconnection/rtc_rtp_receiver.idl",
"peerconnection/rtc_rtp_sender.idl",
@@ -233,6 +234,7 @@ modules_idl_files =
"peerconnection/rtc_track_event.idl",
"permissions/permissions.idl",
"permissions/permission_status.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",
@@ -306,6 +308,8 @@ modules_idl_files =
"vr/vr_frame_data.idl",
"vr/vr_pose.idl",
"vr/vr_stage_parameters.idl",
+ "wake_lock/wake_lock.idl",
+ "wake_lock/wake_lock_request.idl",
"webaudio/analyser_node.idl",
"webaudio/audio_buffer.idl",
"webaudio/audio_buffer_source_node.idl",
@@ -385,6 +389,7 @@ modules_idl_files =
"webgl/webgl_draw_buffers.idl",
"webgl/webgl_framebuffer.idl",
"webgl/webgl_lose_context.idl",
+ "webgl/webgl_multiview.idl",
"webgl/webgl_program.idl",
"webgl/webgl_query.idl",
"webgl/webgl_renderbuffer.idl",
@@ -441,7 +446,6 @@ modules_idl_files =
"xr/xr_session.idl",
"xr/xr_session_event.idl",
"xr/xr_stage_bounds.idl",
- "xr/xr_stage_bounds_point.idl",
"xr/xr_view.idl",
"xr/xr_viewport.idl",
"xr/xr_webgl_layer.idl",
@@ -465,12 +469,9 @@ modules_dictionary_idl_files =
[
"app_banner/app_banner_prompt_result.idl",
"app_banner/before_install_prompt_event_init.idl",
- "background_fetch/background_fetch_click_event_init.idl",
"background_fetch/background_fetch_event_init.idl",
- "background_fetch/background_fetch_fail_event_init.idl",
"background_fetch/background_fetch_options.idl",
- "background_fetch/background_fetch_settled_event_init.idl",
- "background_fetch/background_fetched_event_init.idl",
+ "background_fetch/background_fetch_ui_options.idl",
"background_sync/sync_event_init.idl",
"bluetooth/bluetooth_le_scan_filter_init.idl",
"bluetooth/request_device_options.idl",
@@ -591,10 +592,14 @@ modules_dictionary_idl_files =
"peerconnection/rtc_dtmf_tone_change_event_init.idl",
"peerconnection/rtc_data_channel_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_event_init.idl",
+ "peerconnection/rtc_quic_parameters.idl",
"peerconnection/rtc_rtcp_parameters.idl",
"peerconnection/rtc_rtp_capabilities.idl",
"peerconnection/rtc_rtp_codec_capability.idl",
@@ -612,6 +617,8 @@ modules_dictionary_idl_files =
"permissions/midi_permission_descriptor.idl",
"permissions/permission_descriptor.idl",
"permissions/push_permission_descriptor.idl",
+ "picture_in_picture/enter_picture_in_picture_event_init.idl",
+ "picture_in_picture/picture_in_picture_control.idl",
"presentation/presentation_connection_available_event_init.idl",
"presentation/presentation_connection_close_event_init.idl",
"push_messaging/push_event_init.idl",
@@ -695,8 +702,6 @@ modules_dependency_idl_files =
"battery/navigator_battery.idl",
"beacon/navigator_beacon.idl",
"bluetooth/navigator_bluetooth.idl",
- "budget/navigator_budget.idl",
- "budget/worker_navigator_budget.idl",
"cache_storage/window_cache_storage.idl",
"cache_storage/worker_cache_storage.idl",
"canvas/canvas2d/canvas_path.idl",
@@ -737,6 +742,7 @@ modules_dependency_idl_files =
"mediasource/html_video_element_media_source.idl",
"mediasource/url_media_source.idl",
"mediastream/media_stream_track_content_hint.idl",
+ "mediastream/navigator_display_media.idl",
"mediastream/navigator_media_stream.idl",
"mediastream/navigator_user_media.idl",
"mediastream/url_media_stream.idl",
@@ -771,6 +777,7 @@ modules_dependency_idl_files =
"storage/window_storage.idl",
"vibration/navigator_vibration.idl",
"vr/navigator_vr.idl",
+ "wake_lock/navigator_wake_lock.idl",
"wake_lock/screen_wake_lock.idl",
"webdatabase/window_web_database.idl",
"webgl/webgl2_rendering_context_base.idl",
diff --git a/chromium/third_party/blink/renderer/modules/modules_initializer.cc b/chromium/third_party/blink/renderer/modules/modules_initializer.cc
index 690c337d13d..b62523ddaf3 100644
--- a/chromium/third_party/blink/renderer/modules/modules_initializer.cc
+++ b/chromium/third_party/blink/renderer/modules/modules_initializer.cc
@@ -239,7 +239,7 @@ void ModulesInitializer::OnClearWindowObjectInMainWorld(
NavigatorGamepad::From(document);
NavigatorServiceWorker::From(document);
DOMWindowStorageController::From(document);
- if (RuntimeEnabledFeatures::WebVREnabled())
+ if (OriginTrials::WebVREnabled(document.GetExecutionContext()))
NavigatorVR::From(document);
if (RuntimeEnabledFeatures::PresentationEnabled() &&
settings.GetPresentationReceiver()) {
diff --git a/chromium/third_party/blink/renderer/modules/navigatorcontentutils/OWNERS b/chromium/third_party/blink/renderer/modules/navigatorcontentutils/OWNERS
new file mode 100644
index 00000000000..4a108e15962
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/navigatorcontentutils/OWNERS
@@ -0,0 +1,3 @@
+gyuyoung.kim@lge.com
+
+# COMPONENT: Blink>HTML>CustomHandlers
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 1e4fd253849..127db758e76 100644
--- a/chromium/third_party/blink/renderer/modules/netinfo/network_information.cc
+++ b/chromium/third_party/blink/renderer/modules/netinfo/network_information.cc
@@ -177,8 +177,8 @@ void NetworkInformation::ConnectionChange(
save_data_ = save_data;
if (type_changed)
- DispatchEvent(Event::Create(EventTypeNames::typechange));
- DispatchEvent(Event::Create(EventTypeNames::change));
+ DispatchEvent(*Event::Create(EventTypeNames::typechange));
+ DispatchEvent(*Event::Create(EventTypeNames::change));
}
const AtomicString& NetworkInformation::InterfaceName() const {
diff --git a/chromium/third_party/blink/renderer/modules/netinfo/network_information.idl b/chromium/third_party/blink/renderer/modules/netinfo/network_information.idl
index fe8d5ba1cd6..fdb729a806a 100644
--- a/chromium/third_party/blink/renderer/modules/netinfo/network_information.idl
+++ b/chromium/third_party/blink/renderer/modules/netinfo/network_information.idl
@@ -31,10 +31,10 @@ typedef unsigned long long Milliseconds;
] interface NetworkInformation : EventTarget {
[RuntimeEnabled=NetInfoDownlinkMax, MeasureAs=NetInfoType] readonly attribute ConnectionType type;
[RuntimeEnabled=NetInfoDownlinkMax, MeasureAs=NetInfoDownlinkMax] readonly attribute Megabit downlinkMax;
- [RuntimeEnabled=NetInfoEffectiveType, MeasureAs=NetInfoOnChange] attribute EventHandler onchange;
+ [MeasureAs=NetInfoOnChange] attribute EventHandler onchange;
[RuntimeEnabled=NetInfoDownlinkMax, MeasureAs=NetInfoOnTypeChange] attribute EventHandler ontypechange;
- [RuntimeEnabled=NetInfoEffectiveType, MeasureAs=NetInfoEffectiveType] readonly attribute EffectiveConnectionType effectiveType;
- [RuntimeEnabled=NetInfoRtt, MeasureAs=NetInfoRtt] readonly attribute Milliseconds rtt;
- [RuntimeEnabled=NetInfoDownlink, MeasureAs=NetInfoDownlink] readonly attribute Megabit downlink;
- [RuntimeEnabled=NetInfoSaveData, MeasureAs=NetInfoSaveData] readonly attribute boolean saveData;
+ [MeasureAs=NetInfoEffectiveType] readonly attribute EffectiveConnectionType effectiveType;
+ [MeasureAs=NetInfoRtt] readonly attribute Milliseconds rtt;
+ [MeasureAs=NetInfoDownlink] readonly attribute Megabit downlink;
+ [MeasureAs=NetInfoSaveData] readonly attribute boolean saveData;
};
diff --git a/chromium/third_party/blink/renderer/modules/notifications/OWNERS b/chromium/third_party/blink/renderer/modules/notifications/OWNERS
index f3d5fb2ac0c..2fd0e4bec55 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/OWNERS
+++ b/chromium/third_party/blink/renderer/modules/notifications/OWNERS
@@ -1,4 +1,3 @@
-awdf@chromium.org
peter@chromium.org
# TEAM: platform-capabilities@chromium.org
diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification.cc b/chromium/third_party/blink/renderer/modules/notifications/notification.cc
index 7dc85efa933..6e277ad9cba 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/notification.cc
+++ b/chromium/third_party/blink/renderer/modules/notifications/notification.cc
@@ -31,7 +31,6 @@
#include "third_party/blink/renderer/modules/notifications/notification.h"
#include "base/unguessable_token.h"
-#include "third_party/blink/public/platform/modules/notifications/web_notification_action.h"
#include "third_party/blink/public/platform/modules/notifications/web_notification_constants.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_factory.h"
@@ -103,8 +102,8 @@ Notification* Notification::Create(ExecutionContext* context,
}
}
- WebNotificationData data =
- CreateWebNotificationData(context, title, options, exception_state);
+ mojom::blink::NotificationDataPtr data =
+ CreateNotificationData(context, title, options, exception_state);
if (exception_state.HadException())
return nullptr;
@@ -114,15 +113,15 @@ Notification* Notification::Create(ExecutionContext* context,
}
Notification* notification =
- new Notification(context, Type::kNonPersistent, data);
+ new Notification(context, Type::kNonPersistent, std::move(data));
// TODO(https://crbug.com/595685): Make |token| a constructor parameter
// once persistent notifications have been mojofied too.
- if (data.tag.IsNull() || data.tag.IsEmpty()) {
+ if (notification->tag().IsNull() || notification->tag().IsEmpty()) {
auto unguessable_token = base::UnguessableToken::Create();
notification->SetToken(unguessable_token.ToString().c_str());
} else {
- notification->SetToken(data.tag);
+ notification->SetToken(notification->tag());
}
notification->SchedulePrepareShow();
@@ -140,10 +139,10 @@ Notification* Notification::Create(ExecutionContext* context,
Notification* Notification::Create(ExecutionContext* context,
const String& notification_id,
- const WebNotificationData& data,
+ mojom::blink::NotificationDataPtr data,
bool showing) {
Notification* notification =
- new Notification(context, Type::kPersistent, data);
+ new Notification(context, Type::kPersistent, std::move(data));
notification->SetState(showing ? State::kShowing : State::kClosed);
notification->SetNotificationId(notification_id);
return notification;
@@ -151,13 +150,12 @@ Notification* Notification::Create(ExecutionContext* context,
Notification::Notification(ExecutionContext* context,
Type type,
- const WebNotificationData& data)
+ mojom::blink::NotificationDataPtr data)
: ContextLifecycleObserver(context),
type_(type),
state_(State::kLoading),
- data_(data),
- listener_binding_(this) {
-}
+ data_(std::move(data)),
+ listener_binding_(this) {}
Notification::~Notification() = default;
@@ -186,7 +184,7 @@ void Notification::PrepareShow() {
loader_ = new NotificationResourcesLoader(
WTF::Bind(&Notification::DidLoadResources, WrapWeakPersistent(this)));
- loader_->Start(GetExecutionContext(), data_);
+ loader_->Start(GetExecutionContext(), *data_);
}
void Notification::DidLoadResources(NotificationResourcesLoader* loader) {
@@ -197,7 +195,8 @@ void Notification::DidLoadResources(NotificationResourcesLoader* loader) {
listener_binding_.Bind(mojo::MakeRequest(&event_listener));
NotificationManager::From(GetExecutionContext())
- ->DisplayNonPersistentNotification(token_, data_, loader->GetResources(),
+ ->DisplayNonPersistentNotification(token_, data_->Clone(),
+ loader->GetResources(),
std::move(event_listener));
loader_.Clear();
@@ -225,7 +224,7 @@ void Notification::close() {
}
void Notification::OnShow() {
- DispatchEvent(Event::Create(EventTypeNames::show));
+ DispatchEvent(*Event::Create(EventTypeNames::show));
}
void Notification::OnClick(OnClickCallback completed_closure) {
@@ -235,7 +234,7 @@ void Notification::OnClick(OnClickCallback completed_closure) {
Frame::NotifyUserActivation(document ? document->GetFrame() : nullptr,
UserGestureToken::kNewGesture);
ScopedWindowFocusAllowedIndicator window_focus_allowed(GetExecutionContext());
- DispatchEvent(Event::Create(EventTypeNames::click));
+ DispatchEvent(*Event::Create(EventTypeNames::click));
std::move(completed_closure).Run();
}
@@ -245,26 +244,26 @@ void Notification::OnClose(OnCloseCallback completed_closure) {
// should be Closing if the developer initiated the close.
if (state_ == State::kShowing || state_ == State::kClosing) {
state_ = State::kClosed;
- DispatchEvent(Event::Create(EventTypeNames::close));
+ DispatchEvent(*Event::Create(EventTypeNames::close));
}
std::move(completed_closure).Run();
}
void Notification::DispatchErrorEvent() {
- DispatchEvent(Event::Create(EventTypeNames::error));
+ DispatchEvent(*Event::Create(EventTypeNames::error));
}
String Notification::title() const {
- return data_.title;
+ return data_->title;
}
String Notification::dir() const {
- switch (data_.direction) {
- case WebNotificationData::kDirectionLeftToRight:
+ switch (data_->direction) {
+ case mojom::blink::NotificationDirection::LEFT_TO_RIGHT:
return "ltr";
- case WebNotificationData::kDirectionRightToLeft:
+ case mojom::blink::NotificationDirection::RIGHT_TO_LEFT:
return "rtl";
- case WebNotificationData::kDirectionAuto:
+ case mojom::blink::NotificationDirection::AUTO:
return "auto";
}
@@ -273,57 +272,65 @@ String Notification::dir() const {
}
String Notification::lang() const {
- return data_.lang;
+ return data_->lang;
}
String Notification::body() const {
- return data_.body;
+ return data_->body;
}
String Notification::tag() const {
- return data_.tag;
+ return data_->tag;
}
String Notification::image() const {
- return data_.image.GetString();
+ return data_->image.GetString();
}
String Notification::icon() const {
- return data_.icon.GetString();
+ return data_->icon.GetString();
}
String Notification::badge() const {
- return data_.badge.GetString();
+ return data_->badge.GetString();
}
NavigatorVibration::VibrationPattern Notification::vibrate() const {
NavigatorVibration::VibrationPattern pattern;
- pattern.AppendRange(data_.vibrate.begin(), data_.vibrate.end());
+ if (data_->vibration_pattern.has_value()) {
+ pattern.AppendRange(data_->vibration_pattern->begin(),
+ data_->vibration_pattern->end());
+ }
return pattern;
}
DOMTimeStamp Notification::timestamp() const {
- return data_.timestamp;
+ return data_->timestamp;
}
bool Notification::renotify() const {
- return data_.renotify;
+ return data_->renotify;
}
bool Notification::silent() const {
- return data_.silent;
+ return data_->silent;
}
bool Notification::requireInteraction() const {
- return data_.require_interaction;
+ return data_->require_interaction;
}
ScriptValue Notification::data(ScriptState* script_state) {
- const WebVector<char>& serialized_data = data_.data;
+ const char* data = nullptr;
+ size_t length = 0;
+ if (data_->data.has_value()) {
+ // TODO(https://crbug.com/798466): Align data types to avoid this cast.
+ data = reinterpret_cast<const char*>(data_->data->data());
+ length = data_->data->size();
+ }
scoped_refptr<SerializedScriptValue> serialized_value =
- SerializedScriptValue::Create(serialized_data.Data(),
- serialized_data.size());
+ SerializedScriptValue::Create(data, length);
return ScriptValue(script_state,
serialized_value->Deserialize(script_state->GetIsolate()));
@@ -331,35 +338,40 @@ ScriptValue Notification::data(ScriptState* script_state) {
Vector<v8::Local<v8::Value>> Notification::actions(
ScriptState* script_state) const {
- Vector<v8::Local<v8::Value>> actions;
- actions.Grow(data_.actions.size());
-
- for (size_t i = 0; i < data_.actions.size(); ++i) {
+ Vector<v8::Local<v8::Value>> result;
+ if (!data_->actions.has_value())
+ return result;
+
+ const Vector<mojom::blink::NotificationActionPtr>& actions =
+ data_->actions.value();
+ result.Grow(actions.size());
+ for (size_t i = 0; i < actions.size(); ++i) {
NotificationAction action;
- switch (data_.actions[i].type) {
- case WebNotificationAction::kButton:
+ switch (actions[i]->type) {
+ case mojom::blink::NotificationActionType::BUTTON:
action.setType("button");
break;
- case WebNotificationAction::kText:
+ case mojom::blink::NotificationActionType::TEXT:
action.setType("text");
break;
default:
- NOTREACHED() << "Unknown action type: " << data_.actions[i].type;
+ NOTREACHED() << "Unknown action type: " << actions[i]->type;
}
- action.setAction(data_.actions[i].action);
- action.setTitle(data_.actions[i].title);
- action.setIcon(data_.actions[i].icon.GetString());
- action.setPlaceholder(data_.actions[i].placeholder);
+ action.setAction(actions[i]->action);
+ action.setTitle(actions[i]->title);
+ action.setIcon(actions[i]->icon.GetString());
+ action.setPlaceholder(actions[i]->placeholder);
// Both the Action dictionaries themselves and the sequence they'll be
- // returned in are expected to the frozen. This cannot be done with WebIDL.
- actions[i] =
+ // returned in are expected to the frozen. This cannot be done with
+ // WebIDL.
+ result[i] =
FreezeV8Object(ToV8(action, script_state), script_state->GetIsolate());
}
- return actions;
+ return result;
}
String Notification::PermissionString(
@@ -437,7 +449,7 @@ size_t Notification::maxActions() {
return kWebNotificationMaxActions;
}
-DispatchEventResult Notification::DispatchEventInternal(Event* event) {
+DispatchEventResult Notification::DispatchEventInternal(Event& event) {
DCHECK(GetExecutionContext()->IsContextThread());
return EventTarget::DispatchEventInternal(event);
}
diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification.h b/chromium/third_party/blink/renderer/modules/notifications/notification.h
index 879da4f9191..3cd76838585 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/notification.h
+++ b/chromium/third_party/blink/renderer/modules/notifications/notification.h
@@ -33,7 +33,6 @@
#include "mojo/public/cpp/bindings/binding.h"
#include "third_party/blink/public/platform/modules/notifications/notification_service.mojom-blink.h"
-#include "third_party/blink/public/platform/modules/notifications/web_notification_data.h"
#include "third_party/blink/public/platform/modules/permissions/permission.mojom-blink.h"
#include "third_party/blink/public/platform/modules/permissions/permission_status.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
@@ -78,7 +77,7 @@ class MODULES_EXPORT Notification final
// of the notification as either Showing or Closed based on |showing|.
static Notification* Create(ExecutionContext* context,
const String& notification_id,
- const WebNotificationData& data,
+ mojom::blink::NotificationDataPtr data,
bool showing);
~Notification() override;
@@ -135,7 +134,7 @@ class MODULES_EXPORT Notification final
protected:
// EventTarget interface.
- DispatchEventResult DispatchEventInternal(Event* event) final;
+ DispatchEventResult DispatchEventInternal(Event& event) final;
private:
// The type of notification this instance represents. Non-persistent
@@ -148,7 +147,7 @@ class MODULES_EXPORT Notification final
Notification(ExecutionContext* context,
Type type,
- const WebNotificationData& data);
+ mojom::blink::NotificationDataPtr data);
// Sets the state of the notification in its lifecycle.
void SetState(State state) { state_ = state; }
@@ -180,7 +179,7 @@ class MODULES_EXPORT Notification final
Type type_;
State state_;
- WebNotificationData data_;
+ mojom::blink::NotificationDataPtr data_;
String notification_id_;
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 37342635b6a..76675044019 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/notification_data.cc
+++ b/chromium/third_party/blink/renderer/modules/notifications/notification_data.cc
@@ -4,7 +4,6 @@
#include "third_party/blink/renderer/modules/notifications/notification_data.h"
-#include "third_party/blink/public/platform/web_url.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/core/execution_context/execution_context.h"
@@ -18,25 +17,26 @@
namespace blink {
namespace {
-WebNotificationData::Direction ToDirectionEnumValue(const String& direction) {
+mojom::blink::NotificationDirection ToDirectionEnumValue(
+ const String& direction) {
if (direction == "ltr")
- return WebNotificationData::kDirectionLeftToRight;
+ return mojom::blink::NotificationDirection::LEFT_TO_RIGHT;
if (direction == "rtl")
- return WebNotificationData::kDirectionRightToLeft;
+ return mojom::blink::NotificationDirection::RIGHT_TO_LEFT;
- return WebNotificationData::kDirectionAuto;
+ return mojom::blink::NotificationDirection::AUTO;
}
-WebURL CompleteURL(ExecutionContext* context, const String& string_url) {
- WebURL url = context->CompleteURL(string_url);
+KURL CompleteURL(ExecutionContext* context, const String& string_url) {
+ KURL url = context->CompleteURL(string_url);
if (url.IsValid())
return url;
- return WebURL();
+ return KURL();
}
} // namespace
-WebNotificationData CreateWebNotificationData(
+mojom::blink::NotificationDataPtr CreateNotificationData(
ExecutionContext* context,
const String& title,
const NotificationOptions& options,
@@ -45,7 +45,7 @@ WebNotificationData CreateWebNotificationData(
if (options.hasVibrate() && options.silent()) {
exception_state.ThrowTypeError(
"Silent notifications must not specify vibration patterns.");
- return WebNotificationData();
+ return nullptr;
}
// If renotify is true, the notification must have a tag.
@@ -53,34 +53,37 @@ WebNotificationData CreateWebNotificationData(
exception_state.ThrowTypeError(
"Notifications which set the renotify flag must specify a non-empty "
"tag.");
- return WebNotificationData();
+ return nullptr;
}
- WebNotificationData web_data;
+ auto notification_data = mojom::blink::NotificationData::New();
- web_data.title = title;
- web_data.direction = ToDirectionEnumValue(options.dir());
- web_data.lang = options.lang();
- web_data.body = options.body();
- web_data.tag = options.tag();
+ notification_data->title = title;
+ notification_data->direction = ToDirectionEnumValue(options.dir());
+ notification_data->lang = options.lang();
+ notification_data->body = options.body();
+ notification_data->tag = options.tag();
if (options.hasImage() && !options.image().IsEmpty())
- web_data.image = CompleteURL(context, options.image());
+ notification_data->image = CompleteURL(context, options.image());
if (options.hasIcon() && !options.icon().IsEmpty())
- web_data.icon = CompleteURL(context, options.icon());
+ notification_data->icon = CompleteURL(context, options.icon());
if (options.hasBadge() && !options.badge().IsEmpty())
- web_data.badge = CompleteURL(context, options.badge());
+ notification_data->badge = CompleteURL(context, options.badge());
- web_data.vibrate =
+ VibrationController::VibrationPattern vibration_pattern =
VibrationController::SanitizeVibrationPattern(options.vibrate());
- web_data.timestamp = options.hasTimestamp()
- ? static_cast<double>(options.timestamp())
- : WTF::CurrentTimeMS();
- web_data.renotify = options.renotify();
- web_data.silent = options.silent();
- web_data.require_interaction = options.requireInteraction();
+ notification_data->vibration_pattern = Vector<int32_t>();
+ notification_data->vibration_pattern->Append(vibration_pattern.data(),
+ vibration_pattern.size());
+ notification_data->timestamp = options.hasTimestamp()
+ ? static_cast<double>(options.timestamp())
+ : WTF::CurrentTimeMS();
+ notification_data->renotify = options.renotify();
+ notification_data->silent = options.silent();
+ notification_data->require_interaction = options.requireInteraction();
if (options.hasData()) {
const ScriptValue& data = options.data();
@@ -92,47 +95,51 @@ WebNotificationData CreateWebNotificationData(
SerializedScriptValue::Serialize(isolate, data.V8Value(), options,
exception_state);
if (exception_state.HadException())
- return WebNotificationData();
+ return nullptr;
- web_data.data = WebVector<char>(serialized_script_value->GetWireData());
+ notification_data->data = Vector<uint8_t>();
+ notification_data->data->Append(
+ serialized_script_value->Data(),
+ serialized_script_value->DataLengthInBytes());
}
- Vector<WebNotificationAction> actions;
+ Vector<mojom::blink::NotificationActionPtr> actions;
const size_t max_actions = Notification::maxActions();
for (const NotificationAction& action : options.actions()) {
if (actions.size() >= max_actions)
break;
- WebNotificationAction web_action;
- web_action.action = action.action();
- web_action.title = action.title();
+ auto notification_action = mojom::blink::NotificationAction::New();
+ notification_action->action = action.action();
+ notification_action->title = action.title();
if (action.type() == "button")
- web_action.type = WebNotificationAction::kButton;
+ notification_action->type = mojom::blink::NotificationActionType::BUTTON;
else if (action.type() == "text")
- web_action.type = WebNotificationAction::kText;
+ notification_action->type = mojom::blink::NotificationActionType::TEXT;
else
NOTREACHED() << "Unknown action type: " << action.type();
if (action.hasPlaceholder() &&
- web_action.type == WebNotificationAction::kButton) {
+ notification_action->type ==
+ mojom::blink::NotificationActionType::BUTTON) {
exception_state.ThrowTypeError(
"Notifications of type \"button\" cannot specify a placeholder.");
- return WebNotificationData();
+ return nullptr;
}
- web_action.placeholder = action.placeholder();
+ notification_action->placeholder = action.placeholder();
if (action.hasIcon() && !action.icon().IsEmpty())
- web_action.icon = CompleteURL(context, action.icon());
+ notification_action->icon = CompleteURL(context, action.icon());
- actions.push_back(web_action);
+ actions.push_back(std::move(notification_action));
}
- web_data.actions = actions;
+ notification_data->actions = std::move(actions);
- return web_data;
+ return notification_data;
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification_data.h b/chromium/third_party/blink/renderer/modules/notifications/notification_data.h
index 88235839b2c..0dcb0f0228b 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/notification_data.h
+++ b/chromium/third_party/blink/renderer/modules/notifications/notification_data.h
@@ -5,7 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_NOTIFICATIONS_NOTIFICATION_DATA_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_NOTIFICATIONS_NOTIFICATION_DATA_H_
-#include "third_party/blink/public/platform/modules/notifications/web_notification_data.h"
+#include "third_party/blink/public/platform/modules/notifications/notification.mojom-blink.h"
#include "third_party/blink/renderer/modules/modules_export.h"
namespace WTF {
@@ -18,14 +18,15 @@ class ExceptionState;
class ExecutionContext;
class NotificationOptions;
-// Creates a WebNotificationData object based on the developer-provided
-// notification options. An exception will be thrown on the ExceptionState when
-// the given options do not match the constraints imposed by the specification.
-MODULES_EXPORT WebNotificationData
-CreateWebNotificationData(ExecutionContext* context,
- const String& title,
- const NotificationOptions& options,
- ExceptionState& exception_state);
+// Creates a mojom::blink::NotificationData object based on the
+// developer-provided notification options. An exception will be thrown on the
+// ExceptionState when the given options do not match the constraints imposed by
+// the specification.
+MODULES_EXPORT mojom::blink::NotificationDataPtr CreateNotificationData(
+ ExecutionContext* context,
+ const String& title,
+ const NotificationOptions& options,
+ ExceptionState& exception_state);
} // namespace blink
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 f250a34e91a..edd59252eee 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
@@ -35,8 +35,8 @@ const bool kNotificationRenotify = true;
const bool kNotificationSilent = false;
const bool kNotificationRequireInteraction = true;
-const WebNotificationAction::Type kWebNotificationActionType =
- WebNotificationAction::kText;
+const mojom::blink::NotificationActionType kWebNotificationActionType =
+ mojom::blink::NotificationActionType::TEXT;
const char kNotificationActionType[] = "text";
const char kNotificationActionAction[] = "my_action";
const char kNotificationActionTitle[] = "My Action";
@@ -113,41 +113,44 @@ TEST_F(NotificationDataTest, ReflectProperties) {
// TODO(peter): Test |options.data| and |notificationData.data|.
DummyExceptionStateForTesting exception_state;
- WebNotificationData notification_data = CreateWebNotificationData(
+ mojom::blink::NotificationDataPtr notification_data = CreateNotificationData(
GetExecutionContext(), kNotificationTitle, options, exception_state);
ASSERT_FALSE(exception_state.HadException());
- EXPECT_EQ(kNotificationTitle, notification_data.title);
+ EXPECT_EQ(kNotificationTitle, notification_data->title);
- EXPECT_EQ(WebNotificationData::kDirectionRightToLeft,
- notification_data.direction);
- EXPECT_EQ(kNotificationLang, notification_data.lang);
- EXPECT_EQ(kNotificationBody, notification_data.body);
- EXPECT_EQ(kNotificationTag, notification_data.tag);
+ EXPECT_EQ(mojom::blink::NotificationDirection::RIGHT_TO_LEFT,
+ notification_data->direction);
+ EXPECT_EQ(kNotificationLang, notification_data->lang);
+ EXPECT_EQ(kNotificationBody, notification_data->body);
+ EXPECT_EQ(kNotificationTag, notification_data->tag);
KURL base(kNotificationBaseUrl);
// URLs should be resolved against the base URL of the execution context.
- EXPECT_EQ(WebURL(KURL(base, kNotificationImage)), notification_data.image);
- EXPECT_EQ(WebURL(KURL(base, kNotificationIcon)), notification_data.icon);
- EXPECT_EQ(WebURL(KURL(base, kNotificationBadge)), notification_data.badge);
-
- ASSERT_EQ(vibration_pattern.size(), notification_data.vibrate.size());
- for (size_t i = 0; i < vibration_pattern.size(); ++i)
- EXPECT_EQ(vibration_pattern[i],
- static_cast<unsigned>(notification_data.vibrate[i]));
-
- EXPECT_EQ(kNotificationTimestamp, notification_data.timestamp);
- EXPECT_EQ(kNotificationRenotify, notification_data.renotify);
- EXPECT_EQ(kNotificationSilent, notification_data.silent);
+ EXPECT_EQ(KURL(base, kNotificationImage), notification_data->image);
+ EXPECT_EQ(KURL(base, kNotificationIcon), notification_data->icon);
+ EXPECT_EQ(KURL(base, kNotificationBadge), notification_data->badge);
+
+ ASSERT_EQ(vibration_pattern.size(),
+ notification_data->vibration_pattern->size());
+ for (size_t i = 0; i < vibration_pattern.size(); ++i) {
+ EXPECT_EQ(
+ vibration_pattern[i],
+ static_cast<unsigned>(notification_data->vibration_pattern.value()[i]));
+ }
+
+ EXPECT_EQ(kNotificationTimestamp, notification_data->timestamp);
+ EXPECT_EQ(kNotificationRenotify, notification_data->renotify);
+ EXPECT_EQ(kNotificationSilent, notification_data->silent);
EXPECT_EQ(kNotificationRequireInteraction,
- notification_data.require_interaction);
- EXPECT_EQ(actions.size(), notification_data.actions.size());
- for (const auto& action : notification_data.actions) {
- EXPECT_EQ(kWebNotificationActionType, action.type);
- EXPECT_EQ(kNotificationActionAction, action.action);
- EXPECT_EQ(kNotificationActionTitle, action.title);
- EXPECT_EQ(kNotificationActionPlaceholder, action.placeholder);
+ notification_data->require_interaction);
+ EXPECT_EQ(actions.size(), notification_data->actions->size());
+ for (const auto& action : notification_data->actions.value()) {
+ EXPECT_EQ(kWebNotificationActionType, action->type);
+ EXPECT_EQ(kNotificationActionAction, action->action);
+ EXPECT_EQ(kNotificationActionTitle, action->title);
+ EXPECT_EQ(kNotificationActionPlaceholder, action->placeholder);
}
}
@@ -164,7 +167,7 @@ TEST_F(NotificationDataTest, SilentNotificationWithVibration) {
options.setSilent(true);
DummyExceptionStateForTesting exception_state;
- WebNotificationData notification_data = CreateWebNotificationData(
+ mojom::blink::NotificationDataPtr notification_data = CreateNotificationData(
GetExecutionContext(), kNotificationTitle, options, exception_state);
ASSERT_TRUE(exception_state.HadException());
@@ -183,7 +186,7 @@ TEST_F(NotificationDataTest, ActionTypeButtonWithPlaceholder) {
options.setActions(actions);
DummyExceptionStateForTesting exception_state;
- WebNotificationData notification_data = CreateWebNotificationData(
+ mojom::blink::NotificationDataPtr notification_data = CreateNotificationData(
GetExecutionContext(), kNotificationTitle, options, exception_state);
ASSERT_TRUE(exception_state.HadException());
@@ -197,7 +200,7 @@ TEST_F(NotificationDataTest, RenotifyWithEmptyTag) {
options.setRenotify(true);
DummyExceptionStateForTesting exception_state;
- WebNotificationData notification_data = CreateWebNotificationData(
+ mojom::blink::NotificationDataPtr notification_data = CreateNotificationData(
GetExecutionContext(), kNotificationTitle, options, exception_state);
ASSERT_TRUE(exception_state.HadException());
@@ -223,15 +226,15 @@ TEST_F(NotificationDataTest, InvalidIconUrls) {
options.setActions(actions);
DummyExceptionStateForTesting exception_state;
- WebNotificationData notification_data = CreateWebNotificationData(
+ mojom::blink::NotificationDataPtr notification_data = CreateNotificationData(
GetExecutionContext(), kNotificationTitle, options, exception_state);
ASSERT_FALSE(exception_state.HadException());
- EXPECT_TRUE(notification_data.image.IsEmpty());
- EXPECT_TRUE(notification_data.icon.IsEmpty());
- EXPECT_TRUE(notification_data.badge.IsEmpty());
- for (const auto& action : notification_data.actions)
- EXPECT_TRUE(action.icon.IsEmpty());
+ EXPECT_TRUE(notification_data->image.IsEmpty());
+ EXPECT_TRUE(notification_data->icon.IsEmpty());
+ EXPECT_TRUE(notification_data->badge.IsEmpty());
+ for (const auto& action : notification_data->actions.value())
+ EXPECT_TRUE(action->icon.IsEmpty());
}
TEST_F(NotificationDataTest, VibrationNormalization) {
@@ -246,7 +249,7 @@ TEST_F(NotificationDataTest, VibrationNormalization) {
options.setVibrate(vibration_sequence);
DummyExceptionStateForTesting exception_state;
- WebNotificationData notification_data = CreateWebNotificationData(
+ mojom::blink::NotificationDataPtr notification_data = CreateNotificationData(
GetExecutionContext(), kNotificationTitle, options, exception_state);
EXPECT_FALSE(exception_state.HadException());
@@ -254,44 +257,48 @@ TEST_F(NotificationDataTest, VibrationNormalization) {
for (size_t i = 0; i < arraysize(kNotificationVibrationNormalized); ++i)
normalized_pattern.push_back(kNotificationVibrationNormalized[i]);
- ASSERT_EQ(normalized_pattern.size(), notification_data.vibrate.size());
- for (size_t i = 0; i < normalized_pattern.size(); ++i)
- EXPECT_EQ(normalized_pattern[i], notification_data.vibrate[i]);
+ ASSERT_EQ(normalized_pattern.size(),
+ notification_data->vibration_pattern->size());
+ for (size_t i = 0; i < normalized_pattern.size(); ++i) {
+ EXPECT_EQ(normalized_pattern[i],
+ notification_data->vibration_pattern.value()[i]);
+ }
}
TEST_F(NotificationDataTest, DefaultTimestampValue) {
NotificationOptions options;
DummyExceptionStateForTesting exception_state;
- WebNotificationData notification_data = CreateWebNotificationData(
+ mojom::blink::NotificationDataPtr notification_data = CreateNotificationData(
GetExecutionContext(), kNotificationTitle, options, exception_state);
EXPECT_FALSE(exception_state.HadException());
// The timestamp should be set to the current time since the epoch if it
// wasn't supplied by the developer. "32" has no significance, but an equal
// comparison of the value could lead to flaky failures.
- EXPECT_NEAR(notification_data.timestamp, WTF::CurrentTimeMS(), 32);
+ EXPECT_NEAR(notification_data->timestamp, WTF::CurrentTimeMS(), 32);
}
TEST_F(NotificationDataTest, DirectionValues) {
- WTF::HashMap<String, WebNotificationData::Direction> mappings;
- mappings.insert("ltr", WebNotificationData::kDirectionLeftToRight);
- mappings.insert("rtl", WebNotificationData::kDirectionRightToLeft);
- mappings.insert("auto", WebNotificationData::kDirectionAuto);
+ WTF::HashMap<String, mojom::blink::NotificationDirection> mappings;
+ mappings.insert("ltr", mojom::blink::NotificationDirection::LEFT_TO_RIGHT);
+ mappings.insert("rtl", mojom::blink::NotificationDirection::RIGHT_TO_LEFT);
+ mappings.insert("auto", mojom::blink::NotificationDirection::AUTO);
// Invalid values should default to "auto".
- mappings.insert("peter", WebNotificationData::kDirectionAuto);
+ mappings.insert("peter", mojom::blink::NotificationDirection::AUTO);
for (const String& direction : mappings.Keys()) {
NotificationOptions options;
options.setDir(direction);
DummyExceptionStateForTesting exception_state;
- WebNotificationData notification_data = CreateWebNotificationData(
- GetExecutionContext(), kNotificationTitle, options, exception_state);
+ mojom::blink::NotificationDataPtr notification_data =
+ CreateNotificationData(GetExecutionContext(), kNotificationTitle,
+ options, exception_state);
ASSERT_FALSE(exception_state.HadException());
- EXPECT_EQ(mappings.at(direction), notification_data.direction);
+ EXPECT_EQ(mappings.at(direction), notification_data->direction);
}
}
@@ -309,16 +316,16 @@ TEST_F(NotificationDataTest, MaximumActionCount) {
options.setActions(actions);
DummyExceptionStateForTesting exception_state;
- WebNotificationData notification_data = CreateWebNotificationData(
+ mojom::blink::NotificationDataPtr notification_data = CreateNotificationData(
GetExecutionContext(), kNotificationTitle, options, exception_state);
ASSERT_FALSE(exception_state.HadException());
// The stored actions will be capped to |maxActions| entries.
- ASSERT_EQ(Notification::maxActions(), notification_data.actions.size());
+ ASSERT_EQ(Notification::maxActions(), notification_data->actions->size());
for (size_t i = 0; i < Notification::maxActions(); ++i) {
- WebString expected_action = String::Number(i);
- EXPECT_EQ(expected_action, notification_data.actions[i].action);
+ String expected_action = String::Number(i);
+ EXPECT_EQ(expected_action, notification_data->actions.value()[i]->action);
}
}
diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification_image_loader.cc b/chromium/third_party/blink/renderer/modules/notifications/notification_image_loader.cc
index 164d95d543a..fffba5f48a7 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/notification_image_loader.cc
+++ b/chromium/third_party/blink/renderer/modules/notifications/notification_image_loader.cc
@@ -106,9 +106,6 @@ void NotificationImageLoader::Start(ExecutionContext* context,
start_time_ = CurrentTimeTicks();
image_callback_ = std::move(image_callback);
- ThreadableLoaderOptions threadable_loader_options;
- threadable_loader_options.timeout_milliseconds = kImageFetchTimeoutInMs;
-
// TODO(mvanouwerkerk): Add an entry for notifications to
// FetchInitiatorTypeNames and use it.
ResourceLoaderOptions resource_loader_options;
@@ -120,8 +117,10 @@ void NotificationImageLoader::Start(ExecutionContext* context,
resource_request.SetPriority(ResourceLoadPriority::kMedium);
resource_request.SetRequestorOrigin(context->GetSecurityOrigin());
- threadable_loader_ = ThreadableLoader::Create(
- *context, this, threadable_loader_options, resource_loader_options);
+ threadable_loader_ = new ThreadableLoader(
+ *context, this, resource_loader_options);
+ threadable_loader_->SetTimeout(
+ TimeDelta::FromMilliseconds(kImageFetchTimeoutInMs));
threadable_loader_->Start(resource_request);
}
diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification_image_loader_test.cc b/chromium/third_party/blink/renderer/modules/notifications/notification_image_loader_test.cc
index e4654d0d46b..1495b7fe57c 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/notification_image_loader_test.cc
+++ b/chromium/third_party/blink/renderer/modules/notifications/notification_image_loader_test.cc
@@ -11,7 +11,6 @@
#include "third_party/blink/renderer/core/testing/page_test_base.h"
#include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h"
#include "third_party/blink/renderer/platform/testing/histogram_tester.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/testing/url_test_helpers.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
@@ -40,11 +39,13 @@ class NotificationImageLoaderTest : public PageTestBase {
// use.
loader_(
new NotificationImageLoader(NotificationImageLoader::Type::kIcon)) {
+ EnablePlatform();
}
~NotificationImageLoaderTest() override {
loader_->Stop();
- platform_->GetURLLoaderMockFactory()
+ platform()
+ ->GetURLLoaderMockFactory()
->UnregisterAllURLsAndClearMemoryCache();
}
@@ -80,7 +81,6 @@ class NotificationImageLoaderTest : public PageTestBase {
protected:
HistogramTester histogram_tester_;
- ScopedTestingPlatformSupport<TestingPlatformSupport> platform_;
private:
Persistent<NotificationImageLoader> loader_;
@@ -93,7 +93,7 @@ TEST_F(NotificationImageLoaderTest, SuccessTest) {
histogram_tester_.ExpectTotalCount("Notifications.LoadFinishTime.Icon", 0);
histogram_tester_.ExpectTotalCount("Notifications.LoadFileSize.Icon", 0);
histogram_tester_.ExpectTotalCount("Notifications.LoadFailTime.Icon", 0);
- platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
+ platform()->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
EXPECT_EQ(NotificationLoadState::kLoadSuccessful, Loaded());
histogram_tester_.ExpectTotalCount("Notifications.LoadFinishTime.Icon", 1);
histogram_tester_.ExpectUniqueSample("Notifications.LoadFileSize.Icon", 7439,
@@ -102,9 +102,6 @@ TEST_F(NotificationImageLoaderTest, SuccessTest) {
}
TEST_F(NotificationImageLoaderTest, TimeoutTest) {
- ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
- platform;
-
// To test for a timeout, this needs to override the clock in the platform.
// Just creating the mock platform will do everything to set it up.
KURL url = RegisterMockedURL(kNotificationImageLoaderIcon500x500);
@@ -112,14 +109,14 @@ TEST_F(NotificationImageLoaderTest, TimeoutTest) {
// Run the platform for kImageFetchTimeoutInMs-1 seconds. This should not
// result in a timeout.
- platform->RunForPeriodSeconds(kImageFetchTimeoutInMs / 1000 - 1);
+ platform()->RunForPeriodSeconds(kImageFetchTimeoutInMs / 1000 - 1);
EXPECT_EQ(NotificationLoadState::kNotLoaded, Loaded());
histogram_tester_.ExpectTotalCount("Notifications.LoadFinishTime.Icon", 0);
histogram_tester_.ExpectTotalCount("Notifications.LoadFileSize.Icon", 0);
histogram_tester_.ExpectTotalCount("Notifications.LoadFailTime.Icon", 0);
// Now advance time until a timeout should be expected.
- platform->RunForPeriodSeconds(2);
+ platform()->RunForPeriodSeconds(2);
// If the loader times out, it calls the callback and returns an empty bitmap.
EXPECT_EQ(NotificationLoadState::kLoadFailed, Loaded());
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 f5656f2aa92..21d3be41d51 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/notification_manager.cc
+++ b/chromium/third_party/blink/renderer/modules/notifications/notification_manager.cc
@@ -7,7 +7,6 @@
#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/blink/public/platform/interface_provider.h"
#include "third_party/blink/public/platform/modules/notifications/notification.mojom-blink.h"
-#include "third_party/blink/public/platform/modules/notifications/web_notification_data.h"
#include "third_party/blink/public/platform/modules/permissions/permission.mojom-blink.h"
#include "third_party/blink/public/platform/modules/permissions/permission_status.mojom-blink.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_registration.h"
@@ -114,13 +113,13 @@ void NotificationManager::OnPermissionServiceConnectionError() {
void NotificationManager::DisplayNonPersistentNotification(
const String& token,
- const WebNotificationData& notification_data,
- std::unique_ptr<WebNotificationResources> notification_resources,
+ mojom::blink::NotificationDataPtr notification_data,
+ mojom::blink::NotificationResourcesPtr notification_resources,
mojom::blink::NonPersistentNotificationListenerPtr event_listener) {
DCHECK(!token.IsEmpty());
DCHECK(notification_resources);
GetNotificationService()->DisplayNonPersistentNotification(
- token, notification_data, *notification_resources,
+ token, std::move(notification_data), std::move(notification_resources),
std::move(event_listener));
}
@@ -131,12 +130,17 @@ void NotificationManager::CloseNonPersistentNotification(const String& token) {
void NotificationManager::DisplayPersistentNotification(
blink::WebServiceWorkerRegistration* service_worker_registration,
- const blink::WebNotificationData& notification_data,
- std::unique_ptr<blink::WebNotificationResources> notification_resources,
+ mojom::blink::NotificationDataPtr notification_data,
+ mojom::blink::NotificationResourcesPtr notification_resources,
ScriptPromiseResolver* resolver) {
+ DCHECK(notification_data);
DCHECK(notification_resources);
- DCHECK_EQ(notification_data.actions.size(),
- notification_resources->action_icons.size());
+ DCHECK_EQ(notification_data->actions.has_value()
+ ? notification_data->actions->size()
+ : 0,
+ notification_resources->action_icons.has_value()
+ ? notification_resources->action_icons->size()
+ : 0);
// Verify that the author-provided payload size does not exceed our limit.
// This is an implementation-defined limit to prevent abuse of notification
@@ -146,7 +150,8 @@ void NotificationManager::DisplayPersistentNotification(
// If the size exceeds this limit, reject the showNotification() promise. This
// is outside of the boundaries set by the specification, but it gives authors
// an indication that something has gone wrong.
- size_t author_data_size = notification_data.data.size();
+ 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,
@@ -160,8 +165,8 @@ void NotificationManager::DisplayPersistentNotification(
}
GetNotificationService()->DisplayPersistentNotification(
- service_worker_registration->RegistrationId(), notification_data,
- *notification_resources,
+ service_worker_registration->RegistrationId(),
+ std::move(notification_data), std::move(notification_resources),
WTF::Bind(&NotificationManager::DidDisplayPersistentNotification,
WrapPersistent(this), WrapPersistent(resolver)));
}
@@ -200,7 +205,7 @@ void NotificationManager::GetNotifications(
void NotificationManager::DidGetNotifications(
ScriptPromiseResolver* resolver,
const Vector<String>& notification_ids,
- const Vector<WebNotificationData>& notification_datas) {
+ Vector<mojom::blink::NotificationDataPtr> notification_datas) {
DCHECK_EQ(notification_ids.size(), notification_datas.size());
HeapVector<Member<Notification>> notifications;
@@ -209,7 +214,7 @@ void NotificationManager::DidGetNotifications(
for (size_t i = 0; i < notification_ids.size(); ++i) {
notifications.push_back(Notification::Create(
resolver->GetExecutionContext(), notification_ids[i],
- notification_datas[i], true /* showing */));
+ std::move(notification_datas[i]), true /* showing */));
}
resolver->Resolve(notifications);
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 412a6c506bb..988715534ee 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/notification_manager.h
+++ b/chromium/third_party/blink/renderer/modules/notifications/notification_manager.h
@@ -7,6 +7,7 @@
#include "third_party/blink/public/platform/modules/notifications/notification_service.mojom-blink.h"
#include "third_party/blink/public/platform/modules/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/wtf/noncopyable.h"
@@ -18,7 +19,6 @@ class ScriptPromise;
class ScriptPromiseResolver;
class ScriptState;
class WebServiceWorkerRegistration;
-struct WebNotificationData;
// The notification manager, unique to the execution context, is responsible for
// connecting and communicating with the Mojo notification service.
@@ -52,8 +52,8 @@ class NotificationManager final
// else displays a new notification.
void DisplayNonPersistentNotification(
const String& token,
- const WebNotificationData& notification_data,
- std::unique_ptr<WebNotificationResources> notification_resources,
+ mojom::blink::NotificationDataPtr notification_data,
+ mojom::blink::NotificationResourcesPtr notification_resources,
mojom::blink::NonPersistentNotificationListenerPtr event_listener);
// Closes the notification that was most recently displayed with this token.
@@ -62,8 +62,8 @@ class NotificationManager final
// Shows a notification from a service worker.
void DisplayPersistentNotification(
blink::WebServiceWorkerRegistration* service_worker_registration,
- const blink::WebNotificationData& notification_data,
- std::unique_ptr<blink::WebNotificationResources> notification_resources,
+ mojom::blink::NotificationDataPtr notification_data,
+ mojom::blink::NotificationResourcesPtr notification_resources,
ScriptPromiseResolver* resolver);
// Closes a persistent notification identified by its notification id.
@@ -71,8 +71,7 @@ class NotificationManager final
// Asynchronously gets the persistent notifications belonging to the Service
// Worker Registration. If |filter_tag| is not an empty string, only the
- // notification with the given tag will be considered. Will take ownership of
- // the WebNotificationGetCallbacks object.
+ // notification with the given tag will be considered.
void GetNotifications(
WebServiceWorkerRegistration* service_worker_registration,
const WebString& filter_tag,
@@ -90,7 +89,7 @@ class NotificationManager final
void DidGetNotifications(
ScriptPromiseResolver* resolver,
const Vector<String>& notification_ids,
- const Vector<WebNotificationData>& notification_datas);
+ Vector<mojom::blink::NotificationDataPtr> notification_datas);
// Returns an initialized NotificationServicePtr. A connection will be
// established the first time this method is called.
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 fda5091b296..9e861a7858d 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
@@ -5,8 +5,6 @@
#include "third_party/blink/renderer/modules/notifications/notification_resources_loader.h"
#include <cmath>
-#include "third_party/blink/public/platform/modules/notifications/web_notification_data.h"
-#include "third_party/blink/public/platform/modules/notifications/web_notification_resources.h"
#include "third_party/blink/renderer/platform/histogram.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/threading.h"
@@ -26,11 +24,13 @@ NotificationResourcesLoader::~NotificationResourcesLoader() = default;
void NotificationResourcesLoader::Start(
ExecutionContext* context,
- const WebNotificationData& notification_data) {
+ const mojom::blink::NotificationData& notification_data) {
DCHECK(!started_);
started_ = true;
- size_t num_actions = notification_data.actions.size();
+ size_t num_actions = notification_data.actions.has_value()
+ ? notification_data.actions->size()
+ : 0;
pending_request_count_ = 3 /* image, icon, badge */ + num_actions;
// TODO(johnme): ensure image is not loaded when it will not be used.
@@ -51,15 +51,14 @@ void NotificationResourcesLoader::Start(
action_icons_.resize(num_actions);
for (size_t i = 0; i < num_actions; i++)
LoadImage(context, NotificationImageLoader::Type::kActionIcon,
- notification_data.actions[i].icon,
+ notification_data.actions.value()[i]->icon,
WTF::Bind(&NotificationResourcesLoader::DidLoadActionIcon,
WrapWeakPersistent(this), i));
}
-std::unique_ptr<WebNotificationResources>
+mojom::blink::NotificationResourcesPtr
NotificationResourcesLoader::GetResources() const {
- std::unique_ptr<WebNotificationResources> resources(
- new WebNotificationResources());
+ auto resources = mojom::blink::NotificationResources::New();
resources->image = image_;
resources->icon = icon_;
resources->badge = badge_;
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 8087fd800fe..f9b3e5fa784 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
@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_NOTIFICATIONS_NOTIFICATION_RESOURCES_LOADER_H_
#include <memory>
+#include "third_party/blink/public/platform/modules/notifications/notification.mojom-blink.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/notifications/notification_image_loader.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
@@ -19,10 +20,8 @@
namespace blink {
class ExecutionContext;
-struct WebNotificationData;
-struct WebNotificationResources;
-// Fetches the resources specified in a given WebNotificationData. Uses a
+// Fetches the resources specified in a given NotificationData. Uses a
// callback to notify the caller when all fetches have finished.
class MODULES_EXPORT NotificationResourcesLoader final
: public GarbageCollectedFinalized<NotificationResourcesLoader> {
@@ -38,17 +37,17 @@ class MODULES_EXPORT NotificationResourcesLoader final
explicit NotificationResourcesLoader(CompletionCallback completion_callback);
~NotificationResourcesLoader();
- // Starts fetching the resources specified in the given WebNotificationData.
+ // Starts fetching the resources specified in the given NotificationData.
// If all the urls for the resources are empty or invalid,
// |m_completionCallback| will be run synchronously, otherwise it will be
// run asynchronously when all fetches have finished. Should not be called
// more than once.
void Start(ExecutionContext* context,
- const WebNotificationData& notification_data);
+ const mojom::blink::NotificationData& notification_data);
- // Returns a new WebNotificationResources populated with the resources that
+ // Returns a new NotificationResourcesPtr populated with the resources that
// have been fetched.
- std::unique_ptr<WebNotificationResources> GetResources() const;
+ mojom::blink::NotificationResourcesPtr GetResources() const;
// Stops every loader in |m_imageLoaders|. This is also used as the
// pre-finalizer.
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 15da9918ec8..860dcad26ad 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
@@ -7,11 +7,7 @@
#include <memory>
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/modules/notifications/web_notification_constants.h"
-#include "third_party/blink/public/platform/modules/notifications/web_notification_data.h"
-#include "third_party/blink/public/platform/modules/notifications/web_notification_resources.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/public/platform/web_url_response.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h"
@@ -55,7 +51,9 @@ class NotificationResourcesLoaderTest : public PageTestBase {
NotificationResourcesLoader* Loader() const { return loader_.Get(); }
- WebNotificationResources* Resources() const { return resources_.get(); }
+ const mojom::blink::NotificationResources* Resources() const {
+ return resources_.get();
+ }
void DidFetchResources(NotificationResourcesLoader* loader) {
resources_ = loader->GetResources();
@@ -63,8 +61,8 @@ class NotificationResourcesLoaderTest : public PageTestBase {
// Registers a mocked url. When fetched, |fileName| will be loaded from the
// test data directory.
- WebURL RegisterMockedURL(const String& file_name) {
- WebURL registered_url = URLTestHelpers::RegisterMockedURLLoadFromBase(
+ KURL RegisterMockedURL(const String& file_name) {
+ KURL registered_url = URLTestHelpers::RegisterMockedURLLoadFromBase(
kResourcesLoaderBaseUrl,
test::CoreTestDataPath(kResourcesLoaderBaseDir), file_name,
"image/png");
@@ -72,8 +70,8 @@ class NotificationResourcesLoaderTest : public PageTestBase {
}
// Registers a mocked url that will fail to be fetched, with a 404 error.
- WebURL RegisterMockedErrorURL(const String& file_name) {
- WebURL url(KURL(kResourcesLoaderBaseUrl + file_name));
+ KURL RegisterMockedErrorURL(const String& file_name) {
+ KURL url(kResourcesLoaderBaseUrl + file_name);
URLTestHelpers::RegisterMockedErrorURLLoad(url);
return url;
}
@@ -82,24 +80,27 @@ class NotificationResourcesLoaderTest : public PageTestBase {
private:
Persistent<NotificationResourcesLoader> loader_;
- std::unique_ptr<WebNotificationResources> resources_;
+ mojom::blink::NotificationResourcesPtr resources_;
};
TEST_F(NotificationResourcesLoaderTest, LoadMultipleResources) {
- WebNotificationData notification_data;
- notification_data.image = RegisterMockedURL(kResourcesLoaderIcon500x500);
- notification_data.icon = RegisterMockedURL(kResourcesLoaderIcon100x100);
- notification_data.badge = RegisterMockedURL(kResourcesLoaderIcon48x48);
- notification_data.actions =
- WebVector<WebNotificationAction>(static_cast<size_t>(2));
- notification_data.actions[0].icon =
+ auto notification_data = mojom::blink::NotificationData::New();
+ notification_data->image = RegisterMockedURL(kResourcesLoaderIcon500x500);
+ notification_data->icon = RegisterMockedURL(kResourcesLoaderIcon100x100);
+ notification_data->badge = RegisterMockedURL(kResourcesLoaderIcon48x48);
+ notification_data->actions = Vector<mojom::blink::NotificationActionPtr>();
+ notification_data->actions->push_back(
+ mojom::blink::NotificationAction::New());
+ notification_data->actions.value()[0]->icon =
RegisterMockedURL(kResourcesLoaderIcon110x110);
- notification_data.actions[1].icon =
+ notification_data->actions->push_back(
+ mojom::blink::NotificationAction::New());
+ notification_data->actions.value()[1]->icon =
RegisterMockedURL(kResourcesLoaderIcon120x120);
ASSERT_FALSE(Resources());
- Loader()->Start(GetExecutionContext(), notification_data);
+ Loader()->Start(GetExecutionContext(), *notification_data);
platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
ASSERT_TRUE(Resources());
@@ -114,24 +115,27 @@ TEST_F(NotificationResourcesLoaderTest, LoadMultipleResources) {
ASSERT_FALSE(Resources()->badge.drawsNothing());
ASSERT_EQ(48, Resources()->badge.width());
- ASSERT_EQ(2u, Resources()->action_icons.size());
- ASSERT_FALSE(Resources()->action_icons[0].drawsNothing());
- ASSERT_EQ(110, Resources()->action_icons[0].width());
- ASSERT_FALSE(Resources()->action_icons[1].drawsNothing());
- ASSERT_EQ(120, Resources()->action_icons[1].width());
+ ASSERT_TRUE(Resources()->action_icons.has_value());
+ auto& action_icons = Resources()->action_icons.value();
+ ASSERT_EQ(2u, action_icons.size());
+ ASSERT_FALSE(action_icons[0].drawsNothing());
+ ASSERT_EQ(110, action_icons[0].width());
+ ASSERT_FALSE(action_icons[1].drawsNothing());
+ ASSERT_EQ(120, action_icons[1].width());
}
TEST_F(NotificationResourcesLoaderTest, LargeIconsAreScaledDown) {
- WebNotificationData notification_data;
- notification_data.icon = RegisterMockedURL(kResourcesLoaderIcon500x500);
- notification_data.badge = notification_data.icon;
- notification_data.actions =
- WebVector<WebNotificationAction>(static_cast<size_t>(1));
- notification_data.actions[0].icon = notification_data.icon;
+ auto notification_data = mojom::blink::NotificationData::New();
+ notification_data->icon = RegisterMockedURL(kResourcesLoaderIcon500x500);
+ notification_data->badge = notification_data->icon;
+ notification_data->actions = Vector<mojom::blink::NotificationActionPtr>();
+ notification_data->actions->push_back(
+ mojom::blink::NotificationAction::New());
+ notification_data->actions.value()[0]->icon = notification_data->icon;
ASSERT_FALSE(Resources());
- Loader()->Start(GetExecutionContext(), notification_data);
+ Loader()->Start(GetExecutionContext(), *notification_data);
platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
ASSERT_TRUE(Resources());
@@ -144,21 +148,21 @@ TEST_F(NotificationResourcesLoaderTest, LargeIconsAreScaledDown) {
ASSERT_EQ(kWebNotificationMaxBadgeSizePx, Resources()->badge.width());
ASSERT_EQ(kWebNotificationMaxBadgeSizePx, Resources()->badge.height());
- ASSERT_EQ(1u, Resources()->action_icons.size());
- ASSERT_FALSE(Resources()->action_icons[0].drawsNothing());
- ASSERT_EQ(kWebNotificationMaxActionIconSizePx,
- Resources()->action_icons[0].width());
- ASSERT_EQ(kWebNotificationMaxActionIconSizePx,
- Resources()->action_icons[0].height());
+ ASSERT_TRUE(Resources()->action_icons.has_value());
+ auto& action_icons = Resources()->action_icons.value();
+ ASSERT_EQ(1u, action_icons.size());
+ ASSERT_FALSE(action_icons[0].drawsNothing());
+ ASSERT_EQ(kWebNotificationMaxActionIconSizePx, action_icons[0].width());
+ ASSERT_EQ(kWebNotificationMaxActionIconSizePx, action_icons[0].height());
}
TEST_F(NotificationResourcesLoaderTest, DownscalingPreserves3_1AspectRatio) {
- WebNotificationData notification_data;
- notification_data.image = RegisterMockedURL(kResourcesLoaderIcon3000x1000);
+ auto notification_data = mojom::blink::NotificationData::New();
+ notification_data->image = RegisterMockedURL(kResourcesLoaderIcon3000x1000);
ASSERT_FALSE(Resources());
- Loader()->Start(GetExecutionContext(), notification_data);
+ Loader()->Start(GetExecutionContext(), *notification_data);
platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
ASSERT_TRUE(Resources());
@@ -169,12 +173,12 @@ TEST_F(NotificationResourcesLoaderTest, DownscalingPreserves3_1AspectRatio) {
}
TEST_F(NotificationResourcesLoaderTest, DownscalingPreserves3_2AspectRatio) {
- WebNotificationData notification_data;
- notification_data.image = RegisterMockedURL(kResourcesLoaderIcon3000x2000);
+ auto notification_data = mojom::blink::NotificationData::New();
+ notification_data->image = RegisterMockedURL(kResourcesLoaderIcon3000x2000);
ASSERT_FALSE(Resources());
- Loader()->Start(GetExecutionContext(), notification_data);
+ Loader()->Start(GetExecutionContext(), *notification_data);
platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
ASSERT_TRUE(Resources());
@@ -186,11 +190,11 @@ TEST_F(NotificationResourcesLoaderTest, DownscalingPreserves3_2AspectRatio) {
}
TEST_F(NotificationResourcesLoaderTest, EmptyDataYieldsEmptyResources) {
- WebNotificationData notification_data;
+ auto notification_data = mojom::blink::NotificationData::New();
ASSERT_FALSE(Resources());
- Loader()->Start(GetExecutionContext(), notification_data);
+ Loader()->Start(GetExecutionContext(), *notification_data);
platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
ASSERT_TRUE(Resources());
@@ -198,21 +202,22 @@ TEST_F(NotificationResourcesLoaderTest, EmptyDataYieldsEmptyResources) {
ASSERT_TRUE(Resources()->image.drawsNothing());
ASSERT_TRUE(Resources()->icon.drawsNothing());
ASSERT_TRUE(Resources()->badge.drawsNothing());
- ASSERT_EQ(0u, Resources()->action_icons.size());
+ ASSERT_EQ(0u, Resources()->action_icons.value().size());
}
TEST_F(NotificationResourcesLoaderTest, EmptyResourcesIfAllImagesFailToLoad) {
- WebNotificationData notification_data;
- notification_data.image = notification_data.icon;
- notification_data.icon = RegisterMockedErrorURL(kResourcesLoaderIcon100x100);
- notification_data.badge = notification_data.icon;
- notification_data.actions =
- WebVector<WebNotificationAction>(static_cast<size_t>(1));
- notification_data.actions[0].icon = notification_data.icon;
+ auto notification_data = mojom::blink::NotificationData::New();
+ notification_data->icon = RegisterMockedErrorURL(kResourcesLoaderIcon100x100);
+ notification_data->image = notification_data->icon;
+ notification_data->badge = notification_data->icon;
+ notification_data->actions = Vector<mojom::blink::NotificationActionPtr>();
+ notification_data->actions->push_back(
+ mojom::blink::NotificationAction::New());
+ notification_data->actions.value()[0]->icon = notification_data->icon;
ASSERT_FALSE(Resources());
- Loader()->Start(GetExecutionContext(), notification_data);
+ Loader()->Start(GetExecutionContext(), *notification_data);
platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
ASSERT_TRUE(Resources());
@@ -222,18 +227,18 @@ TEST_F(NotificationResourcesLoaderTest, EmptyResourcesIfAllImagesFailToLoad) {
ASSERT_TRUE(Resources()->image.drawsNothing());
ASSERT_TRUE(Resources()->icon.drawsNothing());
ASSERT_TRUE(Resources()->badge.drawsNothing());
- ASSERT_EQ(1u, Resources()->action_icons.size());
- ASSERT_TRUE(Resources()->action_icons[0].drawsNothing());
+ ASSERT_EQ(1u, Resources()->action_icons.value().size());
+ ASSERT_TRUE(Resources()->action_icons.value()[0].drawsNothing());
}
TEST_F(NotificationResourcesLoaderTest, OneImageFailsToLoad) {
- WebNotificationData notification_data;
- notification_data.icon = RegisterMockedURL(kResourcesLoaderIcon100x100);
- notification_data.badge = RegisterMockedErrorURL(kResourcesLoaderIcon48x48);
+ auto notification_data = mojom::blink::NotificationData::New();
+ notification_data->icon = RegisterMockedURL(kResourcesLoaderIcon100x100);
+ notification_data->badge = RegisterMockedErrorURL(kResourcesLoaderIcon48x48);
ASSERT_FALSE(Resources());
- Loader()->Start(GetExecutionContext(), notification_data);
+ Loader()->Start(GetExecutionContext(), *notification_data);
platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
ASSERT_TRUE(Resources());
@@ -244,24 +249,27 @@ TEST_F(NotificationResourcesLoaderTest, OneImageFailsToLoad) {
ASSERT_FALSE(Resources()->icon.drawsNothing());
ASSERT_EQ(100, Resources()->icon.width());
ASSERT_TRUE(Resources()->badge.drawsNothing());
- ASSERT_EQ(0u, Resources()->action_icons.size());
+ ASSERT_EQ(0u, Resources()->action_icons.value().size());
}
TEST_F(NotificationResourcesLoaderTest, StopYieldsNoResources) {
- WebNotificationData notification_data;
- notification_data.image = RegisterMockedURL(kResourcesLoaderIcon500x500);
- notification_data.icon = RegisterMockedURL(kResourcesLoaderIcon100x100);
- notification_data.badge = RegisterMockedURL(kResourcesLoaderIcon48x48);
- notification_data.actions =
- WebVector<WebNotificationAction>(static_cast<size_t>(2));
- notification_data.actions[0].icon =
+ auto notification_data = mojom::blink::NotificationData::New();
+ notification_data->image = RegisterMockedURL(kResourcesLoaderIcon500x500);
+ notification_data->icon = RegisterMockedURL(kResourcesLoaderIcon100x100);
+ notification_data->badge = RegisterMockedURL(kResourcesLoaderIcon48x48);
+ notification_data->actions = Vector<mojom::blink::NotificationActionPtr>();
+ notification_data->actions->push_back(
+ mojom::blink::NotificationAction::New());
+ notification_data->actions.value()[0]->icon =
RegisterMockedURL(kResourcesLoaderIcon110x110);
- notification_data.actions[1].icon =
+ notification_data->actions->push_back(
+ mojom::blink::NotificationAction::New());
+ notification_data->actions.value()[1]->icon =
RegisterMockedURL(kResourcesLoaderIcon120x120);
ASSERT_FALSE(Resources());
- Loader()->Start(GetExecutionContext(), notification_data);
+ Loader()->Start(GetExecutionContext(), *notification_data);
// Check that starting the loader did not synchronously fail, providing
// empty resources. The requests should be pending now.
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 48055401b08..72dba71a5f7 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
@@ -6,7 +6,6 @@
#include <utility>
#include "base/memory/scoped_refptr.h"
-#include "third_party/blink/public/platform/modules/notifications/web_notification_data.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_security_origin.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
@@ -55,8 +54,8 @@ ScriptPromise ServiceWorkerRegistrationNotifications::showNotification(
return ScriptPromise();
}
- // Validate the developer-provided options to get the WebNotificationData.
- WebNotificationData data = CreateWebNotificationData(
+ // Validate the developer-provided options to get the NotificationData.
+ mojom::blink::NotificationDataPtr data = CreateNotificationData(
execution_context, title, options, exception_state);
if (exception_state.HadException())
return ScriptPromise();
@@ -74,7 +73,7 @@ ScriptPromise ServiceWorkerRegistrationNotifications::showNotification(
ScriptPromise promise = resolver->Promise();
ServiceWorkerRegistrationNotifications::From(execution_context, registration)
- .PrepareShow(data, resolver);
+ .PrepareShow(std::move(data), resolver);
return promise;
}
@@ -125,28 +124,28 @@ ServiceWorkerRegistrationNotifications::From(
}
void ServiceWorkerRegistrationNotifications::PrepareShow(
- const WebNotificationData& data,
+ mojom::blink::NotificationDataPtr data,
ScriptPromiseResolver* resolver) {
scoped_refptr<const SecurityOrigin> origin =
GetExecutionContext()->GetSecurityOrigin();
NotificationResourcesLoader* loader = new NotificationResourcesLoader(
WTF::Bind(&ServiceWorkerRegistrationNotifications::DidLoadResources,
- WrapWeakPersistent(this), std::move(origin), data,
+ WrapWeakPersistent(this), std::move(origin), data->Clone(),
WrapPersistent(resolver)));
loaders_.insert(loader);
- loader->Start(GetExecutionContext(), data);
+ loader->Start(GetExecutionContext(), *data);
}
void ServiceWorkerRegistrationNotifications::DidLoadResources(
scoped_refptr<const SecurityOrigin> origin,
- const WebNotificationData& data,
+ mojom::blink::NotificationDataPtr data,
ScriptPromiseResolver* resolver,
NotificationResourcesLoader* loader) {
DCHECK(loaders_.Contains(loader));
NotificationManager::From(GetExecutionContext())
- ->DisplayPersistentNotification(registration_->WebRegistration(), data,
- loader->GetResources(),
+ ->DisplayPersistentNotification(registration_->WebRegistration(),
+ std::move(data), loader->GetResources(),
WrapPersistent(resolver));
loaders_.erase(loader);
}
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 995219c7203..4af07fde36b 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
@@ -7,6 +7,7 @@
#include <memory>
#include "base/memory/scoped_refptr.h"
+#include "third_party/blink/public/platform/modules/notifications/notification.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
@@ -26,7 +27,6 @@ class ScriptPromiseResolver;
class ScriptState;
class SecurityOrigin;
class ServiceWorkerRegistration;
-struct WebNotificationData;
class ServiceWorkerRegistrationNotifications final
: public GarbageCollected<ServiceWorkerRegistrationNotifications>,
@@ -60,11 +60,11 @@ class ServiceWorkerRegistrationNotifications final
ExecutionContext* context,
ServiceWorkerRegistration& registration);
- void PrepareShow(const WebNotificationData& data,
+ void PrepareShow(mojom::blink::NotificationDataPtr data,
ScriptPromiseResolver* resolver);
void DidLoadResources(scoped_refptr<const SecurityOrigin> origin,
- const WebNotificationData& data,
+ mojom::blink::NotificationDataPtr data,
ScriptPromiseResolver* resolver,
NotificationResourcesLoader* loader);
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 48d74181632..f764cbd7214 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
@@ -5,7 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_BASIC_CARD_HELPER_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_BASIC_CARD_HELPER_H_
-#include "third_party/blink/public/platform/modules/payments/payment_request.mojom-blink.h"
+#include "third_party/blink/public/mojom/payments/payment_request.mojom-blink.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_address.h b/chromium/third_party/blink/renderer/modules/payments/payment_address.h
index 2a6d3a0fe54..f993e0f8397 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_address.h
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_address.h
@@ -5,7 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_PAYMENT_ADDRESS_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_PAYMENT_ADDRESS_H_
-#include "third_party/blink/public/platform/modules/payments/payment_request.mojom-blink.h"
+#include "third_party/blink/public/mojom/payments/payment_request.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_details_modifier.idl b/chromium/third_party/blink/renderer/modules/payments/payment_details_modifier.idl
index 9eb92085538..b59f2e2ad9f 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_details_modifier.idl
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_details_modifier.idl
@@ -8,5 +8,5 @@ dictionary PaymentDetailsModifier {
[ImplementedAs=supportedMethod] required DOMString supportedMethods;
PaymentItem total;
sequence<PaymentItem> additionalDisplayItems;
- [RuntimeEnabled=PaymentDetailsModifierData] object data;
+ object data;
};
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 a0a30bf7a90..3c0e57ec11f 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_instruments.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_instruments.cc
@@ -94,6 +94,52 @@ ScriptPromise RejectNotAllowedToUsePaymentFeatures(ScriptState* script_state) {
} // namespace
+// Class used to convert the placement only |PaymentInstrument| to
+// GarbageCollected, so it can be used in WTF::Bind. Otherwise, on-heap objects
+// referenced by |PaymentInstrument| will not be traced through the callback and
+// can be prematurely destroyed.
+// TODO(keishi): Remove this conversion if IDLDictionaryBase situation changes.
+class PaymentInstrumentParameter
+ : public GarbageCollectedFinalized<PaymentInstrumentParameter> {
+ public:
+ explicit PaymentInstrumentParameter(const PaymentInstrument& instrument)
+ : has_icons_(instrument.hasIcons()),
+ has_capabilities_(instrument.hasCapabilities()),
+ has_method_(instrument.hasMethod()),
+ has_name_(instrument.hasName()),
+ capabilities_(instrument.capabilities()),
+ method_(instrument.method()),
+ name_(instrument.name()) {
+ if (has_icons_)
+ icons_ = instrument.icons();
+ }
+
+ bool has_capabilities() const { return has_capabilities_; }
+ ScriptValue capabilities() const { return capabilities_; }
+
+ bool has_icons() const { return has_icons_; }
+ const HeapVector<ImageObject>& icons() const { return icons_; }
+
+ bool has_method() const { return has_method_; }
+ const String& method() const { return method_; }
+
+ bool has_name() const { return has_name_; }
+ const String& name() const { return name_; }
+
+ void Trace(blink::Visitor* visitor) { visitor->Trace(icons_); }
+
+ private:
+ bool has_icons_;
+ bool has_capabilities_;
+ bool has_method_;
+ bool has_name_;
+
+ ScriptValue capabilities_;
+ HeapVector<ImageObject> icons_;
+ String method_;
+ String name_;
+};
+
PaymentInstruments::PaymentInstruments(
const payments::mojom::blink::PaymentManagerPtr& manager)
: manager_(manager) {}
@@ -207,7 +253,8 @@ ScriptPromise PaymentInstruments::set(ScriptState* script_state,
Frame::HasTransientUserActivation(doc ? doc->GetFrame() : nullptr),
WTF::Bind(&PaymentInstruments::OnRequestPermission,
WrapPersistent(this), WrapPersistent(resolver),
- instrument_key, details));
+ instrument_key,
+ WrapPersistent(new PaymentInstrumentParameter(details))));
return resolver->Promise();
}
@@ -242,7 +289,7 @@ mojom::blink::PermissionService* PaymentInstruments::GetPermissionService(
void PaymentInstruments::OnRequestPermission(
ScriptPromiseResolver* resolver,
const String& instrument_key,
- const PaymentInstrument& details,
+ PaymentInstrumentParameter* details,
mojom::blink::PermissionStatus status) {
DCHECK(resolver);
if (!resolver->GetExecutionContext() ||
@@ -260,11 +307,12 @@ void PaymentInstruments::OnRequestPermission(
payments::mojom::blink::PaymentInstrumentPtr instrument =
payments::mojom::blink::PaymentInstrument::New();
- instrument->name = details.hasName() ? details.name() : WTF::g_empty_string;
- if (details.hasIcons()) {
+ instrument->name =
+ details->has_name() ? details->name() : WTF::g_empty_string;
+ if (details->has_icons()) {
ExecutionContext* context =
ExecutionContext::From(resolver->GetScriptState());
- for (const ImageObject image_object : details.icons()) {
+ for (const ImageObject image_object : details->icons()) {
KURL parsed_url = context->CompleteURL(image_object.src());
if (!parsed_url.IsValid() || !parsed_url.ProtocolIsInHTTPFamily()) {
resolver->Reject(V8ThrowException::CreateTypeError(
@@ -288,12 +336,12 @@ void PaymentInstruments::OnRequestPermission(
}
instrument->method =
- details.hasMethod() ? details.method() : WTF::g_empty_string;
+ details->has_method() ? details->method() : WTF::g_empty_string;
- if (details.hasCapabilities()) {
+ if (details->has_capabilities()) {
v8::Local<v8::String> value;
if (!v8::JSON::Stringify(resolver->GetScriptState()->GetContext(),
- details.capabilities().V8Value().As<v8::Object>())
+ details->capabilities().V8Value().As<v8::Object>())
.ToLocal(&value)) {
resolver->Reject(V8ThrowException::CreateTypeError(
resolver->GetScriptState()->GetIsolate(),
@@ -306,7 +354,7 @@ void PaymentInstruments::OnRequestPermission(
ExceptionState::kSetterContext,
"PaymentInstruments", "set");
BasicCardHelper::ParseBasiccardData(
- details.capabilities(), instrument->supported_networks,
+ details->capabilities(), instrument->supported_networks,
instrument->supported_types, exception_state);
if (exception_state.HadException()) {
resolver->Reject(exception_state);
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 02f9046dfb0..664a90e3c1f 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_instruments.h
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_instruments.h
@@ -5,7 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_PAYMENT_INSTRUMENTS_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_PAYMENT_INSTRUMENTS_H_
-#include "third_party/blink/public/platform/modules/payments/payment_app.mojom-blink.h"
+#include "third_party/blink/public/mojom/payments/payment_app.mojom-blink.h"
#include "third_party/blink/public/platform/modules/permissions/permission.mojom-blink.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
@@ -20,6 +20,7 @@ class PaymentInstrument;
class ScriptPromise;
class ScriptPromiseResolver;
class ScriptState;
+class PaymentInstrumentParameter;
class MODULES_EXPORT PaymentInstruments final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
@@ -42,7 +43,7 @@ class MODULES_EXPORT PaymentInstruments final : public ScriptWrappable {
mojom::blink::PermissionService* GetPermissionService(ScriptState*);
void OnRequestPermission(ScriptPromiseResolver*,
const String&,
- const PaymentInstrument&,
+ PaymentInstrumentParameter*,
mojom::blink::PermissionStatus);
void onDeletePaymentInstrument(ScriptPromiseResolver*,
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 6cfaea3db69..139d0018fdb 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_manager.h
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_manager.h
@@ -5,7 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_PAYMENT_MANAGER_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_PAYMENT_MANAGER_H_
-#include "third_party/blink/public/platform/modules/payments/payment_app.mojom-blink.h"
+#include "third_party/blink/public/mojom/payments/payment_app.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
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 4b803e9cb19..18edea360e1 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_request.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_request.cc
@@ -25,6 +25,8 @@
#include "third_party/blink/renderer/core/event_type_names.h"
#include "third_party/blink/renderer/core/frame/deprecation.h"
#include "third_party/blink/renderer/core/frame/frame_owner.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/frame/use_counter.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
@@ -32,11 +34,13 @@
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/inspector/console_types.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_error_fields.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_update.h"
@@ -44,12 +48,12 @@
#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/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/feature_policy/feature_policy.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/uuid.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
@@ -57,7 +61,11 @@
namespace {
+using ::payments::mojom::blink::AddressErrors;
+using ::payments::mojom::blink::AddressErrorsPtr;
using ::payments::mojom::blink::CanMakePaymentQueryResult;
+using ::payments::mojom::blink::PayerErrorFields;
+using ::payments::mojom::blink::PayerErrorFieldsPtr;
using ::payments::mojom::blink::PaymentAddress;
using ::payments::mojom::blink::PaymentAddressPtr;
using ::payments::mojom::blink::PaymentCurrencyAmount;
@@ -71,6 +79,8 @@ using ::payments::mojom::blink::PaymentOptionsPtr;
using ::payments::mojom::blink::PaymentResponsePtr;
using ::payments::mojom::blink::PaymentShippingOptionPtr;
using ::payments::mojom::blink::PaymentShippingType;
+using ::payments::mojom::blink::PaymentValidationErrors;
+using ::payments::mojom::blink::PaymentValidationErrorsPtr;
} // namespace
@@ -132,6 +142,65 @@ struct TypeConverter<PaymentOptionsPtr, blink::PaymentOptions> {
}
};
+template <>
+struct TypeConverter<PaymentValidationErrorsPtr,
+ blink::PaymentValidationErrors> {
+ static PaymentValidationErrorsPtr Convert(
+ const blink::PaymentValidationErrors& input) {
+ PaymentValidationErrorsPtr output =
+ payments::mojom::blink::PaymentValidationErrors::New();
+ output->payer = input.hasPayer()
+ ? PayerErrorFields::From(input.payer())
+ : PayerErrorFields::From(blink::PayerErrorFields());
+ output->shipping_address =
+ input.hasShippingAddress()
+ ? AddressErrors::From(input.shippingAddress())
+ : AddressErrors::From(blink::AddressErrors());
+ return output;
+ }
+};
+
+template <>
+struct TypeConverter<PayerErrorFieldsPtr, blink::PayerErrorFields> {
+ static PayerErrorFieldsPtr Convert(const blink::PayerErrorFields& input) {
+ PayerErrorFieldsPtr output =
+ payments::mojom::blink::PayerErrorFields::New();
+ output->email = input.hasEmail() ? input.email() : g_empty_string;
+ output->name = input.hasName() ? input.name() : g_empty_string;
+ output->phone = input.hasPhone() ? input.phone() : g_empty_string;
+ return output;
+ }
+};
+
+template <>
+struct TypeConverter<AddressErrorsPtr, blink::AddressErrors> {
+ static AddressErrorsPtr Convert(const blink::AddressErrors& input) {
+ AddressErrorsPtr output = payments::mojom::blink::AddressErrors::New();
+ output->address_line =
+ input.hasAddressLine() ? input.addressLine() : g_empty_string;
+ output->city = input.hasCity() ? input.city() : g_empty_string;
+ output->country = input.hasCountry() ? input.country() : g_empty_string;
+ output->dependent_locality = input.hasDependentLocality()
+ ? input.dependentLocality()
+ : g_empty_string;
+ output->language_code =
+ input.hasLanguageCode() ? input.languageCode() : g_empty_string;
+ output->organization =
+ input.hasOrganization() ? input.organization() : g_empty_string;
+ output->phone = input.hasPhone() ? input.phone() : g_empty_string;
+ output->postal_code =
+ input.hasPostalCode() ? input.postalCode() : g_empty_string;
+ output->recipient =
+ input.hasRecipient() ? input.recipient() : g_empty_string;
+ output->region = input.hasRegion() ? input.region() : g_empty_string;
+ output->region_code =
+ input.hasRegionCode() ? input.regionCode() : g_empty_string;
+ output->sorting_code =
+ input.hasSortingCode() ? input.sortingCode() : g_empty_string;
+ return output;
+ }
+};
+
} // namespace mojo
namespace blink {
@@ -450,8 +519,7 @@ void StringifyAndParseMethodSpecificData(const String& supported_method,
if (exception_state.HadException())
exception_state.ClearException();
}
- if (RuntimeEnabledFeatures::PaymentRequestBasicCardEnabled() &&
- supported_method == "basic-card") {
+ if (supported_method == "basic-card") {
SetBasicCardMethodData(input, output, exception_state);
if (exception_state.HadException())
exception_state.ClearException();
@@ -672,7 +740,8 @@ bool AllowedToUsePaymentRequest(const Frame* frame) {
return false;
// 2. If Feature Policy is enabled, return the policy for "payment" feature.
- return frame->IsFeatureEnabled(mojom::FeaturePolicyFeature::kPayment);
+ return frame->IsFeatureEnabled(mojom::FeaturePolicyFeature::kPayment,
+ ReportOptions::kReportOnFailure);
}
void WarnIgnoringQueryQuotaForCanMakePayment(
@@ -708,7 +777,7 @@ PaymentRequest* PaymentRequest::Create(
PaymentRequest::~PaymentRequest() = default;
ScriptPromise PaymentRequest::show(ScriptState* script_state) {
- if (!payment_provider_.is_bound() || show_resolver_) {
+ if (!payment_provider_.is_bound() || accept_resolver_) {
return ScriptPromise::RejectWithDOMException(
script_state, DOMException::Create(DOMExceptionCode::kInvalidStateError,
"Already called show() once"));
@@ -739,8 +808,8 @@ ScriptPromise PaymentRequest::show(ScriptState* script_state) {
payment_provider_->Show(is_user_gesture);
- show_resolver_ = ScriptPromiseResolver::Create(script_state);
- return show_resolver_->Promise();
+ accept_resolver_ = ScriptPromiseResolver::Create(script_state);
+ return accept_resolver_->Promise();
}
ScriptPromise PaymentRequest::abort(ScriptState* script_state) {
@@ -758,11 +827,12 @@ ScriptPromise PaymentRequest::abort(ScriptState* script_state) {
"has resolved or rejected"));
}
- if (!show_resolver_) {
+ if (!GetPendingAcceptPromiseResolver()) {
return ScriptPromise::RejectWithDOMException(
script_state,
- DOMException::Create(DOMExceptionCode::kInvalidStateError,
- "Never called show(), so nothing to abort"));
+ DOMException::Create(
+ DOMExceptionCode::kInvalidStateError,
+ "No show() or retry() in progress, so nothing to abort"));
}
abort_resolver_ = ScriptPromiseResolver::Create(script_state);
@@ -771,7 +841,7 @@ ScriptPromise PaymentRequest::abort(ScriptState* script_state) {
}
ScriptPromise PaymentRequest::canMakePayment(ScriptState* script_state) {
- if (!payment_provider_.is_bound() || show_resolver_ ||
+ if (!payment_provider_.is_bound() || GetPendingAcceptPromiseResolver() ||
can_make_payment_resolver_ || !script_state->ContextIsValid()) {
return ScriptPromise::RejectWithDOMException(
script_state, DOMException::Create(DOMExceptionCode::kInvalidStateError,
@@ -785,7 +855,7 @@ ScriptPromise PaymentRequest::canMakePayment(ScriptState* script_state) {
}
bool PaymentRequest::HasPendingActivity() const {
- return show_resolver_ || complete_resolver_;
+ return GetPendingAcceptPromiseResolver() || complete_resolver_;
}
const AtomicString& PaymentRequest::InterfaceName() const {
@@ -796,12 +866,53 @@ ExecutionContext* PaymentRequest::GetExecutionContext() const {
return ContextLifecycleObserver::GetExecutionContext();
}
-ScriptPromise PaymentRequest::Retry(ScriptState*,
- const PaymentValidationErrors&) {
- // TODO(zino): Should implement this method. Please see
- // https://crbug.com/861704
- NOTIMPLEMENTED();
- return ScriptPromise();
+ScriptPromise PaymentRequest::Retry(ScriptState* script_state,
+ const PaymentValidationErrors& errors) {
+ if (!script_state->ContextIsValid() || !LocalDOMWindow::From(script_state) ||
+ !LocalDOMWindow::From(script_state)->GetFrame()) {
+ return ScriptPromise::RejectWithDOMException(
+ script_state, DOMException::Create(DOMExceptionCode::kAbortError,
+ "Cannot retry the payment request"));
+ }
+
+ if (complete_resolver_) {
+ return ScriptPromise::RejectWithDOMException(
+ script_state,
+ DOMException::Create(
+ DOMExceptionCode::kInvalidStateError,
+ "Cannot call retry() because already called complete()"));
+ }
+
+ if (retry_resolver_) {
+ return ScriptPromise::RejectWithDOMException(
+ script_state, DOMException::Create(DOMExceptionCode::kInvalidStateError,
+ "Cannot call retry() again until "
+ "the previous retry() is finished"));
+ }
+
+ if (!payment_provider_) {
+ return ScriptPromise::RejectWithDOMException(
+ script_state, DOMException::Create(DOMExceptionCode::kInvalidStateError,
+ "Payment request terminated"));
+ }
+
+ String error_message;
+ if (!PaymentsValidators::IsValidPaymentValidationErrorsFormat(
+ errors, &error_message)) {
+ return ScriptPromise::Reject(
+ script_state, V8ThrowException::CreateTypeError(
+ script_state->GetIsolate(), error_message));
+ }
+
+ complete_timer_.Stop();
+
+ // The payment provider should respond in PaymentRequest::OnPaymentResponse().
+ payment_provider_->Retry(
+ payments::mojom::blink::PaymentValidationErrors::From(errors));
+
+ retry_resolver_ = ScriptPromiseResolver::Create(script_state);
+
+ return retry_resolver_->Promise();
}
ScriptPromise PaymentRequest::Complete(ScriptState* script_state,
@@ -818,6 +929,13 @@ ScriptPromise PaymentRequest::Complete(ScriptState* script_state,
"Already called complete() once"));
}
+ if (retry_resolver_) {
+ return ScriptPromise::RejectWithDOMException(
+ script_state, DOMException::Create(
+ DOMExceptionCode::kInvalidStateError,
+ "Cannot call complete() before retry() is finished"));
+ }
+
if (!complete_timer_.IsActive()) {
return ScriptPromise::RejectWithDOMException(
script_state,
@@ -844,7 +962,7 @@ ScriptPromise PaymentRequest::Complete(ScriptState* script_state,
void PaymentRequest::OnUpdatePaymentDetails(
const ScriptValue& details_script_value) {
- if (!show_resolver_ || !payment_provider_)
+ if (!GetPendingAcceptPromiseResolver() || !payment_provider_)
return;
PaymentDetailsUpdate details;
@@ -854,14 +972,15 @@ void PaymentRequest::OnUpdatePaymentDetails(
V8PaymentDetailsUpdate::ToImpl(details_script_value.GetIsolate(),
details_script_value.V8Value(), details,
exception_state);
+ ScriptPromiseResolver* resolver = GetPendingAcceptPromiseResolver();
if (exception_state.HadException()) {
- show_resolver_->Reject(exception_state.GetException());
+ resolver->Reject(exception_state.GetException());
ClearResolversAndCloseMojoConnection();
return;
}
if (!details.hasTotal()) {
- show_resolver_->Reject(
+ resolver->Reject(
DOMException::Create(DOMExceptionCode::kSyntaxError, "Total required"));
ClearResolversAndCloseMojoConnection();
return;
@@ -873,7 +992,7 @@ void PaymentRequest::OnUpdatePaymentDetails(
details, options_, validated_details, shipping_option_,
*GetExecutionContext(), exception_state);
if (exception_state.HadException()) {
- show_resolver_->Reject(exception_state.GetException());
+ resolver->Reject(exception_state.GetException());
ClearResolversAndCloseMojoConnection();
return;
}
@@ -885,8 +1004,9 @@ void PaymentRequest::OnUpdatePaymentDetails(
}
void PaymentRequest::OnUpdatePaymentDetailsFailure(const String& error) {
- if (show_resolver_) {
- show_resolver_->Reject(
+ ScriptPromiseResolver* resolver = GetPendingAcceptPromiseResolver();
+ if (resolver) {
+ resolver->Reject(
DOMException::Create(DOMExceptionCode::kAbortError, error));
}
if (complete_resolver_) {
@@ -899,7 +1019,9 @@ void PaymentRequest::OnUpdatePaymentDetailsFailure(const String& error) {
void PaymentRequest::Trace(blink::Visitor* visitor) {
visitor->Trace(options_);
visitor->Trace(shipping_address_);
- visitor->Trace(show_resolver_);
+ visitor->Trace(payment_response_);
+ visitor->Trace(accept_resolver_);
+ visitor->Trace(retry_resolver_);
visitor->Trace(complete_resolver_);
visitor->Trace(abort_resolver_);
visitor->Trace(can_make_payment_resolver_);
@@ -984,12 +1106,12 @@ void PaymentRequest::ContextDestroyed(ExecutionContext*) {
}
void PaymentRequest::OnShippingAddressChange(PaymentAddressPtr address) {
- DCHECK(show_resolver_);
+ DCHECK(GetPendingAcceptPromiseResolver());
DCHECK(!complete_resolver_);
String error_message;
if (!PaymentsValidators::IsValidShippingAddress(address, &error_message)) {
- show_resolver_->Reject(
+ GetPendingAcceptPromiseResolver()->Reject(
DOMException::Create(DOMExceptionCode::kSyntaxError, error_message));
ClearResolversAndCloseMojoConnection();
return;
@@ -1001,7 +1123,7 @@ void PaymentRequest::OnShippingAddressChange(PaymentAddressPtr address) {
GetExecutionContext(), EventTypeNames::shippingaddresschange);
event->SetTarget(this);
event->SetPaymentDetailsUpdater(this);
- DispatchEvent(event);
+ DispatchEvent(*event);
if (!event->is_waiting_for_update()) {
GetExecutionContext()->AddConsoleMessage(ConsoleMessage::Create(
kJSMessageSource, kWarningMessageLevel,
@@ -1012,7 +1134,7 @@ void PaymentRequest::OnShippingAddressChange(PaymentAddressPtr address) {
}
void PaymentRequest::OnShippingOptionChange(const String& shipping_option_id) {
- DCHECK(show_resolver_);
+ DCHECK(GetPendingAcceptPromiseResolver());
DCHECK(!complete_resolver_);
shipping_option_ = shipping_option_id;
@@ -1020,7 +1142,7 @@ void PaymentRequest::OnShippingOptionChange(const String& shipping_option_id) {
GetExecutionContext(), EventTypeNames::shippingoptionchange);
event->SetTarget(this);
event->SetPaymentDetailsUpdater(this);
- DispatchEvent(event);
+ DispatchEvent(*event);
if (!event->is_waiting_for_update()) {
GetExecutionContext()->AddConsoleMessage(ConsoleMessage::Create(
kJSMessageSource, kWarningMessageLevel,
@@ -1031,14 +1153,13 @@ void PaymentRequest::OnShippingOptionChange(const String& shipping_option_id) {
}
void PaymentRequest::OnPaymentResponse(PaymentResponsePtr response) {
- DCHECK(show_resolver_);
+ DCHECK(GetPendingAcceptPromiseResolver());
DCHECK(!complete_resolver_);
- DCHECK(!complete_timer_.IsActive());
+ ScriptPromiseResolver* resolver = GetPendingAcceptPromiseResolver();
if (options_.requestShipping()) {
if (!response->shipping_address || response->shipping_option.IsEmpty()) {
- show_resolver_->Reject(
- DOMException::Create(DOMExceptionCode::kSyntaxError));
+ resolver->Reject(DOMException::Create(DOMExceptionCode::kSyntaxError));
ClearResolversAndCloseMojoConnection();
return;
}
@@ -1046,7 +1167,7 @@ void PaymentRequest::OnPaymentResponse(PaymentResponsePtr response) {
String error_message;
if (!PaymentsValidators::IsValidShippingAddress(response->shipping_address,
&error_message)) {
- show_resolver_->Reject(
+ resolver->Reject(
DOMException::Create(DOMExceptionCode::kSyntaxError, error_message));
ClearResolversAndCloseMojoConnection();
return;
@@ -1057,8 +1178,7 @@ void PaymentRequest::OnPaymentResponse(PaymentResponsePtr response) {
shipping_option_ = response->shipping_option;
} else {
if (response->shipping_address || !response->shipping_option.IsNull()) {
- show_resolver_->Reject(
- DOMException::Create(DOMExceptionCode::kSyntaxError));
+ resolver->Reject(DOMException::Create(DOMExceptionCode::kSyntaxError));
ClearResolversAndCloseMojoConnection();
return;
}
@@ -1070,21 +1190,32 @@ void PaymentRequest::OnPaymentResponse(PaymentResponsePtr response) {
(!options_.requestPayerName() && !response->payer_name.IsNull()) ||
(!options_.requestPayerEmail() && !response->payer_email.IsNull()) ||
(!options_.requestPayerPhone() && !response->payer_phone.IsNull())) {
- show_resolver_->Reject(
- DOMException::Create(DOMExceptionCode::kSyntaxError));
+ resolver->Reject(DOMException::Create(DOMExceptionCode::kSyntaxError));
ClearResolversAndCloseMojoConnection();
return;
}
complete_timer_.StartOneShot(kCompleteTimeout, FROM_HERE);
- show_resolver_->Resolve(new PaymentResponse(
- std::move(response), shipping_address_.Get(), this, id_));
-
- // Do not close the mojo connection here. The merchant website should call
- // PaymentResponse::complete(String), which will be forwarded over the mojo
- // connection to display a success or failure message to the user.
- show_resolver_.Clear();
+ if (retry_resolver_) {
+ DCHECK(payment_response_);
+ payment_response_->Update(std::move(response), shipping_address_.Get());
+ retry_resolver_->Resolve();
+
+ // Do not close the mojo connection here. The merchant website should call
+ // PaymentResponse::complete(String), which will be forwarded over the mojo
+ // connection to display a success or failure message to the user.
+ retry_resolver_.Clear();
+ } else if (accept_resolver_) {
+ payment_response_ = new PaymentResponse(std::move(response),
+ shipping_address_.Get(), this, id_);
+ accept_resolver_->Resolve(payment_response_);
+
+ // Do not close the mojo connection here. The merchant website should call
+ // PaymentResponse::complete(String), which will be forwarded over the mojo
+ // connection to display a success or failure message to the user.
+ accept_resolver_.Clear();
+ }
}
void PaymentRequest::OnError(PaymentErrorReason error) {
@@ -1120,6 +1251,14 @@ void PaymentRequest::OnError(PaymentErrorReason error) {
break;
}
+ case PaymentErrorReason::ALREADY_SHOWING: {
+ exception_code = DOMExceptionCode::kAbortError;
+ message =
+ "Another PaymentRequest UI is already showing in a different tab or "
+ "window";
+ break;
+ }
+
case PaymentErrorReason::UNKNOWN: {
exception_code = DOMExceptionCode::kUnknownError;
message = "Request failed";
@@ -1138,8 +1277,9 @@ void PaymentRequest::OnError(PaymentErrorReason error) {
complete_resolver_->Resolve();
}
- if (show_resolver_)
- show_resolver_->Reject(DOMException::Create(exception_code, message));
+ ScriptPromiseResolver* resolver = GetPendingAcceptPromiseResolver();
+ if (resolver)
+ resolver->Reject(DOMException::Create(exception_code, message));
if (abort_resolver_)
abort_resolver_->Reject(DOMException::Create(exception_code, message));
@@ -1160,7 +1300,7 @@ void PaymentRequest::OnComplete() {
void PaymentRequest::OnAbort(bool aborted_successfully) {
DCHECK(abort_resolver_);
- DCHECK(show_resolver_);
+ DCHECK(GetPendingAcceptPromiseResolver());
if (!aborted_successfully) {
abort_resolver_->Reject(DOMException::Create(
@@ -1169,14 +1309,18 @@ void PaymentRequest::OnAbort(bool aborted_successfully) {
return;
}
- show_resolver_->Reject(DOMException::Create(
- DOMExceptionCode::kAbortError, "The website has aborted the payment"));
+ ScriptPromiseResolver* resolver = GetPendingAcceptPromiseResolver();
+ resolver->Reject(DOMException::Create(DOMExceptionCode::kAbortError,
+ "The website has aborted the payment"));
abort_resolver_->Resolve();
ClearResolversAndCloseMojoConnection();
}
void PaymentRequest::OnCanMakePayment(CanMakePaymentQueryResult result) {
- DCHECK(can_make_payment_resolver_);
+ // TODO(https://crbug.com/891371): Understand how the resolver could be null
+ // here and prevent it.
+ if (!can_make_payment_resolver_)
+ return;
switch (result) {
case CanMakePaymentQueryResult::WARNING_CAN_MAKE_PAYMENT:
@@ -1219,7 +1363,8 @@ void PaymentRequest::OnCompleteTimeout(TimerBase*) {
void PaymentRequest::ClearResolversAndCloseMojoConnection() {
complete_timer_.Stop();
complete_resolver_.Clear();
- show_resolver_.Clear();
+ accept_resolver_.Clear();
+ retry_resolver_.Clear();
abort_resolver_.Clear();
can_make_payment_resolver_.Clear();
if (client_binding_.is_bound())
@@ -1227,4 +1372,8 @@ void PaymentRequest::ClearResolversAndCloseMojoConnection() {
payment_provider_.reset();
}
+ScriptPromiseResolver* PaymentRequest::GetPendingAcceptPromiseResolver() const {
+ return retry_resolver_ ? retry_resolver_.Get() : accept_resolver_.Get();
+}
+
} // namespace blink
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 7a3d307ccef..4a722414604 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_request.h
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_request.h
@@ -8,7 +8,7 @@
#include "base/memory/scoped_refptr.h"
#include "components/payments/mojom/payment_request_data.mojom-blink.h"
#include "mojo/public/cpp/bindings/binding.h"
-#include "third_party/blink/public/platform/modules/payments/payment_request.mojom-blink.h"
+#include "third_party/blink/public/mojom/payments/payment_request.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
@@ -33,6 +33,7 @@ class ExceptionState;
class ExecutionContext;
class PaymentAddress;
class PaymentDetailsInit;
+class PaymentResponse;
class ScriptPromiseResolver;
class ScriptState;
@@ -128,14 +129,22 @@ class MODULES_EXPORT PaymentRequest final
// Clears the promise resolvers and closes the Mojo connection.
void ClearResolversAndCloseMojoConnection();
+ // Returns the resolver for the current pending accept promise that should
+ // be resolved if the user accepts or aborts the payment request.
+ // The pending promise can be [[acceptPromise]] or [[retryPromise]] in the
+ // spec.
+ ScriptPromiseResolver* GetPendingAcceptPromiseResolver() const;
+
PaymentOptions options_;
Member<PaymentAddress> shipping_address_;
+ Member<PaymentResponse> payment_response_;
String id_;
String shipping_option_;
String shipping_type_;
HashSet<String> method_names_;
- Member<ScriptPromiseResolver> show_resolver_;
+ Member<ScriptPromiseResolver> accept_resolver_;
Member<ScriptPromiseResolver> complete_resolver_;
+ Member<ScriptPromiseResolver> retry_resolver_;
Member<ScriptPromiseResolver> abort_resolver_;
Member<ScriptPromiseResolver> can_make_payment_resolver_;
payments::mojom::blink::PaymentRequestPtr payment_provider_;
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 e0e340fb2d9..eb6539bba9b 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_response.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_response.cc
@@ -33,6 +33,19 @@ PaymentResponse::PaymentResponse(
PaymentResponse::~PaymentResponse() = default;
+void PaymentResponse::Update(
+ payments::mojom::blink::PaymentResponsePtr response,
+ PaymentAddress* shipping_address) {
+ DCHECK(response);
+ method_name_ = response->method_name;
+ stringified_details_ = response->stringified_details;
+ shipping_address_ = shipping_address;
+ shipping_option_ = response->shipping_option;
+ payer_name_ = response->payer_name;
+ payer_email_ = response->payer_email;
+ payer_phone_ = response->payer_phone;
+}
+
ScriptValue PaymentResponse::toJSONForBinding(ScriptState* script_state) const {
V8ObjectBuilder result(script_state);
result.AddString("requestId", requestId());
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 6ad8d55ec5d..7bbef17b997 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_response.h
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_response.h
@@ -5,7 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_PAYMENT_RESPONSE_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_PAYMENT_RESPONSE_H_
-#include "third_party/blink/public/platform/modules/payments/payment_request.mojom-blink.h"
+#include "third_party/blink/public/mojom/payments/payment_request.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/modules/modules_export.h"
@@ -34,6 +34,8 @@ class MODULES_EXPORT PaymentResponse final : public ScriptWrappable {
const String& requestId);
~PaymentResponse() override;
+ void Update(payments::mojom::blink::PaymentResponsePtr, PaymentAddress*);
+
ScriptValue toJSONForBinding(ScriptState*) const;
const String& requestId() const { return requestId_; }
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 ddd5662db91..f81fbc53187 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
@@ -6,7 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_PAYMENT_TEST_HELPER_H_
#include "testing/gmock/include/gmock/gmock.h"
-#include "third_party/blink/public/platform/modules/payments/payment_request.mojom-blink.h"
+#include "third_party/blink/public/mojom/payments/payment_request.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_function.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_dom_exception.h"
#include "third_party/blink/renderer/modules/payments/payment_details_init.h"
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 30483f47143..3b2bdeccca4 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payments_validators.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/payments_validators.cc
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/modules/payments/payments_validators.h"
#include "third_party/blink/renderer/bindings/core/v8/script_regexp.h"
+#include "third_party/blink/renderer/modules/payments/payment_validation_errors.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/text/string_impl.h"
@@ -124,4 +125,66 @@ bool PaymentsValidators::IsValidErrorMsgFormat(const String& error,
return false;
}
+// static
+bool PaymentsValidators::IsValidPaymentValidationErrorsFormat(
+ const PaymentValidationErrors& errors,
+ String* optional_error_message) {
+ if (errors.hasPayer()) {
+ if ((errors.payer().hasEmail() &&
+ !IsValidErrorMsgFormat(errors.payer().email(),
+ optional_error_message)) ||
+ (errors.payer().hasName() &&
+ !IsValidErrorMsgFormat(errors.payer().name(),
+ optional_error_message)) ||
+ (errors.payer().hasPhone() &&
+ !IsValidErrorMsgFormat(errors.payer().phone(),
+ optional_error_message))) {
+ return false;
+ }
+ }
+
+ if (errors.hasShippingAddress()) {
+ if ((errors.shippingAddress().hasAddressLine() &&
+ !IsValidErrorMsgFormat(errors.shippingAddress().addressLine(),
+ optional_error_message)) ||
+ (errors.shippingAddress().hasCity() &&
+ !IsValidErrorMsgFormat(errors.shippingAddress().city(),
+ optional_error_message)) ||
+ (errors.shippingAddress().hasCountry() &&
+ !IsValidErrorMsgFormat(errors.shippingAddress().country(),
+ optional_error_message)) ||
+ (errors.shippingAddress().hasDependentLocality() &&
+ !IsValidErrorMsgFormat(errors.shippingAddress().dependentLocality(),
+ optional_error_message)) ||
+ (errors.shippingAddress().hasLanguageCode() &&
+ !IsValidErrorMsgFormat(errors.shippingAddress().languageCode(),
+ optional_error_message)) ||
+ (errors.shippingAddress().hasOrganization() &&
+ !IsValidErrorMsgFormat(errors.shippingAddress().organization(),
+ optional_error_message)) ||
+ (errors.shippingAddress().hasPhone() &&
+ !IsValidErrorMsgFormat(errors.shippingAddress().phone(),
+ optional_error_message)) ||
+ (errors.shippingAddress().hasPostalCode() &&
+ !IsValidErrorMsgFormat(errors.shippingAddress().postalCode(),
+ optional_error_message)) ||
+ (errors.shippingAddress().hasRecipient() &&
+ !IsValidErrorMsgFormat(errors.shippingAddress().recipient(),
+ optional_error_message)) ||
+ (errors.shippingAddress().hasRegion() &&
+ !IsValidErrorMsgFormat(errors.shippingAddress().region(),
+ optional_error_message)) ||
+ (errors.shippingAddress().hasRegionCode() &&
+ !IsValidErrorMsgFormat(errors.shippingAddress().regionCode(),
+ optional_error_message)) ||
+ (errors.shippingAddress().hasSortingCode() &&
+ !IsValidErrorMsgFormat(errors.shippingAddress().sortingCode(),
+ optional_error_message))) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/payments/payments_validators.h b/chromium/third_party/blink/renderer/modules/payments/payments_validators.h
index ee597f02b64..c9c2f86f38e 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payments_validators.h
+++ b/chromium/third_party/blink/renderer/modules/payments/payments_validators.h
@@ -5,13 +5,15 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_PAYMENTS_VALIDATORS_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_PAYMENTS_VALIDATORS_H_
-#include "third_party/blink/public/platform/modules/payments/payment_request.mojom-blink.h"
+#include "third_party/blink/public/mojom/payments/payment_request.mojom-blink.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
+class PaymentValidationErrors;
+
class MODULES_EXPORT PaymentsValidators final {
STATIC_ONLY(PaymentsValidators);
@@ -51,6 +53,12 @@ class MODULES_EXPORT PaymentsValidators final {
// Returns false if |error| is too long (greater than 2048).
static bool IsValidErrorMsgFormat(const String& code,
String* optional_error_message);
+
+ // Returns false if |payment_validation_errors| has too long string (greater
+ // than 2048).
+ static bool IsValidPaymentValidationErrorsFormat(
+ const PaymentValidationErrors& errors,
+ String* optional_error_message);
};
} // namespace blink
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 8690156a7ca..3f2928c34da 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
@@ -6,6 +6,7 @@
#include <ostream> // NOLINT
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/modules/payments/payment_validation_errors.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
@@ -23,11 +24,11 @@ struct CurrencyCodeTestCase {
class PaymentsCurrencyValidatorTest
: public testing::TestWithParam<CurrencyCodeTestCase> {};
-const char* LongString2048() {
- static char long_string[2049];
- for (int i = 0; i < 2048; i++)
+const char* LongString2049() {
+ static char long_string[2050];
+ for (int i = 0; i < 2049; i++)
long_string[i] = 'a';
- long_string[2048] = '\0';
+ long_string[2049] = '\0';
return long_string;
}
@@ -64,7 +65,7 @@ INSTANTIATE_TEST_CASE_P(
CurrencyCodeTestCase("usd", true),
CurrencyCodeTestCase("ANYSTRING", false),
CurrencyCodeTestCase("", false),
- CurrencyCodeTestCase(LongString2048(), false)));
+ CurrencyCodeTestCase(LongString2049(), false)));
struct TestCase {
TestCase(const char* input, bool expected_valid)
@@ -262,5 +263,152 @@ INSTANTIATE_TEST_CASE_P(
ShippingAddressTestCase("US", "en", "InvalidScriptCode", false),
ShippingAddressTestCase("US", "", "Latn", false)));
+struct ValidationErrorsTestCase {
+ ValidationErrorsTestCase(bool expected_valid)
+ : expected_valid(expected_valid) {}
+
+ const char* m_payer_email = "";
+ const char* m_payer_name = "";
+ const char* m_payer_phone = "";
+ const char* m_shipping_address_address_line = "";
+ const char* m_shipping_address_city = "";
+ const char* m_shipping_address_country = "";
+ const char* m_shipping_address_dependent_locality = "";
+ const char* m_shipping_address_language_code = "";
+ const char* m_shipping_address_organization = "";
+ const char* m_shipping_address_phone = "";
+ const char* m_shipping_address_postal_code = "";
+ const char* m_shipping_address_recipient = "";
+ const char* m_shipping_address_region = "";
+ const char* m_shipping_address_region_code = "";
+ const char* m_shipping_address_sorting_code = "";
+ bool expected_valid;
+};
+
+#define VALIDATION_ERRORS_TEST_CASE(field, value, expected_valid) \
+ ([]() { \
+ ValidationErrorsTestCase test_case(expected_valid); \
+ test_case.m_##field = value; \
+ return test_case; \
+ })()
+
+PaymentValidationErrors toPaymentValidationErrors(
+ ValidationErrorsTestCase test_case) {
+ PaymentValidationErrors errors;
+
+ PayerErrorFields payer;
+ payer.setEmail(test_case.m_payer_email);
+ payer.setName(test_case.m_payer_name);
+ payer.setPhone(test_case.m_payer_phone);
+
+ AddressErrors shipping_address;
+ shipping_address.setAddressLine(test_case.m_shipping_address_address_line);
+ shipping_address.setCity(test_case.m_shipping_address_city);
+ shipping_address.setCountry(test_case.m_shipping_address_country);
+ shipping_address.setDependentLocality(
+ test_case.m_shipping_address_dependent_locality);
+ shipping_address.setLanguageCode(test_case.m_shipping_address_language_code);
+ shipping_address.setOrganization(test_case.m_shipping_address_organization);
+ shipping_address.setPhone(test_case.m_shipping_address_phone);
+ shipping_address.setPostalCode(test_case.m_shipping_address_postal_code);
+ shipping_address.setRecipient(test_case.m_shipping_address_recipient);
+ shipping_address.setRegion(test_case.m_shipping_address_region);
+ shipping_address.setRegionCode(test_case.m_shipping_address_region_code);
+ shipping_address.setSortingCode(test_case.m_shipping_address_sorting_code);
+
+ errors.setPayer(payer);
+ errors.setShippingAddress(shipping_address);
+
+ return errors;
+}
+
+class PaymentsErrorMessageValidatorTest
+ : public testing::TestWithParam<ValidationErrorsTestCase> {};
+
+TEST_P(PaymentsErrorMessageValidatorTest,
+ IsValidPaymentValidationErrorsFormat) {
+ PaymentValidationErrors errors = toPaymentValidationErrors(GetParam());
+
+ String error_message;
+ EXPECT_EQ(GetParam().expected_valid,
+ PaymentsValidators::IsValidPaymentValidationErrorsFormat(
+ errors, &error_message))
+ << error_message;
+}
+
+INSTANTIATE_TEST_CASE_P(
+ PaymentValidationErrorss,
+ PaymentsErrorMessageValidatorTest,
+ testing::Values(
+ VALIDATION_ERRORS_TEST_CASE(payer_email, "test", true),
+ VALIDATION_ERRORS_TEST_CASE(payer_name, "test", true),
+ VALIDATION_ERRORS_TEST_CASE(payer_phone, "test", true),
+ VALIDATION_ERRORS_TEST_CASE(shipping_address_city, "test", true),
+ VALIDATION_ERRORS_TEST_CASE(shipping_address_address_line,
+ "test",
+ true),
+ VALIDATION_ERRORS_TEST_CASE(shipping_address_city, "test", true),
+ VALIDATION_ERRORS_TEST_CASE(shipping_address_country, "test", true),
+ VALIDATION_ERRORS_TEST_CASE(shipping_address_dependent_locality,
+ "test",
+ true),
+ VALIDATION_ERRORS_TEST_CASE(shipping_address_language_code,
+ "test",
+ true),
+ VALIDATION_ERRORS_TEST_CASE(shipping_address_organization,
+ "test",
+ true),
+ VALIDATION_ERRORS_TEST_CASE(shipping_address_phone, "test", true),
+ VALIDATION_ERRORS_TEST_CASE(shipping_address_postal_code, "test", true),
+ VALIDATION_ERRORS_TEST_CASE(shipping_address_recipient, "test", true),
+ VALIDATION_ERRORS_TEST_CASE(shipping_address_region, "test", true),
+ VALIDATION_ERRORS_TEST_CASE(shipping_address_region_code, "test", true),
+ VALIDATION_ERRORS_TEST_CASE(shipping_address_sorting_code,
+ "test",
+ true),
+ VALIDATION_ERRORS_TEST_CASE(payer_email, LongString2049(), false),
+ VALIDATION_ERRORS_TEST_CASE(payer_name, LongString2049(), false),
+ VALIDATION_ERRORS_TEST_CASE(payer_phone, LongString2049(), false),
+ VALIDATION_ERRORS_TEST_CASE(shipping_address_city,
+ LongString2049(),
+ false),
+ VALIDATION_ERRORS_TEST_CASE(shipping_address_address_line,
+ LongString2049(),
+ false),
+ VALIDATION_ERRORS_TEST_CASE(shipping_address_city,
+ LongString2049(),
+ false),
+ VALIDATION_ERRORS_TEST_CASE(shipping_address_country,
+ LongString2049(),
+ false),
+ VALIDATION_ERRORS_TEST_CASE(shipping_address_dependent_locality,
+ LongString2049(),
+ false),
+ VALIDATION_ERRORS_TEST_CASE(shipping_address_language_code,
+ LongString2049(),
+ false),
+ VALIDATION_ERRORS_TEST_CASE(shipping_address_organization,
+ LongString2049(),
+ false),
+ VALIDATION_ERRORS_TEST_CASE(shipping_address_phone,
+ LongString2049(),
+ false),
+ VALIDATION_ERRORS_TEST_CASE(shipping_address_postal_code,
+ LongString2049(),
+ false),
+ VALIDATION_ERRORS_TEST_CASE(shipping_address_recipient,
+ LongString2049(),
+ false),
+ VALIDATION_ERRORS_TEST_CASE(shipping_address_region,
+ LongString2049(),
+ false),
+ VALIDATION_ERRORS_TEST_CASE(shipping_address_region_code,
+ LongString2049(),
+ false),
+ VALIDATION_ERRORS_TEST_CASE(shipping_address_sorting_code,
+ LongString2049(),
+ false)));
+
} // namespace
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/BUILD.gn b/chromium/third_party/blink/renderer/modules/peerconnection/BUILD.gn
index 924ebf1e8a0..70eb3421216 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/BUILD.gn
@@ -6,6 +6,12 @@ import("//third_party/blink/renderer/modules/modules.gni")
blink_modules_sources("peerconnection") {
sources = [
+ "adapters/ice_transport_host.cc",
+ "adapters/ice_transport_host.h",
+ "adapters/ice_transport_proxy.cc",
+ "adapters/ice_transport_proxy.h",
+ "adapters/web_rtc_cross_thread_copier.cc",
+ "adapters/web_rtc_cross_thread_copier.h",
"rtc_certificate.cc",
"rtc_certificate.h",
"rtc_data_channel.cc",
@@ -20,12 +26,18 @@ blink_modules_sources("peerconnection") {
"rtc_error_util.h",
"rtc_ice_candidate.cc",
"rtc_ice_candidate.h",
+ "rtc_ice_transport.cc",
+ "rtc_ice_transport.h",
"rtc_legacy_stats_report.cc",
"rtc_legacy_stats_report.h",
"rtc_peer_connection.cc",
"rtc_peer_connection.h",
"rtc_peer_connection_ice_event.cc",
"rtc_peer_connection_ice_event.h",
+ "rtc_quic_stream.cc",
+ "rtc_quic_stream.h",
+ "rtc_quic_transport.cc",
+ "rtc_quic_transport.h",
"rtc_rtp_contributing_source.cc",
"rtc_rtp_contributing_source.h",
"rtc_rtp_receiver.cc",
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/DEPS b/chromium/third_party/blink/renderer/modules/peerconnection/DEPS
index 35eb70405bd..1e08706b174 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/DEPS
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/DEPS
@@ -1,4 +1,5 @@
include_rules = [
+ "+services/metrics/public/cpp/ukm_builders.h",
"-third_party/blink/renderer/modules",
"+third_party/blink/renderer/modules/crypto",
"+third_party/blink/renderer/modules/event_modules.h",
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/OWNERS b/chromium/third_party/blink/renderer/modules/peerconnection/OWNERS
index 7a731f91fe4..076109be5f9 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/OWNERS
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/OWNERS
@@ -1,5 +1,6 @@
guidou@chromium.org
hbos@chromium.org
+orphis@chromium.org
tommi@chromium.org
# COMPONENT: Blink>WebRTC
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/README.md b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/README.md
new file mode 100644
index 00000000000..8c7794b7b2a
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/README.md
@@ -0,0 +1,13 @@
+## WebRTC API Adapters
+
+This directory contains code that wraps components of the WebRTC native API in
+classes that expose an API specialized for implementing the Web API. Some of
+these adapters also allow the WebRTC component to be safely used from a remote
+thread.
+
+### Blink Types
+
+Blink types (like AtomicString, HeapVector, etc.) should not be used inside this
+directory. The bindings in the parent directory are responsible for converting
+the Blink binding types to the corresponding STL/WebRTC types before interacting
+with the adapters.
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_host.cc b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_host.cc
new file mode 100644
index 00000000000..34ce669362c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_host.cc
@@ -0,0 +1,129 @@
+// 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/peerconnection/adapters/ice_transport_host.h"
+
+#include "third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h"
+#include "third_party/blink/renderer/platform/cross_thread_functional.h"
+#include "third_party/blink/renderer/platform/web_task_runner.h"
+
+namespace blink {
+
+IceTransportHost::IceTransportHost(
+ scoped_refptr<base::SingleThreadTaskRunner> proxy_thread,
+ base::WeakPtr<IceTransportProxy> proxy,
+ std::unique_ptr<cricket::PortAllocator> port_allocator)
+ : proxy_thread_(std::move(proxy_thread)),
+ port_allocator_(std::move(port_allocator)),
+ proxy_(std::move(proxy)) {
+ DETACH_FROM_THREAD(thread_checker_);
+ DCHECK(proxy_thread_);
+ DCHECK(proxy_);
+ DCHECK(port_allocator_);
+}
+
+IceTransportHost::~IceTransportHost() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+}
+
+void IceTransportHost::Initialize(rtc::Thread* host_thread_rtc_thread) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ // TODO(bugs.webrtc.org/9419): Remove once WebRTC can be built as a component.
+ if (!rtc::ThreadManager::Instance()->CurrentThread()) {
+ rtc::ThreadManager::Instance()->SetCurrentThread(host_thread_rtc_thread);
+ }
+ // These settings are copied from PeerConnection:
+ // https://codesearch.chromium.org/chromium/src/third_party/webrtc/pc/peerconnection.cc?l=4708&rcl=820ebd0f661696043959b5105b2814e0edd8b694
+ port_allocator_->set_step_delay(cricket::kMinimumStepDelay);
+ port_allocator_->set_flags(port_allocator_->flags() |
+ cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET |
+ cricket::PORTALLOCATOR_ENABLE_IPV6 |
+ cricket::PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
+ port_allocator_->Initialize();
+ transport_ = std::make_unique<cricket::P2PTransportChannel>(
+ "", 0, port_allocator_.get());
+ transport_->SignalGatheringState.connect(
+ this, &IceTransportHost::OnGatheringStateChanged);
+ transport_->SignalCandidateGathered.connect(
+ this, &IceTransportHost::OnCandidateGathered);
+ transport_->SignalStateChanged.connect(this,
+ &IceTransportHost::OnStateChanged);
+ // The ICE tiebreaker is used to determine which side is controlling/
+ // controlled when both sides start in the same role. The number is randomly
+ // generated so that each peer can calculate a.tiebreaker <= b.tiebreaker
+ // consistently.
+ transport_->SetIceTiebreaker(rtc::CreateRandomId64());
+}
+
+void IceTransportHost::StartGathering(
+ const cricket::IceParameters& local_parameters,
+ const cricket::ServerAddresses& stun_servers,
+ const std::vector<cricket::RelayServerConfig>& turn_servers,
+ int32_t candidate_filter) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ port_allocator_->set_candidate_filter(candidate_filter);
+ port_allocator_->SetConfiguration(stun_servers, turn_servers,
+ port_allocator_->candidate_pool_size(),
+ port_allocator_->prune_turn_ports());
+
+ transport_->SetIceParameters(local_parameters);
+ transport_->MaybeStartGathering();
+ DCHECK_EQ(transport_->gathering_state(), cricket::kIceGatheringGathering);
+}
+
+void IceTransportHost::SetRole(cricket::IceRole role) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ transport_->SetIceRole(role);
+}
+
+void IceTransportHost::SetRemoteParameters(
+ const cricket::IceParameters& remote_parameters) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ transport_->SetRemoteIceParameters(remote_parameters);
+}
+
+void IceTransportHost::AddRemoteCandidate(const cricket::Candidate& candidate) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ transport_->AddRemoteCandidate(candidate);
+}
+
+void IceTransportHost::ClearRemoteCandidates() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ auto remote_candidates = transport_->remote_candidates();
+ for (const auto& remote_candidate : remote_candidates) {
+ transport_->RemoveRemoteCandidate(remote_candidate);
+ }
+}
+
+void IceTransportHost::OnGatheringStateChanged(
+ cricket::IceTransportInternal* transport) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK_EQ(transport, transport_.get());
+ PostCrossThreadTask(
+ *proxy_thread_, FROM_HERE,
+ CrossThreadBind(&IceTransportProxy::OnGatheringStateChanged, proxy_,
+ transport_->gathering_state()));
+}
+
+void IceTransportHost::OnCandidateGathered(
+ cricket::IceTransportInternal* transport,
+ const cricket::Candidate& candidate) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK_EQ(transport, transport_.get());
+ PostCrossThreadTask(*proxy_thread_, FROM_HERE,
+ CrossThreadBind(&IceTransportProxy::OnCandidateGathered,
+ proxy_, candidate));
+}
+
+void IceTransportHost::OnStateChanged(
+ cricket::IceTransportInternal* transport) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK_EQ(transport, transport_.get());
+ PostCrossThreadTask(*proxy_thread_, FROM_HERE,
+ CrossThreadBind(&IceTransportProxy::OnStateChanged,
+ proxy_, transport_->GetState()));
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_host.h b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_host.h
new file mode 100644
index 00000000000..094130d2e91
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_host.h
@@ -0,0 +1,82 @@
+// 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_PEERCONNECTION_ADAPTERS_ICE_TRANSPORT_HOST_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_ICE_TRANSPORT_HOST_H_
+
+#include "base/memory/scoped_refptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/single_thread_task_runner.h"
+#include "base/threading/thread_checker.h"
+#include "third_party/webrtc/p2p/base/p2ptransportchannel.h"
+
+namespace rtc {
+class Thread;
+}
+
+namespace blink {
+
+class IceTransportProxy;
+
+// This class is the host side correspondent to the IceTransportProxy. See the
+// IceTransportProxy documentation for background. This class lives on the host
+// thread and proxies calls between the IceTransportProxy and the
+// P2PTransportChannel (which is single-threaded).
+//
+// proxy thread host thread
+// +------------------+ unique_ptr +------------------------------+
+// | | =========> | |
+// | client <-> Proxy | | Host <-> P2PTransportChannel |
+// | | <--------- | |
+// +------------------+ WeakPtr +------------------------------+
+//
+// Since the client code controls the Proxy lifetime, the Proxy has a unique_ptr
+// to the Host that lives on the host thread. The unique_ptr has an
+// OnTaskRunnerDeleter so that when the Proxy is destroyed a task will be queued
+// to delete the Host as well (and the P2PTransportChannel with it). The Host
+// needs a pointer back to the Proxy to post callbacks, and by using a WeakPtr
+// any callbacks run on the proxy thread after the proxy has been deleted will
+// be safely dropped.
+//
+// The Host can be constructed on any thread but after that point all methods
+// must be called on the host thread.
+class IceTransportHost final : public sigslot::has_slots<> {
+ public:
+ IceTransportHost(scoped_refptr<base::SingleThreadTaskRunner> proxy_thread,
+ base::WeakPtr<IceTransportProxy> proxy,
+ std::unique_ptr<cricket::PortAllocator> port_allocator);
+ ~IceTransportHost() override;
+
+ void Initialize(rtc::Thread* host_thread_rtc_thread);
+
+ void StartGathering(
+ const cricket::IceParameters& local_parameters,
+ const cricket::ServerAddresses& stun_servers,
+ const std::vector<cricket::RelayServerConfig>& turn_servers,
+ int32_t candidate_filter);
+
+ void SetRole(cricket::IceRole role);
+ void SetRemoteParameters(const cricket::IceParameters& remote_parameters);
+
+ void AddRemoteCandidate(const cricket::Candidate& candidate);
+ void ClearRemoteCandidates();
+
+ private:
+ // Callbacks from P2PTransportChannel.
+ void OnGatheringStateChanged(cricket::IceTransportInternal* transport);
+ void OnCandidateGathered(cricket::IceTransportInternal* transport,
+ const cricket::Candidate& candidate);
+ void OnStateChanged(cricket::IceTransportInternal* transport);
+
+ const scoped_refptr<base::SingleThreadTaskRunner> proxy_thread_;
+ std::unique_ptr<cricket::PortAllocator> port_allocator_;
+ std::unique_ptr<cricket::P2PTransportChannel> transport_;
+ base::WeakPtr<IceTransportProxy> proxy_;
+
+ THREAD_CHECKER(thread_checker_);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_ICE_TRANSPORT_HOST_H_
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.cc b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.cc
new file mode 100644
index 00000000000..a8ab2c4e151
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.cc
@@ -0,0 +1,112 @@
+// 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/peerconnection/adapters/ice_transport_proxy.h"
+
+#include "third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_host.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h"
+#include "third_party/blink/renderer/platform/cross_thread_functional.h"
+#include "third_party/blink/renderer/platform/web_task_runner.h"
+
+namespace blink {
+
+IceTransportProxy::IceTransportProxy(
+ FrameScheduler* frame_scheduler,
+ scoped_refptr<base::SingleThreadTaskRunner> host_thread,
+ rtc::Thread* host_thread_rtc_thread,
+ Delegate* delegate,
+ std::unique_ptr<cricket::PortAllocator> port_allocator)
+ : host_thread_(std::move(host_thread)),
+ host_(nullptr, base::OnTaskRunnerDeleter(host_thread_)),
+ delegate_(delegate),
+ connection_handle_for_scheduler_(
+ frame_scheduler->OnActiveConnectionCreated()),
+ weak_ptr_factory_(this) {
+ DCHECK(host_thread_);
+ DCHECK(delegate_);
+ scoped_refptr<base::SingleThreadTaskRunner> proxy_thread =
+ frame_scheduler->GetTaskRunner(TaskType::kNetworking);
+ DCHECK(proxy_thread->BelongsToCurrentThread());
+ // Wait to initialize the host until the weak_ptr_factory_ is initialized.
+ // The IceTransportHost is constructed on the proxy thread but should only be
+ // interacted with via PostTask to the host thread. The OnTaskRunnerDeleter
+ // (configured above) will ensure it gets deleted on the host thread.
+ host_.reset(new IceTransportHost(proxy_thread, weak_ptr_factory_.GetWeakPtr(),
+ std::move(port_allocator)));
+ PostCrossThreadTask(
+ *host_thread_, FROM_HERE,
+ CrossThreadBind(&IceTransportHost::Initialize,
+ CrossThreadUnretained(host_.get()),
+ CrossThreadUnretained(host_thread_rtc_thread)));
+}
+
+IceTransportProxy::~IceTransportProxy() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ // Note: The IceTransportHost will be deleted on the host thread.
+}
+
+void IceTransportProxy::StartGathering(
+ const cricket::IceParameters& local_parameters,
+ const cricket::ServerAddresses& stun_servers,
+ const std::vector<cricket::RelayServerConfig>& turn_servers,
+ int32_t candidate_filter) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ PostCrossThreadTask(
+ *host_thread_, FROM_HERE,
+ CrossThreadBind(&IceTransportHost::StartGathering,
+ CrossThreadUnretained(host_.get()), local_parameters,
+ stun_servers, turn_servers, candidate_filter));
+}
+
+void IceTransportProxy::SetRole(cricket::IceRole role) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ PostCrossThreadTask(
+ *host_thread_, FROM_HERE,
+ CrossThreadBind(&IceTransportHost::SetRole,
+ CrossThreadUnretained(host_.get()), role));
+}
+
+void IceTransportProxy::SetRemoteParameters(
+ const cricket::IceParameters& remote_parameters) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ PostCrossThreadTask(
+ *host_thread_, FROM_HERE,
+ CrossThreadBind(&IceTransportHost::SetRemoteParameters,
+ CrossThreadUnretained(host_.get()), remote_parameters));
+}
+
+void IceTransportProxy::AddRemoteCandidate(
+ const cricket::Candidate& candidate) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ PostCrossThreadTask(
+ *host_thread_, FROM_HERE,
+ CrossThreadBind(&IceTransportHost::AddRemoteCandidate,
+ CrossThreadUnretained(host_.get()), candidate));
+}
+
+void IceTransportProxy::ClearRemoteCandidates() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ PostCrossThreadTask(*host_thread_, FROM_HERE,
+ CrossThreadBind(&IceTransportHost::ClearRemoteCandidates,
+ CrossThreadUnretained(host_.get())));
+}
+
+void IceTransportProxy::OnGatheringStateChanged(
+ cricket::IceGatheringState new_state) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ delegate_->OnGatheringStateChanged(new_state);
+}
+
+void IceTransportProxy::OnCandidateGathered(
+ const cricket::Candidate& candidate) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ delegate_->OnCandidateGathered(candidate);
+}
+
+void IceTransportProxy::OnStateChanged(cricket::IceTransportState new_state) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ delegate_->OnStateChanged(new_state);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.h b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.h
new file mode 100644
index 00000000000..10b3f33c286
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.h
@@ -0,0 +1,102 @@
+// 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_PEERCONNECTION_ADAPTERS_ICE_TRANSPORT_PROXY_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_ICE_TRANSPORT_PROXY_H_
+
+#include "base/memory/scoped_refptr.h"
+#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/scheduler/public/frame_scheduler.h"
+#include "third_party/webrtc/p2p/base/p2ptransportchannel.h"
+
+namespace rtc {
+class Thread;
+}
+
+namespace blink {
+
+class IceTransportHost;
+
+// This class allows the ICE implementation (P2PTransportChannel) to run on a
+// thread different from the thread from which it is controlled. All
+// interactions with the ICE implementation happen asynchronously.
+//
+// Terminology:
+// - Proxy thread: Thread from which the P2PTransportChannel is controlled. This
+// is the thread on which the IceTransportProxy is created.
+// - Host thread: Thread on which the P2PTransportChannel runs. This is usually
+// the WebRTC worker thread and is specified when creating the
+// IceTransportProxy.
+//
+// The client must create the IceTransportProxy on the same thread it wishes
+// to control it from. The Proxy will manage all cross-thread interactions; the
+// client should call all methods from the proxy thread and all callbacks will
+// be run on the proxy thread.
+class IceTransportProxy final {
+ public:
+ // Delegate for receiving callbacks from the ICE implementation. These all run
+ // on the proxy thread.
+ class Delegate {
+ public:
+ virtual ~Delegate() = default;
+
+ virtual void OnGatheringStateChanged(cricket::IceGatheringState new_state) {
+ }
+ virtual void OnCandidateGathered(const cricket::Candidate& candidate) {}
+ virtual void OnStateChanged(cricket::IceTransportState new_state) {}
+ };
+
+ // Construct a Proxy with the underlying ICE implementation running on the
+ // given host thread and callbacks serviced by the given delegate.
+ // The P2PTransportChannel will be created with the given PortAllocator.
+ // The delegate must outlive the IceTransportProxy.
+ IceTransportProxy(FrameScheduler* frame_scheduler,
+ scoped_refptr<base::SingleThreadTaskRunner> host_thread,
+ rtc::Thread* host_thread_rtc_thread,
+ Delegate* delegate,
+ std::unique_ptr<cricket::PortAllocator> port_allocator);
+ ~IceTransportProxy();
+
+ void StartGathering(
+ const cricket::IceParameters& local_parameters,
+ const cricket::ServerAddresses& stun_servers,
+ const std::vector<cricket::RelayServerConfig>& turn_servers,
+ int32_t candidate_filter);
+
+ void SetRole(cricket::IceRole role);
+ void SetRemoteParameters(const cricket::IceParameters& remote_parameters);
+
+ void AddRemoteCandidate(const cricket::Candidate& candidate);
+ void ClearRemoteCandidates();
+
+ private:
+ // Callbacks from RTCIceTransportHost.
+ friend class IceTransportHost;
+ void OnGatheringStateChanged(cricket::IceGatheringState new_state);
+ void OnCandidateGathered(const cricket::Candidate& candidate);
+ void OnStateChanged(cricket::IceTransportState new_state);
+
+ const scoped_refptr<base::SingleThreadTaskRunner> host_thread_;
+ // Since the Host is deleted on the host thread (via OnTaskRunnerDeleter), as
+ // long as this is alive it is safe to post tasks to it (using unretained).
+ std::unique_ptr<IceTransportHost, base::OnTaskRunnerDeleter> host_;
+ Delegate* const delegate_;
+
+ // This handle notifies scheduler about an active connection associated
+ // with a frame. Handle should be destroyed when connection is closed.
+ // This should have the same lifetime as |proxy_|.
+ std::unique_ptr<FrameScheduler::ActiveConnectionHandle>
+ connection_handle_for_scheduler_;
+
+ THREAD_CHECKER(thread_checker_);
+
+ // Must be the last member.
+ base::WeakPtrFactory<IceTransportProxy> weak_ptr_factory_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_ICE_TRANSPORT_PROXY_H_
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.cc b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.cc
new file mode 100644
index 00000000000..0277157a502
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.cc
@@ -0,0 +1,5 @@
+// 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/peerconnection/adapters/web_rtc_cross_thread_copier.h"
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
new file mode 100644
index 00000000000..7f19fb64954
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h
@@ -0,0 +1,55 @@
+// 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_PEERCONNECTION_ADAPTERS_WEB_RTC_CROSS_THREAD_COPIER_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_WEB_RTC_CROSS_THREAD_COPIER_H_
+
+// This file defines specializations for the CrossThreadCopier that allow WebRTC
+// types to be passed across threads using their copy constructors.
+
+#include <set>
+#include <vector>
+
+#include "third_party/blink/renderer/platform/cross_thread_copier.h"
+
+namespace cricket {
+class Candidate;
+struct IceParameters;
+struct RelayServerConfig;
+} // namespace cricket
+
+namespace rtc {
+class SocketAddress;
+}
+
+namespace blink {
+
+template <>
+struct CrossThreadCopier<cricket::IceParameters>
+ : public CrossThreadCopierPassThrough<cricket::IceParameters> {
+ STATIC_ONLY(CrossThreadCopier);
+};
+
+template <>
+struct CrossThreadCopier<std::set<rtc::SocketAddress>>
+ : public CrossThreadCopierPassThrough<std::set<rtc::SocketAddress>> {
+ STATIC_ONLY(CrossThreadCopier);
+};
+
+template <>
+struct CrossThreadCopier<std::vector<cricket::RelayServerConfig>>
+ : public CrossThreadCopierPassThrough<
+ std::vector<cricket::RelayServerConfig>> {
+ STATIC_ONLY(CrossThreadCopier);
+};
+
+template <>
+struct CrossThreadCopier<cricket::Candidate>
+ : public CrossThreadCopierPassThrough<cricket::Candidate> {
+ STATIC_ONLY(CrossThreadCopier);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_WEB_RTC_CROSS_THREAD_COPIER_H_
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_certificate.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_certificate.cc
index 317ee0b17d4..4fd68ad6a02 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_certificate.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_certificate.cc
@@ -36,29 +36,31 @@
namespace blink {
-RTCCertificate::RTCCertificate(std::unique_ptr<WebRTCCertificate> certificate)
- : certificate_(base::WrapUnique(certificate.release())) {}
-
-std::unique_ptr<WebRTCCertificate> RTCCertificate::CertificateShallowCopy()
- const {
- return certificate_->ShallowCopy();
-}
+RTCCertificate::RTCCertificate(
+ rtc::scoped_refptr<rtc::RTCCertificate> certificate)
+ : certificate_(std::move(certificate)) {}
DOMTimeStamp RTCCertificate::expires() const {
return static_cast<DOMTimeStamp>(certificate_->Expires());
}
HeapVector<RTCDtlsFingerprint> RTCCertificate::getFingerprints() {
- WebVector<WebRTCDtlsFingerprint> web_fingerprints =
- certificate_->GetFingerprints();
- DCHECK(!web_fingerprints.IsEmpty());
- HeapVector<RTCDtlsFingerprint> fingerprints(web_fingerprints.size());
- for (size_t i = 0; i < fingerprints.size(); ++i) {
- DCHECK(!web_fingerprints[i].Algorithm().IsEmpty());
- DCHECK(!web_fingerprints[i].Value().IsEmpty());
- fingerprints[i].setAlgorithm(web_fingerprints[i].Algorithm());
- fingerprints[i].setValue(web_fingerprints[i].Value());
+ std::unique_ptr<rtc::SSLCertificateStats> first_certificate_stats =
+ certificate_->ssl_certificate().GetStats();
+
+ HeapVector<RTCDtlsFingerprint> fingerprints;
+ for (rtc::SSLCertificateStats* certificate_stats =
+ first_certificate_stats.get();
+ certificate_stats; certificate_stats = certificate_stats->issuer.get()) {
+ fingerprints.emplace_back();
+ auto& fingerprint = fingerprints.back();
+ fingerprint.setAlgorithm(WTF::String::FromUTF8(
+ certificate_stats->fingerprint_algorithm.c_str()));
+ fingerprint.setValue(
+ WTF::String::FromUTF8(certificate_stats->fingerprint.c_str())
+ .LowerASCII());
}
+
return fingerprints;
}
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 47fcbf5aa27..4b3aa2e47d1 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_certificate.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_certificate.h
@@ -33,7 +33,6 @@
#include <memory>
-#include "third_party/blink/public/platform/web_rtc_certificate.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"
@@ -41,6 +40,7 @@
#include "third_party/blink/renderer/platform/heap/garbage_collected.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/rtc_base/rtccertificate.h"
namespace blink {
@@ -49,18 +49,18 @@ class MODULES_EXPORT RTCCertificate final : public ScriptWrappable {
public:
// Takes ownership of the certificate.
- RTCCertificate(std::unique_ptr<WebRTCCertificate>);
+ RTCCertificate(rtc::scoped_refptr<rtc::RTCCertificate>);
- // Returns a new WebRTCCertificate shallow copy.
- std::unique_ptr<WebRTCCertificate> CertificateShallowCopy() const;
- const WebRTCCertificate& Certificate() const { return *certificate_; }
+ const rtc::scoped_refptr<rtc::RTCCertificate>& Certificate() const {
+ return certificate_;
+ }
// Returns the expiration time in ms relative to epoch, 1970-01-01T00:00:00Z.
DOMTimeStamp expires() const;
HeapVector<RTCDtlsFingerprint> getFingerprints();
private:
- std::unique_ptr<WebRTCCertificate> certificate_;
+ rtc::scoped_refptr<rtc::RTCCertificate> certificate_;
};
} // namespace blink
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 b68c03908dc..2c897858d57 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
@@ -373,7 +373,7 @@ void RTCDataChannel::ScheduledEventTimerFired(TimerBase*) {
HeapVector<Member<Event>>::iterator it = events.begin();
for (; it != events.end(); ++it)
- DispatchEvent((*it).Release());
+ DispatchEvent(*it->Release());
events.clear();
}
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 0e47b72215f..8f44593af4f 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
@@ -164,7 +164,7 @@ void RTCDTMFSender::ScheduledEventTimerFired(TimerBase*) {
HeapVector<Member<Event>>::iterator it = events.begin();
for (; it != events.end(); ++it)
- DispatchEvent((*it).Release());
+ DispatchEvent(*it->Release());
}
void RTCDTMFSender::Trace(blink::Visitor* visitor) {
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 d20987fe393..edb5571b9ca 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
@@ -25,6 +25,8 @@
#include "third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.h"
+#include "third_party/blink/renderer/core/event_type_names.h"
+
namespace blink {
RTCDTMFToneChangeEvent* RTCDTMFToneChangeEvent::Create(const String& tone) {
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate_pair.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate_pair.idl
new file mode 100644
index 00000000000..56681878be0
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate_pair.idl
@@ -0,0 +1,9 @@
+// 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://w3c.github.io/webrtc-pc/#dom-rtcicecandidatepair
+dictionary RTCIceCandidatePair {
+ RTCIceCandidate local;
+ RTCIceCandidate remote;
+};
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_gather_options.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_gather_options.idl
new file mode 100644
index 00000000000..441eeac53d5
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_gather_options.idl
@@ -0,0 +1,9 @@
+// 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://w3c.github.io/webrtc-ice/#dom-rtcicegatheroptions
+dictionary RTCIceGatherOptions {
+ RTCIceTransportPolicy gatherPolicy = "all";
+ sequence<RTCIceServer> iceServers;
+};
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_parameters.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_parameters.idl
new file mode 100644
index 00000000000..4598ce85781
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_parameters.idl
@@ -0,0 +1,9 @@
+// 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://w3c.github.io/webrtc-pc/#dom-rtciceparameters
+dictionary RTCIceParameters {
+ DOMString usernameFragment;
+ DOMString password;
+};
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
new file mode 100644
index 00000000000..117eccf66e5
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc
@@ -0,0 +1,409 @@
+// 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/peerconnection/rtc_ice_transport.h"
+
+#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/public/platform/web_thread.h"
+#include "third_party/blink/public/web/web_local_frame.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/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_ice_event.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event_init.h"
+#include "third_party/webrtc/api/jsepicecandidate.h"
+#include "third_party/webrtc/api/peerconnectioninterface.h"
+#include "third_party/webrtc/p2p/base/portallocator.h"
+#include "third_party/webrtc/p2p/base/transportdescription.h"
+#include "third_party/webrtc/pc/iceserverparsing.h"
+#include "third_party/webrtc/pc/webrtcsdp.h"
+
+namespace blink {
+namespace {
+
+const char* kIceRoleControllingStr = "controlling";
+const char* kIceRoleControlledStr = "controlled";
+
+base::Optional<cricket::Candidate> ConvertToCricketIceCandidate(
+ const RTCIceCandidate& candidate) {
+ webrtc::JsepIceCandidate jsep_candidate("", 0);
+ webrtc::SdpParseError error;
+ if (!webrtc::SdpDeserializeCandidate(WebString(candidate.candidate()).Utf8(),
+ &jsep_candidate, &error)) {
+ LOG(WARNING) << "Failed to deserialize candidate: " << error.description;
+ return base::nullopt;
+ }
+ return jsep_candidate.candidate();
+}
+
+RTCIceCandidate* ConvertToRtcIceCandidate(const cricket::Candidate& candidate) {
+ return RTCIceCandidate::Create(WebRTCICECandidate::Create(
+ WebString::FromUTF8(webrtc::SdpSerializeCandidate(candidate)), "", 0));
+}
+
+} // namespace
+
+RTCIceTransport* RTCIceTransport::Create(ExecutionContext* context) {
+ return new RTCIceTransport(context);
+}
+
+RTCIceTransport::RTCIceTransport(ExecutionContext* context)
+ : ContextLifecycleObserver(context) {
+ Document* document = ToDocument(GetExecutionContext());
+ LocalFrame* frame = document->GetFrame();
+ DCHECK(frame);
+
+ std::unique_ptr<cricket::PortAllocator> port_allocator =
+ Platform::Current()->CreateWebRtcPortAllocator(
+ WebLocalFrame::FrameForCurrentContext());
+ proxy_.reset(new IceTransportProxy(
+ frame->GetFrameScheduler(), Platform::Current()->GetWebRtcWorkerThread(),
+ Platform::Current()->GetWebRtcWorkerThreadRtcThread(), this,
+ std::move(port_allocator)));
+
+ GenerateLocalParameters();
+}
+
+RTCIceTransport::~RTCIceTransport() {
+ DCHECK(!proxy_);
+}
+
+String RTCIceTransport::role() const {
+ switch (role_) {
+ case cricket::ICEROLE_CONTROLLING:
+ return kIceRoleControllingStr;
+ case cricket::ICEROLE_CONTROLLED:
+ return kIceRoleControlledStr;
+ case cricket::ICEROLE_UNKNOWN:
+ return String();
+ }
+ NOTREACHED();
+ return String();
+}
+
+String RTCIceTransport::state() const {
+ switch (state_) {
+ case RTCIceTransportState::kNew:
+ return "new";
+ case RTCIceTransportState::kChecking:
+ return "checking";
+ case RTCIceTransportState::kConnected:
+ return "connected";
+ case RTCIceTransportState::kCompleted:
+ return "completed";
+ case RTCIceTransportState::kDisconnected:
+ return "disconnected";
+ case RTCIceTransportState::kFailed:
+ return "failed";
+ case RTCIceTransportState::kClosed:
+ return "closed";
+ }
+ NOTREACHED();
+ return g_empty_string;
+}
+
+String RTCIceTransport::gatheringState() const {
+ switch (gathering_state_) {
+ case cricket::kIceGatheringNew:
+ return "new";
+ case cricket::kIceGatheringGathering:
+ return "gathering";
+ case cricket::kIceGatheringComplete:
+ return "complete";
+ default:
+ NOTREACHED();
+ return g_empty_string;
+ }
+}
+
+const HeapVector<Member<RTCIceCandidate>>& RTCIceTransport::getLocalCandidates()
+ const {
+ return local_candidates_;
+}
+
+const HeapVector<Member<RTCIceCandidate>>&
+RTCIceTransport::getRemoteCandidates() const {
+ return remote_candidates_;
+}
+
+void RTCIceTransport::getSelectedCandidatePair(
+ base::Optional<RTCIceCandidatePair>& result) const {
+ result = selected_candidate_pair_;
+}
+
+void RTCIceTransport::getLocalParameters(
+ base::Optional<RTCIceParameters>& result) const {
+ result = local_parameters_;
+}
+
+void RTCIceTransport::getRemoteParameters(
+ base::Optional<RTCIceParameters>& result) const {
+ result = remote_parameters_;
+}
+
+static webrtc::PeerConnectionInterface::IceServer ConvertIceServer(
+ const RTCIceServer& ice_server) {
+ 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.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()) {
+ url_strings.push_back(ice_server.url());
+ }
+ for (const String& url_string : url_strings) {
+ converted_ice_server.urls.push_back(WebString(url_string).Utf8());
+ }
+ converted_ice_server.username = WebString(ice_server.username()).Utf8();
+ converted_ice_server.password = WebString(ice_server.credential()).Utf8();
+ return converted_ice_server;
+}
+
+static cricket::IceParameters ConvertIceParameters(
+ const RTCIceParameters& ice_parameters) {
+ cricket::IceParameters converted_ice_parameters;
+ converted_ice_parameters.ufrag =
+ WebString(ice_parameters.usernameFragment()).Utf8();
+ converted_ice_parameters.pwd = WebString(ice_parameters.password()).Utf8();
+ return converted_ice_parameters;
+}
+
+static std::vector<webrtc::PeerConnectionInterface::IceServer>
+ConvertIceServers(const HeapVector<RTCIceServer>& ice_servers) {
+ std::vector<webrtc::PeerConnectionInterface::IceServer> converted_ice_servers;
+ for (const RTCIceServer& ice_server : ice_servers) {
+ converted_ice_servers.push_back(ConvertIceServer(ice_server));
+ }
+ return converted_ice_servers;
+}
+
+void RTCIceTransport::gather(const RTCIceGatherOptions& options,
+ ExceptionState& exception_state) {
+ if (RaiseExceptionIfClosed(exception_state)) {
+ return;
+ }
+ // TODO(github.com/w3c/webrtc-ice/issues/7): Possibly support calling gather()
+ // more than once.
+ if (gathering_state_ != cricket::kIceGatheringNew) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Can only call gather() once.");
+ return;
+ }
+ std::vector<webrtc::PeerConnectionInterface::IceServer> ice_servers;
+ if (options.hasIceServers()) {
+ ice_servers = ConvertIceServers(options.iceServers());
+ }
+ cricket::ServerAddresses stun_servers;
+ std::vector<cricket::RelayServerConfig> turn_servers;
+ webrtc::RTCErrorType error_type =
+ webrtc::ParseIceServers(ice_servers, &stun_servers, &turn_servers);
+ if (error_type != webrtc::RTCErrorType::NONE) {
+ ThrowExceptionFromRTCError(
+ webrtc::RTCError(error_type, "Invalid ICE server URL(s)."),
+ exception_state);
+ return;
+ }
+ gathering_state_ = cricket::kIceGatheringGathering;
+ uint32_t candidate_filter = cricket::CF_ALL;
+ if (options.gatherPolicy() == "relay") {
+ candidate_filter = cricket::CF_RELAY;
+ } else {
+ DCHECK_EQ(options.gatherPolicy(), "all");
+ }
+ proxy_->StartGathering(ConvertIceParameters(local_parameters_), stun_servers,
+ turn_servers, candidate_filter);
+}
+
+static cricket::IceRole IceRoleFromString(const String& role_string) {
+ if (role_string == kIceRoleControllingStr) {
+ return cricket::ICEROLE_CONTROLLING;
+ }
+ if (role_string == kIceRoleControlledStr) {
+ return cricket::ICEROLE_CONTROLLED;
+ }
+ NOTREACHED();
+ return cricket::ICEROLE_UNKNOWN;
+}
+
+static bool RTCIceParametersAreEqual(const RTCIceParameters& a,
+ const RTCIceParameters& b) {
+ return a.usernameFragment() == b.usernameFragment() &&
+ a.password() == b.password();
+}
+
+void RTCIceTransport::start(const RTCIceParameters& remote_parameters,
+ const String& role_string,
+ ExceptionState& exception_state) {
+ if (RaiseExceptionIfClosed(exception_state)) {
+ return;
+ }
+ if (!remote_parameters.hasUsernameFragment() ||
+ !remote_parameters.hasPassword()) {
+ exception_state.ThrowTypeError(
+ "remoteParameters must have usernameFragment and password fields set.");
+ return;
+ }
+ cricket::IceRole role = IceRoleFromString(role_string);
+ if (role_ != cricket::ICEROLE_UNKNOWN && role != role_) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "Cannot change role once start() has been called.");
+ return;
+ }
+ if (remote_parameters_ &&
+ RTCIceParametersAreEqual(*remote_parameters_, remote_parameters)) {
+ // No change to remote parameters: do nothing.
+ return;
+ }
+ if (!remote_parameters_) {
+ // Calling start() for the first time.
+ proxy_->SetRole(role);
+ role_ = role;
+ if (remote_candidates_.size() > 0) {
+ for (RTCIceCandidate* remote_candidate : remote_candidates_) {
+ // This conversion is safe since we throw an exception in
+ // addRemoteCandidate on malformed ICE candidates.
+ proxy_->AddRemoteCandidate(
+ *ConvertToCricketIceCandidate(*remote_candidate));
+ }
+ state_ = RTCIceTransportState::kChecking;
+ }
+ } else {
+ proxy_->ClearRemoteCandidates();
+ remote_candidates_.clear();
+ state_ = RTCIceTransportState::kNew;
+ }
+ remote_parameters_ = remote_parameters;
+}
+
+void RTCIceTransport::stop() {
+ if (IsClosed()) {
+ return;
+ }
+ state_ = RTCIceTransportState::kClosed;
+ proxy_.reset();
+}
+
+void RTCIceTransport::addRemoteCandidate(RTCIceCandidate* remote_candidate,
+ ExceptionState& exception_state) {
+ if (RaiseExceptionIfClosed(exception_state)) {
+ return;
+ }
+ base::Optional<cricket::Candidate> converted_remote_candidate =
+ ConvertToCricketIceCandidate(*remote_candidate);
+ if (!converted_remote_candidate) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kOperationError,
+ "Invalid ICE candidate.");
+ return;
+ }
+ remote_candidates_.push_back(remote_candidate);
+ if (remote_parameters_) {
+ proxy_->AddRemoteCandidate(*converted_remote_candidate);
+ state_ = RTCIceTransportState::kChecking;
+ }
+}
+
+void RTCIceTransport::GenerateLocalParameters() {
+ local_parameters_.setUsernameFragment(
+ WebString::FromUTF8(rtc::CreateRandomString(cricket::ICE_UFRAG_LENGTH)));
+ local_parameters_.setPassword(
+ WebString::FromUTF8(rtc::CreateRandomString(cricket::ICE_PWD_LENGTH)));
+}
+
+void RTCIceTransport::OnGatheringStateChanged(
+ cricket::IceGatheringState new_state) {
+ if (new_state == gathering_state_) {
+ return;
+ }
+ if (new_state == cricket::kIceGatheringComplete) {
+ // Generate a null ICE candidate to signal the end of candidates.
+ DispatchEvent(*RTCPeerConnectionIceEvent::Create(nullptr));
+ }
+ gathering_state_ = new_state;
+ DispatchEvent(*Event::Create(EventTypeNames::gatheringstatechange));
+}
+
+void RTCIceTransport::OnCandidateGathered(
+ const cricket::Candidate& parsed_candidate) {
+ RTCIceCandidate* candidate = ConvertToRtcIceCandidate(parsed_candidate);
+ local_candidates_.push_back(candidate);
+ RTCPeerConnectionIceEventInit event_init;
+ event_init.setCandidate(candidate);
+ DispatchEvent(*RTCPeerConnectionIceEvent::Create(EventTypeNames::icecandidate,
+ event_init));
+}
+
+static RTCIceTransportState ConvertIceTransportState(
+ cricket::IceTransportState state) {
+ switch (state) {
+ case cricket::IceTransportState::STATE_INIT:
+ return RTCIceTransportState::kNew;
+ case cricket::IceTransportState::STATE_CONNECTING:
+ return RTCIceTransportState::kChecking;
+ case cricket::IceTransportState::STATE_COMPLETED:
+ return RTCIceTransportState::kConnected;
+ case cricket::IceTransportState::STATE_FAILED:
+ return RTCIceTransportState::kFailed;
+ default:
+ NOTREACHED();
+ return RTCIceTransportState::kClosed;
+ }
+}
+
+void RTCIceTransport::OnStateChanged(cricket::IceTransportState new_state) {
+ RTCIceTransportState local_new_state = ConvertIceTransportState(new_state);
+ if (local_new_state == state_) {
+ return;
+ }
+ state_ = local_new_state;
+ DispatchEvent(*Event::Create(EventTypeNames::statechange));
+}
+
+bool RTCIceTransport::RaiseExceptionIfClosed(
+ ExceptionState& exception_state) const {
+ if (IsClosed()) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "The RTCIceTransport's state is 'closed'.");
+ return true;
+ }
+ return false;
+}
+
+const AtomicString& RTCIceTransport::InterfaceName() const {
+ return EventTargetNames::RTCIceTransport;
+}
+
+ExecutionContext* RTCIceTransport::GetExecutionContext() const {
+ return ContextLifecycleObserver::GetExecutionContext();
+}
+
+void RTCIceTransport::ContextDestroyed(ExecutionContext*) {
+ stop();
+}
+
+bool RTCIceTransport::HasPendingActivity() const {
+ // Only allow the RTCIceTransport to be garbage collected if the ICE
+ // implementation is not active.
+ return static_cast<bool>(proxy_);
+}
+
+void RTCIceTransport::Trace(blink::Visitor* visitor) {
+ visitor->Trace(local_candidates_);
+ visitor->Trace(remote_candidates_);
+ visitor->Trace(selected_candidate_pair_);
+ EventTargetWithInlineData::Trace(visitor);
+ ContextLifecycleObserver::Trace(visitor);
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..fa8e307d1f9
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h
@@ -0,0 +1,125 @@
+// 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_PEERCONNECTION_RTC_ICE_TRANSPORT_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_ICE_TRANSPORT_H_
+
+#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/dom/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"
+
+namespace blink {
+
+class ExceptionState;
+class RTCIceCandidate;
+class RTCIceGatherOptions;
+
+enum class RTCIceTransportState {
+ kNew,
+ kChecking,
+ kConnected,
+ kCompleted,
+ kDisconnected,
+ kFailed,
+ kClosed
+};
+
+// Blink bindings for the RTCIceTransport JavaScript object.
+//
+// This class uses the IceTransportProxy to run and interact with the WebRTC
+// ICE implementation running on the WebRTC worker thread managed by //content
+// (called network_thread here).
+//
+// This object inherits from ActiveScriptWrappable since it must be kept alive
+// while the ICE implementation is active, regardless of the number of
+// JavaScript references held to it.
+class MODULES_EXPORT RTCIceTransport final
+ : public EventTargetWithInlineData,
+ public ActiveScriptWrappable<RTCIceTransport>,
+ public ContextLifecycleObserver,
+ private IceTransportProxy::Delegate {
+ DEFINE_WRAPPERTYPEINFO();
+ USING_GARBAGE_COLLECTED_MIXIN(RTCIceTransport);
+
+ public:
+ static RTCIceTransport* Create(ExecutionContext* context);
+
+ ~RTCIceTransport() override;
+
+ bool IsClosed() const { return state_ == RTCIceTransportState::kClosed; }
+
+ // rtc_ice_transport.idl
+ String role() const;
+ String state() const;
+ String gatheringState() const;
+ const HeapVector<Member<RTCIceCandidate>>& getLocalCandidates() const;
+ const HeapVector<Member<RTCIceCandidate>>& getRemoteCandidates() const;
+ void getSelectedCandidatePair(
+ base::Optional<RTCIceCandidatePair>& result) const;
+ void getLocalParameters(base::Optional<RTCIceParameters>& result) const;
+ void getRemoteParameters(base::Optional<RTCIceParameters>& result) const;
+ void gather(const RTCIceGatherOptions& options,
+ ExceptionState& exception_state);
+ void start(const RTCIceParameters& remote_parameters,
+ const String& role,
+ ExceptionState& exception_state);
+ void stop();
+ void addRemoteCandidate(RTCIceCandidate* remote_candidate,
+ ExceptionState& exception_state);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(statechange);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(gatheringstatechange);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(icecandidate);
+
+ // EventTarget overrides.
+ const AtomicString& InterfaceName() const override;
+ ExecutionContext* GetExecutionContext() const override;
+
+ // ContextLifecycleObserver overrides.
+ void ContextDestroyed(ExecutionContext*) override;
+
+ // ActiveScriptWrappable overrides.
+ bool HasPendingActivity() const override;
+
+ // For garbage collection.
+ void Trace(blink::Visitor* visitor) override;
+
+ private:
+ explicit RTCIceTransport(ExecutionContext* context);
+
+ // IceTransportProxy::Delegate overrides.
+ void OnGatheringStateChanged(cricket::IceGatheringState new_state) override;
+ void OnCandidateGathered(const cricket::Candidate& candidate) override;
+ void OnStateChanged(cricket::IceTransportState new_state) override;
+
+ // Fills in |local_parameters_| with a random usernameFragment and a random
+ // password.
+ void GenerateLocalParameters();
+
+ bool RaiseExceptionIfClosed(ExceptionState& exception_state) const;
+
+ cricket::IceRole role_ = cricket::ICEROLE_UNKNOWN;
+ RTCIceTransportState state_ = RTCIceTransportState::kNew;
+ cricket::IceGatheringState gathering_state_ = cricket::kIceGatheringNew;
+
+ HeapVector<Member<RTCIceCandidate>> local_candidates_;
+ HeapVector<Member<RTCIceCandidate>> remote_candidates_;
+
+ RTCIceParameters local_parameters_;
+ base::Optional<RTCIceParameters> remote_parameters_;
+
+ base::Optional<RTCIceCandidatePair> selected_candidate_pair_;
+
+ // Handle to the WebRTC ICE transport. Created when this binding is
+ // constructed and deleted once network traffic should be stopped.
+ std::unique_ptr<IceTransportProxy> proxy_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_ICE_TRANSPORT_H_
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
new file mode 100644
index 00000000000..a2aca1fe626
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.idl
@@ -0,0 +1,60 @@
+// 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://w3c.github.io/webrtc-pc/#dom-rtcicerole
+enum RTCIceRole {
+ "controlling",
+ "controlled",
+};
+
+// https://w3c.github.io/webrtc-pc/#dom-rtcicetransportstate
+enum RTCIceTransportState {
+ "new",
+ "checking",
+ "connected",
+ "completed",
+ "disconnected",
+ "failed",
+ "closed",
+};
+
+// https://w3c.github.io/webrtc-pc/#dom-rtcicegatheringstate
+enum RTCIceGatheringState {
+ "new",
+ "gathering",
+ "complete"
+};
+
+// https://w3c.github.io/webrtc-pc/#rtcicetransport
+[
+ ActiveScriptWrappable,
+ // Constructor from https://w3c.github.io/webrtc-ice/#rtcicetransport*
+ Constructor(),
+ ConstructorCallWith=ExecutionContext,
+ Exposed=Window,
+ RuntimeEnabled=RTCIceTransportExtension
+] interface RTCIceTransport : EventTarget {
+ // TODO(github.com/w3c/webrtc-ice/issues/4): role is non-null in the
+ // WebRTC-PC specification.
+ readonly attribute RTCIceRole? role;
+ readonly attribute RTCIceTransportState state;
+ readonly attribute RTCIceGatheringState gatheringState;
+ sequence<RTCIceCandidate> getLocalCandidates();
+ sequence<RTCIceCandidate> getRemoteCandidates();
+ RTCIceCandidatePair? getSelectedCandidatePair();
+ RTCIceParameters? getLocalParameters();
+ RTCIceParameters? getRemoteParameters();
+ attribute EventHandler onstatechange;
+ attribute EventHandler ongatheringstatechange;
+ // TODO(crbug.com/864871): Implement onselectedcandidatepairchange.
+
+ // The following is defined in the WebRTC-ICE extension specification.
+ // https://w3c.github.io/webrtc-ice/#rtcicetransport*
+ [RaisesException] void gather(RTCIceGatherOptions options);
+ [RaisesException] void start(RTCIceParameters remoteParameters, optional RTCIceRole role = "controlled");
+ void stop();
+ [RaisesException] void addRemoteCandidate(RTCIceCandidate remoteCandidate);
+ // TODO(crbug.com/864871): Implement onerror.
+ attribute EventHandler onicecandidate;
+};
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 1506e6e6346..f89532a99f3 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
@@ -36,15 +36,15 @@
#include <utility>
#include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_macros.h"
#include "base/optional.h"
+#include "services/metrics/public/cpp/ukm_builders.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_crypto_algorithm_params.h"
#include "third_party/blink/public/platform/web_media_stream.h"
#include "third_party/blink/public/platform/web_rtc_answer_options.h"
-#include "third_party/blink/public/platform/web_rtc_certificate.h"
#include "third_party/blink/public/platform/web_rtc_certificate_generator.h"
-#include "third_party/blink/public/platform/web_rtc_configuration.h"
#include "third_party/blink/public/platform/web_rtc_data_channel_handler.h"
#include "third_party/blink/public/platform/web_rtc_data_channel_init.h"
#include "third_party/blink/public/platform/web_rtc_ice_candidate.h"
@@ -113,6 +113,7 @@
#include "third_party/blink/renderer/platform/peerconnection/rtc_offer_options_platform.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/time.h"
+#include "third_party/webrtc/api/peerconnectioninterface.h"
namespace blink {
@@ -226,6 +227,29 @@ scoped_refptr<WebRTCICECandidate> ConvertToWebRTCIceCandidate(
return candidate.GetAsRTCIceCandidate()->WebCandidate();
}
+enum SdpSemanticRequested {
+ kSdpSemanticRequestedDefault,
+ kSdpSemanticRequestedPlanB,
+ kSdpSemanticRequestedUnifiedPlan,
+ kSdpSemanticRequestedMax
+};
+
+SdpSemanticRequested GetSdpSemanticRequested(
+ const blink::RTCConfiguration& configuration) {
+ if (!configuration.hasSdpSemantics()) {
+ return kSdpSemanticRequestedDefault;
+ }
+ if (configuration.sdpSemantics() == "plan-b") {
+ return kSdpSemanticRequestedPlanB;
+ }
+ if (configuration.sdpSemantics() == "unified-plan") {
+ return kSdpSemanticRequestedUnifiedPlan;
+ }
+
+ NOTREACHED();
+ return kSdpSemanticRequestedDefault;
+}
+
// Helper class for RTCPeerConnection::generateCertificate.
class WebRTCCertificateObserver : public WebRTCCertificateCallback {
public:
@@ -240,7 +264,7 @@ class WebRTCCertificateObserver : public WebRTCCertificateCallback {
explicit WebRTCCertificateObserver(ScriptPromiseResolver* resolver)
: resolver_(resolver) {}
- void OnSuccess(std::unique_ptr<WebRTCCertificate> certificate) override {
+ void OnSuccess(rtc::scoped_refptr<rtc::RTCCertificate> certificate) override {
resolver_->Resolve(new RTCCertificate(std::move(certificate)));
}
@@ -249,68 +273,70 @@ class WebRTCCertificateObserver : public WebRTCCertificateCallback {
Persistent<ScriptPromiseResolver> resolver_;
};
-WebRTCIceTransportPolicy IceTransportPolicyFromString(const String& policy) {
+webrtc::PeerConnectionInterface::IceTransportsType IceTransportPolicyFromString(
+ const String& policy) {
if (policy == "relay")
- return WebRTCIceTransportPolicy::kRelay;
+ return webrtc::PeerConnectionInterface::kRelay;
DCHECK_EQ(policy, "all");
- return WebRTCIceTransportPolicy::kAll;
+ return webrtc::PeerConnectionInterface::kAll;
}
-WebRTCConfiguration ParseConfiguration(ExecutionContext* context,
- const RTCConfiguration& configuration,
- ExceptionState& exception_state) {
+webrtc::PeerConnectionInterface::RTCConfiguration ParseConfiguration(
+ ExecutionContext* context,
+ const RTCConfiguration& configuration,
+ ExceptionState& exception_state) {
DCHECK(context);
- WebRTCIceTransportPolicy ice_transport_policy =
- WebRTCIceTransportPolicy::kAll;
+ webrtc::PeerConnectionInterface::RTCConfiguration web_configuration;
+
if (configuration.hasIceTransportPolicy()) {
UseCounter::Count(context, WebFeature::kRTCConfigurationIceTransportPolicy);
- ice_transport_policy =
+ web_configuration.type =
IceTransportPolicyFromString(configuration.iceTransportPolicy());
} else if (configuration.hasIceTransports()) {
UseCounter::Count(context, WebFeature::kRTCConfigurationIceTransports);
- ice_transport_policy =
+ web_configuration.type =
IceTransportPolicyFromString(configuration.iceTransports());
}
- WebRTCBundlePolicy bundle_policy = WebRTCBundlePolicy::kBalanced;
- String bundle_policy_string = configuration.bundlePolicy();
- if (bundle_policy_string == "max-compat") {
- bundle_policy = WebRTCBundlePolicy::kMaxCompat;
- } else if (bundle_policy_string == "max-bundle") {
- bundle_policy = WebRTCBundlePolicy::kMaxBundle;
+ if (configuration.bundlePolicy() == "max-compat") {
+ web_configuration.bundle_policy =
+ webrtc::PeerConnectionInterface::kBundlePolicyMaxCompat;
+ } else if (configuration.bundlePolicy() == "max-bundle") {
+ web_configuration.bundle_policy =
+ webrtc::PeerConnectionInterface::kBundlePolicyMaxBundle;
} else {
- DCHECK_EQ(bundle_policy_string, "balanced");
+ DCHECK_EQ(configuration.bundlePolicy(), "balanced");
}
- WebRTCRtcpMuxPolicy rtcp_mux_policy = WebRTCRtcpMuxPolicy::kRequire;
- String rtcp_mux_policy_string = configuration.rtcpMuxPolicy();
- if (rtcp_mux_policy_string == "negotiate") {
- rtcp_mux_policy = WebRTCRtcpMuxPolicy::kNegotiate;
+ if (configuration.rtcpMuxPolicy() == "negotiate") {
+ web_configuration.rtcp_mux_policy =
+ webrtc::PeerConnectionInterface::kRtcpMuxPolicyNegotiate;
Deprecation::CountDeprecation(context, WebFeature::kRtcpMuxPolicyNegotiate);
} else {
- DCHECK_EQ(rtcp_mux_policy_string, "require");
+ DCHECK_EQ(configuration.rtcpMuxPolicy(), "require");
}
- WebRTCSdpSemantics sdp_semantics = WebRTCSdpSemantics::kDefault;
if (configuration.hasSdpSemantics()) {
- String sdp_semantics_string = configuration.sdpSemantics();
- if (sdp_semantics_string == "plan-b") {
- sdp_semantics = WebRTCSdpSemantics::kPlanB;
+ if (configuration.sdpSemantics() == "plan-b") {
+ web_configuration.sdp_semantics = webrtc::SdpSemantics::kPlanB;
} else {
- DCHECK_EQ(sdp_semantics_string, "unified-plan");
- sdp_semantics = WebRTCSdpSemantics::kUnifiedPlan;
+ DCHECK_EQ(configuration.sdpSemantics(), "unified-plan");
+ web_configuration.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan;
+ }
+ } else {
+ if (!RuntimeEnabledFeatures::RTCUnifiedPlanByDefaultEnabled()) {
+ // By default: The default SDP semantics is: "kPlanB".
+ web_configuration.sdp_semantics = webrtc::SdpSemantics::kPlanB;
+ } else {
+ // Override default SDP semantics to "kUnifiedPlan" with
+ // RuntimeEnabled=RTCUnifiedPlanByDefault.
+ web_configuration.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan;
}
}
- WebRTCConfiguration web_configuration;
- web_configuration.ice_transport_policy = ice_transport_policy;
- web_configuration.bundle_policy = bundle_policy;
- web_configuration.rtcp_mux_policy = rtcp_mux_policy;
- web_configuration.sdp_semantics = sdp_semantics;
-
if (configuration.hasIceServers()) {
- Vector<WebRTCIceServer> ice_servers;
+ std::vector<webrtc::PeerConnectionInterface::IceServer> ice_servers;
for (const RTCIceServer& ice_server : configuration.iceServers()) {
Vector<String> url_strings;
if (ice_server.hasURLs()) {
@@ -327,7 +353,7 @@ WebRTCConfiguration ParseConfiguration(ExecutionContext* context,
url_strings.push_back(ice_server.url());
} else {
exception_state.ThrowTypeError("Malformed RTCIceServer");
- return WebRTCConfiguration();
+ return {};
}
String username = ice_server.username();
@@ -339,7 +365,7 @@ WebRTCConfiguration ParseConfiguration(ExecutionContext* context,
exception_state.ThrowDOMException(
DOMExceptionCode::kSyntaxError,
"'" + url_string + "' is not a valid URL.");
- return WebRTCConfiguration();
+ return {};
}
if (!(url.ProtocolIs("turn") || url.ProtocolIs("turns") ||
url.ProtocolIs("stun"))) {
@@ -348,7 +374,7 @@ WebRTCConfiguration ParseConfiguration(ExecutionContext* context,
"'" + url.Protocol() +
"' is not one of the supported URL schemes "
"'stun', 'turn' or 'turns'.");
- return WebRTCConfiguration();
+ return {};
}
if ((url.ProtocolIs("turn") || url.ProtocolIs("turns")) &&
(username.IsNull() || credential.IsNull())) {
@@ -358,19 +384,23 @@ WebRTCConfiguration ParseConfiguration(ExecutionContext* context,
"required when the URL scheme is "
"\"turn\" or \"turns\".");
}
- ice_servers.push_back(WebRTCIceServer{url, username, credential});
+ ice_servers.emplace_back();
+ auto& converted_ice_server = ice_servers.back();
+ converted_ice_server.urls.push_back(WebString(url).Utf8());
+ converted_ice_server.username = WebString(username).Utf8();
+ converted_ice_server.password = WebString(credential).Utf8();
}
}
- web_configuration.ice_servers = ice_servers;
+ web_configuration.servers = ice_servers;
}
if (configuration.hasCertificates()) {
const HeapVector<Member<RTCCertificate>>& certificates =
configuration.certificates();
- WebVector<std::unique_ptr<WebRTCCertificate>> certificates_copy(
+ std::vector<rtc::scoped_refptr<rtc::RTCCertificate>> certificates_copy(
certificates.size());
for (size_t i = 0; i < certificates.size(); ++i) {
- certificates_copy[i] = certificates[i]->CertificateShallowCopy();
+ certificates_copy[i] = certificates[i]->Certificate();
}
web_configuration.certificates = std::move(certificates_copy);
}
@@ -491,7 +521,7 @@ RTCPeerConnection* RTCPeerConnection::Create(
WebFeature::kRTCPeerConnectionConstructorCompliant);
}
- WebRTCConfiguration configuration =
+ webrtc::PeerConnectionInterface::RTCConfiguration configuration =
ParseConfiguration(context, rtc_configuration, exception_state);
if (exception_state.HadException())
return nullptr;
@@ -499,7 +529,7 @@ RTCPeerConnection* RTCPeerConnection::Create(
// Make sure no certificates have expired.
if (configuration.certificates.size() > 0) {
DOMTimeStamp now = ConvertSecondsToDOMTimeStamp(CurrentTime());
- for (const std::unique_ptr<WebRTCCertificate>& certificate :
+ for (const rtc::scoped_refptr<rtc::RTCCertificate>& certificate :
configuration.certificates) {
DOMTimeStamp expires = certificate->Expires();
if (expires <= now) {
@@ -524,13 +554,18 @@ RTCPeerConnection* RTCPeerConnection::Create(
if (exception_state.HadException())
return nullptr;
+ UMA_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.SdpSemanticRequested",
+ GetSdpSemanticRequested(rtc_configuration),
+ kSdpSemanticRequestedMax);
+
return peer_connection;
}
-RTCPeerConnection::RTCPeerConnection(ExecutionContext* context,
- WebRTCConfiguration configuration,
- WebMediaConstraints constraints,
- ExceptionState& exception_state)
+RTCPeerConnection::RTCPeerConnection(
+ ExecutionContext* context,
+ webrtc::PeerConnectionInterface::RTCConfiguration configuration,
+ WebMediaConstraints constraints,
+ ExceptionState& exception_state)
: PausableObject(context),
signaling_state_(
webrtc::PeerConnectionInterface::SignalingState::kStable),
@@ -548,24 +583,6 @@ RTCPeerConnection::RTCPeerConnection(ExecutionContext* context,
closed_(false),
has_data_channels_(false),
sdp_semantics_(configuration.sdp_semantics) {
- // The original SDP semantics value is the value passed in by the caller,
- // which if not specified has the value "kDefault". For |sdp_semantics_| this
- // is translated to the actual SDP semantics used ("kPlanB" or
- // "kUnifiedPlan"), but for the sake of UMA use counters it is of interest to
- // know if the caller did not explicitly set it.
- WebRTCSdpSemantics original_sdp_semantics_value = sdp_semantics_;
- if (sdp_semantics_ == WebRTCSdpSemantics::kDefault) {
- if (!RuntimeEnabledFeatures::RTCUnifiedPlanByDefaultEnabled()) {
- // By default: The default SDP semantics is: "kPlanB".
- sdp_semantics_ = configuration.sdp_semantics = WebRTCSdpSemantics::kPlanB;
- } else {
- // Override default SDP semantics to "kUnifiedPlan" with
- // RuntimeEnabled=RTCUnifiedPlanByDefault.
- sdp_semantics_ = configuration.sdp_semantics =
- WebRTCSdpSemantics::kUnifiedPlan;
- }
- }
-
Document* document = ToDocument(GetExecutionContext());
InstanceCounters::IncrementCounter(
@@ -603,8 +620,7 @@ RTCPeerConnection::RTCPeerConnection(ExecutionContext* context,
document->GetFrame()->Client()->DispatchWillStartUsingPeerConnectionHandler(
peer_handler_.get());
- if (!peer_handler_->Initialize(configuration, constraints,
- original_sdp_semantics_value)) {
+ if (!peer_handler_->Initialize(configuration, constraints)) {
closed_ = true;
stopped_ = true;
exception_state.ThrowDOMException(
@@ -889,6 +905,24 @@ RTCSessionDescription* RTCPeerConnection::localDescription() {
return RTCSessionDescription::Create(web_session_description);
}
+RTCSessionDescription* RTCPeerConnection::currentLocalDescription() {
+ WebRTCSessionDescription web_session_description =
+ peer_handler_->CurrentLocalDescription();
+ if (web_session_description.IsNull())
+ return nullptr;
+
+ return RTCSessionDescription::Create(web_session_description);
+}
+
+RTCSessionDescription* RTCPeerConnection::pendingLocalDescription() {
+ WebRTCSessionDescription web_session_description =
+ peer_handler_->PendingLocalDescription();
+ if (web_session_description.IsNull())
+ return nullptr;
+
+ return RTCSessionDescription::Create(web_session_description);
+}
+
ScriptPromise RTCPeerConnection::setRemoteDescription(
ScriptState* script_state,
const RTCSessionDescriptionInit& session_description_init) {
@@ -952,6 +986,106 @@ RTCSessionDescription* RTCPeerConnection::remoteDescription() {
return RTCSessionDescription::Create(web_session_description);
}
+RTCSessionDescription* RTCPeerConnection::currentRemoteDescription() {
+ WebRTCSessionDescription web_session_description =
+ peer_handler_->CurrentRemoteDescription();
+ if (web_session_description.IsNull())
+ return nullptr;
+
+ return RTCSessionDescription::Create(web_session_description);
+}
+
+RTCSessionDescription* RTCPeerConnection::pendingRemoteDescription() {
+ WebRTCSessionDescription web_session_description =
+ peer_handler_->PendingRemoteDescription();
+ if (web_session_description.IsNull())
+ return nullptr;
+
+ return RTCSessionDescription::Create(web_session_description);
+}
+
+void RTCPeerConnection::getConfiguration(RTCConfiguration& result) {
+ const auto& webrtc_configuration = peer_handler_->GetConfiguration();
+
+ switch (webrtc_configuration.type) {
+ case webrtc::PeerConnectionInterface::kRelay:
+ result.setIceTransportPolicy("relay");
+ break;
+ case webrtc::PeerConnectionInterface::kAll:
+ result.setIceTransportPolicy("all");
+ break;
+ default:
+ NOTREACHED();
+ }
+
+ switch (webrtc_configuration.bundle_policy) {
+ case webrtc::PeerConnectionInterface::kBundlePolicyMaxCompat:
+ result.setBundlePolicy("max-compat");
+ break;
+ case webrtc::PeerConnectionInterface::kBundlePolicyMaxBundle:
+ result.setBundlePolicy("max-bundle");
+ break;
+ case webrtc::PeerConnectionInterface::kBundlePolicyBalanced:
+ result.setBundlePolicy("balanced");
+ break;
+ default:
+ NOTREACHED();
+ }
+
+ switch (webrtc_configuration.rtcp_mux_policy) {
+ case webrtc::PeerConnectionInterface::kRtcpMuxPolicyNegotiate:
+ result.setRtcpMuxPolicy("negotiate");
+ break;
+ case webrtc::PeerConnectionInterface::kRtcpMuxPolicyRequire:
+ result.setRtcpMuxPolicy("require");
+ break;
+ default:
+ NOTREACHED();
+ }
+
+ switch (webrtc_configuration.sdp_semantics) {
+ case webrtc::SdpSemantics::kPlanB:
+ result.setSdpSemantics("plan-b");
+ break;
+ case webrtc::SdpSemantics::kUnifiedPlan:
+ result.setSdpSemantics("unified-plan");
+ break;
+ default:
+ NOTREACHED();
+ }
+
+ HeapVector<RTCIceServer> ice_servers;
+ ice_servers.ReserveCapacity(webrtc_configuration.servers.size());
+ for (const auto& webrtc_server : webrtc_configuration.servers) {
+ ice_servers.emplace_back();
+ auto& ice_server = ice_servers.back();
+
+ StringOrStringSequence urls;
+ Vector<String> url_vector;
+ url_vector.ReserveCapacity(webrtc_server.urls.size());
+ for (const auto& url : webrtc_server.urls) {
+ url_vector.emplace_back(url.c_str());
+ }
+ urls.SetStringSequence(std::move(url_vector));
+
+ ice_server.setURLs(urls);
+ ice_server.setUsername(webrtc_server.username.c_str());
+ ice_server.setCredential(webrtc_server.password.c_str());
+ }
+ result.setIceServers(ice_servers);
+
+ if (!webrtc_configuration.certificates.empty()) {
+ HeapVector<blink::Member<RTCCertificate>> certificates;
+ certificates.ReserveCapacity(webrtc_configuration.certificates.size());
+ for (const auto& webrtc_certificate : webrtc_configuration.certificates) {
+ certificates.emplace_back(new RTCCertificate(webrtc_certificate));
+ }
+ result.setCertificates(certificates);
+ }
+
+ result.setIceCandidatePoolSize(webrtc_configuration.ice_candidate_pool_size);
+}
+
void RTCPeerConnection::setConfiguration(
ScriptState* script_state,
const RTCConfiguration& rtc_configuration,
@@ -959,14 +1093,9 @@ void RTCPeerConnection::setConfiguration(
if (ThrowExceptionIfSignalingStateClosed(signaling_state_, exception_state))
return;
- WebRTCConfiguration configuration = ParseConfiguration(
- ExecutionContext::From(script_state), rtc_configuration, exception_state);
- // Overwrite "kDefault" with |sdp_semantics_| as set in the constructor to
- // avoid duplicate logic for interpreting the default and SetConfiguration()
- // failing if different layers have different notions of default.
- if (configuration.sdp_semantics == blink::WebRTCSdpSemantics::kDefault) {
- configuration.sdp_semantics = sdp_semantics_;
- }
+ webrtc::PeerConnectionInterface::RTCConfiguration configuration =
+ ParseConfiguration(ExecutionContext::From(script_state),
+ rtc_configuration, exception_state);
if (exception_state.HadException())
return;
@@ -1296,7 +1425,7 @@ String RTCPeerConnection::id(ScriptState* script_state) const {
MediaStreamVector RTCPeerConnection::getLocalStreams() const {
MediaStreamVector local_streams;
- if (sdp_semantics_ == WebRTCSdpSemantics::kPlanB) {
+ if (sdp_semantics_ == webrtc::SdpSemantics::kPlanB) {
for (const auto& sender : rtp_senders_) {
for (const auto& stream : sender->streams()) {
if (!local_streams.Contains(stream))
@@ -1318,7 +1447,7 @@ MediaStreamVector RTCPeerConnection::getLocalStreams() const {
MediaStreamVector RTCPeerConnection::getRemoteStreams() const {
MediaStreamVector remote_streams;
- if (sdp_semantics_ == WebRTCSdpSemantics::kPlanB) {
+ if (sdp_semantics_ == webrtc::SdpSemantics::kPlanB) {
for (const auto& receiver : rtp_receivers_) {
for (const auto& stream : receiver->streams()) {
if (!remote_streams.Contains(stream))
@@ -1505,7 +1634,7 @@ RTCRtpTransceiver* RTCPeerConnection::addTransceiver(
const MediaStreamTrackOrString& track_or_kind,
const RTCRtpTransceiverInit& init,
ExceptionState& exception_state) {
- if (sdp_semantics_ != WebRTCSdpSemantics::kUnifiedPlan) {
+ if (sdp_semantics_ != webrtc::SdpSemantics::kUnifiedPlan) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
kOnlySupportedInUnifiedPlanMessage);
return nullptr;
@@ -1552,7 +1681,7 @@ RTCRtpSender* RTCPeerConnection::addTrack(MediaStreamTrack* track,
DCHECK(track->Component());
if (ThrowExceptionIfSignalingStateClosed(signaling_state_, exception_state))
return nullptr;
- if (sdp_semantics_ == WebRTCSdpSemantics::kPlanB && streams.size() >= 2) {
+ if (sdp_semantics_ == webrtc::SdpSemantics::kPlanB && streams.size() >= 2) {
// TODO(hbos): Update peer_handler_ to call the AddTrack() that returns the
// appropriate errors, and let the lower layers handle it.
exception_state.ThrowDOMException(
@@ -1589,12 +1718,12 @@ RTCRtpSender* RTCPeerConnection::addTrack(MediaStreamTrack* track,
auto stream_ids = web_transceiver->Sender()->StreamIds();
RTCRtpSender* sender;
- if (sdp_semantics_ == WebRTCSdpSemantics::kPlanB) {
+ if (sdp_semantics_ == webrtc::SdpSemantics::kPlanB) {
DCHECK_EQ(web_transceiver->ImplementationType(),
WebRTCRtpTransceiverImplementationType::kPlanBSenderOnly);
sender = CreateOrUpdateSender(web_transceiver->Sender(), track->kind());
} else {
- DCHECK_EQ(sdp_semantics_, WebRTCSdpSemantics::kUnifiedPlan);
+ DCHECK_EQ(sdp_semantics_, webrtc::SdpSemantics::kUnifiedPlan);
DCHECK_EQ(web_transceiver->ImplementationType(),
WebRTCRtpTransceiverImplementationType::kFullTransceiver);
RTCRtpTransceiver* transceiver =
@@ -1607,10 +1736,10 @@ RTCRtpSender* RTCPeerConnection::addTrack(MediaStreamTrack* track,
// The stream IDs should match between layers, with one exception;
// in Plan B if no stream was supplied, the lower layer still generates a
// stream which has no blink layer correspondence.
- DCHECK(sdp_semantics_ != WebRTCSdpSemantics::kPlanB ||
+ DCHECK(sdp_semantics_ != webrtc::SdpSemantics::kPlanB ||
(streams.size() == 0u && stream_ids.size() == 1u) ||
stream_ids.size() == streams.size());
- DCHECK(sdp_semantics_ != WebRTCSdpSemantics::kUnifiedPlan ||
+ DCHECK(sdp_semantics_ != webrtc::SdpSemantics::kUnifiedPlan ||
stream_ids.size() == streams.size());
return sender;
}
@@ -1629,7 +1758,7 @@ void RTCPeerConnection::removeTrack(RTCRtpSender* sender,
}
auto error_or_transceiver = peer_handler_->RemoveTrack(sender->web_sender());
- if (sdp_semantics_ == WebRTCSdpSemantics::kPlanB) {
+ if (sdp_semantics_ == webrtc::SdpSemantics::kPlanB) {
// Plan B: Was the sender removed?
if (!error_or_transceiver.ok()) {
// Operation aborted. This indicates that the sender is no longer used by
@@ -1644,7 +1773,7 @@ void RTCPeerConnection::removeTrack(RTCRtpSender* sender,
rtp_senders_.erase(it);
} else {
// Unified Plan: Was the transceiver updated?
- DCHECK_EQ(sdp_semantics_, WebRTCSdpSemantics::kUnifiedPlan);
+ DCHECK_EQ(sdp_semantics_, webrtc::SdpSemantics::kUnifiedPlan);
if (!error_or_transceiver.ok()) {
ThrowExceptionFromRTCError(error_or_transceiver.error(), exception_state);
return;
@@ -1930,7 +2059,7 @@ void RTCPeerConnection::MaybeFireNegotiationNeeded() {
if (!negotiation_needed_ || closed_)
return;
negotiation_needed_ = false;
- DispatchEvent(Event::Create(EventTypeNames::negotiationneeded));
+ DispatchEvent(*Event::Create(EventTypeNames::negotiationneeded));
}
void RTCPeerConnection::DidGenerateICECandidate(
@@ -1968,7 +2097,7 @@ void RTCPeerConnection::DidAddReceiverPlanB(
std::unique_ptr<WebRTCRtpReceiver> web_receiver) {
DCHECK(!closed_);
DCHECK(GetExecutionContext()->IsContextThread());
- DCHECK_EQ(sdp_semantics_, WebRTCSdpSemantics::kPlanB);
+ DCHECK_EQ(sdp_semantics_, webrtc::SdpSemantics::kPlanB);
if (signaling_state_ ==
webrtc::PeerConnectionInterface::SignalingState::kClosed)
return;
@@ -2024,7 +2153,7 @@ void RTCPeerConnection::DidRemoveReceiverPlanB(
std::unique_ptr<WebRTCRtpReceiver> web_receiver) {
DCHECK(!closed_);
DCHECK(GetExecutionContext()->IsContextThread());
- DCHECK_EQ(sdp_semantics_, WebRTCSdpSemantics::kPlanB);
+ DCHECK_EQ(sdp_semantics_, webrtc::SdpSemantics::kPlanB);
auto* it = FindReceiver(*web_receiver);
DCHECK(it != rtp_receivers_.end());
@@ -2191,6 +2320,14 @@ void RTCPeerConnection::DidAddRemoteDataChannel(
has_data_channels_ = true;
}
+void RTCPeerConnection::DidNoteInterestingUsage(int usage_pattern) {
+ Document* document = ToDocument(GetExecutionContext());
+ ukm::SourceId source_id = document->UkmSourceID();
+ ukm::builders::WebRTC_AddressHarvesting(source_id)
+ .SetUsagePattern(usage_pattern)
+ .Record(document->UkmRecorder());
+}
+
void RTCPeerConnection::ReleasePeerConnectionHandler() {
if (stopped_)
return;
@@ -2242,7 +2379,7 @@ void RTCPeerConnection::ChangeSignalingState(
signaling_state_ = signaling_state;
Event* event = Event::Create(EventTypeNames::signalingstatechange);
if (dispatch_event_immediately)
- DispatchEvent(event);
+ DispatchEvent(*event);
else
ScheduleDispatchEvent(event);
}
@@ -2338,7 +2475,7 @@ void RTCPeerConnection::DispatchScheduledEvent() {
HeapVector<Member<EventWrapper>>::iterator it = events.begin();
for (; it != events.end(); ++it) {
if ((*it)->Setup()) {
- DispatchEvent((*it)->event_.Release());
+ DispatchEvent(*(*it)->event_.Release());
}
}
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 0c170bb7499..49450d4fd8d 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,7 +34,6 @@
#include <memory>
#include "third_party/blink/public/platform/web_media_constraints.h"
-#include "third_party/blink/public/platform/web_rtc_configuration.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"
@@ -72,7 +71,6 @@ class V8RTCPeerConnectionErrorCallback;
class V8RTCSessionDescriptionCallback;
class V8RTCStatsCallback;
class V8VoidFunction;
-struct WebRTCConfiguration;
class MODULES_EXPORT RTCPeerConnection final
: public EventTargetWithInlineData,
@@ -112,6 +110,8 @@ class MODULES_EXPORT RTCPeerConnection final
V8VoidFunction*,
V8RTCPeerConnectionErrorCallback* = nullptr);
RTCSessionDescription* localDescription();
+ RTCSessionDescription* currentLocalDescription();
+ RTCSessionDescription* pendingLocalDescription();
ScriptPromise setRemoteDescription(ScriptState*,
const RTCSessionDescriptionInit&);
@@ -121,9 +121,12 @@ class MODULES_EXPORT RTCPeerConnection final
V8VoidFunction*,
V8RTCPeerConnectionErrorCallback* = nullptr);
RTCSessionDescription* remoteDescription();
+ RTCSessionDescription* currentRemoteDescription();
+ RTCSessionDescription* pendingRemoteDescription();
String signalingState() const;
+ void getConfiguration(RTCConfiguration&);
void setConfiguration(ScriptState*, const RTCConfiguration&, ExceptionState&);
// Certificate management
@@ -234,6 +237,7 @@ class MODULES_EXPORT RTCPeerConnection final
void DidModifyTransceivers(std::vector<std::unique_ptr<WebRTCRtpTransceiver>>,
bool is_remote_description) override;
void DidAddRemoteDataChannel(WebRTCDataChannelHandler*) override;
+ void DidNoteInterestingUsage(int usage_pattern) override;
void ReleasePeerConnectionHandler() override;
void ClosePeerConnection() override;
@@ -283,7 +287,7 @@ class MODULES_EXPORT RTCPeerConnection final
};
RTCPeerConnection(ExecutionContext*,
- WebRTCConfiguration,
+ webrtc::PeerConnectionInterface::RTCConfiguration,
WebMediaConstraints,
ExceptionState&);
void Dispose();
@@ -437,7 +441,7 @@ class MODULES_EXPORT RTCPeerConnection final
// information is surfaced from webrtc. This has the value "kPlanB" or
// "kUnifiedPlan", if constructed with "kDefault" it is translated to one or
// the other.
- WebRTCSdpSemantics sdp_semantics_;
+ webrtc::SdpSemantics sdp_semantics_;
};
} // 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 35913caf0d8..41becb6a96d 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
@@ -39,12 +39,6 @@ enum RTCSignalingState {
"closed"
};
-enum RTCIceGatheringState {
- "new",
- "gathering",
- "complete"
-};
-
enum RTCIceConnectionState {
"new",
"checking",
@@ -71,18 +65,18 @@ enum RTCIceConnectionState {
[CallWith=ScriptState] Promise<RTCSessionDescription> createAnswer(optional RTCAnswerOptions options);
[CallWith=ScriptState] Promise<void> setLocalDescription(RTCSessionDescriptionInit description);
readonly attribute RTCSessionDescription? localDescription;
- // readonly attribute RTCSessionDescription? currentLocalDescription;
- // readonly attribute RTCSessionDescription? pendingLocalDescription;
+ readonly attribute RTCSessionDescription? currentLocalDescription;
+ readonly attribute RTCSessionDescription? pendingLocalDescription;
[CallWith=ScriptState] Promise<void> setRemoteDescription(RTCSessionDescriptionInit description);
readonly attribute RTCSessionDescription? remoteDescription;
- // readonly attribute RTCSessionDescription? currentRemoteDescription;
- // readonly attribute RTCSessionDescription? pendingRemoteDescription;
+ readonly attribute RTCSessionDescription? currentRemoteDescription;
+ readonly attribute RTCSessionDescription? pendingRemoteDescription;
[CallWith=ScriptState, RaisesException, MeasureAs=RTCPeerConnectionAddIceCandidatePromise] Promise<void> addIceCandidate((RTCIceCandidateInit or RTCIceCandidate) candidate);
readonly attribute RTCSignalingState signalingState;
readonly attribute RTCIceGatheringState iceGatheringState;
readonly attribute RTCIceConnectionState iceConnectionState;
// readonly attribute boolean? canTrickleIceCandidates;
- // RTCConfiguration getConfiguration();
+ RTCConfiguration getConfiguration();
[CallWith=ScriptState, RaisesException] void setConfiguration(RTCConfiguration configuration);
void close();
attribute EventHandler onnegotiationneeded;
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 377dae9faf1..97ee5a333f0 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,6 +24,7 @@
#include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.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"
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_parameters.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_parameters.idl
new file mode 100644
index 00000000000..4fd90d7a19c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_parameters.idl
@@ -0,0 +1,16 @@
+// 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://w3c.github.io/webrtc-quic/#dom-rtcquicrole
+enum RTCQuicRole {
+ "auto",
+ "client",
+ "server",
+};
+
+// https://w3c.github.io/webrtc-quic/#rtcquicparameters*
+dictionary RTCQuicParameters {
+ RTCQuicRole role = "auto";
+ sequence<RTCDtlsFingerprint> fingerprints;
+};
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
new file mode 100644
index 00000000000..ef0cc254f68
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.cc
@@ -0,0 +1,54 @@
+// 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/peerconnection/rtc_quic_stream.h"
+
+#include "third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.h"
+
+namespace blink {
+
+RTCQuicStream::RTCQuicStream(RTCQuicTransport* transport)
+ : transport_(transport) {
+ DCHECK(transport_);
+}
+
+RTCQuicStream::~RTCQuicStream() = default;
+
+RTCQuicTransport* RTCQuicStream::transport() const {
+ return transport_;
+}
+
+String RTCQuicStream::state() const {
+ switch (state_) {
+ case RTCQuicStreamState::kNew:
+ return "new";
+ case RTCQuicStreamState::kOpening:
+ return "opening";
+ case RTCQuicStreamState::kOpen:
+ return "open";
+ case RTCQuicStreamState::kClosing:
+ return "closing";
+ case RTCQuicStreamState::kClosed:
+ return "closed";
+ }
+ return String();
+}
+
+uint32_t RTCQuicStream::readBufferedAmount() const {
+ return read_buffered_amount_;
+}
+
+uint32_t RTCQuicStream::writeBufferedAmount() const {
+ return write_buffered_amount_;
+}
+
+void RTCQuicStream::Stop() {
+ state_ = RTCQuicStreamState::kClosed;
+}
+
+void RTCQuicStream::Trace(blink::Visitor* visitor) {
+ visitor->Trace(transport_);
+ ScriptWrappable::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
new file mode 100644
index 00000000000..db56e123ab7
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.h
@@ -0,0 +1,44 @@
+// 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_PEERCONNECTION_RTC_QUIC_STREAM_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_QUIC_STREAM_H_
+
+#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+
+namespace blink {
+
+class RTCQuicTransport;
+
+enum class RTCQuicStreamState { kNew, kOpening, kOpen, kClosing, kClosed };
+
+class MODULES_EXPORT RTCQuicStream final : public ScriptWrappable {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ RTCQuicStream(RTCQuicTransport* transport);
+ ~RTCQuicStream() override;
+
+ void Stop();
+
+ // rtc_quic_stream.idl
+ RTCQuicTransport* transport() const;
+ String state() const;
+ uint32_t readBufferedAmount() const;
+ uint32_t writeBufferedAmount() const;
+
+ // For garbage collection.
+ void Trace(blink::Visitor* visitor) override;
+
+ private:
+ Member<RTCQuicTransport> transport_;
+ RTCQuicStreamState state_ = RTCQuicStreamState::kNew;
+ uint32_t read_buffered_amount_ = 0;
+ uint32_t write_buffered_amount_ = 0;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_QUIC_STREAM_H_
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.idl
new file mode 100644
index 00000000000..edc318407df
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.idl
@@ -0,0 +1,25 @@
+// 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://w3c.github.io/webrtc-quic/#rtcquicstreamstate*
+enum RTCQuicStreamState {
+ "new",
+ "opening",
+ "open",
+ "closing",
+ "closed",
+};
+
+// https://w3c.github.io/webrtc-quic/#quicstream*
+[
+ Exposed=Window,
+ RuntimeEnabled=RTCQuicStream
+] interface RTCQuicStream {
+ readonly attribute RTCQuicTransport transport;
+ readonly attribute RTCQuicStreamState state;
+ readonly attribute unsigned long readBufferedAmount;
+ readonly attribute unsigned long writeBufferedAmount;
+ // TODO(crbug.com/868068): Implement remaining methods, attributes, and events.
+};
+
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
new file mode 100644
index 00000000000..407a8bb249a
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.cc
@@ -0,0 +1,128 @@
+// 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/peerconnection/rtc_quic_transport.h"
+
+#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_certificate.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_quic_parameters.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.h"
+
+namespace blink {
+
+RTCQuicTransport* RTCQuicTransport::Create(
+ RTCIceTransport* transport,
+ const HeapVector<Member<RTCCertificate>>& certificates,
+ ExceptionState& exception_state) {
+ if (transport->IsClosed()) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "Cannot construct an RTCQuicTransport with a closed RTCIceTransport.");
+ return nullptr;
+ }
+ for (const auto& certificate : certificates) {
+ if (certificate->expires() < ConvertSecondsToDOMTimeStamp(CurrentTime())) {
+ exception_state.ThrowTypeError(
+ "Cannot construct an RTCQuicTransport with an expired certificate.");
+ return nullptr;
+ }
+ }
+ return new RTCQuicTransport(transport, certificates, exception_state);
+}
+
+RTCQuicTransport::RTCQuicTransport(
+ RTCIceTransport* transport,
+ const HeapVector<Member<RTCCertificate>>& certificates,
+ ExceptionState& exception_state)
+ : transport_(transport), certificates_(certificates) {}
+
+RTCQuicTransport::~RTCQuicTransport() = default;
+
+RTCIceTransport* RTCQuicTransport::transport() const {
+ return transport_;
+}
+
+String RTCQuicTransport::state() const {
+ switch (state_) {
+ case RTCQuicTransportState::kNew:
+ return "new";
+ case RTCQuicTransportState::kConnecting:
+ return "connecting";
+ case RTCQuicTransportState::kConnected:
+ return "connected";
+ case RTCQuicTransportState::kClosed:
+ return "closed";
+ case RTCQuicTransportState::kFailed:
+ return "failed";
+ }
+ return String();
+}
+
+void RTCQuicTransport::getLocalParameters(RTCQuicParameters& result) const {
+ HeapVector<RTCDtlsFingerprint> fingerprints;
+ for (const auto& certificate : certificates_) {
+ // TODO(github.com/w3c/webrtc-quic/issues/33): The specification says that
+ // getLocalParameters should return one fingerprint per certificate but is
+ // not clear which one to pick if an RTCCertificate has multiple
+ // fingerprints.
+ for (const auto& certificate_fingerprint : certificate->getFingerprints()) {
+ fingerprints.push_back(certificate_fingerprint);
+ }
+ }
+ result.setFingerprints(fingerprints);
+}
+
+void RTCQuicTransport::getRemoteParameters(
+ base::Optional<RTCQuicParameters>& result) const {
+ result = base::nullopt;
+}
+
+const HeapVector<Member<RTCCertificate>>& RTCQuicTransport::getCertificates()
+ const {
+ return certificates_;
+}
+
+const HeapVector<Member<DOMArrayBuffer>>&
+RTCQuicTransport::getRemoteCertificates() const {
+ return remote_certificates_;
+}
+
+void RTCQuicTransport::stop() {
+ for (RTCQuicStream* stream : streams_) {
+ stream->Stop();
+ }
+ streams_.clear();
+ state_ = RTCQuicTransportState::kClosed;
+}
+
+RTCQuicStream* RTCQuicTransport::createStream(ExceptionState& exception_state) {
+ if (RaiseExceptionIfClosed(exception_state)) {
+ return nullptr;
+ }
+ RTCQuicStream* stream = new RTCQuicStream(this);
+ streams_.insert(stream);
+ return stream;
+}
+
+bool RTCQuicTransport::RaiseExceptionIfClosed(
+ ExceptionState& exception_state) const {
+ if (IsClosed()) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "The RTCQuicTransport's state is 'closed'.");
+ return true;
+ }
+ return false;
+}
+
+void RTCQuicTransport::Trace(blink::Visitor* visitor) {
+ visitor->Trace(transport_);
+ visitor->Trace(certificates_);
+ visitor->Trace(remote_certificates_);
+ visitor->Trace(streams_);
+ ScriptWrappable::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
new file mode 100644
index 00000000000..161dd63c873
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.h
@@ -0,0 +1,69 @@
+// 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_PEERCONNECTION_RTC_QUIC_TRANSPORT_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_QUIC_TRANSPORT_H_
+
+#include "third_party/blink/renderer/modules/peerconnection/rtc_quic_parameters.h"
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+
+namespace blink {
+
+class DOMArrayBuffer;
+class ExceptionState;
+class RTCCertificate;
+class RTCIceTransport;
+class RTCQuicParameters;
+class RTCQuicStream;
+
+enum class RTCQuicTransportState {
+ kNew,
+ kConnecting,
+ kConnected,
+ kClosed,
+ kFailed
+};
+
+class MODULES_EXPORT RTCQuicTransport final : public ScriptWrappable {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ static RTCQuicTransport* Create(
+ RTCIceTransport* transport,
+ const HeapVector<Member<RTCCertificate>>& certificates,
+ ExceptionState& exception_state);
+
+ ~RTCQuicTransport() override;
+
+ // https://w3c.github.io/webrtc-quic/#quic-transport*
+ RTCIceTransport* transport() const;
+ String state() const;
+ void getLocalParameters(RTCQuicParameters& result) const;
+ void getRemoteParameters(base::Optional<RTCQuicParameters>& result) const;
+ const HeapVector<Member<RTCCertificate>>& getCertificates() const;
+ const HeapVector<Member<DOMArrayBuffer>>& getRemoteCertificates() const;
+ void stop();
+ RTCQuicStream* createStream(ExceptionState& exception_state);
+
+ // For garbage collection.
+ void Trace(blink::Visitor* visitor) override;
+
+ private:
+ RTCQuicTransport(RTCIceTransport* transport,
+ const HeapVector<Member<RTCCertificate>>& certificates,
+ ExceptionState& exception_state);
+
+ bool IsClosed() const { return state_ == RTCQuicTransportState::kClosed; }
+ bool RaiseExceptionIfClosed(ExceptionState& exception_state) const;
+
+ Member<RTCIceTransport> transport_;
+ RTCQuicTransportState state_ = RTCQuicTransportState::kNew;
+ HeapVector<Member<RTCCertificate>> certificates_;
+ HeapVector<Member<DOMArrayBuffer>> remote_certificates_;
+ HeapHashSet<Member<RTCQuicStream>> streams_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_QUIC_TRANSPORT_H_
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
new file mode 100644
index 00000000000..df348136a76
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.idl
@@ -0,0 +1,30 @@
+// 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://w3c.github.io/webrtc-quic/#dom-rtcquictransportstate
+enum RTCQuicTransportState {
+ "new",
+ "connecting",
+ "connected",
+ "closed",
+ "failed",
+};
+
+// https://w3c.github.io/webrtc-quic/#quic-transport*
+[
+ Constructor(RTCIceTransport transport, sequence<RTCCertificate> certificates),
+ RaisesException=Constructor,
+ Exposed=Window,
+ RuntimeEnabled=RTCQuicTransport
+] interface RTCQuicTransport {
+ readonly attribute RTCIceTransport transport;
+ readonly attribute RTCQuicTransportState state;
+ RTCQuicParameters getLocalParameters();
+ RTCQuicParameters? getRemoteParameters();
+ sequence<RTCCertificate> getCertificates();
+ sequence<ArrayBuffer> getRemoteCertificates();
+ void stop();
+ [RaisesException, RuntimeEnabled=RTCQuicStream] RTCQuicStream createStream();
+ // TODO(crbug.com/868068): Implement remaining control methods + events.
+};
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/testing/internals_rtc_certificate.cc b/chromium/third_party/blink/renderer/modules/peerconnection/testing/internals_rtc_certificate.cc
index 0b28fecbeaa..8853bde37ca 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/testing/internals_rtc_certificate.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/testing/internals_rtc_certificate.cc
@@ -9,7 +9,7 @@ namespace blink {
bool InternalsRTCCertificate::rtcCertificateEquals(Internals& internals,
RTCCertificate* a,
RTCCertificate* b) {
- return a->Certificate().Equals(b->Certificate());
+ return a->Certificate() == b->Certificate();
}
} // namespace blink
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 1a7178b1add..ca9bfea83c7 100644
--- a/chromium/third_party/blink/renderer/modules/permissions/permission_status.cc
+++ b/chromium/third_party/blink/renderer/modules/permissions/permission_status.cc
@@ -106,7 +106,7 @@ void PermissionStatus::OnPermissionStatusChange(MojoPermissionStatus status) {
return;
status_ = status;
- DispatchEvent(Event::Create(EventTypeNames::change));
+ DispatchEvent(*Event::Create(EventTypeNames::change));
}
void PermissionStatus::Trace(blink::Visitor* visitor) {
diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/BUILD.gn b/chromium/third_party/blink/renderer/modules/picture_in_picture/BUILD.gn
index bf8d03bc771..96135824cc6 100644
--- a/chromium/third_party/blink/renderer/modules/picture_in_picture/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/BUILD.gn
@@ -8,6 +8,8 @@ blink_modules_sources("picture_in_picture") {
sources = [
"document_picture_in_picture.cc",
"document_picture_in_picture.h",
+ "enter_picture_in_picture_event.cc",
+ "enter_picture_in_picture_event.h",
"html_video_element_picture_in_picture.cc",
"html_video_element_picture_in_picture.h",
"picture_in_picture_controller_impl.cc",
diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/DEPS b/chromium/third_party/blink/renderer/modules/picture_in_picture/DEPS
index 2813822a755..03fe8e3a0ad 100644
--- a/chromium/third_party/blink/renderer/modules/picture_in_picture/DEPS
+++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/DEPS
@@ -1,5 +1,6 @@
include_rules = [
"-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/picture_in_picture",
] \ No newline at end of file
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
new file mode 100644
index 00000000000..3b3e738175a
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.cc
@@ -0,0 +1,43 @@
+// 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/picture_in_picture/enter_picture_in_picture_event.h"
+
+namespace blink {
+
+EnterPictureInPictureEvent* EnterPictureInPictureEvent::Create(
+ const AtomicString& type,
+ PictureInPictureWindow* picture_in_picture_window) {
+ return new EnterPictureInPictureEvent(type, picture_in_picture_window);
+}
+
+EnterPictureInPictureEvent* EnterPictureInPictureEvent::Create(
+ const AtomicString& type,
+ const EnterPictureInPictureEventInit& initializer) {
+ return new EnterPictureInPictureEvent(type, initializer);
+}
+
+PictureInPictureWindow* EnterPictureInPictureEvent::pictureInPictureWindow()
+ const {
+ return picture_in_picture_window_.Get();
+}
+
+EnterPictureInPictureEvent::EnterPictureInPictureEvent(
+ AtomicString const& type,
+ PictureInPictureWindow* picture_in_picture_window)
+ : Event(type, Bubbles::kYes, Cancelable::kNo),
+ picture_in_picture_window_(picture_in_picture_window) {}
+
+EnterPictureInPictureEvent::EnterPictureInPictureEvent(
+ AtomicString const& type,
+ const EnterPictureInPictureEventInit& initializer)
+ : Event(type, initializer),
+ picture_in_picture_window_(initializer.pictureInPictureWindow()) {}
+
+void EnterPictureInPictureEvent::Trace(blink::Visitor* visitor) {
+ visitor->Trace(picture_in_picture_window_);
+ Event::Trace(visitor);
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..5db7c83cde1
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.h
@@ -0,0 +1,41 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PICTURE_IN_PICTURE_ENTER_PICTURE_IN_PICTURE_EVENT_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PICTURE_IN_PICTURE_ENTER_PICTURE_IN_PICTURE_EVENT_H_
+
+#include "third_party/blink/renderer/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"
+
+namespace blink {
+
+// An EnterPictureInPictureEvent is a subclass of Event with an additional
+// attribute that points to the Picture-in-Picture window.
+class MODULES_EXPORT EnterPictureInPictureEvent final : public Event {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ static EnterPictureInPictureEvent* Create(const AtomicString&,
+ PictureInPictureWindow*);
+ static EnterPictureInPictureEvent* Create(
+ const AtomicString&,
+ const EnterPictureInPictureEventInit&);
+
+ PictureInPictureWindow* pictureInPictureWindow() const;
+
+ void Trace(blink::Visitor*) override;
+
+ private:
+ EnterPictureInPictureEvent(AtomicString const&, PictureInPictureWindow*);
+ EnterPictureInPictureEvent(AtomicString const&,
+ const EnterPictureInPictureEventInit&);
+
+ Member<PictureInPictureWindow> picture_in_picture_window_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PICTURE_IN_PICTURE_ENTER_PICTURE_IN_PICTURE_EVENT_H_
diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.idl b/chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.idl
new file mode 100644
index 00000000000..a10341a77a6
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.idl
@@ -0,0 +1,14 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://wicg.github.io/picture-in-picture/#enterpictureinpictureevent
+[
+ RuntimeEnabled=PictureInPictureAPI,
+ Constructor(DOMString type, EnterPictureInPictureEventInit eventInitDict),
+ Exposed=Window
+]
+interface EnterPictureInPictureEvent : Event {
+ [SameObject] readonly attribute PictureInPictureWindow pictureInPictureWindow;
+};
+
diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event_init.idl b/chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event_init.idl
new file mode 100644
index 00000000000..a2117b3e527
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event_init.idl
@@ -0,0 +1,8 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://wicg.github.io/picture-in-picture/#dictdef-enterpictureinpictureeventinit
+dictionary EnterPictureInPictureEventInit : EventInit {
+ required PictureInPictureWindow pictureInPictureWindow;
+};
diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/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 02c3959ecf4..4b869169e28 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
@@ -4,12 +4,14 @@
#include "third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.h"
-#include "third_party/blink/public/platform/web_media_player.h"
+#include "third_party/blink/public/common/picture_in_picture/picture_in_picture_control_info.h"
+#include "third_party/blink/public/platform/web_icon_sizes_parser.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/html/media/html_video_element.h"
+#include "third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_control.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_window.h"
#include "third_party/blink/renderer/platform/feature_policy/feature_policy.h"
@@ -26,6 +28,8 @@ const char kMetadataNotLoadedError[] =
"Metadata for the video element are not loaded yet.";
const char kVideoTrackNotAvailableError[] =
"The video element has no video track.";
+const char kMediaStreamsNotSupportedYet[] =
+ "Media Streams are not supported yet.";
const char kFeaturePolicyBlocked[] =
"Access to the feature \"picture-in-picture\" is disallowed by feature "
"policy.";
@@ -60,6 +64,11 @@ ScriptPromise HTMLVideoElementPictureInPicture::requestPictureInPicture(
script_state,
DOMException::Create(DOMExceptionCode::kInvalidStateError,
kVideoTrackNotAvailableError));
+ case Status::kMediaStreamsNotSupportedYet:
+ return ScriptPromise::RejectWithDOMException(
+ script_state,
+ DOMException::Create(DOMExceptionCode::kNotSupportedError,
+ kMediaStreamsNotSupportedYet));
case Status::kDisabledByFeaturePolicy:
return ScriptPromise::RejectWithDOMException(
script_state, DOMException::Create(DOMExceptionCode::kSecurityError,
@@ -88,14 +97,6 @@ ScriptPromise HTMLVideoElementPictureInPicture::requestPictureInPicture(
kUserGestureRequired));
}
- // TODO(crbug.com/806249): Remove this when MediaStreams are supported.
- if (element.GetLoadType() == WebMediaPlayer::kLoadTypeMediaStream) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- DOMException::Create(DOMExceptionCode::kNotSupportedError,
- "MediaStreams are not supported yet."));
- }
-
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
ScriptPromise promise = resolver->Promise();
@@ -109,6 +110,18 @@ ScriptPromise HTMLVideoElementPictureInPicture::requestPictureInPicture(
return promise;
}
+void HTMLVideoElementPictureInPicture::setPictureInPictureControls(
+ HTMLVideoElement& element,
+ const HeapVector<PictureInPictureControl>& controls) {
+ Document& document = element.GetDocument();
+
+ PictureInPictureControllerImpl& controller =
+ PictureInPictureControllerImpl::From(document);
+
+ controller.SetPictureInPictureCustomControls(
+ &element, ToPictureInPictureControlInfoVector(controls));
+}
+
// static
bool HTMLVideoElementPictureInPicture::FastHasAttribute(
const QualifiedName& name,
@@ -137,4 +150,37 @@ void HTMLVideoElementPictureInPicture::SetBooleanAttribute(
}
}
+// static
+std::vector<PictureInPictureControlInfo>
+HTMLVideoElementPictureInPicture::ToPictureInPictureControlInfoVector(
+ const HeapVector<PictureInPictureControl>& controls) {
+ std::vector<PictureInPictureControlInfo> converted_controls;
+ for (size_t i = 0; i < controls.size(); ++i) {
+ PictureInPictureControlInfo current_converted_control;
+ HeapVector<MediaImage> current_icons = controls[i].icons();
+
+ // Only two icons are supported, so cap the loop at running that many times
+ // to avoid potential problems.
+ for (size_t j = 0; j < current_icons.size() && j < 2; ++j) {
+ PictureInPictureControlInfo::Icon current_icon;
+ current_icon.src = KURL(WebString(current_icons[j].src()));
+
+ WebVector<WebSize> sizes = WebIconSizesParser::ParseIconSizes(
+ WebString(current_icons[j].sizes()));
+ std::vector<gfx::Size> converted_sizes;
+ for (size_t i = 0; i < sizes.size(); ++i)
+ converted_sizes.push_back(static_cast<gfx::Size>(sizes[i]));
+
+ current_icon.sizes = converted_sizes;
+ current_icon.type = WebString(current_icons[j].type()).Utf8();
+ current_converted_control.icons.push_back(current_icon);
+ }
+
+ current_converted_control.id = WebString(controls[i].id()).Utf8();
+ current_converted_control.label = WebString(controls[i].label()).Utf8();
+ converted_controls.push_back(current_converted_control);
+ }
+ return converted_controls;
+}
+
} // namespace blink
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 97718342fdd..8cdd5b42c2e 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
@@ -14,13 +14,19 @@ namespace blink {
class HTMLVideoElement;
class ScriptPromise;
class ScriptState;
+class PictureInPictureControl;
+struct PictureInPictureControlInfo;
-class HTMLVideoElementPictureInPicture {
+class MODULES_EXPORT HTMLVideoElementPictureInPicture {
STATIC_ONLY(HTMLVideoElementPictureInPicture);
public:
static ScriptPromise requestPictureInPicture(ScriptState*, HTMLVideoElement&);
+ static void setPictureInPictureControls(
+ HTMLVideoElement&,
+ const HeapVector<PictureInPictureControl>&);
+
static bool FastHasAttribute(const QualifiedName&, const HTMLVideoElement&);
static void SetBooleanAttribute(const QualifiedName&,
@@ -30,6 +36,10 @@ class HTMLVideoElementPictureInPicture {
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(enterpictureinpicture);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(leavepictureinpicture);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(pictureinpicturecontrolclick);
+
+ static std::vector<PictureInPictureControlInfo>
+ ToPictureInPictureControlInfoVector(
+ const HeapVector<PictureInPictureControl>&);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.idl b/chromium/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.idl
index 34ee29bcccc..f46c613d102 100644
--- a/chromium/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.idl
+++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.idl
@@ -9,6 +9,7 @@
]
partial interface HTMLVideoElement {
[CallWith=ScriptState, Measure, NewObject] Promise<PictureInPictureWindow> requestPictureInPicture();
+ [RuntimeEnabled=PictureInPictureControl] void setPictureInPictureControls(sequence<PictureInPictureControl> pipControls);
attribute EventHandler onenterpictureinpicture;
attribute EventHandler onleavepictureinpicture;
diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture_test.cc b/chromium/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture_test.cc
new file mode 100644
index 00000000000..4587e413f41
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture_test.cc
@@ -0,0 +1,113 @@
+// 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/picture_in_picture/html_video_element_picture_in_picture.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/picture_in_picture/picture_in_picture_control_info.h"
+#include "third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_control.h"
+
+namespace blink {
+
+TEST(HTMLVideoElementPictureInPictureTest,
+ ToPictureInPictureControlInfoVector_Basic) {
+ MediaImage image;
+ image.setSrc("https://dummyimage.com/144x144/7d727d/fafafa.gif");
+ image.setSizes("144x144");
+ image.setType("image/gif");
+ HeapVector<MediaImage> images;
+ images.push_back(image);
+
+ PictureInPictureControl control;
+ control.setId(WTF::String("Test id"));
+ control.setLabel(WTF::String("Test label"));
+ control.setIcons(images);
+
+ HeapVector<PictureInPictureControl> controls;
+ controls.push_back(control);
+
+ std::vector<PictureInPictureControlInfo> converted_controls =
+ HTMLVideoElementPictureInPicture::ToPictureInPictureControlInfoVector(
+ controls);
+
+ ASSERT_EQ(1U, converted_controls.size());
+ EXPECT_EQ(144, converted_controls[0].icons[0].sizes[0].width());
+ EXPECT_EQ(144, converted_controls[0].icons[0].sizes[0].height());
+}
+
+TEST(HTMLVideoElementPictureInPictureTest,
+ ToPictureInPictureControlInfoVector_MultipleImages) {
+ MediaImage image;
+ image.setSrc("https://dummyimage.com/144x144/7d727d/fafafa.gif");
+ image.setSizes("144x144");
+ image.setType("image/gif");
+
+ MediaImage image2;
+ image2.setSrc("https://dummyimage.com/96x96/7d727d/fafafa.gif");
+ image2.setSizes("96x96");
+ image2.setType("image/gif");
+
+ HeapVector<MediaImage> images;
+ images.push_back(image);
+ images.push_back(image2);
+
+ PictureInPictureControl control;
+ control.setId(WTF::String("Test id"));
+ control.setLabel(WTF::String("Test label"));
+ control.setIcons(images);
+
+ HeapVector<PictureInPictureControl> controls;
+ controls.push_back(control);
+
+ std::vector<PictureInPictureControlInfo> converted_controls =
+ HTMLVideoElementPictureInPicture::ToPictureInPictureControlInfoVector(
+ controls);
+
+ ASSERT_EQ(1U, converted_controls.size());
+ EXPECT_EQ(144, converted_controls[0].icons[0].sizes[0].width());
+ EXPECT_EQ(144, converted_controls[0].icons[0].sizes[0].height());
+ EXPECT_EQ(96, converted_controls[0].icons[1].sizes[0].width());
+ EXPECT_EQ(96, converted_controls[0].icons[1].sizes[0].height());
+}
+
+TEST(HTMLVideoElementPictureInPictureTest,
+ ToPictureInPictureControlInfoVector_InvalidSize) {
+ MediaImage image;
+ image.setSrc("https://dummyimage.com/144x144/7d727d/fafafa.gif");
+ image.setSizes("144");
+ image.setType("image/gif");
+ HeapVector<MediaImage> images;
+ images.push_back(image);
+
+ PictureInPictureControl control;
+ control.setId(WTF::String("Test id"));
+ control.setLabel(WTF::String("Test label"));
+ control.setIcons(images);
+
+ HeapVector<PictureInPictureControl> controls;
+ controls.push_back(control);
+
+ std::vector<PictureInPictureControlInfo> converted_controls =
+ HTMLVideoElementPictureInPicture::ToPictureInPictureControlInfoVector(
+ controls);
+
+ ASSERT_EQ(1U, converted_controls.size());
+
+ ASSERT_EQ(1U, converted_controls[0].icons.size());
+
+ EXPECT_EQ(0U, converted_controls[0].icons[0].sizes.size());
+}
+
+TEST(HTMLVideoElementPictureInPictureTest,
+ ToPictureInPictureControlInfoVector_Empty) {
+ HeapVector<PictureInPictureControl> controls;
+
+ std::vector<PictureInPictureControlInfo> converted_controls =
+ HTMLVideoElementPictureInPicture::ToPictureInPictureControlInfoVector(
+ controls);
+
+ EXPECT_EQ(0U, converted_controls.size());
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_control.idl b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_control.idl
new file mode 100644
index 00000000000..964c0cdb014
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_control.idl
@@ -0,0 +1,9 @@
+// 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.
+
+dictionary PictureInPictureControl {
+ DOMString id = "";
+ DOMString label = "";
+ sequence<MediaImage> icons = [];
+};
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 75819a52df2..163159c6508 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
@@ -4,12 +4,14 @@
#include "third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.h"
+#include "third_party/blink/public/platform/web_media_player.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"
#include "third_party/blink/renderer/core/events/picture_in_picture_control_event.h"
#include "third_party/blink/renderer/core/frame/settings.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_window.h"
#include "third_party/blink/renderer/platform/feature_policy/feature_policy.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
@@ -77,6 +79,10 @@ PictureInPictureControllerImpl::IsElementAllowed(
if (element.FastHasAttribute(HTMLNames::disablepictureinpictureAttr))
return Status::kDisabledByAttribute;
+ // TODO(crbug.com/806249): Remove this when MediaStreams are supported.
+ if (element.GetLoadType() == WebMediaPlayer::kLoadTypeMediaStream)
+ return Status::kMediaStreamsNotSupportedYet;
+
return Status::kEnabled;
}
@@ -88,6 +94,9 @@ void PictureInPictureControllerImpl::EnterPictureInPicture(
WTF::Bind(&PictureInPictureControllerImpl::OnEnteredPictureInPicture,
WrapPersistent(this), WrapPersistent(element),
WrapPersistent(resolver)));
+ // If the media element has already been given custom controls, this will
+ // ensure that they get set. Otherwise, this will do nothing.
+ element->SendCustomControlsToPipWindow();
return;
}
@@ -112,9 +121,6 @@ void PictureInPictureControllerImpl::OnEnteredPictureInPicture(
picture_in_picture_element_->OnEnteredPictureInPicture();
- picture_in_picture_element_->DispatchEvent(
- Event::CreateBubble(EventTypeNames::enterpictureinpicture));
-
// Closes the current Picture-in-Picture window if any.
if (picture_in_picture_window_)
picture_in_picture_window_->OnClose();
@@ -122,6 +128,11 @@ void PictureInPictureControllerImpl::OnEnteredPictureInPicture(
picture_in_picture_window_ = new PictureInPictureWindow(
GetSupplementable(), picture_in_picture_window_size);
+ picture_in_picture_element_->DispatchEvent(
+ *EnterPictureInPictureEvent::Create(
+ EventTypeNames::enterpictureinpicture,
+ WrapPersistent(picture_in_picture_window_.Get())));
+
element->GetWebMediaPlayer()->RegisterPictureInPictureWindowResizeCallback(
WTF::BindRepeating(&PictureInPictureWindow::OnResize,
WrapPersistent(picture_in_picture_window_.Get())));
@@ -138,6 +149,14 @@ void PictureInPictureControllerImpl::ExitPictureInPicture(
WrapPersistent(this), WrapPersistent(resolver)));
}
+void PictureInPictureControllerImpl::SetPictureInPictureCustomControls(
+ HTMLVideoElement* element,
+ const std::vector<PictureInPictureControlInfo>& controls) {
+ element->SetPictureInPictureCustomControls(controls);
+ if (IsPictureInPictureElement(element))
+ element->SendCustomControlsToPipWindow();
+}
+
void PictureInPictureControllerImpl::OnExitedPictureInPicture(
ScriptPromiseResolver* resolver) {
DCHECK(GetSupplementable());
@@ -155,7 +174,7 @@ void PictureInPictureControllerImpl::OnExitedPictureInPicture(
element->OnExitedPictureInPicture();
element->DispatchEvent(
- Event::CreateBubble(EventTypeNames::leavepictureinpicture));
+ *Event::CreateBubble(EventTypeNames::leavepictureinpicture));
}
if (resolver)
@@ -173,7 +192,7 @@ void PictureInPictureControllerImpl::OnPictureInPictureControlClicked(
if (RuntimeEnabledFeatures::PictureInPictureControlEnabled() &&
picture_in_picture_element_) {
picture_in_picture_element_->DispatchEvent(
- PictureInPictureControlEvent::Create(
+ *PictureInPictureControlEvent::Create(
EventTypeNames::pictureinpicturecontrolclick, control_id));
}
}
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 45b0e6aeb02..b7bcf09314c 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
@@ -45,12 +45,6 @@ class PictureInPictureControllerImpl : public PictureInPictureController {
// request Picture-in-Picture.
Status IsDocumentAllowed() const;
- // Meant to be called internally when an element has entered successfully
- // Picture-in-Picture.
- void OnEnteredPictureInPicture(HTMLVideoElement*,
- ScriptPromiseResolver*,
- const WebSize& picture_in_picture_window_size);
-
// Returns element currently in Picture-in-Picture if any. Null otherwise.
Element* PictureInPictureElement(TreeScope&) const;
@@ -58,14 +52,21 @@ class PictureInPictureControllerImpl : public PictureInPictureController {
void EnterPictureInPicture(HTMLVideoElement*,
ScriptPromiseResolver*) override;
void ExitPictureInPicture(HTMLVideoElement*, ScriptPromiseResolver*) override;
- void OnExitedPictureInPicture(ScriptPromiseResolver*) override;
- void OnPictureInPictureControlClicked(const WebString& control_id) override;
+ void SetPictureInPictureCustomControls(
+ HTMLVideoElement*,
+ const std::vector<PictureInPictureControlInfo>&) override;
Status IsElementAllowed(const HTMLVideoElement&) const override;
bool IsPictureInPictureElement(const Element*) const override;
void Trace(blink::Visitor*) override;
private:
+ void OnEnteredPictureInPicture(HTMLVideoElement*,
+ ScriptPromiseResolver*,
+ const WebSize& picture_in_picture_window_size);
+ void OnExitedPictureInPicture(ScriptPromiseResolver*) override;
+ void OnPictureInPictureControlClicked(const WebString& control_id) override;
+
explicit PictureInPictureControllerImpl(Document&);
// The Picture-in-Picture element for the associated document.
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 dfcbcfc1604..847602d7121 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
@@ -24,7 +24,7 @@ void PictureInPictureWindow::OnResize(const WebSize& size) {
return;
size_ = size;
- DispatchEvent(Event::Create(EventTypeNames::resize));
+ DispatchEvent(*Event::Create(EventTypeNames::resize));
}
const AtomicString& PictureInPictureWindow::InterfaceName() const {
diff --git a/chromium/third_party/blink/renderer/modules/presentation/mock_presentation_service.h b/chromium/third_party/blink/renderer/modules/presentation/mock_presentation_service.h
index 1b7d6d551d2..45ef4c60317 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/mock_presentation_service.h
+++ b/chromium/third_party/blink/renderer/modules/presentation/mock_presentation_service.h
@@ -6,7 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PRESENTATION_MOCK_PRESENTATION_SERVICE_H_
#include "testing/gmock/include/gmock/gmock.h"
-#include "third_party/blink/public/platform/modules/presentation/presentation.mojom-blink.h"
+#include "third_party/blink/public/mojom/presentation/presentation.mojom-blink.h"
namespace blink {
@@ -37,17 +37,6 @@ class MockPresentationService : public mojom::blink::PresentationService {
const String& presentation_id,
ReconnectPresentationCallback&));
- void SetPresentationConnection(
- mojom::blink::PresentationInfoPtr presentation_info,
- mojom::blink::PresentationConnectionPtr controller_conn_ptr,
- mojom::blink::PresentationConnectionRequest receiver_conn_request)
- override {
- SetPresentationConnection(*presentation_info, controller_conn_ptr.get());
- }
- MOCK_METHOD2(SetPresentationConnection,
- void(const mojom::blink::PresentationInfo&,
- mojom::blink::PresentationConnection*));
-
MOCK_METHOD2(CloseConnection, void(const KURL&, const String&));
MOCK_METHOD2(Terminate, void(const KURL&, const String&));
};
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 724b191094a..a677e26afa3 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability.cc
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability.cc
@@ -70,7 +70,7 @@ void PresentationAvailability::AvailabilityChanged(
return;
value_ = value;
- DispatchEvent(Event::Create(EventTypeNames::change));
+ DispatchEvent(*Event::Create(EventTypeNames::change));
}
bool PresentationAvailability::HasPendingActivity() const {
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_observer.h b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_observer.h
index 502835e1282..9d6cda36820 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_observer.h
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_observer.h
@@ -5,7 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PRESENTATION_PRESENTATION_AVAILABILITY_OBSERVER_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PRESENTATION_PRESENTATION_AVAILABILITY_OBSERVER_H_
-#include "third_party/blink/public/platform/modules/presentation/presentation.mojom-blink.h"
+#include "third_party/blink/public/mojom/presentation/presentation.mojom-blink.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
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 41d2f05db62..0f95fc02686 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
@@ -10,7 +10,7 @@
#include <vector>
#include "base/macros.h"
-#include "third_party/blink/public/platform/modules/presentation/presentation.mojom-blink.h"
+#include "third_party/blink/public/mojom/presentation/presentation.mojom-blink.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/presentation/presentation_availability_callbacks.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
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 918a2efe481..42711dda72b 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection.cc
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection.cc
@@ -278,7 +278,9 @@ void ControllerPresentationConnection::Trace(blink::Visitor* visitor) {
PresentationConnection::Trace(visitor);
}
-void ControllerPresentationConnection::Init() {
+void ControllerPresentationConnection::Init(
+ mojom::blink::PresentationConnectionPtr connection_ptr,
+ mojom::blink::PresentationConnectionRequest connection_request) {
// Note that it is possible for the binding to be already bound here, because
// the ControllerPresentationConnection object could be reused when
// reconnecting in the same frame. In this case the existing connections are
@@ -288,16 +290,9 @@ void ControllerPresentationConnection::Init() {
target_connection_.reset();
}
- mojom::blink::PresentationConnectionPtr controller_connection_ptr;
- connection_binding_.Bind(mojo::MakeRequest(&controller_connection_ptr));
-
- auto& service = controller_->GetPresentationService();
- if (service) {
- service->SetPresentationConnection(
- mojom::blink::PresentationInfo::New(url_, id_),
- std::move(controller_connection_ptr),
- mojo::MakeRequest(&target_connection_));
- }
+ DidChangeState(mojom::blink::PresentationConnectionState::CONNECTING);
+ target_connection_ = std::move(connection_ptr);
+ connection_binding_.Bind(std::move(connection_request));
}
void ControllerPresentationConnection::DoClose() {
@@ -413,6 +408,7 @@ void PresentationConnection::AddedEventListener(
}
void PresentationConnection::ContextDestroyed(ExecutionContext*) {
+ target_connection_.reset();
connection_binding_.Close();
}
@@ -534,7 +530,7 @@ void PresentationConnection::DidReceiveTextMessage(const WebString& message) {
if (state_ != mojom::blink::PresentationConnectionState::CONNECTED)
return;
- DispatchEvent(MessageEvent::Create(message));
+ DispatchEvent(*MessageEvent::Create(message));
}
void PresentationConnection::DidReceiveBinaryMessage(const uint8_t* data,
@@ -548,12 +544,12 @@ void PresentationConnection::DidReceiveBinaryMessage(const uint8_t* data,
blob_data->AppendBytes(data, length);
Blob* blob =
Blob::Create(BlobDataHandle::Create(std::move(blob_data), length));
- DispatchEvent(MessageEvent::Create(blob));
+ DispatchEvent(*MessageEvent::Create(blob));
return;
}
case kBinaryTypeArrayBuffer:
DOMArrayBuffer* buffer = DOMArrayBuffer::Create(data, length);
- DispatchEvent(MessageEvent::Create(buffer));
+ DispatchEvent(*MessageEvent::Create(buffer));
return;
}
NOTREACHED();
@@ -644,7 +640,7 @@ void PresentationConnection::DispatchEventAsync(EventTarget* target,
Event* event) {
DCHECK(target);
DCHECK(event);
- target->DispatchEvent(event);
+ target->DispatchEvent(*event);
}
void PresentationConnection::TearDown() {
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 4012e758d1a..c6adf86ff57 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection.h
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection.h
@@ -7,7 +7,7 @@
#include <memory>
#include "mojo/public/cpp/bindings/binding.h"
-#include "third_party/blink/public/platform/modules/presentation/presentation.mojom-blink.h"
+#include "third_party/blink/public/mojom/presentation/presentation.mojom-blink.h"
#include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
#include "third_party/blink/renderer/core/fileapi/blob.h"
@@ -174,7 +174,8 @@ class ControllerPresentationConnection final : public PresentationConnection {
void Trace(blink::Visitor*) override;
// Initializes Mojo message pipes and registers with the PresentationService.
- void Init();
+ void Init(mojom::blink::PresentationConnectionPtr connection_ptr,
+ mojom::blink::PresentationConnectionRequest connection_request);
private:
// PresentationConnection implementation.
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_callbacks.cc b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_callbacks.cc
index fa2ab28362e..506a1ece448 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_callbacks.cc
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_callbacks.cc
@@ -29,21 +29,29 @@ PresentationConnectionCallbacks::PresentationConnectionCallbacks(
}
void PresentationConnectionCallbacks::HandlePresentationResponse(
- mojom::blink::PresentationInfoPtr presentation_info,
+ mojom::blink::PresentationConnectionResultPtr result,
mojom::blink::PresentationErrorPtr error) {
if (!resolver_->GetExecutionContext() ||
resolver_->GetExecutionContext()->IsContextDestroyed()) {
return;
}
- if (presentation_info)
- OnSuccess(*presentation_info);
- else
+ if (result) {
+ DCHECK(result->connection_ptr);
+ DCHECK(result->connection_request);
+ OnSuccess(*result->presentation_info,
+ mojom::blink::PresentationConnectionPtr(
+ std::move(result->connection_ptr)),
+ std::move(result->connection_request));
+ } else {
OnError(*error);
+ }
}
void PresentationConnectionCallbacks::OnSuccess(
- const mojom::blink::PresentationInfo& presentation_info) {
+ const mojom::blink::PresentationInfo& presentation_info,
+ mojom::blink::PresentationConnectionPtr connection_ptr,
+ mojom::blink::PresentationConnectionRequest connection_request) {
// Reconnect to existing connection.
if (connection_ && connection_->GetState() ==
mojom::blink::PresentationConnectionState::CLOSED) {
@@ -58,7 +66,7 @@ void PresentationConnectionCallbacks::OnSuccess(
}
resolver_->Resolve(connection_);
- connection_->Init();
+ connection_->Init(std::move(connection_ptr), std::move(connection_request));
}
void PresentationConnectionCallbacks::OnError(
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_callbacks.h b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_callbacks.h
index 8c6a2daa8c9..bbff94f019f 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_callbacks.h
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_callbacks.h
@@ -5,7 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PRESENTATION_PRESENTATION_CONNECTION_CALLBACKS_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PRESENTATION_PRESENTATION_CONNECTION_CALLBACKS_H_
-#include "third_party/blink/public/platform/modules/presentation/presentation.mojom-blink.h"
+#include "third_party/blink/public/mojom/presentation/presentation.mojom-blink.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/noncopyable.h"
@@ -28,11 +28,14 @@ class PresentationConnectionCallbacks final {
ControllerPresentationConnection*);
~PresentationConnectionCallbacks() = default;
- void HandlePresentationResponse(mojom::blink::PresentationInfoPtr,
+ void HandlePresentationResponse(mojom::blink::PresentationConnectionResultPtr,
mojom::blink::PresentationErrorPtr);
private:
- void OnSuccess(const mojom::blink::PresentationInfo&);
+ void OnSuccess(
+ const mojom::blink::PresentationInfo&,
+ mojom::blink::PresentationConnectionPtr connection_ptr,
+ mojom::blink::PresentationConnectionRequest connection_request);
void OnError(const mojom::blink::PresentationError&);
Persistent<ScriptPromiseResolver> resolver_;
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 b0507d3123d..b3e4f0017bc 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
@@ -54,7 +54,7 @@ bool PresentationConnectionList::RemoveConnection(
void PresentationConnectionList::DispatchConnectionAvailableEvent(
PresentationConnection* connection) {
- DispatchEvent(PresentationConnectionAvailableEvent::Create(
+ DispatchEvent(*PresentationConnectionAvailableEvent::Create(
EventTypeNames::connectionavailable, connection));
}
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 1e521098b83..a9a3e752cfa 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_controller.cc
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_controller.cc
@@ -115,15 +115,22 @@ void PresentationController::OnConnectionClosed(
}
void PresentationController::OnDefaultPresentationStarted(
- mojom::blink::PresentationInfoPtr presentation_info) {
- DCHECK(presentation_info);
+ mojom::blink::PresentationConnectionResultPtr result) {
+ DCHECK(result);
+ DCHECK(result->presentation_info);
+ DCHECK(result->connection_ptr && result->connection_request);
if (!presentation_ || !presentation_->defaultRequest())
return;
PresentationRequest::RecordStartOriginTypeAccess(*GetExecutionContext());
auto* connection = ControllerPresentationConnection::Take(
- this, *presentation_info, presentation_->defaultRequest());
- connection->Init();
+ this, *result->presentation_info, presentation_->defaultRequest());
+ // TODO(btolsch): Convert this and similar calls to just use InterfacePtrInfo
+ // instead of constructing an InterfacePtr every time we have
+ // InterfacePtrInfo.
+ connection->Init(mojom::blink::PresentationConnectionPtr(
+ std::move(result->connection_ptr)),
+ std::move(result->connection_request));
}
void PresentationController::ContextDestroyed(ExecutionContext*) {
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 f7ff0d061eb..986fa387a4a 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_controller.h
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_controller.h
@@ -7,7 +7,7 @@
#include "mojo/public/cpp/bindings/binding.h"
#include "services/service_manager/public/cpp/interface_provider.h"
-#include "third_party/blink/public/platform/modules/presentation/presentation.mojom-blink.h"
+#include "third_party/blink/public/mojom/presentation/presentation.mojom-blink.h"
#include "third_party/blink/renderer/core/dom/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"
@@ -94,7 +94,8 @@ class MODULES_EXPORT PresentationController
void OnConnectionClosed(mojom::blink::PresentationInfoPtr,
mojom::blink::PresentationConnectionCloseReason,
const String& message) override;
- void OnDefaultPresentationStarted(mojom::blink::PresentationInfoPtr) override;
+ void OnDefaultPresentationStarted(
+ mojom::blink::PresentationConnectionResultPtr result) override;
// Return the connection associated with the given |presentation_info| or
// null if it doesn't exist.
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_error.h b/chromium/third_party/blink/renderer/modules/presentation/presentation_error.h
index f377a49b5e4..46cb65f3f74 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_error.h
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_error.h
@@ -5,7 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PRESENTATION_PRESENTATION_ERROR_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PRESENTATION_PRESENTATION_ERROR_H_
-#include "third_party/blink/public/platform/modules/presentation/presentation.mojom-blink.h"
+#include "third_party/blink/public/mojom/presentation/presentation.mojom-blink.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
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 fc9181fc3f4..d95ea24bff0 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_receiver.h
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_receiver.h
@@ -6,7 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PRESENTATION_PRESENTATION_RECEIVER_H_
#include "mojo/public/cpp/bindings/binding.h"
-#include "third_party/blink/public/platform/modules/presentation/presentation.mojom-blink.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/context_lifecycle_observer.h"
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 08cf531afcb..17200449440 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
@@ -10,6 +10,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/core/dom/events/event_listener.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/presentation/presentation_connection.h"
diff --git a/chromium/third_party/blink/renderer/modules/quota/OWNERS b/chromium/third_party/blink/renderer/modules/quota/OWNERS
index 55d8058f6d6..84d5cb66e1c 100644
--- a/chromium/third_party/blink/renderer/modules/quota/OWNERS
+++ b/chromium/third_party/blink/renderer/modules/quota/OWNERS
@@ -1,7 +1,4 @@
-jsbell@chromium.org
-kinuko@chromium.org
-nhiroki@chromium.org
-tzik@chromium.org
+file://storage/browser/quota/OWNERS
# TEAM: storage-dev@chromium.org
# COMPONENT: Blink>Storage>Quota
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 02e692b9498..4f50a227565 100644
--- a/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc
+++ b/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc
@@ -227,6 +227,7 @@ bool RemotePlayback::HasPendingActivity() const {
}
void RemotePlayback::ContextDestroyed(ExecutionContext*) {
+ target_presentation_connection_.reset();
presentation_connection_binding_.Close();
}
@@ -348,7 +349,7 @@ void RemotePlayback::StateChanged(WebRemotePlaybackState state) {
state_ = state;
switch (state_) {
case WebRemotePlaybackState::kConnecting:
- DispatchEvent(Event::Create(EventTypeNames::connecting));
+ DispatchEvent(*Event::Create(EventTypeNames::connecting));
if (RuntimeEnabledFeatures::NewRemotePlaybackPipelineEnabled()) {
if (media_element_->IsHTMLVideoElement()) {
// TODO(xjz): Pass the remote device name.
@@ -358,10 +359,10 @@ void RemotePlayback::StateChanged(WebRemotePlaybackState state) {
}
break;
case WebRemotePlaybackState::kConnected:
- DispatchEvent(Event::Create(EventTypeNames::connect));
+ DispatchEvent(*Event::Create(EventTypeNames::connect));
break;
case WebRemotePlaybackState::kDisconnected:
- DispatchEvent(Event::Create(EventTypeNames::disconnect));
+ DispatchEvent(*Event::Create(EventTypeNames::disconnect));
if (RuntimeEnabledFeatures::NewRemotePlaybackPipelineEnabled()) {
if (media_element_->IsHTMLVideoElement()) {
ToHTMLVideoElement(media_element_)
@@ -503,10 +504,10 @@ const Vector<KURL>& RemotePlayback::Urls() const {
}
void RemotePlayback::OnConnectionSuccess(
- const mojom::blink::PresentationInfo& presentation_info) {
+ mojom::blink::PresentationConnectionResultPtr result) {
DCHECK(RuntimeEnabledFeatures::NewRemotePlaybackPipelineEnabled());
- presentation_id_ = presentation_info.id;
- presentation_url_ = presentation_info.url;
+ presentation_id_ = std::move(result->presentation_info->id);
+ presentation_url_ = std::move(result->presentation_info->url);
StateChanged(WebRemotePlaybackState::kConnecting);
@@ -517,12 +518,9 @@ void RemotePlayback::OnConnectionSuccess(
if (!presentation_controller)
return;
- mojom::blink::PresentationConnectionPtr connection_ptr;
- presentation_connection_binding_.Bind(mojo::MakeRequest(&connection_ptr));
- presentation_controller->GetPresentationService()->SetPresentationConnection(
- mojom::blink::PresentationInfo::New(presentation_url_, presentation_id_),
- std::move(connection_ptr),
- mojo::MakeRequest(&target_presentation_connection_));
+ // Note: Messages on |connection_request| are ignored.
+ target_presentation_connection_.Bind(std::move(result->connection_ptr));
+ presentation_connection_binding_.Bind(std::move(result->connection_request));
}
void RemotePlayback::OnConnectionError(
@@ -540,12 +538,13 @@ void RemotePlayback::OnConnectionError(
}
void RemotePlayback::HandlePresentationResponse(
- mojom::blink::PresentationInfoPtr presentation_info,
+ mojom::blink::PresentationConnectionResultPtr result,
mojom::blink::PresentationErrorPtr error) {
- if (presentation_info)
- OnConnectionSuccess(*presentation_info);
- else
+ if (result) {
+ OnConnectionSuccess(std::move(result));
+ } else {
OnConnectionError(*error);
+ }
}
void RemotePlayback::OnMessage(
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 1179b8996bf..fdf5b795580 100644
--- a/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.h
+++ b/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.h
@@ -6,7 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_REMOTEPLAYBACK_REMOTE_PLAYBACK_H_
#include "mojo/public/cpp/bindings/binding.h"
-#include "third_party/blink/public/platform/modules/presentation/presentation.mojom-blink.h"
+#include "third_party/blink/public/mojom/presentation/presentation.mojom-blink.h"
#include "third_party/blink/public/platform/modules/remoteplayback/web_remote_playback_availability.h"
#include "third_party/blink/public/platform/modules/remoteplayback/web_remote_playback_client.h"
#include "third_party/blink/public/platform/modules/remoteplayback/web_remote_playback_state.h"
@@ -100,9 +100,9 @@ class MODULES_EXPORT RemotePlayback final
const Vector<KURL>& Urls() const override;
// Handles the response from PresentationService::StartPresentation.
- void HandlePresentationResponse(mojom::blink::PresentationInfoPtr,
+ void HandlePresentationResponse(mojom::blink::PresentationConnectionResultPtr,
mojom::blink::PresentationErrorPtr);
- void OnConnectionSuccess(const mojom::blink::PresentationInfo&);
+ void OnConnectionSuccess(mojom::blink::PresentationConnectionResultPtr);
void OnConnectionError(const mojom::blink::PresentationError&);
// mojom::blink::PresentationConnection implementation.
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 2427c47e321..fa7b972603c 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
@@ -10,6 +10,7 @@
#include "third_party/blink/renderer/bindings/core/v8/script_function.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_remote_playback_availability_callback.h"
+#include "third_party/blink/renderer/core/dom/events/event_listener.h"
#include "third_party/blink/renderer/core/dom/user_gesture_indicator.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/html/media/html_media_element.h"
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 2f7ab9a6c44..00ac5f416c0 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
@@ -13,12 +13,12 @@
#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/frame/local_frame_view.h"
+#include "third_party/blink/renderer/core/fullscreen/scoped_allow_fullscreen.h"
#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/modules/screen_orientation/screen_orientation.h"
#include "third_party/blink/renderer/modules/screen_orientation/screen_orientation_dispatcher.h"
#include "third_party/blink/renderer/platform/layout_test_support.h"
-#include "third_party/blink/renderer/platform/scoped_orientation_change_indicator.h"
namespace blink {
@@ -219,8 +219,9 @@ void ScreenOrientationControllerImpl::DispatchEventTimerFired(TimerBase*) {
if (!orientation_)
return;
- ScopedOrientationChangeIndicator orientation_change_indicator;
- orientation_->DispatchEvent(Event::Create(EventTypeNames::change));
+ ScopedAllowFullscreen allow_fullscreen(
+ ScopedAllowFullscreen::kOrientationChange);
+ orientation_->DispatchEvent(*Event::Create(EventTypeNames::change));
}
void ScreenOrientationControllerImpl::DidUpdateData() {
diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor.cc b/chromium/third_party/blink/renderer/modules/sensor/sensor.cc
index a819ae10b29..484baee05b1 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/sensor.cc
+++ b/chromium/third_party/blink/renderer/modules/sensor/sensor.cc
@@ -8,6 +8,7 @@
#include "services/device/public/mojom/sensor.mojom-blink.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_dom_window.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/timing/dom_window_performance.h"
#include "third_party/blink/renderer/core/timing/window_performance.h"
@@ -337,7 +338,7 @@ void Sensor::HandleError(DOMExceptionCode code,
void Sensor::NotifyReading() {
DCHECK_EQ(state_, SensorState::kActivated);
last_reported_timestamp_ = sensor_proxy_->GetReading().timestamp();
- DispatchEvent(Event::Create(EventTypeNames::reading));
+ DispatchEvent(*Event::Create(EventTypeNames::reading));
}
void Sensor::NotifyActivated() {
@@ -353,13 +354,13 @@ void Sensor::NotifyActivated() {
WTF::Bind(&Sensor::NotifyReading, WrapWeakPersistent(this)));
}
- DispatchEvent(Event::Create(EventTypeNames::activate));
+ DispatchEvent(*Event::Create(EventTypeNames::activate));
}
void Sensor::NotifyError(DOMException* error) {
DCHECK_NE(state_, SensorState::kIdle);
state_ = SensorState::kIdle;
- DispatchEvent(SensorErrorEvent::Create(EventTypeNames::error, error));
+ DispatchEvent(*SensorErrorEvent::Create(EventTypeNames::error, error));
}
bool Sensor::IsIdleOrErrored() const {
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 27612021a23..9a752de5dea 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/client.idl
+++ b/chromium/third_party/blink/renderer/modules/service_worker/client.idl
@@ -10,7 +10,8 @@
readonly attribute USVString url;
readonly attribute DOMString id;
readonly attribute ClientType type;
- [PostMessage, RaisesException, CallWith=ScriptState] void postMessage(any message, optional sequence<object> transfer);
+ [CallWith=ScriptState, RaisesException] void postMessage(any message, optional sequence<object> transfer = []);
+ [RuntimeEnabled=PostMessageOptions, CallWith=ScriptState, RaisesException] void postMessage(any message, 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/service_worker.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker.cc
index 33dad765d81..20ff71cf4f4 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
@@ -34,10 +34,12 @@
#include "third_party/blink/public/mojom/service_worker/service_worker_state.mojom-blink.h"
#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/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_client.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -50,8 +52,18 @@ const AtomicString& ServiceWorker::InterfaceName() const {
}
void ServiceWorker::postMessage(ScriptState* script_state,
- scoped_refptr<SerializedScriptValue> message,
- const MessagePortArray& ports,
+ const ScriptValue& message,
+ Vector<ScriptValue>& transfer,
+ ExceptionState& exception_state) {
+ PostMessageOptions options;
+ if (!transfer.IsEmpty())
+ options.setTransfer(transfer);
+ postMessage(script_state, message, options, exception_state);
+}
+
+void ServiceWorker::postMessage(ScriptState* script_state,
+ const ScriptValue& message,
+ const PostMessageOptions& options,
ExceptionState& exception_state) {
ServiceWorkerContainerClient* client =
ServiceWorkerContainerClient::From(GetExecutionContext());
@@ -62,10 +74,21 @@ void ServiceWorker::postMessage(ScriptState* script_state,
return;
}
+ Transferables transferables;
+
+ scoped_refptr<SerializedScriptValue> serialized_message =
+ PostMessageHelper::SerializeMessageByCopy(script_state->GetIsolate(),
+ message, options, transferables,
+ exception_state);
+ if (exception_state.HadException())
+ return;
+ DCHECK(serialized_message);
+
BlinkTransferableMessage msg;
- msg.message = message;
+ msg.message = serialized_message;
msg.ports = MessagePort::DisentanglePorts(
- ExecutionContext::From(script_state), ports, exception_state);
+ ExecutionContext::From(script_state), transferables.message_ports,
+ exception_state);
if (exception_state.HadException())
return;
@@ -89,7 +112,7 @@ ScriptPromise ServiceWorker::InternalsTerminate(ScriptState* script_state) {
}
void ServiceWorker::DispatchStateChangeEvent() {
- this->DispatchEvent(Event::Create(EventTypeNames::statechange));
+ this->DispatchEvent(*Event::Create(EventTypeNames::statechange));
}
String ServiceWorker::scriptURL() const {
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 bdd5d3a4936..be575e131f5 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
@@ -43,6 +43,7 @@
namespace blink {
+class PostMessageOptions;
class ScriptState;
class MODULES_EXPORT ServiceWorker final
@@ -63,10 +64,13 @@ class MODULES_EXPORT ServiceWorker final
EAGERLY_FINALIZE();
void postMessage(ScriptState*,
- scoped_refptr<SerializedScriptValue> message,
- const MessagePortArray&,
+ const ScriptValue& message,
+ Vector<ScriptValue>& transfer,
+ ExceptionState&);
+ void postMessage(ScriptState*,
+ const ScriptValue& message,
+ const PostMessageOptions&,
ExceptionState&);
- static bool CanTransferArrayBuffersAndImageBitmaps() { return false; }
String scriptURL() const;
String state() const;
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 505ea0114a1..44814895f2e 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
@@ -43,7 +43,8 @@ enum ServiceWorkerState {
SecureContext
] interface ServiceWorker : EventTarget {
- [PostMessage, RaisesException] void postMessage(any message, optional sequence<object> transfer);
+ [CallWith=ScriptState, RaisesException] void postMessage(any message, optional sequence<object> transfer = []);
+ [RuntimeEnabled=PostMessageOptions, CallWith=ScriptState, RaisesException] void postMessage(any message, 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 4a1d2df4f77..959f27b1a02 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,11 @@
#include "third_party/blink/public/mojom/service_worker/service_worker_client.mojom-blink.h"
#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/serialized_script_value.h"
+#include "third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/frame/use_counter.h"
#include "third_party/blink/renderer/core/messaging/blink_transferable_message.h"
+#include "third_party/blink/renderer/core/messaging/post_message_options.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
@@ -86,15 +87,35 @@ String ServiceWorkerClient::frameType(ScriptState* script_state) const {
return String();
}
-void ServiceWorkerClient::postMessage(
- ScriptState* script_state,
- scoped_refptr<SerializedScriptValue> message,
- const MessagePortArray& ports,
- ExceptionState& exception_state) {
+void ServiceWorkerClient::postMessage(ScriptState* script_state,
+ const ScriptValue& message,
+ Vector<ScriptValue>& transfer,
+ ExceptionState& exception_state) {
+ PostMessageOptions options;
+ if (!transfer.IsEmpty())
+ options.setTransfer(transfer);
+ postMessage(script_state, message, options, exception_state);
+}
+
+void ServiceWorkerClient::postMessage(ScriptState* script_state,
+ const ScriptValue& message,
+ const PostMessageOptions& options,
+ ExceptionState& exception_state) {
ExecutionContext* context = ExecutionContext::From(script_state);
+ Transferables transferables;
+
+ scoped_refptr<SerializedScriptValue> serialized_message =
+ PostMessageHelper::SerializeMessageByCopy(script_state->GetIsolate(),
+ message, options, transferables,
+ exception_state);
+ if (exception_state.HadException())
+ return;
+ DCHECK(serialized_message);
+
BlinkTransferableMessage msg;
- msg.message = message;
- msg.ports = MessagePort::DisentanglePorts(context, ports, exception_state);
+ msg.message = serialized_message;
+ msg.ports = MessagePort::DisentanglePorts(
+ context, transferables.message_ports, exception_state);
if (exception_state.HadException())
return;
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 7cbe7818f79..8dc40463664 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
@@ -8,7 +8,6 @@
#include <memory>
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_clients_info.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
-#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/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -16,6 +15,7 @@
namespace blink {
+class PostMessageOptions;
class ScriptPromiseResolver;
class ScriptState;
@@ -38,11 +38,13 @@ class MODULES_EXPORT ServiceWorkerClient : public ScriptWrappable {
String frameType(ScriptState*) const;
String id() const { return uuid_; }
void postMessage(ScriptState*,
- scoped_refptr<SerializedScriptValue> message,
- const MessagePortArray&,
+ const ScriptValue& message,
+ Vector<ScriptValue>& transfer,
+ ExceptionState&);
+ void postMessage(ScriptState*,
+ const ScriptValue& message,
+ const PostMessageOptions&,
ExceptionState&);
-
- static bool CanTransferArrayBuffersAndImageBitmaps() { return false; }
protected:
explicit ServiceWorkerClient(const WebServiceWorkerClientInfo&);
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 c2cd91e8b21..b86eca316ed 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
@@ -422,7 +422,7 @@ void ServiceWorkerContainer::SetController(
WebFeature::kServiceWorkerControlledPage);
}
if (should_notify_controller_change)
- DispatchEvent(Event::Create(EventTypeNames::controllerchange));
+ DispatchEvent(*Event::Create(EventTypeNames::controllerchange));
}
void ServiceWorkerContainer::DispatchMessageEvent(
@@ -435,10 +435,18 @@ void ServiceWorkerContainer::DispatchMessageEvent(
MessagePort::EntanglePorts(*GetExecutionContext(), std::move(msg.ports));
ServiceWorker* source =
ServiceWorker::From(GetExecutionContext(), std::move(handle));
- DispatchEvent(MessageEvent::Create(
- ports, std::move(msg.message),
- GetExecutionContext()->GetSecurityOrigin()->ToString(),
- String() /* lastEventId */, source));
+ MessageEvent* event;
+ if (!msg.locked_agent_cluster_id ||
+ GetExecutionContext()->IsSameAgentCluster(*msg.locked_agent_cluster_id)) {
+ event = MessageEvent::Create(
+ ports, std::move(msg.message),
+ GetExecutionContext()->GetSecurityOrigin()->ToString(),
+ String() /* lastEventId */, source);
+ } else {
+ event = MessageEvent::CreateError(
+ GetExecutionContext()->GetSecurityOrigin()->ToString(), source);
+ }
+ DispatchEvent(*event);
}
void ServiceWorkerContainer::CountFeature(mojom::WebFeature feature) {
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 81089270260..3bea7b455ec 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
@@ -43,6 +43,7 @@
#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"
+#include "third_party/blink/renderer/core/frame/deprecation.h"
#include "third_party/blink/renderer/core/frame/use_counter.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/inspector/worker_inspector_controller.h"
@@ -135,8 +136,7 @@ void ServiceWorkerGlobalScope::EvaluateClassicScript(
InstalledScriptsManager::ScriptStatus status =
installed_scripts_manager->GetScriptData(script_url, &script_data);
if (status == InstalledScriptsManager::ScriptStatus::kFailed) {
- // This eventually terminates the worker thread.
- ReportingProxy().DidEvaluateClassicScript(false);
+ close();
return;
}
@@ -159,10 +159,7 @@ void ServiceWorkerGlobalScope::EvaluateClassicScript(
script_data.CreateOriginTrialTokens();
OriginTrialContext::AddTokens(this, origin_trial_tokens.get());
- // This may block until CSP and referrer policy are set on the main
- // thread.
- ReportingProxy().DidLoadInstalledScript(
- content_security_policy_raw_headers.value(), referrer_policy);
+ ReportingProxy().DidLoadInstalledScript();
}
WorkerGlobalScope::EvaluateClassicScript(script_url, source_code,
@@ -290,7 +287,7 @@ void ServiceWorkerGlobalScope::DispatchExtendableEvent(
Event* event,
WaitUntilObserver* observer) {
observer->WillDispatchEvent();
- DispatchEvent(event);
+ DispatchEvent(*event);
// Check if the worker thread is forcibly terminated during the event
// because of timeout etc.
@@ -303,7 +300,7 @@ void ServiceWorkerGlobalScope::DispatchExtendableEventWithRespondWith(
RespondWithObserver* respond_with_observer) {
wait_until_observer->WillDispatchEvent();
respond_with_observer->WillDispatchEvent();
- DispatchEventResult dispatch_result = DispatchEvent(event);
+ DispatchEventResult dispatch_result = DispatchEvent(*event);
respond_with_observer->DidDispatchEvent(dispatch_result);
// false is okay because waitUntil() for events with respondWith() doesn't
// care about the promise rejection or an uncaught runtime script error.
@@ -331,6 +328,8 @@ void ServiceWorkerGlobalScope::importScripts(const Vector<String>& urls,
!installed_scripts_manager->IsScriptInstalled(completed_url)) {
DCHECK(installed_scripts_manager->IsScriptInstalled(Url()));
CountFeature(WebFeature::kServiceWorkerImportScriptNotInstalled);
+ Deprecation::CountDeprecation(
+ this, WebFeature::kServiceWorkerImportScriptNotInstalled);
}
// Bust the MemoryCache to ensure script requests reach the browser-side
// and get added to and retrieved from the ServiceWorker's script cache.
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.cc
index 68b29db3412..ae17974d99b 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.cc
@@ -111,12 +111,12 @@ void ServiceWorkerGlobalScopeClient::DidHandleBackgroundFetchFailEvent(
event_dispatch_time);
}
-void ServiceWorkerGlobalScopeClient::DidHandleBackgroundFetchedEvent(
+void ServiceWorkerGlobalScopeClient::DidHandleBackgroundFetchSuccessEvent(
int event_id,
mojom::ServiceWorkerEventStatus status,
double event_dispatch_time) {
- client_.DidHandleBackgroundFetchedEvent(event_id, status,
- event_dispatch_time);
+ client_.DidHandleBackgroundFetchSuccessEvent(event_id, status,
+ event_dispatch_time);
}
void ServiceWorkerGlobalScopeClient::DidHandleCookieChangeEvent(
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.h
index cb62c62aaf4..91096359d82 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.h
@@ -92,9 +92,9 @@ class MODULES_EXPORT ServiceWorkerGlobalScopeClient
void DidHandleBackgroundFetchFailEvent(int event_id,
mojom::ServiceWorkerEventStatus,
double event_dispatch_time);
- void DidHandleBackgroundFetchedEvent(int event_id,
- mojom::ServiceWorkerEventStatus,
- double event_dispatch_time);
+ void DidHandleBackgroundFetchSuccessEvent(int event_id,
+ mojom::ServiceWorkerEventStatus,
+ double event_dispatch_time);
void DidHandleCookieChangeEvent(int event_id,
mojom::ServiceWorkerEventStatus,
double event_dispatch_time);
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 88c47ee2bbf..f55fc9ae2e1 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
@@ -36,6 +36,7 @@
#include "base/memory/ptr_util.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_client.mojom-blink.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom-blink.h"
+#include "third_party/blink/public/platform/modules/notifications/notification.mojom-blink.h"
#include "third_party/blink/public/platform/modules/notifications/web_notification_data.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_request.h"
#include "third_party/blink/public/web/modules/service_worker/web_service_worker_context_client.h"
@@ -44,7 +45,6 @@
#include "third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/fetch/headers.h"
-#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/messaging/blink_transferable_message.h"
#include "third_party/blink/renderer/core/messaging/message_port.h"
@@ -52,14 +52,10 @@
#include "third_party/blink/renderer/core/workers/parent_execution_context_task_runners.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/modules/background_fetch/background_fetch_click_event.h"
-#include "third_party/blink/renderer/modules/background_fetch/background_fetch_click_event_init.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_fail_event.h"
-#include "third_party/blink/renderer/modules/background_fetch/background_fetch_fail_event_init.h"
-#include "third_party/blink/renderer/modules/background_fetch/background_fetch_settled_event_init.h"
-#include "third_party/blink/renderer/modules/background_fetch/background_fetch_update_event.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/sync_event.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"
@@ -88,31 +84,88 @@
#include "third_party/blink/renderer/modules/service_worker/wait_until_observer.h"
#include "third_party/blink/renderer/platform/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_response.h"
-#include "third_party/blink/renderer/platform/network/content_security_policy_response_headers.h"
-#include "third_party/blink/renderer/platform/waitable_event.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
-namespace blink {
+namespace mojo {
namespace {
-void SetContentSecurityPolicyAndReferrerPolicyOnMainThread(
- WebEmbeddedWorkerImpl* embedded_worker,
- ContentSecurityPolicyResponseHeaders csp_headers,
- String referrer_policy,
- WaitableEvent* waitable_event) {
- DCHECK(IsMainThread());
- ContentSecurityPolicy* content_security_policy =
- ContentSecurityPolicy::Create();
- content_security_policy->DidReceiveHeaders(csp_headers);
- embedded_worker->SetContentSecurityPolicyAndReferrerPolicy(
- content_security_policy, std::move(referrer_policy));
- waitable_event->Signal();
+blink::mojom::NotificationDirection ToMojomNotificationDirection(
+ blink::WebNotificationData::Direction input) {
+ switch (input) {
+ case blink::WebNotificationData::kDirectionLeftToRight:
+ return blink::mojom::NotificationDirection::LEFT_TO_RIGHT;
+ case blink::WebNotificationData::kDirectionRightToLeft:
+ return blink::mojom::NotificationDirection::RIGHT_TO_LEFT;
+ case blink::WebNotificationData::kDirectionAuto:
+ return blink::mojom::NotificationDirection::AUTO;
+ }
+
+ NOTREACHED();
+ return blink::mojom::NotificationDirection::AUTO;
+}
+
+blink::mojom::NotificationActionType ToMojomNotificationActionType(
+ blink::WebNotificationAction::Type input) {
+ switch (input) {
+ case blink::WebNotificationAction::kButton:
+ return blink::mojom::NotificationActionType::BUTTON;
+ case blink::WebNotificationAction::kText:
+ return blink::mojom::NotificationActionType::TEXT;
+ }
+
+ NOTREACHED();
+ return blink::mojom::NotificationActionType::BUTTON;
}
} // namespace
+// Inside Blink we're using mojom structs to represent notification data, not
+// WebNotification{Action,Data}, however, we still need WebNotificationData to
+// carry data from Content into Blink, so, for now we need these type
+// converters. They would disappear once we eliminate the abstract interface
+// layer blink::WebServiceWorkerContextProxy via Onion Soup effort later.
+template <>
+struct TypeConverter<blink::mojom::blink::NotificationActionPtr,
+ blink::WebNotificationAction> {
+ static blink::mojom::blink::NotificationActionPtr Convert(
+ const blink::WebNotificationAction& input) {
+ return blink::mojom::blink::NotificationAction::New(
+ ToMojomNotificationActionType(input.type), input.action, input.title,
+ input.icon, input.placeholder);
+ }
+};
+
+template <>
+struct TypeConverter<blink::mojom::blink::NotificationDataPtr,
+ blink::WebNotificationData> {
+ static blink::mojom::blink::NotificationDataPtr Convert(
+ const blink::WebNotificationData& input) {
+ Vector<int32_t> vibration_pattern;
+ vibration_pattern.Append(input.vibrate.Data(), input.vibrate.size());
+
+ Vector<uint8_t> data;
+ data.Append(input.data.Data(), input.data.size());
+
+ Vector<blink::mojom::blink::NotificationActionPtr> actions;
+ for (const auto& web_action : input.actions) {
+ actions.push_back(
+ blink::mojom::blink::NotificationAction::From(web_action));
+ }
+
+ return blink::mojom::blink::NotificationData::New(
+ input.title, ToMojomNotificationDirection(input.direction), input.lang,
+ input.body, input.tag, input.image, input.icon, input.badge,
+ std::move(vibration_pattern), input.timestamp, input.renotify,
+ input.silent, input.require_interaction, std::move(data),
+ std::move(actions));
+ }
+};
+
+} // namespace mojo
+
+namespace blink {
ServiceWorkerGlobalScopeProxy* ServiceWorkerGlobalScopeProxy::Create(
WebEmbeddedWorkerImpl& embedded_worker,
WebServiceWorkerContextClient& client) {
@@ -141,9 +194,7 @@ void ServiceWorkerGlobalScopeProxy::SetRegistration(
void ServiceWorkerGlobalScopeProxy::DispatchBackgroundFetchAbortEvent(
int event_id,
- const WebString& developer_id,
- const WebString& unique_id,
- const WebVector<WebBackgroundFetchSettledFetch>& fetches) {
+ const WebBackgroundFetchRegistration& registration) {
DCHECK(WorkerGlobalScope()->IsContextThread());
WaitUntilObserver* observer = WaitUntilObserver::Create(
WorkerGlobalScope(), WaitUntilObserver::kBackgroundFetchAbort, event_id);
@@ -152,43 +203,33 @@ void ServiceWorkerGlobalScopeProxy::DispatchBackgroundFetchAbortEvent(
WorkerGlobalScope()->ScriptController()->GetScriptState();
// Do not remove this, |scope| is needed by
- // BackgroundFetchSettledFetches::Create which eventually calls ToV8.
+ // BackgroundFetchEvent::Create which eventually calls ToV8.
ScriptState::Scope scope(script_state);
- BackgroundFetchSettledEventInit init;
- init.setId(developer_id);
- init.setFetches(BackgroundFetchSettledFetches::Create(script_state, fetches));
+ BackgroundFetchEventInit init;
+ init.setRegistration(new BackgroundFetchRegistration(
+ WorkerGlobalScope()->registration() /* service_worker_registration */,
+ registration));
- BackgroundFetchSettledEvent* event = BackgroundFetchSettledEvent::Create(
- EventTypeNames::backgroundfetchabort, init, unique_id, observer);
+ BackgroundFetchEvent* event = BackgroundFetchEvent::Create(
+ EventTypeNames::backgroundfetchabort, init, observer);
WorkerGlobalScope()->DispatchExtendableEvent(event, observer);
}
void ServiceWorkerGlobalScopeProxy::DispatchBackgroundFetchClickEvent(
int event_id,
- const WebString& developer_id,
- BackgroundFetchState status) {
+ const WebBackgroundFetchRegistration& registration) {
DCHECK(WorkerGlobalScope()->IsContextThread());
WaitUntilObserver* observer = WaitUntilObserver::Create(
WorkerGlobalScope(), WaitUntilObserver::kBackgroundFetchClick, event_id);
- BackgroundFetchClickEventInit init;
- init.setId(developer_id);
-
- switch (status) {
- case BackgroundFetchState::kPending:
- init.setState("pending");
- break;
- case BackgroundFetchState::kSucceeded:
- init.setState("succeeded");
- break;
- case BackgroundFetchState::kFailed:
- init.setState("failed");
- break;
- }
+ BackgroundFetchEventInit init;
+ init.setRegistration(new BackgroundFetchRegistration(
+ WorkerGlobalScope()->registration() /* service_worker_registration */,
+ registration));
- BackgroundFetchClickEvent* event = BackgroundFetchClickEvent::Create(
+ BackgroundFetchEvent* event = BackgroundFetchEvent::Create(
EventTypeNames::backgroundfetchclick, init, observer);
WorkerGlobalScope()->DispatchExtendableEvent(event, observer);
@@ -196,9 +237,7 @@ void ServiceWorkerGlobalScopeProxy::DispatchBackgroundFetchClickEvent(
void ServiceWorkerGlobalScopeProxy::DispatchBackgroundFetchFailEvent(
int event_id,
- const WebString& developer_id,
- const WebString& unique_id,
- const WebVector<WebBackgroundFetchSettledFetch>& fetches) {
+ const WebBackgroundFetchRegistration& registration) {
DCHECK(WorkerGlobalScope()->IsContextThread());
WaitUntilObserver* observer = WaitUntilObserver::Create(
WorkerGlobalScope(), WaitUntilObserver::kBackgroundFetchFail, event_id);
@@ -207,43 +246,44 @@ void ServiceWorkerGlobalScopeProxy::DispatchBackgroundFetchFailEvent(
WorkerGlobalScope()->ScriptController()->GetScriptState();
// Do not remove this, |scope| is needed by
- // BackgroundFetchSettledFetches::Create which eventually calls ToV8.
+ // BackgroundFetchSettledEvent::Create which eventually calls ToV8.
ScriptState::Scope scope(script_state);
- BackgroundFetchSettledEventInit init;
- init.setId(developer_id);
- init.setFetches(BackgroundFetchSettledFetches::Create(script_state, fetches));
+ BackgroundFetchEventInit init;
+ init.setRegistration(new BackgroundFetchRegistration(
+ WorkerGlobalScope()->registration() /* service_worker_registration */,
+ registration));
- BackgroundFetchUpdateEvent* event = BackgroundFetchUpdateEvent::Create(
- EventTypeNames::backgroundfetchfail, init, unique_id, script_state,
- observer, worker_global_scope_->registration());
+ BackgroundFetchUpdateUIEvent* event = BackgroundFetchUpdateUIEvent::Create(
+ EventTypeNames::backgroundfetchfail, init, observer,
+ worker_global_scope_->registration());
WorkerGlobalScope()->DispatchExtendableEvent(event, observer);
}
-void ServiceWorkerGlobalScopeProxy::DispatchBackgroundFetchedEvent(
+void ServiceWorkerGlobalScopeProxy::DispatchBackgroundFetchSuccessEvent(
int event_id,
- const WebString& developer_id,
- const WebString& unique_id,
- const WebVector<WebBackgroundFetchSettledFetch>& fetches) {
+ const WebBackgroundFetchRegistration& registration) {
DCHECK(WorkerGlobalScope()->IsContextThread());
WaitUntilObserver* observer = WaitUntilObserver::Create(
- WorkerGlobalScope(), WaitUntilObserver::kBackgroundFetched, event_id);
+ WorkerGlobalScope(), WaitUntilObserver::kBackgroundFetchSuccess,
+ event_id);
ScriptState* script_state =
WorkerGlobalScope()->ScriptController()->GetScriptState();
// Do not remove this, |scope| is needed by
- // BackgroundFetchSettledFetches::Create which eventually calls ToV8.
+ // BackgroundFetchSettledEvent::Create which eventually calls ToV8.
ScriptState::Scope scope(script_state);
- BackgroundFetchSettledEventInit init;
- init.setId(developer_id);
- init.setFetches(BackgroundFetchSettledFetches::Create(script_state, fetches));
+ BackgroundFetchEventInit init;
+ init.setRegistration(new BackgroundFetchRegistration(
+ WorkerGlobalScope()->registration() /* service_worker_registration */,
+ registration));
- BackgroundFetchUpdateEvent* event = BackgroundFetchUpdateEvent::Create(
- EventTypeNames::backgroundfetched, init, unique_id, script_state,
- observer, worker_global_scope_->registration());
+ BackgroundFetchUpdateUIEvent* event = BackgroundFetchUpdateUIEvent::Create(
+ EventTypeNames::backgroundfetchsuccess, init, observer,
+ worker_global_scope_->registration());
WorkerGlobalScope()->DispatchExtendableEvent(event, observer);
}
@@ -433,7 +473,8 @@ void ServiceWorkerGlobalScopeProxy::DispatchNotificationClickEvent(
WorkerGlobalScope(), WaitUntilObserver::kNotificationClick, event_id);
NotificationEventInit event_init;
event_init.setNotification(Notification::Create(
- WorkerGlobalScope(), notification_id, data, true /* showing */));
+ WorkerGlobalScope(), notification_id,
+ mojom::blink::NotificationData::From(data), true /* showing */));
if (0 <= action_index && action_index < static_cast<int>(data.actions.size()))
event_init.setAction(data.actions[action_index].action);
event_init.setReply(reply);
@@ -452,7 +493,8 @@ void ServiceWorkerGlobalScopeProxy::DispatchNotificationCloseEvent(
NotificationEventInit event_init;
event_init.setAction(WTF::String()); // initialize as null.
event_init.setNotification(Notification::Create(
- WorkerGlobalScope(), notification_id, data, false /* showing */));
+ WorkerGlobalScope(), notification_id,
+ mojom::blink::NotificationData::From(data), false /* showing */));
Event* event = NotificationEvent::Create(EventTypeNames::notificationclose,
event_init, observer);
WorkerGlobalScope()->DispatchExtendableEvent(event, observer);
@@ -548,8 +590,8 @@ void ServiceWorkerGlobalScopeProxy::CountFeature(WebFeature feature) {
void ServiceWorkerGlobalScopeProxy::CountDeprecation(WebFeature feature) {
// Go through the same code path with countFeature() because a deprecation
- // message is already shown on the worker console and a remaining work is just
- // to record an API use.
+ // message is already shown on the worker console and a remaining work is
+ // just to record an API use.
CountFeature(feature);
}
@@ -599,27 +641,9 @@ void ServiceWorkerGlobalScopeProxy::DidInitializeWorkerContext() {
WorkerGlobalScope()->ScriptController()->GetContext());
}
-void ServiceWorkerGlobalScopeProxy::DidLoadInstalledScript(
- const ContentSecurityPolicyResponseHeaders& csp_headers_on_worker_thread,
- const String& referrer_policy_on_worker_thread) {
- // Post a task to the main thread to set CSP and ReferrerPolicy on the shadow
- // page.
- DCHECK(embedded_worker_);
- WaitableEvent waitable_event;
- PostCrossThreadTask(
- *parent_execution_context_task_runners_->Get(TaskType::kInternalWorker),
- FROM_HERE,
- CrossThreadBind(&SetContentSecurityPolicyAndReferrerPolicyOnMainThread,
- CrossThreadUnretained(embedded_worker_),
- csp_headers_on_worker_thread,
- referrer_policy_on_worker_thread,
- CrossThreadUnretained(&waitable_event)));
+void ServiceWorkerGlobalScopeProxy::DidLoadInstalledScript() {
+ DCHECK(WorkerGlobalScope()->IsContextThread());
Client().WorkerScriptLoaded();
-
- // Wait for the task to complete before returning. This ensures that worker
- // script evaluation can't start and issue any fetches until CSP and
- // ReferrerPolicy are set.
- waitable_event.Wait();
}
void ServiceWorkerGlobalScopeProxy::WillEvaluateClassicScript(
@@ -644,9 +668,30 @@ void ServiceWorkerGlobalScopeProxy::DidEvaluateClassicScript(bool success) {
}
void ServiceWorkerGlobalScopeProxy::DidCloseWorkerGlobalScope() {
- // This should never be called because close() is not defined in
- // ServiceWorkerGlobalScope.
- NOTREACHED();
+ DCHECK(WorkerGlobalScope()->IsContextThread());
+ // close() is not web-exposed. This is called when ServiceWorkerGlobalScope
+ // internally requests close() due to failure on startup when installed
+ // scripts couldn't be read.
+ //
+ // This may look like a roundabout way to terminate the thread, but close()
+ // seems like the standard way to initiate termination from inside the thread.
+
+ // Tell ServiceWorkerContextClient about the failure. The generic
+ // WorkerContextFailedToStart() wouldn't make sense because
+ // WorkerContextStarted() was already called.
+ Client().FailedToLoadInstalledScript();
+
+ // ServiceWorkerGlobalScope expects us to terminate the thread, so request
+ // that here.
+ PostCrossThreadTask(
+ *parent_execution_context_task_runners_->Get(TaskType::kInternalDefault),
+ FROM_HERE,
+ CrossThreadBind(&WebEmbeddedWorkerImpl::TerminateWorkerContext,
+ CrossThreadUnretained(embedded_worker_)));
+
+ // NOTE: WorkerThread calls WillDestroyWorkerGlobalScope() synchronously after
+ // this function returns, since it calls DidCloseWorkerGlobalScope() then
+ // PrepareForShutdownOnWorkerThread().
}
void ServiceWorkerGlobalScopeProxy::WillDestroyWorkerGlobalScope() {
@@ -658,7 +703,7 @@ void ServiceWorkerGlobalScopeProxy::WillDestroyWorkerGlobalScope() {
}
void ServiceWorkerGlobalScopeProxy::DidTerminateWorkerThread() {
- // This should be called after WillDestroyWorkerGlobalScope().
+ // This must be called after WillDestroyWorkerGlobalScope().
DCHECK(!worker_global_scope_);
Client().WorkerContextDestroyed();
}
@@ -670,10 +715,10 @@ ServiceWorkerGlobalScopeProxy::ServiceWorkerGlobalScopeProxy(
client_(&client),
worker_global_scope_(nullptr) {
DCHECK(IsMainThread());
- // ServiceWorker can sometimes run tasks that are initiated by/associated with
- // a document's frame but these documents can be from a different process. So
- // we intentionally populate the task runners with default task runners of the
- // main thread.
+ // ServiceWorker can sometimes run tasks that are initiated by/associated
+ // with a document's frame but these documents can be from a different
+ // process. So we intentionally populate the task runners with default task
+ // runners of the main thread.
parent_execution_context_task_runners_ =
ParentExecutionContextTaskRunners::Create();
}
@@ -685,6 +730,7 @@ void ServiceWorkerGlobalScopeProxy::Detach() {
}
void ServiceWorkerGlobalScopeProxy::TerminateWorkerContext() {
+ DCHECK(IsMainThread());
embedded_worker_->TerminateWorkerContext();
}
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 89c1dcd1d4b..aad7210a856 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
@@ -83,22 +83,16 @@ class ServiceWorkerGlobalScopeProxy final
void DispatchActivateEvent(int) override;
void DispatchBackgroundFetchAbortEvent(
int event_id,
- const WebString& developer_id,
- const WebString& unique_id,
- const WebVector<WebBackgroundFetchSettledFetch>& fetches) override;
- void DispatchBackgroundFetchClickEvent(int event_id,
- const WebString& developer_id,
- BackgroundFetchState) override;
+ const WebBackgroundFetchRegistration& registration) override;
+ void DispatchBackgroundFetchClickEvent(
+ int event_id,
+ const WebBackgroundFetchRegistration& registration) override;
void DispatchBackgroundFetchFailEvent(
int event_id,
- const WebString& developer_id,
- const WebString& unique_id,
- const WebVector<WebBackgroundFetchSettledFetch>& fetches) override;
- void DispatchBackgroundFetchedEvent(
+ const WebBackgroundFetchRegistration& registration) override;
+ void DispatchBackgroundFetchSuccessEvent(
int event_id,
- const WebString& developer_id,
- const WebString& unique_id,
- const WebVector<WebBackgroundFetchSettledFetch>& fetches) override;
+ const WebBackgroundFetchRegistration& registration) override;
void DispatchCookieChangeEvent(
int event_id,
const WebCanonicalCookie& cookie,
@@ -159,9 +153,7 @@ class ServiceWorkerGlobalScopeProxy final
void PostMessageToPageInspector(int session_id, const String&) override;
void DidCreateWorkerGlobalScope(WorkerOrWorkletGlobalScope*) override;
void DidInitializeWorkerContext() override;
- void DidLoadInstalledScript(
- const ContentSecurityPolicyResponseHeaders&,
- const String& referrer_policy_on_worker_thread) override;
+ void DidLoadInstalledScript() override;
void WillEvaluateClassicScript(size_t script_size,
size_t cached_metadata_size) override;
void WillEvaluateImportedClassicScript(size_t script_size,
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 eb4d7c6b4bc..f65cf9c6ce9 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
@@ -37,7 +37,7 @@ const AtomicString& ServiceWorkerRegistration::InterfaceName() const {
}
void ServiceWorkerRegistration::DispatchUpdateFoundEvent() {
- DispatchEvent(Event::Create(EventTypeNames::updatefound));
+ DispatchEvent(*Event::Create(EventTypeNames::updatefound));
}
void ServiceWorkerRegistration::SetInstalling(
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_thread.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_thread.cc
index 6c0099605f6..1cec901709b 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_thread.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_thread.cc
@@ -41,12 +41,11 @@
namespace blink {
ServiceWorkerThread::ServiceWorkerThread(
- ThreadableLoadingContext* loading_context,
ServiceWorkerGlobalScopeProxy* global_scope_proxy,
std::unique_ptr<ServiceWorkerInstalledScriptsManager>
installed_scripts_manager,
mojom::blink::CacheStoragePtrInfo cache_storage_info)
- : WorkerThread(loading_context, *global_scope_proxy),
+ : WorkerThread(*global_scope_proxy),
global_scope_proxy_(global_scope_proxy),
worker_backing_thread_(WorkerBackingThread::Create(
WebThreadCreationParams(GetThreadType()))),
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_thread.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_thread.h
index ddff0041540..d07384160df 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_thread.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_thread.h
@@ -48,8 +48,7 @@ class MODULES_EXPORT ServiceWorkerThread final : public WorkerThread {
public:
// ServiceWorkerThread owns a given ServiceWorkerGlobalScopeProxy via
// Persistent.
- ServiceWorkerThread(ThreadableLoadingContext*,
- ServiceWorkerGlobalScopeProxy*,
+ ServiceWorkerThread(ServiceWorkerGlobalScopeProxy*,
std::unique_ptr<ServiceWorkerInstalledScriptsManager>,
mojom::blink::CacheStoragePtrInfo cache_storage_info);
~ServiceWorkerThread() override;
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 7af9c60258e..ecbfbbdb272 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
@@ -305,9 +305,9 @@ void WaitUntilObserver::MaybeCompleteEvent() {
client->DidHandleBackgroundFetchFailEvent(event_id_, status,
event_dispatch_time_);
break;
- case kBackgroundFetched:
- client->DidHandleBackgroundFetchedEvent(event_id_, status,
- event_dispatch_time_);
+ case kBackgroundFetchSuccess:
+ client->DidHandleBackgroundFetchSuccessEvent(event_id_, status,
+ event_dispatch_time_);
break;
}
execution_context_ = nullptr;
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 f602d983f66..47560c2d683 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
@@ -42,7 +42,7 @@ class MODULES_EXPORT WaitUntilObserver final
kBackgroundFetchAbort,
kBackgroundFetchClick,
kBackgroundFetchFail,
- kBackgroundFetched
+ kBackgroundFetchSuccess
};
static WaitUntilObserver* Create(ExecutionContext*, EventType, int event_id);
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 d17f7e49ba5..231bb6286bb 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
@@ -130,7 +130,7 @@ class WebEmbeddedWorkerImplTest : public testing::Test {
mojo::ScopedMessagePipeHandle());
WebURL script_url = URLTestHelpers::ToKURL("https://www.example.com/sw.js");
- WebURLResponse response;
+ WebURLResponse response(script_url);
response.SetMIMEType("text/javascript");
response.SetHTTPStatusCode(200);
Platform::Current()->GetURLLoaderMockFactory()->RegisterURL(script_url,
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 42690b5941d..0d89b5bf68c 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector.idl
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector.idl
@@ -9,7 +9,7 @@
ConstructorCallWith=ExecutionContext,
Exposed=(Window,Worker),
MeasureAs=ShapeDetection_BarcodeDetectorConstructor,
- RuntimeEnabled=ShapeDetection
+ OriginTrialEnabled=ShapeDetection
] interface BarcodeDetector {
- [CallWith=ScriptState] Promise<sequence<DetectedBarcode>> detect(ImageBitmapSource image);
+ [CallWith=ScriptState, MeasureAs=ShapeDetectionAPI] Promise<sequence<DetectedBarcode>> detect(ImageBitmapSource image);
};
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 56951d2c1cd..8d6aa759712 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/detected_barcode.idl
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/detected_barcode.idl
@@ -6,7 +6,7 @@
[
Constructor,
- RuntimeEnabled=ShapeDetection
+ OriginTrialEnabled=ShapeDetection
] interface DetectedBarcode {
// TODO(mcasas): Implement missing fields. https://crbug.com/646083
[SameObject] readonly attribute DOMString rawValue;
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 d07c2972ffe..fda03e7c2f0 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/detected_face.idl
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/detected_face.idl
@@ -6,7 +6,7 @@
[
Constructor,
- RuntimeEnabled=ShapeDetection
+ OriginTrialEnabled=ShapeDetection
] interface DetectedFace {
// TODO(xianglu): Implement any other fields. https://crbug.com/646083
[SameObject] readonly attribute DOMRectReadOnly boundingBox;
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 ec0a22a7bea..8b08cde053c 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/detected_text.idl
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/detected_text.idl
@@ -6,7 +6,7 @@
[
Constructor,
- RuntimeEnabled=ShapeDetection
+ OriginTrialEnabled=ShapeDetection
] interface DetectedText {
[SameObject] readonly attribute DOMString rawValue;
[SameObject] readonly attribute DOMRectReadOnly boundingBox;
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 6b3b8ab5cb9..32218dff569 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/face_detector.idl
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/face_detector.idl
@@ -9,7 +9,7 @@
ConstructorCallWith=ExecutionContext,
Exposed=(Window,Worker),
MeasureAs=ShapeDetection_FaceDetectorConstructor,
- RuntimeEnabled=ShapeDetection
+ OriginTrialEnabled=ShapeDetection
] interface FaceDetector {
- [CallWith=ScriptState] Promise<sequence<DetectedFace>> detect(ImageBitmapSource image);
+ [CallWith=ScriptState, MeasureAs=ShapeDetectionAPI] Promise<sequence<DetectedFace>> detect(ImageBitmapSource image);
};
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 ea26d9686ae..0c7000514e6 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/text_detector.idl
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/text_detector.idl
@@ -9,7 +9,7 @@
ConstructorCallWith=ExecutionContext,
Exposed=(Window,Worker),
MeasureAs=ShapeDetection_TextDetectorConstructor,
- RuntimeEnabled=ShapeDetection
+ OriginTrialEnabled=ShapeDetection
] interface TextDetector {
- [CallWith=ScriptState] Promise<sequence<DetectedText>> detect(ImageBitmapSource image);
+ [CallWith=ScriptState, MeasureAs=ShapeDetectionAPI] Promise<sequence<DetectedText>> detect(ImageBitmapSource image);
};
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 2394ae84e3b..9f2d5589ba9 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition.cc
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition.cc
@@ -130,7 +130,7 @@ void SpeechRecognition::ResultRetrieved(
final_results_ = std::move(new_final_results);
// We dispatch an event with (1) + (2) + (3).
- DispatchEvent(SpeechRecognitionEvent::CreateResult(
+ DispatchEvent(*SpeechRecognitionEvent::CreateResult(
aggregated_results.size() - results.size(),
std::move(aggregated_results)));
}
@@ -138,33 +138,33 @@ void SpeechRecognition::ResultRetrieved(
void SpeechRecognition::ErrorOccurred(
mojom::blink::SpeechRecognitionErrorPtr error) {
if (error->code == mojom::blink::SpeechRecognitionErrorCode::kNoMatch) {
- DispatchEvent(SpeechRecognitionEvent::CreateNoMatch(nullptr));
+ DispatchEvent(*SpeechRecognitionEvent::CreateNoMatch(nullptr));
} else {
// TODO(primiano): message?
- DispatchEvent(SpeechRecognitionError::Create(error->code, String()));
+ DispatchEvent(*SpeechRecognitionError::Create(error->code, String()));
}
}
void SpeechRecognition::Started() {
- DispatchEvent(Event::Create(EventTypeNames::start));
+ DispatchEvent(*Event::Create(EventTypeNames::start));
}
void SpeechRecognition::AudioStarted() {
- DispatchEvent(Event::Create(EventTypeNames::audiostart));
+ DispatchEvent(*Event::Create(EventTypeNames::audiostart));
}
void SpeechRecognition::SoundStarted() {
- DispatchEvent(Event::Create(EventTypeNames::soundstart));
- DispatchEvent(Event::Create(EventTypeNames::speechstart));
+ DispatchEvent(*Event::Create(EventTypeNames::soundstart));
+ DispatchEvent(*Event::Create(EventTypeNames::speechstart));
}
void SpeechRecognition::SoundEnded() {
- DispatchEvent(Event::Create(EventTypeNames::speechend));
- DispatchEvent(Event::Create(EventTypeNames::soundend));
+ DispatchEvent(*Event::Create(EventTypeNames::speechend));
+ DispatchEvent(*Event::Create(EventTypeNames::soundend));
}
void SpeechRecognition::AudioEnded() {
- DispatchEvent(Event::Create(EventTypeNames::audioend));
+ DispatchEvent(*Event::Create(EventTypeNames::audioend));
}
void SpeechRecognition::Ended() {
@@ -172,7 +172,7 @@ void SpeechRecognition::Ended() {
stopping_ = false;
session_.reset();
binding_.Close();
- DispatchEvent(Event::Create(EventTypeNames::end));
+ DispatchEvent(*Event::Create(EventTypeNames::end));
}
const AtomicString& SpeechRecognition::InterfaceName() const {
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_error.cc b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_error.cc
index 44f1bd88004..1e2ba2253d6 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_error.cc
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_error.cc
@@ -24,6 +24,8 @@
*/
#include "third_party/blink/renderer/modules/speech/speech_recognition_error.h"
+
+#include "third_party/blink/renderer/core/event_type_names.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
namespace blink {
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 c6a3e2f9eba..8c77fcda614 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
@@ -25,6 +25,8 @@
#include "third_party/blink/renderer/modules/speech/speech_recognition_event.h"
+#include "third_party/blink/renderer/core/event_type_names.h"
+
namespace blink {
SpeechRecognitionEvent* SpeechRecognitionEvent::Create(
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 ad460c9db39..b873d8ed6b9 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis.cc
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis.cc
@@ -27,6 +27,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/frame/deprecation.h"
#include "third_party/blink/renderer/core/frame/use_counter.h"
#include "third_party/blink/renderer/core/html/media/autoplay_policy.h"
#include "third_party/blink/renderer/core/timing/dom_window_performance.h"
@@ -55,7 +56,7 @@ void SpeechSynthesis::SetPlatformSynthesizer(
void SpeechSynthesis::VoicesDidChange() {
voice_list_.clear();
if (GetExecutionContext())
- DispatchEvent(Event::Create(EventTypeNames::voiceschanged));
+ DispatchEvent(*Event::Create(EventTypeNames::voiceschanged));
}
const HeapVector<Member<SpeechSynthesisVoice>>& SpeechSynthesis::getVoices() {
@@ -119,8 +120,8 @@ void SpeechSynthesis::speak(SpeechSynthesisUtterance* utterance) {
UseCounter::CountCrossOriginIframe(
*document, WebFeature::kTextToSpeech_SpeakCrossOrigin);
if (!IsAllowedToStartByAutoplay()) {
- UseCounter::Count(document,
- WebFeature::kTextToSpeech_SpeakDisallowedByAutoplay);
+ Deprecation::CountDeprecation(
+ document, WebFeature::kTextToSpeech_SpeakDisallowedByAutoplay);
}
utterance_queue_.push_back(utterance);
@@ -158,7 +159,7 @@ void SpeechSynthesis::FireEvent(const AtomicString& type,
return;
double elapsed_time_millis = millis - utterance->StartTime() * 1000.0;
- utterance->DispatchEvent(SpeechSynthesisEvent::Create(
+ utterance->DispatchEvent(*SpeechSynthesisEvent::Create(
type, utterance, char_index, elapsed_time_millis, name));
}
diff --git a/chromium/third_party/blink/renderer/modules/storage/BUILD.gn b/chromium/third_party/blink/renderer/modules/storage/BUILD.gn
index d6c8f876a63..4a5dba165ea 100644
--- a/chromium/third_party/blink/renderer/modules/storage/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/storage/BUILD.gn
@@ -6,6 +6,8 @@ import("//third_party/blink/renderer/modules/modules.gni")
blink_modules_sources("storage") {
sources = [
+ "cached_storage_area.cc",
+ "cached_storage_area.h",
"dom_window_storage.cc",
"dom_window_storage.h",
"dom_window_storage_controller.cc",
@@ -28,7 +30,11 @@ blink_modules_sources("storage") {
jumbo_source_set("unit_tests") {
testonly = true
sources = [
+ "cached_storage_area_test.cc",
"storage_area_map_test.cc",
+ "testing/fake_area_source.h",
+ "testing/mock_storage_area.cc",
+ "testing/mock_storage_area.h",
]
configs += [
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
new file mode 100644
index 00000000000..0cf518029b5
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/storage/cached_storage_area.cc
@@ -0,0 +1,630 @@
+// 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/storage/cached_storage_area.h"
+
+#include "base/metrics/histogram_macros.h"
+#include "base/rand_util.h"
+#include "mojo/public/cpp/bindings/strong_associated_binding.h"
+#include "third_party/blink/public/platform/scheduler/web_thread_scheduler.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_buffer.h"
+#include "third_party/blink/renderer/platform/wtf/text/unicode.h"
+#include "third_party/blink/renderer/platform/wtf/text/utf8.h"
+
+namespace blink {
+
+namespace {
+
+// Don't change or reorder any of the values in this enum, as these values
+// are serialized on disk.
+enum class StorageFormat : uint8_t { UTF16 = 0, Latin1 = 1 };
+
+class GetAllCallback : public mojom::blink::StorageAreaGetAllCallback {
+ public:
+ static mojom::blink::StorageAreaGetAllCallbackAssociatedPtrInfo CreateAndBind(
+ base::OnceCallback<void(bool)> callback) {
+ mojom::blink::StorageAreaGetAllCallbackAssociatedPtrInfo ptr_info;
+ auto request = mojo::MakeRequest(&ptr_info);
+ mojo::MakeStrongAssociatedBinding(
+ base::WrapUnique(new GetAllCallback(std::move(callback))),
+ std::move(request));
+ return ptr_info;
+ }
+
+ 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) {
+ return page_url.GetString() + "\n" + storage_area_id;
+}
+
+void UnpackSource(const String& source,
+ KURL* page_url,
+ String* storage_area_id) {
+ Vector<String> result;
+ source.Split("\n", true, result);
+ DCHECK_EQ(result.size(), 2u);
+ *page_url = KURL(result[0]);
+ *storage_area_id = result[1];
+}
+
+} // namespace
+
+// static
+scoped_refptr<CachedStorageArea> CachedStorageArea::CreateForLocalStorage(
+ scoped_refptr<const SecurityOrigin> origin,
+ mojo::InterfacePtr<mojom::blink::StorageArea> area,
+ scoped_refptr<base::SingleThreadTaskRunner> ipc_runner) {
+ return base::AdoptRef(new CachedStorageArea(
+ std::move(origin), std::move(area), std::move(ipc_runner)));
+}
+
+// static
+scoped_refptr<CachedStorageArea> CachedStorageArea::CreateForSessionStorage(
+ scoped_refptr<const SecurityOrigin> origin,
+ mojo::AssociatedInterfacePtr<mojom::blink::StorageArea> area,
+ scoped_refptr<base::SingleThreadTaskRunner> ipc_runner) {
+ return base::AdoptRef(new CachedStorageArea(
+ std::move(origin), std::move(area), std::move(ipc_runner)));
+}
+
+unsigned CachedStorageArea::GetLength() {
+ EnsureLoaded();
+ return map_->GetLength();
+}
+
+String CachedStorageArea::GetKey(unsigned index) {
+ EnsureLoaded();
+ return map_->GetKey(index);
+}
+
+String CachedStorageArea::GetItem(const String& key) {
+ EnsureLoaded();
+ return map_->GetItem(key);
+}
+
+bool CachedStorageArea::SetItem(const String& key,
+ const String& value,
+ Source* source) {
+ DCHECK(areas_.Contains(source));
+
+ // A quick check to reject obviously overbudget items to avoid priming the
+ // cache.
+ if ((key.length() + value.length()) * 2 >
+ 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())
+ 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) {
+ for (const auto& area : areas_) {
+ if (area.key != source)
+ area.key->EnqueueStorageEvent(key, old_value, value, page_url);
+ }
+ }
+ return true;
+}
+
+void CachedStorageArea::RemoveItem(const String& key, Source* source) {
+ DCHECK(areas_.Contains(source));
+
+ EnsureLoaded();
+ String old_value;
+ 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);
+
+ 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()) {
+ for (const auto& area : areas_) {
+ if (area.key != source)
+ area.key->EnqueueStorageEvent(key, old_value, String(), page_url);
+ }
+ }
+}
+
+void CachedStorageArea::Clear(Source* source) {
+ DCHECK(areas_.Contains(source));
+
+ bool already_empty = false;
+ if (IsSessionStorage()) {
+ EnsureLoaded();
+ already_empty = map_->GetLength() == 0u;
+ }
+ // 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) {
+ for (const auto& area : areas_) {
+ if (area.key != source)
+ area.key->EnqueueStorageEvent(String(), String(), String(), page_url);
+ }
+ }
+}
+
+String CachedStorageArea::RegisterSource(Source* source) {
+ String id = String::Number(base::RandUint64());
+ areas_.insert(source, id);
+ return id;
+}
+
+CachedStorageArea::CachedStorageArea(
+ scoped_refptr<const SecurityOrigin> origin,
+ mojo::InterfacePtr<mojom::blink::StorageArea> area,
+ scoped_refptr<base::SingleThreadTaskRunner> ipc_runner)
+ : origin_(std::move(origin)),
+ mojo_area_(area.get()),
+ mojo_area_ptr_(std::move(area)),
+ binding_(this),
+ weak_factory_(this) {
+ mojom::blink::StorageAreaObserverAssociatedPtrInfo ptr_info;
+ binding_.Bind(mojo::MakeRequest(&ptr_info), std::move(ipc_runner));
+ mojo_area_->AddObserver(std::move(ptr_info));
+}
+
+CachedStorageArea::CachedStorageArea(
+ scoped_refptr<const SecurityOrigin> origin,
+ mojo::AssociatedInterfacePtr<mojom::blink::StorageArea> area,
+ scoped_refptr<base::SingleThreadTaskRunner> ipc_runner)
+ : origin_(std::move(origin)),
+ mojo_area_(area.get()),
+ mojo_area_associated_ptr_(std::move(area)),
+ binding_(this),
+ weak_factory_(this) {
+ mojom::blink::StorageAreaObserverAssociatedPtrInfo ptr_info;
+ binding_.Bind(mojo::MakeRequest(&ptr_info), std::move(ipc_runner));
+ mojo_area_->AddObserver(std::move(ptr_info));
+}
+
+CachedStorageArea::~CachedStorageArea() = default;
+
+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::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::KeyDeleted(const Vector<uint8_t>& key,
+ const Vector<uint8_t>& old_value,
+ const String& source) {
+ DCHECK(!IsSessionStorage());
+ KURL page_url;
+ String storage_area_id;
+ UnpackSource(source, &page_url, &storage_area_id);
+
+ String key_string =
+ Uint8VectorToString(key, FormatOption::kLocalStorageDetectFormat);
+
+ bool from_local_area = false;
+ for (const auto& area : areas_) {
+ if (area.value == storage_area_id) {
+ from_local_area = true;
+ } else {
+ area.key->EnqueueStorageEvent(
+ key_string,
+ Uint8VectorToString(old_value,
+ FormatOption::kLocalStorageDetectFormat),
+ String(), page_url);
+ }
+ }
+
+ 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())
+ map_->RemoveItem(key_string, nullptr);
+ }
+}
+
+void CachedStorageArea::AllDeleted(const String& source) {
+ KURL page_url;
+ String storage_area_id;
+ UnpackSource(source, &page_url, &storage_area_id);
+
+ bool from_local_area = false;
+ for (const auto& area : areas_) {
+ if (area.value == storage_area_id) {
+ from_local_area = true;
+ } else {
+ area.key->EnqueueStorageEvent(String(), String(), String(), page_url);
+ }
+ }
+
+ if (map_ && !from_local_area && !ignore_all_mutations_) {
+ auto old = std::move(map_);
+ 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;
+ }
+ }
+}
+
+void CachedStorageArea::ShouldSendOldValueOnMutations(bool value) {
+ DCHECK(!IsSessionStorage());
+ should_send_old_value_on_mutations_ = value;
+}
+
+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);
+
+ String key_string =
+ Uint8VectorToString(key, FormatOption::kLocalStorageDetectFormat);
+ String new_value_string =
+ Uint8VectorToString(new_value, FormatOption::kLocalStorageDetectFormat);
+
+ bool from_local_area = false;
+ for (const auto& area : areas_) {
+ if (area.value == storage_area_id) {
+ from_local_area = true;
+ } else {
+ area.key->EnqueueStorageEvent(key_string, old_value, new_value_string,
+ page_url);
+ }
+ }
+
+ 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()) {
+ // 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);
+ }
+ }
+}
+
+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;
+}
+
+void CachedStorageArea::EnsureLoaded() {
+ if (map_)
+ return;
+
+ 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);
+
+ // Determine data formats.
+ const FormatOption key_format = GetKeyFormat();
+ const FormatOption value_format = GetValueFormat();
+
+ map_ = std::make_unique<StorageAreaMap>(
+ mojom::blink::StorageArea::kPerStorageAreaQuota);
+ for (const auto& item : data) {
+ map_->SetItemIgnoringQuota(Uint8VectorToString(item->key, key_format),
+ Uint8VectorToString(item->value, value_format));
+ }
+
+ base::TimeDelta time_to_prime = base::TimeTicks::Now() - before;
+ UMA_HISTOGRAM_TIMES("LocalStorage.MojoTimeToPrime", time_to_prime);
+
+ size_t local_storage_size_kb = map_->quota_used() / 1024;
+ // Track localStorage size, from 0-6MB. Note that the maximum size should be
+ // 10MB, but we add some slop since we want to make sure the max size is
+ // always above what we see in practice, since histograms can't change.
+ UMA_HISTOGRAM_CUSTOM_COUNTS("LocalStorage.MojoSizeInKB",
+ local_storage_size_kb, 1, 6 * 1024, 50);
+ if (local_storage_size_kb < 100) {
+ UMA_HISTOGRAM_TIMES("LocalStorage.MojoTimeToPrimeForUnder100KB",
+ time_to_prime);
+ } else if (local_storage_size_kb < 1000) {
+ UMA_HISTOGRAM_TIMES("LocalStorage.MojoTimeToPrimeFor100KBTo1MB",
+ time_to_prime);
+ } else {
+ UMA_HISTOGRAM_TIMES("LocalStorage.MojoTimeToPrimeFor1MBTo5MB",
+ time_to_prime);
+ }
+}
+
+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;
+}
+
+CachedStorageArea::FormatOption CachedStorageArea::GetValueFormat() const {
+ return IsSessionStorage() ? FormatOption::kSessionStorageForceUTF16
+ : FormatOption::kLocalStorageDetectFormat;
+}
+
+bool CachedStorageArea::IsSessionStorage() const {
+ return mojo_area_associated_ptr_.is_bound();
+}
+
+// static
+String CachedStorageArea::Uint8VectorToString(const Vector<uint8_t>& input,
+ FormatOption format_option) {
+ if (input.IsEmpty())
+ return g_empty_string;
+ const size_t input_size = input.size();
+ String result;
+ bool corrupt = false;
+ switch (format_option) {
+ case FormatOption::kSessionStorageForceUTF16: {
+ if (input_size % sizeof(UChar) != 0) {
+ corrupt = true;
+ break;
+ }
+ StringBuffer<UChar> buffer(input_size / sizeof(UChar));
+ std::memcpy(buffer.Characters(), input.data(), input_size);
+ result = String::Adopt(buffer);
+ break;
+ }
+ case FormatOption::kSessionStorageForceUTF8: {
+ // TODO(mek): When this lived in content it used to do a "lenient"
+ // conversion, while this is a strict conversion. Figure out if that
+ // difference actually matters in practice.
+ result = String::FromUTF8(input.data(), input_size);
+ if (result.IsNull()) {
+ corrupt = true;
+ break;
+ }
+ break;
+ }
+ case FormatOption::kLocalStorageDetectFormat: {
+ StorageFormat format = static_cast<StorageFormat>(input[0]);
+ const size_t payload_size = input_size - 1;
+ switch (format) {
+ case StorageFormat::UTF16: {
+ if (payload_size % sizeof(UChar) != 0) {
+ corrupt = true;
+ break;
+ }
+ StringBuffer<UChar> buffer(payload_size / sizeof(UChar));
+ std::memcpy(buffer.Characters(), input.data() + 1, payload_size);
+ result = String::Adopt(buffer);
+ break;
+ }
+ case StorageFormat::Latin1:
+ result = String(reinterpret_cast<const char*>(input.data() + 1),
+ payload_size);
+ break;
+ default:
+ corrupt = true;
+ }
+ break;
+ }
+ }
+ if (corrupt) {
+ // TODO(mek): Better error recovery when corrupt (or otherwise invalid) data
+ // is detected.
+ LOCAL_HISTOGRAM_BOOLEAN("LocalStorageCachedArea.CorruptData", true);
+ LOG(ERROR) << "Corrupt data in domstorage";
+ return g_empty_string;
+ }
+ return result;
+}
+
+// static
+Vector<uint8_t> CachedStorageArea::StringToUint8Vector(
+ const String& input,
+ FormatOption format_option) {
+ switch (format_option) {
+ case FormatOption::kSessionStorageForceUTF16: {
+ Vector<uint8_t> result(input.length() * sizeof(UChar));
+ input.CopyTo(reinterpret_cast<UChar*>(result.data()), 0, input.length());
+ return result;
+ }
+ case FormatOption::kSessionStorageForceUTF8: {
+ unsigned length = input.length();
+ if (input.Is8Bit() && input.ContainsOnlyASCII()) {
+ Vector<uint8_t> result(length);
+ std::memcpy(result.data(), input.Characters8(), length);
+ return result;
+ }
+ // Handle 8 bit case where it's not only ascii.
+ if (input.Is8Bit()) {
+ // This code is copied from WTF::String::Utf8(), except the vector
+ // doesn't have a stack-allocated capacity.
+ // We do this because there isn't a way to transform the CString we get
+ // from WTF::String::Utf8() to a Vector without an extra copy.
+ if (length > std::numeric_limits<unsigned>::max() / 3)
+ return Vector<uint8_t>();
+ Vector<uint8_t> buffer_vector(length * 3);
+ uint8_t* buffer = buffer_vector.data();
+ const LChar* characters = input.Characters8();
+
+ WTF::Unicode::ConversionResult result =
+ WTF::Unicode::ConvertLatin1ToUTF8(
+ &characters, characters + length,
+ reinterpret_cast<char**>(&buffer),
+ reinterpret_cast<char*>(buffer + buffer_vector.size()));
+ // (length * 3) should be sufficient for any conversion
+ DCHECK_NE(result, WTF::Unicode::kTargetExhausted);
+ buffer_vector.Shrink(buffer - buffer_vector.data());
+ return buffer_vector;
+ }
+
+ // TODO(dmurph): Figure out how to avoid a copy here.
+ // TODO(dmurph): Handle invalid UTF16 better. https://crbug.com/873280.
+ CString utf8 = input.Utf8(
+ WTF::kStrictUTF8ConversionReplacingUnpairedSurrogatesWithFFFD);
+ Vector<uint8_t> result(utf8.length());
+ std::memcpy(result.data(), utf8.data(), utf8.length());
+ return result;
+ }
+ case FormatOption::kLocalStorageDetectFormat: {
+ if (input.ContainsOnlyLatin1()) {
+ Vector<uint8_t> result(input.length() + 1);
+ result[0] = static_cast<uint8_t>(StorageFormat::Latin1);
+ if (input.Is8Bit()) {
+ std::memcpy(result.data() + 1, input.Characters8(), input.length());
+ } else {
+ for (unsigned i = 0; i < input.length(); ++i) {
+ result[i + 1] = input[i];
+ }
+ }
+ return result;
+ }
+ DCHECK(!input.Is8Bit());
+ Vector<uint8_t> result(input.length() * sizeof(UChar) + 1);
+ result[0] = static_cast<uint8_t>(StorageFormat::UTF16);
+ std::memcpy(result.data() + 1, input.Characters16(),
+ input.length() * sizeof(UChar));
+ return result;
+ }
+ }
+ NOTREACHED();
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..006552e5420
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/storage/cached_storage_area.h
@@ -0,0 +1,170 @@
+// 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_STORAGE_CACHED_STORAGE_AREA_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_STORAGE_CACHED_STORAGE_AREA_H_
+
+#include "mojo/public/cpp/bindings/associated_binding.h"
+#include "mojo/public/cpp/bindings/associated_interface_ptr.h"
+#include "mojo/public/cpp/bindings/interface_ptr.h"
+#include "third_party/blink/public/mojom/dom_storage/storage_area.mojom-blink.h"
+#include "third_party/blink/public/platform/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/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/text/wtf_string.h"
+
+namespace blink {
+
+// An in-process implementation of LocalStorage using a LevelDB Mojo service.
+// Maintains a complete cache of the origin's Map of key/value pairs for fast
+// access. The cache is primed on first access and changes are written to the
+// backend through the level db interface pointer. Mutations originating in
+// other processes are applied to the cache via mojom::LevelDBObserver
+// callbacks.
+// There is one CachedStorageArea for potentially many LocalStorageArea
+// objects.
+class MODULES_EXPORT CachedStorageArea
+ : public mojom::blink::StorageAreaObserver,
+ public RefCounted<CachedStorageArea> {
+ public:
+ // Instances of this class are used to identify the "source" of any changes
+ // made to this storage area, as well as to dispatch any incoming change
+ // events. Change events are not sent back to the source that caused the
+ // change. The source passed to the various methods that modify storage
+ // should have been registered first by calling RegisterSource.
+ class Source : public GarbageCollectedMixin {
+ public:
+ virtual ~Source() {}
+ virtual KURL GetPageUrl() const = 0;
+ virtual void EnqueueStorageEvent(const String& key,
+ const String& old_value,
+ const String& new_value,
+ const String& url) = 0;
+ virtual blink::WebScopedVirtualTimePauser CreateWebScopedVirtualTimePauser(
+ const char* name,
+ WebScopedVirtualTimePauser::VirtualTaskDuration duration) = 0;
+ };
+
+ static scoped_refptr<CachedStorageArea> CreateForLocalStorage(
+ scoped_refptr<const SecurityOrigin> origin,
+ mojo::InterfacePtr<mojom::blink::StorageArea> area,
+ scoped_refptr<base::SingleThreadTaskRunner> ipc_runner);
+ static scoped_refptr<CachedStorageArea> CreateForSessionStorage(
+ scoped_refptr<const SecurityOrigin> origin,
+ mojo::AssociatedInterfacePtr<mojom::blink::StorageArea> area,
+ scoped_refptr<base::SingleThreadTaskRunner> ipc_runner);
+
+ // These correspond to blink::Storage.
+ unsigned GetLength();
+ String GetKey(unsigned index);
+ String GetItem(const String& key);
+ bool SetItem(const String& key, const String& value, Source* source);
+ void RemoveItem(const String& key, Source* source);
+ void Clear(Source* source);
+
+ // Allow this object to keep track of the Source instances corresponding to
+ // it, which is needed for mutation event notifications.
+ // Returns the (unique) id allocated for this source for testing purposes.
+ String RegisterSource(Source* source);
+
+ size_t memory_used() const { return map_ ? map_->quota_used() : 0; }
+
+ // Only public to allow tests to parametrize on this type.
+ enum class FormatOption {
+ kLocalStorageDetectFormat,
+ kSessionStorageForceUTF16,
+ kSessionStorageForceUTF8
+ };
+
+ private:
+ CachedStorageArea(scoped_refptr<const SecurityOrigin> origin,
+ mojo::InterfacePtr<mojom::blink::StorageArea> area,
+ scoped_refptr<base::SingleThreadTaskRunner> ipc_runner);
+ CachedStorageArea(
+ scoped_refptr<const SecurityOrigin> origin,
+ mojo::AssociatedInterfacePtr<mojom::blink::StorageArea> area,
+ scoped_refptr<base::SingleThreadTaskRunner> ipc_runner);
+
+ friend class RefCounted<CachedStorageArea>;
+ ~CachedStorageArea() override;
+
+ friend class CachedStorageAreaTest;
+ friend class CachedStorageAreaStringFormatTest;
+
+ // StorageAreaObserver:
+ void KeyAdded(const Vector<uint8_t>& key,
+ const Vector<uint8_t>& value,
+ const String& source) override;
+ void KeyChanged(const Vector<uint8_t>& key,
+ const Vector<uint8_t>& new_value,
+ const Vector<uint8_t>& old_value,
+ const String& source) override;
+ void KeyDeleted(const Vector<uint8_t>& key,
+ const Vector<uint8_t>& old_value,
+ const String& source) override;
+ void AllDeleted(const String& source) override;
+ void ShouldSendOldValueOnMutations(bool value) 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);
+
+ // 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;
+
+ static String Uint8VectorToString(const Vector<uint8_t>& input,
+ FormatOption format_option);
+ static Vector<uint8_t> StringToUint8Vector(const String& input,
+ FormatOption format_option);
+
+ scoped_refptr<const SecurityOrigin> origin_;
+
+ std::unique_ptr<StorageAreaMap> map_;
+
+ HashMap<String, int> ignore_key_mutations_;
+ bool ignore_all_mutations_ = false;
+
+ // 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_ptr_| and |mojo_area_associated_ptr_| will be non-null. Either
+ // way |mojo_area_| will be equal to the non-null one.
+ mojom::blink::StorageArea* mojo_area_;
+ mojo::InterfacePtr<mojom::blink::StorageArea> mojo_area_ptr_;
+ mojo::AssociatedInterfacePtr<mojom::blink::StorageArea>
+ mojo_area_associated_ptr_;
+ mojo::AssociatedBinding<mojom::blink::StorageAreaObserver> binding_;
+
+ PersistentHeapHashMap<WeakMember<Source>, String> areas_;
+
+ base::WeakPtrFactory<CachedStorageArea> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(CachedStorageArea);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_STORAGE_CACHED_STORAGE_AREA_H_
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
new file mode 100644
index 00000000000..e38be688b90
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/storage/cached_storage_area_test.cc
@@ -0,0 +1,574 @@
+// Copyright 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/storage/cached_storage_area.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/platform/scheduler/test/fake_renderer_scheduler.h"
+#include "third_party/blink/renderer/modules/storage/testing/fake_area_source.h"
+#include "third_party/blink/renderer/modules/storage/testing/mock_storage_area.h"
+#include "third_party/blink/renderer/platform/weborigin/kurl.h"
+#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
+
+namespace blink {
+
+using FormatOption = CachedStorageArea::FormatOption;
+
+class CachedStorageAreaTest : public testing::Test {
+ public:
+ const scoped_refptr<SecurityOrigin> kOrigin =
+ SecurityOrigin::CreateFromString("http://dom_storage/");
+ const String kKey = "key";
+ const String kValue = "value";
+ const String kValue2 = "another value";
+ const KURL kPageUrl = KURL("http://dom_storage/page");
+ const KURL kPageUrl2 = KURL("http://dom_storage/other_page");
+ const String kRemoteSourceId = "1234";
+ const String kRemoteSource = kPageUrl2.GetString() + "\n" + kRemoteSourceId;
+
+ void SetUp() override {
+ if (IsSessionStorage()) {
+ cached_area_ = CachedStorageArea::CreateForSessionStorage(
+ kOrigin, mock_storage_area_.GetAssociatedInterfacePtr(),
+ renderer_scheduler_->IPCTaskRunner());
+ } else {
+ cached_area_ = CachedStorageArea::CreateForLocalStorage(
+ kOrigin, mock_storage_area_.GetInterfacePtr(),
+ renderer_scheduler_->IPCTaskRunner());
+ }
+ source_area_ = new FakeAreaSource(kPageUrl);
+ source_area_id_ = cached_area_->RegisterSource(source_area_);
+ source_ = kPageUrl.GetString() + "\n" + source_area_id_;
+ source_area2_ = new FakeAreaSource(kPageUrl2);
+ cached_area_->RegisterSource(source_area2_);
+ }
+
+ 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();
+ }
+
+ static Vector<uint8_t> StringToUint8Vector(const String& input,
+ FormatOption format) {
+ return CachedStorageArea::StringToUint8Vector(input, format);
+ }
+
+ static String Uint8VectorToString(const Vector<uint8_t>& input,
+ FormatOption format) {
+ return CachedStorageArea::Uint8VectorToString(input, format);
+ }
+
+ Vector<uint8_t> KeyToUint8Vector(const String& key) {
+ return StringToUint8Vector(
+ key, IsSessionStorage() ? FormatOption::kSessionStorageForceUTF8
+ : FormatOption::kLocalStorageDetectFormat);
+ }
+
+ Vector<uint8_t> ValueToUint8Vector(const String& value) {
+ return StringToUint8Vector(
+ value, IsSessionStorage() ? FormatOption::kSessionStorageForceUTF16
+ : FormatOption::kLocalStorageDetectFormat);
+ }
+
+ String KeyFromUint8Vector(const Vector<uint8_t>& key) {
+ return Uint8VectorToString(
+ key, IsSessionStorage() ? FormatOption::kSessionStorageForceUTF8
+ : FormatOption::kLocalStorageDetectFormat);
+ }
+
+ String ValueFromUint8Vector(const Vector<uint8_t>& value) {
+ return Uint8VectorToString(
+ value, IsSessionStorage() ? FormatOption::kSessionStorageForceUTF16
+ : FormatOption::kLocalStorageDetectFormat);
+ }
+
+ protected:
+ std::unique_ptr<scheduler::WebThreadScheduler> renderer_scheduler_ =
+ std::make_unique<scheduler::FakeRendererScheduler>();
+ MockStorageArea mock_storage_area_;
+ Persistent<FakeAreaSource> source_area_;
+ Persistent<FakeAreaSource> source_area2_;
+ scoped_refptr<CachedStorageArea> cached_area_;
+ String source_area_id_;
+ String source_;
+};
+
+class CachedStorageAreaTestWithParam
+ : public CachedStorageAreaTest,
+ public testing::WithParamInterface<bool> {
+ public:
+ bool IsSessionStorage() override { return GetParam(); }
+};
+
+INSTANTIATE_TEST_CASE_P(CachedStorageAreaTest,
+ CachedStorageAreaTestWithParam,
+ ::testing::Bool());
+
+TEST_P(CachedStorageAreaTestWithParam, Basics) {
+ EXPECT_FALSE(IsCacheLoaded());
+
+ EXPECT_EQ(0u, cached_area_->GetLength());
+ EXPECT_TRUE(cached_area_->SetItem(kKey, kValue, source_area_));
+ EXPECT_EQ(1u, cached_area_->GetLength());
+ EXPECT_EQ(kKey, cached_area_->GetKey(0));
+ EXPECT_EQ(kValue, cached_area_->GetItem(kKey));
+ cached_area_->RemoveItem(kKey, source_area_);
+ EXPECT_EQ(0u, cached_area_->GetLength());
+
+ mock_storage_area_.Flush();
+ EXPECT_EQ(1u, mock_storage_area_.observer_count());
+}
+
+TEST_P(CachedStorageAreaTestWithParam, GetLength) {
+ // GetLength, we expect to see one call to load in the db.
+ 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());
+}
+
+TEST_P(CachedStorageAreaTestWithParam, GetKey) {
+ // GetKey, expect the one call to load.
+ 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());
+}
+
+TEST_P(CachedStorageAreaTestWithParam, GetItem) {
+ // GetItem, ditto.
+ 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());
+}
+
+TEST_P(CachedStorageAreaTestWithParam, SetItem) {
+ // SetItem, we expect a call to load followed by a call to put in the db.
+ 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_TRUE(source_area_->events.IsEmpty());
+ if (IsSessionStorage()) {
+ ASSERT_EQ(1u, source_area2_->events.size());
+ EXPECT_EQ(kKey, source_area2_->events[0].key);
+ EXPECT_TRUE(source_area2_->events[0].old_value.IsNull());
+ EXPECT_EQ(kValue, source_area2_->events[0].new_value);
+ EXPECT_EQ(kPageUrl, source_area2_->events[0].url);
+ } else {
+ EXPECT_TRUE(source_area2_->events.IsEmpty());
+ }
+}
+
+TEST_P(CachedStorageAreaTestWithParam, Clear_AlreadyEmpty) {
+ // Clear, we expect just the one call to clear in the db since
+ // there's no need to load the data prior to deleting it.
+ // Except if we're testing session storage, in which case we also expect a
+ // load call first, since it needs that for event dispatching.
+ 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());
+ if (IsSessionStorage()) {
+ EXPECT_TRUE(mock_storage_area_.observed_get_all());
+ EXPECT_EQ(2u, mock_storage_area_.pending_callbacks_count());
+ } else {
+ EXPECT_FALSE(mock_storage_area_.observed_get_all());
+ EXPECT_EQ(1u, mock_storage_area_.pending_callbacks_count());
+ }
+
+ // Neither should have events since area was already empty.
+ EXPECT_TRUE(source_area_->events.IsEmpty());
+ EXPECT_TRUE(source_area2_->events.IsEmpty());
+}
+
+TEST_P(CachedStorageAreaTestWithParam, Clear_WithData) {
+ mock_storage_area_.mutable_get_all_return_values().push_back(
+ mojom::blink::KeyValue::New(KeyToUint8Vector(kKey),
+ ValueToUint8Vector(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());
+ if (IsSessionStorage()) {
+ EXPECT_TRUE(mock_storage_area_.observed_get_all());
+ EXPECT_EQ(2u, mock_storage_area_.pending_callbacks_count());
+ } else {
+ EXPECT_FALSE(mock_storage_area_.observed_get_all());
+ EXPECT_EQ(1u, mock_storage_area_.pending_callbacks_count());
+ }
+
+ EXPECT_TRUE(source_area_->events.IsEmpty());
+ if (IsSessionStorage()) {
+ ASSERT_EQ(1u, source_area2_->events.size());
+ EXPECT_TRUE(source_area2_->events[0].key.IsNull());
+ EXPECT_TRUE(source_area2_->events[0].old_value.IsNull());
+ EXPECT_TRUE(source_area2_->events[0].new_value.IsNull());
+ EXPECT_EQ(kPageUrl, source_area2_->events[0].url);
+ } else {
+ EXPECT_TRUE(source_area2_->events.IsEmpty());
+ }
+}
+
+TEST_P(CachedStorageAreaTestWithParam, RemoveItem_NothingToRemove) {
+ // RemoveItem with nothing to remove, expect just one call to load.
+ 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_FALSE(mock_storage_area_.observed_delete());
+ EXPECT_EQ(1u, mock_storage_area_.pending_callbacks_count());
+
+ // Neither should have events since area was already empty.
+ EXPECT_TRUE(source_area_->events.IsEmpty());
+ EXPECT_TRUE(source_area2_->events.IsEmpty());
+}
+
+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)));
+ 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_TRUE(source_area_->events.IsEmpty());
+ if (IsSessionStorage()) {
+ ASSERT_EQ(1u, source_area2_->events.size());
+ EXPECT_EQ(kKey, source_area2_->events[0].key);
+ EXPECT_EQ(kValue, source_area2_->events[0].old_value);
+ EXPECT_TRUE(source_area2_->events[0].new_value.IsNull());
+ EXPECT_EQ(kPageUrl, source_area2_->events[0].url);
+ } else {
+ EXPECT_TRUE(source_area2_->events.IsEmpty());
+ }
+}
+
+TEST_P(CachedStorageAreaTestWithParam, BrowserDisconnect) {
+ // 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
+ // browser might be forced to destroy the LevelDBWrapperImpl.
+ mock_storage_area_.CloseAllBindings();
+
+ // Getters should still function.
+ EXPECT_EQ(1u, cached_area_->GetLength());
+ EXPECT_EQ(kValue, cached_area_->GetItem(kKey));
+
+ // And setters should also still function.
+ 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();
+
+ EXPECT_TRUE(cached_area_->GetItem(kKey).IsNull());
+ EXPECT_TRUE(IsCacheLoaded());
+ EXPECT_TRUE(IsIgnoringAllMutations());
+
+ // Before load completion, the mutation should be ignored.
+ observer->KeyAdded(KeyToUint8Vector(kKey), ValueToUint8Vector(kValue),
+ kRemoteSource);
+ EXPECT_TRUE(cached_area_->GetItem(kKey).IsNull());
+
+ // Call the load completion callback.
+ mock_storage_area_.CompleteOnePendingCallback(true);
+ mock_storage_area_.Flush();
+ EXPECT_FALSE(IsIgnoringAllMutations());
+
+ // Verify that mutations are now applied.
+ observer->KeyAdded(KeyToUint8Vector(kKey), ValueToUint8Vector(kValue),
+ kRemoteSource);
+ EXPECT_EQ(kValue, cached_area_->GetItem(kKey));
+}
+
+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());
+
+ // Verify that calling Clear twice works as expected, the first
+ // completion callback should have been cancelled.
+ ResetCache();
+ cached_area_->Clear(source_area_);
+ mock_storage_area_.Flush();
+ EXPECT_TRUE(IsIgnoringAllMutations());
+ cached_area_->Clear(source_area_);
+ mock_storage_area_.Flush();
+ EXPECT_TRUE(IsIgnoringAllMutations());
+ mock_storage_area_.CompleteOnePendingCallback(true);
+ mock_storage_area_.Flush();
+ EXPECT_TRUE(IsIgnoringAllMutations());
+ mock_storage_area_.CompleteOnePendingCallback(true);
+ mock_storage_area_.Flush();
+ EXPECT_FALSE(IsIgnoringAllMutations());
+}
+
+TEST_F(CachedStorageAreaTest, KeyMutationsAreIgnoredUntilCompletion) {
+ mojom::blink::StorageAreaObserver* observer = cached_area_.get();
+
+ // 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();
+ EXPECT_EQ(kValue, cached_area_->GetItem(kKey));
+ mock_storage_area_.CompleteOnePendingCallback(true); // set completion
+ mock_storage_area_.Flush();
+ 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();
+ 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();
+ EXPECT_FALSE(IsIgnoringKeyMutations(kKey));
+
+ // A failed set item operation should Reset the cache.
+ 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());
+}
+
+TEST_F(CachedStorageAreaTest, ChangeEvents) {
+ mojom::blink::StorageAreaObserver* observer = cached_area_.get();
+
+ observer->KeyAdded(KeyToUint8Vector(kKey), ValueToUint8Vector(kValue),
+ 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);
+
+ // Source area should have ignored all but the last two events.
+ ASSERT_EQ(2u, source_area_->events.size());
+
+ EXPECT_EQ(kKey, source_area_->events[0].key);
+ EXPECT_TRUE(source_area_->events[0].old_value.IsNull());
+ EXPECT_EQ(kValue, source_area_->events[0].new_value);
+ EXPECT_EQ(kPageUrl2, source_area_->events[0].url);
+
+ EXPECT_TRUE(source_area_->events[1].key.IsNull());
+ EXPECT_TRUE(source_area_->events[1].old_value.IsNull());
+ EXPECT_TRUE(source_area_->events[1].new_value.IsNull());
+ EXPECT_EQ(kPageUrl2, source_area_->events[1].url);
+
+ // Second area should not have ignored any of the events.
+ ASSERT_EQ(5u, source_area2_->events.size());
+
+ EXPECT_EQ(kKey, source_area2_->events[0].key);
+ EXPECT_TRUE(source_area2_->events[0].old_value.IsNull());
+ EXPECT_EQ(kValue, source_area2_->events[0].new_value);
+ EXPECT_EQ(kPageUrl, source_area2_->events[0].url);
+
+ EXPECT_EQ(kKey, source_area2_->events[1].key);
+ EXPECT_EQ(kValue, source_area2_->events[1].old_value);
+ EXPECT_EQ(kValue2, source_area2_->events[1].new_value);
+ EXPECT_EQ(kPageUrl, source_area2_->events[1].url);
+
+ EXPECT_EQ(kKey, source_area2_->events[2].key);
+ EXPECT_EQ(kValue2, source_area2_->events[2].old_value);
+ EXPECT_TRUE(source_area2_->events[2].new_value.IsNull());
+ EXPECT_EQ(kPageUrl, source_area2_->events[2].url);
+
+ EXPECT_EQ(kKey, source_area2_->events[3].key);
+ EXPECT_TRUE(source_area2_->events[3].old_value.IsNull());
+ EXPECT_EQ(kValue, source_area2_->events[3].new_value);
+ EXPECT_EQ(kPageUrl2, source_area2_->events[3].url);
+
+ EXPECT_TRUE(source_area2_->events[4].key.IsNull());
+ EXPECT_TRUE(source_area2_->events[4].old_value.IsNull());
+ EXPECT_TRUE(source_area2_->events[4].new_value.IsNull());
+ EXPECT_EQ(kPageUrl2, source_area2_->events[4].url);
+}
+
+namespace {
+
+class StringEncoding : public CachedStorageAreaTest,
+ public testing::WithParamInterface<FormatOption> {};
+
+INSTANTIATE_TEST_CASE_P(
+ CachedStorageAreaTest,
+ StringEncoding,
+ ::testing::Values(FormatOption::kLocalStorageDetectFormat,
+ FormatOption::kSessionStorageForceUTF16,
+ FormatOption::kSessionStorageForceUTF8));
+
+TEST_P(StringEncoding, RoundTrip_ASCII) {
+ String key("simplekey");
+ EXPECT_EQ(
+ Uint8VectorToString(StringToUint8Vector(key, GetParam()), GetParam()),
+ key);
+}
+
+TEST_P(StringEncoding, RoundTrip_Latin1) {
+ String key("Test\xf6\xb5");
+ EXPECT_TRUE(key.Is8Bit());
+ EXPECT_EQ(
+ Uint8VectorToString(StringToUint8Vector(key, GetParam()), GetParam()),
+ key);
+}
+
+TEST_P(StringEncoding, RoundTrip_UTF16) {
+ String key("key");
+ key.append(UChar(0xd83d));
+ key.append(UChar(0xde00));
+ EXPECT_EQ(
+ Uint8VectorToString(StringToUint8Vector(key, GetParam()), GetParam()),
+ key);
+}
+
+TEST_P(StringEncoding, RoundTrip_InvalidUTF16) {
+ String key("foo");
+ key.append(UChar(0xd83d));
+ key.append(UChar(0xde00));
+ key.append(UChar(0xdf01));
+ key.append("bar");
+ if (GetParam() != FormatOption::kSessionStorageForceUTF8) {
+ EXPECT_EQ(
+ Uint8VectorToString(StringToUint8Vector(key, GetParam()), GetParam()),
+ key);
+ } else {
+ String validKey("foo");
+ validKey.append(UChar(0xd83d));
+ validKey.append(UChar(0xde00));
+ validKey.append(UChar(0xfffd));
+ validKey.append("bar");
+ EXPECT_EQ(
+ Uint8VectorToString(StringToUint8Vector(key, GetParam()), GetParam()),
+ validKey);
+ }
+}
+
+} // namespace
+
+TEST_F(CachedStorageAreaTest, StringEncoding_LocalStorage) {
+ String ascii_key("simplekey");
+ String non_ascii_key("key");
+ non_ascii_key.append(UChar(0xd83d));
+ non_ascii_key.append(UChar(0xde00));
+ EXPECT_EQ(
+ StringToUint8Vector(ascii_key, FormatOption::kLocalStorageDetectFormat)
+ .size(),
+ ascii_key.length() + 1);
+ EXPECT_EQ(StringToUint8Vector(non_ascii_key,
+ FormatOption::kLocalStorageDetectFormat)
+ .size(),
+ non_ascii_key.length() * 2 + 1);
+}
+
+TEST_F(CachedStorageAreaTest, StringEncoding_UTF8) {
+ String ascii_key("simplekey");
+ String non_ascii_key("key");
+ non_ascii_key.append(UChar(0xd83d));
+ non_ascii_key.append(UChar(0xde00));
+ EXPECT_EQ(
+ StringToUint8Vector(ascii_key, FormatOption::kSessionStorageForceUTF8)
+ .size(),
+ ascii_key.length());
+ EXPECT_EQ(
+ StringToUint8Vector(non_ascii_key, FormatOption::kSessionStorageForceUTF8)
+ .size(),
+ 7u);
+}
+
+TEST_F(CachedStorageAreaTest, StringEncoding_UTF16) {
+ String ascii_key("simplekey");
+ String non_ascii_key("key");
+ non_ascii_key.append(UChar(0xd83d));
+ non_ascii_key.append(UChar(0xde00));
+ EXPECT_EQ(
+ StringToUint8Vector(ascii_key, FormatOption::kSessionStorageForceUTF16)
+ .size(),
+ ascii_key.length() * 2);
+ EXPECT_EQ(StringToUint8Vector(non_ascii_key,
+ FormatOption::kSessionStorageForceUTF16)
+ .size(),
+ non_ascii_key.length() * 2);
+}
+
+} // namespace blink
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 a3b49bc4f2f..0f48ab2f9dd 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
@@ -42,13 +42,8 @@
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
namespace blink {
-
using protocol::Response;
-namespace DOMStorageAgentState {
-static const char kDomStorageAgentEnabled[] = "domStorageAgentEnabled";
-};
-
static Response ToResponse(ExceptionState& exception_state) {
if (!exception_state.HadException())
return Response::OK();
@@ -63,7 +58,8 @@ static Response ToResponse(ExceptionState& exception_state) {
InspectorDOMStorageAgent::InspectorDOMStorageAgent(
InspectedFrames* inspected_frames)
- : inspected_frames_(inspected_frames), is_enabled_(false) {}
+ : inspected_frames_(inspected_frames),
+ enabled_(&agent_state_, /*default_value=*/false) {}
InspectorDOMStorageAgent::~InspectorDOMStorageAgent() = default;
@@ -73,28 +69,28 @@ void InspectorDOMStorageAgent::Trace(blink::Visitor* visitor) {
}
void InspectorDOMStorageAgent::Restore() {
- if (state_->booleanProperty(DOMStorageAgentState::kDomStorageAgentEnabled,
- false)) {
- enable();
- }
+ if (enabled_.Get())
+ InnerEnable();
}
-Response InspectorDOMStorageAgent::enable() {
- if (is_enabled_)
- return Response::OK();
- is_enabled_ = true;
- state_->setBoolean(DOMStorageAgentState::kDomStorageAgentEnabled, true);
+void InspectorDOMStorageAgent::InnerEnable() {
if (StorageNamespaceController* controller = StorageNamespaceController::From(
inspected_frames_->Root()->GetPage()))
controller->SetInspectorAgent(this);
+}
+
+Response InspectorDOMStorageAgent::enable() {
+ if (enabled_.Get())
+ return Response::OK();
+ enabled_.Set(true);
+ InnerEnable();
return Response::OK();
}
Response InspectorDOMStorageAgent::disable() {
- if (!is_enabled_)
+ if (!enabled_.Get())
return Response::OK();
- is_enabled_ = false;
- state_->setBoolean(DOMStorageAgentState::kDomStorageAgentEnabled, false);
+ enabled_.Set(false);
if (StorageNamespaceController* controller = StorageNamespaceController::From(
inspected_frames_->Root()->GetPage()))
controller->SetInspectorAgent(nullptr);
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 adc23d1b128..f2d68b67f31 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
@@ -54,6 +54,7 @@ class MODULES_EXPORT InspectorDOMStorageAgent final
const SecurityOrigin*);
private:
+ void InnerEnable();
// InspectorBaseAgent overrides.
void Restore() override;
@@ -84,7 +85,7 @@ class MODULES_EXPORT InspectorDOMStorageAgent final
bool is_local_storage);
Member<InspectedFrames> inspected_frames_;
- bool is_enabled_;
+ InspectorAgentState::Boolean enabled_;
};
} // namespace blink
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 36f73d3a52d..15d31039c25 100644
--- a/chromium/third_party/blink/renderer/modules/storage/storage_area.cc
+++ b/chromium/third_party/blink/renderer/modules/storage/storage_area.cc
@@ -224,8 +224,8 @@ void StorageArea::DispatchLocalStorageEvent(
!IsEventSource(storage, source_area_instance)) {
// https://www.w3.org/TR/webstorage/#the-storage-event
local_frame->DomWindow()->EnqueueWindowEvent(
- StorageEvent::Create(EventTypeNames::storage, key, old_value,
- new_value, page_url, storage),
+ *StorageEvent::Create(EventTypeNames::storage, key, old_value,
+ new_value, page_url, storage),
TaskType::kDOMManipulation);
}
}
@@ -265,8 +265,8 @@ void StorageArea::DispatchSessionStorageEvent(
!IsEventSource(storage, source_area_instance)) {
// https://www.w3.org/TR/webstorage/#the-storage-event
local_frame->DomWindow()->EnqueueWindowEvent(
- StorageEvent::Create(EventTypeNames::storage, key, old_value,
- new_value, page_url, storage),
+ *StorageEvent::Create(EventTypeNames::storage, key, old_value,
+ new_value, page_url, storage),
TaskType::kDOMManipulation);
}
}
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
new file mode 100644
index 00000000000..92e1cf497e4
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/storage/testing/fake_area_source.h
@@ -0,0 +1,47 @@
+// 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_STORAGE_TESTING_FAKE_AREA_SOURCE_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_STORAGE_TESTING_FAKE_AREA_SOURCE_H_
+
+#include "third_party/blink/public/platform/web_scoped_virtual_time_pauser.h"
+#include "third_party/blink/renderer/modules/storage/cached_storage_area.h"
+#include "third_party/blink/renderer/platform/weborigin/kurl.h"
+
+namespace blink {
+
+class FakeAreaSource : public GarbageCollectedFinalized<FakeAreaSource>,
+ public CachedStorageArea::Source {
+ USING_GARBAGE_COLLECTED_MIXIN(FakeAreaSource);
+
+ public:
+ explicit FakeAreaSource(const KURL& page_url) : page_url_(page_url) {}
+
+ KURL GetPageUrl() const override { return page_url_; }
+ void EnqueueStorageEvent(const String& key,
+ const String& old_value,
+ const String& new_value,
+ const String& url) override {
+ events.push_back(Event{key, old_value, new_value, url});
+ }
+
+ blink::WebScopedVirtualTimePauser CreateWebScopedVirtualTimePauser(
+ const char* name,
+ WebScopedVirtualTimePauser::VirtualTaskDuration duration) override {
+ return blink::WebScopedVirtualTimePauser();
+ }
+
+ struct Event {
+ String key, old_value, new_value, url;
+ };
+
+ Vector<Event> events;
+
+ private:
+ KURL page_url_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_STORAGE_TESTING_FAKE_AREA_SOURCE_H_
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
new file mode 100644
index 00000000000..0586747ebf0
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/storage/testing/mock_storage_area.cc
@@ -0,0 +1,81 @@
+// 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/storage/testing/mock_storage_area.h"
+
+#include "third_party/blink/renderer/platform/wtf/functional.h"
+
+namespace blink {
+
+MockStorageArea::MockStorageArea() = default;
+MockStorageArea::~MockStorageArea() = default;
+
+mojom::blink::StorageAreaPtr MockStorageArea::GetInterfacePtr() {
+ mojom::blink::StorageAreaPtr result;
+ bindings_.AddBinding(this, MakeRequest(&result));
+ return result;
+}
+
+mojom::blink::StorageAreaAssociatedPtr
+MockStorageArea::GetAssociatedInterfacePtr() {
+ mojom::blink::StorageAreaAssociatedPtr result;
+ associated_bindings_.AddBinding(
+ this, MakeRequestAssociatedWithDedicatedPipe(&result));
+ return result;
+}
+
+void MockStorageArea::AddObserver(
+ mojom::blink::StorageAreaObserverAssociatedPtrInfo observer) {
+ ++observer_count_;
+}
+
+void MockStorageArea::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) {
+ observed_put_ = true;
+ observed_key_ = key;
+ observed_value_ = value;
+ observed_source_ = source;
+ pending_callbacks_.push_back(std::move(callback));
+}
+
+void MockStorageArea::Delete(
+ const Vector<uint8_t>& key,
+ 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));
+}
+
+void MockStorageArea::DeleteAll(const String& source,
+ DeleteAllCallback callback) {
+ observed_delete_all_ = true;
+ observed_source_ = source;
+ pending_callbacks_.push_back(std::move(callback));
+}
+
+void MockStorageArea::Get(const Vector<uint8_t>& key, GetCallback callback) {
+ NOTREACHED();
+}
+
+void MockStorageArea::GetAll(
+ mojom::blink::StorageAreaGetAllCallbackAssociatedPtrInfo complete_callback,
+ GetAllCallback callback) {
+ mojom::blink::StorageAreaGetAllCallbackAssociatedPtr complete_ptr;
+ complete_ptr.Bind(std::move(complete_callback));
+ pending_callbacks_.push_back(
+ WTF::Bind(&mojom::blink::StorageAreaGetAllCallback::Complete,
+ std::move(complete_ptr)));
+
+ observed_get_all_ = true;
+ std::move(callback).Run(true, std::move(get_all_return_values_));
+}
+
+} // 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
new file mode 100644
index 00000000000..099b55f283e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/storage/testing/mock_storage_area.h
@@ -0,0 +1,120 @@
+// 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_STORAGE_TESTING_MOCK_STORAGE_AREA_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_STORAGE_TESTING_MOCK_STORAGE_AREA_H_
+
+#include "mojo/public/cpp/bindings/associated_binding_set.h"
+#include "mojo/public/cpp/bindings/binding_set.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/mojom/dom_storage/storage_area.mojom-blink.h"
+#include "third_party/blink/renderer/platform/wtf/deque.h"
+
+namespace blink {
+
+// Mock StorageArea that records all read and write events.
+class MockStorageArea : public mojom::blink::StorageArea {
+ public:
+ using ResultCallback = base::OnceCallback<void(bool)>;
+
+ MockStorageArea();
+ ~MockStorageArea() override;
+
+ mojom::blink::StorageAreaPtr GetInterfacePtr();
+ mojom::blink::StorageAreaAssociatedPtr GetAssociatedInterfacePtr();
+
+ // StorageArea implementation:
+ void AddObserver(
+ mojom::blink::StorageAreaObserverAssociatedPtrInfo 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 Get(const Vector<uint8_t>& key, GetCallback callback) override;
+
+ void GetAll(mojom::blink::StorageAreaGetAllCallbackAssociatedPtrInfo
+ complete_callback,
+ GetAllCallback callback) override;
+
+ // Methods and members for use by test fixtures.
+ bool HasBindings() {
+ return !bindings_.empty() || !associated_bindings_.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();
+ }
+
+ void Flush() {
+ bindings_.FlushForTesting();
+ associated_bindings_.FlushForTesting();
+ }
+
+ void CloseAllBindings() {
+ bindings_.CloseAllBindings();
+ associated_bindings_.CloseAllBindings();
+ }
+
+ 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_;
+ }
+
+ 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_;
+ size_t observer_count_ = 0;
+
+ Vector<mojom::blink::KeyValuePtr> get_all_return_values_;
+
+ mojo::BindingSet<mojom::blink::StorageArea> bindings_;
+ mojo::AssociatedBindingSet<mojom::blink::StorageArea> associated_bindings_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_STORAGE_TESTING_MOCK_STORAGE_AREA_H_
diff --git a/chromium/third_party/blink/renderer/modules/vr/navigator_vr.cc b/chromium/third_party/blink/renderer/modules/vr/navigator_vr.cc
index 815847206ee..ad15980a428 100644
--- a/chromium/third_party/blink/renderer/modules/vr/navigator_vr.cc
+++ b/chromium/third_party/blink/renderer/modules/vr/navigator_vr.cc
@@ -229,7 +229,7 @@ void NavigatorVR::EnqueueVREvent(VRDisplayEvent* event) {
return;
GetSupplementable()->GetFrame()->DomWindow()->EnqueueWindowEvent(
- event, TaskType::kMiscPlatformAPI);
+ *event, TaskType::kMiscPlatformAPI);
}
void NavigatorVR::DispatchVREvent(VRDisplayEvent* event) {
@@ -239,7 +239,7 @@ void NavigatorVR::DispatchVREvent(VRDisplayEvent* event) {
LocalDOMWindow* window = GetSupplementable()->GetFrame()->DomWindow();
DCHECK(window);
event->SetTarget(window);
- window->DispatchEvent(event);
+ window->DispatchEvent(*event);
}
void NavigatorVR::FocusedFrameChanged() {
diff --git a/chromium/third_party/blink/renderer/modules/vr/navigator_vr.h b/chromium/third_party/blink/renderer/modules/vr/navigator_vr.h
index 9a6da1bd02f..9841513c48c 100644
--- a/chromium/third_party/blink/renderer/modules/vr/navigator_vr.h
+++ b/chromium/third_party/blink/renderer/modules/vr/navigator_vr.h
@@ -39,8 +39,8 @@ class MODULES_EXPORT NavigatorVR final
~NavigatorVR() override;
// XR API
- // TODO(offenwanger) Should eventually move this out into it's own separate
- // Navigator supplement.
+ // TODO(http://crbug.com/842025) Should eventually move this out into it's own
+ // separate Navigator supplement.
static XR* xr(Navigator&);
XR* xr();
diff --git a/chromium/third_party/blink/renderer/modules/vr/navigator_vr.idl b/chromium/third_party/blink/renderer/modules/vr/navigator_vr.idl
index 133163db0df..7e7fc582542 100644
--- a/chromium/third_party/blink/renderer/modules/vr/navigator_vr.idl
+++ b/chromium/third_party/blink/renderer/modules/vr/navigator_vr.idl
@@ -10,5 +10,5 @@
[SecureContext, OriginTrialEnabled=WebXR, MeasureAs=NavigatorXR] readonly attribute XR xr;
// Legacy API
- [RuntimeEnabled=WebVR, CallWith=ScriptState] Promise getVRDisplays();
+ [OriginTrialEnabled=WebVR, CallWith=ScriptState] Promise getVRDisplays();
};
diff --git a/chromium/third_party/blink/renderer/modules/vr/vr_controller.cc b/chromium/third_party/blink/renderer/modules/vr/vr_controller.cc
index 6805adadfc9..c726001ee72 100644
--- a/chromium/third_party/blink/renderer/modules/vr/vr_controller.cc
+++ b/chromium/third_party/blink/renderer/modules/vr/vr_controller.cc
@@ -28,9 +28,10 @@ VRController::VRController(NavigatorVR* navigator_vr)
device::mojom::blink::VRServiceClientPtr client;
binding_.Bind(mojo::MakeRequest(&client));
- service_->SetClient(
- std::move(client),
- WTF::Bind(&VRController::OnDisplaysSynced, WrapPersistent(this)));
+ service_->SetClient(std::move(client));
+
+ service_->RequestDevice(
+ WTF::Bind(&VRController::OnRequestDeviceReturned, WrapPersistent(this)));
}
VRController::~VRController() = default;
@@ -41,7 +42,10 @@ void VRController::GetDisplays(ScriptPromiseResolver* resolver) {
// disconnected this will be an empty array.
if (!service_ || display_synced_) {
LogGetDisplayResult();
- resolver->Resolve(displays_);
+ HeapVector<Member<VRDisplay>> displays;
+ if (display_)
+ displays.push_back(display_);
+ resolver->Resolve(displays);
return;
}
@@ -52,37 +56,94 @@ void VRController::GetDisplays(ScriptPromiseResolver* resolver) {
}
void VRController::SetListeningForActivate(bool listening) {
- if (service_)
- service_->SetListeningForActivate(listening);
+ if (!service_ || !display_) {
+ pending_listening_for_activate_ = listening;
+ return;
+ }
+
+ if (listening_for_activate_ && listening) {
+ // We're already listening so leave things as is.
+ return;
+ }
+
+ listening_for_activate_ = listening;
+
+ if (listening) {
+ service_->SetListeningForActivate(display_->GetDisplayClient());
+ } else {
+ service_->SetListeningForActivate(nullptr);
+ }
+}
+
+// Called when the XRDevice has been initialized.
+void VRController::OnRequestDeviceReturned(
+ device::mojom::blink::XRDevicePtr device) {
+ if (!device) {
+ // There are no devices connected to the system. We can't do any VR, at all.
+ OnGetDisplays();
+ return;
+ }
+
+ device->GetImmersiveVRDisplayInfo(WTF::Bind(
+ &VRController::OnImmersiveDisplayInfoReturned, WrapPersistent(this)));
+
+ display_ = new VRDisplay(navigator_vr_, std::move(device));
+
+ if (pending_listening_for_activate_) {
+ SetListeningForActivate(pending_listening_for_activate_);
+ pending_listening_for_activate_ = false;
+ }
}
-// Each time a new VRDisplay is connected we'll receive a VRDisplayPtr for it
-// here. Upon calling SetClient in the constructor we should receive one call
-// for each VRDisplay that was already connected at the time.
-void VRController::OnDisplayConnected(
- device::mojom::blink::VRDisplayHostPtr display,
- device::mojom::blink::VRDisplayClientRequest request,
- device::mojom::blink::VRDisplayInfoPtr display_info) {
- VRDisplay* vr_display =
- new VRDisplay(navigator_vr_, std::move(display), std::move(request));
- vr_display->Update(display_info);
- vr_display->OnConnected();
- vr_display->FocusChanged();
-
- has_presentation_capable_display_ = display_info->capabilities->canPresent;
- has_display_ = true;
-
- displays_.push_back(vr_display);
+void VRController::OnNewDeviceReturned(
+ device::mojom::blink::XRDevicePtr device) {
+ if (device) {
+ display_->OnConnected();
+ }
+ OnRequestDeviceReturned(std::move(device));
+}
+
+void VRController::OnDeviceChanged() {
+ if (!display_ && !display_synced_) {
+ // We're already underway checking if there is a device.
+ return;
+ }
+
+ display_synced_ = false;
+
+ if (!display_) {
+ service_->RequestDevice(
+ WTF::Bind(&VRController::OnNewDeviceReturned, WrapPersistent(this)));
+ } else if (!display_->canPresent()) {
+ // If we can't present, see if that's changed.
+ display_->device()->GetImmersiveVRDisplayInfo(WTF::Bind(
+ &VRController::OnImmersiveDisplayInfoReturned, WrapPersistent(this)));
+ } else {
+ display_synced_ = true;
+ }
}
void VRController::FocusChanged() {
- for (const auto& display : displays_)
- display->FocusChanged();
+ if (display_)
+ display_->FocusChanged();
}
-// Called when the VRService has called OnDisplayConnected for all active
-// VRDisplays.
-void VRController::OnDisplaysSynced() {
+void VRController::OnImmersiveDisplayInfoReturned(
+ device::mojom::blink::VRDisplayInfoPtr info) {
+ if (!display_) {
+ // We must have been disposed and are shutting down.
+ return;
+ }
+
+ has_presentation_capable_display_ = info ? true : false;
+
+ if (info) {
+ display_->OnChanged(std::move(info), true /* is_immersive */);
+ display_->OnConnected();
+ has_display_ = true;
+ }
+ display_->FocusChanged();
+
display_synced_ = true;
OnGetDisplays();
}
@@ -102,9 +163,14 @@ void VRController::LogGetDisplayResult() {
void VRController::OnGetDisplays() {
while (!pending_get_devices_callbacks_.IsEmpty()) {
LogGetDisplayResult();
+
+ HeapVector<Member<VRDisplay>> displays;
+ if (display_)
+ displays.push_back(display_);
+
std::unique_ptr<VRGetDevicesCallback> callback =
pending_get_devices_callbacks_.TakeFirst();
- callback->OnSuccess(displays_);
+ callback->OnSuccess(displays);
}
}
@@ -119,10 +185,10 @@ void VRController::Dispose() {
binding_.Close();
// Shutdown all displays' message pipe
- for (const auto& display : displays_)
- display->Dispose();
-
- displays_.clear();
+ if (display_) {
+ display_->Dispose();
+ display_ = nullptr;
+ }
// Ensure that any outstanding getDisplays promises are resolved.
OnGetDisplays();
@@ -130,7 +196,7 @@ void VRController::Dispose() {
void VRController::Trace(blink::Visitor* visitor) {
visitor->Trace(navigator_vr_);
- visitor->Trace(displays_);
+ visitor->Trace(display_);
ContextLifecycleObserver::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/vr/vr_controller.h b/chromium/third_party/blink/renderer/modules/vr/vr_controller.h
index b91a0e55d14..d49ab9cdbef 100644
--- a/chromium/third_party/blink/renderer/modules/vr/vr_controller.h
+++ b/chromium/third_party/blink/renderer/modules/vr/vr_controller.h
@@ -34,9 +34,8 @@ class VRController final : public GarbageCollectedFinalized<VRController>,
void GetDisplays(ScriptPromiseResolver*);
void SetListeningForActivate(bool);
- void OnDisplayConnected(device::mojom::blink::VRDisplayHostPtr,
- device::mojom::blink::VRDisplayClientRequest,
- device::mojom::blink::VRDisplayInfoPtr) override;
+ // VRServiceClient override.
+ void OnDeviceChanged() override;
void FocusChanged();
@@ -46,6 +45,14 @@ class VRController final : public GarbageCollectedFinalized<VRController>,
void OnDisplaysSynced();
void OnGetDisplays();
+ // Initial callback for requesting the device when VR boots up.
+ void OnRequestDeviceReturned(device::mojom::blink::XRDevicePtr);
+ // Callback for subsequent request device calls.
+ void OnNewDeviceReturned(device::mojom::blink::XRDevicePtr);
+
+ void OnImmersiveDisplayInfoReturned(
+ device::mojom::blink::VRDisplayInfoPtr info);
+
// ContextLifecycleObserver.
void ContextDestroyed(ExecutionContext*) override;
void Dispose();
@@ -53,12 +60,14 @@ class VRController final : public GarbageCollectedFinalized<VRController>,
void LogGetDisplayResult();
Member<NavigatorVR> navigator_vr_;
- VRDisplayVector displays_;
+ Member<VRDisplay> display_;
bool display_synced_;
bool has_presentation_capable_display_ = false;
bool has_display_ = false;
+ bool pending_listening_for_activate_ = false;
+ bool listening_for_activate_ = false;
Deque<std::unique_ptr<VRGetDevicesCallback>> pending_get_devices_callbacks_;
device::mojom::blink::VRServicePtr service_;
diff --git a/chromium/third_party/blink/renderer/modules/vr/vr_display.cc b/chromium/third_party/blink/renderer/modules/vr/vr_display.cc
index a221211fdad..3a73e9a0f16 100644
--- a/chromium/third_party/blink/renderer/modules/vr/vr_display.cc
+++ b/chromium/third_party/blink/renderer/modules/vr/vr_display.cc
@@ -44,10 +44,10 @@ namespace blink {
namespace {
-// Threshold for rejecting stored magic window poses as being too old.
-// If it's exceeded, defer magic window rAF callback execution until
+// Threshold for rejecting stored non-immersive poses as being too old.
+// If it's exceeded, defer non-immersive rAF callback execution until
// a fresh pose is received.
-constexpr WTF::TimeDelta kMagicWindowPoseAgeThreshold =
+constexpr WTF::TimeDelta kNonImmersivePoseAgeThreshold =
WTF::TimeDelta::FromMilliseconds(250);
VREye StringToVREye(const String& which_eye) {
@@ -65,7 +65,7 @@ class VRDisplayFrameRequestCallback
: vr_display_(vr_display) {}
~VRDisplayFrameRequestCallback() override = default;
void Invoke(double high_res_time_ms) override {
- if (Id() != vr_display_->PendingMagicWindowVSyncId())
+ if (Id() != vr_display_->PendingNonImmersiveVSyncId())
return;
TimeTicks monotonic_time;
if (!vr_display_->GetDocument() || !vr_display_->GetDocument()->Loader()) {
@@ -79,7 +79,7 @@ class VRDisplayFrameRequestCallback
monotonic_time = reference_monotonic_time +
TimeDelta::FromMillisecondsD(high_res_time_ms);
}
- vr_display_->OnMagicWindowVSync(monotonic_time);
+ vr_display_->OnNonImmersiveVSync(monotonic_time);
}
void Trace(blink::Visitor* visitor) override {
@@ -93,27 +93,59 @@ class VRDisplayFrameRequestCallback
} // namespace
-VRDisplay::VRDisplay(
- NavigatorVR* navigator_vr,
- device::mojom::blink::VRDisplayHostPtr display,
- device::mojom::blink::VRDisplayClientRequest request)
+SessionClientBinding::SessionClientBinding(
+ VRDisplay* display,
+ bool is_immersive,
+ device::mojom::blink::XRSessionClientRequest request)
+ : display_(display),
+ is_immersive_(is_immersive),
+ client_binding_(this, std::move(request)){};
+
+SessionClientBinding::~SessionClientBinding() = default;
+
+void SessionClientBinding::Close() {
+ DCHECK(client_binding_);
+ client_binding_.Close();
+}
+void SessionClientBinding::OnChanged(
+ device::mojom::blink::VRDisplayInfoPtr ptr) {
+ display_->OnChanged(std::move(ptr), is_immersive_);
+};
+void SessionClientBinding::OnExitPresent() {
+ display_->OnExitPresent(is_immersive_);
+};
+void SessionClientBinding::OnBlur() {
+ display_->OnBlur(is_immersive_);
+};
+void SessionClientBinding::OnFocus() {
+ display_->OnFocus(is_immersive_);
+};
+void SessionClientBinding::Trace(blink::Visitor* visitor) {
+ visitor->Trace(display_);
+}
+
+VRDisplay::VRDisplay(NavigatorVR* navigator_vr,
+ device::mojom::blink::XRDevicePtr device)
: PausableObject(navigator_vr->GetDocument()),
navigator_vr_(navigator_vr),
capabilities_(new VRDisplayCapabilities()),
- display_(std::move(display)),
- display_client_binding_(this, std::move(request)) {
+ device_ptr_(std::move(device)),
+ display_client_binding_(this) {
PauseIfNeeded(); // Initialize SuspendabaleObject.
- // Request a non-exclusive session to provide magic window.
+ // Request a non-immersive session immediately as WebVR 1.1 expects to be able
+ // to get non-immersive poses as soon as the display is returned.
device::mojom::blink::XRSessionOptionsPtr options =
device::mojom::blink::XRSessionOptions::New();
options->immersive = false;
// Set in_on_display_activate to true, this will prevent the request present
// from being logged.
- // TODO(offenwanger): clean up the logging when refactors are complete.
- display_->RequestSession(std::move(options), true,
- WTF::Bind(&VRDisplay::OnMagicWindowRequestReturned,
- WrapPersistent(this)));
+ // TODO(http://crbug.com/842025): clean up the logging when refactors are
+ // complete.
+ device_ptr_->RequestSession(
+ std::move(options), true,
+ WTF::Bind(&VRDisplay::OnNonImmersiveSessionRequestReturned,
+ WrapPersistent(this)));
}
VRDisplay::~VRDisplay() = default;
@@ -129,7 +161,6 @@ VRController* VRDisplay::Controller() {
}
void VRDisplay::Update(const device::mojom::blink::VRDisplayInfoPtr& display) {
- display_id_ = display->index;
display_name_ = display->displayName;
is_connected_ = true;
@@ -226,12 +257,12 @@ void VRDisplay::RequestVSync() {
<< " start: pending_vrdisplay_raf_=" << pending_vrdisplay_raf_
<< " in_animation_frame_=" << in_animation_frame_
<< " did_submit_this_frame_=" << did_submit_this_frame_
- << " pending_magic_window_vsync_=" << pending_magic_window_vsync_
+ << " pending_non_immersive_vsync_=" << pending_non_immersive_vsync_
<< " pending_presenting_vsync_=" << pending_presenting_vsync_;
if (!pending_vrdisplay_raf_)
return;
Document* doc = navigator_vr_->GetDocument();
- if (!doc || !display_)
+ if (!doc || !device_ptr_)
return;
if (display_blurred_)
return;
@@ -242,31 +273,31 @@ void VRDisplay::RequestVSync() {
if (pending_presenting_vsync_)
return;
- pending_magic_window_vsync_ = false;
+ pending_non_immersive_vsync_ = false;
pending_presenting_vsync_ = true;
- vr_presentation_provider_->GetFrameData(
+ vr_presentation_data_provider_->GetFrameData(
WTF::Bind(&VRDisplay::OnPresentingVSync, WrapWeakPersistent(this)));
DVLOG(2) << __FUNCTION__ << " done: pending_presenting_vsync_="
<< pending_presenting_vsync_;
} else {
- // Check if magic_window_provider_, if not then we are not fully
- // initialized, or we do not support magic window, so don't request the
- // vsync. If and when magic_window_provider_ is set it will run this code
+ // Check if non_immersive_provider_, if not then we are not fully
+ // initialized, or we do not support non-immersive, so don't request the
+ // vsync. If and when non_immersive_provider_ is set it will run this code
// again.
- if (!magic_window_provider_)
+ if (!non_immersive_provider_)
return;
- if (pending_magic_window_vsync_)
+ if (pending_non_immersive_vsync_)
return;
- magic_window_vsync_waiting_for_pose_.Reset();
- magic_window_pose_request_time_ = WTF::CurrentTimeTicks();
- magic_window_provider_->GetFrameData(WTF::Bind(
- &VRDisplay::OnMagicWindowFrameData, WrapWeakPersistent(this)));
- pending_magic_window_vsync_ = true;
- pending_magic_window_vsync_id_ =
+ non_immersive_vsync_waiting_for_pose_.Reset();
+ non_immersive_pose_request_time_ = WTF::CurrentTimeTicks();
+ non_immersive_provider_->GetFrameData(WTF::Bind(
+ &VRDisplay::OnNonImmersiveFrameData, WrapWeakPersistent(this)));
+ pending_non_immersive_vsync_ = true;
+ pending_non_immersive_vsync_id_ =
doc->RequestAnimationFrame(new VRDisplayFrameRequestCallback(this));
- DVLOG(2) << __FUNCTION__ << " done: pending_magic_window_vsync_="
- << pending_magic_window_vsync_;
+ DVLOG(2) << __FUNCTION__ << " done: pending_non_immersive_vsync_="
+ << pending_non_immersive_vsync_;
}
}
@@ -293,14 +324,20 @@ void VRDisplay::cancelAnimationFrame(int id) {
scripted_animation_controller_->CancelCallback(id);
}
-void VRDisplay::OnBlur() {
+void VRDisplay::OnBlur(bool is_immersive) {
+ // TODO(http://crbug.com/845283) When cleaning up the Blur events, determine
+ // whether we should react to blur events from both immersive and non-
+ // immersive sessions.
DVLOG(1) << __FUNCTION__;
display_blurred_ = true;
navigator_vr_->EnqueueVREvent(
VRDisplayEvent::Create(EventTypeNames::vrdisplayblur, this, ""));
}
-void VRDisplay::OnFocus() {
+void VRDisplay::OnFocus(bool is_immersive) {
+ // TODO(http://crbug.com/845283) When cleaning up the Blur events, determine
+ // whether we should react to blur events from both immersive and non-
+ // immersive sessions.
DVLOG(1) << __FUNCTION__;
display_blurred_ = false;
RequestVSync();
@@ -464,7 +501,7 @@ ScriptPromise VRDisplay::requestPresent(ScriptState* script_state,
// original request returns.
pending_present_resolvers_.push_back(resolver);
} else if (first_present) {
- if (!display_) {
+ if (!device_ptr_) {
ForceExitPresent();
DOMException* exception =
DOMException::Create(DOMExceptionCode::kInvalidStateError,
@@ -482,9 +519,10 @@ ScriptPromise VRDisplay::requestPresent(ScriptState* script_state,
options->immersive = true;
options->use_legacy_webvr_render_path = true;
- display_->RequestSession(
+ device_ptr_->RequestSession(
std::move(options), in_display_activate_,
- WTF::Bind(&VRDisplay::OnRequestSessionReturned, WrapPersistent(this)));
+ WTF::Bind(&VRDisplay::OnRequestImmersiveSessionReturned,
+ WrapPersistent(this)));
pending_present_request_ = true;
// The old vr_presentation_provider_ won't be delivering any vsyncs anymore,
@@ -499,20 +537,37 @@ ScriptPromise VRDisplay::requestPresent(ScriptState* script_state,
return promise;
}
-void VRDisplay::OnRequestSessionReturned(
+void VRDisplay::OnRequestImmersiveSessionReturned(
device::mojom::blink::XRSessionPtr session) {
pending_present_request_ = false;
- if (session && session->connection) {
- vr_presentation_provider_.Bind(std::move(session->connection->provider));
+ if (session) {
+ DCHECK(session->submit_frame_sink);
+ vr_presentation_data_provider_.reset();
+ vr_presentation_data_provider_.Bind(std::move(session->data_provider));
+ // The presentation provider error handler can trigger if a device is
+ // disconnected from the system. This can happen if, for example, an HMD is
+ // unplugged.
+ vr_presentation_data_provider_.set_connection_error_handler(
+ WTF::Bind(&VRDisplay::OnPresentationProviderConnectionError,
+ WrapWeakPersistent(this)));
+ vr_presentation_provider_.Bind(
+ std::move(session->submit_frame_sink->provider));
vr_presentation_provider_.set_connection_error_handler(
WTF::Bind(&VRDisplay::OnPresentationProviderConnectionError,
WrapWeakPersistent(this)));
frame_transport_ = new XRFrameTransport();
frame_transport_->BindSubmitFrameClient(
- std::move(session->connection->client_request));
+ std::move(session->submit_frame_sink->client_request));
frame_transport_->SetTransportOptions(
- std::move(session->connection->transport_options));
+ std::move(session->submit_frame_sink->transport_options));
+
+ if (immersive_client_binding_)
+ immersive_client_binding_->Close();
+ immersive_client_binding_ = new SessionClientBinding(
+ this, false, std::move(session->client_request));
+
+ Update(std::move(session->display_info));
this->BeginPresent();
} else {
@@ -527,13 +582,15 @@ void VRDisplay::OnRequestSessionReturned(
}
}
-void VRDisplay::OnMagicWindowRequestReturned(
+void VRDisplay::OnNonImmersiveSessionRequestReturned(
device::mojom::blink::XRSessionPtr session) {
- if (!session || !session->magic_window_provider) {
- // System does not support any kind of magic window.
+ if (!session) {
+ // System does not support any kind of session.
return;
}
- magic_window_provider_.Bind(std::move(session->magic_window_provider));
+ non_immersive_provider_.Bind(std::move(session->data_provider));
+ non_immersive_client_binding_ =
+ new SessionClientBinding(this, false, std::move(session->client_request));
RequestVSync();
}
@@ -550,13 +607,13 @@ ScriptPromise VRDisplay::exitPresent(ScriptState* script_state) {
return promise;
}
- if (!display_) {
+ if (!device_ptr_) {
DOMException* exception = DOMException::Create(
DOMExceptionCode::kInvalidStateError, "VRService is not available.");
resolver->Reject(exception);
return promise;
}
- display_->ExitPresent();
+ device_ptr_->ExitPresent();
resolver->Resolve();
@@ -607,11 +664,11 @@ void VRDisplay::BeginPresent() {
if (!FocusedOrPresenting() && display_blurred_) {
// Presentation doesn't care about focus, so if we're blurred because of
// focus, then unblur.
- OnFocus();
+ OnFocus(true);
}
is_presenting_ = true;
// Call RequestVSync to switch from the (internal) document rAF to the
- // VrPresentationProvider GetFrameData rate.
+ // XRPresentationProvider GetFrameData rate.
RequestVSync();
ReportPresentationResult(PresentationResult::kSuccess);
@@ -636,14 +693,14 @@ void VRDisplay::BeginPresent() {
// Need to close service if exists and then free rendering context.
void VRDisplay::ForceExitPresent() {
- if (display_) {
- display_->ExitPresent();
+ if (device_ptr_) {
+ device_ptr_->ExitPresent();
}
StopPresenting();
}
void VRDisplay::UpdateLayerBounds() {
- if (!display_)
+ if (!device_ptr_)
return;
// Left eye defaults
@@ -702,7 +759,7 @@ scoped_refptr<Image> VRDisplay::GetFrameImage(
void VRDisplay::submitFrame() {
DVLOG(2) << __FUNCTION__;
- if (!display_)
+ if (!device_ptr_)
return;
TRACE_EVENT1("gpu", "submitFrame", "frame", vr_frame_id_);
@@ -789,6 +846,13 @@ Document* VRDisplay::GetDocument() {
return navigator_vr_->GetDocument();
}
+device::mojom::blink::VRDisplayClientPtr VRDisplay::GetDisplayClient() {
+ display_client_binding_.Close();
+ device::mojom::blink::VRDisplayClientPtr client;
+ display_client_binding_.Bind(mojo::MakeRequest(&client));
+ return client;
+}
+
void VRDisplay::OnPresentChange() {
if (frame_transport_)
frame_transport_->PresentChange();
@@ -802,12 +866,22 @@ void VRDisplay::OnPresentChange() {
VRDisplayEvent::Create(EventTypeNames::vrdisplaypresentchange, this, ""));
}
-void VRDisplay::OnChanged(device::mojom::blink::VRDisplayInfoPtr display) {
- Update(display);
+void VRDisplay::OnChanged(device::mojom::blink::VRDisplayInfoPtr display,
+ bool is_immersive) {
+ // VrDisplayInfo is only used for immersive sessions, so unless this is
+ // from an immersive device, ignore it.
+ // We expect that non-immersive sessions don't use display info, and immersive
+ // sessions will not use display info until they are presenting, so it is fine
+ // for us not to start listening until then.
+ if (is_immersive) {
+ Update(display);
+ }
}
-void VRDisplay::OnExitPresent() {
- StopPresenting();
+void VRDisplay::OnExitPresent(bool is_immersive) {
+ if (is_immersive) {
+ StopPresenting();
+ }
}
void VRDisplay::OnConnected() {
@@ -949,7 +1023,7 @@ void VRDisplay::ProcessScheduledAnimations(TimeTicks timestamp) {
// Sanity check: If pending_vrdisplay_raf_ is true and the vsync provider
// is connected, we must now have a pending vsync.
- DCHECK(!pending_vrdisplay_raf_ || pending_magic_window_vsync_ ||
+ DCHECK(!pending_vrdisplay_raf_ || pending_non_immersive_vsync_ ||
pending_presenting_vsync_);
}
@@ -965,7 +1039,7 @@ void VRDisplay::OnPresentingVSync(
return;
}
- // All early exits that want this VSync converted to a magic window
+ // All early exits that want this VSync converted to a non-immersive
// VSync must happen before this line. Once it's set to not pending,
// an early exit woud break animation.
pending_presenting_vsync_ = false;
@@ -991,24 +1065,24 @@ void VRDisplay::OnPresentingVSync(
TimeTicks() + frame_data->time_delta));
}
-void VRDisplay::OnMagicWindowVSync(TimeTicks timestamp) {
+void VRDisplay::OnNonImmersiveVSync(TimeTicks timestamp) {
DVLOG(2) << __FUNCTION__;
- pending_magic_window_vsync_ = false;
- pending_magic_window_vsync_id_ = -1;
+ pending_non_immersive_vsync_ = false;
+ pending_non_immersive_vsync_id_ = -1;
if (is_presenting_)
return;
vr_frame_id_ = -1;
WTF::TimeDelta pose_age =
- WTF::CurrentTimeTicks() - magic_window_pose_received_time_;
- if (pose_age >= kMagicWindowPoseAgeThreshold &&
- magic_window_pose_request_time_ > magic_window_pose_received_time_) {
+ WTF::CurrentTimeTicks() - non_immersive_pose_received_time_;
+ if (pose_age >= kNonImmersivePoseAgeThreshold &&
+ non_immersive_pose_request_time_ > non_immersive_pose_received_time_) {
// The VSync got triggered before ever receiving a pose, or the pose is
// stale. Defer the animation until a pose arrives to avoid passing null
// poses to the application, but only do this if we have an outstanding
// unresolved GetPose request. For example, the pose might be stale after
- // exiting VR Browser magic window mode due to a longish transition, but we
+ // exiting VR Browser non-immersive mode due to a longish transition, but we
// need to use it anyway if it's from the current frame's GetPose.
- magic_window_vsync_waiting_for_pose_ =
+ non_immersive_vsync_waiting_for_pose_ =
WTF::Bind(&VRDisplay::ProcessScheduledAnimations,
WrapWeakPersistent(this), timestamp);
} else {
@@ -1016,9 +1090,9 @@ void VRDisplay::OnMagicWindowVSync(TimeTicks timestamp) {
}
}
-void VRDisplay::OnMagicWindowFrameData(
+void VRDisplay::OnNonImmersiveFrameData(
device::mojom::blink::XRFrameDataPtr data) {
- magic_window_pose_received_time_ = WTF::CurrentTimeTicks();
+ non_immersive_pose_received_time_ = WTF::CurrentTimeTicks();
if (data) {
if (!in_animation_frame_) {
frame_pose_ = std::move(data->pose);
@@ -1026,18 +1100,19 @@ void VRDisplay::OnMagicWindowFrameData(
pending_pose_ = std::move(data->pose);
}
}
- if (magic_window_vsync_waiting_for_pose_) {
+ if (non_immersive_vsync_waiting_for_pose_) {
// We have a vsync waiting for a pose, run it now.
- std::move(magic_window_vsync_waiting_for_pose_).Run();
- magic_window_vsync_waiting_for_pose_.Reset();
+ std::move(non_immersive_vsync_waiting_for_pose_).Run();
+ non_immersive_vsync_waiting_for_pose_.Reset();
}
}
void VRDisplay::OnPresentationProviderConnectionError() {
DVLOG(1) << __FUNCTION__ << ";;; is_presenting_=" << is_presenting_
- << " pending_magic_window_vsync_=" << pending_magic_window_vsync_
+ << " pending_non_immersive_vsync_=" << pending_non_immersive_vsync_
<< " pending_presenting_vsync_=" << pending_presenting_vsync_;
vr_presentation_provider_.reset();
+ vr_presentation_data_provider_.reset();
if (is_presenting_) {
ForceExitPresent();
}
@@ -1054,7 +1129,9 @@ ScriptedAnimationController& VRDisplay::EnsureScriptedAnimationController(
}
void VRDisplay::Dispose() {
- display_client_binding_.Close();
+ if (non_immersive_client_binding_)
+ non_immersive_client_binding_->Close();
+ non_immersive_client_binding_ = nullptr;
vr_presentation_provider_.reset();
}
@@ -1084,9 +1161,13 @@ bool VRDisplay::HasPendingActivity() const {
void VRDisplay::FocusChanged() {
DVLOG(1) << __FUNCTION__;
if (navigator_vr_->IsFocused()) {
- OnFocus();
+ if (is_presenting_) {
+ OnFocus(true /* is_immmersive */);
+ } else {
+ OnFocus(false /* is_immmersive */);
+ }
} else if (!is_presenting_) {
- OnBlur();
+ OnBlur(false);
}
}
@@ -1107,6 +1188,8 @@ void VRDisplay::Trace(blink::Visitor* visitor) {
visitor->Trace(rendering_context_);
visitor->Trace(frame_transport_);
visitor->Trace(scripted_animation_controller_);
+ visitor->Trace(non_immersive_client_binding_);
+ visitor->Trace(immersive_client_binding_);
visitor->Trace(pending_present_resolvers_);
EventTargetWithInlineData::Trace(visitor);
ContextLifecycleObserver::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/vr/vr_display.h b/chromium/third_party/blink/renderer/modules/vr/vr_display.h
index bfd146986b0..de85257ee3c 100644
--- a/chromium/third_party/blink/renderer/modules/vr/vr_display.h
+++ b/chromium/third_party/blink/renderer/modules/vr/vr_display.h
@@ -35,9 +35,37 @@ class VRController;
class VREyeParameters;
class VRFrameData;
class VRStageParameters;
+class VRDisplay;
class WebGLRenderingContextBase;
+// Wrapper class to allow the VRDisplay to distinguish between immersive and
+// non-immersive XRSession events.
+class SessionClientBinding
+ : public GarbageCollectedFinalized<SessionClientBinding>,
+ public device::mojom::blink::XRSessionClient {
+ public:
+ SessionClientBinding(VRDisplay* display,
+ bool is_immersive,
+ device::mojom::blink::XRSessionClientRequest request);
+ ~SessionClientBinding() override;
+ void Close();
+
+ void Trace(blink::Visitor*);
+
+ private:
+ void OnChanged(device::mojom::blink::VRDisplayInfoPtr) override;
+ void OnExitPresent() override;
+ void OnBlur() override;
+ void OnFocus() override;
+
+ // VRDisplay keeps all references to SessionClientBinding, so as soon as
+ // VRDisplay is destroyed, so is the SessionClientBinding.
+ Member<VRDisplay> display_;
+ bool is_immersive_;
+ mojo::Binding<device::mojom::blink::XRSessionClient> client_binding_;
+};
+
enum VREye { kVREyeNone, kVREyeLeft, kVREyeRight };
class VRDisplay final : public EventTargetWithInlineData,
@@ -57,8 +85,10 @@ class VRDisplay final : public EventTargetWithInlineData,
VRDisplayCapabilities* capabilities() const { return capabilities_; }
VRStageParameters* stageParameters() const { return stage_parameters_; }
+ device::mojom::blink::XRDevice* device() { return device_ptr_.get(); }
bool isPresenting() const { return is_presenting_; }
+ bool canPresent() const { return capabilities_->canPresent(); }
bool getFrameData(VRFrameData*);
@@ -82,6 +112,7 @@ class VRDisplay final : public EventTargetWithInlineData,
void submitFrame();
Document* GetDocument();
+ device::mojom::blink::VRDisplayClientPtr GetDisplayClient();
// EventTarget overrides:
ExecutionContext* GetExecutionContext() const override;
@@ -97,19 +128,22 @@ class VRDisplay final : public EventTargetWithInlineData,
void Pause() override;
void Unpause() override;
+ void OnChanged(device::mojom::blink::VRDisplayInfoPtr, bool is_immersive);
+ void OnExitPresent(bool is_immersive);
+ void OnBlur(bool is_immersive);
+ void OnFocus(bool is_immersive);
+
void FocusChanged();
- void OnMagicWindowVSync(TimeTicks timestamp);
- int PendingMagicWindowVSyncId() { return pending_magic_window_vsync_id_; }
+ void OnNonImmersiveVSync(TimeTicks timestamp);
+ int PendingNonImmersiveVSyncId() { return pending_non_immersive_vsync_id_; }
void Trace(blink::Visitor*) override;
protected:
friend class VRController;
- VRDisplay(NavigatorVR*,
- device::mojom::blink::VRDisplayHostPtr,
- device::mojom::blink::VRDisplayClientRequest);
+ VRDisplay(NavigatorVR*, device::mojom::blink::XRDevicePtr);
void Update(const device::mojom::blink::VRDisplayInfoPtr&);
@@ -123,8 +157,10 @@ class VRDisplay final : public EventTargetWithInlineData,
VRController* Controller();
private:
- void OnRequestSessionReturned(device::mojom::blink::XRSessionPtr session);
- void OnMagicWindowRequestReturned(device::mojom::blink::XRSessionPtr session);
+ void OnRequestImmersiveSessionReturned(
+ device::mojom::blink::XRSessionPtr session);
+ void OnNonImmersiveSessionRequestReturned(
+ device::mojom::blink::XRSessionPtr session);
void OnConnected();
void OnDisconnected();
@@ -134,10 +170,6 @@ class VRDisplay final : public EventTargetWithInlineData,
void OnPresentChange();
// VRDisplayClient
- void OnChanged(device::mojom::blink::VRDisplayInfoPtr) override;
- void OnExitPresent() override;
- void OnBlur() override;
- void OnFocus() override;
void OnActivate(device::mojom::blink::VRDisplayEventReason,
OnActivateCallback on_handled) override;
void OnDeactivate(device::mojom::blink::VRDisplayEventReason) override;
@@ -145,7 +177,7 @@ class VRDisplay final : public EventTargetWithInlineData,
void OnPresentingVSync(device::mojom::blink::XRFrameDataPtr);
void OnPresentationProviderConnectionError();
- void OnMagicWindowFrameData(device::mojom::blink::XRFrameDataPtr);
+ void OnNonImmersiveFrameData(device::mojom::blink::XRFrameDataPtr);
bool FocusedOrPresenting();
@@ -163,7 +195,6 @@ class VRDisplay final : public EventTargetWithInlineData,
std::unique_ptr<viz::SingleReleaseCallback>* out_release_callback);
Member<NavigatorVR> navigator_vr_;
- unsigned display_id_ = 0;
String display_name_;
bool is_connected_ = false;
bool is_presenting_ = false;
@@ -202,11 +233,11 @@ class VRDisplay final : public EventTargetWithInlineData,
scripted_animation_controller_;
bool pending_vrdisplay_raf_ = false;
bool pending_presenting_vsync_ = false;
- bool pending_magic_window_vsync_ = false;
- int pending_magic_window_vsync_id_ = -1;
- base::OnceClosure magic_window_vsync_waiting_for_pose_;
- WTF::TimeTicks magic_window_pose_request_time_;
- WTF::TimeTicks magic_window_pose_received_time_;
+ bool pending_non_immersive_vsync_ = false;
+ int pending_non_immersive_vsync_id_ = -1;
+ base::OnceClosure non_immersive_vsync_waiting_for_pose_;
+ WTF::TimeTicks non_immersive_pose_request_time_;
+ WTF::TimeTicks non_immersive_pose_received_time_;
bool in_animation_frame_ = false;
bool did_submit_this_frame_ = false;
bool display_blurred_ = false;
@@ -217,14 +248,17 @@ class VRDisplay final : public EventTargetWithInlineData,
bool did_log_getFrameData_ = false;
bool did_log_requestPresent_ = false;
- device::mojom::blink::VRMagicWindowProviderPtr magic_window_provider_;
+ device::mojom::blink::XRFrameDataProviderPtr non_immersive_provider_;
- device::mojom::blink::VRDisplayHostPtr display_;
+ device::mojom::blink::XRDevicePtr device_ptr_;
bool present_image_needs_copy_ = false;
+ Member<SessionClientBinding> non_immersive_client_binding_;
+ Member<SessionClientBinding> immersive_client_binding_;
mojo::Binding<device::mojom::blink::VRDisplayClient> display_client_binding_;
- device::mojom::blink::VRPresentationProviderPtr vr_presentation_provider_;
+ device::mojom::blink::XRFrameDataProviderPtr vr_presentation_data_provider_;
+ device::mojom::blink::XRPresentationProviderPtr vr_presentation_provider_;
HeapDeque<Member<ScriptPromiseResolver>> pending_present_resolvers_;
};
diff --git a/chromium/third_party/blink/renderer/modules/vr/vr_display.idl b/chromium/third_party/blink/renderer/modules/vr/vr_display.idl
index 207643036ba..026d6ce8317 100644
--- a/chromium/third_party/blink/renderer/modules/vr/vr_display.idl
+++ b/chromium/third_party/blink/renderer/modules/vr/vr_display.idl
@@ -10,7 +10,7 @@ enum VREye {
// https://w3c.github.io/webvr/#interface-vrdisplay
[
ActiveScriptWrappable,
- RuntimeEnabled=WebVR
+ OriginTrialEnabled=WebVR
] interface VRDisplay : EventTarget {
// An identifier for this device unique across VRDisplays.
readonly attribute unsigned long displayId;
diff --git a/chromium/third_party/blink/renderer/modules/vr/vr_display_capabilities.idl b/chromium/third_party/blink/renderer/modules/vr/vr_display_capabilities.idl
index 78cd1f5eca0..14d8265674a 100644
--- a/chromium/third_party/blink/renderer/modules/vr/vr_display_capabilities.idl
+++ b/chromium/third_party/blink/renderer/modules/vr/vr_display_capabilities.idl
@@ -4,7 +4,7 @@
// https://w3c.github.io/webvr/#interface-vrdisplaycapabilities
[
- RuntimeEnabled=WebVR
+ OriginTrialEnabled=WebVR
] interface VRDisplayCapabilities {
// Whether or not the VR display is capable of reporting user position.
// If false position may still be reported using simulated values like
diff --git a/chromium/third_party/blink/renderer/modules/vr/vr_display_event.idl b/chromium/third_party/blink/renderer/modules/vr/vr_display_event.idl
index 56272794a5c..ae9103af393 100644
--- a/chromium/third_party/blink/renderer/modules/vr/vr_display_event.idl
+++ b/chromium/third_party/blink/renderer/modules/vr/vr_display_event.idl
@@ -12,7 +12,7 @@ enum VRDisplayEventReason {
// https://w3c.github.io/webvr/#interface-vrdisplayevent
[
- RuntimeEnabled=WebVR,
+ OriginTrialEnabled=WebVR,
Constructor(DOMString type, optional VRDisplayEventInit eventInitDict)
] interface VRDisplayEvent : Event {
readonly attribute VRDisplay display;
diff --git a/chromium/third_party/blink/renderer/modules/vr/vr_eye_parameters.cc b/chromium/third_party/blink/renderer/modules/vr/vr_eye_parameters.cc
index 3121569ff8c..0c4f15ffa2d 100644
--- a/chromium/third_party/blink/renderer/modules/vr/vr_eye_parameters.cc
+++ b/chromium/third_party/blink/renderer/modules/vr/vr_eye_parameters.cc
@@ -9,14 +9,12 @@ namespace blink {
VREyeParameters::VREyeParameters(
const device::mojom::blink::VREyeParametersPtr& eye_parameters,
double render_scale) {
- // TODO(offenwanger): Convert this into initializers.
offset_ = DOMFloat32Array::Create(3);
- field_of_view_ = new VRFieldOfView();
-
offset_->Data()[0] = eye_parameters->offset[0];
offset_->Data()[1] = eye_parameters->offset[1];
offset_->Data()[2] = eye_parameters->offset[2];
+ field_of_view_ = new VRFieldOfView();
field_of_view_->SetUpDegrees(eye_parameters->fieldOfView->upDegrees);
field_of_view_->SetDownDegrees(eye_parameters->fieldOfView->downDegrees);
field_of_view_->SetLeftDegrees(eye_parameters->fieldOfView->leftDegrees);
diff --git a/chromium/third_party/blink/renderer/modules/vr/vr_eye_parameters.idl b/chromium/third_party/blink/renderer/modules/vr/vr_eye_parameters.idl
index 4da215cefc0..7b5b630e1d2 100644
--- a/chromium/third_party/blink/renderer/modules/vr/vr_eye_parameters.idl
+++ b/chromium/third_party/blink/renderer/modules/vr/vr_eye_parameters.idl
@@ -4,7 +4,7 @@
// https://w3c.github.io/webvr/#interface-vreyeparameters
[
- RuntimeEnabled=WebVR
+ OriginTrialEnabled=WebVR
] interface VREyeParameters {
/* These values will vary after a FOV has been set */
[DeprecateAs=VREyeParametersOffset] readonly attribute Float32Array offset;
diff --git a/chromium/third_party/blink/renderer/modules/vr/vr_frame_data.cc b/chromium/third_party/blink/renderer/modules/vr/vr_frame_data.cc
index dbc87757846..d17d973b810 100644
--- a/chromium/third_party/blink/renderer/modules/vr/vr_frame_data.cc
+++ b/chromium/third_party/blink/renderer/modules/vr/vr_frame_data.cc
@@ -187,8 +187,6 @@ bool VRFrameData::Update(const device::mojom::blink::VRPosePtr& pose,
fov_right = right_eye->FieldOfView();
} else {
DCHECK(!left_eye && !right_eye);
- // TODO(offenwanger): Look into making the projection matrixes null instead
- // of hard coding values. May break some apps.
fov_left = fov_right = new VRFieldOfView(45, 45, 45, 45);
}
diff --git a/chromium/third_party/blink/renderer/modules/vr/vr_frame_data.idl b/chromium/third_party/blink/renderer/modules/vr/vr_frame_data.idl
index 9df122c1159..5d1f3484ea7 100644
--- a/chromium/third_party/blink/renderer/modules/vr/vr_frame_data.idl
+++ b/chromium/third_party/blink/renderer/modules/vr/vr_frame_data.idl
@@ -4,7 +4,7 @@
// https://w3c.github.io/webvr/#interface-vrframedata
[
- RuntimeEnabled=WebVR,
+ OriginTrialEnabled=WebVR,
Constructor
] interface VRFrameData {
readonly attribute Float32Array leftProjectionMatrix;
diff --git a/chromium/third_party/blink/renderer/modules/vr/vr_pose.idl b/chromium/third_party/blink/renderer/modules/vr/vr_pose.idl
index e8dcd6349c0..e935c5fe015 100644
--- a/chromium/third_party/blink/renderer/modules/vr/vr_pose.idl
+++ b/chromium/third_party/blink/renderer/modules/vr/vr_pose.idl
@@ -4,7 +4,7 @@
// https://w3c.github.io/webvr/#interface-vrpose
[
- RuntimeEnabled=WebVR
+ OriginTrialEnabled=WebVR
] interface VRPose {
readonly attribute Float32Array? position;
[MeasureAs=VRPoseLinearVelocity] readonly attribute Float32Array? linearVelocity;
diff --git a/chromium/third_party/blink/renderer/modules/vr/vr_stage_parameters.idl b/chromium/third_party/blink/renderer/modules/vr/vr_stage_parameters.idl
index 562c9b5a2f2..458582f9ba8 100644
--- a/chromium/third_party/blink/renderer/modules/vr/vr_stage_parameters.idl
+++ b/chromium/third_party/blink/renderer/modules/vr/vr_stage_parameters.idl
@@ -4,7 +4,7 @@
// https://w3c.github.io/webvr/#interface-vrstageparameters
[
- RuntimeEnabled=WebVR
+ OriginTrialEnabled=WebVR
] interface VRStageParameters {
// A 16 element array containing the components of a 4x4 transform
// matrix. This matrix transforms the sitting space position
diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/BUILD.gn b/chromium/third_party/blink/renderer/modules/wake_lock/BUILD.gn
index 9d7c73be16e..6adccd6dd73 100644
--- a/chromium/third_party/blink/renderer/modules/wake_lock/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/wake_lock/BUILD.gn
@@ -6,7 +6,18 @@ import("//third_party/blink/renderer/modules/modules.gni")
blink_modules_sources("wake_lock") {
sources = [
+ "navigator_wake_lock.cc",
+ "navigator_wake_lock.h",
"screen_wake_lock.cc",
"screen_wake_lock.h",
+ "wake_lock.cc",
+ "wake_lock.h",
+ "wake_lock_request.cc",
+ "wake_lock_request.h",
+ ]
+ deps = [
+ "//mojo/public/cpp/bindings",
+ "//services/service_manager/public/cpp",
+ "//third_party/blink/renderer/platform",
]
}
diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/DEPS b/chromium/third_party/blink/renderer/modules/wake_lock/DEPS
index a720dece13b..23424fb8031 100644
--- a/chromium/third_party/blink/renderer/modules/wake_lock/DEPS
+++ b/chromium/third_party/blink/renderer/modules/wake_lock/DEPS
@@ -1,4 +1,7 @@
include_rules = [
"+mojo/public/cpp/bindings",
"+services/device/public/mojom",
+ "+services/device/public/interfaces/constants.mojom-blink.h",
+ "+services/device/public/mojom/wake_lock.mojom-blink.h",
+ "+third_party/blink/renderer/modules/event_target_modules.h",
]
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
new file mode 100644
index 00000000000..43671330e6c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.cc
@@ -0,0 +1,57 @@
+// 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/wake_lock/navigator_wake_lock.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/wake_lock/wake_lock.h"
+
+namespace blink {
+
+// static
+const char NavigatorWakeLock::kSupplementName[] = "NavigatorWakeLock";
+
+NavigatorWakeLock::NavigatorWakeLock(Navigator& navigator)
+ : Supplement<Navigator>(navigator) {}
+
+// static
+ScriptPromise NavigatorWakeLock::getWakeLock(ScriptState* script_state,
+ Navigator& navigator,
+ String lock_type) {
+ return NavigatorWakeLock::From(navigator).getWakeLock(script_state,
+ lock_type);
+}
+
+ScriptPromise NavigatorWakeLock::getWakeLock(ScriptState* script_state,
+ String lock_type) {
+ // TODO(crbug.com/873030): Handle 'system' Wake Lock
+ if (lock_type == "screen") {
+ if (!wake_lock_screen_)
+ wake_lock_screen_ = WakeLock::CreateScreenWakeLock(script_state);
+ return wake_lock_screen_->GetPromise(script_state);
+ }
+
+ return ScriptPromise::RejectWithDOMException(
+ script_state, DOMException::Create(DOMExceptionCode::kNotSupportedError,
+ "WakeLockType Not Supported"));
+}
+
+NavigatorWakeLock& NavigatorWakeLock::From(Navigator& navigator) {
+ NavigatorWakeLock* supplement =
+ Supplement<Navigator>::From<NavigatorWakeLock>(navigator);
+ if (!supplement) {
+ supplement = new NavigatorWakeLock(navigator);
+ ProvideTo(navigator, supplement);
+ }
+ return *supplement;
+}
+
+void NavigatorWakeLock::Trace(blink::Visitor* visitor) {
+ visitor->Trace(wake_lock_screen_);
+ Supplement<Navigator>::Trace(visitor);
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..1ffe09eee67
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.h
@@ -0,0 +1,40 @@
+// 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_WAKE_LOCK_NAVIGATOR_WAKE_LOCK_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_WAKE_LOCK_NAVIGATOR_WAKE_LOCK_H_
+
+#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/core/frame/navigator.h"
+#include "third_party/blink/renderer/modules/wake_lock/wake_lock.h"
+#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/supplementable.h"
+
+namespace blink {
+
+class Navigator;
+
+class NavigatorWakeLock final : public GarbageCollected<NavigatorWakeLock>,
+ public Supplement<Navigator> {
+ USING_GARBAGE_COLLECTED_MIXIN(NavigatorWakeLock);
+
+ public:
+ static const char kSupplementName[];
+
+ static NavigatorWakeLock& From(Navigator&);
+
+ static ScriptPromise getWakeLock(ScriptState*, Navigator&, String);
+
+ void Trace(blink::Visitor*) override;
+
+ private:
+ ScriptPromise getWakeLock(ScriptState*, String);
+ explicit NavigatorWakeLock(Navigator&);
+
+ Member<WakeLock> wake_lock_screen_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WAKE_LOCK_NAVIGATOR_WAKE_LOCK_H_
diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.idl b/chromium/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.idl
new file mode 100644
index 00000000000..609ac6e849c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.idl
@@ -0,0 +1,13 @@
+// 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://www.w3.org/TR/wake-lock
+[
+ SecureContext,
+ Exposed=Window,
+ ImplementedAs=NavigatorWakeLock,
+ RuntimeEnabled=WakeLockNavigator
+] partial interface Navigator {
+ [CallWith=ScriptState] Promise getWakeLock(WakeLockType type);
+}; \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/screen_wake_lock_test.cc b/chromium/third_party/blink/renderer/modules/wake_lock/screen_wake_lock_test.cc
index b7c53492a9d..5565fbf918f 100644
--- a/chromium/third_party/blink/renderer/modules/wake_lock/screen_wake_lock_test.cc
+++ b/chromium/third_party/blink/renderer/modules/wake_lock/screen_wake_lock_test.cc
@@ -14,6 +14,7 @@
#include "third_party/blink/renderer/core/dom/document_init.h"
#include "third_party/blink/renderer/core/dom/dom_implementation.h"
#include "third_party/blink/renderer/core/frame/frame_test_helpers.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/platform/testing/testing_platform_support.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
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
new file mode 100644
index 00000000000..109ce866f9f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.cc
@@ -0,0 +1,133 @@
+// 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/wake_lock/wake_lock.h"
+
+#include "services/device/public/mojom/constants.mojom-blink.h"
+#include "services/service_manager/public/cpp/interface_provider.h"
+#include "third_party/blink/public/platform/platform.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"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/modules/wake_lock/wake_lock_request.h"
+#include "third_party/blink/renderer/platform/wtf/assertions.h"
+
+namespace blink {
+
+WakeLock* WakeLock::CreateScreenWakeLock(ScriptState* script_state) {
+ return new WakeLock(script_state, LockType::kScreen);
+}
+
+WakeLock::~WakeLock() = default;
+
+WakeLock::WakeLock(ScriptState* script_state, LockType type)
+ : ContextLifecycleObserver(blink::ExecutionContext::From(script_state)),
+ PageVisibilityObserver(
+ ToDocument(blink::ExecutionContext::From(script_state))->GetPage()),
+ type_(type) {
+ DCHECK(type == LockType::kScreen);
+}
+
+ScriptPromise WakeLock::GetPromise(ScriptState* script_state) {
+ if (!wake_lock_property_) {
+ wake_lock_property_ = new WakeLockProperty(
+ ExecutionContext::From(script_state), this, WakeLockProperty::kReady);
+ wake_lock_property_->Resolve(this);
+ }
+ return wake_lock_property_->Promise(script_state->World());
+}
+
+AtomicString WakeLock::type() const {
+ switch (type_) {
+ case LockType::kSystem:
+ return "system";
+ case LockType::kScreen:
+ return "screen";
+ }
+
+ NOTREACHED();
+ return AtomicString();
+}
+
+bool WakeLock::active() const {
+ return active_;
+}
+
+void WakeLock::OnConnectionError() {
+ wake_lock_service_.reset();
+}
+
+void WakeLock::ChangeActiveStatus(bool active) {
+ if (active_ == active)
+ return;
+
+ BindToServiceIfNeeded();
+ if (active)
+ wake_lock_service_->RequestWakeLock();
+ else
+ wake_lock_service_->CancelWakeLock();
+
+ active_ = active;
+ EnqueueEvent(*Event::Create(EventTypeNames::activechange),
+ TaskType::kMiscPlatformAPI);
+}
+
+void WakeLock::BindToServiceIfNeeded() {
+ if (wake_lock_service_)
+ return;
+
+ LocalFrame* frame = ToDocument(GetExecutionContext())->GetFrame();
+ frame->GetInterfaceProvider().GetInterface(
+ mojo::MakeRequest(&wake_lock_service_));
+ wake_lock_service_.set_connection_error_handler(
+ WTF::Bind(&WakeLock::OnConnectionError, WrapWeakPersistent(this)));
+}
+
+WakeLockRequest* WakeLock::createRequest() {
+ if (!active_ && request_counter_ == 0)
+ ChangeActiveStatus(true);
+
+ request_counter_++;
+ return new WakeLockRequest(this);
+}
+
+void WakeLock::CancelRequest() {
+ DCHECK_GT(request_counter_, 0);
+ if (active_ && request_counter_ == 1)
+ ChangeActiveStatus(false);
+
+ request_counter_--;
+}
+
+const WTF::AtomicString& WakeLock::InterfaceName() const {
+ return EventTargetNames::WakeLock;
+}
+
+ExecutionContext* WakeLock::GetExecutionContext() const {
+ return ContextLifecycleObserver::GetExecutionContext();
+}
+
+bool WakeLock::HasPendingActivity() const {
+ // Prevent V8 from garbage collecting the wrapper object if there are
+ // event listeners attached to it.
+ return GetExecutionContext() && HasEventListeners();
+}
+
+void WakeLock::ContextDestroyed(ExecutionContext*) {
+ ChangeActiveStatus(false);
+}
+
+void WakeLock::PageVisibilityChanged() {
+ ChangeActiveStatus(GetPage() && GetPage()->IsPageVisible());
+}
+
+void WakeLock::Trace(blink::Visitor* visitor) {
+ visitor->Trace(wake_lock_property_);
+ EventTargetWithInlineData::Trace(visitor);
+ ContextLifecycleObserver::Trace(visitor);
+ PageVisibilityObserver::Trace(visitor);
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..40112dc4acc
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.h
@@ -0,0 +1,92 @@
+// 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_WAKE_LOCK_WAKE_LOCK_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_WAKE_LOCK_WAKE_LOCK_H_
+
+#include "services/device/public/mojom/wake_lock.mojom-blink.h"
+#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_promise_property.h"
+#include "third_party/blink/renderer/core/dom/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/platform/heap/handle.h"
+
+namespace blink {
+
+class WakeLockRequest;
+
+class WakeLock final : public EventTargetWithInlineData,
+ public ActiveScriptWrappable<WakeLock>,
+ public ContextLifecycleObserver,
+ public PageVisibilityObserver {
+ DEFINE_WRAPPERTYPEINFO();
+ USING_GARBAGE_COLLECTED_MIXIN(WakeLock);
+
+ public:
+ ~WakeLock() override;
+
+ // wake_lock.idl implementation
+ AtomicString type() const;
+ bool active() const;
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(activechange);
+ WakeLockRequest* createRequest();
+
+ // Called by NavigatorWakeLock to create Screen Wake Lock
+ static WakeLock* CreateScreenWakeLock(ScriptState*);
+
+ // Resolves and returns same promise of that particular WakeLockType each time
+ ScriptPromise GetPromise(ScriptState*);
+
+ // EventTarget overrides.
+ const WTF::AtomicString& InterfaceName() const override;
+ ExecutionContext* GetExecutionContext() const override;
+
+ // ActiveScriptWrappable overrides.
+ bool HasPendingActivity() const final;
+
+ // ContextLifecycleObserver overrides.
+ void ContextDestroyed(ExecutionContext*) override;
+
+ // PageVisibilityObserver overrides.
+ void PageVisibilityChanged() override;
+
+ void Trace(blink::Visitor*) override;
+
+ // Called by WakeLockRequest to decrease the request counter by one
+ void CancelRequest();
+
+ private:
+ enum class LockType { kSystem, kScreen };
+
+ WakeLock(ScriptState*, LockType);
+
+ // Error handler in case of failure to connect to Wake Lock mojo service
+ void OnConnectionError();
+
+ // Depending on active_ status change, requests or cancels Wake Lock
+ void ChangeActiveStatus(bool);
+
+ // Binds to the Wake Lock mojo service
+ void BindToServiceIfNeeded();
+
+ device::mojom::blink::WakeLockPtr wake_lock_service_;
+
+ int request_counter_ = 0;
+ LockType type_;
+ bool active_ = false;
+
+ // We use ScriptPromiseProperty instead of ScriptPromiseResolver or other
+ // mechanism because we need to return same promise of that WakeLockType for
+ // any subsequent calls to navigator.getWakeLock(WakeLockType).
+ using WakeLockProperty = ScriptPromiseProperty<Member<WakeLock>,
+ Member<WakeLock>,
+ Member<DOMException>>;
+ Member<WakeLockProperty> wake_lock_property_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WAKE_LOCK_WAKE_LOCK_H_
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
new file mode 100644
index 00000000000..4f2a1257769
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.idl
@@ -0,0 +1,22 @@
+// 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.
+
+enum WakeLockType {
+ "screen",
+ "system"
+};
+
+// https://www.w3.org/TR/wake-lock
+[
+ ActiveScriptWrappable,
+ SecureContext,
+ Exposed=Window,
+ RuntimeEnabled=WakeLockNavigator
+] interface WakeLock : EventTarget {
+ readonly attribute WakeLockType type;
+ readonly attribute boolean active;
+
+ attribute EventHandler onactivechange;
+ WakeLockRequest createRequest();
+}; \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_request.cc b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_request.cc
new file mode 100644
index 00000000000..a5300493e4d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_request.cc
@@ -0,0 +1,27 @@
+// 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/wake_lock/wake_lock_request.h"
+
+namespace blink {
+
+WakeLockRequest::WakeLockRequest(WakeLock* wake_lock)
+ : owner_wake_lock_(wake_lock) {}
+
+WakeLockRequest::~WakeLockRequest() = default;
+
+void WakeLockRequest::cancel() {
+ if (cancelled_)
+ return;
+
+ cancelled_ = true;
+ owner_wake_lock_->CancelRequest();
+}
+
+void WakeLockRequest::Trace(blink::Visitor* visitor) {
+ visitor->Trace(owner_wake_lock_);
+ ScriptWrappable::Trace(visitor);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_request.h b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_request.h
new file mode 100644
index 00000000000..f5912a97826
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_request.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_MODULES_WAKE_LOCK_WAKE_LOCK_REQUEST_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_WAKE_LOCK_WAKE_LOCK_REQUEST_H_
+
+#include "third_party/blink/renderer/modules/wake_lock/wake_lock.h"
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+
+namespace blink {
+
+class WakeLockRequest final : public ScriptWrappable {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ explicit WakeLockRequest(WakeLock*);
+ ~WakeLockRequest() override;
+
+ void Trace(blink::Visitor*) override;
+
+ void cancel();
+
+ private:
+ Member<WakeLock> owner_wake_lock_;
+ bool cancelled_ = false;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WAKE_LOCK_WAKE_LOCK_REQUEST_H_
diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_request.idl b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_request.idl
new file mode 100644
index 00000000000..2d921120095
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_request.idl
@@ -0,0 +1,12 @@
+// 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://www.w3.org/TR/wake-lock
+[
+ SecureContext,
+ Exposed=Window,
+ RuntimeEnabled=WakeLockNavigator
+] interface WakeLockRequest {
+ void cancel();
+}; \ No newline at end of file
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 f1567e169b2..6a2819e3f18 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/analyser_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/analyser_node.cc
@@ -148,7 +148,7 @@ void AnalyserHandler::SetSmoothingTimeConstant(
}
void AnalyserHandler::UpdatePullStatusIfNeeded() {
- DCHECK(Context()->IsGraphOwner());
+ Context()->AssertGraphOwner();
if (Output(0).IsConnected()) {
// When an AudioBasicInspectorNode is connected to a downstream node, it
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_basic_inspector_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_basic_inspector_node.cc
index 0320632587c..bc5eb7f158c 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_basic_inspector_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_basic_inspector_node.cc
@@ -53,7 +53,7 @@ void AudioBasicInspectorHandler::PullInputs(size_t frames_to_process) {
void AudioBasicInspectorHandler::CheckNumberOfChannelsForInput(
AudioNodeInput* input) {
DCHECK(Context()->IsAudioThread());
- DCHECK(Context()->IsGraphOwner());
+ Context()->AssertGraphOwner();
DCHECK_EQ(input, &this->Input(0));
if (input != &this->Input(0))
@@ -73,7 +73,7 @@ void AudioBasicInspectorHandler::CheckNumberOfChannelsForInput(
}
void AudioBasicInspectorHandler::UpdatePullStatusIfNeeded() {
- DCHECK(Context()->IsGraphOwner());
+ Context()->AssertGraphOwner();
if (Output(0).IsConnected()) {
// When an AudioBasicInspectorNode is connected to a downstream node, it
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 57cdc41521b..a7f6b05aed0 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
@@ -108,7 +108,7 @@ void AudioBasicProcessorHandler::PullInputs(size_t frames_to_process) {
void AudioBasicProcessorHandler::CheckNumberOfChannelsForInput(
AudioNodeInput* input) {
DCHECK(Context()->IsAudioThread());
- DCHECK(Context()->IsGraphOwner());
+ Context()->AssertGraphOwner();
DCHECK_EQ(input, &this->Input(0));
if (input != &this->Input(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 8f7d4cbdab0..7e5d2d715cd 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
@@ -123,8 +123,9 @@ void AudioBufferSourceHandler::Process(size_t frames_to_process) {
size_t buffer_frames_to_process;
double start_time_offset;
- UpdateSchedulingInfo(frames_to_process, output_bus, quantum_frame_offset,
- buffer_frames_to_process, start_time_offset);
+ std::tie(quantum_frame_offset, buffer_frames_to_process,
+ start_time_offset) =
+ UpdateSchedulingInfo(frames_to_process, output_bus);
if (!buffer_frames_to_process) {
output_bus->Zero();
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 23a82aacfa7..272bb914556 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_context.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_context.cc
@@ -7,10 +7,12 @@
#include "build/build_config.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/metrics/public/cpp/ukm_recorder.h"
+#include "services/service_manager/public/cpp/interface_provider.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/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/frame/use_counter.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
@@ -103,8 +105,8 @@ AudioContext* AudioContext::Create(Document& document,
if (RuntimeEnabledFeatures::AutoplayIgnoresWebAudioEnabled()) {
document.AddConsoleMessage(ConsoleMessage::Create(
kOtherMessageSource, kWarningMessageLevel,
- "The Web Audio autoplay policy will be re-enabled in Chrome 70 (October"
- " 2018). Please check that your website is compatible with it. "
+ "The Web Audio autoplay policy will be re-enabled in Chrome 71 ("
+ "December 2018). Please check that your website is compatible with it. "
"https://goo.gl/7K7WLu"));
}
@@ -164,7 +166,6 @@ void AudioContext::Trace(blink::Visitor* visitor) {
ScriptPromise AudioContext::suspendContext(ScriptState* script_state) {
DCHECK(IsMainThread());
- GraphAutoLocker locker(this);
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
ScriptPromise promise = resolver->Promise();
@@ -468,4 +469,32 @@ void AudioContext::ContextDestroyed(ExecutionContext*) {
Uninitialize();
}
+void AudioContext::NotifyAudibleAudioStarted() {
+ DCHECK(IsMainThread());
+
+ if (!audio_context_manager_) {
+ Document* document = GetDocument();
+
+ // If there's no document don't bother to try to create the mojom interface.
+ // This can happen if the document has been reloaded while the audio thread
+ // is still running.
+ if (!document) {
+ return;
+ }
+
+ document->GetFrame()->GetInterfaceProvider().GetInterface(
+ mojo::MakeRequest(&audio_context_manager_));
+ }
+
+ DCHECK(audio_context_manager_);
+ audio_context_manager_->AudioContextAudiblePlaybackStarted(context_id_);
+}
+
+void AudioContext::NotifyAudibleAudioStopped() {
+ DCHECK(IsMainThread());
+ DCHECK(audio_context_manager_);
+
+ audio_context_manager_->AudioContextAudiblePlaybackStopped(context_id_);
+}
+
} // namespace blink
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 a239599207a..d93934e4e0c 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_context.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_context.h
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBAUDIO_AUDIO_CONTEXT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBAUDIO_AUDIO_CONTEXT_H_
+#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/core/html/media/autoplay_policy.h"
@@ -105,6 +106,11 @@ class MODULES_EXPORT AudioContext : public BaseAudioContext {
void DidClose();
+ // Send notification to browser that an AudioContext has started or stopped
+ // playing audible audio.
+ void NotifyAudibleAudioStarted() final;
+ void NotifyAudibleAudioStopped() final;
+
unsigned context_id_;
Member<ScriptPromiseResolver> close_resolver_;
@@ -123,6 +129,9 @@ class MODULES_EXPORT AudioContext : public BaseAudioContext {
// Records if start() was ever called for any source node in this context.
bool source_node_started_ = false;
+
+ // AudioContextManager for reporting audibility.
+ mojom::blink::AudioContextManagerPtr audio_context_manager_;
};
} // namespace blink
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 1fcc1afca2c..936f36d5465 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_node.cc
@@ -104,7 +104,7 @@ void AudioHandler::Uninitialize() {
void AudioHandler::Dispose() {
DCHECK(IsMainThread());
- DCHECK(Context()->IsGraphOwner());
+ Context()->AssertGraphOwner();
Context()->GetDeferredTaskHandler().RemoveChangedChannelCountMode(this);
Context()->GetDeferredTaskHandler().RemoveChangedChannelInterpretation(this);
@@ -364,7 +364,7 @@ void AudioHandler::ProcessIfNecessary(size_t frames_to_process) {
void AudioHandler::CheckNumberOfChannelsForInput(AudioNodeInput* input) {
DCHECK(Context()->IsAudioThread());
- DCHECK(Context()->IsGraphOwner());
+ Context()->AssertGraphOwner();
DCHECK(inputs_.Contains(input));
if (!inputs_.Contains(input))
@@ -406,7 +406,7 @@ void AudioHandler::UnsilenceOutputs() {
void AudioHandler::EnableOutputsIfNecessary() {
DCHECK(IsMainThread());
- DCHECK(Context()->IsGraphOwner());
+ Context()->AssertGraphOwner();
// We're enabling outputs for this handler. Remove this from the tail
// processing list (if it's there) so that we don't inadvertently disable the
@@ -431,7 +431,7 @@ void AudioHandler::EnableOutputsIfNecessary() {
void AudioHandler::DisableOutputsIfNecessary() {
// This function calls other functions that require graph ownership,
// so assert that this needs graph ownership too.
- DCHECK(Context()->IsGraphOwner());
+ Context()->AssertGraphOwner();
// Disable outputs if appropriate. We do this if the number of connections is
// 0 or 1. The case of 0 is from deref() where there are no connections left.
@@ -511,7 +511,7 @@ void AudioHandler::BreakConnection() {
}
void AudioHandler::BreakConnectionWithLock() {
- DCHECK(Context()->IsGraphOwner());
+ Context()->AssertGraphOwner();
AtomicDecrement(&connection_ref_count_);
@@ -593,7 +593,18 @@ unsigned AudioHandler::NumberOfOutputChannels() const {
// ----------------------------------------------------------------
AudioNode::AudioNode(BaseAudioContext& context)
- : context_(context), handler_(nullptr) {}
+ : context_(context),
+ deferred_task_handler_(&context.GetDeferredTaskHandler()),
+ handler_(nullptr) {}
+
+AudioNode::~AudioNode() {
+ // The graph lock is required to destroy the handler. And we can't use
+ // |context_| to touch it, since that object may also be a dead heap object.
+ {
+ DeferredTaskHandler::GraphAutoLocker locker(*deferred_task_handler_);
+ handler_ = nullptr;
+ }
+}
void AudioNode::Dispose() {
DCHECK(IsMainThread());
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 e16e9596b90..be391ade062 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_node.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_node.h
@@ -47,6 +47,7 @@ class AudioNodeOptions;
class AudioNodeInput;
class AudioNodeOutput;
class AudioParam;
+class DeferredTaskHandler;
class ExceptionState;
// An AudioNode is the basic building block for handling audio within an
@@ -314,6 +315,8 @@ class MODULES_EXPORT AudioNode : public EventTargetWithInlineData {
USING_PRE_FINALIZER(AudioNode, Dispose);
public:
+ ~AudioNode() override;
+
void Trace(blink::Visitor*) override;
AudioHandler& Handler() const;
@@ -367,7 +370,12 @@ class MODULES_EXPORT AudioNode : public EventTargetWithInlineData {
bool DisconnectFromOutputIfConnected(unsigned output_index, AudioParam&);
Member<BaseAudioContext> context_;
+
+ // Needed in the destructor, where |context_| is not guaranteed to be alive.
+ scoped_refptr<DeferredTaskHandler> deferred_task_handler_;
+
scoped_refptr<AudioHandler> handler_;
+
// Represents audio node graph with Oilpan references. N-th HeapHashSet
// represents a set of AudioNode objects connected to this AudioNode's N-th
// output.
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 e2124a84b7c..0e557c93e54 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
@@ -46,7 +46,7 @@ std::unique_ptr<AudioNodeInput> AudioNodeInput::Create(AudioHandler& handler) {
}
void AudioNodeInput::Connect(AudioNodeOutput& output) {
- DCHECK(GetDeferredTaskHandler().IsGraphOwner());
+ GetDeferredTaskHandler().AssertGraphOwner();
// Check if we're already connected to this output.
if (outputs_.Contains(&output))
@@ -58,7 +58,7 @@ void AudioNodeInput::Connect(AudioNodeOutput& output) {
}
void AudioNodeInput::Disconnect(AudioNodeOutput& output) {
- DCHECK(GetDeferredTaskHandler().IsGraphOwner());
+ GetDeferredTaskHandler().AssertGraphOwner();
// First try to disconnect from "active" connections.
if (outputs_.Contains(&output)) {
@@ -83,7 +83,7 @@ void AudioNodeInput::Disconnect(AudioNodeOutput& output) {
}
void AudioNodeInput::Disable(AudioNodeOutput& output) {
- DCHECK(GetDeferredTaskHandler().IsGraphOwner());
+ GetDeferredTaskHandler().AssertGraphOwner();
DCHECK(outputs_.Contains(&output));
disabled_outputs_.insert(&output);
@@ -95,7 +95,7 @@ void AudioNodeInput::Disable(AudioNodeOutput& output) {
}
void AudioNodeInput::Enable(AudioNodeOutput& output) {
- DCHECK(GetDeferredTaskHandler().IsGraphOwner());
+ GetDeferredTaskHandler().AssertGraphOwner();
// Move output from disabled list to active list.
outputs_.insert(&output);
@@ -115,7 +115,7 @@ void AudioNodeInput::DidUpdate() {
void AudioNodeInput::UpdateInternalBus() {
DCHECK(GetDeferredTaskHandler().IsAudioThread());
- DCHECK(GetDeferredTaskHandler().IsGraphOwner());
+ GetDeferredTaskHandler().AssertGraphOwner();
unsigned number_of_input_channels = NumberOfChannels();
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_node_output.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_node_output.cc
index c229c43406d..a90d51e2c62 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_node_output.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_node_output.cc
@@ -67,7 +67,7 @@ void AudioNodeOutput::Dispose() {
void AudioNodeOutput::SetNumberOfChannels(unsigned number_of_channels) {
DCHECK_LE(number_of_channels, BaseAudioContext::MaxNumberOfChannels());
- DCHECK(GetDeferredTaskHandler().IsGraphOwner());
+ GetDeferredTaskHandler().AssertGraphOwner();
desired_number_of_channels_ = number_of_channels;
@@ -99,7 +99,7 @@ void AudioNodeOutput::UpdateRenderingState() {
void AudioNodeOutput::UpdateNumberOfChannels() {
DCHECK(GetDeferredTaskHandler().IsAudioThread());
- DCHECK(GetDeferredTaskHandler().IsGraphOwner());
+ GetDeferredTaskHandler().AssertGraphOwner();
if (number_of_channels_ != desired_number_of_channels_) {
number_of_channels_ = desired_number_of_channels_;
@@ -110,7 +110,7 @@ void AudioNodeOutput::UpdateNumberOfChannels() {
void AudioNodeOutput::PropagateChannelCount() {
DCHECK(GetDeferredTaskHandler().IsAudioThread());
- DCHECK(GetDeferredTaskHandler().IsGraphOwner());
+ GetDeferredTaskHandler().AssertGraphOwner();
if (IsChannelCountKnown()) {
// Announce to any nodes we're connected to that we changed our channel
@@ -149,12 +149,12 @@ AudioBus* AudioNodeOutput::Bus() const {
}
unsigned AudioNodeOutput::FanOutCount() {
- DCHECK(GetDeferredTaskHandler().IsGraphOwner());
+ GetDeferredTaskHandler().AssertGraphOwner();
return inputs_.size();
}
unsigned AudioNodeOutput::ParamFanOutCount() {
- DCHECK(GetDeferredTaskHandler().IsGraphOwner());
+ GetDeferredTaskHandler().AssertGraphOwner();
return params_.size();
}
@@ -163,19 +163,19 @@ unsigned AudioNodeOutput::RenderingFanOutCount() const {
}
void AudioNodeOutput::AddInput(AudioNodeInput& input) {
- DCHECK(GetDeferredTaskHandler().IsGraphOwner());
+ GetDeferredTaskHandler().AssertGraphOwner();
inputs_.insert(&input);
input.Handler().MakeConnection();
}
void AudioNodeOutput::RemoveInput(AudioNodeInput& input) {
- DCHECK(GetDeferredTaskHandler().IsGraphOwner());
+ GetDeferredTaskHandler().AssertGraphOwner();
input.Handler().BreakConnectionWithLock();
inputs_.erase(&input);
}
void AudioNodeOutput::DisconnectAllInputs() {
- DCHECK(GetDeferredTaskHandler().IsGraphOwner());
+ GetDeferredTaskHandler().AssertGraphOwner();
// AudioNodeInput::disconnect() changes m_inputs by calling removeInput().
while (!inputs_.IsEmpty())
@@ -183,29 +183,29 @@ void AudioNodeOutput::DisconnectAllInputs() {
}
void AudioNodeOutput::DisconnectInput(AudioNodeInput& input) {
- DCHECK(GetDeferredTaskHandler().IsGraphOwner());
+ GetDeferredTaskHandler().AssertGraphOwner();
DCHECK(IsConnectedToInput(input));
input.Disconnect(*this);
}
void AudioNodeOutput::DisconnectAudioParam(AudioParamHandler& param) {
- DCHECK(GetDeferredTaskHandler().IsGraphOwner());
+ GetDeferredTaskHandler().AssertGraphOwner();
DCHECK(IsConnectedToAudioParam(param));
param.Disconnect(*this);
}
void AudioNodeOutput::AddParam(AudioParamHandler& param) {
- DCHECK(GetDeferredTaskHandler().IsGraphOwner());
+ GetDeferredTaskHandler().AssertGraphOwner();
params_.insert(&param);
}
void AudioNodeOutput::RemoveParam(AudioParamHandler& param) {
- DCHECK(GetDeferredTaskHandler().IsGraphOwner());
+ GetDeferredTaskHandler().AssertGraphOwner();
params_.erase(&param);
}
void AudioNodeOutput::DisconnectAllParams() {
- DCHECK(GetDeferredTaskHandler().IsGraphOwner());
+ GetDeferredTaskHandler().AssertGraphOwner();
// AudioParam::disconnect() changes m_params by calling removeParam().
while (!params_.IsEmpty())
@@ -218,17 +218,17 @@ void AudioNodeOutput::DisconnectAll() {
}
bool AudioNodeOutput::IsConnectedToInput(AudioNodeInput& input) {
- DCHECK(GetDeferredTaskHandler().IsGraphOwner());
+ GetDeferredTaskHandler().AssertGraphOwner();
return inputs_.Contains(&input);
}
bool AudioNodeOutput::IsConnectedToAudioParam(AudioParamHandler& param) {
- DCHECK(GetDeferredTaskHandler().IsGraphOwner());
+ GetDeferredTaskHandler().AssertGraphOwner();
return params_.Contains(&param);
}
void AudioNodeOutput::Disable() {
- DCHECK(GetDeferredTaskHandler().IsGraphOwner());
+ GetDeferredTaskHandler().AssertGraphOwner();
if (is_enabled_) {
is_enabled_ = false;
@@ -238,7 +238,7 @@ void AudioNodeOutput::Disable() {
}
void AudioNodeOutput::Enable() {
- DCHECK(GetDeferredTaskHandler().IsGraphOwner());
+ GetDeferredTaskHandler().AssertGraphOwner();
if (!is_enabled_) {
is_enabled_ = true;
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 2d596c59c27..eb6008313aa 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_param.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_param.cc
@@ -295,7 +295,7 @@ void AudioParamHandler::CalculateTimelineValues(float* values,
}
void AudioParamHandler::Connect(AudioNodeOutput& output) {
- DCHECK(GetDeferredTaskHandler().IsGraphOwner());
+ GetDeferredTaskHandler().AssertGraphOwner();
if (outputs_.Contains(&output))
return;
@@ -306,7 +306,7 @@ void AudioParamHandler::Connect(AudioNodeOutput& output) {
}
void AudioParamHandler::Disconnect(AudioNodeOutput& output) {
- DCHECK(GetDeferredTaskHandler().IsGraphOwner());
+ GetDeferredTaskHandler().AssertGraphOwner();
if (outputs_.Contains(&output)) {
outputs_.erase(&output);
@@ -339,7 +339,8 @@ AudioParam::AudioParam(BaseAudioContext& context,
rate_mode,
min_value,
max_value)),
- context_(context) {}
+ context_(context),
+ deferred_task_handler_(&context.GetDeferredTaskHandler()) {}
AudioParam* AudioParam::Create(BaseAudioContext& context,
AudioParamType param_type,
@@ -364,6 +365,15 @@ AudioParam* AudioParam::Create(BaseAudioContext& context,
min_value, max_value);
}
+AudioParam::~AudioParam() {
+ // The graph lock is required to destroy the handler. And we can't use
+ // |context_| to touch it, since that object may also be a dead heap object.
+ {
+ DeferredTaskHandler::GraphAutoLocker locker(*deferred_task_handler_);
+ handler_ = nullptr;
+ }
+}
+
void AudioParam::Trace(blink::Visitor* visitor) {
visitor->Trace(context_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_param.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_param.h
index 96c782dc57a..1dfb251c0a2 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_param.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_param.h
@@ -270,6 +270,8 @@ class AudioParam final : public ScriptWrappable {
float min_value = -std::numeric_limits<float>::max(),
float max_value = std::numeric_limits<float>::max());
+ ~AudioParam() override;
+
void Trace(blink::Visitor*) override;
// |handler| always returns a valid object.
AudioParamHandler& Handler() const { return *handler_; }
@@ -325,6 +327,8 @@ class AudioParam final : public ScriptWrappable {
scoped_refptr<AudioParamHandler> handler_;
Member<BaseAudioContext> context_;
+ // Needed in the destructor, where |context_| is not guaranteed to be alive.
+ scoped_refptr<DeferredTaskHandler> deferred_task_handler_;
};
} // namespace blink
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 12737c6e218..a7db4bac113 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
@@ -493,8 +493,8 @@ void AudioParamTimeline::SetValueCurveAtTime(const Vector<float>& curve,
if (curve.size() < 2) {
exception_state.ThrowDOMException(
DOMExceptionCode::kInvalidStateError,
- ExceptionMessages::IndexExceedsMinimumBound(
- "curve length", curve.size(), static_cast<size_t>(2)));
+ ExceptionMessages::IndexExceedsMinimumBound("curve length",
+ curve.size(), 2u));
return;
}
@@ -1860,106 +1860,6 @@ unsigned AudioParamTimeline::FillWithDefault(float* values,
return index;
}
-std::tuple<bool, size_t> AudioParamTimeline::EventAtFrame(
- size_t current_frame,
- float sample_rate) const {
-
- size_t number_of_events = events_.size();
- ParamEvent* event = nullptr;
- ParamEvent* next_event = nullptr;
- size_t current_event_index = 0;
-
- for (current_event_index = 0; current_event_index < number_of_events;
- ++current_event_index) {
- event = events_[current_event_index].get();
- next_event = current_event_index < number_of_events - 1
- ? events_[current_event_index + 1].get()
- : nullptr;
-
- // Exit when we find a current event
- if (IsEventCurrent(event, next_event, current_frame, sample_rate)) {
- break;
- }
- }
-
- // No current event, so no conflict.
- if (current_event_index >= number_of_events) {
- return std::make_tuple(false, 0);
- }
-
- double current_time = current_frame / sample_rate;
-
- // Determine if setting the value at this time would overlap some
- // event.
- if (next_event) {
- // There's a following event. If the current event has ended
- // and the next event hasn't started, then there's no conflict.
- ParamEvent::Type next_type = next_event->GetType();
- switch (event->GetType()) {
- case ParamEvent::kSetValue:
- case ParamEvent::kLinearRampToValue:
- case ParamEvent::kExponentialRampToValue:
- // The current event is happening right now or is in the
- // past and is followed by some automation that starts in
- // the future (like SetValue, SetTarget, etc.). Then
- // there's no overlap. Otherwise there is.
- if (current_time < next_event->Time() &&
- (next_type == ParamEvent::kSetValue ||
- next_type == ParamEvent::kSetTarget ||
- next_type == ParamEvent::kSetValueCurve)) {
- return std::make_tuple(false, 0);
- }
- return std::make_tuple(true, current_event_index);
- break;
- default:
- return std::make_tuple(true, current_event_index);
- }
- }
-
- // No next event.
- switch (event->GetType()) {
- case ParamEvent::kSetValue:
- return std::make_tuple(false, 0);
- case ParamEvent::kSetValueCurve:
- if (current_time <= event->Time() + event->Duration()) {
- return std::make_tuple(true, current_event_index);
- }
- break;
- case ParamEvent::kSetTarget:
- if (current_time >= event->Time()) {
- return std::make_tuple(true, current_event_index);
- }
- break;
- default:
- break;
- }
-
- return std::make_tuple(false, 0);
-}
-
-// TODO(crbug.com/764396): Remove this when fixed.
-void AudioParamTimeline::WarnSetterOverlapsEvent(
- String param_name,
- size_t event_index,
- BaseAudioContext& context) const {
-
- DCHECK_LT(event_index, events_.size());
-
- ParamEvent* event = events_[event_index].get();
- size_t next_index = event_index + 1;
- ParamEvent* next =
- next_index < events_.size() ? events_[next_index].get() : nullptr;
-
- String message = EventToString(*event) +
- (next ? " to " + EventToString(*next) : String(""));
-
- context.GetExecutionContext()->AddConsoleMessage(
- ConsoleMessage::Create(kJSMessageSource, kWarningMessageLevel,
- param_name + ".value setter called at time " +
- String::Number(context.currentTime(), 16) +
- " overlaps event " + message));
-}
-
void AudioParamTimeline::RemoveCancelledEvents(size_t first_event_to_remove) {
// For all the events that are being removed, also remove that event
// from |new_events_|.
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_param_timeline.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_param_timeline.h
index a37f8b05678..e0cf3cd4825 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_param_timeline.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_param_timeline.h
@@ -445,22 +445,6 @@ class AudioParamTimeline {
size_t end_frame,
unsigned write_index);
- // TODO(crbug.com/764396): Remove these two methods when the bug is fixed.
-
- // |EventAtFrame| finds the current event that would run at the specified
- // |frame|. The first return value is true if a setValueAtTime call would
- // overlap some ongoing event. The second return value is the index of the
- // current event. The second value must be ignored if the first value is
- // false.
- std::tuple<bool, size_t> EventAtFrame(size_t frame, float sample_rate) const;
-
- // Prints a console warning that a call to the AudioParam value setter
- // overlaps the event at |event_index|. |param_name| is the name of the
- // AudioParam where the where this is happening.
- void WarnSetterOverlapsEvent(String param_name,
- size_t event_index,
- BaseAudioContext&) const;
-
// When cancelling events, remove the items from |events_| starting
// at the given index. Update |new_events_| too.
void RemoveCancelledEvents(size_t first_event_to_remove);
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 3c3dbedc9b7..b580ddffe2a 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
@@ -24,6 +24,8 @@
*/
#include "third_party/blink/renderer/modules/webaudio/audio_processing_event.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 {
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_node.cc
index 27936b87f28..4c6c0e4baa3 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_node.cc
@@ -54,20 +54,26 @@ AudioScheduledSourceHandler::AudioScheduledSourceHandler(NodeType node_type,
}
}
-void AudioScheduledSourceHandler::UpdateSchedulingInfo(
- size_t quantum_frame_size,
- AudioBus* output_bus,
- size_t& quantum_frame_offset,
- size_t& non_silent_frames_to_process,
- double& start_frame_offset) {
+std::tuple<size_t, size_t, double>
+AudioScheduledSourceHandler::UpdateSchedulingInfo(size_t quantum_frame_size,
+ AudioBus* output_bus) {
+ // Set up default values for the three return values.
+ size_t quantum_frame_offset = 0;
+ size_t non_silent_frames_to_process = 0;
+ double start_frame_offset = 0;
+
DCHECK(output_bus);
- if (!output_bus)
- return;
+ if (!output_bus) {
+ return std::make_tuple(quantum_frame_offset, non_silent_frames_to_process,
+ start_frame_offset);
+ }
DCHECK_EQ(quantum_frame_size,
static_cast<size_t>(AudioUtilities::kRenderQuantumFrames));
- if (quantum_frame_size != AudioUtilities::kRenderQuantumFrames)
- return;
+ if (quantum_frame_size != AudioUtilities::kRenderQuantumFrames) {
+ return std::make_tuple(quantum_frame_offset, non_silent_frames_to_process,
+ start_frame_offset);
+ }
double sample_rate = Context()->sampleRate();
@@ -96,7 +102,8 @@ void AudioScheduledSourceHandler::UpdateSchedulingInfo(
// Output silence.
output_bus->Zero();
non_silent_frames_to_process = 0;
- return;
+ return std::make_tuple(quantum_frame_offset, non_silent_frames_to_process,
+ start_frame_offset);
}
// Check if it's time to start playing.
@@ -119,7 +126,8 @@ void AudioScheduledSourceHandler::UpdateSchedulingInfo(
if (!non_silent_frames_to_process) {
// Output silence.
output_bus->Zero();
- return;
+ return std::make_tuple(quantum_frame_offset, non_silent_frames_to_process,
+ start_frame_offset);
}
// Handle silence before we start playing.
@@ -158,7 +166,8 @@ void AudioScheduledSourceHandler::UpdateSchedulingInfo(
Finish();
}
- return;
+ return std::make_tuple(quantum_frame_offset, non_silent_frames_to_process,
+ start_frame_offset);
}
void AudioScheduledSourceHandler::Start(double when,
@@ -243,7 +252,7 @@ void AudioScheduledSourceHandler::NotifyEnded() {
if (!Context() || !Context()->GetExecutionContext())
return;
if (GetNode())
- GetNode()->DispatchEvent(Event::Create(EventTypeNames::ended));
+ GetNode()->DispatchEvent(*Event::Create(EventTypeNames::ended));
}
// ----------------------------------------------------------------
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 bf0256597dd..27a25b70390 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
@@ -91,7 +91,9 @@ class AudioScheduledSourceHandler : public AudioHandler {
// zeroing out portions of the outputBus which are outside the range of
// startFrame and endFrame.
//
- // Each frame time is relative to the context's currentSampleFrame().
+ // Each frame time is relative to the context's currentSampleFrame(). Three
+ // values are returned, in this order:
+ //
// quantumFrameOffset : Offset frame in this time quantum to start
// rendering.
// nonSilentFramesToProcess : Number of frames rendering non-silence (will be
@@ -100,11 +102,12 @@ class AudioScheduledSourceHandler : public AudioHandler {
// and the actual starting time of the source. This is
// non-zero only when transitioning from the
// SCHEDULED_STATE to the PLAYING_STATE.
- void UpdateSchedulingInfo(size_t quantum_frame_size,
- AudioBus* output_bus,
- size_t& quantum_frame_offset,
- size_t& non_silent_frames_to_process,
- double& start_frame_offset);
+ //
+ // Callers should check nonSilentFramesToProcess to decide what to
+ // do. If it is zero, the other return values are meaningless.
+ std::tuple<size_t, size_t, double> UpdateSchedulingInfo(
+ size_t quantum_frame_size,
+ AudioBus* output_bus);
// Called when we have no more sound to play or the stop() time has been
// reached. No onEnded event is called.
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_summing_junction.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_summing_junction.cc
index 4146dd2e74f..83a58f4223c 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_summing_junction.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_summing_junction.cc
@@ -33,11 +33,12 @@ AudioSummingJunction::AudioSummingJunction(DeferredTaskHandler& handler)
: deferred_task_handler_(&handler), rendering_state_need_updating_(false) {}
AudioSummingJunction::~AudioSummingJunction() {
+ GetDeferredTaskHandler().AssertGraphOwner();
GetDeferredTaskHandler().RemoveMarkedSummingJunction(this);
}
void AudioSummingJunction::ChangedOutputs() {
- DCHECK(GetDeferredTaskHandler().IsGraphOwner());
+ GetDeferredTaskHandler().AssertGraphOwner();
if (!rendering_state_need_updating_) {
GetDeferredTaskHandler().MarkSummingJunctionDirty(this);
rendering_state_need_updating_ = true;
@@ -46,7 +47,7 @@ void AudioSummingJunction::ChangedOutputs() {
void AudioSummingJunction::UpdateRenderingState() {
DCHECK(GetDeferredTaskHandler().IsAudioThread());
- DCHECK(GetDeferredTaskHandler().IsGraphOwner());
+ GetDeferredTaskHandler().AssertGraphOwner();
if (rendering_state_need_updating_) {
// Copy from m_outputs to m_renderingOutputs.
rendering_outputs_.resize(outputs_.size());
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 dd82c715c43..ab36e530610 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet.h
@@ -24,8 +24,6 @@ class MODULES_EXPORT AudioWorklet final : public Worklet {
WTF_MAKE_NONCOPYABLE(AudioWorklet);
public:
- // When the AudioWorklet runtime flag is not enabled, this constructor returns
- // |nullptr|.
static AudioWorklet* Create(BaseAudioContext*);
~AudioWorklet() override = default;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.idl b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.idl
index ccdbf87c183..150a4018bbb 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.idl
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.idl
@@ -8,7 +8,9 @@
Exposed=AudioWorklet,
Global=(Worklet,AudioWorklet)
] interface AudioWorkletGlobalScope : WorkletGlobalScope {
- [RaisesException, MeasureAs=AudioWorkletGlobalScopeRegisterProcessor] void registerProcessor(DOMString name, Function processorConstructor);
+ // TODO(yukishiino): |processorConstructor| should be of callback function
+ // type (should be: callback T = any ()).
+ [RaisesException, MeasureAs=AudioWorkletGlobalScopeRegisterProcessor] void registerProcessor(DOMString name, CallbackFunctionTreatedAsScriptValue processorConstructor);
readonly attribute unsigned long long currentFrame;
readonly attribute double currentTime;
readonly attribute float sampleRate;
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 59e564d2255..d2130f08b8a 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
@@ -65,14 +65,15 @@ class AudioWorkletGlobalScopeTest : public PageTestBase {
std::unique_ptr<AudioWorkletThread> CreateAudioWorkletThread() {
std::unique_ptr<AudioWorkletThread> thread =
- AudioWorkletThread::Create(nullptr, *reporting_proxy_);
+ AudioWorkletThread::Create(*reporting_proxy_);
Document* document = &GetDocument();
thread->Start(
std::make_unique<GlobalScopeCreationParams>(
document->Url(), ScriptType::kModule, document->UserAgent(),
Vector<CSPHeaderAndType>(), document->GetReferrerPolicy(),
document->GetSecurityOrigin(), document->IsSecureContext(),
- nullptr /* worker_clients */, document->AddressSpace(),
+ document->GetHttpsState(), nullptr /* worker_clients */,
+ document->AddressSpace(),
OriginTrialContext::GetTokens(document).get(),
base::UnguessableToken::Create(), nullptr /* worker_settings */,
kV8CacheOptionsDefault, new WorkletModuleResponsesMap),
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_messaging_proxy.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_messaging_proxy.cc
index 479330b64c2..b9d26b3fa31 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_messaging_proxy.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_messaging_proxy.cc
@@ -93,8 +93,7 @@ AudioWorkletMessagingProxy::CreateObjectProxy(
}
std::unique_ptr<WorkerThread> AudioWorkletMessagingProxy::CreateWorkerThread() {
- return AudioWorkletThread::Create(CreateThreadableLoadingContext(),
- WorkletObjectProxy());
+ return AudioWorkletThread::Create(WorkletObjectProxy());
}
void AudioWorkletMessagingProxy::Trace(Visitor* visitor) {
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 7dc449ad697..d74292811d0 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
@@ -129,7 +129,7 @@ void AudioWorkletHandler::Process(size_t frames_to_process) {
void AudioWorkletHandler::CheckNumberOfChannelsForInput(AudioNodeInput* input) {
DCHECK(Context()->IsAudioThread());
- DCHECK(Context()->IsGraphOwner());
+ Context()->AssertGraphOwner();
DCHECK(input);
// Dynamic channel count only works when the node has 1 input and 1 output.
@@ -379,7 +379,7 @@ MessagePort* AudioWorkletNode::port() const {
}
void AudioWorkletNode::FireProcessorError() {
- DispatchEvent(Event::Create(EventTypeNames::processorerror));
+ DispatchEvent(*Event::Create(EventTypeNames::processorerror));
}
scoped_refptr<AudioWorkletHandler> AudioWorkletNode::GetWorkletHandler() const {
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_thread.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_thread.cc
index 312cb3aa988..bf6104358df 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_thread.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_thread.cc
@@ -23,32 +23,29 @@ namespace blink {
template class WorkletThreadHolder<AudioWorkletThread>;
-WebThread* AudioWorkletThread::s_backing_thread_ = nullptr;
-
unsigned AudioWorkletThread::s_ref_count_ = 0;
std::unique_ptr<AudioWorkletThread> AudioWorkletThread::Create(
- ThreadableLoadingContext* loading_context,
WorkerReportingProxy& worker_reporting_proxy) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("audio-worklet"),
"AudioWorkletThread::create");
- return base::WrapUnique(
- new AudioWorkletThread(loading_context, worker_reporting_proxy));
+ return base::WrapUnique(new AudioWorkletThread(worker_reporting_proxy));
}
AudioWorkletThread::AudioWorkletThread(
- ThreadableLoadingContext* loading_context,
WorkerReportingProxy& worker_reporting_proxy)
- : WorkerThread(loading_context, worker_reporting_proxy) {
+ : WorkerThread(worker_reporting_proxy) {
DCHECK(IsMainThread());
- if (++s_ref_count_ == 1)
+ if (++s_ref_count_ == 1) {
EnsureSharedBackingThread();
+ }
}
AudioWorkletThread::~AudioWorkletThread() {
DCHECK(IsMainThread());
- if (--s_ref_count_ == 0)
+ if (--s_ref_count_ == 0) {
ClearSharedBackingThread();
+ }
}
WorkerBackingThread& AudioWorkletThread::GetWorkerBackingThread() {
@@ -75,18 +72,14 @@ void AudioWorkletThread::CollectAllGarbage() {
void AudioWorkletThread::EnsureSharedBackingThread() {
DCHECK(IsMainThread());
- if (!s_backing_thread_)
- s_backing_thread_ = Platform::Current()->CreateWebAudioThread().release();
- WorkletThreadHolder<AudioWorkletThread>::EnsureInstance(s_backing_thread_);
+ WorkletThreadHolder<AudioWorkletThread>::EnsureInstance(
+ WebThreadCreationParams(blink::WebThreadType::kWebAudioThread));
}
void AudioWorkletThread::ClearSharedBackingThread() {
DCHECK(IsMainThread());
- DCHECK(s_backing_thread_);
DCHECK_EQ(s_ref_count_, 0u);
WorkletThreadHolder<AudioWorkletThread>::ClearInstance();
- delete s_backing_thread_;
- s_backing_thread_ = nullptr;
}
WebThread* AudioWorkletThread::GetSharedBackingThread() {
@@ -97,9 +90,8 @@ WebThread* AudioWorkletThread::GetSharedBackingThread() {
}
void AudioWorkletThread::CreateSharedBackingThreadForTest() {
- if (!s_backing_thread_)
- s_backing_thread_ = Platform::Current()->CreateWebAudioThread().release();
- WorkletThreadHolder<AudioWorkletThread>::CreateForTest(s_backing_thread_);
+ WorkletThreadHolder<AudioWorkletThread>::CreateForTest(
+ WebThreadCreationParams(blink::WebThreadType::kWebAudioThread));
}
WorkerOrWorkletGlobalScope* AudioWorkletThread::CreateWorkerGlobalScope(
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_thread.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_thread.h
index 0277ad51102..3181902f9c7 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_thread.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_thread.h
@@ -12,18 +12,15 @@
namespace blink {
-class WebThread;
class WorkerReportingProxy;
-// AudioWorkletThread is a per-frame singleton object that represents the
-// backing thread for the processing of AudioWorkletNode/AudioWorkletProcessor.
-// It is supposed to run an instance of V8 isolate. The life cycle of this
-// object is managed by the reference counting of the static backing thread.
+// AudioWorkletThread is a per-frame singleton object that has a reference count
+// to the backing thread for the processing of AudioWorkletNode and
+// AudioWorkletProcessor.
class MODULES_EXPORT AudioWorkletThread final : public WorkerThread {
public:
- static std::unique_ptr<AudioWorkletThread> Create(ThreadableLoadingContext*,
- WorkerReportingProxy&);
+ static std::unique_ptr<AudioWorkletThread> Create(WorkerReportingProxy&);
~AudioWorkletThread() override;
WorkerBackingThread& GetWorkerBackingThread() override;
@@ -45,7 +42,7 @@ class MODULES_EXPORT AudioWorkletThread final : public WorkerThread {
static WebThread* GetSharedBackingThread();
private:
- AudioWorkletThread(ThreadableLoadingContext*, WorkerReportingProxy&);
+ explicit AudioWorkletThread(WorkerReportingProxy&);
WorkerOrWorkletGlobalScope* CreateWorkerGlobalScope(
std::unique_ptr<GlobalScopeCreationParams>) final;
@@ -56,10 +53,6 @@ class MODULES_EXPORT AudioWorkletThread final : public WorkerThread {
return WebThreadType::kAudioWorkletThread;
}
- // This raw pointer gets assigned in EnsureSharedBackingThread() and manually
- // released by ClearSharedBackingThread().
- static WebThread* s_backing_thread_;
-
// This is only accessed by the main thread. Incremented by the constructor,
// and decremented by destructor.
static unsigned s_ref_count_;
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 060c0164670..8c54cadf397 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
@@ -49,14 +49,15 @@ class AudioWorkletThreadTest : public PageTestBase {
std::unique_ptr<AudioWorkletThread> CreateAudioWorkletThread() {
std::unique_ptr<AudioWorkletThread> thread =
- AudioWorkletThread::Create(nullptr, *reporting_proxy_);
+ AudioWorkletThread::Create(*reporting_proxy_);
Document* document = &GetDocument();
thread->Start(
std::make_unique<GlobalScopeCreationParams>(
document->Url(), ScriptType::kModule, document->UserAgent(),
Vector<CSPHeaderAndType>(), document->GetReferrerPolicy(),
document->GetSecurityOrigin(), document->IsSecureContext(),
- nullptr /* worker_clients */, document->AddressSpace(),
+ document->GetHttpsState(), nullptr /* worker_clients */,
+ document->AddressSpace(),
OriginTrialContext::GetTokens(document).get(),
base::UnguessableToken::Create(), nullptr /* worker_settings */,
kV8CacheOptionsDefault, new 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 f30bd880a15..27cf8f0e928 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
@@ -69,12 +69,13 @@
#include "third_party/blink/renderer/modules/webaudio/script_processor_node.h"
#include "third_party/blink/renderer/modules/webaudio/stereo_panner_node.h"
#include "third_party/blink/renderer/modules/webaudio/wave_shaper_node.h"
-#include "third_party/blink/renderer/platform/uuid.h"
#include "third_party/blink/renderer/platform/audio/iir_filter.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/bindings/script_state.h"
#include "third_party/blink/renderer/platform/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/histogram.h"
+#include "third_party/blink/renderer/platform/uuid.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
@@ -104,6 +105,13 @@ BaseAudioContext::BaseAudioContext(Document* document,
output_position_() {}
BaseAudioContext::~BaseAudioContext() {
+ {
+ // We may need to destroy summing junctions, which must happen while this
+ // object is still valid and with the graph lock held.
+ GraphAutoLocker locker(this);
+ destination_handler_ = nullptr;
+ }
+
GetDeferredTaskHandler().ContextWillBeDestroyed();
DCHECK(!active_source_nodes_.size());
DCHECK(!is_resolving_resume_promises_);
@@ -619,6 +627,16 @@ void BaseAudioContext::SetContextState(AudioContextState new_state) {
context_state_ = new_state;
+ // Audibility checks only happen when the context is running so manual
+ // notification is required when the context gets suspended or closed.
+ if (was_audible_ && context_state_ != kRunning) {
+ was_audible_ = false;
+ PostCrossThreadTask(
+ *Platform::Current()->MainThread()->GetTaskRunner(), FROM_HERE,
+ CrossThreadBind(&BaseAudioContext::NotifyAudibleAudioStopped,
+ WrapCrossThreadPersistent(this)));
+ }
+
// Notify context that state changed
if (GetExecutionContext()) {
GetExecutionContext()
@@ -629,7 +647,7 @@ void BaseAudioContext::SetContextState(AudioContextState new_state) {
}
void BaseAudioContext::NotifyStateChange() {
- DispatchEvent(Event::Create(EventTypeNames::statechange));
+ DispatchEvent(*Event::Create(EventTypeNames::statechange));
}
void BaseAudioContext::NotifySourceNodeFinishedProcessing(
@@ -663,7 +681,7 @@ void BaseAudioContext::ReleaseActiveSourceNodes() {
void BaseAudioContext::HandleStoppableSourceNodes() {
DCHECK(IsAudioThread());
- DCHECK(IsGraphOwner());
+ AssertGraphOwner();
if (finished_source_handlers_.size())
ScheduleMainThreadCleanup();
@@ -695,7 +713,24 @@ void BaseAudioContext::HandlePreRenderTasks(
}
}
-void BaseAudioContext::HandlePostRenderTasks() {
+// Determine if the rendered data is audible.
+static bool IsAudible(const AudioBus* rendered_data) {
+ // Compute the energy in each channel and sum up the energy in each channel
+ // for the total energy.
+ float energy = 0;
+
+ unsigned data_size = rendered_data->length();
+ for (unsigned k = 0; k < rendered_data->NumberOfChannels(); ++k) {
+ const float* data = rendered_data->Channel(k)->Data();
+ float channel_energy;
+ VectorMath::Vsvesq(data, 1, &channel_energy, data_size);
+ energy += channel_energy;
+ }
+
+ return energy > 0;
+}
+
+void BaseAudioContext::HandlePostRenderTasks(const AudioBus* destination_bus) {
DCHECK(IsAudioThread());
// Must use a tryLock() here too. Don't worry, the lock will very rarely be
@@ -712,6 +747,32 @@ void BaseAudioContext::HandlePostRenderTasks() {
unlock();
}
+
+ // Notify browser if audible audio has started or stopped.
+ if (HasRealtimeConstraint()) {
+ // Detect silence (or not) for MEI
+ bool is_audible = IsAudible(destination_bus);
+
+ if (is_audible) {
+ ++total_audible_renders_;
+ }
+
+ if (was_audible_ != is_audible) {
+ // Audibility changed in this render, so report the change.
+ was_audible_ = is_audible;
+ if (is_audible) {
+ PostCrossThreadTask(
+ *Platform::Current()->MainThread()->GetTaskRunner(), FROM_HERE,
+ CrossThreadBind(&BaseAudioContext::NotifyAudibleAudioStarted,
+ WrapCrossThreadPersistent(this)));
+ } else {
+ PostCrossThreadTask(
+ *Platform::Current()->MainThread()->GetTaskRunner(), FROM_HERE,
+ CrossThreadBind(&BaseAudioContext::NotifyAudibleAudioStopped,
+ WrapCrossThreadPersistent(this)));
+ }
+ }
+ }
}
void BaseAudioContext::PerformCleanupOnMainThread() {
@@ -798,7 +859,7 @@ void BaseAudioContext::ResolvePromisesForUnpause() {
// This runs inside the BaseAudioContext's lock when handling pre-render
// tasks.
DCHECK(IsAudioThread());
- DCHECK(IsGraphOwner());
+ AssertGraphOwner();
// Resolve any pending promises created by resume(). Only do this if we
// haven't already started resolving these promises. This gets called very
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 f55e32c4b70..fadb4834357 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
@@ -245,7 +245,7 @@ class MODULES_EXPORT BaseAudioContext
void HandlePreRenderTasks(const AudioIOPosition& output_position);
// Called at the end of each render quantum.
- void HandlePostRenderTasks();
+ void HandlePostRenderTasks(const AudioBus* destination_bus);
DeferredTaskHandler& GetDeferredTaskHandler() const {
return *deferred_task_handler_;
@@ -262,8 +262,8 @@ class MODULES_EXPORT BaseAudioContext
bool TryLock() { return GetDeferredTaskHandler().TryLock(); }
void unlock() { GetDeferredTaskHandler().unlock(); }
- // Returns true if this thread owns the context's lock.
- bool IsGraphOwner() { return GetDeferredTaskHandler().IsGraphOwner(); }
+ // In DCHECK builds, fails if this thread does not own the context's lock.
+ void AssertGraphOwner() const { GetDeferredTaskHandler().AssertGraphOwner(); }
using GraphAutoLocker = DeferredTaskHandler::GraphAutoLocker;
@@ -452,6 +452,20 @@ class MODULES_EXPORT BaseAudioContext
// This cannot be nullptr once it is assigned from AudioWorkletThread until
// the BaseAudioContext goes away.
WorkerThread* audio_worklet_thread_ = nullptr;
+
+ // Notifies browser when audible audio starts or stops. This should
+ // only apply for AudioContexts.
+ virtual void NotifyAudibleAudioStarted() { NOTREACHED(); }
+ virtual void NotifyAudibleAudioStopped() { NOTREACHED(); }
+
+ // Keeps track if the output of this destination was audible, before the
+ // current rendering quantum. Used for recording "playback" time.
+ bool was_audible_ = false;
+
+ // Counts the number of render quanta where audible sound was played. We
+ // determine audibility on render quantum boundaries, so counting quanta is
+ // all that's needed.
+ size_t total_audible_renders_ = 0;
};
} // namespace blink
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 75a87fd2eb4..21349c352e8 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
@@ -61,8 +61,9 @@ void ConstantSourceHandler::Process(size_t frames_to_process) {
// Figure out where in the current rendering quantum that the source is
// active and for how many frames.
- UpdateSchedulingInfo(frames_to_process, output_bus, quantum_frame_offset,
- non_silent_frames_to_process, start_frame_offset);
+ std::tie(quantum_frame_offset, non_silent_frames_to_process,
+ start_frame_offset) =
+ UpdateSchedulingInfo(frames_to_process, output_bus);
if (!non_silent_frames_to_process) {
output_bus->Zero();
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 2d73dfee3ab..372008bc98a 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/convolver_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/convolver_node.cc
@@ -241,7 +241,7 @@ void ConvolverHandler::SetChannelCountMode(const String& mode,
void ConvolverHandler::CheckNumberOfChannelsForInput(AudioNodeInput* input) {
DCHECK(Context()->IsAudioThread());
- DCHECK(Context()->IsGraphOwner());
+ Context()->AssertGraphOwner();
DCHECK(input);
DCHECK_EQ(input, &this->Input(0));
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/default_audio_destination_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/default_audio_destination_node.cc
index a5427bff57a..0e5675e2bd1 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/default_audio_destination_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/default_audio_destination_node.cc
@@ -197,7 +197,7 @@ void DefaultAudioDestinationHandler::Render(
Context()->GetDeferredTaskHandler().ProcessAutomaticPullNodes(
number_of_frames);
- Context()->HandlePostRenderTasks();
+ Context()->HandlePostRenderTasks(destination_bus);
// Advances the current sample-frame.
size_t new_sample_frame = current_sample_frame_ + number_of_frames;
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 d0115b1065c..70131fea333 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
@@ -68,16 +68,6 @@ void DeferredTaskHandler::OfflineLock() {
context_graph_mutex_.lock();
}
-bool DeferredTaskHandler::IsGraphOwner() {
-#if DCHECK_IS_ON()
- return context_graph_mutex_.Locked();
-#else
- // The method is only used inside of DCHECK() so it must be no-op in the
- // release build. Returning false so we can catch when it happens.
- return false;
-#endif
-}
-
void DeferredTaskHandler::AddDeferredBreakConnection(AudioHandler& node) {
DCHECK(IsAudioThread());
deferred_break_connection_list_.push_back(&node);
@@ -85,7 +75,7 @@ void DeferredTaskHandler::AddDeferredBreakConnection(AudioHandler& node) {
void DeferredTaskHandler::BreakConnections() {
DCHECK(IsAudioThread());
- DCHECK(IsGraphOwner());
+ AssertGraphOwner();
for (unsigned i = 0; i < deferred_break_connection_list_.size(); ++i)
deferred_break_connection_list_[i]->BreakConnectionWithLock();
@@ -94,39 +84,38 @@ void DeferredTaskHandler::BreakConnections() {
void DeferredTaskHandler::MarkSummingJunctionDirty(
AudioSummingJunction* summing_junction) {
- DCHECK(IsGraphOwner());
+ AssertGraphOwner();
dirty_summing_junctions_.insert(summing_junction);
}
void DeferredTaskHandler::RemoveMarkedSummingJunction(
AudioSummingJunction* summing_junction) {
DCHECK(IsMainThread());
- GraphAutoLocker locker(*this);
+ AssertGraphOwner();
dirty_summing_junctions_.erase(summing_junction);
}
void DeferredTaskHandler::MarkAudioNodeOutputDirty(AudioNodeOutput* output) {
- DCHECK(IsGraphOwner());
DCHECK(IsMainThread());
+ AssertGraphOwner();
dirty_audio_node_outputs_.insert(output);
}
void DeferredTaskHandler::RemoveMarkedAudioNodeOutput(AudioNodeOutput* output) {
- DCHECK(IsGraphOwner());
DCHECK(IsMainThread());
+ AssertGraphOwner();
dirty_audio_node_outputs_.erase(output);
}
void DeferredTaskHandler::HandleDirtyAudioSummingJunctions() {
- DCHECK(IsGraphOwner());
-
+ AssertGraphOwner();
for (AudioSummingJunction* junction : dirty_summing_junctions_)
junction->UpdateRenderingState();
dirty_summing_junctions_.clear();
}
void DeferredTaskHandler::HandleDirtyAudioNodeOutputs() {
- DCHECK(IsGraphOwner());
+ AssertGraphOwner();
HashSet<AudioNodeOutput*> dirty_outputs;
dirty_audio_node_outputs_.swap(dirty_outputs);
@@ -139,7 +128,7 @@ void DeferredTaskHandler::HandleDirtyAudioNodeOutputs() {
}
void DeferredTaskHandler::AddAutomaticPullNode(AudioHandler* node) {
- DCHECK(IsGraphOwner());
+ AssertGraphOwner();
if (!automatic_pull_nodes_.Contains(node)) {
automatic_pull_nodes_.insert(node);
@@ -148,7 +137,7 @@ void DeferredTaskHandler::AddAutomaticPullNode(AudioHandler* node) {
}
void DeferredTaskHandler::RemoveAutomaticPullNode(AudioHandler* node) {
- DCHECK(IsGraphOwner());
+ AssertGraphOwner();
if (automatic_pull_nodes_.Contains(node)) {
automatic_pull_nodes_.erase(node);
@@ -157,7 +146,7 @@ void DeferredTaskHandler::RemoveAutomaticPullNode(AudioHandler* node) {
}
void DeferredTaskHandler::UpdateAutomaticPullNodes() {
- DCHECK(IsGraphOwner());
+ AssertGraphOwner();
if (automatic_pull_nodes_need_updating_) {
CopyToVector(automatic_pull_nodes_, rendering_automatic_pull_nodes_);
@@ -174,7 +163,7 @@ void DeferredTaskHandler::ProcessAutomaticPullNodes(size_t frames_to_process) {
void DeferredTaskHandler::AddTailProcessingHandler(
scoped_refptr<AudioHandler> handler) {
- DCHECK(IsGraphOwner());
+ AssertGraphOwner();
if (!tail_processing_handlers_.Contains(handler)) {
#if DEBUG_AUDIONODE_REFERENCES > 1
@@ -187,7 +176,7 @@ void DeferredTaskHandler::AddTailProcessingHandler(
void DeferredTaskHandler::RemoveTailProcessingHandler(
scoped_refptr<AudioHandler> handler,
bool disable_outputs) {
- DCHECK(IsGraphOwner());
+ AssertGraphOwner();
size_t index = tail_processing_handlers_.Find(handler);
if (index != kNotFound) {
@@ -236,41 +225,37 @@ void DeferredTaskHandler::UpdateTailProcessingHandlers() {
}
void DeferredTaskHandler::AddChangedChannelCountMode(AudioHandler* node) {
- DCHECK(IsGraphOwner());
DCHECK(IsMainThread());
+ AssertGraphOwner();
deferred_count_mode_change_.insert(node);
}
void DeferredTaskHandler::RemoveChangedChannelCountMode(AudioHandler* node) {
- DCHECK(IsGraphOwner());
-
+ AssertGraphOwner();
deferred_count_mode_change_.erase(node);
}
void DeferredTaskHandler::AddChangedChannelInterpretation(AudioHandler* node) {
- DCHECK(IsGraphOwner());
DCHECK(IsMainThread());
+ AssertGraphOwner();
deferred_channel_interpretation_change_.insert(node);
}
void DeferredTaskHandler::RemoveChangedChannelInterpretation(
AudioHandler* node) {
- DCHECK(IsGraphOwner());
-
+ AssertGraphOwner();
deferred_channel_interpretation_change_.erase(node);
}
void DeferredTaskHandler::UpdateChangedChannelCountMode() {
- DCHECK(IsGraphOwner());
-
+ AssertGraphOwner();
for (AudioHandler* node : deferred_count_mode_change_)
node->UpdateChannelCountMode();
deferred_count_mode_change_.clear();
}
void DeferredTaskHandler::UpdateChangedChannelInterpretation() {
- DCHECK(IsGraphOwner());
-
+ AssertGraphOwner();
for (AudioHandler* node : deferred_channel_interpretation_change_)
node->UpdateChannelInterpretation();
deferred_channel_interpretation_change_.clear();
@@ -327,8 +312,8 @@ void DeferredTaskHandler::AddRenderingOrphanHandler(
}
void DeferredTaskHandler::RequestToDeleteHandlersOnMainThread() {
- DCHECK(IsGraphOwner());
DCHECK(IsAudioThread());
+ AssertGraphOwner();
if (rendering_orphan_handlers_.IsEmpty())
return;
deletable_orphan_handlers_.AppendVector(rendering_orphan_handlers_);
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 2db9eb1a637..f83258f9793 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
@@ -145,8 +145,8 @@ class MODULES_EXPORT DeferredTaskHandler final
// MUST NOT be used in the real-time audio context.
void OfflineLock();
- // Returns true if this thread owns the context's lock.
- bool IsGraphOwner();
+ // In DCHECK builds, fails if this thread does not own the context's lock.
+ void AssertGraphOwner() const { context_graph_mutex_.AssertAcquired(); }
class MODULES_EXPORT GraphAutoLocker {
STACK_ALLOCATED();
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 546e2d4d300..b2e8c6328b6 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/gain_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/gain_node.cc
@@ -107,7 +107,7 @@ void GainHandler::ProcessOnlyAudioParams(size_t frames_to_process) {
// channel count.
void GainHandler::CheckNumberOfChannelsForInput(AudioNodeInput* input) {
DCHECK(Context()->IsAudioThread());
- DCHECK(Context()->IsGraphOwner());
+ Context()->AssertGraphOwner();
DCHECK(input);
DCHECK_EQ(input, &this->Input(0));
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 8156266c23e..29ae509469e 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
@@ -25,6 +25,8 @@
#include "third_party/blink/renderer/modules/webaudio/offline_audio_completion_event.h"
+#include "third_party/blink/renderer/core/event_type_names.h"
+
namespace blink {
OfflineAudioCompletionEvent* OfflineAudioCompletionEvent::Create() {
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 a8626462212..fa3c1d6dc0b 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
@@ -369,7 +369,7 @@ void OfflineAudioContext::FireCompletionEvent() {
// Call the offline rendering completion event listener and resolve the
// promise too.
- DispatchEvent(OfflineAudioCompletionEvent::Create(rendered_buffer));
+ DispatchEvent(*OfflineAudioCompletionEvent::Create(rendered_buffer));
complete_resolver_->Resolve(rendered_buffer);
} else {
// The resolver should be rejected when the execution context is gone.
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 5c679152a33..6292f04046f 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.cc
@@ -360,8 +360,9 @@ void OscillatorHandler::Process(size_t frames_to_process) {
size_t non_silent_frames_to_process;
double start_frame_offset;
- UpdateSchedulingInfo(frames_to_process, output_bus, quantum_frame_offset,
- non_silent_frames_to_process, start_frame_offset);
+ std::tie(quantum_frame_offset, non_silent_frames_to_process,
+ start_frame_offset) =
+ UpdateSchedulingInfo(frames_to_process, output_bus);
if (!non_silent_frames_to_process) {
output_bus->Zero();
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 12f620d5ac8..d6da662107b 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
@@ -279,7 +279,7 @@ void ScriptProcessorHandler::FireProcessEvent(unsigned double_buffer_index) {
static_cast<double>(Context()->sampleRate());
// Call the JavaScript event handler which will do the audio processing.
- GetNode()->DispatchEvent(AudioProcessingEvent::Create(
+ GetNode()->DispatchEvent(*AudioProcessingEvent::Create(
input_buffer, output_buffer, playback_time));
}
}
@@ -311,7 +311,7 @@ void ScriptProcessorHandler::FireProcessEventForOfflineAudioContext(
// is locked by the waitable event.
double playback_time = (Context()->CurrentSampleFrame() + buffer_size_) /
static_cast<double>(Context()->sampleRate());
- GetNode()->DispatchEvent(AudioProcessingEvent::Create(
+ GetNode()->DispatchEvent(*AudioProcessingEvent::Create(
input_buffer, output_buffer, playback_time));
}
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/database.cc b/chromium/third_party/blink/renderer/modules/webdatabase/database.cc
index 1bad37db3a7..d3c597ee455 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/database.cc
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/database.cc
@@ -51,7 +51,6 @@
#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/platform/cross_thread_functional.h"
-#include "third_party/blink/renderer/platform/heap/safe_point.h"
#include "third_party/blink/renderer/platform/waitable_event.h"
#include "third_party/blink/renderer/platform/web_task_runner.h"
#include "third_party/blink/renderer/platform/wtf/atomics.h"
@@ -100,7 +99,7 @@ class DatabaseVersionCache {
// lifetime of the process.
DatabaseGuid RegisterOriginAndName(const String& origin, const String& name)
EXCLUSIVE_LOCKS_REQUIRED(mutex_) {
- CheckLocked();
+ mutex_.AssertAcquired();
String string_id = origin + "/" + name;
DCHECK(string_id.IsSafeToSendToAnotherThread());
DatabaseGuid guid = origin_name_to_guid_.at(string_id);
@@ -116,7 +115,7 @@ class DatabaseVersionCache {
// RegisterOriginAndName). If all uses are released, the cached version will
// be erased from memory.
void ReleaseGuid(DatabaseGuid guid) EXCLUSIVE_LOCKS_REQUIRED(mutex_) {
- CheckLocked();
+ mutex_.AssertAcquired();
DCHECK(count_.Contains(guid));
if (count_.erase(guid))
guid_to_version_.erase(guid);
@@ -124,7 +123,7 @@ class DatabaseVersionCache {
// The null string is returned only if the cached version has not been set.
String GetVersion(DatabaseGuid guid) const EXCLUSIVE_LOCKS_REQUIRED(mutex_) {
- CheckLocked();
+ mutex_.AssertAcquired();
return guid_to_version_.at(guid).IsolatedCopy();
}
@@ -132,19 +131,13 @@ class DatabaseVersionCache {
// The null string is treated as the empty string.
void SetVersion(DatabaseGuid guid, const String& new_version)
EXCLUSIVE_LOCKS_REQUIRED(mutex_) {
- CheckLocked();
+ mutex_.AssertAcquired();
guid_to_version_.Set(guid, new_version.IsNull()
? g_empty_string
: new_version.IsolatedCopy());
}
private:
- void CheckLocked() const ASSERT_EXCLUSIVE_LOCK(mutex_) {
-#if DCHECK_IS_ON()
- DCHECK(mutex_.Locked());
-#endif
- }
-
mutable Mutex mutex_;
HashMap<String, DatabaseGuid> origin_name_to_guid_ GUARDED_BY(mutex_);
HashCountedSet<DatabaseGuid> count_ GUARDED_BY(mutex_);
@@ -375,9 +368,7 @@ void Database::InProgressTransactionCompleted() {
}
void Database::ScheduleTransaction() {
-#if DCHECK_IS_ON()
- DCHECK(transaction_in_progress_mutex_.Locked()); // Locked by caller.
-#endif // DCHECK_IS_ON()
+ transaction_in_progress_mutex_.AssertAcquired();
SQLTransactionBackend* transaction = nullptr;
if (is_transaction_queue_enabled_ && !transaction_queue_.IsEmpty())
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 95499656922..5c77fbdb83b 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
@@ -48,14 +48,9 @@ typedef blink::protocol::Database::Backend::ExecuteSQLCallback
ExecuteSQLCallback;
namespace blink {
-
using protocol::Maybe;
using protocol::Response;
-namespace DatabaseAgentState {
-static const char kDatabaseAgentEnabled[] = "databaseAgentEnabled";
-};
-
namespace {
class ExecuteSQLCallbackWrapper : public RefCounted<ExecuteSQLCallbackWrapper> {
@@ -230,7 +225,7 @@ void InspectorDatabaseAgent::DidOpenDatabase(blink::Database* database,
InspectorDatabaseResource::Create(database, domain, name, version);
resources_.Set(resource->Id(), resource);
// Resources are only bound while visible.
- DCHECK(enabled_);
+ DCHECK(enabled_.Get());
DCHECK(GetFrontend());
resource->Bind(GetFrontend());
}
@@ -244,29 +239,31 @@ void InspectorDatabaseAgent::DidCommitLoadForLocalFrame(LocalFrame* frame) {
}
InspectorDatabaseAgent::InspectorDatabaseAgent(Page* page)
- : page_(page), enabled_(false) {}
+ : page_(page), enabled_(&agent_state_, /*default_value=*/false) {}
InspectorDatabaseAgent::~InspectorDatabaseAgent() = default;
-Response InspectorDatabaseAgent::enable() {
- if (enabled_)
- return Response::OK();
- enabled_ = true;
- state_->setBoolean(DatabaseAgentState::kDatabaseAgentEnabled, enabled_);
+void InspectorDatabaseAgent::InnerEnable() {
if (DatabaseClient* client = DatabaseClient::FromPage(page_))
client->SetInspectorAgent(this);
DatabaseTracker::Tracker().ForEachOpenDatabaseInPage(
page_,
WTF::BindRepeating(&InspectorDatabaseAgent::RegisterDatabaseOnCreation,
WrapPersistent(this)));
+}
+
+Response InspectorDatabaseAgent::enable() {
+ if (enabled_.Get())
+ return Response::OK();
+ enabled_.Set(true);
+ InnerEnable();
return Response::OK();
}
Response InspectorDatabaseAgent::disable() {
- if (!enabled_)
+ if (!enabled_.Get())
return Response::OK();
- enabled_ = false;
- state_->setBoolean(DatabaseAgentState::kDatabaseAgentEnabled, enabled_);
+ enabled_.Set(false);
if (DatabaseClient* client = DatabaseClient::FromPage(page_))
client->SetInspectorAgent(nullptr);
resources_.clear();
@@ -274,16 +271,14 @@ Response InspectorDatabaseAgent::disable() {
}
void InspectorDatabaseAgent::Restore() {
- if (state_->booleanProperty(DatabaseAgentState::kDatabaseAgentEnabled,
- false)) {
- enable();
- }
+ if (enabled_.Get())
+ InnerEnable();
}
Response InspectorDatabaseAgent::getDatabaseTableNames(
const String& database_id,
std::unique_ptr<protocol::Array<String>>* names) {
- if (!enabled_)
+ if (!enabled_.Get())
return Response::Error("Database agent is not enabled");
*names = protocol::Array<String>::create();
@@ -305,7 +300,7 @@ void InspectorDatabaseAgent::executeSQL(
std::unique_ptr<ExecuteSQLCallback> request_callback =
std::move(prp_request_callback);
- if (!enabled_) {
+ if (!enabled_.Get()) {
request_callback->sendFailure(
Response::Error("Database agent is not enabled"));
return;
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 f8d1a7de253..0643e9a6c00 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
@@ -74,6 +74,7 @@ class MODULES_EXPORT InspectorDatabaseAgent final
private:
explicit InspectorDatabaseAgent(Page*);
+ void InnerEnable();
void RegisterDatabaseOnCreation(blink::Database*);
blink::Database* DatabaseForId(const String& database_id);
@@ -83,7 +84,7 @@ class MODULES_EXPORT InspectorDatabaseAgent final
typedef HeapHashMap<String, Member<InspectorDatabaseResource>>
DatabaseResourcesHeapMap;
DatabaseResourcesHeapMap resources_;
- bool enabled_;
+ InspectorAgentState::Boolean enabled_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system.cc b/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system.cc
index c5a28916bf3..987281c913b 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system.cc
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system.cc
@@ -32,7 +32,6 @@
#include "sql/initialization.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/heap/safe_point.h"
#include "third_party/blink/renderer/platform/wtf/text/cstring.h"
#include "third_party/sqlite/sqlite3.h"
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system_posix.cc b/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system_posix.cc
index c907446f292..1ac378cd9ad 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system_posix.cc
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system_posix.cc
@@ -249,7 +249,7 @@ int ChromiumDelete(sqlite3_vfs*, const char* file_name, int sync_dir) {
sync_dir);
}
-// Check the existance and status of the given file.
+// Check the existence and status of the given file.
//
// vfs - pointer to the sqlite3_vfs object.
// fileName - the name of the file.
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system_win.cc b/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system_win.cc
index 40a0d56cd50..5480922be61 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system_win.cc
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system_win.cc
@@ -83,7 +83,7 @@ int ChromiumDelete(sqlite3_vfs*, const char* file_name, int) {
false);
}
-// Check the existance and status of the given file.
+// Check the existence and status of the given file.
//
// vfs - pointer to the sqlite3_vfs object.
// fileName - the name of the file.
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_statement.cc b/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_statement.cc
index bd362db21d6..5b443d16633 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_statement.cc
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_statement.cc
@@ -28,7 +28,6 @@
#include <memory>
#include "third_party/blink/renderer/modules/webdatabase/sqlite/sql_log.h"
#include "third_party/blink/renderer/modules/webdatabase/sqlite/sql_value.h"
-#include "third_party/blink/renderer/platform/heap/safe_point.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/text/cstring.h"
#include "third_party/sqlite/sqlite3.h"
diff --git a/chromium/third_party/blink/renderer/modules/webgl/BUILD.gn b/chromium/third_party/blink/renderer/modules/webgl/BUILD.gn
index b4fa673896c..b8b35ff312c 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/webgl/BUILD.gn
@@ -87,6 +87,8 @@ blink_modules_sources("webgl") {
"webgl_framebuffer.h",
"webgl_lose_context.cc",
"webgl_lose_context.h",
+ "webgl_multiview.cc",
+ "webgl_multiview.h",
"webgl_object.cc",
"webgl_object.h",
"webgl_program.cc",
diff --git a/chromium/third_party/blink/renderer/modules/webgl/DEPS b/chromium/third_party/blink/renderer/modules/webgl/DEPS
index a1d284bb9c1..e04241d560e 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/DEPS
+++ b/chromium/third_party/blink/renderer/modules/webgl/DEPS
@@ -1,6 +1,7 @@
include_rules = [
"+gpu/GLES2/gl2extchromium.h",
"+gpu/command_buffer/client/gles2_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/webgl2_compute_rendering_context.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context.cc
index 0e654818853..cef47c715b5 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
@@ -87,7 +87,7 @@ CanvasRenderingContext* WebGL2ComputeRenderingContext::Factory::Create(
void WebGL2ComputeRenderingContext::Factory::OnError(HTMLCanvasElement* canvas,
const String& error) {
- canvas->DispatchEvent(WebGLContextEvent::Create(
+ canvas->DispatchEvent(*WebGLContextEvent::Create(
EventTypeNames::webglcontextcreationerror, error));
}
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context.idl b/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context.idl
index 9a434041c65..08e57554224 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context.idl
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context.idl
@@ -4,7 +4,7 @@
[
DoNotCheckConstants,
- Exposed(Worker OffscreenCanvas, Window StableBlinkFeatures)
+ Exposed(Worker WebGL2ComputeContext, Window WebGL2ComputeContext)
] interface WebGL2ComputeRenderingContext { };
WebGL2ComputeRenderingContext implements WebGLRenderingContextBase;
WebGL2ComputeRenderingContext implements WebGL2RenderingContextBase;
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 ffb32f12422..53d9de343c9 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
@@ -32,8 +32,7 @@ void WebGL2ComputeRenderingContextBase::InitializeNewContext() {
void WebGL2ComputeRenderingContextBase::dispatchCompute(GLuint numGroupsX,
GLuint numGroupsY,
GLuint numGroupsZ) {
- SynthesizeGLError(GL_INVALID_OPERATION, "dispatchCompute", "UNIMPLEMENTED");
- return;
+ ContextGL()->DispatchCompute(numGroupsX, numGroupsY, numGroupsZ);
}
void WebGL2ComputeRenderingContextBase::bindImageTexture(GLuint unit,
@@ -43,17 +42,17 @@ void WebGL2ComputeRenderingContextBase::bindImageTexture(GLuint unit,
GLint layer,
GLenum access,
GLenum format) {
- SynthesizeGLError(GL_INVALID_OPERATION, "bindImageTexture", "UNIMPLEMENTED");
+ ContextGL()->BindImageTexture(unit, ObjectOrZero(texture), level, layered,
+ layer, access, format);
}
void WebGL2ComputeRenderingContextBase::memoryBarrier(GLbitfield barriers) {
- SynthesizeGLError(GL_INVALID_OPERATION, "memoryBarrier", "UNIMPLEMENTED");
+ ContextGL()->MemoryBarrierEXT(barriers);
}
void WebGL2ComputeRenderingContextBase::memoryBarrierByRegion(
GLbitfield barriers) {
- SynthesizeGLError(GL_INVALID_OPERATION, "memoryBarrierByRegion",
- "UNIMPLEMENTED");
+ ContextGL()->MemoryBarrierByRegion(barriers);
}
void WebGL2ComputeRenderingContextBase::Trace(blink::Visitor* visitor) {
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 274e3c8121f..c0c85e3fb14 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
@@ -29,6 +29,7 @@
#include "third_party/blink/renderer/modules/webgl/webgl_debug_renderer_info.h"
#include "third_party/blink/renderer/modules/webgl/webgl_debug_shaders.h"
#include "third_party/blink/renderer/modules/webgl/webgl_lose_context.h"
+#include "third_party/blink/renderer/modules/webgl/webgl_multiview.h"
#include "third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h"
namespace blink {
@@ -84,7 +85,7 @@ CanvasRenderingContext* WebGL2RenderingContext::Factory::Create(
void WebGL2RenderingContext::Factory::OnError(HTMLCanvasElement* canvas,
const String& error) {
- canvas->DispatchEvent(WebGLContextEvent::Create(
+ canvas->DispatchEvent(*WebGLContextEvent::Create(
EventTypeNames::webglcontextcreationerror, error));
}
@@ -133,6 +134,7 @@ void WebGL2RenderingContext::RegisterContextExtensions() {
RegisterExtension<WebGLDebugRendererInfo>(webgl_debug_renderer_info_);
RegisterExtension<WebGLDebugShaders>(webgl_debug_shaders_);
RegisterExtension<WebGLLoseContext>(webgl_lose_context_);
+ RegisterExtension<WebGLMultiview>(webgl_multiview_, kDraftExtension);
}
void WebGL2RenderingContext::Trace(blink::Visitor* visitor) {
@@ -149,6 +151,7 @@ void WebGL2RenderingContext::Trace(blink::Visitor* visitor) {
visitor->Trace(webgl_debug_renderer_info_);
visitor->Trace(webgl_debug_shaders_);
visitor->Trace(webgl_lose_context_);
+ visitor->Trace(webgl_multiview_);
WebGL2RenderingContextBase::Trace(visitor);
}
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 db77f15bb5b..1db2acea31e 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
@@ -17,6 +17,7 @@ class EXTTextureFilterAnisotropic;
class OESTextureFloatLinear;
class WebGLDebugRendererInfo;
class WebGLLoseContext;
+class WebGLMultiview;
class WebGL2RenderingContext : public WebGL2RenderingContextBase {
DEFINE_WRAPPERTYPEINFO();
@@ -69,6 +70,7 @@ class WebGL2RenderingContext : public WebGL2RenderingContextBase {
Member<WebGLDebugRendererInfo> webgl_debug_renderer_info_;
Member<WebGLDebugShaders> webgl_debug_shaders_;
Member<WebGLLoseContext> webgl_lose_context_;
+ Member<WebGLMultiview> webgl_multiview_;
};
DEFINE_TYPE_CASTS(WebGL2RenderingContext,
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 2f4376ad2be..690a0193749 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
@@ -168,6 +168,8 @@ void WebGL2RenderingContextBase::InitializeNewContext() {
bound_pixel_unpack_buffer_ = nullptr;
bound_transform_feedback_buffer_ = nullptr;
bound_uniform_buffer_ = nullptr;
+ bound_atomic_counter_buffer_ = nullptr;
+ bound_shader_storage_buffer_ = nullptr;
current_boolean_occlusion_query_ = nullptr;
current_transform_feedback_primitives_written_query_ = nullptr;
@@ -197,6 +199,22 @@ void WebGL2RenderingContextBase::InitializeNewContext() {
bound_indexed_uniform_buffers_.resize(max_uniform_buffer_bindings);
max_bound_uniform_buffer_index_ = 0;
+ if (ContextType() == Platform::kWebGL2ComputeContextType) {
+ GLint max_atomic_counter_buffer_bindings = 0;
+ ContextGL()->GetIntegerv(GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS,
+ &max_atomic_counter_buffer_bindings);
+ bound_indexed_atomic_counter_buffers_.clear();
+ bound_indexed_atomic_counter_buffers_.resize(
+ max_atomic_counter_buffer_bindings);
+
+ GLint max_shader_storage_buffer_bindings = 0;
+ ContextGL()->GetIntegerv(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS,
+ &max_shader_storage_buffer_bindings);
+ bound_indexed_shader_storage_buffers_.clear();
+ bound_indexed_shader_storage_buffers_.resize(
+ max_shader_storage_buffer_bindings);
+ }
+
pack_row_length_ = 0;
pack_skip_pixels_ = 0;
pack_skip_rows_ = 0;
@@ -453,7 +471,7 @@ void WebGL2RenderingContextBase::framebufferTextureLayer(GLenum target,
return;
}
framebuffer_binding->SetAttachmentForBoundFramebuffer(
- target, attachment, textarget, texture, level, layer);
+ target, attachment, textarget, texture, level, layer, 0);
ApplyStencilTest();
}
@@ -1204,7 +1222,7 @@ void WebGL2RenderingContextBase::texImage2D(ExecutionContext* execution_context,
GLint border,
GLenum format,
GLenum type,
- HTMLCanvasElement* canvas,
+ CanvasRenderingContextHost* canvas,
ExceptionState& exception_state) {
if (isContextLost())
return;
@@ -1214,7 +1232,7 @@ void WebGL2RenderingContextBase::texImage2D(ExecutionContext* execution_context,
return;
}
- TexImageHelperHTMLCanvasElement(
+ TexImageHelperCanvasRenderingContextHost(
execution_context->GetSecurityOrigin(), kTexImage2D, target, level,
internalformat, format, type, 0, 0, 0, canvas,
GetTextureSourceSubRectangle(width, height), 1, 0, exception_state);
@@ -1306,14 +1324,15 @@ void WebGL2RenderingContextBase::texImage2D(ExecutionContext* execution_context,
exception_state);
}
-void WebGL2RenderingContextBase::texImage2D(ExecutionContext* execution_context,
- GLenum target,
- GLint level,
- GLint internalformat,
- GLenum format,
- GLenum type,
- HTMLCanvasElement* canvas,
- ExceptionState& exception_state) {
+void WebGL2RenderingContextBase::texImage2D(
+ ExecutionContext* execution_context,
+ GLenum target,
+ GLint level,
+ GLint internalformat,
+ GLenum format,
+ GLenum type,
+ CanvasRenderingContextHost* context_host,
+ ExceptionState& exception_state) {
if (isContextLost())
return;
if (bound_pixel_unpack_buffer_) {
@@ -1323,8 +1342,8 @@ void WebGL2RenderingContextBase::texImage2D(ExecutionContext* execution_context,
}
WebGLRenderingContextBase::texImage2D(execution_context, target, level,
- internalformat, format, type, canvas,
- exception_state);
+ internalformat, format, type,
+ context_host, exception_state);
}
void WebGL2RenderingContextBase::texImage2D(ExecutionContext* execution_context,
@@ -1468,7 +1487,7 @@ void WebGL2RenderingContextBase::texSubImage2D(
GLsizei height,
GLenum format,
GLenum type,
- HTMLCanvasElement* canvas,
+ CanvasRenderingContextHost* canvas,
ExceptionState& exception_state) {
if (isContextLost())
return;
@@ -1478,7 +1497,7 @@ void WebGL2RenderingContextBase::texSubImage2D(
return;
}
- TexImageHelperHTMLCanvasElement(
+ TexImageHelperCanvasRenderingContextHost(
execution_context->GetSecurityOrigin(), kTexSubImage2D, target, level, 0,
format, type, xoffset, yoffset, 0, canvas,
GetTextureSourceSubRectangle(width, height), 1, 0, exception_state);
@@ -1584,7 +1603,7 @@ void WebGL2RenderingContextBase::texSubImage2D(
GLint yoffset,
GLenum format,
GLenum type,
- HTMLCanvasElement* canvas,
+ CanvasRenderingContextHost* context_host,
ExceptionState& exception_state) {
if (isContextLost())
return;
@@ -1596,7 +1615,7 @@ void WebGL2RenderingContextBase::texSubImage2D(
WebGLRenderingContextBase::texSubImage2D(execution_context, target, level,
xoffset, yoffset, format, type,
- canvas, exception_state);
+ context_host, exception_state);
}
void WebGL2RenderingContextBase::texSubImage2D(
@@ -1810,7 +1829,7 @@ void WebGL2RenderingContextBase::texImage3D(ExecutionContext* execution_context,
GLint border,
GLenum format,
GLenum type,
- HTMLCanvasElement* canvas,
+ CanvasRenderingContextHost* canvas,
ExceptionState& exception_state) {
if (isContextLost())
return;
@@ -1820,11 +1839,11 @@ void WebGL2RenderingContextBase::texImage3D(ExecutionContext* execution_context,
return;
}
- TexImageHelperHTMLCanvasElement(execution_context->GetSecurityOrigin(),
- kTexImage3D, target, level, internalformat,
- format, type, 0, 0, 0, canvas,
- GetTextureSourceSubRectangle(width, height),
- depth, unpack_image_height_, exception_state);
+ TexImageHelperCanvasRenderingContextHost(
+ execution_context->GetSecurityOrigin(), kTexImage3D, target, level,
+ internalformat, format, type, 0, 0, 0, canvas,
+ GetTextureSourceSubRectangle(width, height), depth, unpack_image_height_,
+ exception_state);
}
void WebGL2RenderingContextBase::texImage3D(ExecutionContext* execution_context,
@@ -2015,7 +2034,7 @@ void WebGL2RenderingContextBase::texSubImage3D(
GLsizei depth,
GLenum format,
GLenum type,
- HTMLCanvasElement* canvas,
+ CanvasRenderingContextHost* context_host,
ExceptionState& exception_state) {
if (isContextLost())
return;
@@ -2025,11 +2044,11 @@ void WebGL2RenderingContextBase::texSubImage3D(
return;
}
- TexImageHelperHTMLCanvasElement(execution_context->GetSecurityOrigin(),
- kTexSubImage3D, target, level, 0, format,
- type, xoffset, yoffset, zoffset, canvas,
- GetTextureSourceSubRectangle(width, height),
- depth, unpack_image_height_, exception_state);
+ TexImageHelperCanvasRenderingContextHost(
+ execution_context->GetSecurityOrigin(), kTexSubImage3D, target, level, 0,
+ format, type, xoffset, yoffset, zoffset, context_host,
+ GetTextureSourceSubRectangle(width, height), depth, unpack_image_height_,
+ exception_state);
}
void WebGL2RenderingContextBase::texSubImage3D(
@@ -4216,7 +4235,7 @@ WebGLSync* WebGL2RenderingContextBase::fenceSync(GLenum condition,
}
GLboolean WebGL2RenderingContextBase::isSync(WebGLSync* sync) {
- if (isContextLost() || !sync)
+ if (isContextLost() || !sync || !sync->Validate(ContextGroup(), this))
return 0;
return sync->Object() != 0;
@@ -4661,6 +4680,34 @@ ScriptValue WebGL2RenderingContextBase::getIndexedParameter(
}
return WebGLAny(script_state,
bound_indexed_uniform_buffers_[index].Get());
+ case GL_ATOMIC_COUNTER_BUFFER_BINDING: {
+ if (ContextType() != Platform::kWebGL2ComputeContextType) {
+ SynthesizeGLError(GL_INVALID_ENUM, "getIndexedParameter",
+ "invalid parameter name");
+ return ScriptValue::CreateNull(script_state);
+ }
+ if (index >= bound_indexed_atomic_counter_buffers_.size()) {
+ SynthesizeGLError(GL_INVALID_VALUE, "getIndexedParameter",
+ "index out of range");
+ return ScriptValue::CreateNull(script_state);
+ }
+ return WebGLAny(script_state,
+ bound_indexed_atomic_counter_buffers_[index].Get());
+ }
+ case GL_SHADER_STORAGE_BUFFER_BINDING: {
+ if (ContextType() != Platform::kWebGL2ComputeContextType) {
+ SynthesizeGLError(GL_INVALID_ENUM, "getIndexedParameter",
+ "invalid parameter name");
+ return ScriptValue::CreateNull(script_state);
+ }
+ if (index >= bound_indexed_shader_storage_buffers_.size()) {
+ SynthesizeGLError(GL_INVALID_VALUE, "getIndexedParameter",
+ "index out of range");
+ return ScriptValue::CreateNull(script_state);
+ }
+ return WebGLAny(script_state,
+ bound_indexed_shader_storage_buffers_[index].Get());
+ }
case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
case GL_TRANSFORM_FEEDBACK_BUFFER_START:
case GL_UNIFORM_BUFFER_SIZE:
@@ -4669,6 +4716,19 @@ ScriptValue WebGL2RenderingContextBase::getIndexedParameter(
ContextGL()->GetInteger64i_v(target, index, &value);
return WebGLAny(script_state, value);
}
+ case GL_ATOMIC_COUNTER_BUFFER_SIZE:
+ case GL_ATOMIC_COUNTER_BUFFER_START:
+ case GL_SHADER_STORAGE_BUFFER_SIZE:
+ case GL_SHADER_STORAGE_BUFFER_START: {
+ if (ContextType() != Platform::kWebGL2ComputeContextType) {
+ SynthesizeGLError(GL_INVALID_ENUM, "getIndexedParameter",
+ "invalid parameter name");
+ return ScriptValue::CreateNull(script_state);
+ }
+ GLint64 value = -1;
+ ContextGL()->GetInteger64i_v(target, index, &value);
+ return WebGLAny(script_state, value);
+ }
default:
SynthesizeGLError(GL_INVALID_ENUM, "getIndexedParameter",
"invalid parameter name");
@@ -5217,6 +5277,8 @@ bool WebGL2RenderingContextBase::ValidateBufferTargetCompatibility(
case GL_PIXEL_UNPACK_BUFFER:
case GL_TRANSFORM_FEEDBACK_BUFFER:
case GL_UNIFORM_BUFFER:
+ case GL_ATOMIC_COUNTER_BUFFER:
+ case GL_SHADER_STORAGE_BUFFER:
SynthesizeGLError(
GL_INVALID_OPERATION, function_name,
"element array buffers can not be bound to a different target");
@@ -5233,6 +5295,8 @@ bool WebGL2RenderingContextBase::ValidateBufferTargetCompatibility(
case GL_PIXEL_UNPACK_BUFFER:
case GL_UNIFORM_BUFFER:
case GL_TRANSFORM_FEEDBACK_BUFFER:
+ case GL_ATOMIC_COUNTER_BUFFER:
+ case GL_SHADER_STORAGE_BUFFER:
if (target == GL_ELEMENT_ARRAY_BUFFER) {
SynthesizeGLError(GL_INVALID_OPERATION, function_name,
"buffers bound to non ELEMENT_ARRAY_BUFFER targets "
@@ -5259,6 +5323,13 @@ bool WebGL2RenderingContextBase::ValidateBufferTarget(const char* function_name,
case GL_TRANSFORM_FEEDBACK_BUFFER:
case GL_UNIFORM_BUFFER:
return true;
+ case GL_ATOMIC_COUNTER_BUFFER:
+ case GL_SHADER_STORAGE_BUFFER:
+ if (ContextType() != Platform::kWebGL2ComputeContextType) {
+ SynthesizeGLError(GL_INVALID_ENUM, function_name, "invalid target");
+ return false;
+ }
+ return true;
default:
SynthesizeGLError(GL_INVALID_ENUM, function_name, "invalid target");
return false;
@@ -5301,6 +5372,12 @@ bool WebGL2RenderingContextBase::ValidateAndUpdateBufferBindTarget(
case GL_UNIFORM_BUFFER:
bound_uniform_buffer_ = buffer;
break;
+ case GL_ATOMIC_COUNTER_BUFFER:
+ bound_atomic_counter_buffer_ = buffer;
+ break;
+ case GL_SHADER_STORAGE_BUFFER:
+ bound_shader_storage_buffer_ = buffer;
+ break;
default:
NOTREACHED();
break;
@@ -5318,6 +5395,13 @@ bool WebGL2RenderingContextBase::ValidateBufferBaseTarget(
case GL_TRANSFORM_FEEDBACK_BUFFER:
case GL_UNIFORM_BUFFER:
return true;
+ case GL_ATOMIC_COUNTER_BUFFER:
+ case GL_SHADER_STORAGE_BUFFER:
+ if (ContextType() != Platform::kWebGL2ComputeContextType) {
+ SynthesizeGLError(GL_INVALID_ENUM, function_name, "invalid target");
+ return false;
+ }
+ return true;
default:
SynthesizeGLError(GL_INVALID_ENUM, function_name, "invalid target");
return false;
@@ -5369,6 +5453,24 @@ bool WebGL2RenderingContextBase::ValidateAndUpdateBufferBindBaseTarget(
max_bound_uniform_buffer_index_ = i;
}
break;
+ case GL_ATOMIC_COUNTER_BUFFER:
+ if (index >= bound_indexed_atomic_counter_buffers_.size()) {
+ SynthesizeGLError(GL_INVALID_VALUE, function_name,
+ "index out of range");
+ return false;
+ }
+ bound_indexed_atomic_counter_buffers_[index] = buffer;
+ bound_atomic_counter_buffer_ = buffer;
+ break;
+ case GL_SHADER_STORAGE_BUFFER:
+ if (index >= bound_indexed_shader_storage_buffers_.size()) {
+ SynthesizeGLError(GL_INVALID_VALUE, function_name,
+ "index out of range");
+ return false;
+ }
+ bound_indexed_shader_storage_buffers_[index] = buffer;
+ bound_shader_storage_buffer_ = buffer;
+ break;
default:
NOTREACHED();
break;
@@ -5609,6 +5711,20 @@ ScriptValue WebGL2RenderingContextBase::getFramebufferAttachmentParameter(
return WebGLAny(script_state, GL_UNSIGNED_NORMALIZED);
case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
return WebGLAny(script_state, GL_LINEAR);
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR:
+ if (ExtensionEnabled(kWebGLMultiviewName))
+ return WebGLAny(script_state, 0);
+ SynthesizeGLError(
+ GL_INVALID_ENUM, kFunctionName,
+ "invalid parameter name, WEBGL_multiview not enabled");
+ return ScriptValue::CreateNull(script_state);
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR:
+ if (ExtensionEnabled(kWebGLMultiviewName))
+ return WebGLAny(script_state, 0);
+ SynthesizeGLError(
+ GL_INVALID_ENUM, kFunctionName,
+ "invalid parameter name, WEBGL_multiview not enabled");
+ return ScriptValue::CreateNull(script_state);
default:
SynthesizeGLError(GL_INVALID_ENUM, kFunctionName,
"invalid parameter name");
@@ -5685,6 +5801,19 @@ ScriptValue WebGL2RenderingContextBase::getFramebufferAttachmentParameter(
pname, &value);
return WebGLAny(script_state, static_cast<unsigned>(value));
}
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR:
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR: {
+ if (!ExtensionEnabled(kWebGLMultiviewName)) {
+ SynthesizeGLError(
+ GL_INVALID_ENUM, kFunctionName,
+ "invalid parameter name, WEBGL_multiview not enabled");
+ return ScriptValue::CreateNull(script_state);
+ }
+ GLint value = 0;
+ ContextGL()->GetFramebufferAttachmentParameteriv(target, attachment,
+ pname, &value);
+ return WebGLAny(script_state, static_cast<unsigned>(value));
+ }
default:
break;
}
@@ -5703,6 +5832,10 @@ void WebGL2RenderingContextBase::Trace(blink::Visitor* visitor) {
visitor->Trace(bound_transform_feedback_buffer_);
visitor->Trace(bound_uniform_buffer_);
visitor->Trace(bound_indexed_uniform_buffers_);
+ visitor->Trace(bound_atomic_counter_buffer_);
+ visitor->Trace(bound_indexed_atomic_counter_buffers_);
+ visitor->Trace(bound_shader_storage_buffer_);
+ visitor->Trace(bound_indexed_shader_storage_buffers_);
visitor->Trace(current_boolean_occlusion_query_);
visitor->Trace(current_transform_feedback_primitives_written_query_);
visitor->Trace(current_elapsed_query_);
@@ -5810,6 +5943,22 @@ WebGLBuffer* WebGL2RenderingContextBase::ValidateBufferDataTarget(
case GL_UNIFORM_BUFFER:
buffer = bound_uniform_buffer_.Get();
break;
+ case GL_ATOMIC_COUNTER_BUFFER: {
+ if (ContextType() != Platform::kWebGL2ComputeContextType) {
+ SynthesizeGLError(GL_INVALID_ENUM, function_name, "invalid target");
+ return nullptr;
+ }
+ buffer = bound_atomic_counter_buffer_.Get();
+ break;
+ }
+ case GL_SHADER_STORAGE_BUFFER: {
+ if (ContextType() != Platform::kWebGL2ComputeContextType) {
+ SynthesizeGLError(GL_INVALID_ENUM, function_name, "invalid target");
+ return nullptr;
+ }
+ buffer = bound_shader_storage_buffer_.Get();
+ break;
+ }
default:
SynthesizeGLError(GL_INVALID_ENUM, function_name, "invalid target");
return nullptr;
@@ -5908,6 +6057,10 @@ void WebGL2RenderingContextBase::RemoveBoundBuffer(WebGLBuffer* buffer) {
bound_transform_feedback_buffer_ = nullptr;
if (bound_uniform_buffer_ == buffer)
bound_uniform_buffer_ = nullptr;
+ if (bound_atomic_counter_buffer_ == buffer)
+ bound_atomic_counter_buffer_ = nullptr;
+ if (bound_shader_storage_buffer_ == buffer)
+ bound_shader_storage_buffer_ = nullptr;
transform_feedback_binding_->UnbindBuffer(buffer);
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 7ef3f4cf82f..a410ef3d21f 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
@@ -128,7 +128,7 @@ class WebGL2RenderingContextBase : public WebGLRenderingContextBase {
GLint,
GLenum,
GLenum,
- HTMLCanvasElement*,
+ CanvasRenderingContextHost*,
ExceptionState&);
void texImage2D(ExecutionContext*,
GLenum,
@@ -200,7 +200,7 @@ class WebGL2RenderingContextBase : public WebGLRenderingContextBase {
GLsizei,
GLenum,
GLenum,
- HTMLCanvasElement*,
+ CanvasRenderingContextHost*,
ExceptionState&);
void texSubImage2D(ExecutionContext*,
GLenum,
@@ -252,7 +252,7 @@ class WebGL2RenderingContextBase : public WebGLRenderingContextBase {
GLint,
GLenum,
GLenum,
- HTMLCanvasElement*,
+ CanvasRenderingContextHost*,
ExceptionState&);
void texImage2D(ExecutionContext*,
GLenum,
@@ -286,7 +286,7 @@ class WebGL2RenderingContextBase : public WebGLRenderingContextBase {
GLint,
GLenum,
GLenum,
- HTMLCanvasElement*,
+ CanvasRenderingContextHost*,
ExceptionState&);
void texSubImage2D(ExecutionContext*,
GLenum,
@@ -361,7 +361,7 @@ class WebGL2RenderingContextBase : public WebGLRenderingContextBase {
GLint,
GLenum,
GLenum,
- HTMLCanvasElement*,
+ CanvasRenderingContextHost*,
ExceptionState&);
void texImage3D(ExecutionContext*,
GLenum,
@@ -454,7 +454,7 @@ class WebGL2RenderingContextBase : public WebGLRenderingContextBase {
GLsizei,
GLenum,
GLenum,
- HTMLCanvasElement*,
+ CanvasRenderingContextHost*,
ExceptionState&);
void texSubImage3D(ExecutionContext*,
GLenum,
@@ -1127,7 +1127,13 @@ class WebGL2RenderingContextBase : public WebGLRenderingContextBase {
TraceWrapperMember<WebGLBuffer> bound_pixel_unpack_buffer_;
TraceWrapperMember<WebGLBuffer> bound_transform_feedback_buffer_;
TraceWrapperMember<WebGLBuffer> bound_uniform_buffer_;
+ TraceWrapperMember<WebGLBuffer> bound_atomic_counter_buffer_;
+ TraceWrapperMember<WebGLBuffer> bound_shader_storage_buffer_;
+ HeapVector<TraceWrapperMember<WebGLBuffer>>
+ bound_indexed_atomic_counter_buffers_;
+ HeapVector<TraceWrapperMember<WebGLBuffer>>
+ bound_indexed_shader_storage_buffers_;
HeapVector<TraceWrapperMember<WebGLBuffer>> bound_indexed_uniform_buffers_;
GLint max_transform_feedback_separate_attribs_;
size_t max_bound_uniform_buffer_index_;
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.idl b/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.idl
index 0952630b011..9046cbf916e 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.idl
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.idl
@@ -298,6 +298,7 @@ typedef unsigned long long GLuint64;
void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, ImageData data);
[CallWith=ExecutionContext, RaisesException] void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, HTMLImageElement image);
[CallWith=ExecutionContext, RaisesException] void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, HTMLCanvasElement canvas);
+ [CallWith=ExecutionContext, RaisesException] void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, OffscreenCanvas offscreenCanvas);
[CallWith=ExecutionContext,RaisesException] void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, HTMLVideoElement video);
[RaisesException] void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, ImageBitmap bitmap);
void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, [AllowShared] ArrayBufferView srcData, GLuint srcOffset);
@@ -305,6 +306,7 @@ typedef unsigned long long GLuint64;
void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, ImageData data);
[CallWith=ExecutionContext, RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, HTMLImageElement image);
[CallWith=ExecutionContext, RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, HTMLCanvasElement canvas);
+ [CallWith=ExecutionContext, RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, OffscreenCanvas offscreenCanvas);
[CallWith=ExecutionContext, RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, HTMLVideoElement video);
[RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, ImageBitmap bitmap);
void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, [AllowShared] ArrayBufferView srcData, GLuint srcOffset);
@@ -314,6 +316,7 @@ typedef unsigned long long GLuint64;
void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, ImageData data);
[CallWith=ExecutionContext, RaisesException] void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, HTMLImageElement image);
[CallWith=ExecutionContext, RaisesException] void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, HTMLCanvasElement canvas);
+ [CallWith=ExecutionContext, RaisesException] void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, OffscreenCanvas offscreenCanvas);
[CallWith=ExecutionContext, RaisesException] void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, HTMLVideoElement video);
[RaisesException] void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, ImageBitmap bitmap);
void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, [AllowShared] ArrayBufferView? pixels);
@@ -322,6 +325,7 @@ typedef unsigned long long GLuint64;
void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, ImageData data);
[CallWith=ExecutionContext, RaisesException] void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, HTMLImageElement image);
[CallWith=ExecutionContext, RaisesException] void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, HTMLCanvasElement canvas);
+ [CallWith=ExecutionContext, RaisesException] void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, OffscreenCanvas offscreenCanvas);
[CallWith=ExecutionContext, RaisesException] void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, HTMLVideoElement video);
[RaisesException] void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, ImageBitmap bitmap);
void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, [AllowShared] ArrayBufferView pixels, optional GLuint srcOffset = 0);
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 9e2181da334..f3e544031f2 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
@@ -39,6 +39,7 @@ enum WebGLExtensionName {
kWebGLDrawBuffersName,
kWebGLGetBufferSubDataAsyncName,
kWebGLLoseContextName,
+ kWebGLMultiviewName,
kWebGLExtensionNameCount, // Must be the last entry
};
} // namespace blink
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 1d9b966ed7b..7d03d4031e2 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_framebuffer.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_framebuffer.cc
@@ -227,7 +227,8 @@ void WebGLFramebuffer::SetAttachmentForBoundFramebuffer(GLenum target,
GLenum tex_target,
WebGLTexture* texture,
GLint level,
- GLint layer) {
+ GLint layer,
+ GLsizei num_views) {
DCHECK(object_);
DCHECK(IsBound(target));
if (Context()->IsWebGL2OrHigher()) {
@@ -247,17 +248,25 @@ void WebGLFramebuffer::SetAttachmentForBoundFramebuffer(GLenum target,
case 0:
case GL_TEXTURE_3D:
case GL_TEXTURE_2D_ARRAY:
- Context()->ContextGL()->FramebufferTextureLayer(
- target, attachment, texture_id, level, layer);
+ if (num_views > 0) {
+ DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D_ARRAY), tex_target);
+ Context()->ContextGL()->FramebufferTextureMultiviewLayeredANGLE(
+ target, attachment, texture_id, level, layer, num_views);
+ } else {
+ Context()->ContextGL()->FramebufferTextureLayer(
+ target, attachment, texture_id, level, layer);
+ }
break;
default:
DCHECK_EQ(layer, 0);
+ DCHECK_EQ(num_views, 0);
Context()->ContextGL()->FramebufferTexture2D(
target, attachment, tex_target, texture_id, level);
break;
}
} else {
DCHECK_EQ(layer, 0);
+ DCHECK_EQ(num_views, 0);
SetAttachmentInternal(target, attachment, tex_target, texture, level,
layer);
switch (attachment) {
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 ee755029e3a..e1b58213804 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_framebuffer.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_framebuffer.h
@@ -76,12 +76,15 @@ class WebGLFramebuffer final : public WebGLContextObject {
GLuint Object() const { return object_; }
+ // For a non-multiview attachment, set the num_views parameter to 0. For a
+ // multiview attachment, set the layer to the base view index.
void SetAttachmentForBoundFramebuffer(GLenum target,
GLenum attachment,
GLenum tex_target,
WebGLTexture*,
GLint level,
- GLint layer);
+ GLint layer,
+ GLsizei num_views);
void SetAttachmentForBoundFramebuffer(GLenum target,
GLenum attachment,
WebGLRenderbuffer*);
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_multiview.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_multiview.cc
new file mode 100644
index 00000000000..06fe14a24ee
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_multiview.cc
@@ -0,0 +1,106 @@
+// 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_multiview.h"
+
+#include "third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.h"
+#include "third_party/blink/renderer/modules/webgl/webgl_framebuffer.h"
+#include "third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h"
+
+namespace blink {
+
+WebGLMultiview::WebGLMultiview(WebGLRenderingContextBase* context)
+ : WebGLExtension(context) {
+ context->ExtensionsUtil()->EnsureExtensionEnabled("GL_ANGLE_multiview");
+ context->ContextGL()->GetIntegerv(GL_MAX_VIEWS_OVR, &max_views_ovr_);
+}
+
+WebGLExtensionName WebGLMultiview::GetName() const {
+ return kWebGLMultiviewName;
+}
+
+WebGLMultiview* WebGLMultiview::Create(WebGLRenderingContextBase* context) {
+ return new WebGLMultiview(context);
+}
+
+void WebGLMultiview::framebufferTextureMultiviewWEBGL(GLenum target,
+ GLenum attachment,
+ WebGLTexture* texture,
+ GLint level,
+ GLint base_view_index,
+ GLsizei num_views) {
+ WebGLExtensionScopedContext scoped(this);
+ if (scoped.IsLost())
+ return;
+ if (texture &&
+ !texture->Validate(scoped.Context()->ContextGroup(), scoped.Context())) {
+ scoped.Context()->SynthesizeGLError(
+ GL_INVALID_OPERATION, "framebufferTextureMultiviewWEBGL",
+ "texture does not belong to this context");
+ return;
+ }
+ GLenum textarget = texture ? texture->GetTarget() : 0;
+ if (texture) {
+ if (textarget != GL_TEXTURE_2D_ARRAY) {
+ scoped.Context()->SynthesizeGLError(GL_INVALID_OPERATION,
+ "framebufferTextureMultiviewWEBGL",
+ "invalid texture type");
+ return;
+ }
+ if (num_views < 1) {
+ scoped.Context()->SynthesizeGLError(GL_INVALID_VALUE,
+ "framebufferTextureMultiviewWEBGL",
+ "numViews is less than one");
+ return;
+ }
+ if (num_views > max_views_ovr_) {
+ scoped.Context()->SynthesizeGLError(
+ GL_INVALID_VALUE, "framebufferTextureMultiviewWEBGL",
+ "numViews is more than the value of MAX_VIEWS_OVR");
+ return;
+ }
+ if (!static_cast<WebGL2RenderingContextBase*>(scoped.Context())
+ ->ValidateTexFuncLayer("framebufferTextureMultiviewWEBGL",
+ textarget, base_view_index))
+ return;
+ if (!static_cast<WebGL2RenderingContextBase*>(scoped.Context())
+ ->ValidateTexFuncLayer("framebufferTextureMultiviewWEBGL",
+ textarget, base_view_index + num_views - 1))
+ return;
+ if (!scoped.Context()->ValidateTexFuncLevel(
+ "framebufferTextureMultiviewWEBGL", textarget, level))
+ return;
+ }
+
+ WebGLFramebuffer* framebuffer_binding =
+ scoped.Context()->GetFramebufferBinding(target);
+ if (!framebuffer_binding || !framebuffer_binding->Object()) {
+ scoped.Context()->SynthesizeGLError(GL_INVALID_OPERATION,
+ "framebufferTextureMultiviewWEBGL",
+ "no framebuffer bound");
+ return;
+ }
+ // Don't allow modifications to opaque framebuffer attachements.
+ if (framebuffer_binding->Opaque()) {
+ scoped.Context()->SynthesizeGLError(GL_INVALID_OPERATION,
+ "framebufferTextureMultiviewWEBGL",
+ "opaque framebuffer bound");
+ return;
+ }
+
+ framebuffer_binding->SetAttachmentForBoundFramebuffer(
+ target, attachment, textarget, texture, level, base_view_index,
+ num_views);
+ scoped.Context()->ApplyStencilTest();
+}
+
+bool WebGLMultiview::Supported(WebGLRenderingContextBase* context) {
+ return context->ExtensionsUtil()->SupportsExtension("GL_ANGLE_multiview");
+}
+
+const char* WebGLMultiview::ExtensionName() {
+ return "WEBGL_multiview";
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_multiview.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_multiview.h
new file mode 100644
index 00000000000..d59c12442ed
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_multiview.h
@@ -0,0 +1,37 @@
+// 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_MULTIVIEW_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_WEBGL_MULTIVIEW_H_
+
+#include "third_party/blink/renderer/modules/webgl/webgl_extension.h"
+
+namespace blink {
+
+class WebGLMultiview final : public WebGLExtension {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ static WebGLMultiview* Create(WebGLRenderingContextBase*);
+ static bool Supported(WebGLRenderingContextBase*);
+ static const char* ExtensionName();
+
+ WebGLExtensionName GetName() const override;
+
+ void framebufferTextureMultiviewWEBGL(GLenum target,
+ GLenum attachment,
+ WebGLTexture* texture,
+ GLint level,
+ GLint baseViewIndex,
+ GLsizei numViews);
+
+ private:
+ explicit WebGLMultiview(WebGLRenderingContextBase*);
+
+ GLsizei max_views_ovr_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_WEBGL_MULTIVIEW_H_
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_multiview.idl b/chromium/third_party/blink/renderer/modules/webgl/webgl_multiview.idl
new file mode 100644
index 00000000000..2ca349ff2a8
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_multiview.idl
@@ -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.
+
+// https://www.khronos.org/registry/webgl/extensions/WEBGL_multiview/
+
+[
+ NoInterfaceObject,
+ DoNotCheckConstants
+]
+interface WebGLMultiview {
+ const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR = 0x9630;
+ const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR = 0x9632;
+ const GLenum MAX_VIEWS_OVR = 0x9631;
+ const GLenum FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR = 0x9633;
+
+ void framebufferTextureMultiviewWEBGL(GLenum target, GLenum attachment,
+ WebGLTexture? texture, GLint level,
+ GLint baseViewIndex,
+ GLsizei numViews);
+};
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 d3d659d6ddd..4c6e51707f4 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_program.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_program.cc
@@ -62,6 +62,10 @@ void WebGLProgram::DeleteObjectImpl(gpu::gles2::GLES2Interface* gl) {
fragment_shader_->OnDetached(gl);
fragment_shader_ = nullptr;
}
+ if (compute_shader_) {
+ compute_shader_->OnDetached(gl);
+ compute_shader_ = nullptr;
+ }
}
}
@@ -89,6 +93,8 @@ WebGLShader* WebGLProgram::GetAttachedShader(GLenum type) {
return vertex_shader_;
case GL_FRAGMENT_SHADER:
return fragment_shader_;
+ case GL_COMPUTE_SHADER:
+ return compute_shader_;
default:
return nullptr;
}
@@ -108,6 +114,11 @@ bool WebGLProgram::AttachShader(WebGLShader* shader) {
return false;
fragment_shader_ = shader;
return true;
+ case GL_COMPUTE_SHADER:
+ if (compute_shader_)
+ return false;
+ compute_shader_ = shader;
+ return true;
default:
return false;
}
@@ -127,6 +138,11 @@ bool WebGLProgram::DetachShader(WebGLShader* shader) {
return false;
fragment_shader_ = nullptr;
return true;
+ case GL_COMPUTE_SHADER:
+ if (compute_shader_ != shader)
+ return false;
+ compute_shader_ = nullptr;
+ return true;
default:
return false;
}
@@ -150,6 +166,7 @@ void WebGLProgram::CacheInfoIfNeeded(WebGLRenderingContextBase* context) {
void WebGLProgram::Trace(blink::Visitor* visitor) {
visitor->Trace(vertex_shader_);
visitor->Trace(fragment_shader_);
+ visitor->Trace(compute_shader_);
WebGLSharedPlatform3DObject::Trace(visitor);
}
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 063d217b140..40f0042022e 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_program.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_program.h
@@ -94,6 +94,7 @@ class WebGLProgram final : public WebGLSharedPlatform3DObject {
TraceWrapperMember<WebGLShader> vertex_shader_;
TraceWrapperMember<WebGLShader> fragment_shader_;
+ TraceWrapperMember<WebGLShader> compute_shader_;
bool info_valid_;
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 0e874487418..c5d482bba1d 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
@@ -113,7 +113,7 @@ CanvasRenderingContext* WebGLRenderingContext::Factory::Create(
void WebGLRenderingContext::Factory::OnError(HTMLCanvasElement* canvas,
const String& error) {
- canvas->DispatchEvent(WebGLContextEvent::Create(
+ canvas->DispatchEvent(*WebGLContextEvent::Create(
EventTypeNames::webglcontextcreationerror, error));
}
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 d22b722fcad..051cb2897f0 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
@@ -30,6 +30,7 @@
#include "base/numerics/checked_math.h"
#include "build/build_config.h"
#include "gpu/command_buffer/client/gles2_interface.h"
+#include "gpu/command_buffer/common/capabilities.h"
#include "gpu/config/gpu_feature_info.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/task_type.h"
@@ -783,7 +784,11 @@ scoped_refptr<StaticBitmapImage> WebGLRenderingContextBase::GetImage(
if (!GetDrawingBuffer())
return nullptr;
GetDrawingBuffer()->ResolveAndBindForReadAndDraw();
- IntSize size = ClampedCanvasSize();
+ // Use the drawing buffer size here instead of the canvas size to ensure that
+ // sizing is consistent for the GetStaticBitmapImage() result. The forced
+ // downsizing logic in Reshape() can lead to the drawing buffer being smaller
+ // than the canvas size. See https:://crbug.com/845742.
+ IntSize size = GetDrawingBuffer()->Size();
// 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)
@@ -792,7 +797,7 @@ scoped_refptr<StaticBitmapImage> WebGLRenderingContextBase::GetImage(
size, CanvasResourceProvider::kAcceleratedResourceUsage,
SharedGpuContext::ContextProviderWrapper(), 0, ColorParams(),
CanvasResourceProvider::kDefaultPresentationMode,
- nullptr); // canvas_resource_dispatcher
+ nullptr /* canvas_resource_dispatcher */, is_origin_top_left_);
if (!resource_provider || !resource_provider->IsValid())
return nullptr;
if (!CopyRenderingResultsFromDrawingBuffer(resource_provider.get(),
@@ -825,7 +830,8 @@ ScriptPromise WebGLRenderingContextBase::setCompatibleXRDevice(
compatible_xr_device_ = xr_device;
return ScriptPromise::CastUndefined(script_state);
} else {
- // TODO(offenwanger): Trigger context loss and recreate on compatible GPU.
+ // TODO(http://crbug.com/876140) Trigger context loss and recreate on
+ // compatible GPU.
return ScriptPromise::RejectWithDOMException(
script_state,
DOMException::Create(
@@ -1002,34 +1008,20 @@ WebGLRenderingContextBase::WebGLRenderingContextBase(
Platform::ContextType context_type)
: CanvasRenderingContext(host, requested_attributes),
context_group_(new WebGLContextGroup()),
- is_hidden_(false),
- context_lost_mode_(kNotLostContext),
- auto_recovery_method_(kManual),
dispatch_context_lost_event_timer_(
task_runner,
this,
&WebGLRenderingContextBase::DispatchContextLostEvent),
- restore_allowed_(false),
restore_timer_(task_runner,
this,
&WebGLRenderingContextBase::MaybeRestoreContext),
task_runner_(task_runner),
- generated_image_cache_(4),
- synthesized_errors_to_console_(true),
num_gl_errors_to_console_allowed_(kMaxGLErrorsAllowedToConsole),
- one_plus_max_non_default_texture_unit_(0),
- is_web_gl2_formats_types_added_(false),
- is_web_gl2_tex_image_source_formats_types_added_(false),
- is_web_gl2_internal_formats_copy_tex_image_added_(false),
- is_oes_texture_float_formats_types_added_(false),
- is_oes_texture_half_float_formats_types_added_(false),
- is_web_gl_depth_texture_formats_types_added_(false),
- is_ext_srgb_formats_types_added_(false),
- is_ext_color_buffer_float_formats_added_(false),
context_type_(context_type) {
DCHECK(context_provider);
- // TODO(offenwanger) Make sure this is being created on a compatible adapter.
+ // TODO(http://crbug.com/876140) Make sure this is being created on a
+ // compatible adapter.
compatible_xr_device_ =
static_cast<XRDevice*>(requested_attributes.compatible_xr_device.Get());
@@ -1123,8 +1115,8 @@ void WebGLRenderingContextBase::InitializeNewContext() {
DCHECK(!isContextLost());
DCHECK(GetDrawingBuffer());
- // TODO(offenwanger): Check if compatible_xr_device needs to be taken into
- // account here.
+ // TODO(http://crbug.com/876140) Does compatible_xr_device needs to be taken
+ // into account here?
marked_canvas_dirty_ = false;
animation_frame_in_progress_ = false;
@@ -1217,6 +1209,13 @@ void WebGLRenderingContextBase::InitializeNewContext() {
WTF::BindRepeating(&WebGLRenderingContextBase::OnErrorMessage,
WrapWeakPersistent(this)));
+ // If the context has the flip_y extension, it will behave as having the
+ // origin of coordinates on the top left.
+ is_origin_top_left_ = GetDrawingBuffer()
+ ->ContextProvider()
+ ->GetCapabilities()
+ .mesa_framebuffer_flip_y;
+
// If WebGL 2, the PRIMITIVE_RESTART_FIXED_INDEX should be always enabled.
// See the section <Primitive Restart is Always Enabled> in WebGL 2 spec:
// https://www.khronos.org/registry/webgl/specs/latest/2.0/#4.1.4
@@ -1522,6 +1521,12 @@ void WebGLRenderingContextBase::MarkLayerComposited() {
GetDrawingBuffer()->ResetBuffersToAutoClear();
}
+bool WebGLRenderingContextBase::IsOriginTopLeft() const {
+ if (isContextLost())
+ return false;
+ return is_origin_top_left_;
+}
+
void WebGLRenderingContextBase::SetIsHidden(bool hidden) {
is_hidden_ = hidden;
if (GetDrawingBuffer())
@@ -1543,10 +1548,13 @@ bool WebGLRenderingContextBase::PaintRenderingResultsToCanvas(
if (!marked_canvas_dirty_ && !must_clear_now)
return false;
- if (canvas())
- canvas()->ClearCopiedImage();
marked_canvas_dirty_ = false;
+ if (Host()->ResourceProvider() &&
+ Host()->ResourceProvider()->Size() != GetDrawingBuffer()->Size()) {
+ Host()->DiscardResourceProvider();
+ }
+
if (!Host()->GetOrCreateCanvasResourceProvider(kPreferAcceleration))
return false;
@@ -1568,7 +1576,8 @@ bool WebGLRenderingContextBase::PaintRenderingResultsToCanvas(
bool WebGLRenderingContextBase::ContextCreatedOnCompatibleAdapter(
const XRDevice* device) {
- // TODO(offenwanger): Determine if device is compatible with current context.
+ // TODO(http://crbug.com/876140) Determine if device is compatible with
+ // current context.
return true;
}
@@ -1594,8 +1603,9 @@ bool WebGLRenderingContextBase::CopyRenderingResultsFromDrawingBuffer(
gl->Flush();
return drawing_buffer_->CopyToPlatformTexture(
- gl, GL_TEXTURE_2D, texture_id, true, false, IntPoint(0, 0),
- IntRect(IntPoint(0, 0), drawing_buffer_->Size()), source_buffer);
+ gl, GL_TEXTURE_2D, texture_id, true, is_origin_top_left_,
+ 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
@@ -2297,11 +2307,29 @@ void WebGLRenderingContextBase::SetBoundVertexArrayObject(
bound_vertex_array_object_ = default_vertex_array_object_;
}
+bool WebGLRenderingContextBase::ValidateShaderType(const char* function_name,
+ GLenum shader_type) {
+ switch (shader_type) {
+ case GL_VERTEX_SHADER:
+ case GL_FRAGMENT_SHADER:
+ return true;
+ case GL_COMPUTE_SHADER:
+ if (context_type_ != Platform::kWebGL2ComputeContextType) {
+ SynthesizeGLError(GL_INVALID_ENUM, function_name,
+ "invalid shader type");
+ return false;
+ }
+ return true;
+ default:
+ SynthesizeGLError(GL_INVALID_ENUM, function_name, "invalid shader type");
+ return false;
+ }
+}
+
WebGLShader* WebGLRenderingContextBase::createShader(GLenum type) {
if (isContextLost())
return nullptr;
- if (type != GL_VERTEX_SHADER && type != GL_FRAGMENT_SHADER) {
- SynthesizeGLError(GL_INVALID_ENUM, "createShader", "invalid shader type");
+ if (!ValidateShaderType("createShader", type)) {
return nullptr;
}
@@ -2697,7 +2725,7 @@ void WebGLRenderingContextBase::framebufferTexture2D(GLenum target,
return;
}
framebuffer_binding->SetAttachmentForBoundFramebuffer(
- target, attachment, textarget, texture, level, 0);
+ target, attachment, textarget, texture, level, 0, 0);
ApplyStencilTest();
}
@@ -2781,7 +2809,8 @@ WebGLRenderingContextBase::getAttachedShaders(WebGLProgram* program) {
return base::nullopt;
HeapVector<Member<WebGLShader>> shader_objects;
- const GLenum kShaderType[] = {GL_VERTEX_SHADER, GL_FRAGMENT_SHADER};
+ const GLenum kShaderType[] = {GL_VERTEX_SHADER, GL_FRAGMENT_SHADER,
+ GL_COMPUTE_SHADER};
for (unsigned i = 0; i < sizeof(kShaderType) / sizeof(GLenum); ++i) {
WebGLShader* shader = program->GetAttachedShader(kShaderType[i]);
if (shader)
@@ -3307,7 +3336,12 @@ ScriptValue WebGLRenderingContextBase::getParameter(ScriptState* script_state,
GL_INVALID_ENUM, "getParameter",
"invalid parameter name, EXT_disjoint_timer_query not enabled");
return ScriptValue::CreateNull(script_state);
-
+ case GL_MAX_VIEWS_OVR:
+ if (ExtensionEnabled(kWebGLMultiviewName))
+ return GetIntParameter(script_state, pname);
+ SynthesizeGLError(GL_INVALID_ENUM, "getParameter",
+ "invalid parameter name, WEBGL_multiview not enabled");
+ return ScriptValue::CreateNull(script_state);
default:
if ((ExtensionEnabled(kWebGLDrawBuffersName) || IsWebGL2OrHigher()) &&
pname >= GL_DRAW_BUFFER0_EXT &&
@@ -3456,14 +3490,8 @@ WebGLShaderPrecisionFormat* WebGLRenderingContextBase::getShaderPrecisionFormat(
GLenum precision_type) {
if (isContextLost())
return nullptr;
- switch (shader_type) {
- case GL_VERTEX_SHADER:
- case GL_FRAGMENT_SHADER:
- break;
- default:
- SynthesizeGLError(GL_INVALID_ENUM, "getShaderPrecisionFormat",
- "invalid shader type");
- return nullptr;
+ if (!ValidateShaderType("getShaderPrecisionFormat", shader_type)) {
+ return nullptr;
}
switch (precision_type) {
case GL_LOW_FLOAT:
@@ -3743,6 +3771,27 @@ ScriptValue WebGLRenderingContextBase::getUniform(
base_type = GL_INT;
length = 1;
break;
+ case GL_IMAGE_2D:
+ case GL_IMAGE_3D:
+ case GL_IMAGE_CUBE:
+ case GL_IMAGE_2D_ARRAY:
+ case GL_INT_IMAGE_2D:
+ case GL_INT_IMAGE_3D:
+ case GL_INT_IMAGE_CUBE:
+ case GL_INT_IMAGE_2D_ARRAY:
+ case GL_UNSIGNED_INT_IMAGE_2D:
+ case GL_UNSIGNED_INT_IMAGE_3D:
+ case GL_UNSIGNED_INT_IMAGE_CUBE:
+ case GL_UNSIGNED_INT_IMAGE_2D_ARRAY: {
+ if (context_type_ != Platform::kWebGL2ComputeContextType) {
+ SynthesizeGLError(GL_INVALID_VALUE, "getUniform",
+ "unhandled type");
+ return ScriptValue::CreateNull(script_state);
+ }
+ base_type = GL_INT;
+ length = 1;
+ break;
+ }
default:
// Can't handle this type
SynthesizeGLError(GL_INVALID_VALUE, "getUniform",
@@ -4498,6 +4547,7 @@ void WebGLRenderingContextBase::TexImage2DBase(GLenum target,
height, border, format, type, pixels);
}
+// Software-based upload of Image* to WebGL texture.
void WebGLRenderingContextBase::TexImageImpl(
TexImageFunctionID function_id,
GLenum target,
@@ -5027,8 +5077,8 @@ void WebGLRenderingContextBase::texImage2D(ExecutionContext* execution_context,
SentinelEmptyRect(), 1, 0, exception_state);
}
-bool WebGLRenderingContextBase::CanUseTexImageByGPU(GLenum format,
- GLenum type) {
+bool WebGLRenderingContextBase::CanUseTexImageViaGPU(GLenum format,
+ GLenum type) {
#if defined(OS_MACOSX)
// RGB5_A1 is not color-renderable on NVIDIA Mac, see crbug.com/676209.
// Though, glCopyTextureCHROMIUM can handle RGB5_A1 internalformat by doing a
@@ -5063,42 +5113,7 @@ bool WebGLRenderingContextBase::CanUseTexImageByGPU(GLenum format,
return true;
}
-void WebGLRenderingContextBase::TexImageCanvasByGPU(
- TexImageFunctionID function_id,
- HTMLCanvasElement* canvas,
- GLenum target,
- GLuint target_texture,
- GLint xoffset,
- GLint yoffset,
- const IntRect& source_sub_rectangle) {
- if (!canvas->Is3d()) {
- if (Extensions3DUtil::CanUseCopyTextureCHROMIUM(target) &&
- canvas->GetOrCreateCanvas2DLayerBridge()) {
- scoped_refptr<StaticBitmapImage> image =
- canvas->GetCanvas2DLayerBridge()->NewImageSnapshot(
- kPreferAcceleration);
- if (!!image && image->CopyToTexture(
- ContextGL(), target, target_texture,
- unpack_premultiply_alpha_, unpack_flip_y_,
- IntPoint(xoffset, yoffset), source_sub_rectangle)) {
- return;
- }
- }
- NOTREACHED();
- } else {
- WebGLRenderingContextBase* gl =
- ToWebGLRenderingContextBase(canvas->RenderingContext());
- ScopedTexture2DRestorer restorer(gl);
- if (!gl->GetDrawingBuffer()->CopyToPlatformTexture(
- ContextGL(), target, target_texture, unpack_premultiply_alpha_,
- !unpack_flip_y_, IntPoint(xoffset, yoffset), source_sub_rectangle,
- kBackBuffer)) {
- NOTREACHED();
- }
- }
-}
-
-void WebGLRenderingContextBase::TexImageByGPU(
+void WebGLRenderingContextBase::TexImageViaGPU(
TexImageFunctionID function_id,
WebGLTexture* texture,
GLenum target,
@@ -5106,9 +5121,15 @@ void WebGLRenderingContextBase::TexImageByGPU(
GLint xoffset,
GLint yoffset,
GLint zoffset,
- CanvasImageSource* image,
- const IntRect& source_sub_rectangle) {
- DCHECK(image->IsCanvasElement() || image->IsImageBitmap());
+ AcceleratedStaticBitmapImage* source_image,
+ WebGLRenderingContextBase* source_canvas_webgl_context,
+ const IntRect& source_sub_rectangle,
+ bool premultiply_alpha,
+ bool flip_y) {
+ bool have_source_image = source_image;
+ bool have_source_canvas_webgl_context = source_canvas_webgl_context;
+ DCHECK(have_source_image ^ have_source_canvas_webgl_context);
+
int width = source_sub_rectangle.Width();
int height = source_sub_rectangle.Height();
@@ -5148,14 +5169,21 @@ void WebGLRenderingContextBase::TexImageByGPU(
// glCopyTextureCHROMIUM has a DRAW_AND_READBACK path which will call
// texImage2D. So, reset unpack buffer parameters before that.
ScopedUnpackParametersResetRestore temporaryResetUnpack(this);
- if (image->IsCanvasElement()) {
- TexImageCanvasByGPU(function_id, static_cast<HTMLCanvasElement*>(image),
- copy_target, target_texture, copy_x_offset,
- copy_y_offset, source_sub_rectangle);
+ if (source_image) {
+ source_image->CopyToTexture(
+ ContextGL(), target, target_texture, premultiply_alpha, flip_y,
+ IntPoint(xoffset, yoffset), source_sub_rectangle);
} else {
- TexImageBitmapByGPU(static_cast<ImageBitmap*>(image), copy_target,
- target_texture, copy_x_offset, copy_y_offset,
- source_sub_rectangle);
+ WebGLRenderingContextBase* gl = source_canvas_webgl_context;
+ if (gl->is_origin_top_left_)
+ flip_y = !flip_y;
+ ScopedTexture2DRestorer restorer(gl);
+ if (!gl->GetDrawingBuffer()->CopyToPlatformTexture(
+ ContextGL(), target, target_texture, unpack_premultiply_alpha_,
+ !flip_y, IntPoint(xoffset, yoffset), source_sub_rectangle,
+ kBackBuffer)) {
+ NOTREACHED();
+ }
}
}
@@ -5183,7 +5211,7 @@ void WebGLRenderingContextBase::TexImageByGPU(
}
}
-void WebGLRenderingContextBase::TexImageHelperHTMLCanvasElement(
+void WebGLRenderingContextBase::TexImageHelperCanvasRenderingContextHost(
const SecurityOrigin* security_origin,
TexImageFunctionID function_id,
GLenum target,
@@ -5194,7 +5222,7 @@ void WebGLRenderingContextBase::TexImageHelperHTMLCanvasElement(
GLint xoffset,
GLint yoffset,
GLint zoffset,
- HTMLCanvasElement* canvas,
+ CanvasRenderingContextHost* context_host,
const IntRect& source_sub_rectangle,
GLsizei depth,
GLint unpack_image_height,
@@ -5203,8 +5231,8 @@ void WebGLRenderingContextBase::TexImageHelperHTMLCanvasElement(
if (isContextLost())
return;
- if (!ValidateHTMLCanvasElement(security_origin, func_name, canvas,
- exception_state))
+ if (!ValidateCanvasRenderingContextHost(security_origin, func_name,
+ context_host, exception_state))
return;
WebGLTexture* texture =
ValidateTexImageBinding(func_name, function_id, target);
@@ -5227,29 +5255,51 @@ void WebGLRenderingContextBase::TexImageHelperHTMLCanvasElement(
// (texImageImpl).
bool selecting_sub_rectangle = false;
if (!ValidateTexImageSubRectangle(
- func_name, function_id, canvas, source_sub_rectangle, depth,
+ func_name, function_id, context_host, source_sub_rectangle, depth,
unpack_image_height, &selecting_sub_rectangle)) {
return;
}
- if (function_id == kTexImage2D || function_id == kTexSubImage2D) {
- // texImageByGPU relies on copyTextureCHROMIUM which doesn't support
- // float/integer/sRGB internal format.
- // TODO(crbug.com/622958): relax the constrains if copyTextureCHROMIUM is
- // upgraded to handle more formats.
- if (!canvas->IsAccelerated() || !CanUseTexImageByGPU(format, type)) {
- TexImageImpl(function_id, target, level, internalformat, xoffset, yoffset,
- zoffset, format, type,
- canvas->CopiedImage(kBackBuffer, kPreferAcceleration).get(),
- WebGLImageConversion::kHtmlDomCanvas, unpack_flip_y_,
- unpack_premultiply_alpha_, source_sub_rectangle, 1, 0);
+ bool is_webgl_canvas = context_host->Is3d();
+ WebGLRenderingContextBase* source_canvas_webgl_context = nullptr;
+ SourceImageStatus source_image_status = kInvalidSourceImageStatus;
+ scoped_refptr<Image> image;
+
+ bool upload_via_gpu =
+ (function_id == kTexImage2D || function_id == kTexSubImage2D) &&
+ CanUseTexImageViaGPU(format, type);
+
+ // The Image-based upload path may still be used for WebGL-rendered
+ // canvases in the case of driver bug workarounds
+ // (e.g. CanUseTexImageViaGPU returning false).
+ if (is_webgl_canvas && upload_via_gpu) {
+ source_canvas_webgl_context =
+ ToWebGLRenderingContextBase(context_host->RenderingContext());
+ } else {
+ image = context_host->GetSourceImageForCanvas(
+ &source_image_status, kPreferAcceleration,
+ FloatSize(source_sub_rectangle.Width(), source_sub_rectangle.Height()));
+ if (source_image_status != kNormalSourceImageStatus)
return;
+ }
+
+ // Still not clear whether we will take the accelerated upload path
+ // at this point; it depends on what came back from
+ // CanUseTexImageViaGPU, for example.
+ upload_via_gpu &= source_canvas_webgl_context ||
+ (image->IsStaticBitmapImage() && image->IsTextureBacked());
+
+ if (upload_via_gpu) {
+ AcceleratedStaticBitmapImage* accel_image = nullptr;
+ if (image) {
+ accel_image = static_cast<AcceleratedStaticBitmapImage*>(
+ ToStaticBitmapImage(image.get()));
}
// The GPU-GPU copy path uses the Y-up coordinate system.
IntRect adjusted_source_sub_rectangle = source_sub_rectangle;
if (!unpack_flip_y_) {
- adjusted_source_sub_rectangle.SetY(canvas->height() -
+ adjusted_source_sub_rectangle.SetY(context_host->Size().Height() -
adjusted_source_sub_rectangle.MaxY());
}
@@ -5257,39 +5307,46 @@ void WebGLRenderingContextBase::TexImageHelperHTMLCanvasElement(
TexImage2DBase(target, level, internalformat,
source_sub_rectangle.Width(),
source_sub_rectangle.Height(), 0, format, type, nullptr);
- TexImageByGPU(function_id, texture, target, level, 0, 0, 0, canvas,
- adjusted_source_sub_rectangle);
+ TexImageViaGPU(function_id, texture, target, level, 0, 0, 0, accel_image,
+ source_canvas_webgl_context, adjusted_source_sub_rectangle,
+ unpack_premultiply_alpha_, unpack_flip_y_);
} else {
- TexImageByGPU(function_id, texture, target, level, xoffset, yoffset, 0,
- canvas, adjusted_source_sub_rectangle);
+ TexImageViaGPU(function_id, texture, target, level, xoffset, yoffset, 0,
+ accel_image, source_canvas_webgl_context,
+ adjusted_source_sub_rectangle, unpack_premultiply_alpha_,
+ unpack_flip_y_);
}
} else {
- // 3D functions.
-
- // TODO(zmo): Implement GPU-to-GPU copy path (crbug.com/612542).
- // Note that code will also be needed to copy to layers of 3D
- // textures, and elements of 2D texture arrays.
+ // If these are the 2D functions, the caller must have passed in 1
+ // for the depth and 0 for the unpack_image_height.
+ DCHECK(!(function_id == kTexSubImage2D || function_id == kTexSubImage2D) ||
+ (depth == 1 && unpack_image_height == 0));
+ // We expect an Image at this point, not a WebGL-rendered canvas.
+ DCHECK(image);
+ // TODO(crbug.com/612542): Implement GPU-to-GPU copy path for more
+ // cases, like copying to layers of 3D textures, and elements of
+ // 2D texture arrays.
TexImageImpl(function_id, target, level, internalformat, xoffset, yoffset,
- zoffset, format, type,
- canvas->CopiedImage(kBackBuffer, kPreferAcceleration).get(),
+ zoffset, format, type, image.get(),
WebGLImageConversion::kHtmlDomCanvas, unpack_flip_y_,
unpack_premultiply_alpha_, source_sub_rectangle, depth,
unpack_image_height);
}
}
-void WebGLRenderingContextBase::texImage2D(ExecutionContext* execution_context,
- GLenum target,
- GLint level,
- GLint internalformat,
- GLenum format,
- GLenum type,
- HTMLCanvasElement* canvas,
- ExceptionState& exception_state) {
- TexImageHelperHTMLCanvasElement(
+void WebGLRenderingContextBase::texImage2D(
+ ExecutionContext* execution_context,
+ GLenum target,
+ GLint level,
+ GLint internalformat,
+ GLenum format,
+ GLenum type,
+ CanvasRenderingContextHost* context_host,
+ ExceptionState& exception_state) {
+ TexImageHelperCanvasRenderingContextHost(
execution_context->GetSecurityOrigin(), kTexImage2D, target, level,
- internalformat, format, type, 0, 0, 0, canvas,
- GetTextureSourceSize(canvas), 1, 0, exception_state);
+ internalformat, format, type, 0, 0, 0, context_host,
+ GetTextureSourceSize(context_host), 1, 0, exception_state);
}
scoped_refptr<Image> WebGLRenderingContextBase::VideoFrameToImage(
@@ -5374,13 +5431,14 @@ void WebGLRenderingContextBase::TexImageHelperHTMLVideoElement(
const bool use_copyTextureCHROMIUM = function_id == kTexImage2D &&
source_image_rect_is_default &&
depth == 1 && GL_TEXTURE_2D == target &&
- CanUseTexImageByGPU(format, type);
+ 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
// cause precision lost. So, uploading such video texture to half float or
// float texture can not use GPU-GPU path.
if (use_copyTextureCHROMIUM) {
+ DCHECK(Extensions3DUtil::CanUseCopyTextureCHROMIUM(target));
DCHECK_EQ(xoffset, 0);
DCHECK_EQ(yoffset, 0);
DCHECK_EQ(zoffset, 0);
@@ -5395,6 +5453,17 @@ void WebGLRenderingContextBase::TexImageHelperHTMLVideoElement(
texture->UpdateLastUploadedFrame(frame_metadata);
return;
}
+
+ // For certain video frame formats (e.g. I420/YUV), if they start on the CPU
+ // (e.g. video camera frames): upload them to the GPU, do a GPU decode, and
+ // then copy into the target texture.
+ if (video->CopyVideoYUVDataToPlatformTexture(
+ ContextGL(), target, texture->Object(), internalformat, format,
+ type, level, unpack_premultiply_alpha_, unpack_flip_y_,
+ already_uploaded_id, frame_metadata_ptr)) {
+ texture->UpdateLastUploadedFrame(frame_metadata);
+ return;
+ }
}
if (source_image_rect_is_default) {
@@ -5414,50 +5483,6 @@ void WebGLRenderingContextBase::TexImageHelperHTMLVideoElement(
}
}
- if (use_copyTextureCHROMIUM) {
- // Try using an accelerated image buffer, this allows YUV conversion to be
- // done on the GPU.
- std::unique_ptr<CanvasResourceProvider> resource_provider =
- CanvasResourceProvider::Create(
- IntSize(video->videoWidth(), video->videoHeight()),
- CanvasResourceProvider::kAcceleratedResourceUsage,
- SharedGpuContext::ContextProviderWrapper(),
- 0, // msaa_sample_count
- CanvasColorParams(),
- CanvasResourceProvider::kDefaultPresentationMode,
- nullptr); // canvas_resource_dispatcher
- if (resource_provider && resource_provider->IsValid()) {
- // The video element paints an RGBA frame into our surface here. By
- // using an AcceleratedImageBufferSurface, we enable the WebMediaPlayer
- // implementation to do any necessary color space conversion on the GPU
- // (though it may still do a CPU conversion and upload the results).
- video->PaintCurrentFrame(
- resource_provider->Canvas(),
- IntRect(0, 0, video->videoWidth(), video->videoHeight()), nullptr,
- already_uploaded_id, frame_metadata_ptr);
-
- // This is a straight GPU-GPU copy, any necessary color space conversion
- // was handled in the paintCurrentFrameInContext() call.
-
- // Note that copyToPlatformTexture no longer allocates the destination
- // texture.
- TexImage2DBase(target, level, internalformat, video->videoWidth(),
- video->videoHeight(), 0, format, type, nullptr);
-
- if (Extensions3DUtil::CanUseCopyTextureCHROMIUM(target)) {
- scoped_refptr<StaticBitmapImage> image = resource_provider->Snapshot();
- if (!!image &&
- image->CopyToTexture(
- ContextGL(), target, texture->Object(),
- unpack_premultiply_alpha_, unpack_flip_y_, IntPoint(0, 0),
- IntRect(0, 0, video->videoWidth(), video->videoHeight()))) {
- texture->UpdateLastUploadedFrame(frame_metadata);
- return;
- }
- }
- }
- }
-
scoped_refptr<Image> image =
VideoFrameToImage(video, already_uploaded_id, frame_metadata_ptr);
if (!image)
@@ -5470,21 +5495,6 @@ void WebGLRenderingContextBase::TexImageHelperHTMLVideoElement(
texture->UpdateLastUploadedFrame(frame_metadata);
}
-void WebGLRenderingContextBase::TexImageBitmapByGPU(
- ImageBitmap* bitmap,
- GLenum target,
- GLuint target_texture,
- GLint xoffset,
- GLint yoffset,
- const IntRect& source_sub_rect) {
- // We hard-code premultiply_alpha and flip_y values because these values
- // should have been already manipulated during construction of ImageBitmap.
- bitmap->BitmapImage()->CopyToTexture(
- GetDrawingBuffer()->ContextProvider()->ContextGL(), target,
- target_texture, true /* unpack_premultiply_alpha */,
- false /* unpack_flip_y_ */, IntPoint(xoffset, yoffset), source_sub_rect);
-}
-
void WebGLRenderingContextBase::texImage2D(ExecutionContext* execution_context,
GLenum target,
GLint level,
@@ -5543,25 +5553,41 @@ void WebGLRenderingContextBase::TexImageHelperImageBitmap(
level, internalformat, width, height, depth, 0, format,
type, xoffset, yoffset, zoffset))
return;
- DCHECK(bitmap->BitmapImage());
+ scoped_refptr<StaticBitmapImage> image = bitmap->BitmapImage();
+ DCHECK(image);
// TODO(kbr): make this work for sub-rectangles of ImageBitmaps.
if (function_id != kTexSubImage3D && function_id != kTexImage3D &&
- bitmap->IsAccelerated() && CanUseTexImageByGPU(format, type) &&
+ image->IsTextureBacked() && CanUseTexImageViaGPU(format, type) &&
!selecting_sub_rectangle) {
+ AcceleratedStaticBitmapImage* accel_image =
+ static_cast<AcceleratedStaticBitmapImage*>(image.get());
+ // We hard-code premultiply_alpha and flip_y values because these should
+ // have already been manipulated during construction of the ImageBitmap.
+ bool premultiply_alpha = true; // TODO(kbr): this looks wrong!
+ bool flip_y = false;
if (function_id == kTexImage2D) {
TexImage2DBase(target, level, internalformat, width, height, 0, format,
type, nullptr);
- TexImageByGPU(function_id, texture, target, level, 0, 0, 0, bitmap,
- source_sub_rect);
+ TexImageViaGPU(function_id, texture, target, level, 0, 0, 0, accel_image,
+ nullptr, source_sub_rect, premultiply_alpha, flip_y);
} else if (function_id == kTexSubImage2D) {
- TexImageByGPU(function_id, texture, target, level, xoffset, yoffset, 0,
- bitmap, source_sub_rect);
+ TexImageViaGPU(function_id, texture, target, level, xoffset, yoffset, 0,
+ accel_image, nullptr, source_sub_rect, premultiply_alpha,
+ flip_y);
}
return;
}
+
+ // TODO(kbr): refactor this away to use TexImageImpl on image.
sk_sp<SkImage> sk_image =
bitmap->BitmapImage()->PaintImageForCurrentFrame().GetSkImage();
+ if (!sk_image) {
+ SynthesizeGLError(GL_OUT_OF_MEMORY, func_name,
+ "ImageBitmap unexpectedly empty");
+ return;
+ }
+
SkPixmap pixmap;
uint8_t* pixel_data_ptr = nullptr;
scoped_refptr<Uint8Array> pixel_data;
@@ -5765,12 +5791,12 @@ void WebGLRenderingContextBase::texSubImage2D(
GLint yoffset,
GLenum format,
GLenum type,
- HTMLCanvasElement* canvas,
+ CanvasRenderingContextHost* context_host,
ExceptionState& exception_state) {
- TexImageHelperHTMLCanvasElement(
+ TexImageHelperCanvasRenderingContextHost(
execution_context->GetSecurityOrigin(), kTexSubImage2D, target, level, 0,
- format, type, xoffset, yoffset, 0, canvas, GetTextureSourceSize(canvas),
- 1, 0, exception_state);
+ format, type, xoffset, yoffset, 0, context_host,
+ GetTextureSourceSize(context_host), 1, 0, exception_state);
}
void WebGLRenderingContextBase::texSubImage2D(
@@ -7509,17 +7535,17 @@ bool WebGLRenderingContextBase::ValidateHTMLImageElement(
return true;
}
-bool WebGLRenderingContextBase::ValidateHTMLCanvasElement(
+bool WebGLRenderingContextBase::ValidateCanvasRenderingContextHost(
const SecurityOrigin* security_origin,
const char* function_name,
- HTMLCanvasElement* canvas,
+ CanvasRenderingContextHost* context_host,
ExceptionState& exception_state) {
- if (!canvas || !canvas->IsPaintable()) {
+ if (!context_host || !context_host->IsPaintable()) {
SynthesizeGLError(GL_INVALID_VALUE, function_name, "no canvas");
return false;
}
- if (WouldTaintOrigin(canvas, security_origin)) {
+ if (WouldTaintOrigin(context_host, security_origin)) {
exception_state.ThrowSecurityError("Tainted canvases may not be loaded.");
return false;
}
@@ -7745,7 +7771,7 @@ CanvasResourceProvider* WebGLRenderingContextBase::
nullptr)); // canvas_resource_dispatcher
if (!temp)
return nullptr;
- i = std::min(resource_providers_.size() - 1, i);
+ i = std::min(static_cast<size_t>(resource_providers_.size() - 1), i);
resource_providers_[i] = std::move(temp);
CanvasResourceProvider* resource_provider = resource_providers_[i].get();
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 bed21bdfaf2..424f8bcf4f6 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
@@ -55,6 +55,7 @@
#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"
+#include "third_party/khronos/GLES3/gl31.h"
namespace cc {
class Layer;
@@ -68,6 +69,7 @@ class GLES2Interface;
namespace blink {
+class AcceleratedStaticBitmapImage;
class CanvasResourceProvider;
class EXTDisjointTimerQuery;
class EXTDisjointTimerQueryWebGL2;
@@ -373,7 +375,7 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
GLint internalformat,
GLenum format,
GLenum type,
- HTMLCanvasElement*,
+ CanvasRenderingContextHost*,
ExceptionState&);
void texImage2D(ExecutionContext*,
GLenum target,
@@ -426,7 +428,7 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
GLint yoffset,
GLenum format,
GLenum type,
- HTMLCanvasElement*,
+ CanvasRenderingContextHost*,
ExceptionState&);
void texSubImage2D(ExecutionContext*,
GLenum target,
@@ -630,6 +632,7 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
friend class WebGLCompressedTexturePVRTC;
friend class WebGLCompressedTextureS3TC;
friend class WebGLCompressedTextureS3TCsRGB;
+ friend class WebGLMultiview;
friend class WebGLRenderingContextErrorMessageCallback;
friend class WebGLVertexArrayObjectBase;
friend class ScopedDrawingBufferBinder;
@@ -651,6 +654,7 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
bool Is3d() const override { return true; }
bool IsComposited() const override { return true; }
bool IsAccelerated() const override { return true; }
+ bool IsOriginTopLeft() const override;
void SetIsHidden(bool) override;
bool PaintRenderingResultsToCanvas(SourceDrawingBuffer) override;
cc::Layer* CcLayer() const override;
@@ -709,16 +713,18 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
TraceWrapperMember<WebGLContextGroup> context_group_;
- bool is_hidden_;
- LostContextMode context_lost_mode_;
- AutoRecoveryMethod auto_recovery_method_;
+ bool is_origin_top_left_ = false;
+
+ bool is_hidden_ = false;
+ LostContextMode context_lost_mode_ = kNotLostContext;
+ AutoRecoveryMethod auto_recovery_method_ = kManual;
// Dispatches a context lost event once it is determined that one is needed.
// This is used for synthetic, WEBGL_lose_context and real context losses. For
// real ones, it's likely that there's no JavaScript on the stack, but that
// might be dependent on how exactly the platform discovers that the context
// was lost. For better portability we always defer the dispatch of the event.
TaskRunnerTimer<WebGLRenderingContextBase> dispatch_context_lost_event_timer_;
- bool restore_allowed_;
+ bool restore_allowed_ = false;
TaskRunnerTimer<WebGLRenderingContextBase> restore_timer_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
@@ -766,7 +772,8 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
void BubbleToFront(size_t idx);
Vector<std::unique_ptr<CanvasResourceProvider>> resource_providers_;
};
- LRUCanvasResourceProviderCache generated_image_cache_;
+ LRUCanvasResourceProviderCache generated_image_cache_ =
+ LRUCanvasResourceProviderCache(4);
GLint max_texture_size_;
GLint max_cube_map_texture_size_;
@@ -813,10 +820,10 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
bool is_depth_stencil_supported_;
- bool synthesized_errors_to_console_;
+ bool synthesized_errors_to_console_ = true;
int num_gl_errors_to_console_allowed_;
- unsigned long one_plus_max_non_default_texture_unit_;
+ unsigned long one_plus_max_non_default_texture_unit_ = 0;
std::unique_ptr<Extensions3DUtil> extensions_util_;
@@ -962,14 +969,14 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
// Other errors raised by synthesizeGLError().
Vector<GLenum> synthetic_errors_;
- bool is_web_gl2_formats_types_added_;
- bool is_web_gl2_tex_image_source_formats_types_added_;
- bool is_web_gl2_internal_formats_copy_tex_image_added_;
- bool is_oes_texture_float_formats_types_added_;
- bool is_oes_texture_half_float_formats_types_added_;
- bool is_web_gl_depth_texture_formats_types_added_;
- bool is_ext_srgb_formats_types_added_;
- bool is_ext_color_buffer_float_formats_added_;
+ bool is_web_gl2_formats_types_added_ = false;
+ bool is_web_gl2_tex_image_source_formats_types_added_ = false;
+ bool is_web_gl2_internal_formats_copy_tex_image_added_ = false;
+ bool is_oes_texture_float_formats_types_added_ = false;
+ bool is_oes_texture_half_float_formats_types_added_ = false;
+ 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;
std::set<GLenum> supported_internal_formats_;
std::set<GLenum> supported_tex_image_source_internal_formats_;
@@ -1048,7 +1055,6 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
const IntRect&,
GLsizei depth,
GLint unpack_image_height);
-
template <typename T>
IntRect GetTextureSourceSize(T* texture_source) {
return IntRect(0, 0, texture_source->width(), texture_source->height());
@@ -1064,7 +1070,12 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
bool* selecting_sub_rectangle) {
DCHECK(function_name);
DCHECK(selecting_sub_rectangle);
- DCHECK(image);
+ if (!image) {
+ // Probably indicates a failure to allocate the image.
+ SynthesizeGLError(GL_OUT_OF_MEMORY, function_name, "out of memory");
+ return false;
+ }
+
int image_width = static_cast<int>(image->width());
int image_height = static_cast<int>(image->height());
*selecting_sub_rectangle =
@@ -1130,19 +1141,6 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
return true;
}
- // Copy from the source directly to the texture via the gpu, without a
- // read-back to system memory. Source could be canvas or imageBitmap.
- void TexImageByGPU(TexImageFunctionID,
- WebGLTexture*,
- GLenum target,
- GLint level,
- GLint xoffset,
- GLint yoffset,
- GLint zoffset,
- CanvasImageSource*,
- const IntRect& source_sub_rectangle);
- bool CanUseTexImageByGPU(GLenum format, GLenum type);
-
virtual WebGLImageConversion::PixelStoreParams GetPackPixelStoreParams();
virtual WebGLImageConversion::PixelStoreParams GetUnpackPixelStoreParams(
TexImageDimension);
@@ -1447,12 +1445,12 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
HTMLImageElement*,
ExceptionState&);
- // Helper function for tex{Sub}Image2D to make sure canvas is ready and
- // wouldn't taint Origin.
- bool ValidateHTMLCanvasElement(const SecurityOrigin*,
- const char* function_name,
- HTMLCanvasElement*,
- ExceptionState&);
+ // Helper function for tex{Sub}Image2D to make sure canvas or OffscreenCanvas
+ // is ready and wouldn't taint Origin.
+ bool ValidateCanvasRenderingContextHost(const SecurityOrigin*,
+ const char* function_name,
+ CanvasRenderingContextHost*,
+ ExceptionState&);
// Helper function for tex{Sub}Image2D to make sure video is ready wouldn't
// taint Origin.
@@ -1613,21 +1611,21 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
GLint,
ExceptionState&);
- void TexImageHelperHTMLCanvasElement(const SecurityOrigin*,
- TexImageFunctionID,
- GLenum,
- GLint,
- GLint,
- GLenum,
- GLenum,
- GLint,
- GLint,
- GLint,
- HTMLCanvasElement*,
- const IntRect&,
- GLsizei,
- GLint,
- ExceptionState&);
+ void TexImageHelperCanvasRenderingContextHost(const SecurityOrigin*,
+ TexImageFunctionID,
+ GLenum,
+ GLint,
+ GLint,
+ GLenum,
+ GLenum,
+ GLint,
+ GLint,
+ GLint,
+ CanvasRenderingContextHost*,
+ const IntRect&,
+ GLsizei,
+ GLint,
+ ExceptionState&);
void TexImageHelperHTMLVideoElement(const SecurityOrigin*,
TexImageFunctionID,
@@ -1686,19 +1684,24 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
const CanvasContextCreationAttributesCore&,
Platform::ContextType context_type,
bool* using_gpu_compositing);
- void TexImageCanvasByGPU(TexImageFunctionID,
- HTMLCanvasElement*,
- GLenum,
- GLuint,
- GLint,
- GLint,
- const IntRect&);
- void TexImageBitmapByGPU(ImageBitmap*,
- GLenum,
- GLuint,
- GLint,
- GLint,
- const IntRect&);
+ // Copy from the source directly to the texture via the gpu, without
+ // a read-back to system memory. Source can be a texture-backed
+ // Image, or another canvas's WebGLRenderingContext.
+ void TexImageViaGPU(TexImageFunctionID,
+ WebGLTexture*,
+ GLenum,
+ GLint,
+ GLint,
+ GLint,
+ GLint,
+ AcceleratedStaticBitmapImage*,
+ WebGLRenderingContextBase*,
+ const IntRect& source_sub_rectangle,
+ bool premultiply_alpha,
+ bool flip_y);
+ bool CanUseTexImageViaGPU(GLenum format, GLenum type);
+
+ bool ValidateShaderType(const char* function_name, GLenum shader_type);
const Platform::ContextType context_type_;
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 7755123e605..f424abb8847 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
@@ -628,6 +628,9 @@ typedef unrestricted float GLclampf;
GLenum format, GLenum type, HTMLCanvasElement canvas);
[CallWith=ExecutionContext, RaisesException] void texImage2D(
GLenum target, GLint level, GLint internalformat,
+ GLenum format, GLenum type, OffscreenCanvas offscreenCanvas);
+ [CallWith=ExecutionContext, RaisesException] void texImage2D(
+ GLenum target, GLint level, GLint internalformat,
GLenum format, GLenum type, HTMLVideoElement video);
[RaisesException] void texImage2D(
GLenum target, GLint level, GLint internalformat,
@@ -648,6 +651,9 @@ typedef unrestricted float GLclampf;
GLenum format, GLenum type, HTMLCanvasElement canvas);
[CallWith=ExecutionContext, RaisesException] void texSubImage2D(
GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLenum format, GLenum type, OffscreenCanvas offscreenCanvas);
+ [CallWith=ExecutionContext, RaisesException] void texSubImage2D(
+ GLenum target, GLint level, GLint xoffset, GLint yoffset,
GLenum format, GLenum type, HTMLVideoElement video);
[RaisesException] void texSubImage2D(
GLenum target, GLint level, GLint xoffset, GLint yoffset,
@@ -708,5 +714,5 @@ typedef unrestricted float GLclampf;
[RuntimeEnabled=OffscreenCanvasCommit] void commit();
// WebXR Device API support
- [OriginTrialEnabled=WebXR, SecureContext, CallWith=ScriptState] Promise setCompatibleXRDevice(XRDevice device);
+ [OriginTrialEnabled=WebXR, SecureContext, CallWith=ScriptState] Promise<void> setCompatibleXRDevice(XRDevice device);
};
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/DEPS b/chromium/third_party/blink/renderer/modules/webgpu/DEPS
new file mode 100644
index 00000000000..f3113a02881
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webgpu/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+ "+gpu/command_buffer/client/webgpu_interface.h",
+] \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/webgpu_adapter.cc b/chromium/third_party/blink/renderer/modules/webgpu/webgpu_adapter.cc
index 1e1f49e55d9..1d026aea4c1 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/webgpu_adapter.cc
+++ b/chromium/third_party/blink/renderer/modules/webgpu/webgpu_adapter.cc
@@ -17,8 +17,8 @@ const String& WebGPUAdapter::name() const {
return name_;
}
-WebGPUDevice* WebGPUAdapter::createDevice() {
- return WebGPUDevice::Create(this);
+WebGPUDevice* WebGPUAdapter::createDevice(ExecutionContext* execution_context) {
+ return WebGPUDevice::Create(execution_context, this);
}
WebGPUAdapter::WebGPUAdapter(const String& name) : name_(name) {}
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/webgpu_adapter.h b/chromium/third_party/blink/renderer/modules/webgpu/webgpu_adapter.h
index d1342c60662..1111631f3e7 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/webgpu_adapter.h
+++ b/chromium/third_party/blink/renderer/modules/webgpu/webgpu_adapter.h
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_WEBGPU_ADAPTER_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_WEBGPU_ADAPTER_H_
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -21,7 +22,7 @@ class WebGPUAdapter final : public ScriptWrappable {
const String& name() const;
- WebGPUDevice* createDevice();
+ WebGPUDevice* createDevice(ExecutionContext*);
private:
WebGPUAdapter(const String& name);
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/webgpu_adapter.idl b/chromium/third_party/blink/renderer/modules/webgpu/webgpu_adapter.idl
index 7623ef7c3c0..08a9d3ff788 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/webgpu_adapter.idl
+++ b/chromium/third_party/blink/renderer/modules/webgpu/webgpu_adapter.idl
@@ -7,5 +7,5 @@
] interface WebGPUAdapter {
readonly attribute DOMString name;
- WebGPUDevice createDevice();
+ [CallWith=ExecutionContext] WebGPUDevice createDevice();
};
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/webgpu_device.cc b/chromium/third_party/blink/renderer/modules/webgpu/webgpu_device.cc
index 2364f6ee641..f10c7e37fed 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/webgpu_device.cc
+++ b/chromium/third_party/blink/renderer/modules/webgpu/webgpu_device.cc
@@ -4,24 +4,60 @@
#include "third_party/blink/renderer/modules/webgpu/webgpu_device.h"
+#include "gpu/command_buffer/client/webgpu_interface.h"
+#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/modules/webgpu/webgpu_adapter.h"
namespace blink {
// static
-WebGPUDevice* WebGPUDevice::Create(WebGPUAdapter* adapter) {
- return new WebGPUDevice(adapter);
+WebGPUDevice* WebGPUDevice::Create(ExecutionContext* execution_context,
+ WebGPUAdapter* adapter) {
+ DCHECK(IsMainThread());
+
+ const auto& url = execution_context->Url();
+ Platform::GraphicsInfo info;
+
+ std::unique_ptr<WebGraphicsContext3DProvider> context_provider =
+ Platform::Current()->CreateWebGPUGraphicsContext3DProvider(url, &info);
+
+ // TODO(kainino): we will need a better way of accessing the WebGPU interface
+ // from multiple threads than BindToCurrentThread et al.
+ if (context_provider && context_provider->BindToCurrentThread()) {
+ info.error_message =
+ String("bindToCurrentThread failed: " + String(info.error_message));
+ }
+
+ if (!context_provider) {
+ // TODO(kainino): send the error message somewhere
+ // (see ExtractWebGLContextCreationError).
+ return nullptr;
+ }
+
+ return new WebGPUDevice(adapter, std::move(context_provider));
}
WebGPUAdapter* WebGPUDevice::adapter() const {
return adapter_;
}
+void WebGPUDevice::dummy() const {
+ Interface()->Dummy();
+}
+
void WebGPUDevice::Trace(blink::Visitor* visitor) {
visitor->Trace(adapter_);
ScriptWrappable::Trace(visitor);
}
-WebGPUDevice::WebGPUDevice(WebGPUAdapter* adapter) : adapter_(adapter) {}
+WebGPUDevice::WebGPUDevice(
+ WebGPUAdapter* adapter,
+ std::unique_ptr<WebGraphicsContext3DProvider> context_provider)
+ : adapter_(adapter), context_provider_(std::move(context_provider)) {}
+
+gpu::webgpu::WebGPUInterface* WebGPUDevice::Interface() const {
+ DCHECK(context_provider_);
+ return context_provider_->WebGPUInterface();
+}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/webgpu_device.h b/chromium/third_party/blink/renderer/modules/webgpu/webgpu_device.h
index 9fa781276c7..5b1bd9d9b4c 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/webgpu_device.h
+++ b/chromium/third_party/blink/renderer/modules/webgpu/webgpu_device.h
@@ -5,6 +5,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_WEBGPU_DEVICE_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_WEBGPU_DEVICE_H_
+#include "third_party/blink/public/platform/web_graphics_context_3d_provider.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
namespace blink {
@@ -16,16 +18,21 @@ class WebGPUDevice final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
- static WebGPUDevice* Create(WebGPUAdapter*);
+ static WebGPUDevice* Create(ExecutionContext*, WebGPUAdapter*);
WebGPUAdapter* adapter() const;
+ void dummy() const;
+
void Trace(blink::Visitor*) override;
private:
- WebGPUDevice(WebGPUAdapter*);
+ WebGPUDevice(WebGPUAdapter*, std::unique_ptr<WebGraphicsContext3DProvider>);
+
+ gpu::webgpu::WebGPUInterface* Interface() const;
Member<WebGPUAdapter> adapter_;
+ std::unique_ptr<WebGraphicsContext3DProvider> context_provider_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/webgpu_device.idl b/chromium/third_party/blink/renderer/modules/webgpu/webgpu_device.idl
index e7fb9034cc9..793ffad95f1 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/webgpu_device.idl
+++ b/chromium/third_party/blink/renderer/modules/webgpu/webgpu_device.idl
@@ -5,5 +5,7 @@
[
RuntimeEnabled=WebGPU
] interface WebGPUDevice {
- readonly attribute WebGPUAdapter adapter;
+ readonly attribute WebGPUAdapter adapter;
+
+ void dummy();
};
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 52a91208edb..884e88aa912 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/midi_access.cc
+++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_access.cc
@@ -146,7 +146,7 @@ void MIDIAccess::DidAddInputPort(const String& id,
MIDIInput* port = MIDIInput::Create(this, id, manufacturer, name, version,
ToDeviceState(state));
inputs_.push_back(port);
- DispatchEvent(MIDIConnectionEvent::Create(port));
+ DispatchEvent(*MIDIConnectionEvent::Create(port));
}
void MIDIAccess::DidAddOutputPort(const String& id,
@@ -159,7 +159,7 @@ void MIDIAccess::DidAddOutputPort(const String& id,
MIDIOutput* port = MIDIOutput::Create(this, port_index, id, manufacturer,
name, version, ToDeviceState(state));
outputs_.push_back(port);
- DispatchEvent(MIDIConnectionEvent::Create(port));
+ DispatchEvent(*MIDIConnectionEvent::Create(port));
}
void MIDIAccess::DidSetInputPortState(unsigned port_index, PortState state) {
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 045ed469ab0..0992d957d1d 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/midi_input.cc
+++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_input.cc
@@ -99,7 +99,7 @@ void MIDIInput::DidReceiveMIDIData(unsigned port_index,
if (data[0] == 0xf0 && !midiAccess()->sysexEnabled())
return;
DOMUint8Array* array = DOMUint8Array::Create(data, length);
- DispatchEvent(MIDIMessageEvent::Create(time_stamp, array));
+ DispatchEvent(*MIDIMessageEvent::Create(time_stamp, array));
UseCounter::Count(*ToDocument(GetExecutionContext()),
WebFeature::kMIDIMessageEvent);
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 68247d1eb86..5a2336d14be 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
@@ -32,6 +32,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBMIDI_MIDI_MESSAGE_EVENT_H_
#include "base/time/time.h"
+#include "third_party/blink/renderer/core/event_type_names.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
#include "third_party/blink/renderer/modules/event_modules.h"
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 48a502e4425..da3e04f5abc 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/midi_port.cc
+++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_port.cc
@@ -247,8 +247,8 @@ void MIDIPort::SetStates(PortState state, ConnectionState connection) {
return;
state_ = state;
connection_ = connection;
- DispatchEvent(MIDIConnectionEvent::Create(this));
- access_->DispatchEvent(MIDIConnectionEvent::Create(this));
+ DispatchEvent(*MIDIConnectionEvent::Create(this));
+ access_->DispatchEvent(*MIDIConnectionEvent::Create(this));
}
} // namespace blink
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 4185a3532d4..4d08522cff1 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
@@ -102,20 +102,15 @@ ScriptPromise NavigatorWebMIDI::requestMIDIAccess(ScriptState* script_state,
UseCounter::CountCrossOriginIframe(
document, WebFeature::kRequestMIDIAccessIframe_ObscuredByFootprinting);
- if (RuntimeEnabledFeatures::FeaturePolicyForPermissionsEnabled()) {
- if (!document.GetFrame()->IsFeatureEnabled(
- mojom::FeaturePolicyFeature::kMidiFeature)) {
- UseCounter::Count(document, WebFeature::kMidiDisabledByFeaturePolicy);
- document.AddConsoleMessage(
- ConsoleMessage::Create(kJSMessageSource, kWarningMessageLevel,
- kFeaturePolicyConsoleWarning));
- return ScriptPromise::RejectWithDOMException(
- script_state, DOMException::Create(DOMExceptionCode::kSecurityError,
- kFeaturePolicyErrorMessage));
- }
- } else {
- Deprecation::CountDeprecationFeaturePolicy(
- document, mojom::FeaturePolicyFeature::kMidiFeature);
+ if (!document.GetFrame()->IsFeatureEnabled(
+ mojom::FeaturePolicyFeature::kMidiFeature,
+ ReportOptions::kReportOnFailure)) {
+ UseCounter::Count(document, WebFeature::kMidiDisabledByFeaturePolicy);
+ document.AddConsoleMessage(ConsoleMessage::Create(
+ kJSMessageSource, kWarningMessageLevel, kFeaturePolicyConsoleWarning));
+ return ScriptPromise::RejectWithDOMException(
+ script_state, DOMException::Create(DOMExceptionCode::kSecurityError,
+ kFeaturePolicyErrorMessage));
}
return MIDIAccessInitializer::Start(script_state, options);
diff --git a/chromium/third_party/blink/renderer/modules/websockets/BUILD.gn b/chromium/third_party/blink/renderer/modules/websockets/BUILD.gn
index 02643db10a0..b7a03c266e4 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/websockets/BUILD.gn
@@ -15,7 +15,6 @@ blink_modules_sources("websockets") {
"web_pepper_socket_channel_client_proxy.h",
"web_pepper_socket_impl.cc",
"web_pepper_socket_impl.h",
- "websocket_channel.cc",
"websocket_channel.h",
"websocket_channel_client.h",
"websocket_channel_impl.cc",
@@ -24,7 +23,5 @@ blink_modules_sources("websockets") {
"websocket_handle_client.h",
"websocket_handle_impl.cc",
"websocket_handle_impl.h",
- "worker_websocket_channel.cc",
- "worker_websocket_channel.h",
]
}
diff --git a/chromium/third_party/blink/renderer/modules/websockets/OWNERS b/chromium/third_party/blink/renderer/modules/websockets/OWNERS
index d1ce751904e..d5f50691953 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/OWNERS
+++ b/chromium/third_party/blink/renderer/modules/websockets/OWNERS
@@ -1,4 +1,4 @@
-tyoshino@chromium.org
+ricea@chromium.org
yhirano@chromium.org
# TEAM: blink-network-dev@chromium.org
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 75126c8edfb..5e643649ae6 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/dom_websocket.cc
+++ b/chromium/third_party/blink/renderer/modules/websockets/dom_websocket.cc
@@ -30,6 +30,7 @@
#include "third_party/blink/renderer/modules/websockets/dom_websocket.h"
+#include "base/location.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"
@@ -51,6 +52,7 @@
#include "third_party/blink/renderer/modules/websockets/close_event.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/persistent.h"
#include "third_party/blink/renderer/platform/histogram.h"
#include "third_party/blink/renderer/platform/network/network_log.h"
#include "third_party/blink/renderer/platform/weborigin/known_ports.h"
@@ -64,16 +66,12 @@
static const size_t kMaxByteSizeForHistogram = 100 * 1000 * 1000;
static const int32_t kBucketCountForMessageSizeHistogram = 50;
+static const char kWebSocketSubprotocolSeparator[] = ", ";
namespace blink {
DOMWebSocket::EventQueue::EventQueue(EventTarget* target)
- : state_(kActive),
- target_(target),
- resume_timer_(
- target->GetExecutionContext()->GetTaskRunner(TaskType::kWebSocket),
- this,
- &EventQueue::ResumeTimerFired) {}
+ : state_(kActive), target_(target) {}
DOMWebSocket::EventQueue::~EventQueue() {
ContextDestroyed();
@@ -84,9 +82,10 @@ void DOMWebSocket::EventQueue::Dispatch(Event* event) {
case kActive:
DCHECK(events_.IsEmpty());
DCHECK(target_->GetExecutionContext());
- target_->DispatchEvent(event);
+ target_->DispatchEvent(*event);
break;
case kPaused:
+ case kUnpausePosted:
events_.push_back(event);
break;
case kStopped:
@@ -101,18 +100,21 @@ bool DOMWebSocket::EventQueue::IsEmpty() const {
}
void DOMWebSocket::EventQueue::Pause() {
- resume_timer_.Stop();
- if (state_ != kActive)
+ if (state_ == kStopped || state_ == kPaused)
return;
state_ = kPaused;
}
void DOMWebSocket::EventQueue::Unpause() {
- if (state_ != kPaused || resume_timer_.IsActive())
+ if (state_ != kPaused || state_ == kUnpausePosted)
return;
- resume_timer_.StartOneShot(TimeDelta(), FROM_HERE);
+ state_ = kUnpausePosted;
+ target_->GetExecutionContext()
+ ->GetTaskRunner(TaskType::kWebSocket)
+ ->PostTask(FROM_HERE,
+ WTF::Bind(&EventQueue::UnpauseTask, WrapWeakPersistent(this)));
}
void DOMWebSocket::EventQueue::ContextDestroyed() {
@@ -120,10 +122,13 @@ void DOMWebSocket::EventQueue::ContextDestroyed() {
return;
state_ = kStopped;
- resume_timer_.Stop();
events_.clear();
}
+bool DOMWebSocket::EventQueue::IsPaused() {
+ return state_ == kPaused || state_ == kUnpausePosted;
+}
+
void DOMWebSocket::EventQueue::DispatchQueuedEvents() {
if (state_ != kActive)
return;
@@ -131,22 +136,23 @@ void DOMWebSocket::EventQueue::DispatchQueuedEvents() {
HeapDeque<Member<Event>> events;
events.Swap(events_);
while (!events.IsEmpty()) {
- if (state_ == kStopped || state_ == kPaused)
+ if (state_ == kStopped || state_ == kPaused || state_ == kUnpausePosted)
break;
DCHECK_EQ(state_, kActive);
DCHECK(target_->GetExecutionContext());
- target_->DispatchEvent(events.TakeFirst());
+ target_->DispatchEvent(*events.TakeFirst());
// |this| can be stopped here.
}
- if (state_ == kPaused) {
+ if (state_ == kPaused || state_ == kUnpausePosted) {
while (!events_.IsEmpty())
events.push_back(events_.TakeFirst());
events.Swap(events_);
}
}
-void DOMWebSocket::EventQueue::ResumeTimerFired(TimerBase*) {
- DCHECK_EQ(state_, kPaused);
+void DOMWebSocket::EventQueue::UnpauseTask() {
+ if (state_ != kUnpausePosted)
+ return;
state_ = kActive;
DispatchQueuedEvents();
}
@@ -215,10 +221,6 @@ static void SetInvalidStateErrorForSendMethod(ExceptionState& exception_state) {
"Still in CONNECTING state.");
}
-const char* DOMWebSocket::SubprotocolSeperator() {
- return ", ";
-}
-
DOMWebSocket::DOMWebSocket(ExecutionContext* context)
: PausableObject(context),
state_(kConnecting),
@@ -229,10 +231,7 @@ DOMWebSocket::DOMWebSocket(ExecutionContext* context)
subprotocol_(""),
extensions_(""),
event_queue_(EventQueue::Create(this)),
- buffered_amount_consume_timer_(
- context->GetTaskRunner(TaskType::kWebSocket),
- this,
- &DOMWebSocket::ReflectBufferedAmountConsumption) {}
+ buffered_amount_update_task_pending_(false) {}
DOMWebSocket::~DOMWebSocket() {
DCHECK(!channel_);
@@ -294,7 +293,8 @@ void DOMWebSocket::Connect(const String& url,
if (GetExecutionContext()->GetSecurityContext().GetInsecureRequestPolicy() &
kUpgradeInsecureRequests &&
- url_.Protocol() == "ws") {
+ url_.Protocol() == "ws" &&
+ !SecurityOrigin::Create(url_)->IsPotentiallyTrustworthy()) {
UseCounter::Count(GetExecutionContext(),
WebFeature::kUpgradeInsecureRequestsUpgradedRequest);
url_.SetProtocol("wss");
@@ -375,7 +375,7 @@ void DOMWebSocket::Connect(const String& url,
String protocol_string;
if (!protocols.IsEmpty())
- protocol_string = JoinStrings(protocols, SubprotocolSeperator());
+ protocol_string = JoinStrings(protocols, kWebSocketSubprotocolSeparator);
origin_string_ = SecurityOrigin::Create(url_)->ToString();
channel_ = CreateChannel(GetExecutionContext(), this);
@@ -396,10 +396,25 @@ void DOMWebSocket::UpdateBufferedAmountAfterClose(uint64_t payload_size) {
LogError("WebSocket is already in CLOSING or CLOSED state.");
}
-void DOMWebSocket::ReflectBufferedAmountConsumption(TimerBase*) {
+void DOMWebSocket::PostBufferedAmountUpdateTask() {
+ if (buffered_amount_update_task_pending_)
+ return;
+ buffered_amount_update_task_pending_ = true;
+ GetExecutionContext()
+ ->GetTaskRunner(TaskType::kWebSocket)
+ ->PostTask(FROM_HERE, WTF::Bind(&DOMWebSocket::BufferedAmountUpdateTask,
+ WrapWeakPersistent(this)));
+}
+
+void DOMWebSocket::BufferedAmountUpdateTask() {
+ buffered_amount_update_task_pending_ = false;
+ ReflectBufferedAmountConsumption();
+}
+
+void DOMWebSocket::ReflectBufferedAmountConsumption() {
+ if (event_queue_->IsPaused())
+ return;
DCHECK_GE(buffered_amount_, consumed_buffered_amount_);
- // Cast to unsigned long long is required since clang doesn't accept
- // combination of %llu and uint64_t (known as unsigned long).
NETWORK_DVLOG(1) << "WebSocket " << this
<< " reflectBufferedAmountConsumption() " << buffered_amount_
<< " => " << (buffered_amount_ - consumed_buffered_amount_);
@@ -653,6 +668,11 @@ void DOMWebSocket::Pause() {
void DOMWebSocket::Unpause() {
event_queue_->Unpause();
+
+ // If |consumed_buffered_amount_| was updated while the object was paused then
+ // the changes to |buffered_amount_| will not yet have been applied. Post
+ // another task to update it.
+ PostBufferedAmountUpdateTask();
}
void DOMWebSocket::DidConnect(const String& subprotocol,
@@ -669,7 +689,7 @@ void DOMWebSocket::DidConnect(const String& subprotocol,
void DOMWebSocket::DidReceiveTextMessage(const String& msg) {
NETWORK_DVLOG(1) << "WebSocket " << this
<< " DidReceiveTextMessage() Text message " << msg;
-
+ ReflectBufferedAmountConsumption();
DCHECK_NE(state_, kConnecting);
if (state_ != kOpen)
return;
@@ -683,7 +703,7 @@ void DOMWebSocket::DidReceiveBinaryMessage(
std::unique_ptr<Vector<char>> binary_data) {
NETWORK_DVLOG(1) << "WebSocket " << this << " DidReceiveBinaryMessage() "
<< binary_data->size() << " byte binary message";
-
+ ReflectBufferedAmountConsumption();
DCHECK(!origin_string_.IsNull());
DCHECK_NE(state_, kConnecting);
@@ -719,6 +739,7 @@ void DOMWebSocket::DidReceiveBinaryMessage(
void DOMWebSocket::DidError() {
NETWORK_DVLOG(1) << "WebSocket " << this << " DidError()";
+ ReflectBufferedAmountConsumption();
state_ = kClosed;
event_queue_->Dispatch(Event::Create(EventTypeNames::error));
}
@@ -730,12 +751,12 @@ void DOMWebSocket::DidConsumeBufferedAmount(uint64_t consumed) {
if (state_ == kClosed)
return;
consumed_buffered_amount_ += consumed;
- if (!buffered_amount_consume_timer_.IsActive())
- buffered_amount_consume_timer_.StartOneShot(TimeDelta(), FROM_HERE);
+ PostBufferedAmountUpdateTask();
}
void DOMWebSocket::DidStartClosingHandshake() {
NETWORK_DVLOG(1) << "WebSocket " << this << " DidStartClosingHandshake()";
+ ReflectBufferedAmountConsumption();
state_ = kClosing;
}
@@ -744,6 +765,7 @@ void DOMWebSocket::DidClose(
unsigned short code,
const String& reason) {
NETWORK_DVLOG(1) << "WebSocket " << this << " DidClose()";
+ ReflectBufferedAmountConsumption();
if (!channel_)
return;
bool all_data_has_been_consumed =
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 8a290125ba1..4278acea08c 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/dom_websocket.h
+++ b/chromium/third_party/blink/renderer/modules/websockets/dom_websocket.h
@@ -43,6 +43,7 @@
#include "third_party/blink/renderer/modules/modules_export.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_channel_impl.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"
@@ -68,7 +69,6 @@ class MODULES_EXPORT DOMWebSocket : public EventTargetWithInlineData,
USING_GARBAGE_COLLECTED_MIXIN(DOMWebSocket);
public:
- static const char* SubprotocolSeperator();
// DOMWebSocket instances must be used with a wrapper since this class's
// lifetime management is designed assuming the V8 holds a ref on it while
// hasPendingActivity() returns true.
@@ -168,12 +168,15 @@ class MODULES_EXPORT DOMWebSocket : public EventTargetWithInlineData,
void Unpause();
void ContextDestroyed();
+ bool IsPaused();
+
void Trace(blink::Visitor*);
private:
enum State {
kActive,
kPaused,
+ kUnpausePosted,
kStopped,
};
@@ -182,12 +185,11 @@ class MODULES_EXPORT DOMWebSocket : public EventTargetWithInlineData,
// Dispatches queued events if this queue is active.
// Does nothing otherwise.
void DispatchQueuedEvents();
- void ResumeTimerFired(TimerBase*);
+ void UnpauseTask();
State state_;
Member<EventTarget> target_;
HeapDeque<Member<Event>> events_;
- TaskRunnerTimer<EventQueue> resume_timer_;
};
enum WebSocketSendType {
@@ -208,10 +210,10 @@ class MODULES_EXPORT DOMWebSocket : public EventTargetWithInlineData,
enum BinaryType { kBinaryTypeBlob, kBinaryTypeArrayBuffer };
// This function is virtual for unittests.
- // FIXME: Move WebSocketChannel::create here.
virtual WebSocketChannel* CreateChannel(ExecutionContext* context,
WebSocketChannelClient* client) {
- return WebSocketChannel::Create(context, client);
+ return WebSocketChannelImpl::Create(context, client,
+ SourceLocation::Capture(context));
}
// Adds a console message with JSMessageSource and ErrorMessageLevel.
@@ -225,7 +227,18 @@ class MODULES_EXPORT DOMWebSocket : public EventTargetWithInlineData,
// Updates |buffered_amount_after_close_| given the amount of data passed to
// send() method after the state changed to CLOSING or CLOSED.
void UpdateBufferedAmountAfterClose(uint64_t);
- void ReflectBufferedAmountConsumption(TimerBase*);
+
+ // Causes |buffered_amount_| to be updated asynchronously after returning to
+ // the event loop. Uses |buffered_amount_update_task_pending_| to avoid
+ // posting multiple tasks simultaneously.
+ void PostBufferedAmountUpdateTask();
+
+ // Updates |buffered_amount_| and resets
+ // |buffered_amount_update_task_pending_|.
+ void BufferedAmountUpdateTask();
+
+ // Updates |buffered_amount_| provided the object is not currently paused.
+ void ReflectBufferedAmountConsumption();
void ReleaseChannel();
void RecordSendTypeHistogram(WebSocketSendType);
@@ -251,7 +264,8 @@ class MODULES_EXPORT DOMWebSocket : public EventTargetWithInlineData,
String extensions_;
Member<EventQueue> event_queue_;
- TaskRunnerTimer<DOMWebSocket> buffered_amount_consume_timer_;
+
+ bool buffered_amount_update_task_pending_;
};
} // namespace blink
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 a1cc7d17cf7..f46924e609f 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
@@ -19,6 +19,7 @@
#include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.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/testing/unit_test_helpers.h"
#include "third_party/blink/renderer/platform/wtf/text/cstring.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -228,6 +229,25 @@ TEST(DOMWebSocketTest, insecureRequestsUpgrade) {
EXPECT_EQ(KURL("wss://example.com/endpoint"), websocket_scope.Socket().url());
}
+TEST(DOMWebSocketTest, insecureRequestsUpgradePotentiallyTrustworthy) {
+ V8TestingScope scope;
+ DOMWebSocketTestScope websocket_scope(scope.GetExecutionContext());
+ {
+ InSequence s;
+ EXPECT_CALL(websocket_scope.Channel(),
+ Connect(KURL("ws://127.0.0.1/endpoint"), String()))
+ .WillOnce(Return(true));
+ }
+
+ scope.GetDocument().SetInsecureRequestPolicy(kUpgradeInsecureRequests);
+ websocket_scope.Socket().Connect("ws://127.0.0.1/endpoint", Vector<String>(),
+ scope.GetExceptionState());
+
+ EXPECT_FALSE(scope.GetExceptionState().HadException());
+ EXPECT_EQ(DOMWebSocket::kConnecting, websocket_scope.Socket().readyState());
+ EXPECT_EQ(KURL("ws://127.0.0.1/endpoint"), websocket_scope.Socket().url());
+}
+
TEST(DOMWebSocketTest, insecureRequestsDoNotUpgrade) {
V8TestingScope scope;
DOMWebSocketTestScope websocket_scope(scope.GetExecutionContext());
@@ -809,7 +829,68 @@ TEST(DOMWebSocketTest, sendArrayBufferSuccess) {
// FIXME: We should have Blob tests here.
// We can't create a Blob because the blob registration cannot be mocked yet.
-// FIXME: We should add tests for bufferedAmount.
+TEST(DOMWebSocketTest, bufferedAmountUpdated) {
+ V8TestingScope scope;
+ DOMWebSocketTestScope websocket_scope(scope.GetExecutionContext());
+ {
+ InSequence s;
+ EXPECT_CALL(websocket_scope.Channel(),
+ Connect(KURL("ws://example.com/"), String()))
+ .WillOnce(Return(true));
+ EXPECT_CALL(websocket_scope.Channel(), Send(CString("hello")));
+ EXPECT_CALL(websocket_scope.Channel(), Send(CString("world")));
+ }
+ websocket_scope.Socket().Connect("ws://example.com/", Vector<String>(),
+ scope.GetExceptionState());
+
+ EXPECT_FALSE(scope.GetExceptionState().HadException());
+
+ websocket_scope.Socket().DidConnect("", "");
+ websocket_scope.Socket().send("hello", scope.GetExceptionState());
+ EXPECT_EQ(websocket_scope.Socket().bufferedAmount(), 5u);
+ websocket_scope.Socket().send("world", scope.GetExceptionState());
+ EXPECT_EQ(websocket_scope.Socket().bufferedAmount(), 10u);
+ websocket_scope.Socket().DidConsumeBufferedAmount(5);
+ websocket_scope.Socket().DidConsumeBufferedAmount(5);
+ EXPECT_EQ(websocket_scope.Socket().bufferedAmount(), 10u);
+ blink::test::RunPendingTasks();
+ EXPECT_EQ(websocket_scope.Socket().bufferedAmount(), 0u);
+
+ EXPECT_FALSE(scope.GetExceptionState().HadException());
+}
+
+TEST(DOMWebSocketTest, bufferedAmountUpdatedBeforeOnMessage) {
+ V8TestingScope scope;
+ DOMWebSocketTestScope websocket_scope(scope.GetExecutionContext());
+ {
+ InSequence s;
+ EXPECT_CALL(websocket_scope.Channel(),
+ Connect(KURL("ws://example.com/"), String()))
+ .WillOnce(Return(true));
+ EXPECT_CALL(websocket_scope.Channel(), Send(CString("hello")));
+ }
+ websocket_scope.Socket().Connect("ws://example.com/", Vector<String>(),
+ scope.GetExceptionState());
+
+ EXPECT_FALSE(scope.GetExceptionState().HadException());
+
+ websocket_scope.Socket().DidConnect("", "");
+ // send() is called from onopen
+ websocket_scope.Socket().send("hello", scope.GetExceptionState());
+ // (return to event loop)
+ websocket_scope.Socket().DidConsumeBufferedAmount(5);
+ EXPECT_EQ(websocket_scope.Socket().bufferedAmount(), 5ul);
+ // New message was already queued, is processed before task posted from
+ // DidConsumeBufferedAmount().
+ websocket_scope.Socket().DidReceiveTextMessage("hello");
+ // bufferedAmount is observed inside onmessage event handler.
+ EXPECT_EQ(websocket_scope.Socket().bufferedAmount(), 0ul);
+
+ blink::test::RunPendingTasks();
+ EXPECT_EQ(websocket_scope.Socket().bufferedAmount(), 0ul);
+
+ EXPECT_FALSE(scope.GetExceptionState().HadException());
+}
// FIXME: We should add tests for data receiving.
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 ed6b88954ed..52655c4b097 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
@@ -32,10 +32,12 @@
#include <stddef.h>
#include <memory>
+#include "third_party/blink/public/platform/web_feature.mojom-shared.h"
#include "third_party/blink/public/platform/web_url.h"
#include "third_party/blink/public/web/web_array_buffer.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/frame/deprecation.h"
#include "third_party/blink/renderer/core/inspector/console_types.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
#include "third_party/blink/renderer/modules/websockets/web_pepper_socket_channel_client_proxy.h"
@@ -64,6 +66,7 @@ WebPepperSocketImpl::WebPepperSocketImpl(const WebDocument& document,
Document* core_document = document;
private_ = WebSocketChannelImpl::Create(core_document, channel_proxy_.Get(),
SourceLocation::Capture());
+ Deprecation::CountDeprecation(*core_document, WebFeature::kPPAPIWebSocket);
DCHECK(private_);
}
diff --git a/chromium/third_party/blink/renderer/modules/websockets/websocket_channel.cc b/chromium/third_party/blink/renderer/modules/websockets/websocket_channel.cc
deleted file mode 100644
index c05a94c048d..00000000000
--- a/chromium/third_party/blink/renderer/modules/websockets/websocket_channel.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2009, 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "third_party/blink/renderer/modules/websockets/websocket_channel.h"
-
-#include <memory>
-#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/execution_context/execution_context.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/modules/websockets/websocket_channel_client.h"
-#include "third_party/blink/renderer/modules/websockets/websocket_channel_impl.h"
-#include "third_party/blink/renderer/modules/websockets/worker_websocket_channel.h"
-#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
-
-namespace blink {
-
-WebSocketChannel* WebSocketChannel::Create(ExecutionContext* context,
- WebSocketChannelClient* client) {
- DCHECK(context);
- DCHECK(client);
-
- std::unique_ptr<SourceLocation> location = SourceLocation::Capture(context);
-
- // When the off-main-thread WebSocket flag is enabled, web workers use
- // WebSocketChannelImpl as opposed to WorkerWebSocketChannel. See
- // https://crbug.com/825740
- if (context->IsDocument() ||
- RuntimeEnabledFeatures::OffMainThreadWebSocketEnabled()) {
- return WebSocketChannelImpl::Create(context, client, std::move(location));
- }
-
- WorkerGlobalScope* worker_global_scope = ToWorkerGlobalScope(context);
- return WorkerWebSocketChannel::Create(*worker_global_scope, client,
- std::move(location));
-}
-
-} // namespace blink
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 70672cc997f..aa300aa478a 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/websocket_channel.h
+++ b/chromium/third_party/blink/renderer/modules/websockets/websocket_channel.h
@@ -44,13 +44,11 @@ namespace blink {
class BlobDataHandle;
class DOMArrayBuffer;
class KURL;
-class WebSocketChannelClient;
class MODULES_EXPORT WebSocketChannel
: public GarbageCollectedFinalized<WebSocketChannel> {
public:
WebSocketChannel() = default;
- static WebSocketChannel* Create(ExecutionContext*, WebSocketChannelClient*);
enum CloseEventCode {
kCloseEventCodeNotSpecified = -1,
@@ -77,15 +75,13 @@ class MODULES_EXPORT WebSocketChannel
unsigned byte_offset,
unsigned byte_length) = 0;
virtual void Send(scoped_refptr<BlobDataHandle>) = 0;
-
- // For WorkerWebSocketChannel.
virtual void SendTextAsCharVector(std::unique_ptr<Vector<char>>) = 0;
virtual void SendBinaryAsCharVector(std::unique_ptr<Vector<char>>) = 0;
- // Do not call |send| after calling this method.
+ // Do not call |Send| after calling this method.
virtual void Close(int code, const String& reason) = 0;
- // Log the reason text and close the connection. Will call didClose().
+ // Log the reason text and close the connection. Will call DidClose().
// The MessageLevel parameter will be used for the level of the message
// shown at the devtools console.
// SourceLocation parameter may be shown with the reason text
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 25e05c0ded8..c7755b7977e 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
@@ -48,14 +48,15 @@
#include "third_party/blink/renderer/core/loader/base_fetch_context.h"
#include "third_party/blink/renderer/core/loader/mixed_content_checker.h"
#include "third_party/blink/renderer/core/loader/subresource_filter.h"
-#include "third_party/blink/renderer/core/loader/threadable_loading_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/core/probe/core_probes.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
+#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/modules/websockets/websocket_handle_impl.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"
#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
@@ -158,38 +159,42 @@ WebSocketChannelImpl* WebSocketChannelImpl::CreateForTesting(
std::unique_ptr<SourceLocation> location,
WebSocketHandle* handle,
std::unique_ptr<WebSocketHandshakeThrottle> handshake_throttle) {
- return new WebSocketChannelImpl(
- ThreadableLoadingContext::Create(*document), client, std::move(location),
- base::WrapUnique(handle), std::move(handshake_throttle));
+ auto* channel = new WebSocketChannelImpl(
+ document, client, std::move(location), base::WrapUnique(handle));
+ channel->handshake_throttle_ = std::move(handshake_throttle);
+ return channel;
}
// static
WebSocketChannelImpl* WebSocketChannelImpl::Create(
- ThreadableLoadingContext* loading_context,
+ ExecutionContext* execution_context,
WebSocketChannelClient* client,
std::unique_ptr<SourceLocation> location) {
- return new WebSocketChannelImpl(
- loading_context, client, std::move(location),
- std::make_unique<WebSocketHandleImpl>(),
- loading_context->GetFetchContext()->CreateWebSocketHandshakeThrottle());
+ auto* channel =
+ new WebSocketChannelImpl(execution_context, client, std::move(location),
+ std::make_unique<WebSocketHandleImpl>());
+ channel->handshake_throttle_ =
+ channel->GetBaseFetchContext()->CreateWebSocketHandshakeThrottle();
+ return channel;
}
WebSocketChannelImpl::WebSocketChannelImpl(
- ThreadableLoadingContext* loading_context,
+ ExecutionContext* execution_context,
WebSocketChannelClient* client,
std::unique_ptr<SourceLocation> location,
- std::unique_ptr<WebSocketHandle> handle,
- std::unique_ptr<WebSocketHandshakeThrottle> handshake_throttle)
+ std::unique_ptr<WebSocketHandle> handle)
: handle_(std::move(handle)),
client_(client),
identifier_(CreateUniqueIdentifier()),
- loading_context_(loading_context),
+ execution_context_(execution_context),
sending_quota_(0),
received_data_size_for_flow_control_(0),
sent_size_of_top_message_(0),
location_at_construction_(std::move(location)),
- handshake_throttle_(std::move(handshake_throttle)),
- throttle_passed_(false) {}
+ throttle_passed_(false) {
+ if (execution_context_->IsWorkerGlobalScope())
+ ToWorkerGlobalScope(execution_context_)->EnsureFetcher();
+}
WebSocketChannelImpl::~WebSocketChannelImpl() {
DCHECK(!blob_loader_);
@@ -203,20 +208,18 @@ bool WebSocketChannelImpl::Connect(
if (!handle_)
return false;
- if (loading_context_->GetFetchContext()
- ->ShouldBlockWebSocketByMixedContentCheck(url)) {
+ if (GetBaseFetchContext()->ShouldBlockWebSocketByMixedContentCheck(url))
return false;
- }
- if (auto* scheduler = GetExecutionContext()->GetScheduler())
+ if (auto* scheduler = execution_context_->GetScheduler())
connection_handle_for_scheduler_ = scheduler->OnActiveConnectionCreated();
if (MixedContentChecker::IsMixedContent(
- GetExecutionContext()->GetSecurityOrigin(), url)) {
+ execution_context_->GetSecurityOrigin(), url)) {
String message =
"Connecting to a non-secure WebSocket server from a secure origin is "
"deprecated.";
- GetExecutionContext()->AddConsoleMessage(ConsoleMessage::Create(
+ execution_context_->AddConsoleMessage(ConsoleMessage::Create(
kJSMessageSource, kWarningMessageLevel, message));
}
@@ -234,20 +237,18 @@ bool WebSocketChannelImpl::Connect(
// failure blocks the worker thread which should be avoided. Note that
// returning "true" just indicates that this was not a mixed content error.
if (ShouldDisallowConnection(url)) {
- GetExecutionContext()
- ->GetTaskRunner(TaskType::kNetworking)
+ execution_context_->GetTaskRunner(TaskType::kNetworking)
->PostTask(FROM_HERE,
WTF::Bind(&WebSocketChannelImpl::TearDownFailedConnection,
WrapPersistent(this)));
return true;
}
- handle_->Connect(std::move(socket_ptr), url, protocols,
- loading_context_->GetFetchContext()->GetSiteForCookies(),
- loading_context_->GetExecutionContext()->UserAgent(), this,
- loading_context_->GetExecutionContext()
- ->GetTaskRunner(TaskType::kNetworking)
- .get());
+ handle_->Connect(
+ std::move(socket_ptr), url, protocols,
+ GetBaseFetchContext()->GetSiteForCookies(),
+ execution_context_->UserAgent(), this,
+ execution_context_->GetTaskRunner(TaskType::kNetworking).get());
if (handshake_throttle_) {
handshake_throttle_->ThrottleHandshake(url, this);
@@ -259,8 +260,8 @@ bool WebSocketChannelImpl::Connect(
TRACE_EVENT_INSTANT1("devtools.timeline", "WebSocketCreate",
TRACE_EVENT_SCOPE_THREAD, "data",
InspectorWebSocketCreateEvent::Data(
- GetExecutionContext(), identifier_, url, protocol));
- probe::didCreateWebSocket(GetExecutionContext(), identifier_, url, protocol);
+ execution_context_, identifier_, url, protocol));
+ probe::didCreateWebSocket(execution_context_, identifier_, url, protocol);
return true;
}
@@ -268,7 +269,7 @@ bool WebSocketChannelImpl::Connect(const KURL& url, const String& protocol) {
network::mojom::blink::WebSocketPtr socket_ptr;
auto socket_request = mojo::MakeRequest(&socket_ptr);
service_manager::InterfaceProvider* interface_provider =
- GetExecutionContext()->GetInterfaceProvider();
+ execution_context_->GetInterfaceProvider();
if (interface_provider)
interface_provider->GetInterface(std::move(socket_request));
return Connect(url, protocol, std::move(socket_ptr));
@@ -278,7 +279,7 @@ void WebSocketChannelImpl::Send(const CString& message) {
NETWORK_DVLOG(1) << this << " Send(" << message << ") (CString argument)";
// FIXME: Change the inspector API to show the entire message instead
// of individual frames.
- probe::didSendWebSocketFrame(GetExecutionContext(), identifier_,
+ probe::didSendWebSocketFrame(execution_context_, identifier_,
WebSocketOpCode::kOpCodeText, true,
message.data(), message.length());
messages_.push_back(new Message(message));
@@ -296,7 +297,7 @@ void WebSocketChannelImpl::Send(
// FIXME: We can't access the data here.
// Since Binary data are not displayed in Inspector, this does not
// affect actual behavior.
- probe::didSendWebSocketFrame(GetExecutionContext(), identifier_,
+ probe::didSendWebSocketFrame(execution_context_, identifier_,
WebSocketOpCode::kOpCodeBinary, true, "", 0);
messages_.push_back(new Message(std::move(blob_data_handle)));
ProcessSendQueue();
@@ -311,7 +312,7 @@ void WebSocketChannelImpl::Send(const DOMArrayBuffer& buffer,
// FIXME: Change the inspector API to show the entire message instead
// of individual frames.
probe::didSendWebSocketFrame(
- GetExecutionContext(), identifier_, WebSocketOpCode::kOpCodeBinary, true,
+ execution_context_, identifier_, WebSocketOpCode::kOpCodeBinary, true,
static_cast<const char*>(buffer.Data()) + byte_offset, byte_length);
// buffer.slice copies its contents.
// FIXME: Reduce copy by sending the data immediately when we don't need to
@@ -328,7 +329,7 @@ void WebSocketChannelImpl::SendTextAsCharVector(
<< ")";
// FIXME: Change the inspector API to show the entire message instead
// of individual frames.
- probe::didSendWebSocketFrame(GetExecutionContext(), identifier_,
+ probe::didSendWebSocketFrame(execution_context_, identifier_,
WebSocketOpCode::kOpCodeText, true, data->data(),
data->size());
messages_.push_back(
@@ -343,7 +344,7 @@ void WebSocketChannelImpl::SendBinaryAsCharVector(
<< ")";
// FIXME: Change the inspector API to show the entire message instead
// of individual frames.
- probe::didSendWebSocketFrame(GetExecutionContext(), identifier_,
+ probe::didSendWebSocketFrame(execution_context_, identifier_,
WebSocketOpCode::kOpCodeBinary, true,
data->data(), data->size());
messages_.push_back(
@@ -364,8 +365,7 @@ void WebSocketChannelImpl::Fail(const String& reason,
MessageLevel level,
std::unique_ptr<SourceLocation> location) {
NETWORK_DVLOG(1) << this << " Fail(" << reason << ")";
- probe::didReceiveWebSocketFrameError(GetExecutionContext(), identifier_,
- reason);
+ probe::didReceiveWebSocketFrameError(execution_context_, identifier_, reason);
const String message =
"WebSocket connection to '" + url_.ElidedString() + "' failed: " + reason;
@@ -380,7 +380,7 @@ void WebSocketChannelImpl::Fail(const String& reason,
location = location_at_construction_->Clone();
}
- GetExecutionContext()->AddConsoleMessage(ConsoleMessage::Create(
+ execution_context_->AddConsoleMessage(ConsoleMessage::Create(
kJSMessageSource, 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.
@@ -392,9 +392,8 @@ void WebSocketChannelImpl::Disconnect() {
if (identifier_) {
TRACE_EVENT_INSTANT1(
"devtools.timeline", "WebSocketDestroy", TRACE_EVENT_SCOPE_THREAD,
- "data",
- InspectorWebSocketEvent::Data(GetExecutionContext(), identifier_));
- probe::didCloseWebSocket(GetExecutionContext(), identifier_);
+ "data", InspectorWebSocketEvent::Data(execution_context_, identifier_));
+ probe::didCloseWebSocket(execution_context_, identifier_);
}
connection_handle_for_scheduler_.reset();
AbortAsyncOperations();
@@ -547,10 +546,6 @@ void WebSocketChannelImpl::HandleDidClose(bool was_clean,
client->DidClose(status, code, reason);
}
-ExecutionContext* WebSocketChannelImpl::GetExecutionContext() const {
- return loading_context_->GetExecutionContext();
-}
-
void WebSocketChannelImpl::DidConnect(WebSocketHandle* handle,
const String& selected_protocol,
const String& extensions) {
@@ -586,8 +581,8 @@ void WebSocketChannelImpl::DidStartOpeningHandshake(
TRACE_EVENT_INSTANT1(
"devtools.timeline", "WebSocketSendHandshakeRequest",
TRACE_EVENT_SCOPE_THREAD, "data",
- InspectorWebSocketEvent::Data(GetExecutionContext(), identifier_));
- probe::willSendWebSocketHandshakeRequest(GetExecutionContext(), identifier_,
+ InspectorWebSocketEvent::Data(execution_context_, identifier_));
+ probe::willSendWebSocketHandshakeRequest(execution_context_, identifier_,
request.get());
handshake_request_ = std::move(request);
}
@@ -603,10 +598,10 @@ void WebSocketChannelImpl::DidFinishOpeningHandshake(
TRACE_EVENT_INSTANT1(
"devtools.timeline", "WebSocketReceiveHandshakeResponse",
TRACE_EVENT_SCOPE_THREAD, "data",
- InspectorWebSocketEvent::Data(GetExecutionContext(), identifier_));
- probe::didReceiveWebSocketHandshakeResponse(
- GetExecutionContext(), identifier_, handshake_request_.get(),
- response.get());
+ InspectorWebSocketEvent::Data(execution_context_, identifier_));
+ probe::didReceiveWebSocketHandshakeResponse(execution_context_, identifier_,
+ handshake_request_.get(),
+ response.get());
handshake_request_ = nullptr;
}
@@ -666,7 +661,7 @@ void WebSocketChannelImpl::DidReceiveData(WebSocketHandle* handle,
auto opcode = receiving_message_type_is_text_
? WebSocketOpCode::kOpCodeText
: WebSocketOpCode::kOpCodeBinary;
- probe::didReceiveWebSocketFrame(GetExecutionContext(), identifier_, opcode,
+ probe::didReceiveWebSocketFrame(execution_context_, identifier_, opcode,
false, receiving_message_data_.data(),
receiving_message_data_.size());
if (receiving_message_type_is_text_) {
@@ -705,9 +700,8 @@ void WebSocketChannelImpl::DidClose(WebSocketHandle* handle,
if (identifier_) {
TRACE_EVENT_INSTANT1(
"devtools.timeline", "WebSocketDestroy", TRACE_EVENT_SCOPE_THREAD,
- "data",
- InspectorWebSocketEvent::Data(GetExecutionContext(), identifier_));
- probe::didCloseWebSocket(GetExecutionContext(), identifier_);
+ "data", InspectorWebSocketEvent::Data(execution_context_, identifier_));
+ probe::didCloseWebSocket(execution_context_, identifier_);
identifier_ = 0;
}
@@ -795,18 +789,23 @@ void WebSocketChannelImpl::TearDownFailedConnection() {
bool WebSocketChannelImpl::ShouldDisallowConnection(const KURL& url) {
DCHECK(handle_);
- BaseFetchContext* fetch_context = loading_context_->GetFetchContext();
- SubresourceFilter* subresource_filter = fetch_context->GetSubresourceFilter();
+ SubresourceFilter* subresource_filter =
+ GetBaseFetchContext()->GetSubresourceFilter();
if (!subresource_filter)
return false;
return !subresource_filter->AllowWebSocketConnection(url);
}
+BaseFetchContext* WebSocketChannelImpl::GetBaseFetchContext() const {
+ ResourceFetcher* resource_fetcher = execution_context_->Fetcher();
+ return static_cast<BaseFetchContext*>(&resource_fetcher->Context());
+}
+
void WebSocketChannelImpl::Trace(blink::Visitor* visitor) {
visitor->Trace(blob_loader_);
visitor->Trace(messages_);
visitor->Trace(client_);
- visitor->Trace(loading_context_);
+ visitor->Trace(execution_context_);
WebSocketChannel::Trace(visitor);
}
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 d7e4af0a8de..dfb664c18db 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
@@ -40,7 +40,6 @@
#include "third_party/blink/renderer/bindings/core/v8/source_location.h"
#include "third_party/blink/renderer/core/fileapi/blob.h"
#include "third_party/blink/renderer/core/fileapi/file_error.h"
-#include "third_party/blink/renderer/core/loader/threadable_loading_context.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/websockets/websocket_channel.h"
#include "third_party/blink/renderer/modules/websockets/websocket_handle.h"
@@ -55,6 +54,8 @@
namespace blink {
+class BaseFetchContext;
+class WebSocketChannelClient;
class WebSocketHandshakeThrottle;
// This is an implementation of WebSocketChannel. This is created on the main
@@ -69,17 +70,9 @@ class MODULES_EXPORT WebSocketChannelImpl final
// explicitly by passing the last parameter.
// In the usual case, they are set automatically and you don't have to
// pass it.
- static WebSocketChannelImpl* Create(
- ExecutionContext* context,
- WebSocketChannelClient* client,
- std::unique_ptr<SourceLocation> location) {
- DCHECK(context);
- return Create(ThreadableLoadingContext::Create(*context), client,
- std::move(location));
- }
- static WebSocketChannelImpl* Create(ThreadableLoadingContext*,
- WebSocketChannelClient*,
- std::unique_ptr<SourceLocation>);
+ static WebSocketChannelImpl* Create(ExecutionContext* context,
+ WebSocketChannelClient* client,
+ std::unique_ptr<SourceLocation> location);
static WebSocketChannelImpl* CreateForTesting(
Document*,
WebSocketChannelClient*,
@@ -133,11 +126,10 @@ class MODULES_EXPORT WebSocketChannelImpl final
Vector<char> data;
};
- WebSocketChannelImpl(ThreadableLoadingContext*,
+ WebSocketChannelImpl(ExecutionContext*,
WebSocketChannelClient*,
std::unique_ptr<SourceLocation>,
- std::unique_ptr<WebSocketHandle>,
- std::unique_ptr<WebSocketHandshakeThrottle>);
+ std::unique_ptr<WebSocketHandle>);
void SendInternal(WebSocketHandle::MessageType,
const char* data,
@@ -154,8 +146,6 @@ class MODULES_EXPORT WebSocketChannelImpl final
unsigned short code,
const String& reason);
- ExecutionContext* GetExecutionContext() const;
-
// WebSocketHandleClient functions.
void DidConnect(WebSocketHandle*,
const String& selected_protocol,
@@ -191,6 +181,8 @@ class MODULES_EXPORT WebSocketChannelImpl final
void TearDownFailedConnection();
bool ShouldDisallowConnection(const KURL&);
+ BaseFetchContext* GetBaseFetchContext() const;
+
// |handle_| is a handle of the connection.
// |handle_| == nullptr means this channel is closed.
std::unique_ptr<WebSocketHandle> handle_;
@@ -203,7 +195,7 @@ class MODULES_EXPORT WebSocketChannelImpl final
Member<BlobLoader> blob_loader_;
HeapDeque<Member<Message>> messages_;
Vector<char> receiving_message_data_;
- Member<ThreadableLoadingContext> loading_context_;
+ Member<ExecutionContext> execution_context_;
bool receiving_message_type_is_text_;
uint64_t sending_quota_;
diff --git a/chromium/third_party/blink/renderer/modules/websockets/worker_websocket_channel.cc b/chromium/third_party/blink/renderer/modules/websockets/worker_websocket_channel.cc
deleted file mode 100644
index c84700b4d7f..00000000000
--- a/chromium/third_party/blink/renderer/modules/websockets/worker_websocket_channel.cc
+++ /dev/null
@@ -1,524 +0,0 @@
-/*
- * Copyright (C) 2011, 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "third_party/blink/renderer/modules/websockets/worker_websocket_channel.h"
-
-#include <memory>
-#include "services/service_manager/public/cpp/interface_provider.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/fileapi/blob.h"
-#include "third_party/blink/renderer/core/loader/threadable_loading_context.h"
-#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.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/core/workers/worker_thread_lifecycle_context.h"
-#include "third_party/blink/renderer/platform/cross_thread_functional.h"
-#include "third_party/blink/renderer/platform/heap/safe_point.h"
-#include "third_party/blink/renderer/platform/waitable_event.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
-#include "third_party/blink/renderer/platform/wtf/assertions.h"
-#include "third_party/blink/renderer/platform/wtf/functional.h"
-#include "third_party/blink/renderer/platform/wtf/text/cstring.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-
-namespace blink {
-
-typedef WorkerWebSocketChannel::Bridge Bridge;
-typedef WorkerWebSocketChannel::MainChannelClient MainChannelClient;
-
-// Created and destroyed on the worker thread. All setters of this class are
-// called on the main thread, while all getters are called on the worker
-// thread. signalWorkerThread() must be called before any getters are called.
-class WebSocketChannelSyncHelper {
- public:
- WebSocketChannelSyncHelper() = default;
- ~WebSocketChannelSyncHelper() = default;
-
- // All setters are called on the main thread.
- void SetConnectRequestResult(bool connect_request_result) {
- DCHECK(IsMainThread());
- connect_request_result_ = connect_request_result;
- }
-
- // All getters are called on the worker thread.
- bool ConnectRequestResult() const {
- DCHECK(!IsMainThread());
- return connect_request_result_;
- }
-
- // This should be called after all setters are called and before any
- // getters are called.
- void SignalWorkerThread() {
- DCHECK(IsMainThread());
- event_.Signal();
- }
-
- void Wait() {
- DCHECK(!IsMainThread());
- event_.Wait();
- }
-
- private:
- WaitableEvent event_;
- bool connect_request_result_ = false;
-};
-
-WorkerWebSocketChannel::WorkerWebSocketChannel(
- WorkerGlobalScope& worker_global_scope,
- WebSocketChannelClient* client,
- std::unique_ptr<SourceLocation> location)
- : bridge_(new Bridge(client, worker_global_scope)),
- location_at_connection_(std::move(location)) {}
-
-WorkerWebSocketChannel::~WorkerWebSocketChannel() {
- DCHECK(!bridge_);
-}
-
-bool WorkerWebSocketChannel::Connect(const KURL& url, const String& protocol) {
- DCHECK(bridge_);
- return bridge_->Connect(location_at_connection_->Clone(), url, protocol);
-}
-
-void WorkerWebSocketChannel::Send(const CString& message) {
- DCHECK(bridge_);
- bridge_->Send(message);
-}
-
-void WorkerWebSocketChannel::Send(const DOMArrayBuffer& binary_data,
- unsigned byte_offset,
- unsigned byte_length) {
- DCHECK(bridge_);
- bridge_->Send(binary_data, byte_offset, byte_length);
-}
-
-void WorkerWebSocketChannel::Send(scoped_refptr<BlobDataHandle> blob_data) {
- DCHECK(bridge_);
- bridge_->Send(std::move(blob_data));
-}
-
-void WorkerWebSocketChannel::Close(int code, const String& reason) {
- DCHECK(bridge_);
- bridge_->Close(code, reason);
-}
-
-void WorkerWebSocketChannel::Fail(const String& reason,
- MessageLevel level,
- std::unique_ptr<SourceLocation> location) {
- DCHECK(bridge_);
-
- std::unique_ptr<SourceLocation> captured_location = SourceLocation::Capture();
- if (!captured_location->IsUnknown()) {
- // If we are in JavaScript context, use the current location instead
- // of passed one - it's more precise.
- bridge_->Fail(reason, level, std::move(captured_location));
- } else if (location->IsUnknown()) {
- // No information is specified by the caller - use the url
- // and the line number at the connection.
- bridge_->Fail(reason, level, location_at_connection_->Clone());
- } else {
- // Use the specified information.
- bridge_->Fail(reason, level, std::move(location));
- }
-}
-
-void WorkerWebSocketChannel::Disconnect() {
- bridge_->Disconnect();
- bridge_.Clear();
-}
-
-void WorkerWebSocketChannel::Trace(blink::Visitor* visitor) {
- visitor->Trace(bridge_);
- WebSocketChannel::Trace(visitor);
-}
-
-MainChannelClient::MainChannelClient(
- Bridge* bridge,
- scoped_refptr<base::SingleThreadTaskRunner> worker_networking_task_runner,
- WorkerThreadLifecycleContext* worker_thread_lifecycle_context)
- : WorkerThreadLifecycleObserver(worker_thread_lifecycle_context),
- bridge_(bridge),
- worker_networking_task_runner_(std::move(worker_networking_task_runner)),
- main_channel_(nullptr) {
- DCHECK(IsMainThread());
-}
-
-MainChannelClient::~MainChannelClient() {
- DCHECK(IsMainThread());
-}
-
-bool MainChannelClient::Initialize(std::unique_ptr<SourceLocation> location,
- ThreadableLoadingContext* loading_context) {
- DCHECK(IsMainThread());
- if (WasContextDestroyedBeforeObserverCreation())
- return false;
- main_channel_ =
- WebSocketChannelImpl::Create(loading_context, this, std::move(location));
- return true;
-}
-
-bool MainChannelClient::Connect(
- const KURL& url,
- const String& protocol,
- network::mojom::blink::WebSocketPtr socket_ptr) {
- DCHECK(IsMainThread());
- if (!main_channel_)
- return false;
- if (socket_ptr)
- return main_channel_->Connect(url, protocol, std::move(socket_ptr));
- // See Bridge::Connect for an explanation of the case where |socket_ptr| is
- // null. In this case we allow |main_channel_| to connect the pipe for us.
- return main_channel_->Connect(url, protocol);
-}
-
-void MainChannelClient::SendTextAsCharVector(
- std::unique_ptr<Vector<char>> data) {
- DCHECK(IsMainThread());
- if (main_channel_)
- main_channel_->SendTextAsCharVector(std::move(data));
-}
-
-void MainChannelClient::SendBinaryAsCharVector(
- std::unique_ptr<Vector<char>> data) {
- DCHECK(IsMainThread());
- if (main_channel_)
- main_channel_->SendBinaryAsCharVector(std::move(data));
-}
-
-void MainChannelClient::SendBlob(scoped_refptr<BlobDataHandle> blob_data) {
- DCHECK(IsMainThread());
- if (main_channel_)
- main_channel_->Send(std::move(blob_data));
-}
-
-void MainChannelClient::Close(int code, const String& reason) {
- DCHECK(IsMainThread());
- if (main_channel_)
- main_channel_->Close(code, reason);
-}
-
-void MainChannelClient::Fail(const String& reason,
- MessageLevel level,
- std::unique_ptr<SourceLocation> location) {
- DCHECK(IsMainThread());
- if (main_channel_)
- main_channel_->Fail(reason, level, std::move(location));
-}
-
-void MainChannelClient::ReleaseMainChannel() {
- if (!main_channel_)
- return;
-
- main_channel_->Disconnect();
- main_channel_ = nullptr;
-}
-
-void MainChannelClient::Disconnect() {
- DCHECK(IsMainThread());
-
- ReleaseMainChannel();
-}
-
-static void WorkerGlobalScopeDidConnect(Bridge* bridge,
- const String& subprotocol,
- const String& extensions) {
- if (bridge && bridge->Client())
- bridge->Client()->DidConnect(subprotocol, extensions);
-}
-
-void MainChannelClient::DidConnect(const String& subprotocol,
- const String& extensions) {
- DCHECK(IsMainThread());
- PostCrossThreadTask(*worker_networking_task_runner_, FROM_HERE,
- CrossThreadBind(&WorkerGlobalScopeDidConnect, bridge_,
- subprotocol, extensions));
-}
-
-static void WorkerGlobalScopeDidReceiveTextMessage(Bridge* bridge,
- const String& payload) {
- if (bridge && bridge->Client())
- bridge->Client()->DidReceiveTextMessage(payload);
-}
-
-void MainChannelClient::DidReceiveTextMessage(const String& payload) {
- DCHECK(IsMainThread());
- PostCrossThreadTask(*worker_networking_task_runner_, FROM_HERE,
- CrossThreadBind(&WorkerGlobalScopeDidReceiveTextMessage,
- bridge_, payload));
-}
-
-static void WorkerGlobalScopeDidReceiveBinaryMessage(
- Bridge* bridge,
- std::unique_ptr<Vector<char>> payload) {
- if (bridge && bridge->Client())
- bridge->Client()->DidReceiveBinaryMessage(std::move(payload));
-}
-
-void MainChannelClient::DidReceiveBinaryMessage(
- std::unique_ptr<Vector<char>> payload) {
- DCHECK(IsMainThread());
- PostCrossThreadTask(
- *worker_networking_task_runner_, FROM_HERE,
- CrossThreadBind(&WorkerGlobalScopeDidReceiveBinaryMessage, bridge_,
- WTF::Passed(std::move(payload))));
-}
-
-static void WorkerGlobalScopeDidConsumeBufferedAmount(Bridge* bridge,
- uint64_t consumed) {
- if (bridge && bridge->Client())
- bridge->Client()->DidConsumeBufferedAmount(consumed);
-}
-
-void MainChannelClient::DidConsumeBufferedAmount(uint64_t consumed) {
- DCHECK(IsMainThread());
- PostCrossThreadTask(
- *worker_networking_task_runner_, FROM_HERE,
- CrossThreadBind(&WorkerGlobalScopeDidConsumeBufferedAmount, bridge_,
- consumed));
-}
-
-static void WorkerGlobalScopeDidStartClosingHandshake(Bridge* bridge) {
- if (bridge && bridge->Client())
- bridge->Client()->DidStartClosingHandshake();
-}
-
-void MainChannelClient::DidStartClosingHandshake() {
- DCHECK(IsMainThread());
- PostCrossThreadTask(
- *worker_networking_task_runner_, FROM_HERE,
- CrossThreadBind(&WorkerGlobalScopeDidStartClosingHandshake, bridge_));
-}
-
-static void WorkerGlobalScopeDidClose(
- Bridge* bridge,
- WebSocketChannelClient::ClosingHandshakeCompletionStatus
- closing_handshake_completion,
- unsigned short code,
- const String& reason) {
- if (bridge && bridge->Client())
- bridge->Client()->DidClose(closing_handshake_completion, code, reason);
-}
-
-void MainChannelClient::DidClose(
- ClosingHandshakeCompletionStatus closing_handshake_completion,
- unsigned short code,
- const String& reason) {
- DCHECK(IsMainThread());
-
- ReleaseMainChannel();
-
- PostCrossThreadTask(
- *worker_networking_task_runner_, FROM_HERE,
- CrossThreadBind(&WorkerGlobalScopeDidClose, bridge_,
- closing_handshake_completion, code, reason));
-}
-
-static void WorkerGlobalScopeDidError(Bridge* bridge) {
- if (bridge && bridge->Client())
- bridge->Client()->DidError();
-}
-
-void MainChannelClient::DidError() {
- DCHECK(IsMainThread());
- PostCrossThreadTask(*worker_networking_task_runner_, FROM_HERE,
- CrossThreadBind(&WorkerGlobalScopeDidError, bridge_));
-}
-
-void MainChannelClient::ContextDestroyed(WorkerThreadLifecycleContext*) {
- DCHECK(IsMainThread());
-
- ReleaseMainChannel();
-
- bridge_ = nullptr;
-}
-
-void MainChannelClient::Trace(blink::Visitor* visitor) {
- visitor->Trace(main_channel_);
- WebSocketChannelClient::Trace(visitor);
- WorkerThreadLifecycleObserver::Trace(visitor);
-}
-
-Bridge::Bridge(WebSocketChannelClient* client,
- WorkerGlobalScope& worker_global_scope)
- : client_(client),
- worker_global_scope_(worker_global_scope),
- parent_execution_context_task_runners_(
- worker_global_scope_->GetThread()
- ->GetParentExecutionContextTaskRunners()) {}
-
-Bridge::~Bridge() {
- DCHECK(!main_channel_client_);
-}
-
-void Bridge::ConnectOnMainThread(
- std::unique_ptr<SourceLocation> location,
- ThreadableLoadingContext* loading_context,
- scoped_refptr<base::SingleThreadTaskRunner> worker_networking_task_runner,
- WorkerThreadLifecycleContext* worker_thread_lifecycle_context,
- const KURL& url,
- const String& protocol,
- network::mojom::blink::WebSocketPtrInfo socket_ptr_info,
- WebSocketChannelSyncHelper* sync_helper) {
- DCHECK(IsMainThread());
- DCHECK(!main_channel_client_);
- MainChannelClient* main_channel_client =
- new MainChannelClient(this, std::move(worker_networking_task_runner),
- worker_thread_lifecycle_context);
- if (main_channel_client->Initialize(std::move(location), loading_context)) {
- main_channel_client_ = main_channel_client;
- sync_helper->SetConnectRequestResult(main_channel_client_->Connect(
- url, protocol, mojo::MakeProxy(std::move(socket_ptr_info))));
- }
- sync_helper->SignalWorkerThread();
-}
-
-bool Bridge::Connect(std::unique_ptr<SourceLocation> location,
- const KURL& url,
- const String& protocol) {
- DCHECK(worker_global_scope_->IsContextThread());
- // Wait for completion of the task on the main thread because the mixed
- // content check must synchronously be conducted.
- WebSocketChannelSyncHelper sync_helper;
- scoped_refptr<base::SingleThreadTaskRunner> worker_networking_task_runner =
- worker_global_scope_->GetTaskRunner(TaskType::kNetworking);
- WorkerThread* worker_thread = worker_global_scope_->GetThread();
-
- // Dedicated workers are a special case as they always have an associated
- // document and so can make requests using that context. In the case of
- // https://crbug.com/760708 for example this is necessary to apply the user's
- // SSL interstitial decision to WebSocket connections from the worker.
- network::mojom::blink::WebSocketPtrInfo socket_ptr_info;
- if (!worker_global_scope_->IsDedicatedWorkerGlobalScope()) {
- worker_global_scope_->GetInterfaceProvider()->GetInterface(
- mojo::MakeRequest(&socket_ptr_info));
- }
-
- PostCrossThreadTask(
- *parent_execution_context_task_runners_->Get(TaskType::kNetworking),
- FROM_HERE,
- CrossThreadBind(
- &Bridge::ConnectOnMainThread, WrapCrossThreadPersistent(this),
- WTF::Passed(location->Clone()),
- WrapCrossThreadPersistent(worker_thread->GetLoadingContext()),
- std::move(worker_networking_task_runner),
- WrapCrossThreadPersistent(
- worker_thread->GetWorkerThreadLifecycleContext()),
- url, protocol, WTF::Passed(std::move(socket_ptr_info)),
- CrossThreadUnretained(&sync_helper)));
- sync_helper.Wait();
- return sync_helper.ConnectRequestResult();
-}
-
-void Bridge::Send(const CString& message) {
- DCHECK(main_channel_client_);
- std::unique_ptr<Vector<char>> data =
- std::make_unique<Vector<char>>(message.length());
- if (message.length()) {
- memcpy(data->data(), static_cast<const char*>(message.data()),
- message.length());
- }
-
- PostCrossThreadTask(
- *parent_execution_context_task_runners_->Get(TaskType::kNetworking),
- FROM_HERE,
- CrossThreadBind(&MainChannelClient::SendTextAsCharVector,
- main_channel_client_, WTF::Passed(std::move(data))));
-}
-
-void Bridge::Send(const DOMArrayBuffer& binary_data,
- unsigned byte_offset,
- unsigned byte_length) {
- DCHECK(main_channel_client_);
- // ArrayBuffer isn't thread-safe, hence the content of ArrayBuffer is copied
- // into Vector<char>.
- std::unique_ptr<Vector<char>> data =
- std::make_unique<Vector<char>>(byte_length);
- if (binary_data.ByteLength()) {
- memcpy(data->data(),
- static_cast<const char*>(binary_data.Data()) + byte_offset,
- byte_length);
- }
-
- PostCrossThreadTask(
- *parent_execution_context_task_runners_->Get(TaskType::kNetworking),
- FROM_HERE,
- CrossThreadBind(&MainChannelClient::SendBinaryAsCharVector,
- main_channel_client_, WTF::Passed(std::move(data))));
-}
-
-void Bridge::Send(scoped_refptr<BlobDataHandle> data) {
- DCHECK(main_channel_client_);
- PostCrossThreadTask(
- *parent_execution_context_task_runners_->Get(TaskType::kNetworking),
- FROM_HERE,
- CrossThreadBind(&MainChannelClient::SendBlob, main_channel_client_,
- std::move(data)));
-}
-
-void Bridge::Close(int code, const String& reason) {
- DCHECK(main_channel_client_);
- PostCrossThreadTask(
- *parent_execution_context_task_runners_->Get(TaskType::kNetworking),
- FROM_HERE,
- CrossThreadBind(&MainChannelClient::Close, main_channel_client_, code,
- reason));
-}
-
-void Bridge::Fail(const String& reason,
- MessageLevel level,
- std::unique_ptr<SourceLocation> location) {
- DCHECK(main_channel_client_);
- PostCrossThreadTask(
- *parent_execution_context_task_runners_->Get(TaskType::kNetworking),
- FROM_HERE,
- CrossThreadBind(&MainChannelClient::Fail, main_channel_client_, reason,
- level, WTF::Passed(location->Clone())));
-}
-
-void Bridge::Disconnect() {
- if (!main_channel_client_)
- return;
-
- PostCrossThreadTask(
- *parent_execution_context_task_runners_->Get(TaskType::kNetworking),
- FROM_HERE,
- CrossThreadBind(&MainChannelClient::Disconnect, main_channel_client_));
-
- client_ = nullptr;
- main_channel_client_ = nullptr;
- worker_global_scope_.Clear();
-}
-
-void Bridge::Trace(blink::Visitor* visitor) {
- visitor->Trace(client_);
- visitor->Trace(worker_global_scope_);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/websockets/worker_websocket_channel.h b/chromium/third_party/blink/renderer/modules/websockets/worker_websocket_channel.h
deleted file mode 100644
index af463954b54..00000000000
--- a/chromium/third_party/blink/renderer/modules/websockets/worker_websocket_channel.h
+++ /dev/null
@@ -1,217 +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.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBSOCKETS_WORKER_WEBSOCKET_CHANNEL_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBSOCKETS_WORKER_WEBSOCKET_CHANNEL_H_
-
-#include <stdint.h>
-#include <memory>
-#include "base/location.h"
-#include "base/macros.h"
-#include "base/memory/scoped_refptr.h"
-#include "base/single_thread_task_runner.h"
-#include "services/network/public/mojom/websocket.mojom-blink.h"
-#include "third_party/blink/renderer/bindings/core/v8/source_location.h"
-#include "third_party/blink/renderer/core/workers/parent_execution_context_task_runners.h"
-#include "third_party/blink/renderer/core/workers/worker_thread_lifecycle_observer.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_channel_impl.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/forward.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-#include "third_party/blink/renderer/platform/wtf/vector.h"
-
-namespace blink {
-
-class BlobDataHandle;
-class KURL;
-class ThreadableLoadingContext;
-class WebSocketChannelSyncHelper;
-class WorkerGlobalScope;
-class WorkerThreadLifecycleContext;
-
-class WorkerWebSocketChannel final : public WebSocketChannel {
- public:
- static WebSocketChannel* Create(WorkerGlobalScope& worker_global_scope,
- WebSocketChannelClient* client,
- std::unique_ptr<SourceLocation> location) {
- return new WorkerWebSocketChannel(worker_global_scope, client,
- std::move(location));
- }
- ~WorkerWebSocketChannel() override;
-
- // WebSocketChannel functions.
- bool Connect(const KURL&, const String& protocol) override;
- void Send(const CString&) override;
- void Send(const DOMArrayBuffer&,
- unsigned byte_offset,
- unsigned byte_length) override;
- void Send(scoped_refptr<BlobDataHandle>) override;
- void SendTextAsCharVector(std::unique_ptr<Vector<char>>) override {
- NOTREACHED();
- }
- void SendBinaryAsCharVector(std::unique_ptr<Vector<char>>) override {
- NOTREACHED();
- }
- void Close(int code, const String& reason) override;
- void Fail(const String& reason,
- MessageLevel,
- std::unique_ptr<SourceLocation>) override;
- void Disconnect() override; // Will suppress didClose().
-
- void Trace(blink::Visitor*) override;
-
- class Bridge;
-
- // A WebSocketChannelClient to pass to |main_channel_|. It forwards
- // method incovactions to the worker thread, and re-invokes them on the
- // WebSocketChannelClient given to the WorkerWebSocketChannel.
- //
- // Allocated and used in the main thread.
- class MainChannelClient final
- : public GarbageCollectedFinalized<MainChannelClient>,
- public WebSocketChannelClient,
- public WorkerThreadLifecycleObserver {
- USING_GARBAGE_COLLECTED_MIXIN(MainChannelClient);
-
- public:
- MainChannelClient(Bridge*,
- scoped_refptr<base::SingleThreadTaskRunner>,
- WorkerThreadLifecycleContext*);
- ~MainChannelClient() override;
-
- // SourceLocation parameter may be shown when the connection fails.
- bool Initialize(std::unique_ptr<SourceLocation>, ThreadableLoadingContext*);
-
- bool Connect(const KURL&,
- const String& protocol,
- network::mojom::blink::WebSocketPtr);
- void SendTextAsCharVector(std::unique_ptr<Vector<char>>);
- void SendBinaryAsCharVector(std::unique_ptr<Vector<char>>);
- void SendBlob(scoped_refptr<BlobDataHandle>);
- void Close(int code, const String& reason);
- void Fail(const String& reason,
- MessageLevel,
- std::unique_ptr<SourceLocation>);
- void Disconnect();
-
- void Trace(blink::Visitor*) override;
- // Promptly clear connection to bridge + loader proxy.
- EAGERLY_FINALIZE();
-
- // WebSocketChannelClient functions.
- void DidConnect(const String& subprotocol,
- const String& extensions) override;
- void DidReceiveTextMessage(const String& payload) override;
- void DidReceiveBinaryMessage(std::unique_ptr<Vector<char>>) override;
- void DidConsumeBufferedAmount(uint64_t) override;
- void DidStartClosingHandshake() override;
- void DidClose(ClosingHandshakeCompletionStatus,
- unsigned short code,
- const String& reason) override;
- void DidError() override;
-
- // WorkerThreadLifecycleObserver function.
- void ContextDestroyed(WorkerThreadLifecycleContext*) override;
-
- private:
- void ReleaseMainChannel();
-
- CrossThreadWeakPersistent<Bridge> bridge_;
- scoped_refptr<base::SingleThreadTaskRunner> worker_networking_task_runner_;
- Member<WebSocketChannelImpl> main_channel_;
-
- DISALLOW_COPY_AND_ASSIGN(MainChannelClient);
- };
-
- // Bridge for MainChannelClient. Running on the worker thread.
- class Bridge final : public GarbageCollectedFinalized<Bridge> {
- public:
- Bridge(WebSocketChannelClient*, WorkerGlobalScope&);
- ~Bridge();
-
- // SourceLocation parameter may be shown when the connection fails.
- bool Connect(std::unique_ptr<SourceLocation>,
- const KURL&,
- const String& protocol);
-
- void Send(const CString& message);
- void Send(const DOMArrayBuffer&,
- unsigned byte_offset,
- unsigned byte_length);
- void Send(scoped_refptr<BlobDataHandle>);
- void Close(int code, const String& reason);
- void Fail(const String& reason,
- MessageLevel,
- std::unique_ptr<SourceLocation>);
- void Disconnect();
-
- void ConnectOnMainThread(std::unique_ptr<SourceLocation>,
- ThreadableLoadingContext*,
- scoped_refptr<base::SingleThreadTaskRunner>,
- WorkerThreadLifecycleContext*,
- const KURL&,
- const String& protocol,
- network::mojom::blink::WebSocketPtrInfo,
- WebSocketChannelSyncHelper*);
-
- // Returns null when |disconnect| has already been called.
- WebSocketChannelClient* Client() { return client_; }
-
- void Trace(blink::Visitor*);
- // Promptly clear connection to peer + loader proxy.
- EAGERLY_FINALIZE();
-
- private:
- Member<WebSocketChannelClient> client_;
- Member<WorkerGlobalScope> worker_global_scope_;
- CrossThreadPersistent<ParentExecutionContextTaskRunners>
- parent_execution_context_task_runners_;
- CrossThreadPersistent<MainChannelClient> main_channel_client_;
-
- DISALLOW_COPY_AND_ASSIGN(Bridge);
- };
-
- private:
- WorkerWebSocketChannel(WorkerGlobalScope&,
- WebSocketChannelClient*,
- std::unique_ptr<SourceLocation>);
-
- Member<Bridge> bridge_;
- std::unique_ptr<SourceLocation> location_at_connection_;
-
- DISALLOW_COPY_AND_ASSIGN(WorkerWebSocketChannel);
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBSOCKETS_WORKER_WEBSOCKET_CHANNEL_H_
diff --git a/chromium/third_party/blink/renderer/modules/webusb/BUILD.gn b/chromium/third_party/blink/renderer/modules/webusb/BUILD.gn
index 5f8e5b15774..31718fecc9a 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/webusb/BUILD.gn
@@ -31,8 +31,4 @@ blink_modules_sources("webusb") {
"worker_navigator_usb.cc",
"worker_navigator_usb.h",
]
-
- deps = [
- "//device/usb/public/mojom:mojom_blink",
- ]
}
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb.cc b/chromium/third_party/blink/renderer/modules/webusb/usb.cc
index 431d39b3e70..6f96c1ae804 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb.cc
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb.cc
@@ -13,6 +13,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/frame/frame.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/webusb/usb_connection_event.h"
#include "third_party/blink/renderer/modules/webusb/usb_device.h"
@@ -61,11 +62,10 @@ USB::USB(ExecutionContext& context)
: ContextLifecycleObserver(&context), client_binding_(this) {}
USB::~USB() {
- // |m_deviceManager| and |m_chooserService| may still be valid but there
- // should be no more outstanding requests to them because each holds a
- // persistent handle to this object.
- DCHECK(device_manager_requests_.IsEmpty());
- DCHECK(chooser_service_requests_.IsEmpty());
+ // |service_| may still be valid but there should be no more outstanding
+ // requests to them because each holds a persistent handle to this object.
+ DCHECK(get_devices_requests_.IsEmpty());
+ DCHECK(get_permission_requests_.IsEmpty());
}
void USB::Dispose() {
@@ -81,17 +81,22 @@ ScriptPromise USB::getDevices(ScriptState* script_state) {
DOMException::Create(DOMExceptionCode::kNotSupportedError));
}
if (!IsFeatureEnabled()) {
+ ExecutionContext* execution_context = ExecutionContext::From(script_state);
+ if (execution_context && execution_context->IsDocument()) {
+ ToDocument(execution_context)
+ ->GetFrame()
+ ->ReportFeaturePolicyViolation(mojom::FeaturePolicyFeature::kUsb);
+ }
return ScriptPromise::RejectWithDOMException(
script_state, DOMException::Create(DOMExceptionCode::kSecurityError,
kFeaturePolicyBlocked));
}
- EnsureDeviceManagerConnection();
+ EnsureServiceConnection();
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
- device_manager_requests_.insert(resolver);
- device_manager_->GetDevices(
- nullptr, WTF::Bind(&USB::OnGetDevices, WrapPersistent(this),
- WrapPersistent(resolver)));
+ get_devices_requests_.insert(resolver);
+ service_->GetDevices(WTF::Bind(&USB::OnGetDevices, WrapPersistent(this),
+ WrapPersistent(resolver)));
return resolver->Promise();
}
@@ -104,18 +109,14 @@ ScriptPromise USB::requestDevice(ScriptState* script_state,
DOMException::Create(DOMExceptionCode::kNotSupportedError));
}
- if (!frame->IsFeatureEnabled(mojom::FeaturePolicyFeature::kUsb)) {
+ if (!frame->IsFeatureEnabled(mojom::FeaturePolicyFeature::kUsb,
+ ReportOptions::kReportOnFailure)) {
return ScriptPromise::RejectWithDOMException(
script_state, DOMException::Create(DOMExceptionCode::kSecurityError,
kFeaturePolicyBlocked));
}
- if (!chooser_service_) {
- GetFrame()->GetInterfaceProvider().GetInterface(
- mojo::MakeRequest(&chooser_service_));
- chooser_service_.set_connection_error_handler(WTF::Bind(
- &USB::OnChooserServiceConnectionError, WrapWeakPersistent(this)));
- }
+ EnsureServiceConnection();
if (!Frame::HasTransientUserActivation(frame)) {
return ScriptPromise::RejectWithDOMException(
@@ -133,9 +134,9 @@ ScriptPromise USB::requestDevice(ScriptState* script_state,
}
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
- chooser_service_requests_.insert(resolver);
- chooser_service_->GetPermission(
- std::move(filters), WTF::Bind(&USB::OnGetPermission, WrapPersistent(this),
+ get_permission_requests_.insert(resolver);
+ service_->GetPermission(std::move(filters),
+ WTF::Bind(&USB::OnGetPermission, WrapPersistent(this),
WrapPersistent(resolver)));
return resolver->Promise();
}
@@ -149,10 +150,9 @@ const AtomicString& USB::InterfaceName() const {
}
void USB::ContextDestroyed(ExecutionContext*) {
- device_manager_.reset();
- device_manager_requests_.clear();
- chooser_service_.reset();
- chooser_service_requests_.clear();
+ service_.reset();
+ get_devices_requests_.clear();
+ get_permission_requests_.clear();
}
USBDevice* USB::GetOrCreateDevice(UsbDeviceInfoPtr device_info) {
@@ -160,7 +160,7 @@ USBDevice* USB::GetOrCreateDevice(UsbDeviceInfoPtr device_info) {
if (!device) {
String guid = device_info->guid;
UsbDevicePtr pipe;
- device_manager_->GetDevice(guid, mojo::MakeRequest(&pipe));
+ service_->GetDevice(guid, mojo::MakeRequest(&pipe));
device = USBDevice::Create(std::move(device_info), std::move(pipe),
GetExecutionContext());
device_cache_.insert(guid, device);
@@ -170,40 +170,35 @@ USBDevice* USB::GetOrCreateDevice(UsbDeviceInfoPtr device_info) {
void USB::OnGetDevices(ScriptPromiseResolver* resolver,
Vector<UsbDeviceInfoPtr> device_infos) {
- auto request_entry = device_manager_requests_.find(resolver);
- if (request_entry == device_manager_requests_.end())
- return;
- device_manager_requests_.erase(request_entry);
+ DCHECK(get_devices_requests_.Contains(resolver));
HeapVector<Member<USBDevice>> devices;
for (auto& device_info : device_infos)
devices.push_back(GetOrCreateDevice(std::move(device_info)));
resolver->Resolve(devices);
- device_manager_requests_.erase(resolver);
+ get_devices_requests_.erase(resolver);
}
void USB::OnGetPermission(ScriptPromiseResolver* resolver,
UsbDeviceInfoPtr device_info) {
- auto request_entry = chooser_service_requests_.find(resolver);
- if (request_entry == chooser_service_requests_.end())
- return;
- chooser_service_requests_.erase(request_entry);
+ DCHECK(get_permission_requests_.Contains(resolver));
- EnsureDeviceManagerConnection();
+ EnsureServiceConnection();
- if (device_manager_ && device_info) {
+ if (service_ && device_info) {
resolver->Resolve(GetOrCreateDevice(std::move(device_info)));
} else {
resolver->Reject(DOMException::Create(DOMExceptionCode::kNotFoundError,
kNoDeviceSelected));
}
+ get_permission_requests_.erase(resolver);
}
void USB::OnDeviceAdded(UsbDeviceInfoPtr device_info) {
- if (!device_manager_)
+ if (!service_)
return;
- DispatchEvent(USBConnectionEvent::Create(
+ DispatchEvent(*USBConnectionEvent::Create(
EventTypeNames::connect, GetOrCreateDevice(std::move(device_info))));
}
@@ -214,25 +209,23 @@ void USB::OnDeviceRemoved(UsbDeviceInfoPtr device_info) {
device = USBDevice::Create(std::move(device_info), nullptr,
GetExecutionContext());
}
- DispatchEvent(USBConnectionEvent::Create(EventTypeNames::disconnect, device));
+ DispatchEvent(
+ *USBConnectionEvent::Create(EventTypeNames::disconnect, device));
device_cache_.erase(guid);
}
-void USB::OnDeviceManagerConnectionError() {
- device_manager_.reset();
+void USB::OnServiceConnectionError() {
+ service_.reset();
client_binding_.Close();
- for (ScriptPromiseResolver* resolver : device_manager_requests_)
+ for (ScriptPromiseResolver* resolver : get_devices_requests_)
resolver->Resolve(HeapVector<Member<USBDevice>>(0));
- device_manager_requests_.clear();
-}
+ get_devices_requests_.clear();
-void USB::OnChooserServiceConnectionError() {
- chooser_service_.reset();
- for (ScriptPromiseResolver* resolver : chooser_service_requests_) {
+ for (ScriptPromiseResolver* resolver : get_permission_requests_) {
resolver->Reject(DOMException::Create(DOMExceptionCode::kNotFoundError,
kNoDeviceSelected));
}
- chooser_service_requests_.clear();
+ get_permission_requests_.clear();
}
void USB::AddedEventListener(const AtomicString& event_type,
@@ -246,25 +239,25 @@ void USB::AddedEventListener(const AtomicString& event_type,
if (!IsContextSupported() || !IsFeatureEnabled())
return;
- EnsureDeviceManagerConnection();
+ EnsureServiceConnection();
}
-void USB::EnsureDeviceManagerConnection() {
- if (device_manager_)
+void USB::EnsureServiceConnection() {
+ if (service_)
return;
DCHECK(IsContextSupported());
DCHECK(IsFeatureEnabled());
GetExecutionContext()->GetInterfaceProvider()->GetInterface(
- mojo::MakeRequest(&device_manager_));
- device_manager_.set_connection_error_handler(WTF::Bind(
- &USB::OnDeviceManagerConnectionError, WrapWeakPersistent(this)));
+ mojo::MakeRequest(&service_));
+ service_.set_connection_error_handler(
+ WTF::Bind(&USB::OnServiceConnectionError, WrapWeakPersistent(this)));
DCHECK(!client_binding_.is_bound());
device::mojom::blink::UsbDeviceManagerClientPtr client;
client_binding_.Bind(mojo::MakeRequest(&client));
- device_manager_->SetClient(std::move(client));
+ service_->SetClient(std::move(client));
}
bool USB::IsContextSupported() const {
@@ -276,12 +269,9 @@ bool USB::IsContextSupported() const {
if (!context)
return false;
- DCHECK(context->IsDocument() || context->IsDedicatedWorkerGlobalScope() ||
- context->IsSharedWorkerGlobalScope());
+ DCHECK(context->IsDocument() || context->IsDedicatedWorkerGlobalScope());
DCHECK(!context->IsDedicatedWorkerGlobalScope() ||
RuntimeEnabledFeatures::WebUSBOnDedicatedWorkersEnabled());
- DCHECK(!context->IsSharedWorkerGlobalScope() ||
- RuntimeEnabledFeatures::WebUSBOnSharedWorkersEnabled());
return true;
}
@@ -289,20 +279,12 @@ bool USB::IsContextSupported() const {
bool USB::IsFeatureEnabled() const {
ExecutionContext* context = GetExecutionContext();
FeaturePolicy* policy = context->GetSecurityContext().GetFeaturePolicy();
- // Feature policy is not yet supported in all contexts.
- if (policy)
- return policy->IsFeatureEnabled(mojom::FeaturePolicyFeature::kUsb);
-
- // TODO(https://crbug.com/843780): Enable this check for shared workers.
- if (context->IsSharedWorkerGlobalScope())
- return true;
-
- return false;
+ return policy->IsFeatureEnabled(mojom::FeaturePolicyFeature::kUsb);
}
void USB::Trace(blink::Visitor* visitor) {
- visitor->Trace(device_manager_requests_);
- visitor->Trace(chooser_service_requests_);
+ visitor->Trace(get_devices_requests_);
+ visitor->Trace(get_permission_requests_);
visitor->Trace(device_cache_);
EventTargetWithInlineData::Trace(visitor);
ContextLifecycleObserver::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb.h b/chromium/third_party/blink/renderer/modules/webusb/usb.h
index 56c55843214..9c871d920fd 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb.h
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb.h
@@ -5,9 +5,9 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBUSB_USB_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBUSB_USB_H_
-#include "device/usb/public/mojom/chooser_service.mojom-blink.h"
#include "device/usb/public/mojom/device_manager.mojom-blink.h"
#include "mojo/public/cpp/bindings/binding.h"
+#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/context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
@@ -51,8 +51,8 @@ class USB final : public EventTargetWithInlineData,
USBDevice* GetOrCreateDevice(device::mojom::blink::UsbDeviceInfoPtr);
- device::mojom::blink::UsbDeviceManager* GetDeviceManager() const {
- return device_manager_.get();
+ mojom::blink::WebUsbService* GetWebUsbService() const {
+ return service_.get();
}
void OnGetDevices(ScriptPromiseResolver*,
@@ -64,8 +64,7 @@ class USB final : public EventTargetWithInlineData,
void OnDeviceAdded(device::mojom::blink::UsbDeviceInfoPtr) override;
void OnDeviceRemoved(device::mojom::blink::UsbDeviceInfoPtr) override;
- void OnDeviceManagerConnectionError();
- void OnChooserServiceConnectionError();
+ void OnServiceConnectionError();
void Trace(blink::Visitor*) override;
@@ -77,15 +76,14 @@ class USB final : public EventTargetWithInlineData,
private:
explicit USB(ExecutionContext&);
- void EnsureDeviceManagerConnection();
+ void EnsureServiceConnection();
bool IsContextSupported() const;
bool IsFeatureEnabled() const;
- device::mojom::blink::UsbDeviceManagerPtr device_manager_;
- HeapHashSet<Member<ScriptPromiseResolver>> device_manager_requests_;
- device::mojom::blink::UsbChooserServicePtr chooser_service_;
- HeapHashSet<Member<ScriptPromiseResolver>> chooser_service_requests_;
+ mojom::blink::WebUsbServicePtr service_;
+ HeapHashSet<Member<ScriptPromiseResolver>> get_devices_requests_;
+ HeapHashSet<Member<ScriptPromiseResolver>> get_permission_requests_;
mojo::Binding<device::mojom::blink::UsbDeviceManagerClient> client_binding_;
HeapHashMap<String, WeakMember<USBDevice>> device_cache_;
};
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb.idl b/chromium/third_party/blink/renderer/modules/webusb/usb.idl
index 06b82871d7b..05247015fbc 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb.idl
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb.idl
@@ -5,7 +5,7 @@
// https://wicg.github.io/webusb/#usb
[
- Exposed(DedicatedWorker WebUSBOnDedicatedWorkers, SharedWorker WebUSBOnSharedWorkers, Window WebUSB),
+ Exposed(DedicatedWorker WebUSBOnDedicatedWorkers, Window WebUSB),
SecureContext
] interface USB : EventTarget {
attribute EventHandler onconnect;
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 20cfe45c31b..80de8d96866 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
@@ -6,7 +6,7 @@
[
Constructor(USBInterface deviceInterface, octet alternateSetting),
- Exposed(DedicatedWorker WebUSBOnDedicatedWorkers, SharedWorker WebUSBOnSharedWorkers, Window WebUSB),
+ Exposed(DedicatedWorker WebUSBOnDedicatedWorkers, Window WebUSB),
RaisesException=Constructor,
SecureContext
] interface USBAlternateInterface {
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 a4ebe754bea..62e2d00c9ff 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_configuration.idl
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_configuration.idl
@@ -6,7 +6,7 @@
[
Constructor(USBDevice device, octet configurationValue),
- Exposed(DedicatedWorker WebUSBOnDedicatedWorkers, SharedWorker WebUSBOnSharedWorkers, Window WebUSB),
+ Exposed(DedicatedWorker WebUSBOnDedicatedWorkers, Window WebUSB),
RaisesException=Constructor,
SecureContext
] interface USBConfiguration {
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 ed62a8e08d6..e3c22d176c7 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
@@ -6,7 +6,7 @@
[
Constructor(DOMString type, USBConnectionEventInit eventInitDict),
- Exposed(DedicatedWorker WebUSBOnDedicatedWorkers, SharedWorker WebUSBOnSharedWorkers, Window WebUSB),
+ Exposed(DedicatedWorker WebUSBOnDedicatedWorkers, Window WebUSB),
SecureContext
] interface USBConnectionEvent : Event {
[SameObject] readonly attribute USBDevice device;
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_device.idl b/chromium/third_party/blink/renderer/modules/webusb/usb_device.idl
index bff5d2ed90d..223fb5faa3f 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_device.idl
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_device.idl
@@ -13,7 +13,7 @@ enum USBTransferStatus {
// https://wicg.github.io/webusb/#device-usage
[
- Exposed(DedicatedWorker WebUSBOnDedicatedWorkers, SharedWorker WebUSBOnSharedWorkers, Window WebUSB),
+ Exposed(DedicatedWorker WebUSBOnDedicatedWorkers, Window WebUSB),
SecureContext
] interface USBDevice {
readonly attribute octet usbVersionMajor;
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 80d529894e3..679e88250ed 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_endpoint.idl
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_endpoint.idl
@@ -17,7 +17,7 @@ enum USBEndpointType {
[
Constructor(USBAlternateInterface alternate, octet endpointNumber, USBDirection direction),
- Exposed(DedicatedWorker WebUSBOnDedicatedWorkers, SharedWorker WebUSBOnSharedWorkers, Window WebUSB),
+ Exposed(DedicatedWorker WebUSBOnDedicatedWorkers, Window WebUSB),
RaisesException=Constructor,
SecureContext
] interface USBEndpoint {
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 3efc62c55ca..2c9fed6e37b 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
@@ -5,7 +5,7 @@
// https://wicg.github.io/webusb/#usbintransferresult
[
- Exposed(DedicatedWorker WebUSBOnDedicatedWorkers, SharedWorker WebUSBOnSharedWorkers, Window WebUSB),
+ Exposed(DedicatedWorker WebUSBOnDedicatedWorkers, Window WebUSB),
Constructor(USBTransferStatus status, optional DataView? data),
SecureContext
] interface USBInTransferResult {
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 a25d466adcb..16da8b78372 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_interface.idl
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_interface.idl
@@ -6,7 +6,7 @@
[
Constructor(USBConfiguration configuration, octet interfaceNumber),
- Exposed(DedicatedWorker WebUSBOnDedicatedWorkers, SharedWorker WebUSBOnSharedWorkers, Window WebUSB),
+ Exposed(DedicatedWorker WebUSBOnDedicatedWorkers, Window WebUSB),
RaisesException=Constructor,
SecureContext
] interface USBInterface {
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 313adbb9374..d1f213e0a6a 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
@@ -6,7 +6,7 @@
[
Constructor(USBTransferStatus status, optional DataView? data),
- Exposed(DedicatedWorker WebUSBOnDedicatedWorkers, SharedWorker WebUSBOnSharedWorkers, Window WebUSB),
+ Exposed(DedicatedWorker WebUSBOnDedicatedWorkers, Window WebUSB),
SecureContext
] interface USBIsochronousInTransferPacket {
readonly attribute USBTransferStatus status;
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 0d6b8187d74..ccf61d828f1 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
@@ -6,7 +6,7 @@
[
Constructor(sequence<USBIsochronousInTransferPacket> packets, optional DataView? data),
- Exposed(DedicatedWorker WebUSBOnDedicatedWorkers, SharedWorker WebUSBOnSharedWorkers, Window WebUSB),
+ Exposed(DedicatedWorker WebUSBOnDedicatedWorkers, Window WebUSB),
SecureContext
] interface USBIsochronousInTransferResult {
readonly attribute DataView? data;
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 f080b0e4bc2..7473dd031c9 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
@@ -6,7 +6,7 @@
[
Constructor(USBTransferStatus status, optional unsigned long bytesWritten = 0),
- Exposed(DedicatedWorker WebUSBOnDedicatedWorkers, SharedWorker WebUSBOnSharedWorkers, Window WebUSB),
+ Exposed(DedicatedWorker WebUSBOnDedicatedWorkers, Window WebUSB),
SecureContext
] interface USBIsochronousOutTransferPacket {
readonly attribute unsigned long bytesWritten;
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 01e694029a0..3062e081a7f 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
@@ -6,7 +6,7 @@
[
Constructor(sequence<USBIsochronousOutTransferPacket> packets),
- Exposed(DedicatedWorker WebUSBOnDedicatedWorkers, SharedWorker WebUSBOnSharedWorkers, Window WebUSB),
+ Exposed(DedicatedWorker WebUSBOnDedicatedWorkers, Window WebUSB),
SecureContext
] interface USBIsochronousOutTransferResult {
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 b68561e164b..dec458c6cde 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
@@ -5,7 +5,7 @@
// https://wicg.github.io/webusb/#usbouttransferresult
[
- Exposed(DedicatedWorker WebUSBOnDedicatedWorkers, SharedWorker WebUSBOnSharedWorkers, Window WebUSB),
+ Exposed(DedicatedWorker WebUSBOnDedicatedWorkers, Window WebUSB),
Constructor(USBTransferStatus status, optional unsigned long bytesWritten = 0),
SecureContext
] interface USBOutTransferResult {
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 d26f54be32c..b521d2f00a2 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
@@ -42,11 +42,8 @@ USB* WorkerNavigatorUSB::usb(ScriptState* script_state) {
bool isDedicatedWorkerAndEnabled =
context->IsDedicatedWorkerGlobalScope() &&
RuntimeEnabledFeatures::WebUSBOnDedicatedWorkersEnabled();
- bool isSharedWorkerAndEnabled =
- context->IsSharedWorkerGlobalScope() &&
- RuntimeEnabledFeatures::WebUSBOnSharedWorkersEnabled();
- if (isDedicatedWorkerAndEnabled || isSharedWorkerAndEnabled) {
+ if (isDedicatedWorkerAndEnabled) {
usb_ = USB::Create(*context);
}
}
diff --git a/chromium/third_party/blink/renderer/modules/webusb/worker_navigator_usb.idl b/chromium/third_party/blink/renderer/modules/webusb/worker_navigator_usb.idl
index 555bbcc74af..9985ad45b0b 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/worker_navigator_usb.idl
+++ b/chromium/third_party/blink/renderer/modules/webusb/worker_navigator_usb.idl
@@ -5,7 +5,7 @@
// https://wicg.github.io/webusb/#enumeration
[
- Exposed(DedicatedWorker WebUSBOnDedicatedWorkers, SharedWorker WebUSBOnSharedWorkers),
+ Exposed(DedicatedWorker WebUSBOnDedicatedWorkers),
ImplementedAs=WorkerNavigatorUSB,
SecureContext
] partial interface WorkerNavigator {
diff --git a/chromium/third_party/blink/renderer/modules/xr/BUILD.gn b/chromium/third_party/blink/renderer/modules/xr/BUILD.gn
index c9d3f2f3904..e742a893b65 100644
--- a/chromium/third_party/blink/renderer/modules/xr/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/xr/BUILD.gn
@@ -44,7 +44,6 @@ blink_modules_sources("xr") {
"xr_session_event.h",
"xr_stage_bounds.cc",
"xr_stage_bounds.h",
- "xr_stage_bounds_point.h",
"xr_utils.cc",
"xr_utils.h",
"xr_view.cc",
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr.cc b/chromium/third_party/blink/renderer/modules/xr/xr.cc
index 58c4a8aa7f4..94d75fb3781 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr.cc
@@ -32,26 +32,17 @@ const char kNoDevicesMessage[] = "No devices found.";
XR::XR(LocalFrame& frame, int64_t ukm_source_id)
: ContextLifecycleObserver(frame.GetDocument()),
FocusChangedObserver(frame.GetPage()),
- devices_synced_(false),
ukm_source_id_(ukm_source_id),
binding_(this) {
frame.GetInterfaceProvider().GetInterface(mojo::MakeRequest(&service_));
service_.set_connection_error_handler(
WTF::Bind(&XR::Dispose, WrapWeakPersistent(this)));
-
- device::mojom::blink::VRServiceClientPtr client;
- binding_.Bind(mojo::MakeRequest(&client));
-
- // Setting the client kicks off a request for the details of any connected
- // XRDevices.
- service_->SetClient(std::move(client),
- WTF::Bind(&XR::OnDevicesSynced, WrapPersistent(this)));
}
void XR::FocusedFrameChanged() {
- // Tell devices that focus changed.
- for (const auto& device : devices_)
- device->OnFrameFocusChanged();
+ // Tell device that focus changed.
+ if (device_)
+ device_->OnFrameFocusChanged();
}
bool XR::IsFrameFocused() {
@@ -99,60 +90,58 @@ ScriptPromise XR::requestDevice(ScriptState* script_state) {
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
ScriptPromise promise = resolver->Promise();
- // If we've previously synced the XRDevices or no longer have a valid service
- // connection just use the current list. In the case of the service being
- // disconnected this will be an empty array.
- if (!service_ || devices_synced_) {
- // TODO (offenwanger): When we have a prioritized order of devices, or some
- // other method of getting the prefered device, insert that here. For now,
- // just get the first device out of the list, if there is one.
- if (devices_.size() == 0) {
- resolver->Reject(DOMException::Create(DOMExceptionCode::kNotFoundError,
- kNoDevicesMessage));
- } else {
- resolver->Resolve(devices_[0]);
- }
+ // If we no longer have a valid service connection reject the request.
+ if (!service_) {
+ resolver->Reject(DOMException::Create(DOMExceptionCode::kNotFoundError,
+ kNoDevicesMessage));
+ return promise;
+ }
+ // If we already have a device, use that.
+ if (device_) {
+ resolver->Resolve(device_);
return promise;
}
- // Otherwise wait for the full list of devices to be populated and resolve
- // when onDevicesSynced is called.
+ // Otherwise wait for device request callback.
pending_devices_resolver_ = resolver;
- return promise;
-}
+ // If we're waiting for sync, then request device is already underway.
+ if (pending_sync_) {
+ return promise;
+ }
-// Each time a new XRDevice is connected we'll recieve a XRDisplayPtr for it
-// here. Upon calling SetClient in the constructor we should receive one call
-// for each XRDevice that was already connected at the time.
-void XR::OnDisplayConnected(
- device::mojom::blink::VRDisplayHostPtr display,
- device::mojom::blink::VRDisplayClientRequest client_request,
- device::mojom::blink::VRDisplayInfoPtr display_info) {
- XRDevice* xr_device =
- new XRDevice(this, std::move(display), std::move(client_request),
- std::move(display_info));
+ service_->RequestDevice(
+ WTF::Bind(&XR::OnRequestDeviceReturned, WrapPersistent(this)));
+ pending_sync_ = true;
- devices_.push_back(xr_device);
+ return promise;
+}
- DispatchEvent(blink::Event::Create(EventTypeNames::devicechange));
+// This will call when the XRDevice and its capabilities has potentially
+// changed. For example, if a new physical device was connected to the system,
+// the XRDevice might now be able to support immersive sessions, where it
+// couldn't before.
+void XR::OnDeviceChanged() {
+ DispatchEvent(*blink::Event::Create(EventTypeNames::devicechange));
}
-// Called when the XRService has called OnDevicesConnected for all active
-// XRDevices.
-void XR::OnDevicesSynced() {
- devices_synced_ = true;
+void XR::OnRequestDeviceReturned(device::mojom::blink::XRDevicePtr device) {
+ pending_sync_ = false;
+ if (device) {
+ device_ = new XRDevice(this, std::move(device));
+ }
ResolveRequestDevice();
}
// Called when details for every connected XRDevice has been received.
void XR::ResolveRequestDevice() {
if (pending_devices_resolver_) {
- if (devices_.size() == 0) {
+ if (!device_) {
pending_devices_resolver_->Reject(DOMException::Create(
DOMExceptionCode::kNotFoundError, kNoDevicesMessage));
} else {
+ // Log metrics
if (!did_log_returned_device_ || !did_log_supports_immersive_) {
Document* doc = GetFrame() ? GetFrame()->GetDocument() : nullptr;
if (doc) {
@@ -160,23 +149,59 @@ void XR::ResolveRequestDevice() {
ukm_builder.SetReturnedDevice(1);
did_log_returned_device_ = true;
- // We only expose a single device to WebXR, so report that device's
- // capabilities.
- if (devices_[0]->SupportsImmersive()) {
- ukm_builder.SetReturnedPresentationCapableDevice(1);
- did_log_supports_immersive_ = true;
- }
-
ukm_builder.Record(doc->UkmRecorder());
+
+ device::mojom::blink::XRSessionOptionsPtr session_options =
+ device::mojom::blink::XRSessionOptions::New();
+ session_options->immersive = true;
+
+ // TODO(http://crbug.com/872086) This shouldn't need to be called.
+ // This information should be logged on the browser side.
+ device_->xrDevicePtr()->SupportsSession(
+ std::move(session_options),
+ WTF::Bind(&XR::ReportImmersiveSupported, WrapPersistent(this)));
}
}
- pending_devices_resolver_->Resolve(devices_[0]);
+
+ // Return the device.
+ pending_devices_resolver_->Resolve(device_);
}
pending_devices_resolver_ = nullptr;
}
}
+void XR::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_);
+ ukm_builder.SetReturnedPresentationCapableDevice(1);
+ ukm_builder.Record(doc->UkmRecorder());
+ did_log_supports_immersive_ = true;
+ }
+}
+
+void XR::AddedEventListener(const AtomicString& event_type,
+ RegisteredEventListener& registered_listener) {
+ EventTargetWithInlineData::AddedEventListener(event_type,
+ registered_listener);
+
+ // If we don't have device and there is no sync pending, then request the
+ // device to ensure devices have been enumerated and register as a listener
+ // for changes.
+ if (event_type == EventTypeNames::devicechange && !device_ &&
+ !pending_sync_) {
+ device::mojom::blink::VRServiceClientPtr client;
+ binding_.Bind(mojo::MakeRequest(&client));
+
+ service_->RequestDevice(
+ WTF::Bind(&XR::OnRequestDeviceReturned, WrapPersistent(this)));
+ service_->SetClient(std::move(client));
+
+ pending_sync_ = true;
+ }
+};
+
void XR::ContextDestroyed(ExecutionContext*) {
Dispose();
}
@@ -187,11 +212,9 @@ void XR::Dispose() {
service_.reset();
binding_.Close();
- // Shutdown all devices' message pipe
- for (const auto& device : devices_)
- device->Dispose();
-
- devices_.clear();
+ // Shutdown device's message pipe.
+ if (device_)
+ device_->Dispose();
// Ensure that any outstanding requestDevice promises are resolved. They will
// receive a null result.
@@ -199,7 +222,7 @@ void XR::Dispose() {
}
void XR::Trace(blink::Visitor* visitor) {
- visitor->Trace(devices_);
+ visitor->Trace(device_);
visitor->Trace(pending_devices_resolver_);
ContextLifecycleObserver::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.h
index 4c6efa8c063..fc3dc56ab09 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr.h
@@ -36,10 +36,8 @@ class XR final : public EventTargetWithInlineData,
ScriptPromise requestDevice(ScriptState*);
- // XRServiceClient overrides.
- void OnDisplayConnected(device::mojom::blink::VRDisplayHostPtr,
- device::mojom::blink::VRDisplayClientRequest,
- device::mojom::blink::VRDisplayInfoPtr) override;
+ // VRServiceClient overrides.
+ void OnDeviceChanged() override;
// EventTarget overrides.
ExecutionContext* GetExecutionContext() const override;
@@ -58,11 +56,16 @@ class XR final : public EventTargetWithInlineData,
private:
explicit XR(LocalFrame& frame, int64_t ukm_source_id_);
- void OnDevicesSynced();
+ void OnRequestDeviceReturned(device::mojom::blink::XRDevicePtr device);
void ResolveRequestDevice();
+ void ReportImmersiveSupported(bool supported);
+
+ void AddedEventListener(const AtomicString& event_type,
+ RegisteredEventListener&) override;
+
void Dispose();
- bool devices_synced_;
+ bool pending_sync_ = false;
// Indicates whether use of requestDevice has already been logged.
bool did_log_requestDevice_ = false;
@@ -70,7 +73,7 @@ class XR final : public EventTargetWithInlineData,
bool did_log_supports_immersive_ = false;
const int64_t ukm_source_id_;
- HeapVector<Member<XRDevice>> devices_;
+ Member<XRDevice> device_;
Member<ScriptPromiseResolver> pending_devices_resolver_;
device::mojom::blink::VRServicePtr service_;
mojo::Binding<device::mojom::blink::VRServiceClient> binding_;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr.idl b/chromium/third_party/blink/renderer/modules/xr/xr.idl
index e17562fc7d1..de578ac5324 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr.idl
@@ -5,8 +5,9 @@
// https://immersive-web.github.io/webxr/#xr-interface
[
SecureContext,
+ Exposed=Window,
OriginTrialEnabled=WebXR
] interface XR : EventTarget {
attribute EventHandler ondevicechange;
- [CallWith=ScriptState, MeasureAs=XRRequestDevice] Promise requestDevice();
+ [CallWith=ScriptState, MeasureAs=XRRequestDevice] Promise<XRDevice?> requestDevice();
};
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 91b22ee9e7c..93f341e1af0 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
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/modules/xr/xr_canvas_input_provider.h"
+#include "third_party/blink/renderer/core/dom/events/event_listener.h"
#include "third_party/blink/renderer/core/events/mouse_event.h"
#include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h"
#include "third_party/blink/renderer/modules/xr/xr_device.h"
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_coordinate_system.idl b/chromium/third_party/blink/renderer/modules/xr/xr_coordinate_system.idl
index 3bb482b8a39..42e5a9b1029 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_coordinate_system.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_coordinate_system.idl
@@ -5,6 +5,7 @@
// https://immersive-web.github.io/webxr/#xrcoordinatesystem-interface
[
SecureContext,
+ Exposed=Window,
OriginTrialEnabled=WebXR
] interface XRCoordinateSystem {
Float32Array? getTransformTo(XRCoordinateSystem other);
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_device.cc b/chromium/third_party/blink/renderer/modules/xr/xr_device.cc
index 7925e0210b3..92cd3cb2d44 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_device.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_device.cc
@@ -13,6 +13,7 @@
#include "third_party/blink/renderer/modules/event_target_modules.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_presentation_context.h"
#include "third_party/blink/renderer/modules/xr/xr_session.h"
namespace blink {
@@ -22,9 +23,6 @@ namespace {
const char kActiveImmersiveSession[] =
"XRDevice already has an active, immersive session";
-const char kImmersiveNotSupported[] =
- "XRDevice does not support the creation of immersive sessions.";
-
const char kNoOutputContext[] =
"Non-immersive sessions must be created with an outputContext.";
@@ -34,20 +32,10 @@ const char kRequestRequiresUserActivation[] =
const char kSessionNotSupported[] =
"The specified session configuration is not supported.";
-const char kRequestFailed[] = "Request for XRSession failed.";
-
} // namespace
-XRDevice::XRDevice(
- XR* xr,
- device::mojom::blink::VRDisplayHostPtr display,
- device::mojom::blink::VRDisplayClientRequest client_request,
- device::mojom::blink::VRDisplayInfoPtr display_info)
- : xr_(xr),
- display_(std::move(display)),
- display_client_binding_(this, std::move(client_request)) {
- SetXRDisplayInfo(std::move(display_info));
-}
+XRDevice::XRDevice(XR* xr, device::mojom::blink::XRDevicePtr device)
+ : xr_(xr), device_ptr_(std::move(device)) {}
const char* XRDevice::checkSessionSupport(
const XRSessionCreationOptions& options) const {
@@ -59,14 +47,6 @@ const char* XRDevice::checkSessionSupport(
}
}
- if (options.environmentIntegration() && !supports_ar_) {
- return kSessionNotSupported;
- }
-
- if (options.immersive() && !supports_immersive_) {
- return kSessionNotSupported;
- }
-
return nullptr;
}
@@ -76,7 +56,7 @@ ScriptPromise XRDevice::supportsSession(
// Check to see if the device is capable of supporting the requested session
// options. Note that reporting support here does not guarantee that creating
// a session with those options will succeed, as other external and
- // time-sensitve factors (focus state, existance of another immersive session,
+ // time-sensitve factors (focus state, existence of another immersive session,
// etc.) may prevent the creation of a session as well.
const char* reject_reason = checkSessionSupport(options);
if (reject_reason) {
@@ -94,7 +74,7 @@ ScriptPromise XRDevice::supportsSession(
device::mojom::blink::XRSessionOptions::New();
session_options->immersive = options.immersive();
- display_->SupportsSession(
+ device_ptr_->SupportsSession(
std::move(session_options),
WTF::Bind(&XRDevice::OnSupportsSessionReturned, WrapPersistent(this),
WrapPersistent(resolver)));
@@ -104,13 +84,10 @@ ScriptPromise XRDevice::supportsSession(
void XRDevice::OnSupportsSessionReturned(ScriptPromiseResolver* resolver,
bool supports_session) {
- // kImmersiveNotSupported is currently the only reason that SupportsSession
- // rejects on the browser side. That or there are no devices, but that should
- // technically not be possible.
supports_session
? resolver->Resolve()
: resolver->Reject(DOMException::Create(
- DOMExceptionCode::kNotSupportedError, kImmersiveNotSupported));
+ DOMExceptionCode::kNotSupportedError, kSessionNotSupported));
}
int64_t XRDevice::GetSourceId() const {
@@ -178,48 +155,54 @@ ScriptPromise XRDevice::requestSession(
options.environmentIntegration();
session_options->has_user_activation = has_user_activation;
- // TODO(offenwanger): Once device activation is sorted out for WebXR, either
- // pass in the value for metrics, or remove the value as soon as legacy API
- // has been removed.
- display_->RequestSession(
+ XRPresentationContext* output_context =
+ options.hasOutputContext() ? options.outputContext() : nullptr;
+
+ // TODO(http://crbug.com/826899) Once device activation is sorted out for
+ // WebXR, either pass in the correct value for metrics to know whether
+ // this was triggered by device activation, or remove the value as soon as
+ // legacy API has been removed.
+ device_ptr_->RequestSession(
std::move(session_options), false /* triggered by display activate */,
WTF::Bind(&XRDevice::OnRequestSessionReturned, WrapWeakPersistent(this),
- WrapPersistent(resolver), options));
+ WrapPersistent(resolver), WrapPersistent(output_context),
+ options.environmentIntegration(), options.immersive()));
return promise;
}
void XRDevice::OnRequestSessionReturned(
ScriptPromiseResolver* resolver,
- const XRSessionCreationOptions& options,
+ XRPresentationContext* output_context,
+ bool environment_integration,
+ bool immersive,
device::mojom::blink::XRSessionPtr session_ptr) {
+ // TODO(https://crbug.com/872316) Improve the error messaging to indicate why
+ // a request failed.
if (!session_ptr) {
DOMException* exception = DOMException::Create(
- DOMExceptionCode::kNotAllowedError, kRequestFailed);
+ DOMExceptionCode::kNotSupportedError, kSessionNotSupported);
resolver->Reject(exception);
return;
}
- if (session_ptr->magic_window_provider)
- magic_window_provider_.Bind(std::move(session_ptr->magic_window_provider));
-
- XRPresentationContext* output_context = nullptr;
- if (options.hasOutputContext()) {
- output_context = options.outputContext();
- }
-
XRSession::EnvironmentBlendMode blend_mode = XRSession::kBlendModeOpaque;
- if (options.environmentIntegration()) {
+ if (environment_integration)
blend_mode = XRSession::kBlendModeAlphaBlend;
- }
XRSession* session =
- new XRSession(this, options.immersive(), options.environmentIntegration(),
- output_context, blend_mode);
+ new XRSession(this, std::move(session_ptr->client_request), immersive,
+ environment_integration, output_context, blend_mode);
+ // immersive sessions must supply display info.
+ DCHECK(!immersive || session_ptr->display_info);
+ if (session_ptr->display_info)
+ session->SetXRDisplayInfo(std::move(session_ptr->display_info));
sessions_.insert(session);
- if (options.immersive()) {
- frameProvider()->BeginImmersiveSession(session,
- std::move(session_ptr->connection));
+ if (immersive) {
+ frameProvider()->BeginImmersiveSession(session, std::move(session_ptr));
+ } else {
+ magic_window_provider_.Bind(std::move(session_ptr->data_provider));
+ environment_provider_.Bind(std::move(session_ptr->environment_provider));
}
resolver->Resolve(session);
@@ -243,26 +226,6 @@ bool XRDevice::IsFrameFocused() {
return xr_->IsFrameFocused();
}
-// TODO: Forward these calls on to the sessions once they've been implemented.
-void XRDevice::OnChanged(device::mojom::blink::VRDisplayInfoPtr display_info) {
- SetXRDisplayInfo(std::move(display_info));
-}
-void XRDevice::OnExitPresent() {}
-void XRDevice::OnBlur() {
- // The device is reporting to us that it is blurred. This could happen for a
- // variety of reasons, such as browser UI, a different application using the
- // headset, or another page entering an immersive session.
- has_device_focus_ = false;
- OnFocusChanged();
-}
-void XRDevice::OnFocus() {
- has_device_focus_ = true;
- OnFocusChanged();
-}
-void XRDevice::OnActivate(device::mojom::blink::VRDisplayEventReason,
- OnActivateCallback on_handled) {}
-void XRDevice::OnDeactivate(device::mojom::blink::VRDisplayEventReason) {}
-
XRFrameProvider* XRDevice::frameProvider() {
if (!frame_provider_) {
frame_provider_ = new XRFrameProvider(this);
@@ -272,20 +235,10 @@ XRFrameProvider* XRDevice::frameProvider() {
}
void XRDevice::Dispose() {
- display_client_binding_.Close();
if (frame_provider_)
frame_provider_->Dispose();
}
-void XRDevice::SetXRDisplayInfo(
- device::mojom::blink::VRDisplayInfoPtr display_info) {
- display_info_id_++;
- display_info_ = std::move(display_info);
- is_external_ = display_info_->capabilities->hasExternalDisplay;
- supports_immersive_ = (display_info_->capabilities->canPresent);
- supports_ar_ = display_info_->capabilities->can_provide_pass_through_images;
-}
-
void XRDevice::Trace(blink::Visitor* visitor) {
visitor->Trace(xr_);
visitor->Trace(frame_provider_);
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_device.h b/chromium/third_party/blink/renderer/modules/xr/xr_device.h
index f4db8e216aa..83e27506412 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_device.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_device.h
@@ -22,69 +22,46 @@ class XR;
class XRFrameProvider;
class XRSession;
-class XRDevice final : public ScriptWrappable,
- public device::mojom::blink::VRDisplayClient {
+class XRDevice final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
- XRDevice(XR*,
- device::mojom::blink::VRDisplayHostPtr,
- device::mojom::blink::VRDisplayClientRequest,
- device::mojom::blink::VRDisplayInfoPtr);
+ XRDevice(XR*, device::mojom::blink::XRDevicePtr);
XR* xr() const { return xr_; }
- bool external() const { return is_external_; }
-
ScriptPromise supportsSession(ScriptState*, const XRSessionCreationOptions&);
ScriptPromise requestSession(ScriptState*, const XRSessionCreationOptions&);
- // XRDisplayClient
- void OnChanged(device::mojom::blink::VRDisplayInfoPtr) override;
- void OnExitPresent() override;
- void OnBlur() override;
- void OnFocus() override;
- void OnActivate(device::mojom::blink::VRDisplayEventReason,
- OnActivateCallback on_handled) override;
- void OnDeactivate(device::mojom::blink::VRDisplayEventReason) override;
-
XRFrameProvider* frameProvider();
void Dispose();
- const device::mojom::blink::VRDisplayHostPtr& xrDisplayHostPtr() const {
- return display_;
+ const device::mojom::blink::XRDevicePtr& xrDevicePtr() const {
+ return device_ptr_;
}
- const device::mojom::blink::VRMagicWindowProviderPtr&
- xrMagicWindowProviderPtr() const {
+ const device::mojom::blink::XRFrameDataProviderPtr& xrMagicWindowProviderPtr()
+ const {
return magic_window_provider_;
}
- const device::mojom::blink::VRDisplayInfoPtr& xrDisplayInfoPtr() const {
- return display_info_;
+ const device::mojom::blink::XREnvironmentIntegrationProviderPtr&
+ xrEnvironmentProviderPtr() const {
+ return environment_provider_;
}
- // Incremented every time display_info_ is changed, so that other objects that
- // depend on it can know when they need to update.
- unsigned int xrDisplayInfoPtrId() const { return display_info_id_; }
void OnFrameFocusChanged();
- // The device may report focus to us - for example if another application is
- // using the headset, or some browsing UI is shown, we may not have device
- // focus.
- bool HasDeviceFocus() { return has_device_focus_; }
- bool HasDeviceAndFrameFocus() { return IsFrameFocused() && HasDeviceFocus(); }
-
- bool SupportsImmersive() { return supports_immersive_; }
+ bool HasFrameFocus() { return IsFrameFocused(); }
int64_t GetSourceId() const;
void Trace(blink::Visitor*) override;
private:
- void SetXRDisplayInfo(device::mojom::blink::VRDisplayInfoPtr);
-
const char* checkSessionSupport(const XRSessionCreationOptions&) const;
void OnRequestSessionReturned(ScriptPromiseResolver* resolver,
- const XRSessionCreationOptions& options,
+ XRPresentationContext* output_context,
+ bool environment_integration,
+ bool immersive,
device::mojom::blink::XRSessionPtr session);
void OnSupportsSessionReturned(ScriptPromiseResolver* resolver,
bool supports_session);
@@ -99,20 +76,14 @@ class XRDevice final : public ScriptWrappable,
Member<XR> xr_;
Member<XRFrameProvider> frame_provider_;
HeapHashSet<WeakMember<XRSession>> sessions_;
- bool is_external_ = false;
- bool supports_immersive_ = false;
- bool supports_ar_ = false;
- bool has_device_focus_ = true;
// Indicates whether we've already logged a request for an immersive session.
bool did_log_request_immersive_session_ = false;
- device::mojom::blink::VRMagicWindowProviderPtr magic_window_provider_;
- device::mojom::blink::VRDisplayHostPtr display_;
- device::mojom::blink::VRDisplayInfoPtr display_info_;
- unsigned int display_info_id_ = 0;
-
- mojo::Binding<device::mojom::blink::VRDisplayClient> display_client_binding_;
+ device::mojom::blink::XRFrameDataProviderPtr magic_window_provider_;
+ device::mojom::blink::XREnvironmentIntegrationProviderPtr
+ environment_provider_;
+ device::mojom::blink::XRDevicePtr device_ptr_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_device.idl b/chromium/third_party/blink/renderer/modules/xr/xr_device.idl
index 30e102b5e07..5d5a879f95f 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_device.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_device.idl
@@ -5,8 +5,9 @@
// https://immersive-web.github.io/webxr/#xrdevice-interface
[
SecureContext,
+ Exposed=Window,
OriginTrialEnabled=WebXR
] interface XRDevice {
- [CallWith=ScriptState, MeasureAs=XRSupportsSession] Promise supportsSession([PermissiveDictionaryConversion] optional XRSessionCreationOptions options);
- [CallWith=ScriptState, MeasureAs=XRRequestSession] Promise requestSession([PermissiveDictionaryConversion] optional XRSessionCreationOptions options);
+ [CallWith=ScriptState, MeasureAs=XRSupportsSession] Promise<void> supportsSession([PermissiveDictionaryConversion] optional XRSessionCreationOptions options);
+ [CallWith=ScriptState, MeasureAs=XRRequestSession] Promise<XRSession> requestSession([PermissiveDictionaryConversion] optional XRSessionCreationOptions options);
};
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_device_pose.cc b/chromium/third_party/blink/renderer/modules/xr/xr_device_pose.cc
index 10e154755e6..1942968a5e3 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_device_pose.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_device_pose.cc
@@ -18,7 +18,7 @@ XRDevicePose::XRDevicePose(
DOMFloat32Array* XRDevicePose::poseModelMatrix() const {
if (!pose_model_matrix_)
return nullptr;
- return transformationMatrixToFloat32Array(*pose_model_matrix_);
+ return transformationMatrixToDOMFloat32Array(*pose_model_matrix_);
}
DOMFloat32Array* XRDevicePose::getViewMatrix(XRView* view) {
@@ -36,7 +36,7 @@ DOMFloat32Array* XRDevicePose::getViewMatrix(XRView* view) {
view_matrix.PostTranslate3d(-view_offset.X(), -view_offset.Y(),
-view_offset.Z());
- return transformationMatrixToFloat32Array(view_matrix);
+ return transformationMatrixToDOMFloat32Array(view_matrix);
}
void XRDevicePose::Trace(blink::Visitor* visitor) {
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_device_pose.idl b/chromium/third_party/blink/renderer/modules/xr/xr_device_pose.idl
index 8b7053ce561..f71be26d9ef 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_device_pose.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_device_pose.idl
@@ -5,6 +5,7 @@
// https://immersive-web.github.io/webxr/#xrdevicepose-interface
[
SecureContext,
+ Exposed=Window,
OriginTrialEnabled=WebXR
] interface XRDevicePose {
readonly attribute Float32Array poseModelMatrix;
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 bfa5a79ce9d..5b3a9df3fbd 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_frame.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_frame.idl
@@ -5,6 +5,7 @@
// https://immersive-web.github.io/webxr/#xrframe
[
SecureContext,
+ Exposed=Window,
OriginTrialEnabled=WebXR
] interface XRFrame {
readonly attribute XRSession session;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_frame_of_reference.cc b/chromium/third_party/blink/renderer/modules/xr/xr_frame_of_reference.cc
index d58997d19ba..5c29f5d3d17 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_frame_of_reference.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_frame_of_reference.cc
@@ -31,9 +31,9 @@ void XRFrameOfReference::UpdateStageBounds(XRStageBounds* bounds) {
void XRFrameOfReference::UpdateStageTransform() {
const device::mojom::blink::VRDisplayInfoPtr& display_info =
- session()->device()->xrDisplayInfoPtr();
+ session()->GetVRDisplayInfo();
- if (display_info->stageParameters) {
+ if (display_info && display_info->stageParameters) {
// Use the transform given by xrDisplayInfo's stageParamters if available.
const WTF::Vector<float>& m =
display_info->stageParameters->standingTransform;
@@ -52,7 +52,7 @@ void XRFrameOfReference::UpdateStageTransform() {
pose_transform_.reset();
}
- display_info_id_ = session()->device()->xrDisplayInfoPtrId();
+ display_info_id_ = session()->DisplayInfoPtrId();
}
// Enables emulated height when using a stage frame of reference, which should
@@ -97,7 +97,7 @@ std::unique_ptr<TransformationMatrix> XRFrameOfReference::TransformBasePose(
case kTypeStage:
// Check first to see if the xrDisplayInfo has updated since the last
// call. If so, update the pose transform.
- if (display_info_id_ != session()->device()->xrDisplayInfoPtrId())
+ if (display_info_id_ != session()->DisplayInfoPtrId())
UpdateStageTransform();
// If the stage has a transform apply it to the base pose and return that,
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_frame_of_reference.idl b/chromium/third_party/blink/renderer/modules/xr/xr_frame_of_reference.idl
index e5e797d6769..b1b3856f596 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_frame_of_reference.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_frame_of_reference.idl
@@ -12,6 +12,7 @@ enum XRFrameOfReferenceType {
[
SecureContext,
+ Exposed=Window,
OriginTrialEnabled=WebXR
] interface XRFrameOfReference : XRCoordinateSystem {
readonly attribute XRStageBounds? bounds;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_frame_of_reference_options.idl b/chromium/third_party/blink/renderer/modules/xr/xr_frame_of_reference_options.idl
index a480e8fecc9..cdc2f098d12 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_frame_of_reference_options.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_frame_of_reference_options.idl
@@ -3,9 +3,7 @@
// found in the LICENSE file.
// https://immersive-web.github.io/webxr/#xrframeofreference-interface
-[
- SecureContext
-] dictionary XRFrameOfReferenceOptions {
+dictionary XRFrameOfReferenceOptions {
boolean disableStageEmulation = false;
double stageEmulationHeight = 0.0;
};
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 8a5a4e9b791..b985bd429f0 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
@@ -86,36 +86,40 @@ std::unique_ptr<TransformationMatrix> getPoseMatrix(
} // namespace
XRFrameProvider::XRFrameProvider(XRDevice* device)
- : device_(device), last_has_focus_(device->HasDeviceAndFrameFocus()) {
+ : device_(device), last_has_focus_(device->HasFrameFocus()) {
frame_transport_ = new XRFrameTransport();
}
void XRFrameProvider::BeginImmersiveSession(
XRSession* session,
- device::mojom::blink::XRPresentationConnectionPtr connection) {
+ device::mojom::blink::XRSessionPtr session_ptr) {
// Make sure the session is indeed an immersive one.
DCHECK(session && session->immersive());
// Ensure we can only have one immersive session at a time.
DCHECK(!immersive_session_);
- DCHECK(connection);
+ DCHECK(session_ptr->data_provider);
+ DCHECK(session_ptr->submit_frame_sink);
immersive_session_ = session;
- presentation_provider_.Bind(std::move(connection->provider));
+ immersive_data_provider_.Bind(std::move(session_ptr->data_provider));
+
+ presentation_provider_.Bind(
+ std::move(session_ptr->submit_frame_sink->provider));
presentation_provider_.set_connection_error_handler(
WTF::Bind(&XRFrameProvider::OnPresentationProviderConnectionError,
WrapWeakPersistent(this)));
frame_transport_->BindSubmitFrameClient(
- std::move(connection->client_request));
+ std::move(session_ptr->submit_frame_sink->client_request));
frame_transport_->SetTransportOptions(
- std::move(connection->transport_options));
+ std::move(session_ptr->submit_frame_sink->transport_options));
frame_transport_->PresentChange();
}
void XRFrameProvider::OnFocusChanged() {
- bool focus = device_->HasDeviceAndFrameFocus();
+ bool focus = device_->HasFrameFocus();
// If we are gaining focus, schedule a frame for magic window. This accounts
// for skipping RAFs in ProcessScheduledFrame. Only do this when there are
@@ -131,6 +135,7 @@ void XRFrameProvider::OnFocusChanged() {
void XRFrameProvider::OnPresentationProviderConnectionError() {
presentation_provider_.reset();
+ immersive_data_provider_.reset();
if (vsync_connection_failed_)
return;
immersive_session_->ForceEnd();
@@ -142,15 +147,13 @@ void XRFrameProvider::OnImmersiveSessionEnded() {
if (!immersive_session_)
return;
- device_->xrDisplayHostPtr()->ExitPresent();
+ device_->xrDevicePtr()->ExitPresent();
immersive_session_ = nullptr;
pending_immersive_vsync_ = false;
frame_id_ = -1;
-
- if (presentation_provider_.is_bound()) {
- presentation_provider_.reset();
- }
+ presentation_provider_.reset();
+ immersive_data_provider_.reset();
frame_transport_ = new XRFrameTransport();
@@ -200,7 +203,7 @@ void XRFrameProvider::ScheduleImmersiveFrame() {
pending_immersive_vsync_ = true;
- presentation_provider_->GetFrameData(WTF::Bind(
+ immersive_data_provider_->GetFrameData(WTF::Bind(
&XRFrameProvider::OnImmersiveFrameData, WrapWeakPersistent(this)));
}
@@ -352,7 +355,7 @@ void XRFrameProvider::ProcessScheduledFrame(
TRACE_EVENT2("gpu", "XRFrameProvider::ProcessScheduledFrame", "frame",
frame_id_, "timestamp", high_res_now_ms);
- if (!device_->HasDeviceAndFrameFocus() && !immersive_session_) {
+ if (!device_->HasFrameFocus() && !immersive_session_) {
return; // Not currently focused, so we won't expose poses (except to
// immersive sessions).
}
@@ -380,10 +383,15 @@ void XRFrameProvider::ProcessScheduledFrame(
// If there's an immersive session active only process its frame.
std::unique_ptr<TransformationMatrix> pose_matrix =
getPoseMatrix(frame_pose_);
+#if DCHECK_IS_ON()
// Sanity check: if drawing into a shared buffer, the optional mailbox
- // holder must be present.
- DCHECK(!frame_transport_->DrawingIntoSharedBuffer() ||
- buffer_mailbox_holder_);
+ // holder must be present. Exception is the first immersive frame after a
+ // transition where the frame ID wasn't set yet. In that case, drawing can
+ // proceed, but the result will be discarded in SubmitWebGLLayer().
+ if (frame_transport_->DrawingIntoSharedBuffer() && frame_id_ >= 0) {
+ DCHECK(buffer_mailbox_holder_);
+ }
+#endif
immersive_session_->OnFrame(high_res_now_ms, std::move(pose_matrix),
buffer_mailbox_holder_, base::nullopt,
base::nullopt);
@@ -391,12 +399,12 @@ void XRFrameProvider::ProcessScheduledFrame(
// 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
// from the requests to prevent infinite loops.
- HeapVector<Member<XRSession>> processing_sessions;
- swap(requesting_sessions_, processing_sessions);
+ DCHECK(processing_sessions_.IsEmpty());
+ swap(requesting_sessions_, processing_sessions_);
// Inform sessions with a pending request of the new frame
- for (unsigned i = 0; i < processing_sessions.size(); ++i) {
- XRSession* session = processing_sessions.at(i).Get();
+ for (unsigned i = 0; i < processing_sessions_.size(); ++i) {
+ XRSession* session = processing_sessions_.at(i).Get();
if (frame_pose_ && frame_pose_->input_state.has_value()) {
session->OnInputStateChange(frame_id_,
@@ -424,6 +432,8 @@ void XRFrameProvider::ProcessScheduledFrame(
base::nullopt, base::nullopt);
}
}
+
+ processing_sessions_.clear();
}
}
@@ -487,7 +497,7 @@ void XRFrameProvider::SubmitWebGLLayer(XRWebGLLayer* layer, bool was_changed) {
// TODO(bajones): Remove this when the Windows path has been updated to no
// longer require a texture copy.
- bool needs_copy = device_->external();
+ bool needs_copy = immersive_session_->External();
frame_transport_->FrameSubmit(
presentation_provider_.get(), webgl_context->ContextGL(), webgl_context,
@@ -527,6 +537,7 @@ void XRFrameProvider::UpdateWebGLLayerViewports(XRWebGLLayer* layer) {
void XRFrameProvider::Dispose() {
presentation_provider_.reset();
+ immersive_data_provider_.reset();
// TODO(bajones): Do something for outstanding frame requests?
}
@@ -535,6 +546,7 @@ void XRFrameProvider::Trace(blink::Visitor* visitor) {
visitor->Trace(frame_transport_);
visitor->Trace(immersive_session_);
visitor->Trace(requesting_sessions_);
+ visitor->Trace(processing_sessions_);
}
} // namespace blink
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 159a4d55c17..945283df416 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
@@ -27,11 +27,10 @@ class XRFrameProvider final
explicit XRFrameProvider(XRDevice*);
XRSession* immersive_session() const { return immersive_session_; }
- device::mojom::blink::VRSubmitFrameClientPtr GetSubmitFrameClient();
+ device::mojom::blink::XRPresentationClientPtr GetSubmitFrameClient();
- void BeginImmersiveSession(
- XRSession* session,
- device::mojom::blink::XRPresentationConnectionPtr connection);
+ void BeginImmersiveSession(XRSession* session,
+ device::mojom::blink::XRSessionPtr session_ptr);
void OnImmersiveSessionEnded();
void RequestFrame(XRSession*);
@@ -65,9 +64,10 @@ class XRFrameProvider final
// Non-immersive Sessions which have requested a frame update.
HeapVector<Member<XRSession>> requesting_sessions_;
+ HeapVector<Member<XRSession>> processing_sessions_;
- device::mojom::blink::VRPresentationProviderPtr presentation_provider_;
- device::mojom::blink::VRMagicWindowProviderPtr magic_window_provider_;
+ device::mojom::blink::XRPresentationProviderPtr presentation_provider_;
+ device::mojom::blink::XRFrameDataProviderPtr immersive_data_provider_;
device::mojom::blink::VRPosePtr frame_pose_;
// 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 0de1f348c74..8f799cdfacf 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
@@ -30,6 +30,7 @@ XRFrameRequestCallbackCollection::RegisterCallback(
void XRFrameRequestCallbackCollection::CancelCallback(CallbackId id) {
if (IsValidCallbackId(id)) {
callbacks_.erase(id);
+ current_callbacks_.erase(id);
}
}
@@ -38,26 +39,36 @@ void XRFrameRequestCallbackCollection::ExecuteCallbacks(XRSession* session,
XRFrame* frame) {
// First, generate a list of callbacks to consider. Callbacks registered from
// this point on are considered only for the "next" frame, not this one.
- DCHECK(callbacks_to_invoke_.IsEmpty());
- callbacks_to_invoke_.swap(pending_callbacks_);
- for (const auto& id : callbacks_to_invoke_) {
- V8XRFrameRequestCallback* callback = callbacks_.Take(id);
+ // Conceptually we are just going to iterate through current_callbacks_, and
+ // call each callback. However, if we had multiple callbacks, subsequent ones
+ // could be removed while we are iterating. HeapHashMap iterators aren't
+ // valid after collection modifications, so we also store a corresponding set
+ // of ids for iteration purposes. current_callback_ids is the set of ids for
+ // callbacks we will call, and is kept in sync with current_callbacks_ but
+ // safe to iterate over.
+ DCHECK(current_callbacks_.IsEmpty());
+ current_callbacks_.swap(callbacks_);
- // Callback won't be found if it was cancelled.
- if (!callback)
+ Vector<CallbackId> current_callback_ids;
+ current_callback_ids.swap(pending_callbacks_);
+
+ for (const auto& id : current_callback_ids) {
+ auto it = current_callbacks_.find(id);
+ if (it == current_callbacks_.end())
continue;
- probe::AsyncTask async_task(context_, callback);
+ probe::AsyncTask async_task(context_, it->value);
probe::UserCallback probe(context_, "XRRequestFrame", AtomicString(), true);
- callback->InvokeAndReportException(session, timestamp, frame);
+ it->value->InvokeAndReportException(session, timestamp, frame);
}
- callbacks_to_invoke_.clear();
+ current_callbacks_.clear();
}
void XRFrameRequestCallbackCollection::Trace(blink::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 28b79e93f15..28ff06d4a61 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
@@ -45,8 +45,9 @@ class XRFrameRequestCallbackCollection final
HeapHashMap<CallbackId, TraceWrapperMember<V8XRFrameRequestCallback>>;
CallbackMap callbacks_;
Vector<CallbackId> pending_callbacks_;
+
// Only non-empty while inside executeCallbacks.
- Vector<CallbackId> callbacks_to_invoke_;
+ CallbackMap current_callbacks_;
CallbackId next_callback_id_ = 0;
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
index 004c50aa759..07b93496df8 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_hit_result.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_hit_result.cc
@@ -16,10 +16,7 @@ XRHitResult::~XRHitResult() {}
DOMFloat32Array* XRHitResult::hitMatrix() const {
if (!hit_transform_)
return nullptr;
- // TODO(https://crbug.com/845296): rename
- // transformationMatrixToFloat32Array() to
- // TransformationMatrixToDOMFloat32Array().
- return transformationMatrixToFloat32Array(*hit_transform_);
+ return transformationMatrixToDOMFloat32Array(*hit_transform_);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_input_pose.cc b/chromium/third_party/blink/renderer/modules/xr/xr_input_pose.cc
index 8057426f241..5b7ce8560c9 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_input_pose.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_input_pose.cc
@@ -20,7 +20,7 @@ XRInputPose::~XRInputPose() {}
DOMFloat32Array* XRInputPose::gripMatrix() const {
if (!grip_matrix_)
return nullptr;
- return transformationMatrixToFloat32Array(*grip_matrix_);
+ return transformationMatrixToDOMFloat32Array(*grip_matrix_);
}
void XRInputPose::Trace(blink::Visitor* visitor) {
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_input_pose.idl b/chromium/third_party/blink/renderer/modules/xr/xr_input_pose.idl
index 377ee58a76d..0359c6a5fc1 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_input_pose.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_input_pose.idl
@@ -4,9 +4,10 @@
[
SecureContext,
+ Exposed=Window,
OriginTrialEnabled=WebXR
] interface XRInputPose {
readonly attribute XRRay targetRay;
readonly attribute Float32Array? gripMatrix;
readonly attribute boolean emulatedPosition;
-}; \ No newline at end of file
+};
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 f290e724bc3..bd3a7bff9ec 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
@@ -15,8 +15,9 @@ enum XRTargetRayMode {
[
SecureContext,
+ Exposed=Window,
OriginTrialEnabled=WebXR
] interface XRInputSource {
readonly attribute XRHandedness handedness;
readonly attribute XRTargetRayMode targetRayMode;
-}; \ No newline at end of file
+};
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 0c8fe9f30a8..1eb733bf5f1 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
@@ -4,6 +4,7 @@
[
SecureContext,
+ Exposed=Window,
OriginTrialEnabled=WebXR,
Constructor(DOMString type, XRInputSourceEventInit eventInitDict)
] interface XRInputSourceEvent : Event {
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_input_source_event_init.idl b/chromium/third_party/blink/renderer/modules/xr/xr_input_source_event_init.idl
index e5ca3ac255c..5600c66580d 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_input_source_event_init.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_input_source_event_init.idl
@@ -2,9 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-[
- SecureContext
-] dictionary XRInputSourceEventInit : EventInit {
+dictionary XRInputSourceEventInit : EventInit {
required XRFrame frame;
required XRInputSource inputSource;
-}; \ No newline at end of file
+};
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_layer.idl b/chromium/third_party/blink/renderer/modules/xr/xr_layer.idl
index 3b30353ffd3..26ceefed6f5 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_layer.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_layer.idl
@@ -5,5 +5,6 @@
// https://immersive-web.github.io/webxr/#xrlayer-interface
[
SecureContext,
+ Exposed=Window,
OriginTrialEnabled=WebXR
] interface XRLayer {};
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_presentation_context.idl b/chromium/third_party/blink/renderer/modules/xr/xr_presentation_context.idl
index 4f457b464ec..2ecd3164e04 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_presentation_context.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_presentation_context.idl
@@ -5,8 +5,9 @@
// https://immersive-web.github.io/webxr/#xrpresentationcontext-interface
[
SecureContext,
+ Exposed=Window,
OriginTrialEnabled=WebXR
] interface XRPresentationContext {
// back-reference to the canvas
readonly attribute HTMLCanvasElement canvas;
-}; \ No newline at end of file
+};
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 22ae3d40ed2..5189e5ddf43 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_ray.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_ray.cc
@@ -24,10 +24,7 @@ XRRay::~XRRay() {}
DOMFloat32Array* XRRay::transformMatrix() const {
if (!transform_matrix_)
return nullptr;
- // TODO(https://crbug.com/845296): rename
- // transformationMatrixToFloat32Array() to
- // TransformationMatrixToDOMFloat32Array().
- return transformationMatrixToFloat32Array(*transform_matrix_);
+ return transformationMatrixToDOMFloat32Array(*transform_matrix_);
}
void XRRay::Trace(blink::Visitor* visitor) {
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 b9ca32e318e..405451962a5 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_ray.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_ray.idl
@@ -3,8 +3,12 @@
// found in the LICENSE file.
// https://immersive-web.github.io/webxr/#xrray-interface
-[SecureContext, OriginTrialEnabled=WebXR] interface XRRay {
+[
+ SecureContext,
+ Exposed=Window,
+ OriginTrialEnabled=WebXR
+] interface XRRay {
readonly attribute DOMPointReadOnly origin;
readonly attribute DOMPointReadOnly direction;
readonly attribute Float32Array transformMatrix;
-}; \ No newline at end of file
+};
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 d838ef8bdba..08fdc3abdb5 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_session.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_session.cc
@@ -89,15 +89,18 @@ class XRSession::XRSessionResizeObserverDelegate final
Member<XRSession> session_;
};
-XRSession::XRSession(XRDevice* device,
- bool immersive,
- bool environment_integration,
- XRPresentationContext* output_context,
- EnvironmentBlendMode environment_blend_mode)
+XRSession::XRSession(
+ XRDevice* device,
+ device::mojom::blink::XRSessionClientRequest client_request,
+ bool immersive,
+ bool environment_integration,
+ XRPresentationContext* output_context,
+ EnvironmentBlendMode environment_blend_mode)
: device_(device),
immersive_(immersive),
environment_integration_(environment_integration),
output_context_(output_context),
+ client_binding_(this, std::move(client_request)),
callback_collection_(new XRFrameRequestCallbackCollection(
device->xr()->GetExecutionContext())) {
blurred_ = !HasAppropriateFocus();
@@ -198,7 +201,7 @@ ScriptPromise XRSession::requestFrameOfReference(
if (!options.disableStageEmulation()) {
frameOfRef = new XRFrameOfReference(this, XRFrameOfReference::kTypeStage);
frameOfRef->UseEmulatedHeight(options.stageEmulationHeight());
- } else if (device_->xrDisplayInfoPtr()->stageParameters) {
+ } else if (display_info_ && display_info_->stageParameters) {
frameOfRef = new XRFrameOfReference(this, XRFrameOfReference::kTypeStage);
} else {
return ScriptPromise::RejectWithDOMException(
@@ -296,23 +299,24 @@ ScriptPromise XRSession::requestHitTest(ScriptState* script_state,
// TODO(https://crbug.com/843376): Reject the promise if device doesn't
// support the hit-test API.
-
device::mojom::blink::XRRayPtr ray = device::mojom::blink::XRRay::New();
- ray->origin.resize(3);
- ray->origin[0] = origin.View()->Data()[0];
- ray->origin[1] = origin.View()->Data()[1];
- ray->origin[2] = origin.View()->Data()[2];
- ray->direction.resize(3);
- ray->direction[0] = direction.View()->Data()[0];
- ray->direction[1] = direction.View()->Data()[1];
- ray->direction[2] = direction.View()->Data()[2];
+
+ ray->origin = gfx::mojom::blink::Point3F::New();
+ ray->origin->x = origin.View()->Data()[0];
+ ray->origin->y = origin.View()->Data()[1];
+ ray->origin->z = origin.View()->Data()[2];
+
+ ray->direction = gfx::mojom::blink::Vector3dF::New();
+ ray->direction->x = direction.View()->Data()[0];
+ ray->direction->y = direction.View()->Data()[1];
+ ray->direction->z = direction.View()->Data()[2];
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
ScriptPromise promise = resolver->Promise();
// TODO(https://crbug.com/845520): Promise should be rejected if session
// is deleted.
- device_->xrMagicWindowProviderPtr()->RequestHitTest(
+ device_->xrEnvironmentProviderPtr()->RequestHitTest(
std::move(ray),
WTF::Bind(&XRSession::OnHitTestResults, WrapWeakPersistent(this),
WrapPersistent(resolver)));
@@ -380,12 +384,12 @@ void XRSession::ForceEnd() {
device_->frameProvider()->OnImmersiveSessionEnded();
}
- DispatchEvent(XRSessionEvent::Create(EventTypeNames::end, this));
+ DispatchEvent(*XRSessionEvent::Create(EventTypeNames::end, this));
}
double XRSession::NativeFramebufferScale() const {
if (immersive_) {
- double scale = device_->xrDisplayInfoPtr()->webxr_default_framebuffer_scale;
+ double scale = display_info_->webxr_default_framebuffer_scale;
DCHECK(scale);
// Return the inverse of the default scale, since that's what we'll need to
@@ -400,12 +404,12 @@ DoubleSize XRSession::DefaultFramebufferSize() const {
return OutputCanvasSize();
}
- double width = (device_->xrDisplayInfoPtr()->leftEye->renderWidth +
- device_->xrDisplayInfoPtr()->rightEye->renderWidth);
- double height = std::max(device_->xrDisplayInfoPtr()->leftEye->renderHeight,
- device_->xrDisplayInfoPtr()->rightEye->renderHeight);
+ double width = (display_info_->leftEye->renderWidth +
+ display_info_->rightEye->renderWidth);
+ double height = std::max(display_info_->leftEye->renderHeight,
+ display_info_->rightEye->renderHeight);
- double scale = device_->xrDisplayInfoPtr()->webxr_default_framebuffer_scale;
+ double scale = display_info_->webxr_default_framebuffer_scale;
return DoubleSize(width * scale, height * scale);
}
@@ -422,7 +426,7 @@ void XRSession::OnFocus() {
return;
blurred_ = false;
- DispatchEvent(XRSessionEvent::Create(EventTypeNames::focus, this));
+ DispatchEvent(*XRSessionEvent::Create(EventTypeNames::focus, this));
}
void XRSession::OnBlur() {
@@ -430,15 +434,15 @@ void XRSession::OnBlur() {
return;
blurred_ = true;
- DispatchEvent(XRSessionEvent::Create(EventTypeNames::blur, this));
+ DispatchEvent(*XRSessionEvent::Create(EventTypeNames::blur, this));
}
// Immersive sessions may still not be blurred in headset even if the page isn't
// focused. This prevents the in-headset experience from freezing on an
// external display headset when the user clicks on another tab.
bool XRSession::HasAppropriateFocus() {
- return immersive_ ? device_->HasDeviceFocus()
- : device_->HasDeviceAndFrameFocus();
+ return immersive_ ? has_device_focus_
+ : has_device_focus_ && device_->HasFrameFocus();
}
void XRSession::OnFocusChanged() {
@@ -550,8 +554,8 @@ void XRSession::UpdateCanvasDimensions(Element* element) {
DVLOG(2) << __FUNCTION__ << ": got angle=" << output_angle;
}
- if (device_->xrMagicWindowProviderPtr()) {
- device_->xrMagicWindowProviderPtr()->UpdateSessionGeometry(
+ if (device_->xrEnvironmentProviderPtr()) {
+ device_->xrEnvironmentProviderPtr()->UpdateSessionGeometry(
IntSize(output_width_, output_height_),
display::Display::DegreesToRotation(output_angle));
}
@@ -597,7 +601,7 @@ void XRSession::OnInputStateChange(
if (devices_changed) {
DispatchEvent(
- XRSessionEvent::Create(EventTypeNames::inputsourceschange, this));
+ *XRSessionEvent::Create(EventTypeNames::inputsourceschange, this));
}
}
@@ -611,7 +615,7 @@ void XRSession::OnSelectStart(XRInputSource* input_source) {
XRInputSourceEvent* event =
CreateInputSourceEvent(EventTypeNames::selectstart, input_source);
- DispatchEvent(event);
+ DispatchEvent(*event);
if (event->defaultPrevented())
input_source->selection_cancelled = true;
@@ -633,7 +637,7 @@ void XRSession::OnSelectEnd(XRInputSource* input_source) {
XRInputSourceEvent* event =
CreateInputSourceEvent(EventTypeNames::selectend, input_source);
- DispatchEvent(event);
+ DispatchEvent(*event);
if (event->defaultPrevented())
input_source->selection_cancelled = true;
@@ -653,12 +657,12 @@ void XRSession::OnSelect(XRInputSource* input_source) {
if (!input_source->selection_cancelled) {
XRInputSourceEvent* event =
CreateInputSourceEvent(EventTypeNames::select, input_source);
- DispatchEvent(event);
+ DispatchEvent(*event);
}
}
void XRSession::OnPoseReset() {
- DispatchEvent(XRSessionEvent::Create(EventTypeNames::resetpose, this));
+ DispatchEvent(*XRSessionEvent::Create(EventTypeNames::resetpose, this));
}
void XRSession::UpdateInputSourceState(
@@ -723,6 +727,24 @@ XRInputSourceEvent* XRSession::CreateInputSourceEvent(
return XRInputSourceEvent::Create(type, presentation_frame, input_source);
}
+void XRSession::OnChanged(device::mojom::blink::VRDisplayInfoPtr display_info) {
+ DCHECK(display_info);
+ SetXRDisplayInfo(std::move(display_info));
+}
+
+void XRSession::OnExitPresent() {
+ if (immersive_) {
+ ForceEnd();
+ }
+}
+
+void XRSession::SetXRDisplayInfo(
+ device::mojom::blink::VRDisplayInfoPtr display_info) {
+ display_info_id_++;
+ display_info_ = std::move(display_info);
+ is_external_ = display_info_->capabilities->hasExternalDisplay;
+}
+
const HeapVector<Member<XRView>>& XRSession::views() {
// TODO(bajones): For now we assume that immersive sessions render a stereo
// pair of views and non-immersive sessions render a single view. That doesn't
@@ -738,11 +760,11 @@ const HeapVector<Member<XRView>>& XRSession::views() {
// In immersive mode the projection and view matrices must be aligned with
// the device's physical optics.
UpdateViewFromEyeParameters(views_[XRView::kEyeLeft],
- device_->xrDisplayInfoPtr()->leftEye,
- depth_near_, depth_far_);
+ display_info_->leftEye, depth_near_,
+ depth_far_);
UpdateViewFromEyeParameters(views_[XRView::kEyeRight],
- device_->xrDisplayInfoPtr()->rightEye,
- depth_near_, depth_far_);
+ display_info_->rightEye, depth_near_,
+ depth_far_);
} else {
if (views_.IsEmpty()) {
views_.push_back(new XRView(this, XRView::kEyeLeft));
@@ -782,6 +804,10 @@ const HeapVector<Member<XRView>>& XRSession::views() {
return views_;
}
+bool XRSession::HasPendingActivity() const {
+ return !callback_collection_->IsEmpty() && !ended_;
+}
+
void XRSession::Trace(blink::Visitor* visitor) {
visitor->Trace(device_);
visitor->Trace(output_context_);
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 c71429ba1f8..293b9035134 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_session.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_session.h
@@ -19,6 +19,8 @@
#include "third_party/blink/renderer/platform/transforms/transformation_matrix.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
+#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
+
namespace blink {
class Element;
@@ -34,8 +36,11 @@ class XRLayer;
class XRPresentationContext;
class XRView;
-class XRSession final : public EventTargetWithInlineData {
+class XRSession final : public EventTargetWithInlineData,
+ public device::mojom::blink::XRSessionClient,
+ public ActiveScriptWrappable<XRSession> {
DEFINE_WRAPPERTYPEINFO();
+ USING_GARBAGE_COLLECTED_MIXIN(XRSession);
public:
enum EnvironmentBlendMode {
@@ -45,6 +50,7 @@ class XRSession final : public EventTargetWithInlineData {
};
XRSession(XRDevice*,
+ device::mojom::blink::XRSessionClientRequest client_request,
bool immersive,
bool environment_integration,
XRPresentationContext* output_context,
@@ -139,10 +145,22 @@ class XRSession final : public EventTargetWithInlineData {
void OnPoseReset();
+ const device::mojom::blink::VRDisplayInfoPtr& GetVRDisplayInfo() {
+ return display_info_;
+ }
+ bool External() const { return is_external_; }
+ // Incremented every time display_info_ is changed, so that other objects that
+ // depend on it can know when they need to update.
+ unsigned int DisplayInfoPtrId() const { return display_info_id_; }
+
void SetNonImmersiveProjectionMatrix(const WTF::Vector<float>&);
+ void SetXRDisplayInfo(device::mojom::blink::VRDisplayInfoPtr display_info);
void Trace(blink::Visitor*) override;
+ // ScriptWrappable
+ bool HasPendingActivity() const override;
+
private:
class XRSessionResizeObserverDelegate;
@@ -155,8 +173,12 @@ class XRSession final : public EventTargetWithInlineData {
XRInputSourceEvent* CreateInputSourceEvent(const AtomicString&,
XRInputSource*);
- void OnFocus();
- void OnBlur();
+ // XRSessionClient
+ void OnChanged(device::mojom::blink::VRDisplayInfoPtr) override;
+ void OnExitPresent() override;
+ void OnFocus() override;
+ void OnBlur() override;
+
bool HasAppropriateFocus();
void OnHitTestResults(
@@ -175,6 +197,13 @@ class XRSession final : public EventTargetWithInlineData {
Member<ResizeObserver> resize_observer_;
Member<XRCanvasInputProvider> canvas_input_provider_;
+ bool has_device_focus_ = true;
+ bool is_external_ = false;
+ int display_info_id_ = 0;
+ device::mojom::blink::VRDisplayInfoPtr display_info_;
+
+ mojo::Binding<device::mojom::blink::XRSessionClient> client_binding_;
+
TraceWrapperMember<XRFrameRequestCallbackCollection> callback_collection_;
std::unique_ptr<TransformationMatrix> base_pose_matrix_;
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 a34084b75e3..01b791d5df5 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_session.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_session.idl
@@ -10,7 +10,9 @@ enum XREnvironmentBlendMode {
};
[
+ ActiveScriptWrappable,
SecureContext,
+ Exposed=Window,
OriginTrialEnabled=WebXR
] interface XRSession : EventTarget {
readonly attribute XRDevice device;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_session_creation_options.idl b/chromium/third_party/blink/renderer/modules/xr/xr_session_creation_options.idl
index 60db82cc910..d66ce6fa69c 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_session_creation_options.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_session_creation_options.idl
@@ -3,9 +3,7 @@
// found in the LICENSE file.
// https://immersive-web.github.io/webxr/#xrsessioncreationoptions-interface
-[
- SecureContext
-] dictionary XRSessionCreationOptions {
+dictionary XRSessionCreationOptions {
[RuntimeEnabled=WebXRHitTest] boolean environmentIntegration = false;
boolean immersive = false;
XRPresentationContext outputContext;
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 1f5c66dee73..7bf08de61b0 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
@@ -5,8 +5,9 @@
// https://immersive-web.github.io/webxr/#xrsessionevent-interface
[
SecureContext,
+ Exposed=Window,
OriginTrialEnabled=WebXR,
Constructor(DOMString type, XRSessionEventInit eventInitDict)
] interface XRSessionEvent : Event {
readonly attribute XRSession session;
-}; \ No newline at end of file
+};
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_session_event_init.idl b/chromium/third_party/blink/renderer/modules/xr/xr_session_event_init.idl
index 9e8937a9d16..77afdce2314 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_session_event_init.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_session_event_init.idl
@@ -3,8 +3,6 @@
// found in the LICENSE file.
// https://immersive-web.github.io/webxr/#xrsessionevent-interface
-[
- SecureContext
-] dictionary XRSessionEventInit : EventInit {
+dictionary XRSessionEventInit : EventInit {
required XRSession session;
-}; \ No newline at end of file
+};
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_stage_bounds.h b/chromium/third_party/blink/renderer/modules/xr/xr_stage_bounds.h
index 9429fc170d6..77cf827accd 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_stage_bounds.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_stage_bounds.h
@@ -5,7 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_STAGE_BOUNDS_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_STAGE_BOUNDS_H_
-#include "third_party/blink/renderer/modules/xr/xr_stage_bounds_point.h"
+#include "third_party/blink/renderer/core/geometry/dom_point_read_only.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"
@@ -18,12 +18,12 @@ class XRStageBounds final : public ScriptWrappable {
public:
XRStageBounds() = default;
- HeapVector<Member<XRStageBoundsPoint>> geometry() const { return geometry_; }
+ HeapVector<Member<DOMPointReadOnly>> geometry() const { return geometry_; }
void Trace(blink::Visitor*) override;
private:
- HeapVector<Member<XRStageBoundsPoint>> geometry_;
+ HeapVector<Member<DOMPointReadOnly>> geometry_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_stage_bounds.idl b/chromium/third_party/blink/renderer/modules/xr/xr_stage_bounds.idl
index 7a83043d2f1..95e0fad2e80 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_stage_bounds.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_stage_bounds.idl
@@ -5,7 +5,8 @@
// https://immersive-web.github.io/webxr/#xrstagebounds-interface
[
SecureContext,
+ Exposed=Window,
OriginTrialEnabled=WebXR
] interface XRStageBounds {
- readonly attribute FrozenArray<XRStageBoundsPoint> geometry;
+ readonly attribute FrozenArray<DOMPointReadOnly> geometry;
};
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_stage_bounds_point.h b/chromium/third_party/blink/renderer/modules/xr/xr_stage_bounds_point.h
deleted file mode 100644
index a29055b11b4..00000000000
--- a/chromium/third_party/blink/renderer/modules/xr/xr_stage_bounds_point.h
+++ /dev/null
@@ -1,30 +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_XR_XR_STAGE_BOUNDS_POINT_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_STAGE_BOUNDS_POINT_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 XRStageBoundsPoint final : public ScriptWrappable {
- DEFINE_WRAPPERTYPEINFO();
-
- public:
- XRStageBoundsPoint(double x, double z) : x_(x), z_(z) {}
-
- double x() const { return x_; }
- double z() const { return z_; }
-
- private:
- double x_;
- double z_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_STAGE_BOUNDS_POINT_H_
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_stage_bounds_point.idl b/chromium/third_party/blink/renderer/modules/xr/xr_stage_bounds_point.idl
deleted file mode 100644
index c00acb11fe8..00000000000
--- a/chromium/third_party/blink/renderer/modules/xr/xr_stage_bounds_point.idl
+++ /dev/null
@@ -1,12 +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.
-
-// https://immersive-web.github.io/webxr/#xrstageboundspoint-interface
-[
- SecureContext,
- OriginTrialEnabled=WebXR
-] interface XRStageBoundsPoint {
- readonly attribute double x;
- readonly attribute double z;
-};
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_utils.cc b/chromium/third_party/blink/renderer/modules/xr/xr_utils.cc
index 34ef2243b7d..3b549c1abb2 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_utils.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_utils.cc
@@ -6,7 +6,7 @@
namespace blink {
-DOMFloat32Array* transformationMatrixToFloat32Array(
+DOMFloat32Array* transformationMatrixToDOMFloat32Array(
const TransformationMatrix& matrix) {
float array[] = {
static_cast<float>(matrix.M11()), static_cast<float>(matrix.M12()),
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_utils.h b/chromium/third_party/blink/renderer/modules/xr/xr_utils.h
index d484e5bc914..a90d05c9d63 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_utils.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_utils.h
@@ -10,7 +10,7 @@
namespace blink {
-DOMFloat32Array* transformationMatrixToFloat32Array(
+DOMFloat32Array* transformationMatrixToDOMFloat32Array(
const TransformationMatrix&);
} // namespace blink
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 2486ab6146f..875c5e5b590 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_view.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_view.cc
@@ -10,7 +10,7 @@
namespace blink {
-XRView::XRView(XRSession* session, Eye eye)
+XRView::XRView(XRSession* session, XREye eye)
: eye_(eye),
session_(session),
projection_matrix_(DOMFloat32Array::Create(16)) {
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 8554bdb93a4..dbdb1c5697e 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_view.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_view.h
@@ -21,12 +21,12 @@ class XRView final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
- enum Eye { kEyeLeft = 0, kEyeRight = 1 };
+ enum XREye { kEyeLeft = 0, kEyeRight = 1 };
- XRView(XRSession*, Eye);
+ XRView(XRSession*, XREye);
const String& eye() const { return eye_string_; }
- Eye EyeValue() const { return eye_; }
+ XREye EyeValue() const { return eye_; }
XRSession* session() const;
DOMFloat32Array* projectionMatrix() const { return projection_matrix_; }
@@ -60,7 +60,7 @@ class XRView final : public ScriptWrappable {
void Trace(blink::Visitor*) override;
private:
- const Eye eye_;
+ const XREye eye_;
String eye_string_;
Member<XRSession> session_;
Member<DOMFloat32Array> projection_matrix_;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_view.idl b/chromium/third_party/blink/renderer/modules/xr/xr_view.idl
index a4cb6a12f43..28f1436b60f 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_view.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_view.idl
@@ -3,10 +3,16 @@
// found in the LICENSE file.
// https://immersive-web.github.io/webxr/#xrview-interface
+enum XREye {
+ "left",
+ "right"
+};
+
[
SecureContext,
+ Exposed=Window,
OriginTrialEnabled=WebXR
] interface XRView {
- readonly attribute VREye? eye;
+ readonly attribute XREye eye;
readonly attribute Float32Array projectionMatrix;
};
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_viewport.idl b/chromium/third_party/blink/renderer/modules/xr/xr_viewport.idl
index 7888d5908d9..8c51f30f61b 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_viewport.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_viewport.idl
@@ -5,6 +5,7 @@
// https://immersive-web.github.io/webxr/#xrviewport-interface
[
SecureContext,
+ Exposed=Window,
OriginTrialEnabled=WebXR
] interface XRViewport {
readonly attribute long x;
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 0971d900225..be53fae2a05 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
@@ -126,8 +126,7 @@ XRWebGLLayer::XRWebGLLayer(XRSession* session,
framebuffer_scale_(framebuffer_scale) {
DCHECK(drawing_buffer_);
// If the contents need mirroring, indicate that to the drawing buffer.
- if (session->immersive() && session->outputContext() &&
- session->device()->external()) {
+ if (session->immersive() && session->outputContext() && session->External()) {
mirroring_ = true;
drawing_buffer_->SetMirrorClient(this);
}
@@ -158,7 +157,7 @@ XRViewport* XRWebGLLayer::getViewport(XRView* view) {
return GetViewportForEye(view->EyeValue());
}
-XRViewport* XRWebGLLayer::GetViewportForEye(XRView::Eye eye) {
+XRViewport* XRWebGLLayer::GetViewportForEye(XRView::XREye eye) {
if (viewports_dirty_)
UpdateViewports();
@@ -188,7 +187,6 @@ void XRWebGLLayer::requestViewportScaling(double scale_factor) {
double XRWebGLLayer::getNativeFramebufferScaleFactor(XRSession* session) {
return session->NativeFramebufferScale();
- ;
}
void XRWebGLLayer::UpdateViewports() {
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 c0012c27700..7616c7ce1ae 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
@@ -62,7 +62,7 @@ class XRWebGLLayer final : public XRLayer,
static double getNativeFramebufferScaleFactor(XRSession* session);
- XRViewport* GetViewportForEye(XRView::Eye);
+ XRViewport* GetViewportForEye(XRView::XREye);
void UpdateViewports();
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 56db1739098..f5d7a6fe99e 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
@@ -7,6 +7,7 @@ typedef (WebGLRenderingContext or WebGL2RenderingContext) XRWebGLRenderingContex
// https://immersive-web.github.io/webxr/#xrwebgllayer-interface
[
SecureContext,
+ Exposed=Window,
OriginTrialEnabled=WebXR,
Constructor(XRSession session, XRWebGLRenderingContext context, optional XRWebGLLayerInit layerInit),
RaisesException=Constructor
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer_init.idl b/chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer_init.idl
index 7209d81b091..81c6b505ca4 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer_init.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer_init.idl
@@ -3,9 +3,7 @@
// found in the LICENSE file.
// https://immersive-web.github.io/webxr/#xrwebgllayer-interface
-[
- SecureContext
-] dictionary XRWebGLLayerInit {
+dictionary XRWebGLLayerInit {
boolean antialias = true;
boolean depth = true;
boolean stencil = false;
diff --git a/chromium/third_party/blink/renderer/platform/BUILD.gn b/chromium/third_party/blink/renderer/platform/BUILD.gn
index d5d8e48305b..7b47402ebe6 100644
--- a/chromium/third_party/blink/renderer/platform/BUILD.gn
+++ b/chromium/third_party/blink/renderer/platform/BUILD.gn
@@ -22,21 +22,6 @@ blink_platform_avx_files = [
"audio/cpu/x86/vector_math_avx.h",
]
-blink_platform_neon_files = [
- "audio/cpu/arm/vector_math_neon.h",
- "graphics/cpu/arm/webgl_image_conversion_neon.h",
-]
-
-blink_platform_msa_files = [
- "audio/cpu/mips/vector_math_msa.h",
- "graphics/cpu/mips/webgl_image_conversion_msa.h",
-]
-
-blink_platform_sse_files = [
- "audio/cpu/x86/vector_math_sse.h",
- "graphics/cpu/x86/webgl_image_conversion_sse.h",
-]
-
make_names("font_family_names") {
in_files = [ "fonts/font_family_names.json5" ]
output_dir = blink_platform_output_dir
@@ -214,6 +199,11 @@ group("blink_platform_public_deps") {
"//v8",
]
public_configs = [ "//third_party/blink/renderer:features" ]
+
+ if (is_android) {
+ public_deps +=
+ [ "//third_party/blink/public/common:font_unique_name_table_proto" ]
+ }
}
declare_args() {
@@ -423,6 +413,7 @@ jumbo_component("platform") {
"bindings/callback_function_base.h",
"bindings/callback_interface_base.cc",
"bindings/callback_interface_base.h",
+ "bindings/custom_wrappable.h",
"bindings/dom_data_store.h",
"bindings/dom_wrapper_map.h",
"bindings/dom_wrapper_world.cc",
@@ -437,6 +428,8 @@ jumbo_component("platform") {
"bindings/name_client.h",
"bindings/origin_trial_features.cc",
"bindings/origin_trial_features.h",
+ "bindings/parkable_string.cc",
+ "bindings/parkable_string.h",
"bindings/runtime_call_stats.cc",
"bindings/runtime_call_stats.h",
"bindings/scoped_persistent.h",
@@ -597,9 +590,10 @@ jumbo_component("platform") {
"feature_policy/feature_policy.h",
"file_metadata.cc",
"file_metadata.h",
- "file_system_type.h",
"fonts/alternate_font_family.h",
"fonts/android/font_cache_android.cc",
+ "fonts/android/font_unique_name_lookup_android.cc",
+ "fonts/android/font_unique_name_lookup_android.h",
"fonts/bitmap_glyphs_blacklist.cc",
"fonts/bitmap_glyphs_blacklist.h",
"fonts/canvas_rotation_in_vertical.h",
@@ -651,6 +645,8 @@ jumbo_component("platform") {
"fonts/font_selector_client.h",
"fonts/font_smoothing_mode.cc",
"fonts/font_smoothing_mode.h",
+ "fonts/font_unique_name_lookup.cc",
+ "fonts/font_unique_name_lookup.h",
"fonts/font_variant_east_asian.cc",
"fonts/font_variant_east_asian.h",
"fonts/font_variant_numeric.cc",
@@ -744,6 +740,7 @@ jumbo_component("platform") {
"fonts/win/font_fallback_win.cc",
"fonts/win/font_fallback_win.h",
"fonts/win/font_platform_data_win.cc",
+ "geometry/blend.h",
"geometry/cg/float_point_cg.cc",
"geometry/cg/float_rect_cg.cc",
"geometry/cg/float_size_cg.cc",
@@ -964,6 +961,8 @@ jumbo_component("platform") {
"graphics/image_animation_policy.h",
"graphics/image_data_buffer.cc",
"graphics/image_data_buffer.h",
+ "graphics/image_decoder_wrapper.cc",
+ "graphics/image_decoder_wrapper.h",
"graphics/image_decoding_store.cc",
"graphics/image_decoding_store.h",
"graphics/image_frame_generator.cc",
@@ -985,8 +984,6 @@ jumbo_component("platform") {
"graphics/mailbox_texture_holder.h",
"graphics/offscreen_canvas_placeholder.cc",
"graphics/offscreen_canvas_placeholder.h",
- "graphics/offscreen_canvas_resource_provider.cc",
- "graphics/offscreen_canvas_resource_provider.h",
"graphics/paint/clip_paint_property_node.cc",
"graphics/paint/clip_paint_property_node.h",
"graphics/paint/cull_rect.cc",
@@ -1163,8 +1160,6 @@ jumbo_component("platform") {
"lifecycle_observer.h",
"link_hash.cc",
"link_hash.h",
- "long_task_detector.cc",
- "long_task_detector.h",
"mac/block_exceptions.h",
"mac/block_exceptions.mm",
"mac/color_mac.h",
@@ -1173,9 +1168,6 @@ jumbo_component("platform") {
"mac/graphics_context_canvas.mm",
"mac/local_current_graphics_context.h",
"mac/local_current_graphics_context.mm",
- "mac/ns_scroller_imp_details.h",
- "mac/scroll_animator_mac.h",
- "mac/scroll_animator_mac.mm",
"mac/theme_mac.h",
"mac/theme_mac.mm",
"mac/version_util_mac.h",
@@ -1210,8 +1202,6 @@ jumbo_component("platform") {
"mojo/interface_invalidator.cc",
"mojo/interface_invalidator.h",
"mojo/mojo_helper.h",
- "mojo/notification_struct_traits.cc",
- "mojo/notification_struct_traits.h",
"mojo/revocable_binding.h",
"mojo/revocable_interface_ptr.h",
"mojo/revocable_strong_binding.h",
@@ -1219,14 +1209,12 @@ jumbo_component("platform") {
"mojo/string16_mojom_traits.h",
"partition_alloc_memory_dump_provider.cc",
"partition_alloc_memory_dump_provider.h",
- "paste_mode.h",
"peerconnection/rtc_answer_options_platform.h",
"peerconnection/rtc_offer_options_platform.h",
"peerconnection/rtc_session_description_request.h",
"peerconnection/rtc_stats_request.h",
"peerconnection/rtc_stats_response_base.h",
"peerconnection/rtc_void_request.h",
- "platform_chrome_client.h",
"plugins/plugin_data.cc",
"plugins/plugin_data.h",
"plugins/plugin_script_forbidden_scope.cc",
@@ -1244,46 +1232,13 @@ jumbo_component("platform") {
"probe/platform_trace_events_agent.cc",
"probe/platform_trace_events_agent.h",
"resolution_units.h",
- "scoped_orientation_change_indicator.cc",
- "scoped_orientation_change_indicator.h",
"scroll/main_thread_scrolling_reason.h",
- "scroll/programmatic_scroll_animator.cc",
- "scroll/programmatic_scroll_animator.h",
+ "scroll/overscroll_behavior.h",
"scroll/scroll_alignment.cc",
"scroll/scroll_alignment.h",
- "scroll/scroll_animator.cc",
- "scroll/scroll_animator.h",
- "scroll/scroll_animator_base.cc",
- "scroll/scroll_animator_base.h",
- "scroll/scroll_animator_compositor_coordinator.cc",
- "scroll/scroll_animator_compositor_coordinator.h",
- "scroll/scroll_customization.cc",
- "scroll/scroll_customization.h",
"scroll/scroll_snap_data.h",
- "scroll/scroll_state_data.h",
"scroll/scroll_types.h",
- "scroll/scrollable_area.cc",
- "scroll/scrollable_area.h",
- "scroll/scrollbar.cc",
- "scroll/scrollbar.h",
- "scroll/scrollbar_layer_delegate.cc",
- "scroll/scrollbar_layer_delegate.h",
- "scroll/scrollbar_theme.cc",
- "scroll/scrollbar_theme.h",
- "scroll/scrollbar_theme_android.cc",
- "scroll/scrollbar_theme_aura.cc",
- "scroll/scrollbar_theme_aura.h",
- "scroll/scrollbar_theme_mac.h",
- "scroll/scrollbar_theme_mac.mm",
- "scroll/scrollbar_theme_mock.cc",
- "scroll/scrollbar_theme_mock.h",
- "scroll/scrollbar_theme_overlay.cc",
- "scroll/scrollbar_theme_overlay.h",
- "scroll/scrollbar_theme_overlay_mock.h",
- "scroll/smooth_scroll_sequencer.cc",
- "scroll/smooth_scroll_sequencer.h",
- "scroll/web_scroll_into_view_params.cc",
- "scroll/web_scrollbar_theme.mm",
+ "scroll/web_scrollbar_theme_client.h",
"serialized_resource.h",
"shared_buffer.cc",
"shared_buffer.h",
@@ -1367,8 +1322,6 @@ jumbo_component("platform") {
"theme.cc",
"theme.h",
"theme_types.h",
- "time_clamper.cc",
- "time_clamper.h",
"timer.cc",
"timer.h",
"transforms/affine_transform.cc",
@@ -1439,9 +1392,6 @@ jumbo_component("platform") {
]
sources -= blink_platform_avx_files
- sources -= blink_platform_neon_files
- sources -= blink_platform_msa_files
- sources -= blink_platform_sse_files
# Add in the generated files.
sources += get_target_outputs(":character_data") +
@@ -1502,10 +1452,11 @@ jumbo_component("platform") {
"//mojo/public/cpp/bindings",
"//mojo/public/cpp/bindings:wtf_support",
"//services/service_manager/public/cpp",
- "//services/ui/public/cpp/gpu",
+ "//services/ws/public/cpp/gpu",
"//skia:skcms",
"//third_party:freetype_harfbuzz",
"//third_party/blink/public:embedded_frame_sink_mojo_bindings_blink",
+ "//third_party/blink/public/common",
"//third_party/ced",
"//third_party/icu",
"//ui/gfx",
@@ -1516,8 +1467,6 @@ jumbo_component("platform") {
sources -= [
"fonts/skia/font_cache_skia.cc",
"fonts/web_font_render_style.cc",
- "scroll/scroll_animator.cc",
- "scroll/scroll_animator.h",
# Uses LocaleMac instead.
"text/locale_icu.cc",
@@ -1572,26 +1521,8 @@ jumbo_component("platform") {
]
}
- if (!use_default_render_theme) {
- sources -= [
- "scroll/scrollbar_theme_aura.cc",
- "scroll/scrollbar_theme_aura.h",
- ]
- }
-
- if (current_cpu == "arm") {
- deps += [ ":blink_arm_neon" ]
- }
-
- if (current_cpu == "mipsel" || current_cpu == "mips64el") {
- deps += [ ":blink_mips_msa" ]
- }
-
if (current_cpu == "x86" || current_cpu == "x64") {
- deps += [
- ":blink_x86_avx",
- ":blink_x86_sse",
- ]
+ deps += [ ":blink_x86_avx" ]
}
if (use_webaudio_ffmpeg) {
@@ -1613,7 +1544,8 @@ jumbo_static_library("test_support") {
sources = [
"graphics/gpu/drawing_buffer_test_helpers.h",
- "scroll/scrollbar_test_suite.h",
+ "testing/code_cache_loader_mock.cc",
+ "testing/code_cache_loader_mock.h",
"testing/compositor_test.cc",
"testing/compositor_test.h",
"testing/empty_web_media_player.cc",
@@ -1645,6 +1577,8 @@ jumbo_static_library("test_support") {
"testing/test_paint_artifact.h",
"testing/testing_platform_support.cc",
"testing/testing_platform_support.h",
+ "testing/testing_platform_support_with_custom_scheduler.cc",
+ "testing/testing_platform_support_with_custom_scheduler.h",
"testing/testing_platform_support_with_mock_scheduler.cc",
"testing/testing_platform_support_with_mock_scheduler.h",
"testing/testing_platform_support_with_web_rtc.cc",
@@ -1653,7 +1587,8 @@ jumbo_static_library("test_support") {
"testing/unit_test_helpers.h",
"testing/url_test_helpers.cc",
"testing/url_test_helpers.h",
- "testing/use_mock_scrollbar_settings.h",
+ "testing/viewport_layers_setup.cc",
+ "testing/viewport_layers_setup.h",
"testing/weburl_loader_mock.cc",
"testing/weburl_loader_mock.h",
"testing/weburl_loader_mock_factory_impl.cc",
@@ -1718,6 +1653,7 @@ jumbo_source_set("blink_platform_unittests_sources") {
"audio/push_pull_fifo_multithread_test.cc",
"audio/push_pull_fifo_test.cc",
"audio/vector_math_test.cc",
+ "bindings/parkable_string_test.cc",
"bindings/runtime_call_stats_test.cc",
"drag_image_test.cc",
"exported/file_path_conversion_test.cc",
@@ -1821,7 +1757,6 @@ jumbo_source_set("blink_platform_unittests_sources") {
"json/json_values_test.cc",
"layout_unit_test.cc",
"lifecycle_context_test.cc",
- "long_task_detector_test.cc",
"mac/graphics_context_canvas_test.mm",
"mac/version_util_mac_test.mm",
"mhtml/mhtml_parser_test.cc",
@@ -1829,16 +1764,12 @@ jumbo_source_set("blink_platform_unittests_sources") {
"mojo/geometry_struct_traits_test.cc",
"mojo/interface_invalidator_test.cc",
"mojo/kurl_security_origin_test.cc",
- "mojo/notification_struct_traits_test.cc",
"mojo/string16_mojom_traits_test.cc",
"plugins/plugin_data_test.cc",
"pod_arena_test.cc",
"pod_free_list_arena_test.cc",
"pod_interval_tree_test.cc",
"pod_red_black_tree_test.cc",
- "scoped_orientation_change_indicator_test.cc",
- "scroll/scrollable_area_test.cc",
- "scroll/scrollbar_theme_overlay_test.cc",
"shared_buffer_test.cc",
"testing/arena_test_helpers.h",
"testing/tree_test_helpers.cc",
@@ -1861,7 +1792,6 @@ jumbo_source_set("blink_platform_unittests_sources") {
"text/text_run_test.cc",
"text/unicode_utilities_test.cc",
"text/writing_mode_utils_test.cc",
- "time_clamper_test.cc",
"timer_test.cc",
"transforms/affine_transform_test.cc",
"transforms/rotation_test.cc",
@@ -1875,7 +1805,6 @@ jumbo_source_set("blink_platform_unittests_sources") {
"web_vector_test.cc",
"weborigin/known_ports_test.cc",
"weborigin/kurl_test.cc",
- "weborigin/origin_access_entry_test.cc",
"weborigin/scheme_registry_test.cc",
"weborigin/security_origin_test.cc",
"weborigin/security_policy_test.cc",
@@ -1889,14 +1818,6 @@ jumbo_source_set("blink_platform_unittests_sources") {
sources += [ "text/locale_icu_test.cc" ]
}
- if (!is_mac) {
- sources += [ "scroll/scroll_animator_test.cc" ]
- }
-
- if (use_default_render_theme) {
- sources += [ "scroll/scrollbar_theme_aura_test.cc" ]
- }
-
sources += [ "testing/run_all_tests.cc" ]
configs += [
@@ -1919,6 +1840,7 @@ jumbo_source_set("blink_platform_unittests_sources") {
"//services/viz/public/interfaces",
"//services/viz/public/interfaces:interfaces_blink",
"//skia",
+ "//skia:skcms",
"//testing/gmock",
"//testing/gtest",
"//third_party:freetype_harfbuzz",
@@ -2006,28 +1928,6 @@ group("blink_platform_unittests_data") {
]
}
-if (current_cpu == "arm") {
- source_set("blink_arm_neon") {
- sources = blink_platform_neon_files
- # The *NEON.cpp files fail to compile when -mthumb is passed. Force
- # them to build in ARM mode.
- # See https://bugs.webkit.org/show_bug.cgi?id=62916.
- # TODO(GYP)
- #'cflags': ['-marm'],
- # 'conditions': [
- # ['OS=="android"', {
- # 'cflags!': ['-mthumb'],
- # }],
- # ],
- }
-}
-
-if (current_cpu == "mipsel" || current_cpu == "mips64el") {
- source_set("blink_mips_msa") {
- sources = blink_platform_msa_files
- }
-}
-
if (current_cpu == "x86" || current_cpu == "x64") {
source_set("blink_x86_avx") {
sources = blink_platform_avx_files
@@ -2036,15 +1936,12 @@ if (current_cpu == "x86" || current_cpu == "x64") {
":blink_platform_implementation",
"//third_party/blink/renderer:non_test_config",
]
- if (!is_clang && is_win) {
+ if (is_win) {
cflags = [ "/arch:AVX" ]
} else {
cflags = [ "-mavx" ]
}
}
- source_set("blink_x86_sse") {
- sources = blink_platform_sse_files
- }
}
test("blink_fuzzer_unittests") {
@@ -2209,6 +2106,7 @@ jumbo_source_set("unit_tests") {
visibility = []
visibility = [ "//third_party/blink/renderer/*" ]
sources = [
+ "animation/animated_layers_test.cc",
"graphics/canvas_2d_layer_bridge_test.cc",
"graphics/canvas_color_params_test.cc",
"graphics/canvas_resource_test.cc",
diff --git a/chromium/third_party/blink/renderer/platform/DEPS b/chromium/third_party/blink/renderer/platform/DEPS
index e00bfd444fd..ebf694744aa 100644
--- a/chromium/third_party/blink/renderer/platform/DEPS
+++ b/chromium/third_party/blink/renderer/platform/DEPS
@@ -29,7 +29,6 @@ include_rules = [
"+base/numerics/safe_conversions.h",
"+base/rand_util.h",
"+base/run_loop.h",
- "+base/sampling_heap_profiler/sampling_heap_profiler.h",
"+base/strings/pattern.h",
"+base/strings/string_util.h",
"+base/strings/stringprintf.h",
diff --git a/chromium/third_party/blink/renderer/platform/OWNERS b/chromium/third_party/blink/renderer/platform/OWNERS
index 7e45d470ca9..a6ca217c757 100644
--- a/chromium/third_party/blink/renderer/platform/OWNERS
+++ b/chromium/third_party/blink/renderer/platform/OWNERS
@@ -3,6 +3,7 @@ dgozman@chromium.org
drott@chromium.org
eae@chromium.org
fmalita@chromium.org
+fserb@chromium.org
haraken@chromium.org
jbroman@chromium.org
jochen@chromium.org
diff --git a/chromium/third_party/blink/renderer/platform/animation/DEPS b/chromium/third_party/blink/renderer/platform/animation/DEPS
index 26f742b2719..d15d7b3e622 100644
--- a/chromium/third_party/blink/renderer/platform/animation/DEPS
+++ b/chromium/third_party/blink/renderer/platform/animation/DEPS
@@ -10,7 +10,6 @@ include_rules = [
"+third_party/blink/renderer/platform/geometry",
"+third_party/blink/renderer/platform/graphics",
"+third_party/blink/renderer/platform/heap",
- "+third_party/blink/renderer/platform/instrumentation",
"+third_party/blink/renderer/platform/layout_unit.h",
"+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/animation/animated_layers_test.cc b/chromium/third_party/blink/renderer/platform/animation/animated_layers_test.cc
new file mode 100644
index 00000000000..1b278094dae
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/animation/animated_layers_test.cc
@@ -0,0 +1,122 @@
+// 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 <memory>
+
+#include "cc/layers/picture_layer.h"
+#include "cc/trees/layer_tree_host.h"
+#include "cc/trees/mutator_host.h"
+#include "testing/gtest/include/gtest/gtest.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_host.h"
+#include "third_party/blink/renderer/platform/animation/compositor_animation_timeline.h"
+#include "third_party/blink/renderer/platform/animation/compositor_float_animation_curve.h"
+#include "third_party/blink/renderer/platform/animation/compositor_keyframe_model.h"
+#include "third_party/blink/renderer/platform/animation/compositor_target_property.h"
+#include "third_party/blink/renderer/platform/graphics/compositor_element_id.h"
+#include "third_party/blink/renderer/platform/testing/fake_graphics_layer.h"
+#include "third_party/blink/renderer/platform/testing/fake_graphics_layer_client.h"
+#include "third_party/blink/renderer/platform/testing/paint_test_configurations.h"
+#include "third_party/blink/renderer/platform/testing/viewport_layers_setup.h"
+
+namespace blink {
+
+class AnimatedLayersTest : public testing::Test,
+ public PaintTestConfigurations {
+ public:
+ AnimatedLayersTest() = default;
+ ~AnimatedLayersTest() = default;
+
+ protected:
+ ViewportLayersSetup layers_;
+};
+
+INSTANTIATE_TEST_CASE_P(All,
+ AnimatedLayersTest,
+ testing::Values(0, kBlinkGenPropertyTrees));
+
+class AnimationForTesting : public CompositorAnimationClient {
+ public:
+ AnimationForTesting() {
+ compositor_animation_ = CompositorAnimation::Create();
+ }
+
+ CompositorAnimation* GetCompositorAnimation() const override {
+ return compositor_animation_.get();
+ }
+
+ std::unique_ptr<CompositorAnimation> compositor_animation_;
+};
+
+TEST_P(AnimatedLayersTest, updateLayerShouldFlattenTransformWithAnimations) {
+ // TODO(bokan): This test doesn't yet work in blink-gen-property-trees
+ // because cc::Layers can't set an element id in that mode. We fail at
+ // AttachElement since the element id is invalid. https://crbug.com/836897.
+ if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled())
+ return;
+
+ cc::Layer* cc_layer = layers_.graphics_layer().CcLayer();
+ cc::MutatorHost* mutator = layers_.layer_tree_host()->mutator_host();
+ EXPECT_FALSE(
+ mutator->HasTickingKeyframeModelForTesting(cc_layer->element_id()));
+
+ std::unique_ptr<CompositorFloatAnimationCurve> curve =
+ CompositorFloatAnimationCurve::Create();
+ curve->AddKeyframe(
+ CompositorFloatKeyframe(0.0, 0.0,
+ *CubicBezierTimingFunction::Preset(
+ CubicBezierTimingFunction::EaseType::EASE)));
+ std::unique_ptr<CompositorKeyframeModel> float_keyframe_model(
+ CompositorKeyframeModel::Create(*curve, CompositorTargetProperty::OPACITY,
+ 0, 0));
+ int keyframe_model_id = float_keyframe_model->Id();
+
+ std::unique_ptr<CompositorAnimationTimeline> compositor_timeline =
+ CompositorAnimationTimeline::Create();
+ AnimationForTesting animation;
+
+ CompositorAnimationHost host(layers_.animation_host());
+
+ host.AddTimeline(*compositor_timeline);
+ compositor_timeline->AnimationAttached(animation);
+
+ cc_layer->SetElementId(CompositorElementId(cc_layer->id()));
+
+ animation.GetCompositorAnimation()->AttachElement(cc_layer->element_id());
+ ASSERT_TRUE(animation.GetCompositorAnimation()->IsElementAttached());
+
+ animation.GetCompositorAnimation()->AddKeyframeModel(
+ std::move(float_keyframe_model));
+
+ EXPECT_TRUE(
+ mutator->HasTickingKeyframeModelForTesting(cc_layer->element_id()));
+
+ layers_.graphics_layer().SetShouldFlattenTransform(false);
+
+ cc_layer = layers_.graphics_layer().CcLayer();
+ ASSERT_TRUE(cc_layer);
+
+ EXPECT_TRUE(
+ mutator->HasTickingKeyframeModelForTesting(cc_layer->element_id()));
+ animation.GetCompositorAnimation()->RemoveKeyframeModel(keyframe_model_id);
+ EXPECT_FALSE(
+ mutator->HasTickingKeyframeModelForTesting(cc_layer->element_id()));
+
+ layers_.graphics_layer().SetShouldFlattenTransform(true);
+
+ cc_layer = layers_.graphics_layer().CcLayer();
+ ASSERT_TRUE(cc_layer);
+
+ EXPECT_FALSE(
+ mutator->HasTickingKeyframeModelForTesting(cc_layer->element_id()));
+
+ animation.GetCompositorAnimation()->DetachElement();
+ ASSERT_FALSE(animation.GetCompositorAnimation()->IsElementAttached());
+
+ compositor_timeline->AnimationDestroyed(animation);
+ host.RemoveTimeline(*compositor_timeline.get());
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/animation/animation_utilities.h b/chromium/third_party/blink/renderer/platform/animation/animation_utilities.h
index fd6a05c818a..183f3ee3b38 100644
--- a/chromium/third_party/blink/renderer/platform/animation/animation_utilities.h
+++ b/chromium/third_party/blink/renderer/platform/animation/animation_utilities.h
@@ -26,56 +26,11 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_ANIMATION_ANIMATION_UTILITIES_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_ANIMATION_ANIMATION_UTILITIES_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/layout_unit.h"
-#include "third_party/blink/renderer/platform/platform_export.h"
-#include "third_party/blink/renderer/platform/wtf/math_extras.h"
+#include "third_party/blink/renderer/platform/geometry/blend.h"
#include "ui/gfx/geometry/cubic_bezier.h"
-#include <type_traits>
-
namespace blink {
-inline int Blend(int from, int to, double progress) {
- return lround(from + (to - from) * progress);
-}
-
-// For unsigned types.
-template <typename T>
-inline T Blend(T from, T to, double progress) {
- static_assert(std::is_integral<T>::value,
- "blend can only be used with integer types");
- return clampTo<T>(round(to > from ? from + (to - from) * progress
- : from - (from - to) * progress));
-}
-
-inline double Blend(double from, double to, double progress) {
- return from + (to - from) * progress;
-}
-
-inline float Blend(float from, float to, double progress) {
- return static_cast<float>(from + (to - from) * progress);
-}
-
-inline LayoutUnit Blend(LayoutUnit from, LayoutUnit to, double progress) {
- return LayoutUnit(from + (to - from) * progress);
-}
-
-inline IntPoint Blend(const IntPoint& from,
- const IntPoint& to,
- double progress) {
- return IntPoint(Blend(from.X(), to.X(), progress),
- Blend(from.Y(), to.Y(), progress));
-}
-
-inline FloatPoint Blend(const FloatPoint& from,
- const FloatPoint& to,
- double progress) {
- return FloatPoint(Blend(from.X(), to.X(), progress),
- Blend(from.Y(), to.Y(), progress));
-}
-
// Calculates the accuracy for evaluating a timing function for an animation
// with the specified duration.
inline double AccuracyForDuration(double duration) {
diff --git a/chromium/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.cc b/chromium/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.cc
index 8e727fd6650..1b339b18aee 100644
--- a/chromium/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.cc
+++ b/chromium/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.cc
@@ -72,7 +72,7 @@ FloatPoint CompositorScrollOffsetAnimationCurve::TargetValue() const {
return FloatPoint(target.x(), target.y());
}
-void CompositorScrollOffsetAnimationCurve::UpdateTarget(double time,
+void CompositorScrollOffsetAnimationCurve::UpdateTarget(TimeDelta time,
FloatPoint new_target) {
curve_->UpdateTarget(time, gfx::ScrollOffset(new_target.X(), new_target.Y()));
}
diff --git a/chromium/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.h b/chromium/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.h
index a4c0291c55d..7b2dec4dadf 100644
--- a/chromium/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.h
+++ b/chromium/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.h
@@ -12,6 +12,7 @@
#include "third_party/blink/renderer/platform/geometry/float_point.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/noncopyable.h"
+#include "third_party/blink/renderer/platform/wtf/time.h"
namespace cc {
class ScrollOffsetAnimationCurve;
@@ -49,7 +50,7 @@ class PLATFORM_EXPORT CompositorScrollOffsetAnimationCurve
double Duration() const;
FloatPoint TargetValue() const;
void ApplyAdjustment(IntSize);
- void UpdateTarget(double time, FloatPoint new_target);
+ void UpdateTarget(TimeDelta time, FloatPoint new_target);
// CompositorAnimationCurve implementation.
std::unique_ptr<cc::AnimationCurve> CloneToAnimationCurve() const override;
diff --git a/chromium/third_party/blink/renderer/platform/async_file_system_callbacks.h b/chromium/third_party/blink/renderer/platform/async_file_system_callbacks.h
index 94b1cbf828f..5a6c6466fcc 100644
--- a/chromium/third_party/blink/renderer/platform/async_file_system_callbacks.h
+++ b/chromium/third_party/blink/renderer/platform/async_file_system_callbacks.h
@@ -32,10 +32,10 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_ASYNC_FILE_SYSTEM_CALLBACKS_H_
#include <memory>
+#include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink.h"
#include "third_party/blink/public/platform/web_file_writer.h"
#include "third_party/blink/renderer/platform/blob/blob_data.h"
#include "third_party/blink/renderer/platform/file_metadata.h"
-#include "third_party/blink/renderer/platform/file_system_type.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/noncopyable.h"
@@ -61,7 +61,7 @@ class PLATFORM_EXPORT AsyncFileSystemCallbacks {
// Called when a filesystem URL is resolved.
virtual void DidResolveURL(const String& name,
const KURL& root_url,
- FileSystemType,
+ mojom::blink::FileSystemType,
const String& file_path,
bool is_directory) {
NOTREACHED();
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 1c98e7ca63f..5e740515fed 100644
--- a/chromium/third_party/blink/renderer/platform/audio/audio_destination.cc
+++ b/chromium/third_party/blink/renderer/platform/audio/audio_destination.cc
@@ -150,22 +150,6 @@ void AudioDestination::Render(const WebVector<float*>& destination_data,
delay_timestamp, "delay (s)", delay);
}
-// Determine if the rendered data is audible.
-static bool IsAudible(const AudioBus* rendered_data) {
- // Compute the energy in each channel and sum up the energy in each channel
- // for the total energy.
- float energy = 0;
-
- unsigned data_size = rendered_data->length();
- for (unsigned k = 0; k < rendered_data->NumberOfChannels(); ++k) {
- const float* data = rendered_data->Channel(k)->Data();
- float channel_energy;
- VectorMath::Vsvesq(data, 1, &channel_energy, data_size);
- energy += channel_energy;
- }
-
- return energy > 0;
-}
void AudioDestination::RequestRender(size_t frames_requested,
size_t frames_to_render,
@@ -204,23 +188,6 @@ void AudioDestination::RequestRender(size_t frames_requested,
callback_.Render(render_bus_.get(),
AudioUtilities::kRenderQuantumFrames, output_position);
- // Detect silence (or not) for MEI
- bool is_audible = IsAudible(render_bus_.get());
-
- if (is_audible) {
- ++total_audible_renders_;
- }
-
- if (was_audible_) {
- if (!is_audible) {
- was_audible_ = false;
- }
- } else {
- if (is_audible) {
- was_audible_ = true;
- }
- }
-
fifo_->Push(render_bus_.get());
}
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 71388f76156..a42f2ee932b 100644
--- a/chromium/third_party/blink/renderer/platform/audio/audio_destination.h
+++ b/chromium/third_party/blink/renderer/platform/audio/audio_destination.h
@@ -138,15 +138,6 @@ class PLATFORM_EXPORT AudioDestination
// graph into the FIFO.
scoped_refptr<AudioBus> render_bus_;
- // Keeps track if the output of this destination was audible, before the
- // current rendering quantum. Used for recording "playback" time.
- bool was_audible_ = false;
-
- // Counts the number of render quanta where audible sound was played. We
- // determine audibility on render quantum boundaries, so counting quanta is
- // all that's needed.
- size_t total_audible_renders_ = 0;
-
// Accessed by rendering thread: the render callback function of WebAudio
// engine. (i.e. DestinationNode)
AudioIOCallback& callback_;
diff --git a/chromium/third_party/blink/renderer/platform/bindings/DEPS b/chromium/third_party/blink/renderer/platform/bindings/DEPS
index f59246cf3c3..87cfbf26f01 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/DEPS
+++ b/chromium/third_party/blink/renderer/platform/bindings/DEPS
@@ -13,7 +13,6 @@ include_rules = [
"+third_party/blink/renderer/platform/platform_export.h",
"+third_party/blink/renderer/platform/runtime_enabled_features.h",
"+third_party/blink/renderer/platform/scheduler",
- "+third_party/blink/renderer/platform/supplementable.h",
"+third_party/blink/renderer/platform/testing",
"+third_party/blink/renderer/platform/weborigin",
"+third_party/blink/renderer/platform/wtf",
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 2ddaaa2285d..6d2eb3757b3 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
@@ -6,15 +6,15 @@
#include "third_party/blink/renderer/platform/bindings/dom_data_store.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
-#include "third_party/blink/renderer/platform/bindings/script_wrappable_visitor.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/heap/visitor.h"
namespace blink {
void ActiveScriptWrappableBase::TraceActiveScriptWrappables(
v8::Isolate* isolate,
- ScriptWrappableVisitor* visitor) {
+ Visitor* visitor) {
V8PerIsolateData* isolate_data = V8PerIsolateData::From(isolate);
const auto* active_script_wrappables = isolate_data->ActiveScriptWrappables();
if (!active_script_wrappables)
@@ -40,8 +40,6 @@ void ActiveScriptWrappableBase::TraceActiveScriptWrappables(
if (active_wrappable->IsContextDestroyed())
continue;
ScriptWrappable* script_wrappable = active_wrappable->ToScriptWrappable();
- // Notify the visitor about this script_wrappable by dispatching to the
- // corresponding Trace method.
visitor->TraceWithWrappers(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 7c94f0ad8d4..63667dfc51d 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
@@ -13,7 +13,7 @@
namespace blink {
class ScriptWrappable;
-class ScriptWrappableVisitor;
+class Visitor;
/**
* Classes deriving from ActiveScriptWrappable will be registered in a
@@ -24,8 +24,7 @@ class PLATFORM_EXPORT ActiveScriptWrappableBase : public GarbageCollectedMixin {
WTF_MAKE_NONCOPYABLE(ActiveScriptWrappableBase);
public:
- static void TraceActiveScriptWrappables(v8::Isolate*,
- ScriptWrappableVisitor*);
+ static void TraceActiveScriptWrappables(v8::Isolate*, Visitor*);
virtual ~ActiveScriptWrappableBase() = default;
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 b46b253fe11..4acb4fd5acc 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
@@ -38,6 +38,9 @@ class PLATFORM_EXPORT CallbackFunctionBase
return callback_relevant_script_state_;
}
+ // Returns true if the ES function has a [[Construct]] internal method.
+ bool IsConstructor() const { return CallbackFunction()->IsConstructor(); }
+
protected:
explicit CallbackFunctionBase(v8::Local<v8::Function>);
@@ -57,6 +60,9 @@ class PLATFORM_EXPORT CallbackFunctionBase
Member<ScriptState> incumbent_script_state_;
friend class V8PersistentCallbackFunctionBase;
+ friend v8::Local<v8::Value> ToV8(CallbackFunctionBase* callback,
+ v8::Local<v8::Object> creation_context,
+ v8::Isolate*);
};
// V8PersistentCallbackFunctionBase retains the underlying v8::Function of a
diff --git a/chromium/third_party/blink/renderer/platform/bindings/custom_wrappable.h b/chromium/third_party/blink/renderer/platform/bindings/custom_wrappable.h
new file mode 100644
index 00000000000..6be47e62fc8
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/bindings/custom_wrappable.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_BINDINGS_CUSTOM_WRAPPABLE_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_CUSTOM_WRAPPABLE_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/noncopyable.h"
+
+namespace blink {
+
+// See the comment on CustomWrappableAdaptor.
+class PLATFORM_EXPORT CustomWrappable
+ : public GarbageCollectedFinalized<CustomWrappable>,
+ public NameClient {
+ WTF_MAKE_NONCOPYABLE(CustomWrappable);
+
+ public:
+ virtual ~CustomWrappable() = default;
+ virtual void Trace(Visitor*) {}
+ const char* NameInHeapSnapshot() const override { return "CustomWrappable"; }
+
+ protected:
+ CustomWrappable() = default;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_CUSTOM_WRAPPABLE_H_
diff --git a/chromium/third_party/blink/renderer/platform/wtf/text/movable_string.cc b/chromium/third_party/blink/renderer/platform/bindings/parkable_string.cc
index fdfa440ea96..21f9781b608 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/text/movable_string.cc
+++ b/chromium/third_party/blink/renderer/platform/bindings/parkable_string.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/platform/wtf/text/movable_string.h"
+#include "third_party/blink/renderer/platform/bindings/parkable_string.h"
#include "base/metrics/histogram_macros.h"
+#include "third_party/blink/renderer/platform/wtf/thread_specific.h"
-namespace WTF {
+namespace blink {
namespace {
@@ -16,39 +17,39 @@ bool IsLargeEnough(const StringImpl* impl) {
return impl && impl->length() > kSizeThreshold;
}
-void RecordParkingAction(MovableStringImpl::ParkingAction action) {
+void RecordParkingAction(ParkableStringImpl::ParkingAction action) {
UMA_HISTOGRAM_ENUMERATION("Memory.MovableStringParkingAction", action);
}
} // namespace
-MovableStringImpl::MovableStringImpl() = default;
+ParkableStringImpl::ParkableStringImpl() = default;
-MovableStringImpl::MovableStringImpl(scoped_refptr<StringImpl>&& impl)
+ParkableStringImpl::ParkableStringImpl(scoped_refptr<StringImpl>&& impl)
: string_(std::move(impl)), is_parked_(false) {}
-MovableStringImpl::~MovableStringImpl() {
- MovableStringTable::Instance().Remove(string_.Impl());
+ParkableStringImpl::~ParkableStringImpl() {
+ ParkableStringTable::Instance().Remove(string_.Impl());
}
-bool MovableStringImpl::Is8Bit() const {
+bool ParkableStringImpl::Is8Bit() const {
return string_.Is8Bit();
}
-bool MovableStringImpl::IsNull() const {
+bool ParkableStringImpl::IsNull() const {
return string_.IsNull();
}
-const String& MovableStringImpl::ToString() {
+const String& ParkableStringImpl::ToString() {
Unpark();
return string_;
}
-unsigned MovableStringImpl::CharactersSizeInBytes() const {
+unsigned ParkableStringImpl::CharactersSizeInBytes() const {
return string_.CharactersSizeInBytes();
}
-bool MovableStringImpl::Park() {
+bool ParkableStringImpl::Park() {
// Cannot park strings with several references.
if (string_.Impl()->HasOneRef()) {
RecordParkingAction(ParkingAction::kParkedInBackground);
@@ -57,59 +58,65 @@ bool MovableStringImpl::Park() {
return is_parked_;
}
-void MovableStringImpl::Unpark() {
+void ParkableStringImpl::Unpark() {
if (!is_parked_)
return;
- bool backgrounded = MovableStringTable::Instance().IsRendererBackgrounded();
+ bool backgrounded = ParkableStringTable::Instance().IsRendererBackgrounded();
RecordParkingAction(backgrounded ? ParkingAction::kUnparkedInBackground
: ParkingAction::kUnparkedInForeground);
is_parked_ = false;
}
-MovableString::MovableString(scoped_refptr<StringImpl>&& impl) {
- // Don't move small strings.
+ParkableString::ParkableString(scoped_refptr<StringImpl>&& impl) {
+ // Don't park small strings.
if (IsLargeEnough(impl.get())) {
- impl_ = MovableStringTable::Instance().Add(std::move(impl));
+ impl_ = ParkableStringTable::Instance().Add(std::move(impl));
} else {
- impl_ = base::MakeRefCounted<MovableStringImpl>(std::move(impl));
+ impl_ = base::MakeRefCounted<ParkableStringImpl>(std::move(impl));
}
}
-MovableString::~MovableString() = default;
+ParkableString::~ParkableString() = default;
-bool MovableString::Is8Bit() const {
+bool ParkableString::Is8Bit() const {
return impl_->Is8Bit();
}
-bool MovableString::IsNull() const {
+bool ParkableString::IsNull() const {
return impl_->IsNull();
}
-const String& MovableString::ToString() const {
+const String& ParkableString::ToString() const {
return impl_->ToString();
}
-unsigned MovableString::CharactersSizeInBytes() const {
+unsigned ParkableString::CharactersSizeInBytes() const {
return impl_->CharactersSizeInBytes();
}
-MovableStringTable::MovableStringTable() = default;
-MovableStringTable::~MovableStringTable() = default;
+// static
+ParkableStringTable& ParkableStringTable::Instance() {
+ static auto* table = new WTF::ThreadSpecific<ParkableStringTable>();
+ return **table;
+}
+
+ParkableStringTable::ParkableStringTable() = default;
+ParkableStringTable::~ParkableStringTable() = default;
-scoped_refptr<MovableStringImpl> MovableStringTable::Add(
+scoped_refptr<ParkableStringImpl> ParkableStringTable::Add(
scoped_refptr<StringImpl>&& string) {
StringImpl* raw_ptr = string.get();
auto it = table_.find(raw_ptr);
if (it != table_.end()) {
return it->second;
}
- auto new_movable_string =
- base::MakeRefCounted<MovableStringImpl>(std::move(string));
- table_.emplace(raw_ptr, new_movable_string.get());
- return new_movable_string;
+ auto new_parkable_string =
+ base::MakeRefCounted<ParkableStringImpl>(std::move(string));
+ table_.emplace(raw_ptr, new_parkable_string.get());
+ return new_parkable_string;
}
-void MovableStringTable::Remove(StringImpl* string) {
+void ParkableStringTable::Remove(StringImpl* string) {
if (!IsLargeEnough(string))
return;
@@ -118,21 +125,21 @@ void MovableStringTable::Remove(StringImpl* string) {
table_.erase(it);
}
-void MovableStringTable::SetRendererBackgrounded(bool backgrounded) {
+void ParkableStringTable::SetRendererBackgrounded(bool backgrounded) {
backgrounded_ = backgrounded;
}
-bool MovableStringTable::IsRendererBackgrounded() const {
+bool ParkableStringTable::IsRendererBackgrounded() const {
return backgrounded_;
}
-void MovableStringTable::MaybeParkAll() {
+void ParkableStringTable::MaybeParkAll() {
if (!IsRendererBackgrounded())
return;
size_t total_size = 0, count = 0;
for (auto& kv : table_) {
- MovableStringImpl* str = kv.second;
+ ParkableStringImpl* str = kv.second;
str->Park();
total_size += str->CharactersSizeInBytes();
count += 1;
@@ -144,4 +151,4 @@ void MovableStringTable::MaybeParkAll() {
UMA_HISTOGRAM_COUNTS_1000("Memory.MovableStringsCount", table_.size());
}
-} // namespace WTF
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/wtf/text/movable_string.h b/chromium/third_party/blink/renderer/platform/bindings/parkable_string.h
index 7b943e9b578..f4c6ea0a786 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/text/movable_string.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/parkable_string.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_PLATFORM_WTF_TEXT_MOVABLE_STRING_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TEXT_MOVABLE_STRING_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_PARKABLE_STRING_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_PARKABLE_STRING_H_
#include <map>
#include <set>
@@ -12,9 +12,11 @@
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
-#include "third_party/blink/renderer/platform/wtf/wtf_thread_data.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/ref_counted.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-// MovableString represents a string that may be moved in memory, that it its
+// ParkableString represents a string that may be parked in memory, that it its
// underlying memory address may change. Its content can be retrieved with the
// |ToString()| method.
// As a consequence, the inner pointer should never be cached, and only touched
@@ -23,13 +25,13 @@
// As with WTF::AtomicString, this class is *not* thread-safe, and strings
// created on a thread must always be used on the same thread.
//
-// Implementation note: the string content is not moved yet, it is merely
+// Implementation note: the string content is not parked yet, it is merely
// used to gather statistics.
-namespace WTF {
+namespace blink {
-class WTF_EXPORT MovableStringImpl final
- : public RefCounted<MovableStringImpl> {
+class PLATFORM_EXPORT ParkableStringImpl final
+ : public RefCounted<ParkableStringImpl> {
public:
// Histogram buckets, exported for testing.
enum class ParkingAction {
@@ -39,9 +41,9 @@ class WTF_EXPORT MovableStringImpl final
kMaxValue = kUnparkedInForeground
};
- MovableStringImpl();
- explicit MovableStringImpl(scoped_refptr<StringImpl>&& impl);
- ~MovableStringImpl();
+ ParkableStringImpl();
+ explicit ParkableStringImpl(scoped_refptr<StringImpl>&& impl);
+ ~ParkableStringImpl();
// The returned string may be used as a normal one, as long as the
// returned value (or a copy of it) is alive.
@@ -65,21 +67,21 @@ class WTF_EXPORT MovableStringImpl final
String string_;
bool is_parked_;
- DISALLOW_COPY_AND_ASSIGN(MovableStringImpl);
+ DISALLOW_COPY_AND_ASSIGN(ParkableStringImpl);
};
-class WTF_EXPORT MovableString final {
+class PLATFORM_EXPORT ParkableString final {
public:
- MovableString() : impl_(base::MakeRefCounted<MovableStringImpl>(nullptr)) {}
- explicit MovableString(scoped_refptr<StringImpl>&& impl);
- MovableString(const MovableString& rhs) : impl_(rhs.impl_) {}
- ~MovableString();
+ ParkableString() : impl_(base::MakeRefCounted<ParkableStringImpl>(nullptr)) {}
+ explicit ParkableString(scoped_refptr<StringImpl>&& impl);
+ ParkableString(const ParkableString& rhs) : impl_(rhs.impl_) {}
+ ~ParkableString();
// See the matching String methods.
bool Is8Bit() const;
bool IsNull() const;
unsigned length() const { return impl_->length(); }
- MovableStringImpl* Impl() const { return impl_.get(); }
+ ParkableStringImpl* Impl() const { return impl_.get(); }
// Returns an unparked version of the string.
// The string is guaranteed to be valid for
// max(lifetime of a copy of the returned reference, current thread task).
@@ -92,22 +94,20 @@ class WTF_EXPORT MovableString final {
const UChar* Characters16() const { return ToString().Characters16(); }
private:
- scoped_refptr<MovableStringImpl> impl_;
+ scoped_refptr<ParkableStringImpl> impl_;
};
-// Per-thread registry of all MovableString instances. NOT thread-safe.
-class WTF_EXPORT MovableStringTable final {
+// Per-thread registry of all ParkableString instances. NOT thread-safe.
+class PLATFORM_EXPORT ParkableStringTable final {
public:
- MovableStringTable();
- ~MovableStringTable();
+ ParkableStringTable();
+ ~ParkableStringTable();
- static MovableStringTable& Instance() {
- return WtfThreadData().GetMovableStringTable();
- }
+ static ParkableStringTable& Instance();
- scoped_refptr<MovableStringImpl> Add(scoped_refptr<StringImpl>&&);
+ scoped_refptr<ParkableStringImpl> Add(scoped_refptr<StringImpl>&&);
- // This is for ~MovableStringImpl to unregister a string before
+ // This is for ~ParkableStringImpl to unregister a string before
// destruction since the table is holding raw pointers. It should not be used
// directly.
void Remove(StringImpl*);
@@ -121,19 +121,15 @@ class WTF_EXPORT MovableStringTable final {
private:
bool backgrounded_;
// Could bet a set where the hashing function is
- // MovableStringImpl::string_.Impl(), but clearer this way.
- std::map<StringImpl*, MovableStringImpl*> table_;
+ // ParkableStringImpl::string_.Impl(), but clearer this way.
+ std::map<StringImpl*, ParkableStringImpl*> table_;
- FRIEND_TEST_ALL_PREFIXES(MovableStringTest, TableSimple);
- FRIEND_TEST_ALL_PREFIXES(MovableStringTest, TableMultiple);
+ FRIEND_TEST_ALL_PREFIXES(ParkableStringTest, TableSimple);
+ FRIEND_TEST_ALL_PREFIXES(ParkableStringTest, TableMultiple);
- DISALLOW_COPY_AND_ASSIGN(MovableStringTable);
+ DISALLOW_COPY_AND_ASSIGN(ParkableStringTable);
};
-} // namespace WTF
+} // namespace blink
-using WTF::MovableStringTable;
-using WTF::MovableString;
-using WTF::MovableStringImpl;
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TEXT_MOVABLE_STRING_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_PARKABLE_STRING_H_
diff --git a/chromium/third_party/blink/renderer/platform/wtf/text/movable_string_test.cc b/chromium/third_party/blink/renderer/platform/bindings/parkable_string_test.cc
index 6eebafcd3f8..0e103545e2b 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/text/movable_string_test.cc
+++ b/chromium/third_party/blink/renderer/platform/bindings/parkable_string_test.cc
@@ -2,175 +2,175 @@
// Use 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/text/movable_string.h"
+#include "third_party/blink/renderer/platform/bindings/parkable_string.h"
#include <vector>
#include "base/test/metrics/histogram_tester.h"
#include "testing/gtest/include/gtest/gtest.h"
-namespace WTF {
+namespace blink {
-class MovableStringTest : public ::testing::Test {
+class ParkableStringTest : public ::testing::Test {
protected:
void SetUp() override {
- MovableStringTable::Instance().SetRendererBackgrounded(false);
+ ParkableStringTable::Instance().SetRendererBackgrounded(false);
}
};
-TEST_F(MovableStringTest, Simple) {
- MovableString movable_abc(String("abc").ReleaseImpl());
+TEST_F(ParkableStringTest, Simple) {
+ ParkableString parkable_abc(String("abc").ReleaseImpl());
- EXPECT_TRUE(MovableString().IsNull());
- EXPECT_FALSE(movable_abc.IsNull());
- EXPECT_TRUE(movable_abc.Is8Bit());
- EXPECT_EQ(3u, movable_abc.length());
- EXPECT_EQ(3u, movable_abc.CharactersSizeInBytes());
+ EXPECT_TRUE(ParkableString().IsNull());
+ EXPECT_FALSE(parkable_abc.IsNull());
+ EXPECT_TRUE(parkable_abc.Is8Bit());
+ EXPECT_EQ(3u, parkable_abc.length());
+ EXPECT_EQ(3u, parkable_abc.CharactersSizeInBytes());
- EXPECT_EQ(String("abc"), movable_abc.ToString());
- MovableString copy = movable_abc;
- EXPECT_EQ(copy.Impl(), movable_abc.Impl());
+ EXPECT_EQ(String("abc"), parkable_abc.ToString());
+ ParkableString copy = parkable_abc;
+ EXPECT_EQ(copy.Impl(), parkable_abc.Impl());
}
-TEST_F(MovableStringTest, Park) {
+TEST_F(ParkableStringTest, Park) {
base::HistogramTester histogram_tester;
- MovableString movable(String("abc").Impl());
- EXPECT_FALSE(movable.Impl()->is_parked());
- EXPECT_TRUE(movable.Impl()->Park());
- EXPECT_TRUE(movable.Impl()->is_parked());
+ ParkableString parkable(String("abc").Impl());
+ EXPECT_FALSE(parkable.Impl()->is_parked());
+ EXPECT_TRUE(parkable.Impl()->Park());
+ EXPECT_TRUE(parkable.Impl()->is_parked());
// Not the only one to have a reference to the string.
String abc("abc");
- MovableString movable2(abc.Impl());
- EXPECT_FALSE(movable2.Impl()->Park());
+ ParkableString parkable2(abc.Impl());
+ EXPECT_FALSE(parkable2.Impl()->Park());
abc = String();
- EXPECT_TRUE(movable2.Impl()->Park());
+ EXPECT_TRUE(parkable2.Impl()->Park());
histogram_tester.ExpectBucketCount(
"Memory.MovableStringParkingAction",
- MovableStringImpl::ParkingAction::kParkedInBackground, 2);
+ ParkableStringImpl::ParkingAction::kParkedInBackground, 2);
histogram_tester.ExpectTotalCount("Memory.MovableStringParkingAction", 2);
}
-TEST_F(MovableStringTest, Unpark) {
+TEST_F(ParkableStringTest, Unpark) {
base::HistogramTester histogram_tester;
- MovableString movable(String("abc").Impl());
- EXPECT_FALSE(movable.Impl()->is_parked());
- EXPECT_TRUE(movable.Impl()->Park());
- EXPECT_TRUE(movable.Impl()->is_parked());
+ ParkableString parkable(String("abc").Impl());
+ EXPECT_FALSE(parkable.Impl()->is_parked());
+ EXPECT_TRUE(parkable.Impl()->Park());
+ EXPECT_TRUE(parkable.Impl()->is_parked());
- String unparked = movable.ToString();
+ String unparked = parkable.ToString();
EXPECT_EQ(String("abc"), unparked);
- EXPECT_FALSE(movable.Impl()->is_parked());
+ EXPECT_FALSE(parkable.Impl()->is_parked());
histogram_tester.ExpectTotalCount("Memory.MovableStringParkingAction", 2);
histogram_tester.ExpectBucketCount(
"Memory.MovableStringParkingAction",
- MovableStringImpl::ParkingAction::kParkedInBackground, 1);
+ ParkableStringImpl::ParkingAction::kParkedInBackground, 1);
histogram_tester.ExpectBucketCount(
"Memory.MovableStringParkingAction",
- MovableStringImpl::ParkingAction::kUnparkedInForeground, 1);
+ ParkableStringImpl::ParkingAction::kUnparkedInForeground, 1);
}
-TEST_F(MovableStringTest, TableSimple) {
+TEST_F(ParkableStringTest, TableSimple) {
base::HistogramTester histogram_tester;
std::vector<char> data(20000, 'a');
- MovableString movable(String(data.data(), data.size()).ReleaseImpl());
- ASSERT_FALSE(movable.Impl()->is_parked());
+ ParkableString parkable(String(data.data(), data.size()).ReleaseImpl());
+ ASSERT_FALSE(parkable.Impl()->is_parked());
- auto& table = MovableStringTable::Instance();
+ auto& table = ParkableStringTable::Instance();
EXPECT_EQ(1u, table.table_.size());
// Small strings are not in the table.
- MovableString small(String("abc").ReleaseImpl());
+ ParkableString small(String("abc").ReleaseImpl());
EXPECT_EQ(1u, table.table_.size());
// No parking as the current state is not "backgrounded".
table.SetRendererBackgrounded(false);
ASSERT_FALSE(table.IsRendererBackgrounded());
table.MaybeParkAll();
- EXPECT_FALSE(movable.Impl()->is_parked());
+ EXPECT_FALSE(parkable.Impl()->is_parked());
histogram_tester.ExpectTotalCount("Memory.MovableStringsCount", 0);
table.SetRendererBackgrounded(true);
ASSERT_TRUE(table.IsRendererBackgrounded());
table.MaybeParkAll();
- EXPECT_TRUE(movable.Impl()->is_parked());
+ EXPECT_TRUE(parkable.Impl()->is_parked());
histogram_tester.ExpectUniqueSample("Memory.MovableStringsCount", 1, 1);
// Park and unpark.
- movable.ToString();
- EXPECT_FALSE(movable.Impl()->is_parked());
+ parkable.ToString();
+ EXPECT_FALSE(parkable.Impl()->is_parked());
table.MaybeParkAll();
- EXPECT_TRUE(movable.Impl()->is_parked());
+ EXPECT_TRUE(parkable.Impl()->is_parked());
histogram_tester.ExpectUniqueSample("Memory.MovableStringsCount", 1, 2);
// More than one reference, no parking.
table.SetRendererBackgrounded(false);
- String alive_unparked = movable.ToString(); // Unparked in foreground.
+ String alive_unparked = parkable.ToString(); // Unparked in foreground.
table.SetRendererBackgrounded(true);
table.MaybeParkAll();
- EXPECT_FALSE(movable.Impl()->is_parked());
+ EXPECT_FALSE(parkable.Impl()->is_parked());
// Other reference is dropped, OK to park.
alive_unparked = String();
table.MaybeParkAll();
- EXPECT_TRUE(movable.Impl()->is_parked());
+ EXPECT_TRUE(parkable.Impl()->is_parked());
histogram_tester.ExpectTotalCount("Memory.MovableStringParkingAction", 5);
histogram_tester.ExpectBucketCount(
"Memory.MovableStringParkingAction",
- MovableStringImpl::ParkingAction::kParkedInBackground, 3);
+ ParkableStringImpl::ParkingAction::kParkedInBackground, 3);
histogram_tester.ExpectBucketCount(
"Memory.MovableStringParkingAction",
- MovableStringImpl::ParkingAction::kUnparkedInBackground, 1);
+ ParkableStringImpl::ParkingAction::kUnparkedInBackground, 1);
histogram_tester.ExpectBucketCount(
"Memory.MovableStringParkingAction",
- MovableStringImpl::ParkingAction::kUnparkedInForeground, 1);
+ ParkableStringImpl::ParkingAction::kUnparkedInForeground, 1);
}
-TEST_F(MovableStringTest, TableMultiple) {
+TEST_F(ParkableStringTest, TableMultiple) {
base::HistogramTester histogram_tester;
size_t size_kb = 20;
std::vector<char> data(size_kb * 1000, 'a');
- MovableString movable(String(data.data(), data.size()).ReleaseImpl());
- MovableString movable2(String(data.data(), data.size()).ReleaseImpl());
+ ParkableString parkable(String(data.data(), data.size()).ReleaseImpl());
+ ParkableString parkable2(String(data.data(), data.size()).ReleaseImpl());
- auto& table = MovableStringTable::Instance();
+ auto& table = ParkableStringTable::Instance();
EXPECT_EQ(2u, table.table_.size());
- movable2 = MovableString();
+ parkable2 = ParkableString();
EXPECT_EQ(1u, table.table_.size());
- MovableString copy = movable;
- movable = MovableString();
+ ParkableString copy = parkable;
+ parkable = ParkableString();
EXPECT_EQ(1u, table.table_.size());
- copy = MovableString();
+ copy = ParkableString();
EXPECT_EQ(0u, table.table_.size());
String str(data.data(), data.size());
- MovableString movable3(str.Impl());
+ ParkableString parkable3(str.Impl());
EXPECT_EQ(1u, table.table_.size());
// De-duplicated.
- MovableString other_movable3(str.Impl());
+ ParkableString other_parkable3(str.Impl());
EXPECT_EQ(1u, table.table_.size());
- EXPECT_EQ(movable3.Impl(), other_movable3.Impl());
+ EXPECT_EQ(parkable3.Impl(), other_parkable3.Impl());
// If all the references to a string are in the table, park it.
str = String();
table.SetRendererBackgrounded(true);
ASSERT_TRUE(table.IsRendererBackgrounded());
table.MaybeParkAll();
- EXPECT_TRUE(movable3.Impl()->is_parked());
+ EXPECT_TRUE(parkable3.Impl()->is_parked());
// Only drop it from the table when the last one is gone.
- movable3 = MovableString();
+ parkable3 = ParkableString();
EXPECT_EQ(1u, table.table_.size());
- other_movable3 = MovableString();
+ other_parkable3 = ParkableString();
EXPECT_EQ(0u, table.table_.size());
histogram_tester.ExpectUniqueSample("Memory.MovableStringsCount", 1, 1);
@@ -179,7 +179,7 @@ TEST_F(MovableStringTest, TableMultiple) {
histogram_tester.ExpectTotalCount("Memory.MovableStringParkingAction", 1);
histogram_tester.ExpectBucketCount(
"Memory.MovableStringParkingAction",
- MovableStringImpl::ParkingAction::kParkedInBackground, 1);
+ ParkableStringImpl::ParkingAction::kParkedInBackground, 1);
}
-} // namespace WTF
+} // namespace blink
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
index 1506c3a3e18..ef9e174ec04 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/script_promise_properties.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/script_promise_properties.h
@@ -6,13 +6,14 @@
#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, kReleased##__VA_ARGS__) \
- P(ScriptPromise, kUserChoice##__VA_ARGS__) \
+#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, 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_wrappable_marking_visitor.cc b/chromium/third_party/blink/renderer/platform/bindings/script_wrappable_marking_visitor.cc
index 2ab286e5e56..99e4ae111d2 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/script_wrappable_marking_visitor.cc
+++ b/chromium/third_party/blink/renderer/platform/bindings/script_wrappable_marking_visitor.cc
@@ -7,6 +7,7 @@
#include "base/auto_reset.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/bindings/active_script_wrappable_base.h"
+#include "third_party/blink/renderer/platform/bindings/custom_wrappable.h"
#include "third_party/blink/renderer/platform/bindings/dom_wrapper_map.h"
#include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h"
#include "third_party/blink/renderer/platform/bindings/scoped_persistent.h"
@@ -19,7 +20,6 @@
#include "third_party/blink/renderer/platform/heap/heap_page.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
-#include "third_party/blink/renderer/platform/supplementable.h"
#include "third_party/blink/renderer/platform/wtf/time.h"
namespace blink {
@@ -42,10 +42,10 @@ void ScriptWrappableMarkingVisitor::TracePrologue() {
ThreadState::Current()->EnableWrapperTracingBarrier();
}
-void ScriptWrappableMarkingVisitor::EnterFinalPause() {
+void ScriptWrappableMarkingVisitor::EnterFinalPause(EmbedderStackState) {
CHECK(ThreadState::Current());
CHECK(!ThreadState::Current()->IsWrapperTracingForbidden());
- ActiveScriptWrappableBase::TraceActiveScriptWrappables(isolate_, this);
+ ActiveScriptWrappableBase::TraceActiveScriptWrappables(isolate(), this);
}
void ScriptWrappableMarkingVisitor::TraceEpilogue() {
@@ -53,7 +53,7 @@ void ScriptWrappableMarkingVisitor::TraceEpilogue() {
CHECK(!ThreadState::Current()->IsWrapperTracingForbidden());
DCHECK(marking_deque_.IsEmpty());
#if DCHECK_IS_ON()
- ScriptWrappableVisitorVerifier verifier;
+ ScriptWrappableVisitorVerifier verifier(ThreadState::Current());
for (auto& marking_data : verifier_deque_) {
// Check that all children of this object are marked.
marking_data.Trace(&verifier);
@@ -157,38 +157,28 @@ void ScriptWrappableMarkingVisitor::PerformLazyCleanup(TimeTicks deadline) {
void ScriptWrappableMarkingVisitor::RegisterV8Reference(
const std::pair<void*, void*>& internal_fields) {
- if (!tracing_in_progress_) {
- return;
- }
+ DCHECK(tracing_in_progress_);
WrapperTypeInfo* wrapper_type_info =
reinterpret_cast<WrapperTypeInfo*>(internal_fields.first);
if (wrapper_type_info->gin_embedder != gin::GinEmbedder::kEmbedderBlink) {
return;
}
- DCHECK(wrapper_type_info->wrapper_class_id == WrapperTypeInfo::kNodeClassId ||
- wrapper_type_info->wrapper_class_id ==
- WrapperTypeInfo::kObjectClassId);
- ScriptWrappable* script_wrappable =
- reinterpret_cast<ScriptWrappable*>(internal_fields.second);
- TraceWithWrappers(script_wrappable);
+ wrapper_type_info->TraceWithWrappers(this, internal_fields.second);
}
void ScriptWrappableMarkingVisitor::RegisterV8References(
const std::vector<std::pair<void*, void*>>&
internal_fields_of_potential_wrappers) {
CHECK(ThreadState::Current());
- // TODO(hlopko): Visit the vector in the V8 instead of passing it over if
- // there is no performance impact
for (auto& pair : internal_fields_of_potential_wrappers) {
RegisterV8Reference(pair);
}
}
-bool ScriptWrappableMarkingVisitor::AdvanceTracing(
- double deadline_in_ms,
- v8::EmbedderHeapTracer::AdvanceTracingActions actions) {
+bool ScriptWrappableMarkingVisitor::AdvanceTracing(double deadline_in_ms) {
+ constexpr int kObjectsBeforeInterrupt = 100;
// Do not drain the marking deque in a state where we can generally not
// perform a GC. This makes sure that TraceTraits and friends find
// themselves in a well-defined environment, e.g., properly set up vtables.
@@ -198,15 +188,15 @@ bool ScriptWrappableMarkingVisitor::AdvanceTracing(
base::AutoReset<bool>(&advancing_tracing_, true);
TimeTicks deadline =
TimeTicks() + TimeDelta::FromMillisecondsD(deadline_in_ms);
- while (actions.force_completion ==
- v8::EmbedderHeapTracer::ForceCompletionAction::FORCE_COMPLETION ||
- WTF::CurrentTimeTicks() < deadline) {
- if (marking_deque_.IsEmpty()) {
- return false;
+ while (deadline.is_max() || WTF::CurrentTimeTicks() < deadline) {
+ for (int objects = 0; objects++ < kObjectsBeforeInterrupt;) {
+ if (marking_deque_.IsEmpty()) {
+ return true;
+ }
+ marking_deque_.TakeFirst().Trace(this);
}
- marking_deque_.TakeFirst().Trace(this);
}
- return true;
+ return false;
}
void ScriptWrappableMarkingVisitor::MarkWrapperHeader(
@@ -223,8 +213,10 @@ void ScriptWrappableMarkingVisitor::MarkWrapperHeader(
void ScriptWrappableMarkingVisitor::WriteBarrier(
v8::Isolate* isolate,
const TraceWrapperV8Reference<v8::Value>& dst_object) {
+ if (dst_object.IsEmpty() || !ThreadState::IsAnyWrapperTracing())
+ return;
ScriptWrappableMarkingVisitor* visitor = CurrentVisitor(isolate);
- if (dst_object.IsEmpty() || !visitor->WrapperTracingInProgress())
+ if (!visitor->WrapperTracingInProgress())
return;
// Conservatively assume that the source object containing |dst_object| is
@@ -236,13 +228,29 @@ void ScriptWrappableMarkingVisitor::WriteBarrier(
v8::Isolate* isolate,
DOMWrapperMap<ScriptWrappable>* wrapper_map,
ScriptWrappable* key) {
+ if (!ThreadState::IsAnyWrapperTracing())
+ return;
ScriptWrappableMarkingVisitor* visitor = CurrentVisitor(isolate);
if (!visitor->WrapperTracingInProgress())
return;
+
// Conservatively assume that the source object key is marked.
visitor->Trace(wrapper_map, key);
}
+void ScriptWrappableMarkingVisitor::WriteBarrier(
+ v8::Isolate* isolate,
+ const WrapperTypeInfo* wrapper_type_info,
+ void* object) {
+ if (!ThreadState::IsAnyWrapperTracing())
+ return;
+ ScriptWrappableMarkingVisitor* visitor = CurrentVisitor(isolate);
+ if (!visitor->WrapperTracingInProgress())
+ return;
+
+ wrapper_type_info->TraceWithWrappers(visitor, object);
+}
+
void ScriptWrappableMarkingVisitor::Visit(
const TraceWrapperV8Reference<v8::Value>& traced_wrapper) {
// The write barrier may try to mark a wrapper because cleanup is still
@@ -250,7 +258,7 @@ void ScriptWrappableMarkingVisitor::Visit(
// requires us to bail out here when tracing is not in progress.
if (!tracing_in_progress_ || traced_wrapper.Get().IsEmpty())
return;
- traced_wrapper.Get().RegisterExternalReference(isolate_);
+ traced_wrapper.Get().RegisterExternalReference(isolate());
}
void ScriptWrappableMarkingVisitor::VisitWithWrappers(
@@ -275,6 +283,8 @@ void ScriptWrappableMarkingVisitor::VisitBackingStoreStrongly(
void* object,
void** object_slot,
TraceDescriptor desc) {
+ if (!object)
+ return;
desc.callback(this, desc.base_object_payload);
}
diff --git a/chromium/third_party/blink/renderer/platform/bindings/script_wrappable_marking_visitor.h b/chromium/third_party/blink/renderer/platform/bindings/script_wrappable_marking_visitor.h
index 4050f645e64..3fa4069005f 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/script_wrappable_marking_visitor.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/script_wrappable_marking_visitor.h
@@ -24,6 +24,7 @@ class ScriptWrappable;
class ScriptWrappableVisitor;
template <typename T>
class TraceWrapperV8Reference;
+struct WrapperTypeInfo;
// ScriptWrappableVisitor is used to trace through Blink's heap to find all
// reachable wrappers. V8 calls this visitor during its garbage collection,
@@ -56,6 +57,8 @@ class PLATFORM_EXPORT ScriptWrappableMarkingVisitor
template <typename T>
inline static void WriteBarrier(const T* dst_object);
+ static void WriteBarrier(v8::Isolate*, const WrapperTypeInfo*, void*);
+
static void WriteBarrier(v8::Isolate*,
const TraceWrapperV8Reference<v8::Value>&);
@@ -63,26 +66,24 @@ class PLATFORM_EXPORT ScriptWrappableMarkingVisitor
DOMWrapperMap<ScriptWrappable>*,
ScriptWrappable* key);
- ScriptWrappableMarkingVisitor(v8::Isolate* isolate) : isolate_(isolate){};
+ explicit ScriptWrappableMarkingVisitor(ThreadState* thread_state)
+ : ScriptWrappableVisitor(thread_state) {}
~ScriptWrappableMarkingVisitor() override;
bool WrapperTracingInProgress() const { return tracing_in_progress_; }
// v8::EmbedderHeapTracer interface.
-
void TracePrologue() override;
void RegisterV8References(const std::vector<std::pair<void*, void*>>&
internal_fields_of_potential_wrappers) override;
void RegisterV8Reference(const std::pair<void*, void*>& internal_fields);
- bool AdvanceTracing(double deadline_in_ms,
- v8::EmbedderHeapTracer::AdvanceTracingActions) override;
+ bool AdvanceTracing(double deadline_in_ms) override;
void TraceEpilogue() override;
void AbortTracing() override;
- void EnterFinalPause() override;
+ void EnterFinalPause(EmbedderStackState) override;
size_t NumberOfWrappersToTrace() override;
// ScriptWrappableVisitor interface.
-
void Visit(const TraceWrapperV8Reference<v8::Value>&) override;
void VisitWithWrappers(void*, TraceDescriptor) override;
void Visit(DOMWrapperMap<ScriptWrappable>*,
@@ -94,8 +95,6 @@ class PLATFORM_EXPORT ScriptWrappableMarkingVisitor
protected:
using Visitor::Visit;
- v8::Isolate* isolate() const { return isolate_; }
-
private:
class MarkingDequeItem {
public:
@@ -192,7 +191,6 @@ class PLATFORM_EXPORT ScriptWrappableMarkingVisitor
// - objects this headers belong to are invalidated by the oilpan GC in
// invalidateDeadObjectsInMarkingDeque.
WTF::Vector<HeapObjectHeader*> headers_to_unmark_;
- v8::Isolate* isolate_;
FRIEND_TEST_ALL_PREFIXES(ScriptWrappableMarkingVisitorTest, MixinTracing);
FRIEND_TEST_ALL_PREFIXES(ScriptWrappableMarkingVisitorTest,
diff --git a/chromium/third_party/blink/renderer/platform/bindings/script_wrappable_visitor.h b/chromium/third_party/blink/renderer/platform/bindings/script_wrappable_visitor.h
index 4caa74fcc81..ab4e527755d 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/script_wrappable_visitor.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/script_wrappable_visitor.h
@@ -15,7 +15,8 @@ namespace blink {
// references related to wrappers.
class PLATFORM_EXPORT ScriptWrappableVisitor : public Visitor {
public:
- ScriptWrappableVisitor() : Visitor(ThreadState::Current()) {}
+ explicit ScriptWrappableVisitor(ThreadState* thread_state)
+ : Visitor(thread_state) {}
// Unused blink::Visitor overrides. Derived visitors should still override
// the cross-component visitation methods. See Visitor documentation.
@@ -30,7 +31,8 @@ class PLATFORM_EXPORT ScriptWrappableVisitor : public Visitor {
WeakCallback,
void*) final {}
void VisitBackingStoreOnly(void*, void**) final {}
- void RegisterBackingStoreCallback(void*, MovingObjectCallback, void*) final {}
+ void RegisterBackingStoreCallback(void**, MovingObjectCallback, void*) final {
+ }
void RegisterWeakCallback(void*, WeakCallback) final {}
protected:
diff --git a/chromium/third_party/blink/renderer/platform/bindings/script_wrappable_visitor_verifier.h b/chromium/third_party/blink/renderer/platform/bindings/script_wrappable_visitor_verifier.h
index 84724bc686d..170327b3abc 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/script_wrappable_visitor_verifier.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/script_wrappable_visitor_verifier.h
@@ -16,6 +16,9 @@ namespace blink {
// is also marked.
class ScriptWrappableVisitorVerifier final : public ScriptWrappableVisitor {
public:
+ ScriptWrappableVisitorVerifier(ThreadState* thread_state)
+ : ScriptWrappableVisitor(thread_state) {}
+
void Visit(const TraceWrapperV8Reference<v8::Value>&) final {}
void VisitWithWrappers(void* object, TraceDescriptor descriptor) final {
diff --git a/chromium/third_party/blink/renderer/platform/bindings/string_resource.cc b/chromium/third_party/blink/renderer/platform/bindings/string_resource.cc
index 3be41ac09ee..d7b89ce8bcc 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/string_resource.cc
+++ b/chromium/third_party/blink/renderer/platform/bindings/string_resource.cc
@@ -12,7 +12,7 @@ template <class StringClass>
struct StringTraits {
static const StringClass& FromStringResource(StringResourceBase*);
template <typename V8StringTrait>
- static StringClass FromV8String(v8::Local<v8::String>, int);
+ static StringClass FromV8String(v8::Isolate*, v8::Local<v8::String>, int);
};
template <>
@@ -21,7 +21,7 @@ struct StringTraits<String> {
return resource->GetWTFString();
}
template <typename V8StringTrait>
- static String FromV8String(v8::Local<v8::String>, int);
+ static String FromV8String(v8::Isolate*, v8::Local<v8::String>, int);
};
template <>
@@ -30,39 +30,43 @@ struct StringTraits<AtomicString> {
return resource->GetAtomicString();
}
template <typename V8StringTrait>
- static AtomicString FromV8String(v8::Local<v8::String>, int);
+ static AtomicString FromV8String(v8::Isolate*, v8::Local<v8::String>, int);
};
struct V8StringTwoBytesTrait {
typedef UChar CharType;
- ALWAYS_INLINE static void Write(v8::Local<v8::String> v8_string,
+ ALWAYS_INLINE static void Write(v8::Isolate* isolate,
+ v8::Local<v8::String> v8_string,
CharType* buffer,
int length) {
- v8_string->Write(reinterpret_cast<uint16_t*>(buffer), 0, length);
+ v8_string->Write(isolate, reinterpret_cast<uint16_t*>(buffer), 0, length);
}
};
struct V8StringOneByteTrait {
typedef LChar CharType;
- ALWAYS_INLINE static void Write(v8::Local<v8::String> v8_string,
+ ALWAYS_INLINE static void Write(v8::Isolate* isolate,
+ v8::Local<v8::String> v8_string,
CharType* buffer,
int length) {
- v8_string->WriteOneByte(buffer, 0, length);
+ v8_string->WriteOneByte(isolate, buffer, 0, length);
}
};
template <typename V8StringTrait>
-String StringTraits<String>::FromV8String(v8::Local<v8::String> v8_string,
+String StringTraits<String>::FromV8String(v8::Isolate* isolate,
+ v8::Local<v8::String> v8_string,
int length) {
DCHECK(v8_string->Length() == length);
typename V8StringTrait::CharType* buffer;
String result = String::CreateUninitialized(length, buffer);
- V8StringTrait::Write(v8_string, buffer, length);
+ V8StringTrait::Write(isolate, v8_string, buffer, length);
return result;
}
template <typename V8StringTrait>
AtomicString StringTraits<AtomicString>::FromV8String(
+ v8::Isolate* isolate,
v8::Local<v8::String> v8_string,
int length) {
DCHECK(v8_string->Length() == length);
@@ -70,12 +74,12 @@ AtomicString StringTraits<AtomicString>::FromV8String(
32 / sizeof(typename V8StringTrait::CharType);
if (length <= kInlineBufferSize) {
typename V8StringTrait::CharType inline_buffer[kInlineBufferSize];
- V8StringTrait::Write(v8_string, inline_buffer, length);
+ V8StringTrait::Write(isolate, v8_string, inline_buffer, length);
return AtomicString(inline_buffer, static_cast<unsigned>(length));
}
typename V8StringTrait::CharType* buffer;
String string = String::CreateUninitialized(length, buffer);
- V8StringTrait::Write(v8_string, buffer, length);
+ V8StringTrait::Write(isolate, v8_string, buffer, length);
return AtomicString(string);
}
@@ -101,11 +105,13 @@ StringType ToBlinkString(v8::Local<v8::String> v8_string,
if (UNLIKELY(!length))
return StringType("");
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
bool one_byte = v8_string->ContainsOnlyOneByte();
- StringType result(one_byte ? StringTraits<StringType>::template FromV8String<
- V8StringOneByteTrait>(v8_string, length)
- : StringTraits<StringType>::template FromV8String<
- V8StringTwoBytesTrait>(v8_string, length));
+ StringType result(
+ one_byte ? StringTraits<StringType>::template FromV8String<
+ V8StringOneByteTrait>(isolate, v8_string, length)
+ : StringTraits<StringType>::template FromV8String<
+ V8StringTwoBytesTrait>(isolate, v8_string, length));
if (external != kExternalize || !v8_string->CanMakeExternal())
return result;
diff --git a/chromium/third_party/blink/renderer/platform/bindings/string_resource.h b/chromium/third_party/blink/renderer/platform/bindings/string_resource.h
index 41b0f5a2a59..06a0b1b2f4a 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/string_resource.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/string_resource.h
@@ -6,10 +6,10 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_STRING_RESOURCE_H_
#include "base/macros.h"
+#include "third_party/blink/renderer/platform/bindings/parkable_string.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
-#include "third_party/blink/renderer/platform/wtf/text/movable_string.h"
#include "third_party/blink/renderer/platform/wtf/threading.h"
#include "v8/include/v8.h"
@@ -40,8 +40,8 @@ class StringResourceBase {
string.CharactersSizeInBytes());
}
- explicit StringResourceBase(const MovableString& string)
- : movable_string_(string) {
+ explicit StringResourceBase(const ParkableString& string)
+ : parkable_string_(string) {
#if DCHECK_IS_ON()
thread_id_ = WTF::CurrentThread();
#endif
@@ -64,10 +64,10 @@ class StringResourceBase {
}
const String& GetWTFString() {
- if (!movable_string_.IsNull()) {
+ if (!parkable_string_.IsNull()) {
DCHECK(plain_string_.IsNull());
DCHECK(atomic_string_.IsNull());
- return movable_string_.ToString();
+ return parkable_string_.ToString();
}
return plain_string_;
}
@@ -76,10 +76,10 @@ class StringResourceBase {
#if DCHECK_IS_ON()
DCHECK(thread_id_ == WTF::CurrentThread());
#endif
- if (!movable_string_.IsNull()) {
+ if (!parkable_string_.IsNull()) {
DCHECK(plain_string_.IsNull());
DCHECK(atomic_string_.IsNull());
- return AtomicString(movable_string_.ToString());
+ return AtomicString(parkable_string_.ToString());
}
if (atomic_string_.IsNull()) {
atomic_string_ = AtomicString(plain_string_);
@@ -102,9 +102,9 @@ class StringResourceBase {
// the original string alive because v8 may keep derived pointers
// into that string.
AtomicString atomic_string_;
- // If this string is movable, its value is held here, and the other
+ // If this string is parkable, its value is held here, and the other
// members above are null.
- MovableString movable_string_;
+ ParkableString parkable_string_;
private:
#if DCHECK_IS_ON()
@@ -155,46 +155,46 @@ class StringResource8 final : public StringResourceBase,
DISALLOW_COPY_AND_ASSIGN(StringResource8);
};
-class MovableStringResource16 final
+class ParkableStringResource16 final
: public StringResourceBase,
public v8::String::ExternalStringResource {
public:
- explicit MovableStringResource16(const MovableString& string)
+ explicit ParkableStringResource16(const ParkableString& string)
: StringResourceBase(string) {
- DCHECK(!movable_string_.Is8Bit());
+ DCHECK(!parkable_string_.Is8Bit());
}
- // V8 external resources are "compressible", not "movable".
+ // V8 external resources are "compressible", not "parkable".
bool IsCompressible() const override { return true; }
- size_t length() const override { return movable_string_.length(); }
+ size_t length() const override { return parkable_string_.length(); }
const uint16_t* data() const override {
- return reinterpret_cast<const uint16_t*>(movable_string_.Characters16());
+ return reinterpret_cast<const uint16_t*>(parkable_string_.Characters16());
}
- DISALLOW_COPY_AND_ASSIGN(MovableStringResource16);
+ DISALLOW_COPY_AND_ASSIGN(ParkableStringResource16);
};
-class MovableStringResource8 final
+class ParkableStringResource8 final
: public StringResourceBase,
public v8::String::ExternalOneByteStringResource {
public:
- explicit MovableStringResource8(const MovableString& string)
+ explicit ParkableStringResource8(const ParkableString& string)
: StringResourceBase(string) {
- DCHECK(movable_string_.Is8Bit());
+ DCHECK(parkable_string_.Is8Bit());
}
- // V8 external resources are "compressible", not "movable".
+ // V8 external resources are "compressible", not "parkable".
bool IsCompressible() const override { return true; }
- size_t length() const override { return movable_string_.length(); }
+ size_t length() const override { return parkable_string_.length(); }
const char* data() const override {
- return reinterpret_cast<const char*>(movable_string_.Characters8());
+ return reinterpret_cast<const char*>(parkable_string_.Characters8());
}
- DISALLOW_COPY_AND_ASSIGN(MovableStringResource8);
+ DISALLOW_COPY_AND_ASSIGN(ParkableStringResource8);
};
enum ExternalMode { kExternalize, kDoNotExternalize };
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 1595d8dec5d..3746e29ea89 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/to_v8.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/to_v8.h
@@ -11,6 +11,7 @@
#include <utility>
#include "base/optional.h"
+#include "third_party/blink/renderer/platform/bindings/callback_function_base.h"
#include "third_party/blink/renderer/platform/bindings/callback_interface_base.h"
#include "third_party/blink/renderer/platform/bindings/dom_data_store.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
@@ -37,6 +38,20 @@ inline v8::Local<v8::Value> ToV8(ScriptWrappable* impl,
return wrapper;
}
+// Callback function
+
+inline v8::Local<v8::Value> ToV8(CallbackFunctionBase* callback,
+ v8::Local<v8::Object> creation_context,
+ v8::Isolate* isolate) {
+ // |creation_context| is intentionally ignored. Callback functions are not
+ // wrappers nor clonable. ToV8 on a callback function must be used only when
+ // it's the same origin-domain in the same world.
+ DCHECK(!callback || (callback->CallbackRelevantScriptState()->GetContext() ==
+ creation_context->CreationContext()));
+ return callback ? callback->CallbackFunction().As<v8::Value>()
+ : v8::Null(isolate).As<v8::Value>();
+}
+
// Callback interface
inline v8::Local<v8::Value> ToV8(CallbackInterfaceBase* callback,
@@ -191,14 +206,14 @@ inline v8::Local<v8::Value> ToV8SequenceInternal(
v8::Local<v8::Object> creation_context,
v8::Isolate*);
-template <typename T, size_t inlineCapacity>
+template <typename T, wtf_size_t inlineCapacity>
inline v8::Local<v8::Value> ToV8(const Vector<T, inlineCapacity>& value,
v8::Local<v8::Object> creation_context,
v8::Isolate* isolate) {
return ToV8SequenceInternal(value, creation_context, isolate);
}
-template <typename T, size_t inlineCapacity>
+template <typename T, wtf_size_t inlineCapacity>
inline v8::Local<v8::Value> ToV8(const HeapVector<T, inlineCapacity>& value,
v8::Local<v8::Object> creation_context,
v8::Isolate* isolate) {
diff --git a/chromium/third_party/blink/renderer/platform/bindings/trace_wrapper_v8_string.cc b/chromium/third_party/blink/renderer/platform/bindings/trace_wrapper_v8_string.cc
index af5b491f2b3..af72eccff2f 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/trace_wrapper_v8_string.cc
+++ b/chromium/third_party/blink/renderer/platform/bindings/trace_wrapper_v8_string.cc
@@ -12,9 +12,10 @@ void TraceWrapperV8String::Concat(v8::Isolate* isolate, const String& string) {
DCHECK(isolate);
v8::HandleScope handle_scope(isolate);
v8::Local<v8::String> target_string =
- (string_.IsEmpty()) ? V8String(isolate, string)
- : v8::String::Concat(string_.NewLocal(isolate),
- V8String(isolate, string));
+ (string_.IsEmpty())
+ ? V8String(isolate, string)
+ : v8::String::Concat(isolate, string_.NewLocal(isolate),
+ V8String(isolate, string));
string_.Set(isolate, target_string);
}
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 180bc217978..f5209d21c8a 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/v8_binding.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/v8_binding.h
@@ -291,7 +291,7 @@ inline v8::Local<v8::Value> V8StringOrNull(v8::Isolate* isolate,
}
inline v8::Local<v8::String> V8String(v8::Isolate* isolate,
- const MovableString& string) {
+ const ParkableString& string) {
if (string.IsNull())
return v8::String::Empty(isolate);
return V8PerIsolateData::From(isolate)->GetStringCache()->V8ExternalString(
diff --git a/chromium/third_party/blink/renderer/platform/bindings/v8_dom_wrapper.cc b/chromium/third_party/blink/renderer/platform/bindings/v8_dom_wrapper.cc
index 12104ab2a26..adee1ee25f7 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/v8_dom_wrapper.cc
+++ b/chromium/third_party/blink/renderer/platform/bindings/v8_dom_wrapper.cc
@@ -94,10 +94,11 @@ bool V8DOMWrapper::HasInternalFieldsSet(v8::Local<v8::Value> value) {
if (object->InternalFieldCount() < kV8DefaultWrapperInternalFieldCount)
return false;
- const ScriptWrappable* untrusted_script_wrappable = ToScriptWrappable(object);
+ // The untyped wrappable can either be ScriptWrappable or CustomWrappable.
+ const void* untrused_wrappable = ToUntypedWrappable(object);
const WrapperTypeInfo* untrusted_wrapper_type_info =
ToWrapperTypeInfo(object);
- return untrusted_script_wrappable && untrusted_wrapper_type_info &&
+ return untrused_wrappable && untrusted_wrapper_type_info &&
untrusted_wrapper_type_info->gin_embedder == gin::kEmbedderBlink;
}
diff --git a/chromium/third_party/blink/renderer/platform/bindings/v8_dom_wrapper.h b/chromium/third_party/blink/renderer/platform/bindings/v8_dom_wrapper.h
index dbcdd80a548..a98d4f04938 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/v8_dom_wrapper.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/v8_dom_wrapper.h
@@ -32,9 +32,11 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_V8_DOM_WRAPPER_H_
#include "base/stl_util.h"
+#include "third_party/blink/renderer/platform/bindings/custom_wrappable.h"
#include "third_party/blink/renderer/platform/bindings/dom_data_store.h"
#include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+#include "third_party/blink/renderer/platform/bindings/script_wrappable_marking_visitor.h"
#include "third_party/blink/renderer/platform/bindings/v8_binding.h"
#include "third_party/blink/renderer/platform/bindings/wrapper_creation_security_check.h"
#include "third_party/blink/renderer/platform/platform_export.h"
@@ -67,10 +69,24 @@ class V8DOMWrapper {
ScriptWrappable*,
const WrapperTypeInfo*,
v8::Local<v8::Object> wrapper);
- static void SetNativeInfo(v8::Isolate*,
- v8::Local<v8::Object>,
- const WrapperTypeInfo*,
- ScriptWrappable*);
+ static void AssociateObjectWithWrapper(v8::Isolate*,
+ CustomWrappable*,
+ const WrapperTypeInfo*,
+ v8::Local<v8::Object> wrapper);
+ static void SetNativeInfo(v8::Isolate* isolate,
+ v8::Local<v8::Object> wrapper,
+ const WrapperTypeInfo* wrapper_type_info,
+ ScriptWrappable* script_wrappable) {
+ SetNativeInfoInternal(isolate, wrapper, wrapper_type_info,
+ script_wrappable);
+ }
+ static void SetNativeInfo(v8::Isolate* isolate,
+ v8::Local<v8::Object> wrapper,
+ const WrapperTypeInfo* wrapper_type_info,
+ CustomWrappable* custom_wrappable) {
+ SetNativeInfoInternal(isolate, wrapper, wrapper_type_info,
+ custom_wrappable);
+ }
static void ClearNativeInfo(v8::Isolate*, v8::Local<v8::Object>);
// hasInternalFieldsSet only checks if the value has the internal fields for
@@ -78,29 +94,31 @@ class V8DOMWrapper {
// value may not be a Blink's wrapper object. In order to make sure of it,
// Use isWrapper function instead.
PLATFORM_EXPORT static bool HasInternalFieldsSet(v8::Local<v8::Value>);
+
+ private:
+ static void SetNativeInfoInternal(v8::Isolate*,
+ v8::Local<v8::Object>,
+ const WrapperTypeInfo*,
+ void*);
};
-inline void V8DOMWrapper::SetNativeInfo(
+inline void V8DOMWrapper::SetNativeInfoInternal(
v8::Isolate* isolate,
v8::Local<v8::Object> wrapper,
const WrapperTypeInfo* wrapper_type_info,
- ScriptWrappable* script_wrappable) {
+ void* wrappable) {
DCHECK_GE(wrapper->InternalFieldCount(), 2);
- DCHECK(script_wrappable);
+ DCHECK(wrappable);
DCHECK(wrapper_type_info);
int indices[] = {kV8DOMWrapperObjectIndex, kV8DOMWrapperTypeIndex};
- void* values[] = {script_wrappable,
- const_cast<WrapperTypeInfo*>(wrapper_type_info)};
+ void* values[] = {wrappable, const_cast<WrapperTypeInfo*>(wrapper_type_info)};
wrapper->SetAlignedPointerInInternalFields(base::size(indices), indices,
values);
- auto* per_isolate_data = V8PerIsolateData::From(isolate);
- // We notify ScriptWrappableVisitor about the new wrapper association,
- // so the visitor can make sure to trace the association (in case it is
- // currently tracing). Because of some optimizations, V8 will not
- // necessarily detect wrappers created during its incremental marking.
- per_isolate_data->GetScriptWrappableMarkingVisitor()->RegisterV8Reference(
- std::make_pair(const_cast<WrapperTypeInfo*>(wrapper_type_info),
- script_wrappable));
+ // The following write barrier is necessary as V8 might not see the newly
+ // created object during garbage collection, e.g., when the object is black
+ // allocated.
+ ScriptWrappableMarkingVisitor::WriteBarrier(isolate, wrapper_type_info,
+ wrappable);
}
inline void V8DOMWrapper::ClearNativeInfo(v8::Isolate* isolate,
@@ -127,6 +145,19 @@ inline v8::Local<v8::Object> V8DOMWrapper::AssociateObjectWithWrapper(
return wrapper;
}
+inline void V8DOMWrapper::AssociateObjectWithWrapper(
+ v8::Isolate* isolate,
+ CustomWrappable* impl,
+ const WrapperTypeInfo* wrapper_type_info,
+ v8::Local<v8::Object> wrapper) {
+ RUNTIME_CALL_TIMER_SCOPE(
+ isolate, RuntimeCallStats::CounterId::kAssociateObjectWithWrapper);
+ WrapperTypeInfo::WrapperCreated();
+ SetNativeInfo(isolate, wrapper, wrapper_type_info, impl);
+ DCHECK(HasInternalFieldsSet(wrapper));
+ SECURITY_CHECK(ToCustomWrappable(wrapper) == impl);
+}
+
class V8WrapperInstantiationScope {
STACK_ALLOCATED();
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 44cb5a9489f..481863a52ef 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
@@ -38,6 +38,7 @@
#include "third_party/blink/renderer/platform/bindings/dom_data_store.h"
#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
+#include "third_party/blink/renderer/platform/bindings/script_wrappable_marking_visitor.h"
#include "third_party/blink/renderer/platform/bindings/v8_binding.h"
#include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
#include "third_party/blink/renderer/platform/bindings/v8_private_property.h"
@@ -66,10 +67,13 @@ V8PerIsolateData::V8PerIsolateData(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
V8ContextSnapshotMode v8_context_snapshot_mode)
: v8_context_snapshot_mode_(v8_context_snapshot_mode),
- isolate_holder_(task_runner,
- gin::IsolateHolder::kSingleThread,
- IsMainThread() ? gin::IsolateHolder::kDisallowAtomicsWait
- : gin::IsolateHolder::kAllowAtomicsWait),
+ isolate_holder_(
+ task_runner,
+ gin::IsolateHolder::kSingleThread,
+ IsMainThread() ? gin::IsolateHolder::kDisallowAtomicsWait
+ : gin::IsolateHolder::kAllowAtomicsWait,
+ IsMainThread() ? gin::IsolateHolder::IsolateType::kBlinkMainThread
+ : gin::IsolateHolder::IsolateType::kBlinkWorkerThread),
interface_template_map_for_v8_context_snapshot_(GetIsolate()),
string_cache_(std::make_unique<StringCache>(GetIsolate())),
private_property_(V8PrivateProperty::Create()),
@@ -77,6 +81,8 @@ V8PerIsolateData::V8PerIsolateData(
use_counter_disabled_(false),
is_handling_recursion_level_error_(false),
is_reporting_exception_(false),
+ script_wrappable_visitor_(
+ new ScriptWrappableMarkingVisitor(ThreadState::Current())),
runtime_call_stats_(base::DefaultTickClock::GetInstance()),
handled_near_v8_heap_limit_(false) {
// FIXME: Remove once all v8::Isolate::GetCurrent() calls are gone.
@@ -94,6 +100,7 @@ V8PerIsolateData::V8PerIsolateData()
isolate_holder_(Platform::Current()->MainThread()->GetTaskRunner(),
gin::IsolateHolder::kSingleThread,
gin::IsolateHolder::kAllowAtomicsWait,
+ gin::IsolateHolder::IsolateType::kBlinkMainThread,
gin::IsolateHolder::IsolateCreationMode::kCreateSnapshot),
interface_template_map_for_v8_context_snapshot_(GetIsolate()),
string_cache_(std::make_unique<StringCache>(GetIsolate())),
@@ -368,16 +375,4 @@ void V8PerIsolateData::AddActiveScriptWrappable(
active_script_wrappables_->insert(wrappable);
}
-void V8PerIsolateData::TemporaryScriptWrappableVisitorScope::
- SwapWithV8PerIsolateDataVisitor(
- std::unique_ptr<ScriptWrappableMarkingVisitor>& visitor) {
- ScriptWrappableMarkingVisitor* current = CurrentVisitor();
- if (current)
- ScriptWrappableMarkingVisitor::PerformCleanup(isolate_);
-
- V8PerIsolateData::From(isolate_)->script_wrappable_visitor_.swap(
- saved_visitor_);
- isolate_->SetEmbedderHeapTracer(CurrentVisitor());
-}
-
} // namespace blink
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 7788274e57c..a01a44708f3 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
@@ -200,41 +200,15 @@ class PLATFORM_EXPORT V8PerIsolateData {
return active_script_wrappables_.Get();
}
- class PLATFORM_EXPORT TemporaryScriptWrappableVisitorScope {
- WTF_MAKE_NONCOPYABLE(TemporaryScriptWrappableVisitorScope);
- STACK_ALLOCATED();
-
- public:
- TemporaryScriptWrappableVisitorScope(
- v8::Isolate* isolate,
- std::unique_ptr<ScriptWrappableMarkingVisitor> visitor)
- : isolate_(isolate), saved_visitor_(std::move(visitor)) {
- SwapWithV8PerIsolateDataVisitor(saved_visitor_);
- }
- ~TemporaryScriptWrappableVisitorScope() {
- SwapWithV8PerIsolateDataVisitor(saved_visitor_);
- }
-
- inline ScriptWrappableMarkingVisitor* CurrentVisitor() {
- return V8PerIsolateData::From(isolate_)
- ->GetScriptWrappableMarkingVisitor();
- }
-
- private:
- void SwapWithV8PerIsolateDataVisitor(
- std::unique_ptr<ScriptWrappableMarkingVisitor>&);
-
- v8::Isolate* isolate_;
- std::unique_ptr<ScriptWrappableMarkingVisitor> saved_visitor_;
- };
-
- void SetScriptWrappableMarkingVisitor(
- std::unique_ptr<ScriptWrappableMarkingVisitor> visitor) {
- script_wrappable_visitor_ = std::move(visitor);
- }
- ScriptWrappableMarkingVisitor* GetScriptWrappableMarkingVisitor() {
+ ScriptWrappableMarkingVisitor* GetScriptWrappableMarkingVisitor() const {
return script_wrappable_visitor_.get();
}
+
+ void SwapScriptWrappableMarkingVisitor(
+ std::unique_ptr<ScriptWrappableMarkingVisitor>& other) {
+ script_wrappable_visitor_.swap(other);
+ }
+
int IsNearV8HeapLimitHandled() { return handled_near_v8_heap_limit_; }
void HandledNearV8HeapLimit() { handled_near_v8_heap_limit_ = true; }
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 34ac38312c8..d74a5d34f06 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
@@ -51,8 +51,8 @@ class ScriptWrappable;
X(SameObject, PerformanceLongTaskTimingAttribution) \
X(SameObject, PushManagerSupportedContentEncodings) \
X(V8ErrorHandler, ErrorHandler) \
- X(V8EventListener, AttributeListener) \
- X(V8EventListener, Listener) \
+ X(V8EventListenerOrEventHandler, AttributeListener) \
+ X(V8EventListenerOrEventHandler, Listener) \
SCRIPT_PROMISE_PROPERTIES(X, Promise) \
SCRIPT_PROMISE_PROPERTIES(X, Resolver)
diff --git a/chromium/third_party/blink/renderer/platform/bindings/v8_value_cache.cc b/chromium/third_party/blink/renderer/platform/bindings/v8_value_cache.cc
index 7fe6873e2e5..b19c1719b4f 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/v8_value_cache.cc
+++ b/chromium/third_party/blink/renderer/platform/bindings/v8_value_cache.cc
@@ -61,26 +61,26 @@ void StringCacheMapTraits::OnWeakCallback(
->InvalidateLastString();
}
-MovableStringCacheMapTraits::MapType*
-MovableStringCacheMapTraits::MapFromWeakCallbackInfo(
+ParkableStringCacheMapTraits::MapType*
+ParkableStringCacheMapTraits::MapFromWeakCallbackInfo(
const v8::WeakCallbackInfo<WeakCallbackDataType>& data) {
return &(V8PerIsolateData::From(data.GetIsolate())
->GetStringCache()
- ->movable_string_cache_);
+ ->parkable_string_cache_);
}
-void MovableStringCacheMapTraits::Dispose(v8::Isolate* isolate,
- v8::Global<v8::String> value,
- MovableStringImpl* key) {
+void ParkableStringCacheMapTraits::Dispose(v8::Isolate* isolate,
+ v8::Global<v8::String> value,
+ ParkableStringImpl* key) {
key->Release();
}
-void MovableStringCacheMapTraits::DisposeWeak(
+void ParkableStringCacheMapTraits::DisposeWeak(
const v8::WeakCallbackInfo<WeakCallbackDataType>& data) {
data.GetParameter()->Release();
}
-void MovableStringCacheMapTraits::OnWeakCallback(
+void ParkableStringCacheMapTraits::OnWeakCallback(
const v8::WeakCallbackInfo<WeakCallbackDataType>& data) {}
void StringCache::Dispose() {
@@ -114,9 +114,9 @@ static v8::Local<v8::String> MakeExternalString(v8::Isolate* isolate,
}
static v8::Local<v8::String> MakeExternalString(v8::Isolate* isolate,
- const MovableString& string) {
+ const ParkableString& string) {
if (string.Is8Bit()) {
- auto* string_resource = new MovableStringResource8(string);
+ auto* string_resource = new ParkableStringResource8(string);
v8::Local<v8::String> new_string;
if (!v8::String::NewExternalOneByte(isolate, string_resource)
.ToLocal(&new_string)) {
@@ -126,7 +126,7 @@ static v8::Local<v8::String> MakeExternalString(v8::Isolate* isolate,
return new_string;
}
- auto* string_resource = new MovableStringResource16(string);
+ auto* string_resource = new ParkableStringResource16(string);
v8::Local<v8::String> new_string;
if (!v8::String::NewExternalTwoByte(isolate, string_resource)
.ToLocal(&new_string)) {
@@ -157,12 +157,12 @@ v8::Local<v8::String> StringCache::V8ExternalStringSlow(
v8::Local<v8::String> StringCache::V8ExternalString(
v8::Isolate* isolate,
- const MovableString& string) {
+ const ParkableString& string) {
if (!string.length())
return v8::String::Empty(isolate);
- MovableStringCacheMapTraits::MapType::PersistentValueReference
- cached_v8_string = movable_string_cache_.GetReference(string.Impl());
+ ParkableStringCacheMapTraits::MapType::PersistentValueReference
+ cached_v8_string = parkable_string_cache_.GetReference(string.Impl());
if (!cached_v8_string.IsEmpty()) {
return cached_v8_string.NewLocal(isolate);
}
@@ -216,23 +216,23 @@ v8::Local<v8::String> StringCache::CreateStringAndInsertIntoCache(
v8::Local<v8::String> StringCache::CreateStringAndInsertIntoCache(
v8::Isolate* isolate,
- const MovableString& string) {
- MovableStringImpl* string_impl = string.Impl();
- DCHECK(!movable_string_cache_.Contains(string_impl));
+ const ParkableString& string) {
+ ParkableStringImpl* string_impl = string.Impl();
+ DCHECK(!parkable_string_cache_.Contains(string_impl));
DCHECK(string_impl->length());
v8::Local<v8::String> new_string =
- MakeExternalString(isolate, MovableString(string));
+ MakeExternalString(isolate, ParkableString(string));
DCHECK(!new_string.IsEmpty());
DCHECK(new_string->Length());
v8::UniquePersistent<v8::String> wrapper(isolate, new_string);
string_impl->AddRef();
- // MovableStringImpl objects are not cache in |string_cache_| or
+ // ParkableStringImpl objects are not cache in |string_cache_| or
// |last_string_impl_|.
- MovableStringCacheMapTraits::MapType::PersistentValueReference unused;
- movable_string_cache_.Set(string_impl, std::move(wrapper), &unused);
+ ParkableStringCacheMapTraits::MapType::PersistentValueReference unused;
+ parkable_string_cache_.Set(string_impl, std::move(wrapper), &unused);
return new_string;
}
diff --git a/chromium/third_party/blink/renderer/platform/bindings/v8_value_cache.h b/chromium/third_party/blink/renderer/platform/bindings/v8_value_cache.h
index 66ed25cdd8e..c9fde8c1deb 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/v8_value_cache.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/v8_value_cache.h
@@ -27,13 +27,13 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_V8_VALUE_CACHE_H_
#include "base/memory/scoped_refptr.h"
+#include "third_party/blink/renderer/platform/bindings/parkable_string.h"
#include "third_party/blink/renderer/platform/bindings/v8_global_value_map.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
#include "third_party/blink/renderer/platform/wtf/noncopyable.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
-#include "third_party/blink/renderer/platform/wtf/text/movable_string.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "v8/include/v8.h"
@@ -75,23 +75,23 @@ class StringCacheMapTraits
static void DisposeWeak(const v8::WeakCallbackInfo<WeakCallbackDataType>&);
};
-class MovableStringCacheMapTraits
- : public V8GlobalValueMapTraits<MovableStringImpl*,
+class ParkableStringCacheMapTraits
+ : public V8GlobalValueMapTraits<ParkableStringImpl*,
v8::String,
v8::kWeakWithParameter> {
- STATIC_ONLY(MovableStringCacheMapTraits);
+ STATIC_ONLY(ParkableStringCacheMapTraits);
public:
// Weak traits:
- typedef MovableStringImpl WeakCallbackDataType;
- typedef v8::GlobalValueMap<MovableStringImpl*,
+ typedef ParkableStringImpl WeakCallbackDataType;
+ typedef v8::GlobalValueMap<ParkableStringImpl*,
v8::String,
- MovableStringCacheMapTraits>
+ ParkableStringCacheMapTraits>
MapType;
static WeakCallbackDataType* WeakCallbackParameter(
MapType* map,
- MovableStringImpl* key,
+ ParkableStringImpl* key,
v8::Local<v8::String>& value) {
return key;
}
@@ -100,7 +100,7 @@ class MovableStringCacheMapTraits
static MapType* MapFromWeakCallbackInfo(
const v8::WeakCallbackInfo<WeakCallbackDataType>&);
- static MovableStringImpl* KeyFromWeakCallbackInfo(
+ static ParkableStringImpl* KeyFromWeakCallbackInfo(
const v8::WeakCallbackInfo<WeakCallbackDataType>& data) {
return data.GetParameter();
}
@@ -109,7 +109,7 @@ class MovableStringCacheMapTraits
static void Dispose(v8::Isolate*,
v8::Global<v8::String> value,
- MovableStringImpl* key);
+ ParkableStringImpl* key);
static void DisposeWeak(const v8::WeakCallbackInfo<WeakCallbackDataType>&);
};
@@ -124,7 +124,7 @@ class PLATFORM_EXPORT StringCache {
public:
explicit StringCache(v8::Isolate* isolate)
- : string_cache_(isolate), movable_string_cache_(isolate) {}
+ : string_cache_(isolate), parkable_string_cache_(isolate) {}
v8::Local<v8::String> V8ExternalString(v8::Isolate* isolate,
StringImpl* string_impl) {
@@ -135,7 +135,7 @@ class PLATFORM_EXPORT StringCache {
}
v8::Local<v8::String> V8ExternalString(v8::Isolate* isolate,
- const MovableString& string);
+ const ParkableString& string);
void SetReturnValueFromString(v8::ReturnValue<v8::Value> return_value,
StringImpl* string_impl) {
@@ -149,7 +149,7 @@ class PLATFORM_EXPORT StringCache {
void Dispose();
friend class StringCacheMapTraits;
- friend class MovableStringCacheMapTraits;
+ friend class ParkableStringCacheMapTraits;
private:
v8::Local<v8::String> V8ExternalStringSlow(v8::Isolate*, StringImpl*);
@@ -157,12 +157,12 @@ class PLATFORM_EXPORT StringCache {
v8::Local<v8::String> CreateStringAndInsertIntoCache(v8::Isolate*,
StringImpl*);
v8::Local<v8::String> CreateStringAndInsertIntoCache(v8::Isolate*,
- const MovableString&);
+ const ParkableString&);
void InvalidateLastString();
StringCacheMapTraits::MapType string_cache_;
StringCacheMapTraits::MapType::PersistentValueReference last_v8_string_;
- MovableStringCacheMapTraits::MapType movable_string_cache_;
+ ParkableStringCacheMapTraits::MapType parkable_string_cache_;
// Note: RefPtr is a must as we cache by StringImpl* equality, not identity
// hence lastStringImpl might be not a key of the cache (in sense of identity)
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 1788bf2a4ac..45c8cc662cc 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
@@ -4,6 +4,8 @@
#include "third_party/blink/renderer/platform/bindings/wrapper_type_info.h"
+#include "third_party/blink/renderer/platform/bindings/custom_wrappable.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_stats_collector.h"
@@ -25,4 +27,32 @@ void WrapperTypeInfo::WrapperDestroyed() {
stats_collector->IncreaseCollectedWrapperCount(1);
}
+void WrapperTypeInfo::Trace(Visitor* visitor, void* impl) const {
+ switch (wrapper_class_id) {
+ case WrapperTypeInfo::kNodeClassId:
+ case WrapperTypeInfo::kObjectClassId:
+ visitor->Trace(reinterpret_cast<ScriptWrappable*>(impl));
+ break;
+ case WrapperTypeInfo::kCustomWrappableId:
+ visitor->Trace(reinterpret_cast<CustomWrappable*>(impl));
+ break;
+ default:
+ NOTREACHED();
+ }
+}
+
+void WrapperTypeInfo::TraceWithWrappers(Visitor* visitor, void* impl) const {
+ switch (wrapper_class_id) {
+ case WrapperTypeInfo::kNodeClassId:
+ case WrapperTypeInfo::kObjectClassId:
+ visitor->TraceWithWrappers(reinterpret_cast<ScriptWrappable*>(impl));
+ break;
+ case WrapperTypeInfo::kCustomWrappableId:
+ visitor->TraceWithWrappers(reinterpret_cast<CustomWrappable*>(impl));
+ break;
+ default:
+ NOTREACHED();
+ }
+}
+
} // namespace blink
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 2e6899dce06..1a913f2be52 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
@@ -40,8 +40,10 @@
namespace blink {
class ActiveScriptWrappableBase;
+class CustomWrappable;
class DOMWrapperWorld;
class ScriptWrappable;
+class Visitor;
ScriptWrappable* ToScriptWrappable(
const v8::PersistentBase<v8::Object>& wrapper);
@@ -87,6 +89,7 @@ struct WrapperTypeInfo {
enum WrapperClassId {
kNodeClassId = 1, // NodeClassId must be smaller than ObjectClassId.
kObjectClassId,
+ kCustomWrappableId,
};
enum ActiveScriptWrappableInheritance {
@@ -143,6 +146,11 @@ struct WrapperTypeInfo {
kInheritFromActiveScriptWrappable;
}
+ // Garbage collection support for when the type depends the WrapperTypeInfo
+ // object.
+ PLATFORM_EXPORT void Trace(Visitor*, void*) const;
+ PLATFORM_EXPORT void TraceWithWrappers(Visitor*, void*) const;
+
// This field must be the first member of the struct WrapperTypeInfo.
// See also static_assert() in .cpp file.
const gin::GinEmbedder gin_embedder;
@@ -182,6 +190,23 @@ inline ScriptWrappable* ToScriptWrappable(v8::Local<v8::Object> wrapper) {
return GetInternalField<ScriptWrappable, kV8DOMWrapperObjectIndex>(wrapper);
}
+inline CustomWrappable* ToCustomWrappable(
+ const v8::PersistentBase<v8::Object>& wrapper) {
+ return GetInternalField<CustomWrappable, kV8DOMWrapperObjectIndex>(wrapper);
+}
+
+inline CustomWrappable* ToCustomWrappable(v8::Local<v8::Object> wrapper) {
+ return GetInternalField<CustomWrappable, kV8DOMWrapperObjectIndex>(wrapper);
+}
+
+inline void* ToUntypedWrappable(const v8::PersistentBase<v8::Object>& wrapper) {
+ return GetInternalField<void, kV8DOMWrapperObjectIndex>(wrapper);
+}
+
+inline void* ToUntypedWrappable(v8::Local<v8::Object> wrapper) {
+ return GetInternalField<void, kV8DOMWrapperObjectIndex>(wrapper);
+}
+
inline const WrapperTypeInfo* ToWrapperTypeInfo(
const v8::PersistentBase<v8::Object>& wrapper) {
return GetInternalField<WrapperTypeInfo, kV8DOMWrapperTypeIndex>(wrapper);
diff --git a/chromium/third_party/blink/renderer/platform/blob/BUILD.gn b/chromium/third_party/blink/renderer/platform/blob/BUILD.gn
index f6af4da29ae..b40abbee1c1 100644
--- a/chromium/third_party/blink/renderer/platform/blob/BUILD.gn
+++ b/chromium/third_party/blink/renderer/platform/blob/BUILD.gn
@@ -13,11 +13,9 @@ import("//third_party/blink/renderer/platform/platform.gni")
# another.
jumbo_source_set("generator") {
public_deps = [
- "//third_party/blink/public/mojom:mojom_platform_blink__generator",
- "//url/mojom:url_mojom_gurl_blink__generator",
- "//url/mojom:url_mojom_gurl_shared__generator",
- "//url/mojom:url_mojom_origin_blink__generator",
- "//url/mojom:url_mojom_origin_shared__generator",
+ "//third_party/blink/public/mojom:mojom_platform_blink_headers",
+ "//url/mojom:url_mojom_gurl_blink_headers",
+ "//url/mojom:url_mojom_origin_blink_headers",
]
}
diff --git a/chromium/third_party/blink/renderer/platform/blob/DEPS b/chromium/third_party/blink/renderer/platform/blob/DEPS
index 24f75939c14..299df734e23 100644
--- a/chromium/third_party/blink/renderer/platform/blob/DEPS
+++ b/chromium/third_party/blink/renderer/platform/blob/DEPS
@@ -7,11 +7,9 @@ include_rules = [
# Dependencies.
"+third_party/blink/renderer/platform/cross_thread_functional.h",
- "+third_party/blink/renderer/platform/file_metadata.h",
"+third_party/blink/renderer/platform/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",
"+third_party/blink/renderer/platform/testing",
"+third_party/blink/renderer/platform/text/line_ending.h",
"+third_party/blink/renderer/platform/uuid.h",
diff --git a/chromium/third_party/blink/renderer/platform/blob/OWNERS b/chromium/third_party/blink/renderer/platform/blob/OWNERS
index 592111ed461..5866bae80c5 100644
--- a/chromium/third_party/blink/renderer/platform/blob/OWNERS
+++ b/chromium/third_party/blink/renderer/platform/blob/OWNERS
@@ -1,5 +1,4 @@
-dmurph@chromium.org
-mek@chromium.org
+file://storage/browser/blob/OWNERS
per-file *_struct_traits*.*=set noparent
per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS
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 412ae11284f..5c7bc7a0c8f 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
@@ -5,7 +5,7 @@
#include "third_party/blink/renderer/platform/blob/blob_bytes_provider.h"
#include "base/numerics/safe_conversions.h"
-#include "base/task_scheduler/post_task.h"
+#include "base/task/post_task.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_thread.h"
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 543574f8eb2..678cee0434f 100644
--- a/chromium/third_party/blink/renderer/platform/blob/blob_data.cc
+++ b/chromium/third_party/blink/renderer/platform/blob/blob_data.cc
@@ -46,7 +46,6 @@
#include "third_party/blink/renderer/platform/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/histogram.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/text/line_ending.h"
#include "third_party/blink/renderer/platform/uuid.h"
#include "third_party/blink/renderer/platform/web_task_runner.h"
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 e51d4c055a7..1afc9f231a4 100644
--- a/chromium/third_party/blink/renderer/platform/blob/blob_data.h
+++ b/chromium/third_party/blink/renderer/platform/blob/blob_data.h
@@ -36,7 +36,6 @@
#include "base/thread_annotations.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/renderer/platform/file_metadata.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
diff --git a/chromium/third_party/blink/renderer/platform/cross_thread_copier.cc b/chromium/third_party/blink/renderer/platform/cross_thread_copier.cc
index 240eb81f6a4..1154c8d2825 100644
--- a/chromium/third_party/blink/renderer/platform/cross_thread_copier.cc
+++ b/chromium/third_party/blink/renderer/platform/cross_thread_copier.cc
@@ -31,9 +31,6 @@
#include "third_party/blink/renderer/platform/cross_thread_copier.h"
#include <memory>
-#include "third_party/blink/renderer/platform/loader/fetch/resource_error.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/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -48,21 +45,6 @@ CrossThreadCopier<String>::Type CrossThreadCopier<String>::Copy(
return str.IsolatedCopy();
}
-CrossThreadCopier<ResourceError>::Type CrossThreadCopier<ResourceError>::Copy(
- const ResourceError& error) {
- return error.Copy();
-}
-
-CrossThreadCopier<ResourceRequest>::Type
-CrossThreadCopier<ResourceRequest>::Copy(const ResourceRequest& request) {
- return WTF::Passed(request.CopyData());
-}
-
-CrossThreadCopier<ResourceResponse>::Type
-CrossThreadCopier<ResourceResponse>::Copy(const ResourceResponse& response) {
- return WTF::Passed(response.CopyData());
-}
-
// Test CrossThreadCopier using static_assert.
// Verify that ThreadSafeRefCounted objects get handled correctly.
diff --git a/chromium/third_party/blink/renderer/platform/cross_thread_copier.h b/chromium/third_party/blink/renderer/platform/cross_thread_copier.h
index f42cc3b88ac..db807378b19 100644
--- a/chromium/third_party/blink/renderer/platform/cross_thread_copier.h
+++ b/chromium/third_party/blink/renderer/platform/cross_thread_copier.h
@@ -42,6 +42,7 @@
#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/functional.h" // FunctionThreadAffinity
#include "third_party/blink/renderer/platform/wtf/type_traits.h"
+#include "third_party/blink/renderer/platform/wtf/wtf_size_t.h"
namespace base {
template <typename, typename>
@@ -66,11 +67,6 @@ namespace blink {
class IntRect;
class IntSize;
class KURL;
-class ResourceError;
-class ResourceRequest;
-class ResourceResponse;
-struct CrossThreadResourceResponseData;
-struct CrossThreadResourceRequestData;
template <typename T>
class CrossThreadPersistent;
template <typename T>
@@ -176,7 +172,7 @@ struct CrossThreadCopier<std::unique_ptr<T, Deleter>> {
}
};
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
struct CrossThreadCopier<
Vector<std::unique_ptr<T>, inlineCapacity, Allocator>> {
STATIC_ONLY(CrossThreadCopier);
@@ -186,7 +182,7 @@ struct CrossThreadCopier<
}
};
-template <size_t inlineCapacity, typename Allocator>
+template <wtf_size_t inlineCapacity, typename Allocator>
struct CrossThreadCopier<Vector<uint64_t, inlineCapacity, Allocator>> {
STATIC_ONLY(CrossThreadCopier);
using Type = Vector<uint64_t, inlineCapacity, Allocator>;
@@ -248,29 +244,6 @@ struct CrossThreadCopier<String> {
PLATFORM_EXPORT static Type Copy(const String&);
};
-template <>
-struct CrossThreadCopier<ResourceError> {
- STATIC_ONLY(CrossThreadCopier);
- typedef ResourceError Type;
- PLATFORM_EXPORT static Type Copy(const ResourceError&);
-};
-
-template <>
-struct CrossThreadCopier<ResourceRequest> {
- STATIC_ONLY(CrossThreadCopier);
- typedef WTF::PassedWrapper<std::unique_ptr<CrossThreadResourceRequestData>>
- Type;
- PLATFORM_EXPORT static Type Copy(const ResourceRequest&);
-};
-
-template <>
-struct CrossThreadCopier<ResourceResponse> {
- STATIC_ONLY(CrossThreadCopier);
- typedef WTF::PassedWrapper<std::unique_ptr<CrossThreadResourceResponseData>>
- Type;
- PLATFORM_EXPORT static Type Copy(const ResourceResponse&);
-};
-
// mojo::InterfacePtrInfo is a cross-thread safe mojo::InterfacePtr.
template <typename Interface>
struct CrossThreadCopier<mojo::InterfacePtrInfo<Interface>> {
@@ -299,7 +272,7 @@ struct CrossThreadCopier<MessagePortChannel> {
}
};
-template <size_t inlineCapacity, typename Allocator>
+template <wtf_size_t inlineCapacity, typename Allocator>
struct CrossThreadCopier<
Vector<MessagePortChannel, inlineCapacity, Allocator>> {
STATIC_ONLY(CrossThreadCopier);
diff --git a/chromium/third_party/blink/renderer/platform/exported/DEPS b/chromium/third_party/blink/renderer/platform/exported/DEPS
index 7e486bb11c3..53f699c8da1 100644
--- a/chromium/third_party/blink/renderer/platform/exported/DEPS
+++ b/chromium/third_party/blink/renderer/platform/exported/DEPS
@@ -2,6 +2,4 @@
include_rules = [
"+net/cookies/canonical_cookie.h",
"+net/cookies/cookie_constants.h",
- "+net/cookies/canonical_cookie.h",
- "+net/cookies/cookie_constants.h",
]
diff --git a/chromium/third_party/blink/renderer/platform/exported/platform.cc b/chromium/third_party/blink/renderer/platform/exported/platform.cc
index 848cda38f0b..256f1461ffc 100644
--- a/chromium/third_party/blink/renderer/platform/exported/platform.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/platform.cc
@@ -62,6 +62,7 @@
#include "third_party/blink/renderer/platform/language.h"
#include "third_party/blink/renderer/platform/memory_coordinator.h"
#include "third_party/blink/renderer/platform/partition_alloc_memory_dump_provider.h"
+#include "third_party/blink/renderer/platform/scheduler/common/simple_thread_scheduler.h"
#include "third_party/blink/renderer/platform/web_task_runner.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
#include "third_party/webrtc/api/rtpparameters.h"
@@ -114,12 +115,45 @@ Platform::Platform() : main_thread_(nullptr) {
Platform::~Platform() = default;
-void Platform::Initialize(Platform* platform) {
+namespace {
+
+class SimpleMainThread : public WebThread {
+ public:
+ bool IsCurrentThread() const override {
+ DCHECK(WTF::IsMainThread());
+ return true;
+ }
+ // TODO(yutak): Remove the const qualifier so we don't have to use mutable.
+ ThreadScheduler* Scheduler() const override { return &scheduler_; }
+ scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() const override {
+ DCHECK(WTF::IsMainThread());
+ return base::ThreadTaskRunnerHandle::Get();
+ }
+
+ private:
+ mutable scheduler::SimpleThreadScheduler scheduler_;
+};
+
+} // namespace
+
+void Platform::Initialize(Platform* platform, WebThread* main_thread) {
DCHECK(!g_platform);
DCHECK(platform);
g_platform = platform;
- g_platform->main_thread_ = platform->CurrentThread();
+ g_platform->main_thread_ = main_thread;
+ InitializeCommon(platform);
+}
+
+void Platform::CreateMainThreadAndInitialize(Platform* platform) {
+ DCHECK(!g_platform);
+ DCHECK(platform);
+ g_platform = platform;
+ g_platform->owned_main_thread_ = std::make_unique<SimpleMainThread>();
+ g_platform->main_thread_ = g_platform->owned_main_thread_.get();
+ InitializeCommon(platform);
+}
+void Platform::InitializeCommon(Platform* platform) {
WTF::Initialize(CallOnMainThreadFunction);
ProcessHeap::Init();
@@ -175,6 +209,13 @@ WebThread* Platform::MainThread() const {
return main_thread_;
}
+WebThread* Platform::CurrentThread() {
+ // This version must be called only if the main thread is owned by Platform.
+ // See the comments in the header.
+ DCHECK(owned_main_thread_);
+ return main_thread_;
+}
+
service_manager::Connector* Platform::GetConnector() {
DEFINE_STATIC_LOCAL(DefaultConnector, connector, ());
return connector.Get();
@@ -220,6 +261,12 @@ Platform::CreateSharedOffscreenGraphicsContext3DProvider() {
return nullptr;
}
+std::unique_ptr<WebGraphicsContext3DProvider>
+Platform::CreateWebGPUGraphicsContext3DProvider(const WebURL& top_document_url,
+ GraphicsInfo*) {
+ return nullptr;
+}
+
std::unique_ptr<WebRTCPeerConnectionHandler>
Platform::CreateRTCPeerConnectionHandler(
WebRTCPeerConnectionHandlerClient*,
@@ -248,11 +295,6 @@ std::unique_ptr<WebCanvasCaptureHandler> Platform::CreateCanvasCaptureHandler(
return nullptr;
}
-std::unique_ptr<WebSocketHandshakeThrottle>
-Platform::CreateWebSocketHandshakeThrottle() {
- return nullptr;
-}
-
std::unique_ptr<WebImageCaptureFrameGrabber>
Platform::CreateImageCaptureFrameGrabber() {
return nullptr;
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_cors.cc b/chromium/third_party/blink/renderer/platform/exported/web_cors.cc
index eab6b54b207..8e0a3c5f949 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_cors.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/web_cors.cc
@@ -129,53 +129,6 @@ class HTTPHeaderNameListParser {
} // namespace
-base::Optional<network::CORSErrorStatus> HandleRedirect(
- WebSecurityOrigin& current_security_origin,
- WebURLRequest& new_request,
- const WebURL redirect_response_url,
- const int redirect_response_status_code,
- const WebHTTPHeaderMap& redirect_response_header,
- network::mojom::FetchCredentialsMode credentials_mode,
- ResourceLoaderOptions& options) {
- const KURL& last_url = redirect_response_url;
- const KURL& new_url = new_request.Url();
-
- WebSecurityOrigin& new_security_origin = current_security_origin;
-
- // TODO(tyoshino): This should be fixed to check not only the last one but
- // all redirect responses.
- if (!current_security_origin.CanRequest(last_url)) {
- base::Optional<CORSError> redirect_error =
- CORS::CheckRedirectLocation(new_url);
- if (redirect_error)
- return network::CORSErrorStatus(*redirect_error);
-
- KURL redirect_response_kurl = redirect_response_url;
- base::Optional<network::CORSErrorStatus> access_error =
- CORS::CheckAccess(redirect_response_kurl, redirect_response_status_code,
- redirect_response_header.GetHTTPHeaderMap(),
- credentials_mode, *current_security_origin.Get());
- if (access_error)
- return access_error;
-
- scoped_refptr<const SecurityOrigin> last_origin =
- SecurityOrigin::Create(last_url);
- // Set request's origin to a globally unique identifier as specified in
- // the step 10 in https://fetch.spec.whatwg.org/#http-redirect-fetch.
- if (!last_origin->CanRequest(new_url)) {
- options.security_origin = SecurityOrigin::CreateUniqueOpaque();
- new_security_origin = options.security_origin;
- }
- }
-
- if (!current_security_origin.CanRequest(new_url)) {
- new_request.SetHTTPHeaderField(WebString(HTTPNames::Origin),
- new_security_origin.ToString());
- options.cors_flag = true;
- }
- return base::nullopt;
-}
-
WebHTTPHeaderSet ExtractCorsExposedHeaderNamesList(
network::mojom::FetchCredentialsMode credentials_mode,
const WebURLResponse& response) {
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_file_system_callbacks.cc b/chromium/third_party/blink/renderer/platform/exported/web_file_system_callbacks.cc
index e4858aa42c7..c02b1ae1b05 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_file_system_callbacks.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/web_file_system_callbacks.cc
@@ -139,9 +139,9 @@ void WebFileSystemCallbacks::DidResolveURL(const WebString& name,
const WebString& file_path,
bool is_directory) {
DCHECK(!private_.IsNull());
- private_->Callbacks()->DidResolveURL(name, root_url,
- static_cast<FileSystemType>(type),
- file_path, is_directory);
+ private_->Callbacks()->DidResolveURL(
+ name, root_url, static_cast<mojom::blink::FileSystemType>(type),
+ file_path, is_directory);
private_.Reset();
}
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_media_constraints.cc b/chromium/third_party/blink/renderer/platform/exported/web_media_constraints.cc
index c379548df3e..bcbcf0606ae 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_media_constraints.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/web_media_constraints.cc
@@ -172,7 +172,7 @@ LongConstraint::LongConstraint(const char* name)
has_exact_(false),
has_ideal_(false) {}
-bool LongConstraint::Matches(long value) const {
+bool LongConstraint::Matches(int32_t value) const {
if (has_min_ && value < min_) {
return false;
}
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 f0569624a29..3af4b48de1d 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
@@ -177,11 +177,6 @@ void WebMediaStreamSource::SetAudioProcessingProperties(
auto_gain_control, noise_supression);
}
-WebMediaConstraints WebMediaStreamSource::Constraints() {
- DCHECK(!private_.IsNull());
- return private_->Constraints();
-}
-
void WebMediaStreamSource::SetCapabilities(
const WebMediaStreamSource::Capabilities& capabilities) {
DCHECK(!private_.IsNull());
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 e3383f473da..edec0b4169e 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
@@ -76,10 +76,6 @@ void WebRuntimeFeatures::EnableOriginTrialControlledFeatures(bool enable) {
RuntimeEnabledFeatures::SetOriginTrialControlledFeaturesEnabled(enable);
}
-void WebRuntimeFeatures::EnableOriginPolicy(bool enable) {
- RuntimeEnabledFeatures::SetOriginPolicyEnabled(enable);
-}
-
void WebRuntimeFeatures::EnableOutOfBlinkCORS(bool enable) {
RuntimeEnabledFeatures::SetOutOfBlinkCORSEnabled(enable);
}
@@ -108,6 +104,10 @@ void WebRuntimeFeatures::EnableCacheInlineScriptCode(bool enable) {
RuntimeEnabledFeatures::SetCacheInlineScriptCodeEnabled(enable);
}
+void WebRuntimeFeatures::EnableIsolatedCodeCache(bool enable) {
+ RuntimeEnabledFeatures::SetIsolatedCodeCacheEnabled(enable);
+}
+
void WebRuntimeFeatures::EnableCanvas2dImageChromium(bool enable) {
RuntimeEnabledFeatures::SetCanvas2dImageChromiumEnabled(enable);
}
@@ -196,6 +196,14 @@ void WebRuntimeFeatures::EnableLazyFrameVisibleLoadTimeMetrics(bool enable) {
RuntimeEnabledFeatures::SetLazyFrameVisibleLoadTimeMetricsEnabled(enable);
}
+void WebRuntimeFeatures::EnableLazyImageLoading(bool enable) {
+ RuntimeEnabledFeatures::SetLazyImageLoadingEnabled(enable);
+}
+
+void WebRuntimeFeatures::EnableLazyImageVisibleLoadTimeMetrics(bool enable) {
+ RuntimeEnabledFeatures::SetLazyImageVisibleLoadTimeMetricsEnabled(enable);
+}
+
void WebRuntimeFeatures::EnableLazyParseCSS(bool enable) {
RuntimeEnabledFeatures::SetLazyParseCSSEnabled(enable);
}
@@ -284,6 +292,10 @@ void WebRuntimeFeatures::EnablePassiveDocumentEventListeners(bool enable) {
RuntimeEnabledFeatures::SetPassiveDocumentEventListenersEnabled(enable);
}
+void WebRuntimeFeatures::EnablePassiveDocumentWheelEventListeners(bool enable) {
+ RuntimeEnabledFeatures::SetPassiveDocumentWheelEventListenersEnabled(enable);
+}
+
void WebRuntimeFeatures::EnablePaymentApp(bool enable) {
RuntimeEnabledFeatures::SetPaymentAppEnabled(enable);
}
@@ -304,6 +316,10 @@ void WebRuntimeFeatures::EnablePictureInPictureAPI(bool enable) {
RuntimeEnabledFeatures::SetPictureInPictureAPIEnabled(enable);
}
+void WebRuntimeFeatures::EnablePortals(bool enable) {
+ RuntimeEnabledFeatures::SetPortalsEnabled(enable);
+}
+
void WebRuntimeFeatures::EnablePreloadDefaultIsMetadata(bool enable) {
RuntimeEnabledFeatures::SetPreloadDefaultIsMetadataEnabled(enable);
}
@@ -364,6 +380,10 @@ void WebRuntimeFeatures::EnableSharedWorker(bool enable) {
RuntimeEnabledFeatures::SetSharedWorkerEnabled(enable);
}
+void WebRuntimeFeatures::EnableSignedHTTPExchange(bool enable) {
+ RuntimeEnabledFeatures::SetSignedHTTPExchangeEnabled(enable);
+}
+
void WebRuntimeFeatures::EnablePreciseMemoryInfo(bool enable) {
RuntimeEnabledFeatures::SetPreciseMemoryInfoEnabled(enable);
}
@@ -440,10 +460,6 @@ void WebRuntimeFeatures::EnableServiceWorkerScriptFullCodeCache(bool enable) {
RuntimeEnabledFeatures::SetServiceWorkerScriptFullCodeCacheEnabled(enable);
}
-void WebRuntimeFeatures::EnableAutoplayMutedVideos(bool enable) {
- RuntimeEnabledFeatures::SetAutoplayMutedVideosEnabled(enable);
-}
-
void WebRuntimeFeatures::EnableTimerThrottlingForBackgroundTabs(bool enable) {
RuntimeEnabledFeatures::SetTimerThrottlingForBackgroundTabsEnabled(enable);
}
@@ -524,12 +540,8 @@ void WebRuntimeFeatures::EnableWorkStealingInScriptRunner(bool enable) {
RuntimeEnabledFeatures::SetWorkStealingInScriptRunnerEnabled(enable);
}
-void WebRuntimeFeatures::EnableStopInBackground(bool enable) {
- RuntimeEnabledFeatures::SetStopInBackgroundEnabled(enable);
-}
-
-void WebRuntimeFeatures::EnableStopNonTimersInBackground(bool enable) {
- RuntimeEnabledFeatures::SetStopNonTimersInBackgroundEnabled(enable);
+void WebRuntimeFeatures::EnableScheduledScriptStreaming(bool enable) {
+ RuntimeEnabledFeatures::SetScheduledScriptStreamingEnabled(enable);
}
void WebRuntimeFeatures::EnablePWAFullCodeCache(bool enable) {
@@ -556,4 +568,8 @@ void WebRuntimeFeatures::EnableMediaControlsExpandGesture(bool enable) {
RuntimeEnabledFeatures::SetMediaControlsExpandGestureEnabled(enable);
}
+void WebRuntimeFeatures::EnableHrefTranslate(bool enable) {
+ RuntimeEnabledFeatures::SetHrefTranslateEnabled(enable);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_service_worker_request.cc b/chromium/third_party/blink/renderer/platform/exported/web_service_worker_request.cc
index ba0a0c6d25a..98aeddf120b 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_service_worker_request.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/web_service_worker_request.cc
@@ -37,6 +37,7 @@ class WebServiceWorkerRequestPrivate
network::mojom::RequestContextFrameType frame_type_ =
network::mojom::RequestContextFrameType::kNone;
WebString integrity_;
+ WebURLRequest::Priority priority_ = WebURLRequest::Priority::kUnresolved;
bool keepalive_ = false;
WebString client_id_;
bool is_reload_ = false;
@@ -62,6 +63,10 @@ const WebString& WebServiceWorkerRequest::Integrity() const {
return private_->integrity_;
}
+WebURLRequest::Priority WebServiceWorkerRequest::Priority() const {
+ return private_->priority_;
+}
+
bool WebServiceWorkerRequest::Keepalive() const {
return private_->keepalive_;
}
@@ -189,6 +194,10 @@ void WebServiceWorkerRequest::SetIntegrity(const WebString& integrity) {
private_->integrity_ = integrity;
}
+void WebServiceWorkerRequest::SetPriority(WebURLRequest::Priority priority) {
+ private_->priority_ = priority;
+}
+
void WebServiceWorkerRequest::SetKeepalive(bool keepalive) {
private_->keepalive_ = keepalive;
}
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 0a8f1173569..802cb0f2153 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
@@ -154,6 +154,8 @@ void WebURLRequest::SetHTTPReferrer(const WebString& web_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, static_cast<ReferrerPolicy>(referrer_policy)));
}
@@ -355,14 +357,6 @@ void WebURLRequest::SetPriority(WebURLRequest::Priority priority) {
resource_request_->SetPriority(static_cast<ResourceLoadPriority>(priority));
}
-bool WebURLRequest::CheckForBrowserSideNavigation() const {
- return resource_request_->CheckForBrowserSideNavigation();
-}
-
-void WebURLRequest::SetCheckForBrowserSideNavigation(bool check) {
- resource_request_->SetCheckForBrowserSideNavigation(check);
-}
-
bool WebURLRequest::WasDiscarded() const {
return resource_request_->WasDiscarded();
}
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 eee8ae58c69..8fa019e0851 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
@@ -326,14 +326,12 @@ void WebURLResponse::SetWasFallbackRequiredByServiceWorker(bool value) {
resource_response_->SetWasFallbackRequiredByServiceWorker(value);
}
-void WebURLResponse::SetResponseTypeViaServiceWorker(
- network::mojom::FetchResponseType value) {
- resource_response_->SetResponseTypeViaServiceWorker(value);
+void WebURLResponse::SetType(network::mojom::FetchResponseType value) {
+ resource_response_->SetType(value);
}
-network::mojom::FetchResponseType WebURLResponse::ResponseTypeViaServiceWorker()
- const {
- return resource_response_->ResponseTypeViaServiceWorker();
+network::mojom::FetchResponseType WebURLResponse::GetType() const {
+ return resource_response_->GetType();
}
void WebURLResponse::SetURLListViaServiceWorker(
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 10fe0edd98c..93a3d2217ae 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,
- const cc::LayerTreeSettings& settings) {
+ const cc::LayerTreeSettings& settings,
+ bool use_sync_primitives) {
return std::make_unique<VideoFrameSubmitter>(
std::move(context_provider_callback),
- std::make_unique<VideoFrameResourceProvider>(settings));
+ std::make_unique<VideoFrameResourceProvider>(settings,
+ use_sync_primitives));
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/feature_policy/feature_policy.cc b/chromium/third_party/blink/renderer/platform/feature_policy/feature_policy.cc
index 79d0ba67f18..8aef9a6681b 100644
--- a/chromium/third_party/blink/renderer/platform/feature_policy/feature_policy.cc
+++ b/chromium/third_party/blink/renderer/platform/feature_policy/feature_policy.cc
@@ -210,6 +210,8 @@ void AllowFeatureEverywhere(mojom::FeaturePolicyFeature feature,
const FeatureNameMap& GetDefaultFeatureNameMap() {
DEFINE_STATIC_LOCAL(FeatureNameMap, default_feature_name_map, ());
if (default_feature_name_map.IsEmpty()) {
+ default_feature_name_map.Set("autoplay",
+ mojom::FeaturePolicyFeature::kAutoplay);
default_feature_name_map.Set("camera",
mojom::FeaturePolicyFeature::kCamera);
default_feature_name_map.Set("encrypted-media",
@@ -249,10 +251,6 @@ const FeatureNameMap& GetDefaultFeatureNameMap() {
default_feature_name_map.Set("sync-script",
mojom::FeaturePolicyFeature::kSyncScript);
}
- if (RuntimeEnabledFeatures::FeaturePolicyAutoplayFeatureEnabled()) {
- default_feature_name_map.Set("autoplay",
- mojom::FeaturePolicyFeature::kAutoplay);
- }
if (RuntimeEnabledFeatures::PaymentRequestEnabled()) {
default_feature_name_map.Set("payment",
mojom::FeaturePolicyFeature::kPayment);
@@ -279,4 +277,13 @@ const FeatureNameMap& GetDefaultFeatureNameMap() {
return default_feature_name_map;
}
+const String& GetNameForFeature(mojom::FeaturePolicyFeature feature) {
+ const static String empty_string;
+ for (const auto& entry : GetDefaultFeatureNameMap()) {
+ if (entry.value == feature)
+ return entry.key;
+ }
+ return empty_string;
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/feature_policy/feature_policy.h b/chromium/third_party/blink/renderer/platform/feature_policy/feature_policy.h
index 05c3737a1d3..fa5d340af4a 100644
--- a/chromium/third_party/blink/renderer/platform/feature_policy/feature_policy.h
+++ b/chromium/third_party/blink/renderer/platform/feature_policy/feature_policy.h
@@ -90,6 +90,8 @@ PLATFORM_EXPORT void DisallowFeature(mojom::FeaturePolicyFeature,
PLATFORM_EXPORT void AllowFeatureEverywhere(mojom::FeaturePolicyFeature,
ParsedFeaturePolicy&);
+PLATFORM_EXPORT const String& GetNameForFeature(mojom::FeaturePolicyFeature);
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_FEATURE_POLICY_FEATURE_POLICY_H_
diff --git a/chromium/third_party/blink/renderer/platform/file_system_type.h b/chromium/third_party/blink/renderer/platform/file_system_type.h
deleted file mode 100644
index 2e545dea41d..00000000000
--- a/chromium/third_party/blink/renderer/platform/file_system_type.h
+++ /dev/null
@@ -1,56 +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_FILE_SYSTEM_TYPE_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FILE_SYSTEM_TYPE_H_
-
-namespace blink {
-
-// For file system types used in FileSystem API.
-//
-// WARNING: These enumerators can be serialized to disk (with IndexedDB).
-// If you have to update this list, also modify deserialization logic to handle
-// the previous version of this enum.
-enum FileSystemType {
- kFileSystemTypeTemporary,
- kFileSystemTypePersistent,
-
- // Transient isolated non-sandboxed filesystem.
- kFileSystemTypeIsolated,
-
- // Non-sandbox filesystem.
- kFileSystemTypeExternal,
-
- kFileSystemTypeLast = kFileSystemTypeExternal,
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_FILE_SYSTEM_TYPE_H_
diff --git a/chromium/third_party/blink/renderer/platform/fonts/DEPS b/chromium/third_party/blink/renderer/platform/fonts/DEPS
index 98ddf831ee0..d6d836773e8 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/DEPS
+++ b/chromium/third_party/blink/renderer/platform/fonts/DEPS
@@ -9,7 +9,6 @@ include_rules = [
"+third_party/blink/renderer/platform/font_family_names.h",
"+third_party/blink/renderer/platform/geometry",
"+third_party/blink/renderer/platform/graphics",
- "+third_party/blink/renderer/platform/heap/handle.h",
"+third_party/blink/renderer/platform/heap",
"+third_party/blink/renderer/platform/histogram.h",
"+third_party/blink/renderer/platform/instrumentation",
@@ -23,6 +22,5 @@ include_rules = [
"+third_party/blink/renderer/platform/shared_buffer.h",
"+third_party/blink/renderer/platform/testing",
"+third_party/blink/renderer/platform/text",
- "+third_party/blink/renderer/platform/transforms/affine_transform.h",
"+third_party/blink/renderer/platform/wtf",
]
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
new file mode 100644
index 00000000000..0b211881222
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/fonts/android/font_unique_name_lookup_android.cc
@@ -0,0 +1,49 @@
+// 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/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/platform/modules/font_unique_name_lookup/font_unique_name_lookup.mojom-blink.h"
+#include "third_party/blink/public/platform/platform.h"
+
+namespace blink {
+
+FontUniqueNameLookupAndroid::~FontUniqueNameLookupAndroid() = default;
+
+bool FontUniqueNameLookupAndroid::EnsureMatchingServiceConnected() {
+ if (font_table_matcher_)
+ return true;
+
+ mojom::blink::FontUniqueNameLookupPtr service;
+ Platform::Current()->GetInterfaceProvider()->GetInterface(
+ mojo::MakeRequest(&service));
+
+ base::ReadOnlySharedMemoryRegion region_ptr;
+ if (!service->GetUniqueNameLookupTable(&region_ptr)) {
+ // Tests like StyleEngineTest do not set up a full browser where Blink can
+ // connect to a browser side service for font lookups. Placing a DCHECK here
+ // is too strict for such a case.
+ LOG(ERROR) << "Unable to connect to browser side service for src: local() "
+ "font lookup.";
+ return false;
+ }
+
+ font_table_matcher_ = std::make_unique<FontTableMatcher>(region_ptr.Map());
+ return true;
+}
+
+sk_sp<SkTypeface> FontUniqueNameLookupAndroid::MatchUniqueName(
+ const String& font_unique_name) {
+ if (!EnsureMatchingServiceConnected())
+ return nullptr;
+ base::Optional<FontTableMatcher::MatchResult> match_result =
+ font_table_matcher_->MatchName(font_unique_name.Utf8().data());
+ if (!match_result)
+ return nullptr;
+ return SkTypeface::MakeFromFile(match_result->font_path.c_str(),
+ match_result->ttc_index);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/android/font_unique_name_lookup_android.h b/chromium/third_party/blink/renderer/platform/fonts/android/font_unique_name_lookup_android.h
new file mode 100644
index 00000000000..54b1cc7c177
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/fonts/android/font_unique_name_lookup_android.h
@@ -0,0 +1,29 @@
+// 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_FONTS_ANDROID_FONT_UNIQUE_NAME_LOOKUP_ANDROID_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_ANDROID_FONT_UNIQUE_NAME_LOOKUP_ANDROID_H_
+
+#include "third_party/blink/public/common/font_unique_name_lookup/font_table_matcher.h"
+#include "third_party/blink/renderer/platform/fonts/font_unique_name_lookup.h"
+
+#include <memory>
+
+namespace blink {
+
+class FontUniqueNameLookupAndroid : public FontUniqueNameLookup {
+ public:
+ FontUniqueNameLookupAndroid() = default;
+ ~FontUniqueNameLookupAndroid() override;
+ sk_sp<SkTypeface> MatchUniqueName(const String& font_unique_name) override;
+
+ private:
+ bool EnsureMatchingServiceConnected();
+ std::unique_ptr<FontTableMatcher> font_table_matcher_;
+ DISALLOW_COPY_AND_ASSIGN(FontUniqueNameLookupAndroid);
+};
+
+} // namespace blink
+
+#endif
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font.cc b/chromium/third_party/blink/renderer/platform/fonts/font.cc
index 140c9e34153..2df090852c4 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/font.cc
@@ -37,13 +37,11 @@
#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/paint/paint_text_blob.h"
-#include "third_party/blink/renderer/platform/layout_test_support.h"
#include "third_party/blink/renderer/platform/layout_unit.h"
#include "third_party/blink/renderer/platform/text/bidi_resolver.h"
#include "third_party/blink/renderer/platform/text/character.h"
#include "third_party/blink/renderer/platform/text/text_run.h"
#include "third_party/blink/renderer/platform/text/text_run_iterator.h"
-#include "third_party/blink/renderer/platform/transforms/affine_transform.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "third_party/blink/renderer/platform/wtf/text/character_names.h"
#include "third_party/blink/renderer/platform/wtf/text/unicode.h"
@@ -507,6 +505,12 @@ Vector<CharacterRange> Font::IndividualCharacterRanges(
return ranges;
}
+Vector<double> Font::IndividualCharacterAdvances(const TextRun& run) const {
+ FontCachePurgePreventer purge_preventer;
+ CachingWordShaper shaper(*this);
+ return shaper.IndividualCharacterAdvances(run);
+}
+
void Font::ExpandRangeToIncludePartialGlyphs(const TextRun& text_run,
int* from,
int* to) const {
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font.h b/chromium/third_party/blink/renderer/platform/fonts/font.h
index de3a27cbd69..a661792b309 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font.h
@@ -156,6 +156,11 @@ class PLATFORM_EXPORT Font {
unsigned to) const;
Vector<CharacterRange> IndividualCharacterRanges(const TextRun&) const;
+ // Returns a vector of same size as TextRun.length() with advances measured
+ // in pixels from the left bounding box of the full TextRun to the left bound
+ // of the glyph rendered by each character. Values should always be positive.
+ Vector<double> IndividualCharacterAdvances(const TextRun&) const;
+
void ExpandRangeToIncludePartialGlyphs(const TextRun&,
int* from,
int* to) const;
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 b02c8ac1075..b37971a9b9b 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
@@ -40,7 +40,6 @@
#include "third_party/blink/renderer/platform/fonts/web_font_decoder.h"
#include "third_party/blink/renderer/platform/fonts/web_font_typeface_factory.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_typeface.h"
-#include "third_party/blink/renderer/platform/layout_test_support.h"
#include "third_party/blink/renderer/platform/shared_buffer.h"
#include "third_party/skia/include/core/SkStream.h"
#include "third_party/skia/include/core/SkTypeface.h"
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 140e099364f..15a999cb190 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_description.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_description.h
@@ -100,6 +100,8 @@ class PLATFORM_EXPORT FontDescription {
struct VariantLigatures {
STACK_ALLOCATED();
+
+ public:
VariantLigatures(LigaturesState state = kNormalLigaturesState)
: common(state),
discretionary(state),
@@ -116,6 +118,8 @@ class PLATFORM_EXPORT FontDescription {
struct Size {
STACK_ALLOCATED();
+
+ public:
Size(unsigned keyword, float value, bool is_absolute)
: keyword(keyword), is_absolute(is_absolute), value(value) {}
@@ -128,6 +132,8 @@ class PLATFORM_EXPORT FontDescription {
struct FamilyDescription {
STACK_ALLOCATED();
+
+ public:
FamilyDescription(GenericFamilyType generic_family)
: generic_family(generic_family) {}
FamilyDescription(GenericFamilyType generic_family,
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 fd825e721cc..cff578049fa 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
@@ -9,7 +9,6 @@
#include "third_party/blink/renderer/platform/fonts/font_fallback_list.h"
#include "third_party/blink/renderer/platform/fonts/segmented_font_data.h"
#include "third_party/blink/renderer/platform/fonts/simple_font_data.h"
-#include "third_party/blink/renderer/platform/text/icu_error.h"
namespace blink {
@@ -82,6 +81,22 @@ scoped_refptr<FontDataForRangeSet> FontFallbackIterator::UniqueOrNext(
return candidate;
}
+bool FontFallbackIterator::NeedsHintList() const {
+ if (fallback_stage_ == kSegmentedFace)
+ return true;
+
+ if (fallback_stage_ != kFontGroupFonts)
+ return false;
+
+ const FontData* font_data = font_fallback_list_->FontDataAt(
+ font_description_, current_font_data_index_);
+
+ if (!font_data)
+ return false;
+
+ return font_data->IsSegmented();
+}
+
scoped_refptr<FontDataForRangeSet> FontFallbackIterator::Next(
const Vector<UChar32>& hint_list) {
if (fallback_stage_ == kOutOfLuck)
@@ -209,16 +224,8 @@ static inline unsigned ChooseHintIndex(const Vector<UChar32>& hint_list) {
if (hint_list.size() <= 1)
return 0;
- ICUError err;
- UScriptCode hint_char_script = uscript_getScript(hint_list[0], &err);
- if (!U_SUCCESS(err) || hint_char_script > USCRIPT_INHERITED)
- return 0;
-
for (size_t i = 1; i < hint_list.size(); ++i) {
- UScriptCode new_hint_script = uscript_getScript(hint_list[i], &err);
- if (!U_SUCCESS(err))
- return 0;
- if (new_hint_script > USCRIPT_INHERITED)
+ if (Character::HasDefiniteScript(hint_list[i]))
return i;
}
return 0;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_fallback_iterator.h b/chromium/third_party/blink/renderer/platform/fonts/font_fallback_iterator.h
index 22e1667ce0e..7ea449a4c20 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_fallback_iterator.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_fallback_iterator.h
@@ -28,6 +28,13 @@ class FontFallbackIterator : public RefCounted<FontFallbackIterator> {
FontFallbackPriority);
bool HasNext() const { return fallback_stage_ != kOutOfLuck; };
+ // Returns whether the next call to Next() needs a full hint list, or whether
+ // a single character is sufficient. Intended to serve as an optimization in
+ // HarfBuzzShaper to avoid spending too much time and resources collecting a
+ // full hint character list. Returns true when the next font in line is a
+ // segmented font, i.e. one that requires the hint list to work out which
+ // unicode range segment should be used.
+ bool NeedsHintList() const;
// Some system fallback APIs (Windows, Android) require a character, or a
// portion of the string to be passed. On Mac and Linux, we get a list of
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 bbdabeddf37..ae6358c361c 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
@@ -5,6 +5,7 @@
#include "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/font_unique_name_lookup.h"
#include "third_party/blink/renderer/platform/wtf/thread_specific.h"
namespace blink {
@@ -20,6 +21,16 @@ FontGlobalContext* FontGlobalContext::Get(CreateIfNeeded create_if_needed) {
FontGlobalContext::FontGlobalContext() : harfbuzz_font_funcs_(nullptr) {}
+FontGlobalContext::~FontGlobalContext() = default;
+
+FontUniqueNameLookup* FontGlobalContext::GetFontUniqueNameLookup() {
+ if (!Get()->font_unique_name_lookup_) {
+ Get()->font_unique_name_lookup_ =
+ FontUniqueNameLookup::GetPlatformUniqueNameLookup();
+ }
+ return Get()->font_unique_name_lookup_.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 928df28d42d..4dcb928342f 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
@@ -15,6 +15,7 @@ struct hb_font_funcs_t;
namespace blink {
class FontCache;
+class FontUniqueNameLookup;
enum CreateIfNeeded { kDoNotCreate, kCreate };
@@ -40,6 +41,8 @@ class PLATFORM_EXPORT FontGlobalContext {
Get()->harfbuzz_font_funcs_ = funcs;
}
+ static FontUniqueNameLookup* GetFontUniqueNameLookup();
+
// Called by MemoryCoordinator to clear memory.
static void ClearMemory();
@@ -49,11 +52,12 @@ class PLATFORM_EXPORT FontGlobalContext {
friend class WTF::ThreadSpecific<FontGlobalContext>;
FontGlobalContext();
- ~FontGlobalContext() = default;
+ ~FontGlobalContext();
FontCache font_cache_;
HarfBuzzFontCache harfbuzz_font_cache_;
hb_font_funcs_t* harfbuzz_font_funcs_;
+ std::unique_ptr<FontUniqueNameLookup> font_unique_name_lookup_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_unique_name_lookup.cc b/chromium/third_party/blink/renderer/platform/fonts/font_unique_name_lookup.cc
new file mode 100644
index 00000000000..5c9d9bbf65e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_unique_name_lookup.cc
@@ -0,0 +1,28 @@
+// 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/fonts/font_unique_name_lookup.h"
+#include "base/macros.h"
+#include "build/build_config.h"
+
+#if defined(OS_ANDROID)
+#include "third_party/blink/renderer/platform/fonts/android/font_unique_name_lookup_android.h"
+#endif
+
+namespace blink {
+
+FontUniqueNameLookup::FontUniqueNameLookup() = default;
+
+// static
+std::unique_ptr<FontUniqueNameLookup>
+FontUniqueNameLookup::GetPlatformUniqueNameLookup() {
+#if defined(OS_ANDROID)
+ return std::make_unique<FontUniqueNameLookupAndroid>();
+#else
+ NOTREACHED();
+ return nullptr;
+#endif
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_unique_name_lookup.h b/chromium/third_party/blink/renderer/platform/fonts/font_unique_name_lookup.h
new file mode 100644
index 00000000000..38428c7a9dc
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_unique_name_lookup.h
@@ -0,0 +1,36 @@
+// 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_FONTS_FONT_UNIQUE_NAME_LOOKUP_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_FONT_UNIQUE_NAME_LOOKUP_H_
+
+#include "base/macros.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+#include <SkRefCnt.h>
+#include <SkTypeface.h>
+#include <memory>
+
+namespace blink {
+
+class FontUniqueNameLookup {
+ public:
+ // Factory function to construct a platform specific font unique name lookup
+ // instance. Client must not use this directly as it is thread
+ // specific. Retrieve it from FontGlobalContext instead.
+ static std::unique_ptr<FontUniqueNameLookup> GetPlatformUniqueNameLookup();
+
+ virtual sk_sp<SkTypeface> MatchUniqueName(const String& font_unique_name) = 0;
+
+ virtual ~FontUniqueNameLookup() = default;
+
+ protected:
+ FontUniqueNameLookup();
+
+ DISALLOW_COPY_AND_ASSIGN(FontUniqueNameLookup);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_FONT_UNIQUE_NAME_LOOKUP_
diff --git a/chromium/third_party/blink/renderer/platform/fonts/mac/font_family_matcher_mac.mm b/chromium/third_party/blink/renderer/platform/fonts/mac/font_family_matcher_mac.mm
index 63b185c2bd8..0c0a9833ad4 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/mac/font_family_matcher_mac.mm
+++ b/chromium/third_party/blink/renderer/platform/fonts/mac/font_family_matcher_mac.mm
@@ -33,7 +33,6 @@
#import <Foundation/Foundation.h>
#import <math.h>
#include "third_party/blink/renderer/platform/fonts/font_cache.h"
-#include "third_party/blink/renderer/platform/layout_test_support.h"
#include "third_party/blink/renderer/platform/mac/version_util_mac.h"
#import "third_party/blink/renderer/platform/wtf/hash_set.h"
#import "third_party/blink/renderer/platform/wtf/text/atomic_string_hash.h"
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 aab219b6acf..970e20a0c6d 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
@@ -40,6 +40,8 @@ ShapeCache* CachingWordShaper::GetShapeCache() const {
return font_.font_fallback_list_->GetShapeCache(font_.font_description_);
}
+// Returns the total advance width of the TextRun run. If glyph_bounds
+// is specified it constructs on it the smallest bounding box covering all ink.
float CachingWordShaper::Width(const TextRun& run,
HashSet<const SimpleFontData*>* fallback_fonts,
FloatRect* glyph_bounds) {
@@ -48,6 +50,11 @@ float CachingWordShaper::Width(const TextRun& run,
CachingWordShapeIterator iterator(GetShapeCache(), run, &font_);
while (iterator.Next(&word_result)) {
if (word_result) {
+ // For every word_result we need to accumulate its width to adjust the
+ // glyph_bounds. When the word_result is in RTL we accumulate in the
+ // opposite direction (negative).
+ if (run.Rtl())
+ width -= word_result->Width();
if (glyph_bounds) {
FloatRect adjusted_bounds = word_result->Bounds();
// Translate glyph bounds to the current glyph position which
@@ -55,12 +62,21 @@ float CachingWordShaper::Width(const TextRun& run,
adjusted_bounds.SetX(adjusted_bounds.X() + width);
glyph_bounds->Unite(adjusted_bounds);
}
- width += word_result->Width();
+ if (!run.Rtl())
+ width += word_result->Width();
if (fallback_fonts)
word_result->FallbackFonts(fallback_fonts);
}
}
+ if (run.Rtl()) {
+ // Finally, convert width back to positive if run is RTL.
+ width = -width;
+ if (glyph_bounds) {
+ glyph_bounds->SetX(glyph_bounds->X() + width);
+ }
+ }
+
return width;
}
@@ -103,14 +119,14 @@ CharacterRange CachingWordShaper::GetCharacterRange(const TextRun& run,
ShapeResultBuffer buffer;
float total_width = ShapeResultsForRun(GetShapeCache(), &font_, run, &buffer);
- return buffer.GetCharacterRange(total_width, run.Direction(), from, to);
+ return buffer.GetCharacterRange(run.ToStringView(), run.Direction(),
+ total_width, from, to);
}
Vector<CharacterRange> CachingWordShaper::IndividualCharacterRanges(
const TextRun& run) {
ShapeResultBuffer buffer;
float total_width = ShapeResultsForRun(GetShapeCache(), &font_, run, &buffer);
-
auto ranges = buffer.IndividualCharacterRanges(run.Direction(), total_width);
// The shaper can fail to return glyph metrics for all characters (see
// crbug.com/613915 and crbug.com/615661) so add empty ranges to ensure all
@@ -120,6 +136,14 @@ Vector<CharacterRange> CachingWordShaper::IndividualCharacterRanges(
return ranges;
}
+Vector<double> CachingWordShaper::IndividualCharacterAdvances(
+ const TextRun& run) {
+ ShapeResultBuffer buffer;
+ float total_width = ShapeResultsForRun(GetShapeCache(), &font_, run, &buffer);
+ return buffer.IndividualCharacterAdvances(run.ToStringView(), run.Direction(),
+ total_width);
+}
+
Vector<ShapeResult::RunFontData> CachingWordShaper::GetRunFontData(
const TextRun& run) const {
ShapeResultBuffer buffer;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.h b/chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.h
index 1adfe2208e0..7565968b79b 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.h
@@ -61,6 +61,7 @@ class PLATFORM_EXPORT CachingWordShaper final {
void FillResultBuffer(const TextRunPaintInfo&, ShapeResultBuffer*);
CharacterRange GetCharacterRange(const TextRun&, unsigned from, unsigned to);
Vector<CharacterRange> IndividualCharacterRanges(const TextRun&);
+ Vector<double> IndividualCharacterAdvances(const TextRun&);
Vector<ShapeResult::RunFontData> GetRunFontData(const TextRun&) const;
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 264a94398a9..86a67e7cb86 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
@@ -135,6 +135,21 @@ static hb_position_t HarfBuzzGetGlyphHorizontalAdvance(hb_font_t* hb_font,
return advance;
}
+static void HarfBuzzGetGlyphHorizontalAdvances(hb_font_t* font,
+ void* font_data,
+ unsigned count,
+ hb_codepoint_t* first_glyph,
+ unsigned int glyph_stride,
+ hb_position_t* first_advance,
+ unsigned int advance_stride,
+ void* user_data) {
+ HarfBuzzFontData* hb_font_data =
+ reinterpret_cast<HarfBuzzFontData*>(font_data);
+ SkiaTextMetrics(&hb_font_data->paint_)
+ .GetGlyphWidthForHarfBuzz(count, first_glyph, glyph_stride, first_advance,
+ advance_stride);
+}
+
static hb_bool_t HarfBuzzGetGlyphVerticalOrigin(hb_font_t* hb_font,
void* font_data,
hb_codepoint_t glyph,
@@ -302,6 +317,8 @@ static hb_font_funcs_t* HarfBuzzSkiaGetFontFuncs() {
hb_font_funcs_set_glyph_func(funcs, HarfBuzzGetGlyph, nullptr, nullptr);
hb_font_funcs_set_glyph_h_advance_func(
funcs, HarfBuzzGetGlyphHorizontalAdvance, nullptr, nullptr);
+ hb_font_funcs_set_glyph_h_advances_func(
+ funcs, HarfBuzzGetGlyphHorizontalAdvances, nullptr, nullptr);
hb_font_funcs_set_glyph_h_kerning_func(
funcs, HarfBuzzGetGlyphHorizontalKerning, nullptr, nullptr);
hb_font_funcs_set_glyph_v_advance_func(
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.cc
index 1666578e0dc..813704c669f 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.cc
@@ -338,13 +338,10 @@ void HarfBuzzShaper::CommitGlyphs(RangeData* range_data,
// Here we need to specify glyph positions.
BufferSlice next_slice;
for (const BufferSlice* current_slice = &slice;;) {
- Vector<unsigned> graphemes;
- GraphemesClusterList(text_, current_slice->start_character_index,
- current_slice->num_characters, &graphemes);
ShapeResult::RunInfo* run = new ShapeResult::RunInfo(
current_font, direction, canvas_rotation, script,
current_slice->start_character_index, current_slice->num_glyphs,
- current_slice->num_characters, graphemes);
+ current_slice->num_characters);
shape_result->InsertRun(base::WrapUnique(run),
current_slice->start_glyph_index,
current_slice->num_glyphs, range_data->buffer);
@@ -484,6 +481,7 @@ void HarfBuzzShaper::ExtractShapeResults(
bool HarfBuzzShaper::CollectFallbackHintChars(
const Deque<ReshapeQueueItem>& reshape_queue,
+ bool needs_hint_list,
Vector<UChar32>& hint) const {
if (!reshape_queue.size())
return false;
@@ -501,16 +499,32 @@ bool HarfBuzzShaper::CollectFallbackHintChars(
for (unsigned i = 0; i < it->num_characters_; i++) {
hint.push_back(text_[it->start_index_ + i]);
num_chars_added++;
+ // Determine if we can take a shortcut and not fill the hint list
+ // further: We can do that if we do not need a hint list, and we have
+ // managed to find a character with a definite script since
+ // FontFallbackIterator needs a character with a determined script to
+ // perform meaningful system fallback.
+ if (!needs_hint_list &&
+ Character::HasDefiniteScript(text_[it->start_index_ + i]))
+ return true;
}
continue;
}
+ // !text_.Is8Bit()...
UChar32 hint_char;
UTF16TextIterator iterator(text_.Characters16() + it->start_index_,
it->num_characters_);
while (iterator.Consume(hint_char)) {
hint.push_back(hint_char);
num_chars_added++;
+ // Determine if we can take a shortcut and not fill the hint list
+ // further: We can do that if we do not need a hint list, and we have
+ // managed to find a character with a definite script since
+ // FontFallbackIterator needs a character with a determined script to
+ // perform meaningful system fallback.
+ if (!needs_hint_list && Character::HasDefiniteScript(hint_char))
+ return true;
iterator.Advance();
}
}
@@ -837,23 +851,19 @@ void HarfBuzzShaper::ShapeSegment(
bool font_cycle_queued = false;
Vector<UChar32> fallback_chars_hint;
- // Reserve enough capacity to avoid multiple reallocations.
- // TODO(kojii): Should review if we really need to collect all characters.
- // crbug.com/848295
- fallback_chars_hint.ReserveInitialCapacity(range_data->end -
- range_data->start);
+ // Reserve sufficient capacity to avoid multiple reallocations, only when a
+ // full hint list is needed.
+ if (fallback_iterator->NeedsHintList()) {
+ fallback_chars_hint.ReserveInitialCapacity(range_data->end -
+ range_data->start);
+ }
scoped_refptr<FontDataForRangeSet> current_font_data_for_range_set;
while (range_data->reshape_queue.size()) {
ReshapeQueueItem current_queue_item = range_data->reshape_queue.TakeFirst();
if (current_queue_item.action_ == kReshapeQueueNextFont) {
- // For now, we're building a character list with which we probe
- // for needed fonts depending on the declared unicode-range of a
- // segmented CSS font. Alternatively, we can build a fake font
- // for the shaper and check whether any glyphs were found, or
- // define a new API on the shaper which will give us coverage
- // information?
if (!CollectFallbackHintChars(range_data->reshape_queue,
+ fallback_iterator->NeedsHintList(),
fallback_chars_hint)) {
// Give up shaping since we cannot retrieve a font fallback
// font without a hintlist.
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.h b/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.h
index a65259f230d..f0bf16f23e3 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.h
@@ -95,6 +95,7 @@ class PLATFORM_EXPORT HarfBuzzShaper final {
ShapeResult*) const;
bool CollectFallbackHintChars(const Deque<ReshapeQueueItem>&,
+ bool needs_hint_list,
Vector<UChar32>& hint) const;
void CommitGlyphs(RangeData*,
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 8c96a9bbd52..a6c267b157d 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
@@ -8,6 +8,7 @@
#include "base/stl_util.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/platform/fonts/font.h"
#include "third_party/blink/renderer/platform/fonts/font_cache.h"
@@ -22,8 +23,59 @@
#include "third_party/blink/renderer/platform/text/text_run.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
+using testing::ElementsAre;
+
namespace blink {
+namespace {
+
+ShapeResultTestInfo* TestInfo(const scoped_refptr<ShapeResult>& result) {
+ return static_cast<ShapeResultTestInfo*>(result.get());
+}
+
+// Test helper to compare all RunInfo with the expected array.
+struct ShapeResultRunData {
+ unsigned start_index;
+ unsigned num_characters;
+ unsigned num_glyphs;
+ hb_script_t script;
+
+ static Vector<ShapeResultRunData> Get(
+ const scoped_refptr<ShapeResult>& result) {
+ const ShapeResultTestInfo* test_info = TestInfo(result);
+ const unsigned num_runs = test_info->NumberOfRunsForTesting();
+ Vector<ShapeResultRunData> runs(num_runs);
+ for (unsigned i = 0; i < num_runs; i++) {
+ ShapeResultRunData& run = runs[i];
+ test_info->RunInfoForTesting(i, run.start_index, run.num_characters,
+ run.num_glyphs, run.script);
+ }
+ return runs;
+ }
+};
+
+bool operator==(const ShapeResultRunData& x, const ShapeResultRunData& y) {
+ return x.start_index == y.start_index &&
+ x.num_characters == y.num_characters && x.num_glyphs == y.num_glyphs &&
+ x.script == y.script;
+}
+
+void operator<<(std::ostream& output, const ShapeResultRunData& x) {
+ output << "{ start_index=" << x.start_index
+ << ", num_characters=" << x.num_characters
+ << ", num_glyphs=" << x.num_glyphs << ", script=" << x.script << " }";
+}
+
+// Create a string of the specified length, filled with |ch|.
+String CreateStringOf(UChar ch, unsigned length) {
+ UChar* data;
+ String string(StringImpl::CreateUninitialized(length, data));
+ string.Fill(ch);
+ return string;
+}
+
+} // namespace
+
class HarfBuzzShaperTest : public testing::Test {
protected:
void SetUp() override {
@@ -124,11 +176,6 @@ INSTANTIATE_TEST_CASE_P(HarfBuzzShaperTest,
testing::Values(TextDirection::kLtr,
TextDirection::kRtl));
-static inline ShapeResultTestInfo* TestInfo(
- scoped_refptr<ShapeResult>& result) {
- return static_cast<ShapeResultTestInfo*>(result.get());
-}
-
TEST_F(HarfBuzzShaperTest, MutableUnique) {
scoped_refptr<ShapeResult> result =
ShapeResult::Create(&font, 0, TextDirection::kLtr);
@@ -367,9 +414,13 @@ TEST_F(HarfBuzzShaperTest, ShapeLatinSegment) {
// Represents the case where a part of a cluster has a different color.
// <div>0x647<span style="color: red;">0x64A</span></div>
-// This test requires context-aware shaping which hasn't been implemented yet.
-// See crbug.com/689155
-TEST_F(HarfBuzzShaperTest, DISABLED_ShapeArabicWithContext) {
+// TODO(crbug.com/689155): Still fails on Mac, AAT?
+#if defined(OS_MACOSX)
+#define MAYBE_ShapeArabicWithContext DISABLED_ShapeArabicWithContext
+#else
+#define MAYBE_ShapeArabicWithContext ShapeArabicWithContext
+#endif
+TEST_F(HarfBuzzShaperTest, MAYBE_ShapeArabicWithContext) {
UChar arabic_string[] = {0x647, 0x64A};
HarfBuzzShaper shaper(String(arabic_string, 2));
@@ -493,6 +544,90 @@ TEST_P(ShapeParameterTest, MissingGlyph) {
EXPECT_EQ(string.length(), result->EndIndexForResult());
}
+// Test splitting runs by kMaxCharacterIndex using a simple string that has code
+// point:glyph:cluster are all 1:1.
+TEST_P(ShapeParameterTest, MaxGlyphsSimple) {
+ const unsigned length = HarfBuzzRunGlyphData::kMaxCharacterIndex + 2;
+ String string = CreateStringOf('X', length);
+ HarfBuzzShaper shaper(string);
+ scoped_refptr<ShapeResult> result = ShapeWithParameter(&shaper);
+ EXPECT_EQ(length, result->NumCharacters());
+ EXPECT_EQ(length, result->NumGlyphs());
+ Vector<ShapeResultRunData> runs = ShapeResultRunData::Get(result);
+ if (IsRtl(GetParam()))
+ runs.Reverse();
+ EXPECT_THAT(
+ runs, testing::ElementsAre(
+ ShapeResultRunData{0, length - 1, length - 1, HB_SCRIPT_LATIN},
+ ShapeResultRunData{length - 1, 1, 1, HB_SCRIPT_LATIN}));
+}
+
+// 'X' + U+0300 COMBINING GRAVE ACCENT is a cluster, but most fonts do not have
+// a pre-composed glyph for it, so code points and glyphs are 1:1. Because the
+// length is "+1" and the last character is combining, this string does not hit
+// kMaxCharacterIndex but hits kMaxGlyphs.
+TEST_P(ShapeParameterTest, MaxGlyphsClusterLatin) {
+ const unsigned length = HarfBuzzRunGlyphData::kMaxGlyphs + 1;
+ String string = CreateStringOf('X', length);
+ string.replace(1, 1, u"\u0300");
+ string.replace(length - 2, 2, u"Z\u0300");
+ HarfBuzzShaper shaper(string);
+ scoped_refptr<ShapeResult> result = ShapeWithParameter(&shaper);
+ EXPECT_EQ(length, result->NumCharacters());
+ EXPECT_EQ(length, result->NumGlyphs());
+ Vector<ShapeResultRunData> runs = ShapeResultRunData::Get(result);
+ if (IsRtl(GetParam()))
+ runs.Reverse();
+ EXPECT_THAT(
+ runs, testing::ElementsAre(
+ ShapeResultRunData{0, length - 2, length - 2, HB_SCRIPT_LATIN},
+ ShapeResultRunData{length - 2, 2u, 2u, HB_SCRIPT_LATIN}));
+}
+
+// Same as MaxGlyphsClusterLatin, but by making the length "+2", this string
+// hits kMaxCharacterIndex.
+TEST_P(ShapeParameterTest, MaxGlyphsClusterLatin2) {
+ const unsigned length = HarfBuzzRunGlyphData::kMaxGlyphs + 2;
+ String string = CreateStringOf('X', length);
+ string.replace(1, 1, u"\u0300");
+ string.replace(length - 2, 2, u"Z\u0300");
+ HarfBuzzShaper shaper(string);
+ scoped_refptr<ShapeResult> result = ShapeWithParameter(&shaper);
+ EXPECT_EQ(length, result->NumCharacters());
+ EXPECT_EQ(length, result->NumGlyphs());
+ Vector<ShapeResultRunData> runs = ShapeResultRunData::Get(result);
+ if (IsRtl(GetParam()))
+ runs.Reverse();
+ EXPECT_THAT(
+ runs, testing::ElementsAre(
+ ShapeResultRunData{0, length - 2, length - 2, HB_SCRIPT_LATIN},
+ ShapeResultRunData{length - 2, 2u, 2u, HB_SCRIPT_LATIN}));
+}
+
+TEST_P(ShapeParameterTest, MaxGlyphsClusterDevanagari) {
+ const unsigned length = HarfBuzzRunGlyphData::kMaxCharacterIndex + 2;
+ String string = CreateStringOf(0x930, length);
+ string.replace(0, 3, u"\u0930\u093F\u0902");
+ string.replace(length - 3, 3, u"\u0930\u093F\u0902");
+ HarfBuzzShaper shaper(string);
+ scoped_refptr<ShapeResult> result = ShapeWithParameter(&shaper);
+ EXPECT_EQ(length, result->NumCharacters());
+#if defined(OS_LINUX)
+ // Linux doesn't have glyphs. We can't test RunInfo without all glyphs.
+ if (result->NumGlyphs() != length)
+ return;
+#endif
+ EXPECT_EQ(length, result->NumGlyphs());
+ Vector<ShapeResultRunData> runs = ShapeResultRunData::Get(result);
+ if (IsRtl(GetParam()))
+ runs.Reverse();
+ EXPECT_THAT(
+ runs,
+ testing::ElementsAre(
+ ShapeResultRunData{0, length - 3, length - 3, HB_SCRIPT_DEVANAGARI},
+ ShapeResultRunData{length - 3, 3u, 3u, HB_SCRIPT_DEVANAGARI}));
+}
+
TEST_P(ShapeParameterTest, ZeroWidthSpace) {
UChar string[] = {kZeroWidthSpaceCharacter,
kZeroWidthSpaceCharacter,
@@ -679,11 +814,9 @@ TEST_P(OffsetForPositionTest, Data) {
scoped_refptr<ShapeResult> result =
SplitRun(shaper.Shape(&ahem, TextDirection::kLtr), 2);
EXPECT_EQ(data.offset_ltr,
- result->OffsetForPosition(data.position, OnlyFullGlyphs,
- DontBreakGlyphs));
- EXPECT_EQ(data.hit_test_ltr,
- result->OffsetForPosition(data.position, IncludePartialGlyphs,
- DontBreakGlyphs));
+ result->OffsetForPosition(data.position, DontBreakGlyphs));
+ EXPECT_EQ(data.hit_test_ltr, result->CaretOffsetForHitTest(
+ data.position, string, DontBreakGlyphs));
EXPECT_EQ(data.fit_ltr_ltr,
result->OffsetToFit(data.position, TextDirection::kLtr));
EXPECT_EQ(data.fit_ltr_rtl,
@@ -691,11 +824,9 @@ TEST_P(OffsetForPositionTest, Data) {
result = SplitRun(shaper.Shape(&ahem, TextDirection::kRtl), 3);
EXPECT_EQ(data.offset_rtl,
- result->OffsetForPosition(data.position, OnlyFullGlyphs,
- DontBreakGlyphs));
- EXPECT_EQ(data.hit_test_rtl,
- result->OffsetForPosition(data.position, IncludePartialGlyphs,
- DontBreakGlyphs));
+ result->OffsetForPosition(data.position, DontBreakGlyphs));
+ EXPECT_EQ(data.hit_test_rtl, result->CaretOffsetForHitTest(
+ data.position, string, DontBreakGlyphs));
EXPECT_EQ(data.fit_rtl_ltr,
result->OffsetToFit(data.position, TextDirection::kLtr));
EXPECT_EQ(data.fit_rtl_rtl,
@@ -743,12 +874,15 @@ TEST_F(HarfBuzzShaperTest, EmojiZWJSequence) {
// A Value-Parameterized Test class to test OffsetForPosition() with
// |include_partial_glyphs| parameter.
-class IncludePartialGlyphsTest : public HarfBuzzShaperTest,
- public ::testing::WithParamInterface<bool> {};
+class IncludePartialGlyphsTest
+ : public HarfBuzzShaperTest,
+ public ::testing::WithParamInterface<IncludePartialGlyphsOption> {};
-INSTANTIATE_TEST_CASE_P(OffsetForPositionTest,
- IncludePartialGlyphsTest,
- ::testing::Bool());
+INSTANTIATE_TEST_CASE_P(
+ HarfBuzzShaperTest,
+ IncludePartialGlyphsTest,
+ ::testing::Values(IncludePartialGlyphsOption::OnlyFullGlyphs,
+ IncludePartialGlyphsOption::IncludePartialGlyphs));
TEST_P(IncludePartialGlyphsTest,
OffsetForPositionMatchesPositionForOffsetLatin) {
@@ -758,84 +892,77 @@ TEST_P(IncludePartialGlyphsTest,
HarfBuzzShaper shaper(string);
scoped_refptr<ShapeResult> result = shaper.Shape(&font, direction);
- bool include_partial_glyphs = GetParam();
- IncludePartialGlyphsOption partial =
- include_partial_glyphs ? IncludePartialGlyphs : OnlyFullGlyphs;
-
- EXPECT_EQ(0u, result->OffsetForPosition(result->PositionForOffset(0), partial,
- DontBreakGlyphs));
- EXPECT_EQ(1u, result->OffsetForPosition(result->PositionForOffset(1), partial,
- DontBreakGlyphs));
- EXPECT_EQ(2u, result->OffsetForPosition(result->PositionForOffset(2), partial,
- DontBreakGlyphs));
- EXPECT_EQ(3u, result->OffsetForPosition(result->PositionForOffset(3), partial,
- DontBreakGlyphs));
- EXPECT_EQ(4u, result->OffsetForPosition(result->PositionForOffset(4), partial,
- DontBreakGlyphs));
- EXPECT_EQ(5u, result->OffsetForPosition(result->PositionForOffset(5), partial,
- DontBreakGlyphs));
- EXPECT_EQ(6u, result->OffsetForPosition(result->PositionForOffset(6), partial,
- DontBreakGlyphs));
- EXPECT_EQ(7u, result->OffsetForPosition(result->PositionForOffset(7), partial,
- DontBreakGlyphs));
- EXPECT_EQ(8u, result->OffsetForPosition(result->PositionForOffset(8), partial,
- DontBreakGlyphs));
- EXPECT_EQ(9u, result->OffsetForPosition(result->PositionForOffset(9), partial,
- DontBreakGlyphs));
+ IncludePartialGlyphsOption partial = GetParam();
+ EXPECT_EQ(0u, result->OffsetForPosition(result->PositionForOffset(0), string,
+ partial, DontBreakGlyphs));
+ EXPECT_EQ(1u, result->OffsetForPosition(result->PositionForOffset(1), string,
+ partial, DontBreakGlyphs));
+ EXPECT_EQ(2u, result->OffsetForPosition(result->PositionForOffset(2), string,
+ partial, DontBreakGlyphs));
+ EXPECT_EQ(3u, result->OffsetForPosition(result->PositionForOffset(3), string,
+ partial, DontBreakGlyphs));
+ EXPECT_EQ(4u, result->OffsetForPosition(result->PositionForOffset(4), string,
+ partial, DontBreakGlyphs));
+ EXPECT_EQ(5u, result->OffsetForPosition(result->PositionForOffset(5), string,
+ partial, DontBreakGlyphs));
+ EXPECT_EQ(6u, result->OffsetForPosition(result->PositionForOffset(6), string,
+ partial, DontBreakGlyphs));
+ EXPECT_EQ(7u, result->OffsetForPosition(result->PositionForOffset(7), string,
+ partial, DontBreakGlyphs));
+ EXPECT_EQ(8u, result->OffsetForPosition(result->PositionForOffset(8), string,
+ partial, DontBreakGlyphs));
+ EXPECT_EQ(9u, result->OffsetForPosition(result->PositionForOffset(9), string,
+ partial, DontBreakGlyphs));
EXPECT_EQ(10u, result->OffsetForPosition(result->PositionForOffset(10),
- partial, DontBreakGlyphs));
+ string, partial, DontBreakGlyphs));
EXPECT_EQ(11u, result->OffsetForPosition(result->PositionForOffset(11),
- partial, DontBreakGlyphs));
+ string, partial, DontBreakGlyphs));
EXPECT_EQ(12u, result->OffsetForPosition(result->PositionForOffset(12),
- partial, DontBreakGlyphs));
+ string, partial, DontBreakGlyphs));
}
TEST_P(IncludePartialGlyphsTest,
OffsetForPositionMatchesPositionForOffsetArabic) {
UChar arabic_string[] = {0x628, 0x64A, 0x629};
+ String string(arabic_string, 3);
TextDirection direction = TextDirection::kRtl;
- HarfBuzzShaper shaper(String(arabic_string, 3));
+ HarfBuzzShaper shaper(string);
scoped_refptr<ShapeResult> result = shaper.Shape(&font, direction);
- bool include_partial_glyphs = GetParam();
- IncludePartialGlyphsOption partial =
- include_partial_glyphs ? IncludePartialGlyphs : OnlyFullGlyphs;
-
- EXPECT_EQ(0u, result->OffsetForPosition(result->PositionForOffset(0), partial,
- DontBreakGlyphs));
- EXPECT_EQ(1u, result->OffsetForPosition(result->PositionForOffset(1), partial,
- DontBreakGlyphs));
- EXPECT_EQ(2u, result->OffsetForPosition(result->PositionForOffset(2), partial,
- DontBreakGlyphs));
- EXPECT_EQ(3u, result->OffsetForPosition(result->PositionForOffset(3), partial,
- DontBreakGlyphs));
+ IncludePartialGlyphsOption partial = GetParam();
+ EXPECT_EQ(0u, result->OffsetForPosition(result->PositionForOffset(0), string,
+ partial, DontBreakGlyphs));
+ EXPECT_EQ(1u, result->OffsetForPosition(result->PositionForOffset(1), string,
+ partial, DontBreakGlyphs));
+ EXPECT_EQ(2u, result->OffsetForPosition(result->PositionForOffset(2), string,
+ partial, DontBreakGlyphs));
+ EXPECT_EQ(3u, result->OffsetForPosition(result->PositionForOffset(3), string,
+ partial, DontBreakGlyphs));
}
TEST_P(IncludePartialGlyphsTest,
OffsetForPositionMatchesPositionForOffsetMixed) {
UChar mixed_string[] = {0x628, 0x64A, 0x629, 0xE20, 0x65E5, 0x62};
- HarfBuzzShaper shaper(String(mixed_string, 6));
+ String string(mixed_string, 6);
+ HarfBuzzShaper shaper(string);
scoped_refptr<ShapeResult> result = shaper.Shape(&font, TextDirection::kLtr);
- bool include_partial_glyphs = GetParam();
- IncludePartialGlyphsOption partial =
- include_partial_glyphs ? IncludePartialGlyphs : OnlyFullGlyphs;
-
- EXPECT_EQ(0u, result->OffsetForPosition(result->PositionForOffset(0), partial,
- DontBreakGlyphs));
- EXPECT_EQ(1u, result->OffsetForPosition(result->PositionForOffset(1), partial,
- DontBreakGlyphs));
- EXPECT_EQ(2u, result->OffsetForPosition(result->PositionForOffset(2), partial,
- DontBreakGlyphs));
- EXPECT_EQ(3u, result->OffsetForPosition(result->PositionForOffset(3), partial,
- DontBreakGlyphs));
- EXPECT_EQ(4u, result->OffsetForPosition(result->PositionForOffset(4), partial,
- DontBreakGlyphs));
- EXPECT_EQ(5u, result->OffsetForPosition(result->PositionForOffset(5), partial,
- DontBreakGlyphs));
- EXPECT_EQ(6u, result->OffsetForPosition(result->PositionForOffset(6), partial,
- DontBreakGlyphs));
+ IncludePartialGlyphsOption partial = GetParam();
+ EXPECT_EQ(0u, result->OffsetForPosition(result->PositionForOffset(0), string,
+ partial, DontBreakGlyphs));
+ EXPECT_EQ(1u, result->OffsetForPosition(result->PositionForOffset(1), string,
+ partial, DontBreakGlyphs));
+ EXPECT_EQ(2u, result->OffsetForPosition(result->PositionForOffset(2), string,
+ partial, DontBreakGlyphs));
+ EXPECT_EQ(3u, result->OffsetForPosition(result->PositionForOffset(3), string,
+ partial, DontBreakGlyphs));
+ EXPECT_EQ(4u, result->OffsetForPosition(result->PositionForOffset(4), string,
+ partial, DontBreakGlyphs));
+ EXPECT_EQ(5u, result->OffsetForPosition(result->PositionForOffset(5), string,
+ partial, DontBreakGlyphs));
+ EXPECT_EQ(6u, result->OffsetForPosition(result->PositionForOffset(6), string,
+ partial, DontBreakGlyphs));
}
TEST_F(HarfBuzzShaperTest, CachedOffsetPositionMappingForOffsetLatin) {
@@ -890,6 +1017,46 @@ TEST_F(HarfBuzzShaperTest, CachedOffsetPositionMappingMixed) {
EXPECT_EQ(6u, sr->CachedOffsetForPosition(sr->CachedPositionForOffset(6)));
}
+TEST_F(HarfBuzzShaperTest, PositionForOffsetMultiGlyphClusterLtr) {
+ // In this Hindi text, each code unit produces a glyph, and the first 3 glyphs
+ // form a grapheme cluster, and the last 2 glyphs form another.
+ String string(u"\u0930\u093F\u0902\u0926\u0940");
+ TextDirection direction = TextDirection::kLtr;
+ HarfBuzzShaper shaper(string);
+ scoped_refptr<ShapeResult> sr = shaper.Shape(&font, direction);
+ sr->EnsurePositionData();
+
+ // The first 3 code units should be at position 0.
+ EXPECT_EQ(0, sr->CachedPositionForOffset(0));
+ EXPECT_EQ(0, sr->CachedPositionForOffset(1));
+ EXPECT_EQ(0, sr->CachedPositionForOffset(2));
+ // The last 2 code units should be > 0, and the same position.
+ EXPECT_GT(sr->CachedPositionForOffset(3), 0);
+ EXPECT_EQ(sr->CachedPositionForOffset(3), sr->CachedPositionForOffset(4));
+}
+
+TEST_F(HarfBuzzShaperTest, PositionForOffsetMultiGlyphClusterRtl) {
+ // In this Hindi text, each code unit produces a glyph, and the first 3 glyphs
+ // form a grapheme cluster, and the last 2 glyphs form another.
+ String string(u"\u0930\u093F\u0902\u0926\u0940");
+ TextDirection direction = TextDirection::kRtl;
+ HarfBuzzShaper shaper(string);
+ scoped_refptr<ShapeResult> sr = shaper.Shape(&font, direction);
+ sr->EnsurePositionData();
+
+ // The first 3 code units should be at position 0, but since this is RTL, the
+ // position is the right edgef of the character, and thus > 0.
+ float pos0 = sr->CachedPositionForOffset(0);
+ EXPECT_GT(pos0, 0);
+ EXPECT_EQ(pos0, sr->CachedPositionForOffset(1));
+ EXPECT_EQ(pos0, sr->CachedPositionForOffset(2));
+ // The last 2 code units should be > 0, and the same position.
+ float pos3 = sr->CachedPositionForOffset(3);
+ EXPECT_GT(pos3, 0);
+ EXPECT_LT(pos3, pos0);
+ EXPECT_EQ(pos3, sr->CachedPositionForOffset(4));
+}
+
TEST_F(HarfBuzzShaperTest, PositionForOffsetMissingGlyph) {
String string(u"\u0633\u0644\u0627\u0645");
HarfBuzzShaper shaper(string);
@@ -1283,8 +1450,15 @@ TEST_F(HarfBuzzShaperTest, SafeToBreakLatinDiscretionaryLigatures) {
referenceResult->SnappedStartPositionForOffset(12));
}
-// TODO(layout-dev): This test fails on Mac due to AAT shaping.
-TEST_F(HarfBuzzShaperTest, DISABLED_SafeToBreakArabicCommonLigatures) {
+// TODO(crbug.com/870712): This test fails on Mac due to AAT shaping and
+// font fallback differences on Android.
+#if defined(OS_MACOSX) || defined(OS_ANDROID)
+#define MAYBE_SafeToBreakArabicCommonLigatures \
+ DISABLED_SafeToBreakArabicCommonLigatures
+#else
+#define MAYBE_SafeToBreakArabicCommonLigatures SafeToBreakArabicCommonLigatures
+#endif
+TEST_F(HarfBuzzShaperTest, MAYBE_SafeToBreakArabicCommonLigatures) {
FontDescription::VariantLigatures ligatures;
ligatures.common = FontDescription::kEnabledLigaturesState;
@@ -1316,7 +1490,12 @@ TEST_F(HarfBuzzShaperTest, DISABLED_SafeToBreakArabicCommonLigatures) {
// Test when some characters are missing in |runs_|.
// RTL on Mac may not have runs for all characters. crbug.com/774034
-TEST_P(ShapeParameterTest, DISABLED_SafeToBreakMissingRun) {
+#if defined(OS_MACOSX)
+#define MAYBE_SafeToBreakMissingRun DISABLED_SafeToBreakMissingRun
+#else
+#define MAYBE_SafeToBreakMissingRun SafeToBreakMissingRun
+#endif
+TEST_P(ShapeParameterTest, MAYBE_SafeToBreakMissingRun) {
TextDirection direction = GetParam();
scoped_refptr<ShapeResult> result = ShapeResult::Create(&font, 8, direction);
result->InsertRunForTesting(2, 1, direction, {0});
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 5d23754b831..ba444da6503 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
@@ -39,16 +39,19 @@
#include "base/containers/adapters.h"
#include "base/memory/ptr_util.h"
+#include "build/build_config.h"
#include "third_party/blink/renderer/platform/fonts/character_range.h"
#include "third_party/blink/renderer/platform/fonts/font.h"
#include "third_party/blink/renderer/platform/fonts/shaping/shape_result_buffer.h"
#include "third_party/blink/renderer/platform/fonts/shaping/shape_result_inline_headers.h"
#include "third_party/blink/renderer/platform/fonts/shaping/shape_result_spacing.h"
+#include "third_party/blink/renderer/platform/text/text_break_iterator.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
namespace blink {
constexpr unsigned HarfBuzzRunGlyphData::kMaxCharacterIndex;
+constexpr unsigned HarfBuzzRunGlyphData::kMaxGlyphs;
unsigned ShapeResult::RunInfo::NextSafeToBreakOffset(unsigned offset) const {
DCHECK_LE(offset, num_characters_);
@@ -110,6 +113,34 @@ unsigned ShapeResult::RunInfo::NumGraphemes(unsigned start,
return graphemes_[end - 1] - graphemes_[start] + 1;
}
+void ShapeResult::EnsureGraphemes(const StringView& text) const {
+ DCHECK_EQ(NumCharacters(), text.length());
+
+ // Hit-testing, canvas, etc. may still call this function for 0-length text,
+ // or glyphs may be missing at all.
+ if (runs_.IsEmpty())
+ return;
+
+ bool is_computed = !runs_.front()->graphemes_.IsEmpty();
+#if DCHECK_IS_ON()
+ for (const auto& run : runs_)
+ DCHECK_EQ(is_computed, !run->graphemes_.IsEmpty());
+#endif
+ if (is_computed)
+ return;
+
+ unsigned result_start_index = StartIndexForResult();
+ for (const auto& run : runs_) {
+ if (!run)
+ continue;
+ DCHECK_GE(run->start_index_, result_start_index);
+ GraphemesClusterList(
+ StringView(text, run->start_index_ - result_start_index,
+ run->num_characters_),
+ &run->graphemes_);
+ }
+}
+
// XPositionForOffset returns the X position (in layout space) from the
// beginning of the run to the beginning of the cluster of glyphs for X
// character.
@@ -350,6 +381,7 @@ ShapeResult::ShapeResult(const ShapeResult& other)
: width_(other.width_),
glyph_bounding_box_(other.glyph_bounding_box_),
primary_font_(other.primary_font_),
+ start_index_(other.start_index_),
num_characters_(other.num_characters_),
num_glyphs_(other.num_glyphs_),
direction_(other.direction_),
@@ -369,30 +401,12 @@ size_t ShapeResult::ByteSize() const {
return self_byte_size;
}
-CharacterRange ShapeResult::GetCharacterRange(unsigned from,
+CharacterRange ShapeResult::GetCharacterRange(const StringView& text,
+ unsigned from,
unsigned to) const {
- return ShapeResultBuffer::GetCharacterRange(this, Direction(), Width(), from,
- to);
-}
-
-unsigned ShapeResult::StartIndexForResult() const {
- if (UNLIKELY(runs_.IsEmpty()))
- return 0;
- const RunInfo& first_run = *runs_.front();
- if (!Rtl())
- return first_run.start_index_;
- unsigned end = first_run.start_index_ + first_run.num_characters_;
- DCHECK_GE(end, NumCharacters());
- return end - NumCharacters();
-}
-
-unsigned ShapeResult::EndIndexForResult() const {
- if (UNLIKELY(runs_.IsEmpty()))
- return NumCharacters();
- const RunInfo& first_run = *runs_.front();
- if (!Rtl())
- return first_run.start_index_ + NumCharacters();
- return first_run.start_index_ + first_run.num_characters_;
+ EnsureGraphemes(text);
+ return ShapeResultBuffer::GetCharacterRange(this, text, Direction(), Width(),
+ from, to);
}
scoped_refptr<ShapeResult> ShapeResult::MutableUnique() const {
@@ -537,9 +551,13 @@ unsigned ShapeResult::OffsetForPosition(
return result.right_character_index;
}
-unsigned ShapeResult::OffsetForHitTest(
+unsigned ShapeResult::CaretOffsetForHitTest(
float x,
+ const StringView& text,
BreakGlyphsOption break_glyphs_option) const {
+ if (break_glyphs_option == BreakGlyphs)
+ EnsureGraphemes(text);
+
GlyphIndexResult result;
OffsetForPosition(x, break_glyphs_option, &result);
@@ -603,6 +621,14 @@ float ShapeResult::PositionForOffset(
return offset_x;
}
+float ShapeResult::CaretPositionForOffset(
+ unsigned offset,
+ const StringView& text,
+ AdjustMidCluster adjust_mid_cluster) const {
+ EnsureGraphemes(text);
+ return PositionForOffset(offset, adjust_mid_cluster);
+}
+
void ShapeResult::FallbackFonts(
HashSet<const SimpleFontData*>* fallback) const {
DCHECK(fallback);
@@ -807,6 +833,82 @@ bool IsSafeToBreakBefore(const hb_glyph_info_t* glyph_infos,
} // anonymous namespace
+// This function computes the number of glyphs and characters that can fit into
+// this RunInfo.
+//
+// HarfBuzzRunGlyphData has a limit kMaxCharacterIndex for the character index
+// in order to packsave memory. Also, RunInfo has kMaxGlyphs to make the number
+// of glyphs predictable and to minimize the buffer reallocations.
+unsigned ShapeResult::RunInfo::LimitNumGlyphs(
+ unsigned start_glyph,
+ unsigned* num_glyphs_in_out,
+ const bool is_ltr,
+ const hb_glyph_info_t* glyph_infos) {
+ unsigned num_glyphs = *num_glyphs_in_out;
+
+ // If there were larger character indexes than kMaxCharacterIndex, reduce
+ // num_glyphs so that all character indexes can fit to kMaxCharacterIndex.
+ // Because code points and glyphs are not always 1:1, we need to check the
+ // first and the last cluster.
+ unsigned start_cluster;
+ if (is_ltr) {
+ start_cluster = glyph_infos[start_glyph].cluster;
+ unsigned last_cluster = glyph_infos[start_glyph + num_glyphs - 1].cluster;
+ unsigned last_character_index = last_cluster - start_cluster;
+ if (UNLIKELY(last_character_index >
+ HarfBuzzRunGlyphData::kMaxCharacterIndex)) {
+ // Make sure the end is a cluster boundary.
+ do {
+ num_glyphs--;
+ num_characters_ = last_character_index;
+ last_cluster = glyph_infos[start_glyph + num_glyphs - 1].cluster;
+ last_character_index = last_cluster - start_cluster;
+ } while (last_character_index > HarfBuzzRunGlyphData::kMaxCharacterIndex);
+ }
+ } else {
+ start_cluster = glyph_infos[start_glyph + num_glyphs - 1].cluster;
+ const unsigned last_cluster = glyph_infos[start_glyph].cluster;
+ unsigned last_character_index = last_cluster - start_cluster;
+ if (UNLIKELY(last_character_index >
+ HarfBuzzRunGlyphData::kMaxCharacterIndex)) {
+ do {
+ num_glyphs--;
+ num_characters_ = last_character_index;
+ start_cluster = glyph_infos[start_glyph + num_glyphs - 1].cluster;
+ last_character_index = last_cluster - start_cluster;
+ } while (last_character_index > HarfBuzzRunGlyphData::kMaxCharacterIndex);
+ }
+ }
+
+ // num_glyphs maybe still larger than kMaxGlyphs after it was reduced to fit
+ // to kMaxCharacterIndex. Reduce to kMaxGlyphs if so.
+ if (UNLIKELY(num_glyphs > HarfBuzzRunGlyphData::kMaxGlyphs)) {
+ num_glyphs = HarfBuzzRunGlyphData::kMaxGlyphs;
+
+ // If kMaxGlyphs is not a cluster boundary, reduce further until the last
+ // boundary.
+ const unsigned end_cluster = glyph_infos[start_glyph + num_glyphs].cluster;
+ for (;; num_glyphs--) {
+ if (!num_glyphs) {
+ // Extreme edge case when kMaxGlyphs is one grapheme cluster. We don't
+ // have much choices, just cut at kMaxGlyphs.
+ num_glyphs = HarfBuzzRunGlyphData::kMaxGlyphs;
+ break;
+ }
+ if (glyph_infos[start_glyph + num_glyphs - 1].cluster != end_cluster)
+ break;
+ }
+ num_characters_ = is_ltr ? end_cluster - start_cluster
+ : glyph_infos[start_glyph].cluster - end_cluster;
+ }
+
+ if (num_glyphs == *num_glyphs_in_out)
+ return start_cluster;
+ glyph_data_.Shrink(num_glyphs);
+ *num_glyphs_in_out = num_glyphs;
+ return start_cluster;
+}
+
// Computes glyph positions, sets advance and offset of each glyph to RunInfo.
//
// Also computes glyph bounding box of the run. In this function, glyph bounding
@@ -817,21 +919,21 @@ void ShapeResult::ComputeGlyphPositions(ShapeResult::RunInfo* run,
unsigned num_glyphs,
hb_buffer_t* harfbuzz_buffer) {
DCHECK_EQ(is_horizontal_run, run->IsHorizontal());
- const SimpleFontData& current_font_data = *run->font_data_;
const hb_glyph_info_t* glyph_infos =
hb_buffer_get_glyph_infos(harfbuzz_buffer, nullptr);
const hb_glyph_position_t* glyph_positions =
hb_buffer_get_glyph_positions(harfbuzz_buffer, nullptr);
- const unsigned start_cluster =
- HB_DIRECTION_IS_FORWARD(hb_buffer_get_direction(harfbuzz_buffer))
- ? glyph_infos[start_glyph].cluster
- : glyph_infos[start_glyph + num_glyphs - 1].cluster;
+
+ const bool is_ltr =
+ HB_DIRECTION_IS_FORWARD(hb_buffer_get_direction(harfbuzz_buffer));
+ unsigned start_cluster =
+ run->LimitNumGlyphs(start_glyph, &num_glyphs, is_ltr, glyph_infos);
+ DCHECK_LE(num_glyphs, HarfBuzzRunGlyphData::kMaxGlyphs);
// Compute glyph_origin and glyph_bounding_box in physical, since both offsets
// and boudning box of glyphs are in physical. It's the caller's
// responsibility to convert the united physical bounds to logical.
float total_advance = 0.0f;
- GlyphBoundsAccumulator bounds(width_);
bool has_vertical_offsets = !is_horizontal_run;
// HarfBuzz returns result in visual order, no need to flip for RTL.
@@ -851,28 +953,52 @@ void ShapeResult::ComputeGlyphPositions(ShapeResult::RunInfo* run,
uint16_t character_index =
glyph_infos[start_glyph + i].cluster - start_cluster;
- if (UNLIKELY(character_index > HarfBuzzRunGlyphData::kMaxCharacterIndex)) {
- // If the character index exceeds the limit, abort and shrink the run to
- // what are actually stored.
- run->num_characters_ = character_index;
- run->glyph_data_.Shrink(i);
- break;
- }
+ DCHECK_LE(character_index, HarfBuzzRunGlyphData::kMaxCharacterIndex);
HarfBuzzRunGlyphData& glyph_data = run->glyph_data_[i];
glyph_data.SetGlyphAndPositions(
glyph, character_index, advance, offset,
IsSafeToBreakBefore(glyph_infos + start_glyph, num_glyphs, i));
total_advance += advance;
has_vertical_offsets |= (offset.Height() != 0);
-
- bounds.Unite<is_horizontal_run>(
- glyph_data, current_font_data.BoundsForGlyph(glyph_data.glyph));
- bounds.origin += advance;
}
run->width_ = std::max(0.0f, total_advance);
has_vertical_offsets_ |= has_vertical_offsets;
+ ComputeGlyphBounds<is_horizontal_run>(*run);
+}
+
+template <bool is_horizontal_run>
+void ShapeResult::ComputeGlyphBounds(const ShapeResult::RunInfo& run) {
+ // Skia runs much faster if we give a list of glyph ID rather than calling it
+ // on each glyph.
+ const SimpleFontData& current_font_data = *run.font_data_;
+#if defined(OS_MACOSX)
+ // TODO(kojii): MacOS does not benefit from batching the Skia request due to
+ // https://bugs.chromium.org/p/skia/issues/detail?id=5328 , and the cost to
+ // prepare batching, which is normally much less than the benefit of batching,
+ // is not ignorable unfortunately.
+ GlyphBoundsAccumulator bounds(width_);
+ for (const HarfBuzzRunGlyphData& glyph_data : run.glyph_data_) {
+ bounds.Unite<is_horizontal_run>(
+ glyph_data, current_font_data.BoundsForGlyph(glyph_data.glyph));
+ bounds.origin += glyph_data.advance;
+ }
+#else
+ unsigned num_glyphs = run.glyph_data_.size();
+ Vector<Glyph, 256> glyphs(num_glyphs);
+ for (unsigned i = 0; i < num_glyphs; i++)
+ glyphs[i] = run.glyph_data_[i].glyph;
+ Vector<FloatRect, 256> bounds_list(num_glyphs);
+ current_font_data.BoundsForGlyphs(glyphs, &bounds_list);
+
+ GlyphBoundsAccumulator bounds(width_);
+ for (unsigned i = 0; i < num_glyphs; i++) {
+ const HarfBuzzRunGlyphData& glyph_data = run.glyph_data_[i];
+ bounds.Unite<is_horizontal_run>(glyph_data, bounds_list[i]);
+ bounds.origin += glyph_data.advance;
+ }
+#endif
if (!is_horizontal_run)
bounds.ConvertVerticalRunToLogical(current_font_data.GetFontMetrics());
glyph_bounding_box_.Unite(bounds.bounds);
@@ -884,7 +1010,6 @@ void ShapeResult::InsertRun(std::unique_ptr<ShapeResult::RunInfo> run_to_insert,
hb_buffer_t* harfbuzz_buffer) {
DCHECK_GT(num_glyphs, 0u);
std::unique_ptr<ShapeResult::RunInfo> run(std::move(run_to_insert));
- DCHECK_EQ(num_glyphs, run->glyph_data_.size());
if (run->IsHorizontal()) {
// Inserting a horizontal run into a horizontal or vertical result. In both
@@ -927,6 +1052,10 @@ void ShapeResult::InsertRun(std::unique_ptr<ShapeResult::RunInfo> run) {
// If we didn't find an existing slot to place it, append.
if (run)
runs_.push_back(std::move(run));
+
+ // TODO(layout-dev): We could skip this unless the inserted run is the first
+ // one but determiening that is likely as expensive as the computation.
+ UpdateStartIndex();
}
// Insert a |RunInfo| without glyphs. |StartIndexForResult()| needs a run to
@@ -934,24 +1063,22 @@ void ShapeResult::InsertRun(std::unique_ptr<ShapeResult::RunInfo> run) {
// synthesize a run without glyphs.
void ShapeResult::InsertRunForIndex(unsigned start_character_index) {
DCHECK(runs_.IsEmpty());
- // TODO(fserb): do we need the proper graphemes?
- Vector<unsigned> graphemes;
runs_.push_back(std::make_unique<RunInfo>(
primary_font_.get(), !Rtl() ? HB_DIRECTION_LTR : HB_DIRECTION_RTL,
CanvasRotationInVertical::kRegular, HB_SCRIPT_UNKNOWN,
- start_character_index, 0, num_characters_, graphemes));
+ start_character_index, 0, num_characters_));
+ UpdateStartIndex();
}
ShapeResult::RunInfo* ShapeResult::InsertRunForTesting(
unsigned start_index,
unsigned num_characters,
TextDirection direction,
- Vector<uint16_t> safe_break_offsets,
- Vector<unsigned> graphemes) {
+ Vector<uint16_t> safe_break_offsets) {
std::unique_ptr<RunInfo> run = std::make_unique<ShapeResult::RunInfo>(
nullptr, IsLtr(direction) ? HB_DIRECTION_LTR : HB_DIRECTION_RTL,
CanvasRotationInVertical::kRegular, HB_SCRIPT_COMMON, start_index,
- num_characters, num_characters, std::move(graphemes));
+ num_characters, num_characters);
unsigned i = 0;
for (auto& glyph_data : run->glyph_data_)
glyph_data.SetGlyphAndPositions(0, i++, 0, FloatSize(), false);
@@ -995,6 +1122,21 @@ void ShapeResult::ReorderRtlRuns(unsigned run_size_before) {
runs_.swap(new_runs);
}
+unsigned ShapeResult::ComputeStartIndex() const {
+ if (UNLIKELY(runs_.IsEmpty()))
+ return 0;
+ const RunInfo& first_run = *runs_.front();
+ if (!Rtl()) // Left-to-right.
+ return first_run.start_index_;
+ // Right-to-left.
+ unsigned end_index = first_run.start_index_ + first_run.num_characters_;
+ return end_index - num_characters_;
+}
+
+void ShapeResult::UpdateStartIndex() {
+ start_index_ = ComputeStartIndex();
+}
+
// Returns the left of the glyph bounding box of the left most character.
float ShapeResult::LineLeftBounds() const {
DCHECK(!runs_.IsEmpty());
@@ -1077,8 +1219,10 @@ void ShapeResult::CopyRange(unsigned start_offset,
}
}
- if (!target->num_glyphs_)
+ if (!target->num_glyphs_) {
+ target->UpdateStartIndex();
return;
+ }
// Runs in RTL result are in visual order, and that new runs should be
// prepended. Reorder appended runs.
@@ -1108,6 +1252,7 @@ void ShapeResult::CopyRange(unsigned start_offset,
target->glyph_bounding_box_.UniteIfNonZero(adjusted_box);
target->has_vertical_offsets_ |= has_vertical_offsets_;
+ target->UpdateStartIndex();
#if DCHECK_IS_ON()
DCHECK_EQ(target->num_characters_ - target_num_characters_before,
@@ -1142,6 +1287,7 @@ scoped_refptr<ShapeResult> ShapeResult::CopyAdjustedOffset(
}
}
+ result->UpdateStartIndex();
return result;
}
@@ -1153,6 +1299,7 @@ void ShapeResult::CheckConsistency() const {
return;
}
+ DCHECK_EQ(start_index_, ComputeStartIndex());
const unsigned start_index = StartIndexForResult();
unsigned index = start_index;
unsigned num_glyphs = 0;
@@ -1187,12 +1334,9 @@ scoped_refptr<ShapeResult> ShapeResult::CreateForTabulationCharacters(
const SimpleFontData* font_data = font->PrimaryFont();
// Tab characters are always LTR or RTL, not TTB, even when
// isVerticalAnyUpright().
- // We don't pass proper graphemes for tabulation.
- Vector<unsigned> graphemes;
std::unique_ptr<ShapeResult::RunInfo> run = std::make_unique<RunInfo>(
font_data, text_run.Rtl() ? HB_DIRECTION_RTL : HB_DIRECTION_LTR,
- CanvasRotationInVertical::kRegular, HB_SCRIPT_COMMON, 0, count, count,
- graphemes);
+ CanvasRotationInVertical::kRegular, HB_SCRIPT_COMMON, 0, count, count);
float position = text_run.XPos() + position_offset;
float start_position = position;
for (unsigned i = 0; i < count; i++) {
@@ -1213,6 +1357,7 @@ scoped_refptr<ShapeResult> ShapeResult::CreateForTabulationCharacters(
result->has_vertical_offsets_ =
font_data->PlatformData().IsVerticalAnyUpright();
result->runs_.push_back(std::move(run));
+ result->UpdateStartIndex();
return result;
}
@@ -1268,71 +1413,69 @@ template <bool rtl>
void ShapeResult::ComputePositionData() const {
auto& data = character_position_->data_;
unsigned start_offset = StartIndexForResult();
- unsigned next_character_index;
- float run_advance;
-
- if (!rtl) {
- next_character_index = 0;
- run_advance = 0;
- } else {
- DCHECK_GE(EndIndexForResult(), start_offset + 1);
- next_character_index = EndIndexForResult() - (start_offset + 1);
- run_advance = width_;
- }
-
+ unsigned next_character_index = 0;
+ float run_advance = 0;
+ float last_x_position = 0;
+
+ // Iterate runs/glyphs in the visual order; i.e., from the left edge
+ // regardless of the directionality, so that |x_position| is always in
+ // ascending order.
+ // TODO(kojii): It does not work when large negative letter-/word-
+ // spacing is applied.
for (const auto& run : runs_) {
if (!run)
continue;
+ // Assumes all runs have the same directionality as the ShapeResult so that
+ // |x_position| is in ascending order.
+ DCHECK_EQ(Rtl(), run->Rtl());
+
float total_advance = run_advance;
for (const auto& glyph_data : run->glyph_data_) {
- DCHECK_GE(run->start_index_ + glyph_data.character_index, start_offset);
+ DCHECK_GE(run->start_index_, start_offset);
unsigned character_index =
run->start_index_ + glyph_data.character_index - start_offset;
- // Multiple glyphs may have the same character index and not all character
- // indices may have glyphs.
- // For character indices without glyps set the x-position to that of the
- // nearest preceding glyph.
- if (!rtl) {
- for (unsigned i = next_character_index; i < character_index; i++) {
- DCHECK_LT(i, num_characters_);
- data[i] = {total_advance, false};
- }
+ // Make |character_index| to the visual offset.
+ DCHECK_LT(character_index, num_characters_);
+ if (rtl)
+ character_index = num_characters_ - character_index - 1;
- // TODO(layout-dev): This is a bit of a hack, need to represent next
- // better for RTL. Perhaps by storing last index instead and subtracting
- // one here instead.
- } else if (next_character_index != static_cast<unsigned>(-1)) {
- for (unsigned i = next_character_index; i > character_index; i--) {
- DCHECK_LT(i, num_characters_);
- data[i] = {total_advance, false};
+ // If this glyph is the first glyph of a new cluster, set the data.
+ // Otherwise, |data[character_index]| is already set. Do not overwrite.
+ DCHECK_LT(character_index, num_characters_);
+ if (next_character_index <= character_index) {
+ if (next_character_index < character_index) {
+ // Multiple glyphs may have the same character index and not all
+ // character indices may have glyphs. For character indices without
+ // glyphs set the x-position to that of the nearest preceding glyph in
+ // the logical order; i.e., the last position for LTR or this position
+ // for RTL.
+ float x_position = !rtl ? last_x_position : total_advance;
+ for (unsigned i = next_character_index; i < character_index; i++) {
+ DCHECK_LT(i, num_characters_);
+ data[i] = {x_position, false, false};
+ }
}
- }
-
- // For glyphs with the same character index the last logical one wins.
- // This is the last visual one in LTR, no need to do anything speical.
- // For RTL this is the first visual one so skip subsequent ones with the
- // same character index.
- if (rtl && next_character_index + 1 == character_index)
- continue;
- // For glyphs with the same character index in LTR take the advance from
- // the last one but the safe to break flag from the first.
- DCHECK_LT(character_index, num_characters_);
- bool safe_to_break =
- next_character_index > character_index
- ? data[next_character_index - 1].safe_to_break_before
- : glyph_data.safe_to_break_before;
- data[character_index] = {total_advance, safe_to_break};
+ data[character_index] = {total_advance, true,
+ glyph_data.safe_to_break_before};
+ last_x_position = total_advance;
+ }
total_advance += glyph_data.advance;
- next_character_index = character_index + (!rtl ? 1 : -1);
+ next_character_index = character_index + 1;
+ }
+ run_advance += run->width_;
+ }
+
+ // Fill |x_position| for the rest of characters, when they don't have
+ // corresponding glyphs.
+ if (next_character_index < num_characters_) {
+ float x_position = !rtl ? last_x_position : run_advance;
+ for (unsigned i = next_character_index; i < num_characters_; i++) {
+ data[i] = {x_position, false, false};
}
- if (!rtl)
- run_advance += run->width_;
- else
- run_advance -= run->width_;
}
character_position_->start_offset_ = start_offset;
@@ -1351,23 +1494,25 @@ void ShapeResult::EnsurePositionData() const {
}
unsigned ShapeResult::CachedOffsetForPosition(float x) const {
- // TODO(layout-dev): Remove once CharacterPositionData::OffsetForPosition
- // properly supports RTL.
- if (Rtl())
- return OffsetForPosition(x, DontBreakGlyphs);
-
DCHECK(character_position_);
- return character_position_->OffsetForPosition(x);
+ unsigned offset = character_position_->OffsetForPosition(x, Rtl());
+#if 0
+ // TODO(kojii): This DCHECK fails in ~10 tests. Needs investigations.
+ DCHECK_EQ(OffsetForPosition(x, BreakGlyphsOption::DontBreakGlyphs), offset) << x;
+#endif
+ return offset;
}
float ShapeResult::CachedPositionForOffset(unsigned offset) const {
- // TODO(layout-dev): Remove once CharacterPositionData::PositionForOffset
- // properly supports RTL.
- if (Rtl())
- return PositionForOffset(offset);
-
+ DCHECK_GE(offset, 0u);
+ DCHECK_LE(offset, num_characters_);
DCHECK(character_position_);
- return character_position_->PositionForOffset(offset);
+ float position = character_position_->PositionForOffset(offset, Rtl());
+#if 0
+ // TODO(kojii): This DCHECK fails in several tests. Needs investigations.
+ DCHECK_EQ(PositionForOffset(offset), position) << offset;
+#endif
+ return position;
}
unsigned ShapeResult::CachedNextSafeToBreakOffset(unsigned offset) const {
@@ -1389,14 +1534,14 @@ unsigned ShapeResult::CachedPreviousSafeToBreakOffset(unsigned offset) const {
// TODO(eae): Might be worth trying to set midpoint to ~50% more than the number
// of characters in the previous line for the first try. Would cut the number
// of tries in the majority of cases for long strings.
-unsigned ShapeResult::CharacterPositionData::OffsetForPosition(float x) const {
- // At or before start, return offset *before* the first character.
- if (x <= 0)
- return 0;
-
+unsigned ShapeResult::CharacterPositionData::OffsetForPosition(float x,
+ bool rtl) const {
+ // At or before start, return offset *of* the first character.
// At or beyond the end, return offset *after* the last character.
+ if (x <= 0)
+ return !rtl ? 0 : data_.size();
if (x >= width_)
- return data_.size();
+ return !rtl ? data_.size() : 0;
// Do a binary search to find the largest x-position that is less than or
// equal to the supplied x value.
@@ -1407,7 +1552,11 @@ unsigned ShapeResult::CharacterPositionData::OffsetForPosition(float x) const {
unsigned midpoint = low + (high - low) / 2;
if (data_[midpoint].x_position <= x &&
(midpoint + 1 == length || data_[midpoint + 1].x_position > x)) {
- return midpoint;
+ if (!rtl)
+ return midpoint;
+ // The border belongs to the logical next character.
+ return data_[midpoint].x_position == x ? data_.size() - midpoint
+ : data_.size() - midpoint - 1;
}
if (x < data_[midpoint].x_position)
high = midpoint - 1;
@@ -1418,12 +1567,27 @@ unsigned ShapeResult::CharacterPositionData::OffsetForPosition(float x) const {
return 0;
}
-float ShapeResult::CharacterPositionData::PositionForOffset(
- unsigned offset) const {
+float ShapeResult::CharacterPositionData::PositionForOffset(unsigned offset,
+ bool rtl) const {
DCHECK_GT(data_.size(), 0u);
- if (offset >= data_.size())
- return width_;
- return data_[offset].x_position;
+ if (!rtl) {
+ if (offset < data_.size())
+ return data_[offset].x_position;
+ } else {
+ if (offset >= data_.size())
+ return 0;
+ // Return the left edge of the next character because in RTL, the position
+ // is the right edge of the character.
+ for (unsigned visual_offset = data_.size() - offset - 1;
+ visual_offset < data_.size(); visual_offset++) {
+ if (data_[visual_offset].is_cluster_base) {
+ return visual_offset + 1 < data_.size()
+ ? data_[visual_offset + 1].x_position
+ : width_;
+ }
+ }
+ }
+ return width_;
}
unsigned ShapeResult::CharacterPositionData::NextSafeToBreakOffset(
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 926faed4e2b..05a88058e82 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
@@ -64,6 +64,8 @@ enum class AdjustMidCluster {
struct ShapeResultCharacterData {
DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
float x_position;
+ // Set for the logical first character of a cluster.
+ unsigned is_cluster_base : 1;
unsigned safe_to_break_before : 1;
};
@@ -111,10 +113,13 @@ class PLATFORM_EXPORT ShapeResult : public RefCounted<ShapeResult> {
// even when the result is in vertical flow.
const FloatRect& Bounds() const { return glyph_bounding_box_; }
unsigned NumCharacters() const { return num_characters_; }
- CharacterRange GetCharacterRange(unsigned from, unsigned to) const;
+ unsigned NumGlyphs() const { return num_glyphs_; }
+ CharacterRange GetCharacterRange(const StringView& text,
+ unsigned from,
+ unsigned to) const;
// The character start/end index of a range shape result.
- unsigned StartIndexForResult() const;
- unsigned EndIndexForResult() const;
+ unsigned StartIndexForResult() const { return start_index_; }
+ unsigned EndIndexForResult() const { return start_index_ + num_characters_; }
void FallbackFonts(HashSet<const SimpleFontData*>*) const;
TextDirection Direction() const {
return static_cast<TextDirection>(direction_);
@@ -145,21 +150,34 @@ class PLATFORM_EXPORT ShapeResult : public RefCounted<ShapeResult> {
// whether |x| is on the left-half or the right-half of the glyph, it
// determines the left-boundary or the right-boundary, then computes the
// offset from the bidi direction.
- unsigned OffsetForHitTest(float x, BreakGlyphsOption) const;
+ unsigned CaretOffsetForHitTest(float x,
+ const StringView& text,
+ BreakGlyphsOption) const;
// Returns the offset that can fit to between |x| and the left or the right
// edge. The side of the edge is determined by |line_direction|.
unsigned OffsetToFit(float x, TextDirection line_direction) const;
unsigned OffsetForPosition(float x,
+ const StringView& text,
IncludePartialGlyphsOption include_partial_glyphs,
BreakGlyphsOption break_glyphs_option) const {
- return include_partial_glyphs == OnlyFullGlyphs
- ? OffsetForPosition(x, break_glyphs_option)
- : OffsetForHitTest(x, break_glyphs_option);
+ if (include_partial_glyphs == OnlyFullGlyphs) {
+ // TODO(kojii): Consider prohibiting OnlyFullGlyphs+BreakGlyphs, used only
+ // in tests.
+ if (break_glyphs_option == BreakGlyphs)
+ EnsureGraphemes(text);
+ return OffsetForPosition(x, break_glyphs_option);
+ }
+ return CaretOffsetForHitTest(x, text, break_glyphs_option);
}
// Returns the position for a given offset, relative to StartIndexForResult.
float PositionForOffset(unsigned offset,
AdjustMidCluster = AdjustMidCluster::kToEnd) const;
+ // Similar to |PositionForOffset| with mid-glyph (mid-ligature) support.
+ float CaretPositionForOffset(
+ unsigned offset,
+ const StringView& text,
+ AdjustMidCluster = AdjustMidCluster::kToEnd) const;
LayoutUnit SnappedStartPositionForOffset(unsigned offset) const {
return LayoutUnit::FromFloatFloor(PositionForOffset(offset));
}
@@ -217,8 +235,7 @@ class PLATFORM_EXPORT ShapeResult : public RefCounted<ShapeResult> {
RunInfo* InsertRunForTesting(unsigned start_index,
unsigned num_characters,
TextDirection,
- Vector<uint16_t> safe_break_offsets = {},
- Vector<unsigned> graphemes = {});
+ Vector<uint16_t> safe_break_offsets = {});
#if DCHECK_IS_ON()
void CheckConsistency() const;
#endif
@@ -235,9 +252,14 @@ class PLATFORM_EXPORT ShapeResult : public RefCounted<ShapeResult> {
new ShapeResult(font_data, num_characters, direction));
}
+ // Ensure |grapheme_| is computed. |BreakGlyphs| is valid only when
+ // |grapheme_| is computed.
+ void EnsureGraphemes(const StringView& text) const;
+
struct GlyphIndexResult {
STACK_ALLOCATED();
+ public:
unsigned run_index = 0;
// The total number of characters of runs_[0..run_index - 1].
unsigned characters_on_left_runs = 0;
@@ -275,12 +297,14 @@ class PLATFORM_EXPORT ShapeResult : public RefCounted<ShapeResult> {
// Returns the offset of the last character that fully fits before the given
// x-position.
- unsigned OffsetForPosition(float x) const;
+ unsigned OffsetForPosition(float x, bool rtl) const;
// Returns the x-position for a given offset.
- float PositionForOffset(unsigned offset) const;
+ float PositionForOffset(unsigned offset, bool rtl) const;
private:
+ // This vector is indexed by visual-offset; the character offset from the
+ // left edge regardless of the TextDirection.
Vector<ShapeResultCharacterData> data_;
unsigned start_offset_;
float width_;
@@ -299,6 +323,8 @@ class PLATFORM_EXPORT ShapeResult : public RefCounted<ShapeResult> {
unsigned start_glyph,
unsigned num_glyphs,
hb_buffer_t*);
+ template <bool is_horizontal_run>
+ void ComputeGlyphBounds(const ShapeResult::RunInfo&);
void InsertRun(std::unique_ptr<ShapeResult::RunInfo>,
unsigned start_glyph,
unsigned num_glyphs,
@@ -306,6 +332,8 @@ class PLATFORM_EXPORT ShapeResult : public RefCounted<ShapeResult> {
void InsertRun(std::unique_ptr<ShapeResult::RunInfo>);
void InsertRunForIndex(unsigned start_character_index);
void ReorderRtlRuns(unsigned run_size_before);
+ unsigned ComputeStartIndex() const;
+ void UpdateStartIndex();
float LineLeftBounds() const;
float LineRightBounds() const;
@@ -316,6 +344,7 @@ class PLATFORM_EXPORT ShapeResult : public RefCounted<ShapeResult> {
scoped_refptr<const SimpleFontData> primary_font_;
mutable std::unique_ptr<CharacterPositionData> character_position_;
+ unsigned start_index_;
unsigned num_characters_;
unsigned num_glyphs_ : 30;
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 1800d807bdc..a9597407e17 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
@@ -13,34 +13,53 @@
namespace blink {
+namespace {
+
+unsigned CharactersInShapeResult(
+ const Vector<scoped_refptr<const ShapeResult>, 64>& results) {
+ unsigned num_characters = 0;
+ for (const scoped_refptr<const ShapeResult>& result : results)
+ num_characters += result->NumCharacters();
+ return num_characters;
+}
+
+} // namespace
+
// TODO(eae): This is a bit of a hack to allow reuse of the implementation
// for both ShapeResultBuffer and single ShapeResult use cases. Ideally the
// logic should move into ShapeResult itself and then the ShapeResultBuffer
// implementation may wrap that.
CharacterRange ShapeResultBuffer::GetCharacterRange(
scoped_refptr<const ShapeResult> result,
+ const StringView& text,
TextDirection direction,
float total_width,
unsigned from,
unsigned to) {
Vector<scoped_refptr<const ShapeResult>, 64> results;
results.push_back(result);
- return GetCharacterRangeInternal(results, direction, total_width, from, to);
+ return GetCharacterRangeInternal(results, text, direction, total_width, from,
+ to);
}
-CharacterRange ShapeResultBuffer::GetCharacterRange(float total_width,
+CharacterRange ShapeResultBuffer::GetCharacterRange(const StringView& text,
TextDirection direction,
+ float total_width,
unsigned from,
unsigned to) const {
- return GetCharacterRangeInternal(results_, direction, total_width, from, to);
+ return GetCharacterRangeInternal(results_, text, direction, total_width, from,
+ to);
}
CharacterRange ShapeResultBuffer::GetCharacterRangeInternal(
const Vector<scoped_refptr<const ShapeResult>, 64>& results,
+ const StringView& text,
TextDirection direction,
float total_width,
unsigned absolute_from,
unsigned absolute_to) {
+ DCHECK_EQ(CharactersInShapeResult(results), text.length());
+
float current_x = 0;
float from_x = 0;
float to_x = 0;
@@ -61,6 +80,8 @@ CharacterRange ShapeResultBuffer::GetCharacterRangeInternal(
unsigned total_num_characters = 0;
for (unsigned j = 0; j < results.size(); j++) {
const scoped_refptr<const ShapeResult> result = results[j];
+ result->EnsureGraphemes(
+ StringView(text, total_num_characters, result->NumCharacters()));
if (direction == TextDirection::kRtl) {
// Convert logical offsets to visual offsets, because results are in
// logical order while runs are in visual order.
@@ -138,10 +159,13 @@ void ShapeResultBuffer::AddRunInfoRanges(const ShapeResult::RunInfo& run_info,
for (const auto& glyph : run_info.glyph_data_)
character_widths[glyph.character_index] += glyph.advance;
+ if (run_info.Rtl())
+ offset += run_info.width_;
+
for (unsigned character_index = 0; character_index < run_info.num_characters_;
character_index++) {
float start = offset;
- offset += character_widths[character_index];
+ offset += character_widths[character_index] * (run_info.Rtl() ? -1 : 1);
float end = offset;
// To match getCharacterRange we flip ranges to ensure start <= end.
@@ -158,26 +182,109 @@ Vector<CharacterRange> ShapeResultBuffer::IndividualCharacterRanges(
Vector<CharacterRange> ranges;
float current_x = direction == TextDirection::kRtl ? total_width : 0;
for (const scoped_refptr<const ShapeResult> result : results_) {
- if (direction == TextDirection::kRtl)
- current_x -= result->Width();
unsigned run_count = result->runs_.size();
- for (unsigned index = 0; index < run_count; index++) {
- unsigned run_index =
- direction == TextDirection::kRtl ? run_count - 1 - index : index;
- AddRunInfoRanges(*result->runs_[run_index], current_x, ranges);
- current_x += result->runs_[run_index]->width_;
+
+ if (result->Rtl()) {
+ for (int index = run_count - 1; index >= 0; index--) {
+ current_x -= result->runs_[index]->width_;
+ AddRunInfoRanges(*result->runs_[index], current_x, ranges);
+ }
+ } else {
+ for (unsigned index = 0; index < run_count; index++) {
+ AddRunInfoRanges(*result->runs_[index], current_x, ranges);
+ current_x += result->runs_[index]->width_;
+ }
}
- if (direction == TextDirection::kRtl)
- current_x -= result->Width();
}
return ranges;
}
+void ShapeResultBuffer::AddRunInfoAdvances(const ShapeResult::RunInfo& run_info,
+ float offset,
+ Vector<double>& advances) {
+ const unsigned num_glyphs = run_info.glyph_data_.size();
+ const unsigned num_chars = run_info.num_characters_;
+
+ if (run_info.Rtl())
+ offset += run_info.width_;
+
+ double current_width = 0;
+ for (unsigned glyph_id = 0; glyph_id < num_glyphs; glyph_id++) {
+ unsigned gid = run_info.Rtl() ? num_glyphs - glyph_id - 1 : glyph_id;
+ unsigned next_gid =
+ run_info.Rtl() ? num_glyphs - glyph_id - 2 : glyph_id + 1;
+ const HarfBuzzRunGlyphData& glyph = run_info.glyph_data_[gid];
+
+ unsigned char_id = glyph.character_index;
+ unsigned next_char_id =
+ (glyph_id + 1 == num_glyphs)
+ ? num_chars
+ : run_info.glyph_data_[next_gid].character_index;
+
+ current_width += glyph.advance;
+
+ if (char_id == next_char_id)
+ continue;
+
+ unsigned num_graphemes = run_info.NumGraphemes(char_id, next_char_id);
+
+ for (unsigned i = char_id; i < next_char_id; i++) {
+ if (run_info.Rtl()) {
+ advances.push_back(offset - (current_width / num_graphemes));
+ } else {
+ advances.push_back(offset);
+ }
+
+ if (num_graphemes == next_char_id - char_id) {
+ offset += (current_width / num_graphemes) * (run_info.Rtl() ? -1 : 1);
+ }
+ }
+
+ if (num_graphemes != next_char_id - char_id) {
+ offset += current_width * (run_info.Rtl() ? -1 : 1);
+ }
+
+ current_width = 0;
+ }
+}
+
+Vector<double> ShapeResultBuffer::IndividualCharacterAdvances(
+ const StringView& text,
+ TextDirection direction,
+ float total_width) const {
+ unsigned character_offset = 0;
+ Vector<double> advances;
+ float current_x = direction == TextDirection::kRtl ? total_width : 0;
+
+ for (const scoped_refptr<const ShapeResult> result : results_) {
+ unsigned run_count = result->runs_.size();
+
+ result->EnsureGraphemes(
+ StringView(text, character_offset, result->NumCharacters()));
+
+ if (result->Rtl()) {
+ for (int index = run_count - 1; index >= 0; index--) {
+ current_x -= result->runs_[index]->width_;
+ AddRunInfoAdvances(*result->runs_[index], current_x, advances);
+ }
+ } else {
+ for (unsigned index = 0; index < run_count; index++) {
+ AddRunInfoAdvances(*result->runs_[index], current_x, advances);
+ current_x += result->runs_[index]->width_;
+ }
+ }
+
+ character_offset += result->NumCharacters();
+ }
+ return advances;
+}
+
int ShapeResultBuffer::OffsetForPosition(
const TextRun& run,
float target_x,
IncludePartialGlyphsOption partial_glyphs,
BreakGlyphsOption break_glyphs) const {
+ StringView text = run.ToStringView();
unsigned total_offset;
if (run.Rtl()) {
total_offset = run.length();
@@ -188,22 +295,26 @@ int ShapeResultBuffer::OffsetForPosition(
total_offset -= word_result->NumCharacters();
if (target_x >= 0 && target_x <= word_result->Width()) {
int offset_for_word = word_result->OffsetForPosition(
- target_x, partial_glyphs, break_glyphs);
+ target_x,
+ StringView(text, total_offset, word_result->NumCharacters()),
+ partial_glyphs, break_glyphs);
return total_offset + offset_for_word;
}
target_x -= word_result->Width();
}
} else {
total_offset = 0;
- for (const auto& word_result : results_) {
+ for (const scoped_refptr<const ShapeResult>& word_result : results_) {
if (!word_result)
continue;
int offset_for_word = word_result->OffsetForPosition(
- target_x, partial_glyphs, break_glyphs);
+ target_x, StringView(text, 0, word_result->NumCharacters()),
+ partial_glyphs, break_glyphs);
DCHECK_GE(offset_for_word, 0);
total_offset += offset_for_word;
if (target_x >= 0 && target_x <= word_result->Width())
return total_offset;
+ text = StringView(text, word_result->NumCharacters());
target_x -= word_result->Width();
}
}
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_buffer.h b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_buffer.h
index ace7dcd7b48..fb601df7a7a 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_buffer.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_buffer.h
@@ -37,14 +37,19 @@ class PLATFORM_EXPORT ShapeResultBuffer {
float target_x,
IncludePartialGlyphsOption,
BreakGlyphsOption) const;
- CharacterRange GetCharacterRange(float total_width,
+ CharacterRange GetCharacterRange(const StringView& text,
TextDirection,
+ float total_width,
unsigned from,
unsigned to) const;
Vector<CharacterRange> IndividualCharacterRanges(TextDirection,
float total_width) const;
+ Vector<double> IndividualCharacterAdvances(const StringView&,
+ TextDirection,
+ float total_width) const;
static CharacterRange GetCharacterRange(scoped_refptr<const ShapeResult>,
+ const StringView& text,
TextDirection,
float total_width,
unsigned from,
@@ -60,11 +65,15 @@ class PLATFORM_EXPORT ShapeResultBuffer {
friend class ShapeResultBloberizer;
static CharacterRange GetCharacterRangeInternal(
const Vector<scoped_refptr<const ShapeResult>, 64>&,
+ const StringView& text,
TextDirection,
float total_width,
unsigned from,
unsigned to);
+ static void AddRunInfoAdvances(const ShapeResult::RunInfo& run_info,
+ float offset,
+ Vector<double>& advances);
static void AddRunInfoRanges(const ShapeResult::RunInfo&,
float offset,
Vector<CharacterRange>&);
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 3609c766682..408baf47d00 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
@@ -48,10 +48,12 @@ class SimpleFontData;
struct HarfBuzzRunGlyphData {
DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
- static constexpr unsigned kMaxCharacterIndex = (1 << 15) - 1;
+ static constexpr unsigned kCharacterIndexBits = 15;
+ static constexpr unsigned kMaxCharacterIndex = (1 << kCharacterIndexBits) - 1;
+ static constexpr unsigned kMaxGlyphs = 1 << kCharacterIndexBits;
uint16_t glyph;
- unsigned character_index : 15;
+ unsigned character_index : kCharacterIndexBits;
unsigned safe_to_break_before : 1;
float advance;
FloatSize offset;
@@ -73,14 +75,13 @@ struct ShapeResult::RunInfo {
hb_script_t script,
unsigned start_index,
unsigned num_glyphs,
- unsigned num_characters,
- Vector<unsigned> graphemes)
+ unsigned num_characters)
: font_data_(const_cast<SimpleFontData*>(font)),
direction_(dir),
canvas_rotation_(canvas_rotation),
script_(script),
- glyph_data_(num_glyphs),
- graphemes_(graphemes),
+ glyph_data_(
+ std::min(num_glyphs, HarfBuzzRunGlyphData::kMaxCharacterIndex + 1)),
start_index_(start_index),
num_characters_(num_characters),
width_(0.0f) {}
@@ -107,6 +108,10 @@ struct ShapeResult::RunInfo {
void CharacterIndexForXPosition(float,
BreakGlyphsOption,
GlyphIndexResult*) const;
+ unsigned LimitNumGlyphs(unsigned start_glyph,
+ unsigned* num_glyphs_in_out,
+ const bool is_ltr,
+ const hb_glyph_info_t* glyph_infos);
void SetGlyphAndPositions(unsigned index,
uint16_t glyph_id,
float advance,
@@ -172,18 +177,9 @@ struct ShapeResult::RunInfo {
auto glyphs = FindGlyphDataRange(start, end);
unsigned number_of_glyphs = std::distance(glyphs.begin, glyphs.end);
- Vector<unsigned> sub_graphemes;
- if (graphemes_.size()) {
- sub_graphemes.resize(number_of_characters);
- for (unsigned i = 0; i < number_of_characters; ++i) {
- sub_graphemes[i] = graphemes_[start + i];
- }
- }
-
auto run = std::make_unique<RunInfo>(
font_data_.get(), direction_, canvas_rotation_, script_,
- start_index_ + start, number_of_glyphs, number_of_characters,
- std::move(sub_graphemes));
+ start_index_ + start, number_of_glyphs, number_of_characters);
static_assert(base::is_trivially_copyable<HarfBuzzRunGlyphData>::value,
"HarfBuzzRunGlyphData should be trivially copyable");
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker.cc
index a7cd5af2461..04da776c57a 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker.cc
@@ -158,7 +158,8 @@ ShapingLineBreaker::PreviousBreakOpportunity(unsigned offset,
ShapingLineBreaker::BreakOpportunity ShapingLineBreaker::NextBreakOpportunity(
unsigned offset,
- unsigned start) const {
+ unsigned start,
+ unsigned len) const {
if (UNLIKELY(!IsSoftHyphenEnabled())) {
const String& text = GetText();
for (;; offset++) {
@@ -171,7 +172,7 @@ ShapingLineBreaker::BreakOpportunity ShapingLineBreaker::NextBreakOpportunity(
if (UNLIKELY(hyphenation_))
return Hyphenate(offset, start, false);
- return {break_iterator_->NextBreakOpportunity(offset), false};
+ return {break_iterator_->NextBreakOpportunity(offset, len), false};
}
inline scoped_refptr<ShapeResult> ShapingLineBreaker::Shape(TextDirection direction,
@@ -267,8 +268,9 @@ scoped_refptr<const ShapeResult> ShapingLineBreaker::ShapeLine(
if (is_overflow) {
if (options & kNoResultIfOverflow)
return nullptr;
- break_opportunity =
- NextBreakOpportunity(std::max(candidate_break, start + 1), start);
+ // No need to scan past range_end for a break oppertunity.
+ break_opportunity = NextBreakOpportunity(
+ std::max(candidate_break, start + 1), start, range_end);
// |range_end| may not be a break opportunity, but this function cannot
// measure beyond it.
if (break_opportunity.offset >= range_end) {
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker.h b/chromium/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker.h
index d06cc93ae58..e58db434b6e 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker.h
@@ -53,6 +53,7 @@ class PLATFORM_EXPORT ShapingLineBreaker final {
struct Result {
STACK_ALLOCATED();
+ public:
// Indicates the resulting break offset.
unsigned break_offset;
@@ -97,12 +98,15 @@ class PLATFORM_EXPORT ShapingLineBreaker final {
struct BreakOpportunity {
STACK_ALLOCATED();
+ public:
unsigned offset;
bool is_hyphenated;
};
BreakOpportunity PreviousBreakOpportunity(unsigned offset,
unsigned start) const;
- BreakOpportunity NextBreakOpportunity(unsigned offset, unsigned start) const;
+ BreakOpportunity NextBreakOpportunity(unsigned offset,
+ unsigned start,
+ unsigned len) const;
BreakOpportunity Hyphenate(unsigned offset,
unsigned start,
bool backwards) const;
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 16b10a59128..bb83a5cfca7 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
@@ -48,7 +48,8 @@ class ShapingLineBreakerTest : public testing::Test {
const String& string) {
Vector<unsigned> break_positions;
for (unsigned i = 0; i <= string.length(); i++) {
- unsigned next = breaker.NextBreakOpportunity(i, 0).offset;
+ unsigned next =
+ breaker.NextBreakOpportunity(i, 0, string.length()).offset;
if (break_positions.IsEmpty() || break_positions.back() != next)
break_positions.push_back(next);
}
diff --git a/chromium/third_party/blink/renderer/platform/fonts/simple_font_data.cc b/chromium/third_party/blink/renderer/platform/fonts/simple_font_data.cc
index 4b93a924162..811beb0fc4d 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/simple_font_data.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/simple_font_data.cc
@@ -354,6 +354,20 @@ FloatRect SimpleFontData::PlatformBoundsForGlyph(Glyph glyph) const {
return FloatRect(bounds);
}
+void SimpleFontData::BoundsForGlyphs(const Vector<Glyph, 256> glyphs,
+ Vector<FloatRect, 256>* bounds) const {
+ DCHECK_EQ(glyphs.size(), bounds->size());
+
+ if (!platform_data_.size())
+ return;
+
+ Vector<SkRect, 256> skia_bounds(glyphs.size());
+ SkiaTextMetrics(&paint_).GetSkiaBoundsForGlyphs(glyphs, skia_bounds.data());
+
+ for (unsigned i = 0; i < skia_bounds.size(); i++)
+ (*bounds)[i] = FloatRect(skia_bounds[i]);
+}
+
float SimpleFontData::PlatformWidthForGlyph(Glyph glyph) const {
if (!platform_data_.size())
return 0;
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 0c159ad6161..ea751f5c5c2 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
@@ -54,6 +54,8 @@ namespace blink {
// character.
struct GlyphData {
STACK_ALLOCATED();
+
+ public:
GlyphData(
Glyph g = 0,
const SimpleFontData* f = nullptr,
@@ -110,6 +112,7 @@ class PLATFORM_EXPORT SimpleFontData : public FontData {
}
FloatRect BoundsForGlyph(Glyph) const;
+ void BoundsForGlyphs(const Vector<Glyph, 256>, Vector<FloatRect, 256>*) const;
FloatRect PlatformBoundsForGlyph(Glyph) const;
float WidthForGlyph(Glyph) const;
float PlatformWidthForGlyph(Glyph) const;
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 5781cafc4ff..b11a193d2ac 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
@@ -1,4 +1,3 @@
-
/*
* Copyright (c) 2006, 2007, 2008, 2009 Google Inc. All rights reserved.
*
@@ -43,9 +42,12 @@
#include "third_party/blink/renderer/platform/fonts/font_cache.h"
#include "third_party/blink/renderer/platform/fonts/font_description.h"
#include "third_party/blink/renderer/platform/fonts/font_face_creation_params.h"
+#include "third_party/blink/renderer/platform/fonts/font_global_context.h"
+#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/graphics/skia/skia_utils.h"
#include "third_party/blink/renderer/platform/language.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/text/atomic_string.h"
#include "third_party/blink/renderer/platform/wtf/text/cstring.h"
@@ -55,6 +57,25 @@
namespace blink {
+#if defined(OS_ANDROID)
+namespace {
+
+static PaintTypeface CreateTypefaceFromUniqueName(
+ const FontFaceCreationParams& creation_params,
+ CString& name) {
+ FontUniqueNameLookup* unique_name_lookup =
+ FontGlobalContext::Get()->GetFontUniqueNameLookup();
+ DCHECK(unique_name_lookup);
+ sk_sp<SkTypeface> uniquely_identified_font =
+ unique_name_lookup->MatchUniqueName(creation_params.Family());
+ if (uniquely_identified_font) {
+ return PaintTypeface::FromSkTypeface(uniquely_identified_font);
+ }
+ return PaintTypeface();
+}
+} // namespace
+#endif
+
AtomicString ToAtomicString(const SkString& str) {
return AtomicString::FromUTF8(str.c_str(), str.size());
}
@@ -274,10 +295,21 @@ std::unique_ptr<FontPlatformData> FontCache::CreateFontPlatformData(
const FontDescription& font_description,
const FontFaceCreationParams& creation_params,
float font_size,
- AlternateFontName) {
+ AlternateFontName alternate_name) {
CString name;
- PaintTypeface paint_tf =
- CreateTypeface(font_description, creation_params, name);
+
+ PaintTypeface paint_tf;
+#if defined(OS_ANDROID)
+ if (alternate_name == AlternateFontName::kLocalUniqueFace &&
+ RuntimeEnabledFeatures::FontSrcLocalMatchingEnabled()) {
+ paint_tf = CreateTypefaceFromUniqueName(creation_params, name);
+ } else {
+ paint_tf = CreateTypeface(font_description, creation_params, name);
+ }
+#else
+ paint_tf = CreateTypeface(font_description, creation_params, name);
+#endif
+
if (!paint_tf)
return nullptr;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/skia/skia_text_metrics.cc b/chromium/third_party/blink/renderer/platform/fonts/skia/skia_text_metrics.cc
index 47ee36d7fae..9d7f4b5c083 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/skia/skia_text_metrics.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/skia/skia_text_metrics.cc
@@ -11,6 +11,15 @@
namespace blink {
+namespace {
+
+template <class T>
+T* advance_by_byte_size(T* p, unsigned byte_size) {
+ return reinterpret_cast<T*>(reinterpret_cast<uint8_t*>(p) + byte_size);
+}
+
+} // namespace
+
SkiaTextMetrics::SkiaTextMetrics(const SkPaint* paint) : paint_(paint) {
CHECK(paint_->getTextEncoding() == SkPaint::kGlyphID_TextEncoding);
}
@@ -29,6 +38,35 @@ void SkiaTextMetrics::GetGlyphWidthForHarfBuzz(hb_codepoint_t codepoint,
*width = SkiaScalarToHarfBuzzPosition(sk_width);
}
+void SkiaTextMetrics::GetGlyphWidthForHarfBuzz(unsigned count,
+ hb_codepoint_t* glyphs,
+ unsigned glyph_stride,
+ hb_position_t* advances,
+ unsigned advance_stride) {
+ // Batch the call to getTextWidths because its function entry cost is not
+ // cheap. getTextWidths accepts multiple glyphd ID, but not from a sparse
+ // array that copy them to a regular array.
+ Vector<Glyph, 256> glyph_array(count);
+ for (unsigned i = 0; i < count;
+ i++, glyphs = advance_by_byte_size(glyphs, glyph_stride)) {
+ glyph_array[i] = *glyphs;
+ }
+ Vector<SkScalar, 256> sk_width_array(count);
+ paint_->getTextWidths(glyph_array.data(), sizeof(Glyph) * count,
+ sk_width_array.data(), nullptr);
+
+ if (!paint_->isSubpixelText()) {
+ for (unsigned i = 0; i < count; i++)
+ sk_width_array[i] = SkScalarRoundToInt(sk_width_array[i]);
+ }
+
+ // Copy the results back to the sparse array.
+ for (unsigned i = 0; i < count;
+ i++, advances = advance_by_byte_size(advances, advance_stride)) {
+ *advances = SkiaScalarToHarfBuzzPosition(sk_width_array[i]);
+ }
+}
+
void SkiaTextMetrics::GetGlyphExtentsForHarfBuzz(hb_codepoint_t codepoint,
hb_glyph_extents_t* extents) {
DCHECK_LE(codepoint, 0xFFFFu);
@@ -72,6 +110,27 @@ void SkiaTextMetrics::GetSkiaBoundsForGlyph(Glyph glyph, SkRect* bounds) {
}
}
+void SkiaTextMetrics::GetSkiaBoundsForGlyphs(const Vector<Glyph, 256> glyphs,
+ SkRect* bounds) {
+#if defined(OS_MACOSX)
+ for (unsigned i = 0; i < glyphs.size(); i++) {
+ GetSkiaBoundsForGlyph(glyphs[i], &bounds[i]);
+ }
+#else
+ static_assert(sizeof(Glyph) == 2, "Skia expects 2 bytes glyph id.");
+ paint_->getTextWidths(glyphs.data(), sizeof(Glyph) * glyphs.size(), nullptr,
+ bounds);
+
+ if (!paint_->isSubpixelText()) {
+ for (unsigned i = 0; i < glyphs.size(); i++) {
+ SkIRect ir;
+ bounds[i].roundOut(&ir);
+ bounds[i].set(ir);
+ }
+ }
+#endif
+}
+
float SkiaTextMetrics::GetSkiaWidthForGlyph(Glyph glyph) {
SkScalar sk_width;
paint_->getTextWidths(&glyph, sizeof(glyph), &sk_width, nullptr);
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 e8a38f94142..bd9c0a320f3 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
@@ -9,6 +9,7 @@
#include <SkPaint.h>
#include <hb.h>
+#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
@@ -17,9 +18,15 @@ class SkiaTextMetrics final {
SkiaTextMetrics(const SkPaint*);
void GetGlyphWidthForHarfBuzz(hb_codepoint_t, hb_position_t* width);
+ void GetGlyphWidthForHarfBuzz(unsigned count,
+ hb_codepoint_t* first_glyph,
+ unsigned glyph_stride,
+ hb_position_t* first_advance,
+ unsigned advance_stride);
void GetGlyphExtentsForHarfBuzz(hb_codepoint_t, hb_glyph_extents_t*);
void GetSkiaBoundsForGlyph(Glyph, SkRect* bounds);
+ void GetSkiaBoundsForGlyphs(const Vector<Glyph, 256>, SkRect*);
float GetSkiaWidthForGlyph(Glyph);
static hb_position_t SkiaScalarToHarfBuzzPosition(SkScalar value);
diff --git a/chromium/third_party/blink/renderer/platform/geometry/blend.h b/chromium/third_party/blink/renderer/platform/geometry/blend.h
new file mode 100644
index 00000000000..10005926763
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/geometry/blend.h
@@ -0,0 +1,59 @@
+// 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_GEOMETRY_BLEND_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GEOMETRY_BLEND_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/layout_unit.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/math_extras.h"
+
+#include <type_traits>
+
+namespace blink {
+
+inline int Blend(int from, int to, double progress) {
+ return lround(from + (to - from) * progress);
+}
+
+// For unsigned types.
+template <typename T>
+inline T Blend(T from, T to, double progress) {
+ static_assert(std::is_integral<T>::value,
+ "blend can only be used with integer types");
+ return clampTo<T>(round(to > from ? from + (to - from) * progress
+ : from - (from - to) * progress));
+}
+
+inline double Blend(double from, double to, double progress) {
+ return from + (to - from) * progress;
+}
+
+inline float Blend(float from, float to, double progress) {
+ return static_cast<float>(from + (to - from) * progress);
+}
+
+inline LayoutUnit Blend(LayoutUnit from, LayoutUnit to, double progress) {
+ return LayoutUnit(from + (to - from) * progress);
+}
+
+inline IntPoint Blend(const IntPoint& from,
+ const IntPoint& to,
+ double progress) {
+ return IntPoint(Blend(from.X(), to.X(), progress),
+ Blend(from.Y(), to.Y(), progress));
+}
+
+inline FloatPoint Blend(const FloatPoint& from,
+ const FloatPoint& to,
+ double progress) {
+ return FloatPoint(Blend(from.X(), to.X(), progress),
+ Blend(from.Y(), to.Y(), progress));
+}
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GEOMETRY_BLEND_H_
diff --git a/chromium/third_party/blink/renderer/platform/geometry/double_point.h b/chromium/third_party/blink/renderer/platform/geometry/double_point.h
index 9b251482fd7..ece84130307 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/double_point.h
+++ b/chromium/third_party/blink/renderer/platform/geometry/double_point.h
@@ -20,27 +20,27 @@ class PLATFORM_EXPORT DoublePoint {
DISALLOW_NEW();
public:
- DoublePoint() : x_(0), y_(0) {}
- DoublePoint(double x, double y) : x_(x), y_(y) {}
- DoublePoint(const IntPoint& p) : x_(p.X()), y_(p.Y()) {}
- DoublePoint(const FloatPoint& p) : x_(p.X()), y_(p.Y()) {}
+ constexpr DoublePoint() : x_(0), y_(0) {}
+ constexpr DoublePoint(double x, double y) : x_(x), y_(y) {}
+ constexpr DoublePoint(const IntPoint& p) : x_(p.X()), y_(p.Y()) {}
+ constexpr DoublePoint(const FloatPoint& p) : x_(p.X()), y_(p.Y()) {}
explicit DoublePoint(const LayoutPoint&);
- explicit DoublePoint(const IntSize& size)
+ constexpr explicit DoublePoint(const IntSize& size)
: x_(size.Width()), y_(size.Height()) {}
explicit DoublePoint(const FloatSize&);
- explicit DoublePoint(const DoubleSize& size)
+ constexpr explicit DoublePoint(const DoubleSize& size)
: x_(size.Width()), y_(size.Height()) {}
- static DoublePoint Zero() { return DoublePoint(); }
+ static constexpr DoublePoint Zero() { return DoublePoint(); }
DoublePoint ExpandedTo(const DoublePoint&) const;
DoublePoint ShrunkTo(const DoublePoint&) const;
- double X() const { return x_; }
- double Y() const { return y_; }
+ constexpr double X() const { return x_; }
+ constexpr double Y() const { return y_; }
void SetX(double x) { x_ = x; }
void SetY(double y) { y_ = y; }
@@ -74,12 +74,12 @@ class PLATFORM_EXPORT DoublePoint {
double x_, y_;
};
-inline bool operator==(const DoublePoint& a, const DoublePoint& b) {
+constexpr bool operator==(const DoublePoint& a, const DoublePoint& b) {
return a.X() == b.X() && a.Y() == b.Y();
}
-inline bool operator!=(const DoublePoint& a, const DoublePoint& b) {
- return a.X() != b.X() || a.Y() != b.Y();
+constexpr bool operator!=(const DoublePoint& a, const DoublePoint& b) {
+ return !(a == b);
}
inline DoublePoint& operator+=(DoublePoint& a, const DoubleSize& b) {
@@ -94,19 +94,19 @@ inline DoublePoint& operator-=(DoublePoint& a, const DoubleSize& b) {
return a;
}
-inline DoublePoint operator+(const DoublePoint& a, const DoubleSize& b) {
+constexpr DoublePoint operator+(const DoublePoint& a, const DoubleSize& b) {
return DoublePoint(a.X() + b.Width(), a.Y() + b.Height());
}
-inline DoubleSize operator-(const DoublePoint& a, const DoublePoint& b) {
+constexpr DoubleSize operator-(const DoublePoint& a, const DoublePoint& b) {
return DoubleSize(a.X() - b.X(), a.Y() - b.Y());
}
-inline DoublePoint operator-(const DoublePoint& a) {
+constexpr DoublePoint operator-(const DoublePoint& a) {
return DoublePoint(-a.X(), -a.Y());
}
-inline DoublePoint operator-(const DoublePoint& a, const DoubleSize& b) {
+constexpr DoublePoint operator-(const DoublePoint& a, const DoubleSize& b) {
return DoublePoint(a.X() - b.Width(), a.Y() - b.Height());
}
@@ -122,11 +122,11 @@ inline IntPoint FlooredIntPoint(const DoublePoint& p) {
return IntPoint(clampTo<int>(floor(p.X())), clampTo<int>(floor(p.Y())));
}
-inline FloatPoint ToFloatPoint(const DoublePoint& a) {
+constexpr FloatPoint ToFloatPoint(const DoublePoint& a) {
return FloatPoint(a.X(), a.Y());
}
-inline DoubleSize ToDoubleSize(const DoublePoint& a) {
+constexpr DoubleSize ToDoubleSize(const DoublePoint& a) {
return DoubleSize(a.X(), a.Y());
}
diff --git a/chromium/third_party/blink/renderer/platform/geometry/double_rect.h b/chromium/third_party/blink/renderer/platform/geometry/double_rect.h
index c8f8b92e986..d0560dae6d7 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/double_rect.h
+++ b/chromium/third_party/blink/renderer/platform/geometry/double_rect.h
@@ -20,35 +20,35 @@ class PLATFORM_EXPORT DoubleRect {
STACK_ALLOCATED();
public:
- DoubleRect() = default;
- DoubleRect(const DoublePoint& location, const DoubleSize& size)
+ constexpr DoubleRect() = default;
+ constexpr DoubleRect(const DoublePoint& location, const DoubleSize& size)
: location_(location), size_(size) {}
- DoubleRect(double x, double y, double width, double height)
+ constexpr DoubleRect(double x, double y, double width, double height)
: location_(DoublePoint(x, y)), size_(DoubleSize(width, height)) {}
DoubleRect(const IntRect&);
DoubleRect(const FloatRect&);
DoubleRect(const LayoutRect&);
- DoublePoint Location() const { return location_; }
- DoubleSize Size() const { return size_; }
+ constexpr DoublePoint Location() const { return location_; }
+ constexpr DoubleSize Size() const { return size_; }
void SetLocation(const DoublePoint& location) { location_ = location; }
void SetSize(const DoubleSize& size) { size_ = size; }
- double X() const { return location_.X(); }
- double Y() const { return location_.Y(); }
- double MaxX() const { return X() + Width(); }
- double MaxY() const { return Y() + Height(); }
- double Width() const { return size_.Width(); }
- double Height() const { return size_.Height(); }
+ constexpr double X() const { return location_.X(); }
+ constexpr double Y() const { return location_.Y(); }
+ constexpr double MaxX() const { return X() + Width(); }
+ constexpr double MaxY() const { return Y() + Height(); }
+ constexpr double Width() const { return size_.Width(); }
+ constexpr double Height() const { return size_.Height(); }
void SetX(double x) { location_.SetX(x); }
void SetY(double y) { location_.SetY(y); }
void SetWidth(double width) { size_.SetWidth(width); }
void SetHeight(double height) { size_.SetHeight(height); }
- bool IsEmpty() const { return size_.IsEmpty(); }
- bool IsZero() const { return size_.IsZero(); }
+ constexpr bool IsEmpty() const { return size_.IsEmpty(); }
+ constexpr bool IsZero() const { return size_.IsZero(); }
void Move(const DoubleSize& delta) { location_ += delta; }
void Move(double dx, double dy) { location_.Move(dx, dy); }
@@ -56,14 +56,16 @@ class PLATFORM_EXPORT DoubleRect {
location_.Move(delta.X(), delta.Y());
}
- DoublePoint MinXMinYCorner() const { return location_; } // typically topLeft
- DoublePoint MaxXMinYCorner() const {
+ constexpr DoublePoint MinXMinYCorner() const {
+ return location_;
+ } // typically topLeft
+ constexpr DoublePoint MaxXMinYCorner() const {
return DoublePoint(location_.X() + size_.Width(), location_.Y());
} // typically topRight
- DoublePoint MinXMaxYCorner() const {
+ constexpr DoublePoint MinXMaxYCorner() const {
return DoublePoint(location_.X(), location_.Y() + size_.Height());
} // typically bottomLeft
- DoublePoint MaxXMaxYCorner() const {
+ constexpr DoublePoint MaxXMaxYCorner() const {
return DoublePoint(location_.X() + size_.Width(),
location_.Y() + size_.Height());
} // typically bottomRight
diff --git a/chromium/third_party/blink/renderer/platform/geometry/double_size.cc b/chromium/third_party/blink/renderer/platform/geometry/double_size.cc
index 45efb50ed67..5b07fea1cce 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/double_size.cc
+++ b/chromium/third_party/blink/renderer/platform/geometry/double_size.cc
@@ -14,11 +14,6 @@ namespace blink {
DoubleSize::DoubleSize(const LayoutSize& size)
: width_(size.Width().ToDouble()), height_(size.Height().ToDouble()) {}
-bool DoubleSize::IsZero() const {
- return fabs(width_) < std::numeric_limits<double>::epsilon() &&
- fabs(height_) < std::numeric_limits<double>::epsilon();
-}
-
std::ostream& operator<<(std::ostream& ostream, const DoubleSize& size) {
return ostream << size.ToString();
}
diff --git a/chromium/third_party/blink/renderer/platform/geometry/double_size.h b/chromium/third_party/blink/renderer/platform/geometry/double_size.h
index 917c81c4c52..0f950ecbc19 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/double_size.h
+++ b/chromium/third_party/blink/renderer/platform/geometry/double_size.h
@@ -19,22 +19,30 @@ class PLATFORM_EXPORT DoubleSize {
DISALLOW_NEW();
public:
- DoubleSize() : width_(0), height_(0) {}
- DoubleSize(double width, double height) : width_(width), height_(height) {}
- explicit DoubleSize(const IntSize& p)
+ constexpr DoubleSize() : width_(0), height_(0) {}
+ constexpr DoubleSize(double width, double height)
+ : width_(width), height_(height) {}
+ constexpr explicit DoubleSize(const IntSize& p)
: width_(p.Width()), height_(p.Height()) {}
- DoubleSize(const FloatSize& s) : width_(s.Width()), height_(s.Height()) {}
+ constexpr DoubleSize(const FloatSize& s)
+ : width_(s.Width()), height_(s.Height()) {}
explicit DoubleSize(const LayoutSize&);
- double Width() const { return width_; }
- double Height() const { return height_; }
+ constexpr double Width() const { return width_; }
+ constexpr double Height() const { return height_; }
void SetWidth(double width) { width_ = width; }
void SetHeight(double height) { height_ = height; }
- bool IsEmpty() const { return width_ <= 0 || height_ <= 0; }
+ constexpr bool IsEmpty() const { return width_ <= 0 || height_ <= 0; }
- bool IsZero() const;
+ constexpr bool IsZero() const {
+ // Not using fabs as it is not a constexpr in LLVM libc++
+ return -std::numeric_limits<double>::epsilon() < width_ &&
+ width_ < std::numeric_limits<double>::epsilon() &&
+ -std::numeric_limits<double>::epsilon() < height_ &&
+ height_ < std::numeric_limits<double>::epsilon();
+ }
void Expand(float width, float height) {
width_ += width;
@@ -66,19 +74,19 @@ inline DoubleSize& operator-=(DoubleSize& a, const DoubleSize& b) {
return a;
}
-inline DoubleSize operator+(const DoubleSize& a, const DoubleSize& b) {
+constexpr DoubleSize operator+(const DoubleSize& a, const DoubleSize& b) {
return DoubleSize(a.Width() + b.Width(), a.Height() + b.Height());
}
-inline DoubleSize operator-(const DoubleSize& a, const DoubleSize& b) {
+constexpr DoubleSize operator-(const DoubleSize& a, const DoubleSize& b) {
return DoubleSize(a.Width() - b.Width(), a.Height() - b.Height());
}
-inline bool operator==(const DoubleSize& a, const DoubleSize& b) {
+constexpr bool operator==(const DoubleSize& a, const DoubleSize& b) {
return a.Width() == b.Width() && a.Height() == b.Height();
}
-inline bool operator!=(const DoubleSize& a, const DoubleSize& b) {
+constexpr bool operator!=(const DoubleSize& a, const DoubleSize& b) {
return a.Width() != b.Width() || a.Height() != b.Height();
}
@@ -96,7 +104,7 @@ inline IntSize ExpandedIntSize(const DoubleSize& p) {
return IntSize(clampTo<int>(ceil(p.Width())), clampTo<int>(ceil(p.Height())));
}
-inline FloatSize ToFloatSize(const DoubleSize& p) {
+constexpr FloatSize ToFloatSize(const DoubleSize& p) {
return FloatSize(p.Width(), p.Height());
}
diff --git a/chromium/third_party/blink/renderer/platform/geometry/float_box.h b/chromium/third_party/blink/renderer/platform/geometry/float_box.h
index 8365088b3c1..24bc3c43788 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/float_box.h
+++ b/chromium/third_party/blink/renderer/platform/geometry/float_box.h
@@ -42,12 +42,18 @@ class PLATFORM_EXPORT FloatBox {
DISALLOW_NEW();
public:
- FloatBox() : x_(0), y_(0), z_(0), width_(0), height_(0), depth_(0) {}
-
- FloatBox(float x, float y, float z, float width, float height, float depth)
+ constexpr FloatBox()
+ : x_(0), y_(0), z_(0), width_(0), height_(0), depth_(0) {}
+
+ constexpr FloatBox(float x,
+ float y,
+ float z,
+ float width,
+ float height,
+ float depth)
: x_(x), y_(y), z_(z), width_(width), height_(height), depth_(depth) {}
- FloatBox(const FloatBox& box)
+ constexpr FloatBox(const FloatBox& box)
: x_(box.X()),
y_(box.Y()),
z_(box.Z()),
@@ -102,20 +108,20 @@ class PLATFORM_EXPORT FloatBox {
ExpandTo(box);
}
- bool IsEmpty() const {
+ constexpr bool IsEmpty() const {
return (width_ <= 0 && height_ <= 0) || (width_ <= 0 && depth_ <= 0) ||
(height_ <= 0 && depth_ <= 0);
}
- float Right() const { return x_ + width_; }
- float Bottom() const { return y_ + height_; }
- float front() const { return z_ + depth_; }
- float X() const { return x_; }
- float Y() const { return y_; }
- float Z() const { return z_; }
- float Width() const { return width_; }
- float Height() const { return height_; }
- float Depth() const { return depth_; }
+ constexpr float Right() const { return x_ + width_; }
+ constexpr float Bottom() const { return y_ + height_; }
+ constexpr float front() const { return z_ + depth_; }
+ constexpr float X() const { return x_; }
+ constexpr float Y() const { return y_; }
+ constexpr float Z() const { return z_; }
+ constexpr float Width() const { return width_; }
+ constexpr float Height() const { return height_; }
+ constexpr float Depth() const { return depth_; }
String ToString() const;
@@ -128,13 +134,13 @@ class PLATFORM_EXPORT FloatBox {
float depth_;
};
-inline bool operator==(const FloatBox& a, const FloatBox& b) {
+constexpr bool operator==(const FloatBox& a, const FloatBox& b) {
return a.X() == b.X() && a.Y() == b.Y() && a.Z() == b.Z() &&
a.Width() == b.Width() && a.Height() == b.Height() &&
a.Depth() == b.Depth();
}
-inline bool operator!=(const FloatBox& a, const FloatBox& b) {
+constexpr bool operator!=(const FloatBox& a, const FloatBox& b) {
return !(a == b);
}
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 e2f0565f8d2..6aaa4efb4da 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/float_point.h
+++ b/chromium/third_party/blink/renderer/platform/geometry/float_point.h
@@ -62,24 +62,24 @@ class PLATFORM_EXPORT FloatPoint {
DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
public:
- FloatPoint() : x_(0), y_(0) {}
- FloatPoint(float x, float y) : x_(x), y_(y) {}
+ constexpr FloatPoint() : x_(0), y_(0) {}
+ constexpr FloatPoint(float x, float y) : x_(x), y_(y) {}
explicit FloatPoint(const IntPoint&);
explicit FloatPoint(const SkPoint&);
explicit FloatPoint(const DoublePoint&);
explicit FloatPoint(const LayoutPoint&);
- explicit FloatPoint(const FloatSize& size)
+ constexpr explicit FloatPoint(const FloatSize& size)
: x_(size.Width()), y_(size.Height()) {}
explicit FloatPoint(const LayoutSize&);
- explicit FloatPoint(const IntSize& size)
+ constexpr explicit FloatPoint(const IntSize& size)
: x_(size.Width()), y_(size.Height()) {}
- static FloatPoint Zero() { return FloatPoint(); }
+ static constexpr FloatPoint Zero() { return FloatPoint(); }
static FloatPoint NarrowPrecision(double x, double y);
- float X() const { return x_; }
- float Y() const { return y_; }
+ constexpr float X() const { return x_; }
+ constexpr float Y() const { return y_; }
void SetX(float x) { x_ = x; }
void SetY(float y) { y_ = y; }
@@ -159,48 +159,48 @@ inline FloatPoint& operator-=(FloatPoint& a, const FloatSize& b) {
return a;
}
-inline FloatPoint operator+(const FloatPoint& a, const FloatSize& b) {
+constexpr FloatPoint operator+(const FloatPoint& a, const FloatSize& b) {
return FloatPoint(a.X() + b.Width(), a.Y() + b.Height());
}
-inline FloatPoint operator+(const FloatPoint& a, const IntSize& b) {
+constexpr FloatPoint operator+(const FloatPoint& a, const IntSize& b) {
return FloatPoint(a.X() + b.Width(), a.Y() + b.Height());
}
-inline FloatPoint operator+(const IntPoint& a, const FloatSize& b) {
+constexpr FloatPoint operator+(const IntPoint& a, const FloatSize& b) {
return FloatPoint(a.X() + b.Width(), a.Y() + b.Height());
}
-inline FloatPoint operator+(const FloatPoint& a, const FloatPoint& b) {
+constexpr FloatPoint operator+(const FloatPoint& a, const FloatPoint& b) {
return FloatPoint(a.X() + b.X(), a.Y() + b.Y());
}
-inline FloatPoint operator+(const FloatPoint& a, const IntPoint& b) {
+constexpr FloatPoint operator+(const FloatPoint& a, const IntPoint& b) {
return FloatPoint(a.X() + b.X(), a.Y() + b.Y());
}
-inline FloatSize operator-(const FloatPoint& a, const FloatPoint& b) {
+constexpr FloatSize operator-(const FloatPoint& a, const FloatPoint& b) {
return FloatSize(a.X() - b.X(), a.Y() - b.Y());
}
-inline FloatSize operator-(const FloatPoint& a, const IntPoint& b) {
+constexpr FloatSize operator-(const FloatPoint& a, const IntPoint& b) {
return FloatSize(a.X() - b.X(), a.Y() - b.Y());
}
-inline FloatPoint operator-(const FloatPoint& a, const FloatSize& b) {
+constexpr FloatPoint operator-(const FloatPoint& a, const FloatSize& b) {
return FloatPoint(a.X() - b.Width(), a.Y() - b.Height());
}
-inline FloatPoint operator-(const FloatPoint& a) {
+constexpr FloatPoint operator-(const FloatPoint& a) {
return FloatPoint(-a.X(), -a.Y());
}
-inline bool operator==(const FloatPoint& a, const FloatPoint& b) {
+constexpr bool operator==(const FloatPoint& a, const FloatPoint& b) {
return a.X() == b.X() && a.Y() == b.Y();
}
-inline bool operator!=(const FloatPoint& a, const FloatPoint& b) {
- return a.X() != b.X() || a.Y() != b.Y();
+constexpr bool operator!=(const FloatPoint& a, const FloatPoint& b) {
+ return !(a == b);
}
inline float operator*(const FloatPoint& a, const FloatPoint& b) {
diff --git a/chromium/third_party/blink/renderer/platform/geometry/float_point_3d.h b/chromium/third_party/blink/renderer/platform/geometry/float_point_3d.h
index 6717f3f16b3..9083de73c1e 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/float_point_3d.h
+++ b/chromium/third_party/blink/renderer/platform/geometry/float_point_3d.h
@@ -38,21 +38,22 @@ class PLATFORM_EXPORT FloatPoint3D {
DISALLOW_NEW();
public:
- FloatPoint3D() : x_(0), y_(0), z_(0) {}
+ constexpr FloatPoint3D() : x_(0), y_(0), z_(0) {}
- FloatPoint3D(float x, float y, float z) : x_(x), y_(y), z_(z) {}
+ constexpr FloatPoint3D(float x, float y, float z) : x_(x), y_(y), z_(z) {}
- FloatPoint3D(const FloatPoint& p) : x_(p.X()), y_(p.Y()), z_(0) {}
+ constexpr FloatPoint3D(const FloatPoint& p) : x_(p.X()), y_(p.Y()), z_(0) {}
- FloatPoint3D(const FloatPoint3D& p) : x_(p.X()), y_(p.Y()), z_(p.Z()) {}
+ constexpr FloatPoint3D(const FloatPoint3D& p)
+ : x_(p.X()), y_(p.Y()), z_(p.Z()) {}
- float X() const { return x_; }
+ constexpr float X() const { return x_; }
void SetX(float x) { x_ = x; }
- float Y() const { return y_; }
+ constexpr float Y() const { return y_; }
void SetY(float y) { y_ = y; }
- float Z() const { return z_; }
+ constexpr float Z() const { return z_; }
void SetZ(float z) { z_ = z; }
void Set(float x, float y, float z) {
x_ = x;
@@ -70,7 +71,7 @@ class PLATFORM_EXPORT FloatPoint3D {
z_ *= sz;
}
- bool IsZero() const { return !x_ && !y_ && !z_; }
+ constexpr bool IsZero() const { return !x_ && !y_ && !z_; }
void Normalize();
@@ -128,20 +129,20 @@ inline FloatPoint3D& operator-=(FloatPoint3D& a, const FloatPoint3D& b) {
return a;
}
-inline FloatPoint3D operator+(const FloatPoint3D& a, const FloatPoint3D& b) {
+constexpr FloatPoint3D operator+(const FloatPoint3D& a, const FloatPoint3D& b) {
return FloatPoint3D(a.X() + b.X(), a.Y() + b.Y(), a.Z() + b.Z());
}
-inline FloatPoint3D operator-(const FloatPoint3D& a, const FloatPoint3D& b) {
+constexpr FloatPoint3D operator-(const FloatPoint3D& a, const FloatPoint3D& b) {
return FloatPoint3D(a.X() - b.X(), a.Y() - b.Y(), a.Z() - b.Z());
}
-inline bool operator==(const FloatPoint3D& a, const FloatPoint3D& b) {
+constexpr bool operator==(const FloatPoint3D& a, const FloatPoint3D& b) {
return a.X() == b.X() && a.Y() == b.Y() && a.Z() == b.Z();
}
-inline bool operator!=(const FloatPoint3D& a, const FloatPoint3D& b) {
- return a.X() != b.X() || a.Y() != b.Y() || a.Z() != b.Z();
+constexpr bool operator!=(const FloatPoint3D& a, const FloatPoint3D& b) {
+ return !(a == b);
}
inline float operator*(const FloatPoint3D& a, const FloatPoint3D& b) {
diff --git a/chromium/third_party/blink/renderer/platform/geometry/float_quad.h b/chromium/third_party/blink/renderer/platform/geometry/float_quad.h
index 26922ce6f55..a004696e2c1 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/float_quad.h
+++ b/chromium/third_party/blink/renderer/platform/geometry/float_quad.h
@@ -47,15 +47,15 @@ class PLATFORM_EXPORT FloatQuad {
USING_FAST_MALLOC(FloatQuad);
public:
- FloatQuad() = default;
+ constexpr FloatQuad() = default;
- FloatQuad(const FloatPoint& p1,
- const FloatPoint& p2,
- const FloatPoint& p3,
- const FloatPoint& p4)
+ constexpr FloatQuad(const FloatPoint& p1,
+ const FloatPoint& p2,
+ const FloatPoint& p3,
+ const FloatPoint& p4)
: p1_(p1), p2_(p2), p3_(p3), p4_(p4) {}
- FloatQuad(const FloatRect& in_rect)
+ constexpr FloatQuad(const FloatRect& in_rect)
: p1_(in_rect.Location()),
p2_(in_rect.MaxX(), in_rect.Y()),
p3_(in_rect.MaxX(), in_rect.MaxY()),
@@ -70,10 +70,10 @@ class PLATFORM_EXPORT FloatQuad {
// Converts from an array of four SkPoints, as from SkMatrix::mapRectToQuad.
explicit FloatQuad(const SkPoint (&)[4]);
- FloatPoint P1() const { return p1_; }
- FloatPoint P2() const { return p2_; }
- FloatPoint P3() const { return p3_; }
- FloatPoint P4() const { return p4_; }
+ constexpr FloatPoint P1() const { return p1_; }
+ constexpr FloatPoint P2() const { return p2_; }
+ constexpr FloatPoint P3() const { return p3_; }
+ constexpr FloatPoint P4() const { return p4_; }
void SetP1(const FloatPoint& p) { p1_ = p; }
void SetP2(const FloatPoint& p) { p2_ = p; }
@@ -174,14 +174,13 @@ inline FloatQuad& operator-=(FloatQuad& a, const FloatSize& b) {
return a;
}
-inline bool operator==(const FloatQuad& a, const FloatQuad& b) {
+constexpr bool operator==(const FloatQuad& a, const FloatQuad& b) {
return a.P1() == b.P1() && a.P2() == b.P2() && a.P3() == b.P3() &&
a.P4() == b.P4();
}
-inline bool operator!=(const FloatQuad& a, const FloatQuad& b) {
- return a.P1() != b.P1() || a.P2() != b.P2() || a.P3() != b.P3() ||
- a.P4() != b.P4();
+constexpr bool operator!=(const FloatQuad& a, const FloatQuad& b) {
+ return !(a == b);
}
PLATFORM_EXPORT std::ostream& operator<<(std::ostream&, const FloatQuad&);
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 3434286b5af..b677554b148 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/float_rect.h
+++ b/chromium/third_party/blink/renderer/platform/geometry/float_rect.h
@@ -62,10 +62,10 @@ class PLATFORM_EXPORT FloatRect {
public:
enum ContainsMode { kInsideOrOnStroke, kInsideButNotOnStroke };
- FloatRect() = default;
- FloatRect(const FloatPoint& location, const FloatSize& size)
+ constexpr FloatRect() = default;
+ constexpr FloatRect(const FloatPoint& location, const FloatSize& size)
: location_(location), size_(size) {}
- FloatRect(float x, float y, float width, float height)
+ constexpr FloatRect(float x, float y, float width, float height)
: location_(FloatPoint(x, y)), size_(FloatSize(width, height)) {}
explicit FloatRect(const IntRect&);
explicit FloatRect(const LayoutRect&);
@@ -76,26 +76,26 @@ class PLATFORM_EXPORT FloatRect {
double width,
double height);
- FloatPoint Location() const { return location_; }
- FloatSize Size() const { return size_; }
+ constexpr FloatPoint Location() const { return location_; }
+ constexpr FloatSize Size() const { return size_; }
void SetLocation(const FloatPoint& location) { location_ = location; }
void SetSize(const FloatSize& size) { size_ = size; }
- float X() const { return location_.X(); }
- float Y() const { return location_.Y(); }
- float MaxX() const { return X() + Width(); }
- float MaxY() const { return Y() + Height(); }
- float Width() const { return size_.Width(); }
- float Height() const { return size_.Height(); }
+ constexpr float X() const { return location_.X(); }
+ constexpr float Y() const { return location_.Y(); }
+ constexpr float MaxX() const { return X() + Width(); }
+ constexpr float MaxY() const { return Y() + Height(); }
+ constexpr float Width() const { return size_.Width(); }
+ constexpr float Height() const { return size_.Height(); }
void SetX(float x) { location_.SetX(x); }
void SetY(float y) { location_.SetY(y); }
void SetWidth(float width) { size_.SetWidth(width); }
void SetHeight(float height) { size_.SetHeight(height); }
- bool IsEmpty() const { return size_.IsEmpty(); }
- bool IsZero() const { return size_.IsZero(); }
+ constexpr bool IsEmpty() const { return size_.IsEmpty(); }
+ constexpr bool IsZero() const { return size_.IsZero(); }
bool IsExpressibleAsIntRect() const;
FloatPoint Center() const {
@@ -235,18 +235,16 @@ inline FloatRect& operator+=(FloatRect& a, const FloatRect& b) {
return a;
}
-inline FloatRect operator+(const FloatRect& a, const FloatRect& b) {
- FloatRect c = a;
- c += b;
- return c;
+constexpr FloatRect operator+(const FloatRect& a, const FloatRect& b) {
+ return FloatRect(a.Location() + b.Location(), a.Size() + b.Size());
}
-inline bool operator==(const FloatRect& a, const FloatRect& b) {
+constexpr bool operator==(const FloatRect& a, const FloatRect& b) {
return a.Location() == b.Location() && a.Size() == b.Size();
}
-inline bool operator!=(const FloatRect& a, const FloatRect& b) {
- return a.Location() != b.Location() || a.Size() != b.Size();
+constexpr bool operator!=(const FloatRect& a, const FloatRect& b) {
+ return !(a == b);
}
// Returns a IntRect containing the given FloatRect.
diff --git a/chromium/third_party/blink/renderer/platform/geometry/float_rect_outsets.h b/chromium/third_party/blink/renderer/platform/geometry/float_rect_outsets.h
index 6d809ad6478..ef8c31a9574 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/float_rect_outsets.h
+++ b/chromium/third_party/blink/renderer/platform/geometry/float_rect_outsets.h
@@ -19,15 +19,15 @@ class PLATFORM_EXPORT FloatRectOutsets {
STACK_ALLOCATED();
public:
- FloatRectOutsets() : top_(0), right_(0), bottom_(0), left_(0) {}
+ constexpr FloatRectOutsets() : top_(0), right_(0), bottom_(0), left_(0) {}
- FloatRectOutsets(float top, float right, float bottom, float left)
+ constexpr FloatRectOutsets(float top, float right, float bottom, float left)
: top_(top), right_(right), bottom_(bottom), left_(left) {}
- float Top() const { return top_; }
- float Right() const { return right_; }
- float Bottom() const { return bottom_; }
- float Left() const { return left_; }
+ constexpr float Top() const { return top_; }
+ constexpr float Right() const { return right_; }
+ constexpr float Bottom() const { return bottom_; }
+ constexpr float Left() const { return left_; }
void SetTop(float top) { top_ = top; }
void SetRight(float right) { right_ = right; }
diff --git a/chromium/third_party/blink/renderer/platform/geometry/float_rounded_rect.h b/chromium/third_party/blink/renderer/platform/geometry/float_rounded_rect.h
index edd2c533fb9..877f9f60610 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/float_rounded_rect.h
+++ b/chromium/third_party/blink/renderer/platform/geometry/float_rounded_rect.h
@@ -48,17 +48,17 @@ class PLATFORM_EXPORT FloatRoundedRect {
DISALLOW_NEW();
public:
- Radii() = default;
- Radii(const FloatSize& top_left,
- const FloatSize& top_right,
- const FloatSize& bottom_left,
- const FloatSize& bottom_right)
+ constexpr Radii() = default;
+ constexpr Radii(const FloatSize& top_left,
+ const FloatSize& top_right,
+ const FloatSize& bottom_left,
+ const FloatSize& bottom_right)
: top_left_(top_left),
top_right_(top_right),
bottom_left_(bottom_left),
bottom_right_(bottom_right) {}
- Radii(const FloatRoundedRect::Radii& int_radii)
+ constexpr Radii(const FloatRoundedRect::Radii& int_radii)
: top_left_(int_radii.TopLeft()),
top_right_(int_radii.TopRight()),
bottom_left_(int_radii.BottomLeft()),
@@ -68,12 +68,12 @@ class PLATFORM_EXPORT FloatRoundedRect {
void SetTopRight(const FloatSize& size) { top_right_ = size; }
void SetBottomLeft(const FloatSize& size) { bottom_left_ = size; }
void SetBottomRight(const FloatSize& size) { bottom_right_ = size; }
- const FloatSize& TopLeft() const { return top_left_; }
- const FloatSize& TopRight() const { return top_right_; }
- const FloatSize& BottomLeft() const { return bottom_left_; }
- const FloatSize& BottomRight() const { return bottom_right_; }
+ constexpr const FloatSize& TopLeft() const { return top_left_; }
+ constexpr const FloatSize& TopRight() const { return top_right_; }
+ constexpr const FloatSize& BottomLeft() const { return bottom_left_; }
+ constexpr const FloatSize& BottomRight() const { return bottom_right_; }
- bool IsZero() const {
+ constexpr bool IsZero() const {
return top_left_.IsZero() && top_right_.IsZero() &&
bottom_left_.IsZero() && bottom_right_.IsZero();
}
@@ -109,7 +109,7 @@ class PLATFORM_EXPORT FloatRoundedRect {
FloatSize bottom_right_;
};
- FloatRoundedRect() = default;
+ constexpr FloatRoundedRect() = default;
explicit FloatRoundedRect(const FloatRect&, const Radii& = Radii());
explicit FloatRoundedRect(const IntRect&, const Radii& = Radii());
FloatRoundedRect(float x, float y, float width, float height);
@@ -119,10 +119,10 @@ class PLATFORM_EXPORT FloatRoundedRect {
const FloatSize& bottom_left,
const FloatSize& bottom_right);
- const FloatRect& Rect() const { return rect_; }
- const Radii& GetRadii() const { return radii_; }
- bool IsRounded() const { return !radii_.IsZero(); }
- bool IsEmpty() const { return rect_.IsEmpty(); }
+ constexpr const FloatRect& Rect() const { return rect_; }
+ constexpr const Radii& GetRadii() const { return radii_; }
+ constexpr bool IsRounded() const { return !radii_.IsZero(); }
+ constexpr bool IsEmpty() const { return rect_.IsEmpty(); }
void SetRect(const FloatRect& rect) { rect_ = rect; }
void SetRadii(const Radii& radii) { radii_ = radii; }
@@ -141,19 +141,19 @@ class PLATFORM_EXPORT FloatRoundedRect {
// Returns a quickly computed rect enclosed by the rounded rect.
FloatRect RadiusCenterRect() const;
- FloatRect TopLeftCorner() const {
+ constexpr FloatRect TopLeftCorner() const {
return FloatRect(rect_.X(), rect_.Y(), radii_.TopLeft().Width(),
radii_.TopLeft().Height());
}
- FloatRect TopRightCorner() const {
+ constexpr FloatRect TopRightCorner() const {
return FloatRect(rect_.MaxX() - radii_.TopRight().Width(), rect_.Y(),
radii_.TopRight().Width(), radii_.TopRight().Height());
}
- FloatRect BottomLeftCorner() const {
+ constexpr FloatRect BottomLeftCorner() const {
return FloatRect(rect_.X(), rect_.MaxY() - radii_.BottomLeft().Height(),
radii_.BottomLeft().Width(), radii_.BottomLeft().Height());
}
- FloatRect BottomRightCorner() const {
+ constexpr FloatRect BottomRightCorner() const {
return FloatRect(rect_.MaxX() - radii_.BottomRight().Width(),
rect_.MaxY() - radii_.BottomRight().Height(),
radii_.BottomRight().Width(),
@@ -218,22 +218,24 @@ inline FloatRoundedRect::operator SkRRect() const {
return rrect;
}
-inline bool operator==(const FloatRoundedRect::Radii& a,
- const FloatRoundedRect::Radii& b) {
+constexpr bool operator==(const FloatRoundedRect::Radii& a,
+ const FloatRoundedRect::Radii& b) {
return a.TopLeft() == b.TopLeft() && a.TopRight() == b.TopRight() &&
a.BottomLeft() == b.BottomLeft() && a.BottomRight() == b.BottomRight();
}
-inline bool operator!=(const FloatRoundedRect::Radii& a,
- const FloatRoundedRect::Radii& b) {
+constexpr bool operator!=(const FloatRoundedRect::Radii& a,
+ const FloatRoundedRect::Radii& b) {
return !(a == b);
}
-inline bool operator==(const FloatRoundedRect& a, const FloatRoundedRect& b) {
+constexpr bool operator==(const FloatRoundedRect& a,
+ const FloatRoundedRect& b) {
return a.Rect() == b.Rect() && a.GetRadii() == b.GetRadii();
}
-inline bool operator!=(const FloatRoundedRect& a, const FloatRoundedRect& b) {
+constexpr bool operator!=(const FloatRoundedRect& a,
+ const FloatRoundedRect& b) {
return !(a == b);
}
diff --git a/chromium/third_party/blink/renderer/platform/geometry/float_size.h b/chromium/third_party/blink/renderer/platform/geometry/float_size.h
index faf4827472b..b7989075bdc 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/float_size.h
+++ b/chromium/third_party/blink/renderer/platform/geometry/float_size.h
@@ -34,6 +34,7 @@
#include "third_party/blink/renderer/platform/geometry/int_point.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
+#include "third_party/blink/renderer/platform/wtf/math_extras.h"
#if defined(OS_MACOSX)
typedef struct CGSize CGSize;
@@ -59,8 +60,9 @@ class PLATFORM_EXPORT FloatSize {
DISALLOW_NEW();
public:
- FloatSize() : width_(0), height_(0) {}
- FloatSize(float width, float height) : width_(width), height_(height) {}
+ constexpr FloatSize() : width_(0), height_(0) {}
+ constexpr FloatSize(float width, float height)
+ : width_(width), height_(height) {}
explicit FloatSize(const IntSize& size)
: width_(size.Width()), height_(size.Height()) {}
FloatSize(const SkSize&);
@@ -68,16 +70,19 @@ class PLATFORM_EXPORT FloatSize {
static FloatSize NarrowPrecision(double width, double height);
- float Width() const { return width_; }
- float Height() const { return height_; }
+ constexpr float Width() const { return width_; }
+ constexpr float Height() const { return height_; }
- void SetWidth(float width) { width_ = width; }
- void SetHeight(float height) { height_ = height; }
+ constexpr void SetWidth(float width) { width_ = width; }
+ constexpr void SetHeight(float height) { height_ = height; }
- bool IsEmpty() const { return width_ <= 0 || height_ <= 0; }
- bool IsZero() const {
- return fabs(width_) < std::numeric_limits<float>::epsilon() &&
- fabs(height_) < std::numeric_limits<float>::epsilon();
+ constexpr bool IsEmpty() const { return width_ <= 0 || height_ <= 0; }
+ constexpr bool IsZero() const {
+ // Not using fabs as it is not a constexpr in LLVM libc++
+ return -std::numeric_limits<float>::epsilon() < width_ &&
+ width_ < std::numeric_limits<float>::epsilon() &&
+ -std::numeric_limits<float>::epsilon() < height_ &&
+ height_ < std::numeric_limits<float>::epsilon();
}
bool IsExpressibleAsIntSize() const;
@@ -153,38 +158,38 @@ inline FloatSize& operator+=(FloatSize& a, const FloatSize& b) {
return a;
}
-inline FloatSize& operator-=(FloatSize& a, const FloatSize& b) {
+constexpr FloatSize& operator-=(FloatSize& a, const FloatSize& b) {
a.SetWidth(a.Width() - b.Width());
a.SetHeight(a.Height() - b.Height());
return a;
}
-inline FloatSize operator+(const FloatSize& a, const FloatSize& b) {
+constexpr FloatSize operator+(const FloatSize& a, const FloatSize& b) {
return FloatSize(a.Width() + b.Width(), a.Height() + b.Height());
}
-inline FloatSize operator-(const FloatSize& a, const FloatSize& b) {
+constexpr FloatSize operator-(const FloatSize& a, const FloatSize& b) {
return FloatSize(a.Width() - b.Width(), a.Height() - b.Height());
}
-inline FloatSize operator-(const FloatSize& size) {
+constexpr FloatSize operator-(const FloatSize& size) {
return FloatSize(-size.Width(), -size.Height());
}
-inline FloatSize operator*(const FloatSize& a, const float b) {
+constexpr FloatSize operator*(const FloatSize& a, const float b) {
return FloatSize(a.Width() * b, a.Height() * b);
}
-inline FloatSize operator*(const float a, const FloatSize& b) {
+constexpr FloatSize operator*(const float a, const FloatSize& b) {
return FloatSize(a * b.Width(), a * b.Height());
}
-inline bool operator==(const FloatSize& a, const FloatSize& b) {
+constexpr bool operator==(const FloatSize& a, const FloatSize& b) {
return a.Width() == b.Width() && a.Height() == b.Height();
}
-inline bool operator!=(const FloatSize& a, const FloatSize& b) {
- return a.Width() != b.Width() || a.Height() != b.Height();
+constexpr bool operator!=(const FloatSize& a, const FloatSize& b) {
+ return !(a == b);
}
inline IntSize RoundedIntSize(const FloatSize& p) {
diff --git a/chromium/third_party/blink/renderer/platform/geometry/int_point.h b/chromium/third_party/blink/renderer/platform/geometry/int_point.h
index 95b7daf655d..5da33140e4c 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/int_point.h
+++ b/chromium/third_party/blink/renderer/platform/geometry/int_point.h
@@ -54,15 +54,15 @@ class PLATFORM_EXPORT IntPoint {
USING_FAST_MALLOC(IntPoint);
public:
- IntPoint() : x_(0), y_(0) {}
- IntPoint(int x, int y) : x_(x), y_(y) {}
+ constexpr IntPoint() : x_(0), y_(0) {}
+ constexpr IntPoint(int x, int y) : x_(x), y_(y) {}
explicit IntPoint(const IntSize& size)
: x_(size.Width()), y_(size.Height()) {}
static IntPoint Zero() { return IntPoint(); }
- int X() const { return x_; }
- int Y() const { return y_; }
+ constexpr int X() const { return x_; }
+ constexpr int Y() const { return y_; }
void SetX(int x) { x_ = x; }
void SetY(int y) { y_ = y; }
@@ -126,32 +126,32 @@ inline IntPoint& operator-=(IntPoint& a, const IntSize& b) {
return a;
}
-inline IntPoint operator+(const IntPoint& a, const IntSize& b) {
+constexpr IntPoint operator+(const IntPoint& a, const IntSize& b) {
return IntPoint(a.X() + b.Width(), a.Y() + b.Height());
}
-inline IntPoint operator+(const IntPoint& a, const IntPoint& b) {
+constexpr IntPoint operator+(const IntPoint& a, const IntPoint& b) {
return IntPoint(a.X() + b.X(), a.Y() + b.Y());
}
-inline IntSize operator-(const IntPoint& a, const IntPoint& b) {
+constexpr IntSize operator-(const IntPoint& a, const IntPoint& b) {
return IntSize(a.X() - b.X(), a.Y() - b.Y());
}
-inline IntPoint operator-(const IntPoint& a, const IntSize& b) {
+constexpr IntPoint operator-(const IntPoint& a, const IntSize& b) {
return IntPoint(a.X() - b.Width(), a.Y() - b.Height());
}
-inline IntPoint operator-(const IntPoint& point) {
+constexpr IntPoint operator-(const IntPoint& point) {
return IntPoint(-point.X(), -point.Y());
}
-inline bool operator==(const IntPoint& a, const IntPoint& b) {
+constexpr bool operator==(const IntPoint& a, const IntPoint& b) {
return a.X() == b.X() && a.Y() == b.Y();
}
-inline bool operator!=(const IntPoint& a, const IntPoint& b) {
- return a.X() != b.X() || a.Y() != b.Y();
+constexpr bool operator!=(const IntPoint& a, const IntPoint& b) {
+ return !(a == b);
}
inline IntSize ToIntSize(const IntPoint& a) {
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 e9d86bf8714..6d07e19ac76 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/int_rect.h
+++ b/chromium/third_party/blink/renderer/platform/geometry/int_rect.h
@@ -58,38 +58,38 @@ class PLATFORM_EXPORT IntRect {
USING_FAST_MALLOC(IntRect);
public:
- IntRect() = default;
- IntRect(const IntPoint& location, const IntSize& size)
+ constexpr IntRect() = default;
+ constexpr IntRect(const IntPoint& location, const IntSize& size)
: location_(location), size_(size) {}
- IntRect(int x, int y, int width, int height)
+ constexpr IntRect(int x, int y, int width, int height)
: location_(IntPoint(x, y)), size_(IntSize(width, height)) {}
// Use EnclosingIntRect(), EnclosedIntRect(), RoundedIntRect(),
// PixelSnappedIntRect(), etc. instead.
- explicit IntRect(const FloatRect&) = delete;
- explicit IntRect(const LayoutRect&) = delete;
+ constexpr explicit IntRect(const FloatRect&) = delete;
+ constexpr explicit IntRect(const LayoutRect&) = delete;
explicit IntRect(const gfx::Rect& rect);
- IntPoint Location() const { return location_; }
- IntSize Size() const { return size_; }
+ constexpr IntPoint Location() const { return location_; }
+ constexpr IntSize Size() const { return size_; }
void SetLocation(const IntPoint& location) { location_ = location; }
void SetSize(const IntSize& size) { size_ = size; }
- int X() const { return location_.X(); }
- int Y() const { return location_.Y(); }
- int MaxX() const { return X() + Width(); }
- int MaxY() const { return Y() + Height(); }
- int Width() const { return size_.Width(); }
- int Height() const { return size_.Height(); }
+ constexpr int X() const { return location_.X(); }
+ constexpr int Y() const { return location_.Y(); }
+ constexpr int MaxX() const { return X() + Width(); }
+ constexpr int MaxY() const { return Y() + Height(); }
+ constexpr int Width() const { return size_.Width(); }
+ constexpr int Height() const { return size_.Height(); }
void SetX(int x) { location_.SetX(x); }
void SetY(int y) { location_.SetY(y); }
void SetWidth(int width) { size_.SetWidth(width); }
void SetHeight(int height) { size_.SetHeight(height); }
- bool IsEmpty() const { return size_.IsEmpty(); }
+ constexpr bool IsEmpty() const { return size_.IsEmpty(); }
// NOTE: The result is rounded to integer values, and thus may be not the
// exact center point.
@@ -120,14 +120,16 @@ class PLATFORM_EXPORT IntRect {
void ShiftYEdgeTo(int);
void ShiftMaxYEdgeTo(int);
- IntPoint MinXMinYCorner() const { return location_; } // typically topLeft
- IntPoint MaxXMinYCorner() const {
+ constexpr IntPoint MinXMinYCorner() const {
+ return location_;
+ } // typically topLeft
+ constexpr IntPoint MaxXMinYCorner() const {
return IntPoint(location_.X() + size_.Width(), location_.Y());
} // typically topRight
- IntPoint MinXMaxYCorner() const {
+ constexpr IntPoint MinXMaxYCorner() const {
return IntPoint(location_.X(), location_.Y() + size_.Height());
} // typically bottomLeft
- IntPoint MaxXMaxYCorner() const {
+ constexpr IntPoint MaxXMaxYCorner() const {
return IntPoint(location_.X() + size_.Width(),
location_.Y() + size_.Height());
} // typically bottomRight
@@ -218,17 +220,17 @@ inline IntRect UnionRectEvenIfEmpty(const IntRect& a, const IntRect& b) {
PLATFORM_EXPORT IntRect UnionRectEvenIfEmpty(const Vector<IntRect>&);
-inline IntRect SaturatedRect(const IntRect& r) {
+constexpr IntRect SaturatedRect(const IntRect& r) {
return IntRect(r.X(), r.Y(), ClampAdd(r.X(), r.Width()) - r.X(),
ClampAdd(r.Y(), r.Height()) - r.Y());
}
-inline bool operator==(const IntRect& a, const IntRect& b) {
+constexpr bool operator==(const IntRect& a, const IntRect& b) {
return a.Location() == b.Location() && a.Size() == b.Size();
}
-inline bool operator!=(const IntRect& a, const IntRect& b) {
- return a.Location() != b.Location() || a.Size() != b.Size();
+constexpr bool operator!=(const IntRect& a, const IntRect& b) {
+ return !(a == b);
}
PLATFORM_EXPORT std::ostream& operator<<(std::ostream&, const IntRect&);
diff --git a/chromium/third_party/blink/renderer/platform/geometry/int_rect_outsets.h b/chromium/third_party/blink/renderer/platform/geometry/int_rect_outsets.h
index a5e4689b560..30ccf488e81 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/int_rect_outsets.h
+++ b/chromium/third_party/blink/renderer/platform/geometry/int_rect_outsets.h
@@ -44,22 +44,24 @@ class PLATFORM_EXPORT IntRectOutsets {
DISALLOW_NEW();
public:
- IntRectOutsets() : top_(0), right_(0), bottom_(0), left_(0) {}
+ constexpr IntRectOutsets() : top_(0), right_(0), bottom_(0), left_(0) {}
- IntRectOutsets(int top, int right, int bottom, int left)
+ constexpr IntRectOutsets(int top, int right, int bottom, int left)
: top_(top), right_(right), bottom_(bottom), left_(left) {}
- int Top() const { return top_; }
- int Right() const { return right_; }
- int Bottom() const { return bottom_; }
- int Left() const { return left_; }
+ constexpr int Top() const { return top_; }
+ constexpr int Right() const { return right_; }
+ constexpr int Bottom() const { return bottom_; }
+ constexpr int Left() const { return left_; }
void SetTop(int top) { top_ = top; }
void SetRight(int right) { right_ = right; }
void SetBottom(int bottom) { bottom_ = bottom; }
void SetLeft(int left) { left_ = left; }
- bool IsZero() const { return !Left() && !Right() && !Top() && !Bottom(); }
+ constexpr bool IsZero() const {
+ return !Left() && !Right() && !Top() && !Bottom();
+ }
private:
int top_;
diff --git a/chromium/third_party/blink/renderer/platform/geometry/int_size.h b/chromium/third_party/blink/renderer/platform/geometry/int_size.h
index ca7913e5d60..a67d57574ea 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/int_size.h
+++ b/chromium/third_party/blink/renderer/platform/geometry/int_size.h
@@ -53,18 +53,18 @@ class PLATFORM_EXPORT IntSize {
DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
public:
- IntSize() : width_(0), height_(0) {}
- IntSize(int width, int height) : width_(width), height_(height) {}
+ constexpr IntSize() : width_(0), height_(0) {}
+ constexpr IntSize(int width, int height) : width_(width), height_(height) {}
explicit IntSize(const gfx::Size&);
- int Width() const { return width_; }
- int Height() const { return height_; }
+ constexpr int Width() const { return width_; }
+ constexpr int Height() const { return height_; }
void SetWidth(int width) { width_ = width; }
void SetHeight(int height) { height_ = height; }
- bool IsEmpty() const { return width_ <= 0 || height_ <= 0; }
- bool IsZero() const { return !width_ && !height_; }
+ constexpr bool IsEmpty() const { return width_ <= 0 || height_ <= 0; }
+ constexpr bool IsZero() const { return !width_ && !height_; }
float AspectRatio() const {
return static_cast<float>(width_) / static_cast<float>(height_);
diff --git a/chromium/third_party/blink/renderer/platform/geometry/layout_point.h b/chromium/third_party/blink/renderer/platform/geometry/layout_point.h
index 10726fb782c..2f3c1beb0fc 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/layout_point.h
+++ b/chromium/third_party/blink/renderer/platform/geometry/layout_point.h
@@ -44,21 +44,21 @@ class PLATFORM_EXPORT LayoutPoint {
DISALLOW_NEW();
public:
- LayoutPoint() = default;
- LayoutPoint(LayoutUnit x, LayoutUnit y) : x_(x), y_(y) {}
+ constexpr LayoutPoint() = default;
+ constexpr LayoutPoint(LayoutUnit x, LayoutUnit y) : x_(x), y_(y) {}
LayoutPoint(int x, int y) : x_(LayoutUnit(x)), y_(LayoutUnit(y)) {}
LayoutPoint(const IntPoint& point) : x_(point.X()), y_(point.Y()) {}
explicit LayoutPoint(const FloatPoint& point)
: x_(point.X()), y_(point.Y()) {}
explicit LayoutPoint(const DoublePoint& point)
: x_(point.X()), y_(point.Y()) {}
- explicit LayoutPoint(const LayoutSize& size)
+ constexpr explicit LayoutPoint(const LayoutSize& size)
: x_(size.Width()), y_(size.Height()) {}
- static LayoutPoint Zero() { return LayoutPoint(); }
+ static constexpr LayoutPoint Zero() { return LayoutPoint(); }
- LayoutUnit X() const { return x_; }
- LayoutUnit Y() const { return y_; }
+ constexpr LayoutUnit X() const { return x_; }
+ constexpr LayoutUnit Y() const { return y_; }
void SetX(LayoutUnit x) { x_ = x; }
void SetY(LayoutUnit y) { y_ = y; }
@@ -148,23 +148,24 @@ inline LayoutPoint operator-(const LayoutPoint& point) {
return LayoutPoint(-point.X(), -point.Y());
}
-ALWAYS_INLINE bool operator==(const LayoutPoint& a, const LayoutPoint& b) {
+constexpr ALWAYS_INLINE bool operator==(const LayoutPoint& a,
+ const LayoutPoint& b) {
return a.X() == b.X() && a.Y() == b.Y();
}
-inline bool operator!=(const LayoutPoint& a, const LayoutPoint& b) {
- return a.X() != b.X() || a.Y() != b.Y();
+constexpr bool operator!=(const LayoutPoint& a, const LayoutPoint& b) {
+ return !(a == b);
}
-inline LayoutPoint ToPoint(const LayoutSize& size) {
+constexpr inline LayoutPoint ToPoint(const LayoutSize& size) {
return LayoutPoint(size.Width(), size.Height());
}
-inline LayoutPoint ToLayoutPoint(const LayoutSize& p) {
+constexpr inline LayoutPoint ToLayoutPoint(const LayoutSize& p) {
return LayoutPoint(p.Width(), p.Height());
}
-inline LayoutSize ToSize(const LayoutPoint& a) {
+constexpr inline LayoutSize ToSize(const LayoutPoint& a) {
return LayoutSize(a.X(), a.Y());
}
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 e05e54d40df..c3dd51bb55e 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/layout_rect.h
+++ b/chromium/third_party/blink/renderer/platform/geometry/layout_rect.h
@@ -48,10 +48,13 @@ class PLATFORM_EXPORT LayoutRect {
DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
public:
- LayoutRect() = default;
- LayoutRect(const LayoutPoint& location, const LayoutSize& size)
+ constexpr LayoutRect() = default;
+ constexpr LayoutRect(const LayoutPoint& location, const LayoutSize& size)
: location_(location), size_(size) {}
- LayoutRect(LayoutUnit x, LayoutUnit y, LayoutUnit width, LayoutUnit height)
+ constexpr LayoutRect(LayoutUnit x,
+ LayoutUnit y,
+ LayoutUnit width,
+ LayoutUnit height)
: location_(LayoutPoint(x, y)), size_(LayoutSize(width, height)) {}
LayoutRect(int x, int y, int width, int height)
: location_(LayoutPoint(x, y)), size_(LayoutSize(width, height)) {}
@@ -68,8 +71,8 @@ class PLATFORM_EXPORT LayoutRect {
explicit LayoutRect(const FloatRect&);
explicit LayoutRect(const DoubleRect&);
- LayoutPoint Location() const { return location_; }
- LayoutSize Size() const { return size_; }
+ constexpr LayoutPoint Location() const { return location_; }
+ constexpr LayoutSize Size() const { return size_; }
IntPoint PixelSnappedLocation() const { return RoundedIntPoint(location_); }
IntSize PixelSnappedSize() const {
@@ -80,12 +83,12 @@ class PLATFORM_EXPORT LayoutRect {
void SetLocation(const LayoutPoint& location) { location_ = location; }
void SetSize(const LayoutSize& size) { size_ = size; }
- ALWAYS_INLINE LayoutUnit X() const { return location_.X(); }
- ALWAYS_INLINE LayoutUnit Y() const { return location_.Y(); }
+ constexpr ALWAYS_INLINE LayoutUnit X() const { return location_.X(); }
+ constexpr ALWAYS_INLINE LayoutUnit Y() const { return location_.Y(); }
ALWAYS_INLINE LayoutUnit MaxX() const { return X() + Width(); }
ALWAYS_INLINE LayoutUnit MaxY() const { return Y() + Height(); }
- LayoutUnit Width() const { return size_.Width(); }
- LayoutUnit Height() const { return size_.Height(); }
+ constexpr LayoutUnit Width() const { return size_.Width(); }
+ constexpr LayoutUnit Height() const { return size_.Height(); }
int PixelSnappedWidth() const { return SnapSizeToPixel(Width(), X()); }
int PixelSnappedHeight() const { return SnapSizeToPixel(Height(), Y()); }
@@ -95,7 +98,7 @@ class PLATFORM_EXPORT LayoutRect {
void SetWidth(LayoutUnit width) { size_.SetWidth(width); }
void SetHeight(LayoutUnit height) { size_.SetHeight(height); }
- ALWAYS_INLINE bool IsEmpty() const { return size_.IsEmpty(); }
+ constexpr ALWAYS_INLINE bool IsEmpty() const { return size_.IsEmpty(); }
// NOTE: The result is rounded to integer values, and thus may be not the
// exact center point.
@@ -169,7 +172,9 @@ class PLATFORM_EXPORT LayoutRect {
SetHeight((Height() + delta).ClampNegativeToZero());
}
- LayoutPoint MinXMinYCorner() const { return location_; } // typically topLeft
+ constexpr LayoutPoint MinXMinYCorner() const {
+ return location_;
+ } // typically topLeft
LayoutPoint MaxXMinYCorner() const {
return LayoutPoint(location_.X() + size_.Width(), location_.Y());
} // typically topRight
@@ -277,12 +282,13 @@ inline LayoutRect UnionRectEvenIfEmpty(const LayoutRect& a,
PLATFORM_EXPORT LayoutRect UnionRectEvenIfEmpty(const Vector<LayoutRect>&);
-ALWAYS_INLINE bool operator==(const LayoutRect& a, const LayoutRect& b) {
+constexpr ALWAYS_INLINE bool operator==(const LayoutRect& a,
+ const LayoutRect& b) {
return a.Location() == b.Location() && a.Size() == b.Size();
}
-inline bool operator!=(const LayoutRect& a, const LayoutRect& b) {
- return a.Location() != b.Location() || a.Size() != b.Size();
+constexpr bool operator!=(const LayoutRect& a, const LayoutRect& b) {
+ return !(a == b);
}
inline IntRect PixelSnappedIntRect(const LayoutRect& rect) {
diff --git a/chromium/third_party/blink/renderer/platform/geometry/layout_rect_outsets.h b/chromium/third_party/blink/renderer/platform/geometry/layout_rect_outsets.h
index 6086d2cfa42..9f9c4bcc6b9 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/layout_rect_outsets.h
+++ b/chromium/third_party/blink/renderer/platform/geometry/layout_rect_outsets.h
@@ -49,11 +49,11 @@ class PLATFORM_EXPORT LayoutRectOutsets {
DISALLOW_NEW();
public:
- LayoutRectOutsets() = default;
- LayoutRectOutsets(LayoutUnit top,
- LayoutUnit right,
- LayoutUnit bottom,
- LayoutUnit left)
+ constexpr LayoutRectOutsets() = default;
+ constexpr LayoutRectOutsets(LayoutUnit top,
+ LayoutUnit right,
+ LayoutUnit bottom,
+ LayoutUnit left)
: top_(top), right_(right), bottom_(bottom), left_(left) {}
LayoutRectOutsets(int top, int right, int bottom, int left)
: top_(LayoutUnit(top)),
@@ -73,10 +73,10 @@ class PLATFORM_EXPORT LayoutRectOutsets {
bottom_(LayoutUnit(outsets.Bottom())),
left_(LayoutUnit(outsets.Left())) {}
- LayoutUnit Top() const { return top_; }
- LayoutUnit Right() const { return right_; }
- LayoutUnit Bottom() const { return bottom_; }
- LayoutUnit Left() const { return left_; }
+ constexpr LayoutUnit Top() const { return top_; }
+ constexpr LayoutUnit Right() const { return right_; }
+ constexpr LayoutUnit Bottom() const { return bottom_; }
+ constexpr LayoutUnit Left() const { return left_; }
void SetTop(LayoutUnit value) { top_ = value; }
void SetRight(LayoutUnit value) { right_ = value; }
@@ -84,7 +84,9 @@ class PLATFORM_EXPORT LayoutRectOutsets {
void SetLeft(LayoutUnit value) { left_ = value; }
LayoutSize Size() const { return LayoutSize(left_ + right_, top_ + bottom_); }
- bool IsZero() const { return !top_ && !right_ && !bottom_ && !left_; }
+ constexpr bool IsZero() const {
+ return !top_ && !right_ && !bottom_ && !left_;
+ }
void ClampNegativeToZero();
@@ -92,7 +94,7 @@ class PLATFORM_EXPORT LayoutRectOutsets {
void FlipHorizontally() { std::swap(left_, right_); }
- bool operator==(const LayoutRectOutsets other) const {
+ constexpr bool operator==(const LayoutRectOutsets other) const {
return Top() == other.Top() && Right() == other.Right() &&
Bottom() == other.Bottom() && Left() == other.Left();
}
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 280ee87ccf3..e50638247dd 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/layout_size.h
+++ b/chromium/third_party/blink/renderer/platform/geometry/layout_size.h
@@ -48,10 +48,10 @@ class PLATFORM_EXPORT LayoutSize {
DISALLOW_NEW();
public:
- LayoutSize() = default;
+ constexpr LayoutSize() = default;
explicit LayoutSize(const IntSize& size)
: width_(size.Width()), height_(size.Height()) {}
- LayoutSize(LayoutUnit width, LayoutUnit height)
+ constexpr LayoutSize(LayoutUnit width, LayoutUnit height)
: width_(width), height_(height) {}
LayoutSize(int width, int height)
: width_(LayoutUnit(width)), height_(LayoutUnit(height)) {}
@@ -63,16 +63,16 @@ class PLATFORM_EXPORT LayoutSize {
explicit LayoutSize(const DoubleSize& size)
: width_(size.Width()), height_(size.Height()) {}
- LayoutUnit Width() const { return width_; }
- LayoutUnit Height() const { return height_; }
+ constexpr LayoutUnit Width() const { return width_; }
+ constexpr LayoutUnit Height() const { return height_; }
void SetWidth(LayoutUnit width) { width_ = width; }
void SetHeight(LayoutUnit height) { height_ = height; }
- bool IsEmpty() const {
+ constexpr bool IsEmpty() const {
return width_.RawValue() <= 0 || height_.RawValue() <= 0;
}
- bool IsZero() const { return !width_ && !height_; }
+ constexpr bool IsZero() const { return !width_ && !height_; }
float AspectRatio() const { return width_.ToFloat() / height_.ToFloat(); }
@@ -194,7 +194,7 @@ inline LayoutSize operator*(const LayoutSize& a, const float scale) {
return LayoutSize(a.Width() * scale, a.Height() * scale);
}
-inline bool operator==(const LayoutSize& a, const LayoutSize& b) {
+constexpr bool operator==(const LayoutSize& a, const LayoutSize& b) {
return a.Width() == b.Width() && a.Height() == b.Height();
}
@@ -202,15 +202,15 @@ inline bool operator==(const LayoutSize& a, const IntSize& b) {
return a.Width() == b.Width() && a.Height() == b.Height();
}
-inline bool operator!=(const LayoutSize& a, const LayoutSize& b) {
- return a.Width() != b.Width() || a.Height() != b.Height();
+constexpr bool operator!=(const LayoutSize& a, const LayoutSize& b) {
+ return !(a == b);
}
inline bool operator!=(const LayoutSize& a, const IntSize& b) {
return a.Width() != b.Width() || a.Height() != b.Height();
}
-inline FloatPoint operator+(const FloatPoint& a, const LayoutSize& b) {
+constexpr FloatPoint operator+(const FloatPoint& a, const LayoutSize& b) {
return FloatPoint(a.X() + b.Width(), a.Y() + b.Height());
}
diff --git a/chromium/third_party/blink/renderer/platform/geometry/layout_size_test.cc b/chromium/third_party/blink/renderer/platform/geometry/layout_size_test.cc
index 2eb9e1ff244..8c5e394c337 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/layout_size_test.cc
+++ b/chromium/third_party/blink/renderer/platform/geometry/layout_size_test.cc
@@ -18,7 +18,6 @@ TEST(LayoutSizeTest, FitToAspectRatioDoesntOverflow) {
.FitToAspectRatio(aspect_ratio, kAspectRatioFitShrink)
.ToString());
- LayoutSize size(1000, 2000);
EXPECT_EQ("1000x1000",
LayoutSize(1000, 2000)
.FitToAspectRatio(aspect_ratio, kAspectRatioFitShrink)
diff --git a/chromium/third_party/blink/renderer/platform/graphics/DEPS b/chromium/third_party/blink/renderer/platform/graphics/DEPS
index 0ef1e730698..11fa8ee237a 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/DEPS
+++ b/chromium/third_party/blink/renderer/platform/graphics/DEPS
@@ -3,18 +3,11 @@ include_rules = [
"-third_party/blink/renderer/platform",
# Module.
- "+third_party/blink/renderer/platform/geometry",
+ "+third_party/blink/renderer/platform/graphics",
# Dependencies.
- "+base/bind.h",
- "+base/callback.h",
- "+base/compiler_specific.h",
- "+base/message_loop",
- "+base/task_runner.h",
- "+base/task_runner_util.h",
"+base/threading/sequenced_task_runner_handle.h",
- "+base/threading/thread.h",
- "+base/threading/thread_checker.h",
+ "+base/threading/thread_restrictions.h",
"+cc",
"+components/viz/client",
"+components/viz/common",
@@ -29,25 +22,21 @@ include_rules = [
"+media/base/media_switches.h",
"+media/base/video_frame.h",
"+media/renderers/video_resource_updater.h",
- "+services/ui/public/cpp/gpu/context_provider_command_buffer.h",
"+services/viz/public/interfaces",
- "+third_party/blink/renderer/platform/animation",
- "+third_party/blink/renderer/platform/bindings/runtime_call_stats.h",
- "+third_party/blink/renderer/platform/bindings",
+ "+services/ws/public/cpp/gpu/context_provider_command_buffer.h",
"+third_party/blink/renderer/platform/cpu/mips/common_macros_msa.h",
"+third_party/blink/renderer/platform/cross_thread_functional.h",
"+third_party/blink/renderer/platform/drag_image.h",
"+third_party/blink/renderer/platform/fonts",
- "+third_party/blink/renderer/platform/graphics",
+ "+third_party/blink/renderer/platform/geometry",
"+third_party/blink/renderer/platform/heap",
"+third_party/blink/renderer/platform/histogram.h",
"+third_party/blink/renderer/platform/image-decoders",
"+third_party/blink/renderer/platform/image-encoders",
"+third_party/blink/renderer/platform/instrumentation",
- "+third_party/blink/renderer/platform/json/json_values.h",
+ "+third_party/blink/renderer/platform/json",
"+third_party/blink/renderer/platform/length.h",
"+third_party/blink/renderer/platform/mojo/mojo_helper.h",
- "+third_party/blink/renderer/platform/network/mime/mime_type_registry.h",
"+third_party/blink/renderer/platform/platform_export.h",
"+third_party/blink/renderer/platform/runtime_enabled_features.h",
"+third_party/blink/renderer/platform/scheduler",
@@ -61,7 +50,6 @@ include_rules = [
"+third_party/blink/renderer/platform/weborigin/kurl.h",
"+third_party/blink/renderer/platform/web_task_runner.h",
"+third_party/blink/renderer/platform/wtf",
- "+third_party/blink/public/web/web_settings.h",
"+ui/gfx/geometry",
]
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 f6a0cca44e1..b5a53cca646 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
@@ -42,6 +42,14 @@ void BeginFrameProvider::OnMojoConnectionError(uint32_t custom_reason,
ResetCompositorFrameSink();
}
+bool BeginFrameProvider::IsValidFrameProvider() {
+ if (!parent_frame_sink_id_.is_valid() || !frame_sink_id_.is_valid()) {
+ return false;
+ }
+
+ return true;
+}
+
void BeginFrameProvider::CreateCompositorFrameSinkIfNeeded() {
if (!parent_frame_sink_id_.is_valid() || !frame_sink_id_.is_valid()) {
return;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/begin_frame_provider.h b/chromium/third_party/blink/renderer/platform/graphics/begin_frame_provider.h
index f1f211ed0e8..409ea510d0c 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/begin_frame_provider.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/begin_frame_provider.h
@@ -60,6 +60,8 @@ class PLATFORM_EXPORT BeginFrameProvider
void ResetCompositorFrameSink();
+ bool IsValidFrameProvider();
+
~BeginFrameProvider() override = default;
private:
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 8bf47e9b7b7..14042996cb2 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/bitmap_image.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/bitmap_image.cc
@@ -32,7 +32,6 @@
#include "base/memory/scoped_refptr.h"
#include "base/metrics/histogram_macros.h"
-#include "third_party/blink/public/web/web_settings.h"
#include "third_party/blink/renderer/platform/geometry/float_rect.h"
#include "third_party/blink/renderer/platform/graphics/bitmap_image_metrics.h"
#include "third_party/blink/renderer/platform/graphics/deferred_image_decoder.h"
@@ -110,13 +109,14 @@ size_t BitmapImage::TotalFrameBytes() {
return 0u;
}
-PaintImage BitmapImage::PaintImageForTesting(size_t frame_index) {
- return CreatePaintImage(frame_index);
+PaintImage BitmapImage::PaintImageForTesting() {
+ return CreatePaintImage();
}
-PaintImage BitmapImage::CreatePaintImage(size_t index) {
+PaintImage BitmapImage::CreatePaintImage() {
sk_sp<PaintImageGenerator> generator =
- decoder_ ? decoder_->CreateGenerator(index) : nullptr;
+ decoder_ ? decoder_->CreateGenerator(PaintImage::kDefaultFrameIndex)
+ : nullptr;
if (!generator)
return PaintImage();
@@ -126,7 +126,6 @@ PaintImage BitmapImage::CreatePaintImage(size_t index) {
auto builder =
CreatePaintImageBuilder()
.set_paint_image_generator(std::move(generator))
- .set_frame_index(index)
.set_repetition_count(GetRepetitionCountWithPolicyOverride(
RepetitionCount(), animation_policy_))
.set_completion_state(completion_state)
@@ -186,6 +185,15 @@ Image::SizeAvailability BitmapImage::SetData(scoped_refptr<SharedBuffer> data,
return DataChanged(all_data_received);
}
+// Return the image density in 0.01 "bits per pixel" rounded to the nearest
+// integer.
+static inline int ImageDensityInCentiBpp(IntSize size,
+ size_t image_size_bytes) {
+ uint64_t image_area = static_cast<uint64_t>(size.Width()) * size.Height();
+ return (static_cast<uint64_t>(image_size_bytes) * 100 * 8 + image_area / 2) /
+ image_area;
+}
+
Image::SizeAvailability BitmapImage::DataChanged(bool all_data_received) {
TRACE_EVENT0("blink", "BitmapImage::dataChanged");
@@ -194,6 +202,17 @@ Image::SizeAvailability BitmapImage::DataChanged(bool all_data_received) {
// requires a new PaintImageGenerator instance.
cached_frame_ = PaintImage();
+ // Report the image density metric right after we received all the data. The
+ // SetData() call on the decoder_ (if there is one) should have decoded the
+ // images and we should know the image size at this point. We still check it
+ // here as a sanity check.
+ if (!all_data_received_ && all_data_received && decoder_ &&
+ decoder_->Data() && decoder_->FilenameExtension() == "jpg" &&
+ IsSizeAvailable() && Size().Width() >= 100 && Size().Height() >= 100) {
+ BitmapImageMetrics::CountImageJpegDensity(
+ ImageDensityInCentiBpp(Size(), decoder_->Data()->size()));
+ }
+
// Feed all the data we've seen so far to the image decoder.
all_data_received_ = all_data_received;
have_frame_count_ = false;
@@ -306,7 +325,7 @@ PaintImage BitmapImage::PaintImageForCurrentFrame() {
if (cached_frame_)
return cached_frame_;
- cached_frame_ = CreatePaintImage(PaintImage::kDefaultFrameIndex);
+ cached_frame_ = CreatePaintImage();
// Create the SkImage backing for this PaintImage here to ensure that copies
// of the PaintImage share the same SkImage. Skia's caching of the decoded
@@ -367,7 +386,7 @@ bool BitmapImage::CurrentFrameIsLazyDecoded() {
return true;
}
-ImageOrientation BitmapImage::CurrentFrameOrientation() {
+ImageOrientation BitmapImage::CurrentFrameOrientation() const {
return decoder_ ? decoder_->OrientationAtIndex(PaintImage::kDefaultFrameIndex)
: kDefaultImageOrientation;
}
@@ -414,11 +433,4 @@ void BitmapImage::SetAnimationPolicy(ImageAnimationPolicy policy) {
ResetAnimation();
}
-STATIC_ASSERT_ENUM(WebSettings::kImageAnimationPolicyAllowed,
- kImageAnimationPolicyAllowed);
-STATIC_ASSERT_ENUM(WebSettings::kImageAnimationPolicyAnimateOnce,
- kImageAnimationPolicyAnimateOnce);
-STATIC_ASSERT_ENUM(WebSettings::kImageAnimationPolicyNoAnimation,
- kImageAnimationPolicyNoAnimation);
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/bitmap_image.h b/chromium/third_party/blink/renderer/platform/graphics/bitmap_image.h
index 8aabf7fbe9e..eb3d0f6ca0b 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/bitmap_image.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/bitmap_image.h
@@ -91,9 +91,9 @@ class PLATFORM_EXPORT BitmapImage final : public Image {
bool CurrentFrameIsLazyDecoded() override;
size_t FrameCount() override;
PaintImage PaintImageForCurrentFrame() override;
- ImageOrientation CurrentFrameOrientation();
+ ImageOrientation CurrentFrameOrientation() const;
- PaintImage PaintImageForTesting(size_t frame_index);
+ PaintImage PaintImageForTesting();
void AdvanceAnimationForTesting() override {
NOTREACHED() << "Supported only with svgs";
}
@@ -129,7 +129,7 @@ class PLATFORM_EXPORT BitmapImage final : public Image {
ImageClampingMode,
ImageDecodingMode) override;
- PaintImage CreatePaintImage(size_t index);
+ PaintImage CreatePaintImage();
void UpdateSize() const;
// Called to wipe out the entire frame buffer cache and tell the image
diff --git a/chromium/third_party/blink/renderer/platform/graphics/bitmap_image_metrics.cc b/chromium/third_party/blink/renderer/platform/graphics/bitmap_image_metrics.cc
index e0e7a057267..b616f865962 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/bitmap_image_metrics.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/bitmap_image_metrics.cc
@@ -42,6 +42,13 @@ void BitmapImageMetrics::CountImageOrientation(
orientation_histogram.Count(orientation);
}
+void BitmapImageMetrics::CountImageJpegDensity(int64_t density_centi_bpp) {
+ DEFINE_THREAD_SAFE_STATIC_LOCAL(
+ CustomCountHistogram, density_histogram,
+ ("Blink.DecodedImage.JpegDensity", 1, 1000, 100)); // 0.01 to 10 bpp
+ density_histogram.Count(density_centi_bpp);
+}
+
void BitmapImageMetrics::CountImageGammaAndGamut(
const skcms_ICCProfile* color_profile) {
DEFINE_THREAD_SAFE_STATIC_LOCAL(EnumerationHistogram, gamma_named_histogram,
diff --git a/chromium/third_party/blink/renderer/platform/graphics/bitmap_image_metrics.h b/chromium/third_party/blink/renderer/platform/graphics/bitmap_image_metrics.h
index 5adc237e46f..c5a8ee724d7 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/bitmap_image_metrics.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/bitmap_image_metrics.h
@@ -49,6 +49,7 @@ class PLATFORM_EXPORT BitmapImageMetrics {
static void CountDecodedImageType(const String& type);
static void CountImageOrientation(const ImageOrientationEnum);
+ static void CountImageJpegDensity(int64_t density_centi_bpp);
static void CountImageGammaAndGamut(const skcms_ICCProfile*);
private:
@@ -57,4 +58,4 @@ class PLATFORM_EXPORT BitmapImageMetrics {
} // namespace blink
-#endif
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_BITMAP_IMAGE_METRICS_H_
diff --git a/chromium/third_party/blink/renderer/platform/graphics/bitmap_image_test.cc b/chromium/third_party/blink/renderer/platform/graphics/bitmap_image_test.cc
index 30a73bb3b88..eb0cd37c706 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/bitmap_image_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/bitmap_image_test.cc
@@ -50,6 +50,46 @@
#include "third_party/skia/include/core/SkImage.h"
namespace blink {
+namespace {
+
+class FrameSettingImageProvider : public cc::ImageProvider {
+ public:
+ FrameSettingImageProvider(size_t frame_index,
+ cc::PaintImage::GeneratorClientId client_id)
+ : frame_index_(frame_index), client_id_(client_id) {}
+ ~FrameSettingImageProvider() override = default;
+
+ ScopedDecodedDrawImage GetDecodedDrawImage(
+ const cc::DrawImage& draw_image) override {
+ auto sk_image =
+ draw_image.paint_image().GetSkImageForFrame(frame_index_, client_id_);
+ return ScopedDecodedDrawImage(
+ cc::DecodedDrawImage(sk_image, SkSize::MakeEmpty(), SkSize::Make(1, 1),
+ draw_image.filter_quality(), true));
+ }
+
+ private:
+ size_t frame_index_;
+ cc::PaintImage::GeneratorClientId client_id_;
+};
+
+void GenerateBitmapForPaintImage(cc::PaintImage paint_image,
+ size_t frame_index,
+ cc::PaintImage::GeneratorClientId client_id,
+ SkBitmap* bitmap) {
+ CHECK(paint_image);
+ CHECK_GE(paint_image.FrameCount(), frame_index);
+
+ SkImageInfo info =
+ SkImageInfo::MakeN32Premul(paint_image.width(), paint_image.height());
+ bitmap->allocPixels(info, paint_image.width() * 4);
+ bitmap->eraseColor(SK_AlphaTRANSPARENT);
+ FrameSettingImageProvider image_provider(frame_index, client_id);
+ cc::SkiaPaintCanvas canvas(*bitmap, &image_provider);
+ canvas.drawImage(paint_image, 0u, 0u, nullptr);
+}
+
+} // namespace
class BitmapImageTest : public testing::Test {
public:
@@ -97,18 +137,10 @@ class BitmapImageTest : public testing::Test {
}
SkBitmap GenerateBitmap(size_t frame_index) {
- CHECK_GE(image_->FrameCount(), frame_index);
- auto paint_image = image_->PaintImageForTesting(frame_index);
- CHECK(paint_image);
- CHECK_EQ(paint_image.frame_index(), frame_index);
-
SkBitmap bitmap;
- SkImageInfo info = SkImageInfo::MakeN32Premul(image_->Size().Width(),
- image_->Size().Height());
- bitmap.allocPixels(info, image_->Size().Width() * 4);
- bitmap.eraseColor(SK_AlphaTRANSPARENT);
- cc::SkiaPaintCanvas canvas(bitmap);
- canvas.drawImage(paint_image, 0u, 0u, nullptr);
+ GenerateBitmapForPaintImage(image_->PaintImageForTesting(), frame_index,
+ cc::PaintImage::kDefaultGeneratorClientId,
+ &bitmap);
return bitmap;
}
@@ -122,7 +154,6 @@ class BitmapImageTest : public testing::Test {
image->SetData(image_data, true);
auto paint_image = image->PaintImageForCurrentFrame();
CHECK(paint_image);
- CHECK_EQ(paint_image.frame_index(), 0u);
SkBitmap bitmap;
SkImageInfo info = SkImageInfo::MakeN32Premul(image->Size().Width(),
@@ -313,10 +344,8 @@ TEST_F(BitmapImageTest, ConstantImageIdForPartiallyLoadedImages) {
EXPECT_EQ(sk_image1->uniqueID(), sk_image2->uniqueID());
// Frame keys should be the same for these PaintImages.
- EXPECT_EQ(image1.GetKeyForFrame(image1.frame_index()),
- image2.GetKeyForFrame(image2.frame_index()));
- EXPECT_EQ(image1.frame_index(), 0u);
- EXPECT_EQ(image2.frame_index(), 0u);
+ EXPECT_EQ(image1.GetKeyForFrame(PaintImage::kDefaultFrameIndex),
+ image2.GetKeyForFrame(PaintImage::kDefaultFrameIndex));
// Destroy the decoded data. This generates a new id since we don't cache
// image ids for partial decodes.
@@ -328,9 +357,8 @@ TEST_F(BitmapImageTest, ConstantImageIdForPartiallyLoadedImages) {
// Since the cached generator is discarded on destroying the cached decode,
// the new content id is generated resulting in an updated frame key.
- EXPECT_NE(image1.GetKeyForFrame(image1.frame_index()),
- image3.GetKeyForFrame(image3.frame_index()));
- EXPECT_EQ(image3.frame_index(), 0u);
+ EXPECT_NE(image1.GetKeyForFrame(PaintImage::kDefaultFrameIndex),
+ image3.GetKeyForFrame(PaintImage::kDefaultFrameIndex));
// Load complete. This should generate a new image id.
image_->SetData(image_data, true);
@@ -338,9 +366,8 @@ TEST_F(BitmapImageTest, ConstantImageIdForPartiallyLoadedImages) {
auto complete_sk_image = complete_image.GetSkImage();
EXPECT_NE(sk_image3, complete_sk_image);
EXPECT_NE(sk_image3->uniqueID(), complete_sk_image->uniqueID());
- EXPECT_NE(complete_image.GetKeyForFrame(complete_image.frame_index()),
- image3.GetKeyForFrame(image3.frame_index()));
- EXPECT_EQ(complete_image.frame_index(), 0u);
+ EXPECT_NE(complete_image.GetKeyForFrame(PaintImage::kDefaultFrameIndex),
+ image3.GetKeyForFrame(PaintImage::kDefaultFrameIndex));
// Destroy the decoded data and re-create the PaintImage. The frame key
// remains constant but the SkImage id will change since we don't cache skia
@@ -349,9 +376,8 @@ TEST_F(BitmapImageTest, ConstantImageIdForPartiallyLoadedImages) {
auto new_complete_image = image_->PaintImageForCurrentFrame();
auto new_complete_sk_image = new_complete_image.GetSkImage();
EXPECT_NE(new_complete_sk_image, complete_sk_image);
- EXPECT_EQ(new_complete_image.GetKeyForFrame(new_complete_image.frame_index()),
- complete_image.GetKeyForFrame(complete_image.frame_index()));
- EXPECT_EQ(new_complete_image.frame_index(), 0u);
+ EXPECT_EQ(new_complete_image.GetKeyForFrame(PaintImage::kDefaultFrameIndex),
+ complete_image.GetKeyForFrame(PaintImage::kDefaultFrameIndex));
}
TEST_F(BitmapImageTest, ImageForDefaultFrame_MultiFrame) {
@@ -402,6 +428,37 @@ TEST_F(BitmapImageTest, GifDecoderFrame3) {
VerifyBitmap(bitmap, SK_ColorYELLOW);
}
+TEST_F(BitmapImageTest, GifDecoderMultiThreaded) {
+ LoadImage("/images/resources/green-red-blue-yellow-animated.gif");
+ auto paint_image = image_->PaintImageForTesting();
+ ASSERT_EQ(paint_image.FrameCount(), 4u);
+
+ struct Decode {
+ SkBitmap bitmap;
+ std::unique_ptr<base::Thread> thread;
+ cc::PaintImage::GeneratorClientId client_id;
+ };
+
+ Decode decodes[4];
+ SkColor expected_color[4] = {SkColorSetARGB(255, 0, 128, 0), SK_ColorRED,
+ SK_ColorBLUE, SK_ColorYELLOW};
+ for (int i = 0; i < 4; ++i) {
+ decodes[i].thread =
+ std::make_unique<base::Thread>("Decode" + std::to_string(i));
+ decodes[i].client_id = cc::PaintImage::GetNextGeneratorClientId();
+
+ decodes[i].thread->StartAndWaitForTesting();
+ decodes[i].thread->task_runner()->PostTask(
+ FROM_HERE, base::BindOnce(&GenerateBitmapForPaintImage, paint_image, i,
+ decodes[i].client_id, &decodes[i].bitmap));
+ }
+
+ for (int i = 0; i < 4; ++i) {
+ decodes[i].thread->FlushForTesting();
+ VerifyBitmap(decodes[i].bitmap, expected_color[i]);
+ }
+}
+
TEST_F(BitmapImageTest, APNGDecoder00) {
LoadImage("/images/resources/apng00.png");
auto actual_bitmap = GenerateBitmap(0u);
@@ -716,4 +773,22 @@ INSTANTIATE_TEST_CASE_P(
DecodedImageOrientationHistogramTest,
testing::ValuesIn(kDecodedImageOrientationHistogramTestParams));
+using DecodedImageDensityHistogramTest = BitmapHistogramTest<int>;
+
+TEST_P(DecodedImageDensityHistogramTest, ImageOrientation) {
+ RunTest("Blink.DecodedImage.JpegDensity");
+}
+
+const DecodedImageDensityHistogramTest::ParamType
+ kDecodedImageDensityHistogramTestParams[] = {
+ // 439x154, 23220 bytes --> 2.74 bpp
+ {"/images/resources/cropped_mandrill.jpg", 274},
+ // 320x320, 74017 bytes --> 5.78
+ {"/images/resources/blue-wheel-srgb-color-profile.jpg", 578}};
+
+INSTANTIATE_TEST_CASE_P(
+ DecodedImageDensityHistogramTest,
+ DecodedImageDensityHistogramTest,
+ testing::ValuesIn(kDecodedImageDensityHistogramTestParams));
+
} // 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 678a5ed2f72..9603c55a8b3 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
@@ -246,7 +246,8 @@ void Canvas2DLayerBridge::Hibernate() {
snapshot->PaintImageForCurrentFrame().GetSkImage(), 0, 0, &copy_paint);
hibernation_image_ = temp_hibernation_surface->makeImageSnapshot();
ResetResourceProvider();
- layer_->ClearTexture();
+ if (layer_)
+ layer_->ClearTexture();
// shouldBeDirectComposited() may have changed.
if (resource_host_)
@@ -280,10 +281,17 @@ CanvasResourceProvider* Canvas2DLayerBridge::GetOrCreateResourceProvider(
}
if (resource_provider && resource_provider->IsValid()) {
+#if DCHECK_IS_ON()
// If resource provider is accelerated, a layer should already exist.
- // If not, it could mean that the resource provider was create without
- // going through this method, which is bad.
- DCHECK(!IsAccelerated() || !!layer_);
+ // unless this is a canvas in low latency mode.
+ // If this DCHECK fails, it probably means that
+ // CanvasRenderingContextHost::GetOrCreateCanvasResourceProvider() was
+ // called on a 2D context before this function.
+ if (IsAccelerated()) {
+ DCHECK(!!layer_ ||
+ (resource_host_ && resource_host_->LowLatencyEnabled()));
+ }
+#endif
return resource_provider;
}
@@ -301,8 +309,10 @@ CanvasResourceProvider* Canvas2DLayerBridge::GetOrCreateResourceProvider(
AccelerationHint adjusted_hint =
want_acceleration ? kPreferAcceleration : kPreferNoAcceleration;
+ // We call Impl directly here, to allow HTMLCanvasElement to call us
+ // in GetOrCreateCanvasResourceProvider.
resource_provider =
- resource_host_->GetOrCreateCanvasResourceProvider(adjusted_hint);
+ resource_host_->GetOrCreateCanvasResourceProviderImpl(adjusted_hint);
if (!resource_provider)
ReportResourceProviderCreationFailure();
@@ -558,7 +568,8 @@ bool Canvas2DLayerBridge::Restore() {
if (shared_gl && shared_gl->GetGraphicsResetStatusKHR() == GL_NO_ERROR) {
CanvasResourceProvider* resource_provider =
- resource_host_->GetOrCreateCanvasResourceProvider(kPreferAcceleration);
+ resource_host_->GetOrCreateCanvasResourceProviderImpl(
+ kPreferAcceleration);
if (!resource_provider)
ReportResourceProviderCreationFailure();
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 a22973eb878..60263c7a607 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
@@ -164,6 +164,7 @@ class PLATFORM_EXPORT Canvas2DLayerBridge : public cc::TextureLayerClient {
CanvasResourceProvider* GetOrCreateResourceProvider(
AccelerationHint = kPreferAcceleration);
CanvasResourceProvider* ResourceProvider() const;
+ void FlushRecording();
private:
bool IsHidden() { return is_hidden_; }
@@ -172,7 +173,6 @@ class PLATFORM_EXPORT Canvas2DLayerBridge : public cc::TextureLayerClient {
void StartRecording();
void SkipQueuedDrawCommands();
- void FlushRecording();
void ReportResourceProviderCreationFailure();
bool ShouldAccelerate(AccelerationHint) const;
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 829faff22c6..16924424534 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
@@ -9,6 +9,7 @@
#include "components/viz/common/quads/compositor_frame.h"
#include "components/viz/common/quads/texture_draw_quad.h"
#include "components/viz/common/resources/resource_format.h"
+#include "components/viz/common/resources/single_release_callback.h"
#include "third_party/blink/public/platform/interface_provider.h"
#include "third_party/blink/public/platform/modules/frame_sinks/embedded_frame_sink.mojom-blink.h"
#include "third_party/blink/public/platform/platform.h"
@@ -28,6 +29,21 @@ enum {
kMaxUnreclaimedPlaceholderFrames = 3,
};
+struct CanvasResourceDispatcher::FrameResource {
+ FrameResource() = default;
+ ~FrameResource() {
+ if (release_callback)
+ release_callback->Run(sync_token, is_lost);
+ }
+
+ // TODO(junov): What does this do?
+ bool spare_lock = true;
+
+ std::unique_ptr<viz::SingleReleaseCallback> release_callback;
+ gpu::SyncToken sync_token;
+ bool is_lost = false;
+};
+
CanvasResourceDispatcher::CanvasResourceDispatcher(
CanvasResourceDispatcherClient* client,
uint32_t client_id,
@@ -43,22 +59,20 @@ CanvasResourceDispatcher::CanvasResourceDispatcher(
num_unreclaimed_frames_posted_(0),
client_(client),
weak_ptr_factory_(this) {
- if (frame_sink_id_.is_valid()) {
- // Only frameless canvas pass an invalid frame sink id; we don't create
- // mojo channel for this special case.
- DCHECK(!sink_.is_bound());
- mojom::blink::EmbeddedFrameSinkProviderPtr provider;
- Platform::Current()->GetInterfaceProvider()->GetInterface(
- mojo::MakeRequest(&provider));
- DCHECK(provider);
-
- binding_.Bind(mojo::MakeRequest(&client_ptr_));
- provider->CreateCompositorFrameSink(frame_sink_id_, std::move(client_ptr_),
- mojo::MakeRequest(&sink_));
- }
- offscreen_canvas_resource_provider_ =
- std::make_unique<OffscreenCanvasResourceProvider>(size_.Width(),
- size_.Height(), this);
+ // Frameless canvas pass an invalid |frame_sink_id_|; don't create mojo
+ // channel for this special case.
+ if (!frame_sink_id_.is_valid())
+ return;
+
+ DCHECK(!sink_.is_bound());
+ mojom::blink::EmbeddedFrameSinkProviderPtr provider;
+ Platform::Current()->GetInterfaceProvider()->GetInterface(
+ mojo::MakeRequest(&provider));
+ DCHECK(provider);
+
+ binding_.Bind(mojo::MakeRequest(&client_ptr_));
+ provider->CreateCompositorFrameSink(frame_sink_id_, std::move(client_ptr_),
+ mojo::MakeRequest(&sink_));
}
CanvasResourceDispatcher::~CanvasResourceDispatcher() = default;
@@ -69,76 +83,74 @@ void UpdatePlaceholderImage(
base::WeakPtr<CanvasResourceDispatcher> dispatcher,
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
int placeholder_canvas_id,
- scoped_refptr<blink::CanvasResource> image,
+ scoped_refptr<blink::CanvasResource> canvas_resource,
viz::ResourceId resource_id) {
DCHECK(IsMainThread());
OffscreenCanvasPlaceholder* placeholder_canvas =
OffscreenCanvasPlaceholder::GetPlaceholderById(placeholder_canvas_id);
if (placeholder_canvas) {
placeholder_canvas->SetPlaceholderFrame(
- std::move(image), std::move(dispatcher), std::move(task_runner),
- resource_id);
+ std::move(canvas_resource), std::move(dispatcher),
+ std::move(task_runner), resource_id);
}
}
} // namespace
void CanvasResourceDispatcher::PostImageToPlaceholderIfNotBlocked(
- scoped_refptr<CanvasResource> image,
+ scoped_refptr<CanvasResource> canvas_resource,
viz::ResourceId resource_id) {
if (placeholder_canvas_id_ == kInvalidPlaceholderCanvasId) {
- offscreen_canvas_resource_provider_->ReclaimResource(resource_id);
+ ReclaimResourceInternal(resource_id);
return;
}
- // Determines whether the main thread may be blocked. If unblocked, post the
- // image. Otherwise, save the image and do not post it.
+ // Determines whether the main thread may be blocked. If unblocked, post
+ // |canvas_resource|. Otherwise, save it but do not post it.
if (num_unreclaimed_frames_posted_ < kMaxUnreclaimedPlaceholderFrames) {
- this->PostImageToPlaceholder(std::move(image), resource_id);
+ this->PostImageToPlaceholder(std::move(canvas_resource), resource_id);
num_unreclaimed_frames_posted_++;
} else {
DCHECK(num_unreclaimed_frames_posted_ == kMaxUnreclaimedPlaceholderFrames);
if (latest_unposted_image_) {
- // The previous unposted image becomes obsolete now.
- offscreen_canvas_resource_provider_->ReclaimResource(
- latest_unposted_resource_id_);
+ // The previous unposted resource becomes obsolete now.
+ ReclaimResourceInternal(latest_unposted_resource_id_);
}
- latest_unposted_image_ = std::move(image);
+ latest_unposted_image_ = std::move(canvas_resource);
latest_unposted_resource_id_ = resource_id;
}
}
void CanvasResourceDispatcher::PostImageToPlaceholder(
- scoped_refptr<CanvasResource> image,
+ scoped_refptr<CanvasResource> canvas_resource,
viz::ResourceId resource_id) {
scoped_refptr<base::SingleThreadTaskRunner> dispatcher_task_runner =
Platform::Current()->CurrentThread()->GetTaskRunner();
- // After this point, |image| can only be used on the main thread, until it
- // is returned.
- image->Transfer();
+ // After this point, |canvas_resource| can only be used on the main thread,
+ // until it is returned.
+ canvas_resource->Transfer();
PostCrossThreadTask(
*Platform::Current()->MainThread()->Scheduler()->CompositorTaskRunner(),
FROM_HERE,
CrossThreadBind(UpdatePlaceholderImage, this->GetWeakPtr(),
WTF::Passed(std::move(dispatcher_task_runner)),
- placeholder_canvas_id_, std::move(image), resource_id));
+ placeholder_canvas_id_, std::move(canvas_resource),
+ resource_id));
}
void CanvasResourceDispatcher::DispatchFrameSync(
- scoped_refptr<StaticBitmapImage> image,
+ scoped_refptr<CanvasResource> canvas_resource,
base::TimeTicks commit_start_time,
- const SkIRect& damage_rect) {
- scoped_refptr<CanvasResource> canvas_resource = CanvasResourceBitmap::Create(
- std::move(image),
- nullptr, // Resource provider not specified -> recycling will not work
- kLow_SkFilterQuality, CanvasColorParams());
-
+ const SkIRect& damage_rect,
+ bool needs_vertical_flip) {
+ TRACE_EVENT0("blink", "CanvasResourceDispatcher::DispatchFrameSync");
viz::CompositorFrame frame;
if (!PrepareFrame(std::move(canvas_resource), commit_start_time, damage_rect,
- &frame))
+ needs_vertical_flip, &frame)) {
return;
+ }
pending_compositor_frames_++;
WTF::Vector<viz::ReturnedResource> resources;
@@ -149,18 +161,16 @@ void CanvasResourceDispatcher::DispatchFrameSync(
}
void CanvasResourceDispatcher::DispatchFrame(
- scoped_refptr<StaticBitmapImage> image,
+ scoped_refptr<CanvasResource> canvas_resource,
base::TimeTicks commit_start_time,
- const SkIRect& damage_rect) {
- scoped_refptr<CanvasResource> canvas_resource = CanvasResourceBitmap::Create(
- std::move(image),
- nullptr, // Resource provider not specified -> recycling will not work
- kLow_SkFilterQuality, CanvasColorParams());
-
+ const SkIRect& damage_rect,
+ bool needs_vertical_flip) {
+ TRACE_EVENT0("blink", "CanvasResourceDispatcher::DispatchFrame");
viz::CompositorFrame frame;
if (!PrepareFrame(std::move(canvas_resource), commit_start_time, damage_rect,
- &frame))
+ needs_vertical_flip, &frame)) {
return;
+ }
pending_compositor_frames_++;
sink_->SubmitCompositorFrame(
@@ -172,17 +182,18 @@ bool CanvasResourceDispatcher::PrepareFrame(
scoped_refptr<CanvasResource> canvas_resource,
base::TimeTicks commit_start_time,
const SkIRect& damage_rect,
+ bool needs_vertical_flip,
viz::CompositorFrame* frame) {
+ TRACE_EVENT0("blink", "CanvasResourceDispatcher::PrepareFrame");
if (!canvas_resource || !VerifyImageSize(canvas_resource->Size()))
return false;
- offscreen_canvas_resource_provider_->IncNextResourceId();
+ next_resource_id_++;
// For frameless canvas, we don't get a valid frame_sink_id and should drop.
if (!frame_sink_id_.is_valid()) {
- PostImageToPlaceholderIfNotBlocked(
- std::move(canvas_resource),
- offscreen_canvas_resource_provider_->GetNextResourceId());
+ PostImageToPlaceholderIfNotBlocked(std::move(canvas_resource),
+ next_resource_id_);
return false;
}
@@ -213,9 +224,6 @@ bool CanvasResourceDispatcher::PrepareFrame(
sqs->SetAll(gfx::Transform(), bounds, bounds, bounds, is_clipped,
are_contents_opaque, 1.f, SkBlendMode::kSrcOver, 0);
- viz::TransferableResource resource;
-
- bool yflipped = false;
OffscreenCanvasCommitType commit_type;
DEFINE_THREAD_SAFE_STATIC_LOCAL(
EnumerationHistogram, commit_type_histogram,
@@ -229,49 +237,41 @@ bool CanvasResourceDispatcher::PrepareFrame(
if (SharedGpuContext::IsGpuCompositingEnabled()) {
// Case 1: both canvas and compositor are gpu accelerated.
commit_type = kCommitGPUCanvasGPUCompositing;
- offscreen_canvas_resource_provider_
- ->SetTransferableResourceToStaticBitmapImage(&resource,
- canvas_resource);
- yflipped = true;
} else {
// Case 2: canvas is accelerated but gpu compositing is disabled.
commit_type = kCommitGPUCanvasSoftwareCompositing;
- offscreen_canvas_resource_provider_
- ->SetTransferableResourceToSharedBitmap(resource,
- canvas_resource->Bitmap());
}
} else {
if (SharedGpuContext::IsGpuCompositingEnabled()) {
// Case 3: canvas is not gpu-accelerated, but compositor is.
commit_type = kCommitSoftwareCanvasGPUCompositing;
- scoped_refptr<CanvasResource> accelerated_resource =
- canvas_resource->MakeAccelerated(
- SharedGpuContext::ContextProviderWrapper());
- if (!accelerated_resource)
- return false;
- offscreen_canvas_resource_provider_
- ->SetTransferableResourceToStaticBitmapImage(&resource,
- accelerated_resource);
} else {
// Case 4: both canvas and compositor are not gpu accelerated.
commit_type = kCommitSoftwareCanvasSoftwareCompositing;
- offscreen_canvas_resource_provider_
- ->SetTransferableResourceToSharedBitmap(resource,
- canvas_resource->Bitmap());
}
}
+ viz::TransferableResource resource;
+ auto frame_resource = std::make_unique<FrameResource>();
+
+ canvas_resource->PrepareTransferableResource(
+ &resource, &frame_resource->release_callback, kVerifiedSyncToken);
+ resource.id = next_resource_id_;
+
+ resources_.insert(next_resource_id_, std::move(frame_resource));
+
+ // TODO(crbug.com/869913): add unit testing for this.
+ const gfx::Size canvas_resource_size(canvas_resource->Size());
+
commit_type_histogram.Count(commit_type);
- PostImageToPlaceholderIfNotBlocked(
- std::move(canvas_resource),
- offscreen_canvas_resource_provider_->GetNextResourceId());
+ PostImageToPlaceholderIfNotBlocked(std::move(canvas_resource),
+ next_resource_id_);
frame->resource_list.push_back(std::move(resource));
viz::TextureDrawQuad* quad =
pass->CreateAndAppendDrawQuad<viz::TextureDrawQuad>();
- gfx::Size rect_size(size_.Width(), size_.Height());
// TODO(crbug.com/705019): optimize for contexts that have {alpha: false}
const bool kNeedsBlending = true;
@@ -281,16 +281,21 @@ bool CanvasResourceDispatcher::PrepareFrame(
const bool kPremultipliedAlpha = true;
const gfx::PointF uv_top_left(0.f, 0.f);
const gfx::PointF uv_bottom_right(1.f, 1.f);
- float vertex_opacity[4] = {1.f, 1.f, 1.f, 1.f};
+ const float vertex_opacity[4] = {1.f, 1.f, 1.f, 1.f};
// TODO(crbug.com/645994): this should be true when using style
// "image-rendering: pixelated".
// TODO(crbug.com/645590): filter should respect the image-rendering CSS
// property of associated canvas element.
const bool kNearestNeighbor = false;
- quad->SetAll(sqs, bounds, bounds, kNeedsBlending, resource.id, gfx::Size(),
- kPremultipliedAlpha, uv_top_left, uv_bottom_right,
- SK_ColorTRANSPARENT, vertex_opacity, yflipped, kNearestNeighbor,
- false);
+ // Accelerated resources have the origin of coordinates in the upper left
+ // corner while canvases have it in the lower left corner. The DrawQuad is
+ // marked as vertically flipped unless someone else has done the flip for us.
+ const bool yflipped =
+ SharedGpuContext::IsGpuCompositingEnabled() && needs_vertical_flip;
+ quad->SetAll(sqs, bounds, bounds, kNeedsBlending, resource.id,
+ canvas_resource_size, kPremultipliedAlpha, uv_top_left,
+ uv_bottom_right, SK_ColorTRANSPARENT, vertex_opacity, yflipped,
+ kNearestNeighbor, false);
frame->render_pass_list.push_back(std::move(pass));
@@ -418,9 +423,8 @@ void CanvasResourceDispatcher::SetSuspendAnimation(bool suspend_animation) {
}
void CanvasResourceDispatcher::SetNeedsBeginFrameInternal() {
- if (sink_) {
+ if (sink_)
sink_->SetNeedsBeginFrame(needs_begin_frame_ && !suspend_animation_);
- }
}
void CanvasResourceDispatcher::OnBeginFrame(
@@ -435,18 +439,29 @@ void CanvasResourceDispatcher::OnBeginFrame(
if (Client())
Client()->BeginFrame();
- // TODO(eseckler): Tell |m_sink| if we did not draw during the BeginFrame.
+ // TODO(eseckler): Tell |sink_| if we did not draw during the BeginFrame.
current_begin_frame_ack_.sequence_number =
viz::BeginFrameArgs::kInvalidFrameNumber;
}
void CanvasResourceDispatcher::ReclaimResources(
const WTF::Vector<viz::ReturnedResource>& resources) {
- offscreen_canvas_resource_provider_->ReclaimResources(resources);
+ for (const auto& resource : resources) {
+ auto it = resources_.find(resource.id);
+
+ DCHECK(it != resources_.end());
+ if (it == resources_.end())
+ continue;
+
+ it->value->sync_token = resource.sync_token;
+ it->value->is_lost = resource.lost;
+ ReclaimResourceInternal(it);
+ }
}
void CanvasResourceDispatcher::ReclaimResource(viz::ResourceId resource_id) {
- offscreen_canvas_resource_provider_->ReclaimResource(resource_id);
+ ReclaimResourceInternal(resource_id);
+
num_unreclaimed_frames_posted_--;
// The main thread has become unblocked recently and we have an image that
@@ -461,15 +476,12 @@ void CanvasResourceDispatcher::ReclaimResource(viz::ResourceId resource_id) {
}
bool CanvasResourceDispatcher::VerifyImageSize(const IntSize image_size) {
- if (image_size == size_)
- return true;
- return false;
+ return image_size == size_;
}
void CanvasResourceDispatcher::Reshape(const IntSize& size) {
if (size_ != size) {
size_ = size;
- offscreen_canvas_resource_provider_->Reshape(size_.Width(), size_.Height());
change_size_for_next_commit_ = true;
}
}
@@ -477,12 +489,30 @@ void CanvasResourceDispatcher::Reshape(const IntSize& size) {
void CanvasResourceDispatcher::DidAllocateSharedBitmap(
mojo::ScopedSharedBufferHandle buffer,
::gpu::mojom::blink::MailboxPtr id) {
- sink_->DidAllocateSharedBitmap(std::move(buffer), std::move(id));
+ if (sink_)
+ sink_->DidAllocateSharedBitmap(std::move(buffer), std::move(id));
}
void CanvasResourceDispatcher::DidDeleteSharedBitmap(
::gpu::mojom::blink::MailboxPtr id) {
- sink_->DidDeleteSharedBitmap(std::move(id));
+ if (sink_)
+ sink_->DidDeleteSharedBitmap(std::move(id));
+}
+
+void CanvasResourceDispatcher::ReclaimResourceInternal(
+ viz::ResourceId resource_id) {
+ auto it = resources_.find(resource_id);
+ if (it != resources_.end())
+ ReclaimResourceInternal(it);
+}
+
+void CanvasResourceDispatcher::ReclaimResourceInternal(
+ const ResourceMap::iterator& it) {
+ if (it->value->spare_lock) {
+ it->value->spare_lock = false;
+ return;
+ }
+ resources_.erase(it);
}
} // namespace blink
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 d2afb6a9098..7ecb4ecb117 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
@@ -11,7 +11,6 @@
#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "services/viz/public/interfaces/compositing/compositor_frame_sink.mojom-blink.h"
-#include "third_party/blink/renderer/platform/graphics/offscreen_canvas_resource_provider.h"
#include "third_party/blink/renderer/platform/wtf/compiler.h"
namespace blink {
@@ -47,13 +46,15 @@ class PLATFORM_EXPORT CanvasResourceDispatcher
void SetSuspendAnimation(bool);
bool NeedsBeginFrame() const { return needs_begin_frame_; }
bool IsAnimationSuspended() const { return suspend_animation_; }
- void DispatchFrame(scoped_refptr<StaticBitmapImage>,
+ void DispatchFrame(scoped_refptr<CanvasResource>,
base::TimeTicks commit_start_time,
- const SkIRect& damage_rect);
+ const SkIRect& damage_rect,
+ bool needs_vertical_flip);
void ReclaimResource(viz::ResourceId);
- void DispatchFrameSync(scoped_refptr<StaticBitmapImage>,
+ void DispatchFrameSync(scoped_refptr<CanvasResource>,
base::TimeTicks commit_start_time,
- const SkIRect& damage_rect);
+ const SkIRect& damage_rect,
+ bool needs_vertical_flip);
void Reshape(const IntSize&);
@@ -79,15 +80,17 @@ class PLATFORM_EXPORT CanvasResourceDispatcher
kCommitSoftwareCanvasGPUCompositing = 2,
kCommitSoftwareCanvasSoftwareCompositing = 3,
kOffscreenCanvasCommitTypeCount,
-
};
private:
friend class CanvasResourceDispatcherTest;
+ struct FrameResource;
+ using ResourceMap = HashMap<unsigned, std::unique_ptr<FrameResource>>;
bool PrepareFrame(scoped_refptr<CanvasResource>,
base::TimeTicks commit_start_time,
const SkIRect& damage_rect,
+ bool needs_vertical_flip,
viz::CompositorFrame* frame);
// Surface-related
@@ -109,12 +112,18 @@ class PLATFORM_EXPORT CanvasResourceDispatcher
virtual void PostImageToPlaceholder(scoped_refptr<CanvasResource>,
viz::ResourceId resource_id);
+ void ReclaimResourceInternal(viz::ResourceId resource_id);
+ void ReclaimResourceInternal(const ResourceMap::iterator&);
+
viz::mojom::blink::CompositorFrameSinkPtr sink_;
mojo::Binding<viz::mojom::blink::CompositorFrameSinkClient> binding_;
viz::mojom::blink::CompositorFrameSinkClientPtr client_ptr_;
int placeholder_canvas_id_;
+ unsigned next_resource_id_ = 0;
+ ResourceMap resources_;
+
// The latest_unposted_resource_id_ always refers to the Id of the frame
// resource used by the latest_unposted_image_.
scoped_refptr<CanvasResource> latest_unposted_image_;
@@ -125,9 +134,6 @@ class PLATFORM_EXPORT CanvasResourceDispatcher
CanvasResourceDispatcherClient* client_;
- std::unique_ptr<OffscreenCanvasResourceProvider>
- offscreen_canvas_resource_provider_;
-
base::WeakPtrFactory<CanvasResourceDispatcher> weak_ptr_factory_;
};
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 99f178d6d28..239e25f23c6 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
@@ -27,8 +27,11 @@ class PLATFORM_EXPORT CanvasResourceHost {
virtual void UpdateMemoryUsage() = 0;
virtual CanvasResourceProvider* GetOrCreateCanvasResourceProvider(
AccelerationHint hint) = 0;
+ virtual CanvasResourceProvider* GetOrCreateCanvasResourceProviderImpl(
+ AccelerationHint hint) = 0;
virtual SkFilterQuality FilterQuality() const = 0;
+ virtual bool LowLatencyEnabled() const { return false; }
CanvasResourceProvider* ResourceProvider() const;
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 7f8abac90a5..ebb0addee34 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
@@ -41,12 +41,14 @@ class CanvasResourceProviderTexture : public CanvasResourceProvider {
const CanvasColorParams color_params,
base::WeakPtr<WebGraphicsContext3DProviderWrapper>
context_provider_wrapper,
- base::WeakPtr<CanvasResourceDispatcher> resource_dispatcher)
+ base::WeakPtr<CanvasResourceDispatcher> resource_dispatcher,
+ bool is_origin_top_left)
: CanvasResourceProvider(size,
color_params,
std::move(context_provider_wrapper),
std::move(resource_dispatcher)),
- msaa_sample_count_(msaa_sample_count) {}
+ msaa_sample_count_(msaa_sample_count),
+ is_origin_top_left_(is_origin_top_left) {}
~CanvasResourceProviderTexture() override = default;
@@ -116,15 +118,21 @@ class CanvasResourceProviderTexture : public CanvasResourceProvider {
auto* gr = GetGrContext();
DCHECK(gr);
- SkImageInfo info = SkImageInfo::Make(
+ const SkImageInfo info = SkImageInfo::Make(
Size().Width(), Size().Height(), ColorParams().GetSkColorType(),
kPremul_SkAlphaType, ColorParams().GetSkColorSpaceForSkSurfaces());
+
+ const enum GrSurfaceOrigin surface_origin =
+ is_origin_top_left_ ? kTopLeft_GrSurfaceOrigin
+ : kBottomLeft_GrSurfaceOrigin;
+
return SkSurface::MakeRenderTarget(gr, SkBudgeted::kNo, info,
- msaa_sample_count_,
+ msaa_sample_count_, surface_origin,
ColorParams().GetSkSurfaceProps());
}
const unsigned msaa_sample_count_;
+ const bool is_origin_top_left_;
};
// CanvasResourceProviderTextureGpuMemoryBuffer
@@ -143,15 +151,18 @@ class CanvasResourceProviderTextureGpuMemoryBuffer final
const CanvasColorParams color_params,
base::WeakPtr<WebGraphicsContext3DProviderWrapper>
context_provider_wrapper,
- base::WeakPtr<CanvasResourceDispatcher> resource_dispatcher)
+ base::WeakPtr<CanvasResourceDispatcher> resource_dispatcher,
+ bool is_origin_top_left)
: CanvasResourceProviderTexture(size,
msaa_sample_count,
color_params,
std::move(context_provider_wrapper),
- std::move(resource_dispatcher)) {}
+ std::move(resource_dispatcher),
+ is_origin_top_left) {}
~CanvasResourceProviderTextureGpuMemoryBuffer() override = default;
bool SupportsDirectCompositing() const override { return true; }
+ bool SupportsSingleBuffering() const override { return true; }
private:
scoped_refptr<CanvasResource> CreateResource() final {
@@ -264,6 +275,7 @@ class CanvasResourceProviderRamGpuMemoryBuffer final
~CanvasResourceProviderRamGpuMemoryBuffer() override = default;
bool SupportsDirectCompositing() const override { return true; }
+ bool SupportsSingleBuffering() const override { return true; }
private:
scoped_refptr<CanvasResource> CreateResource() final {
@@ -319,6 +331,7 @@ class CanvasResourceProviderSharedBitmap : public CanvasResourceProviderBitmap {
}
~CanvasResourceProviderSharedBitmap() override = default;
bool SupportsDirectCompositing() const override { return true; }
+ bool SupportsSingleBuffering() const override { return true; }
private:
scoped_refptr<CanvasResource> CreateResource() final {
@@ -394,7 +407,8 @@ std::unique_ptr<CanvasResourceProvider> CanvasResourceProvider::Create(
unsigned msaa_sample_count,
const CanvasColorParams& color_params,
PresentationMode presentation_mode,
- base::WeakPtr<CanvasResourceDispatcher> resource_dispatcher) {
+ base::WeakPtr<CanvasResourceDispatcher> resource_dispatcher,
+ bool is_origin_top_left) {
const ResourceType* resource_type_fallback_list = nullptr;
size_t list_length = 0;
@@ -447,7 +461,7 @@ std::unique_ptr<CanvasResourceProvider> CanvasResourceProvider::Create(
provider =
std::make_unique<CanvasResourceProviderTextureGpuMemoryBuffer>(
size, msaa_sample_count, color_params, context_provider_wrapper,
- resource_dispatcher);
+ resource_dispatcher, is_origin_top_left);
break;
case kRamGpuMemoryBufferResourceType:
if (!SharedGpuContext::IsGpuCompositingEnabled())
@@ -476,7 +490,7 @@ std::unique_ptr<CanvasResourceProvider> CanvasResourceProvider::Create(
continue;
provider = std::make_unique<CanvasResourceProviderTexture>(
size, msaa_sample_count, color_params, context_provider_wrapper,
- resource_dispatcher);
+ resource_dispatcher, is_origin_top_left);
break;
case kBitmapResourceType:
provider = std::make_unique<CanvasResourceProviderBitmap>(
@@ -530,15 +544,21 @@ void CanvasResourceProvider::CanvasImageProvider::ReleaseLockedImages() {
void CanvasResourceProvider::CanvasImageProvider::CanUnlockImage(
ScopedDecodedDrawImage image) {
- if (locked_images_.empty()) {
+ if (!cleanup_task_pending_) {
+ cleanup_task_pending_ = true;
Platform::Current()->CurrentThread()->GetTaskRunner()->PostTask(
- FROM_HERE, base::BindOnce(&CanvasImageProvider::ReleaseLockedImages,
+ FROM_HERE, base::BindOnce(&CanvasImageProvider::CleanupLockedImages,
weak_factory_.GetWeakPtr()));
}
locked_images_.push_back(std::move(image));
}
+void CanvasResourceProvider::CanvasImageProvider::CleanupLockedImages() {
+ cleanup_task_pending_ = false;
+ ReleaseLockedImages();
+}
+
CanvasResourceProvider::CanvasResourceProvider(
const IntSize& size,
const CanvasColorParams& color_params,
@@ -699,6 +719,7 @@ void CanvasResourceProvider::InvalidateSurface() {
canvas_image_provider_.reset();
xform_canvas_ = nullptr;
surface_ = nullptr;
+ single_buffer_ = nullptr;
}
uint32_t CanvasResourceProvider::ContentUniqueID() const {
@@ -736,6 +757,11 @@ void CanvasResourceProvider::ClearRecycledResources() {
}
scoped_refptr<CanvasResource> CanvasResourceProvider::NewOrRecycledResource() {
+ if (IsSingleBuffered()) {
+ if (!single_buffer_)
+ single_buffer_ = CreateResource();
+ return single_buffer_;
+ }
if (recycled_resources_.size()) {
scoped_refptr<CanvasResource> resource =
std::move(recycled_resources_.back());
@@ -745,4 +771,11 @@ scoped_refptr<CanvasResource> CanvasResourceProvider::NewOrRecycledResource() {
return CreateResource();
}
+void CanvasResourceProvider::TryEnableSingleBuffering() {
+ if (IsSingleBuffered() || !SupportsSingleBuffering())
+ return;
+ SetResourceRecyclingEnabled(false);
+ is_single_buffered_ = true;
+}
+
} // 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 2e0197b412f..0995007575d 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
@@ -80,7 +80,8 @@ class PLATFORM_EXPORT CanvasResourceProvider
unsigned msaa_sample_count,
const CanvasColorParams&,
PresentationMode,
- base::WeakPtr<CanvasResourceDispatcher>);
+ base::WeakPtr<CanvasResourceDispatcher>,
+ bool is_origin_top_left = true);
// Use this method for capturing a frame that is intended to be displayed via
// the compositor. Cases that need to acquire a snaptshot that is not destined
@@ -100,11 +101,26 @@ class PLATFORM_EXPORT CanvasResourceProvider
virtual bool IsValid() const = 0;
virtual bool IsAccelerated() const = 0;
virtual bool SupportsDirectCompositing() const = 0;
+ virtual bool SupportsSingleBuffering() const { return false; }
uint32_t ContentUniqueID() const;
CanvasResourceDispatcher* ResourceDispatcher() {
return resource_dispatcher_.get();
}
+ // Indicates that the compositing path is single buffered, meaning that
+ // ProduceFrame() return a reference to the same resource each time, which
+ // implies that Producing an animation frame may overwrite the resource used
+ // by the previous frame. This results in graphics updates skipping the
+ // queue, thus reducing latency, but with the possible side effects of
+ // tearring (in cases where the resource is scanned out directly) and
+ // irregular frame rate.
+ bool IsSingleBuffered() { return is_single_buffered_; }
+
+ // Attempt to enable single buffering mode on this resource provider. May
+ // fail if the CanvasResourcePRovider subclass does not support this mode of
+ // operation.
+ void TryEnableSingleBuffering();
+
void RecycleResource(scoped_refptr<CanvasResource>);
void SetResourceRecyclingEnabled(bool);
void ClearRecycledResources();
@@ -169,7 +185,9 @@ class PLATFORM_EXPORT CanvasResourceProvider
private:
void CanUnlockImage(ScopedDecodedDrawImage);
+ void CleanupLockedImages();
+ bool cleanup_task_pending_ = false;
std::vector<ScopedDecodedDrawImage> locked_images_;
cc::PlaybackImageProvider playback_image_provider_;
@@ -188,7 +206,7 @@ class PLATFORM_EXPORT CanvasResourceProvider
std::unique_ptr<cc::SkiaPaintCanvas> canvas_;
mutable sk_sp<SkSurface> surface_; // mutable for lazy init
std::unique_ptr<SkCanvas> xform_canvas_;
- SkFilterQuality filter_quality_;
+ SkFilterQuality filter_quality_ = kLow_SkFilterQuality;
const cc::PaintImage::Id snapshot_paint_image_id_;
cc::PaintImage::ContentId snapshot_paint_image_content_id_ =
@@ -198,6 +216,9 @@ class PLATFORM_EXPORT CanvasResourceProvider
WTF::Vector<scoped_refptr<CanvasResource>> recycled_resources_;
bool resource_recycling_enabled_ = true;
+ bool is_single_buffered_ = false;
+ scoped_refptr<CanvasResource> single_buffer_;
+
base::WeakPtrFactory<CanvasResourceProvider> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(CanvasResourceProvider);
diff --git a/chromium/third_party/blink/renderer/platform/graphics/color_blend.h b/chromium/third_party/blink/renderer/platform/graphics/color_blend.h
index dc03dea5d42..a31cb72a79e 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/color_blend.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/color_blend.h
@@ -26,7 +26,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_COLOR_BLEND_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_COLOR_BLEND_H_
-#include "third_party/blink/renderer/platform/animation/animation_utilities.h"
+#include "third_party/blink/renderer/platform/geometry/blend.h"
#include "third_party/blink/renderer/platform/graphics/color.h"
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 7d8fccdbb83..7c55b077844 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
@@ -84,7 +84,9 @@ void PaintArtifactCompositor::RemoveChildLayers() {
if (!host)
return;
for (auto child : root_layer_->children()) {
- host->UnregisterElement(child->element_id(), cc::ElementListType::ACTIVE);
+ auto element_id = child->element_id();
+ if (element_id)
+ host->UnregisterElement(element_id, cc::ElementListType::ACTIVE);
}
root_layer_->RemoveAllChildren();
if (extra_data_for_testing_enabled_) {
@@ -545,14 +547,14 @@ void PaintArtifactCompositor::LayerizeGroup(
: subgroup_layer.property_tree_state.Clip(),
&current_group));
}
- // At this point pendingLayers.back() is the either a layer from a
+ // At this point pending_layers.back() is the either a layer from a
// "decomposited" subgroup or a layer created from a chunk we just
// processed. Now determine whether it could be merged into a previous
// layer.
const PendingLayer& new_layer = pending_layers.back();
DCHECK(!new_layer.requires_own_layer);
DCHECK_EQ(&current_group, new_layer.property_tree_state.Effect());
- // This iterates pendingLayers[firstLayerInCurrentGroup:-1] in reverse.
+ // This iterates pending_layers[first_layer_in_current_group:-1] in reverse.
for (size_t candidate_index = pending_layers.size() - 1;
candidate_index-- > first_layer_in_current_group;) {
PendingLayer& candidate_layer = pending_layers[candidate_index];
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 b2d0209c85e..2ac29aa32ae 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
@@ -105,6 +105,10 @@ void PropertyTreeManager::SetupRootClipNode() {
DCHECK_EQ(clip_node.id, kSecondaryRootNodeId);
clip_node.clip_type = cc::ClipNode::ClipType::APPLIES_LOCAL_CLIP;
+ // TODO(bokan): This needs to come from the Visual Viewport which will
+ // correctly account for the URL bar. In fact, the visual viewport property
+ // tree builder should probably be the one to create the property tree state
+ // and have this created in the same way as other layers.
clip_node.clip = gfx::RectF(
gfx::SizeF(root_layer_->layer_tree_host()->device_viewport_size()));
clip_node.transform_id = kRealRootNodeId;
@@ -179,6 +183,11 @@ int PropertyTreeManager::EnsureCompositorTransformNode(
transform_node->FlattensInheritedTransform();
compositor_node.sorting_context_id = transform_node->RenderingContextId();
+ if (transform_node->IsAffectedByOuterViewportBoundsDelta()) {
+ compositor_node.moved_by_outer_viewport_bounds_delta_y = true;
+ GetTransformTree().AddNodeAffectedByOuterViewportBoundsDelta(id);
+ }
+
CompositorElementId compositor_element_id =
transform_node->GetCompositorElementId();
if (compositor_element_id) {
@@ -285,6 +294,12 @@ void PropertyTreeManager::CreateCompositorScrollNode(
scroll_node->MaxScrollOffsetAffectedByPageScale();
compositor_node.main_thread_scrolling_reasons =
scroll_node->GetMainThreadScrollingReasons();
+ compositor_node.overscroll_behavior = cc::OverscrollBehavior(
+ static_cast<cc::OverscrollBehavior::OverscrollBehaviorType>(
+ scroll_node->OverscrollBehaviorX()),
+ static_cast<cc::OverscrollBehavior::OverscrollBehaviorType>(
+ scroll_node->OverscrollBehaviorY()));
+ compositor_node.snap_container_data = scroll_node->SnapContainerData();
auto compositor_element_id = scroll_node->GetCompositorElementId();
if (compositor_element_id) {
diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositor_element_id.cc b/chromium/third_party/blink/renderer/platform/graphics/compositor_element_id.cc
index 3d01b478ffa..0a2feefeb6c 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/compositor_element_id.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/compositor_element_id.cc
@@ -35,7 +35,8 @@ CompositorElementId PLATFORM_EXPORT CompositorElementIdFromUniqueObjectId(
namespace_id == CompositorElementIdNamespace::kEffectMask ||
namespace_id == CompositorElementIdNamespace::kEffectClipPath ||
namespace_id == CompositorElementIdNamespace::kVerticalScrollbar ||
- namespace_id == CompositorElementIdNamespace::kHorizontalScrollbar);
+ namespace_id == CompositorElementIdNamespace::kHorizontalScrollbar ||
+ namespace_id == CompositorElementIdNamespace::kOverscrollElasticity);
return CreateCompositorElementId(id, namespace_id);
}
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 34532cac3d4..9357cd018a9 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,6 +25,7 @@ enum class CompositorElementIdNamespace {
kEffectClipPath,
kVerticalScrollbar,
kHorizontalScrollbar,
+ kOverscrollElasticity,
// A sentinel to indicate the maximum representable namespace id
// (the maximum is one less than this value).
kMaxRepresentableNamespaceId = 1 << kCompositorNamespaceBitCount
diff --git a/chromium/third_party/blink/renderer/platform/graphics/decoding_image_generator.cc b/chromium/third_party/blink/renderer/platform/graphics/decoding_image_generator.cc
index 3af4ecede7a..a46a8c156b1 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/decoding_image_generator.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/decoding_image_generator.cc
@@ -69,7 +69,8 @@ DecodingImageGenerator::CreateAsSkImageGenerator(sk_sp<SkData> data) {
std::move(frame), info, std::move(segment_reader), std::move(frames),
PaintImage::GetNextContentId(), true);
return std::make_unique<SkiaPaintImageGenerator>(
- std::move(generator), PaintImage::kDefaultFrameIndex);
+ std::move(generator), PaintImage::kDefaultFrameIndex,
+ PaintImage::kDefaultGeneratorClientId);
}
// static
@@ -115,9 +116,10 @@ bool DecodingImageGenerator::GetPixels(const SkImageInfo& dst_info,
void* pixels,
size_t row_bytes,
size_t frame_index,
+ PaintImage::GeneratorClientId client_id,
uint32_t lazy_pixel_ref) {
- TRACE_EVENT1("blink", "DecodingImageGenerator::getPixels", "frame index",
- static_cast<int>(frame_index));
+ TRACE_EVENT2("blink", "DecodingImageGenerator::getPixels", "frame index",
+ static_cast<int>(frame_index), "client_id", client_id);
// Implementation only supports decoding to a supported size.
if (dst_info.dimensions() != GetSupportedDecodeSize(dst_info.dimensions())) {
@@ -153,7 +155,7 @@ bool DecodingImageGenerator::GetPixels(const SkImageInfo& dst_info,
PlatformInstrumentation::WillDecodeLazyPixelRef(lazy_pixel_ref);
const bool decoded = frame_generator_->DecodeAndScale(
data_.get(), all_data_received_, frame_index, decode_info, pixels,
- row_bytes, alpha_option);
+ row_bytes, alpha_option, client_id);
PlatformInstrumentation::DidDecodeLazyPixelRef();
if (decoded && needs_color_xform) {
diff --git a/chromium/third_party/blink/renderer/platform/graphics/decoding_image_generator.h b/chromium/third_party/blink/renderer/platform/graphics/decoding_image_generator.h
index 3a0b8eedcd7..8e083e0d288 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/decoding_image_generator.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/decoding_image_generator.h
@@ -72,6 +72,7 @@ class PLATFORM_EXPORT DecodingImageGenerator final
void* pixels,
size_t row_bytes,
size_t frame_index,
+ PaintImage::GeneratorClientId client_id,
uint32_t lazy_pixel_ref) override;
bool QueryYUV8(SkYUVSizeInfo*, SkYUVColorSpace*) const override;
bool GetYUV8Planes(const SkYUVSizeInfo&,
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 a65acf537fe..96fb7a44c32 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
@@ -115,15 +115,13 @@ class DeferredImageDecoderTest : public testing::Test,
IntSize DecodedSize() const override { return decoded_size_; }
- PaintImage CreatePaintImageAtIndex(
- size_t index,
+ PaintImage CreatePaintImage(
PaintImage::CompletionState state = PaintImage::CompletionState::DONE) {
- return CreatePaintImageAtIndex(lazy_decoder_.get(), index, state);
+ return CreatePaintImage(lazy_decoder_.get(), state);
}
- PaintImage CreatePaintImageAtIndex(
+ PaintImage CreatePaintImage(
DeferredImageDecoder* decoder,
- size_t index,
PaintImage::CompletionState state = PaintImage::CompletionState::DONE) {
PaintImage::AnimationType type = FrameCount() > 1
? PaintImage::AnimationType::ANIMATED
@@ -133,8 +131,8 @@ class DeferredImageDecoderTest : public testing::Test,
.set_id(paint_image_id_)
.set_animation_type(type)
.set_completion_state(state)
- .set_paint_image_generator(decoder->CreateGenerator(index))
- .set_frame_index(index)
+ .set_paint_image_generator(
+ decoder->CreateGenerator(PaintImage::kDefaultFrameIndex))
.TakePaintImage();
}
@@ -161,7 +159,7 @@ class DeferredImageDecoderTest : public testing::Test,
TEST_F(DeferredImageDecoderTest, drawIntoPaintRecord) {
lazy_decoder_->SetData(data_, true);
- PaintImage image = CreatePaintImageAtIndex(0);
+ PaintImage image = CreatePaintImage();
ASSERT_TRUE(image);
EXPECT_EQ(1, image.width());
EXPECT_EQ(1, image.height());
@@ -186,13 +184,13 @@ TEST_F(DeferredImageDecoderTest, drawIntoPaintRecordProgressive) {
PaintRecorder recorder;
cc::PaintCanvas* temp_canvas = recorder.beginRecording(100, 100);
PaintImage image =
- CreatePaintImageAtIndex(0, PaintImage::CompletionState::PARTIALLY_DONE);
+ CreatePaintImage(PaintImage::CompletionState::PARTIALLY_DONE);
temp_canvas->drawImage(image, 0, 0);
canvas_->drawPicture(recorder.finishRecordingAsPicture());
// Fully received the file and draw the PaintRecord again.
lazy_decoder_->SetData(data_, true);
- image = CreatePaintImageAtIndex(0);
+ image = CreatePaintImage();
ASSERT_TRUE(image);
temp_canvas = recorder.beginRecording(100, 100);
temp_canvas->drawImage(image, 0, 0);
@@ -212,7 +210,7 @@ static void RasterizeMain(cc::PaintCanvas* canvas, sk_sp<PaintRecord> record) {
#endif
TEST_F(DeferredImageDecoderTest, MAYBE_decodeOnOtherThread) {
lazy_decoder_->SetData(data_, true);
- PaintImage image = CreatePaintImageAtIndex(0);
+ PaintImage image = CreatePaintImage();
ASSERT_TRUE(image);
EXPECT_EQ(1, image.width());
EXPECT_EQ(1, image.height());
@@ -240,7 +238,7 @@ TEST_F(DeferredImageDecoderTest, singleFrameImageLoading) {
status_ = ImageFrame::kFramePartial;
lazy_decoder_->SetData(data_, false);
EXPECT_FALSE(lazy_decoder_->FrameIsReceivedAtIndex(0));
- PaintImage image = CreatePaintImageAtIndex(0);
+ PaintImage image = CreatePaintImage();
ASSERT_TRUE(image);
EXPECT_FALSE(lazy_decoder_->FrameIsReceivedAtIndex(0));
EXPECT_TRUE(actual_decoder_);
@@ -251,7 +249,7 @@ TEST_F(DeferredImageDecoderTest, singleFrameImageLoading) {
EXPECT_FALSE(actual_decoder_);
EXPECT_TRUE(lazy_decoder_->FrameIsReceivedAtIndex(0));
- image = CreatePaintImageAtIndex(0);
+ image = CreatePaintImage();
ASSERT_TRUE(image);
EXPECT_FALSE(decode_request_count_);
}
@@ -263,7 +261,7 @@ TEST_F(DeferredImageDecoderTest, multiFrameImageLoading) {
status_ = ImageFrame::kFramePartial;
lazy_decoder_->SetData(data_, false);
- PaintImage image = CreatePaintImageAtIndex(0);
+ PaintImage image = CreatePaintImage();
ASSERT_TRUE(image);
EXPECT_FALSE(lazy_decoder_->FrameIsReceivedAtIndex(0));
// Anything <= 10ms is clamped to 100ms. See the implementaiton for details.
@@ -276,7 +274,7 @@ TEST_F(DeferredImageDecoderTest, multiFrameImageLoading) {
data_->Append(" ", 1u);
lazy_decoder_->SetData(data_, false);
- image = CreatePaintImageAtIndex(0);
+ image = CreatePaintImage();
ASSERT_TRUE(image);
EXPECT_TRUE(lazy_decoder_->FrameIsReceivedAtIndex(0));
EXPECT_TRUE(lazy_decoder_->FrameIsReceivedAtIndex(1));
@@ -304,7 +302,7 @@ TEST_F(DeferredImageDecoderTest, multiFrameImageLoading) {
TEST_F(DeferredImageDecoderTest, decodedSize) {
decoded_size_ = IntSize(22, 33);
lazy_decoder_->SetData(data_, true);
- PaintImage image = CreatePaintImageAtIndex(0);
+ PaintImage image = CreatePaintImage();
ASSERT_TRUE(image);
EXPECT_EQ(decoded_size_.Width(), image.width());
EXPECT_EQ(decoded_size_.Height(), image.height());
@@ -352,8 +350,7 @@ TEST_F(DeferredImageDecoderTest, frameOpacity) {
SkPixmap pixmap(pix_info, storage.data(), row_bytes);
// Before decoding, the frame is not known to be opaque.
- sk_sp<SkImage> frame =
- CreatePaintImageAtIndex(decoder.get(), 0).GetSkImage();
+ sk_sp<SkImage> frame = CreatePaintImage(decoder.get()).GetSkImage();
ASSERT_TRUE(frame);
EXPECT_FALSE(frame->isOpaque());
EXPECT_TRUE(decoder->FrameHasAlphaAtIndex(0));
@@ -363,7 +360,7 @@ TEST_F(DeferredImageDecoderTest, frameOpacity) {
// After decoding, the frame is known to be opaque.
EXPECT_FALSE(decoder->FrameHasAlphaAtIndex(0));
- frame = CreatePaintImageAtIndex(decoder.get(), 0).GetSkImage();
+ frame = CreatePaintImage(decoder.get()).GetSkImage();
ASSERT_TRUE(frame);
EXPECT_TRUE(frame->isOpaque());
@@ -402,7 +399,7 @@ TEST_F(MultiFrameDeferredImageDecoderTest, PaintImage) {
lazy_decoder_->SetData(data_, false);
// Only the first frame is complete.
- PaintImage image = CreatePaintImageAtIndex(0);
+ PaintImage image = CreatePaintImage();
ASSERT_TRUE(image);
EXPECT_EQ(image.GetFrameMetadata().size(), 2u);
EXPECT_TRUE(image.GetFrameMetadata()[0].complete);
@@ -417,7 +414,7 @@ TEST_F(MultiFrameDeferredImageDecoderTest, PaintImage) {
// Send some more data but the frame status remains the same.
last_complete_frame_ = 0u;
lazy_decoder_->SetData(data_, false);
- PaintImage updated_image = CreatePaintImageAtIndex(0);
+ PaintImage updated_image = CreatePaintImage();
ASSERT_TRUE(updated_image);
EXPECT_EQ(updated_image.GetFrameMetadata().size(), 2u);
EXPECT_TRUE(updated_image.GetFrameMetadata()[0].complete);
@@ -434,7 +431,7 @@ TEST_F(MultiFrameDeferredImageDecoderTest, PaintImage) {
// Mark all frames complete.
last_complete_frame_ = 1u;
lazy_decoder_->SetData(data_, true);
- PaintImage complete_image = CreatePaintImageAtIndex(0);
+ PaintImage complete_image = CreatePaintImage();
ASSERT_TRUE(complete_image);
EXPECT_EQ(complete_image.GetFrameMetadata().size(), 2u);
EXPECT_TRUE(complete_image.GetFrameMetadata()[0].complete);
@@ -455,7 +452,7 @@ TEST_F(MultiFrameDeferredImageDecoderTest, FrameDurationOverride) {
// If the frame duration is below a threshold, we override it to a constant
// value of 100 ms.
- PaintImage image = CreatePaintImageAtIndex(0);
+ PaintImage image = CreatePaintImage();
EXPECT_EQ(image.GetFrameMetadata()[0].duration,
base::TimeDelta::FromMilliseconds(100));
EXPECT_EQ(image.GetFrameMetadata()[1].duration,
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 d689fdf7f7b..4a99e0494fe 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
@@ -18,7 +18,8 @@ namespace {
sk_sp<SkImage> CreateFrameAtIndex(DeferredImageDecoder* decoder, size_t index) {
return SkImage::MakeFromGenerator(std::make_unique<SkiaPaintImageGenerator>(
- decoder->CreateGenerator(index), index));
+ decoder->CreateGenerator(index), index,
+ cc::PaintImage::kDefaultGeneratorClientId));
}
} // namespace
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 7658bd05636..b04c5675260 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
@@ -180,7 +180,9 @@ DrawingBuffer::DrawingBuffer(
sampler_color_space_(color_params.GetSamplerGfxColorSpace()),
use_half_float_storage_(color_params.PixelFormat() ==
kF16CanvasPixelFormat),
- chromium_image_usage_(chromium_image_usage) {
+ chromium_image_usage_(chromium_image_usage),
+ opengl_flip_y_extension_(
+ ContextProvider()->GetCapabilities().mesa_framebuffer_flip_y) {
// Used by browser tests to detect the use of a DrawingBuffer.
TRACE_EVENT_INSTANT0("test_gpu", "DrawingBufferCreation",
TRACE_EVENT_SCOPE_GLOBAL);
@@ -188,7 +190,6 @@ DrawingBuffer::DrawingBuffer(
DrawingBuffer::~DrawingBuffer() {
DCHECK(destruction_in_progress_);
- SwapPreviousFrameCallback(nullptr);
if (layer_) {
layer_->ClearClient();
layer_ = nullptr;
@@ -449,10 +450,10 @@ void DrawingBuffer::FinishPrepareTransferableResourceGpu(
// there are implicit flushes between contexts at the lowest level.
gl_->GenUnverifiedSyncTokenCHROMIUM(
color_buffer_for_mailbox->produce_sync_token.GetData());
-#if defined(OS_MACOSX)
- // Needed for GPU back-pressure on macOS. Used to be in the middle
- // of the commands above; try to move it to the bottom to allow
- // them to be treated atomically.
+#if defined(OS_MACOSX) || defined(OS_ANDROID)
+ // Needed for GPU back-pressure on macOS and Android. Used to be in the
+ // middle of the commands above; try to move it to the bottom to allow them
+ // to be treated atomically.
gl_->DescheduleUntilFinishedCHROMIUM();
#endif
}
@@ -804,10 +805,15 @@ bool DrawingBuffer::Initialize(const IntSize& size, bool use_multisampling) {
state_restorer_->SetFramebufferBindingDirty();
gl_->GenFramebuffers(1, &fbo_);
gl_->BindFramebuffer(GL_FRAMEBUFFER, fbo_);
+ if (opengl_flip_y_extension_)
+ gl_->FramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 1);
+
if (WantExplicitResolve()) {
gl_->GenFramebuffers(1, &multisample_fbo_);
gl_->BindFramebuffer(GL_FRAMEBUFFER, multisample_fbo_);
gl_->GenRenderbuffers(1, &multisample_renderbuffer_);
+ if (opengl_flip_y_extension_)
+ gl_->FramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 1);
}
if (!ResizeFramebufferInternal(size)) {
DLOG(ERROR) << "Initialization failed to allocate backbuffer.";
@@ -926,6 +932,9 @@ cc::Layer* DrawingBuffer::CcLayer() {
premultiplied_alpha_false_texture_);
layer_->SetNearestNeighbor(filter_quality_ == kNone_SkFilterQuality);
+ if (opengl_flip_y_extension_)
+ layer_->SetFlipped(false);
+
GraphicsLayer::RegisterContentsLayer(layer_.get());
}
@@ -1643,15 +1652,6 @@ DrawingBuffer::ScopedStateRestorer::~ScopedStateRestorer() {
client->DrawingBufferClientRestorePixelPackBufferBinding();
}
-void DrawingBuffer::SwapPreviousFrameCallback(
- std::unique_ptr<viz::SingleReleaseCallback> release_callback) {
- if (previous_image_release_callback_) {
- previous_image_release_callback_->Run(gpu::SyncToken(), false);
- }
-
- previous_image_release_callback_ = std::move(release_callback);
-}
-
bool DrawingBuffer::ShouldUseChromiumImage() {
return RuntimeEnabledFeatures::WebGLImageChromiumEnabled() &&
chromium_image_usage_ == kAllowChromiumImage &&
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 f65927d8d15..82a8e397720 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
@@ -248,11 +248,6 @@ class PLATFORM_EXPORT DrawingBuffer : public cc::TextureLayerClient,
// Restore all state that may have been dirtied by any call.
void RestoreAllState();
- // Run the previous release callback if it exists. If the release_callback is
- // not null, assign it to the previous_image_release_callback_.
- void SwapPreviousFrameCallback(
- std::unique_ptr<viz::SingleReleaseCallback> release_callback);
-
// This class helps implement correct semantics for BlitFramebuffer
// when the DrawingBuffer is using a CHROMIUM image for its backing
// store and RGB emulation is in use (basically, macOS only).
@@ -591,9 +586,7 @@ class PLATFORM_EXPORT DrawingBuffer : public cc::TextureLayerClient,
ChromiumImageUsage chromium_image_usage_;
bool ShouldUseChromiumImage();
- // A release callback that is run when the previouis image passed to
- // OffscreenCanvas::Commit() is no longer needed.
- std::unique_ptr<viz::SingleReleaseCallback> previous_image_release_callback_;
+ bool opengl_flip_y_extension_;
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 e67ef2b7e61..c5f07c6736e 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
@@ -218,8 +218,6 @@ TEST_F(DrawingBufferTest, VerifyDestructionCompleteAfterAllResourceReleased) {
viz::TransferableResource resource3;
std::unique_ptr<viz::SingleReleaseCallback> release_callback3;
- IntSize initial_size(kInitialWidth, kInitialHeight);
-
// Produce resources.
EXPECT_FALSE(drawing_buffer_->MarkContentsChanged());
drawing_buffer_->ClearFramebuffers(GL_STENCIL_BUFFER_BIT);
@@ -521,7 +519,6 @@ TEST_F(DrawingBufferImageChromiumTest, AllocationFailure) {
// Request a resource. An image should already be created. Everything works
// as expected.
EXPECT_CALL(*gl_, BindTexImage2DMock(_)).Times(1);
- IntSize initial_size(kInitialWidth, kInitialHeight);
EXPECT_FALSE(drawing_buffer_->MarkContentsChanged());
EXPECT_TRUE(drawing_buffer_->PrepareTransferableResource(nullptr, &resource1,
&release_callback1));
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 2cdc932901a..5d78f23d032 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
@@ -41,6 +41,7 @@ class WebGraphicsContext3DProviderForTests
// Not used by WebGL code.
GrContext* GetGrContext() override { return nullptr; }
+ gpu::webgpu::WebGPUInterface* WebGPUInterface() override { return nullptr; }
bool BindToCurrentThread() override { return false; }
const gpu::Capabilities& GetCapabilities() const override {
return capabilities_;
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 10739aae009..a0ace7b10a9 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
@@ -30,24 +30,24 @@ void XRFrameTransport::PresentChange() {
}
void XRFrameTransport::SetTransportOptions(
- device::mojom::blink::VRDisplayFrameTransportOptionsPtr transport_options) {
+ device::mojom::blink::XRPresentationTransportOptionsPtr transport_options) {
transport_options_ = std::move(transport_options);
}
void XRFrameTransport::BindSubmitFrameClient(
- device::mojom::blink::VRSubmitFrameClientRequest request) {
+ device::mojom::blink::XRPresentationClientRequest request) {
submit_frame_client_binding_.Close();
submit_frame_client_binding_.Bind(std::move(request));
}
bool XRFrameTransport::DrawingIntoSharedBuffer() {
switch (transport_options_->transport_method) {
- case device::mojom::blink::VRDisplayFrameTransportMethod::
+ case device::mojom::blink::XRPresentationTransportMethod::
SUBMIT_AS_TEXTURE_HANDLE:
- case device::mojom::blink::VRDisplayFrameTransportMethod::
+ case device::mojom::blink::XRPresentationTransportMethod::
SUBMIT_AS_MAILBOX_HOLDER:
return false;
- case device::mojom::blink::VRDisplayFrameTransportMethod::
+ case device::mojom::blink::XRPresentationTransportMethod::
DRAW_INTO_TEXTURE_MAILBOX:
return true;
default:
@@ -85,7 +85,7 @@ void XRFrameTransport::CallPreviousFrameCallback() {
}
void XRFrameTransport::FrameSubmitMissing(
- device::mojom::blink::VRPresentationProvider* vr_presentation_provider,
+ device::mojom::blink::XRPresentationProvider* vr_presentation_provider,
gpu::gles2::GLES2Interface* gl,
int16_t vr_frame_id) {
TRACE_EVENT0("gpu", __FUNCTION__);
@@ -95,7 +95,7 @@ void XRFrameTransport::FrameSubmitMissing(
}
void XRFrameTransport::FrameSubmit(
- device::mojom::blink::VRPresentationProvider* vr_presentation_provider,
+ device::mojom::blink::XRPresentationProvider* vr_presentation_provider,
gpu::gles2::GLES2Interface* gl,
DrawingBuffer::Client* drawing_buffer_client,
scoped_refptr<Image> image_ref,
@@ -105,7 +105,7 @@ void XRFrameTransport::FrameSubmit(
DCHECK(transport_options_);
if (transport_options_->transport_method ==
- device::mojom::blink::VRDisplayFrameTransportMethod::
+ device::mojom::blink::XRPresentationTransportMethod::
SUBMIT_AS_TEXTURE_HANDLE) {
#if defined(OS_WIN)
// Currently, we assume that this transport needs a copy.
@@ -134,8 +134,7 @@ 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
// passed over IPC.
- gfx::GpuMemoryBufferHandle gpu_handle =
- CloneHandleForIPC(gpu_memory_buffer->GetHandle());
+ gfx::GpuMemoryBufferHandle gpu_handle = gpu_memory_buffer->CloneHandle();
vr_presentation_provider->SubmitFrameWithTextureHandle(
vr_frame_id,
mojo::WrapPlatformFile(gpu_handle.dxgi_handle.GetHandle()));
@@ -144,7 +143,7 @@ void XRFrameTransport::FrameSubmit(
NOTIMPLEMENTED();
#endif
} else if (transport_options_->transport_method ==
- device::mojom::blink::VRDisplayFrameTransportMethod::
+ device::mojom::blink::XRPresentationTransportMethod::
SUBMIT_AS_MAILBOX_HOLDER) {
// Currently, this transport assumes we don't need to make a separate copy
// of the canvas content.
@@ -189,7 +188,7 @@ void XRFrameTransport::FrameSubmit(
frame_wait_time_);
TRACE_EVENT_END0("gpu", "XRFrameTransport::SubmitFrame");
} else if (transport_options_->transport_method ==
- device::mojom::blink::VRDisplayFrameTransportMethod::
+ device::mojom::blink::XRPresentationTransportMethod::
DRAW_INTO_TEXTURE_MAILBOX) {
TRACE_EVENT0("gpu", "XRFrameTransport::SubmitFrameDrawnIntoTexture");
gpu::SyncToken sync_token;
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 1af00bceb4f..57dc83993d8 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
@@ -30,25 +30,25 @@ class Image;
class PLATFORM_EXPORT XRFrameTransport final
: public GarbageCollectedFinalized<XRFrameTransport>,
- public device::mojom::blink::VRSubmitFrameClient {
+ public device::mojom::blink::XRPresentationClient {
public:
explicit XRFrameTransport();
~XRFrameTransport() override;
void BindSubmitFrameClient(
- device::mojom::blink::VRSubmitFrameClientRequest request);
+ device::mojom::blink::XRPresentationClientRequest request);
void PresentChange();
void SetTransportOptions(
- device::mojom::blink::VRDisplayFrameTransportOptionsPtr);
+ device::mojom::blink::XRPresentationTransportOptionsPtr);
bool DrawingIntoSharedBuffer();
// Call before finalizing the frame's image snapshot.
void FramePreImage(gpu::gles2::GLES2Interface*);
- void FrameSubmit(device::mojom::blink::VRPresentationProvider*,
+ void FrameSubmit(device::mojom::blink::XRPresentationProvider*,
gpu::gles2::GLES2Interface*,
DrawingBuffer::Client*,
scoped_refptr<Image> image_ref,
@@ -56,7 +56,7 @@ class PLATFORM_EXPORT XRFrameTransport final
int16_t vr_frame_id,
bool needs_copy);
- void FrameSubmitMissing(device::mojom::blink::VRPresentationProvider*,
+ void FrameSubmitMissing(device::mojom::blink::XRPresentationProvider*,
gpu::gles2::GLES2Interface*,
int16_t vr_frame_id);
@@ -68,12 +68,12 @@ class PLATFORM_EXPORT XRFrameTransport final
WTF::TimeDelta WaitForGpuFenceReceived();
void CallPreviousFrameCallback();
- // VRSubmitFrameClient
+ // XRPresentationClient
void OnSubmitFrameTransferred(bool success) override;
void OnSubmitFrameRendered() override;
void OnSubmitFrameGpuFence(const gfx::GpuFenceHandle&) override;
- mojo::Binding<device::mojom::blink::VRSubmitFrameClient>
+ mojo::Binding<device::mojom::blink::XRPresentationClient>
submit_frame_client_binding_;
// Used to keep the image alive until the next frame if using
@@ -91,7 +91,7 @@ class PLATFORM_EXPORT XRFrameTransport final
bool waiting_for_previous_frame_fence_ = false;
std::unique_ptr<gfx::GpuFence> previous_frame_fence_;
- device::mojom::blink::VRDisplayFrameTransportOptionsPtr transport_options_;
+ device::mojom::blink::XRPresentationTransportOptionsPtr transport_options_;
std::unique_ptr<GpuMemoryBufferImageCopy> frame_copier_;
};
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gradient.cc b/chromium/third_party/blink/renderer/platform/graphics/gradient.cc
index a30acd776cd..745999aee35 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gradient.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/gradient.cc
@@ -28,6 +28,7 @@
#include "third_party/blink/renderer/platform/graphics/gradient.h"
#include <algorithm>
+#include "base/optional.h"
#include "third_party/blink/renderer/platform/geometry/float_rect.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_shader.h"
@@ -35,7 +36,6 @@
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkMatrix.h"
#include "third_party/skia/include/core/SkShader.h"
-#include "third_party/skia/include/core/SkTLazy.h"
#include "third_party/skia/include/effects/SkGradientShader.h"
namespace blink {
@@ -233,13 +233,15 @@ class RadialGradient final : public Gradient {
uint32_t flags,
const SkMatrix& local_matrix,
SkColor fallback_color) const override {
- SkTCopyOnFirstWrite<SkMatrix> adjusted_local_matrix(local_matrix);
+ const SkMatrix* matrix = &local_matrix;
+ base::Optional<SkMatrix> adjusted_local_matrix;
if (aspect_ratio_ != 1) {
// CSS3 elliptical gradients: apply the elliptical scaling at the
// gradient center point.
DCHECK(p0_ == p1_);
- adjusted_local_matrix.writable()->preScale(1, 1 / aspect_ratio_, p0_.X(),
- p0_.Y());
+ adjusted_local_matrix.emplace(local_matrix);
+ adjusted_local_matrix->preScale(1, 1 / aspect_ratio_, p0_.X(), p0_.Y());
+ matrix = &*adjusted_local_matrix;
}
// The radii we give to Skia must be positive. If we're given a
@@ -249,7 +251,7 @@ class RadialGradient final : public Gradient {
return PaintShader::MakeTwoPointConicalGradient(
FloatPointToSkPoint(p0_), radius0, FloatPointToSkPoint(p1_), radius1,
colors.data(), pos.data(), static_cast<int>(colors.size()), tile_mode,
- flags, adjusted_local_matrix, fallback_color);
+ flags, matrix, fallback_color);
}
private:
@@ -283,16 +285,19 @@ class ConicGradient final : public Gradient {
SkColor fallback_color) const override {
// Skia's sweep gradient angles are relative to the x-axis, not the y-axis.
const float skia_rotation = rotation_ - 90;
- SkTCopyOnFirstWrite<SkMatrix> adjusted_local_matrix(local_matrix);
+ const SkMatrix* matrix = &local_matrix;
+ base::Optional<SkMatrix> adjusted_local_matrix;
if (skia_rotation) {
- adjusted_local_matrix.writable()->preRotate(skia_rotation, position_.X(),
- position_.Y());
+ adjusted_local_matrix.emplace(local_matrix);
+ adjusted_local_matrix->preRotate(skia_rotation, position_.X(),
+ position_.Y());
+ matrix = &*adjusted_local_matrix;
}
return PaintShader::MakeSweepGradient(
position_.X(), position_.Y(), colors.data(), pos.data(),
static_cast<int>(colors.size()), tile_mode, start_angle_, end_angle_,
- flags, adjusted_local_matrix, fallback_color);
+ flags, matrix, fallback_color);
}
private:
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 07dc0da01aa..a7b0b515532 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/graphics_layer.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/graphics_layer.cc
@@ -41,8 +41,6 @@
#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/bindings/runtime_call_stats.h"
-#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
#include "third_party/blink/renderer/platform/drag_image.h"
#include "third_party/blink/renderer/platform/geometry/float_rect.h"
#include "third_party/blink/renderer/platform/geometry/layout_rect.h"
@@ -878,7 +876,8 @@ void GraphicsLayer::SetContentsToImage(
}
image_layer_->SetImage(std::move(paint_image), matrix,
image_orientation.UsesWidthAsHeight());
- image_layer_->SetContentsOpaque(image->CurrentFrameKnownToBeOpaque());
+ // 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());
@@ -1006,6 +1005,9 @@ void GraphicsLayer::SetLayerState(const PropertyTreeState& layer_state,
}
layer_state_->state = layer_state;
layer_state_->offset = layer_offset;
+
+ CHECK(layer_state_->state.Transform() && layer_state_->state.Clip() &&
+ layer_state_->state.Effect());
}
void GraphicsLayer::SetContentsLayerState(const PropertyTreeState& layer_state,
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 f675e99e840..42c230476bd 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/graphics_layer.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/graphics_layer.h
@@ -188,7 +188,7 @@ class PLATFORM_EXPORT GraphicsLayer : public cc::LayerClient,
void SetIsRootForIsolatedGroup(bool);
void SetHitTestableWithoutDrawsContent(bool);
- bool GetHitTestableWithoutDrawsContentForTesting() {
+ bool GetHitTestableWithoutDrawsContent() const {
return hit_testable_without_draws_content_;
}
@@ -245,9 +245,9 @@ class PLATFORM_EXPORT GraphicsLayer : public cc::LayerClient,
void AddLinkHighlight(LinkHighlight*);
void RemoveLinkHighlight(LinkHighlight*);
- // Exposed for tests
- unsigned NumLinkHighlights() { return link_highlights_.size(); }
- LinkHighlight* GetLinkHighlight(int i) { return link_highlights_[i]; }
+ const Vector<LinkHighlight*>& GetLinkHighlights() const {
+ return link_highlights_;
+ }
int GetRenderingContext3D() const { return rendering_context3d_; }
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 b4aaadae26a..9d11f2086a2 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
@@ -29,28 +29,14 @@
#include <utility>
#include "cc/layers/picture_layer.h"
-#include "cc/trees/layer_tree_host.h"
-#include "cc/trees/mutator_host.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/public/platform/web_thread.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_host.h"
-#include "third_party/blink/renderer/platform/animation/compositor_animation_timeline.h"
-#include "third_party/blink/renderer/platform/animation/compositor_float_animation_curve.h"
-#include "third_party/blink/renderer/platform/animation/compositor_keyframe_model.h"
-#include "third_party/blink/renderer/platform/animation/compositor_target_property.h"
-#include "third_party/blink/renderer/platform/graphics/compositor_element_id.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_controller_test.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/scheduler/public/thread_scheduler.h"
#include "third_party/blink/renderer/platform/testing/fake_graphics_layer.h"
#include "third_party/blink/renderer/platform/testing/fake_graphics_layer_client.h"
-#include "third_party/blink/renderer/platform/testing/layer_tree_host_embedder.h"
#include "third_party/blink/renderer/platform/testing/paint_property_test_helpers.h"
#include "third_party/blink/renderer/platform/testing/paint_test_configurations.h"
+#include "third_party/blink/renderer/platform/testing/viewport_layers_setup.h"
#include "third_party/blink/renderer/platform/transforms/matrix_3d_transform_operation.h"
#include "third_party/blink/renderer/platform/transforms/rotate_transform_operation.h"
#include "third_party/blink/renderer/platform/transforms/translate_transform_operation.h"
@@ -59,39 +45,9 @@ namespace blink {
class GraphicsLayerTest : public testing::Test, public PaintTestConfigurations {
public:
- GraphicsLayerTest() {
- clip_layer_ = std::make_unique<FakeGraphicsLayer>(client_);
- scroll_elasticity_layer_ = std::make_unique<FakeGraphicsLayer>(client_);
- page_scale_layer_ = std::make_unique<FakeGraphicsLayer>(client_);
- graphics_layer_ = std::make_unique<FakeGraphicsLayer>(client_);
- graphics_layer_->SetDrawsContent(true);
- clip_layer_->AddChild(scroll_elasticity_layer_.get());
- scroll_elasticity_layer_->AddChild(page_scale_layer_.get());
- page_scale_layer_->AddChild(graphics_layer_.get());
- graphics_layer_->CcLayer()->SetScrollable(clip_layer_->CcLayer()->bounds());
- cc_layer_ = graphics_layer_->CcLayer();
- layer_tree_ = std::make_unique<LayerTreeHostEmbedder>();
- layer_tree_->layer_tree_host()->SetRootLayer(clip_layer_->CcLayer());
- cc::LayerTreeHost::ViewportLayers viewport_layers;
- viewport_layers.overscroll_elasticity = scroll_elasticity_layer_->CcLayer();
- viewport_layers.page_scale = page_scale_layer_->CcLayer();
- viewport_layers.inner_viewport_container = clip_layer_->CcLayer();
- viewport_layers.inner_viewport_scroll = graphics_layer_->CcLayer();
- layer_tree_->layer_tree_host()->RegisterViewportLayers(viewport_layers);
- layer_tree_->layer_tree_host()->SetViewportSizeAndScale(
- gfx::Size(1, 1), /*device_scale_factor=*/1.f, viz::LocalSurfaceId());
-
- graphics_layer_->SetLayerState(PropertyTreeState(PropertyTreeState::Root()),
- IntPoint());
- }
-
+ GraphicsLayerTest() = default;
~GraphicsLayerTest() = default;
- cc::LayerTreeHost* layer_tree_host() {
- return layer_tree_->layer_tree_host();
- }
- cc::AnimationHost* animation_host() { return layer_tree_->animation_host(); }
-
protected:
bool PaintWithoutCommit(GraphicsLayer& layer, const IntRect* interest_rect) {
return layer.PaintWithoutCommit(interest_rect);
@@ -116,15 +72,7 @@ class GraphicsLayerTest : public testing::Test, public PaintTestConfigurations {
return layer.paint_controller_.get();
}
- cc::Layer* cc_layer_;
- std::unique_ptr<FakeGraphicsLayer> graphics_layer_;
- std::unique_ptr<FakeGraphicsLayer> page_scale_layer_;
- std::unique_ptr<FakeGraphicsLayer> scroll_elasticity_layer_;
- std::unique_ptr<FakeGraphicsLayer> clip_layer_;
- FakeGraphicsLayerClient client_;
-
- private:
- std::unique_ptr<LayerTreeHostEmbedder> layer_tree_;
+ ViewportLayersSetup layers_;
};
INSTANTIATE_TEST_CASE_P(All,
@@ -132,108 +80,27 @@ INSTANTIATE_TEST_CASE_P(All,
testing::Values(0,
kBlinkGenPropertyTrees));
-class AnimationForTesting : public CompositorAnimationClient {
- public:
- AnimationForTesting() {
- compositor_animation_ = CompositorAnimation::Create();
- }
-
- CompositorAnimation* GetCompositorAnimation() const override {
- return compositor_animation_.get();
- }
-
- std::unique_ptr<CompositorAnimation> compositor_animation_;
-};
-
-TEST_P(GraphicsLayerTest, updateLayerShouldFlattenTransformWithAnimations) {
- // TODO(bokan): This test doesn't yet work in blink-gen-property-trees
- // because cc::Layers can't set an element id in that mode. We fail at
- // AttachElement since the element id is invalid. https://crbug.com/836897.
- if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled())
- return;
-
- cc::MutatorHost* mutator = layer_tree_host()->mutator_host();
- EXPECT_FALSE(
- mutator->HasTickingKeyframeModelForTesting(cc_layer_->element_id()));
-
- std::unique_ptr<CompositorFloatAnimationCurve> curve =
- CompositorFloatAnimationCurve::Create();
- curve->AddKeyframe(
- CompositorFloatKeyframe(0.0, 0.0,
- *CubicBezierTimingFunction::Preset(
- CubicBezierTimingFunction::EaseType::EASE)));
- std::unique_ptr<CompositorKeyframeModel> float_keyframe_model(
- CompositorKeyframeModel::Create(*curve, CompositorTargetProperty::OPACITY,
- 0, 0));
- int keyframe_model_id = float_keyframe_model->Id();
-
- std::unique_ptr<CompositorAnimationTimeline> compositor_timeline =
- CompositorAnimationTimeline::Create();
- AnimationForTesting animation;
-
- CompositorAnimationHost host(animation_host());
-
- host.AddTimeline(*compositor_timeline);
- compositor_timeline->AnimationAttached(animation);
-
- cc_layer_->SetElementId(CompositorElementId(cc_layer_->id()));
-
- animation.GetCompositorAnimation()->AttachElement(cc_layer_->element_id());
- ASSERT_TRUE(animation.GetCompositorAnimation()->IsElementAttached());
-
- animation.GetCompositorAnimation()->AddKeyframeModel(
- std::move(float_keyframe_model));
-
- EXPECT_TRUE(
- mutator->HasTickingKeyframeModelForTesting(cc_layer_->element_id()));
-
- graphics_layer_->SetShouldFlattenTransform(false);
-
- cc_layer_ = graphics_layer_->CcLayer();
- ASSERT_TRUE(cc_layer_);
-
- EXPECT_TRUE(
- mutator->HasTickingKeyframeModelForTesting(cc_layer_->element_id()));
- animation.GetCompositorAnimation()->RemoveKeyframeModel(keyframe_model_id);
- EXPECT_FALSE(
- mutator->HasTickingKeyframeModelForTesting(cc_layer_->element_id()));
-
- graphics_layer_->SetShouldFlattenTransform(true);
-
- cc_layer_ = graphics_layer_->CcLayer();
- ASSERT_TRUE(cc_layer_);
-
- EXPECT_FALSE(
- mutator->HasTickingKeyframeModelForTesting(cc_layer_->element_id()));
-
- animation.GetCompositorAnimation()->DetachElement();
- ASSERT_FALSE(animation.GetCompositorAnimation()->IsElementAttached());
-
- compositor_timeline->AnimationDestroyed(animation);
- host.RemoveTimeline(*compositor_timeline.get());
-}
-
TEST_P(GraphicsLayerTest, Paint) {
IntRect interest_rect(1, 2, 3, 4);
- EXPECT_TRUE(PaintWithoutCommit(*graphics_layer_, &interest_rect));
- CommitAndFinishCycle(*graphics_layer_);
+ EXPECT_TRUE(PaintWithoutCommit(layers_.graphics_layer(), &interest_rect));
+ CommitAndFinishCycle(layers_.graphics_layer());
- client_.SetNeedsRepaint(true);
- EXPECT_TRUE(PaintWithoutCommit(*graphics_layer_, &interest_rect));
- CommitAndFinishCycle(*graphics_layer_);
+ layers_.graphics_layer_client().SetNeedsRepaint(true);
+ EXPECT_TRUE(PaintWithoutCommit(layers_.graphics_layer(), &interest_rect));
+ CommitAndFinishCycle(layers_.graphics_layer());
- client_.SetNeedsRepaint(false);
- EXPECT_FALSE(PaintWithoutCommit(*graphics_layer_, &interest_rect));
+ layers_.graphics_layer_client().SetNeedsRepaint(false);
+ EXPECT_FALSE(PaintWithoutCommit(layers_.graphics_layer(), &interest_rect));
interest_rect.Move(IntSize(10, 20));
- EXPECT_TRUE(PaintWithoutCommit(*graphics_layer_, &interest_rect));
- CommitAndFinishCycle(*graphics_layer_);
- EXPECT_FALSE(PaintWithoutCommit(*graphics_layer_, &interest_rect));
-
- graphics_layer_->SetNeedsDisplay();
- EXPECT_TRUE(PaintWithoutCommit(*graphics_layer_, &interest_rect));
- CommitAndFinishCycle(*graphics_layer_);
- EXPECT_FALSE(PaintWithoutCommit(*graphics_layer_, &interest_rect));
+ EXPECT_TRUE(PaintWithoutCommit(layers_.graphics_layer(), &interest_rect));
+ CommitAndFinishCycle(layers_.graphics_layer());
+ EXPECT_FALSE(PaintWithoutCommit(layers_.graphics_layer(), &interest_rect));
+
+ layers_.graphics_layer().SetNeedsDisplay();
+ EXPECT_TRUE(PaintWithoutCommit(layers_.graphics_layer(), &interest_rect));
+ CommitAndFinishCycle(layers_.graphics_layer());
+ EXPECT_FALSE(PaintWithoutCommit(layers_.graphics_layer(), &interest_rect));
}
TEST_P(GraphicsLayerTest, PaintRecursively) {
@@ -244,8 +111,10 @@ TEST_P(GraphicsLayerTest, PaintRecursively) {
auto transform2 =
CreateTransform(*transform1, TransformationMatrix().Scale(2));
- client_.SetPainter([&](const GraphicsLayer* layer, GraphicsContext& context,
- GraphicsLayerPaintingPhase, const IntRect&) {
+ layers_.graphics_layer_client().SetPainter([&](const GraphicsLayer* layer,
+ GraphicsContext& context,
+ GraphicsLayerPaintingPhase,
+ const IntRect&) {
{
ScopedPaintChunkProperties properties(context.GetPaintController(),
transform1.get(), *layer,
@@ -267,23 +136,23 @@ TEST_P(GraphicsLayerTest, PaintRecursively) {
TransformationMatrix().Translate(20, 30)});
EXPECT_TRUE(transform1->Changed(transform_root));
EXPECT_TRUE(transform2->Changed(transform_root));
- client_.SetNeedsRepaint(true);
- graphics_layer_->PaintRecursively();
+ layers_.graphics_layer_client().SetNeedsRepaint(true);
+ layers_.graphics_layer().PaintRecursively();
EXPECT_FALSE(transform1->Changed(transform_root));
EXPECT_FALSE(transform2->Changed(transform_root));
}
TEST_P(GraphicsLayerTest, SetDrawsContentFalse) {
- EXPECT_TRUE(graphics_layer_->DrawsContent());
- graphics_layer_->GetPaintController();
- EXPECT_NE(nullptr, GetInternalPaintController(*graphics_layer_));
- EnsureRasterInvalidator(*graphics_layer_);
- EXPECT_NE(nullptr, GetInternalRasterInvalidator(*graphics_layer_));
-
- graphics_layer_->SetDrawsContent(false);
- EXPECT_EQ(nullptr, GetInternalPaintController(*graphics_layer_));
- EXPECT_EQ(nullptr, GetInternalRasterInvalidator(*graphics_layer_));
+ EXPECT_TRUE(layers_.graphics_layer().DrawsContent());
+ layers_.graphics_layer().GetPaintController();
+ EXPECT_NE(nullptr, GetInternalPaintController(layers_.graphics_layer()));
+ EnsureRasterInvalidator(layers_.graphics_layer());
+ EXPECT_NE(nullptr, GetInternalRasterInvalidator(layers_.graphics_layer()));
+
+ layers_.graphics_layer().SetDrawsContent(false);
+ EXPECT_EQ(nullptr, GetInternalPaintController(layers_.graphics_layer()));
+ EXPECT_EQ(nullptr, GetInternalRasterInvalidator(layers_.graphics_layer()));
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/graphics_types.cc b/chromium/third_party/blink/renderer/platform/graphics/graphics_types.cc
index 703a49cea2d..01b3cda6766 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/graphics_types.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/graphics_types.cc
@@ -84,6 +84,27 @@ String CompositeOperatorName(CompositeOperator op, BlendMode blend_op) {
return kCompositeOperatorNames[op];
}
+bool ParseImageEncodingMimeType(const String& mime_type_name,
+ ImageEncodingMimeType& mime_type) {
+ if (mime_type_name == "image/png")
+ mime_type = kMimeTypePng;
+ else if (mime_type_name == "image/jpeg")
+ mime_type = kMimeTypeJpeg;
+ else if (mime_type_name == "image/webp")
+ mime_type = kMimeTypeWebp;
+ else
+ return false;
+ return true;
+}
+
+String ImageEncodingMimeTypeName(ImageEncodingMimeType mime_type) {
+ DCHECK_GE(mime_type, 0);
+ DCHECK_LT(mime_type, 3);
+ const char* const kMimeTypeNames[3] = {"image/png", "image/jpeg",
+ "image/webp"};
+ return kMimeTypeNames[mime_type];
+}
+
bool ParseLineCap(const String& s, LineCap& cap) {
if (s == "butt") {
cap = kButtCap;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/graphics_types.h b/chromium/third_party/blink/renderer/platform/graphics/graphics_types.h
index 636dd547f31..5c71afd879e 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/graphics_types.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/graphics_types.h
@@ -51,6 +51,12 @@ enum ImageDataStorageFormat {
kFloat32ArrayStorageFormat,
};
+enum ImageEncodingMimeType {
+ kMimeTypePng,
+ kMimeTypeJpeg,
+ kMimeTypeWebp,
+};
+
enum StrokeStyle {
kNoStroke,
kSolidStroke,
@@ -214,6 +220,10 @@ PLATFORM_EXPORT bool ParseCompositeAndBlendMode(const String&,
CompositeOperator&,
BlendMode&);
+PLATFORM_EXPORT String ImageEncodingMimeTypeName(ImageEncodingMimeType);
+PLATFORM_EXPORT bool ParseImageEncodingMimeType(const String&,
+ ImageEncodingMimeType&);
+
PLATFORM_EXPORT String LineCapName(LineCap);
PLATFORM_EXPORT bool ParseLineCap(const String&, LineCap&);
diff --git a/chromium/third_party/blink/renderer/platform/graphics/image.cc b/chromium/third_party/blink/renderer/platform/graphics/image.cc
index 883b046672e..c561c134f2f 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/image.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/image.cc
@@ -46,7 +46,6 @@
#include "third_party/blink/renderer/platform/instrumentation/platform_instrumentation.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/length.h"
-#include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h"
#include "third_party/blink/renderer/platform/shared_buffer.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -81,7 +80,8 @@ cc::ImageDecodeCache& Image::SharedCCDecodeCache() {
static const size_t kLockedMemoryLimitBytes = 64 * 1024 * 1024;
DEFINE_THREAD_SAFE_STATIC_LOCAL(cc::SoftwareImageDecodeCache,
image_decode_cache,
- (kN32_SkColorType, kLockedMemoryLimitBytes));
+ (kN32_SkColorType, kLockedMemoryLimitBytes,
+ PaintImage::kDefaultGeneratorClientId));
return image_decode_cache;
}
@@ -95,10 +95,6 @@ scoped_refptr<Image> Image::LoadPlatformResource(const char* name) {
return image;
}
-bool Image::SupportsType(const String& type) {
- return MIMETypeRegistry::IsSupportedImageResourceMIMEType(type);
-}
-
Image::SizeAvailability Image::SetData(scoped_refptr<SharedBuffer> data,
bool all_data_received) {
encoded_image_data_ = std::move(data);
diff --git a/chromium/third_party/blink/renderer/platform/graphics/image.h b/chromium/third_party/blink/renderer/platform/graphics/image.h
index 7524079f269..c7e847ce6bb 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/image.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/image.h
@@ -75,7 +75,6 @@ class PLATFORM_EXPORT Image : public ThreadSafeRefCounted<Image> {
static cc::ImageDecodeCache& SharedCCDecodeCache();
static scoped_refptr<Image> LoadPlatformResource(const char* name);
- static bool SupportsType(const String&);
virtual bool IsSVGImage() const { return false; }
virtual bool IsBitmapImage() const { return false; }
diff --git a/chromium/third_party/blink/renderer/platform/graphics/image_data_buffer.cc b/chromium/third_party/blink/renderer/platform/graphics/image_data_buffer.cc
index c3d7df4e8cb..7992494b1c2 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/image_data_buffer.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/image_data_buffer.cc
@@ -37,7 +37,6 @@
#include "base/memory/ptr_util.h"
#include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
#include "third_party/blink/renderer/platform/image-encoders/image_encoder.h"
-#include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/text/base64.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -117,19 +116,19 @@ const unsigned char* ImageDataBuffer::Pixels() const {
return static_cast<const unsigned char*>(pixmap_.addr());
}
-bool ImageDataBuffer::EncodeImage(const String& mime_type,
+bool ImageDataBuffer::EncodeImage(const ImageEncodingMimeType mime_type,
const double& quality,
Vector<unsigned char>* encoded_image) const {
return EncodeImageInternal(mime_type, quality, encoded_image, pixmap_);
}
-bool ImageDataBuffer::EncodeImageInternal(const String& mime_type,
+bool ImageDataBuffer::EncodeImageInternal(const ImageEncodingMimeType mime_type,
const double& quality,
Vector<unsigned char>* encoded_image,
const SkPixmap& pixmap) const {
DCHECK(is_valid_);
- if (mime_type == "image/jpeg") {
+ if (mime_type == kMimeTypeJpeg) {
SkJpegEncoder::Options options;
options.fQuality = ImageEncoder::ComputeJpegQuality(quality);
options.fAlphaOption = SkJpegEncoder::AlphaOption::kBlendOnBlack;
@@ -139,22 +138,21 @@ bool ImageDataBuffer::EncodeImageInternal(const String& mime_type,
return ImageEncoder::Encode(encoded_image, pixmap, options);
}
- if (mime_type == "image/webp") {
+ if (mime_type == kMimeTypeWebp) {
SkWebpEncoder::Options options = ImageEncoder::ComputeWebpOptions(quality);
return ImageEncoder::Encode(encoded_image, pixmap, options);
}
- DCHECK_EQ(mime_type, "image/png");
+ DCHECK_EQ(mime_type, kMimeTypePng);
SkPngEncoder::Options options;
options.fFilterFlags = SkPngEncoder::FilterFlag::kSub;
options.fZLibLevel = 3;
return ImageEncoder::Encode(encoded_image, pixmap, options);
}
-String ImageDataBuffer::ToDataURL(const String& mime_type,
+String ImageDataBuffer::ToDataURL(const ImageEncodingMimeType mime_type,
const double& quality) const {
DCHECK(is_valid_);
- DCHECK(MIMETypeRegistry::IsSupportedImageMIMETypeForEncoding(mime_type));
// toDataURL always encodes in sRGB and does not include the color space
// information.
@@ -173,7 +171,8 @@ String ImageDataBuffer::ToDataURL(const String& mime_type,
if (!EncodeImageInternal(mime_type, quality, &result, pixmap))
return "data:,";
- return "data:" + mime_type + ";base64," + Base64Encode(result);
+ return "data:" + ImageEncodingMimeTypeName(mime_type) + ";base64," +
+ Base64Encode(result);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/image_data_buffer.h b/chromium/third_party/blink/renderer/platform/graphics/image_data_buffer.h
index 3002ac9875b..9dc4c9a9b38 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/image_data_buffer.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/image_data_buffer.h
@@ -32,6 +32,7 @@
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/renderer/platform/geometry/float_rect.h"
#include "third_party/blink/renderer/platform/geometry/int_size.h"
+#include "third_party/blink/renderer/platform/graphics/graphics_types.h"
#include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -47,8 +48,9 @@ class PLATFORM_EXPORT ImageDataBuffer {
scoped_refptr<StaticBitmapImage>);
static std::unique_ptr<ImageDataBuffer> Create(const SkPixmap&);
- String ToDataURL(const String& mime_type, const double& quality) const;
- bool EncodeImage(const String& mime_type,
+ String ToDataURL(const ImageEncodingMimeType mime_type,
+ const double& quality) const;
+ bool EncodeImage(const ImageEncodingMimeType mime_type,
const double& quality,
Vector<unsigned char>* encoded_image) const;
@@ -66,7 +68,7 @@ class PLATFORM_EXPORT ImageDataBuffer {
bool IsValid() { return is_valid_; } // Only used by Create()
- bool EncodeImageInternal(const String& mime_type,
+ bool EncodeImageInternal(const ImageEncodingMimeType mime_type,
const double& quality,
Vector<unsigned char>* encoded_image,
const SkPixmap& pixmap) const;
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
new file mode 100644
index 00000000000..803b7d505ef
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/graphics/image_decoder_wrapper.cc
@@ -0,0 +1,302 @@
+// 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/image_decoder_wrapper.h"
+
+#include "third_party/blink/renderer/platform/graphics/image_decoding_store.h"
+#include "third_party/blink/renderer/platform/graphics/image_frame_generator.h"
+
+namespace blink {
+namespace {
+
+void CopyPixels(void* dst_addr,
+ size_t dst_row_bytes,
+ const void* src_addr,
+ size_t src_row_bytes,
+ const SkImageInfo& info) {
+ size_t row_bytes = info.bytesPerPixel() * info.width();
+ for (int y = 0; y < info.height(); ++y) {
+ memcpy(dst_addr, src_addr, row_bytes);
+ src_addr = static_cast<const char*>(src_addr) + src_row_bytes;
+ dst_addr = static_cast<char*>(dst_addr) + dst_row_bytes;
+ }
+}
+
+bool CompatibleInfo(const SkImageInfo& src, const SkImageInfo& dst) {
+ if (src == dst)
+ return true;
+
+ // It is legal to write kOpaque_SkAlphaType pixels into a kPremul_SkAlphaType
+ // buffer. This can happen when DeferredImageDecoder allocates an
+ // kOpaque_SkAlphaType image generator based on cached frame info, while the
+ // ImageFrame-allocated dest bitmap stays kPremul_SkAlphaType.
+ if (src.alphaType() == kOpaque_SkAlphaType &&
+ dst.alphaType() == kPremul_SkAlphaType) {
+ const SkImageInfo& tmp = src.makeAlphaType(kPremul_SkAlphaType);
+ return tmp == dst;
+ }
+
+ return false;
+}
+
+// Creates a SkPixelRef such that the memory for pixels is given by an external
+// body. This is used to write directly to the memory given by Skia during
+// decoding.
+class ExternalMemoryAllocator final : public SkBitmap::Allocator {
+ USING_FAST_MALLOC(ExternalMemoryAllocator);
+
+ public:
+ ExternalMemoryAllocator(const SkImageInfo& info,
+ void* pixels,
+ size_t row_bytes)
+ : info_(info), pixels_(pixels), row_bytes_(row_bytes) {}
+
+ bool allocPixelRef(SkBitmap* dst) override {
+ const SkImageInfo& info = dst->info();
+ if (kUnknown_SkColorType == info.colorType())
+ return false;
+
+ if (!CompatibleInfo(info_, info) || row_bytes_ != dst->rowBytes())
+ return false;
+
+ return dst->installPixels(info, pixels_, row_bytes_);
+ }
+
+ private:
+ SkImageInfo info_;
+ void* pixels_;
+ size_t row_bytes_;
+
+ DISALLOW_COPY_AND_ASSIGN(ExternalMemoryAllocator);
+};
+
+} // namespace
+
+ImageDecoderWrapper::ImageDecoderWrapper(
+ ImageFrameGenerator* generator,
+ SegmentReader* data,
+ const SkISize& scaled_size,
+ ImageDecoder::AlphaOption alpha_option,
+ ColorBehavior decoder_color_behavior,
+ ImageDecoder::HighBitDepthDecodingOption decoding_option,
+ size_t index,
+ const SkImageInfo& info,
+ void* pixels,
+ size_t row_bytes,
+ bool all_data_received,
+ cc::PaintImage::GeneratorClientId client_id)
+ : generator_(generator),
+ data_(data),
+ scaled_size_(scaled_size),
+ alpha_option_(alpha_option),
+ decoder_color_behavior_(decoder_color_behavior),
+ decoding_option_(decoding_option),
+ frame_index_(index),
+ info_(info),
+ pixels_(pixels),
+ row_bytes_(row_bytes),
+ all_data_received_(all_data_received),
+ client_id_(client_id) {}
+
+ImageDecoderWrapper::~ImageDecoderWrapper() = default;
+
+bool ImageDecoderWrapper::Decode(ImageDecoderFactory* factory,
+ size_t* frame_count,
+ bool* has_alpha) {
+ DCHECK(frame_count);
+ DCHECK(has_alpha);
+
+ ImageDecoder* decoder = nullptr;
+ std::unique_ptr<ImageDecoder> new_decoder;
+
+ const bool resume_decoding = ImageDecodingStore::Instance().LockDecoder(
+ generator_, scaled_size_, alpha_option_, client_id_, &decoder);
+ DCHECK(!resume_decoding || decoder);
+
+ if (resume_decoding) {
+ decoder->SetData(data_, all_data_received_);
+ } else {
+ new_decoder = CreateDecoderWithData(factory);
+ if (!new_decoder)
+ return false;
+ decoder = new_decoder.get();
+ }
+
+ // 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
+ // decoder, particularly with GIF.
+ if (all_data_received_)
+ *frame_count = decoder->FrameCount();
+
+ const bool decode_to_external_memory =
+ ShouldDecodeToExternalMemory(*frame_count, resume_decoding);
+
+ ExternalMemoryAllocator external_memory_allocator(info_, pixels_, row_bytes_);
+ if (decode_to_external_memory)
+ decoder->SetMemoryAllocator(&external_memory_allocator);
+ ImageFrame* frame = decoder->DecodeFrameBufferAtIndex(frame_index_);
+ // SetMemoryAllocator() can try to access decoder's data, so we have to
+ // clear it before clearing SegmentReader.
+ if (decode_to_external_memory)
+ decoder->SetMemoryAllocator(nullptr);
+ // Verify we have the only ref-count.
+ DCHECK(external_memory_allocator.unique());
+
+ decoder->SetData(scoped_refptr<SegmentReader>(nullptr), false);
+ decoder->ClearCacheExceptFrame(frame_index_);
+
+ const bool has_decoded_frame =
+ frame && frame->GetStatus() != ImageFrame::kFrameEmpty &&
+ !frame->Bitmap().isNull();
+ if (!has_decoded_frame) {
+ decode_failed_ = decoder->Failed();
+ if (resume_decoding) {
+ ImageDecodingStore::Instance().UnlockDecoder(generator_, client_id_,
+ decoder);
+ }
+ return false;
+ }
+
+ SkBitmap scaled_size_bitmap = frame->Bitmap();
+ DCHECK_EQ(scaled_size_bitmap.width(), scaled_size_.width());
+ DCHECK_EQ(scaled_size_bitmap.height(), scaled_size_.height());
+
+ // If we decoded into external memory, the bitmap should be backed by the
+ // pixels passed to the allocator.
+ DCHECK(!decode_to_external_memory ||
+ scaled_size_bitmap.getPixels() == pixels_);
+
+ *has_alpha = !scaled_size_bitmap.isOpaque();
+ if (!decode_to_external_memory) {
+ CopyPixels(pixels_, row_bytes_, scaled_size_bitmap.getPixels(),
+ scaled_size_bitmap.rowBytes(), info_);
+ }
+
+ // Free as much memory as possible. For single-frame images, we can
+ // just delete the decoder entirely if they use the external allocator.
+ // For multi-frame images, we keep the decoder around in order to preserve
+ // decoded information such as the required previous frame indexes, but if
+ // we've reached the last frame we can at least delete all the cached frames.
+ // (If we were to do this before reaching the last frame, any subsequent
+ // requested frames which relied on the current frame would trigger extra
+ // re-decoding of all frames in the dependency chain).
+ const bool frame_was_completely_decoded =
+ frame->GetStatus() == ImageFrame::kFrameComplete || all_data_received_;
+ PurgeAllFramesIfNecessary(decoder, frame_was_completely_decoded,
+ *frame_count);
+
+ const bool should_remove_decoder = ShouldRemoveDecoder(
+ frame_was_completely_decoded, decode_to_external_memory);
+ if (resume_decoding) {
+ if (should_remove_decoder) {
+ ImageDecodingStore::Instance().RemoveDecoder(generator_, client_id_,
+ decoder);
+ } else {
+ ImageDecodingStore::Instance().UnlockDecoder(generator_, client_id_,
+ decoder);
+ }
+ } else if (!should_remove_decoder) {
+ // If we have a newly created decoder which we don't want to remove, add
+ // it to the cache.
+ ImageDecodingStore::Instance().InsertDecoder(generator_, client_id_,
+ std::move(new_decoder));
+ }
+
+ return true;
+}
+
+bool ImageDecoderWrapper::ShouldDecodeToExternalMemory(
+ size_t frame_count,
+ bool resume_decoding) const {
+ // Multi-frame images need their decode cached in the decoder to allow using
+ // subsequent frames to be decoded by caching dependent frames.
+ // Also external allocators don't work for multi-frame images right now.
+ if (generator_->IsMultiFrame())
+ return false;
+
+ // On low-end devices, always use the external allocator, to avoid storing
+ // duplicate copies of the data for partial decodes in the ImageDecoder's
+ // cache.
+ if (Platform::Current()->IsLowEndDevice()) {
+ DCHECK(!resume_decoding);
+ return true;
+ }
+
+ // TODO (scroggo): If !is_multi_frame_ && new_decoder && frame_count_, it
+ // should always be the case that 1u == frame_count_. But it looks like it
+ // is currently possible for frame_count_ to be another value.
+ if (1u == frame_count && all_data_received_ && !resume_decoding) {
+ // Also use external allocator in situations when all of the data has been
+ // received and there is not already a partial cache in the image decoder.
+ return true;
+ }
+
+ return false;
+}
+
+bool ImageDecoderWrapper::ShouldRemoveDecoder(
+ bool frame_was_completely_decoded,
+ bool decoded_to_external_memory) const {
+ // Mult-frame images need the decode cached to allow decoding subsequent
+ // frames without having to decode the complete dependency chain. For this
+ // reason, we should never be decoding directly to external memory for these
+ // images.
+ if (generator_->IsMultiFrame()) {
+ DCHECK(!decoded_to_external_memory);
+ return false;
+ }
+
+ // If the decode was done directly to external memory, the decoder has no
+ // data to cache. Remove it.
+ if (decoded_to_external_memory)
+ return true;
+
+ // If we were caching a decoder with a partially decoded frame which has
+ // now been completely decoded, we don't need to cache this decoder anymore.
+ if (frame_was_completely_decoded)
+ return true;
+
+ return false;
+}
+
+void ImageDecoderWrapper::PurgeAllFramesIfNecessary(
+ ImageDecoder* decoder,
+ bool frame_was_completely_decoded,
+ size_t frame_count) const {
+ // We only purge all frames when we have decoded the last frame for a
+ // multi-frame image. This is because once the last frame is decoded, the
+ // animation will loop back to the first frame which does not need the last
+ // frame as a dependency and therefore can be purged.
+ // For single-frame images, the complete decoder is removed once it has been
+ // completely decoded.
+ if (!generator_->IsMultiFrame())
+ return;
+
+ // The frame was only partially decoded, we need to retain it to be able to
+ // resume the decoder.
+ if (!frame_was_completely_decoded)
+ return;
+
+ const size_t last_frame_index = frame_count - 1;
+ if (frame_index_ == last_frame_index)
+ decoder->ClearCacheExceptFrame(kNotFound);
+}
+
+std::unique_ptr<ImageDecoder> ImageDecoderWrapper::CreateDecoderWithData(
+ ImageDecoderFactory* factory) const {
+ if (factory) {
+ auto decoder = factory->Create();
+ if (decoder)
+ decoder->SetData(data_, all_data_received_);
+ return decoder;
+ }
+
+ // The newly created decoder just grabbed the data. No need to reset it.
+ return ImageDecoder::Create(data_, all_data_received_, alpha_option_,
+ decoding_option_, decoder_color_behavior_,
+ scaled_size_);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/image_decoder_wrapper.h b/chromium/third_party/blink/renderer/platform/graphics/image_decoder_wrapper.h
new file mode 100644
index 00000000000..f9008ff746c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/graphics/image_decoder_wrapper.h
@@ -0,0 +1,70 @@
+// 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_IMAGE_DECODER_WRAPPER_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_IMAGE_DECODER_WRAPPER_H_
+
+#include "cc/paint/paint_image.h"
+#include "third_party/blink/renderer/platform/image-decoders/image_decoder.h"
+#include "third_party/skia/include/core/SkSize.h"
+
+namespace blink {
+class ImageDecoderFactory;
+class ImageFrameGenerator;
+class SegmentReader;
+
+class ImageDecoderWrapper {
+ public:
+ ImageDecoderWrapper(ImageFrameGenerator* generator,
+ SegmentReader* data,
+ const SkISize& scaled_size,
+ ImageDecoder::AlphaOption alpha_option,
+ ColorBehavior decoder_color_behavior,
+ ImageDecoder::HighBitDepthDecodingOption decoding_option,
+ size_t index,
+ const SkImageInfo& info,
+ void* pixels,
+ size_t row_bytes,
+ bool all_data_received,
+ cc::PaintImage::GeneratorClientId client_id);
+ ~ImageDecoderWrapper();
+
+ // Returns true if the decode succeeded.
+ bool Decode(ImageDecoderFactory* factory,
+ size_t* frame_count,
+ bool* has_alpha);
+
+ // Indicates that the decode failed due to a corrupt image.
+ bool decode_failed() const { return decode_failed_; }
+
+ private:
+ bool ShouldDecodeToExternalMemory(size_t frame_count,
+ bool has_cached_decoder) const;
+ bool ShouldRemoveDecoder(bool frame_was_completely_decoded,
+ bool decoded_to_external_memory) const;
+ void PurgeAllFramesIfNecessary(ImageDecoder* decoder,
+ bool frame_was_completely_decoded,
+ size_t frame_count) const;
+ std::unique_ptr<ImageDecoder> CreateDecoderWithData(
+ ImageDecoderFactory* factory) const;
+
+ const ImageFrameGenerator* const generator_;
+ SegmentReader* data_;
+ const SkISize scaled_size_;
+ const ImageDecoder::AlphaOption alpha_option_;
+ const ColorBehavior decoder_color_behavior_;
+ const ImageDecoder::HighBitDepthDecodingOption decoding_option_;
+ const size_t frame_index_;
+ const SkImageInfo info_;
+ void* pixels_;
+ const size_t row_bytes_;
+ const bool all_data_received_;
+ const cc::PaintImage::GeneratorClientId client_id_;
+
+ bool decode_failed_ = false;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_IMAGE_DECODER_WRAPPER_H_
diff --git a/chromium/third_party/blink/renderer/platform/graphics/image_decoding_store.cc b/chromium/third_party/blink/renderer/platform/graphics/image_decoding_store.cc
index 02fff1a6bb5..ce30ef71017 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/image_decoding_store.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/image_decoding_store.cc
@@ -56,15 +56,18 @@ ImageDecodingStore& ImageDecodingStore::Instance() {
return store;
}
-bool ImageDecodingStore::LockDecoder(const ImageFrameGenerator* generator,
- const SkISize& scaled_size,
- ImageDecoder::AlphaOption alpha_option,
- ImageDecoder** decoder) {
+bool ImageDecodingStore::LockDecoder(
+ const ImageFrameGenerator* generator,
+ const SkISize& scaled_size,
+ ImageDecoder::AlphaOption alpha_option,
+ cc::PaintImage::GeneratorClientId client_id,
+ ImageDecoder** decoder) {
DCHECK(decoder);
MutexLocker lock(mutex_);
- DecoderCacheMap::iterator iter = decoder_cache_map_.find(
- DecoderCacheEntry::MakeCacheKey(generator, scaled_size, alpha_option));
+ DecoderCacheMap::iterator iter =
+ decoder_cache_map_.find(DecoderCacheEntry::MakeCacheKey(
+ generator, scaled_size, alpha_option, client_id));
if (iter == decoder_cache_map_.end())
return false;
@@ -77,11 +80,13 @@ bool ImageDecodingStore::LockDecoder(const ImageFrameGenerator* generator,
return true;
}
-void ImageDecodingStore::UnlockDecoder(const ImageFrameGenerator* generator,
- const ImageDecoder* decoder) {
+void ImageDecodingStore::UnlockDecoder(
+ const ImageFrameGenerator* generator,
+ cc::PaintImage::GeneratorClientId client_id,
+ const ImageDecoder* decoder) {
MutexLocker lock(mutex_);
DecoderCacheMap::iterator iter = decoder_cache_map_.find(
- DecoderCacheEntry::MakeCacheKey(generator, decoder));
+ DecoderCacheEntry::MakeCacheKey(generator, decoder, client_id));
SECURITY_DCHECK(iter != decoder_cache_map_.end());
CacheEntry* cache_entry = iter->value.get();
@@ -92,13 +97,15 @@ void ImageDecodingStore::UnlockDecoder(const ImageFrameGenerator* generator,
ordered_cache_list_.Append(cache_entry);
}
-void ImageDecodingStore::InsertDecoder(const ImageFrameGenerator* generator,
- std::unique_ptr<ImageDecoder> decoder) {
+void ImageDecodingStore::InsertDecoder(
+ const ImageFrameGenerator* generator,
+ cc::PaintImage::GeneratorClientId client_id,
+ std::unique_ptr<ImageDecoder> decoder) {
// Prune old cache entries to give space for the new one.
Prune();
std::unique_ptr<DecoderCacheEntry> new_cache_entry =
- DecoderCacheEntry::Create(generator, std::move(decoder));
+ DecoderCacheEntry::Create(generator, std::move(decoder), client_id);
MutexLocker lock(mutex_);
DCHECK(!decoder_cache_map_.Contains(new_cache_entry->CacheKey()));
@@ -106,13 +113,15 @@ void ImageDecodingStore::InsertDecoder(const ImageFrameGenerator* generator,
&decoder_cache_key_map_);
}
-void ImageDecodingStore::RemoveDecoder(const ImageFrameGenerator* generator,
- const ImageDecoder* decoder) {
+void ImageDecodingStore::RemoveDecoder(
+ const ImageFrameGenerator* generator,
+ cc::PaintImage::GeneratorClientId client_id,
+ const ImageDecoder* decoder) {
Vector<std::unique_ptr<CacheEntry>> cache_entries_to_delete;
{
MutexLocker lock(mutex_);
DecoderCacheMap::iterator iter = decoder_cache_map_.find(
- DecoderCacheEntry::MakeCacheKey(generator, decoder));
+ DecoderCacheEntry::MakeCacheKey(generator, decoder, client_id));
SECURITY_DCHECK(iter != decoder_cache_map_.end());
CacheEntry* cache_entry = iter->value.get();
@@ -241,6 +250,8 @@ void ImageDecodingStore::RemoveFromCacheInternal(
U* cache_map,
V* identifier_map,
Vector<std::unique_ptr<CacheEntry>>* deletion_list) {
+ DCHECK_EQ(cache_entry->UseCount(), 0);
+
const size_t cache_entry_bytes = cache_entry->MemoryUsageInBytes();
DCHECK_GE(heap_memory_usage_in_bytes_, cache_entry_bytes);
heap_memory_usage_in_bytes_ -= cache_entry_bytes;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/image_decoding_store.h b/chromium/third_party/blink/renderer/platform/graphics/image_decoding_store.h
index 77cd5bf9c17..91a6071fcc9 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/image_decoding_store.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/image_decoding_store.h
@@ -33,6 +33,7 @@
#include "SkTypes.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
+#include "cc/paint/paint_image_generator.h"
#include "third_party/blink/renderer/platform/graphics/image_frame_generator.h"
#include "third_party/blink/renderer/platform/graphics/skia/sk_size_hash.h"
#include "third_party/blink/renderer/platform/image-decoders/image_decoder.h"
@@ -52,17 +53,19 @@ struct DecoderCacheKey {
const blink::ImageFrameGenerator* gen_;
SkISize size_;
blink::ImageDecoder::AlphaOption alpha_option_;
+ cc::PaintImage::GeneratorClientId client_id_;
DecoderCacheKey()
: gen_(nullptr),
size_(SkISize::Make(0, 0)),
- alpha_option_(static_cast<blink::ImageDecoder::AlphaOption>(0)) {}
+ alpha_option_(static_cast<blink::ImageDecoder::AlphaOption>(0)),
+ client_id_(cc::PaintImage::kDefaultGeneratorClientId) {}
};
static inline bool operator==(const DecoderCacheKey& a,
const DecoderCacheKey& b) {
return a.gen_ == b.gen_ && a.size_ == b.size_ &&
- a.alpha_option_ == b.alpha_option_;
+ a.alpha_option_ == b.alpha_option_ && a.client_id_ == b.client_id_;
}
static inline bool operator!=(const DecoderCacheKey& a,
@@ -116,9 +119,10 @@ class DecoderCacheEntry final : public CacheEntry {
public:
static std::unique_ptr<DecoderCacheEntry> Create(
const ImageFrameGenerator* generator,
- std::unique_ptr<ImageDecoder> decoder) {
+ std::unique_ptr<ImageDecoder> decoder,
+ cc::PaintImage::GeneratorClientId client_id) {
return base::WrapUnique(
- new DecoderCacheEntry(generator, 0, std::move(decoder)));
+ new DecoderCacheEntry(generator, 0, std::move(decoder), client_id));
}
size_t MemoryUsageInBytes() const override {
@@ -126,40 +130,48 @@ class DecoderCacheEntry final : public CacheEntry {
}
CacheType GetType() const override { return kTypeDecoder; }
- static DecoderCacheKey MakeCacheKey(const ImageFrameGenerator* generator,
- const SkISize& size,
- ImageDecoder::AlphaOption alpha_option) {
+ static DecoderCacheKey MakeCacheKey(
+ const ImageFrameGenerator* generator,
+ const SkISize& size,
+ ImageDecoder::AlphaOption alpha_option,
+ cc::PaintImage::GeneratorClientId client_id) {
DecoderCacheKey key;
key.gen_ = generator;
key.size_ = size;
key.alpha_option_ = alpha_option;
+ key.client_id_ = client_id;
return key;
}
- static DecoderCacheKey MakeCacheKey(const ImageFrameGenerator* generator,
- const ImageDecoder* decoder) {
+ static DecoderCacheKey MakeCacheKey(
+ const ImageFrameGenerator* generator,
+ const ImageDecoder* decoder,
+ cc::PaintImage::GeneratorClientId client_id) {
return MakeCacheKey(generator,
SkISize::Make(decoder->DecodedSize().Width(),
decoder->DecodedSize().Height()),
- decoder->GetAlphaOption());
+ decoder->GetAlphaOption(), client_id);
}
DecoderCacheKey CacheKey() const {
- return MakeCacheKey(generator_, size_, alpha_option_);
+ return MakeCacheKey(generator_, size_, alpha_option_, client_id_);
}
ImageDecoder* CachedDecoder() const { return cached_decoder_.get(); }
private:
DecoderCacheEntry(const ImageFrameGenerator* generator,
int count,
- std::unique_ptr<ImageDecoder> decoder)
+ std::unique_ptr<ImageDecoder> decoder,
+ cc::PaintImage::GeneratorClientId client_id)
: CacheEntry(generator, count),
cached_decoder_(std::move(decoder)),
size_(SkISize::Make(cached_decoder_->DecodedSize().Width(),
cached_decoder_->DecodedSize().Height())),
- alpha_option_(cached_decoder_->GetAlphaOption()) {}
+ alpha_option_(cached_decoder_->GetAlphaOption()),
+ client_id_(client_id) {}
std::unique_ptr<ImageDecoder> cached_decoder_;
SkISize size_;
ImageDecoder::AlphaOption alpha_option_;
+ cc::PaintImage::GeneratorClientId client_id_;
};
} // namespace blink
@@ -172,17 +184,19 @@ struct DefaultHash<blink::DecoderCacheKey> {
struct Hash {
STATIC_ONLY(Hash);
static unsigned GetHash(const blink::DecoderCacheKey& p) {
- return HashInts(
+ auto first =
HashInts(DefaultHash<blink::ImageFrameGenerator*>::Hash::GetHash(
const_cast<blink::ImageFrameGenerator*>(p.gen_)),
- DefaultHash<SkISize>::Hash::GetHash(p.size_)),
- DefaultHash<uint8_t>::Hash::GetHash(
- static_cast<uint8_t>(p.alpha_option_)));
+ DefaultHash<SkISize>::Hash::GetHash(p.size_));
+ auto second = HashInts(DefaultHash<uint8_t>::Hash::GetHash(
+ static_cast<uint8_t>(p.alpha_option_)),
+ p.client_id_);
+ return HashInts(first, second);
}
static bool Equal(const blink::DecoderCacheKey& a,
const blink::DecoderCacheKey& b) {
return a.gen_ == b.gen_ && a.size_ == b.size_ &&
- a.alpha_option_ == b.alpha_option_;
+ a.alpha_option_ == b.alpha_option_ && a.client_id_ == b.client_id_;
}
static const bool safe_to_compare_to_empty_or_deleted = true;
};
@@ -196,12 +210,14 @@ struct HashTraits<blink::DecoderCacheKey>
static blink::DecoderCacheKey EmptyValue() {
return blink::DecoderCacheEntry::MakeCacheKey(
nullptr, SkISize::Make(0, 0),
- static_cast<blink::ImageDecoder::AlphaOption>(0));
+ static_cast<blink::ImageDecoder::AlphaOption>(0),
+ cc::PaintImage::kDefaultGeneratorClientId);
}
static void ConstructDeletedValue(blink::DecoderCacheKey& slot, bool) {
slot = blink::DecoderCacheEntry::MakeCacheKey(
nullptr, SkISize::Make(-1, -1),
- static_cast<blink::ImageDecoder::AlphaOption>(0));
+ static_cast<blink::ImageDecoder::AlphaOption>(0),
+ cc::PaintImage::kDefaultGeneratorClientId);
}
static bool IsDeletedValue(const blink::DecoderCacheKey& value) {
return value.size_ == SkISize::Make(-1, -1);
@@ -248,10 +264,17 @@ class PLATFORM_EXPORT ImageDecodingStore final {
bool LockDecoder(const ImageFrameGenerator*,
const SkISize& scaled_size,
ImageDecoder::AlphaOption,
+ cc::PaintImage::GeneratorClientId client_id,
ImageDecoder**);
- void UnlockDecoder(const ImageFrameGenerator*, const ImageDecoder*);
- void InsertDecoder(const ImageFrameGenerator*, std::unique_ptr<ImageDecoder>);
- void RemoveDecoder(const ImageFrameGenerator*, const ImageDecoder*);
+ void UnlockDecoder(const ImageFrameGenerator*,
+ cc::PaintImage::GeneratorClientId client_id,
+ const ImageDecoder*);
+ void InsertDecoder(const ImageFrameGenerator*,
+ cc::PaintImage::GeneratorClientId client_id,
+ std::unique_ptr<ImageDecoder>);
+ void RemoveDecoder(const ImageFrameGenerator*,
+ cc::PaintImage::GeneratorClientId client_id,
+ const ImageDecoder*);
// Remove all cache entries indexed by ImageFrameGenerator.
void RemoveCacheIndexedByGenerator(const ImageFrameGenerator*);
diff --git a/chromium/third_party/blink/renderer/platform/graphics/image_decoding_store_test.cc b/chromium/third_party/blink/renderer/platform/graphics/image_decoding_store_test.cc
index 40500788863..ce45677d0b5 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/image_decoding_store_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/image_decoding_store_test.cc
@@ -79,18 +79,21 @@ TEST_F(ImageDecodingStoreTest, insertDecoder) {
std::unique_ptr<ImageDecoder> decoder = MockImageDecoder::Create(this);
decoder->SetSize(1, 1);
const ImageDecoder* ref_decoder = decoder.get();
- ImageDecodingStore::Instance().InsertDecoder(generator_.get(),
- std::move(decoder));
+ ImageDecodingStore::Instance().InsertDecoder(
+ generator_.get(), cc::PaintImage::kDefaultGeneratorClientId,
+ std::move(decoder));
EXPECT_EQ(1, ImageDecodingStore::Instance().CacheEntries());
EXPECT_EQ(4u, ImageDecodingStore::Instance().MemoryUsageInBytes());
ImageDecoder* test_decoder;
EXPECT_TRUE(ImageDecodingStore::Instance().LockDecoder(
generator_.get(), size, ImageDecoder::kAlphaPremultiplied,
- &test_decoder));
+ cc::PaintImage::kDefaultGeneratorClientId, &test_decoder));
EXPECT_TRUE(test_decoder);
EXPECT_EQ(ref_decoder, test_decoder);
- ImageDecodingStore::Instance().UnlockDecoder(generator_.get(), test_decoder);
+ ImageDecodingStore::Instance().UnlockDecoder(
+ generator_.get(), cc::PaintImage::kDefaultGeneratorClientId,
+ test_decoder);
EXPECT_EQ(1, ImageDecodingStore::Instance().CacheEntries());
}
@@ -101,12 +104,15 @@ TEST_F(ImageDecodingStoreTest, evictDecoder) {
decoder1->SetSize(1, 1);
decoder2->SetSize(2, 2);
decoder3->SetSize(3, 3);
- ImageDecodingStore::Instance().InsertDecoder(generator_.get(),
- std::move(decoder1));
- ImageDecodingStore::Instance().InsertDecoder(generator_.get(),
- std::move(decoder2));
- ImageDecodingStore::Instance().InsertDecoder(generator_.get(),
- std::move(decoder3));
+ ImageDecodingStore::Instance().InsertDecoder(
+ generator_.get(), cc::PaintImage::kDefaultGeneratorClientId,
+ std::move(decoder1));
+ ImageDecodingStore::Instance().InsertDecoder(
+ generator_.get(), cc::PaintImage::kDefaultGeneratorClientId,
+ std::move(decoder2));
+ ImageDecodingStore::Instance().InsertDecoder(
+ generator_.get(), cc::PaintImage::kDefaultGeneratorClientId,
+ std::move(decoder3));
EXPECT_EQ(3, ImageDecodingStore::Instance().CacheEntries());
EXPECT_EQ(56u, ImageDecodingStore::Instance().MemoryUsageInBytes());
@@ -130,18 +136,21 @@ TEST_F(ImageDecodingStoreTest, decoderInUseNotEvicted) {
decoder1->SetSize(1, 1);
decoder2->SetSize(2, 2);
decoder3->SetSize(3, 3);
- ImageDecodingStore::Instance().InsertDecoder(generator_.get(),
- std::move(decoder1));
- ImageDecodingStore::Instance().InsertDecoder(generator_.get(),
- std::move(decoder2));
- ImageDecodingStore::Instance().InsertDecoder(generator_.get(),
- std::move(decoder3));
+ ImageDecodingStore::Instance().InsertDecoder(
+ generator_.get(), cc::PaintImage::kDefaultGeneratorClientId,
+ std::move(decoder1));
+ ImageDecodingStore::Instance().InsertDecoder(
+ generator_.get(), cc::PaintImage::kDefaultGeneratorClientId,
+ std::move(decoder2));
+ ImageDecodingStore::Instance().InsertDecoder(
+ generator_.get(), cc::PaintImage::kDefaultGeneratorClientId,
+ std::move(decoder3));
EXPECT_EQ(3, ImageDecodingStore::Instance().CacheEntries());
ImageDecoder* test_decoder;
EXPECT_TRUE(ImageDecodingStore::Instance().LockDecoder(
generator_.get(), SkISize::Make(2, 2), ImageDecoder::kAlphaPremultiplied,
- &test_decoder));
+ cc::PaintImage::kDefaultGeneratorClientId, &test_decoder));
EvictOneCache();
EvictOneCache();
@@ -149,7 +158,9 @@ TEST_F(ImageDecodingStoreTest, decoderInUseNotEvicted) {
EXPECT_EQ(1, ImageDecodingStore::Instance().CacheEntries());
EXPECT_EQ(16u, ImageDecodingStore::Instance().MemoryUsageInBytes());
- ImageDecodingStore::Instance().UnlockDecoder(generator_.get(), test_decoder);
+ ImageDecodingStore::Instance().UnlockDecoder(
+ generator_.get(), cc::PaintImage::kDefaultGeneratorClientId,
+ test_decoder);
EvictOneCache();
EXPECT_FALSE(ImageDecodingStore::Instance().CacheEntries());
EXPECT_FALSE(ImageDecodingStore::Instance().MemoryUsageInBytes());
@@ -160,23 +171,66 @@ TEST_F(ImageDecodingStoreTest, removeDecoder) {
std::unique_ptr<ImageDecoder> decoder = MockImageDecoder::Create(this);
decoder->SetSize(1, 1);
const ImageDecoder* ref_decoder = decoder.get();
- ImageDecodingStore::Instance().InsertDecoder(generator_.get(),
- std::move(decoder));
+ ImageDecodingStore::Instance().InsertDecoder(
+ generator_.get(), cc::PaintImage::kDefaultGeneratorClientId,
+ std::move(decoder));
EXPECT_EQ(1, ImageDecodingStore::Instance().CacheEntries());
EXPECT_EQ(4u, ImageDecodingStore::Instance().MemoryUsageInBytes());
ImageDecoder* test_decoder;
EXPECT_TRUE(ImageDecodingStore::Instance().LockDecoder(
generator_.get(), size, ImageDecoder::kAlphaPremultiplied,
- &test_decoder));
+ cc::PaintImage::kDefaultGeneratorClientId, &test_decoder));
EXPECT_TRUE(test_decoder);
EXPECT_EQ(ref_decoder, test_decoder);
- ImageDecodingStore::Instance().RemoveDecoder(generator_.get(), test_decoder);
+ ImageDecodingStore::Instance().RemoveDecoder(
+ generator_.get(), cc::PaintImage::kDefaultGeneratorClientId,
+ test_decoder);
EXPECT_FALSE(ImageDecodingStore::Instance().CacheEntries());
EXPECT_FALSE(ImageDecodingStore::Instance().LockDecoder(
generator_.get(), size, ImageDecoder::kAlphaPremultiplied,
- &test_decoder));
+ cc::PaintImage::kDefaultGeneratorClientId, &test_decoder));
+}
+
+TEST_F(ImageDecodingStoreTest, MultipleClientsForSameGenerator) {
+ ImageDecodingStore::Instance().Clear();
+ ASSERT_EQ(ImageDecodingStore::Instance().CacheEntries(), 0);
+
+ const SkISize size = SkISize::Make(1, 1);
+
+ std::unique_ptr<ImageDecoder> decoder = MockImageDecoder::Create(this);
+ ImageDecoder* decoder_1 = decoder.get();
+ decoder_1->SetSize(1, 1);
+ auto client_id_1 = cc::PaintImage::GetNextGeneratorClientId();
+ ImageDecodingStore::Instance().InsertDecoder(generator_.get(), client_id_1,
+ std::move(decoder));
+ EXPECT_EQ(ImageDecodingStore::Instance().CacheEntries(), 1);
+
+ decoder = MockImageDecoder::Create(this);
+ ImageDecoder* decoder_2 = decoder.get();
+ decoder_2->SetSize(1, 1);
+ auto client_id_2 = cc::PaintImage::GetNextGeneratorClientId();
+ ImageDecodingStore::Instance().InsertDecoder(generator_.get(), client_id_2,
+ std::move(decoder));
+ EXPECT_EQ(ImageDecodingStore::Instance().CacheEntries(), 2);
+
+ ImageDecoder* cached_decoder = nullptr;
+ ImageDecodingStore::Instance().LockDecoder(generator_.get(), size,
+ ImageDecoder::kAlphaPremultiplied,
+ client_id_1, &cached_decoder);
+ EXPECT_EQ(decoder_1, cached_decoder);
+
+ ImageDecodingStore::Instance().LockDecoder(generator_.get(), size,
+ ImageDecoder::kAlphaPremultiplied,
+ client_id_2, &cached_decoder);
+ EXPECT_EQ(decoder_2, cached_decoder);
+
+ ImageDecodingStore::Instance().RemoveDecoder(generator_.get(), client_id_1,
+ decoder_1);
+ ImageDecodingStore::Instance().RemoveDecoder(generator_.get(), client_id_2,
+ decoder_2);
+ EXPECT_EQ(ImageDecodingStore::Instance().CacheEntries(), 0);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/image_frame_generator.cc b/chromium/third_party/blink/renderer/platform/graphics/image_frame_generator.cc
index 660c7551498..0b3c8d3cf11 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/image_frame_generator.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/image_frame_generator.cc
@@ -30,6 +30,7 @@
#include "SkData.h"
#include "base/macros.h"
+#include "third_party/blink/renderer/platform/graphics/image_decoder_wrapper.h"
#include "third_party/blink/renderer/platform/graphics/image_decoding_store.h"
#include "third_party/blink/renderer/platform/image-decoders/image_decoder.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
@@ -37,67 +38,6 @@
namespace blink {
-static void CopyPixels(void* dst_addr,
- size_t dst_row_bytes,
- const void* src_addr,
- size_t src_row_bytes,
- const SkImageInfo& info) {
- size_t row_bytes = info.bytesPerPixel() * info.width();
- for (int y = 0; y < info.height(); ++y) {
- memcpy(dst_addr, src_addr, row_bytes);
- src_addr = static_cast<const char*>(src_addr) + src_row_bytes;
- dst_addr = static_cast<char*>(dst_addr) + dst_row_bytes;
- }
-}
-
-static bool CompatibleInfo(const SkImageInfo& src, const SkImageInfo& dst) {
- if (src == dst)
- return true;
-
- // It is legal to write kOpaque_SkAlphaType pixels into a kPremul_SkAlphaType
- // buffer. This can happen when DeferredImageDecoder allocates an
- // kOpaque_SkAlphaType image generator based on cached frame info, while the
- // ImageFrame-allocated dest bitmap stays kPremul_SkAlphaType.
- if (src.alphaType() == kOpaque_SkAlphaType &&
- dst.alphaType() == kPremul_SkAlphaType) {
- const SkImageInfo& tmp = src.makeAlphaType(kPremul_SkAlphaType);
- return tmp == dst;
- }
-
- return false;
-}
-
-// Creates a SkPixelRef such that the memory for pixels is given by an external
-// body. This is used to write directly to the memory given by Skia during
-// decoding.
-class ExternalMemoryAllocator final : public SkBitmap::Allocator {
- USING_FAST_MALLOC(ExternalMemoryAllocator);
-
- public:
- ExternalMemoryAllocator(const SkImageInfo& info,
- void* pixels,
- size_t row_bytes)
- : info_(info), pixels_(pixels), row_bytes_(row_bytes) {}
-
- bool allocPixelRef(SkBitmap* dst) override {
- const SkImageInfo& info = dst->info();
- if (kUnknown_SkColorType == info.colorType())
- return false;
-
- if (!CompatibleInfo(info_, info) || row_bytes_ != dst->rowBytes())
- return false;
-
- return dst->installPixels(info, pixels_, row_bytes_);
- }
-
- private:
- SkImageInfo info_;
- void* pixels_;
- size_t row_bytes_;
-
- DISALLOW_COPY_AND_ASSIGN(ExternalMemoryAllocator);
-};
-
static bool UpdateYUVComponentSizes(ImageDecoder* decoder,
SkISize component_sizes[3],
size_t component_width_bytes[3]) {
@@ -120,9 +60,6 @@ ImageFrameGenerator::ImageFrameGenerator(const SkISize& full_size,
: full_size_(full_size),
decoder_color_behavior_(color_behavior),
is_multi_frame_(is_multi_frame),
- decode_failed_(false),
- yuv_decoding_failed_(false),
- frame_count_(0),
supported_sizes_(std::move(supported_sizes)) {
#if DCHECK_IS_ON()
// Verify that sizes are in an increasing order, since
@@ -146,45 +83,63 @@ bool ImageFrameGenerator::DecodeAndScale(
const SkImageInfo& info,
void* pixels,
size_t row_bytes,
- ImageDecoder::AlphaOption alpha_option) {
- if (decode_failed_)
- return false;
-
- TRACE_EVENT1("blink", "ImageFrameGenerator::decodeAndScale", "frame index",
- static_cast<int>(index));
+ ImageDecoder::AlphaOption alpha_option,
+ cc::PaintImage::GeneratorClientId client_id) {
+ {
+ MutexLocker lock(generator_mutex_);
+ if (decode_failed_)
+ return false;
+ }
- // Lock the mutex, so only one thread can use the decoder at once.
- MutexLocker lock(decode_mutex_);
+ TRACE_EVENT1("blink", "ImageFrameGenerator::decodeAndScale", "generator",
+ this);
// This implementation does not support arbitrary scaling so check the
// requested size.
SkISize scaled_size = SkISize::Make(info.width(), info.height());
CHECK(GetSupportedDecodeSize(scaled_size) == scaled_size);
- // It is okay to allocate ref-counted ExternalMemoryAllocator on the stack,
- // because 1) it contains references to memory that will be invalid after
- // returning (i.e. a pointer to |pixels|) and therefore 2) should not live
- // longer than the call to the current method.
- ExternalMemoryAllocator external_allocator(info, pixels, row_bytes);
ImageDecoder::HighBitDepthDecodingOption high_bit_depth_decoding_option =
ImageDecoder::kDefaultBitDepth;
if (info.colorType() == kRGBA_F16_SkColorType) {
high_bit_depth_decoding_option = ImageDecoder::kHighBitDepthToHalfFloat;
}
- SkBitmap bitmap = TryToResumeDecode(
- data, all_data_received, index, scaled_size, external_allocator,
- alpha_option, high_bit_depth_decoding_option);
- DCHECK(external_allocator.unique()); // Verify we have the only ref-count.
- if (bitmap.isNull())
+ size_t frame_count = 0u;
+ bool has_alpha = true;
+
+ // |decode_failed| indicates a failure due to a corrupt image.
+ bool decode_failed = false;
+ // |current_decode_succeeded| indicates a failure to decode the current frame.
+ // Its possible to have a valid but fail to decode a frame in the case where
+ // we don't have enough data to decode this particular frame yet.
+ bool current_decode_succeeded = false;
+ {
+ // Lock the mutex, so only one thread can use the decoder at once.
+ ClientMutexLocker lock(this, client_id);
+ ImageDecoderWrapper decoder_wrapper(
+ this, data, scaled_size, alpha_option, decoder_color_behavior_,
+ high_bit_depth_decoding_option, index, info, pixels, row_bytes,
+ all_data_received, client_id);
+ current_decode_succeeded = decoder_wrapper.Decode(
+ image_decoder_factory_.get(), &frame_count, &has_alpha);
+ decode_failed = decoder_wrapper.decode_failed();
+ }
+
+ MutexLocker lock(generator_mutex_);
+ decode_failed_ = decode_failed;
+ if (decode_failed_) {
+ DCHECK(!current_decode_succeeded);
return false;
+ }
+
+ if (!current_decode_succeeded)
+ return false;
+
+ SetHasAlpha(index, has_alpha);
+ if (frame_count != 0u)
+ frame_count_ = frame_count;
- // Check to see if the decoder has written directly to the pixel memory
- // provided. If not, make a copy.
- DCHECK_EQ(bitmap.width(), scaled_size.width());
- DCHECK_EQ(bitmap.height(), scaled_size.height());
- if (bitmap.getPixels() != pixels)
- CopyPixels(pixels, row_bytes, bitmap.getPixels(), bitmap.rowBytes(), info);
return true;
}
@@ -193,6 +148,8 @@ bool ImageFrameGenerator::DecodeToYUV(SegmentReader* data,
const SkISize component_sizes[3],
void* planes[3],
const size_t row_bytes[3]) {
+ MutexLocker lock(generator_mutex_);
+
// TODO (scroggo): The only interesting thing this uses from the
// ImageFrameGenerator is m_decodeFailed. Move this into
// DecodingImageGenerator, which is the only class that calls it.
@@ -231,90 +188,9 @@ bool ImageFrameGenerator::DecodeToYUV(SegmentReader* data,
return false;
}
-SkBitmap ImageFrameGenerator::TryToResumeDecode(
- SegmentReader* data,
- bool all_data_received,
- size_t index,
- const SkISize& scaled_size,
- SkBitmap::Allocator& allocator,
- ImageDecoder::AlphaOption alpha_option,
- ImageDecoder::HighBitDepthDecodingOption high_bit_depth_decoding_option) {
-#if DCHECK_IS_ON()
- DCHECK(decode_mutex_.Locked());
-#endif
-
- TRACE_EVENT1("blink", "ImageFrameGenerator::tryToResumeDecode", "frame index",
- static_cast<int>(index));
-
- ImageDecoder* decoder = nullptr;
- const bool resume_decoding = ImageDecodingStore::Instance().LockDecoder(
- this, scaled_size, alpha_option, &decoder);
- DCHECK(!resume_decoding || decoder);
-
- bool used_external_allocator = false;
- ImageFrame* current_frame = Decode(
- data, all_data_received, index, &decoder, allocator, alpha_option,
- high_bit_depth_decoding_option, scaled_size, used_external_allocator);
-
- if (!decoder)
- return SkBitmap();
-
- // If we are not resuming decoding that means the decoder is freshly
- // created and we have ownership. If we are resuming decoding then
- // the decoder is owned by ImageDecodingStore.
- std::unique_ptr<ImageDecoder> decoder_container;
- if (!resume_decoding)
- decoder_container = base::WrapUnique(decoder);
-
- if (!current_frame || current_frame->Bitmap().isNull()) {
- // If decoding has failed, we can save work in the future by
- // ignoring further requests to decode the image.
- decode_failed_ = decoder->Failed();
- if (resume_decoding)
- ImageDecodingStore::Instance().UnlockDecoder(this, decoder);
- return SkBitmap();
- }
-
- SkBitmap scaled_size_bitmap = current_frame->Bitmap();
- DCHECK_EQ(scaled_size_bitmap.width(), scaled_size.width());
- DCHECK_EQ(scaled_size_bitmap.height(), scaled_size.height());
- SetHasAlpha(index, !scaled_size_bitmap.isOpaque());
-
- // Free as much memory as possible. For single-frame images, we can
- // just delete the decoder entirely if they use the external allocator.
- // For multi-frame images, we keep the decoder around in order to preserve
- // decoded information such as the required previous frame indexes, but if
- // we've reached the last frame we can at least delete all the cached frames.
- // (If we were to do this before reaching the last frame, any subsequent
- // requested frames which relied on the current frame would trigger extra
- // re-decoding of all frames in the dependency chain.
- bool remove_decoder = false;
- if (current_frame->GetStatus() == ImageFrame::kFrameComplete ||
- all_data_received) {
- if (!is_multi_frame_) {
- remove_decoder = true;
- } else if (index == frame_count_ - 1) {
- decoder->ClearCacheExceptFrame(kNotFound);
- }
- } else if (used_external_allocator) {
- remove_decoder = true;
- }
-
- if (resume_decoding) {
- if (remove_decoder)
- ImageDecodingStore::Instance().RemoveDecoder(this, decoder);
- else
- ImageDecodingStore::Instance().UnlockDecoder(this, decoder);
- } else if (!remove_decoder) {
- ImageDecodingStore::Instance().InsertDecoder(this,
- std::move(decoder_container));
- }
-
- return scaled_size_bitmap;
-}
-
void ImageFrameGenerator::SetHasAlpha(size_t index, bool has_alpha) {
- MutexLocker lock(alpha_mutex_);
+ generator_mutex_.AssertAcquired();
+
if (index >= has_alpha_.size()) {
const size_t old_size = has_alpha_.size();
has_alpha_.resize(index + 1);
@@ -324,95 +200,9 @@ void ImageFrameGenerator::SetHasAlpha(size_t index, bool has_alpha) {
has_alpha_[index] = has_alpha;
}
-ImageFrame* ImageFrameGenerator::Decode(
- SegmentReader* data,
- bool all_data_received,
- size_t index,
- ImageDecoder** decoder,
- SkBitmap::Allocator& allocator,
- ImageDecoder::AlphaOption alpha_option,
- ImageDecoder::HighBitDepthDecodingOption high_bit_depth_decoding_option,
- const SkISize& scaled_size,
- bool& used_external_allocator) {
-#if DCHECK_IS_ON()
- DCHECK(decode_mutex_.Locked());
-#endif
- TRACE_EVENT2("blink", "ImageFrameGenerator::decode", "width",
- full_size_.width(), "height", full_size_.height());
-
- // Try to create an ImageDecoder if we are not given one.
- DCHECK(decoder);
- bool new_decoder = false;
- bool should_call_set_data = true;
- if (!*decoder) {
- new_decoder = true;
- // TODO(vmpstr): The factory is only used for tests. We can convert all
- // calls to use a factory so that we don't need to worry about this call.
- if (image_decoder_factory_)
- *decoder = image_decoder_factory_->Create().release();
-
- if (!*decoder) {
- *decoder = ImageDecoder::Create(data, all_data_received, alpha_option,
- high_bit_depth_decoding_option,
- decoder_color_behavior_, scaled_size)
- .release();
- // The newly created decoder just grabbed the data. No need to reset it.
- should_call_set_data = false;
- }
-
- if (!*decoder)
- return nullptr;
- }
-
- if (should_call_set_data)
- (*decoder)->SetData(data, all_data_received);
-
- // 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
- // decoder, particularly with GIF.
- if (all_data_received)
- frame_count_ = (*decoder)->FrameCount();
-
- used_external_allocator = false;
- // External allocators don't work for multi-frame images right now.
- if (!is_multi_frame_) {
- if (Platform::Current()->IsLowEndDevice()) {
- // On low-end devices, always use the external allocator, to avoid
- // storing duplicate copies of the data in the ImageDecoder's cache.
- used_external_allocator = true;
- DCHECK(new_decoder);
- // TODO (scroggo): If !is_multi_frame_ && new_decoder && frame_count_, it
- // should always be the case that 1u == frame_count_. But it looks like it
- // is currently possible for frame_count_ to be another value.
- } else if (1u == frame_count_ && all_data_received && new_decoder) {
- // Also use external allocator situations when all of the data has been
- // received and there is not already a partial cache in the image decoder.
- used_external_allocator = true;
- }
- }
-
- if (used_external_allocator)
- (*decoder)->SetMemoryAllocator(&allocator);
-
- ImageFrame* frame = (*decoder)->DecodeFrameBufferAtIndex(index);
-
- // SetMemoryAllocator() can try to access decoder's data, so
- // we have to do it before clearing SegmentReader.
- if (used_external_allocator)
- (*decoder)->SetMemoryAllocator(nullptr);
- (*decoder)->SetData(scoped_refptr<SegmentReader>(nullptr),
- false); // Unref SegmentReader from ImageDecoder.
- (*decoder)->ClearCacheExceptFrame(index);
-
- if (!frame || frame->GetStatus() == ImageFrame::kFrameEmpty)
- return nullptr;
-
- return frame;
-}
-
bool ImageFrameGenerator::HasAlpha(size_t index) {
- MutexLocker lock(alpha_mutex_);
+ MutexLocker lock(generator_mutex_);
+
if (index < has_alpha_.size())
return has_alpha_[index];
return true;
@@ -423,6 +213,8 @@ bool ImageFrameGenerator::GetYUVComponentSizes(SegmentReader* data,
TRACE_EVENT2("blink", "ImageFrameGenerator::getYUVComponentSizes", "width",
full_size_.width(), "height", full_size_.height());
+ MutexLocker lock(generator_mutex_);
+
if (yuv_decoding_failed_)
return false;
@@ -454,4 +246,35 @@ SkISize ImageFrameGenerator::GetSupportedDecodeSize(
return full_size_;
}
+ImageFrameGenerator::ClientMutexLocker::ClientMutexLocker(
+ ImageFrameGenerator* generator,
+ cc::PaintImage::GeneratorClientId client_id)
+ : generator_(generator), client_id_(client_id) {
+ {
+ MutexLocker lock(generator_->generator_mutex_);
+ ClientMutex* client_mutex = nullptr;
+ auto it = generator_->mutex_map_.find(client_id_);
+ if (it == generator_->mutex_map_.end())
+ client_mutex = &generator_->mutex_map_[client_id];
+ else
+ client_mutex = &it->second;
+ client_mutex->ref_count++;
+ mutex_ = &client_mutex->mutex;
+ }
+
+ mutex_->lock();
+}
+
+ImageFrameGenerator::ClientMutexLocker::~ClientMutexLocker() {
+ mutex_->unlock();
+
+ MutexLocker lock(generator_->generator_mutex_);
+ auto it = generator_->mutex_map_.find(client_id_);
+ DCHECK(it != generator_->mutex_map_.end());
+ it->second.ref_count--;
+
+ if (it->second.ref_count == 0)
+ generator_->mutex_map_.erase(it);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/image_frame_generator.h b/chromium/third_party/blink/renderer/platform/graphics/image_frame_generator.h
index 0e972e53142..593722cf6c5 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/image_frame_generator.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/image_frame_generator.h
@@ -30,6 +30,7 @@
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
+#include "cc/paint/paint_image.h"
#include "third_party/blink/renderer/platform/image-decoders/image_decoder.h"
#include "third_party/blink/renderer/platform/image-decoders/segment_reader.h"
#include "third_party/blink/renderer/platform/platform_export.h"
@@ -85,7 +86,8 @@ class PLATFORM_EXPORT ImageFrameGenerator final
const SkImageInfo&,
void* pixels,
size_t row_bytes,
- ImageDecoder::AlphaOption);
+ ImageDecoder::AlphaOption,
+ cc::PaintImage::GeneratorClientId);
// Decodes YUV components directly into the provided memory planes. Must not
// be called unless getYUVComponentSizes has been called and returned true.
@@ -113,6 +115,18 @@ class PLATFORM_EXPORT ImageFrameGenerator final
bool GetYUVComponentSizes(SegmentReader*, SkYUVSizeInfo*);
private:
+ class ClientMutexLocker {
+ public:
+ ClientMutexLocker(ImageFrameGenerator* generator,
+ cc::PaintImage::GeneratorClientId client_id);
+ ~ClientMutexLocker();
+
+ private:
+ ImageFrameGenerator* generator_;
+ cc::PaintImage::GeneratorClientId client_id_;
+ Mutex* mutex_;
+ };
+
ImageFrameGenerator(const SkISize& full_size,
bool is_multi_frame,
const ColorBehavior&,
@@ -128,46 +142,30 @@ class PLATFORM_EXPORT ImageFrameGenerator final
void SetHasAlpha(size_t index, bool has_alpha);
- SkBitmap TryToResumeDecode(SegmentReader*,
- bool all_data_received,
- size_t index,
- const SkISize& scaled_size,
- SkBitmap::Allocator&,
- ImageDecoder::AlphaOption,
- ImageDecoder::HighBitDepthDecodingOption);
- // This method should only be called while decode_mutex_ is locked.
- // Returns a pointer to frame |index|'s ImageFrame, if available.
- // Sets |used_external_allocator| to true if the the image was decoded into
- // |external_allocator|'s memory.
- ImageFrame* Decode(SegmentReader*,
- bool all_data_received,
- size_t index,
- ImageDecoder**,
- SkBitmap::Allocator& external_allocator,
- ImageDecoder::AlphaOption,
- ImageDecoder::HighBitDepthDecodingOption,
- const SkISize& scaled_size,
- bool& used_external_allocator);
-
const SkISize full_size_;
-
// Parameters used to create internal ImageDecoder objects.
const ColorBehavior decoder_color_behavior_;
-
const bool is_multi_frame_;
- bool decode_failed_;
- bool yuv_decoding_failed_;
- size_t frame_count_;
- Vector<bool> has_alpha_;
- std::vector<SkISize> supported_sizes_;
+ const std::vector<SkISize> supported_sizes_;
- std::unique_ptr<ImageDecoderFactory> image_decoder_factory_;
+ // Prevents concurrent access to all variables below.
+ Mutex generator_mutex_;
+
+ bool decode_failed_ = false;
+ bool yuv_decoding_failed_ = false;
+ size_t frame_count_ = 0u;
+ Vector<bool> has_alpha_;
- // Prevents multiple decode operations on the same data.
- Mutex decode_mutex_;
+ struct ClientMutex {
+ int ref_count = 0;
+ Mutex mutex;
+ };
+ // Note that it is necessary to use unordered_map here to ensure that
+ // references to entries in the map, stored in ClientMutexLocker, remain valid
+ // across insertions into the map.
+ std::unordered_map<cc::PaintImage::GeneratorClientId, ClientMutex> mutex_map_;
- // Protect concurrent access to has_alpha_.
- Mutex alpha_mutex_;
+ std::unique_ptr<ImageDecoderFactory> image_decoder_factory_;
DISALLOW_COPY_AND_ASSIGN(ImageFrameGenerator);
};
diff --git a/chromium/third_party/blink/renderer/platform/graphics/image_frame_generator_test.cc b/chromium/third_party/blink/renderer/platform/graphics/image_frame_generator_test.cc
index b9ad8b751f3..d4e87e9113b 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/image_frame_generator_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/image_frame_generator_test.cc
@@ -164,15 +164,15 @@ TEST_F(ImageFrameGeneratorTest, incompleteDecode) {
char buffer[100 * 100 * 4];
generator_->DecodeAndScale(segment_reader_.get(), false, 0, ImageInfo(),
- buffer, 100 * 4,
- ImageDecoder::kAlphaPremultiplied);
+ buffer, 100 * 4, ImageDecoder::kAlphaPremultiplied,
+ cc::PaintImage::kDefaultGeneratorClientId);
EXPECT_EQ(1, decode_request_count_);
EXPECT_EQ(0, memory_allocator_set_count_);
AddNewData();
generator_->DecodeAndScale(segment_reader_.get(), false, 0, ImageInfo(),
- buffer, 100 * 4,
- ImageDecoder::kAlphaPremultiplied);
+ buffer, 100 * 4, ImageDecoder::kAlphaPremultiplied,
+ cc::PaintImage::kDefaultGeneratorClientId);
EXPECT_EQ(2, decode_request_count_);
EXPECT_EQ(0, decoders_destroyed_);
EXPECT_EQ(0, memory_allocator_set_count_);
@@ -191,8 +191,8 @@ TEST_F(ImageFrameGeneratorTest, LowEndDeviceDestroysDecoderOnPartialDecode) {
char buffer[100 * 100 * 4];
generator_->DecodeAndScale(segment_reader_.get(), false, 0, ImageInfo(),
- buffer, 100 * 4,
- ImageDecoder::kAlphaPremultiplied);
+ buffer, 100 * 4, ImageDecoder::kAlphaPremultiplied,
+ cc::PaintImage::kDefaultGeneratorClientId);
EXPECT_EQ(1, decode_request_count_);
EXPECT_EQ(1, decoders_destroyed_);
// The memory allocator is set to the external one, then cleared after decode.
@@ -200,8 +200,8 @@ TEST_F(ImageFrameGeneratorTest, LowEndDeviceDestroysDecoderOnPartialDecode) {
AddNewData();
generator_->DecodeAndScale(segment_reader_.get(), false, 0, ImageInfo(),
- buffer, 100 * 4,
- ImageDecoder::kAlphaPremultiplied);
+ buffer, 100 * 4, ImageDecoder::kAlphaPremultiplied,
+ cc::PaintImage::kDefaultGeneratorClientId);
EXPECT_EQ(2, decode_request_count_);
EXPECT_EQ(2, decoders_destroyed_);
// The memory allocator is set to the external one, then cleared after decode.
@@ -213,8 +213,8 @@ TEST_F(ImageFrameGeneratorTest, incompleteDecodeBecomesComplete) {
char buffer[100 * 100 * 4];
generator_->DecodeAndScale(segment_reader_.get(), false, 0, ImageInfo(),
- buffer, 100 * 4,
- ImageDecoder::kAlphaPremultiplied);
+ buffer, 100 * 4, ImageDecoder::kAlphaPremultiplied,
+ cc::PaintImage::kDefaultGeneratorClientId);
EXPECT_EQ(1, decode_request_count_);
EXPECT_EQ(0, decoders_destroyed_);
EXPECT_EQ(0, memory_allocator_set_count_);
@@ -223,15 +223,15 @@ TEST_F(ImageFrameGeneratorTest, incompleteDecodeBecomesComplete) {
AddNewData();
generator_->DecodeAndScale(segment_reader_.get(), false, 0, ImageInfo(),
- buffer, 100 * 4,
- ImageDecoder::kAlphaPremultiplied);
+ buffer, 100 * 4, ImageDecoder::kAlphaPremultiplied,
+ cc::PaintImage::kDefaultGeneratorClientId);
EXPECT_EQ(2, decode_request_count_);
EXPECT_EQ(1, decoders_destroyed_);
// Decoder created again.
generator_->DecodeAndScale(segment_reader_.get(), false, 0, ImageInfo(),
- buffer, 100 * 4,
- ImageDecoder::kAlphaPremultiplied);
+ buffer, 100 * 4, ImageDecoder::kAlphaPremultiplied,
+ cc::PaintImage::kDefaultGeneratorClientId);
EXPECT_EQ(3, decode_request_count_);
}
@@ -239,7 +239,8 @@ static void DecodeThreadMain(ImageFrameGenerator* generator,
SegmentReader* segment_reader) {
char buffer[100 * 100 * 4];
generator->DecodeAndScale(segment_reader, false, 0, ImageInfo(), buffer,
- 100 * 4, ImageDecoder::kAlphaPremultiplied);
+ 100 * 4, ImageDecoder::kAlphaPremultiplied,
+ cc::PaintImage::kDefaultGeneratorClientId);
}
TEST_F(ImageFrameGeneratorTest, incompleteDecodeBecomesCompleteMultiThreaded) {
@@ -247,8 +248,8 @@ TEST_F(ImageFrameGeneratorTest, incompleteDecodeBecomesCompleteMultiThreaded) {
char buffer[100 * 100 * 4];
generator_->DecodeAndScale(segment_reader_.get(), false, 0, ImageInfo(),
- buffer, 100 * 4,
- ImageDecoder::kAlphaPremultiplied);
+ buffer, 100 * 4, ImageDecoder::kAlphaPremultiplied,
+ cc::PaintImage::kDefaultGeneratorClientId);
EXPECT_EQ(1, decode_request_count_);
EXPECT_EQ(0, decoders_destroyed_);
@@ -268,8 +269,8 @@ TEST_F(ImageFrameGeneratorTest, incompleteDecodeBecomesCompleteMultiThreaded) {
// Decoder created again.
generator_->DecodeAndScale(segment_reader_.get(), false, 0, ImageInfo(),
- buffer, 100 * 4,
- ImageDecoder::kAlphaPremultiplied);
+ buffer, 100 * 4, ImageDecoder::kAlphaPremultiplied,
+ cc::PaintImage::kDefaultGeneratorClientId);
EXPECT_EQ(3, decode_request_count_);
AddNewData();
@@ -283,24 +284,26 @@ TEST_F(ImageFrameGeneratorTest, frameHasAlpha) {
char buffer[100 * 100 * 4];
generator_->DecodeAndScale(segment_reader_.get(), false, 0, ImageInfo(),
- buffer, 100 * 4,
- ImageDecoder::kAlphaPremultiplied);
+ buffer, 100 * 4, ImageDecoder::kAlphaPremultiplied,
+ cc::PaintImage::kDefaultGeneratorClientId);
EXPECT_TRUE(generator_->HasAlpha(0));
EXPECT_EQ(1, decode_request_count_);
ImageDecoder* temp_decoder = nullptr;
EXPECT_TRUE(ImageDecodingStore::Instance().LockDecoder(
generator_.get(), FullSize(), ImageDecoder::kAlphaPremultiplied,
- &temp_decoder));
+ cc::PaintImage::kDefaultGeneratorClientId, &temp_decoder));
ASSERT_TRUE(temp_decoder);
temp_decoder->DecodeFrameBufferAtIndex(0)->SetHasAlpha(false);
- ImageDecodingStore::Instance().UnlockDecoder(generator_.get(), temp_decoder);
+ ImageDecodingStore::Instance().UnlockDecoder(
+ generator_.get(), cc::PaintImage::kDefaultGeneratorClientId,
+ temp_decoder);
EXPECT_EQ(2, decode_request_count_);
SetFrameStatus(ImageFrame::kFrameComplete);
generator_->DecodeAndScale(segment_reader_.get(), false, 0, ImageInfo(),
- buffer, 100 * 4,
- ImageDecoder::kAlphaPremultiplied);
+ buffer, 100 * 4, ImageDecoder::kAlphaPremultiplied,
+ cc::PaintImage::kDefaultGeneratorClientId);
EXPECT_EQ(3, decode_request_count_);
EXPECT_FALSE(generator_->HasAlpha(0));
}
@@ -311,8 +314,8 @@ TEST_F(ImageFrameGeneratorTest, clearMultiFrameDecoder) {
char buffer[100 * 100 * 4];
generator_->DecodeAndScale(segment_reader_.get(), true, 0, ImageInfo(),
- buffer, 100 * 4,
- ImageDecoder::kAlphaPremultiplied);
+ buffer, 100 * 4, ImageDecoder::kAlphaPremultiplied,
+ cc::PaintImage::kDefaultGeneratorClientId);
EXPECT_EQ(1, decode_request_count_);
EXPECT_EQ(0, decoders_destroyed_);
EXPECT_EQ(0U, requested_clear_except_frame_);
@@ -320,8 +323,8 @@ TEST_F(ImageFrameGeneratorTest, clearMultiFrameDecoder) {
SetFrameStatus(ImageFrame::kFrameComplete);
generator_->DecodeAndScale(segment_reader_.get(), true, 1, ImageInfo(),
- buffer, 100 * 4,
- ImageDecoder::kAlphaPremultiplied);
+ buffer, 100 * 4, ImageDecoder::kAlphaPremultiplied,
+ cc::PaintImage::kDefaultGeneratorClientId);
EXPECT_EQ(2, decode_request_count_);
EXPECT_EQ(0, decoders_destroyed_);
EXPECT_EQ(1U, requested_clear_except_frame_);
@@ -332,8 +335,8 @@ TEST_F(ImageFrameGeneratorTest, clearMultiFrameDecoder) {
// all the frame data, but not destroying the decoder. See comments in
// ImageFrameGenerator::tryToResumeDecode().
generator_->DecodeAndScale(segment_reader_.get(), true, 2, ImageInfo(),
- buffer, 100 * 4,
- ImageDecoder::kAlphaPremultiplied);
+ buffer, 100 * 4, ImageDecoder::kAlphaPremultiplied,
+ cc::PaintImage::kDefaultGeneratorClientId);
EXPECT_EQ(3, decode_request_count_);
EXPECT_EQ(0, decoders_destroyed_);
EXPECT_EQ(kNotFound, requested_clear_except_frame_);
diff --git a/chromium/third_party/blink/renderer/platform/graphics/image_layer_chromium_test.cc b/chromium/third_party/blink/renderer/platform/graphics/image_layer_chromium_test.cc
index 25de4618f8a..bd11e25e145 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/image_layer_chromium_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/image_layer_chromium_test.cc
@@ -131,7 +131,9 @@ TEST(ImageLayerChromiumTest, opaqueImages) {
graphics_layer->SetContentsToImage(opaque_image.get(),
Image::kUnspecifiedDecode);
- ASSERT_TRUE(graphics_layer->ContentsLayer()->contents_opaque());
+ // This would normally have contents_opaque set but due to crbug.com/870857,
+ // we cannot set image layers as having contents_opaque.
+ ASSERT_FALSE(graphics_layer->ContentsLayer()->contents_opaque());
graphics_layer->SetContentsToImage(non_opaque_image.get(),
Image::kUnspecifiedDecode);
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 482a437fdfb..f17b64acc09 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/intercepting_canvas.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/intercepting_canvas.h
@@ -130,11 +130,6 @@ class InterceptingCanvasBase : public SkCanvas {
const SkScalar xpos[],
SkScalar const_y,
const SkPaint&) override = 0;
- void onDrawTextOnPath(const void* text,
- size_t byte_length,
- const SkPath&,
- const SkMatrix*,
- const SkPaint&) override = 0;
void onDrawTextBlob(const SkTextBlob*,
SkScalar x,
SkScalar y,
@@ -289,15 +284,6 @@ class InterceptingCanvas : public InterceptingCanvasBase {
this->SkCanvas::onDrawPosTextH(text, byte_length, xpos, const_y, paint);
}
- void onDrawTextOnPath(const void* text,
- size_t byte_length,
- const SkPath& path,
- const SkMatrix* matrix,
- const SkPaint& paint) override {
- Interceptor interceptor(this);
- this->SkCanvas::onDrawTextOnPath(text, byte_length, path, matrix, paint);
- }
-
void onDrawTextBlob(const SkTextBlob* blob,
SkScalar x,
SkScalar y,
diff --git a/chromium/third_party/blink/renderer/platform/graphics/link_highlight.h b/chromium/third_party/blink/renderer/platform/graphics/link_highlight.h
index b352afe5919..4044ad955f3 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/link_highlight.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/link_highlight.h
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_LINK_HIGHLIGHT_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_LINK_HIGHLIGHT_H_
+#include "third_party/blink/renderer/platform/graphics/paint/display_item_client.h"
#include "third_party/blink/renderer/platform/platform_export.h"
namespace cc {
@@ -13,14 +14,21 @@ class Layer;
namespace blink {
-class PLATFORM_EXPORT LinkHighlight {
+class EffectPaintPropertyNode;
+
+class PLATFORM_EXPORT LinkHighlight : public DisplayItemClient {
public:
+ ~LinkHighlight() override {}
+
virtual void Invalidate() = 0;
virtual void ClearCurrentGraphicsLayer() = 0;
virtual cc::Layer* Layer() = 0;
- protected:
- virtual ~LinkHighlight() = default;
+ virtual const EffectPaintPropertyNode* effect() = 0;
+
+ // DisplayItemClient methods
+ String DebugName() const final { return "LinkHighlight"; }
+ LayoutRect VisualRect() const final { return LayoutRect(); }
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/logging_canvas.cc b/chromium/third_party/blink/renderer/platform/graphics/logging_canvas.cc
index 09dbc7eb337..93c255ffeca 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/logging_canvas.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/logging_canvas.cc
@@ -53,6 +53,8 @@ namespace {
struct VerbParams {
STACK_ALLOCATED();
+
+ public:
String name;
unsigned point_count;
unsigned point_offset;
@@ -782,21 +784,6 @@ void LoggingCanvas::onDrawPosTextH(const void* text,
this->SkCanvas::onDrawPosTextH(text, byte_length, xpos, const_y, paint);
}
-void LoggingCanvas::onDrawTextOnPath(const void* text,
- size_t byte_length,
- const SkPath& path,
- const SkMatrix* matrix,
- const SkPaint& paint) {
- AutoLogger logger(this);
- JSONObject* params = logger.LogItemWithParams("drawTextOnPath");
- params->SetString("text", StringForText(text, byte_length, paint));
- params->SetObject("path", ObjectForSkPath(path));
- if (matrix)
- params->SetArray("matrix", ArrayForSkMatrix(*matrix));
- params->SetObject("paint", ObjectForSkPaint(paint));
- this->SkCanvas::onDrawTextOnPath(text, byte_length, path, matrix, paint);
-}
-
void LoggingCanvas::onDrawTextBlob(const SkTextBlob* blob,
SkScalar x,
SkScalar y,
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 bb8ac6139c7..eceee7d8ddd 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/logging_canvas.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/logging_canvas.h
@@ -93,11 +93,6 @@ class LoggingCanvas : public InterceptingCanvasBase {
const SkScalar xpos[],
SkScalar const_y,
const SkPaint&) override;
- void onDrawTextOnPath(const void* text,
- size_t byte_length,
- const SkPath&,
- const SkMatrix*,
- const SkPaint&) override;
void onDrawTextBlob(const SkTextBlob*,
SkScalar x,
SkScalar y,
diff --git a/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_frame_dispatcher_test.cc b/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_frame_dispatcher_test.cc
index 86812fcecd3..17822636246 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_frame_dispatcher_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_frame_dispatcher_test.cc
@@ -10,6 +10,7 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.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/skia/include/core/SkSurface.h"
using testing::_;
@@ -29,9 +30,6 @@ class MockCanvasResourceDispatcher : public CanvasResourceDispatcher {
class CanvasResourceDispatcherTest : public testing::Test {
public:
void DispatchOneFrame();
- OffscreenCanvasResourceProvider* GetResourceProvider() {
- return dispatcher_->offscreen_canvas_resource_provider_.get();
- }
unsigned GetNumUnreclaimedFramesPosted() {
return dispatcher_->num_unreclaimed_frames_posted_;
@@ -41,13 +39,24 @@ class CanvasResourceDispatcherTest : public testing::Test {
return dispatcher_->latest_unposted_image_.get();
}
- unsigned GetLatestUnpostedResourceId() {
+ viz::ResourceId GetLatestUnpostedResourceId() {
return dispatcher_->latest_unposted_resource_id_;
}
+ viz::ResourceId GetCurrentResourceId() {
+ return dispatcher_->next_resource_id_;
+ }
+
protected:
CanvasResourceDispatcherTest() {
dispatcher_ = std::make_unique<MockCanvasResourceDispatcher>();
+ resource_provider_ = CanvasResourceProvider::Create(
+ IntSize(10, 10),
+ CanvasResourceProvider::kSoftwareCompositedResourceUsage,
+ nullptr, // context_provider_wrapper
+ 0, // msaa_sample_count
+ CanvasColorParams(), CanvasResourceProvider::kDefaultPresentationMode,
+ dispatcher_->GetWeakPtr());
}
MockCanvasResourceDispatcher* Dispatcher() { return dispatcher_.get(); }
@@ -55,13 +64,13 @@ class CanvasResourceDispatcherTest : public testing::Test {
private:
scoped_refptr<StaticBitmapImage> PrepareStaticBitmapImage();
std::unique_ptr<MockCanvasResourceDispatcher> dispatcher_;
+ std::unique_ptr<CanvasResourceProvider> resource_provider_;
};
void CanvasResourceDispatcherTest::DispatchOneFrame() {
- sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(10, 10);
- dispatcher_->DispatchFrame(
- StaticBitmapImage::Create(surface->makeImageSnapshot()),
- base::TimeTicks(), SkIRect::MakeEmpty());
+ dispatcher_->DispatchFrame(resource_provider_->ProduceFrame(),
+ base::TimeTicks(), SkIRect::MakeEmpty(),
+ false /* needs_vertical_flip */);
}
TEST_F(CanvasResourceDispatcherTest, PlaceholderRunsNormally) {
@@ -72,7 +81,7 @@ TEST_F(CanvasResourceDispatcherTest, PlaceholderRunsNormally) {
EXPECT_CALL(*(Dispatcher()), PostImageToPlaceholder(_, post_resource_id));
DispatchOneFrame();
EXPECT_EQ(1u, GetNumUnreclaimedFramesPosted());
- EXPECT_EQ(1u, GetResourceProvider()->GetNextResourceId());
+ EXPECT_EQ(1u, GetCurrentResourceId());
Mock::VerifyAndClearExpectations(Dispatcher());
// Post second frame
@@ -80,7 +89,7 @@ TEST_F(CanvasResourceDispatcherTest, PlaceholderRunsNormally) {
EXPECT_CALL(*(Dispatcher()), PostImageToPlaceholder(_, post_resource_id));
DispatchOneFrame();
EXPECT_EQ(2u, GetNumUnreclaimedFramesPosted());
- EXPECT_EQ(2u, GetResourceProvider()->GetNextResourceId());
+ EXPECT_EQ(2u, GetCurrentResourceId());
Mock::VerifyAndClearExpectations(Dispatcher());
// Post third frame
@@ -88,7 +97,7 @@ TEST_F(CanvasResourceDispatcherTest, PlaceholderRunsNormally) {
EXPECT_CALL(*(Dispatcher()), PostImageToPlaceholder(_, post_resource_id));
DispatchOneFrame();
EXPECT_EQ(3u, GetNumUnreclaimedFramesPosted());
- EXPECT_EQ(3u, GetResourceProvider()->GetNextResourceId());
+ EXPECT_EQ(3u, GetCurrentResourceId());
EXPECT_EQ(nullptr, GetLatestUnpostedImage());
Mock::VerifyAndClearExpectations(Dispatcher());
@@ -123,7 +132,7 @@ TEST_F(CanvasResourceDispatcherTest, PlaceholderBeingBlocked) {
DispatchOneFrame();
unsigned post_resource_id = 4u;
EXPECT_EQ(3u, GetNumUnreclaimedFramesPosted());
- EXPECT_EQ(post_resource_id, GetResourceProvider()->GetNextResourceId());
+ EXPECT_EQ(post_resource_id, GetCurrentResourceId());
EXPECT_TRUE(GetLatestUnpostedImage());
EXPECT_EQ(post_resource_id, GetLatestUnpostedResourceId());
@@ -131,7 +140,7 @@ TEST_F(CanvasResourceDispatcherTest, PlaceholderBeingBlocked) {
post_resource_id++;
DispatchOneFrame();
EXPECT_EQ(3u, GetNumUnreclaimedFramesPosted());
- EXPECT_EQ(post_resource_id, GetResourceProvider()->GetNextResourceId());
+ EXPECT_EQ(post_resource_id, GetCurrentResourceId());
EXPECT_TRUE(GetLatestUnpostedImage());
EXPECT_EQ(post_resource_id, GetLatestUnpostedResourceId());
@@ -146,7 +155,7 @@ TEST_F(CanvasResourceDispatcherTest, PlaceholderBeingBlocked) {
// Reclaim 1 frame and post 1 frame, so numPostImagesUnresponded remains as 3
EXPECT_EQ(3u, GetNumUnreclaimedFramesPosted());
// Not generating new resource Id
- EXPECT_EQ(post_resource_id, GetResourceProvider()->GetNextResourceId());
+ EXPECT_EQ(post_resource_id, GetCurrentResourceId());
EXPECT_FALSE(GetLatestUnpostedImage());
EXPECT_EQ(0u, GetLatestUnpostedResourceId());
Mock::VerifyAndClearExpectations(Dispatcher());
diff --git a/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_placeholder.cc b/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_placeholder.cc
index d92901f961c..bb5b34354e5 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_placeholder.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_placeholder.cc
@@ -10,6 +10,7 @@
#include "third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.h"
#include "third_party/blink/renderer/platform/web_task_runner.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
+#include "third_party/blink/renderer/platform/wtf/wtf.h"
namespace {
diff --git a/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_resource_provider.cc b/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_resource_provider.cc
deleted file mode 100644
index a99595fbae4..00000000000
--- a/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_resource_provider.cc
+++ /dev/null
@@ -1,175 +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/offscreen_canvas_resource_provider.h"
-
-#include "base/memory/shared_memory.h"
-#include "base/numerics/checked_math.h"
-#include "components/viz/common/resources/bitmap_allocation.h"
-#include "components/viz/common/resources/shared_bitmap.h"
-#include "components/viz/common/resources/single_release_callback.h"
-#include "gpu/command_buffer/client/gles2_interface.h"
-#include "gpu/command_buffer/common/capabilities.h"
-#include "services/viz/public/interfaces/compositing/compositor_frame_sink.mojom-blink.h"
-#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/public/platform/web_graphics_context_3d_provider.h"
-#include "third_party/blink/renderer/platform/graphics/canvas_resource.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/runtime_enabled_features.h"
-#include "third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer.h"
-#include "third_party/blink/renderer/platform/wtf/typed_arrays/uint8_array.h"
-#include "third_party/khronos/GLES2/gl2.h"
-#include "third_party/khronos/GLES2/gl2ext.h"
-#include "third_party/skia/include/core/SkColor.h"
-#include "third_party/skia/include/core/SkImage.h"
-#include "third_party/skia/include/core/SkSwizzle.h"
-#include "third_party/skia/include/gpu/GrContext.h"
-
-namespace blink {
-
-OffscreenCanvasResourceProvider::OffscreenCanvasResourceProvider(
- int width,
- int height,
- CanvasResourceDispatcher* frame_dispatcher)
- : frame_dispatcher_(frame_dispatcher), width_(width), height_(height) {}
-
-OffscreenCanvasResourceProvider::~OffscreenCanvasResourceProvider() = default;
-
-std::unique_ptr<OffscreenCanvasResourceProvider::FrameResource>
-OffscreenCanvasResourceProvider::CreateOrRecycleFrameResource() {
- if (recyclable_resource_) {
- recyclable_resource_->spare_lock = true;
- return std::move(recyclable_resource_);
- }
- return std::make_unique<FrameResource>();
-}
-
-void OffscreenCanvasResourceProvider::SetTransferableResourceToSharedBitmap(
- viz::TransferableResource& resource,
- scoped_refptr<StaticBitmapImage> image) {
- std::unique_ptr<FrameResource> frame_resource =
- CreateOrRecycleFrameResource();
- if (!frame_resource->shared_memory) {
- frame_resource->provider = this;
- frame_resource->shared_bitmap_id = viz::SharedBitmap::GenerateId();
- frame_resource->shared_memory =
- viz::bitmap_allocation::AllocateMappedBitmap(gfx::Size(width_, height_),
- resource.format);
- frame_dispatcher_->DidAllocateSharedBitmap(
- viz::bitmap_allocation::DuplicateAndCloseMappedBitmap(
- frame_resource->shared_memory.get(), gfx::Size(width_, height_),
- resource.format),
- SharedBitmapIdToGpuMailboxPtr(frame_resource->shared_bitmap_id));
- }
- void* pixels = frame_resource->shared_memory->memory();
- DCHECK(pixels);
- // When |image| is texture backed, this function does a GPU readback which is
- // required.
- sk_sp<SkImage> sk_image = image->PaintImageForCurrentFrame().GetSkImage();
- if (sk_image->bounds().isEmpty())
- return;
- SkImageInfo image_info = SkImageInfo::Make(
- width_, height_, kN32_SkColorType,
- image->IsPremultiplied() ? kPremul_SkAlphaType : kUnpremul_SkAlphaType,
- sk_image->refColorSpace());
- if (image_info.isEmpty())
- return;
-
- if (RuntimeEnabledFeatures::CanvasColorManagementEnabled()) {
- image_info = image_info.makeColorType(sk_image->colorType());
- }
-
- // TODO(junov): Optimize to avoid copying pixels for non-texture-backed
- // sk_image. See crbug.com/651456.
- bool read_pixels_successful =
- sk_image->readPixels(image_info, pixels, image_info.minRowBytes(), 0, 0);
- DCHECK(read_pixels_successful);
- if (!read_pixels_successful)
- return;
- resource.mailbox_holder.mailbox = frame_resource->shared_bitmap_id;
- resource.mailbox_holder.texture_target = 0;
- resource.is_software = true;
- resource.id = next_resource_id_;
- resource.format = viz::ResourceFormat::RGBA_8888;
- resource.size = gfx::Size(width_, height_);
- // This indicates the filtering on the resource inherently, not the desired
- // filtering effect on the quad.
- resource.filter = GL_NEAREST;
- // TODO(crbug.com/646022): making this overlay-able.
- resource.is_overlay_candidate = false;
-
- resources_.insert(next_resource_id_, std::move(frame_resource));
-}
-
-void OffscreenCanvasResourceProvider::
- SetTransferableResourceToStaticBitmapImage(
- viz::TransferableResource* out_resource,
- scoped_refptr<CanvasResource> image) {
- DCHECK(image->IsAccelerated());
- DCHECK(image->IsValid());
-
- std::unique_ptr<FrameResource> frame_resource =
- CreateOrRecycleFrameResource();
-
- // TODO(junov): Using verified sync tokens for each offscreencanvas is
- // suboptimal in the case where there are multiple offscreen canvases
- // commiting frames. Would be more efficient to batch the verifications.
- image->PrepareTransferableResource(
- out_resource, &frame_resource->release_callback, kVerifiedSyncToken);
- out_resource->id = next_resource_id_;
-
- resources_.insert(next_resource_id_, std::move(frame_resource));
-}
-
-void OffscreenCanvasResourceProvider::ReclaimResources(
- const WTF::Vector<viz::ReturnedResource>& resources) {
- for (const auto& resource : resources) {
- auto it = resources_.find(resource.id);
-
- DCHECK(it != resources_.end());
- if (it == resources_.end())
- continue;
-
- it->value->sync_token = resource.sync_token;
- it->value->is_lost = resource.lost;
- ReclaimResourceInternal(it);
- }
-}
-
-void OffscreenCanvasResourceProvider::ReclaimResource(unsigned resource_id) {
- auto it = resources_.find(resource_id);
- if (it != resources_.end()) {
- ReclaimResourceInternal(it);
- }
-}
-
-void OffscreenCanvasResourceProvider::ReclaimResourceInternal(
- const ResourceMap::iterator& it) {
- if (it->value->spare_lock) {
- it->value->spare_lock = false;
- } else {
- if (it->value->release_callback) {
- it->value->release_callback->Run(it->value->sync_token,
- it->value->is_lost);
- }
- // Recycle resource.
- recyclable_resource_ = std::move(it->value);
- recyclable_resource_->release_callback = nullptr;
- recyclable_resource_->sync_token.Clear();
- recyclable_resource_->is_lost = false;
- resources_.erase(it);
- }
-}
-
-OffscreenCanvasResourceProvider::FrameResource::~FrameResource() {
- if (release_callback)
- release_callback->Run(sync_token, is_lost);
- if (provider && !shared_bitmap_id.IsZero()) {
- provider->frame_dispatcher_->DidDeleteSharedBitmap(
- SharedBitmapIdToGpuMailboxPtr(shared_bitmap_id));
- }
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_resource_provider.h b/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_resource_provider.h
deleted file mode 100644
index a1615b377bb..00000000000
--- a/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_resource_provider.h
+++ /dev/null
@@ -1,96 +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_OFFSCREEN_CANVAS_RESOURCE_PROVIDER_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_OFFSCREEN_CANVAS_RESOURCE_PROVIDER_H_
-
-#include "components/viz/common/resources/returned_resource.h"
-#include "components/viz/common/resources/transferable_resource.h"
-#include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
-
-namespace base {
-class SharedMemory;
-}
-
-namespace viz {
-class SingleReleaseCallback;
-namespace mojom {
-namespace blink {
-class CompositorFrameSink;
-}
-} // namespace mojom
-} // namespace viz
-
-namespace blink {
-
-class CanvasResource;
-class CanvasResourceDispatcher;
-
-class PLATFORM_EXPORT OffscreenCanvasResourceProvider {
- public:
- // The CompositorFrameSink given here must be kept alive as long as this
- // class is, as it is used to free the software-backed resources in the
- // display compositor.
- OffscreenCanvasResourceProvider(int width,
- int height,
- CanvasResourceDispatcher*);
-
- ~OffscreenCanvasResourceProvider();
-
- void SetTransferableResourceToSharedBitmap(viz::TransferableResource&,
- scoped_refptr<StaticBitmapImage>);
- void SetTransferableResourceToStaticBitmapImage(
- viz::TransferableResource* out_resource,
- scoped_refptr<CanvasResource>);
-
- void ReclaimResource(unsigned resource_id);
- void ReclaimResources(const WTF::Vector<viz::ReturnedResource>& resources);
- void IncNextResourceId() { next_resource_id_++; }
- unsigned GetNextResourceId() { return next_resource_id_; }
-
- void Reshape(int width, int height) {
- width_ = width;
- height_ = height;
- // TODO(junov): Prevent recycling resources of the wrong size.
- }
-
- private:
- struct FrameResource {
- FrameResource() = default;
- ~FrameResource();
-
- // TODO(junov): What does this do?
- bool spare_lock = true;
-
- // Holds the backing for a software-backed resource.
- std::unique_ptr<base::SharedMemory> shared_memory;
- // The id given to the display compositor to display a software-backed
- // resource.
- viz::SharedBitmapId shared_bitmap_id;
-
- // Back-pointer to the OffscreenCanvasResourceProvider. FrameResource does
- // not outlive the provider.
- OffscreenCanvasResourceProvider* provider = nullptr;
- std::unique_ptr<viz::SingleReleaseCallback> release_callback;
- gpu::SyncToken sync_token;
- bool is_lost = false;
- };
-
- using ResourceMap = HashMap<unsigned, std::unique_ptr<FrameResource>>;
-
- void SetNeedsBeginFrameInternal();
- std::unique_ptr<FrameResource> CreateOrRecycleFrameResource();
- void ReclaimResourceInternal(const ResourceMap::iterator&);
-
- CanvasResourceDispatcher* frame_dispatcher_;
- int width_;
- int height_;
- unsigned next_resource_id_ = 0;
- std::unique_ptr<FrameResource> recyclable_resource_;
- ResourceMap resources_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_OFFSCREEN_CANVAS_RESOURCE_PROVIDER_H_
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 307b7b6d922..5f5984a09b7 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
@@ -128,6 +128,7 @@ static String ForeignLayerTypeAsDebugString(DisplayItem::Type type) {
DEBUG_STRING_CASE(ForeignLayerVideo);
DEBUG_STRING_CASE(ForeignLayerWrapper);
DEBUG_STRING_CASE(ForeignLayerContentsWrapper);
+ DEBUG_STRING_CASE(ForeignLayerLinkHighlight);
DEFAULT_CASE;
}
}
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 be665246f7b..9965d5ff7b3 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
@@ -116,7 +116,8 @@ class PLATFORM_EXPORT DisplayItem {
kForeignLayerVideo,
kForeignLayerWrapper,
kForeignLayerContentsWrapper,
- kForeignLayerLast = kForeignLayerContentsWrapper,
+ kForeignLayerLinkHighlight,
+ kForeignLayerLast = kForeignLayerLinkHighlight,
kClipPaintPhaseFirst,
kClipPaintPhaseLast = kClipPaintPhaseFirst + kPaintPhaseMax,
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 fe337c41e3f..7bf52f4360f 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
@@ -31,7 +31,7 @@ String PaintChunk::ToString() const {
known_to_be_opaque);
if (hit_test_data) {
ret_val.append(String::Format(
- ", border_rect=(%s), touch_action_rects=(%zu), "
+ ", border_rect=(%s), touch_action_rects=(%u), "
"wheel_event_handler_region=(%s) non_fast_scrollable_region=(%s))",
hit_test_data->border_rect.ToString().Ascii().data(),
hit_test_data->touch_action_rects.size(),
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 abaa96b51bb..b2faaef74f8 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
@@ -211,10 +211,8 @@ const DisplayItem* PaintController::LastDisplayItem(unsigned offset) {
void PaintController::ProcessNewItem(DisplayItem& display_item) {
DCHECK(!construction_disabled_);
- if (IsSkippingCache()) {
- DCHECK_EQ(usage_, kMultiplePaints);
+ if (IsSkippingCache() && usage_ == kMultiplePaints)
display_item.Client().Invalidate(PaintInvalidationReason::kUncacheable);
- }
#if DCHECK_IS_ON()
bool chunk_added =
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 c64e6fbb576..183561d8f6f 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
@@ -157,7 +157,9 @@ class PLATFORM_EXPORT PaintController {
DCHECK(skipping_cache_count_ > 0);
--skipping_cache_count_;
}
- bool IsSkippingCache() const { return skipping_cache_count_; }
+ bool IsSkippingCache() const {
+ return usage_ == kTransient || skipping_cache_count_;
+ }
// Must be called when a painting is finished. Updates the current paint
// artifact with the new paintings.
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_property_node.h b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_property_node.h
index ab428286fbc..def059e51d7 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_property_node.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_property_node.h
@@ -91,7 +91,8 @@ class PaintPropertyNode : public RefCounted<NodeType> {
#endif
protected:
- PaintPropertyNode(const NodeType* parent) : parent_(parent) {}
+ PaintPropertyNode(const NodeType* parent)
+ : parent_(parent), changed_(!!parent) {}
bool SetParent(const NodeType* parent) {
DCHECK(!IsRoot());
@@ -104,14 +105,17 @@ class PaintPropertyNode : public RefCounted<NodeType> {
return true;
}
- void SetChanged() { changed_ = true; }
+ void SetChanged() {
+ DCHECK(!IsRoot());
+ changed_ = true;
+ }
bool NodeChanged() const { return changed_; }
private:
friend class PaintPropertyNodeTest;
scoped_refptr<const NodeType> parent_;
- mutable bool changed_ = true;
+ mutable bool changed_;
#if DCHECK_IS_ON()
String debug_name_;
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 516fbce1011..5d928f381a5 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
@@ -84,7 +84,7 @@ class PaintPropertyNodeTest : public testing::Test {
template <typename NodeType>
void ExpectInitialState(const Tree<NodeType>& tree) {
- EXPECT_TRUE(tree.root->NodeChanged());
+ EXPECT_FALSE(tree.root->NodeChanged());
EXPECT_TRUE(tree.ancestor->NodeChanged());
EXPECT_TRUE(tree.child1->NodeChanged());
EXPECT_TRUE(tree.child2->NodeChanged());
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 743ab2ccf8c..dc1716f6518 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
@@ -6,6 +6,24 @@
namespace blink {
+namespace {
+
+WTF::String OverscrollBehaviorTypeToString(
+ OverscrollBehavior::OverscrollBehaviorType value) {
+ switch (value) {
+ case OverscrollBehavior::kOverscrollBehaviorTypeNone:
+ return "none";
+ case OverscrollBehavior::kOverscrollBehaviorTypeAuto:
+ return "auto";
+ case OverscrollBehavior::kOverscrollBehaviorTypeContain:
+ return "contain";
+ default:
+ NOTREACHED();
+ }
+}
+
+} // namespace
+
const ScrollPaintPropertyNode& ScrollPaintPropertyNode::Root() {
DEFINE_STATIC_REF(
ScrollPaintPropertyNode, root,
@@ -44,6 +62,30 @@ std::unique_ptr<JSONObject> ScrollPaintPropertyNode::ToJSON() const {
json->SetString("compositorElementId",
state_.compositor_element_id.ToString().c_str());
}
+ if (state_.overscroll_behavior.x !=
+ OverscrollBehavior::kOverscrollBehaviorTypeAuto) {
+ json->SetString("overscroll-behavior-x", OverscrollBehaviorTypeToString(
+ state_.overscroll_behavior.x));
+ }
+ if (state_.overscroll_behavior.y !=
+ OverscrollBehavior::kOverscrollBehaviorTypeAuto) {
+ json->SetString("overscroll-behavior-y", OverscrollBehaviorTypeToString(
+ state_.overscroll_behavior.y));
+ }
+
+ if (state_.snap_container_data) {
+ json->SetString("snap_container_rect",
+ state_.snap_container_data->rect().ToString().c_str());
+ if (state_.snap_container_data->size()) {
+ auto area_rects_json = JSONArray::Create();
+ for (size_t i = 0; i < state_.snap_container_data->size(); ++i) {
+ area_rects_json->PushString(
+ state_.snap_container_data->at(i).rect.ToString().c_str());
+ }
+ json->SetArray("snap_area_rects", std::move(area_rects_json));
+ }
+ }
+
return json;
}
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 e4b93dfbd2a..2bd206ee960 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
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_SCROLL_PAINT_PROPERTY_NODE_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_SCROLL_PAINT_PROPERTY_NODE_H_
+#include "base/optional.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"
@@ -12,6 +13,8 @@
#include "third_party/blink/renderer/platform/graphics/paint/paint_property_node.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/scroll/main_thread_scrolling_reason.h"
+#include "third_party/blink/renderer/platform/scroll/overscroll_behavior.h"
+#include "third_party/blink/renderer/platform/scroll/scroll_snap_data.h"
namespace blink {
@@ -44,9 +47,12 @@ class PLATFORM_EXPORT ScrollPaintPropertyNode
bool max_scroll_offset_affected_by_page_scale = false;
MainThreadScrollingReasons main_thread_scrolling_reasons =
MainThreadScrollingReason::kNotScrollingOnMain;
- // The scrolling element id is stored directly on the scroll node and not on
- // the associated TransformPaintPropertyNode used for scroll offset.
+ // The scrolling element id is stored directly on the scroll node and not
+ // on the associated TransformPaintPropertyNode used for scroll offset.
CompositorElementId compositor_element_id;
+ OverscrollBehavior overscroll_behavior = blink::OverscrollBehavior(
+ blink::OverscrollBehavior::kOverscrollBehaviorTypeAuto);
+ base::Optional<SnapContainerData> snap_container_data;
bool operator==(const State& o) const {
return container_rect == o.container_rect &&
@@ -58,7 +64,9 @@ class PLATFORM_EXPORT ScrollPaintPropertyNode
max_scroll_offset_affected_by_page_scale ==
o.max_scroll_offset_affected_by_page_scale &&
main_thread_scrolling_reasons == o.main_thread_scrolling_reasons &&
- compositor_element_id == o.compositor_element_id;
+ compositor_element_id == o.compositor_element_id &&
+ overscroll_behavior == o.overscroll_behavior &&
+ snap_container_data == o.snap_container_data;
}
};
@@ -83,6 +91,18 @@ class PLATFORM_EXPORT ScrollPaintPropertyNode
return true;
}
+ OverscrollBehavior::OverscrollBehaviorType OverscrollBehaviorX() const {
+ return state_.overscroll_behavior.x;
+ }
+
+ OverscrollBehavior::OverscrollBehaviorType OverscrollBehaviorY() const {
+ return state_.overscroll_behavior.y;
+ }
+
+ base::Optional<SnapContainerData> SnapContainerData() const {
+ return state_.snap_container_data;
+ }
+
// Rect of the container area that the contents scrolls in, in the space of
// the parent of the associated transform node (ScrollTranslation).
// It doesn't include non-overlay scrollbars. Overlay scrollbars do not affect
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 6de51874451..f670c908e86 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
@@ -49,6 +49,7 @@ class PLATFORM_EXPORT TransformPaintPropertyNode
CompositingReasons direct_compositing_reasons = CompositingReason::kNone;
CompositorElementId compositor_element_id;
scoped_refptr<const ScrollPaintPropertyNode> scroll;
+ bool affected_by_outer_viewport_bounds_delta = false;
bool operator==(const State& o) const {
return matrix == o.matrix && origin == o.origin &&
@@ -57,7 +58,9 @@ class PLATFORM_EXPORT TransformPaintPropertyNode
rendering_context_id == o.rendering_context_id &&
direct_compositing_reasons == o.direct_compositing_reasons &&
compositor_element_id == o.compositor_element_id &&
- scroll == o.scroll;
+ scroll == o.scroll &&
+ affected_by_outer_viewport_bounds_delta ==
+ o.affected_by_outer_viewport_bounds_delta;
}
};
@@ -97,6 +100,13 @@ class PLATFORM_EXPORT TransformPaintPropertyNode
return state_.scroll.get();
}
+ // If true, this node is translated by the viewport bounds delta, which is
+ // used to keep bottom-fixed elements appear fixed to the bottom of the
+ // screen in the presence of URL bar movement.
+ bool IsAffectedByOuterViewportBoundsDelta() const {
+ return state_.affected_by_outer_viewport_bounds_delta;
+ }
+
// If this is a scroll offset translation (i.e., has an associated scroll
// node), returns this. Otherwise, returns the transform node that this node
// scrolls with respect to. This can require a full ancestor traversal.
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint_invalidation_reason.cc b/chromium/third_party/blink/renderer/platform/graphics/paint_invalidation_reason.cc
index 37861d191bd..8fd5c50d98e 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint_invalidation_reason.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint_invalidation_reason.cc
@@ -72,8 +72,6 @@ const char* PaintInvalidationReasonToString(PaintInvalidationReason reason) {
return "full layer";
case PaintInvalidationReason::kForTesting:
return "for testing";
- case PaintInvalidationReason::kDelayedFull:
- return "delayed full";
}
NOTREACHED();
return "";
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint_invalidation_reason.h b/chromium/third_party/blink/renderer/platform/graphics/paint_invalidation_reason.h
index 8afacba30df..c81b0d2edf8 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint_invalidation_reason.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint_invalidation_reason.h
@@ -31,6 +31,8 @@ enum class PaintInvalidationReason : uint8_t {
// Scroll bars, scroll corner, etc.
kScrollControl,
kOutline,
+ // The object is invalidated as a part of a subtree full invalidation (forced
+ // by LayoutObject::SetSubtreeShouldDoFullPaintInvalidation()).
kSubtree,
kSVGResource,
kBackground,
@@ -51,13 +53,7 @@ enum class PaintInvalidationReason : uint8_t {
// invalidation may be implicit, e.g. when a layer is created.
kFullLayer,
kForTesting,
- // kDelayedFull means that kFull is needed in order to fully paint the
- // content, but that painting of the object can be delayed until a future
- // frame. This can be the case for an object whose content is not visible to
- // the user.
- kDelayedFull,
-
- kMax = kDelayedFull
+ kMax = kForTesting,
};
PLATFORM_EXPORT const char* PaintInvalidationReasonToString(
@@ -71,12 +67,6 @@ inline bool IsFullPaintInvalidationReason(PaintInvalidationReason reason) {
return reason >= PaintInvalidationReason::kFull;
}
-inline bool IsImmediateFullPaintInvalidationReason(
- PaintInvalidationReason reason) {
- return IsFullPaintInvalidationReason(reason) &&
- reason != PaintInvalidationReason::kDelayedFull;
-}
-
PLATFORM_EXPORT std::ostream& operator<<(std::ostream&,
PaintInvalidationReason);
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint_invalidation_reason_test.cc b/chromium/third_party/blink/renderer/platform/graphics/paint_invalidation_reason_test.cc
index 7ecdd3897dd..547928a13d1 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint_invalidation_reason_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint_invalidation_reason_test.cc
@@ -9,18 +9,25 @@
namespace blink {
+TEST(PaintInvalidationReasonTest, ToString) {
+ for (auto i = PaintInvalidationReason::kNone;
+ i <= PaintInvalidationReason::kMax;
+ i = static_cast<PaintInvalidationReason>(static_cast<int>(i) + 1))
+ EXPECT_STRNE("", PaintInvalidationReasonToString(i));
+
+ EXPECT_STREQ("none",
+ PaintInvalidationReasonToString(PaintInvalidationReason::kNone));
+ EXPECT_STREQ("full",
+ PaintInvalidationReasonToString(PaintInvalidationReason::kFull));
+}
+
TEST(PaintInvalidationReasonTest, StreamOutput) {
- {
- std::stringstream string_stream;
- PaintInvalidationReason reason = PaintInvalidationReason::kNone;
- string_stream << reason;
- EXPECT_EQ("none", string_stream.str());
- }
- {
+ for (auto i = PaintInvalidationReason::kNone;
+ i <= PaintInvalidationReason::kMax;
+ i = static_cast<PaintInvalidationReason>(static_cast<int>(i) + 1)) {
std::stringstream string_stream;
- PaintInvalidationReason reason = PaintInvalidationReason::kDelayedFull;
- string_stream << reason;
- EXPECT_EQ("delayed full", string_stream.str());
+ string_stream << i;
+ EXPECT_EQ(PaintInvalidationReasonToString(i), string_stream.str());
}
}
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 0f3d63acb7a..ea223029985 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
@@ -138,6 +138,8 @@ class PLATFORM_EXPORT StaticBitmapImage : public Image {
bool is_origin_clean_ = true;
};
+DEFINE_IMAGE_TYPE_CASTS(StaticBitmapImage);
+
} // namespace blink
#endif
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 3aa75b4dea6..c42c311f08c 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
@@ -78,8 +78,8 @@ void SurfaceLayerBridge::OnFirstSurfaceActivation(
current_surface_id_ = surface_info.id();
- surface_layer_->SetPrimarySurfaceId(surface_info.id(),
- cc::DeadlinePolicy::UseDefaultDeadline());
+ surface_layer_->SetPrimarySurfaceId(
+ surface_info.id(), cc::DeadlinePolicy::UseSpecifiedDeadline(0u));
surface_layer_->SetFallbackSurfaceId(surface_info.id());
if (observer_) {
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 6a0023a8bcc..382cbf027ff 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
@@ -6,6 +6,7 @@
#include <memory>
#include "base/bind.h"
+#include "base/threading/thread_restrictions.h"
#include "base/trace_event/trace_event.h"
#include "components/viz/client/client_resource_provider.h"
#include "components/viz/common/gpu/context_provider.h"
@@ -19,8 +20,9 @@
namespace blink {
VideoFrameResourceProvider::VideoFrameResourceProvider(
- const cc::LayerTreeSettings& settings)
- : settings_(settings) {}
+ const cc::LayerTreeSettings& settings,
+ bool use_sync_primitives)
+ : settings_(settings), use_sync_primitives_(use_sync_primitives) {}
VideoFrameResourceProvider::~VideoFrameResourceProvider() {
// Drop all resources before closing the ClientResourceProvider.
@@ -92,7 +94,20 @@ void VideoFrameResourceProvider::AppendQuads(
break;
}
- resource_updater_->ObtainFrameResources(frame);
+ // When obtaining frame resources, we end up having to wait. See
+ // https://crbug/878070.
+ // Unfortunately, we have no idea if blocking is allowed on the current thread
+ // or not. If we're on the cc impl thread, the answer is yes, and further
+ // the thread is marked as not allowing blocking primitives. On the various
+ // media threads, however, blocking is not allowed but the blocking scopes
+ // are. So, we use ScopedAllow only if we're told that we should do so.
+ if (use_sync_primitives_) {
+ base::ScopedAllowBaseSyncPrimitives allow_base_sync_primitives;
+ resource_updater_->ObtainFrameResources(frame);
+ } else {
+ resource_updater_->ObtainFrameResources(frame);
+ }
+
// TODO(lethalantidote) : update with true value;
gfx::Rect visible_layer_rect = gfx::Rect(rotated_size);
gfx::Rect clip_rect = gfx::Rect(frame->coded_size());
diff --git a/chromium/third_party/blink/renderer/platform/graphics/video_frame_resource_provider.h b/chromium/third_party/blink/renderer/platform/graphics/video_frame_resource_provider.h
index b689026e27c..a5481e28030 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/video_frame_resource_provider.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/video_frame_resource_provider.h
@@ -30,7 +30,12 @@ namespace blink {
// https://crbug.com/753605
class PLATFORM_EXPORT VideoFrameResourceProvider {
public:
- explicit VideoFrameResourceProvider(const cc::LayerTreeSettings&);
+ // |use_sync_primitives| controls whether we ScopedAllowBaseSyncPrimitives
+ // when calling into |resource_updater_|. It waits, but the cc impl thread
+ // doesn't seem to mind. It does mind, however, the ScopedAllow. When this
+ // is run on the media thread, we need to ScopedAllow first.
+ VideoFrameResourceProvider(const cc::LayerTreeSettings&,
+ bool use_sync_primitives);
virtual ~VideoFrameResourceProvider();
@@ -56,10 +61,10 @@ class PLATFORM_EXPORT VideoFrameResourceProvider {
private:
const cc::LayerTreeSettings settings_;
- WebContextProviderCallback context_provider_callback_;
viz::ContextProvider* context_provider_;
std::unique_ptr<viz::ClientResourceProvider> resource_provider_;
std::unique_ptr<media::VideoResourceUpdater> resource_updater_;
+ bool use_sync_primitives_ = false;
};
} // namespace blink
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 50950be7494..c6e15aae27b 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
@@ -6,7 +6,6 @@
#include <vector>
-#include "base/task_runner.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
#include "cc/paint/filter_operations.h"
@@ -14,8 +13,8 @@
#include "components/viz/common/resources/resource_id.h"
#include "components/viz/common/resources/returned_resource.h"
#include "media/base/video_frame.h"
-#include "services/ui/public/cpp/gpu/context_provider_command_buffer.h"
#include "services/viz/public/interfaces/compositing/compositor_frame_sink.mojom-blink.h"
+#include "services/ws/public/cpp/gpu/context_provider_command_buffer.h"
#include "third_party/blink/public/platform/interface_provider.h"
#include "third_party/blink/public/platform/modules/frame_sinks/embedded_frame_sink.mojom-blink.h"
#include "third_party/blink/public/platform/platform.h"
@@ -26,7 +25,8 @@ namespace blink {
namespace {
// Delay to retry getting the context_provider.
-constexpr int kGetContextProviderRetryMS = 150;
+constexpr base::TimeDelta kGetContextProviderRetryTimeout =
+ base::TimeDelta::FromMilliseconds(150);
} // namespace
@@ -163,33 +163,45 @@ void VideoFrameSubmitter::Initialize(cc::VideoFrameProvider* provider) {
DCHECK(!provider_);
provider_ = provider;
context_provider_callback_.Run(
- base::BindOnce(&VideoFrameSubmitter::OnReceivedContextProvider,
- weak_ptr_factory_.GetWeakPtr()));
+ nullptr, base::BindOnce(&VideoFrameSubmitter::OnReceivedContextProvider,
+ weak_ptr_factory_.GetWeakPtr()));
}
}
void VideoFrameSubmitter::OnReceivedContextProvider(
bool use_gpu_compositing,
- scoped_refptr<ui::ContextProviderCommandBuffer> context_provider) {
- // We could get a null |context_provider| back if the context is still lost.
- if (!context_provider && use_gpu_compositing) {
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE,
- base::BindOnce(
- context_provider_callback_,
- base::BindOnce(&VideoFrameSubmitter::OnReceivedContextProvider,
- weak_ptr_factory_.GetWeakPtr())),
- base::TimeDelta::FromMilliseconds(kGetContextProviderRetryMS));
+ scoped_refptr<viz::ContextProvider> context_provider) {
+ if (!use_gpu_compositing) {
+ resource_provider_->Initialize(nullptr, this);
return;
}
- context_provider_ = std::move(context_provider);
- if (use_gpu_compositing) {
- context_provider_->AddObserver(this);
- resource_provider_->Initialize(context_provider_.get(), nullptr);
- } else {
- resource_provider_->Initialize(nullptr, this);
+ bool has_good_context = false;
+ while (!has_good_context) {
+ if (!context_provider) {
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE,
+ base::BindOnce(
+ context_provider_callback_, context_provider_,
+ base::BindOnce(&VideoFrameSubmitter::OnReceivedContextProvider,
+ weak_ptr_factory_.GetWeakPtr())),
+ kGetContextProviderRetryTimeout);
+ return;
+ }
+
+ // Note that |context_provider| is now null after the move, such that if we
+ // end up having !|has_good_context|, we will retry to obtain the
+ // context_provider.
+ context_provider_ = std::move(context_provider);
+ auto result = context_provider_->BindToCurrentThread();
+
+ has_good_context =
+ result == gpu::ContextResult::kSuccess &&
+ context_provider_->ContextGL()->GetGraphicsResetStatusKHR() ==
+ GL_NO_ERROR;
}
+ context_provider_->AddObserver(this);
+ resource_provider_->Initialize(context_provider_.get(), nullptr);
if (frame_sink_id_.is_valid())
StartSubmitting();
@@ -340,7 +352,6 @@ void VideoFrameSubmitter::OnContextLost() {
if (context_provider_) {
context_provider_->RemoveObserver(this);
- context_provider_ = nullptr;
}
waiting_for_compositor_ack_ = false;
@@ -350,6 +361,7 @@ void VideoFrameSubmitter::OnContextLost() {
compositor_frame_sink_.reset();
context_provider_callback_.Run(
+ context_provider_,
base::BindOnce(&VideoFrameSubmitter::OnReceivedContextProvider,
weak_ptr_factory_.GetWeakPtr()));
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 8b558645d38..d1384945f19 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
@@ -47,9 +47,7 @@ class PLATFORM_EXPORT VideoFrameSubmitter
return &binding_;
}
- void OnReceivedContextProvider(
- bool,
- scoped_refptr<ui::ContextProviderCommandBuffer>);
+ void OnReceivedContextProvider(bool, scoped_refptr<viz::ContextProvider>);
// cc::VideoFrameProvider::Client implementation.
void StopUsingProvider() override;
@@ -118,7 +116,7 @@ class PLATFORM_EXPORT VideoFrameSubmitter
bool ShouldSubmit() const;
cc::VideoFrameProvider* provider_ = nullptr;
- scoped_refptr<ui::ContextProviderCommandBuffer> context_provider_;
+ scoped_refptr<viz::ContextProvider> context_provider_;
viz::mojom::blink::CompositorFrameSinkPtr compositor_frame_sink_;
mojo::Binding<viz::mojom::blink::CompositorFrameSinkClient> binding_;
WebContextProviderCallback context_provider_callback_;
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 f4071fd2310..b21f2e4cd25 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
@@ -6,10 +6,8 @@
#include <memory>
#include "base/memory/ptr_util.h"
-#include "base/task_runner_util.h"
#include "base/test/scoped_task_environment.h"
#include "base/test/simple_test_tick_clock.h"
-#include "base/threading/thread.h"
#include "cc/layers/video_frame_provider.h"
#include "cc/test/layer_test_common.h"
#include "cc/trees/layer_tree_settings.h"
@@ -103,7 +101,7 @@ class MockVideoFrameResourceProvider
MockVideoFrameResourceProvider(
viz::ContextProvider* context_provider,
viz::SharedBitmapReporter* shared_bitmap_reporter)
- : blink::VideoFrameResourceProvider(cc::LayerTreeSettings()) {
+ : blink::VideoFrameResourceProvider(cc::LayerTreeSettings(), false) {
blink::VideoFrameResourceProvider::Initialize(context_provider,
shared_bitmap_reporter);
}
@@ -150,8 +148,9 @@ class VideoFrameSubmitterTest : public testing::Test {
context_provider_.get(), nullptr);
submitter_ = std::make_unique<VideoFrameSubmitter>(
base::BindRepeating(
- [](base::OnceCallback<void(
- bool, scoped_refptr<ui::ContextProviderCommandBuffer>)>) {}),
+ [](scoped_refptr<viz::ContextProvider>,
+ base::OnceCallback<void(
+ bool, scoped_refptr<viz::ContextProvider>)>) {}),
base::WrapUnique<MockVideoFrameResourceProvider>(resource_provider_));
submitter_->Initialize(provider_.get());
diff --git a/chromium/third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_wrapper.h b/chromium/third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_wrapper.h
index e0f35200c51..93a0854bb39 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_wrapper.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_wrapper.h
@@ -48,7 +48,7 @@ class PLATFORM_EXPORT WebGraphicsContext3DProviderWrapper {
private:
std::unique_ptr<GraphicsContext3DUtils> utils_;
std::unique_ptr<WebGraphicsContext3DProvider> context_provider_;
- base::ObserverList<DestructionObserver> observers_;
+ base::ObserverList<DestructionObserver>::Unchecked observers_;
base::WeakPtrFactory<WebGraphicsContext3DProviderWrapper> weak_ptr_factory_;
};
diff --git a/chromium/third_party/blink/renderer/platform/heap/BUILD.gn b/chromium/third_party/blink/renderer/platform/heap/BUILD.gn
index 3859f8c0600..337d4cbfe9e 100644
--- a/chromium/third_party/blink/renderer/platform/heap/BUILD.gn
+++ b/chromium/third_party/blink/renderer/platform/heap/BUILD.gn
@@ -69,7 +69,6 @@ blink_platform_sources("heap") {
"persistent_node.h",
"process_heap.cc",
"process_heap.h",
- "safe_point.h",
"self_keep_alive.h",
"sparse_heap_bitmap.cc",
"sparse_heap_bitmap.h",
diff --git a/chromium/third_party/blink/renderer/platform/heap/BlinkGCDesign.md b/chromium/third_party/blink/renderer/platform/heap/BlinkGCDesign.md
index 9748c4d3691..cbac6aa5766 100644
--- a/chromium/third_party/blink/renderer/platform/heap/BlinkGCDesign.md
+++ b/chromium/third_party/blink/renderer/platform/heap/BlinkGCDesign.md
@@ -1,3 +1,4 @@
+
# Blink GC Design
Oilpan is a garbage collection system for Blink objects.
@@ -9,159 +10,117 @@ see [BlinkGCAPIReference](BlinkGCAPIReference.md).
## Overview
-Oilpan is a single-threaded mark-and-sweep GC.
-It doesn't (yet) implement a generational or incremental GC.
-
-Blink has multiple threads including the main thread, HTML parser threads,
-database threads and worker threads. Threads that touch Oilpan's heap need
-to be attached to Oilpan. These threads can have cross-thread pointers.
-Oilpan scans the object graph spanning these threads and collects
-unreachable objects.
+Oilpan implements a mark-and-sweep GC. It features thread-local garbage
+collection with incremental marking and lazy sweeping. It can also do
+compaction for a subset of objects (collection backings).
## Threading model
-Oilpan runs a GC in the following steps:
-
-Step 1. A thread decides to trigger a GC. The thread can be any thread
-(it is likely to be the main thread because most allocations take place
-on the main thread). The thread is called a GCing thread.
-
-Step 2. The GCing thread waits for all other threads to enter safe points.
-A safe point is a place where it's guaranteed that the thread does not
-mutate the object graph of objects in Oilpan's heap. In common cases the thread
-stops at the safe point but doesn't necessarily need to stop. For example,
-the thread is allowed to execute a synchronous IO at the safe point as
-long as it doesn't mutate the object graph. Safe points are inserted into
-many places so that the thread can enter the safe point as soon as possible
-when the GCing thread requests the thread to do so. For example, safe points
-are inserted into V8 interruptors, at the end of event loops,
-before acquiring a mutex, before starting a synchronous IO operation etc.
-
-Step 3. Once all the threads enter the safe points, the GCing thread starts
-a marking phase. The GCing thread marks all objects reachable from the root
-set by calling trace() methods defined on each object. This means that the
-GCing thread marks objects owned by all the threads. This doesn't cause any
-threading race because all the other threads are at the safe points.
-
-Step 4. Once the marking is complete, the GCing thread resumes executions of
-all the other threads. Each thread starts a sweeping phase. Each thread is
-responsible for destructing objects that the thread has allocated.
-That way objects are guaranteed to get destructed on the thread that has
-allocated the objects. The sweeping is done by each thread lazily.
-Instead of completing the sweeping phase in one go, the thread sweeps
-objects incrementally as much as it allocates. Lazy sweeping is helpful
-to distribute a long pause time of the sweeping phase into small chunks.
-
-The step 2 and 3 is the pause time of the GC.
-The pause time is proportional to the number of objects marked
-in the marking phase, meaning that it is proportional to the number of
-live objects.
-
-Notes:
-
-* If the GCing thread fails at stopping all the other threads in a
-certain period of time, it gives up triggering a GC. That way we avoid
-introducing an unacceptably long pause time. (This will rarely happen
-because each thread enters safe points very frequently.)
-
-* It is not really nice that the GCing thread has to stop all the other threads.
-For example, a worker thread has to get involved in a GC
-caused by a lot of allocations happening on the main thread.
-To resolve the issue, we have a plan to split the Oilpan's heap
-into per-thread heaps. Once it's implemented, each thread can run
-GCs independently.
+Oilpan creates a different heap and root set for each thread. This allows Oilpan
+to run garbage collection in parallel with mutators running in other threads.
+
+Any object or `Persistent` that is allocated on a thread automatically belong to
+that thread's heap or root set. References to objects belonging to another
+thread's heap, must use the `CrossThreadPersistent` handle. This is even true
+for on-heap to on-heap references.
+
+Assigning to a `CrossThreadPersistent` requires a global lock, meaning it might
+block waiting for garbage collection to end on all other threads.
+
+Threads that want to allocate Oilpan objects must be "attached" to Oilpan
+(typically through `WebThreadSupportingGC`).
+
+## Heap partitioning
+
+As mentioned earlier, we have separate heaps for each thread. This `ThreadHeap`
+is further partitioned into "Arenas". The Arena for an object is chosen
+depending on a number of criteria.
+
+For example
+- objects over 64KiB goes into `kLargeObjectArenaIndex`
+- objects that have an eager finalizer goes into `kEagerSweepArenaIndex`
+- objects that is a collection backing goes into one of the collection backing
+arenas
+- objects that is a Node or a CSSValue goes into one of the typed arenas
+- other objects goes into one of the normal page arenas bucketed depending on
+their size
## Precise GC and conservative GC
-Oilpan has two kinds of GCs.
+Oilpan has three kinds of GCs.
-When all threads are stopped at the safe points at the end of event loops,
-a precise GC is triggered. At this point it is guaranteed that
-there are no on-stack pointers pointing to Oilpan's heap.
-Thus Oilpan runs a precise GC. The root set of a precise GC is
-persistent handles.
+Precise GC is triggered at the end of an event loop. At this point, it is
+guaranteed that there are no on-stack pointers pointing to Oilpan's heap. Oilpan
+can just trace from the `Persistent` handles and collect all garbage precisely.
-Otherwise, a conservative GC is triggered. In this case, the GC scans
-a native stack of the threads (which are not stopped at the safe points
-at the end of event loops) and push the pointers discovered via the native
-stacks into the root set. (That's why you can use raw pointers on the
-native stack.) The root set of a conservative GC is persistent handles
-and the native stacks of the threads.
+Conservative GC runs when we are under memory pressure, and a GC cannot wait
+until we go back to an event loop. In this case, the GC scans the native stack
+and treats the pointers discovered via the native stacks as part of the root
+set. (That's why raw pointers are used instead of handles on the native stack.)
-A conservative GC is more expensive than a precise GC because
-the conservative GC needs to scan the native stacks.
-Thus Oilpan tries its best to trigger GCs at the end of an event loop.
-In particular, Oilpan tries its best to trigger GCs in idle tasks.
+Incremental GC is the most common type of GC. It splits the marking phase into
+small chunks and runs them between tasks. The smaller pause times help with
+reducing jank.
## Marking phase
-The marking phase (the step 3 in the above description) consists of
-the following steps. The marking phase is executed in a stop-the-world manner.
+The marking phase consists of the following steps. The marking phase is executed
+in a stop-the-world manner.
-Step 3-1. The GCing thread marks all objects reachable from the root set
-by calling trace() methods defined on each object.
+Step 1. Mark all objects reachable from the root set by calling `Trace()`
+methods defined on each object.
-Step 3-2. The GCing thread clears out all trivial WeakMembers.
+Step 2. Clear out all weak handles and run weak callbacks.
To prevent a use-after-free from happening, it is very important to
make sure that Oilpan doesn't mis-trace any edge of the object graph.
This means that all pointers except on-stack pointers must be wrapped
with Oilpan's handles (i.e., Persistent<>, Member<>, WeakMember<> etc).
Raw pointers to on-heap objects have a risk of creating an edge Oilpan
-cannot understand and causing a use-after-free. You should not use raw pointers
-to on-heap objects (except raw pointers on native stacks) unless you're pretty
-sure that the target objects are guaranteed to be kept alive in other ways.
+cannot understand and causing a use-after-free. Raw pointers shall not be used
+to reference on-heap objects (except raw pointers on native stacks). Exceptions
+can be made if the target object is guaranteed to be kept alive in other ways.
## Sweeping phase
-The sweeping phase (the step 4 in the above description) consists of
-the following steps. The sweeping phase is executed by each thread in parallel.
-
-Step 4-1. The thread clears out all non-trivial WeakMembers.
-Non-trivial WeakMembers are the ones that have manual weak processing
-(registered by registerWeakMembers()) and the ones embedded in HeapHashMap etc.
-The reason we don't run non-trivial WeakMembers in the marking phase is that
-clearing out the non-trivial WeakMembers can invoke some destructors
-(e.g., if you have HeapHashMap<WeakMember<X>, OwnPtr<Y>>, Y's destructor
-is invoked when the weak processing removes the key).
-The destructors must run in the same thread that has allocated the objects.
+The sweeping phase consists of the following steps.
-Step 4-2. The thread invokes pre-finalizers.
+Step 1. Invoke pre-finalizers.
At this point, no destructors have been invoked.
Thus the pre-finalizers are allowed to touch any other on-heap objects
(which may get destructed in this sweeping phase).
-Step 4-3. The thread invokes destructors of dead objects that are marked
-as eagerly-finalized. See the following notes for more details about the
+Step 2. Invokes destructors of dead objects that are marked as
+eagerly-finalized. See the following notes for more details about the
eagerly-finalized objects.
-Step 4-4. The thread resumes mutator's execution. (A mutator means user code.)
+Step 3. The thread resumes mutator's execution. (A mutator means user code.)
-Step 4-5. As the mutator allocates new objects, lazy sweeping invokes
+Step 4. As the mutator allocates new objects, lazy sweeping invokes
destructors of the remaining dead objects incrementally.
There is no guarantee of the order in which the destructors are invoked.
That's why destructors must not touch any other on-heap objects
(which might have already been destructed). If some destructor unavoidably
-needs to touch other on-heap objects, you need to use a pre-finalizer.
-The pre-finalizer is allowed to touch other on-heap objects.
+needs to touch other on-heap objects, it will have to be converted to a
+pre-finalizer. The pre-finalizer is allowed to touch other on-heap objects.
The mutator is resumed before all the destructors has run.
For example, imagine a case where X is a client of Y, and Y holds
-a list of clients. If you rely on X's destructor removing X from the list,
+a list of clients. If the code relies on X's destructor removing X from the list,
there is a risk that Y iterates the list and calls some method of X
which may touch other on-heap objects. This causes a use-after-free.
-You need to make sure that X is explicitly removed from the list
+Care must be taken to make sure that X is explicitly removed from the list
before the mutator resumes its execution in a way that doesn't rely on
X's destructor.
Either way, the most important thing is that there is no guarantee of
-when destructors run. You shouldn't put any assumption about
-the order and the timing.
+when destructors run. Assumptions should not be made about the order and the
+timing of their execution.
(In general, it's dangerous to do something complicated in a destructor.)
-Notes (The followings are features you'll need only when you have
-unusual destruction requirements):
+Notes (The followings are features that shall be reserved for unusual
+destruction requirements):
* Weak processing runs only when the holder object of the WeakMember
outlives the pointed object. If the holder object and the pointed object die
@@ -170,8 +129,8 @@ assuming that the weak processing always runs.
* Pre-finalizers are heavy because the thread needs to scan all pre-finalizers
at each sweeping phase to determine which pre-finalizers to be invoked
-(the thread needs to invoke pre-finalizers of dead objects).
-You should avoid adding pre-finalizers to frequently created objects.
+(the thread needs to invoke pre-finalizers of dead objects). Adding
+pre-finalizers to frequently created objects should be avoided.
* Eagerly-finalized objects are guaranteed to get destructed before the
mutator resumes its execution. This means that a destructor of
@@ -179,22 +138,3 @@ an eagerly-finalized object is allowed to touch other not-eagerly-finalized
objects whereas it's not allowed to touch other eagerly-finalized objects.
This notion is useful for some objects, but nasty.
We're planning to replace most eagerly-finalized objects with pre-finalizers.
-
-* There is a subtle scenario where a next GC is triggered before
-the thread finishes lazy sweeping. In that case, the not-yet-swept objects
-are marked as dead and the next GC starts. The objects marked as dead are
-swept in the sweeping phase of the next GC. This means that you cannot assume
-that some two objects get destructed in the same GC cycle.
-
-## Heap structures
-
-Each thread has its dedicated heap so that the thread can allocate an object
-without acquiring a lock. For example, an object allocated on thread 1 goes
-to a different heap than an object allocated on thread 2.
-
-In addition, each thread provides multiple arenas to group objects by their type
-and thus improves locality.
-For example, a Node object allocated on thread 1 goes to a different heap than
-a CSSValue object allocated on thread 1. (See BlinkGC.h to get the list of
-the typed arenas.)
-
diff --git a/chromium/third_party/blink/renderer/platform/heap/DEPS b/chromium/third_party/blink/renderer/platform/heap/DEPS
index c5aa107a763..4d6fe98210a 100644
--- a/chromium/third_party/blink/renderer/platform/heap/DEPS
+++ b/chromium/third_party/blink/renderer/platform/heap/DEPS
@@ -8,9 +8,8 @@ include_rules = [
# Dependencies.
"+base/atomicops.h",
"+base/bits.h",
- "+base/compiler_specific.h",
+ "+base/sampling_heap_profiler/poisson_allocation_sampler.h",
"+base/synchronization/lock.h",
- "+base/sys_info.h",
"+third_party/blink/renderer/platform/bindings",
"+third_party/blink/renderer/platform/cross_thread_functional.h",
diff --git a/chromium/third_party/blink/renderer/platform/heap/address_cache.cc b/chromium/third_party/blink/renderer/platform/heap/address_cache.cc
index 06c24e011f5..fb93fbcbe22 100644
--- a/chromium/third_party/blink/renderer/platform/heap/address_cache.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/address_cache.cc
@@ -8,6 +8,16 @@
namespace blink {
+AddressCache::EnabledScope::EnabledScope(AddressCache* address_cache)
+ : address_cache_(address_cache) {
+ address_cache_->FlushIfDirty();
+ address_cache_->EnableLookup();
+}
+
+AddressCache::EnabledScope::~EnabledScope() {
+ address_cache_->DisableLookup();
+}
+
void AddressCache::Flush() {
if (has_entries_) {
for (size_t i = 0; i < kNumberOfEntries; ++i)
diff --git a/chromium/third_party/blink/renderer/platform/heap/address_cache.h b/chromium/third_party/blink/renderer/platform/heap/address_cache.h
index 85c676cd6b2..526594f9562 100644
--- a/chromium/third_party/blink/renderer/platform/heap/address_cache.h
+++ b/chromium/third_party/blink/renderer/platform/heap/address_cache.h
@@ -16,12 +16,17 @@ class PLATFORM_EXPORT AddressCache {
USING_FAST_MALLOC(AddressCache);
public:
- AddressCache() : enabled_(false), has_entries_(false), dirty_(false) {
- // Start by flushing the cache in a non-empty state to initialize all the
- // cache entries.
- for (size_t i = 0; i < kNumberOfEntries; ++i)
- entries_[i] = nullptr;
- }
+ class PLATFORM_EXPORT EnabledScope {
+ public:
+ explicit EnabledScope(AddressCache*);
+ ~EnabledScope();
+
+ private:
+ AddressCache* const address_cache_;
+ };
+
+ AddressCache()
+ : entries_{}, enabled_(false), has_entries_(false), dirty_(false) {}
void EnableLookup() { enabled_ = true; }
void DisableLookup() { enabled_ = false; }
@@ -29,7 +34,7 @@ class PLATFORM_EXPORT AddressCache {
void MarkDirty() { dirty_ = true; }
void Flush();
void FlushIfDirty();
- bool IsEmpty() { return !has_entries_; }
+ bool IsEmpty() const { return !has_entries_; }
// Perform a lookup in the cache. Returns true if the address is guaranteed
// to not in Blink's heap and false otherwise.
diff --git a/chromium/third_party/blink/renderer/platform/heap/address_cache_test.cc b/chromium/third_party/blink/renderer/platform/heap/address_cache_test.cc
index 001b32ce553..280920dd1c4 100644
--- a/chromium/third_party/blink/renderer/platform/heap/address_cache_test.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/address_cache_test.cc
@@ -15,6 +15,12 @@ const Address kObjectAddress = reinterpret_cast<Address>(kBlinkPageSize);
} // namespace
+TEST(AddressCacheTest, Scope) {
+ AddressCache cache;
+ AddressCache::EnabledScope scope(&cache);
+ EXPECT_FALSE(cache.Lookup(kObjectAddress));
+}
+
TEST(AddressCacheTest, InitialIsEmpty) {
AddressCache cache;
cache.EnableLookup();
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 3111f5c7f4a..d07e1e4cf23 100644
--- a/chromium/third_party/blink/renderer/platform/heap/garbage_collected.h
+++ b/chromium/third_party/blink/renderer/platform/heap/garbage_collected.h
@@ -49,6 +49,8 @@ struct IsGarbageCollectedMixin {
struct TraceDescriptor {
STACK_ALLOCATED();
+
+ public:
void* base_object_payload;
TraceCallback callback;
bool can_trace_eagerly;
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 1033c658f78..6c515bc5c9f 100644
--- a/chromium/third_party/blink/renderer/platform/heap/gc_info.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/gc_info.cc
@@ -49,7 +49,7 @@ void GCInfoTable::CreateGlobalTable() {
}
void GCInfoTable::EnsureGCInfoIndex(const GCInfo* gc_info,
- size_t* gc_info_index_slot) {
+ uint32_t* gc_info_index_slot) {
DCHECK(gc_info);
DCHECK(gc_info_index_slot);
@@ -64,14 +64,13 @@ void GCInfoTable::EnsureGCInfoIndex(const GCInfo* gc_info,
if (*gc_info_index_slot)
return;
- int index = ++current_index_;
- size_t gc_info_index = static_cast<size_t>(index);
+ uint32_t gc_info_index = ++current_index_;
CHECK(gc_info_index < GCInfoTable::kMaxIndex);
if (current_index_ >= limit_)
Resize();
table_[gc_info_index] = gc_info;
- ReleaseStore(reinterpret_cast<int*>(gc_info_index_slot), index);
+ ReleaseStore(gc_info_index_slot, gc_info_index);
}
void GCInfoTable::Resize() {
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 b6e7e42f512..46eb0fdbb51 100644
--- a/chromium/third_party/blink/renderer/platform/heap/gc_info.h
+++ b/chromium/third_party/blink/renderer/platform/heap/gc_info.h
@@ -44,7 +44,7 @@ struct GCInfo {
};
#if DCHECK_IS_ON()
-PLATFORM_EXPORT void AssertObjectHasGCInfo(const void*, size_t gc_info_index);
+PLATFORM_EXPORT void AssertObjectHasGCInfo(const void*, uint32_t gc_info_index);
#endif
class PLATFORM_EXPORT GCInfoTable {
@@ -56,14 +56,14 @@ 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 size_t kMaxIndex = 1 << 14;
+ static constexpr uint32_t kMaxIndex = 1 << 14;
// Sets up a singleton table that can be acquired using Get().
static void CreateGlobalTable();
static GCInfoTable& Get() { return *global_table_; }
- inline const GCInfo* GCInfoFromIndex(size_t index) {
+ inline const GCInfo* GCInfoFromIndex(uint32_t index) {
DCHECK_GE(index, 1u);
DCHECK(index < kMaxIndex);
DCHECK(table_);
@@ -72,9 +72,9 @@ class PLATFORM_EXPORT GCInfoTable {
return info;
}
- void EnsureGCInfoIndex(const GCInfo*, size_t*);
+ void EnsureGCInfoIndex(const GCInfo*, uint32_t*);
- size_t GcInfoIndex() { return current_index_; }
+ uint32_t GcInfoIndex() { return current_index_; }
private:
FRIEND_TEST_ALL_PREFIXES(GCInfoTest, InitialEmpty);
@@ -95,10 +95,10 @@ class PLATFORM_EXPORT GCInfoTable {
// GCInfo indices start from 1 for heap objects, with 0 being treated
// specially as the index for freelist entries and large heap objects.
- size_t current_index_ = 0;
+ uint32_t current_index_ = 0;
// The limit (exclusive) of the currently allocated table.
- size_t limit_ = 0;
+ uint32_t limit_ = 0;
Mutex table_mutex_;
};
@@ -108,14 +108,14 @@ class PLATFORM_EXPORT GCInfoTable {
template <typename T>
struct GCInfoAtBaseType {
STATIC_ONLY(GCInfoAtBaseType);
- static size_t Index() {
+ static uint32_t Index() {
static_assert(sizeof(T), "T must be fully defined");
static const GCInfo kGcInfo = {
TraceTrait<T>::Trace, FinalizerTrait<T>::Finalize,
NameTrait<T>::GetName, FinalizerTrait<T>::kNonTrivialFinalizer,
std::is_polymorphic<T>::value,
};
- static size_t gc_info_index = 0;
+ static uint32_t gc_info_index = 0;
if (!AcquireLoad(&gc_info_index))
GCInfoTable::Get().EnsureGCInfoIndex(&kGcInfo, &gc_info_index);
DCHECK_GE(gc_info_index, 1u);
@@ -144,7 +144,7 @@ struct GetGarbageCollectedType<T, false> {
template <typename T>
struct GCInfoTrait {
STATIC_ONLY(GCInfoTrait);
- static size_t Index() {
+ static uint32_t Index() {
return GCInfoAtBaseType<typename GetGarbageCollectedType<T>::type>::Index();
}
};
@@ -158,13 +158,13 @@ template <typename T, typename U, typename V>
class HeapHashSet;
template <typename T, typename U, typename V>
class HeapLinkedHashSet;
-template <typename T, size_t inlineCapacity, typename U>
+template <typename T, wtf_size_t inlineCapacity, typename U>
class HeapListHashSet;
-template <typename ValueArg, size_t inlineCapacity>
+template <typename ValueArg, wtf_size_t inlineCapacity>
class HeapListHashSetAllocator;
-template <typename T, size_t inlineCapacity>
+template <typename T, wtf_size_t inlineCapacity>
class HeapVector;
-template <typename T, size_t inlineCapacity>
+template <typename T, wtf_size_t inlineCapacity>
class HeapDeque;
template <typename T, typename U, typename V>
class HeapHashCountedSet;
@@ -178,17 +178,17 @@ struct GCInfoTrait<HeapHashSet<T, U, V>>
template <typename T, typename U, typename V>
struct GCInfoTrait<HeapLinkedHashSet<T, U, V>>
: public GCInfoTrait<LinkedHashSet<T, U, V, HeapAllocator>> {};
-template <typename T, size_t inlineCapacity, typename U>
+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, size_t inlineCapacity>
+template <typename T, wtf_size_t inlineCapacity>
struct GCInfoTrait<HeapVector<T, inlineCapacity>>
: public GCInfoTrait<Vector<T, inlineCapacity, HeapAllocator>> {};
-template <typename T, size_t inlineCapacity>
+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>
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 d651be09c53..6447fc31900 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
@@ -16,8 +16,8 @@ TEST(GCInfoTest, InitialEmpty) {
TEST(GCInfoTest, ResizeToMaxIndex) {
GCInfoTable table;
GCInfo info = {nullptr, nullptr, nullptr, false, false};
- size_t slot = 0;
- for (size_t i = 0; i < (GCInfoTable::kMaxIndex - 1); i++) {
+ uint32_t slot = 0;
+ for (uint32_t i = 0; i < (GCInfoTable::kMaxIndex - 1); i++) {
slot = 0;
table.EnsureGCInfoIndex(&info, &slot);
EXPECT_LT(0u, slot);
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap.cc b/chromium/third_party/blink/renderer/platform/heap/heap.cc
index 7688dfb5f79..8a1dc1bd0d8 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/heap.cc
@@ -44,7 +44,6 @@
#include "third_party/blink/renderer/platform/heap/marking_visitor.h"
#include "third_party/blink/renderer/platform/heap/page_memory.h"
#include "third_party/blink/renderer/platform/heap/page_pool.h"
-#include "third_party/blink/renderer/platform/heap/safe_point.h"
#include "third_party/blink/renderer/platform/heap/thread_state.h"
#include "third_party/blink/renderer/platform/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
@@ -199,25 +198,16 @@ HeapCompact* ThreadHeap::Compaction() {
}
void ThreadHeap::RegisterMovingObjectReference(MovableReference* slot) {
- DCHECK(slot);
- DCHECK(*slot);
Compaction()->RegisterMovingObjectReference(slot);
}
-void ThreadHeap::RegisterMovingObjectCallback(MovableReference reference,
+void ThreadHeap::RegisterMovingObjectCallback(MovableReference* slot,
MovingObjectCallback callback,
void* callback_data) {
- DCHECK(reference);
- Compaction()->RegisterMovingObjectCallback(reference, callback,
- callback_data);
+ Compaction()->RegisterMovingObjectCallback(slot, callback, callback_data);
}
-void ThreadHeap::ProcessMarkingStack(Visitor* visitor) {
- bool complete = AdvanceMarkingStackProcessing(visitor, TimeTicks::Max());
- CHECK(complete);
-}
-
-void ThreadHeap::MarkNotFullyConstructedObjects(Visitor* visitor) {
+void ThreadHeap::MarkNotFullyConstructedObjects(MarkingVisitor* visitor) {
DCHECK(!thread_state_->IsIncrementalMarking());
ThreadHeapStatsCollector::Scope stats_scope(
stats_collector(),
@@ -227,8 +217,7 @@ void ThreadHeap::MarkNotFullyConstructedObjects(Visitor* visitor) {
while (
not_fully_constructed_worklist_->Pop(WorklistTaskId::MainThread, &item)) {
BasePage* const page = PageFromObject(item);
- reinterpret_cast<MarkingVisitor*>(visitor)->ConservativelyMarkAddress(
- page, reinterpret_cast<Address>(item));
+ visitor->ConservativelyMarkAddress(page, reinterpret_cast<Address>(item));
}
}
@@ -256,8 +245,7 @@ void ThreadHeap::InvokeEphemeronCallbacks(Visitor* visitor) {
ephemeron_callbacks_ = std::move(final_set);
}
-bool ThreadHeap::AdvanceMarkingStackProcessing(Visitor* visitor,
- TimeTicks deadline) {
+bool ThreadHeap::AdvanceMarking(MarkingVisitor* visitor, TimeTicks deadline) {
const size_t kDeadlineCheckInterval = 2500;
size_t processed_callback_count = 0;
// Ephemeron fixed point loop.
@@ -324,25 +312,7 @@ size_t ThreadHeap::ObjectPayloadSizeForTesting() {
return object_payload_size;
}
-void ThreadHeap::VisitPersistentRoots(Visitor* visitor) {
- ThreadHeapStatsCollector::Scope stats_scope(
- stats_collector(), ThreadHeapStatsCollector::kVisitPersistentRoots);
- DCHECK(thread_state_->InAtomicMarkingPause());
- thread_state_->VisitPersistents(visitor);
-}
-
-void ThreadHeap::VisitStackRoots(MarkingVisitor* visitor) {
- ThreadHeapStatsCollector::Scope stats_scope(
- stats_collector(), ThreadHeapStatsCollector::kVisitStackRoots);
- DCHECK(thread_state_->InAtomicMarkingPause());
- address_cache_->FlushIfDirty();
- address_cache_->EnableLookup();
- thread_state_->VisitStack(visitor);
- address_cache_->DisableLookup();
-}
-
BasePage* ThreadHeap::LookupPageForAddress(Address address) {
- DCHECK(thread_state_->InAtomicMarkingPause());
if (PageMemoryRegion* region = region_tree_->Lookup(address)) {
return region->PageFromAddress(address);
}
@@ -430,8 +400,8 @@ int ThreadHeap::ArenaIndexOfVectorArenaLeastRecentlyExpanded(
return arena_index_with_min_arena_age;
}
-BaseArena* ThreadHeap::ExpandedVectorBackingArena(size_t gc_info_index) {
- size_t entry_index = gc_info_index & kLikelyToBePromptlyFreedArrayMask;
+BaseArena* ThreadHeap::ExpandedVectorBackingArena(uint32_t gc_info_index) {
+ uint32_t entry_index = gc_info_index & kLikelyToBePromptlyFreedArrayMask;
--likely_to_be_promptly_freed_[entry_index];
int arena_index = vector_backing_arena_index_;
arena_ages_[arena_index] = ++current_arena_ages_;
@@ -448,9 +418,9 @@ void ThreadHeap::AllocationPointAdjusted(int arena_index) {
}
}
-void ThreadHeap::PromptlyFreed(size_t gc_info_index) {
+void ThreadHeap::PromptlyFreed(uint32_t gc_info_index) {
DCHECK(thread_state_->CheckThread());
- size_t entry_index = gc_info_index & kLikelyToBePromptlyFreedArrayMask;
+ uint32_t entry_index = gc_info_index & kLikelyToBePromptlyFreedArrayMask;
// See the comment in vectorBackingArena() for why this is +3.
likely_to_be_promptly_freed_[entry_index] += 3;
}
@@ -550,7 +520,7 @@ void ThreadHeap::TakeSnapshot(SnapshotType type) {
size_t total_dead_count = 0;
size_t total_live_size = 0;
size_t total_dead_size = 0;
- for (size_t gc_info_index = 1;
+ for (uint32_t gc_info_index = 1;
gc_info_index <= GCInfoTable::Get().GcInfoIndex(); ++gc_info_index) {
total_live_count += info.live_count[gc_info_index];
total_dead_count += info.dead_count[gc_info_index];
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap.h b/chromium/third_party/blink/renderer/platform/heap/heap.h
index 1623c4188ce..499750ce30a 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap.h
+++ b/chromium/third_party/blink/renderer/platform/heap/heap.h
@@ -203,11 +203,6 @@ class PLATFORM_EXPORT ThreadHeap {
return weak_callback_worklist_.get();
}
- void VisitPersistentRoots(Visitor*);
- void VisitStackRoots(MarkingVisitor*);
- void EnterSafePoint(ThreadState*);
- void LeaveSafePoint();
-
// Is the finalizable GC object still alive, but slated for lazy sweeping?
// If a lazy sweep is in progress, returns true if the object was found
// to be not reachable during the marking phase, but it has yet to be swept
@@ -262,7 +257,7 @@ class PLATFORM_EXPORT ThreadHeap {
//
// For Blink, |HeapLinkedHashSet<>| is currently the only abstraction which
// relies on this feature.
- void RegisterMovingObjectCallback(MovableReference,
+ void RegisterMovingObjectCallback(MovableReference*,
MovingObjectCallback,
void* callback_data);
@@ -280,17 +275,19 @@ class PLATFORM_EXPORT ThreadHeap {
Address AllocateOnArenaIndex(ThreadState*,
size_t,
int arena_index,
- size_t gc_info_index,
+ uint32_t gc_info_index,
const char* type_name);
template <typename T>
static Address Allocate(size_t, bool eagerly_sweep = false);
template <typename T>
static Address Reallocate(void* previous, size_t);
- void ProcessMarkingStack(Visitor*);
void WeakProcessing(Visitor*);
- void MarkNotFullyConstructedObjects(Visitor*);
- bool AdvanceMarkingStackProcessing(Visitor*, TimeTicks deadline);
+
+ // Marks not fully constructed objects.
+ void MarkNotFullyConstructedObjects(MarkingVisitor*);
+ // Marks the transitive closure including ephemerons.
+ bool AdvanceMarking(MarkingVisitor*, TimeTicks deadline);
void VerifyMarking();
// Conservatively checks whether an address is a pointer in any of the
@@ -304,7 +301,7 @@ class PLATFORM_EXPORT ThreadHeap {
size_t ObjectPayloadSizeForTesting();
- AddressCache* address_cache() { return address_cache_.get(); }
+ AddressCache* address_cache() const { return address_cache_.get(); }
PagePool* GetFreePagePool() { return free_page_pool_.get(); }
@@ -350,9 +347,9 @@ class PLATFORM_EXPORT ThreadHeap {
// (*) More than 33% of the same type of vectors have been promptly
// freed since the last GC.
//
- BaseArena* VectorBackingArena(size_t gc_info_index) {
+ BaseArena* VectorBackingArena(uint32_t gc_info_index) {
DCHECK(thread_state_->CheckThread());
- size_t entry_index = gc_info_index & kLikelyToBePromptlyFreedArrayMask;
+ uint32_t entry_index = gc_info_index & kLikelyToBePromptlyFreedArrayMask;
--likely_to_be_promptly_freed_[entry_index];
int arena_index = vector_backing_arena_index_;
// If likely_to_be_promptly_freed_[entryIndex] > 0, that means that
@@ -367,14 +364,14 @@ class PLATFORM_EXPORT ThreadHeap {
DCHECK(IsVectorArenaIndex(arena_index));
return arenas_[arena_index];
}
- BaseArena* ExpandedVectorBackingArena(size_t gc_info_index);
+ BaseArena* ExpandedVectorBackingArena(uint32_t gc_info_index);
static bool IsVectorArenaIndex(int arena_index) {
return BlinkGC::kVector1ArenaIndex <= arena_index &&
arena_index <= BlinkGC::kVector4ArenaIndex;
}
static bool IsNormalArenaIndex(int);
void AllocationPointAdjusted(int arena_index);
- void PromptlyFreed(size_t gc_info_index);
+ void PromptlyFreed(uint32_t gc_info_index);
void ClearArenaAges();
int ArenaIndexOfVectorArenaLeastRecentlyExpanded(int begin_arena_index,
int end_arena_index);
@@ -602,7 +599,7 @@ class VerifyEagerFinalization {
inline Address ThreadHeap::AllocateOnArenaIndex(ThreadState* state,
size_t size,
int arena_index,
- size_t gc_info_index,
+ uint32_t gc_info_index,
const char* type_name) {
DCHECK(state->IsAllocationAllowed());
DCHECK_NE(arena_index, BlinkGC::kLargeObjectArenaIndex);
@@ -651,7 +648,7 @@ Address ThreadHeap::Reallocate(void* previous, size_t size) {
arena_index = ArenaIndexForObjectSize(size);
}
- size_t gc_info_index = GCInfoTrait<T>::Index();
+ uint32_t gc_info_index = GCInfoTrait<T>::Index();
// TODO(haraken): We don't support reallocate() for finalizable objects.
DCHECK(!GCInfoTable::Get()
.GCInfoFromIndex(previous_header->GcInfoIndex())
@@ -677,11 +674,17 @@ Address ThreadHeap::Reallocate(void* previous, size_t size) {
template <typename T>
void Visitor::HandleWeakCell(Visitor* self, void* object) {
T** cell = reinterpret_cast<T**>(object);
- // '-1' means deleted value. This can happen when weak fields are deleted
- // while incremental marking is running.
- if (*cell && (*cell == reinterpret_cast<T*>(-1) ||
- !ObjectAliveTrait<T>::IsHeapObjectAlive(*cell)))
- *cell = nullptr;
+ T* contents = *cell;
+ if (contents) {
+ if (contents == reinterpret_cast<T*>(-1)) {
+ // '-1' means deleted value. This can happen when weak fields are deleted
+ // while incremental marking is running. Deleted values need to be
+ // preserved to avoid reviving objects in containers.
+ return;
+ }
+ if (!ObjectAliveTrait<T>::IsHeapObjectAlive(contents))
+ *cell = nullptr;
+ }
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_allocator.cc b/chromium/third_party/blink/renderer/platform/heap/heap_allocator.cc
index 7791505bbcd..411f19a7878 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_allocator.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/heap_allocator.cc
@@ -40,8 +40,10 @@ void HeapAllocator::FreeInlineVectorBacking(void* address) {
BackingFree(address);
}
-void HeapAllocator::FreeHashTableBacking(void* address, bool is_weak_table) {
- if (!ThreadState::Current()->IsMarkingInProgress() || !is_weak_table)
+void HeapAllocator::FreeHashTableBacking(void* address) {
+ // When incremental marking is enabled weak callbacks may have been
+ // registered.
+ if (!ThreadState::Current()->IsMarkingInProgress())
BackingFree(address);
}
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 ab841704e2e..ec3b12684c6 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_allocator.h
+++ b/chromium/third_party/blink/renderer/platform/heap/heap_allocator.h
@@ -72,7 +72,7 @@ class PLATFORM_EXPORT HeapAllocator {
ThreadState* state =
ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState();
DCHECK(state->IsAllocationAllowed());
- size_t gc_info_index = GCInfoTrait<HeapVectorBacking<T>>::Index();
+ uint32_t gc_info_index = GCInfoTrait<HeapVectorBacking<T>>::Index();
NormalPageArena* arena = static_cast<NormalPageArena*>(
state->Heap().VectorBackingArena(gc_info_index));
return reinterpret_cast<T*>(arena->AllocateObject(
@@ -83,7 +83,7 @@ class PLATFORM_EXPORT HeapAllocator {
ThreadState* state =
ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState();
DCHECK(state->IsAllocationAllowed());
- size_t gc_info_index = GCInfoTrait<HeapVectorBacking<T>>::Index();
+ uint32_t gc_info_index = GCInfoTrait<HeapVectorBacking<T>>::Index();
NormalPageArena* arena = static_cast<NormalPageArena*>(
state->Heap().ExpandedVectorBackingArena(gc_info_index));
return reinterpret_cast<T*>(arena->AllocateObject(
@@ -96,7 +96,7 @@ class PLATFORM_EXPORT HeapAllocator {
size_t quantized_shrunk_size);
template <typename T>
static T* AllocateInlineVectorBacking(size_t size) {
- size_t gc_info_index = GCInfoTrait<HeapVectorBacking<T>>::Index();
+ uint32_t gc_info_index = GCInfoTrait<HeapVectorBacking<T>>::Index();
ThreadState* state =
ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState();
const char* type_name = WTF_HEAP_PROFILER_TYPE_NAME(HeapVectorBacking<T>);
@@ -112,7 +112,7 @@ class PLATFORM_EXPORT HeapAllocator {
template <typename T, typename HashTable>
static T* AllocateHashTableBacking(size_t size) {
- size_t gc_info_index =
+ uint32_t gc_info_index =
GCInfoTrait<HeapHashTableBacking<HashTable>>::Index();
ThreadState* state =
ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState();
@@ -125,7 +125,7 @@ class PLATFORM_EXPORT HeapAllocator {
static T* AllocateZeroedHashTableBacking(size_t size) {
return AllocateHashTableBacking<T, HashTable>(size);
}
- static void FreeHashTableBacking(void* address, bool is_weak_table);
+ static void FreeHashTableBacking(void* address);
static bool ExpandHashTableBacking(void*, size_t);
static void TraceMarkedBackingStore(void* address) {
@@ -192,11 +192,11 @@ class PLATFORM_EXPORT HeapAllocator {
template <typename T, typename VisitorDispatcher>
static void RegisterBackingStoreCallback(VisitorDispatcher visitor,
- T* backing_store,
+ T** backing_store_slot,
MovingObjectCallback callback,
void* callback_data) {
- visitor->RegisterBackingStoreCallback(backing_store, callback,
- callback_data);
+ visitor->RegisterBackingStoreCallback(
+ reinterpret_cast<void**>(backing_store_slot), callback, callback_data);
}
static void EnterGCForbiddenScope() {
@@ -309,7 +309,7 @@ class PLATFORM_EXPORT HeapAllocator {
size_t quantized_current_size,
size_t quantized_shrunk_size);
- template <typename T, size_t u, typename V>
+ template <typename T, wtf_size_t u, typename V>
friend class WTF::Vector;
template <typename T, typename U, typename V, typename W>
friend class WTF::HashSet;
@@ -339,7 +339,7 @@ static void TraceListHashSetValue(VisitorDispatcher visitor, Value& value) {
// This inherits from the static-only HeapAllocator trait class, but we do
// declare pointers to instances. These pointers are always null, and no
// objects are instantiated.
-template <typename ValueArg, size_t inlineCapacity>
+template <typename ValueArg, wtf_size_t inlineCapacity>
class HeapListHashSetAllocator : public HeapAllocator {
DISALLOW_NEW();
@@ -477,8 +477,9 @@ class HeapLinkedHashSet
};
template <typename ValueArg,
- size_t inlineCapacity = 0, // The inlineCapacity is just a dummy to
- // match ListHashSet (off-heap).
+ wtf_size_t inlineCapacity =
+ 0, // The inlineCapacity is just a dummy to
+ // match ListHashSet (off-heap).
typename HashArg = typename DefaultHash<ValueArg>::Hash>
class HeapListHashSet
: public ListHashSet<ValueArg,
@@ -502,7 +503,7 @@ class HeapHashCountedSet
"HashCountedSet<> instead of HeapHashCountedSet<>");
};
-template <typename T, size_t inlineCapacity = 0>
+template <typename T, wtf_size_t inlineCapacity = 0>
class HeapVector : public Vector<T, inlineCapacity, HeapAllocator> {
IS_GARBAGE_COLLECTED_TYPE();
using Base = Vector<T, inlineCapacity, HeapAllocator>;
@@ -538,18 +539,18 @@ class HeapVector : public Vector<T, inlineCapacity, HeapAllocator> {
return Base::operator new(size, location);
}
- explicit HeapVector(size_t size)
+ explicit HeapVector(wtf_size_t size)
: Vector<T, inlineCapacity, HeapAllocator>(size) {}
- HeapVector(size_t size, const T& val)
+ HeapVector(wtf_size_t size, const T& val)
: Vector<T, inlineCapacity, HeapAllocator>(size, val) {}
- template <size_t otherCapacity>
+ template <wtf_size_t otherCapacity>
HeapVector(const HeapVector<T, otherCapacity>& other)
: Vector<T, inlineCapacity, HeapAllocator>(other) {}
};
-template <typename T, size_t inlineCapacity = 0>
+template <typename T, wtf_size_t inlineCapacity = 0>
class HeapDeque : public Deque<T, inlineCapacity, HeapAllocator> {
IS_GARBAGE_COLLECTED_TYPE();
using Base = Deque<T, inlineCapacity, HeapAllocator>;
@@ -585,10 +586,10 @@ class HeapDeque : public Deque<T, inlineCapacity, HeapAllocator> {
return Base::operator new(size, location);
}
- explicit HeapDeque(size_t size)
+ explicit HeapDeque(wtf_size_t size)
: Deque<T, inlineCapacity, HeapAllocator>(size) {}
- HeapDeque(size_t size, const T& val)
+ HeapDeque(wtf_size_t size, const T& val)
: Deque<T, inlineCapacity, HeapAllocator>(size, val) {}
HeapDeque& operator=(const HeapDeque& other) {
@@ -597,7 +598,7 @@ class HeapDeque : public Deque<T, inlineCapacity, HeapAllocator> {
return *this;
}
- template <size_t otherCapacity>
+ template <wtf_size_t otherCapacity>
HeapDeque(const HeapDeque<T, otherCapacity>& other)
: Deque<T, inlineCapacity, HeapAllocator>(other) {}
};
@@ -712,7 +713,7 @@ struct VectorTraits<blink::HeapDeque<T, 0>>
static const bool kCanMoveWithMemcpy = true;
};
-template <typename T, size_t inlineCapacity>
+template <typename T, wtf_size_t inlineCapacity>
struct VectorTraits<blink::HeapVector<T, inlineCapacity>>
: VectorTraitsBase<blink::HeapVector<T, inlineCapacity>> {
STATIC_ONLY(VectorTraits);
@@ -724,7 +725,7 @@ struct VectorTraits<blink::HeapVector<T, inlineCapacity>>
static const bool kCanMoveWithMemcpy = VectorTraits<T>::kCanMoveWithMemcpy;
};
-template <typename T, size_t inlineCapacity>
+template <typename T, wtf_size_t inlineCapacity>
struct VectorTraits<blink::HeapDeque<T, inlineCapacity>>
: VectorTraitsBase<blink::HeapDeque<T, inlineCapacity>> {
STATIC_ONLY(VectorTraits);
@@ -915,7 +916,7 @@ struct HashTraits<blink::UntracedMember<T>>
}
};
-template <typename T, size_t inlineCapacity>
+template <typename T, wtf_size_t inlineCapacity>
struct IsTraceable<
ListHashSetNode<T, blink::HeapListHashSetAllocator<T, inlineCapacity>>*> {
STATIC_ONLY(IsTraceable);
@@ -926,7 +927,7 @@ struct IsTraceable<
static const bool value = true;
};
-template <typename T, size_t inlineCapacity>
+template <typename T, wtf_size_t inlineCapacity>
struct IsGarbageCollectedType<
ListHashSetNode<T, blink::HeapListHashSetAllocator<T, inlineCapacity>>> {
static const bool value = true;
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 4594fbfd18a..4b6e34ce42b 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_compact.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/heap_compact.cc
@@ -13,7 +13,6 @@
#include "third_party/blink/renderer/platform/histogram.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
-#include "third_party/blink/renderer/platform/wtf/hash_set.h"
#include "third_party/blink/renderer/platform/wtf/time.h"
namespace blink {
@@ -29,8 +28,8 @@ bool HeapCompact::force_compaction_gc_ = false;
// heap compaction-enhanced GC.
class HeapCompact::MovableObjectFixups final {
public:
- static std::unique_ptr<MovableObjectFixups> Create() {
- return base::WrapUnique(new MovableObjectFixups);
+ static std::unique_ptr<MovableObjectFixups> Create(ThreadHeap* heap) {
+ return base::WrapUnique(new MovableObjectFixups(heap));
}
~MovableObjectFixups() = default;
@@ -61,14 +60,23 @@ class HeapCompact::MovableObjectFixups final {
}
void Add(MovableReference* slot) {
+ DCHECK(*slot);
MovableReference reference = *slot;
- BasePage* ref_page = PageFromObject(reference);
+ BasePage* ref_page =
+ heap_->LookupPageForAddress(reinterpret_cast<Address>(reference));
+
+ // 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.
+ if (!ref_page)
+ return;
// Nothing to compact on a large object's page.
if (ref_page->IsLargeObjectPage())
return;
+ if (!HeapCompact::IsCompactableArena(ref_page->Arena()->ArenaIndex()))
+ return;
#if DCHECK_IS_ON()
- DCHECK(HeapCompact::IsCompactableArena(ref_page->Arena()->ArenaIndex()));
auto it = fixups_.find(reference);
DCHECK(it == fixups_.end() || it->value == slot);
#endif
@@ -107,12 +115,18 @@ class HeapCompact::MovableObjectFixups final {
AddInteriorFixup(slot);
}
- void AddFixupCallback(MovableReference reference,
+ void AddFixupCallback(MovableReference* slot,
MovingObjectCallback callback,
void* callback_data) {
- DCHECK(!fixup_callbacks_.Contains(reference));
- fixup_callbacks_.insert(reference, std::pair<void*, MovingObjectCallback>(
- callback_data, callback));
+ DCHECK(!fixup_callbacks_.Contains(slot));
+ fixup_callbacks_.insert(
+ slot, std::pair<void*, MovingObjectCallback>(callback_data, callback));
+ }
+
+ void RemoveFixupCallback(MovableReference* slot) {
+ auto it = fixup_callbacks_.find(slot);
+ if (it != fixup_callbacks_.end())
+ fixup_callbacks_.erase(it);
}
void RelocateInteriorFixups(Address from, Address to, size_t size) {
@@ -124,25 +138,22 @@ class HeapCompact::MovableObjectFixups final {
// to adjust. If the backing store of such an interior slot hasn't
// been moved already, update the slot -> real location mapping.
// When the backing store is eventually moved, it'll use that location.
- //
for (size_t offset = 0; offset < size; offset += sizeof(void*)) {
- if (!range->IsSet(from + offset))
- continue;
MovableReference* slot =
reinterpret_cast<MovableReference*>(from + offset);
+
+ // Early bailout.
+ if (!range->IsSet(reinterpret_cast<Address>(slot)))
+ continue;
+
auto it = interior_fixups_.find(slot);
if (it == interior_fixups_.end())
continue;
- // TODO: with the right sparse bitmap representation, it could be possible
- // to quickly determine if we've now stepped past the last address
- // that needed fixup in [address, address + size). Breaking out of this
- // loop might be worth doing for hash table backing stores with a very
- // low load factor. But interior fixups are rare.
-
// If |slot|'s mapping is set, then the slot has been adjusted already.
if (it->value)
continue;
+
Address fixup = to + offset;
LOG_HEAP_COMPACTION() << "Range interior fixup: " << (from + offset)
<< " " << it->value << " " << fixup;
@@ -151,16 +162,37 @@ class HeapCompact::MovableObjectFixups final {
// moved/compacted, it'll update |to + offset| with a pointer to the
// moved backing store.
interior_fixups_.Set(slot, fixup);
+
+ // If the |slot|'s content is pointing into the region [from, from + size)
+ // we are dealing with an interior pointer that does not point to a valid
+ // HeapObjectHeader. Such references need to be fixed up immediately.
+ Address fixup_contents = *reinterpret_cast<Address*>(fixup);
+ if (fixup_contents > from && fixup_contents < (from + size)) {
+ *reinterpret_cast<Address*>(fixup) = fixup_contents - from + to;
+ continue;
+ }
}
}
void Relocate(Address from, Address to) {
auto it = fixups_.find(from);
- DCHECK(it != fixups_.end());
+ // This means that there is no corresponding slot for a live backing store.
+ // This may happen because a mutator may change the slot to point to a
+ // different backing store because e.g.:
+ // - Incremental marking marked a backing store as live that was later on
+ // replaced.
+ // - Backings were changed when being processed in
+ // EagerSweep/PreFinalizer/WeakProcessing.
+ if (it == fixups_.end())
+ return;
+
#if DCHECK_IS_ON()
BasePage* from_page = PageFromObject(from);
DCHECK(relocatable_pages_.Contains(from_page));
#endif
+
+ // If the object is referenced by a slot that is contained on a compacted
+ // area itself, check whether it can be updated already.
MovableReference* slot = reinterpret_cast<MovableReference*>(it->value);
auto interior = interior_fixups_.find(slot);
if (interior != interior_fixups_.end()) {
@@ -174,6 +206,7 @@ class HeapCompact::MovableObjectFixups final {
slot = slot_location;
}
}
+
// If the slot has subsequently been updated, a prefinalizer or
// a destructor having mutated and expanded/shrunk the collection,
// do not update and relocate the slot -- |from| is no longer valid
@@ -185,27 +218,19 @@ class HeapCompact::MovableObjectFixups final {
LOG_HEAP_COMPACTION()
<< "No relocation: slot = " << slot << ", *slot = " << *slot
<< ", from = " << from << ", to = " << to;
-#if DCHECK_IS_ON()
- // Verify that the already updated slot is valid, meaning:
- // - has been cleared.
- // - has been updated & expanded with a large object backing store.
- // - has been updated with a larger, freshly allocated backing store.
- // (on a fresh page in a compactable arena that is not being
- // compacted.)
- if (!*slot)
- return;
- BasePage* slot_page = PageFromObject(*slot);
- DCHECK(
- slot_page->IsLargeObjectPage() ||
- (HeapCompact::IsCompactableArena(slot_page->Arena()->ArenaIndex()) &&
- !relocatable_pages_.Contains(slot_page)));
-#endif
+ VerifyUpdatedSlot(slot);
return;
}
+
+ // Update the slots new value.
*slot = to;
size_t size = 0;
- auto callback = fixup_callbacks_.find(from);
+
+ // Execute potential fixup callbacks.
+ MovableReference* callback_slot =
+ reinterpret_cast<MovableReference*>(it->value);
+ auto callback = fixup_callbacks_.find(callback_slot);
if (UNLIKELY(callback != fixup_callbacks_.end())) {
size = HeapObjectHeader::FromPayload(to)->PayloadSize();
callback->value.second(callback->value.first, from, to, size);
@@ -231,7 +256,11 @@ class HeapCompact::MovableObjectFixups final {
#endif
private:
- MovableObjectFixups() = default;
+ MovableObjectFixups(ThreadHeap* heap) : heap_(heap) {}
+
+ void VerifyUpdatedSlot(MovableReference* slot);
+
+ ThreadHeap* heap_;
// Tracking movable and updatable references. For now, we keep a
// map which for each movable object, recording the slot that
@@ -243,7 +272,7 @@ class HeapCompact::MovableObjectFixups final {
// Map from movable reference to callbacks that need to be invoked
// when the object moves.
- HashMap<MovableReference, std::pair<void*, MovingObjectCallback>>
+ HashMap<MovableReference*, std::pair<void*, MovingObjectCallback>>
fixup_callbacks_;
// Slot => relocated slot/final location.
@@ -257,6 +286,30 @@ class HeapCompact::MovableObjectFixups final {
std::unique_ptr<SparseHeapBitmap> interiors_;
};
+void HeapCompact::MovableObjectFixups::VerifyUpdatedSlot(
+ MovableReference* slot) {
+// Verify that the already updated slot is valid, meaning:
+// - has been cleared.
+// - has been updated & expanded with a large object backing store.
+// - has been updated with a larger, freshly allocated backing store.
+// (on a fresh page in a compactable arena that is not being
+// compacted.)
+#if DCHECK_IS_ON()
+ if (!*slot)
+ return;
+ BasePage* slot_page =
+ heap_->LookupPageForAddress(reinterpret_cast<Address>(*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.
+ if (!slot_page)
+ return;
+ DCHECK(slot_page->IsLargeObjectPage() ||
+ (HeapCompact::IsCompactableArena(slot_page->Arena()->ArenaIndex()) &&
+ !relocatable_pages_.Contains(slot_page)));
+#endif // DCHECK_IS_ON()
+}
+
HeapCompact::HeapCompact(ThreadHeap* heap)
: heap_(heap),
do_compact_(false),
@@ -283,7 +336,7 @@ HeapCompact::~HeapCompact() = default;
HeapCompact::MovableObjectFixups& HeapCompact::Fixups() {
if (!fixups_)
- fixups_ = MovableObjectFixups::Create();
+ fixups_ = MovableObjectFixups::Create(heap_);
return *fixups_;
}
@@ -301,12 +354,6 @@ bool HeapCompact::ShouldCompact(ThreadHeap* heap,
<< " count=" << gc_count_since_last_compaction_
<< " free=" << free_list_size_;
gc_count_since_last_compaction_++;
- // It is only safe to compact during non-conservative GCs.
- // TODO: for the main thread, limit this further to only idle GCs.
- if (reason != BlinkGC::GCReason::kIdleGC &&
- reason != BlinkGC::GCReason::kPreciseGC &&
- reason != BlinkGC::GCReason::kForcedGC)
- return false;
// If the GCing thread requires a stack scan, do not compact.
// Why? Should the stack contain an iterator pointing into its
@@ -315,10 +362,22 @@ bool HeapCompact::ShouldCompact(ThreadHeap* heap,
if (stack_state == BlinkGC::kHeapPointersOnStack)
return false;
+ if (reason == BlinkGC::GCReason::kTesting) {
+ UpdateHeapResidency();
+ return force_compaction_gc_;
+ }
+
// TODO(keishi): Should be enable after fixing the crashes.
if (marking_type == BlinkGC::kIncrementalMarking)
return false;
+ // TODO(harukamt): Add kIncrementalIdleGC and kIncrementalV8FollowupGC when we
+ // enable heap compaction for incremental marking.
+ if (reason != BlinkGC::GCReason::kIdleGC &&
+ reason != BlinkGC::GCReason::kPreciseGC &&
+ reason != BlinkGC::GCReason::kForcedGC)
+ return false;
+
// Compaction enable rules:
// - It's been a while since the last time.
// - "Considerable" amount of heap memory is bound up in freelist
@@ -353,20 +412,27 @@ void HeapCompact::Initialize(ThreadState* state) {
force_compaction_gc_ = false;
}
+void HeapCompact::RemoveSlot(MovableReference* slot) {
+ auto it = traced_slots_.find(slot);
+ if (it != traced_slots_.end())
+ traced_slots_.erase(it);
+ Fixups().RemoveFixupCallback(slot);
+}
+
void HeapCompact::RegisterMovingObjectReference(MovableReference* slot) {
if (!do_compact_)
return;
- Fixups().Add(slot);
+ traced_slots_.insert(slot);
}
-void HeapCompact::RegisterMovingObjectCallback(MovableReference reference,
+void HeapCompact::RegisterMovingObjectCallback(MovableReference* slot,
MovingObjectCallback callback,
void* callback_data) {
if (!do_compact_)
return;
- Fixups().AddFixupCallback(reference, callback, callback_data);
+ Fixups().AddFixupCallback(slot, callback, callback_data);
}
void HeapCompact::UpdateHeapResidency() {
@@ -415,13 +481,19 @@ void HeapCompact::FinishedArenaCompaction(NormalPageArena* arena,
}
void HeapCompact::Relocate(Address from, Address to) {
- DCHECK(fixups_);
- fixups_->Relocate(from, to);
+ Fixups().Relocate(from, to);
}
void HeapCompact::StartThreadCompaction() {
if (!do_compact_)
return;
+
+ // The mapping between the slots and the backing stores are created
+ for (auto** slot : traced_slots_) {
+ if (*slot)
+ Fixups().Add(slot);
+ }
+ traced_slots_.clear();
}
void HeapCompact::FinishThreadCompaction() {
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 dc32e77b229..780e72f56a4 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_compact.h
+++ b/chromium/third_party/blink/renderer/platform/heap/heap_compact.h
@@ -10,6 +10,7 @@
#include "base/memory/ptr_util.h"
#include "third_party/blink/renderer/platform/heap/blink_gc.h"
#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/hash_set.h"
#include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
#include <bitset>
@@ -35,12 +36,18 @@
namespace blink {
+namespace incremental_marking_test {
+class IncrementalMarkingTestDriver;
+}
+
class NormalPageArena;
class BasePage;
class ThreadState;
class ThreadHeap;
class PLATFORM_EXPORT HeapCompact final {
+ friend class incremental_marking_test::IncrementalMarkingTestDriver;
+
public:
static std::unique_ptr<HeapCompact> Create(ThreadHeap* heap) {
return base::WrapUnique(new HeapCompact(heap));
@@ -48,6 +55,10 @@ class PLATFORM_EXPORT HeapCompact final {
~HeapCompact();
+ // Remove slot from traced_slots_ when a registered slot is destructed by
+ // mutator
+ void RemoveSlot(MovableReference* slot);
+
// Determine if a GC for the given type and reason should also perform
// additional heap compaction.
//
@@ -80,7 +91,7 @@ class PLATFORM_EXPORT HeapCompact final {
void RegisterMovingObjectReference(MovableReference* slot);
// See |Heap::registerMovingObjectCallback()| documentation.
- void RegisterMovingObjectCallback(MovableReference,
+ void RegisterMovingObjectCallback(MovableReference*,
MovingObjectCallback,
void* callback_data);
@@ -164,6 +175,11 @@ class PLATFORM_EXPORT HeapCompact final {
// the range of BlinkGC::ArenaIndices.
unsigned compactable_arenas_;
+ // The set is to remember slots that traced during
+ // marking phases. The mapping between the slots and the backing stores are
+ // created at the atomic pause phase.
+ HashSet<MovableReference*> traced_slots_;
+
static bool force_compaction_gc_;
};
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 2dcb6ab1e90..7ecb8bfe27a 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
@@ -491,6 +491,38 @@ TEST(HeapCompactTest, CompactLinkedHashSetNested) {
}
}
+TEST(HeapCompactTest, CompactInlinedBackingStore) {
+ // Regression test: https://crbug.com/875044
+ //
+ // This test checks that compaction properly updates pointers to statically
+ // allocated inline backings, see e.g. Vector::inline_buffer_.
+
+ // Use a Key with pre-defined hash traits.
+ using Key = Member<IntWrapper>;
+ // Value uses a statically allocated inline backing of size 64. As long as no
+ // more than elements are added no out-of-line allocation is triggered.
+ // The internal forwarding pointer to the inlined storage needs to be handled
+ // by compaction.
+ using Value = HeapVector<Member<IntWrapper>, 64>;
+ using MapWithInlinedBacking = HeapHashMap<Key, Value>;
+
+ Persistent<MapWithInlinedBacking> map = new MapWithInlinedBacking;
+ {
+ // Create a map that is reclaimed during compaction.
+ (new MapWithInlinedBacking)
+ ->insert(IntWrapper::Create(1, HashTablesAreCompacted), Value());
+
+ IntWrapper* wrapper = IntWrapper::Create(1, HashTablesAreCompacted);
+ Value storage;
+ storage.push_front(wrapper);
+ map->insert(wrapper, std::move(storage));
+ }
+ PerformHeapCompaction();
+ // The first GC should update the pointer accordingly and thus not crash on
+ // the second GC.
+ PerformHeapCompaction();
+}
+
} // namespace blink
#endif // ENABLE_HEAP_COMPACTION
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 47b4c3d7fed..c5552d65116 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_page.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/heap_page.cc
@@ -42,7 +42,6 @@
#include "third_party/blink/renderer/platform/heap/marking_verifier.h"
#include "third_party/blink/renderer/platform/heap/page_memory.h"
#include "third_party/blink/renderer/platform/heap/page_pool.h"
-#include "third_party/blink/renderer/platform/heap/safe_point.h"
#include "third_party/blink/renderer/platform/heap/thread_state.h"
#include "third_party/blink/renderer/platform/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
@@ -1496,6 +1495,7 @@ void NormalPage::SweepAndCompact(CompactionContext& context) {
void NormalPage::MakeConsistentForMutator() {
object_start_bit_map()->Clear();
+ size_t marked_object_size = 0;
Address start_of_gap = Payload();
NormalPageArena* normal_arena = ArenaForNormalPage();
for (Address header_address = Payload(); header_address < PayloadEnd();) {
@@ -1519,6 +1519,7 @@ void NormalPage::MakeConsistentForMutator() {
normal_arena->AddToFreeList(start_of_gap, header_address - start_of_gap);
if (header->IsMarked()) {
header->Unmark();
+ marked_object_size += size;
}
object_start_bit_map()->SetBit(header_address);
header_address += size;
@@ -1528,6 +1529,11 @@ void NormalPage::MakeConsistentForMutator() {
if (start_of_gap != PayloadEnd())
normal_arena->AddToFreeList(start_of_gap, PayloadEnd() - start_of_gap);
+ if (marked_object_size) {
+ ArenaForNormalPage()->GetThreadState()->Heap().IncreaseMarkedObjectSize(
+ marked_object_size);
+ }
+
VerifyObjectStartBitmapIsConsistentWithPayload();
}
@@ -1646,14 +1652,14 @@ void NormalPage::TakeSnapshot(base::trace_event::MemoryAllocatorDump* page_dump,
live_count++;
live_size += header->size();
- size_t gc_info_index = header->GcInfoIndex();
+ uint32_t gc_info_index = header->GcInfoIndex();
info.live_count[gc_info_index]++;
info.live_size[gc_info_index] += header->size();
} else {
dead_count++;
dead_size += header->size();
- size_t gc_info_index = header->GcInfoIndex();
+ uint32_t gc_info_index = header->GcInfoIndex();
info.dead_count[gc_info_index]++;
info.dead_size[gc_info_index] += header->size();
}
@@ -1709,8 +1715,10 @@ bool LargeObjectPage::Sweep() {
void LargeObjectPage::MakeConsistentForMutator() {
HeapObjectHeader* header = ObjectHeader();
- if (header->IsMarked())
+ if (header->IsMarked()) {
header->Unmark();
+ Arena()->GetThreadState()->Heap().IncreaseMarkedObjectSize(size());
+ }
}
#if defined(ADDRESS_SANITIZER)
@@ -1730,7 +1738,7 @@ void LargeObjectPage::TakeSnapshot(
size_t live_count = 0;
size_t dead_count = 0;
HeapObjectHeader* header = ObjectHeader();
- size_t gc_info_index = header->GcInfoIndex();
+ uint32_t gc_info_index = header->GcInfoIndex();
size_t payload_size = header->PayloadSize();
if (header->IsMarked()) {
live_count = 1;
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 b697773664e..2bc6d7cc77f 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_page.h
+++ b/chromium/third_party/blink/renderer/platform/heap/heap_page.h
@@ -194,7 +194,7 @@ class PLATFORM_EXPORT HeapObjectHeader {
size_t size() const;
- NO_SANITIZE_ADDRESS size_t GcInfoIndex() const {
+ NO_SANITIZE_ADDRESS uint32_t GcInfoIndex() const {
return (encoded_ & kHeaderGCInfoIndexMask) >> kHeaderGCInfoIndexShift;
}
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 30ee866cc63..05680bbd4d9 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
@@ -99,14 +99,11 @@ class PLATFORM_EXPORT ThreadHeapStatsCollector {
static constexpr int kNumScopeIds = kLastScopeId + 1;
- enum TraceDefaultBehavior {
- kEnabled,
- kDisabled,
- };
+ enum TraceCategory { kEnabled, kDisabled, kDevTools };
// Trace a particular scope. Will emit a trace event and record the time in
// the corresponding ThreadHeapStatsCollector.
- template <TraceDefaultBehavior default_behavior = kDisabled>
+ template <TraceCategory trace_category = kDisabled>
class PLATFORM_EXPORT InternalScope {
DISALLOW_NEW();
DISALLOW_COPY_AND_ASSIGN(InternalScope);
@@ -125,9 +122,14 @@ class PLATFORM_EXPORT ThreadHeapStatsCollector {
private:
constexpr static const char* TraceCategory() {
- return default_behavior == kEnabled
- ? "blink_gc"
- : TRACE_DISABLED_BY_DEFAULT("blink_gc");
+ 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() { TRACE_EVENT_BEGIN0(TraceCategory(), ToString(id_)); }
@@ -149,6 +151,7 @@ class PLATFORM_EXPORT ThreadHeapStatsCollector {
using Scope = InternalScope<kDisabled>;
using EnabledScope = InternalScope<kEnabled>;
+ using DevToolsScope = InternalScope<kDevTools>;
// POD to hold interesting data accumulated during a garbage collection cycle.
// The event is always fully polulated when looking at previous events but
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 031cfc109a6..4e7a71d4d3c 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_test.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/heap_test.cc
@@ -47,7 +47,6 @@
#include "third_party/blink/renderer/platform/heap/heap_terminated_array_builder.h"
#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h"
#include "third_party/blink/renderer/platform/heap/marking_visitor.h"
-#include "third_party/blink/renderer/platform/heap/safe_point.h"
#include "third_party/blink/renderer/platform/heap/self_keep_alive.h"
#include "third_party/blink/renderer/platform/heap/stack_frame_depth.h"
#include "third_party/blink/renderer/platform/heap/thread_state.h"
@@ -361,9 +360,9 @@ class TestGCCollectGarbageScope {
~TestGCCollectGarbageScope() { ThreadState::Current()->CompleteSweep(); }
};
-class TestGCMarkingScope : public TestGCCollectGarbageScope {
+class TestGCScope : public TestGCCollectGarbageScope {
public:
- explicit TestGCMarkingScope(BlinkGC::StackState state)
+ explicit TestGCScope(BlinkGC::StackState state)
: TestGCCollectGarbageScope(state),
atomic_pause_scope_(ThreadState::Current()) {
ThreadState::Current()->Heap().stats_collector()->NotifyMarkingStarted(
@@ -371,7 +370,7 @@ class TestGCMarkingScope : public TestGCCollectGarbageScope {
ThreadState::Current()->AtomicPausePrologue(state, BlinkGC::kAtomicMarking,
BlinkGC::GCReason::kPreciseGC);
}
- ~TestGCMarkingScope() {
+ ~TestGCScope() {
ThreadState::Current()->MarkPhaseEpilogue(BlinkGC::kAtomicMarking);
ThreadState::Current()->AtomicPauseEpilogue(BlinkGC::kAtomicMarking,
BlinkGC::kEagerSweeping);
@@ -381,16 +380,6 @@ class TestGCMarkingScope : public TestGCCollectGarbageScope {
ThreadState::AtomicPauseScope atomic_pause_scope_;
};
-class TestGCScope : public TestGCMarkingScope {
- public:
- explicit TestGCScope(BlinkGC::StackState state)
- : TestGCMarkingScope(state), safe_point_scope_(state) {}
- ~TestGCScope() {}
-
- private:
- SafePointScope safe_point_scope_;
-};
-
class SimpleObject : public GarbageCollected<SimpleObject> {
public:
static SimpleObject* Create() { return new SimpleObject(); }
@@ -1734,7 +1723,7 @@ TEST(HeapTest, BasicFunctionality) {
ClearOutOldGarbage();
size_t initial_object_payload_size = heap.ObjectPayloadSizeForTesting();
{
- size_t slack = 0;
+ wtf_size_t slack = 0;
// When the test starts there may already have been leaked some memory
// on the heap, so we establish a base line.
@@ -1776,7 +1765,7 @@ TEST(HeapTest, BasicFunctionality) {
ClearOutOldGarbage();
size_t total = 0;
- size_t slack = 0;
+ wtf_size_t slack = 0;
size_t base_level = heap.ObjectPayloadSizeForTesting();
bool test_pages_allocated = !base_level;
if (test_pages_allocated)
@@ -2396,8 +2385,8 @@ TEST(HeapTest, MAYBE_LargeHashMap) {
// Try to allocate a HashTable larger than kMaxHeapObjectSize
// (crbug.com/597953).
- size_t size = kMaxHeapObjectSize /
- sizeof(HeapHashMap<int, Member<IntWrapper>>::ValueType);
+ wtf_size_t size = kMaxHeapObjectSize /
+ sizeof(HeapHashMap<int, Member<IntWrapper>>::ValueType);
Persistent<HeapHashMap<int, Member<IntWrapper>>> map =
new HeapHashMap<int, Member<IntWrapper>>();
map->ReserveCapacityForSize(size);
@@ -2409,7 +2398,7 @@ TEST(HeapTest, LargeVector) {
// Try to allocate a HeapVectors larger than kMaxHeapObjectSize
// (crbug.com/597953).
- size_t size = kMaxHeapObjectSize / sizeof(int);
+ wtf_size_t size = kMaxHeapObjectSize / sizeof(int);
Persistent<HeapVector<int>> vector = new HeapVector<int>(size);
EXPECT_LE(size, vector->capacity());
}
@@ -2458,7 +2447,7 @@ TEST(HeapTest, HeapVectorFilledWithValue) {
IntWrapper* val = IntWrapper::Create(1);
HeapVector<Member<IntWrapper>> vector(10, val);
EXPECT_EQ(10u, vector.size());
- for (size_t i = 0; i < vector.size(); i++)
+ for (wtf_size_t i = 0; i < vector.size(); i++)
EXPECT_EQ(val, vector[i]);
}
@@ -2584,16 +2573,18 @@ TEST(HeapTest, HeapVectorOnStackLargeObjectPageSized) {
// LargeObjectPage ends.
using Container = HeapVector<Member<IntWrapper>>;
Container vector;
- size_t size = (kLargeObjectSizeThreshold + kBlinkGuardPageSize -
- LargeObjectPage::PageHeaderSize() - sizeof(HeapObjectHeader)) /
- sizeof(Container::ValueType);
+ wtf_size_t size =
+ (kLargeObjectSizeThreshold + kBlinkGuardPageSize -
+ static_cast<wtf_size_t>(LargeObjectPage::PageHeaderSize()) -
+ sizeof(HeapObjectHeader)) /
+ sizeof(Container::ValueType);
vector.ReserveCapacity(size);
for (unsigned i = 0; i < size; ++i)
vector.push_back(IntWrapper::Create(i));
ConservativelyCollectGarbage();
}
-template <typename T, size_t inlineCapacity, typename U>
+template <typename T, wtf_size_t inlineCapacity, typename U>
bool DequeContains(HeapDeque<T, inlineCapacity>& deque, U u) {
typedef typename HeapDeque<T, inlineCapacity>::iterator iterator;
for (iterator it = deque.begin(); it != deque.end(); ++it) {
@@ -4042,7 +4033,7 @@ TEST(HeapTest, CheckAndMarkPointer) {
MarkingVisitor::kGlobalMarking);
heap.address_cache()->EnableLookup();
heap.address_cache()->Flush();
- for (size_t i = 0; i < object_addresses.size(); i++) {
+ for (wtf_size_t i = 0; i < object_addresses.size(); i++) {
EXPECT_TRUE(heap.CheckAndMarkPointer(&visitor, object_addresses[i],
ReportMarkedPointer));
EXPECT_TRUE(heap.CheckAndMarkPointer(&visitor, end_addresses[i],
@@ -4067,7 +4058,7 @@ TEST(HeapTest, CheckAndMarkPointer) {
MarkingVisitor::kGlobalMarking);
heap.address_cache()->EnableLookup();
heap.address_cache()->Flush();
- for (size_t i = 0; i < object_addresses.size(); i++) {
+ for (wtf_size_t i = 0; i < object_addresses.size(); i++) {
// We would like to assert that checkAndMarkPointer returned false
// here because the pointers no longer point into a valid object
// (it's been freed by the GCs. But checkAndMarkPointer will return
@@ -4548,14 +4539,14 @@ TEST(HeapTest, HeapTerminatedArray) {
HeapTerminatedArray<TerminatedArrayItem>* arr = nullptr;
- const size_t kPrefixSize = 4;
- const size_t kSuffixSize = 4;
+ const wtf_size_t kPrefixSize = 4;
+ const wtf_size_t kSuffixSize = 4;
{
HeapTerminatedArrayBuilder<TerminatedArrayItem> builder(arr);
builder.Grow(kPrefixSize);
ConservativelyCollectGarbage();
- for (size_t i = 0; i < kPrefixSize; i++)
+ for (wtf_size_t i = 0; i < kPrefixSize; i++)
builder.Append(TerminatedArrayItem(IntWrapper::Create(i)));
arr = builder.Release();
}
@@ -4563,13 +4554,13 @@ TEST(HeapTest, HeapTerminatedArray) {
ConservativelyCollectGarbage();
EXPECT_EQ(0, IntWrapper::destructor_calls_);
EXPECT_EQ(kPrefixSize, arr->size());
- for (size_t i = 0; i < kPrefixSize; i++)
- EXPECT_EQ(i, static_cast<size_t>(arr->at(i).Payload()->Value()));
+ for (wtf_size_t i = 0; i < kPrefixSize; i++)
+ EXPECT_EQ(i, static_cast<wtf_size_t>(arr->at(i).Payload()->Value()));
{
HeapTerminatedArrayBuilder<TerminatedArrayItem> builder(arr);
builder.Grow(kSuffixSize);
- for (size_t i = 0; i < kSuffixSize; i++)
+ for (wtf_size_t i = 0; i < kSuffixSize; i++)
builder.Append(TerminatedArrayItem(IntWrapper::Create(kPrefixSize + i)));
arr = builder.Release();
}
@@ -4577,8 +4568,8 @@ TEST(HeapTest, HeapTerminatedArray) {
ConservativelyCollectGarbage();
EXPECT_EQ(0, IntWrapper::destructor_calls_);
EXPECT_EQ(kPrefixSize + kSuffixSize, arr->size());
- for (size_t i = 0; i < kPrefixSize + kSuffixSize; i++)
- EXPECT_EQ(i, static_cast<size_t>(arr->at(i).Payload()->Value()));
+ for (wtf_size_t i = 0; i < kPrefixSize + kSuffixSize; i++)
+ EXPECT_EQ(i, static_cast<wtf_size_t>(arr->at(i).Payload()->Value()));
{
Persistent<HeapTerminatedArray<TerminatedArrayItem>> persistent_arr = arr;
@@ -4587,8 +4578,8 @@ TEST(HeapTest, HeapTerminatedArray) {
arr = persistent_arr.Get();
EXPECT_EQ(0, IntWrapper::destructor_calls_);
EXPECT_EQ(kPrefixSize + kSuffixSize, arr->size());
- for (size_t i = 0; i < kPrefixSize + kSuffixSize; i++)
- EXPECT_EQ(i, static_cast<size_t>(arr->at(i).Payload()->Value()));
+ for (wtf_size_t i = 0; i < kPrefixSize + kSuffixSize; i++)
+ EXPECT_EQ(i, static_cast<wtf_size_t>(arr->at(i).Payload()->Value()));
}
arr = nullptr;
@@ -4603,9 +4594,9 @@ TEST(HeapTest, HeapLinkedStack) {
HeapLinkedStack<TerminatedArrayItem>* stack =
new HeapLinkedStack<TerminatedArrayItem>();
- const size_t kStackSize = 10;
+ const wtf_size_t kStackSize = 10;
- for (size_t i = 0; i < kStackSize; i++)
+ for (wtf_size_t i = 0; i < kStackSize; i++)
stack->Push(TerminatedArrayItem(IntWrapper::Create(i)));
ConservativelyCollectGarbage();
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 16123472b26..59d153eb9e9 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
@@ -10,6 +10,7 @@
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
#include "third_party/blink/renderer/platform/heap/heap_buildflags.h"
+#include "third_party/blink/renderer/platform/heap/heap_compact.h"
#include "third_party/blink/renderer/platform/heap/heap_terminated_array.h"
#include "third_party/blink/renderer/platform/heap/heap_terminated_array_builder.h"
#include "third_party/blink/renderer/platform/heap/member.h"
@@ -65,7 +66,7 @@ class BackingVisitor : public Visitor {
WeakCallback,
void*) final {}
void VisitBackingStoreOnly(void*, void**) final {}
- void RegisterBackingStoreCallback(void* backing_store,
+ void RegisterBackingStoreCallback(void** slot,
MovingObjectCallback,
void* callback_data) final {}
void RegisterWeakCallback(void* closure, WeakCallback) final {}
@@ -1630,6 +1631,11 @@ class IncrementalMarkingTestDriver {
thread_state_->CompleteSweep();
}
+ HashSet<MovableReference*>& GetTracedSlot() {
+ HeapCompact* compaction = ThreadState::Current()->Heap().Compaction();
+ return compaction->traced_slots_;
+ }
+
private:
ThreadState* const thread_state_;
};
@@ -1645,7 +1651,7 @@ TEST(IncrementalMarkingTest, TestDriver) {
}
TEST(IncrementalMarkingTest, DropBackingStore) {
- // Regression test: crbug.com/828537
+ // Regression test: https://crbug.com/828537
using WeakStore = HeapHashCountedSet<WeakMember<Object>>;
Persistent<WeakStore> persistent(new WeakStore);
@@ -1659,6 +1665,140 @@ TEST(IncrementalMarkingTest, DropBackingStore) {
driver.FinishGC();
}
+TEST(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(new 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({Object::Create(), 1});
+ persistent->insert({Object::Create(), 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(IncrementalMarkingTest, NoBackingFreeDuringIncrementalMarking) {
+ // Regression test: https://crbug.com/870306
+ // Only reproduces in ASAN configurations.
+ using WeakStore = HeapHashCountedSet<std::pair<WeakMember<Object>, size_t>>;
+
+ Persistent<WeakStore> persistent(new 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.
+ for (size_t i = 0; i < 8; i++) {
+ persistent->insert({Object::Create(), i});
+ }
+ IncrementalMarkingTestDriver driver(ThreadState::Current());
+ driver.Start();
+ persistent->insert({Object::Create(), 8});
+ // Is not allowed to free the backing store as the previous insert may have
+ // registered a slot.
+ persistent->clear();
+ driver.FinishSteps();
+ driver.FinishGC();
+}
+
+TEST(IncrementalMarkingTest, DropReferenceWithHeapCompaction) {
+ using Store = HeapHashCountedSet<Member<Object>>;
+
+ Persistent<Store> persistent(new Store);
+ persistent->insert(Object::Create());
+ IncrementalMarkingTestDriver driver(ThreadState::Current());
+ HeapCompact::ScheduleCompactionGCForTesting(true);
+ driver.Start();
+ driver.FinishSteps();
+ persistent->clear();
+ // Registration of movable and updatable references should not crash because
+ // if a slot have nullptr reference, it doesn't call registeration method.
+ driver.FinishGC();
+}
+
+TEST(IncrementalMarkingTest, HasInlineCapacityCollectionWithHeapCompaction) {
+ using Store = HeapVector<Member<Object>, 2>;
+
+ Persistent<Store> persistent(new Store);
+ Persistent<Store> persistent2(new Store);
+
+ IncrementalMarkingTestDriver driver(ThreadState::Current());
+ HeapCompact::ScheduleCompactionGCForTesting(true);
+ persistent->push_back(Object::Create());
+ driver.Start();
+ driver.FinishSteps();
+
+ // Should collect also slots that has only inline buffer and nullptr
+ // references.
+ EXPECT_EQ(driver.GetTracedSlot().size(), 2u);
+ driver.FinishGC();
+}
+
+TEST(IncrementalMarkingTest, SlotDestruction) {
+ IncrementalMarkingTestDriver driver(ThreadState::Current());
+ HeapCompact::ScheduleCompactionGCForTesting(true);
+ Vector<MovableReference*> ref(7);
+
+ {
+ Object* obj = Object::Create();
+ PersistentHeapHashSet<Member<Object>> p_hashset;
+ PersistentHeapHashMap<Member<Object>, Member<Object>> p_hashmap;
+ PersistentHeapLinkedHashSet<Member<Object>> p_linkedhashset;
+ PersistentHeapListHashSet<Member<Object>> p_listhashset;
+ PersistentHeapHashCountedSet<Member<Object>> p_hashcountedset;
+ PersistentHeapVector<Member<Object>> p_vector;
+ PersistentHeapDeque<Member<Object>> p_deque;
+
+ p_hashset.insert(obj);
+ p_hashmap.insert(obj, obj);
+ p_linkedhashset.insert(obj);
+ p_listhashset.insert(obj);
+ p_hashcountedset.insert(obj);
+ p_vector.push_back(obj);
+ p_deque.push_back(obj);
+
+ ref[0] = reinterpret_cast<MovableReference*>(&p_hashset);
+ ref[1] = reinterpret_cast<MovableReference*>(&p_hashmap);
+ ref[2] = reinterpret_cast<MovableReference*>(&p_linkedhashset);
+ ref[3] = reinterpret_cast<MovableReference*>(&p_listhashset);
+ ref[4] = reinterpret_cast<MovableReference*>(&p_hashcountedset);
+ ref[5] = reinterpret_cast<MovableReference*>(&p_vector);
+ ref[6] = reinterpret_cast<MovableReference*>(&p_deque);
+
+ driver.Start();
+ driver.FinishSteps();
+
+ for (size_t i = 0; i < ref.size(); ++i) {
+ EXPECT_TRUE(driver.GetTracedSlot().Contains(ref[i]));
+ }
+ }
+ for (size_t i = 0; i < ref.size(); ++i) {
+ EXPECT_FALSE(driver.GetTracedSlot().Contains(ref[i]));
+ }
+}
+
} // namespace incremental_marking_test
} // namespace blink
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 d5b01125efe..33f084dcf68 100644
--- a/chromium/third_party/blink/renderer/platform/heap/marking_verifier.h
+++ b/chromium/third_party/blink/renderer/platform/heap/marking_verifier.h
@@ -53,7 +53,8 @@ class MarkingVerifier final : public Visitor {
WeakCallback,
void*) final {}
void VisitBackingStoreOnly(void*, void**) final {}
- void RegisterBackingStoreCallback(void*, MovingObjectCallback, void*) final {}
+ void RegisterBackingStoreCallback(void**, MovingObjectCallback, void*) final {
+ }
void RegisterWeakCallback(void*, WeakCallback) final {}
void Visit(const TraceWrapperV8Reference<v8::Value>&) final {}
void Visit(DOMWrapperMap<ScriptWrappable>*,
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 eb320b74f4f..d803593d36d 100644
--- a/chromium/third_party/blink/renderer/platform/heap/marking_visitor.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/marking_visitor.cc
@@ -117,21 +117,20 @@ void MarkingVisitor::RegisterWeakCallback(void* object, WeakCallback callback) {
weak_callback_worklist_.Push({object, callback});
}
-void MarkingVisitor::RegisterBackingStoreReference(void* slot) {
+void MarkingVisitor::RegisterBackingStoreReference(void** slot) {
if (marking_mode_ != kGlobalMarkingWithCompaction)
return;
Heap().RegisterMovingObjectReference(
reinterpret_cast<MovableReference*>(slot));
}
-void MarkingVisitor::RegisterBackingStoreCallback(void* backing_store,
+void MarkingVisitor::RegisterBackingStoreCallback(void** slot,
MovingObjectCallback callback,
void* callback_data) {
if (marking_mode_ != kGlobalMarkingWithCompaction)
return;
- Heap().RegisterMovingObjectCallback(
- reinterpret_cast<MovableReference>(backing_store), callback,
- callback_data);
+ Heap().RegisterMovingObjectCallback(reinterpret_cast<MovableReference*>(slot),
+ callback, callback_data);
}
bool MarkingVisitor::RegisterWeakTable(const void* closure,
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 24ae2cedb3e..18eedcdf918 100644
--- a/chromium/third_party/blink/renderer/platform/heap/marking_visitor.h
+++ b/chromium/third_party/blink/renderer/platform/heap/marking_visitor.h
@@ -124,6 +124,8 @@ class PLATFORM_EXPORT MarkingVisitor final : public Visitor {
void** object_slot,
TraceDescriptor desc) final {
RegisterBackingStoreReference(object_slot);
+ if (!object)
+ return;
Visit(object, desc);
}
@@ -140,11 +142,13 @@ class PLATFORM_EXPORT MarkingVisitor final : public Visitor {
// processing. In this case, the contents are processed separately using
// the corresponding traits but the backing store requires marking.
void VisitBackingStoreOnly(void* object, void** object_slot) final {
- MarkHeaderNoTracing(HeapObjectHeader::FromPayload(object));
RegisterBackingStoreReference(object_slot);
+ if (!object)
+ return;
+ MarkHeaderNoTracing(HeapObjectHeader::FromPayload(object));
}
- void RegisterBackingStoreCallback(void* backing_store,
+ void RegisterBackingStoreCallback(void** slot,
MovingObjectCallback,
void* callback_data) final;
bool RegisterWeakTable(const void* closure,
@@ -161,7 +165,7 @@ class PLATFORM_EXPORT MarkingVisitor final : public Visitor {
static void WriteBarrierSlow(void*);
static void TraceMarkedBackingStoreSlow(void*);
- void RegisterBackingStoreReference(void* slot);
+ void RegisterBackingStoreReference(void** slot);
void ConservativelyMarkHeader(HeapObjectHeader*);
diff --git a/chromium/third_party/blink/renderer/platform/heap/persistent.h b/chromium/third_party/blink/renderer/platform/heap/persistent.h
index 0b62143ad41..d15be07f002 100644
--- a/chromium/third_party/blink/renderer/platform/heap/persistent.h
+++ b/chromium/third_party/blink/renderer/platform/heap/persistent.h
@@ -7,6 +7,7 @@
#include "base/bind.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
+#include "third_party/blink/renderer/platform/heap/heap_compact.h"
#include "third_party/blink/renderer/platform/heap/member.h"
#include "third_party/blink/renderer/platform/heap/persistent_node.h"
#include "third_party/blink/renderer/platform/heap/visitor.h"
@@ -115,6 +116,9 @@ class PersistentBase {
return *raw_;
}
explicit operator bool() const { return raw_; }
+ // TODO(https://crbug.com/653394): Consider returning a thread-safe best
+ // guess of validity.
+ bool MaybeValid() const { return true; }
operator T*() const {
CheckPointer();
return raw_;
@@ -182,7 +186,7 @@ class PersistentBase {
crossThreadnessConfiguration == kCrossThreadPersistentConfiguration,
"This Persistent does not require the cross-thread lock.");
#if DCHECK_IS_ON()
- DCHECK(ProcessHeap::CrossThreadPersistentMutex().Locked());
+ ProcessHeap::CrossThreadPersistentMutex().AssertAcquired();
#endif
raw_ = nullptr;
CrossThreadPersistentRegion& region =
@@ -338,7 +342,7 @@ class PersistentBase {
kWeakPersistentConfiguration,
kCrossThreadPersistentConfiguration>* persistent) {
#if DCHECK_IS_ON()
- DCHECK(ProcessHeap::CrossThreadPersistentMutex().Locked());
+ ProcessHeap::CrossThreadPersistentMutex().AssertAcquired();
#endif
persistent->ClearWithLockHeld();
}
@@ -683,6 +687,11 @@ class PersistentHeapCollectionBase : public Collection {
#if DCHECK_IS_ON()
DCHECK_EQ(state_, state);
#endif
+ HeapCompact* compactor = state->Heap().Compaction();
+ if (compactor->IsCompacting()) {
+ compactor->RemoveSlot(
+ reinterpret_cast<MovableReference*>(this->GetBufferSlot()));
+ }
state->FreePersistentNode(state->GetPersistentRegion(), persistent_node_);
persistent_node_ = nullptr;
}
@@ -719,7 +728,7 @@ class PersistentHeapLinkedHashSet
HeapLinkedHashSet<ValueArg, HashArg, TraitsArg>> {};
template <typename ValueArg,
- size_t inlineCapacity = 0,
+ wtf_size_t inlineCapacity = 0,
typename HashArg = typename DefaultHash<ValueArg>::Hash>
class PersistentHeapListHashSet
: public PersistentHeapCollectionBase<
@@ -732,13 +741,13 @@ class PersistentHeapHashCountedSet
: public PersistentHeapCollectionBase<
HeapHashCountedSet<ValueArg, HashFunctions, Traits>> {};
-template <typename T, size_t inlineCapacity = 0>
+template <typename T, wtf_size_t inlineCapacity = 0>
class PersistentHeapVector
: public PersistentHeapCollectionBase<HeapVector<T, inlineCapacity>> {
public:
PersistentHeapVector() { InitializeUnusedSlots(); }
- explicit PersistentHeapVector(size_t size)
+ explicit PersistentHeapVector(wtf_size_t size)
: PersistentHeapCollectionBase<HeapVector<T, inlineCapacity>>(size) {
InitializeUnusedSlots();
}
@@ -748,7 +757,7 @@ class PersistentHeapVector
InitializeUnusedSlots();
}
- template <size_t otherCapacity>
+ template <wtf_size_t otherCapacity>
PersistentHeapVector(const HeapVector<T, otherCapacity>& other)
: PersistentHeapCollectionBase<HeapVector<T, inlineCapacity>>(other) {
InitializeUnusedSlots();
@@ -759,19 +768,19 @@ class PersistentHeapVector
// The PersistentHeapVector is allocated off heap along with its
// inline buffer (if any.) Maintain the invariant that unused
// slots are cleared for the off-heap inline buffer also.
- size_t unused_slots = this->capacity() - this->size();
+ wtf_size_t unused_slots = this->capacity() - this->size();
if (unused_slots)
this->ClearUnusedSlots(this->end(), this->end() + unused_slots);
}
};
-template <typename T, size_t inlineCapacity = 0>
+template <typename T, wtf_size_t inlineCapacity = 0>
class PersistentHeapDeque
: public PersistentHeapCollectionBase<HeapDeque<T, inlineCapacity>> {
public:
PersistentHeapDeque() = default;
- template <size_t otherCapacity>
+ template <wtf_size_t otherCapacity>
PersistentHeapDeque(const HeapDeque<T, otherCapacity>& other)
: PersistentHeapCollectionBase<HeapDeque<T, inlineCapacity>>(other) {}
};
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 1255bf444ad..d32346534d6 100644
--- a/chromium/third_party/blink/renderer/platform/heap/persistent_node.h
+++ b/chromium/third_party/blink/renderer/platform/heap/persistent_node.h
@@ -174,7 +174,7 @@ class CrossThreadPersistentRegion final {
void* self,
TraceCallback trace) {
#if DCHECK_IS_ON()
- DCHECK(ProcessHeap::CrossThreadPersistentMutex().Locked());
+ ProcessHeap::CrossThreadPersistentMutex().AssertAcquired();
#endif
PersistentNode* node =
persistent_region_.AllocatePersistentNode(self, trace);
@@ -204,7 +204,7 @@ class CrossThreadPersistentRegion final {
void TracePersistentNodes(Visitor* visitor) {
// If this assert triggers, you're tracing without being in a LockScope.
#if DCHECK_IS_ON()
- DCHECK(ProcessHeap::CrossThreadPersistentMutex().Locked());
+ ProcessHeap::CrossThreadPersistentMutex().AssertAcquired();
#endif
persistent_region_.TracePersistentNodes(
visitor, CrossThreadPersistentRegion::ShouldTracePersistentNode);
diff --git a/chromium/third_party/blink/renderer/platform/heap/process_heap.cc b/chromium/third_party/blink/renderer/platform/heap/process_heap.cc
index a8fcc0a46e6..26afa8bd483 100644
--- a/chromium/third_party/blink/renderer/platform/heap/process_heap.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/process_heap.cc
@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/platform/heap/process_heap.h"
-#include "base/sampling_heap_profiler/sampling_heap_profiler.h"
+#include "base/sampling_heap_profiler/poisson_allocation_sampler.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/persistent_node.h"
@@ -14,12 +14,14 @@ namespace blink {
namespace {
-void BlinkGCAllocHook(uint8_t* address, size_t size, const char*) {
- base::SamplingHeapProfiler::RecordAlloc(address, size);
+void BlinkGCAllocHook(uint8_t* address, size_t size, const char* context) {
+ base::PoissonAllocationSampler::RecordAlloc(
+ address, size, base::PoissonAllocationSampler::AllocatorType::kBlinkGC,
+ context);
}
void BlinkGCFreeHook(uint8_t* address) {
- base::SamplingHeapProfiler::RecordFree(address);
+ base::PoissonAllocationSampler::RecordFree(address);
}
} // namespace
@@ -31,7 +33,7 @@ void ProcessHeap::Init() {
GCInfoTable::CreateGlobalTable();
- base::SamplingHeapProfiler::SetHooksInstallCallback([]() {
+ base::PoissonAllocationSampler::SetHooksInstallCallback([]() {
HeapAllocHooks::SetAllocationHook(&BlinkGCAllocHook);
HeapAllocHooks::SetFreeHook(&BlinkGCFreeHook);
});
diff --git a/chromium/third_party/blink/renderer/platform/heap/safe_point.h b/chromium/third_party/blink/renderer/platform/heap/safe_point.h
deleted file mode 100644
index 41a3e7b1177..00000000000
--- a/chromium/third_party/blink/renderer/platform/heap/safe_point.h
+++ /dev/null
@@ -1,39 +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_HEAP_SAFE_POINT_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_SAFE_POINT_H_
-
-#include "base/macros.h"
-#include "third_party/blink/renderer/platform/heap/thread_state.h"
-#include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
-
-namespace blink {
-
-class SafePointScope final {
- STACK_ALLOCATED();
-
- public:
- explicit SafePointScope(BlinkGC::StackState stack_state,
- ThreadState* state = ThreadState::Current())
- : state_(state) {
- if (state_) {
- state_->EnterSafePoint(stack_state, this);
- }
- }
-
- ~SafePointScope() {
- if (state_)
- state_->LeaveSafePoint();
- }
-
- private:
- ThreadState* state_;
-
- DISALLOW_COPY_AND_ASSIGN(SafePointScope);
-};
-
-} // namespace blink
-
-#endif
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 94c2171db9f..b5bf92262fd 100644
--- a/chromium/third_party/blink/renderer/platform/heap/thread_state.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/thread_state.cc
@@ -43,6 +43,7 @@
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_thread.h"
#include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h"
+#include "third_party/blink/renderer/platform/heap/address_cache.h"
#include "third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
@@ -51,12 +52,12 @@
#include "third_party/blink/renderer/platform/heap/heap_stats_collector.h"
#include "third_party/blink/renderer/platform/heap/marking_visitor.h"
#include "third_party/blink/renderer/platform/heap/page_pool.h"
-#include "third_party/blink/renderer/platform/heap/safe_point.h"
#include "third_party/blink/renderer/platform/heap/visitor.h"
#include "third_party/blink/renderer/platform/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/web_memory_allocator_dump.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/web_process_memory_dump.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
#include "third_party/blink/renderer/platform/wtf/allocator/partitions.h"
#include "third_party/blink/renderer/platform/wtf/stack_util.h"
#include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
@@ -167,7 +168,12 @@ ThreadState::ThreadState()
weak_persistent_region_(std::make_unique<PersistentRegion>()),
start_of_stack_(reinterpret_cast<intptr_t*>(WTF::GetStackStart())),
end_of_stack_(reinterpret_cast<intptr_t*>(WTF::GetStackStart())),
- safe_point_scope_marker_(nullptr),
+#if HAS_FEATURE(safe_stack)
+ start_of_unsafe_stack_(
+ reinterpret_cast<intptr_t*>(__builtin___get_unsafe_stack_top())),
+ end_of_unsafe_stack_(
+ reinterpret_cast<intptr_t*>(__builtin___get_unsafe_stack_bottom())),
+#endif
sweep_forbidden_(false),
no_allocation_count_(0),
gc_forbidden_count_(0),
@@ -323,24 +329,15 @@ void ThreadState::VisitAsanFakeStackForPointer(MarkingVisitor* visitor,
NO_SANITIZE_ADDRESS
NO_SANITIZE_THREAD
void ThreadState::VisitStack(MarkingVisitor* visitor) {
- if (stack_state_ == BlinkGC::kNoHeapPointersOnStack)
- return;
+ DCHECK_EQ(current_gc_data_.stack_state, BlinkGC::kHeapPointersOnStack);
Address* start = reinterpret_cast<Address*>(start_of_stack_);
- // If there is a safepoint scope marker we should stop the stack
- // scanning there to not touch active parts of the stack. Anything
- // interesting beyond that point is in the safepoint stack copy.
- // If there is no scope marker the thread is blocked and we should
- // scan all the way to the recorded end stack pointer.
Address* end = reinterpret_cast<Address*>(end_of_stack_);
- Address* safe_point_scope_marker =
- reinterpret_cast<Address*>(safe_point_scope_marker_);
- Address* current = safe_point_scope_marker ? safe_point_scope_marker : end;
// Ensure that current is aligned by address size otherwise the loop below
// will read past start address.
- current = reinterpret_cast<Address*>(reinterpret_cast<intptr_t>(current) &
- ~(sizeof(Address) - 1));
+ Address* current = reinterpret_cast<Address*>(
+ reinterpret_cast<intptr_t>(end) & ~(sizeof(Address) - 1));
for (; current < start; ++current) {
Address ptr = *current;
@@ -356,17 +353,32 @@ void ThreadState::VisitStack(MarkingVisitor* visitor) {
VisitAsanFakeStackForPointer(visitor, ptr);
}
- for (Address ptr : safe_point_stack_copy_) {
-#if defined(MEMORY_SANITIZER)
- // See the comment above.
- __msan_unpoison(&ptr, sizeof(ptr));
-#endif
+#if HAS_FEATURE(safe_stack)
+ start = reinterpret_cast<Address*>(start_of_unsafe_stack_);
+ end = reinterpret_cast<Address*>(end_of_unsafe_stack_);
+ current = end;
+
+ for (; current < start; ++current) {
+ Address ptr = *current;
+ // SafeStack And MSan are not compatible
heap_->CheckAndMarkPointer(visitor, ptr);
VisitAsanFakeStackForPointer(visitor, ptr);
}
+#endif
+}
+
+void ThreadState::VisitDOMWrappers(Visitor* visitor) {
+ if (trace_dom_wrappers_) {
+ ThreadHeapStatsCollector::Scope stats_scope(
+ Heap().stats_collector(), ThreadHeapStatsCollector::kVisitDOMWrappers);
+ trace_dom_wrappers_(isolate_, visitor);
+ }
}
void ThreadState::VisitPersistents(Visitor* visitor) {
+ ThreadHeapStatsCollector::Scope stats_scope(
+ Heap().stats_collector(),
+ ThreadHeapStatsCollector::kVisitPersistentRoots);
{
ThreadHeapStatsCollector::Scope stats_scope(
Heap().stats_collector(),
@@ -380,11 +392,6 @@ void ThreadState::VisitPersistents(Visitor* visitor) {
Heap().stats_collector(), ThreadHeapStatsCollector::kVisitPersistents);
persistent_region_->TracePersistentNodes(visitor);
}
- if (trace_dom_wrappers_) {
- ThreadHeapStatsCollector::Scope stats_scope(
- Heap().stats_collector(), ThreadHeapStatsCollector::kVisitDOMWrappers);
- trace_dom_wrappers_(isolate_, visitor);
- }
}
void ThreadState::VisitWeakPersistents(Visitor* visitor) {
@@ -959,7 +966,6 @@ void ThreadState::FinishSnapshot() {
gc_state_ = kNoGCScheduled;
SetGCPhase(GCPhase::kSweeping);
SetGCPhase(GCPhase::kNone);
- Heap().stats_collector()->NotifySweepingCompleted();
}
void ThreadState::AtomicPauseEpilogue(BlinkGC::MarkingType marking_type,
@@ -1038,11 +1044,19 @@ void ThreadState::CompleteSweep() {
return;
{
- AtomicPauseScope atomic_pause_scope(this);
+ // CompleteSweep may be called during regular mutator exececution, from a
+ // task, or from the atomic pause in which the atomic scope has already been
+ // opened.
+ const bool was_in_atomic_pause = in_atomic_pause();
+ if (!was_in_atomic_pause)
+ EnterAtomicPause();
+ ScriptForbiddenScope script_forbidden;
SweepForbiddenScope scope(this);
ThreadHeapStatsCollector::EnabledScope stats_scope(
Heap().stats_collector(), ThreadHeapStatsCollector::kCompleteSweep);
Heap().CompleteSweep();
+ if (!was_in_atomic_pause)
+ LeaveAtomicPause();
}
PostSweep();
}
@@ -1208,6 +1222,16 @@ void UpdateHistograms(const ThreadHeapStatsCollector::Event& event) {
} // namespace
+void ThreadState::UpdateStatisticsAfterSweeping() {
+ DCHECK(!IsSweepingInProgress());
+ DCHECK(Heap().stats_collector()->is_started());
+ Heap().stats_collector()->NotifySweepingCompleted();
+ if (IsMainThread())
+ UpdateHistograms(Heap().stats_collector()->previous());
+ // Emit trace counters for all threads.
+ UpdateTraceCounters(*Heap().stats_collector());
+}
+
void ThreadState::PostSweep() {
DCHECK(CheckThread());
@@ -1220,74 +1244,36 @@ void ThreadState::PostSweep() {
for (auto* const observer : observers_)
observer->OnCompleteSweepDone();
- Heap().stats_collector()->NotifySweepingCompleted();
- if (IsMainThread())
- UpdateHistograms(Heap().stats_collector()->previous());
- // Emit trace counters for all threads.
- UpdateTraceCounters(*Heap().stats_collector());
+ if (!in_atomic_pause()) {
+ // Immediately update the statistics if running outside of the atomic pause.
+ UpdateStatisticsAfterSweeping();
+ }
}
void ThreadState::SafePoint(BlinkGC::StackState stack_state) {
DCHECK(CheckThread());
RunScheduledGC(stack_state);
- stack_state_ = BlinkGC::kHeapPointersOnStack;
}
-#ifdef ADDRESS_SANITIZER
-// When we are running under AddressSanitizer with
-// detect_stack_use_after_return=1 then stack marker obtained from
-// SafePointScope will point into a fake stack. Detect this case by checking if
-// it falls in between current stack frame and stack start and use an arbitrary
-// high enough value for it. Don't adjust stack marker in any other case to
-// match behavior of code running without AddressSanitizer.
-NO_SANITIZE_ADDRESS static void* AdjustScopeMarkerForAdressSanitizer(
- void* scope_marker) {
- Address start = reinterpret_cast<Address>(WTF::GetStackStart());
- Address end = reinterpret_cast<Address>(&start);
- CHECK_LT(end, start);
-
- if (end <= scope_marker && scope_marker < start)
- return scope_marker;
-
- // 256 is as good an approximation as any else.
- const size_t kBytesToCopy = sizeof(Address) * 256;
- if (static_cast<size_t>(start - end) < kBytesToCopy)
- return start;
-
- return end + kBytesToCopy;
-}
-#endif
-
// TODO(haraken): The first void* pointer is unused. Remove it.
using PushAllRegistersCallback = void (*)(void*, ThreadState*, intptr_t*);
extern "C" void PushAllRegisters(void*, ThreadState*, PushAllRegistersCallback);
-static void EnterSafePointAfterPushRegisters(void*,
- ThreadState* state,
- intptr_t* stack_end) {
+static void DidPushRegisters(void*, ThreadState* state, intptr_t* stack_end) {
state->RecordStackEnd(stack_end);
- state->CopyStackUntilSafePointScope();
-}
-
-void ThreadState::EnterSafePoint(BlinkGC::StackState stack_state,
- void* scope_marker) {
- DCHECK(CheckThread());
-#ifdef ADDRESS_SANITIZER
- if (stack_state == BlinkGC::kHeapPointersOnStack)
- scope_marker = AdjustScopeMarkerForAdressSanitizer(scope_marker);
+#if HAS_FEATURE(safe_stack)
+ state->RecordUnsafeStackEnd(
+ reinterpret_cast<intptr_t*>(__builtin___get_unsafe_stack_ptr()));
#endif
- DCHECK(stack_state == BlinkGC::kNoHeapPointersOnStack || scope_marker);
- DCHECK(IsGCForbidden());
- stack_state_ = stack_state;
- safe_point_scope_marker_ = scope_marker;
- PushAllRegisters(nullptr, this, EnterSafePointAfterPushRegisters);
}
-void ThreadState::LeaveSafePoint() {
+void ThreadState::PushRegistersAndVisitStack() {
DCHECK(CheckThread());
- stack_state_ = BlinkGC::kHeapPointersOnStack;
- ClearSafePointScopeMarker();
+ DCHECK(IsGCForbidden());
+ DCHECK_EQ(current_gc_data_.stack_state, BlinkGC::kHeapPointersOnStack);
+ PushAllRegisters(nullptr, this, DidPushRegisters);
+ VisitStack(static_cast<MarkingVisitor*>(CurrentVisitor()));
}
void ThreadState::AddObserver(BlinkGCObserver* observer) {
@@ -1314,32 +1300,6 @@ void ThreadState::ReportMemoryToV8() {
reported_memory_to_v8_ = current_heap_size;
}
-void ThreadState::CopyStackUntilSafePointScope() {
- if (!safe_point_scope_marker_ ||
- stack_state_ == BlinkGC::kNoHeapPointersOnStack)
- return;
-
- Address* to = reinterpret_cast<Address*>(safe_point_scope_marker_);
- Address* from = reinterpret_cast<Address*>(end_of_stack_);
- CHECK_LT(from, to);
- CHECK_LE(to, reinterpret_cast<Address*>(start_of_stack_));
- size_t slot_count = static_cast<size_t>(to - from);
-// Catch potential performance issues.
-#if defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER)
- // ASan/LSan use more space on the stack and we therefore
- // increase the allowed stack copying for those builds.
- DCHECK_LT(slot_count, 2048u);
-#else
- DCHECK_LT(slot_count, 1024u);
-#endif
-
- DCHECK(!safe_point_stack_copy_.size());
- safe_point_stack_copy_.resize(slot_count);
- for (size_t i = 0; i < slot_count; ++i) {
- safe_point_stack_copy_[i] = from[i];
- }
-}
-
void ThreadState::RegisterStaticPersistentNode(
PersistentNode* node,
PersistentClearCallback callback) {
@@ -1452,7 +1412,7 @@ void ThreadState::IncrementalMarkingStart(BlinkGC::GCReason reason) {
CompleteSweep();
Heap().stats_collector()->NotifyMarkingStarted(reason);
{
- ThreadHeapStatsCollector::Scope stats_scope(
+ ThreadHeapStatsCollector::EnabledScope stats_scope(
Heap().stats_collector(),
ThreadHeapStatsCollector::kIncrementalMarkingStartMarking, "reason",
GcReasonString(reason));
@@ -1470,7 +1430,7 @@ void ThreadState::IncrementalMarkingStart(BlinkGC::GCReason reason) {
}
void ThreadState::IncrementalMarkingStep() {
- ThreadHeapStatsCollector::Scope stats_scope(
+ ThreadHeapStatsCollector::EnabledScope stats_scope(
Heap().stats_collector(),
ThreadHeapStatsCollector::kIncrementalMarkingStep);
VLOG(2) << "[state:" << this << "] "
@@ -1487,7 +1447,7 @@ void ThreadState::IncrementalMarkingStep() {
}
void ThreadState::IncrementalMarkingFinalize() {
- ThreadHeapStatsCollector::Scope stats_scope(
+ ThreadHeapStatsCollector::EnabledScope stats_scope(
Heap().stats_collector(),
ThreadHeapStatsCollector::kIncrementalMarkingFinalize);
VLOG(2) << "[state:" << this << "] "
@@ -1571,27 +1531,27 @@ void ThreadState::CollectGarbage(BlinkGC::StackState stack_state,
<< " reason: " << GcReasonString(reason);
}
-void ThreadState::RunAtomicPause(BlinkGC::StackState stack_state,
- BlinkGC::MarkingType marking_type,
- BlinkGC::SweepingType sweeping_type,
- BlinkGC::GCReason reason) {
- {
- ThreadHeapStatsCollector::EnabledScope stats1(
- Heap().stats_collector(), ThreadHeapStatsCollector::kAtomicPhase);
- AtomicPauseScope atomic_pause_scope(this);
- {
- ThreadHeapStatsCollector::EnabledScope stats2(
- Heap().stats_collector(),
- ThreadHeapStatsCollector::kAtomicPhaseMarking, "lazySweeping",
- sweeping_type == BlinkGC::kLazySweeping ? "yes" : "no", "gcReason",
- GcReasonString(reason));
- AtomicPausePrologue(stack_state, marking_type, reason);
- MarkPhaseVisitRoots();
- CHECK(MarkPhaseAdvanceMarking(TimeTicks::Max()));
- MarkPhaseEpilogue(marking_type);
- }
- AtomicPauseEpilogue(marking_type, sweeping_type);
- }
+void ThreadState::AtomicPauseMarkPrologue(BlinkGC::StackState stack_state,
+ BlinkGC::MarkingType marking_type,
+ BlinkGC::GCReason reason) {
+ AtomicPausePrologue(stack_state, marking_type, reason);
+ MarkPhaseVisitRoots();
+ MarkPhaseVisitNotFullyConstructedObjects();
+}
+
+void ThreadState::AtomicPauseMarkTransitiveClosure() {
+ CHECK(MarkPhaseAdvanceMarking(TimeTicks::Max()));
+}
+
+void ThreadState::AtomicPauseMarkEpilogue(BlinkGC::MarkingType marking_type) {
+ MarkPhaseEpilogue(marking_type);
+}
+
+void ThreadState::AtomicPauseSweepAndCompact(
+ BlinkGC::MarkingType marking_type,
+ BlinkGC::SweepingType sweeping_type) {
+ AtomicPauseScope atomic_pause_scope(this);
+ AtomicPauseEpilogue(marking_type, sweeping_type);
if (marking_type == BlinkGC::kTakeSnapshot) {
FinishSnapshot();
CHECK(!IsSweepingInProgress());
@@ -1609,6 +1569,33 @@ void ThreadState::RunAtomicPause(BlinkGC::StackState stack_state,
}
}
+void ThreadState::RunAtomicPause(BlinkGC::StackState stack_state,
+ BlinkGC::MarkingType marking_type,
+ BlinkGC::SweepingType sweeping_type,
+ BlinkGC::GCReason reason) {
+ {
+ ThreadHeapStatsCollector::DevToolsScope stats1(
+ Heap().stats_collector(), ThreadHeapStatsCollector::kAtomicPhase);
+ {
+ AtomicPauseScope atomic_pause_scope(this);
+ ThreadHeapStatsCollector::EnabledScope stats2(
+ Heap().stats_collector(),
+ ThreadHeapStatsCollector::kAtomicPhaseMarking, "lazySweeping",
+ sweeping_type == BlinkGC::kLazySweeping ? "yes" : "no", "gcReason",
+ GcReasonString(reason));
+ AtomicPauseMarkPrologue(stack_state, marking_type, reason);
+ AtomicPauseMarkTransitiveClosure();
+ AtomicPauseMarkEpilogue(marking_type);
+ }
+ AtomicPauseSweepAndCompact(marking_type, sweeping_type);
+ }
+ if (!IsSweepingInProgress()) {
+ // Sweeping was finished during the atomic pause. Update statistics needs to
+ // run outside of the top-most stats scope.
+ UpdateStatisticsAfterSweeping();
+ }
+}
+
namespace {
MarkingVisitor::MarkingMode GetMarkingMode(bool should_compact,
@@ -1668,25 +1655,29 @@ void ThreadState::AtomicPausePrologue(BlinkGC::StackState stack_state,
}
void ThreadState::MarkPhaseVisitRoots() {
- // StackFrameDepth should be disabled so we don't trace most of the object
- // graph in one incremental marking step.
+ // StackFrameDepth should be disabled to avoid eagerly tracing into the object
+ // graph when just visiting roots.
DCHECK(!Heap().GetStackFrameDepth().IsEnabled());
- // 1. Trace persistent roots.
- Heap().VisitPersistentRoots(current_gc_data_.visitor.get());
+ Visitor* visitor = current_gc_data_.visitor.get();
- // 2. Trace objects reachable from the stack.
- {
- SafePointScope safe_point_scope(current_gc_data_.stack_state, this);
- Heap().VisitStackRoots(current_gc_data_.visitor.get());
+ VisitPersistents(visitor);
+
+ VisitDOMWrappers(visitor);
+
+ if (current_gc_data_.stack_state == BlinkGC::kHeapPointersOnStack) {
+ ThreadHeapStatsCollector::Scope stats_scope(
+ Heap().stats_collector(), ThreadHeapStatsCollector::kVisitStackRoots);
+ AddressCache::EnabledScope address_cache_scope(Heap().address_cache());
+ PushRegistersAndVisitStack();
}
}
bool ThreadState::MarkPhaseAdvanceMarking(TimeTicks deadline) {
StackFrameDepthScope stack_depth_scope(&Heap().GetStackFrameDepth());
- // 3. Transitive closure to trace objects including ephemerons.
- return Heap().AdvanceMarkingStackProcessing(current_gc_data_.visitor.get(),
- deadline);
+ return Heap().AdvanceMarking(
+ reinterpret_cast<MarkingVisitor*>(current_gc_data_.visitor.get()),
+ deadline);
}
bool ThreadState::ShouldVerifyMarking() const {
@@ -1698,12 +1689,13 @@ bool ThreadState::ShouldVerifyMarking() const {
return should_verify_marking;
}
+void ThreadState::MarkPhaseVisitNotFullyConstructedObjects() {
+ Heap().MarkNotFullyConstructedObjects(
+ reinterpret_cast<MarkingVisitor*>(current_gc_data_.visitor.get()));
+}
+
void ThreadState::MarkPhaseEpilogue(BlinkGC::MarkingType marking_type) {
Visitor* visitor = current_gc_data_.visitor.get();
- // Finish marking of not-fully-constructed objects.
- Heap().MarkNotFullyConstructedObjects(visitor);
- CHECK(Heap().AdvanceMarkingStackProcessing(visitor, TimeTicks::Max()));
-
{
// See ProcessHeap::CrossThreadPersistentMutex().
MutexLocker persistent_lock(ProcessHeap::CrossThreadPersistentMutex());
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 0060c09e379..c77816c53e8 100644
--- a/chromium/third_party/blink/renderer/platform/heap/thread_state.h
+++ b/chromium/third_party/blink/renderer/platform/heap/thread_state.h
@@ -35,11 +35,11 @@
#include "base/atomicops.h"
#include "base/macros.h"
+#include "third_party/blink/public/platform/scheduler/web_rail_mode_observer.h"
#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
#include "third_party/blink/renderer/platform/heap/blink_gc.h"
#include "third_party/blink/renderer/platform/heap/threading_traits.h"
#include "third_party/blink/renderer/platform/platform_export.h"
-#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
#include "third_party/blink/renderer/platform/wtf/address_sanitizer.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
@@ -139,7 +139,7 @@ class PLATFORM_EXPORT BlinkGCObserver {
};
class PLATFORM_EXPORT ThreadState final
- : scheduler::WebThreadScheduler::RAILModeObserver {
+ : private scheduler::WebRAILModeObserver {
USING_FAST_MALLOC(ThreadState);
public:
@@ -408,37 +408,16 @@ class PLATFORM_EXPORT ThreadState final
void FlushHeapDoesNotContainCacheIfNeeded();
- // Safepoint related functionality.
- //
- // When a thread attempts to perform GC it needs to stop all other threads
- // that use the heap or at least guarantee that they will not touch any
- // heap allocated object until GC is complete.
- //
- // We say that a thread is at a safepoint if this thread is guaranteed to
- // not touch any heap allocated object or any heap related functionality until
- // it leaves the safepoint.
- //
- // Notice that a thread does not have to be paused if it is at safepoint it
- // can continue to run and perform tasks that do not require interaction
- // with the heap. It will be paused if it attempts to leave the safepoint and
- // there is a GC in progress.
- //
- // Each thread that has ThreadState attached must:
- // - periodically check if GC is requested from another thread by calling a
- // safePoint() method;
- // - use SafePointScope around long running loops that have no safePoint()
- // invocation inside, such loops must not touch any heap object;
- //
- // Check if GC is requested by another thread and pause this thread if this is
- // the case. Can only be called when current thread is in a consistent state.
void SafePoint(BlinkGC::StackState);
- // Mark current thread as running inside safepoint.
- void EnterSafePoint(BlinkGC::StackState, void*);
- void LeaveSafePoint();
-
void RecordStackEnd(intptr_t* end_of_stack) { end_of_stack_ = end_of_stack; }
- NO_SANITIZE_ADDRESS void CopyStackUntilSafePointScope();
+#if HAS_FEATURE(safe_stack)
+ void RecordUnsafeStackEnd(intptr_t* end_of_unsafe_stack) {
+ end_of_unsafe_stack_ = end_of_unsafe_stack;
+ }
+#endif
+
+ void PushRegistersAndVisitStack();
// A region of non-weak PersistentNodes allocated on the given thread.
PersistentRegion* GetPersistentRegion() const {
@@ -464,8 +443,13 @@ class PLATFORM_EXPORT ThreadState final
// Visit all weak persistents allocated on this thread.
void VisitWeakPersistents(Visitor*);
+ // Visit all DOM wrappers allocatd on this thread.
+ void VisitDOMWrappers(Visitor*);
+
struct GCSnapshotInfo {
STACK_ALLOCATED();
+
+ public:
GCSnapshotInfo(size_t num_object_types);
// Map from gcInfoIndex (vector-index) to count/size.
@@ -527,8 +511,6 @@ class PLATFORM_EXPORT ThreadState final
v8::Isolate* GetIsolate() const { return isolate_; }
- BlinkGC::StackState GetStackState() const { return stack_state_; }
-
void CollectGarbage(BlinkGC::StackState,
BlinkGC::MarkingType,
BlinkGC::SweepingType,
@@ -569,20 +551,15 @@ class PLATFORM_EXPORT ThreadState final
MarkingVisitor* CurrentVisitor() { return current_gc_data_.visitor.get(); }
- // Implementation for RAILModeObserver
+ // Implementation for WebRAILModeObserver
void OnRAILModeChanged(v8::RAILMode new_mode) override {
should_optimize_for_load_time_ = new_mode == v8::RAILMode::PERFORMANCE_LOAD;
+ if (should_optimize_for_load_time_ && IsIncrementalMarking() &&
+ GetGCState() == GCState::kIncrementalMarkingStepScheduled)
+ ScheduleIncrementalMarkingFinalize();
}
private:
- // Needs to set up visitor for testing purposes.
- friend class incremental_marking_test::IncrementalMarkingScope;
- friend class incremental_marking_test::IncrementalMarkingTestDriver;
- template <typename T>
- friend class PrefinalizerRegistration;
- friend class TestGCMarkingScope;
- friend class ThreadStateSchedulingTest;
-
// Number of ThreadState's that are currently in incremental marking. The
// counter is incremented by one when some ThreadState enters incremental
// marking and decremented upon finishing.
@@ -594,6 +571,24 @@ class PLATFORM_EXPORT ThreadState final
ThreadState();
~ThreadState() override;
+ // 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,
+ BlinkGC::MarkingType,
+ BlinkGC::GCReason);
+ void AtomicPauseMarkTransitiveClosure();
+ void AtomicPauseMarkEpilogue(BlinkGC::MarkingType);
+ void AtomicPauseSweepAndCompact(BlinkGC::MarkingType marking_type,
+ BlinkGC::SweepingType sweeping_type);
+
+ void RunAtomicPause(BlinkGC::StackState,
+ BlinkGC::MarkingType,
+ BlinkGC::SweepingType,
+ BlinkGC::GCReason);
+
+ void UpdateStatisticsAfterSweeping();
+
// The version is needed to be able to start incremental marking.
void MarkPhasePrologue(BlinkGC::StackState,
BlinkGC::MarkingType,
@@ -604,19 +599,10 @@ class PLATFORM_EXPORT ThreadState final
void AtomicPauseEpilogue(BlinkGC::MarkingType, BlinkGC::SweepingType);
void MarkPhaseEpilogue(BlinkGC::MarkingType);
void MarkPhaseVisitRoots();
+ void MarkPhaseVisitNotFullyConstructedObjects();
bool MarkPhaseAdvanceMarking(TimeTicks deadline);
void VerifyMarking(BlinkGC::MarkingType);
- void RunAtomicPause(BlinkGC::StackState,
- BlinkGC::MarkingType,
- BlinkGC::SweepingType,
- BlinkGC::GCReason);
-
- void ClearSafePointScopeMarker() {
- safe_point_stack_copy_.clear();
- safe_point_scope_marker_ = nullptr;
- }
-
bool ShouldVerifyMarking() const;
// shouldScheduleIdleGC and shouldForceConservativeGC
@@ -669,7 +655,6 @@ class PLATFORM_EXPORT ThreadState final
void ReportMemoryToV8();
- friend class SafePointScope;
friend class BlinkGCObserver;
@@ -698,12 +683,14 @@ class PLATFORM_EXPORT ThreadState final
ThreadIdentifier thread_;
std::unique_ptr<PersistentRegion> persistent_region_;
std::unique_ptr<PersistentRegion> weak_persistent_region_;
- BlinkGC::StackState stack_state_;
intptr_t* start_of_stack_;
intptr_t* end_of_stack_;
- void* safe_point_scope_marker_;
- Vector<Address> safe_point_stack_copy_;
+#if HAS_FEATURE(safe_stack)
+ intptr_t* start_of_unsafe_stack_;
+ intptr_t* end_of_unsafe_stack_;
+#endif
+
bool sweep_forbidden_;
size_t no_allocation_count_;
size_t gc_forbidden_count_;
@@ -766,6 +753,14 @@ class PLATFORM_EXPORT ThreadState final
};
GCData current_gc_data_;
+ // Needs to set up visitor for testing purposes.
+ friend class incremental_marking_test::IncrementalMarkingScope;
+ friend class incremental_marking_test::IncrementalMarkingTestDriver;
+ template <typename T>
+ friend class PrefinalizerRegistration;
+ friend class TestGCScope;
+ friend class ThreadStateSchedulingTest;
+
DISALLOW_COPY_AND_ASSIGN(ThreadState);
};
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 34a66f1ae5b..036118b18b6 100644
--- a/chromium/third_party/blink/renderer/platform/heap/threading_traits.h
+++ b/chromium/third_party/blink/renderer/platform/heap/threading_traits.h
@@ -169,9 +169,9 @@ 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, size_t inlineCapacity>
+template <typename T, wtf_size_t inlineCapacity>
class HeapVector;
-template <typename T, size_t inlineCapacity>
+template <typename T, wtf_size_t inlineCapacity>
class HeapDeque;
template <typename T, typename U, typename V>
class HeapHashCountedSet;
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 9ac4c315e2b..b7473d85ef4 100644
--- a/chromium/third_party/blink/renderer/platform/heap/trace_traits.h
+++ b/chromium/third_party/blink/renderer/platform/heap/trace_traits.h
@@ -400,9 +400,9 @@ class TraceEagerlyTrait<HeapDoublyLinkedList<T>> {
static const bool value = TraceEagerlyTrait<T>::value;
};
-template <typename ValueArg, size_t inlineCapacity>
+template <typename ValueArg, wtf_size_t inlineCapacity>
class HeapListHashSetAllocator;
-template <typename T, size_t inlineCapacity>
+template <typename T, wtf_size_t inlineCapacity>
class TraceEagerlyTrait<
WTF::ListHashSetNode<T, HeapListHashSetAllocator<T, inlineCapacity>>> {
STATIC_ONLY(TraceEagerlyTrait);
diff --git a/chromium/third_party/blink/renderer/platform/heap/visitor.h b/chromium/third_party/blink/renderer/platform/heap/visitor.h
index 9b9ba505449..e0723f7ae6c 100644
--- a/chromium/third_party/blink/renderer/platform/heap/visitor.h
+++ b/chromium/third_party/blink/renderer/platform/heap/visitor.h
@@ -120,8 +120,6 @@ class PLATFORM_EXPORT Visitor {
static_assert(IsGarbageCollectedType<T>::value,
"T needs to be a garbage collected object");
- if (!backing_store)
- return;
VisitBackingStoreStrongly(reinterpret_cast<void*>(backing_store),
reinterpret_cast<void**>(backing_store_slot),
TraceDescriptorFor(backing_store));
@@ -151,8 +149,6 @@ class PLATFORM_EXPORT Visitor {
static_assert(IsGarbageCollectedType<T>::value,
"T needs to be a garbage collected object");
- if (!backing_store)
- return;
VisitBackingStoreOnly(reinterpret_cast<void*>(backing_store),
reinterpret_cast<void**>(backing_store_slot));
}
@@ -270,7 +266,7 @@ class PLATFORM_EXPORT Visitor {
// Registers backing store pointers so that they can be moved and properly
// updated.
- virtual void RegisterBackingStoreCallback(void* backing_store,
+ virtual void RegisterBackingStoreCallback(void** slot,
MovingObjectCallback,
void* callback_data) = 0;
diff --git a/chromium/third_party/blink/renderer/platform/histogram.h b/chromium/third_party/blink/renderer/platform/histogram.h
index b380122df87..e7c7624fd2a 100644
--- a/chromium/third_party/blink/renderer/platform/histogram.h
+++ b/chromium/third_party/blink/renderer/platform/histogram.h
@@ -78,11 +78,32 @@ class PLATFORM_EXPORT ScopedUsHistogramTimer {
CustomCountHistogram& counter_;
};
+class PLATFORM_EXPORT ScopedHighResUsHistogramTimer {
+ public:
+ explicit ScopedHighResUsHistogramTimer(CustomCountHistogram& counter)
+ : start_time_(CurrentTimeTicks()), counter_(counter) {}
+
+ ~ScopedHighResUsHistogramTimer() {
+ if (TimeTicks::IsHighResolution())
+ counter_.CountMicroseconds(CurrentTimeTicks() - start_time_);
+ }
+
+ private:
+ TimeTicks start_time_;
+ CustomCountHistogram& counter_;
+};
+
#define SCOPED_BLINK_UMA_HISTOGRAM_TIMER_IMPL(name, allow_cross_thread) \
DEFINE_STATIC_LOCAL_IMPL(CustomCountHistogram, scoped_us_counter, \
(name, 0, 10000000, 50), allow_cross_thread); \
ScopedUsHistogramTimer timer(scoped_us_counter);
+#define SCOPED_BLINK_UMA_HISTOGRAM_TIMER_HIGHRES_IMPL(name, \
+ allow_cross_thread) \
+ DEFINE_STATIC_LOCAL_IMPL(CustomCountHistogram, scoped_us_counter, \
+ (name, 0, 10000000, 50), allow_cross_thread); \
+ ScopedHighResUsHistogramTimer timer(scoped_us_counter);
+
// Use code like this to record time, in microseconds, to execute a block of
// code:
//
@@ -95,6 +116,10 @@ class PLATFORM_EXPORT ScopedUsHistogramTimer {
#define SCOPED_BLINK_UMA_HISTOGRAM_TIMER(name) \
SCOPED_BLINK_UMA_HISTOGRAM_TIMER_IMPL(name, false)
+// Only record samples when we have a high resolution timer
+#define SCOPED_BLINK_UMA_HISTOGRAM_TIMER_HIGHRES(name) \
+ SCOPED_BLINK_UMA_HISTOGRAM_TIMER_HIGHRES_IMPL(name, false)
+
// Thread-safe variant of SCOPED_BLINK_UMA_HISTOGRAM_TIMER.
// Use if the histogram can be accessed by multiple threads.
#define SCOPED_BLINK_UMA_HISTOGRAM_TIMER_THREAD_SAFE(name) \
diff --git a/chromium/third_party/blink/renderer/platform/histogram_test.cc b/chromium/third_party/blink/renderer/platform/histogram_test.cc
index ac514eed026..7892e35db9c 100644
--- a/chromium/third_party/blink/renderer/platform/histogram_test.cc
+++ b/chromium/third_party/blink/renderer/platform/histogram_test.cc
@@ -23,7 +23,8 @@ class TestCustomCountHistogram : public CustomCountHistogram {
};
TEST(ScopedUsHistogramTimerTest, Basic) {
- TestCustomCountHistogram scoped_us_counter("test", 0, 10000000, 50);
+ TestCustomCountHistogram scoped_us_counter("ScopedUsHistogramTimerTest.Basic",
+ 0, 10000000, 50);
{
WTF::ScopedMockClock clock;
ScopedUsHistogramTimer timer(scoped_us_counter);
@@ -33,4 +34,16 @@ TEST(ScopedUsHistogramTimerTest, Basic) {
EXPECT_EQ(500000, scoped_us_counter.Histogram()->SnapshotSamples()->sum());
}
+TEST(ScopedHighResUsHistogramTimerTest, Basic) {
+ TestCustomCountHistogram scoped_us_counter(
+ "ScopedHighResUsHistogramTimerTest.Basic", 0, 10000000, 50);
+ {
+ WTF::ScopedMockClock clock;
+ ScopedHighResUsHistogramTimer timer(scoped_us_counter);
+ clock.Advance(TimeDelta::FromMilliseconds(500));
+ }
+ int64_t expected = TimeTicks::IsHighResolution() ? 500000 : 0;
+ EXPECT_EQ(expected, scoped_us_counter.Histogram()->SnapshotSamples()->sum());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/DEPS b/chromium/third_party/blink/renderer/platform/image-decoders/DEPS
index 24c3c139d17..d6e7af7d420 100644
--- a/chromium/third_party/blink/renderer/platform/image-decoders/DEPS
+++ b/chromium/third_party/blink/renderer/platform/image-decoders/DEPS
@@ -7,8 +7,10 @@ include_rules = [
# Dependencies.
"+cc/paint/image_animation_count.h",
+ "+third_party/blink/renderer/platform/histogram.h",
"+third_party/blink/renderer/platform/geometry",
"+third_party/blink/renderer/platform/graphics",
+ "+third_party/blink/renderer/platform/histogram.h",
"+third_party/blink/renderer/platform/instrumentation",
"+third_party/blink/renderer/platform/platform_export.h",
"+third_party/blink/renderer/platform/shared_buffer.h",
diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/ico/ico_image_decoder.cc b/chromium/third_party/blink/renderer/platform/image-decoders/ico/ico_image_decoder.cc
index 79c81f135b2..15f37e77849 100644
--- a/chromium/third_party/blink/renderer/platform/image-decoders/ico/ico_image_decoder.cc
+++ b/chromium/third_party/blink/renderer/platform/image-decoders/ico/ico_image_decoder.cc
@@ -227,7 +227,10 @@ bool ICOImageDecoder::DecodeAtIndex(size_t index) {
if (png_decoder->Size() != dir_entry.size_)
return SetFailed();
+ png_decoder->SetMemoryAllocator(frame_buffer_cache_[index].GetAllocator());
const auto* frame = png_decoder->DecodeFrameBufferAtIndex(0);
+ png_decoder->SetMemoryAllocator(nullptr);
+
if (frame)
frame_buffer_cache_[index] = *frame;
}
diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/image_decoder.cc b/chromium/third_party/blink/renderer/platform/image-decoders/image_decoder.cc
index 0f7452007d2..c544780efa9 100644
--- a/chromium/third_party/blink/renderer/platform/image-decoders/image_decoder.cc
+++ b/chromium/third_party/blink/renderer/platform/image-decoders/image_decoder.cc
@@ -64,6 +64,8 @@ inline bool MatchesBMPSignature(const char* contents) {
}
static constexpr size_t kLongestSignatureLength = sizeof("RIFF????WEBPVP") - 1;
+static const size_t k4BytesPerPixel = 4;
+static const size_t k8BytesPerPixel = 8;
std::unique_ptr<ImageDecoder> ImageDecoder::Create(
scoped_refptr<SegmentReader> data,
@@ -75,15 +77,24 @@ std::unique_ptr<ImageDecoder> ImageDecoder::Create(
// At least kLongestSignatureLength bytes are needed to sniff the signature.
if (data->size() < kLongestSignatureLength)
return nullptr;
+ // On low end devices, always decode to 8888.
+ if (high_bit_depth_decoding_option == kHighBitDepthToHalfFloat &&
+ Platform::Current() && Platform::Current()->IsLowEndDevice()) {
+ high_bit_depth_decoding_option = kDefaultBitDepth;
+ }
size_t max_decoded_bytes = Platform::Current()
? Platform::Current()->MaxDecodedImageBytes()
: kNoDecodedImageByteLimit;
if (!desired_size.isEmpty()) {
- static const size_t kBytesPerPixels = 4;
- size_t requested_decoded_bytes =
- kBytesPerPixels * desired_size.width() * desired_size.height();
- max_decoded_bytes = std::min(requested_decoded_bytes, max_decoded_bytes);
+ size_t num_pixels = desired_size.width() * desired_size.height();
+ if (high_bit_depth_decoding_option == kDefaultBitDepth) {
+ max_decoded_bytes =
+ std::min(k4BytesPerPixel * num_pixels, max_decoded_bytes);
+ } else { // kHighBitDepthToHalfFloat
+ max_decoded_bytes =
+ std::min(k8BytesPerPixel * num_pixels, max_decoded_bytes);
+ }
}
// Access the first kLongestSignatureLength chars to sniff the signature.
@@ -139,6 +150,8 @@ size_t ImageDecoder::FrameCount() {
}
ImageFrame* ImageDecoder::DecodeFrameBufferAtIndex(size_t index) {
+ TRACE_EVENT0("blink", "ImageDecoder::DecodeFrameBufferAtIndex");
+
if (index >= FrameCount())
return nullptr;
ImageFrame* frame = &frame_buffer_cache_[index];
@@ -188,8 +201,12 @@ size_t ImageDecoder::FrameBytesAtIndex(size_t index) const {
uint64_t area;
};
- return ImageSize(FrameSizeAtIndex(index)).area *
- sizeof(ImageFrame::PixelData);
+ size_t decoded_bytes_per_pixel = k4BytesPerPixel;
+ if (frame_buffer_cache_[index].GetPixelFormat() ==
+ ImageFrame::PixelFormat::kRGBA_F16) {
+ decoded_bytes_per_pixel = k8BytesPerPixel;
+ }
+ return ImageSize(FrameSizeAtIndex(index)).area * decoded_bytes_per_pixel;
}
size_t ImageDecoder::ClearCacheExceptFrame(size_t clear_except_frame) {
@@ -391,12 +408,18 @@ void ImageDecoder::UpdateAggressivePurging(size_t index) {
// As we decode we will learn the total number of frames, and thus total
// possible image memory used.
+ size_t decoded_bytes_per_pixel = k4BytesPerPixel;
+
+ if (frame_buffer_cache_.size() && frame_buffer_cache_[0].GetPixelFormat() ==
+ ImageFrame::PixelFormat::kRGBA_F16) {
+ decoded_bytes_per_pixel = k8BytesPerPixel;
+ }
const uint64_t frame_memory_usage =
- DecodedSize().Area() * 4; // 4 bytes per pixel
+ DecodedSize().Area() * decoded_bytes_per_pixel;
// This condition never fails in the current code. Our existing image decoders
// parse for the image size and SetFailed() if that size overflows
- DCHECK_EQ(frame_memory_usage / 4, DecodedSize().Area());
+ DCHECK_EQ(frame_memory_usage / decoded_bytes_per_pixel, DecodedSize().Area());
const uint64_t total_memory_usage = frame_memory_usage * index;
if (total_memory_usage / frame_memory_usage != index) { // overflow occurred
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 dff162eb87c..1242a2ed840 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
@@ -153,6 +153,12 @@ class PLATFORM_EXPORT ImageDecoder {
bool IsAllDataReceived() const { return is_all_data_received_; }
+ // Returns true if the decoder supports decoding to high bit depth. The
+ // decoded output will be high bit depth (half float backed bitmap) iff
+ // encoded image is high bit depth and high_bit_depth_decoding_option_ is set
+ // to kHighBitDepthToHalfFloat.
+ virtual bool ImageIsHighBitDepth() { return false; }
+
// Returns true if the buffer holds enough data to instantiate a decoder.
// This is useful for callers to determine whether a decoder instantiation
// failure is due to insufficient or bad data.
@@ -214,7 +220,11 @@ class PLATFORM_EXPORT ImageDecoder {
// Returns whether the size is legal (i.e. not going to result in
// overflow elsewhere). If not, marks decoding as failed.
virtual bool SetSize(unsigned width, unsigned height) {
- if (SizeCalculationMayOverflow(width, height))
+ unsigned decoded_bytes_per_pixel = 4;
+ if (ImageIsHighBitDepth() &&
+ high_bit_depth_decoding_option_ == kHighBitDepthToHalfFloat)
+ decoded_bytes_per_pixel = 8;
+ if (SizeCalculationMayOverflow(width, height, decoded_bytes_per_pixel))
return SetFailed();
size_ = IntSize(width, height);
@@ -447,12 +457,16 @@ class PLATFORM_EXPORT ImageDecoder {
}
private:
- // Some code paths compute the size of the image as "width * height * 4"
+ // Some code paths compute the size of the image as "width * height * 4 or 8"
// and return it as a (signed) int. Avoid overflow.
- static bool SizeCalculationMayOverflow(unsigned width, unsigned height) {
+ static bool SizeCalculationMayOverflow(unsigned width,
+ unsigned height,
+ unsigned decoded_bytes_per_pixel) {
unsigned long long total_size = static_cast<unsigned long long>(width) *
static_cast<unsigned long long>(height);
- return total_size > ((1 << 29) - 1);
+ if (decoded_bytes_per_pixel == 4)
+ return total_size > ((1 << 29) - 1);
+ return total_size > ((1 << 28) - 1);
}
bool purge_aggressively_;
diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/image_decoder_test.cc b/chromium/third_party/blink/renderer/platform/image-decoders/image_decoder_test.cc
index c6fc45b2a42..0ae6fa600b6 100644
--- a/chromium/third_party/blink/renderer/platform/image-decoders/image_decoder_test.cc
+++ b/chromium/third_party/blink/renderer/platform/image-decoders/image_decoder_test.cc
@@ -39,12 +39,15 @@ namespace blink {
class TestImageDecoder : public ImageDecoder {
public:
- TestImageDecoder()
+ TestImageDecoder(
+ ImageDecoder::HighBitDepthDecodingOption high_bit_depth_decoding_option)
: ImageDecoder(kAlphaNotPremultiplied,
- ImageDecoder::kDefaultBitDepth,
+ high_bit_depth_decoding_option,
ColorBehavior::TransformToSRGB(),
kNoDecodedImageByteLimit) {}
+ TestImageDecoder() : TestImageDecoder(ImageDecoder::kDefaultBitDepth) {}
+
String FilenameExtension() const override { return ""; }
Vector<ImageFrame, 1>& FrameBufferCache() { return frame_buffer_cache_; }
@@ -64,20 +67,52 @@ class TestImageDecoder : public ImageDecoder {
frame_buffer_cache_[i].SetOriginalFrameRect(IntRect(0, 0, width, height));
}
+ bool ImageIsHighBitDepth() override { return image_is_high_bit_depth_; }
+ void SetImageToHighBitDepthForTest() { image_is_high_bit_depth_ = true; }
+
private:
+ bool image_is_high_bit_depth_ = false;
void DecodeSize() override {}
void Decode(size_t index) override {}
};
TEST(ImageDecoderTest, sizeCalculationMayOverflow) {
- std::unique_ptr<TestImageDecoder> decoder(
- std::make_unique<TestImageDecoder>());
- EXPECT_FALSE(decoder->SetSize(1 << 29, 1));
- EXPECT_FALSE(decoder->SetSize(1, 1 << 29));
- EXPECT_FALSE(decoder->SetSize(1 << 15, 1 << 15));
- EXPECT_TRUE(decoder->SetSize(1 << 28, 1));
- EXPECT_TRUE(decoder->SetSize(1, 1 << 28));
- EXPECT_TRUE(decoder->SetSize(1 << 14, 1 << 14));
+ // Test coverage:
+ // Regular bit depth image with regular decoder
+ // Regular bit depth image with high bit depth decoder
+ // High bit depth image with regular decoder
+ // High bit depth image with high bit depth decoder
+ bool high_bit_depth_decoder_status[] = {false, true};
+ bool high_bit_depth_image_status[] = {false, true};
+
+ for (bool high_bit_depth_decoder : high_bit_depth_decoder_status) {
+ for (bool high_bit_depth_image : high_bit_depth_image_status) {
+ std::unique_ptr<TestImageDecoder> decoder;
+ if (high_bit_depth_decoder) {
+ decoder = std::make_unique<TestImageDecoder>(
+ ImageDecoder::kHighBitDepthToHalfFloat);
+ } else {
+ decoder = std::make_unique<TestImageDecoder>();
+ }
+ if (high_bit_depth_image)
+ decoder->SetImageToHighBitDepthForTest();
+
+ unsigned log_pixel_size = 2; // pixel is 4 bytes
+ if (high_bit_depth_decoder && high_bit_depth_image)
+ log_pixel_size = 3; // pixel is 8 byts
+ unsigned overflow_dim_shift = 31 - log_pixel_size;
+ unsigned overflow_dim_shift_half = (overflow_dim_shift + 1) / 2;
+
+ EXPECT_FALSE(decoder->SetSize(1 << overflow_dim_shift, 1));
+ EXPECT_FALSE(decoder->SetSize(1, 1 << overflow_dim_shift));
+ EXPECT_FALSE(decoder->SetSize(1 << overflow_dim_shift_half,
+ 1 << overflow_dim_shift_half));
+ EXPECT_TRUE(decoder->SetSize(1 << (overflow_dim_shift - 1), 1));
+ EXPECT_TRUE(decoder->SetSize(1, 1 << (overflow_dim_shift - 1)));
+ EXPECT_TRUE(decoder->SetSize(1 << (overflow_dim_shift_half - 1),
+ 1 << (overflow_dim_shift_half - 1)));
+ }
+ }
}
TEST(ImageDecoderTest, requiredPreviousFrameIndex) {
diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/image_frame.cc b/chromium/third_party/blink/renderer/platform/image-decoders/image_frame.cc
index b93d6f17e85..02ed602282d 100644
--- a/chromium/third_party/blink/renderer/platform/image-decoders/image_frame.cc
+++ b/chromium/third_party/blink/renderer/platform/image-decoders/image_frame.cc
@@ -86,6 +86,7 @@ void ImageFrame::ZeroFillPixelData() {
bool ImageFrame::CopyBitmapData(const ImageFrame& other) {
DCHECK_NE(this, &other);
has_alpha_ = other.has_alpha_;
+ pixel_format_ = other.pixel_format_;
bitmap_.reset();
SkImageInfo info = other.bitmap_.info();
return bitmap_.tryAllocPixels(info) &&
@@ -101,6 +102,7 @@ bool ImageFrame::TakeBitmapDataIfWritable(ImageFrame* other) {
if (other->bitmap_.isImmutable())
return false;
has_alpha_ = other->has_alpha_;
+ pixel_format_ = other->pixel_format_;
bitmap_.reset();
bitmap_.swap(other->bitmap_);
other->status_ = kFrameEmpty;
@@ -157,24 +159,6 @@ void ImageFrame::ZeroFillFrameRect(const IntRect& rect) {
SetHasAlpha(true);
}
-void ImageFrame::SetRGBAPremultiplyF16Buffer(PixelDataF16* dst,
- PixelDataF16* src,
- size_t num_pixels) {
- sk_sp<SkColorSpace> color_space = SkColorSpace::MakeSRGBLinear();
- auto color_format = SkColorSpaceXform::ColorFormat::kRGBA_F16_ColorFormat;
- SkColorSpaceXform::Apply(color_space.get(), color_format, dst,
- color_space.get(), color_format, src, num_pixels,
- SkColorSpaceXform::AlphaOp::kPremul_AlphaOp);
-}
-
-void ImageFrame::SetPixelsOpaqueF16Buffer(PixelDataF16* dst,
- PixelDataF16* src,
- size_t num_pixels) {
- // We set the alpha half float to 0x3c00, which is equal to 1.
- while (num_pixels-- > 0)
- *dst++ = (*src++ & 0x0000ffffffffffff) | 0x3c00000000000000;
-}
-
static void BlendRGBAF16Buffer(ImageFrame::PixelDataF16* dst,
ImageFrame::PixelDataF16* src,
size_t num_pixels,
diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/image_frame.h b/chromium/third_party/blink/renderer/platform/image-decoders/image_frame.h
index 0aec08ec956..9562391d7b2 100644
--- a/chromium/third_party/blink/renderer/platform/image-decoders/image_frame.h
+++ b/chromium/third_party/blink/renderer/platform/image-decoders/image_frame.h
@@ -81,10 +81,6 @@ class PLATFORM_EXPORT ImageFrame final {
ImageFrame();
- ImageFrame(PixelFormat pixel_format) : ImageFrame() {
- pixel_format_ = pixel_format;
- }
-
// The assignment operator reads has_alpha_ (inside SetStatus()) before it
// sets it (in SetHasAlpha()). This doesn't cause any problems, since the
// SetHasAlpha() call ensures all state is set correctly, but it means we
@@ -157,6 +153,7 @@ class PLATFORM_EXPORT ImageFrame final {
return required_previous_frame_index_;
}
void SetHasAlpha(bool alpha);
+ void SetPixelFormat(PixelFormat format) { pixel_format_ = format; }
void SetOriginalFrameRect(const IntRect& r) { original_frame_rect_ = r; }
void SetStatus(Status);
void SetDuration(TimeDelta duration) { duration_ = duration; }
@@ -234,10 +231,6 @@ class PLATFORM_EXPORT ImageFrame final {
*dest = SkPackARGB32NoCheck(a, r, g, b);
}
- static void SetRGBAPremultiplyF16Buffer(PixelDataF16* dst,
- PixelDataF16* src,
- size_t num_pixels);
-
static inline void SetRGBARaw(PixelData* dest,
unsigned r,
unsigned g,
@@ -246,10 +239,6 @@ class PLATFORM_EXPORT ImageFrame final {
*dest = SkPackARGB32NoCheck(a, r, g, b);
}
- static void SetPixelsOpaqueF16Buffer(PixelDataF16* dst,
- PixelDataF16* src,
- size_t num_pixels);
-
// Blend the RGBA pixel provided by |red|, |green|, |blue| and |alpha| over
// the pixel in |dest|, without premultiplication, and overwrite |dest| with
// the result.
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 07a506ac694..908a772ff33 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
@@ -65,80 +65,6 @@ class ImageFrameTest : public testing::Test {
}
};
-TEST_F(ImageFrameTest, TestF16API) {
- ImageFrame::PixelFormat kN32 = ImageFrame::PixelFormat::kN32;
- ImageFrame::PixelFormat kRGBA_F16 = ImageFrame::PixelFormat::kRGBA_F16;
-
- ImageFrame frame_no_pixel_format;
- ASSERT_EQ(kN32, frame_no_pixel_format.GetPixelFormat());
-
- ImageFrame frame_pixel_format_n32(kN32);
- ASSERT_EQ(kN32, frame_pixel_format_n32.GetPixelFormat());
-
- ImageFrame frame_pixel_format_f16(kRGBA_F16);
- ASSERT_EQ(kRGBA_F16, frame_pixel_format_f16.GetPixelFormat());
-
- ImageFrame frame_copy_ctor_n32(frame_pixel_format_n32);
- ASSERT_EQ(kN32, frame_copy_ctor_n32.GetPixelFormat());
-
- ImageFrame frame_copy_ctor_f16(frame_pixel_format_f16);
- ASSERT_EQ(kRGBA_F16, frame_copy_ctor_f16.GetPixelFormat());
-
- ImageFrame frame_test_assignment;
- frame_test_assignment = frame_pixel_format_n32;
- ASSERT_EQ(kN32, frame_test_assignment.GetPixelFormat());
- frame_test_assignment = frame_pixel_format_f16;
- ASSERT_EQ(kRGBA_F16, frame_test_assignment.GetPixelFormat());
-
- SkBitmap bitmap(frame_pixel_format_f16.Bitmap());
- ASSERT_EQ(0, bitmap.width());
- ASSERT_EQ(0, bitmap.height());
- ASSERT_EQ(nullptr, bitmap.colorSpace());
-
- TestAllocator allocator;
- frame_pixel_format_f16.SetMemoryAllocator(&allocator);
- sk_sp<SkColorSpace> srgb_linear = SkColorSpace::MakeSRGBLinear();
-
- ASSERT_TRUE(frame_pixel_format_f16.AllocatePixelData(2, 2, srgb_linear));
- bitmap = frame_pixel_format_f16.Bitmap();
- ASSERT_EQ(2, bitmap.width());
- ASSERT_EQ(2, bitmap.height());
- ASSERT_TRUE(SkColorSpace::Equals(srgb_linear.get(), bitmap.colorSpace()));
-}
-
-TEST_F(ImageFrameTest, SetRGBAPremultiplyF16Buffer) {
- ImageFrame::PixelDataF16 premul_f16;
- ImageFrame::SetRGBAPremultiplyF16Buffer(&premul_f16, &src_f16, 1);
-
- float f32_from_src_f16[4];
- ConvertF16ToF32(f32_from_src_f16, src_f16);
- for (int i = 0; i < 3; i++)
- f32_from_src_f16[i] *= f32_from_src_f16[3];
-
- float f32_from_premul_f16[4];
- ConvertF16ToF32(f32_from_premul_f16, premul_f16);
-
- for (int i = 0; i < 4; i++) {
- ASSERT_TRUE(fabs(f32_from_src_f16[i] - f32_from_premul_f16[i]) <
- color_compoenent_tolerance);
- }
-}
-
-TEST_F(ImageFrameTest, SetPixelsOpaqueF16Buffer) {
- ImageFrame::PixelDataF16 opaque_f16;
- ImageFrame::SetPixelsOpaqueF16Buffer(&opaque_f16, &src_f16, 1);
-
- float f32_from_src_f16[4];
- ConvertF16ToF32(f32_from_src_f16, src_f16);
-
- float f32_from_opaque_f16[4];
- ConvertF16ToF32(f32_from_opaque_f16, opaque_f16);
-
- for (int i = 0; i < 3; i++)
- ASSERT_EQ(f32_from_src_f16[i], f32_from_opaque_f16[i]);
- ASSERT_EQ(1.0f, f32_from_opaque_f16[3]);
-}
-
TEST_F(ImageFrameTest, BlendRGBARawF16Buffer) {
ImageFrame::PixelData blended_8888(dst_8888);
ImageFrame::BlendRGBARaw(&blended_8888, src_8888_r, src_8888_g, src_8888_b,
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 a1e440f6eed..5792b23b144 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
@@ -38,7 +38,10 @@
#include "third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.h"
#include <memory>
+#include "base/numerics/safe_conversions.h"
#include "build/build_config.h"
+#include "third_party/blink/renderer/platform/geometry/int_size.h"
+#include "third_party/blink/renderer/platform/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/platform_instrumentation.h"
extern "C" {
@@ -79,6 +82,24 @@ const int exifMarker = JPEG_APP0 + 1;
// JPEG only supports a denominator of 8.
const unsigned g_scale_denomiator = 8;
+// Configuration for the JPEG image area histogram. See RecordJpegImageArea().
+const char* kImageAreaHistogramName = "Blink.ImageDecoders.Jpeg.Area";
+constexpr base::HistogramBase::Sample kImageAreaHistogramMin = 1;
+constexpr base::HistogramBase::Sample kImageAreaHistogramMax = 8192 * 8192;
+constexpr int32_t kImageAreaHistogramBucketCount = 100;
+
+// Records the area (total number of pixels) of a JPEG image as a UMA.
+void RecordJpegImageArea(const blink::IntSize& size) {
+ DEFINE_THREAD_SAFE_STATIC_LOCAL(
+ blink::CustomCountHistogram, image_area_histogram,
+ (kImageAreaHistogramName, kImageAreaHistogramMin, kImageAreaHistogramMax,
+ kImageAreaHistogramBucketCount));
+ // A base::HistogramBase::Sample may not fit |size.Area()|. Hence the use of
+ // saturated_cast.
+ image_area_histogram.Count(
+ base::saturated_cast<base::HistogramBase::Sample>(size.Area()));
+}
+
} // namespace
namespace blink {
@@ -631,6 +652,7 @@ class JPEGImageReader final {
case JPEG_DONE:
// Finish decompression.
+ RecordJpegImageArea(decoder_->Size());
return jpeg_finish_decompress(&info_);
}
@@ -643,6 +665,9 @@ class JPEGImageReader final {
IntSize UvSize() const { return uv_size_; }
private:
+#if defined(USE_SYSTEM_LIBJPEG)
+ NO_SANITIZE_CFI_ICALL
+#endif
JSAMPARRAY AllocateSampleArray() {
// Some output color spaces don't need the sample array: don't allocate in that
// case.
diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.cc b/chromium/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.cc
index 67e0bba5e71..f81c0fe0e9c 100644
--- a/chromium/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.cc
+++ b/chromium/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.cc
@@ -39,6 +39,7 @@
#include "third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.h"
#include <memory>
+#include "third_party/skia/third_party/skcms/skcms.h"
#if (defined(__ARM_NEON__) || defined(__ARM_NEON))
#include <arm_neon.h>
@@ -63,7 +64,9 @@ PNGImageDecoder::PNGImageDecoder(
// never be respected.
repetition_count_(kAnimationLoopOnce),
has_alpha_channel_(false),
- current_buffer_saw_alpha_(false) {}
+ current_buffer_saw_alpha_(false),
+ decode_to_half_float_(false),
+ bit_depth_(0) {}
PNGImageDecoder::~PNGImageDecoder() = default;
@@ -139,6 +142,8 @@ int PNGImageDecoder::RepetitionCount() const {
void PNGImageDecoder::InitializeNewFrame(size_t index) {
const PNGImageReader::FrameInfo& frame_info = reader_->GetFrameInfo(index);
ImageFrame& buffer = frame_buffer_cache_[index];
+ if (decode_to_half_float_)
+ buffer.SetPixelFormat(ImageFrame::PixelFormat::kRGBA_F16);
DCHECK(IntRect(IntPoint(), Size()).Contains(frame_info.frame_rect));
buffer.SetOriginalFrameRect(frame_info.frame_rect);
@@ -226,6 +231,26 @@ void PNGImageDecoder::SetColorSpace() {
}
}
+void PNGImageDecoder::SetBitDepth() {
+ if (bit_depth_)
+ return;
+ png_structp png = reader_->PngPtr();
+ png_infop info = reader_->InfoPtr();
+ bit_depth_ = png_get_bit_depth(png, info);
+ decode_to_half_float_ =
+ (bit_depth_ == 16) &&
+ (high_bit_depth_decoding_option_ == kHighBitDepthToHalfFloat) &&
+ // TODO(zakerinasab): https://crbug.com/874057
+ // Due to a lack of 16 bit APNG encoders, multi-frame 16 bit APNGs are not
+ // supported. In this case the decoder falls back to 8888 decode mode.
+ (repetition_count_ == kAnimationNone);
+}
+
+bool PNGImageDecoder::ImageIsHighBitDepth() {
+ SetBitDepth();
+ return bit_depth_ == 16;
+}
+
bool PNGImageDecoder::SetSize(unsigned width, unsigned height) {
DCHECK(!IsDecodedSizeAvailable());
// Protect against large PNGs. See http://bugzil.la/251381 for more details.
@@ -255,7 +280,7 @@ void PNGImageDecoder::HeaderAvailable() {
if (png_get_valid(png, info, PNG_INFO_tRNS))
png_set_expand(png);
- if (bit_depth == 16)
+ if (!decode_to_half_float_)
png_set_strip_16(png);
if (color_type == PNG_COLOR_TYPE_GRAY ||
@@ -503,7 +528,10 @@ void PNGImageDecoder::RowAvailable(unsigned char* row_buffer,
if (PNG_INTERLACE_ADAM7 ==
png_get_interlace_type(png, reader_->InfoPtr())) {
unsigned color_channels = has_alpha_channel_ ? 4 : 3;
- reader_->CreateInterlaceBuffer(color_channels * Size().Area());
+ unsigned interlace_buffer_size = color_channels * Size().Area();
+ if (decode_to_half_float_)
+ interlace_buffer_size *= 2;
+ reader_->CreateInterlaceBuffer(interlace_buffer_size);
if (!reader_->InterlaceBuffer()) {
longjmp(JMPBUF(png), 1);
return;
@@ -575,120 +603,143 @@ void PNGImageDecoder::RowAvailable(unsigned char* row_buffer,
// Write the decoded row pixels to the frame buffer. The repetitive
// form of the row write loops is for speed.
- ImageFrame::PixelData* const dst_row = buffer.GetAddr(frame_rect.X(), y);
const int width = frame_rect.Width();
-
png_bytep src_ptr = row;
- if (has_alpha) {
- // Here we apply the color space transformation to the dst space.
- // It does not really make sense to transform to a gamma-encoded
- // space and then immediately after, perform a linear premultiply.
- // Ideally we would pass kPremul_SkAlphaType to xform->apply(),
- // instructing SkColorSpaceXform to perform the linear premultiply
- // while the pixels are a linear space.
- // We cannot do this because when we apply the gamma encoding after
- // the premultiply, we will very likely end up with valid pixels
- // where R, G, and/or B are greater than A. The legacy drawing
- // pipeline does not know how to handle this.
- if (ColorProfileTransform* xform = ColorTransform()) {
- ImageFrame::PixelData* xform_dst = dst_row;
- // If we're blending over the previous frame, we can't overwrite that
- // when we do the color transform. So we allocate another row of pixels
- // to hold the temporary result before blending. In all other cases,
- // we can safely transform directly to the destination buffer, then do
- // any operations in-place (premul, swizzle).
- if (frame_buffer_cache_[current_frame_].GetAlphaBlendSource() ==
- ImageFrame::kBlendAtopPreviousFrame) {
- if (!color_transform_scanline_) {
- // This buffer may be wider than necessary for this frame, but by
- // allocating the full width of the PNG, we know it will be able to
- // hold temporary data for any subsequent frame.
- color_transform_scanline_.reset(
- new ImageFrame::PixelData[Size().Width()]);
+
+ if (!decode_to_half_float_) {
+ ImageFrame::PixelData* const dst_row = buffer.GetAddr(frame_rect.X(), y);
+ if (has_alpha) {
+ if (ColorProfileTransform* xform = ColorTransform()) {
+ ImageFrame::PixelData* xform_dst = dst_row;
+ // If we're blending over the previous frame, we can't overwrite that
+ // when we do the color transform. So we allocate another row of pixels
+ // to hold the temporary result before blending. In all other cases,
+ // we can safely transform directly to the destination buffer, then do
+ // any operations in-place (premul, swizzle).
+ if (frame_buffer_cache_[current_frame_].GetAlphaBlendSource() ==
+ ImageFrame::kBlendAtopPreviousFrame) {
+ if (!color_transform_scanline_) {
+ // This buffer may be wider than necessary for this frame, but by
+ // allocating the full width of the PNG, we know it will be able to
+ // hold temporary data for any subsequent frame.
+ color_transform_scanline_.reset(
+ new ImageFrame::PixelData[Size().Width()]);
+ }
+ xform_dst = color_transform_scanline_.get();
}
- xform_dst = color_transform_scanline_.get();
+ skcms_PixelFormat color_format = skcms_PixelFormat_RGBA_8888;
+ skcms_AlphaFormat alpha_format = skcms_AlphaFormat_Unpremul;
+ bool color_conversion_successful = skcms_Transform(
+ src_ptr, color_format, alpha_format, xform->SrcProfile(), xform_dst,
+ color_format, alpha_format, xform->DstProfile(), width);
+ DCHECK(color_conversion_successful);
+ src_ptr = png_bytep(xform_dst);
}
- skcms_PixelFormat color_format = skcms_PixelFormat_RGBA_8888;
- skcms_AlphaFormat alpha_format = skcms_AlphaFormat_Unpremul;
- bool color_conversion_successful = skcms_Transform(
- src_ptr, color_format, alpha_format, xform->SrcProfile(), xform_dst,
- color_format, alpha_format, xform->DstProfile(), width);
- DCHECK(color_conversion_successful);
- src_ptr = png_bytep(xform_dst);
- }
- unsigned alpha_mask = 255;
- if (frame_buffer_cache_[current_frame_].GetAlphaBlendSource() ==
- ImageFrame::kBlendAtopBgcolor) {
- if (buffer.PremultiplyAlpha()) {
+ unsigned alpha_mask = 255;
+ if (frame_buffer_cache_[current_frame_].GetAlphaBlendSource() ==
+ ImageFrame::kBlendAtopBgcolor) {
+ if (buffer.PremultiplyAlpha()) {
#if (defined(__ARM_NEON__) || defined(__ARM_NEON))
- SetRGBAPremultiplyRowNeon(src_ptr, width, dst_row, &alpha_mask);
+ SetRGBAPremultiplyRowNeon(src_ptr, width, dst_row, &alpha_mask);
#else
- for (auto *dst_pixel = dst_row; dst_pixel < dst_row + width;
- dst_pixel++, src_ptr += 4) {
- ImageFrame::SetRGBAPremultiply(dst_pixel, src_ptr[0], src_ptr[1],
- src_ptr[2], src_ptr[3]);
- alpha_mask &= src_ptr[3];
- }
+ for (auto *dst_pixel = dst_row; dst_pixel < dst_row + width;
+ dst_pixel++, src_ptr += 4) {
+ ImageFrame::SetRGBAPremultiply(dst_pixel, src_ptr[0], src_ptr[1],
+ src_ptr[2], src_ptr[3]);
+ alpha_mask &= src_ptr[3];
+ }
#endif
- } else {
+ } else {
#if (defined(__ARM_NEON__) || defined(__ARM_NEON))
- SetRGBARawRowNeon(src_ptr, width, dst_row, &alpha_mask);
+ SetRGBARawRowNeon(src_ptr, width, dst_row, &alpha_mask);
#else
- for (auto *dst_pixel = dst_row; dst_pixel < dst_row + width;
- dst_pixel++, src_ptr += 4) {
- ImageFrame::SetRGBARaw(dst_pixel, src_ptr[0], src_ptr[1], src_ptr[2],
- src_ptr[3]);
- alpha_mask &= src_ptr[3];
- }
+ for (auto *dst_pixel = dst_row; dst_pixel < dst_row + width;
+ dst_pixel++, src_ptr += 4) {
+ ImageFrame::SetRGBARaw(dst_pixel, src_ptr[0], src_ptr[1],
+ src_ptr[2], src_ptr[3]);
+ alpha_mask &= src_ptr[3];
+ }
#endif
- }
- } else {
- // Now, the blend method is ImageFrame::BlendAtopPreviousFrame. Since the
- // frame data of the previous frame is copied at InitFrameBuffer, we can
- // blend the pixel of this frame, stored in |src_ptr|, over the previous
- // pixel stored in |dst_pixel|.
- if (buffer.PremultiplyAlpha()) {
- for (auto *dst_pixel = dst_row; dst_pixel < dst_row + width;
- dst_pixel++, src_ptr += 4) {
- ImageFrame::BlendRGBAPremultiplied(dst_pixel, src_ptr[0], src_ptr[1],
- src_ptr[2], src_ptr[3]);
- alpha_mask &= src_ptr[3];
}
} else {
- for (auto *dst_pixel = dst_row; dst_pixel < dst_row + width;
- dst_pixel++, src_ptr += 4) {
- ImageFrame::BlendRGBARaw(dst_pixel, src_ptr[0], src_ptr[1],
- src_ptr[2], src_ptr[3]);
- alpha_mask &= src_ptr[3];
+ // Now, the blend method is ImageFrame::BlendAtopPreviousFrame. Since
+ // the frame data of the previous frame is copied at InitFrameBuffer, we
+ // can blend the pixel of this frame, stored in |src_ptr|, over the
+ // previous pixel stored in |dst_pixel|.
+ if (buffer.PremultiplyAlpha()) {
+ for (auto *dst_pixel = dst_row; dst_pixel < dst_row + width;
+ dst_pixel++, src_ptr += 4) {
+ ImageFrame::BlendRGBAPremultiplied(
+ dst_pixel, src_ptr[0], src_ptr[1], src_ptr[2], src_ptr[3]);
+ alpha_mask &= src_ptr[3];
+ }
+ } else {
+ for (auto *dst_pixel = dst_row; dst_pixel < dst_row + width;
+ dst_pixel++, src_ptr += 4) {
+ ImageFrame::BlendRGBARaw(dst_pixel, src_ptr[0], src_ptr[1],
+ src_ptr[2], src_ptr[3]);
+ alpha_mask &= src_ptr[3];
+ }
}
}
- }
- if (alpha_mask != 255)
- current_buffer_saw_alpha_ = true;
+ if (alpha_mask != 255)
+ current_buffer_saw_alpha_ = true;
- } else {
+ } else {
#if (defined(__ARM_NEON__) || defined(__ARM_NEON))
- SetRGBARawRowNoAlphaNeon(src_ptr, width, dst_row);
+ SetRGBARawRowNoAlphaNeon(src_ptr, width, dst_row);
#else
- for (auto *dst_pixel = dst_row; dst_pixel < dst_row + width;
- src_ptr += 3, ++dst_pixel) {
- ImageFrame::SetRGBARaw(dst_pixel, src_ptr[0], src_ptr[1], src_ptr[2],
- 255);
- }
+ for (auto *dst_pixel = dst_row; dst_pixel < dst_row + width;
+ src_ptr += 3, ++dst_pixel) {
+ ImageFrame::SetRGBARaw(dst_pixel, src_ptr[0], src_ptr[1], src_ptr[2],
+ 255);
+ }
#endif
- // We'll apply the color space xform to opaque pixels after they have been
- // written to the ImageFrame.
- // TODO: Apply the xform to the RGB pixels, skipping second pass over data.
- if (ColorProfileTransform* xform = ColorTransform()) {
- skcms_AlphaFormat alpha_format = skcms_AlphaFormat_Opaque;
- bool color_conversion_successful =
- skcms_Transform(dst_row, XformColorFormat(), alpha_format,
- xform->SrcProfile(), dst_row, XformColorFormat(),
- alpha_format, xform->DstProfile(), width);
- DCHECK(color_conversion_successful);
+ // We'll apply the color space xform to opaque pixels after they have been
+ // written to the ImageFrame.
+ // TODO: Apply the xform to the RGB pixels, skipping second pass over
+ // data.
+ if (ColorProfileTransform* xform = ColorTransform()) {
+ skcms_AlphaFormat alpha_format = skcms_AlphaFormat_Opaque;
+ bool color_conversion_successful =
+ skcms_Transform(dst_row, XformColorFormat(), alpha_format,
+ xform->SrcProfile(), dst_row, XformColorFormat(),
+ alpha_format, xform->DstProfile(), width);
+ DCHECK(color_conversion_successful);
+ }
}
+ } else { // for if (!decode_to_half_float_)
+ ImageFrame::PixelDataF16* const dst_row_f16 =
+ buffer.GetAddrF16(frame_rect.X(), y);
+
+ // TODO(zakerinasab): https://crbug.com/874057
+ // Due to a lack of 16 bit APNG encoders, multi-frame 16 bit APNGs are not
+ // supported. Hence, we expect the blending mode always be
+ // kBlendAtopBgcolor.
+ DCHECK(frame_buffer_cache_[current_frame_].GetAlphaBlendSource() ==
+ ImageFrame::kBlendAtopBgcolor);
+
+ // Color space transformation to the dst space and converting the decoded
+ // color componenets from uint16 to float16.
+ auto* xform = ColorTransform();
+ auto* src_profile = xform ? xform->SrcProfile() : nullptr;
+ auto* dst_profile = xform ? xform->DstProfile() : nullptr;
+ auto src_format = has_alpha ? skcms_PixelFormat_RGBA_16161616
+ : skcms_PixelFormat_RGB_161616;
+ auto src_alpha_format =
+ has_alpha ? skcms_AlphaFormat_Unpremul : skcms_AlphaFormat_Opaque;
+ auto dst_alpha_format = has_alpha ? (buffer.PremultiplyAlpha()
+ ? skcms_AlphaFormat_PremulAsEncoded
+ : skcms_AlphaFormat_Unpremul)
+ : skcms_AlphaFormat_Opaque;
+ bool success = skcms_Transform(
+ src_ptr, src_format, src_alpha_format, src_profile, dst_row_f16,
+ skcms_PixelFormat_RGBA_hhhh, dst_alpha_format, dst_profile, width);
+ DCHECK(success);
+
+ current_buffer_saw_alpha_ = has_alpha;
}
buffer.SetPixelsChanged(true);
diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.h b/chromium/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.h
index a82f8a0028f..8c44bfe8025 100644
--- a/chromium/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.h
+++ b/chromium/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.h
@@ -48,6 +48,7 @@ class PLATFORM_EXPORT PNGImageDecoder final : public ImageDecoder {
String FilenameExtension() const override { return "png"; }
bool SetSize(unsigned, unsigned) override;
int RepetitionCount() const override;
+ bool ImageIsHighBitDepth() override;
bool FrameIsReceivedAtIndex(size_t) const override;
TimeDelta FrameDurationAtIndex(size_t) const override;
bool SetFailed() override;
@@ -59,6 +60,7 @@ class PLATFORM_EXPORT PNGImageDecoder final : public ImageDecoder {
void SetColorSpace();
void SetRepetitionCount(int);
+ void SetBitDepth();
private:
using ParseQuery = PNGImageReader::ParseQuery;
@@ -78,6 +80,8 @@ class PLATFORM_EXPORT PNGImageDecoder final : public ImageDecoder {
int repetition_count_;
bool has_alpha_channel_;
bool current_buffer_saw_alpha_;
+ bool decode_to_half_float_;
+ size_t bit_depth_;
std::unique_ptr<ImageFrame::PixelData[]> color_transform_scanline_;
};
diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder_test.cc b/chromium/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder_test.cc
index c24afa1ab12..26ab25430ac 100644
--- a/chromium/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder_test.cc
+++ b/chromium/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder_test.cc
@@ -9,6 +9,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/platform/image-decoders/image_decoder_test_helpers.h"
#include "third_party/blink/renderer/platform/wtf/time.h"
+#include "third_party/skia/include/core/SkImage.h"
// /LayoutTests/images/resources/png-animated-idat-part-of-animation.png
// is modified in multiple tests to simulate erroneous PNGs. As a reference,
@@ -43,6 +44,13 @@ std::unique_ptr<ImageDecoder> CreatePNGDecoder() {
return CreatePNGDecoder(ImageDecoder::kAlphaNotPremultiplied);
}
+std::unique_ptr<ImageDecoder> Create16BitPNGDecoder() {
+ return std::make_unique<PNGImageDecoder>(
+ ImageDecoder::kAlphaNotPremultiplied,
+ ImageDecoder::kHighBitDepthToHalfFloat, ColorBehavior::Tag(),
+ ImageDecoder::kNoDecodedImageByteLimit);
+}
+
std::unique_ptr<ImageDecoder> CreatePNGDecoderWithPngData(
const char* png_file) {
auto decoder = CreatePNGDecoder();
@@ -994,6 +1002,252 @@ TEST(StaticPNGTests, ProgressiveDecodingContinuesAfterFullData) {
"/images/resources/png-simple.png", 1000u);
}
+struct PNGSample {
+ String filename;
+ String color_space;
+ bool is_transparent;
+ bool is_high_bit_depth;
+ scoped_refptr<SharedBuffer> png_contents;
+ std::vector<float> expected_pixels;
+};
+
+static void TestHighBitDepthPNGDecoding(const PNGSample& png_sample,
+ ImageDecoder* decoder) {
+ scoped_refptr<SharedBuffer> png = png_sample.png_contents;
+ ASSERT_TRUE(png.get());
+ decoder->SetData(png.get(), true);
+ ASSERT_TRUE(decoder->IsSizeAvailable());
+ ASSERT_TRUE(decoder->IsDecodedSizeAvailable());
+
+ IntSize size(2, 2);
+ ASSERT_EQ(size, decoder->Size());
+ ASSERT_EQ(size, decoder->DecodedSize());
+ ASSERT_EQ(true, decoder->ImageIsHighBitDepth());
+
+ ASSERT_TRUE(decoder->FrameIsReceivedAtIndex(0));
+ ASSERT_EQ(size, decoder->FrameSizeAtIndex(0));
+
+ ASSERT_EQ(1u, decoder->FrameCount());
+ ASSERT_EQ(kAnimationNone, decoder->RepetitionCount());
+
+ auto* frame = decoder->DecodeFrameBufferAtIndex(0);
+ ASSERT_TRUE(frame);
+ ASSERT_EQ(ImageFrame::kFrameComplete, frame->GetStatus());
+ ASSERT_EQ(ImageFrame::kRGBA_F16, frame->GetPixelFormat());
+
+ sk_sp<SkImage> image = frame->FinalizePixelsAndGetImage();
+ ASSERT_TRUE(image);
+
+ ASSERT_EQ(2, image->width());
+ ASSERT_EQ(2, image->height());
+ ASSERT_EQ(kRGBA_F16_SkColorType, image->colorType());
+
+ // Readback pixels and convert color components from half float to float.
+ SkImageInfo info =
+ SkImageInfo::Make(2, 2, kRGBA_F16_SkColorType, kUnpremul_SkAlphaType,
+ image->refColorSpace());
+ std::unique_ptr<uint8_t[]> decoded_pixels(
+ new uint8_t[info.computeMinByteSize()]());
+ ASSERT_TRUE(
+ image->readPixels(info, decoded_pixels.get(), info.minRowBytes(), 0, 0));
+
+ float decoded_pixels_float_32[16];
+ ASSERT_TRUE(skcms_Transform(
+ decoded_pixels.get(), skcms_PixelFormat_RGBA_hhhh,
+ skcms_AlphaFormat_Unpremul, nullptr, decoded_pixels_float_32,
+ skcms_PixelFormat_RGBA_ffff, skcms_AlphaFormat_Unpremul, nullptr, 4));
+
+ std::vector<float> expected_pixels = png_sample.expected_pixels;
+ bool test_succeed = true;
+ const float decoding_tolerance = 0.001;
+ for (int i = 0; i < 16; i++) {
+ if (fabs(decoded_pixels_float_32[i] - expected_pixels[i]) >
+ decoding_tolerance) {
+ DLOG(DCHECK) << "Pixel comparison failed. File: " << png_sample.filename
+ << ", component index: " << i
+ << ", actual: " << decoded_pixels_float_32[i]
+ << ", expected: " << expected_pixels[i]
+ << ", tolerance: " << decoding_tolerance;
+ test_succeed = false;
+ }
+ }
+ ASSERT_TRUE(test_succeed);
+}
+
+static void FillPNGSamplesSourcePixels(std::vector<PNGSample>& png_samples) {
+ // Color components of opaque and transparent 16 bit PNG, read with libpng
+ // in BigEndian and scaled to [0,1]. The values are read from non-interlaced
+ // samples, but used for both interlaced and non-interlaced test cases.
+ static const std::vector<float> source_pixels_opaque_srgb = {
+ 0.4986953536, 0.5826657511, 0.7013199054, 1, // Top left pixel
+ 0.907988098, 0.8309605554, 0.492011902, 1, // Top right pixel
+ 0.6233157855, 0.9726558328, 0.9766536965, 1, // Bottom left pixel
+ 0.8946517128, 0.9663080797, 0.9053025101, 1}; // Bottom right pixel
+ static const std::vector<float> source_pixels_opaque_adobe_rgb = {
+ 0.4448004883, 0.5216296635, 0.6506294347, 1, // Top left pixel
+ 0.8830548562, 0.7978179599, 0.4323186084, 1, // Top right pixel
+ 0.6841992828, 0.9704280156, 0.9711299306, 1, // Bottom left pixel
+ 0.8874799725, 0.96099794, 0.8875715267, 1}; // Bottom right pixel
+ static const std::vector<float> source_pixels_opaque_p3 = {
+ 0.515648127, 0.5802243076, 0.6912489509, 1, // Top left pixel
+ 0.8954146639, 0.8337987335, 0.5691767758, 1, // Top right pixel
+ 0.772121767, 0.9671625849, 0.973510338, 1, // Bottom left pixel
+ 0.9118944076, 0.9645685512, 0.9110704204, 1}; // Bottom right pixel
+ static const std::vector<float> source_pixels_opaque_e_srgb = {
+ 0.6414435035, 0.6857862211, 0.747005417, 1, // Top left pixel
+ 0.877347982, 0.8382848859, 0.6494087129, 1, // Top right pixel
+ 0.735194934, 0.9353933013, 0.9374380102, 1, // Bottom left pixel
+ 0.9209277485, 0.9575799191, 0.9264515145, 1}; // Bottom right pixel
+ static const std::vector<float> source_pixels_opaque_prophoto = {
+ 0.5032883192, 0.5191271839, 0.6309147784, 1, // Top left pixel
+ 0.8184176394, 0.8002899214, 0.5526970321, 1, // Top right pixel
+ 0.842526894, 0.945616846, 0.9667048142, 1, // Bottom left pixel
+ 0.9119554437, 0.9507133593, 0.9001754788, 1}; // Bottom right pixel
+ static const std::vector<float> source_pixels_opaque_rec2020 = {
+ 0.5390554665, 0.5766842145, 0.6851758602, 1, // Top left pixel
+ 0.871061265, 0.831326772, 0.5805294881, 1, // Top right pixel
+ 0.8386205844, 0.9599603265, 0.9727168688, 1, // Bottom left pixel
+ 0.9235217823, 0.9611200122, 0.9112840467, 1}; // Bottom right pixel
+
+ static const std::vector<float> source_pixels_transparent_srgb = {
+ 0.3733272297, 0.4783093004, 0.6266422522, 0.8, // Top left pixel
+ 0.8466468299, 0.7182879377, 0.153322652, 0.6, // Top right pixel
+ 0.05831998169, 0.9316395819, 0.9416495003, 0.4, // Bottom left pixel
+ 0.4733043412, 0.8316319524, 0.5266346227, 0.2}; // Bottom right pixel
+ static const std::vector<float> source_pixels_transparent_adobe_rgb = {
+ 0.305943389, 0.4019836728, 0.5632867933, 0.8, // Top left pixel
+ 0.8051117723, 0.6630197604, 0.05374227512, 0.6, // Top right pixel
+ 0.210482948, 0.926115816, 0.9278248264, 0.4, // Bottom left pixel
+ 0.4374456397, 0.8050812543, 0.4379644465, 0.2}; // Bottom right pixel
+ static const std::vector<float> source_pixels_transparent_p3 = {
+ 0.3945372702, 0.475257496, 0.6140383001, 0.8, // Top left pixel
+ 0.8257114519, 0.7230182345, 0.2819256886, 0.6, // Top right pixel
+ 0.4302738994, 0.9179064622, 0.933806363, 0.4, // Bottom left pixel
+ 0.5595330739, 0.8228122377, 0.5554436561, 0.2}; // Bottom right pixel
+ static const std::vector<float> source_pixels_transparent_e_srgb = {
+ 0.5517814908, 0.6072327764, 0.6837415122, 0.8, // Top left pixel
+ 0.7955901427, 0.7304646372, 0.4156557565, 0.6, // Top right pixel
+ 0.3380178531, 0.8385290303, 0.8435950256, 0.4, // Bottom left pixel
+ 0.6046997787, 0.7879606317, 0.6323186084, 0.2}; // Bottom right pixel
+ static const std::vector<float> source_pixels_transparent_prophoto = {
+ 0.379064622, 0.3988708324, 0.5386282139, 0.8, // Top left pixel
+ 0.6973525597, 0.6671396963, 0.2544289311, 0.6, // Top right pixel
+ 0.6063477531, 0.864103151, 0.9168078126, 0.4, // Bottom left pixel
+ 0.5598077363, 0.7536278325, 0.5009384298, 0.2}; // Bottom right pixel
+ static const std::vector<float> source_pixels_transparent_rec2020 = {
+ 0.4237735561, 0.4708323796, 0.6064698253, 0.8, // Top left pixel
+ 0.7851224537, 0.7188677806, 0.3008468757, 0.6, // Top right pixel
+ 0.5965819791, 0.8999618524, 0.9318532082, 0.4, // Bottom left pixel
+ 0.6176699474, 0.805600061, 0.5565117876, 0.2}; // Bottom right pixel
+
+ for (PNGSample& png_sample : png_samples) {
+ if (png_sample.color_space == "sRGB") {
+ png_sample.expected_pixels = png_sample.is_transparent
+ ? source_pixels_transparent_srgb
+ : source_pixels_opaque_srgb;
+ } else if (png_sample.color_space == "AdobeRGB") {
+ png_sample.expected_pixels = png_sample.is_transparent
+ ? source_pixels_transparent_adobe_rgb
+ : source_pixels_opaque_adobe_rgb;
+ } else if (png_sample.color_space == "DisplayP3") {
+ png_sample.expected_pixels = png_sample.is_transparent
+ ? source_pixels_transparent_p3
+ : source_pixels_opaque_p3;
+ } else if (png_sample.color_space == "e-sRGB") {
+ png_sample.expected_pixels = png_sample.is_transparent
+ ? source_pixels_transparent_e_srgb
+ : source_pixels_opaque_e_srgb;
+ } else if (png_sample.color_space == "ProPhoto") {
+ png_sample.expected_pixels = png_sample.is_transparent
+ ? source_pixels_transparent_prophoto
+ : source_pixels_opaque_prophoto;
+ } else if (png_sample.color_space == "Rec2020") {
+ png_sample.expected_pixels = png_sample.is_transparent
+ ? source_pixels_transparent_rec2020
+ : source_pixels_opaque_rec2020;
+ } else {
+ NOTREACHED();
+ }
+ }
+}
+
+static std::vector<PNGSample> GetPNGSamplesInfo(bool include_8bit_pngs) {
+ std::vector<PNGSample> png_samples;
+ std::vector<String> interlace_status = {"", "_interlaced"};
+ // TODO(zakerinasab) https://crbug.com/874939:
+ // e-sRGB decodes fine to 8888, but fails to decode to F16, hence not tested.
+ std::vector<String> color_spaces = {"sRGB", "AdobeRGB", "DisplayP3",
+ "ProPhoto", "Rec2020"};
+ std::vector<String> alpha_status = {"_opaque", "_transparent"};
+
+ for (String color_space : color_spaces) {
+ for (String alpha : alpha_status) {
+ PNGSample png_sample;
+ png_sample.filename.append("_");
+ png_sample.filename.append(color_space);
+ png_sample.filename.append(alpha);
+ png_sample.filename.append(".png");
+ png_sample.color_space = color_space;
+ png_sample.is_transparent = (alpha == "_transparent");
+
+ for (String interlace : interlace_status) {
+ PNGSample high_bit_depth_sample(png_sample);
+ high_bit_depth_sample.filename.insert(interlace, 0);
+ high_bit_depth_sample.filename.insert("2x2_16bit", 0);
+ high_bit_depth_sample.is_high_bit_depth = true;
+ png_samples.push_back(high_bit_depth_sample);
+ }
+ if (include_8bit_pngs) {
+ PNGSample regular_bit_depth_sample(png_sample);
+ regular_bit_depth_sample.filename.insert("2x2_8bit", 0);
+ regular_bit_depth_sample.is_high_bit_depth = false;
+ png_samples.push_back(regular_bit_depth_sample);
+ }
+ }
+ }
+
+ return png_samples;
+}
+
+TEST(StaticPNGTests, DecodeHighBitDepthPngToHalfFloat) {
+ const bool include_8bit_pngs = false;
+ std::vector<PNGSample> png_samples = GetPNGSamplesInfo(include_8bit_pngs);
+ FillPNGSamplesSourcePixels(png_samples);
+ String path = "/images/resources/png-16bit/";
+ for (PNGSample& png_sample : png_samples) {
+ String full_path = path;
+ full_path.append(png_sample.filename);
+ png_sample.png_contents = ReadFile(full_path.Ascii().data());
+ auto decoder = Create16BitPNGDecoder();
+ TestHighBitDepthPNGDecoding(png_sample, decoder.get());
+ }
+}
+
+TEST(StaticPNGTests, ImageIsHighBitDepth) {
+ const bool include_8bit_pngs = true;
+ std::vector<PNGSample> png_samples = GetPNGSamplesInfo(include_8bit_pngs);
+ IntSize size(2, 2);
+
+ String path = "/images/resources/png-16bit/";
+ for (PNGSample& png_sample : png_samples) {
+ String full_path = path;
+ full_path.append(png_sample.filename);
+ png_sample.png_contents = ReadFile(full_path.Ascii().data());
+ ASSERT_TRUE(png_sample.png_contents.get());
+
+ std::unique_ptr<ImageDecoder> decoders[] = {CreatePNGDecoder(),
+ Create16BitPNGDecoder()};
+ for (auto& decoder : decoders) {
+ decoder->SetData(png_sample.png_contents.get(), true);
+ ASSERT_TRUE(decoder->IsSizeAvailable());
+ ASSERT_TRUE(decoder->IsDecodedSizeAvailable());
+ ASSERT_EQ(size, decoder->Size());
+ ASSERT_EQ(size, decoder->DecodedSize());
+ ASSERT_EQ(png_sample.is_high_bit_depth, decoder->ImageIsHighBitDepth());
+ }
+ }
+}
+
TEST(PNGTests, VerifyFrameCompleteBehavior) {
struct {
const char* name;
@@ -1071,14 +1325,15 @@ TEST(PNGTests, truncated) {
auto decoder =
CreatePNGDecoderWithPngData("/images/resources/crbug807324.png");
- // An update to libpng (without using the libpng-provided workaround) resulted
- // in truncating this image. It has no transparency, so no pixel should be
- // transparent.
+ // An update to libpng (without using the libpng-provided workaround)
+ // resulted in truncating this image. It has no transparency, so no pixel
+ // should be transparent.
auto* frame = decoder->DecodeFrameBufferAtIndex(0);
auto size = decoder->Size();
- for (int i = 0; i < size.Width(); ++i)
- for (int j = 0; j < size.Height(); ++j) {
- ASSERT_NE(SK_ColorTRANSPARENT, *frame->GetAddr(i, j));
+ for (int i = 0; i < size.Width(); ++i) {
+ for (int j = 0; j < size.Height(); ++j) {
+ ASSERT_NE(SK_ColorTRANSPARENT, *frame->GetAddr(i, j));
+ }
}
}
diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/png/png_image_reader.cc b/chromium/third_party/blink/renderer/platform/image-decoders/png/png_image_reader.cc
index a0b617fb4d9..fe55f769d38 100644
--- a/chromium/third_party/blink/renderer/platform/image-decoders/png/png_image_reader.cc
+++ b/chromium/third_party/blink/renderer/platform/image-decoders/png/png_image_reader.cc
@@ -543,8 +543,14 @@ bool PNGImageReader::ParseSize(const FastSharedBufferReader& reader) {
fctl_needs_dat_chunk_ = false;
if (ignore_animation_)
is_animated_ = false;
+ // SetSize() requires bit depth information to correctly fallback to 8888
+ // decoding if there is not enough memory to decode to f16 pixel format.
+ // SetBitDepth() requires repition count to correctly fallback to 8888
+ // decoding for multi-frame APNGs (https://crbug.com/874057). Therefore,
+ // the order of the next three calls matters.
if (!is_animated_ || 1 == reported_frame_count_)
decoder_->SetRepetitionCount(kAnimationNone);
+ decoder_->SetBitDepth();
if (!decoder_->SetSize(width_, height_))
return false;
decoder_->SetColorSpace();
diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder.cc b/chromium/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder.cc
index 24d59cb1161..fea41f6b1f5 100644
--- a/chromium/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder.cc
+++ b/chromium/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder.cc
@@ -29,6 +29,7 @@
#include "third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder.h"
#include "build/build_config.h"
+#include "third_party/blink/renderer/platform/histogram.h"
#include "third_party/skia/include/core/SkData.h"
#if defined(ARCH_CPU_BIG_ENDIAN)
@@ -115,6 +116,50 @@ void alphaBlendNonPremultiplied(blink::ImageFrame& src,
}
}
+// Do not rename entries nor reuse numeric values. See the following link for
+// descriptions: https://developers.google.com/speed/webp/docs/riff_container.
+enum WebPFileFormat {
+ kSimpleLossyFileFormat = 0,
+ kSimpleLosslessFileFormat = 1,
+ kExtendedAlphaFileFormat = 2,
+ kExtendedAnimationFileFormat = 3,
+ kExtendedAnimationWithAlphaFileFormat = 4,
+ kUnknownFileFormat = 5,
+ kCountWebPFileFormats
+};
+
+// This method parses |blob|'s header and emits a UMA with the file format, as
+// defined by WebP, see WebPFileFormat.
+void UpdateWebPFileFormatUMA(const sk_sp<SkData>& blob) {
+ if (!IsMainThread())
+ return;
+
+ WebPBitstreamFeatures features{};
+ if (WebPGetFeatures(blob->bytes(), blob->size(), &features) != VP8_STATUS_OK)
+ return;
+
+ // These constants are defined verbatim in webp_dec.c::ParseHeadersInternal().
+ constexpr int kLossyFormat = 1;
+ constexpr int kLosslessFormat = 2;
+
+ WebPFileFormat file_format = kUnknownFileFormat;
+ if (features.has_alpha && features.has_animation)
+ file_format = kExtendedAnimationWithAlphaFileFormat;
+ else if (features.has_animation)
+ file_format = kExtendedAnimationFileFormat;
+ else if (features.has_alpha)
+ file_format = kExtendedAlphaFileFormat;
+ else if (features.format == kLossyFormat)
+ file_format = kSimpleLossyFileFormat;
+ else if (features.format == kLosslessFormat)
+ file_format = kSimpleLosslessFileFormat;
+
+ DEFINE_THREAD_SAFE_STATIC_LOCAL(
+ blink::EnumerationHistogram, file_format_histogram,
+ ("Blink.DecodedImage.WebPFileFormat", kCountWebPFileFormats));
+ file_format_histogram.Count(file_format);
+}
+
} // namespace
namespace blink {
@@ -235,6 +280,8 @@ bool WEBPImageDecoder::UpdateDemuxer() {
if (!SetSize(width, height))
return SetFailed();
+ UpdateWebPFileFormatUMA(consolidated_data_);
+
format_flags_ = WebPDemuxGetI(demux_, WEBP_FF_FORMAT_FLAGS);
if (!(format_flags_ & ANIMATION_FLAG)) {
repetition_count_ = kAnimationNone;
diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder_test.cc b/chromium/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder_test.cc
index 3b7b8dc7b51..f95c8efdcc0 100644
--- a/chromium/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder_test.cc
+++ b/chromium/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder_test.cc
@@ -391,10 +391,8 @@ TEST(AnimatedWebPTests, randomDecodeAfterClearFrameBufferCache) {
&CreateWEBPDecoder, "/images/resources/webp-animated-icc-xmp.webp");
}
-// This test is disabled since it timed out on the Windows bot. See
-// crrev.com/962853004
TEST(AnimatedWebPTests,
- DISABLED_resumePartialDecodeAfterClearFrameBufferCache) {
+ resumePartialDecodeAfterClearFrameBufferCache) {
TestResumePartialDecodeAfterClearFrameBufferCache(
&CreateWEBPDecoder, "/images/resources/webp-animated-large.webp");
}
diff --git a/chromium/third_party/blink/renderer/platform/image-encoders/DEPS b/chromium/third_party/blink/renderer/platform/image-encoders/DEPS
index 5acbcd396c0..bbb4bc7b542 100644
--- a/chromium/third_party/blink/renderer/platform/image-encoders/DEPS
+++ b/chromium/third_party/blink/renderer/platform/image-encoders/DEPS
@@ -6,13 +6,9 @@ include_rules = [
"+third_party/blink/renderer/platform/image-encoders",
# Dependencies.
- "+third_party/blink/renderer/platform/geometry",
- "+third_party/blink/renderer/platform/graphics",
+ "+third_party/blink/renderer/platform/graphics/graphics_types.h",
"+third_party/blink/renderer/platform/histogram.h",
- "+third_party/blink/renderer/platform/instrumentation",
"+third_party/blink/renderer/platform/network/mime/mime_type_registry.h",
"+third_party/blink/renderer/platform/platform_export.h",
- "+third_party/blink/renderer/platform/shared_buffer.h",
- "+third_party/blink/renderer/platform/testing",
"+third_party/blink/renderer/platform/wtf",
]
diff --git a/chromium/third_party/blink/renderer/platform/image-encoders/image_encoder.cc b/chromium/third_party/blink/renderer/platform/image-encoders/image_encoder.cc
index b564b1ccb7e..44e294ae2ce 100644
--- a/chromium/third_party/blink/renderer/platform/image-encoders/image_encoder.cc
+++ b/chromium/third_party/blink/renderer/platform/image-encoders/image_encoder.cc
@@ -66,7 +66,7 @@ std::unique_ptr<ImageEncoder> ImageEncoder::Create(
return image_encoder;
}
-int ImageEncoder::MaxDimension(MimeType mime_type) {
+int ImageEncoder::MaxDimension(ImageEncodingMimeType mime_type) {
switch (mime_type) {
case kMimeTypePng:
return 65535;
diff --git a/chromium/third_party/blink/renderer/platform/image-encoders/image_encoder.h b/chromium/third_party/blink/renderer/platform/image-encoders/image_encoder.h
index 3822c4a8d22..4cb32b170b6 100644
--- a/chromium/third_party/blink/renderer/platform/image-encoders/image_encoder.h
+++ b/chromium/third_party/blink/renderer/platform/image-encoders/image_encoder.h
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_IMAGE_ENCODERS_IMAGE_ENCODER_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_IMAGE_ENCODERS_IMAGE_ENCODER_H_
+#include "third_party/blink/renderer/platform/graphics/graphics_types.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
#include "third_party/skia/include/core/SkStream.h"
@@ -47,14 +48,7 @@ class PLATFORM_EXPORT ImageEncoder {
const SkPixmap& src,
const SkWebpEncoder::Options&);
- enum MimeType {
- kMimeTypePng,
- kMimeTypeJpeg,
- kMimeTypeWebp,
- kNumberOfMimeTypeSupported
- };
-
- static int MaxDimension(MimeType mime_type);
+ static int MaxDimension(ImageEncodingMimeType mime_type);
static std::unique_ptr<ImageEncoder> Create(Vector<unsigned char>* dst,
const SkPixmap& src,
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 3578bfd004c..2a6639ad427 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
@@ -10,7 +10,9 @@
namespace blink {
-const char ImageEncoderUtils::kDefaultMimeType[] = "image/png";
+const ImageEncodingMimeType ImageEncoderUtils::kDefaultEncodingMimeType =
+ kMimeTypePng;
+const char ImageEncoderUtils::kDefaultRequestedMimeType[] = "image/png";
// This enum is used in a UMA histogram; the values should not be changed.
enum RequestedImageMimeType {
@@ -25,60 +27,64 @@ enum RequestedImageMimeType {
kNumberOfRequestedImageMimeTypes
};
-String ImageEncoderUtils::ToEncodingMimeType(const String& mime_type,
- const EncodeReason encode_reason) {
- String lowercase_mime_type = mime_type.DeprecatedLower();
+ImageEncodingMimeType ImageEncoderUtils::ToEncodingMimeType(
+ const String& mime_type_name,
+ const EncodeReason encode_reason) {
+ String lowercase_mime_type = mime_type_name.DeprecatedLower();
- if (mime_type.IsNull())
- lowercase_mime_type = kDefaultMimeType;
+ RequestedImageMimeType requested_mime_type;
+ if (mime_type_name.IsNull())
+ lowercase_mime_type = kDefaultRequestedMimeType;
- RequestedImageMimeType image_format;
if (lowercase_mime_type == "image/png") {
- image_format = kRequestedImageMimeTypePng;
+ requested_mime_type = kRequestedImageMimeTypePng;
} else if (lowercase_mime_type == "image/jpeg") {
- image_format = kRequestedImageMimeTypeJpeg;
+ requested_mime_type = kRequestedImageMimeTypeJpeg;
} else if (lowercase_mime_type == "image/webp") {
- image_format = kRequestedImageMimeTypeWebp;
+ requested_mime_type = kRequestedImageMimeTypeWebp;
} else if (lowercase_mime_type == "image/gif") {
- image_format = kRequestedImageMimeTypeGif;
+ requested_mime_type = kRequestedImageMimeTypeGif;
} else if (lowercase_mime_type == "image/bmp" ||
lowercase_mime_type == "image/x-windows-bmp") {
- image_format = kRequestedImageMimeTypeBmp;
+ requested_mime_type = kRequestedImageMimeTypeBmp;
} else if (lowercase_mime_type == "image/x-icon") {
- image_format = kRequestedImageMimeTypeIco;
+ requested_mime_type = kRequestedImageMimeTypeIco;
} else if (lowercase_mime_type == "image/tiff" ||
lowercase_mime_type == "image/x-tiff") {
- image_format = kRequestedImageMimeTypeTiff;
+ requested_mime_type = kRequestedImageMimeTypeTiff;
} else {
- image_format = kRequestedImageMimeTypeUnknown;
+ requested_mime_type = kRequestedImageMimeTypeUnknown;
}
if (encode_reason == kEncodeReasonToDataURL) {
DEFINE_THREAD_SAFE_STATIC_LOCAL(EnumerationHistogram,
- to_data_url_image_format_histogram,
+ to_data_url_requested_mime_type_histogram,
("Canvas.RequestedImageMimeTypes_toDataURL",
kNumberOfRequestedImageMimeTypes));
- to_data_url_image_format_histogram.Count(image_format);
+ to_data_url_requested_mime_type_histogram.Count(requested_mime_type);
} else if (encode_reason == kEncodeReasonToBlobCallback) {
DEFINE_THREAD_SAFE_STATIC_LOCAL(
- EnumerationHistogram, to_blob_callback_image_format_histogram,
+ EnumerationHistogram, to_blob_callback_requested_mime_type_histogram,
("Canvas.RequestedImageMimeTypes_toBlobCallback",
kNumberOfRequestedImageMimeTypes));
- to_blob_callback_image_format_histogram.Count(image_format);
+ to_blob_callback_requested_mime_type_histogram.Count(requested_mime_type);
} else if (encode_reason == kEncodeReasonConvertToBlobPromise) {
DEFINE_THREAD_SAFE_STATIC_LOCAL(
- EnumerationHistogram, convert_to_blob_promise_image_format_histogram,
+ EnumerationHistogram,
+ convert_to_blob_promise_requested_mime_type_histogram,
("Canvas.RequestedImageMimeTypes_convertToBlobPromise",
kNumberOfRequestedImageMimeTypes));
- convert_to_blob_promise_image_format_histogram.Count(image_format);
+ convert_to_blob_promise_requested_mime_type_histogram.Count(
+ requested_mime_type);
}
+ ImageEncodingMimeType encoding_mime_type = kDefaultEncodingMimeType;
// FIXME: Make isSupportedImageMIMETypeForEncoding threadsafe (to allow this
// method to be used on a worker thread).
- if (!MIMETypeRegistry::IsSupportedImageMIMETypeForEncoding(
+ if (MIMETypeRegistry::IsSupportedImageMIMETypeForEncoding(
lowercase_mime_type))
- lowercase_mime_type = kDefaultMimeType;
- return lowercase_mime_type;
+ ParseImageEncodingMimeType(lowercase_mime_type, encoding_mime_type);
+ return encoding_mime_type;
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/image-encoders/image_encoder_utils.h b/chromium/third_party/blink/renderer/platform/image-encoders/image_encoder_utils.h
index f5293beb41f..0d295cebeb9 100644
--- a/chromium/third_party/blink/renderer/platform/image-encoders/image_encoder_utils.h
+++ b/chromium/third_party/blink/renderer/platform/image-encoders/image_encoder_utils.h
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_IMAGE_ENCODERS_IMAGE_ENCODER_UTILS_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_IMAGE_ENCODERS_IMAGE_ENCODER_UTILS_H_
+#include "third_party/blink/renderer/platform/graphics/graphics_types.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -18,10 +19,13 @@ class PLATFORM_EXPORT ImageEncoderUtils {
kEncodeReasonConvertToBlobPromise = 2,
kNumberOfEncodeReasons
};
- static String ToEncodingMimeType(const String& mime_type, const EncodeReason);
// Default image mime type for toDataURL and toBlob functions
- static const char kDefaultMimeType[];
+ static const char kDefaultRequestedMimeType[];
+ static const ImageEncodingMimeType kDefaultEncodingMimeType;
+
+ static ImageEncodingMimeType ToEncodingMimeType(const String&,
+ const EncodeReason);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/instrumentation/DEPS b/chromium/third_party/blink/renderer/platform/instrumentation/DEPS
index 20dc455fb85..7f6cc453304 100644
--- a/chromium/third_party/blink/renderer/platform/instrumentation/DEPS
+++ b/chromium/third_party/blink/renderer/platform/instrumentation/DEPS
@@ -8,10 +8,8 @@ include_rules = [
# Dependencies.
"+base/gtest_prod_util.h",
"+base/json",
- "+base/macros.h",
"+base/memory",
"+base/strings",
- "+base/time",
"+base/trace_event",
"+base/values.h",
"+skia/ext/skia_trace_memory_dump_impl.h",
diff --git a/chromium/third_party/blink/renderer/platform/layout_unit.h b/chromium/third_party/blink/renderer/platform/layout_unit.h
index 7865a05d174..8521847ddc2 100644
--- a/chromium/third_party/blink/renderer/platform/layout_unit.h
+++ b/chromium/third_party/blink/renderer/platform/layout_unit.h
@@ -58,13 +58,13 @@ const int kIntMinForLayoutUnit = INT_MIN / kFixedPointDenominator;
// TODO(thakis): Remove these two lines once http://llvm.org/PR26504 is resolved
class PLATFORM_EXPORT LayoutUnit;
-inline bool operator<(const LayoutUnit&, const LayoutUnit&);
+constexpr inline bool operator<(const LayoutUnit&, const LayoutUnit&);
class LayoutUnit {
DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
public:
- LayoutUnit() : value_(0) {}
+ constexpr LayoutUnit() : value_(0) {}
explicit LayoutUnit(int value) { SetValue(value); }
explicit LayoutUnit(unsigned short value) { SetValue(value); }
explicit LayoutUnit(unsigned value) { SetValue(value); }
@@ -107,11 +107,11 @@ class LayoutUnit {
return v;
}
- int ToInt() const { return value_ / kFixedPointDenominator; }
- float ToFloat() const {
+ constexpr int ToInt() const { return value_ / kFixedPointDenominator; }
+ constexpr float ToFloat() const {
return static_cast<float>(value_) / kFixedPointDenominator;
}
- double ToDouble() const {
+ constexpr double ToDouble() const {
return static_cast<double>(value_) / kFixedPointDenominator;
}
unsigned ToUnsigned() const {
@@ -126,16 +126,16 @@ class LayoutUnit {
operator int() const = delete;
operator unsigned() const = delete;
- operator double() const { return ToDouble(); }
- operator float() const { return ToFloat(); }
- operator bool() const { return value_; }
+ constexpr operator double() const { return ToDouble(); }
+ constexpr operator float() const { return ToFloat(); }
+ constexpr operator bool() const { return value_; }
LayoutUnit operator++(int) {
value_ = ClampAdd(value_, kFixedPointDenominator);
return *this;
}
- inline int RawValue() const { return value_; }
+ constexpr int RawValue() const { return value_; }
inline void SetRawValue(int value) { value_ = value; }
void SetRawValue(long long value) {
REPORT_OVERFLOW(value > std::numeric_limits<int>::min() &&
@@ -252,11 +252,11 @@ class LayoutUnit {
int value_;
};
-inline bool operator<=(const LayoutUnit& a, const LayoutUnit& b) {
+constexpr bool operator<=(const LayoutUnit& a, const LayoutUnit& b) {
return a.RawValue() <= b.RawValue();
}
-inline bool operator<=(const LayoutUnit& a, float b) {
+constexpr bool operator<=(const LayoutUnit& a, float b) {
return a.ToFloat() <= b;
}
@@ -264,7 +264,7 @@ inline bool operator<=(const LayoutUnit& a, int b) {
return a <= LayoutUnit(b);
}
-inline bool operator<=(const float a, const LayoutUnit& b) {
+constexpr bool operator<=(const float a, const LayoutUnit& b) {
return a <= b.ToFloat();
}
@@ -272,7 +272,7 @@ inline bool operator<=(const int a, const LayoutUnit& b) {
return LayoutUnit(a) <= b;
}
-inline bool operator>=(const LayoutUnit& a, const LayoutUnit& b) {
+constexpr bool operator>=(const LayoutUnit& a, const LayoutUnit& b) {
return a.RawValue() >= b.RawValue();
}
@@ -280,11 +280,11 @@ inline bool operator>=(const LayoutUnit& a, int b) {
return a >= LayoutUnit(b);
}
-inline bool operator>=(const float a, const LayoutUnit& b) {
+constexpr bool operator>=(const float a, const LayoutUnit& b) {
return a >= b.ToFloat();
}
-inline bool operator>=(const LayoutUnit& a, float b) {
+constexpr bool operator>=(const LayoutUnit& a, float b) {
return a.ToFloat() >= b;
}
@@ -292,7 +292,7 @@ inline bool operator>=(const int a, const LayoutUnit& b) {
return LayoutUnit(a) >= b;
}
-inline bool operator<(const LayoutUnit& a, const LayoutUnit& b) {
+constexpr bool operator<(const LayoutUnit& a, const LayoutUnit& b) {
return a.RawValue() < b.RawValue();
}
@@ -300,11 +300,11 @@ inline bool operator<(const LayoutUnit& a, int b) {
return a < LayoutUnit(b);
}
-inline bool operator<(const LayoutUnit& a, float b) {
+constexpr bool operator<(const LayoutUnit& a, float b) {
return a.ToFloat() < b;
}
-inline bool operator<(const LayoutUnit& a, double b) {
+constexpr bool operator<(const LayoutUnit& a, double b) {
return a.ToDouble() < b;
}
@@ -312,19 +312,19 @@ inline bool operator<(const int a, const LayoutUnit& b) {
return LayoutUnit(a) < b;
}
-inline bool operator<(const float a, const LayoutUnit& b) {
+constexpr bool operator<(const float a, const LayoutUnit& b) {
return a < b.ToFloat();
}
-inline bool operator>(const LayoutUnit& a, const LayoutUnit& b) {
+constexpr bool operator>(const LayoutUnit& a, const LayoutUnit& b) {
return a.RawValue() > b.RawValue();
}
-inline bool operator>(const LayoutUnit& a, double b) {
+constexpr bool operator>(const LayoutUnit& a, double b) {
return a.ToDouble() > b;
}
-inline bool operator>(const LayoutUnit& a, float b) {
+constexpr bool operator>(const LayoutUnit& a, float b) {
return a.ToFloat() > b;
}
@@ -336,15 +336,15 @@ inline bool operator>(const int a, const LayoutUnit& b) {
return LayoutUnit(a) > b;
}
-inline bool operator>(const float a, const LayoutUnit& b) {
+constexpr bool operator>(const float a, const LayoutUnit& b) {
return a > b.ToFloat();
}
-inline bool operator>(const double a, const LayoutUnit& b) {
+constexpr bool operator>(const double a, const LayoutUnit& b) {
return a > b.ToDouble();
}
-inline bool operator!=(const LayoutUnit& a, const LayoutUnit& b) {
+constexpr bool operator!=(const LayoutUnit& a, const LayoutUnit& b) {
return a.RawValue() != b.RawValue();
}
@@ -360,7 +360,7 @@ inline bool operator!=(const LayoutUnit& a, int b) {
return a != LayoutUnit(b);
}
-inline bool operator==(const LayoutUnit& a, const LayoutUnit& b) {
+constexpr bool operator==(const LayoutUnit& a, const LayoutUnit& b) {
return a.RawValue() == b.RawValue();
}
@@ -372,11 +372,11 @@ inline bool operator==(const int a, const LayoutUnit& b) {
return LayoutUnit(a) == b;
}
-inline bool operator==(const LayoutUnit& a, float b) {
+constexpr bool operator==(const LayoutUnit& a, float b) {
return a.ToFloat() == b;
}
-inline bool operator==(const float a, const LayoutUnit& b) {
+constexpr bool operator==(const float a, const LayoutUnit& b) {
return a == b.ToFloat();
}
@@ -452,11 +452,11 @@ inline LayoutUnit operator*(const int a, const LayoutUnit& b) {
return LayoutUnit(a) * b;
}
-inline float operator*(const float a, const LayoutUnit& b) {
+constexpr float operator*(const float a, const LayoutUnit& b) {
return a * b.ToFloat();
}
-inline double operator*(const double a, const LayoutUnit& b) {
+constexpr double operator*(const double a, const LayoutUnit& b) {
return a * b.ToDouble();
}
@@ -468,11 +468,11 @@ inline LayoutUnit operator/(const LayoutUnit& a, const LayoutUnit& b) {
return return_val;
}
-inline float operator/(const LayoutUnit& a, float b) {
+constexpr float operator/(const LayoutUnit& a, float b) {
return a.ToFloat() / b;
}
-inline double operator/(const LayoutUnit& a, double b) {
+constexpr double operator/(const LayoutUnit& a, double b) {
return a.ToDouble() / b;
}
@@ -496,11 +496,11 @@ inline LayoutUnit operator/(const LayoutUnit& a, unsigned long long b) {
return a / LayoutUnit(b);
}
-inline float operator/(const float a, const LayoutUnit& b) {
+constexpr float operator/(const float a, const LayoutUnit& b) {
return a / b.ToFloat();
}
-inline double operator/(const double a, const LayoutUnit& b) {
+constexpr double operator/(const double a, const LayoutUnit& b) {
return a / b.ToDouble();
}
@@ -546,11 +546,11 @@ inline LayoutUnit operator+(const int a, const LayoutUnit& b) {
return LayoutUnit(a) + b;
}
-inline float operator+(const float a, const LayoutUnit& b) {
+constexpr inline float operator+(const float a, const LayoutUnit& b) {
return a + b.ToFloat();
}
-inline double operator+(const double a, const LayoutUnit& b) {
+constexpr inline double operator+(const double a, const LayoutUnit& b) {
return a + b.ToDouble();
}
@@ -568,11 +568,11 @@ inline LayoutUnit operator-(const LayoutUnit& a, unsigned b) {
return a - LayoutUnit(b);
}
-inline float operator-(const LayoutUnit& a, float b) {
+constexpr float operator-(const LayoutUnit& a, float b) {
return a.ToFloat() - b;
}
-inline double operator-(const LayoutUnit& a, double b) {
+constexpr double operator-(const LayoutUnit& a, double b) {
return a.ToDouble() - b;
}
@@ -580,7 +580,7 @@ inline LayoutUnit operator-(const int a, const LayoutUnit& b) {
return LayoutUnit(a) - b;
}
-inline float operator-(const float a, const LayoutUnit& b) {
+constexpr float operator-(const float a, const LayoutUnit& b) {
return a - b.ToFloat();
}
diff --git a/chromium/third_party/blink/renderer/platform/lifecycle_notifier.h b/chromium/third_party/blink/renderer/platform/lifecycle_notifier.h
index 668002ef099..47e9a28330f 100644
--- a/chromium/third_party/blink/renderer/platform/lifecycle_notifier.h
+++ b/chromium/third_party/blink/renderer/platform/lifecycle_notifier.h
@@ -81,20 +81,6 @@ class LifecycleNotifier : public GarbageCollectedMixin {
}
}
- // ForEachObserver() variant that does not protect against memory corruption.
- //
- // Only used by SynchronousMutationNotifier::NotifyUpdateCharacterData. See
- // implementation comment for why it is necessary.
- //
- // TODO(crbug.com/862900): Fix SynchronousMutationNotifier and remove this.
- template <typename ForEachCallable>
- void ForEachObserverWithoutChecks(const ForEachCallable& callable) const {
- for (LifecycleObserverBase* observer_base : observers_) {
- Observer* observer = static_cast<Observer*>(observer_base);
- callable(observer);
- }
- }
-
private:
using ObserverSet = HeapHashSet<WeakMember<LifecycleObserverBase>>;
diff --git a/chromium/third_party/blink/renderer/platform/loader/BUILD.gn b/chromium/third_party/blink/renderer/platform/loader/BUILD.gn
index 2e0307462b4..89cb07a378b 100644
--- a/chromium/third_party/blink/renderer/platform/loader/BUILD.gn
+++ b/chromium/third_party/blink/renderer/platform/loader/BUILD.gn
@@ -33,6 +33,8 @@ blink_platform_sources("loader") {
"fetch/fetch_parameters.h",
"fetch/fetch_utils.cc",
"fetch/fetch_utils.h",
+ "fetch/https_state.cc",
+ "fetch/https_state.h",
"fetch/integrity_metadata.cc",
"fetch/integrity_metadata.h",
"fetch/memory_cache.cc",
@@ -68,6 +70,8 @@ blink_platform_sources("loader") {
"fetch/resource_status.h",
"fetch/resource_timing_info.cc",
"fetch/resource_timing_info.h",
+ "fetch/script_cached_metadata_handler.cc",
+ "fetch/script_cached_metadata_handler.h",
"fetch/script_fetch_options.cc",
"fetch/script_fetch_options.h",
"fetch/source_keyed_cached_metadata_handler.cc",
@@ -112,7 +116,6 @@ jumbo_source_set("unit_tests") {
"fetch/raw_resource_test.cc",
"fetch/resource_fetcher_test.cc",
"fetch/resource_load_scheduler_test.cc",
- "fetch/resource_loader_options_test.cc",
"fetch/resource_loader_test.cc",
"fetch/resource_request_test.cc",
"fetch/resource_response_test.cc",
diff --git a/chromium/third_party/blink/renderer/platform/loader/DEPS b/chromium/third_party/blink/renderer/platform/loader/DEPS
index 624703cb663..aa6fb766afe 100644
--- a/chromium/third_party/blink/renderer/platform/loader/DEPS
+++ b/chromium/third_party/blink/renderer/platform/loader/DEPS
@@ -10,6 +10,7 @@ include_rules = [
"+base/strings/string_number_conversions.h", # for fetch/ResourceLoadScheduler.cpp
"+components/link_header_util", # for LinkHeader.cpp
"+services/network/public", # for Fetch API and CORS
+ "+third_party/blink/renderer/platform/bindings/parkable_string.h",
"+third_party/blink/renderer/platform/bindings/script_forbidden_scope.h",
"+third_party/blink/renderer/platform/blob/blob_data.h",
"+third_party/blink/renderer/platform/cross_origin_attribute_value.h",
diff --git a/chromium/third_party/blink/renderer/platform/loader/OWNERS b/chromium/third_party/blink/renderer/platform/loader/OWNERS
index fa3423b99fb..b2c834a0937 100644
--- a/chromium/third_party/blink/renderer/platform/loader/OWNERS
+++ b/chromium/third_party/blink/renderer/platform/loader/OWNERS
@@ -1,5 +1,6 @@
japhet@chromium.org
mkwst@chromium.org
+toyoshim@chromium.org
yhirano@chromium.org
yoav@yoav.ws
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 07a52467ced..cf7106345a8 100644
--- a/chromium/third_party/blink/renderer/platform/loader/cors/cors.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/cors/cors.cc
@@ -104,18 +104,19 @@ base::Optional<network::CORSErrorStatus> CheckPreflightAccess(
!privilege->block_local_access_from_local_origin_);
}
-base::Optional<network::mojom::CORSError> CheckRedirectLocation(
- const KURL& url) {
- static const bool run_blink_side_scheme_check =
- !RuntimeEnabledFeatures::OutOfBlinkCORSEnabled();
- // TODO(toyoshim): Deprecate Blink side scheme check when we enable
- // out-of-renderer CORS support. This will need to deprecate Blink APIs that
- // are currently used by an embedder. See https://crbug.com/800669.
- if (run_blink_side_scheme_check &&
- !SchemeRegistry::ShouldTreatURLSchemeAsCORSEnabled(url.Protocol())) {
- return network::mojom::CORSError::kRedirectDisallowedScheme;
- }
- return network::cors::CheckRedirectLocation(url, run_blink_side_scheme_check);
+base::Optional<network::CORSErrorStatus> CheckRedirectLocation(
+ const KURL& url,
+ network::mojom::FetchRequestMode request_mode,
+ const SecurityOrigin* origin,
+ CORSFlag cors_flag) {
+ base::Optional<url::Origin> origin_to_pass;
+ if (origin)
+ origin_to_pass = origin->ToUrlOrigin();
+
+ // Blink-side implementations rewrite the origin instead of setting the
+ // tainted flag.
+ return network::cors::CheckRedirectLocation(
+ url, request_mode, origin_to_pass, cors_flag == CORSFlag::Set, false);
}
base::Optional<network::mojom::CORSError> CheckPreflight(
@@ -133,17 +134,15 @@ bool IsCORSEnabledRequestMode(network::mojom::FetchRequestMode request_mode) {
return network::cors::IsCORSEnabledRequestMode(request_mode);
}
-bool EnsurePreflightResultAndCacheOnSuccess(
+base::Optional<network::CORSErrorStatus> EnsurePreflightResultAndCacheOnSuccess(
const HTTPHeaderMap& response_header_map,
const String& origin,
const KURL& request_url,
const String& request_method,
const HTTPHeaderMap& request_header_map,
- network::mojom::FetchCredentialsMode request_credentials_mode,
- String* error_description) {
+ network::mojom::FetchCredentialsMode request_credentials_mode) {
DCHECK(!origin.IsNull());
DCHECK(!request_method.IsNull());
- DCHECK(error_description);
base::Optional<network::mojom::CORSError> error;
@@ -157,38 +156,23 @@ bool EnsurePreflightResultAndCacheOnSuccess(
GetOptionalHeaderValue(response_header_map,
HTTPNames::Access_Control_Max_Age),
&error);
- if (error) {
- *error_description = CORS::GetErrorString(
- CORS::ErrorParameter::CreateForPreflightResponseCheck(*error,
- String()));
- return false;
- }
+ if (error)
+ return network::CORSErrorStatus(*error);
- error = result->EnsureAllowedCrossOriginMethod(
+ base::Optional<network::CORSErrorStatus> status;
+ status = result->EnsureAllowedCrossOriginMethod(
std::string(request_method.Ascii().data()));
- if (error) {
- *error_description = CORS::GetErrorString(
- CORS::ErrorParameter::CreateForPreflightResponseCheck(*error,
- request_method));
- return false;
- }
+ if (status)
+ return status;
- std::string detected_error_header;
- error = result->EnsureAllowedCrossOriginHeaders(
- *CreateNetHttpRequestHeaders(request_header_map), &detected_error_header);
- if (error) {
- *error_description = CORS::GetErrorString(
- CORS::ErrorParameter::CreateForPreflightResponseCheck(
- *error, String(detected_error_header.data(),
- detected_error_header.length())));
- return false;
- }
-
- DCHECK(!error);
+ status = result->EnsureAllowedCrossOriginHeaders(
+ *CreateNetHttpRequestHeaders(request_header_map));
+ if (status)
+ return status;
GetPerThreadPreflightCache().AppendEntry(std::string(origin.Ascii().data()),
request_url, std::move(result));
- return true;
+ return base::nullopt;
}
bool CheckIfRequestCanSkipPreflight(
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 80304420294..5a192c7f5b2 100644
--- a/chromium/third_party/blink/renderer/platform/loader/cors/cors.h
+++ b/chromium/third_party/blink/renderer/platform/loader/cors/cors.h
@@ -18,6 +18,11 @@ class HTTPHeaderMap;
class KURL;
class SecurityOrigin;
+enum class CORSFlag : uint8_t {
+ Unset,
+ Set,
+};
+
// CORS related utility functions.
namespace CORS {
@@ -38,8 +43,11 @@ PLATFORM_EXPORT base::Optional<network::CORSErrorStatus> CheckPreflightAccess(
network::mojom::FetchCredentialsMode,
const SecurityOrigin&);
-PLATFORM_EXPORT base::Optional<network::mojom::CORSError> CheckRedirectLocation(
- const KURL&);
+PLATFORM_EXPORT base::Optional<network::CORSErrorStatus> CheckRedirectLocation(
+ const KURL&,
+ network::mojom::FetchRequestMode,
+ const SecurityOrigin*,
+ CORSFlag);
PLATFORM_EXPORT base::Optional<network::mojom::CORSError> CheckPreflight(
const int preflight_response_status_code);
@@ -49,14 +57,14 @@ PLATFORM_EXPORT base::Optional<network::CORSErrorStatus> CheckExternalPreflight(
PLATFORM_EXPORT bool IsCORSEnabledRequestMode(network::mojom::FetchRequestMode);
-PLATFORM_EXPORT bool EnsurePreflightResultAndCacheOnSuccess(
+PLATFORM_EXPORT base::Optional<network::CORSErrorStatus>
+EnsurePreflightResultAndCacheOnSuccess(
const HTTPHeaderMap& response_header_map,
const String& origin,
const KURL& request_url,
const String& request_method,
const HTTPHeaderMap& request_header_map,
- network::mojom::FetchCredentialsMode request_credentials_mode,
- String* error_description);
+ network::mojom::FetchCredentialsMode request_credentials_mode);
PLATFORM_EXPORT bool CheckIfRequestCanSkipPreflight(
const String& origin,
diff --git a/chromium/third_party/blink/renderer/platform/loader/cors/cors_error_string.cc b/chromium/third_party/blink/renderer/platform/loader/cors/cors_error_string.cc
index 961b7677d39..ef29410fa23 100644
--- a/chromium/third_party/blink/renderer/platform/loader/cors/cors_error_string.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/cors/cors_error_string.cc
@@ -4,8 +4,17 @@
#include "third_party/blink/renderer/platform/loader/cors/cors_error_string.h"
+#include <initializer_list>
+
+#include "third_party/blink/renderer/platform/loader/fetch/fetch_initiator_type_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_origin.h"
+#include "third_party/blink/renderer/platform/wtf/ascii_ctype.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
+#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
+#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
+#include "third_party/blink/renderer/platform/wtf/text/string_view.h"
namespace blink {
@@ -13,355 +22,190 @@ namespace CORS {
namespace {
-const KURL& GetInvalidURL() {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(KURL, invalid_url, ());
- return invalid_url;
-}
-
-bool IsInterestingStatusCode(int status_code) {
- // Predicate that gates what status codes should be included in console error
- // messages for responses containing no access control headers.
- return status_code >= 400;
-}
-
-ErrorParameter CreateWrongParameter(network::mojom::CORSError error) {
- return ErrorParameter(
- error, GetInvalidURL(), GetInvalidURL(), 0 /* status_code */,
- *SecurityOrigin::CreateUniqueOpaque(),
- WebURLRequest::kRequestContextUnspecified, String(), true);
-}
-
-} // namespace
-
-// static
-ErrorParameter ErrorParameter::Create(
- const network::CORSErrorStatus& error_status,
- const KURL& first_url,
- const KURL& second_url,
- const int status_code,
- const SecurityOrigin& origin,
- const WebURLRequest::RequestContext context) {
- return ErrorParameter(error_status.cors_error, first_url, second_url,
- status_code, origin, context,
- String(error_status.failed_parameter.c_str()), false);
-}
-
-// static
-ErrorParameter ErrorParameter::CreateForDisallowedByMode(
- const KURL& request_url) {
- return ErrorParameter(network::mojom::CORSError::kDisallowedByMode,
- request_url, GetInvalidURL(), 0 /* status_code */,
- *SecurityOrigin::CreateUniqueOpaque(),
- WebURLRequest::kRequestContextUnspecified, String(),
- false);
-}
-
-// static
-ErrorParameter ErrorParameter::CreateForInvalidResponse(
- const KURL& request_url,
- const SecurityOrigin& origin) {
- return ErrorParameter(network::mojom::CORSError::kInvalidResponse,
- request_url, GetInvalidURL(), 0 /* status_code */,
- origin, WebURLRequest::kRequestContextUnspecified,
- String(), false);
+void Append(StringBuilder& builder, std::initializer_list<StringView> views) {
+ for (const StringView& view : views) {
+ builder.Append(view);
+ }
}
-// static
-ErrorParameter ErrorParameter::CreateForAccessCheck(
- const network::CORSErrorStatus& error_status,
- const KURL& request_url,
- int response_status_code,
- const SecurityOrigin& origin,
- const WebURLRequest::RequestContext context,
- const KURL& redirect_url) {
- switch (error_status.cors_error) {
- case network::mojom::CORSError::kInvalidResponse:
- case network::mojom::CORSError::kWildcardOriginNotAllowed:
- case network::mojom::CORSError::kMissingAllowOriginHeader:
- case network::mojom::CORSError::kMultipleAllowOriginValues:
- case network::mojom::CORSError::kInvalidAllowOriginValue:
- case network::mojom::CORSError::kAllowOriginMismatch:
- case network::mojom::CORSError::kInvalidAllowCredentials:
+bool IsPreflightError(network::mojom::CORSError error_code) {
+ switch (error_code) {
case network::mojom::CORSError::kPreflightWildcardOriginNotAllowed:
case network::mojom::CORSError::kPreflightMissingAllowOriginHeader:
case network::mojom::CORSError::kPreflightMultipleAllowOriginValues:
case network::mojom::CORSError::kPreflightInvalidAllowOriginValue:
case network::mojom::CORSError::kPreflightAllowOriginMismatch:
case network::mojom::CORSError::kPreflightInvalidAllowCredentials:
- return ErrorParameter(error_status.cors_error, request_url, redirect_url,
- response_status_code, origin, context,
- String(error_status.failed_parameter.c_str()),
- false);
- default:
- NOTREACHED();
- }
- return CreateWrongParameter(error_status.cors_error);
-}
-
-// static
-ErrorParameter ErrorParameter::CreateForPreflightStatusCheck(
- int response_status_code) {
- return ErrorParameter(network::mojom::CORSError::kPreflightInvalidStatus,
- GetInvalidURL(), GetInvalidURL(), response_status_code,
- *SecurityOrigin::CreateUniqueOpaque(),
- WebURLRequest::kRequestContextUnspecified, String(),
- false);
-}
-
-// static
-ErrorParameter ErrorParameter::CreateForDisallowedRedirect() {
- return ErrorParameter(
- network::mojom::CORSError::kPreflightDisallowedRedirect, GetInvalidURL(),
- GetInvalidURL(), 0, *SecurityOrigin::CreateUniqueOpaque(),
- WebURLRequest::kRequestContextUnspecified, String(), false);
-}
-
-// static
-ErrorParameter ErrorParameter::CreateForExternalPreflightCheck(
- const network::CORSErrorStatus& error) {
- switch (error.cors_error) {
+ case network::mojom::CORSError::kPreflightInvalidStatus:
+ case network::mojom::CORSError::kPreflightDisallowedRedirect:
case network::mojom::CORSError::kPreflightMissingAllowExternal:
case network::mojom::CORSError::kPreflightInvalidAllowExternal:
- return ErrorParameter(error.cors_error, GetInvalidURL(), GetInvalidURL(),
- 0 /* status_code */,
- *SecurityOrigin::CreateUniqueOpaque(),
- WebURLRequest::kRequestContextUnspecified,
- error.failed_parameter.c_str(), false);
- default:
- NOTREACHED();
- }
- return CreateWrongParameter(error.cors_error);
-}
-
-// static
-ErrorParameter ErrorParameter::CreateForPreflightResponseCheck(
- const network::mojom::CORSError error,
- const String& hint) {
- switch (error) {
- case network::mojom::CORSError::kInvalidAllowMethodsPreflightResponse:
- case network::mojom::CORSError::kInvalidAllowHeadersPreflightResponse:
- case network::mojom::CORSError::kMethodDisallowedByPreflightResponse:
- case network::mojom::CORSError::kHeaderDisallowedByPreflightResponse:
- return ErrorParameter(
- error, GetInvalidURL(), GetInvalidURL(), 0 /* status_code */,
- *SecurityOrigin::CreateUniqueOpaque(),
- WebURLRequest::kRequestContextUnspecified, hint, false);
+ return true;
default:
- NOTREACHED();
+ return false;
}
- return CreateWrongParameter(error);
}
-// static
-ErrorParameter ErrorParameter::CreateForRedirectCheck(
- network::mojom::CORSError error,
- const KURL& request_url,
- const KURL& redirect_url) {
- switch (error) {
- case network::mojom::CORSError::kRedirectDisallowedScheme:
- case network::mojom::CORSError::kRedirectContainsCredentials:
- return ErrorParameter(
- error, request_url, redirect_url, 0 /* status_code */,
- *SecurityOrigin::CreateUniqueOpaque(),
- WebURLRequest::kRequestContextUnspecified, String(), false);
- default:
- NOTREACHED();
- }
- return CreateWrongParameter(error);
-}
-
-ErrorParameter::ErrorParameter(const network::mojom::CORSError error,
- const KURL& first_url,
- const KURL& second_url,
- const int status_code,
- const SecurityOrigin& origin,
- const WebURLRequest::RequestContext context,
- const String& hint,
- bool unknown)
- : error(error),
- first_url(first_url),
- second_url(second_url),
- status_code(status_code),
- origin(origin),
- context(context),
- hint(hint),
- unknown(unknown) {}
+} // namespace
-String GetErrorString(const ErrorParameter& param) {
- static const char kNoCorsInformation[] =
+String GetErrorString(const network::CORSErrorStatus& status,
+ const KURL& initial_request_url,
+ const KURL& last_request_url,
+ const SecurityOrigin& origin,
+ Resource::Type resource_type,
+ const AtomicString& initiator_name) {
+ StringBuilder builder;
+ static constexpr char kNoCorsInformation[] =
" Have the server send the header with a valid value, or, if an opaque "
"response serves your needs, set the request's mode to 'no-cors' to "
"fetch the resource with CORS disabled.";
- static const char kPreflightInformation[] =
- "Response to preflight request doesn't pass access control check: ";
using CORSError = network::mojom::CORSError;
- const auto& hint = param.hint;
-
- if (param.unknown)
- return String::Format("CORS error, code %d", static_cast<int>(param.error));
+ const StringView hint(status.failed_parameter.data(),
+ status.failed_parameter.size());
+
+ const char* resource_kind_raw =
+ Resource::ResourceTypeToString(resource_type, initiator_name);
+ String resource_kind(resource_kind_raw);
+ if (strlen(resource_kind_raw) >= 2 && IsASCIILower(resource_kind_raw[1]))
+ resource_kind = resource_kind.LowerASCII();
+
+ Append(builder, {"Access to ", resource_kind, " at '",
+ last_request_url.GetString(), "' "});
+ if (initial_request_url != last_request_url) {
+ Append(builder,
+ {"(redirected from '", initial_request_url.GetString(), "') "});
+ }
+ Append(builder, {"from origin '", origin.ToString(),
+ "' has been blocked by CORS policy: "});
- String redirect_denied =
- param.second_url.IsValid()
- ? String::Format(
- "Redirect from '%s' to '%s' has been blocked by CORS policy: ",
- param.first_url.GetString().Utf8().data(),
- param.second_url.GetString().Utf8().data())
- : String();
+ if (IsPreflightError(status.cors_error)) {
+ builder.Append(
+ "Response to preflight request doesn't pass access control check: ");
+ }
- switch (param.error) {
+ switch (status.cors_error) {
case CORSError::kDisallowedByMode:
- return String::Format(
- "Failed to load '%s': Cross origin requests are not allowed by "
- "request mode.",
- param.first_url.GetString().Utf8().data());
+ builder.Append("Cross origin requests are not allowed by request mode.");
+ break;
case CORSError::kInvalidResponse:
- return String::Format(
- "%sInvalid response. Origin '%s' is therefore not allowed access.",
- redirect_denied.Utf8().data(), param.origin.ToString().Utf8().data());
+ builder.Append("The response is invalid.");
+ break;
case CORSError::kWildcardOriginNotAllowed:
case CORSError::kPreflightWildcardOriginNotAllowed:
- return String::Format(
- "%s%sThe value of the 'Access-Control-Allow-Origin' header in the "
+ builder.Append(
+ "The value of the 'Access-Control-Allow-Origin' header in the "
"response must not be the wildcard '*' when the request's "
- "credentials mode is 'include'. Origin '%s' is therefore not allowed "
- "access.%s",
- param.error == CORSError::kPreflightWildcardOriginNotAllowed
- ? kPreflightInformation
- : "",
- redirect_denied.Utf8().data(), param.origin.ToString().Utf8().data(),
- param.context == WebURLRequest::kRequestContextXMLHttpRequest
- ? " The credentials mode of requests initiated by the "
- "XMLHttpRequest is controlled by the withCredentials attribute."
- : "");
+ "credentials mode is 'include'.");
+ if (initiator_name == FetchInitiatorTypeNames::xmlhttprequest) {
+ builder.Append(
+ " The credentials mode of requests initiated by the "
+ "XMLHttpRequest is controlled by the withCredentials attribute.");
+ }
+ break;
case CORSError::kMissingAllowOriginHeader:
case CORSError::kPreflightMissingAllowOriginHeader:
- return String::Format(
- "%s%sNo 'Access-Control-Allow-Origin' header is present on the "
- "requested resource. Origin '%s' is therefore not allowed access."
- "%s%s",
- param.error == CORSError::kPreflightMissingAllowOriginHeader
- ? kPreflightInformation
- : "",
- redirect_denied.Utf8().data(), param.origin.ToString().Utf8().data(),
- IsInterestingStatusCode(param.status_code)
- ? String::Format(" The response had HTTP status code %d.",
- param.status_code)
- .Utf8()
- .data()
- : "",
- param.context == WebURLRequest::kRequestContextFetch
- ? " If an opaque response serves your needs, set the request's "
- "mode to 'no-cors' to fetch the resource with CORS disabled."
- : "");
+ builder.Append(
+ "No 'Access-Control-Allow-Origin' header is present on the "
+ "requested resource.");
+ if (initiator_name == FetchInitiatorTypeNames::fetch) {
+ builder.Append(
+ " If an opaque response serves your needs, set the request's "
+ "mode to 'no-cors' to fetch the resource with CORS disabled.");
+ }
+ break;
case CORSError::kMultipleAllowOriginValues:
case CORSError::kPreflightMultipleAllowOriginValues:
- return String::Format(
- "%s%sThe 'Access-Control-Allow-Origin' header contains multiple "
- "values '%s', but only one is allowed. Origin '%s' is therefore not "
- "allowed access.%s",
- param.error == CORSError::kPreflightMultipleAllowOriginValues
- ? kPreflightInformation
- : "",
- redirect_denied.Utf8().data(), hint.Utf8().data(),
- param.origin.ToString().Utf8().data(),
- param.context == WebURLRequest::kRequestContextFetch
- ? kNoCorsInformation
- : "");
+ Append(builder,
+ {"The 'Access-Control-Allow-Origin' header contains multiple "
+ "values '",
+ hint, "', but only one is allowed."});
+ if (initiator_name == FetchInitiatorTypeNames::fetch)
+ builder.Append(kNoCorsInformation);
+ break;
case CORSError::kInvalidAllowOriginValue:
case CORSError::kPreflightInvalidAllowOriginValue:
- return String::Format(
- "%s%sThe 'Access-Control-Allow-Origin' header contains the invalid "
- "value '%s'. Origin '%s' is therefore not allowed access.%s",
- param.error == CORSError::kPreflightInvalidAllowOriginValue
- ? kPreflightInformation
- : "",
- redirect_denied.Utf8().data(), hint.Utf8().data(),
- param.origin.ToString().Utf8().data(),
- param.context == WebURLRequest::kRequestContextFetch
- ? kNoCorsInformation
- : "");
+ Append(builder, {"The 'Access-Control-Allow-Origin' header contains the "
+ "invalid value '",
+ hint, "'."});
+ if (initiator_name == FetchInitiatorTypeNames::fetch)
+ builder.Append(kNoCorsInformation);
+ break;
case CORSError::kAllowOriginMismatch:
case CORSError::kPreflightAllowOriginMismatch:
- return String::Format(
- "%s%sThe 'Access-Control-Allow-Origin' header has a value '%s' that "
- "is not equal to the supplied origin. Origin '%s' is therefore not "
- "allowed access.%s",
- param.error == CORSError::kPreflightAllowOriginMismatch
- ? kPreflightInformation
- : "",
- redirect_denied.Utf8().data(), hint.Utf8().data(),
- param.origin.ToString().Utf8().data(),
- param.context == WebURLRequest::kRequestContextFetch
- ? kNoCorsInformation
- : "");
+ Append(builder, {"The 'Access-Control-Allow-Origin' header has a value '",
+ hint, "' that is not equal to the supplied origin."});
+ if (initiator_name == FetchInitiatorTypeNames::fetch)
+ builder.Append(kNoCorsInformation);
+ break;
case CORSError::kInvalidAllowCredentials:
case CORSError::kPreflightInvalidAllowCredentials:
- return String::Format(
- "%s%sThe value of the 'Access-Control-Allow-Credentials' header in "
- "the response is '%s' which must be 'true' when the request's "
- "credentials mode is 'include'. Origin '%s' is therefore not allowed "
- "access.%s",
- param.error == CORSError::kPreflightInvalidAllowCredentials
- ? kPreflightInformation
- : "",
- redirect_denied.Utf8().data(), hint.Utf8().data(),
- param.origin.ToString().Utf8().data(),
- (param.context == WebURLRequest::kRequestContextXMLHttpRequest
- ? " The credentials mode of requests initiated by the "
- "XMLHttpRequest is controlled by the withCredentials "
- "attribute."
- : ""));
+ Append(builder,
+ {"The value of the 'Access-Control-Allow-Credentials' header in "
+ "the response is '",
+ hint,
+ "' which must be 'true' when the request's credentials mode is "
+ "'include'."});
+ if (initiator_name == FetchInitiatorTypeNames::xmlhttprequest) {
+ builder.Append(
+ " The credentials mode of requests initiated by the "
+ "XMLHttpRequest is controlled by the withCredentials "
+ "attribute.");
+ }
+ break;
+ case CORSError::kCORSDisabledScheme:
+ Append(builder,
+ {"Cross origin requests are only supported for protocol schemes: ",
+ SchemeRegistry::ListOfCORSEnabledURLSchemes(), "."});
+ break;
case CORSError::kPreflightInvalidStatus:
- return String("Response for preflight does not have HTTP ok status.");
+ builder.Append("It does not have HTTP ok status.");
+ break;
case CORSError::kPreflightDisallowedRedirect:
- return String("Response for preflight is invalid (redirect)");
+ builder.Append("Redirect is not allowed for a preflight request.");
+ break;
case CORSError::kPreflightMissingAllowExternal:
- return String(
+ builder.Append(
"No 'Access-Control-Allow-External' header was present in the "
"preflight response for this external request (This is an "
"experimental header which is defined in "
"'https://wicg.github.io/cors-rfc1918/').");
+ break;
case CORSError::kPreflightInvalidAllowExternal:
- return String::Format(
- "The 'Access-Control-Allow-External' header in the preflight "
- "response for this external request had a value of '%s', not 'true' "
- "(This is an experimental header which is defined in "
- "'https://wicg.github.io/cors-rfc1918/').",
- hint.Utf8().data());
+ Append(builder,
+ {"The 'Access-Control-Allow-External' header in the preflight "
+ "response for this external request had a value of '",
+ hint,
+ "', not 'true' (This is an experimental header which is defined "
+ "in 'https://wicg.github.io/cors-rfc1918/')."});
+ break;
case CORSError::kInvalidAllowMethodsPreflightResponse:
- return String(
+ builder.Append(
"Cannot parse Access-Control-Allow-Methods response header field in "
"preflight response.");
+ break;
case CORSError::kInvalidAllowHeadersPreflightResponse:
- return String(
+ builder.Append(
"Cannot parse Access-Control-Allow-Headers response header field in "
"preflight response.");
+ break;
case CORSError::kMethodDisallowedByPreflightResponse:
- return String::Format(
- "Method %s is not allowed by Access-Control-Allow-Methods in "
- "preflight response.",
- hint.Utf8().data());
+ Append(builder, {"Method ", hint,
+ " is not allowed by Access-Control-Allow-Methods in "
+ "preflight response."});
+ break;
case CORSError::kHeaderDisallowedByPreflightResponse:
- return String::Format(
- "Request header field %s is not allowed by "
- "Access-Control-Allow-Headers in preflight response.",
- hint.Utf8().data());
- case CORSError::kRedirectDisallowedScheme:
- return String::Format(
- "%sRedirect location '%s' has a disallowed scheme for cross-origin "
- "requests.",
- redirect_denied.Utf8().data(),
- param.second_url.GetString().Utf8().data());
+ Append(builder, {"Request header field ", hint,
+ " is not allowed by "
+ "Access-Control-Allow-Headers in preflight response."});
+ break;
case CORSError::kRedirectContainsCredentials:
- return String::Format(
- "%sRedirect location '%s' contains a username and password, which is "
- "disallowed for cross-origin requests.",
- redirect_denied.Utf8().data(),
- param.second_url.GetString().Utf8().data());
+ Append(builder, {"Redirect location '", hint,
+ "' contains a username and password, which is "
+ "disallowed for cross-origin requests."});
+ break;
}
- NOTREACHED();
- return String();
+ return builder.ToString();
}
} // namespace CORS
diff --git a/chromium/third_party/blink/renderer/platform/loader/cors/cors_error_string.h b/chromium/third_party/blink/renderer/platform/loader/cors/cors_error_string.h
index 6f6396beca2..5a0198041cb 100644
--- a/chromium/third_party/blink/renderer/platform/loader/cors/cors_error_string.h
+++ b/chromium/third_party/blink/renderer/platform/loader/cors/cors_error_string.h
@@ -9,100 +9,26 @@
#include "services/network/public/cpp/cors/cors_error_status.h"
#include "services/network/public/mojom/cors.mojom-shared.h"
#include "third_party/blink/public/platform/web_url_request.h"
+#include "third_party/blink/renderer/platform/loader/fetch/resource.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/wtf/forward.h"
namespace blink {
+class KURL;
class SecurityOrigin;
// CORS error strings related utility functions.
namespace CORS {
-// A struct to pass error dependent arguments for |GetErrorString|.
-struct PLATFORM_EXPORT ErrorParameter {
- // Creates an ErrorParameter for generic cases. Use this function if |error|
- // can contain any.
- static ErrorParameter Create(const network::CORSErrorStatus&,
- const KURL& first_url,
- const KURL& second_url,
- const int status_code,
- const SecurityOrigin&,
- const WebURLRequest::RequestContext);
-
- // Creates an ErrorParameter for kDisallowedByMode.
- static ErrorParameter CreateForDisallowedByMode(const KURL& request_url);
-
- // Creates an ErrorParameter for kInvalidResponse.
- static ErrorParameter CreateForInvalidResponse(const KURL& request_url,
- const SecurityOrigin&);
-
- // Creates an ErrorParameter for an error that CORS::CheckAccess() returns.
- // |error| for redirect check needs to specify a valid |redirect_url|. The
- // |redirect_url| can be omitted not to include redirect related information.
- static ErrorParameter CreateForAccessCheck(
- const network::CORSErrorStatus&,
- const KURL& request_url,
- int response_status_code,
- const SecurityOrigin&,
- const WebURLRequest::RequestContext,
- const KURL& redirect_url = KURL());
-
- // Creates an ErrorParameter for kPreflightInvalidStatus that
- // CORS::CheckPreflight() returns.
- static ErrorParameter CreateForPreflightStatusCheck(int response_status_code);
-
- // Creates an ErrorParameter for kPreflightDisallowedRedirect.
- static ErrorParameter CreateForDisallowedRedirect();
-
- // Creates an ErrorParameter for an error that CORS::CheckExternalPreflight()
- // returns.
- static ErrorParameter CreateForExternalPreflightCheck(
- const network::CORSErrorStatus&);
-
- // Creates an ErrorParameter for an error that is related to CORS-preflight
- // response checks.
- // |hint| should contain a banned request method for
- // kMethodDisallowedByPreflightResponse, a banned request header name for
- // kHeaderDisallowedByPreflightResponse, or can be omitted for others.
- static ErrorParameter CreateForPreflightResponseCheck(
- const network::mojom::CORSError,
- const String& hint);
-
- // Creates an ErrorParameter for CORS::CheckRedirectLocation() returns.
- static ErrorParameter CreateForRedirectCheck(network::mojom::CORSError,
- const KURL& request_url,
- const KURL& redirect_url);
-
- // Should not be used directly by external callers. Use Create functions
- // above.
- ErrorParameter(const network::mojom::CORSError,
- const KURL& first_url,
- const KURL& second_url,
- const int status_code,
- const SecurityOrigin&,
- const WebURLRequest::RequestContext,
- const String& hint,
- bool unknown);
-
- // Members that this struct carries.
- const network::mojom::CORSError error;
- const KURL& first_url;
- const KURL& second_url;
- const int status_code;
- const SecurityOrigin& origin;
- const WebURLRequest::RequestContext context;
- // Do not use a reference here. See https://crbug.com/851419.
- const String hint;
-
- // Set to true when an ErrorParameter was created in a wrong way. Used in
- // GetErrorString() to be robust for coding errors.
- const bool unknown;
-};
-
// Stringify CORSError mainly for inspector messages. Generated string should
// not be exposed to JavaScript for security reasons.
-PLATFORM_EXPORT String GetErrorString(const ErrorParameter&);
+PLATFORM_EXPORT String GetErrorString(const network::CORSErrorStatus& status,
+ const KURL& initial_request_url,
+ const KURL& last_request_url,
+ const SecurityOrigin& origin,
+ Resource::Type resource_type,
+ const AtomicString& initiator_name);
} // namespace CORS
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 961f89d9ffc..20ef7e619fe 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
@@ -30,8 +30,7 @@ void ParseAcceptChHeader(const String& header_value,
enabled_hints.SetIsEnabled(
mojom::WebClientHintsType::kDeviceMemory,
- enabled_hints.IsEnabled(mojom::WebClientHintsType::kDeviceMemory) &&
- RuntimeEnabledFeatures::DeviceMemoryHeaderEnabled());
+ enabled_hints.IsEnabled(mojom::WebClientHintsType::kDeviceMemory));
enabled_hints.SetIsEnabled(
mojom::WebClientHintsType::kRtt,
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_context.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_context.cc
index 2eb30104d4c..113dfdb2e92 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_context.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_context.cc
@@ -112,6 +112,8 @@ void FetchContext::AddResourceTiming(const ResourceTimingInfo&) {}
void FetchContext::AddInfoConsoleMessage(const String&, LogSource) const {}
+void FetchContext::AddWarningConsoleMessage(const String&, LogSource) const {}
+
void FetchContext::AddErrorConsoleMessage(const String&, LogSource) const {}
void FetchContext::PopulateResourceRequest(
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 1b713826046..03e2e859dc5 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
@@ -37,6 +37,7 @@
#include "base/single_thread_task_runner.h"
#include "services/network/public/mojom/request_context_frame_type.mojom-shared.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom-blink.h"
+#include "third_party/blink/public/platform/code_cache_loader.h"
#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom-shared.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/resource_request_blocked_reason.h"
@@ -184,7 +185,6 @@ class PLATFORM_EXPORT FetchContext
const KURL&,
const ResourceLoaderOptions&,
SecurityViolationReportingPolicy,
- FetchParameters::OriginRestriction,
ResourceRequest::RedirectStatus) const {
return ResourceRequestBlockedReason::kOther;
}
@@ -214,6 +214,7 @@ class PLATFORM_EXPORT FetchContext
}
virtual void AddInfoConsoleMessage(const String&, LogSource) const;
+ virtual void AddWarningConsoleMessage(const String&, LogSource) const;
virtual void AddErrorConsoleMessage(const String&, LogSource) const;
virtual const SecurityOrigin* GetSecurityOrigin() const { return nullptr; }
@@ -239,6 +240,11 @@ class PLATFORM_EXPORT FetchContext
return nullptr;
}
+ // Create a default code cache loader to fetch data from code caches.
+ virtual std::unique_ptr<CodeCacheLoader> CreateCodeCacheLoader() {
+ return Platform::Current()->CreateCodeCacheLoader();
+ }
+
// Returns the initial throttling policy used by the associated
// ResourceLoadScheduler.
virtual ResourceLoadScheduler::ThrottlingPolicy InitialLoadThrottlingPolicy()
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_initiator_info.h b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_initiator_info.h
index 8d471afcb18..2230bccf4ec 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_initiator_info.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_initiator_info.h
@@ -32,6 +32,7 @@
namespace blink {
+// This class is thread-bound. Do not copy/pass an instance across threads.
struct FetchInitiatorInfo {
DISALLOW_NEW();
FetchInitiatorInfo()
@@ -40,8 +41,6 @@ struct FetchInitiatorInfo {
start_time(0.0),
is_link_preload(false) {}
- // ATTENTION: When adding members, update CrossThreadFetchInitiatorInfoData,
- // too.
AtomicString name;
TextPosition position;
double start_time;
@@ -49,34 +48,6 @@ struct FetchInitiatorInfo {
String imported_module_referrer;
};
-// Encode AtomicString as String to cross threads.
-struct CrossThreadFetchInitiatorInfoData {
- DISALLOW_NEW();
- explicit CrossThreadFetchInitiatorInfoData(const FetchInitiatorInfo& info)
- : name(info.name.GetString().IsolatedCopy()),
- position(info.position),
- start_time(info.start_time),
- is_link_preload(info.is_link_preload),
- imported_module_referrer(info.imported_module_referrer.IsolatedCopy()) {
- }
-
- operator FetchInitiatorInfo() const {
- FetchInitiatorInfo info;
- info.name = AtomicString(name);
- info.position = position;
- info.start_time = start_time;
- info.is_link_preload = is_link_preload;
- info.imported_module_referrer = imported_module_referrer;
- return info;
- }
-
- String name;
- TextPosition position;
- double start_time;
- bool is_link_preload;
- String imported_module_referrer;
-};
-
} // namespace blink
#endif
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 970713f10d2..b4401a6dc3e 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
@@ -38,20 +38,7 @@ FetchParameters::FetchParameters(const ResourceRequest& resource_request)
decoder_options_(TextResourceDecoderOptions::kPlainTextContent),
speculative_preload_type_(SpeculativePreloadType::kNotSpeculative),
defer_(kNoDefer),
- origin_restriction_(kUseDefaultOriginRestrictionForType),
- placeholder_image_request_type_(kDisallowPlaceholder) {}
-
-FetchParameters::FetchParameters(
- std::unique_ptr<CrossThreadFetchParametersData> data)
- : resource_request_(data->resource_request.get()),
- decoder_options_(data->decoder_options),
- options_(data->options),
- speculative_preload_type_(data->speculative_preload_type),
- defer_(data->defer),
- origin_restriction_(data->origin_restriction),
- resource_width_(data->resource_width),
- client_hint_preferences_(data->client_hint_preferences),
- placeholder_image_request_type_(data->placeholder_image_request_type) {}
+ image_request_optimization_(kNone) {}
FetchParameters::FetchParameters(const ResourceRequest& resource_request,
const ResourceLoaderOptions& options)
@@ -60,8 +47,7 @@ FetchParameters::FetchParameters(const ResourceRequest& resource_request,
options_(options),
speculative_preload_type_(SpeculativePreloadType::kNotSpeculative),
defer_(kNoDefer),
- origin_restriction_(kUseDefaultOriginRestrictionForType),
- placeholder_image_request_type_(kDisallowPlaceholder) {}
+ image_request_optimization_(kNone) {}
FetchParameters::~FetchParameters() = default;
@@ -125,8 +111,14 @@ void FetchParameters::MakeSynchronous() {
options_.synchronous_policy = kRequestSynchronously;
}
+void FetchParameters::SetClientLoFiPlaceholder() {
+ resource_request_.SetPreviewsState(resource_request_.GetPreviewsState() |
+ WebURLRequest::kClientLoFiOn);
+ SetAllowImagePlaceholder();
+}
+
void FetchParameters::SetAllowImagePlaceholder() {
- DCHECK_EQ(kDisallowPlaceholder, placeholder_image_request_type_);
+ DCHECK_EQ(kNone, image_request_optimization_);
if (!resource_request_.Url().ProtocolIsInHTTPFamily() ||
resource_request_.HttpMethod() != "GET" ||
!resource_request_.HttpHeaderField("range").IsNull()) {
@@ -137,7 +129,7 @@ void FetchParameters::SetAllowImagePlaceholder() {
return;
}
- placeholder_image_request_type_ = kAllowPlaceholder;
+ image_request_optimization_ = kAllowPlaceholder;
// Fetch the first few bytes of the image. This number is tuned to both (a)
// likely capture the entire image for small images and (b) likely contain
@@ -150,19 +142,4 @@ void FetchParameters::SetAllowImagePlaceholder() {
// fresh in the cache.
}
-std::unique_ptr<CrossThreadFetchParametersData> FetchParameters::CopyData()
- const {
- auto data = std::make_unique<CrossThreadFetchParametersData>();
- data->resource_request = resource_request_.CopyData();
- data->decoder_options = decoder_options_;
- data->options = CrossThreadResourceLoaderOptionsData(options_);
- data->speculative_preload_type = speculative_preload_type_;
- data->defer = defer_;
- data->origin_restriction = origin_restriction_;
- data->resource_width = resource_width_;
- data->client_hint_preferences = client_hint_preferences_;
- data->placeholder_image_request_type = placeholder_image_request_type_;
- return data;
-}
-
} // namespace blink
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 5e41c9089be..6d520e60632 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
@@ -41,16 +41,12 @@
namespace blink {
class SecurityOrigin;
-struct CrossThreadFetchParametersData;
// A FetchParameters is a "parameter object" for
// ResourceFetcher::requestResource to avoid the method having too many
// arguments.
//
-// There are cases where we need to copy a FetchParameters across threads, and
-// CrossThreadFetchParametersData is a struct for the purpose. When you add a
-// member variable to this class, do not forget to add the corresponding
-// one in CrossThreadFetchParametersData and write copying logic.
+// This class is thread-bound. Do not copy/pass an instance across threads.
class PLATFORM_EXPORT FetchParameters {
DISALLOW_NEW();
@@ -61,14 +57,12 @@ class PLATFORM_EXPORT FetchParameters {
kInDocument, // The request was discovered in the main document
kInserted // The request was discovered in a document.write()
};
- enum OriginRestriction {
- kUseDefaultOriginRestrictionForType,
- kRestrictToSameOrigin,
- kNoOriginRestriction
- };
- enum PlaceholderImageRequestType {
- kDisallowPlaceholder = 0, // The requested image must not be a placeholder.
- kAllowPlaceholder, // The image is allowed to be a placeholder.
+ enum ImageRequestOptimization {
+ kNone = 0, // No optimization.
+ kAllowPlaceholder, // The image is allowed to be a placeholder.
+ kDeferImageLoad, // Defer loading the image from network. Full image might
+ // still load if the request is already-loaded or in
+ // memory cache.
};
struct ResourceWidth {
DISALLOW_NEW();
@@ -79,7 +73,6 @@ class PLATFORM_EXPORT FetchParameters {
};
explicit FetchParameters(const ResourceRequest&);
- explicit FetchParameters(std::unique_ptr<CrossThreadFetchParametersData>);
FetchParameters(const ResourceRequest&, const ResourceLoaderOptions&);
~FetchParameters();
@@ -156,10 +149,6 @@ class PLATFORM_EXPORT FetchParameters {
// credentials mode.
void SetCrossOriginAccessControl(const SecurityOrigin*,
network::mojom::FetchCredentialsMode);
- OriginRestriction GetOriginRestriction() const { return origin_restriction_; }
- void SetOriginRestriction(OriginRestriction restriction) {
- origin_restriction_ = restriction;
- }
const IntegrityMetadataSet IntegrityMetadata() const {
return options_.integrity_metadata;
}
@@ -185,18 +174,19 @@ class PLATFORM_EXPORT FetchParameters {
void MakeSynchronous();
- PlaceholderImageRequestType GetPlaceholderImageRequestType() const {
- return placeholder_image_request_type_;
+ ImageRequestOptimization GetImageRequestOptimization() const {
+ return image_request_optimization_;
}
// Configures the request to load an image placeholder if the request is
// eligible (e.g. the url's protocol is HTTP, etc.). If this request is
// non-eligible, this method doesn't modify the ResourceRequest. Calling this
- // method sets m_placeholderImageRequestType to the appropriate value.
+ // method sets image_request_optimization_ to the appropriate value.
void SetAllowImagePlaceholder();
- // Gets a copy of the data suitable for passing to another thread.
- std::unique_ptr<CrossThreadFetchParametersData> CopyData() const;
+ // Configures the request to load an image as a placeholder and sets the
+ // Client LoFi preview bit.
+ void SetClientLoFiPlaceholder();
private:
ResourceRequest resource_request_;
@@ -207,51 +197,12 @@ class PLATFORM_EXPORT FetchParameters {
ResourceLoaderOptions options_;
SpeculativePreloadType speculative_preload_type_;
DeferOption defer_;
- OriginRestriction origin_restriction_;
ResourceWidth resource_width_;
ClientHintsPreferences client_hint_preferences_;
- PlaceholderImageRequestType placeholder_image_request_type_;
+ ImageRequestOptimization image_request_optimization_;
bool is_stale_revalidation_ = false;
};
-// This class is needed to copy a FetchParameters across threads, because it
-// has some members which cannot be transferred across threads (AtomicString
-// for example).
-// There are some rules / restrictions:
-// - This struct cannot contain an object that cannot be transferred across
-// threads (e.g., AtomicString)
-// - Non-simple members need explicit copying (e.g., String::IsolatedCopy,
-// KURL::Copy) rather than the copy constructor or the assignment operator.
-struct CrossThreadFetchParametersData {
- WTF_MAKE_NONCOPYABLE(CrossThreadFetchParametersData);
- USING_FAST_MALLOC(CrossThreadFetchParametersData);
-
- public:
- CrossThreadFetchParametersData()
- : decoder_options(TextResourceDecoderOptions::kPlainTextContent),
- options(ResourceLoaderOptions()) {}
-
- std::unique_ptr<CrossThreadResourceRequestData> resource_request;
- TextResourceDecoderOptions decoder_options;
- CrossThreadResourceLoaderOptionsData options;
- FetchParameters::SpeculativePreloadType speculative_preload_type;
- FetchParameters::DeferOption defer;
- FetchParameters::OriginRestriction origin_restriction;
- FetchParameters::ResourceWidth resource_width;
- ClientHintsPreferences client_hint_preferences;
- FetchParameters::PlaceholderImageRequestType placeholder_image_request_type;
-};
-
-template <>
-struct CrossThreadCopier<FetchParameters> {
- STATIC_ONLY(CrossThreadCopier);
- using Type =
- WTF::PassedWrapper<std::unique_ptr<CrossThreadFetchParametersData>>;
- static Type Copy(const FetchParameters& fetch_params) {
- return WTF::Passed(fetch_params.CopyData());
- }
-};
-
} // namespace blink
#endif
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/https_state.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/https_state.cc
new file mode 100644
index 00000000000..98b50a6d6cd
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/https_state.cc
@@ -0,0 +1,22 @@
+// 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/loader/fetch/https_state.h"
+
+#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
+
+namespace blink {
+
+HttpsState CalculateHttpsState(const SecurityOrigin* security_origin,
+ base::Optional<HttpsState> parent_https_state) {
+ if (security_origin && security_origin->Protocol() == "https")
+ return HttpsState::kModern;
+
+ if (parent_https_state && *parent_https_state != HttpsState::kNone)
+ return *parent_https_state;
+
+ return HttpsState::kNone;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/https_state.h b/chromium/third_party/blink/renderer/platform/loader/fetch/https_state.h
new file mode 100644
index 00000000000..77023b88d9e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/https_state.h
@@ -0,0 +1,35 @@
+// 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_LOADER_FETCH_HTTPS_STATE_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_HTTPS_STATE_H_
+
+#include "base/optional.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+
+namespace blink {
+
+class SecurityOrigin;
+
+// https://fetch.spec.whatwg.org/#concept-https-state-value
+enum class HttpsState {
+ kNone,
+ // kDeprecated is not used.
+ kModern
+};
+
+// According to the Fetch spec, HTTPS state is set during fetch, e.g. to
+// modern for https: or to request's client's HTTPS state for data:.
+// In the Blink implementation however, HTTPS state is calculated from
+// response URL's SecurityOrigin and optional |parent_https_state| (that
+// represents request's client's HTTPS state) to emulate this behavior.
+// TODO(https://crbug.com/880986): Implement HTTPS state in more
+// spec-conformant way.
+PLATFORM_EXPORT HttpsState CalculateHttpsState(
+ const SecurityOrigin*,
+ base::Optional<HttpsState> parent_https_state = base::nullopt);
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_HTTPS_STATE_H_
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 950ae3f9c3f..a31faed32b8 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
@@ -85,6 +85,8 @@ class PLATFORM_EXPORT MemoryCache final
struct TypeStatistic {
STACK_ALLOCATED();
+
+ public:
size_t count;
size_t size;
size_t decoded_size;
@@ -105,6 +107,8 @@ class PLATFORM_EXPORT MemoryCache final
struct Statistics {
STACK_ALLOCATED();
+
+ public:
TypeStatistic images;
TypeStatistic css_style_sheets;
TypeStatistic scripts;
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 22802033079..0993d4482f7 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
@@ -34,6 +34,7 @@
#include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_client_walker.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
+#include "third_party/blink/renderer/platform/loader/fetch/script_cached_metadata_handler.h"
#include "third_party/blink/renderer/platform/loader/fetch/source_keyed_cached_metadata_handler.h"
#include "third_party/blink/renderer/platform/network/http_names.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
@@ -194,18 +195,24 @@ void RawResource::WillNotFollowRedirect() {
c->RedirectBlocked();
}
-SourceKeyedCachedMetadataHandler* RawResource::CacheHandler() {
+SourceKeyedCachedMetadataHandler* RawResource::InlineScriptCacheHandler() {
+ DCHECK_EQ(kMainResource, GetType());
return static_cast<SourceKeyedCachedMetadataHandler*>(
Resource::CacheHandler());
}
+SingleCachedMetadataHandler* RawResource::ScriptCacheHandler() {
+ DCHECK_EQ(kRaw, GetType());
+ return static_cast<SingleCachedMetadataHandler*>(Resource::CacheHandler());
+}
+
void RawResource::ResponseReceived(
const ResourceResponse& response,
std::unique_ptr<WebDataConsumerHandle> handle) {
if (response.WasFallbackRequiredByServiceWorker()) {
// The ServiceWorker asked us to re-fetch the request. This resource must
// not be reused.
- // Note: This logic is needed here because DocumentThreadableLoader handles
+ // Note: This logic is needed here because ThreadableLoader handles
// CORS independently from ResourceLoader. Fix it.
if (IsMainThread())
GetMemoryCache()->Remove(this);
@@ -227,16 +234,29 @@ void RawResource::ResponseReceived(
CachedMetadataHandler* RawResource::CreateCachedMetadataHandler(
std::unique_ptr<CachedMetadataSender> send_callback) {
- return new SourceKeyedCachedMetadataHandler(Encoding(),
- std::move(send_callback));
+ if (GetType() == kMainResource) {
+ // This is a document resource; create a cache handler that can handle
+ // multiple inline scripts.
+ return new SourceKeyedCachedMetadataHandler(Encoding(),
+ std::move(send_callback));
+ } else if (GetType() == kRaw) {
+ // This is a resource of indeterminate type, e.g. a fetched WebAssembly
+ // module; create a cache handler that can store a single metadata entry.
+ return new ScriptCachedMetadataHandler(Encoding(),
+ std::move(send_callback));
+ }
+ return Resource::CreateCachedMetadataHandler(std::move(send_callback));
}
void RawResource::SetSerializedCachedMetadata(const char* data, size_t size) {
Resource::SetSerializedCachedMetadata(data, size);
- SourceKeyedCachedMetadataHandler* cache_handler = CacheHandler();
- if (cache_handler) {
- cache_handler->SetSerializedCachedMetadata(data, size);
+ if (GetType() == kMainResource) {
+ SourceKeyedCachedMetadataHandler* cache_handler =
+ InlineScriptCacheHandler();
+ if (cache_handler) {
+ cache_handler->SetSerializedCachedMetadata(data, size);
+ }
}
ResourceClientWalker<RawResourceClient> w(Clients());
@@ -339,34 +359,11 @@ static bool ShouldIgnoreHeaderForCacheReuse(AtomicString header_name) {
return headers.Contains(header_name);
}
-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 != HTTPNames::POST && method != HTTPNames::PUT &&
- method != "DELETE";
-}
-
-bool RawResource::CanReuse(
+Resource::MatchStatus RawResource::CanReuse(
const FetchParameters& new_fetch_parameters,
scoped_refptr<const SecurityOrigin> new_source_origin) const {
const ResourceRequest& new_request =
new_fetch_parameters.GetResourceRequest();
-
- if (GetDataBufferingPolicy() == kDoNotBufferData)
- return false;
-
- if (!IsCacheableHTTPMethod(GetResourceRequest().HttpMethod()))
- return false;
- if (GetResourceRequest().HttpMethod() != new_request.HttpMethod())
- return false;
-
- if (GetResourceRequest().HttpBody() != new_request.HttpBody())
- return false;
-
- if (GetResourceRequest().AllowStoredCredentials() !=
- new_request.AllowStoredCredentials())
- return false;
-
// Ensure most headers match the existing headers before continuing. Note that
// the list of ignored headers includes some headers explicitly related to
// caching. A more detailed check of caching policy will be performed later,
@@ -378,15 +375,17 @@ bool RawResource::CanReuse(
for (const auto& header : new_headers) {
AtomicString header_name = header.key;
if (!ShouldIgnoreHeaderForCacheReuse(header_name) &&
- header.value != old_headers.Get(header_name))
- return false;
+ header.value != old_headers.Get(header_name)) {
+ return MatchStatus::kRequestHeadersDoNotMatch;
+ }
}
for (const auto& header : old_headers) {
AtomicString header_name = header.key;
if (!ShouldIgnoreHeaderForCacheReuse(header_name) &&
- header.value != new_headers.Get(header_name))
- return false;
+ header.value != new_headers.Get(header_name)) {
+ return MatchStatus::kRequestHeadersDoNotMatch;
+ }
}
return Resource::CanReuse(new_fetch_parameters, std::move(new_source_origin));
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 950e634af33..8a66653a8c9 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
@@ -80,7 +80,7 @@ class PLATFORM_EXPORT RawResource final : public Resource {
}
// Resource implementation
- bool CanReuse(
+ MatchStatus CanReuse(
const FetchParameters&,
scoped_refptr<const SecurityOrigin> new_source_origin) const override;
bool WillFollowRedirect(const ResourceRequest&,
@@ -90,8 +90,14 @@ class PLATFORM_EXPORT RawResource final : public Resource {
// Used for code caching of scripts with source code inline in the HTML.
// Returns a cache handler which can store multiple cache metadata entries,
- // keyed by the source code of the script.
- SourceKeyedCachedMetadataHandler* CacheHandler();
+ // keyed by the source code of the script. This is valid only if type is
+ // kMainResource.
+ SourceKeyedCachedMetadataHandler* InlineScriptCacheHandler();
+
+ // Used for code caching of fetched code resources. Returns a cache handler
+ // which can only store a single cache metadata entry. This is valid only if
+ // type is kRaw.
+ SingleCachedMetadataHandler* ScriptCacheHandler();
scoped_refptr<BlobDataHandle> DownloadedBlob() const {
return downloaded_blob_;
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 44799f2a130..7bc8293038c 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
@@ -74,9 +74,9 @@ TEST_F(RawResourceTest, DontIgnoreAcceptForCacheReuse) {
ResourceRequest png_request;
png_request.SetHTTPAccept("image/png");
-
- EXPECT_FALSE(
- jpeg_resource->CanReuse(FetchParameters(png_request), source_origin));
+ EXPECT_NE(
+ jpeg_resource->CanReuse(FetchParameters(png_request), source_origin),
+ Resource::MatchStatus::kOk);
}
class DummyClient final : public GarbageCollectedFinalized<DummyClient>,
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 97a1597f54d..28f0d0e7599 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource.cc
@@ -403,16 +403,6 @@ AtomicString Resource::HttpContentType() const {
return GetResponse().HttpContentType();
}
-bool Resource::PassesAccessControlCheck(
- const SecurityOrigin& security_origin) const {
- base::Optional<network::CORSErrorStatus> cors_status = CORS::CheckAccess(
- GetResponse().Url(), GetResponse().HttpStatusCode(),
- GetResponse().HttpHeaderFields(),
- LastResourceRequest().GetFetchCredentialsMode(), security_origin);
-
- return !cors_status;
-}
-
bool Resource::MustRefetchDueToIntegrityMetadata(
const FetchParameters& params) const {
if (params.IntegrityMetadata().IsEmpty())
@@ -774,21 +764,21 @@ void Resource::FinishPendingClients() {
DCHECK(clients_awaiting_callback_.IsEmpty() || scheduled);
}
-bool Resource::CanReuse(
+Resource::MatchStatus Resource::CanReuse(
const FetchParameters& params,
scoped_refptr<const SecurityOrigin> new_source_origin) const {
const ResourceRequest& new_request = params.GetResourceRequest();
const ResourceLoaderOptions& new_options = params.Options();
+ DCHECK_EQ(GetDataBufferingPolicy(), kBufferData);
// Never reuse opaque responses from a service worker for requests that are
// not no-cors. https://crbug.com/625575
// TODO(yhirano): Remove this.
if (GetResponse().WasFetchedViaServiceWorker() &&
- GetResponse().ResponseTypeViaServiceWorker() ==
- network::mojom::FetchResponseType::kOpaque &&
+ GetResponse().GetType() == network::mojom::FetchResponseType::kOpaque &&
new_request.GetFetchRequestMode() !=
network::mojom::FetchRequestMode::kNoCORS) {
- return false;
+ return MatchStatus::kUnknownFailure;
}
// If credentials were sent with the previous request and won't be with this
@@ -798,8 +788,9 @@ bool Resource::CanReuse(
// "Access-Control-Allow-Origin: *" all the time, but some of the client's
// requests are made without CORS and some with.
if (GetResourceRequest().AllowStoredCredentials() !=
- new_request.AllowStoredCredentials())
- return false;
+ new_request.AllowStoredCredentials()) {
+ return MatchStatus::kRequestCredentialsModeDoesNotMatch;
+ }
// Certain requests (e.g., XHRs) might have manually set headers that require
// revalidation. In theory, this should be a Revalidate case. In practice, the
@@ -812,8 +803,9 @@ bool Resource::CanReuse(
// status code, but for a manual revalidation the response code remains 304.
// In this case, the Resource likely has insufficient context to provide a
// useful cache hit or revalidation. See http://crbug.com/643659
- if (new_request.IsConditional() || response_.HttpStatusCode() == 304)
- return false;
+ if (new_request.IsConditional() || response_.HttpStatusCode() == 304) {
+ return MatchStatus::kUnknownFailure;
+ }
// Answers the question "can a separate request with different options be
// re-used" (e.g. preload request). The safe (but possibly slow) answer is
@@ -838,32 +830,39 @@ bool Resource::CanReuse(
// (crbug.com/618967) and bypassing redirect restriction around revalidation
// (crbug.com/613971 for 2. and crbug.com/614989 for 3.).
if (new_options.synchronous_policy == kRequestSynchronously ||
- options_.synchronous_policy == kRequestSynchronously)
- return false;
-
- if (resource_request_.GetKeepalive() || new_request.GetKeepalive()) {
- return false;
+ options_.synchronous_policy == kRequestSynchronously) {
+ return MatchStatus::kSynchronousFlagDoesNotMatch;
}
+ if (resource_request_.GetKeepalive() || new_request.GetKeepalive())
+ return MatchStatus::kKeepaliveSet;
+
+ if (GetResourceRequest().HttpMethod() != new_request.HttpMethod())
+ return MatchStatus::kRequestMethodDoesNotMatch;
+
+ if (GetResourceRequest().HttpBody() != new_request.HttpBody())
+ return MatchStatus::kUnknownFailure;
+
DCHECK(source_origin_);
DCHECK(new_source_origin);
// Don't reuse an existing resource when the source origin is different.
if (!source_origin_->IsSameSchemeHostPort(new_source_origin.get()))
- return false;
+ return MatchStatus::kUnknownFailure;
// securityOrigin has more complicated checks which callers are responsible
// for.
if (new_request.GetFetchCredentialsMode() !=
- resource_request_.GetFetchCredentialsMode())
- return false;
+ resource_request_.GetFetchCredentialsMode()) {
+ return MatchStatus::kRequestCredentialsModeDoesNotMatch;
+ }
const auto new_mode = new_request.GetFetchRequestMode();
const auto existing_mode = resource_request_.GetFetchRequestMode();
if (new_mode != existing_mode)
- return false;
+ return MatchStatus::kRequestModeDoesNotMatch;
switch (new_mode) {
case network::mojom::FetchRequestMode::kNoCORS:
@@ -873,25 +872,25 @@ bool Resource::CanReuse(
case network::mojom::FetchRequestMode::kCORS:
case network::mojom::FetchRequestMode::kSameOrigin:
case network::mojom::FetchRequestMode::kCORSWithForcedPreflight:
- // We have two separate CORS handling logics in DocumentThreadableLoader
+ // We have two separate CORS handling logics in ThreadableLoader
// and ResourceLoader and sharing resources is difficult when they are
// handled differently.
if (options_.cors_handling_by_resource_fetcher !=
new_options.cors_handling_by_resource_fetcher) {
- // If the existing one is handled in DocumentThreadableLoader and the
+ // If the existing one is handled in ThreadableLoader and the
// new one is handled in ResourceLoader, reusing the existing one will
// lead to CORS violations.
if (!options_.cors_handling_by_resource_fetcher)
- return false;
+ return MatchStatus::kUnknownFailure;
// Otherwise (i.e., if the existing one is handled in ResourceLoader
- // and the new one is handled in DocumentThreadableLoader), reusing
+ // and the new one is handled in ThreadableLoader), reusing
// the existing one will lead to double check which is harmless.
}
break;
}
- return true;
+ return MatchStatus::kOk;
}
void Resource::Prune() {
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 eb30e6a033a..048989909ca 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource.h
@@ -88,6 +88,53 @@ class PLATFORM_EXPORT Resource : public GarbageCollectedFinalized<Resource>,
WTF_MAKE_NONCOPYABLE(Resource);
public:
+ // An enum representing whether a resource match with another resource.
+ // There are three kinds of status.
+ // - kOk, which represents the success.
+ // - kUnknownFailure, which represents miscellaneous failures. This includes
+ // failures which cannot happen for preload matching (for example,
+ // a failure due to non-cacheable request method cannot be happen for
+ // preload matching).
+ // - other specific error status
+ enum class MatchStatus {
+ // Match succeeds.
+ kOk,
+
+ // Match fails because of an unknown reason.
+ kUnknownFailure,
+
+ // Subresource integrity value doesn't match.
+ kIntegrityMismatch,
+
+ // Match fails because the new request wants to load the content
+ // as a blob.
+ kBlobRequest,
+
+ // Match fails because loading image is disabled.
+ kImageLoadingDisabled,
+
+ // Match fails due to different synchronous flags.
+ kSynchronousFlagDoesNotMatch,
+
+ // Match fails due to different request modes.
+ kRequestModeDoesNotMatch,
+
+ // Match fails due to different request credentials modes.
+ kRequestCredentialsModeDoesNotMatch,
+
+ // Match fails because keepalive flag is set on either requests.
+ kKeepaliveSet,
+
+ // Match fails due to different request methods.
+ kRequestMethodDoesNotMatch,
+
+ // Match fails due to different request headers.
+ kRequestHeadersDoNotMatch,
+
+ // Match fails due to different image placeholder policies.
+ kImagePlaceholder,
+ };
+
// |Type| enum values are used in UMAs, so do not change the values of
// existing |Type|. When adding a new |Type|, append it at the end and update
// |kLastResourceType|.
@@ -215,8 +262,6 @@ class PLATFORM_EXPORT Resource : public GarbageCollectedFinalized<Resource>,
virtual void Finish(TimeTicks finish_time, base::SingleThreadTaskRunner*);
void FinishForTest() { Finish(TimeTicks(), nullptr); }
- bool PassesAccessControlCheck(const SecurityOrigin&) const;
-
virtual scoped_refptr<const SharedBuffer> ResourceBuffer() const {
return data_;
}
@@ -327,8 +372,9 @@ class PLATFORM_EXPORT Resource : public GarbageCollectedFinalized<Resource>,
response_.SetDecodedBodyLength(value);
}
- virtual bool CanReuse(
- const FetchParameters&,
+ // Returns |kOk| when |this| can be resused for the given arguments.
+ virtual MatchStatus CanReuse(
+ const FetchParameters& params,
scoped_refptr<const SecurityOrigin> new_source_origin) const;
// If cache-aware loading is activated, this callback is called when the first
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 788f95b599f..1670ba04db8 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
@@ -87,11 +87,16 @@ ResourceError::ResourceError(
base::Optional<network::CORSErrorStatus> cors_error_status)
: error_code_(error_code),
failing_url_(url),
+ is_access_check_(cors_error_status.has_value()),
cors_error_status_(cors_error_status) {
DCHECK_NE(error_code_, 0);
InitializeDescription();
}
+ResourceError::ResourceError(const KURL& url,
+ const network::CORSErrorStatus& cors_error_status)
+ : ResourceError(net::ERR_FAILED, url, cors_error_status) {}
+
ResourceError::ResourceError(const WebURLError& error)
: error_code_(error.reason()),
extended_error_code_(error.extended_reason()),
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 5aaaa0c37f5..7ffdfeae2d0 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
@@ -64,6 +64,8 @@ class PLATFORM_EXPORT ResourceError final {
ResourceError(int error_code,
const KURL& failing_url,
base::Optional<network::CORSErrorStatus>);
+ ResourceError(const KURL& failing_url,
+ const network::CORSErrorStatus& status);
ResourceError(const WebURLError&);
// Makes a deep copy. Useful for when you need to use a ResourceError on
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 dd3ff0fd819..08357dad5b1 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
@@ -41,6 +41,7 @@
#include "third_party/blink/renderer/platform/instance_counters.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/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/memory_cache.h"
@@ -59,11 +60,13 @@
#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/known_ports.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/cstring.h"
+#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/wtf.h"
@@ -154,6 +157,13 @@ ResourceLoadPriority TypeToPriority(Resource::Type 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 != HTTPNames::POST && method != HTTPNames::PUT &&
+ method != "DELETE";
+}
+
bool ShouldResourceBeAddedToMemoryCache(const FetchParameters& params,
Resource* resource) {
if (!IsMainThread())
@@ -162,6 +172,8 @@ bool ShouldResourceBeAddedToMemoryCache(const FetchParameters& params,
return false;
if (IsRawResource(*resource))
return false;
+ if (!IsCacheableHTTPMethod(params.GetResourceRequest().HttpMethod()))
+ return false;
return true;
}
@@ -408,9 +420,11 @@ bool ResourceFetcher::ResourceNeedsLoad(Resource* resource,
// - images are disabled
// - instructed to defer loading images from network
if (resource->GetType() == Resource::kImage &&
- ShouldDeferImageLoad(resource->Url()))
+ (ShouldDeferImageLoad(resource->Url()) ||
+ params.GetImageRequestOptimization() ==
+ FetchParameters::kDeferImageLoad)) {
return false;
-
+ }
return policy != kUse || resource->StillNeedsLoad();
}
@@ -654,7 +668,7 @@ base::Optional<ResourceRequestBlockedReason> ResourceFetcher::PrepareRequest(
: SecurityViolationReportingPolicy::kReport;
// Note that resource_request.GetRedirectStatus() may return kFollowedRedirect
- // here since e.g. DocumentThreadableLoader may create a new Resource from
+ // here since e.g. ThreadableLoader may create a new Resource from
// a ResourceRequest that originates from the ResourceRequest passed to
// the redirect handling callback.
@@ -713,7 +727,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, params.GetOriginRestriction(),
+ reporting_policy,
resource_request.GetRedirectStatus());
if (Context().IsAdResource(url, resource_type,
@@ -746,11 +760,23 @@ base::Optional<ResourceRequestBlockedReason> ResourceFetcher::PrepareRequest(
if (!params.Url().IsValid())
return ResourceRequestBlockedReason::kOther;
- params.MutableOptions().cors_flag =
- !origin || !origin->CanRequest(params.Url());
-
- if (options.cors_handling_by_resource_fetcher ==
- kEnableCORSHandlingByResourceFetcher) {
+ if (!RuntimeEnabledFeatures::OutOfBlinkCORSEnabled() &&
+ options.cors_handling_by_resource_fetcher ==
+ kEnableCORSHandlingByResourceFetcher) {
+ if (CORS::IsCORSEnabledRequestMode(
+ resource_request.GetFetchRequestMode())) {
+ DCHECK(origin);
+ if (!origin->CanRequest(params.Url())) {
+ params.MutableOptions().cors_flag = true;
+ // Cross-origin requests are only allowed certain registered schemes.
+ if (!SchemeRegistry::ShouldTreatURLSchemeAsCORSEnabled(
+ url.Protocol())) {
+ // This won't create a CORS related console error.
+ // TODO(yhirano): Fix this.
+ return ResourceRequestBlockedReason::kOther;
+ }
+ }
+ }
bool allow_stored_credentials = false;
switch (resource_request.GetFetchCredentialsMode()) {
case network::mojom::FetchCredentialsMode::kOmit:
@@ -1072,8 +1098,11 @@ Resource* ResourceFetcher::MatchPreload(const FetchParameters& params,
Resource* resource = it->value;
- if (resource->MustRefetchDueToIntegrityMetadata(params))
+ if (resource->MustRefetchDueToIntegrityMetadata(params)) {
+ if (!params.IsSpeculativePreload() && !params.IsLinkPreload())
+ PrintPreloadWarning(resource, Resource::MatchStatus::kIntegrityMismatch);
return nullptr;
+ }
if (params.IsSpeculativePreload())
return resource;
@@ -1083,20 +1112,87 @@ Resource* ResourceFetcher::MatchPreload(const FetchParameters& params,
}
const ResourceRequest& request = params.GetResourceRequest();
- if (request.DownloadToBlob())
+ if (request.DownloadToBlob()) {
+ PrintPreloadWarning(resource, Resource::MatchStatus::kBlobRequest);
return nullptr;
+ }
+
+ if (IsImageResourceDisallowedToBeReused(*resource)) {
+ PrintPreloadWarning(resource, Resource::MatchStatus::kImageLoadingDisabled);
+ return nullptr;
+ }
- if (IsImageResourceDisallowedToBeReused(*resource) ||
- !resource->CanReuse(params, GetSourceOrigin(params.Options())))
+ const Resource::MatchStatus match_status =
+ resource->CanReuse(params, GetSourceOrigin(params.Options()));
+ if (match_status != Resource::MatchStatus::kOk) {
+ PrintPreloadWarning(resource, match_status);
return nullptr;
+ }
- if (!resource->MatchPreload(params, Context().GetLoadingTaskRunner().get()))
+ if (!resource->MatchPreload(params, Context().GetLoadingTaskRunner().get())) {
+ PrintPreloadWarning(resource, Resource::MatchStatus::kUnknownFailure);
return nullptr;
+ }
+
preloads_.erase(it);
matched_preloads_.push_back(resource);
return resource;
}
+void ResourceFetcher::PrintPreloadWarning(Resource* resource,
+ Resource::MatchStatus status) {
+ if (!resource->IsLinkPreload())
+ return;
+
+ StringBuilder builder;
+ builder.Append("A preload for '");
+ builder.Append(resource->Url());
+ builder.Append("' is found, but is not used ");
+
+ switch (status) {
+ case Resource::MatchStatus::kOk:
+ NOTREACHED();
+ break;
+ case Resource::MatchStatus::kUnknownFailure:
+ builder.Append("due to an unknown reason.");
+ break;
+ case Resource::MatchStatus::kIntegrityMismatch:
+ builder.Append("due to an integrity mismatch.");
+ break;
+ case Resource::MatchStatus::kBlobRequest:
+ builder.Append("because the new request loads the content as a blob.");
+ break;
+ case Resource::MatchStatus::kImageLoadingDisabled:
+ builder.Append("because image loading is disabled.");
+ break;
+ case Resource::MatchStatus::kSynchronousFlagDoesNotMatch:
+ builder.Append("because the new request is synchronous.");
+ break;
+ case Resource::MatchStatus::kRequestModeDoesNotMatch:
+ builder.Append("because the request mode does not match. ");
+ builder.Append("Consider taking a look at crossorigin attribute.");
+ break;
+ case Resource::MatchStatus::kRequestCredentialsModeDoesNotMatch:
+ builder.Append("because the request credentials mode does not match. ");
+ builder.Append("Consider taking a look at crossorigin attribute.");
+ break;
+ case Resource::MatchStatus::kKeepaliveSet:
+ builder.Append("because the keepalive flag is set.");
+ break;
+ case Resource::MatchStatus::kRequestMethodDoesNotMatch:
+ builder.Append("because the request HTTP method does not match.");
+ break;
+ case Resource::MatchStatus::kRequestHeadersDoNotMatch:
+ builder.Append("because the request headers do not match.");
+ break;
+ case Resource::MatchStatus::kImagePlaceholder:
+ builder.Append("due to different image placeholder policies.");
+ break;
+ }
+ Context().AddWarningConsoleMessage(builder.ToString(),
+ FetchContext::kOtherSource);
+}
+
void ResourceFetcher::InsertAsPreloadIfNecessary(Resource* resource,
const FetchParameters& params,
Resource::Type type) {
@@ -1220,8 +1316,9 @@ ResourceFetcher::DetermineRevalidationPolicyInternal(
if (is_static_data)
return kUse;
- if (!existing_resource.CanReuse(fetch_params,
- GetSourceOrigin(fetch_params.Options()))) {
+ if (existing_resource.CanReuse(fetch_params,
+ GetSourceOrigin(fetch_params.Options())) !=
+ Resource::MatchStatus::kOk) {
RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::DetermineRevalidationPolicy "
"reloading due to Resource::CanReuse() "
"returning false.";
@@ -1760,7 +1857,6 @@ void ResourceFetcher::EmulateLoadStartedForInspector(
Context().CanRequest(resource->GetType(), resource->LastResourceRequest(),
resource->LastResourceRequest().Url(), params.Options(),
SecurityViolationReportingPolicy::kReport,
- params.GetOriginRestriction(),
resource->LastResourceRequest().GetRedirectStatus());
RequestLoadStarted(resource->Identifier(), resource, params, kUse);
}
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 e127d40507a..f90312f1ed3 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
@@ -228,6 +228,7 @@ class PLATFORM_EXPORT ResourceFetcher
ResourceClient*);
Resource* MatchPreload(const FetchParameters& params, Resource::Type);
+ void PrintPreloadWarning(Resource*, Resource::MatchStatus);
void InsertAsPreloadIfNecessary(Resource*,
const FetchParameters& params,
Resource::Type);
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 635c78ca44e..5d0ef7598b8 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
@@ -95,6 +95,12 @@ class ResourceFetcherTest : public testing::Test {
ResourceFetcherTest() = default;
~ResourceFetcherTest() override { GetMemoryCache()->EvictResources(); }
+ void RunUntilIdle() {
+ base::SingleThreadTaskRunner* runner =
+ Context()->GetLoadingTaskRunner().get();
+ static_cast<scheduler::FakeTaskRunner*>(runner)->RunUntilIdle();
+ }
+
protected:
MockFetchContext* Context() { return platform_->Context(); }
void AddResourceToMemoryCache(
@@ -905,7 +911,7 @@ TEST_F(ResourceFetcherTest, StaleWhileRevalidate) {
new_resource = MockResource::Fetch(fetch_params, fetcher, nullptr);
EXPECT_EQ(resource, new_resource);
EXPECT_TRUE(GetMemoryCache()->Contains(resource));
- platform_->RunUntilIdle();
+ RunUntilIdle();
platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
EXPECT_FALSE(GetMemoryCache()->Contains(resource));
}
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 a010169b9a7..36059664f09 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
@@ -192,53 +192,15 @@ void ResourceLoadScheduler::TrafficMonitor::Report(
("Blink.ResourceLoadScheduler.RequestCount",
ToSample(ReportCircumstance::kNumOfCircumstances)));
- DEFINE_STATIC_LOCAL(
- CustomCountHistogram, main_frame_throttled_traffic_bytes,
- ("Blink.ResourceLoadScheduler.TrafficBytes.MainframeThrottled", 0,
- kMaximumReportSize1G, kReportBucketCount));
- DEFINE_STATIC_LOCAL(
- CustomCountHistogram, main_frame_not_throttled_traffic_bytes,
- ("Blink.ResourceLoadScheduler.TrafficBytes.MainframeNotThrottled", 0,
- kMaximumReportSize1G, kReportBucketCount));
- DEFINE_STATIC_LOCAL(
- CustomCountHistogram, sub_frame_throttled_traffic_bytes,
- ("Blink.ResourceLoadScheduler.TrafficBytes.SubframeThrottled", 0,
- kMaximumReportSize1G, kReportBucketCount));
- DEFINE_STATIC_LOCAL(
- CustomCountHistogram, sub_frame_not_throttled_traffic_bytes,
- ("Blink.ResourceLoadScheduler.TrafficBytes.SubframeNotThrottled", 0,
- kMaximumReportSize1G, kReportBucketCount));
-
- DEFINE_STATIC_LOCAL(
- CustomCountHistogram, main_frame_throttled_decoded_bytes,
- ("Blink.ResourceLoadScheduler.DecodedBytes.MainframeThrottled", 0,
- kMaximumReportSize1G, kReportBucketCount));
- DEFINE_STATIC_LOCAL(
- CustomCountHistogram, main_frame_not_throttled_decoded_bytes,
- ("Blink.ResourceLoadScheduler.DecodedBytes.MainframeNotThrottled", 0,
- kMaximumReportSize1G, kReportBucketCount));
- DEFINE_STATIC_LOCAL(
- CustomCountHistogram, sub_frame_throttled_decoded_bytes,
- ("Blink.ResourceLoadScheduler.DecodedBytes.SubframeThrottled", 0,
- kMaximumReportSize1G, kReportBucketCount));
- DEFINE_STATIC_LOCAL(
- CustomCountHistogram, sub_frame_not_throttled_decoded_bytes,
- ("Blink.ResourceLoadScheduler.DecodedBytes.SubframeNotThrottled", 0,
- kMaximumReportSize1G, kReportBucketCount));
-
switch (current_state_) {
case scheduler::SchedulingLifecycleState::kThrottled:
case scheduler::SchedulingLifecycleState::kHidden:
if (is_main_frame_) {
request_count_by_circumstance.Count(
ToSample(ReportCircumstance::kMainframeThrottled));
- main_frame_throttled_traffic_bytes.Count(hints.encoded_data_length());
- main_frame_throttled_decoded_bytes.Count(hints.decoded_body_length());
} else {
request_count_by_circumstance.Count(
ToSample(ReportCircumstance::kSubframeThrottled));
- sub_frame_throttled_traffic_bytes.Count(hints.encoded_data_length());
- sub_frame_throttled_decoded_bytes.Count(hints.decoded_body_length());
}
total_throttled_request_count_++;
total_throttled_traffic_bytes_ += hints.encoded_data_length();
@@ -248,17 +210,9 @@ void ResourceLoadScheduler::TrafficMonitor::Report(
if (is_main_frame_) {
request_count_by_circumstance.Count(
ToSample(ReportCircumstance::kMainframeNotThrottled));
- main_frame_not_throttled_traffic_bytes.Count(
- hints.encoded_data_length());
- main_frame_not_throttled_decoded_bytes.Count(
- hints.decoded_body_length());
} else {
request_count_by_circumstance.Count(
ToSample(ReportCircumstance::kSubframeNotThrottled));
- sub_frame_not_throttled_traffic_bytes.Count(
- hints.encoded_data_length());
- sub_frame_not_throttled_decoded_bytes.Count(
- hints.decoded_body_length());
}
total_not_throttled_request_count_++;
total_not_throttled_traffic_bytes_ += hints.encoded_data_length();
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 cc52420a1cf..aecb00ca8ea 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
@@ -52,6 +52,7 @@
#include "third_party/blink/renderer/platform/network/network_instrumentation.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
#include "third_party/blink/renderer/platform/shared_buffer.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/assertions.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
@@ -305,7 +306,6 @@ bool ResourceLoader::WillFollowRedirect(
base::Optional<ResourceRequestBlockedReason> blocked_reason =
Context().CanRequest(
resource_type, *new_request, new_url, options, reporting_policy,
- FetchParameters::kUseDefaultOriginRestrictionForType,
ResourceRequest::RedirectStatus::kFollowedRedirect);
if (Context().IsAdResource(new_url, resource_type,
@@ -322,23 +322,25 @@ bool ResourceLoader::WillFollowRedirect(
kEnableCORSHandlingByResourceFetcher &&
fetch_request_mode == network::mojom::FetchRequestMode::kCORS) {
scoped_refptr<const SecurityOrigin> source_origin = GetSourceOrigin();
- WebSecurityOrigin source_web_origin(source_origin.get());
- WrappedResourceRequest new_request_wrapper(*new_request);
- base::Optional<network::CORSErrorStatus> cors_error =
- WebCORS::HandleRedirect(
- source_web_origin, new_request_wrapper, redirect_response.Url(),
- redirect_response.HttpStatusCode(),
- redirect_response.HttpHeaderFields(), fetch_credentials_mode,
- resource_->MutableOptions());
+ base::Optional<network::CORSErrorStatus> cors_error;
+ cors_error = CORS::CheckRedirectLocation(
+ new_url, fetch_request_mode, source_origin.get(),
+ GetCORSFlag() ? CORSFlag::Set : CORSFlag::Unset);
+ if (!cors_error && GetCORSFlag()) {
+ cors_error =
+ CORS::CheckAccess(new_url, redirect_response.HttpStatusCode(),
+ redirect_response.HttpHeaderFields(),
+ fetch_credentials_mode, *source_origin);
+ }
if (cors_error) {
resource_->SetCORSStatus(CORSStatus::kFailed);
if (!unused_preload) {
Context().AddErrorConsoleMessage(
- CORS::GetErrorString(CORS::ErrorParameter::Create(
- *cors_error, redirect_response.Url(), new_url,
- redirect_response.HttpStatusCode(), *source_origin.get(),
- resource_->LastResourceRequest().GetRequestContext())),
+ CORS::GetErrorString(*cors_error, initial_request.Url(),
+ redirect_response.Url(),
+ *source_origin.get(), resource_->GetType(),
+ resource_->Options().initiator_info.name),
FetchContext::kJSSource);
}
@@ -346,8 +348,18 @@ bool ResourceLoader::WillFollowRedirect(
ResourceRequestBlockedReason::kOther);
return false;
}
-
- source_origin = source_web_origin;
+ // If |actualResponse|’s location URL’s origin is not same origin with
+ // |request|’s current url’s origin and |request|’s origin is not same
+ // origin with |request|’s current url’s origin, then set |request|’s
+ // tainted origin flag.
+ if (resource_->Options().security_origin &&
+ !SecurityOrigin::AreSameSchemeHostPort(new_url,
+ redirect_response.Url()) &&
+ !resource_->Options().security_origin->CanRequest(
+ redirect_response.Url())) {
+ resource_->MutableOptions().security_origin =
+ SecurityOrigin::CreateUniqueOpaque();
+ }
}
if (resource_type == Resource::kImage &&
fetcher_->ShouldDeferImageLoad(new_url)) {
@@ -424,6 +436,24 @@ bool ResourceLoader::WillFollowRedirect(
return false;
}
+ if (options.cors_handling_by_resource_fetcher ==
+ kEnableCORSHandlingByResourceFetcher &&
+ CORS::IsCORSEnabledRequestMode(fetch_request_mode)) {
+ const auto origin = GetSourceOrigin();
+ if (!origin->CanRequest(new_request->Url()))
+ resource_->MutableOptions().cors_flag = true;
+ if (GetCORSFlag()) {
+ // Cross-origin requests are only allowed certain registered schemes.
+ if (!SchemeRegistry::ShouldTreatURLSchemeAsCORSEnabled(
+ KURL(new_url).Protocol())) {
+ HandleError(ResourceError(
+ new_url, network::CORSErrorStatus(
+ network::mojom::CORSError::kCORSDisabledScheme)));
+ return false;
+ }
+ }
+ }
+
report_raw_headers = new_request->ReportRawHeaders();
return true;
@@ -455,7 +485,7 @@ CORSStatus ResourceLoader::DetermineCORSStatus(const ResourceResponse& response,
StringBuilder& error_msg) const {
// Service workers handle CORS separately.
if (response.WasFetchedViaServiceWorker()) {
- switch (response.ResponseTypeViaServiceWorker()) {
+ switch (response.GetType()) {
case network::mojom::FetchResponseType::kBasic:
case network::mojom::FetchResponseType::kCORS:
case network::mojom::FetchResponseType::kDefault:
@@ -506,18 +536,10 @@ CORSStatus ResourceLoader::DetermineCORSStatus(const ResourceResponse& response,
String resource_type = Resource::ResourceTypeToString(
resource_->GetType(), resource_->Options().initiator_info.name);
- error_msg.Append("Access to ");
- error_msg.Append(resource_type);
- error_msg.Append(" at '");
- error_msg.Append(response.Url().GetString());
- error_msg.Append("' from origin '");
- error_msg.Append(source_origin->ToString());
- error_msg.Append("' has been blocked by CORS policy: ");
- error_msg.Append(CORS::GetErrorString(CORS::ErrorParameter::Create(
- *cors_error, initial_request.Url(), KURL(),
- response_for_access_control.HttpStatusCode(), *source_origin,
- initial_request.GetRequestContext())));
-
+ error_msg.Append(CORS::GetErrorString(
+ *cors_error, initial_request.Url(),
+ resource_->LastResourceRequest().Url(), *source_origin,
+ resource_->GetType(), resource_->Options().initiator_info.name));
return CORSStatus::kFailed;
}
@@ -601,7 +623,6 @@ void ResourceLoader::DidReceiveResponse(
Context().CanRequest(
resource_type, initial_request, original_url, options,
SecurityViolationReportingPolicy::kReport,
- FetchParameters::kUseDefaultOriginRestrictionForType,
ResourceRequest::RedirectStatus::kFollowedRedirect);
if (blocked_reason) {
HandleError(ResourceError::CancelledDueToAccessCheckError(
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 0d10f6e645a..cc9ddd361d0 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
@@ -174,6 +174,8 @@ class PLATFORM_EXPORT ResourceLoader final
void OnProgress(uint64_t delta) override;
void FinishedCreatingBlob(const scoped_refptr<BlobDataHandle>&);
+ bool GetCORSFlag() const { return resource_->Options().cors_flag; }
+
base::Optional<ResourceRequestBlockedReason> CheckResponseNosniff(
WebURLRequest::RequestContext,
const ResourceResponse&) const;
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 0907407eedf..2dc495bed26 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
@@ -33,7 +33,6 @@
#include "base/memory/scoped_refptr.h"
#include "services/network/public/mojom/url_loader_factory.mojom-blink.h"
-#include "third_party/blink/renderer/platform/cross_thread_copier.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_initiator_info.h"
#include "third_party/blink/renderer/platform/loader/fetch/integrity_metadata.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
@@ -59,7 +58,7 @@ enum SynchronousPolicy : uint8_t {
kRequestAsynchronously
};
-// Used by the DocumentThreadableLoader to turn off part of the CORS handling
+// Used by the ThreadableLoader to turn off part of the CORS handling
// logic in the ResourceFetcher to use its own CORS handling logic.
enum CORSHandlingByResourceFetcher {
kDisableCORSHandlingByResourceFetcher,
@@ -75,6 +74,7 @@ enum CacheAwareLoadingEnabled : uint8_t {
kIsCacheAwareLoadingEnabled
};
+// This class is thread-bound. Do not copy/pass an instance across threads.
struct ResourceLoaderOptions {
USING_FAST_MALLOC(ResourceLoaderOptions);
@@ -91,9 +91,6 @@ struct ResourceLoaderOptions {
FetchInitiatorInfo initiator_info;
- // ATTENTION: When adding members, update
- // CrossThreadResourceLoaderOptionsData, too.
-
DataBufferingPolicy data_buffering_policy;
ContentSecurityPolicyDisposition content_security_policy_option;
@@ -102,7 +99,7 @@ struct ResourceLoaderOptions {
// When set to kDisableCORSHandlingByResourceFetcher, the ResourceFetcher
// suppresses part of its CORS handling logic.
- // Used by DocumentThreadableLoader which does CORS handling by itself.
+ // Used by ThreadableLoader which does CORS handling by itself.
CORSHandlingByResourceFetcher cors_handling_by_resource_fetcher;
// Corresponds to the CORS flag in the Fetch spec.
@@ -122,88 +119,6 @@ struct ResourceLoaderOptions {
url_loader_factory;
};
-// Encode AtomicString (in FetchInitiatorInfo) as String to cross threads.
-struct CrossThreadResourceLoaderOptionsData {
- DISALLOW_NEW();
- explicit CrossThreadResourceLoaderOptionsData(
- const ResourceLoaderOptions& options)
- : data_buffering_policy(options.data_buffering_policy),
- content_security_policy_option(options.content_security_policy_option),
- initiator_info(options.initiator_info),
- request_initiator_context(options.request_initiator_context),
- synchronous_policy(options.synchronous_policy),
- cors_handling_by_resource_fetcher(
- options.cors_handling_by_resource_fetcher),
- cors_flag(options.cors_flag),
- security_origin(options.security_origin
- ? options.security_origin->IsolatedCopy()
- : nullptr),
- content_security_policy_nonce(
- options.content_security_policy_nonce.IsolatedCopy()),
- integrity_metadata(options.integrity_metadata),
- parser_disposition(options.parser_disposition),
- cache_aware_loading_enabled(options.cache_aware_loading_enabled) {
- if (options.url_loader_factory) {
- DCHECK(options.url_loader_factory->data.is_bound());
- url_loader_factory = base::MakeRefCounted<base::RefCountedData<
- network::mojom::blink::URLLoaderFactoryPtrInfo>>();
- options.url_loader_factory->data->Clone(
- MakeRequest(&url_loader_factory->data));
- }
- }
-
- operator ResourceLoaderOptions() const {
- ResourceLoaderOptions options;
- options.data_buffering_policy = data_buffering_policy;
- options.content_security_policy_option = content_security_policy_option;
- options.initiator_info = initiator_info;
- options.request_initiator_context = request_initiator_context;
- options.synchronous_policy = synchronous_policy;
- options.cors_handling_by_resource_fetcher =
- cors_handling_by_resource_fetcher;
- options.cors_flag = cors_flag;
- options.security_origin = security_origin;
- options.content_security_policy_nonce = content_security_policy_nonce;
- options.integrity_metadata = integrity_metadata;
- options.parser_disposition = parser_disposition;
- options.cache_aware_loading_enabled = cache_aware_loading_enabled;
- if (url_loader_factory) {
- DCHECK(url_loader_factory->data.is_valid());
- options.url_loader_factory = base::MakeRefCounted<
- base::RefCountedData<network::mojom::blink::URLLoaderFactoryPtr>>(
- network::mojom::blink::URLLoaderFactoryPtr(
- std::move(url_loader_factory->data)));
- }
- return options;
- }
-
- DataBufferingPolicy data_buffering_policy;
- ContentSecurityPolicyDisposition content_security_policy_option;
- CrossThreadFetchInitiatorInfoData initiator_info;
- RequestInitiatorContext request_initiator_context;
- SynchronousPolicy synchronous_policy;
-
- CORSHandlingByResourceFetcher cors_handling_by_resource_fetcher;
- bool cors_flag;
- scoped_refptr<const SecurityOrigin> security_origin;
-
- String content_security_policy_nonce;
- IntegrityMetadataSet integrity_metadata;
- ParserDisposition parser_disposition;
- CacheAwareLoadingEnabled cache_aware_loading_enabled;
- scoped_refptr<
- base::RefCountedData<network::mojom::blink::URLLoaderFactoryPtrInfo>>
- url_loader_factory;
-};
-
-template <>
-struct CrossThreadCopier<ResourceLoaderOptions> {
- using Type = CrossThreadResourceLoaderOptionsData;
- static Type Copy(const ResourceLoaderOptions& options) {
- return CrossThreadResourceLoaderOptionsData(options);
- }
-};
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_RESOURCE_LOADER_OPTIONS_H_
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader_options_test.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader_options_test.cc
deleted file mode 100644
index 9fd9edd4160..00000000000
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader_options_test.cc
+++ /dev/null
@@ -1,108 +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/platform/loader/fetch/resource_loader_options.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include <type_traits>
-
-namespace blink {
-
-namespace {
-
-TEST(ResourceLoaderOptionsTest, DeepCopy) {
- // Check that the fields of ResourceLoaderOptions are enums, except for
- // initiatorInfo and securityOrigin.
- static_assert(std::is_enum<DataBufferingPolicy>::value,
- "DataBufferingPolicy should be an enum");
- static_assert(std::is_enum<ContentSecurityPolicyDisposition>::value,
- "ContentSecurityPolicyDisposition should be an enum");
- static_assert(std::is_enum<RequestInitiatorContext>::value,
- "RequestInitiatorContext should be an enum");
- static_assert(std::is_enum<SynchronousPolicy>::value,
- "SynchronousPolicy should be an enum");
- static_assert(std::is_enum<CORSHandlingByResourceFetcher>::value,
- "CORSHandlingByResourceFetcher should be an enum");
-
- ResourceLoaderOptions original;
- scoped_refptr<const SecurityOrigin> security_origin =
- SecurityOrigin::CreateFromString("http://www.google.com");
- original.security_origin = security_origin;
- original.initiator_info.name = AtomicString("xmlhttprequest");
-
- CrossThreadResourceLoaderOptionsData copy_data =
- CrossThreadCopier<ResourceLoaderOptions>::Copy(original);
- ResourceLoaderOptions copy = copy_data;
-
- // Check that contents are correctly copied to |copyData|
- EXPECT_EQ(original.data_buffering_policy, copy_data.data_buffering_policy);
- EXPECT_EQ(original.content_security_policy_option,
- copy_data.content_security_policy_option);
- EXPECT_EQ(original.initiator_info.name, copy_data.initiator_info.name);
- EXPECT_EQ(original.initiator_info.position,
- copy_data.initiator_info.position);
- EXPECT_EQ(original.initiator_info.start_time,
- copy_data.initiator_info.start_time);
- EXPECT_EQ(original.request_initiator_context,
- copy_data.request_initiator_context);
- EXPECT_EQ(original.synchronous_policy, copy_data.synchronous_policy);
- EXPECT_EQ(original.cors_handling_by_resource_fetcher,
- copy_data.cors_handling_by_resource_fetcher);
- EXPECT_EQ(original.security_origin->Protocol(),
- copy_data.security_origin->Protocol());
- EXPECT_EQ(original.security_origin->Host(),
- copy_data.security_origin->Host());
- EXPECT_EQ(original.security_origin->Domain(),
- copy_data.security_origin->Domain());
-
- // Check that pointers are different between |original| and |copyData|
- EXPECT_NE(original.initiator_info.name.Impl(),
- copy_data.initiator_info.name.Impl());
- EXPECT_NE(original.security_origin.get(), copy_data.security_origin.get());
- EXPECT_NE(original.security_origin->Protocol().Impl(),
- copy_data.security_origin->Protocol().Impl());
- EXPECT_NE(original.security_origin->Host().Impl(),
- copy_data.security_origin->Host().Impl());
- EXPECT_NE(original.security_origin->Domain().Impl(),
- copy_data.security_origin->Domain().Impl());
-
- // Check that contents are correctly copied to |copy|
- EXPECT_EQ(original.data_buffering_policy, copy.data_buffering_policy);
- EXPECT_EQ(original.content_security_policy_option,
- copy.content_security_policy_option);
- EXPECT_EQ(original.initiator_info.name, copy.initiator_info.name);
- EXPECT_EQ(original.initiator_info.position, copy.initiator_info.position);
- EXPECT_EQ(original.initiator_info.start_time, copy.initiator_info.start_time);
- EXPECT_EQ(original.request_initiator_context, copy.request_initiator_context);
- EXPECT_EQ(original.synchronous_policy, copy.synchronous_policy);
- EXPECT_EQ(original.cors_handling_by_resource_fetcher,
- copy.cors_handling_by_resource_fetcher);
- EXPECT_EQ(original.security_origin->Protocol(),
- copy.security_origin->Protocol());
- EXPECT_EQ(original.security_origin->Host(), copy.security_origin->Host());
- EXPECT_EQ(original.security_origin->Domain(), copy.security_origin->Domain());
-
- // Check that pointers are different between |original| and |copy|
- // FIXME: When |original| and |copy| are in different threads, then
- // EXPECT_NE(original.initiatorInfo.name.impl(),
- // copy.initiatorInfo.name.impl());
- // should pass. However, in the unit test here, these two pointers are the
- // same, because initiatorInfo.name is AtomicString.
- EXPECT_NE(original.security_origin.get(), copy.security_origin.get());
- EXPECT_NE(original.security_origin->Protocol().Impl(),
- copy.security_origin->Protocol().Impl());
- EXPECT_NE(original.security_origin->Host().Impl(),
- copy.security_origin->Host().Impl());
- EXPECT_NE(original.security_origin->Domain().Impl(),
- copy.security_origin->Domain().Impl());
-
- // FIXME: The checks for content equality/pointer inequality for
- // securityOrigin here is not complete (i.e. m_filePath is not checked). A
- // unit test for SecurityOrigin::isolatedCopy() that covers these checks
- // should be added.
-}
-
-} // namespace
-
-} // namespace blink
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 0336dc93bc3..d0cbd3e3626 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
@@ -137,11 +137,9 @@ TEST_F(ResourceLoaderTest, DetermineCORSStatus) {
response.SetWasFetchedViaServiceWorker(true);
if (test.service_worker == kSWOpaque) {
- response.SetResponseTypeViaServiceWorker(
- network::mojom::FetchResponseType::kOpaque);
+ response.SetType(network::mojom::FetchResponseType::kOpaque);
} else {
- response.SetResponseTypeViaServiceWorker(
- network::mojom::FetchResponseType::kDefault);
+ response.SetType(network::mojom::FetchResponseType::kDefault);
}
}
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 aabeebe9b41..291eaa46e37 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
@@ -74,59 +74,15 @@ ResourceRequest::ResourceRequest(const KURL& url)
fetch_importance_mode_(mojom::FetchImportanceMode::kImportanceAuto),
fetch_credentials_mode_(network::mojom::FetchCredentialsMode::kInclude),
fetch_redirect_mode_(network::mojom::FetchRedirectMode::kFollow),
+ referrer_string_(Referrer::ClientReferrerString()),
referrer_policy_(kReferrerPolicyDefault),
did_set_http_referrer_(false),
- check_for_browser_side_navigation_(true),
was_discarded_(false),
is_external_request_(false),
cors_preflight_policy_(
network::mojom::CORSPreflightPolicy::kConsiderPreflight),
redirect_status_(RedirectStatus::kNoRedirect) {}
-ResourceRequest::ResourceRequest(CrossThreadResourceRequestData* data)
- : ResourceRequest(data->url_) {
- SetTimeoutInterval(data->timeout_interval_);
- SetSiteForCookies(data->site_for_cookies_);
- SetRequestorOrigin(data->requestor_origin_);
- SetHTTPMethod(AtomicString(data->http_method_));
- SetPriority(data->priority_, data->intra_priority_value_);
-
- http_header_fields_.Adopt(std::move(data->http_headers_));
-
- SetHTTPBody(data->http_body_);
- SetAllowStoredCredentials(data->allow_stored_credentials_);
- SetReportUploadProgress(data->report_upload_progress_);
- SetHasUserGesture(data->has_user_gesture_);
- SetDownloadToBlob(data->download_to_blob_);
- SetUseStreamOnResponse(data->use_stream_on_response_);
- SetKeepalive(data->keepalive_);
- SetCacheMode(data->cache_mode_);
- SetSkipServiceWorker(data->skip_service_worker_);
- SetShouldResetAppCache(data->should_reset_app_cache_);
- SetRequestorID(data->requestor_id_);
- SetPluginChildID(data->plugin_child_id_);
- SetAppCacheHostID(data->app_cache_host_id_);
- SetPreviewsState(data->previews_state_);
- SetRequestContext(data->request_context_);
- SetFrameType(data->frame_type_);
- SetFetchRequestMode(data->fetch_request_mode_);
- SetFetchImportanceMode(data->fetch_importance_mode_);
- SetFetchCredentialsMode(data->fetch_credentials_mode_);
- SetFetchRedirectMode(data->fetch_redirect_mode_);
- SetFetchIntegrity(data->fetch_integrity_.IsolatedCopy());
- referrer_policy_ = data->referrer_policy_;
- did_set_http_referrer_ = data->did_set_http_referrer_;
- check_for_browser_side_navigation_ = data->check_for_browser_side_navigation_;
- is_external_request_ = data->is_external_request_;
- cors_preflight_policy_ = data->cors_preflight_policy_;
- redirect_status_ = data->redirect_status_;
- suggested_filename_ = data->suggested_filename_;
- is_ad_resource_ = data->is_ad_resource_;
- SetInitiatorCSP(data->navigation_csp_);
- upgrade_if_insecure_ = data->upgrade_if_insecure_;
- devtools_token_ = data->devtools_token_;
-}
-
ResourceRequest::ResourceRequest(const ResourceRequest&) = default;
ResourceRequest::~ResourceRequest() = default;
@@ -146,6 +102,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, static_cast<ReferrerPolicy>(new_referrer_policy)));
request->SetSkipServiceWorker(skip_service_worker);
@@ -164,7 +122,6 @@ std::unique_ptr<ResourceRequest> ResourceRequest::CreateRedirectRequest(
if (request->HttpMethod() == HttpMethod())
request->SetHTTPBody(HttpBody());
- request->SetCheckForBrowserSideNavigation(CheckForBrowserSideNavigation());
request->SetWasDiscarded(WasDiscarded());
request->SetCORSPreflightPolicy(CORSPreflightPolicy());
if (IsAdResource())
@@ -175,57 +132,6 @@ std::unique_ptr<ResourceRequest> ResourceRequest::CreateRedirectRequest(
return request;
}
-std::unique_ptr<CrossThreadResourceRequestData> ResourceRequest::CopyData()
- const {
- std::unique_ptr<CrossThreadResourceRequestData> data =
- std::make_unique<CrossThreadResourceRequestData>();
- data->url_ = Url().Copy();
- data->timeout_interval_ = TimeoutInterval();
- data->site_for_cookies_ = SiteForCookies().Copy();
- data->requestor_origin_ =
- RequestorOrigin() ? RequestorOrigin()->IsolatedCopy() : nullptr;
- data->http_method_ = HttpMethod().GetString().IsolatedCopy();
- data->http_headers_ = HttpHeaderFields().CopyData();
- data->priority_ = Priority();
- data->intra_priority_value_ = intra_priority_value_;
-
- if (http_body_)
- data->http_body_ = http_body_->DeepCopy();
- data->allow_stored_credentials_ = allow_stored_credentials_;
- data->report_upload_progress_ = report_upload_progress_;
- data->has_user_gesture_ = has_user_gesture_;
- data->download_to_blob_ = download_to_blob_;
- data->use_stream_on_response_ = use_stream_on_response_;
- data->keepalive_ = keepalive_;
- data->cache_mode_ = GetCacheMode();
- data->skip_service_worker_ = skip_service_worker_;
- data->should_reset_app_cache_ = should_reset_app_cache_;
- data->requestor_id_ = requestor_id_;
- data->plugin_child_id_ = plugin_child_id_;
- data->app_cache_host_id_ = app_cache_host_id_;
- data->previews_state_ = previews_state_;
- data->request_context_ = request_context_;
- data->frame_type_ = frame_type_;
- data->fetch_request_mode_ = fetch_request_mode_;
- data->fetch_importance_mode_ = fetch_importance_mode_;
- data->fetch_credentials_mode_ = fetch_credentials_mode_;
- data->fetch_redirect_mode_ = fetch_redirect_mode_;
- data->fetch_integrity_ = fetch_integrity_.IsolatedCopy();
- data->referrer_policy_ = referrer_policy_;
- data->did_set_http_referrer_ = did_set_http_referrer_;
- data->check_for_browser_side_navigation_ = check_for_browser_side_navigation_;
- data->is_external_request_ = is_external_request_;
- data->cors_preflight_policy_ = cors_preflight_policy_;
- data->redirect_status_ = redirect_status_;
- data->suggested_filename_ = suggested_filename_;
- data->is_ad_resource_ = is_ad_resource_;
- data->navigation_csp_ = initiator_csp_;
-
- data->upgrade_if_insecure_ = upgrade_if_insecure_;
- data->devtools_token_ = devtools_token_;
- return data;
-}
-
bool ResourceRequest::IsNull() const {
return url_.IsNull();
}
@@ -473,8 +379,4 @@ bool ResourceRequest::NeedsHTTPOrigin() const {
return true;
}
-CrossThreadResourceRequestData::CrossThreadResourceRequestData() = default;
-
-CrossThreadResourceRequestData::~CrossThreadResourceRequestData() = default;
-
} // namespace blink
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 cc93416d2e6..668414ad871 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
@@ -54,7 +54,6 @@ namespace blink {
class EncodedFormData;
class SecurityOrigin;
-struct CrossThreadResourceRequestData;
// A ResourceRequest is a "request" object for ResourceLoader. Conceptually
// it is https://fetch.spec.whatwg.org/#concept-request, but it contains
@@ -62,10 +61,7 @@ struct CrossThreadResourceRequestData;
// of this class and WebURLLoader needs it. See WebURLRequest and
// WrappedResourceRequest.
//
-// There are cases where we need to copy a request across threads, and
-// CrossThreadResourceRequestData is a struct for the purpose. When you add a
-// member variable to this class, do not forget to add the corresponding
-// one in CrossThreadResourceRequestData and write copying logic.
+// This class is thread-bound. Do not copy/pass an instance across threads.
class PLATFORM_EXPORT ResourceRequest final {
USING_FAST_MALLOC(ResourceRequest);
@@ -75,7 +71,6 @@ class PLATFORM_EXPORT ResourceRequest final {
ResourceRequest();
explicit ResourceRequest(const String& url_string);
explicit ResourceRequest(const KURL&);
- explicit ResourceRequest(CrossThreadResourceRequestData*);
// TODO(toyoshim): Use std::unique_ptr as much as possible, and hopefully
// make ResourceRequest WTF_MAKE_NONCOPYABLE. See crbug.com/787704.
@@ -93,9 +88,6 @@ class PLATFORM_EXPORT ResourceRequest final {
ReferrerPolicy new_referrer_policy,
bool skip_service_worker) const;
- // Gets a copy of the data suitable for passing to another thread.
- std::unique_ptr<CrossThreadResourceRequestData> CopyData() const;
-
bool IsNull() const;
const KURL& Url() const;
@@ -132,14 +124,26 @@ class PLATFORM_EXPORT ResourceRequest final {
SetHTTPHeaderField(HTTPNames::Content_Type, http_content_type);
}
- bool DidSetHTTPReferrer() const { return did_set_http_referrer_; }
+ // 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(HTTPNames::Referer);
}
- ReferrerPolicy GetReferrerPolicy() const { return referrer_policy_; }
void SetHTTPReferrer(const Referrer&);
+ bool DidSetHTTPReferrer() const { return did_set_http_referrer_; }
void ClearHTTPReferrer();
+ void SetReferrerPolicy(ReferrerPolicy referrer_policy) {
+ referrer_policy_ = referrer_policy;
+ }
+ ReferrerPolicy GetReferrerPolicy() const { return referrer_policy_; }
+
+ void SetReferrerString(const String& referrer_string) {
+ referrer_string_ = referrer_string;
+ }
+ const String& ReferrerString() const { return referrer_string_; }
+
const AtomicString& HttpOrigin() const {
return HttpHeaderField(HTTPNames::Origin);
}
@@ -313,13 +317,6 @@ class PLATFORM_EXPORT ResourceRequest final {
bool CacheControlContainsNoStore() const;
bool HasCacheValidatorFields() const;
- bool CheckForBrowserSideNavigation() const {
- return check_for_browser_side_navigation_;
- }
- void SetCheckForBrowserSideNavigation(bool check) {
- check_for_browser_side_navigation_ = check;
- }
-
bool WasDiscarded() const { return was_discarded_; }
void SetWasDiscarded(bool was_discarded) { was_discarded_ = was_discarded; }
@@ -424,9 +421,12 @@ class PLATFORM_EXPORT ResourceRequest final {
network::mojom::FetchCredentialsMode fetch_credentials_mode_;
network::mojom::FetchRedirectMode fetch_redirect_mode_;
String fetch_integrity_;
+ // TODO(domfarolino): Use AtomicString for referrer_string_ once
+ // off-main-thread fetch is fully implemented and ResourceRequest never gets
+ // transferred between threads. See https://crbug.com/706331.
+ String referrer_string_;
ReferrerPolicy referrer_policy_;
bool did_set_http_referrer_;
- bool check_for_browser_side_navigation_;
bool was_discarded_;
bool is_external_request_;
network::mojom::CORSPreflightPolicy cors_preflight_policy_;
@@ -448,66 +448,6 @@ class PLATFORM_EXPORT ResourceRequest final {
String origin_policy_;
};
-// This class is needed to copy a ResourceRequest across threads, because it
-// has some members which cannot be transferred across threads (AtomicString
-// for example).
-// There are some rules / restrictions:
-// - This struct cannot contain an object that cannot be transferred across
-// threads (e.g., AtomicString)
-// - Non-simple members need explicit copying (e.g., String::IsolatedCopy,
-// KURL::Copy) rather than the copy constructor or the assignment operator.
-struct PLATFORM_EXPORT CrossThreadResourceRequestData {
- DISALLOW_COPY_AND_ASSIGN(CrossThreadResourceRequestData);
- USING_FAST_MALLOC(CrossThreadResourceRequestData);
-
- public:
- CrossThreadResourceRequestData();
- ~CrossThreadResourceRequestData();
-
- KURL url_;
-
- mojom::FetchCacheMode cache_mode_;
- base::TimeDelta timeout_interval_;
- KURL site_for_cookies_;
- scoped_refptr<const SecurityOrigin> requestor_origin_;
-
- String http_method_;
- std::unique_ptr<CrossThreadHTTPHeaderMapData> http_headers_;
- scoped_refptr<EncodedFormData> http_body_;
- bool allow_stored_credentials_;
- bool report_upload_progress_;
- bool has_user_gesture_;
- bool download_to_blob_;
- bool skip_service_worker_;
- bool use_stream_on_response_;
- bool keepalive_;
- bool should_reset_app_cache_;
- ResourceLoadPriority priority_;
- int intra_priority_value_;
- int requestor_id_;
- int plugin_child_id_;
- int app_cache_host_id_;
- WebURLRequest::RequestContext request_context_;
- network::mojom::RequestContextFrameType frame_type_;
- network::mojom::FetchRequestMode fetch_request_mode_;
- mojom::FetchImportanceMode fetch_importance_mode_;
- network::mojom::FetchCredentialsMode fetch_credentials_mode_;
- network::mojom::FetchRedirectMode fetch_redirect_mode_;
- String fetch_integrity_;
- WebURLRequest::PreviewsState previews_state_;
- ReferrerPolicy referrer_policy_;
- bool did_set_http_referrer_;
- bool check_for_browser_side_navigation_;
- bool is_external_request_;
- network::mojom::CORSPreflightPolicy cors_preflight_policy_;
- ResourceRequest::RedirectStatus redirect_status_;
- base::Optional<String> suggested_filename_;
- bool is_ad_resource_;
- WebContentSecurityPolicyList navigation_csp_;
- bool upgrade_if_insecure_;
- base::Optional<base::UnguessableToken> devtools_token_;
-};
-
} // 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 b9aa59f9adc..ffb5fbcea4d 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
@@ -14,126 +14,6 @@
namespace blink {
-TEST(ResourceRequestTest, CrossThreadResourceRequestData) {
- ResourceRequest original;
- original.SetURL(KURL("http://www.example.com/test.htm"));
- original.SetCacheMode(mojom::FetchCacheMode::kDefault);
- original.SetTimeoutInterval(base::TimeDelta::FromSeconds(10));
- original.SetSiteForCookies(KURL("http://www.example.com/first_party.htm"));
- original.SetRequestorOrigin(
- SecurityOrigin::Create(KURL("http://www.example.com/first_party.htm")));
- original.SetHTTPMethod(HTTPNames::GET);
- original.SetHTTPHeaderField(AtomicString("Foo"), AtomicString("Bar"));
- original.SetHTTPHeaderField(AtomicString("Piyo"), AtomicString("Fuga"));
- original.SetPriority(ResourceLoadPriority::kLow, 20);
-
- scoped_refptr<EncodedFormData> original_body(
- EncodedFormData::Create("Test Body"));
- original.SetHTTPBody(original_body);
- original.SetAllowStoredCredentials(false);
- original.SetReportUploadProgress(false);
- original.SetHasUserGesture(false);
- original.SetDownloadToBlob(false);
- original.SetSkipServiceWorker(false);
- original.SetFetchRequestMode(network::mojom::FetchRequestMode::kCORS);
- original.SetFetchCredentialsMode(
- network::mojom::FetchCredentialsMode::kSameOrigin);
- original.SetRequestorID(30);
- original.SetPluginChildID(40);
- original.SetAppCacheHostID(50);
- original.SetRequestContext(WebURLRequest::kRequestContextAudio);
- original.SetFrameType(network::mojom::RequestContextFrameType::kNested);
- original.SetHTTPReferrer(
- Referrer("http://www.example.com/referrer.htm", kReferrerPolicyDefault));
-
- EXPECT_STREQ("http://www.example.com/test.htm",
- original.Url().GetString().Utf8().data());
- EXPECT_EQ(mojom::FetchCacheMode::kDefault, original.GetCacheMode());
- EXPECT_EQ(base::TimeDelta::FromSeconds(10), original.TimeoutInterval());
- EXPECT_STREQ("http://www.example.com/first_party.htm",
- original.SiteForCookies().GetString().Utf8().data());
- EXPECT_STREQ("www.example.com",
- original.RequestorOrigin()->Host().Utf8().data());
- EXPECT_STREQ("GET", original.HttpMethod().Utf8().data());
- EXPECT_STREQ("Bar", original.HttpHeaderFields().Get("Foo").Utf8().data());
- EXPECT_STREQ("Fuga", original.HttpHeaderFields().Get("Piyo").Utf8().data());
- EXPECT_EQ(ResourceLoadPriority::kLow, original.Priority());
- EXPECT_STREQ("Test Body",
- original.HttpBody()->FlattenToString().Utf8().data());
- EXPECT_FALSE(original.AllowStoredCredentials());
- EXPECT_FALSE(original.ReportUploadProgress());
- EXPECT_FALSE(original.HasUserGesture());
- EXPECT_FALSE(original.DownloadToBlob());
- EXPECT_FALSE(original.GetSkipServiceWorker());
- EXPECT_EQ(network::mojom::FetchRequestMode::kCORS,
- original.GetFetchRequestMode());
- EXPECT_EQ(network::mojom::FetchCredentialsMode::kSameOrigin,
- original.GetFetchCredentialsMode());
- EXPECT_EQ(30, original.RequestorID());
- EXPECT_EQ(40, original.GetPluginChildID());
- EXPECT_EQ(50, original.AppCacheHostID());
- EXPECT_EQ(WebURLRequest::kRequestContextAudio, original.GetRequestContext());
- EXPECT_EQ(network::mojom::RequestContextFrameType::kNested,
- original.GetFrameType());
- EXPECT_STREQ("http://www.example.com/referrer.htm",
- original.HttpReferrer().Utf8().data());
- EXPECT_EQ(kReferrerPolicyDefault, original.GetReferrerPolicy());
-
- std::unique_ptr<CrossThreadResourceRequestData> data1(original.CopyData());
- ResourceRequest copy1(data1.get());
-
- EXPECT_STREQ("http://www.example.com/test.htm",
- copy1.Url().GetString().Utf8().data());
- EXPECT_EQ(mojom::FetchCacheMode::kDefault, copy1.GetCacheMode());
- EXPECT_EQ(base::TimeDelta::FromSeconds(10), copy1.TimeoutInterval());
- EXPECT_STREQ("http://www.example.com/first_party.htm",
- copy1.SiteForCookies().GetString().Utf8().data());
- EXPECT_STREQ("www.example.com",
- copy1.RequestorOrigin()->Host().Utf8().data());
- EXPECT_STREQ("GET", copy1.HttpMethod().Utf8().data());
- EXPECT_STREQ("Bar", copy1.HttpHeaderFields().Get("Foo").Utf8().data());
- EXPECT_EQ(ResourceLoadPriority::kLow, copy1.Priority());
- EXPECT_STREQ("Test Body", copy1.HttpBody()->FlattenToString().Utf8().data());
- EXPECT_FALSE(copy1.AllowStoredCredentials());
- EXPECT_FALSE(copy1.ReportUploadProgress());
- EXPECT_FALSE(copy1.HasUserGesture());
- EXPECT_FALSE(copy1.DownloadToBlob());
- EXPECT_FALSE(copy1.GetSkipServiceWorker());
- EXPECT_EQ(network::mojom::FetchRequestMode::kCORS,
- copy1.GetFetchRequestMode());
- EXPECT_EQ(network::mojom::FetchCredentialsMode::kSameOrigin,
- copy1.GetFetchCredentialsMode());
- EXPECT_EQ(30, copy1.RequestorID());
- EXPECT_EQ(40, copy1.GetPluginChildID());
- EXPECT_EQ(50, copy1.AppCacheHostID());
- EXPECT_EQ(WebURLRequest::kRequestContextAudio, copy1.GetRequestContext());
- EXPECT_EQ(network::mojom::RequestContextFrameType::kNested,
- copy1.GetFrameType());
- EXPECT_STREQ("http://www.example.com/referrer.htm",
- copy1.HttpReferrer().Utf8().data());
- EXPECT_EQ(kReferrerPolicyDefault, copy1.GetReferrerPolicy());
-
- copy1.SetAllowStoredCredentials(true);
- copy1.SetReportUploadProgress(true);
- copy1.SetHasUserGesture(true);
- copy1.SetDownloadToBlob(true);
- copy1.SetSkipServiceWorker(true);
- copy1.SetFetchRequestMode(network::mojom::FetchRequestMode::kNoCORS);
- copy1.SetFetchCredentialsMode(network::mojom::FetchCredentialsMode::kInclude);
-
- std::unique_ptr<CrossThreadResourceRequestData> data2(copy1.CopyData());
- ResourceRequest copy2(data2.get());
- EXPECT_TRUE(copy2.AllowStoredCredentials());
- EXPECT_TRUE(copy2.ReportUploadProgress());
- EXPECT_TRUE(copy2.HasUserGesture());
- EXPECT_TRUE(copy2.DownloadToBlob());
- EXPECT_TRUE(copy2.GetSkipServiceWorker());
- EXPECT_EQ(network::mojom::FetchRequestMode::kNoCORS,
- copy1.GetFetchRequestMode());
- EXPECT_EQ(network::mojom::FetchCredentialsMode::kInclude,
- copy1.GetFetchCredentialsMode());
-}
-
TEST(ResourceRequestTest, SetHasUserGesture) {
ResourceRequest original;
EXPECT_FALSE(original.HasUserGesture());
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 8771ae8787b..4daa8870615 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
@@ -90,134 +90,10 @@ ResourceResponse::ResourceResponse(const KURL& url,
text_encoding_name_(text_encoding_name),
is_null_(false) {}
-ResourceResponse::ResourceResponse(CrossThreadResourceResponseData* data)
- : ResourceResponse() {
- SetURL(data->url_);
- SetMimeType(AtomicString(data->mime_type_));
- SetExpectedContentLength(data->expected_content_length_);
- SetTextEncodingName(AtomicString(data->text_encoding_name_));
-
- SetHTTPStatusCode(data->http_status_code_);
- SetHTTPStatusText(AtomicString(data->http_status_text_));
-
- http_header_fields_.Adopt(std::move(data->http_headers_));
- SetResourceLoadTiming(std::move(data->resource_load_timing_));
- remote_ip_address_ = AtomicString(data->remote_ip_address_);
- remote_port_ = data->remote_port_;
- has_major_certificate_errors_ = data->has_major_certificate_errors_;
- ct_policy_compliance_ = data->ct_policy_compliance_;
- is_legacy_symantec_cert_ = data->is_legacy_symantec_cert_;
- cert_validity_start_ = data->cert_validity_start_;
- was_fetched_via_spdy_ = data->was_fetched_via_spdy_;
- was_fetched_via_proxy_ = data->was_fetched_via_proxy_;
- was_fetched_via_service_worker_ = data->was_fetched_via_service_worker_;
- was_fallback_required_by_service_worker_ =
- data->was_fallback_required_by_service_worker_;
- did_service_worker_navigation_preload_ =
- data->did_service_worker_navigation_preload_;
- async_revalidation_requested_ = data->async_revalidation_requested_;
- response_type_via_service_worker_ = data->response_type_via_service_worker_;
- security_style_ = data->security_style_;
- security_details_.protocol = data->security_details_.protocol;
- security_details_.cipher = data->security_details_.cipher;
- security_details_.key_exchange = data->security_details_.key_exchange;
- security_details_.key_exchange_group =
- data->security_details_.key_exchange_group;
- security_details_.mac = data->security_details_.mac;
- security_details_.subject_name = data->security_details_.subject_name;
- security_details_.san_list = data->security_details_.san_list;
- security_details_.issuer = data->security_details_.issuer;
- security_details_.valid_from = data->security_details_.valid_from;
- security_details_.valid_to = data->security_details_.valid_to;
- for (auto& cert : data->certificate_)
- security_details_.certificate.push_back(AtomicString(cert));
- security_details_.sct_list = data->security_details_.sct_list;
- http_version_ = data->http_version_;
- app_cache_id_ = data->app_cache_id_;
- app_cache_manifest_url_ = data->app_cache_manifest_url_.Copy();
- multipart_boundary_ = data->multipart_boundary_;
- url_list_via_service_worker_ = data->url_list_via_service_worker_;
- cache_storage_cache_name_ = data->cache_storage_cache_name_;
- response_time_ = data->response_time_;
- encoded_data_length_ = data->encoded_data_length_;
- encoded_body_length_ = data->encoded_body_length_;
- decoded_body_length_ = data->decoded_body_length_;
-
- // Bug https://bugs.webkit.org/show_bug.cgi?id=60397 this doesn't support
- // whatever values may be present in the opaque m_extraData structure.
-}
-
ResourceResponse::ResourceResponse(const ResourceResponse&) = default;
ResourceResponse& ResourceResponse::operator=(const ResourceResponse&) =
default;
-std::unique_ptr<CrossThreadResourceResponseData> ResourceResponse::CopyData()
- const {
- std::unique_ptr<CrossThreadResourceResponseData> data =
- std::make_unique<CrossThreadResourceResponseData>();
- data->url_ = Url().Copy();
- data->mime_type_ = MimeType().GetString().IsolatedCopy();
- data->expected_content_length_ = ExpectedContentLength();
- data->text_encoding_name_ = TextEncodingName().GetString().IsolatedCopy();
- data->http_status_code_ = HttpStatusCode();
- data->http_status_text_ = HttpStatusText().GetString().IsolatedCopy();
- data->http_headers_ = HttpHeaderFields().CopyData();
- if (resource_load_timing_)
- data->resource_load_timing_ = resource_load_timing_->DeepCopy();
- data->remote_ip_address_ = remote_ip_address_.GetString().IsolatedCopy();
- data->remote_port_ = remote_port_;
- data->has_major_certificate_errors_ = has_major_certificate_errors_;
- data->ct_policy_compliance_ = ct_policy_compliance_;
- data->is_legacy_symantec_cert_ = is_legacy_symantec_cert_;
- data->cert_validity_start_ = cert_validity_start_;
- data->was_fetched_via_spdy_ = was_fetched_via_spdy_;
- data->was_fetched_via_proxy_ = was_fetched_via_proxy_;
- data->was_fetched_via_service_worker_ = was_fetched_via_service_worker_;
- data->was_fallback_required_by_service_worker_ =
- was_fallback_required_by_service_worker_;
- data->did_service_worker_navigation_preload_ =
- did_service_worker_navigation_preload_;
- data->async_revalidation_requested_ = async_revalidation_requested_;
- data->response_type_via_service_worker_ = response_type_via_service_worker_;
- data->security_style_ = security_style_;
- data->security_details_.protocol = security_details_.protocol.IsolatedCopy();
- data->security_details_.cipher = security_details_.cipher.IsolatedCopy();
- data->security_details_.key_exchange =
- security_details_.key_exchange.IsolatedCopy();
- data->security_details_.key_exchange_group =
- security_details_.key_exchange_group.IsolatedCopy();
- data->security_details_.mac = security_details_.mac.IsolatedCopy();
- data->security_details_.subject_name =
- security_details_.subject_name.IsolatedCopy();
- data->security_details_.san_list = IsolatedCopy(security_details_.san_list);
- data->security_details_.issuer = security_details_.issuer.IsolatedCopy();
- data->security_details_.valid_from = security_details_.valid_from;
- data->security_details_.valid_to = security_details_.valid_to;
- for (auto& cert : security_details_.certificate)
- data->certificate_.push_back(cert.GetString().IsolatedCopy());
- data->security_details_.sct_list = IsolatedCopy(security_details_.sct_list);
- data->http_version_ = http_version_;
- data->app_cache_id_ = app_cache_id_;
- data->app_cache_manifest_url_ = app_cache_manifest_url_.Copy();
- data->multipart_boundary_ = multipart_boundary_;
- data->url_list_via_service_worker_.resize(
- url_list_via_service_worker_.size());
- std::transform(url_list_via_service_worker_.begin(),
- url_list_via_service_worker_.end(),
- data->url_list_via_service_worker_.begin(),
- [](const KURL& url) { return url.Copy(); });
- data->cache_storage_cache_name_ = CacheStorageCacheName().IsolatedCopy();
- data->response_time_ = response_time_;
- data->encoded_data_length_ = encoded_data_length_;
- data->encoded_body_length_ = encoded_body_length_;
- data->decoded_body_length_ = decoded_body_length_;
-
- // Bug https://bugs.webkit.org/show_bug.cgi?id=60397 this doesn't support
- // whatever values may be present in the opaque m_extraData structure.
-
- return data;
-}
-
bool ResourceResponse::IsHTTP() const {
return url_.ProtocolIsInHTTPFamily();
}
@@ -534,7 +410,7 @@ void ResourceResponse::SetCTPolicyCompliance(CTPolicyCompliance compliance) {
}
bool ResourceResponse::IsOpaqueResponseFromServiceWorker() const {
- switch (response_type_via_service_worker_) {
+ switch (response_type_) {
case network::mojom::FetchResponseType::kBasic:
case network::mojom::FetchResponseType::kCORS:
case network::mojom::FetchResponseType::kDefault:
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 05ba71260d8..d5b85d476b4 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
@@ -49,17 +49,12 @@
namespace blink {
-struct CrossThreadResourceResponseData;
-
// A ResourceResponse is a "response" object used in blink. Conceptually
// it is https://fetch.spec.whatwg.org/#concept-response, but it contains
// a lot of blink specific fields. WebURLResponse is the "public version"
// of this class and public classes (i.e., classes in public/platform) use it.
//
-// There are cases where we need to copy a response across threads, and
-// CrossThreadResourceResponseData is a struct for the purpose. When you add a
-// member variable to this class, do not forget to add the corresponding
-// one in CrossThreadResourceResponseData and write copying logic.
+// This class is thread-bound. Do not copy/pass an instance across threads.
class PLATFORM_EXPORT ResourceResponse final {
public:
enum HTTPVersion : uint8_t {
@@ -147,11 +142,6 @@ class PLATFORM_EXPORT ResourceResponse final {
virtual ~ExtraData() = default;
};
- explicit ResourceResponse(CrossThreadResourceResponseData*);
-
- // Gets a copy of the data suitable for passing to another thread.
- std::unique_ptr<CrossThreadResourceResponseData> CopyData() const;
-
ResourceResponse();
explicit ResourceResponse(
const KURL&,
@@ -306,12 +296,9 @@ class PLATFORM_EXPORT ResourceResponse final {
was_fallback_required_by_service_worker_ = value;
}
- network::mojom::FetchResponseType ResponseTypeViaServiceWorker() const {
- return response_type_via_service_worker_;
- }
- void SetResponseTypeViaServiceWorker(
- network::mojom::FetchResponseType value) {
- response_type_via_service_worker_ = value;
+ network::mojom::FetchResponseType GetType() const { return response_type_; }
+ void SetType(network::mojom::FetchResponseType value) {
+ response_type_ = value;
}
bool IsOpaqueResponseFromServiceWorker() const;
@@ -466,9 +453,6 @@ class PLATFORM_EXPORT ResourceResponse final {
// Was the resource fetched over SPDY. See http://dev.chromium.org/spdy
bool was_fetched_via_spdy_ = false;
- // Was the resource fetched over an explicit proxy (HTTP, SOCKS, etc).
- bool was_fetched_via_proxy_ = false;
-
// Was the resource fetched over a ServiceWorker.
bool was_fetched_via_service_worker_ = false;
@@ -483,8 +467,8 @@ class PLATFORM_EXPORT ResourceResponse final {
// possibly be set if the load_flags indicated SUPPORT_ASYNC_REVALIDATION.
bool async_revalidation_requested_ = false;
- // The type of the response which was returned by the ServiceWorker.
- network::mojom::FetchResponseType response_type_via_service_worker_ =
+ // https://fetch.spec.whatwg.org/#concept-response-type
+ network::mojom::FetchResponseType response_type_ =
network::mojom::FetchResponseType::kDefault;
// HTTP version used in the response, if known.
@@ -569,58 +553,6 @@ inline bool operator!=(const ResourceResponse& a, const ResourceResponse& b) {
return !(a == b);
}
-// This class is needed to copy a ResourceResponse across threads, because it
-// has some members which cannot be transferred across threads (AtomicString
-// for example).
-// There are some rules / restrictions:
-// - This struct cannot contain an object that cannot be transferred across
-// threads (e.g., AtomicString)
-// - Non-simple members need explicit copying (e.g., String::IsolatedCopy,
-// KURL::Copy) rather than the copy constructor or the assignment operator.
-struct CrossThreadResourceResponseData {
- WTF_MAKE_NONCOPYABLE(CrossThreadResourceResponseData);
- USING_FAST_MALLOC(CrossThreadResourceResponseData);
-
- public:
- CrossThreadResourceResponseData() = default;
- KURL url_;
- String mime_type_;
- long long expected_content_length_;
- String text_encoding_name_;
- int http_status_code_;
- String http_status_text_;
- std::unique_ptr<CrossThreadHTTPHeaderMapData> http_headers_;
- scoped_refptr<ResourceLoadTiming> resource_load_timing_;
- bool has_major_certificate_errors_;
- ResourceResponse::CTPolicyCompliance ct_policy_compliance_;
- bool is_legacy_symantec_cert_;
- base::Time cert_validity_start_;
- ResourceResponse::SecurityStyle security_style_;
- ResourceResponse::SecurityDetails security_details_;
- // This is |certificate| from SecurityDetails since that structure should
- // use an AtomicString but this temporary structure is sent across threads.
- Vector<String> certificate_;
- ResourceResponse::HTTPVersion http_version_;
- long long app_cache_id_;
- KURL app_cache_manifest_url_;
- Vector<char> multipart_boundary_;
- bool was_fetched_via_spdy_;
- bool was_fetched_via_proxy_;
- bool was_fetched_via_service_worker_;
- bool was_fallback_required_by_service_worker_;
- network::mojom::FetchResponseType response_type_via_service_worker_;
- Vector<KURL> url_list_via_service_worker_;
- String cache_storage_cache_name_;
- bool did_service_worker_navigation_preload_;
- bool async_revalidation_requested_;
- Time response_time_;
- String remote_ip_address_;
- unsigned short remote_port_;
- long long encoded_data_length_;
- long long encoded_body_length_;
- long long decoded_body_length_;
-};
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_RESOURCE_RESPONSE_H_
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_timing_info.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_timing_info.cc
index 31574cfc049..a01ad9317e1 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_timing_info.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_timing_info.cc
@@ -5,45 +5,9 @@
#include "third_party/blink/renderer/platform/loader/fetch/resource_timing_info.h"
#include <memory>
-#include "third_party/blink/renderer/platform/cross_thread_copier.h"
namespace blink {
-scoped_refptr<ResourceTimingInfo> ResourceTimingInfo::Adopt(
- std::unique_ptr<CrossThreadResourceTimingInfoData> data) {
- scoped_refptr<ResourceTimingInfo> info = ResourceTimingInfo::Create(
- AtomicString(data->type_), data->initial_time_, data->is_main_resource_);
- info->original_timing_allow_origin_ =
- AtomicString(data->original_timing_allow_origin_);
- info->load_finish_time_ = data->load_finish_time_;
- info->initial_url_ = data->initial_url_.Copy();
- info->final_response_ = ResourceResponse(data->final_response_.get());
- for (auto& response_data : data->redirect_chain_)
- info->redirect_chain_.push_back(ResourceResponse(response_data.get()));
- info->transfer_size_ = data->transfer_size_;
- info->negative_allowed_ = data->negative_allowed_;
- return info;
-}
-
-std::unique_ptr<CrossThreadResourceTimingInfoData>
-ResourceTimingInfo::CopyData() const {
- std::unique_ptr<CrossThreadResourceTimingInfoData> data =
- std::make_unique<CrossThreadResourceTimingInfoData>();
- data->type_ = type_.GetString().IsolatedCopy();
- data->original_timing_allow_origin_ =
- original_timing_allow_origin_.GetString().IsolatedCopy();
- data->initial_time_ = initial_time_;
- data->load_finish_time_ = load_finish_time_;
- data->initial_url_ = initial_url_.Copy();
- data->final_response_ = final_response_.CopyData();
- for (const auto& response : redirect_chain_)
- data->redirect_chain_.push_back(response.CopyData());
- data->transfer_size_ = transfer_size_;
- data->is_main_resource_ = is_main_resource_;
- data->negative_allowed_ = negative_allowed_;
- return data;
-}
-
void ResourceTimingInfo::AddRedirect(const ResourceResponse& redirect_response,
bool cross_origin) {
redirect_chain_.push_back(redirect_response);
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 afff3bffdc2..eba60765dc0 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
@@ -32,7 +32,6 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_RESOURCE_TIMING_INFO_H_
#include <memory>
-#include "third_party/blink/renderer/platform/cross_thread_copier.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/wtf/allocator.h"
@@ -43,8 +42,6 @@
namespace blink {
-struct CrossThreadResourceTimingInfoData;
-
class PLATFORM_EXPORT ResourceTimingInfo
: public RefCounted<ResourceTimingInfo> {
USING_FAST_MALLOC(ResourceTimingInfo);
@@ -56,12 +53,6 @@ class PLATFORM_EXPORT ResourceTimingInfo
bool is_main_resource) {
return base::AdoptRef(new ResourceTimingInfo(type, time, is_main_resource));
}
- static scoped_refptr<ResourceTimingInfo> Adopt(
- std::unique_ptr<CrossThreadResourceTimingInfoData>);
-
- // Gets a copy of the data suitable for passing to another thread.
- std::unique_ptr<CrossThreadResourceTimingInfoData> CopyData() const;
-
TimeTicks InitialTime() const { return initial_time_; }
bool IsMainResource() const { return is_main_resource_; }
@@ -133,34 +124,6 @@ class PLATFORM_EXPORT ResourceTimingInfo
bool negative_allowed_ = false;
};
-struct CrossThreadResourceTimingInfoData {
- WTF_MAKE_NONCOPYABLE(CrossThreadResourceTimingInfoData);
- USING_FAST_MALLOC(CrossThreadResourceTimingInfoData);
-
- public:
- CrossThreadResourceTimingInfoData() = default;
-
- String type_;
- String original_timing_allow_origin_;
- TimeTicks initial_time_;
- TimeTicks load_finish_time_;
- KURL initial_url_;
- std::unique_ptr<CrossThreadResourceResponseData> final_response_;
- Vector<std::unique_ptr<CrossThreadResourceResponseData>> redirect_chain_;
- long long transfer_size_;
- bool is_main_resource_;
- bool negative_allowed_;
-};
-
-template <>
-struct CrossThreadCopier<ResourceTimingInfo> {
- typedef WTF::PassedWrapper<std::unique_ptr<CrossThreadResourceTimingInfoData>>
- Type;
- static Type Copy(const ResourceTimingInfo& info) {
- return WTF::Passed(info.CopyData());
- }
-};
-
} // namespace blink
#endif
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
new file mode 100644
index 00000000000..db7ad35c8f5
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/script_cached_metadata_handler.cc
@@ -0,0 +1,75 @@
+// 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/loader/fetch/script_cached_metadata_handler.h"
+
+#include "third_party/blink/renderer/platform/loader/fetch/cached_metadata.h"
+#include "third_party/blink/renderer/platform/loader/fetch/resource.h"
+
+namespace blink {
+
+ScriptCachedMetadataHandler::ScriptCachedMetadataHandler(
+ const WTF::TextEncoding& encoding,
+ std::unique_ptr<CachedMetadataSender> sender)
+ : sender_(std::move(sender)), encoding_(encoding) {}
+
+void ScriptCachedMetadataHandler::Trace(blink::Visitor* visitor) {
+ CachedMetadataHandler::Trace(visitor);
+}
+
+void ScriptCachedMetadataHandler::SetCachedMetadata(
+ uint32_t data_type_id,
+ const char* 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.
+ DCHECK(!cached_metadata_);
+ cached_metadata_ = CachedMetadata::Create(data_type_id, data, size);
+ if (cache_type == CachedMetadataHandler::kSendToPlatform)
+ SendToPlatform();
+}
+
+void ScriptCachedMetadataHandler::ClearCachedMetadata(
+ CachedMetadataHandler::CacheType cache_type) {
+ cached_metadata_ = nullptr;
+ if (cache_type == CachedMetadataHandler::kSendToPlatform)
+ SendToPlatform();
+}
+
+scoped_refptr<CachedMetadata> ScriptCachedMetadataHandler::GetCachedMetadata(
+ uint32_t data_type_id) const {
+ if (!cached_metadata_ || cached_metadata_->DataTypeID() != data_type_id)
+ return nullptr;
+ return cached_metadata_;
+}
+
+void ScriptCachedMetadataHandler::SetSerializedCachedMetadata(const char* data,
+ size_t size) {
+ // We only expect to receive cached metadata from the platform once. If this
+ // triggers, it indicates an efficiency problem which is most likely
+ // unexpected in code designed to improve performance.
+ DCHECK(!cached_metadata_);
+ cached_metadata_ = CachedMetadata::CreateFromSerializedData(data, size);
+}
+
+String ScriptCachedMetadataHandler::Encoding() const {
+ return String(encoding_.GetName());
+}
+
+bool ScriptCachedMetadataHandler::IsServedFromCacheStorage() const {
+ return sender_->IsServedFromCacheStorage();
+}
+
+void ScriptCachedMetadataHandler::SendToPlatform() {
+ if (cached_metadata_) {
+ const Vector<char>& serialized_data = cached_metadata_->SerializedData();
+ sender_->Send(serialized_data.data(), serialized_data.size());
+ } else {
+ sender_->Send(nullptr, 0);
+ }
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..a30fb19797d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/script_cached_metadata_handler.h
@@ -0,0 +1,65 @@
+// 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_LOADER_FETCH_SCRIPT_CACHED_METADATA_HANDLER_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_SCRIPT_CACHED_METADATA_HANDLER_H_
+
+#include <memory>
+
+#include "third_party/blink/renderer/platform/bindings/parkable_string.h"
+#include "third_party/blink/renderer/platform/loader/fetch/cached_metadata_handler.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/forward.h"
+#include "third_party/blink/renderer/platform/wtf/text/text_encoding.h"
+
+namespace blink {
+
+class CachedMetadata;
+class CachedMetadataSender;
+
+// ScriptCachedMetadataHandler should be created when a response is received,
+// and can be used independently from its Resource.
+// - It doesn't have any references to the Resource. Necessary data are captured
+// from the Resource when the handler is created.
+// - It is not affected by Resource's revalidation on MemoryCache. The validity
+// of the handler is solely checked by |response_url_| and |response_time_|
+// (not by Resource) by the browser process, and the cached metadata written to
+// the handler is rejected if e.g. the disk cache entry has been updated and the
+// handler refers to an older response.
+class PLATFORM_EXPORT ScriptCachedMetadataHandler final
+ : public SingleCachedMetadataHandler {
+ public:
+ ScriptCachedMetadataHandler(const WTF::TextEncoding&,
+ std::unique_ptr<CachedMetadataSender>);
+ ~ScriptCachedMetadataHandler() override = default;
+ void Trace(blink::Visitor*) override;
+ void SetCachedMetadata(uint32_t, const char*, size_t, CacheType) override;
+ void ClearCachedMetadata(CacheType) override;
+ scoped_refptr<CachedMetadata> GetCachedMetadata(uint32_t) const override;
+
+ // This returns the encoding at the time of ResponseReceived(). Therefore this
+ // does NOT reflect encoding detection from body contents, but the actual
+ // encoding after the encoding detection can be determined uniquely from
+ // Encoding(), provided the body content is the same, as we can assume the
+ // encoding detection will result in the same final encoding.
+ // TODO(hiroshige): Make these semantics cleaner.
+ String Encoding() const override;
+
+ bool IsServedFromCacheStorage() const override;
+
+ // Sets the serialized metadata retrieved from the platform's cache.
+ void SetSerializedCachedMetadata(const char*, size_t);
+
+ private:
+ void SendToPlatform();
+
+ scoped_refptr<CachedMetadata> cached_metadata_;
+ std::unique_ptr<CachedMetadataSender> sender_;
+
+ const WTF::TextEncoding encoding_;
+};
+
+} // 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 ed49f458a6a..f5538849ca0 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
@@ -53,9 +53,12 @@ FetchParameters ScriptFetchOptions::CreateFetchParameters(
params.MutableResourceRequest().SetFetchIntegrity(
GetIntegrityAttributeValue());
- // and its parser metadata to options's parser metadata. [spec text]
+ // its parser metadata to options's parser metadata, [spec text]
params.SetParserDisposition(ParserState());
+ // its referrer policy to options's referrer policy. [spec text]
+ params.MutableResourceRequest().SetReferrerPolicy(referrer_policy_);
+
params.SetCharset(encoding);
// This DeferOption logic is only for classic scripts, as we always set
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 929caf2ff7d..81f640afc44 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
@@ -271,11 +271,9 @@ class SubresourceIntegrityTest : public testing::Test {
response.SetWasFetchedViaServiceWorker(true);
if (service_worker_mode == kSWOpaqueResponse) {
- response.SetResponseTypeViaServiceWorker(
- network::mojom::FetchResponseType::kOpaque);
+ response.SetType(network::mojom::FetchResponseType::kOpaque);
} else {
- response.SetResponseTypeViaServiceWorker(
- network::mojom::FetchResponseType::kDefault);
+ response.SetType(network::mojom::FetchResponseType::kDefault);
}
}
diff --git a/chromium/third_party/blink/renderer/platform/loader/testing/fetch_testing_platform_support.cc b/chromium/third_party/blink/renderer/platform/loader/testing/fetch_testing_platform_support.cc
index 5bf93981f03..0938f6fb4e4 100644
--- a/chromium/third_party/blink/renderer/platform/loader/testing/fetch_testing_platform_support.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/testing/fetch_testing_platform_support.cc
@@ -30,8 +30,7 @@ FetchTestingPlatformSupport::~FetchTestingPlatformSupport() {
MockFetchContext* FetchTestingPlatformSupport::Context() {
if (!context_) {
context_ =
- MockFetchContext::Create(MockFetchContext::kShouldLoadNewResource,
- scheduler_->DefaultTaskRunner());
+ MockFetchContext::Create(MockFetchContext::kShouldLoadNewResource);
}
return context_;
}
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 a2e6067e25c..925d16a2818 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
@@ -74,7 +74,6 @@ class MockFetchContext : public FetchContext {
const KURL&,
const ResourceLoaderOptions&,
SecurityViolationReportingPolicy,
- FetchParameters::OriginRestriction,
ResourceRequest::RedirectStatus redirect_status) const override {
return base::nullopt;
}
diff --git a/chromium/third_party/blink/renderer/platform/mac/theme_mac.mm b/chromium/third_party/blink/renderer/platform/mac/theme_mac.mm
index b5308fdeeed..50f2f9ebf2b 100644
--- a/chromium/third_party/blink/renderer/platform/mac/theme_mac.mm
+++ b/chromium/third_party/blink/renderer/platform/mac/theme_mac.mm
@@ -31,7 +31,6 @@
#import "third_party/blink/renderer/platform/mac/local_current_graphics_context.h"
#import "third_party/blink/renderer/platform/mac/version_util_mac.h"
#import "third_party/blink/renderer/platform/mac/web_core_ns_cell_extras.h"
-#import "third_party/blink/renderer/platform/scroll/scrollable_area.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
// This is a view whose sole purpose is to tell AppKit that it's flipped.
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 dfc765b830d..2c138540fd4 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
@@ -103,10 +103,6 @@ class PLATFORM_EXPORT MediaStreamSource final
bool auto_gain_control,
bool noise_supression);
- void SetConstraints(WebMediaConstraints constraints) {
- constraints_ = constraints;
- }
- WebMediaConstraints Constraints() { return constraints_; }
void GetSettings(WebMediaStreamTrack::Settings&);
const WebMediaStreamSource::Capabilities& GetCapabilities() {
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 6dfcdcb1580..193acba1a6e 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/blink_typemaps.gni
+++ b/chromium/third_party/blink/renderer/platform/mojo/blink_typemaps.gni
@@ -6,6 +6,7 @@ typemaps = [
"//mojo/public/cpp/base/file_info.typemap",
"//mojo/public/cpp/base/file_path.typemap",
"//mojo/public/cpp/base/shared_memory.typemap",
+ "//mojo/public/cpp/base/unguessable_token.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/platform/blob/serialized_blob.typemap",
@@ -21,7 +22,6 @@ typemaps = [
"//third_party/blink/renderer/platform/mojo/time.typemap",
"//third_party/blink/public/platform/modules/bluetooth/bluetooth.typemap",
"//third_party/blink/public/platform/modules/fetch/fetch_api_request.typemap",
- "//third_party/blink/public/platform/modules/notifications/notification_types.typemap",
"//third_party/blink/public/common/manifest/display_mode.typemap",
"//third_party/blink/public/common/screen_orientation/screen_orientation_lock_types.typemap",
]
diff --git a/chromium/third_party/blink/renderer/platform/mojo/geometry_struct_traits_test.cc b/chromium/third_party/blink/renderer/platform/mojo/geometry_struct_traits_test.cc
index fb7c72414df..46a82b78b33 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/geometry_struct_traits_test.cc
+++ b/chromium/third_party/blink/renderer/platform/mojo/geometry_struct_traits_test.cc
@@ -37,6 +37,12 @@ class GeometryStructTraitsTest
std::move(callback).Run(p);
}
+ void EchoPoint3F(::gfx::mojom::blink::Point3FPtr p,
+ EchoPoint3FCallback callback) override {
+ // The type map is not specified.
+ NOTREACHED();
+ }
+
void EchoSize(const WebSize& s, EchoSizeCallback callback) override {
std::move(callback).Run(s);
}
@@ -77,6 +83,12 @@ class GeometryStructTraitsTest
NOTREACHED();
}
+ void EchoVector3dF(gfx::mojom::blink::Vector3dFPtr,
+ EchoVector3dFCallback) override {
+ // The type map is not specified.
+ NOTREACHED();
+ }
+
mojo::BindingSet<gfx::mojom::blink::GeometryTraitsTestService>
traits_test_bindings_;
diff --git a/chromium/third_party/blink/renderer/platform/mojo/interface_invalidator.h b/chromium/third_party/blink/renderer/platform/mojo/interface_invalidator.h
index 6a65fe2e8ca..50028aa9efe 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/interface_invalidator.h
+++ b/chromium/third_party/blink/renderer/platform/mojo/interface_invalidator.h
@@ -32,7 +32,7 @@ class PLATFORM_EXPORT InterfaceInvalidator {
private:
void NotifyInvalidate();
- base::ObserverList<Observer> observers_;
+ base::ObserverList<Observer>::Unchecked observers_;
base::WeakPtrFactory<InterfaceInvalidator> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(InterfaceInvalidator);
diff --git a/chromium/third_party/blink/renderer/platform/mojo/interface_invalidator_test.cc b/chromium/third_party/blink/renderer/platform/mojo/interface_invalidator_test.cc
index cc25bde800b..f10727bc6fe 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/interface_invalidator_test.cc
+++ b/chromium/third_party/blink/renderer/platform/mojo/interface_invalidator_test.cc
@@ -34,14 +34,14 @@ class PingServiceImplBase : public mojo::test::blink::PingService {
~PingServiceImplBase() override {}
// mojo::test::blink::PingService:
- void Ping(const PingCallback& callback) override {
+ void Ping(PingCallback callback) override {
if (ping_handler_)
ping_handler_.Run();
if (send_response_) {
- callback.Run();
+ std::move(callback).Run();
} else {
- saved_callback_ = callback;
+ saved_callback_ = std::move(callback);
}
if (post_ping_handler_)
diff --git a/chromium/third_party/blink/renderer/platform/mojo/notification_struct_traits.cc b/chromium/third_party/blink/renderer/platform/mojo/notification_struct_traits.cc
deleted file mode 100644
index 5cd6623fa3a..00000000000
--- a/chromium/third_party/blink/renderer/platform/mojo/notification_struct_traits.cc
+++ /dev/null
@@ -1,287 +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/mojo/notification_struct_traits.h"
-
-#include <iterator>
-
-namespace mojo {
-
-using blink::mojom::NotificationDirection;
-using blink::mojom::NotificationActionType;
-
-// static
-NotificationDirection
-EnumTraits<NotificationDirection, blink::WebNotificationData::Direction>::
- ToMojom(blink::WebNotificationData::Direction input) {
- switch (input) {
- case blink::WebNotificationData::kDirectionLeftToRight:
- return NotificationDirection::LEFT_TO_RIGHT;
- case blink::WebNotificationData::kDirectionRightToLeft:
- return NotificationDirection::RIGHT_TO_LEFT;
- case blink::WebNotificationData::kDirectionAuto:
- return NotificationDirection::AUTO;
- }
-
- NOTREACHED();
- return NotificationDirection::AUTO;
-}
-
-// static
-bool EnumTraits<NotificationDirection, blink::WebNotificationData::Direction>::
- FromMojom(NotificationDirection input,
- blink::WebNotificationData::Direction* out) {
- switch (input) {
- case NotificationDirection::LEFT_TO_RIGHT:
- *out = blink::WebNotificationData::kDirectionLeftToRight;
- return true;
- case NotificationDirection::RIGHT_TO_LEFT:
- *out = blink::WebNotificationData::kDirectionRightToLeft;
- return true;
- case NotificationDirection::AUTO:
- *out = blink::WebNotificationData::kDirectionAuto;
- return true;
- }
-
- return false;
-}
-
-// static
-NotificationActionType
-EnumTraits<NotificationActionType, blink::WebNotificationAction::Type>::ToMojom(
- blink::WebNotificationAction::Type input) {
- switch (input) {
- case blink::WebNotificationAction::kButton:
- return NotificationActionType::BUTTON;
- case blink::WebNotificationAction::kText:
- return NotificationActionType::TEXT;
- }
-
- NOTREACHED();
- return NotificationActionType::BUTTON;
-}
-
-// static
-bool EnumTraits<NotificationActionType, blink::WebNotificationAction::Type>::
- FromMojom(NotificationActionType input,
- blink::WebNotificationAction::Type* out) {
- switch (input) {
- case NotificationActionType::BUTTON:
- *out = blink::WebNotificationAction::kButton;
- return true;
- case NotificationActionType::TEXT:
- *out = blink::WebNotificationAction::kText;
- return true;
- }
-
- return false;
-}
-
-// static
-WTF::String StructTraits<blink::mojom::NotificationActionDataView,
- blink::WebNotificationAction>::
- action(const blink::WebNotificationAction& action) {
- return action.action;
-}
-
-// static
-WTF::String StructTraits<blink::mojom::NotificationActionDataView,
- blink::WebNotificationAction>::
- title(const blink::WebNotificationAction& action) {
- return action.title;
-}
-
-// static
-blink::KURL StructTraits<blink::mojom::NotificationActionDataView,
- blink::WebNotificationAction>::
- icon(const blink::WebNotificationAction& action) {
- return action.icon;
-}
-
-// static
-WTF::String StructTraits<blink::mojom::NotificationActionDataView,
- blink::WebNotificationAction>::
- placeholder(const blink::WebNotificationAction& action) {
- return action.placeholder;
-}
-
-// static
-bool StructTraits<blink::mojom::NotificationActionDataView,
- blink::WebNotificationAction>::
- Read(blink::mojom::NotificationActionDataView notification_action,
- blink::WebNotificationAction* out) {
- WTF::String action;
- WTF::String title;
- blink::KURL icon;
- WTF::String placeholder;
-
- if (!notification_action.ReadType(&out->type) ||
- !notification_action.ReadTitle(&title) ||
- !notification_action.ReadAction(&action) ||
- !notification_action.ReadIcon(&icon) ||
- !notification_action.ReadPlaceholder(&placeholder)) {
- return false;
- }
-
- out->action = action;
- out->title = title;
- out->icon = icon;
- out->placeholder = placeholder;
- return true;
-}
-
-// static
-WTF::String StructTraits<
- blink::mojom::NotificationDataDataView,
- blink::WebNotificationData>::title(const blink::WebNotificationData& data) {
- return data.title;
-}
-
-// static
-WTF::String StructTraits<
- blink::mojom::NotificationDataDataView,
- blink::WebNotificationData>::lang(const blink::WebNotificationData& data) {
- return data.lang;
-}
-
-// static
-WTF::String StructTraits<
- blink::mojom::NotificationDataDataView,
- blink::WebNotificationData>::body(const blink::WebNotificationData& data) {
- return data.body;
-}
-
-// static
-WTF::String StructTraits<
- blink::mojom::NotificationDataDataView,
- blink::WebNotificationData>::tag(const blink::WebNotificationData& data) {
- return data.tag;
-}
-
-// static
-blink::KURL StructTraits<
- blink::mojom::NotificationDataDataView,
- blink::WebNotificationData>::image(const blink::WebNotificationData& data) {
- return data.image;
-}
-
-// static
-blink::KURL StructTraits<
- blink::mojom::NotificationDataDataView,
- blink::WebNotificationData>::icon(const blink::WebNotificationData& data) {
- return data.icon;
-}
-
-// static
-blink::KURL StructTraits<
- blink::mojom::NotificationDataDataView,
- blink::WebNotificationData>::badge(const blink::WebNotificationData& data) {
- return data.badge;
-}
-
-// static
-base::span<const int32_t> StructTraits<blink::mojom::NotificationDataDataView,
- blink::WebNotificationData>::
- vibration_pattern(const blink::WebNotificationData& data) {
- // TODO(https://crbug.com/798466): Align data types to avoid this cast.
- return base::make_span(reinterpret_cast<const int32_t*>(data.vibrate.Data()),
- data.vibrate.size());
-}
-
-// static
-base::span<const blink::WebNotificationAction> StructTraits<
- blink::mojom::NotificationDataDataView,
- blink::WebNotificationData>::actions(const blink::WebNotificationData&
- data) {
- return base::make_span(data.actions.Data(), data.actions.size());
-}
-
-// static
-base::span<const int8_t> StructTraits<
- blink::mojom::NotificationDataDataView,
- blink::WebNotificationData>::data(const blink::WebNotificationData& data) {
- // TODO(https://crbug.com/798466): Align data types to avoid this cast.
- return base::make_span(reinterpret_cast<const int8_t*>(data.data.Data()),
- data.data.size());
-}
-
-// static
-bool StructTraits<blink::mojom::NotificationDataDataView,
- blink::WebNotificationData>::
- Read(blink::mojom::NotificationDataDataView notification_data,
- blink::WebNotificationData* out) {
- // We can't read these values to the |out| type directly because it relies
- // on Web* types, whereas Mojo uses the regular WTF types. This will be
- // solved when the Web* types are removed as part of the Onion Soup refactor.
- WTF::String title;
- WTF::String lang;
- WTF::String body;
- WTF::String tag;
-
- blink::KURL image;
- blink::KURL icon;
- blink::KURL badge;
- Vector<int32_t> vibrate;
- Vector<int8_t> data;
- Vector<blink::WebNotificationAction> actions;
-
- if (!notification_data.ReadTitle(&title) ||
- !notification_data.ReadDirection(&out->direction) ||
- !notification_data.ReadLang(&lang) ||
- !notification_data.ReadBody(&body) || !notification_data.ReadTag(&tag) ||
- !notification_data.ReadImage(&image) ||
- !notification_data.ReadIcon(&icon) ||
- !notification_data.ReadBadge(&badge) ||
- !notification_data.ReadVibrationPattern(&vibrate) ||
- !notification_data.ReadData(&data) ||
- !notification_data.ReadActions(&actions)) {
- return false;
- }
-
- out->title = title;
- out->lang = lang;
- out->body = body;
- out->tag = tag;
- out->image = image;
- out->icon = icon;
- out->badge = badge;
- out->vibrate = vibrate;
- out->timestamp = notification_data.timestamp();
- out->renotify = notification_data.renotify();
- out->silent = notification_data.silent();
- out->require_interaction = notification_data.require_interaction();
- out->data = data;
- out->actions = actions;
- return true;
-}
-
-// static
-base::span<const SkBitmap>
-StructTraits<blink::mojom::NotificationResourcesDataView,
- blink::WebNotificationResources>::
- action_icons(const blink::WebNotificationResources& resources) {
- return base::make_span(resources.action_icons.Data(),
- resources.action_icons.size());
-}
-
-// static
-bool StructTraits<blink::mojom::NotificationResourcesDataView,
- blink::WebNotificationResources>::
- Read(blink::mojom::NotificationResourcesDataView notification_resources,
- blink::WebNotificationResources* out) {
- // Cannot read to |out| directly because it expects a WebVector (see above).
- Vector<SkBitmap> action_icons;
-
- if (!notification_resources.ReadImage(&out->image) ||
- !notification_resources.ReadIcon(&out->icon) ||
- !notification_resources.ReadBadge(&out->badge) ||
- !notification_resources.ReadActionIcons(&action_icons)) {
- return false;
- }
-
- out->action_icons = action_icons;
- return true;
-}
-
-} // namespace mojo
diff --git a/chromium/third_party/blink/renderer/platform/mojo/notification_struct_traits.h b/chromium/third_party/blink/renderer/platform/mojo/notification_struct_traits.h
deleted file mode 100644
index ac67fd10220..00000000000
--- a/chromium/third_party/blink/renderer/platform/mojo/notification_struct_traits.h
+++ /dev/null
@@ -1,140 +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_MOJO_NOTIFICATION_STRUCT_TRAITS_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_NOTIFICATION_STRUCT_TRAITS_H_
-
-#include "base/containers/span.h"
-#include "mojo/public/cpp/bindings/array_traits_wtf_vector.h"
-#include "mojo/public/cpp/bindings/string_traits_wtf.h"
-#include "skia/public/interfaces/bitmap_skbitmap_struct_traits.h"
-#include "third_party/blink/public/platform/modules/notifications/notification.mojom-blink.h"
-#include "third_party/blink/public/platform/modules/notifications/web_notification_action.h"
-#include "third_party/blink/renderer/platform/mojo/kurl_struct_traits.h"
-#include "third_party/blink/renderer/platform/mojo/string16_mojom_traits.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/wtf/text/wtf_string.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-
-namespace mojo {
-
-template <>
-struct PLATFORM_EXPORT EnumTraits<blink::mojom::NotificationDirection,
- blink::WebNotificationData::Direction> {
- static blink::mojom::NotificationDirection ToMojom(
- blink::WebNotificationData::Direction input);
-
- static bool FromMojom(blink::mojom::NotificationDirection input,
- blink::WebNotificationData::Direction* out);
-};
-
-template <>
-struct PLATFORM_EXPORT EnumTraits<blink::mojom::NotificationActionType,
- blink::WebNotificationAction::Type> {
- static blink::mojom::NotificationActionType ToMojom(
- blink::WebNotificationAction::Type input);
-
- static bool FromMojom(blink::mojom::NotificationActionType input,
- blink::WebNotificationAction::Type* out);
-};
-
-template <>
-struct PLATFORM_EXPORT StructTraits<blink::mojom::NotificationActionDataView,
- blink::WebNotificationAction> {
- static blink::WebNotificationAction::Type type(
- const blink::WebNotificationAction& action) {
- return action.type;
- }
-
- static WTF::String action(const blink::WebNotificationAction&);
-
- static WTF::String title(const blink::WebNotificationAction&);
-
- static blink::KURL icon(const blink::WebNotificationAction&);
-
- static WTF::String placeholder(const blink::WebNotificationAction&);
-
- static bool Read(blink::mojom::NotificationActionDataView,
- blink::WebNotificationAction* output);
-};
-
-template <>
-struct PLATFORM_EXPORT StructTraits<blink::mojom::NotificationDataDataView,
- blink::WebNotificationData> {
- static WTF::String title(const blink::WebNotificationData&);
-
- static blink::WebNotificationData::Direction direction(
- const blink::WebNotificationData& data) {
- return data.direction;
- }
-
- static WTF::String lang(const blink::WebNotificationData&);
-
- static WTF::String body(const blink::WebNotificationData&);
-
- static WTF::String tag(const blink::WebNotificationData&);
-
- static blink::KURL image(const blink::WebNotificationData&);
-
- static blink::KURL icon(const blink::WebNotificationData&);
-
- static blink::KURL badge(const blink::WebNotificationData&);
-
- static base::span<const int32_t> vibration_pattern(
- const blink::WebNotificationData&);
-
- static double timestamp(const blink::WebNotificationData& data) {
- return data.timestamp;
- }
-
- static bool renotify(const blink::WebNotificationData& data) {
- return data.renotify;
- }
-
- static bool silent(const blink::WebNotificationData& data) {
- return data.silent;
- }
-
- static bool require_interaction(const blink::WebNotificationData& data) {
- return data.require_interaction;
- }
-
- static base::span<const int8_t> data(const blink::WebNotificationData&);
-
- static base::span<const blink::WebNotificationAction> actions(
- const blink::WebNotificationData&);
-
- static bool Read(blink::mojom::NotificationDataDataView,
- blink::WebNotificationData* output);
-};
-
-template <>
-struct PLATFORM_EXPORT StructTraits<blink::mojom::NotificationResourcesDataView,
- blink::WebNotificationResources> {
- static const SkBitmap& image(
- const blink::WebNotificationResources& resources) {
- return resources.image;
- }
-
- static const SkBitmap& icon(
- const blink::WebNotificationResources& resources) {
- return resources.icon;
- }
-
- static const SkBitmap& badge(
- const blink::WebNotificationResources& resources) {
- return resources.badge;
- }
-
- static base::span<const SkBitmap> action_icons(
- const blink::WebNotificationResources&);
-
- static bool Read(blink::mojom::NotificationResourcesDataView,
- blink::WebNotificationResources* output);
-};
-
-} // namespace mojo
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_NOTIFICATION_STRUCT_TRAITS_H_
diff --git a/chromium/third_party/blink/renderer/platform/mojo/notification_struct_traits_test.cc b/chromium/third_party/blink/renderer/platform/mojo/notification_struct_traits_test.cc
deleted file mode 100644
index e61ef3efb7d..00000000000
--- a/chromium/third_party/blink/renderer/platform/mojo/notification_struct_traits_test.cc
+++ /dev/null
@@ -1,176 +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/mojo/notification_struct_traits.h"
-
-#include <algorithm>
-
-#include "base/macros.h"
-#include "base/strings/stringprintf.h"
-#include "mojo/public/cpp/test_support/test_utils.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/modules/notifications/notification.mojom-blink.h"
-#include "third_party/blink/public/platform/modules/notifications/web_notification_data.h"
-#include "third_party/blink/public/platform/modules/notifications/web_notification_resources.h"
-#include "third_party/blink/public/platform/web_url.h"
-#include "third_party/blink/public/platform/web_vector.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "third_party/skia/include/core/SkColor.h"
-
-namespace blink {
-
-namespace {
-
-const char kNotificationBaseUrl[] = "https://example.com/directory/";
-
-SkBitmap CreateBitmap(int width, int height, SkColor color) {
- SkBitmap bitmap;
- bitmap.allocN32Pixels(width, height);
- bitmap.eraseColor(color);
- return bitmap;
-}
-
-// Returns true if |lhs| and |rhs| have the same width and height and the
-// pixel at position (0, 0) is the same color in both.
-bool ImagesShareDimensionsAndColor(const SkBitmap& lhs, const SkBitmap& rhs) {
- return lhs.width() == rhs.width() && lhs.height() == rhs.height() &&
- lhs.getColor(0, 0) == rhs.getColor(0, 0);
-}
-
-} // namespace
-
-TEST(NotificationStructTraitsTest, NotificationDataRoundtrip) {
- WebNotificationData notification_data;
- notification_data.title = "Notification Title";
- notification_data.direction = WebNotificationData::kDirectionRightToLeft;
- notification_data.lang = "foo-lang";
- notification_data.body = "Notification body...";
- notification_data.tag = "notificationTag";
-
- const KURL kBaseUrl(kNotificationBaseUrl);
- notification_data.image = WebURL(KURL(kBaseUrl, "noti_img.png"));
- notification_data.icon = WebURL(KURL(kBaseUrl, "noti_icon.png"));
- notification_data.badge = WebURL(KURL(kBaseUrl, "noti_badge.png"));
-
- const int vibrate[] = {200, 100, 300};
- WebVector<char> vibrate_vector(vibrate, arraysize(vibrate));
- notification_data.vibrate = vibrate_vector;
-
- notification_data.timestamp = 1513963983000.;
- notification_data.renotify = true;
- notification_data.silent = true;
- notification_data.require_interaction = true;
-
- const char data[] = "some binary data";
- WebVector<char> data_vector(data, arraysize(data));
- notification_data.data = data_vector;
-
- WebVector<blink::WebNotificationAction> actions(static_cast<size_t>(2));
-
- actions[0].type = blink::WebNotificationAction::kButton;
- actions[0].action = "my_button_click";
- actions[0].title = "Button Title";
- actions[0].icon = blink::WebURL(KURL(kBaseUrl, "button.png"));
-
- actions[1].type = blink::WebNotificationAction::kText;
- actions[1].action = "on_reply";
- actions[1].title = "Reply";
- actions[1].icon = blink::WebURL(KURL(kBaseUrl, "replyButton.png"));
- actions[1].placeholder = "placeholder...";
-
- notification_data.actions = actions;
-
- WebNotificationData roundtrip_notification_data;
-
- ASSERT_TRUE(mojom::blink::NotificationData::Deserialize(
- mojom::blink::NotificationData::Serialize(&notification_data),
- &roundtrip_notification_data));
-
- EXPECT_EQ(notification_data.title, roundtrip_notification_data.title);
- EXPECT_EQ(notification_data.direction, roundtrip_notification_data.direction);
- EXPECT_EQ(notification_data.lang, roundtrip_notification_data.lang);
- EXPECT_EQ(notification_data.tag, roundtrip_notification_data.tag);
- EXPECT_EQ(notification_data.image, roundtrip_notification_data.image);
- EXPECT_EQ(notification_data.icon, roundtrip_notification_data.icon);
- EXPECT_EQ(notification_data.badge, roundtrip_notification_data.badge);
-
- ASSERT_EQ(notification_data.vibrate.size(),
- roundtrip_notification_data.vibrate.size());
- EXPECT_TRUE(std::equal(notification_data.vibrate.begin(),
- notification_data.vibrate.end(),
- roundtrip_notification_data.vibrate.begin()));
-
- EXPECT_EQ(notification_data.timestamp, roundtrip_notification_data.timestamp);
- EXPECT_EQ(notification_data.renotify, roundtrip_notification_data.renotify);
- EXPECT_EQ(notification_data.silent, roundtrip_notification_data.silent);
- EXPECT_EQ(notification_data.require_interaction,
- roundtrip_notification_data.require_interaction);
-
- ASSERT_EQ(notification_data.data.size(),
- roundtrip_notification_data.data.size());
- EXPECT_TRUE(std::equal(notification_data.data.begin(),
- notification_data.data.end(),
- roundtrip_notification_data.data.begin()));
-
- ASSERT_EQ(notification_data.actions.size(),
- roundtrip_notification_data.actions.size());
- for (size_t i = 0; i < notification_data.actions.size(); ++i) {
- SCOPED_TRACE(base::StringPrintf("Action index: %zd", i));
- EXPECT_EQ(notification_data.actions[i].type,
- roundtrip_notification_data.actions[i].type);
- EXPECT_EQ(notification_data.actions[i].action,
- roundtrip_notification_data.actions[i].action);
- EXPECT_EQ(notification_data.actions[i].title,
- roundtrip_notification_data.actions[i].title);
- EXPECT_EQ(notification_data.actions[i].icon,
- roundtrip_notification_data.actions[i].icon);
- EXPECT_EQ(notification_data.actions[i].placeholder,
- roundtrip_notification_data.actions[i].placeholder);
- }
-}
-
-TEST(NotificationStructTraitsTest, NotificationResourcesRoundtrip) {
- WebNotificationResources resources;
-
- resources.image = CreateBitmap(300, 100, SK_ColorCYAN);
- resources.icon = CreateBitmap(80, 100, SK_ColorRED);
- resources.badge = CreateBitmap(50, 40, SK_ColorGREEN);
-
- WebVector<SkBitmap> action_icons(static_cast<size_t>(2));
- action_icons[0] = CreateBitmap(10, 10, SK_ColorLTGRAY);
- action_icons[1] = CreateBitmap(11, 11, SK_ColorDKGRAY);
-
- resources.action_icons = action_icons;
-
- WebNotificationResources roundtrip_resources;
-
- ASSERT_TRUE(
- mojo::test::SerializeAndDeserialize<mojom::blink::NotificationResources>(
- &resources, &roundtrip_resources));
-
- ASSERT_FALSE(roundtrip_resources.image.empty());
- EXPECT_TRUE(ImagesShareDimensionsAndColor(resources.image,
- roundtrip_resources.image));
-
- ASSERT_FALSE(roundtrip_resources.icon.empty());
- EXPECT_TRUE(
- ImagesShareDimensionsAndColor(resources.icon, roundtrip_resources.icon));
-
- ASSERT_FALSE(roundtrip_resources.badge.empty());
- EXPECT_TRUE(ImagesShareDimensionsAndColor(resources.badge,
- roundtrip_resources.badge));
-
- ASSERT_EQ(resources.action_icons.size(),
- roundtrip_resources.action_icons.size());
-
- for (size_t i = 0; i < roundtrip_resources.action_icons.size(); ++i) {
- SCOPED_TRACE(base::StringPrintf("Action icon index: %zd", i));
-
- ASSERT_FALSE(roundtrip_resources.action_icons[i].empty());
- EXPECT_TRUE(ImagesShareDimensionsAndColor(
- resources.action_icons[i], roundtrip_resources.action_icons[i]));
- }
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/network/DEPS b/chromium/third_party/blink/renderer/platform/network/DEPS
index 77af399ae9c..e31a6fc2b5b 100644
--- a/chromium/third_party/blink/renderer/platform/network/DEPS
+++ b/chromium/third_party/blink/renderer/platform/network/DEPS
@@ -25,8 +25,6 @@ include_rules = [
"+third_party/blink/renderer/platform/heap",
"+third_party/blink/renderer/platform/instrumentation",
"+third_party/blink/renderer/platform/loader",
- "+third_party/blink/renderer/platform/loader",
- "+third_party/blink/renderer/platform/loader",
"+third_party/blink/renderer/platform/platform_export.h",
"+third_party/blink/renderer/platform/scheduler",
"+third_party/blink/renderer/platform/shared_buffer.h",
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 50b795fd45f..2107d3cb0ac 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
@@ -66,4 +66,7 @@ STATIC_ASSERT_ENUM(kWebContentSecurityPolicySourceHTTP,
kContentSecurityPolicyHeaderSourceHTTP);
STATIC_ASSERT_ENUM(kWebContentSecurityPolicySourceMeta,
kContentSecurityPolicyHeaderSourceMeta);
+STATIC_ASSERT_ENUM(kWebContentSecurityPolicySourceOriginPolicy,
+ 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 0fb0dc51a1e..e352fa904e3 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
@@ -20,7 +20,8 @@ enum ContentSecurityPolicyHeaderType {
enum ContentSecurityPolicyHeaderSource {
kContentSecurityPolicyHeaderSourceHTTP,
- kContentSecurityPolicyHeaderSourceMeta
+ kContentSecurityPolicyHeaderSourceMeta,
+ kContentSecurityPolicyHeaderSourceOriginPolicy
};
enum ContentSecurityPolicyHashAlgorithm {
diff --git a/chromium/third_party/blink/renderer/platform/network/header_field_tokenizer.cc b/chromium/third_party/blink/renderer/platform/network/header_field_tokenizer.cc
index 7825946bf63..b48dfaf9288 100644
--- a/chromium/third_party/blink/renderer/platform/network/header_field_tokenizer.cc
+++ b/chromium/third_party/blink/renderer/platform/network/header_field_tokenizer.cc
@@ -55,7 +55,7 @@ bool IsTokenCharacter(Mode mode, UChar c) {
HeaderFieldTokenizer::HeaderFieldTokenizer(const String& header_field)
: index_(0u), input_(header_field) {
- SkipSpaces();
+ SkipOptionalWhitespace();
}
HeaderFieldTokenizer::HeaderFieldTokenizer(HeaderFieldTokenizer&&) = default;
@@ -63,12 +63,13 @@ HeaderFieldTokenizer::HeaderFieldTokenizer(HeaderFieldTokenizer&&) = default;
bool HeaderFieldTokenizer::Consume(char c) {
// TODO(cvazac) change this to use LChar
DCHECK_NE(c, ' ');
+ DCHECK_NE(c, '\t');
if (IsConsumed() || input_[index_] != c)
return false;
++index_;
- SkipSpaces();
+ SkipOptionalWhitespace();
return true;
}
@@ -82,7 +83,7 @@ bool HeaderFieldTokenizer::ConsumeQuotedString(String& output) {
if (input_[index_] == '"') {
output = builder.ToString();
++index_;
- SkipSpaces();
+ SkipOptionalWhitespace();
return true;
}
if (input_[index_] == '\\') {
@@ -107,7 +108,7 @@ bool HeaderFieldTokenizer::ConsumeToken(Mode mode, StringView& output) {
return false;
output = StringView(input_, start, index_ - start);
- SkipSpaces();
+ SkipOptionalWhitespace();
return true;
}
@@ -126,10 +127,8 @@ bool HeaderFieldTokenizer::ConsumeTokenOrQuotedString(Mode mode,
return true;
}
-void HeaderFieldTokenizer::SkipSpaces() {
- // TODO(cvazac) skip tabs, per:
- // https://tools.ietf.org/html/rfc7230#section-3.2.3
- while (!IsConsumed() && input_[index_] == ' ')
+void HeaderFieldTokenizer::SkipOptionalWhitespace() {
+ while (!IsConsumed() && (input_[index_] == ' ' || input_[index_] == '\t'))
++index_;
}
diff --git a/chromium/third_party/blink/renderer/platform/network/header_field_tokenizer.h b/chromium/third_party/blink/renderer/platform/network/header_field_tokenizer.h
index 71702553e29..f8da70cd247 100644
--- a/chromium/third_party/blink/renderer/platform/network/header_field_tokenizer.h
+++ b/chromium/third_party/blink/renderer/platform/network/header_field_tokenizer.h
@@ -41,7 +41,7 @@ class PLATFORM_EXPORT HeaderFieldTokenizer final {
private:
bool ConsumeQuotedString(String& output);
- void SkipSpaces();
+ void SkipOptionalWhitespace();
unsigned index_;
const String input_;
@@ -49,4 +49,4 @@ class PLATFORM_EXPORT HeaderFieldTokenizer final {
} // namespace blink
-#endif
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_NETWORK_HEADER_FIELD_TOKENIZER_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 c50743eb5d0..e12b5fe4c54 100644
--- a/chromium/third_party/blink/renderer/platform/network/http_names.json5
+++ b/chromium/third_party/blink/renderer/platform/network/http_names.json5
@@ -51,6 +51,7 @@
"Pragma",
"Purpose",
"Range",
+ // TODO(domfarolino): Remove "Referer" as part of https://crbug.com/850813.
"Referer",
"Referrer-Policy",
"Refresh",
diff --git a/chromium/third_party/blink/renderer/platform/network/parsed_content_header_field_parameters_test.cc b/chromium/third_party/blink/renderer/platform/network/parsed_content_header_field_parameters_test.cc
index d1ea6bb6fbe..dec0e74de7e 100644
--- a/chromium/third_party/blink/renderer/platform/network/parsed_content_header_field_parameters_test.cc
+++ b/chromium/third_party/blink/renderer/platform/network/parsed_content_header_field_parameters_test.cc
@@ -35,21 +35,32 @@ void CheckValidity(bool expected,
TEST(ParsedContentHeaderFieldParametersTest, Validity) {
CheckValidity(true, "");
CheckValidity(true, " ");
+ CheckValidity(true, "\t");
CheckValidity(true, " ;p1=v1");
+ CheckValidity(true, "\t;p1=v1");
CheckValidity(true, "; p1=v1");
+ CheckValidity(true, ";\tp1=v1");
CheckValidity(true, ";p1=v1 ");
+ CheckValidity(true, ";p1=v1\t");
CheckValidity(true, ";p1 = v1");
+ CheckValidity(true, ";p1\t=\tv1");
+ CheckValidity(true, "; p1 = v1 ");
+ CheckValidity(true, ";\tp1\t=\tv1\t");
CheckValidity(true, ";z=\"ttx&r=z;;\\u\\\"kd==\"");
CheckValidity(true, "; z=\"\xff\"");
CheckValidity(false, "\r");
CheckValidity(false, "\n");
CheckValidity(false, " p1=v1");
+ CheckValidity(false, "\tp1=v1");
CheckValidity(false, ";p1=v1;");
CheckValidity(false, ";");
CheckValidity(false, "; ");
+ CheckValidity(false, ";\t");
CheckValidity(false, "; p1");
+ CheckValidity(false, ";\tp1");
CheckValidity(false, "; p1;");
+ CheckValidity(false, ";\tp1;");
CheckValidity(false, ";\"xx");
CheckValidity(false, ";\"xx=y");
CheckValidity(false, "; \"z\"=u");
diff --git a/chromium/third_party/blink/renderer/platform/platform_chrome_client.h b/chromium/third_party/blink/renderer/platform/platform_chrome_client.h
deleted file mode 100644
index 4626ea6d008..00000000000
--- a/chromium/third_party/blink/renderer/platform/platform_chrome_client.h
+++ /dev/null
@@ -1,54 +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 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_PLATFORM_PLATFORM_CHROME_CLIENT_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PLATFORM_CHROME_CLIENT_H_
-
-#include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/platform_export.h"
-#include "third_party/blink/renderer/platform/wtf/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/noncopyable.h"
-
-namespace blink {
-
-class PLATFORM_EXPORT PlatformChromeClient
- : public GarbageCollectedFinalized<PlatformChromeClient> {
- WTF_MAKE_NONCOPYABLE(PlatformChromeClient);
-
- public:
- PlatformChromeClient() = default;
- virtual ~PlatformChromeClient() = default;
- virtual void Trace(blink::Visitor* visitor) {}
-
- // Converts the scalar value from the window coordinates to the viewport
- // scale.
- virtual float WindowToViewportScalar(const float) const = 0;
-
- virtual bool IsPopup() { return false; }
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_PLATFORM_CHROME_CLIENT_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 7fa2c263589..d7c26b202fe 100644
--- a/chromium/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/chromium/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -104,10 +104,6 @@
status: "experimental",
},
{
- name: "AudioWorklet",
- status: "stable",
- },
- {
name: "AutomationControlled",
settable_from_internals: true,
},
@@ -117,10 +113,6 @@
settable_from_internals: true,
},
{
- name: "AutoplayMutedVideos",
- settable_from_internals: true,
- },
- {
name: "BackgroundFetch",
status: "experimental",
},
@@ -155,18 +147,13 @@
status: "stable"
},
{
- name: "Budget",
- status: "stable",
+ name: "CacheInlineScriptCode"
},
{
- name: "BudgetQuery",
- origin_trial_feature_name: "BudgetQuery",
+ name: "CacheStorageAddAllRejectsDuplicates",
status: "experimental",
},
{
- name: "CacheInlineScriptCode"
- },
- {
name: "CacheStyleSheetWithMediaQueries",
status: "experimental",
},
@@ -213,11 +200,6 @@
status: "experimental",
},
{
- name: "CompositeOpaqueScrollers",
- settable_from_internals: true,
- status: "stable",
- },
- {
name: "CompositorTouchAction",
status: "test",
},
@@ -255,10 +237,6 @@
status: "experimental",
},
{
- name: "CSSDisplayContents",
- status: "stable",
- },
- {
name: "CSSEnvironmentVariables",
status: "stable",
},
@@ -292,6 +270,7 @@
{
name: "CSSLogical",
status: "experimental",
+ settable_from_internals: true,
},
{
name: "CSSMaskSourceType",
@@ -317,10 +296,6 @@
name: "CSSOMSmoothScroll",
status: "stable",
},
- {
- name: "CSSOverscrollBehavior",
- status: "stable",
- },
// Do not ship CSSPaintAPIArguments without shipping CSSVariables2 first.
//
// CSSPaintAPIArguments depends on parts of the the 'CSS Properties and
@@ -348,10 +323,6 @@
status: "experimental",
},
{
- name: "CSSTransformBox",
- status: "stable",
- },
- {
name: "CSSVariables2",
status: "experimental",
},
@@ -389,10 +360,6 @@
status: "experimental",
},
{
- name: "DeviceMemoryHeader",
- status: "stable",
- },
- {
name: "DisableHardwareNoiseSuppression",
origin_trial_feature_name: "DisableHardwareNoiseSuppression",
status: "experimental",
@@ -415,8 +382,8 @@
name: "DocumentWrite",
},
{
- name: "EmbedderCSPEnforcement",
- status: "stable",
+ // http://crbug.com/707656 content editable in LayoutNG.
+ name: "EditingNG",
},
{
name: "EncryptedMediaEncryptionSchemeQuery",
@@ -428,6 +395,10 @@
status: "experimental",
},
{
+ name: "EncryptedMediaPersistentUsageRecordSession",
+ status: "test",
+ },
+ {
name: "EventTiming",
origin_trial_feature_name: "EventTiming",
status: "experimental",
@@ -470,10 +441,6 @@
status: "experimental",
},
{
- name: "ExtendedImageBitmapOptions",
- status: "experimental",
- },
- {
name: "ExtendedTextMetrics",
status: "experimental",
},
@@ -485,19 +452,15 @@
name: "FastMobileScrolling",
},
{
- name: "FeaturePolicyAutoplayFeature",
- status: "stable"
- },
- {
- name: "FeaturePolicyForPermissions",
- status: "stable"
- },
- {
name: "FeaturePolicyJavaScriptInterface",
origin_trial_feature_name: "FeaturePolicyJSAPI",
status: "experimental"
},
{
+ name: "FeaturePolicyReporting",
+ status: "experimental"
+ },
+ {
name: "FeaturePolicyVibrateFeature"
},
{
@@ -505,11 +468,11 @@
status: "stable",
},
{
- name: "FocusOptions",
- status: "stable",
+ name: "FontCacheScaling",
+ status: "test",
},
{
- name: "FontCacheScaling",
+ name: "FontSrcLocalMatching",
status: "test",
},
// For simulating Android's overlay fullscreen video in layout tests on Linux.
@@ -552,7 +515,12 @@
status: "experimental",
},
{
+ name: "GamepadButtonAxisEvents",
+ status: "experimental",
+ },
+ {
name: "GamepadExtensions",
+ origin_trial_feature_name: "WebVR1.1M62",
status: "experimental",
},
{
@@ -560,15 +528,28 @@
status: "experimental",
},
{
+ name: "GetDisplayMedia",
+ status: "experimental",
+ },
+ {
name: "HeapCompaction",
status: "stable",
},
{
name: "HeapIncrementalMarking",
+ status: "stable",
},
{
name: "HeapIncrementalMarkingStress"
},
+ {
+ name: "HeapUnifiedGarbageCollection",
+ },
+ // Only exposed when a translation engine is available
+ // and experimental features are enabled.
+ {
+ name: "HrefTranslate",
+ },
// https://crbug.com/766694 for testing disabling the feature.
{
name: "HTMLImports",
@@ -588,10 +569,6 @@
status: "stable",
},
{
- name: "ImageDecodingAttribute",
- status: "stable",
- },
- {
name: "ImageOrientation",
status: "test",
},
@@ -623,6 +600,14 @@
},
{
name: "InterventionReporting",
+ status: "stable",
+ },
+ {
+ name: "InvisibleDOM",
+ status: "experimental",
+ },
+ {
+ name: "IsolatedCodeCache",
status: "experimental",
},
{
@@ -632,10 +617,6 @@
status: "experimental",
},
{
- name: "JSImageDecode",
- status: "stable",
- },
- {
name: "KeyboardMap",
status: "stable",
},
@@ -648,7 +629,7 @@
},
{
name: "LayoutNG",
- implied_by: ["LayoutNGBlockFragmentation", "LayoutNGFlexBox"],
+ implied_by: ["LayoutNGBlockFragmentation", "LayoutNGFlexBox", "EditingNG"],
},
{
name: "LayoutNGBlockFragmentation",
@@ -667,6 +648,12 @@
name: "LazyFrameVisibleLoadTimeMetrics",
},
{
+ name: "LazyImageLoading",
+ },
+ {
+ name: "LazyImageVisibleLoadTimeMetrics",
+ },
+ {
name: "LazyInitializeMediaControls",
// This is enabled by features::kLazyInitializeMediaControls.
},
@@ -675,10 +662,6 @@
status: "experimental",
},
{
- name: "LongTaskObserver",
- status: "stable",
- },
- {
name: "LongTaskV2",
},
{
@@ -687,6 +670,10 @@
status: "experimental",
},
{
+ name:"ManualSlotting",
+ status:"test",
+ },
+ {
name: "MediaCapabilities",
origin_trial_feature_name: "MediaCapabilities",
status: "stable",
@@ -706,10 +693,6 @@
name: "MediaCaptureDepthVideoKind",
status: "experimental",
},
- {
- name: "MediaCaptureFromVideo",
- status: "stable",
- },
// Set to reflect the MediaCastOverlayButton feature.
{
name: "MediaCastOverlayButton",
@@ -748,7 +731,7 @@
},
{
name: "MediaStreamTrackContentHint",
- status: "experimental",
+ status: "stable",
},
// This is enabled by default on Windows only. The only part that's
// "experimental" is the support on other platforms.
@@ -802,10 +785,6 @@
status: "stable",
},
{
- name: "NetInfoDownlink",
- status: "stable",
- },
- {
name: "NetInfoDownlinkHeader",
status: "stable",
},
@@ -814,26 +793,14 @@
status: "stable",
},
{
- name: "NetInfoEffectiveType",
- status: "stable",
- },
- {
name: "NetInfoEffectiveTypeHeader",
status: "stable",
},
{
- name: "NetInfoRtt",
- status: "stable",
- },
- {
name: "NetInfoRttHeader",
status: "stable",
},
{
- name: "NetInfoSaveData",
- status: "stable",
- },
- {
name: "NetworkService",
},
// Not a web exposed feature, enabled from the command line.
@@ -841,6 +808,10 @@
name: "NewRemotePlaybackPipeline",
},
{
+ name: "NoIdleEncodingForLayoutTests",
+ status: "test",
+ },
+ {
name: "NotificationConstructor",
status: "stable",
},
@@ -851,7 +822,7 @@
},
{
name: "NotificationInlineReplies",
- status: "experimental",
+ status: "stable",
},
{
name: "Notifications",
@@ -884,10 +855,6 @@
name: "OrientationEvent",
},
{
- name: "OriginPolicy",
- status: "test",
- },
- {
name: "OriginTrials",
status: "stable",
},
@@ -939,26 +906,21 @@
status: "stable",
},
{
+ name: "PassiveDocumentWheelEventListeners",
+ },
+ {
name: "PassPaintVisualRectToCompositor",
},
{
name: "PaymentApp",
status: "experimental",
},
- {
- name: "PaymentDetailsModifierData",
- status: "stable",
- },
// PaymentRequest is enabled by default on Android
{
name: "PaymentRequest",
status: "experimental",
},
{
- name: "PaymentRequestBasicCard",
- status: "stable",
- },
- {
name: "PaymentRetry",
status: "experimental",
},
@@ -967,10 +929,6 @@
status: "stable",
},
{
- name: "PerformancePaintTiming",
- status: "stable",
- },
- {
name: "PermissionDelegation",
status: "test",
},
@@ -996,11 +954,19 @@
status: "experimental",
},
{
- name: "PreciseMemoryInfo",
+ name: "PointerRawMove",
+ status: "experimental",
},
{
- name: "PreferredImageRasterBounds",
- settable_from_internals: true,
+ name: "Portals",
+ status: "test",
+ },
+ {
+ name: "PostMessageOptions",
+ status: "stable",
+ },
+ {
+ name: "PreciseMemoryInfo",
},
// This feature is deprecated and we are evangelizing affected sites.
// See https://crbug.com/346236 for current status.
@@ -1057,47 +1023,42 @@
status: "stable",
},
{
- name: "RenderingPipelineThrottlingLoadingIframes",
- status: "stable",
- },
- {
- name: "RenderUnicodeControlCharacters",
- status: "stable",
- },
- {
name: "ReportingObserver",
implied_by: ["DeprecationReporting", "InterventionReporting"],
status: "stable",
},
{
- name: "RequestIsHistoryNavigation",
- status: "stable",
- },
- {
name: "RequireCSSExtensionForFile",
status: "stable",
},
{
- name: "ResizeObserver",
- status: "stable",
- },
- {
name: "ResourceLoadScheduler",
status: "experimental",
},
{
name: "RestrictAppCacheToSecureContexts",
- status: "experimental",
+ status: "stable",
},
+ // Enables the use of the RTCIceTransport with extensions.
{
- name: "RestrictCanRequestURLCharacterSet",
- status: "stable",
+ name: "RTCIceTransportExtension",
+ status: "test",
},
{
name: "RtcPeerConnectionId",
origin_trial_feature_name: "RtcPeerConnectionId",
status: "experimental",
},
+ // Enables the use of the RTCQuicStream object.
+ {
+ name: "RTCQuicStream",
+ status: "test",
+ },
+ // Enables the use of the RTCQuicTransport object.
+ {
+ name: "RTCQuicTransport",
+ status: "test",
+ },
{
name: "RTCRtpSenderParameters",
status: "stable",
@@ -1114,6 +1075,9 @@
name: "RTCUnifiedPlanByDefault",
},
{
+ name: "ScheduledScriptStreaming",
+ },
+ {
name: "ScriptedSpeech",
status: "stable",
},
@@ -1152,10 +1116,6 @@
status: "experimental",
},
{
- name: "ServerTiming",
- status: "stable",
- },
- {
name: "ServiceWorkerScriptFullCodeCache",
},
{
@@ -1178,6 +1138,7 @@
},
{
name: "ShapeDetection",
+ origin_trial_feature_name: "ShapeDetection",
status: "experimental",
},
{
@@ -1194,11 +1155,10 @@
status: "experimental",
},
{
- name: "SlimmingPaintV2",
+ name: "SignedHTTPExchange",
},
{
- name: "SlotInFlatTree",
- status: "stable",
+ name: "SlimmingPaintV2",
},
{
name: "SMIL",
@@ -1225,11 +1185,7 @@
status: "experimental",
},
{
- name: "StopInBackground",
- status: "test",
- },
- {
- name: "StopNonTimersInBackground",
+ name: "TestReporting",
status: "test",
},
{
@@ -1309,15 +1265,11 @@
status: "experimental",
},
{
- name: "VisibilityCollapseRow",
- status: "stable",
- },
- {
- name: "VisualViewportAPI",
- status: "stable",
+ name: "WakeLock",
+ status: "experimental",
},
{
- name: "WakeLock",
+ name: "WakeLockNavigator",
status: "experimental",
},
{
@@ -1333,6 +1285,11 @@
status: "experimental",
},
{
+ name: "WebAssemblyThreads",
+ origin_trial_feature_name: "WebAssemblyThreads",
+ status: "experimental",
+ },
+ {
name: "WebAuth",
status: "experimental",
},
@@ -1384,16 +1341,12 @@
},
{
name: "WebUSBOnDedicatedWorkers",
- status: "experimental",
- depends_on: ["WebUSB"],
- },
- {
- name: "WebUSBOnSharedWorkers",
- status: "test",
+ status: "stable",
depends_on: ["WebUSB"],
},
{
name: "WebVR",
+ origin_trial_feature_name: "WebVR1.1M62",
status: "experimental",
},
{
@@ -1419,16 +1372,12 @@
status: "experimental"
},
{
- name: "WindowPostMessageOptions",
- status: "experimental",
- },
- {
name: "WorkerNosniffBlock",
- status: "test",
+ status: "experimental",
},
{
name: "WorkerNosniffWarn",
- status: "test",
+ status: "stable",
implied_by: ["WorkerNosniffBlock"],
},
{
@@ -1436,6 +1385,9 @@
status: "experimental",
},
{
+ name: "WritableFiles",
+ },
+ {
name: "XSLT",
status: "stable",
},
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/BUILD.gn b/chromium/third_party/blink/renderer/platform/scheduler/BUILD.gn
index eb785992cbe..dbe485ca93a 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/BUILD.gn
+++ b/chromium/third_party/blink/renderer/platform/scheduler/BUILD.gn
@@ -9,14 +9,13 @@ import("//testing/libfuzzer/fuzzer_test.gni")
blink_platform_sources("scheduler") {
sources = [
+ "child/features.cc",
"child/features.h",
"child/pollable_thread_safe_flag.cc",
"child/pollable_thread_safe_flag.h",
"child/process_state.cc",
"child/process_state.h",
"child/single_thread_idle_task_runner.cc",
- "child/task_queue_with_task_type.cc",
- "child/task_queue_with_task_type.h",
"child/webthread_base.cc",
"child/webthread_impl_for_worker_scheduler.cc",
"child/webthread_impl_for_worker_scheduler.h",
@@ -33,7 +32,11 @@ blink_platform_sources("scheduler") {
"common/scheduler_helper.cc",
"common/scheduler_helper.h",
"common/scheduling_lifecycle_state.cc",
+ "common/simple_thread_scheduler.cc",
+ "common/simple_thread_scheduler.h",
"common/thread_scheduler.cc",
+ "common/thread_scheduler_impl.cc",
+ "common/thread_scheduler_impl.h",
"common/throttling/budget_pool.cc",
"common/throttling/budget_pool.h",
"common/throttling/cpu_time_budget_pool.cc",
@@ -44,8 +47,6 @@ blink_platform_sources("scheduler") {
"common/throttling/throttled_time_domain.h",
"common/throttling/wake_up_budget_pool.cc",
"common/throttling/wake_up_budget_pool.h",
- "common/total_duration_metric_reporter.cc",
- "common/total_duration_metric_reporter.h",
"common/unprioritized_resource_loading_task_runner_handle.cc",
"common/unprioritized_resource_loading_task_runner_handle.h",
"common/web_resource_loading_task_runner_handle.cc",
@@ -84,6 +85,8 @@ blink_platform_sources("scheduler") {
"main_thread/resource_loading_task_runner_handle_impl.h",
"main_thread/task_cost_estimator.cc",
"main_thread/task_cost_estimator.h",
+ "main_thread/task_type_names.cc",
+ "main_thread/task_type_names.h",
"main_thread/use_case.h",
"main_thread/user_model.cc",
"main_thread/user_model.h",
@@ -102,7 +105,6 @@ blink_platform_sources("scheduler") {
"renderer/webthread_impl_for_renderer_scheduler.cc",
"renderer/webthread_impl_for_renderer_scheduler.h",
"util/aggregated_metric_reporter.h",
- "util/task_duration_metric_reporter.h",
"util/thread_cpu_throttler.cc",
"util/thread_cpu_throttler.h",
"util/thread_load_tracker.cc",
@@ -110,8 +112,6 @@ blink_platform_sources("scheduler") {
"util/thread_type.h",
"util/tracing_helper.cc",
"util/tracing_helper.h",
- "utility/webthread_impl_for_utility_thread.cc",
- "utility/webthread_impl_for_utility_thread.h",
"worker/compositor_metrics_helper.cc",
"worker/compositor_metrics_helper.h",
"worker/compositor_thread_scheduler.cc",
@@ -134,8 +134,10 @@ blink_platform_sources("scheduler") {
deps = [
"//base",
"//cc",
+ "//components/scheduling_metrics",
"//device/base/synchronization",
"//services/metrics/public/cpp:ukm_builders",
+ "//services/metrics/public/mojom",
"//third_party/blink/renderer/platform:make_platform_generated",
"//third_party/blink/renderer/platform/wtf",
]
@@ -158,7 +160,8 @@ jumbo_source_set("test_support") {
deps = [
"//base",
"//base/test:test_support",
- "//third_party/blink/public/mojom:mojom_platform_blink__generator",
+ "//mojo/public/cpp/bindings",
+ "//third_party/blink/public/mojom:mojom_platform_blink_headers",
]
configs += [ "//third_party/blink/renderer/platform:blink_platform_config" ]
@@ -176,7 +179,6 @@ jumbo_source_set("unit_tests") {
"common/scheduler_helper_unittest.cc",
"common/throttling/budget_pool_unittest.cc",
"common/throttling/task_queue_throttler_unittest.cc",
- "common/total_duration_metric_reporter_unittest.cc",
"main_thread/auto_advancing_virtual_time_domain_unittest.cc",
"main_thread/deadline_task_runner_unittest.cc",
"main_thread/frame_scheduler_impl_unittest.cc",
@@ -242,9 +244,16 @@ source_set("scheduler_fuzzer_tests") {
if (is_linux) {
sources += [
- "base/sequence_manager_fuzzer_processor.cc",
- "base/sequence_manager_fuzzer_processor.h",
- "base/sequence_manager_fuzzer_processor_unittest.cc",
+ "test/fuzzer/sequence_manager_fuzzer_processor.cc",
+ "test/fuzzer/sequence_manager_fuzzer_processor.h",
+ "test/fuzzer/sequence_manager_fuzzer_processor_unittest.cc",
+ "test/fuzzer/simple_thread_impl.cc",
+ "test/fuzzer/simple_thread_impl.h",
+ "test/fuzzer/task_queue_with_voters.h",
+ "test/fuzzer/thread_manager.cc",
+ "test/fuzzer/thread_manager.h",
+ "test/fuzzer/thread_pool_manager.cc",
+ "test/fuzzer/thread_pool_manager.h",
]
deps += [
@@ -258,9 +267,16 @@ source_set("scheduler_fuzzer_tests") {
fuzzer_test("sequence_manager_fuzzer") {
sources = [
- "base/sequence_manager_fuzzer.cc",
- "base/sequence_manager_fuzzer_processor.cc",
- "base/sequence_manager_fuzzer_processor.h",
+ "test/fuzzer/sequence_manager_fuzzer.cc",
+ "test/fuzzer/sequence_manager_fuzzer_processor.cc",
+ "test/fuzzer/sequence_manager_fuzzer_processor.h",
+ "test/fuzzer/simple_thread_impl.cc",
+ "test/fuzzer/simple_thread_impl.h",
+ "test/fuzzer/task_queue_with_voters.h",
+ "test/fuzzer/thread_manager.cc",
+ "test/fuzzer/thread_manager.h",
+ "test/fuzzer/thread_pool_manager.cc",
+ "test/fuzzer/thread_pool_manager.h",
]
deps = [
@@ -273,6 +289,6 @@ fuzzer_test("sequence_manager_fuzzer") {
proto_library("sequence_manager_test_description_proto") {
sources = [
- "base/proto/sequence_manager_test_description.proto",
+ "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 c8e9a1cdcca..928da1be0a0 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/DEPS
+++ b/chromium/third_party/blink/renderer/platform/scheduler/DEPS
@@ -39,12 +39,15 @@ include_rules = [
"+base/task/sequence_manager/sequence_manager.h",
"+base/task/sequence_manager/task_queue.h",
"+base/task/sequence_manager/time_domain.h",
+ "+base/task/task_traits.h",
"+base/threading/platform_thread.h",
"+base/threading/sequenced_task_runner_handle.h",
"+base/threading/thread.h",
"+base/threading/thread_checker.h",
+ "+components/scheduling_metrics",
"+services/metrics",
+ "+third_party/blink/renderer/platform/bindings/parkable_string.h",
"+third_party/blink/renderer/platform/cross_thread_functional.h",
"+third_party/blink/renderer/platform/histogram.h",
"+third_party/blink/renderer/platform/instrumentation",
@@ -60,6 +63,7 @@ specific_include_rules = {
".*test\.cc": [
"+base/metrics/field_trial_param_associator.h",
"+base/task/sequence_manager/test",
+ "+components/ukm/test_ukm_recorder.h",
"+testing",
],
"sequence_manager_fuzzer.cc": [
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/README.md b/chromium/third_party/blink/renderer/platform/scheduler/README.md
index 461593517e0..88299cfb052 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/README.md
+++ b/chromium/third_party/blink/renderer/platform/scheduler/README.md
@@ -18,6 +18,33 @@ The following is a collection of scheduling-related documentation about the
Blink Scheduler as well as other schedulers in Chrome.
+## 2018
+* [Browser-side scheduling roadmap](https://docs.google.com/document/d/1yxjka3kyKieEWP6gRlLyXVy72DJ5Gc22Nqp9vehFj14/edit)
+* [Browser UI thread scheduler](https://docs.google.com/document/d/1z1BDq9vzcEpkhN9LSPF5XMnZ0kLJ8mWWkNAi4OI7cos/edit)
+* [Browser IO thread scheduling for input latency](https://docs.google.com/document/d/12waKYiZOOu1DwUJO5faSonq9OwRIJuaP0GavClPTHWY/edit)
+* [Off Main Thread: Scheduling API](https://docs.google.com/document/d/1SGWR1LrrgOUWHNJZU6JfUC89dCMSIXP7TH8RmoWLqyc/edit)
+* [Task traits for sequence scheduling in //content](https://docs.google.com/document/d/1SGy9VTXUwyXEX_yBZ0ukFAnS8B0hDeMUJD-1iALaE-Q/edit)
+* [Stop more task queues in background on Android](https://docs.google.com/document/d/10D2uvOVxBZ2YhcwtK1XOb6CClminPpqAeS82KOVT7hk/edit)
+* [Discussion of more graceful worker shutdown](https://docs.google.com/document/d/11waILCkPehUfML6_defbpkNk4mau6qiK8f7qXtqauwY/edit)
+* [Stop loading in background on Android](https://docs.google.com/document/d/1DEGgG9HfA2ixJpXQDsKbYCJJyHILWz3CQmuNEJr9Xho/edit)
+* [Android startup performance tweaks](https://docs.google.com/document/d/1rGbdF0Rjv0wl7dEQ4kGj2f79Q20MlIv7ch9MSlm2G3M/edit#heading=h.e7o0jj9sx1od)
+* [C++ Promises for Chromium](https://docs.google.com/document/d/1l12PAJgEtlrqTXKiw6mk2cR2jP7FAfCCDr-DGIdiC9w/edit)
+* [C++ Promise/Future/Coroutine in Chromium](https://docs.google.com/document/d/1RThP0a8fTyuYqpPN2zrMxt8Te9M0v3JUv1XhcquBz9E/edit)
+* [Java task scheduling](https://docs.google.com/document/d/1z2ALaVDkfxurPpzDzO9dAAK3dLuLCjYViJijydPoMHs/edit)
+* [Scheduling resource responses with right priority](https://docs.google.com/document/d/18WcfptovabsfE-2Nb4M_x8abVqInr-94fno81E_NcJk/edit)
+* [Refactor EventQueue](https://docs.google.com/document/d/1BBtBPTarOF4NeVKSWZe3XaDHo4yTGhdlqYm35yVzPs4/edit)
+* [Looking into scrolling lag](https://docs.google.com/document/d/1l2e3B6Ad0mqMRqs3_cK8a-o4Po6XMhOgIZt2B5r_ZG0/edit#heading=h.2ef1y98v91gv)
+* [Better scheduling metrics](https://docs.google.com/document/d/1o6QHeY8y6PssEv--Qs6uNeNWrOzTwDyrbTk9iuq2WmY/edit#heading=h.ia9zbay5xpwt)
+* [Scheduler architecture 2.0](https://docs.google.com/document/d/1dk71yTd5fndb5gMSb7wlB2P80hw5ImFxbPao06Ti8EQ/edit#heading=h.7m3oi6qeqhdv)
+* [Task Scheduler - Message Loop integration and migration](https://docs.google.com/document/d/1Vy7kz_9evp6xOFRQBD6M1h4qmk4EEBu0cutipQ3e6kA/edit)
+* [Supporting per-frame priorities in Blink Scheduler](https://docs.google.com/document/d/1-0nNG75hfsg1WhW3Xa4yUNDQdP1D6EJ9r2tl4tmAVJM/edit)
+* [Simplifying scheduler interfaces](https://docs.google.com/document/d/1oz-Rjpn6KhmQvaJF4b674Jofiy3PQQPbyngqFGlYknY/edit)
+* [Using dedicated workers for background work](https://docs.google.com/document/d/1qTYo9ZQwsycJYPAuT5AKw6JYBEsSfJQR823mma3CGvQ/edit)
+* [Untangling spaghetti of platform/scheduler/](https://docs.google.com/document/d/1jxM32tM-djMl7Xzy_tQbVadX1HjQ06fH0x7ofxeeSVc/edit#heading=h.34va28zf1wfu)
+* [Better layering for platform/scheduler/](https://docs.google.com/document/d/1Brt1oSUrL4M_TBSl-KiCbvQt8kYxwnmqsXrmJM00ylA/edit)
+* [Keyed Service scheduling](https://docs.google.com/document/d/1JCvCQvux0DW0X3tyfE_u70Fvpspfn7KDTTdJVD7M524/edit)
+
+
## 2017
* [Improved load time scheduling](https://docs.google.com/document/d/1q5uPIKyUP0X7KaQRyxWXmIzMvKF3fx1j6QPCWhjI82o/edit)
* [Wake-up based throttling](https://docs.google.com/document/d/1A87Ci3_USDyQEdlmXTO1spQxUcR_ML5zqiCsaow4NGM/edit)
@@ -25,11 +52,23 @@ Blink Scheduler as well as other schedulers in Chrome.
* [BeginFrame sequence numbers + acknowledgements](https://docs.google.com/document/d/1nxaunQ0cYWxhtS6Zzfwa99nae74F7gxanbuT5JRpI6Y/edit)
* [Background tab use cases](https://docs.google.com/document/d/16-QGneIkYNbNleoXbdD-mRMYdZAG2JIjMcTVxSC3ZWc/edit)
* [Activity traits](https://docs.google.com/document/d/1BaJpx08vbPz_1LCj9tehnatZNqh1eLPeE9xoUnWdlW4/edit#heading=h.nwhgpfhlxswr)
+* [Blink and Task Scheduler integration](https://docs.google.com/document/d/1h-FlOeO-27g__JnuRvdJ8KG9G-bmG_zn6zuw7GerFkc/edit)
+* [Lifecycle use cases](https://docs.google.com/document/d/16-QGneIkYNbNleoXbdD-mRMYdZAG2JIjMcTVxSC3ZWc/edit)
+* [Task execution policies in Blink](https://docs.google.com/document/d/1tFI0pkLp1LCFDKRxwT6BSdA-ub8K4cZJLlCaAlqmsvM/edit)
+* [Capturing task type metadata](https://docs.google.com/document/d/1Py2ZdjpaCMdpVtKfdHMITAn5gst_owjQiqlbPm3mCxc/edit)
+* [Further per-frame scheduler work](https://docs.google.com/document/d/1yOhE6-1HLb3aeNWmoa9O2LlnegWjd4awYUn2OhUL4vk/edit)
+* [Better tracing for Blink Scheduler](https://docs.google.com/document/d/18Iz0lVX38_ZIMNoAp4e2RpeIFcCUUU2cghDwy_aLK3k/edit)
+* [Scheduling architecture roadmap: one pager](https://docs.google.com/document/d/13dQAthHRn7bkEgsb7OzG50zhxFFB1rHEDCM7ObXH1_c/edit)
+* [RendererMainThreadLoad metrics](https://docs.google.com/document/d/1MvAadiO3kwSodfOIZ35k2j4oJX-zVY9FsQaSshI-vus/edit#heading=h.r8nzo35yh6ck)
+* [State of the throttling](https://docs.google.com/document/d/1csir1MUkI1maqjAIzhR51LTy1pwSqeh9HDmAPTZWirw/edit)
+* [Background tabs & offscreen frames](https://docs.google.com/document/d/18_sX-KGRaHcV3xe5Xk_l6NNwXoxm-23IOepgMx4OlE4/edit)
+* [Prototyping cooperative scheduling](https://docs.google.com/document/d/1ennqB9cCfko6eg1a6bNoJjaypESjfFvhVup9LSJCyUg/edit)
+* [Cooperative scheduling in Blink](https://docs.google.com/document/d/14WoGZ8pfD4TmOFDebE-WIgkfQ62MnOiyafQI4Zhqjzs/edit)
## 2016
* [Time-based renderer task throttling](https://drive.google.com/open?id=1vCUeGfr2xzZ67SFt2yZjNeaIcXGp2Td6KHN7bI02ySo)
-* [kV8 Performance Mode](https://drive.google.com/open?id=1bRVAP08qNBvnEm_vO4hW1-NqQC9-lQZjUH29_vwfYRY)
+* [V8 Performance Mode](https://drive.google.com/open?id=1bRVAP08qNBvnEm_vO4hW1-NqQC9-lQZjUH29_vwfYRY)
* [Isolating performance of third-party iframes](https://docs.google.com/document/d/1CEggurHQGXenhu_GQT7KnRvtSuowuenXpxVzYSeRxSY/edit)
* [Folly of Scheduling (BlinkOn 6)](https://drive.google.com/open?id=1ZMxbnSn1R1o2-NGztP0mVyOOoQg24bLSqWE1SWXnQ_E)
* [Rendering pipeline throttling (BlinkOn 6)](https://docs.google.com/presentation/d/1aPZzH7J0O29sqA_FzsuWQNDwK6CoNcAcpMvJexsO6Vg/edit)
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/DEPS b/chromium/third_party/blink/renderer/platform/scheduler/base/DEPS
index 5fcbda71de3..2b191979763 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/base/DEPS
+++ b/chromium/third_party/blink/renderer/platform/scheduler/base/DEPS
@@ -6,10 +6,3 @@ include_rules = [
"+third_party/blink/renderer/platform/platform_export.h",
"+base",
]
-
-specific_include_rules = {
- "sequence_manager_fuzzer_processor_unittest.cc": [
- "+third_party/protobuf/src/google/protobuf/text_format.h",
- "+third_party/protobuf/src/google/protobuf/util/message_differencer.h",
- ],
-}
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/proto/sequence_manager_test_description.proto b/chromium/third_party/blink/renderer/platform/scheduler/base/proto/sequence_manager_test_description.proto
deleted file mode 100644
index 59f25384bc7..00000000000
--- a/chromium/third_party/blink/renderer/platform/scheduler/base/proto/sequence_manager_test_description.proto
+++ /dev/null
@@ -1,67 +0,0 @@
-syntax = "proto2";
-
-package base.sequence_manager;
-
-// Describes the grammar of the fuzzer's test description. At a high level, it
-// describes a sequence of actions that can be executed.
-message SequenceManagerTestDescription {
- // NEXT ID = 2
-
- enum QueuePriority {
- // NEXT ID = 6
-
- UNDEFINED = 0;
- BEST_EFFORT = 1;
- LOW = 2;
- NORMAL = 3;
- HIGH = 4;
- HIGHEST = 5;
- }
-
- // Describes interfaces that can be tested by the fuzzer.
- // TODO(farahcharab) Add more interfaces here.
- message Action {
- // NEXT ID = 4
-
- optional uint64 action_id = 1;
-
- oneof action {
- CreateTaskQueueAction create_task_queue = 2;
- PostDelayedTaskAction post_delayed_task = 3;
- }
- }
-
- message Task {
- // NEXT ID = 4
-
- optional uint64 task_id = 1;
-
- optional uint64 duration_ms = 2;
-
- // If not set, then this is a no-op task.
- repeated Action action = 3;
- }
-
- // Describes the grammar of SequenceManager::CreateTaskQueue.
- message CreateTaskQueueAction {
- // NEXT ID = 2
-
- optional QueuePriority initial_priority = 1;
- }
-
- // Describes the grammar of TaskQueue::PostDelayedTask.
- message PostDelayedTaskAction {
- // NEXT ID = 4
-
- // Used to identify the queue to post to.
- optional uint64 task_queue_id = 1;
-
- optional Task task = 2;
-
- // Delay parameter passed to TaskQueue::PostDelayedTask i.e. the delay is
- // measured after executing the PostDelayedTaskAction.
- optional uint64 delay_ms = 3;
- }
-
- repeated Action initial_actions = 1;
-}
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/sequence_manager_fuzzer.cc b/chromium/third_party/blink/renderer/platform/scheduler/base/sequence_manager_fuzzer.cc
deleted file mode 100644
index 4c50375e643..00000000000
--- a/chromium/third_party/blink/renderer/platform/scheduler/base/sequence_manager_fuzzer.cc
+++ /dev/null
@@ -1,24 +0,0 @@
-#include <stdlib.h>
-#include <iostream>
-
-#include "testing/libfuzzer/proto/lpm_interface.h"
-#include "third_party/blink/renderer/platform/scheduler/base/proto/sequence_manager_test_description.pb.h"
-#include "third_party/blink/renderer/platform/scheduler/base/sequence_manager_fuzzer_processor.h"
-
-// Tests some APIs in base::sequence_manager::SequenceManager (ones defined in
-// SequenceManagerTesrDescription proto) for crashes, hangs, memory leaks,
-// etc ... by running randomly generated tests, and exposing problematic corner
-// cases. For more details, check out go/libfuzzer-chromium.
-DEFINE_BINARY_PROTO_FUZZER(
- const base::sequence_manager::SequenceManagerTestDescription&
- fuzzer_input) {
- // Dump code for debugging.
- // TODO(farahcharab): Add code so that output looks more like the native
- // function call.
- if (getenv("LPM_DUMP_NATIVE_INPUT")) {
- std::cout << fuzzer_input.DebugString() << std::endl;
- }
-
- base::sequence_manager::SequenceManagerFuzzerProcessor::ParseAndRun(
- fuzzer_input);
-}
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/sequence_manager_fuzzer_processor.cc b/chromium/third_party/blink/renderer/platform/scheduler/base/sequence_manager_fuzzer_processor.cc
deleted file mode 100644
index fc78acb2ba6..00000000000
--- a/chromium/third_party/blink/renderer/platform/scheduler/base/sequence_manager_fuzzer_processor.cc
+++ /dev/null
@@ -1,170 +0,0 @@
-#include "third_party/blink/renderer/platform/scheduler/base/sequence_manager_fuzzer_processor.h"
-
-#include <algorithm>
-#include <string>
-
-#include "base/task/sequence_manager/test/sequence_manager_for_test.h"
-#include "base/test/test_mock_time_task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
-
-namespace base {
-namespace sequence_manager {
-
-void SequenceManagerFuzzerProcessor::ParseAndRun(
- const SequenceManagerTestDescription& description) {
- SequenceManagerFuzzerProcessor processor;
- processor.RunTest(description);
-}
-
-SequenceManagerFuzzerProcessor::SequenceManagerFuzzerProcessor()
- : SequenceManagerFuzzerProcessor(false) {}
-
-SequenceManagerFuzzerProcessor::SequenceManagerFuzzerProcessor(
- bool log_for_testing)
- : log_for_testing_(log_for_testing) {
- test_task_runner_ = WrapRefCounted(
- new TestMockTimeTaskRunner(TestMockTimeTaskRunner::Type::kBoundToThread));
-
- // A zero clock triggers some assertions.
- test_task_runner_->AdvanceMockTickClock(TimeDelta::FromMilliseconds(1));
-
- initial_time_ = test_task_runner_->GetMockTickClock()->NowTicks();
-
- manager_ =
- SequenceManagerForTest::Create(nullptr, ThreadTaskRunnerHandle::Get(),
- test_task_runner_->GetMockTickClock());
-
- TaskQueue::Spec spec = TaskQueue::Spec("default_task_queue");
- task_queues_.push_back(manager_->CreateTaskQueue<TestTaskQueue>(spec));
-}
-
-void SequenceManagerFuzzerProcessor::RunTest(
- const SequenceManagerTestDescription& description) {
- for (const auto& initial_action : description.initial_actions()) {
- RunAction(initial_action);
- }
-
- test_task_runner_->FastForwardUntilNoTasksRemain();
-}
-
-void SequenceManagerFuzzerProcessor::RunAction(
- const SequenceManagerTestDescription::Action& action) {
- if (action.has_create_task_queue()) {
- return CreateTaskQueueFromAction(action.action_id(),
- action.create_task_queue());
- }
-
- return PostDelayedTaskFromAction(action.action_id(),
- action.post_delayed_task());
-}
-
-void SequenceManagerFuzzerProcessor::PostDelayedTaskFromAction(
- uint64_t action_id,
- const SequenceManagerTestDescription::PostDelayedTaskAction& action) {
- DCHECK(!task_queues_.empty());
-
- LogActionForTesting(action_id, ActionForTest::ActionType::kPostDelayedTask,
- test_task_runner_->GetMockTickClock()->NowTicks());
-
- size_t index = action.task_queue_id() % task_queues_.size();
- TestTaskQueue* chosen_task_queue = task_queues_[index].get();
-
- // TODO(farahcharab) After adding non-nestable/nestable tasks, fix this to
- // PostNonnestableDelayedTask for the former and PostDelayedTask for the
- // latter.
- chosen_task_queue->PostDelayedTask(
- FROM_HERE,
- BindOnce(&SequenceManagerFuzzerProcessor::ExecuteTask, Unretained(this),
- action.task()),
- TimeDelta::FromMilliseconds(action.delay_ms()));
-}
-
-void SequenceManagerFuzzerProcessor::CreateTaskQueueFromAction(
- uint64_t action_id,
- const SequenceManagerTestDescription::CreateTaskQueueAction& action) {
- LogActionForTesting(action_id, ActionForTest::ActionType::kCreateTaskQueue,
- test_task_runner_->GetMockTickClock()->NowTicks());
-
- TaskQueue::Spec spec = TaskQueue::Spec("test_task_queue");
- task_queues_.push_back(manager_->CreateTaskQueue<TestTaskQueue>(spec));
-}
-
-void SequenceManagerFuzzerProcessor::ExecuteTask(
- const SequenceManagerTestDescription::Task& task) {
- TimeTicks start_time = test_task_runner_->GetMockTickClock()->NowTicks();
-
- // We can limit the depth of the nested post delayed action when processing
- // the proto.
- for (const auto& task_action : task.action()) {
- // TODO(farahcharab) Add run loop to deal with nested tasks later. So far,
- // we are assuming tasks are non-nestable.
- RunAction(task_action);
- }
-
- TimeTicks end_time = test_task_runner_->GetMockTickClock()->NowTicks();
-
- test_task_runner_->AdvanceMockTickClock(
- TimeDelta::FromMilliseconds(task.duration_ms()) -
- (end_time - start_time));
-
- LogTaskForTesting(task.task_id(), start_time,
- test_task_runner_->GetMockTickClock()->NowTicks());
-}
-
-void SequenceManagerFuzzerProcessor::LogTaskForTesting(uint64_t task_id,
- TimeTicks start_time,
- TimeTicks end_time) {
- if (!log_for_testing_)
- return;
-
- uint64_t start_time_ms = (start_time - initial_time_).InMilliseconds();
- uint64_t end_time_ms = (end_time - initial_time_).InMilliseconds();
-
- ordered_tasks_.emplace_back(task_id, start_time_ms, end_time_ms);
-}
-
-void SequenceManagerFuzzerProcessor::LogActionForTesting(
- uint64_t action_id,
- ActionForTest::ActionType type,
- TimeTicks start_time) {
- if (!log_for_testing_)
- return;
-
- ordered_actions_.emplace_back(action_id, type,
- (start_time - initial_time_).InMilliseconds());
-}
-
-const std::vector<SequenceManagerFuzzerProcessor::TaskForTest>&
-SequenceManagerFuzzerProcessor::ordered_tasks() const {
- return ordered_tasks_;
-}
-
-const std::vector<SequenceManagerFuzzerProcessor::ActionForTest>&
-SequenceManagerFuzzerProcessor::ordered_actions() const {
- return ordered_actions_;
-}
-
-SequenceManagerFuzzerProcessor::TaskForTest::TaskForTest(uint64_t id,
- uint64_t start,
- uint64_t end)
- : task_id(id), start_time_ms(start), end_time_ms(end) {}
-
-bool SequenceManagerFuzzerProcessor::TaskForTest::operator==(
- const TaskForTest& rhs) const {
- return task_id == rhs.task_id && start_time_ms == rhs.start_time_ms &&
- end_time_ms == rhs.end_time_ms;
-}
-
-SequenceManagerFuzzerProcessor::ActionForTest::ActionForTest(uint64_t id,
- ActionType type,
- uint64_t start)
- : action_id(id), action_type(type), start_time_ms(start) {}
-
-bool SequenceManagerFuzzerProcessor::ActionForTest::operator==(
- const ActionForTest& rhs) const {
- return action_id == rhs.action_id && action_type == rhs.action_type &&
- start_time_ms == rhs.start_time_ms;
-}
-
-} // namespace sequence_manager
-} // namespace base
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/sequence_manager_fuzzer_processor.h b/chromium/third_party/blink/renderer/platform/scheduler/base/sequence_manager_fuzzer_processor.h
deleted file mode 100644
index 07140f8d652..00000000000
--- a/chromium/third_party/blink/renderer/platform/scheduler/base/sequence_manager_fuzzer_processor.h
+++ /dev/null
@@ -1,102 +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_SCHEDULER_BASE_SEQUENCE_MANAGER_FUZZER_PROCESSOR_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_SEQUENCE_MANAGER_FUZZER_PROCESSOR_H_
-
-#include <memory>
-#include <vector>
-
-#include "base/task/sequence_manager/test/sequence_manager_for_test.h"
-#include "base/task/sequence_manager/test/test_task_queue.h"
-#include "base/test/test_mock_time_task_runner.h"
-#include "base/time/time.h"
-#include "third_party/blink/renderer/platform/platform_export.h"
-#include "third_party/blink/renderer/platform/scheduler/base/proto/sequence_manager_test_description.pb.h"
-
-namespace base {
-namespace sequence_manager {
-
-// Provides functionality to parse the fuzzer's test description and run the
-// relevant APIs.
-class PLATFORM_EXPORT SequenceManagerFuzzerProcessor {
- public:
- // Public interface used to parse the fuzzer's test description and
- // run the relevant APIs.
- static void ParseAndRun(const SequenceManagerTestDescription& description);
-
- protected:
- struct TaskForTest {
- TaskForTest(uint64_t id, uint64_t start, uint64_t end);
- bool operator==(const TaskForTest& rhs) const;
-
- uint64_t task_id;
- uint64_t start_time_ms;
- uint64_t end_time_ms;
- };
-
- struct ActionForTest {
- enum class ActionType { kCreateTaskQueue, kPostDelayedTask };
-
- ActionForTest(uint64_t id, ActionType type, uint64_t start);
- bool operator==(const ActionForTest& rhs) const;
-
- uint64_t action_id;
- ActionType action_type;
- uint64_t start_time_ms;
- };
-
- SequenceManagerFuzzerProcessor();
-
- explicit SequenceManagerFuzzerProcessor(bool log_for_testing);
-
- void RunTest(const SequenceManagerTestDescription& description);
-
- void RunAction(const SequenceManagerTestDescription::Action& action);
-
- const std::vector<TaskForTest>& ordered_tasks() const;
- const std::vector<ActionForTest>& ordered_actions() const;
-
- private:
- void CreateTaskQueueFromAction(
- uint64_t action_id,
- const SequenceManagerTestDescription::CreateTaskQueueAction& action);
-
- void PostDelayedTaskFromAction(
- uint64_t action_id,
- const SequenceManagerTestDescription::PostDelayedTaskAction& action);
-
- void ExecuteTask(const SequenceManagerTestDescription::Task& task);
-
- void LogTaskForTesting(uint64_t task_id,
- TimeTicks start_time,
- TimeTicks end_time);
-
- void LogActionForTesting(uint64_t action_id,
- ActionForTest::ActionType type,
- TimeTicks start_time);
-
- std::unique_ptr<SequenceManagerForTest> manager_;
-
- // Bound to current thread. Used to control the clock of the task queue
- // manager.
- scoped_refptr<TestMockTimeTaskRunner> test_task_runner_;
-
- std::vector<scoped_refptr<TestTaskQueue>> task_queues_;
-
- const bool log_for_testing_;
-
- TimeTicks initial_time_;
-
- // For Testing. Used to log tasks in their order of execution.
- std::vector<TaskForTest> ordered_tasks_;
-
- // For Testing. Used to log actions in their order of execution.
- std::vector<ActionForTest> ordered_actions_;
-};
-
-} // namespace sequence_manager
-} // namespace base
-
-#endif
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/sequence_manager_fuzzer_processor_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/base/sequence_manager_fuzzer_processor_unittest.cc
deleted file mode 100644
index 00aed913222..00000000000
--- a/chromium/third_party/blink/renderer/platform/scheduler/base/sequence_manager_fuzzer_processor_unittest.cc
+++ /dev/null
@@ -1,347 +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/base/sequence_manager_fuzzer_processor.h"
-
-#include <memory>
-
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/platform/scheduler/base/proto/sequence_manager_test_description.pb.h"
-#include "third_party/protobuf/src/google/protobuf/text_format.h"
-#include "third_party/protobuf/src/google/protobuf/util/message_differencer.h"
-
-namespace base {
-namespace sequence_manager {
-
-using testing::ContainerEq;
-
-class SequenceManagerFuzzerProcessorForTest
- : public SequenceManagerFuzzerProcessor {
- public:
- SequenceManagerFuzzerProcessorForTest()
- : SequenceManagerFuzzerProcessor(true) {}
-
- static void ParseAndRun(std::string test_description,
- std::vector<TaskForTest>* executed_tasks,
- std::vector<ActionForTest>* executed_actions) {
- SequenceManagerTestDescription proto_description;
- google::protobuf::TextFormat::ParseFromString(test_description,
- &proto_description);
-
- SequenceManagerFuzzerProcessorForTest processor;
- processor.RunTest(proto_description);
-
- if (executed_tasks)
- *executed_tasks = processor.ordered_tasks();
- if (executed_actions)
- *executed_actions = processor.ordered_actions();
- }
-
- using SequenceManagerFuzzerProcessor::ordered_actions;
- using SequenceManagerFuzzerProcessor::ordered_tasks;
-
- using SequenceManagerFuzzerProcessor::ActionForTest;
- using SequenceManagerFuzzerProcessor::TaskForTest;
-};
-
-using ActionForTest = SequenceManagerFuzzerProcessorForTest::ActionForTest;
-using TaskForTest = SequenceManagerFuzzerProcessorForTest::TaskForTest;
-
-TEST(SequenceManagerFuzzerProcessorTest, CreateTaskQueue) {
- std::vector<ActionForTest> executed_actions;
- SequenceManagerFuzzerProcessorForTest::ParseAndRun(R"(
- initial_actions {
- action_id : 1
- create_task_queue {
- }
- })",
- nullptr,
- &executed_actions);
-
- std::vector<ActionForTest> expected_actions;
- expected_actions.emplace_back(1, ActionForTest::ActionType::kCreateTaskQueue,
- 0);
-
- EXPECT_THAT(executed_actions, ContainerEq(expected_actions));
-}
-
-TEST(SequenceManagerFuzzerProcessorTest, PostDelayedTaskWithDuration) {
- std::vector<TaskForTest> executed_tasks;
- std::vector<ActionForTest> executed_actions;
-
- // Posts an 10 ms delayed task of duration 20 ms.
- SequenceManagerFuzzerProcessorForTest::ParseAndRun(R"(
- initial_actions {
- action_id : 1
- post_delayed_task {
- task_queue_id : 1
- delay_ms : 10
- task {
- task_id : 1
- duration_ms : 20
- }
- }
- })",
- &executed_tasks,
- &executed_actions);
-
- std::vector<TaskForTest> expected_tasks;
- expected_tasks.emplace_back(1, 10, 30);
- EXPECT_THAT(executed_tasks, ContainerEq(expected_tasks));
-
- std::vector<ActionForTest> expected_actions;
- expected_actions.emplace_back(1, ActionForTest::ActionType::kPostDelayedTask,
- 0);
- EXPECT_THAT(executed_actions, ContainerEq(expected_actions));
-}
-
-TEST(SequenceManagerFuzzerProcessorTest,
- TaskDurationBlocksOtherPendingTasksPostedFromOutsideOfTask) {
- std::vector<TaskForTest> executed_tasks;
- std::vector<ActionForTest> executed_actions;
-
- // Posts a task of duration 40 ms and a 10 ms delayed task of duration 20 ms.
- SequenceManagerFuzzerProcessorForTest::ParseAndRun(R"(
- initial_actions {
- action_id : 1
- post_delayed_task {
- delay_ms : 10
- task {
- task_id : 1
- duration_ms : 20
- }
- }
- }
- initial_actions {
- action_id :2
- post_delayed_task {
- delay_ms : 0
- task {
- task_id : 2
- duration_ms : 40
- }
- }
- })",
- &executed_tasks,
- &executed_actions);
-
- // Task with id 2 is expected to run first and block the other task until it
- // done.
- std::vector<TaskForTest> expected_tasks;
- expected_tasks.emplace_back(2, 0, 40);
- expected_tasks.emplace_back(1, 40, 60);
- EXPECT_THAT(executed_tasks, ContainerEq(expected_tasks));
-
- std::vector<ActionForTest> expected_actions;
- expected_actions.emplace_back(1, ActionForTest::ActionType::kPostDelayedTask,
- 0);
- expected_actions.emplace_back(2, ActionForTest::ActionType::kPostDelayedTask,
- 0);
- EXPECT_THAT(executed_actions, ContainerEq(expected_actions));
-}
-
-TEST(SequenceManagerFuzzerProcessorTest,
- TaskDurationBlocksOtherNonNestableTaskWhenPostedFromTheWithinTask) {
- // Posts an instant task of duration 40 ms that posts another non-nested
- // instant task.
- std::vector<TaskForTest> executed_tasks;
- SequenceManagerFuzzerProcessorForTest::ParseAndRun(R"(
- initial_actions {
- post_delayed_task {
- task {
- task_id : 1
- duration_ms : 40
- action {
- post_delayed_task {
- task {
- task_id : 2
- }
- }
- }
- }
- }
- })",
- &executed_tasks, nullptr);
-
- // Task with task id 1 is expected to run for 40 ms, and block the other
- // posted task from running until its done. Note that the task with id 2 is
- // blocked since it is non-nested, so it is not supposed to run from within
- // the posting task.
- std::vector<TaskForTest> expected_tasks;
- expected_tasks.emplace_back(1, 0, 40);
- expected_tasks.emplace_back(2, 40, 40);
-
- EXPECT_THAT(executed_tasks, ContainerEq(expected_tasks));
-}
-
-TEST(SequenceManagerFuzzerProcessorTest, PostNonEmptyTask) {
- // Posts a 5 ms delayed task of duration 40 ms that creates a task queue,
- // posts a 4 ms delayed task, posts an instant task, creates a task queue,
- // and then posts a 40 ms delayed task.
- std::vector<TaskForTest> executed_tasks;
- std::vector<ActionForTest> executed_actions;
-
- SequenceManagerFuzzerProcessorForTest::ParseAndRun(R"(
- initial_actions {
- action_id : 1
- post_delayed_task {
- delay_ms: 5
- task {
- task_id : 1
- duration_ms : 40
- action {
- action_id : 2
- create_task_queue {
- }
- }
- action {
- action_id : 3
- post_delayed_task {
- delay_ms : 4
- task {
- task_id : 2
- }
- }
- }
- action {
- action_id: 4
- post_delayed_task {
- task {
- task_id : 3
- }
- }
- }
- action {
- action_id : 5
- create_task_queue {
- }
- }
- action {
- action_id : 6
- post_delayed_task {
- delay_ms : 40
- task {
- task_id : 4
- }
- }
- }
- }
- }
- })",
- &executed_tasks,
- &executed_actions);
-
- // Task with task id 1 is expected to run first, and block all other pending
- // tasks until its done. The remaining tasks will be executed in
- // non-decreasing order of the delay parameter with ties broken by
- // the post order.
- std::vector<TaskForTest> expected_tasks;
- expected_tasks.emplace_back(1, 5, 45);
- expected_tasks.emplace_back(3, 45, 45);
- expected_tasks.emplace_back(2, 45, 45);
- expected_tasks.emplace_back(4, 45, 45);
- EXPECT_THAT(executed_tasks, ContainerEq(expected_tasks));
-
- std::vector<ActionForTest> expected_actions;
- expected_actions.emplace_back(1, ActionForTest::ActionType::kPostDelayedTask,
- 0);
- expected_actions.emplace_back(2, ActionForTest::ActionType::kCreateTaskQueue,
- 5);
- expected_actions.emplace_back(3, ActionForTest::ActionType::kPostDelayedTask,
- 5);
- expected_actions.emplace_back(4, ActionForTest::ActionType::kPostDelayedTask,
- 5);
- expected_actions.emplace_back(5, ActionForTest::ActionType::kCreateTaskQueue,
- 5);
- expected_actions.emplace_back(6, ActionForTest::ActionType::kPostDelayedTask,
- 5);
- EXPECT_THAT(executed_actions, ContainerEq(expected_actions));
-}
-
-TEST(SequenceManagerFuzzerProcessorTest, OrderOfSimpleUnnestedExecutedActions) {
- // Creates a task queue, creates a task queue after 10 ms of delay, posts a
- // task after 20 ms delay, posts a 10 ms duration task after 15 ms of delay,
- // and posts a task after 100 ms of delay.
- std::vector<TaskForTest> executed_tasks;
- std::vector<ActionForTest> executed_actions;
- SequenceManagerFuzzerProcessorForTest::ParseAndRun(R"(
- initial_actions {
- action_id : 1
- create_task_queue {
- }
- }
- initial_actions {
- action_id : 2
- post_delayed_task {
- delay_ms : 10
- task {
- task_id : 1
- action {
- action_id : 3
- create_task_queue {
- }
- }
- }
- }
- }
- initial_actions {
- action_id : 4
- post_delayed_task {
- delay_ms : 20
- task {
- task_id : 2
- }
- }
- }
- initial_actions {
- action_id : 5
- post_delayed_task {
- delay_ms : 15
- task {
- task_id : 3
- duration_ms : 10
- }
- }
- }
- initial_actions {
- action_id : 6
- post_delayed_task {
- delay_ms : 100
- task {
- task_id : 4
- }
- }
- })",
- &executed_tasks,
- &executed_actions);
-
- // Tasks are expected to run in order of non-decreasing delay with ties broken
- // by order of posting. Note that the task with id 3 will block the task with
- // id 2 from running at its scheduled time.
- std::vector<TaskForTest> expected_tasks;
- expected_tasks.emplace_back(1, 10, 10);
- expected_tasks.emplace_back(3, 15, 25);
- expected_tasks.emplace_back(2, 25, 25);
- expected_tasks.emplace_back(4, 100, 100);
- EXPECT_THAT(executed_tasks, ContainerEq(expected_tasks));
-
- std::vector<ActionForTest> expected_actions;
- expected_actions.emplace_back(1, ActionForTest::ActionType::kCreateTaskQueue,
- 0);
- expected_actions.emplace_back(2, ActionForTest::ActionType::kPostDelayedTask,
- 0);
- expected_actions.emplace_back(4, ActionForTest::ActionType::kPostDelayedTask,
- 0);
- expected_actions.emplace_back(5, ActionForTest::ActionType::kPostDelayedTask,
- 0);
- expected_actions.emplace_back(6, ActionForTest::ActionType::kPostDelayedTask,
- 0);
- expected_actions.emplace_back(3, ActionForTest::ActionType::kCreateTaskQueue,
- 10);
- EXPECT_THAT(executed_actions, ContainerEq(expected_actions));
-}
-
-} // namespace sequence_manager
-} // namespace base
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/child/features.cc b/chromium/third_party/blink/renderer/platform/scheduler/child/features.cc
new file mode 100644
index 00000000000..e16aa5d850d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/scheduler/child/features.cc
@@ -0,0 +1,19 @@
+// 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/child/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/child/features.h b/chromium/third_party/blink/renderer/platform/scheduler/child/features.h
index 4b7c8b74743..65aad5124e1 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/child/features.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/child/features.h
@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_CHILD_FEATURES_H_
#include "base/feature_list.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
namespace blink {
namespace scheduler {
@@ -133,6 +134,15 @@ 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};
+
+// Parameters for |kThrottleAndFreezeTaskTypes|.
+extern const char PLATFORM_EXPORT kThrottleableTaskTypesListParam[];
+extern const char PLATFORM_EXPORT kFreezableTaskTypesListParam[];
+
} // namespace scheduler
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/child/process_state.h b/chromium/third_party/blink/renderer/platform/scheduler/child/process_state.h
index 5b5899d6603..37d0fbcc5fd 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/child/process_state.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/child/process_state.h
@@ -7,14 +7,16 @@
#include <atomic>
+#include "third_party/blink/renderer/platform/platform_export.h"
+
namespace blink {
namespace scheduler {
namespace internal {
// Helper lock-free struct to share main state of the process between threads
-// for recording methods.
+// for recording metrics.
// This class should not be used for synchronization between threads.
-struct ProcessState {
+struct PLATFORM_EXPORT ProcessState {
static ProcessState* Get();
std::atomic_bool is_process_backgrounded;
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.cc b/chromium/third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.cc
deleted file mode 100644
index 8e672dcb97d..00000000000
--- a/chromium/third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.h"
-
-#include <utility>
-
-#include "base/bind.h"
-#include "base/location.h"
-#include "base/task/sequence_manager/task_queue.h"
-
-namespace blink {
-namespace scheduler {
-
-scoped_refptr<TaskQueueWithTaskType> TaskQueueWithTaskType::Create(
- scoped_refptr<base::sequence_manager::TaskQueue> task_queue,
- TaskType task_type) {
- return base::WrapRefCounted(
- new TaskQueueWithTaskType(std::move(task_queue), task_type));
-}
-
-bool TaskQueueWithTaskType::RunsTasksInCurrentSequence() const {
- return task_queue_->RunsTasksInCurrentSequence();
-}
-
-TaskQueueWithTaskType::TaskQueueWithTaskType(
- scoped_refptr<base::sequence_manager::TaskQueue> task_queue,
- TaskType task_type)
- : task_queue_(std::move(task_queue)), task_type_(task_type) {}
-
-TaskQueueWithTaskType::~TaskQueueWithTaskType() = default;
-
-bool TaskQueueWithTaskType::PostDelayedTask(const base::Location& location,
- base::OnceClosure task,
- base::TimeDelta delay) {
- return task_queue_->PostTaskWithMetadata(
- base::sequence_manager::TaskQueue::PostedTask(
- std::move(task), location, delay, base::Nestable::kNestable,
- static_cast<int>(task_type_)));
-}
-
-bool TaskQueueWithTaskType::PostNonNestableDelayedTask(
- const base::Location& location,
- base::OnceClosure task,
- base::TimeDelta delay) {
- return task_queue_->PostTaskWithMetadata(
- base::sequence_manager::TaskQueue::PostedTask(
- std::move(task), location, delay, base::Nestable::kNonNestable,
- static_cast<int>(task_type_)));
-}
-
-} // namespace scheduler
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.h b/chromium/third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.h
deleted file mode 100644
index 4232da92248..00000000000
--- a/chromium/third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.h
+++ /dev/null
@@ -1,60 +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_SCHEDULER_CHILD_TASK_QUEUE_WITH_TASK_TYPE_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_CHILD_TASK_QUEUE_WITH_TASK_TYPE_H_
-
-#include <memory>
-
-#include "base/callback.h"
-#include "base/macros.h"
-#include "base/memory/scoped_refptr.h"
-#include "base/single_thread_task_runner.h"
-#include "base/time/time.h"
-#include "third_party/blink/public/platform/task_type.h"
-#include "third_party/blink/renderer/platform/platform_export.h"
-
-namespace base {
-namespace sequence_manager {
-class TaskQueue;
-}
-} // namespace base
-
-namespace blink {
-namespace scheduler {
-
-class PLATFORM_EXPORT TaskQueueWithTaskType
- : public base::SingleThreadTaskRunner {
- public:
- static scoped_refptr<TaskQueueWithTaskType> Create(
- scoped_refptr<base::sequence_manager::TaskQueue> task_queue,
- TaskType task_type);
-
- // base::SingleThreadTaskRunner implementation:
- bool RunsTasksInCurrentSequence() const override;
-
- protected:
- bool PostDelayedTask(const base::Location&,
- base::OnceClosure,
- base::TimeDelta) override;
- bool PostNonNestableDelayedTask(const base::Location&,
- base::OnceClosure,
- base::TimeDelta) override;
-
- private:
- TaskQueueWithTaskType(
- scoped_refptr<base::sequence_manager::TaskQueue> task_queue,
- TaskType task_type);
- ~TaskQueueWithTaskType() override;
-
- scoped_refptr<base::sequence_manager::TaskQueue> task_queue_;
- TaskType task_type_;
-
- DISALLOW_COPY_AND_ASSIGN(TaskQueueWithTaskType);
-};
-
-} // namespace scheduler
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_CHILD_TASK_RUNNER_IMPL_H_
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/child/webthread_base.cc b/chromium/third_party/blink/renderer/platform/scheduler/child/webthread_base.cc
index 2a9efbd4d75..8d80881c7cc 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/child/webthread_base.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/child/webthread_base.cc
@@ -16,7 +16,6 @@
#include "base/pending_task.h"
#include "base/threading/platform_thread.h"
#include "third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler.h"
-#include "third_party/blink/renderer/platform/scheduler/utility/webthread_impl_for_utility_thread.h"
#include "third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.h"
namespace blink {
@@ -124,9 +123,5 @@ std::unique_ptr<WebThreadBase> WebThreadBase::CreateCompositorThread(
return std::make_unique<WebThreadForCompositor>(params);
}
-std::unique_ptr<WebThreadBase> WebThreadBase::InitializeUtilityThread() {
- return std::make_unique<WebThreadImplForUtilityThread>();
-}
-
} // namespace scheduler
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler.cc b/chromium/third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler.cc
index 7c9a23d8794..1d01b3e5292 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler.cc
@@ -12,7 +12,6 @@
#include "base/task/sequence_manager/task_queue.h"
#include "base/time/default_tick_clock.h"
#include "third_party/blink/public/platform/task_type.h"
-#include "third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.h"
#include "third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy.h"
#include "third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h"
@@ -65,8 +64,8 @@ void WebThreadImplForWorkerScheduler::InitOnThread(
non_main_thread_scheduler_ = CreateNonMainThreadScheduler();
non_main_thread_scheduler_->Init();
task_queue_ = non_main_thread_scheduler_->DefaultTaskQueue();
- task_runner_ = TaskQueueWithTaskType::Create(
- task_queue_, TaskType::kWorkerThreadTaskQueueDefault);
+ task_runner_ =
+ task_queue_->CreateTaskRunner(TaskType::kWorkerThreadTaskQueueDefault);
base::MessageLoopCurrent::Get()->AddDestructionObserver(this);
completion->Signal();
}
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler.h b/chromium/third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler.h
index 59a9fcdb7eb..1114407ab4d 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler.h
@@ -14,9 +14,6 @@
#include "third_party/blink/public/platform/web_private_ptr.h"
namespace base {
-namespace sequence_manager {
-class TaskQueue;
-}
class WaitableEvent;
}
@@ -28,6 +25,7 @@ namespace blink {
namespace scheduler {
class NonMainThreadSchedulerImpl;
+class NonMainThreadTaskQueue;
class WorkerSchedulerProxy;
class PLATFORM_EXPORT WebThreadImplForWorkerScheduler
@@ -80,7 +78,7 @@ class PLATFORM_EXPORT WebThreadImplForWorkerScheduler
std::unique_ptr<scheduler::WorkerSchedulerProxy> worker_scheduler_proxy_;
std::unique_ptr<scheduler::NonMainThreadSchedulerImpl>
non_main_thread_scheduler_;
- scoped_refptr<base::sequence_manager::TaskQueue> task_queue_;
+ scoped_refptr<NonMainThreadTaskQueue> task_queue_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
base::AtomicFlag was_shutdown_on_thread_;
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/background_scheduler.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/background_scheduler.cc
index 18d898e39f3..dbf59fae8f7 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/background_scheduler.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/background_scheduler.cc
@@ -5,14 +5,22 @@
#include "third_party/blink/renderer/platform/scheduler/public/background_scheduler.h"
#include "base/location.h"
-#include "base/task_scheduler/post_task.h"
+#include "base/task/post_task.h"
namespace blink {
void BackgroundScheduler::PostOnBackgroundThread(const base::Location& location,
CrossThreadClosure closure) {
- base::PostTaskWithTraits(location,
- {base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
+ PostOnBackgroundThreadWithTraits(
+ location, {base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
+ std::move(closure));
+}
+
+void BackgroundScheduler::PostOnBackgroundThreadWithTraits(
+ const base::Location& location,
+ const base::TaskTraits& traits,
+ CrossThreadClosure closure) {
+ base::PostTaskWithTraits(location, traits,
ConvertToBaseCallback(std::move(closure)));
}
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 6929547040f..79b7f6b4f37 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
@@ -10,7 +10,6 @@
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/trace_event_argument.h"
-#include "third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.h"
#include "third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h"
namespace blink {
@@ -39,8 +38,8 @@ IdleHelper::IdleHelper(
&IdleHelper::OnIdleTaskPostedOnMainThread, weak_idle_helper_ptr_));
idle_task_runner_ = base::MakeRefCounted<SingleThreadIdleTaskRunner>(
- TaskQueueWithTaskType::Create(idle_queue_,
- TaskType::kMainThreadTaskQueueIdle),
+ idle_queue_->CreateTaskRunner(
+ static_cast<int>(TaskType::kMainThreadTaskQueueIdle)),
this);
// This fence will block any idle tasks from running.
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/metrics_helper.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/metrics_helper.cc
index 7a802b74f53..3755be27535 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/metrics_helper.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/metrics_helper.cc
@@ -17,14 +17,43 @@ namespace {
constexpr base::TimeDelta kLongTaskDiscardingThreshold =
base::TimeDelta::FromSeconds(30);
+scheduling_metrics::ThreadType ConvertBlinkThreadType(
+ WebThreadType thread_type) {
+ switch (thread_type) {
+ case WebThreadType::kMainThread:
+ return scheduling_metrics::ThreadType::kRendererMainThread;
+ case WebThreadType::kCompositorThread:
+ return scheduling_metrics::ThreadType::kRendererCompositorThread;
+ case WebThreadType::kDedicatedWorkerThread:
+ return scheduling_metrics::ThreadType::kRendererDedicatedWorkerThread;
+ case WebThreadType::kServiceWorkerThread:
+ return scheduling_metrics::ThreadType::kRendererServiceWorkerThread;
+ case WebThreadType::kAnimationWorkletThread:
+ case WebThreadType::kAudioWorkletThread:
+ case WebThreadType::kDatabaseThread:
+ case WebThreadType::kFileThread:
+ case WebThreadType::kHRTFDatabaseLoaderThread:
+ case WebThreadType::kOfflineAudioRenderThread:
+ case WebThreadType::kReverbConvolutionBackgroundThread:
+ case WebThreadType::kScriptStreamerThread:
+ case WebThreadType::kSharedWorkerThread:
+ case WebThreadType::kUnspecifiedWorkerThread:
+ case WebThreadType::kWebAudioThread:
+ case WebThreadType::kTestThread:
+ return scheduling_metrics::ThreadType::kRendererOtherBlinkThread;
+ case WebThreadType::kCount:
+ NOTREACHED();
+ return scheduling_metrics::ThreadType::kCount;
+ }
+}
+
} // namespace
MetricsHelper::MetricsHelper(WebThreadType thread_type,
bool has_cpu_timing_for_each_task)
: thread_type_(thread_type),
- has_cpu_timing_for_each_task_(has_cpu_timing_for_each_task),
- last_known_time_(has_cpu_timing_for_each_task_ ? base::ThreadTicks::Now()
- : base::ThreadTicks()),
+ thread_metrics_(ConvertBlinkThreadType(thread_type),
+ has_cpu_timing_for_each_task),
thread_task_duration_reporter_(
"RendererScheduler.TaskDurationPerThreadType2"),
thread_task_cpu_duration_reporter_(
@@ -36,11 +65,7 @@ MetricsHelper::MetricsHelper(WebThreadType thread_type,
background_thread_task_duration_reporter_(
"RendererScheduler.TaskDurationPerThreadType2.Background"),
background_thread_task_cpu_duration_reporter_(
- "RendererScheduler.TaskCPUDurationPerThreadType2.Background"),
- tracked_cpu_duration_reporter_(
- "Scheduler.Experimental.Renderer.CPUTimePerThread.Tracked"),
- non_tracked_cpu_duration_reporter_(
- "Scheduler.Experimental.Renderer.CPUTimePerThread.Untracked") {}
+ "RendererScheduler.TaskCPUDurationPerThreadType2.Background") {}
MetricsHelper::~MetricsHelper() {}
@@ -57,7 +82,8 @@ void MetricsHelper::RecordCommonTaskMetrics(
base::sequence_manager::TaskQueue* queue,
const base::sequence_manager::TaskQueue::Task& task,
const base::sequence_manager::TaskQueue::TaskTiming& task_timing) {
- DCHECK(!has_cpu_timing_for_each_task_ || task_timing.has_thread_time());
+ thread_metrics_.RecordTaskMetrics(queue, task, task_timing);
+
thread_task_duration_reporter_.RecordTask(thread_type_,
task_timing.wall_duration());
@@ -82,15 +108,6 @@ void MetricsHelper::RecordCommonTaskMetrics(
foreground_thread_task_cpu_duration_reporter_.RecordTask(
thread_type_, task_timing.thread_duration());
}
-
- if (has_cpu_timing_for_each_task_) {
- non_tracked_cpu_duration_reporter_.RecordTask(
- thread_type_, task_timing.start_thread_time() - last_known_time_);
- tracked_cpu_duration_reporter_.RecordTask(thread_type_,
- task_timing.thread_duration());
-
- last_known_time_ = task_timing.end_thread_time();
- }
}
} // namespace scheduler
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/metrics_helper.h b/chromium/third_party/blink/renderer/platform/scheduler/common/metrics_helper.h
index 643523250ef..e2f6697e4bd 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/metrics_helper.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/metrics_helper.h
@@ -8,10 +8,11 @@
#include "base/optional.h"
#include "base/task/sequence_manager/task_queue.h"
#include "base/time/time.h"
+#include "components/scheduling_metrics/task_duration_metric_reporter.h"
+#include "components/scheduling_metrics/thread_metrics.h"
+#include "components/scheduling_metrics/total_duration_metric_reporter.h"
#include "third_party/blink/public/platform/web_thread_type.h"
#include "third_party/blink/renderer/platform/platform_export.h"
-#include "third_party/blink/renderer/platform/scheduler/common/total_duration_metric_reporter.h"
-#include "third_party/blink/renderer/platform/scheduler/util/task_duration_metric_reporter.h"
namespace base {
namespace sequence_manager {
@@ -22,6 +23,8 @@ class TaskQueue;
namespace blink {
namespace scheduler {
+constexpr int kUkmMetricVersion = 2;
+
// Helper class to take care of task metrics shared between main thread
// and worker threads of the renderer process, including per-thread
// task metrics.
@@ -50,23 +53,22 @@ class PLATFORM_EXPORT MetricsHelper {
protected:
const WebThreadType thread_type_;
- const bool has_cpu_timing_for_each_task_;
private:
- base::ThreadTicks last_known_time_;
+ scheduling_metrics::ThreadMetrics thread_metrics_;
- TaskDurationMetricReporter<WebThreadType> thread_task_duration_reporter_;
- TaskDurationMetricReporter<WebThreadType> thread_task_cpu_duration_reporter_;
- TaskDurationMetricReporter<WebThreadType>
+ scheduling_metrics::TaskDurationMetricReporter<WebThreadType>
+ thread_task_duration_reporter_;
+ scheduling_metrics::TaskDurationMetricReporter<WebThreadType>
+ thread_task_cpu_duration_reporter_;
+ scheduling_metrics::TaskDurationMetricReporter<WebThreadType>
foreground_thread_task_duration_reporter_;
- TaskDurationMetricReporter<WebThreadType>
+ scheduling_metrics::TaskDurationMetricReporter<WebThreadType>
foreground_thread_task_cpu_duration_reporter_;
- TaskDurationMetricReporter<WebThreadType>
+ scheduling_metrics::TaskDurationMetricReporter<WebThreadType>
background_thread_task_duration_reporter_;
- TaskDurationMetricReporter<WebThreadType>
+ scheduling_metrics::TaskDurationMetricReporter<WebThreadType>
background_thread_task_cpu_duration_reporter_;
- TaskDurationMetricReporter<WebThreadType> tracked_cpu_duration_reporter_;
- TaskDurationMetricReporter<WebThreadType> non_tracked_cpu_duration_reporter_;
DISALLOW_COPY_AND_ASSIGN(MetricsHelper);
};
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/metrics_helper_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/metrics_helper_unittest.cc
index 8fec7193d4e..5af9e4ed515 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/metrics_helper_unittest.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/metrics_helper_unittest.cc
@@ -85,34 +85,5 @@ TEST(MetricsHelperTest, TaskDurationPerThreadType) {
static_cast<int>(WebThreadType::kUnspecifiedWorkerThread), 25)));
}
-TEST(MetricsHelperTest, TrackedCPUTimeMetrics) {
- base::HistogramTester histogram_tester;
- base::subtle::ScopedTimeClockOverrides time_override(
- []() { return base::Time(); }, []() { return Seconds(1); },
- []() { return ThreadSeconds(1); });
-
- MetricsHelperForTest main_thread_metrics(
- WebThreadType::kMainThread, true /* has_cpu_timing_for_each_task */);
-
- main_thread_metrics.RecordCommonTaskMetrics(
- nullptr, FakeTask(),
- FakeTaskTiming(Seconds(10), Seconds(50), ThreadSeconds(5),
- ThreadSeconds(15)));
- main_thread_metrics.RecordCommonTaskMetrics(
- nullptr, FakeTask(),
- FakeTaskTiming(Seconds(10), Seconds(50), ThreadSeconds(20),
- ThreadSeconds(25)));
-
- EXPECT_THAT(histogram_tester.GetAllSamples(
- "Scheduler.Experimental.Renderer.CPUTimePerThread.Tracked"),
- testing::UnorderedElementsAre(base::Bucket(
- static_cast<int>(WebThreadType::kMainThread), 15)));
- // 9 = 4 seconds before task 1 and 5 seconds between tasks 1 and 2.
- EXPECT_THAT(histogram_tester.GetAllSamples(
- "Scheduler.Experimental.Renderer.CPUTimePerThread.Untracked"),
- testing::UnorderedElementsAre(base::Bucket(
- static_cast<int>(WebThreadType::kMainThread), 9)));
-}
-
} // namespace scheduler
} // namespace blink
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 dc58a367443..ae458f1a2e1 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
@@ -10,7 +10,6 @@
#include "base/time/default_tick_clock.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/trace_event_argument.h"
-#include "third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.h"
namespace blink {
namespace scheduler {
@@ -33,7 +32,7 @@ void SchedulerHelper::InitDefaultQueues(
control_task_queue->SetQueuePriority(TaskQueue::kControlPriority);
default_task_runner_ =
- TaskQueueWithTaskType::Create(default_task_queue, default_task_type);
+ default_task_queue->CreateTaskRunner(static_cast<int>(default_task_type));
DCHECK(sequence_manager_);
sequence_manager_->SetDefaultTaskRunner(default_task_runner_);
@@ -136,7 +135,9 @@ void SchedulerHelper::OnExitNestedRunLoop() {
}
const base::TickClock* SchedulerHelper::GetClock() const {
- return sequence_manager_->GetTickClock();
+ if (sequence_manager_)
+ return sequence_manager_->GetTickClock();
+ return nullptr;
}
base::TimeTicks SchedulerHelper::NowTicks() const {
@@ -146,6 +147,10 @@ base::TimeTicks SchedulerHelper::NowTicks() const {
return base::TimeTicks::Now();
}
+void SchedulerHelper::SetTimerSlack(base::TimerSlack timer_slack) {
+ sequence_manager_->SetTimerSlack(timer_slack);
+}
+
double SchedulerHelper::GetSamplingRateForRecordingCPUTime() const {
if (sequence_manager_) {
return sequence_manager_->GetMetricRecordingSettings()
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 2cb6a3e9f27..577f1ed8f85 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
@@ -33,6 +33,7 @@ class PLATFORM_EXPORT SchedulerHelper
const base::TickClock* GetClock() const;
base::TimeTicks NowTicks() const;
+ void SetTimerSlack(base::TimerSlack timer_slack);
// Returns the default task queue.
virtual scoped_refptr<base::sequence_manager::TaskQueue>
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
new file mode 100644
index 00000000000..426d1e41c1f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/simple_thread_scheduler.cc
@@ -0,0 +1,83 @@
+// 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/simple_thread_scheduler.h"
+
+#include "base/threading/thread_task_runner_handle.h"
+#include "base/time/time.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
+
+namespace blink {
+namespace scheduler {
+
+SimpleThreadScheduler::SimpleThreadScheduler() {}
+
+SimpleThreadScheduler::~SimpleThreadScheduler() {}
+
+void SimpleThreadScheduler::Shutdown() {}
+
+bool SimpleThreadScheduler::ShouldYieldForHighPriorityWork() {
+ return false;
+}
+
+bool SimpleThreadScheduler::CanExceedIdleDeadlineIfRequired() const {
+ return false;
+}
+
+void SimpleThreadScheduler::PostIdleTask(const base::Location& location,
+ WebThread::IdleTask task) {
+ base::TimeTicks deadline =
+ base::TimeTicks::Now() + base::TimeDelta::FromSeconds(1);
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ location, WTF::Bind(std::move(task), deadline));
+}
+
+void SimpleThreadScheduler::PostNonNestableIdleTask(
+ const base::Location& location,
+ WebThread::IdleTask task) {
+ base::TimeTicks deadline =
+ base::TimeTicks::Now() + base::TimeDelta::FromSeconds(1);
+ base::ThreadTaskRunnerHandle::Get()->PostNonNestableTask(
+ location, WTF::Bind(std::move(task), deadline));
+}
+
+void SimpleThreadScheduler::AddRAILModeObserver(WebRAILModeObserver* observer) {
+}
+
+scoped_refptr<base::SingleThreadTaskRunner>
+SimpleThreadScheduler::V8TaskRunner() {
+ return base::ThreadTaskRunnerHandle::Get();
+}
+
+scoped_refptr<base::SingleThreadTaskRunner>
+SimpleThreadScheduler::CompositorTaskRunner() {
+ return base::ThreadTaskRunnerHandle::Get();
+}
+
+std::unique_ptr<PageScheduler> SimpleThreadScheduler::CreatePageScheduler(
+ PageScheduler::Delegate* delegate) {
+ return nullptr;
+}
+
+std::unique_ptr<ThreadScheduler::RendererPauseHandle>
+SimpleThreadScheduler::PauseScheduler() {
+ return nullptr;
+}
+
+base::TimeTicks SimpleThreadScheduler::MonotonicallyIncreasingVirtualTime() {
+ return base::TimeTicks::Now();
+}
+
+void SimpleThreadScheduler::AddTaskObserver(
+ base::MessageLoop::TaskObserver* task_observer) {}
+
+void SimpleThreadScheduler::RemoveTaskObserver(
+ base::MessageLoop::TaskObserver* task_observer) {}
+
+NonMainThreadSchedulerImpl* SimpleThreadScheduler::AsNonMainThreadScheduler() {
+ return nullptr;
+}
+
+} // namespace scheduler
+} // namespace blink
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
new file mode 100644
index 00000000000..b6c83d563c0
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/simple_thread_scheduler.h
@@ -0,0 +1,75 @@
+// 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_SCHEDULER_COMMON_SIMPLE_THREAD_SCHEDULER_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_COMMON_SIMPLE_THREAD_SCHEDULER_H_
+
+#include "base/macros.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
+
+namespace blink {
+namespace scheduler {
+
+// ThreadScheduler implementation that should be used when you don't have a
+// dedicated ThreadScheduler instance. This is essentially a scheduler doesn't
+// really schedule anything -- it just runs tasks as they come.
+//
+// This scheduler does not implement several features (see comments at each
+// function). If you invoke a Blink functionality that relies on an
+// unimplemented scheduler function, you might observe crashes or misbehavior.
+// Apparently we don't rely on those missing features at least for things that
+// use this scheduler.
+
+class SimpleThreadScheduler : public ThreadScheduler {
+ public:
+ SimpleThreadScheduler();
+ ~SimpleThreadScheduler() override;
+
+ // Do nothing.
+ void Shutdown() override;
+
+ // Always return false.
+ bool ShouldYieldForHighPriorityWork() override;
+
+ // Always return false.
+ bool CanExceedIdleDeadlineIfRequired() const override;
+
+ // Post the task to the thread task runner with the time limit of 1 second.
+ void PostIdleTask(const base::Location&, WebThread::IdleTask) override;
+ void PostNonNestableIdleTask(const base::Location&,
+ WebThread::IdleTask) override;
+
+ // Do nothing (the observer won't get notified).
+ void AddRAILModeObserver(WebRAILModeObserver*) override;
+
+ // Return the thread task runner (there's no separate task runner for them).
+ scoped_refptr<base::SingleThreadTaskRunner> V8TaskRunner() override;
+ scoped_refptr<base::SingleThreadTaskRunner> CompositorTaskRunner() override;
+
+ // Unsupported. Return nullptr, and it may cause a crash.
+ std::unique_ptr<PageScheduler> CreatePageScheduler(
+ PageScheduler::Delegate*) override;
+
+ // Unsupported. Return nullptr, and it may cause a crash.
+ std::unique_ptr<RendererPauseHandle> PauseScheduler() override;
+
+ // Return the current time.
+ base::TimeTicks MonotonicallyIncreasingVirtualTime() override;
+
+ // Unsupported. The observer won't get called. May break some functionalities
+ // that rely on the task observer.
+ void AddTaskObserver(base::MessageLoop::TaskObserver*) override;
+ void RemoveTaskObserver(base::MessageLoop::TaskObserver*) override;
+
+ // Return nullptr.
+ NonMainThreadSchedulerImpl* AsNonMainThreadScheduler() override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SimpleThreadScheduler);
+};
+
+} // namespace scheduler
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_COMMON_SIMPLE_THREAD_SCHEDULER_H_
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.cc
new file mode 100644
index 00000000000..afcd0c2cdc9
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.cc
@@ -0,0 +1,51 @@
+// 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/thread_scheduler_impl.h"
+
+#include "third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h"
+
+namespace blink {
+namespace scheduler {
+
+namespace {
+const double kSamplingRateForTaskUkm = 0.0001;
+} // namespace
+
+ThreadSchedulerImpl::ThreadSchedulerImpl()
+ : ukm_task_sampling_rate_(kSamplingRateForTaskUkm),
+ uniform_distribution_(0.0f, 1.0f) {}
+
+ThreadSchedulerImpl::~ThreadSchedulerImpl() = default;
+
+bool ThreadSchedulerImpl::ShouldIgnoreTaskForUkm(bool has_thread_time,
+ double* sampling_rate) {
+ const double thread_time_sampling_rate =
+ GetHelper()->GetSamplingRateForRecordingCPUTime();
+ if (thread_time_sampling_rate && *sampling_rate < thread_time_sampling_rate) {
+ if (!has_thread_time)
+ return true;
+ *sampling_rate /= thread_time_sampling_rate;
+ }
+ return false;
+}
+
+bool ThreadSchedulerImpl::ShouldRecordTaskUkm(bool has_thread_time) {
+ double sampling_rate = ukm_task_sampling_rate_;
+
+ // If thread_time is sampled as well, try to align UKM sampling with it so
+ // that we only record UKMs for tasks that also record thread_time.
+ if (ShouldIgnoreTaskForUkm(has_thread_time, &sampling_rate)) {
+ return false;
+ }
+
+ return uniform_distribution_(random_generator_) < sampling_rate;
+}
+
+void ThreadSchedulerImpl::SetUkmTaskSamplingRateForTest(double sampling_rate) {
+ ukm_task_sampling_rate_ = sampling_rate;
+}
+
+} // namespace scheduler
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.h b/chromium/third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.h
index 20ac914b910..270cbdfbc47 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.h
@@ -7,6 +7,8 @@
#include "third_party/blink/renderer/platform/platform_export.h"
+#include <random>
+
#include "base/single_thread_task_runner.h"
#include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
@@ -21,6 +23,7 @@ class TimeDomain;
namespace blink {
namespace scheduler {
+class SchedulerHelper;
// Scheduler-internal interface for the common methods between
// MainThreadSchedulerImpl and NonMainThreadSchedulerImpl which should
@@ -42,6 +45,28 @@ class PLATFORM_EXPORT ThreadSchedulerImpl : public ThreadScheduler,
virtual base::sequence_manager::TimeDomain* GetActiveTimeDomain() = 0;
virtual const base::TickClock* GetTickClock() = 0;
+
+ protected:
+ ThreadSchedulerImpl();
+ ~ThreadSchedulerImpl() override;
+
+ // Returns true if the current task should not be reported in UKM because no
+ // thread time was recorded for it. Also updates |sampling_rate| to account
+ // for the ignored tasks by sampling the remaining tasks with higher
+ // probability.
+ bool ShouldIgnoreTaskForUkm(bool has_thread_time, double* sampling_rate);
+
+ // Returns true with probability of kSamplingRateForTaskUkm.
+ bool ShouldRecordTaskUkm(bool has_thread_time);
+
+ virtual SchedulerHelper* GetHelper() = 0;
+
+ void SetUkmTaskSamplingRateForTest(double sampling_rate);
+
+ double ukm_task_sampling_rate_;
+
+ std::mt19937_64 random_generator_;
+ std::uniform_real_distribution<double> uniform_distribution_;
};
} // namespace scheduler
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/total_duration_metric_reporter.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/total_duration_metric_reporter.cc
deleted file mode 100644
index 54ed2afdb4a..00000000000
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/total_duration_metric_reporter.cc
+++ /dev/null
@@ -1,47 +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/total_duration_metric_reporter.h"
-
-namespace blink {
-namespace scheduler {
-
-namespace {
-
-constexpr base::TimeDelta kMinimalValue = base::TimeDelta::FromSeconds(1);
-constexpr base::TimeDelta kMaximalValue = base::TimeDelta::FromHours(1);
-constexpr int kBucketCount = 50;
-
-} // namespace
-
-TotalDurationMetricReporter::TotalDurationMetricReporter(
- const char* positive_histogram_name,
- const char* negative_histogram_name)
- : positive_histogram_(base::Histogram::FactoryGet(
- positive_histogram_name,
- kMinimalValue.InSeconds(),
- kMaximalValue.InSeconds(),
- kBucketCount,
- base::Histogram::kUmaTargetedHistogramFlag)),
- negative_histogram_(base::Histogram::FactoryGet(
- negative_histogram_name,
- kMinimalValue.InSeconds(),
- kMaximalValue.InSeconds(),
- kBucketCount,
- base::Histogram::kUmaTargetedHistogramFlag)) {}
-
-void TotalDurationMetricReporter::RecordAdditionalDuration(
- base::TimeDelta duration) {
- if (reported_value_)
- negative_histogram_->Add(reported_value_->InSeconds());
- reported_value_ = reported_value_.value_or(base::TimeDelta()) + duration;
- positive_histogram_->Add(reported_value_->InSeconds());
-}
-
-void TotalDurationMetricReporter::Reset() {
- reported_value_ = base::nullopt;
-}
-
-} // namespace scheduler
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/total_duration_metric_reporter.h b/chromium/third_party/blink/renderer/platform/scheduler/common/total_duration_metric_reporter.h
deleted file mode 100644
index f15e5011399..00000000000
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/total_duration_metric_reporter.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_SCHEDULER_COMMON_TOTAL_DURATION_METRIC_REPORTER_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_COMMON_TOTAL_DURATION_METRIC_REPORTER_H_
-
-#include "base/metrics/histogram.h"
-#include "base/optional.h"
-#include "base/time/time.h"
-#include "third_party/blink/renderer/platform/platform_export.h"
-
-namespace blink {
-namespace scheduler {
-
-// Helper class to measure the total duration of the event accounting for
-// possibility of the renderer process going away at any point.
-//
-// This is implemented by "undoing" old total value and "applying" new one
-// each time RecordAdditionalDuration() is called.
-// "Undoing" is implemented by having a second "negative" histogram, so to
-// obtain the result, |positive_histogram - negative_histogram| difference
-// should be analysed.
-class PLATFORM_EXPORT TotalDurationMetricReporter {
- public:
- TotalDurationMetricReporter(const char* positive_histogram_name,
- const char* negative_histogram_name);
-
- void RecordAdditionalDuration(base::TimeDelta duration);
-
- void Reset();
-
- private:
- base::Optional<base::TimeDelta> reported_value_;
-
- base::HistogramBase* positive_histogram_;
- base::HistogramBase* negative_histogram_;
-};
-
-} // namespace scheduler
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_COMMON_TOTAL_DURATION_METRIC_REPORTER_H_
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/total_duration_metric_reporter_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/total_duration_metric_reporter_unittest.cc
deleted file mode 100644
index c30cfaae128..00000000000
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/total_duration_metric_reporter_unittest.cc
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/platform/scheduler/common/total_duration_metric_reporter.h"
-#include "base/test/metrics/histogram_tester.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace blink {
-namespace scheduler {
-
-TEST(TotalDurationMetricReporterTest, Test) {
- base::HistogramTester histogram_tester;
-
- TotalDurationMetricReporter metric_reporter("TestHistogram.Positive",
- "TestHistogram.Negative");
-
- metric_reporter.RecordAdditionalDuration(base::TimeDelta::FromSeconds(1));
- metric_reporter.RecordAdditionalDuration(base::TimeDelta::FromSeconds(2));
- metric_reporter.RecordAdditionalDuration(base::TimeDelta::FromSeconds(5));
-
- metric_reporter.Reset();
-
- metric_reporter.RecordAdditionalDuration(base::TimeDelta::FromSeconds(10));
-
- std::map<base::Histogram::Sample, base::HistogramBase::Count> result;
-
- for (const base::Bucket& bucket :
- histogram_tester.GetAllSamples("TestHistogram.Positive")) {
- result[bucket.min] += bucket.count;
- }
- for (const base::Bucket& bucket :
- histogram_tester.GetAllSamples("TestHistogram.Negative")) {
- result[bucket.min] -= bucket.count;
- }
-
- // 1 and 3 correspond to "reverted" values.
- EXPECT_THAT(result, testing::UnorderedElementsAre(
- std::make_pair(1, 0), std::make_pair(3, 0),
- std::make_pair(8, 1), std::make_pair(10, 1)));
-}
-
-} // namespace scheduler
-} // namespace blink
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 2d93ae8a391..09fe0803e06 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
@@ -15,8 +15,6 @@ namespace scheduler {
WebThreadScheduler::~WebThreadScheduler() = default;
-WebThreadScheduler::RAILModeObserver::~RAILModeObserver() = default;
-
// static
std::unique_ptr<WebThreadScheduler>
WebThreadScheduler::CreateMainThreadScheduler(
@@ -72,6 +70,12 @@ WebThreadScheduler::IPCTaskRunner() {
return nullptr;
}
+scoped_refptr<base::SingleThreadTaskRunner>
+WebThreadScheduler::CleanupTaskRunner() {
+ NOTREACHED();
+ return nullptr;
+}
+
std::unique_ptr<WebThread> WebThreadScheduler::CreateMainThread() {
NOTREACHED();
return nullptr;
@@ -153,7 +157,7 @@ void WebThreadScheduler::SetTopLevelBlameContext(
NOTREACHED();
}
-void WebThreadScheduler::AddRAILModeObserver(RAILModeObserver* observer) {
+void WebThreadScheduler::AddRAILModeObserver(WebRAILModeObserver* observer) {
NOTREACHED();
}
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/DEPS b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/DEPS
index 7e5548fc57e..02ff2156bcd 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/DEPS
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/DEPS
@@ -8,6 +8,7 @@ include_rules = [
specific_include_rules = {
"main_thread_task_queue.h": [
"+base/task/sequence_manager/task_queue_impl.h",
+ "+net/base/request_priority.h"
],
"frame_scheduler_impl.h": [
"+net/base/request_priority.h"
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 f94bcb88e6d..57b546b0536 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
@@ -5,20 +5,24 @@
#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h"
#include <memory>
+#include <set>
+#include <string>
+#include "base/metrics/field_trial_params.h"
#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/platform/blame_context.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/scheduler/child/features.h"
-#include "third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.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/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"
#include "third_party/blink/renderer/platform/scheduler/main_thread/resource_loading_task_runner_handle_impl.h"
+#include "third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.h"
#include "third_party/blink/renderer/platform/scheduler/util/tracing_helper.h"
#include "third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy.h"
@@ -27,6 +31,7 @@ namespace blink {
namespace scheduler {
using base::sequence_manager::TaskQueue;
+using QueueTraits = MainThreadTaskQueue::QueueTraits;
namespace {
@@ -73,6 +78,44 @@ 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.
+std::string ExtractAndTrimString(std::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.substr(start, end - start);
+ return "";
+}
+
+std::set<std::string> TaskTypesFromFieldTrialParam(const char* param) {
+ std::set<std::string> result;
+ std::string task_type_list = 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)) != std::string::npos) {
+ std::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.
+ std::string task_type =
+ ExtractAndTrimString(task_type_list, start, task_type_list.length());
+ DCHECK(task_type.length());
+ result.insert(task_type);
+
+ return result;
+}
+
} // namespace
FrameSchedulerImpl::ActiveConnectionHandleImpl::ActiveConnectionHandleImpl(
@@ -104,11 +147,12 @@ FrameSchedulerImpl::PauseSubresourceLoadingHandleImpl::
std::unique_ptr<FrameSchedulerImpl> FrameSchedulerImpl::Create(
PageSchedulerImpl* parent_page_scheduler,
+ FrameScheduler::Delegate* delegate,
base::trace_event::BlameContext* blame_context,
FrameScheduler::FrameType frame_type) {
- std::unique_ptr<FrameSchedulerImpl> frame_scheduler(
- new FrameSchedulerImpl(parent_page_scheduler->GetMainThreadScheduler(),
- parent_page_scheduler, blame_context, frame_type));
+ std::unique_ptr<FrameSchedulerImpl> frame_scheduler(new FrameSchedulerImpl(
+ parent_page_scheduler->GetMainThreadScheduler(), parent_page_scheduler,
+ delegate, blame_context, frame_type));
parent_page_scheduler->RegisterFrameSchedulerImpl(frame_scheduler.get());
return frame_scheduler;
}
@@ -116,12 +160,14 @@ std::unique_ptr<FrameSchedulerImpl> FrameSchedulerImpl::Create(
FrameSchedulerImpl::FrameSchedulerImpl(
MainThreadSchedulerImpl* main_thread_scheduler,
PageSchedulerImpl* parent_page_scheduler,
+ FrameScheduler::Delegate* delegate,
base::trace_event::BlameContext* blame_context,
FrameScheduler::FrameType frame_type)
: frame_type_(frame_type),
is_ad_frame_(false),
main_thread_scheduler_(main_thread_scheduler),
parent_page_scheduler_(parent_page_scheduler),
+ delegate_(delegate),
blame_context_(blame_context),
throttling_state_(SchedulingLifecycleState::kNotThrottled),
frame_visible_(true,
@@ -147,11 +193,11 @@ FrameSchedulerImpl::FrameSchedulerImpl(
&tracing_controller_,
PausedStateToString),
url_tracer_("FrameScheduler.URL", this),
- task_queue_throttled_(false,
- "FrameScheduler.TaskQueueThrottled",
- this,
- &tracing_controller_,
- YesNoStateToString),
+ task_queues_throttled_(false,
+ "FrameScheduler.TaskQueuesThrottled",
+ this,
+ &tracing_controller_,
+ YesNoStateToString),
active_connection_count_(0),
subresource_loading_pause_count_(0u),
has_active_connection_(false,
@@ -179,16 +225,23 @@ FrameSchedulerImpl::FrameSchedulerImpl(
this,
&tracing_controller_,
KeepActiveStateToString),
- weak_factory_(this) {}
+ weak_factory_(this) {
+ frame_task_queue_controller_.reset(
+ new FrameTaskQueueController(main_thread_scheduler_, this, this));
+}
FrameSchedulerImpl::FrameSchedulerImpl()
- : FrameSchedulerImpl(nullptr, nullptr, nullptr, FrameType::kSubframe) {}
+ : FrameSchedulerImpl(nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ FrameType::kSubframe) {}
namespace {
void CleanUpQueue(MainThreadTaskQueue* queue) {
- if (!queue)
- return;
+ DCHECK(queue);
+
queue->DetachFromMainThreadScheduler();
queue->DetachFromFrameScheduler();
queue->SetBlameContext(nullptr);
@@ -200,17 +253,13 @@ void CleanUpQueue(MainThreadTaskQueue* queue) {
FrameSchedulerImpl::~FrameSchedulerImpl() {
weak_factory_.InvalidateWeakPtrs();
- RemoveThrottleableQueueFromBackgroundCPUTimeBudgetPool();
-
- CleanUpQueue(loading_task_queue_.get());
- CleanUpQueue(loading_control_task_queue_.get());
- CleanUpQueue(throttleable_task_queue_.get());
- CleanUpQueue(deferrable_task_queue_.get());
- CleanUpQueue(pausable_task_queue_.get());
- CleanUpQueue(unpausable_task_queue_.get());
-
- for (const auto& pair : resource_loading_task_queues_) {
- CleanUpQueue(pair.key.get());
+ for (const auto& task_queue_and_voter :
+ frame_task_queue_controller_->GetAllTaskQueuesAndVoters()) {
+ if (task_queue_and_voter.first->CanBeThrottled()) {
+ RemoveThrottleableQueueFromBackgroundCPUTimeBudgetPool(
+ task_queue_and_voter.first);
+ }
+ CleanUpQueue(task_queue_and_voter.first);
}
if (parent_page_scheduler_) {
@@ -222,15 +271,21 @@ FrameSchedulerImpl::~FrameSchedulerImpl() {
}
void FrameSchedulerImpl::DetachFromPageScheduler() {
- RemoveThrottleableQueueFromBackgroundCPUTimeBudgetPool();
+ for (const auto& task_queue_and_voter :
+ frame_task_queue_controller_->GetAllTaskQueuesAndVoters()) {
+ if (task_queue_and_voter.first->CanBeThrottled()) {
+ RemoveThrottleableQueueFromBackgroundCPUTimeBudgetPool(
+ task_queue_and_voter.first);
+ }
+ }
parent_page_scheduler_ = nullptr;
}
-void FrameSchedulerImpl::
- RemoveThrottleableQueueFromBackgroundCPUTimeBudgetPool() {
- if (!throttleable_task_queue_)
- return;
+void FrameSchedulerImpl::RemoveThrottleableQueueFromBackgroundCPUTimeBudgetPool(
+ MainThreadTaskQueue* task_queue) {
+ DCHECK(task_queue);
+ DCHECK(task_queue->CanBeThrottled());
if (!parent_page_scheduler_)
return;
@@ -241,9 +296,14 @@ void FrameSchedulerImpl::
if (!time_budget_pool)
return;
- time_budget_pool->RemoveQueue(
- main_thread_scheduler_->tick_clock()->NowTicks(),
- throttleable_task_queue_.get());
+ // On tests, the scheduler helper might already be shut down and tick is not
+ // available.
+ base::TimeTicks now;
+ if (main_thread_scheduler_->tick_clock())
+ now = main_thread_scheduler_->tick_clock()->NowTicks();
+ else
+ now = base::TimeTicks::Now();
+ time_budget_pool->RemoveQueue(now, task_queue);
}
void FrameSchedulerImpl::SetFrameVisible(bool frame_visible) {
@@ -294,18 +354,52 @@ FrameScheduler::FrameType FrameSchedulerImpl::GetFrameType() const {
return frame_type_;
}
-scoped_refptr<base::SingleThreadTaskRunner> FrameSchedulerImpl::GetTaskRunner(
+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.
+ std::set<std::string> throttleable_task_type_names;
+ std::set<std::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.size() ||
+ freezable_task_type_names.size())) {
+ const char* task_type_name = TaskTypeNames::TaskTypeToString(type);
+ if (throttleable_task_type_names.erase(task_type_name))
+ queue_traits->SetCanBeThrottled(true);
+ if (freezable_task_type_names.erase(task_type_name))
+ queue_traits->SetCanBeFrozen(true);
+ }
+ frame_task_types_to_queue_traits[i] = queue_traits;
+ }
+ // Protect against configuration errors.
+ DCHECK(throttleable_task_type_names.empty());
+ DCHECK(freezable_task_type_names.empty());
+}
+
+// static
+base::Optional<QueueTraits> FrameSchedulerImpl::CreateQueueTraitsForTaskType(
TaskType type) {
// TODO(haraken): Optimize the mapping from TaskTypes to task runners.
switch (type) {
case TaskType::kJavascriptTimer:
- return TaskQueueWithTaskType::Create(ThrottleableTaskQueue(), type);
+ return ThrottleableTaskQueueTraits();
case TaskType::kInternalLoading:
case TaskType::kNetworking:
case TaskType::kNetworkingWithURLLoaderAnnotation:
- return TaskQueueWithTaskType::Create(LoadingTaskQueue(), type);
case TaskType::kNetworkingControl:
- return TaskQueueWithTaskType::Create(LoadingControlTaskQueue(), type);
+ // Loading task queues are handled separately.
+ return base::nullopt;
// Throttling following tasks may break existing web pages, so tentatively
// these are unthrottled.
// TODO(nhiroki): Throttle them again after we're convinced that it's safe
@@ -329,7 +423,7 @@ scoped_refptr<base::SingleThreadTaskRunner> FrameSchedulerImpl::GetTaskRunner(
case TaskType::kInternalDefault:
case TaskType::kMiscPlatformAPI:
// TODO(altimin): Move appropriate tasks to throttleable task queue.
- return TaskQueueWithTaskType::Create(DeferrableTaskQueue(), type);
+ return DeferrableTaskQueueTraits();
// PostedMessage can be used for navigation, so we shouldn't defer it
// when expecting a user gesture.
case TaskType::kPostedMessage:
@@ -346,7 +440,7 @@ scoped_refptr<base::SingleThreadTaskRunner> FrameSchedulerImpl::GetTaskRunner(
case TaskType::kInternalMediaRealTime:
case TaskType::kInternalUserInteraction:
case TaskType::kInternalIntersectionObserver:
- return TaskQueueWithTaskType::Create(PausableTaskQueue(), type);
+ return PausableTaskQueueTraits();
case TaskType::kInternalIPC:
// The TaskType of Inspector tasks needs to be unpausable because they need
// to run even on a paused page.
@@ -355,7 +449,7 @@ scoped_refptr<base::SingleThreadTaskRunner> FrameSchedulerImpl::GetTaskRunner(
// unthrottled and undeferred) not to prevent service workers that may
// control browser navigation on multiple tabs.
case TaskType::kInternalWorker:
- return TaskQueueWithTaskType::Create(UnpausableTaskQueue(), type);
+ return UnpausableTaskQueueTraits();
case TaskType::kDeprecatedNone:
case TaskType::kMainThreadTaskQueueV8:
case TaskType::kMainThreadTaskQueueCompositor:
@@ -364,41 +458,53 @@ scoped_refptr<base::SingleThreadTaskRunner> FrameSchedulerImpl::GetTaskRunner(
case TaskType::kMainThreadTaskQueueIdle:
case TaskType::kMainThreadTaskQueueIPC:
case TaskType::kMainThreadTaskQueueControl:
+ case TaskType::kMainThreadTaskQueueCleanup:
case TaskType::kCompositorThreadTaskQueueDefault:
case TaskType::kCompositorThreadTaskQueueInput:
case TaskType::kWorkerThreadTaskQueueDefault:
case TaskType::kWorkerThreadTaskQueueV8:
case TaskType::kWorkerThreadTaskQueueCompositor:
case TaskType::kCount:
- NOTREACHED();
- break;
+ // Not a valid frame-level TaskType.
+ return base::nullopt;
}
- NOTREACHED();
- return nullptr;
+ // 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;
}
-std::pair<scoped_refptr<MainThreadTaskQueue>,
- std::unique_ptr<TaskQueue::QueueEnabledVoter>>
-FrameSchedulerImpl::CreateNewLoadingTaskQueue() {
- // TODO(panicker): Avoid adding this queue in RS task_runners_.
- scoped_refptr<MainThreadTaskQueue> loading_task_queue =
- main_thread_scheduler_->NewLoadingTaskQueue(
- MainThreadTaskQueue::QueueType::kFrameLoading, this);
- loading_task_queue->SetBlameContext(blame_context_);
- std::unique_ptr<TaskQueue::QueueEnabledVoter> voter =
- loading_task_queue->CreateQueueEnabledVoter();
- voter->SetQueueEnabled(!frame_paused_);
- return std::make_pair(loading_task_queue, std::move(voter));
+scoped_refptr<base::SingleThreadTaskRunner> FrameSchedulerImpl::GetTaskRunner(
+ TaskType type) {
+ scoped_refptr<MainThreadTaskQueue> task_queue = GetTaskQueue(type);
+ DCHECK(task_queue);
+ return task_queue->CreateTaskRunner(type);
}
-scoped_refptr<TaskQueue> FrameSchedulerImpl::LoadingTaskQueue() {
- DCHECK(parent_page_scheduler_);
- if (!loading_task_queue_) {
- auto queue_voter_pair = CreateNewLoadingTaskQueue();
- loading_task_queue_ = queue_voter_pair.first;
- loading_queue_enabled_voter_ = std::move(queue_voter_pair.second);
+scoped_refptr<MainThreadTaskQueue> FrameSchedulerImpl::GetTaskQueue(
+ TaskType type) {
+ switch (type) {
+ case TaskType::kInternalLoading:
+ case TaskType::kNetworking:
+ case TaskType::kNetworkingWithURLLoaderAnnotation:
+ return frame_task_queue_controller_->LoadingTaskQueue();
+ case TaskType::kNetworkingControl:
+ return frame_task_queue_controller_->LoadingControlTaskQueue();
+ default:
+ // Non-loading task queue.
+ 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_->NonLoadingTaskQueue(
+ queue_traits.value());
}
- return loading_task_queue_;
}
std::unique_ptr<WebResourceLoadingTaskRunnerHandle>
@@ -413,143 +519,51 @@ FrameSchedulerImpl::CreateResourceLoadingTaskRunnerHandleImpl() {
(parent_page_scheduler_->IsLoading() &&
main_thread_scheduler_->scheduling_settings()
.use_resource_priorities_only_during_loading)) {
- auto queue_voter_pair = CreateNewLoadingTaskQueue();
-
- resource_loading_task_queues_.insert(
- queue_voter_pair.first, ResourceLoadingTaskQueueMetadata(
- queue_voter_pair.first->GetQueuePriority(),
- std::move(queue_voter_pair.second)));
-
- return ResourceLoadingTaskRunnerHandleImpl::WrapTaskRunner(
- queue_voter_pair.first);
+ scoped_refptr<MainThreadTaskQueue> task_queue =
+ frame_task_queue_controller_->NewResourceLoadingTaskQueue();
+ resource_loading_task_queue_priorities_.insert(
+ task_queue, task_queue->GetQueuePriority());
+ return ResourceLoadingTaskRunnerHandleImpl::WrapTaskRunner(task_queue);
}
- // Make sure the loading task queue exists.
- LoadingTaskQueue();
return ResourceLoadingTaskRunnerHandleImpl::WrapTaskRunner(
- loading_task_queue_);
+ frame_task_queue_controller_->LoadingTaskQueue());
}
void FrameSchedulerImpl::DidChangeResourceLoadingPriority(
scoped_refptr<MainThreadTaskQueue> task_queue,
net::RequestPriority priority) {
// This check is done since in some cases (when kUseResourceFetchPriority
- // feature isn't enabled) we use |loading_task_queue_| for resource loading
+ // feature isn't enabled) we use the loading task queue for resource loading
// and the priority of this queue shouldn't be affected by resource
// priorities.
- auto queue_metadata_pair = resource_loading_task_queues_.find(task_queue);
- if (queue_metadata_pair != resource_loading_task_queues_.end()) {
- queue_metadata_pair->value.priority =
- main_thread_scheduler_->scheduling_settings()
- .net_to_blink_priority[priority];
- UpdateQueuePolicy(task_queue.get(), queue_metadata_pair->value.voter.get());
+ auto queue_priority_pair =
+ resource_loading_task_queue_priorities_.find(task_queue);
+ if (queue_priority_pair != resource_loading_task_queue_priorities_.end()) {
+ task_queue->SetNetRequestPriority(priority);
+ queue_priority_pair->value = main_thread_scheduler_->scheduling_settings()
+ .net_to_blink_priority[priority];
+ auto* voter =
+ frame_task_queue_controller_->GetQueueEnabledVoter(task_queue);
+ UpdateQueuePolicy(task_queue.get(), voter);
}
}
void FrameSchedulerImpl::OnShutdownResourceLoadingTaskQueue(
scoped_refptr<MainThreadTaskQueue> task_queue) {
// This check is done since in some cases (when kUseResourceFetchPriority
- // feature isn't enabled) we use |loading_task_queue_| for resource loading,
+ // feature isn't enabled) we use the loading task queue for resource loading,
// and the lifetime of this queue isn't bound to one resource.
- auto iter = resource_loading_task_queues_.find(task_queue);
- if (iter != resource_loading_task_queues_.end()) {
- resource_loading_task_queues_.erase(iter);
+ auto iter = resource_loading_task_queue_priorities_.find(task_queue);
+ if (iter != resource_loading_task_queue_priorities_.end()) {
+ resource_loading_task_queue_priorities_.erase(iter);
+ bool removed = frame_task_queue_controller_->RemoveResourceLoadingTaskQueue(
+ task_queue);
+ DCHECK(removed);
CleanUpQueue(task_queue.get());
}
}
-scoped_refptr<TaskQueue> FrameSchedulerImpl::LoadingControlTaskQueue() {
- DCHECK(parent_page_scheduler_);
- if (!loading_control_task_queue_) {
- loading_control_task_queue_ = main_thread_scheduler_->NewLoadingTaskQueue(
- MainThreadTaskQueue::QueueType::kFrameLoadingControl, this);
- loading_control_task_queue_->SetBlameContext(blame_context_);
- loading_control_queue_enabled_voter_ =
- loading_control_task_queue_->CreateQueueEnabledVoter();
- loading_control_queue_enabled_voter_->SetQueueEnabled(!frame_paused_);
- }
- return loading_control_task_queue_;
-}
-
-scoped_refptr<TaskQueue> FrameSchedulerImpl::ThrottleableTaskQueue() {
- DCHECK(parent_page_scheduler_);
- if (!throttleable_task_queue_) {
- // TODO(panicker): Avoid adding this queue in RS task_runners_.
- throttleable_task_queue_ = main_thread_scheduler_->NewTaskQueue(
- MainThreadTaskQueue::QueueCreationParams(
- MainThreadTaskQueue::QueueType::kFrameThrottleable)
- .SetCanBeThrottled(true)
- .SetCanBeFrozen(true)
- .SetFreezeWhenKeepActive(true)
- .SetCanBeDeferred(true)
- .SetCanBePaused(true)
- .SetFrameScheduler(this));
- throttleable_task_queue_->SetBlameContext(blame_context_);
- throttleable_queue_enabled_voter_ =
- throttleable_task_queue_->CreateQueueEnabledVoter();
- throttleable_queue_enabled_voter_->SetQueueEnabled(!frame_paused_);
-
- CPUTimeBudgetPool* time_budget_pool =
- parent_page_scheduler_->BackgroundCPUTimeBudgetPool();
- if (time_budget_pool) {
- time_budget_pool->AddQueue(
- main_thread_scheduler_->tick_clock()->NowTicks(),
- throttleable_task_queue_.get());
- }
- UpdateThrottling();
- }
- return throttleable_task_queue_;
-}
-
-scoped_refptr<TaskQueue> FrameSchedulerImpl::DeferrableTaskQueue() {
- DCHECK(parent_page_scheduler_);
- if (!deferrable_task_queue_) {
- deferrable_task_queue_ = main_thread_scheduler_->NewTaskQueue(
- MainThreadTaskQueue::QueueCreationParams(
- MainThreadTaskQueue::QueueType::kFrameDeferrable)
- .SetCanBeDeferred(true)
- .SetCanBeFrozen(
- RuntimeEnabledFeatures::StopNonTimersInBackgroundEnabled())
- .SetCanBePaused(true)
- .SetFrameScheduler(this));
- deferrable_task_queue_->SetBlameContext(blame_context_);
- deferrable_queue_enabled_voter_ =
- deferrable_task_queue_->CreateQueueEnabledVoter();
- deferrable_queue_enabled_voter_->SetQueueEnabled(!frame_paused_);
- }
- return deferrable_task_queue_;
-}
-
-scoped_refptr<TaskQueue> FrameSchedulerImpl::PausableTaskQueue() {
- DCHECK(parent_page_scheduler_);
- if (!pausable_task_queue_) {
- pausable_task_queue_ = main_thread_scheduler_->NewTaskQueue(
- MainThreadTaskQueue::QueueCreationParams(
- MainThreadTaskQueue::QueueType::kFramePausable)
- .SetCanBeFrozen(
- RuntimeEnabledFeatures::StopNonTimersInBackgroundEnabled())
- .SetCanBePaused(true)
- .SetFrameScheduler(this));
- pausable_task_queue_->SetBlameContext(blame_context_);
- pausable_queue_enabled_voter_ =
- pausable_task_queue_->CreateQueueEnabledVoter();
- pausable_queue_enabled_voter_->SetQueueEnabled(!frame_paused_);
- }
- return pausable_task_queue_;
-}
-
-scoped_refptr<TaskQueue> FrameSchedulerImpl::UnpausableTaskQueue() {
- DCHECK(parent_page_scheduler_);
- if (!unpausable_task_queue_) {
- unpausable_task_queue_ = main_thread_scheduler_->NewTaskQueue(
- MainThreadTaskQueue::QueueCreationParams(
- MainThreadTaskQueue::QueueType::kFrameUnpausable)
- .SetFrameScheduler(this));
- unpausable_task_queue_->SetBlameContext(blame_context_);
- }
- return unpausable_task_queue_;
-}
-
scoped_refptr<base::SingleThreadTaskRunner>
FrameSchedulerImpl::ControlTaskRunner() {
DCHECK(parent_page_scheduler_);
@@ -605,36 +619,10 @@ void FrameSchedulerImpl::AsValueInto(
state->SetBoolean(
"disable_background_timer_throttling",
!RuntimeEnabledFeatures::TimerThrottlingForBackgroundTabsEnabled());
- if (loading_task_queue_) {
- state->SetString("loading_task_queue",
- PointerToString(loading_task_queue_.get()));
- }
- if (loading_control_task_queue_) {
- state->SetString("loading_control_task_queue",
- PointerToString(loading_control_task_queue_.get()));
- }
- if (throttleable_task_queue_) {
- state->SetString("throttleable_task_queue",
- PointerToString(throttleable_task_queue_.get()));
- }
- if (deferrable_task_queue_) {
- state->SetString("deferrable_task_queue",
- PointerToString(deferrable_task_queue_.get()));
- }
- if (pausable_task_queue_) {
- state->SetString("pausable_task_queue",
- PointerToString(pausable_task_queue_.get()));
- }
- if (unpausable_task_queue_) {
- state->SetString("unpausable_task_queue",
- PointerToString(unpausable_task_queue_.get()));
- }
- state->BeginArray("resource_loading_task_queues");
- for (const auto& queue : resource_loading_task_queues_) {
- state->AppendString(PointerToString(queue.key.get()));
- }
- state->EndArray();
+ state->BeginDictionary("frame_task_queue_controller");
+ frame_task_queue_controller_->AsValueInto(state);
+ state->EndDictionary();
if (blame_context_) {
state->BeginDictionary("blame_context");
@@ -679,37 +667,33 @@ void FrameSchedulerImpl::SetPageKeepActiveForTracing(bool keep_active) {
}
void FrameSchedulerImpl::UpdatePolicy() {
- // Per-frame (stoppable) task queues will be frozen after 5mins in
- // background. They will be resumed when the page is visible.
- UpdateQueuePolicy(throttleable_task_queue_,
- throttleable_queue_enabled_voter_.get());
- UpdateQueuePolicy(loading_task_queue_, loading_queue_enabled_voter_.get());
- UpdateQueuePolicy(loading_control_task_queue_,
- loading_control_queue_enabled_voter_.get());
- UpdateQueuePolicy(deferrable_task_queue_,
- deferrable_queue_enabled_voter_.get());
- UpdateQueuePolicy(pausable_task_queue_, pausable_queue_enabled_voter_.get());
- UpdateQueuePolicy(unpausable_task_queue_, nullptr);
-
- for (const auto& pair : resource_loading_task_queues_) {
- UpdateQueuePolicy(pair.key, pair.value.voter.get());
+ bool task_queues_were_throttled = task_queues_throttled_;
+ task_queues_throttled_ = ShouldThrottleTaskQueues();
+
+ for (const auto& task_queue_and_voter :
+ frame_task_queue_controller_->GetAllTaskQueuesAndVoters()) {
+ UpdateQueuePolicy(task_queue_and_voter.first, task_queue_and_voter.second);
+ if (task_queues_were_throttled != task_queues_throttled_) {
+ UpdateTaskQueueThrottling(task_queue_and_voter.first,
+ task_queues_throttled_);
+ }
}
- UpdateThrottling();
-
NotifyLifecycleObservers();
}
void FrameSchedulerImpl::UpdateQueuePolicy(
- const scoped_refptr<MainThreadTaskQueue>& queue,
+ MainThreadTaskQueue* queue,
TaskQueue::QueueEnabledVoter* voter) {
- if (!queue)
- return;
- UpdatePriority(queue.get());
+ DCHECK(queue);
+ UpdatePriority(queue);
if (!voter)
return;
DCHECK(parent_page_scheduler_);
bool queue_paused = frame_paused_ && queue->CanBePaused();
+ // Per-frame freezable task queues will be frozen after 5 mins in background
+ // on Android, and if the browser freezes the page in the background. They
+ // will be resumed when the page is visible.
bool queue_frozen =
parent_page_scheduler_->IsFrozen() && queue->CanBeFrozen();
// Override freezing if keep-active is true.
@@ -751,7 +735,7 @@ FrameSchedulerImpl::OnActiveConnectionCreated() {
return std::make_unique<FrameSchedulerImpl::ActiveConnectionHandleImpl>(this);
}
-bool FrameSchedulerImpl::ShouldThrottleTimers() const {
+bool FrameSchedulerImpl::ShouldThrottleTaskQueues() const {
if (!RuntimeEnabledFeatures::TimerThrottlingForBackgroundTabsEnabled())
return false;
if (parent_page_scheduler_ && parent_page_scheduler_->IsAudioPlaying())
@@ -762,24 +746,17 @@ bool FrameSchedulerImpl::ShouldThrottleTimers() const {
!frame_visible_ && IsCrossOrigin();
}
-void FrameSchedulerImpl::UpdateThrottling() {
- // Before we initialize a trottleable task queue, |task_queue_throttled_|
- // stays false and this function ensures it indicates whether are we holding
- // a queue reference for throttler or not.
- // Don't modify that value neither amend the reference counter anywhere else.
- if (!throttleable_task_queue_)
+void FrameSchedulerImpl::UpdateTaskQueueThrottling(
+ MainThreadTaskQueue* task_queue,
+ bool should_throttle) {
+ if (!task_queue->CanBeThrottled())
return;
- bool should_throttle = ShouldThrottleTimers();
- if (task_queue_throttled_ == should_throttle)
- return;
- task_queue_throttled_ = should_throttle;
-
if (should_throttle) {
main_thread_scheduler_->task_queue_throttler()->IncreaseThrottleRefCount(
- throttleable_task_queue_.get());
+ task_queue);
} else {
main_thread_scheduler_->task_queue_throttler()->DecreaseThrottleRefCount(
- throttleable_task_queue_.get());
+ task_queue);
}
}
@@ -796,10 +773,10 @@ TaskQueue::QueuePriority FrameSchedulerImpl::ComputePriority(
// Checks the task queue is associated with this frame scheduler.
DCHECK_EQ(frame_scheduler, this);
- auto queue_metadata_pair =
- resource_loading_task_queues_.find(base::WrapRefCounted(task_queue));
- if (queue_metadata_pair != resource_loading_task_queues_.end()) {
- return queue_metadata_pair->value.priority;
+ auto queue_priority_pair = resource_loading_task_queue_priorities_.find(
+ base::WrapRefCounted(task_queue));
+ if (queue_priority_pair != resource_loading_task_queue_priorities_.end()) {
+ return queue_priority_pair->value;
}
base::Optional<TaskQueue::QueuePriority> fixed_priority =
@@ -911,5 +888,72 @@ void FrameSchedulerImpl::RemovePauseSubresourceLoadingHandle() {
}
}
+ukm::UkmRecorder* FrameSchedulerImpl::GetUkmRecorder() {
+ if (!delegate_)
+ return nullptr;
+ return delegate_->GetUkmRecorder();
+}
+
+ukm::SourceId FrameSchedulerImpl::GetUkmSourceId() {
+ if (!delegate_)
+ return ukm::kInvalidSourceId;
+ return delegate_->GetUkmSourceId();
+}
+
+void FrameSchedulerImpl::OnTaskQueueCreated(
+ MainThreadTaskQueue* task_queue,
+ base::sequence_manager::TaskQueue::QueueEnabledVoter* voter) {
+ DCHECK(parent_page_scheduler_);
+
+ task_queue->SetBlameContext(blame_context_);
+ UpdateQueuePolicy(task_queue, voter);
+
+ if (task_queue->CanBeThrottled()) {
+ CPUTimeBudgetPool* time_budget_pool =
+ parent_page_scheduler_->BackgroundCPUTimeBudgetPool();
+ if (time_budget_pool) {
+ time_budget_pool->AddQueue(
+ main_thread_scheduler_->tick_clock()->NowTicks(), task_queue);
+ }
+ if (task_queues_throttled_) {
+ UpdateTaskQueueThrottling(task_queue, true);
+ }
+ }
+}
+
+// static
+MainThreadTaskQueue::QueueTraits
+FrameSchedulerImpl::ThrottleableTaskQueueTraits() {
+ return QueueTraits()
+ .SetCanBeThrottled(true)
+ .SetCanBeFrozen(true)
+ .SetCanBeDeferred(true)
+ .SetCanBePaused(true);
+}
+
+// static
+MainThreadTaskQueue::QueueTraits
+FrameSchedulerImpl::DeferrableTaskQueueTraits() {
+ return QueueTraits()
+ .SetCanBeDeferred(true)
+ .SetCanBeFrozen(base::FeatureList::IsEnabled(
+ blink::features::kStopNonTimersInBackground))
+ .SetCanBePaused(true);
+}
+
+// static
+MainThreadTaskQueue::QueueTraits FrameSchedulerImpl::PausableTaskQueueTraits() {
+ return QueueTraits()
+ .SetCanBeFrozen(base::FeatureList::IsEnabled(
+ blink::features::kStopNonTimersInBackground))
+ .SetCanBePaused(true);
+}
+
+// static
+MainThreadTaskQueue::QueueTraits
+FrameSchedulerImpl::UnpausableTaskQueueTraits() {
+ return QueueTraits();
+}
+
} // 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 1f5cb1c0d65..b0aada21f06 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
@@ -5,18 +5,24 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_FRAME_SCHEDULER_IMPL_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_FRAME_SCHEDULER_IMPL_H_
+#include <array>
#include <memory>
#include <utility>
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
+#include "base/optional.h"
#include "base/single_thread_task_runner.h"
#include "base/task/sequence_manager/task_queue.h"
#include "base/trace_event/trace_event.h"
#include "net/base/request_priority.h"
+#include "services/metrics/public/cpp/ukm_source_id.h"
+#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_origin_type.h"
+#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.h"
+#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/page_visibility_state.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/util/tracing_helper.h"
@@ -33,6 +39,10 @@ class TracedValue;
} // namespace trace_event
} // namespace base
+namespace ukm {
+class UkmRecorder;
+}
+
namespace blink {
namespace scheduler {
@@ -53,10 +63,12 @@ namespace page_scheduler_impl_unittest {
class PageSchedulerImplTest;
}
-class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler {
+class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler,
+ FrameTaskQueueController::Delegate {
public:
static std::unique_ptr<FrameSchedulerImpl> Create(
PageSchedulerImpl* page_scheduler,
+ FrameScheduler::Delegate* delegate,
base::trace_event::BlameContext* blame_context,
FrameScheduler::FrameType frame_type);
~FrameSchedulerImpl() override;
@@ -120,9 +132,28 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler {
base::sequence_manager::TaskQueue::QueuePriority ComputePriority(
MainThreadTaskQueue* task_queue) const;
+ ukm::SourceId GetUkmSourceId() override;
+ ukm::UkmRecorder* GetUkmRecorder();
+
+ // FrameTaskQueueController::Delegate implementation.
+ void OnTaskQueueCreated(
+ 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&);
+
protected:
FrameSchedulerImpl(MainThreadSchedulerImpl* main_thread_scheduler,
PageSchedulerImpl* parent_page_scheduler,
+ FrameScheduler::Delegate* delegate,
base::trace_event::BlameContext* blame_context,
FrameScheduler::FrameType frame_type);
@@ -137,6 +168,8 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler {
scoped_refptr<MainThreadTaskQueue> task_queue,
net::RequestPriority priority);
+ scoped_refptr<MainThreadTaskQueue> GetTaskQueue(TaskType);
+
private:
friend class PageSchedulerImpl;
friend class main_thread_scheduler_impl_unittest::MainThreadSchedulerImplTest;
@@ -172,29 +205,21 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler {
DISALLOW_COPY_AND_ASSIGN(PauseSubresourceLoadingHandleImpl);
};
- struct ResourceLoadingTaskQueueMetadata {
- ResourceLoadingTaskQueueMetadata(){};
-
- ResourceLoadingTaskQueueMetadata(
- base::sequence_manager::TaskQueue::QueuePriority queue_priority,
- std::unique_ptr<base::sequence_manager::TaskQueue::QueueEnabledVoter>
- queue_voter)
- : priority(queue_priority), voter(std::move(queue_voter)) {}
-
- base::sequence_manager::TaskQueue::QueuePriority priority;
- std::unique_ptr<base::sequence_manager::TaskQueue::QueueEnabledVoter> voter;
- };
-
void DetachFromPageScheduler();
- void RemoveThrottleableQueueFromBackgroundCPUTimeBudgetPool();
+ void RemoveThrottleableQueueFromBackgroundCPUTimeBudgetPool(
+ MainThreadTaskQueue*);
void ApplyPolicyToThrottleableQueue();
- bool ShouldThrottleTimers() const;
+ bool ShouldThrottleTaskQueues() const;
SchedulingLifecycleState CalculateLifecycleState(
ObserverType type) const override;
void UpdateQueuePolicy(
- const scoped_refptr<MainThreadTaskQueue>& queue,
+ MainThreadTaskQueue* queue,
base::sequence_manager::TaskQueue::QueueEnabledVoter* voter);
- void UpdateThrottling();
+ // Update throttling for |task_queue|. This changes the throttling ref counts
+ // and should only be called for new queues if throttling is enabled, or if
+ // the throttling state changes.
+ void UpdateTaskQueueThrottling(MainThreadTaskQueue* task_queue,
+ bool should_throttle);
void DidOpenActiveConnection();
void DidCloseActiveConnection();
@@ -205,49 +230,39 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler {
std::unique_ptr<ResourceLoadingTaskRunnerHandleImpl>
CreateResourceLoadingTaskRunnerHandleImpl();
- std::pair<
- scoped_refptr<MainThreadTaskQueue>,
- std::unique_ptr<base::sequence_manager::TaskQueue::QueueEnabledVoter>>
- CreateNewLoadingTaskQueue();
+ FrameTaskQueueController* FrameTaskQueueControllerForTest() {
+ return frame_task_queue_controller_.get();
+ }
+
+ // 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);
- scoped_refptr<base::sequence_manager::TaskQueue> LoadingTaskQueue();
- scoped_refptr<base::sequence_manager::TaskQueue> LoadingControlTaskQueue();
- scoped_refptr<base::sequence_manager::TaskQueue> ThrottleableTaskQueue();
- scoped_refptr<base::sequence_manager::TaskQueue> DeferrableTaskQueue();
- scoped_refptr<base::sequence_manager::TaskQueue> PausableTaskQueue();
- scoped_refptr<base::sequence_manager::TaskQueue> UnpausableTaskQueue();
+ // Create QueueTraits for the default (non-finch) task queues.
+ static MainThreadTaskQueue::QueueTraits ThrottleableTaskQueueTraits();
+ static MainThreadTaskQueue::QueueTraits DeferrableTaskQueueTraits();
+ static MainThreadTaskQueue::QueueTraits PausableTaskQueueTraits();
+ static MainThreadTaskQueue::QueueTraits UnpausableTaskQueueTraits();
const FrameScheduler::FrameType frame_type_;
bool is_ad_frame_;
TraceableVariableController tracing_controller_;
- scoped_refptr<MainThreadTaskQueue> loading_task_queue_;
- scoped_refptr<MainThreadTaskQueue> loading_control_task_queue_;
- scoped_refptr<MainThreadTaskQueue> throttleable_task_queue_;
- scoped_refptr<MainThreadTaskQueue> deferrable_task_queue_;
- scoped_refptr<MainThreadTaskQueue> pausable_task_queue_;
- scoped_refptr<MainThreadTaskQueue> unpausable_task_queue_;
- std::unique_ptr<base::sequence_manager::TaskQueue::QueueEnabledVoter>
- loading_queue_enabled_voter_;
- std::unique_ptr<base::sequence_manager::TaskQueue::QueueEnabledVoter>
- loading_control_queue_enabled_voter_;
- std::unique_ptr<base::sequence_manager::TaskQueue::QueueEnabledVoter>
- throttleable_queue_enabled_voter_;
- std::unique_ptr<base::sequence_manager::TaskQueue::QueueEnabledVoter>
- deferrable_queue_enabled_voter_;
- std::unique_ptr<base::sequence_manager::TaskQueue::QueueEnabledVoter>
- pausable_queue_enabled_voter_;
-
- using ResourceLoadingTaskQueueMetadataMap =
+ std::unique_ptr<FrameTaskQueueController> frame_task_queue_controller_;
+
+ using ResourceLoadingTaskQueuePriorityMap =
WTF::HashMap<scoped_refptr<MainThreadTaskQueue>,
- ResourceLoadingTaskQueueMetadata>;
+ base::sequence_manager::TaskQueue::QueuePriority>;
- // Holds queues created by CreateResourceLoadingTaskRunnerHandle.
- ResourceLoadingTaskQueueMetadataMap resource_loading_task_queues_;
+ // Queue to priority map of resource loading task queues created by
+ // |frame_task_queue_controller_| via CreateResourceLoadingTaskRunnerHandle.
+ ResourceLoadingTaskQueuePriorityMap resource_loading_task_queue_priorities_;
MainThreadSchedulerImpl* main_thread_scheduler_; // NOT OWNED
PageSchedulerImpl* parent_page_scheduler_; // NOT OWNED
+ FrameScheduler::Delegate* delegate_; // NOT OWNED
base::trace_event::BlameContext* blame_context_; // NOT OWNED
SchedulingLifecycleState throttling_state_;
TraceableState<bool, kTracingCategoryNameInfo> frame_visible_;
@@ -255,8 +270,7 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler {
TraceableState<FrameOriginType, kTracingCategoryNameInfo> frame_origin_type_;
TraceableState<bool, kTracingCategoryNameInfo> subresource_loading_paused_;
StateTracer<kTracingCategoryNameInfo> url_tracer_;
- // |task_queue_throttled_| is false if |throttleable_task_queue_| is absent.
- TraceableState<bool, kTracingCategoryNameInfo> task_queue_throttled_;
+ TraceableState<bool, kTracingCategoryNameInfo> task_queues_throttled_;
// TODO(kraynov): https://crbug.com/827113
// Trace active connection count.
int active_connection_count_;
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 97dd4266058..8457836c044 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
@@ -8,6 +8,7 @@
#include "base/callback.h"
#include "base/location.h"
+#include "base/metrics/field_trial_param_associator.h"
#include "base/metrics/field_trial_params.h"
#include "base/run_loop.h"
#include "base/task/sequence_manager/test/sequence_manager_for_test.h"
@@ -15,9 +16,11 @@
#include "base/test/scoped_task_environment.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/renderer/platform/scheduler/child/features.h"
+#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h"
+#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/resource_loading_task_runner_handle_impl.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
@@ -56,8 +59,9 @@ class FrameSchedulerImplTest : public testing::Test {
task_environment_.GetMockTickClock()),
base::nullopt));
page_scheduler_.reset(new PageSchedulerImpl(nullptr, scheduler_.get()));
- frame_scheduler_ = FrameSchedulerImpl::Create(
- page_scheduler_.get(), nullptr, FrameScheduler::FrameType::kSubframe);
+ frame_scheduler_ =
+ FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr, nullptr,
+ FrameScheduler::FrameType::kSubframe);
}
void TearDown() override {
@@ -69,37 +73,50 @@ class FrameSchedulerImplTest : public testing::Test {
protected:
scoped_refptr<TaskQueue> throttleable_task_queue() {
- return frame_scheduler_->throttleable_task_queue_;
+ return throttleable_task_queue_;
}
void LazyInitThrottleableTaskQueue() {
EXPECT_FALSE(throttleable_task_queue());
- frame_scheduler_->ThrottleableTaskQueue();
+ throttleable_task_queue_ = ThrottleableTaskQueue();
EXPECT_TRUE(throttleable_task_queue());
}
+ scoped_refptr<MainThreadTaskQueue> NonLoadingTaskQueue(
+ MainThreadTaskQueue::QueueTraits queue_traits) {
+ return frame_scheduler_->FrameTaskQueueControllerForTest()
+ ->NonLoadingTaskQueue(queue_traits);
+ }
+
scoped_refptr<TaskQueue> ThrottleableTaskQueue() {
- return frame_scheduler_->ThrottleableTaskQueue();
+ return NonLoadingTaskQueue(
+ FrameSchedulerImpl::ThrottleableTaskQueueTraits());
}
scoped_refptr<TaskQueue> LoadingTaskQueue() {
- return frame_scheduler_->LoadingTaskQueue();
+ return frame_scheduler_->FrameTaskQueueControllerForTest()
+ ->LoadingTaskQueue();
}
scoped_refptr<TaskQueue> LoadingControlTaskQueue() {
- return frame_scheduler_->LoadingControlTaskQueue();
+ return frame_scheduler_->FrameTaskQueueControllerForTest()
+ ->LoadingControlTaskQueue();
}
scoped_refptr<TaskQueue> DeferrableTaskQueue() {
- return frame_scheduler_->DeferrableTaskQueue();
+ return NonLoadingTaskQueue(FrameSchedulerImpl::DeferrableTaskQueueTraits());
}
scoped_refptr<TaskQueue> PausableTaskQueue() {
- return frame_scheduler_->PausableTaskQueue();
+ return NonLoadingTaskQueue(FrameSchedulerImpl::PausableTaskQueueTraits());
}
scoped_refptr<TaskQueue> UnpausableTaskQueue() {
- return frame_scheduler_->UnpausableTaskQueue();
+ return NonLoadingTaskQueue(FrameSchedulerImpl::UnpausableTaskQueueTraits());
+ }
+
+ scoped_refptr<MainThreadTaskQueue> GetTaskQueue(TaskType type) {
+ return frame_scheduler_->GetTaskQueue(type);
}
std::unique_ptr<ResourceLoadingTaskRunnerHandleImpl>
@@ -124,12 +141,23 @@ class FrameSchedulerImplTest : public testing::Test {
frame_scheduler_->DidChangeResourceLoadingPriority(task_queue, priority);
}
+ base::test::ScopedFeatureList& scoped_feature_list() { return feature_list_; }
+
std::unique_ptr<base::FieldTrialList> field_trial_list_;
base::test::ScopedFeatureList feature_list_;
base::test::ScopedTaskEnvironment task_environment_;
std::unique_ptr<MainThreadSchedulerImpl> scheduler_;
std::unique_ptr<PageSchedulerImpl> page_scheduler_;
std::unique_ptr<FrameSchedulerImpl> frame_scheduler_;
+ scoped_refptr<TaskQueue> throttleable_task_queue_;
+};
+
+class FrameSchedulerImplStopNonTimersInBackgroundEnabledTest
+ : public FrameSchedulerImplTest {
+ public:
+ FrameSchedulerImplStopNonTimersInBackgroundEnabledTest()
+ : FrameSchedulerImplTest({blink::features::kStopNonTimersInBackground},
+ {}) {}
};
namespace {
@@ -333,8 +361,8 @@ TEST_F(FrameSchedulerImplTest, PauseAndResume) {
EXPECT_EQ(5, counter);
}
-TEST_F(FrameSchedulerImplTest, PageFreezeAndUnfreezeFlagEnabled) {
- ScopedStopNonTimersInBackgroundForTest stop_non_timers_enabler(true);
+TEST_F(FrameSchedulerImplStopNonTimersInBackgroundEnabledTest,
+ PageFreezeAndUnfreezeFlagEnabled) {
int counter = 0;
LoadingTaskQueue()->PostTask(
FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
@@ -364,7 +392,6 @@ TEST_F(FrameSchedulerImplTest, PageFreezeAndUnfreezeFlagEnabled) {
}
TEST_F(FrameSchedulerImplTest, PageFreezeAndUnfreezeFlagDisabled) {
- ScopedStopNonTimersInBackgroundForTest stop_non_timers_enabler(false);
int counter = 0;
LoadingTaskQueue()->PostTask(
FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
@@ -394,7 +421,6 @@ TEST_F(FrameSchedulerImplTest, PageFreezeAndUnfreezeFlagDisabled) {
}
TEST_F(FrameSchedulerImplTest, PageFreezeWithKeepActive) {
- ScopedStopNonTimersInBackgroundForTest stop_non_timers_enabler(false);
std::vector<std::string> tasks;
LoadingTaskQueue()->PostTask(
FROM_HERE, base::BindOnce(&RecordQueueName, LoadingTaskQueue(), &tasks));
@@ -451,8 +477,8 @@ TEST_F(FrameSchedulerImplTest, PageFreezeWithKeepActive) {
UnorderedElementsAre(std::string(LoadingTaskQueue()->GetName())));
}
-TEST_F(FrameSchedulerImplTest, PageFreezeAndPageVisible) {
- ScopedStopNonTimersInBackgroundForTest stop_non_timers_enabler(true);
+TEST_F(FrameSchedulerImplStopNonTimersInBackgroundEnabledTest,
+ PageFreezeAndPageVisible) {
int counter = 0;
LoadingTaskQueue()->PostTask(
FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)));
@@ -864,8 +890,9 @@ TEST_F(LowPrioritySubFrameExperimentTest, FrameQueuesPriorities) {
EXPECT_EQ(UnpausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
- frame_scheduler_ = FrameSchedulerImpl::Create(
- page_scheduler_.get(), nullptr, FrameScheduler::FrameType::kMainFrame);
+ frame_scheduler_ =
+ FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr, nullptr,
+ FrameScheduler::FrameType::kMainFrame);
// Main Frame Task Queues.
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
@@ -953,8 +980,9 @@ TEST_F(LowPrioritySubFrameThrottleableTaskExperimentTest,
EXPECT_EQ(UnpausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
- frame_scheduler_ = FrameSchedulerImpl::Create(
- page_scheduler_.get(), nullptr, FrameScheduler::FrameType::kMainFrame);
+ frame_scheduler_ =
+ FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr, nullptr,
+ FrameScheduler::FrameType::kMainFrame);
// Main Frame Task Queues.
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
@@ -1042,8 +1070,9 @@ TEST_F(LowPriorityThrottleableTaskExperimentTest, FrameQueuesPriorities) {
EXPECT_EQ(UnpausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
- frame_scheduler_ = FrameSchedulerImpl::Create(
- page_scheduler_.get(), nullptr, FrameScheduler::FrameType::kMainFrame);
+ frame_scheduler_ =
+ FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr, nullptr,
+ FrameScheduler::FrameType::kMainFrame);
// Main Frame Task Queues.
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
@@ -1108,8 +1137,9 @@ TEST_F(LowPriorityThrottleableTaskDuringLoadingExperimentTest,
TEST_F(LowPriorityThrottleableTaskDuringLoadingExperimentTest,
MainFrameQueuesPriorities) {
- frame_scheduler_ = FrameSchedulerImpl::Create(
- page_scheduler_.get(), nullptr, FrameScheduler::FrameType::kMainFrame);
+ frame_scheduler_ =
+ FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr, nullptr,
+ FrameScheduler::FrameType::kMainFrame);
// Main thread is in the loading use case.
scheduler_->DidStartProvisionalLoad(true);
@@ -1531,6 +1561,213 @@ TEST_F(LowPriorityCrossOriginTaskDuringLoadingExperimentTest,
TaskQueue::QueuePriority::kNormalPriority);
}
+TEST_F(FrameSchedulerImplTest, TaskTypeToTaskQueueMapping) {
+ // Make sure the queue lookup and task type to queue traits map works as
+ // expected. This test will fail if these task types are moved to different
+ // default queues.
+ EXPECT_EQ(GetTaskQueue(TaskType::kJavascriptTimer), ThrottleableTaskQueue());
+ EXPECT_EQ(GetTaskQueue(TaskType::kDatabaseAccess), DeferrableTaskQueue());
+ EXPECT_EQ(GetTaskQueue(TaskType::kPostedMessage), PausableTaskQueue());
+ EXPECT_EQ(GetTaskQueue(TaskType::kInternalIPC), UnpausableTaskQueue());
+ EXPECT_EQ(GetTaskQueue(TaskType::kNetworking), LoadingTaskQueue());
+ EXPECT_EQ(GetTaskQueue(TaskType::kNetworkingControl),
+ LoadingControlTaskQueue());
+}
+
+class ThrottleAndFreezeTaskTypesExperimentTest : public FrameSchedulerImplTest {
+ public:
+ ThrottleAndFreezeTaskTypesExperimentTest(
+ std::map<std::string, std::string> params,
+ const char* group_name) {
+ const char kStudyName[] = "ThrottleAndFreezeTaskTypes";
+
+ field_trial_list_ = std::make_unique<base::FieldTrialList>(nullptr);
+
+ scoped_refptr<base::FieldTrial> trial =
+ base::FieldTrialList::CreateFieldTrial(kStudyName, group_name);
+
+ base::FieldTrialParamAssociator::GetInstance()->AssociateFieldTrialParams(
+ kStudyName, group_name, params);
+
+ std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
+ feature_list->RegisterFieldTrialOverride(
+ kThrottleAndFreezeTaskTypes.name,
+ base::FeatureList::OVERRIDE_ENABLE_FEATURE, trial.get());
+ scoped_feature_list().InitWithFeatureList(std::move(feature_list));
+ }
+};
+
+class ThrottleableAndFreezableTaskTypesTest
+ : public ThrottleAndFreezeTaskTypesExperimentTest {
+ public:
+ ThrottleableAndFreezableTaskTypesTest()
+ : ThrottleAndFreezeTaskTypesExperimentTest(
+ std::map<std::string, std::string>{
+ // Leading spaces are allowed.
+ {kThrottleableTaskTypesListParam,
+ "PostedMessage, DatabaseAccess"},
+ {kFreezableTaskTypesListParam,
+ "PostedMessage, MediaElementEvent,DOMManipulation"}},
+ "Group1") {}
+};
+
+TEST_F(ThrottleableAndFreezableTaskTypesTest, QueueTraitsFromFieldTrialParams) {
+ // 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));
+
+ 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()
+ .SetCanBeThrottled(true)
+ .SetCanBeDeferred(true)
+ .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::kInternalIPC);
+ EXPECT_EQ(task_queue->GetQueueTraits(), MainThreadTaskQueue::QueueTraits());
+
+ task_queue = GetTaskQueue(TaskType::kInternalIndexedDB);
+ EXPECT_EQ(task_queue->GetQueueTraits(),
+ MainThreadTaskQueue::QueueTraits().SetCanBePaused(true));
+
+ task_queue = GetTaskQueue(TaskType::kMiscPlatformAPI);
+ EXPECT_EQ(
+ task_queue->GetQueueTraits(),
+ MainThreadTaskQueue::QueueTraits().SetCanBeDeferred(true).SetCanBePaused(
+ true));
+}
+
+class FreezableOnlyTaskTypesTest
+ : public ThrottleAndFreezeTaskTypesExperimentTest {
+ public:
+ FreezableOnlyTaskTypesTest()
+ : ThrottleAndFreezeTaskTypesExperimentTest(
+ std::map<std::string, std::string>{
+ {kThrottleableTaskTypesListParam, ""},
+ {kFreezableTaskTypesListParam,
+ "PostedMessage,MediaElementEvent,DOMManipulation"}},
+ "Group2") {}
+};
+
+TEST_F(FreezableOnlyTaskTypesTest, QueueTraitsFromFieldTrialParams) {
+ // 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().SetCanBeDeferred(true).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::kInternalIPC);
+ EXPECT_EQ(task_queue->GetQueueTraits(), MainThreadTaskQueue::QueueTraits());
+
+ task_queue = GetTaskQueue(TaskType::kInternalIndexedDB);
+ EXPECT_EQ(task_queue->GetQueueTraits(),
+ MainThreadTaskQueue::QueueTraits().SetCanBePaused(true));
+
+ task_queue = GetTaskQueue(TaskType::kMiscPlatformAPI);
+ EXPECT_EQ(
+ task_queue->GetQueueTraits(),
+ MainThreadTaskQueue::QueueTraits().SetCanBeDeferred(true).SetCanBePaused(
+ true));
+}
+
+class ThrottleableOnlyTaskTypesTest
+ : public ThrottleAndFreezeTaskTypesExperimentTest {
+ public:
+ ThrottleableOnlyTaskTypesTest()
+ : ThrottleAndFreezeTaskTypesExperimentTest(
+ std::map<std::string, std::string>{
+ {kFreezableTaskTypesListParam, ""},
+ {kThrottleableTaskTypesListParam,
+ "PostedMessage,DatabaseAccess"}},
+ "Group3") {}
+};
+
+TEST_F(ThrottleableOnlyTaskTypesTest, QueueTraitsFromFieldTrialParams) {
+ // 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));
+
+ task_queue = GetTaskQueue(TaskType::kMediaElementEvent);
+ EXPECT_EQ(task_queue->GetQueueTraits(),
+ MainThreadTaskQueue::QueueTraits().SetCanBePaused(true));
+
+ task_queue = GetTaskQueue(TaskType::kDatabaseAccess);
+ EXPECT_EQ(task_queue->GetQueueTraits(), MainThreadTaskQueue::QueueTraits()
+ .SetCanBeThrottled(true)
+ .SetCanBeDeferred(true)
+ .SetCanBePaused(true));
+
+ task_queue = GetTaskQueue(TaskType::kDOMManipulation);
+ EXPECT_EQ(
+ task_queue->GetQueueTraits(),
+ MainThreadTaskQueue::QueueTraits().SetCanBeDeferred(true).SetCanBePaused(
+ true));
+
+ // Test some task types that were not configured through field trial
+ // parameters.
+ task_queue = GetTaskQueue(TaskType::kInternalIPC);
+ EXPECT_EQ(task_queue->GetQueueTraits(), MainThreadTaskQueue::QueueTraits());
+
+ task_queue = GetTaskQueue(TaskType::kInternalIndexedDB);
+ EXPECT_EQ(task_queue->GetQueueTraits(),
+ MainThreadTaskQueue::QueueTraits().SetCanBePaused(true));
+
+ task_queue = GetTaskQueue(TaskType::kMiscPlatformAPI);
+ EXPECT_EQ(
+ task_queue->GetQueueTraits(),
+ MainThreadTaskQueue::QueueTraits().SetCanBeDeferred(true).SetCanBePaused(
+ true));
+}
+
} // namespace frame_scheduler_impl_unittest
} // namespace scheduler
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.cc
index 5c1a7612b08..d0689f8a4ee 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
@@ -10,9 +10,11 @@
#include "base/callback.h"
#include "base/logging.h"
+#include "base/trace_event/trace_event_argument.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h"
+#include "third_party/blink/renderer/platform/scheduler/util/tracing_helper.h"
namespace blink {
namespace scheduler {
@@ -28,7 +30,6 @@ FrameTaskQueueController::FrameTaskQueueController(
: main_thread_scheduler_impl_(main_thread_scheduler_impl),
frame_scheduler_impl_(frame_scheduler_impl),
delegate_(delegate) {
- DCHECK(main_thread_scheduler_impl_);
DCHECK(frame_scheduler_impl_);
DCHECK(delegate_);
}
@@ -36,12 +37,29 @@ FrameTaskQueueController::FrameTaskQueueController(
FrameTaskQueueController::~FrameTaskQueueController() = default;
scoped_refptr<MainThreadTaskQueue>
-FrameTaskQueueController::GetNonLoadingTaskQueue(
- QueueTraits queue_traits) const {
+FrameTaskQueueController::LoadingTaskQueue() {
+ if (!loading_task_queue_)
+ CreateLoadingTaskQueue();
+ DCHECK(loading_task_queue_);
+ return loading_task_queue_;
+}
+
+scoped_refptr<MainThreadTaskQueue>
+FrameTaskQueueController::LoadingControlTaskQueue() {
+ if (!loading_control_task_queue_)
+ CreateLoadingControlTaskQueue();
+ DCHECK(loading_control_task_queue_);
+ return loading_control_task_queue_;
+}
+
+scoped_refptr<MainThreadTaskQueue>
+FrameTaskQueueController::NonLoadingTaskQueue(
+ MainThreadTaskQueue::QueueTraits queue_traits) {
+ if (!non_loading_task_queues_.Contains(queue_traits.Key()))
+ CreateNonLoadingTaskQueue(queue_traits);
auto it = non_loading_task_queues_.find(queue_traits.Key());
- if (it != non_loading_task_queues_.end())
- return it->value;
- return nullptr;
+ DCHECK(it != non_loading_task_queues_.end());
+ return it->value;
}
const std::vector<FrameTaskQueueController::TaskQueueAndEnabledVoterPair>&
@@ -49,26 +67,26 @@ FrameTaskQueueController::GetAllTaskQueuesAndVoters() const {
return all_task_queues_and_voters_;
}
-scoped_refptr<MainThreadTaskQueue>
-FrameTaskQueueController::NewLoadingTaskQueue() {
+void FrameTaskQueueController::CreateLoadingTaskQueue() {
DCHECK(!loading_task_queue_);
+ // |main_thread_scheduler_impl_| can be null in unit tests.
+ DCHECK(main_thread_scheduler_impl_);
loading_task_queue_ = main_thread_scheduler_impl_->NewLoadingTaskQueue(
MainThreadTaskQueue::QueueType::kFrameLoading, frame_scheduler_impl_);
TaskQueueCreated(loading_task_queue_);
- return loading_task_queue_;
}
-scoped_refptr<MainThreadTaskQueue>
-FrameTaskQueueController::NewLoadingControlTaskQueue() {
+void FrameTaskQueueController::CreateLoadingControlTaskQueue() {
DCHECK(!loading_control_task_queue_);
+ // |main_thread_scheduler_impl_| can be null in unit tests.
+ DCHECK(main_thread_scheduler_impl_);
loading_control_task_queue_ =
main_thread_scheduler_impl_->NewLoadingTaskQueue(
MainThreadTaskQueue::QueueType::kFrameLoadingControl,
frame_scheduler_impl_);
TaskQueueCreated(loading_control_task_queue_);
- return loading_control_task_queue_;
}
scoped_refptr<MainThreadTaskQueue>
@@ -81,9 +99,11 @@ FrameTaskQueueController::NewResourceLoadingTaskQueue() {
return task_queue;
}
-scoped_refptr<MainThreadTaskQueue>
-FrameTaskQueueController::NewNonLoadingTaskQueue(QueueTraits queue_traits) {
- DCHECK(!GetNonLoadingTaskQueue(queue_traits));
+void FrameTaskQueueController::CreateNonLoadingTaskQueue(
+ QueueTraits queue_traits) {
+ DCHECK(!non_loading_task_queues_.Contains(queue_traits.Key()));
+ // |main_thread_scheduler_impl_| can be null in unit tests.
+ DCHECK(main_thread_scheduler_impl_);
scoped_refptr<MainThreadTaskQueue> task_queue =
main_thread_scheduler_impl_->NewTaskQueue(
@@ -92,12 +112,14 @@ FrameTaskQueueController::NewNonLoadingTaskQueue(QueueTraits queue_traits) {
.SetQueueTraits(queue_traits)
// Freeze when keep active is currently only set for the
// throttleable queue.
- // TODO(shaseley): Figure out how to set this for new queues.
+ // TODO(altimin): Figure out how to set this for new queues.
+ // Investigate which tasks must be kept alive, and if possible
+ // move them to an unfreezable queue and remove this override and
+ // the page scheduler KeepActive freezing override.
.SetFreezeWhenKeepActive(queue_traits.can_be_throttled)
.SetFrameScheduler(frame_scheduler_impl_));
TaskQueueCreated(task_queue);
non_loading_task_queues_.insert(queue_traits.Key(), task_queue);
- return task_queue;
}
void FrameTaskQueueController::TaskQueueCreated(
@@ -153,6 +175,29 @@ bool FrameTaskQueueController::RemoveResourceLoadingTaskQueue(
return true;
}
+void FrameTaskQueueController::AsValueInto(
+ base::trace_event::TracedValue* state) const {
+ if (loading_task_queue_) {
+ state->SetString("loading_task_queue",
+ PointerToString(loading_task_queue_.get()));
+ }
+ if (loading_control_task_queue_) {
+ state->SetString("loading_control_task_queue",
+ PointerToString(loading_control_task_queue_.get()));
+ }
+ state->BeginArray("non_loading_task_queues");
+ for (const auto it : non_loading_task_queues_) {
+ state->AppendString(PointerToString(it.value.get()));
+ }
+ state->EndArray();
+
+ state->BeginArray("resource_loading_task_queues");
+ for (const auto& queue : resource_loading_task_queues_) {
+ state->AppendString(PointerToString(queue.get()));
+ }
+ state->EndArray();
+}
+
// static
MainThreadTaskQueue::QueueType
FrameTaskQueueController::QueueTypeFromQueueTraits(QueueTraits queue_traits) {
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.h
index 356d27a8181..1ec57ba8276 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.h
@@ -21,6 +21,9 @@ namespace base {
namespace sequence_manager {
class TaskQueue;
} // namespace sequence_manager
+namespace trace_event {
+class TracedValue;
+} // namespace trace_event
} // namespace base
namespace blink {
@@ -31,9 +34,9 @@ class FrameTaskQueueControllerTest;
class MainThreadSchedulerImpl;
// FrameTaskQueueController creates and manages and FrameSchedulerImpl's task
-// queues. It is in charge of maintaining mappings between TaskType and
-// QueueTraits and from QueueTraits to MainThreadTaskQueue, for accessing task
-// queues and their related voters, and for creating new task queues.
+// queues. It is in charge of maintaining mappings between QueueTraits and
+// MainThreadTaskQueues for non-loading queues, for accessing task queues and
+// their related voters, and for creating new task queues.
class PLATFORM_EXPORT FrameTaskQueueController {
public:
using TaskQueueAndEnabledVoterPair =
@@ -60,6 +63,19 @@ class PLATFORM_EXPORT FrameTaskQueueController {
Delegate*);
~FrameTaskQueueController();
+ // Return the loading task queue and create it if it doesn't exist.
+ scoped_refptr<MainThreadTaskQueue> LoadingTaskQueue();
+
+ // Return the loading control task queue and create it if it doesn't exist.
+ scoped_refptr<MainThreadTaskQueue> LoadingControlTaskQueue();
+
+ // Return the non-loading task queue associated with the given queue traits,
+ // and created it if it doesn't exist.
+ scoped_refptr<MainThreadTaskQueue> NonLoadingTaskQueue(
+ MainThreadTaskQueue::QueueTraits);
+
+ scoped_refptr<MainThreadTaskQueue> NewResourceLoadingTaskQueue();
+
// Get the list of all task queue and voter pairs.
const std::vector<TaskQueueAndEnabledVoterPair>& GetAllTaskQueuesAndVoters()
const;
@@ -69,8 +85,6 @@ class PLATFORM_EXPORT FrameTaskQueueController {
base::sequence_manager::TaskQueue::QueueEnabledVoter* GetQueueEnabledVoter(
const scoped_refptr<MainThreadTaskQueue>&);
- scoped_refptr<MainThreadTaskQueue> NewResourceLoadingTaskQueue();
-
// Remove a resource loading task queue that FrameTaskQueueController created,
// along with its QueueEnabledVoter, if one exists. Returns true if the task
// queue was found and erased and false otherwise.
@@ -80,24 +94,20 @@ class PLATFORM_EXPORT FrameTaskQueueController {
bool RemoveResourceLoadingTaskQueue(
const scoped_refptr<MainThreadTaskQueue>&);
+ void AsValueInto(base::trace_event::TracedValue* state) const;
+
private:
friend class FrameTaskQueueControllerTest;
- scoped_refptr<MainThreadTaskQueue> NewLoadingTaskQueue();
- scoped_refptr<MainThreadTaskQueue> NewLoadingControlTaskQueue();
- scoped_refptr<MainThreadTaskQueue> NewNonLoadingTaskQueue(
- MainThreadTaskQueue::QueueTraits);
+ void CreateLoadingTaskQueue();
+ void CreateLoadingControlTaskQueue();
+ void CreateNonLoadingTaskQueue(MainThreadTaskQueue::QueueTraits);
void TaskQueueCreated(const scoped_refptr<MainThreadTaskQueue>&);
- // Returns the unique non-loading task queue for the given QueueTraits, or
- // nullptr if one has not yet been created.
- scoped_refptr<MainThreadTaskQueue> GetNonLoadingTaskQueue(
- MainThreadTaskQueue::QueueTraits) const;
-
// Map a set of QueueTraits to a QueueType.
- // TODO(shaseley): Consider creating a new queue type kFrameNonLoading and use
- // it instead of this for new queue types.
+ // TODO(crbug.com/877245): Consider creating a new queue type kFrameNonLoading
+ // and use it instead of this for new queue types.
static MainThreadTaskQueue::QueueType QueueTypeFromQueueTraits(
MainThreadTaskQueue::QueueTraits);
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 2f862a9886f..3044678d7af 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
@@ -22,6 +22,7 @@
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
+#include "third_party/blink/renderer/platform/wtf/hash_set.h"
using base::sequence_manager::TaskQueue;
using QueueType = blink::scheduler::MainThreadTaskQueue::QueueType;
@@ -48,8 +49,9 @@ class FrameTaskQueueControllerTest : public testing::Test,
task_environment_.GetMockTickClock()),
base::nullopt));
page_scheduler_.reset(new PageSchedulerImpl(nullptr, scheduler_.get()));
- frame_scheduler_ = FrameSchedulerImpl::Create(
- page_scheduler_.get(), nullptr, FrameScheduler::FrameType::kSubframe);
+ frame_scheduler_ =
+ FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr, nullptr,
+ FrameScheduler::FrameType::kSubframe);
frame_task_queue_controller_.reset(new FrameTaskQueueController(
scheduler_.get(), frame_scheduler_.get(), this));
}
@@ -69,17 +71,17 @@ class FrameTaskQueueControllerTest : public testing::Test,
}
protected:
- scoped_refptr<MainThreadTaskQueue> NewLoadingTaskQueue() const {
- return frame_task_queue_controller_->NewLoadingTaskQueue();
+ scoped_refptr<MainThreadTaskQueue> LoadingTaskQueue() const {
+ return frame_task_queue_controller_->LoadingTaskQueue();
}
- scoped_refptr<MainThreadTaskQueue> NewLoadingControlTaskQueue() const {
- return frame_task_queue_controller_->NewLoadingControlTaskQueue();
+ scoped_refptr<MainThreadTaskQueue> LoadingControlTaskQueue() const {
+ return frame_task_queue_controller_->LoadingControlTaskQueue();
}
- scoped_refptr<MainThreadTaskQueue> NewNonLoadingTaskQueue(
+ scoped_refptr<MainThreadTaskQueue> NonLoadingTaskQueue(
QueueTraits queue_traits) const {
- return frame_task_queue_controller_->NewNonLoadingTaskQueue(queue_traits);
+ return frame_task_queue_controller_->NonLoadingTaskQueue(queue_traits);
}
scoped_refptr<MainThreadTaskQueue> NewResourceLoadingTaskQueue() const {
@@ -107,38 +109,38 @@ TEST_F(FrameTaskQueueControllerTest, CreateAllTaskQueues) {
WTF::HashMap<scoped_refptr<MainThreadTaskQueue>, QueueCheckResult>
all_task_queues;
- scoped_refptr<MainThreadTaskQueue> task_queue = NewLoadingTaskQueue();
+ scoped_refptr<MainThreadTaskQueue> task_queue = LoadingTaskQueue();
EXPECT_FALSE(all_task_queues.Contains(task_queue));
all_task_queues.insert(task_queue.get(), QueueCheckResult::kDidNotSeeQueue);
EXPECT_EQ(all_task_queues.size(), task_queue_created_count());
- task_queue = NewLoadingControlTaskQueue();
+ task_queue = LoadingControlTaskQueue();
EXPECT_FALSE(all_task_queues.Contains(task_queue));
all_task_queues.insert(task_queue.get(), QueueCheckResult::kDidNotSeeQueue);
EXPECT_EQ(all_task_queues.size(), task_queue_created_count());
// Create the 4 default non-loading task queues used by FrameSchedulerImpl.
- task_queue = NewNonLoadingTaskQueue(QueueTraits()
- .SetCanBeThrottled(true)
- .SetCanBeDeferred(true)
- .SetCanBeFrozen(true)
- .SetCanBePaused(true));
+ task_queue = NonLoadingTaskQueue(QueueTraits()
+ .SetCanBeThrottled(true)
+ .SetCanBeDeferred(true)
+ .SetCanBeFrozen(true)
+ .SetCanBePaused(true));
EXPECT_FALSE(all_task_queues.Contains(task_queue));
all_task_queues.insert(task_queue.get(), QueueCheckResult::kDidNotSeeQueue);
EXPECT_EQ(all_task_queues.size(), task_queue_created_count());
- task_queue = NewNonLoadingTaskQueue(
+ task_queue = NonLoadingTaskQueue(
QueueTraits().SetCanBeDeferred(true).SetCanBePaused(true));
EXPECT_FALSE(all_task_queues.Contains(task_queue));
all_task_queues.insert(task_queue.get(), QueueCheckResult::kDidNotSeeQueue);
EXPECT_EQ(all_task_queues.size(), task_queue_created_count());
- task_queue = NewNonLoadingTaskQueue(QueueTraits().SetCanBePaused(true));
+ task_queue = NonLoadingTaskQueue(QueueTraits().SetCanBePaused(true));
EXPECT_FALSE(all_task_queues.Contains(task_queue));
all_task_queues.insert(task_queue.get(), QueueCheckResult::kDidNotSeeQueue);
EXPECT_EQ(all_task_queues.size(), task_queue_created_count());
- task_queue = NewNonLoadingTaskQueue(QueueTraits());
+ task_queue = NonLoadingTaskQueue(QueueTraits());
EXPECT_FALSE(all_task_queues.Contains(task_queue));
all_task_queues.insert(task_queue.get(), QueueCheckResult::kDidNotSeeQueue);
EXPECT_EQ(all_task_queues.size(), task_queue_created_count());
@@ -221,7 +223,7 @@ TEST_F(FrameTaskQueueControllerTest, RemoveResourceLoadingTaskQueues) {
}
TEST_F(FrameTaskQueueControllerTest, CannotRemoveNonResourceLoadingTaskQueues) {
- scoped_refptr<MainThreadTaskQueue> task_queue = NewLoadingTaskQueue();
+ scoped_refptr<MainThreadTaskQueue> task_queue = LoadingTaskQueue();
EXPECT_EQ(1u,
frame_task_queue_controller_->GetAllTaskQueuesAndVoters().size());
bool was_removed =
@@ -231,5 +233,35 @@ TEST_F(FrameTaskQueueControllerTest, CannotRemoveNonResourceLoadingTaskQueues) {
frame_task_queue_controller_->GetAllTaskQueuesAndVoters().size());
}
+TEST_F(FrameTaskQueueControllerTest, AddAndRetrieveAllNonLoadingTaskQueues) {
+ // Create queues for all combination of queue traits for all combinations of
+ // the 4 QueueTraits bits.
+ WTF::HashSet<scoped_refptr<MainThreadTaskQueue>> all_task_queues;
+ constexpr size_t kTotalUniqueQueueTraits = 1 << 4;
+ for (size_t i = 0; i < kTotalUniqueQueueTraits; i++) {
+ MainThreadTaskQueue::QueueTraits queue_traits =
+ QueueTraits()
+ .SetCanBeThrottled(!!(i & 1 << 0))
+ .SetCanBeDeferred(!!(i & 1 << 1))
+ .SetCanBeFrozen(!!(i & 1 << 2))
+ .SetCanBePaused(!!(i & 1 << 3));
+ scoped_refptr<MainThreadTaskQueue> task_queue =
+ frame_task_queue_controller_->NonLoadingTaskQueue(queue_traits);
+ EXPECT_FALSE(all_task_queues.Contains(task_queue));
+ all_task_queues.insert(task_queue);
+ EXPECT_EQ(task_queue->GetQueueTraits(), queue_traits);
+ }
+ // Make sure we get the same queues back, with matching QueueTraits.
+ EXPECT_EQ(all_task_queues.size(), kTotalUniqueQueueTraits);
+ for (const auto& task_queue : all_task_queues) {
+ scoped_refptr<MainThreadTaskQueue> returned_task_queue =
+ frame_task_queue_controller_->NonLoadingTaskQueue(
+ task_queue->GetQueueTraits());
+ EXPECT_EQ(task_queue->GetQueueTraits(),
+ returned_task_queue->GetQueueTraits());
+ EXPECT_TRUE(task_queue == returned_task_queue);
+ }
+}
+
} // namespace scheduler
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.cc
index 69bc681f6b3..9c357a6c338 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.cc
@@ -452,6 +452,13 @@ void MainThreadMetricsHelper::RecordTaskMetrics(
input_handling_per_task_type_duration_reporter_.RecordTask(task_type,
duration);
}
+ if (task_type == TaskType::kNetworkingWithURLLoaderAnnotation && queue &&
+ queue->net_request_priority()) {
+ UMA_HISTOGRAM_ENUMERATION(
+ "RendererScheduler.ResourceLoadingTaskCountPerNetPriority",
+ queue->net_request_priority().value(),
+ net::RequestPriority::MAXIMUM_PRIORITY + 1);
+ }
}
void MainThreadMetricsHelper::RecordMainThreadTaskLoad(base::TimeTicks time,
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.h
index 88d0e58e237..f8e9062efd1 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.h
@@ -8,15 +8,15 @@
#include "base/macros.h"
#include "base/optional.h"
#include "base/time/time.h"
+#include "components/scheduling_metrics/task_duration_metric_reporter.h"
+#include "components/scheduling_metrics/total_duration_metric_reporter.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/web_thread_type.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/scheduler/common/metrics_helper.h"
-#include "third_party/blink/renderer/platform/scheduler/common/total_duration_metric_reporter.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/use_case.h"
#include "third_party/blink/renderer/platform/scheduler/renderer/frame_status.h"
-#include "third_party/blink/renderer/platform/scheduler/util/task_duration_metric_reporter.h"
#include "third_party/blink/renderer/platform/scheduler/util/thread_load_tracker.h"
namespace blink {
@@ -26,6 +26,15 @@ enum class MainThreadTaskLoadState;
class MainThreadTaskQueue;
class MainThreadSchedulerImpl;
+enum class UkmRecordingStatus {
+ kSuccess = 0,
+ kErrorMissingFrame = 1,
+ kErrorDetachedFrame = 2,
+ kErrorMissingUkmRecorder = 3,
+
+ kCount = 4,
+};
+
// Helper class to take care of metrics on behalf of MainThreadScheduler.
// This class should be used only on the main thread.
class PLATFORM_EXPORT MainThreadMetricsHelper : public MetricsHelper {
@@ -52,6 +61,10 @@ class PLATFORM_EXPORT MainThreadMetricsHelper : public MetricsHelper {
void ResetForTest(base::TimeTicks now);
private:
+ using TaskDurationPerQueueTypeMetricReporter =
+ scheduling_metrics::TaskDurationMetricReporter<
+ MainThreadTaskQueue::QueueType>;
+
void ReportLowThreadLoadForPageAlmostIdleSignal(int load_percentage);
MainThreadSchedulerImpl* main_thread_scheduler_; // NOT OWNED
@@ -69,9 +82,6 @@ class PLATFORM_EXPORT MainThreadMetricsHelper : public MetricsHelper {
ThreadLoadTracker background_main_thread_load_tracker_;
ThreadLoadTracker foreground_main_thread_load_tracker_;
- using TaskDurationPerQueueTypeMetricReporter =
- TaskDurationMetricReporter<MainThreadTaskQueue::QueueType>;
-
struct PerQueueTypeDurationReporters {
PerQueueTypeDurationReporters();
@@ -100,10 +110,11 @@ class PLATFORM_EXPORT MainThreadMetricsHelper : public MetricsHelper {
PerQueueTypeDurationReporters per_queue_type_reporters_;
- TaskDurationMetricReporter<FrameStatus> per_frame_status_duration_reporter_;
+ scheduling_metrics::TaskDurationMetricReporter<FrameStatus>
+ per_frame_status_duration_reporter_;
using TaskDurationPerTaskTypeMetricReporter =
- TaskDurationMetricReporter<TaskType>;
+ scheduling_metrics::TaskDurationMetricReporter<TaskType>;
TaskDurationPerTaskTypeMetricReporter per_task_type_duration_reporter_;
@@ -127,9 +138,10 @@ class PLATFORM_EXPORT MainThreadMetricsHelper : public MetricsHelper {
TaskDurationPerTaskTypeMetricReporter
background_after_tenth_minute_per_task_type_duration_reporter_;
- TaskDurationMetricReporter<UseCase> per_task_use_case_duration_reporter_;
+ scheduling_metrics::TaskDurationMetricReporter<UseCase>
+ per_task_use_case_duration_reporter_;
- TotalDurationMetricReporter total_task_time_reporter_;
+ scheduling_metrics::TotalDurationMetricReporter total_task_time_reporter_;
MainThreadTaskLoadState main_thread_task_load_state_;
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.cc
index bd4d984a589..6222ae68489 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.cc
@@ -4,7 +4,6 @@
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.h"
-#include "third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h"
namespace blink {
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 970f7113daf..32becb7833c 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
@@ -27,6 +27,7 @@
#include "third_party/blink/public/platform/scheduler/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.h"
#include "third_party/blink/renderer/platform/instrumentation/resource_coordinator/blink_resource_coordinator_base.h"
#include "third_party/blink/renderer/platform/instrumentation/resource_coordinator/renderer_resource_coordinator.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
@@ -36,8 +37,8 @@
#include "third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h"
+#include "third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.h"
#include "third_party/blink/renderer/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler.h"
-#include "third_party/blink/renderer/platform/wtf/text/movable_string.h"
namespace blink {
namespace scheduler {
@@ -62,7 +63,6 @@ const double kShortIdlePeriodDurationPercentile = 50;
const double kFastCompositingIdleTimeThreshold = .2;
constexpr base::TimeDelta kQueueingTimeWindowDuration =
base::TimeDelta::FromSeconds(1);
-const double kSamplingRateForTaskUkm = 0.0001;
const int64_t kSecondsPerMinute = 60;
// Wake-up throttling trial.
@@ -121,119 +121,12 @@ const char* RendererProcessTypeToString(RendererProcessType process_type) {
return ""; // MSVC needs that.
}
-const char* TaskTypeToString(TaskType task_type) {
- switch (task_type) {
- case TaskType::kDeprecatedNone:
- return "None";
- case TaskType::kDOMManipulation:
- return "DOMManipultion";
- case TaskType::kUserInteraction:
- return "UserInteraction";
- case TaskType::kNetworking:
- return "Networking";
- case TaskType::kNetworkingWithURLLoaderAnnotation:
- return "NetworkingWithURLLoaderAnnotation";
- case TaskType::kNetworkingControl:
- return "NetworkingControl";
- case TaskType::kHistoryTraversal:
- return "HistoryTraversal";
- case TaskType::kEmbed:
- return "Embed";
- case TaskType::kMediaElementEvent:
- return "MediaElementEvent";
- case TaskType::kCanvasBlobSerialization:
- return "CanvasBlobSerialization";
- case TaskType::kMicrotask:
- return "Microtask";
- case TaskType::kJavascriptTimer:
- return "JavascriptTimer";
- case TaskType::kRemoteEvent:
- return "RemoteEvent";
- case TaskType::kWebSocket:
- return "WebSocket";
- case TaskType::kPostedMessage:
- return "PostedMessage";
- case TaskType::kUnshippedPortMessage:
- return "UnshipedPortMessage";
- case TaskType::kFileReading:
- return "FileReading";
- case TaskType::kDatabaseAccess:
- return "DatabaseAccess";
- case TaskType::kPresentation:
- return "Presentation";
- case TaskType::kSensor:
- return "Sensor";
- case TaskType::kPerformanceTimeline:
- return "PerformanceTimeline";
- case TaskType::kWebGL:
- return "WebGL";
- case TaskType::kIdleTask:
- return "IdleTask";
- case TaskType::kMiscPlatformAPI:
- return "MiscPlatformAPI";
- case TaskType::kInternalDefault:
- return "InternalDefault";
- case TaskType::kInternalLoading:
- return "InternalLoading";
- case TaskType::kInternalTest:
- return "InternalTest";
- case TaskType::kInternalWebCrypto:
- return "InternalWebCrypto";
- case TaskType::kInternalIndexedDB:
- return "InternalIndexedDB";
- case TaskType::kInternalMedia:
- return "InternalMedia";
- case TaskType::kInternalMediaRealTime:
- return "InternalMediaRealTime";
- case TaskType::kInternalIPC:
- return "InternalIPC";
- case TaskType::kInternalUserInteraction:
- return "InternalUserInteraction";
- case TaskType::kInternalInspector:
- return "InternalInspector";
- case TaskType::kInternalWorker:
- return "InternalWorker";
- case TaskType::kMainThreadTaskQueueV8:
- return "MainThreadTaskQueueV8";
- case TaskType::kMainThreadTaskQueueCompositor:
- return "MainThreadTaskQueueCompositor";
- case TaskType::kMainThreadTaskQueueDefault:
- return "MainThreadTaskQueueDefault";
- case TaskType::kMainThreadTaskQueueInput:
- return "MainThreadTaskQueueInput";
- case TaskType::kMainThreadTaskQueueIdle:
- return "MainThreadTaskQueueIdle";
- case TaskType::kMainThreadTaskQueueIPC:
- return "MainThreadTaskQueueIPC";
- case TaskType::kMainThreadTaskQueueControl:
- return "MainThreadTaskQueueControl";
- case TaskType::kInternalIntersectionObserver:
- return "InternalIntersectionObserver";
- case TaskType::kCompositorThreadTaskQueueDefault:
- return "CompositorThreadTaskQueueDefault";
- case TaskType::kCompositorThreadTaskQueueInput:
- return "CompositorThreadTaskQueueInput";
- case TaskType::kWorkerThreadTaskQueueDefault:
- return "WorkerThreadTaskQueueDefault";
- case TaskType::kWorkerThreadTaskQueueV8:
- return "WorkerThreadTaskQueueV8";
- case TaskType::kWorkerThreadTaskQueueCompositor:
- return "WorkerThreadTaskQueueCompositor";
- case TaskType::kWorkerAnimation:
- return "WorkerAnimation";
- case TaskType::kCount:
- return "Count";
- }
- NOTREACHED();
- return "";
-}
-
const char* OptionalTaskDescriptionToString(
base::Optional<MainThreadSchedulerImpl::TaskDescriptionForTracing> desc) {
if (!desc)
return nullptr;
if (desc->task_type != TaskType::kDeprecatedNone)
- return TaskTypeToString(desc->task_type);
+ return TaskTypeNames::TaskTypeToString(desc->task_type);
if (!desc->queue_type)
return "detached_tq";
return MainThreadTaskQueue::NameForQueueType(desc->queue_type.value());
@@ -321,8 +214,8 @@ MainThreadSchedulerImpl::MainThreadSchedulerImpl(
delayed_update_policy_runner_(
base::BindRepeating(&MainThreadSchedulerImpl::UpdatePolicy,
base::Unretained(this)),
- TaskQueueWithTaskType::Create(helper_.ControlMainThreadTaskQueue(),
- TaskType::kMainThreadTaskQueueControl)),
+ helper_.ControlMainThreadTaskQueue()->CreateTaskRunner(
+ TaskType::kMainThreadTaskQueueControl)),
queueing_time_estimator_(this, kQueueingTimeWindowDuration, 20),
main_thread_only_(this,
compositor_task_queue_,
@@ -345,18 +238,21 @@ MainThreadSchedulerImpl::MainThreadSchedulerImpl(
MainThreadTaskQueue::QueueType::kV8));
ipc_task_queue_ = NewTaskQueue(MainThreadTaskQueue::QueueCreationParams(
MainThreadTaskQueue::QueueType::kIPC));
-
- v8_task_runner_ = TaskQueueWithTaskType::Create(
- v8_task_queue_, TaskType::kMainThreadTaskQueueV8);
- compositor_task_runner_ = TaskQueueWithTaskType::Create(
- compositor_task_queue_, TaskType::kMainThreadTaskQueueCompositor);
- control_task_runner_ =
- TaskQueueWithTaskType::Create(helper_.ControlMainThreadTaskQueue(),
- TaskType::kMainThreadTaskQueueControl);
- input_task_runner_ = TaskQueueWithTaskType::Create(
- input_task_queue_, TaskType::kMainThreadTaskQueueInput);
- ipc_task_runner_ = TaskQueueWithTaskType::Create(
- ipc_task_queue_, TaskType::kMainThreadTaskQueueIPC);
+ cleanup_task_queue_ = NewTaskQueue(MainThreadTaskQueue::QueueCreationParams(
+ MainThreadTaskQueue::QueueType::kCleanup));
+
+ v8_task_runner_ =
+ v8_task_queue_->CreateTaskRunner(TaskType::kMainThreadTaskQueueV8);
+ compositor_task_runner_ = compositor_task_queue_->CreateTaskRunner(
+ 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);
// TaskQueueThrottler requires some task runners, then initialize
// TaskQueueThrottler after task queues/runners are initialized.
@@ -610,7 +506,6 @@ MainThreadSchedulerImpl::MainThreadOnly::MainThreadOnly(
max_virtual_time_task_starvation_count(0),
virtual_time_stopped(false),
nested_runloop(false),
- uniform_distribution(0.0f, 1.0f),
compositing_experiment(main_thread_scheduler_impl),
should_prioritize_compositing(false) {}
@@ -718,6 +613,9 @@ MainThreadSchedulerImpl::SchedulingSettings::SchedulingSettings() {
}
}
}
+
+ FrameSchedulerImpl::InitializeTaskTypeQueueTraitsMap(
+ frame_task_types_to_queue_traits);
}
MainThreadSchedulerImpl::AnyThread::~AnyThread() = default;
@@ -783,6 +681,11 @@ MainThreadSchedulerImpl::IPCTaskRunner() {
}
scoped_refptr<base::SingleThreadTaskRunner>
+MainThreadSchedulerImpl::CleanupTaskRunner() {
+ return cleanup_task_runner_;
+}
+
+scoped_refptr<base::SingleThreadTaskRunner>
MainThreadSchedulerImpl::VirtualTimeControlTaskRunner() {
return virtual_time_control_task_queue_;
}
@@ -1064,6 +967,13 @@ void MainThreadSchedulerImpl::SetRendererHidden(bool hidden) {
void MainThreadSchedulerImpl::SetRendererBackgrounded(bool backgrounded) {
helper_.CheckOnValidThread();
+
+ // Increasing timer slack helps the OS to coalesce timers efficiently.
+ base::TimerSlack timer_slack = base::TIMER_SLACK_NONE;
+ if (backgrounded)
+ timer_slack = base::TIMER_SLACK_MAXIMUM;
+ helper_.SetTimerSlack(timer_slack);
+
if (helper_.IsShutdown() ||
main_thread_only().renderer_backgrounded == backgrounded)
return;
@@ -1091,12 +1001,13 @@ void MainThreadSchedulerImpl::SetRendererBackgrounded(bool backgrounded) {
main_thread_only().metrics_helper.OnRendererForegrounded(now);
}
- auto& movable_string_table = MovableStringTable::Instance();
- movable_string_table.SetRendererBackgrounded(backgrounded);
+ auto& parkable_string_table = ParkableStringTable::Instance();
+ parkable_string_table.SetRendererBackgrounded(backgrounded);
if (backgrounded) {
DefaultTaskRunner()->PostDelayedTask(
- FROM_HERE,
- base::BindOnce([]() { MovableStringTable::Instance().MaybeParkAll(); }),
+ FROM_HERE, base::BindOnce([]() {
+ ParkableStringTable::Instance().MaybeParkAll();
+ }),
base::TimeDelta::FromSeconds(10));
}
}
@@ -1849,6 +1760,10 @@ base::TimeDelta MainThreadSchedulerImpl::EstimateLongestJankFreeTaskDuration()
}
}
+SchedulerHelper* MainThreadSchedulerImpl::GetHelper() {
+ return &helper_;
+}
+
bool MainThreadSchedulerImpl::CanEnterLongIdlePeriod(
base::TimeTicks now,
base::TimeDelta* next_long_idle_period_delay_out) {
@@ -2457,7 +2372,8 @@ void MainThreadSchedulerImpl::SetTopLevelBlameContext(
ipc_task_queue_->SetBlameContext(blame_context);
}
-void MainThreadSchedulerImpl::AddRAILModeObserver(RAILModeObserver* observer) {
+void MainThreadSchedulerImpl::AddRAILModeObserver(
+ WebRAILModeObserver* observer) {
main_thread_only().rail_mode_observers.AddObserver(observer);
observer->OnRAILModeChanged(main_thread_only().current_policy.rail_mode());
}
@@ -2617,38 +2533,47 @@ void MainThreadSchedulerImpl::RecordTaskUkm(
return;
if (queue && queue->GetFrameScheduler()) {
- RecordTaskUkmImpl(queue, task, task_timing,
- static_cast<PageSchedulerImpl*>(
- queue->GetFrameScheduler()->GetPageScheduler()),
- 1);
+ auto status = RecordTaskUkmImpl(queue, task, task_timing,
+ queue->GetFrameScheduler(), true);
+ UMA_HISTOGRAM_ENUMERATION(
+ "Scheduler.Experimental.Renderer.UkmRecordingStatus", status,
+ UkmRecordingStatus::kCount);
return;
}
for (PageSchedulerImpl* page_scheduler : main_thread_only().page_schedulers) {
- RecordTaskUkmImpl(queue, task, task_timing, page_scheduler,
- main_thread_only().page_schedulers.size());
+ auto status = RecordTaskUkmImpl(
+ queue, task, task_timing,
+ page_scheduler->SelectFrameForUkmAttribution(), false);
+ UMA_HISTOGRAM_ENUMERATION(
+ "Scheduler.Experimental.Renderer.UkmRecordingStatus", status,
+ UkmRecordingStatus::kCount);
}
}
-void MainThreadSchedulerImpl::RecordTaskUkmImpl(
+UkmRecordingStatus MainThreadSchedulerImpl::RecordTaskUkmImpl(
MainThreadTaskQueue* queue,
const TaskQueue::Task& task,
const TaskQueue::TaskTiming& task_timing,
- PageSchedulerImpl* page_scheduler,
- size_t page_schedulers_to_attribute) {
- // Skip tasks which have deleted the page scheduler.
- if (!page_scheduler)
- return;
-
- ukm::UkmRecorder* ukm_recorder = page_scheduler->GetUkmRecorder();
+ FrameSchedulerImpl* frame_scheduler,
+ bool precise_attribution) {
+ // Skip tasks which have deleted the frame or the page scheduler.
+ if (!frame_scheduler)
+ return UkmRecordingStatus::kErrorMissingFrame;
+ if (!frame_scheduler->GetPageScheduler())
+ return UkmRecordingStatus::kErrorDetachedFrame;
+
+ ukm::UkmRecorder* ukm_recorder = frame_scheduler->GetUkmRecorder();
// OOPIFs are not supported.
if (!ukm_recorder)
- return;
+ return UkmRecordingStatus::kErrorMissingUkmRecorder;
ukm::builders::RendererSchedulerTask builder(
- page_scheduler->GetUkmSourceId());
+ frame_scheduler->GetUkmSourceId());
+
+ builder.SetVersion(kUkmMetricVersion);
+ builder.SetPageSchedulers(main_thread_only().page_schedulers.size());
- builder.SetPageSchedulers(page_schedulers_to_attribute);
builder.SetRendererBackgrounded(main_thread_only().renderer_backgrounded);
builder.SetRendererHidden(main_thread_only().renderer_hidden);
builder.SetRendererAudible(main_thread_only().is_audio_playing);
@@ -2660,6 +2585,7 @@ void MainThreadSchedulerImpl::RecordTaskUkmImpl(
builder.SetFrameStatus(static_cast<int>(
GetFrameStatus(queue ? queue->GetFrameScheduler() : nullptr)));
builder.SetTaskDuration(task_timing.wall_duration().InMicroseconds());
+ builder.SetIsOOPIF(!frame_scheduler->GetPageScheduler()->IsMainFrameLocal());
if (main_thread_only().renderer_backgrounded) {
base::TimeDelta time_since_backgrounded =
@@ -2684,6 +2610,8 @@ void MainThreadSchedulerImpl::RecordTaskUkmImpl(
}
builder.Record(ukm_recorder);
+
+ return UkmRecordingStatus::kSuccess;
}
TaskQueue::QueuePriority MainThreadSchedulerImpl::ComputePriority(
@@ -2855,31 +2783,6 @@ bool MainThreadSchedulerImpl::IsAudioPlaying() const {
return main_thread_only().is_audio_playing;
}
-bool MainThreadSchedulerImpl::ShouldIgnoreTaskForUkm(bool has_thread_time,
- double* sampling_rate) {
- const double thread_time_sampling_rate =
- helper_.GetSamplingRateForRecordingCPUTime();
- if (thread_time_sampling_rate && *sampling_rate < thread_time_sampling_rate) {
- if (!has_thread_time)
- return true;
- *sampling_rate /= thread_time_sampling_rate;
- }
- return false;
-}
-
-bool MainThreadSchedulerImpl::ShouldRecordTaskUkm(bool has_thread_time) {
- double sampling_rate = kSamplingRateForTaskUkm;
-
- // If thread_time is sampled as well, try to align UKM sampling with it so
- // that we only record UKMs for tasks that also record thread_time.
- if (ShouldIgnoreTaskForUkm(has_thread_time, &sampling_rate)) {
- return false;
- }
-
- return main_thread_only().uniform_distribution(
- main_thread_only().random_generator) < sampling_rate;
-}
-
bool MainThreadSchedulerImpl::ShouldUpdateTaskQueuePriorities(
Policy old_policy) const {
return old_policy.use_case() !=
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 20fb1a37a14..e34eb40b16e 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
@@ -17,6 +17,7 @@
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/metrics/single_sample_metrics.h"
+#include "base/optional.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/lock.h"
#include "base/task/sequence_manager/task_queue.h"
@@ -26,7 +27,6 @@
#include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/scheduler/child/pollable_thread_safe_flag.h"
-#include "third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.h"
#include "third_party/blink/renderer/platform/scheduler/common/idle_canceled_delayed_task_sweeper.h"
#include "third_party/blink/renderer/platform/scheduler/common/idle_helper.h"
#include "third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.h"
@@ -125,8 +125,13 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
net::RequestPrioritySize::NUM_PRIORITIES>
net_to_blink_priority;
- // Turn on relevant experiments during the loading phase.
- bool experiment_only_when_loading;
+ 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);
@@ -154,6 +159,7 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
std::unique_ptr<WebThread> CreateMainThread() override;
scoped_refptr<SingleThreadIdleTaskRunner> IdleTaskRunner() override;
scoped_refptr<base::SingleThreadTaskRunner> IPCTaskRunner() override;
+ scoped_refptr<base::SingleThreadTaskRunner> CleanupTaskRunner() override;
std::unique_ptr<WebRenderWidgetSchedulingState>
NewRenderWidgetSchedulingState() override;
void WillBeginFrame(const viz::BeginFrameArgs& args) override;
@@ -186,7 +192,7 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
void Shutdown() override;
void SetTopLevelBlameContext(
base::trace_event::BlameContext* blame_context) override;
- void AddRAILModeObserver(RAILModeObserver* observer) override;
+ void AddRAILModeObserver(WebRAILModeObserver* observer) override;
void SetRendererProcessType(RendererProcessType type) override;
WebScopedVirtualTimePauser CreateWebScopedVirtualTimePauser(
const char* name,
@@ -582,6 +588,9 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
MainThreadSchedulerImpl* scheduler_; // NOT OWNED
};
+ // ThreadSchedulerImpl implementation:
+ SchedulerHelper* GetHelper() override;
+
// IdleHelper::Delegate implementation:
bool CanEnterLongIdlePeriod(
base::TimeTicks now,
@@ -589,8 +598,8 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
void IsNotQuiescent() override {}
void OnIdlePeriodStarted() override;
void OnIdlePeriodEnded() override;
-
void OnPendingTasksChanged(bool has_tasks) override;
+
void DispatchRequestBeginMainFrameNotExpected(bool has_tasks);
void EndIdlePeriod();
@@ -643,7 +652,7 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
kForceUpdate,
};
- // The implelemtation of UpdatePolicy & ForceUpdatePolicy. It is allowed to
+ // The implementation of UpdatePolicy & ForceUpdatePolicy. It is allowed to
// early out if |update_type| is kMayEarlyOutIfPolicyUnchanged.
virtual void UpdatePolicyLocked(UpdateType update_type);
@@ -702,15 +711,6 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
// TaskQueueThrottler.
void VirtualTimeResumed();
- // Returns true if the current task should not be reported in UKM because no
- // thread time was recorded for it. Also updates |sampling_rate| to account
- // for the ignored tasks by sampling the remaining tasks with higher
- // probability.
- bool ShouldIgnoreTaskForUkm(bool has_thread_time, double* sampling_rate);
-
- // Returns true with probability of kSamplingRateForTaskUkm.
- bool ShouldRecordTaskUkm(bool has_thread_time);
-
// Returns true if there is a change in the main thread's policy that should
// trigger a priority update.
bool ShouldUpdateTaskQueuePriorities(Policy new_policy) const;
@@ -725,12 +725,12 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
const base::sequence_manager::TaskQueue::Task& task,
const base::sequence_manager::TaskQueue::TaskTiming& task_timing);
- void RecordTaskUkmImpl(
+ UkmRecordingStatus RecordTaskUkmImpl(
MainThreadTaskQueue* queue,
const base::sequence_manager::TaskQueue::Task& task,
const base::sequence_manager::TaskQueue::TaskTiming& task_timing,
- PageSchedulerImpl* page_scheduler,
- size_t page_schedulers_to_attribute);
+ FrameSchedulerImpl* frame_scheduler,
+ bool precise_attribution);
void InitWakeUpBudgetPoolIfNeeded();
@@ -777,12 +777,14 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
scoped_refptr<MainThreadTaskQueue> v8_task_queue_;
scoped_refptr<MainThreadTaskQueue> ipc_task_queue_;
+ scoped_refptr<MainThreadTaskQueue> cleanup_task_queue_;
- scoped_refptr<TaskQueueWithTaskType> v8_task_runner_;
- scoped_refptr<TaskQueueWithTaskType> compositor_task_runner_;
- scoped_refptr<TaskQueueWithTaskType> control_task_runner_;
- scoped_refptr<TaskQueueWithTaskType> input_task_runner_;
- scoped_refptr<TaskQueueWithTaskType> ipc_task_runner_;
+ 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_;
// Note |virtual_time_domain_| is lazily created.
std::unique_ptr<AutoAdvancingVirtualTimeDomain> virtual_time_domain_;
@@ -853,9 +855,10 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
std::unique_ptr<base::SingleSampleMetric> max_queueing_time_metric;
base::TimeDelta max_queueing_time;
base::TimeTicks background_status_changed_at;
- std::set<PageSchedulerImpl*> page_schedulers; // Not owned.
- base::ObserverList<RAILModeObserver> rail_mode_observers; // Not owned.
- WakeUpBudgetPool* wake_up_budget_pool; // Not owned.
+ std::set<PageSchedulerImpl*> page_schedulers; // Not owned.
+ base::ObserverList<WebRAILModeObserver>::Unchecked
+ rail_mode_observers; // Not owned.
+ WakeUpBudgetPool* wake_up_budget_pool; // Not owned.
MainThreadMetricsHelper metrics_helper;
TraceableState<RendererProcessType, kTracingCategoryNameTopLevel>
process_type;
@@ -866,7 +869,7 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
base::Optional<base::sequence_manager::TaskQueue::QueuePriority>,
kTracingCategoryNameInfo>
task_priority_for_tracing; // Only used for tracing.
- base::ObserverList<VirtualTimeObserver> virtual_time_observers;
+ base::ObserverList<VirtualTimeObserver>::Unchecked virtual_time_observers;
base::Time initial_virtual_time;
base::TimeTicks initial_virtual_time_ticks;
@@ -896,9 +899,6 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
// True if a nested RunLoop is running.
bool nested_runloop;
- std::mt19937_64 random_generator;
- std::uniform_real_distribution<double> uniform_distribution;
-
// High-priority for compositing events after input experiment.
PrioritizeCompositingAfterInputExperiment compositing_experiment;
bool should_prioritize_compositing;
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 8e37aaea02c..a9c26790de0 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
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h"
#include <memory>
+#include <string>
#include <utility>
#include "base/callback.h"
@@ -30,6 +31,7 @@
#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/frame_scheduler_impl.h"
+#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
using base::sequence_manager::TaskQueue;
@@ -276,7 +278,7 @@ class MainThreadSchedulerImplForTest : public MainThreadSchedulerImpl {
return any_thread().begin_main_frame_on_critical_path;
}
- void RemoveRAILModeObserver(RAILModeObserver const* observer) {
+ void RemoveRAILModeObserver(WebRAILModeObserver const* observer) {
main_thread_only().rail_mode_observers.RemoveObserver(observer);
}
@@ -350,13 +352,18 @@ class MainThreadSchedulerImplTest : public testing::Test {
page_scheduler_ =
std::make_unique<PageSchedulerImpl>(nullptr, scheduler_.get());
- main_frame_scheduler_ = FrameSchedulerImpl::Create(
- page_scheduler_.get(), nullptr, FrameScheduler::FrameType::kMainFrame);
+ main_frame_scheduler_ =
+ FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr, nullptr,
+ FrameScheduler::FrameType::kMainFrame);
- loading_task_runner_ = main_frame_scheduler_->LoadingTaskQueue();
+ auto* frame_task_queue_controller =
+ main_frame_scheduler_->FrameTaskQueueControllerForTest();
+ loading_task_runner_ = frame_task_queue_controller->LoadingTaskQueue();
loading_control_task_runner_ =
- main_frame_scheduler_->LoadingControlTaskQueue();
- timer_task_runner_ = main_frame_scheduler_->ThrottleableTaskQueue();
+ frame_task_queue_controller->LoadingControlTaskQueue();
+ auto queue_traits = main_frame_scheduler_->ThrottleableTaskQueueTraits();
+ timer_task_runner_ =
+ frame_task_queue_controller->NonLoadingTaskQueue(queue_traits);
}
void TearDown() override {
@@ -767,7 +774,10 @@ class MainThreadSchedulerImplTest : public testing::Test {
static scoped_refptr<TaskQueue> ThrottleableTaskQueue(
FrameSchedulerImpl* scheduler) {
- return scheduler->ThrottleableTaskQueue();
+ auto* frame_task_queue_controller =
+ scheduler->FrameTaskQueueControllerForTest();
+ auto queue_traits = FrameSchedulerImpl::ThrottleableTaskQueueTraits();
+ return frame_task_queue_controller->NonLoadingTaskQueue(queue_traits);
}
QueueingTimeEstimator* queueing_time_estimator() {
@@ -3358,7 +3368,7 @@ TEST_F(MainThreadSchedulerImplTest, MAIN_THREAD_GESTURE) {
EXPECT_EQ(279u, run_order.size());
}
-class MockRAILModeObserver : public WebThreadScheduler::RAILModeObserver {
+class MockRAILModeObserver : public WebRAILModeObserver {
public:
MOCK_METHOD1(OnRAILModeChanged, void(v8::RAILMode rail_mode));
};
@@ -3558,7 +3568,7 @@ TEST_F(MainThreadSchedulerImplTest, EnableVirtualTimeAfterThrottling) {
scheduler_->AddPageScheduler(page_scheduler.get());
std::unique_ptr<FrameSchedulerImpl> frame_scheduler =
- FrameSchedulerImpl::Create(page_scheduler.get(), nullptr,
+ FrameSchedulerImpl::Create(page_scheduler.get(), nullptr, nullptr,
FrameScheduler::FrameType::kSubframe);
TaskQueue* timer_tq = ThrottleableTaskQueue(frame_scheduler.get()).get();
@@ -3647,7 +3657,7 @@ TEST_F(MainThreadSchedulerImplTest, Tracing) {
scheduler_->AddPageScheduler(page_scheduler1.get());
std::unique_ptr<FrameSchedulerImpl> frame_scheduler =
- FrameSchedulerImpl::Create(page_scheduler1.get(), nullptr,
+ FrameSchedulerImpl::Create(page_scheduler1.get(), nullptr, nullptr,
FrameScheduler::FrameType::kSubframe);
std::unique_ptr<PageSchedulerImpl> page_scheduler2 =
@@ -3667,6 +3677,7 @@ TEST_F(MainThreadSchedulerImplTest, Tracing) {
std::unique_ptr<base::trace_event::ConvertableToTraceFormat> value =
scheduler_->AsValue(base::TimeTicks());
EXPECT_TRUE(value);
+ EXPECT_FALSE(value->ToString().empty());
}
void RecordingTimeTestTask(
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 c7f9dffa9cc..07d6cc5204f 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
@@ -51,6 +51,8 @@ const char* MainThreadTaskQueue::NameForQueueType(
return "input_tq";
case MainThreadTaskQueue::QueueType::kDetached:
return "detached_tq";
+ case MainThreadTaskQueue::QueueType::kCleanup:
+ return "cleanup_tq";
case MainThreadTaskQueue::QueueType::kOther:
return "other_tq";
case MainThreadTaskQueue::QueueType::kCount:
@@ -70,6 +72,7 @@ MainThreadTaskQueue::QueueClass MainThreadTaskQueue::QueueClassForQueueType(
case QueueType::kTest:
case QueueType::kV8:
case QueueType::kIPC:
+ case QueueType::kCleanup:
return QueueClass::kNone;
case QueueType::kFrameLoading:
case QueueType::kFrameLoadingControl:
@@ -178,5 +181,15 @@ void MainThreadTaskQueue::SetFrameSchedulerForTest(
frame_scheduler_ = frame_scheduler;
}
+void MainThreadTaskQueue::SetNetRequestPriority(
+ net::RequestPriority net_request_priority) {
+ net_request_priority_ = net_request_priority;
+}
+
+base::Optional<net::RequestPriority> MainThreadTaskQueue::net_request_priority()
+ const {
+ return net_request_priority_;
+}
+
} // namespace scheduler
} // namespace blink
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 f3e08007def..2d60b0ccbf2 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
@@ -7,6 +7,7 @@
#include "base/task/sequence_manager/task_queue.h"
#include "base/task/sequence_manager/task_queue_impl.h"
+#include "net/base/request_priority.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
namespace base {
@@ -57,9 +58,11 @@ class PLATFORM_EXPORT MainThreadTaskQueue
// TODO(altimin): Move to the top when histogram is renumbered.
kDetached = 19,
+ kCleanup = 20,
+
// Used to group multiple types when calculating Expected Queueing Time.
- kOther = 20,
- kCount = 21
+ kOther = 21,
+ kCount = 22
};
// Returns name of the given queue type. Returned string has application
@@ -255,6 +258,14 @@ class PLATFORM_EXPORT MainThreadTaskQueue
FrameSchedulerImpl* GetFrameScheduler() const;
void DetachFromFrameScheduler();
+ scoped_refptr<base::SingleThreadTaskRunner> CreateTaskRunner(
+ TaskType task_type) {
+ return TaskQueue::CreateTaskRunner(static_cast<int>(task_type));
+ }
+
+ void SetNetRequestPriority(net::RequestPriority net_request_priority);
+ base::Optional<net::RequestPriority> net_request_priority() const;
+
protected:
void SetFrameSchedulerForTest(FrameSchedulerImpl* frame_scheduler);
@@ -280,6 +291,13 @@ class PLATFORM_EXPORT MainThreadTaskQueue
const QueueTraits queue_traits_;
const bool freeze_when_keep_active_;
+ // Warning: net_request_priority is not the same as the priority of the queue.
+ // It is the priority (at the loading stack level) of the resource associated
+ // to the queue, if one exists.
+ //
+ // Used to track UMA metrics for resource loading tasks split by net priority.
+ base::Optional<net::RequestPriority> net_request_priority_;
+
// Needed to notify renderer scheduler about completed tasks.
MainThreadSchedulerImpl* main_thread_scheduler_; // NOT OWNED
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc
index 0b74a9da022..47c4dc9d189 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc
@@ -10,6 +10,7 @@
#include "base/optional.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h"
@@ -288,9 +289,10 @@ void PageSchedulerImpl::RegisterFrameSchedulerImpl(
}
std::unique_ptr<blink::FrameScheduler> PageSchedulerImpl::CreateFrameScheduler(
+ FrameScheduler::Delegate* delegate,
blink::BlameContext* blame_context,
FrameScheduler::FrameType frame_type) {
- return FrameSchedulerImpl::Create(this, blame_context, frame_type);
+ return FrameSchedulerImpl::Create(this, delegate, blame_context, frame_type);
}
void PageSchedulerImpl::Unregister(FrameSchedulerImpl* frame_scheduler) {
@@ -577,24 +579,12 @@ MainThreadSchedulerImpl* PageSchedulerImpl::GetMainThreadScheduler() const {
return main_thread_scheduler_;
}
-ukm::UkmRecorder* PageSchedulerImpl::GetUkmRecorder() {
- if (!delegate_)
- return nullptr;
- return delegate_->GetUkmRecorder();
-}
-
-int64_t PageSchedulerImpl::GetUkmSourceId() {
- if (!delegate_)
- return 0;
- return delegate_->GetUkmSourceId();
-}
-
bool PageSchedulerImpl::IsBackgrounded() const {
return page_visibility_ == PageVisibilityState::kHidden && !IsAudioPlaying();
}
bool PageSchedulerImpl::ShouldFreezePage() const {
- if (!RuntimeEnabledFeatures::StopInBackgroundEnabled())
+ if (!base::FeatureList::IsEnabled(blink::features::kStopInBackground))
return false;
return IsBackgrounded();
}
@@ -688,6 +678,14 @@ PageSchedulerImpl::PageLifecycleStateTracker::
}
}
+FrameSchedulerImpl* PageSchedulerImpl::SelectFrameForUkmAttribution() {
+ for (FrameSchedulerImpl* frame_scheduler : frame_schedulers_) {
+ if (frame_scheduler->GetUkmRecorder())
+ return frame_scheduler;
+ }
+ return nullptr;
+}
+
// static
const char PageSchedulerImpl::kHistogramPageLifecycleStateTransition[] =
"PageScheduler.PageLifecycleStateTransition";
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h
index 1d4d6db82f3..175131defa3 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h
@@ -57,6 +57,7 @@ class PLATFORM_EXPORT PageSchedulerImpl : public PageScheduler {
void SetIsMainFrameLocal(bool is_local) override;
std::unique_ptr<FrameScheduler> CreateFrameScheduler(
+ FrameScheduler::Delegate* delegate,
BlameContext*,
FrameScheduler::FrameType) override;
base::TimeTicks EnableVirtualTime() override;
@@ -107,10 +108,15 @@ class PLATFORM_EXPORT PageSchedulerImpl : public PageScheduler {
// Return a number of child web frame schedulers for this PageScheduler.
size_t FrameCount() const;
- void AsValueInto(base::trace_event::TracedValue* state) const;
+ // Generally UKMs are asssociated with the main frame of a page, but the
+ // implementation allows to request a recorder from any local frame with
+ // the same result (e.g. for OOPIF support), therefore we need to select
+ // any frame here.
+ // Note that selecting main frame doesn't work for OOPIFs where the main
+ // frame it not a local one.
+ FrameSchedulerImpl* SelectFrameForUkmAttribution();
- ukm::UkmRecorder* GetUkmRecorder();
- int64_t GetUkmSourceId();
+ void AsValueInto(base::trace_event::TracedValue* state) const;
base::WeakPtr<PageSchedulerImpl> GetWeakPtr() {
return weak_factory_.GetWeakPtr();
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc
index e17810b31c4..cba019f89dc 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc
@@ -17,11 +17,13 @@
#include "base/task/sequence_manager/test/fake_task.h"
#include "base/task/sequence_manager/test/sequence_manager_for_test.h"
#include "base/test/metrics/histogram_tester.h"
+#include "base/test/scoped_feature_list.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/child/task_queue_with_task_type.h"
+#include "third_party/blink/public/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/frame_task_queue_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_visibility_state.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
@@ -48,7 +50,15 @@ using testing::UnorderedElementsAreArray;
class PageSchedulerImplTest : public testing::Test {
public:
- PageSchedulerImplTest() = default;
+ PageSchedulerImplTest() {
+ feature_list_.InitAndEnableFeature(blink::features::kStopInBackground);
+ }
+
+ PageSchedulerImplTest(std::vector<base::Feature> enabled_features,
+ std::vector<base::Feature> disabled_features) {
+ feature_list_.InitWithFeatures(enabled_features, disabled_features);
+ }
+
~PageSchedulerImplTest() override = default;
protected:
@@ -63,8 +73,9 @@ class PageSchedulerImplTest : public testing::Test {
nullptr, test_task_runner_, test_task_runner_->GetMockTickClock()),
base::nullopt));
page_scheduler_.reset(new PageSchedulerImpl(nullptr, scheduler_.get()));
- frame_scheduler_ = FrameSchedulerImpl::Create(
- page_scheduler_.get(), nullptr, FrameScheduler::FrameType::kSubframe);
+ frame_scheduler_ =
+ FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr, nullptr,
+ FrameScheduler::FrameType::kSubframe);
}
void TearDown() override {
@@ -82,7 +93,10 @@ class PageSchedulerImplTest : public testing::Test {
static scoped_refptr<TaskQueue> ThrottleableTaskQueueForScheduler(
FrameSchedulerImpl* scheduler) {
- return scheduler->ThrottleableTaskQueue();
+ auto* frame_task_queue_controller =
+ scheduler->FrameTaskQueueControllerForTest();
+ auto queue_traits = FrameSchedulerImpl::ThrottleableTaskQueueTraits();
+ return frame_task_queue_controller->NonLoadingTaskQueue(queue_traits);
}
base::TimeDelta delay_for_background_tab_freezing() const {
@@ -94,33 +108,39 @@ class PageSchedulerImplTest : public testing::Test {
}
scoped_refptr<base::SingleThreadTaskRunner> ThrottleableTaskRunner() {
- return TaskQueueWithTaskType::Create(ThrottleableTaskQueue(),
- TaskType::kInternalTest);
+ return ThrottleableTaskQueue()->CreateTaskRunner(TaskType::kInternalTest);
}
scoped_refptr<base::SingleThreadTaskRunner> LoadingTaskRunner() {
- return TaskQueueWithTaskType::Create(LoadingTaskQueue(),
- TaskType::kInternalTest);
+ return LoadingTaskQueue()->CreateTaskRunner(TaskType::kInternalTest);
}
- scoped_refptr<TaskQueue> ThrottleableTaskQueue() {
- return frame_scheduler_->ThrottleableTaskQueue();
+ scoped_refptr<MainThreadTaskQueue> NonLoadingTaskQueue(
+ MainThreadTaskQueue::QueueTraits queue_traits) {
+ return frame_scheduler_->FrameTaskQueueControllerForTest()
+ ->NonLoadingTaskQueue(queue_traits);
}
- scoped_refptr<TaskQueue> LoadingTaskQueue() {
- return frame_scheduler_->LoadingTaskQueue();
+ scoped_refptr<MainThreadTaskQueue> ThrottleableTaskQueue() {
+ return NonLoadingTaskQueue(
+ FrameSchedulerImpl::ThrottleableTaskQueueTraits());
}
- scoped_refptr<TaskQueue> DeferrableTaskQueue() {
- return frame_scheduler_->DeferrableTaskQueue();
+ scoped_refptr<MainThreadTaskQueue> LoadingTaskQueue() {
+ return frame_scheduler_->FrameTaskQueueControllerForTest()
+ ->LoadingTaskQueue();
}
- scoped_refptr<TaskQueue> PausableTaskQueue() {
- return frame_scheduler_->PausableTaskQueue();
+ scoped_refptr<MainThreadTaskQueue> DeferrableTaskQueue() {
+ return NonLoadingTaskQueue(FrameSchedulerImpl::DeferrableTaskQueueTraits());
}
- scoped_refptr<TaskQueue> UnpausableTaskQueue() {
- return frame_scheduler_->UnpausableTaskQueue();
+ scoped_refptr<MainThreadTaskQueue> PausableTaskQueue() {
+ return NonLoadingTaskQueue(FrameSchedulerImpl::PausableTaskQueueTraits());
+ }
+
+ scoped_refptr<MainThreadTaskQueue> UnpausableTaskQueue() {
+ return NonLoadingTaskQueue(FrameSchedulerImpl::UnpausableTaskQueueTraits());
}
bool ShouldFreezePage() { return page_scheduler_->ShouldFreezePage(); }
@@ -129,8 +149,6 @@ class PageSchedulerImplTest : public testing::Test {
// set the page as visible or unfreezes it while still hidden (depending on
// the argument), and verifies that tasks can run.
void TestFreeze(bool make_page_visible) {
- ScopedStopNonTimersInBackgroundForTest stop_non_timers_enabler(true);
-
int counter = 0;
LoadingTaskQueue()->PostTask(
FROM_HERE,
@@ -195,24 +213,38 @@ class PageSchedulerImplTest : public testing::Test {
std::unique_ptr<MainThreadSchedulerImpl> scheduler_;
std::unique_ptr<PageSchedulerImpl> page_scheduler_;
std::unique_ptr<FrameSchedulerImpl> frame_scheduler_;
+
+ private:
+ base::test::ScopedFeatureList feature_list_;
+};
+
+class PageSchedulerImplStopNonTimersInBackgroundEnabledTest
+ : public PageSchedulerImplTest {
+ public:
+ PageSchedulerImplStopNonTimersInBackgroundEnabledTest()
+ : PageSchedulerImplTest({blink::features::kStopInBackground,
+ blink::features::kStopNonTimersInBackground},
+ {}) {}
+
+ ~PageSchedulerImplStopNonTimersInBackgroundEnabledTest() override = default;
};
TEST_F(PageSchedulerImplTest, TestDestructionOfFrameSchedulersBefore) {
std::unique_ptr<blink::FrameScheduler> frame1(
page_scheduler_->CreateFrameScheduler(
- nullptr, FrameScheduler::FrameType::kSubframe));
+ nullptr, nullptr, FrameScheduler::FrameType::kSubframe));
std::unique_ptr<blink::FrameScheduler> frame2(
page_scheduler_->CreateFrameScheduler(
- nullptr, FrameScheduler::FrameType::kSubframe));
+ nullptr, nullptr, FrameScheduler::FrameType::kSubframe));
}
TEST_F(PageSchedulerImplTest, TestDestructionOfFrameSchedulersAfter) {
std::unique_ptr<blink::FrameScheduler> frame1(
page_scheduler_->CreateFrameScheduler(
- nullptr, FrameScheduler::FrameType::kSubframe));
+ nullptr, nullptr, FrameScheduler::FrameType::kSubframe));
std::unique_ptr<blink::FrameScheduler> frame2(
page_scheduler_->CreateFrameScheduler(
- nullptr, FrameScheduler::FrameType::kSubframe));
+ nullptr, nullptr, FrameScheduler::FrameType::kSubframe));
page_scheduler_.reset();
}
@@ -298,7 +330,7 @@ TEST_F(PageSchedulerImplTest, RepeatingTimers_OneBackgroundOneForeground) {
std::unique_ptr<PageSchedulerImpl> page_scheduler2(
new PageSchedulerImpl(nullptr, scheduler_.get()));
std::unique_ptr<FrameSchedulerImpl> frame_scheduler2 =
- FrameSchedulerImpl::Create(page_scheduler2.get(), nullptr,
+ FrameSchedulerImpl::Create(page_scheduler2.get(), nullptr, nullptr,
FrameScheduler::FrameType::kSubframe);
page_scheduler_->SetPageVisible(true);
@@ -550,7 +582,7 @@ TEST_F(PageSchedulerImplTest, VirtualTimeSettings_NewFrameScheduler) {
page_scheduler_->EnableVirtualTime();
std::unique_ptr<FrameSchedulerImpl> frame_scheduler =
- FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr,
+ FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr, nullptr,
FrameScheduler::FrameType::kSubframe);
ThrottleableTaskQueueForScheduler(frame_scheduler.get())
@@ -580,7 +612,7 @@ base::OnceClosure MakeDeletionTask(T* obj) {
TEST_F(PageSchedulerImplTest, DeleteFrameSchedulers_InTask) {
for (int i = 0; i < 10; i++) {
FrameSchedulerImpl* frame_scheduler =
- FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr,
+ FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr, nullptr,
FrameScheduler::FrameType::kSubframe)
.release();
ThrottleableTaskQueueForScheduler(frame_scheduler)
@@ -600,7 +632,7 @@ TEST_F(PageSchedulerImplTest, DeleteThrottledQueue_InTask) {
page_scheduler_->SetPageVisible(false);
FrameSchedulerImpl* frame_scheduler =
- FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr,
+ FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr, nullptr,
FrameScheduler::FrameType::kSubframe)
.release();
scoped_refptr<TaskQueue> timer_task_queue =
@@ -653,7 +685,7 @@ TEST_F(PageSchedulerImplTest,
VirtualTimePolicy::kDeterministicLoading);
std::unique_ptr<FrameSchedulerImpl> frame_scheduler =
- FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr,
+ FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr, nullptr,
FrameScheduler::FrameType::kSubframe);
{
@@ -720,7 +752,7 @@ TEST_F(PageSchedulerImplTest,
base::TimeTicks time_second_task;
std::unique_ptr<FrameSchedulerImpl> frame_scheduler =
- FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr,
+ FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr, nullptr,
FrameScheduler::FrameType::kSubframe);
// Pauses and unpauses virtual time, thereby advancing virtual time by an
@@ -756,7 +788,7 @@ TEST_F(PageSchedulerImplTest,
VirtualTimePolicy::kDeterministicLoading);
std::unique_ptr<FrameSchedulerImpl> frame_scheduler =
- FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr,
+ FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr, nullptr,
FrameScheduler::FrameType::kSubframe);
WebScopedVirtualTimePauser virtual_time_pauser1 =
@@ -801,7 +833,7 @@ TEST_F(PageSchedulerImplTest, PauseTimersWhileVirtualTimeIsPaused) {
std::vector<int> run_order;
std::unique_ptr<FrameSchedulerImpl> frame_scheduler =
- FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr,
+ FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr, nullptr,
FrameScheduler::FrameType::kSubframe);
page_scheduler_->SetVirtualTimePolicy(VirtualTimePolicy::kPause);
page_scheduler_->EnableVirtualTime();
@@ -1087,8 +1119,9 @@ TEST_F(PageSchedulerImplTest, BackgroundTimerThrottling) {
EXPECT_FALSE(page_scheduler_->IsThrottled());
std::vector<base::TimeTicks> run_times;
- frame_scheduler_ = FrameSchedulerImpl::Create(
- page_scheduler_.get(), nullptr, FrameScheduler::FrameType::kSubframe);
+ frame_scheduler_ =
+ FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr, nullptr,
+ FrameScheduler::FrameType::kSubframe);
page_scheduler_->SetPageVisible(true);
EXPECT_FALSE(page_scheduler_->IsThrottled());
@@ -1153,10 +1186,10 @@ TEST_F(PageSchedulerImplTest, OpenWebSocketExemptsFromBudgetThrottling) {
std::vector<base::TimeTicks> run_times;
std::unique_ptr<FrameSchedulerImpl> frame_scheduler1 =
- FrameSchedulerImpl::Create(page_scheduler.get(), nullptr,
+ FrameSchedulerImpl::Create(page_scheduler.get(), nullptr, nullptr,
FrameScheduler::FrameType::kSubframe);
std::unique_ptr<FrameSchedulerImpl> frame_scheduler2 =
- FrameSchedulerImpl::Create(page_scheduler.get(), nullptr,
+ FrameSchedulerImpl::Create(page_scheduler.get(), nullptr, nullptr,
FrameScheduler::FrameType::kSubframe);
page_scheduler->SetPageVisible(false);
@@ -1252,13 +1285,15 @@ TEST_F(PageSchedulerImplTest, OpenWebSocketExemptsFromBudgetThrottling) {
// Verify that freezing a page prevents tasks in its task queues from running.
// Then, verify that making the page visible unfreezes it and allows tasks in
// its task queues to run.
-TEST_F(PageSchedulerImplTest, PageFreezeAndSetVisible) {
+TEST_F(PageSchedulerImplStopNonTimersInBackgroundEnabledTest,
+ PageFreezeAndSetVisible) {
TestFreeze(true);
}
// Same as before, but unfreeze the page explicitly instead of making it
// visible.
-TEST_F(PageSchedulerImplTest, PageFreezeAndUnfreeze) {
+TEST_F(PageSchedulerImplStopNonTimersInBackgroundEnabledTest,
+ PageFreezeAndUnfreeze) {
TestFreeze(false);
}
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/resource_loading_task_runner_handle_impl.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/resource_loading_task_runner_handle_impl.cc
index 685fd6a8acd..6e0ef04baed 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/resource_loading_task_runner_handle_impl.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/resource_loading_task_runner_handle_impl.cc
@@ -5,7 +5,6 @@
#include "base/memory/ptr_util.h"
#include "base/task/sequence_manager/task_queue.h"
#include "third_party/blink/public/platform/task_type.h"
-#include "third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h"
namespace blink {
@@ -24,8 +23,7 @@ ResourceLoadingTaskRunnerHandleImpl::WrapTaskRunner(
ResourceLoadingTaskRunnerHandleImpl::ResourceLoadingTaskRunnerHandleImpl(
scoped_refptr<MainThreadTaskQueue> task_queue)
: task_queue_(std::move(task_queue)),
- task_runner_(TaskQueueWithTaskType::Create(
- task_queue_,
+ task_runner_(task_queue_->CreateTaskRunner(
TaskType::kNetworkingWithURLLoaderAnnotation)){};
ResourceLoadingTaskRunnerHandleImpl::~ResourceLoadingTaskRunnerHandleImpl() {
@@ -37,6 +35,7 @@ ResourceLoadingTaskRunnerHandleImpl::~ResourceLoadingTaskRunnerHandleImpl() {
void ResourceLoadingTaskRunnerHandleImpl::DidChangeRequestPriority(
net::RequestPriority priority) {
+ task_queue_->SetNetRequestPriority(priority);
FrameSchedulerImpl* frame_scheduler = task_queue_->GetFrameScheduler();
if (frame_scheduler) {
frame_scheduler->DidChangeResourceLoadingPriority(task_queue_, priority);
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
new file mode 100644
index 00000000000..208d6c7f6cf
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.cc
@@ -0,0 +1,125 @@
+// 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/main_thread/task_type_names.h"
+
+#include "base/logging.h"
+
+namespace blink {
+namespace scheduler {
+
+// static
+const char* TaskTypeNames::TaskTypeToString(TaskType task_type) {
+ // These names are used in finch trials and should not be changed.
+ switch (task_type) {
+ case TaskType::kDeprecatedNone:
+ return "None";
+ case TaskType::kDOMManipulation:
+ return "DOMManipulation";
+ case TaskType::kUserInteraction:
+ return "UserInteraction";
+ case TaskType::kNetworking:
+ return "Networking";
+ case TaskType::kNetworkingWithURLLoaderAnnotation:
+ return "NetworkingWithURLLoaderAnnotation";
+ case TaskType::kNetworkingControl:
+ return "NetworkingControl";
+ case TaskType::kHistoryTraversal:
+ return "HistoryTraversal";
+ case TaskType::kEmbed:
+ return "Embed";
+ case TaskType::kMediaElementEvent:
+ return "MediaElementEvent";
+ case TaskType::kCanvasBlobSerialization:
+ return "CanvasBlobSerialization";
+ case TaskType::kMicrotask:
+ return "Microtask";
+ case TaskType::kJavascriptTimer:
+ return "JavascriptTimer";
+ case TaskType::kRemoteEvent:
+ return "RemoteEvent";
+ case TaskType::kWebSocket:
+ return "WebSocket";
+ case TaskType::kPostedMessage:
+ return "PostedMessage";
+ case TaskType::kUnshippedPortMessage:
+ return "UnshippedPortMessage";
+ case TaskType::kFileReading:
+ return "FileReading";
+ case TaskType::kDatabaseAccess:
+ return "DatabaseAccess";
+ case TaskType::kPresentation:
+ return "Presentation";
+ case TaskType::kSensor:
+ return "Sensor";
+ case TaskType::kPerformanceTimeline:
+ return "PerformanceTimeline";
+ case TaskType::kWebGL:
+ return "WebGL";
+ case TaskType::kIdleTask:
+ return "IdleTask";
+ case TaskType::kMiscPlatformAPI:
+ return "MiscPlatformAPI";
+ case TaskType::kInternalDefault:
+ return "InternalDefault";
+ case TaskType::kInternalLoading:
+ return "InternalLoading";
+ case TaskType::kInternalTest:
+ return "InternalTest";
+ case TaskType::kInternalWebCrypto:
+ return "InternalWebCrypto";
+ case TaskType::kInternalIndexedDB:
+ return "InternalIndexedDB";
+ case TaskType::kInternalMedia:
+ return "InternalMedia";
+ case TaskType::kInternalMediaRealTime:
+ return "InternalMediaRealTime";
+ case TaskType::kInternalIPC:
+ return "InternalIPC";
+ case TaskType::kInternalUserInteraction:
+ return "InternalUserInteraction";
+ case TaskType::kInternalInspector:
+ return "InternalInspector";
+ case TaskType::kInternalWorker:
+ return "InternalWorker";
+ case TaskType::kMainThreadTaskQueueV8:
+ return "MainThreadTaskQueueV8";
+ case TaskType::kMainThreadTaskQueueCompositor:
+ return "MainThreadTaskQueueCompositor";
+ case TaskType::kMainThreadTaskQueueDefault:
+ return "MainThreadTaskQueueDefault";
+ case TaskType::kMainThreadTaskQueueInput:
+ return "MainThreadTaskQueueInput";
+ case TaskType::kMainThreadTaskQueueIdle:
+ return "MainThreadTaskQueueIdle";
+ case TaskType::kMainThreadTaskQueueIPC:
+ return "MainThreadTaskQueueIPC";
+ case TaskType::kMainThreadTaskQueueControl:
+ return "MainThreadTaskQueueControl";
+ case TaskType::kMainThreadTaskQueueCleanup:
+ return "MainThreadTaskQueueCleanup";
+ case TaskType::kInternalIntersectionObserver:
+ return "InternalIntersectionObserver";
+ case TaskType::kCompositorThreadTaskQueueDefault:
+ return "CompositorThreadTaskQueueDefault";
+ case TaskType::kCompositorThreadTaskQueueInput:
+ return "CompositorThreadTaskQueueInput";
+ case TaskType::kWorkerThreadTaskQueueDefault:
+ return "WorkerThreadTaskQueueDefault";
+ case TaskType::kWorkerThreadTaskQueueV8:
+ return "WorkerThreadTaskQueueV8";
+ case TaskType::kWorkerThreadTaskQueueCompositor:
+ return "WorkerThreadTaskQueueCompositor";
+ case TaskType::kWorkerAnimation:
+ return "WorkerAnimation";
+ case TaskType::kCount:
+ return "Count";
+ }
+ // FrameSchedulerImpl should not call this for invalid TaskTypes.
+ NOTREACHED();
+ return "";
+}
+
+} // namespace scheduler
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.h
new file mode 100644
index 00000000000..81270ec0086
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.h
@@ -0,0 +1,27 @@
+// 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_SCHEDULER_MAIN_THREAD_TASK_TYPE_NAMES_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_TASK_TYPE_NAMES_H_
+
+#include "third_party/blink/public/platform/task_type.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"
+
+namespace blink {
+namespace scheduler {
+
+class TaskTypeNames {
+ public:
+ static const char* TaskTypeToString(TaskType task_type);
+
+ private:
+ TaskTypeNames();
+};
+
+} // namespace scheduler
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_TASK_TYPE_NAMES_H_
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/public/background_scheduler.h b/chromium/third_party/blink/renderer/platform/scheduler/public/background_scheduler.h
index ef80a0a828e..8139d02ab36 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/public/background_scheduler.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/public/background_scheduler.h
@@ -6,6 +6,8 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_PUBLIC_BACKGROUND_SCHEDULER_H_
#include "base/location.h"
+#include "base/sequenced_task_runner.h"
+#include "base/task/task_traits.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
@@ -13,14 +15,22 @@ namespace blink {
namespace BackgroundScheduler {
-// This is a thin wrapper around base::TaskScheduler to accomodate
-// Blink's CrossThreadClosure, which only allows background tasks.
+// These are a thin wrapper around base::TaskScheduler to accomodate
+// Blink's CrossThreadClosure, which only allows background tasks
+// (i.e. tasks which are run off the main thread).
//
// Non-background tasks should be posted using another scheduler, e.g.
// FrameShceduler.
PLATFORM_EXPORT void PostOnBackgroundThread(const base::Location&,
CrossThreadClosure);
+PLATFORM_EXPORT void PostOnBackgroundThreadWithTraits(const base::Location&,
+ const base::TaskTraits&,
+ CrossThreadClosure);
+
+// TODO(altimin): Expose CreateBackgroundTaskRunnerWithTraits when the
+// need arises.
+
} // namespace BackgroundScheduler
} // namespace blink
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 d82659b7ddf..a644fbe59bf 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
@@ -9,6 +9,7 @@
#include "base/memory/scoped_refptr.h"
#include "base/single_thread_task_runner.h"
+#include "services/metrics/public/cpp/ukm_source_id.h"
#include "third_party/blink/public/mojom/loader/pause_subresource_loading_handle.mojom-blink.h"
#include "third_party/blink/public/platform/scheduler/web_resource_loading_task_runner_handle.h"
#include "third_party/blink/public/platform/task_type.h"
@@ -17,12 +18,24 @@
#include "third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+namespace ukm {
+class UkmRecorder;
+}
+
namespace blink {
class PageScheduler;
class FrameScheduler : public FrameOrWorkerScheduler {
public:
+ class PLATFORM_EXPORT Delegate {
+ public:
+ virtual ~Delegate() = default;
+
+ virtual ukm::UkmRecorder* GetUkmRecorder() = 0;
+ virtual ukm::SourceId GetUkmSourceId() = 0;
+ };
+
~FrameScheduler() override = default;
// Represents the type of frame: main (top-level) vs not.
@@ -135,6 +148,9 @@ class FrameScheduler : public FrameOrWorkerScheduler {
// of the page.
virtual bool IsExemptFromBudgetBasedThrottling() const = 0;
+ // Returns UKM source id for recording metrics associated with this frame.
+ virtual ukm::SourceId GetUkmSourceId() = 0;
+
FrameScheduler* ToFrameScheduler() override { return this; }
// Returns a handle that prevents resource loading as long as the handle
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/public/page_scheduler.h b/chromium/third_party/blink/renderer/platform/scheduler/public/page_scheduler.h
index 603595002d2..e32f97cf601 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/public/page_scheduler.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/public/page_scheduler.h
@@ -13,10 +13,6 @@
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-namespace ukm {
-class UkmRecorder;
-}
-
namespace blink {
class PLATFORM_EXPORT PageScheduler {
@@ -30,8 +26,6 @@ class PLATFORM_EXPORT PageScheduler {
// compositor.
virtual bool RequestBeginMainFrameNotExpected(bool new_state) = 0;
virtual void SetLifecycleState(PageLifecycleState) = 0;
- virtual ukm::UkmRecorder* GetUkmRecorder() = 0;
- virtual int64_t GetUkmSourceId() = 0;
};
virtual ~PageScheduler() = default;
@@ -52,6 +46,7 @@ class PLATFORM_EXPORT PageScheduler {
// it. All tasks executed by the frame scheduler will be attributed to
// |blame_context|.
virtual std::unique_ptr<FrameScheduler> CreateFrameScheduler(
+ FrameScheduler::Delegate* delegate,
BlameContext*,
FrameScheduler::FrameType) = 0;
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 8381a3615cc..4e014f9cfeb 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
@@ -69,7 +69,7 @@ class PLATFORM_EXPORT ThreadScheduler {
WebThread::IdleTask) = 0;
virtual void AddRAILModeObserver(
- scheduler::WebThreadScheduler::RAILModeObserver* observer) = 0;
+ scheduler::WebRAILModeObserver* observer) = 0;
// Returns a task runner for kV8 tasks. Can be called from any thread.
virtual scoped_refptr<base::SingleThreadTaskRunner> V8TaskRunner() = 0;
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/public/worker_scheduler.h b/chromium/third_party/blink/renderer/platform/scheduler/public/worker_scheduler.h
index 63873ee6db3..528963cecfb 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/public/worker_scheduler.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/public/worker_scheduler.h
@@ -7,15 +7,14 @@
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
-#include "base/task/sequence_manager/task_queue.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
namespace blink {
-
namespace scheduler {
+class NonMainThreadTaskQueue;
class WorkerSchedulerProxy;
class WorkerThreadScheduler;
@@ -49,16 +48,16 @@ class PLATFORM_EXPORT WorkerScheduler : public FrameOrWorkerScheduler {
SchedulingLifecycleState CalculateLifecycleState(ObserverType) const override;
protected:
- scoped_refptr<base::sequence_manager::TaskQueue> ThrottleableTaskQueue();
- scoped_refptr<base::sequence_manager::TaskQueue> UnthrottleableTaskQueue();
+ scoped_refptr<NonMainThreadTaskQueue> ThrottleableTaskQueue();
+ scoped_refptr<NonMainThreadTaskQueue> UnthrottleableTaskQueue();
private:
void SetUpThrottling();
base::WeakPtr<WorkerScheduler> GetWeakPtr();
- scoped_refptr<base::sequence_manager::TaskQueue> throttleable_task_queue_;
- scoped_refptr<base::sequence_manager::TaskQueue> unthrottleable_task_queue_;
+ scoped_refptr<NonMainThreadTaskQueue> throttleable_task_queue_;
+ scoped_refptr<NonMainThreadTaskQueue> unthrottleable_task_queue_;
SchedulingLifecycleState lifecycle_state_ =
SchedulingLifecycleState::kNotThrottled;
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler_unittest.cc
index 3e4cc6ddb78..a0a944e3926 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler_unittest.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler_unittest.cc
@@ -46,7 +46,6 @@ class WebThreadImplForRendererSchedulerTest : public testing::Test {
base::sequence_manager::SequenceManagerForTest::Create(
&message_loop_, message_loop_.task_runner(), &clock_),
base::nullopt));
- default_task_runner_ = scheduler_->DefaultTaskRunner();
thread_ = scheduler_->CreateMainThread();
}
@@ -63,7 +62,6 @@ class WebThreadImplForRendererSchedulerTest : public testing::Test {
base::MessageLoop message_loop_;
base::SimpleTestTickClock clock_;
std::unique_ptr<MainThreadSchedulerImpl> scheduler_;
- scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_;
std::unique_ptr<blink::WebThread> thread_;
DISALLOW_COPY_AND_ASSIGN(WebThreadImplForRendererSchedulerTest);
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/util/task_duration_metric_reporter.h b/chromium/third_party/blink/renderer/platform/scheduler/util/task_duration_metric_reporter.h
deleted file mode 100644
index de4dc8a3738..00000000000
--- a/chromium/third_party/blink/renderer/platform/scheduler/util/task_duration_metric_reporter.h
+++ /dev/null
@@ -1,61 +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_SCHEDULER_UTIL_TASK_DURATION_METRIC_REPORTER_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_UTIL_TASK_DURATION_METRIC_REPORTER_H_
-
-#include "base/macros.h"
-#include "base/metrics/histogram.h"
-#include "base/time/time.h"
-
-namespace base {
-class HistogramBase;
-}
-
-namespace blink {
-namespace scheduler {
-
-// A helper class to report total task runtime split by the different types of
-// |TypeClass|. Only full seconds are reported. Note that partial seconds are
-// rounded up/down, so that on average the correct value is reported when many
-// reports are added.
-//
-//|TaskClass| is an enum which should have COUNT field.
-template <class TaskClass>
-class TaskDurationMetricReporter {
- public:
- // Note that 1000*1000 is used to get microseconds precision.
- explicit TaskDurationMetricReporter(const char* metric_name)
- : value_per_type_histogram_(new base::ScaledLinearHistogram(
- metric_name,
- 1,
- static_cast<int>(TaskClass::kCount),
- static_cast<int>(TaskClass::kCount) + 1,
- 1000 * 1000,
- base::HistogramBase::kUmaTargetedHistogramFlag)){};
-
- void RecordTask(TaskClass task_class, base::TimeDelta duration) {
- DCHECK_LT(static_cast<int>(task_class),
- static_cast<int>(TaskClass::kCount));
-
- // To get mircoseconds precision, duration is converted to microseconds
- // since |value_per_type_histogram_| is constructed with a scale of
- // 1000*1000.
- if (!duration.is_zero()) {
- value_per_type_histogram_->AddScaledCount(
- static_cast<int>(task_class),
- base::saturated_cast<int>(duration.InMicroseconds()));
- }
- }
-
- private:
- std::unique_ptr<base::ScaledLinearHistogram> value_per_type_histogram_;
-
- DISALLOW_COPY_AND_ASSIGN(TaskDurationMetricReporter);
-};
-
-} // namespace scheduler
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_UTIL_TASK_DURATION_METRIC_REPORTER_H_
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/utility/webthread_impl_for_utility_thread.cc b/chromium/third_party/blink/renderer/platform/scheduler/utility/webthread_impl_for_utility_thread.cc
deleted file mode 100644
index c37f106f886..00000000000
--- a/chromium/third_party/blink/renderer/platform/scheduler/utility/webthread_impl_for_utility_thread.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/platform/scheduler/utility/webthread_impl_for_utility_thread.h"
-
-#include "base/threading/thread_task_runner_handle.h"
-
-namespace blink {
-namespace scheduler {
-
-WebThreadImplForUtilityThread::WebThreadImplForUtilityThread()
- : task_runner_(base::ThreadTaskRunnerHandle::Get()),
- thread_id_(base::PlatformThread::CurrentId()) {}
-
-WebThreadImplForUtilityThread::~WebThreadImplForUtilityThread() = default;
-
-blink::ThreadScheduler* WebThreadImplForUtilityThread::Scheduler() const {
- NOTIMPLEMENTED();
- return nullptr;
-}
-
-blink::PlatformThreadId WebThreadImplForUtilityThread::ThreadId() const {
- return thread_id_;
-}
-
-scoped_refptr<base::SingleThreadTaskRunner>
-WebThreadImplForUtilityThread::GetTaskRunner() const {
- return task_runner_;
-}
-
-void WebThreadImplForUtilityThread::Init() {}
-
-} // namespace scheduler
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/utility/webthread_impl_for_utility_thread.h b/chromium/third_party/blink/renderer/platform/scheduler/utility/webthread_impl_for_utility_thread.h
deleted file mode 100644
index e3137f013ba..00000000000
--- a/chromium/third_party/blink/renderer/platform/scheduler/utility/webthread_impl_for_utility_thread.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_UTILITY_WEBTHREAD_IMPL_FOR_UTILITY_THREAD_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_UTILITY_WEBTHREAD_IMPL_FOR_UTILITY_THREAD_H_
-
-#include "base/macros.h"
-#include "base/memory/scoped_refptr.h"
-#include "base/single_thread_task_runner.h"
-#include "third_party/blink/public/platform/scheduler/child/webthread_base.h"
-#include "third_party/blink/renderer/platform/platform_export.h"
-
-namespace blink {
-namespace scheduler {
-
-class PLATFORM_EXPORT WebThreadImplForUtilityThread
- : public scheduler::WebThreadBase {
- public:
- WebThreadImplForUtilityThread();
- ~WebThreadImplForUtilityThread() override;
-
- // WebThread implementation.
- ThreadScheduler* Scheduler() const override;
- PlatformThreadId ThreadId() const override;
- scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() const override;
-
- // WebThreadBase implementation.
- void Init() override;
-
- private:
- scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
- PlatformThreadId thread_id_;
-
- DISALLOW_COPY_AND_ASSIGN(WebThreadImplForUtilityThread);
-};
-
-} // namespace scheduler
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_UTILITY_WEBTHREAD_IMPL_FOR_UTILITY_THREAD_H_
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 9063c89ed00..12da463a4e4 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
@@ -14,7 +14,6 @@
#include "base/threading/thread_task_runner_handle.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/platform/scheduler/child/features.h"
-#include "third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.h"
#include "third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h"
namespace blink {
@@ -33,10 +32,8 @@ WebThreadScheduler* WebThreadScheduler::CompositorThreadScheduler() {
CompositorThreadScheduler::CompositorThreadScheduler(
std::unique_ptr<base::sequence_manager::SequenceManager> sequence_manager)
- : NonMainThreadSchedulerImpl(std::make_unique<NonMainThreadSchedulerHelper>(
- std::move(sequence_manager),
- this,
- TaskType::kCompositorThreadTaskQueueDefault)),
+ : NonMainThreadSchedulerImpl(std::move(sequence_manager),
+ TaskType::kCompositorThreadTaskQueueDefault),
input_task_queue_(
base::FeatureList::IsEnabled(kHighPriorityInputOnCompositorThread)
? helper()->NewTaskQueue(
@@ -44,8 +41,7 @@ CompositorThreadScheduler::CompositorThreadScheduler(
.SetShouldMonitorQuiescence(true))
: nullptr),
input_task_runner_(input_task_queue_
- ? TaskQueueWithTaskType::Create(
- input_task_queue_,
+ ? input_task_queue_->CreateTaskRunner(
TaskType::kCompositorThreadTaskQueueInput)
: nullptr),
compositor_metrics_helper_(helper()->HasCPUTimingForEachTask()) {
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 08f0dcec537..739f8c01965 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
@@ -8,10 +8,10 @@
#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/single_thread_task_runner.h"
+#include "components/scheduling_metrics/task_duration_metric_reporter.h"
#include "third_party/blink/public/platform/scheduler/single_thread_idle_task_runner.h"
#include "third_party/blink/public/platform/web_thread_type.h"
#include "third_party/blink/renderer/platform/platform_export.h"
-#include "third_party/blink/renderer/platform/scheduler/util/task_duration_metric_reporter.h"
#include "third_party/blink/renderer/platform/scheduler/worker/compositor_metrics_helper.h"
#include "third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_impl.h"
@@ -46,7 +46,7 @@ class PLATFORM_EXPORT CompositorThreadScheduler
void AddTaskObserver(base::MessageLoop::TaskObserver* task_observer) override;
void RemoveTaskObserver(
base::MessageLoop::TaskObserver* task_observer) override;
- void AddRAILModeObserver(RAILModeObserver*) override {}
+ void AddRAILModeObserver(WebRAILModeObserver*) override {}
void Shutdown() override;
// SingleThreadIdleTaskRunner::Delegate:
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_helper.cc b/chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_helper.cc
index a63fae8f06e..85b34bde904 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_helper.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_helper.cc
@@ -5,7 +5,6 @@
#include "third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_helper.h"
#include "third_party/blink/public/platform/task_type.h"
-#include "third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.h"
#include "third_party/blink/renderer/platform/scheduler/worker/non_main_thread_task_queue.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_impl.cc b/chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_impl.cc
index ccfd7cbc73d..3b795781539 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_impl.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_impl.cc
@@ -7,15 +7,15 @@
#include <utility>
#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.h"
#include "third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h"
namespace blink {
namespace scheduler {
NonMainThreadSchedulerImpl::NonMainThreadSchedulerImpl(
- std::unique_ptr<NonMainThreadSchedulerHelper> helper)
- : helper_(std::move(helper)) {}
+ std::unique_ptr<base::sequence_manager::SequenceManager> manager,
+ TaskType default_task_type)
+ : helper_(std::move(manager), this, default_task_type) {}
NonMainThreadSchedulerImpl::~NonMainThreadSchedulerImpl() = default;
@@ -33,11 +33,11 @@ void NonMainThreadSchedulerImpl::Init() {
}
scoped_refptr<NonMainThreadTaskQueue>
-NonMainThreadSchedulerImpl::CreateTaskRunner(const char* name) {
- helper_->CheckOnValidThread();
- return helper_->NewTaskQueue(base::sequence_manager::TaskQueue::Spec(name)
- .SetShouldMonitorQuiescence(true)
- .SetTimeDomain(nullptr));
+NonMainThreadSchedulerImpl::CreateTaskQueue(const char* name) {
+ helper_.CheckOnValidThread();
+ return helper_.NewTaskQueue(base::sequence_manager::TaskQueue::Spec(name)
+ .SetShouldMonitorQuiescence(true)
+ .SetTimeDomain(nullptr));
}
void NonMainThreadSchedulerImpl::RunIdleTask(blink::WebThread::IdleTask task,
@@ -79,26 +79,30 @@ NonMainThreadSchedulerImpl::MonotonicallyIncreasingVirtualTime() {
scoped_refptr<base::SingleThreadTaskRunner>
NonMainThreadSchedulerImpl::ControlTaskRunner() {
- return helper_->ControlNonMainThreadTaskQueue();
+ return helper_.ControlNonMainThreadTaskQueue();
}
void NonMainThreadSchedulerImpl::RegisterTimeDomain(
base::sequence_manager::TimeDomain* time_domain) {
- return helper_->RegisterTimeDomain(time_domain);
+ return helper_.RegisterTimeDomain(time_domain);
}
void NonMainThreadSchedulerImpl::UnregisterTimeDomain(
base::sequence_manager::TimeDomain* time_domain) {
- return helper_->UnregisterTimeDomain(time_domain);
+ return helper_.UnregisterTimeDomain(time_domain);
}
base::sequence_manager::TimeDomain*
NonMainThreadSchedulerImpl::GetActiveTimeDomain() {
- return helper_->real_time_domain();
+ return helper_.real_time_domain();
}
const base::TickClock* NonMainThreadSchedulerImpl::GetTickClock() {
- return helper_->GetClock();
+ return helper_.GetClock();
+}
+
+SchedulerHelper* NonMainThreadSchedulerImpl::GetHelper() {
+ return &helper_;
}
} // namespace scheduler
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_impl.h b/chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_impl.h
index f6b0dc6e1cc..019dae1fcea 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_impl.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_impl.h
@@ -83,23 +83,26 @@ class PLATFORM_EXPORT NonMainThreadSchedulerImpl : public ThreadSchedulerImpl {
//
// virtual void Shutdown();
- scoped_refptr<NonMainThreadTaskQueue> CreateTaskRunner(const char* name);
+ scoped_refptr<NonMainThreadTaskQueue> CreateTaskQueue(const char* name);
protected:
static void RunIdleTask(WebThread::IdleTask task, base::TimeTicks deadline);
explicit NonMainThreadSchedulerImpl(
- std::unique_ptr<NonMainThreadSchedulerHelper> helper);
+ std::unique_ptr<base::sequence_manager::SequenceManager> sequence_manager,
+ TaskType default_task_type);
friend class WorkerScheduler;
// Called during Init() for delayed initialization for subclasses.
virtual void InitImpl() = 0;
- NonMainThreadSchedulerHelper* helper() { return helper_.get(); }
+ NonMainThreadSchedulerHelper* helper() { return &helper_; }
private:
- std::unique_ptr<NonMainThreadSchedulerHelper> helper_;
+ SchedulerHelper* GetHelper() override;
+
+ NonMainThreadSchedulerHelper helper_;
DISALLOW_COPY_AND_ASSIGN(NonMainThreadSchedulerImpl);
};
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_task_queue.h b/chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_task_queue.h
index ac48631136f..7667c5434f2 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_task_queue.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_task_queue.h
@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_WORKER_NON_MAIN_THREAD_TASK_QUEUE_H_
#include "base/task/sequence_manager/task_queue_impl.h"
+#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/platform/platform_export.h"
namespace blink {
@@ -27,6 +28,11 @@ class PLATFORM_EXPORT NonMainThreadTaskQueue
const base::sequence_manager::TaskQueue::Task& task,
const base::sequence_manager::TaskQueue::TaskTiming& task_timing);
+ scoped_refptr<base::SingleThreadTaskRunner> CreateTaskRunner(
+ TaskType task_type) {
+ return TaskQueue::CreateTaskRunner(static_cast<int>(task_type));
+ }
+
private:
// Not owned.
NonMainThreadSchedulerImpl* non_main_thread_scheduler_;
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_metrics_helper.h b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_metrics_helper.h
index b4dd2cadaa1..9b1fb01858b 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_metrics_helper.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_metrics_helper.h
@@ -28,13 +28,13 @@ class PLATFORM_EXPORT WorkerMetricsHelper : public MetricsHelper {
void SetParentFrameType(FrameOriginType frame_type);
private:
- TaskDurationMetricReporter<TaskType>
+ scheduling_metrics::TaskDurationMetricReporter<TaskType>
dedicated_worker_per_task_type_duration_reporter_;
- TaskDurationMetricReporter<TaskType>
+ scheduling_metrics::TaskDurationMetricReporter<TaskType>
dedicated_worker_per_task_type_cpu_duration_reporter_;
- TaskDurationMetricReporter<FrameOriginType>
+ scheduling_metrics::TaskDurationMetricReporter<FrameOriginType>
dedicated_worker_per_parent_frame_status_duration_reporter_;
- TaskDurationMetricReporter<FrameOriginType>
+ scheduling_metrics::TaskDurationMetricReporter<FrameOriginType>
background_dedicated_worker_per_parent_frame_status_duration_reporter_;
base::Optional<FrameOriginType> parent_frame_type_;
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 61bb507f5d2..6ff3d3b956b 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
@@ -4,7 +4,6 @@
#include "third_party/blink/renderer/platform/scheduler/public/worker_scheduler.h"
-#include "third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.h"
#include "third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h"
#include "third_party/blink/renderer/platform/scheduler/common/throttling/wake_up_budget_pool.h"
#include "third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy.h"
@@ -16,9 +15,9 @@ namespace scheduler {
WorkerScheduler::WorkerScheduler(WorkerThreadScheduler* worker_thread_scheduler,
WorkerSchedulerProxy* proxy)
: throttleable_task_queue_(
- worker_thread_scheduler->CreateTaskRunner("worker_throttleable_tq")),
- unthrottleable_task_queue_(worker_thread_scheduler->CreateTaskRunner(
- "worker_unthrottleable_tq")),
+ worker_thread_scheduler->CreateTaskQueue("worker_throttleable_tq")),
+ unthrottleable_task_queue_(
+ worker_thread_scheduler->CreateTaskQueue("worker_unthrottleable_tq")),
thread_scheduler_(worker_thread_scheduler),
weak_factory_(this) {
thread_scheduler_->RegisterWorkerScheduler(this);
@@ -93,7 +92,7 @@ scoped_refptr<base::SingleThreadTaskRunner> WorkerScheduler::GetTaskRunner(
case TaskType::kJavascriptTimer:
case TaskType::kPostedMessage:
case TaskType::kWorkerAnimation:
- return TaskQueueWithTaskType::Create(throttleable_task_queue_, type);
+ return throttleable_task_queue_->CreateTaskRunner(type);
case TaskType::kDeprecatedNone:
case TaskType::kDOMManipulation:
case TaskType::kUserInteraction:
@@ -132,7 +131,7 @@ scoped_refptr<base::SingleThreadTaskRunner> WorkerScheduler::GetTaskRunner(
// TODO(nhiroki): Identify which tasks can be throttled / suspendable and
// move them into other task runners. See also comments in
// Get(LocalFrame). (https://crbug.com/670534)
- return TaskQueueWithTaskType::Create(unthrottleable_task_queue_, type);
+ return unthrottleable_task_queue_->CreateTaskRunner(type);
case TaskType::kMainThreadTaskQueueV8:
case TaskType::kMainThreadTaskQueueCompositor:
case TaskType::kMainThreadTaskQueueDefault:
@@ -140,6 +139,7 @@ scoped_refptr<base::SingleThreadTaskRunner> WorkerScheduler::GetTaskRunner(
case TaskType::kMainThreadTaskQueueIdle:
case TaskType::kMainThreadTaskQueueIPC:
case TaskType::kMainThreadTaskQueueControl:
+ case TaskType::kMainThreadTaskQueueCleanup:
case TaskType::kCompositorThreadTaskQueueDefault:
case TaskType::kCompositorThreadTaskQueueInput:
case TaskType::kWorkerThreadTaskQueueDefault:
@@ -171,13 +171,12 @@ void WorkerScheduler::OnLifecycleStateChanged(
NotifyLifecycleObservers();
}
-scoped_refptr<base::sequence_manager::TaskQueue>
+scoped_refptr<NonMainThreadTaskQueue>
WorkerScheduler::UnthrottleableTaskQueue() {
return unthrottleable_task_queue_.get();
}
-scoped_refptr<base::sequence_manager::TaskQueue>
-WorkerScheduler::ThrottleableTaskQueue() {
+scoped_refptr<NonMainThreadTaskQueue> WorkerScheduler::ThrottleableTaskQueue() {
return throttleable_task_queue_.get();
}
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy.cc b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy.cc
index 67d6279836d..9400efc6a03 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy.cc
@@ -4,6 +4,8 @@
#include "third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy.h"
+#include "services/metrics/public/cpp/mojo_ukm_recorder.h"
+#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h"
#include "third_party/blink/renderer/platform/scheduler/public/worker_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h"
@@ -17,6 +19,12 @@ WorkerSchedulerProxy::WorkerSchedulerProxy(FrameOrWorkerScheduler* scheduler) {
FrameOrWorkerScheduler::ObserverType::kWorkerScheduler, this);
if (FrameScheduler* frame_scheduler = scheduler->ToFrameScheduler()) {
parent_frame_type_ = GetFrameOriginType(frame_scheduler);
+ initial_frame_status_ = GetFrameStatus(frame_scheduler);
+ ukm_source_id_ = frame_scheduler->GetUkmSourceId();
+ if (ukm_source_id_ != ukm::kInvalidSourceId) {
+ ukm_recorder_ =
+ ukm::MojoUkmRecorder::Create(Platform::Current()->GetConnector());
+ }
}
}
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy.h b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy.h
index e01b24f5a15..5699b21830d 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy.h
@@ -11,9 +11,12 @@
#include "base/optional.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_checker.h"
+#include "services/metrics/public/cpp/ukm_recorder.h"
+#include "services/metrics/public/cpp/ukm_source_id.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_origin_type.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h"
+#include "third_party/blink/renderer/platform/scheduler/renderer/frame_status.h"
#include "third_party/blink/renderer/platform/wtf/wtf.h"
namespace blink {
@@ -52,6 +55,28 @@ class PLATFORM_EXPORT WorkerSchedulerProxy
return parent_frame_type_;
}
+ // Accessed only during init.
+ ukm::SourceId ukm_source_id() const {
+ DCHECK(!initialized_);
+ return ukm_source_id_;
+ }
+
+ // Accessed only during init.
+ std::unique_ptr<ukm::UkmRecorder> TakeUkmRecorder() {
+ DCHECK(!initialized_);
+#if DCHECK_IS_ON()
+ DCHECK(!ukm_recorder_taken_);
+ ukm_recorder_taken_ = true;
+#endif
+ return std::move(ukm_recorder_);
+ }
+
+ // Accessed only during init.
+ FrameStatus initial_frame_status() const {
+ DCHECK(!initialized_);
+ return initial_frame_status_;
+ }
+
private:
// Can be accessed only from the worker thread.
base::WeakPtr<WorkerScheduler> worker_scheduler_;
@@ -66,8 +91,14 @@ class PLATFORM_EXPORT WorkerSchedulerProxy
throttling_observer_handle_;
bool initialized_ = false;
-
base::Optional<FrameOriginType> parent_frame_type_;
+ FrameStatus initial_frame_status_ = FrameStatus::kNone;
+ ukm::SourceId ukm_source_id_ = ukm::kInvalidSourceId;
+ std::unique_ptr<ukm::UkmRecorder> ukm_recorder_;
+
+#if DCHECK_IS_ON()
+ bool ukm_recorder_taken_ = false;
+#endif
THREAD_CHECKER(parent_thread_checker_);
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy_unittest.cc
index 6d8438a9776..bbb555d925c 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy_unittest.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy_unittest.cc
@@ -124,6 +124,7 @@ class WorkerSchedulerProxyTest : public testing::Test {
frame_scheduler_(
FrameSchedulerImpl::Create(page_scheduler_.get(),
nullptr,
+ nullptr,
FrameScheduler::FrameType::kMainFrame)) {
// Null clock triggers some assertions.
task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(5));
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 cfbe0417331..259928fbc45 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
@@ -15,9 +15,10 @@
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/trace_event_argument.h"
+#include "services/metrics/public/cpp/ukm_builders.h"
#include "third_party/blink/renderer/platform/histogram.h"
#include "third_party/blink/renderer/platform/scheduler/child/features.h"
-#include "third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.h"
+#include "third_party/blink/renderer/platform/scheduler/child/process_state.h"
#include "third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h"
#include "third_party/blink/renderer/platform/scheduler/public/worker_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_helper.h"
@@ -97,10 +98,9 @@ WorkerThreadScheduler::WorkerThreadScheduler(
WebThreadType thread_type,
std::unique_ptr<base::sequence_manager::SequenceManager> sequence_manager,
WorkerSchedulerProxy* proxy)
- : NonMainThreadSchedulerImpl(std::make_unique<NonMainThreadSchedulerHelper>(
- std::move(sequence_manager),
- this,
- TaskType::kWorkerThreadTaskQueueDefault)),
+ : NonMainThreadSchedulerImpl(std::move(sequence_manager),
+ TaskType::kWorkerThreadTaskQueueDefault),
+ thread_type_(thread_type),
idle_helper_(helper(),
this,
"WorkerSchedulerIdlePeriod",
@@ -113,7 +113,11 @@ WorkerThreadScheduler::WorkerThreadScheduler(
kUnspecifiedWorkerThreadLoadTrackerReportingInterval),
lifecycle_state_(proxy ? proxy->lifecycle_state()
: SchedulingLifecycleState::kNotThrottled),
- worker_metrics_helper_(thread_type, helper()->HasCPUTimingForEachTask()) {
+ worker_metrics_helper_(thread_type, helper()->HasCPUTimingForEachTask()),
+ initial_frame_status_(proxy ? proxy->initial_frame_status()
+ : FrameStatus::kNone),
+ ukm_source_id_(proxy ? proxy->ukm_source_id() : ukm::kInvalidSourceId),
+ ukm_recorder_(proxy ? proxy->TakeUkmRecorder() : nullptr) {
thread_start_time_ = helper()->NowTicks();
load_tracker_.Resume(thread_start_time_);
helper()->AddTaskTimeObserver(this);
@@ -205,23 +209,24 @@ void WorkerThreadScheduler::InitImpl() {
initialized_ = true;
idle_helper_.EnableLongIdlePeriod();
- v8_task_runner_ = TaskQueueWithTaskType::Create(
- DefaultTaskQueue(), TaskType::kWorkerThreadTaskQueueV8);
- compositor_task_runner_ = TaskQueueWithTaskType::Create(
- DefaultTaskQueue(), TaskType::kWorkerThreadTaskQueueCompositor);
+ v8_task_runner_ =
+ DefaultTaskQueue()->CreateTaskRunner(TaskType::kWorkerThreadTaskQueueV8);
+ compositor_task_runner_ = DefaultTaskQueue()->CreateTaskRunner(
+ TaskType::kWorkerThreadTaskQueueCompositor);
}
void WorkerThreadScheduler::OnTaskCompleted(
- NonMainThreadTaskQueue* worker_task_queue,
+ NonMainThreadTaskQueue* task_queue,
const TaskQueue::Task& task,
const TaskQueue::TaskTiming& task_timing) {
- worker_metrics_helper_.RecordTaskMetrics(worker_task_queue, task,
- task_timing);
+ worker_metrics_helper_.RecordTaskMetrics(task_queue, task, task_timing);
if (task_queue_throttler_) {
task_queue_throttler_->OnTaskRunTimeReported(
- worker_task_queue, task_timing.start_time(), task_timing.end_time());
+ task_queue, task_timing.start_time(), task_timing.end_time());
}
+
+ RecordTaskUkm(task_queue, task, task_timing);
}
SchedulerHelper* WorkerThreadScheduler::GetSchedulerHelperForTesting() {
@@ -289,6 +294,34 @@ void WorkerThreadScheduler::CreateTaskQueueThrottler() {
cpu_time_budget_pool_->SetMaxThrottlingDelay(now, GetMaxThrottlingDelay());
}
+void WorkerThreadScheduler::RecordTaskUkm(
+ NonMainThreadTaskQueue* worker_task_queue,
+ const base::sequence_manager::TaskQueue::Task& task,
+ const base::sequence_manager::TaskQueue::TaskTiming& task_timing) {
+ if (!ShouldRecordTaskUkm(task_timing.has_thread_time()))
+ return;
+ ukm::builders::RendererSchedulerTask builder(ukm_source_id_);
+
+ builder.SetVersion(kUkmMetricVersion);
+ builder.SetThreadType(static_cast<int>(thread_type_));
+
+ builder.SetRendererBackgrounded(
+ internal::ProcessState::Get()->is_process_backgrounded);
+ builder.SetTaskType(task.task_type());
+ builder.SetFrameStatus(static_cast<int>(initial_frame_status_));
+ builder.SetTaskDuration(task_timing.wall_duration().InMicroseconds());
+
+ if (task_timing.has_thread_time())
+ builder.SetTaskCPUDuration(task_timing.thread_duration().InMicroseconds());
+
+ builder.Record(ukm_recorder_.get());
+}
+
+void WorkerThreadScheduler::SetUkmRecorderForTest(
+ std::unique_ptr<ukm::UkmRecorder> ukm_recorder) {
+ ukm_recorder_ = std::move(ukm_recorder);
+}
+
void WorkerThreadScheduler::SetCPUTimeBudgetPoolForTesting(
CPUTimeBudgetPool* cpu_time_budget_pool) {
cpu_time_budget_pool_ = cpu_time_budget_pool;
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 19e9ac40675..7d560b95a16 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
@@ -9,11 +9,12 @@
#include "base/message_loop/message_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/task/sequence_manager/task_time_observer.h"
+#include "components/scheduling_metrics/task_duration_metric_reporter.h"
#include "third_party/blink/public/platform/web_thread_type.h"
#include "third_party/blink/renderer/platform/scheduler/common/idle_canceled_delayed_task_sweeper.h"
#include "third_party/blink/renderer/platform/scheduler/common/idle_helper.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
-#include "third_party/blink/renderer/platform/scheduler/util/task_duration_metric_reporter.h"
+#include "third_party/blink/renderer/platform/scheduler/renderer/frame_status.h"
#include "third_party/blink/renderer/platform/scheduler/util/thread_load_tracker.h"
#include "third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_impl.h"
#include "third_party/blink/renderer/platform/scheduler/worker/worker_metrics_helper.h"
@@ -24,6 +25,10 @@ class SequenceManager;
}
} // namespace base
+namespace ukm {
+class UkmRecorder;
+}
+
namespace blink {
namespace scheduler {
@@ -53,7 +58,7 @@ class PLATFORM_EXPORT WorkerThreadScheduler
void AddTaskObserver(base::MessageLoop::TaskObserver* task_observer) override;
void RemoveTaskObserver(
base::MessageLoop::TaskObserver* task_observer) override;
- void AddRAILModeObserver(RAILModeObserver*) override {}
+ void AddRAILModeObserver(WebRAILModeObserver*) override {}
void Shutdown() override;
// NonMainThreadSchedulerImpl implementation:
@@ -116,9 +121,17 @@ class PLATFORM_EXPORT WorkerThreadScheduler
std::unordered_set<WorkerScheduler*>& GetWorkerSchedulersForTesting();
+ void SetUkmRecorderForTest(std::unique_ptr<ukm::UkmRecorder> ukm_recorder);
+
private:
void MaybeStartLongIdlePeriod();
+ void RecordTaskUkm(
+ NonMainThreadTaskQueue* worker_task_queue,
+ const base::sequence_manager::TaskQueue::Task& task,
+ const base::sequence_manager::TaskQueue::TaskTiming& task_timing);
+
+ const WebThreadType thread_type_;
IdleHelper idle_helper_;
IdleCanceledDelayedTaskSweeper idle_canceled_delayed_task_sweeper_;
ThreadLoadTracker load_tracker_;
@@ -143,6 +156,12 @@ class PLATFORM_EXPORT WorkerThreadScheduler
WakeUpBudgetPool* wake_up_budget_pool_ = nullptr;
CPUTimeBudgetPool* cpu_time_budget_pool_ = nullptr;
+ // The status of the parent frame when the worker was created.
+ const FrameStatus initial_frame_status_;
+
+ const ukm::SourceId ukm_source_id_;
+ std::unique_ptr<ukm::UkmRecorder> ukm_recorder_;
+
DISALLOW_COPY_AND_ASSIGN(WorkerThreadScheduler);
};
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 7144c3516f0..afaf4d165f7 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
@@ -3,15 +3,18 @@
// found in the LICENSE file.
#include "third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h"
-
#include "base/callback.h"
#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/stringprintf.h"
+#include "base/task/sequence_manager/test/fake_task.h"
#include "base/task/sequence_manager/test/sequence_manager_for_test.h"
#include "base/test/scoped_task_environment.h"
+#include "components/ukm/test_ukm_recorder.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/platform/scheduler/child/process_state.h"
+#include "third_party/blink/renderer/platform/scheduler/test/fake_frame_scheduler.h"
using testing::ElementsAreArray;
@@ -61,6 +64,20 @@ class WorkerThreadSchedulerForTest : public WorkerThreadScheduler {
clock_(clock_),
timeline_(timeline) {}
+ WorkerThreadSchedulerForTest(
+ std::unique_ptr<base::sequence_manager::SequenceManager> manager,
+ const base::TickClock* clock_,
+ std::vector<std::string>* timeline,
+ WorkerSchedulerProxy* proxy)
+ : WorkerThreadScheduler(WebThreadType::kTestThread,
+ std::move(manager),
+ proxy),
+ clock_(clock_),
+ timeline_(timeline) {}
+
+ using ThreadSchedulerImpl::SetUkmTaskSamplingRateForTest;
+ using WorkerThreadScheduler::SetUkmRecorderForTest;
+
private:
bool CanEnterLongIdlePeriod(
base::TimeTicks now,
@@ -101,7 +118,7 @@ class WorkerThreadSchedulerTest : public testing::Test {
// Null clock might trigger some assertions.
task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(5));
scheduler_->Init();
- default_task_runner_ = scheduler_->CreateTaskRunner("test_tq");
+ default_task_runner_ = scheduler_->CreateTaskQueue("test_tq");
idle_task_runner_ = scheduler_->IdleTaskRunner();
}
@@ -370,6 +387,113 @@ TEST_F(WorkerThreadSchedulerTest, TestLongIdlePeriodTimeline) {
EXPECT_THAT(timeline_, ElementsAreArray(expected_timeline));
}
+namespace {
+
+class FrameSchedulerDelegateWithUkmSourceId : public FrameScheduler::Delegate {
+ public:
+ FrameSchedulerDelegateWithUkmSourceId(ukm::SourceId source_id)
+ : source_id_(source_id) {}
+
+ ~FrameSchedulerDelegateWithUkmSourceId() override {}
+
+ ukm::UkmRecorder* GetUkmRecorder() override { return nullptr; }
+
+ ukm::SourceId GetUkmSourceId() override { return source_id_; }
+
+ private:
+ ukm::SourceId source_id_;
+};
+
+} // namespace
+
+class WorkerThreadSchedulerWithProxyTest : public testing::Test {
+ public:
+ WorkerThreadSchedulerWithProxyTest()
+ : task_environment_(
+ base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME,
+ base::test::ScopedTaskEnvironment::ExecutionMode::QUEUED) {
+ frame_scheduler_delegate_ =
+ std::make_unique<FrameSchedulerDelegateWithUkmSourceId>(42);
+ frame_scheduler_ = FakeFrameScheduler::Builder()
+ .SetIsPageVisible(false)
+ .SetFrameType(FrameScheduler::FrameType::kSubframe)
+ .SetIsCrossOrigin(true)
+ .SetDelegate(frame_scheduler_delegate_.get())
+ .Build();
+ frame_scheduler_->SetCrossOrigin(true);
+
+ worker_scheduler_proxy_ =
+ std::make_unique<WorkerSchedulerProxy>(frame_scheduler_.get());
+
+ scheduler_ = std::make_unique<WorkerThreadSchedulerForTest>(
+ base::sequence_manager::SequenceManagerForTest::Create(
+ nullptr, task_environment_.GetMainThreadTaskRunner(),
+ task_environment_.GetMockTickClock()),
+ task_environment_.GetMockTickClock(), &timeline_,
+ worker_scheduler_proxy_.get());
+
+ task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(5));
+
+ scheduler_->Init();
+ }
+
+ ~WorkerThreadSchedulerWithProxyTest() override = default;
+
+ void TearDown() override {
+ task_environment_.FastForwardUntilNoTasksRemain();
+ }
+
+ protected:
+ base::test::ScopedTaskEnvironment task_environment_;
+ std::vector<std::string> timeline_;
+ std::unique_ptr<FrameScheduler::Delegate> frame_scheduler_delegate_;
+ std::unique_ptr<FrameScheduler> frame_scheduler_;
+ std::unique_ptr<WorkerSchedulerProxy> worker_scheduler_proxy_;
+ std::unique_ptr<WorkerThreadSchedulerForTest> scheduler_;
+ scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_;
+ scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_;
+
+ DISALLOW_COPY_AND_ASSIGN(WorkerThreadSchedulerWithProxyTest);
+};
+
+TEST_F(WorkerThreadSchedulerWithProxyTest, UkmTaskRecording) {
+ internal::ProcessState::Get()->is_process_backgrounded = true;
+
+ std::unique_ptr<ukm::TestUkmRecorder> owned_ukm_recorder =
+ std::make_unique<ukm::TestUkmRecorder>();
+ ukm::TestUkmRecorder* ukm_recorder = owned_ukm_recorder.get();
+
+ scheduler_->SetUkmTaskSamplingRateForTest(1);
+ scheduler_->SetUkmRecorderForTest(std::move(owned_ukm_recorder));
+
+ base::sequence_manager::FakeTask task(
+ static_cast<int>(TaskType::kJavascriptTimer));
+ base::sequence_manager::FakeTaskTiming task_timing(
+ base::TimeTicks() + base::TimeDelta::FromMilliseconds(200),
+ base::TimeTicks() + base::TimeDelta::FromMilliseconds(700),
+ base::ThreadTicks() + base::TimeDelta::FromMilliseconds(250),
+ base::ThreadTicks() + base::TimeDelta::FromMilliseconds(500));
+
+ scheduler_->OnTaskCompleted(nullptr, task, task_timing);
+
+ auto entries = ukm_recorder->GetEntriesByName("RendererSchedulerTask");
+
+ EXPECT_EQ(entries.size(), static_cast<size_t>(1));
+
+ ukm::TestUkmRecorder::ExpectEntryMetric(
+ entries[0], "ThreadType", static_cast<int>(WebThreadType::kTestThread));
+ ukm::TestUkmRecorder::ExpectEntryMetric(entries[0], "RendererBackgrounded",
+ true);
+ ukm::TestUkmRecorder::ExpectEntryMetric(
+ entries[0], "TaskType", static_cast<int>(TaskType::kJavascriptTimer));
+ ukm::TestUkmRecorder::ExpectEntryMetric(
+ entries[0], "FrameStatus",
+ static_cast<int>(FrameStatus::kCrossOriginBackground));
+ ukm::TestUkmRecorder::ExpectEntryMetric(entries[0], "TaskDuration", 500000);
+ ukm::TestUkmRecorder::ExpectEntryMetric(entries[0], "TaskCPUDuration",
+ 250000);
+}
+
} // namespace worker_thread_scheduler_unittest
} // namespace scheduler
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scoped_orientation_change_indicator.cc b/chromium/third_party/blink/renderer/platform/scoped_orientation_change_indicator.cc
deleted file mode 100644
index a96f0002edb..00000000000
--- a/chromium/third_party/blink/renderer/platform/scoped_orientation_change_indicator.cc
+++ /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.
-
-#include "third_party/blink/renderer/platform/scoped_orientation_change_indicator.h"
-
-#include "base/logging.h"
-#include "third_party/blink/renderer/platform/wtf/wtf.h"
-
-namespace blink {
-
-ScopedOrientationChangeIndicator::State
- ScopedOrientationChangeIndicator::state_ =
- ScopedOrientationChangeIndicator::State::kNotProcessing;
-
-ScopedOrientationChangeIndicator::ScopedOrientationChangeIndicator() {
- DCHECK(IsMainThread());
-
- previous_state_ = state_;
- state_ = State::kProcessing;
-}
-
-ScopedOrientationChangeIndicator::~ScopedOrientationChangeIndicator() {
- DCHECK(IsMainThread());
- state_ = previous_state_;
-}
-
-// static
-bool ScopedOrientationChangeIndicator::ProcessingOrientationChange() {
- DCHECK(IsMainThread());
- return state_ == State::kProcessing;
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scoped_orientation_change_indicator.h b/chromium/third_party/blink/renderer/platform/scoped_orientation_change_indicator.h
deleted file mode 100644
index e25e19f8c44..00000000000
--- a/chromium/third_party/blink/renderer/platform/scoped_orientation_change_indicator.h
+++ /dev/null
@@ -1,37 +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_SCOPED_ORIENTATION_CHANGE_INDICATOR_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCOPED_ORIENTATION_CHANGE_INDICATOR_H_
-
-#include "third_party/blink/renderer/platform/platform_export.h"
-#include "third_party/blink/renderer/platform/wtf/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/noncopyable.h"
-
-namespace blink {
-
-class PLATFORM_EXPORT ScopedOrientationChangeIndicator final {
- STACK_ALLOCATED();
- WTF_MAKE_NONCOPYABLE(ScopedOrientationChangeIndicator);
-
- public:
- static bool ProcessingOrientationChange();
-
- explicit ScopedOrientationChangeIndicator();
- ~ScopedOrientationChangeIndicator();
-
- private:
- enum class State {
- kProcessing,
- kNotProcessing,
- };
-
- static State state_;
-
- State previous_state_ = State::kNotProcessing;
-};
-
-} // namespace blink
-
-#endif
diff --git a/chromium/third_party/blink/renderer/platform/scoped_orientation_change_indicator_test.cc b/chromium/third_party/blink/renderer/platform/scoped_orientation_change_indicator_test.cc
deleted file mode 100644
index 3485a9fba5b..00000000000
--- a/chromium/third_party/blink/renderer/platform/scoped_orientation_change_indicator_test.cc
+++ /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.
-
-#include "third_party/blink/renderer/platform/scoped_orientation_change_indicator.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace blink {
-
-TEST(ScopedOrientationChangeIndicatorTest, InitialState) {
- EXPECT_FALSE(ScopedOrientationChangeIndicator::ProcessingOrientationChange());
-}
-
-TEST(ScopedOrientationChangeIndicatorTest, ConstructOneIndicatorWithGesture) {
- ScopedOrientationChangeIndicator indicator;
-
- EXPECT_TRUE(ScopedOrientationChangeIndicator::ProcessingOrientationChange());
-}
-
-TEST(ScopedOrientationChangeIndicatorTest, MultipleIndicatorInTheSameScope) {
- ScopedOrientationChangeIndicator indicator1;
-
- EXPECT_TRUE(ScopedOrientationChangeIndicator::ProcessingOrientationChange());
-
- ScopedOrientationChangeIndicator indicator2;
-
- EXPECT_TRUE(ScopedOrientationChangeIndicator::ProcessingOrientationChange());
-}
-
-TEST(ScopedOrientationChangeIndicatorTest, DestructResetsStateUsingGesture) {
- { ScopedOrientationChangeIndicator indicator; }
-
- EXPECT_FALSE(ScopedOrientationChangeIndicator::ProcessingOrientationChange());
-}
-
-TEST(ScopedOrientationChangeIndicatorTest, DestructResetsStateUsingNoGesture) {
- ScopedOrientationChangeIndicator indicator;
- { ScopedOrientationChangeIndicator indicator; }
-
- EXPECT_TRUE(ScopedOrientationChangeIndicator::ProcessingOrientationChange());
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scroll/DEPS b/chromium/third_party/blink/renderer/platform/scroll/DEPS
index 4ae5c6e0ec8..67597e2215e 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/DEPS
+++ b/chromium/third_party/blink/renderer/platform/scroll/DEPS
@@ -7,19 +7,7 @@ include_rules = [
# Dependencies.
"+cc",
- "+third_party/blink/renderer/platform/animation",
"+third_party/blink/renderer/platform/geometry",
- "+third_party/blink/renderer/platform/graphics",
- "+third_party/blink/renderer/platform/heap",
- "+third_party/blink/renderer/platform/instrumentation",
- "+third_party/blink/renderer/platform/layout_test_support.h",
- "+third_party/blink/renderer/platform/mac",
- "+third_party/blink/renderer/platform/platform_chrome_client.h",
"+third_party/blink/renderer/platform/platform_export.h",
- "+third_party/blink/renderer/platform/runtime_enabled_features.h",
- "+third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h",
- "+third_party/blink/renderer/platform/timer.h",
- "+third_party/blink/renderer/platform/transforms/transformation_matrix.h",
- "+third_party/blink/renderer/platform/testing",
"+third_party/blink/renderer/platform/wtf",
]
diff --git a/chromium/third_party/blink/renderer/platform/scroll/overscroll_behavior.h b/chromium/third_party/blink/renderer/platform/scroll/overscroll_behavior.h
new file mode 100644
index 00000000000..d4ba8d63183
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/scroll/overscroll_behavior.h
@@ -0,0 +1,24 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_OVERSCROLL_BEHAVIOR_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_OVERSCROLL_BEHAVIOR_H_
+
+#include "cc/input/overscroll_behavior.h"
+
+namespace blink {
+
+// A wrapper around cc's structure to expose it to core.
+struct OverscrollBehavior : public cc::OverscrollBehavior {
+ OverscrollBehavior() = default;
+ explicit OverscrollBehavior(OverscrollBehaviorType type)
+ : cc::OverscrollBehavior(type) {}
+ OverscrollBehavior(OverscrollBehaviorType x_type,
+ OverscrollBehaviorType y_type)
+ : cc::OverscrollBehavior(x_type, y_type) {}
+};
+
+} // namespace blink
+
+#endif
diff --git a/chromium/third_party/blink/renderer/platform/scroll/scroll_alignment.h b/chromium/third_party/blink/renderer/platform/scroll/scroll_alignment.h
index 7a4d5e3a8e8..26d57bdde39 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/scroll_alignment.h
+++ b/chromium/third_party/blink/renderer/platform/scroll/scroll_alignment.h
@@ -64,6 +64,8 @@ class LayoutRect;
struct PLATFORM_EXPORT ScrollAlignment {
STACK_ALLOCATED();
+
+ public:
static ScrollAlignmentBehavior GetVisibleBehavior(const ScrollAlignment& s) {
return s.rect_visible_;
}
diff --git a/chromium/third_party/blink/renderer/platform/scroll/scroll_types.h b/chromium/third_party/blink/renderer/platform/scroll/scroll_types.h
index 4f4884b73ba..6be6f5166c1 100644
--- a/chromium/third_party/blink/renderer/platform/scroll/scroll_types.h
+++ b/chromium/third_party/blink/renderer/platform/scroll/scroll_types.h
@@ -213,6 +213,8 @@ enum ScrollBehavior {
// by scrolling.
struct ScrollResult {
STACK_ALLOCATED();
+
+ public:
explicit ScrollResult()
: did_scroll_x(false),
did_scroll_y(false),
diff --git a/chromium/third_party/blink/renderer/platform/scroll/web_scrollbar_theme_client.h b/chromium/third_party/blink/renderer/platform/scroll/web_scrollbar_theme_client.h
new file mode 100644
index 00000000000..6a9952eac1d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/scroll/web_scrollbar_theme_client.h
@@ -0,0 +1,20 @@
+// 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_SCROLL_WEB_SCROLLBAR_THEME_CLIENT_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_WEB_SCROLLBAR_THEME_CLIENT_H_
+
+namespace blink {
+
+class WebScrollbarThemeClient {
+ protected:
+ WebScrollbarThemeClient() = default;
+
+ public:
+ virtual void PreferencesChanged() {}
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_WEB_SCROLLBAR_THEME_CLIENT_H_
diff --git a/chromium/third_party/blink/renderer/platform/shared_buffer.h b/chromium/third_party/blink/renderer/platform/shared_buffer.h
index 3bd98712d68..311fb9c5e46 100644
--- a/chromium/third_party/blink/renderer/platform/shared_buffer.h
+++ b/chromium/third_party/blink/renderer/platform/shared_buffer.h
@@ -100,22 +100,22 @@ class PLATFORM_EXPORT SharedBuffer : public RefCounted<SharedBuffer> {
HAS_STRICTLY_TYPED_ARG
static scoped_refptr<SharedBuffer> Create(STRICTLY_TYPED_ARG(size)) {
- STRICT_ARG_TYPE(size_t);
- return base::AdoptRef(new SharedBuffer(size));
+ ALLOW_NUMERIC_ARG_TYPES_PROMOTABLE_TO(size_t);
+ return base::AdoptRef(new SharedBuffer(SafeCast<wtf_size_t>(size)));
}
HAS_STRICTLY_TYPED_ARG
static scoped_refptr<SharedBuffer> Create(const char* data,
STRICTLY_TYPED_ARG(size)) {
- STRICT_ARG_TYPE(size_t);
- return base::AdoptRef(new SharedBuffer(data, size));
+ ALLOW_NUMERIC_ARG_TYPES_PROMOTABLE_TO(size_t);
+ return base::AdoptRef(new SharedBuffer(data, SafeCast<wtf_size_t>(size)));
}
HAS_STRICTLY_TYPED_ARG
static scoped_refptr<SharedBuffer> Create(const unsigned char* data,
STRICTLY_TYPED_ARG(size)) {
- STRICT_ARG_TYPE(size_t);
- return base::AdoptRef(new SharedBuffer(data, size));
+ ALLOW_NUMERIC_ARG_TYPES_PROMOTABLE_TO(size_t);
+ return base::AdoptRef(new SharedBuffer(data, SafeCast<wtf_size_t>(size)));
}
static scoped_refptr<SharedBuffer> AdoptVector(Vector<char>&);
@@ -168,7 +168,7 @@ class PLATFORM_EXPORT SharedBuffer : public RefCounted<SharedBuffer> {
HAS_STRICTLY_TYPED_ARG
WARN_UNUSED_RESULT
bool GetBytes(void* dest, STRICTLY_TYPED_ARG(byte_length)) const {
- STRICT_ARG_TYPE(size_t);
+ ALLOW_NUMERIC_ARG_TYPES_PROMOTABLE_TO(size_t);
return GetBytesInternal(dest, byte_length);
}
diff --git a/chromium/third_party/blink/renderer/platform/testing/code_cache_loader_mock.cc b/chromium/third_party/blink/renderer/platform/testing/code_cache_loader_mock.cc
new file mode 100644
index 00000000000..a4e9fb30bf2
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/testing/code_cache_loader_mock.cc
@@ -0,0 +1,23 @@
+// 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/testing/code_cache_loader_mock.h"
+
+namespace blink {
+
+void CodeCacheLoaderMock::FetchFromCodeCacheSynchronously(
+ const GURL& url,
+ base::Time* response_time_out,
+ std::vector<uint8_t>* data_out) {
+ *response_time_out = base::Time();
+ *data_out = std::vector<uint8_t>();
+}
+
+void CodeCacheLoaderMock::FetchFromCodeCache(
+ const GURL& kurl,
+ CodeCacheLoader::FetchCodeCacheCallback callback) {
+ std::move(callback).Run(base::Time(), std::vector<uint8_t>());
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/testing/code_cache_loader_mock.h b/chromium/third_party/blink/renderer/platform/testing/code_cache_loader_mock.h
new file mode 100644
index 00000000000..0459e8e926a
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/testing/code_cache_loader_mock.h
@@ -0,0 +1,38 @@
+// 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_TESTING_CODE_CACHE_LOADER_MOCK_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_TESTING_CODE_CACHE_LOADER_MOCK_H_
+
+#include "base/memory/weak_ptr.h"
+#include "third_party/blink/public/platform/code_cache_loader.h"
+#include "url/gurl.h"
+
+namespace blink {
+
+// A simple class for mocking CodeCacheLoader.
+class CodeCacheLoaderMock : public CodeCacheLoader {
+ public:
+ CodeCacheLoaderMock() : weak_ptr_factory_(this) {}
+ ~CodeCacheLoaderMock() override = default;
+
+ // CodeCacheLoader methods:
+ void FetchFromCodeCacheSynchronously(const GURL& url,
+ base::Time* response_time_out,
+ std::vector<uint8_t>* data_out) override;
+ void FetchFromCodeCache(
+ const GURL& url,
+ CodeCacheLoader::FetchCodeCacheCallback callback) override;
+
+ base::WeakPtr<CodeCacheLoaderMock> GetWeakPtr();
+
+ private:
+ base::WeakPtrFactory<CodeCacheLoaderMock> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(CodeCacheLoaderMock);
+};
+
+} // namespace blink
+
+#endif // CodeCacheLoaderMock_h
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 ef7511a198c..89981be162e 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,8 @@ class EmptyWebMediaPlayer : public WebMediaPlayer {
void SetVolume(double) override {}
void EnterPictureInPicture(PipWindowOpenedCallback) override {}
void ExitPictureInPicture(PipWindowClosedCallback) override {}
+ void SetPictureInPictureCustomControls(
+ const std::vector<PictureInPictureControlInfo>&) override {}
void RegisterPictureInPictureWindowResizeCallback(
PipWindowResizedCallback) override {}
WebTimeRanges Buffered() const override;
@@ -56,8 +58,8 @@ class EmptyWebMediaPlayer : public WebMediaPlayer {
};
unsigned DecodedFrameCount() const override { return 0; }
unsigned DroppedFrameCount() const override { return 0; }
- size_t AudioDecodedByteCount() const override { return 0; }
- size_t VideoDecodedByteCount() const override { return 0; }
+ uint64_t AudioDecodedByteCount() const override { return 0; }
+ uint64_t VideoDecodedByteCount() const override { return 0; }
void Paint(cc::PaintCanvas*,
const WebRect&,
cc::PaintFlags&,
diff --git a/chromium/third_party/blink/renderer/platform/testing/fake_graphics_layer.h b/chromium/third_party/blink/renderer/platform/testing/fake_graphics_layer.h
index d6cd8f8160c..7199a538f9f 100644
--- a/chromium/third_party/blink/renderer/platform/testing/fake_graphics_layer.h
+++ b/chromium/third_party/blink/renderer/platform/testing/fake_graphics_layer.h
@@ -5,6 +5,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_TESTING_FAKE_GRAPHICS_LAYER_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_TESTING_FAKE_GRAPHICS_LAYER_H_
+#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
+
namespace blink {
// A simple GraphicsLayer implementation suitable for use in unit tests.
diff --git a/chromium/third_party/blink/renderer/platform/testing/fake_graphics_layer_client.h b/chromium/third_party/blink/renderer/platform/testing/fake_graphics_layer_client.h
index 4d4e7c98f37..38ce668a97e 100644
--- a/chromium/third_party/blink/renderer/platform/testing/fake_graphics_layer_client.h
+++ b/chromium/third_party/blink/renderer/platform/testing/fake_graphics_layer_client.h
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_TESTING_FAKE_GRAPHICS_LAYER_CLIENT_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_TESTING_FAKE_GRAPHICS_LAYER_CLIENT_H_
+#include "third_party/blink/renderer/platform/geometry/int_rect.h"
#include "third_party/blink/renderer/platform/graphics/graphics_layer_client.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/platform/testing/image_decode_bench.cc b/chromium/third_party/blink/renderer/platform/testing/image_decode_bench.cc
index 00c158d339f..ba40fb1d49d 100644
--- a/chromium/third_party/blink/renderer/platform/testing/image_decode_bench.cc
+++ b/chromium/third_party/blink/renderer/platform/testing/image_decode_bench.cc
@@ -128,7 +128,8 @@ int ImageDecodeBenchMain(int argc, char* argv[]) {
// has a protected constructor.
class WebPlatform : public Platform {};
- Platform::Initialize(new WebPlatform());
+ std::unique_ptr<WebPlatform> platform(new WebPlatform());
+ Platform::Initialize(platform.get(), platform->CurrentThread());
// Read entire file content into |data| (a contiguous block of memory) then
// decode it to verify the image and record its ImageMeta data.
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 fafe1ade6bb..3276b78c970 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
@@ -42,6 +42,11 @@ class PaintTestConfigurations
#define INSTANTIATE_SPV2_TEST_CASE_P(test_class) \
INSTANTIATE_TEST_CASE_P(All, test_class, ::testing::Values(kSlimmingPaintV2))
+#define INSTANTIATE_LAYER_LIST_TEST_CASE_P(test_class) \
+ INSTANTIATE_TEST_CASE_P( \
+ All, test_class, \
+ ::testing::Values(kBlinkGenPropertyTrees, kSlimmingPaintV2))
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_TESTING_PAINT_TEST_CONFIGURATIONS_H_
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 6b51f9a6e16..2017a8cc2dc 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
@@ -124,8 +124,8 @@ WebBlobRegistry* TestingPlatformSupport::GetBlobRegistry() {
return old_platform_ ? old_platform_->GetBlobRegistry() : nullptr;
}
-WebIDBFactory* TestingPlatformSupport::IdbFactory() {
- return old_platform_ ? old_platform_->IdbFactory() : nullptr;
+std::unique_ptr<WebIDBFactory> TestingPlatformSupport::CreateIdbFactory() {
+ return old_platform_ ? old_platform_->CreateIdbFactory() : nullptr;
}
WebURLLoaderMockFactory* TestingPlatformSupport::GetURLLoaderMockFactory() {
@@ -150,6 +150,14 @@ void TestingPlatformSupport::RunUntilIdle() {
base::RunLoop().RunUntilIdle();
}
+bool TestingPlatformSupport::IsThreadedAnimationEnabled() {
+ return is_threaded_animation_enabled_;
+}
+
+void TestingPlatformSupport::SetThreadedAnimationEnabled(bool enabled) {
+ is_threaded_animation_enabled_ = enabled;
+}
+
class ScopedUnittestsEnvironmentSetup::DummyPlatform final
: public blink::Platform {
public:
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 cf5dec66d5c..fb45b23777a 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
@@ -39,6 +39,7 @@
#include "base/macros.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"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
@@ -62,14 +63,19 @@ class TestingPlatformSupport : public Platform {
WebString DefaultLocale() override;
WebThread* CurrentThread() override;
WebBlobRegistry* GetBlobRegistry() override;
- WebIDBFactory* IdbFactory() override;
+ std::unique_ptr<WebIDBFactory> CreateIdbFactory() override;
WebURLLoaderMockFactory* GetURLLoaderMockFactory() override;
std::unique_ptr<blink::WebURLLoaderFactory> CreateDefaultURLLoaderFactory()
override;
+ std::unique_ptr<CodeCacheLoader> CreateCodeCacheLoader() override {
+ return std::make_unique<CodeCacheLoaderMock>();
+ }
WebData GetDataResource(const char* name) override;
InterfaceProvider* GetInterfaceProvider() override;
+ bool IsThreadedAnimationEnabled() override;
virtual void RunUntilIdle();
+ void SetThreadedAnimationEnabled(bool enabled);
// Overrides the handling of GetInterface on the platform's associated
// interface provider.
@@ -91,6 +97,9 @@ class TestingPlatformSupport : public Platform {
Platform* const old_platform_;
std::unique_ptr<TestingInterfaceProvider> interface_provider_;
+ private:
+ bool is_threaded_animation_enabled_ = false;
+
DISALLOW_COPY_AND_ASSIGN(TestingPlatformSupport);
};
diff --git a/chromium/third_party/blink/renderer/platform/testing/testing_platform_support_with_custom_scheduler.cc b/chromium/third_party/blink/renderer/platform/testing/testing_platform_support_with_custom_scheduler.cc
new file mode 100644
index 00000000000..79c3ff07665
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/testing/testing_platform_support_with_custom_scheduler.cc
@@ -0,0 +1,44 @@
+// 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/testing/testing_platform_support_with_custom_scheduler.h"
+
+#include "third_party/blink/public/platform/web_thread.h"
+#include "third_party/blink/renderer/platform/wtf/wtf.h"
+
+namespace blink {
+
+namespace {
+
+class ThreadWithCustomScheduler : public WebThread {
+ public:
+ explicit ThreadWithCustomScheduler(ThreadScheduler* scheduler)
+ : scheduler_(scheduler) {}
+ ~ThreadWithCustomScheduler() override {}
+
+ bool IsCurrentThread() const override {
+ DCHECK(WTF::IsMainThread());
+ return true;
+ }
+ ThreadScheduler* Scheduler() const override { return scheduler_; }
+
+ private:
+ ThreadScheduler* scheduler_;
+};
+
+} // namespace
+
+TestingPlatformSupportWithCustomScheduler ::
+ TestingPlatformSupportWithCustomScheduler(ThreadScheduler* scheduler)
+ : thread_(std::make_unique<ThreadWithCustomScheduler>(scheduler)) {}
+
+TestingPlatformSupportWithCustomScheduler ::
+ ~TestingPlatformSupportWithCustomScheduler() {}
+
+WebThread* TestingPlatformSupportWithCustomScheduler::CurrentThread() {
+ DCHECK(WTF::IsMainThread());
+ return thread_.get();
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/testing/testing_platform_support_with_custom_scheduler.h b/chromium/third_party/blink/renderer/platform/testing/testing_platform_support_with_custom_scheduler.h
new file mode 100644
index 00000000000..828a0af9d41
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/testing/testing_platform_support_with_custom_scheduler.h
@@ -0,0 +1,39 @@
+// 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_TESTING_TESTING_PLATFORM_SUPPORT_WITH_CUSTOM_SCHEDULER_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_TESTING_TESTING_PLATFORM_SUPPORT_WITH_CUSTOM_SCHEDULER_H_
+
+#include <memory>
+#include "base/macros.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
+#include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
+
+// Test environment where you can inject your custom implementation of
+// ThreadScheduler on the main thread. Multi-thread is not supported.
+//
+// You would probably like to use this with ScopedTestingPlatformSupport
+// class template. See testing_platform_support.h for details.
+
+namespace blink {
+
+class TestingPlatformSupportWithCustomScheduler
+ : public TestingPlatformSupport {
+ public:
+ // |scheduler| must be owned by the caller.
+ explicit TestingPlatformSupportWithCustomScheduler(
+ ThreadScheduler* scheduler);
+ ~TestingPlatformSupportWithCustomScheduler() override;
+
+ WebThread* CurrentThread() override;
+
+ private:
+ std::unique_ptr<WebThread> thread_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestingPlatformSupportWithCustomScheduler);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_TESTING_TESTING_PLATFORM_SUPPORT_WITH_CUSTOM_SCHEDULER_H_
diff --git a/chromium/third_party/blink/renderer/platform/testing/testing_platform_support_with_web_rtc.cc b/chromium/third_party/blink/renderer/platform/testing/testing_platform_support_with_web_rtc.cc
index db69771b88a..440c68fcf99 100644
--- a/chromium/third_party/blink/renderer/platform/testing/testing_platform_support_with_web_rtc.cc
+++ b/chromium/third_party/blink/renderer/platform/testing/testing_platform_support_with_web_rtc.cc
@@ -95,9 +95,9 @@ MockWebRTCPeerConnectionHandler::MockWebRTCPeerConnectionHandler() = default;
MockWebRTCPeerConnectionHandler::~MockWebRTCPeerConnectionHandler() = default;
-bool MockWebRTCPeerConnectionHandler::Initialize(const WebRTCConfiguration&,
- const WebMediaConstraints&,
- WebRTCSdpSemantics) {
+bool MockWebRTCPeerConnectionHandler::Initialize(
+ const webrtc::PeerConnectionInterface::RTCConfiguration&,
+ const WebMediaConstraints&) {
return true;
}
@@ -133,8 +133,34 @@ WebRTCSessionDescription MockWebRTCPeerConnectionHandler::RemoteDescription() {
return WebRTCSessionDescription();
}
+WebRTCSessionDescription
+MockWebRTCPeerConnectionHandler::CurrentLocalDescription() {
+ return WebRTCSessionDescription();
+}
+
+WebRTCSessionDescription
+MockWebRTCPeerConnectionHandler::CurrentRemoteDescription() {
+ return WebRTCSessionDescription();
+}
+
+WebRTCSessionDescription
+MockWebRTCPeerConnectionHandler::PendingLocalDescription() {
+ return WebRTCSessionDescription();
+}
+
+WebRTCSessionDescription
+MockWebRTCPeerConnectionHandler::PendingRemoteDescription() {
+ return WebRTCSessionDescription();
+}
+
+const webrtc::PeerConnectionInterface::RTCConfiguration&
+MockWebRTCPeerConnectionHandler::GetConfiguration() const {
+ static webrtc::PeerConnectionInterface::RTCConfiguration configuration;
+ return configuration;
+}
+
webrtc::RTCErrorType MockWebRTCPeerConnectionHandler::SetConfiguration(
- const WebRTCConfiguration&) {
+ const webrtc::PeerConnectionInterface::RTCConfiguration&) {
return webrtc::RTCErrorType::NONE;
}
diff --git a/chromium/third_party/blink/renderer/platform/testing/testing_platform_support_with_web_rtc.h b/chromium/third_party/blink/renderer/platform/testing/testing_platform_support_with_web_rtc.h
index 091f79d6570..af2f28bf7dd 100644
--- a/chromium/third_party/blink/renderer/platform/testing/testing_platform_support_with_web_rtc.h
+++ b/chromium/third_party/blink/renderer/platform/testing/testing_platform_support_with_web_rtc.h
@@ -8,6 +8,7 @@
#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/testing/testing_platform_support.h"
+#include "third_party/webrtc/api/peerconnectioninterface.h"
namespace blink {
@@ -16,9 +17,8 @@ class MockWebRTCPeerConnectionHandler : public WebRTCPeerConnectionHandler {
MockWebRTCPeerConnectionHandler();
~MockWebRTCPeerConnectionHandler() override;
- bool Initialize(const WebRTCConfiguration&,
- const WebMediaConstraints&,
- WebRTCSdpSemantics original_sdp_semantics_value) override;
+ bool Initialize(const webrtc::PeerConnectionInterface::RTCConfiguration&,
+ const WebMediaConstraints&) override;
void CreateOffer(const WebRTCSessionDescriptionRequest&,
const WebMediaConstraints&) override;
@@ -34,7 +34,14 @@ class MockWebRTCPeerConnectionHandler : public WebRTCPeerConnectionHandler {
const WebRTCSessionDescription&) override;
WebRTCSessionDescription LocalDescription() override;
WebRTCSessionDescription RemoteDescription() override;
- webrtc::RTCErrorType SetConfiguration(const WebRTCConfiguration&) override;
+ WebRTCSessionDescription CurrentLocalDescription() override;
+ WebRTCSessionDescription CurrentRemoteDescription() override;
+ WebRTCSessionDescription PendingLocalDescription() override;
+ WebRTCSessionDescription PendingRemoteDescription() override;
+ const webrtc::PeerConnectionInterface::RTCConfiguration& GetConfiguration()
+ const override;
+ webrtc::RTCErrorType SetConfiguration(
+ const webrtc::PeerConnectionInterface::RTCConfiguration&) override;
void GetStats(const WebRTCStatsRequest&) override;
void GetStats(std::unique_ptr<WebRTCStatsReportCallback>) override;
webrtc::RTCErrorOr<std::unique_ptr<WebRTCRtpTransceiver>>
diff --git a/chromium/third_party/blink/renderer/platform/testing/viewport_layers_setup.cc b/chromium/third_party/blink/renderer/platform/testing/viewport_layers_setup.cc
new file mode 100644
index 00000000000..548263843e0
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/testing/viewport_layers_setup.cc
@@ -0,0 +1,58 @@
+// 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/testing/viewport_layers_setup.h"
+
+#include <memory>
+#include "cc/layers/picture_layer.h"
+#include "cc/trees/layer_tree_host.h"
+#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
+#include "third_party/blink/renderer/platform/graphics/paint/property_tree_state.h"
+#include "third_party/blink/renderer/platform/testing/fake_graphics_layer.h"
+#include "third_party/blink/renderer/platform/testing/fake_graphics_layer_client.h"
+#include "third_party/blink/renderer/platform/testing/layer_tree_host_embedder.h"
+
+namespace blink {
+
+ViewportLayersSetup::ViewportLayersSetup() {
+ clip_layer_ = std::make_unique<FakeGraphicsLayer>(client_);
+ scroll_elasticity_layer_ = std::make_unique<FakeGraphicsLayer>(client_);
+ page_scale_layer_ = std::make_unique<FakeGraphicsLayer>(client_);
+ graphics_layer_ = std::make_unique<FakeGraphicsLayer>(client_);
+ graphics_layer_->SetDrawsContent(true);
+ clip_layer_->AddChild(scroll_elasticity_layer_.get());
+ scroll_elasticity_layer_->AddChild(page_scale_layer_.get());
+ page_scale_layer_->AddChild(graphics_layer_.get());
+ graphics_layer_->CcLayer()->SetScrollable(clip_layer_->CcLayer()->bounds());
+ layer_tree_ = std::make_unique<LayerTreeHostEmbedder>();
+ layer_tree_->layer_tree_host()->SetRootLayer(clip_layer_->CcLayer());
+
+ scroll_elasticity_layer_->SetElementId(cc::LayerIdToElementIdForTesting(
+ scroll_elasticity_layer_->CcLayer()->id()));
+
+ cc::LayerTreeHost::ViewportLayers viewport_layers;
+ viewport_layers.overscroll_elasticity_element_id =
+ scroll_elasticity_layer_->GetElementId();
+ viewport_layers.page_scale = page_scale_layer_->CcLayer();
+ viewport_layers.inner_viewport_container = clip_layer_->CcLayer();
+ viewport_layers.inner_viewport_scroll = graphics_layer_->CcLayer();
+ layer_tree_->layer_tree_host()->RegisterViewportLayers(viewport_layers);
+ layer_tree_->layer_tree_host()->SetViewportSizeAndScale(
+ gfx::Size(1, 1), /*device_scale_factor=*/1.f, viz::LocalSurfaceId());
+
+ graphics_layer_->SetLayerState(PropertyTreeState(PropertyTreeState::Root()),
+ IntPoint());
+}
+
+ViewportLayersSetup::~ViewportLayersSetup() = default;
+
+cc::LayerTreeHost* ViewportLayersSetup::layer_tree_host() {
+ return layer_tree_->layer_tree_host();
+}
+
+cc::AnimationHost* ViewportLayersSetup::animation_host() {
+ return layer_tree_->animation_host();
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/testing/viewport_layers_setup.h b/chromium/third_party/blink/renderer/platform/testing/viewport_layers_setup.h
new file mode 100644
index 00000000000..febdac812c9
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/testing/viewport_layers_setup.h
@@ -0,0 +1,44 @@
+// 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_TESTING_VIEWPORT_LAYERS_SETUP_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_TESTING_VIEWPORT_LAYERS_SETUP_H_
+
+#include <memory>
+
+#include "third_party/blink/renderer/platform/testing/fake_graphics_layer_client.h"
+
+namespace cc {
+class AnimationHost;
+class LayerTreeHost;
+} // namespace cc
+
+namespace blink {
+
+class FakeGraphicsLayer;
+class LayerTreeHostEmbedder;
+
+class ViewportLayersSetup {
+ public:
+ ViewportLayersSetup();
+ ~ViewportLayersSetup();
+
+ FakeGraphicsLayer& graphics_layer() { return *graphics_layer_; }
+ FakeGraphicsLayerClient& graphics_layer_client() { return client_; }
+
+ cc::LayerTreeHost* layer_tree_host();
+ cc::AnimationHost* animation_host();
+
+ private:
+ std::unique_ptr<FakeGraphicsLayer> graphics_layer_;
+ std::unique_ptr<FakeGraphicsLayer> page_scale_layer_;
+ std::unique_ptr<FakeGraphicsLayer> scroll_elasticity_layer_;
+ std::unique_ptr<FakeGraphicsLayer> clip_layer_;
+ FakeGraphicsLayerClient client_;
+ std::unique_ptr<LayerTreeHostEmbedder> layer_tree_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_TESTING_VIEWPORT_LAYERS_SETUP_H_
diff --git a/chromium/third_party/blink/renderer/platform/text/character.cc b/chromium/third_party/blink/renderer/platform/text/character.cc
index 6f64a2a2240..b1805945132 100644
--- a/chromium/third_party/blink/renderer/platform/text/character.cc
+++ b/chromium/third_party/blink/renderer/platform/text/character.cc
@@ -303,4 +303,13 @@ bool Character::IsNonCharacter(UChar32 character) {
return U_IS_UNICODE_NONCHAR(character);
}
+bool Character::HasDefiniteScript(UChar32 character) {
+ ICUError err;
+ UScriptCode hint_char_script = uscript_getScript(character, &err);
+ if (!U_SUCCESS(err))
+ return false;
+ return hint_char_script != USCRIPT_INHERITED &&
+ hint_char_script != USCRIPT_COMMON;
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/text/character.h b/chromium/third_party/blink/renderer/platform/text/character.h
index 8437e4d3db5..0008f58449e 100644
--- a/chromium/third_party/blink/renderer/platform/text/character.h
+++ b/chromium/third_party/blink/renderer/platform/text/character.h
@@ -186,6 +186,10 @@ class PLATFORM_EXPORT Character {
static bool IsPrivateUse(UChar32);
static bool IsNonCharacter(UChar32);
+ // Returns whether a script code could be determined for the given character
+ // and that script code is not USCRIPT_COMMON or USCRIPT_INHERITED.
+ static bool HasDefiniteScript(UChar32);
+
static bool IsModernGeorgianUppercase(UChar32 c) {
return IsInRange(c, 0x1C90, 0x1CBF);
}
diff --git a/chromium/third_party/blink/renderer/platform/text/text_break_iterator.cc b/chromium/third_party/blink/renderer/platform/text/text_break_iterator.cc
index bc6d101d91d..e39e8df0f79 100644
--- a/chromium/third_party/blink/renderer/platform/text/text_break_iterator.cc
+++ b/chromium/third_party/blink/renderer/platform/text/text_break_iterator.cc
@@ -53,17 +53,13 @@ unsigned NumGraphemeClusters(const String& string) {
return num;
}
-void GraphemesClusterList(String text,
- unsigned start,
- unsigned length,
- Vector<unsigned>* graphemes) {
+void GraphemesClusterList(const StringView& text, Vector<unsigned>* graphemes) {
+ const unsigned length = text.length();
graphemes->resize(length);
if (!length)
return;
- String substring = text.Substring(start, length);
- NonSharedCharacterBreakIterator it(substring);
-
+ NonSharedCharacterBreakIterator it(text);
int cursor_pos = it.Next();
unsigned count = 0;
unsigned pos = 0;
@@ -304,6 +300,8 @@ inline int LazyLineBreakIterator::NextBreakablePosition(
int pos,
const CharacterType* str,
int len) const {
+ DCHECK_GE(pos, 0);
+ DCHECK_GE(static_cast<unsigned>(pos), start_offset_);
int next_break = -1;
UChar last_last_ch = pos > 1 ? str[pos - 2] : SecondToLastCharacter();
UChar last_ch = pos > 0 ? str[pos - 1] : LastCharacter();
@@ -311,7 +309,7 @@ inline int LazyLineBreakIterator::NextBreakablePosition(
ULineBreak last_line_break;
if (lineBreakType == LineBreakType::kBreakAll)
last_line_break = LineBreakPropertyValue(last_last_ch, last_ch);
- unsigned prior_context_length = PriorContextLength();
+ PriorContext prior_context = GetPriorContext();
CharacterType ch;
bool is_space;
for (int i = pos; i < len;
@@ -357,13 +355,15 @@ inline int LazyLineBreakIterator::NextBreakablePosition(
if (next_break < i) {
// Don't break if positioned at start of primary context and there is no
// prior context.
- if (i || prior_context_length) {
- TextBreakIterator* break_iterator = Get(prior_context_length);
- if (break_iterator) {
- next_break =
- break_iterator->following(i - 1 + prior_context_length);
+ if (i || prior_context.length) {
+ if (TextBreakIterator* break_iterator = GetIterator(prior_context)) {
+ // Adjust the offset by |start_offset_| because |break_iterator| has
+ // text after |start_offset_|.
+ DCHECK_GE(i + prior_context.length, start_offset_);
+ next_break = break_iterator->following(
+ i - 1 + prior_context.length - start_offset_);
if (next_break >= 0) {
- next_break -= prior_context_length;
+ next_break = next_break + start_offset_ - prior_context.length;
}
}
}
@@ -411,9 +411,13 @@ inline int LazyLineBreakIterator::NextBreakablePosition(int pos,
}
int LazyLineBreakIterator::NextBreakablePositionBreakCharacter(int pos) const {
- NonSharedCharacterBreakIterator iterator(string_);
+ DCHECK_LE(start_offset_, string_.length());
+ NonSharedCharacterBreakIterator iterator(StringView(string_, start_offset_));
+ DCHECK_GE(pos, 0);
+ DCHECK_GE(static_cast<unsigned>(pos), start_offset_);
+ pos -= start_offset_;
int next = iterator.Following(std::max(pos - 1, 0));
- return next != kTextBreakDone ? next : string_.length();
+ return next != kTextBreakDone ? next + start_offset_ : string_.length();
}
int LazyLineBreakIterator::NextBreakablePosition(int pos,
@@ -446,6 +450,14 @@ unsigned LazyLineBreakIterator::NextBreakOpportunity(unsigned offset) const {
return next_break;
}
+unsigned LazyLineBreakIterator::NextBreakOpportunity(unsigned offset,
+ unsigned len) const {
+ DCHECK_LE(len, string_.length());
+ int next_break = NextBreakablePosition(offset, break_type_, len);
+ DCHECK_GE(next_break, 0);
+ return next_break;
+}
+
unsigned LazyLineBreakIterator::PreviousBreakOpportunity(unsigned offset,
unsigned min) const {
unsigned pos = std::min(offset, string_.length());
diff --git a/chromium/third_party/blink/renderer/platform/text/text_break_iterator.h b/chromium/third_party/blink/renderer/platform/text/text_break_iterator.h
index 958e3f844d6..f7f02ebcb29 100644
--- a/chromium/third_party/blink/renderer/platform/text/text_break_iterator.h
+++ b/chromium/third_party/blink/renderer/platform/text/text_break_iterator.h
@@ -121,8 +121,6 @@ class PLATFORM_EXPORT LazyLineBreakIterator final {
public:
LazyLineBreakIterator()
: iterator_(nullptr),
- cached_prior_context_(nullptr),
- cached_prior_context_length_(0),
break_type_(LineBreakType::kNormal) {
ResetPriorContext();
}
@@ -133,8 +131,6 @@ class PLATFORM_EXPORT LazyLineBreakIterator final {
: string_(string),
locale_(locale),
iterator_(nullptr),
- cached_prior_context_(nullptr),
- cached_prior_context_length_(0),
break_type_(break_type) {
ResetPriorContext();
}
@@ -179,55 +175,42 @@ class PLATFORM_EXPORT LazyLineBreakIterator final {
prior_context_[1] = 0;
}
- unsigned PriorContextLength() const {
- unsigned prior_context_length = 0;
+ struct PriorContext {
+ const UChar* text = nullptr;
+ unsigned length = 0;
+ };
+
+ PriorContext GetPriorContext() const {
static_assert(arraysize(prior_context_) == 2,
"TextBreakIterator has unexpected prior context length");
if (prior_context_[1]) {
- ++prior_context_length;
if (prior_context_[0])
- ++prior_context_length;
+ return PriorContext{&prior_context_[0], 2};
+ return PriorContext{&prior_context_[1], 1};
}
- return prior_context_length;
+ return PriorContext{nullptr, 0};
}
- // Obtain text break iterator, possibly previously cached, where this iterator
- // is (or has been) initialized to use the previously stored string as the
- // primary breaking context and using previously stored prior context if
- // non-empty.
- TextBreakIterator* Get(unsigned prior_context_length) const {
- DCHECK(prior_context_length <= kPriorContextCapacity);
- const UChar* prior_context =
- prior_context_length
- ? &prior_context_[kPriorContextCapacity - prior_context_length]
- : nullptr;
- if (!iterator_) {
- if (string_.Is8Bit())
- iterator_ = AcquireLineBreakIterator(
- string_.Characters8(), string_.length(), locale_, prior_context,
- prior_context_length);
- else
- iterator_ = AcquireLineBreakIterator(
- string_.Characters16(), string_.length(), locale_, prior_context,
- prior_context_length);
- cached_prior_context_ = prior_context;
- cached_prior_context_length_ = prior_context_length;
- } else if (prior_context != cached_prior_context_ ||
- prior_context_length != cached_prior_context_length_) {
- ReleaseIterator();
- return Get(prior_context_length);
- }
- return iterator_;
- }
+ unsigned PriorContextLength() const { return GetPriorContext().length; }
void ResetStringAndReleaseIterator(String string,
const AtomicString& locale) {
string_ = string;
+ start_offset_ = 0;
locale_ = locale;
ReleaseIterator();
}
+ // Set the start offset. Text before this offset is disregarded. Properly
+ // setting the start offset improves the performance significantly, because
+ // ICU break iterator computes all the text from the beginning.
+ void SetStartOffset(unsigned offset) {
+ CHECK_LE(offset, string_.length());
+ start_offset_ = offset;
+ ReleaseIterator();
+ }
+
void SetLocale(const AtomicString& locale) {
if (locale == locale_)
return;
@@ -254,12 +237,19 @@ class PLATFORM_EXPORT LazyLineBreakIterator final {
}
inline bool IsBreakable(int pos) const {
- int next_breakable = -1;
- return IsBreakable(pos, next_breakable, break_type_);
+ // No need to scan the entire string for the next breakable position when
+ // all we need to determine is whether the current position is breakable.
+ // Limit length to pos + 1.
+ // TODO(layout-dev): We should probably try to break out an actual
+ // IsBreakable method from NextBreakablePosition and get rid of this hack.
+ int len = std::min(pos + 1, static_cast<int>(string_.length()));
+ int next_breakable = NextBreakablePosition(pos, break_type_, len);
+ return pos == next_breakable;
}
// Returns the break opportunity at or after |offset|.
unsigned NextBreakOpportunity(unsigned offset) const;
+ unsigned NextBreakOpportunity(unsigned offset, unsigned len) const;
// Returns the break opportunity at or before |offset|.
unsigned PreviousBreakOpportunity(unsigned offset, unsigned min = 0) const;
@@ -274,8 +264,45 @@ class PLATFORM_EXPORT LazyLineBreakIterator final {
if (iterator_)
ReleaseLineBreakIterator(iterator_);
iterator_ = nullptr;
- cached_prior_context_ = nullptr;
- cached_prior_context_length_ = 0;
+ cached_prior_context_.text = nullptr;
+ cached_prior_context_.length = 0;
+ }
+
+ // Obtain text break iterator, possibly previously cached, where this iterator
+ // is (or has been) initialized to use the previously stored string as the
+ // primary breaking context and using previously stored prior context if
+ // non-empty.
+ TextBreakIterator* GetIterator(const PriorContext& prior_context) const {
+ DCHECK(prior_context.length <= kPriorContextCapacity);
+ if (iterator_) {
+ if (prior_context.length == cached_prior_context_.length) {
+ DCHECK_EQ(prior_context.text, cached_prior_context_.text);
+ return iterator_;
+ }
+ ReleaseIterator();
+ }
+
+ // Create the iterator, or get one from the cache, for the text after
+ // |start_offset_|. Because ICU TextBreakIterator computes all characters
+ // from the beginning of the given text, using |start_offset_| improves the
+ // performance significantly.
+ //
+ // For this reason, the offset for the TextBreakIterator must be adjusted by
+ // |start_offset_|.
+ cached_prior_context_ = prior_context;
+ CHECK_LE(start_offset_, string_.length());
+ if (string_.Is8Bit()) {
+ iterator_ =
+ AcquireLineBreakIterator(string_.Characters8() + start_offset_,
+ string_.length() - start_offset_, locale_,
+ prior_context.text, prior_context.length);
+ } else {
+ iterator_ =
+ AcquireLineBreakIterator(string_.Characters16() + start_offset_,
+ string_.length() - start_offset_, locale_,
+ prior_context.text, prior_context.length);
+ }
+ return iterator_;
}
template <typename CharacterType, LineBreakType, BreakSpaceType>
@@ -293,8 +320,8 @@ class PLATFORM_EXPORT LazyLineBreakIterator final {
AtomicString locale_;
mutable TextBreakIterator* iterator_;
UChar prior_context_[kPriorContextCapacity];
- mutable const UChar* cached_prior_context_;
- mutable unsigned cached_prior_context_length_;
+ mutable PriorContext cached_prior_context_;
+ unsigned start_offset_ = 0;
LineBreakType break_type_;
BreakSpaceType break_space_ = BreakSpaceType::kBeforeEverySpace;
};
@@ -308,7 +335,7 @@ class PLATFORM_EXPORT NonSharedCharacterBreakIterator final {
STACK_ALLOCATED();
public:
- explicit NonSharedCharacterBreakIterator(const String&);
+ explicit NonSharedCharacterBreakIterator(const StringView&);
NonSharedCharacterBreakIterator(const UChar*, unsigned length);
~NonSharedCharacterBreakIterator();
@@ -365,9 +392,7 @@ PLATFORM_EXPORT unsigned LengthOfGraphemeCluster(const String&, unsigned = 0);
// Returns a list of graphemes cluster at each character using character break
// rules.
-PLATFORM_EXPORT void GraphemesClusterList(String text,
- unsigned start,
- unsigned length,
+PLATFORM_EXPORT void GraphemesClusterList(const StringView& text,
Vector<unsigned>* graphemes);
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/text/text_break_iterator_icu.cc b/chromium/third_party/blink/renderer/platform/text/text_break_iterator_icu.cc
index 327c6f9a9e1..1a5c8e0bb48 100644
--- a/chromium/third_party/blink/renderer/platform/text/text_break_iterator_icu.cc
+++ b/chromium/third_party/blink/renderer/platform/text/text_break_iterator_icu.cc
@@ -751,7 +751,7 @@ static TextBreakIterator* GetNonSharedCharacterBreakIterator() {
}
NonSharedCharacterBreakIterator::NonSharedCharacterBreakIterator(
- const String& string)
+ const StringView& string)
: is8_bit_(true),
charaters8_(nullptr),
offset_(0),
diff --git a/chromium/third_party/blink/renderer/platform/text/text_break_iterator_test.cc b/chromium/third_party/blink/renderer/platform/text/text_break_iterator_test.cc
index fd23955285d..cd52e2e5864 100644
--- a/chromium/third_party/blink/renderer/platform/text/text_break_iterator_test.cc
+++ b/chromium/third_party/blink/renderer/platform/text/text_break_iterator_test.cc
@@ -75,7 +75,7 @@ class TextBreakIteratorTest : public testing::Test {
unsigned start,
unsigned length) {
Vector<unsigned> result;
- ::blink::GraphemesClusterList(input, start, length, &result);
+ ::blink::GraphemesClusterList(StringView(input, start, length), &result);
return result;
}
@@ -291,6 +291,10 @@ TEST_F(TextBreakIteratorTest, GraphemesClusterListTest) {
// NO ZWJ on this sequence.
EXPECT_EQ(GraphemesClusterList(u"🏳🌈", 0, 4),
Vector<unsigned>({0, 0, 1, 1}));
+
+ // ARABIC LETTER MEEM + ARABIC FATHA
+ EXPECT_EQ(GraphemesClusterList(u"\u0645\u064E", 0, 2),
+ Vector<unsigned>({0, 0}));
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/text/text_run.cc b/chromium/third_party/blink/renderer/platform/text/text_run.cc
index 74782e83b62..9f3ad6b1ae9 100644
--- a/chromium/third_party/blink/renderer/platform/text/text_run.cc
+++ b/chromium/third_party/blink/renderer/platform/text/text_run.cc
@@ -83,11 +83,6 @@ String TextRun::NormalizedUTF16() const {
} else if (Character::TreatAsSpace(character) &&
character != kNoBreakSpaceCharacter) {
character = kSpaceCharacter;
- } else if (!RuntimeEnabledFeatures::
- RenderUnicodeControlCharactersEnabled() &&
- Character::LegacyTreatAsZeroWidthSpaceInComplexScript(
- character)) {
- character = kZeroWidthSpaceCharacter;
} else if (Character::TreatAsZeroWidthSpaceInComplexScript(character)) {
character = kZeroWidthSpaceCharacter;
}
diff --git a/chromium/third_party/blink/renderer/platform/text/text_run.h b/chromium/third_party/blink/renderer/platform/text/text_run.h
index e2522c3f33b..df07c6f3915 100644
--- a/chromium/third_party/blink/renderer/platform/text/text_run.h
+++ b/chromium/third_party/blink/renderer/platform/text/text_run.h
@@ -174,6 +174,11 @@ class PLATFORM_EXPORT TextRun final {
return data_.characters16;
}
+ StringView ToStringView() const {
+ return Is8Bit() ? StringView(data_.characters8, len_)
+ : StringView(data_.characters16, len_);
+ }
+
UChar32 CodepointAt(unsigned i) const {
SECURITY_DCHECK(i < len_);
if (Is8Bit())
diff --git a/chromium/third_party/blink/renderer/platform/timer_test.cc b/chromium/third_party/blink/renderer/platform/timer_test.cc
index 3ba86fac13c..faa55590af6 100644
--- a/chromium/third_party/blink/renderer/platform/timer_test.cc
+++ b/chromium/third_party/blink/renderer/platform/timer_test.cc
@@ -12,7 +12,6 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_thread.h"
-#include "third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
@@ -21,6 +20,7 @@
#include "third_party/blink/renderer/platform/wtf/time.h"
using base::sequence_manager::TaskQueue;
+using blink::scheduler::MainThreadTaskQueue;
using testing::ElementsAre;
namespace blink {
@@ -28,6 +28,14 @@ namespace {
class TimerTest : public testing::Test {
public:
+ TimerTest() {
+ scoped_refptr<MainThreadTaskQueue> task_queue =
+ platform_->GetMainThreadScheduler()->NewTaskQueue(
+ MainThreadTaskQueue::QueueCreationParams(
+ MainThreadTaskQueue::QueueType::kTest));
+ task_runner_ = task_queue->CreateTaskRunner(TaskType::kInternalTest);
+ }
+
void SetUp() override {
run_times_.clear();
platform_->AdvanceClock(TimeDelta::FromSeconds(10));
@@ -63,12 +71,17 @@ class TimerTest : public testing::Test {
return true;
}
+ scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() {
+ return task_runner_;
+ }
+
protected:
TimeTicks start_time_;
WTF::Vector<TimeTicks> run_times_;
WTF::Vector<TimeTicks> next_fire_times_;
ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
platform_;
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
base::MessageLoop message_loop_;
};
@@ -119,16 +132,16 @@ class OnHeapTimerOwner final
};
class GCForbiddenScope final {
- public:
STACK_ALLOCATED();
+
+ public:
GCForbiddenScope() { ThreadState::Current()->EnterGCForbiddenScope(); }
~GCForbiddenScope() { ThreadState::Current()->LeaveGCForbiddenScope(); }
};
TEST_F(TimerTest, StartOneShot_Zero) {
- TaskRunnerTimer<TimerTest> timer(
- platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this,
- &TimerTest::CountingTask);
+ TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this,
+ &TimerTest::CountingTask);
timer.StartOneShot(TimeDelta(), FROM_HERE);
TimeDelta run_time;
@@ -139,9 +152,8 @@ TEST_F(TimerTest, StartOneShot_Zero) {
}
TEST_F(TimerTest, StartOneShot_ZeroAndCancel) {
- TaskRunnerTimer<TimerTest> timer(
- platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this,
- &TimerTest::CountingTask);
+ TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this,
+ &TimerTest::CountingTask);
timer.StartOneShot(TimeDelta(), FROM_HERE);
TimeDelta run_time;
@@ -154,9 +166,8 @@ TEST_F(TimerTest, StartOneShot_ZeroAndCancel) {
}
TEST_F(TimerTest, StartOneShot_ZeroAndCancelThenRepost) {
- TaskRunnerTimer<TimerTest> timer(
- platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this,
- &TimerTest::CountingTask);
+ TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this,
+ &TimerTest::CountingTask);
timer.StartOneShot(TimeDelta(), FROM_HERE);
TimeDelta run_time;
@@ -176,9 +187,8 @@ TEST_F(TimerTest, StartOneShot_ZeroAndCancelThenRepost) {
}
TEST_F(TimerTest, StartOneShot_Zero_RepostingAfterRunning) {
- TaskRunnerTimer<TimerTest> timer(
- platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this,
- &TimerTest::CountingTask);
+ TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this,
+ &TimerTest::CountingTask);
timer.StartOneShot(TimeDelta(), FROM_HERE);
TimeDelta run_time;
@@ -196,9 +206,8 @@ TEST_F(TimerTest, StartOneShot_Zero_RepostingAfterRunning) {
}
TEST_F(TimerTest, StartOneShot_NonZero) {
- TaskRunnerTimer<TimerTest> timer(
- platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this,
- &TimerTest::CountingTask);
+ TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this,
+ &TimerTest::CountingTask);
timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE);
TimeDelta run_time;
@@ -211,9 +220,8 @@ TEST_F(TimerTest, StartOneShot_NonZero) {
}
TEST_F(TimerTest, StartOneShot_NonZeroAndCancel) {
- TaskRunnerTimer<TimerTest> timer(
- platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this,
- &TimerTest::CountingTask);
+ TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this,
+ &TimerTest::CountingTask);
timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE);
TimeDelta run_time;
@@ -228,9 +236,8 @@ TEST_F(TimerTest, StartOneShot_NonZeroAndCancel) {
}
TEST_F(TimerTest, StartOneShot_NonZeroAndCancelThenRepost) {
- TaskRunnerTimer<TimerTest> timer(
- platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this,
- &TimerTest::CountingTask);
+ TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this,
+ &TimerTest::CountingTask);
timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE);
TimeDelta run_time;
@@ -255,9 +262,8 @@ TEST_F(TimerTest, StartOneShot_NonZeroAndCancelThenRepost) {
}
TEST_F(TimerTest, StartOneShot_NonZero_RepostingAfterRunning) {
- TaskRunnerTimer<TimerTest> timer(
- platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this,
- &TimerTest::CountingTask);
+ TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this,
+ &TimerTest::CountingTask);
timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE);
TimeDelta run_time;
@@ -280,9 +286,8 @@ TEST_F(TimerTest, StartOneShot_NonZero_RepostingAfterRunning) {
}
TEST_F(TimerTest, PostingTimerTwiceWithSameRunTimeDoesNothing) {
- TaskRunnerTimer<TimerTest> timer(
- platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this,
- &TimerTest::CountingTask);
+ TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this,
+ &TimerTest::CountingTask);
timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE);
timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE);
@@ -296,9 +301,8 @@ TEST_F(TimerTest, PostingTimerTwiceWithSameRunTimeDoesNothing) {
}
TEST_F(TimerTest, PostingTimerTwiceWithNewerRunTimeCancelsOriginalTask) {
- TaskRunnerTimer<TimerTest> timer(
- platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this,
- &TimerTest::CountingTask);
+ TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this,
+ &TimerTest::CountingTask);
timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE);
timer.StartOneShot(TimeDelta(), FROM_HERE);
@@ -307,9 +311,8 @@ TEST_F(TimerTest, PostingTimerTwiceWithNewerRunTimeCancelsOriginalTask) {
}
TEST_F(TimerTest, PostingTimerTwiceWithLaterRunTimeCancelsOriginalTask) {
- TaskRunnerTimer<TimerTest> timer(
- platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this,
- &TimerTest::CountingTask);
+ TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this,
+ &TimerTest::CountingTask);
timer.StartOneShot(TimeDelta(), FROM_HERE);
timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE);
@@ -319,9 +322,8 @@ TEST_F(TimerTest, PostingTimerTwiceWithLaterRunTimeCancelsOriginalTask) {
}
TEST_F(TimerTest, StartRepeatingTask) {
- TaskRunnerTimer<TimerTest> timer(
- platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this,
- &TimerTest::CountingTask);
+ TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this,
+ &TimerTest::CountingTask);
timer.StartRepeating(TimeDelta::FromSeconds(1), FROM_HERE);
TimeDelta run_time;
@@ -337,9 +339,8 @@ TEST_F(TimerTest, StartRepeatingTask) {
}
TEST_F(TimerTest, StartRepeatingTask_ThenCancel) {
- TaskRunnerTimer<TimerTest> timer(
- platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this,
- &TimerTest::CountingTask);
+ TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this,
+ &TimerTest::CountingTask);
timer.StartRepeating(TimeDelta::FromSeconds(1), FROM_HERE);
TimeDelta run_time;
@@ -358,9 +359,8 @@ TEST_F(TimerTest, StartRepeatingTask_ThenCancel) {
}
TEST_F(TimerTest, StartRepeatingTask_ThenPostOneShot) {
- TaskRunnerTimer<TimerTest> timer(
- platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this,
- &TimerTest::CountingTask);
+ TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this,
+ &TimerTest::CountingTask);
timer.StartRepeating(TimeDelta::FromSeconds(1), FROM_HERE);
TimeDelta run_time;
@@ -381,44 +381,39 @@ TEST_F(TimerTest, StartRepeatingTask_ThenPostOneShot) {
}
TEST_F(TimerTest, IsActive_NeverPosted) {
- TaskRunnerTimer<TimerTest> timer(
- platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this,
- &TimerTest::CountingTask);
+ TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this,
+ &TimerTest::CountingTask);
EXPECT_FALSE(timer.IsActive());
}
TEST_F(TimerTest, IsActive_AfterPosting_OneShotZero) {
- TaskRunnerTimer<TimerTest> timer(
- platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this,
- &TimerTest::CountingTask);
+ TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this,
+ &TimerTest::CountingTask);
timer.StartOneShot(TimeDelta(), FROM_HERE);
EXPECT_TRUE(timer.IsActive());
}
TEST_F(TimerTest, IsActive_AfterPosting_OneShotNonZero) {
- TaskRunnerTimer<TimerTest> timer(
- platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this,
- &TimerTest::CountingTask);
+ TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this,
+ &TimerTest::CountingTask);
timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE);
EXPECT_TRUE(timer.IsActive());
}
TEST_F(TimerTest, IsActive_AfterPosting_Repeating) {
- TaskRunnerTimer<TimerTest> timer(
- platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this,
- &TimerTest::CountingTask);
+ TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this,
+ &TimerTest::CountingTask);
timer.StartRepeating(TimeDelta::FromSeconds(1), FROM_HERE);
EXPECT_TRUE(timer.IsActive());
}
TEST_F(TimerTest, IsActive_AfterRunning_OneShotZero) {
- TaskRunnerTimer<TimerTest> timer(
- platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this,
- &TimerTest::CountingTask);
+ TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this,
+ &TimerTest::CountingTask);
timer.StartOneShot(TimeDelta(), FROM_HERE);
platform_->RunUntilIdle();
@@ -426,9 +421,8 @@ TEST_F(TimerTest, IsActive_AfterRunning_OneShotZero) {
}
TEST_F(TimerTest, IsActive_AfterRunning_OneShotNonZero) {
- TaskRunnerTimer<TimerTest> timer(
- platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this,
- &TimerTest::CountingTask);
+ TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this,
+ &TimerTest::CountingTask);
timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE);
platform_->RunUntilIdle();
@@ -436,9 +430,8 @@ TEST_F(TimerTest, IsActive_AfterRunning_OneShotNonZero) {
}
TEST_F(TimerTest, IsActive_AfterRunning_Repeating) {
- TaskRunnerTimer<TimerTest> timer(
- platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this,
- &TimerTest::CountingTask);
+ TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this,
+ &TimerTest::CountingTask);
timer.StartRepeating(TimeDelta::FromSeconds(1), FROM_HERE);
RunUntilDeadline(start_time_ + TimeDelta::FromSeconds(10));
@@ -446,18 +439,16 @@ TEST_F(TimerTest, IsActive_AfterRunning_Repeating) {
}
TEST_F(TimerTest, NextFireInterval_OneShotZero) {
- TaskRunnerTimer<TimerTest> timer(
- platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this,
- &TimerTest::CountingTask);
+ TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this,
+ &TimerTest::CountingTask);
timer.StartOneShot(TimeDelta(), FROM_HERE);
EXPECT_TRUE(timer.NextFireInterval().is_zero());
}
TEST_F(TimerTest, NextFireInterval_OneShotNonZero) {
- TaskRunnerTimer<TimerTest> timer(
- platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this,
- &TimerTest::CountingTask);
+ TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this,
+ &TimerTest::CountingTask);
timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE);
EXPECT_EQ(TimeDelta::FromSeconds(10), timer.NextFireInterval());
@@ -466,9 +457,8 @@ TEST_F(TimerTest, NextFireInterval_OneShotNonZero) {
TEST_F(TimerTest, NextFireInterval_OneShotNonZero_AfterAFewSeconds) {
platform_->SetAutoAdvanceNowToPendingTasks(false);
- TaskRunnerTimer<TimerTest> timer(
- platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this,
- &TimerTest::CountingTask);
+ TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this,
+ &TimerTest::CountingTask);
timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE);
platform_->AdvanceClock(TimeDelta::FromSeconds(2));
@@ -476,53 +466,47 @@ TEST_F(TimerTest, NextFireInterval_OneShotNonZero_AfterAFewSeconds) {
}
TEST_F(TimerTest, NextFireInterval_Repeating) {
- TaskRunnerTimer<TimerTest> timer(
- platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this,
- &TimerTest::CountingTask);
+ TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this,
+ &TimerTest::CountingTask);
timer.StartRepeating(TimeDelta::FromSeconds(20), FROM_HERE);
EXPECT_EQ(TimeDelta::FromSeconds(20), timer.NextFireInterval());
}
TEST_F(TimerTest, RepeatInterval_NeverStarted) {
- TaskRunnerTimer<TimerTest> timer(
- platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this,
- &TimerTest::CountingTask);
+ TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this,
+ &TimerTest::CountingTask);
EXPECT_TRUE(timer.RepeatInterval().is_zero());
}
TEST_F(TimerTest, RepeatInterval_OneShotZero) {
- TaskRunnerTimer<TimerTest> timer(
- platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this,
- &TimerTest::CountingTask);
+ TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this,
+ &TimerTest::CountingTask);
timer.StartOneShot(TimeDelta(), FROM_HERE);
EXPECT_TRUE(timer.RepeatInterval().is_zero());
}
TEST_F(TimerTest, RepeatInterval_OneShotNonZero) {
- TaskRunnerTimer<TimerTest> timer(
- platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this,
- &TimerTest::CountingTask);
+ TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this,
+ &TimerTest::CountingTask);
timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE);
EXPECT_TRUE(timer.RepeatInterval().is_zero());
}
TEST_F(TimerTest, RepeatInterval_Repeating) {
- TaskRunnerTimer<TimerTest> timer(
- platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this,
- &TimerTest::CountingTask);
+ TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this,
+ &TimerTest::CountingTask);
timer.StartRepeating(TimeDelta::FromSeconds(20), FROM_HERE);
EXPECT_EQ(TimeDelta::FromSeconds(20), timer.RepeatInterval());
}
TEST_F(TimerTest, AugmentRepeatInterval) {
- TaskRunnerTimer<TimerTest> timer(
- platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this,
- &TimerTest::CountingTask);
+ TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this,
+ &TimerTest::CountingTask);
timer.StartRepeating(TimeDelta::FromSeconds(10), FROM_HERE);
EXPECT_EQ(TimeDelta::FromSeconds(10), timer.RepeatInterval());
EXPECT_EQ(TimeDelta::FromSeconds(10), timer.NextFireInterval());
@@ -542,9 +526,8 @@ TEST_F(TimerTest, AugmentRepeatInterval) {
TEST_F(TimerTest, AugmentRepeatInterval_TimerFireDelayed) {
platform_->SetAutoAdvanceNowToPendingTasks(false);
- TaskRunnerTimer<TimerTest> timer(
- platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this,
- &TimerTest::CountingTask);
+ TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this,
+ &TimerTest::CountingTask);
timer.StartRepeating(TimeDelta::FromSeconds(10), FROM_HERE);
EXPECT_EQ(TimeDelta::FromSeconds(10), timer.RepeatInterval());
EXPECT_EQ(TimeDelta::FromSeconds(10), timer.NextFireInterval());
@@ -561,9 +544,8 @@ TEST_F(TimerTest, AugmentRepeatInterval_TimerFireDelayed) {
TEST_F(TimerTest, RepeatingTimerDoesNotDrift) {
platform_->SetAutoAdvanceNowToPendingTasks(false);
- TaskRunnerTimer<TimerTest> timer(
- platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this,
- &TimerTest::RecordNextFireTimeTask);
+ TaskRunnerTimer<TimerTest> timer(GetTaskRunner(), this,
+ &TimerTest::RecordNextFireTimeTask);
timer.StartRepeating(TimeDelta::FromSeconds(2), FROM_HERE);
RecordNextFireTimeTask(
@@ -618,26 +600,24 @@ class TimerForTest : public TaskRunnerTimer<TimerFiredClass> {
};
TEST_F(TimerTest, UserSuppliedTaskRunner) {
- scoped_refptr<TaskQueue> task_runner(
+ scoped_refptr<MainThreadTaskQueue> task_queue(
platform_->GetMainThreadScheduler()->NewTimerTaskQueue(
scheduler::MainThreadTaskQueue::QueueType::kFrameThrottleable,
nullptr));
- scoped_refptr<scheduler::TaskQueueWithTaskType> task_queue_with_task_type =
- scheduler::TaskQueueWithTaskType::Create(task_runner,
- TaskType::kInternalTest);
- TimerForTest<TimerTest> timer(task_queue_with_task_type, this,
- &TimerTest::CountingTask);
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner =
+ task_queue->CreateTaskRunner(TaskType::kInternalTest);
+ TimerForTest<TimerTest> timer(task_runner, this, &TimerTest::CountingTask);
timer.StartOneShot(TimeDelta(), FROM_HERE);
// Make sure the task was posted on taskRunner.
- EXPECT_FALSE(task_runner->IsEmpty());
+ EXPECT_FALSE(task_queue->IsEmpty());
}
TEST_F(TimerTest, RunOnHeapTimer) {
scoped_refptr<OnHeapTimerOwner::Record> record =
OnHeapTimerOwner::Record::Create();
- Persistent<OnHeapTimerOwner> owner = new OnHeapTimerOwner(
- record, platform_->GetMainThreadScheduler()->DefaultTaskRunner());
+ Persistent<OnHeapTimerOwner> owner =
+ new OnHeapTimerOwner(record, GetTaskRunner());
owner->StartOneShot(TimeDelta(), FROM_HERE);
@@ -649,8 +629,8 @@ TEST_F(TimerTest, RunOnHeapTimer) {
TEST_F(TimerTest, DestructOnHeapTimer) {
scoped_refptr<OnHeapTimerOwner::Record> record =
OnHeapTimerOwner::Record::Create();
- Persistent<OnHeapTimerOwner> owner = new OnHeapTimerOwner(
- record, platform_->GetMainThreadScheduler()->DefaultTaskRunner());
+ Persistent<OnHeapTimerOwner> owner =
+ new OnHeapTimerOwner(record, GetTaskRunner());
record->Dispose();
owner->StartOneShot(TimeDelta(), FROM_HERE);
@@ -669,8 +649,8 @@ TEST_F(TimerTest, DestructOnHeapTimer) {
TEST_F(TimerTest, MarkOnHeapTimerAsUnreachable) {
scoped_refptr<OnHeapTimerOwner::Record> record =
OnHeapTimerOwner::Record::Create();
- Persistent<OnHeapTimerOwner> owner = new OnHeapTimerOwner(
- record, platform_->GetMainThreadScheduler()->DefaultTaskRunner());
+ Persistent<OnHeapTimerOwner> owner =
+ new OnHeapTimerOwner(record, GetTaskRunner());
record->Dispose();
owner->StartOneShot(TimeDelta(), FROM_HERE);
@@ -715,28 +695,25 @@ class TaskObserver : public base::MessageLoop::TaskObserver {
TEST_F(TimerTest, MoveToNewTaskRunnerOneShot) {
std::vector<scoped_refptr<base::SingleThreadTaskRunner>> run_order;
- scoped_refptr<TaskQueue> task_runner1(
+ scoped_refptr<MainThreadTaskQueue> task_queue1(
platform_->GetMainThreadScheduler()->NewTimerTaskQueue(
scheduler::MainThreadTaskQueue::QueueType::kFrameThrottleable,
nullptr));
- scoped_refptr<scheduler::TaskQueueWithTaskType> task_queue_with_task_type1 =
- scheduler::TaskQueueWithTaskType::Create(task_runner1,
- TaskType::kInternalTest);
- TaskObserver task_observer1(task_queue_with_task_type1, &run_order);
- task_runner1->AddTaskObserver(&task_observer1);
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner1 =
+ task_queue1->CreateTaskRunner(TaskType::kInternalTest);
+ TaskObserver task_observer1(task_runner1, &run_order);
+ task_queue1->AddTaskObserver(&task_observer1);
- scoped_refptr<TaskQueue> task_runner2(
+ scoped_refptr<MainThreadTaskQueue> task_queue2(
platform_->GetMainThreadScheduler()->NewTimerTaskQueue(
scheduler::MainThreadTaskQueue::QueueType::kFrameThrottleable,
nullptr));
- scoped_refptr<scheduler::TaskQueueWithTaskType> task_queue_with_task_type2 =
- scheduler::TaskQueueWithTaskType::Create(task_runner2,
- TaskType::kInternalTest);
- TaskObserver task_observer2(task_queue_with_task_type2, &run_order);
- task_runner2->AddTaskObserver(&task_observer2);
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner2 =
+ task_queue2->CreateTaskRunner(TaskType::kInternalTest);
+ TaskObserver task_observer2(task_runner2, &run_order);
+ task_queue2->AddTaskObserver(&task_observer2);
- TimerForTest<TimerTest> timer(task_queue_with_task_type1, this,
- &TimerTest::CountingTask);
+ TimerForTest<TimerTest> timer(task_runner1, this, &TimerTest::CountingTask);
TimeTicks start_time = CurrentTimeTicks();
@@ -744,43 +721,40 @@ TEST_F(TimerTest, MoveToNewTaskRunnerOneShot) {
platform_->RunForPeriod(TimeDelta::FromMilliseconds(500));
- timer.MoveToNewTaskRunner(task_queue_with_task_type2);
+ timer.MoveToNewTaskRunner(task_runner2);
platform_->RunUntilIdle();
EXPECT_THAT(run_times_, ElementsAre(start_time + TimeDelta::FromSeconds(1)));
- EXPECT_THAT(run_order, ElementsAre(task_queue_with_task_type2));
+ EXPECT_THAT(run_order, ElementsAre(task_runner2));
- EXPECT_TRUE(task_runner1->IsEmpty());
- EXPECT_TRUE(task_runner2->IsEmpty());
+ EXPECT_TRUE(task_queue1->IsEmpty());
+ EXPECT_TRUE(task_queue2->IsEmpty());
}
TEST_F(TimerTest, MoveToNewTaskRunnerRepeating) {
std::vector<scoped_refptr<base::SingleThreadTaskRunner>> run_order;
- scoped_refptr<TaskQueue> task_runner1(
+ scoped_refptr<MainThreadTaskQueue> task_queue1(
platform_->GetMainThreadScheduler()->NewTimerTaskQueue(
scheduler::MainThreadTaskQueue::QueueType::kFrameThrottleable,
nullptr));
- scoped_refptr<scheduler::TaskQueueWithTaskType> task_queue_with_task_type1 =
- scheduler::TaskQueueWithTaskType::Create(task_runner1,
- TaskType::kInternalTest);
- TaskObserver task_observer1(task_queue_with_task_type1, &run_order);
- task_runner1->AddTaskObserver(&task_observer1);
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner1 =
+ task_queue1->CreateTaskRunner(TaskType::kInternalTest);
+ TaskObserver task_observer1(task_runner1, &run_order);
+ task_queue1->AddTaskObserver(&task_observer1);
- scoped_refptr<TaskQueue> task_runner2(
+ scoped_refptr<MainThreadTaskQueue> task_queue2(
platform_->GetMainThreadScheduler()->NewTimerTaskQueue(
scheduler::MainThreadTaskQueue::QueueType::kFrameThrottleable,
nullptr));
- scoped_refptr<scheduler::TaskQueueWithTaskType> task_queue_with_task_type2 =
- scheduler::TaskQueueWithTaskType::Create(task_runner2,
- TaskType::kInternalTest);
- TaskObserver task_observer2(task_queue_with_task_type2, &run_order);
- task_runner2->AddTaskObserver(&task_observer2);
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner2 =
+ task_queue2->CreateTaskRunner(TaskType::kInternalTest);
+ TaskObserver task_observer2(task_runner2, &run_order);
+ task_queue2->AddTaskObserver(&task_observer2);
- TimerForTest<TimerTest> timer(task_queue_with_task_type1, this,
- &TimerTest::CountingTask);
+ TimerForTest<TimerTest> timer(task_runner1, this, &TimerTest::CountingTask);
TimeTicks start_time = CurrentTimeTicks();
@@ -788,7 +762,7 @@ TEST_F(TimerTest, MoveToNewTaskRunnerRepeating) {
platform_->RunForPeriod(TimeDelta::FromMilliseconds(2500));
- timer.MoveToNewTaskRunner(task_queue_with_task_type2);
+ timer.MoveToNewTaskRunner(task_runner2);
platform_->RunForPeriod(TimeDelta::FromSeconds(2));
@@ -797,41 +771,36 @@ TEST_F(TimerTest, MoveToNewTaskRunnerRepeating) {
start_time + TimeDelta::FromSeconds(3),
start_time + TimeDelta::FromSeconds(4)));
- EXPECT_THAT(
- run_order,
- ElementsAre(task_queue_with_task_type1, task_queue_with_task_type1,
- task_queue_with_task_type2, task_queue_with_task_type2));
+ EXPECT_THAT(run_order, ElementsAre(task_runner1, task_runner1, task_runner2,
+ task_runner2));
- EXPECT_TRUE(task_runner1->IsEmpty());
- EXPECT_FALSE(task_runner2->IsEmpty());
+ EXPECT_TRUE(task_queue1->IsEmpty());
+ EXPECT_FALSE(task_queue2->IsEmpty());
}
// This test checks that when inactive timer is moved to a different task
// runner it isn't activated.
TEST_F(TimerTest, MoveToNewTaskRunnerWithoutTasks) {
- scoped_refptr<TaskQueue> task_runner1(
+ scoped_refptr<MainThreadTaskQueue> task_queue1(
platform_->GetMainThreadScheduler()->NewTimerTaskQueue(
scheduler::MainThreadTaskQueue::QueueType::kFrameThrottleable,
nullptr));
- scoped_refptr<scheduler::TaskQueueWithTaskType> task_queue_with_task_type1 =
- scheduler::TaskQueueWithTaskType::Create(task_runner1,
- TaskType::kInternalTest);
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner1 =
+ task_queue1->CreateTaskRunner(TaskType::kInternalTest);
- scoped_refptr<TaskQueue> task_runner2(
+ scoped_refptr<MainThreadTaskQueue> task_queue2(
platform_->GetMainThreadScheduler()->NewTimerTaskQueue(
scheduler::MainThreadTaskQueue::QueueType::kFrameThrottleable,
nullptr));
- scoped_refptr<scheduler::TaskQueueWithTaskType> task_queue_with_task_type2 =
- scheduler::TaskQueueWithTaskType::Create(task_runner2,
- TaskType::kInternalTest);
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner2 =
+ task_queue2->CreateTaskRunner(TaskType::kInternalTest);
- TimerForTest<TimerTest> timer(task_queue_with_task_type1, this,
- &TimerTest::CountingTask);
+ TimerForTest<TimerTest> timer(task_runner1, this, &TimerTest::CountingTask);
platform_->RunUntilIdle();
EXPECT_TRUE(!run_times_.size());
- EXPECT_TRUE(task_runner1->IsEmpty());
- EXPECT_TRUE(task_runner2->IsEmpty());
+ EXPECT_TRUE(task_queue1->IsEmpty());
+ EXPECT_TRUE(task_queue2->IsEmpty());
}
} // namespace
diff --git a/chromium/third_party/blink/renderer/platform/transforms/DEPS b/chromium/third_party/blink/renderer/platform/transforms/DEPS
index ab3e5b684bd..ab6d0043cfd 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/DEPS
+++ b/chromium/third_party/blink/renderer/platform/transforms/DEPS
@@ -6,7 +6,6 @@ include_rules = [
"+third_party/blink/renderer/platform/transforms",
# Dependencies.
- "+third_party/blink/renderer/platform/animation",
"+third_party/blink/renderer/platform/cpu/mips/common_macros_msa.h",
"+third_party/blink/renderer/platform/geometry",
"+third_party/blink/renderer/platform/json",
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 531d274d7eb..5cc3d0ca48b 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
@@ -33,7 +33,6 @@ scoped_refptr<TransformOperation> MatrixTransformOperation::Blend(
return this;
// convert the TransformOperations into matrices
- FloatSize size;
TransformationMatrix from_t;
TransformationMatrix to_t(a_, b_, c_, d_, e_, f_);
if (from) {
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 48d89c48e2e..a5753ed38cc 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
@@ -25,7 +25,7 @@
#include "third_party/blink/renderer/platform/transforms/perspective_transform_operation.h"
-#include "third_party/blink/renderer/platform/animation/animation_utilities.h"
+#include "third_party/blink/renderer/platform/geometry/blend.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
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 def305a3293..3f8852f0afe 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
@@ -21,7 +21,7 @@
#include "third_party/blink/renderer/platform/transforms/rotate_transform_operation.h"
-#include "third_party/blink/renderer/platform/animation/animation_utilities.h"
+#include "third_party/blink/renderer/platform/geometry/blend.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/platform/transforms/rotation.cc b/chromium/third_party/blink/renderer/platform/transforms/rotation.cc
index eb4fb2d8deb..ff9482444d6 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/rotation.cc
+++ b/chromium/third_party/blink/renderer/platform/transforms/rotation.cc
@@ -21,7 +21,7 @@
#include "third_party/blink/renderer/platform/transforms/rotation.h"
-#include "third_party/blink/renderer/platform/animation/animation_utilities.h"
+#include "third_party/blink/renderer/platform/geometry/blend.h"
#include "third_party/blink/renderer/platform/transforms/transformation_matrix.h"
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 7b6d5ce438c..24a08849c2a 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
@@ -21,7 +21,7 @@
#include "third_party/blink/renderer/platform/transforms/scale_transform_operation.h"
-#include "third_party/blink/renderer/platform/animation/animation_utilities.h"
+#include "third_party/blink/renderer/platform/geometry/blend.h"
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 608716022d2..bf9558488a3 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
@@ -21,7 +21,7 @@
#include "third_party/blink/renderer/platform/transforms/skew_transform_operation.h"
-#include "third_party/blink/renderer/platform/animation/animation_utilities.h"
+#include "third_party/blink/renderer/platform/geometry/blend.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/platform/transforms/transform_operations.cc b/chromium/third_party/blink/renderer/platform/transforms/transform_operations.cc
index 77b56ea934b..5e8c1cff290 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/transform_operations.cc
+++ b/chromium/third_party/blink/renderer/platform/transforms/transform_operations.cc
@@ -22,7 +22,7 @@
#include "third_party/blink/renderer/platform/transforms/transform_operations.h"
#include <algorithm>
-#include "third_party/blink/renderer/platform/animation/animation_utilities.h"
+#include "third_party/blink/renderer/platform/geometry/blend.h"
#include "third_party/blink/renderer/platform/geometry/float_box.h"
#include "third_party/blink/renderer/platform/transforms/identity_transform_operation.h"
#include "third_party/blink/renderer/platform/transforms/interpolated_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 88488a05c70..aaf95cd8530 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
@@ -21,7 +21,7 @@
#include "third_party/blink/renderer/platform/transforms/translate_transform_operation.h"
-#include "third_party/blink/renderer/platform/animation/animation_utilities.h"
+#include "third_party/blink/renderer/platform/geometry/blend.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/platform/ukm_time_aggregator.cc b/chromium/third_party/blink/renderer/platform/ukm_time_aggregator.cc
index 9a4dd175c6a..3dab37cbd9d 100644
--- a/chromium/third_party/blink/renderer/platform/ukm_time_aggregator.cc
+++ b/chromium/third_party/blink/renderer/platform/ukm_time_aggregator.cc
@@ -31,7 +31,7 @@ UkmTimeAggregator::ScopedUkmTimer::ScopedUkmTimer(ScopedUkmTimer&& other)
}
UkmTimeAggregator::ScopedUkmTimer::~ScopedUkmTimer() {
- if (aggregator_) {
+ if (aggregator_ && base::TimeTicks::IsHighResolution()) {
aggregator_->RecordSample(metric_index_, start_time_, CurrentTimeTicks(),
histogram_counter_);
}
diff --git a/chromium/third_party/blink/renderer/platform/ukm_time_aggregator_test.cc b/chromium/third_party/blink/renderer/platform/ukm_time_aggregator_test.cc
index c6f7f450095..99ad4f022df 100644
--- a/chromium/third_party/blink/renderer/platform/ukm_time_aggregator_test.cc
+++ b/chromium/third_party/blink/renderer/platform/ukm_time_aggregator_test.cc
@@ -21,6 +21,12 @@ const char* kMetric2Average = "Paint.Average";
const char* kMetric2WorstCase = "Paint.WorstCase";
TEST(UkmTimeAggregatorTest, EmptyEventsNotRecorded) {
+ // 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;
+
WTF::ScopedMockClock clock;
ukm::TestUkmRecorder recorder;
int64_t source_id = ukm::UkmRecorder::GetNewSourceID();
@@ -35,6 +41,12 @@ TEST(UkmTimeAggregatorTest, EmptyEventsNotRecorded) {
}
TEST(UkmTimeAggregatorTest, EventsRecordedPerSecond) {
+ // 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;
+
WTF::ScopedMockClock clock;
ukm::TestUkmRecorder recorder;
int64_t source_id = ukm::UkmRecorder::GetNewSourceID();
@@ -83,6 +95,12 @@ TEST(UkmTimeAggregatorTest, EventsRecordedPerSecond) {
}
TEST(UkmTimeAggregatorTest, EventsAveragedCorrectly) {
+ // 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;
+
WTF::ScopedMockClock clock;
ukm::TestUkmRecorder recorder;
int64_t source_id = ukm::UkmRecorder::GetNewSourceID();
diff --git a/chromium/third_party/blink/renderer/platform/waitable_event.cc b/chromium/third_party/blink/renderer/platform/waitable_event.cc
index 677113badc3..453b9ac1d25 100644
--- a/chromium/third_party/blink/renderer/platform/waitable_event.cc
+++ b/chromium/third_party/blink/renderer/platform/waitable_event.cc
@@ -7,7 +7,6 @@
#include <vector>
#include "base/optional.h"
#include "base/synchronization/waitable_event.h"
-#include "third_party/blink/renderer/platform/heap/safe_point.h"
#include "third_party/blink/renderer/platform/heap/thread_state.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/platform/waitable_event.h b/chromium/third_party/blink/renderer/platform/waitable_event.h
index 214a07ddca8..bdaaeda4752 100644
--- a/chromium/third_party/blink/renderer/platform/waitable_event.h
+++ b/chromium/third_party/blink/renderer/platform/waitable_event.h
@@ -41,11 +41,11 @@ class WaitableEvent;
namespace blink {
-// TODO(crbug.com/796799): Deprecate blink::WaitableEvent and use
-// base::WaitableEvent instead.
+// DEPRECATED, use base::WaitableEvent instead of blink::WaitableEvent.
//
// Provides a thread synchronization that can be used to allow one thread to
// wait until another thread to finish some work.
+// TODO(crbug.com/796799): Remove this class in favor of base::WaitableEvent.
class PLATFORM_EXPORT WaitableEvent {
public:
// If ResetPolicy::Manual is specified on creation, to set the event state
diff --git a/chromium/third_party/blink/renderer/platform/web_icon_sizes_parser.cc b/chromium/third_party/blink/renderer/platform/web_icon_sizes_parser.cc
index 9784162d598..c0d15778358 100644
--- a/chromium/third_party/blink/renderer/platform/web_icon_sizes_parser.cc
+++ b/chromium/third_party/blink/renderer/platform/web_icon_sizes_parser.cc
@@ -33,9 +33,8 @@ static bool IsNonDigit(UChar c) {
return !IsASCIIDigit(c);
}
-static inline size_t FindEndOfWord(const String& string, size_t start) {
- return std::min(string.Find(IsWhitespace, start),
- static_cast<size_t>(string.length()));
+static inline wtf_size_t FindEndOfWord(const String& string, wtf_size_t start) {
+ return std::min(string.Find(IsWhitespace, start), string.length());
}
static inline int PartialStringToInt(const String& string,
@@ -61,8 +60,7 @@ WebVector<WebSize> WebIconSizesParser::ParseIconSizes(
unsigned length = sizes_string.length();
for (unsigned i = 0; i < length; ++i) {
// Skip whitespaces.
- i = std::min(sizes_string.Find(IsNotWhitespace, i),
- static_cast<size_t>(length));
+ i = std::min(sizes_string.Find(IsNotWhitespace, i), length);
if (i >= length)
break;
@@ -80,7 +78,7 @@ WebVector<WebSize> WebIconSizesParser::ParseIconSizes(
continue;
}
unsigned width_start = i;
- i = std::min(sizes_string.Find(IsNonDigit, i), static_cast<size_t>(length));
+ i = std::min(sizes_string.Find(IsNonDigit, i), length);
if (i >= length || (sizes_string[i] != 'x' && sizes_string[i] != 'X')) {
i = FindEndOfWord(sizes_string, i);
continue;
@@ -93,7 +91,7 @@ WebVector<WebSize> WebIconSizesParser::ParseIconSizes(
continue;
}
unsigned height_start = i;
- i = std::min(sizes_string.Find(IsNonDigit, i), static_cast<size_t>(length));
+ i = std::min(sizes_string.Find(IsNonDigit, i), length);
if (i < length && !IsWhitespace(sizes_string[i])) {
i = FindEndOfWord(sizes_string, i);
continue;
diff --git a/chromium/third_party/blink/renderer/platform/web_task_runner.cc b/chromium/third_party/blink/renderer/platform/web_task_runner.cc
index 818c8870194..261a0bc03dc 100644
--- a/chromium/third_party/blink/renderer/platform/web_task_runner.cc
+++ b/chromium/third_party/blink/renderer/platform/web_task_runner.cc
@@ -80,6 +80,14 @@ struct CallbackCancellationTraits<
const blink::TaskHandle& handle) {
return !handle.IsActive();
}
+
+ static bool MaybeValid(RunnerMethodType,
+ const base::WeakPtr<blink::TaskHandle::Runner>&,
+ const blink::TaskHandle& handle) {
+ // TODO(https://crbug.com/653394): Consider returning a thread-safe best
+ // guess of validity.
+ return true;
+ }
};
} // namespace base
diff --git a/chromium/third_party/blink/renderer/platform/web_thread_supporting_gc.cc b/chromium/third_party/blink/renderer/platform/web_thread_supporting_gc.cc
index fd0cd5f9958..74c9740dc4b 100644
--- a/chromium/third_party/blink/renderer/platform/web_thread_supporting_gc.cc
+++ b/chromium/third_party/blink/renderer/platform/web_thread_supporting_gc.cc
@@ -7,7 +7,6 @@
#include <memory>
#include "base/memory/ptr_util.h"
-#include "third_party/blink/renderer/platform/heap/safe_point.h"
#include "third_party/blink/renderer/platform/memory_coordinator.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
#include "third_party/blink/renderer/platform/wtf/threading.h"
@@ -36,11 +35,17 @@ WebThreadSupportingGC::WebThreadSupportingGC(
WTF::WillCreateThread();
#endif
if (!thread_) {
- // If |thread| is not given, create a new one and own it.
// TODO(scheduler-dev): AnimationWorklet can pass nullptr as WebThread*
// reference when a test doesn't have a compositor thread.
- owning_thread_ = Platform::Current()->CreateThread(
- params ? *params : WebThreadCreationParams(WebThreadType::kTestThread));
+ if (params->thread_type == WebThreadType::kAudioWorkletThread) {
+ owning_thread_ = Platform::Current()->CreateWebAudioThread();
+ } else {
+ // If |thread| is not given, create a new one and own it.
+ owning_thread_ =
+ Platform::Current()->CreateThread(params
+ ? *params
+ : WebThreadCreationParams(WebThreadType::kTestThread));
+ }
thread_ = owning_thread_.get();
}
MemoryCoordinator::Instance().RegisterThread(thread_);
diff --git a/chromium/third_party/blink/renderer/platform/weborigin/DEPS b/chromium/third_party/blink/renderer/platform/weborigin/DEPS
index b33b9de59b3..46fd51d8a00 100644
--- a/chromium/third_party/blink/renderer/platform/weborigin/DEPS
+++ b/chromium/third_party/blink/renderer/platform/weborigin/DEPS
@@ -9,6 +9,9 @@ include_rules = [
# net/ includes should be allowed only in a limited set of directories,
# so we have separate DEPS from platform's one.
"+net/base",
+ "+services/network/public/cpp/cors/origin_access_entry.h",
+ "+services/network/public/cpp/cors/origin_access_list.h",
+ "+services/network/public/mojom/cors_origin_pattern.mojom-shared.h",
"+third_party/blink/renderer/platform/blob/blob_url.h",
"+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/weborigin/kurl_test.cc b/chromium/third_party/blink/renderer/platform/weborigin/kurl_test.cc
index bafdb256be9..47df890a9f5 100644
--- a/chromium/third_party/blink/renderer/platform/weborigin/kurl_test.cc
+++ b/chromium/third_party/blink/renderer/platform/weborigin/kurl_test.cc
@@ -248,10 +248,12 @@ TEST(KURLTest, DecodeURLEscapeSequences) {
EXPECT_EQ(String(kDecodedExpected, arraysize(kDecodedExpected)), decoded);
// Test the error behavior for invalid UTF-8 (we differ from WebKit here).
+ // %e4 %a0 are invalid for UTF-8, but %e5%a5%bd is valid.
String invalid = DecodeURLEscapeSequences("%e4%a0%e5%a5%bd");
- UChar invalid_expected_helper[4] = {0x00e4, 0x00a0, 0x597d, 0};
+ UChar invalid_expected_helper[6] = {0x00e4, 0x00a0, 0x00e5,
+ 0x00a5, 0x00bd, 0};
String invalid_expected(
- reinterpret_cast<const ::UChar*>(invalid_expected_helper), 3);
+ reinterpret_cast<const ::UChar*>(invalid_expected_helper), 5);
EXPECT_EQ(invalid_expected, invalid);
}
diff --git a/chromium/third_party/blink/renderer/platform/weborigin/origin_access_entry.cc b/chromium/third_party/blink/renderer/platform/weborigin/origin_access_entry.cc
index 37220fd5888..9e729629a8c 100644
--- a/chromium/third_party/blink/renderer/platform/weborigin/origin_access_entry.cc
+++ b/chromium/third_party/blink/renderer/platform/weborigin/origin_access_entry.cc
@@ -30,143 +30,32 @@
#include "third_party/blink/renderer/platform/weborigin/origin_access_entry.h"
-#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
-#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
-#include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h"
-#include "url/third_party/mozilla/url_parse.h"
-#include "url/url_canon.h"
namespace blink {
-namespace {
+OriginAccessEntry::OriginAccessEntry(
+ const String& protocol,
+ const String& host,
+ network::cors::OriginAccessEntry::MatchMode match_mode)
+ : private_(std::string(protocol.Utf8().data()),
+ std::string(host.Utf8().data()),
+ match_mode) {}
-// TODO(mkwst): This basically replicates GURL::HostIsIPAddress. If/when
-// we re-evaluate everything after merging the Blink and Chromium
-// repositories, perhaps we can just use that directly.
-bool HostIsIPAddress(const String& host) {
- if (host.IsEmpty())
- return false;
+OriginAccessEntry::OriginAccessEntry(OriginAccessEntry&& from) = default;
- String protocol("https://");
- KURL url(NullURL(), protocol + host + "/");
- if (!url.IsValid())
- return false;
-
- url::RawCanonOutputT<char, 128> ignored_output;
- url::CanonHostInfo host_info;
- url::Component host_component(0,
- static_cast<int>(url.Host().Utf8().length()));
- url::CanonicalizeIPAddress(url.Host().Utf8().data(), host_component,
- &ignored_output, &host_info);
- return host_info.IsIPAddress();
-}
-
-bool IsSubdomainOfHost(const String& subdomain, const String& host) {
- if (subdomain.length() <= host.length())
- return false;
-
- if (subdomain[subdomain.length() - host.length() - 1] != '.')
- return false;
-
- if (!subdomain.EndsWith(host))
- return false;
-
- return true;
-}
-} // namespace
-
-OriginAccessEntry::OriginAccessEntry(const String& protocol,
- const String& host,
- SubdomainSetting subdomain_setting)
- : protocol_(protocol),
- host_(host),
- subdomain_settings_(subdomain_setting),
- host_is_public_suffix_(false) {
- DCHECK(subdomain_setting >= kAllowSubdomains ||
- subdomain_setting <= kDisallowSubdomains);
-
- host_is_ip_address_ = blink::HostIsIPAddress(host);
-
- // Look for top-level domains, either with or without an additional dot.
- if (!host_is_ip_address_) {
- // Blink passes some things that aren't technically hosts like "*.foo", so
- // use the permissive variant.
- size_t public_suffix_length =
- net::registry_controlled_domains::PermissiveGetHostRegistryLength(
- StringUTF8Adaptor(host_).AsStringPiece(),
- net::registry_controlled_domains::INCLUDE_UNKNOWN_REGISTRIES,
- net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
- if (public_suffix_length == 0)
- public_suffix_length = host_.length();
-
- if (host_.length() <= public_suffix_length + 1) {
- host_is_public_suffix_ = true;
- } else if (subdomain_setting == kAllowRegisterableDomains &&
- public_suffix_length) {
- // The "2" in the next line is 1 for the '.', plus a 1-char minimum label
- // length.
- const size_t dot =
- host_.ReverseFind('.', host_.length() - public_suffix_length - 2);
- if (dot == kNotFound)
- registerable_domain_ = host;
- else
- registerable_domain_ = host.Substring(dot + 1);
- }
- }
-}
-
-OriginAccessEntry::MatchResult OriginAccessEntry::MatchesOrigin(
+network::cors::OriginAccessEntry::MatchResult OriginAccessEntry::MatchesOrigin(
const SecurityOrigin& origin) const {
- if (protocol_ != origin.Protocol())
- return kDoesNotMatchOrigin;
-
- return MatchesDomain(origin);
+ return private_.MatchesOrigin(origin.ToUrlOrigin());
}
-OriginAccessEntry::MatchResult OriginAccessEntry::MatchesDomain(
+network::cors::OriginAccessEntry::MatchResult OriginAccessEntry::MatchesDomain(
const SecurityOrigin& origin) const {
- // Special case: Include subdomains and empty host means "all hosts, including
- // ip addresses".
- if (subdomain_settings_ != kDisallowSubdomains && host_.IsEmpty())
- return kMatchesOrigin;
-
- // Exact match.
- if (host_ == origin.Host())
- return kMatchesOrigin;
-
- // Don't try to do subdomain matching on IP addresses.
- if (host_is_ip_address_)
- return kDoesNotMatchOrigin;
-
- // Match subdomains.
- switch (subdomain_settings_) {
- case kDisallowSubdomains:
- return kDoesNotMatchOrigin;
-
- case kAllowSubdomains:
- if (!IsSubdomainOfHost(origin.Host(), host_))
- return kDoesNotMatchOrigin;
- break;
-
- case kAllowRegisterableDomains:
- // Fall back to a simple subdomain check if no registerable domain could
- // be found:
- if (registerable_domain_.IsEmpty()) {
- if (!IsSubdomainOfHost(origin.Host(), host_))
- return kDoesNotMatchOrigin;
- } else if (registerable_domain_ != origin.Host() &&
- !IsSubdomainOfHost(origin.Host(), registerable_domain_)) {
- return kDoesNotMatchOrigin;
- }
- break;
- };
-
- if (host_is_public_suffix_)
- return kMatchesOriginButIsPublicSuffix;
+ return private_.MatchesDomain(origin.ToUrlOrigin());
+}
- return kMatchesOrigin;
+bool OriginAccessEntry::HostIsIPAddress() const {
+ return private_.host_is_ip_address();
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/weborigin/origin_access_entry.h b/chromium/third_party/blink/renderer/platform/weborigin/origin_access_entry.h
index 73212c78e66..037cae51e59 100644
--- a/chromium/third_party/blink/renderer/platform/weborigin/origin_access_entry.h
+++ b/chromium/third_party/blink/renderer/platform/weborigin/origin_access_entry.h
@@ -31,6 +31,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WEBORIGIN_ORIGIN_ACCESS_ENTRY_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WEBORIGIN_ORIGIN_ACCESS_ENTRY_H_
+#include "services/network/public/cpp/cors/origin_access_entry.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -39,66 +40,34 @@ namespace blink {
class SecurityOrigin;
+// A class to wrap network::cors::OriginAccessEntry to use with Blink types.
class PLATFORM_EXPORT OriginAccessEntry {
USING_FAST_MALLOC(OriginAccessEntry);
public:
- enum SubdomainSetting {
- // 'www.example.com' matches an OriginAccessEntry for 'example.com'
- kAllowSubdomains,
-
- // 'www.example.com' matches an OriginAccessEntry for 'not-www.example.com'
- kAllowRegisterableDomains,
-
- // 'www.example.com' does not match an OriginAccessEntry for 'example.com'
- kDisallowSubdomains
- };
-
- enum MatchResult {
- kMatchesOrigin,
- kMatchesOriginButIsPublicSuffix,
- kDoesNotMatchOrigin
- };
-
- // If host is empty string and SubdomainSetting is not DisallowSubdomains, the
- // entry will match all domains in the specified protocol.
+ // If host is empty string and MatchMode is not DisallowSubdomains, the entry
+ // will match all domains in the specified protocol.
// IPv6 addresses must include brackets (e.g.
// '[2001:db8:85a3::8a2e:370:7334]', not '2001:db8:85a3::8a2e:370:7334').
OriginAccessEntry(const String& protocol,
const String& host,
- SubdomainSetting);
+ network::cors::OriginAccessEntry::MatchMode);
+ OriginAccessEntry(OriginAccessEntry&& from);
// 'matchesOrigin' requires a protocol match (e.g. 'http' != 'https').
// 'matchesDomain' relaxes this constraint.
- MatchResult MatchesOrigin(const SecurityOrigin&) const;
- MatchResult MatchesDomain(const SecurityOrigin&) const;
+ network::cors::OriginAccessEntry::MatchResult MatchesOrigin(
+ const SecurityOrigin&) const;
+ network::cors::OriginAccessEntry::MatchResult MatchesDomain(
+ const SecurityOrigin&) const;
- const String& Protocol() const { return protocol_; }
- const String& Host() const { return host_; }
- SubdomainSetting SubdomainSettings() const { return subdomain_settings_; }
- bool HostIsIPAddress() const { return host_is_ip_address_; }
- const String& Registerable() const { return registerable_domain_; }
+ bool HostIsIPAddress() const;
private:
- String protocol_;
- String host_;
- String registerable_domain_;
- SubdomainSetting subdomain_settings_;
- bool host_is_ip_address_;
- bool host_is_public_suffix_;
-};
-
-PLATFORM_EXPORT inline bool operator==(const OriginAccessEntry& a,
- const OriginAccessEntry& b) {
- return EqualIgnoringASCIICase(a.Protocol(), b.Protocol()) &&
- EqualIgnoringASCIICase(a.Host(), b.Host()) &&
- a.SubdomainSettings() == b.SubdomainSettings();
-}
+ network::cors::OriginAccessEntry private_;
-PLATFORM_EXPORT inline bool operator!=(const OriginAccessEntry& a,
- const OriginAccessEntry& b) {
- return !(a == b);
-}
+ DISALLOW_COPY_AND_ASSIGN(OriginAccessEntry);
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/weborigin/origin_access_entry_test.cc b/chromium/third_party/blink/renderer/platform/weborigin/origin_access_entry_test.cc
deleted file mode 100644
index 9bfe18073ed..00000000000
--- a/chromium/third_party/blink/renderer/platform/weborigin/origin_access_entry_test.cc
+++ /dev/null
@@ -1,330 +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/renderer/platform/weborigin/origin_access_entry.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
-#include "third_party/blink/renderer/platform/weborigin/kurl.h"
-#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
-
-namespace blink {
-
-TEST(OriginAccessEntryTest, PublicSuffixListTest) {
- scoped_refptr<const SecurityOrigin> origin =
- SecurityOrigin::CreateFromString("http://www.google.com");
- OriginAccessEntry entry1("http", "google.com",
- OriginAccessEntry::kAllowSubdomains);
- OriginAccessEntry entry2("http", "hamster.com",
- OriginAccessEntry::kAllowSubdomains);
- OriginAccessEntry entry3("http", "com", OriginAccessEntry::kAllowSubdomains);
- EXPECT_EQ(OriginAccessEntry::kMatchesOrigin, entry1.MatchesOrigin(*origin));
- EXPECT_EQ(OriginAccessEntry::kDoesNotMatchOrigin,
- entry2.MatchesOrigin(*origin));
- EXPECT_EQ(OriginAccessEntry::kMatchesOriginButIsPublicSuffix,
- entry3.MatchesOrigin(*origin));
-}
-
-TEST(OriginAccessEntryTest, AllowSubdomainsTest) {
- struct TestCase {
- const char* protocol;
- const char* host;
- const char* origin;
- OriginAccessEntry::MatchResult expected_origin;
- OriginAccessEntry::MatchResult expected_domain;
- } inputs[] = {
- {"http", "example.com", "http://example.com/",
- OriginAccessEntry::kMatchesOrigin, OriginAccessEntry::kMatchesOrigin},
- {"http", "example.com", "http://www.example.com/",
- OriginAccessEntry::kMatchesOrigin, OriginAccessEntry::kMatchesOrigin},
- {"http", "example.com", "http://www.www.example.com/",
- OriginAccessEntry::kMatchesOrigin, OriginAccessEntry::kMatchesOrigin},
- {"http", "www.example.com", "http://example.com/",
- OriginAccessEntry::kDoesNotMatchOrigin,
- OriginAccessEntry::kDoesNotMatchOrigin},
- {"http", "www.example.com", "http://www.example.com/",
- OriginAccessEntry::kMatchesOrigin, OriginAccessEntry::kMatchesOrigin},
- {"http", "www.example.com", "http://www.www.example.com/",
- OriginAccessEntry::kMatchesOrigin, OriginAccessEntry::kMatchesOrigin},
- {"http", "com", "http://example.com/",
- OriginAccessEntry::kMatchesOriginButIsPublicSuffix,
- OriginAccessEntry::kMatchesOriginButIsPublicSuffix},
- {"http", "com", "http://www.example.com/",
- OriginAccessEntry::kMatchesOriginButIsPublicSuffix,
- OriginAccessEntry::kMatchesOriginButIsPublicSuffix},
- {"http", "com", "http://www.www.example.com/",
- OriginAccessEntry::kMatchesOriginButIsPublicSuffix,
- OriginAccessEntry::kMatchesOriginButIsPublicSuffix},
- {"https", "example.com", "http://example.com/",
- OriginAccessEntry::kDoesNotMatchOrigin,
- OriginAccessEntry::kMatchesOrigin},
- {"https", "example.com", "http://www.example.com/",
- OriginAccessEntry::kDoesNotMatchOrigin,
- OriginAccessEntry::kMatchesOrigin},
- {"https", "example.com", "http://www.www.example.com/",
- OriginAccessEntry::kDoesNotMatchOrigin,
- OriginAccessEntry::kMatchesOrigin},
- {"http", "example.com", "http://beispiel.de/",
- OriginAccessEntry::kDoesNotMatchOrigin,
- OriginAccessEntry::kDoesNotMatchOrigin},
- {"http", "example.com", "https://beispiel.de/",
- OriginAccessEntry::kDoesNotMatchOrigin,
- OriginAccessEntry::kDoesNotMatchOrigin},
- {"http", "", "http://example.com/", OriginAccessEntry::kMatchesOrigin,
- OriginAccessEntry::kMatchesOrigin},
- {"http", "", "http://beispiel.de/", OriginAccessEntry::kMatchesOrigin,
- OriginAccessEntry::kMatchesOrigin},
- {"https", "", "http://beispiel.de/",
- OriginAccessEntry::kDoesNotMatchOrigin,
- OriginAccessEntry::kMatchesOrigin},
- };
-
- for (const auto& test : inputs) {
- SCOPED_TRACE(testing::Message()
- << "Host: " << test.host << ", Origin: " << test.origin);
- scoped_refptr<const SecurityOrigin> origin_to_test =
- SecurityOrigin::CreateFromString(test.origin);
- OriginAccessEntry entry1(test.protocol, test.host,
- OriginAccessEntry::kAllowSubdomains);
- EXPECT_EQ(test.expected_origin, entry1.MatchesOrigin(*origin_to_test));
- EXPECT_EQ(test.expected_domain, entry1.MatchesDomain(*origin_to_test));
- }
-}
-
-TEST(OriginAccessEntryTest, AllowRegisterableDomainsTest) {
- struct TestCase {
- const char* protocol;
- const char* host;
- const char* origin;
- OriginAccessEntry::MatchResult expected;
- } inputs[] = {
- {"http", "example.com", "http://example.com/",
- OriginAccessEntry::kMatchesOrigin},
- {"http", "example.com", "http://www.example.com/",
- OriginAccessEntry::kMatchesOrigin},
- {"http", "example.com", "http://www.www.example.com/",
- OriginAccessEntry::kMatchesOrigin},
- {"http", "www.example.com", "http://example.com/",
- OriginAccessEntry::kMatchesOrigin},
- {"http", "www.example.com", "http://www.example.com/",
- OriginAccessEntry::kMatchesOrigin},
- {"http", "www.example.com", "http://www.www.example.com/",
- OriginAccessEntry::kMatchesOrigin},
- {"http", "com", "http://example.com/",
- OriginAccessEntry::kMatchesOriginButIsPublicSuffix},
- {"http", "com", "http://www.example.com/",
- OriginAccessEntry::kMatchesOriginButIsPublicSuffix},
- {"http", "com", "http://www.www.example.com/",
- OriginAccessEntry::kMatchesOriginButIsPublicSuffix},
- {"https", "example.com", "http://example.com/",
- OriginAccessEntry::kDoesNotMatchOrigin},
- {"https", "example.com", "http://www.example.com/",
- OriginAccessEntry::kDoesNotMatchOrigin},
- {"https", "example.com", "http://www.www.example.com/",
- OriginAccessEntry::kDoesNotMatchOrigin},
- {"http", "example.com", "http://beispiel.de/",
- OriginAccessEntry::kDoesNotMatchOrigin},
- {"http", "", "http://example.com/", OriginAccessEntry::kMatchesOrigin},
- {"http", "", "http://beispiel.de/", OriginAccessEntry::kMatchesOrigin},
- {"https", "", "http://beispiel.de/",
- OriginAccessEntry::kDoesNotMatchOrigin},
- };
-
- for (const auto& test : inputs) {
- scoped_refptr<const SecurityOrigin> origin_to_test =
- SecurityOrigin::CreateFromString(test.origin);
- OriginAccessEntry entry1(test.protocol, test.host,
- OriginAccessEntry::kAllowRegisterableDomains);
-
- SCOPED_TRACE(testing::Message()
- << "Host: " << test.host << ", Origin: " << test.origin
- << ", Domain: " << entry1.Registerable().Utf8().data());
- EXPECT_EQ(test.expected, entry1.MatchesOrigin(*origin_to_test));
- }
-}
-
-TEST(OriginAccessEntryTest, AllowRegisterableDomainsTestWithDottedSuffix) {
- struct TestCase {
- const char* protocol;
- const char* host;
- const char* origin;
- OriginAccessEntry::MatchResult expected;
- } inputs[] = {
- {"http", "example.appspot.com", "http://example.appspot.com/",
- OriginAccessEntry::kMatchesOrigin},
- {"http", "example.appspot.com", "http://www.example.appspot.com/",
- OriginAccessEntry::kMatchesOrigin},
- {"http", "example.appspot.com", "http://www.www.example.appspot.com/",
- OriginAccessEntry::kMatchesOrigin},
- {"http", "www.example.appspot.com", "http://example.appspot.com/",
- OriginAccessEntry::kMatchesOrigin},
- {"http", "www.example.appspot.com", "http://www.example.appspot.com/",
- OriginAccessEntry::kMatchesOrigin},
- {"http", "www.example.appspot.com", "http://www.www.example.appspot.com/",
- OriginAccessEntry::kMatchesOrigin},
- {"http", "appspot.com", "http://example.appspot.com/",
- OriginAccessEntry::kMatchesOriginButIsPublicSuffix},
- {"http", "appspot.com", "http://www.example.appspot.com/",
- OriginAccessEntry::kMatchesOriginButIsPublicSuffix},
- {"http", "appspot.com", "http://www.www.example.appspot.com/",
- OriginAccessEntry::kMatchesOriginButIsPublicSuffix},
- {"https", "example.appspot.com", "http://example.appspot.com/",
- OriginAccessEntry::kDoesNotMatchOrigin},
- {"https", "example.appspot.com", "http://www.example.appspot.com/",
- OriginAccessEntry::kDoesNotMatchOrigin},
- {"https", "example.appspot.com", "http://www.www.example.appspot.com/",
- OriginAccessEntry::kDoesNotMatchOrigin},
- {"http", "example.appspot.com", "http://beispiel.de/",
- OriginAccessEntry::kDoesNotMatchOrigin},
- {"http", "", "http://example.appspot.com/",
- OriginAccessEntry::kMatchesOrigin},
- {"http", "", "http://beispiel.de/", OriginAccessEntry::kMatchesOrigin},
- {"https", "", "http://beispiel.de/",
- OriginAccessEntry::kDoesNotMatchOrigin},
- };
-
- for (const auto& test : inputs) {
- scoped_refptr<const SecurityOrigin> origin_to_test =
- SecurityOrigin::CreateFromString(test.origin);
- OriginAccessEntry entry1(test.protocol, test.host,
- OriginAccessEntry::kAllowRegisterableDomains);
-
- SCOPED_TRACE(testing::Message()
- << "Host: " << test.host << ", Origin: " << test.origin
- << ", Domain: " << entry1.Registerable().Utf8().data());
- EXPECT_EQ(test.expected, entry1.MatchesOrigin(*origin_to_test));
- }
-}
-
-TEST(OriginAccessEntryTest, DisallowSubdomainsTest) {
- struct TestCase {
- const char* protocol;
- const char* host;
- const char* origin;
- OriginAccessEntry::MatchResult expected;
- } inputs[] = {
- {"http", "example.com", "http://example.com/",
- OriginAccessEntry::kMatchesOrigin},
- {"http", "example.com", "http://www.example.com/",
- OriginAccessEntry::kDoesNotMatchOrigin},
- {"http", "example.com", "http://www.www.example.com/",
- OriginAccessEntry::kDoesNotMatchOrigin},
- {"http", "com", "http://example.com/",
- OriginAccessEntry::kDoesNotMatchOrigin},
- {"http", "com", "http://www.example.com/",
- OriginAccessEntry::kDoesNotMatchOrigin},
- {"http", "com", "http://www.www.example.com/",
- OriginAccessEntry::kDoesNotMatchOrigin},
- {"https", "example.com", "http://example.com/",
- OriginAccessEntry::kDoesNotMatchOrigin},
- {"https", "example.com", "http://www.example.com/",
- OriginAccessEntry::kDoesNotMatchOrigin},
- {"https", "example.com", "http://www.www.example.com/",
- OriginAccessEntry::kDoesNotMatchOrigin},
- {"http", "example.com", "http://beispiel.de/",
- OriginAccessEntry::kDoesNotMatchOrigin},
- {"http", "", "http://example.com/",
- OriginAccessEntry::kDoesNotMatchOrigin},
- {"http", "", "http://beispiel.de/",
- OriginAccessEntry::kDoesNotMatchOrigin},
- {"https", "", "http://beispiel.de/",
- OriginAccessEntry::kDoesNotMatchOrigin},
- };
-
- for (const auto& test : inputs) {
- SCOPED_TRACE(testing::Message()
- << "Host: " << test.host << ", Origin: " << test.origin);
- scoped_refptr<const SecurityOrigin> origin_to_test =
- SecurityOrigin::CreateFromString(test.origin);
- OriginAccessEntry entry1(test.protocol, test.host,
- OriginAccessEntry::kDisallowSubdomains);
- EXPECT_EQ(test.expected, entry1.MatchesOrigin(*origin_to_test));
- }
-}
-
-TEST(OriginAccessEntryTest, IPAddressTest) {
- struct TestCase {
- const char* protocol;
- const char* host;
- bool is_ip_address;
- } inputs[] = {
- {"http", "1.1.1.1", true},
- {"http", "1.1.1.1.1", false},
- {"http", "example.com", false},
- {"http", "hostname.that.ends.with.a.number1", false},
- {"http", "2001:db8::1", false},
- {"http", "[2001:db8::1]", true},
- {"http", "2001:db8::a", false},
- {"http", "[2001:db8::a]", true},
- {"http", "", false},
- };
-
- for (const auto& test : inputs) {
- SCOPED_TRACE(testing::Message() << "Host: " << test.host);
- OriginAccessEntry entry(test.protocol, test.host,
- OriginAccessEntry::kDisallowSubdomains);
- EXPECT_EQ(test.is_ip_address, entry.HostIsIPAddress()) << test.host;
- }
-}
-
-TEST(OriginAccessEntryTest, IPAddressMatchingTest) {
- struct TestCase {
- const char* protocol;
- const char* host;
- const char* origin;
- OriginAccessEntry::MatchResult expected;
- } inputs[] = {
- {"http", "192.0.0.123", "http://192.0.0.123/",
- OriginAccessEntry::kMatchesOrigin},
- {"http", "0.0.123", "http://192.0.0.123/",
- OriginAccessEntry::kDoesNotMatchOrigin},
- {"http", "0.123", "http://192.0.0.123/",
- OriginAccessEntry::kDoesNotMatchOrigin},
- {"http", "1.123", "http://192.0.0.123/",
- OriginAccessEntry::kDoesNotMatchOrigin},
- };
-
- for (const auto& test : inputs) {
- SCOPED_TRACE(testing::Message()
- << "Host: " << test.host << ", Origin: " << test.origin);
- scoped_refptr<const SecurityOrigin> origin_to_test =
- SecurityOrigin::CreateFromString(test.origin);
- OriginAccessEntry entry1(test.protocol, test.host,
- OriginAccessEntry::kAllowSubdomains);
- EXPECT_EQ(test.expected, entry1.MatchesOrigin(*origin_to_test));
-
- OriginAccessEntry entry2(test.protocol, test.host,
- OriginAccessEntry::kDisallowSubdomains);
- EXPECT_EQ(test.expected, entry2.MatchesOrigin(*origin_to_test));
- }
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/weborigin/referrer.h b/chromium/third_party/blink/renderer/platform/weborigin/referrer.h
index e94952ed5eb..aa577e33d14 100644
--- a/chromium/third_party/blink/renderer/platform/weborigin/referrer.h
+++ b/chromium/third_party/blink/renderer/platform/weborigin/referrer.h
@@ -45,7 +45,9 @@ struct Referrer {
DCHECK(referrer == NoReferrer() || KURL(NullURL(), referrer).IsValid());
}
Referrer() : referrer_policy(kReferrerPolicyDefault) {}
+ // We use these strings instead of "no-referrer" and "client" in the spec.
static String NoReferrer() { return String(); }
+ static String ClientReferrerString() { return "about:client"; }
AtomicString referrer;
ReferrerPolicy referrer_policy;
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 8b511f95242..a86de192760 100644
--- a/chromium/third_party/blink/renderer/platform/weborigin/scheme_registry.cc
+++ b/chromium/third_party/blink/renderer/platform/weborigin/scheme_registry.cc
@@ -224,11 +224,6 @@ bool SchemeRegistry::ShouldTreatURLSchemeAsNotAllowingJavascriptURLs(
scheme);
}
-void SchemeRegistry::RegisterURLSchemeAsCORSEnabled(const String& scheme) {
- DCHECK_EQ(scheme, scheme.LowerASCII());
- GetMutableURLSchemesRegistry().cors_enabled_schemes.insert(scheme);
-}
-
bool SchemeRegistry::ShouldTreatURLSchemeAsCORSEnabled(const String& scheme) {
DCHECK_EQ(scheme, scheme.LowerASCII());
if (scheme.IsEmpty())
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 09189d0ffc7..4676a712d39 100644
--- a/chromium/third_party/blink/renderer/platform/weborigin/scheme_registry.h
+++ b/chromium/third_party/blink/renderer/platform/weborigin/scheme_registry.h
@@ -87,12 +87,6 @@ class PLATFORM_EXPORT SchemeRegistry {
static bool ShouldTreatURLSchemeAsNotAllowingJavascriptURLs(
const String& scheme);
- // Allow non-HTTP schemes to be registered to allow CORS requests.
- // This is not used in Chromium anymore but left here intentionally
- // to allow other embedders of Blink to add more schemes
- // to the CORS-enabled schemes list.
- // As for now (Nov 2017) it is used by Electron.
- static void RegisterURLSchemeAsCORSEnabled(const String& scheme);
static bool ShouldTreatURLSchemeAsCORSEnabled(const String& scheme);
// Serialize the registered schemes in a comma-separated list.
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 2a11de1e2c6..7fc040b93ae 100644
--- a/chromium/third_party/blink/renderer/platform/weborigin/security_origin.cc
+++ b/chromium/third_party/blink/renderer/platform/weborigin/security_origin.cc
@@ -313,7 +313,7 @@ bool SecurityOrigin::CanRequest(const KURL& url) const {
if (IsSameSchemeHostPort(target_origin.get()))
return true;
- if (SecurityPolicy::IsAccessWhiteListed(this, target_origin.get()))
+ if (SecurityPolicy::IsOriginAccessAllowed(this, target_origin.get()))
return true;
return false;
@@ -341,13 +341,15 @@ bool SecurityOrigin::CanDisplay(const KURL& url) const {
if (SchemeRegistry::CanDisplayOnlyIfCanRequest(protocol))
return CanRequest(url);
- if (SchemeRegistry::ShouldTreatURLSchemeAsDisplayIsolated(protocol))
+ if (SchemeRegistry::ShouldTreatURLSchemeAsDisplayIsolated(protocol)) {
return protocol_ == protocol ||
- SecurityPolicy::IsAccessToURLWhiteListed(this, url);
+ SecurityPolicy::IsOriginAccessToURLAllowed(this, url);
+ }
- if (SchemeRegistry::ShouldTreatURLSchemeAsLocal(protocol))
+ if (SchemeRegistry::ShouldTreatURLSchemeAsLocal(protocol)) {
return CanLoadLocalResources() ||
- SecurityPolicy::IsAccessToURLWhiteListed(this, url);
+ SecurityPolicy::IsOriginAccessToURLAllowed(this, url);
+ }
return true;
}
@@ -358,8 +360,9 @@ bool SecurityOrigin::IsPotentiallyTrustworthy() const {
return is_opaque_origin_potentially_trustworthy_;
if (SchemeRegistry::ShouldTreatURLSchemeAsSecure(protocol_) || IsLocal() ||
- IsLocalhost())
+ IsLocalhost()) {
return true;
+ }
if (SecurityPolicy::IsOriginWhiteListedTrustworthy(*this))
return true;
@@ -438,6 +441,15 @@ void SecurityOrigin::BuildRawString(StringBuilder& builder) const {
}
}
+String SecurityOrigin::ToTokenForFastCheck() const {
+ if (SerializesAsNull())
+ return String();
+
+ StringBuilder result;
+ BuildRawString(result);
+ return result.ToString();
+}
+
scoped_refptr<SecurityOrigin> SecurityOrigin::CreateFromString(
const String& origin_string) {
return SecurityOrigin::Create(KURL(NullURL(), origin_string));
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 4101ef4e39c..d4b37b3f1f0 100644
--- a/chromium/third_party/blink/renderer/platform/weborigin/security_origin.h
+++ b/chromium/third_party/blink/renderer/platform/weborigin/security_origin.h
@@ -213,6 +213,21 @@ class PLATFORM_EXPORT SecurityOrigin : public RefCounted<SecurityOrigin> {
// could make the string return "null".
String ToRawString() const;
+ // Returns a token that helps distinguish origins, or null string. When not
+ // null string, the tokens are guaranteed to be different if not the same
+ // origin, i.e. if two tokens are the same and not null, the two
+ // SecurityOrigins are the same origin. Thus, tokens can be used for fast
+ // check of origins.
+ //
+ // This is pretty similar to ToString(), but this returns null string instead
+ // of "null", and includes a host part in case of file: scheme.
+ //
+ // Note that the same tokens only guarantee that the SecurityOrigins are
+ // the same origin and not the same origin-domain. See also:
+ // https://html.spec.whatwg.org/C/origin.html#same-origin
+ // https://html.spec.whatwg.org/C/origin.html#same-origin-domain
+ String ToTokenForFastCheck() const;
+
// This method checks for equality, ignoring the value of document.domain
// (and whether it was set) but considering the host. It is used for
// postMessage.
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 5c8d61a3ccd..0b344311c10 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
@@ -233,6 +233,8 @@ TEST_F(SecurityOriginTest, CanAccess) {
TestCase tests[] = {
{true, "https://foobar.com", "https://foobar.com"},
{false, "https://foobar.com", "https://bazbar.com"},
+ {true, "file://localhost/", "file://localhost/"},
+ {false, "file:///", "file://localhost/"},
};
for (size_t i = 0; i < arraysize(tests); ++i) {
@@ -241,6 +243,7 @@ TEST_F(SecurityOriginTest, CanAccess) {
scoped_refptr<const SecurityOrigin> origin2 =
SecurityOrigin::CreateFromString(tests[i].origin2);
EXPECT_EQ(tests[i].can_access, origin1->CanAccess(origin2.get()));
+ EXPECT_EQ(tests[i].can_access, origin2->CanAccess(origin1.get()));
}
}
@@ -271,7 +274,7 @@ TEST_F(SecurityOriginTest, CanRequestWithWhitelistedAccess) {
EXPECT_FALSE(origin->CanRequest(url));
// Adding the url to the access whitelist should allow the request.
- SecurityPolicy::AddOriginAccessWhitelistEntry(*origin, "https", "example.com",
+ SecurityPolicy::AddOriginAccessAllowListEntry(*origin, "https", "example.com",
false);
EXPECT_TRUE(origin->CanRequest(url));
}
@@ -504,4 +507,34 @@ TEST_F(SecurityOriginTest, EffectiveDomainSetFromDom) {
}
}
+TEST_F(SecurityOriginTest, ToTokenForFastCheck) {
+ constexpr struct {
+ const char* url;
+ const char* token;
+ } kTestCases[] = {
+ {"", nullptr},
+ {"null", nullptr},
+ {"data:text/plain,hello, world", nullptr},
+ {"http://example.org/foo/bar", "http://example.org"},
+ {"http://example.org:8080/foo/bar", "http://example.org:8080"},
+ {"https://example.org:443/foo/bar", "https://example.org"},
+ {"https://example.org:444/foo/bar", "https://example.org:444"},
+ {"file:///foo/bar", "file://"},
+ {"file://localhost/foo/bar", "file://localhost"},
+ {"filesystem:http://example.org:88/foo/bar", "http://example.org:88"},
+ // Somehow the host part in the inner URL is dropped.
+ // See https://crbug.com/867914 for details.
+ {"filesystem:file://localhost/foo/bar", "file://"},
+ {"blob:http://example.org:88/foo/bar", "http://example.org:88"},
+ {"blob:file://localhost/foo/bar", "file://localhost"},
+ };
+
+ for (const auto& test : kTestCases) {
+ SCOPED_TRACE(test.url);
+ scoped_refptr<const SecurityOrigin> origin =
+ SecurityOrigin::CreateFromString(test.url);
+ EXPECT_EQ(test.token, origin->ToTokenForFastCheck()) << test.token;
+ }
+}
+
} // 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 1147ed188da..5374e036a4d 100644
--- a/chromium/third_party/blink/renderer/platform/weborigin/security_policy.cc
+++ b/chromium/third_party/blink/renderer/platform/weborigin/security_policy.cc
@@ -31,121 +31,45 @@
#include <memory>
#include "base/strings/pattern.h"
+#include "services/network/public/cpp/cors/origin_access_list.h"
+#include "services/network/public/mojom/cors_origin_pattern.mojom-shared.h"
#include "third_party/blink/public/platform/web_referrer_policy.h"
+#include "third_party/blink/public/platform/web_string.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/origin_access_entry.h"
#include "third_party/blink/renderer/platform/weborigin/scheme_registry.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
#include "third_party/blink/renderer/platform/wtf/assertions.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/std_lib_extras.h"
#include "third_party/blink/renderer/platform/wtf/text/parsing_utilities.h"
-#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
#include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h"
#include "third_party/blink/renderer/platform/wtf/threading.h"
+#include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
#include "third_party/blink/renderer/platform/wtf/wtf.h"
+#include "url/gurl.h"
namespace blink {
-using OriginAccessList = Vector<OriginAccessEntry>;
-using OriginAccessMap = HashMap<String, std::unique_ptr<OriginAccessList>>;
-using OriginSet = HashSet<String>;
-
-static OriginAccessMap& GetOriginAccessWhitelistMap() {
- DEFINE_STATIC_LOCAL(OriginAccessMap, origin_access_whitelist_map, ());
- return origin_access_whitelist_map;
+static Mutex& GetMutex() {
+ DEFINE_THREAD_SAFE_STATIC_LOCAL(Mutex, mutex, ());
+ return mutex;
}
-static OriginAccessMap& GetOriginAccessBlacklistMap() {
- DEFINE_STATIC_LOCAL(OriginAccessMap, origin_access_blacklist_map, ());
- return origin_access_blacklist_map;
+static network::cors::OriginAccessList& GetOriginAccessList() {
+ DEFINE_THREAD_SAFE_STATIC_LOCAL(network::cors::OriginAccessList,
+ origin_access_list, ());
+ return origin_access_list;
}
+using OriginSet = HashSet<String>;
+
static OriginSet& TrustworthyOriginSet() {
DEFINE_STATIC_LOCAL(OriginSet, trustworthy_origin_set, ());
return trustworthy_origin_set;
}
-static void AddOriginAccessEntry(const SecurityOrigin& source_origin,
- const String& destination_protocol,
- const String& destination_domain,
- bool allow_destination_subdomains,
- OriginAccessMap& access_map) {
- DCHECK(IsMainThread());
- DCHECK(!source_origin.IsOpaque());
- if (source_origin.IsOpaque())
- return;
-
- String source_string = source_origin.ToString();
- OriginAccessMap::AddResult result = access_map.insert(source_string, nullptr);
- if (result.is_new_entry)
- result.stored_value->value = std::make_unique<OriginAccessList>();
-
- OriginAccessList* list = result.stored_value->value.get();
- list->push_back(OriginAccessEntry(
- destination_protocol, destination_domain,
- allow_destination_subdomains ? OriginAccessEntry::kAllowSubdomains
- : OriginAccessEntry::kDisallowSubdomains));
-}
-
-static void RemoveOriginAccessEntry(const SecurityOrigin& source_origin,
- const String& destination_protocol,
- const String& destination_domain,
- bool allow_destination_subdomains,
- OriginAccessMap& access_map) {
- DCHECK(IsMainThread());
- DCHECK(!source_origin.IsOpaque());
- if (source_origin.IsOpaque())
- return;
-
- String source_string = source_origin.ToString();
- OriginAccessMap::iterator it = access_map.find(source_string);
- if (it == access_map.end())
- return;
-
- OriginAccessList* list = it->value.get();
- size_t index = list->Find(OriginAccessEntry(
- destination_protocol, destination_domain,
- allow_destination_subdomains ? OriginAccessEntry::kAllowSubdomains
- : OriginAccessEntry::kDisallowSubdomains));
-
- if (index == kNotFound)
- return;
-
- list->EraseAt(index);
-
- if (list->IsEmpty())
- access_map.erase(it);
-}
-
-static void RemoveAllOriginAccessEntriesForOrigin(
- const SecurityOrigin& source_origin,
- OriginAccessMap& access_map) {
- DCHECK(IsMainThread());
- DCHECK(!source_origin.IsOpaque());
- access_map.erase(source_origin.ToString());
-}
-
-static bool IsOriginPairInAccessMap(const SecurityOrigin* active_origin,
- const SecurityOrigin* target_origin,
- const OriginAccessMap& access_map) {
- if (access_map.IsEmpty())
- return false;
-
- if (OriginAccessList* list = access_map.at(active_origin->ToString())) {
- for (size_t i = 0; i < list->size(); ++i) {
- if (list->at(i).MatchesOrigin(*target_origin) !=
- OriginAccessEntry::kDoesNotMatchOrigin)
- return true;
- }
- }
- return false;
-}
-
void SecurityPolicy::Init() {
- GetOriginAccessWhitelistMap();
- GetOriginAccessBlacklistMap();
TrustworthyOriginSet();
}
@@ -296,76 +220,59 @@ bool SecurityPolicy::IsUrlWhiteListedTrustworthy(const KURL& url) {
return IsOriginWhiteListedTrustworthy(*SecurityOrigin::Create(url).get());
}
-bool SecurityPolicy::IsAccessWhiteListed(const SecurityOrigin* active_origin,
- const SecurityOrigin* target_origin) {
- return IsOriginPairInAccessMap(active_origin, target_origin,
- GetOriginAccessWhitelistMap()) &&
- !IsOriginPairInAccessMap(active_origin, target_origin,
- GetOriginAccessBlacklistMap());
+bool SecurityPolicy::IsOriginAccessAllowed(
+ const SecurityOrigin* active_origin,
+ const SecurityOrigin* target_origin) {
+ MutexLocker lock(GetMutex());
+ return GetOriginAccessList().IsAllowed(active_origin->ToUrlOrigin(),
+ target_origin->ToUrlOrigin().GetURL());
}
-bool SecurityPolicy::IsAccessToURLWhiteListed(
+bool SecurityPolicy::IsOriginAccessToURLAllowed(
const SecurityOrigin* active_origin,
const KURL& url) {
- scoped_refptr<const SecurityOrigin> target_origin =
- SecurityOrigin::Create(url);
- return IsAccessWhiteListed(active_origin, target_origin.get());
+ MutexLocker lock(GetMutex());
+ return GetOriginAccessList().IsAllowed(active_origin->ToUrlOrigin(), url);
}
-void SecurityPolicy::AddOriginAccessWhitelistEntry(
+void SecurityPolicy::AddOriginAccessAllowListEntry(
const SecurityOrigin& source_origin,
const String& destination_protocol,
const String& destination_domain,
bool allow_destination_subdomains) {
- AddOriginAccessEntry(source_origin, destination_protocol, destination_domain,
- allow_destination_subdomains,
- GetOriginAccessWhitelistMap());
+ MutexLocker lock(GetMutex());
+ GetOriginAccessList().AddAllowListEntryForOrigin(
+ source_origin.ToUrlOrigin(), WebString(destination_protocol).Utf8(),
+ WebString(destination_domain).Utf8(), allow_destination_subdomains);
}
-void SecurityPolicy::RemoveOriginAccessWhitelistEntry(
- const SecurityOrigin& source_origin,
- const String& destination_protocol,
- const String& destination_domain,
- bool allow_destination_subdomains) {
- RemoveOriginAccessEntry(source_origin, destination_protocol,
- destination_domain, allow_destination_subdomains,
- GetOriginAccessWhitelistMap());
-}
-
-void SecurityPolicy::RemoveAllOriginAccessWhitelistEntriesForOrigin(
+void SecurityPolicy::ClearOriginAccessAllowListForOrigin(
const SecurityOrigin& source_origin) {
- RemoveAllOriginAccessEntriesForOrigin(source_origin,
- GetOriginAccessWhitelistMap());
-}
-
-void SecurityPolicy::ResetOriginAccessWhitelists() {
- DCHECK(IsMainThread());
- GetOriginAccessWhitelistMap().clear();
+ MutexLocker lock(GetMutex());
+ GetOriginAccessList().SetAllowListForOrigin(
+ source_origin.ToUrlOrigin(),
+ std::vector<network::mojom::CorsOriginPatternPtr>());
}
-void SecurityPolicy::AddOriginAccessBlacklistEntry(
- const SecurityOrigin& source_origin,
- const String& destination_protocol,
- const String& destination_domain,
- bool allow_destination_subdomains) {
- AddOriginAccessEntry(source_origin, destination_protocol, destination_domain,
- allow_destination_subdomains,
- GetOriginAccessBlacklistMap());
+void SecurityPolicy::ClearOriginAccessAllowList() {
+ MutexLocker lock(GetMutex());
+ GetOriginAccessList().ClearAllowList();
}
-void SecurityPolicy::RemoveOriginAccessBlacklistEntry(
+void SecurityPolicy::AddOriginAccessBlockListEntry(
const SecurityOrigin& source_origin,
const String& destination_protocol,
const String& destination_domain,
bool allow_destination_subdomains) {
- RemoveOriginAccessEntry(source_origin, destination_protocol,
- destination_domain, allow_destination_subdomains,
- GetOriginAccessBlacklistMap());
+ MutexLocker lock(GetMutex());
+ GetOriginAccessList().AddBlockListEntryForOrigin(
+ source_origin.ToUrlOrigin(), WebString(destination_protocol).Utf8(),
+ WebString(destination_domain).Utf8(), allow_destination_subdomains);
}
-void SecurityPolicy::ResetOriginAccessBlacklists() {
- DCHECK(IsMainThread());
- GetOriginAccessBlacklistMap().clear();
+void SecurityPolicy::ClearOriginAccessBlockList() {
+ MutexLocker lock(GetMutex());
+ GetOriginAccessList().ClearBlockList();
}
bool SecurityPolicy::ReferrerPolicyFromString(
diff --git a/chromium/third_party/blink/renderer/platform/weborigin/security_policy.h b/chromium/third_party/blink/renderer/platform/weborigin/security_policy.h
index 30f338e4c00..5cf330bf9f3 100644
--- a/chromium/third_party/blink/renderer/platform/weborigin/security_policy.h
+++ b/chromium/third_party/blink/renderer/platform/weborigin/security_policy.h
@@ -65,34 +65,24 @@ class PLATFORM_EXPORT SecurityPolicy {
const KURL&,
const String& referrer);
- static void AddOriginAccessWhitelistEntry(const SecurityOrigin& source_origin,
+ static void AddOriginAccessAllowListEntry(const SecurityOrigin& source_origin,
const String& destination_protocol,
const String& destination_domain,
bool allow_destination_subdomains);
- static void RemoveOriginAccessWhitelistEntry(
- const SecurityOrigin& source_origin,
- const String& destination_protocol,
- const String& destination_domain,
- bool allow_destination_subdomains);
- static void RemoveAllOriginAccessWhitelistEntriesForOrigin(
+ static void ClearOriginAccessAllowListForOrigin(
const SecurityOrigin& source_origin);
- static void ResetOriginAccessWhitelists();
+ static void ClearOriginAccessAllowList();
- static void AddOriginAccessBlacklistEntry(const SecurityOrigin& source_origin,
+ static void AddOriginAccessBlockListEntry(const SecurityOrigin& source_origin,
const String& destination_protocol,
const String& destination_domain,
bool allow_destination_subdomains);
- static void RemoveOriginAccessBlacklistEntry(
- const SecurityOrigin& source_origin,
- const String& destination_protocol,
- const String& destination_domain,
- bool allow_destination_subdomains);
- static void ResetOriginAccessBlacklists();
-
- static bool IsAccessWhiteListed(const SecurityOrigin* active_origin,
- const SecurityOrigin* target_origin);
- static bool IsAccessToURLWhiteListed(const SecurityOrigin* active_origin,
- const KURL&);
+ static void ClearOriginAccessBlockList();
+
+ static bool IsOriginAccessAllowed(const SecurityOrigin* active_origin,
+ const SecurityOrigin* target_origin);
+ static bool IsOriginAccessToURLAllowed(const SecurityOrigin* active_origin,
+ const KURL&);
static void AddOriginTrustworthyWhiteList(const String&);
static bool IsOriginWhiteListedTrustworthy(const SecurityOrigin&);
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 a31ecf3e4ce..e38c0b51958 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
@@ -306,8 +306,8 @@ class SecurityPolicyAccessTest : public testing::Test {
}
void TearDown() override {
- SecurityPolicy::ResetOriginAccessWhitelists();
- SecurityPolicy::ResetOriginAccessBlacklists();
+ SecurityPolicy::ClearOriginAccessAllowList();
+ SecurityPolicy::ClearOriginAccessBlockList();
}
const SecurityOrigin* https_example_origin() const {
@@ -336,113 +336,103 @@ class SecurityPolicyAccessTest : public testing::Test {
DISALLOW_COPY_AND_ASSIGN(SecurityPolicyAccessTest);
};
-TEST_F(SecurityPolicyAccessTest, IsAccessWhiteListed) {
- // By default, no access should be whitelisted.
- EXPECT_FALSE(SecurityPolicy::IsAccessWhiteListed(https_chromium_origin(),
- https_example_origin()));
- EXPECT_FALSE(SecurityPolicy::IsAccessWhiteListed(https_chromium_origin(),
- https_sub_example_origin()));
- EXPECT_FALSE(SecurityPolicy::IsAccessWhiteListed(https_chromium_origin(),
- http_example_origin()));
+// TODO(toyoshim): Simplify origin access related tests since all we need here
+// is to check think wrapper functions to the network::cors::OriginAccessList.
+TEST_F(SecurityPolicyAccessTest, IsOriginAccessAllowed) {
+ // By default, no access should be allowed.
+ EXPECT_FALSE(SecurityPolicy::IsOriginAccessAllowed(https_chromium_origin(),
+ https_example_origin()));
+ EXPECT_FALSE(SecurityPolicy::IsOriginAccessAllowed(
+ https_chromium_origin(), https_sub_example_origin()));
+ EXPECT_FALSE(SecurityPolicy::IsOriginAccessAllowed(https_chromium_origin(),
+ http_example_origin()));
// Adding access for https://example.com should work, but should not grant
// access to subdomains or other schemes.
- SecurityPolicy::AddOriginAccessWhitelistEntry(*https_chromium_origin(),
+ SecurityPolicy::AddOriginAccessAllowListEntry(*https_chromium_origin(),
"https", "example.com", false);
- EXPECT_TRUE(SecurityPolicy::IsAccessWhiteListed(https_chromium_origin(),
- https_example_origin()));
- EXPECT_FALSE(SecurityPolicy::IsAccessWhiteListed(https_chromium_origin(),
- https_sub_example_origin()));
- EXPECT_FALSE(SecurityPolicy::IsAccessWhiteListed(https_chromium_origin(),
- http_example_origin()));
-
- // Removing the entry should revoke access.
- SecurityPolicy::RemoveOriginAccessWhitelistEntry(
- *https_chromium_origin(), "https", "example.com", false);
- EXPECT_FALSE(SecurityPolicy::IsAccessWhiteListed(https_chromium_origin(),
- https_example_origin()));
- EXPECT_FALSE(SecurityPolicy::IsAccessWhiteListed(https_chromium_origin(),
- https_sub_example_origin()));
- EXPECT_FALSE(SecurityPolicy::IsAccessWhiteListed(https_chromium_origin(),
- http_example_origin()));
+ EXPECT_TRUE(SecurityPolicy::IsOriginAccessAllowed(https_chromium_origin(),
+ https_example_origin()));
+ EXPECT_FALSE(SecurityPolicy::IsOriginAccessAllowed(
+ https_chromium_origin(), https_sub_example_origin()));
+ EXPECT_FALSE(SecurityPolicy::IsOriginAccessAllowed(https_chromium_origin(),
+ http_example_origin()));
+
+ // Clearing the map should revoke all special access.
+ SecurityPolicy::ClearOriginAccessAllowList();
+ EXPECT_FALSE(SecurityPolicy::IsOriginAccessAllowed(https_chromium_origin(),
+ https_example_origin()));
+ EXPECT_FALSE(SecurityPolicy::IsOriginAccessAllowed(
+ https_chromium_origin(), https_sub_example_origin()));
+ EXPECT_FALSE(SecurityPolicy::IsOriginAccessAllowed(https_chromium_origin(),
+ http_example_origin()));
// Adding an entry that matches subdomains should grant access to any
// subdomains.
- SecurityPolicy::AddOriginAccessWhitelistEntry(*https_chromium_origin(),
+ SecurityPolicy::AddOriginAccessAllowListEntry(*https_chromium_origin(),
"https", "example.com", true);
- EXPECT_TRUE(SecurityPolicy::IsAccessWhiteListed(https_chromium_origin(),
- https_example_origin()));
- EXPECT_TRUE(SecurityPolicy::IsAccessWhiteListed(https_chromium_origin(),
- https_sub_example_origin()));
- EXPECT_FALSE(SecurityPolicy::IsAccessWhiteListed(https_chromium_origin(),
- http_example_origin()));
-
- // Clearing the map should revoke all special access.
- SecurityPolicy::ResetOriginAccessWhitelists();
- EXPECT_FALSE(SecurityPolicy::IsAccessWhiteListed(https_chromium_origin(),
- https_example_origin()));
- EXPECT_FALSE(SecurityPolicy::IsAccessWhiteListed(https_chromium_origin(),
- https_sub_example_origin()));
- EXPECT_FALSE(SecurityPolicy::IsAccessWhiteListed(https_chromium_origin(),
- http_example_origin()));
+ EXPECT_TRUE(SecurityPolicy::IsOriginAccessAllowed(https_chromium_origin(),
+ https_example_origin()));
+ EXPECT_TRUE(SecurityPolicy::IsOriginAccessAllowed(
+ https_chromium_origin(), https_sub_example_origin()));
+ EXPECT_FALSE(SecurityPolicy::IsOriginAccessAllowed(https_chromium_origin(),
+ http_example_origin()));
}
-TEST_F(SecurityPolicyAccessTest, IsAccessWhiteListedWildCard) {
+TEST_F(SecurityPolicyAccessTest, IsOriginAccessAllowedWildCard) {
// An empty domain that matches subdomains results in matching every domain.
- SecurityPolicy::AddOriginAccessWhitelistEntry(*https_chromium_origin(),
+ SecurityPolicy::AddOriginAccessAllowListEntry(*https_chromium_origin(),
"https", "", true);
- EXPECT_TRUE(SecurityPolicy::IsAccessWhiteListed(https_chromium_origin(),
- https_example_origin()));
- EXPECT_TRUE(SecurityPolicy::IsAccessWhiteListed(https_chromium_origin(),
- https_google_origin()));
- EXPECT_FALSE(SecurityPolicy::IsAccessWhiteListed(https_chromium_origin(),
- http_example_origin()));
+ EXPECT_TRUE(SecurityPolicy::IsOriginAccessAllowed(https_chromium_origin(),
+ https_example_origin()));
+ EXPECT_TRUE(SecurityPolicy::IsOriginAccessAllowed(https_chromium_origin(),
+ https_google_origin()));
+ EXPECT_FALSE(SecurityPolicy::IsOriginAccessAllowed(https_chromium_origin(),
+ http_example_origin()));
}
-TEST_F(SecurityPolicyAccessTest, IsAccessWhiteListedWithBlacklistedEntries) {
- // The blacklists take priority over the whitelist.
- SecurityPolicy::AddOriginAccessWhitelistEntry(*https_chromium_origin(),
+TEST_F(SecurityPolicyAccessTest, IsOriginAccessAllowedWithBlockListEntry) {
+ // The block list takes priority over the allow list.
+ SecurityPolicy::AddOriginAccessAllowListEntry(*https_chromium_origin(),
"https", "example.com", true);
- SecurityPolicy::AddOriginAccessBlacklistEntry(*https_chromium_origin(),
+ SecurityPolicy::AddOriginAccessBlockListEntry(*https_chromium_origin(),
"https", "example.com", false);
- EXPECT_FALSE(SecurityPolicy::IsAccessWhiteListed(https_chromium_origin(),
- https_example_origin()));
- EXPECT_TRUE(SecurityPolicy::IsAccessWhiteListed(https_chromium_origin(),
- https_sub_example_origin()));
+ EXPECT_FALSE(SecurityPolicy::IsOriginAccessAllowed(https_chromium_origin(),
+ https_example_origin()));
+ EXPECT_TRUE(SecurityPolicy::IsOriginAccessAllowed(
+ https_chromium_origin(), https_sub_example_origin()));
}
TEST_F(SecurityPolicyAccessTest,
- IsAccessWhiteListedWildcardWithBlacklistedEntries) {
- SecurityPolicy::AddOriginAccessWhitelistEntry(*https_chromium_origin(),
+ IsOriginAccessAllowedWildcardWithBlockListEntry) {
+ SecurityPolicy::AddOriginAccessAllowListEntry(*https_chromium_origin(),
"https", "", true);
- SecurityPolicy::AddOriginAccessBlacklistEntry(*https_chromium_origin(),
+ SecurityPolicy::AddOriginAccessBlockListEntry(*https_chromium_origin(),
"https", "google.com", false);
- EXPECT_TRUE(SecurityPolicy::IsAccessWhiteListed(https_chromium_origin(),
- https_example_origin()));
- EXPECT_FALSE(SecurityPolicy::IsAccessWhiteListed(https_chromium_origin(),
- https_google_origin()));
+ EXPECT_TRUE(SecurityPolicy::IsOriginAccessAllowed(https_chromium_origin(),
+ https_example_origin()));
+ EXPECT_FALSE(SecurityPolicy::IsOriginAccessAllowed(https_chromium_origin(),
+ https_google_origin()));
}
-TEST_F(SecurityPolicyAccessTest,
- RemoveAllOriginAccessWhitelistEntriesForOrigin) {
- SecurityPolicy::AddOriginAccessWhitelistEntry(*https_chromium_origin(),
+TEST_F(SecurityPolicyAccessTest, ClearOriginAccessAllowListForOrigin) {
+ SecurityPolicy::AddOriginAccessAllowListEntry(*https_chromium_origin(),
"https", "example.com", true);
- SecurityPolicy::AddOriginAccessWhitelistEntry(*https_chromium_origin(),
+ SecurityPolicy::AddOriginAccessAllowListEntry(*https_chromium_origin(),
"https", "google.com", true);
- SecurityPolicy::AddOriginAccessWhitelistEntry(*https_example_origin(),
+ SecurityPolicy::AddOriginAccessAllowListEntry(*https_example_origin(),
"https", "google.com", true);
- SecurityPolicy::RemoveAllOriginAccessWhitelistEntriesForOrigin(
- *https_chromium_origin());
+ SecurityPolicy::ClearOriginAccessAllowListForOrigin(*https_chromium_origin());
- EXPECT_FALSE(SecurityPolicy::IsAccessWhiteListed(https_chromium_origin(),
- https_example_origin()));
- EXPECT_FALSE(SecurityPolicy::IsAccessWhiteListed(https_chromium_origin(),
- https_google_origin()));
- EXPECT_TRUE(SecurityPolicy::IsAccessWhiteListed(https_example_origin(),
- https_google_origin()));
+ EXPECT_FALSE(SecurityPolicy::IsOriginAccessAllowed(https_chromium_origin(),
+ https_example_origin()));
+ EXPECT_FALSE(SecurityPolicy::IsOriginAccessAllowed(https_chromium_origin(),
+ https_google_origin()));
+ EXPECT_TRUE(SecurityPolicy::IsOriginAccessAllowed(https_example_origin(),
+ https_google_origin()));
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/wtf/BUILD.gn b/chromium/third_party/blink/renderer/platform/wtf/BUILD.gn
index dba0b46aff5..6b95b5019b5 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/BUILD.gn
+++ b/chromium/third_party/blink/renderer/platform/wtf/BUILD.gn
@@ -46,6 +46,7 @@ jumbo_component("wtf") {
sources = [
"address_sanitizer.h",
"alignment.h",
+ "allocator.cc",
"allocator.h",
"allocator/partition_allocator.cc",
"allocator/partition_allocator.h",
@@ -144,8 +145,6 @@ jumbo_component("wtf") {
"text/cstring.cc",
"text/cstring.h",
"text/integer_to_string_conversion.h",
- "text/movable_string.cc",
- "text/movable_string.h",
"text/number_parsing_options.h",
"text/parsing_utilities.h",
"text/string_buffer.h",
@@ -199,6 +198,7 @@ jumbo_component("wtf") {
"thread_restriction_verifier.h",
"thread_safe_ref_counted.h",
"thread_specific.h",
+ "threading.cc",
"threading.h",
"threading_primitives.h",
"threading_pthreads.cc",
@@ -312,6 +312,7 @@ jumbo_source_set("wtf_unittests_sources") {
"assertions_test.cc",
"decimal_test.cc",
"deque_test.cc",
+ "doubly_linked_list_test.cc",
"dtoa_test.cc",
"experimental/container_type_operations_test.cc",
"functional_test.cc",
@@ -326,7 +327,6 @@ jumbo_source_set("wtf_unittests_sources") {
"text/atomic_string_test.cc",
"text/cstring_test.cc",
"text/integer_to_string_conversion_test.cc",
- "text/movable_string_test.cc",
"text/string_buffer_test.cc",
"text/string_builder_test.cc",
"text/string_impl_test.cc",
@@ -338,6 +338,7 @@ jumbo_source_set("wtf_unittests_sources") {
"text/text_codec_utf8_test.cc",
"text/text_encoding_test.cc",
"text/wtf_string_test.cc",
+ "threading_primitives_test.cc",
"tree_node_test.cc",
"type_traits_test.cc",
"typed_arrays/array_buffer_builder_test.cc",
diff --git a/chromium/third_party/blink/renderer/platform/wtf/DEPS b/chromium/third_party/blink/renderer/platform/wtf/DEPS
index 2576c5d932a..2cff45e547c 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/DEPS
+++ b/chromium/third_party/blink/renderer/platform/wtf/DEPS
@@ -20,8 +20,7 @@ include_rules = [
"+base/strings",
"+base/template_util.h",
"+base/test/metrics/histogram_tester.h",
- "+base/threading/thread_checker.h",
- "+base/threading/thread_local_storage.h",
+ "+base/threading",
"+base/time/time.h",
"+base/tuple.h",
# To avoid recursive dependency, we impose a blanket ban on using other
@@ -30,9 +29,3 @@ include_rules = [
"+third_party/blink/renderer/platform/wtf",
"-v8",
]
-
-specific_include_rules = {
- ".*_test\.cc": [
- "+base/threading/thread.h"
- ]
-}
diff --git a/chromium/third_party/blink/renderer/platform/wtf/allocator.cc b/chromium/third_party/blink/renderer/platform/wtf/allocator.cc
new file mode 100644
index 00000000000..927e7e09cb9
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/wtf/allocator.cc
@@ -0,0 +1,20 @@
+// 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/wtf/allocator.h"
+
+namespace {
+
+struct Empty {};
+
+struct StackAllocatedType {
+ STACK_ALLOCATED();
+};
+
+static_assert(!WTF::IsStackAllocatedType<Empty>::value,
+ "Failed to detect STACK_ALLOCATED macro.");
+static_assert(WTF::IsStackAllocatedType<StackAllocatedType>::value,
+ "Failed to detect STACK_ALLOCATED macro.");
+
+} // namespace
diff --git a/chromium/third_party/blink/renderer/platform/wtf/allocator.h b/chromium/third_party/blink/renderer/platform/wtf/allocator.h
index ff81a049cda..31722fdd75e 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/allocator.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/allocator.h
@@ -71,16 +71,21 @@ class __thisIsHereToForceASemicolonAfterThisMacro;
friend class ::WTF::internal::__thisIsHereToForceASemicolonAfterThisMacro
#if defined(__clang__)
-#define STACK_ALLOCATED() \
- __attribute__((annotate("blink_stack_allocated"))) void* operator new( \
- size_t) = delete; \
- void* operator new(size_t, NotNullTag, void*) = delete; \
- void* operator new(size_t, void*) = delete
-
+#define ANNOTATE_STACK_ALLOCATED \
+ __attribute__((annotate("blink_stack_allocated")))
#else
-#define STACK_ALLOCATED() DISALLOW_NEW()
+#define ANNOTATE_STACK_ALLOCATED
#endif
+#define STACK_ALLOCATED() \
+ public: \
+ using IsStackAllocatedTypeMarker[[maybe_unused]] = int; \
+ \
+ private: \
+ ANNOTATE_STACK_ALLOCATED void* operator new(size_t) = delete; \
+ void* operator new(size_t, NotNullTag, void*) = delete; \
+ void* operator new(size_t, void*) = delete
+
// Provides customizable overrides of fastMalloc/fastFree and operator
// new/delete
//
diff --git a/chromium/third_party/blink/renderer/platform/wtf/allocator/partition_allocator.cc b/chromium/third_party/blink/renderer/platform/wtf/allocator/partition_allocator.cc
index bb4fd19f1c8..30686ea6182 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/allocator/partition_allocator.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/allocator/partition_allocator.cc
@@ -17,8 +17,7 @@ void PartitionAllocator::FreeVectorBacking(void* address) {
Partitions::BufferFree(address);
}
-void PartitionAllocator::FreeHashTableBacking(void* address,
- bool is_weak_table) {
+void PartitionAllocator::FreeHashTableBacking(void* address) {
Partitions::BufferFree(address);
}
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 cbd0f90b4b3..bcfff8670c7 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
@@ -82,7 +82,7 @@ class WTF_EXPORT PartitionAllocator {
memset(result, 0, size);
return reinterpret_cast<T*>(result);
}
- static void FreeHashTableBacking(void* address, bool is_weak_table);
+ static void FreeHashTableBacking(void* address);
template <typename Return, typename Metadata>
static Return Malloc(size_t size, const char* type_name) {
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 079afd0c248..8ee8698e91d 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/allocator/partitions.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/allocator/partitions.h
@@ -101,6 +101,11 @@ class WTF_EXPORT Partitions {
const char* type_name) {
return BufferPartition()->Realloc(p, n, type_name);
}
+ ALWAYS_INLINE static void* BufferTryRealloc(void* p,
+ size_t n,
+ const char* type_name) {
+ return BufferPartition()->TryRealloc(p, n, type_name);
+ }
ALWAYS_INLINE static void BufferFree(void* p) { BufferPartition()->Free(p); }
ALWAYS_INLINE static size_t BufferActualSize(size_t n) {
return BufferPartition()->ActualSize(n);
diff --git a/chromium/third_party/blink/renderer/platform/wtf/compiler.h b/chromium/third_party/blink/renderer/platform/wtf/compiler.h
index 51595afdc95..40f79d40706 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/compiler.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/compiler.h
@@ -57,8 +57,16 @@
#if defined(__clang__)
#define NO_SANITIZE_UNRELATED_CAST \
__attribute__((no_sanitize("cfi-unrelated-cast", "vptr")))
+#define NO_SANITIZE_CFI_ICALL __attribute__((no_sanitize("cfi-icall")))
#else
#define NO_SANITIZE_UNRELATED_CAST
+#define NO_SANITIZE_CFI_ICALL
+#endif
+
+#if defined(COMPILER_MSVC)
+#define WTF_NOINLINE __declspec(noinline)
+#else
+#define WTF_NOINLINE __attribute__((noinline))
#endif
#endif /* WTF_Compiler_h */
diff --git a/chromium/third_party/blink/renderer/platform/wtf/deque.h b/chromium/third_party/blink/renderer/platform/wtf/deque.h
index bdc041e0787..cc3974ac000 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/deque.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/deque.h
@@ -42,15 +42,15 @@
namespace WTF {
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
class DequeIteratorBase;
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
class DequeIterator;
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
class DequeConstIterator;
template <typename T,
- size_t inlineCapacity = 0,
+ wtf_size_t inlineCapacity = 0,
typename Allocator = PartitionAllocator>
class Deque {
USE_ALLOCATOR(Deque, Allocator);
@@ -72,7 +72,7 @@ class Deque {
void Swap(Deque&);
- size_t size() const {
+ wtf_size_t size() const {
return start_ <= end_ ? end_ - start_ : end_ + buffer_.capacity() - start_;
}
bool IsEmpty() const { return start_ == end_; }
@@ -110,21 +110,21 @@ class Deque {
}
T TakeLast();
- T& at(size_t i) {
+ T& at(wtf_size_t i) {
CHECK_LT(i, size());
- size_t right = buffer_.capacity() - start_;
+ wtf_size_t right = buffer_.capacity() - start_;
return i < right ? buffer_.Buffer()[start_ + i]
: buffer_.Buffer()[i - right];
}
- const T& at(size_t i) const {
+ const T& at(wtf_size_t i) const {
CHECK_LT(i, size());
- size_t right = buffer_.capacity() - start_;
+ wtf_size_t right = buffer_.capacity() - start_;
return i < right ? buffer_.Buffer()[start_ + i]
: buffer_.Buffer()[i - right];
}
- T& operator[](size_t i) { return at(i); }
- const T& operator[](size_t i) const { return at(i); }
+ T& operator[](wtf_size_t i) { return at(i); }
+ const T& operator[](wtf_size_t i) const { return at(i); }
template <typename U>
void push_front(U&&);
@@ -160,6 +160,9 @@ class Deque {
"Cannot put raw pointers to garbage-collected classes into a "
"Deque. Use HeapDeque<Member<T>> instead.");
+ protected:
+ T** GetBufferSlot() { return buffer_.BufferSlot(); }
+
private:
friend class DequeIteratorBase<T, inlineCapacity, Allocator>;
@@ -170,9 +173,9 @@ class Deque {
public:
BackingBuffer() : Base() {}
- explicit BackingBuffer(size_t capacity) : Base(capacity) {}
+ explicit BackingBuffer(wtf_size_t capacity) : Base(capacity) {}
- void SetSize(size_t size) { size_ = size; }
+ void SetSize(wtf_size_t size) { size_ = size; }
DISALLOW_COPY_AND_ASSIGN(BackingBuffer);
};
@@ -180,23 +183,23 @@ class Deque {
typedef VectorTypeOperations<T, Allocator> TypeOperations;
typedef DequeIteratorBase<T, inlineCapacity, Allocator> IteratorBase;
- void erase(size_t position);
+ void erase(wtf_size_t position);
void DestroyAll();
void ExpandCapacityIfNeeded();
void ExpandCapacity();
BackingBuffer buffer_;
- unsigned start_;
- unsigned end_;
+ wtf_size_t start_;
+ wtf_size_t end_;
};
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
class DequeIteratorBase {
DISALLOW_NEW();
protected:
DequeIteratorBase();
- DequeIteratorBase(const Deque<T, inlineCapacity, Allocator>*, size_t);
+ DequeIteratorBase(const Deque<T, inlineCapacity, Allocator>*, wtf_size_t);
DequeIteratorBase(const DequeIteratorBase&);
DequeIteratorBase& operator=(const DequeIteratorBase<T, 0, Allocator>&);
~DequeIteratorBase();
@@ -219,7 +222,7 @@ class DequeIteratorBase {
};
template <typename T,
- size_t inlineCapacity = 0,
+ wtf_size_t inlineCapacity = 0,
typename Allocator = PartitionAllocator>
class DequeIterator : public DequeIteratorBase<T, inlineCapacity, Allocator> {
private:
@@ -233,7 +236,7 @@ class DequeIterator : public DequeIteratorBase<T, inlineCapacity, Allocator> {
typedef T& reference;
typedef std::bidirectional_iterator_tag iterator_category;
- DequeIterator(Deque<T, inlineCapacity, Allocator>* deque, size_t index)
+ DequeIterator(Deque<T, inlineCapacity, Allocator>* deque, wtf_size_t index)
: Base(deque, index) {}
DequeIterator(const Iterator& other) : Base(other) {}
@@ -261,7 +264,7 @@ class DequeIterator : public DequeIteratorBase<T, inlineCapacity, Allocator> {
};
template <typename T,
- size_t inlineCapacity = 0,
+ wtf_size_t inlineCapacity = 0,
typename Allocator = PartitionAllocator>
class DequeConstIterator
: public DequeIteratorBase<T, inlineCapacity, Allocator> {
@@ -278,7 +281,7 @@ class DequeConstIterator
typedef std::bidirectional_iterator_tag iterator_category;
DequeConstIterator(const Deque<T, inlineCapacity, Allocator>* deque,
- size_t index)
+ wtf_size_t index)
: Base(deque, index) {}
DequeConstIterator(const Iterator& other) : Base(other) {}
@@ -310,10 +313,10 @@ class DequeConstIterator
// postfix -- intentionally omitted
};
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
inline Deque<T, inlineCapacity, Allocator>::Deque() : start_(0), end_(0) {}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
inline Deque<T, inlineCapacity, Allocator>::Deque(const Deque& other)
: buffer_(other.buffer_.capacity()),
start_(other.start_),
@@ -331,7 +334,7 @@ inline Deque<T, inlineCapacity, Allocator>::Deque(const Deque& other)
}
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
inline Deque<T, inlineCapacity, Allocator>&
Deque<T, inlineCapacity, Allocator>::operator=(const Deque& other) {
Deque<T> copy(other);
@@ -339,20 +342,20 @@ Deque<T, inlineCapacity, Allocator>::operator=(const Deque& other) {
return *this;
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
inline Deque<T, inlineCapacity, Allocator>::Deque(Deque&& other)
: start_(0), end_(0) {
Swap(other);
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
inline Deque<T, inlineCapacity, Allocator>&
Deque<T, inlineCapacity, Allocator>::operator=(Deque&& other) {
Swap(other);
return *this;
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
inline void Deque<T, inlineCapacity, Allocator>::DestroyAll() {
if (start_ <= end_) {
TypeOperations::Destruct(buffer_.Buffer() + start_,
@@ -371,7 +374,7 @@ inline void Deque<T, inlineCapacity, Allocator>::DestroyAll() {
// For design of the destructor, please refer to
// [here](https://docs.google.com/document/d/1AoGTvb3tNLx2tD1hNqAfLRLmyM59GM0O-7rCHTT_7_U/)
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
inline Deque<T, inlineCapacity, Allocator>::~Deque() {
if ((!INLINE_CAPACITY && !buffer_.Buffer()))
return;
@@ -385,7 +388,7 @@ inline Deque<T, inlineCapacity, Allocator>::~Deque() {
buffer_.Destruct();
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
inline void Deque<T, inlineCapacity, Allocator>::Swap(Deque& other) {
typename BackingBuffer::OffsetRange this_hole;
if (start_ <= end_) {
@@ -414,7 +417,7 @@ inline void Deque<T, inlineCapacity, Allocator>::Swap(Deque& other) {
std::swap(end_, other.end_);
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
inline void Deque<T, inlineCapacity, Allocator>::clear() {
DestroyAll();
start_ = 0;
@@ -423,7 +426,7 @@ inline void Deque<T, inlineCapacity, Allocator>::clear() {
buffer_.ResetBufferPointer();
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
inline void Deque<T, inlineCapacity, Allocator>::ExpandCapacityIfNeeded() {
if (start_) {
if (end_ + 1 != start_)
@@ -438,17 +441,16 @@ inline void Deque<T, inlineCapacity, Allocator>::ExpandCapacityIfNeeded() {
ExpandCapacity();
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
void Deque<T, inlineCapacity, Allocator>::ExpandCapacity() {
- size_t old_capacity = buffer_.capacity();
+ wtf_size_t old_capacity = buffer_.capacity();
T* old_buffer = buffer_.Buffer();
- size_t new_capacity =
- std::max(static_cast<size_t>(16), old_capacity + old_capacity / 4 + 1);
+ wtf_size_t new_capacity = std::max(16u, old_capacity + old_capacity / 4 + 1);
if (buffer_.ExpandBuffer(new_capacity)) {
if (start_ <= end_) {
// No adjustments to be done.
} else {
- size_t new_start = buffer_.capacity() - (old_capacity - start_);
+ wtf_size_t new_start = buffer_.capacity() - (old_capacity - start_);
TypeOperations::MoveOverlapping(old_buffer + start_,
old_buffer + old_capacity,
buffer_.Buffer() + new_start);
@@ -466,7 +468,7 @@ void Deque<T, inlineCapacity, Allocator>::ExpandCapacity() {
} else {
TypeOperations::Move(old_buffer, old_buffer + end_, buffer_.Buffer());
buffer_.ClearUnusedSlots(old_buffer, old_buffer + end_);
- size_t new_start = buffer_.capacity() - (old_capacity - start_);
+ wtf_size_t new_start = buffer_.capacity() - (old_capacity - start_);
TypeOperations::Move(old_buffer + start_, old_buffer + old_capacity,
buffer_.Buffer() + new_start);
buffer_.ClearUnusedSlots(old_buffer + start_, old_buffer + old_capacity);
@@ -475,21 +477,21 @@ void Deque<T, inlineCapacity, Allocator>::ExpandCapacity() {
buffer_.DeallocateBuffer(old_buffer);
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
inline T Deque<T, inlineCapacity, Allocator>::TakeFirst() {
T old_first = std::move(front());
pop_front();
return old_first;
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
inline T Deque<T, inlineCapacity, Allocator>::TakeLast() {
T old_last = std::move(back());
pop_back();
return old_last;
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
template <typename U>
inline void Deque<T, inlineCapacity, Allocator>::push_back(U&& value) {
ExpandCapacityIfNeeded();
@@ -502,7 +504,7 @@ inline void Deque<T, inlineCapacity, Allocator>::push_back(U&& value) {
new_element, std::forward<U>(value));
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
template <typename U>
inline void Deque<T, inlineCapacity, Allocator>::push_front(U&& value) {
ExpandCapacityIfNeeded();
@@ -514,7 +516,7 @@ inline void Deque<T, inlineCapacity, Allocator>::push_front(U&& value) {
&buffer_.Buffer()[start_], std::forward<U>(value));
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
template <typename... Args>
inline void Deque<T, inlineCapacity, Allocator>::emplace_back(Args&&... args) {
ExpandCapacityIfNeeded();
@@ -527,7 +529,7 @@ inline void Deque<T, inlineCapacity, Allocator>::emplace_back(Args&&... args) {
new_element, std::forward<Args>(args)...);
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
template <typename... Args>
inline void Deque<T, inlineCapacity, Allocator>::emplace_front(Args&&... args) {
ExpandCapacityIfNeeded();
@@ -539,7 +541,7 @@ inline void Deque<T, inlineCapacity, Allocator>::emplace_front(Args&&... args) {
&buffer_.Buffer()[start_], std::forward<Args>(args)...);
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
inline void Deque<T, inlineCapacity, Allocator>::pop_front() {
DCHECK(!IsEmpty());
TypeOperations::Destruct(&buffer_.Buffer()[start_],
@@ -552,7 +554,7 @@ inline void Deque<T, inlineCapacity, Allocator>::pop_front() {
++start_;
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
inline void Deque<T, inlineCapacity, Allocator>::pop_back() {
DCHECK(!IsEmpty());
if (!end_)
@@ -565,18 +567,18 @@ inline void Deque<T, inlineCapacity, Allocator>::pop_back() {
&buffer_.Buffer()[end_ + 1]);
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
inline void Deque<T, inlineCapacity, Allocator>::erase(iterator& it) {
erase(it.index_);
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
inline void Deque<T, inlineCapacity, Allocator>::erase(const_iterator& it) {
erase(it.index_);
}
-template <typename T, size_t inlineCapacity, typename Allocator>
-inline void Deque<T, inlineCapacity, Allocator>::erase(size_t position) {
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
+inline void Deque<T, inlineCapacity, Allocator>::erase(wtf_size_t position) {
if (position == end_)
return;
@@ -598,23 +600,23 @@ inline void Deque<T, inlineCapacity, Allocator>::erase(size_t position) {
}
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
inline DequeIteratorBase<T, inlineCapacity, Allocator>::DequeIteratorBase()
: deque_(0) {}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
inline DequeIteratorBase<T, inlineCapacity, Allocator>::DequeIteratorBase(
const Deque<T, inlineCapacity, Allocator>* deque,
- size_t index)
+ wtf_size_t index)
: deque_(const_cast<Deque<T, inlineCapacity, Allocator>*>(deque)),
index_(index) {}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
inline DequeIteratorBase<T, inlineCapacity, Allocator>::DequeIteratorBase(
const DequeIteratorBase& other)
: deque_(other.deque_), index_(other.index_) {}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
inline DequeIteratorBase<T, inlineCapacity, Allocator>&
DequeIteratorBase<T, inlineCapacity, Allocator>::operator=(
const DequeIteratorBase<T, 0, Allocator>& other) {
@@ -623,17 +625,17 @@ DequeIteratorBase<T, inlineCapacity, Allocator>::operator=(
return *this;
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
inline DequeIteratorBase<T, inlineCapacity, Allocator>::~DequeIteratorBase() =
default;
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
inline bool DequeIteratorBase<T, inlineCapacity, Allocator>::IsEqual(
const DequeIteratorBase& other) const {
return index_ == other.index_;
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
inline void DequeIteratorBase<T, inlineCapacity, Allocator>::Increment() {
DCHECK_NE(index_, deque_->end_);
DCHECK(deque_->buffer_.capacity());
@@ -643,7 +645,7 @@ inline void DequeIteratorBase<T, inlineCapacity, Allocator>::Increment() {
++index_;
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
inline void DequeIteratorBase<T, inlineCapacity, Allocator>::Decrement() {
DCHECK_NE(index_, deque_->start_);
DCHECK(deque_->buffer_.capacity());
@@ -653,13 +655,13 @@ inline void DequeIteratorBase<T, inlineCapacity, Allocator>::Decrement() {
--index_;
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
inline T* DequeIteratorBase<T, inlineCapacity, Allocator>::After() const {
CHECK_NE(index_, deque_->end_);
return &deque_->buffer_.Buffer()[index_];
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
inline T* DequeIteratorBase<T, inlineCapacity, Allocator>::Before() const {
CHECK_NE(index_, deque_->start_);
if (!index_)
@@ -669,7 +671,7 @@ inline T* DequeIteratorBase<T, inlineCapacity, Allocator>::Before() const {
// This is only defined if the allocator is a HeapAllocator. It is used when
// visiting during a tracing GC.
-template <typename T, size_t inlineCapacity, typename Allocator>
+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) {
@@ -679,6 +681,8 @@ Deque<T, inlineCapacity, Allocator>::Trace(VisitorDispatcher visitor) {
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) {
@@ -705,7 +709,7 @@ Deque<T, inlineCapacity, Allocator>::Trace(VisitorDispatcher visitor) {
}
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
inline void swap(Deque<T, inlineCapacity, Allocator>& a,
Deque<T, inlineCapacity, Allocator>& b) {
a.Swap(b);
diff --git a/chromium/third_party/blink/renderer/platform/wtf/deque_test.cc b/chromium/third_party/blink/renderer/platform/wtf/deque_test.cc
index 4b7cc4627da..6dac66778cc 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/deque_test.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/deque_test.cc
@@ -40,13 +40,13 @@ TEST(DequeTest, Basic) {
EXPECT_EQ(0ul, int_deque.size());
}
-template <size_t inlineCapacity>
+template <wtf_size_t inlineCapacity>
void CheckNumberSequence(Deque<int, inlineCapacity>& deque,
int from,
int to,
bool increment) {
auto it = increment ? deque.begin() : deque.end();
- size_t index = increment ? 0 : deque.size();
+ wtf_size_t index = increment ? 0 : deque.size();
int step = from < to ? 1 : -1;
for (int i = from; i != to + step; i += step) {
if (!increment) {
@@ -66,13 +66,13 @@ void CheckNumberSequence(Deque<int, inlineCapacity>& deque,
EXPECT_EQ(increment ? deque.size() : 0, index);
}
-template <size_t inlineCapacity>
+template <wtf_size_t inlineCapacity>
void CheckNumberSequenceReverse(Deque<int, inlineCapacity>& deque,
int from,
int to,
bool increment) {
auto it = increment ? deque.rbegin() : deque.rend();
- size_t index = increment ? 0 : deque.size();
+ wtf_size_t index = increment ? 0 : deque.size();
int step = from < to ? 1 : -1;
for (int i = from; i != to + step; i += step) {
if (!increment) {
@@ -92,7 +92,7 @@ void CheckNumberSequenceReverse(Deque<int, inlineCapacity>& deque,
EXPECT_EQ(increment ? deque.size() : 0, index);
}
-template <size_t inlineCapacity>
+template <wtf_size_t inlineCapacity>
void ReverseTest() {
Deque<int, inlineCapacity> int_deque;
int_deque.push_back(10);
@@ -250,7 +250,7 @@ TEST(DequeTest, MoveOnlyType) {
HashSet<void*> g_constructed_wrapped_ints;
-template <size_t inlineCapacity>
+template <wtf_size_t inlineCapacity>
void SwapWithOrWithoutInlineCapacity() {
Deque<WrappedInt, inlineCapacity> deque_a;
deque_a.push_back(WrappedInt(1));
@@ -306,7 +306,7 @@ bool InterestingNumber(int i) {
return i < 4 || (i & 1);
}
-template <size_t inlineCapacity>
+template <wtf_size_t inlineCapacity>
void TestDequeDestructorAndConstructorCallsWhenSwappingWithInlineCapacity() {
LivenessCounter::live_ = 0;
LivenessCounter counter;
@@ -378,7 +378,7 @@ TEST(DequeTest, SwapWithConstructorsAndDestructors) {
TestDequeDestructorAndConstructorCallsWhenSwappingWithInlineCapacity<9>();
}
-template <size_t inlineCapacity>
+template <wtf_size_t inlineCapacity>
void TestDequeValuesMovedAndSwappedWithInlineCapacity() {
Deque<unsigned, inlineCapacity> deque;
Deque<unsigned, inlineCapacity> deque2;
diff --git a/chromium/third_party/blink/renderer/platform/wtf/doubly_linked_list.h b/chromium/third_party/blink/renderer/platform/wtf/doubly_linked_list.h
index 94f95ffd735..6b99798da89 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/doubly_linked_list.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/doubly_linked_list.h
@@ -28,6 +28,7 @@
#include "base/macros.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
+#include "third_party/blink/renderer/platform/wtf/wtf_size_t.h"
namespace WTF {
@@ -78,7 +79,7 @@ class DoublyLinkedList {
DoublyLinkedList();
bool IsEmpty() const;
- size_t size() const; // This is O(n).
+ wtf_size_t size() const; // This is O(n).
void Clear();
T* Head() const;
@@ -90,6 +91,29 @@ class DoublyLinkedList {
void Append(T*);
void Remove(T*);
+ struct AddResult {
+ T* node;
+ bool is_new_entry;
+
+ explicit operator bool() const { return is_new_entry; }
+ };
+
+ // This function should return -1 if the first argument is strictly
+ // less than the second, 0 if they are equal or 1 otherwise.
+ using CompareFunc = std::function<int(T*, T*)>;
+
+ // The following two functions can be used to implement a sorted
+ // version of the doubly linked list. It's guaranteed that the list
+ // will be sorted by only using Insert(). However the caller is the
+ // responsible of inserting the nodes in the right order if
+ // InsertAfter() is used. The main use case of the latter is to
+ // cheaply insert several consecutive items without having to
+ // traverse the whole list.
+ AddResult Insert(std::unique_ptr<T>, const CompareFunc&);
+ AddResult InsertAfter(std::unique_ptr<T> node, T* insertion_point);
+ AddResult Insert(T*, const CompareFunc&);
+ AddResult InsertAfter(T* node, T* insertion_point);
+
protected:
PointerType head_;
PointerType tail_;
@@ -113,8 +137,8 @@ inline bool DoublyLinkedList<T, PointerType>::IsEmpty() const {
}
template <typename T, typename PointerType>
-inline size_t DoublyLinkedList<T, PointerType>::size() const {
- size_t size = 0;
+inline wtf_size_t DoublyLinkedList<T, PointerType>::size() const {
+ wtf_size_t size = 0;
for (T* node = head_; node; node = node->Next())
++size;
return size;
@@ -199,6 +223,65 @@ inline T* DoublyLinkedList<T, PointerType>::RemoveHead() {
return node;
}
+template <typename T, typename PointerType>
+inline typename DoublyLinkedList<T, PointerType>::AddResult
+DoublyLinkedList<T, PointerType>::Insert(std::unique_ptr<T> node,
+ const CompareFunc& compare_func) {
+ DCHECK(node);
+ auto result = Insert(node.get(), compare_func);
+ if (result.is_new_entry)
+ node.release();
+ return result;
+}
+
+template <typename T, typename PointerType>
+inline typename DoublyLinkedList<T, PointerType>::AddResult
+DoublyLinkedList<T, PointerType>::Insert(T* node,
+ const CompareFunc& compare_func) {
+ DCHECK(node);
+ T* iter = head_;
+ while (iter && compare_func(iter, node) < 0)
+ iter = iter->Next();
+
+ if (iter && !compare_func(iter, node))
+ return {iter, false};
+
+ return InsertAfter(node, iter ? iter->Prev() : tail_);
+}
+
+template <typename T, typename PointerType>
+inline typename DoublyLinkedList<T, PointerType>::AddResult
+DoublyLinkedList<T, PointerType>::InsertAfter(std::unique_ptr<T> node,
+ T* insertion_point) {
+ DCHECK(node);
+ auto result = InsertAfter(node.get(), insertion_point);
+ if (result.is_new_entry)
+ node.release();
+ return result;
+}
+
+template <typename T, typename PointerType>
+inline typename DoublyLinkedList<T, PointerType>::AddResult
+DoublyLinkedList<T, PointerType>::InsertAfter(T* node, T* insertion_point) {
+ DCHECK(node);
+
+ if (!insertion_point) {
+ Push(node);
+ return {head_, true};
+ }
+
+ node->SetNext(insertion_point->Next());
+ if (insertion_point->Next())
+ insertion_point->Next()->SetPrev(node);
+ node->SetPrev(insertion_point);
+ insertion_point->SetNext(node);
+
+ if (insertion_point == tail_)
+ tail_ = node;
+
+ return {node, true};
+}
+
} // namespace WTF
using WTF::DoublyLinkedListNode;
diff --git a/chromium/third_party/blink/renderer/platform/wtf/doubly_linked_list_test.cc b/chromium/third_party/blink/renderer/platform/wtf/doubly_linked_list_test.cc
new file mode 100644
index 00000000000..94e17599a50
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/wtf/doubly_linked_list_test.cc
@@ -0,0 +1,222 @@
+// 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/wtf/doubly_linked_list.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/platform/wtf/wtf_test_helper.h"
+
+namespace WTF {
+
+namespace {
+
+static size_t test_node_counter = 0;
+
+class TestNode final : public DoublyLinkedListNode<TestNode> {
+ USING_FAST_MALLOC(TestNode);
+ friend class WTF::DoublyLinkedListNode<TestNode>;
+
+ public:
+ TestNode(int i) : i_(i) { ++test_node_counter; };
+ ~TestNode() { --test_node_counter; }
+ int i() { return i_; }
+
+ private:
+ int i_{0};
+ TestNode* next_{nullptr};
+ TestNode* prev_{nullptr};
+};
+
+class DoublyLinkedListTest : public testing::Test {
+ public:
+ void SetUp() override;
+ void TearDown() override;
+
+ static int CompareInt(TestNode*, TestNode*);
+ bool IsSorted() const;
+ DoublyLinkedList<TestNode>& List() { return list_; }
+ DoublyLinkedList<TestNode>::AddResult CheckedInsert(int i);
+
+ protected:
+ DoublyLinkedList<TestNode> list_;
+};
+
+void DoublyLinkedListTest::SetUp() {
+ EXPECT_TRUE(list_.IsEmpty());
+ EXPECT_EQ(0ul, list_.size());
+ EXPECT_EQ(0ul, test_node_counter);
+}
+
+void DoublyLinkedListTest::TearDown() {
+ while (!list_.IsEmpty())
+ delete list_.RemoveHead();
+ EXPECT_EQ(0ul, test_node_counter);
+}
+
+int DoublyLinkedListTest::CompareInt(TestNode* first, TestNode* second) {
+ return first->i() - second->i();
+};
+
+bool DoublyLinkedListTest::IsSorted() const {
+ for (auto* node = list_.Head(); node && node->Next(); node = node->Next()) {
+ if (node->i() >= node->Next()->i())
+ return false;
+ }
+ return true;
+}
+
+DoublyLinkedList<TestNode>::AddResult DoublyLinkedListTest::CheckedInsert(
+ int i) {
+ size_t current_size = list_.size();
+
+ auto result = list_.Insert(std::make_unique<TestNode>(i), CompareInt);
+ EXPECT_EQ(list_.size(),
+ result.is_new_entry ? current_size + 1 : current_size);
+ EXPECT_EQ(test_node_counter,
+ result.is_new_entry ? current_size + 1 : current_size);
+ EXPECT_FALSE(list_.IsEmpty());
+ return result;
+};
+
+TEST_F(DoublyLinkedListTest, InsertEmpty) {
+ CheckedInsert(1);
+ EXPECT_EQ(list_.Head(), list_.Tail());
+
+ auto* node_heap = list_.RemoveHead();
+ EXPECT_EQ(0ul, list_.size());
+ EXPECT_EQ(1ul, test_node_counter);
+ EXPECT_TRUE(list_.IsEmpty());
+
+ delete node_heap;
+ EXPECT_EQ(0ul, test_node_counter);
+
+ list_.InsertAfter(std::make_unique<TestNode>(0), nullptr);
+ EXPECT_EQ(1ul, list_.size());
+ EXPECT_EQ(1ul, test_node_counter);
+ EXPECT_FALSE(list_.IsEmpty());
+ delete list_.RemoveHead();
+
+ TestNode node_stack(-1);
+ list_.Insert(&node_stack, CompareInt);
+ EXPECT_EQ(1ul, list_.size());
+ EXPECT_EQ(1ul, test_node_counter);
+ EXPECT_EQ(list_.Head(), list_.Tail());
+ EXPECT_FALSE(list_.IsEmpty());
+
+ list_.Remove(&node_stack);
+ EXPECT_EQ(0ul, list_.size());
+ EXPECT_EQ(1ul, test_node_counter);
+ EXPECT_TRUE(list_.IsEmpty());
+}
+
+TEST_F(DoublyLinkedListTest, InsertRandom) {
+ const size_t num_items = 6;
+ int items[6] = {2, -1, 3, 4, 0, 1};
+
+ for (int item : items) {
+ auto result = list_.Insert(std::make_unique<TestNode>(item), CompareInt);
+ EXPECT_TRUE(result.is_new_entry);
+ }
+ EXPECT_EQ(num_items, list_.size());
+ EXPECT_EQ(num_items, test_node_counter);
+ EXPECT_NE(list_.Head(), list_.Tail());
+ EXPECT_FALSE(list_.IsEmpty());
+
+ EXPECT_TRUE(IsSorted());
+}
+
+TEST_F(DoublyLinkedListTest, InsertSorted) {
+ const size_t num_items = 6;
+ int items[6] = {0, 1, 2, 3, 4, 5};
+
+ for (int item : items) {
+ auto result = list_.Insert(std::make_unique<TestNode>(item), CompareInt);
+ EXPECT_TRUE(result.is_new_entry);
+ }
+ EXPECT_EQ(num_items, list_.size());
+ EXPECT_EQ(num_items, test_node_counter);
+ EXPECT_NE(list_.Head(), list_.Tail());
+ EXPECT_FALSE(list_.IsEmpty());
+
+ EXPECT_TRUE(IsSorted());
+}
+
+TEST_F(DoublyLinkedListTest, InsertAfter) {
+ auto begin_result = CheckedInsert(0);
+ EXPECT_EQ(list_.Head(), list_.Tail());
+
+ auto end_result =
+ list_.InsertAfter(std::make_unique<TestNode>(10), begin_result.node);
+ EXPECT_EQ(2ul, list_.size());
+ EXPECT_EQ(2ul, test_node_counter);
+ EXPECT_FALSE(list_.IsEmpty());
+ EXPECT_TRUE(IsSorted());
+ EXPECT_EQ(end_result.node, list_.Tail());
+
+ auto center_result =
+ list_.InsertAfter(std::make_unique<TestNode>(5), begin_result.node);
+ EXPECT_EQ(3ul, list_.size());
+ EXPECT_EQ(3ul, test_node_counter);
+ EXPECT_TRUE(IsSorted());
+ EXPECT_NE(center_result.node, list_.Head());
+ EXPECT_NE(center_result.node, list_.Tail());
+
+ auto new_end_result =
+ list_.InsertAfter(std::make_unique<TestNode>(20), end_result.node);
+ EXPECT_EQ(4ul, list_.size());
+ EXPECT_EQ(4ul, test_node_counter);
+ EXPECT_TRUE(IsSorted());
+ EXPECT_EQ(new_end_result.node, list_.Tail());
+}
+
+TEST_F(DoublyLinkedListTest, InsertDup) {
+ CheckedInsert(0);
+ CheckedInsert(0);
+ CheckedInsert(1);
+ CheckedInsert(1);
+ CheckedInsert(0);
+}
+
+TEST_F(DoublyLinkedListTest, InsertAfterDup) {
+ // InsertAfter does not guarantee neither sorting nor uniqueness.
+ auto result = list_.InsertAfter(std::make_unique<TestNode>(0), nullptr);
+ EXPECT_EQ(1ul, list_.size());
+ EXPECT_EQ(1ul, test_node_counter);
+ EXPECT_FALSE(list_.IsEmpty());
+ EXPECT_TRUE(IsSorted());
+ EXPECT_TRUE(result.is_new_entry);
+ EXPECT_EQ(result.node, list_.Head());
+ EXPECT_EQ(result.node, list_.Tail());
+
+ result = list_.InsertAfter(std::make_unique<TestNode>(0), list_.Head());
+ EXPECT_EQ(2ul, list_.size());
+ EXPECT_EQ(2ul, test_node_counter);
+ EXPECT_FALSE(list_.IsEmpty());
+ EXPECT_FALSE(IsSorted());
+ EXPECT_TRUE(result.is_new_entry);
+ EXPECT_NE(result.node, list_.Head());
+ EXPECT_EQ(result.node, list_.Tail());
+
+ result = list_.InsertAfter(std::make_unique<TestNode>(1), list_.Head());
+ EXPECT_EQ(3ul, list_.size());
+ EXPECT_EQ(3ul, test_node_counter);
+ EXPECT_FALSE(list_.IsEmpty());
+ EXPECT_FALSE(IsSorted());
+ EXPECT_TRUE(result.is_new_entry);
+ EXPECT_NE(result.node, list_.Head());
+ EXPECT_NE(result.node, list_.Tail());
+
+ result = list_.InsertAfter(std::make_unique<TestNode>(1), list_.Tail());
+ EXPECT_EQ(4ul, list_.size());
+ EXPECT_EQ(4ul, test_node_counter);
+ EXPECT_FALSE(list_.IsEmpty());
+ EXPECT_FALSE(IsSorted());
+ EXPECT_TRUE(result.is_new_entry);
+ EXPECT_NE(result.node, list_.Head());
+ EXPECT_EQ(result.node, list_.Tail());
+}
+
+} // anonymous namespace
+
+} // namespace WTF
diff --git a/chromium/third_party/blink/renderer/platform/wtf/forward.h b/chromium/third_party/blink/renderer/platform/wtf/forward.h
index 0d1ac36ec48..f3ba221bf8b 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/forward.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/forward.h
@@ -22,7 +22,9 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_FORWARD_H_
#include <stddef.h>
+#include <stdint.h>
#include "third_party/blink/renderer/platform/wtf/compiler.h"
+#include "third_party/blink/renderer/platform/wtf/wtf_size_t.h"
template <typename T>
class scoped_refptr;
@@ -33,7 +35,7 @@ template <typename T>
class StringBuffer;
class PartitionAllocator;
template <typename T,
- size_t inlineCapacity = 0,
+ wtf_size_t inlineCapacity = 0,
typename Allocator = PartitionAllocator>
class Vector;
diff --git a/chromium/third_party/blink/renderer/platform/wtf/functional.h b/chromium/third_party/blink/renderer/platform/wtf/functional.h
index 83dc4141696..8eb23b5260d 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/functional.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/functional.h
@@ -208,7 +208,9 @@ struct CheckGCedTypeRestriction {
"WrapWeakPersistent, WrapCrossThreadPersistent or "
"WrapCrossThreadWeakPersistent.");
static_assert(!WTF::IsGarbageCollectedType<T>::value,
- "GCed type is forbidden as a bound parameters.");
+ "GCed types are forbidden as bound parameters.");
+ static_assert(!WTF::IsStackAllocatedType<T>::value,
+ "Stack allocated types are forbidden as bound parameters.");
};
template <typename Index, typename... Args>
@@ -247,6 +249,8 @@ class ThreadCheckingCallbackWrapper<CallbackType, R(Args...)> {
bool IsCancelled() const { return callback_.IsCancelled(); }
+ bool MaybeValid() const { return callback_.MaybeValid(); }
+
private:
static R RunInternal(base::RepeatingCallback<R(Args...)>* callback,
Args&&... args) {
@@ -285,6 +289,13 @@ struct CallbackCancellationTraits<
const RunArgs&...) {
return receiver->IsCancelled();
}
+
+ template <typename Functor, typename Receiver, typename... RunArgs>
+ static bool MaybeValid(const Functor&,
+ const Receiver& receiver,
+ const RunArgs&...) {
+ return receiver->MaybeValid();
+ }
};
} // namespace base
@@ -337,12 +348,12 @@ class CrossThreadFunction<R(Args...)> {
// above for the correct usage of those.
template <typename FunctionType, typename... BoundParameters>
base::OnceCallback<base::MakeUnboundRunType<FunctionType, BoundParameters...>>
-Bind(FunctionType function, BoundParameters&&... bound_parameters) {
+Bind(FunctionType&& function, BoundParameters&&... bound_parameters) {
static_assert(internal::CheckGCedTypeRestrictions<
std::index_sequence_for<BoundParameters...>,
std::decay_t<BoundParameters>...>::ok,
"A bound argument uses a bad pattern.");
- auto cb = base::BindOnce(function,
+ auto cb = base::BindOnce(std::forward<FunctionType>(function),
std::forward<BoundParameters>(bound_parameters)...);
#if DCHECK_IS_ON()
using UnboundRunType =
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 25f781809e2..9e15db75c15 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
@@ -110,6 +110,11 @@ class HashCountedSet {
impl_.Trace(visitor);
}
+ protected:
+ typename ImplType::ValueType** GetBufferSlot() {
+ return impl_.GetBufferSlot();
+ }
+
private:
ImplType impl_;
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 f5f1c9e00fe..96cb4996ffe 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/hash_map.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/hash_map.h
@@ -31,6 +31,12 @@ namespace WTF {
template <typename KeyTraits, typename MappedTraits>
struct HashMapValueTraits;
+template <typename Value,
+ typename HashFunctions,
+ typename Traits,
+ typename Allocator>
+class HashCountedSet;
+
struct KeyValuePairKeyExtractor {
STATIC_ONLY(KeyValuePairKeyExtractor);
template <typename T>
@@ -51,6 +57,8 @@ template <typename KeyArg,
typename Allocator = PartitionAllocator>
class HashMap {
USE_ALLOCATOR(HashMap, Allocator);
+ template <typename T, typename U, typename V, typename W>
+ friend class HashCountedSet;
private:
typedef KeyTraitsArg KeyTraits;
@@ -197,6 +205,9 @@ class HashMap {
impl_.Trace(visitor);
}
+ protected:
+ ValueType** GetBufferSlot() { return impl_.GetBufferSlot(); }
+
private:
template <typename IncomingKeyType, typename IncomingMappedType>
AddResult InlineAdd(IncomingKeyType&&, IncomingMappedType&&);
@@ -353,7 +364,7 @@ template <typename T,
typename Y>
HashMap<T, U, V, W, X, Y>::HashMap(std::initializer_list<ValueType> elements) {
if (elements.size())
- impl_.ReserveCapacityForSize(elements.size());
+ impl_.ReserveCapacityForSize(SafeCast<wtf_size_t>(elements.size()));
for (const ValueType& element : elements)
insert(element.key, element.value);
}
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 01e3190cfc0..d7cdeeddf1c 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/hash_set.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/hash_set.h
@@ -24,6 +24,7 @@
#include <initializer_list>
#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"
namespace WTF {
@@ -137,6 +138,9 @@ class HashSet {
impl_.Trace(visitor);
}
+ protected:
+ ValueType** GetBufferSlot() { return impl_.GetBufferSlot(); }
+
private:
HashTableType impl_;
};
@@ -173,7 +177,7 @@ template <typename Value,
HashSet<Value, HashFunctions, Traits, Allocator>::HashSet(
std::initializer_list<ValueType> elements) {
if (elements.size())
- impl_.ReserveCapacityForSize(elements.size());
+ impl_.ReserveCapacityForSize(SafeCast<wtf_size_t>(elements.size()));
for (const ValueType& element : elements)
insert(element);
}
diff --git a/chromium/third_party/blink/renderer/platform/wtf/hash_set_test.cc b/chromium/third_party/blink/renderer/platform/wtf/hash_set_test.cc
index 968c7e5819c..c206627c215 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/hash_set_test.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/hash_set_test.cc
@@ -98,7 +98,7 @@ void TestReserveCapacity() {
EXPECT_GE(initial_capacity, kMinimumTableSize);
// Adding items up to size should never change the capacity.
- for (size_t i = 0; i < size; ++i) {
+ for (wtf_size_t i = 0; i < size; ++i) {
test_set.insert(i + 1); // Avoid adding '0'.
EXPECT_EQ(initial_capacity, test_set.Capacity());
}
@@ -106,7 +106,7 @@ void TestReserveCapacity() {
// Adding items up to less than half the capacity should not change the
// capacity.
unsigned capacity_limit = initial_capacity / 2 - 1;
- for (size_t i = size; i < capacity_limit; ++i) {
+ for (wtf_size_t i = size; i < capacity_limit; ++i) {
test_set.insert(i + 1);
EXPECT_EQ(initial_capacity, test_set.Capacity());
}
@@ -197,6 +197,8 @@ TEST(HashSetTest, HashSetOwnPtr) {
TEST(HashSetTest, HashSetRefPtr) {
bool is_deleted = false;
+ DummyRefCounted::ref_invokes_count_ = 0;
+
scoped_refptr<DummyRefCounted> ptr =
base::AdoptRef(new DummyRefCounted(is_deleted));
EXPECT_EQ(0, DummyRefCounted::ref_invokes_count_);
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 f47d1d6a7f0..9d5b057d490 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/hash_table.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/hash_table.h
@@ -607,6 +607,8 @@ class IdentityHashTranslator {
template <typename HashTableType, typename ValueType>
struct HashTableAddResult final {
STACK_ALLOCATED();
+
+ public:
HashTableAddResult(const HashTableType* container,
ValueType* stored_value,
bool is_new_entry)
@@ -827,6 +829,8 @@ class HashTable final {
template <typename HashTranslator, typename T>
const ValueType* Lookup(const T&) const;
+ ValueType** GetBufferSlot() { return &table_; }
+
template <typename VisitorDispatcher, typename A = Allocator>
std::enable_if_t<A::kIsGarbageCollected> Trace(VisitorDispatcher);
@@ -1665,10 +1669,7 @@ void HashTable<Key,
}
}
}
- // Notify if this is a weak table since immediately freeing a weak hash table
- // backing may cause a use-after-free when the weak callback is called.
- Allocator::FreeHashTableBacking(table,
- Traits::kWeakHandlingFlag == kWeakHandling);
+ Allocator::FreeHashTableBacking(table);
}
template <typename Key,
@@ -2123,9 +2124,6 @@ template <typename VisitorDispatcher, typename A>
std::enable_if_t<A::kIsGarbageCollected>
HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::
Trace(VisitorDispatcher visitor) {
- if (!table_)
- return;
-
if (Traits::kWeakHandlingFlag == kNoWeakHandling) {
// Strong HashTable.
DCHECK(IsTraceableInCollectionTrait<Traits>::value);
@@ -2166,6 +2164,8 @@ HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::
template <typename HashTableType, typename Traits>
struct HashTableConstIteratorAdapter {
STACK_ALLOCATED();
+
+ public:
HashTableConstIteratorAdapter() = default;
HashTableConstIteratorAdapter(
const typename HashTableType::const_iterator& impl)
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 794a22ef2b5..28bb8035487 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
@@ -195,6 +195,8 @@ class LinkedHashSet {
struct AddResult final {
STACK_ALLOCATED();
+
+ public:
AddResult(const typename ImplType::AddResult& hash_table_add_result)
: stored_value(&hash_table_add_result.stored_value->value_),
is_new_entry(hash_table_add_result.is_new_entry) {}
@@ -305,11 +307,9 @@ class LinkedHashSet {
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_) {
- Allocator::RegisterBackingStoreCallback(
- visitor, impl_.table_, MoveBackingCallback,
- reinterpret_cast<void*>(&anchor_));
- }
+ Allocator::RegisterBackingStoreCallback(visitor, &impl_.table_,
+ MoveBackingCallback,
+ reinterpret_cast<void*>(&anchor_));
}
int64_t Modifications() const { return impl_.Modifications(); }
@@ -317,6 +317,11 @@ class LinkedHashSet {
impl_.CheckModifications(mods);
}
+ protected:
+ typename ImplType::ValueType** GetBufferSlot() {
+ return impl_.GetBufferSlot();
+ }
+
private:
Node* Anchor() { return reinterpret_cast<Node*>(&anchor_); }
const Node* Anchor() const { return reinterpret_cast<const Node*>(&anchor_); }
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 ddc89aa3809..ce913652bbb 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
@@ -129,6 +129,8 @@ class ListHashSet {
struct AddResult final {
STACK_ALLOCATED();
+
+ public:
friend class ListHashSet<ValueArg, inlineCapacity, HashArg, AllocatorArg>;
AddResult(Node* node, bool is_new_entry)
: stored_value(&node->value_),
@@ -232,6 +234,11 @@ class ListHashSet {
template <typename VisitorDispatcher>
void Trace(VisitorDispatcher);
+ protected:
+ typename ImplType::ValueType** GetBufferSlot() {
+ return impl_.GetBufferSlot();
+ }
+
private:
void Unlink(Node*);
void UnlinkAndDelete(Node*);
diff --git a/chromium/third_party/blink/renderer/platform/wtf/math_extras.h b/chromium/third_party/blink/renderer/platform/wtf/math_extras.h
index c090e11627f..6913d3dc486 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/math_extras.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/math_extras.h
@@ -48,83 +48,83 @@
#include <sys/types.h>
#endif
-const double kPiDouble = M_PI;
-const float kPiFloat = static_cast<float>(M_PI);
+constexpr double kPiDouble = M_PI;
+constexpr float kPiFloat = static_cast<float>(M_PI);
-const double kPiOverTwoDouble = M_PI_2;
-const float kPiOverTwoFloat = static_cast<float>(M_PI_2);
+constexpr double kPiOverTwoDouble = M_PI_2;
+constexpr float kPiOverTwoFloat = static_cast<float>(M_PI_2);
-const double kPiOverFourDouble = M_PI_4;
-const float kPiOverFourFloat = static_cast<float>(M_PI_4);
+constexpr double kPiOverFourDouble = M_PI_4;
+constexpr float kPiOverFourFloat = static_cast<float>(M_PI_4);
-const double kTwoPiDouble = kPiDouble * 2.0;
-const float kTwoPiFloat = kPiFloat * 2.0f;
+constexpr double kTwoPiDouble = kPiDouble * 2.0;
+constexpr float kTwoPiFloat = kPiFloat * 2.0f;
-inline double deg2rad(double d) {
+constexpr double deg2rad(double d) {
return d * kPiDouble / 180.0;
}
-inline double rad2deg(double r) {
+constexpr double rad2deg(double r) {
return r * 180.0 / kPiDouble;
}
-inline double deg2grad(double d) {
+constexpr double deg2grad(double d) {
return d * 400.0 / 360.0;
}
-inline double grad2deg(double g) {
+constexpr double grad2deg(double g) {
return g * 360.0 / 400.0;
}
-inline double turn2deg(double t) {
+constexpr double turn2deg(double t) {
return t * 360.0;
}
-inline double deg2turn(double d) {
+constexpr double deg2turn(double d) {
return d / 360.0;
}
-inline double rad2grad(double r) {
+constexpr double rad2grad(double r) {
return r * 200.0 / kPiDouble;
}
-inline double grad2rad(double g) {
+constexpr double grad2rad(double g) {
return g * kPiDouble / 200.0;
}
-inline double turn2grad(double t) {
+constexpr double turn2grad(double t) {
return t * 400;
}
-inline double grad2turn(double g) {
+constexpr double grad2turn(double g) {
return g / 400;
}
-inline double rad2turn(double r) {
+constexpr double rad2turn(double r) {
return r / kTwoPiDouble;
}
-inline double turn2rad(double t) {
+constexpr double turn2rad(double t) {
return t * kTwoPiDouble;
}
-inline float deg2rad(float d) {
+constexpr float deg2rad(float d) {
return d * kPiFloat / 180.0f;
}
-inline float rad2deg(float r) {
+constexpr float rad2deg(float r) {
return r * 180.0f / kPiFloat;
}
-inline float deg2grad(float d) {
+constexpr float deg2grad(float d) {
return d * 400.0f / 360.0f;
}
-inline float grad2deg(float g) {
+constexpr float grad2deg(float g) {
return g * 360.0f / 400.0f;
}
-inline float turn2deg(float t) {
+constexpr float turn2deg(float t) {
return t * 360.0f;
}
-inline float deg2turn(float d) {
+constexpr float deg2turn(float d) {
return d / 360.0f;
}
-inline float rad2grad(float r) {
+constexpr float rad2grad(float r) {
return r * 200.0f / kPiFloat;
}
-inline float grad2rad(float g) {
+constexpr float grad2rad(float g) {
return g * kPiFloat / 200.0f;
}
-inline float turn2grad(float t) {
+constexpr float turn2grad(float t) {
return t * 400;
}
-inline float grad2turn(float g) {
+constexpr float grad2turn(float g) {
return g / 400;
}
@@ -297,20 +297,20 @@ class ClampToHelper<unsigned long long int, ValueType> {
};
template <typename T>
-inline T defaultMaximumForClamp() {
+constexpr T defaultMaximumForClamp() {
return std::numeric_limits<T>::max();
}
// This basically reimplements C++11's std::numeric_limits<T>::lowest().
template <typename T>
-inline T defaultMinimumForClamp() {
+constexpr T defaultMinimumForClamp() {
return std::numeric_limits<T>::min();
}
template <>
-inline float defaultMinimumForClamp<float>() {
+constexpr float defaultMinimumForClamp<float>() {
return -std::numeric_limits<float>::max();
}
template <>
-inline double defaultMinimumForClamp<double>() {
+constexpr double defaultMinimumForClamp<double>() {
return -std::numeric_limits<double>::max();
}
@@ -324,16 +324,16 @@ inline LimitType clampTo(ValueType value,
return ClampToHelper<LimitType, ValueType>::clampTo(value, min, max);
}
-inline bool isWithinIntRange(float x) {
+constexpr bool isWithinIntRange(float x) {
return x > static_cast<float>(std::numeric_limits<int>::min()) &&
x < static_cast<float>(std::numeric_limits<int>::max());
}
-static size_t greatestCommonDivisor(size_t a, size_t b) {
+static constexpr size_t greatestCommonDivisor(size_t a, size_t b) {
return b ? greatestCommonDivisor(b, a % b) : a;
}
-inline size_t lowestCommonMultiple(size_t a, size_t b) {
+constexpr size_t lowestCommonMultiple(size_t a, size_t b) {
return a && b ? a / greatestCommonDivisor(a, b) * b : 0;
}
diff --git a/chromium/third_party/blink/renderer/platform/wtf/not_found.h b/chromium/third_party/blink/renderer/platform/wtf/not_found.h
index 765f0be3103..8a8926cc625 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/not_found.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/not_found.h
@@ -26,10 +26,10 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_NOT_FOUND_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_NOT_FOUND_H_
-#include <stddef.h>
+#include "third_party/blink/renderer/platform/wtf/wtf_size_t.h"
namespace WTF {
-const size_t kNotFound = static_cast<size_t>(-1);
+const wtf_size_t kNotFound = UINT_MAX;
}
using WTF::kNotFound;
diff --git a/chromium/third_party/blink/renderer/platform/wtf/ref_vector.h b/chromium/third_party/blink/renderer/platform/wtf/ref_vector.h
index 53e3e0a799d..8634f6d72ef 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/ref_vector.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/ref_vector.h
@@ -27,15 +27,15 @@ class RefVector : public RefCounted<RefVector<T>> {
}
scoped_refptr<RefVector> Copy() { return Create(GetVector()); }
- const T& operator[](size_t i) const { return vector_[i]; }
- T& operator[](size_t i) { return vector_[i]; }
- const T& at(size_t i) const { return vector_.at(i); }
- T& at(size_t i) { return vector_.at(i); }
+ const T& operator[](wtf_size_t i) const { return vector_[i]; }
+ T& operator[](wtf_size_t i) { return vector_[i]; }
+ const T& at(wtf_size_t i) const { return vector_.at(i); }
+ T& at(wtf_size_t i) { return vector_.at(i); }
bool operator==(const RefVector& o) const { return vector_ == o.vector_; }
bool operator!=(const RefVector& o) const { return vector_ != o.vector_; }
- size_t size() const { return vector_.size(); }
+ wtf_size_t size() const { return vector_.size(); }
bool IsEmpty() const { return !size(); }
void push_back(const T& decoration) { vector_.push_back(decoration); }
const Vector<T>& GetVector() const { return vector_; }
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 10f1c0df11f..21f49cf07a3 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/stack_util.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/stack_util.cc
@@ -143,6 +143,14 @@ void* GetStackStart() {
#endif
}
+uintptr_t GetCurrentStackPosition() {
+#if defined(COMPILER_MSVC)
+ return reinterpret_cast<uintptr_t>(_AddressOfReturnAddress());
+#else
+ return reinterpret_cast<uintptr_t>(__builtin_frame_address(0));
+#endif
+}
+
namespace internal {
uintptr_t g_main_thread_stack_start = 0;
diff --git a/chromium/third_party/blink/renderer/platform/wtf/stack_util.h b/chromium/third_party/blink/renderer/platform/wtf/stack_util.h
index b94f759bc1b..1f8c8a5c3a5 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/stack_util.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/stack_util.h
@@ -8,6 +8,7 @@
#include <stddef.h>
#include <stdint.h>
#include "build/build_config.h"
+#include "third_party/blink/renderer/platform/wtf/compiler.h"
#include "third_party/blink/renderer/platform/wtf/wtf_export.h"
namespace WTF {
@@ -15,6 +16,12 @@ namespace WTF {
WTF_EXPORT size_t GetUnderestimatedStackSize();
WTF_EXPORT void* GetStackStart();
+// Returns the current stack position such that it works correctly with ASAN and
+// SafeStack. Must be marked noinline because it relies on compiler intrinsics
+// that report the current stack frame and if inlined it could report a position
+// above the current stack position.
+WTF_EXPORT WTF_NOINLINE uintptr_t GetCurrentStackPosition();
+
namespace internal {
WTF_EXPORT extern uintptr_t g_main_thread_stack_start;
diff --git a/chromium/third_party/blink/renderer/platform/wtf/text/atomic_string.h b/chromium/third_party/blink/renderer/platform/wtf/text/atomic_string.h
index 3ace8cc9de1..30e88b133d3 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/text/atomic_string.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/text/atomic_string.h
@@ -76,7 +76,7 @@ class WTF_EXPORT AtomicString {
AtomicString(const char16_t* chars)
: AtomicString(reinterpret_cast<const UChar*>(chars)) {}
- template <size_t inlineCapacity>
+ template <wtf_size_t inlineCapacity>
explicit AtomicString(const Vector<UChar, inlineCapacity>& vector)
: AtomicString(vector.data(), vector.size()) {}
@@ -94,42 +94,44 @@ class WTF_EXPORT AtomicString {
bool Is8Bit() const { return string_.Is8Bit(); }
const LChar* Characters8() const { return string_.Characters8(); }
const UChar* Characters16() const { return string_.Characters16(); }
- unsigned length() const { return string_.length(); }
+ wtf_size_t length() const { return string_.length(); }
- UChar operator[](unsigned i) const { return string_[i]; }
+ UChar operator[](wtf_size_t i) const { return string_[i]; }
// Find characters.
- size_t find(UChar c, unsigned start = 0) const {
+ wtf_size_t find(UChar c, wtf_size_t start = 0) const {
return string_.find(c, start);
}
- size_t find(LChar c, unsigned start = 0) const {
+ wtf_size_t find(LChar c, wtf_size_t start = 0) const {
return string_.find(c, start);
}
- size_t find(char c, unsigned start = 0) const {
+ wtf_size_t find(char c, wtf_size_t start = 0) const {
return find(static_cast<LChar>(c), start);
}
- size_t Find(CharacterMatchFunctionPtr match_function,
- unsigned start = 0) const {
+ wtf_size_t Find(CharacterMatchFunctionPtr match_function,
+ wtf_size_t start = 0) const {
return string_.Find(match_function, start);
}
// Find substrings.
- size_t Find(const StringView& value,
- unsigned start = 0,
- TextCaseSensitivity case_sensitivity = kTextCaseSensitive) const {
+ wtf_size_t Find(
+ const StringView& value,
+ wtf_size_t start = 0,
+ TextCaseSensitivity case_sensitivity = kTextCaseSensitive) const {
return string_.Find(value, start, case_sensitivity);
}
// Unicode aware case insensitive string matching. Non-ASCII characters might
// match to ASCII characters. This function is rarely used to implement web
// platform features.
- size_t FindIgnoringCase(const StringView& value, unsigned start = 0) const {
+ wtf_size_t FindIgnoringCase(const StringView& value,
+ wtf_size_t start = 0) const {
return string_.FindIgnoringCase(value, start);
}
// ASCII case insensitive string matching.
- size_t FindIgnoringASCIICase(const StringView& value,
- unsigned start = 0) const {
+ wtf_size_t FindIgnoringASCIICase(const StringView& value,
+ wtf_size_t start = 0) const {
return string_.FindIgnoringASCIICase(value, start);
}
@@ -141,10 +143,11 @@ class WTF_EXPORT AtomicString {
}
// Find the last instance of a single character or string.
- size_t ReverseFind(UChar c, unsigned start = UINT_MAX) const {
+ wtf_size_t ReverseFind(UChar c, wtf_size_t start = UINT_MAX) const {
return string_.ReverseFind(c, start);
}
- size_t ReverseFind(const StringView& value, unsigned start = UINT_MAX) const {
+ wtf_size_t ReverseFind(const StringView& value,
+ wtf_size_t start = UINT_MAX) const {
return string_.ReverseFind(value, start);
}
diff --git a/chromium/third_party/blink/renderer/platform/wtf/text/cstring.cc b/chromium/third_party/blink/renderer/platform/wtf/text/cstring.cc
index 33ac70a692a..56da166af3a 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/text/cstring.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/text/cstring.cc
@@ -36,8 +36,8 @@ namespace WTF {
scoped_refptr<CStringImpl> CStringImpl::CreateUninitialized(size_t length,
char*& data) {
- unsigned length_in_unsigned = SafeCast<unsigned>(length);
- base::CheckedNumeric<size_t> size = length;
+ wtf_size_t length_in_unsigned = SafeCast<wtf_size_t>(length);
+ base::CheckedNumeric<size_t> size = length_in_unsigned;
// The +1 is for the terminating NUL character.
size += sizeof(CStringImpl) + 1;
CStringImpl* buffer = static_cast<CStringImpl*>(Partitions::BufferMalloc(
diff --git a/chromium/third_party/blink/renderer/platform/wtf/text/cstring.h b/chromium/third_party/blink/renderer/platform/wtf/text/cstring.h
index 5a912e240d4..243c76662f1 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/text/cstring.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/text/cstring.h
@@ -35,6 +35,7 @@
#include "third_party/blink/renderer/platform/wtf/allocator/partition_allocator.h"
#include "third_party/blink/renderer/platform/wtf/ref_counted.h"
#include "third_party/blink/renderer/platform/wtf/wtf_export.h"
+#include "third_party/blink/renderer/platform/wtf/wtf_size_t.h"
namespace WTF {
@@ -52,7 +53,7 @@ class WTF_EXPORT CStringImpl : public RefCounted<CStringImpl> {
char*& data);
const char* data() const { return reinterpret_cast<const char*>(this + 1); }
- size_t length() const { return length_; }
+ wtf_size_t length() const { return length_; }
private:
explicit CStringImpl(unsigned length) : length_(length) {}
@@ -80,7 +81,7 @@ class WTF_EXPORT CString {
CString(CStringImpl* buffer) : buffer_(buffer) {}
CString(scoped_refptr<CStringImpl> buffer) : buffer_(std::move(buffer)) {}
- static CString CreateUninitialized(size_t length, char*& data) {
+ static CString CreateUninitialized(wtf_size_t length, char*& data) {
return CStringImpl::CreateUninitialized(length, data);
}
@@ -88,7 +89,7 @@ class WTF_EXPORT CString {
const char* data() const { return buffer_ ? buffer_->data() : nullptr; }
// The length of the data(), *not* including the NUL terminator.
- size_t length() const { return buffer_ ? buffer_->length() : 0; }
+ wtf_size_t length() const { return buffer_ ? buffer_->length() : 0; }
bool IsNull() const { return !buffer_; }
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 2eed705ccbe..c1795ff65a0 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
@@ -258,7 +258,7 @@ bool DeprecatedEqualIgnoringCase(const StringBuilder& s,
inline bool DeprecatedEqualIgnoringCase(const StringBuilder& s,
const char* string) {
return DeprecatedEqualIgnoringCase(s, reinterpret_cast<const LChar*>(string),
- strlen(string));
+ SafeCast<wtf_size_t>(strlen(string)));
}
template <typename StringType>
diff --git a/chromium/third_party/blink/renderer/platform/wtf/text/string_concatenate.cc b/chromium/third_party/blink/renderer/platform/wtf/text/string_concatenate.cc
index ae3c881b5bc..f2f21914d0b 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/text/string_concatenate.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/text/string_concatenate.cc
@@ -24,7 +24,8 @@ void WTF::StringTypeAdapter<char*>::WriteTo(UChar* destination) const {
}
WTF::StringTypeAdapter<LChar*>::StringTypeAdapter(LChar* buffer)
- : buffer_(buffer), length_(strlen(reinterpret_cast<char*>(buffer))) {}
+ : buffer_(buffer),
+ length_(SafeCast<wtf_size_t>(strlen(reinterpret_cast<char*>(buffer)))) {}
void WTF::StringTypeAdapter<LChar*>::WriteTo(LChar* destination) const {
memcpy(destination, buffer_, length_ * sizeof(LChar));
@@ -42,7 +43,7 @@ void WTF::StringTypeAdapter<const UChar*>::WriteTo(UChar* destination) const {
}
WTF::StringTypeAdapter<const char*>::StringTypeAdapter(const char* buffer)
- : buffer_(buffer), length_(strlen(buffer)) {}
+ : buffer_(buffer), length_(SafeCast<wtf_size_t>(strlen(buffer))) {}
void WTF::StringTypeAdapter<const char*>::WriteTo(LChar* destination) const {
memcpy(destination, buffer_, static_cast<size_t>(length_) * sizeof(LChar));
@@ -56,7 +57,10 @@ void WTF::StringTypeAdapter<const char*>::WriteTo(UChar* destination) const {
}
WTF::StringTypeAdapter<const LChar*>::StringTypeAdapter(const LChar* buffer)
- : buffer_(buffer), length_(strlen(reinterpret_cast<const char*>(buffer))) {}
+ : buffer_(buffer),
+ length_(
+ SafeCast<wtf_size_t>(strlen(reinterpret_cast<const char*>(buffer)))) {
+}
void WTF::StringTypeAdapter<const LChar*>::WriteTo(LChar* destination) const {
memcpy(destination, buffer_, static_cast<size_t>(length_) * sizeof(LChar));
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 ec6efec57ab..871f2647dbc 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
@@ -102,7 +102,7 @@ std::string StringImpl::AsciiForDebugging() const {
}
#endif
-scoped_refptr<StringImpl> StringImpl::CreateUninitialized(unsigned length,
+scoped_refptr<StringImpl> StringImpl::CreateUninitialized(wtf_size_t length,
LChar*& data) {
if (!length) {
data = nullptr;
@@ -119,7 +119,7 @@ scoped_refptr<StringImpl> StringImpl::CreateUninitialized(unsigned length,
return base::AdoptRef(new (string) StringImpl(length, kForce8BitConstructor));
}
-scoped_refptr<StringImpl> StringImpl::CreateUninitialized(unsigned length,
+scoped_refptr<StringImpl> StringImpl::CreateUninitialized(wtf_size_t length,
UChar*& data) {
if (!length) {
data = nullptr;
@@ -157,7 +157,7 @@ void StringImpl::FreezeStaticStrings() {
#endif
}
-unsigned StringImpl::highest_static_string_length_ = 0;
+wtf_size_t StringImpl::highest_static_string_length_ = 0;
DEFINE_GLOBAL(StringImpl, g_global_empty);
DEFINE_GLOBAL(StringImpl, g_global_empty16_bit);
@@ -177,8 +177,8 @@ void StringImpl::InitStatics() {
}
StringImpl* StringImpl::CreateStatic(const char* string,
- unsigned length,
- unsigned hash) {
+ wtf_size_t length,
+ wtf_size_t hash) {
#if DCHECK_IS_ON()
DCHECK(g_allow_creation_of_static_strings);
#endif
@@ -195,9 +195,9 @@ StringImpl* StringImpl::CreateStatic(const char* string,
// struct as well as the data which it contains. This removes one
// heap allocation from this call.
CHECK_LE(length,
- ((std::numeric_limits<unsigned>::max() - sizeof(StringImpl)) /
+ ((std::numeric_limits<wtf_size_t>::max() - sizeof(StringImpl)) /
sizeof(LChar)));
- size_t size = sizeof(StringImpl) + length * sizeof(LChar);
+ wtf_size_t size = sizeof(StringImpl) + length * sizeof(LChar);
WTF_INTERNAL_LEAK_SANITIZER_DISABLED_SCOPE;
StringImpl* impl = static_cast<StringImpl*>(
@@ -221,7 +221,7 @@ StringImpl* StringImpl::CreateStatic(const char* string,
return impl;
}
-void StringImpl::ReserveStaticStringsCapacityForSize(unsigned size) {
+void StringImpl::ReserveStaticStringsCapacityForSize(wtf_size_t size) {
#if DCHECK_IS_ON()
DCHECK(g_allow_creation_of_static_strings);
#endif
@@ -229,7 +229,7 @@ void StringImpl::ReserveStaticStringsCapacityForSize(unsigned size) {
}
scoped_refptr<StringImpl> StringImpl::Create(const UChar* characters,
- unsigned length) {
+ wtf_size_t length) {
if (!characters || !length)
return empty_;
@@ -240,7 +240,7 @@ scoped_refptr<StringImpl> StringImpl::Create(const UChar* characters,
}
scoped_refptr<StringImpl> StringImpl::Create(const LChar* characters,
- unsigned length) {
+ wtf_size_t length) {
if (!characters || !length)
return empty_;
@@ -252,14 +252,14 @@ scoped_refptr<StringImpl> StringImpl::Create(const LChar* characters,
scoped_refptr<StringImpl> StringImpl::Create8BitIfPossible(
const UChar* characters,
- unsigned length) {
+ wtf_size_t length) {
if (!characters || !length)
return empty_;
LChar* data;
scoped_refptr<StringImpl> string = CreateUninitialized(length, data);
- for (size_t i = 0; i < length; ++i) {
+ for (wtf_size_t i = 0; i < length; ++i) {
if (characters[i] & 0xff00)
return Create(characters, length);
data[i] = static_cast<LChar>(characters[i]);
@@ -272,8 +272,7 @@ scoped_refptr<StringImpl> StringImpl::Create(const LChar* string) {
if (!string)
return empty_;
size_t length = strlen(reinterpret_cast<const char*>(string));
- CHECK_LE(length, numeric_limits<unsigned>::max());
- return Create(string, length);
+ return Create(string, SafeCast<wtf_size_t>(length));
}
bool StringImpl::ContainsOnlyWhitespace() {
@@ -281,7 +280,7 @@ bool StringImpl::ContainsOnlyWhitespace() {
// that are not whitespace from the point of view of LayoutText; I wonder if
// that's a problem in practice.
if (Is8Bit()) {
- for (unsigned i = 0; i < length_; ++i) {
+ for (wtf_size_t i = 0; i < length_; ++i) {
UChar c = Characters8()[i];
if (!IsASCIISpace(c))
return false;
@@ -290,7 +289,7 @@ bool StringImpl::ContainsOnlyWhitespace() {
return true;
}
- for (unsigned i = 0; i < length_; ++i) {
+ for (wtf_size_t i = 0; i < length_; ++i) {
UChar c = Characters16()[i];
if (!IsASCIISpace(c))
return false;
@@ -298,11 +297,11 @@ bool StringImpl::ContainsOnlyWhitespace() {
return true;
}
-scoped_refptr<StringImpl> StringImpl::Substring(unsigned start,
- unsigned length) const {
+scoped_refptr<StringImpl> StringImpl::Substring(wtf_size_t start,
+ wtf_size_t length) const {
if (start >= length_)
return empty_;
- unsigned max_length = length_ - start;
+ wtf_size_t max_length = length_ - start;
if (length >= max_length) {
// RefPtr has trouble dealing with const arguments. It should be updated
// so this const_cast is not necessary.
@@ -316,7 +315,7 @@ scoped_refptr<StringImpl> StringImpl::Substring(unsigned start,
return Create(Characters16() + start, length);
}
-UChar32 StringImpl::CharacterStartingAt(unsigned i) {
+UChar32 StringImpl::CharacterStartingAt(wtf_size_t i) {
if (Is8Bit())
return Characters8()[i];
if (U16_IS_SINGLE(Characters16()[i]))
@@ -327,10 +326,10 @@ UChar32 StringImpl::CharacterStartingAt(unsigned i) {
return 0;
}
-unsigned StringImpl::CopyTo(UChar* buffer,
- unsigned start,
- unsigned max_length) const {
- unsigned number_of_characters_to_copy =
+wtf_size_t StringImpl::CopyTo(UChar* buffer,
+ wtf_size_t start,
+ wtf_size_t max_length) const {
+ wtf_size_t number_of_characters_to_copy =
std::min(length() - start, max_length);
if (!number_of_characters_to_copy)
return 0;
@@ -344,8 +343,8 @@ unsigned StringImpl::CopyTo(UChar* buffer,
scoped_refptr<StringImpl> StringImpl::LowerASCII() {
// First scan the string for uppercase and non-ASCII characters:
if (Is8Bit()) {
- unsigned first_index_to_be_lowered = length_;
- for (unsigned i = 0; i < length_; ++i) {
+ wtf_size_t first_index_to_be_lowered = length_;
+ for (wtf_size_t i = 0; i < length_; ++i) {
LChar ch = Characters8()[i];
if (IsASCIIUpper(ch)) {
first_index_to_be_lowered = i;
@@ -362,7 +361,7 @@ scoped_refptr<StringImpl> StringImpl::LowerASCII() {
scoped_refptr<StringImpl> new_impl = CreateUninitialized(length_, data8);
memcpy(data8, Characters8(), first_index_to_be_lowered);
- for (unsigned i = first_index_to_be_lowered; i < length_; ++i) {
+ for (wtf_size_t i = first_index_to_be_lowered; i < length_; ++i) {
LChar ch = Characters8()[i];
data8[i] = IsASCIIUpper(ch) ? ToASCIILower(ch) : ch;
}
@@ -381,13 +380,13 @@ scoped_refptr<StringImpl> StringImpl::LowerASCII() {
if (no_upper && !(ored & ~0x7F))
return this;
- CHECK_LE(length_, static_cast<unsigned>(numeric_limits<unsigned>::max()));
- unsigned length = length_;
+ CHECK_LE(length_, static_cast<wtf_size_t>(numeric_limits<wtf_size_t>::max()));
+ wtf_size_t length = length_;
UChar* data16;
scoped_refptr<StringImpl> new_impl = CreateUninitialized(length_, data16);
- for (unsigned i = 0; i < length; ++i) {
+ for (wtf_size_t i = 0; i < length; ++i) {
UChar c = Characters16()[i];
data16[i] = IsASCIIUpper(c) ? ToASCIILower(c) : c;
}
@@ -400,8 +399,8 @@ scoped_refptr<StringImpl> StringImpl::LowerUnicode() {
// First scan the string for uppercase and non-ASCII characters:
if (Is8Bit()) {
- unsigned first_index_to_be_lowered = length_;
- for (unsigned i = 0; i < length_; ++i) {
+ wtf_size_t first_index_to_be_lowered = length_;
+ for (wtf_size_t i = 0; i < length_; ++i) {
LChar ch = Characters8()[i];
if (UNLIKELY(IsASCIIUpper(ch) || ch & ~0x7F)) {
first_index_to_be_lowered = i;
@@ -417,7 +416,7 @@ scoped_refptr<StringImpl> StringImpl::LowerUnicode() {
scoped_refptr<StringImpl> new_impl = CreateUninitialized(length_, data8);
memcpy(data8, Characters8(), first_index_to_be_lowered);
- for (unsigned i = first_index_to_be_lowered; i < length_; ++i) {
+ for (wtf_size_t i = first_index_to_be_lowered; i < length_; ++i) {
LChar ch = Characters8()[i];
data8[i] = UNLIKELY(ch & ~0x7F) ? static_cast<LChar>(Unicode::ToLower(ch))
: ToASCIILower(ch);
@@ -439,7 +438,7 @@ scoped_refptr<StringImpl> StringImpl::LowerUnicode() {
if (no_upper && !(ored & ~0x7F))
return this;
- CHECK_LE(length_, static_cast<unsigned>(numeric_limits<int32_t>::max()));
+ CHECK_LE(length_, static_cast<wtf_size_t>(numeric_limits<int32_t>::max()));
int32_t length = length_;
if (!(ored & ~0x7F)) {
@@ -475,7 +474,7 @@ scoped_refptr<StringImpl> StringImpl::UpperUnicode() {
// but in empirical testing, few actual calls to UpperUnicode() are no-ops, so
// it wouldn't be worth the extra time for pre-scanning.
- CHECK_LE(length_, static_cast<unsigned>(numeric_limits<int32_t>::max()));
+ CHECK_LE(length_, static_cast<wtf_size_t>(numeric_limits<int32_t>::max()));
int32_t length = length_;
if (Is8Bit()) {
@@ -570,7 +569,7 @@ scoped_refptr<StringImpl> StringImpl::UpperASCII() {
LChar* data8;
scoped_refptr<StringImpl> new_impl = CreateUninitialized(length_, data8);
- for (unsigned i = 0; i < length_; ++i) {
+ for (wtf_size_t i = 0; i < length_; ++i) {
LChar c = Characters8()[i];
data8[i] = IsASCIILower(c) ? ToASCIIUpper(c) : c;
}
@@ -580,7 +579,7 @@ scoped_refptr<StringImpl> StringImpl::UpperASCII() {
UChar* data16;
scoped_refptr<StringImpl> new_impl = CreateUninitialized(length_, data16);
- for (unsigned i = 0; i < length_; ++i) {
+ for (wtf_size_t i = 0; i < length_; ++i) {
UChar c = Characters16()[i];
data16[i] = IsASCIILower(c) ? ToASCIIUpper(c) : c;
}
@@ -608,12 +607,12 @@ typedef int32_t (*icuCaseConverter)(UChar*,
UErrorCode*);
static scoped_refptr<StringImpl> CaseConvert(const UChar* source16,
- size_t length,
+ wtf_size_t length,
icuCaseConverter converter,
const char* locale,
StringImpl* original_string) {
UChar* data16;
- size_t target_length = length;
+ wtf_size_t target_length = length;
scoped_refptr<StringImpl> output =
StringImpl::CreateUninitialized(length, data16);
do {
@@ -649,7 +648,7 @@ scoped_refptr<StringImpl> StringImpl::LowerUnicode(
else
return LowerUnicode();
- CHECK_LE(length_, static_cast<unsigned>(numeric_limits<int32_t>::max()));
+ CHECK_LE(length_, static_cast<wtf_size_t>(numeric_limits<int32_t>::max()));
int length = length_;
scoped_refptr<StringImpl> upconverted = UpconvertedString();
@@ -674,7 +673,7 @@ scoped_refptr<StringImpl> StringImpl::UpperUnicode(
else
return UpperUnicode();
- CHECK_LE(length_, static_cast<unsigned>(numeric_limits<int32_t>::max()));
+ CHECK_LE(length_, static_cast<wtf_size_t>(numeric_limits<int32_t>::max()));
int length = length_;
scoped_refptr<StringImpl> upconverted = UpconvertedString();
@@ -688,19 +687,19 @@ scoped_refptr<StringImpl> StringImpl::Fill(UChar character) {
if (!(character & ~0x7F)) {
LChar* data;
scoped_refptr<StringImpl> new_impl = CreateUninitialized(length_, data);
- for (unsigned i = 0; i < length_; ++i)
+ for (wtf_size_t i = 0; i < length_; ++i)
data[i] = static_cast<LChar>(character);
return new_impl;
}
UChar* data;
scoped_refptr<StringImpl> new_impl = CreateUninitialized(length_, data);
- for (unsigned i = 0; i < length_; ++i)
+ for (wtf_size_t i = 0; i < length_; ++i)
data[i] = character;
return new_impl;
}
scoped_refptr<StringImpl> StringImpl::FoldCase() {
- CHECK_LE(length_, static_cast<unsigned>(numeric_limits<int32_t>::max()));
+ CHECK_LE(length_, static_cast<wtf_size_t>(numeric_limits<int32_t>::max()));
int32_t length = length_;
if (Is8Bit()) {
@@ -751,7 +750,7 @@ scoped_refptr<StringImpl> StringImpl::FoldCase() {
return new_impl;
}
-scoped_refptr<StringImpl> StringImpl::Truncate(unsigned length) {
+scoped_refptr<StringImpl> StringImpl::Truncate(wtf_size_t length) {
if (length >= length_)
return this;
if (Is8Bit())
@@ -765,8 +764,8 @@ inline scoped_refptr<StringImpl> StringImpl::StripMatchedCharacters(
if (!length_)
return empty_;
- unsigned start = 0;
- unsigned end = length_ - 1;
+ wtf_size_t start = 0;
+ wtf_size_t end = length_ - 1;
// skip white space from start
while (start <= end &&
@@ -832,7 +831,7 @@ ALWAYS_INLINE scoped_refptr<StringImpl> StringImpl::RemoveCharacters(
StringBuffer<CharType> data(length_);
CharType* to = data.Characters();
- unsigned outc = from - characters;
+ wtf_size_t outc = static_cast<wtf_size_t>(from - characters);
if (outc)
memcpy(to, characters, outc * sizeof(CharType));
@@ -858,15 +857,15 @@ scoped_refptr<StringImpl> StringImpl::RemoveCharacters(
return RemoveCharacters(Characters16(), find_match);
}
-scoped_refptr<StringImpl> StringImpl::Remove(unsigned start,
- unsigned length_to_remove) {
+scoped_refptr<StringImpl> StringImpl::Remove(wtf_size_t start,
+ wtf_size_t length_to_remove) {
if (length_to_remove <= 0)
return this;
if (start >= length_)
return this;
length_to_remove = std::min(length_ - start, length_to_remove);
- unsigned removed_end = start + length_to_remove;
+ wtf_size_t removed_end = start + length_to_remove;
if (Is8Bit()) {
StringBuffer<LChar> buffer(length_ - length_to_remove);
@@ -924,7 +923,7 @@ inline scoped_refptr<StringImpl> StringImpl::SimplifyMatchedCharactersToSpace(
}
}
- if (static_cast<unsigned>(outc) == length_ && !changed_to_space)
+ if (static_cast<wtf_size_t>(outc) == length_ && !changed_to_space)
return this;
data.Shrink(outc);
@@ -957,13 +956,13 @@ int StringImpl::ToInt(NumberParsingOptions options, bool* ok) const {
return CharactersToInt(Characters16(), length_, options, ok);
}
-unsigned StringImpl::ToUInt(NumberParsingOptions options, bool* ok) const {
+wtf_size_t StringImpl::ToUInt(NumberParsingOptions options, bool* ok) const {
if (Is8Bit())
return CharactersToUInt(Characters8(), length_, options, ok);
return CharactersToUInt(Characters16(), length_, options, ok);
}
-unsigned StringImpl::HexToUIntStrict(bool* ok) {
+wtf_size_t StringImpl::HexToUIntStrict(bool* ok) {
if (Is8Bit()) {
return HexCharactersToUInt(Characters8(), length_,
NumberParsingOptions::kStrict, ok);
@@ -1031,7 +1030,7 @@ const UChar StringImpl::kLatin1CaseFoldTable[256] = {
bool DeprecatedEqualIgnoringCase(const LChar* a,
const LChar* b,
- unsigned length) {
+ wtf_size_t length) {
DCHECK_GE(length, 0u);
if (a == b)
return true;
@@ -1045,7 +1044,7 @@ bool DeprecatedEqualIgnoringCase(const LChar* a,
bool DeprecatedEqualIgnoringCase(const UChar* a,
const UChar* b,
- unsigned length) {
+ wtf_size_t length) {
DCHECK_GE(length, 0u);
if (a == b)
return true;
@@ -1054,7 +1053,7 @@ bool DeprecatedEqualIgnoringCase(const UChar* a,
bool DeprecatedEqualIgnoringCase(const UChar* a,
const LChar* b,
- unsigned length) {
+ wtf_size_t length) {
while (length--) {
if (Unicode::FoldCase(*a++) != StringImpl::kLatin1CaseFoldTable[*b++])
return false;
@@ -1062,36 +1061,36 @@ bool DeprecatedEqualIgnoringCase(const UChar* a,
return true;
}
-size_t StringImpl::Find(CharacterMatchFunctionPtr match_function,
- unsigned start) {
+wtf_size_t StringImpl::Find(CharacterMatchFunctionPtr match_function,
+ wtf_size_t start) {
if (Is8Bit())
return WTF::Find(Characters8(), length_, match_function, start);
return WTF::Find(Characters16(), length_, match_function, start);
}
template <typename SearchCharacterType, typename MatchCharacterType>
-ALWAYS_INLINE static size_t FindInternal(
+ALWAYS_INLINE static wtf_size_t FindInternal(
const SearchCharacterType* search_characters,
const MatchCharacterType* match_characters,
- unsigned index,
- unsigned search_length,
- unsigned match_length) {
+ wtf_size_t index,
+ wtf_size_t search_length,
+ wtf_size_t match_length) {
// Optimization: keep a running hash of the strings,
// only call equal() if the hashes match.
// delta is the number of additional times to test; delta == 0 means test only
// once.
- unsigned delta = search_length - match_length;
+ wtf_size_t delta = search_length - match_length;
- unsigned search_hash = 0;
- unsigned match_hash = 0;
+ wtf_size_t search_hash = 0;
+ wtf_size_t match_hash = 0;
- for (unsigned i = 0; i < match_length; ++i) {
+ for (wtf_size_t i = 0; i < match_length; ++i) {
search_hash += search_characters[i];
match_hash += match_characters[i];
}
- unsigned i = 0;
+ wtf_size_t i = 0;
// keep looping until we match
while (search_hash != match_hash ||
!Equal(search_characters + i, match_characters, match_length)) {
@@ -1104,11 +1103,11 @@ ALWAYS_INLINE static size_t FindInternal(
return index + i;
}
-size_t StringImpl::Find(const StringView& match_string, unsigned index) {
+wtf_size_t StringImpl::Find(const StringView& match_string, wtf_size_t index) {
if (UNLIKELY(match_string.IsNull()))
return kNotFound;
- unsigned match_length = match_string.length();
+ wtf_size_t match_length = match_string.length();
// Optimization 1: fast case for strings of length 1.
if (match_length == 1) {
@@ -1123,7 +1122,7 @@ size_t StringImpl::Find(const StringView& match_string, unsigned index) {
// Check index & matchLength are in range.
if (index > length())
return kNotFound;
- unsigned search_length = length() - index;
+ wtf_size_t search_length = length() - index;
if (match_length > search_length)
return kNotFound;
@@ -1142,17 +1141,17 @@ size_t StringImpl::Find(const StringView& match_string, unsigned index) {
}
template <typename SearchCharacterType, typename MatchCharacterType>
-ALWAYS_INLINE static size_t FindIgnoringCaseInternal(
+ALWAYS_INLINE static wtf_size_t FindIgnoringCaseInternal(
const SearchCharacterType* search_characters,
const MatchCharacterType* match_characters,
- unsigned index,
- unsigned search_length,
- unsigned match_length) {
+ wtf_size_t index,
+ wtf_size_t search_length,
+ wtf_size_t match_length) {
// delta is the number of additional times to test; delta == 0 means test only
// once.
- unsigned delta = search_length - match_length;
+ wtf_size_t delta = search_length - match_length;
- unsigned i = 0;
+ wtf_size_t i = 0;
// keep looping until we match
while (!DeprecatedEqualIgnoringCase(search_characters + i, match_characters,
match_length)) {
@@ -1163,19 +1162,19 @@ ALWAYS_INLINE static size_t FindIgnoringCaseInternal(
return index + i;
}
-size_t StringImpl::FindIgnoringCase(const StringView& match_string,
- unsigned index) {
+wtf_size_t StringImpl::FindIgnoringCase(const StringView& match_string,
+ wtf_size_t index) {
if (UNLIKELY(match_string.IsNull()))
return kNotFound;
- unsigned match_length = match_string.length();
+ wtf_size_t match_length = match_string.length();
if (!match_length)
return std::min(index, length());
// Check index & matchLength are in range.
if (index > length())
return kNotFound;
- unsigned search_length = length() - index;
+ wtf_size_t search_length = length() - index;
if (match_length > search_length)
return kNotFound;
@@ -1198,17 +1197,17 @@ size_t StringImpl::FindIgnoringCase(const StringView& match_string,
}
template <typename SearchCharacterType, typename MatchCharacterType>
-ALWAYS_INLINE static size_t FindIgnoringASCIICaseInternal(
+ALWAYS_INLINE static wtf_size_t FindIgnoringASCIICaseInternal(
const SearchCharacterType* search_characters,
const MatchCharacterType* match_characters,
- unsigned index,
- unsigned search_length,
- unsigned match_length) {
+ wtf_size_t index,
+ wtf_size_t search_length,
+ wtf_size_t match_length) {
// delta is the number of additional times to test; delta == 0 means test only
// once.
- unsigned delta = search_length - match_length;
+ wtf_size_t delta = search_length - match_length;
- unsigned i = 0;
+ wtf_size_t i = 0;
// keep looping until we match
while (!EqualIgnoringASCIICase(search_characters + i, match_characters,
match_length)) {
@@ -1219,19 +1218,19 @@ ALWAYS_INLINE static size_t FindIgnoringASCIICaseInternal(
return index + i;
}
-size_t StringImpl::FindIgnoringASCIICase(const StringView& match_string,
- unsigned index) {
+wtf_size_t StringImpl::FindIgnoringASCIICase(const StringView& match_string,
+ wtf_size_t index) {
if (UNLIKELY(match_string.IsNull()))
return kNotFound;
- unsigned match_length = match_string.length();
+ wtf_size_t match_length = match_string.length();
if (!match_length)
return std::min(index, length());
// Check index & matchLength are in range.
if (index > length())
return kNotFound;
- unsigned search_length = length() - index;
+ wtf_size_t search_length = length() - index;
if (match_length > search_length)
return kNotFound;
@@ -1253,29 +1252,29 @@ size_t StringImpl::FindIgnoringASCIICase(const StringView& match_string,
search_length, match_length);
}
-size_t StringImpl::ReverseFind(UChar c, unsigned index) {
+wtf_size_t StringImpl::ReverseFind(UChar c, wtf_size_t index) {
if (Is8Bit())
return WTF::ReverseFind(Characters8(), length_, c, index);
return WTF::ReverseFind(Characters16(), length_, c, index);
}
template <typename SearchCharacterType, typename MatchCharacterType>
-ALWAYS_INLINE static size_t ReverseFindInternal(
+ALWAYS_INLINE static wtf_size_t ReverseFindInternal(
const SearchCharacterType* search_characters,
const MatchCharacterType* match_characters,
- unsigned index,
- unsigned length,
- unsigned match_length) {
+ wtf_size_t index,
+ wtf_size_t length,
+ wtf_size_t match_length) {
// Optimization: keep a running hash of the strings,
// only call equal if the hashes match.
// delta is the number of additional times to test; delta == 0 means test only
// once.
- unsigned delta = std::min(index, length - match_length);
+ wtf_size_t delta = std::min(index, length - match_length);
- unsigned search_hash = 0;
- unsigned match_hash = 0;
- for (unsigned i = 0; i < match_length; ++i) {
+ wtf_size_t search_hash = 0;
+ wtf_size_t match_hash = 0;
+ for (wtf_size_t i = 0; i < match_length; ++i) {
search_hash += search_characters[delta + i];
match_hash += match_characters[i];
}
@@ -1292,12 +1291,13 @@ ALWAYS_INLINE static size_t ReverseFindInternal(
return delta;
}
-size_t StringImpl::ReverseFind(const StringView& match_string, unsigned index) {
+wtf_size_t StringImpl::ReverseFind(const StringView& match_string,
+ wtf_size_t index) {
if (UNLIKELY(match_string.IsNull()))
return kNotFound;
- unsigned match_length = match_string.length();
- unsigned our_length = length();
+ wtf_size_t match_length = match_string.length();
+ wtf_size_t our_length = length();
if (!match_length)
return std::min(index, our_length);
@@ -1387,7 +1387,7 @@ bool StringImpl::EndsWith(UChar character) const {
bool StringImpl::EndsWith(const StringView& suffix) const {
if (suffix.length() > length())
return false;
- unsigned start_offset = length() - suffix.length();
+ wtf_size_t start_offset = length() - suffix.length();
if (Is8Bit()) {
if (suffix.Is8Bit())
return Equal(Characters8() + start_offset, suffix.Characters8(),
@@ -1405,7 +1405,7 @@ bool StringImpl::EndsWith(const StringView& suffix) const {
bool StringImpl::EndsWithIgnoringCase(const StringView& suffix) const {
if (suffix.length() > length())
return false;
- unsigned start_offset = length() - suffix.length();
+ wtf_size_t start_offset = length() - suffix.length();
if (Is8Bit()) {
if (suffix.Is8Bit()) {
return DeprecatedEqualIgnoringCase(Characters8() + start_offset,
@@ -1425,7 +1425,7 @@ bool StringImpl::EndsWithIgnoringCase(const StringView& suffix) const {
bool StringImpl::EndsWithIgnoringASCIICase(const StringView& suffix) const {
if (suffix.length() > length())
return false;
- unsigned start_offset = length() - suffix.length();
+ wtf_size_t start_offset = length() - suffix.length();
if (Is8Bit()) {
if (suffix.Is8Bit())
return EqualIgnoringASCIICase(Characters8() + start_offset,
@@ -1447,7 +1447,7 @@ scoped_refptr<StringImpl> StringImpl::Replace(UChar old_c, UChar new_c) {
if (Find(old_c) == kNotFound)
return this;
- unsigned i;
+ wtf_size_t i;
if (Is8Bit()) {
if (new_c <= 0xff) {
LChar* data;
@@ -1495,17 +1495,17 @@ scoped_refptr<StringImpl> StringImpl::Replace(UChar old_c, UChar new_c) {
// TODO(esprehn): Passing a null replacement is the same as empty string for
// this method but all others treat null as a no-op. We should choose one
// behavior.
-scoped_refptr<StringImpl> StringImpl::Replace(unsigned position,
- unsigned length_to_replace,
+scoped_refptr<StringImpl> StringImpl::Replace(wtf_size_t position,
+ wtf_size_t length_to_replace,
const StringView& string) {
position = std::min(position, length());
length_to_replace = std::min(length_to_replace, length() - position);
- unsigned length_to_insert = string.length();
+ wtf_size_t length_to_insert = string.length();
if (!length_to_replace && !length_to_insert)
return this;
CHECK_LT((length() - length_to_replace),
- (numeric_limits<unsigned>::max() - length_to_insert));
+ (numeric_limits<wtf_size_t>::max() - length_to_insert));
if (Is8Bit() && (string.IsNull() || string.Is8Bit())) {
LChar* data;
@@ -1524,20 +1524,20 @@ scoped_refptr<StringImpl> StringImpl::Replace(unsigned position,
scoped_refptr<StringImpl> new_impl = CreateUninitialized(
length() - length_to_replace + length_to_insert, data);
if (Is8Bit())
- for (unsigned i = 0; i < position; ++i)
+ for (wtf_size_t i = 0; i < position; ++i)
data[i] = Characters8()[i];
else
memcpy(data, Characters16(), position * sizeof(UChar));
if (!string.IsNull()) {
if (string.Is8Bit())
- for (unsigned i = 0; i < length_to_insert; ++i)
+ for (wtf_size_t i = 0; i < length_to_insert; ++i)
data[i + position] = string.Characters8()[i];
else
memcpy(data + position, string.Characters16(),
length_to_insert * sizeof(UChar));
}
if (Is8Bit()) {
- for (unsigned i = 0; i < length() - position - length_to_replace; ++i)
+ for (wtf_size_t i = 0; i < length() - position - length_to_replace; ++i)
data[i + position + length_to_insert] =
Characters8()[i + position + length_to_replace];
} else {
@@ -1559,11 +1559,11 @@ scoped_refptr<StringImpl> StringImpl::Replace(UChar pattern,
scoped_refptr<StringImpl> StringImpl::Replace(UChar pattern,
const LChar* replacement,
- unsigned rep_str_length) {
+ wtf_size_t rep_str_length) {
DCHECK(replacement);
- size_t src_segment_start = 0;
- unsigned match_count = 0;
+ wtf_size_t src_segment_start = 0;
+ wtf_size_t match_count = 0;
// Count the matches.
while ((src_segment_start = Find(pattern, src_segment_start)) != kNotFound) {
@@ -1576,19 +1576,19 @@ scoped_refptr<StringImpl> StringImpl::Replace(UChar pattern,
return this;
CHECK(!rep_str_length ||
- match_count <= numeric_limits<unsigned>::max() / rep_str_length);
+ match_count <= numeric_limits<wtf_size_t>::max() / rep_str_length);
- unsigned replace_size = match_count * rep_str_length;
- unsigned new_size = length_ - match_count;
- CHECK_LT(new_size, (numeric_limits<unsigned>::max() - replace_size));
+ wtf_size_t replace_size = match_count * rep_str_length;
+ wtf_size_t new_size = length_ - match_count;
+ CHECK_LT(new_size, (numeric_limits<wtf_size_t>::max() - replace_size));
new_size += replace_size;
// Construct the new data.
- size_t src_segment_end;
- unsigned src_segment_length;
+ wtf_size_t src_segment_end;
+ wtf_size_t src_segment_length;
src_segment_start = 0;
- unsigned dst_offset = 0;
+ wtf_size_t dst_offset = 0;
if (Is8Bit()) {
LChar* data;
@@ -1622,7 +1622,7 @@ scoped_refptr<StringImpl> StringImpl::Replace(UChar pattern,
src_segment_length * sizeof(UChar));
dst_offset += src_segment_length;
- for (unsigned i = 0; i < rep_str_length; ++i)
+ for (wtf_size_t i = 0; i < rep_str_length; ++i)
data[i + dst_offset] = replacement[i];
dst_offset += rep_str_length;
@@ -1640,11 +1640,11 @@ scoped_refptr<StringImpl> StringImpl::Replace(UChar pattern,
scoped_refptr<StringImpl> StringImpl::Replace(UChar pattern,
const UChar* replacement,
- unsigned rep_str_length) {
+ wtf_size_t rep_str_length) {
DCHECK(replacement);
- size_t src_segment_start = 0;
- unsigned match_count = 0;
+ wtf_size_t src_segment_start = 0;
+ wtf_size_t match_count = 0;
// Count the matches.
while ((src_segment_start = Find(pattern, src_segment_start)) != kNotFound) {
@@ -1657,19 +1657,19 @@ scoped_refptr<StringImpl> StringImpl::Replace(UChar pattern,
return this;
CHECK(!rep_str_length ||
- match_count <= numeric_limits<unsigned>::max() / rep_str_length);
+ match_count <= numeric_limits<wtf_size_t>::max() / rep_str_length);
- unsigned replace_size = match_count * rep_str_length;
- unsigned new_size = length_ - match_count;
- CHECK_LT(new_size, (numeric_limits<unsigned>::max() - replace_size));
+ wtf_size_t replace_size = match_count * rep_str_length;
+ wtf_size_t new_size = length_ - match_count;
+ CHECK_LT(new_size, (numeric_limits<wtf_size_t>::max() - replace_size));
new_size += replace_size;
// Construct the new data.
- size_t src_segment_end;
- unsigned src_segment_length;
+ wtf_size_t src_segment_end;
+ wtf_size_t src_segment_length;
src_segment_start = 0;
- unsigned dst_offset = 0;
+ wtf_size_t dst_offset = 0;
if (Is8Bit()) {
UChar* data;
@@ -1677,7 +1677,7 @@ scoped_refptr<StringImpl> StringImpl::Replace(UChar pattern,
while ((src_segment_end = Find(pattern, src_segment_start)) != kNotFound) {
src_segment_length = src_segment_end - src_segment_start;
- for (unsigned i = 0; i < src_segment_length; ++i)
+ for (wtf_size_t i = 0; i < src_segment_length; ++i)
data[i + dst_offset] = Characters8()[i + src_segment_start];
dst_offset += src_segment_length;
@@ -1688,7 +1688,7 @@ scoped_refptr<StringImpl> StringImpl::Replace(UChar pattern,
}
src_segment_length = length_ - src_segment_start;
- for (unsigned i = 0; i < src_segment_length; ++i)
+ for (wtf_size_t i = 0; i < src_segment_length; ++i)
data[i + dst_offset] = Characters8()[i + src_segment_start];
DCHECK_EQ(dst_offset + src_segment_length, new_impl->length());
@@ -1725,13 +1725,13 @@ scoped_refptr<StringImpl> StringImpl::Replace(const StringView& pattern,
if (pattern.IsNull() || replacement.IsNull())
return this;
- unsigned pattern_length = pattern.length();
+ wtf_size_t pattern_length = pattern.length();
if (!pattern_length)
return this;
- unsigned rep_str_length = replacement.length();
- size_t src_segment_start = 0;
- unsigned match_count = 0;
+ wtf_size_t rep_str_length = replacement.length();
+ wtf_size_t src_segment_start = 0;
+ wtf_size_t match_count = 0;
// Count the matches.
while ((src_segment_start = Find(pattern, src_segment_start)) != kNotFound) {
@@ -1743,20 +1743,20 @@ scoped_refptr<StringImpl> StringImpl::Replace(const StringView& pattern,
if (!match_count)
return this;
- unsigned new_size = length_ - match_count * pattern_length;
+ wtf_size_t new_size = length_ - match_count * pattern_length;
CHECK(!rep_str_length ||
- match_count <= numeric_limits<unsigned>::max() / rep_str_length);
+ match_count <= numeric_limits<wtf_size_t>::max() / rep_str_length);
CHECK_LE(new_size,
- (numeric_limits<unsigned>::max() - match_count * rep_str_length));
+ (numeric_limits<wtf_size_t>::max() - match_count * rep_str_length));
new_size += match_count * rep_str_length;
// Construct the new data
- size_t src_segment_end;
- unsigned src_segment_length;
+ wtf_size_t src_segment_end;
+ wtf_size_t src_segment_length;
src_segment_start = 0;
- unsigned dst_offset = 0;
+ wtf_size_t dst_offset = 0;
bool src_is8_bit = Is8Bit();
bool replacement_is8_bit = replacement.Is8Bit();
@@ -1795,7 +1795,7 @@ scoped_refptr<StringImpl> StringImpl::Replace(const StringView& pattern,
src_segment_length = src_segment_end - src_segment_start;
if (src_is8_bit) {
// Case 3.
- for (unsigned i = 0; i < src_segment_length; ++i)
+ for (wtf_size_t i = 0; i < src_segment_length; ++i)
data[i + dst_offset] = Characters8()[i + src_segment_start];
} else {
// Case 2 & 4.
@@ -1805,7 +1805,7 @@ scoped_refptr<StringImpl> StringImpl::Replace(const StringView& pattern,
dst_offset += src_segment_length;
if (replacement_is8_bit) {
// Cases 2 & 3.
- for (unsigned i = 0; i < rep_str_length; ++i)
+ for (wtf_size_t i = 0; i < rep_str_length; ++i)
data[i + dst_offset] = replacement.Characters8()[i];
} else {
// Case 4
@@ -1819,7 +1819,7 @@ scoped_refptr<StringImpl> StringImpl::Replace(const StringView& pattern,
src_segment_length = length_ - src_segment_start;
if (src_is8_bit) {
// Case 3.
- for (unsigned i = 0; i < src_segment_length; ++i)
+ for (wtf_size_t i = 0; i < src_segment_length; ++i)
data[i + dst_offset] = Characters8()[i + src_segment_start];
} else {
// Cases 2 & 4.
@@ -1841,8 +1841,8 @@ scoped_refptr<StringImpl> StringImpl::UpconvertedString() {
static inline bool StringImplContentEqual(const StringImpl* a,
const StringImpl* b) {
- unsigned a_length = a->length();
- unsigned b_length = b->length();
+ wtf_size_t a_length = a->length();
+ wtf_size_t b_length = b->length();
if (a_length != b_length)
return false;
@@ -1873,7 +1873,7 @@ bool Equal(const StringImpl* a, const StringImpl* b) {
template <typename CharType>
inline bool EqualInternal(const StringImpl* a,
const CharType* b,
- unsigned length) {
+ wtf_size_t length) {
if (!a)
return !b;
if (!b)
@@ -1886,11 +1886,11 @@ inline bool EqualInternal(const StringImpl* a,
return Equal(a->Characters16(), b, length);
}
-bool Equal(const StringImpl* a, const LChar* b, unsigned length) {
+bool Equal(const StringImpl* a, const LChar* b, wtf_size_t length) {
return EqualInternal(a, b, length);
}
-bool Equal(const StringImpl* a, const UChar* b, unsigned length) {
+bool Equal(const StringImpl* a, const UChar* b, wtf_size_t length) {
return EqualInternal(a, b, length);
}
@@ -1900,11 +1900,11 @@ bool Equal(const StringImpl* a, const LChar* b) {
if (!b)
return !a;
- unsigned length = a->length();
+ wtf_size_t length = a->length();
if (a->Is8Bit()) {
const LChar* a_ptr = a->Characters8();
- for (unsigned i = 0; i != length; ++i) {
+ for (wtf_size_t i = 0; i != length; ++i) {
LChar bc = b[i];
LChar ac = a_ptr[i];
if (!bc)
@@ -1917,7 +1917,7 @@ bool Equal(const StringImpl* a, const LChar* b) {
}
const UChar* a_ptr = a->Characters16();
- for (unsigned i = 0; i != length; ++i) {
+ for (wtf_size_t i = 0; i != length; ++i) {
LChar bc = b[i];
if (!bc)
return false;
@@ -1946,12 +1946,12 @@ bool EqualIgnoringNullity(StringImpl* a, StringImpl* b) {
}
template <typename CharacterType1, typename CharacterType2>
-int CodePointCompareIgnoringASCIICase(unsigned l1,
- unsigned l2,
+int CodePointCompareIgnoringASCIICase(wtf_size_t l1,
+ wtf_size_t l2,
const CharacterType1* c1,
const CharacterType2* c2) {
- const unsigned lmin = l1 < l2 ? l1 : l2;
- unsigned pos = 0;
+ const wtf_size_t lmin = l1 < l2 ? l1 : l2;
+ wtf_size_t pos = 0;
while (pos < lmin && ToASCIILower(*c1) == ToASCIILower(*c2)) {
++c1;
++c2;
@@ -1969,8 +1969,9 @@ int CodePointCompareIgnoringASCIICase(unsigned l1,
int CodePointCompareIgnoringASCIICase(const StringImpl* string1,
const LChar* string2) {
- unsigned length1 = string1 ? string1->length() : 0;
- size_t length2 = string2 ? strlen(reinterpret_cast<const char*>(string2)) : 0;
+ wtf_size_t length1 = string1 ? string1->length() : 0;
+ wtf_size_t length2 = SafeCast<wtf_size_t>(
+ string2 ? strlen(reinterpret_cast<const char*>(string2)) : 0);
if (!string1)
return length2 > 0 ? -1 : 0;
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 0e7c40b732e..be183011e7f 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
@@ -72,7 +72,7 @@ enum StripBehavior { kStripExtraWhiteSpace, kDoNotStripWhiteSpace };
typedef bool (*CharacterMatchFunctionPtr)(UChar);
typedef bool (*IsWhiteSpaceFunctionPtr)(UChar);
-typedef HashMap<unsigned, StringImpl*, AlreadyHashed> StaticStringsTable;
+typedef HashMap<wtf_size_t, StringImpl*, AlreadyHashed> StaticStringsTable;
// You can find documentation about this class in this doc:
// https://docs.google.com/document/d/1kOCUlJdh2WJMJGDf-WoEQhmnjKLaOYRbiHz5TiGJl14/edit?usp=sharing
@@ -119,7 +119,7 @@ class WTF_EXPORT StringImpl {
// FIXME: there has to be a less hacky way to do this.
enum Force8Bit { kForce8BitConstructor };
- StringImpl(unsigned length, Force8Bit)
+ StringImpl(wtf_size_t length, Force8Bit)
: ref_count_(1),
length_(length),
hash_(0),
@@ -131,7 +131,7 @@ class WTF_EXPORT StringImpl {
DCHECK(length_);
}
- StringImpl(unsigned length)
+ StringImpl(wtf_size_t length)
: ref_count_(1),
length_(length),
hash_(0),
@@ -144,7 +144,7 @@ class WTF_EXPORT StringImpl {
}
enum StaticStringTag { kStaticString };
- StringImpl(unsigned length, unsigned hash, StaticStringTag)
+ StringImpl(wtf_size_t length, wtf_size_t hash, StaticStringTag)
: ref_count_(1),
length_(length),
hash_(hash),
@@ -164,27 +164,27 @@ class WTF_EXPORT StringImpl {
static void InitStatics();
static StringImpl* CreateStatic(const char* string,
- unsigned length,
- unsigned hash);
- static void ReserveStaticStringsCapacityForSize(unsigned size);
+ wtf_size_t length,
+ wtf_size_t hash);
+ static void ReserveStaticStringsCapacityForSize(wtf_size_t size);
static void FreezeStaticStrings();
static const StaticStringsTable& AllStaticStrings();
- static unsigned HighestStaticStringLength() {
+ static wtf_size_t HighestStaticStringLength() {
return highest_static_string_length_;
}
- static scoped_refptr<StringImpl> Create(const UChar*, unsigned length);
- static scoped_refptr<StringImpl> Create(const LChar*, unsigned length);
+ static scoped_refptr<StringImpl> Create(const UChar*, wtf_size_t length);
+ static scoped_refptr<StringImpl> Create(const LChar*, wtf_size_t length);
static scoped_refptr<StringImpl> Create8BitIfPossible(const UChar*,
- unsigned length);
- template <size_t inlineCapacity>
+ wtf_size_t length);
+ template <wtf_size_t inlineCapacity>
static scoped_refptr<StringImpl> Create8BitIfPossible(
const Vector<UChar, inlineCapacity>& vector) {
return Create8BitIfPossible(vector.data(), vector.size());
}
ALWAYS_INLINE static scoped_refptr<StringImpl> Create(const char* s,
- unsigned length) {
+ wtf_size_t length) {
return Create(reinterpret_cast<const LChar*>(s), length);
}
static scoped_refptr<StringImpl> Create(const LChar*);
@@ -192,12 +192,12 @@ class WTF_EXPORT StringImpl {
return Create(reinterpret_cast<const LChar*>(s));
}
- static scoped_refptr<StringImpl> CreateUninitialized(unsigned length,
+ static scoped_refptr<StringImpl> CreateUninitialized(wtf_size_t length,
LChar*& data);
- static scoped_refptr<StringImpl> CreateUninitialized(unsigned length,
+ static scoped_refptr<StringImpl> CreateUninitialized(wtf_size_t length,
UChar*& data);
- unsigned length() const { return length_; }
+ wtf_size_t length() const { return length_; }
bool Is8Bit() const { return is8_bit_; }
ALWAYS_INLINE const LChar* Characters8() const {
@@ -232,7 +232,7 @@ class WTF_EXPORT StringImpl {
// flags in the low bits because it makes them slightly more efficient to
// access. So, we shift left and right when setting and getting our hash
// code.
- void SetHash(unsigned hash) const {
+ void SetHash(wtf_size_t hash) const {
DCHECK(!HasHash());
// Multiple clients assume that StringHasher is the canonical string
// hash function.
@@ -246,12 +246,12 @@ class WTF_EXPORT StringImpl {
bool HasHash() const { return hash_ != 0; }
- unsigned ExistingHash() const {
+ wtf_size_t ExistingHash() const {
DCHECK(HasHash());
return hash_;
}
- unsigned GetHash() const {
+ wtf_size_t GetHash() const {
if (HasHash())
return ExistingHash();
return HashSlowCase();
@@ -286,14 +286,14 @@ class WTF_EXPORT StringImpl {
template <typename T>
static void CopyChars(T* destination,
const T* source,
- unsigned num_characters) {
+ wtf_size_t num_characters) {
memcpy(destination, source, num_characters * sizeof(T));
}
ALWAYS_INLINE static void CopyChars(UChar* destination,
const LChar* source,
- unsigned num_characters) {
- for (unsigned i = 0; i < num_characters; ++i)
+ wtf_size_t num_characters) {
+ for (wtf_size_t i = 0; i < num_characters; ++i)
destination[i] = source[i];
}
@@ -302,25 +302,25 @@ class WTF_EXPORT StringImpl {
// its own copy of the string.
scoped_refptr<StringImpl> IsolatedCopy() const;
- scoped_refptr<StringImpl> Substring(unsigned pos,
- unsigned len = UINT_MAX) const;
+ scoped_refptr<StringImpl> Substring(wtf_size_t pos,
+ wtf_size_t len = UINT_MAX) const;
- UChar operator[](unsigned i) const {
+ UChar operator[](wtf_size_t i) const {
SECURITY_DCHECK(i < length_);
if (Is8Bit())
return Characters8()[i];
return Characters16()[i];
}
- UChar32 CharacterStartingAt(unsigned);
+ UChar32 CharacterStartingAt(wtf_size_t);
bool ContainsOnlyWhitespace();
int ToInt(NumberParsingOptions, bool* ok) const;
- unsigned ToUInt(NumberParsingOptions, bool* ok) const;
+ wtf_size_t ToUInt(NumberParsingOptions, bool* ok) const;
int64_t ToInt64(NumberParsingOptions, bool* ok) const;
uint64_t ToUInt64(NumberParsingOptions, bool* ok) const;
- unsigned HexToUIntStrict(bool* ok);
+ wtf_size_t HexToUIntStrict(bool* ok);
// FIXME: Like NumberParsingOptions::kStrict, these give false for "ok" when
// there is trailing garbage. Like NumberParsingOptions::kLoose, these return
@@ -341,7 +341,7 @@ class WTF_EXPORT StringImpl {
// ASCII?
scoped_refptr<StringImpl> FoldCase();
- scoped_refptr<StringImpl> Truncate(unsigned length);
+ scoped_refptr<StringImpl> Truncate(wtf_size_t length);
scoped_refptr<StringImpl> StripWhiteSpace();
scoped_refptr<StringImpl> StripWhiteSpace(IsWhiteSpaceFunctionPtr);
@@ -359,25 +359,25 @@ class WTF_EXPORT StringImpl {
// Remove characters between [start, start+lengthToRemove). The range is
// clamped to the size of the string. Does nothing if start >= length().
- scoped_refptr<StringImpl> Remove(unsigned start,
- unsigned length_to_remove = 1);
+ scoped_refptr<StringImpl> Remove(wtf_size_t start,
+ wtf_size_t length_to_remove = 1);
// Find characters.
- size_t Find(LChar character, unsigned start = 0);
- size_t Find(char character, unsigned start = 0);
- size_t Find(UChar character, unsigned start = 0);
- size_t Find(CharacterMatchFunctionPtr, unsigned index = 0);
+ wtf_size_t Find(LChar character, wtf_size_t start = 0);
+ wtf_size_t Find(char character, wtf_size_t start = 0);
+ wtf_size_t Find(UChar character, wtf_size_t start = 0);
+ wtf_size_t Find(CharacterMatchFunctionPtr, wtf_size_t index = 0);
// Find substrings.
- size_t Find(const StringView&, unsigned index = 0);
+ wtf_size_t Find(const StringView&, wtf_size_t index = 0);
// Unicode aware case insensitive string matching. Non-ASCII characters might
// match to ASCII characters. This function is rarely used to implement web
// platform features.
- size_t FindIgnoringCase(const StringView&, unsigned index = 0);
- size_t FindIgnoringASCIICase(const StringView&, unsigned index = 0);
+ wtf_size_t FindIgnoringCase(const StringView&, wtf_size_t index = 0);
+ wtf_size_t FindIgnoringASCIICase(const StringView&, wtf_size_t index = 0);
- size_t ReverseFind(UChar, unsigned index = UINT_MAX);
- size_t ReverseFind(const StringView&, unsigned index = UINT_MAX);
+ wtf_size_t ReverseFind(UChar, wtf_size_t index = UINT_MAX);
+ wtf_size_t ReverseFind(const StringView&, wtf_size_t index = UINT_MAX);
bool StartsWith(UChar) const;
bool StartsWith(const StringView&) const;
@@ -395,8 +395,8 @@ class WTF_EXPORT StringImpl {
const StringView& replacement);
scoped_refptr<StringImpl> Replace(const StringView& pattern,
const StringView& replacement);
- scoped_refptr<StringImpl> Replace(unsigned index,
- unsigned length_to_replace,
+ scoped_refptr<StringImpl> Replace(wtf_size_t index,
+ wtf_size_t length_to_replace,
const StringView& replacement);
scoped_refptr<StringImpl> UpconvertedString();
@@ -404,27 +404,29 @@ class WTF_EXPORT StringImpl {
// Copy characters from string starting at |start| up until |maxLength| or
// the end of the string is reached. Returns the actual number of characters
// copied.
- unsigned CopyTo(UChar* buffer, unsigned start, unsigned max_length) const;
+ wtf_size_t CopyTo(UChar* buffer,
+ wtf_size_t start,
+ wtf_size_t max_length) const;
// Append characters from this string into a buffer. Expects the buffer to
// have the methods:
- // append(const UChar*, unsigned length);
- // append(const LChar*, unsigned length);
+ // append(const UChar*, wtf_size_t length);
+ // append(const LChar*, wtf_size_t length);
// StringBuilder and Vector conform to this protocol.
template <typename BufferType>
void AppendTo(BufferType&,
- unsigned start = 0,
- unsigned length = UINT_MAX) const;
+ wtf_size_t start = 0,
+ wtf_size_t length = UINT_MAX) const;
// Prepend characters from this string into a buffer. Expects the buffer to
// have the methods:
- // prepend(const UChar*, unsigned length);
- // prepend(const LChar*, unsigned length);
+ // prepend(const UChar*, wtf_size_t length);
+ // prepend(const LChar*, wtf_size_t length);
// Vector conforms to this protocol.
template <typename BufferType>
void PrependTo(BufferType&,
- unsigned start = 0,
- unsigned length = UINT_MAX) const;
+ wtf_size_t start = 0,
+ wtf_size_t length = UINT_MAX) const;
#if defined(OS_MACOSX)
RetainPtr<CFStringRef> CreateCFString();
@@ -437,26 +439,26 @@ class WTF_EXPORT StringImpl {
private:
template <typename CharType>
- static size_t AllocationSize(unsigned length) {
+ static size_t AllocationSize(wtf_size_t length) {
CHECK_LE(length,
- ((std::numeric_limits<unsigned>::max() - sizeof(StringImpl)) /
+ ((std::numeric_limits<wtf_size_t>::max() - sizeof(StringImpl)) /
sizeof(CharType)));
return sizeof(StringImpl) + length * sizeof(CharType);
}
scoped_refptr<StringImpl> Replace(UChar pattern,
const LChar* replacement,
- unsigned replacement_length);
+ wtf_size_t replacement_length);
scoped_refptr<StringImpl> Replace(UChar pattern,
const UChar* replacement,
- unsigned replacement_length);
+ wtf_size_t replacement_length);
template <class UCharPredicate>
scoped_refptr<StringImpl> StripMatchedCharacters(UCharPredicate);
template <typename CharType, class UCharPredicate>
scoped_refptr<StringImpl> SimplifyMatchedCharactersToSpace(UCharPredicate,
StripBehavior);
- NOINLINE unsigned HashSlowCase() const;
+ NOINLINE wtf_size_t HashSlowCase() const;
void DestroyIfNotStatic() const;
void UpdateContainsOnlyASCII() const;
@@ -465,7 +467,7 @@ class WTF_EXPORT StringImpl {
std::string AsciiForDebugging() const;
#endif
- static unsigned highest_static_string_length_;
+ static wtf_size_t highest_static_string_length_;
#if DCHECK_IS_ON()
void AssertHashIsCorrect() {
@@ -506,9 +508,9 @@ WTF_EXPORT bool Equal(const StringImpl*, const LChar*);
inline bool Equal(const StringImpl* a, const char* b) {
return Equal(a, reinterpret_cast<const LChar*>(b));
}
-WTF_EXPORT bool Equal(const StringImpl*, const LChar*, unsigned);
-WTF_EXPORT bool Equal(const StringImpl*, const UChar*, unsigned);
-inline bool Equal(const StringImpl* a, const char* b, unsigned length) {
+WTF_EXPORT bool Equal(const StringImpl*, const LChar*, wtf_size_t);
+WTF_EXPORT bool Equal(const StringImpl*, const UChar*, wtf_size_t);
+inline bool Equal(const StringImpl* a, const char* b, wtf_size_t length) {
return Equal(a, reinterpret_cast<const LChar*>(b), length);
}
inline bool Equal(const LChar* a, StringImpl* b) {
@@ -528,19 +530,19 @@ ALWAYS_INLINE bool StringImpl::ContainsOnlyASCII() const {
template <typename CharType>
ALWAYS_INLINE bool Equal(const CharType* a,
const CharType* b,
- unsigned length) {
+ wtf_size_t length) {
return !memcmp(a, b, length * sizeof(CharType));
}
-ALWAYS_INLINE bool Equal(const LChar* a, const UChar* b, unsigned length) {
- for (unsigned i = 0; i < length; ++i) {
+ALWAYS_INLINE bool Equal(const LChar* a, const UChar* b, wtf_size_t length) {
+ for (wtf_size_t i = 0; i < length; ++i) {
if (a[i] != b[i])
return false;
}
return true;
}
-ALWAYS_INLINE bool Equal(const UChar* a, const LChar* b, unsigned length) {
+ALWAYS_INLINE bool Equal(const UChar* a, const LChar* b, wtf_size_t length) {
return Equal(b, a, length);
}
@@ -551,26 +553,26 @@ ALWAYS_INLINE bool Equal(const UChar* a, const LChar* b, unsigned length) {
// EqualIgnoringUnicodeCase(). See crbug.com/627682
WTF_EXPORT bool DeprecatedEqualIgnoringCase(const LChar*,
const LChar*,
- unsigned length);
+ wtf_size_t length);
WTF_EXPORT bool DeprecatedEqualIgnoringCase(const UChar*,
const LChar*,
- unsigned length);
+ wtf_size_t length);
inline bool DeprecatedEqualIgnoringCase(const LChar* a,
const UChar* b,
- unsigned length) {
+ wtf_size_t length) {
return DeprecatedEqualIgnoringCase(b, a, length);
}
WTF_EXPORT bool DeprecatedEqualIgnoringCase(const UChar*,
const UChar*,
- unsigned length);
+ wtf_size_t length);
WTF_EXPORT bool EqualIgnoringNullity(StringImpl*, StringImpl*);
template <typename CharacterTypeA, typename CharacterTypeB>
inline bool EqualIgnoringASCIICase(const CharacterTypeA* a,
const CharacterTypeB* b,
- unsigned length) {
- for (unsigned i = 0; i < length; ++i) {
+ wtf_size_t length) {
+ for (wtf_size_t i = 0; i < length; ++i) {
if (ToASCIILower(a[i]) != ToASCIILower(b[i]))
return false;
}
@@ -580,22 +582,22 @@ inline bool EqualIgnoringASCIICase(const CharacterTypeA* a,
WTF_EXPORT int CodePointCompareIgnoringASCIICase(const StringImpl*,
const LChar*);
-inline size_t Find(const LChar* characters,
- unsigned length,
- LChar match_character,
- unsigned index = 0) {
+inline wtf_size_t Find(const LChar* characters,
+ wtf_size_t length,
+ LChar match_character,
+ wtf_size_t index = 0) {
// Some clients rely on being able to pass index >= length.
if (index >= length)
return kNotFound;
const LChar* found = static_cast<const LChar*>(
memchr(characters + index, match_character, length - index));
- return found ? found - characters : kNotFound;
+ return found ? static_cast<wtf_size_t>(found - characters) : kNotFound;
}
-inline size_t Find(const UChar* characters,
- unsigned length,
- UChar match_character,
- unsigned index = 0) {
+inline wtf_size_t Find(const UChar* characters,
+ wtf_size_t length,
+ UChar match_character,
+ wtf_size_t index = 0) {
while (index < length) {
if (characters[index] == match_character)
return index;
@@ -604,34 +606,34 @@ inline size_t Find(const UChar* characters,
return kNotFound;
}
-ALWAYS_INLINE size_t Find(const UChar* characters,
- unsigned length,
- LChar match_character,
- unsigned index = 0) {
+ALWAYS_INLINE wtf_size_t Find(const UChar* characters,
+ wtf_size_t length,
+ LChar match_character,
+ wtf_size_t index = 0) {
return Find(characters, length, static_cast<UChar>(match_character), index);
}
-inline size_t Find(const LChar* characters,
- unsigned length,
- UChar match_character,
- unsigned index = 0) {
+inline wtf_size_t Find(const LChar* characters,
+ wtf_size_t length,
+ UChar match_character,
+ wtf_size_t index = 0) {
if (match_character & ~0xFF)
return kNotFound;
return Find(characters, length, static_cast<LChar>(match_character), index);
}
template <typename CharacterType>
-inline size_t Find(const CharacterType* characters,
- unsigned length,
- char match_character,
- unsigned index = 0) {
+inline wtf_size_t Find(const CharacterType* characters,
+ wtf_size_t length,
+ char match_character,
+ wtf_size_t index = 0) {
return Find(characters, length, static_cast<LChar>(match_character), index);
}
-inline size_t Find(const LChar* characters,
- unsigned length,
- CharacterMatchFunctionPtr match_function,
- unsigned index = 0) {
+inline wtf_size_t Find(const LChar* characters,
+ wtf_size_t length,
+ CharacterMatchFunctionPtr match_function,
+ wtf_size_t index = 0) {
while (index < length) {
if (match_function(characters[index]))
return index;
@@ -640,10 +642,10 @@ inline size_t Find(const LChar* characters,
return kNotFound;
}
-inline size_t Find(const UChar* characters,
- unsigned length,
- CharacterMatchFunctionPtr match_function,
- unsigned index = 0) {
+inline wtf_size_t Find(const UChar* characters,
+ wtf_size_t length,
+ CharacterMatchFunctionPtr match_function,
+ wtf_size_t index = 0) {
while (index < length) {
if (match_function(characters[index]))
return index;
@@ -653,10 +655,10 @@ inline size_t Find(const UChar* characters,
}
template <typename CharacterType>
-inline size_t ReverseFind(const CharacterType* characters,
- unsigned length,
- CharacterType match_character,
- unsigned index = UINT_MAX) {
+inline wtf_size_t ReverseFind(const CharacterType* characters,
+ wtf_size_t length,
+ CharacterType match_character,
+ wtf_size_t index = UINT_MAX) {
if (!length)
return kNotFound;
if (index >= length)
@@ -668,49 +670,48 @@ inline size_t ReverseFind(const CharacterType* characters,
return index;
}
-ALWAYS_INLINE size_t ReverseFind(const UChar* characters,
- unsigned length,
- LChar match_character,
- unsigned index = UINT_MAX) {
+ALWAYS_INLINE wtf_size_t ReverseFind(const UChar* characters,
+ wtf_size_t length,
+ LChar match_character,
+ wtf_size_t index = UINT_MAX) {
return ReverseFind(characters, length, static_cast<UChar>(match_character),
index);
}
-inline size_t ReverseFind(const LChar* characters,
- unsigned length,
- UChar match_character,
- unsigned index = UINT_MAX) {
+inline wtf_size_t ReverseFind(const LChar* characters,
+ wtf_size_t length,
+ UChar match_character,
+ wtf_size_t index = UINT_MAX) {
if (match_character & ~0xFF)
return kNotFound;
return ReverseFind(characters, length, static_cast<LChar>(match_character),
index);
}
-inline size_t StringImpl::Find(LChar character, unsigned start) {
+inline wtf_size_t StringImpl::Find(LChar character, wtf_size_t start) {
if (Is8Bit())
return WTF::Find(Characters8(), length_, character, start);
return WTF::Find(Characters16(), length_, character, start);
}
-ALWAYS_INLINE size_t StringImpl::Find(char character, unsigned start) {
+ALWAYS_INLINE wtf_size_t StringImpl::Find(char character, wtf_size_t start) {
return Find(static_cast<LChar>(character), start);
}
-inline size_t StringImpl::Find(UChar character, unsigned start) {
+inline wtf_size_t StringImpl::Find(UChar character, wtf_size_t start) {
if (Is8Bit())
return WTF::Find(Characters8(), length_, character, start);
return WTF::Find(Characters16(), length_, character, start);
}
-inline unsigned LengthOfNullTerminatedString(const UChar* string) {
+inline wtf_size_t LengthOfNullTerminatedString(const UChar* string) {
size_t length = 0;
while (string[length] != UChar(0))
++length;
- CHECK_LE(length, std::numeric_limits<unsigned>::max());
- return static_cast<unsigned>(length);
+ return SafeCast<wtf_size_t>(length);
}
-template <size_t inlineCapacity>
+template <wtf_size_t inlineCapacity>
bool EqualIgnoringNullity(const Vector<UChar, inlineCapacity>& a,
StringImpl* b) {
if (!b)
@@ -723,12 +724,12 @@ bool EqualIgnoringNullity(const Vector<UChar, inlineCapacity>& a,
}
template <typename CharacterType1, typename CharacterType2>
-static inline int CodePointCompare(unsigned l1,
- unsigned l2,
+static inline int CodePointCompare(wtf_size_t l1,
+ wtf_size_t l2,
const CharacterType1* c1,
const CharacterType2* c2) {
- const unsigned lmin = l1 < l2 ? l1 : l2;
- unsigned pos = 0;
+ const wtf_size_t lmin = l1 < l2 ? l1 : l2;
+ wtf_size_t pos = 0;
while (pos < lmin && *c1 == *c2) {
++c1;
++c2;
@@ -798,9 +799,9 @@ inline scoped_refptr<StringImpl> StringImpl::IsolatedCopy() const {
template <typename BufferType>
inline void StringImpl::AppendTo(BufferType& result,
- unsigned start,
- unsigned length) const {
- unsigned number_of_characters_to_copy = std::min(length, length_ - start);
+ wtf_size_t start,
+ wtf_size_t length) const {
+ wtf_size_t number_of_characters_to_copy = std::min(length, length_ - start);
if (!number_of_characters_to_copy)
return;
if (Is8Bit())
@@ -811,9 +812,9 @@ inline void StringImpl::AppendTo(BufferType& result,
template <typename BufferType>
inline void StringImpl::PrependTo(BufferType& result,
- unsigned start,
- unsigned length) const {
- unsigned number_of_characters_to_copy = std::min(length, length_ - start);
+ wtf_size_t start,
+ wtf_size_t length) const {
+ wtf_size_t number_of_characters_to_copy = std::min(length, length_ - start);
if (!number_of_characters_to_copy)
return;
if (Is8Bit())
diff --git a/chromium/third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h b/chromium/third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h
index 8ff99a6a625..7bde4329f8f 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h
@@ -66,7 +66,7 @@ class StringUTF8Adaptor final {
}
const char* Data() const { return data_; }
- size_t length() const { return length_; }
+ wtf_size_t length() const { return length_; }
base::StringPiece AsStringPiece() const {
return base::StringPiece(data_, length_);
@@ -75,7 +75,7 @@ class StringUTF8Adaptor final {
private:
CString utf8_buffer_;
const char* data_;
- size_t length_;
+ wtf_size_t length_;
};
} // namespace WTF
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 4f7effa67af..652afb2cb95 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
@@ -538,7 +538,7 @@ void String::Split(const StringView& separator,
result.clear();
unsigned start_pos = 0;
- size_t end_pos;
+ wtf_size_t end_pos;
while ((end_pos = Find(separator, start_pos)) != kNotFound) {
if (allow_empty_entries || start_pos != end_pos)
result.push_back(Substring(start_pos, end_pos - start_pos));
@@ -554,7 +554,7 @@ void String::Split(UChar separator,
result.clear();
unsigned start_pos = 0;
- size_t end_pos;
+ wtf_size_t end_pos;
while ((end_pos = find(separator, start_pos)) != kNotFound) {
if (allow_empty_entries || start_pos != end_pos)
result.push_back(Substring(start_pos, end_pos - start_pos));
@@ -726,7 +726,7 @@ CString String::Utf8(UTF8ConversionMode mode) const {
return CString(buffer_vector.data(), buffer - buffer_vector.data());
}
-String String::Make8BitFrom16BitSource(const UChar* source, size_t length) {
+String String::Make8BitFrom16BitSource(const UChar* source, wtf_size_t length) {
if (!length)
return g_empty_string;
@@ -738,7 +738,7 @@ String String::Make8BitFrom16BitSource(const UChar* source, size_t length) {
return result;
}
-String String::Make16BitFrom8BitSource(const LChar* source, size_t length) {
+String String::Make16BitFrom8BitSource(const LChar* source, wtf_size_t length) {
if (!length)
return g_empty_string16_bit;
@@ -750,8 +750,8 @@ String String::Make16BitFrom8BitSource(const LChar* source, size_t length) {
return result;
}
-String String::FromUTF8(const LChar* string_start, size_t length) {
- CHECK_LE(length, std::numeric_limits<unsigned>::max());
+String String::FromUTF8(const LChar* string_start, size_t string_length) {
+ wtf_size_t length = SafeCast<wtf_size_t>(string_length);
if (!string_start)
return String();
@@ -773,7 +773,8 @@ String String::FromUTF8(const LChar* string_start, size_t length) {
buffer_current + buffer.size()) != Unicode::kConversionOK)
return String();
- unsigned utf16_length = buffer_current - buffer_start;
+ unsigned utf16_length =
+ static_cast<wtf_size_t>(buffer_current - buffer_start);
DCHECK_LT(utf16_length, length);
return StringImpl::Create(buffer_start, utf16_length);
}
@@ -791,7 +792,7 @@ String String::FromUTF8(const CString& s) {
String String::FromUTF8WithLatin1Fallback(const LChar* string, size_t size) {
String utf8 = FromUTF8(string, size);
if (!utf8)
- return String(string, size);
+ return String(string, SafeCast<wtf_size_t>(size));
return utf8;
}
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 a177893f98b..f1755fb5bb9 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
@@ -35,6 +35,7 @@
#include "third_party/blink/renderer/platform/wtf/text/string_impl.h"
#include "third_party/blink/renderer/platform/wtf/text/string_view.h"
#include "third_party/blink/renderer/platform/wtf/wtf_export.h"
+#include "third_party/blink/renderer/platform/wtf/wtf_size_t.h"
#ifdef __OBJC__
#include <objc/objc.h>
@@ -77,7 +78,7 @@ class WTF_EXPORT String {
// which will sometimes return a null string when vector.data() is null
// which can only occur for vectors without inline capacity.
// See: https://bugs.webkit.org/show_bug.cgi?id=109792
- template <size_t inlineCapacity>
+ template <wtf_size_t inlineCapacity>
explicit String(const Vector<UChar, inlineCapacity>&);
// Construct a string with UTF-16 data, from a null-terminated source.
@@ -177,24 +178,25 @@ class WTF_EXPORT String {
static String NumberToStringFixedWidth(double, unsigned decimal_places);
// Find characters.
- size_t find(UChar c, unsigned start = 0) const {
+ wtf_size_t find(UChar c, unsigned start = 0) const {
return impl_ ? impl_->Find(c, start) : kNotFound;
}
- size_t find(LChar c, unsigned start = 0) const {
+ wtf_size_t find(LChar c, unsigned start = 0) const {
return impl_ ? impl_->Find(c, start) : kNotFound;
}
- size_t find(char c, unsigned start = 0) const {
+ wtf_size_t find(char c, unsigned start = 0) const {
return find(static_cast<LChar>(c), start);
}
- size_t Find(CharacterMatchFunctionPtr match_function,
- unsigned start = 0) const {
+ wtf_size_t Find(CharacterMatchFunctionPtr match_function,
+ unsigned start = 0) const {
return impl_ ? impl_->Find(match_function, start) : kNotFound;
}
// Find substrings.
- size_t Find(const StringView& value,
- unsigned start = 0,
- TextCaseSensitivity case_sensitivity = kTextCaseSensitive) const {
+ wtf_size_t Find(
+ const StringView& value,
+ unsigned start = 0,
+ TextCaseSensitivity case_sensitivity = kTextCaseSensitive) const {
return impl_
? DISPATCH_CASE_OP(case_sensitivity, impl_->Find, (value, start))
: kNotFound;
@@ -203,13 +205,14 @@ class WTF_EXPORT String {
// Unicode aware case insensitive string matching. Non-ASCII characters might
// match to ASCII characters. This function is rarely used to implement web
// platform features.
- size_t FindIgnoringCase(const StringView& value, unsigned start = 0) const {
+ wtf_size_t FindIgnoringCase(const StringView& value,
+ unsigned start = 0) const {
return impl_ ? impl_->FindIgnoringCase(value, start) : kNotFound;
}
// ASCII case insensitive string matching.
- size_t FindIgnoringASCIICase(const StringView& value,
- unsigned start = 0) const {
+ wtf_size_t FindIgnoringASCIICase(const StringView& value,
+ unsigned start = 0) const {
return impl_ ? impl_->FindIgnoringASCIICase(value, start) : kNotFound;
}
@@ -221,10 +224,11 @@ class WTF_EXPORT String {
}
// Find the last instance of a single character or string.
- size_t ReverseFind(UChar c, unsigned start = UINT_MAX) const {
+ wtf_size_t ReverseFind(UChar c, unsigned start = UINT_MAX) const {
return impl_ ? impl_->ReverseFind(c, start) : kNotFound;
}
- size_t ReverseFind(const StringView& value, unsigned start = UINT_MAX) const {
+ wtf_size_t ReverseFind(const StringView& value,
+ unsigned start = UINT_MAX) const {
return impl_ ? impl_->ReverseFind(value, start) : kNotFound;
}
@@ -471,14 +475,14 @@ class WTF_EXPORT String {
}
#endif
- static String Make8BitFrom16BitSource(const UChar*, size_t);
- template <size_t inlineCapacity>
+ static String Make8BitFrom16BitSource(const UChar*, wtf_size_t);
+ template <wtf_size_t inlineCapacity>
static String Make8BitFrom16BitSource(
const Vector<UChar, inlineCapacity>& buffer) {
return Make8BitFrom16BitSource(buffer.data(), buffer.size());
}
- static String Make16BitFrom8BitSource(const LChar*, size_t);
+ static String Make16BitFrom8BitSource(const LChar*, wtf_size_t);
// String::fromUTF8 will return a null string if
// the input data contains invalid UTF-8 sequences.
@@ -554,7 +558,7 @@ inline bool EqualIgnoringNullity(const String& a, const String& b) {
return EqualIgnoringNullity(a.Impl(), b.Impl());
}
-template <size_t inlineCapacity>
+template <wtf_size_t inlineCapacity>
inline bool EqualIgnoringNullity(const Vector<UChar, inlineCapacity>& a,
const String& b) {
return EqualIgnoringNullity(a, b.Impl());
@@ -566,7 +570,7 @@ inline void swap(String& a, String& b) {
// Definitions of string operations
-template <size_t inlineCapacity>
+template <wtf_size_t inlineCapacity>
String::String(const Vector<UChar, inlineCapacity>& vector)
: impl_(vector.size() ? StringImpl::Create(vector.data(), vector.size())
: StringImpl::empty_) {}
@@ -592,7 +596,7 @@ inline bool String::ContainsOnlyLatin1() const {
const UChar* characters = Characters16();
UChar ored = 0;
- for (size_t i = 0; i < impl_->length(); ++i)
+ for (wtf_size_t i = 0; i < impl_->length(); ++i)
ored |= characters[i];
return !(ored & 0xFF00);
}
diff --git a/chromium/third_party/blink/renderer/platform/wtf/threading.cc b/chromium/third_party/blink/renderer/platform/wtf/threading.cc
new file mode 100644
index 00000000000..4728e5ec928
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/wtf/threading.cc
@@ -0,0 +1,122 @@
+// 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/wtf/threading.h"
+
+#include "build/build_config.h"
+#include "third_party/blink/renderer/platform/wtf/date_math.h"
+#include "third_party/blink/renderer/platform/wtf/dtoa/double-conversion.h"
+#include "third_party/blink/renderer/platform/wtf/wtf_thread_data.h"
+
+#if defined(OS_WIN)
+#include <windows.h>
+#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
+#include <pthread.h>
+#else
+#error Blink does not support threading on your platform.
+#endif
+
+#if defined(OS_LINUX)
+#include <sys/syscall.h>
+#elif defined(OS_ANDROID)
+#include <sys/types.h>
+#endif
+
+namespace WTF {
+
+// Current thread identity
+
+namespace internal {
+
+ThreadIdentifier CurrentThreadSyscall() {
+#if defined(OS_WIN)
+ return static_cast<ThreadIdentifier>(GetCurrentThreadId());
+#elif defined(OS_MACOSX)
+ return pthread_mach_thread_np(pthread_self());
+#elif defined(OS_LINUX)
+ return syscall(__NR_gettid);
+#elif defined(OS_ANDROID)
+ return gettid();
+#else
+ return reinterpret_cast<uintptr_t>(pthread_self());
+#endif
+}
+
+} // namespace internal
+
+namespace {
+bool g_current_thread_key_initialized = false;
+
+#if defined(OS_WIN)
+DWORD g_current_thread_key;
+void RawCurrentThreadInit() {
+ g_current_thread_key = ::TlsAlloc();
+ CHECK_NE(g_current_thread_key, TLS_OUT_OF_INDEXES);
+}
+void* RawCurrentThreadGet() {
+ return ::TlsGetValue(g_current_thread_key);
+}
+void RawCurrentThreadSet(void* value) {
+ ::TlsSetValue(g_current_thread_key, value);
+}
+#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
+pthread_key_t g_current_thread_key;
+void RawCurrentThreadInit() {
+ int error = pthread_key_create(&g_current_thread_key, nullptr);
+ CHECK(!error);
+}
+void* RawCurrentThreadGet() {
+ return pthread_getspecific(g_current_thread_key);
+}
+void RawCurrentThreadSet(void* value) {
+ pthread_setspecific(g_current_thread_key, value);
+}
+#endif
+} // namespace
+
+void InitializeCurrentThread() {
+ DCHECK(!g_current_thread_key_initialized);
+ RawCurrentThreadInit();
+ g_current_thread_key_initialized = true;
+}
+
+ThreadIdentifier CurrentThread() {
+ // This doesn't use WTF::ThreadSpecific (e.g. WTFThreadData) because
+ // ThreadSpecific now depends on currentThread. It is necessary to avoid this
+ // or a similar loop:
+ //
+ // CurrentThread
+ // -> WtfThreadData
+ // -> ThreadSpecific::operator*
+ // -> IsMainThread
+ // -> CurrentThread
+ static_assert(sizeof(ThreadIdentifier) <= sizeof(void*),
+ "ThreadIdentifier must fit in a void*.");
+ DCHECK(g_current_thread_key_initialized);
+ void* value = RawCurrentThreadGet();
+ if (UNLIKELY(!value)) {
+ value = reinterpret_cast<void*>(internal::CurrentThreadSyscall());
+ DCHECK(value);
+ RawCurrentThreadSet(value);
+ }
+ return reinterpret_cast<ThreadIdentifier>(value);
+}
+
+// For debugging only -- whether a non-main thread has been created.
+// No synchronization is required, since this is called before any such thread
+// exists.
+
+#if DCHECK_IS_ON()
+static bool g_thread_created = false;
+
+bool IsBeforeThreadCreated() {
+ return !g_thread_created;
+}
+
+void WillCreateThread() {
+ g_thread_created = true;
+}
+#endif
+
+} // namespace WTF
diff --git a/chromium/third_party/blink/renderer/platform/wtf/threading_primitives.h b/chromium/third_party/blink/renderer/platform/wtf/threading_primitives.h
index f112896f6ac..7f1bbccb95d 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/threading_primitives.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/threading_primitives.h
@@ -72,7 +72,12 @@ class WTF_EXPORT MutexBase {
void lock();
void unlock();
#if DCHECK_IS_ON()
- bool Locked() { return mutex_.recursion_count_ > 0; }
+ // Deprecated in favour of AssertAcquired.
+ bool Locked() const { return mutex_.recursion_count_ > 0; }
+
+ void AssertAcquired() const { DCHECK(Locked()); }
+#else
+ void AssertAcquired() const {}
#endif
public:
@@ -91,12 +96,17 @@ class LOCKABLE WTF_EXPORT Mutex : public MutexBase {
Mutex() : MutexBase(false) {}
bool TryLock() EXCLUSIVE_TRYLOCK_FUNCTION(true);
- // lock() and unlock() are overridden solely for the purpose of annotating
- // them. The compiler is expected to optimize the calls away.
+ // Overridden solely for the purpose of annotating them.
+ // The compiler is expected to optimize the calls away.
void lock() EXCLUSIVE_LOCK_FUNCTION() { MutexBase::lock(); }
void unlock() UNLOCK_FUNCTION() { MutexBase::unlock(); }
+ void AssertAcquired() const ASSERT_EXCLUSIVE_LOCK() {
+ MutexBase::AssertAcquired();
+ }
};
+// RecursiveMutex is deprecated AND WILL BE REMOVED.
+// https://crbug.com/856641
class WTF_EXPORT RecursiveMutex : public MutexBase {
public:
RecursiveMutex() : MutexBase(true) {}
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
new file mode 100644
index 00000000000..fee226d9c24
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/wtf/threading_primitives_test.cc
@@ -0,0 +1,81 @@
+// 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/wtf/threading_primitives.h"
+
+#include "base/bind.h"
+#include "base/synchronization/waitable_event.h"
+#include "base/threading/scoped_blocking_call.h"
+#include "base/threading/thread.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/platform/wtf/time.h"
+
+namespace WTF {
+namespace {
+
+class MockBlockingObserver : public base::internal::BlockingObserver {
+ public:
+ // base::internal::BlockingObserver
+ MOCK_METHOD1(BlockingStarted, void(base::BlockingType));
+ MOCK_METHOD0(BlockingTypeUpgraded, void());
+ MOCK_METHOD0(BlockingEnded, void());
+};
+
+class ThreadConditionTest : public testing::Test {
+ public:
+ void RunOtherThreadInfiniteWait() {
+ base::internal::SetBlockingObserverForCurrentThread(&observer_);
+ MutexLocker lock(mutex_);
+ ready_.Signal();
+ condition_.Wait(mutex_);
+ }
+
+ void RunOtherThreadTimedWait() {
+ base::internal::SetBlockingObserverForCurrentThread(&observer_);
+ MutexLocker lock(mutex_);
+ ready_.Signal();
+ condition_.TimedWait(mutex_, CurrentTime() + 10.0);
+ }
+
+ protected:
+ base::WaitableEvent ready_;
+ testing::StrictMock<MockBlockingObserver> observer_;
+ Mutex mutex_;
+ ThreadCondition condition_;
+};
+
+TEST_F(ThreadConditionTest, WaitReportsBlockingCall) {
+ EXPECT_CALL(observer_, BlockingStarted(base::BlockingType::MAY_BLOCK));
+ EXPECT_CALL(observer_, BlockingEnded());
+
+ base::Thread other_thread("other thread");
+ other_thread.StartAndWaitForTesting();
+ other_thread.task_runner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&ThreadConditionTest::RunOtherThreadInfiniteWait,
+ base::Unretained(this)));
+
+ ready_.Wait();
+ MutexLocker lock(mutex_);
+ condition_.Signal();
+}
+
+TEST_F(ThreadConditionTest, TimedWaitReportsBlockingCall) {
+ EXPECT_CALL(observer_, BlockingStarted(base::BlockingType::MAY_BLOCK));
+ EXPECT_CALL(observer_, BlockingEnded());
+
+ base::Thread other_thread("other thread");
+ other_thread.StartAndWaitForTesting();
+ other_thread.task_runner()->PostTask(
+ FROM_HERE, base::BindOnce(&ThreadConditionTest::RunOtherThreadTimedWait,
+ base::Unretained(this)));
+
+ ready_.Wait();
+ MutexLocker lock(mutex_);
+ condition_.Signal();
+}
+
+} // namespace
+} // namespace WTF
diff --git a/chromium/third_party/blink/renderer/platform/wtf/threading_pthreads.cc b/chromium/third_party/blink/renderer/platform/wtf/threading_pthreads.cc
index cf4f9837b3e..a49db17ff5a 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/threading_pthreads.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/threading_pthreads.cc
@@ -38,6 +38,7 @@
#include <limits.h>
#include <sched.h>
#include <sys/time.h>
+#include "base/threading/scoped_blocking_call.h"
#include "third_party/blink/renderer/platform/wtf/date_math.h"
#include "third_party/blink/renderer/platform/wtf/dtoa/double-conversion.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
@@ -61,67 +62,6 @@
namespace WTF {
-namespace internal {
-
-ThreadIdentifier CurrentThreadSyscall() {
-#if defined(OS_MACOSX)
- return pthread_mach_thread_np(pthread_self());
-#elif defined(OS_LINUX)
- return syscall(__NR_gettid);
-#elif defined(OS_ANDROID)
- return gettid();
-#else
- return reinterpret_cast<uintptr_t>(pthread_self());
-#endif
-}
-
-} // namespace internal
-
-void InitializeThreading() {
- // This should only be called once.
- WTFThreadData::Initialize();
-
- InitializeDates();
- // Force initialization of static DoubleToStringConverter converter variable
- // inside EcmaScriptConverter function while we are in single thread mode.
- double_conversion::DoubleToStringConverter::EcmaScriptConverter();
-}
-
-namespace {
-pthread_key_t g_current_thread_key;
-bool g_current_thread_key_initialized = false;
-} // namespace
-
-void InitializeCurrentThread() {
- DCHECK(!g_current_thread_key_initialized);
- int error = pthread_key_create(&g_current_thread_key, nullptr);
- CHECK(!error);
- g_current_thread_key_initialized = true;
-}
-
-ThreadIdentifier CurrentThread() {
- // This doesn't use WTF::ThreadSpecific (e.g. WTFThreadData) because
- // ThreadSpecific now depends on currentThread. It is necessary to avoid this
- // or a similar loop:
- //
- // currentThread
- // -> wtfThreadData
- // -> ThreadSpecific::operator*
- // -> isMainThread
- // -> currentThread
- static_assert(sizeof(ThreadIdentifier) <= sizeof(void*),
- "ThreadIdentifier must fit in a void*.");
- DCHECK(g_current_thread_key_initialized);
- void* value = pthread_getspecific(g_current_thread_key);
- if (UNLIKELY(!value)) {
- value = reinterpret_cast<void*>(
- static_cast<intptr_t>(internal::CurrentThreadSyscall()));
- DCHECK(value);
- pthread_setspecific(g_current_thread_key, value);
- }
- return reinterpret_cast<intptr_t>(pthread_getspecific(g_current_thread_key));
-}
-
MutexBase::MutexBase(bool recursive) {
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
@@ -146,6 +86,8 @@ void MutexBase::lock() {
int result = pthread_mutex_lock(&mutex_.internal_mutex_);
DCHECK_EQ(result, 0);
#if DCHECK_IS_ON()
+ DCHECK(!mutex_.recursion_count_)
+ << "WTF does not support recursive mutex acquisition!";
++mutex_.recursion_count_;
#endif
}
@@ -170,7 +112,8 @@ bool Mutex::TryLock() {
#if DCHECK_IS_ON()
// The Mutex class is not recursive, so the recursionCount should be
// zero after getting the lock.
- DCHECK(!mutex_.recursion_count_);
+ DCHECK(!mutex_.recursion_count_)
+ << "WTF does not support recursive mutex acquisition!";
++mutex_.recursion_count_;
#endif
return true;
@@ -186,6 +129,8 @@ bool RecursiveMutex::TryLock() {
int result = pthread_mutex_trylock(&mutex_.internal_mutex_);
if (result == 0) {
#if DCHECK_IS_ON()
+ DCHECK(!mutex_.recursion_count_)
+ << "WTF does not support recursive mutex acquisition!";
++mutex_.recursion_count_;
#endif
return true;
@@ -206,7 +151,11 @@ ThreadCondition::~ThreadCondition() {
}
void ThreadCondition::Wait(Mutex& mutex) {
+ base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
PlatformMutex& platform_mutex = mutex.Impl();
+#if DCHECK_IS_ON()
+ --platform_mutex.recursion_count_;
+#endif
int result = pthread_cond_wait(&condition_, &platform_mutex.internal_mutex_);
DCHECK_EQ(result, 0);
#if DCHECK_IS_ON()
@@ -230,7 +179,11 @@ bool ThreadCondition::TimedWait(Mutex& mutex, double absolute_time) {
target_time.tv_sec = time_seconds;
target_time.tv_nsec = time_nanoseconds;
+ base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
PlatformMutex& platform_mutex = mutex.Impl();
+#if DCHECK_IS_ON()
+ --platform_mutex.recursion_count_;
+#endif
int result = pthread_cond_timedwait(
&condition_, &platform_mutex.internal_mutex_, &target_time);
#if DCHECK_IS_ON()
@@ -249,25 +202,6 @@ void ThreadCondition::Broadcast() {
DCHECK_EQ(result, 0);
}
-#if DCHECK_IS_ON()
-static bool g_thread_created = false;
-
-Mutex& GetThreadCreatedMutex() {
- static Mutex g_thread_created_mutex;
- return g_thread_created_mutex;
-}
-
-bool IsBeforeThreadCreated() {
- MutexLocker locker(GetThreadCreatedMutex());
- return !g_thread_created;
-}
-
-void WillCreateThread() {
- MutexLocker locker(GetThreadCreatedMutex());
- g_thread_created = true;
-}
-#endif
-
} // namespace WTF
#endif // defined(OS_POSIX) || defined(OS_FUCHSIA)
diff --git a/chromium/third_party/blink/renderer/platform/wtf/threading_win.cc b/chromium/third_party/blink/renderer/platform/wtf/threading_win.cc
index 09cc847bd63..7d994366534 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/threading_win.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/threading_win.cc
@@ -105,83 +105,12 @@
#include <errno.h>
#include <process.h>
#include <windows.h>
-#include "third_party/blink/renderer/platform/wtf/date_math.h"
-#include "third_party/blink/renderer/platform/wtf/dtoa/double-conversion.h"
-#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/thread_specific.h"
+#include "base/threading/scoped_blocking_call.h"
#include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
#include "third_party/blink/renderer/platform/wtf/time.h"
-#include "third_party/blink/renderer/platform/wtf/wtf_thread_data.h"
namespace WTF {
-// THREADNAME_INFO comes from
-// <http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx>.
-#pragma pack(push, 8)
-typedef struct tagTHREADNAME_INFO {
- DWORD dw_type; // must be 0x1000
- LPCSTR sz_name; // pointer to name (in user addr space)
- DWORD dw_thread_id; // thread ID (-1=caller thread)
- DWORD dw_flags; // reserved for future use, must be zero
-} THREADNAME_INFO;
-#pragma pack(pop)
-
-namespace internal {
-
-ThreadIdentifier CurrentThreadSyscall() {
- return static_cast<ThreadIdentifier>(GetCurrentThreadId());
-}
-
-} // namespace internal
-
-void InitializeThreading() {
- // This should only be called once.
- WTFThreadData::Initialize();
-
- InitializeDates();
- // Force initialization of static DoubleToStringConverter converter variable
- // inside EcmaScriptConverter function while we are in single thread mode.
- double_conversion::DoubleToStringConverter::EcmaScriptConverter();
-}
-
-namespace {
-DWORD g_current_thread_key;
-bool g_current_thread_key_initialized = false;
-} // namespace
-
-void InitializeCurrentThread() {
- DCHECK(!g_current_thread_key_initialized);
-
- // This key is never destroyed.
- g_current_thread_key = ::TlsAlloc();
-
- CHECK_NE(g_current_thread_key, TLS_OUT_OF_INDEXES);
- g_current_thread_key_initialized = true;
-}
-
-ThreadIdentifier CurrentThread() {
- // This doesn't use WTF::ThreadSpecific (e.g. WTFThreadData) because
- // ThreadSpecific now depends on currentThread. It is necessary to avoid this
- // or a similar loop:
- //
- // currentThread
- // -> wtfThreadData
- // -> ThreadSpecific::operator*
- // -> isMainThread
- // -> currentThread
- static_assert(sizeof(ThreadIdentifier) <= sizeof(void*),
- "ThreadIdentifier must fit in a void*.");
- DCHECK(g_current_thread_key_initialized);
- void* value = ::TlsGetValue(g_current_thread_key);
- if (UNLIKELY(!value)) {
- value = reinterpret_cast<void*>(internal::CurrentThreadSyscall());
- DCHECK(value);
- ::TlsSetValue(g_current_thread_key, value);
- }
- return reinterpret_cast<intptr_t>(::TlsGetValue(g_current_thread_key));
-}
-
MutexBase::MutexBase(bool recursive) {
mutex_.recursion_count_ = 0;
InitializeCriticalSection(&mutex_.internal_mutex_);
@@ -193,6 +122,8 @@ MutexBase::~MutexBase() {
void MutexBase::lock() {
EnterCriticalSection(&mutex_.internal_mutex_);
+ DCHECK(!mutex_.recursion_count_)
+ << "WTF does not support recursive mutex acquisition!";
++mutex_.recursion_count_;
}
@@ -218,6 +149,8 @@ bool Mutex::TryLock() {
// check in the lock method (presumably due to performance?). This
// means lock() will succeed even if the current thread has already
// entered the critical section.
+ DCHECK(!mutex_.recursion_count_)
+ << "WTF does not support recursive mutex acquisition!";
if (mutex_.recursion_count_ > 0) {
LeaveCriticalSection(&mutex_.internal_mutex_);
return false;
@@ -236,6 +169,8 @@ bool RecursiveMutex::TryLock() {
if (result == 0) { // We didn't get the lock.
return false;
}
+ DCHECK(!mutex_.recursion_count_)
+ << "WTF does not support recursive mutex acquisition!";
++mutex_.recursion_count_;
return true;
}
@@ -248,6 +183,8 @@ ThreadCondition::~ThreadCondition() {}
void ThreadCondition::Wait(Mutex& mutex) {
PlatformMutex& platform_mutex = mutex.Impl();
+ base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
+ --platform_mutex.recursion_count_;
BOOL result = SleepConditionVariableCS(
&condition_, &platform_mutex.internal_mutex_, INFINITE);
DCHECK_NE(result, 0);
@@ -271,7 +208,9 @@ bool ThreadCondition::TimedWait(Mutex& mutex, double absolute_time) {
? INFINITE
: ((absolute_time - current_time) * 1000.0);
+ base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
PlatformMutex& platform_mutex = mutex.Impl();
+ --platform_mutex.recursion_count_;
BOOL result = SleepConditionVariableCS(
&condition_, &platform_mutex.internal_mutex_, interval);
++platform_mutex.recursion_count_;
@@ -287,25 +226,6 @@ void ThreadCondition::Broadcast() {
WakeAllConditionVariable(&condition_);
}
-#if DCHECK_IS_ON()
-static bool g_thread_created = false;
-
-Mutex& GetThreadCreatedMutex() {
- static Mutex g_thread_created_mutex;
- return g_thread_created_mutex;
-}
-
-bool IsBeforeThreadCreated() {
- MutexLocker locker(GetThreadCreatedMutex());
- return !g_thread_created;
-}
-
-void WillCreateThread() {
- MutexLocker locker(GetThreadCreatedMutex());
- g_thread_created = true;
-}
-#endif
-
} // namespace WTF
#endif // defined(OS_WIN)
diff --git a/chromium/third_party/blink/renderer/platform/wtf/type_traits.h b/chromium/third_party/blink/renderer/platform/wtf/type_traits.h
index 7fd0ecc9cb9..6d1603d6d0b 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/type_traits.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/type_traits.h
@@ -25,6 +25,7 @@
#include <cstddef>
#include <type_traits>
#include <utility>
+#include "base/template_util.h"
#include "build/build_config.h"
#include "third_party/blink/renderer/platform/wtf/compiler.h"
@@ -262,6 +263,14 @@ class IsPointerToGarbageCollectedType<T*, false> {
static const bool value = IsGarbageCollectedType<T>::value;
};
+template <typename T, typename = void>
+struct IsStackAllocatedType : std::false_type {};
+
+template <typename T>
+struct IsStackAllocatedType<
+ T,
+ base::void_t<typename T::IsStackAllocatedTypeMarker>> : std::true_type {};
+
} // namespace WTF
using WTF::IsGarbageCollectedType;
diff --git a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.cc b/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.cc
index 053babce105..83133e1a836 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.cc
@@ -128,12 +128,13 @@ void ArrayBufferContents::FreeMemory(void* data) {
ArrayBufferContents::DataHandle ArrayBufferContents::CreateDataHandle(
size_t size,
InitializationPolicy policy) {
- return DataHandle(ArrayBufferContents::AllocateMemoryOrNull(size, policy),
- size, FreeMemory);
+ return DataHandle(
+ ArrayBufferContents::AllocateMemoryOrNull(size, policy), size,
+ [](void* buffer, size_t, void*) { FreeMemory(buffer); }, nullptr);
}
ArrayBufferContents::DataHolder::DataHolder()
- : data_(nullptr, 0, FreeMemory),
+ : data_(nullptr, 0, [](void*, size_t, void*) {}, nullptr),
is_shared_(kNotShared),
has_registered_external_allocation_(false) {}
@@ -156,7 +157,7 @@ void ArrayBufferContents::DataHolder::AllocateNew(size_t length,
is_shared_ = is_shared;
- AdjustAmountOfExternalAllocatedMemory(length);
+ RegisterExternalAllocationWithCurrentContext();
}
void ArrayBufferContents::DataHolder::Adopt(DataHandle data,
@@ -167,7 +168,7 @@ void ArrayBufferContents::DataHolder::Adopt(DataHandle data,
data_ = std::move(data);
is_shared_ = is_shared;
- AdjustAmountOfExternalAllocatedMemory(data.DataLength());
+ RegisterExternalAllocationWithCurrentContext();
}
void ArrayBufferContents::DataHolder::CopyMemoryFrom(const DataHolder& source) {
@@ -180,12 +181,17 @@ void ArrayBufferContents::DataHolder::CopyMemoryFrom(const DataHolder& source) {
memcpy(data_.Data(), source.Data(), source.DataLength());
- AdjustAmountOfExternalAllocatedMemory(source.DataLength());
+ RegisterExternalAllocationWithCurrentContext();
}
void ArrayBufferContents::DataHolder::
RegisterExternalAllocationWithCurrentContext() {
DCHECK(!has_registered_external_allocation_);
+ // Currently, we can only track an allocation if we have a single owner. For
+ // shared data this is not true, hence do not attempt to track at all.
+ // TODO(crbug.com/877055) Implement tracking of shared external allocations.
+ if (IsShared())
+ return;
AdjustAmountOfExternalAllocatedMemory(static_cast<int64_t>(DataLength()));
}
@@ -193,6 +199,7 @@ void ArrayBufferContents::DataHolder::
UnregisterExternalAllocationWithCurrentContext() {
if (!has_registered_external_allocation_)
return;
+ DCHECK(!IsShared());
AdjustAmountOfExternalAllocatedMemory(-static_cast<int64_t>(DataLength()));
}
diff --git a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.h b/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.h
index 809229caa87..a87a02bdaf4 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.h
@@ -50,7 +50,7 @@ class WTF_EXPORT ArrayBufferContents {
// ArrayBufferContents::FreeMemory as the DataDeleter. Most clients would want
// to use ArrayBufferContents::CreateDataHandle, which allocates memory and
// specifies the correct deleter.
- using DataDeleter = void (*)(void* data);
+ using DataDeleter = void (*)(void* data, size_t length, void* info);
enum class AllocationKind { kNormal, kReservation };
@@ -58,25 +58,31 @@ class WTF_EXPORT ArrayBufferContents {
DISALLOW_COPY_AND_ASSIGN(DataHandle);
public:
- DataHandle(void* data, size_t length, DataDeleter deleter)
+ DataHandle(void* data,
+ size_t length,
+ DataDeleter deleter,
+ void* deleter_info)
: allocation_base_(data),
allocation_length_(length),
data_(data),
data_length_(length),
kind_(AllocationKind::kNormal),
- deleter_(deleter) {}
+ deleter_(deleter),
+ deleter_info_(deleter_info) {}
DataHandle(void* allocation_base,
size_t allocation_length,
void* data,
size_t data_length,
AllocationKind kind,
- DataDeleter deleter)
+ DataDeleter deleter,
+ void* deleter_info)
: allocation_base_(allocation_base),
allocation_length_(allocation_length),
data_(data),
data_length_(data_length),
kind_(kind),
- deleter_(deleter) {
+ deleter_(deleter),
+ deleter_info_(deleter_info) {
DCHECK(reinterpret_cast<uintptr_t>(allocation_base_) <=
reinterpret_cast<uintptr_t>(data_));
DCHECK(reinterpret_cast<uintptr_t>(data_) + data_length_ <=
@@ -96,10 +102,11 @@ class WTF_EXPORT ArrayBufferContents {
switch (kind_) {
case AllocationKind::kNormal:
DCHECK(deleter_);
- deleter_(data_);
+ deleter_(data_, data_length_, deleter_info_);
return;
case AllocationKind::kReservation:
- base::FreePages(allocation_base_, allocation_length_);
+ DCHECK(deleter_);
+ deleter_(data_, data_length_, deleter_info_);
return;
}
}
@@ -112,6 +119,7 @@ class WTF_EXPORT ArrayBufferContents {
data_length_ = other.data_length_;
kind_ = other.kind_;
deleter_ = other.deleter_;
+ deleter_info_ = other.deleter_info_;
other.allocation_base_ = nullptr;
return *this;
}
@@ -137,6 +145,7 @@ class WTF_EXPORT ArrayBufferContents {
ArrayBufferContents::AllocationKind kind_;
DataDeleter deleter_;
+ void* deleter_info_;
};
enum InitializationPolicy { kZeroInitialize, kDontInitialize };
diff --git a/chromium/third_party/blink/renderer/platform/wtf/vector.h b/chromium/third_party/blink/renderer/platform/wtf/vector.h
index 51bf9f034f0..1a3f291358c 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/vector.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/vector.h
@@ -39,6 +39,7 @@
#include "third_party/blink/renderer/platform/wtf/not_found.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "third_party/blink/renderer/platform/wtf/vector_traits.h"
+#include "third_party/blink/renderer/platform/wtf/wtf_size_t.h"
// For ASAN builds, disable inline buffers completely as they cause various
// issues.
@@ -51,15 +52,15 @@
namespace WTF {
#if defined(MEMORY_SANITIZER_INITIAL_SIZE)
-static const size_t kInitialVectorSize = 1;
+static const wtf_size_t kInitialVectorSize = 1;
#else
#ifndef WTF_VECTOR_INITIAL_SIZE
#define WTF_VECTOR_INITIAL_SIZE 4
#endif
-static const size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE;
+static const wtf_size_t kInitialVectorSize = WTF_VECTOR_INITIAL_SIZE;
#endif
-template <typename T, size_t inlineBuffer, typename Allocator>
+template <typename T, wtf_size_t inlineBuffer, typename Allocator>
class Deque;
//
@@ -389,7 +390,7 @@ class VectorBufferBase {
DISALLOW_NEW();
public:
- void AllocateBuffer(size_t new_capacity) {
+ void AllocateBuffer(wtf_size_t new_capacity) {
DCHECK(new_capacity);
DCHECK_LE(new_capacity,
Allocator::template MaxElementCountInBackingStore<T>());
@@ -399,11 +400,11 @@ class VectorBufferBase {
Allocator::template AllocateInlineVectorBacking<T>(size_to_allocate);
else
buffer_ = Allocator::template AllocateVectorBacking<T>(size_to_allocate);
- capacity_ = size_to_allocate / sizeof(T);
+ capacity_ = static_cast<wtf_size_t>(size_to_allocate / sizeof(T));
Allocator::BackingWriteBarrier(buffer_);
}
- void AllocateExpandedBuffer(size_t new_capacity) {
+ void AllocateExpandedBuffer(wtf_size_t new_capacity) {
DCHECK(new_capacity);
size_t size_to_allocate = AllocationSize(new_capacity);
if (hasInlineCapacity)
@@ -412,7 +413,7 @@ class VectorBufferBase {
else
buffer_ = Allocator::template AllocateExpandedVectorBacking<T>(
size_to_allocate);
- capacity_ = size_to_allocate / sizeof(T);
+ capacity_ = static_cast<wtf_size_t>(size_to_allocate / sizeof(T));
Allocator::BackingWriteBarrier(buffer_);
}
@@ -422,7 +423,7 @@ class VectorBufferBase {
T* Buffer() { return buffer_; }
const T* Buffer() const { return buffer_; }
- size_t capacity() const { return capacity_; }
+ wtf_size_t capacity() const { return capacity_; }
void ClearUnusedSlots(T* from, T* to) {
// If the vector backing is garbage-collected and needs tracing or
@@ -448,18 +449,19 @@ class VectorBufferBase {
// |end| is exclusive, a la STL.
struct OffsetRange final {
OffsetRange() : begin(0), end(0) {}
- explicit OffsetRange(size_t begin, size_t end) : begin(begin), end(end) {
+ explicit OffsetRange(wtf_size_t begin, wtf_size_t end)
+ : begin(begin), end(end) {
DCHECK_LE(begin, end);
}
bool empty() const { return begin == end; }
- size_t begin;
- size_t end;
+ wtf_size_t begin;
+ wtf_size_t end;
};
protected:
VectorBufferBase() : buffer_(nullptr), capacity_(0) {}
- VectorBufferBase(T* buffer, size_t capacity)
+ VectorBufferBase(T* buffer, wtf_size_t capacity)
: buffer_(buffer), capacity_(capacity) {}
VectorBufferBase(HashTableDeletedValueType value)
@@ -469,14 +471,14 @@ class VectorBufferBase {
}
T* buffer_;
- unsigned capacity_;
- unsigned size_;
+ wtf_size_t capacity_;
+ wtf_size_t size_;
DISALLOW_COPY_AND_ASSIGN(VectorBufferBase);
};
template <typename T,
- size_t inlineCapacity,
+ wtf_size_t inlineCapacity,
typename Allocator = PartitionAllocator>
class VectorBuffer;
@@ -491,7 +493,7 @@ class VectorBuffer<T, 0, Allocator>
VectorBuffer() = default;
- explicit VectorBuffer(size_t capacity) {
+ explicit VectorBuffer(wtf_size_t capacity) {
// Calling malloc(0) might take a lock and may actually do an allocation
// on some systems.
if (capacity)
@@ -507,21 +509,21 @@ class VectorBuffer<T, 0, Allocator>
Allocator::FreeVectorBacking(buffer_to_deallocate);
}
- bool ExpandBuffer(size_t new_capacity) {
+ bool ExpandBuffer(wtf_size_t new_capacity) {
size_t size_to_allocate = AllocationSize(new_capacity);
if (Allocator::ExpandVectorBacking(buffer_, size_to_allocate)) {
- capacity_ = size_to_allocate / sizeof(T);
+ capacity_ = static_cast<wtf_size_t>(size_to_allocate / sizeof(T));
return true;
}
return false;
}
- inline bool ShrinkBuffer(size_t new_capacity) {
+ inline bool ShrinkBuffer(wtf_size_t new_capacity) {
DCHECK_LT(new_capacity, capacity());
size_t size_to_allocate = AllocationSize(new_capacity);
if (Allocator::ShrinkVectorBacking(buffer_, AllocationSize(capacity()),
size_to_allocate)) {
- capacity_ = size_to_allocate / sizeof(T);
+ capacity_ = static_cast<wtf_size_t>(size_to_allocate / sizeof(T));
return true;
}
return false;
@@ -571,7 +573,7 @@ class VectorBuffer<T, 0, Allocator>
using Base::capacity_;
};
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
class VectorBuffer : protected VectorBufferBase<T, true, Allocator> {
private:
using Base = VectorBufferBase<T, true, Allocator>;
@@ -586,7 +588,7 @@ class VectorBuffer : protected VectorBufferBase<T, true, Allocator> {
return Base::IsHashTableDeletedValue();
}
- explicit VectorBuffer(size_t capacity)
+ explicit VectorBuffer(wtf_size_t capacity)
: Base(InlineBuffer(), inlineCapacity) {
if (capacity > inlineCapacity)
Base::AllocateBuffer(capacity);
@@ -606,20 +608,20 @@ class VectorBuffer : protected VectorBufferBase<T, true, Allocator> {
ReallyDeallocateBuffer(buffer_to_deallocate);
}
- bool ExpandBuffer(size_t new_capacity) {
+ bool ExpandBuffer(wtf_size_t new_capacity) {
DCHECK_GT(new_capacity, inlineCapacity);
if (buffer_ == InlineBuffer())
return false;
size_t size_to_allocate = AllocationSize(new_capacity);
if (Allocator::ExpandInlineVectorBacking(buffer_, size_to_allocate)) {
- capacity_ = size_to_allocate / sizeof(T);
+ capacity_ = static_cast<wtf_size_t>(size_to_allocate / sizeof(T));
return true;
}
return false;
}
- inline bool ShrinkBuffer(size_t new_capacity) {
+ inline bool ShrinkBuffer(wtf_size_t new_capacity) {
DCHECK_LT(new_capacity, capacity());
if (new_capacity <= inlineCapacity) {
// We need to switch to inlineBuffer. Vector::shrinkCapacity will
@@ -631,7 +633,7 @@ class VectorBuffer : protected VectorBufferBase<T, true, Allocator> {
if (!Allocator::ShrinkInlineVectorBacking(
buffer_, AllocationSize(capacity()), new_size))
return false;
- capacity_ = new_size / sizeof(T);
+ capacity_ = static_cast<wtf_size_t>(new_size / sizeof(T));
return true;
}
@@ -640,7 +642,7 @@ class VectorBuffer : protected VectorBufferBase<T, true, Allocator> {
capacity_ = inlineCapacity;
}
- void AllocateBuffer(size_t new_capacity) {
+ void AllocateBuffer(wtf_size_t new_capacity) {
// FIXME: This should DCHECK(!buffer_) to catch misuse/leaks.
if (new_capacity > inlineCapacity)
Base::AllocateBuffer(new_capacity);
@@ -648,7 +650,7 @@ class VectorBuffer : protected VectorBufferBase<T, true, Allocator> {
ResetBufferPointer();
}
- void AllocateExpandedBuffer(size_t new_capacity) {
+ void AllocateExpandedBuffer(wtf_size_t new_capacity) {
if (new_capacity > inlineCapacity)
Base::AllocateExpandedBuffer(new_capacity);
else
@@ -709,7 +711,7 @@ class VectorBuffer : protected VectorBufferBase<T, true, Allocator> {
// buffer's inline buffer. Elements in an out-of-line buffer won't move,
// because we can just swap pointers of out-of-line buffers.
T* this_source_begin = nullptr;
- size_t this_source_size = 0;
+ wtf_size_t this_source_size = 0;
T* this_destination_begin = nullptr;
if (Buffer() == InlineBuffer()) {
this_source_begin = Buffer();
@@ -724,7 +726,7 @@ class VectorBuffer : protected VectorBufferBase<T, true, Allocator> {
this_hole.begin = this_hole.end = 0;
}
T* other_source_begin = nullptr;
- size_t other_source_size = 0;
+ wtf_size_t other_source_size = 0;
T* other_destination_begin = nullptr;
if (other.Buffer() == other.InlineBuffer()) {
other_source_begin = other.Buffer();
@@ -775,11 +777,11 @@ class VectorBuffer : protected VectorBufferBase<T, true, Allocator> {
// We are ready to move elements. We determine an action for each "section",
// which is a contiguous range such that all elements in the range are
// treated similarly.
- size_t section_begin = 0;
+ wtf_size_t section_begin = 0;
while (section_begin < inlineCapacity) {
// To determine the end of this section, we list up all the boundaries
// where the "occupiedness" may change.
- size_t section_end = inlineCapacity;
+ wtf_size_t section_end = inlineCapacity;
if (this_source_begin && section_begin < this_source_size)
section_end = std::min(section_end, this_source_size);
if (!this_hole.empty() && section_begin < this_hole.begin)
@@ -858,14 +860,14 @@ class VectorBuffer : protected VectorBufferBase<T, true, Allocator> {
using Base::buffer_;
using Base::capacity_;
- static const size_t kInlineBufferSize = inlineCapacity * sizeof(T);
+ static const wtf_size_t kInlineBufferSize = inlineCapacity * sizeof(T);
T* InlineBuffer() { return unsafe_reinterpret_cast_ptr<T*>(inline_buffer_); }
const T* InlineBuffer() const {
return unsafe_reinterpret_cast_ptr<const T*>(inline_buffer_);
}
alignas(T) char inline_buffer_[kInlineBufferSize];
- template <typename U, size_t inlineBuffer, typename V>
+ template <typename U, wtf_size_t inlineBuffer, typename V>
friend class Deque;
DISALLOW_COPY_AND_ASSIGN(VectorBuffer);
@@ -977,7 +979,7 @@ class VectorBuffer : protected VectorBufferBase<T, true, Allocator> {
// allocate an iterator on stack (as a local variable), and you should not
// store iterators in another heap object.
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
class Vector : private VectorBuffer<T, INLINE_CAPACITY, Allocator> {
USE_ALLOCATOR(Vector, Allocator);
using Base = VectorBuffer<T, INLINE_CAPACITY, Allocator>;
@@ -997,10 +999,10 @@ class Vector : private VectorBuffer<T, INLINE_CAPACITY, Allocator> {
inline Vector();
// Create a vector containing the specified number of default-initialized
// elements.
- inline explicit Vector(size_t);
+ inline explicit Vector(wtf_size_t);
// Create a vector containing the specified number of elements, each of which
// is copy initialized from the specified value.
- inline Vector(size_t, const T&);
+ inline Vector(wtf_size_t, const T&);
// HashTable support
Vector(HashTableDeletedValueType value) : Base(value) {}
@@ -1010,11 +1012,11 @@ class Vector : private VectorBuffer<T, INLINE_CAPACITY, Allocator> {
// Copying.
Vector(const Vector&);
- template <size_t otherCapacity>
+ template <wtf_size_t otherCapacity>
explicit Vector(const Vector<T, otherCapacity, Allocator>&);
Vector& operator=(const Vector&);
- template <size_t otherCapacity>
+ template <wtf_size_t otherCapacity>
Vector& operator=(const Vector<T, otherCapacity, Allocator>&);
// Moving.
@@ -1032,8 +1034,8 @@ class Vector : private VectorBuffer<T, INLINE_CAPACITY, Allocator> {
//
// capacity() is the maximum number of elements that the Vector can hold
// without a reallocation. It can be zero.
- size_t size() const { return size_; }
- size_t capacity() const { return Base::capacity(); }
+ wtf_size_t size() const { return size_; }
+ wtf_size_t capacity() const { return Base::capacity(); }
bool IsEmpty() const { return !size(); }
// at() and operator[]: Obtain the reference of the element that is located
@@ -1043,17 +1045,17 @@ class Vector : private VectorBuffer<T, INLINE_CAPACITY, Allocator> {
// pointerToVector->at(1);
// instead of:
// (*pointerToVector)[1];
- T& at(size_t i) {
+ T& at(wtf_size_t i) {
CHECK_LT(i, size());
return Base::Buffer()[i];
}
- const T& at(size_t i) const {
+ const T& at(wtf_size_t i) const {
CHECK_LT(i, size());
return Base::Buffer()[i];
}
- T& operator[](size_t i) { return at(i); }
- const T& operator[](size_t i) const { return at(i); }
+ T& operator[](wtf_size_t i) { return at(i); }
+ const T& operator[](wtf_size_t i) const { return at(i); }
// Return a pointer to the front of the backing buffer. Those pointers get
// invalidated on a reallocation.
@@ -1090,9 +1092,9 @@ class Vector : private VectorBuffer<T, INLINE_CAPACITY, Allocator> {
template <typename U>
bool Contains(const U&) const;
template <typename U>
- size_t Find(const U&) const;
+ wtf_size_t Find(const U&) const;
template <typename U>
- size_t ReverseFind(const U&) const;
+ wtf_size_t ReverseFind(const U&) const;
// Resize the vector to the specified size.
//
@@ -1107,19 +1109,19 @@ class Vector : private VectorBuffer<T, INLINE_CAPACITY, Allocator> {
//
// When a vector grows, new elements will be added in the back, and they
// will be default-initialized. A reallocation may happen in this case.
- void Shrink(size_t);
- void Grow(size_t);
- void resize(size_t);
+ void Shrink(wtf_size_t);
+ void Grow(wtf_size_t);
+ void resize(wtf_size_t);
// Increase the capacity of the vector to at least |newCapacity|. The
// elements in the vector are not affected. This function does not shrink
// the size of the backing buffer, even if |newCapacity| is small. This
// function may cause a reallocation.
- void ReserveCapacity(size_t new_capacity);
+ void ReserveCapacity(wtf_size_t new_capacity);
// This is similar to reserveCapacity() but must be called immediately after
// the vector is default-constructed.
- void ReserveInitialCapacity(size_t initial_capacity);
+ void ReserveInitialCapacity(wtf_size_t initial_capacity);
// Shrink the backing buffer so it can contain exactly |size()| elements.
// This function may cause a reallocation.
@@ -1166,8 +1168,8 @@ class Vector : private VectorBuffer<T, INLINE_CAPACITY, Allocator> {
return back();
}
template <typename U>
- void Append(const U*, size_t);
- template <typename U, size_t otherCapacity, typename V>
+ void Append(const U*, wtf_size_t);
+ template <typename U, wtf_size_t otherCapacity, typename V>
void AppendVector(const Vector<U, otherCapacity, V>&);
template <typename Iterator>
void AppendRange(Iterator begin, Iterator end);
@@ -1187,11 +1189,11 @@ class Vector : private VectorBuffer<T, INLINE_CAPACITY, Allocator> {
// Insert multiple elements represented by either |buffer| and |size|
// or |vector| at |position|. The elements will be copied.
template <typename U>
- void insert(size_t position, U&&);
+ void insert(wtf_size_t position, U&&);
template <typename U>
- void insert(size_t position, const U*, size_t);
- template <typename U, size_t otherCapacity, typename OtherAllocator>
- void InsertVector(size_t position,
+ void insert(wtf_size_t position, const U*, wtf_size_t);
+ template <typename U, wtf_size_t otherCapacity, typename OtherAllocator>
+ void InsertVector(wtf_size_t position,
const Vector<U, otherCapacity, OtherAllocator>&);
// Insertion to the front. All of these functions will take O(size())-time.
@@ -1208,16 +1210,16 @@ class Vector : private VectorBuffer<T, INLINE_CAPACITY, Allocator> {
template <typename U>
void push_front(U&&);
template <typename U>
- void push_front(const U*, size_t);
- template <typename U, size_t otherCapacity, typename OtherAllocator>
+ void push_front(const U*, wtf_size_t);
+ template <typename U, wtf_size_t otherCapacity, typename OtherAllocator>
void PrependVector(const Vector<U, otherCapacity, OtherAllocator>&);
// Remove an element or elements at the specified position. These functions
// take O(size())-time. All of the elements after the removed ones will be
// moved to the new locations. All the iterators pointing to any element
// after |position| will be invalidated.
- void EraseAt(size_t position);
- void EraseAt(size_t position, size_t length);
+ void EraseAt(wtf_size_t position);
+ void EraseAt(wtf_size_t position, wtf_size_t length);
iterator erase(iterator position);
// Remove the last element. Unlike remove(), (1) this function is fast, and
@@ -1236,7 +1238,7 @@ class Vector : private VectorBuffer<T, INLINE_CAPACITY, Allocator> {
// or copy-initialize all the elements.
//
// fill(value) is a synonym for fill(value, size()).
- void Fill(const T&, size_t);
+ void Fill(const T&, wtf_size_t);
void Fill(const T& val) { Fill(val, size()); }
// Swap two vectors quickly.
@@ -1293,16 +1295,18 @@ class Vector : private VectorBuffer<T, INLINE_CAPACITY, Allocator> {
using Base::CheckUnusedSlots;
using Base::ClearUnusedSlots;
+ T** GetBufferSlot() { return Base::BufferSlot(); }
+
private:
- void ExpandCapacity(size_t new_min_capacity);
- T* ExpandCapacity(size_t new_min_capacity, T*);
- T* ExpandCapacity(size_t new_min_capacity, const T* data) {
+ void ExpandCapacity(wtf_size_t new_min_capacity);
+ T* ExpandCapacity(wtf_size_t new_min_capacity, T*);
+ T* ExpandCapacity(wtf_size_t new_min_capacity, const T* data) {
return ExpandCapacity(new_min_capacity, const_cast<T*>(data));
}
template <typename U>
- U* ExpandCapacity(size_t new_min_capacity, U*);
- void ShrinkCapacity(size_t new_capacity);
+ U* ExpandCapacity(wtf_size_t new_min_capacity, U*);
+ void ShrinkCapacity(wtf_size_t new_capacity);
template <typename U>
void AppendSlowCase(U&&);
@@ -1320,7 +1324,7 @@ class Vector : private VectorBuffer<T, INLINE_CAPACITY, Allocator> {
// Vector out-of-line implementation
//
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
inline Vector<T, inlineCapacity, Allocator>::Vector() {
static_assert(!std::is_polymorphic<T>::value ||
!VectorTraits<T>::kCanInitializeWithMemset,
@@ -1338,8 +1342,9 @@ inline Vector<T, inlineCapacity, Allocator>::Vector() {
size_ = 0;
}
-template <typename T, size_t inlineCapacity, typename Allocator>
-inline Vector<T, inlineCapacity, Allocator>::Vector(size_t size) : Base(size) {
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
+inline Vector<T, inlineCapacity, Allocator>::Vector(wtf_size_t size)
+ : Base(size) {
static_assert(!std::is_polymorphic<T>::value ||
!VectorTraits<T>::kCanInitializeWithMemset,
"Cannot initialize with memset if there is a vtable");
@@ -1357,8 +1362,9 @@ inline Vector<T, inlineCapacity, Allocator>::Vector(size_t size) : Base(size) {
TypeOperations::Initialize(begin(), end());
}
-template <typename T, size_t inlineCapacity, typename Allocator>
-inline Vector<T, inlineCapacity, Allocator>::Vector(size_t size, const T& val)
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
+inline Vector<T, inlineCapacity, Allocator>::Vector(wtf_size_t size,
+ const T& val)
: Base(size) {
// TODO(yutak): Introduce these assertions. Some use sites call this function
// in the context where T is an incomplete type.
@@ -1381,7 +1387,7 @@ inline Vector<T, inlineCapacity, Allocator>::Vector(size_t size, const T& val)
TypeOperations::UninitializedFill(begin(), end(), val);
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
Vector<T, inlineCapacity, Allocator>::Vector(const Vector& other)
: Base(other.capacity()) {
ANNOTATE_NEW_BUFFER(begin(), capacity(), other.size());
@@ -1389,8 +1395,8 @@ Vector<T, inlineCapacity, Allocator>::Vector(const Vector& other)
TypeOperations::UninitializedCopy(other.begin(), other.end(), begin());
}
-template <typename T, size_t inlineCapacity, typename Allocator>
-template <size_t otherCapacity>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
+template <wtf_size_t otherCapacity>
Vector<T, inlineCapacity, Allocator>::Vector(
const Vector<T, otherCapacity, Allocator>& other)
: Base(other.capacity()) {
@@ -1399,7 +1405,7 @@ Vector<T, inlineCapacity, Allocator>::Vector(
TypeOperations::UninitializedCopy(other.begin(), other.end(), begin());
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
Vector<T, inlineCapacity, Allocator>& Vector<T, inlineCapacity, Allocator>::
operator=(const Vector<T, inlineCapacity, Allocator>& other) {
if (UNLIKELY(&other == this))
@@ -1425,8 +1431,8 @@ inline bool TypelessPointersAreEqual(const void* a, const void* b) {
return a == b;
}
-template <typename T, size_t inlineCapacity, typename Allocator>
-template <size_t otherCapacity>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
+template <wtf_size_t otherCapacity>
Vector<T, inlineCapacity, Allocator>& Vector<T, inlineCapacity, Allocator>::
operator=(const Vector<T, otherCapacity, Allocator>& other) {
// If the inline capacities match, we should call the more specific
@@ -1450,7 +1456,7 @@ operator=(const Vector<T, otherCapacity, Allocator>& other) {
return *this;
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
Vector<T, inlineCapacity, Allocator>::Vector(
Vector<T, inlineCapacity, Allocator>&& other) {
size_ = 0;
@@ -1459,74 +1465,77 @@ Vector<T, inlineCapacity, Allocator>::Vector(
swap(other);
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
Vector<T, inlineCapacity, Allocator>& Vector<T, inlineCapacity, Allocator>::
operator=(Vector<T, inlineCapacity, Allocator>&& other) {
swap(other);
return *this;
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
Vector<T, inlineCapacity, Allocator>::Vector(std::initializer_list<T> elements)
- : Base(elements.size()) {
+ : Base(SafeCast<wtf_size_t>(elements.size())) {
ANNOTATE_NEW_BUFFER(begin(), capacity(), elements.size());
- size_ = elements.size();
+ size_ = static_cast<wtf_size_t>(elements.size());
TypeOperations::UninitializedCopy(elements.begin(), elements.end(), begin());
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
Vector<T, inlineCapacity, Allocator>& Vector<T, inlineCapacity, Allocator>::
operator=(std::initializer_list<T> elements) {
- if (size() > elements.size()) {
- Shrink(elements.size());
- } else if (elements.size() > capacity()) {
+ wtf_size_t input_size = SafeCast<wtf_size_t>(elements.size());
+ if (size() > input_size) {
+ Shrink(input_size);
+ } else if (input_size > capacity()) {
clear();
- ReserveCapacity(elements.size());
+ ReserveCapacity(input_size);
DCHECK(begin());
}
- ANNOTATE_CHANGE_SIZE(begin(), capacity(), size_, elements.size());
+ ANNOTATE_CHANGE_SIZE(begin(), capacity(), size_, input_size);
std::copy(elements.begin(), elements.begin() + size_, begin());
TypeOperations::UninitializedCopy(elements.begin() + size_, elements.end(),
end());
- size_ = elements.size();
+ size_ = input_size;
return *this;
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
template <typename U>
bool Vector<T, inlineCapacity, Allocator>::Contains(const U& value) const {
return Find(value) != kNotFound;
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
template <typename U>
-size_t Vector<T, inlineCapacity, Allocator>::Find(const U& value) const {
+wtf_size_t Vector<T, inlineCapacity, Allocator>::Find(const U& value) const {
const T* b = begin();
const T* e = end();
for (const T* iter = b; iter < e; ++iter) {
if (TypeOperations::CompareElement(*iter, value))
- return iter - b;
+ return static_cast<wtf_size_t>(iter - b);
}
return kNotFound;
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
template <typename U>
-size_t Vector<T, inlineCapacity, Allocator>::ReverseFind(const U& value) const {
+wtf_size_t Vector<T, inlineCapacity, Allocator>::ReverseFind(
+ const U& value) const {
const T* b = begin();
const T* iter = end();
while (iter > b) {
--iter;
if (TypeOperations::CompareElement(*iter, value))
- return iter - b;
+ return static_cast<wtf_size_t>(iter - b);
}
return kNotFound;
}
-template <typename T, size_t inlineCapacity, typename Allocator>
-void Vector<T, inlineCapacity, Allocator>::Fill(const T& val, size_t new_size) {
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
+void 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()) {
@@ -1541,11 +1550,11 @@ void Vector<T, inlineCapacity, Allocator>::Fill(const T& val, size_t new_size) {
size_ = new_size;
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
void Vector<T, inlineCapacity, Allocator>::ExpandCapacity(
- size_t new_min_capacity) {
- size_t old_capacity = capacity();
- size_t expanded_capacity = old_capacity;
+ wtf_size_t new_min_capacity) {
+ wtf_size_t old_capacity = capacity();
+ wtf_size_t expanded_capacity = old_capacity;
// We use a more aggressive expansion strategy for Vectors with inline
// storage. This is because they are more likely to be on the stack, so the
// risk of heap bloat is minimized. Furthermore, exceeding the inline
@@ -1564,14 +1573,14 @@ void Vector<T, inlineCapacity, Allocator>::ExpandCapacity(
// (2^31 - 1) allocations.
expanded_capacity += (expanded_capacity / 4) + 1;
}
- ReserveCapacity(std::max(
- new_min_capacity,
- std::max(static_cast<size_t>(kInitialVectorSize), expanded_capacity)));
+ ReserveCapacity(std::max(new_min_capacity,
+ std::max(kInitialVectorSize, expanded_capacity)));
}
-template <typename T, size_t inlineCapacity, typename Allocator>
-T* Vector<T, inlineCapacity, Allocator>::ExpandCapacity(size_t new_min_capacity,
- T* ptr) {
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
+T* Vector<T, inlineCapacity, Allocator>::ExpandCapacity(
+ wtf_size_t new_min_capacity,
+ T* ptr) {
if (ptr < begin() || ptr >= end()) {
ExpandCapacity(new_min_capacity);
return ptr;
@@ -1581,17 +1590,17 @@ T* Vector<T, inlineCapacity, Allocator>::ExpandCapacity(size_t new_min_capacity,
return begin() + index;
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
template <typename U>
inline U* Vector<T, inlineCapacity, Allocator>::ExpandCapacity(
- size_t new_min_capacity,
+ wtf_size_t new_min_capacity,
U* ptr) {
ExpandCapacity(new_min_capacity);
return ptr;
}
-template <typename T, size_t inlineCapacity, typename Allocator>
-inline void Vector<T, inlineCapacity, Allocator>::resize(size_t size) {
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
+inline void Vector<T, inlineCapacity, Allocator>::resize(wtf_size_t size) {
if (size <= size_) {
TypeOperations::Destruct(begin() + size, end());
ClearUnusedSlots(begin() + size, end());
@@ -1606,8 +1615,8 @@ inline void Vector<T, inlineCapacity, Allocator>::resize(size_t size) {
size_ = size;
}
-template <typename T, size_t inlineCapacity, typename Allocator>
-void Vector<T, inlineCapacity, Allocator>::Shrink(size_t size) {
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
+void Vector<T, inlineCapacity, Allocator>::Shrink(wtf_size_t size) {
DCHECK_LE(size, size_);
TypeOperations::Destruct(begin() + size, end());
ClearUnusedSlots(begin() + size, end());
@@ -1615,8 +1624,8 @@ void Vector<T, inlineCapacity, Allocator>::Shrink(size_t size) {
size_ = size;
}
-template <typename T, size_t inlineCapacity, typename Allocator>
-void Vector<T, inlineCapacity, Allocator>::Grow(size_t size) {
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
+void Vector<T, inlineCapacity, Allocator>::Grow(wtf_size_t size) {
DCHECK_GE(size, size_);
if (size > capacity())
ExpandCapacity(size);
@@ -1625,9 +1634,9 @@ void Vector<T, inlineCapacity, Allocator>::Grow(size_t size) {
size_ = size;
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
void Vector<T, inlineCapacity, Allocator>::ReserveCapacity(
- size_t new_capacity) {
+ wtf_size_t new_capacity) {
if (UNLIKELY(new_capacity <= capacity()))
return;
T* old_buffer = begin();
@@ -1636,7 +1645,7 @@ void Vector<T, inlineCapacity, Allocator>::ReserveCapacity(
return;
}
#ifdef ANNOTATE_CONTIGUOUS_CONTAINER
- size_t old_capacity = capacity();
+ wtf_size_t old_capacity = capacity();
#endif
// The Allocator::isGarbageCollected check is not needed. The check is just
// a static hint for a compiler to indicate that Base::expandBuffer returns
@@ -1657,9 +1666,9 @@ void Vector<T, inlineCapacity, Allocator>::ReserveCapacity(
Base::DeallocateBuffer(old_buffer);
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
inline void Vector<T, inlineCapacity, Allocator>::ReserveInitialCapacity(
- size_t initial_capacity) {
+ wtf_size_t initial_capacity) {
DCHECK(!size_);
DCHECK(capacity() == INLINE_CAPACITY);
if (initial_capacity > INLINE_CAPACITY) {
@@ -1669,8 +1678,9 @@ inline void Vector<T, inlineCapacity, Allocator>::ReserveInitialCapacity(
}
}
-template <typename T, size_t inlineCapacity, typename Allocator>
-void Vector<T, inlineCapacity, Allocator>::ShrinkCapacity(size_t new_capacity) {
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
+void Vector<T, inlineCapacity, Allocator>::ShrinkCapacity(
+ wtf_size_t new_capacity) {
if (new_capacity >= capacity())
return;
@@ -1679,7 +1689,7 @@ void Vector<T, inlineCapacity, Allocator>::ShrinkCapacity(size_t new_capacity) {
T* old_buffer = begin();
#ifdef ANNOTATE_CONTIGUOUS_CONTAINER
- size_t old_capacity = capacity();
+ wtf_size_t old_capacity = capacity();
#endif
if (new_capacity > 0) {
if (Base::ShrinkBuffer(new_capacity)) {
@@ -1713,7 +1723,7 @@ void Vector<T, inlineCapacity, Allocator>::ShrinkCapacity(size_t new_capacity) {
// Templatizing these is better than just letting the conversion happen
// implicitly.
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
template <typename U>
ALWAYS_INLINE void Vector<T, inlineCapacity, Allocator>::push_back(U&& val) {
DCHECK(Allocator::IsAllocationAllowed());
@@ -1728,7 +1738,7 @@ ALWAYS_INLINE void Vector<T, inlineCapacity, Allocator>::push_back(U&& val) {
AppendSlowCase(std::forward<U>(val));
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
template <typename... Args>
ALWAYS_INLINE T& Vector<T, inlineCapacity, Allocator>::emplace_back(
Args&&... args) {
@@ -1744,12 +1754,12 @@ ALWAYS_INLINE T& Vector<T, inlineCapacity, Allocator>::emplace_back(
return *t;
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
template <typename U>
void Vector<T, inlineCapacity, Allocator>::Append(const U* data,
- size_t data_size) {
+ wtf_size_t data_size) {
DCHECK(Allocator::IsAllocationAllowed());
- size_t new_size = size_ + data_size;
+ wtf_size_t new_size = size_ + data_size;
if (new_size > capacity()) {
data = ExpandCapacity(new_size, data);
DCHECK(begin());
@@ -1762,7 +1772,7 @@ void Vector<T, inlineCapacity, Allocator>::Append(const U* data,
size_ = new_size;
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
template <typename U>
NOINLINE void Vector<T, inlineCapacity, Allocator>::AppendSlowCase(U&& val) {
DCHECK_EQ(size(), capacity());
@@ -1777,14 +1787,14 @@ NOINLINE void Vector<T, inlineCapacity, Allocator>::AppendSlowCase(U&& val) {
++size_;
}
-template <typename T, size_t inlineCapacity, typename Allocator>
-template <typename U, size_t otherCapacity, typename OtherAllocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
+template <typename U, wtf_size_t otherCapacity, typename OtherAllocator>
inline void Vector<T, inlineCapacity, Allocator>::AppendVector(
const Vector<U, otherCapacity, OtherAllocator>& val) {
Append(val.begin(), val.size());
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
template <typename Iterator>
void Vector<T, inlineCapacity, Allocator>::AppendRange(Iterator begin,
Iterator end) {
@@ -1794,7 +1804,7 @@ void Vector<T, inlineCapacity, Allocator>::AppendRange(Iterator begin,
// This version of append saves a branch in the case where you know that the
// vector's capacity is large enough for the append to succeed.
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
template <typename U>
ALWAYS_INLINE void Vector<T, inlineCapacity, Allocator>::UncheckedAppend(
U&& val) {
@@ -1809,9 +1819,9 @@ ALWAYS_INLINE void Vector<T, inlineCapacity, Allocator>::UncheckedAppend(
#endif
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
template <typename U>
-inline void Vector<T, inlineCapacity, Allocator>::insert(size_t position,
+inline void Vector<T, inlineCapacity, Allocator>::insert(wtf_size_t position,
U&& val) {
DCHECK(Allocator::IsAllocationAllowed());
CHECK_LE(position, size());
@@ -1828,14 +1838,14 @@ inline void Vector<T, inlineCapacity, Allocator>::insert(size_t position,
++size_;
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
template <typename U>
-void Vector<T, inlineCapacity, Allocator>::insert(size_t position,
+void Vector<T, inlineCapacity, Allocator>::insert(wtf_size_t position,
const U* data,
- size_t data_size) {
+ wtf_size_t data_size) {
DCHECK(Allocator::IsAllocationAllowed());
CHECK_LE(position, size());
- size_t new_size = size_ + data_size;
+ wtf_size_t new_size = size_ + data_size;
if (new_size > capacity()) {
data = ExpandCapacity(new_size, data);
DCHECK(begin());
@@ -1849,36 +1859,36 @@ void Vector<T, inlineCapacity, Allocator>::insert(size_t position,
size_ = new_size;
}
-template <typename T, size_t inlineCapacity, typename Allocator>
-template <typename U, size_t otherCapacity, typename OtherAllocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
+template <typename U, wtf_size_t otherCapacity, typename OtherAllocator>
inline void Vector<T, inlineCapacity, Allocator>::InsertVector(
- size_t position,
+ wtf_size_t position,
const Vector<U, otherCapacity, OtherAllocator>& val) {
insert(position, val.begin(), val.size());
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
template <typename U>
inline void Vector<T, inlineCapacity, Allocator>::push_front(U&& val) {
insert(0, std::forward<U>(val));
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
template <typename U>
void Vector<T, inlineCapacity, Allocator>::push_front(const U* data,
- size_t data_size) {
+ wtf_size_t data_size) {
insert(0, data, data_size);
}
-template <typename T, size_t inlineCapacity, typename Allocator>
-template <typename U, size_t otherCapacity, typename OtherAllocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
+template <typename U, wtf_size_t otherCapacity, typename OtherAllocator>
inline void Vector<T, inlineCapacity, Allocator>::PrependVector(
const Vector<U, otherCapacity, OtherAllocator>& val) {
insert(0, val.begin(), val.size());
}
-template <typename T, size_t inlineCapacity, typename Allocator>
-inline void Vector<T, inlineCapacity, Allocator>::EraseAt(size_t position) {
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
+inline void Vector<T, inlineCapacity, Allocator>::EraseAt(wtf_size_t position) {
CHECK_LT(position, size());
T* spot = begin() + position;
spot->~T();
@@ -1888,17 +1898,17 @@ inline void Vector<T, inlineCapacity, Allocator>::EraseAt(size_t position) {
--size_;
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
inline auto Vector<T, inlineCapacity, Allocator>::erase(iterator position)
-> iterator {
- size_t index = position - begin();
+ wtf_size_t index = static_cast<wtf_size_t>(position - begin());
EraseAt(index);
return begin() + index;
}
-template <typename T, size_t inlineCapacity, typename Allocator>
-inline void Vector<T, inlineCapacity, Allocator>::EraseAt(size_t position,
- size_t length) {
+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());
if (!length)
return;
@@ -1912,21 +1922,21 @@ inline void Vector<T, inlineCapacity, Allocator>::EraseAt(size_t position,
size_ -= length;
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
inline void Vector<T, inlineCapacity, Allocator>::Reverse() {
- for (size_t i = 0; i < size_ / 2; ++i)
+ for (wtf_size_t i = 0; i < size_ / 2; ++i)
std::swap(at(i), at(size_ - 1 - i));
}
-template <typename T, size_t inlineCapacity, typename Allocator>
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
inline void swap(Vector<T, inlineCapacity, Allocator>& a,
Vector<T, inlineCapacity, Allocator>& b) {
a.Swap(b);
}
template <typename T,
- size_t inlineCapacityA,
- size_t inlineCapacityB,
+ wtf_size_t inlineCapacityA,
+ wtf_size_t inlineCapacityB,
typename Allocator>
bool operator==(const Vector<T, inlineCapacityA, Allocator>& a,
const Vector<T, inlineCapacityB, Allocator>& b) {
@@ -1939,8 +1949,8 @@ bool operator==(const Vector<T, inlineCapacityA, Allocator>& a,
}
template <typename T,
- size_t inlineCapacityA,
- size_t inlineCapacityB,
+ wtf_size_t inlineCapacityA,
+ wtf_size_t inlineCapacityB,
typename Allocator>
inline bool operator!=(const Vector<T, inlineCapacityA, Allocator>& a,
const Vector<T, inlineCapacityB, Allocator>& b) {
@@ -1948,17 +1958,22 @@ inline bool operator!=(const Vector<T, inlineCapacityA, Allocator>& a,
}
// Only defined for HeapAllocator. Used when visiting vector object.
-template <typename T, size_t inlineCapacity, typename Allocator>
+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) {
static_assert(Allocator::kIsGarbageCollected,
"Garbage collector must be enabled.");
- if (!Buffer())
- return;
+
if (this->HasOutOfLineBuffer()) {
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())
+ return;
// Inline buffer requires tracing immediately.
const T* buffer_begin = Buffer();
const T* buffer_end = Buffer() + size();
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 0e507355351..5a7cfc34fd4 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/vector_test.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/vector_test.cc
@@ -180,19 +180,19 @@ TEST(VectorTest, OwnPtr) {
ASSERT_EQ(1, counter1);
ASSERT_EQ(0, destruct_number);
- size_t index = 0;
+ wtf_size_t index = 0;
for (OwnPtrVector::iterator iter = vector.begin(); iter != vector.end();
++iter) {
std::unique_ptr<DestructCounter>* ref_counter = iter;
- EXPECT_EQ(index, static_cast<size_t>(ref_counter->get()->Get()));
- EXPECT_EQ(index, static_cast<size_t>((*ref_counter)->Get()));
+ EXPECT_EQ(index, static_cast<wtf_size_t>(ref_counter->get()->Get()));
+ EXPECT_EQ(index, static_cast<wtf_size_t>((*ref_counter)->Get()));
index++;
}
EXPECT_EQ(0, destruct_number);
for (index = 0; index < vector.size(); index++) {
std::unique_ptr<DestructCounter>& ref_counter = vector[index];
- EXPECT_EQ(index, static_cast<size_t>(ref_counter->Get()));
+ EXPECT_EQ(index, static_cast<wtf_size_t>(ref_counter->Get()));
}
EXPECT_EQ(0, destruct_number);
@@ -249,14 +249,14 @@ TEST(VectorTest, MoveOnlyType) {
ASSERT_EQ(2, move_only.Value());
ASSERT_EQ(0u, vector.size());
- size_t count = vector.capacity() + 1;
- for (size_t i = 0; i < count; i++)
+ wtf_size_t count = vector.capacity() + 1;
+ for (wtf_size_t i = 0; i < count; i++)
vector.push_back(
MoveOnly(i + 1)); // +1 to distinguish from default-constructed.
// Reallocation did not affect the vector's content.
EXPECT_EQ(count, vector.size());
- for (size_t i = 0; i < vector.size(); i++)
+ for (wtf_size_t i = 0; i < vector.size(); i++)
EXPECT_EQ(static_cast<int>(i + 1), vector[i].Value());
WTF::Vector<MoveOnly> other_vector;
diff --git a/chromium/third_party/blink/renderer/platform/wtf/wtf.cc b/chromium/third_party/blink/renderer/platform/wtf/wtf.cc
index d283ca542f9..10f76b16eb8 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/wtf.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/wtf.cc
@@ -32,6 +32,8 @@
#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/date_math.h"
+#include "third_party/blink/renderer/platform/wtf/dtoa/double-conversion.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/stack_util.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
@@ -39,11 +41,10 @@
#include "third_party/blink/renderer/platform/wtf/thread_specific.h"
#include "third_party/blink/renderer/platform/wtf/threading.h"
#include "third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.h"
+#include "third_party/blink/renderer/platform/wtf/wtf_thread_data.h"
namespace WTF {
-extern void InitializeThreading();
-
bool g_initialized;
void (*g_call_on_main_thread_function)(MainThreadFunction, void*);
ThreadIdentifier g_main_thread_identifier;
@@ -69,7 +70,13 @@ void Initialize(void (*call_on_main_thread_function)(MainThreadFunction,
InitializeCurrentThread();
g_main_thread_identifier = CurrentThread();
- InitializeThreading();
+ WTFThreadData::Initialize();
+
+ InitializeDates();
+
+ // Force initialization of static DoubleToStringConverter converter variable
+ // inside EcmaScriptConverter function while we are in single thread mode.
+ double_conversion::DoubleToStringConverter::EcmaScriptConverter();
g_call_on_main_thread_function = call_on_main_thread_function;
internal::InitializeMainThreadStackEstimate();
diff --git a/chromium/third_party/blink/renderer/platform/wtf/wtf_size_t.h b/chromium/third_party/blink/renderer/platform/wtf/wtf_size_t.h
new file mode 100644
index 00000000000..fb28364830d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/wtf/wtf_size_t.h
@@ -0,0 +1,36 @@
+// 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_WTF_WTF_SIZE_T_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_WTF_SIZE_T_H_
+
+#include <stdint.h>
+
+namespace WTF {
+// TLDR: size_t != wtf_size_t
+//
+// WTF defines wtf_size_t as an unsigned 32 bit integer. This is to align
+// with the maximum heap allocation object size and save memory. This deviates
+// from Chromium C++ style guide which calls for interfaces to use the
+// stdint.h types (aka. int32_t) on the exposed interface.
+//
+// Matching the external API to match the internal API have a number of
+// required properties:
+// - Internal storage for Vector and String are all uint32_t based
+// - Max heap allocation size is kMaxHeapObjectSize (much less than UINTMAX)
+// - static_casts from size_t to uint32_t are not good enough and checked_casts
+// would need to be used.
+// - checked_casts are too slow
+// - consumers of APIs such as WTF::Vector may store their indicies in some
+// other storage and using size_t consumes extra data.
+//
+// It may be possible in the future to move Vector and String to be size_t
+// based and this definition may not be necessary, so long as the internal
+// type matches the external type.
+using wtf_size_t = uint32_t;
+} // namespace WTF
+
+using WTF::wtf_size_t;
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_WTF_SIZE_T_H_
diff --git a/chromium/third_party/blink/renderer/platform/wtf/wtf_thread_data.cc b/chromium/third_party/blink/renderer/platform/wtf/wtf_thread_data.cc
index 1bd1b10327e..91bdf2e9caf 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/wtf_thread_data.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/wtf_thread_data.cc
@@ -28,7 +28,6 @@
#include "third_party/blink/renderer/platform/wtf/stack_util.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string_table.h"
-#include "third_party/blink/renderer/platform/wtf/text/movable_string.h"
#include "third_party/blink/renderer/platform/wtf/text/text_codec_icu.h"
namespace WTF {
@@ -37,7 +36,6 @@ ThreadSpecific<WTFThreadData>* WTFThreadData::static_data_;
WTFThreadData::WTFThreadData()
: atomic_string_table_(new AtomicStringTable),
- movable_string_table_(new MovableStringTable),
cached_converter_icu_(new ICUConverterWrapper),
thread_id_(internal::CurrentThreadSyscall()) {}
diff --git a/chromium/third_party/blink/renderer/platform/wtf/wtf_thread_data.h b/chromium/third_party/blink/renderer/platform/wtf/wtf_thread_data.h
index 84707d248c4..c45674e3df8 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/wtf_thread_data.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/wtf_thread_data.h
@@ -41,7 +41,6 @@
namespace WTF {
class AtomicStringTable;
-class MovableStringTable;
struct ICUConverterWrapper;
class WTF_EXPORT WTFThreadData {
@@ -53,8 +52,6 @@ class WTF_EXPORT WTFThreadData {
AtomicStringTable& GetAtomicStringTable() { return *atomic_string_table_; }
- MovableStringTable& GetMovableStringTable() { return *movable_string_table_; }
-
ICUConverterWrapper& CachedConverterICU() { return *cached_converter_icu_; }
ThreadIdentifier ThreadId() const { return thread_id_; }
@@ -68,7 +65,6 @@ class WTF_EXPORT WTFThreadData {
private:
std::unique_ptr<AtomicStringTable> atomic_string_table_;
- std::unique_ptr<MovableStringTable> movable_string_table_;
std::unique_ptr<ICUConverterWrapper> cached_converter_icu_;
ThreadIdentifier thread_id_;
diff --git a/chromium/third_party/blink/tools/apache_config/mime.types b/chromium/third_party/blink/tools/apache_config/mime.types
index 6934e1bef2f..63794889639 100644
--- a/chromium/third_party/blink/tools/apache_config/mime.types
+++ b/chromium/third_party/blink/tools/apache_config/mime.types
@@ -84,7 +84,7 @@ application/set-registration-initiation
application/sgml
application/sgml-open-catalog
application/sieve
-application/signed-exchange;v=b1 sxg
+application/signed-exchange;v=b2 sxg
application/slate
application/smil smi smil
application/srgs gram
diff --git a/chromium/third_party/blink/tools/audit_non_blink_usage.py b/chromium/third_party/blink/tools/audit_non_blink_usage.py
index 0b33cd740a1..1973977ca6d 100755
--- a/chromium/third_party/blink/tools/audit_non_blink_usage.py
+++ b/chromium/third_party/blink/tools/audit_non_blink_usage.py
@@ -28,11 +28,12 @@ _CONFIG = [
'gfx::CubicBezier',
'gfx::ICCProfile',
'gfx::RadToDeg',
- 'gfx::ScrollOffset',
# //base constructs that are allowed everywhere
'base::AdoptRef',
'base::AutoReset',
+ 'base::File',
+ 'base::FilePath',
'base::GetUniqueIdForProcess',
'base::Location',
'base::MakeRefCounted',
@@ -77,6 +78,12 @@ _CONFIG = [
# //base/memory/ptr_util.h.
'base::WrapUnique',
+ # //base/metrics/field_trial_params.h.
+ 'base::GetFieldTrialParamValueByFeature',
+ 'base::GetFieldTrialParamByFeatureAsBool',
+ 'base::GetFieldTrialParamByFeatureAsDouble',
+ 'base::GetFieldTrialParamByFeatureAsInt',
+
# //base/numerics/safe_conversions.h.
'base::as_signed',
'base::as_unsigned',
@@ -118,6 +125,13 @@ _CONFIG = [
# Base atomic utilities
'base::AtomicSequenceNumber',
+ # Task traits
+ 'base::TaskTraits',
+ 'base::MayBlock',
+ 'base::TaskPriority',
+ 'base::TaskShutdownBehavior',
+ 'base::WithBaseSyncPrimitives',
+
# Byte order
'base::ByteSwap',
'base::NetToHost(16|32|64)',
@@ -184,6 +198,12 @@ _CONFIG = [
'cc::EventListenerClass',
'cc::EventListenerProperties',
+ # Scrolling
+ 'cc::ScrollOffsetAnimationCurve',
+ 'cc::ScrollStateData',
+ 'gfx::RectToSkRect',
+ 'gfx::ScrollOffset',
+
# Standalone utility libraries that only depend on //base
'skia::.+',
'url::.+',
@@ -240,9 +260,6 @@ _CONFIG = [
# Blink uses UKM for logging e.g. always-on leak detection (crbug/757374)
'ukm::.+',
-
- # WebRTC classes
- 'webrtc::.+',
],
'disallowed': ['.+'],
},
@@ -269,6 +286,13 @@ _CONFIG = [
],
},
{
+ 'paths': ['third_party/blink/renderer/core/fetch/data_consumer_handle_test_util.cc'],
+ 'allowed': [
+ # The existing code already contains gin::IsolateHolder.
+ 'gin::IsolateHolder',
+ ],
+ },
+ {
'paths': ['third_party/blink/renderer/core/paint'],
'allowed': [
# cc painting types.
@@ -289,6 +313,8 @@ _CONFIG = [
{
'paths': ['third_party/blink/renderer/core/inspector/inspector_memory_agent.cc'],
'allowed': [
+ 'base::ModuleCache',
+ 'base::PoissonAllocationSampler',
'base::SamplingHeapProfiler',
],
},
@@ -326,6 +352,16 @@ _CONFIG = [
},
{
'paths': [
+ 'third_party/blink/renderer/modules/webgpu/',
+ ],
+ # The WebGPU Blink module needs access to the WebGPU control
+ # command buffer interface.
+ 'allowed': [
+ 'gpu::webgpu::WebGPUInterface',
+ ],
+ },
+ {
+ 'paths': [
'third_party/blink/renderer/platform/',
],
# Suppress almost all checks on platform since code in this directory
@@ -374,6 +410,31 @@ _CONFIG = [
],
'allowed': ['crypto::.+'],
},
+ {
+ 'paths': [
+ 'third_party/blink/renderer/modules/peerconnection',
+ 'third_party/blink/renderer/bindings/modules/v8/serialization',
+ ],
+ 'allowed': [
+ 'cricket::.*',
+ 'rtc::.+',
+ 'webrtc::.+',
+ ]
+ },
+ {
+ 'paths': [
+ 'third_party/blink/renderer/modules/peerconnection/adapters/',
+ ],
+ # The code in adapters/ wraps WebRTC APIs using STL/WebRTC types only.
+ # Thus, the restriction that objects should only be created and
+ # destroyed on the same thread can be relaxed since no Blink types (like
+ # AtomicString or HeapVector) are used cross thread. These Blink types
+ # are converted to the STL/WebRTC counterparts in the parent directory.
+ 'allowed': [
+ 'base::OnTaskRunnerDeleter',
+ 'sigslot::.+',
+ ],
+ }
]
diff --git a/chromium/third_party/blink/tools/blinkpy/common/checkout/baseline_optimizer.py b/chromium/third_party/blink/tools/blinkpy/common/checkout/baseline_optimizer.py
index 16e97cf6652..cf2b8ca4863 100644
--- a/chromium/third_party/blink/tools/blinkpy/common/checkout/baseline_optimizer.py
+++ b/chromium/third_party/blink/tools/blinkpy/common/checkout/baseline_optimizer.py
@@ -34,8 +34,6 @@ from blinkpy.web_tests.models.testharness_results import is_all_pass_testharness
_log = logging.getLogger(__name__)
-ALL_PASS = '<PASS> testharness.js'
-
class BaselineOptimizer(object):
@@ -97,7 +95,7 @@ class BaselineOptimizer(object):
def write_by_directory(self, results_by_directory, writer, indent):
"""Logs results_by_directory in a pretty format."""
for path in sorted(results_by_directory):
- writer('%s%s: %s' % (indent, self._platform(path), results_by_directory[path][0:6]))
+ writer('%s%s: %s' % (indent, self._platform(path), results_by_directory[path]))
def read_results_by_directory(self, baseline_name):
"""Reads the baselines with the given file name in all directories.
@@ -113,7 +111,7 @@ class BaselineOptimizer(object):
for directory in directories:
path = self._join_directory(directory, baseline_name)
if self._filesystem.exists(path):
- results_by_directory[directory] = self._digest_result(path)
+ results_by_directory[directory] = ResultDigest(self._filesystem, path)
return results_by_directory
def _optimize_subtree(self, baseline_name):
@@ -263,7 +261,7 @@ class BaselineOptimizer(object):
# See if all the successors of the virtual root (i.e. all non-virtual
# platforms) have the same baseline as the virtual root. If so, the
# virtual root is redundant and can be safely removed.
- virtual_root_digest = self._digest_result(virtual_root_baseline_path)
+ virtual_root_digest = ResultDigest(self._filesystem, virtual_root_baseline_path)
# Read the base (non-virtual) results.
results_by_directory = self.read_results_by_directory(self._virtual_base(baseline_name))
@@ -284,7 +282,8 @@ class BaselineOptimizer(object):
# of the work done in _patch_virtual_subtree.
def unpatcher(virtual_baseline, non_virtual_fallback):
if self._filesystem.exists(virtual_baseline) and \
- self._digest_result(virtual_baseline) == self._digest_result(non_virtual_fallback):
+ (ResultDigest(self._filesystem, virtual_baseline) ==
+ ResultDigest(self._filesystem, non_virtual_fallback)):
_log.debug(' Deleting (file system): %s (redundant with %s).', virtual_baseline, non_virtual_fallback)
self._filesystem.remove(virtual_baseline)
self._walk_immediate_predecessors_of_virtual_root(test_name, extension, baseline_name, unpatcher)
@@ -342,7 +341,8 @@ class BaselineOptimizer(object):
results_by_port_name[port_name] = results_by_directory[directory]
break
if port_name not in results_by_port_name:
- results_by_port_name[port_name] = ALL_PASS
+ # Implicit all-PASS testharness.js result.
+ results_by_port_name[port_name] = ResultDigest(None, None)
return results_by_port_name
@memoized
@@ -441,7 +441,8 @@ class BaselineOptimizer(object):
# the implicit result.
# Note that we do not remove the generic all-PASS result here.
# Roots (virtual and non-virtual) are treated specially later.
- if (not found_different_result and current_result == ALL_PASS
+ if (not found_different_result
+ and current_result.is_all_pass_testharness_result
and current_directory != self._baseline_root()
and current_directory in new_results_by_directory):
del new_results_by_directory[current_directory]
@@ -453,7 +454,7 @@ class BaselineOptimizer(object):
for index, directory in enumerate(search_path):
if directory in results_by_directory and (results_by_directory[directory] == current_result):
return index, directory
- assert current_result == ALL_PASS, (
+ assert current_result.is_all_pass_testharness_result, (
'result %s not found in search path %s, %s' % (current_result, search_path, results_by_directory))
# Implicit all-PASS at the root.
return len(search_path) - 1, search_path[-1]
@@ -462,31 +463,64 @@ class BaselineOptimizer(object):
"""Removes the all-PASS testharness.js result at the non-virtual root."""
assert not self._virtual_base(baseline_name), 'A virtual baseline is passed in.'
path = self._join_directory(self._baseline_root(), baseline_name)
- if self._filesystem.exists(path) and self._is_all_pass_testharness_result(path):
+ if (self._filesystem.exists(path)
+ and ResultDigest.test_all_pass_testharness_result(self._filesystem, path)):
_log.debug('Deleting redundant all-PASS root baseline.')
_log.debug(' Deleting (file system): ' + path)
self._filesystem.remove(path)
- def _digest_result(self, path):
- """Digests a result file into a string suitable for comparison.
- Args:
- An absolute path.
+class ResultDigest(object):
+ """Digest of a result file for fast comparison.
- Returns:
- In most cases, the SHA1 sum of the content is returned, but if the
- file is an all-PASS testharness.js result, ALL_PASS is returned.
+ A result file can be any actual or expected output from a layout test,
+ including text and image. SHA1 is used internally to digest the file.
+ """
+
+ _ALL_PASS = '<PASS>'
+
+ def __init__(self, fs, path):
+ """Constructs the digest for a result.
+
+ Args:
+ fs: An instance of common.system.FileSystem.
+ path: The path to a result file. If None is provided, the result is
+ an *implicit* all-PASS testharness.js result.
"""
- # Unfortunately, we may read the file twice, once in text mode and once
- # in binary mode.
- if self._is_all_pass_testharness_result(path):
- return ALL_PASS
- return self._filesystem.sha1(path)
-
- def _is_all_pass_testharness_result(self, path):
- """Checks if a baseline is an all-PASS testharness.js result."""
+ self.path = path
+ if path is None:
+ # Implicit all-PASS result.
+ self.sha = self._ALL_PASS
+ self.is_all_pass_testharness_result = True
+ else:
+ # Unfortunately, we may read the file twice, once in text mode and
+ # once in binary mode.
+ self.sha = fs.sha1(path)
+ self.is_all_pass_testharness_result = self.test_all_pass_testharness_result(fs, path)
+
+ def __eq__(self, other):
+ if other is None:
+ return False
+ # Implicit all-PASS is equal to any all-PASS results.
+ if self.sha == self._ALL_PASS or other.sha == self._ALL_PASS:
+ return self.is_all_pass_testharness_result and other.is_all_pass_testharness_result
+ return self.sha == other.sha
+
+ # Python 2 does not automatically delegate __ne__ to not __eq__.
+ def __ne__(self, other):
+ return not self.__eq__(other)
+
+ def __str__(self):
+ return self.sha[0:6]
+
+ def __repr__(self):
+ all_pass = ' ALL_PASS' if self.is_all_pass_testharness_result else ''
+ return '<ResultDigest %s%s %s>' % (self.sha, all_pass, self.path)
+
+ @staticmethod
+ def test_all_pass_testharness_result(fs, path):
# TODO(robertma): Find an appropriate constant for this (or make one).
if not path.endswith('-expected.txt'):
return False
- content = self._filesystem.read_text_file(path)
+ content = fs.read_text_file(path)
return is_all_pass_testharness_result(content)
diff --git a/chromium/third_party/blink/tools/blinkpy/common/checkout/baseline_optimizer_unittest.py b/chromium/third_party/blink/tools/blinkpy/common/checkout/baseline_optimizer_unittest.py
index 80fa474ad32..0fad61cdd6a 100644
--- a/chromium/third_party/blink/tools/blinkpy/common/checkout/baseline_optimizer_unittest.py
+++ b/chromium/third_party/blink/tools/blinkpy/common/checkout/baseline_optimizer_unittest.py
@@ -28,7 +28,7 @@
import unittest
-from blinkpy.common.checkout.baseline_optimizer import BaselineOptimizer
+from blinkpy.common.checkout.baseline_optimizer import BaselineOptimizer, ResultDigest
from blinkpy.common.host_mock import MockHost
from blinkpy.common.system.filesystem_mock import MockFileSystem
from blinkpy.common.path_finder import PathFinder
@@ -39,6 +39,12 @@ PASS woohoo
Harness: the test ran to completion.
"""
+ALL_PASS_TESTHARNESS_RESULT2 = """This is a testharness.js-based test.
+PASS woohoo
+PASS yahoo
+Harness: the test ran to completion.
+"""
+
class BaselineOptimizerTest(unittest.TestCase):
@@ -328,6 +334,23 @@ class BaselineOptimizerTest(unittest.TestCase):
{'platform/linux/virtual/gpu/fast/canvas': None},
baseline_dirname='virtual/gpu/fast/canvas')
+ def test_all_pass_testharness_can_be_updated(self):
+ # https://crbug.com/866802
+ self._assert_optimization(
+ {
+ 'fast/canvas': 'failure',
+ 'virtual/gpu/fast/canvas': ALL_PASS_TESTHARNESS_RESULT,
+ 'platform/win/virtual/gpu/fast/canvas': ALL_PASS_TESTHARNESS_RESULT2,
+ 'platform/mac/virtual/gpu/fast/canvas': ALL_PASS_TESTHARNESS_RESULT2,
+ },
+ {
+ 'fast/canvas': 'failure',
+ 'virtual/gpu/fast/canvas': ALL_PASS_TESTHARNESS_RESULT2,
+ 'platform/win/virtual/gpu/fast/canvas': None,
+ 'platform/mac/virtual/gpu/fast/canvas': None,
+ },
+ baseline_dirname='virtual/gpu/fast/canvas')
+
def test_all_pass_testharness_falls_back_to_non_pass(self):
# The all-PASS baseline needs to be preserved in this case.
self._assert_optimization(
@@ -403,3 +426,37 @@ class BaselineOptimizerTest(unittest.TestCase):
self.fs.read_binary_file(
'/mock-checkout/third_party/WebKit/LayoutTests/another/test-expected.txt'),
'result A')
+
+
+class ResultDigestTest(unittest.TestCase):
+
+ def setUp(self):
+ self.host = MockHost()
+ self.fs = MockFileSystem()
+ self.host.filesystem = self.fs
+ self.fs.write_text_file('/all-pass/foo-expected.txt', ALL_PASS_TESTHARNESS_RESULT)
+ self.fs.write_text_file('/all-pass/bar-expected.txt', ALL_PASS_TESTHARNESS_RESULT2)
+ self.fs.write_text_file('/failures/baz-expected.txt', 'failure')
+
+ def test_test_all_pass_testharness_result(self):
+ self.assertTrue(ResultDigest.test_all_pass_testharness_result(
+ self.fs, '/all-pass/foo-expected.txt'))
+ self.assertTrue(ResultDigest.test_all_pass_testharness_result(
+ self.fs, '/all-pass/bar-expected.txt'))
+ self.assertFalse(ResultDigest.test_all_pass_testharness_result(
+ self.fs, '/failures/baz-expected.txt'))
+ self.assertFalse(ResultDigest.test_all_pass_testharness_result(
+ self.fs, '/others/something-expected.png'))
+
+ def test_implicit_all_pass(self):
+ # Implicit all-PASS should equal to any all-PASS but not failures.
+ implicit = ResultDigest(None, None)
+ self.assertTrue(implicit == ResultDigest(self.fs, '/all-pass/foo-expected.txt'))
+ self.assertTrue(implicit == ResultDigest(self.fs, '/all-pass/bar-expected.txt'))
+ self.assertFalse(implicit == ResultDigest(self.fs, '/failures/baz-expected.txt'))
+
+ def test_different_all_pass_results(self):
+ x = ResultDigest(self.fs, '/all-pass/foo-expected.txt')
+ y = ResultDigest(self.fs, '/all-pass/bar-expected.txt')
+ self.assertTrue(x != y)
+ self.assertFalse(x == y)
diff --git a/chromium/third_party/blink/tools/blinkpy/common/host_mock.py b/chromium/third_party/blink/tools/blinkpy/common/host_mock.py
index c386a172082..53eb27ffea2 100644
--- a/chromium/third_party/blink/tools/blinkpy/common/host_mock.py
+++ b/chromium/third_party/blink/tools/blinkpy/common/host_mock.py
@@ -122,4 +122,4 @@ class MockHost(MockSystemHost):
filesystem.maybe_make_directory(filesystem.join(external_dir, 'wpt'))
manifest_base_path = filesystem.join(external_dir, 'WPT_BASE_MANIFEST.json')
- filesystem.files[manifest_base_path] = '{}'
+ filesystem.files[manifest_base_path] = '{"manifest": "base"}'
diff --git a/chromium/third_party/blink/tools/blinkpy/common/net/git_cl.py b/chromium/third_party/blink/tools/blinkpy/common/net/git_cl.py
index 887a4cecf57..6fe7faae7c0 100644
--- a/chromium/third_party/blink/tools/blinkpy/common/net/git_cl.py
+++ b/chromium/third_party/blink/tools/blinkpy/common/net/git_cl.py
@@ -87,7 +87,15 @@ class GitCL(object):
return builders_by_bucket
def get_issue_number(self):
- return self.run(['issue']).split()[2]
+ """Returns the issue number as a string, or "None"."""
+ # Expected output of git cl issue looks like:
+ # "<Optional message> Issue number: 1234 (<url>)".
+ # Note: git cl gets the number from local git config, e.g.
+ # by running `git config branch.<branchname>.gerritissue`.
+ output = self.run(['issue']).split()
+ if 'number:' in output:
+ return output[output.index('number:') + 1]
+ return 'None'
def _get_cl_status(self):
return self.run(['status', '--field=status']).strip()
diff --git a/chromium/third_party/blink/tools/blinkpy/common/net/git_cl_unittest.py b/chromium/third_party/blink/tools/blinkpy/common/net/git_cl_unittest.py
index 96a0fda9448..e47ef921fb2 100644
--- a/chromium/third_party/blink/tools/blinkpy/common/net/git_cl_unittest.py
+++ b/chromium/third_party/blink/tools/blinkpy/common/net/git_cl_unittest.py
@@ -121,7 +121,7 @@ class GitCLTest(unittest.TestCase):
def test_get_issue_number(self):
host = MockHost()
- host.executive = MockExecutive(output='Issue number: 12345 (http://crrev.com/12345)')
+ host.executive = MockExecutive(output='Foo\nIssue number: 12345 (http://crrev.com/12345)')
git_cl = GitCL(host)
self.assertEqual(git_cl.get_issue_number(), '12345')
@@ -131,6 +131,12 @@ class GitCLTest(unittest.TestCase):
git_cl = GitCL(host)
self.assertEqual(git_cl.get_issue_number(), 'None')
+ def test_get_issue_number_nothing_in_output(self):
+ host = MockHost()
+ host.executive = MockExecutive(output='Bogus output')
+ git_cl = GitCL(host)
+ self.assertEqual(git_cl.get_issue_number(), 'None')
+
def test_wait_for_try_jobs_timeout(self):
host = MockHost()
git_cl = GitCL(host)
diff --git a/chromium/third_party/blink/tools/blinkpy/common/net/layout_test_results.py b/chromium/third_party/blink/tools/blinkpy/common/net/layout_test_results.py
index 25f79b0812d..b3e6bd78869 100644
--- a/chromium/third_party/blink/tools/blinkpy/common/net/layout_test_results.py
+++ b/chromium/third_party/blink/tools/blinkpy/common/net/layout_test_results.py
@@ -68,12 +68,14 @@ class LayoutTestResult(object):
def expected_results(self):
return self._result_dict['expected']
+ def last_retry_result(self):
+ return self.actual_results().split()[-1]
+
def has_mismatch_result(self):
- last_retry_result = self.actual_results().split()[-1]
- return last_retry_result in ('TEXT', 'IMAGE', 'IMAGE+TEXT', 'AUDIO')
+ return self.last_retry_result() in ('TEXT', 'IMAGE', 'IMAGE+TEXT', 'AUDIO')
def is_missing_baseline(self):
- return self._result_dict['actual'] == 'MISSING'
+ return self.last_retry_result() == 'MISSING'
# FIXME: This should be unified with ResultsSummary or other NRWT layout tests code
diff --git a/chromium/third_party/blink/tools/blinkpy/tool/blink_tool.py b/chromium/third_party/blink/tools/blinkpy/tool/blink_tool.py
index 4ce694bb046..821990c7047 100644
--- a/chromium/third_party/blink/tools/blinkpy/tool/blink_tool.py
+++ b/chromium/third_party/blink/tools/blinkpy/tool/blink_tool.py
@@ -49,7 +49,6 @@ from blinkpy.tool.commands.queries import CrashLog
from blinkpy.tool.commands.queries import PrintBaselines
from blinkpy.tool.commands.queries import PrintExpectations
from blinkpy.tool.commands.rebaseline import Rebaseline
-from blinkpy.tool.commands.rebaseline import RebaselineExpectations
from blinkpy.tool.commands.rebaseline_cl import RebaselineCL
from blinkpy.tool.commands.rebaseline_test import RebaselineTest
@@ -84,7 +83,6 @@ class BlinkTool(Host):
PrintExpectations(),
Rebaseline(),
RebaselineCL(),
- RebaselineExpectations(),
RebaselineTest(),
]
self.help_command = HelpCommand(tool=self)
diff --git a/chromium/third_party/blink/tools/blinkpy/tool/commands/rebaseline.py b/chromium/third_party/blink/tools/blinkpy/tool/commands/rebaseline.py
index de9dede7067..00547b94073 100644
--- a/chromium/third_party/blink/tools/blinkpy/tool/commands/rebaseline.py
+++ b/chromium/third_party/blink/tools/blinkpy/tool/commands/rebaseline.py
@@ -509,53 +509,6 @@ class AbstractParallelRebaselineCommand(AbstractRebaseliningCommand):
return test_result
-class RebaselineExpectations(AbstractParallelRebaselineCommand):
- name = 'rebaseline-expectations'
- help_text = 'Rebaselines the tests indicated in TestExpectations.'
- show_in_main_help = True
-
- def __init__(self):
- super(RebaselineExpectations, self).__init__(options=[
- self.no_optimize_option,
- ] + self.platform_options)
- self._test_baseline_set = None
-
- @staticmethod
- def _tests_to_rebaseline(port):
- tests_to_rebaseline = []
- for path, value in port.expectations_dict().items():
- expectations = TestExpectations(port, include_overrides=False, expectations_dict={path: value})
- for test in expectations.get_rebaselining_failures():
- tests_to_rebaseline.append(test)
- return tests_to_rebaseline
-
- def _add_tests_to_rebaseline(self, port_name):
- builder_name = self._tool.builders.builder_name_for_port_name(port_name)
- if not builder_name:
- return
- tests = self._tests_to_rebaseline(self._tool.port_factory.get(port_name))
-
- if tests:
- _log.info('Retrieving results for %s from %s.', port_name, builder_name)
-
- for test_name in tests:
- _log.info(' %s', test_name)
- self._test_baseline_set.add(test_name, Build(builder_name))
-
- def execute(self, options, args, tool):
- self._tool = tool
- self._test_baseline_set = TestBaselineSet(tool)
- options.results_directory = None
- port_names = tool.port_factory.all_port_names(options.platform)
- for port_name in port_names:
- self._add_tests_to_rebaseline(port_name)
- if not self._test_baseline_set:
- _log.warning('Did not find any tests marked Rebaseline.')
- return
-
- self.rebaseline(options, self._test_baseline_set)
-
-
class Rebaseline(AbstractParallelRebaselineCommand):
name = 'rebaseline'
help_text = 'Rebaseline tests with results from the continuous builders.'
diff --git a/chromium/third_party/blink/tools/blinkpy/tool/commands/rebaseline_unittest.py b/chromium/third_party/blink/tools/blinkpy/tool/commands/rebaseline_unittest.py
index eee4e15974f..be4b1fc6dec 100644
--- a/chromium/third_party/blink/tools/blinkpy/tool/commands/rebaseline_unittest.py
+++ b/chromium/third_party/blink/tools/blinkpy/tool/commands/rebaseline_unittest.py
@@ -10,8 +10,7 @@ from blinkpy.common.net.buildbot import Build
from blinkpy.common.net.layout_test_results import LayoutTestResults
from blinkpy.common.system.executive_mock import MockExecutive
from blinkpy.tool.commands.rebaseline import (
- AbstractParallelRebaselineCommand, Rebaseline, RebaselineExpectations,
- TestBaselineSet
+ AbstractParallelRebaselineCommand, Rebaseline, TestBaselineSet
)
from blinkpy.tool.mock_tool import MockBlinkTool
from blinkpy.web_tests.builder_list import BuilderList
@@ -688,291 +687,6 @@ class TestRebaselineExecute(BaseTestCase):
])
-class TestRebaselineExpectations(BaseTestCase):
- """Tests for the blink_tool.py rebaseline-expectations command."""
-
- command_constructor = RebaselineExpectations
-
- def setUp(self):
- super(TestRebaselineExpectations, self).setUp()
- self.tool.executive = MockExecutive()
- self._zero_out_test_expectations()
-
- @staticmethod
- def options():
- return optparse.Values({
- 'optimize': False,
- 'builders': None,
- 'suffixes': ['txt'],
- 'verbose': False,
- 'platform': None,
- 'results_directory': None
- })
-
- def test_rebaseline_expectations(self):
- for builder in ['MOCK Mac10.10', 'MOCK Mac10.11']:
- self.tool.buildbot.set_results(Build(builder), LayoutTestResults({
- 'tests': {
- 'userscripts': {
- 'another-test.html': {
- 'expected': 'PASS',
- 'actual': 'PASS TEXT'
- },
- 'images.svg': {
- 'expected': 'FAIL',
- 'actual': 'IMAGE+TEXT'
- }
- }
- }
- }))
-
- self._write('userscripts/another-test.html', 'Dummy test contents')
- self._write('userscripts/images.svg', 'Dummy test contents')
- self.command._tests_to_rebaseline = lambda port: {
- 'userscripts/another-test.html',
- 'userscripts/images.svg',
- 'userscripts/not-actually-failing.html',
- }
-
- self.command.execute(self.options(), [], self.tool)
-
- self.assertEqual(self.tool.executive.calls, [
- [
- [
- 'python', 'echo', 'copy-existing-baselines-internal',
- '--test', 'userscripts/another-test.html',
- '--suffixes', 'txt',
- '--port-name', 'test-mac-mac10.10',
- ],
- [
- 'python', 'echo', 'copy-existing-baselines-internal',
- '--test', 'userscripts/another-test.html',
- '--suffixes', 'txt',
- '--port-name', 'test-mac-mac10.11',
- ],
- [
- 'python', 'echo', 'copy-existing-baselines-internal',
- '--test', 'userscripts/images.svg',
- '--suffixes', 'txt,png',
- '--port-name', 'test-mac-mac10.10',
- ],
- [
- 'python', 'echo', 'copy-existing-baselines-internal',
- '--test', 'userscripts/images.svg',
- '--suffixes', 'txt,png',
- '--port-name', 'test-mac-mac10.11',
- ],
- ],
- [
- [
- 'python', 'echo', 'rebaseline-test-internal',
- '--test', 'userscripts/another-test.html',
- '--suffixes', 'txt',
- '--port-name', 'test-mac-mac10.10',
- '--builder', 'MOCK Mac10.10',
- ],
- [
- 'python', 'echo', 'rebaseline-test-internal',
- '--test', 'userscripts/another-test.html',
- '--suffixes', 'txt',
- '--port-name', 'test-mac-mac10.11',
- '--builder', 'MOCK Mac10.11',
- ],
- [
- 'python', 'echo', 'rebaseline-test-internal',
- '--test', 'userscripts/images.svg',
- '--suffixes', 'txt,png',
- '--port-name', 'test-mac-mac10.10',
- '--builder', 'MOCK Mac10.10',
- ],
- [
- 'python', 'echo', 'rebaseline-test-internal',
- '--test', 'userscripts/images.svg',
- '--suffixes', 'txt,png',
- '--port-name', 'test-mac-mac10.11',
- '--builder', 'MOCK Mac10.11',
- ],
- ],
- ])
-
- def test_rebaseline_expectations_reftests(self):
- for builder in ['MOCK Mac10.10', 'MOCK Mac10.11']:
- self.tool.buildbot.set_results(Build(builder), LayoutTestResults({
- 'tests': {
- 'userscripts': {
- 'reftest-text.html': {
- 'expected': 'PASS',
- 'actual': 'TEXT'
- },
- 'reftest-image.html': {
- 'expected': 'FAIL',
- 'actual': 'IMAGE'
- },
- 'reftest-image-text.html': {
- 'expected': 'FAIL',
- 'actual': 'IMAGE+TEXT'
- }
- }
- }
- }))
-
- self._write('userscripts/reftest-text.html', 'Dummy test contents')
- self._write('userscripts/reftest-text-expected.html', 'Dummy test contents')
- self._write('userscripts/reftest-text-expected.html', 'Dummy test contents')
- self.command._tests_to_rebaseline = lambda port: {
- 'userscripts/reftest-text.html': set(['txt']),
- 'userscripts/reftest-image.html': set(['png']),
- 'userscripts/reftest-image-text.html': set(['png', 'txt']),
- }
-
- self.command.execute(self.options(), [], self.tool)
-
- self.assertEqual(self.tool.executive.calls, [
- [
- [
- 'python', 'echo', 'copy-existing-baselines-internal',
- '--test', 'userscripts/reftest-text.html',
- '--suffixes', 'txt',
- '--port-name', 'test-mac-mac10.10',
- ],
- [
- 'python', 'echo', 'copy-existing-baselines-internal',
- '--test', 'userscripts/reftest-text.html',
- '--suffixes', 'txt',
- '--port-name', 'test-mac-mac10.11',
- ],
- ],
- [
- [
- 'python', 'echo', 'rebaseline-test-internal',
- '--test', 'userscripts/reftest-text.html',
- '--suffixes', 'txt',
- '--port-name', 'test-mac-mac10.10',
- '--builder', 'MOCK Mac10.10',
- ],
- [
- 'python', 'echo', 'rebaseline-test-internal',
- '--test', 'userscripts/reftest-text.html',
- '--suffixes', 'txt',
- '--port-name', 'test-mac-mac10.11',
- '--builder', 'MOCK Mac10.11',
- ],
- ],
- ])
-
- def test_rebaseline_expectations_noop(self):
- self.command.execute(self.options(), [], self.tool)
- self.assertEqual(self.tool.filesystem.written_files, {})
-
- def disabled_test_overrides_are_included_correctly(self):
- # TODO(qyearsley): Fix or remove this test method.
- # This tests that any tests marked as REBASELINE in the overrides are found, but
- # that the overrides do not get written into the main file.
-
- self._write(self.test_expectations_path, '')
- self.mac_port.expectations_dict = lambda: {
- self.test_expectations_path: '',
- 'overrides': ('Bug(x) userscripts/another-test.html [ Failure Rebaseline ]\n'
- 'Bug(y) userscripts/test.html [ Crash ]\n')}
- self._write('/userscripts/another-test.html', '')
-
- self.assertDictEqual(self.command._tests_to_rebaseline(self.mac_port),
- {'userscripts/another-test.html': set(['png', 'txt', 'wav'])})
- self.assertEqual(self._read(self.test_expectations_path), '')
-
- def test_rebaseline_without_other_expectations(self):
- self._write('userscripts/another-test.html', 'Dummy test contents')
- self._write(self.test_expectations_path, 'Bug(x) userscripts/another-test.html [ Rebaseline ]\n')
- self.assertEqual(self.command._tests_to_rebaseline(self.mac_port), ['userscripts/another-test.html'])
-
- def test_rebaseline_missing(self):
- self.tool.buildbot.set_results(Build('MOCK Mac10.10'), LayoutTestResults({
- 'tests': {
- 'fast': {
- 'dom': {
- 'missing-text.html': {
- 'expected': 'PASS',
- 'actual': 'MISSING',
- 'is_unexpected': True,
- 'is_missing_text': True
- },
- 'missing-text-and-image.html': {
- 'expected': 'PASS',
- 'actual': 'MISSING',
- 'is_unexpected': True,
- 'is_missing_text': True,
- 'is_missing_image': True
- },
- 'missing-image.html': {
- 'expected': 'PASS',
- 'actual': 'MISSING',
- 'is_unexpected': True,
- 'is_missing_image': True
- }
- }
- }
- }
- }))
-
- self._write('fast/dom/missing-text.html', 'Dummy test contents')
- self._write('fast/dom/missing-text-and-image.html', 'Dummy test contents')
- self._write('fast/dom/missing-image.html', 'Dummy test contents')
-
- self.command._tests_to_rebaseline = lambda port: {
- 'fast/dom/missing-text.html': set(['txt', 'png']),
- 'fast/dom/missing-text-and-image.html': set(['txt', 'png']),
- 'fast/dom/missing-image.html': set(['txt', 'png']),
- }
-
- self.command.execute(self.options(), [], self.tool)
-
- self.assertEqual(self.tool.executive.calls, [
- [
- [
- 'python', 'echo', 'copy-existing-baselines-internal',
- '--test', 'fast/dom/missing-text.html',
- '--suffixes', 'txt',
- '--port-name', 'test-mac-mac10.10',
- ],
- [
- 'python', 'echo', 'copy-existing-baselines-internal',
- '--test', 'fast/dom/missing-text-and-image.html',
- '--suffixes', 'txt,png',
- '--port-name', 'test-mac-mac10.10',
- ],
- [
- 'python', 'echo', 'copy-existing-baselines-internal',
- '--test', 'fast/dom/missing-image.html',
- '--suffixes', 'png',
- '--port-name', 'test-mac-mac10.10',
- ],
- ],
- [
- [
- 'python', 'echo', 'rebaseline-test-internal',
- '--test', 'fast/dom/missing-text.html',
- '--suffixes', 'txt',
- '--port-name', 'test-mac-mac10.10',
- '--builder', 'MOCK Mac10.10',
- ],
- [
- 'python', 'echo', 'rebaseline-test-internal',
- '--test', 'fast/dom/missing-text-and-image.html',
- '--suffixes', 'txt,png',
- '--port-name', 'test-mac-mac10.10',
- '--builder', 'MOCK Mac10.10',
- ],
- [
- 'python', 'echo', 'rebaseline-test-internal',
- '--test', 'fast/dom/missing-image.html',
- '--suffixes', 'png',
- '--port-name', 'test-mac-mac10.10',
- '--builder', 'MOCK Mac10.10',
- ],
- ]
- ])
-
-
class TestBaselineSetTest(unittest.TestCase):
def setUp(self):
diff --git a/chromium/third_party/blink/tools/blinkpy/w3c/chromium_exportable_commits.py b/chromium/third_party/blink/tools/blinkpy/w3c/chromium_exportable_commits.py
index 9417f6f1183..2e3665f39bb 100644
--- a/chromium/third_party/blink/tools/blinkpy/w3c/chromium_exportable_commits.py
+++ b/chromium/third_party/blink/tools/blinkpy/w3c/chromium_exportable_commits.py
@@ -100,7 +100,7 @@ def get_commit_export_state(chromium_commit, local_wpt, wpt_github, verify_merge
apply (i.e. state=CommitExportState.EXPORTABLE_DIRTY).
"""
message = chromium_commit.message()
- if 'NOEXPORT=true' in message or 'No-Export: true' in message or message.startswith('Import'):
+ if 'NOEXPORT=true' in message or 'No-Export: true' in message:
return CommitExportState.IGNORED, ''
patch = chromium_commit.format_patch()
diff --git a/chromium/third_party/blink/tools/blinkpy/w3c/chromium_exportable_commits_unittest.py b/chromium/third_party/blink/tools/blinkpy/w3c/chromium_exportable_commits_unittest.py
index d81432e1fe6..af84a4a05ec 100644
--- a/chromium/third_party/blink/tools/blinkpy/w3c/chromium_exportable_commits_unittest.py
+++ b/chromium/third_party/blink/tools/blinkpy/w3c/chromium_exportable_commits_unittest.py
@@ -115,10 +115,13 @@ class ChromiumExportableCommitsTest(unittest.TestCase):
old_revert = MockChromiumCommit(MockHost(), body='Revert of Message\n> NOEXPORT=true')
self.assertEqual(get_commit_export_state(old_revert, MockLocalWPT(), github), (CommitExportState.IGNORED, ''))
- def test_commit_that_starts_with_import_is_not_exportable(self):
+ # "Import" in commit message doesn't by itself make a commit exportable,
+ # see https://crbug.com/879128.
+ def test_commit_that_starts_with_import_is_exportable(self):
commit = MockChromiumCommit(MockHost(), subject='Import message')
github = MockWPTGitHub(pull_requests=[])
- self.assertEqual(get_commit_export_state(commit, MockLocalWPT(), github), (CommitExportState.IGNORED, ''))
+ self.assertEqual(get_commit_export_state(commit, MockLocalWPT(test_patch=[(True, '')]), github),
+ (CommitExportState.EXPORTABLE_CLEAN, ''))
def test_commit_that_has_open_pr_is_exportable(self):
commit = MockChromiumCommit(MockHost(), change_id='I00decade')
diff --git a/chromium/third_party/blink/tools/blinkpy/w3c/gerrit.py b/chromium/third_party/blink/tools/blinkpy/w3c/gerrit.py
index bb00fc740a7..c50098c9bbc 100644
--- a/chromium/third_party/blink/tools/blinkpy/w3c/gerrit.py
+++ b/chromium/third_party/blink/tools/blinkpy/w3c/gerrit.py
@@ -130,12 +130,6 @@ class GerritCL(object):
_log.info('Rejecting CL with over 1000 files: %s (ID: %s) ', self.subject, self.change_id)
return False
- if self.subject.startswith('Import wpt@'):
- return False
-
- if 'Import' in self.subject:
- return False
-
if 'No-Export: true' in self.current_revision['commit_with_footers']:
return False
diff --git a/chromium/third_party/blink/tools/blinkpy/w3c/gerrit_unittest.py b/chromium/third_party/blink/tools/blinkpy/w3c/gerrit_unittest.py
index 67bdc31034d..a771d09e373 100644
--- a/chromium/third_party/blink/tools/blinkpy/w3c/gerrit_unittest.py
+++ b/chromium/third_party/blink/tools/blinkpy/w3c/gerrit_unittest.py
@@ -60,3 +60,88 @@ class GerritCLTest(unittest.TestCase):
gerrit_cl = GerritCL(data, MockGerritAPI())
# It's important that this does not throw!
self.assertFalse(gerrit_cl.is_exportable())
+
+ def test_wpt_cl_is_exportable(self):
+ data = {
+ 'change_id': 'Ib58c7125d85d2fd71af711ea8bbd2dc927ed02cb',
+ 'subject': 'fake subject',
+ '_number': 638250,
+ 'current_revision': '1',
+ 'revisions': {'1': {
+ 'commit_with_footers': 'fake subject',
+ 'files': {
+ 'third_party/WebKit/LayoutTests/external/wpt/foo/bar.html': '',
+ }
+ }},
+ 'owner': {'email': 'test@chromium.org'},
+ }
+ gerrit_cl = GerritCL(data, MockGerritAPI())
+ self.assertTrue(gerrit_cl.is_exportable())
+
+ def test_no_wpt_cl_is_not_exportable(self):
+ data = {
+ 'change_id': 'Ib58c7125d85d2fd71af711ea8bbd2dc927ed02cb',
+ 'subject': 'fake subject',
+ '_number': 638250,
+ 'current_revision': '1',
+ 'revisions': {'1': {
+ 'commit_with_footers': 'fake subject',
+ 'files': {
+ 'third_party/WebKit/LayoutTests/foo/bar.html': '',
+ }
+ }},
+ 'owner': {'email': 'test@chromium.org'},
+ }
+ gerrit_cl = GerritCL(data, MockGerritAPI())
+ self.assertFalse(gerrit_cl.is_exportable())
+
+ def test_no_export_is_not_exportable(self):
+ data = {
+ 'change_id': 'Ib58c7125d85d2fd71af711ea8bbd2dc927ed02cb',
+ 'subject': 'fake subject',
+ '_number': 638250,
+ 'current_revision': '1',
+ 'revisions': {'1': {
+ 'commit_with_footers': 'fake subject\nNo-Export: true',
+ 'files': {
+ 'third_party/WebKit/LayoutTests/external/wpt/foo/bar.html': '',
+ }
+ }},
+ 'owner': {'email': 'test@chromium.org'},
+ }
+ gerrit_cl = GerritCL(data, MockGerritAPI())
+ self.assertFalse(gerrit_cl.is_exportable())
+
+ def test_legacy_noexport_is_not_exportable(self):
+ data = {
+ 'change_id': 'Ib58c7125d85d2fd71af711ea8bbd2dc927ed02cb',
+ 'subject': 'fake subject',
+ '_number': 638250,
+ 'current_revision': '1',
+ 'revisions': {'1': {
+ 'commit_with_footers': 'fake subject\nNOEXPORT=true',
+ 'files': {
+ 'third_party/WebKit/LayoutTests/external/wpt/foo/bar.html': '',
+ }
+ }},
+ 'owner': {'email': 'test@chromium.org'},
+ }
+ gerrit_cl = GerritCL(data, MockGerritAPI())
+ self.assertFalse(gerrit_cl.is_exportable())
+
+ def test_import_in_subject_is_exportable(self):
+ data = {
+ 'change_id': 'Ib58c7125d85d2fd71af711ea8bbd2dc927ed02cb',
+ 'subject': 'Import something',
+ '_number': 638250,
+ 'current_revision': '1',
+ 'revisions': {'1': {
+ 'commit_with_footers': 'fake subject',
+ 'files': {
+ 'third_party/WebKit/LayoutTests/external/wpt/foo/bar.html': '',
+ }
+ }},
+ 'owner': {'email': 'test@chromium.org'},
+ }
+ gerrit_cl = GerritCL(data, MockGerritAPI())
+ self.assertTrue(gerrit_cl.is_exportable())
diff --git a/chromium/third_party/blink/tools/blinkpy/w3c/import_notifier.py b/chromium/third_party/blink/tools/blinkpy/w3c/import_notifier.py
index dc722c04a08..92f32ff37ff 100644
--- a/chromium/third_party/blink/tools/blinkpy/w3c/import_notifier.py
+++ b/chromium/third_party/blink/tools/blinkpy/w3c/import_notifier.py
@@ -190,7 +190,7 @@ class ImportNotifier(object):
description = prologue + failure_list + epilogue + commit_list
bug = MonorailIssue.new_chromium_issue(summary, description, cc, components)
- _log.info(str(bug))
+ _log.info(unicode(bug))
if is_wpt_notify_enabled:
_log.info("WPT-NOTIFY enabled in this directory; adding the bug to the pending list.")
diff --git a/chromium/third_party/blink/tools/blinkpy/w3c/monorail.py b/chromium/third_party/blink/tools/blinkpy/w3c/monorail.py
index a36a8c01066..e6536eeeaa3 100644
--- a/chromium/third_party/blink/tools/blinkpy/w3c/monorail.py
+++ b/chromium/third_party/blink/tools/blinkpy/w3c/monorail.py
@@ -31,6 +31,7 @@ class MonorailIssue(object):
def _normalize(self):
# These requirements are based on trial and error. No docs were found.
assert self.project_id, 'project_id cannot be empty.'
+ self._body['projectId'] = self.project_id
for field in self._STRING_LIST_FIELDS:
if field in self._body:
# Not a str or unicode.
@@ -42,18 +43,18 @@ class MonorailIssue(object):
assert self._body['status'] in self._VALID_STATUSES, 'Unknown status %s.' % self._body['status']
assert self._body['summary'], 'summary cannot be empty.'
- def __str__(self):
- result = ('Monorail issue in project {}\n'
+ def __unicode__(self):
+ result = (u'Monorail issue in project {}\n'
'Summary: {}\n'
'Status: {}\n').format(self.project_id, self.body['summary'], self.body['status'])
if 'cc' in self.body:
- result += 'CC: {}\n'.format(', '.join(self.body['cc']))
+ result += u'CC: {}\n'.format(', '.join(self.body['cc']))
if 'components' in self.body:
- result += 'Components: {}\n'.format(', '.join(self.body['components']))
+ result += u'Components: {}\n'.format(', '.join(self.body['components']))
if 'labels' in self.body:
- result += 'Labels: {}\n'.format(', '.join(self.body['labels']))
+ result += u'Labels: {}\n'.format(', '.join(self.body['labels']))
if 'description' in self.body:
- result += 'Description:\n{}\n'.format(self.body['description'])
+ result += u'Description:\n{}\n'.format(self.body['description'])
return result
@property
diff --git a/chromium/third_party/blink/tools/blinkpy/w3c/monorail_unittest.py b/chromium/third_party/blink/tools/blinkpy/w3c/monorail_unittest.py
index b492731a0f7..602727fe41f 100644
--- a/chromium/third_party/blink/tools/blinkpy/w3c/monorail_unittest.py
+++ b/chromium/third_party/blink/tools/blinkpy/w3c/monorail_unittest.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
# 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.
@@ -16,17 +17,23 @@ class MonorailIssueTest(unittest.TestCase):
MonorailIssue('chromium', summary='test', status='Untriaged', description='body',
cc=['foo@chromium.org'], labels=['Flaky'], components=['Infra'])
- def test_str(self):
- issue = MonorailIssue('chromium', summary='test', status='Untriaged', description='body',
+ def test_init_fills_project_id(self):
+ issue = MonorailIssue('chromium', summary='test', status='Untriaged')
+ self.assertEqual(issue.body['projectId'], 'chromium')
+
+ def test_unicode(self):
+ issue = MonorailIssue('chromium', summary=u'test', status='Untriaged',
+ description=u'ABC~‾¥≈¤・・•∙·☼★星🌟星★☼·∙•・・¤≈¥‾~XYZ',
cc=['foo@chromium.org', 'bar@chromium.org'], labels=['Flaky'], components=['Infra'])
- self.assertEqual(str(issue),
- ('Monorail issue in project chromium\n'
- 'Summary: test\n'
- 'Status: Untriaged\n'
- 'CC: foo@chromium.org, bar@chromium.org\n'
- 'Components: Infra\n'
- 'Labels: Flaky\n'
- 'Description:\nbody\n'))
+ self.assertEqual(type(unicode(issue)), unicode)
+ self.assertEqual(unicode(issue),
+ (u'Monorail issue in project chromium\n'
+ u'Summary: test\n'
+ u'Status: Untriaged\n'
+ u'CC: foo@chromium.org, bar@chromium.org\n'
+ u'Components: Infra\n'
+ u'Labels: Flaky\n'
+ u'Description:\nABC~‾¥≈¤・・•∙·☼★星🌟星★☼·∙•・・¤≈¥‾~XYZ\n'))
def test_init_unknown_fields(self):
with self.assertRaises(AssertionError):
diff --git a/chromium/third_party/blink/tools/blinkpy/w3c/test_importer.py b/chromium/third_party/blink/tools/blinkpy/w3c/test_importer.py
index 04805ee7515..90cc6e38080 100644
--- a/chromium/third_party/blink/tools/blinkpy/w3c/test_importer.py
+++ b/chromium/third_party/blink/tools/blinkpy/w3c/test_importer.py
@@ -503,6 +503,9 @@ class TestImporter(object):
if directory_owners:
description += self._format_directory_owners(directory_owners) + '\n\n'
+ # Prevent FindIt from auto-reverting import CLs.
+ description += 'NOAUTOREVERT=true\n'
+
# Move any No-Export tag to the end of the description.
description = description.replace('No-Export: true', '')
description = description.replace('\n\n\n\n', '\n\n')
diff --git a/chromium/third_party/blink/tools/blinkpy/w3c/test_importer_unittest.py b/chromium/third_party/blink/tools/blinkpy/w3c/test_importer_unittest.py
index b825383d023..ea073cda431 100644
--- a/chromium/third_party/blink/tools/blinkpy/w3c/test_importer_unittest.py
+++ b/chromium/third_party/blink/tools/blinkpy/w3c/test_importer_unittest.py
@@ -308,6 +308,7 @@ class TestImporterTest(LoggingTestCase):
'lines to TestExpectations rather than reverting. See:\n'
'https://chromium.googlesource.com'
'/chromium/src/+/master/docs/testing/web_platform_tests.md\n\n'
+ 'NOAUTOREVERT=true\n'
'No-Export: true')
self.assertEqual(host.executive.calls, [['git', 'log', '-1', '--format=%B']])
diff --git a/chromium/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater.py b/chromium/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater.py
index 49ce28fae9c..5f1dac68d8e 100644
--- a/chromium/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater.py
+++ b/chromium/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater.py
@@ -41,15 +41,19 @@ class WPTExpectationsUpdater(object):
self.finder = PathFinder(self.host.filesystem)
self.ports_with_no_results = set()
self.ports_with_all_pass = set()
+ self.patchset = None
def run(self, args=None):
parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument('--patchset', default=None,
+ help='Patchset number to fetch new baselines from.')
parser.add_argument('-v', '--verbose', action='store_true', help='More verbose logging.')
args = parser.parse_args(args)
log_level = logging.DEBUG if args.verbose else logging.INFO
configure_logging(logging_level=log_level, include_time=True)
+ self.patchset = args.patchset
self.update_expectations()
return 0
@@ -105,7 +109,7 @@ class WPTExpectationsUpdater(object):
def get_latest_try_jobs(self):
"""Returns the latest finished try jobs as Build objects."""
- return self.git_cl.latest_try_jobs(self._get_try_bots())
+ return self.git_cl.latest_try_jobs(self._get_try_bots(), patchset=self.patchset)
def get_failing_results_dict(self, build):
"""Returns a nested dict of failing test results.
@@ -255,21 +259,22 @@ class WPTExpectationsUpdater(object):
Returns:
A set of one or more test expectation strings with the first letter
- capitalized. Example: set(['Failure', 'Timeout']).
+ capitalized. Example: {'Failure', 'Timeout'}.
"""
+ actual_results = set(result.actual.split())
# If the result is MISSING, this implies that the test was not
# rebaselined and has an actual result but no baseline. We can't
# add a Missing expectation (this is not allowed), but no other
# expectation is correct.
# We also want to skip any new manual tests that are not automated;
# see crbug.com/708241 for context.
- if (result.actual == 'MISSING' or
- '-manual.' in test_name and result.actual == 'TIMEOUT'):
+ if ('MISSING' in actual_results or
+ '-manual.' in test_name and 'TIMEOUT' in actual_results):
return {'Skip'}
expectations = set()
- failure_types = ('TEXT', 'IMAGE+TEXT', 'IMAGE', 'AUDIO')
- other_types = ('TIMEOUT', 'CRASH', 'PASS')
- for actual in result.actual.split():
+ failure_types = {'TEXT', 'IMAGE+TEXT', 'IMAGE', 'AUDIO'}
+ other_types = {'TIMEOUT', 'CRASH', 'PASS'}
+ for actual in actual_results:
if actual in failure_types:
expectations.add('Failure')
if actual in other_types:
@@ -496,14 +501,18 @@ class WPTExpectationsUpdater(object):
_log.info(' %s', test)
blink_tool = self.finder.path_from_blink_tools('blink_tool.py')
- self.host.executive.run_command([
+ command = [
'python',
blink_tool,
'rebaseline-cl',
'--verbose',
'--no-trigger-jobs',
'--fill-missing',
- ] + tests_to_rebaseline)
+ ]
+ if self.patchset:
+ command.append('--patchset=' + str(self.patchset))
+ command += tests_to_rebaseline
+ self.host.executive.run_command(command)
return tests_to_rebaseline, test_results
def get_tests_to_rebaseline(self, test_results):
@@ -540,7 +549,7 @@ class WPTExpectationsUpdater(object):
"""
if self.is_reference_test(test_name):
return False
- if result.actual in ('CRASH', 'TIMEOUT', 'MISSING'):
+ if any(x in result.actual for x in ('CRASH', 'TIMEOUT', 'MISSING')):
return False
return True
diff --git a/chromium/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater_unittest.py b/chromium/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater_unittest.py
index 9c84aa69233..90c3733f4af 100644
--- a/chromium/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater_unittest.py
+++ b/chromium/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater_unittest.py
@@ -257,12 +257,21 @@ class WPTExpectationsUpdaterTest(LoggingTestCase):
updater.get_expectations(SimpleTestResult('FAIL', 'PASS', 'bug')),
{'Pass'})
self.assertEqual(
+ updater.get_expectations(SimpleTestResult('FAIL', 'PASS PASS', 'bug')),
+ {'Pass'})
+ self.assertEqual(
updater.get_expectations(SimpleTestResult('FAIL', 'TIMEOUT', 'bug')),
{'Timeout'})
self.assertEqual(
+ updater.get_expectations(SimpleTestResult('FAIL', 'TIMEOUT TIMEOUT', 'bug')),
+ {'Timeout'})
+ self.assertEqual(
updater.get_expectations(SimpleTestResult('TIMEOUT', 'PASS', 'bug')),
{'Pass'})
self.assertEqual(
+ updater.get_expectations(SimpleTestResult('TIMEOUT', 'PASS PASS', 'bug')),
+ {'Pass'})
+ self.assertEqual(
updater.get_expectations(SimpleTestResult('PASS', 'TEXT PASS', 'bug')),
{'Pass', 'Failure'})
self.assertEqual(
@@ -278,6 +287,9 @@ class WPTExpectationsUpdaterTest(LoggingTestCase):
updater.get_expectations(SimpleTestResult('Pass', 'MISSING', 'bug')),
{'Skip'})
self.assertEqual(
+ updater.get_expectations(SimpleTestResult('Pass', 'MISSING MISSING', 'bug')),
+ {'Skip'})
+ self.assertEqual(
updater.get_expectations(SimpleTestResult('Pass', 'TIMEOUT', 'bug'), test_name='foo/bar-manual.html'),
{'Skip'})
@@ -581,6 +593,26 @@ class WPTExpectationsUpdaterTest(LoggingTestCase):
# The original dict isn't modified.
self.assertEqual(results, results_copy)
+ def test_get_tests_to_rebaseline_handles_retries(self):
+ host = self.mock_host()
+ results = {
+ 'external/wpt/test/foo.html': {
+ 'bot': SimpleTestResult(expected='PASS', actual='TEXT TEXT', bug='bug'),
+ },
+ 'external/wpt/test/bar.html': {
+ 'bot': SimpleTestResult(expected='PASS', actual='TIMEOUT TIMEOUT', bug='bug'),
+ },
+ }
+ updater = WPTExpectationsUpdater(host)
+ tests_to_rebaseline, modified_test_results = updater.get_tests_to_rebaseline(results)
+ self.assertEqual(tests_to_rebaseline, ['external/wpt/test/foo.html'])
+ self.assertEqual(modified_test_results, {
+ 'external/wpt/test/foo.html': {},
+ 'external/wpt/test/bar.html': {
+ 'bot': SimpleTestResult(expected='PASS', actual='TIMEOUT TIMEOUT', bug='bug'),
+ },
+ })
+
def test_run_no_issue_number(self):
updater = WPTExpectationsUpdater(self.mock_host())
updater.git_cl = MockGitCL(updater.host, issue_number='None')
diff --git a/chromium/third_party/blink/tools/blinkpy/w3c/wpt_manifest.py b/chromium/third_party/blink/tools/blinkpy/w3c/wpt_manifest.py
index 594f4816a71..3361cbbd89f 100644
--- a/chromium/third_party/blink/tools/blinkpy/w3c/wpt_manifest.py
+++ b/chromium/third_party/blink/tools/blinkpy/w3c/wpt_manifest.py
@@ -88,6 +88,17 @@ class WPTManifest(object):
def _get_extras_from_item(item):
return item[-1]
+ @staticmethod
+ def _is_not_jsshell(item):
+ """Returns True if the manifest item isn't a jsshell test.
+
+ "jsshell" is one of the scopes automatically generated from .any.js
+ tests. It is intended to run in a thin JavaScript shell instead of a
+ full browser, so we simply ignore it in web tests. (crbug.com/871950)
+ """
+ extras = WPTManifest._get_extras_from_item(item)
+ return not extras.get('jsshell', False)
+
@memoized
def all_url_items(self):
"""Returns a dict mapping every URL in the manifest to its item."""
@@ -96,7 +107,7 @@ class WPTManifest(object):
return url_items
for test_type in self.test_types:
for records in self.raw_dict['items'][test_type].itervalues():
- for item in records:
+ for item in filter(self._is_not_jsshell, records):
url_items[self._get_url_from_item(item)] = item
return url_items
@@ -121,7 +132,8 @@ class WPTManifest(object):
manifest_items = self._items_for_file_path(path_in_wpt)
assert manifest_items is not None
# Remove the leading slashes when returning.
- return [self._get_url_from_item(item)[1:] for item in manifest_items]
+ return [self._get_url_from_item(item)[1:]
+ for item in manifest_items if self._is_not_jsshell(item)]
def is_slow_test(self, url):
"""Checks if a WPT is slow (long timeout) according to the manifest.
@@ -160,7 +172,7 @@ class WPTManifest(object):
@staticmethod
def ensure_manifest(host):
- """Generates the MANIFEST.json file if it does not exist."""
+ """Updates the MANIFEST.json file, or generates if it does not exist."""
finder = PathFinder(host.filesystem)
manifest_path = finder.path_from_layout_tests('external', 'wpt', 'MANIFEST.json')
base_manifest_path = finder.path_from_layout_tests('external', 'WPT_BASE_MANIFEST.json')
@@ -169,11 +181,15 @@ class WPTManifest(object):
_log.error('Manifest base not found at "%s".', base_manifest_path)
host.filesystem.write_text_file(base_manifest_path, '{}')
- if not host.filesystem.exists(manifest_path):
- _log.debug('Manifest not found, copying from base "%s".', base_manifest_path)
- host.filesystem.copyfile(base_manifest_path, manifest_path)
+ # Unconditionally replace MANIFEST.json with WPT_BASE_MANIFEST.json even
+ # if the former exists, to avoid regenerating the manifest from scratch
+ # when the manifest version changes. Remove the destination first as
+ # copyfile will fail if the two files are hardlinked or symlinked.
+ if host.filesystem.exists(manifest_path):
+ host.filesystem.remove(manifest_path)
+ host.filesystem.copyfile(base_manifest_path, manifest_path)
- wpt_path = manifest_path = finder.path_from_layout_tests('external', 'wpt')
+ wpt_path = finder.path_from_layout_tests('external', 'wpt')
WPTManifest.generate_manifest(host, wpt_path)
_log.debug('Manifest generation completed.')
diff --git a/chromium/third_party/blink/tools/blinkpy/w3c/wpt_manifest_unittest.py b/chromium/third_party/blink/tools/blinkpy/w3c/wpt_manifest_unittest.py
index 28a6362355c..927f449e6a5 100644
--- a/chromium/third_party/blink/tools/blinkpy/w3c/wpt_manifest_unittest.py
+++ b/chromium/third_party/blink/tools/blinkpy/w3c/wpt_manifest_unittest.py
@@ -19,6 +19,7 @@ class WPTManifestUnitTest(unittest.TestCase):
self.assertFalse(host.filesystem.exists(manifest_path))
WPTManifest.ensure_manifest(host)
self.assertTrue(host.filesystem.exists(manifest_path))
+ self.assertEqual(host.filesystem.written_files, {manifest_path: '{"manifest": "base"}'})
webkit_base = '/mock-checkout/third_party/WebKit'
self.assertEqual(
@@ -39,11 +40,12 @@ class WPTManifestUnitTest(unittest.TestCase):
host = MockHost()
manifest_path = '/mock-checkout/third_party/WebKit/LayoutTests/external/wpt/MANIFEST.json'
- host.filesystem.write_text_file(manifest_path, '{}')
- self.assertTrue(host.filesystem.exists(manifest_path))
+ host.filesystem.write_text_file(manifest_path, '{"manifest": "NOT base"}')
+ self.assertTrue(host.filesystem.exists(manifest_path))
WPTManifest.ensure_manifest(host)
self.assertTrue(host.filesystem.exists(manifest_path))
+ self.assertEqual(host.filesystem.written_files, {manifest_path: '{"manifest": "base"}'})
webkit_base = '/mock-checkout/third_party/WebKit'
self.assertEqual(
@@ -66,3 +68,43 @@ class WPTManifestUnitTest(unittest.TestCase):
with self.assertRaises(ScriptError):
WPTManifest.ensure_manifest(host)
+
+ def test_all_url_items_skips_jsshell_tests(self):
+ manifest_json = '''
+{
+ "items": {
+ "manual": {},
+ "reftest": {},
+ "testharness": {
+ "test.any.js": [
+ ["/test.any.html", {}],
+ ["/test.any.js", {"jsshell": true}]
+ ]
+ }
+ }
+}
+ '''
+ manifest = WPTManifest(manifest_json)
+ self.assertEqual(manifest.all_url_items(),
+ {u'/test.any.html': [u'/test.any.html', {}]})
+
+ def test_file_path_to_url_paths(self):
+ manifest_json = '''
+{
+ "items": {
+ "manual": {},
+ "reftest": {},
+ "testharness": {
+ "test.any.js": [
+ ["/test.any.html", {}],
+ ["/test.any.js", {"jsshell": true}]
+ ]
+ }
+ }
+}
+ '''
+ manifest = WPTManifest(manifest_json)
+ # Leading slashes should be stripped; and jsshell tests shouldn't be
+ # included.
+ self.assertEqual(manifest.file_path_to_url_paths('test.any.js'),
+ [u'test.any.html'])
diff --git a/chromium/third_party/blink/tools/blinkpy/web_tests/breakpad/dump_reader_multipart.py b/chromium/third_party/blink/tools/blinkpy/web_tests/breakpad/dump_reader_multipart.py
index e83025d3383..ee47da7635d 100644
--- a/chromium/third_party/blink/tools/blinkpy/web_tests/breakpad/dump_reader_multipart.py
+++ b/chromium/third_party/blink/tools/blinkpy/web_tests/breakpad/dump_reader_multipart.py
@@ -175,7 +175,7 @@ class DumpReaderLinux(DumpReaderMultipart):
"""Linux breakpad dump reader."""
def _binaries_to_symbolize(self):
- return ['content_shell', 'libosmesa.so']
+ return ['content_shell']
def _file_extension(self):
return 'dmp'
diff --git a/chromium/third_party/blink/tools/blinkpy/web_tests/controllers/layout_test_finder.py b/chromium/third_party/blink/tools/blinkpy/web_tests/controllers/layout_test_finder.py
index 165d2595aa4..df0a9bbab63 100644
--- a/chromium/third_party/blink/tools/blinkpy/web_tests/controllers/layout_test_finder.py
+++ b/chromium/third_party/blink/tools/blinkpy/web_tests/controllers/layout_test_finder.py
@@ -196,14 +196,20 @@ class LayoutTestFinder(object):
@staticmethod
def _split_into_chunks(test_names, index, count):
- chunk_size = int(math.ceil(len(test_names) * 1.0 / count))
-
- chunk_start = index * chunk_size
- chunk_end = (index + 1) * chunk_size
-
- tests_to_run = test_names[chunk_start:chunk_end]
- other_tests = test_names[:chunk_start] + test_names[chunk_end:]
-
- _log.debug('chunk slice [%d:%d] of %d is %d tests', chunk_start, chunk_end, len(test_names), len(tests_to_run))
+ tests_and_indices = [
+ (test_name, hash(test_name) % count)
+ for test_name in test_names]
+
+ tests_to_run = [
+ test_name
+ for test_name, test_index in tests_and_indices
+ if test_index == index]
+ other_tests = [
+ test_name
+ for test_name, test_index in tests_and_indices
+ if test_index != index]
+
+ _log.debug('chunk %d of %d contains %d tests of %d',
+ index, count, len(tests_to_run), len(test_names))
return tests_to_run, other_tests
diff --git a/chromium/third_party/blink/tools/blinkpy/web_tests/controllers/layout_test_finder_unittest.py b/chromium/third_party/blink/tools/blinkpy/web_tests/controllers/layout_test_finder_unittest.py
index a9a19ac5b7a..a3474ac48e5 100644
--- a/chromium/third_party/blink/tools/blinkpy/web_tests/controllers/layout_test_finder_unittest.py
+++ b/chromium/third_party/blink/tools/blinkpy/web_tests/controllers/layout_test_finder_unittest.py
@@ -2,11 +2,19 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import os
+import sys
import unittest
+from blinkpy.common import path_finder
from blinkpy.common.host_mock import MockHost
from blinkpy.web_tests.controllers import layout_test_finder
+_MOCK_ROOT = os.path.join(
+ path_finder.get_chromium_src_dir(), 'third_party', 'pymock')
+sys.path.append(_MOCK_ROOT)
+import mock
+
class LayoutTestFinderTests(unittest.TestCase):
@@ -89,32 +97,34 @@ class LayoutTestFinderTests(unittest.TestCase):
def test_split_chunks(self):
split = layout_test_finder.LayoutTestFinder._split_into_chunks # pylint: disable=protected-access
- tests = [1, 2, 3, 4]
- self.assertEqual(([1, 2, 3, 4], []), split(tests, 0, 1))
+ with mock.patch('__builtin__.hash', int):
+
+ tests = [1, 2, 3, 4]
+ self.assertEqual(([1, 2, 3, 4], []), split(tests, 0, 1))
- self.assertEqual(([1, 2], [3, 4]), split(tests, 0, 2))
- self.assertEqual(([3, 4], [1, 2]), split(tests, 1, 2))
+ self.assertEqual(([2, 4], [1, 3]), split(tests, 0, 2))
+ self.assertEqual(([1, 3], [2, 4]), split(tests, 1, 2))
- self.assertEqual(([1, 2], [3, 4]), split(tests, 0, 3))
- self.assertEqual(([3, 4], [1, 2]), split(tests, 1, 3))
- self.assertEqual(([], [1, 2, 3, 4]), split(tests, 2, 3))
+ self.assertEqual(([3], [1, 2, 4]), split(tests, 0, 3))
+ self.assertEqual(([1, 4], [2, 3]), split(tests, 1, 3))
+ self.assertEqual(([2], [1, 3, 4]), split(tests, 2, 3))
- tests = [1, 2, 3, 4, 5]
- self.assertEqual(([1, 2, 3, 4, 5], []), split(tests, 0, 1))
+ tests = [1, 2, 3, 4, 5]
+ self.assertEqual(([1, 2, 3, 4, 5], []), split(tests, 0, 1))
- self.assertEqual(([1, 2, 3], [4, 5]), split(tests, 0, 2))
- self.assertEqual(([4, 5], [1, 2, 3]), split(tests, 1, 2))
+ self.assertEqual(([2, 4], [1, 3, 5]), split(tests, 0, 2))
+ self.assertEqual(([1, 3, 5], [2, 4]), split(tests, 1, 2))
- self.assertEqual(([1, 2], [3, 4, 5]), split(tests, 0, 3))
- self.assertEqual(([3, 4], [1, 2, 5]), split(tests, 1, 3))
- self.assertEqual(([5], [1, 2, 3, 4]), split(tests, 2, 3))
+ self.assertEqual(([3], [1, 2, 4, 5]), split(tests, 0, 3))
+ self.assertEqual(([1, 4], [2, 3, 5]), split(tests, 1, 3))
+ self.assertEqual(([2, 5], [1, 3, 4]), split(tests, 2, 3))
- tests = [1, 2, 3, 4, 5, 6]
- self.assertEqual(([1, 2, 3, 4, 5, 6], []), split(tests, 0, 1))
+ tests = [1, 2, 3, 4, 5, 6]
+ self.assertEqual(([1, 2, 3, 4, 5, 6], []), split(tests, 0, 1))
- self.assertEqual(([1, 2, 3], [4, 5, 6]), split(tests, 0, 2))
- self.assertEqual(([4, 5, 6], [1, 2, 3]), split(tests, 1, 2))
+ self.assertEqual(([2, 4, 6], [1, 3, 5]), split(tests, 0, 2))
+ self.assertEqual(([1, 3, 5], [2, 4, 6]), split(tests, 1, 2))
- self.assertEqual(([1, 2], [3, 4, 5, 6]), split(tests, 0, 3))
- self.assertEqual(([3, 4], [1, 2, 5, 6]), split(tests, 1, 3))
- self.assertEqual(([5, 6], [1, 2, 3, 4]), split(tests, 2, 3))
+ self.assertEqual(([3, 6], [1, 2, 4, 5]), split(tests, 0, 3))
+ self.assertEqual(([1, 4], [2, 3, 5, 6]), split(tests, 1, 3))
+ self.assertEqual(([2, 5], [1, 3, 4, 6]), split(tests, 2, 3))
diff --git a/chromium/third_party/blink/tools/blinkpy/web_tests/controllers/layout_test_runner.py b/chromium/third_party/blink/tools/blinkpy/web_tests/controllers/layout_test_runner.py
index c924d263f1d..1fdd62f649d 100644
--- a/chromium/third_party/blink/tools/blinkpy/web_tests/controllers/layout_test_runner.py
+++ b/chromium/third_party/blink/tools/blinkpy/web_tests/controllers/layout_test_runner.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.
+import collections
+import itertools
import logging
import math
import time
@@ -96,6 +98,9 @@ class LayoutTestRunner(object):
self._options.fully_parallel,
self._options.batch_size == 1)
+ self._reorder_tests_by_args(locked_shards)
+ self._reorder_tests_by_args(unlocked_shards)
+
# We don't have a good way to coordinate the workers so that they don't
# try to run the shards that need a lock. The easiest solution is to
# run all of the locked shards first.
@@ -135,6 +140,17 @@ class LayoutTestRunner(object):
return test_run_results
+ def _reorder_tests_by_args(self, shards):
+ reordered_shards = []
+ for shard in shards:
+ tests_by_args = collections.OrderedDict()
+ for test_input in shard.test_inputs:
+ args = tuple(self._port.args_for_test(test_input.test_name))
+ if args not in tests_by_args:
+ tests_by_args[args] = []
+ tests_by_args[args].append(test_input)
+ shard.test_inputs = list(itertools.chain(*tests_by_args.values()))
+
def _worker_factory(self, worker_connection):
results_directory = self._results_directory
if self._retry_attempt > 0:
diff --git a/chromium/third_party/blink/tools/blinkpy/web_tests/controllers/manager.py b/chromium/third_party/blink/tools/blinkpy/web_tests/controllers/manager.py
index 16e184f770d..9c72d6a15c4 100644
--- a/chromium/third_party/blink/tools/blinkpy/web_tests/controllers/manager.py
+++ b/chromium/third_party/blink/tools/blinkpy/web_tests/controllers/manager.py
@@ -111,15 +111,13 @@ class Manager(object):
# This is raised if --test-list doesn't exist
return test_run_results.RunDetails(exit_code=exit_codes.NO_TESTS_EXIT_STATUS)
- # Create a sorted list of test files so the subset chunk,
- # if used, contains alphabetically consecutive tests.
+ test_names, tests_in_other_chunks = self._finder.split_into_chunks(all_test_names)
+
if self._options.order == 'natural':
- all_test_names.sort(key=self._port.test_key)
+ test_names.sort(key=self._port.test_key)
elif self._options.order == 'random':
- all_test_names.sort()
- random.Random(self._options.seed).shuffle(all_test_names)
-
- test_names, tests_in_other_chunks = self._finder.split_into_chunks(all_test_names)
+ test_names.sort()
+ random.Random(self._options.seed).shuffle(test_names)
self._printer.write_update('Parsing expectations ...')
self._expectations = test_expectations.TestExpectations(self._port, test_names)
diff --git a/chromium/third_party/blink/tools/blinkpy/web_tests/controllers/single_test_runner.py b/chromium/third_party/blink/tools/blinkpy/web_tests/controllers/single_test_runner.py
index aa2b3d32d13..9a1862cb5bd 100644
--- a/chromium/third_party/blink/tools/blinkpy/web_tests/controllers/single_test_runner.py
+++ b/chromium/third_party/blink/tools/blinkpy/web_tests/controllers/single_test_runner.py
@@ -113,18 +113,8 @@ class SingleTestRunner(object):
if self._should_fetch_expected_checksum():
image_hash = self._port.expected_checksum(self._test_name)
- test_base = self._port.lookup_virtual_test_base(self._test_name)
- if test_base:
- # If the file actually exists under the virtual dir, we want to use it (largely for virtual references),
- # but we want to use the extra command line args either way.
- if self._filesystem.exists(self._port.abspath_for_test(self._test_name)):
- test_name = self._test_name
- else:
- test_name = test_base
- args = self._port.lookup_virtual_test_args(self._test_name)
- else:
- test_name = self._test_name
- args = self._port.lookup_physical_test_args(self._test_name)
+ args = self._port.args_for_test(self._test_name)
+ test_name = self._port.name_for_test(self._test_name)
return DriverInput(test_name, self._timeout_ms, image_hash, self._should_run_pixel_test, args)
def run(self):
@@ -189,19 +179,36 @@ class SingleTestRunner(object):
if (test_failures.has_failure_type(test_failures.FailureTimeout, failures) or
test_failures.has_failure_type(test_failures.FailureCrash, failures)):
return
+ # We usually don't want to create a new baseline if there isn't one
+ # existing (which usually means this baseline isn't necessary, e.g.
+ # an image-first test without text expectation files). However, in the
+ # following cases, we do:
+ # 1. The failure is MISSING; a baseline is apparently needed.
+ # 2. A testharness.js test fails assertions: testharness.js tests
+ # without baselines are implicitly expected to pass all assertions;
+ # if there are failed assertions we need to create a new baseline.
+ # Note that the created baseline might be redundant, but users can
+ # optimize them later with optimize-baselines.
self._save_baseline_data(driver_output.text, '.txt',
- test_failures.has_failure_type(test_failures.FailureMissingResult, failures))
+ test_failures.has_failure_type(test_failures.FailureMissingResult, failures) or
+ test_failures.has_failure_type(test_failures.FailureTestHarnessAssertion, failures))
self._save_baseline_data(driver_output.audio, '.wav',
test_failures.has_failure_type(test_failures.FailureMissingAudio, failures))
self._save_baseline_data(driver_output.image, '.png',
test_failures.has_failure_type(test_failures.FailureMissingImage, failures))
- def _save_baseline_data(self, data, extension, is_missing):
+ def _save_baseline_data(self, data, extension, force_create_new_baseline):
if data is None:
return
+
port = self._port
fs = self._filesystem
+ # Do not create a new baseline unless we are specifically told so.
+ current_expected_path = port.expected_filename(self._test_name, extension)
+ if not fs.exists(current_expected_path) and not force_create_new_baseline:
+ return
+
flag_specific_dir = port.baseline_flag_specific_dir()
if flag_specific_dir:
output_dir = fs.join(flag_specific_dir, fs.dirname(self._test_name))
@@ -222,11 +229,9 @@ class SingleTestRunner(object):
_log.info('Removing the current baseline "%s"', port.relative_test_filename(output_path))
fs.remove(output_path)
+ # Note that current_expected_path may change because of the above file removal.
current_expected_path = port.expected_filename(self._test_name, extension)
- if not fs.exists(current_expected_path):
- if not is_missing or not self._options.reset_results:
- return
- elif fs.sha1(current_expected_path) == hashlib.sha1(data).hexdigest():
+ if fs.exists(current_expected_path) and fs.sha1(current_expected_path) == hashlib.sha1(data).hexdigest():
if self._options.reset_results:
_log.info('Not writing new expected result "%s" because it is the same as the current expected result',
port.relative_test_filename(output_path))
diff --git a/chromium/third_party/blink/tools/blinkpy/web_tests/layout_package/bot_test_expectations.py b/chromium/third_party/blink/tools/blinkpy/web_tests/layout_package/bot_test_expectations.py
index f7ce07b7233..81d036eb38b 100644
--- a/chromium/third_party/blink/tools/blinkpy/web_tests/layout_package/bot_test_expectations.py
+++ b/chromium/third_party/blink/tools/blinkpy/web_tests/layout_package/bot_test_expectations.py
@@ -218,7 +218,7 @@ class BotTestExpectations(object):
# Distinct resulting expectations.
result_exp = map(string_to_exp, result_strings)
- expected = lambda e: TestExpectations.result_was_expected(e, expectations, False)
+ expected = lambda e: TestExpectations.result_was_expected(e, expectations)
additional_expectations = set(e for e in result_exp if not expected(e))
@@ -328,7 +328,7 @@ class BotTestExpectations(object):
# individual runs' full_results.json, which would be slow and more complicated.
# The only thing we lose by not fixing this is that a test that was flaky
# and got fixed will still get printed out until 100 runs have passed.
- if not TestExpectations.result_was_expected(result_enum, latest_expectations, test_needs_rebaselining=False):
+ if not TestExpectations.result_was_expected(result_enum, latest_expectations):
has_unexpected_results = True
break
diff --git a/chromium/third_party/blink/tools/blinkpy/web_tests/models/test_expectations.py b/chromium/third_party/blink/tools/blinkpy/web_tests/models/test_expectations.py
index ee549c340d0..70f1267627b 100644
--- a/chromium/third_party/blink/tools/blinkpy/web_tests/models/test_expectations.py
+++ b/chromium/third_party/blink/tools/blinkpy/web_tests/models/test_expectations.py
@@ -44,7 +44,7 @@ _log = logging.getLogger(__name__)
# FIXME: range() starts with 0 which makes if expectation checks harder
# as PASS is 0.
(PASS, FAIL, TEXT, IMAGE, IMAGE_PLUS_TEXT, AUDIO, TIMEOUT, CRASH, LEAK, SKIP, WONTFIX,
- SLOW, REBASELINE, NEEDS_REBASELINE_UNUSED, NEEDS_MANUAL_REBASELINE, MISSING, FLAKY, NOW, NONE) = range(19)
+ SLOW, MISSING, FLAKY, NOW, NONE) = range(16)
WEBKIT_BUG_PREFIX = 'webkit.org/b/'
CHROMIUM_BUG_PREFIX = 'crbug.com/'
@@ -73,7 +73,6 @@ class TestExpectationParser(object):
# FIXME: Rename these to *_KEYWORD as in MISSING_KEYWORD above, but make
# the case studdly-caps to match the actual file contents.
- REBASELINE_MODIFIER = 'rebaseline'
PASS_EXPECTATION = 'pass'
SKIP_MODIFIER = 'skip'
SLOW_MODIFIER = 'slow'
@@ -160,12 +159,7 @@ class TestExpectationParser(object):
expectations = [expectation.lower() for expectation in expectation_line.expectations]
if not expectation_line.bugs and self.WONTFIX_MODIFIER not in expectations:
expectation_line.warnings.append(self.MISSING_BUG_WARNING)
- if self.REBASELINE_MODIFIER in expectations:
- expectation_line.warnings.append('REBASELINE should only be used for running rebaseline.py. Cannot be checked in.')
-
specifiers = [specifier.lower() for specifier in expectation_line.specifiers]
- if self.REBASELINE_MODIFIER in expectations and ('debug' in specifiers or 'release' in specifiers):
- expectation_line.warnings.append('A test cannot be rebaselined for Debug/Release.')
def _parse_expectations(self, expectation_line):
result = set()
@@ -296,7 +290,6 @@ class TestExpectationLine(object):
'Failure': 'FAIL',
MISSING_KEYWORD: 'MISSING',
'Pass': 'PASS',
- 'Rebaseline': 'REBASELINE',
'Skip': 'SKIP',
'Slow': 'SLOW',
'Timeout': 'TIMEOUT',
@@ -714,7 +707,7 @@ class TestExpectationsModel(object):
return ' '.join(retval)
def remove_expectation_line(self, test):
- if not self.has_test(test.name):
+ if not self.has_test(test):
return
self._clear_expectations_for_test(test)
del self._test_to_expectation_line[test]
@@ -904,7 +897,6 @@ class TestExpectations(object):
TestExpectationParser.SKIP_MODIFIER: SKIP,
TestExpectationParser.WONTFIX_MODIFIER: WONTFIX,
TestExpectationParser.SLOW_MODIFIER: SLOW,
- TestExpectationParser.REBASELINE_MODIFIER: REBASELINE,
}
EXPECTATIONS_TO_STRING = {k: v.upper() for (v, k) in EXPECTATIONS.iteritems()}
@@ -924,8 +916,6 @@ class TestExpectations(object):
MISSING: 'missing results',
}
- NON_TEST_OUTCOME_EXPECTATIONS = (REBASELINE, SKIP, SLOW, WONTFIX)
-
BUILD_TYPES = ('debug', 'release')
TIMELINES = {
@@ -955,25 +945,26 @@ class TestExpectations(object):
raise ValueError(expectation)
@staticmethod
- def result_was_expected(result, expected_results, test_needs_rebaselining):
+ def result_was_expected(result, expected_results):
"""Returns whether we got a result we were expecting.
Args:
result: actual result of a test execution
expected_results: set of results listed in test_expectations
- test_needs_rebaselining: whether test was marked as REBASELINE
"""
- if not set(expected_results) - set(TestExpectations.NON_TEST_OUTCOME_EXPECTATIONS):
- expected_results = set([PASS])
-
- if result in expected_results:
- return True
- if result in (PASS, TEXT, IMAGE, IMAGE_PLUS_TEXT, AUDIO, MISSING) and NEEDS_MANUAL_REBASELINE in expected_results:
+ local_expected = set(expected_results)
+ if WONTFIX in local_expected:
+ # WontFix should be treated as if we expected a Skip.
+ local_expected.add(SKIP)
+
+ # Make sure we have at least one result type that may actually happen.
+ local_expected.discard(WONTFIX)
+ local_expected.discard(SLOW)
+ if not local_expected:
+ local_expected = {PASS}
+
+ if result in local_expected:
return True
- if result in (TEXT, IMAGE, IMAGE_PLUS_TEXT, AUDIO) and FAIL in expected_results:
- return True
- if result == MISSING and test_needs_rebaselining:
- return True
- if result == SKIP:
+ if result in (TEXT, IMAGE, IMAGE_PLUS_TEXT, AUDIO) and FAIL in local_expected:
return True
return False
@@ -1085,9 +1076,6 @@ class TestExpectations(object):
def expectations(self):
return self._expectations
- def get_rebaselining_failures(self):
- return self._model.get_test_set(REBASELINE)
-
# FIXME: Change the callsites to use TestExpectationsModel and remove.
def get_expectations(self, test):
return self._model.get_expectations(test)
@@ -1113,10 +1101,7 @@ class TestExpectations(object):
expected_results = self.remove_non_sanitizer_failures(expected_results)
elif not pixel_tests_are_enabled:
expected_results = self.remove_pixel_failures(expected_results)
- return self.result_was_expected(result, expected_results, self.is_rebaselining(test))
-
- def is_rebaselining(self, test):
- return REBASELINE in self._model.get_expectations(test)
+ return self.result_was_expected(result, expected_results)
def _shorten_filename(self, filename):
finder = PathFinder(self._port.host.filesystem)
diff --git a/chromium/third_party/blink/tools/blinkpy/web_tests/models/test_expectations_unittest.py b/chromium/third_party/blink/tools/blinkpy/web_tests/models/test_expectations_unittest.py
index 18344a0042e..ff92d5a1cb4 100644
--- a/chromium/third_party/blink/tools/blinkpy/web_tests/models/test_expectations_unittest.py
+++ b/chromium/third_party/blink/tools/blinkpy/web_tests/models/test_expectations_unittest.py
@@ -36,7 +36,7 @@ from blinkpy.web_tests.models.test_configuration import TestConfiguration, TestC
from blinkpy.web_tests.models.test_expectations import (
TestExpectationLine, TestExpectations, ParseError, TestExpectationParser,
PASS, FAIL, TEXT, IMAGE, IMAGE_PLUS_TEXT, AUDIO,
- TIMEOUT, CRASH, LEAK, SKIP, WONTFIX, NEEDS_MANUAL_REBASELINE, MISSING
+ TIMEOUT, CRASH, LEAK, SKIP, WONTFIX, MISSING
)
@@ -121,35 +121,15 @@ class MiscTests(Base):
def test_result_was_expected(self):
# test basics
- self.assertEqual(TestExpectations.result_was_expected(PASS, set([PASS]), test_needs_rebaselining=False), True)
- self.assertEqual(TestExpectations.result_was_expected(FAIL, set([PASS]), test_needs_rebaselining=False), False)
+ self.assertEqual(TestExpectations.result_was_expected(PASS, set([PASS])), True)
+ self.assertEqual(TestExpectations.result_was_expected(FAIL, set([PASS])), False)
# test handling of SKIPped tests and results
- self.assertEqual(TestExpectations.result_was_expected(SKIP, set([CRASH]), test_needs_rebaselining=False), True)
- self.assertEqual(TestExpectations.result_was_expected(SKIP, set([LEAK]), test_needs_rebaselining=False), True)
-
- # test handling of MISSING results and the REBASELINE specifier
- self.assertEqual(TestExpectations.result_was_expected(MISSING, set([PASS]), test_needs_rebaselining=True), True)
- self.assertEqual(TestExpectations.result_was_expected(MISSING, set([PASS]), test_needs_rebaselining=False), False)
-
- self.assertTrue(TestExpectations.result_was_expected(
- PASS, set([NEEDS_MANUAL_REBASELINE]), test_needs_rebaselining=False))
- self.assertTrue(TestExpectations.result_was_expected(
- MISSING, set([NEEDS_MANUAL_REBASELINE]), test_needs_rebaselining=False))
- self.assertTrue(TestExpectations.result_was_expected(
- TEXT, set([NEEDS_MANUAL_REBASELINE]), test_needs_rebaselining=False))
- self.assertTrue(TestExpectations.result_was_expected(
- IMAGE, set([NEEDS_MANUAL_REBASELINE]), test_needs_rebaselining=False))
- self.assertTrue(TestExpectations.result_was_expected(
- IMAGE_PLUS_TEXT, set([NEEDS_MANUAL_REBASELINE]), test_needs_rebaselining=False))
- self.assertTrue(TestExpectations.result_was_expected(
- AUDIO, set([NEEDS_MANUAL_REBASELINE]), test_needs_rebaselining=False))
- self.assertFalse(TestExpectations.result_was_expected(
- TIMEOUT, set([NEEDS_MANUAL_REBASELINE]), test_needs_rebaselining=False))
- self.assertFalse(TestExpectations.result_was_expected(
- CRASH, set([NEEDS_MANUAL_REBASELINE]), test_needs_rebaselining=False))
- self.assertFalse(TestExpectations.result_was_expected(
- LEAK, set([NEEDS_MANUAL_REBASELINE]), test_needs_rebaselining=False))
+ self.assertEqual(TestExpectations.result_was_expected(SKIP, set([CRASH])), False)
+ self.assertEqual(TestExpectations.result_was_expected(SKIP, set([LEAK])), False)
+
+ # test handling of MISSING results
+ self.assertEqual(TestExpectations.result_was_expected(MISSING, set([PASS])), False)
def test_remove_pixel_failures(self):
self.assertEqual(TestExpectations.remove_pixel_failures(set([FAIL])), set([FAIL]))
@@ -776,17 +756,6 @@ Bug(y) [ Mac ] failures/expected/foo.html [ Crash ]
""", actual_expectations)
-class RebaseliningTest(Base):
-
- def test_get_rebaselining_failures(self):
- # Make sure we find a test as needing a rebaseline even if it is not marked as a failure.
- self.parse_exp('Bug(x) failures/expected/text.html [ Rebaseline ]\n')
- self.assertEqual(len(self._exp.get_rebaselining_failures()), 1)
-
- self.parse_exp(self.get_basic_expectations())
- self.assertEqual(len(self._exp.get_rebaselining_failures()), 0)
-
-
class TestExpectationsParserTests(unittest.TestCase):
def __init__(self, testFunc):
diff --git a/chromium/third_party/blink/tools/blinkpy/web_tests/models/test_run_results.py b/chromium/third_party/blink/tools/blinkpy/web_tests/models/test_run_results.py
index 3e7668df311..ad6448ded52 100644
--- a/chromium/third_party/blink/tools/blinkpy/web_tests/models/test_run_results.py
+++ b/chromium/third_party/blink/tools/blinkpy/web_tests/models/test_run_results.py
@@ -245,16 +245,28 @@ def summarize_results(port_obj, expectations, initial_results,
has_unexpected_pass = True
else:
has_expected = True
- # A test is flaky if it has both expected and unexpected runs (NOT pass
- # and failure).
+
+ # TODO(crbug.com/855255): This code calls a test flaky if it has both
+ # expected and unexpected runs (NOT pass and failure); this is generally
+ # wrong (really it should just be if there are multiple kinds of results),
+ # but this works in the normal case because a test will only be retried
+ # if a result is unexpected, and if you get an expected result on the
+ # retry, then you did get multiple results. This fails if you get
+ # one kind of unexpected failure initially and another kind of
+ # unexpected failure on the retry (e.g., TIMEOUT CRASH), or if you
+ # explicitly run a test multiple times and get multiple expected results.
is_flaky = has_expected and has_unexpected
- if len(set(actual)) == 1:
- actual = [actual[0]]
- actual_types = [actual_types[0]]
+ test_dict = {}
+ test_dict['expected'] = expected
+ test_dict['actual'] = ' '.join(actual)
+
+ # Fields below are optional. To avoid bloating the output results json
+ # too much, only add them when they are True or non-empty.
if is_flaky:
num_flaky += 1
+ test_dict['is_flaky'] = True
elif all_pass or has_unexpected_pass:
# We count two situations as a "pass":
# 1. All test runs pass (which is obviously non-flaky, but does not
@@ -268,19 +280,10 @@ def summarize_results(port_obj, expectations, initial_results,
num_passes += 1
if not has_stderr and only_include_failing:
continue
- elif has_unexpected and result.type != test_expectations.SKIP:
+ elif has_unexpected:
# Either no retries or all retries failed unexpectedly.
- # TODO(robertma): When will there be unexpected skip? Do we really
- # want to ignore them when counting regressions?
num_regressions += 1
- test_dict = {}
-
- test_dict['expected'] = expected
- test_dict['actual'] = ' '.join(actual)
-
- # Fields below are optional. To avoid bloating the output results json
- # too much, only add them when they are True or non-empty.
rounded_run_time = round(initial_result.test_run_time, 1)
if rounded_run_time:
@@ -318,11 +321,15 @@ def summarize_results(port_obj, expectations, initial_results,
port_obj.get_option('pixel_tests') or initial_result.reftest_type,
port_obj.get_option('enable_sanitizer'))
- # Note: is_unexpected is intended to capture the *last* result. In the
- # normal use case (stop retrying failures once they pass), this is
- # equivalent to checking if none of the results is expected.
- if not any(is_expected(actual_result) for actual_result in actual_types):
+ # Note: is_unexpected and is_regression are intended to reflect the
+ # *last* result. In the normal use case (stop retrying failures
+ # once they pass), this is equivalent to saying that all of the
+ # results were unexpected failures.
+ last_result = actual_types[-1]
+ if not is_expected(last_result):
test_dict['is_unexpected'] = True
+ if last_result != test_expectations.PASS:
+ test_dict['is_regression'] = True
if initial_result.has_repaint_overlay:
test_dict['has_repaint_overlay'] = True
diff --git a/chromium/third_party/blink/tools/blinkpy/web_tests/models/test_run_results_unittest.py b/chromium/third_party/blink/tools/blinkpy/web_tests/models/test_run_results_unittest.py
index b56872d7ae3..5c587d78f62 100644
--- a/chromium/third_party/blink/tools/blinkpy/web_tests/models/test_run_results_unittest.py
+++ b/chromium/third_party/blink/tools/blinkpy/web_tests/models/test_run_results_unittest.py
@@ -83,7 +83,7 @@ def summarized_results(port, expected, passing, flaky, only_include_failing=Fals
elif passing:
skipped_result = get_result('passes/skipped/skip.html')
skipped_result.type = test_expectations.SKIP
- initial_results.add(skipped_result, expected, test_is_slow)
+ initial_results.add(skipped_result, True, test_is_slow)
initial_results.add(get_result('passes/text.html', run_time=1), expected, test_is_slow)
initial_results.add(get_result('failures/expected/audio.html'), expected, test_is_slow)
@@ -205,7 +205,6 @@ class SummarizedResultsTest(unittest.TestCase):
'TEXT': 1,
'IMAGE': 1,
'PASS': 0,
- 'REBASELINE': 0,
'SKIP': 0,
'SLOW': 0,
'TIMEOUT': 3,
@@ -225,7 +224,6 @@ class SummarizedResultsTest(unittest.TestCase):
'TEXT': 0,
'IMAGE': 0,
'PASS': 1,
- 'REBASELINE': 0,
'SKIP': 0,
'SLOW': 0,
'TIMEOUT': 1,
@@ -245,7 +243,6 @@ class SummarizedResultsTest(unittest.TestCase):
'TEXT': 0,
'IMAGE': 0,
'PASS': 5,
- 'REBASELINE': 0,
'SKIP': 1,
'SLOW': 0,
'TIMEOUT': 0,
@@ -285,7 +282,6 @@ class SummarizedResultsTest(unittest.TestCase):
self.port._options.builder_name = 'dummy builder'
summary = summarized_results(self.port, expected=False, passing=True, flaky=False)
self.assertTrue(summary['tests']['passes']['text.html'])
- self.assertTrue('is_unexpected' not in summary['tests']['passes']['text.html'])
self.assertEqual(summary['num_passes'], 5)
self.assertEqual(summary['num_regressions'], 0)
self.assertEqual(summary['num_flaky'], 0)
@@ -347,7 +343,6 @@ class SummarizedResultsTest(unittest.TestCase):
def test_summarized_results_flaky(self):
summary = summarized_results(self.port, expected=False, passing=False, flaky=True)
- self.assertTrue('is_unexpected' not in summary['tests']['failures']['expected']['crash.html'])
self.assertEquals(summary['tests']['failures']['expected']['crash.html']['expected'], 'CRASH')
self.assertEquals(summary['tests']['failures']['expected']['crash.html']['actual'], 'TIMEOUT AUDIO CRASH LEAK')
@@ -425,15 +420,15 @@ class SummarizedResultsTest(unittest.TestCase):
self.assertTrue(summary['tests']['passes']['text.html']['is_unexpected'])
self.assertEquals(summary['tests']['passes']['text.html']['expected'], 'PASS')
- self.assertEquals(summary['tests']['passes']['text.html']['actual'], 'TIMEOUT')
+ self.assertEquals(summary['tests']['passes']['text.html']['actual'], 'TIMEOUT TIMEOUT TIMEOUT TIMEOUT')
self.assertTrue(summary['tests']['failures']['expected']['crash.html']['is_unexpected'])
self.assertEquals(summary['tests']['failures']['expected']['crash.html']['expected'], 'CRASH')
- self.assertEquals(summary['tests']['failures']['expected']['crash.html']['actual'], 'TIMEOUT')
+ self.assertEquals(summary['tests']['failures']['expected']['crash.html']['actual'], 'TIMEOUT TIMEOUT TIMEOUT TIMEOUT')
self.assertTrue(summary['tests']['failures']['expected']['leak.html']['is_unexpected'])
self.assertEquals(summary['tests']['failures']['expected']['leak.html']['expected'], 'LEAK')
- self.assertEquals(summary['tests']['failures']['expected']['leak.html']['actual'], 'TIMEOUT')
+ self.assertEquals(summary['tests']['failures']['expected']['leak.html']['actual'], 'TIMEOUT TIMEOUT TIMEOUT TIMEOUT')
self.assertTrue(summary['tests']['failures']['expected']['audio.html']['is_unexpected'])
self.assertEquals(summary['tests']['failures']['expected']['audio.html']['expected'], 'FAIL')
diff --git a/chromium/third_party/blink/tools/blinkpy/web_tests/port/android.py b/chromium/third_party/blink/tools/blinkpy/web_tests/port/android.py
index a94f8e13956..b388554b41f 100644
--- a/chromium/third_party/blink/tools/blinkpy/web_tests/port/android.py
+++ b/chromium/third_party/blink/tools/blinkpy/web_tests/port/android.py
@@ -432,7 +432,7 @@ class AndroidPort(base.Port):
device_errors.CommandTimeoutError,
device_errors.DeviceUnreachableError) as error:
with lock:
- _log.warning('[%s] failed to prepare_device: %s', serial, error)
+ _log.warning('[%s] failed to prepare_device: %s', device.serial, error)
devices = self._devices.usable_devices(self.host.executive)
device_utils.DeviceUtils.parallel(devices).pMap(setup_device)
diff --git a/chromium/third_party/blink/tools/blinkpy/web_tests/port/base.py b/chromium/third_party/blink/tools/blinkpy/web_tests/port/base.py
index 09312ae5ff2..1e16870e803 100644
--- a/chromium/third_party/blink/tools/blinkpy/web_tests/port/base.py
+++ b/chromium/third_party/blink/tools/blinkpy/web_tests/port/base.py
@@ -1067,6 +1067,20 @@ class Port(object):
"""
return self._filesystem.join(self.layout_tests_dir(), test_name)
+ @memoized
+ def args_for_test(self, test_name):
+ test_base = self.lookup_virtual_test_base(test_name)
+ if test_base:
+ return self.lookup_virtual_test_args(test_name)
+ return self.lookup_physical_test_args(test_name)
+
+ @memoized
+ def name_for_test(self, test_name):
+ test_base = self.lookup_virtual_test_base(test_name)
+ if test_base and not self._filesystem.exists(self.abspath_for_test(test_name)):
+ return test_base
+ return test_name
+
def results_directory(self):
"""Returns the absolute path to the place to store the test results."""
if not self._results_directory:
diff --git a/chromium/third_party/blink/tools/blinkpy/web_tests/run_webkit_tests_unittest.py b/chromium/third_party/blink/tools/blinkpy/web_tests/run_webkit_tests_unittest.py
index 78f6c76e967..82220141a1e 100644
--- a/chromium/third_party/blink/tools/blinkpy/web_tests/run_webkit_tests_unittest.py
+++ b/chromium/third_party/blink/tools/blinkpy/web_tests/run_webkit_tests_unittest.py
@@ -29,11 +29,14 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import json
+import os
import re
import StringIO
+import sys
import unittest
from blinkpy.common import exit_codes
+from blinkpy.common import path_finder
from blinkpy.common.host import Host
from blinkpy.common.host_mock import MockHost
from blinkpy.common.system.path import abspath_to_uri
@@ -44,6 +47,11 @@ from blinkpy.web_tests.models import test_expectations
from blinkpy.web_tests.models import test_failures
from blinkpy.web_tests.port import test
+_MOCK_ROOT = os.path.join(
+ path_finder.get_chromium_src_dir(), 'third_party', 'pymock')
+sys.path.append(_MOCK_ROOT)
+import mock
+
def parse_args(extra_args=None, tests_included=False):
extra_args = extra_args or []
@@ -521,25 +529,31 @@ class RunTest(unittest.TestCase, StreamTestingMixin):
def test_sharding_even(self):
# Test that we actually select the right part
tests_to_run = ['passes/error.html', 'passes/image.html', 'passes/platform_image.html', 'passes/text.html']
- # Shard 0 of 2
- tests_run = get_tests_run(['--shard-index', '0', '--total-shards', '2', '--order', 'natural'] + tests_to_run)
- self.assertEqual(tests_run, ['passes/error.html', 'passes/image.html'])
- # Shard 1 of 2
- tests_run = get_tests_run(['--shard-index', '1', '--total-shards', '2', '--order', 'natural'] + tests_to_run)
- self.assertEqual(tests_run, ['passes/platform_image.html', 'passes/text.html'])
+
+ with mock.patch('__builtin__.hash', len):
+
+ # Shard 0 of 2
+ tests_run = get_tests_run(['--shard-index', '0', '--total-shards', '2', '--order', 'natural'] + tests_to_run)
+ self.assertEqual(tests_run, ['passes/platform_image.html', 'passes/text.html'])
+ # Shard 1 of 2
+ tests_run = get_tests_run(['--shard-index', '1', '--total-shards', '2', '--order', 'natural'] + tests_to_run)
+ self.assertEqual(tests_run, ['passes/error.html', 'passes/image.html'])
def test_sharding_uneven(self):
tests_to_run = ['passes/error.html', 'passes/image.html', 'passes/platform_image.html', 'passes/text.html',
'perf/foo/test.html']
- # Shard 0 of 3
- tests_run = get_tests_run(['--shard-index', '0', '--total-shards', '3', '--order', 'natural'] + tests_to_run)
- self.assertEqual(tests_run, ['passes/error.html', 'passes/image.html'])
- # Shard 1 of 3
- tests_run = get_tests_run(['--shard-index', '1', '--total-shards', '3', '--order', 'natural'] + tests_to_run)
- self.assertEqual(tests_run, ['passes/platform_image.html', 'passes/text.html'])
- # Shard 2 of 3
- tests_run = get_tests_run(['--shard-index', '2', '--total-shards', '3', '--order', 'natural'] + tests_to_run)
- self.assertEqual(tests_run, ['perf/foo/test.html'])
+
+ with mock.patch('__builtin__.hash', len):
+
+ # Shard 0 of 3
+ tests_run = get_tests_run(['--shard-index', '0', '--total-shards', '3', '--order', 'natural'] + tests_to_run)
+ self.assertEqual(tests_run, ['perf/foo/test.html'])
+ # Shard 1 of 3
+ tests_run = get_tests_run(['--shard-index', '1', '--total-shards', '3', '--order', 'natural'] + tests_to_run)
+ self.assertEqual(tests_run, ['passes/text.html'])
+ # Shard 2 of 3
+ tests_run = get_tests_run(['--shard-index', '2', '--total-shards', '3', '--order', 'natural'] + tests_to_run)
+ self.assertEqual(tests_run, ['passes/error.html', 'passes/image.html', 'passes/platform_image.html'])
def test_sharding_incorrect_arguments(self):
with self.assertRaises(ValueError):
@@ -553,15 +567,17 @@ class RunTest(unittest.TestCase, StreamTestingMixin):
tests_to_run = ['passes/error.html', 'passes/image.html', 'passes/platform_image.html', 'passes/text.html']
host = MockHost()
- host.environ['GTEST_SHARD_INDEX'] = '0'
- host.environ['GTEST_TOTAL_SHARDS'] = '2'
- shard_0_tests_run = get_tests_run(['--order', 'natural'] + tests_to_run, host=host)
- self.assertEqual(shard_0_tests_run, ['passes/error.html', 'passes/image.html'])
+ with mock.patch('__builtin__.hash', len):
+
+ host.environ['GTEST_SHARD_INDEX'] = '0'
+ host.environ['GTEST_TOTAL_SHARDS'] = '2'
+ shard_0_tests_run = get_tests_run(['--order', 'natural'] + tests_to_run, host=host)
+ self.assertEqual(shard_0_tests_run, ['passes/platform_image.html', 'passes/text.html'])
- host.environ['GTEST_SHARD_INDEX'] = '1'
- host.environ['GTEST_TOTAL_SHARDS'] = '2'
- shard_1_tests_run = get_tests_run(['--order', 'natural'] + tests_to_run, host=host)
- self.assertEqual(shard_1_tests_run, ['passes/platform_image.html', 'passes/text.html'])
+ host.environ['GTEST_SHARD_INDEX'] = '1'
+ host.environ['GTEST_TOTAL_SHARDS'] = '2'
+ shard_1_tests_run = get_tests_run(['--order', 'natural'] + tests_to_run, host=host)
+ self.assertEqual(shard_1_tests_run, ['passes/error.html', 'passes/image.html'])
def test_smoke_test(self):
host = MockHost()
@@ -617,16 +633,27 @@ class RunTest(unittest.TestCase, StreamTestingMixin):
'failures/unexpected/text-image-checksum.html'],
tests_included=True, host=host)
self.assertEqual(details.exit_code, 2)
- json_string = host.filesystem.read_text_file('/tmp/layout-test-results/full_results.json')
- self.assertTrue(json_string.find(
- '"text-image-checksum.html":{'
- '"expected":"PASS",'
- '"text_mismatch":"general text mismatch",'
- '"actual":"IMAGE+TEXT","is_unexpected":true') != -1)
- self.assertTrue(json_string.find(
- '"missing_text.html":{"expected":"PASS","is_missing_text":true,"actual":"MISSING","is_unexpected":true') != -1)
- self.assertTrue(json_string.find('"num_regressions":2') != -1)
- self.assertTrue(json_string.find('"num_flaky":0') != -1)
+ results = json.loads(host.filesystem.read_text_file('/tmp/layout-test-results/full_results.json'))
+ self.assertEqual(
+ results['tests']['failures']['unexpected']['text-image-checksum.html'],
+ {
+ 'expected': 'PASS',
+ 'actual': 'IMAGE+TEXT',
+ 'is_unexpected': True,
+ 'is_regression': True,
+ 'text_mismatch': 'general text mismatch',
+ })
+ self.assertEqual(
+ results['tests']['failures']['unexpected']['missing_text.html'],
+ {
+ 'expected': 'PASS',
+ 'actual': 'MISSING',
+ 'is_unexpected': True,
+ 'is_regression': True,
+ 'is_missing_text': True,
+ })
+ self.assertEqual(results['num_regressions'], 2)
+ self.assertEqual(results['num_flaky'], 0)
def test_different_failure_on_retry(self):
# This tests that if a test fails two different ways -- both unexpected
@@ -659,8 +686,8 @@ class RunTest(unittest.TestCase, StreamTestingMixin):
def test_crash_with_stderr(self):
host = MockHost()
logging_run(['failures/unexpected/crash-with-stderr.html'], tests_included=True, host=host)
- self.assertTrue(host.filesystem.read_text_file('/tmp/layout-test-results/full_results.json').find(
- '{"crash-with-stderr.html":{"expected":"PASS","actual":"CRASH","has_stderr":true,"is_unexpected":true') != -1)
+ full_results = json.loads(host.filesystem.read_text_file('/tmp/layout-test-results/full_results.json'))
+ self.assertEqual(full_results['tests']['failures']['unexpected']['crash-with-stderr.html']['has_stderr'], True)
def test_no_image_failure_with_image_diff(self):
host = MockHost()
@@ -828,11 +855,15 @@ class RunTest(unittest.TestCase, StreamTestingMixin):
host.filesystem.exists('/tmp/layout-test-results/retry_3/failures/unexpected/text-image-checksum-actual.png'))
json_string = host.filesystem.read_text_file('/tmp/layout-test-results/full_results.json')
results = parse_full_results(json_string)
- self.assertEqual(results['tests']['failures']['unexpected']['text-image-checksum.html'],
- {'expected': 'PASS',
- 'actual': 'TEXT IMAGE+TEXT IMAGE+TEXT IMAGE+TEXT',
- 'is_unexpected': True,
- 'text_mismatch': 'general text mismatch'})
+ self.assertEqual(
+ results['tests']['failures']['unexpected']['text-image-checksum.html'],
+ {
+ 'expected': 'PASS',
+ 'actual': 'TEXT IMAGE+TEXT IMAGE+TEXT IMAGE+TEXT',
+ 'is_regression': True,
+ 'is_unexpected': True,
+ 'text_mismatch': 'general text mismatch',
+ })
self.assertFalse(results['pixel_tests_enabled'])
self.assertTrue(details.enabled_pixel_tests_in_retry)
@@ -925,7 +956,7 @@ class RunTest(unittest.TestCase, StreamTestingMixin):
host = MockHost()
logging_run(['--no-show-results', 'reftests/foo/'], tests_included=True, host=host)
results = parse_full_results(host.filesystem.read_text_file('/tmp/layout-test-results/full_results.json'))
- self.assertEqual(results['tests']['reftests']['foo']['unlistedtest.html']['actual'], 'MISSING')
+ self.assertEqual(results['tests']['reftests']['foo']['unlistedtest.html']['actual'], 'MISSING MISSING MISSING MISSING')
self.assertEqual(results['num_regressions'], 5)
self.assertEqual(results['num_flaky'], 0)
@@ -1124,12 +1155,33 @@ class EndToEndTest(unittest.TestCase):
self.assertTrue('multiple-mismatch-success.html' not in results['tests']['reftests']['foo'])
self.assertTrue('multiple-both-success.html' not in results['tests']['reftests']['foo'])
- self.assertEqual(results['tests']['reftests']['foo']['multiple-match-failure.html'],
- {'expected': 'PASS', 'actual': 'IMAGE', 'reftest_type': ['=='], 'is_unexpected': True})
- self.assertEqual(results['tests']['reftests']['foo']['multiple-mismatch-failure.html'],
- {'expected': 'PASS', 'actual': 'IMAGE', 'reftest_type': ['!='], 'is_unexpected': True})
- self.assertEqual(results['tests']['reftests']['foo']['multiple-both-failure.html'],
- {'expected': 'PASS', 'actual': 'IMAGE', 'reftest_type': ['==', '!='], 'is_unexpected': True})
+ self.assertEqual(
+ results['tests']['reftests']['foo']['multiple-match-failure.html'],
+ {
+ 'expected': 'PASS',
+ 'actual': 'IMAGE IMAGE IMAGE IMAGE',
+ 'reftest_type': ['=='],
+ 'is_regression': True,
+ 'is_unexpected': True,
+ })
+ self.assertEqual(
+ results['tests']['reftests']['foo']['multiple-mismatch-failure.html'],
+ {
+ 'expected': 'PASS',
+ 'actual': 'IMAGE IMAGE IMAGE IMAGE',
+ 'reftest_type': ['!='],
+ 'is_regression': True,
+ 'is_unexpected': True,
+ })
+ self.assertEqual(
+ results['tests']['reftests']['foo']['multiple-both-failure.html'],
+ {
+ 'expected': 'PASS',
+ 'actual': 'IMAGE IMAGE IMAGE IMAGE',
+ 'reftest_type': ['==', '!='],
+ 'is_regression': True,
+ 'is_unexpected': True,
+ })
class RebaselineTest(unittest.TestCase, StreamTestingMixin):
@@ -1221,7 +1273,8 @@ class RebaselineTest(unittest.TestCase, StreamTestingMixin):
expected_extensions=['.txt'])
def test_reset_results_testharness_no_baseline(self):
- # Tests that we don't create new result for a testharness test without baselines.
+ # Tests that we create new result for a failing testharness test without
+ # baselines, but don't create one for a passing one.
host = MockHost()
details, log_stream, _ = logging_run(
[
@@ -1232,8 +1285,8 @@ class RebaselineTest(unittest.TestCase, StreamTestingMixin):
tests_included=True, host=host)
file_list = host.filesystem.written_files.keys()
self.assertEqual(details.exit_code, 0)
- self.assertEqual(len(file_list), 5)
- self.assert_baselines(file_list, log_stream, 'failures/unexpected/testharness', [])
+ self.assertEqual(len(file_list), 6)
+ self.assert_baselines(file_list, log_stream, 'failures/unexpected/testharness', ['.txt'])
self.assert_baselines(file_list, log_stream, 'passes/testharness', [])
def test_reset_results_testharness_existing_baseline(self):
@@ -1458,6 +1511,58 @@ class RebaselineTest(unittest.TestCase, StreamTestingMixin):
'virtual/virtual_failures/failures/unexpected/text-image-checksum',
expected_extensions=['.png'])
+ def test_new_platform_baseline_with_fallback(self):
+ # Test that we update the existing baseline in the platform-specific
+ # directory if the new baseline is different, with existing fallback
+ # baseline (which should not matter).
+ host = MockHost()
+ host.filesystem.write_text_file(
+ test.LAYOUT_TEST_DIR +
+ '/platform/test-mac-mac10.10/failures/unexpected/text-image-checksum-expected.png',
+ 'wrong-png-baseline')
+
+ details, log_stream, _ = logging_run(
+ [
+ '--reset-results',
+ 'failures/unexpected/text-image-checksum.html'
+ ],
+ tests_included=True, host=host)
+ file_list = host.filesystem.written_files.keys()
+ self.assertEqual(details.exit_code, 0)
+ self.assertEqual(len(file_list), 7)
+ # We should reset the platform image baseline.
+ self.assert_baselines(
+ file_list, log_stream,
+ 'platform/test-mac-mac10.10/failures/unexpected/text-image-checksum',
+ expected_extensions=['.png'])
+
+ def test_new_platform_baseline_without_fallback(self):
+ # Test that we update the existing baseline in the platform-specific
+ # directory if the new baseline is different, without existing fallback
+ # baseline (which should not matter).
+ host = MockHost()
+ host.filesystem.write_text_file(
+ test.LAYOUT_TEST_DIR +
+ '/platform/test-mac-mac10.10/failures/unexpected/text-image-checksum-expected.png',
+ 'wrong-png-baseline')
+ host.filesystem.remove(
+ test.LAYOUT_TEST_DIR + '/failures/unexpected/text-image-checksum-expected.png')
+
+ details, log_stream, _ = logging_run(
+ [
+ '--reset-results',
+ 'failures/unexpected/text-image-checksum.html'
+ ],
+ tests_included=True, host=host)
+ file_list = host.filesystem.written_files.keys()
+ self.assertEqual(details.exit_code, 0)
+ self.assertEqual(len(file_list), 8)
+ # We should reset the platform image baseline.
+ self.assert_baselines(
+ file_list, log_stream,
+ 'platform/test-mac-mac10.10/failures/unexpected/text-image-checksum',
+ expected_extensions=['.png'])
+
def test_new_virtual_baseline_optimize(self):
# Test removing existing baselines under flag-specific directory if the
# actual results are the same as the fallback baselines.
diff --git a/chromium/third_party/blink/tools/blinkpy/web_tests/servers/apache_http.py b/chromium/third_party/blink/tools/blinkpy/web_tests/servers/apache_http.py
index 9f96f043469..991ae4ab03c 100644
--- a/chromium/third_party/blink/tools/blinkpy/web_tests/servers/apache_http.py
+++ b/chromium/third_party/blink/tools/blinkpy/web_tests/servers/apache_http.py
@@ -179,12 +179,11 @@ class ApacheHTTP(server_base.ServerBase):
proc = self._executive.popen([self._port_obj.path_to_apache(),
'-f', self._port_obj.path_to_apache_config_file(),
'-c', 'PidFile "%s"' % self._pid_file,
- '-k', 'stop'], stderr=self._executive.PIPE)
- proc.wait()
+ '-k', 'stop'])
+ _, err = proc.communicate()
retval = proc.returncode
- err = proc.stderr.read()
- if retval or len(err):
- raise server_base.ServerError('Failed to stop %s: %s' % (self._name, err))
+ if retval or (err and len(err)):
+ raise server_base.ServerError('Failed to stop %s: %s %s' % (self._name, err))
# For some reason apache isn't guaranteed to have actually stopped after
# the stop command returns, so we wait a little while longer for the
diff --git a/chromium/third_party/blink/tools/blinkpy/web_tests/update_expectations.py b/chromium/third_party/blink/tools/blinkpy/web_tests/update_expectations.py
index 526f4b43f08..d40f91d168f 100644
--- a/chromium/third_party/blink/tools/blinkpy/web_tests/update_expectations.py
+++ b/chromium/third_party/blink/tools/blinkpy/web_tests/update_expectations.py
@@ -230,8 +230,6 @@ class ExpectationsRemover(object):
otherwise.
"""
unstrippable_expectations = (
- 'NEEDSMANUALREBASELINE',
- 'REBASELINE',
'SKIP',
'SLOW',
)
diff --git a/chromium/third_party/blink/tools/blinkpy/web_tests/update_expectations_unittest.py b/chromium/third_party/blink/tools/blinkpy/web_tests/update_expectations_unittest.py
index 0ab4ee3a70b..3eba7079965 100644
--- a/chromium/third_party/blink/tools/blinkpy/web_tests/update_expectations_unittest.py
+++ b/chromium/third_party/blink/tools/blinkpy/web_tests/update_expectations_unittest.py
@@ -172,8 +172,7 @@ class UpdateTestExpectationsTest(LoggingTestCase):
# expectations are flaky so we shouldn't remove any.
Bug(test) test/a.html [ Pass ]
Bug(test) test/b.html [ Timeout ]
- Bug(test) test/c.html [ Failure Timeout ]
- Bug(test) test/d.html [ Rebaseline ]"""
+ Bug(test) test/c.html [ Failure Timeout ]"""
self._expectations_remover = (
self._create_expectations_remover(self.FLAKE_TYPE))
@@ -213,8 +212,7 @@ class UpdateTestExpectationsTest(LoggingTestCase):
# expectations are failing so we shouldn't remove any.
Bug(test) test/a.html [ Pass ]
Bug(test) test/b.html [ Failure Pass ]
- Bug(test) test/c.html [ Failure Pass Timeout ]
- Bug(test) test/d.html [ Rebaseline ]"""
+ Bug(test) test/c.html [ Failure Pass Timeout ]"""
self._expectations_remover = (
self._create_expectations_remover(self.FAIL_TYPE))
@@ -344,36 +342,6 @@ class UpdateTestExpectationsTest(LoggingTestCase):
self._assert_expectations_match(
updated_expectations, test_expectations_before)
- def test_dont_remove_rebaselines(self):
- """Tests that lines with rebaseline expectations are untouched."""
- test_expectations_before = """
- # Even though the results show all passing, none of the
- # expectations are flaky or failing so we shouldn't remove any.
- Bug(test) test/a.html [ Failure Pass Rebaseline ]
- Bug(test) test/b.html [ Failure Rebaseline ]"""
-
- self._expectations_remover = self._create_expectations_remover()
- self._define_builders({
- 'WebKit Linux Trusty': {
- 'port_name': 'linux-trusty',
- 'specifiers': ['Trusty', 'Release']
- },
- })
- self._port.all_build_types = ('release',)
- self._port.all_systems = (('trusty', 'x86_64'),)
-
- self._parse_expectations(test_expectations_before)
- self._expectation_factory.all_results_by_builder = {
- 'WebKit Linux Trusty': {
- 'test/a.html': ['PASS', 'PASS'],
- 'test/b.html': ['PASS', 'PASS'],
- }
- }
- updated_expectations = (
- self._expectations_remover.get_updated_test_expectations())
- self._assert_expectations_match(
- updated_expectations, test_expectations_before)
-
def test_all_failure_result_types(self):
"""Tests that all failure types are treated as failure."""
test_expectations_before = (